/* =====
   FlakeKill — component styles (hand-written; tokens live in tokens.css,
   generated verbatim from 04/05 by src-final/build.mjs).
   Animated properties: transform/opacity only (hover/selection states are
   opacity layers; the colour of a text link changes instantly).
   ===== */

/* ---------- Reset / base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--ink);
  color: var(--text-hi);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: var(--fw-body);
  -webkit-font-smoothing: antialiased;
}
img, svg { display: block; max-width: 100%; }
button { font-family: inherit; }
a { color: inherit; }
ul { margin: 0; padding: 0; }
h1, h2, h3, h4, p { margin: 0; }

/* content width = min(1280px, 100vw - 2 x --pad-inline) (04): the 1280 is the content box */
.wrap {
  max-width: calc(var(--content-max) + 2 * var(--pad-inline));
  margin-inline: auto;
  padding-inline: var(--pad-inline);
}

:focus { outline: none; }
:focus-visible {
  outline: var(--focus-width) solid var(--focus-ring);
  outline-offset: var(--focus-offset);
  border-radius: var(--radius-cell);
}
.btn--primary:focus-visible,
.cta-sticky-bar__btn:focus-visible { outline-color: var(--focus-on-amber); }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  left: var(--space-4);
  top: -48px;
  z-index: var(--z-menu);
  background: var(--amber);
  color: var(--text-inv);
  font-family: var(--font-mono);
  font-size: var(--fs-mono-sm);
  font-weight: var(--fw-mono-med);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-button);
  transition: transform var(--motion-micro) var(--ease-enter);
}
.skip-link:focus-visible { top: var(--space-4); outline-color: var(--focus-on-amber); }

/* ---------- Buttons / links ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  border: none;
  border-radius: var(--radius-button);
  font-family: var(--font-body);
  font-weight: var(--fw-body-semi);
  font-size: var(--fs-small);
  line-height: 1.2;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
}
/* amber -> amber-hover is an opacity layer (05 #3), the lift is a transform */
.btn--primary {
  position: relative;
  isolation: isolate;
  background: var(--amber);
  color: var(--text-inv);
  padding: var(--space-3) var(--space-5);
  transition: transform var(--motion-micro) var(--ease-inout);
}
.btn--primary::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: var(--amber-hover);
  opacity: 0;
  transition: opacity var(--motion-micro) var(--ease-inout);
}
.btn--primary:hover { transform: translateY(-1px); }
.btn--primary:hover::before { opacity: 1; }
.btn--primary:active { transform: translateY(0); }
.btn--primary:active::before { background: var(--amber-active); opacity: 1; }
.btn--compact { padding: var(--space-2) var(--space-4); }
/* Long CTA copy («Connect your CI. Get your flake report.») must wrap on
   narrow screens instead of widening the document. */
@media (max-width: 639px) {
  .btn--primary { white-space: normal; text-align: center; text-wrap: balance; }
}
.btn--neutral {
  position: relative;
  isolation: isolate;
  background: var(--elevated);
  color: var(--text-hi);
  border: var(--border-hair);
  padding: var(--space-3) var(--space-5);
}
.btn--neutral::before { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; background: var(--hairline-soft); opacity: 0; transition: opacity var(--motion-micro) var(--ease-inout); }
.btn--neutral:hover::before { opacity: 1; }

.link-quiet {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  color: var(--text-mid);
  font-size: var(--fs-small);
  text-decoration: none;
  position: relative;
  background: none;
  border: none;
  padding: 0;
  font-family: inherit;
  cursor: pointer;
}
.link-quiet:hover { color: var(--text-hi); }
.nav-underline {
  position: absolute;
  left: 0; bottom: -4px;
  width: 100%; height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--motion-micro) var(--ease-inout);
}
.link-quiet:hover .nav-underline,
.link-quiet:focus-visible .nav-underline { transform: scaleX(1); }

/* ---------- Run-cell atom (card, demo, scan, auth) ---------- */
.cell {
  position: relative;
  width: var(--cell-size);
  height: var(--cell-size);
  flex: none;
  border-radius: var(--radius-cell);
  background: transparent;
  padding: 0;
  border: none;
  appearance: none;
}
.cell-layer {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  opacity: 0;
  border: 1px solid transparent;
  pointer-events: none;
  transition: opacity var(--motion-short) var(--ease-inout);
}
/* Register of DATA (04, run-cell): hero card, demo rows, dashboard history, step ribbons, scan cells.
   The register of atmosphere (--cell-*-fill/-edge) lives only in ribbons and fields. */
.cell-layer--pass { background: var(--cell-pass-data); border-color: var(--cell-pass-data-edge); }
.cell-layer--fail { background: var(--cell-fail-data); border-color: var(--cell-fail-data-edge); }
.cell-layer--quar { background: var(--cell-quar-fill); border-color: var(--cell-quar-edge); }
.cell[data-state="pass"] .cell-layer--pass,
.cell[data-state="fail"] .cell-layer--fail,
.cell[data-state="quarantine"] .cell-layer--quar { opacity: 1; }
.cell[data-state="empty"] { background: transparent; border: var(--border-dash); }
/* The current (newest) run of a data row is lit: --cell-*-lit. Before the act the liar's current run also glows
   by outcome (--glow-*): hero card (is-lit) and the demo's liar row; honest rows and the dashboard do not glow. */
.cell.is-lit .cell-layer--pass,
.demo-track .cell[data-run="32"][data-state="pass"] .cell-layer--pass,
.demo-fly.cell[data-run="32"][data-state="pass"] .cell-layer--pass { background: var(--cell-pass-lit); border-color: var(--cell-pass-lit); }
.cell.is-lit .cell-layer--fail,
.demo-track .cell[data-run="32"][data-state="fail"] .cell-layer--fail,
.demo-fly.cell[data-run="32"][data-state="fail"] .cell-layer--fail { background: var(--cell-fail-lit); border-color: var(--cell-fail-lit); }
.cell.is-lit .cell-layer--pass,
[data-liar] .demo-track .cell[data-run="32"][data-state="pass"] .cell-layer--pass,
.demo-fly.cell[data-run="32"][data-state="pass"] .cell-layer--pass { box-shadow: var(--glow-pass); }
.cell.is-lit .cell-layer--fail,
[data-liar] .demo-track .cell[data-run="32"][data-state="fail"] .cell-layer--fail,
.demo-fly.cell[data-run="32"][data-state="fail"] .cell-layer--fail { box-shadow: var(--glow-fail); }

/* hero-card current run: CSS cross-fade, paused until the scene is live */
.cell.is-flicker .cell-layer--pass,
.cell.is-flicker .cell-layer--fail {
  animation-duration: 1.8s;
  animation-iteration-count: infinite;
  animation-timing-function: var(--ease-inout);
  animation-delay: var(--seed-delay, 0ms);
  animation-play-state: paused;
}
.cell.is-flicker[data-state="pass"] .cell-layer--pass { animation-name: cellHold; }
.cell.is-flicker[data-state="pass"] .cell-layer--fail { animation-name: cellRise; }
.cell.is-flicker[data-state="fail"] .cell-layer--fail { animation-name: cellHold; }
.cell.is-flicker[data-state="fail"] .cell-layer--pass { animation-name: cellRise; }
[data-scene].is-live .cell.is-flicker .cell-layer--pass,
[data-scene].is-live .cell.is-flicker .cell-layer--fail { animation-play-state: running; }
/* --cell-on: depth opacity of the state layer (1 for near cells) */
@keyframes cellHold { 0%, 42% { opacity: var(--cell-on, 1); } 50%, 92% { opacity: 0; } 100% { opacity: var(--cell-on, 1); } }
@keyframes cellRise { 0%, 42% { opacity: 0; } 50%, 92% { opacity: var(--cell-on, 1); } 100% { opacity: 0; } }

.cell--demo { cursor: pointer; transition: transform var(--motion-micro) var(--ease-inout); }
.cell--demo:focus-visible { outline-offset: 1px; }
.cell--demo:hover,
.cell--demo:focus-visible { transform: translateY(-1px); }

/* anchors under the sticky header (Home only; the header is 64px in every state) */
#hero, #demo, #how, #safety, #dashboard, #pricing-teaser, #integrations, #final-cta { scroll-margin-top: 64px; }

/* ---------- Header ----------
   64px in every state and on every page (04): the condensed state changes only the plate and the line, both are
   opacity layers (05 #6). Sticky + condensing: Home only and only >= 640; Pricing, Connect and < 640: in the flow,
   no line. */
.site-header {
  position: relative;
  z-index: var(--z-header);
  background: var(--ink);
}
.site-header::before,
.site-header::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--motion-short) var(--ease-inout);
}
.site-header::before { top: 0; bottom: 0; z-index: -1; background: var(--surface); }
.site-header::after { top: 100%; height: 1px; background: var(--hairline); }
@media (min-width: 640px) {
  .site-header--sticky { position: sticky; top: 0; }
  .site-header--sticky.is-condensed::before,
  .site-header--sticky.is-condensed::after { opacity: 1; }
}
.header-inner { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); height: 64px; }
.logo {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-1);
  font-family: var(--font-mono);
  font-weight: var(--fw-mono-med);
  font-size: var(--fs-mono);
  color: var(--text-hi);
  text-decoration: none;
}
.logo-mark { color: var(--amber); }
.primary-nav ul { display: flex; gap: var(--space-6); list-style: none; }
.primary-nav a {
  font-family: var(--font-mono);
  font-size: var(--fs-mono-sm);
  color: var(--text-mid);
  text-decoration: none;
  position: relative;
  padding-bottom: 2px;
}
.primary-nav a:hover { color: var(--text-hi); }
.menu-toggle {
  display: none;
  background: none;
  border: var(--border-hair);
  border-radius: var(--radius-button);
  color: var(--text-hi);
  width: 40px; height: 40px;
  align-items: center; justify-content: center;
}
.menu-toggle svg { width: 20px; height: 20px; }
.menu-toggle .ic-close, .menu-toggle[aria-expanded="true"] .ic-menu { display: none; }
.menu-toggle[aria-expanded="true"] .ic-close { display: inline; }
.mobile-nav { display: none; }
/* < 640: wordmark + CTA + toggle, the nav goes under the toggle; the exact complement of (min-width: 640px) */
@media not all and (min-width: 640px) {
  .primary-nav { display: none; }
  .menu-toggle { display: inline-flex; }
  .header-inner { gap: var(--space-3); }
  .header-inner .site-header__cta { margin-left: auto; }
  .mobile-nav {
    display: block;
    position: absolute;
    top: 100%;
    left: 0; right: 0;
    z-index: var(--z-menu);
    background: var(--surface);
    border-block: var(--border-hair);
    padding: var(--space-5) var(--pad-inline);
  }
  .mobile-nav[hidden] { display: none; }
  .mobile-nav ul { list-style: none; display: flex; flex-direction: column; gap: var(--space-5); }
  .mobile-nav a { font-family: var(--font-mono); font-size: var(--fs-mono); color: var(--text-hi); text-decoration: none; }
}

