/* EPHEMERIS — an astronomer's field almanac for friendship.
   The globe is the sky; the chrome is the page: night-ink pages written in
   candlelight — cool near-black surfaces, cream Fraunces for everything
   human, Plex Mono for everything measured, dot leaders, thick-thin folio
   rules, ✦ as punctuation. (Surfaces were warm paper-brown at first; demo
   feedback: brown fights the spacey globe. The warmth lives in the INK —
   text, rules, gold — never the pages.)
   Governing rule: people get the serif, the instrument gets the mono;
   the page gets cream, the act gets gold.
   Recency colors are SEMANTIC and arrive inline from main.js — CSS never
   sets them. The only blue on screen is the Earth. */

* { margin: 0; padding: 0; box-sizing: border-box; }

@font-face {
  font-family: "Brygada 1918";
  src: url(../assets/fonts/brygada-var.woff2) format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Brygada 1918";
  src: url(../assets/fonts/brygada-italic-var.woff2) format('woff2');
  font-weight: 400 700;
  font-style: italic;
  font-display: swap;
}

:root {
  color-scheme: dark;  /* native widgets (select popups, scrollbars) render
                          dark — without this Firefox paints a white dropdown
                          under our pale option text */
  --bg:             #070b0c;                    /* page behind canvas */
  --scrim:          rgba(7, 11, 12, 0.55);        /* form/settings overlay */
  --scrim-light:    rgba(7, 11, 12, 0.35);        /* intro overlay — globe is the pitch */
  --surface:        #0f1715;                    /* cards, buttons — SOLID */
  --surface-deep:   #0b1210;                    /* sidebar (one step below cards) */
  --surface-raised: #131d1a;                    /* suggest list, prefill menu, toast */
  --ink-fill:       rgba(239, 227, 200, 0.05);  /* notes/textarea wash */
  --border:         rgba(217, 181, 108, 0.3);   /* every rule is gold: fields, keys, rows */
  --border-faint:   rgba(217, 181, 108, 0.15);  /* internal separators */
  --rule-strong:    rgba(217, 181, 108, 0.55);  /* the strong stroke of a rule */
  --text:           #efe3c8;                    /* paper cream */
  --text-dim:       #b9ac8c;                    /* faded ink */
  --text-faint:     #8b806a;                    /* pencil */
  --gold:           #d9b56c;                    /* THE accent: actions, focus, ✦ */
  --gold-dim:       rgba(217, 181, 108, 0.55);
  --gold-line:      rgba(217, 181, 108, 0.3);   /* the inner rules of arches and frames */
  --gold-faint:     rgba(217, 181, 108, 0.13);
  --gold-wash:      rgba(217, 181, 108, 0.20);  /* a gold key under the pointer */
  --teal:           #8fa88b;
  --madder:         #d49482;                    /* the warning ink: remove, take out, an error */
  --madder-faint:   rgba(212, 148, 130, 0.12);
  --madder-line:    rgba(212, 148, 130, 0.4);                    /* aurora whisper: two uses only */
  --shadow-card:    0 24px 60px -24px rgba(0, 0, 0, 0.75);
  --serif: "Brygada 1918", Georgia, serif;
  /* the thin stroke of the folio rule, drawn as a background layer so it
     stays pinned while a card's CONTENT scrolls (a positioned ::before
     inside an overflow scroller would ride away with the page) */
  --folio-thin: linear-gradient(var(--border), var(--border)) 0 1px / 100% 1px no-repeat;
  --folio-thin-gold: linear-gradient(rgba(217, 181, 108, 0.20), rgba(217, 181, 108, 0.20)) 0 1px / 100% 1px no-repeat;
}
::selection { background: rgba(143, 168, 139, 0.20); }   /* teal use 1 */

html, body {
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: var(--bg);
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-weight: 400;
  color: var(--text);
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}
button, input, select, textarea { font: inherit; }  /* no control ever falls
                                                       back to the system sans */
:focus-visible { outline: 1px solid var(--gold-dim); outline-offset: 3px; }

/* drop caps: Goudy's initials (a two-layer colour font: the letter in the
   text's cream over its ornament in gold at 60%, the woodcut reversed for the
   night), set into the first three lines of a page. Its ink fills a 1em box
   standing on the baseline (a–z draw the capitals), which leaves Brygada's
   metrics to place it: a line's baseline sits .33em below its middle and the
   capitals stand .67em, so the top lands on the first line's capitals and
   the foot on the third line's baseline. The page must run at line-height
   1.6 and be a block formatting context. js/main.js dropCapIfLong decides. */
@font-face {
  font-family: "Goudy Initials";
  src: url(../assets/fonts/goudy-initials.woff2) format('woff2');
  font-display: block;
}
.drop { --drop-lh: 1.6; --drop-lines: 3; display: flow-root; line-height: var(--drop-lh); }
.drop::first-letter {
  float: left;
  margin: calc((var(--drop-lh) / 2 + 0.33 - 0.67) / ((var(--drop-lines) - 1) * var(--drop-lh) + 0.67) * 1em) 0.1em 0 0;
  font-family: "Goudy Initials";
  font-size: calc(((var(--drop-lines) - 1) * var(--drop-lh) + 0.67) * 1em);
  font-style: normal;
  font-weight: 400;
  line-height: 1;
  color: var(--text);
}

#scene {
  display: block;
  width: 100vw;
  height: 100vh;
  touch-action: none; /* let us handle all gestures */
}

#loading {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font: italic 400 13.5px var(--serif);
  color: var(--text-faint);
  pointer-events: none;
  transition: opacity 0.5s;
}
#loading.hidden { opacity: 0; }
#loading.fallback {           /* WebGL-less browsers: readable, not a whisper */
  font: 400 15px/1.7 var(--serif);
  letter-spacing: normal;
  color: var(--text-dim);
  max-width: 26em;
  margin: 0 auto;
  padding: 0 28px;
  text-align: center;
}

/* ---- the keys over the globe: the arch belongs to the card alone
   (Augustine, 2026-10-04: "we might be overusing the arch shape"). The
   navigation keys (☰ ‹ ›) are framed plaques — a gold rule and a second
   one inside it, the pages' frame in small; the two acts (✎ your book,
   + add a friend) are medallions, the halo's circle without its rays. ---- */
#nav {
  position: fixed;
  bottom: max(16px, calc(env(safe-area-inset-bottom, 0px) + 10px));   /* +10px: clear of the gesture-nav backdrop */
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 10px;
  z-index: 20;
}
#nav button, #side-toggle, #add-btn, #write-btn {
  width: 52px;
  height: 44px;
  border: 1px solid var(--border);
  border-radius: 2px;
  outline: 1px solid var(--gold-line);
  outline-offset: -5px;
  background: rgba(15, 23, 21, 0.92);
  color: var(--text-dim);
  font-weight: 400;
  line-height: 1;
  cursor: pointer;
}
#nav button {
  display: flex;
  align-items: center;
  justify-content: center;
}
#nav button svg { width: 22px; height: 22px; }
/* under the finger the ink lifts to the raised surface (the gold and the
   press come from the button section at the end of the file) */
#nav button:active, #side-toggle:active, #add-btn:active, #write-btn:active {
  background: var(--surface-raised);
}

#side-toggle {
  position: fixed;
  bottom: max(16px, calc(env(safe-area-inset-bottom, 0px) + 10px));   /* +10px: clear of the gesture-nav backdrop */
  left: 16px;
  font-size: 18px;
  z-index: 36;
}

#add-btn, #write-btn { width: 48px; height: 48px; border-radius: 50%; outline-offset: -5px; }
#add-btn {
  position: fixed;
  right: 16px;
  bottom: max(16px, calc(env(safe-area-inset-bottom, 0px) + 10px));   /* +10px: clear of the gesture-nav backdrop */
  z-index: 20;
  font-size: 26px;
  /* the one growth action on screen — gold, a step brighter than its
     siblings (tour feedback: it blended into the star field) */
  color: var(--gold);
  border-color: var(--gold-dim);
}

/* the front door: a moment with… — the pen sits beside the +, one step
   quieter (the + is growth; the pen is the daily act, and it earns the
   gold on press) */
#write-btn {
  position: fixed;
  right: 76px;
  bottom: max(16px, calc(env(safe-area-inset-bottom, 0px) + 10px));
  z-index: 20;
  font-size: 19px;
  color: var(--text);
  border-color: var(--rule-strong);
}
#write-btn.hidden { display: none; }

/* ---- recency sidebar: the index page ---- */
#sidebar {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: min(272px, 80vw);
  z-index: 32;
  display: flex;
  flex-direction: column;
  /* bottom clears the ☰ INCLUDING its safe-area rise: the toggle sits at
     inset+10px and is ~48px tall, so the footer needs inset+68 on phones
     with gesture nav (a fixed 74px let the ☰ climb into the links) */
  padding: max(14px, env(safe-area-inset-top)) 14px
           max(74px, calc(env(safe-area-inset-bottom, 0px) + 68px));
  background: var(--surface-deep);  /* solid: the panel sits behind and
                                       would ghost through alpha */
  border-right: 1px solid transparent;
  border-image: linear-gradient(180deg, transparent, var(--gold-dim) 10%,
                var(--gold-dim) 90%, transparent) 1;
  box-shadow: 12px 0 40px -18px rgba(0, 0, 0, 0.6);
  transition: transform 0.3s cubic-bezier(.2,.8,.2,1), opacity 0.24s;
}
#sidebar.hidden { transform: translateX(-105%); opacity: 0; pointer-events: none; }
#sidebar::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  right: 4px;
  border-right: 1px solid var(--gold-line);
  pointer-events: none;
}

