/* ============================================================================
   The Cortal landing page format, in the Thinking Machines type system.
   Layered on styles.css. Served at cortal.ai from apps/landing/public.

   THREE TYPE ROLES, and the third is the interesting one:
     serif (Iowan)        display + prose. Carries all the weight.
     sans  (Switzer)      chrome, labels, UI, body-in-panels.
     Chakra Petch         replaces Geist Mono for technical labels: timestamps,
                          source lines, indices, the big stat. It is squarish
                          and tabular enough to read as "machine", and it is
                          already the reference site's own display face, so the
                          page stays in one family of shapes instead of
                          importing a fourth unrelated typeface.

   TWO RULES THIS FILE ENFORCES, both learned the hard way:

     1. NOTHING IS SIZED BY BREAKPOINT ALONE. Every type size and every gutter
        is a two-point fluid function whose floor engages below 300px, so a
        phone at 360px is visibly smaller than a phone at 430px. The previous
        version bottomed out every clamp at ~515px, which made a phone look
        like a squeezed desktop.
     2. ONE MAJOR SECTION PER VIEWPORT. Vertical padding scales with window
        height (`vh`), the hero fills the first screen, and story sections
        take at least a full viewport so three chapters never stack in one
        frame. Content can still grow past 100svh; short transitional bands
        (`.l-section--thin`) stay content-tall.
   ========================================================================= */

@font-face {
  font-family: 'Chakra Petch';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('./assets/fonts/chakra-petch/chakra-petch-v12-latin-regular.woff2') format('woff2');
}

:root {
  --font-mono: 'Chakra Petch', ui-monospace, SFMono-Regular, monospace;
  /* Cortal's brand orange, kept for hover only. The reference site uses no
     accent at all on its homepage; one restrained use is the compromise. */
  --accent: #f97518;
  --rule: color-mix(in srgb, var(--fg4) 16%, var(--bg) 84%);
  --shell-max: 1440px;

  /* Fluid gutter: 22px on the smallest phone, 120px from 1500px up. One
     function, no breakpoint steps, so nothing snaps as the window drags. */
  --shell-pad: clamp(20px, 8.34vw - 5px, 120px);
  /* Landing nav chrome height. Matches `.l-nav-inner` (60px default, 64px
     from 768px up). One token for scroll-padding and the hero offset. */
  --l-nav-h: 60px;
  /* Vertical rhythm between sections. Tracks the window HEIGHT so a tall
     desktop gets real air and a short laptop stays usable. Floor ~72px on
     phones; ~12vh mid-range; cap keeps ultrawides from turning into voids. */
  --sec-pad: clamp(72px, 12vh, 168px);
  /* Gap between prose column and device column, shared with the fit maths. */
  --aside-gap: clamp(40px, 4.5vw, 88px);
  /* Width available to a full-shell display line. 0.985 pays for the
     scrollbar that 100vw pretends does not exist. */
  --fit-avail: calc((min(100vw, var(--shell-max)) - 2 * var(--shell-pad)) * 0.985);

  /* Type scale. Each is linear between two real design sizes:
       display  28px @360  →  56px @1440
       h2       23px @360  →  44px @1440
       pull     19px @360  →  34px @1440
       body     15px @360  →  17px @1440
     Floors sit below 300px so the fluid range covers every phone. */
  --t-display: clamp(1.5rem, 1.167rem + 2.593vw, 3.5rem);
  --t-h2: clamp(1.28rem, 1rem + 1.944vw, 2.75rem);
  --t-pull: clamp(1.1rem, 0.875rem + 1.389vw, 2.125rem);
  --t-body: clamp(0.9rem, 0.896rem + 0.185vw, 1.0625rem);
  --t-panel: clamp(0.8125rem, 0.8rem + 0.1vw, 0.875rem);
}

/* The landing page is its own layout: no 660px article column. */
body.landing #wrapper { padding: 0; }
body.landing #main {
  max-width: none;
  padding: 0;
  margin: 0;
  display: block;
}

/* --- Nav ---------------------------------------------------------------- */

.l-nav {
  position: fixed;
  inset-inline: 0;
  top: 0;
  z-index: 50;
  border-bottom: 1px solid transparent;
  background: rgba(255, 255, 255, 0);
  transition: background-color 300ms ease, border-color 300ms ease;
}
/* Solid, not frosted. A translucent + blurred bar smears whatever scrolls
   under it into a grey smudge, which reads as muddy against a design whose
   whole argument is crispness. The reference site's header is opaque `--bg`
   with a hairline; same here. */
.l-nav.is-scrolled {
  border-bottom-color: var(--rule);
  background: var(--bg);
}
.l-nav-inner {
  margin: 0 auto;
  display: flex;
  height: 60px;
  width: 100%;
  max-width: var(--shell-max);
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-inline: clamp(16px, 3vw, 40px);
}
@media (min-width: 768px) {
  :root { --l-nav-h: 64px; }
  .l-nav-inner { height: 64px; }
}

/* The canonical Cortal lockup: 3-bar mark + "Cortal" in Geist semibold.
   Ratios from the brand spec (apps/landing V2Wordmark · Paper node OI-0):
   mark = 76.67% of font size, gap = 11.67%, mark drops 5% below the baseline.
   Monochrome via currentColor. Never a typed placeholder wordmark. */