/* CTA of the header on < 640 (05, «Липкая панель (#5)»): visible in the base; the script hides it with a class on <html>
   while the bar is shown. The exact complement of the bar's (min-width: 640px). */
@media not all and (min-width: 640px) {
  .site-header__cta {
    /* the return is after the bar has left: together they are never in one frame */
    transition:
      opacity    0s linear var(--motion-short),
      visibility 0s linear var(--motion-short);
  }
  .is-cta-bar-shown .site-header__cta {
    opacity: 0;
    visibility: hidden;      /* not display: the header is not rebuilt */
    transition: none;        /* hiding is instant: the bar enters in 200ms, the header CTA is already gone */
  }
}

/* Mobile sticky CTA bar (05 #5): hidden in the base (it duplicates the CTAs that stand in the flow), shown by the
   script outside the four zones; only Home and Pricing, only < 640 */
.cta-sticky-bar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: var(--z-sticky);
  background: var(--surface);
  border-top: var(--border-hair);
  padding: var(--space-3) var(--pad-inline);
  transform: translateY(100%);
  opacity: 0;
  visibility: hidden;          /* discrete: a hidden bar is out of focus and clicks */
  transition:
    transform var(--motion-short) var(--ease-exit),
    opacity   var(--motion-short) var(--ease-exit),
    visibility 0s linear var(--motion-short);   /* after the exit */
}
.cta-sticky-bar.is-shown {
  transform: translateY(0);
  opacity: 1;
  visibility: visible;
  transition:
    transform var(--motion-short) var(--ease-enter),
    opacity   var(--motion-short) var(--ease-enter),
    visibility 0s;             /* at once */
}
@media (min-width: 640px) {
  .cta-sticky-bar { display: none; }
}
.cta-sticky-bar__btn { width: 100%; justify-content: center; }

/* ---------- Section scaffolding / display type ---------- */
section { position: relative; }
.section-pad { padding-block: var(--section-y); }
/* H2 spans the whole container (04: the measure of a paragraph does not apply to a heading);
   the lead and body keep their own measure. */
.section-head { margin-bottom: var(--space-7); }
@media (max-width: 639px) { .section-head { margin-bottom: var(--space-6); } }
.eyebrow {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--text-mid);
  margin-bottom: var(--space-3);
}
.section-title {
  font-family: var(--font-display);
  font-weight: var(--fw-display);
  font-size: var(--fs-h2);
  line-height: var(--lh-h2);
  letter-spacing: var(--ls-h2);
  word-spacing: var(--ws-display);
  color: var(--text-hi);
  text-wrap: balance;
}
.acr { letter-spacing: var(--ls-acronym); }
.section-lead {
  font-size: var(--fs-body-lg);
  line-height: var(--lh-body-lg);
  color: var(--text-mid);
  margin-top: var(--space-5);
  max-width: var(--measure);
  text-wrap: pretty;
}
.section-lead--hi { color: var(--text-hi); }
.section-body { font-size: var(--fs-body); color: var(--text-mid); max-width: var(--measure); margin-top: var(--space-4); }
.section-body strong { color: var(--text-hi); font-weight: var(--fw-body-semi); }

/* Divider ribbon: full-bleed run-cell ribbon. Cells are laid out from the central
   axis of the viewport (odd count, centred), the edges cut them symmetrically; the
   count is derived from the viewport width, there is no dead end before the edge.
   Static, no animation: the "seam", not a live object. */
.ribbon {
  display: flex;
  justify-content: center;
  gap: var(--cell-gap);
  height: var(--cell-size);
  width: 100%;
  overflow: hidden;
}
.ribbon i,
.step__rail i,
.step-ribbon i {
  display: block;
  flex: none;
  width: var(--cell-size);
  height: var(--cell-size);
  border-radius: var(--radius-cell);
}
/* Register of ATMOSPHERE (ribbons, timeline rail): --cell-*-fill/-edge on --field-mid-opacity, quiet */
.ribbon i,
.step__rail i {
  border: 1px solid var(--cell-pass-edge);
  background: linear-gradient(var(--cell-pass-fill), var(--cell-pass-fill)), var(--hairline-soft);
  opacity: var(--field-mid-opacity);
}
/* state «before» (one ribbon after the hero): the liar's pattern as it is */
.ribbon i.f {
  border-color: var(--cell-fail-edge);
  background: linear-gradient(var(--cell-fail-fill), var(--cell-fail-fill)), var(--hairline-soft);
}
/* state «after» (everything below the demo, Pricing, Connect): FAIL = an isolated run, an amber EDGE only,
   no fill, no glow, no red */
.ribbon i.q,
.step__rail i.q {
  border-color: var(--cell-quar-edge);
  background: transparent;
}
/* Register of DATA (step motifs): full opacity, fill >= 3:1; the last run of the ribbon is lit */
.step-ribbon i {
  border: 1px solid var(--cell-pass-data-edge);
  background: var(--cell-pass-data);
}
.step-ribbon i.f { border-color: var(--cell-fail-data-edge); background: var(--cell-fail-data); }
.step-ribbon i.lit { background: var(--cell-pass-lit); border-color: var(--cell-pass-lit); }
.step-ribbon i.f.lit { background: var(--cell-fail-lit); border-color: var(--cell-fail-lit); }
.ribbon--hero { margin-top: var(--space-6); }

/* Reveal: visible by default; only main.js opts blocks into the fade. */
[data-reveal] { transition: opacity var(--motion-medium) var(--ease-enter), transform var(--motion-medium) var(--ease-enter); }
[data-reveal].is-pending { opacity: 0; transform: translateY(16px); }
[data-reveal].is-revealed { opacity: 1; transform: translateY(0); }

/* =====
   HERO — field poster (DOM, base layer without JS) + canvas (js/field.js)
   ===== */
.hero {
  position: relative;
  min-height: clamp(560px, 82vh, 820px);
  display: flex;
  align-items: center;
  padding-block: var(--space-9);
  overflow: hidden;
}
.hero-field {
  position: absolute;
  inset: 0;
  z-index: var(--z-field);
  overflow: hidden;
  /* fills of the field cells: the canvas mixes its colours from these values,
     the poster uses the same numbers (04 п.2: one source for poster and canvas) */
  --field-pass-fill: rgba(61, 224, 138, 0.85);
  --field-fail-fill: rgba(255, 90, 84, 0.85);
}
/* Vignette (token) + the bottom of the field fades into ink: no hard horizontal cut. */
.hero-field::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  background:
    linear-gradient(to bottom, transparent calc(100% - var(--space-7)), var(--ink) 100%),
    var(--vignette);
  pointer-events: none;
}
/* Rows of cells go from the central axis of the viewport: far has an even number
   per row (the middle of a gap sits on the axis), mid an odd one (the centre of a cell
   on the axis); the edges cut them symmetrically. */
.field-layer {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  gap: var(--cell-gap);
}
.frow { display: flex; justify-content: center; gap: var(--cell-gap); flex: none; }
.field-layer--far {
  --cw: var(--field-far-cell);
  --cell-on: calc(var(--field-far-opacity) * var(--field-rest));
  filter: saturate(var(--field-far-saturate));
}
.field-layer--mid {
  --cw: var(--field-mid-cell);
  --cell-on: calc(var(--field-mid-opacity) * var(--field-rest));
  /* the mid lattice is shifted by --field-mid-shift (half its pitch) from the top of the field (no dark seams);
     DOM row 0 is the row cut by the top edge, row 1 starts at --field-mid-shift */
  inset: auto 0 auto 0;
  height: 100%;
  top: calc(var(--field-mid-shift) - var(--field-mid-cell) - var(--cell-gap));
}
/* Static cell = the composite of body + tint at rest depth (same maths as the canvas) */
.field-layer i {
  display: block;
  flex: none;
  position: relative;
  width: var(--cw);
  height: var(--cw);
  border-radius: var(--radius-cell);
  background: color-mix(in srgb, rgb(61 224 138) calc(var(--cell-on) * 85%), var(--field-body));
}
.field-layer i.f { background: color-mix(in srgb, rgb(255 90 84) calc(var(--cell-on) * 85%), var(--field-body)); }
/* Flickering poster cells (<= 40): the only animated nodes, opacity of the state layers */
.field-layer i.is-flicker { background: var(--field-body); }
.field-layer .cell-layer {
  display: block;
  position: absolute;
  inset: 0;
  border: none;
  border-radius: inherit;
  opacity: 0;
  transition: none;
  animation-duration: 2.1s;
  animation-iteration-count: infinite;
  animation-timing-function: var(--ease-inout);
  animation-delay: calc(-1 * var(--seed-delay, 0ms)); /* already in progress at first paint: no cell sits black waiting for its delay */
  animation-play-state: running;
}
.field-layer .cell-layer--pass { background: var(--field-pass-fill); }
.field-layer .cell-layer--fail { background: var(--field-fail-fill); }
.field-layer i.is-flicker:not(.f) .cell-layer--pass { animation-name: cellHold; }
.field-layer i.is-flicker:not(.f) .cell-layer--fail { animation-name: cellRise; }
.field-layer i.is-flicker.f .cell-layer--fail { animation-name: cellHold; }
.field-layer i.is-flicker.f .cell-layer--pass { animation-name: cellRise; }
/* the poster flickers without any script (04 п.2); beats the generic .cell.is-flicker pause above */
.hero-field .cell.is-flicker .cell-layer--pass,
.hero-field .cell.is-flicker .cell-layer--fail { animation-duration: 2.1s; animation-delay: calc(-1 * var(--seed-delay, 0ms)); animation-play-state: running; }
/* glow only on the mid layer, never on far */
.field-layer--mid i.is-flicker:not(.f) .cell-layer--pass { box-shadow: var(--glow-pass); }
.field-layer--mid i.is-flicker.f .cell-layer--fail { box-shadow: var(--glow-fail); }
/* the two poster layers are their own compositor layers (not re-layerized with the canvas) */
.hero-field .field-layer { will-change: transform; }