#side-head {
  display: flex;
  flex-wrap: wrap;            /* the title's line, then the sort trio's */
  justify-content: space-between;
  align-items: baseline;
  padding: 2px 4px 4px;
}
#side-title { font-size: 27px; font-weight: 400; line-height: 1.2; flex: 1 0 100%; }
#side-book {
  margin: 0 0 -4px -1px;
  padding: 6px 0;
  border: none;
  background: none;
  color: var(--text-dim);
  font: italic 400 13.5px var(--serif);
  cursor: pointer;
}
#side-book.hidden { display: none; }
/* The sort trio sits on its own line under the title, right-aligned, in
   readable ink: 10px faint glyphs inside 41px boxes still READ as too small
   (Augustine, 2026-09-04 — the 08-24 pass had only grown the hit areas),
   and at the size they deserve they no longer fit beside "Friends" in the
   272px drawer. Each button is a ~44px box (48dp Android guideline); the
   negative margins tuck the row under the title and hand the right edge
   back so the glyphs align with the list's numbers. */
#side-sorts { display: flex; align-items: center; gap: 2px; margin: -6px -10px -8px auto; }
#side-sort, #side-dir, #side-all {
  border: none;
  background: none;
  color: var(--text-dim);
  font: italic 400 14.5px var(--serif);
  text-transform: lowercase;
  cursor: pointer;
  padding: 14px 8px;
  line-height: 20px;
}
#side-dir, #side-all { min-width: 48px; font-size: 18.5px; padding: 14px 6px; }
#side-all.hidden { display: none; }

#side-search {
  width: 100%;
  margin-bottom: 8px;
  font-size: 14px;
}
#side-search::placeholder { color: var(--text-faint); font-style: italic; }

#side-list {
  flex: 1;
  list-style: none;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-color: rgba(239, 227, 200, 0.18) transparent;
}

#side-footer {
  display: flex;
  flex-wrap: wrap;          /* items hold together and flow as a line */
  align-items: baseline;
  gap: 4px 8px;
  padding: 8px 4px 0;
  border-top: 1px solid transparent;
  border-image: linear-gradient(90deg, transparent, var(--border-faint) 12%,
                var(--border-faint) 88%, transparent) 1;
  font: italic 400 12px var(--serif);
  text-transform: lowercase;
  color: var(--text-faint);
}
#side-footer button {
  border: none;
  background: none;
  padding: 2px 0;
  color: var(--text-faint);
  font: inherit;
  white-space: nowrap;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}
#side-footer a { white-space: nowrap; }
#side-footer a {
  color: var(--text-faint);
  text-decoration: underline;
  text-underline-offset: 3px;
}
#side-footer a:hover { color: var(--teal); }   /* teal use 2 */
#side-export.hidden { display: none; }   /* demo/native never wire it up */
#side-export-status {
  margin-left: auto;
  text-align: right;
  color: var(--text-dim);
}


/* rows read like an almanac index: Amara ······· 42d
   (the 14px left gutter hosts the hover star — a negative offset would be
   clipped by the list's scroll overflow) */
#side-list li {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  /* right 14px: Android's overlay scrollbar rides the list's right edge
     and sat on the days / section counts (Pixel, 2026-09-04) */
  padding: 8px 14px 8px 14px;
  font-size: 14px;
  cursor: pointer;
}
#side-list li:not(.sec)::before {
  content: "";
  position: absolute;
  left: 14px;
  right: 14px;
  top: 1.05em;
  border-top: 1px dotted var(--border);
}
/* the name and the number sit ON the leader; mask with the sidebar's own ink */
#side-list li:not(.sec) :is(.who, .days) {
  position: relative;
  background: var(--surface-deep);
  box-shadow: 0 0 0 5px var(--surface-deep);
}
#side-list li:not(.sec):hover .who { color: var(--gold); }
#side-list li:not(.sec):hover::after {
  content: "✦";
  position: absolute;
  left: 1px;
  top: 0.75em;
  font-size: 9px;
  color: var(--gold-dim);
}
/* fold/collapse section headers (name/city sorts) */
/* a section reads as a heading in gold (a country, a city, a letter) */
#side-list li.sec {
  font-size: 18px;
  font-weight: 400;
  color: var(--gold);
  padding: 14px 4px 4px;
}
#side-list li.sec .chev { font-size: 10px; color: var(--text-faint); font-style: normal; }
#side-list li .who { display: flex; flex-direction: column; font-size: 15px; font-weight: 500; }
#side-list li .sub { font-style: italic; font-size: 11.5px; font-weight: 400; color: var(--text-faint); }
/* the days, after a ✦ that burns brighter the more recent (its opacity
   arrives inline from main.js, recencyGlow) */
#side-list li .days {
  font: italic 400 12.5px var(--serif);
  color: var(--text-faint);
  white-space: nowrap;
}
#side-list li .days .star { margin-right: 7px; font-style: normal; font-size: 12px; color: var(--gold); }

/* dev HUD (?hud) */
#hud {
  position: fixed;
  top: max(8px, env(safe-area-inset-top));
  left: 10px;
  z-index: 40;
  font: italic 400 12.5px/1.4 var(--serif);
  color: #7dffb0;
  background: rgba(0, 0, 0, 0.5);
  padding: 3px 7px;
  border-radius: 2px;
  pointer-events: none;
}

/* ---- the card: an arched panel ----
   NOTE: no backdrop-filter here — blurring an animating WebGL canvas forces a
   recomposite every frame and visibly janks mid-range phones. Solid bg instead.
   Two gold rules draw the arch (the border, and ::before 5px inside it); the
   halo monogram sits in its crown, the head is centred under it down to the
   whiplash rule, and the page below that reads left to right. */
#panel {
  position: fixed;
  z-index: 30;
  background: var(--surface);
  border: 1px solid var(--gold-dim);
  border-radius: 50% 50% 4px 4px / 132px 132px 4px 4px;
  box-shadow: var(--shadow-card);
  transition: transform 0.32s cubic-bezier(.2,.8,.2,1), opacity 0.24s;
}
#panel::before {
  content: "";
  position: absolute;
  inset: 5px;
  border: 1px solid var(--gold-line);
  border-radius: 50% 50% 2px 2px / 127px 127px 2px 2px;
  pointer-events: none;
}

/* landscape (desktop & phones held sideways): side panel on the right.
   Orientation-based (not width-based) so no phone falls through the cracks. */
@media (orientation: landscape) {
  #panel {
    top: 50%;
    right: 24px;
    transform: translateY(-50%);
    width: 300px;
    padding: 14px 24px 22px;
  }
  #panel.hidden { opacity: 0; transform: translateY(-50%) translateX(20px); pointer-events: none; }
}

/* portrait: card in the top zone — the globe sits low, so the sky above the
   focused pin is reserved for info (not a bottom sheet) */
@media (orientation: portrait) {
  #panel {
    left: 12px;
    right: 12px;
    top: calc(12px + env(safe-area-inset-top));
    padding: 10px 20px 16px;
    max-width: 440px;       /* a tablet held upright keeps a card, not a banner */
    margin-inline: auto;
  }
  #panel.hidden { transform: translateY(-140%); opacity: 0; pointer-events: none; }
}

/* × and ‹ sit in the two corners the arch leaves empty */
#panel-close, #panel-back {
  position: absolute;
  top: 4px;
  width: 44px;
  height: 44px;
  border: none;
  border-radius: 2px;
  background: none;
  color: var(--text-dim);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}
#panel-close { right: 2px; }
#panel-back { left: 2px; }
#panel-back.hidden { display: none; }

/* the halo monogram: the friend's initial (a city list's ✦) in a ring of rays */
#panel-halo {
  cursor: pointer;
  display: grid;
  place-items: center;
  width: 92px;
  height: 92px;
  margin: 0 auto;
  background: url(../assets/ornaments/halo.svg) center / contain no-repeat;
  color: var(--gold);
  font-size: 27px;
  line-height: 1;
}

/* the name runs inline and its last word is glued to the pencil
   (main.js setPanelName): a long name wraps at a word boundary and the
   pencil rides the last line, never stranded alone under the name. The
   whole head is the edit-details door; the pencil is the affordance. */
#panel-head { padding: 0 8px; text-align: center; cursor: pointer; }
/* The whole card is the door to their book (Augustine, 2026-10-04 — main.js
   opens it from any part of the card that isn't one of its own keys; the
   ✎ alone opens their details). The head lights as one under the
   pointer, halo and all; a city's list is no door. */
#panel:not(.list) { cursor: pointer; }
#panel.list, #panel.list :is(#panel-halo, #panel-head) { cursor: default; }
#panel-name, #panel-halo { transition: color 0.15s; }
#panel-name {
  font-size: 26px;
  font-weight: 400;
  line-height: 1.15;
}
#panel-name .last { white-space: nowrap; }
/* the pencil beside the name: the edit-details door (2026-09-13 — the
   "edit details" link at the foot of the card is gone). A 44px key drawn
   small: the negative margins keep the name's line height and shrink its
   footprint in the line to 24px (the hit box stays the thumb's 44 —
   measured on the phone viewport by verify-buttons) */
#panel-edit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin: -14px -12px -14px -8px;
  vertical-align: middle;
  border: none;
  border-radius: 2px;
  background: none;
  color: var(--gold-dim);   /* the details' own door: gold, so it reads as one */
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
}
#panel-edit.hidden { display: none; }
/* The ceremony's name settle: ink pressing into paper — tracking closes,
   opacity lands. Applied once per placement (js/main.js), self-removed on
   animationend. (Inline, so no translate: the press is the tracking.) */
