/* Signhome design v2 "the gallery" (WHIP-SHIP DESIGN-V2.md v2.0, Elon 24 Oct 2026). Loaded AFTER the brand tokens/base.
   Grammar from the MIT-licensed VoltAgent awesome-design-md reference (rhythm, type scale, restraint, motion); no third-party
   identity, names, imagery or font files. Light default; dark mode equally finished. One accent, one shadow, weights 400/600. */
/* fix1 design (Elon DESIGN-V2 v2.1): Geist and Geist Mono load exactly as the hub/brand README says: preload
   /brand/fonts/Geist-Variable-latin.woff2, then /brand/fonts.css (pewterkit/brand fonts.css, byte-identical: same files, same
   @font-face, weights 100-900, font-display: swap, SIL OFL 1.1 in /brand/fonts/OFL.txt), all self-hosted by this Worker. No @font-face
   here, no third-party fetch; system-ui is the only fallback. */
:root {
  /* Surfaces and text from the pewterkit/brand kit tokens (tokens.css, DESIGN.md v1.0), which switch for dark mode themselves.
     Light: page --pk-canvas, parchment tiles --pk-surface, the product tile --pk-ink with its card one step up (--pk-pewter-800).
     Dark: page --pk-canvas (#0d0f11), parchment tiles a visible step up (--pk-surface mixed with --pk-hairline), the product tile
     --pk-hairline (#2a2e34) and its card --pk-pewter-800 (#353a41). Text AA on every surface (axe 0 serious). */
  --v-canvas: var(--pk-canvas); --v-parch: var(--pk-surface); --v-ink: var(--pk-ink); --v-muted: var(--pk-muted); --v-hair: var(--pk-hairline);
  --v-tile: var(--pk-ink); --v-tile-ink: var(--pk-pewter-50); --v-tile-muted: var(--pk-pewter-400); --v-tile-hair: rgba(255,255,255,.14);
  --v-accent: #3b5bdb; --v-accent-ink: #ffffff; --v-accent-on-tile: #8ea2f0; /* tokens.css own-domain-signin accents (light / on dark) */
  --v-ok: #1f9d55; --v-warn: #b7791f; --v-bad: #d64545; --v-unk: #8e8e93;
  --v-shadow: 0 5px 30px rgba(0,0,0,.18);
  --v-tile-line: rgba(163,169,177,.32); --v-tile-card: var(--pk-pewter-800); /* pewter-400 hairline at 32% + one-step-lighter card */
  /* fix1 type scale (CEO 23:3x UK): every H1 >= 1.25x the largest H2 on its page at every width, by bringing the H2s down.
     Landing: hero H1 56/40/34/34 vs H2 40/32/27/22. Every other page: H1 36 (>640) / 28 (<=640) vs H2 28 / 22. */
  --v-h1: 36px; --v-h2: 28px; --v-gut: 48px;
  --v-sans: "Geist", system-ui, sans-serif;
  --v-mono: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  /* brand tokens re-pointed so the shared nav/footer and content pages follow v2 */
  --pk-font-sans: var(--v-sans); --pk-font-mono: var(--v-mono);
  --pk-body-lh: 1.47; --pk-body-size: 17px;
  --pk-radius-card: 18px; --pk-radius-input: 9999px; --pk-shadow-raised: none; --pk-nav-height: 52px;
  color-scheme: light dark;
}
[data-tool="own-domain-signin"] { --pk-accent: var(--v-accent); --pk-accent-contrast: var(--v-accent-ink); }
@media (prefers-color-scheme: dark) {
  :root { --v-parch: color-mix(in srgb, var(--pk-surface) 50%, var(--pk-hairline)); --v-tile: var(--pk-hairline);
    --v-accent: #6f8cff; --v-accent-ink: #000000; }
  [data-tool="own-domain-signin"] { --pk-accent: var(--v-accent); --pk-accent-contrast: var(--v-accent-ink); }
}
body { font-family: var(--v-sans); font-size: 17px; line-height: 1.47; color: var(--v-ink); background: var(--v-canvas); letter-spacing: -0.01em; }
h1, h2, h3, h4, h5, h6 { text-wrap: balance; hyphens: none; font-weight: 600; color: inherit; }
b, strong, th, summary, .pk-nav__brand, .pk-btn { font-weight: 600; } /* weights 400/600 only (no UA bold 700) */
h1 { font-size: var(--v-h1); line-height: 1.15; letter-spacing: -0.02em; } /* landing hero H1 = .v-hero */
h2 { font-size: var(--v-h2); line-height: 1.15; letter-spacing: -0.02em; }
@media (max-width: 640px) { :root { --v-h1: 28px; --v-h2: 22px; } }
/* fix1 design (CEO 23:3x UK): hostnames and mono text break ONLY after a dot / path slash (<wbr>, pages.js monoSeg/hostSpan);
   each label is a nowrap span, never hyphenated. A label wider than the line scales the font down (--n = its length in
   characters, --v-gut = the horizontal space outside the text column) instead of wrapping inside it: no sideways scroll at 320. */
.v-host, code, .v-mono, .pk-prompt, kbd { hyphens: none; overflow-wrap: normal; }
.v-host > span, code > span, .v-mono > span, .pk-prompt > span { white-space: nowrap; }
.v-host { font-size: min(1em, calc((100vw - var(--v-gut)) / (var(--n, 1) * .64))); }
.v-mono { font-size: min(1em, calc((100vw - var(--v-gut)) / (var(--n, 1) * .6))); }
h1, h2, h3, p, li, dd, dt, label, figcaption { overflow-wrap: break-word; }
/* Ops D6: a visible field label is a tap target too (it focuses its input): 44px tall. */
.v-label { display: flex; align-items: center; min-height: 44px; margin: 0 0 4px; cursor: pointer; }
.pk-btn:active { transform: scale(.97); }
.pk-nav__brand { min-height: 44px; }
.pk-prompt .pk-btn, button.pk-btn { min-height: 44px; }
/* Ops D5: the snippet and prompt wrap inside their box at 320px instead of widening the page (copied text is unchanged). */
.pk-prompt { white-space: pre-wrap; max-width: 100%; box-sizing: border-box; font-size: min(14px, calc((100vw - var(--v-gut) - 42px) / (var(--n, 1) * .6))); }
p, li { text-wrap: pretty; }
a { color: var(--v-accent); }
a:hover { color: var(--v-accent); opacity: .8; }
:focus-visible { outline: 2px solid var(--v-accent); outline-offset: 3px; }
code { font-family: var(--v-mono); font-size: min(.88em, calc((100vw - var(--v-gut)) / (var(--n, 1) * .6))); }
.pk-nav { background: color-mix(in srgb, var(--v-canvas) 80%, transparent); backdrop-filter: saturate(180%) blur(20px); border-bottom: 1px solid var(--v-hair); }
.pk-section + .pk-section { border-top: 0; }
.pk-footer { background: var(--v-parch); border-top: 0; }
/* fix1 design (panel item 4, CEO 23:3x UK): nav and footer links get a 44px-tall tap area by padding; list gaps become 0 so the
   44px boxes stack edge to edge and never overlap each other or neighbouring text. Inline links in running text are exempt. */
.pk-nav__links { gap: 8px; }
.pk-nav__links a { display: inline-flex; align-items: center; min-height: 44px; padding: 12px 8px; box-sizing: border-box; white-space: nowrap; }
.pk-footer ul { gap: 0; }
.pk-footer li { min-height: 44px; display: flex; align-items: center; }
.pk-footer li a { display: inline-flex; align-items: center; min-height: 44px; padding: 12px 0; box-sizing: border-box; }
.pk-footer .pk-nav__brand { min-height: 44px; }

/* preview pill: on the page grid */
.v-preview { max-width: var(--pk-content-max, 1100px); margin: 0 auto; padding: 16px 24px 0; }
.v-preview .pk-tag { display: inline-block; font-size: 12px; line-height: 1; padding: 6px 10px; border-radius: 9999px; background: var(--v-parch); color: var(--v-muted); border: 1px solid var(--v-hair); }

/* tiles: full width, no radius; the colour change is the divider */
.t { padding: 80px 0; background: var(--v-canvas); color: var(--v-ink); }
.t--parch { background: var(--v-parch); }
.t--dark { background: var(--v-tile); color: var(--v-tile-ink); --v-muted: var(--v-tile-muted); --v-hair: var(--v-tile-hair);
  box-shadow: inset 0 1px 0 var(--v-tile-line), inset 0 -1px 0 var(--v-tile-line); } /* fix1 (panel): pewter hairline top/bottom edge */
.t--dark a:not(.v-btn) { color: var(--v-accent-on-tile); }
.t--first { padding-top: 64px; }
.t__in { max-width: 980px; margin: 0 auto; padding: 0 24px; }
.t__in--wide { max-width: 1200px; }
.t__in--c { text-align: center; }
.t h2 { font-size: var(--v-h2); line-height: 1.1; letter-spacing: -0.02em; margin: 0 0 16px; }
.v-hero { font-size: 56px; line-height: 1.07; letter-spacing: -0.02em; margin: 0 auto 16px; max-width: 16ch; }
.v-lead { font-size: 21px; line-height: 1.3; color: var(--v-muted); margin: 0 auto 32px; max-width: 34em; }
.v-fine { font-size: 12px; line-height: 1.4; color: var(--v-muted); }
.v-muted { color: var(--v-muted); }
small, .pk-small { color: var(--v-muted); } /* the kit's small text follows the surface it sits on (tile-muted on the dark tile: AA) */
@media (max-width: 1068px) { .v-hero { font-size: 40px; } }
@media (max-width: 640px) { .t { padding: 64px 0 48px; } .t--first { padding-top: 64px; } .v-hero { font-size: 34px; } .v-lead { font-size: 19px; } }
/* FIX 3 (CEO 00:1x UK): the landing H1 stays 34px down to 320 (text-wrap: balance; 'sign-in.' is one nowrap unit) */
/* landing (the page with the 56px hero): H2 40/32/27/22 so the hero H1 stays >= 1.25x at every width */
main:has(.v-hero) { --v-h2: 40px; }
@media (max-width: 1068px) { main:has(.v-hero) { --v-h2: 32px; } }
@media (max-width: 640px) { main:has(.v-hero) { --v-h2: 27px; } }
@media (max-width: 419px) { main:has(.v-hero) { --v-h2: 22px; } }

/* one card per tile at most */
.v-card { background: var(--v-canvas); color: var(--v-ink); border: 1px solid var(--v-hair); border-radius: 18px; padding: 32px; text-align: left; }
.t--parch .v-card { background: var(--v-canvas); }
.t--dark .v-card { background: var(--v-tile-card); color: var(--v-tile-ink); border-color: var(--v-tile-line);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06); } /* fix1 (panel): card one step lighter than the tile + pewter hairline (brand v2 dark hierarchy) */
.v-card--c { max-width: 560px; margin: 0 auto; }
.v-card { --v-gut: 112px; }
@media (max-width: 640px) { .v-card { padding: 24px; --v-gut: 96px; } }
@media (max-width: 400px) { .v-card:has([data-for]) { padding: 24px 16px; } } /* /unlock: 238px URL line at 320, so a 30-char project label + scheme fits at 12px */

