/* Nightcut v12, the Russian page (ru/): the English base.css with Russian quote marks (html quotes, the talk quote's
   «ёлочки»); the font comment below holds, and _head.html preloads the Cyrillic file too. Words: ru/VOICE.md.
   Nightcut v12 – one system for the whole page. Every shared component is documented in COMPONENTS.md and shown
   working in _lab/components.html. Warm white page, deep park green for what you can press, the logo's yellow for
   the one thing to notice on a screen, Onest everywhere.
   Rules: one idea and one focal visual per chapter, the page never stops (no pinned scenes), things happen in order
   (the request first, then the result), nothing touches or overlaps anything, hover never moves anything, what looks
   pressable opens something, nothing under 16px outside the hero's app mock. */

/* ---------- Font ----------
   Onest, self-hosted and preloaded (parts/_head.html), cut to Latin (+ Cyrillic, fetched only when used) and without
   the tabular-figures feature: Onest's tabular "1" leaves a hole after it, so figures stay proportional everywhere,
   even where a chapter asks for tabular-nums. While it loads, Arial stands in with Onest's widths and line metrics
   (measured per weight), so nothing reflows when the font arrives. */
@font-face { font-family: Onest; src: url(fonts/onest-latin.woff2) format("woff2"); font-weight: 400 800; font-style: normal; font-display: swap; unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AA, U+20AC, U+2122, U+2190-2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: Onest; src: url(fonts/onest-cyrillic.woff2) format("woff2"); font-weight: 400 800; font-style: normal; font-display: swap; unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; }
@font-face { font-family: "Onest Fallback"; src: local("Arial"), local("ArialMT"); font-weight: 100 449; size-adjust: 104.95%; ascent-override: 92.42%; descent-override: 29.06%; line-gap-override: 0%; }
@font-face { font-family: "Onest Fallback"; src: local("Arial"), local("ArialMT"); font-weight: 450 549; size-adjust: 106.03%; ascent-override: 91.48%; descent-override: 28.77%; line-gap-override: 0%; }
@font-face { font-family: "Onest Fallback"; src: local("Arial Bold"), local("Arial-BoldMT"); font-weight: 550 649; size-adjust: 99.92%; ascent-override: 97.08%; descent-override: 30.52%; line-gap-override: 0%; }
@font-face { font-family: "Onest Fallback"; src: local("Arial Bold"), local("Arial-BoldMT"); font-weight: 650 749; size-adjust: 100.93%; ascent-override: 96.11%; descent-override: 30.22%; line-gap-override: 0%; }
@font-face { font-family: "Onest Fallback"; src: local("Arial Bold"), local("Arial-BoldMT"); font-weight: 750 900; size-adjust: 101.93%; ascent-override: 95.16%; descent-override: 29.92%; line-gap-override: 0%; }

/* ---------- Tokens ---------- */
:root {
  --font: Onest, "Onest Fallback", system-ui, sans-serif;
  /* Colour */
  --bg: #fbfaf7; --soft: #f3f1eb; --soft-2: #ebe8df; --card: #fff; --line: #e5e1d6; --line-2: #d9d4c6;
  --ink: #161512; --ink-2: #34322c; --muted: #66625a;
  --green: #1f4a39; --green-2: #173a2c; --green-3: #2f7355; --green-ink: #f6f4ee; --green-soft: #e6efe9; --green-band: #163629;
  --yellow: #e8b400; --yellow-soft: #fbf0c8;
  --red: #c23d2a; --red-soft: #f9e3de;
  --ok: #2f8a57; --ok-on-dark: #6fd39a;
  --night: #111210; --night-card: #1c1d1a; --night-line: #2e2f2a; --night-ink: #f2f0e9; --night-2: rgba(242, 240, 233, .82); --night-muted: rgba(242, 240, 233, .62);
  /* What you type to your AI (.ask): a filled bubble, the strongest shape on its band. Ink on light bands, cream on
     dark ones (the band classes below swap these). */
  --me-bg: #1f1e1a; --me-ink: #f7f5ef; --me-shadow: 0 16px 30px -18px rgba(22, 21, 18, .55), 0 2px 5px rgba(22, 21, 18, .10);
  /* App mocks (the hero's window, 14's mini windows): one set for every drawing of Claude Code or Codex. The app's
     own grey bubble, a step darker than the app so the eye lands on it, a hairline, the system font. */
  --me-app-bg: #ebe9e4; --me-app-bg-cx: #e0e0e0; --me-app-ink: #1f1e1a; --me-app-line: rgba(31, 30, 26, .14);
  --app-font: ui-sans-serif, -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", Arial, sans-serif;

  /* Spacing – nothing else is used for gaps */
  --s1: 8px; --s2: 12px; --s3: 16px; --s4: 24px; --s5: 32px; --s6: 48px; --s7: 64px; --s8: 96px;
  /* Radius – one scale: cards and windows, media frames (16:9 video, covers, photos), phone-shaped shorts (9:16),
     small thumbnails, controls (buttons, fields, tiles), pills. */
  --r-card: 28px; --r-media: 20px; --r-short: 16px; --r-thumb: 10px; --r-ctl: 14px; --r-pill: 999px;
  /* Shadow – one scale. 1: a hairline lift (chips, tiles). 2: a card that sits on the page. 3: the focal window or
     video of a chapter. dark: media on a dark band (weight, no glow). */
  --sh-1: 0 1px 2px rgba(40, 34, 20, .08), 0 0 0 1px rgba(40, 34, 20, .04);
  --sh-2: 0 12px 30px -18px rgba(40, 34, 20, .35), 0 1px 3px rgba(40, 34, 20, .06);
  --sh-3: 0 30px 70px -36px rgba(40, 34, 20, .30), 0 2px 6px rgba(40, 34, 20, .05);
  --sh-dark: 0 30px 60px -30px rgba(0, 0, 0, .8);
  /* Old names, kept so every chapter keeps working. (--r is retired: as a root token it leaked into chapters' own
     --r custom properties and silently broke rotate(var(--r)) in WebKit. Use --r-media.) */
  --r-lg: var(--r-card); --r-sm: var(--r-short); --pill: var(--r-pill);
  --shadow: var(--sh-3); --shadow-sm: var(--sh-2);

  --ease: cubic-bezier(.2, .8, .2, 1);
  --head: 72px;
  --gutter: 40px;
  /* Chapter padding. Where two chapters in a row share a background, the joint is --pad-join on each side with a
     hairline in the middle, instead of two full paddings. */
  --pad-y: 136px; --pad-join: 72px;
  --wrap: 1200px;
}
@media (max-width: 1100px) { :root { --pad-y: 112px; --pad-join: 60px; } }
@media (max-width: 719px) { :root { --head: 60px; --gutter: 20px; --pad-y: 64px; --pad-join: 40px; --r-card: 24px; --r-media: 16px; --r-short: 14px; } }

