/* nuuko design system. One file, replaces styles.css (347 KB).
   Tokens, base, native feel, type, the components every screen shares.
   A page may add its own small sheet after this one. No raw hex, size, shadow,
   radius or duration anywhere else. Round 7 values (R6 system, 29 Oct 2026, sprint 2 foundation).
   Link order on every page: styles.css, styles-auth.css, tokens.css, then the page's css/<page>.css,
   so these tokens win over the old sheet. */

/* ---------- fonts: two families, bundled, blocked for 200 ms so the first paint is already right ---------- */
/* v9 (her call, 31 Oct: "the prototype is nice"): Crimson Pro and Inter, the prototype's two faces */
@font-face { font-family: 'Crimson Pro'; font-style: normal; font-weight: 200 900; font-display: block; src: url('/fonts/crimson-pro.woff2') format('woff2'); }
@font-face { font-family: 'Crimson Pro'; font-style: italic; font-weight: 200 900; font-display: block; src: url('/fonts/crimson-pro-italic.woff2') format('woff2'); }
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 100 900; font-display: block; src: url('/fonts/inter.woff2') format('woff2'); }

/* ---------- tokens, light ---------- */
:root {
  /* type: Newsreader for what you read, Instrument Sans for what you operate. Line heights are px, never percent. */
  --font-sans: 'Inter', system-ui, Roboto, sans-serif;
  --font-serif: 'Crimson Pro', Georgia, serif;
  --font-display: 'Crimson Pro', Georgia, serif;
  --fs-meta: 0.875rem; --fs-small: 0.875rem; --fs-body: 1rem; --fs-prose: 1.1875rem; --fs-title: 1.75rem; --fs-name: 1.75rem; --fs-display: 2.5rem;   /* old names, round 7 sizes */
  --type-display: 500 2.125rem/2.375rem var(--font-display);
  --type-title: 500 1.75rem/2.125rem var(--font-display);
  --type-heading: 500 1.25rem/1.625rem var(--font-display);
  --type-question: italic 400 1.25rem/1.5625rem var(--font-serif);
  --type-reading: 400 1.25rem/2rem var(--font-serif);
  --type-excerpt: 400 1.125rem/1.5rem var(--font-serif);
  --type-ui: 500 1rem/1.375rem var(--font-sans);
  --type-button: 600 1rem/1.25rem var(--font-sans);
  --type-small: 400 0.875rem/1.25rem var(--font-sans);
  --type-placeholder: 400 1rem/1.375rem var(--font-sans);
  --type-tab: 500 0.75rem/0.875rem var(--font-sans);
  --type-meta: var(--type-small);
  --type-body: var(--type-ui);
  --type-name: var(--type-title);
  --type-prose: var(--type-reading);
  --track-display: -0.015em;
  --track-title: -0.01em;
  --track-tab: 0.01em;

  /* the one number the page is built on: a ruled line */
  --line: 2rem;

  /* space: 4, 8, 12, 16, 20, 24, 32, 40, 48, 64 */
  --s4: 4px; --s8: 8px; --s12: 12px; --s16: 16px; --s20: 20px; --s24: 24px; --s32: 32px; --s40: 40px; --s48: 48px; --s64: 64px;
  --space-1: 4px; --space-2: 8px; --space-3: 16px; --space-4: 16px; --space-5: 24px; --space-6: 24px; --space-8: 40px; --space-10: 40px; --space-12: 64px;   /* legacy, read by styles.css and inline styles */
  /* a mood is a cloth, so the feeling circle and the read view's mood dot match the books (the cloths change with the theme) */
  --mood-anxious: #A26A88; --mood-sad: #7D8C9C; --mood-neutral: #8F886F; --mood-calm: #5E8A78; --mood-happy: #D3A23F;   /* the prototype's feelings */
  --gutter: 24px;
  --tap: 44px;
  --nav-h: max(49px, 3rem);   /* the tab bar grows with the phone's text size */

  /* radii: covers 3, thumbnails 8, buttons and fields 14, cards and sheets 24. --r-s and --r-m are the old names. */
  --r-xs: 3px; --r-sm: 8px; --r-md: 14px; --r-lg: 24px; --r-pill: 999px;
  --r-s: var(--r-sm); --r-m: var(--r-lg);

  /* elevation (R6 2.6). Paper lies flat; the card is the one thing that lifts. */
  --elev-1: 0 0 0 1px var(--c-line) inset, 0 1px 2px rgba(31, 26, 23, 0.06), 0 8px 24px -8px rgba(31, 26, 23, 0.10);
  --elev-2: 0 -8px 32px rgba(31, 26, 23, 0.12);
  --elev-3: 0 2px 4px rgba(31, 26, 23, 0.08), 0 24px 48px -12px rgba(31, 26, 23, 0.24);
  --book-m: 0 1px 1px rgba(31, 26, 23, 0.20), 0 6px 12px -4px rgba(31, 26, 23, 0.18);
  --book-l: 0 2px 2px rgba(31, 26, 23, 0.18), 0 12px 24px -8px rgba(31, 26, 23, 0.20);

  /* motion (v9): quick for taps and screen changes, base for sheets, slow for what travels.
     settle is how a thing arrives, paper is how it travels and leaves. Reduced motion is opacity only, at quick. */
  --quick: 160ms; --base: 320ms; --slow: 560ms;
  --ease-settle: cubic-bezier(0.22, 0.7, 0.3, 1);
  --ease-paper: cubic-bezier(0.45, 0.05, 0.3, 1);
  /* the older names, on the same three steps */
  --dur-quick: var(--quick);
  --dur-gentle: var(--base);
  --dur-land: var(--base);
  --dur-drop: var(--slow);
  --ease: var(--ease-settle);
  --ease-land: var(--ease-settle);

  --z-raised: 10; --z-nav: 100; --z-sheet: 1000; --z-toast: 1100;

  /* colour, by role */
  --c-bg: #F4F0E7;                 /* the desk */
  --c-paper: #FFFCF5;              /* the page, the sheet */
  --c-page-edge: #E6DAC3;          /* the edge of a closed book's paper: a page about nobody on patterns */
  --c-edge-line: #F7F0E1; --c-edge-line-2: #EAE1CE;   /* the paper lines between the page edges' strips */
  /* the one paper: home's today page, a page in a book, the writing page, a page read back */
  --paper-r: 3px 12px 12px 3px;
  --paper-edge: 0 1px 2px rgba(61,45,30,.06), 0 18px 30px -24px rgba(61,45,30,.45);
  --c-surface: #FFFDF8;            /* cards, nav, the keyboard strip */
  --c-field: #FFFDF8;
  --c-sunk: #F1EADC;
  --c-ink: #3D342C;                /* ui text: espresso */
  --c-ink-soft: #6F685F;           /* the second voice, stone. There is no third grey. */
  --c-write: #3D342C;              /* the writer's ink */
  --c-accent: #6F685F;             /* gold is retired: small accent text is soft ink */
  --c-accent-brand: #4F7556;       /* seals, bars, underlines: sage */
  --c-on-accent: #FFFDF8;
  --c-btn: #4F7556;                /* the one sage button */
  --c-on-btn: #FFFDF8;
  --btn-edge: 0 0 0 0 transparent; /* dark adds a hairline so the moss reads on the desk */
  --c-link: #4F7556;
  --c-ribbon: #A8472A;             /* today, and the ribbon on "me" */
  --c-tint: rgba(79, 117, 86, 0.10);
  --c-tint-strong: rgba(79, 117, 86, 0.18);
  --c-clay: #70452F;               /* 4.5:1 on the desk */
  --c-clay-brand: #9A6B51;
  --c-danger: #9E3A24;
  --c-line: #E7DFCF;               /* hairline: dividers and rules only */
  --c-line-strong: #CBBDA8;        /* grabber and shelf ground */
  --c-line-control: #8C7F6E;       /* field borders, choice rings: 3:1 */
  --c-line-art: #8A4A22;           /* the outline on a drawn book: spine, plank */
  --c-plank: #C49A6C;
  --c-rule: var(--c-line);              /* the ruled line */
  --c-margin: rgba(163, 65, 47, 0.28);  /* the margin line, a muted red */
  --c-scrim: rgba(31, 26, 23, 0.32);
  --c-focus: #4F7556;
  --c-select: rgba(214, 190, 92, 0.45); /* highlighter yellow */
  --c-bar: #F8F4EC;                /* status and nav bars */
  --c-card: #FFFDF8;               /* a page card: paper, so it follows the dark theme */
  --c-card-ink: #3D342C;
  --c-card-soft: #6F685F;
  --c-label: #FBF6EC;              /* the paper label on a cover stays paper in the dark */
  --c-label-ink: #1F1A17;
  /* the shared book's split cover: how much spine colour each half keeps, what it is mixed with, and the second initial */
  --shared-top-spine: 80%; --shared-top-mix: black; --shared-bottom-spine: 55%; --shared-bottom-mix: var(--c-paper);
  --c-shared-ink: var(--c-write); --c-shared-seam: rgba(255, 255, 255, 0.6);

  /* book cloths. A person's colour is a cloth; the name sits on a paper label, so it never needs to read on the cloth */
  /* v9: the prototype's one middle band, each tuned so its name reads at 5:1 in cream or ink (--cl-ink) */
  --cloth-sage: #8E9680; --cloth-dusk: #4E6D6B; --cloth-clay: #8F5A48; --cloth-butter: #AA9067; --cloth-plum: #7C6251;
  --cloth-rose: #B18B80; --cloth-olive: #666947; --cloth-slate: #62686E; --cloth-linen: #A39170; --cloth-stamp: #2B2420;
  --spine-cream: #FAF2E2; --spine-ink: #2B231D; --spine-foil: #EEDDB8; --spine-foil-ink: rgba(43, 35, 29, 0.6);
  --c-wood: #9E7056; --c-case-back: #F1EADC;
  /* the older names stay as aliases */
  --cloth-me: var(--cloth-linen); --cloth-blue: var(--cloth-dusk); --cloth-lavender: var(--cloth-plum);
  --c-ink-on-cloth: #1F1A17;

  /* the feather's own colours, from her svg */
  --f-body-a: #FFECD0; --f-body-b: #FDCA9D; --f-line: #B76736; --f-dark: #5E2C0F;

  /* the eight stored colour ids (data untouched) land on eight cloths. The --p-* names stay: scripts and book.css use them. */
  --p-sage: var(--cloth-sage); --p-forest: var(--cloth-sage);
  --p-teal: var(--cloth-dusk); --p-navy: var(--cloth-dusk);
  --p-clay: var(--cloth-rose); --p-brick: var(--cloth-rose);
  --p-ochre: var(--cloth-butter); --p-plum: var(--cloth-plum);
  --wash: linear-gradient(180deg, var(--c-bg), var(--c-bg));

  /* paper grain is off in round 7. The name stays so the old rules that read it draw nothing. */
  --grain: none;
  --grain-opacity: 1;
  /* book cloth: a fine weave over the spine colour */
  --cloth: repeating-linear-gradient(90deg, rgba(255,255,255,0.055) 0 1px, transparent 1px 2px), var(--grain);
}

