/*
 * Dear Santy - ui.css: shared components, the approved look (docs/design-mockups/kit.css).
 * Class names only; no inline styles anywhere (the documents' CSP refuses them). Something a person
 * must not see is never hidden here: it is not rendered at all. Day and night: every colour is a role name
 * from tokens.css (html[data-theme] picks the palette), so nothing here is written twice.
 *
 * COMPONENTS (use these; do not invent a second version of any of them)
 *   Page        body (off-white + pink "x" pattern) .screen (centred column, 24px 16px)
 *               .stack / .stack-lg (vertical rhythm) .row / .row-between .grow .center .quiet .small .lead
 *   Headings    h1 / .script (Pacifico, red) h2 (Pacifico, red, smaller) h3 (Pacifico, green) .santa / .santa-title
 *   Cards       .card (white, 14px radius, soft shadow) .card-flat (hairline border, no shadow)
 *               .note (pink message box; .note.green; empty = hidden) .letterpaper .dear
 *   Buttons     ONE scale (tokens.css: --btn-main / --btn-compact / --btn-small, 48 / 38 / 32px on a phone, 44 / 36 / 32px from
 *               1024px), 6px radius. Roles:
 *                 Primary   .btn.btn-primary (filled red)            main
 *                 Secondary .btn.btn-outline (green outline)         main
 *                 Positive  .btn.btn-green (filled green; "Added")   main, or .btn-compact beside a choice
 *                 Choice    Yes / Maybe / No, stars, Auto / Day / Night (.seg, .seg3, .starpick, .segtabs)   compact
 *                 Small     .chip, inline actions (.btn.btn-small)   small
 *                 Quiet     .btn.btn-text (no box)                   compact
 *               Main buttons are full width on a phone and content-width (at least 150px) from 1024px.
 *               Inside .row / .row-between / .appbar / .banner a .btn is content-width. .btn-block forces full width.
 *               Small round icon button: .icon-btn   Links: a (green)  .link  .link-quiet  .back (the one back link)
 *   Forms       .field (label + control) .label .input .textarea .select .hint  (48px, #ccc border, green focus ring)
 *               .code-cells / .code-cell / .code-dash (the magic code)  .check
 *   Lists       .list (64px rows, hairline dividers; put class "row" on the li to lay its contents out in a line)  .thumb  .avatar  .star  .pill (.pill.red / .pill.green)  .badge
 *               .progress > span (green bar)
 *   Frame       .appbar (white bar: logo + script title)  .tabs (bottom tabs: a/button.on)  .banner (.banner-visit / .banner-warn)
 *   Front door  .door (the card is centred on the screen, top to bottom) .backrow .logo .bigname .links .below-link .terms
 *               Built by DS.door() in gate/pair.js: .door-hero (desktop only) .door-col .door-box. A screen change glides (.door-morph, .door-fresh)
 *   Street      <div class="scene"></div> + DS.scene.mount(host, kind) (shared/scene.js): the snowy street, day and night, 64px
 *               on a phone, on top of the app bar and merged into it (.appbar.has-scene), 96px across the top of the
 *               main area on a desktop (.scene-desk), a fading strip under the status bar on the front door
 *               (.scene-door). It folds away below 520px of viewport height and stands still under reduced motion.
 *   Theme       .seg3 > button[aria-pressed]   the "Auto / Day / Night" choice (DS.theme.control, shared/theme.js)
 *   Sound       .sound-btn (a small round speaker, DS.sound.button)  .seg3.seg2 (the On / Off choice, DS.sound.control)
 *   Snow etc.   .fx-snow (the falling-snow canvas)  .fx-spark (stars from a button)  .fx-mail (the stamped, flying envelope)
 *               .wish-row.fx-new (a new wish pops in). All built by shared/fx.js, all off under reduced motion.
 *   Sleigh bar  .sleighbar > .sb-run > .sb-ic + .sb-track > span   a green track with a little sleigh riding its end
 *               (the child's letter, DS.kidTiers.sleighBar; the grown-ups' Presents keeps its own .sleigh)
 *   Modal       CENTRED card, never a bottom sheet:
 *                 <div class="veil"></div>
 *                 <div class="modal" role="dialog" aria-modal="true" aria-labelledby="t">
 *                   <h2 id="t">Send your letter?</h2><p>...</p>
 *                   <button class="btn btn-primary">Send</button><button class="btn btn-outline">Not yet</button>
 *                 </div>
 *               Append both to document.body; remove both to close. .veil click should close (your code).
 *               The older .sheet name is an alias of .modal; .sheet-handle is hidden.
 *   Toast       .toast (small white card, bottom)   Helpers: .sr-only  .fog / .is-clear
 *   Icons       svg.dsi from DS.icons.get(name) (shared/icons.js): 1em tall, so a box's font-size sizes it.
 *               Line icons stroke in currentColor (.k-soft is a tint of it); art icons (.dsi-art) take the
 *               outline and fill colours below, day and night. No emoji anywhere: draw it here instead.
 *
 * PHONE FRAME (every width; the title-spacing fix)
 *   .ds-app > header.appbar   app bar, no gap under it
 *   .pagehead                 the page title row: 56px tall, 28px below the app bar (.ds-app .pv > .pagehead)
 *   .pbody                    the scrolling area: starts 20px under the title row, no card clipped.
 *                             Add .scrolled to it once it has scrolled: the top edge then fades.
 *   .card.lc (and any card whose first child is a heading) is display:flow-root, so a heading's
 *   top margin stays inside the card instead of collapsing out of it.
 *
 * DESKTOP (1024px and up only; phones and iPads in portrait never see any of it)
 *   Shell       .desk-shell       the whole page: sidebar + main. Put it on the root element.
 *               .desk-sidebar     240px floating white card. Inside: .desk-brand (logo + script name),
 *                                 .desk-nav (a / button, .on = current page), .desk-foot, .desk-quick
 *               .desk-main        the area beside it. Inside it ONE .desk-in (max 1200px, centred):
 *               .desk-head        the title row: 64px, 32px under the top, 24px above the content. Holds an h1
 *                                 (2.6rem script, grows) and optional .btn / .icon-btn / .quiet on the right.
 *                                 .title-row is the same row without the fixed height, for headings inside cards.
 *               .desk-body        the scrolling area (fades at the bottom, shadows never clipped)
 *   Top bar     .desk-bar         a white bar for pages that have no sidebar (a child's letter): .desk-brand left,
 *                                 .desk-tabs (a.on) in the middle, anything on the right
 *   Grids       .desk-grid        cards in 2 columns, 3 from 1360px. .two / .three force a count; .top aligns to the top
 *               .desk-split       a main column and a 340px aside (.desk-split.wide: 380px)
 *               .desk-stack       a vertical column of cards, 20px apart
 *               .desk-actions     form buttons, right aligned, a hairline above
 *   Buttons     inside .desk-shell, .desk-bar, .title-row, .desk-head, .desk-actions a .btn is content width, at least
 *               150px (main, 44px tall). .btn-block still means full width.
 */