@font-face {
  font-family: 'Geist';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('./assets/fonts/geist/Geist-SemiBold.woff2') format('woff2');
}
.l-wordmark {
  display: inline-flex;
  align-items: baseline;
  gap: 0.1167em;
  font-family: 'Geist', var(--font-sans);
  font-weight: 600;
  font-size: clamp(16px, 15px + 0.3vw, 18px);
  line-height: 1;
  letter-spacing: -0.04em;
  color: #0a0a0a;
  text-decoration: none;
  flex-shrink: 0;
}
.l-wordmark .l-mark {
  width: 0.7667em;
  height: 0.7667em;
  flex-shrink: 0;
  margin-bottom: -0.05em;
}
.l-nav-links { display: flex; align-items: center; gap: clamp(18px, 2.4vw, 40px); }
.l-nav-links a {
  font-family: var(--font-sans);
  font-size: clamp(13.5px, 13px + 0.15vw, 15px);
  letter-spacing: -0.01em;
  color: var(--fg1);
  text-decoration: none;
  white-space: nowrap;
  transition: color 200ms ease;
  /* The bar is 60px tall; the links should be tappable through most of it. */
  padding-block: 14px;
}
.l-nav-links a:hover { color: var(--fg); text-decoration: underline; text-underline-offset: 2px; }
.l-nav-cta { display: inline-flex; align-items: center; gap: 6px; color: var(--fg) !important; }
.l-nav-cta .arrow { transition: transform 300ms cubic-bezier(0.16, 1, 0.3, 1); }
.l-nav-cta:hover .arrow { transform: translateX(2px); }
/* Measured, not assumed: mark + both links + the action fit down to ~380px
   with the tightened gap. Below that only the mark and the one action that
   matters survive, because a wrapped nav bar is worse than a shorter one. */
@media (max-width: 419px) { .l-nav-links { gap: 15px; } }
@media (max-width: 379px) { .l-nav-link { display: none; } }

/* --- Section shell ------------------------------------------------------ */

/* Snap is PROXIMITY, not mandatory: each major section owns roughly one
   viewport, so settling near a boundary lands on a chapter start without
   hijacking a mid-section scroll. scroll-padding keeps a snapped (or
   anchor-jumped) section top out from under the fixed nav; smooth behaviour
   comes from styles.css and gives the settle its animation. */
html {
  scroll-snap-type: y proximity;
  scroll-padding-top: var(--l-nav-h);
}
.l-section {
  width: 100%;
  border-top: 1px solid var(--rule);
  scroll-snap-align: start;
}
.l-section:first-of-type { border-top: 0; }
/* Story sections fill the window when their content is shorter than it.
   Overflow still grows naturally: this is a floor, not a cage. Thin bands
   stay content-tall so they remain transitional. */
.l-section:not(.l-section--thin) {
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  box-sizing: border-box;
}
.l-shell {
  margin: 0 auto;
  width: 100%;
  max-width: var(--shell-max);
  padding: var(--sec-pad) var(--shell-pad);
  box-sizing: border-box;
}
.l-section--thin .l-shell { padding-block: clamp(48px, 6vh, 96px); }

/* Prose inside a section keeps the reference's 660px measure. Wide sections
   are for structure; reading always happens at 660. */
.l-prose { max-width: 660px; }
/* Reading voice is the sans, as on the product page. The serif is reserved
   for display lines, section heads, and pull quotes. */
.l-prose p {
  font-family: var(--font-sans);
  font-size: var(--t-body);
  line-height: 1.65;
  color: color-mix(in srgb, var(--fg) 80%, var(--bg));
  margin: 0 0 1.5rem;
}
.l-prose p:last-child { margin-bottom: 0; }

/* --- Display type ------------------------------------------------------- */

/* The one big move on the page. Serif, because the sans is doing label work
   and a 72px grotesk would fight the reference's whole personality. */
.l-display {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: var(--t-display);
  line-height: 1.14;
  letter-spacing: -0.015em;
  color: var(--fg);
  margin: 0;
  max-width: 19ch;
  text-wrap: balance;
  --fit-cap: var(--t-display);
  --fit-floor: 1.45rem;
}

/* --- Line structure ------------------------------------------------------
   A display line must end where a reader would pause, never where the box
   happens to run out. Three rules make that hold at every width:

     .ln   one intended line (usually one sentence). display:block, so the
           break after it is ours, not the layout's.
     .ph   a phrase inside a long line. inline-block, so if the line ever has
           to wrap (floor size on a narrow phone, fallback font), it can only
           break BETWEEN phrases, never mid-phrase.
     .l-fit sizes the type from the content: --lw is the measured em-width of
           the element's longest intended line (probed in Chromium at 100px,
           +1.5% safety), and the font shrinks below its cap only as far as
           that line needs, never below the floor. Above the floor every .ln
           is exactly one rendered line; at the floor, phrases take over.

   No JS, so it holds with scripts off and never flashes.

   .l-fit is doubled (.l-fit.l-fit) on purpose: .l-h2 and .l-pull are defined
   AFTER this block and set max-width/font-size at the same single-class
   specificity, so without the bump the 24ch box cap would win the tie and
   hand line breaking back to the layout, which is the exact bug this block
   exists to kill. */
.ln { display: block; }
.ph { display: inline-block; }
.l-fit.l-fit {
  max-width: none;
  font-size: clamp(var(--fit-floor, 1rem), calc(var(--fit-avail, 1200px) / var(--lw, 0.001)), var(--fit-cap, 3rem));
}
.l-display--sub {
  display: block;
  margin-top: 1.15rem;
  font-family: var(--font-sans);
  font-size: var(--t-body);
  line-height: 1.6;
  letter-spacing: 0;
  color: color-mix(in srgb, var(--fg) 72%, var(--bg));
  max-width: 48ch;
  text-wrap: pretty;
}