#panel-name.letterpress {
  animation: letterpress 1.1s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
@keyframes letterpress {
  from { opacity: 0; letter-spacing: 0.14em; }
  55%  { opacity: 1; }
  to   { opacity: 1; letter-spacing: normal; }
}
@media (prefers-reduced-motion: reduce) {
  #panel-name.letterpress { animation: none; }
}
#panel-city { text-align: center; font-style: italic; font-size: 14px; color: var(--text-dim); }
/* the head's small print: when, the next reminder, the address — italic,
   quiet, centred under the place */
#panel-days, #panel-nudge, #panel-address {
  margin-top: 2px;
  text-align: center;
  font-style: italic;
  font-size: 12.5px;
  color: var(--text-faint);
}
#panel-days { margin-top: 6px; }
#panel-days.hidden, #panel-nudge.hidden { display: none; }
#panel-address {
  display: block;
  text-decoration: underline;
  text-decoration-color: var(--gold-line);
  text-underline-offset: 3px;
}
#panel-address:hover { color: var(--teal); }   /* teal use 2, shared role */
#panel-address.hidden { display: none; }
/* the whiplash rule between the head and the page */
#panel-rule {
  height: 24px;
  max-width: 220px;
  margin: 8px auto 0;
  background: url(../assets/ornaments/whiplash.svg) center / contain no-repeat;
}
#panel-suggest {          /* nudge-opened card: at most ONE contextual offer */
  display: block;
  width: 100%;
  margin-top: 12px;
  padding: 8px 12px;
  border: 1px solid var(--gold-line);
  border-radius: 2px;
  background: var(--gold-faint);
  color: var(--text-dim);
  font-style: italic;
  font-size: 13px;
  text-align: left;
  cursor: pointer;
}
#panel-suggest.hidden { display: none; }
/* on this day: today's echo at the head of the page (js/main.js
   renderPanelEcho), framed like the one contextual offer, centered like the
   card it sits on (Augustine, 2026-10-29); the copy is the card's,
   lowercased — the name and the line are theirs: serif, as written; the act
   sits at its foot in gold */
#panel-echo {
  display: block;
  width: 100%;
  margin-top: 12px;
  padding: 8px 12px;
  border: 1px solid var(--gold-line);
  border-radius: 2px;
  background: var(--gold-faint);
  color: var(--text-dim);
  font: italic 400 13px var(--serif);
  text-transform: lowercase;
  text-align: center;
  cursor: pointer;
}
#panel-echo.hidden { display: none; }
#panel-echo :is(.who, .said) { text-transform: none; color: var(--text); }
#panel-echo .who { font-style: normal; }
#panel-echo .act { display: block; margin-top: 4px; color: var(--gold); }
#panel-echo .act::after { content: ' ✦'; }
/* an echoed memory's picture, small, above the line */
#panel-echo .echo-thumb {
  display: block;
  width: 40px;
  height: 40px;
  margin: 0 auto 6px;
  object-fit: cover;
  padding: 2px;
  border: 1px solid var(--border);
  border-radius: 2px;
}

/* ---- detail actions: handle deep-links, arched like the keys ---- */
#panel-handles {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px 10px;
  margin-top: 14px;
}
#panel-handles.hidden { display: none; }
/* The handles are the PRIMARY act of the nudge flow — buttons, not
   metadata: roomy, labeled, and tapping one logs the catch-up itself. */
#panel-handles .handle {
  min-width: 54px;
  padding: 0;
  display: grid;
  justify-items: center;
  gap: 4px;
  border: none;
  background: none;
  color: var(--text);
  text-decoration: none;
  cursor: pointer;
}
/* the ring is the icon's own box: the hover and the press land on it */
#panel-handles .handle svg {
  display: block;
  width: 44px;
  height: 44px;
  padding: 11px;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: rgba(15, 23, 21, 0.6);
  transition: border-color 0.15s, background-color 0.15s, box-shadow 0.2s;
}
#panel-handles .handle .hl {
  font-style: italic;
  font-size: 11px;
  color: var(--text-faint);
}
#panel-handles .handle:hover .hl { color: var(--text-dim); }

/* ---- the page: open on the card, written in place (js/main.js
   openPageEdit) — plain text on the panel; the textarea takes its place
   while you write, on faintly ruled paper ---- */
#panel-notes, #panel-notes-edit {
  display: block;
  width: 100%;
  margin-top: 10px;
  padding: 0;
  max-height: 32vh;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-color: rgba(239, 227, 200, 0.18) transparent;
  border: none;
  border-radius: 0;
  background: none;
  color: rgba(239, 227, 200, 0.92);
  font-size: 15px;
  line-height: 1.6;
  text-align: center;   /* centered like the rest of the card (Augustine, 2026-10-29) */
  white-space: pre-wrap;
}
#panel-notes { cursor: pointer; }
/* a memory long enough for its initial reads as a page: the initial sets
   the left margin, so the lines run from it (Augustine, 2026-10-29: centered
   lines beside a drop cap sat off to the right) */
#panel-notes.drop { text-align: left; }
#panel-notes.hidden { display: none; }
/* the empty page asks — gold italic, the book's own idiom */
#panel-notes.empty { font-style: italic; color: var(--gold); text-align: center; }
#panel-notes-edit {
  resize: none;
  caret-color: var(--gold);
  outline: none;
  line-height: 24px;
  background: repeating-linear-gradient(transparent 0 23px, var(--gold-line) 23px 24px);
}
#panel-notes-edit::placeholder { color: var(--text-faint); font-style: italic; }
#panel-notes-edit, #panel-notes-hint { display: none; }
#panel.editing #panel-notes { display: none; }
#panel.editing #panel-notes-edit { display: block; }
#panel.editing #panel-notes-hint {
  display: block;
  margin: 4px 2px 0;
  font-style: italic;
  font-size: 11.5px;
  color: var(--text-faint);
}

/* the act gets gold: remember this moment — the card's one stamp */
#panel-moment {
  display: block;
  width: 100%;
  margin-top: 14px;
  padding: 10px 14px;
  border: 1px solid var(--gold-dim);
  border-radius: 2px;
  background: var(--gold-faint);
  color: var(--gold);
  font-size: 16px;
  font-weight: 500;
  letter-spacing: 0.02em;
  cursor: pointer;
}
#panel-moment.hidden { display: none; }
/* the rest of the book, one quiet line below the stamp */
#panel-book {
  display: block;
  width: 100%;
  margin-top: 6px;
  padding: 7px 0;
  border: none;
  background: none;
  color: var(--text-dim);
  font-style: italic;
  font-size: 13.5px;
  text-align: center;
  cursor: pointer;
}
#panel-book.hidden { display: none; }
/* pairing (pair.js): the same quiet line, under the book's */
#panel-pair {
  display: block;
  width: 100%;
  padding: 5px 0;
  border: none;
  background: none;
  color: var(--text-faint);
  font-style: italic;
  font-size: 13px;
  text-align: center;
  cursor: pointer;
}
#panel-pair.hidden { display: none; }
/* the last line's date — a margin note above the open page */
#panel-when {
  margin-top: 12px;
  font-style: italic;
  font-size: 13px;
  letter-spacing: 0.02em;
  color: var(--gold);
  text-align: center;   /* centered like the card's head (Augustine, 2026-10-29) */
}
#panel-when.hidden { display: none; }
#panel-when:not(.hidden) ~ #panel-notes { margin-top: 4px; }
/* the plate: the latest page's picture, above its line (js/main.js
   showPanelPhoto), in a thin gold mount; tap it for the whole picture */
/* the plate is the picture's own shape — never cropped (Augustine,
   2026-09-14: a portrait shot in a wide plate was "cropped oddly"): as
   wide as the card or as tall as the cap, whichever comes first */
#panel-photo {
  display: block;
  width: fit-content;
  max-width: 100%;
  margin: 6px auto 0;
  padding: 3px;
  border: 1px solid var(--gold-line);
  border-radius: 2px;
  overflow: hidden;
  background: none;
  cursor: pointer;
}
#panel-photo.hidden { display: none; }
#panel-photo img { display: block; width: auto; height: auto; max-width: 100%; max-height: 26vh; border-radius: 1px; }
#panel-photo:not(.hidden) + #panel-notes { margin-top: 8px; }

/* a city's list: names on gold dot leaders, a star that burns brighter the
   more recent (its opacity arrives inline from main.js, recencyGlow) */
#panel-list {
  list-style: none;
  margin-top: 10px;
  max-height: 38vh;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-color: rgba(239, 227, 200, 0.18) transparent;
}
#panel-list.hidden { display: none; }
#panel-list li {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 7px 2px;
  font-size: 15px;
  cursor: pointer;
}
#panel-list li:hover .who { color: var(--gold); }
#panel-list li .who { display: flex; flex-direction: column; }
#panel-list li .sub { font-style: italic; font-size: 12px; color: var(--text-faint); }
#panel-list li .lead { flex: 1; min-width: 12px; border-bottom: 1px dotted var(--gold-line); transform: translateY(-5px); }
#panel-list li .star { font-size: 12px; color: var(--gold); }
#panel-list li .days { min-width: 30px; text-align: right; font-style: italic; font-size: 12px; color: var(--text-faint); white-space: nowrap; }

/* Portrait: a tighter card so the globe keeps the lower half; a city list
   folds into two columns so a 9-friend metro doesn't swallow it */