/* canvas takes over the poster: cross-fade, then the poster is skipped by the browser */
.hero-field > canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  display: block;
  pointer-events: none;
  opacity: 0;
  will-change: opacity;
  transition: opacity var(--field-reveal) var(--ease-enter);
}
.hero-field > canvas.is-live { opacity: 1; }
.hero-field[data-poster="off"] .field-layer { visibility: hidden; content-visibility: hidden; }
.hero-field[data-poster="off"][data-measure] .field-layer { content-visibility: visible; }

/* ---------- Hero content ---------- */
.hero-inner {
  position: relative;
  z-index: var(--z-content);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-6);
  width: 100%;
}
/* The second H1 line («lying to you.», measured 5.94em with the word-spacing) must stay on one line in its
   column: the display size never exceeds 16.6% of the column's inline size. It only bites at 1024-1200 (-3.6% on 1024,
   inside the scale; 04's estimate of the line was 5.43em). */
.hero-copy { container-type: inline-size; --h1-fs: min(var(--fs-display), 16.6cqi); }
.hero-copy h1 {
  font-family: var(--font-display);
  font-weight: var(--fw-display-b);
  font-size: var(--h1-fs);
  line-height: var(--lh-display);
  letter-spacing: var(--ls-display);
  word-spacing: var(--ws-display);
  color: var(--text-hi);
}
.hero-sub { margin-top: var(--space-5); }
.hero-copy .lead {
  font-size: var(--fs-body-lg);
  line-height: var(--lh-body-lg);
  color: var(--text-mid);
  max-width: var(--measure);
  text-wrap: pretty;
}
.hero-cta {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  flex-wrap: wrap;
  margin-top: var(--space-6);
}
.legend-glyph { font-size: 1em; line-height: 1; }
.is-pass .legend-glyph, .is-pass { color: var(--pass); }
.is-fail .legend-glyph, .is-fail { color: var(--fail); }
.is-quarantined .legend-glyph, .is-quarantined { color: var(--amber); }

@media (min-width: 1024px) {
  /* 7 + 5 of a 12-column grid; the gutter is the grid gutter (04: «lying to you.» fits 7 columns) */
  .hero-inner { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--grid-gutter); align-items: center; }
  .hero-copy { grid-column: 1 / span 7; }
  .test-card { grid-column: 8 / span 5; }

  /* Text over the field (poster; the canvas masks the same zone itself, then the plate goes away).
     ONE vertical fall of brightness (smoothstep) from the top of the last H1 line to the top of the lead zone, then
     dark down to the bottom of the field. ONE rounded region around H1 + lead + CTA (04, «Текст над полем»):
     the corner is only top right, an ellipse arc (radii: --L horizontally, --up vertically); no transition to the left
     (the region reaches the left edge of the field), open at the bottom (no lower corners or arc). The transition to
     the right is --L = 3.5 x --field-mid-step (the step of the mid lattice, not px; the norm is >= 3 steps and the visible
     span between 2% and 98% of the fall is then >= 3 steps as well). A rectangle with a feather is
     forbidden. Four mask layers = the quadrants of one distance field: region, top ramp, right strip, corner. */
  .hero-sub { position: relative; width: fit-content; max-width: 100%; }
  .hero:not([data-poster="off"]) .hero-sub::before {
    --L: calc(3.5 * var(--field-mid-step));
    --pad: var(--space-4);
    --up: calc(var(--lh-display) * var(--h1-fs) + var(--space-5) - var(--space-4));
    content: "";
    position: absolute;
    z-index: -1;
    pointer-events: none;
    top: calc(-1 * (var(--pad) + var(--up)));
    left: -100vw;
    right: calc(-1 * (var(--pad) + var(--L)));
    bottom: -100vh;
    background: var(--ink);
    mask-image:
      linear-gradient(#000, #000),
      linear-gradient(to bottom, rgba(0,0,0,0) 0%, rgba(0,0,0,0.028) 10%, rgba(0,0,0,0.104) 20%, rgba(0,0,0,0.216) 30%, rgba(0,0,0,0.352) 40%, rgba(0,0,0,0.500) 50%, rgba(0,0,0,0.648) 60%, rgba(0,0,0,0.784) 70%, rgba(0,0,0,0.896) 80%, rgba(0,0,0,0.972) 90%, rgba(0,0,0,1) 100%),
      linear-gradient(to right, rgba(0,0,0,1) 0%, rgba(0,0,0,0.972) 10%, rgba(0,0,0,0.896) 20%, rgba(0,0,0,0.784) 30%, rgba(0,0,0,0.648) 40%, rgba(0,0,0,0.500) 50%, rgba(0,0,0,0.352) 60%, rgba(0,0,0,0.216) 70%, rgba(0,0,0,0.104) 80%, rgba(0,0,0,0.028) 90%, rgba(0,0,0,0) 100%),
      radial-gradient(ellipse 100% 100% at 0 100%, rgba(0,0,0,1) 0%, rgba(0,0,0,0.972) 10%, rgba(0,0,0,0.896) 20%, rgba(0,0,0,0.784) 30%, rgba(0,0,0,0.648) 40%, rgba(0,0,0,0.500) 50%, rgba(0,0,0,0.352) 60%, rgba(0,0,0,0.216) 70%, rgba(0,0,0,0.104) 80%, rgba(0,0,0,0.028) 90%, rgba(0,0,0,0) 100%);
    mask-size:
      calc(100% - var(--L)) calc(100% - var(--up)),
      calc(100% - var(--L)) var(--up),
      var(--L) calc(100% - var(--up)),
      var(--L) var(--up);
    mask-position:
      0 100%,
      0 0,
      100% 100%,
      100% 0;
    mask-repeat: no-repeat;
  }
}

@media (max-width: 639px) {
  /* the card must start inside the first screen (390x844): one step tighter spacing between the blocks */
  .hero-inner { gap: var(--space-5); }
  .hero-cta { gap: var(--space-4); margin-top: var(--space-5); }
}
@media (max-width: 1023px) {
  /* The field is a full-bleed band ahead of the copy: it starts right under the header (no ink
     in between), its bottom --space-5 fades into ink, the H1 stands --space-6 below it on clean ink. */
  .hero { flex-direction: column; align-items: stretch; padding-top: 0; padding-bottom: var(--space-8); }
  .hero-field { position: relative; inset: auto; width: 100%; height: var(--field-band-h); margin-bottom: var(--space-6); flex: none; }
  .hero-field::after {
    background:
      linear-gradient(to bottom, transparent calc(100% - var(--space-5)), var(--ink) 100%),
      var(--vignette);
  }
}

/* Hero test card */
.test-card {
  position: relative;
  background: var(--surface);
  border: var(--border-hair);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: var(--space-5);
  width: 100%;
}
.test-card__head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; }
.test-card__name { font-family: var(--font-mono); font-size: var(--fs-mono); color: var(--text-hi); }
.test-card__name .sep { color: var(--text-low); margin: 0 2px; }
.test-card__status {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--amber);
}
.test-card__status::before { content: "● "; }
.test-card__track { display: flex; gap: var(--cell-gap); margin-top: var(--space-4); flex-wrap: wrap; }
.test-card__caption { margin-top: var(--space-3); font-family: var(--font-mono); font-size: var(--fs-mono-sm); color: var(--text-mid); }
/* legend of the cells: one line right under the caption, glyph + word (shape besides colour), inside the card at any width */
.test-card__legend {
  display: flex;
  gap: var(--space-5);
  list-style: none;
  margin-top: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
}
.test-card__legend li { display: inline-flex; align-items: center; gap: var(--space-1); }
.test-card__divider { border: none; border-top: var(--border-hair); margin: var(--space-4) 0; }
.test-card__quarantine { display: flex; align-items: center; gap: var(--space-3); }
.test-card__quarantine-label {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--text-mid);
}
.test-card__slot { flex: none; }
.motion-fallback { font-family: var(--font-mono); font-size: var(--fs-mono-sm); color: var(--text-mid); margin-top: var(--space-3); }
.motion-fallback[hidden] { display: none; }

/* Tooltip (cells) */
.cell-tooltip {
  position: absolute;
  z-index: var(--z-tooltip);
  background: var(--surface);
  border: var(--border-hair);
  border-radius: var(--radius-cell);
  padding: var(--space-2) var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--fs-mono-sm);
  color: var(--text-hi);
  white-space: nowrap;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity var(--motion-micro) var(--ease-enter), transform var(--motion-micro) var(--ease-enter);
  pointer-events: none;
}
.cell-tooltip.is-visible { opacity: 1; transform: translateY(0); }

/* =====
   LIVE DEMO
   Row layout by width: >=1024 one line (name | track | status), 640-1023 two tiers
   (name + status, track below), <640 tabs (one test at a time; name / track / status).
   Track: the run history, newest first in the DOM, laid out right-to-left and wrapped:
   only whole cells fit the track, the remainder (< 1 pitch) stays blank on the left.
   ===== */