*, *::before, *::after { box-sizing: border-box; }

/* The page paints edge to edge, safe areas included: the canvas and the body carry the same off-white and "x"
   pattern, and the body pads itself by the safe-area insets (the viewport meta says viewport-fit=cover), so
   nothing sits under the status bar and no strip of another colour shows at the bottom. Frames that size
   themselves to the screen subtract --safe-top and --safe-bottom, never the raw env(). */
html {
  -webkit-text-size-adjust: 100%; text-size-adjust: 100%;
  background-color: var(--off-white); background-image: var(--pattern);
}

body {
  margin: 0;
  min-height: 100vh;
  background-color: var(--off-white);
  background-image: var(--pattern);
  color: var(--text);
  font-family: var(--font-ui);
  font-weight: 400;
  font-size: var(--fs-body);
  line-height: var(--lh);
  -webkit-tap-highlight-color: transparent;
  padding: var(--safe-top) var(--safe-right) var(--safe-bottom) var(--safe-left);
}

/* Headings in the plain font, heavy (Stephen, 2026-11-04: the script can't be read when it runs long). The script
   stays for the short words that carry the look: page titles, the children's names on their bands, the
   countdown, initials, and Santy's own voice (each of those names its font). */
h1, h2, h3 { margin: 0 0 var(--s3); line-height: 1.25; font-family: var(--font-ui); font-weight: 800; letter-spacing: -.005em; text-wrap: balance; }
h1 { font-size: 1.6rem; color: var(--red-dark); }
h2 { font-size: 1.3rem; color: var(--red-dark); }
h3 { font-size: 1.1rem; color: var(--green-dark); }
.script { font-family: var(--font-script); font-weight: 400; color: var(--red-dark); }
p { margin: 0 0 var(--s3); max-width: var(--measure); line-height: 1.5; }
a { color: var(--green-dark); }
img { max-width: 100%; display: block; }
strong, b { font-weight: 700; }

/* Santa's voice: script, and nothing else is ever in script but headings */
.santa { font-family: var(--font-santa); font-weight: 400; font-size: var(--fs-santa); line-height: 1.4; color: var(--red-dark); }
.santa-title { font-family: var(--font-santa); font-weight: 400; font-size: var(--fs-santa-title); line-height: 1.3; color: var(--red-dark); }
.big-number { font-weight: 700; font-size: var(--fs-big-number); line-height: 1; }
.quiet { color: var(--text-quiet); }
.small { font-size: var(--fs-small); }
.lead { font-size: 1.02rem; color: var(--text); margin: 0 0 20px; text-wrap: balance; }

/* layout */
.screen { max-width: 640px; margin: 0 auto; padding: var(--s5) var(--s4); }
.stack > * + * { margin-top: var(--s3); }
.stack-lg > * + * { margin-top: var(--s5); }
.row { display: flex; align-items: center; gap: var(--s3); }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); }
.grow { flex: 1 1 auto; min-width: 0; }
.center { text-align: center; }