/* ---------- tokens, dark: a warm paper book in a dim room, never an inverted page ----------
   One mechanism: html.dark, set by the inline head script from nuuko_theme_preference
   and matchMedia before anything paints, and swapped live on a prefers-color-scheme change.
   The desk falls away and the paper is the lit thing. A shadow can't show on a dark desk, so what lifts
   gets a thin edge of lamplight as well. Keep --c-bg in step with themeService.js and values-night/colors.xml. */
html.light { color-scheme: light; }   /* the page's <meta name="color-scheme"> says "light dark", so a chosen light theme on a dark phone stays light */
html.dark {
  color-scheme: dark;
  --c-bg: #181310;
  --wash: radial-gradient(100% 380px at 50% 260px, rgba(120, 82, 48, 0.13), rgba(120, 82, 48, 0));   /* the lamp's pool on the desk; gone by the top edge, so it meets the status bar */
  --c-paper: #382E26;
  --c-page-edge: #B5A68C;
  --c-edge-line: #C9BDA8; --c-edge-line-2: #B4A791;
  --paper-edge: inset 0 0 0 1px rgba(255, 232, 200, 0.07), inset 0 1px 0 rgba(255, 236, 208, 0.09), 0 2px 3px rgba(0, 0, 0, 0.4), 0 22px 34px -20px rgba(0, 0, 0, 0.9);
  --c-surface: #2C241E;
  --c-field: #2C241E;
  --c-sunk: #120E0B;
  --c-ink: #F1E8DA;
  --c-ink-soft: #AFA599;
  --c-write: #EDE3D3;
  --c-accent: #AFA599;
  --c-accent-brand: #9DBBA2;
  --c-on-accent: #1B1714;
  --c-btn: #4F7556;
  --c-on-btn: #FFF9EE;
  --btn-edge: inset 0 1px 0 rgba(255, 246, 226, 0.16), 0 1px 3px rgba(0, 0, 0, 0.45);
  --c-link: #9DBBA2;
  --c-ribbon: #E09A7C;
  --c-tint: rgba(127, 160, 139, 0.14);
  --c-tint-strong: rgba(127, 160, 139, 0.24);
  --c-clay: #D4A088;
  --c-clay-brand: #B07D5E;
  --c-danger: #F0A58F;
  --c-line: #43382F;
  --c-line-strong: #665A4E;
  --c-line-control: #8E8172;
  --c-line-art: rgba(242, 235, 223, 0.42);
  --c-plank: #7A5434;
  --c-margin: rgba(232, 160, 145, 0.26);
  --c-scrim: rgba(8, 5, 3, 0.62);
  --c-focus: #9DBBA2;
  --c-select: rgba(214, 190, 92, 0.3);
  --c-bar: #1D1714;
  --c-card: #312821;
  --c-card-ink: #F1E8DA;
  --c-card-soft: #AFA599;
  --c-label: #E9DFCE;
  --shared-top-spine: 100%; --shared-top-mix: black; --shared-bottom-spine: 45%; --shared-bottom-mix: var(--c-bg);
  --c-shared-ink: var(--c-ink); --c-shared-seam: rgba(0, 0, 0, 0.35);
  /* the same books, at the same lightness so a name reads the same 5:1. Colours fade in dim light, so each cloth carries a little more chroma to look like itself */
  --cloth-sage: #8D977A; --cloth-dusk: #446F6D; --cloth-clay: #945742; --cloth-butter: #AF8F5A; --cloth-plum: #826049;
  --cloth-rose: #B6897C; --cloth-olive: #666A3C; --cloth-slate: #5B6977; --cloth-linen: #A79066;
  --cloth-stamp: #EFE6D8;
  --cloth-dusk-lit: #5E8A87; --cloth-clay-lit: #B2735D; --cloth-plum-lit: #9F7C64; --cloth-olive-lit: #818657; --cloth-slate-lit: #768593;   /* a name or number in a cloth on a dark share card (story.js) */
  --spine-foil-ink: rgba(43, 35, 29, 0.8);   /* the stamp on a light cloth, 3:1 */
  --c-wood: #7A543B; --c-case-back: #1F1814;
  --c-ink-on-cloth: #F2EBDF;
  --elev-1: 0 0 0 1px var(--c-line) inset, inset 0 1px 0 rgba(255, 236, 208, 0.05);
  --elev-2: inset 0 1px 0 rgba(255, 236, 208, 0.10), 0 -12px 40px rgba(0, 0, 0, 0.6);
  --elev-3: 0 0 0 1px var(--c-line), inset 0 1px 0 rgba(255, 236, 208, 0.08), 0 24px 48px -12px rgba(0, 0, 0, 0.7);
  --book-m: 0 1px 2px rgba(0, 0, 0, 0.5), 0 6px 12px -4px rgba(0, 0, 0, 0.6);
  --book-l: 0 2px 3px rgba(0, 0, 0, 0.5), 0 12px 24px -8px rgba(0, 0, 0, 0.7);
}

/* ---------- base and native feel ---------- */
*, *::before, *::after { box-sizing: border-box; }
html {
  background: var(--c-bg);
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior: none;
  height: 100%;
}
body {
  margin: 0; min-height: 100dvh;
  background-color: var(--c-bg); background-image: var(--grain), var(--wash); color: var(--c-ink);
  font: var(--type-body);
  -webkit-font-smoothing: antialiased;
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none;
  padding-top: var(--safe-area-inset-top, env(safe-area-inset-top, 0px));
}
input, textarea, [contenteditable], .selectable { -webkit-user-select: text; user-select: text; }
::selection { background: var(--c-select); }
a { color: inherit; text-decoration: none; }
h1, h2, h3, p, ul, figure { margin: 0; }
ul { padding: 0; list-style: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
img, svg { display: block; max-width: 100%; }
[hidden] { display: none !important; }   /* a component's display (.scrim, .btn) must not beat the hidden attribute */
:focus-visible { outline: 2px solid var(--c-focus); outline-offset: 2px; }
@media (hover: none) { a:hover, button:hover { opacity: 1; } }
/* reduced motion: nothing travels and nothing loops. Whatever arrived by moving fades in at quick instead
   (the list under "motion" below); a state change only fades what fades, never moves */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: var(--quick) !important; animation-delay: 0s !important; animation-iteration-count: 1 !important; transition-duration: var(--quick) !important; transition-delay: 0s !important; transition-property: opacity !important; scroll-behavior: auto !important; }
}