.demo-scene {
  position: relative;
  background: var(--surface);
  /* the hairline is a shadow, not a border: the inner width of the scene stays exactly width - 2 x --space-6 (04 numbers) */
  box-shadow: 0 0 0 1px var(--hairline);
  border-radius: var(--radius-panel);
  padding: var(--space-6);
  --dr-cols: 320px minmax(0, 1fr) 80px;
  --dr-areas: "name track status";
}
@media (max-width: 1023px) {
  .demo-scene { --dr-cols: minmax(0, 1fr) auto; --dr-areas: "name status" "track track"; }
}
@media (max-width: 639px) {
  .demo-scene { --dr-cols: minmax(0, 1fr); --dr-areas: "name" "track" "status"; }
}

@media (max-width: 639px) {
  .demo-grid__row:not(.is-current) { display: none; }
  .demo-grid__row { row-gap: var(--space-2); }
  /* every tab has the same height (two name lines), the scene does not jump on a tab change */
  .demo-name { min-height: calc(2 * var(--lh-mono) * 1em); }
}
.demo-tabs { display: none; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-4); }
@media (max-width: 639px) { .demo-tabs { display: flex; } }
.demo-tabs button {
  background: var(--elevated);
  border: var(--border-hair);
  border-radius: var(--radius-button);
  color: var(--text-hi);
  font-family: var(--font-mono);
  font-size: var(--fs-mono-sm);
  padding: var(--space-2) var(--space-3);
  cursor: pointer;
  white-space: nowrap;
}
/* 320: both labels stay one line each (no wrapping inside a tab), so the tabs tighten instead */
@media (max-width: 359px) { .demo-tabs { gap: var(--space-2); } .demo-tabs button { padding-inline: var(--space-2); } }
.demo-tabs button:disabled { color: var(--text-low); cursor: not-allowed; }

/* stage: grid + the amber quarantine lane. >=1280 the lane stands to the right of the grid
   (252px, gap --space-5, its top = the top of the first row); below that, right under it. */
.demo-stage { display: grid; gap: var(--space-4); position: relative; }
@media (min-width: 1280px) {
  .demo-stage { grid-template-columns: minmax(0, 1fr) 252px; column-gap: var(--space-5); align-items: start; }
}
.demo-grid { display: flex; flex-direction: column; gap: var(--space-5); }

.demo-grid__row,
.demo-row__trace {
  display: grid;
  grid-template-columns: var(--dr-cols);
  grid-template-areas: var(--dr-areas);
  align-items: center;
}
.demo-grid__row { position: relative; min-height: 48px; row-gap: var(--space-2); }
@media (max-width: 1023px) { .demo-grid__row { min-height: 0; } }
.demo-name {
  grid-area: name;
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  line-height: var(--lh-mono);
  color: var(--text-hi);
}
/* a name breaks only after « › »: every segment is unbreakable, no ellipsis anywhere */
.nb { white-space: nowrap; }
.demo-status {
  grid-area: status;
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--text-mid);
  white-space: nowrap;
}
.demo-status.is-fail { color: var(--fail); }
.demo-status.is-pass { color: var(--pass); }
.demo-status.is-pulled { color: var(--text-mid); }
.demo-status.is-pulled > span { color: var(--amber); }

.demo-track {
  grid-area: track;
  display: flex;
  flex-direction: row-reverse;
  flex-wrap: wrap;
  align-content: flex-start;
  /* the second wrap row sits 40px below the first: it is clipped away (only whole cells fit the track) */
  gap: 40px var(--cell-gap);
  /* 14px of room round the cells: the glow of the liar's current run, the focus ring and the hover lift are not clipped */
  padding: 14px;
  margin: -14px;
  height: calc(var(--cell-size) + 28px);
  overflow: hidden;
}
@media (min-width: 1024px) {
  .demo-track { margin: -14px calc(var(--space-4) - 14px) -14px calc(var(--space-5) - 14px); }
}
.demo-track .cell { flex: none; }

/* Opacity layers of the act (05 #9/#10). Base = the way back; the delays of the forward move live in [data-state="extracted"]. */
.demo-row__trace,
.quarantine-final,         /* the pulled liar over the ghost */
.demo-result__green {
  opacity: 0;
  transition: opacity var(--motion-short) var(--ease-exit);
}
.ghost-cover,              /* name and slots of the ghost */
.ghost-keep,               /* chip and caption of the ghost */
.quarantine-track::before, /* the dashed frame of the ghost (part of ghost-keep) */
.demo-act::before {        /* amber layer of the act button */
  opacity: 1;
  transition: opacity var(--motion-short) var(--ease-enter);
}
.demo-scene[data-state="extracted"] .demo-row__trace { opacity: 1; transition: opacity var(--extract-trace) var(--ease-inout); }
.demo-scene[data-state="extracted"] .quarantine-track::after { opacity: 1; transition: opacity var(--motion-short) var(--ease-inout) var(--extract-glow-delay); }
.demo-scene[data-state="extracted"] .ghost-cover { opacity: 0; transition: opacity var(--motion-short) var(--ease-inout) var(--extract-glow-delay); }
.demo-scene[data-state="extracted"] .quarantine-final { opacity: 1; transition: opacity 1ms linear var(--extract-result-delay); }
.demo-scene[data-state="extracted"] .ghost-keep,
.demo-scene[data-state="extracted"] .quarantine-track::before { opacity: 0; transition: opacity 1ms linear var(--extract-result-delay); }
.demo-scene[data-state="extracted"] .demo-result__green { opacity: 1; transition: opacity var(--motion-short) var(--ease-inout) var(--extract-result-delay); }
.demo-scene[data-state="extracted"] .demo-act::before,
.demo-scene[data-state="extracted"] .demo-act::after { opacity: 0; transition: opacity var(--motion-short) var(--ease-inout); }
.demo-scene[data-state="extracted"] .demo-act { color: var(--text-mid); }

/* the liar's trace row ("pulled"): a layer in the same rectangle, same grid */
.demo-row__trace {
  position: absolute;
  inset: 0;
  row-gap: var(--space-2);
  pointer-events: none;
}
.demo-row__trace .demo-name { color: var(--text-low); }
.demo-row__trace .demo-track { overflow: hidden; }
.demo-row__trace .demo-track i,
.qz__cells i {
  display: block;
  flex: none;
  width: var(--cell-size);
  height: var(--cell-size);
  border-radius: var(--radius-cell);
  border: var(--border-dash);
  background: transparent;
}
/* during and after the act the live row is hidden (the clones carry it), only the trace stays */
.demo-scene[data-state="extracted"] [data-liar] > .demo-name,
.demo-scene[data-state="extracted"] [data-liar] > .demo-track,
.demo-scene[data-state="extracted"] [data-liar] > .demo-status { visibility: hidden; }

/* ---- amber quarantine lane ----
   Before the act the lane carries the FINAL content as a ghost on the final positions (name, outlined chip, dashed slots,
   caption, dashed frame): the receiving surface is never an empty frame. The act fills the ghost (opacity layers above):
   the geometry of the lane and of its content is the same before and after, pixel for pixel, at every width. */
.quarantine-track {
  position: relative;
  border-radius: var(--radius-card);
  padding: var(--space-5);
  display: grid;
  gap: var(--space-3);
  align-content: start;
}
/* frame layers (pseudo-elements, no text under them): ::before = the dashed frame of the ghost, ::after = the solid amber
   frame + glow that the act fills it with */
.quarantine-track::before,
.quarantine-track::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
}
.quarantine-track::before { border: var(--border-dash); }
.quarantine-track::after { border: 1px solid var(--amber); box-shadow: var(--glow-amber); opacity: 0; transition: opacity var(--motion-short) var(--ease-exit); }
.qz__label {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--amber);
}
.qz__body { display: grid; }
/* ghost and final are the same grid in the same rectangle (one grid cell, stacked) */
.qz__layer {
  grid-area: 1 / 1;
  display: grid;
  grid-template-columns: var(--qz-cols, minmax(0, 1fr));
  grid-template-areas: var(--qz-areas, "name" "status" "cells" "caption");
  gap: var(--space-3) 0;
  align-items: center;
}
.qz__name { grid-area: name; font-family: var(--font-mono); font-size: var(--fs-mono); line-height: var(--lh-mono); color: var(--text-hi); }
.qz__status {
  grid-area: status;
  justify-self: start;
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  color: var(--amber);
  white-space: nowrap;
  text-transform: uppercase;
  padding: 2px 6px;
  border: 1px solid transparent;
  border-radius: var(--radius-cell);
}
.qz__cells {
  grid-area: cells;
  display: flex;
  flex-direction: row-reverse;
  flex-wrap: wrap;
  align-content: flex-start;
  gap: var(--cell-gap);
  padding: 3px;
  margin: -3px;
  height: calc(var(--cell-size) + 6px);
  overflow: hidden;
}
.qz__caption {
  grid-area: caption;
  font-family: var(--font-mono);
  font-size: var(--fs-mono-sm);
  line-height: var(--lh-mono-sm);
  color: var(--text-mid);
  max-width: 62ch;
}
/* ghost: --text-low name, chip as a dashed outline without fill, dashed slots, --text-low caption */
.qz__layer--ghost .qz__name,
.qz__layer--ghost .qz__caption { color: var(--text-low); }
.qz__layer--ghost .qz__status { color: var(--text-low); border: var(--border-dash); }
.qz__layer--ghost [data-t]::before { content: attr(data-t); }
.qz__layer--ghost .qz__name { white-space: nowrap; }
/* final: the pulled liar (--cell-quar-*, the glow belongs to the frame) */
.qz__layer--final .qz__cells i { border: 1px solid var(--cell-quar-edge); background: var(--cell-quar-fill); }
@media (min-width: 1280px) {
  /* a vertical strip 252px: inside 204px: the name in one line (180px), the chip, the last 10 runs as 2 x 5 (136px) */
  .quarantine-track { padding: var(--space-5); }
  .qz__layer { --qz-cols: minmax(0, 1fr); --qz-areas: "name" "status" "cells" "caption"; }
  .qz__cells { width: calc(5 * var(--cell-size) + 4 * var(--cell-gap) + 6px); height: calc(2 * var(--cell-size) + var(--cell-gap) + 6px); flex-wrap: wrap-reverse; align-content: flex-end; }
  .qz__cells i:nth-child(n+11) { display: none; }
}
@media (min-width: 1024px) and (max-width: 1279px) {
  /* the status word (106px) is wider than the grid's 80px status column: it goes under the name */
  .qz__layer { --qz-cols: 320px minmax(0, 1fr); --qz-areas: "name cells" "status caption"; }
  .qz__cells { margin: -3px -3px -3px calc(var(--space-5) - 3px); }
}
@media (min-width: 640px) and (max-width: 1023px) {
  .qz__layer { --qz-cols: minmax(0, 1fr) auto; --qz-areas: "name status" "cells cells" "caption caption"; row-gap: var(--space-2); }
}
@media (max-width: 639px) {
  .quarantine-track { padding: var(--space-4); }
  .qz__layer { --qz-cols: minmax(0, 1fr); --qz-areas: "name" "cells" "status" "caption"; row-gap: var(--space-2); }
}