@media (orientation: portrait) {
  #panel-halo { width: 76px; height: 76px; font-size: 23px; }
  #panel-name { font-size: 24px; }
  #panel-city { font-size: 13px; }
  #panel-list {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 14px;
    max-height: 24vh;
    margin-top: 8px;
  }
  #panel-list li { padding: 5px 2px; font-size: 13.5px; gap: 6px; }
  #panel-list li .sub { font-size: 11px; }
  #panel-list li .days { min-width: 0; font-size: 11px; }
  #panel-handles { margin-top: 10px; gap: 6px 8px; }
  #panel-handles .handle { min-width: 50px; }
  #panel-handles .handle svg { width: 42px; height: 42px; padding: 11px; }
  #panel-moment { margin-top: 10px; padding: 8px 12px; font-size: 14px; }
  #panel-book { margin-top: 2px; padding: 6px 0; font-size: 12.5px; }
  #panel-notes, #panel-notes-edit { max-height: 18vh; }  /* open by default — don't swallow the globe */
  #panel-photo img { max-height: 22vh; }
}

/* ---- modal cards: hand-set almanac pages ----
   Solid paper, no backdrop-filter (see the panel note: blurring an animating
   WebGL canvas janks phones). */
#form-overlay, #settings-overlay, #pair-overlay, #intro-overlay, #privacy-overlay, #import-overlay, #almanac-overlay, #book-overlay {
  position: fixed;
  inset: 0;
  z-index: 40;
  background: var(--scrim);
  display: grid;
  place-items: center;
  /* the guide banner row hugs the card instead of taking half the screen;
     "safe" + scroll keep both reachable when banner + card outgrow a short
     viewport (the card alone also scrolls internally via its max-height) */
  align-content: safe center;
  overflow-y: auto;
  padding: 16px;
}
/* the composer held upright: up in the sky zone like the card, so the globe
   and their light stay in view below it, and the keyboard keeps the bottom */
@media (orientation: portrait) {
  #form-overlay.f-composer { align-content: start; padding-top: calc(12px + env(safe-area-inset-top)); }
}
#form-card, #settings-card, #pair-card, #intro-card, #privacy-card, #import-card, #almanac-card, #book-card {
  position: relative;  /* anchors the prefill toggle + popover */
  width: min(420px, 100%);
  max-height: min(88vh, 100%);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-color: rgba(239, 227, 200, 0.18) transparent;
  /* the framed page: a gold rule, a second one 7px inside it (the outline),
     a curling corner at each angle — backgrounds and outline stay pinned
     while the content scrolls */
  border: 1px solid var(--gold-dim);
  outline: 1px solid var(--gold-line);
  outline-offset: -7px;
  border-radius: 2px;
  background:
    url(../assets/ornaments/corner-tl.svg) left 11px top 11px / 32px no-repeat,
    url(../assets/ornaments/corner-tr.svg) right 11px top 11px / 32px no-repeat,
    url(../assets/ornaments/corner-bl.svg) left 11px bottom 11px / 32px no-repeat,
    url(../assets/ornaments/corner-br.svg) right 11px bottom 11px / 32px no-repeat,
    var(--surface);
  box-shadow: var(--shadow-card);
  padding: 34px 30px 28px;
}
#form-title, #settings-title, #pair-title { font-size: 25px; font-weight: 400; text-align: center; margin-bottom: 14px; text-wrap: balance; }
/* adding a friend: a band of moon phases under the title */
#form-card.f-contact #form-title::after {
  content: "";
  display: block;
  width: 132px;
  height: 16px;
  margin: 12px auto 0;
  background: url(../assets/ornaments/moons.svg) center / contain no-repeat;
}

/* settings: two folded categories, rows as a ledger, not boxes (js/settings.js) */
.s-fold {
  display: block;
  width: 100%;
  text-align: left;
  margin-top: 16px;
  padding: 4px 0;
  border: none;
  background: none;
  color: var(--text-dim);
  font-style: italic;
  font-size: 14px;
  cursor: pointer;
}
#s-behavior.hidden, #s-appearance.hidden { display: none; }
.s-choice {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 12px 4px;
  border-top: 1px solid var(--border-faint);
  cursor: pointer;
}
.f-label + .s-choice { border-top: none; }
.s-choice:has(input:checked) .s-name { color: var(--gold); }
.s-choice input { margin-top: 3px; accent-color: var(--gold); }
/* where you are (settings.js): each paired friend under the switch */
.s-share-row { padding-left: 26px; }
.s-share-row:has(input:disabled) { opacity: 0.55; }
.s-text { display: flex; flex-direction: column; gap: 2px; }
/* reminders overview — a quiet departures board under the toggle (settings.js) */
#s-reminders { margin: 0 0 4px 26px; }
#s-reminders:empty { display: none; }

/* compact motion select + its one live hint line */
#s-motion { max-width: 200px; }
#s-motion-hint { display: block; margin: 4px 2px 0; }

/* the backup buttons read like the footer link they used to be */
#s-export, #s-restore {
  display: block;
  border: none;
  background: none;
  padding: 2px 0;
  color: var(--text-dim);
  font: italic 400 14px var(--serif);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}
#s-export-status { display: block; margin: 4px 2px 0; }

/* Folio margins (pin ceremony): milestones as quiet almanac margin notes —
   italic label, measured date, one thin gold rule above. Discovered in
   passing, never announced. */
#s-folio {
  margin-top: 18px;
  padding-top: 12px;
  background: var(--folio-thin-gold);
}
.folio-note {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding: 3px 2px;
}
.folio-label { font-style: italic; font-size: 12.5px; color: var(--text-dim); }
.folio-when { font: italic 400 12.5px var(--serif); color: var(--text-faint); }
.s-rem-cap { font-style: italic; font-size: 11.5px; color: var(--text-faint); margin: 4px 0 3px; }
.s-rem-row { display: flex; align-items: baseline; gap: 8px; padding: 1.5px 0; }
.s-rem-name {
  font-size: 13px; color: var(--text-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 65%;
}
.s-rem-lead { flex: 1; border-bottom: 1px dotted var(--border); }
.s-rem-date {
  font: italic 400 12.5px var(--serif);
  text-transform: lowercase; color: var(--text-faint);
}
.s-rem-more, .s-rem-rest {
  font-style: italic; font-size: 11.5px; color: var(--text-faint); margin-top: 4px;
}

/* the almanac card (js/almanac.js, fx 'celestial') — the sky's own page:
   moon disc, dot-leader feed of coming events, folio foot. Leaders reuse the
   .s-rem-lead dotted-border recipe above. */
#alm-moon { display: flex; gap: 14px; align-items: center; padding: 6px 0 10px; }
#alm-moon-disc { width: 56px; height: 56px; flex: none; }
#alm-moon-lines { flex: 1; min-width: 0; }
#alm-phase {
  font: italic 500 14px var(--serif);
  text-transform: lowercase; color: var(--text); margin-bottom: 4px;
}
.alm-cap { font-style: italic; font-size: 11.5px; color: var(--text-faint); margin: 4px 0 3px; }
.alm-row { display: flex; align-items: baseline; gap: 8px; padding: 1.5px 0; }
.alm-name {
  font-style: italic; font-size: 13px; color: var(--text-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 65%;
}
.alm-zhr { font: italic 400 11.5px var(--serif); font-style: normal; color: var(--text-faint); }
.alm-lead { flex: 1; border-bottom: 1px dotted var(--border); }
.alm-when {
  font: italic 400 12.5px var(--serif);
  text-transform: lowercase; color: var(--text-faint);
}
.alm-row.alm-today .alm-name, .alm-row.alm-today .alm-when { color: var(--gold); }
.s-name { font-size: 14px; font-weight: 500; color: var(--text); }
.s-hint { font-style: italic; font-size: 12px; color: var(--text-faint); }
.f-label {
  display: block;
  font-style: italic;
  font-size: 12.5px;
  font-weight: 400;
  color: var(--text-dim);
  margin: 14px 0 6px;
}
/* the focused field's label grows a gold star */
.f-label::after { content: " ✦"; color: var(--gold); opacity: 0; transition: opacity 0.4s; }
label.f-label:has(
  + input:focus, + select:focus, + textarea:focus,
  + .f-suggest-wrap input:focus, + #f-handles :is(input, select):focus,
  + #f-last button:focus
)::after { opacity: 1; }

/* form fields are underline fields — the field-journal signature */
#form-card input, #form-card select, #form-card textarea, #side-search,
#settings-card select, #pair-card input {
  width: 100%;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  padding: 8px 2px;
  color: var(--text);
  font-size: 15px;
  caret-color: var(--gold);
}
/* long writing on faintly ruled paper: a gold rule under every line */
#form-card textarea {
  border-bottom: 0;
  padding: 0 2px;
  line-height: 26px;
  background: repeating-linear-gradient(transparent 0 25px, var(--border) 25px 26px);
  resize: vertical;
  min-height: 78px;
}
#form-card input:focus, #form-card select:focus, #form-card textarea:focus,
#side-search:focus, #settings-card select:focus, #pair-card input:focus {
  outline: none;
  border-bottom-color: var(--gold-dim);
  box-shadow: 0 6px 14px -10px rgba(217, 181, 108, 0.28);   /* candlelight, ≤10% */
}
#form-card ::placeholder, #pair-card ::placeholder, #settings-card ::placeholder { color: var(--text-faint); font-style: italic; }
#f-status {
  margin-top: 10px;
  padding: 8px 12px;
  border-radius: 2px;
  background: rgba(90, 220, 130, 0.12);
  border: 1px solid rgba(90, 220, 130, 0.35);
  color: #b8f0c8;
  font-size: 13px;
}
#f-status.hidden { display: none; }
#toast {
  position: fixed;
  bottom: 92px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 40;
  padding: 10px 18px;
  border-radius: 2px;
  background: var(--surface);
  border: 1px solid var(--gold-dim);
  outline: 1px solid var(--gold-line);
  outline-offset: -4px;
  color: var(--text);
  font: italic 400 14px var(--serif);
  text-transform: lowercase;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s;
}
#toast::before { content: "✦  "; color: var(--gold); }
#toast.show { opacity: 1; }
.f-suggest-wrap { position: relative; }
.f-suggest {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 5;
  list-style: none;
  background: var(--surface);
  border: 1px solid var(--gold-dim);
  outline: 1px solid var(--gold-line);
  outline-offset: -4px;
  border-radius: 2px;
  max-height: 208px;
  overflow-y: auto;
  scrollbar-color: rgba(239, 227, 200, 0.18) transparent;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.5);
}
.f-suggest.hidden { display: none; }
.f-suggest li {
  padding: 9px 12px;
  font-size: 14px;
  cursor: pointer;
}
/* highlight is a mark, not a fill */
.f-suggest li:hover, .f-suggest li.active { color: var(--gold); }
.f-suggest li:hover::before, .f-suggest li.active::before { content: "✦ "; font-size: 10px; }
/* prefill: person+ toggle in the card's top-right, anchored popover — or,
   while the suggestion cache is empty, the same menu inline in the card flow */
