/* Bidwright landing page. Tokens lifted from web/lib/tokens.ts and the prototype.
   Spacing sits on an 8-point grid (4 and 12 allowed for tight inner spacing).
   Motion rule: only transform and opacity animate on scroll, so nothing lays out or repaints per frame. */

:root {
  --ink: #0e0a0a;
  --ink2: #241f1e;
  --ink3: #322d2b;
  --soft: #57514f;
  --muted: #746d6a;
  --faint: #a9a19e;
  --grey: #9c9491;
  --grey-warm: #c0b8b5;
  --paper: #fcfaf7;
  --card: #fffdfb;
  --sand: #f2ece7;
  --rule: #d4cecb;
  --rule-soft: #ebe5e1;
  --dash: #c6bebb;
  --wine: #661420;
  --wine-hover: #982a3b;
  --rose: #a8626f;
  --salmon: #dd7a7c;
  --pink: #c4707e;
  --blush: #d3b6bb;
  --pink-bg: #fbf3f4;
  --pink-rule: #e3ccd0;
  --sage: #225a32;
  --sage-bg: #edf3ee;
  --mint-bg: #f2f7f3;
  --mint-rule: #cfe0d4;
  --amber-bg: #f8eef0;
  --red: #c92f33;
  --red-bg: #fbeeee;

  --serif: 'Playfair Display', Georgia, 'Times New Roman', serif;
  --sans: 'Avenir Next', 'Figtree', 'Segoe UI', system-ui, -apple-system, sans-serif;
  --mono: 'SF Mono', ui-monospace, Menlo, Consolas, monospace;

  --container: 1200px;
  --header-h: 72px;
  --gutter: 24px;
  --radius: 9px;
  --radius-sm: 7px;
  --radius-xs: 5px;
  --ease: cubic-bezier(.22, .61, .36, 1);
  --ease-out: cubic-bezier(.16, 1, .3, 1);
  --ease-spring: cubic-bezier(.34, 1.3, .64, 1);
  --shadow-frame: 0 1px 2px rgba(14, 10, 10, .06), 0 12px 32px rgba(14, 10, 10, .1);
  --shadow-frame-dark: 0 1px 2px rgba(0, 0, 0, .3), 0 24px 60px rgba(0, 0, 0, .5);
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}

a { color: var(--wine); text-decoration: none; transition: color .18s var(--ease); }
a:hover { color: var(--wine-hover); }
img { display: block; max-width: 100%; height: auto; }
button, input { font: inherit; color: inherit; }
h1, h2, h3, h4, p, ul, figure { margin: 0; }
ul { padding: 0; list-style: none; }
:focus-visible { outline: 2px solid var(--wine); outline-offset: 3px; border-radius: 4px; }
::selection { background: var(--blush); color: var(--ink); }

.container { width: 100%; max-width: var(--container); margin-left: auto; margin-right: auto; padding-left: var(--gutter); padding-right: var(--gutter); }
@media (min-width: 768px) { :root { --gutter: 40px; } }
@media (min-width: 1600px) { :root { --container: 1456px; } }

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