.l-h2 {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: var(--t-h2);
  line-height: 1.14;
  letter-spacing: -0.02em;
  color: var(--fg);
  margin: 0;
  max-width: 24ch;
  text-wrap: balance;
  --fit-cap: var(--t-h2);
  --fit-floor: 1.26rem;
}

/* Italic serif pull-line: the reference uses italic serif for emphasis
   rather than a heavier weight. */
.l-pull {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  font-size: var(--t-pull);
  line-height: 1.2;
  letter-spacing: -0.015em;
  color: var(--fg);
  margin: 0;
  max-width: 24ch;
  text-wrap: balance;
  --fit-cap: var(--t-pull);
  --fit-floor: 1.08rem;
}

/* Small technical label. */
.l-label {
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 14px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg4);
  margin: 0;
}

/* --- Buttons ------------------------------------------------------------ */

.l-cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border-radius: 100px;
  background: var(--fg);
  padding: 14px 22px;
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.005em;
  color: #fff !important;
  text-decoration: none !important;
  transition: background-color 300ms ease;
}
.l-cta:hover { background: var(--accent); }
.l-cta .arrow { transition: transform 300ms cubic-bezier(0.16, 1, 0.3, 1); }
.l-cta:hover .arrow { transform: translateX(2px); }

.l-cta-wrap { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; }
.l-cta-ghost {
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 500;
  color: var(--fg2) !important;
  text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, var(--fg) 25%, transparent);
  padding-bottom: 2px;
  transition: color 200ms ease, border-color 200ms ease;
  /* The visible link is a text line; the finger target is not. */
  position: relative;
}
.l-cta-ghost::after { content: ""; position: absolute; inset: -14px -10px; }
.l-cta-ghost:hover { color: var(--fg) !important; border-color: var(--fg); }

.l-inline-link {
  color: var(--fg);
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--fg4) 30%, transparent);
  text-underline-offset: 4px;
  transition: color 200ms ease, text-decoration-color 200ms ease;
}
.l-inline-link:hover { color: var(--accent); text-decoration-color: color-mix(in srgb, var(--accent) 40%, transparent); }

/* --- Reveal ------------------------------------------------------------- */

.reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 700ms cubic-bezier(0.16, 1, 0.3, 1),
              transform 700ms cubic-bezier(0.16, 1, 0.3, 1);
}
.reveal.is-visible { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
}

/* --- Hero --------------------------------------------------------------- */

/* First screen is the hero alone. Center the shell under the fixed nav so
   short and tall windows both feel composed. */
.l-hero {
  min-height: 100svh;
  justify-content: stretch;
}
.l-hero .l-shell {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-top: calc(var(--l-nav-h) + var(--sec-pad));
  padding-bottom: var(--sec-pad);
  min-height: 100svh;
}
/* Headline first at full width, then the lede + CTAs beside the pulse. */
.l-hero-row { margin-top: clamp(26px, 3.2vw, 46px); }
.l-hero .l-display--sub { margin-top: 0; }
.l-hero .l-cta-wrap { margin-top: clamp(24px, 2.8vw, 40px); }

/* --- Live pulse dot (hero + fleet window chrome) ------------------------ */

.l-feed-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 2px;
  background: var(--fg);
  animation: l-pulse 2s ease-in-out infinite;
}
@keyframes l-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
@media (prefers-reduced-motion: reduce) { .l-feed-dot { animation: none; } }

/* --- Jobs list (product.html) ------------------------------------------- */

.l-jobs { margin-top: 48px; display: flex; flex-direction: column; max-width: 780px; list-style: none; padding: 0; }
@media (min-width: 768px) { .l-jobs { margin-top: 72px; } }
.l-job {
  display: flex;
  align-items: flex-start;
  gap: 24px;
  border-top: 1px solid var(--rule);
  padding-block: 28px;
  margin: 0;
}
@media (min-width: 768px) { .l-job { gap: 32px; padding-block: 32px; } }
.l-job:last-child { border-bottom: 1px solid var(--rule); }
.l-job-index {
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 20px;
  letter-spacing: 0.04em;
  color: var(--fg5);
}
.l-jobs .l-job-index { width: 36px; padding-top: 4px; line-height: 30px; }
@media (min-width: 768px) { .l-jobs .l-job-index { width: 48px; } }
.l-job-title {
  font-family: var(--font-sans);
  font-size: clamp(1rem, 0.97rem + 0.14vw, 1.0625rem);
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: -0.01em;
  color: var(--fg);
  margin: 0;
}
.l-job-body {
  font-family: var(--font-sans);
  font-size: var(--t-panel);
  line-height: 1.55;
  color: var(--fg3);
  max-width: 560px;
  margin: 10px 0 0;
}

/* --- Founder ------------------------------------------------------------ */

.l-founder-note {
  margin-top: 40px;
  max-width: 560px;
  font-family: var(--font-sans);
  font-size: var(--t-body);
  line-height: 1.65;
  color: color-mix(in srgb, var(--fg) 78%, var(--bg));
}
.l-byline { margin-top: 28px; display: flex; align-items: center; gap: 14px; }
.l-byline-avatar {
  width: 46px;
  height: 46px;
  flex-shrink: 0;
  border-radius: 50%;
  object-fit: cover;
  background: color-mix(in srgb, var(--fg4) 15%, var(--bg));
}
@media (min-width: 768px) { .l-byline-avatar { width: 52px; height: 52px; } }
.l-byline-name {
  font-family: var(--font-sans);
  font-size: 15px;
  font-weight: 500;
  line-height: 18px;
  color: var(--fg);
}
.l-byline-role {
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 16px;
  letter-spacing: 0.04em;
  color: var(--fg5);
}