/* ---------- type classes ---------- */
.t-display { font: var(--type-display); letter-spacing: var(--track-display); }
.t-title { font: var(--type-title); letter-spacing: var(--track-title); overflow-wrap: anywhere; }
.t-name { font: var(--type-name); letter-spacing: var(--track-title); }
.t-prose { font: var(--type-prose); color: var(--c-write); }
.t-question { font: var(--type-question); color: var(--c-ink-soft); }
.t-body { font: var(--type-body); }
.t-small { font: var(--type-small); color: var(--c-ink-soft); }
.t-meta { font: var(--type-meta); color: var(--c-ink-soft); }
.t-serif { font-family: var(--font-serif); }

/* ---------- pressed state: every control answers the finger ---------- */
.press { transition: transform var(--dur-quick) var(--ease), background-color var(--dur-quick) var(--ease), opacity var(--dur-quick) var(--ease); }
.press:active { transform: scale(0.97); }

/* ---------- buttons: one moss button per screen (52 tall, a pill), links, ghost ---------- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--s8); min-height: 48px; padding: 0 var(--s24); border: 1px solid transparent; border-radius: var(--r-md); font: var(--type-ui); text-align: center; overflow-wrap: anywhere; }   /* a name in a button wraps at a big text size */
.btn-primary { display: flex; align-items: center; justify-content: center; width: 100%; min-height: 52px; border-radius: var(--r-pill); background: var(--c-btn); color: var(--c-on-btn); box-shadow: var(--btn-edge); font: var(--type-button); transition: opacity var(--dur-quick) var(--ease); }
.btn-primary:active { opacity: 0.88; }
.btn-ghost { background: var(--c-tint); color: var(--c-ink); }
.btn-ghost:active { background: var(--c-tint); }
.btn-link { display: inline-flex; align-items: center; min-height: var(--tap); padding: 0 var(--s8); color: var(--c-link); font: var(--type-ui); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.btn-block { width: 100%; }
/* the small way out, under a sheet's one loud button */
.sheet > .btn-link { display: flex; justify-content: center; width: 100%; margin-top: var(--s8); }
.sheet > .where { margin: var(--s16) 0 0; }
.btn-icon { width: var(--tap); height: var(--tap); border-radius: 50%; display: grid; place-items: center; color: var(--c-ink-soft); }
.btn-icon:active { background: var(--c-tint); }
.btn-icon svg { width: 24px; height: 24px; }

/* ---------- chips: a word you can pick, with a tick, never colour alone ---------- */
.chips { display: flex; flex-wrap: wrap; gap: var(--s8); }
.chip, .person-chip { display: inline-flex; align-items: center; gap: var(--s8); min-height: var(--tap); padding: 0 var(--s16); border-radius: var(--r-pill); border: 1px solid var(--c-line-control); color: var(--c-ink); font: var(--type-small); background: transparent; cursor: pointer; transition: background-color var(--dur-quick) var(--ease); }
.person-chip { font-family: var(--font-serif); font-size: var(--fs-body); }   /* a handle is serif, as typed */
.chip:active, .person-chip:active { background: var(--c-tint); }
.chip[aria-pressed="true"], .person-chip.is-on { background: var(--c-tint-strong); border-color: transparent; color: var(--c-ink); font-weight: 600; }
.chip .tick { width: 16px; height: 16px; color: var(--c-ink); }
.dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; background: var(--dot, var(--c-ink-soft)); flex: 0 0 auto; }

/* ---------- rows and lists: settings, a book's pages ---------- */
.row { display: flex; align-items: center; gap: var(--s16); min-height: 56px; padding: var(--s16) 0; border-bottom: 1px solid var(--c-line); color: inherit; }
.row:last-child { border-bottom: 0; }
.row .grow { flex: 1; min-width: 0; }
.row .sub { font: var(--type-small); color: var(--c-ink-soft); margin-top: 2px; }
.row .end { font: var(--type-small); color: var(--c-ink-soft); }
.row svg { width: 20px; height: 20px; color: var(--c-ink-soft); flex: 0 0 auto; }
.row:active { background: var(--c-tint); margin: 0 calc(-1 * var(--gutter)); padding-left: var(--gutter); padding-right: var(--gutter); }
.row-group { padding: 0; }
.row-head { font: var(--type-meta); color: var(--c-ink-soft); text-transform: none; padding: var(--s24) 0 var(--s8); }
html.dark .row-head { color: var(--c-ink-soft) !important; }   /* styles.css lights every dark heading */

/* a switch, drawn by the app */
.switch { width: 44px; height: 26px; border-radius: var(--r-pill); background: var(--c-line-strong); box-shadow: inset 0 0 0 1.5px var(--c-line-control); position: relative; flex: 0 0 auto; transition: background var(--dur-quick) var(--ease); }
.switch::after { content: ''; position: absolute; top: 3px; left: 3px; width: 20px; height: 20px; border-radius: 50%; background: var(--c-surface); box-shadow: var(--elev-1); transition: transform var(--quick) var(--ease-paper); }
.switch::before { content: ''; position: absolute; inset: -9px 0; }   /* 44 tall to tap, 26 to look at */
.switch[aria-checked="true"] { background: var(--c-btn); box-shadow: var(--btn-edge); }
.switch[aria-checked="true"]::after { transform: translateX(18px); background: var(--c-on-btn); }
html.dark .switch:not([aria-checked="true"])::after { background: var(--c-ink-soft); box-shadow: none; }   /* a dark knob on a dark track was hard to find */

/* ---------- card: the one thing that lifts off the desk (home) ---------- */
.card { background: var(--c-card); color: var(--c-card-ink); border-radius: var(--r-lg); padding: var(--s20); box-shadow: var(--elev-1); }

/* ---------- top bar (44): the day or a back chevron on the left, "more" (44 x 44) on the right. The older .day, .settings-btn, .back, .title still work. ---------- */
.topbar { display: flex; align-items: center; justify-content: space-between; height: var(--tap); padding: 0 var(--s4) 0 var(--gutter); }
.topbar .day, .topbar-date { font: var(--type-small); color: var(--c-ink-soft); }
.topbar-back, .topbar-more, .topbar .settings-btn { width: var(--tap); height: var(--tap); display: grid; place-items: center; color: var(--c-ink); flex: 0 0 auto; }
.topbar-back { margin-left: calc(var(--s4) - var(--gutter)); }
.topbar-back svg, .topbar-more svg, .topbar .settings-btn svg { width: 24px; height: 24px; }
.topbar-date { margin-right: auto; padding-left: var(--s8); }
.topbar .title { font: var(--type-ui); }
.topbar .title.serif { font: var(--type-heading); }
.topbar .back { display: inline-flex; align-items: center; gap: var(--s4); min-height: var(--tap); color: var(--c-ink); font: var(--type-ui); margin-left: calc(-1 * var(--s8)); padding: 0 var(--s8); }
.topbar .back svg { width: 24px; height: 24px; }

/* ---------- bottom nav: four tabs, home, write, library, patterns; 49 tall plus the safe area, the desk at 94% over a blur; hidden while typing ---------- */
/* nav.nav-bottom and .nav-bottom .nav-link are one step more specific than styles.css */
nav.nav-bottom { position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-nav); height: calc(var(--nav-h) + var(--safe-area-inset-bottom, env(safe-area-inset-bottom, 0px))); padding: 0 0 var(--safe-area-inset-bottom, env(safe-area-inset-bottom, 0px)); display: grid; grid-template-columns: repeat(4, 1fr); align-items: stretch; background: var(--c-bar); -webkit-backdrop-filter: blur(20px); backdrop-filter: blur(20px); border-top: 1px solid var(--c-line); box-shadow: none; }
.nav-bottom .nav-link { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; min-height: var(--nav-h); padding: 0; border-radius: 0; background: none; font: var(--type-tab); font-size: min(0.75rem, calc((25vw - 8px) / 4.8)); letter-spacing: var(--track-tab); color: var(--c-ink-soft); }   /* 'patterns' stays inside its quarter of the bar, 8px from the next label, at any text size */
.nav-bottom .nav-link svg { width: 24px; height: 24px; padding: 0; border-radius: 0; background: none; }
.nav-bottom .nav-link.active { background: none; color: var(--c-ink); font-weight: 500; }
.nav-bottom .nav-link.active svg { background: none; --on: currentColor; --on-cut: var(--c-bar); }
body.keyboard-open .nav-bottom { display: none; }