.band-green, .band-night { --me-bg: #f7f5ef; --me-ink: #161512; --me-shadow: 0 16px 34px -16px rgba(0, 0, 0, .7); }

* { box-sizing: border-box; }
[hidden] { display: none !important; }
/* scroll-padding keeps a focused control clear of the sticky header. A jump to a chapter (the header's nav, the hero's
   result cards, a #hash in the URL) lands at the natural stop – the headline 14 px under the header, where every demo
   starts with its request and result on one screen – by the section's negative scroll-margin (its top padding hides
   under the header, so no sliver of the band above shows); base.js then measures the headline itself and corrects
   the last pixels. */
html { -webkit-text-size-adjust: 100%; scroll-padding-top: calc(var(--head) + 8px); }
/* …but the header's own links and buttons live inside that padding: focusing one (Tab, or the language switch) made
   the browser scroll the page up half a screen to clear it. Their negative margin cancels the padding for them. */
.top a, .top button { scroll-margin-top: calc(-1 * var(--head) - 8px); }
body { margin: 0; background: var(--bg); color: var(--ink); font: 400 18px/1.5 var(--font); -webkit-font-smoothing: antialiased; overflow-x: clip; }
a { color: inherit; }
img, video { max-width: 100%; }
img { height: auto; }
button, input { font-family: inherit; }
/* No grey or blue flash on tap (Chrome on Android paints one on anything pressable that doesn't opt out): each
   control shows its own pressed state instead (.btn and .link below, chapters' own :active / selected states). */
a, button, summary, label, [role="button"], [role="tab"], [tabindex] { -webkit-tap-highlight-color: transparent; }
:focus-visible { outline: 3px solid var(--green-3); outline-offset: 2px; border-radius: 6px; }
/* A headline that took the focus after a jump from the keyboard (base.js) is a place, not a control: no ring. */
h2[tabindex="-1"]:focus, section.ch[tabindex="-1"]:focus, [data-stop][tabindex="-1"]:focus { outline: none; }
.vh { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* ---------- Layout ---------- */
.wrap { max-width: calc(var(--wrap) + 2 * var(--gutter)); margin: 0 auto; padding: 0 var(--gutter); }
/* Each chapter is its own stacking context: a z-index inside a chapter (06's opening frame uses 60) can never rise
   over the sticky header (z-index 50) or another chapter. */
section.ch { padding: var(--pt, var(--pad-y)) 0 var(--pb, var(--pad-y)); position: relative; overflow-x: clip; isolation: isolate; scroll-margin-top: calc(7px - var(--pt, var(--pad-y))); }
.band-green { background: var(--green-band); color: var(--night-ink); }
.band-night { background: var(--night); color: var(--night-ink); }
.band-soft { background: var(--soft); }
/* Two chapters in a row on the same background: one joint (--pad-join on each side) with a hairline in it.
   Zero specificity, so a chapter that sets its own padding still wins. */
:where(.ch:not(.band-green, .band-night, .band-soft)) + :where(.ch:not(.band-green, .band-night, .band-soft)),
:where(.ch.band-soft) + :where(.ch.band-soft), :where(.ch.band-night) + :where(.ch.band-night), :where(.ch.band-green) + :where(.ch.band-green) { --pt: var(--pad-join); }
:where(.ch:not(.band-green, .band-night, .band-soft):has(+ .ch:not(.band-green, .band-night, .band-soft))),
:where(.ch.band-soft:has(+ .ch.band-soft)), :where(.ch.band-night:has(+ .ch.band-night)), :where(.ch.band-green:has(+ .ch.band-green)) { --pb: var(--pad-join); }
:where(.ch:not(.band-green, .band-night, .band-soft)) + :where(.ch:not(.band-green, .band-night, .band-soft))::before,
:where(.ch.band-soft) + :where(.ch.band-soft)::before,
:where(.ch.band-night) + :where(.ch.band-night)::before, :where(.ch.band-green) + :where(.ch.band-green)::before { content: ""; position: absolute; top: 0; left: 50%; width: min(var(--wrap), 100% - 2 * var(--gutter)); height: 1px; transform: translateX(-50%); background: var(--line); }
:where(.ch.band-night) + :where(.ch.band-night)::before, :where(.ch.band-green) + :where(.ch.band-green)::before { background: rgba(255, 255, 255, .1); }

/* ---------- Type ---------- */
html { quotes: "«" "»" "„" "“"; }
h1, h2, h3 { margin: 0; text-wrap: balance; }
h1 { font-size: clamp(50px, 7.4vw, 112px); line-height: .94; letter-spacing: -0.048em; font-weight: 800; }
/* The plain headline's line height is an em part plus a fixed part, so the ink gap between a descender and the next
   line's ascender is about 8.5px at every size (1.19 at 36px on a phone, 1.09 at 60px): at 1.02 "possible" over
   "Keeps" and "steps" over "just" came within 2.5px (founder note T1: lines must never touch), and at +6.5px the
   closest descender-over-ascender pairs (15's price, 14's steps, 06's picks) still measured only 6.5px of ink gap. */
h2 { font-size: clamp(36px, 4.1vw, 60px); line-height: calc(.95em + 8.5px); letter-spacing: -0.035em; font-weight: 700; }
h2.poster { font-size: clamp(48px, 7.6vw, 112px); line-height: 1.04; letter-spacing: -0.046em; font-weight: 800; }
/* A short phone (375×667, or a 390 phone under Safari's bars, about 390×664): every chapter headline steps down to
   32 px, so the demos keep their request and result on one screen and neighbours never jump in size (04 and 05
   stepped down on their own, the rest stayed 36). 05 may go a hair under (COMPONENTS.md §2). Posters keep theirs. */
@media (max-width: 719px) and (max-height: 760px) { h2 { font-size: 32px; } }
.h2nd { color: var(--green-3); }
.band-green .h2nd, .band-night .h2nd { color: rgba(242, 240, 233, .7); }
.band-green .h2nd.y, .band-night .h2nd.y { color: var(--yellow); }
h3 { font-size: 22px; line-height: 1.25; letter-spacing: -0.015em; font-weight: 700; }
.lead { font-size: clamp(19px, 1.5vw, 22px); line-height: 1.45; font-weight: 500; color: var(--ink-2); margin: 20px 0 0; max-width: 34em; text-wrap: pretty; }
.lead b { color: var(--ink); font-weight: 700; }
.band-green .lead, .band-night .lead { color: var(--night-2); }
.band-green .lead b, .band-night .lead b { color: #fff; }
p { text-wrap: pretty; }
.note { margin: 0; font-size: 17px; line-height: 1.45; font-weight: 500; color: var(--muted); }
.band-green .note, .band-night .note { color: var(--night-muted); }
.num { font-variant-numeric: proportional-nums; }
.nw { white-space: nowrap; }

/* Chapter head: headline + one line. Centred heads for the chapters that stand on one big demo. */
.hd { max-width: 760px; }
.hd.center { margin-left: auto; margin-right: auto; text-align: center; }
.hd.center .lead { margin-left: auto; margin-right: auto; }
.hd + .stage { margin-top: var(--s7); }
@media (max-width: 719px) { .hd + .stage { margin-top: var(--s6); } }

/* ---------- Header ---------- */
/* Fully opaque: WebKit showed the headlines of dark chapters through a translucent, blurred header. */
.top { position: sticky; top: 0; z-index: 50; background: var(--bg); border-bottom: 1px solid transparent; transition: border-color .2s; }
.top.is-stuck { border-bottom-color: var(--line); }
.top-in { display: flex; align-items: center; gap: 28px; height: var(--head); }
.logo { display: inline-flex; align-items: center; min-height: 44px; text-decoration: none; margin-right: auto; }
.logo svg { height: 27px; width: auto; display: block; color: var(--green); }
.top nav { display: flex; gap: 8px; }
.top nav a { display: inline-flex; align-items: center; min-height: 44px; padding: 0 10px; font-size: 16px; font-weight: 500; color: var(--ink-2); text-decoration: none; transition: color .15s; }
.top nav a:hover { color: var(--ink); }
@media (max-width: 899px) { .top nav { display: none; } }
@media (max-width: 719px) { .logo svg { height: 23px; } }

/* ---------- Buttons and links ---------- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 58px; padding: 0 30px; border-radius: 16px; background: var(--green); color: var(--green-ink); font: 600 18px/1 var(--font); text-decoration: none; border: 0; cursor: pointer; transition: background .2s ease, box-shadow .2s ease; box-shadow: 0 12px 26px -14px rgba(31, 74, 57, .75); }
.btn:hover { background: var(--green-2); }
.btn:active { background: #10291f; }
.btn .ico { width: 20px; height: 20px; }
.btn.small { min-height: 44px; padding: 0 18px; font-size: 16px; border-radius: 12px; box-shadow: none; }
.btn.light { background: var(--green-ink); color: var(--green); box-shadow: none; }
.btn.light:hover { background: #fff; }
/* A text link that opens something (an explainer, a replay). 44px tall so a thumb hits it; the text sits centred. */
.link { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0; border: 0; background: none; font: 600 17px/1.3 var(--font); color: var(--green); text-decoration: underline; text-decoration-color: rgba(31, 74, 57, .3); text-underline-offset: 4px; cursor: pointer; transition: text-decoration-color .15s; }
.link:hover { text-decoration-color: currentColor; }
.link:active { text-decoration-color: currentColor; opacity: .72; }
.link .ico { width: 18px; height: 18px; }
.band-green .link, .band-night .link { color: var(--night-ink); text-decoration-color: rgba(242, 240, 233, .35); }
.band-green .link:hover, .band-night .link:hover { text-decoration-color: currentColor; }
/* A replay button takes no room until the demo has run once: <button class="link again" hidden>…</button>,
   NC.demo({ again }) shows it. Legacy replay buttons (.app-again, .pk-again, .c10-again) follow the same rule. */
.again:not(.on), .link[class*="-again"]:not(.on) { display: none; }
.cta { display: flex; flex-direction: column; align-items: flex-start; gap: 14px; }
.cta.center { align-items: center; text-align: center; }
.cta-fine { margin: 0; font-size: 16px; font-weight: 500; color: var(--muted); }
.band-green .cta-fine, .band-night .cta-fine { color: var(--night-muted); }

/* ---------- Icons ---------- */
.ico { width: 24px; height: 24px; display: inline-block; flex: none; vertical-align: middle; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* ---------- 1. The request: what you type to your AI ----------
   <div class="ask" data-ask="Cut the retakes and the dead air." data-done="Done. …"></div>, expanded by build.py.
   Reads as "my message": right-aligned in its column, a speech bubble with the bottom-right corner sharp, filled so
   the eye lands on it. The reply comes under it on the left, like the other side of a chat: a check and plain words.
   The bubble's box is the finished message: the full text (.ask-ph) lays it out and reserves its room, hugging the
   text up to about 32 characters a line (--ask-w), right-aligned. Without JS that box is the bubble. With JS the
   full text is invisible while it types and the bubble (.ask-me::before) grows with the typed letters like a message
   on the right of a chat: the right edge and the sharp tail corner stay put and it widens leftward (--aw / --ah /
   --adx, measured by base.js). The typed letters (.ask-t) are drawn on the finished text's own lines (.is-lined:
   base.js puts the line breaks of .ask-ph into them), so no word ever jumps to the next line while it types, and the
   caret takes no width. Once sent, .ask-ph itself is shown, so the finished bubble is exactly the reserved box:
   nothing below moves and no empty bubble ever shows. Set text-wrap on .ask-me (it reaches both layers).
   Driven by NC.demo / NC.ask (base.js). */
.ask { --ask-max: 560px; --ask-w: 32ch; display: grid; gap: 12px; justify-items: end; width: 100%; max-width: var(--ask-max); }
.ask-me { --ask-px: 20px; position: relative; display: block; max-width: min(100%, calc(var(--ask-w) + 2 * var(--ask-px))); min-height: 52px; padding: 13px var(--ask-px) 14px; border-radius: 22px 22px 6px 22px; background: var(--me-bg); color: var(--me-ink); font: 500 20px/1.4 var(--font); letter-spacing: -0.005em; text-align: left; box-shadow: var(--me-shadow); }
.ask-me .ask-t { display: none; }
.ask-me { text-wrap: pretty; }
.js .ask-me { background: none; box-shadow: none; }
/* direction: rtl puts the layer's starting point at its top-right corner, the one that stays put while it widens
   leftward, so growing with the typed letters is not a layout shift (CLS); it has no text, nothing else changes. */
.js .ask-me::before { content: ""; position: absolute; right: 0; top: 0; width: var(--aw, 0px); height: var(--ah, 0px); border-radius: inherit; background: var(--me-bg); box-shadow: var(--me-shadow); direction: rtl; }
.js .ask.is-sent .ask-me::before { width: 100%; height: 100%; }
.js .ask-me .ask-ph { position: relative; visibility: hidden; }
.js .ask.is-sent .ask-me .ask-ph { visibility: visible; }
.js .ask-me .ask-t { display: block; position: absolute; left: var(--ask-px); right: var(--ask-px); top: 13px; transform: translateX(var(--adx, 0px)); }
.js .ask.is-sent .ask-me .ask-t { visibility: hidden; }
.ask.is-lined .ask-t { white-space: pre; }
.ask-rest { color: transparent; }
/* The caret is a plain inline with a 2px edge and no net width, so it never opens a line break inside a word and the
   text after it never moves. */
.ask-me .ask-car { display: inline; margin: 0 -2px 0 0; border-left: 2px solid currentColor; }
/* It blinks only while the request types (not on every waiting request down the page), and rests while its demo is
   paused (.is-held, base.js). */
.ask.is-typing:not(.is-held) .ask-car { animation: ask-blink 1s steps(1) infinite; }
.ask.is-sent .ask-car { display: none; }
.js .ask .ask-me { transition: opacity .25s var(--ease), transform .35s var(--ease); transform-origin: 100% 0; }
.js .ask:not(.is-shown) .ask-me { opacity: 0; transform: translateY(8px) scale(.98); }
@keyframes ask-blink { 50% { opacity: 0; } }
.ask-re { justify-self: stretch; display: grid; grid-template-columns: 20px minmax(0, 1fr); align-items: start; gap: 10px; min-height: 28px; margin: 0; padding-left: 2px; font-size: 18px; line-height: 1.45; font-weight: 500; color: var(--ink-2); text-align: left; transition: opacity .45s var(--ease), transform .45s var(--ease); }
.js .ask-re { opacity: 0; transform: translateY(6px); }
.ask-re .spin { display: none; }
.ask-re > .ico, .ask-re > .spin { grid-column: 1; grid-row: 1; }
.ask-re-t, .ask-re-sz { grid-column: 2; grid-row: 1; }
.ask-re-sz { visibility: hidden; }
.ask.is-working .ask-re .spin { display: block; }
.ask.is-working .ask-re .ico { display: none; }
.ask-re .ico { width: 20px; height: 20px; margin-top: 3px; color: var(--ok); stroke-width: 2.4; }
.ask-re .spin { margin-top: 4px; width: 18px; height: 18px; border-radius: 50%; border: 2px solid var(--line-2); border-top-color: var(--green-3); animation: nc-spin .8s linear infinite; }
.ask.is-held .ask-re .spin { animation-play-state: paused; }
.js .ask.is-working .ask-re, .js .ask.is-replied .ask-re { opacity: 1; transform: none; }
.ask[data-re="plain"] .ask-re .ico { display: none; }
.band-night .ask-re, .band-green .ask-re { color: var(--night-2); }
.band-night .ask-re .ico, .band-green .ask-re .ico { color: var(--ok-on-dark); }
.band-night .ask-re .spin, .band-green .ask-re .spin { border-color: rgba(255, 255, 255, .2); border-top-color: var(--ok-on-dark); }
/* Requests stacked one after another, like a chat thread: one column, right-aligned as a group; each bubble hugs its
   own text against the right edge, the replies start at the column's left edge and wrap inside it. */
.ask-stack, :has(> .ask + .ask) { display: grid; gap: var(--s4); width: fit-content; max-width: 100%; margin-left: auto; }
.ask-stack > .ask, :has(> .ask + .ask) > .ask { width: auto; max-width: none; }
.ask-stack .ask-re, :has(> .ask + .ask) > .ask .ask-re { contain: inline-size; }
@media (max-width: 719px) {
  .ask-me { --ask-px: 16px; max-width: min(calc(100% - 16px), calc(var(--ask-w) + 2 * var(--ask-px))); font-size: 18px; padding-top: 12px; padding-bottom: 13px; min-height: 48px; border-radius: 20px 20px 6px 20px; }
  .js .ask-me .ask-t { top: 12px; }
  .ask-re { font-size: 17px; }
}
@media (prefers-reduced-motion: reduce) {
  .js .ask-re, .js .ask .ask-me { opacity: 1 !important; transform: none !important; transition: none; }
  .js .ask-me { background: var(--me-bg); box-shadow: var(--me-shadow); }
  .js .ask-me::before { display: none; }
  .ask-me .ask-car { display: none; }
  .js .ask-me .ask-ph { visibility: visible; }
  .js .ask-me .ask-t { display: none; }
}
/* App mocks (the hero's window, 14's mini windows): the app's own grey bubble, one step darker than the app, with a
   hairline, in the system font. .app .chat .me is the hero's; .app-me is the same bubble anywhere else. */
.app .chat .me, .app-me { background: var(--me-app-bg); color: var(--me-app-ink); box-shadow: none; }
.skin-cx .app .chat .me, .skin-cx .app-me, .app-me.cx { background: var(--me-app-bg-cx); }

/* ---------- Reveal: blocks fade up once, as they come into view. Never on hover. ----------
   Inside a demo's result (NC.demo), .reveal and [data-after] wait for the reply instead of the scroll. */
.js .reveal { opacity: 0; transform: translateY(24px); transition: opacity .8s var(--ease), transform .9s var(--ease); }
.js .reveal.is-in { opacity: 1; transform: none; }
.reveal.d1 { transition-delay: .1s; } .reveal.d2 { transition-delay: .2s; } .reveal.d3 { transition-delay: .3s; }
.js [data-after] { opacity: 0; transform: translateY(14px); transition: opacity .6s var(--ease), transform .7s var(--ease); }
.js [data-after].is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .js .reveal, .js [data-after] { opacity: 1; transform: none; transition: none; } }
/* Nothing animates where nobody sees it: a chapter wholly off screen (.nc-off, base.js), a hidden tab (.nc-hidden)
   and a paused demo's result ([data-demo="paused"]) hold every CSS animation in them – spinners, blinking carets,
   17's floating shorts – and let them go on where they were when they come back. */
.ch.nc-off *, .ch.nc-off *::before, .ch.nc-off *::after,
.nc-hidden *, .nc-hidden *::before, .nc-hidden *::after,
[data-demo="paused"] *, [data-demo="paused"] *::before, [data-demo="paused"] *::after { animation-play-state: paused !important; }

/* ---------- Video boxes (media.js): the poster sits behind the video, the video fades in when frames are there ---------- */
.nc-box { background-color: #e7e3da; background-size: cover; background-position: center; background-repeat: no-repeat; position: relative; }
.band-night .nc-box, .band-green .nc-box { background-color: #262723; }
video[data-nc] { display: block; }
.js video[data-nc] { opacity: 0; transition: opacity .3s ease; }
.js video[data-nc].is-ready { opacity: 1; }
.nc-box.needs-tap { cursor: pointer; }
/* While a box waits for a tap (autoplay refused, or reduced motion) a real button covers it (media.js), so a keyboard
   reaches it and a screen reader names it; the play mark under it is the box's ::after. */
.nc-tap { position: absolute; inset: 0; z-index: 3; width: 100%; height: 100%; margin: 0; padding: 0; border: 0; border-radius: inherit; background: none; cursor: pointer; }
.nc-tap:focus-visible { outline: 3px solid #fff; outline-offset: -6px; border-radius: inherit; box-shadow: inset 0 0 0 9px rgba(0, 0, 0, .35); }
.nc-box.is-loading::before { content: ""; position: absolute; left: 50%; top: 50%; width: 34px; height: 34px; margin: -17px 0 0 -17px; border-radius: 50%; border: 3px solid rgba(255, 255, 255, .45); border-top-color: #fff; z-index: 4; opacity: 0; animation: nc-spin .8s linear infinite, nc-show .2s ease .6s forwards; filter: drop-shadow(0 1px 3px rgba(0, 0, 0, .35)); }
@keyframes nc-spin { to { transform: rotate(360deg); } }
@keyframes nc-show { to { opacity: 1; } }
.nc-box.needs-tap::after { content: ""; position: absolute; left: 50%; top: 50%; width: 64px; height: 64px; margin: -32px 0 0 -32px; border-radius: 50%; background: rgba(255, 255, 255, .94) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7.5 5.6v12.8a1.1 1.1 0 0 0 1.7.9l10-6.4a1.1 1.1 0 0 0 0-1.8l-10-6.4a1.1 1.1 0 0 0-1.7.9z' fill='%231b1a17'/%3E%3C/svg%3E") 50% 50% / 30px no-repeat; box-shadow: 0 8px 24px -8px rgba(0, 0, 0, .45); z-index: 2; }

/* A demo: something Nightcut made. Muted, plays while on screen. */
.demo { position: relative; border-radius: var(--r-short); overflow: hidden; }
.demo video { width: 100%; height: 100%; object-fit: cover; }
.tag { position: absolute; left: 14px; top: 14px; z-index: 3; display: inline-flex; align-items: center; gap: 7px; font: 600 16px/1 var(--font); color: var(--ink); background: rgba(255, 255, 255, .95); padding: 8px 12px; border-radius: var(--r-pill); box-shadow: 0 4px 14px -6px rgba(0, 0, 0, .35); }
.tag .ico { width: 16px; height: 16px; }

/* ---------- 3. The talk clip: "watch me say it" ----------
   Me on stage, with sound, only when pressed, playing right where it is. Context first (a lead-in line), then a
   frame from the talk with a big play button and the length, then the quoted line big, then where it was said.
   Short form for build.py: <div class="talk-card" data-src data-poster data-vtt data-dur data-lead data-quote
   data-cite></div>. Full markup and behaviour: COMPONENTS.md, NC.talk in base.js. */
.talk-card { margin: 0; display: grid; gap: var(--s3); align-content: start; max-width: 760px; }
.tc-lead { margin: 0; font-size: 18px; line-height: 1.45; font-weight: 500; color: var(--ink-2); text-wrap: pretty; }
.tc-v { position: relative; aspect-ratio: var(--tc-ar, 16 / 9); border-radius: var(--r-media); overflow: hidden; background: #191a17 center / cover no-repeat; box-shadow: var(--sh-3); isolation: isolate; }
.tc-v video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.tc-v::after { content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none; background: radial-gradient(circle at 50% 50%, rgba(0, 0, 0, .2), rgba(0, 0, 0, 0) 40%), linear-gradient(180deg, rgba(0, 0, 0, 0) 62%, rgba(0, 0, 0, .38)); transition: opacity .3s ease; }
.tc-play { position: absolute; inset: 0; z-index: 2; display: grid; place-items: center; width: 100%; padding: 0; border: 0; background: none; cursor: pointer; color: var(--ink); -webkit-tap-highlight-color: transparent; }
.tc-play:focus-visible { outline: 3px solid #fff; outline-offset: -6px; border-radius: var(--r-media); }
.tc-btn { display: grid; place-items: center; width: 88px; height: 88px; border-radius: 50%; background: rgba(255, 255, 255, .96); box-shadow: 0 14px 34px -12px rgba(0, 0, 0, .6), 0 0 0 0 rgba(255, 255, 255, .28); transition: box-shadow .25s ease, background .2s ease, opacity .25s ease; }
.tc-btn svg { grid-area: 1 / 1; width: 36px; height: 36px; display: block; fill: currentColor; }
.tc-btn .tc-i-again { display: none; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; width: 32px; height: 32px; }
.tc-play:hover .tc-btn, .tc-play:focus-visible .tc-btn { background: #fff; box-shadow: 0 14px 34px -12px rgba(0, 0, 0, .6), 0 0 0 10px rgba(255, 255, 255, .26); }
.tc-dur { position: absolute; right: 14px; bottom: 14px; z-index: 2; display: inline-flex; align-items: center; gap: 6px; padding: 6px 10px 6px 8px; border-radius: 8px; background: rgba(0, 0, 0, .72); color: #fff; font: 600 16px/1 var(--font); pointer-events: none; }
.tc-dur .ico { width: 16px; height: 16px; }
.tc-x { position: absolute; top: 12px; right: 12px; z-index: 3; display: none; place-items: center; width: 44px; height: 44px; border-radius: 50%; border: 0; background: rgba(0, 0, 0, .58); color: #fff; cursor: pointer; -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); transition: background .2s; }
.tc-x:hover { background: rgba(0, 0, 0, .8); }
.tc-x .ico { width: 20px; height: 20px; }
.tc-v .tc-card { position: absolute; inset: 0; z-index: 1; display: block; width: 100%; height: 100%; object-fit: cover; transition: opacity .25s ease; pointer-events: none; }
.talk-card.is-on .tc-card { opacity: 0; }
/* Captions: the dark background sits on each line of an inner span (box-decoration-break), so it hugs the words. */
.tc-cc { position: absolute; left: 50%; bottom: 20px; z-index: 2; transform: translateX(-50%); width: max-content; max-width: calc(100% - 40px); margin: 0; color: #fff; font: 600 clamp(16px, 1.5vw, 20px)/1.6 var(--font); text-align: center; text-wrap: balance; pointer-events: none; }
.tc-cc > span { padding: 3px 10px 4px; border-radius: 7px; background: rgba(0, 0, 0, .74); -webkit-box-decoration-break: clone; box-decoration-break: clone; }
.tc-cc:empty { display: none; }
.tc-bar { position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; height: 4px; background: rgba(255, 255, 255, .22); display: none; pointer-events: none; }
.tc-bar i { display: block; height: 100%; width: 100%; background: var(--yellow); transform: scaleX(var(--p, 0)); transform-origin: 0 50%; }
.talk-card.is-on .tc-v::after { opacity: 0; }
.talk-card.is-on .tc-dur { display: none; }
.talk-card.is-on .tc-x { display: grid; }
.talk-card.is-on .tc-bar { display: block; }
.talk-card.is-playing .tc-btn { opacity: 0; }
.talk-card.is-on:not(.is-playing) .tc-cc { opacity: 0; }
.talk-card.is-ended .tc-btn .tc-i-play { display: none; }
.talk-card.is-ended .tc-btn .tc-i-again { display: block; }
.talk-card .nc-box.is-loading .tc-btn { opacity: 0; }
.tc-q { margin: var(--s1) 0 0; font-size: clamp(24px, 2.3vw, 32px); line-height: 1.22; letter-spacing: -0.02em; font-weight: 700; color: var(--ink); text-wrap: pretty; }
.tc-q::before { content: "«"; color: var(--yellow); }
.tc-q::after { content: "»"; }
.tc-cite { display: flex; align-items: center; gap: 10px; margin: 0; font-style: normal; font-size: 16px; line-height: 1.4; font-weight: 500; color: var(--muted); text-wrap: balance; }
.tc-cite .ico { width: 18px; height: 18px; color: var(--green-3); }
.tc-after { margin: var(--s1) 0 0; font-size: 18px; line-height: 1.45; font-weight: 500; color: var(--ink-2); text-wrap: pretty; }
.tc-after b { color: var(--ink); }
/* Play button somewhere else than the centre (data-play-pos="x% y%" → --tc-px / --tc-py), for a frame with words in it. */
.talk-card[data-play-pos] .tc-play { display: block; }
.talk-card[data-play-pos] .tc-btn { position: absolute; left: var(--tc-px, 50%); top: var(--tc-py, 50%); transform: translate(-50%, -50%); }
.talk-card[data-play-pos] .tc-v::after { background: linear-gradient(180deg, rgba(0, 0, 0, 0) 62%, rgba(0, 0, 0, .34)); }
.band-green .tc-lead, .band-night .tc-lead { color: var(--night-2); }
.band-green .tc-q, .band-night .tc-q { color: #fff; }
.band-green .tc-cite, .band-night .tc-cite { color: var(--night-muted); }
.band-green .tc-cite .ico, .band-night .tc-cite .ico { color: var(--yellow); }
.band-green .tc-after, .band-night .tc-after { color: var(--night-2); }
.band-green .tc-after b, .band-night .tc-after b { color: #fff; }
.band-green .tc-v, .band-night .tc-v { box-shadow: var(--sh-dark); }
/* Beside (from 720px), the page's full size (07, 13): the lead-in across the top, the frame on the left, the quote, the
   cite and the turn-back line beside it, centred on the frame by the two flexible rows around them. */
@media (min-width: 720px) {
  .talk-card.side { grid-template-columns: minmax(0, 1.12fr) minmax(0, 1fr); grid-template-rows: auto 1fr auto auto auto 1fr; column-gap: var(--s6); row-gap: var(--s2); max-width: none; }
  .talk-card.side .tc-lead { grid-column: 1 / -1; grid-row: 1; margin-bottom: var(--s2); font-size: clamp(19px, 1.5vw, 22px); }
  .talk-card.side .tc-v { grid-column: 1; grid-row: 2 / span 5; }
  .talk-card.side .tc-q { grid-column: 2; grid-row: 3; margin: 0; font-size: clamp(26px, 2.7vw, 38px); line-height: 1.15; }
  .talk-card.side .tc-cite { grid-column: 2; grid-row: 4; }
  .talk-card.side .tc-after { grid-column: 2; grid-row: 5; }
}
@media (min-width: 720px) and (max-width: 899px) { .talk-card.side { column-gap: var(--s4); } .talk-card.side .tc-q { font-size: 22px; } }
/* Compact (from 720px): a small frame (about 272–320px) beside the words, for a clip that backs up a chapter's point
   rather than being its focal visual (03, 08). The lead-in, the quote and the cite sit in the words column. */
@media (min-width: 720px) {
  .talk-card.compact { grid-template-columns: clamp(240px, 24vw, 320px) minmax(0, 1fr); grid-template-rows: auto auto 1fr; column-gap: var(--s5); row-gap: var(--s1); align-items: start; max-width: 800px; }
  .talk-card.compact .tc-v { grid-column: 1; grid-row: 1 / span 4; }
  .talk-card.compact .tc-lead { grid-column: 2; grid-row: 1; padding-top: 2px; }
  .talk-card.compact .tc-q { grid-column: 2; grid-row: 2; margin: 0; font-size: clamp(22px, 1.9vw, 26px); }
  .talk-card.compact .tc-cite { grid-column: 2; grid-row: 3; align-self: start; }
  .talk-card.compact .tc-after { grid-column: 2; grid-row: 4; }
  .talk-card.compact .tc-btn { width: 60px; height: 60px; }
  .talk-card.compact .tc-btn svg { width: 26px; height: 26px; }
  .talk-card.compact .tc-btn .tc-i-again { width: 24px; height: 24px; }
  .talk-card.compact .tc-dur { right: 8px; bottom: 8px; padding: 5px 8px 5px 7px; }
  .talk-card.compact .tc-x { top: 6px; right: 6px; }
  .talk-card.compact .tc-cc { bottom: 10px; max-width: calc(100% - 16px); font-size: 16px; }
}
@media (max-width: 719px) {
  .tc-btn { width: 72px; height: 72px; }
  .tc-btn svg { width: 30px; height: 30px; }
  .tc-cc { bottom: 14px; max-width: calc(100% - 24px); font-size: 16px; }
  .tc-dur { right: 10px; bottom: 10px; }
  .tc-x { top: 8px; right: 8px; }
  /* compact on a phone (03, 08; from 03's polish), and side too (07, 13; the page was 23 screens long on a phone):
     a small frame beside the quote, so a clip that backs up a point costs ~150px, not a full-width frame. A tap
     opens it to the full width and plays it there with its captions; × or the end closes it back. The cite is left out (the lead already says where it is from). base.js scrolls the
     page just enough to keep the opened frame on screen. */
  .talk-card:is(.compact, .side) { grid-template-columns: 136px minmax(0, 1fr); column-gap: var(--s3); row-gap: 10px; align-items: center; }
  .talk-card:is(.compact, .side) .tc-lead { grid-column: 1 / -1; grid-row: 1; font-size: 16px; line-height: 1.4; }
  .talk-card:is(.compact, .side) .tc-v { grid-column: 1; grid-row: 2; border-radius: var(--r-thumb); }
  .talk-card:is(.compact, .side) .tc-q { grid-column: 2; grid-row: 2; margin: 0; font-size: 18px; line-height: 1.3; letter-spacing: -0.01em; }
  .talk-card:is(.compact, .side) .tc-cite { display: none; }
  .talk-card:is(.compact, .side) .tc-after { grid-column: 1 / -1; }
  .talk-card:is(.compact, .side) .tc-btn { width: 44px; height: 44px; }
  .talk-card:is(.compact, .side) .tc-btn svg { width: 19px; height: 19px; }
  .talk-card:is(.compact, .side) .tc-btn .tc-i-again { width: 18px; height: 18px; }
  .talk-card:is(.compact, .side):not(.is-on):not(.is-ended) .tc-dur { display: none; }
  .talk-card:is(.compact, .side).is-on, .talk-card:is(.compact, .side).is-ended { row-gap: var(--s2); }
  .talk-card:is(.compact, .side).is-on .tc-v, .talk-card:is(.compact, .side).is-ended .tc-v { grid-column: 1 / -1; border-radius: var(--r-media); }
  .talk-card:is(.compact, .side).is-on .tc-q, .talk-card:is(.compact, .side).is-ended .tc-q { grid-column: 1 / -1; grid-row: 3; }
  .talk-card:is(.compact, .side).is-on .tc-btn, .talk-card:is(.compact, .side).is-ended .tc-btn { width: 72px; height: 72px; }
  .talk-card:is(.compact, .side).is-on .tc-btn svg, .talk-card:is(.compact, .side).is-ended .tc-btn svg { width: 30px; height: 30px; }
}

/* Legacy: v11's talk plaque (button.talk), still in chapters until they move to .talk-card. */
button.talk { display: inline-flex; align-items: center; gap: 14px; margin: 0; padding: 7px 22px 7px 7px; border: 1px solid var(--line); border-radius: var(--r-pill); background: var(--card); cursor: pointer; text-align: left; font: inherit; color: inherit; transition: border-color .2s, background .2s; }
button.talk:hover { border-color: var(--line-2); }
button.talk .talk-v { position: relative; flex: none; width: 48px; height: 48px; border-radius: 50%; background: var(--green) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M7 4.5v11l8.5-5.5z' fill='%23fff'/%3E%3C/svg%3E") 56% 50% / 20px no-repeat; }
button.talk .talk-v img { display: none; }
.band-green button.talk .talk-v, .band-night button.talk .talk-v { background-color: var(--yellow); background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M7 4.5v11l8.5-5.5z' fill='%23161512'/%3E%3C/svg%3E"); }
button.talk .talk-t { display: grid; gap: 2px; }
button.talk .talk-t b { font-size: 17px; font-weight: 600; }
button.talk .talk-t span { font-size: 16px; color: var(--muted); }
.band-green button.talk, .band-night button.talk { background: rgba(255, 255, 255, .06); border-color: rgba(255, 255, 255, .16); }
.band-green button.talk:hover, .band-night button.talk:hover { border-color: rgba(255, 255, 255, .32); }
.band-green button.talk .talk-t span, .band-night button.talk .talk-t span { color: var(--night-muted); }
/* …and its big player: one dialog for the whole page, the video big and with sound. */
dialog.player { border: 0; padding: 0; background: transparent; width: min(1040px, calc(100vw - 32px)); max-height: calc(100vh - 32px); overflow: visible; }
dialog.player::backdrop { background: rgba(14, 14, 12, .84); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.player-v { position: relative; border-radius: var(--r-media); overflow: hidden; background: #000; aspect-ratio: 16 / 9; }
.player-v video { width: 100%; height: 100%; display: block; }
.player-cap { margin: 16px 4px 0; color: #f2f0e9; font-size: 19px; font-weight: 500; text-align: center; }
.player-x { position: absolute; top: -56px; right: 0; width: 44px; height: 44px; border-radius: 50%; border: 0; background: rgba(255, 255, 255, .14); color: #fff; cursor: pointer; display: grid; place-items: center; }
.player-x:hover { background: rgba(255, 255, 255, .24); }
.player-x .ico { width: 20px; height: 20px; }

/* ---------- 4. The explainer sheet ----------
   Any [data-explain="tpl-id"] (or the older [data-sheet]) opens <template id="tpl-id"> in one dialog: a centred
   modal on a laptop, a bottom sheet on a phone (grab handle, swipe down, backdrop tap, Esc and × all close it).
   The template's first <h2> becomes the title row; the rest is the content: one small visual (.ex-fig) and at most
   two or three short lines (.ex-lines). NC.explain.on(id, fn) starts an animation when it opens. */
dialog.sheet { --sheet-pad: 32px; position: fixed; display: none; flex-direction: column; padding: 0; border: 0; border-radius: var(--r-card); width: min(680px, calc(100vw - 32px)); max-width: none; max-height: min(880px, calc(100svh - 48px)); overflow: hidden; background: var(--card); color: var(--ink); box-shadow: 0 40px 100px -30px rgba(20, 18, 10, .55); opacity: 0; transform: translateY(12px) scale(.985); transition: opacity .22s ease, transform .3s var(--ease); }
dialog.sheet[open] { display: flex; }
dialog.sheet.is-open { opacity: 1; transform: none; }
dialog.sheet::backdrop { background: rgba(20, 19, 16, .5); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); opacity: 0; transition: opacity .25s ease; }
dialog.sheet.is-open::backdrop { opacity: 1; }
.sheet-grab { display: none; }
.sheet-top { flex: none; display: flex; align-items: center; gap: var(--s3); min-height: 76px; padding: 16px 16px 0 var(--sheet-pad); }
.sheet-top h2 { flex: 1; min-width: 0; margin: 0; font-size: 30px; line-height: 1.1; letter-spacing: -0.025em; }
.sheet-x { flex: none; align-self: flex-start; display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; border: 0; background: var(--soft); color: var(--ink); cursor: pointer; transition: background .15s; }
.sheet-x:hover { background: var(--soft-2); }
.sheet-x .ico { width: 18px; height: 18px; }
.sheet-in { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 16px var(--sheet-pad) var(--sheet-pad); }
.sheet-in > :first-child { margin-top: 0; }
/* Plain text straight in a template (v11's explainers) still reads well; an explainer's own parts style themselves. */
.sheet-in > p, .sheet-in > ul > li { font-size: 18px; color: var(--ink-2); line-height: 1.5; }
.sheet-in > p { margin: 0 0 14px; }
.sheet-in > ul { margin: 0 0 14px; padding-left: 20px; }
.sheet-in > ul > li + li { margin-top: 8px; }
.sheet-in a { color: var(--green); }
/* The content of an explainer: one visual, then a few short lines. */
.ex-fig { position: relative; margin: 0 0 var(--s4); padding: var(--s4); border-radius: var(--r-media); background: var(--soft); overflow: hidden; }
.ex-fig svg { display: block; width: 100%; height: auto; }
.ex-lines { display: grid; gap: 10px; margin: 0; padding: 0; list-style: none; }
.ex-lines > * { margin: 0; font-size: 18px; line-height: 1.45; color: var(--ink-2); text-wrap: pretty; }
.ex-lines b { color: var(--ink); }
.ex-src { margin: var(--s3) 0 0; font-size: 16px; color: var(--muted); }
@media (max-width: 719px) {
  dialog.sheet { --sheet-pad: 20px; inset: auto 0 0 0; margin: 0; width: 100%; max-height: 85svh; border-radius: 24px 24px 0 0; padding-bottom: env(safe-area-inset-bottom); opacity: 1; transform: translateY(100%); transition: transform .34s var(--ease); box-shadow: 0 -20px 60px -20px rgba(20, 18, 10, .45); }
  dialog.sheet.is-open { transform: translateY(var(--drag, 0px)); }
  dialog.sheet.is-dragging { transition: none; }
  .sheet-grab { display: block; flex: none; height: 20px; touch-action: none; cursor: grab; position: relative; }
  .sheet-grab::before { content: ""; position: absolute; left: 50%; top: 8px; width: 40px; height: 5px; margin-left: -20px; border-radius: 3px; background: var(--line-2); }
  .sheet-top { min-height: 56px; padding: 0 12px 0 var(--sheet-pad); touch-action: none; }
  .sheet-top h2 { font-size: 24px; }
  .sheet-x { align-self: center; }
  .sheet-in { padding-top: 12px; }
  .ex-fig { padding: var(--s3); margin-bottom: var(--s3); }
  .ex-lines > * { font-size: 17px; }
}
/* Short phones (375×667): a tighter title row and figure so a visual and its lines still fit without scrolling. */
@media (max-width: 719px) and (max-height: 700px) {
  .sheet-top { min-height: 48px; }
  .sheet-top h2 { font-size: 22px; }
  .sheet-in { padding-top: 6px; padding-bottom: 12px; }
  .ex-fig { padding: var(--s2); margin-bottom: var(--s2); }
  .ex-lines { gap: 6px; }
  .ex-lines > * { font-size: 16px; line-height: 1.4; }
}
@media (prefers-reduced-motion: reduce) { dialog.sheet, dialog.sheet::backdrop { transition: none; } }

/* ---------- 5. The swipe row ----------
   <div class="swipe" data-swipe><ul class="swipe-track"><li>card</li>…</ul></div>. Apple-style: cards snap, the
   next one peeks, the row runs to the screen edge while its first card lines up with the page margin; dots under
   it, arrow buttons on a laptop, arrow keys work. .swipe.until-lg is a plain grid from 1000px.
   NC.swipe (base.js): the shown card's video plays while the row is 60% on screen; a swipe stops auto-advance. */
.swipe { --swipe-gap: 16px; --swipe-w: 84%; --swipe-w-md: 46%; --swipe-w-lg: 31%; --swipe-cols: 3; position: relative; min-width: 0; }
.swipe-track { display: flex; gap: var(--swipe-gap); margin: -12px calc(-1 * var(--gutter)) -34px; padding: 12px var(--gutter) 44px; overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; scroll-snap-type: x mandatory; scroll-padding-inline: var(--gutter); scrollbar-width: none; list-style: none; }
.swipe-track::-webkit-scrollbar { display: none; }
.swipe-track:focus-visible { outline-offset: -3px; }
.swipe-track > * { flex: none; width: var(--swipe-w); min-width: 0; margin: 0; scroll-snap-align: start; }
/* Straight inside a .wrap (or with .full) the row runs to the edges of the window; its first card still lines up
   with the page's text edge (the .wrap's inset, worked out without % so scroll-padding gets the same number). */
.wrap > .swipe .swipe-track, .swipe.full .swipe-track { --inset: max(var(--gutter), (100vw - var(--wrap)) / 2); margin-inline: calc(-1 * var(--inset)); padding-inline: var(--inset); scroll-padding-inline: var(--inset); }
@media (min-width: 720px) { .swipe-track > * { width: var(--swipe-w-md); } }
@media (min-width: 1000px) {
  .swipe-track > * { width: var(--swipe-w-lg); }
  .swipe.until-lg .swipe-track { display: grid; grid-template-columns: repeat(var(--swipe-cols), minmax(0, 1fr)); margin: 0 !important; padding: 0 !important; overflow: visible; }
  .swipe.until-lg .swipe-track > * { width: auto; }
  .swipe.until-lg .swipe-nav { display: none; }
}
.swipe-nav { position: relative; z-index: 1; display: flex; align-items: center; justify-content: center; min-height: 44px; margin-top: var(--s1); }
.swipe-dots { display: flex; align-items: center; }
.swipe-dot { display: grid; place-items: center; width: 44px; height: 44px; padding: 0; border: 0; background: none; cursor: pointer; }
.swipe-dot::before { content: ""; width: 8px; height: 8px; border-radius: 4px; background: var(--line-2); transition: width .3s var(--ease), background .3s; }
.swipe-dot[aria-current="true"]::before { width: 24px; background: var(--ink); }
.swipe-count { font-size: 16px; font-weight: 600; color: var(--ink-2); }
.swipe-arrows { position: absolute; right: 0; top: 50%; transform: translateY(-50%); display: none; gap: 10px; }
.swipe-arrow { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; border: 1px solid var(--line-2); background: var(--card); color: var(--ink); cursor: pointer; transition: background .15s, opacity .2s; }
.swipe-arrow:hover { background: var(--soft); }
.swipe-arrow:disabled { opacity: .35; cursor: default; }
.swipe-arrow .ico { width: 20px; height: 20px; }
.swipe-arrow.prev .ico { transform: scaleX(-1); }
@media (pointer: fine) and (min-width: 720px) { .swipe-arrows { display: flex; } }
.band-night .swipe-dot::before, .band-green .swipe-dot::before { background: rgba(255, 255, 255, .25); }
.band-night .swipe-dot[aria-current="true"]::before, .band-green .swipe-dot[aria-current="true"]::before { background: #fff; }
.band-night .swipe-count, .band-green .swipe-count { color: var(--night-2); }
.band-night .swipe-arrow, .band-green .swipe-arrow { background: rgba(255, 255, 255, .08); border-color: rgba(255, 255, 255, .2); color: #fff; }
.band-night .swipe-arrow:hover, .band-green .swipe-arrow:hover { background: rgba(255, 255, 255, .16); }

/* ---------- FAQ ---------- */
.faq details { border-bottom: 1px solid var(--line); }
.faq summary { cursor: pointer; list-style: none; padding: 22px 48px 22px 0; font-size: 20px; font-weight: 600; position: relative; transition: color .15s; }
.faq summary:hover { color: var(--green); }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: ""; position: absolute; right: 10px; top: 50%; width: 10px; height: 10px; border: solid currentColor; border-width: 0 2px 2px 0; transform: translateY(-70%) rotate(45deg); transition: transform .2s; }
.faq details[open] summary::after { transform: translateY(-30%) rotate(225deg); }
.faq details p { margin: -6px 0 24px; color: var(--ink-2); max-width: 38em; font-size: 18px; }
.faq-more { display: none; }
/* A long .faq on a phone (base.js): the first six questions, then one more row in the list's own look that opens the
   rest. Green like the open question, a plus where the questions have their icons. */
@media (max-width: 719px) {
  .faq .is-more-hid { display: none; }
  .faq-more { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 64px; margin: 0; padding: 14px 0; border: 0; border-bottom: 1px solid var(--line); background: none; color: var(--green); font: 600 18px/1.3 var(--font); text-align: left; cursor: pointer; }
  .faq-more .ico { width: 20px; height: 20px; color: var(--green-3); }
  .faq-more:active { opacity: .72; }
}

/* ---------- Footer ---------- */
footer.site { padding-top: 40px; padding-bottom: 64px; color: var(--muted); font-size: 16px; border-top: 1px solid var(--line); display: grid; gap: 16px; }
@media (min-width: 900px) { footer.site { grid-template-columns: 1fr auto; align-items: start; } }
.foot-logo { display: inline-flex; margin-bottom: 4px; }
.foot-logo svg { height: 24px; color: var(--green); }
.foot-links { display: flex; flex-wrap: wrap; gap: 0 24px; }
.foot-links a { min-height: 44px; color: var(--ink-2); font-weight: 500; text-decoration: none; display: inline-flex; align-items: center; gap: 8px; }
.foot-links a:hover, .foot-links a:active { color: var(--ink); }
.foot-links .ico { width: 20px; height: 20px; }
.foot-fine { margin: 0; max-width: 46em; }
/* Phone: one compact block (about 150 px, not 350), so the last view is the closing line, not the footer. The logo
   and the two icons on one row (their names are aria-labels), the fine print in two lines under them: the
   .foot-more parts are said on the page already, and the reserve link goes (the header's button and the end's big
   one are on the same screen). 17 measures the footer and gives the rest of the last view to its line. */
@media (max-width: 719px) {
  footer.site { grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: var(--s1) var(--s3); padding-top: var(--s4); padding-bottom: calc(var(--s4) + env(safe-area-inset-bottom, 0px)); }
  footer.site > div { display: contents; }
  .foot-logo { grid-area: 1 / 1; justify-self: start; margin: 0; }
  .foot-links { grid-area: 1 / 2; flex-wrap: nowrap; gap: var(--s1); margin-right: -10px; }
  .foot-links a { justify-content: center; min-width: 44px; }
  .foot-links .ico { width: 24px; height: 24px; }
  .foot-links .foot-t, .foot-links .foot-rs, .foot-fine .foot-more { display: none; }
  .foot-fine { grid-area: 2 / 1 / 3 / -1; line-height: 1.45; }
}

/* ---------- Reserve dialog: title, one line, the field, the button. Never under a phone's keyboard. ---------- */
dialog.reserve { border: 0; border-radius: var(--r-card); padding: 30px 30px 22px; width: min(440px, calc(100vw - 32px)); background: var(--card); color: var(--ink); box-shadow: 0 40px 100px -30px rgba(20, 18, 10, .55); }
dialog.reserve::backdrop { background: rgba(20, 19, 16, .5); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); }
.reserve h2 { font-size: 32px; margin: 0 52px 8px 0; }
.reserve p { color: var(--ink-2); margin: 0 0 20px; font-size: 18px; }
.rs-field { display: block; margin-bottom: 12px; }
.rs-field input { font: 400 18px var(--font); height: 56px; padding: 0 16px; border: 1px solid var(--line-2); border-radius: var(--r-ctl); background: var(--bg); color: var(--ink); width: 100%; }
.rs-field input:focus { outline: 3px solid var(--green); outline-offset: 0; border-color: transparent; }
.rs-form .btn { width: 100%; }
.reserve .rs-fine { font-size: 16px; margin: 12px 0 0; text-align: center; color: var(--muted); }
.rs-close-f { position: absolute; top: 14px; right: 14px; margin: 0; }
.rs-close { width: 44px; height: 44px; border-radius: 50%; border: 0; background: var(--soft); color: var(--ink); cursor: pointer; display: grid; place-items: center; }
.rs-close:hover { background: var(--soft-2); }
.rs-close svg { width: 18px; height: 18px; }
@media (max-width: 719px) {
  dialog.reserve { margin: max(12px, env(safe-area-inset-top)) auto auto; padding: 22px 20px 16px; }
  .reserve h2 { font-size: 27px; }
  .reserve p { margin-bottom: 16px; }
}