#f-prefill-toggle {
  position: absolute;
  top: 30px;
  right: 46px;   /* clear of the frame's corner curl */
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border: 1px solid var(--border);
  border-radius: 2px;
  background: none;
  color: var(--text-dim);
  cursor: pointer;
}
#f-prefill-toggle svg { width: 17px; height: 17px; }
#f-prefill-toggle.hidden { display: none; }
#f-prefill-menu {
  position: absolute;
  top: 70px;
  right: 30px;
  z-index: 6;
  width: min(264px, calc(100% - 60px));
  padding: 14px;
  background: var(--surface);
  border: 1px solid var(--gold-dim);
  outline: 1px solid var(--gold-line);
  outline-offset: -4px;
  border-radius: 2px;
  box-shadow: var(--shadow-card);
}
#f-prefill-menu.hidden { display: none; }
#f-prefill-menu.inline {
  position: static;
  width: 100%;
  margin-bottom: 4px;
  box-shadow: none;
  background: none;
  outline: none;
  border-color: var(--border);
}
#f-imports-label { font-style: italic; font-size: 12.5px; color: var(--text-dim); line-height: 1.5; margin-bottom: 10px; }
#f-imports-label .opt { color: var(--text-faint); }
#f-imports { display: flex; flex-wrap: wrap; gap: 6px; }
.f-import {
  padding: 5px 11px;
  border: 1px solid var(--border);
  border-radius: 2px;
  background: none;
  color: var(--text-dim);
  font: italic 400 12.5px var(--serif);
  text-transform: lowercase;
  cursor: pointer;
}
.f-import:disabled { opacity: 0.5; }
/* chip rows (js/form.js): last-caught-up + place momentum — one tap where
   a select was open-scroll-pick */
.f-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.f-chips.hidden { display: none; }
#f-places { margin-top: 8px; }
.f-chip {
  padding: 5px 11px;
  border: 1px solid var(--border);
  border-radius: 2px;
  background: none;
  color: var(--text-dim);
  font: italic 400 12.5px var(--serif);
  text-transform: lowercase;
  cursor: pointer;
}
/* the lit chip — three classes deep so it holds its full-gold rule under
   the pointer (the button section's hover weighs one id + two classes) */
#form-card .f-chips .f-chip.on { border-color: var(--gold); color: var(--gold); background: var(--gold-faint); }
/* phone-starred favorites in the name typeahead */
.f-suggest li.starred::after { content: " ✦"; font-size: 10px; color: var(--gold-dim); }
/* run card (js/main.js): the explicit fork after a chained landing — the
   notes ask and the next add, dealt where the thumb already is */
#run-card {
  position: fixed;
  bottom: 92px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 40;
  display: flex;
  gap: 8px;
  padding: 12px;
  background: var(--surface);
  border: 1px solid var(--gold-dim);
  outline: 1px solid var(--gold-line);
  outline-offset: -4px;
  border-radius: 2px;
  box-shadow: var(--shadow-card);
  opacity: 0;
  transition: opacity 0.3s;
}
#run-card.show { opacity: 1; }
#run-card button {
  padding: 7px 13px;
  border: 1px solid var(--border);
  border-radius: 2px;
  background: none;
  color: var(--text-dim);
  font: italic 400 13.5px var(--serif);
  text-transform: lowercase;
  cursor: pointer;
  white-space: nowrap;
}
#run-card #run-notes { border-color: var(--gold-dim); color: var(--gold); }
/* first-run guide: welcome banner over the card + a hint that walks down the
   fields (js/form.js) */
.guide-hint {
  margin-top: 7px;
  font-style: italic;
  font-size: 12.5px;
  color: var(--text-dim);
  animation: guide-fade 0.5s ease both;
}
@keyframes guide-fade {
  from { opacity: 0; transform: translateY(5px); }
  to   { opacity: 1; transform: none; }
}
.f-handle-row {
  display: flex;
  gap: 6px;
  align-items: center;
  margin-bottom: 6px;
}
#form-card .f-handle-row select { width: 118px; flex: none; }
#form-card .f-handle-row input { flex: 1; min-width: 0; width: auto; }
/* per-row hint (discord share-profile nudge) — guide-hint voice, pulled up
   against the row it annotates */
.f-handle-hint { margin: -2px 0 8px; }
.f-handle-hint.hidden { display: none; }
.f-del {
  flex: none;
  width: 32px;
  height: 34px;
  border: none;
  border-radius: 2px;
  background: none;
  color: var(--text-faint);
  font-size: 16px;
  cursor: pointer;
}
#f-add-handle, #f-add-address {
  margin-top: 2px;
  padding: 5px 10px;
  border: none;
  background: none;
  color: var(--text-dim);
  font-style: italic;
  font-size: 13px;
  cursor: pointer;
}
#f-add-address.hidden { display: none; }
#f-address-wrap.hidden { display: none; }
/* catch-up history (edit form only): the correction ledger, folded away —
   demo feedback moved it off the card entirely */
#f-rest {
  display: block;
  margin-top: 14px;
  padding: 2px 0;
  border: none;
  background: none;
  color: var(--text-faint);
  font-style: italic;
  font-size: 12.5px;
  cursor: pointer;
  text-align: left;
}

/* ---- the moment composer (form.js openEntryPrompt) ----
   the date in gold italic under the title — the moment's own stamp, shown,
   not a control (the re-date chips came out 2026-09-13) — and the line
   below, on ruled paper */
#f-when-date {
  display: block;
  margin: -8px 0 14px;
  text-align: center;
  font: italic 400 13.5px var(--serif);
  color: var(--gold);
}
#f-when-date::after { content: " ✦"; color: var(--gold-dim); }
#f-when-date.hidden { display: none; }   /* the story: the first page has no date */
#f-entry { min-height: 5.5em; }
/* the memory's pictures (js/media.js): a strip of what it carries, each
   with an × to take it off, then the doors — the phone's two (the system
   camera, the system picker) or the browser's one — as quiet keys */
#f-media {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}
#f-media.hidden { display: none; }
.f-thumb {
  position: relative;
  width: 74px;
  height: 74px;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: 2px;
  overflow: hidden;
  background: none;
}
.f-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
.f-thumb.missing::after {
  content: "✦";
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: var(--text-faint);
}
.f-thumb .del {
  position: absolute;
  top: 5px;
  right: 5px;
  width: 22px;
  height: 22px;
  padding: 0;
  border: none;
  border-radius: 2px;
  background: rgba(5, 9, 10, 0.72);
  color: rgba(239, 227, 200, 0.9);
  font-size: 14px;
  line-height: 22px;
  cursor: pointer;
}
#f-media-keys {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}
#f-media-keys .f-photo {
  padding: 6px 12px;
  border: 1px solid var(--border);
  border-radius: 2px;
  background: none;
  color: var(--text-dim);
  font-size: 13.5px;
  cursor: pointer;
}
#f-media-keys .f-photo:disabled { opacity: 0.5; cursor: default; }
#f-media-note { margin-top: 8px; font-style: italic; font-size: 12.5px; color: var(--text-dim); }
#f-media-note.hidden { display: none; }

/* ---- who? (form.js openWhoPrompt): the index, one tap to a book ---- */
#f-who-list {
  list-style: none;
  margin-top: 10px;
  max-height: 46vh;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-color: rgba(239, 227, 200, 0.18) transparent;
}
#f-who-list li {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 8px 2px;
  cursor: pointer;
}
#f-who-list li::after { content: ""; order: 1; flex: 1; min-width: 12px; border-bottom: 1px dotted var(--border); transform: translateY(-4px); }
#f-who-list li .sub { order: 2; }
#f-who-list li .who { font-size: 15.5px; font-weight: 500; }
#f-who-list li .sub { font-style: italic; font-size: 12px; color: var(--text-faint); }
#f-who-list li:hover .who { color: var(--gold); }
/* pairing by code (pair.js): the code and the three words set large in
   gold, the typed code centred like them */
#pair-card .s-hint { display: block; text-align: center; margin-bottom: 10px; }
#pair-code, #pair-words { margin: 6px 0 14px; text-align: center; color: var(--gold); }
#pair-code { font-size: 40px; letter-spacing: 0.14em; font-variant-numeric: tabular-nums; }
#pair-words { font-size: 25px; font-style: italic; text-wrap: balance; }
#pair-card #pair-code-in { font-size: 28px; letter-spacing: 0.14em; text-align: center; font-variant-numeric: tabular-nums; margin-bottom: 8px; }