/* ---------- main column ---------- */
main { max-width: 42rem; margin: 0 auto; padding: var(--s16) var(--gutter) calc(var(--nav-h) + var(--s40)); }
main.has-sticky { padding-bottom: calc(var(--nav-h) + 100px); }
.sticky { position: fixed; left: 0; right: 0; bottom: calc(var(--nav-h) + var(--safe-area-inset-bottom, env(safe-area-inset-bottom, 0px))); z-index: var(--z-raised); padding: var(--s16) var(--gutter) var(--s16); background: linear-gradient(to top, var(--c-bg) 70%, transparent); }
.sticky .in { max-width: 42rem; margin: 0 auto; display: flex; gap: var(--s16); }
.sticky .btn-primary { flex: 1; }
body.keyboard-open .sticky { display: none; }

/* ---------- the paper ---------- */
.paper { position: relative; background: var(--c-paper); color: var(--c-write); }
.paper::before { content: ''; position: absolute; inset: 0; background-image: var(--grain); opacity: var(--grain-opacity); pointer-events: none; }
.paper > * { position: relative; }
.desk { position: relative; }
.desk > * { position: relative; }

/* a full-bleed page: the write screen. rules every --line, drawn on the editor itself so they scroll with the text */
.page { min-height: 100dvh; padding: var(--line) var(--gutter) calc(var(--line) * 3) var(--gutter); }
.page .salutation { font: var(--type-heading); color: var(--c-write); }
.page .date { position: absolute; top: 0; right: var(--gutter); font: var(--type-small); color: var(--c-ink-soft); line-height: var(--line); }
.ruled { background-image: linear-gradient(transparent calc(var(--line) - 10px), var(--c-rule) calc(var(--line) - 10px), var(--c-rule) calc(var(--line) - 9px), transparent calc(var(--line) - 9px)); background-size: 100% var(--line); background-position: 0 0; }
.editor { font: var(--type-prose); color: var(--c-write); min-height: calc(var(--line) * 6); outline: 0; caret-color: var(--c-write); white-space: pre-wrap; word-break: break-word; }
.editor:empty::before { content: attr(data-hint); color: var(--c-ink-soft); font-style: italic; }
.ink-new { animation: ink var(--dur-quick) var(--ease) both; }
@keyframes ink { from { opacity: 0.55; } to { opacity: 1; } }

/* the strip that sits on the keyboard */
.kstrip { position: fixed; left: 0; right: 0; bottom: var(--keyboard-h, 0px); z-index: var(--z-raised); height: 48px; display: flex; align-items: center; justify-content: space-between; padding: 0 var(--s8) 0 var(--gutter); background: var(--c-surface); border-top: 1px solid var(--c-line); }
.kstrip .who { font: var(--type-ui); color: var(--c-ink); min-height: var(--tap); display: inline-flex; align-items: center; gap: var(--s8); }
.kstrip .done { min-height: var(--tap); padding: 0 var(--s16); font: var(--type-button); color: var(--c-link); }

/* ---------- the shelf: a person is a book ---------- */
.shelf { display: flex; align-items: flex-end; gap: 5px; padding: 0 var(--s16) 0; min-height: 140px; position: relative; z-index: 1; }
/* a blank cover: a new book. The edge is 3:1 on the desk, and the plus is soft ink. */
.book-new { display: grid; place-items: center; border: 0; border-radius: var(--r-xs); background: var(--c-sunk); color: var(--c-ink-soft); box-shadow: inset 0 0 0 1px var(--c-line-control), var(--book-m); }

/* a book, open: two pages on the desk (home) */
/* the leaves under it show as two pale edges at the foot, and the gutter is a soft fold, not a line */
.book { position: relative; display: grid; grid-template-columns: 1fr 1fr; border-radius: var(--r-s); box-shadow: -2px 2px 0 -1px var(--c-paper), -3px 3px 0 -1px var(--c-line-strong), 2px 2px 0 -1px var(--c-paper), 3px 3px 0 -1px var(--c-line-strong), -4px 5px 0 -2px var(--c-paper), -5px 6px 0 -2px var(--c-line-strong), 4px 5px 0 -2px var(--c-paper), 5px 6px 0 -2px var(--c-line-strong), -6px 8px 0 -3px var(--c-paper), -7px 9px 0 -3px var(--c-line-strong), 6px 8px 0 -3px var(--c-paper), 7px 9px 0 -3px var(--c-line-strong), var(--elev-1); overflow: hidden; background: var(--c-paper); }
.book::after { content: ''; position: absolute; top: 0; bottom: 0; left: 50%; width: 48px; margin-left: -24px; background: linear-gradient(to right, transparent, rgba(61,52,44,0.06) 30%, rgba(61,52,44,0.16) 46%, rgba(61,52,44,0.30) 50%, rgba(61,52,44,0.13) 54%, rgba(61,52,44,0.05) 70%, transparent); pointer-events: none; }
html.dark .book::after { background: linear-gradient(to right, transparent, rgba(0,0,0,0.12) 30%, rgba(0,0,0,0.32) 46%, rgba(0,0,0,0.55) 50%, rgba(0,0,0,0.28) 54%, rgba(0,0,0,0.10) 70%, transparent); }
.book .leaf { padding: var(--s16) var(--s16) var(--s24); position: relative; min-height: 200px; }
.book .leaf.left { box-shadow: inset -30px 0 34px -26px rgba(61,52,44,0.32), inset 6px 0 8px -6px rgba(61,52,44,0.18); }
.book .leaf.right { box-shadow: inset 30px 0 34px -26px rgba(61,52,44,0.32), inset -6px 0 8px -6px rgba(61,52,44,0.18); }
.book .leaf::before { content: ''; position: absolute; inset: 0; background-image: var(--grain); opacity: var(--grain-opacity); pointer-events: none; }
.book .leaf > * { position: relative; }

/* ---------- the paper sheet: a page of rows on the desk. Date in a 56px left margin, hairlines between rows ---------- */
.paper-sheet { position: relative; background: var(--c-paper); border-radius: var(--r-s); box-shadow: inset 0 0 0 1px var(--c-line); overflow: hidden; }
.paper-sheet::before { content: ''; position: absolute; inset: 0; background-image: var(--grain); opacity: var(--grain-opacity); pointer-events: none; }
.paper-sheet > * { position: relative; }
.paper-sheet .sheet-row { display: block; position: relative; min-height: 56px; padding: var(--s16) var(--s16) var(--s16) calc(var(--s16) + 2.5rem); border-top: 1px solid var(--c-line); font: var(--type-excerpt); color: var(--c-write); }
.paper-sheet .sheet-row:first-child { border-top: 0; }
.paper-sheet .sheet-row .date { position: absolute; left: var(--s16); top: var(--s16); font: var(--type-small); color: var(--c-ink-soft); }

/* ---------- motion: the drawing drops into the book while the screen and its title arrive; else a quick fade ---------- */
@keyframes drop { from { transform: translateY(-10px); } }   /* it settles, it doesn't fall */
@keyframes title-rise { from { transform: translateY(8px); opacity: 0; } }
@keyframes fade { from { opacity: 0; } }
.drop { animation: drop var(--dur-drop) var(--ease-land) both; }
.title-rise { animation: title-rise var(--base) var(--ease-settle) var(--quick) both; }
.fade { animation: fade var(--dur-quick) var(--ease) both; }

@media (prefers-reduced-motion: reduce) {
  .drop, .title-rise, .sheet, .toast, .cover, .deck-card.is-on :is(.a-rise, .a-grow, .a-grow-x, .a-slide, .a-pop, .a-draw) { animation-name: fade !important; }
  .feather img.on, [data-loop="shelf"] { animation: none !important; }
  .press:active { transform: none; }
}

/* ---------- bottom sheet: slides up on paper, 24 radius and 24 padding, a grabber, over a scrim that fades.
   It leaves the way it came, at quick (filing.js) ---------- */
.scrim:not([hidden]) { animation: fade var(--base) var(--ease-settle) both; }
.scrim { position: fixed; inset: 0; z-index: var(--z-sheet); background: var(--c-scrim); display: flex; align-items: flex-end; justify-content: center; }
.sheet { width: 100%; max-width: 42rem; background: var(--c-paper); border-radius: var(--r-lg) var(--r-lg) 0 0; padding: var(--s24) var(--s24) calc(var(--s24) + var(--safe-area-inset-bottom, env(safe-area-inset-bottom, 0px))); box-shadow: var(--elev-2); max-height: 92dvh; overflow-y: auto; animation: sheet-up var(--base) var(--ease-settle) both; }
.sheet .grip { width: 36px; height: 5px; border-radius: 2.5px; background: var(--c-line-strong); margin: calc(var(--s8) - var(--s24)) auto var(--s16); }
@keyframes sheet-up { from { transform: translateY(48px); opacity: 0; } to { transform: none; opacity: 1; } }
.toast { position: fixed; left: var(--gutter); right: var(--gutter); bottom: calc(var(--nav-h) + var(--s16)); z-index: var(--z-toast); background: var(--c-ink); color: var(--c-bg); padding: var(--s16) var(--s16); border-radius: var(--r-sm); font: var(--type-small); color: var(--c-bg); text-align: center; animation: rise var(--quick) var(--ease-settle) both; }
html.dark .toast { background: var(--c-line); color: var(--c-ink); box-shadow: inset 0 0 0 1px rgba(255, 236, 208, 0.12), 0 8px 24px -6px rgba(0, 0, 0, 0.7); }   /* a bright bar would be the brightest thing in the room */
@keyframes rise { from { transform: translateY(6px); opacity: 0; } to { transform: none; opacity: 1; } }