/* pills */
.v-btn { display: inline-flex; align-items: center; justify-content: center; min-height: 48px; padding: 0 24px; border-radius: 9999px; border: 0;
  background: var(--v-accent); color: var(--v-accent-ink); font: 600 17px/1 var(--v-sans); text-decoration: none; cursor: pointer; transition: transform 120ms ease-out, opacity 120ms ease-out; white-space: nowrap; }
.v-btn:hover { color: var(--v-accent-ink); opacity: .9; }
.v-btn:active { transform: scale(.97); }
.v-link { display: inline-flex; align-items: center; min-height: 44px; }
.v-form { max-width: 620px; margin: 0 auto; }
.v-form__row { display: flex; gap: 8px; }
.v-input { flex: 1; min-width: 0; min-height: 48px; padding: 0 20px; border-radius: 9999px; border: 1px solid var(--v-hair); background: var(--v-canvas); color: var(--v-ink);
  font: 400 17px/1 var(--v-sans); }
.t--parch .v-input { background: var(--v-canvas); }
.v-input::placeholder { color: var(--v-muted); opacity: 1; }
.v-input:focus { outline: 2px solid var(--v-accent); outline-offset: 1px; }
@media (max-width: 640px) { .v-form__row { flex-direction: column; } .v-btn { width: 100%; } .v-row .v-btn { width: auto; } }