/* the clones of the flight (created by main.js at the act; none under reduced motion) */
.demo-fly {
  position: absolute;
  left: 0; top: 0;
  margin: 0;
  z-index: 3;
  pointer-events: none;
  transform: translate(0, 0);
  transition: transform var(--extract-fly) var(--extract-fly-ease);
  will-change: transform;
}
.demo-fly.is-flying { transform: translate(var(--fly-dx), var(--fly-dy)); }
.demo-fly.demo-fly--fade { transition: opacity var(--motion-short) var(--ease-inout); }
.demo-fly--text { white-space: nowrap; }

/* the act button (04, «Панель управления»): an amber layer over a neutral --elevated base; after the act the amber
   layer leaves, the label becomes «Quarantined»; the size is set by the original label (sizer), it does not change */
.demo-act {
  position: relative;
  isolation: isolate;
  display: inline-grid;
  background: var(--elevated);
  color: var(--text-inv);
  border: var(--border-hair);
  padding: var(--space-3) var(--space-5);
  transition: transform var(--motion-micro) var(--ease-inout);
}
/* amber layer (::before) and its hover/active layer (::after) sit under the label; they are opacity layers */
.demo-act::before { content: ""; position: absolute; inset: -1px; z-index: -1; border-radius: inherit; background: var(--amber); }
.demo-act::after { content: ""; position: absolute; inset: -1px; z-index: -1; border-radius: inherit; background: var(--amber-hover); opacity: 0; transition: opacity var(--motion-micro) var(--ease-inout); }
.demo-act:not([aria-disabled="true"]):hover::after { opacity: 1; }
.demo-act:not([aria-disabled="true"]):active::after { background: var(--amber-active); opacity: 1; }
.demo-act__sizer { grid-area: 1 / 1; visibility: hidden; }
.demo-act__label { grid-area: 1 / 1; justify-self: center; }
.demo-act:not([aria-disabled="true"]):hover { transform: translateY(-1px); }
.demo-act:focus-visible { outline-color: var(--focus-on-amber); }
.demo-act[aria-disabled="true"] { cursor: default; }
.demo-act[aria-disabled="true"]:focus-visible { outline-color: var(--focus-ring); }

.demo-controls { display: flex; align-items: center; gap: var(--space-5); flex-wrap: wrap; margin-top: var(--space-6); }
.demo-hint { font-family: var(--font-mono); font-size: var(--fs-label); color: var(--text-mid); }
.demo-legend {
  display: flex;
  gap: var(--space-5);
  list-style: none;
  flex-wrap: wrap;
  margin-top: var(--space-5);
  font-family: var(--font-mono);
  font-size: var(--fs-mono-sm);
}
.demo-legend li { display: flex; align-items: baseline; gap: var(--space-2); }
.demo-legend .glyph { font-size: 1em; }
.demo-legend .who { color: var(--text-mid); }

/* Result line: follows the current run of the visible rows (RED only while a visible row shows FAIL);
   after the act the GREEN layer cross-fades in after the flight. */
.demo-result {
  display: grid;
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: var(--border-hair);
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  line-height: var(--lh-mono);
}
.demo-result__now, .demo-result__green { grid-area: 1 / 1; }
.demo-result__now { color: var(--fail); }
.demo-result.is-pass .demo-result__now { color: var(--pass); }
.demo-result__green { color: var(--pass); }
.demo-result__now { transition: opacity var(--motion-short) var(--ease-enter) var(--motion-short); } /* back: GREEN leaves first, then the live line returns */
.demo-scene[data-state="extracted"] .demo-result__now { opacity: 0; transition: opacity var(--motion-short) var(--ease-inout) var(--extract-glow-delay); } /* forward: the old line is gone at t = 560ms, when GREEN starts */
@media (max-width: 639px) { .demo-result { min-height: calc(3 * var(--lh-mono) * 1em + var(--space-5) + 1px); } }
.demo-cta { margin-top: var(--space-6); }

/* =====
   HOW IT WORKS — the timeline ribbon connects the steps:
   horizontal along the four columns on >=1024, vertical with the numbers on the left below
   ===== */
.steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--grid-gutter);
}
.step { display: flex; flex-direction: column; gap: var(--space-3); position: relative; min-width: 0; }
.step__rail {
  display: flex;
  gap: var(--cell-gap);
  height: var(--cell-size);
  overflow: hidden;
  width: calc(100% + var(--grid-gutter)); /* runs on into the next column: one continuous line */
  margin-bottom: var(--space-2);
}
.step:last-child .step__rail { width: var(--cell-size); }
.step__rail i:first-child { opacity: 1; border-color: var(--text-mid); } /* the node of the step */
.step-number { font-family: var(--font-mono); font-size: var(--fs-h3); line-height: 1; color: var(--text-low); }
.step__body { display: flex; flex-direction: column; gap: var(--space-3); }
/* a phrase that stays together while it fits the column, and wraps inside itself when it cannot */
.step h3 .nb-phrase { display: inline-block; max-width: 100%; vertical-align: top; }
.step h3 { text-wrap: balance; font-family: var(--font-body); font-weight: var(--fw-body-semi); font-size: var(--fs-h4); line-height: var(--lh-h4); color: var(--text-hi); }
.step p { font-size: var(--fs-body); color: var(--text-mid); }
.step-ribbon { display: flex; gap: var(--cell-gap); margin-top: var(--space-2); }
.echo-cell {
  margin-left: var(--space-2);
  transform: translateX(0);
  transition: transform var(--motion-medium) var(--ease-extract);
}
.step-ribbon i.q { border-color: var(--cell-quar-edge); background: var(--cell-quar-fill); opacity: 1; box-shadow: var(--glow-amber); }
.step-ribbon.is-echoed .echo-cell { transform: translateX(var(--space-3)); }
.steps-tail { margin-top: var(--space-7); font-family: var(--font-mono); font-size: var(--fs-mono); color: var(--text-mid); }
.steps-tail strong { color: var(--amber); font-weight: var(--fw-mono-bold); }