/* buttons: ONE scale (tokens.css). Main by default; .btn-compact and .btn-small step down. 6px radius. */
.btn {
  display: flex; align-items: center; justify-content: center; gap: var(--s2);
  width: 100%; min-height: var(--btn-main); padding: 0 var(--btn-px);
  border: 2px solid transparent; border-radius: var(--radius-small);
  font: inherit; font-weight: 700; font-size: var(--btn-fs-main); line-height: 1.2;
  color: var(--text); background: var(--surface);
  cursor: pointer; text-decoration: none; user-select: none;
  transition: transform var(--dur) var(--ease), background-color var(--dur) var(--ease);
}
.btn + .btn { margin-top: var(--s3); }
.btn:active { transform: scale(0.99); }
.btn[disabled], .btn[aria-disabled="true"] { opacity: 0.5; cursor: default; transform: none; }
.btn-primary { background: var(--btn-red); color: #fff; }
.btn-green { background: var(--btn-green); color: #fff; }
.btn-outline { background: var(--surface); color: var(--green-dark); border-color: var(--green-dark); }
.btn-text { background: none; color: var(--text-quiet); min-height: var(--btn-compact); padding: 0 var(--btn-px-compact); font-weight: 500; font-size: var(--btn-fs-compact); width: auto; }
.btn-block, .row > .btn-block, .row-between > .btn-block { width: 100%; }
.btn-big, .btn-hero { min-height: var(--btn-main); }
.btn.btn-compact { min-height: var(--btn-compact); padding: 0 var(--btn-px-compact); font-size: var(--btn-fs-compact); gap: 6px; }
.btn.btn-small { min-height: var(--btn-small); padding: 0 var(--btn-px-small); font-size: var(--btn-fs-small); border-width: 1.5px; gap: 6px; }
/* A wide screen (iPad and up): a button is as wide as its words, never a bar across the page
   (Stephen, 2026-10-20: "why the wide buttons still... I hate them"). The front door's narrow card,
   a centred card (modal) and a sheet keep theirs full width; a phone keeps full width everywhere. */
@media (min-width: 768px) {
  .btn, .btn-block, .row > .btn-block, .row-between > .btn-block { width: auto; min-width: 180px; padding-left: 28px; padding-right: 28px; }
  .btn.btn-compact, .btn.btn-small, .btn-text { min-width: 0; padding-left: var(--btn-px-compact); padding-right: var(--btn-px-compact); }
  .screen .card .btn, .modal .btn, .sheet .btn, .veil + .modal .btn { width: 100%; }
}
/* inside a row a button keeps its own width */
.row > .btn, .row-between > .btn, .appbar .btn, .banner .btn, .toast .btn { width: auto; }
.row > .btn + .btn, .row-between > .btn + .btn { margin-top: 0; }
.link { color: var(--green-dark); font-weight: 500; text-decoration: none; }
button.link { background: none; border: 0; padding: 0; font: inherit; font-weight: 500; cursor: pointer; }
.link-quiet { display: inline-block; color: var(--text-quiet); font: inherit; font-size: .95rem; text-decoration: none; background: none; border: 0; padding: var(--s2) 0; cursor: pointer; }
.back { display: inline-block; color: var(--text-quiet); font-size: .95rem; line-height: 24px; height: 24px; text-align: left; background: none; border: 0; padding: 0; margin: 0; font-family: inherit; cursor: pointer; text-decoration: none; }
.icon-btn {
  width: 44px; height: 44px; border-radius: 50%; border: 1px solid var(--line); background: var(--surface); color: var(--text-quiet);
  display: inline-flex; align-items: center; justify-content: center; font-size: 18px; flex: none; padding: 0; cursor: pointer;
}

/* cards, notes, lists */
.card { background: var(--surface); border-radius: var(--radius); padding: var(--s4); box-shadow: var(--shadow); }
.card.lc, .card:has(> h1, > h2, > h3, > .ch) { display: flow-root; }
.card[hidden] { display: none; }
.card-flat { background: var(--surface); border-radius: var(--radius); padding: var(--s4); border: 1px solid var(--line); }
.note {
  background: var(--tint-red-soft); border: 1px solid var(--tint-red-line); border-radius: 8px;
  padding: 12px 14px; text-align: left; font-size: .92rem; margin: 0 0 16px; color: var(--text);
}
.note.green { background: var(--tint-green-soft); border-color: var(--tint-green-line); }
.note:empty { display: none; }
.note.center { text-align: center; }
.letterpaper {
  background-color: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow); padding: 22px 20px; text-align: left;
  background-image: repeating-linear-gradient(var(--surface) 0 35px, var(--paper-rule) 35px 36px);
}
.dear { font: 400 1.6rem/1.3 var(--font-script); color: var(--red-dark); margin: 0 0 6px; }
.list { list-style: none; margin: 0; padding: 0; text-align: left; }
.list > li:not(.card):not(.card-flat) { min-height: var(--row); padding: 10px 0; border-bottom: 1px solid var(--line); }
.list > li:not(.card):not(.card-flat):first-child { border-top: 1px solid var(--line); }
.list .title { font-weight: 500; }
.list .sub { color: var(--text-quiet); font-size: .85rem; }
.thumb { width: 44px; height: 44px; border-radius: 8px; background: var(--paper); flex: none; display: flex; align-items: center; justify-content: center; font-size: 22px; object-fit: cover; }
.avatar { width: 48px; height: 48px; border-radius: 50%; background: var(--tint-red); color: var(--red-dark); object-fit: cover; flex: none; font-family: var(--font-script); font-size: 1.4rem; display: flex; align-items: center; justify-content: center; }
.avatar.center { text-align: center; }
.avatar-big { width: 96px; height: 96px; font-size: 2.6rem; border: 3px solid var(--surface); box-shadow: var(--shadow); margin: 16px auto 10px; }
.star { color: var(--star-gold); }
.check { width: 26px; height: 26px; border-radius: 6px; border: 2px solid var(--green-dark); flex: none; display: inline-flex; align-items: center; justify-content: center; color: #fff; font-size: 16px; }
.check.on { background: var(--btn-green); }
.pill { display: inline-block; padding: 4px 10px; border-radius: var(--radius-pill); font-size: .8rem; font-weight: 700; background: var(--pill-r-bg); color: var(--pill-r-fg); }
.pill.red { background: var(--pill-r-bg); color: var(--pill-r-fg); }
.pill.green { background: var(--pill-g-bg); color: var(--pill-g-fg); }
.badge { display: inline-block; padding: 3px 10px; border-radius: var(--radius-pill); font-size: .8rem; font-weight: 700; background: var(--pill-r-bg); color: var(--pill-r-fg); text-decoration: none; }
a.badge:hover { text-decoration: underline; }
.progress { height: 10px; background: var(--track); border-radius: var(--radius-pill); overflow: hidden; margin: 6px 0 4px; }
.progress > span { display: block; height: 100%; background: var(--btn-green); }

/* forms: 48px, #ccc border, 6px radius, green focus ring */
.field { display: block; }
.field > label, .field > .label, .label { display: block; text-align: left; font-weight: 500; font-size: .95rem; line-height: normal; margin: 0 0 6px; }
.input, .textarea, .select {
  display: block; width: 100%; min-height: var(--tap); padding: 0 14px;
  font: 400 1rem var(--font-ui); color: var(--text); background: var(--input-bg);
  border: 1px solid var(--line-input); border-radius: var(--radius-small);
}
.textarea { min-height: 96px; padding: 12px 14px; resize: vertical; }
.input::placeholder, .textarea::placeholder { color: var(--hint); }
.hint { color: var(--text-quiet); font-size: .82rem; text-align: left; margin: 6px 0 0; }
.hint:empty { display: none; }
.field > .hint { display: block; }

/* the magic-code cells: 8 boxes and a dash, shrinking to fit the card */
.code-cells { display: flex; justify-content: center; gap: var(--s2); }
.code-cell {
  flex: 0 1 38px; min-width: 0; width: 38px; height: 50px; padding: 0; text-align: center; text-transform: uppercase;
  font: 700 1.3rem var(--font-ui); color: var(--text);
  background: var(--input-bg); border: 1px solid var(--line-input); border-radius: var(--radius-small);
}
.code-dash { flex: 0 1 10px; text-align: center; align-self: center; font-weight: 700; color: var(--text); }

/* the front door: one frame for every screen before sign-in (and the lock screen).
   The card is centred on the screen, top to bottom, and glides between heights. */
.door { max-width: 440px; }
.screen.door {
  min-height: calc(100vh - var(--safe-top) - var(--safe-bottom));
  min-height: calc(100dvh - var(--safe-top) - var(--safe-bottom));
  display: flex; flex-direction: column;
}
.door-col { flex: 1 1 auto; display: flex; flex-direction: column; justify-content: center; }
.door-box { width: 100%; }
/* a screen change glides: the card grows or shrinks to the next screen's height while its contents fade in */
.door-morph { overflow: hidden; transition: height 250ms var(--ease); }
.door-fresh .door-box .card > *, .door-fresh .door-box .below-link { animation: ds-door-fade 250ms var(--ease) both; }
@keyframes ds-door-fade { from { opacity: 0; } to { opacity: 1; } }
.door .card { padding: 14px 22px 26px; text-align: center; }
.backrow { height: 24px; text-align: left; margin: 0 0 6px; }
.door .logo, .logo { width: 110px; height: auto; display: block; margin: 0 auto 10px; }
.door h1 { margin: 0 0 8px; }
.door h1.solo { margin-bottom: 22px; }
.door .lead { margin: 0 auto 22px; }
.door .lead.lead-sm { margin-bottom: 18px; }
.door .logo + .lead { margin-top: 18px; }
.door .code-cells { margin-bottom: 22px; }
.door .field { margin: 0 0 16px; }
.door .btn { margin-top: 8px; }
.door .btn + .btn { margin-top: var(--s3); }
.door .note { margin: 0 0 12px; }
.door .hint.center { text-align: center; }
.door-hero, .lead-desk { display: none; }
.bigname { font-size: 1.6rem; font-weight: 700; margin: 0 0 22px; }
.links { display: flex; justify-content: space-between; margin-top: 20px; font-size: .95rem; line-height: normal; }
.links.one { justify-content: center; }
.below-link { text-align: center; margin: 20px 0 0; font-size: .95rem; max-width: none; }
.terms { color: var(--text-quiet); font-size: .82rem; margin: 14px 0 6px; text-align: center; max-width: none; }
.terms a { color: var(--green-dark); font-weight: 500; text-decoration: none; white-space: nowrap; }

/* the phone frame: title spacing. The title row sits 28px under the app bar, the first card 20px under the
   title row, and the scrolling area starts below the title so nothing is clipped (docs/design-mockups png/4-11, 4-12). */
.ds-app > header.appbar { margin: 0; }
.ds-app .pv > .pagehead { height: 56px; margin: 28px 0 0; }
.ds-app .pv > .pagehead h1 { font-size: 1.8rem; }
.ds-app .pv > .pbody { margin-top: 8px; padding-top: 12px; }
.ds-app .pv > .pbody.scrolled {
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 18px, #000 calc(100% - 24px), transparent);
  mask-image: linear-gradient(to bottom, transparent 0, #000 18px, #000 calc(100% - 24px), transparent);
}

/* app frame: header bar, bottom tabs, banners */
.appbar { display: flex; align-items: center; gap: 10px; background: var(--surface); box-shadow: var(--shadow); border-radius: var(--radius); padding: 8px 12px; margin: 0 0 14px; min-height: 56px; color: var(--text); }
.appbar h1, .appbar .title { font: 400 1.35rem/1.3 var(--font-script); color: var(--red-dark); margin: 0; flex: 1; }
.appbar .logo { width: 64px; margin: 0; }
.tabs { display: flex; background: var(--surface); box-shadow: var(--shadow); border-radius: var(--radius); }
.tabs a, .tabs button { flex: 1; text-align: center; padding: 10px 0 8px; font: inherit; font-size: .75rem; color: var(--text-quiet); text-decoration: none; background: none; border: 0; cursor: pointer; }
.tabs .on { color: var(--red-dark); font-weight: 700; }
.tabs b { display: block; font-size: 20px; font-weight: 400; }

.banner {
  position: sticky; top: 0; z-index: 50;
  display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
  min-height: var(--tap); padding: var(--s2) var(--s4);
  font-weight: 700;
}
.banner-visit { background: var(--btn-green); color: #fff; }
.banner-warn { background: var(--btn-red); color: #fff; }
.banner .btn { min-height: var(--btn-compact); padding: 0 var(--btn-px-compact); font-size: var(--btn-fs-compact); background: var(--surface); color: var(--text); }

/* modal: a CENTRED card over a veil. Never a bottom sheet. See the component list at the top. */
/* One open and one close for every card: the veil fades in under the card as it settles; on close the card
   goes at once and the dimming fades away (.veil-out, added by shared/dom.js). Under reduced motion --dur is 0. */
.veil { position: fixed; inset: 0; background: var(--veil); z-index: 40; animation: ds-veil-in var(--dur) var(--ease); }
.veil.veil-on { animation: none; }
.veil-out { position: fixed; inset: 0; background: var(--veil); z-index: 40; pointer-events: none; animation: ds-veil-out var(--dur) var(--ease) forwards; }
@keyframes ds-veil-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes ds-veil-out { from { opacity: 1; } to { opacity: 0; } }
.modal, .sheet {
  position: fixed; top: 50%; left: 50%; z-index: 41;
  width: calc(100% - 32px); max-width: 360px; max-height: calc(100vh - 32px); overflow: auto;
  transform: translate(-50%, -50%);
  background: var(--surface); color: var(--text); text-align: center;
  border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 24px 22px;
  animation: ds-modal-in var(--dur) var(--ease);
}
.modal h1, .modal h2, .sheet h1, .sheet h2 { margin: 0 0 var(--s2); }
.modal p, .sheet p { margin-left: auto; margin-right: auto; }
.modal .btn, .sheet .btn { margin-top: var(--s3); }
.sheet-handle { display: none; }
@keyframes ds-modal-in { from { transform: translate(-50%, -48%); opacity: 0; } to { transform: translate(-50%, -50%); opacity: 1; } }

/* the site's pages read in the app (shared/pages.js): a full page over everything, one '‹ Back' that stays at the top.
   Above the visit banner (50), under a toast (60) and the lock screen. */
.rdr-layer {
  position: fixed; inset: 0; z-index: 55; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  background-color: var(--off-white); background-image: var(--pattern); color: var(--text); text-align: left;
  padding: 0 var(--safe-right) var(--safe-bottom) var(--safe-left);
}
.rdr-bar { position: sticky; top: 0; z-index: 1; background: var(--off-white); padding: calc(var(--safe-top) + 6px) 12px 6px; }
.rdr-back {
  display: inline-flex; align-items: center; gap: 5px; min-height: var(--tap); padding: 0 10px; margin: 0; border: 0; background: none;
  font: inherit; font-size: 1.05rem; color: var(--text-quiet); cursor: pointer;
}
.rdr-back:focus-visible { outline: 3px solid var(--star); outline-offset: 2px; border-radius: 8px; }
.rdr-wrap { max-width: 720px; margin: 0 auto; padding: 4px 16px 40px; }
.rdr-title { font-size: 1.7rem; margin: 0 0 2px; }
.rdr-upd { color: var(--text-quiet); font-size: .85rem; margin: 0 0 14px; }
.rdr-card { display: flow-root; }
.rdr-card .rdr-h2 { font-size: 1.2rem; margin: 26px 0 8px; scroll-margin-top: calc(var(--safe-top) + 64px); }
.rdr-card .rdr-h3 { font-size: 1.05rem; margin: 18px 0 6px; scroll-margin-top: calc(var(--safe-top) + 64px); }
.rdr-card > :first-child { margin-top: 0; }
.rdr-card p { max-width: none; }
.rdr-list { margin: 0 0 14px; padding-left: 1.3em; }
.rdr-list li { margin: 0 0 6px; line-height: 1.5; }
.rdr-table { margin: 4px 0 16px; border-top: 1px solid var(--line); }
.rdr-tr { padding: 10px 0 6px; border-bottom: 1px solid var(--line); }
.rdr-td { margin: 0 0 6px; font-size: .95rem; }
.rdr-td1 { font-weight: 600; }
.rdr-th { display: block; font-size: .72rem; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--text-quiet); }
.rdr-layer .ds-loading { margin-top: 40px; }

.toast {
  position: fixed; left: var(--s4); right: var(--s4); bottom: calc(var(--s5) + var(--safe-bottom)); z-index: 60;
  max-width: 480px; margin: 0 auto; padding: var(--s3) var(--s4);
  background: var(--surface); color: var(--text); border-radius: var(--radius); box-shadow: var(--shadow);
}

/* formerly the night sky (countdown): there is no dark theme, so it is a plain white card */
.night { background: var(--surface); color: var(--text); }

/* fogged figures: blurred until tapped (the figure is real text, so never rely on this alone) */
.fog { filter: blur(6px); color: var(--muted); cursor: pointer; transition: filter var(--dur) var(--ease); }
.fog.is-clear { filter: none; color: inherit; }

/* focus: always visible for keyboards and switch control */
:focus { outline: none; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-radius: var(--radius-small); }
.input:focus, .textarea:focus, .select:focus, .code-cell:focus { border-color: var(--focus); box-shadow: var(--focus-ring); outline: none; }

/* screen-reader-only text */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* title row (phone and desktop): a heading that grows and buttons beside it */
.title-row { display: flex; align-items: center; gap: var(--s3); }
.title-row > h1, .title-row > h2, .title-row > h3 { flex: 1 1 auto; min-width: 0; margin: 0; }

/* ===== DESKTOP: 1024px and up. Nothing above this line changes. ===== */
@media (min-width: 1024px) {
  .desk-shell { display: flex; height: 100vh; height: 100dvh; overflow: hidden; }
  .desk-sidebar {
    width: 240px; flex: none; margin: 16px 0 16px 16px; padding: 22px 14px 16px;
    background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow);
    display: flex; flex-direction: column; overflow-y: auto;
  }
  .desk-brand { display: flex; align-items: center; gap: 10px; padding: 0 8px 20px; margin: 0 0 14px; border-bottom: 1px solid var(--line); color: var(--red-dark); text-decoration: none; }
  .desk-brand img, .desk-brand .logo { height: 52px; width: auto; margin: 0; display: block; }
  .desk-brand span, .desk-brand .title { font: 400 1.5rem/1.3 var(--font-script); color: var(--red-dark); white-space: nowrap; }
  .desk-nav { display: flex; flex-direction: column; }
  .desk-nav a, .desk-nav button {
    display: flex; align-items: center; gap: 14px; width: 100%; height: 52px; padding: 0 16px; margin: 0 0 4px;
    border: 0; border-radius: 10px; background: none; font: inherit; font-weight: 500; font-size: 1rem;
    color: var(--nav); text-align: left; text-decoration: none; cursor: pointer;
  }
  .desk-nav a:hover, .desk-nav button:hover { background: var(--paper); }
  .desk-nav .on, .desk-nav .on:hover { background: var(--tint-red); color: var(--red-dark); font-weight: 700; }
  .desk-foot { margin-top: auto; border-top: 1px solid var(--line); padding-top: 12px; }
  .desk-quick {
    display: flex; align-items: center; gap: 14px; width: 100%; height: 48px; padding: 0 16px;
    border: 0; border-radius: 10px; background: none; font: inherit; font-weight: 500; color: var(--green-dark); text-align: left; cursor: pointer; text-decoration: none;
  }
  .desk-quick:hover { background: var(--paper); }
  .desk-foot .quiet { font-size: .8rem; padding: 4px 16px 0; margin: 0; }

  .desk-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; padding: 0 40px; }
  .desk-in { width: 100%; max-width: 1200px; margin: 0 auto; flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
  .desk-head { height: 64px; margin: 32px 0 24px; display: flex; align-items: center; gap: 14px; flex: none; }
  .desk-head h1 { font: 400 2.6rem/1.6 var(--font-script); color: var(--red-dark); flex: 1 1 auto; min-width: 0; margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .desk-head .quiet { white-space: nowrap; }
  .desk-body {
    flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; margin: -12px -20px 0; padding: 12px 20px 36px;
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 40px), transparent); mask-image: linear-gradient(to bottom, #000 calc(100% - 40px), transparent);
  }

  .desk-bar {
    display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: var(--s4);
    height: 76px; flex: none; padding: 0 28px; background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow);
  }
  .desk-bar > :last-child { justify-self: end; }
  .desk-bar .desk-brand { padding: 0; margin: 0; border: 0; }
  .desk-tabs { display: flex; gap: 6px; }
  .desk-tabs a, .desk-tabs button {
    display: flex; align-items: center; gap: 8px; height: 48px; padding: 0 20px; border: 0; border-radius: var(--radius-pill);
    background: none; font: inherit; font-weight: 500; color: var(--text-quiet); text-decoration: none; cursor: pointer;
  }
  .desk-tabs .on { background: var(--tint-red); color: var(--red-dark); font-weight: 700; }

  .desk-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; align-items: stretch; }
  .desk-grid.top { align-items: start; }
  .desk-grid.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .desk-grid.three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .desk-split { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 24px; align-items: start; }
  .desk-split.wide { grid-template-columns: minmax(0, 1fr) 380px; }
  .desk-stack { display: flex; flex-direction: column; gap: 20px; min-width: 0; }
  .desk-actions { display: flex; justify-content: flex-end; gap: 12px; margin-top: 28px; padding-top: 24px; border-top: 1px solid var(--line); }

  /* cards, forms and rows at desktop size */
  .desk-shell .card { padding: 20px; margin: 0; }
  .desk-shell .card.lc { padding: 0 20px; }
  .desk-shell .input, .desk-shell .select { min-height: 48px; font-size: 1rem; }
  .desk-shell .field { margin: 0 0 14px; }
  .desk-shell .list > li:not(.card):not(.card-flat) { min-height: var(--row); }

  /* buttons: content width, at least 150px (main); compact and small ones keep their own size */
  .desk-shell .btn, .desk-bar .btn, .title-row .btn, .desk-head .btn, .desk-actions .btn {
    width: auto; min-width: var(--btn-min); padding: 0 var(--btn-px); margin: 0; font-size: var(--btn-fs-main);
  }
  .desk-shell .btn.btn-compact, .desk-bar .btn.btn-compact, .title-row .btn.btn-compact, .desk-head .btn.btn-compact, .desk-actions .btn.btn-compact { min-width: 0; padding: 0 var(--btn-px-compact); font-size: var(--btn-fs-compact); }
  .desk-shell .btn.btn-small, .desk-bar .btn.btn-small, .title-row .btn.btn-small, .desk-head .btn.btn-small, .desk-actions .btn.btn-small { min-width: 0; padding: 0 var(--btn-px-small); font-size: var(--btn-fs-small); }
  .desk-shell .btn + .btn, .desk-bar .btn + .btn, .title-row .btn + .btn, .desk-head .btn + .btn, .desk-actions .btn + .btn { margin-top: 0; }
  .desk-shell .btn.btn-block, .desk-bar .btn.btn-block, .title-row .btn.btn-block, .desk-head .btn.btn-block, .desk-actions .btn.btn-block { width: 100%; }
  .desk-shell .btn.btn-text { min-width: 0; padding: 0 var(--btn-px-compact); font-size: var(--btn-fs-compact); }

  /* the front door: a split. Logo and the line on the left, the card on the right. Every front-door
     screen uses it, so nothing jumps between them. */
  .screen.door {
    max-width: none; padding: 0;
    display: grid; grid-template-columns: 1fr 1fr; align-items: stretch;
  }
  .door-hero { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 48px 64px; text-align: center; }
  .door-hero .door-logo { width: 360px; max-width: 100%; height: auto; margin: 0 0 24px; }
  .door-hero .door-tag { font: 400 3.1rem/1.3 var(--font-script); color: var(--red-dark); max-width: 580px; margin: 0; text-wrap: balance; }
  .door-col { align-items: center; padding: 48px 64px; }
  .door-box { width: 480px; max-width: 100%; }
  .door-box .card { padding: 16px 44px 40px; }
  .door-box .card > .logo { display: none; }
  .door-box .card h1 { font-size: 2.2rem; margin: 0 0 22px; }
  .door-box .card .field { margin: 0 0 18px; }
  .door-box .card .input { min-height: 52px; }
  .door-box .card .lead { font-size: 1.1rem; margin: 16px auto 24px; }
  .door-box .card .code-cells { gap: var(--s2); }
  .door-box .card .code-cell { flex: 0 1 40px; width: 40px; height: 54px; }
  /* the front page: the card and the grown-ups link share one white card */
  .door-box.joined { background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow); padding: 0 0 36px; }
  .door-box.joined .card { background: none; box-shadow: none; border-radius: 0; padding-bottom: 0; }
  .door-box.joined .below-link { margin: 14px 0 0; }
  .door .lead-phone { display: none; }
  .door .lead-desk { display: block; }
}
@media (min-width: 1360px) {
  .desk-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .desk-grid.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ===== the street: day and night (shared/scene.js draws it, theme.js picks the palette) ===== */
.scene { display: block; position: relative; height: 64px; overflow: hidden; pointer-events: none; -webkit-user-select: none; user-select: none; }
.scene > svg { display: block; width: 100%; height: 100%; }
/* both streets are in the picture; the theme shows one. A hidden street does not animate. */
html:not([data-theme="night"]) .sc-night, html[data-theme="night"] .sc-day { display: none; }

/* phone: the street is the top of the app bar, and the bar's own row sits under it (64px + the row) */
@media (min-height: 520px) {
  html .appbar.has-scene { position: relative; overflow: hidden; padding-top: 64px; height: auto; min-height: 116px; }
  .appbar.has-scene > .scene { position: absolute; top: 0; left: 0; right: 0; }
}
/* a short screen (a phone on its side) folds the street away; only the title row stays */
@media (max-height: 519.98px) { .scene { display: none; } }

/* the front door: a strip under the status bar, fading out top and bottom into the page */
.scene.scene-door { position: fixed; left: 0; right: 0; top: var(--safe-top); height: 76px; z-index: -1; }
.screen.door { position: relative; z-index: 0; }
@media (min-width: 1024px) { .scene.scene-door { height: 96px; } }

/* the logo's dark outline vanishes on navy: at night it sits on the cream badge (the app icon's cream) */
html[data-theme="night"] img[src$="dear-santy-logo.png"] { background: var(--badge); box-sizing: content-box; padding: 3px 5px; border-radius: 11px; }
/* the front door's logo sits on a round cream medallion; drawn as a background so the logo itself is never clipped */
html[data-theme="night"] .door img.logo, html[data-theme="night"] img.door-logo {
  aspect-ratio: 1; object-fit: contain; box-sizing: border-box; padding: 9%; border-radius: 0;
  background: radial-gradient(closest-side, var(--badge) 93%, rgba(255, 244, 223, 0.13) 94%, rgba(255, 244, 223, 0.13) 99.5%, transparent 100%);
}
html[data-theme="night"] .door img.logo { width: 128px; height: auto; margin-bottom: 6px; }
html[data-theme="night"] img.door-logo { height: auto; }

/* the street's motion: transform and opacity only. Reduced motion shows the still picture (see the foot of this file). */
.scene .tw { animation: ds-tw 2.6s ease-in-out infinite; }
.scene .tw.d1 { animation-delay: -.9s; animation-duration: 3.1s; }
.scene .tw.d2 { animation-delay: -1.7s; animation-duration: 2.2s; }
.scene .glow { --o: .3; }
@keyframes ds-tw { 0%, 100% { opacity: var(--o, 1); } 50% { opacity: calc(var(--o, 1) * .22); } }
.scene .puff { transform-box: fill-box; transform-origin: center; animation: ds-rise 5s ease-out infinite; }
.scene .puff.p1 { animation-delay: -1.7s; }
.scene .puff.p2 { animation-delay: -3.4s; }
@keyframes ds-rise { 0% { transform: translate(0, 8px) scale(.5); opacity: 0; } 20% { opacity: .9; } 100% { transform: translate(7px, -14px) scale(1.5); opacity: 0; } }
.scene .snow { animation: ds-fall 8s linear infinite; }
.scene .snow.f0 { animation-duration: 6.3s; animation-delay: -1s; }
.scene .snow.f1 { animation-duration: 7.4s; animation-delay: -4.2s; }
.scene .snow.f2 { animation-duration: 8.6s; animation-delay: -2.4s; }
.scene .snow.f3 { animation-duration: 9.5s; animation-delay: -7s; }
.scene .snow.f4 { animation-duration: 10.7s; animation-delay: -3.3s; }
.scene .snow.f5 { animation-duration: 6.9s; animation-delay: -5.6s; }
.scene .snow.f6 { animation-duration: 8.1s; animation-delay: -6.2s; }
.scene .snow.f7 { animation-duration: 9.1s; animation-delay: -.4s; }
@keyframes ds-fall { 0% { transform: translate(0, -10px); opacity: 0; } 10% { opacity: 1; } 50% { transform: translate(4px, 18px); } 90% { opacity: 1; } 100% { transform: translate(-2px, 40px); opacity: 0; } }
/* the sleigh crosses in about 9 seconds, leaves the picture, and the rest of the 30 seconds is quiet */
.scene .sleigh-run { --x1: 130px; animation: ds-cross 30s linear infinite; }
.scene .scene-svg.wide .sleigh-run { --x1: 340px; }
@keyframes ds-cross { 0% { transform: translateX(var(--x0, -800px)); } 30% { transform: translateX(var(--x1)); } 100% { transform: translateX(var(--x1)); } }
.scene .sleigh-bob { animation: ds-bob 2.4s ease-in-out infinite; }
@keyframes ds-bob { 0%, 100% { translate: 0 0; } 50% { translate: 0 -1.5px; } }
.scene .cloud { animation: ds-drift 40s ease-in-out infinite alternate; }
@keyframes ds-drift { from { transform: translateX(-6px); } to { transform: translateX(14px); } }
.scene .robin { animation: ds-hop 12s ease-in-out infinite; }
@keyframes ds-hop { 0%, 56%, 76%, 100% { transform: translate(0, 0); } 60% { transform: translate(2px, -3px); } 64% { transform: translate(4px, 0); } 68% { transform: translate(6px, -3px); } 72% { transform: translate(8px, 0); } 82% { transform: translate(6px, -3px); } 86% { transform: translate(4px, 0); } 90% { transform: translate(2px, -3px); } 94% { transform: translate(0, 0); } }

/* the Auto / Day / Night choice (a Settings row, and the child's "About my letter") */
.set-row b { display: block; font-weight: 500; font-size: .95rem; }
.set-row small { display: block; font-size: .8rem; margin-top: 2px; line-height: 1.3; }
.seg3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px; padding: 4px; margin: 10px 0 0; background: var(--bg); border-radius: 10px; box-shadow: inset 0 0 0 1px var(--line); }
.seg3 button { height: var(--btn-compact); padding: 0 4px; border: 0; border-radius: 8px; background: none; color: var(--text-quiet); font: 500 var(--btn-fs-compact) var(--font-ui); cursor: pointer; white-space: nowrap; }
.seg3 button[aria-pressed="true"] { background: var(--btn-red); color: #fff; font-weight: 700; }

/* ===== sound, snow, sparkle (shared/sound.js, shared/fx.js) ===== */
/* the speaker button's tap target is the full 44px; it sits quietly in a bar */
.sound-btn { color: var(--green-dark); }
.sound-btn svg { display: block; }
.appbar .sound-btn { border: 0; background: none; width: 44px; height: 44px; }
/* the On / Off choice is the same control as Auto / Day / Night with two buttons */
.seg3.seg2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* falling snow: one canvas over the page, under every dialog, taking no taps */
.fx-snow { position: fixed; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 30; }

/* the stars that fly out of the Add button */
.fx-spark { position: fixed; width: 0; height: 0; z-index: 70; pointer-events: none; }
.fx-spark i { position: absolute; left: -8px; top: -9px; font-style: normal; font-size: 17px; line-height: 1; opacity: 0; animation: ds-spark 700ms ease-out forwards; }
.fx-spark i .dsi { display: block; }
.fx-spark i.g0 { color: var(--star-gold); }
.fx-spark i.g1 { color: var(--btn-red); }
.fx-spark i.g2 { color: var(--green-light); }
.fx-spark i.s1 { --dx: 8px; --dy: -45px; }
.fx-spark i.s2 { --dx: 42px; --dy: -40px; }
.fx-spark i.s3 { --dx: 69px; --dy: -10px; }
.fx-spark i.s4 { --dx: 41px; --dy: 22px; }
.fx-spark i.s5 { --dx: 25px; --dy: 52px; }
.fx-spark i.s6 { --dx: -12px; --dy: 69px; }
.fx-spark i.s7 { --dx: -33px; --dy: 32px; }
.fx-spark i.s8 { --dx: -57px; --dy: 8px; }
.fx-spark i.s9 { --dx: -62px; --dy: -33px; }
.fx-spark i.s10 { --dx: -20px; --dy: -41px; }
@keyframes ds-spark {
  0% { opacity: 0; transform: translate(0, 0) scale(.3) rotate(0deg); }
  18% { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(1.15) rotate(160deg); }
}
/* the wish that was just added lights up in the list, and its picture pops (the row itself never moves or resizes) */
.wish-row.fx-new { animation: ds-glow 900ms ease-out; }
.wish-row.fx-new .wish-thumb { animation: ds-pop 700ms ease-out; }
@keyframes ds-glow { 0% { background: var(--tint-red-soft); } 100% { background: transparent; } }
@keyframes ds-pop { 0% { transform: scale(.7); } 45% { transform: scale(1.12); } 100% { transform: none; } }

/* the letter is sent: a stamp thumps on the envelope, and it flies away */
.fx-mail { position: fixed; inset: 0; z-index: 70; pointer-events: none; display: flex; align-items: center; justify-content: center; }
.fx-mail-in { position: relative; width: 200px; height: 130px; filter: drop-shadow(0 6px 14px rgba(0, 0, 0, .25)); animation: ds-mail-fly 800ms 1000ms cubic-bezier(.5, 0, .9, .4) forwards; }
.fx-mail-in > svg:first-child { display: block; width: 200px; height: 130px; animation: ds-mail-in 300ms ease-out both; }
.fx-stamp { position: absolute; right: 16px; top: 26px; opacity: 0; animation: ds-stamp 380ms 350ms cubic-bezier(.2, 1.4, .4, 1) both; }
@keyframes ds-mail-in { from { opacity: 0; transform: scale(.8); } to { opacity: 1; transform: none; } }
@keyframes ds-stamp {
  0% { opacity: 0; transform: scale(2.6) rotate(-14deg); }
  60% { opacity: 1; transform: scale(.92) rotate(4deg); }
  100% { opacity: 1; transform: scale(1) rotate(-3deg); }
}
@keyframes ds-mail-fly { 0% { transform: none; opacity: 1; } 100% { transform: translate(40vw, -70vh) scale(.35) rotate(18deg); opacity: 0; } }

/* the sleigh bar: a green track and a little sleigh riding the end of the green (DS.kidTiers.sleighBar) */
.sleighbar { position: relative; padding: 4px 2px 6px; }
.sleighbar .sb-run { position: relative; height: 26px; margin-right: 28px; }
.sleighbar .sb-ic { position: absolute; left: 0; bottom: -3px; z-index: 1; font-size: 22px; line-height: 1; transition: left 600ms var(--ease); }
.sleighbar .sb-track { height: 10px; background: var(--track); border-radius: 5px; overflow: hidden; box-shadow: inset 0 1px 3px rgba(0, 0, 0, .1); }
.sleighbar .sb-track > span { display: block; height: 100%; background: linear-gradient(90deg, var(--btn-green), var(--green-light)); transition: width 600ms var(--ease); }

/* ---------- icons (shared/icons.js) ---------- */
.dsi {
  display: inline-block; flex: none; vertical-align: -0.14em; overflow: visible;
  --dsi-o: #0D4A38; --dsi-red: #D5343F; --dsi-green: #23856D; --dsi-gold: #F2B134; --dsi-cream: #FFF4DF;
  --dsi-white: #FFFFFF; --dsi-brown: #A8693A; --dsi-tan: #F3D3A0; --dsi-skin: #FBD2B4; --dsi-cheek: #EE8E80; --dsi-blue: #6FA8DC; --dsi-dark: #0D4A38;
}
html[data-theme="night"] .dsi {
  --dsi-o: #F3E9D8; --dsi-red: #E4505B; --dsi-green: #2FA683; --dsi-gold: #F4C95D; --dsi-white: #FFF8EC;
  --dsi-brown: #B87A48; --dsi-tan: #E9C792; --dsi-blue: #7FB4E6; --dsi-dark: #10202F;
}
.dsi-art { stroke: var(--dsi-o); }
.dsi .k-soft { fill: currentColor; fill-opacity: .14; }
.dsi .k-cur { fill: currentColor; }
.dsi .k-red { fill: var(--dsi-red); }
.dsi .k-green { fill: var(--dsi-green); }
.dsi .k-gold { fill: var(--dsi-gold); }
.dsi .k-cream { fill: var(--dsi-cream); }
.dsi .k-white { fill: var(--dsi-white); }
.dsi .k-brown { fill: var(--dsi-brown); }
.dsi .k-tan { fill: var(--dsi-tan); }
.dsi .k-skin { fill: var(--dsi-skin); }
.dsi .k-cheek { fill: var(--dsi-cheek); }
.dsi .k-blue { fill: var(--dsi-blue); }
.dsi .k-ink { fill: var(--dsi-o); }
.dsi .k-dark { fill: var(--dsi-dark); }
.dsi .s-dark { stroke: var(--dsi-dark); }
.dsi .s-red { stroke: var(--dsi-red); }
.dsi .s-gold { stroke: var(--dsi-gold); }
.dsi .s-cream { stroke: var(--dsi-cream); }
.tabs b .dsi { display: block; margin: 0 auto; width: 24px; height: 24px; }
.seg3 button .dsi { width: 17px; height: 17px; margin-right: 6px; vertical-align: -3px; }
.check .dsi { width: .95em; height: .95em; }
.star .dsi { vertical-align: -0.12em; }
.dsi-star + .dsi-star { margin-left: 1px; }
.fog .dsi { width: 13px; height: 13px; margin: 0 1px; vertical-align: -2px; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0ms !important; animation-iteration-count: 1 !important; transition-duration: 0ms !important; scroll-behavior: auto !important; }
  /* the street is a still picture: smoke, snow, stars, lights all drawn, the sleigh parked beside the cloud or moon */
  .scene *, .scene *::before { animation: none !important; }
}

