@layer theme, legacy, base, components, utilities;
@layer legacy {
/* App page layout. Reusable controls live in components.css; rendered notes keep their own portable reading.css styles. */
/* The app puts the page back after each redraw; base.css's smooth scrolling would animate that into a visible slide. */
html:has(body.notefriends-brand) { scroll-behavior: auto; }
body.notefriends-brand {
  margin: 0;
  background: var(--nf-paper);
  color: var(--nf-pencil);
  font-family: var(--nf-font-ui);
}
/* The HTML starts pending, before JavaScript or account lookup can reveal the intended destination.
   Hiding the shell also keeps its draft, controls and page height out of the loading surface. */
.startup-status { display: none; }
body[data-view=pending] :is(.shell, .topbar, .skip) { display: none !important; }
body[data-view=pending] .startup-status { position: fixed; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px; color: var(--nf-pencil-muted); font-size: 14px; }
.notefriends-brand a { color: inherit; }
/* Phones only: a slim header with Back (NF-137). Wide screens have the sidebar's own toggle. */
.topbar { position: sticky; top: 0; z-index: 30; display: flex; align-items: center; gap: 12px; height: 64px; box-sizing: border-box; padding: 0 max(3vw,16px); background: var(--nf-paper); }
.topbar { display: none; }
.topbar-mark img { display: block; }
.wordmark { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; min-width: 0; text-decoration: none; }
.wordmark img { display: block; flex: none; }
.pane-label { font-family: var(--nf-font-label); letter-spacing: .08em; font-size: 11px; }

/* The account sits at the foot of the sidebar: the email opens the Account page (PC-082), beside Sign in/out. */
#account-button { flex: none; margin-left: auto; white-space: nowrap; }
#signin-status, #password-status { margin: 8px 0 0; }
.signin-password { margin-top: 12px; }
.signin-password .link-row { margin-top: 6px; }

/* ---- The room shell (docs/02-design/design-system-v2.md#shell-rules; docs/03-architecture/frontend.md) ----
   Signed in (body[data-nav]) the page is two columns: the rooms sidebar (components/app/rooms-nav.tsx, 272px) and the main column. In a room the main column is the room (#room-frame): its header, then the
   conversation or a page, the composer docked under it, and "Things" (#room-sheet, 300px) on the right. Everything inside is drawn by React with Tailwind utilities on the tokens; these rules only
   place the regions the note session and the frame own (ids, hidden regions, the one note editor). Not signed in there is no sidebar and the page is the note under a slim top bar. */
.shell { display: block; }
body[data-nav] .shell { display: grid; grid-template-columns: var(--nf-nav-w) minmax(0,1fr); height: 100vh; height: 100dvh; align-items: stretch; overflow: hidden; }
.app-nav { display: none; }
body[data-nav] .app-nav { display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
body[data-nav] .app-nav nav { flex: 1 1 auto; }
.main-column { min-width: 0; min-height: 0; display: flex; flex-direction: column; }
body[data-nav] main { flex: 1 1 auto; min-height: 0; overflow: auto; }
/* An account without alpha access has only Account: no sidebar content, one column. */
body[data-nav][data-limited] .shell { grid-template-columns: minmax(0,1fr); }
body[data-nav][data-limited] .app-nav { display: none; }
/* Global pages (Friends, Activity, Account, New room) show alone in the main column. */
body:is([data-view=friends], [data-view=activity], [data-view=account], [data-view=new]) main > :not(.destination) { display: none; }
/* The top bar is for someone not signed in: the brand and Sign in. Signed in, the room's own header is the top. */
.topbar { position: sticky; top: 0; z-index: 30; display: flex; align-items: center; gap: 12px; height: 56px; box-sizing: border-box; padding: 0 max(3vw,16px); background: var(--nf-paper); border-bottom: 1px solid var(--nf-line); }
body[data-nav] .topbar { display: none; }
.topbar-account { display: flex; align-items: center; }
body[data-nav] .topbar-account { display: none; }
/* The room: a header, the conversation or a page, and the composer; the sheet is a column on the right. */
.room-frame { display: none; min-height: 0; }
body:is([data-view=room], [data-view=notebook], [data-view=note]) .room-frame { display: grid; grid-template-columns: minmax(0,1fr); grid-template-rows: minmax(0,1fr); height: 100%; } /* the room fills the height; the narrow sidebar (a fixed overlay) takes no row */
body[data-nav]:is([data-view=room], [data-view=notebook], [data-view=note]) main { overflow: hidden; }
body:not([data-nav])[data-view=note] .room-frame { height: auto; }
.room-main { position: relative; min-width: 0; min-height: 0; display: grid; grid-template-columns: minmax(0,1fr); grid-template-rows: auto minmax(0,1fr) auto; background: var(--nf-paper); }
body:not([data-nav]) .room-main { display: block; }
.room-header:empty, .room-header[hidden] { display: none; }
.room-body { min-height: 0; overflow: auto; overscroll-behavior: contain; }
body:not([data-nav]) .room-body { overflow: visible; }
@media (min-width: 1101px) {
  body[data-nav]:is([data-view=room], [data-view=notebook], [data-view=note]) .room-frame:has(#room-sheet:not([hidden], :empty)) { grid-template-columns: minmax(0,1fr) var(--nf-sheet-w); }
}
.room-sheet { min-height: 0; overflow: auto; display: flex; flex-direction: column; background: var(--nf-sheet); }
.room-sheet aside { flex: 1 1 auto; }
.room-sheet:empty { display: none; }
/* Narrow windows and phones: Things is a sidebar on the right (components/room/room-sheet-view.tsx); it slides in unless motion is reduced. */
@media (prefers-reduced-motion: no-preference) { .room-drawer { animation: room-drawer-in .2s ease-out; } @keyframes room-drawer-in { from { transform: translateX(100%); } } }
/* The conversation is the centre of a room's chat; over a page it is the sheet above the composer. */
.chat-dock { display: contents; }
.chat-dock[hidden] { display: none; }
.chat-sheet { grid-row: 2; min-height: 0; display: flex; flex-direction: column; }
/* The "New messages" pill sits at the bottom of the conversation, above the composer, never over it. */
.chat-sheet[data-in-room=yes] { position: relative; }
.chat-sheet .chat-scroll { flex: 1 1 auto; min-height: 0; overflow: auto; overscroll-behavior: contain; }
.chat-sheet-head { display: flex; align-items: center; justify-content: flex-end; gap: 4px; padding: 6px 12px 0; }
.chat-sheet-head h2 { margin: 0 auto 0 10px; font: 600 14px var(--nf-font-ui); }
.chat-compose { grid-row: 3; position: relative; display: grid; gap: 6px; min-width: 0; }
.chat-status { margin-inline: 22px; }
.chat-status:empty { display: none; }
.chat-status { margin-block: 0 8px; font-size: 12.5px; color: var(--nf-pencil-muted); }
body[data-view=room]:not(:has(#project-appendix:not([hidden]))) .room-body { display: none; }
body[data-view=room]:has(#project-appendix:not([hidden])) .chat-sheet { display: none; }
body:is([data-view=note], [data-view=notebook], [data-view=room]) .chat-sheet:not([data-in-room=yes]) { position: absolute; z-index: 6; left: 16px; right: 16px; bottom: calc(var(--nf-chat-compose-height, 68px) + 18px); max-height: min(60%, 520px); border: 1px solid var(--nf-line); border-radius: 14px; background: var(--nf-sheet); box-shadow: 0 -8px 30px var(--nf-shade); overflow: hidden; }
body[data-view=notebook] #book-leaf { display: none; }
.book-leaf { display: block; }
#project-appendix:not([hidden]) ~ #book-leaf { display: none; }
body[data-view=room] #project-appendix { box-sizing: border-box; width: auto; max-width: none; margin: 0; padding: 0; border: 0; border-radius: 0; background: var(--nf-paper); }
.workspace { min-height: 0; }
/* The editing bar covers the composer while a block is being edited. */
.chat-dock:has(#edit-dock[data-shown=yes]) .chat-compose { visibility: hidden; }
/* The page holds the viewport; the room body scrolls inside it, so the sidebar fills the full height. */
html:has(body[data-nav]), body[data-nav] { height: 100%; overflow: hidden; }
/* A message's menu sits at its top right and shows on hover or focus; it adds no height. A long press (a context menu) opens it on touch. */
.chat-msg { position: relative; }
/* The current person's and Nota's chat bubbles; other room messages keep their existing layout. */
#chat-list .chat-own-message { align-self: flex-end; max-width: min(86%, 620px); }
.chat-own-line, .nota-chat-line { display: flex; align-items: flex-start; gap: 9px; min-width: 0; }
.chat-own-line > span, .nota-chat-line > span { flex: none; }
.chat-own-line { flex-direction: row-reverse; }
.nota-chat-line { max-width: min(86%, 620px); }
.chat-own-content { min-width: 0; }
.chat-own-bubble, .nota-chat-bubble { display: grid; grid-template-columns: minmax(0, 1fr); gap: 4px; min-width: 0; padding: 11px 14px; border: 1px solid var(--nf-line); border-radius: 17px; background: var(--nf-selected); overflow-wrap: anywhere; }
.chat-own-bubble { border-bottom-right-radius: 5px; }
.nota-chat-bubble { border-color: var(--nf-nota-line); border-bottom-left-radius: 5px; background: var(--nf-nota); }
.chat-own-bubble > *, .nota-chat-bubble > * { grid-column-start: 1 !important; }
/* Nota's page preview in chat (components/room/page-preview.tsx): pictures and picture cards draw as on the page, but its view menus and gallery controls are hidden (a preview has no live controls). */
[data-page-preview] .nf-view-menu, [data-page-preview] .nf-gallery-bar, [data-page-preview] .nf-thumbs, [data-page-preview] .nf-image-tools, [data-page-preview] .nf-remote { display: none; }
/* Nota's progress line (components/ui/message.tsx NotaStatus): small face centred in the 30px avatar column (text lines up with messages), one muted line that ends in an ellipsis, quiet buttons. A status, not a reply, so no card. */
.nota-status { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; min-width: 0; color: var(--nf-pencil-muted); font-size: 13px; }
.nota-status-face { display: grid; flex: none; place-items: center; width: 22px; height: 22px; margin: 0 4px; border-radius: 50%; background: var(--nf-pencil-yellow); color: var(--nf-on-yellow); }
.nota-status-text { flex: 1 1 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nota-status-actions { display: flex; flex: none; gap: 2px; }
.nota-status-more { flex-basis: 100%; padding-left: 40px; }
/* Nota's reaction (components/ui/message.tsx ReactionPill): a pill with her face and the emoji. On the current person's bubble it hangs over the bottom edge, and the bubble leaves room below for it. */
.chat-reaction { display: inline-flex; align-items: center; gap: 5px; width: fit-content; padding: 2px 8px 2px 3px; border: 1px solid var(--nf-line); border-radius: 999px; background: var(--nf-sheet); box-shadow: var(--nf-shadow-bar); font-size: 13px; line-height: 1; }
.chat-reaction-face { display: grid; place-items: center; width: 18px; height: 18px; border-radius: 50%; background: var(--nf-pencil-yellow); color: var(--nf-on-yellow); }
.chat-reaction.is-overlap { position: absolute; right: 12px; bottom: -14px; z-index: 1; }
.chat-own-bubble { position: relative; }
.chat-own-bubble:has(> .chat-reaction.is-overlap) { margin-bottom: 14px; }
.chat-own-meta { display: flex; justify-content: flex-end; align-items: baseline; gap: 7px; font-size: 12px; font-weight: 600; }
.chat-own-meta time { color: var(--nf-pencil-muted); font-size: 11.5px; font-weight: 400; }
/* "Saved to Memory": on the time's line, in its text style, for a few seconds after Nota saves the message (docs/03-architecture/nota-memory.md#the-saved-to-memory-label). */
.memory-saved { color: var(--nf-pencil-muted); font-size: inherit; font-weight: 400; white-space: nowrap; }
.memory-saved::before { content: "·"; margin: 0 5px; }
.memory-saved:first-child::before { content: none; }
.chat-own-meta .memory-saved { font-size: 11.5px; }
.chat-own-meta .memory-saved::before { margin-left: 0; }
@media (prefers-reduced-motion: no-preference) { .memory-saved { animation: memory-saved-in .2s ease-out; } @keyframes memory-saved-in { from { opacity: 0; } } }
.chat-own-after { display: grid; gap: 4px; text-align: right; }
.chat-own-after > * { grid-column-start: 1 !important; }
.chat-own-after > div { justify-content: flex-end; }
.chat-own-message .hover-menu { right: 39px; }
@media (max-width: 750px) { #chat-list .chat-own-message, .nota-chat-line { max-width: 94%; } }
/* Sheet rows: the "…" shows on hover or focus (keyboard stays reachable). */
.room-sheet li [aria-haspopup=menu], .room-sheet section [aria-haspopup=menu] { opacity: 0; }
.room-sheet li:hover [aria-haspopup=menu], .room-sheet section:hover [aria-haspopup=menu], .room-sheet [aria-haspopup=menu]:focus-visible, .room-sheet [aria-haspopup=menu][aria-expanded=true] { opacity: 1; }
@media (hover: none) { .room-sheet li [aria-haspopup=menu], .room-sheet section [aria-haspopup=menu] { opacity: 1; } }
/* A page in a room has no toolbar band: its actions are in the header's "…" menu. Saving is silent; only a failed save shows, as a red line at the top of the page (its words open the recovery popup).
   The words stay for screen readers (components/app/app-frame.tsx). docs/06-products/magic-notebook/README.md#the-room-screens. */
.save-status { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.save-status:has(.save-cloud[data-save=problem]) { position: static; width: auto; height: auto; overflow: visible; clip-path: none; white-space: normal; padding: 8px 48px 0; }
@media (max-width: 750px) { .save-status:has(.save-cloud[data-save=problem]) { padding: 6px 16px 0; } }
body[data-nav][data-view=note] .workspace .preview-pane { padding-top: 0; }
/* Phones: the room list is the home screen; a room fills the screen; the sheet is pulled up from the book button; Activity, Friends and Account are tabs on a floating bar (components/ui/phone-tabs.tsx). */
@media (max-width: 750px) {
  body[data-nav] .shell { grid-template-columns: minmax(0,1fr); }
  body[data-nav] .app-nav { display: none; }
  body[data-nav][data-view=home] .app-nav { display: flex; }
  body[data-nav][data-view=home] .main-column { display: none; }
  body[data-tabs] .main-column > main { padding-bottom: calc(84px + env(safe-area-inset-bottom)); }
  body[data-keyboard] .phone-tabs { display: none; }
  body:is([data-view=note], [data-view=notebook], [data-view=room]) .chat-sheet:not([data-in-room=yes]) { left: 8px; right: 8px; bottom: calc(var(--nf-chat-compose-height, 62px) + 8px); }
.chat-status { margin-inline: 10px; }
}
/* The note fills the right side edge to edge; the reading column centres itself. */
main { min-width: 0; width: 100%; box-sizing: border-box; margin: 0; padding: 0; }
/* The note's look fills the rest of the screen below a short note. */
.workspace { display: flex; flex-direction: column; min-height: 0; background: var(--nf-sheet); }
body:not([data-nav]) .workspace { min-height: 100vh; min-height: 100dvh; }
.workspace > * { flex: none; }
.workspace > .panes { flex: 1 0 auto; }
/* The failed-save line: red, underlined, its words (max 14em, 8em on a phone) opening the recovery popup. */
.save-cloud { display: inline-flex; align-items: center; color: var(--nf-danger-note); font-size: 12.5px; text-decoration: underline; text-underline-offset: 2px; }
.save-cloud .save-text { max-width: 14em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 750px) { .save-cloud .save-text { max-width: 8em; } }
/* The glass material for controls that float over the note (the phone bar, the block bar in components.css) is --nf-glass-* in brand/tokens.css. */
/* The blur is written out, not a variable: Safari has ignored -webkit-backdrop-filter given through a custom property. */
#preview .nf-bar { -webkit-backdrop-filter: blur(5px) saturate(180%) brightness(1.04); backdrop-filter: blur(5px) saturate(180%) brightness(1.04); }
.panes { display: grid; grid-template-columns: 1fr; }
.panes:not([data-source]) .editor-pane { display: none; }
.panes[data-source] { grid-template-columns: 1fr 1fr; }
.editor-pane { border-right: 1px solid var(--nf-line); background: var(--nf-sheet); min-width: 0; }
.preview-pane { min-width: 0; }
.pane-label { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding: 20px 24px; color: var(--nf-pencil-muted); font-size: 10px; }
/* NF-142: the sidebar already shows where the note lives; the breadcrumb returns when the sidebar is collapsed. */
.pane-label span:last-child { letter-spacing: 0; text-transform: none; }
/* #209, #210: who shared this note, and the reader's Ask to edit. A quiet row above the note; the avatar is initials, never a photo. */
.shared-by { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 10px; padding: 10px 24px 0; color: var(--nf-pencil-muted); font-size: 13px; }
.shared-by[hidden], .shared-by-avatar[hidden] { display: none; }
.shared-by-avatar { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 28px; height: 28px; border-radius: 50%; background: var(--nf-hover); color: var(--nf-pencil); font-size: 11px; font-weight: 600; letter-spacing: .02em; }
.shared-by-text { min-width: 0; overflow-wrap: anywhere; }
.shared-by-text strong { color: var(--nf-pencil); font-weight: 600; }
.shared-by-status { flex: 1 1 100%; font-size: 12px; }
.shared-by-status:empty { display: none; }
#source { display: block; width: 100%; min-height: 480px; padding: 10px 26px 30px; border: 0; resize: vertical; background: transparent; color: var(--nf-pencil); font: 14px/1.8 ui-monospace,SFMono-Regular,Consolas,monospace; }
#source:focus-visible { outline-offset: -4px; }
#people h2 { margin: 16px 0 0; font-size: 18px; }
#people h3 { margin: 16px 0 0; font-size: 14px; }
.workspace > .upload-status { margin: 12px 16px 0; }
/* NF-035: picture upload progress and failure, under the toolbar like the other notices. */
.upload-status { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; box-sizing: border-box; padding: 12px 16px; border: 1px solid var(--nf-line); border-radius: var(--nf-radius-lg); background: var(--nf-sheet); font-size: 14px; }
.upload-status[data-kind=error] { border-color: var(--nf-danger); background: var(--nf-danger-bg); color: var(--nf-danger); }
.upload-status #upload-text { flex: 1 1 16rem; min-width: 0; overflow-wrap: anywhere; }
.upload-status progress { flex: 0 1 10rem; height: 8px; accent-color: var(--nf-accent); }
.upload-actions { display: flex; gap: 8px; }
body[data-reader] #open { display: none; }
/* NF-248 (was NF-131's Read mode): nobody gets the "Your note" / word-count row. */
.preview-pane > .pane-label { display: none; }
[hidden] { display: none!important; }
@media(max-width: 750px) {
  .topbar { gap: 8px; height: 56px; padding: 0 12px; }
  .topbar-mark { display: inline-flex; align-items: center; gap: 8px; min-width: 0; min-height: 44px; }
  .workspace { background: var(--nf-look-paper, var(--nf-sheet)); }
  .workspace:not(:has(> .upload-status:not([hidden], :empty))) .preview-pane { padding-top: 56px; }
  /* #209, #210: the Shared by row sits under the floating bar (it takes the 56px the note would tuck under). */
  .shared-by { padding-top: 62px; padding-inline: 16px; }
  .workspace:has(> .shared-by:not([hidden])) .preview-pane { padding-top: 0; }
  /* Signed out (no Back): the brand badge and Sign in sit on a glass capsule at the top left, not a logo bar above. */
  body[data-view=note]:not([data-nav]) .topbar { position: fixed; top: 3px; left: 8px; z-index: 30; height: 50px; box-sizing: border-box; gap: 0; padding: 2px; border: var(--nf-glass-edge); border-radius: 999px; background: var(--nf-glass-bg);
    -webkit-backdrop-filter: blur(5px) saturate(180%) brightness(1.04); backdrop-filter: blur(5px) saturate(180%) brightness(1.04); box-shadow: var(--nf-glass-shadow); } /* the same glass capsule as the note's actions, so the note never draws through the badge */
  body[data-view=note]:not([data-nav]) .topbar-mark { padding-left: 8px; }
  body[data-view=note]:not([data-nav]) .topbar-mark img + img { display: none; }
  .workspace > .upload-status { margin: 12px 12px 0; }
  /* The editing grip fits the page margin: the utility sets its width at 22px, the margin is 16px. */
  .nf-handle .nf-handle-button { width: 14px !important; }
  .panes, .panes[data-source] { grid-template-columns: 1fr; }.editor-pane { border-right: 0; border-bottom: 1px solid var(--nf-line); }
  #source { min-height: 300px; padding: 10px 20px 24px; font-size: 16px; }
  .pane-label { padding: 18px 20px; gap: 8px; }
  /* PC-018: helper text and labels stay readable on phones. */
  .link-row label { font-size: 13px; }
}
@media print {
  .shell { display: block!important; }
  .topbar, .page-actions, #edit-dock, .editor-pane, .pane-label, .upload-status, .shared-by, .skip { display: none!important; }
  .panes { display: block!important; }.preview-pane { display: block!important; }
  .workspace { border: 0; box-shadow: none; }body.notefriends-brand { background: white; }main { padding: 0; }.prose { padding: 0!important; }
}

#preview { min-height: 320px; }

/* PC-045: one blanket reduced-motion guard, so transitions and animations added later are covered too. */
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition: none !important; animation-duration: .01ms !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; } }

/* NF-142: New note is one split control: the note button and a chevron menu (From a template, Import). */
/* Wide screens: the sidebar runs at Chrome tab-strip density (13px text, ~32px rows, 16px icons). Phones keep 44px targets. */
/* NF-142: the template browser: the list and a live preview of the selected template as the block note it becomes. */
.template-body { display: grid; grid-template-columns: 240px minmax(0, 1fr); gap: 16px; height: min(560px, calc(100dvh - 160px)); min-height: 0; }
.template-list { overflow: auto; min-height: 0; padding-right: 4px; }
.template-group { margin: 0 0 12px; padding: 0; border: 0; min-width: 0; }
.template-group legend { padding: 0 10px 4px; color: var(--nf-pencil-muted); font-size: 13px; font-weight: 600; }
.template-option { display: block; position: relative; cursor: pointer; }
.template-option input { position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; pointer-events: none; }
.template-option span { display: flex; align-items: center; min-height: 40px; padding: 0 10px; border-radius: var(--nf-radius); font-size: 14px; }
.template-option:hover span { background: var(--nf-hover); }
.template-option input:checked + span { background: var(--nf-selected); font-weight: 600; }
.template-option input:focus-visible + span { outline: var(--nf-focus); outline-offset: 2px; }
.template-preview-box { overflow: auto; min-height: 0; min-width: 0; border: 1px solid var(--nf-line); border-radius: var(--nf-radius-lg); }
.template-name { position: sticky; top: 0; z-index: 1; margin: 0; padding: 8px 16px; background: var(--nf-sheet); border-bottom: 1px solid var(--nf-line); color: var(--nf-pencil-muted); font-size: 13px; }
@media(max-width: 750px) {
  .template-body { grid-template-columns: 1fr; grid-template-rows: minmax(0, 36%) minmax(0, 1fr); height: calc(100dvh - 150px); gap: 10px; }
  .template-option span { min-height: 44px; }
}
/* NF-146/NF-205: the look drawer, a 320px panel pinned to the right edge so the note stays visible (and previews) beside it; on phones a bottom sheet that starts as a compact strip (search, family chips, one row of thumbnails) and expands to the full list. */
/* Slice 10: Looks, its own sidebar (400px; a sheet on phones). Its list is one column of large previews of the open page; the footer holds the status, the scope choice, Cancel and the one Apply. */

/* NF-248: blank page below the note to click into. */
@media(min-width: 751px) {
  body:not([data-reader]) #reading-surface { padding-bottom: max(96px, 30vh); } /* NF-248: blank page below the note to click into */
}
@media(max-width: 750px) {
  body:not([data-reader]) #reading-surface { padding-bottom: calc(max(96px, 30vh) + env(safe-area-inset-bottom)); }
}

/* BUG-055: while a note or view link opens, and on the not-found page, the note column holds nothing of the starter note. */
body[data-opening] .workspace > :not(#passcode-screen), body[data-passcode] .workspace > :not(#passcode-screen), body[data-notfound] .workspace > :not(#not-found) { display: none !important; }
/* The page is still loading (aria-busy) while the passcode is asked: the screen stays visible inside the hidden workspace (book.css). */
body[data-passcode] #passcode-screen { visibility: visible; }
/* The passcode screen has its own header (the wordmark and Read only), so the signed-out bar and its phone capsule step aside. */
body[data-passcode] .topbar { display: none; }

/* PC-089: the passcode screen: eight boxes, [][][][]-[][][][]. */
.passcode-boxes { display: flex; align-items: center; gap: 6px; margin: 8px 0; }
.passcode-box { width: 40px; height: 46px; padding: 0; box-sizing: border-box; text-align: center; font: 600 24px var(--nf-font-label); text-transform: uppercase; border: 1px solid var(--nf-line); border-radius: 10px; background: var(--nf-sheet); color: var(--nf-pencil); }
.passcode-dash { color: var(--nf-pencil-muted); font-size: 24px; padding: 0 2px; }
@media(max-width: 420px) { .passcode-boxes { gap: 4px; } .passcode-box { width: 34px; font-size: 20px; } }
@media(prefers-reduced-motion: no-preference) { .passcode-screen.shake .passcode-boxes { animation: passcode-shake .4s; } @keyframes passcode-shake { 20%, 60% { transform: translateX(-8px); } 40%, 80% { transform: translateX(8px); } } }
/* Slice 3: typing the server did not take. The cloud opens this small popup under it (components/typing-recovery.ts). */
.save-recover { position: fixed; z-index: 30; display: grid; gap: 8px; width: min(320px, calc(100vw - 16px)); box-sizing: border-box; padding: 12px; border: 1px solid var(--nf-line); border-radius: var(--nf-radius); background: var(--nf-sheet); box-shadow: 0 8px 24px var(--nf-shade-md); color: var(--nf-pencil); font-size: 14px; }
.save-recover[hidden] { display: none; }
.save-recover p { margin: 0; }
.save-recover blockquote { margin: 0; padding-left: 10px; border-left: 3px solid var(--nf-line); color: var(--nf-pencil-muted); overflow-wrap: anywhere; white-space: pre-wrap; max-height: 6em; overflow: hidden; }
.save-recover div { display: flex; gap: 8px; }
.save-cloud[role=button]:focus-visible { outline: 2px solid var(--nf-pencil); outline-offset: 2px; }
.save-cloud[role=button] { cursor: pointer; }

/* Magic Notebook slice 9: a notebook page reads until it is edited. Its actions are the page's "…" menu; only a failed save shows (the red line above the note). The row of page actions has no height, so starting
   or ending an edit moves nothing, and it sticks near the top while the page scrolls. */
.page-actions { display: none; }
body[data-page] .page-actions:not([hidden]) { display: flex; position: sticky; top: 8px; z-index: 25; height: 0; align-items: flex-start; justify-content: flex-end; padding-right: 12px; }
.page-actions [hidden] { display: none !important; }
#preview:focus-visible { outline: 2px solid var(--nf-accent); outline-offset: 2px; }
body[data-page]:not([data-editing]) #preview { cursor: text; }

}
/* Approved Nota trace sidebar reuses the existing room grid, paper and type tokens. */
.room-main:has(.nota-trace-sidebar) { grid-template-columns: minmax(0,1fr) 410px; }
.room-main:has(.nota-trace-sidebar) > :not(.chat-dock), .room-main:has(.nota-trace-sidebar) .chat-sheet, .room-main:has(.nota-trace-sidebar) .chat-compose { grid-column: 1; }
.nota-trace-sidebar { grid-column: 2 !important; grid-row: 1 / 4; min-height: 0; overflow: auto; background: var(--nf-sheet); border-left: 1px solid var(--nf-line); font: 13px/1.45 var(--nf-font-ui); }
.nota-trace-header { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 18px 20px; border-bottom: 1px solid var(--nf-line); position: sticky; top: 0; background: var(--nf-sheet); z-index: 1; }
.nota-trace-sidebar h2 { font-size: 17px; margin: 0; }
.nota-trace-sidebar h3 { font-size: 13px; margin: 0; }
.nota-trace-sidebar p { margin: 7px 0 0; }
.nota-trace-header p,.nota-trace-summary p,.nota-trace-notes > p { color: var(--nf-pencil-muted); font-size: 12px; }
.nota-trace-body { padding: 18px 20px; }
.nota-trace-body select { display: block; width: 100%; border: 1px solid var(--nf-line); border-radius: 9px; padding: 8px; margin-top: 6px; background: var(--nf-sheet); font: inherit; }
.nota-trace-summary { margin: 16px 0; padding: 12px; border: 1px solid var(--nf-line); border-radius: 10px; }
.nota-trace-metrics { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 14px; }
.nota-trace-metrics span { display: block; color: var(--nf-pencil-muted); font-size: 12px; }
.nota-trace-metrics b { display: block; font-size: 23px; margin-top: 3px; overflow-wrap: anywhere; }
.nota-trace-notes { padding: 12px; border-radius: 10px; background: var(--nf-paper); margin-bottom: 16px; }
.nota-trace-notes ul { padding-left: 18px; margin: 8px 0 0; }
.nota-trace-notes li + li { margin-top: 7px; }
.nota-trace-event { border-top: 1px solid var(--nf-line); padding: 13px 0; }
.nota-trace-event h3 { display: flex; justify-content: space-between; gap: 8px; }
.nota-trace-event time { color: var(--nf-pencil-muted); font-size: 11.5px; font-weight: 400; }
.nota-trace-event pre { white-space: pre-wrap; overflow-wrap: anywhere; font: 12px/1.45 var(--nf-font-ui); margin: 7px 0 0; }
@media(max-width:750px) {
  .room-main:has(.nota-trace-sidebar) { grid-template-columns: minmax(0,1fr); }
  .nota-trace-sidebar { position: fixed; inset: 60px 0 0; z-index: 30; border: 0; border-radius: 14px 14px 0 0; box-shadow: var(--nf-shadow-sheet); }
}

/* The trace temporarily occupies the right-hand pane, instead of squeezing in a fourth column. */
.room-frame:has(.nota-trace-sidebar) { grid-template-columns: minmax(0,1fr) !important; }
.room-frame:has(.nota-trace-sidebar) > .room-sheet { display: none; }