@media (max-width: 1023px) {
  .steps { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .step {
    display: grid;
    grid-template-columns: 48px minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
    column-gap: var(--space-4);
    row-gap: var(--space-2);
  }
  .step-number { grid-column: 1; grid-row: 1; align-self: start; }
  .step__rail {
    grid-column: 1;
    grid-row: 2;
    flex-direction: column;
    width: var(--cell-size);
    height: auto;
    margin: 0;
    align-self: stretch;
    justify-self: start;
    flex-wrap: wrap; /* whole cells only: what does not fit wraps out of the one-cell-wide clip */
    align-content: flex-start;
    contain: size;
  }
  .step__body { grid-column: 2; grid-row: 1 / span 2; padding-bottom: var(--space-7); }
  .step:last-child .step__rail { display: none; }
  .step:last-child .step__body { padding-bottom: 0; }
}

/* =====
   Q&A panel (Safety, Billing FAQ): >=1024 two columns 6+6 (question left, answer right),
   <1024 an accordion
   ===== */
.qa-panel { background: var(--surface); border: var(--border-hair); border-radius: var(--radius-panel); overflow: hidden; }
.qa-item { border-top: var(--border-soft); }
.qa-item:first-child { border-top: none; }
.qa-item h3 { display: contents; } /* h3 wraps the button for a valid heading order; no box of its own */
.qa-item__question {
  width: 100%;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  background: none;
  border: none;
  text-align: left;
  padding: var(--space-5);
  cursor: default;
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  line-height: var(--lh-mono);
  color: var(--text-hi);
  font-weight: var(--fw-mono-med);
}
.accordion-glyph { flex: none; width: 16px; height: 16px; position: relative; display: none; margin-top: 3px; }
.accordion-glyph::before,
.accordion-glyph::after {
  content: "";
  position: absolute;
  background: var(--text-mid);
  transition: transform var(--motion-short) var(--ease-inout), opacity var(--motion-short) var(--ease-inout);
}
.accordion-glyph::before { left: 0; top: 50%; width: 100%; height: 1.5px; transform: translateY(-50%); }
.accordion-glyph::after { top: 0; left: 50%; width: 1.5px; height: 100%; transform: translateX(-50%); }
.qa-item[data-open="true"] .accordion-glyph::after { transform: translateX(-50%) rotate(90deg); opacity: 0; }
.qa-item[data-open="true"] .accordion-glyph::before { background: var(--amber); }
.qa-item__answer { padding: 0 var(--space-5) var(--space-5); font-size: var(--fs-body); color: var(--text-mid); }
@media (min-width: 1024px) {
  .qa-item { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; }
  .qa-item__question { grid-column: 1; }
  .qa-item__answer { grid-column: 2; padding: calc(var(--space-5) - 2px) var(--space-5) var(--space-5) 0; } /* the answer fills its column (≈ the measure) */
}
@media (max-width: 1023px) {
  .qa-item__question { cursor: pointer; align-items: center; }
  .accordion-glyph { display: block; margin-top: 0; }
  .qa-item__answer { max-width: var(--measure); }
  .qa-item__answer[hidden] { display: none; }
  .qa-item[data-open="true"] { background: var(--elevated); }
}

/* =====
   DASHBOARD — full-bleed --surface band; the module (table / cards) by its own width
   ===== */
.dashboard-section { padding-bottom: var(--section-y); }
.dash-band { background: var(--surface); border-block: var(--border-hair); padding-block: var(--space-6); }
.dash-module { container-type: inline-size; container-name: dash; }
.dash { display: grid; }
/* flakiness column: by the fit of the liar's display figure «40%»: measured 2.2em of --fs-h2 (105px on 1024, 123px on 1440; the
   estimate in 04 was 2.0em), so 2.25em, never narrower than 80px. The extra ~12px of the figure are taken from the status
   (text 108px of 122) and flag (88px of 110) columns: the row on 1024 is 907px of 921 (with a classic scrollbar). */
.dash-row {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: minmax(216px, 1fr) 112px minmax(80px, calc(2.25 * var(--fs-h2))) 276px 100px;
  column-gap: var(--space-4);
  align-items: center;
  padding: var(--space-3) var(--space-4);
  min-height: 64px;
  border-top: var(--border-soft);
}
/* hover = an --elevated layer, opacity (05 #16) */
.dash-row:not(.dash-head)::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--elevated);
  opacity: 0;
  transition: opacity var(--motion-micro) var(--ease-inout);
}
.dash-row:not(.dash-head):hover::before { opacity: 1; }
/* the liar's row is raised: --elevated + a 2px amber edge on the left; its height follows the figure, the others are 64px */
.dash-row.dash-row--liar:not(.dash-head)::before { opacity: 1; }
.dash-row--liar { padding-block: var(--space-2); } /* the row follows the figure: 57px + 2 x 8 = 73px on 1440, 65px on 1024 */
.dash-row--liar::after {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 2px;
  background: var(--amber);
}
.dash-row.dash-head {
  min-height: 0;
  border-top: none;
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--text-mid);
  padding-block: var(--space-3);
}
.dash-name { font-family: var(--font-mono); font-size: var(--fs-mono); line-height: var(--lh-mono); color: var(--text-hi); }
.status-chip {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  white-space: nowrap;
}
.status-chip.is-stable { color: var(--pass); }
.status-chip.is-quarantined { color: var(--amber); }
.dash-flak { font-family: var(--font-mono); font-size: var(--fs-mono); color: var(--text-hi); }
/* the only break of scale between the demo and the final CTA: a display figure inside a product object */
.dash-row--liar .dash-flak {
  font-family: var(--font-display);
  font-weight: var(--fw-display);
  font-size: var(--fs-h2);
  line-height: var(--lh-h2);
  letter-spacing: var(--ls-h2);
  color: var(--text-hi);
}
.dash-flak__lbl { display: none; color: var(--text-mid); font-family: var(--font-mono); font-weight: var(--fw-mono); font-size: var(--fs-mono-sm); letter-spacing: 0; line-height: var(--lh-mono-sm); }
.dash-hist { display: block; }
.dash-hist__cap { display: none; }
/* sparkline: 20 cells; in the table 10px wide (20 x 14 - 4 = 276px), in a card 100% of its inner width */
.sparkline { display: grid; grid-template-columns: repeat(20, 10px); gap: var(--cell-gap); width: 276px; }
/* register of DATA: filled cells + a 1px edge; the last run of the row is lit (no glow); the liar's runs 11-20 that failed in
   isolation (q) are an amber EDGE without fill, without lit, without glow («after the quarantine») */
.sparkline i {
  display: block;
  height: var(--cell-size);
  border-radius: var(--radius-cell);
  border: 1px solid var(--cell-pass-data-edge);
  background: var(--cell-pass-data);
}
.sparkline i.f { border-color: var(--cell-fail-data-edge); background: var(--cell-fail-data); }
.sparkline i.lit { background: var(--cell-pass-lit); border-color: var(--cell-pass-lit); }
.sparkline i.f.lit { background: var(--cell-fail-lit); border-color: var(--cell-fail-lit); }
.sparkline i.q { border-color: var(--cell-quar-edge); background: transparent; }
.fix-first-flag {
  position: relative;
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--amber);
  white-space: nowrap;
  cursor: help;
}
.flag-tip {
  position: absolute;
  bottom: calc(100% + var(--space-2));
  right: 0;
  z-index: var(--z-tooltip);
  width: max-content;
  max-width: min(280px, 80vw);
  white-space: normal;
  background: var(--surface);
  border: var(--border-hair);
  border-radius: var(--radius-cell);
  padding: var(--space-2) var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--fs-mono-sm);
  line-height: var(--lh-mono-sm);
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-hi);
  opacity: 0;
  transform: translateY(4px);
  transition: opacity var(--motion-micro) var(--ease-enter), transform var(--motion-micro) var(--ease-enter);
  pointer-events: none;
}
.fix-first-flag:hover .flag-tip,
.fix-first-flag:focus-visible .flag-tip { opacity: 1; transform: translateY(0); }
.dash-caption { padding: var(--space-4) var(--space-4) 0; font-family: var(--font-mono); font-size: var(--fs-mono-sm); color: var(--text-mid); border-top: var(--border-soft); }

/* card layout: a module narrower than 900px (the width of the module, not of the viewport) */
@container dash (max-width: 919.98px) {
  .dash { gap: var(--space-4); }
  .dash-row.dash-head { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); padding: 0; white-space: nowrap; }
  .dash-row:not(.dash-head) {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-3);
    padding: var(--space-4);
    border: var(--border-soft);
    border-radius: var(--radius-card);
  }
  .dash-name { flex: 0 0 100%; order: 0; }
  .status-chip { order: 1; }
  .dash-fix { order: 2; }
  .dash-fix:empty { display: none; }
  .dash-flak { order: 3; flex: 0 0 100%; }
  .dash-flak__lbl { display: inline; }
  .dash-hist { order: 4; flex: 0 0 100%; }
  .sparkline { grid-template-columns: repeat(20, minmax(0, 1fr)); width: 100%; }
  /* in a card the tip spans the card (anchored to the card, never past its edges) */
  .dash-row:not(.dash-head) { position: relative; }
  .dash-row:not(.dash-head)::before { border-radius: inherit; }
  .dash-row--liar::after { border-radius: var(--radius-card) 0 0 var(--radius-card); }
  .fix-first-flag { position: static; }
  .flag-tip { left: var(--space-4); right: var(--space-4); width: auto; max-width: none; bottom: calc(100% + var(--space-2)); }
  .dash-hist__cap { display: block; margin-top: var(--space-2); font-family: var(--font-mono); font-size: var(--fs-mono-sm); color: var(--text-mid); }
  .dash-caption { padding: var(--space-4) 0 0; border-top: none; }
}

/* =====
   PRICING — volume meter (04 «Метр объёма»), plan cards (Home teaser, Pricing mobile)
   ===== */
.meter { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--cell-gap); height: 10px; width: 100%; }
.meter i { display: block; border-radius: var(--radius-cell); border: 1px solid var(--hairline-soft); }
.meter i.on { background: var(--text-low); border-color: var(--hairline); }
.is-free .meter i.on { border-color: var(--amber); }

.plan-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--grid-gutter); }
@media (max-width: 767px) { .plan-grid { grid-template-columns: minmax(0, 1fr); } }
.plan-card {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  background: var(--surface);
  border: var(--border-hair);
  border-radius: var(--radius-card);
  padding: var(--space-5);
  transition: transform var(--motion-micro) var(--ease-inout);
}
/* hover = an --elevated layer (opacity) + lift */
.plan-card::before { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; background: var(--elevated); opacity: 0; transition: opacity var(--motion-micro) var(--ease-inout); }
.plan-card:hover { transform: translateY(-2px); }
.plan-card:hover::before { opacity: 1; }
.plan-card.is-free { border-color: var(--amber); }
.plan-card__name { font-family: var(--font-body); font-weight: var(--fw-body-semi); font-size: var(--fs-h4); line-height: var(--lh-h4); color: var(--text-hi); }
.plan-card__volume { font-family: var(--font-mono); font-size: var(--fs-mono-sm); color: var(--text-mid); }
/* the voice of the price is ONE for the whole site: display type at the h3 step, --text-hi, amber at Free (cards on Home and Pricing, table) */
.plan-card__price,
.pricing-table .pricing-table__price td { font-family: var(--font-display); font-weight: var(--fw-display); font-size: var(--fs-h3); line-height: var(--lh-h3); letter-spacing: var(--ls-h3); color: var(--text-hi); }
.plan-card.is-free .plan-card__price,
.pricing-table .pricing-table__price td.is-free-col { color: var(--amber); }
.pricing-teaser-foot { margin-top: var(--space-6); display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-4); flex-wrap: wrap; }
.pricing-teaser-foot p { color: var(--text-mid); font-size: var(--fs-small); max-width: var(--measure); }

/* =====
   INTEGRATIONS — the lower tier of the Pricing teaser (--space-7 below it, no ribbon between them).
   The heading states only what works; two LIVE plates (6+6 on >=1024, full width stacked below), solid and large,
   their content fills the width: left a node dot (--text-hi, never pass-green) + the name (mono, h3 step), right the
   provider's own line. The second-tier decision is ONE for the pair: both plates carry identical min-widths in `ch`
   (mono: 0.6em per glyph) of the LONGER content, so they wrap together or not at all, in a row of one height.
   ===== */