/* ---------- screen changes: a short cross-fade, where the webview has it.
   Not a rise on the new page: a 300 ms rise kept the transition alive long enough for the next navigation to abort it (smoke-return). ---------- */
@view-transition { navigation: auto; }
/* every page agrees (one that opts in while the next opts out aborts with an InvalidStateError): reduced motion opts
   out here, and the new page fades in at quick instead (body, below), so a page change is never an instant swap.
   A fade-through at quick: the old page leaves on paper, the new one arrives on settle half of quick (80 ms) later */
@media (prefers-reduced-motion: reduce) { @view-transition { navigation: none; } body { animation: fade var(--quick) var(--ease-settle) both; } }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: var(--quick); }
::view-transition-old(root) { animation-timing-function: var(--ease-paper); }
::view-transition-new(root) { animation-timing-function: var(--ease-settle); animation-delay: calc(var(--quick) / 2); animation-fill-mode: both; }   /* a fade-through: the old page is mostly gone before the new one comes, so they are never seen on top of each other */
/* today's page on home and the page on write share one name, so going between them the card grows into
   the page and shrinks back into the card (Chromium 126+; older webviews get pageTransition.js's fade).
   The card's picture goes at quick while the page's comes in from the start, so no frame is bare paper */
::view-transition-group(book) { animation-duration: var(--slow); animation-timing-function: var(--ease-settle); }
::view-transition-old(book), ::view-transition-new(book) { height: 100%; object-fit: none; object-position: top left; }   /* never scaled: the box grows and the page shows more of itself */
::view-transition-old(book) { animation-duration: var(--quick); animation-timing-function: var(--ease-paper); }
::view-transition-new(book) { animation-duration: var(--base); animation-timing-function: var(--ease-settle); }

/* ---------- the character: one of her illustrations per screen, set by feather.js; it floats a little, and holds still for reduced motion ---------- */
.feather { width: 96px; height: 96px; position: relative; }
.feather.small { width: 56px; height: 56px; }
.feather.hero { width: 160px; height: 160px; }
.feather img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; opacity: 0; transition: opacity var(--base) var(--ease-settle); }
.feather img.on { opacity: 1; animation: float 6s ease-in-out infinite; }
html.dark .feather img, html.dark .ob-art, html.dark .empty img, html.dark .care-feather { filter: brightness(.93); }   /* her art, in the same dim light as the page */
@keyframes float { 50% { transform: translateY(-3px); } }
/* her art, breathing: a slow sway for the awake poses, a slow breathe for the sleeping one. One <img> each,
   [data-loop] names the slot so a real animated loop can replace the src later. Holds still for reduced motion. */
[data-loop] { transform-origin: 50% 100%; }
[data-loop="shelf"] { animation: sway 5s ease-in-out infinite; }   /* welcome.css times its own */
[data-loop="shelf"][src*="sleeping"] { animation: breathe 4s ease-in-out infinite; }
@keyframes sway { 0%, 100% { transform: rotate(-1.2deg) translateY(0); } 50% { transform: rotate(1.2deg) translateY(-4px); } }
@keyframes breathe { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.025); } }

/* ---------- the eight stored colour ids on cloths (data untouched). people.js colourClass emits these ---------- */
.book-color-green { --person: var(--cloth-sage); }
.book-color-deepteal { --person: var(--cloth-olive); }      /* anxious */
.book-color-slate { --person: var(--cloth-dusk); }          /* calm */
.book-color-navy { --person: var(--cloth-slate); }          /* sad */
.book-color-clay { --person: var(--cloth-clay); }
.book-color-burgundy { --person: var(--cloth-rose); }       /* happy */
.book-color-cream { --person: var(--cloth-butter); }
.book-color-espresso { --person: var(--cloth-plum); }

/* ---------- round 7 components. Fixed sizes, nothing scaled. ---------- */

/* a cloth: [data-cloth] sets --cl for covers, dots and anything else drawn in a cloth */
[data-cloth="sage"] { --cl: var(--cloth-sage); } [data-cloth="dusk"] { --cl: var(--cloth-dusk); } [data-cloth="clay"] { --cl: var(--cloth-clay); }
[data-cloth="butter"] { --cl: var(--cloth-butter); } [data-cloth="plum"] { --cl: var(--cloth-plum); } [data-cloth="rose"] { --cl: var(--cloth-rose); }
[data-cloth="olive"] { --cl: var(--cloth-olive); } [data-cloth="slate"] { --cl: var(--cloth-slate); } [data-cloth="linen"] { --cl: var(--cloth-linen); }
[data-cloth="stamp"] { --cl: var(--cloth-stamp); }
/* a name on a cloth: cream on the darker cloths, ink on the lighter ones (5:1 either way), the icon in foil */
[data-cloth] { --cl-ink: var(--spine-cream); --cl-foil: var(--spine-foil); }
[data-cloth="butter"], [data-cloth="rose"], [data-cloth="sage"], [data-cloth="linen"] { --cl-ink: var(--spine-ink); --cl-foil: var(--spine-foil-ink); }

/* ---------- the bookcase (v9): a wooden case of cubbies, books standing as spines. shelf.js draws it ---------- */
.case { position: relative; padding: 6px 6px 0; border-radius: 4px; background: var(--wood-v), linear-gradient(90deg, rgba(255,255,255,.05), rgba(0,0,0,0) 30%, rgba(0,0,0,.05)), var(--c-wood); box-shadow: inset 0 1px 0 rgba(255,255,255,.14), 0 1px 2px rgba(61,40,25,.10), 0 18px 30px -22px rgba(61,40,25,.45); }
.case { --wood-v: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='420' height='420'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.28 0.006' numOctaves='3' seed='3'/%3E%3CfeColorMatrix values='0 0 0 0 .22  0 0 0 0 .12  0 0 0 0 .06  1.6 0 0 0 -.62'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)' opacity='.55'/%3E%3C/svg%3E"); --wood-h: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='420' height='420'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.006 0.28' numOctaves='3' seed='7'/%3E%3CfeColorMatrix values='0 0 0 0 .22  0 0 0 0 .12  0 0 0 0 .06  1.6 0 0 0 -.62'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)' opacity='.55'/%3E%3C/svg%3E"); }
.cubby { position: relative; display: flex; align-items: flex-end; gap: 2px; height: 144px; padding: 0 11px; background: linear-gradient(180deg, rgba(70,45,25,.17) 0, rgba(70,45,25,.05) 16px, rgba(70,45,25,0) 34px), linear-gradient(90deg, rgba(70,45,25,.10), rgba(70,45,25,0) 12px, rgba(70,45,25,0) calc(100% - 12px), rgba(70,45,25,.10)), radial-gradient(ellipse 80% 70% at 50% 45%, rgba(255,252,244,.55), rgba(255,252,244,0)), var(--c-case-back); }
/* at night: the board above throws its shadow, the lamp warms the back a little, and the wood catches the light along its top edge */
html.dark .case { box-shadow: inset 0 1px 0 rgba(255, 226, 190, .20), 0 0 0 1px rgba(0, 0, 0, .35), 0 22px 34px -20px rgba(0, 0, 0, .9); }
html.dark .cubby { background: linear-gradient(180deg, rgba(0,0,0,.42) 0, rgba(0,0,0,0) 26px), linear-gradient(90deg, rgba(0,0,0,.24), rgba(0,0,0,0) 12px, rgba(0,0,0,0) calc(100% - 12px), rgba(0,0,0,.24)), radial-gradient(ellipse 85% 75% at 50% 55%, rgba(224, 170, 110, .07), rgba(224, 170, 110, 0)), var(--c-case-back); }
html.dark .cubby::after { background: linear-gradient(0deg, rgba(0,0,0,.4), rgba(0,0,0,0)); }
html.dark .case .board { background: var(--wood-h), linear-gradient(180deg, rgba(255, 226, 190, .24) 0 1px, transparent 1px), var(--c-wood); box-shadow: 0 1px 0 rgba(0, 0, 0, .5); }
html.dark .cubby .vase { filter: brightness(.78); }
.cubby::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 5px; background: linear-gradient(0deg, rgba(50,30,15,.16), rgba(50,30,15,0)); pointer-events: none; }
.case .board { height: 8px; margin: 0 -6px; background: var(--wood-h), linear-gradient(180deg, rgba(255,255,255,.10) 0 1px, transparent 1px), var(--c-wood); box-shadow: 0 1px 0 rgba(40,25,15,.10); }
.case .board:last-child { height: 10px; border-radius: 0 0 4px 4px; }
.cubby .vase { margin: 0 14px 0 auto; width: 44px; height: auto; }
.cubby .shelf-more { align-self: center; margin-left: auto; padding: 0 var(--s8); min-height: var(--tap); min-width: var(--tap); justify-content: center; box-sizing: border-box; display: flex; align-items: center; border-radius: var(--r-pill); background: var(--c-paper); box-shadow: inset 0 0 0 1px var(--c-line-control), 0 1px 2px rgba(50,30,15,.2); font: 600 var(--fs-small)/1 var(--font-sans); color: var(--c-ink); text-decoration: none; }