/* ---- our book (js/book.js): a person's pages, a framed page of its own ----
   The frame holds still (#book-card: the modal frame, taller) and the page
   scrolls inside it (#book-page); × sits in the frame's top-right corner. */
#book-card {
  display: flex;
  flex-direction: column;
  width: min(460px, 100%);
  max-height: min(92vh, 100%);
  overflow: hidden;
  padding: 0;
}
/* the page fades out before the frame's corners as it scrolls */
#book-page {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-color: rgba(239, 227, 200, 0.18) transparent;
  padding: 44px 34px 44px;
  -webkit-mask-image: linear-gradient(transparent 0, #000 48px, #000 calc(100% - 34px), transparent 100%);
  mask-image: linear-gradient(transparent 0, #000 48px, #000 calc(100% - 34px), transparent 100%);
}
#book-done {
  position: absolute;
  top: 12px;
  right: 14px;
  z-index: 1;
  width: 44px;
  height: 44px;
  border: none;
  border-radius: 2px;
  background: none;
  color: var(--text-dim);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}
#book-halo {
  display: grid;
  place-items: center;
  width: 88px;
  height: 88px;
  margin: 0 auto;
  background: url(../assets/ornaments/halo.svg) center / contain no-repeat;
  color: var(--gold);
  font-size: 26px;
  line-height: 1;
}
#book-title { margin-top: 4px; text-align: center; font-size: 30px; font-weight: 400; line-height: 1.15; text-wrap: balance; }
#book-where { margin-top: 2px; text-align: center; font-style: italic; font-size: 14px; color: var(--text-dim); }
#book-label { margin-top: 4px; text-align: center; font-style: italic; font-size: 13px; color: var(--text-faint); }
#book-how { margin: 24px 0 10px; text-align: center; font-style: italic; font-size: 13px; color: var(--text-dim); }
#book-how.hidden { display: none; }
#book-how.hidden + #book-story-thumbs.hidden + #book-story { margin-top: 24px; }
/* the story: the first page — its own text is the door */
#book-story {
  display: block;
  margin-top: 12px;
  color: rgba(239, 227, 200, 0.92);
  font-size: 15px;
  line-height: 1.6;
  text-align: left;
  white-space: pre-wrap;
  cursor: pointer;
}
#book-story.empty { font-style: italic; color: var(--gold); text-align: center; }
#book-story.drop { display: flow-root; }   /* holds its initial */
#book-rule {
  height: 24px;
  max-width: 220px;
  margin: 24px auto 0;
  background: url(../assets/ornaments/whiplash.svg) center / contain no-repeat;
}
#book-moment {
  display: block;
  width: 100%;
  margin-top: 18px;
  padding: 10px 14px;
  border: 1px solid var(--gold-dim);
  border-radius: 2px;
  background: var(--gold-faint);
  color: var(--gold);
  font-size: 16px;
  font-weight: 500;
  letter-spacing: 0.02em;
  cursor: pointer;
}
/* the memories, newest first, each under a band of moon phases */
#book-entries { list-style: none; margin-top: 30px; }
#book-card:not(.yours) #book-entries li.line + li.line::before {
  content: "";
  display: block;
  width: 132px;
  height: 16px;
  margin: 2px auto 24px;
  background: url(../assets/ornaments/moons.svg) center / contain no-repeat;
}
#book-entries li.line { padding-bottom: 24px; }
#book-entries li .head { display: flex; align-items: baseline; justify-content: space-between; }
#book-entries li .when { font-style: italic; font-size: 13px; letter-spacing: 0.02em; color: var(--gold); }
#book-entries li .body {
  display: block;
  width: 100%;
  margin-top: 6px;
  border: none;
  background: none;
  padding: 0;
  color: rgba(239, 227, 200, 0.92);
  font-size: 15px;
  line-height: 1.6;
  text-align: left;
  white-space: pre-wrap;
  cursor: pointer;
  -webkit-user-select: text;
  user-select: text;
}
/* a picture without a line: the ask, in the empty page's idiom */
#book-entries li .body.empty { font-style: italic; color: var(--gold); }
#book-entries li .del {
  margin-right: -8px;
  border: none;
  background: none;
  padding: 4px 8px;
  border-radius: 2px;
  color: var(--text-faint);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}
#book-entries li.empty {
  font-style: italic;
  font-size: 13.5px;
  text-align: center;
  color: var(--text-faint);
}
/* pictures: one is a plate in its own shape; more are a grid of squares,
   each in a thin gold mount; tap one for the viewer */
#book-card .thumbs { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 8px; }
#book-card .thumbs.one { grid-template-columns: 1fr; }
#book-card .thumbs.hidden { display: none; }
#book-card .thumb {
  aspect-ratio: 1;
  padding: 3px;
  border: 1px solid var(--gold-line);
  border-radius: 2px;
  overflow: hidden;
  background: none;
  cursor: pointer;
}
#book-card .thumbs.one .thumb { aspect-ratio: auto; justify-self: center; max-width: 100%; }
#book-card .thumb img { display: block; width: 100%; height: 100%; object-fit: cover; border-radius: 1px; }
#book-card .thumbs.one .thumb img { width: auto; height: auto; max-width: 100%; max-height: 34vh; }
#book-card .thumb.missing { display: grid; place-items: center; min-height: 84px; color: var(--text-faint); }
#book-card .thumb.missing::after { content: "✦"; }
/* your book (book.js openYourBook): the same framed page; every memory
   under month headings, each with its person's name — the door to their
   book — and the date */
#book-card.yours #book-title { font-size: 34px; }
#book-where.hidden { display: none; }
#book-entries li.month {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 4px 0 18px;
  font-size: 21px;
  color: var(--gold);
}
#book-entries li.month::before, #book-entries li.month::after { content: ""; flex: 1; border-top: 1px solid var(--border); }
#book-entries li.line + li.month { margin-top: 10px; }
#book-entries li .head .who {
  padding: 0;
  border: none;
  background: none;
  color: var(--text);
  font-size: 19px;
  text-align: left;
  cursor: pointer;
}
#f-error {
  margin-top: 12px;
  padding: 8px 12px;
  border-radius: 2px;
  background: var(--madder-faint);
  border: 1px solid var(--madder-line);
  color: var(--madder);
  font-size: 13px;
}
#f-error.hidden { display: none; }
#f-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin-top: 18px;
}
/* the whiplash rule over every page's last row */
#f-actions::before {
  content: "";
  flex: 0 0 100%;
  height: 24px;
  margin-bottom: 10px;
  background: url(../assets/ornaments/whiplash.svg) center / 220px 24px no-repeat;
}
.f-spacer { flex: 1; }
/* :where keeps the row's default at one id, so the stamp, the quiet close
   and the red remove below outweigh it (as `#f-actions button` they never
   did — the save read as a plain key from the day the rule was written) */
#f-actions :where(button) {
  padding: 9px 16px;
  border-radius: 2px;
  border: 1px solid var(--border);
  background: none;
  color: var(--text);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
}
#f-cancel, #f-skip {
  border-color: transparent;
  color: var(--text-dim);
}
/* the gold stamp — the one act on the page */
#f-save {
  background: var(--gold-faint);
  border-color: var(--gold-dim);
  color: var(--gold);
}
/* remove: the warning ink, quiet — words, not a red slab in the frame */
#f-delete {
  font-style: italic;
  background: none;
  border-color: transparent;
  color: var(--madder);
}

/* privacy modal (js/privacy.js) — privacy.html's <main> lifted into a card;
   these style its page markup (h2/p/ul/.card) in the modal's voice */
#privacy-card { -webkit-user-select: text; user-select: text; }
#privacy-card h2 {
  font-style: italic;
  font-size: 15px;
  font-weight: 500;
  color: var(--gold);
  margin: 20px 0 4px;
}
#privacy-card p, #privacy-card li {
  font-size: 14px;
  line-height: 1.6;
  color: rgba(239, 227, 200, 0.92);
}
#privacy-card p { margin: 6px 0 0; }
#privacy-card ul { margin-top: 6px; padding-left: 18px; }
#privacy-card a { color: var(--gold); text-underline-offset: 3px; }
#privacy-card .card {
  background: var(--ink-fill);
  border: 1px solid var(--border-faint);
  border-radius: 2px;
  padding: 4px 14px 8px;
  margin-top: 8px;
}

/* first-visit intro (js/intro.js) — same card idiom, dimmer scrim so the
   globe still reads behind it (it IS the pitch) */
#intro-overlay { background: var(--scrim-light); }
#intro-card { text-align: center; padding-top: 38px; }
#intro-title {
  font-size: 46px;
  font-weight: 400;
  line-height: 1.1;
}
#intro-sub {
  margin-top: 4px;
  font-size: 15px;
  color: var(--text-dim);
  font-style: italic;
}
#intro-sub::after {
  content: "";
  display: block;
  height: 24px;
  margin: 14px auto 0;
  background: url(../assets/ornaments/whiplash.svg) center / 220px 24px no-repeat;
}
.intro-body {
  margin: 14px 0 0;
  font-size: 15px;
  line-height: 1.6;
  color: rgba(239, 227, 200, 0.92);
}
#intro-actions {
  display: flex;
  gap: 8px;
  justify-content: center;
  margin-top: 22px;
}
#intro-actions :where(button) {   /* :where — see #f-actions */
  padding: 9px 16px;
  border-radius: 2px;
  border: 1px solid var(--border);
  background: none;
  color: var(--text);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
}
#intro-start {
  background: var(--gold-faint);
  border-color: var(--gold-dim);
  color: var(--gold);
}