/* Type */
.eyebrow { font-family: var(--mono); font-size: 11px; font-weight: 500; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.eyebrow.wine { color: var(--wine); }
.eyebrow.light { color: var(--blush); }
.display { font-family: var(--serif); font-weight: 500; letter-spacing: -.02em; line-height: 1.1; text-wrap: balance; }
.h1 { font-size: clamp(34px, 4vw, 52px); line-height: 1.06; }
.h2 { font-size: clamp(28px, 4vw, 44px); line-height: 1.12; }
.h3 { font-size: clamp(22px, 2.6vw, 30px); line-height: 1.2; }
.lede { font-size: clamp(17px, 1.4vw, 19px); line-height: 1.55; color: var(--soft); text-wrap: pretty; max-width: 56ch; }
.body { font-size: 16px; line-height: 1.55; color: var(--soft); text-wrap: pretty; }
.small { font-size: 14px; line-height: 1.5; color: var(--muted); }
.mono { font-family: var(--mono); font-size: 12px; color: var(--muted); }

/* Buttons */
.btn { position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 48px; padding: 12px 24px; border-radius: var(--radius-sm); border: 1px solid transparent; font-size: 15px; font-weight: 500; white-space: nowrap; cursor: pointer; text-decoration: none; transition: background .2s var(--ease), border-color .2s var(--ease), color .2s var(--ease), transform .25s var(--ease-out), box-shadow .25s var(--ease-out); -webkit-tap-highlight-color: transparent; }
.btn-primary { background: var(--ink); color: var(--paper); box-shadow: 0 1px 2px rgba(14, 10, 10, .2); }
.btn-primary:hover { background: var(--ink3); color: var(--paper); transform: translateY(-1px); box-shadow: 0 6px 16px rgba(14, 10, 10, .18); }
.btn-primary:active { transform: translateY(0) scale(.985); box-shadow: 0 1px 2px rgba(14, 10, 10, .2); transition-duration: .08s; }
.btn-primary:disabled { background: #efeae1; color: var(--grey); cursor: not-allowed; transform: none; box-shadow: none; }
.btn-ghost { background: var(--card); color: var(--ink3); border-color: var(--rule); }
.btn-ghost:hover { border-color: var(--ink); color: var(--ink); transform: translateY(-1px); }
.btn-ghost:active { transform: translateY(0) scale(.985); transition-duration: .08s; }
.btn-sm { min-height: 44px; padding: 8px 16px; font-size: 14px; border-radius: 6px; }
.btn svg { width: 16px; height: 16px; flex: none; }

/* Header */
.site-header { position: sticky; top: 0; z-index: 40; background: rgba(252, 250, 247, .82); backdrop-filter: saturate(140%) blur(12px); -webkit-backdrop-filter: saturate(140%) blur(12px); border-bottom: 1px solid transparent; transition: border-color .3s var(--ease); }
.site-header.scrolled { border-bottom-color: var(--rule-soft); }
.site-header .container { display: flex; align-items: center; justify-content: space-between; gap: 24px; height: 72px; transition: height .3s var(--ease); }
.site-header.scrolled .container { height: 64px; }
.wordmark { font-family: var(--serif); font-size: 28px; font-weight: 500; letter-spacing: -.015em; line-height: 1; color: var(--ink); }
.wordmark span { color: var(--pink); }
.wordmark:hover { color: var(--ink); }
.site-nav { display: none; gap: 4px; }
.site-nav a { position: relative; padding: 8px 12px; border-radius: 6px; font-size: 14.5px; font-weight: 500; color: var(--soft); transition: color .2s var(--ease), background .2s var(--ease); }
.site-nav a:hover { color: var(--ink); background: var(--sand); }
@media (min-width: 900px) { .site-nav { display: flex; } }
.header-cta { display: none; }
@media (min-width: 640px) { .header-cta { display: inline-flex; } }

/* Section scaffolding */
.section { padding-top: 72px; padding-bottom: 72px; }
@media (min-width: 900px) { .section { padding-top: 120px; padding-bottom: 120px; } }
.section-head { display: grid; gap: 16px; max-width: 720px; margin-bottom: 40px; }
@media (min-width: 900px) { .section-head { margin-bottom: 64px; } }

/* Reveal on scroll */
.reveal { opacity: 0; transform: translateY(20px); transition: opacity .9s var(--ease-out), transform .9s var(--ease-out); will-change: opacity, transform; }
.reveal.in { opacity: 1; transform: none; will-change: auto; }
.reveal[data-delay="1"] { transition-delay: .1s; }
.reveal[data-delay="2"] { transition-delay: .2s; }
.reveal[data-delay="3"] { transition-delay: .3s; }
@media (prefers-reduced-motion: reduce) { .reveal { opacity: 1; transform: none; transition: none; } }

/* Framed screenshots: the app's own margin is inside the crop, the frame adds the hairline and the shadow. */
.shot { position: relative; margin: 0; }
.frame { position: relative; overflow: hidden; border-radius: var(--radius); border: 1px solid var(--rule); background: var(--paper); box-shadow: var(--shadow-frame); }
.frame img { width: 100%; }
.frame-fade::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 64px; background: linear-gradient(to bottom, rgba(252, 250, 247, 0), rgba(252, 250, 247, .92)); pointer-events: none; }
.on-dark .frame, .frame.on-dark { border-color: rgba(255, 255, 255, .16); box-shadow: var(--shadow-frame-dark); }
.shot-caption { font-size: 14px; line-height: 1.5; color: var(--muted); }

/* ------------------------------------------------------------------ */
/* Hero and the scroll stage                                            */
/* ------------------------------------------------------------------ */
.hero { position: relative; background: var(--paper); }
.hero-sticky { position: relative; }
.hero-grid { display: grid; grid-template-columns: 1fr; gap: 40px; padding-top: 40px; padding-bottom: 48px; }
.hero-copy { display: grid; gap: 16px; max-width: 560px; }
.hero-copy .lede { margin-top: 8px; font-size: 17px; line-height: 1.55; max-width: 52ch; }
.hero-copy .waitlist { margin-top: 16px; }
.hero-copy .hero-proof { margin-top: 8px; }
/* 24ch, not 18: at 18 the headline could not fit 'Your next government bid'
   on its first line whatever the wrapping said. */
.hero-copy .h1 { max-width: 24ch; }
/* The accent is the one phrase on the page carrying color, and text-wrap
   balance will split it across two lines to even up the rag. Holding it
   together gives balance one fewer place to break and it picks a better set
   of lines anyway. Released under 360px, where the phrase is wider than the
   column and nowrap would push the page sideways. */
@media (min-width: 360px) { .hero-copy .h1 .accent { white-space: nowrap; } }
/* The turn: the same measure as the lede above it, a step down in weight of
   voice, because it is the second half of one thought rather than a new one. */
.hero-copy .hero-turn { margin-top: 0; font-size: 16px; color: var(--muted); }
.hero-who { font-size: 14px; line-height: 1.5; color: var(--muted); }
.hero-proof { display: grid; gap: 8px; }
.hero-proof li { display: flex; align-items: flex-start; gap: 12px; font-size: 14px; color: var(--soft); }
.hero-proof svg, .check-list svg { width: 16px; height: 16px; flex: none; margin-top: 2px; fill: none; stroke: var(--sage); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* Device: a CSS laptop. The bezel is an overlay, so the morph to a bare card is an opacity change and nothing else. */
.device-pos { position: relative; }
.device { position: relative; transform-origin: 50% 50%; }
.device-screen { position: relative; aspect-ratio: 16 / 10; overflow: hidden; background: var(--ink); border-radius: 14px; box-shadow: 0 1px 2px rgba(14, 10, 10, .2), 0 30px 80px rgba(14, 10, 10, .18); transform: translateZ(0); }
.screen-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top left; opacity: 0; }
.screen-img[data-screen="0"] { opacity: 1; }
.device-bezel { position: absolute; inset: 0; border: 10px solid var(--ink); border-radius: 14px; pointer-events: none; }
.device-hairline { position: absolute; inset: 0; border: 1px solid var(--rule); border-radius: 14px; opacity: 0; pointer-events: none; }
.device-base { height: 14px; margin: 0 -4%; background: linear-gradient(#3a3331, #241f1e); border-radius: 0 0 14px 14px; box-shadow: 0 8px 24px rgba(14, 10, 10, .2); transform-origin: 50% 0; }
.device-base::after { content: ''; display: block; width: 18%; height: 4px; margin: 0 auto; background: #5a504d; border-radius: 0 0 4px 4px; }
.stage-captions { display: none; }

@media (min-width: 1024px) {
  .hero { height: 320vh; }
  /* The stage sits under the header rather than behind it. It used to be 100vh starting below a
     72px header, so at the top of the page the composition was centered on a point 36px below the
     middle of the screen and the eyebrow started 410px down a tall one. Height and top now agree,
     so the stage is exactly the space a person can see and the pin is unchanged. */
  .hero-sticky { position: sticky; top: var(--header-h); height: calc(100vh - var(--header-h)); padding-bottom: 64px; overflow: hidden; display: flex; align-items: center; }
  /* 7/5 rather than half and half: the device is absolutely positioned over the whole grid, so the
     split only decides how wide the copy may run. The left edge stays on the container, which is
     what keeps the eyebrow aligned with the wordmark above it. */
  .hero-grid { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); align-items: center; gap: 48px; padding-top: 0; padding-bottom: 0; width: 100%; }
  .hero-copy { will-change: opacity, transform; }
  .device-pos { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; pointer-events: none; }
  .hero-grid { position: relative; }
  .hero-copy { max-width: 540px; }
  .device { width: min(1040px, 74vw); transform: translate(34%, 6%) scale(.6) rotate(.4deg); will-change: transform; }
  .device-bezel { border-width: 12px; }
  .stage-captions { display: block; position: absolute; left: var(--gutter); bottom: 48px; width: 360px; }
  .stage-caption { position: absolute; left: 0; bottom: 0; width: 100%; display: grid; gap: 8px; opacity: 0; transform: translateY(16px); padding: 16px 24px; background: var(--ink); color: var(--paper); border-radius: var(--radius); box-shadow: 0 16px 40px rgba(14, 10, 10, .22); will-change: opacity, transform; }
  .stage-caption-title { font-family: var(--serif); font-size: 20px; line-height: 1.3; letter-spacing: -.01em; }
}
/* A short desktop is the tightest fit on the page: the stage is only as tall as
   the window minus the header, and the copy block runs a headline, two
   paragraphs, a line of who it is for, the form and three proof lines. Under
   900px of height the whole block steps down rather than the last line sliding
   under the scroll cue. */
@media (min-width: 1024px) and (max-height: 899px) {
  .hero-copy { gap: 12px; }
  .hero-copy .h1 { font-size: 40px; }
  .hero-copy .lede { margin-top: 0; font-size: 16px; }
  .hero-copy .hero-turn { font-size: 15px; }
  .hero-copy .waitlist { margin-top: 8px; }
  .hero-copy .hero-proof { margin-top: 0; }
  .hero-proof { gap: 8px; }
  .hero-proof li { font-size: 13px; }
}

/* The hero is a scroll stage, and the room under it is where that gets said. The cue is desktop
   only because the stage is, it goes on the first pixel of scroll, and it stays hidden under
   reduced motion, where nothing plays and the line would be a promise the page does not keep. */
.hero-cue { display: none; }
@media (min-width: 1024px) {
  .hero-cue { display: grid; justify-items: center; gap: 8px; position: absolute; left: 0; right: 0; bottom: 24px; font-family: var(--mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--faint); transition: opacity .4s var(--ease); }
  .hero-cue-line { width: 1px; height: 40px; background: linear-gradient(var(--rule), rgba(0, 0, 0, 0)); transform-origin: 50% 0; animation: cuedrop 2.4s var(--ease) infinite; }
  @keyframes cuedrop { 0%, 100% { transform: scaleY(.4); opacity: .5; } 50% { transform: scaleY(1); opacity: 1; } }
  .site-header.scrolled ~ main .hero-cue { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .hero-cue { display: none; } }
/* A tall screen was given the same 554px composition as a laptop, so it floated with 400px of air
   over it. The block grows into the room instead: larger headline, looser rhythm, a bigger machine.
   The stage keeps its full height, so nothing about the scroll timeline changes. */
@media (min-width: 1024px) and (min-height: 900px) {
  .hero-copy { gap: 16px; }
  .hero-copy .h1 { font-size: 44px; }
  .hero-copy .lede { margin-top: 0; font-size: 18px; }
  .hero-copy .hero-turn { font-size: 16px; }
  .hero-copy .waitlist { margin-top: 8px; }
  .hero-copy .hero-proof { margin-top: 0; }
  .hero-who { font-size: 15px; }
  .hero-proof { gap: 8px; }
  .hero-proof li { font-size: 14px; }
  .device { width: min(1240px, 74vw); }
}

/* A screen this size is not a laptop with more paper around it. Above 1080px of height the
   composition is re-cut rather than re-centered: a 72px headline in a column half as wide again,
   spacing up one step of the grid, and a machine that can grow because the container did. */
@media (min-width: 1600px) {
  .hero-copy { max-width: 680px; }
}
@media (min-width: 1600px) and (min-height: 1080px) {
  .hero-copy { gap: 24px; }
  .hero-copy .h1 { font-size: 56px; }
  .hero-copy .lede { font-size: 20px; }
  .hero-copy .hero-turn { font-size: 18px; }
  .hero-copy .waitlist { margin-top: 0; }
  .hero-copy .eyebrow { font-size: 13px; }
  .hero-copy .wl-input, .hero-copy .waitlist .btn { min-height: 56px; }
  .hero-who { font-size: 16px; }
  .hero-proof { gap: 8px; }
  .hero-proof li { font-size: 15px; }
  .device { width: min(1440px, 74vw); }
}

/* ------------------------------------------------------------------ */
/* Waitlist form                                                        */
/* ------------------------------------------------------------------ */
.waitlist { display: grid; gap: 16px; }
.wl-step { display: grid; gap: 12px; }
.wl-step.is-entering { animation: stepin .45s var(--ease-out) both; }
@keyframes stepin { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.wl-row { display: flex; flex-direction: column; gap: 8px; }
@media (min-width: 560px) { .wl-row { flex-direction: row; } .wl-row .wl-input { flex: 1; min-width: 0; } }
.wl-input { width: 100%; min-height: 48px; padding: 12px 16px; border: 1px solid var(--rule); border-radius: var(--radius-sm); background: var(--card); font-size: 16px; color: var(--ink); transition: border-color .2s var(--ease), box-shadow .25s var(--ease-out); }
.wl-input::placeholder { color: var(--faint); }
.wl-input:hover { border-color: var(--grey-warm); }
.wl-input:focus { outline: none; border-color: var(--ink); box-shadow: 0 0 0 4px rgba(14, 10, 10, .08); }
.wl-micro { font-size: 13px; color: var(--muted); }
.wl-label { display: block; font-size: 14px; font-weight: 500; color: var(--ink3); }
.wl-label.light { color: var(--grey-warm); }
.wl-position { font-family: var(--serif); font-size: 24px; letter-spacing: -.01em; }
.wl-step-title { font-size: 15px; color: var(--soft); }
.wl-fieldset { margin: 0; padding: 0; border: 0; display: grid; gap: 8px; }
.wl-fieldset legend { padding: 0; margin-bottom: 8px; }
.wl-choices { display: flex; flex-wrap: wrap; gap: 8px; }
.wl-choice { position: relative; }
.wl-choice input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.wl-choice span { display: inline-flex; align-items: center; min-height: 40px; padding: 8px 16px; border: 1px solid var(--rule); border-radius: var(--radius-sm); background: var(--card); font-size: 14px; font-weight: 500; color: var(--ink3); cursor: pointer; transition: border-color .2s var(--ease), background .2s var(--ease), color .2s var(--ease), transform .2s var(--ease-out); }
.wl-choice span:hover { border-color: var(--ink); }
.wl-choice span:active { transform: scale(.97); }
.wl-choice input:checked + span { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.wl-choice input:focus-visible + span { box-shadow: 0 0 0 3px rgba(14, 10, 10, .16); }
.wl-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.wl-status { font-size: 14px; padding: 12px 16px; border-radius: var(--radius-sm); background: var(--sand); color: var(--ink3); animation: stepin .35s var(--ease-out) both; }
.wl-status[data-kind="error"] { background: var(--red-bg); color: var(--red); }
.wl-status[data-kind="warn"] { background: var(--amber-bg); color: var(--wine); }
.wl-done-title { font-size: clamp(22px, 2.4vw, 28px); }
.wl-referral { display: grid; gap: 8px; }

/* dark variant, used in the final call to action */
.waitlist-dark .wl-input { background: rgba(255, 255, 255, .06); border-color: rgba(255, 255, 255, .18); color: var(--paper); }
.waitlist-dark .wl-input::placeholder { color: rgba(252, 250, 247, .45); }
.waitlist-dark .wl-input:hover { border-color: rgba(255, 255, 255, .34); }
.waitlist-dark .wl-input:focus { border-color: var(--paper); box-shadow: 0 0 0 4px rgba(255, 255, 255, .12); }
.waitlist-dark .wl-micro, .waitlist-dark .wl-step-title { color: var(--grey-warm); }
.waitlist-dark .wl-position, .waitlist-dark .wl-done-title { color: var(--paper); }
.waitlist-dark .wl-choice span { background: transparent; border-color: rgba(255, 255, 255, .22); color: var(--grey-warm); }
.waitlist-dark .wl-choice span:hover { border-color: var(--paper); color: var(--paper); }
.waitlist-dark .wl-choice input:checked + span { background: var(--paper); border-color: var(--paper); color: var(--ink); }
.waitlist-dark .wl-status { background: rgba(255, 255, 255, .08); color: var(--paper); }
.waitlist-dark .wl-status[data-kind="error"] { background: rgba(201, 47, 51, .25); color: #ffd7d8; }
.waitlist-dark .wl-status[data-kind="warn"] { background: rgba(255, 255, 255, .1); color: #f1d9dd; }
.btn-light { background: var(--paper); color: var(--ink); box-shadow: none; }
.btn-light:hover { background: #fff; color: var(--ink); box-shadow: 0 6px 16px rgba(0, 0, 0, .3); }
.btn-ghost-dark { background: transparent; color: var(--paper); border-color: rgba(255, 255, 255, .28); }
.btn-ghost-dark:hover { border-color: var(--paper); color: var(--paper); }

/* ------------------------------------------------------------------ */
/* Problem band                                                         */
/* ------------------------------------------------------------------ */
.problem { background: var(--ink); color: var(--paper); }
.problem-grid { display: grid; gap: 40px; }
.problem-lead { display: grid; gap: 24px; max-width: 640px; }
.problem-lead .h2 { color: var(--paper); }
.problem-lede { font-size: 17px; line-height: 1.55; color: var(--grey-warm); text-wrap: pretty; }
.problem-list { display: grid; gap: 0; border-top: 1px solid rgba(255, 255, 255, .14); }
.problem-list li { display: grid; gap: 8px; padding: 24px 0; border-bottom: 1px solid rgba(255, 255, 255, .14); }
.problem-item-title { font-size: 18px; font-weight: 600; letter-spacing: -.01em; color: var(--paper); }
.problem-item-body { font-size: 15px; line-height: 1.5; color: var(--grey-warm); }
@media (min-width: 900px) {
  .problem-grid { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: 80px; align-items: start; }
  .problem-list { grid-template-columns: 1fr 1fr; gap: 0 40px; border-top: 0; }
  .problem-list li { border-top: 1px solid rgba(255, 255, 255, .14); border-bottom: 0; }
}

/* ------------------------------------------------------------------ */
/* Flow                                                                 */
/* ------------------------------------------------------------------ */
.flow { border-bottom: 1px solid var(--rule); }
.flow-grid { display: grid; gap: 40px; }
.flow-copy { display: grid; gap: 24px; max-width: 560px; }
.flow-notes { display: grid; gap: 12px; padding-top: 8px; border-top: 1px solid var(--rule); }
.flow-notes li { font-size: 15px; line-height: 1.5; color: var(--soft); padding-top: 12px; }
.flow-notes strong { color: var(--ink); font-weight: 600; }
.arrow-link { display: inline-flex; align-items: center; gap: 8px; font-size: 15px; font-weight: 500; }
.arrow-link svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; transition: transform .3s var(--ease-out); }
.arrow-link:hover svg { transform: translateX(4px); }
.flow-visual { display: flex; align-items: center; justify-content: flex-start; }
.flow-svg { width: 100%; height: auto; --cycle: 10.4s; }
.flow-wide { display: none; }
.flow-tall { display: block; max-width: 240px; }
@media (min-width: 720px) { .flow-wide { display: block; } .flow-tall { display: none; } .flow-visual { justify-content: center; } }
@media (min-width: 1024px) { .flow-grid { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 80px; align-items: center; } }

.flow-box { fill: none; stroke: rgba(14, 10, 10, .4); stroke-width: 1.2; stroke-dasharray: 5 6; stroke-linecap: round; vector-effect: non-scaling-stroke; }
.flow-box.you { stroke: var(--wine); stroke-dasharray: none; stroke-width: 1.4; fill: var(--pink-bg); }
.flow-box-label { font-family: var(--mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; fill: var(--muted); }
.flow-box-label.you { fill: var(--wine); }
/* Tall layout: the vertical connector passes behind the box labels, so the label carries a halo in its box color. */
.flow-tall .flow-box-label { paint-order: stroke fill; stroke: var(--paper); stroke-width: 6px; stroke-linejoin: round; }
.flow-tall .flow-box-label.you { stroke: var(--pink-bg); }
.conn .base { fill: none; stroke: rgba(14, 10, 10, .16); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.conn .prog { fill: none; stroke: var(--ink); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.conn .clip { transform-box: fill-box; transform-origin: left center; transform: scaleX(0); animation: var(--cycle) cubic-bezier(.2, 0, 0, 1) infinite; }
.conn .clip.vclip { transform-origin: center top; }
.c1 .clip { animation-name: wipe1; } .c2 .clip { animation-name: wipe2; } .c3 .clip { animation-name: wipe3; }
.c4 .clip { animation-name: wipe4; } .c5 .clip { animation-name: wipe5; } .c6 .clip { animation-name: wipe6; }
.c1 .clip.vclip { animation-name: vwipe1; } .c2 .clip.vclip { animation-name: vwipe2; } .c3 .clip.vclip { animation-name: vwipe3; }
.c4 .clip.vclip { animation-name: vwipe4; } .c5 .clip.vclip { animation-name: vwipe5; } .c6 .clip.vclip { animation-name: vwipe6; }
.conn .paint { animation: paintfade var(--cycle) linear infinite; }
/* Nodes never move. The active one gains a ring and a darker stroke, which is what keeps the row aligned. */
.node .tile { fill: var(--card); stroke: rgba(14, 10, 10, .22); stroke-width: 1; animation: tileon var(--cycle) cubic-bezier(.2, 0, 0, 1) infinite var(--d); }
.node .ring { fill: none; stroke: var(--ink); stroke-width: 1; opacity: 0; transform-box: fill-box; transform-origin: center; animation: ringon var(--cycle) cubic-bezier(.2, 0, 0, 1) infinite var(--d); }
.node .icon { fill: none; stroke: var(--ink); stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.node.you .tile { stroke: var(--wine); stroke-width: 1.2; animation-name: tileon-you; }
.node.you .ring { stroke: var(--wine); }
.node.you .icon { stroke: var(--wine); }
.flow-label { fill: var(--ink); opacity: .45; font-family: var(--sans); font-size: 14px; font-weight: 500; text-anchor: middle; animation: labelpop var(--cycle) cubic-bezier(.2, 0, 0, 1) infinite var(--d); }
.flow-label.side { text-anchor: start; }
/* Six wipes, each 9% of the cycle, starting 12.5% apart; everything fades together at the end. */
@keyframes wipe1 { 0%, 5% { transform: scaleX(0); } 14%, 92% { transform: scaleX(1); } 92.01%, 100% { transform: scaleX(0); } }
@keyframes wipe2 { 0%, 17.5% { transform: scaleX(0); } 26.5%, 92% { transform: scaleX(1); } 92.01%, 100% { transform: scaleX(0); } }
@keyframes wipe3 { 0%, 30% { transform: scaleX(0); } 39%, 92% { transform: scaleX(1); } 92.01%, 100% { transform: scaleX(0); } }
@keyframes wipe4 { 0%, 42.5% { transform: scaleX(0); } 51.5%, 92% { transform: scaleX(1); } 92.01%, 100% { transform: scaleX(0); } }
@keyframes wipe5 { 0%, 55% { transform: scaleX(0); } 64%, 92% { transform: scaleX(1); } 92.01%, 100% { transform: scaleX(0); } }
@keyframes wipe6 { 0%, 67.5% { transform: scaleX(0); } 76.5%, 92% { transform: scaleX(1); } 92.01%, 100% { transform: scaleX(0); } }
@keyframes vwipe1 { 0%, 5% { transform: scaleY(0); } 14%, 92% { transform: scaleY(1); } 92.01%, 100% { transform: scaleY(0); } }
@keyframes vwipe2 { 0%, 17.5% { transform: scaleY(0); } 26.5%, 92% { transform: scaleY(1); } 92.01%, 100% { transform: scaleY(0); } }
@keyframes vwipe3 { 0%, 30% { transform: scaleY(0); } 39%, 92% { transform: scaleY(1); } 92.01%, 100% { transform: scaleY(0); } }
@keyframes vwipe4 { 0%, 42.5% { transform: scaleY(0); } 51.5%, 92% { transform: scaleY(1); } 92.01%, 100% { transform: scaleY(0); } }
@keyframes vwipe5 { 0%, 55% { transform: scaleY(0); } 64%, 92% { transform: scaleY(1); } 92.01%, 100% { transform: scaleY(0); } }
@keyframes vwipe6 { 0%, 67.5% { transform: scaleY(0); } 76.5%, 92% { transform: scaleY(1); } 92.01%, 100% { transform: scaleY(0); } }
@keyframes paintfade { 0%, 86% { opacity: 1; } 92%, 100% { opacity: 0; } }
@keyframes tileon { 0%, 100% { stroke: rgba(14, 10, 10, .22); } 3%, 12% { stroke: rgba(14, 10, 10, .9); } 18%, 88% { stroke: rgba(14, 10, 10, .45); } }
@keyframes tileon-you { 0%, 100% { stroke: #661420; } 3%, 12% { stroke: #661420; } 18%, 88% { stroke: #661420; } }
@keyframes ringon { 0%, 1% { opacity: 0; transform: scale(.9); } 4%, 9% { opacity: .9; transform: scale(1); } 16%, 100% { opacity: 0; transform: scale(1.18); } }
@keyframes labelpop { 0%, 100% { opacity: .45; } 3%, 11% { opacity: 1; } 16%, 88% { opacity: .68; } }
.flow-svg:not(.is-live) .clip, .flow-svg:not(.is-live) .paint, .flow-svg:not(.is-live) .tile, .flow-svg:not(.is-live) .ring, .flow-svg:not(.is-live) .flow-label { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
  .conn .clip { animation: none; transform: none; }
  .conn .paint, .node .tile, .node .ring, .flow-label { animation: none; }
  .flow-label { opacity: .85; }
}

/* ------------------------------------------------------------------ */
/* Inside the app                                                       */
/* ------------------------------------------------------------------ */
/* Inside the app: six bands, one per area of the product.
   The screens are 1344 CSS px wide and use every pixel of it, so they get
   the full width of the page. Setting one beside the copy would leave a
   column of about 1000px, which is 0.75 of full size and puts the app's own
   13px labels under 10px. The tabs this replaced were worse still at 0.45.
   So the presentation lands as elevation rather than as a side column: a
   tinted plinth, a card that floats off it, and the annotation resting on
   the card's bottom edge. */
.features { background: var(--paper); }
/* Wider than the rest of the page: 1344px of product plus the plinth's own
   padding needs the room. Copy keeps a readable measure of its own. */
.features > .container { max-width: 1456px; }
.features .section-head, .band-head, .band-hint, .bands-cta { max-width: 1120px; }
.accent { color: var(--wine); }

/* The six panels are stacked in one grid cell rather than laid out down the
   page, and only one is visible. Stacked and hidden by visibility rather than
   by display: they keep their layout, so the container is as tall as the
   tallest of them and switching tabs never moves the page under you, and the
   screens all load rather than flashing in on first reveal. All six crops are
   cut to the same height for the same reason. */
.tabbar-wrap { margin-top: 40px; margin-bottom: 40px; overflow-x: auto; overscroll-behavior-x: contain; padding-bottom: 8px; }
.tabbar-wrap::-webkit-scrollbar { height: 8px; }
.tabbar-wrap::-webkit-scrollbar-thumb { background: rgba(14, 10, 10, .16); border-radius: 4px; }
.tabbar { display: inline-flex; gap: 4px; padding: 4px; border: 1px solid var(--rule); border-radius: 999px; background: var(--card); box-shadow: 0 1px 2px rgba(14, 10, 10, .05); }
.tab { position: relative; z-index: 0; flex: none; min-height: 44px; padding: 8px 24px; border: 0; border-radius: 999px; background: transparent; font-family: var(--sans); font-size: 15px; font-weight: 500; line-height: 1.2; color: var(--soft); white-space: nowrap; cursor: pointer; transition: color .2s var(--ease); -webkit-tap-highlight-color: transparent; }
.tab:hover { color: var(--ink); }
.tab:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.tab.is-active { color: var(--wine); }
.tab.is-active::before { content: ''; position: absolute; inset: 0; z-index: -1; border-radius: 999px; background: var(--pink-bg); }
/* The fill is the clock: the pill deepens left to right over the dwell, so a
   panel that is about to change says so before it does. It is revealed by a
   clip rather than a scaleX, because scaling squashed the 999px radius into a
   lens and the first frame read as a stray red block sitting outside the bar. */
.tab-progress { position: absolute; inset: 0; z-index: -1; border-radius: 999px; background: var(--pink-rule); clip-path: inset(0 100% 0 0 round 999px); }
/* Once a person picks a tab the advance stops, so the pill stops counting and
   simply reads as chosen. */
.tab.is-active .tab-progress { clip-path: none; }
.tabs-run .tab.is-active .tab-progress { animation: tabprogress 9s linear both; }
.tabs-run.is-held .tab.is-active .tab-progress { animation-play-state: paused; }
@keyframes tabprogress { from { clip-path: inset(0 100% 0 0 round 999px); } to { clip-path: inset(0 0 0 0 round 999px); } }

.bands { display: grid; grid-template-columns: minmax(0, 1fr); }
/* min-width 0: a grid item defaults to min-width auto and would size itself
   to the 1120px image, pushing the whole page sideways instead of letting
   the frame scroll. */
.band { grid-area: 1 / 1; display: grid; grid-template-columns: minmax(0, 1fr); align-content: start; opacity: 0; visibility: hidden; pointer-events: none; }
.band:focus-visible { outline: 2px solid var(--ink); outline-offset: 8px; }
.band.is-active { opacity: 1; visibility: visible; pointer-events: auto; animation: bandin .5s var(--ease-out) both; }
@keyframes bandin { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
.band > *, .band-shot, .band-plinth, .band-frame { min-width: 0; }
.band-head { display: grid; gap: 16px; padding-bottom: 24px; }
.band-title { display: grid; gap: 8px; }
.band-blurb { display: grid; gap: 8px; }
.band-blurb .body { max-width: 62ch; }
.band-no { margin-right: 12px; padding-right: 12px; border-right: 1px solid var(--pink-rule); color: var(--rose); }

/* The plinth is what turns a figure in a document into a product on a
   surface: a tinted panel, and the card lifted off it by its own shadow. */
.band-shot { position: relative; }
.band-plinth { padding: 24px; border-radius: 20px; background: linear-gradient(180deg, #eee6df, #f9f5f1); border: 1px solid var(--rule-soft); }
/* The screens are viewport crops, so the app's own chrome runs flush to every
   edge of the picture. A paper mat holds it off the card's corners. It is a
   border rather than padding because this element is the horizontal scroller
   and a border stays outside the scrollport, where padding would scroll away
   on the right. */
.band-frame { overflow-x: auto; overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch; border: 8px solid var(--card); border-radius: 14px; background: var(--card); box-shadow: 0 2px 4px rgba(14, 10, 10, .06), 0 20px 48px rgba(14, 10, 10, .14); }
/* The floor on scale, and the whole reason this section was rebuilt. 1120 is
   0.833 of the 1344px crop, which is where the app's 13px labels drop under
   11px. The frame fits the image to the plinth down to that point and then
   scrolls sideways instead of shrinking past readable. */
.band-frame img { display: block; width: 100%; min-width: 1120px; max-width: 1344px; height: auto; }
.band-frame::-webkit-scrollbar { height: 8px; }
.band-frame::-webkit-scrollbar-thumb { background: rgba(14, 10, 10, .2); border-radius: 4px; }
/* The hint is a claim about the frame, so it has to track the frame rather
   than a breakpoint. The media query is the no-script answer, correct at both
   ends; with script running, main.js measures each frame and the class below
   takes over, which is exact at every width in between. */
.band-hint { margin-top: 12px; font-size: 13px; line-height: 1.5; color: var(--muted); }
@media (min-width: 1240px) { .band-hint { display: none; } }
.js-hints .band-hint { display: none; }
.js-hints .band-shot.scrolls .band-hint { display: block; }

/* One dark chip, and the band's color carried by the dot alone. The tinted
   variants this replaced were pale panels on a pale plinth, which is the least
   legible place on the page for the one line that says where to look. */
.callout { position: relative; margin-top: 12px; display: inline-flex; align-items: center; gap: 8px; max-width: 100%; padding: 8px 12px; border-radius: var(--radius-sm); background: var(--ink); color: var(--paper); font-size: 13px; font-weight: 500; line-height: 1.35; box-shadow: 0 8px 26px rgba(14, 10, 10, .22); }
.callout-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--paper); flex: none; }
.callout-red .callout-dot { background: var(--salmon); }
.callout-sage .callout-dot { background: #7fc494; }
.callout-wine .callout-dot { background: var(--rose); }

.bands-cta { display: grid; gap: 16px; justify-items: start; margin-top: 56px; padding-top: 48px; border-top: 1px solid var(--rule-soft); }
.bands-cta .body { max-width: 52ch; }
.bands-cta svg { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

@media (min-width: 900px) {
  .tabbar-wrap { margin-bottom: 48px; }
  .band-head { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: 40px; align-items: start; padding-bottom: 32px; }
  .callout { font-size: 14px; padding: 12px 16px; margin-top: 16px; }
}
/* At 1240 and up the plinth is wide enough that the frame never scrolls, so
   the chip can rest on the card's bottom edge without colliding with the
   hint that a scrolling frame prints under itself. It overlaps the plinth's
   own padding and never the screen. */
@media (min-width: 1240px) {
  .band-plinth { padding: 32px; }
  .band-frame { border-width: 16px; border-radius: 20px; }
  .band-shot { padding-bottom: 24px; }
  .callout { position: absolute; left: 32px; bottom: 0; margin-top: 0; }
}

/* The panel rises as a whole. Only the chip lands separately, after the screen
   it points at has settled. */
.band.is-active .callout { animation: chipin .5s var(--ease-spring) .35s both; }
@keyframes chipin { from { opacity: 0; transform: translateY(8px) scale(.96); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .band.is-active, .band.is-active .callout { animation: none; }
  .tabs-run .tab.is-active .tab-progress { animation: none; }
}

/* ------------------------------------------------------------------ */
/* Gates                                                                */
/* ------------------------------------------------------------------ */
.gates { background: var(--ink); color: var(--paper); }
.gates-grid { display: grid; gap: 40px; }
.gates-copy { display: grid; gap: 24px; max-width: 560px; }
.gates-copy .h2 { color: var(--paper); }
.gates-lede { font-size: 17px; line-height: 1.55; color: var(--grey-warm); text-wrap: pretty; }
.gates-list { display: grid; gap: 16px; padding-top: 8px; border-top: 1px solid rgba(255, 255, 255, .14); }
.gates-list li { font-size: 15px; line-height: 1.5; color: var(--grey-warm); padding-top: 8px; }
.gates-list strong { color: var(--paper); font-weight: 600; }
.gates-visual { position: relative; display: grid; gap: 24px; }
.gates-shot-a { display: none; }
.gates-shot-b { width: 100%; max-width: 420px; }
@media (min-width: 720px) {
  .gates-shot-a { display: block; }
  .gates-shot-b { width: 62%; justify-self: end; max-width: none; }
}
@media (min-width: 1024px) {
  .gates-grid { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 80px; align-items: center; }
  /* The dialog sits over the bottom right of the gates list, the way it opens in the app. */
  .gates-visual { display: block; padding-bottom: 160px; }
  .gates-shot-a { position: relative; width: 100%; }
  .gates-shot-b { position: absolute; right: -24px; bottom: 0; width: 46%; box-shadow: var(--shadow-frame-dark); }
}

/* ------------------------------------------------------------------ */
/* Split sections, learns, trust, faq, note, final, footer             */
/* ------------------------------------------------------------------ */
.split { display: grid; gap: 40px; }
.split-copy { display: grid; gap: 24px; max-width: 560px; }
.shot-card { max-width: 480px; }
.check-list { display: grid; gap: 12px; }
.check-list li { display: flex; align-items: flex-start; gap: 12px; font-size: 15px; color: var(--soft); }
@media (min-width: 1024px) {
  .split { grid-template-columns: minmax(0, 6fr) minmax(0, 6fr); gap: 80px; align-items: center; }
  .split-reverse .split-copy { order: 0; }
  .split-reverse .split-visual { order: 1; }
}
.evidence { border-bottom: 1px solid var(--rule); }
.onboarding { border-bottom: 1px solid var(--rule); background: var(--card); }
.onboarding .frame { max-width: 560px; }

.learns-grid { display: grid; gap: 32px; }
.learns-grid .shot { display: grid; gap: 12px; }
@media (min-width: 900px) { .learns-grid { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: 40px; align-items: start; } .learns-grid .shot + .shot { position: sticky; top: 96px; } }

.trust-strip { background: var(--ink); color: var(--paper); padding-top: 64px; padding-bottom: 64px; }
.trust-grid { display: grid; gap: 32px; }
.trust-item { display: grid; gap: 12px; }
.trust-item .eyebrow { color: var(--blush); }
.trust-text { font-size: 15px; line-height: 1.55; color: var(--grey-warm); text-wrap: pretty; }
@media (min-width: 900px) { .trust-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 48px; } .trust-item { padding-right: 24px; border-left: 1px solid rgba(255, 255, 255, .14); padding-left: 24px; } }

.faq-grid { display: grid; gap: 40px; }
.faq-head { display: grid; gap: 16px; max-width: 480px; }
.faq-list { border-top: 1px solid var(--rule); }
.faq-item { border-bottom: 1px solid var(--rule); overflow: hidden; }
.faq-item summary { display: flex; align-items: center; justify-content: space-between; gap: 24px; padding: 24px 0; font-size: 17px; font-weight: 500; cursor: pointer; list-style: none; transition: color .2s var(--ease); -webkit-tap-highlight-color: transparent; }
.faq-item summary:hover { color: var(--wine); }
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after { content: ''; flex: none; width: 10px; height: 10px; border-right: 1.5px solid var(--muted); border-bottom: 1.5px solid var(--muted); transform: rotate(45deg) translate(-2px, -2px); transition: transform .4s var(--ease-out), border-color .2s; margin-right: 4px; }
.faq-item[open] summary::after { transform: rotate(225deg) translate(-2px, -2px); border-color: var(--wine); }
.faq-body { padding: 0 0 24px; }
.faq-item p { font-size: 15px; line-height: 1.55; color: var(--soft); max-width: 62ch; }
@media (min-width: 1024px) { .faq-grid { grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); gap: 80px; align-items: start; } }

.note { background: var(--card); border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }
.note-grid { display: grid; gap: 40px; }
.note-copy { display: grid; gap: 24px; max-width: 520px; }
.note-sign { font-family: var(--serif); font-size: 18px; color: var(--ink); }
.note-visual { display: grid; gap: 12px; margin: 0; }
@media (min-width: 1024px) { .note-grid { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 80px; align-items: center; } }

.final { background: var(--ink); color: var(--paper); }
.final-grid { display: grid; gap: 40px; }
.final-copy { display: grid; gap: 24px; max-width: 560px; }
.final-copy .h2 { color: var(--paper); }
.final-lede { font-size: 17px; line-height: 1.55; color: var(--grey-warm); text-wrap: pretty; }
@media (min-width: 1024px) { .final-grid { grid-template-columns: minmax(0, 6fr) minmax(0, 6fr); gap: 80px; align-items: center; } }

.site-footer { padding: 40px 0; border-top: 1px solid var(--rule); background: var(--paper); }
.footer-grid { display: grid; gap: 24px; }
.wordmark-sm { font-size: 22px; display: inline-block; margin-bottom: 8px; }
.footer-legal { max-width: 52ch; }
@media (min-width: 720px) { .footer-grid { grid-template-columns: 1fr 1fr; align-items: end; } .footer-legal { justify-self: end; text-align: right; } }
@media (max-width: 639px) { .site-footer { padding-bottom: 96px; } }

.sticky-cta { position: fixed; left: 0; right: 0; bottom: 0; z-index: 30; padding: 12px var(--gutter) max(12px, env(safe-area-inset-bottom)); background: rgba(252, 250, 247, .92); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border-top: 1px solid var(--rule-soft); transform: translateY(100%); transition: transform .45s var(--ease-out); }
.sticky-cta.is-shown { transform: none; }
.sticky-cta .btn { width: 100%; }
.sticky-cta[hidden] { display: none; }
@media (min-width: 640px) { .sticky-cta { display: none; } }

/* ------------------------------------------------------------------ */
/* Live demos: the Ask panel and the Add material flow, drawn in HTML  */
/* so they stay crisp at any size and loop while on screen. Every     */
/* element is always in the document, so the card never changes height */
/* mid-loop. Revealing is opacity and transform only.                  */
/* ------------------------------------------------------------------ */
.demo-note { margin-top: 12px; font-size: 13px; color: var(--muted); }
.ask-demo { max-width: 520px; border: 1px solid var(--rule); border-radius: var(--radius); background: var(--card); box-shadow: var(--shadow-frame); overflow: hidden; }
.ask-head { padding: 16px 24px; border-bottom: 1px solid var(--rule-soft); }
.ask-title { font-size: 15px; font-weight: 600; color: var(--ink); }
.ask-meta { font-size: 13px; color: var(--muted); margin-top: 2px; }
.ask-body { display: grid; gap: 16px; padding: 24px; background: var(--paper); }
.ask-q { position: relative; justify-self: end; max-width: 88%; padding: 12px 16px; border-radius: var(--radius-sm) var(--radius-sm) 2px var(--radius-sm); background: var(--ink); color: var(--paper); font-size: 14px; line-height: 1.45; opacity: 0; transform: translateY(6px); transition: opacity .3s var(--ease-out), transform .3s var(--ease-out); }
.ask-q.on { opacity: 1; transform: none; }
.ask-q-size { visibility: hidden; }
.ask-q-live { position: absolute; inset: 12px 16px; }
.ask-q-live::after { content: ''; display: inline-block; width: 1px; height: 1em; margin-left: 2px; vertical-align: -2px; background: var(--paper); opacity: 0; }
.ask-q.typing .ask-q-live::after { opacity: 1; animation: caret 1s steps(2, start) infinite; }
@keyframes caret { to { opacity: 0; } }
.ask-a { position: relative; display: grid; grid-template-columns: 32px 1fr; gap: 12px; opacity: 0; transition: opacity .3s var(--ease-out); }
.ask-a.on { opacity: 1; }
.ask-avatar { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 6px; border: 1px solid var(--pink-rule); background: var(--pink-bg); color: var(--wine); font-family: var(--mono); font-size: 11px; }
.ask-answer { position: relative; display: grid; gap: 12px; }
.ask-p { font-size: 14px; line-height: 1.55; color: var(--ink2); }
.ask-p .w { opacity: 0; transition: opacity .18s var(--ease); }
.ask-p .w.on { opacity: 1; }
.ask-thinking { position: absolute; left: 0; top: 4px; display: flex; gap: 4px; opacity: 0; transition: opacity .2s var(--ease); }
.ask-thinking.on { opacity: 1; }
.ask-thinking span { width: 6px; height: 6px; border-radius: 50%; background: var(--grey); animation: think 1s var(--ease) infinite; }
.ask-thinking span:nth-child(2) { animation-delay: .15s; }
.ask-thinking span:nth-child(3) { animation-delay: .3s; }
@keyframes think { 0%, 100% { opacity: .35; transform: translateY(0); } 50% { opacity: 1; transform: translateY(-3px); } }
.ask-from { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding-top: 4px; }
.ask-from-label { font-family: var(--mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); margin-right: 4px; }
.ask-chip { display: inline-flex; align-items: center; gap: 8px; padding: 4px 12px; border: 1px solid var(--rule); border-radius: 6px; background: var(--card); font-family: var(--mono); font-size: 12px; color: var(--ink2); opacity: 0; transform: translateY(4px); transition: opacity .3s var(--ease-out), transform .3s var(--ease-out); }
.ask-chip::before { content: ''; width: 6px; height: 6px; border-radius: 1px; background: var(--wine); }
.ask-chip.on { opacity: 1; transform: none; }
.ask-demo.fading .ask-body > * { opacity: 0; transition: opacity .4s var(--ease); }

.kb-demo { max-width: 560px; border: 1px solid var(--rule); border-radius: var(--radius); background: var(--card); box-shadow: var(--shadow-frame); overflow: hidden; }
.kb-head { padding: 16px 24px; border-bottom: 1px solid var(--rule-soft); }
.kb-title { font-size: 15px; font-weight: 600; color: var(--ink); }
.kb-sub { font-size: 13px; color: var(--muted); margin-top: 2px; }
.kb-drop { display: grid; gap: 4px; justify-items: center; margin: 16px 24px 0; padding: 16px; border: 1px dashed var(--dash); border-radius: var(--radius-sm); text-align: center; transition: border-color .3s var(--ease), background .3s var(--ease); }
.kb-drop.on { border-color: var(--wine); background: var(--pink-bg); }
.kb-drop-text { font-size: 14px; font-weight: 500; color: var(--ink); }
.kb-drop-hint { font-size: 12px; color: var(--muted); }
.kb-files { display: grid; gap: 8px; padding: 16px 24px 0; }
.kb-file { display: grid; grid-template-columns: 36px 1fr auto; gap: 12px; align-items: start; padding: 12px; border: 1px solid var(--rule-soft); border-radius: var(--radius-sm); background: var(--paper); opacity: 0; transform: translateY(8px); transition: opacity .35s var(--ease-out), transform .35s var(--ease-out), border-color .3s var(--ease); }
.kb-file.on { opacity: 1; transform: none; }
.kb-file.done { border-color: var(--rule); }
.kb-ftype { display: inline-flex; align-items: center; justify-content: center; height: 24px; margin-top: 2px; border: 1px solid var(--rule); border-radius: 4px; background: var(--card); font-family: var(--mono); font-size: 9px; letter-spacing: .06em; color: var(--muted); }
.kb-fmain { display: grid; gap: 4px; min-width: 0; }
.kb-fname { font-size: 13.5px; font-weight: 500; color: var(--ink); }
.kb-fmeta { display: block; font-family: var(--mono); font-size: 11px; color: var(--muted); margin-top: 2px; }
.kb-fread, .kb-ffile { display: flex; align-items: baseline; gap: 8px; font-size: 12.5px; line-height: 1.45; color: var(--soft); opacity: 0; transform: translateY(4px); transition: opacity .35s var(--ease-out), transform .35s var(--ease-out); }
.kb-ffile { align-items: center; }
.kb-fread.on, .kb-ffile.on { opacity: 1; transform: none; }
.kb-flabel { flex: none; font-family: var(--mono); font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.kb-chip { display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 4px; background: var(--ink); color: var(--paper); font-size: 12px; font-weight: 500; }
.kb-fstate { font-family: var(--mono); font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); white-space: nowrap; padding-top: 4px; }
.kb-fstate::before { content: ''; display: inline-block; width: 6px; height: 6px; margin-right: 8px; border-radius: 50%; background: var(--grey); animation: think 1s var(--ease) infinite; }
.kb-file.done .kb-fstate { color: var(--sage); }
.kb-file.done .kb-fstate::before { background: var(--sage); animation: none; }
.kb-foot { display: flex; justify-content: space-between; gap: 16px; padding: 12px 24px 16px; font-family: var(--mono); font-size: 11px; letter-spacing: .04em; color: var(--muted); }
.kb-foot-right { color: var(--sage); opacity: 0; transition: opacity .3s var(--ease); }
.kb-foot-right.on { opacity: 1; }
.kb-use { padding: 16px 24px 24px; border-top: 1px solid var(--rule-soft); background: var(--sand); opacity: 0; transform: translateY(8px); transition: opacity .4s var(--ease-out), transform .4s var(--ease-out); }
.kb-use.on { opacity: 1; transform: none; }
.kb-use-label { font-family: var(--mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); margin-bottom: 8px; }
.kb-req { display: grid; grid-template-columns: 24px 1fr auto; gap: 12px; align-items: start; padding: 12px; border: 1px solid var(--rule); border-radius: var(--radius-sm); background: var(--card); }
.kb-req-n { font-family: var(--mono); font-size: 11px; color: var(--faint); padding-top: 2px; }
.kb-req-main { display: grid; gap: 4px; min-width: 0; }
.kb-req-t { font-size: 13.5px; font-weight: 500; color: var(--ink); }
.kb-req-q { font-size: 12px; color: var(--muted); }
.kb-req-ev { font-family: var(--mono); font-size: 11px; color: var(--ink2); opacity: 0; transition: opacity .3s var(--ease); }
.kb-req-ev.on { opacity: 1; }
.kb-req-status { display: inline-flex; align-items: center; gap: 8px; padding: 2px 8px; border-radius: 4px; background: var(--sand); font-size: 12px; font-weight: 500; color: var(--soft); white-space: nowrap; transition: background .3s var(--ease), color .3s var(--ease); }
.kb-req-status::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.kb-req-status.met { background: var(--sage-bg); color: var(--sage); }
.kb-demo.fading > * { opacity: 0; transition: opacity .4s var(--ease); }
@media (prefers-reduced-motion: reduce) {
  .ask-thinking span, .kb-fstate::before, .ask-q.typing .ask-q-live::after { animation: none; }
}
@media (max-width: 559px) {
  /* Phone: the type badge and the state share the top row, the file's details take the full width below. */
  .kb-file { grid-template-columns: 36px minmax(0, 1fr); }
  .kb-fstate { grid-column: 2; grid-row: 1; justify-self: end; padding-top: 4px; }
  .kb-fmain { grid-column: 1 / -1; }
}
