/* buried ember: site styles
   Built from the Buried Ember design system (Settings > Design systems).
   The brand book there is the source of truth; change a rule there first. */

/* Self-hosted faces (design system: no Google Fonts request). block, not swap: the door line never jumps. */
@font-face { font-family: "Alegreya"; src: url("../fonts/alegreya-400.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: block; }
@font-face { font-family: "Alegreya"; src: url("../fonts/alegreya-400-italic.woff2") format("woff2"); font-weight: 400; font-style: italic; font-display: block; }
@font-face { font-family: "Alegreya Sans"; src: url("../fonts/alegreya-sans-400.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Alegreya Sans"; src: url("../fonts/alegreya-sans-500.woff2") format("woff2"); font-weight: 500; font-style: normal; font-display: swap; }

@font-face {
  font-family: "Brad Hand";
  src: url("../fonts/brad-hand.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* Tokens (palette 25b, "true ash, live coal") */
:root {
  color-scheme: light dark;
  --ash: #e7e6e3;
  --soot: #1d1a18;
  --cinder: #605d5a;
  --hearth: #d8d7d4;
  --ember: #e94b27;
  --rule: #cfcecb;
  --ghost-opacity: 0.32;
  --ghost-blend: multiply;
  --font-voice: "Alegreya", Georgia, serif;
  --font-text: "Alegreya Sans", "Helvetica Neue", Arial, sans-serif;
  --font-hand: "Brad Hand", "Alegreya", Georgia, serif;
  --pad: clamp(28px, 7.2vw, 104px);
  --arrive: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ghost-mask: radial-gradient(ellipse 85% 70% at 72% 24%, #000 0%, rgba(0, 0, 0, 0.5) 40%, transparent 80%);
}

/* Dark follows the device unless the reader picks Light or Dark in the footer (data-theme on <html>). */
:root {
  --charcoal-core: oklch(0.36 0.006 60);
  --charcoal-mid: oklch(0.6 0.005 70);
  --charcoal-grain: 0.1;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --ash: #171614;
    --soot: #dfdedb;
    --cinder: #8e8c89;
    --hearth: #252422;
    --ember: #fd6a3a;
    --rule: #2f2d2c;
    --ghost-blend: screen;
    --charcoal-core: oklch(0.55 0.004 60);
    --charcoal-mid: oklch(0.38 0.004 60);
    --charcoal-grain: 0.06;
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --ash: #171614;
  --soot: #dfdedb;
  --cinder: #8e8c89;
  --hearth: #252422;
  --ember: #fd6a3a;
  --rule: #2f2d2c;
  --ghost-blend: screen;
  --charcoal-core: oklch(0.55 0.004 60);
  --charcoal-mid: oklch(0.38 0.004 60);
  --charcoal-grain: 0.06;
}
:root[data-theme="light"] { color-scheme: light; }

/* Base */
*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }
html { background: var(--ash); }
body {
  margin: 0;
  background: var(--ash);
  color: var(--soot);
  font-family: var(--font-text);
  font-size: 18px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img, svg, video { display: block; max-width: 100%; }
p { margin: 0; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Links, and buttons that read as phrase links */
a, .phrase {
  color: var(--soot);
  text-decoration: underline;
  text-decoration-color: var(--cinder);
  text-decoration-thickness: 1px;
  text-underline-offset: 5px;
  transition: text-decoration-color 300ms ease;
}
.phrase {
  appearance: none; background: none; border: 0; padding: 0; margin: 0;
  font: inherit; cursor: pointer;
}
@media (hover: hover) {
  a:hover, .phrase:hover { text-decoration-color: var(--ember); }
}
/* On touch there is no hover: the underline warms to ember while a finger is on the link (Brad, Oct 5, 2026).
   It shows at once on press; site.js adds .pressed, since iOS shows :active only briefly. */
@media (hover: none) {
  a:active, .phrase:active, a.pressed, .phrase.pressed { text-decoration-color: var(--ember); transition: none; }
}
a:focus-visible, .phrase:focus-visible, .buy:focus-visible {
  text-decoration-color: var(--ember);
  outline: 2px solid var(--ember);
  outline-offset: 4px;
}

/* Wordmark: live text, the ı carries the ember */
.wordmark {
  font-family: var(--font-voice);
  font-weight: 400;
  line-height: 1;
  white-space: nowrap;
  text-decoration: none;
  color: var(--soot);
}
.wordmark .i { position: relative; display: inline-block; }
.wordmark .dot {
  position: absolute; left: 50%; top: 0.06em;
  width: 0.15em; height: 0.15em; margin-left: -0.075em;
  border-radius: 50%;
  background: var(--ember);
}
a.wordmark { text-decoration: none; }
.site-head .wordmark { font-size: 22px; }
/* The header dot warms from cinder to ember, once per visit (site.js). */
.js .wordmark[data-ember] .dot { background: var(--cinder); transition: background-color 1200ms ease; }
.js .wordmark[data-ember].lit .dot { background: var(--ember); }
.js .wordmark[data-ember].lit.now .dot { transition: none; }
/* On the homepage the header dot holds the ember at the start and again after the reader scrolls (site.js). */
.js .wordmark[data-door-ember] .dot { background: var(--cinder); transition: background-color 400ms ease; }
.js .wordmark[data-door-ember].lit .dot { background: var(--ember); }
.js .wordmark[data-door-ember].lit.now .dot { transition: none; }
/* Where the page's warm point is a photo or a gesture, the dot rests in cinder. */
.wordmark.quiet .dot, .js .wordmark.quiet .dot { background: var(--cinder); }

/* One unit per screen. Space is the divider. */
.unit {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  min-height: 100vh;
  min-height: 100svh;
  padding: var(--pad);
}

/* The ghost: the same photo (or gesture) fills the unit, grey, masked, still. */
.ghost {
  position: absolute; inset: 0; z-index: -1;
  width: 100%; height: 100%;
  object-fit: cover;
  filter: grayscale(1) contrast(0.85);
  opacity: var(--ghost-opacity);
  mix-blend-mode: var(--ghost-blend);
  -webkit-mask-image: var(--ghost-mask);
  mask-image: var(--ghost-mask);
  pointer-events: none;
}

/* The anchored ghost (31b): one full-unit layer carries filter, opacity, blend and mask;
   inside it the photo or drawing sits at 3.5 times its square, centered on the square (gesture.js). */
.ghost-layer {
  position: absolute; inset: 0; z-index: -1; overflow: hidden;
  filter: grayscale(1) contrast(0.85);
  opacity: var(--ghost-opacity);
  mix-blend-mode: var(--ghost-blend);
  -webkit-mask-image: var(--ghost-mask);
  mask-image: var(--ghost-mask);
  pointer-events: none;
}
.ghost-layer > img, .ghost-layer > svg { position: absolute; display: block; max-width: none; }
.ghost-layer > img {
  object-fit: cover;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 15%, #000 85%, transparent), linear-gradient(to bottom, transparent, #000 15%, #000 85%, transparent);
  -webkit-mask-composite: source-in;
  mask-image: linear-gradient(to right, transparent, #000 15%, #000 85%, transparent), linear-gradient(to bottom, transparent, #000 15%, #000 85%, transparent);
  mask-composite: intersect;
}
/* The door line's ghost is anchored where a frame's square would sit. The anchor itself is never seen. */
.ghost-anchor {
  position: absolute; top: calc(var(--pad) + 40px); right: var(--pad);
  width: min(300px, calc((100% - 2 * var(--pad)) * 0.55)); aspect-ratio: 1 / 1;
  visibility: hidden; pointer-events: none;
}

/* Photos: square, warm grade, light grain */
.sq { position: relative; aspect-ratio: 1 / 1; overflow: hidden; background: var(--hearth); }
.sq > img, .sq > svg, .sq > video { width: 100%; height: 100%; object-fit: cover; }
.sq > img, .sq > video { filter: sepia(0.08) saturate(0.94); }
.sq.grain::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  opacity: 0.14; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/></filter><rect width='160' height='160' filter='url(%23n)'/></svg>");
}

.caption { font-size: 14px; line-height: 1.5; color: var(--cinder); }

/* Type */
.door-lines {
  font-family: var(--font-voice);
  font-size: clamp(30px, 3.6vw, 52px);
  line-height: 1.2;
  font-weight: 400;
}
.short-line {
  font-family: var(--font-voice);
  font-style: italic;
  font-size: clamp(22px, 2.1vw, 30px);
  line-height: 1.4;
  max-width: 480px;
  text-wrap: balance;
}
.heading {
  font-family: var(--font-voice);
  font-weight: 400;
  font-size: clamp(28px, 2.4vw, 34px);
  line-height: 1.2;
  margin: 0;
}

/* 1. Door line */
.door { display: flex; flex-direction: column; padding-top: 40px; padding-bottom: 48px; }
.door .door-lines { flex: 1; display: flex; flex-direction: column; justify-content: center; gap: 24px; padding-block: 64px; }
.door .more { color: var(--cinder); font-size: 22px; letter-spacing: 0.1em; line-height: 1; }

/* The door line's question marks: the glyph's own dot is clipped away and a live dot sits exactly where it was
   (Alegreya: dot center 0.1465em in, 0.0475em above the baseline; italic 0.120em in). The reading sequence
   lights one dot at a time in ember (site.js); a read question's dot rests in cinder. */
.qm { position: relative; display: inline-block; line-height: 1; }
.qm .g { display: inline-block; line-height: 1; -webkit-clip-path: inset(0 0 0.3145em 0); clip-path: inset(0 0 0.3145em 0); }
.qm .qdot {
  position: absolute; left: 0.1465em; top: 0.788em;
  width: 0.12em; height: 0.12em; margin: -0.06em 0 0 -0.06em;
  border-radius: 50%; background: var(--soot);
}
em .qm .qdot, .qm.it .qdot { left: 0.12em; }
/* Each question arrives whole as a mist moving left to right, the same mist as page 3's beats (Brad, Oct 4, 2026).
   Linear here, so site.js can light the question mark's ember the moment the mist passes it. */
.js .door-lines [data-say] {
  --mist: -40%; filter: blur(5px);
  -webkit-mask-image: linear-gradient(to right, #000 var(--mist), transparent calc(var(--mist) + 40%));
  mask-image: linear-gradient(to right, #000 var(--mist), transparent calc(var(--mist) + 40%));
}
.js .door-lines [data-say].mist { --mist: 130%; filter: blur(0); transition: --mist 2200ms linear, filter 2200ms ease-out; }
.js .door-lines .qdot { background: transparent; transition: background-color 400ms ease; }
.js .door-lines .qdot.lit { background: var(--ember); }
.js .door-lines .qdot.read { background: var(--cinder); }
.js .door-lines.rest [data-say] { -webkit-mask-image: none; mask-image: none; filter: none; }
@media (prefers-reduced-motion: reduce) {
  .js .door-lines [data-say] { -webkit-mask-image: none; mask-image: none; filter: none; }
  .js .door-lines .qdot { transition: none; }
}

/* The ellipsis at the foot of the door: the ember walks its three dots, left to right. */
/* The ellipsis is three dots the size of the question marks' dots (0.12em of the door line's type). */
.door .more, .frame.drawn .more { font-size: clamp(30px, 3.6vw, 52px); letter-spacing: 0; line-height: 1; display: flex; gap: 0.16em; }
.more .ed { display: block; width: 0.12em; height: 0.12em; border-radius: 50%; background: var(--cinder); transition: background-color 300ms ease; }
.more .ed.lit { background: var(--ember); }

/* 2. Frame: square pushed right, caption under it, the line bottom left */
.frame { display: grid; grid-template-rows: auto 1fr auto; row-gap: 40px; }
.frame figure { margin: 0; width: min(300px, 55%); justify-self: end; }
.frame figcaption { margin-top: 16px; }
.frame .bottom { align-self: end; display: flex; flex-direction: column; gap: 40px; }

/* The drawn Frame: no visible square; the drawing lives in its ghost, the line sits just under the anchor. */
.frame.drawn { grid-template-rows: auto auto 1fr; row-gap: 24px; }
.frame.drawn figure { width: min(100%, 560px); justify-self: center; }
/* On a wide screen the drawing stays smaller, so the line sits mid-screen, clear of the ellipsis. */
@media (min-width: 900px) { .frame.drawn figure { width: min(420px, 100vh - 480px); width: min(420px, 100svh - 480px); } }
.frame.drawn .sq { background: transparent; }
.frame.drawn .ghost-layer {
  -webkit-mask-image: radial-gradient(ellipse 75% 60% at 50% 32%, #000 0%, rgba(0, 0, 0, 0.6) 45%, transparent 85%);
  mask-image: radial-gradient(ellipse 75% 60% at 50% 32%, #000 0%, rgba(0, 0, 0, 0.6) 45%, transparent 85%);
}
.frame.drawn .bottom { align-self: start; margin-top: clamp(32px, 6vh, 72px); }
/* The ellipsis sits 48px from the foot on pages 1, 2 and 3, at every width. */
.frame.drawn, .story-frame { padding-bottom: 24px; }
/* Page 2 ends on the door's ellipsis, still, in cinder: the drawing's dot is the page's one ember (Brad, Oct 4, 2026). */
.frame.drawn .more { align-self: end; color: var(--cinder); padding-bottom: 24px; }
/* Two lines at most, down to a 360px phone: the drawn line may go to 20px on the smallest screens. */
.frame.drawn .short-line { font-size: clamp(19px, 2.1vw, 30px); max-width: 560px; }
.drawn-ember {
  position: absolute; z-index: 1; width: 14px; height: 14px; margin: -7px 0 0 -7px;
  border-radius: 50%; background: var(--ember); pointer-events: none;
}
/* The drawn ember grows in place from a point to its size while the line is read (duration set per line in gesture.js). */
.js .drawn .drawn-ember { transform: scale(0); transition: transform 3000ms linear 300ms; }
.js .drawn.is-in .drawn-ember { transform: scale(1); }
@media (prefers-reduced-motion: reduce) { .js .drawn .drawn-ember { transform: none; transition: none; } }

/* The 13 Words frame: the book sits on the drawing where the ember was. */
.drawn-book {
  position: absolute; z-index: 1; width: clamp(96px, 30vw, 168px); aspect-ratio: 1 / 1; max-width: 100%;
  transform: translate(-50%, -50%); object-fit: cover; filter: sepia(0.08) saturate(0.94);
}
.book-drawn .bottom { margin-top: 24px; }
.book-drawn .offer { gap: 16px; }
.book-drawn .lead { font-size: 18px; color: var(--soot); max-width: 34em; }

/* The 13 Words story beats (Brad's Amazon description): one beat per screen, its gesture as a ghost,
   the ember growing for the beat's reading time. */
.beat figure { width: min(100%, 440px); }
.beat .short-line { font-size: clamp(20px, 2.1vw, 28px); max-width: 560px; text-wrap: pretty; }
.beat.photo-beat figure { width: min(300px, 70%); justify-self: center; }

/* The 13 Words story frame: photo and ghost change per beat; words arrive at reading pace. */
.story-frame { display: flex; flex-direction: column; }
/* 3b. The book's own screen: the facts and the link, centered in the screen. */
/* Page 4 and the footer share one screen: the page takes what the footer leaves (site.js measures it). */
.book-page { display: flex; flex-direction: column; justify-content: flex-start; row-gap: 0; padding-top: 4px; padding-bottom: 0;
  min-height: calc(100vh - var(--foot-h, 340px)); min-height: calc(100svh - var(--foot-h, 340px)); }
.book-info { display: flex; flex-direction: column; gap: 8px; max-width: 560px; }
.book-info .facts, .book-info p { line-height: 1.38; }
.book-info .facts { font-size: 16px; }
.book-info .title-pair { gap: 0; }
.book-info .heading { line-height: 1.15; }
.book-info .facts { gap: 2px 20px; margin: 2px 0; }
/* Page 4 breathes between page 3's ellipsis and the footer: the book's facts sit high, the songs fill the rest,
   their cover's ghost behind them down to the footer (Brad, Oct 5, 2026). The ghost is square, as tall as the
   space allows between the playlist links and the footer (site.js), never under any text. */
.songs-block { position: relative; isolation: isolate; flex: 1; margin: 6px calc(-1 * var(--pad)) 0; min-height: 0; }
.songs-block .ghost-layer { -webkit-mask-image: none; mask-image: none; }
/* In light the cover is turned negative before the multiply, so its dark ground drops out and only the
   drawn lines and words remain, as in dark (screen). No grey box in either theme. */
.songs-ghost { filter: grayscale(1) invert(1) contrast(1.1); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .songs-ghost { filter: grayscale(1) brightness(0.85) contrast(1.6); } }
:root[data-theme="dark"] .songs-ghost { filter: grayscale(1) brightness(0.85) contrast(1.6); }
.songs-ghost > img { top: 0; width: 300px; height: 300px; object-fit: cover; }
.book-info .songs { margin-top: 4px; }
.book-info .pair { display: flex; gap: 24px; }
/* The stage holds Brad's answer, the picture and the beat on one screen, centered, above the fold on a phone
   (Brad, Oct 4, 2026). The picture is as large as the screen allows and the same size every beat; it bleeds
   10% past its square, so its margins carry that bleed plus the breathing room. */
.story-frame .stage {
  --ph: min(100vw - 2 * var(--pad), 560px, 100vh - 345px - 2 * var(--pad));
  --ph: min(100vw - 2 * var(--pad), 560px, 100svh - 345px - 2 * var(--pad));
  flex: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
}
/* Like page 2: Brad's answer and the picture sit high, the beat right under it, the ellipsis at the foot. */
.story-frame .stage .lead { margin-top: 8px; }
.story-frame figure { width: var(--ph); margin: calc(var(--ph) * 0.1 + 20px) 0 calc(var(--ph) * 0.1 + 24px); justify-self: center; }
.story-frame .stage .more { margin-top: auto; padding-bottom: 24px; }
.story-frame .more { align-self: flex-start; color: var(--cinder); font-size: clamp(30px, 3.6vw, 52px); letter-spacing: 0; line-height: 1; display: flex; gap: 0.16em; margin: 0; }
.story-frame .stage .story-text { width: 100%; max-width: 560px; }
/* breathing room: the picture bleeds 10% past its square, so the margin above and below is wider than the gap */
/* No square on the story frame: the square only anchors the ghost, which is the picture. Every beat's
   picture is the same size, large (Brad, Oct 4, 2026); over the 8 beats it turns from the 31b ghost
   (0.32, gray) to the plain photo, the hardcover in full at the last. --open runs 0 to 1 (story.js).
   Each picture drifts slowly while it is up (a light Ken Burns). */
@property --open { syntax: '<number>'; inherits: true; initial-value: 0; }
.story-frame .sq { visibility: hidden; }
.story-frame .ghost-layer {
  --open: 0;
  transition: --open 1600ms ease-in-out;
  opacity: calc(var(--ghost-opacity) + (1 - var(--ghost-opacity)) * var(--open));
  filter: grayscale(calc(1 - var(--open))) contrast(calc(0.85 + 0.15 * var(--open)));
  -webkit-mask-image: none; mask-image: none;
}
.story-frame .ghost-layer img {
  --f: calc(14% - 6% * var(--open));
  -webkit-mask-image: linear-gradient(to right, transparent, #000 var(--f), #000 calc(100% - var(--f)), transparent), linear-gradient(to bottom, transparent, #000 var(--f), #000 calc(100% - var(--f)), transparent);
  mask-image: linear-gradient(to right, transparent, #000 var(--f), #000 calc(100% - var(--f)), transparent), linear-gradient(to bottom, transparent, #000 var(--f), #000 calc(100% - var(--f)), transparent);
  transition: opacity 1200ms ease-in-out;
  transform-origin: var(--kb-o, 50% 50%);
}
.story-frame .ghost-layer img.off { opacity: 0; }
.story-frame .ghost-layer img.kb { animation: kb var(--kb-t, 6000ms) linear forwards; }
.story-frame.held .ghost-layer img.kb { animation-play-state: paused; }
@keyframes kb { from { transform: scale(1); } to { transform: scale(1.09); } }
@media (prefers-reduced-motion: reduce) { .story-frame .ghost-layer img.kb { animation: none; } }
.story-frame .ghost-layer.full img { filter: sepia(0.08) saturate(0.94); }
.story-frame .lead { font-size: 17px; color: var(--cinder); max-width: 34em; text-align: center; margin: 0; }
.story-frame .lead .lead-line { display: block; text-wrap: balance; }
.story-frame .story-text { min-height: 4.4em; margin: 0; max-width: 560px; font-size: clamp(20px, 2.1vw, 28px); }
/* Each beat arrives whole, left to right, as a mist (Brad, Oct 4, 2026): a soft edge sweeps across every line at once. */
@property --mist { syntax: '<percentage>'; inherits: false; initial-value: 130%; }
.js .story-frame.playing .story-text {
  --mist: -40%; filter: blur(5px);
  -webkit-mask-image: linear-gradient(to right, #000 var(--mist), transparent calc(var(--mist) + 40%));
  mask-image: linear-gradient(to right, #000 var(--mist), transparent calc(var(--mist) + 40%));
}
.js .story-frame.playing .story-text.mist { --mist: 130%; filter: blur(0); transition: --mist 2200ms ease-out, filter 2200ms ease-out, opacity 500ms ease; }
.story-text .pe { transition: color 400ms ease; }
.story-text .pe.lit { color: var(--ember); }
.fade { opacity: 0 !important; }

/* Sounding board: the video under its square, then the offer */
.media-links { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 16px; margin-top: 16px; font-size: 16px; white-space: nowrap; }
.offer { display: flex; flex-direction: column; gap: 16px; max-width: 34em; }
.title-pair { display: flex; flex-direction: column; gap: 4px; }
.subtitle { font-family: "Alegreya", Georgia, serif; font-style: italic; font-size: 19px; color: var(--cinder); }
.facts { display: grid; grid-template-columns: max-content 1fr; gap: 6px 24px; margin: 8px 0; font-size: 17px; }
.facts dt { color: var(--cinder); }
.facts dd { margin: 0; text-wrap: balance; }

/* Mailbox */
.mailbox .send { font-size: 18px; }

/* Proof pages on the 13 Words page: Next and "1 of N", like Look */
.pager-links { display: flex; align-items: baseline; gap: 16px; margin-top: 16px; font-size: 16px; }

/* The What Brad Did subscribe box: the one embed on the site (13 Words page only) */
.subscribe { display: flex; flex-direction: column; gap: 16px; max-width: 480px; }
.subscribe iframe { display: block; width: 100%; max-width: 480px; height: 320px; border: 0; background: transparent; }

/* Footer */
.site-foot {
  padding: 24px var(--pad) 28px;
  display: flex; flex-flow: row wrap; align-items: baseline; gap: 10px 24px;
}
.site-foot .wordmark { font-size: 22px; }
/* the wordmark and the line on their own rows; Light, Dark and the year share the last row */
.site-foot > .wordmark, .site-foot > p:not(.theme):not(.caption) { flex-basis: 100%; }
.site-foot p { font-size: 16px; }
.site-foot .theme { display: flex; gap: 16px; }
.site-foot .theme .phrase { font-size: 14px; color: var(--cinder); }
.site-foot .theme .phrase[aria-pressed="true"] { color: var(--soot); }

/* Offer page: the held object */
.held { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 24px; text-align: center; padding-top: 40px; }
.held .site-head { align-self: stretch; text-align: left; }
.held-body { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 24px; width: 100%; }
.held .stage { width: min(460px, 100%); }
.held .short-line { margin: 0 auto; }
.held .choices, .held .under { display: flex; justify-content: center; align-items: baseline; gap: 24px; font-size: 18px; }
.held .under { font-size: 16px; }
.listen-panel {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  padding: 40px;
  background: var(--hearth);
  font-family: var(--font-voice); font-style: italic;
  font-size: clamp(20px, 2vw, 26px); line-height: 1.4;
}
.page-standin {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center; padding: 40px;
  background: var(--hearth); color: var(--cinder); font-size: 16px;
}

/* Offer page: the signed note */
.note { display: flex; flex-direction: column; justify-content: center; gap: 24px; }
.note .words { max-width: 32em; display: flex; flex-direction: column; gap: 16px; }
.signature {
  font-family: var(--font-hand);
  font-size: 34px; line-height: 1.1;
  color: var(--soot);
  font-feature-settings: "calt" 1, "liga" 1;
}

/* Offer page: the plate, price once, one button */
.plate { display: flex; align-items: center; }
.plate-inner { display: grid; grid-template-columns: 180px minmax(0, 32em); gap: 40px; align-items: start; }
.plate .offer { max-width: none; }
.buy {
  display: inline-block; align-self: flex-start;
  margin-top: 8px;
  font-family: var(--font-text); font-size: 17px; font-weight: 500; line-height: 1.3;
  padding: 12px 22px;
  background: var(--hearth);
  color: var(--soot);
  border: 1px solid var(--cinder);
  text-decoration: none;
  transition: background-color 300ms ease, border-color 300ms ease;
}
@media (hover: hover) {
  .buy:hover { background: var(--ash); border-color: transparent; }
}
@media (max-width: 640px) {
  .plate-inner { grid-template-columns: 1fr; }
  .plate-inner .sq { width: 160px; }
}

/* Motion: arrive. Hidden only once JS runs; never under reduced motion. */
.js [data-arrive] .arrive-photo,
.js [data-arrive] .arrive-line {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 900ms var(--arrive), transform 900ms var(--arrive);
}
.js [data-arrive].is-in .arrive-photo,
.js [data-arrive].is-in .arrive-line { opacity: 1; transform: none; }
.js [data-arrive].is-in .arrive-line { transition-delay: 150ms; }

@media (prefers-reduced-motion: reduce) {
  .js [data-arrive] .arrive-photo,
  .js [data-arrive] .arrive-line { opacity: 1; transform: none; transition: none; }
  a, .phrase, .buy, .js .wordmark[data-ember] .dot { transition: none; }
}