/* styled checkbox: a 44px hit area (the input itself) drawing a 20px box */
.v-check { display: flex; gap: 2px; align-items: flex-start; justify-content: center; margin-top: 8px; font-size: 15px; line-height: 1.45; color: var(--v-muted); text-align: left; cursor: pointer; }
.v-check > span { padding-top: 11px; }
.v-check--l { justify-content: flex-start; }
.v-check input { appearance: none; -webkit-appearance: none; flex: none; width: 44px; height: 44px; margin: 0 0 0 -12px; border: 0; background: none; display: grid; place-items: center; cursor: pointer; }
.v-check input::before { content: ""; grid-area: 1 / 1; width: 20px; height: 20px; box-sizing: border-box; border: 1.5px solid var(--v-muted); border-radius: 6px; background: var(--v-canvas); }
.v-check input::after { content: ""; grid-area: 1 / 1; width: 10px; height: 6px; border: 2px solid var(--v-accent-ink); border-top: 0; border-right: 0; transform: translateY(-1px) rotate(-45deg); opacity: 0; }
.v-check input:checked::before { background: var(--v-accent); border-color: var(--v-accent); }
.v-check input:checked::after { opacity: 1; }
/* fix1 (panel): a visible focus ring around the drawn 20px box, on the input itself (44px box, -10px offset = a 24px ring) */
.v-check input:focus-visible { outline: 2px solid var(--v-accent); outline-offset: -10px; border-radius: 8px; }
/* fix1 design (CEO 23:3x UK): consent label on /unlock. Every line is 22px (even leading, no gap). The Terms link is always on the
   FIRST line (it is the 4th word), so its 44px tap area is that 22px line plus 22px of padding ABOVE it, inside the label's 11px top
   padding and the 12px space above the label, where there is no text. The tap area ends exactly at the first line's bottom edge:
   0 overlap with the second line, and it sits to the right of the 44x44 tickbox (0 overlap). No z-index, nothing painted over text. */