/* first-run import setup (js/onboard.js) — the welcome + bulk-import
   moment, shown before the add form's keyboard steals the screen. The
   import action is the card's hero (live user test 2026-07-25 — it wore
   the form's 11px fallback-chip look and people hesitated); the privacy
   note hugs it, the skip recedes. */
#import-title { font-size: 25px; font-weight: 400; text-align: center; }
#import-card .intro-body { margin: 10px 0 0; }
#import-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 18px; }
.import-action {
  flex: 1 1 100%;
  padding: 12px 16px;
  border: 1px solid var(--gold-dim);
  border-radius: 2px;
  background: var(--gold-faint);
  color: var(--gold);
  font-size: 15px;
  font-weight: 500;
  cursor: pointer;
}
.import-action:disabled { opacity: 0.5; }
#import-note {
  margin: 10px 0 0;
  font-style: italic;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--text-dim);
}
#import-migrate {
  display: block;
  border: none;
  background: none;
  margin-top: 14px;
  padding: 2px 0;
  font-style: italic;
  font-size: 12.5px;
  color: var(--text-dim);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}
#import-migrate:disabled, #import-skip:disabled { opacity: 0.5; cursor: default; }
#import-status {
  margin-top: 12px;
  font-style: italic;
  font-size: 12.5px;
  color: var(--gold);
  animation: guide-fade 0.5s ease both;
}
#import-status.hidden { display: none; }
#import-skip {
  display: block;
  margin: 20px auto 0;
  padding: 4px 0;
  border: none;
  background: none;
  color: var(--text-faint);
  font-style: italic;
  font-size: 12px;
  cursor: pointer;
}

/* invitation slips: PWA install + nudge offer (js/pwa.js, js/push.js) */
#install-card {
  position: fixed;
  bottom: 92px;
  left: 50%;
  transform: translateX(-50%) translateY(12px);
  z-index: 45;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  width: max-content;
  max-width: min(92vw, 480px);
  padding: 14px 16px;
  border-radius: 2px;
  background: var(--surface);
  border: 1px solid var(--gold-dim);
  outline: 1px solid var(--gold-line);
  outline-offset: -4px;
  box-shadow: var(--shadow-card);
  color: var(--text);
  font: italic 400 14px var(--serif);
  text-transform: lowercase;
  opacity: 0;
  transition: opacity 0.3s, transform 0.3s;
}
#install-card.show { opacity: 1; transform: translateX(-50%) translateY(0); }
#install-card span { flex: 1 1 200px; }
#install-card .keys { flex: none; display: flex; gap: 10px; margin-left: auto; }
#install-card button {
  flex-shrink: 0;
  padding: 7px 12px;
  border-radius: 2px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text);
  font: inherit;
  cursor: pointer;
}
#install-card #install-yes {
  background: var(--gold-faint);
  border-color: var(--gold-dim);
  color: var(--gold);
}

/* ---- first-session tour bubble (js/onboard.js) ---- */
#tour-hint {
  position: fixed;
  z-index: 46;              /* above the panel and the card slot */
  max-width: min(78vw, 300px);
  padding: 12px 34px 12px 14px;
  border-radius: 2px;
  background: var(--surface);
  border: 1px solid var(--gold-dim);
  outline: 1px solid var(--gold-line);
  outline-offset: -4px;
  box-shadow: var(--shadow-card);
  opacity: 0;
  transition: opacity 0.45s, top 0.3s, left 0.3s;
  pointer-events: none;
}
#tour-hint.show { opacity: 1; pointer-events: auto; }
#tour-text {
  font-style: italic;       /* the guide-hint voice (form.js), floating */
  font-size: 14px;
  color: var(--text);
  line-height: 1.5;
}
#tour-next {
  margin-top: 8px;
  padding: 5px 10px;
  border-radius: 2px;
  border: 1px solid var(--gold-dim);
  background: var(--gold-faint);
  color: var(--gold);
  font: italic 400 12.5px var(--serif);
  cursor: pointer;
}
#tour-skip {
  position: absolute;
  top: 4px;
  right: 4px;
  border: none;
  background: none;
  color: var(--text-dim);
  font-size: 17px;
  padding: 4px 8px;
  cursor: pointer;
}

/* Spotlight: dims the globe and bottom chrome under the panel (z 30) while
   the tour runs; the showcased element gets .tour-lit — gold edge, soft
   glow, and a z hop over the scrim for fixed-position targets (+ button). */
#tour-scrim {
  position: fixed;
  inset: 0;
  z-index: 25;
  /* 0.5 depth (0.35 read as barely-there on the phone) with a feathered
     porthole cut where the beat's subject sits — the pin, the + button —
     so it keeps full brightness (js/onboard.js drives the vars) */
  background: radial-gradient(circle at var(--hole-x, 50%) var(--hole-y, -200px),
    transparent var(--hole-r, 0px),
    rgba(7, 11, 12, 0.5) calc(var(--hole-r, 0px) + 30px));
  opacity: 0;
  transition: opacity 0.6s;
  pointer-events: none;   /* purely visual — doing the thing still advances */
}
#tour-scrim.show { opacity: 1; }
.tour-lit {
  z-index: 46;   /* positioned targets only; static panel children ignore it */
  box-shadow: 0 0 0 1px var(--gold-dim), 0 0 22px rgba(217, 181, 108, 0.22);
  transition: box-shadow 0.45s;   /* the panel and the handles row; a lit
                                     BUTTON's glow rides the button section's 0.2s */
}
/* the id rule's own z-index outweighs the class — without this the lit
   + button stayed UNDER the scrim (the "highlighted but still dim" report) */
#add-btn.tour-lit { z-index: 46; }
button.tour-lit {
  color: var(--gold);
  border-color: var(--gold-dim);
}
/* the growth invitation (main.js breatheAddBtn): the + button breathes the
   tour's gold — up to the lit look and back, three slow breaths — on a
   small globe's return visit. Barely there: nothing appears, nothing to
   dismiss; the button that was always the invitation glows for a moment. */
@keyframes add-breath {
  0%, 100% { border-color: var(--gold-dim); box-shadow: 0 0 0 1px transparent, 0 0 22px rgba(217, 181, 108, 0); }
  50% { border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold-dim), 0 0 22px rgba(217, 181, 108, 0.22); }
}
#add-btn.breathe { animation: add-breath 3.4s ease-in-out 3; }

/* ---- demo exit chip (main.js, ?demo only): the shop window's door ---- */
#demo-chip {
  position: fixed;
  /* nav's bottom offset + the 44px nav button height + 10px gap: the chip
     shares the bottom-center column with #nav and must sit above it */
  bottom: max(70px, calc(env(safe-area-inset-bottom, 0px) + 64px));
  left: 50%;
  transform: translateX(-50%);
  z-index: 20;
  padding: 9px 16px;
  border-radius: 2px;
  border: 1px solid var(--gold-dim);
  outline: 1px solid var(--gold-line);
  outline-offset: -4px;
  background: rgba(15, 23, 21, 0.94);
  color: var(--text-dim);
  font: italic 400 14px var(--serif);
  cursor: pointer;
}

/* tap-to-place: the offer that follows a tap on open ground (main.js dropAt)
   — floats above the gold ✦ on the globe, re-projected every frame, hidden
   with it on the far side. Place in the almanac's serif, the action in mono. */
#drop-chip {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 9px 16px 8px;
  border: 1px solid var(--gold-dim);
  outline: 1px solid var(--gold-line);
  outline-offset: -4px;
  border-radius: 2px;
  background: rgba(15, 23, 21, 0.94);
  color: var(--text);
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s, border-color 0.15s, translate 0.16s, scale 0.16s;
  will-change: transform;
}
#drop-chip.show { opacity: 1; pointer-events: auto; }
#drop-chip .place {
  font: italic 400 14.5px var(--serif);
  color: var(--text);
  white-space: nowrap;
  max-width: 62vw;
  overflow: hidden;
  text-overflow: ellipsis;
}
#drop-chip .act {
  font: italic 400 12.5px var(--serif);
  text-transform: lowercase;
  color: var(--gold);
}
#drop-chip:is(:hover, :active) .place { color: var(--gold); }   /* the whole chip lights */

/* ---- the viewer (js/viewer.js): the picture, large, over the night;
   the caption in the measured mono; a tap anywhere closes it ---- */
#viewer-overlay {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto;
  justify-items: center;
  gap: 10px;
  padding: max(24px, env(safe-area-inset-top)) 16px max(20px, env(safe-area-inset-bottom));
  background: rgba(5, 9, 10, 0.94);
  opacity: 0;
  transition: opacity 0.2s;
  cursor: pointer;
}
#viewer-overlay.show { opacity: 1; }
#viewer-img {
  width: 100%;
  height: 100%;
  min-height: 0;
  object-fit: contain;
}
#viewer-caption {
  font: italic 400 13.5px var(--serif);
  color: var(--text-dim);
}
#viewer-close {
  position: absolute;
  top: max(10px, env(safe-area-inset-top));
  right: 10px;
  width: 44px;
  height: 44px;
  border: none;
  background: none;
  color: var(--text-dim);
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
}

/* ---- the viewfinder (js/camera.js) ----
   Charis's own camera: the native preview shows THROUGH the page — the
   ground goes transparent and everything but the finder is hidden
   (visibility, so the globe keeps its state). The 4:3 frame sits in the
   middle at the screen's width, as the preview letterboxes it; the bands
   above and below are the app's ground and carry the chrome: the name in
   the mono and an × up top, the flip key and the gold ✦ shutter below. */