/* --- Closing ------------------------------------------------------------ */

.l-closing .l-shell {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
.l-closing .l-h2 { max-width: 24ch; }
.l-closing-sub {
  font-family: var(--font-sans);
  font-size: var(--t-body);
  line-height: 1.6;
  color: var(--fg3);
  max-width: 46ch;
  margin: clamp(14px, 1.6vw, 22px) 0 0;
}

/* ============================================================================
   LAYOUT: prose left, device right
   The 660px measure left 46-60% of most sections empty. Grid, not flex, so the
   device column can never squeeze the prose below its measure and neither
   column can push the row wider than the shell (min-width: 0 on both tracks).
   ========================================================================= */

.l-with-aside {
  display: flex;
  flex-direction: column;
  gap: clamp(36px, 4.5vw, 56px);
}
@media (min-width: 1000px) {
  .l-with-aside {
    display: grid;
    /* The device column is a fixed 420px, not minmax(320px,460px): the fit
       maths below has to know the prose column's true width, and a track
       that floats between 320 and 460 makes that width unknowable in CSS. */
    grid-template-columns: minmax(0, 1fr) 420px;
    gap: var(--aside-gap);
    align-items: start;
  }
  .l-with-aside > .l-main-col {
    max-width: 660px;
    min-width: 0;
    --fit-avail: clamp(220px, calc((min(100vw, var(--shell-max)) - 2 * var(--shell-pad) - 420px - var(--aside-gap)) * 0.985), 660px);
  }
  .l-with-aside > .l-aside-col,
  .l-with-aside > .l-aside-wide { min-width: 0; }

  /* Inverse: a narrow sticky label on the left, the wide content on the
     right. Used by the jobs list (product.html) and the systems grid. */
  .l-with-aside--label { grid-template-columns: minmax(0, 320px) minmax(0, 1fr); }
  .l-with-aside--label > .l-main-col { max-width: none; --fit-avail: 320px; }
  .l-with-aside--label > .l-jobs { margin-top: 0; max-width: 720px; }
  .l-sticky { position: sticky; top: calc(64px + 48px); }
}

/* ============================================================================
   DEVICE 1: key/value receipt
   Anthropic's DATE/CATEGORY rows and Stripe's order receipt are the same
   object: label left, value right, hairline between. It reads as precise
   because it is the shape of a real record, not a marketing panel.
   ========================================================================= */

.kv {
  width: 100%;
  border-top: 1px solid var(--rule);
}
.kv--flush { border-top: 0; }
/* Heads hold two labels, and neither may be clipped or broken mid-word. Keys
   stay nowrap so an identifier like support-agent-3 never splits; the row
   wraps instead, dropping the second label whole onto its own line when the
   two cannot share one. */
.kv-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 3px 14px;
  padding-block: 13px;
  border-bottom: 1px solid var(--rule);
}
.kv-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 18px;
  padding-block: 12px;
  border-bottom: 1px solid var(--rule);
}
.kv-key {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--fg5);
}
.kv-head .kv-key, .kv-row > .kv-key { white-space: nowrap; }
.kv-val {
  font-family: var(--font-sans);
  font-size: var(--t-panel);
  line-height: 1.45;
  color: var(--fg1);
  text-align: right;
  min-width: 0;
}
.kv-val--num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.kv-val--dim { color: var(--fg4); font-style: italic; }

/* The verdict itself: the one place on the page colour earns its keep. */
.kv-verdict {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
}
.kv-verdict::before {
  content: "";
  width: 7px;
  height: 7px;
  flex-shrink: 0;
  border-radius: 50%;
  background: currentColor;
}
.kv-verdict--go { color: #0e9972; }
.kv-verdict--wait { color: #f7a224; }
.kv-verdict--no { color: #ef402c; }

.kv-note {
  font-family: var(--font-sans);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--fg4);
  margin-top: 14px;
}

/* Cycles through sample decisions so the hero has one slow moving part. */
.kv-swap { transition: opacity 260ms ease; }
.kv-swap.is-out { opacity: 0; }

/* ============================================================================
   DEVICE 3: same request, twice
   The problem section needs a picture of INCONSISTENCY, and a list of things a
   bare model does not know cannot show that: absence is not legible at a
   glance. Two runs of one request, side by side, with every unprovable claim
   marked, is readable in about two seconds.
   ========================================================================= */

.cmp { border-top: 1px solid var(--rule); }
.cmp-ask {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: clamp(0.95rem, 0.92rem + 0.15vw, 1.0625rem);
  line-height: 1.4;
  color: var(--fg1);
  margin: 0;
  padding-block: 14px;
  border-bottom: 1px solid var(--rule);
}
.cmp-run { padding-block: 12px 4px; border-bottom: 1px solid var(--rule); }
.cmp-run:last-child { border-bottom: 0; }
.cmp-run-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}
.cmp-run-label {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg5);
  font-variant-numeric: tabular-nums;
}
.cmp-answer {
  font-family: var(--font-sans);
  font-size: var(--t-panel);
  font-weight: 500;
  color: var(--fg);
}
.cmp .check:last-child { border-bottom: 0; }

/* ============================================================================
   DEVICE 4: learning ledger + share bars
   ========================================================================= */

.led-row {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding-block: 12px;
  border-bottom: 1px solid var(--rule);
}
.led-date {
  flex: 0 0 46px;
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 19px;
  letter-spacing: 0.04em;
  color: var(--fg5);
}
.led-body {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-family: var(--font-sans);
  font-size: var(--t-panel);
  line-height: 1.45;
  color: var(--fg1);
}
.led-src {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.03em;
  color: var(--fg5);
}