.integrations-tier { margin-top: var(--space-7); }
.tier-title {
  font-family: var(--font-display);
  font-weight: var(--fw-display);
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  letter-spacing: var(--ls-h3);
  word-spacing: var(--ws-display);
  color: var(--text-hi);
  text-wrap: balance;
}
.integrations-tier .section-lead { margin-top: var(--space-3); }
.integrations-pair {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--grid-gutter);
  margin-top: var(--space-6);
}
@media (max-width: 1023px) { .integrations-pair { grid-template-columns: minmax(0, 1fr); } }
.integration-node {
  background: var(--surface);
  border: var(--border-hair);
  border-radius: var(--radius-card);
  padding: var(--space-5);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2) var(--space-5);
}
.integration-node__id {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  min-width: calc(8px + var(--space-3) + 14ch);   /* dot + gap + the longer name (GitHub Actions, 14 glyphs) */
  font-family: var(--font-mono);
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  color: var(--text-hi);
}
.node-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-hi); flex: none; }
.integration-node__line {
  min-width: 21ch;                                 /* the longer provider line (Watches workflow runs, 21 glyphs) */
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  line-height: var(--lh-mono);
  color: var(--text-mid);
}

/* =====
   FINAL CTA — a band on ink: ribbons are the top and bottom edges (full-bleed), >=1024 a static
   far field between them (fades towards the text block), the button never touches a ribbon
   ===== */
.final-cta { display: flex; flex-direction: column; background: var(--ink); text-align: center; overflow: hidden; }
.final-cta--surface { background: var(--surface); }
.final-cta__ribbon { flex: none; position: relative; z-index: 2; }
.final-cta__inner {
  position: relative;
  z-index: 2;
  padding-block: clamp(3rem, 1rem + 4vw, 6rem);
  overflow: hidden; /* the soft plate under the text stays between the ribbons */
}
.cta-block { position: relative; display: inline-block; max-width: 100%; }
.final-cta h2 {
  font-family: var(--font-display);
  font-weight: var(--fw-display);
  font-size: var(--fs-h2);
  line-height: var(--lh-h2);
  letter-spacing: var(--ls-h2);
  word-spacing: var(--ws-display);
  color: var(--text-hi);
  text-wrap: balance;
}
.final-cta h2 .l { display: block; }
.final-cta h2 .is-fail-word { color: var(--fail); }
.cta-lead { margin-top: var(--space-4); font-size: var(--fs-body-lg); line-height: var(--lh-body-lg); color: var(--text-mid); text-wrap: balance; }
.final-cta .btn--primary { margin-top: var(--space-6); font-size: var(--fs-body-lg); padding: var(--space-4) var(--space-7); }
@media (max-width: 639px) {
  .final-cta .btn--primary { width: 100%; white-space: normal; text-align: center; text-wrap: balance; justify-content: center; padding-inline: var(--space-5); }
}
/* static field (Home only, >=1024); no flicker, no glow, no canvas. State «after» (the liar is pulled): a FAIL position is an
   isolated run: a 1px --cell-quar-edge, no fill, no red. The edge lives at the opacity of the layer (--cell-on). */
.cta-field, .connect-band { --cw: var(--field-far-cell); --cell-on: calc(var(--field-far-opacity) * var(--field-rest)); filter: saturate(var(--field-far-saturate)); }
.cta-field { display: none; position: absolute; left: 0; right: 0; top: var(--cell-size); bottom: var(--cell-size); overflow: hidden; z-index: 1; flex-direction: column; gap: var(--cell-gap); }
.cta-field i, .connect-band i {
  display: block;
  flex: none;
  width: var(--cw);
  height: var(--cw);
  border-radius: var(--radius-cell);
  background: color-mix(in srgb, rgb(61 224 138) calc(var(--cell-on) * 85%), var(--field-body));
}
.cta-field i.q, .connect-band i.q {
  background: transparent;
  border: 1px solid var(--cell-quar-edge);
  opacity: var(--cell-on);
}
@media (min-width: 1024px) {
  .cta-field { display: flex; }
  /* the field falls away towards the text block: an elliptical halo, no straight edges; the field is back to
     rest >= --space-9 from the text bbox + --space-7 (04 «Финальная CTA») */
  .final-cta:not(.final-cta--surface) .cta-block::before {
    --pad: calc(var(--space-7) + var(--space-9));
    content: "";
    position: absolute;
    z-index: -1;
    pointer-events: none;
    inset: calc(-1 * var(--pad));
    background: var(--ink);
    -webkit-mask-image: radial-gradient(closest-side, #000 0, #000 40%, rgba(0,0,0,.896) 52%, rgba(0,0,0,.648) 64%, rgba(0,0,0,.352) 76%, rgba(0,0,0,.106) 88%, transparent 100%);
    mask-image: radial-gradient(closest-side, #000 0, #000 40%, rgba(0,0,0,.896) 52%, rgba(0,0,0,.648) 64%, rgba(0,0,0,.352) 76%, rgba(0,0,0,.106) 88%, transparent 100%);
  }
}

/* ---------- Footer ---------- */
.site-footer { padding-block: var(--space-8); border-top: var(--border-hair); }
.footer-grid { display: flex; flex-direction: column; row-gap: var(--space-6); }
.footer-top { display: flex; align-items: center; justify-content: space-between; column-gap: var(--space-7); }
.footer-legal {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  column-gap: var(--space-5);
}
.footer-nav ul { display: flex; gap: var(--space-5); list-style: none; }
.footer-nav a { font-family: var(--font-mono); font-size: var(--fs-mono-sm); color: var(--text-mid); text-decoration: none; position: relative; }
.footer-nav a:hover { color: var(--text-hi); }
.footer-disclaimer { min-width: 0; font-family: var(--font-body); font-size: var(--fs-small); line-height: var(--lh-small); letter-spacing: var(--ls-small); color: var(--text-mid); }
.footer-disclaimer span { display: inline-block; }
.footer-year { flex: none; font-family: var(--font-mono); font-size: var(--fs-mono-sm); line-height: var(--lh-mono-sm); letter-spacing: var(--ls-mono-sm); color: var(--text-mid); }
/* < 1024: wordmark -> nav -> note -> year, stack, left-aligned (04, Footer) */
@media (max-width: 1023px) {
  .footer-top { flex-direction: column; align-items: flex-start; row-gap: var(--space-3); }
  .footer-legal { flex-direction: column; align-items: flex-start; row-gap: var(--space-2); }
}

/* =====
   PRICING PAGE
   ===== */
.page-title { text-wrap: balance; }
.pricing-hero { padding-top: var(--section-y); }
.section-pad--tight { padding-block: var(--space-7); }
/* 404: the footer sits at the bottom of the screen; the link and the CTA are separated by one step of the scale */
.page-not-found { display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh; }
.page-not-found main { flex: 1; }
.not-found-cta { margin-top: var(--space-5); }
.billing-faq-section { padding-block: var(--space-7) var(--section-y); }
.pricing-table-note { margin-top: var(--space-4); font-family: var(--font-mono); font-size: var(--fs-mono-sm); color: var(--amber); }

.pricing-table {
  width: 100%;
  table-layout: fixed;
  border-collapse: separate;
  border-spacing: 0;
  background: var(--surface);
  border: var(--border-hair);
  border-radius: var(--radius-panel);
  overflow: hidden;
}
@media (max-width: 1023px) { .pricing-table-desktop { display: none; } }
@media (min-width: 1024px) { .pricing-mobile { display: none; } }
.pricing-table th,
.pricing-table td {
  text-align: left;
  vertical-align: top;
  padding: var(--space-4) var(--space-5);
  border-top: var(--border-soft);
  font-size: var(--fs-body);
}
.pricing-table thead th {
  border-top: none;
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--text-mid);
  font-weight: var(--fw-mono-med);
}
.plan-col__name { display: block; }
.plan-col .meter { margin-top: var(--space-3); }
.plan-col__limit { display: block; margin-top: var(--space-2); font-family: var(--font-mono); font-size: var(--fs-mono-sm); letter-spacing: 0; text-transform: none; color: var(--text-mid); }
.pricing-table thead th.is-free .plan-col__name { color: var(--amber); }
/* Free column: one closed 1px --amber frame (04, Pricing tokens). Real cell borders on a separate-border table (a collapsed table
   straddles borders over its edge and the rounded overflow clips them). top = header cell, bottom = last (price) row. */
.pricing-table thead th.is-free { border-top: 1px solid var(--amber); border-left: 1px solid var(--amber); border-right: 1px solid var(--amber); }
.pricing-table td.is-free-col { border-left: 1px solid var(--amber); border-right: 1px solid var(--amber); }
.pricing-table tbody tr:last-child td.is-free-col { border-bottom: 1px solid var(--amber); }
.pricing-table tbody th { font-weight: var(--fw-body-med); color: var(--text-hi); }
.pricing-table tbody tr:hover { background: var(--elevated); } /* instant: a table row cannot carry a layer; nothing animates here */
.pricing-table td { color: var(--text-hi); font-family: var(--font-mono); font-size: var(--fs-mono); }
.pricing-table .pass-glyph { color: var(--text-hi); font-size: 1em; }
.pricing-table__price th, .pricing-table__price td { vertical-align: middle; }

.pricing-mobile__cards { display: grid; gap: var(--space-4); }
.pricing-mobile .eyebrow { margin-top: var(--space-6); }
.pricing-mobile__features { margin-top: var(--space-5); border: var(--border-hair); border-radius: var(--radius-card); padding: var(--space-4) var(--space-5); }
.pricing-mobile__features summary { cursor: pointer; font-family: var(--font-mono); font-size: var(--fs-mono); color: var(--text-hi); }
.pricing-mobile__features-note { margin-top: var(--space-3); color: var(--amber); font-size: var(--fs-small); }
.pricing-mobile__features ul { margin-top: var(--space-3); list-style: none; display: grid; gap: var(--space-2); }
.pricing-mobile__features li { display: flex; align-items: baseline; gap: var(--space-2); font-size: var(--fs-body); color: var(--text-mid); }
.pricing-mobile__features li .pass-glyph { color: var(--text-hi); font-family: var(--font-mono); }
.parity-note { font-size: var(--fs-body-lg); color: var(--text-hi); text-align: center; max-width: var(--measure); margin-inline: auto; text-wrap: pretty; }

/* =====
   CONNECT PAGE
   ===== */
.connect-header .header-inner { justify-content: flex-start; } /* in the flow, no line, no condensing, no CTA (the flow is the CTA) */
.connect-back { display: inline-flex; align-items: center; gap: var(--space-2); }

.connect-main { position: relative; padding-bottom: var(--space-8); } /* height follows the content of the current step */
/* Field band: full-bleed, right under the header, WHOLE rows only: n = floor((clamp(56px, 8vw, 96px) + 4) / pitch),
   height n x pitch - 4 (>=640 pitch 28: 2 rows = 52px, 3 rows = 80px from 1000px; <640 pitch 20: 3 rows = 56px);
   the bottom row fades into ink. The panel of the first step starts --space-6 below the band. */
.connect-band { --cw: var(--cell-size); --cell-on: var(--field-far-opacity); /* 0.20, no --field-rest: twice the rest of the hero's far layer */ display: flex; flex-direction: column; gap: var(--cell-gap); position: relative; overflow: hidden; height: 56px; pointer-events: none; }
.connect-band::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: calc(var(--cell-size) + var(--cell-gap));
  background: linear-gradient(to bottom, transparent, var(--ink));
}
@media (min-width: 640px) { .connect-band { height: 52px; } }
@media (min-width: 1000px) { .connect-band { height: 80px; } }