html.finder-open, html.finder-open body { background: transparent; }
html.finder-open body > :not(#finder) { visibility: hidden; }
#finder {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto minmax(0, 1fr);
  color: var(--text-dim);
}
#finder-top, #finder-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--bg);
}
#finder-top {
  padding: max(10px, env(safe-area-inset-top)) 10px 10px 16px;
  align-items: flex-start;
}
#finder-name {
  font: italic 400 15px var(--serif);
  color: var(--text);
  padding-top: 12px;
}
#finder-frame {
  width: 100%;
  aspect-ratio: 3 / 4;
  max-height: 100vh;
  background:
    url(../assets/ornaments/corner-tl.svg) left 10px top 10px / 32px no-repeat,
    url(../assets/ornaments/corner-tr.svg) right 10px top 10px / 32px no-repeat,
    url(../assets/ornaments/corner-bl.svg) left 10px bottom 10px / 32px no-repeat,
    url(../assets/ornaments/corner-br.svg) right 10px bottom 10px / 32px no-repeat;
}
#finder.opening #finder-frame { background-color: var(--bg); }   /* until the first frame */
#finder-foot {
  padding: 10px 24px max(16px, calc(env(safe-area-inset-bottom, 0px) + 10px));
  min-height: 96px;
}
/* the shutter centred between the flip and a spacer of the flip's width
   (a stretched flip read as an oval ring, Augustine on the iPad, 2026-10-04) */
#finder-foot > * { flex: 0 0 auto; }
#finder-foot .finder-spacer { width: 48px; }
#finder-close, #finder-flip {
  width: 44px;
  height: 44px;
  padding: 0;
  border: none;
  background: none;
  color: var(--text-dim);
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
}
/* the flip key: a medallion, like the acts over the globe */
#finder-flip {
  width: 48px;
  height: 48px;
  border: 1px solid var(--border);
  border-radius: 50%;
  outline: 1px solid var(--gold-line);
  outline-offset: -5px;
  background: rgba(15, 23, 21, 0.92);
  font-size: 20px;
}
/* the shutter: a ✦ in a halo — the ring is the halo's own, its rays
   around the button (::before, out of the way of the touch) */
#finder-shutter {
  position: relative;
  flex: 0 0 72px;
  width: 72px;
  height: 72px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 50%;
  background: var(--gold-faint);
  color: var(--gold);
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
}
#finder-shutter::before {
  content: "";
  position: absolute;
  inset: -28px;
  background: url(../assets/ornaments/halo.svg) center / contain no-repeat;
  pointer-events: none;
}
#finder-shutter:disabled { opacity: 0.5; cursor: default; }
#finder.taking #finder-frame { background-color: rgba(5, 9, 10, 0.35); }   /* the blink */
/* the phone on its side: the frame is 4:3 at the screen's height, the
   bands become the columns either side — the name and the × on the left,
   the shutter and the flip key stacked on the right (a thumb's reach) */
@media (orientation: landscape) {
  #finder {
    grid-template-rows: 100%;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  }
  #finder-frame { width: auto; height: 100%; aspect-ratio: 4 / 3; max-height: none; max-width: 100vw; }
  #finder-top {
    flex-direction: column;
    align-items: flex-start;
    padding: max(10px, env(safe-area-inset-top)) 10px max(10px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
  }
  #finder-top #finder-close { order: -1; align-self: flex-start; margin-left: -10px; }
  #finder-name { padding-top: 6px; }
  #finder-foot {
    flex-direction: column;
    justify-content: center;
    gap: 28px;
    min-height: 0;
    padding: max(10px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) max(10px, env(safe-area-inset-bottom)) 10px;
  }
  #finder-foot > * { flex: 0 0 auto; }
  #finder-foot > :first-child { order: 1; }   /* the flip key below the shutter */
  #finder-foot .finder-spacer { display: none; }
}

/* ---- every button: gold under the pointer, a press you can feel ----
   One rule for the whole app (Augustine, 2026-09-13). It sits last and is
   keyed by the page ids (a hover written beside a button above loses to
   it — add to the lists here instead): pages = the cards, the panel, the
   drawer, the nav; keys = the bordered or filled buttons; stamps = the
   keys that are gold at rest.
   Hover paints the act's colour — gold ink, the dim gold rule, and on the
   keys the faint wash: the stamp's own look. Guarded by (hover: hover) so
   a tapped key on a phone doesn't stay lit. Stamps step up (rule to full
   gold, wash to --gold-wash); the letterpress keys over the globe keep
   their solid ink (a wash would show the Earth through them) and lift to
   the raised surface; the two destructive keys keep their red.
   The press is physical: the key travels down and in (1px, 2%) within a
   frame, a key's fill sinks under an inset shadow, and it springs back on
   release. translate/scale rather than transform so it composes with a
   chip's own transform (#demo-chip's centring, #drop-chip's per-frame
   projection). The finger paints gold too — touch gets the same feedback
   minus the hover. */
:is(#nav, #sidebar, #panel, #form-card, #settings-card, #pair-card, #intro-card, #privacy-card,
    #import-card, #almanac-card, #book-card, #run-card, #install-card, #tour-hint, #viewer-overlay, #finder) button,
#side-toggle, #add-btn, #write-btn, #demo-chip, #panel-handles .handle, #panel-notes, #book-story {
  transition: color 0.15s, border-color 0.15s, background-color 0.15s, box-shadow 0.2s,
              translate 0.16s cubic-bezier(.2,.8,.2,1), scale 0.16s cubic-bezier(.2,.8,.2,1);
}
@media (hover: hover) {
  :is(#nav, #sidebar, #panel, #form-card, #settings-card, #pair-card, #intro-card, #privacy-card,
      #import-card, #almanac-card, #book-card, #run-card, #install-card, #tour-hint, #viewer-overlay, #finder) button:hover:not(:disabled),
  #side-toggle:hover, #add-btn:hover, #write-btn:hover, #demo-chip:hover, #drop-chip:hover,
  #panel-handles .handle:hover, #panel-notes:hover, #book-story:hover {
    color: var(--gold);
    border-color: var(--gold-dim);
  }
  :is(#panel-suggest, #panel-echo, #panel-moment, #panel-notes, #book-story, #book-moment,
      #f-actions button, #form-card .f-chip, .f-import, #f-prefill-toggle, #run-card button,
      #intro-actions button, .import-action, #install-card button, #tour-next):hover:not(:disabled) {
    background-color: var(--gold-faint);
  }
  #panel-handles .handle:hover svg { border-color: var(--gold-dim); background-color: var(--gold-faint); }
  #nav button:hover, #side-toggle:hover, #add-btn:hover, #write-btn:hover, #demo-chip:hover {
    background-color: var(--surface-raised);
  }
  #add-btn:hover { border-color: var(--gold); }   /* gold at rest: its rule lights */
  /* the head lights as one under the pointer, halo and all — the book's
     door (the ✎ lights only under itself: it is the details' door) */
  #panel:not(.list) :is(#panel-halo:hover, #panel-halo:hover + #panel-head #panel-name, #panel-head:hover #panel-name) { color: var(--gold); }
  :is(#form-card #f-save, #panel #panel-moment, #book-card #book-moment, #intro-card #intro-start,
      #import-card .import-action, #install-card #install-yes, #tour-hint #tour-next,
      #run-card #run-notes, #finder #finder-shutter):hover:not(:disabled) {
    border-color: var(--gold);
    background-color: var(--gold-wash);
  }
  :is(#form-card #f-delete, #book-card #book-entries .del, #form-card .f-thumb .del):hover:not(:disabled) {
    color: var(--madder);
    border-color: var(--madder-line);
    background-color: var(--madder-faint);
  }
}
:is(#nav, #sidebar, #panel, #form-card, #settings-card, #pair-card, #intro-card, #privacy-card,
    #import-card, #almanac-card, #book-card, #run-card, #install-card, #tour-hint, #viewer-overlay, #finder) button:active:not(:disabled),
#side-toggle:active, #add-btn:active, #write-btn:active, #demo-chip:active, #drop-chip:active,
#panel-handles .handle:active, #panel-notes:active, #book-story:active {
  color: var(--gold);
  border-color: var(--gold-dim);
  translate: 0 1px;
  scale: 0.98;
  transition-duration: 0.04s;   /* down at once; the release keeps the spring above */
}
:is(#panel-suggest, #panel-echo, #panel-moment, #panel-notes, #book-story, #book-moment,
    #f-actions button, #form-card .f-chip, .f-import, #f-prefill-toggle, #run-card button,
    #intro-actions button, .import-action, #install-card button, #tour-next):active:not(:disabled) {
  background-color: var(--gold-faint);
  box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.5);
}
#panel-handles .handle:active svg {
  border-color: var(--gold-dim);
  background-color: var(--gold-faint);
  box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.5);
}
:is(#form-card #f-save, #panel #panel-moment, #book-card #book-moment, #intro-card #intro-start,
    #import-card .import-action, #install-card #install-yes, #tour-hint #tour-next,
    #run-card #run-notes, #finder #finder-shutter):active:not(:disabled) {
  border-color: var(--gold);
  background-color: var(--gold-dim);
}
:is(#form-card #f-delete, #book-card #book-entries .del, #form-card .f-thumb .del):active:not(:disabled) {
  color: var(--madder);
  border-color: var(--madder-line);
  background-color: rgba(212, 148, 130, 0.2);
}