.bars { display: flex; flex-direction: column; gap: 9px; }
.bar-row { display: flex; align-items: center; gap: 12px; }
.bar-label {
  flex: 0 0 54px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--fg5);
}
.bar-track {
  flex: 1 1 auto;
  min-width: 0;
  height: 8px;
  background: color-mix(in srgb, var(--fg4) 12%, var(--bg));
}
.bar-fill {
  display: block;
  height: 100%;
  width: var(--v, 0%);
  background: var(--fg2);
  transform-origin: left;
  transform: scaleX(0);
  transition: transform 900ms cubic-bezier(0.16, 1, 0.3, 1) 200ms;
}
.reveal.is-visible .bar-fill { transform: scaleX(1); }
@media (prefers-reduced-motion: reduce) { .bar-fill { transform: scaleX(1); transition: none; } }
.bar-val {
  flex: 0 0 40px;
  text-align: right;
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--fg2);
  font-variant-numeric: tabular-nums;
}

/* ============================================================================
   DEVICE 5: systems grid
   ========================================================================= */

/* Hairline-per-cell, not a filled cell grid. `auto-fit` means the column count
   follows the width, so the last row is almost always ragged, and a
   background-plus-1px-gap grid renders that remainder as a visible empty box.
   A rule above each cell reads as a table at every column count. */
.tools {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  column-gap: clamp(16px, 2vw, 32px);
  margin-top: clamp(24px, 2.6vw, 34px);
}
.tool {
  border-top: 1px solid var(--rule);
  padding: 11px 0 13px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.tool-name {
  font-family: var(--font-sans);
  font-size: var(--t-panel);
  font-weight: 500;
  color: var(--fg);
}
.tool-role {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fg5);
}

/* ============================================================================
   THE LOOP: five numbered columns, and the fifth closes it
   Every line a full sentence a non-technical reader can repeat back.
   Columns are declared, not auto-fit: five steps under auto-fit wrap 4+1 at
   most widths, which strands step 05 alone on a row.
   ========================================================================= */

.loop {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: clamp(24px, 2.8vw, 44px);
  /* No rule between the label and the steps: the section's own top hairline
     is one line up, and two rules that close together read as a form. */
  margin-top: clamp(24px, 2.6vw, 36px);
}
@media (max-width: 1120px) { .loop { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 679px) { .loop { grid-template-columns: minmax(0, 1fr); } }
.loop-step { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.loop-num {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  color: var(--fg5);
}
.loop-title {
  font-family: var(--font-sans);
  font-size: clamp(0.95rem, 0.93rem + 0.1vw, 1rem);
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--fg);
}
.loop-body {
  font-family: var(--font-sans);
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--fg3);
}
.loop-body .kv-verdict { font-size: 10px; }

/* --- Verdict legend ------------------------------------------------------ */
.legend { margin-top: clamp(28px, 3vw, 40px); border-top: 1px solid var(--rule); max-width: 520px; }
.legend-row {
  display: flex;
  align-items: baseline;
  gap: 14px;
  padding-block: 13px;
  border-bottom: 1px solid var(--rule);
}
.legend-row .kv-verdict { flex: 0 0 52px; }
.legend-text {
  font-family: var(--font-sans);
  font-size: var(--t-panel);
  line-height: 1.5;
  color: var(--fg3);
}

/* ============================================================================
   HEDGE (X26): faint vertical grid
   Column rules at ~1% ink, full page height. Free structure: a sparse
   left-aligned layout stops looking unfinished and starts looking ruled.
   ========================================================================= */
body.landing #wrapper {
  position: relative;
  --grid-col: clamp(72px, 7.92vw, 114px);
}
/* Painted on a fixed pseudo-element rather than as a background on #wrapper:
   a repeating gradient on the wrapper tiles against the element box and drops
   most of its lines once background-size/position get involved. A fixed layer
   just draws the ruling once, over the viewport, behind everything. */
body.landing #wrapper::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image: repeating-linear-gradient(
    to right,
    color-mix(in srgb, var(--fg4) 22%, transparent) 0 1px,
    transparent 1px var(--grid-col)
  );
  background-position: var(--shell-pad) 0;
}
/* On a phone the ruling lands every ~72px behind 15px text and reads as
   interference rather than structure. */