.connect-shell { position: relative; z-index: var(--z-content); max-width: 640px; margin: var(--space-6) auto 0; }
.connect-step {
  background: var(--surface);
  border: var(--border-hair);
  border-radius: var(--radius-panel);
  padding: var(--space-6);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity var(--motion-medium) var(--ease-enter), transform var(--motion-medium) var(--ease-enter);
}
@media (max-width: 639px) { .connect-step { padding: var(--space-5); } }
.connect-step[hidden] { display: none; }
.connect-step.is-active { opacity: 1; transform: translateY(0); }
.connect-step h1,
.connect-step h2 {
  font-family: var(--font-display);
  font-weight: var(--fw-display);
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  letter-spacing: var(--ls-h3);
  word-spacing: var(--ws-display);
  color: var(--text-hi);
  text-wrap: balance;
}
.connect-step .lead { margin-top: var(--space-4); font-size: var(--fs-body-lg); line-height: var(--lh-body-lg); color: var(--text-mid); }

.provider-list { display: grid; gap: var(--space-3); margin-top: var(--space-6); border: none; padding: 0; }
.provider-card {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  background: var(--surface);
  border: var(--border-hair);
  border-radius: var(--radius-card);
  padding: var(--space-4) var(--space-5);
  cursor: pointer;
}
/* hover / selected = layers (05 #20): --elevated and the amber frame fade by opacity */
.provider-card::before,
.provider-card::after { content: ""; position: absolute; pointer-events: none; border-radius: inherit; opacity: 0; transition: opacity var(--motion-micro) var(--ease-inout); }
.provider-card::before { inset: 0; z-index: -1; background: var(--elevated); }
.provider-card::after { inset: -1px; border: 1px solid var(--amber); }
.provider-card:hover::before,
.provider-card:has(.provider-card__radio:checked)::before,
.provider-card:has(.provider-card__radio:checked)::after { opacity: 1; }
.provider-card:focus-within { outline: var(--focus-width) solid var(--focus-ring); outline-offset: var(--focus-offset); }
.provider-card__radio {
  appearance: none;
  width: 18px; height: 18px;
  flex: none;
  border-radius: 50%;
  border: 1px solid var(--hairline);
  background: var(--surface);
  position: relative;
  margin: 0;
}
.provider-card__radio:focus-visible { outline: none; }
.provider-card__radio::after {
  content: "";
  position: absolute;
  inset: 4px;
  border-radius: 50%;
  background: var(--amber);
  transform: scale(0);
  transition: transform var(--motion-short) var(--ease-enter);
}
.provider-card__radio:checked { border-color: var(--amber); }
.provider-card__radio:checked::after { transform: scale(1); }
.provider-card__label { font-family: var(--font-mono); font-size: var(--fs-mono); color: var(--text-hi); }
.provider-more { margin-top: var(--space-4); font-family: var(--font-mono); font-size: var(--fs-mono-sm); color: var(--text-mid); }

.connect-actions { margin-top: var(--space-6); display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap; }
.connect-actions .btn[disabled],
.connect-actions .btn[aria-disabled="true"],
.connect-shell:not(:has(input[name="provider"]:checked)) #providerContinue { background: var(--elevated); color: var(--text-low); cursor: not-allowed; pointer-events: none; }
.connect-actions .btn[disabled]::before,
.connect-actions .btn[aria-disabled="true"]::before,
.connect-shell:not(:has(input[name="provider"]:checked)) #providerContinue::before { display: none; }
.connect-hint { font-family: var(--font-mono); font-size: var(--fs-mono-sm); color: var(--text-mid); width: 100%; }
.connect-hint[hidden],
.connect-shell:has(input[name="provider"]:checked) .connect-hint { display: none; }
/* the provider named in «Authorize …» follows the radio (state of the page, with or without JS) */
.prov { display: none; }
.connect-shell:has(#prov-github:checked) .prov--github,
.connect-shell:has(#prov-gitlab:checked) .prov--gitlab,
.connect-shell:not(:has(input[name="provider"]:checked)) .prov--none { display: inline; }
.nojs-only { display: none; }
.link-quiet[aria-disabled="true"] { pointer-events: none; opacity: 0.5; }
.connect-caption { margin-top: var(--space-4); font-family: var(--font-mono); font-size: var(--fs-mono-sm); color: var(--text-mid); }

/* Authorize: waiting row that burns amber cell by cell, not a generic spinner */
.authorize-progress { margin-top: var(--space-6); }
.authorize-progress[hidden] { display: none; }
.auth-row { display: flex; gap: var(--cell-gap); }
.auth-cell .cell-layer--quar {
  animation-name: authBurn;
  animation-duration: 1.4s;
  animation-iteration-count: infinite;
  animation-timing-function: var(--ease-inout);
  animation-delay: calc(var(--stagger-cell) * var(--i, 0));
}
@keyframes authBurn { 0%, 55% { opacity: 0; } 70%, 92% { opacity: 1; } 100% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .auth-cell .cell-layer--quar { opacity: 1 !important; } }

/* Analyzing: progress-scan grid, fills in step with the real counter */
.analyzing-grid { display: flex; flex-wrap: wrap; gap: var(--cell-gap); margin-top: var(--space-6); }
.scan-cell { transition: opacity var(--motion-short) var(--ease-inout); }
.scan-cell[data-state="empty"] { background: transparent; border: var(--border-dash); }
.connect-mono { margin-top: var(--space-4); font-family: var(--font-mono); font-size: var(--fs-mono); color: var(--text-hi); }

/* Result branches */
.connect-result { text-align: left; }
.result-accent {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px; height: 40px;
  border-radius: 50%;
  font-size: 1.3rem;
  margin-bottom: var(--space-4);
}
.result-accent.is-pass-accent { background: var(--cell-pass-fill); color: var(--pass); }
.result-accent.is-fail-accent { background: var(--cell-fail-fill); color: var(--fail); }
.connect-result.is-error { border-color: var(--fail); background: var(--state-error-bg); }
/* the report module is the Dashboard module: inside this narrow flow it is always the card stack
   (the module chooses by its own width, not the viewport's) */
.connect-report-panel { margin-top: var(--space-6); }
.connect-report-panel .dash-module { padding: 0; }
.connect-summary { margin-top: var(--space-4); font-family: var(--font-mono); font-size: var(--fs-mono-sm); color: var(--text-mid); }
.connect-result-links { margin-top: var(--space-5); display: flex; gap: var(--space-5); flex-wrap: wrap; }

/* =====
   WITHOUT SCRIPT (@media (scripting: none)). Nothing here changes what is visible with JS; it only makes the
   target action walkable: the Connect flow is steps of one page addressed by :target (every control of the flow is a
   real link to the next step), the report ready / no flakes / error branches are reachable at #step-result-*;
   the mobile menu is a plain list under the header.
   ===== */
@media (scripting: none) {
  .nojs-only { display: inline-flex; }
  .connect-step[hidden]:target,
  .connect-step:target { display: block; opacity: 1; transform: none; }
  .connect-shell:has(.connect-step:not(#step-provider):target) #step-provider { display: none; }
  .connect-step { scroll-margin-top: var(--space-5); }
  .menu-toggle { display: none !important; }
}
@media (scripting: enabled) { .demo-controls { min-height: 2.67rem; } } /* the controls are unwrapped by main.js: the room is held */
@media (scripting: enabled) and (max-width: 639px) { .demo-tabs { min-height: 2.18rem; } }
@media (scripting: none) { /* the demo shows its finished state (the extracted liar, GREEN); its controls are not in the DOM; cells are not focusable */
  .demo-tabs, .demo-controls, .demo-result__now { display: none; }
  .demo-row__trace, .quarantine-final, .demo-result__green, .quarantine-track::after { opacity: 1; }
  .ghost-cover, .ghost-keep, .quarantine-track::before { opacity: 0; }
  [data-liar] > .demo-name, [data-liar] > .demo-track, [data-liar] > .demo-status, .cell--demo { visibility: hidden; }
  .demo-grid__row:not([data-liar]) .cell-layer, .test-card__track .cell-layer { visibility: visible; } /* the cell is not focusable, its layers still draw */
}
@media (scripting: none) and (max-width: 639px) { .demo-grid__row:not(.is-current) { display: grid; } }
@media (scripting: none) and (not all and (min-width: 640px)) {
  .mobile-nav[hidden] { display: block; position: static; z-index: auto; border-block: var(--border-hair); }
}

/* ---------- Reduced motion (components; the 05 block lives in tokens.css verbatim) ---------- */
@media (prefers-reduced-motion: reduce) {
  .hero-field .field-layer .cell-layer { animation: none !important; }
  .demo-fly { display: none !important; }
}