/* a spine: its cloth, a soft round, the 2px page edge on top, the icon in foil and the name down it. --w grows with the pages */
.spine { position: relative; flex: none; width: var(--w); height: var(--h); padding: 0; border-radius: 2px 2px 1.5px 1.5px; color: var(--cl-ink); background: linear-gradient(90deg, rgba(40,25,15,.16), rgba(255,255,255,.04) 20%, rgba(255,255,255,0) 48%, rgba(40,25,15,.03) 80%, rgba(40,25,15,.17)), repeating-linear-gradient(0deg, rgba(255,255,255,.018) 0 1px, transparent 1px 3px), repeating-linear-gradient(90deg, rgba(0,0,0,.02) 0 1px, transparent 1px 3px), var(--cl); box-shadow: inset 0 0 0 .5px rgba(30,20,12,.18), inset 0 1.5px 0 rgba(255,255,255,.10), 1px 0 1px rgba(30,20,12,.10); }
.spine::before { content: ''; position: absolute; left: 1px; right: 1px; top: 0; height: 2px; background: #F4EBDA; box-shadow: 0 .5px 0 rgba(30,20,12,.22); }
.spine::after { content: ''; position: absolute; top: 0; bottom: 0; left: -1px; right: -1px; }   /* a tap opens the book it lands on, so a thin book reaches no further than the gap beside it */
.cubby > .spine:first-child::after { left: -11px; }
.spine:not(:has(+ .spine))::after { right: -10px; }   /* the shelf's ends have room to give */
.spine-icon { position: absolute; left: 0; right: 0; top: 10px; display: flex; justify-content: center; color: var(--cl-foil); opacity: .6; }
.spine-icon svg { width: 13px; height: 13px; }
/* a page's day, in a book (book.css) and opened on its own (write.css): their words stay the biggest thing on it */
.leaf-date { padding-right: var(--s40); font: var(--type-heading); color: var(--c-write); }   /* clear of the ribbon */

/* the front of a closed book (v9, NuukoCover.front): a person's book page, and the onboarding's dress preview */
.front { position: relative; display: block; width: 240px; height: 331px; }
/* the page under the cover is plain paper, so the book opens onto a page; only the 4px of edge past the board is ruled (her note, 8 Nov) */
.front-pages { position: absolute; left: 10px; right: -4px; top: 4px; bottom: -4px; border-radius: 2px 3px 3px 2px; background: linear-gradient(var(--c-paper), var(--c-paper)) 0 0 / calc(100% - 4px) calc(100% - 4px) no-repeat, repeating-linear-gradient(0deg, #F7F0E1 0 1px, #EAE1CE 1px 2px); box-shadow: 0 18px 30px -14px rgba(61,45,30,.38), 0 2px 4px rgba(61,45,30,.10); }
html.dark .front-pages { background: linear-gradient(var(--c-paper), var(--c-paper)) 0 0 / calc(100% - 4px) calc(100% - 4px) no-repeat, repeating-linear-gradient(0deg, #C9BDA8 0 1px, #B4A791 1px 2px); box-shadow: 0 22px 36px -14px rgba(0,0,0,.85), 0 2px 4px rgba(0,0,0,.5); }
.front-board { position: absolute; inset: 0; overflow: hidden; border-radius: 2px 7px 7px 2px; transform-origin: left center; color: var(--cl-ink); background: linear-gradient(90deg, rgba(30,20,12,.20) 0, rgba(30,20,12,.04) 13px, rgba(255,255,255,.08) 16px, rgba(255,255,255,0) 30px), linear-gradient(165deg, rgba(255,255,255,.07), rgba(30,20,12,.08)), repeating-linear-gradient(0deg, rgba(255,255,255,.018) 0 1px, transparent 1px 3px), repeating-linear-gradient(90deg, rgba(0,0,0,.02) 0 1px, transparent 1px 3px), var(--cl); box-shadow: inset 0 0 0 .5px rgba(30,20,12,.2), 0 1px 2px rgba(30,20,12,.12); }
html.dark .front-board { box-shadow: inset 0 0 0 .5px rgba(255, 236, 208, .16), inset 0 1px 0 rgba(255, 236, 208, .10), 0 1px 3px rgba(0, 0, 0, .5); }
.front-board::before { content: ''; position: absolute; left: 14px; top: 0; bottom: 0; width: 1px; background: rgba(30,20,12,.16); }
.front-stamp { position: absolute; left: 14px; right: 0; top: 26%; display: flex; justify-content: center; color: var(--cl-foil); opacity: .92; }
.front-stamp svg { width: 57px; height: 57px; }
.front-name { position: absolute; left: 14px; right: 0; top: calc(26% + 78px); padding: 0 var(--s12); text-align: center; font: italic 500 2.125rem/1.1 var(--font-serif); overflow-wrap: anywhere; }
.front-under { position: absolute; left: 14px; right: 0; top: calc(26% + 124px); text-align: center; font: 600 12px var(--font-sans); letter-spacing: .18em; }
.spine .spine-name { color: var(--cl-ink) !important; }   /* styles.css 'html.dark button span' is important too */
.spine-name { position: absolute; left: 0; right: 0; top: 32px; bottom: 12px; display: flex; justify-content: center; align-items: center; writing-mode: vertical-rl; font: italic 600 18px/1 var(--font-serif); letter-spacing: .01em; white-space: nowrap; overflow: hidden; }
.spine-name.is-long { font-size: 15px; }
.spine-name.is-short { font-size: 22px; }   /* K and jo, easy to miss at 18 */
.spine-name > span { min-width: 0; min-height: 0; overflow: hidden; text-overflow: ellipsis; }   /* a name too long for its spine ends in "...", never cut at both ends */
/* neighbours part by a sliver of shadow and a thin edge, and the page tops are in the same dim light as the rest of the room */
html.dark .spine { box-shadow: inset 0 0 0 .5px rgba(255, 236, 208, .12), inset 0 1.5px 0 rgba(255, 255, 255, .10), 1px 0 2px rgba(0, 0, 0, .55); }
html.dark .spine::before { background: #CDBFA8; }
.spine.distant { filter: saturate(.5); }
html.dark .spine.distant { filter: saturate(.78); }   /* the months keep their differences in dim light */
.spine-new { position: relative; flex: none; width: 30px; height: 114px; margin-left: 6px; padding: 0; border: 1.5px solid var(--c-ink-soft); border-radius: 2px; color: var(--c-ink); background: var(--c-paper); }
.spine-new::after { content: ''; position: absolute; left: -4px; right: -10px; top: 0; bottom: 0; }   /* 44 to tap, clear of the book beside it */
.spine-new span { position: absolute; inset: 12px 0; display: flex; justify-content: center; align-items: center; writing-mode: vertical-rl; font: italic 600 15px/1 var(--font-serif); white-space: nowrap; }

/* field: 52 tall, 14 radius, the edge is 3:1, a 1.5px moss edge on focus (drawn inside, so nothing moves) */
.field { display: block; width: 100%; height: 52px; padding: 0 var(--s16); border: 0; border-radius: var(--r-md); background: var(--c-paper); color: var(--c-ink); font: var(--type-ui); box-shadow: inset 0 0 0 1px var(--c-line-control); -webkit-appearance: none; appearance: none; }
.field::placeholder { font: var(--type-placeholder); color: var(--c-ink-soft); opacity: 1; }
.field::placeholder, .kinds-sheet-handle input::placeholder { font-size: min(1rem, 5.6vw); }   /* at a big text size the hint is smaller, so it is not cut */
.field:focus, .field:focus-visible { outline: none !important; box-shadow: inset 0 0 0 1.5px var(--c-link) !important; }   /* styles.css 278 and 7755 draw their own rings, so one ring needs the !important */

/* choice: a 48 row with a 22 ring. On is a moss ring with a dot. Two columns, 159 wide with 24 between. */
.choices { display: flex; flex-wrap: wrap; column-gap: var(--s24); max-width: 342px; }
.choices .choice { flex: 1 1 9rem; }   /* two across, and a word too long for its half at a big text size takes its own line (a grid's rem column can't grow with it) */
.choice { display: flex; align-items: center; gap: var(--s12); min-height: 48px; text-align: left; font: var(--type-ui); color: var(--c-ink-soft); }
.choice::before { content: ''; flex: 0 0 22px; width: 22px; height: 22px; box-sizing: border-box; border-radius: 50%; border: 1.5px solid var(--c-line-control); }
.choice[aria-pressed="true"] { color: var(--c-ink); }
.choice[aria-pressed="true"]::before { border-color: var(--c-link); background: radial-gradient(circle, var(--c-paper) 0 4px, var(--c-btn) 4.5px); }


/* a page as a slip: the day number on paper, three rules under it (a book, and home's look back) */
/* three 2px rules under the day number: 48, 48 and 32 wide */
.slip { position: relative; display: flex; flex-direction: column; min-height: 128px; padding: var(--s8) 10px var(--s12); border-radius: 3px; box-shadow: var(--elev-1); background: var(--c-paper); color: var(--c-ink); text-align: left; text-decoration: none; }
.slip b { font: var(--type-heading); color: var(--c-ink); }
.slip-who { display: flex; align-items: center; gap: var(--s4); min-width: 0; margin-top: 2px; font: var(--type-meta); color: var(--c-ink); }
.slip-who i { flex: none; width: 6px; height: 13px; border-radius: 1px 2px 2px 1px; background: var(--person); }
.slip-who span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--c-ink) !important; }   /* styles.css 'html.dark button span' is important too */
.slip-line { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; margin-top: var(--s4); font: 400 var(--fs-small)/1.3 var(--font-serif); color: var(--c-ink-soft) !important; }

/* cloth dot: 32 in a 44 hit; the chosen one wears a 40 ring */
.cloth-dot { position: relative; width: 44px; height: 44px; display: grid; place-items: center; }
.cloth-dot::before { content: ''; width: 32px; height: 32px; border-radius: 50%; background: var(--cl, var(--cloth-sage)); box-shadow: inset 0 0 0 1px var(--c-line-control); }   /* a colour that means something needs its own 3:1 edge on the desk */
.cloth-dot::after { content: ''; position: absolute; inset: 2px; border-radius: 50%; border: 1.5px solid var(--c-ink); display: none; }
.cloth-dot[aria-checked="true"]::after { display: block; }

/* feeling circle: 44, the picked one gets a 52 ring and shows its word */
.feel { position: relative; flex: 0 0 44px; width: 44px; height: 44px; border-radius: 50%; background: var(--cl, transparent); box-shadow: inset 0 0 0 1px var(--c-line-control); }
.feel[data-feel="anxious"] { --cl: var(--mood-anxious); } .feel[data-feel="sad"] { --cl: var(--mood-sad); } .feel[data-feel="neutral"] { --cl: var(--mood-neutral); }
.feel[data-feel="calm"] { --cl: var(--mood-calm); } .feel[data-feel="happy"] { --cl: var(--mood-happy); }
.feel[aria-pressed="true"]::after, .feel[aria-checked="true"]::after { content: ''; position: absolute; inset: -4px; border-radius: 50%; border: 1.5px solid var(--c-ink); }
.feel-word { display: none; position: absolute; top: calc(100% + var(--s8)); left: 50%; transform: translateX(-50%); white-space: nowrap; font: var(--type-small); color: var(--c-ink-soft); }
.feel[aria-pressed="true"] .feel-word, .feel[aria-checked="true"] .feel-word, .feels:not(:has([aria-pressed="true"], [aria-checked="true"])) .feel-word { display: block; }   /* every word shows until the first pick, so colour never carries the meaning alone */

/* care surface: the one modal card, 342 wide at most */
.care-surface { width: 100%; max-width: 342px; padding: var(--s24); border-radius: var(--r-lg); background: var(--c-paper); color: var(--c-ink); box-shadow: var(--elev-3); }
/* the card (scripts/care.js) and the same lines on settings share .care-lines: no bar, left aligned, links underlined in ink with a 44px tap */
.filing.care { container-type: size; background: var(--c-scrim); backdrop-filter: none; -webkit-backdrop-filter: none; }
.care .care-surface { max-height: 100%; overflow-y: auto; text-align: left; }
.care .care-feather { display: block; width: 96px; height: 96px; margin: 0 0 var(--s16); }
.care .filing-kicker { margin: 0 0 var(--s8); font: var(--type-small); color: var(--c-ink-soft); animation: none; }
.care .filing-line { margin: 0 0 var(--s12); font: var(--type-heading); letter-spacing: 0; color: var(--c-ink); animation: none; }
.care .care-text { margin: 0 0 var(--s12); font: var(--type-small); color: var(--c-ink-soft); }
.care .filing-line + .care-text { font: var(--type-ui); color: var(--c-ink); }
.care .filing-actions { margin-top: var(--s16); animation: none; }
.care-lines { list-style: none; display: flex; flex-direction: column; gap: var(--s8); margin: 0 0 var(--s12); padding: 0; text-align: left; font: var(--type-small); }
.care-lines li { margin: 0; padding: 0; border: 0; font: var(--type-small); color: var(--c-ink); }
.care .care-lines li:first-child { font: var(--type-ui); }
.care-lines a { display: inline-block; padding-block: 12px; margin-block: -12px; padding-inline: 10px; margin-inline: -10px; color: var(--c-ink); font-weight: 500; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
/* little room or big text: no drawing, a tighter card and 1.5 times the type at most, so the helpline is on the screen without a scroll */
@container (max-height: 36rem) {
  .care .care-feather { display: none; }
  .care .care-surface { padding: var(--s16) var(--s24); }
  .care .filing-line { font-size: min(1.25rem, 26px); }
  .care .filing-line + .care-text, .care .care-lines li:first-child { font-size: min(1rem, 24px); line-height: 1.3; }
}

/* empty state: the drawing, one line, one button (library, patterns) */
.empty { display: flex; flex-direction: column; align-items: center; text-align: center; gap: var(--s24); max-width: none; margin: 0; padding: var(--s48) 0 0; }
.empty img { width: 240px; height: auto; }
.empty p { font: var(--type-title); letter-spacing: var(--track-title); color: var(--c-ink); }
.empty .btn-primary { width: 100%; max-width: 342px; }

/* ui icons: <svg class="icon"><use href="assets/icons/ui.svg#search"/></svg> */
.icon { width: 24px; height: 24px; flex: 0 0 auto; }

/* ---------- stopgaps for old rules that assume a cream card or a gold pill. Delete each when its page is rebuilt (home, library, book) ---------- */
html.dark .kicker, html.dark .lib-latest small, html.dark .lib-date { color: var(--c-card-soft); }   /* home.css 17, library.css 72 hard-code a dark gold */
body .cover .front { color: var(--c-ink-on-cloth); text-shadow: none; }   /* book.css 39: a gold initial, unreadable on a light cloth */

/* the new book screen: full screen, back at the top, the cover live, then cloth, name, who they are, and the button at the foot */
.add-screen { position: fixed; inset: 0; z-index: var(--z-sheet); display: flex; flex-direction: column; overflow-y: auto; padding-top: var(--safe-area-inset-top, env(safe-area-inset-top, 0px)); background: var(--c-bg); }
.add-body { flex: 1; display: flex; flex-direction: column; width: 100%; max-width: 390px; margin: 0 auto; padding: 16px var(--gutter) calc(24px + var(--safe-area-inset-bottom, env(safe-area-inset-bottom, 0px))); box-sizing: border-box; }
.add-cover { display: flex; justify-content: center; }
.add-cover .front { zoom: .65; }   /* the 240 front at 156 */
.add-cover.is-empty .front-name { opacity: .6; }
.cloths { display: flex; justify-content: space-between; margin: 8px -5px 0; }   /* eight 44 hits on a 342 line */
.add-body .field { margin-top: 16px; }
.add-same { margin-top: var(--s8); font: var(--type-small); color: var(--c-ink-soft); }
#addSave { margin-top: auto; }

/* ---------- onboarding (v9 prototype): welcome.html, and the first page's filed screen, dress and nudge (filing.js) ---------- */
/* a step: Nuuko and what it asks in the middle, the buttons at the foot */
.ob { display: flex; flex-direction: column; box-sizing: border-box; width: 100%; max-width: 430px; min-height: 100dvh; margin: 0 auto; padding: calc(60px + var(--safe-area-inset-top, env(safe-area-inset-top, 0px))) var(--s20) calc(var(--s40) + var(--safe-area-inset-bottom, env(safe-area-inset-bottom, 0px))); }
.ob[hidden] { display: none; }
.ob-ask { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.ob-art { display: block; width: 130px; height: auto; }
.ob-wave { width: 210px; }
.ob-bubble { position: relative; display: block; margin-top: var(--s16); padding: 15px 18px; border: 1px solid var(--c-line); border-radius: 18px; background: var(--c-card); color: var(--c-ink); font: 500 1.125rem/1.32 var(--font-sans); text-align: center; }
.ob-bubble::after { content: ''; position: absolute; left: 50%; top: -7px; width: 13px; height: 13px; margin-left: -7px; border: 1px solid var(--c-line); border-top: 0; border-right: 0; background: var(--c-card); transform: rotate(135deg); }
.ob-wave + .ob-bubble { align-self: stretch; margin: 26px 20px 0; }
.ob-soft { margin: 28px 0 0; font: italic 400 1.125rem/1.4 var(--font-serif); color: var(--c-ink-soft); text-align: center; }
.ob-ask .field { margin-top: var(--s20); height: 56px; padding: 0 18px; background: var(--c-field); box-shadow: inset 0 0 0 1.5px var(--c-link); font: 500 1.125rem/1 var(--font-sans); }
.ob-ask .field::placeholder { font: inherit; }
.ob-chips { align-self: stretch; display: flex; flex-wrap: wrap; gap: var(--s8); margin-top: var(--s12); }
.ob-chip { min-height: 40px; padding: 0 var(--s16); border-radius: var(--r-pill); background: var(--c-card); color: var(--c-ink); font: 500 0.875rem/1 var(--font-sans); white-space: nowrap; transition: background-color var(--quick) var(--ease-settle); }
.ob-chip[aria-pressed="true"] { background: var(--c-tint-strong); }
.ob-chip, .word { position: relative; }
.ob-chip::after, .word::after { content: ''; position: absolute; inset: -2px 0; }   /* 44 to tap, 40 to look at */
.ob-foot { display: flex; flex-direction: column; align-items: stretch; }
.ob-foot .ob-soft { margin: var(--s20) 0 0; font-size: 1rem; }
.ob-ghost { display: flex; align-items: center; justify-content: center; min-height: 52px; margin-top: var(--s8); border: 1px solid var(--c-line); border-radius: var(--r-pill); background: var(--c-card); color: var(--c-ink); font: var(--type-button); text-decoration: none; }
.ob-link { align-self: center; display: inline-flex; align-items: center; justify-content: center; min-height: var(--tap); margin-top: var(--s4); padding: 0 var(--s16); color: var(--c-link); font: var(--type-ui); }
/* the nudge: the hour, big, on a card */
.ob-time { align-self: stretch; margin-top: var(--s20); padding: var(--s16); border-radius: var(--r-md); background: var(--c-card); color: var(--c-ink); font: 600 3.125rem/1.1 var(--font-sans); letter-spacing: -0.03em; text-align: center; }
.ob-time small { font: 500 1.375rem/1 var(--font-sans); letter-spacing: 0; color: var(--c-ink-soft); }
.ob-time + .ob-chips { justify-content: center; gap: 6px; }   /* the four times on one line at 390 */
/* dawn: the prototype's warm light behind a hello and a filed page */
.ob-dawn { background: linear-gradient(180deg, #F3DCCB 0, #F4E6D9 300px, var(--c-bg) 620px) no-repeat, var(--c-bg); }
html.dark .ob-dawn { background: linear-gradient(180deg, #3E2C23 0, #2A201B 300px, var(--c-bg) 620px) no-repeat, var(--c-bg); }

/* ---------- a tablet held upright, 768 and wider (a phone on its side is too short to be one): the tabs stay at the foot,
   and each screen keeps to one column, so the bar, the title, the lists and the button share their edges ---------- */
@media (min-width: 768px) and (min-height: 640px) {
  :root { --col: 640px; }
  /* onboarding: Nuuko, what it asks and the buttons stand together in the middle, not at the two ends of a tall screen */
  .ob { justify-content: center; }
  .ob-ask { flex: none; }
  .ob-foot { margin-top: var(--s48); }
  .ob-art { width: 170px; }
  .ob-wave { width: 260px; }
}

/* ---------- a laptop, 1024 and wider: everything a tenth smaller, the four tabs stand in a rail down the left, under the name, and each screen's
   own sheet widens it (home.css, library.css, book.css, write.css, filing.css, welcome.css). A phone never sees this ---------- */
@media (min-width: 1024px) {
  html { zoom: 0.9; }   /* her call, 1 Nov: a laptop read best at 90% */
  /* under the zoom 100dvh is 90% of the window, so whatever fills the screen fills it by 1/0.9 */
  body, .ob { min-height: calc(100dvh / 0.9); }
  :root { --rail: 240px; --col: 760px; }   /* every screen's column: the bookcase, the lists, the paper, the button under it */
  body:has(> nav.nav-bottom) { padding-left: var(--rail); }
  nav.nav-bottom { top: 0; right: auto; width: var(--rail); height: auto; display: flex; flex-direction: column; gap: var(--s4); padding: var(--s32) var(--s16); border-top: 0; border-right: 1px solid var(--c-line); }
  nav.nav-bottom::before { content: 'nuuko'; padding: 0 var(--s16) var(--s32); font: var(--type-title); color: var(--c-ink); }
  .nav-bottom .nav-link { flex-direction: row; justify-content: flex-start; gap: var(--s12); min-height: 48px; padding: 0 var(--s16); border-radius: var(--r-pill); font: var(--type-ui); }
  .nav-bottom .nav-link.active { background: var(--c-tint); }
  body:has(> nav.nav-bottom) > nav.nav { display: none; }   /* an old page still carrying the website's top bar (circle) */
  .sticky, .kstrip { left: var(--rail); }
  .toast { left: calc(var(--rail) + var(--gutter)); }
  /* a bookcase with a few books is a small bookcase, not wide empty shelves (nothing is drawn that isn't there) */
  .case:not(:has(.cubby > :nth-child(5))) { width: fit-content; min-width: 22rem; }
  /* a sheet is a card in the middle of the column, not a drawer pulled up from the foot of a laptop */
  .scrim { align-items: center; }
  body:has(> nav.nav-bottom) .scrim { padding-left: var(--rail); }
  .sheet { max-width: 34rem; border-radius: var(--r-lg); }
  .sheet .grip { display: none; }
  /* every bar sits the same way down from the top, and a back chevron's stroke starts on the column's edge
     (the margins are where each icon draws its stroke inside its box) */
  .topbar:not(.lib-title + .topbar) { margin-top: var(--s24); }
  .topbar-back { place-items: center start; margin-left: -7px; }
  .topbar .back { margin-left: -8px; padding-left: 0; }
}

/* a laptop: an onboarding step is two columns, Nuuko large on the left, what it asks (and the buttons) on the right, the bubble's tail pointing at Nuuko */
@media (min-width: 900px) and (min-height: 640px) {
  .ob { display: grid; grid-template-columns: minmax(0, 1fr) 440px; column-gap: var(--s64); align-content: center; justify-content: center; max-width: 1080px; padding-block: var(--s40); }
  .ob-ask { display: contents; }
  .ob-ask > :not(.ob-art), .ob > .ob-foot { grid-column: 2; }
  .ob .ob-art, .filed-nudge .ob .ob-art { grid-column: 1; grid-row: 1 / span 8; align-self: center; justify-self: end; width: min(300px, 38vh); }
  .ob .ob-wave { width: min(400px, 52vh); }
  .ob .ob-bubble, .ob .ob-wave + .ob-bubble { margin: 0; padding: var(--s20) var(--s24); font-size: 1.5rem; text-align: left; }
  .ob-bubble::after { left: -7px; top: 50%; margin: -7px 0 0; transform: rotate(45deg); }
  .ob .ob-soft { margin-top: var(--s20); text-align: left; font-size: 1.25rem; }
  .ob-foot .ob-soft { font-size: 1rem; }
  .ob-ask .field { height: 64px; font-size: 1.25rem; margin-top: var(--s24); }
  .ob-chip { min-height: 44px; font-size: 1rem; }
  .ob-foot { margin-top: var(--s40); }
  .ob-foot .btn-primary, .ob-ghost { min-height: 56px; font-size: 1.0625rem; }
  .ob-foot .ob-link { align-self: flex-start; margin-left: calc(-1 * var(--s16)); }   /* on the column's edge, under the left-aligned words */
}

/* a laptop: the new book screen sits in the middle of the window */
@media (min-width: 1024px) {
  .add-body { justify-content: center; max-width: 420px; }
  #addSave { margin-top: var(--s24); }
}