.v-check { line-height: 22px; }
.v-check a { display: inline-block; padding: 22px 0 0; margin-top: -22px; line-height: 22px; vertical-align: bottom; }
.v-check--l { margin-top: 12px; }
.t--first .v-check--l { margin-left: 0; }

/* the product visual: our own illustration of a sign-in screen (no third-party logo or wordmark) */
.v-visual { margin: 56px auto 0; max-width: 440px; }
.v-shot { background: #ffffff; color: #1f1f1f; border-radius: 18px; box-shadow: var(--v-shadow); padding: 36px 32px 32px; text-align: left; }
.v-shot__h { font: 400 26px/1.2 var(--v-sans); margin: 0 0 8px; color: #1f1f1f; letter-spacing: 0; }
.v-shot__to { position: relative; font-size: 16px; line-height: 1.4; color: #3c4043; margin: 0 0 28px; min-height: 2.8em; }
.v-shot__name { font-weight: 600; }
.v-shot__a, .v-shot__b { display: block; }
/* fix1 design (CEO 23:3x UK, panel item 3): the drawing paints 'before' from the very first frame (the .js class is set in <head>,
   before first paint), crossfades ONCE to 'after' (text and bar together, 800ms) and holds 'after'. No loop. Without script, or
   with prefers-reduced-motion, it is a static 'after' with no animation. */
.v-shot__a { opacity: 0; } /* static (no JS / reduced motion) = after */
.v-shot__b { position: absolute; inset: 0; opacity: 1; }
.v-shot__bar { position: relative; height: 6px; width: 72px; margin: -12px 0 24px; border-radius: 9999px; }
.v-shot__bar-a, .v-shot__bar-b { position: absolute; inset: 0; border-radius: inherit; }
.v-shot__bar-a { background: #dadce0; opacity: 0; }
.v-shot__bar-b { background: var(--v-muted); opacity: 1; } /* Ops gate 00:2x UK: blue is CTA only; the illustration bar is the neutral brand token */
.v-shot__field { border: 1px solid #747775; border-radius: 6px; height: 54px; padding: 0 14px; display: flex; align-items: center; color: #5f6368; font-size: 16px; }
.v-shot__next { margin: 28px 0 0 auto; width: max-content; padding: 0 22px; line-height: 40px; border-radius: 9999px; background: #e8eaed; color: #3c4043; font-size: 14px; font-weight: 600; }
.v-visual figcaption { margin-top: 20px; text-align: center; }
.v-visual figcaption a { display: inline-block; padding: 6px 0; } /* 44px tap height on the proof link */
/* fix1 design (CEO 23:3x UK, panel item 6): blue is for the CTA only. The lab-proof note and the caption are muted notes; their
   repo link is underlined in the note colour. Step numbers, icons, ticks and +/- are neutral. Styling only, words unchanged. */
.v-proof { font-size: 12px; line-height: 1.45; color: var(--v-muted); }
.v-proof a, .v-visual figcaption a { color: inherit; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 2px; }
.v-proof a:hover, .v-visual figcaption a:hover { color: var(--v-ink); opacity: 1; }
.t--dark .v-proof a { color: inherit; }
/* Release 1 (sell the outcome, order fix 3): the separate proof link under the caption / lab line: small, muted, never blue. */
.v-proof-more { display: block; margin-top: 4px; }
a.v-proof-link, .t--dark a.v-proof-link { font-size: 12px; color: var(--v-muted); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 2px; }
a.v-proof-link:hover, .t--dark a.v-proof-link:hover { color: var(--v-ink); opacity: 1; }
.t--dark a.v-proof-link:hover { color: var(--v-tile-ink); }
a.v-proof-link { display: inline-block; padding-block: 4px; } /* 24px touch target (Ops gate 25 Oct) */
@media (prefers-reduced-motion: no-preference) {
  .js .v-shot__a, .js .v-shot__bar-a { animation: v-out 800ms ease-in-out 1.6s both; }
  .js .v-shot__b, .js .v-shot__bar-b { animation: v-in 800ms ease-in-out 1.6s both; }
}
@keyframes v-out { from { opacity: 1; } to { opacity: 0; } }
@keyframes v-in { from { opacity: 0; } to { opacity: 1; } }

/* lists: icon rows, steps, hairline lists */
.v-three { list-style: none; margin: 40px 0 0; padding: 0; display: grid; gap: 32px; grid-template-columns: repeat(3, 1fr); }
.v-three li { font-size: 19px; line-height: 1.35; }
.v-three svg { width: 32px; height: 32px; color: var(--v-muted); margin-bottom: 12px; }
.v-steps { list-style: none; margin: 40px 0 0; padding: 0; display: grid; gap: 32px; grid-template-columns: repeat(3, 1fr); counter-reset: s; }
.v-steps li { counter-increment: s; font-size: 19px; line-height: 1.35; }
.v-steps li::before { content: counter(s); display: block; font-size: 40px; font-weight: 600; line-height: 1; color: var(--v-muted); margin-bottom: 12px; }
@media (max-width: 734px) { .v-three, .v-steps { grid-template-columns: 1fr; gap: 24px; } }
.v-ticks { list-style: none; margin: 20px 0; padding: 0; display: grid; gap: 12px; }
.v-ticks li { display: grid; grid-template-columns: 24px 1fr; gap: 10px; align-items: start; }
.v-ticks li::before { content: ""; width: 14px; height: 8px; margin-top: 6px; border: 2px solid currentColor; border-top: 0; border-right: 0; transform: rotate(-45deg); }
.v-list { list-style: none; margin: 24px 0 0; padding: 0; border-top: 1px solid var(--v-hair); }
.v-list > li { padding: 20px 0; border-bottom: 1px solid var(--v-hair); }
.v-list h3 { font-size: 19px; line-height: 1.3; margin: 0 0 6px; }
.v-list p { margin: 0 0 6px; }
.v-saw { font-family: var(--v-mono); font-size: 13px; line-height: 1.5; color: var(--v-muted); }
/* FIX 1 (Elon ANSWERS-signhome-fixv2-7, CEO ruling (b)): a hostname never wraps. .v-fit sizes Geist Mono (every glyph 0.6em) to its
   container: --n = the longest token in characters (.5px per glyph spare: Chromium on Linux rounds each advance to the nearest whole pixel), so the whole token fits on one line between --fmin and --fmax. Only when
   even --fmin can't fit, the one <wbr> in a .v-tok ('<project>.' | 'firebaseapp.com') wraps, sized so the longer piece fits
   (--m); a piece that still can't fit at --fmin shrinks rather than overflow. No ellipsis, no sideways scroll. */
.v-hostbox, .v-fitbox, .v-saw { container-type: inline-size; }
.v-fit { --fit-n: calc((100cqi / var(--n, 1) - .5px) / .6); --fit-m: calc((100cqi / var(--m, 1) - .5px) / .6);
  --at-min: calc(clamp(0px, (100cqi / (var(--m, 1) * .6) - 12px) * 100000, 1px) * 12); /* 12px when the longest piece fits at 12px (0.6em/glyph; at 12px Chromium rounds 7.2 down to 7) */
  font-size: max(min(var(--fmax, 1em), var(--fit-n)), min(var(--fmin, 12px), var(--fit-m)), var(--at-min)); font-family: var(--v-mono); letter-spacing: 0; hyphens: none; overflow-wrap: normal; }
.v-fit > span { white-space: nowrap; }
.v-fit .v-tok, .v-hostname .v-tok { display: inline-block; max-width: 100%; white-space: normal; vertical-align: top; } /* nested: break order (src/pages.js tokenHtml) */
.v-hosts .v-tok { display: inline-block; max-width: 100%; white-space: normal; } .v-hosts span:not(.v-tok) { white-space: nowrap; } /* hosts in prose (lab line) */
.v-tok > span:not(.v-tok) { white-space: nowrap; }
code.v-fit { --fmax: .88em; --fmin: 12px; } /* URL lines (00:5x UK): /unlock 'For' 15px, never below 12px; then path / (b) breaks */
.v-fine code.v-fit { --fmax: 12px; } /* /r 'Result for' 12px */
/* Elon fixv2-8: the result hostname line. Geist 600 in neutral ink, kerning off so its width = --w em (per-glyph advances from
   the font, src/pages.js GEIST_600; pixel rounding adds <= .5px per glyph, so ~90% never overflows). One line at ~90% of the line, 18-40px; only
   when 18px can't hold the whole host, the (b) split, sized so the longer piece fits. Never an ellipsis, never sideways scroll. */
.v-hostbox { margin: 0 0 12px; }
.v-hostname { margin: 0; width: fit-content; max-width: 100%; font-family: var(--v-sans); font-weight: 600; font-kerning: none; letter-spacing: 0;
  line-height: 1.15; color: var(--v-ink); hyphens: none; overflow-wrap: normal;
  white-space: nowrap; font-size: max(min(40px, 100cqi * .9 / var(--w, 1)), min(18px, (100cqi - var(--n, 1) * .5px) * .98 / var(--wm, 1))); }
.v-hostname > span:not(.v-tok) { white-space: nowrap; }
.v-sum__txt { flex: 1; min-width: 0; }
.v-price { font-size: 40px; font-weight: 600; line-height: 1.1; letter-spacing: -0.02em; margin: 4px 0 0; }

/* FAQ: hairline list with +/- */
.v-faq { border-top: 1px solid var(--v-hair); margin-top: 32px; }
.v-faq details { border-bottom: 1px solid var(--v-hair); }
.v-faq summary { list-style: none; cursor: pointer; display: flex; justify-content: space-between; gap: 16px; align-items: center; min-height: 56px; padding: 12px 0; font-weight: 600; }
.v-faq summary::-webkit-details-marker { display: none; }
.v-faq summary::after { content: "+"; font-weight: 400; font-size: 24px; line-height: 1; color: var(--v-muted); }
.v-faq details[open] summary::after { content: "\2212"; }
.v-faq details p { margin: 0 0 20px; color: var(--v-muted); }

/* result ring: the only place grade colours appear */
.v-sum { display: flex; gap: 32px; align-items: center; }
.v-ring { flex: none; width: 120px; height: 120px; position: relative; }
.v-ring svg { width: 120px; height: 120px; transform: rotate(-90deg); }
.v-ring circle { fill: none; stroke-width: 8; }
.v-ring .bg { stroke: var(--v-hair); }
.v-ring .fg { stroke: var(--v-unk); stroke-linecap: round; }
.v-ring--ok .fg { stroke: var(--v-ok); } .v-ring--warn .fg { stroke: var(--v-warn); } .v-ring--bad .fg { stroke: var(--v-bad); }
.v-ring b { position: absolute; inset: 0; display: grid; place-items: center; font-size: 44px; font-weight: 600; }
.v-sum h1 { font-size: var(--v-h1); line-height: 1.15; letter-spacing: -0.02em; margin: 0 0 8px; }
.v-sum { --v-gut: 200px; } /* 48px gutters + the 120px ring + 32px gap beside the H1 */
@media (max-width: 640px) { .v-sum { flex-direction: column; align-items: flex-start; gap: 20px; --v-gut: 48px; } .v-sum__txt { align-self: stretch; } }
.v-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.v-chip { min-height: 44px; padding: 0 20px; border-radius: 9999px; border: 1px solid var(--v-hair); background: var(--v-canvas); color: var(--v-ink); font: 400 15px/1 var(--v-sans); cursor: pointer; transition: transform 120ms ease-out; }
.v-chip { display: inline-flex; align-items: center; }
.v-chip:active { transform: scale(.97); }
.v-more { display: inline-block; }
.v-more[open] { flex-basis: 100%; }
.v-more > summary { list-style: none; }
.v-more > summary::-webkit-details-marker { display: none; }
.v-more > summary::after { content: "+"; margin-left: 8px; color: var(--v-muted); }
.v-more[open] > summary::after { content: "\2212"; }
.v-more[open] > summary { border-color: var(--v-accent); }
.v-more > .v-chips { margin-top: 8px; }
.v-list--num { counter-reset: n; }
.v-list--num > li { counter-increment: n; display: grid; grid-template-columns: 28px 1fr; }
.v-list--num > li::before { content: counter(n) "."; color: var(--v-muted); }
.v-row { display: flex; flex-wrap: wrap; gap: 16px 24px; align-items: center; }
.v-alert { border-left: 3px solid var(--v-accent); padding-left: 12px; font-weight: 600; }

/* fade-up once on entering view */
.js .v-up { opacity: 0; transform: translateY(12px); transition: opacity 400ms ease-out, transform 400ms ease-out; }
.js .v-up.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js .v-up { opacity: 1; transform: none; transition: none; }
  .v-btn, .v-chip { transition: none; } .v-btn:active, .v-chip:active { transform: none; }
}

/* Body-size notes (17px) for the reading lines on the offer cards; .v-fine stays for legal/fine print only. */
.v-note { font-size: 17px; line-height: 1.47; color: var(--v-muted); }
/* Dark mode: the drawing sits on the dark tile colour, never a white block (same single shadow in both modes). */
@media (prefers-color-scheme: dark) {
  .v-shot { background: #2c2c2e; color: #f5f5f7; }
  .v-shot__h { color: #f5f5f7; }
  .v-shot__to { color: #d1d1d6; }
  .v-shot__field { border-color: #8e8e93; color: #c7c7cc; }
  .v-shot__next { background: #3a3a3c; color: #f5f5f7; }
  .v-shot__bar-a { background: #48484a; }
}