@media (max-width: 719px) { body.landing #wrapper::before { display: none; } }
/* Sections must not paint over the ruling. */
body.landing .l-section { background: transparent; }

/* ============================================================================
   THE CASE RUN
   FullSeam's agent work-log, in our dress. A case steps through the loop:
   read, draft, conflict, WAIT, approval, GO, receipt. The product's core
   function shown rather than described.
   ========================================================================= */
.case { border-top: 1px solid var(--rule); }
.case-head {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 3px 16px;
  padding-block: 13px;
  border-bottom: 1px solid var(--rule);
}
.case-head .kv-key { white-space: nowrap; }
.case-step {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding-block: 12px;
  border-bottom: 1px solid var(--rule);
}
.case-time {
  flex: 0 0 60px;
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 19px;
  letter-spacing: 0.02em;
  color: var(--fg5);
  font-variant-numeric: tabular-nums;
}
.case-mark {
  flex: 0 0 14px;
  height: 14px;
  margin-top: 3px;
  border-radius: 50%;
  position: relative;
}
.case-mark--done { border: 1.5px solid var(--fg4); }
.case-mark--done::after {
  content: "";
  position: absolute;
  left: 3.5px; top: 1.5px;
  width: 4px; height: 7px;
  border-right: 1.5px solid var(--fg2);
  border-bottom: 1.5px solid var(--fg2);
  transform: rotate(40deg);
}
.case-mark--flag { border: 1.5px solid #f7a224; }
.case-mark--flag::after {
  content: "";
  position: absolute;
  left: 50%; top: 50%;
  width: 4px; height: 4px;
  border-radius: 50%;
  background: #f7a224;
  transform: translate(-50%, -50%);
}
.case-mark--hold { border: 1.5px solid var(--fg3); }
.case-mark--hold::after {
  content: "";
  position: absolute;
  left: 50%; top: 50%;
  width: 6px; height: 1.5px;
  background: var(--fg3);
  transform: translate(-50%, -50%);
}
.case-body {
  font-family: var(--font-sans);
  font-size: 13.5px;
  line-height: 19px;
  color: var(--fg1);
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.case-detail {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.03em;
  color: var(--fg5);
}
.case-body .kv-verdict { font-size: 11px; }

/* ============================================================================
   PRODUCT WINDOW MOCK
   Window chrome (Palus), hairline interior (ours). A preview of the cockpit,
   labelled as such.
   ========================================================================= */
.win {
  border: 1px solid color-mix(in srgb, var(--fg4) 28%, var(--bg));
  border-radius: 10px;
  background: var(--bg);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04), 0 12px 32px -18px rgba(0, 0, 0, 0.14);
  overflow: hidden;
}
.win-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--rule);
}
.win-dots { display: inline-flex; gap: 5px; flex-shrink: 0; }
.win-dots i {
  width: 9px; height: 9px; border-radius: 50%;
  background: color-mix(in srgb, var(--fg4) 22%, var(--bg));
}
.win-title {
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 500;
  color: var(--fg2);
  margin-left: 4px;
  white-space: nowrap;
}
/* The window chrome is the first thing to lose parts on a narrow screen: the
   title and the mode badge carry the meaning, the decoration does not. */
@media (max-width: 559px) {
  .win-dots { display: none; }
  .win-title { margin-left: 0; }
}
.win-badge {
  margin-left: auto;
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #b45309;
  background: color-mix(in srgb, #f7a224 12%, var(--bg));
  border-radius: 100px;
  padding: 3px 8px;
}
.win-badge--clear { color: #0e9972; background: color-mix(in srgb, #0e9972 10%, var(--bg)); }

.win-body { display: grid; grid-template-columns: 1fr; }
.win-body > * { min-width: 0; }
.win-list { display: flex; flex-direction: column; border-bottom: 1px solid var(--rule); }
.q-row {
  appearance: none;
  border: 0;
  background: transparent;
  text-align: left;
  font: inherit;
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 12px;
  border-bottom: 1px solid var(--rule);
  cursor: pointer;
  min-width: 0;
}
.q-row:last-child { border-bottom: 0; }
.q-row.is-selected { background: color-mix(in srgb, var(--fg4) 6%, var(--bg)); }
.q-row .kv-verdict { font-size: 9px; margin-top: 3px; }
.q-row-main {
  font-family: var(--font-sans);
  font-size: 12.5px;
  line-height: 1.35;
  color: var(--fg1);
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.q-row-sub {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.04em;
  color: var(--fg5);
}
.win-detail { padding: 4px 16px 16px; }
.win-detail .kv-row { padding-block: 10px; gap: 14px; }
.win-detail .kv-key, .demo-rail .kv-key { font-size: 10px; letter-spacing: 0.1em; }
.win-detail .kv-val, .demo-rail .kv-val { font-size: 12.5px; }
.win-actions { display: flex; gap: 8px; margin-top: 16px; flex-wrap: wrap; }
.btn-mock {
  font-family: var(--font-sans);
  font-size: 12.5px;
  font-weight: 500;
  padding: 10px 16px;
  border-radius: 100px;
  border: 1px solid var(--rule);
  color: var(--fg2);
  background: transparent;
}
.btn-mock--primary {
  background: var(--fg);
  border-color: var(--fg);
  color: #fff;
}

/* ============================================================================
   THE DESK DEMO: queue, checks, and what Cortal knew
   Three panes on a wide screen, stacked on a phone. The third pane exists
   because "how do you know that?" is the question a sceptic is actually
   asking while they read the checks.
   ========================================================================= */
.demo-win { box-shadow: 0 1px 2px rgba(0,0,0,0.04), 0 18px 44px -22px rgba(0,0,0,0.16); }
/* Tabs wrap onto a second row when the window is narrow. A hidden-scrollbar
   overflow row reads as "there are two tabs" on a phone, which is worse than
   a second row could ever look. */
.demo-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 4px;
  padding: 8px 8px 0;
  border-bottom: 1px solid var(--rule);
}
.demo-tab {
  appearance: none;
  border: 1px solid transparent;
  border-bottom: 0;
  background: transparent;
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 500;
  color: var(--fg3);
  padding: 11px 13px;
  border-radius: 8px 8px 0 0;
  cursor: pointer;
  white-space: nowrap;
}
.demo-tab:hover { color: var(--fg); }
.demo-tab.is-active {
  color: var(--fg);
  border-color: var(--rule);
  background: var(--bg);
  margin-bottom: -1px;
}
.demo-tab-count {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--fg5);
  margin-left: 4px;
}
/* Stretch, not start: all three panes run the full height of the tallest one,
   so the hairlines between them reach the bottom and the short queue column
   can pin a fact to its floor instead of trailing off into white. */
.demo-body { align-items: stretch; }
@media (min-width: 760px) {
  .demo-body { grid-template-columns: minmax(0, 258px) minmax(0, 1fr); }
  .win-list { border-right: 1px solid var(--rule); border-bottom: 0; }
}
/* Two columns, three panes: without this, the rail auto-flows into the 258px
   queue track on row two and leaves the rest of the row blank. In the
   two-column band the rail runs full width under both panes instead. */
@media (min-width: 760px) and (max-width: 1079px) {
  .demo-rail { grid-column: 1 / -1; }
}
@media (min-width: 1080px) {
  .demo-body { grid-template-columns: minmax(0, 262px) minmax(0, 1.25fr) minmax(0, 0.95fr); }
}
.demo-detail { padding: 14px 18px 18px; }
.demo-case-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--rule);
}
.demo-case-title {
  font-family: var(--font-sans);
  font-size: 14.5px;
  font-weight: 500;
  color: var(--fg);
}
.demo-why-label {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg5);
  margin: 14px 0 4px;
}
.demo-why-count { letter-spacing: 0.06em; text-transform: none; }
.demo-rail {
  padding: 14px 18px 18px;
  border-top: 1px solid var(--rule);
}
@media (min-width: 1080px) {
  .demo-rail { border-top: 0; border-left: 1px solid var(--rule); }
}
.demo-rail .kv-row:last-child { border-bottom: 0; }
.demo-rail-note {
  font-family: var(--font-sans);
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--fg2);
  margin: 4px 0 0;
}
.demo-rail-src {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.04em;
  color: var(--fg5);
  margin: 14px 0 0;
  padding-top: 10px;
  border-top: 1px solid var(--rule);
}
/* The queue is short by design: three items, not thirty. Rather than leave
   the column half empty, it ends with the number the queue is small BECAUSE
   of. Information where there was air. */