/* The front door, the letter and the grown-ups' side are three documents: a soft cross-fade between them
   where the browser can (Safari 18.2+, Chrome 126+), an ordinary page change where it can't. */
@view-transition { navigation: auto; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: 180ms; }
@media (prefers-reduced-motion: reduce) { @view-transition { navigation: none; } }

/* the front door's "Scan QR code" (gate.js, app only) */
.gate-scan-btn { margin-top: 12px; gap: 10px; }
.gate-scan-note:empty { display: none; }
.gate-scan-note { margin: 10px 0 0; }

/* The loading mark (icons.js loading()): a turning snowflake in place of words. It waits a beat
   before it shows, so a quick answer never flashes it. */
.ds-loading { display: flex; justify-content: center; align-items: center; padding: 56px 0; color: var(--green, #006F57); opacity: 0; animation: ds-loading-in .3s ease .25s forwards; }
.ds-loading-flake { width: 40px; height: 40px; animation: ds-loading-turn 2.4s linear infinite; }
@keyframes ds-loading-in { to { opacity: 1; } }
@keyframes ds-loading-turn { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .ds-loading-flake { animation: ds-loading-breathe 1.6s ease-in-out infinite alternate; }
  @keyframes ds-loading-breathe { from { opacity: .45; } to { opacity: 1; } }
}

/* The welcome page: dearsanty.com in a web browser (gate.js "welcome"; the app's front door is untouched).
   v9 (Stephen, 2026-10-26): the street scrolls away with the page (nothing slides over it); the logo, the line and the
   buttons come first, then "See how it works" and the tour with no box round it (the box takes the video's shape),
   then the five points and the footer. 1024px and up: logo, line and buttons on the left, the computer tour on the right,
   the points in a row under both. */
.screen.welcome { position: relative; z-index: 0; max-width: 520px; padding: 88px var(--s4) var(--s5); text-align: center; }
.screen.welcome > .scene.scene-door { position: absolute; top: var(--safe-top); left: calc(50% - 50vw); right: auto; width: 100vw; }
body:has(.screen.welcome) { overflow-x: clip; }      /* the street is 100vw wide: no sideways scroll where a scrollbar takes room */
.wl-off { display: none !important; }
.wl-hero { padding: 8px 0 0; }
.wl-logo { width: 144px; height: auto; margin: 0 auto 10px; }
.wl-head { font-size: 2.2rem; line-height: 1.25; margin: 0 0 10px; }
.wl-line { margin: 0 auto; max-width: 28ch; font-size: 1.05rem; text-wrap: balance; }
.wl-btns { margin-top: 18px; }
.wl-btns .btn + .btn { margin-top: 12px; }
.wl-btns .below-link { margin-top: 16px; }
.wl-tour-h { margin: 30px 0 14px; }
.wl-video { position: relative; aspect-ratio: 720 / 1560; width: min(300px, 78vw); margin: 0 auto 4px; border-radius: 26px; overflow: hidden; box-shadow: 0 10px 30px rgba(0, 0, 0, .18); }
.wl-vid { display: block; width: 100%; height: 100%; object-fit: cover; background: var(--surface); }
.wl-play {
  position: absolute; left: 50%; top: 50%; width: 64px; height: 64px; margin: -32px 0 0 -32px; padding: 0;
  display: flex; align-items: center; justify-content: center; border: 0; border-radius: 50%;
  background: var(--btn-red); color: #fff; cursor: pointer; box-shadow: 0 4px 14px rgba(0, 0, 0, 0.28);
  transition: transform var(--dur) var(--ease);
}
.wl-play:hover { transform: scale(1.06); }
.wl-play:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
.wl-play svg { width: 30px; height: 30px; margin-left: 3px; }
.wl-feats { list-style: none; margin: 28px 0 0; padding: 4px 16px; background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow); text-align: left; }
.wl-feat { display: grid; grid-template-columns: 44px 1fr; column-gap: 14px; align-items: center; min-height: var(--row, 64px); padding: 8px 0; border-bottom: 1px solid var(--line); }
.wl-feat:last-child { border-bottom: 0; }
.wl-feat-ic { grid-row: 1 / span 2; width: 44px; height: 44px; border-radius: 50%; background: var(--tint-red); color: var(--green-dark); display: flex; align-items: center; justify-content: center; }
.wl-feat b { font-weight: 700; line-height: 1.25; align-self: end; }
.wl-feat-s { color: var(--text-quiet); font-size: .9rem; line-height: 1.3; align-self: start; }
.wl-foot { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px 20px; margin: 22px 0 6px; }
.wl-foot-link { color: var(--text-quiet); font-size: .95rem; text-decoration: none; padding: 8px 4px; }
.wl-foot-link:hover { color: var(--green-dark); text-decoration: underline; }
@media (min-width: 1024px) {
  .screen.welcome { max-width: 1240px; padding: 136px 56px 32px; display: grid; grid-template-columns: 1fr 1.35fr; column-gap: 48px; align-items: center; text-align: left; }
  .wl-hero { padding: 0; }
  .wl-logo { width: 230px; margin: 0 0 18px; }
  .wl-head { font-size: 3.1rem; line-height: 1.3; margin: 0 0 16px; max-width: 580px; }
  .wl-line { font-size: 1.2rem; max-width: 34ch; margin: 0; }
  .wl-btns { max-width: 380px; margin-top: 26px; }
  .wl-btns .below-link { text-align: left; margin-top: 14px; }
  .wl-tour-h { display: none; }
  .wl-video { width: 100%; margin: 0; border-radius: 16px; aspect-ratio: 1280 / 800; }
  .wl-video.wl-tall { width: min(300px, 100%); margin: 0 auto; border-radius: 26px; }
  .wl-feats { grid-column: 1 / -1; margin-top: 40px; padding: 0; background: none; box-shadow: none; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 20px; }
  .wl-feat { display: flex; flex-direction: column; justify-content: flex-start; align-items: center; text-align: center; gap: 4px; padding: 22px 14px; border: 0; background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow); }
  .wl-feat-ic { margin-bottom: 8px; }
  .wl-feat b, .wl-feat-s { align-self: auto; }
  .wl-foot { grid-column: 1 / -1; margin-top: 30px; }
}
@media (prefers-reduced-motion: reduce) { .wl-play { transition: none; } .wl-play:hover { transform: none; } }