.win-list-foot {
  margin-top: auto;
  padding: 13px 12px 14px;
  border-top: 1px solid var(--rule);
}
.win-list-foot-num {
  display: block;
  font-family: var(--font-mono);
  font-size: 17px;
  letter-spacing: -0.01em;
  color: var(--fg2);
  font-variant-numeric: tabular-nums;
}
.win-list-foot-cap {
  display: block;
  margin-top: 3px;
  font-family: var(--font-sans);
  font-size: 11.5px;
  line-height: 1.4;
  color: var(--fg5);
}

.checks { list-style: none; margin: 0; padding: 0; }
.check {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding-block: 9px;
  border-bottom: 1px solid var(--rule);
}
.checks--tight .check { padding-block: 7px; }
.check-mark { flex: 0 0 14px; height: 14px; border-radius: 50%; position: relative; margin-top: 2px; }
.check--ok .check-mark { border: 1.5px solid var(--fg4); }
.check--ok .check-mark::after {
  content: "";
  position: absolute;
  left: 3.5px; top: 1.5px;
  width: 4px; height: 7px;
  border-right: 1.5px solid var(--fg2);
  border-bottom: 1.5px solid var(--fg2);
  transform: rotate(40deg);
}
.check--fail .check-mark { border: 1.5px solid #ef402c; }
.check--fail .check-mark::before,
.check--fail .check-mark::after {
  content: "";
  position: absolute;
  left: 50%; top: 50%;
  width: 7px; height: 1.5px;
  background: #ef402c;
}
.check--fail .check-mark::before { transform: translate(-50%, -50%) rotate(45deg); }
.check--fail .check-mark::after { transform: translate(-50%, -50%) rotate(-45deg); }
.check-text {
  font-family: var(--font-sans);
  font-size: 13px;
  line-height: 1.5;
  color: var(--fg2);
  min-width: 0;
}
.check--ok .check-text { color: var(--fg3); }
.demo-note {
  font-family: var(--font-sans);
  font-size: 13px;
  line-height: 1.55;
  color: var(--fg4);
  margin: 12px 0 0;
}
.demo-receipt {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.03em;
  color: var(--fg4);
  margin: 14px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--rule);
}
.demo-empty {
  font-family: var(--font-sans);
  font-size: 13px;
  color: var(--fg4);
  padding: 20px;
}
.demo-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 14px;
  padding: 10px 14px;
  border-top: 1px solid var(--rule);
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.04em;
  color: var(--fg5);
}
.demo-reset {
  appearance: none;
  border: 0;
  background: transparent;
  font: inherit;
  color: var(--fg3);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
  flex-shrink: 0;
  /* Text-sized link, finger-sized target. */
  position: relative;
}
.demo-reset::after { content: ""; position: absolute; inset: -14px -10px; }
.demo-reset:hover { color: var(--fg); }
.demo-win .btn-mock { cursor: pointer; transition: transform 120ms ease, background-color 150ms ease; }
.demo-win .btn-mock:active { transform: scale(0.97); }
.demo-win .btn-mock--primary:hover { background: #000; }

/* --- Hero pulse ----------------------------------------------------------- */
.pulse-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 18px;
  padding-block: 12px;
  border-bottom: 1px solid var(--rule);
}
.pulse-num {
  font-family: var(--font-mono);
  font-size: clamp(1.45rem, 1.1rem + 1.1vw, 2rem);
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--fg);
  font-variant-numeric: tabular-nums;
}
.pulse-num--wait { color: #b45309; }
.pulse-num--no { color: #ad2111; }
.pulse-cap {
  font-family: var(--font-sans);
  font-size: 12.5px;
  color: var(--fg4);
  text-align: right;
}
.pulse .kv-head .l-feed-dot { width: 7px; height: 7px; vertical-align: middle; }

/* ============================================================================
   FLEET CONTROL ROOM
   The stream column is absolutely positioned inside a relative wrapper, so it
   contributes NOTHING to the grid row height. The held/stopped rail decides
   how tall the body is, and the stream then fills exactly that height (fleet.js
   grows and trims by measurement). That is what removes the dead white space
   under the actions at every viewport, including after a resize.
   ========================================================================= */
.fleet-win { box-shadow: 0 1px 2px rgba(0,0,0,0.04), 0 18px 44px -22px rgba(0,0,0,0.16); }
.fleet-meta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fg4);
  margin-left: 10px;
  white-space: nowrap;
}
@media (max-width: 719px) { .fleet-meta { display: none; } }
.fleet-clock {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--fg5);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}
.demo-win .fleet-clock { margin-left: auto; }
.demo-win .win-badge { margin-left: 12px; }
.fleet-counters {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border-bottom: 1px solid var(--rule);
}
@media (max-width: 700px) { .fleet-counters { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.fleet-counter { padding: 14px clamp(12px, 1.4vw, 18px); border-right: 1px solid var(--rule); min-width: 0; }
.fleet-counter:last-child { border-right: 0; }
@media (max-width: 700px) {
  .fleet-counter:nth-child(2n) { border-right: 0; }
  .fleet-counter:nth-child(-n+2) { border-bottom: 1px solid var(--rule); }
}
.fleet-num {
  display: block;
  font-family: var(--font-mono);
  font-size: clamp(1.35rem, 1rem + 1.3vw, 2.1rem);
  line-height: 1.05;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--fg);
}
.fleet-num--wait { color: #b45309; }
.fleet-num--no { color: #ad2111; }
.fleet-cap {
  font-family: var(--font-sans);
  font-size: 11.5px;
  line-height: 1.35;
  color: var(--fg4);
  margin-top: 5px;
  display: block;
}
.fleet-body { display: grid; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 900px) { .fleet-body { grid-template-columns: minmax(0, 1fr) 316px; } }
.fleet-stream-wrap {
  position: relative;
  min-width: 0;
  height: clamp(268px, 40vh, 348px);
}
@media (min-width: 900px) { .fleet-stream-wrap { height: auto; min-height: 300px; } }
.fleet-stream {
  position: absolute;
  inset: 0;
  overflow: hidden;
  padding-block: 4px;
}
.fleet-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  /* --row-extra is set by fleet.js: the leftover height that is smaller than
     one row, divided across the rows, so the column ends exactly at its floor
     instead of on a strip of dead white. */
  padding: calc(9px + var(--row-extra, 0px) / 2) clamp(12px, 1.4vw, 18px);
  border-bottom: 1px solid var(--rule);
  min-width: 0;
  opacity: 0;
  transform: translateY(-6px);
  transition: opacity 380ms ease, transform 380ms cubic-bezier(0.16, 1, 0.3, 1);
}
.fleet-row.is-in { opacity: 1; transform: none; }
.fleet-row:last-child { border-bottom: 0; }
.fleet-time {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--fg5);
  font-variant-numeric: tabular-nums;
}
.fleet-row .kv-verdict { flex: 0 0 auto; font-size: 9.5px; }
@media (min-width: 560px) { .fleet-row .kv-verdict { flex: 0 0 44px; } }
/* One markup, two shapes: agent beside the action when there is room, under it
   when there is not. Nothing is ever clipped mid-word. */
.fleet-main { display: flex; min-width: 0; flex-direction: column; gap: 2px; }
@media (min-width: 720px) { .fleet-main { flex-direction: row; align-items: baseline; gap: 12px; } }
.fleet-agent {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.02em;
  color: var(--fg4);
  white-space: nowrap;
  order: 2;
}
@media (min-width: 720px) {
  .fleet-agent { flex: 0 0 126px; font-size: 11px; color: var(--fg3); order: 0; }
}
.fleet-act {
  font-family: var(--font-sans);
  font-size: 12.5px;
  line-height: 1.35;
  color: var(--fg2);
  min-width: 0;
  order: 1;
}
@media (min-width: 720px) {
  .fleet-act { font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
}
.fleet-side {
  min-width: 0;
  padding: 12px clamp(12px, 1.4vw, 18px) 16px;
  border-top: 1px solid var(--rule);
}
@media (min-width: 900px) { .fleet-side { border-top: 0; border-left: 1px solid var(--rule); } }
.fleet-side .demo-why-label:first-child { margin-top: 0; }
.fleet-held-row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding-block: 9px;
  border-bottom: 1px solid var(--rule);
  min-width: 0;
}
.fleet-held-row:last-child { border-bottom: 0; }
.fleet-held-row .kv-verdict { font-size: 9.5px; margin-top: 2px; flex: 0 0 44px; }
.fleet-held-main {
  min-width: 0;
  font-family: var(--font-sans);
  font-size: 12px;
  line-height: 1.4;
  color: var(--fg1);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.fleet-held-reason {
  font-family: var(--font-sans);
  font-size: 11px;
  line-height: 1.4;
  color: var(--fg4);
}
.fleet-rate { font-variant-numeric: tabular-nums; flex-shrink: 0; }
@media (max-width: 559px) { .demo-foot { font-size: 10px; gap: 10px; } }

/* --- Motion: detail panes animate in on every change ---------------------- */
@keyframes pane-in {
  from { opacity: 0; transform: translateY(5px); }
  to   { opacity: 1; transform: none; }
}
.demo-detail, .win-detail { animation: pane-in 240ms cubic-bezier(0.16, 1, 0.3, 1); }
@media (prefers-reduced-motion: reduce) {
  .demo-detail, .win-detail, .fleet-row { animation: none; transition: none; opacity: 1; transform: none; }
}
