/* Piece A: nav and hero. Layout per design.md band model. */

/* ---- Nav ---- */
.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px var(--gutter);
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background var(--dur-base) var(--ease-signal),
              border-color var(--dur-base) var(--ease-signal);
}
.nav.scrolled {
  /* Ruling I: solid. 92 percent opacity ghosts light-band text through the bar. */
  background: var(--color-ink);
  border-bottom-color: var(--color-ink-line);
}
.nav-left { display: flex; align-items: center; gap: 12px; }
.nav-wordmark { font-size: 18px; }

/* ---- Wordmark ----
   Live text in Space Grotesk, never an image: it stays sharp at every pixel
   density and changes colour by register instead of by asset swap.

   Two tone, faithful to the supplied artwork, which is navy and SAND. Ember
   is deliberately absent from the mark, for two independent reasons:
     - on Linen, Ember letters are 2.73:1 and ruling F bans them outright;
     - on Ink, an Ember wordmark would be a FOURTH Ember element type, against
       a ceiling of three that the hero already fills (CTA, live status,
       waveform). The mark's own bars do not count, per ruling O.
   Sand carries the AI on dark in its documented role as warm secondary text.
   On light Sand is 1.43:1 and banned, so Ink Slate takes it at 6.52:1, the
   same substitution the status pill already makes for its complete state. */
.wordmark {
  line-height: 1.36;   /* the display family's own floor; it was inheriting body 1.60 */
  font-family: var(--font-display);
  font-weight: var(--weight-medium);
  /* Positive, so no Turkish tracking rule is touched. An uppercase lockup
     needs air where the sentence-case wordmark wanted -0.006em. */
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.wm-eli { color: var(--color-linen); }
/* Weight carries the split where tone alone did not read at nav size. */
.wm-ai  { color: var(--color-sand); font-weight: var(--weight-semi); }

/* The light register. The nav is NOT one of these: ruling I made the scrolled
   bar solid Ink, so the nav wordmark sits on Ink at every scroll position. */
.on-light .wm-eli { color: var(--color-ink); }
.on-light .wm-ai  { color: var(--color-ink-slate); }
.nav-links { display: flex; gap: 8px; }
.nav-link {
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: var(--weight-medium);
  letter-spacing: 0.005em;
  color: var(--color-ink-mist);
  text-decoration: none;
  padding: 0 16px;
  line-height: 40px;
  transition: color var(--dur-fast) var(--ease-signal);
}
.nav-link:hover { color: var(--color-linen); }
.nav-right { display: flex; align-items: center; gap: 20px; }

.lang-toggle {
  display: flex; align-items: center; gap: 8px;
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  line-height: var(--leading-micro);
  letter-spacing: var(--tracking-micro);
  font-weight: var(--weight-medium);
}
/* The two locales are real buttons now, not spans. They were decoration that
   looked like a control; a control that does nothing is worse than no control.
   Everything below is the button element being talked back down to the text it
   already looked like -- no fill, no border, no padding, the toggle's own mono
   type inherited -- so the rendered result is byte-identical to the spans it
   replaces at rest. */
.lang-opt {
  appearance: none;
  -webkit-appearance: none;
  background: none;
  border: 0;
  margin: 0;
  padding: 0;
  font: inherit;
  letter-spacing: inherit;
  cursor: pointer;
}
.lang-toggle .active   { color: var(--color-linen); }
.lang-toggle .inactive { color: var(--color-ink-slate); }
.lang-opt.inactive:hover { color: var(--color-linen); transition: color var(--dur-fast) var(--ease-signal); }
/* Focus rings are transient and mutually exclusive, so they cost no Ember. */
.lang-opt:focus-visible { outline: 2px solid var(--color-ember); outline-offset: 2px; }
.lang-toggle .rule { width: 1px; height: 10px; background: var(--color-ink-line); }


/* ---- Buttons ---- */
.btn-primary {
  display: inline-block;
  background: var(--accent);
  color: var(--accent-label);
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: var(--weight-semi);
  letter-spacing: 0.005em;
  border: none;
  border-radius: var(--radius-md);
  padding: 13px 22px;
  min-width: 132px;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-signal);
}
.btn-primary:hover  { background: var(--accent-hover); }
.btn-primary:active { background: var(--accent-active); }
.btn-primary:focus-visible { outline: 2px solid var(--color-ember); outline-offset: 2px; }
/* No nav variant: the primary CTA renders identically everywhere, per spec. */

/* ---- Hero ----
   Height is the viewport, exactly. The waveform band is pinned to the
   hero's bottom, so it is pinned to the rendered fold at every breakpoint.
   Content centres in the zone ABOVE the band via the bottom padding. */
/* THREE COLUMNS. The hero is a left card column, a centre text column and a
   right card column, all three derived from the same two numbers on the
   ancestor both descend from. Text lives only in the centre, cards only at
   the sides, so overlap is impossible rather than merely avoided.

   The arithmetic, and why the gap is exact: the centre is centred inside the
   hero's content box, so its right edge lands at
       inset + contentW - (card + gap)
   while the right card's left edge lands at
       inset + contentW - card
   and the difference is --card-gap, at every width, with no drift. */
.hero-zone {
  position: relative;
  --card-w: 340px;
  --card-inset: var(--gutter);
  --card-gap: var(--spacing-48);
  --hero-centre-w: 100%;   /* one column until the viewport can hold three */

  /* The diagonal. Each column is offset from the one before it so the eye
     travels top right, then centre, then lower left. --hero-drop pushes the
     centre column below true centre; the cards take the two extremes. */
  --hero-drop: 0px;
  --card-live-top: 16vh;
  --card-complete-clear: var(--spacing-48);

  /* The band's height, and the gap the hero's content keeps above it. Declared
     once, because this number was written out four times -- the band, the
     hero's bottom reserve, the completed card's anchor, and again at two
     breakpoints -- and a reserve equal to the band leaves the tallest bar tip
     landing flush on the CTA's bottom edge. The clearance is what makes "never
     crossed" visible rather than merely true to the pixel. */
  --wave-h: 180px;
  --wave-clear: var(--spacing-48);
}
.hero {
  position: relative;
  /* min-height, never height. The centre column plus the waveform's 180px
     reserve needs 789px of hero. At a fixed 100vh anything shorter than that
     made the centred column overflow SYMMETRICALLY, so its lower half landed
     inside the reserve and the bars painted over the CTA. The hero grows
     instead: the reserve is never entered at any width or height, and on a
     viewport below 789px the waveform's faded tail goes under the fold.
     The 640px floor is deleted rather than beaten -- two min-heights in one
     rule is the cascade defect, and 640 could not hold the content anyway. */
  min-height: 100vh;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  background:
    radial-gradient(ellipse 70% 55% at 50% 62%, var(--color-ink-elevated) 0%, var(--color-ink) 78%);
  overflow: hidden;
  padding: 96px var(--gutter) calc(var(--wave-h) + var(--wave-clear));
}
/* The centre column, and the headline's sizing container: the display size
   is a function of THIS column's width, not the viewport's, so the headline
   always fills its own column and never has to be capped against a card. */
.hero-centre {
  /* The band is positioned and the centre column was not, so the bars painted
     over the headline, the subhead and the CTA whenever the two met. Raised
     into the same layer the call cards already occupy, one step below them,
     so the text can never be crossed even if a future string grows the column.
     Verified against .card-complete at 1920/1440/1280/1024/900/768/360: the
     two boxes never intersect, so this changes no other paint relationship. */
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  max-width: var(--hero-centre-w);
  container-type: inline-size;
}
.hero-eyebrow {
  color: var(--color-sand);   /* the gradient's core is Ink Elevated: Ink Mist measures 4.48:1 here */
  margin-bottom: 12px;
}
.hero h1 {
  font-size: var(--text-display);
  line-height: var(--leading-display);
  letter-spacing: var(--tracking-display);
  color: var(--color-linen);
  max-width: var(--headline-max-width);
}
.hero-sub {
  font-size: var(--text-body-lg);
  line-height: var(--leading-body-lg);
  color: var(--color-sand);   /* the gradient's core is Ink Elevated, where Ink Mist measures 3.89:1 */
  max-width: 62ch;
  margin: 20px 0 0;
}
.hero-cta { margin-top: 32px; }

/* ---- Waveform ---- */
.waveform-band {
  position: absolute;
  inset: auto 0 0 0;
  height: var(--wave-h);
  pointer-events: none;
}
.waveform {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  height: 100%;
  width: 100%;
  gap: 3px;
  -webkit-mask-image: linear-gradient(180deg, rgb(0 0 0) 0%, rgb(0 0 0) 60%, transparent 100%);
          mask-image: linear-gradient(180deg, rgb(0 0 0) 0%, rgb(0 0 0) 60%, transparent 100%);
}
.waveform-bar {
  flex: 1 1 0;
  max-width: 10px;
  height: calc(100% * var(--bar-amp, 1));
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}

/* ---- Live call cards ----
   Desktop: an absolute overlay across the hero zone, cards at the edges.
   Below 1180: a normal band that follows the hero, so the fold keeps
   the waveform and the live card becomes the first scroll reward. */
.hero-cards {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 2;
}
.call-card {
  position: absolute;
  box-sizing: border-box;   /* 340px is the spec's rendered width, not its content box */
  width: var(--card-w, 340px);
  background: var(--color-ink-elevated);
  border: 1px solid var(--color-ink-line);
  border-radius: var(--radius-md);
  padding: var(--card-padding);
  text-align: left;
  pointer-events: auto;
}
/* The diagonal: live card high on the right, completed card low on the left.
   The completed card is anchored above the waveform band rather than to a vh
   figure, so it keeps its clearance from the bars at every viewport height. */
.call-card.card-live     { right: var(--card-inset); top: var(--card-live-top); }
.call-card.card-complete {
  left: var(--card-inset);
  top: auto;
  bottom: calc(var(--wave-h) + var(--card-complete-clear));
}

/* Three columns from 1024 up. The card column narrows as the viewport does,
   so the centre never starves; the headline follows the centre's own width
   via cqw and therefore holds ~20ch at every one of these widths. */
@media (min-width: 1180px) {
  .hero-zone {
    --hero-centre-w: calc(100% - 2 * (var(--card-w) + var(--card-gap)));
    /* The diagonal costs TWICE its drop in hero height, so on a short laptop
       it was pushing the hero past the viewport and taking the waveform out of
       the fold with it. The drop now spends only the height that is spare:
       full 64px from 809px up, tapering to zero at 681px, which is
       96 top + 356 centre + 228 reserve -- the hero's irreducible height.
       RE-DERIVED 2026-08-28 from 709 after the hero subhead lost the
       reusability claim and shortened by a line. Measured at 1440, the
       TIGHTEST width in this band and therefore the one where the centre
       column runs tallest -- above 1440 the column only widens. It degrades
       gracefully: lengthen the copy and the band slips under the fold again,
       it never crosses the CTA. */
    --hero-drop: clamp(0px, (100vh - 681px) / 2, var(--spacing-64));
    --card-live-top: var(--spacing-96);          /* hard to the top of the hero */
    --card-complete-clear: var(--spacing-32);    /* and hard to the bottom */
  }
  /* The centre is centred inside the hero's content box, so padding the top by
     TWICE the drop moves it down by exactly the drop. The absolute cards are
     positioned against the padding box and are untouched by this. */
  .hero { padding-top: calc(var(--spacing-96) + 2 * var(--hero-drop)); }
  /* The container query was sizing the display step off .hero-centre, which
     is only ~437px once the two call cards take their 680px, so the flagship
     headline rendered at the 36px FLOOR from 1180 to 1220 -- the same size it
     takes on a 360px phone -- and never reached its documented step at any
     width. The type scale is the authority per ruling AA, and the 22ch cap is
     what design.md already prescribes for holding the measure. */
  .hero h1 { font-size: var(--text-display); }
}
@media (min-width: 1180px) and (max-width: 1439.98px) {
  .hero-zone {
    --card-w: 300px;
    --card-gap: var(--spacing-40);
    /* 32 rather than 48: at 800px tall the waveform pins the lower card and a
       deeper drop closes the gap between the headline and that card instead
       of opening the one above it. Height binds this band, not width. */
    /* Same taper, its own floor: the centre column is narrower in this band
       and so runs taller -- 443px at 1180 against 356px at 1440 -- putting the
       irreducible height at 768px. RE-DERIVED 2026-08-28 from 774, and
       measured at 1180 rather than at 1280: the old figure was taken at one
       convenient width inside the band instead of at its tightest, which is
       the mistake this file has been caught making before. */
    --hero-drop: clamp(0px, (100vh - 768px) / 2, var(--spacing-32));
  }
}

.call-card-header {
  display: flex;
  align-items: center;
  gap: 8px;
}
.call-card-label { color: var(--color-sand); }
.call-card-timer {
  margin-left: auto;
  color: var(--color-sand);   /* ruling T: Ink Mist is 3.89:1 on Ink Elevated */
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  line-height: var(--leading-micro);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-micro);
  font-variant-numeric: tabular-nums;
}
.call-card-body { margin-top: 16px; display: flex; flex-direction: column; gap: 10px; }

.transcript-line {
  display: flex;
  gap: 8px;
  font-size: var(--text-body-sm);
  line-height: var(--leading-body-lg);
  letter-spacing: var(--tracking-body-sm);
}
.transcript-line .rule {
  flex: none;
  width: 2px; height: 12px;
  margin-top: 5px;
}
.transcript-line.from-customer { color: var(--color-ink-mist); }
.transcript-line.from-customer .rule { background: var(--color-ink-line); }
.transcript-line.from-agent { color: var(--color-linen); }
.transcript-line.from-agent .rule { background: var(--color-linen); }   /* ruling AB: was Ember */

.call-card-footer { margin-top: 16px; }

/* Ruling AE: a pill on the Live Call Card sits on Ink Elevated, so it takes an
   Ink fill exactly as ruling U requires of every other pill on that surface.
   That surface step is what buys the working label its 5.48:1; on the pill's
   own Ink Elevated fill the same Ember measured 4.44:1 and failed AA, and the
   build had been quietly painting it Sand under a rule written about Ink Mist. */
.call-card .status-pill { background: var(--color-ink); }

/* ---- Status pill ---- */
.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--color-ink-elevated);
  border: 1px solid var(--color-ink-line);
  border-radius: var(--radius-sm);
  padding: 4px 8px;
  min-height: 22px;
}
.status-pill .pill-dot {
  width: 8px; height: 8px;
  border-radius: var(--radius-dot);
  background: var(--color-ink-mist);   /* the queued default; states override */
  flex: none;
}
.status-pill .pill-label {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  line-height: var(--leading-micro);
  letter-spacing: var(--tracking-micro);
  font-weight: var(--weight-medium);
  color: var(--color-ink-mist);        /* the queued default; states override */
  transition: color var(--dur-instant) linear;
}
.status-pill[data-state="working"]  .pill-dot   { background: var(--color-ember); }
.status-pill[data-state="working"]  .pill-label { color: var(--color-ember); }
.status-pill[data-state="complete"] .pill-dot   { background: var(--color-sand); }
.status-pill[data-state="complete"] .pill-label { color: var(--color-sand); }

/* ---- Responsive ---- */
@media (max-width: 1179.98px) {
  .hero-cards {
    position: static;
    display: flex;
    justify-content: center;
    padding: 48px var(--gutter);
    background: var(--color-ink);
  }
  .call-card.card-complete { display: none; }
  .call-card.card-live { position: static; }
}
/* Tall tablet viewports have fold budget for the proof card inside the hero.
   Short or narrow viewports do not: the fold-pinned waveform wins there,
   a documented conflict between the fold rule and proof-above-the-fold. */
@media (max-width: 1179.98px) and (min-height: 900px) {
  .call-card.card-complete {
    display: block;
    position: static;
    margin: 32px auto 0;
    width: min(340px, 100%);
  }
}
@media (max-width: 900px) {
  .nav-links { display: none; }
}
@media (max-width: 768px) {
  .hero-zone { --wave-h: 120px; }
}
@media (max-width: 480px) {
  /* Ruling P, delivered rather than merely intended: the bars give up the fold
     to the proof. The band hangs at the foot of the whole hero zone so the
     call card lands immediately under the CTA, which is the arrangement the
     ruling reversed the original fold trade to get. */
  .hero-zone { position: relative; padding-bottom: 96px; }
  /* .hero is the nearest positioned ancestor at wider widths, which would pin
     the band to the hero's own foot rather than the zone's, putting it back
     above the card. The zone is the containing block here. */
  .hero { position: static; }
  /* Deviation from design.md's collapse list, documented in progress.html:
     the wordmark stays at every width. An unnamed cream circle is a worse
     failure than a fourth nav item; design.md should gain the wordmark here. */
  /* Ruling D removed the compact nav CTA, so the full-size button now has to
     be paid for out of the nav's own spacing rather than the button's. */
  .nav { padding: 20px 16px; }
  /* Fold trade REVERSED 2026-08-25. The intro spends its whole budget
     promising that a call arrives, so the phone hero must actually carry one.
     The hero grows to hold it: the waveform gives up the fold, not the proof. */
  /* overflow-x: clip contains the full-bleed band when a scrollbar makes
     the client area narrower than the viewport; overflow-y stays visible. */
  .hero { min-height: 0; overflow-x: clip; overflow-y: visible; padding-bottom: 8px; }
  /* RULING P, delivered rather than intended. The band used to sit between the
     CTA and the call card in flow order, so the proof was below the fold at
     every phone height and the bars never gave it up. It now hangs at the foot
     of the whole hero zone: the card follows the CTA directly, and the bars
     take the overflow.
     Absolute against .hero-zone, which carries no horizontal padding, so the
     full bleed comes for free where the old static rule needed a negative
     margin to cancel the hero's own gutter. */
  .waveform-band {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    width: auto;
    margin: 0;
  }
  .hero-cards { padding-top: 20px; padding-bottom: 56px; }
  .nav-left { gap: 8px; }
  .nav-right { gap: 12px; }
  .hero-zone { --wave-h: 96px; }

  .call-card { width: 100%; max-width: 340px; }
}

/* ---- Piece B: light register, product core ---- */
.band-light {
  background: var(--color-linen);
  color: var(--color-ink);
  padding: var(--spacing-96) var(--gutter);
}
.band-inner { max-width: var(--page-max-width); margin: 0 auto; }
.band-eyebrow { color: var(--color-ink-slate); margin: 0 0 12px; }
.band-light h2 {
  font-size: var(--text-heading);
  line-height: var(--leading-heading);
  letter-spacing: var(--tracking-heading);
  font-weight: var(--weight-regular);
  color: var(--color-ink);
  max-width: var(--headline-max-width);
}
.band-body {
  font-size: var(--text-body);
  line-height: var(--leading-body);
  color: var(--color-ink-slate);
  max-width: 62ch;
  margin: 20px 0 0;
}

/* Application window frame, not browser chrome */
.product-surface {
  margin-top: var(--spacing-48);
  background: var(--color-linen);
  border: 1px solid var(--color-linen-line);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.surface-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 36px;
  padding: 0 16px;
  background: var(--color-linen-sunken);
  border-bottom: 1px solid var(--color-linen-line);
}
.surface-title { color: var(--color-ink-slate); }
.surface-body { display: flex; min-height: 380px; }

.surface-rail {
  width: 200px;
  box-sizing: border-box;
  flex: none;
  border-right: 1px solid var(--color-linen-line);
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 16px 8px;
}
.rail-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  color: var(--color-ink-slate);
  font-size: var(--text-body-sm);
  letter-spacing: var(--tracking-body-sm);
}
.rail-item.active { background: var(--color-linen-sunken); color: var(--color-ink); }
.rail-icon {
  width: 20px; height: 20px;
  flex: none;
  color: var(--color-ink-slate);
  opacity: 0.85;
}
.band-light[id] { scroll-margin-top: 96px; }

.surface-main { flex: 1; padding: 20px; min-width: 0; }
.call-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-body-sm);
  letter-spacing: var(--tracking-body-sm);
}
.call-table th {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  line-height: var(--leading-micro);
  letter-spacing: var(--tracking-micro);
  font-weight: var(--weight-medium);
  color: var(--color-ink-slate);
  text-align: left;
  background: var(--color-linen-sunken);
  padding: 8px 12px;
}
.call-table td {
  padding: 6px 12px;
}
/* Ruling G: the mono law outranks the component's "cell text Inter" line.
   Timestamps and plates are machine metadata; KONU stays the human face. */
.call-table td:nth-child(1), .call-table td:nth-child(2) {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  line-height: var(--leading-micro);
  letter-spacing: var(--tracking-micro);
  font-weight: var(--weight-medium);
  color: var(--color-ink-slate);
  white-space: nowrap;
}
.call-table td {
  border-bottom: 1px solid var(--color-linen-line);
  color: var(--color-ink);
  font-variant-numeric: tabular-nums;
  vertical-align: middle;
}
.call-table td.ref {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  line-height: var(--leading-micro);
  letter-spacing: var(--tracking-micro);
  font-weight: var(--weight-medium);
  color: var(--color-ink-slate);
}

/* Status pills on the light register */
.status-pill.pill-light {
  background: var(--color-linen-sunken);
  border-color: var(--color-linen-line);
}
/* Ruling T: a light-register pill with no state fell through to the dark
   register default, putting Ink Mist on Linen Sunken at 2.90:1. */
.status-pill.pill-light .pill-dot   { background: var(--color-ink-slate); }
.status-pill.pill-light .pill-label { color: var(--color-ink-slate); }
.status-pill.pill-light[data-state="working"]  .pill-dot   { background: var(--color-ember); }
.status-pill.pill-light[data-state="working"]  .pill-label { color: var(--color-ink); }
.status-pill.pill-light[data-state="complete"] .pill-dot   { background: var(--color-ink-slate); }
.status-pill.pill-light[data-state="complete"] .pill-label { color: var(--color-ink-slate); }
.status-pill.pill-light[data-state="queued"]   .pill-dot   { background: var(--color-ink-slate); }   /* ruling T */
.status-pill.pill-light[data-state="queued"]   .pill-label { color: var(--color-ink-slate); }   /* ruling T */

/* Record write rows: the commit moment */
.writes-title { color: var(--color-ink-slate); margin: 24px 0 8px; }
.write-rows { display: flex; flex-direction: column; gap: 8px; }
.write-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 16px;
  box-sizing: border-box;
  height: 44px;
  padding: 0 16px;
  background: var(--color-linen-sunken);
  border: 1px solid var(--color-linen-line);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.write-system { color: var(--color-ink-slate); flex: none; }
.write-field { font-size: var(--text-body-sm); letter-spacing: var(--tracking-body-sm); color: var(--color-ink); flex: 1; min-width: 0; }
.write-ref {
  color: var(--color-ink-slate);
  background: var(--color-linen);
  border: 1px solid var(--color-linen-line);
  border-radius: var(--radius-sm);
  padding: 3px 6px;
}
/* Reserved, not hidden. Collapsed until the reference arrived, the row grew
   at the exact moment of the commit -- the one event bar.md calls the most
   satisfying on the page, landing as a jump. */
.write-ref:empty { visibility: hidden; }
.write-ref:empty::after { content: "SRV-00000"; }
.write-sweep {
  position: absolute;
  inset: 0 auto 0 0;
  width: 40%;
  background: linear-gradient(90deg, transparent, rgb(255 90 54 / 0.18), transparent);
  transform: translateX(-100%);
  pointer-events: none;
}
.write-row.committing .write-sweep {
  animation: record-write-sweep var(--dur-sweep) var(--ease-signal) 1 both;
}

/* Activity feed */
.surface-feed {
  width: 280px;
  box-sizing: border-box;
  flex: none;
  border-left: 1px solid var(--color-linen-line);
  padding: 20px 16px;
}
.feed-title { color: var(--color-ink-slate); margin: 0 0 12px; }
.feed-item {
  display: flex;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid var(--color-linen-line);
  font-size: var(--text-caption);
  line-height: var(--leading-caption);
  letter-spacing: var(--tracking-caption);
  color: var(--color-ink-slate);
}
.feed-item .mono { color: var(--color-ink-slate); flex: none; }

@media (max-width: 1024px) {
  .surface-feed { display: none; }
}
@media (max-width: 768px) {
  .surface-rail { display: none; }
  .band-light { padding: var(--spacing-64) var(--gutter); }
}
/* At phone width the table restacks as cards: plate and belge share the
   top line, topic below, full status pill last. Nothing clips, the
   call-to-record join stays visible, SAAT alone yields. */
@media (max-width: 540px) {
  .call-table, .call-table tbody { display: block; }
  .call-table thead { display: none; }
  .call-table tr {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 12px;
    padding: 12px 0;
    border-bottom: 1px solid var(--color-linen-line);
  }
  .call-table td { display: block; border-bottom: none; padding: 0; height: auto; }
  .call-table td:nth-child(1) { display: none; }
  .call-table td:nth-child(2) { order: 1; }
  .call-table td:nth-child(5) { order: 2; margin-left: auto; }
  .call-table td:nth-child(3) { order: 3; flex-basis: 100%; }
  .call-table td:nth-child(4) { order: 4; }
  .write-row { gap: 10px; flex-wrap: wrap; height: auto; min-height: 44px; padding: 10px 16px; }
  .write-system { order: 1; }
  .write-ref { order: 2; margin-left: auto; }
  .write-field { order: 3; flex-basis: 100%; }
}

/* ---- Piece C: seams, how it works, integrations ---- */

/* The register seam: navy meets cream through dawn, never through mud. */
.register-seam {
  height: 120px;
  background: linear-gradient(180deg,
    var(--color-ink) 0%,
    color-mix(in oklab, var(--color-sand) 26%, var(--color-ink)) 55%,
    var(--color-linen) 100%);
}
.register-seam.reverse {
  background: linear-gradient(180deg,
    var(--color-linen) 0%,
    color-mix(in oklab, var(--color-sand) 26%, var(--color-ink)) 45%,
    var(--color-ink) 100%);
}

/* Dark band: centred, per the band model. */
.band-dark {
  background: var(--color-ink);
  color: var(--color-linen);
  padding: var(--spacing-96) var(--gutter);
}
.band-dark[id] { scroll-margin-top: 96px; }
.band-centred {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
.eyebrow-dark { color: var(--color-ink-mist); }
.band-dark h2 {
  font-size: var(--text-heading-lg);
  line-height: var(--leading-heading-lg);
  letter-spacing: var(--tracking-heading-lg);
  font-weight: var(--weight-light);
  color: var(--color-linen);
  max-width: var(--headline-max-width);
}
.body-dark { color: var(--color-ink-mist); }

/* ================= The stack =================
   The Agent Roster Card is ABSORBED here, per ruling W: the job / schedule /
   system-of-record triple and the deployment label survive, the card frame
   does not.

   The enclosure is the dark-register sibling of the Light Product Surface,
   with its canvas one step BELOW the page per ruling AC, so the ladder runs
   page -> canvas down -> chrome up -> row up.

   THE SPINE, ruling AG. Five ordinals on one vertical line, one entry pitch apart:
   the pitch is SEEN rather than inferred. It has no hairline; see below. It also
   empties the eyebrow of everything but the product name, which had left
   every entry with two byte-identical mono lines. The rail's index is pinned,
   interactive and tracks the reader; this is a static rule that never
   changes. The opposition that matters is intact. */
.stack {
  /* One spine width and one inset, so the chrome, the ordinals, the entry
     text and the terminal line all measure from the same two numbers. */
  --stack-spine: 64px;
  --stack-inset: var(--spacing-24);
  box-sizing: border-box;
  width: 100%;
  max-width: var(--page-max-width);
  margin-top: var(--spacing-40);
  text-align: left;
  background: var(--color-ink-deep);
  border: 1px solid var(--color-ink-line);
  border-radius: var(--radius-md);
  overflow: hidden;
}
/* The chrome sits BETWEEN the canvas and the content, and the spine divides
   it, so the strip is a header with two cells rather than a mostly empty bar. */
.stack-head {
  display: grid;
  grid-template-columns: var(--stack-spine) minmax(0, 1fr);
  align-items: center;
  box-sizing: border-box;
  height: 36px;
  background: var(--color-ink);
  border-bottom: 1px solid var(--color-ink-line);
}
.stack-title { grid-column: 2; padding-left: var(--stack-inset); color: var(--color-sand); }
/* The closing rule spans the whole enclosure; only the TEXT is capped. */
.stack-foot {
  padding: var(--spacing-12) var(--stack-inset) var(--spacing-12) calc(var(--stack-spine) + var(--stack-inset));
  border-top: 1px solid var(--color-ink-line);
}
.stack-foot p {
  margin: 0;
  max-width: var(--content-max-width);
  font-size: var(--text-caption);
  line-height: var(--leading-caption);
  letter-spacing: var(--tracking-caption);
  color: var(--color-ink-mist);
}

/* ---- One layer entry ---- */
.layer {
  display: grid;
  grid-template-columns: var(--stack-spine) minmax(0, 452px) minmax(0, 1fr);
  column-gap: 0;
  align-items: start;
  box-sizing: border-box;
  min-height: 352px;   /* the tallest entry once the wells' interiors recessed */
  padding: var(--spacing-32) var(--stack-inset) var(--spacing-32) 0;
  border-top: 1px solid var(--color-ink-line);
}
/* first-child loses 1px of border, so it gains 1px of padding: without this
   the first interval measures 289 where the other four measure 288. */
.layer:first-child { border-top: 0; padding-top: calc(var(--spacing-32) + 1px); }
.layer-no {
  grid-column: 1;
  align-self: start;
  margin: 0;
  padding-left: var(--stack-inset);
  font-size: var(--text-mono-sm);
  line-height: var(--leading-mono-sm);
  margin-top: -5px;   /* optical: 13px and 11px mono share a box top but not a baseline */
  letter-spacing: var(--tracking-mono-sm);
  font-weight: var(--weight-regular);
  color: var(--color-sand);
}
/* THE SPINE HAS NO HAIRLINE, and that is a correction, not an omission. Drawn
   as a 1px Ink Line rule it measured 1.67:1 on this canvas: the least visible
   mark in the enclosure was the one carrying the pitch, which is exactly what
   ruling AG's second half forbids. It was also redundant twice over, because
   the ordinals and the entry separators already mark the interval between
   them, and it put a vertical line at the same x as the step rail's own track
   two hundred pixels below, which spent one of the four oppositions the Stack
   Enclosure spec calls load bearing. The ordinals alone hold the column. */
.stack-body { position: relative; }
/* STRETCHED, so the auto margin on the foot has free space to consume and
   every meta rule lands on one shared horizontal. Left as start-aligned, the
   auto margin was dead CSS and the five rules ragged by 26px. */
.layer-text { grid-column: 2; padding-left: var(--stack-inset); align-self: stretch; display: flex; flex-direction: column; align-items: flex-start; width: 100%; }
.layer-view { grid-column: 3; margin-left: var(--spacing-48); }
.layer-eyebrow {
  font-size: var(--text-mono-sm);
  line-height: var(--leading-mono-sm);
  letter-spacing: var(--tracking-mono-sm);
  font-weight: var(--weight-regular);
  color: var(--color-linen);
  margin: 0 0 var(--spacing-12);
}
.layer h3 {
  font-size: var(--text-subheading);
  line-height: var(--leading-subheading);
  letter-spacing: var(--tracking-subheading);
  font-weight: var(--weight-medium);
  color: var(--color-linen);
  max-width: 22ch;
  margin: 0;
}
.layer-body {
  font-size: var(--text-body);
  line-height: var(--leading-body);
  color: var(--color-ink-mist);
  max-width: 40ch;
  margin: var(--spacing-12) 0 0;
}
/* A real tab stop. margin-left:auto IS space-between, and it opened holes of
   85 to 145px at desktop and 250 to 306 stacked, five entries and five values.
   A fixed right column also gives SAHADA and HAZIR one shared LEFT edge. */
.layer-foot {
  display: grid;
  /* 100px, not 88. The tab stop has to clear the LONGEST deployment label in
     EITHER language, and IN PRODUCTION measures 97.24px against SAHADA's 44.88.
     At 88 it wrapped to two lines and made the Voice entry's foot 16px taller
     than the other four -- the pitch the spine exists to make visible, broken
     by one word. One value for both locales, so the stop is shared across the
     five entries AND identical between languages. */
  grid-template-columns: minmax(0, 1fr) 100px;
  align-items: center;
  /* 8, not 16. The foot is capped at the body's own 40ch measure -- 404px --
     and the widest case across BOTH locales is Turkish YERİNDE ÇALIŞTIRMA at
     294.33px beside English IN PRODUCTION at 97.24px, which is 391.57px of
     content. Sixteen does not fit in the 12.43px left over; eight fits with
     4.43px to spare. Widening the cap was the alternative and it is worse: the
     foot rule would then overhang the body paragraph above it, which is the
     defect the 40ch cap was introduced to fix. Nine of the ten entry-and-locale
     combinations still show a 100px gap or more; this only binds the widest. */
  gap: var(--spacing-8);
  width: 100%;
  max-width: 40ch;
  margin-top: auto;
  padding-top: var(--spacing-16);
  border-top: 1px solid var(--color-ink-line);
}
/* nowrap so a future label that outgrows the column overflows VISIBLY rather
   than silently re-wrapping and changing one entry's height again. */
.layer-deploy { white-space: nowrap; }
.layer-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  color: var(--color-ink-mist);
  margin: 0;
  max-width: none;
}
.layer-meta .vrule,
.layer-meta span { white-space: nowrap; }
.layer-deploy { justify-self: start; color: var(--color-ink-mist); }
.layer-deploy.is-live { color: var(--color-sand); }

/* ---- The wells ----
   Every well a DIFFERENT SHAPE, tested on a screen rather than in a spec. */
/* The wells STRETCH and close on the same horizontal as the foot rule beside
   them. Left to their natural height they ended at five different places,
   ragging across 92px and leaving an average of 97px of canvas in the same
   bottom-right corner of every entry: a third of each cell, five times, in an
   L. Making the pitch visible is what made that hole visible. Only the left
   column was closing; now both do. */
.layer-view {
  display: flex;
  flex-direction: column;
  align-self: stretch;
  justify-content: flex-start;
  box-sizing: border-box;
  gap: var(--spacing-12);
  min-height: 176px;
  padding: var(--spacing-20);
  background: var(--color-ink-elevated);
  border: 1px solid var(--color-ink-line);
  border-radius: var(--radius-md);
}
/* Ruling T: on Ink Elevated, Ink Mist is 3.89:1 and takes Sand instead. */
.lv-call-meta, .qa-label, .qa-q, .source-label, .source-doc, .tl-sys, .inbound-label, .perimeter-edge {
  color: var(--color-sand);
}
/* Interiors recess INTO the panel, one step down, the way a console's rows do. */

/* 1. Voice. The metadata line is what makes the transcript visibly a
   conversation rather than two sentences above a record row. */
.lv-call-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  max-width: none;
}
/* The recess. Any block that is CONTENT rather than chrome sits one step into
   the panel. Written once: three wells were unbounded text on a surface, which
   is the panel change half-applied. */
.qa.is-well, .tl-stop.is-well, .lv-outcome {
  box-sizing: border-box;
  background: var(--color-ink);
  border: 1px solid var(--color-ink-line);
  border-radius: var(--radius-sm);
  padding: var(--spacing-12) var(--spacing-16);
}
/* The stretch lands HERE, once, above the block that is the well's
   consequence. Divided by space-between it became 39px between every pair in
   Voice and 44px in Agents -- holes three and five times the authored gap. */
.lv-voice > .lv-outcome,
.lv-agents > .act-row:last-child,
.lv-knowledge > .source { margin-top: auto; }
.lv-talk { display: flex; flex-direction: column; gap: var(--spacing-8); }
.lv-turn {
  display: flex;
  align-items: baseline;
  gap: var(--spacing-12);
  margin: 0;
  padding: 0;
  font-size: var(--text-body-sm);
  line-height: var(--leading-body-sm);
  letter-spacing: var(--tracking-body-sm);
  color: var(--color-sand);
}
.lv-turn.is-agent { color: var(--color-linen); }
/* The speaker is named rather than ticked. A 2px mark is punctuation; a name is
   a participant, which is what separates a console from a mockup. */
.lv-who { flex: none; min-width: 56px; color: var(--color-sand); }
/* The record hangs off the agent's own rule as the consequence of what was
   just said, rather than standing as a fourth filled chip identical to the
   three in the Agents well two entries down. Same leading-rule device as the
   transcript above it, so it reads as the line's outcome. */
.lv-outcome {
  display: flex;
  align-items: baseline;
  gap: var(--spacing-12);
  margin: 0;
  font-size: var(--text-body-sm);
  line-height: var(--leading-body-sm);
  letter-spacing: var(--tracking-body-sm);
  color: var(--color-linen);
}
.lv-outcome .mono { flex: none; color: var(--color-sand); }
.lv-outcome .lv-ref { margin-left: auto; }
.lv-outcome > span:nth-child(2) { flex: 1; min-width: 0; }

/* 2. Knowledge. Labelled on both sides, because SORU with no YANIT is half a
   transcript. The question takes Sand rather than Ink Mist so it cannot be
   confused with the marketing body 500px to its left, which is the same
   colour at the same size. The citation is INDENTED past the question: a
   quotation rule flush with what it quotes is a tick, not a citation mark. */
.lv-knowledge { gap: var(--spacing-20); }
.qa { display: flex; flex-direction: column; }
.qa.is-well { gap: 0; }
.qa-label { margin: 0 0 var(--spacing-8); }
.qa-label-a { margin-top: var(--spacing-16); }
.qa-q {
  margin: 0;
  font-size: var(--text-body-sm);
  line-height: var(--leading-body-sm);
  letter-spacing: var(--tracking-body-sm);
  color: var(--color-sand);
  max-width: 46ch;
}
.qa-a {
  margin: 0;
  font-size: var(--text-body-sm);
  line-height: var(--leading-body-sm);
  letter-spacing: var(--tracking-body-sm);
  color: var(--color-sand);
  max-width: 52ch;
}
.source { display: flex; align-items: stretch; gap: var(--spacing-12); margin-left: var(--spacing-24); }
.source-rule { flex: none; width: 2px; background: var(--color-sand); }
.source-body { display: flex; flex-direction: column; gap: var(--spacing-4); min-width: 0; }

/* Three values, not two. Set at the same size and colour as the question
   above it, the cited document was one voice with the thing it was citing. */
.source-doc {
  font-size: var(--text-body-sm);
  line-height: var(--leading-body-sm);
  letter-spacing: var(--tracking-body-sm);
}
/* The locator takes the peak: it is the part a reader can go and check.
   Linen at 16.31:1 against the title's Sand at 11.38:1, and the machine face,
   because a pointer into a document is machine metadata while the document's
   own title is not. Sentence case, per the Case rule at 13px. */
.source-loc {
  font-size: var(--text-mono-sm);
  line-height: var(--leading-mono-sm);
  letter-spacing: var(--tracking-mono-sm);
  font-weight: var(--weight-regular);
  color: var(--color-linen);
}

/* 3. Agents. Three DIFFERENT systems, and one shared left edge for the action
   text: as flex items the three system names set three different starts, in a
   well that is meant to read as a record. */
.lv-agents { gap: var(--spacing-8); }
.act-row {
  display: flex;
  align-items: center;
  gap: var(--spacing-16);
  box-sizing: border-box;
  min-height: 44px;              /* fixed, the two-line row rendered at zero padding */
  padding: 10px var(--spacing-16);
  background: var(--color-ink);      /* recessed INTO the panel; see the Layer Entry surface rule */
  border: 1px solid var(--color-ink-line);
  border-radius: var(--radius-md);
}
.act-sys { color: var(--color-sand); flex: none; min-width: 140px; white-space: nowrap; }
.act-do {
  font-size: var(--text-body-sm);
  line-height: var(--leading-body-sm);
  letter-spacing: var(--tracking-body-sm);
  color: var(--color-linen);
  flex: 1;
  min-width: 0;
}
.act-ref {
  color: var(--color-sand);
  background: var(--color-ink-deep);   /* the row recessed to Ink; the tag steps again */
  border: 1px solid var(--color-ink-line);
  border-radius: var(--radius-sm);
  padding: 3px 6px;
  flex: none;
}
/* Ruling U: a pill on an Ink Elevated surface takes an Ink fill, which is
   what buys the Ember label 5.48:1 instead of 4.44:1. */
.act-row .status-pill { background: var(--color-ink-deep); flex: none; }   /* ruling U, against the row's own Ink */
.status-pill[data-state="escalated"] { border-color: var(--color-ember); }
.status-pill[data-state="escalated"] .pill-dot { background: var(--color-ember); }
.status-pill[data-state="escalated"] .pill-label { color: var(--color-ember); }
/* Ruling X: nothing here moves, including a dormant transition on a pill
   whose state can never change. */
#katmanlar .pill-label { transition: none; }

/* 4. Workflow. TWO marks, ONE interval. Drawn with three marks the axis gave
   four days 278px and zero days 139px, which said two days passed between two
   events on the same day. Both day-five events now hang under one mark, so
   the only interval with elapsed time is the only interval with width.
   The run is Sand, not Ink Line: at 1.67:1 on this canvas a hairline is not a
   shape, and design.md's own ruling says a claim carried by an invisible mark
   is carried by its caption. Ruling AG.
   The caption is a SIBLING of the run and sits ABOVE it, so the width is
   uninterrupted and the label survives the stacked breakpoint. */
.lv-flow > .tl { height: 100%; }
.tl {
  display: grid;
  grid-template-columns: 2px minmax(0, 1fr) 2px minmax(0, 220px);
  grid-template-rows: 28px auto;
  align-content: space-between;
  align-items: start;
  padding-top: var(--spacing-20);
}
.tl-mark { grid-row: 1; align-self: start; width: 2px; height: 16px; background: var(--color-sand); }
.tl-m1 { grid-column: 1; }
.tl-m2 { grid-column: 3; }
.tl-run { grid-row: 1; grid-column: 2; height: 1px; margin-top: 7px; background: var(--color-sand); }
.tl-gap {
  grid-row: 1;
  grid-column: 2;
  justify-self: center;
  align-self: start;
  margin: -14px 0 0;
  color: var(--color-sand);
  white-space: nowrap;
}
.tl-stop { grid-row: 2; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tl-s1 { grid-column: 1 / span 2; margin-right: var(--spacing-16); }
.tl-s2 { grid-column: 3 / span 2; }
.tl-when { color: var(--color-sand); }
.tl-sys { margin-top: var(--spacing-8); }
.tl-do {
  font-size: var(--text-body-sm);
  line-height: var(--leading-body-sm);
  letter-spacing: var(--tracking-body-sm);
  color: var(--color-linen);
}

/* 5. Private AI. UNFILLED 1px rectangles, which is what the Imagery rule
   specifies and what stops this well being a third copy of the filled row.
   The inbound line runs THROUGH the wall onto the Voice node; stopping at the
   wall said the outside world touches the perimeter and halts, which is the
   opposite of the layer's premise. Nothing leaves. */
/* Everything in this well was drawn at 1.67:1, so the layer whose whole claim
   is "this runs on hardware you own" was the palest object in the band. The
   perimeter and the inbound line CARRY the claim and take Sand at 11.38:1;
   the interior nodes are containment and stay Ink Line, per ruling AG.
   Centred, so the line lands on the node row by construction rather than by a
   hand-rolled offset that drifted at every breakpoint. */
.lv-private { flex-direction: row; align-items: stretch; gap: 0; }
.lv-private .perimeter { align-self: stretch; }
/* The line enters on the FIRST node row's centre, which is where a call would
   arrive, not on the box's midpoint between two rows. */
.inbound-label { align-self: flex-start; margin-top: calc(var(--spacing-20) + 20px - 8px); }
.inbound-line { align-self: flex-start; margin-top: calc(var(--spacing-20) + 20px); }

.inbound-label { flex: none; white-space: nowrap; }
.inbound-line {
  position: relative;
  z-index: 1;
  flex: none;
  width: calc(var(--spacing-24) + var(--spacing-20) + var(--spacing-8));
  height: 1px;
  background: var(--color-sand);
  margin-left: var(--spacing-8);
  margin-right: calc((var(--spacing-20) + var(--spacing-8)) * -1);
}
.perimeter {
  position: relative;
  box-sizing: border-box;
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;   /* the perimeter's top is the well's top, so the first node
                                    row sits at a KNOWN offset and the inbound line can meet it
                                    by construction rather than by chasing a centred box */
  border: 1px solid var(--color-sand);
  border-radius: var(--radius-sm);
  padding: var(--spacing-20);
}
.perimeter-label,
.perimeter-edge {
  position: absolute;
  padding: 0 var(--spacing-8);
  background: var(--color-ink-elevated);   /* the panel, not the enclosure canvas beneath it */
}
.perimeter-label { top: -8px; left: var(--spacing-16); color: var(--color-sand); }
.perimeter-edge, .perimeter-label { z-index: 1; }
.perimeter-edge { bottom: -8px; right: var(--spacing-16); }
.p-nodes { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--spacing-8); }
.p-node {
  display: grid;
  place-items: center;
  box-sizing: border-box;
  min-height: 40px;
  padding: var(--spacing-8) var(--spacing-4);
  background: var(--color-ink);      /* recessed INTO the panel */
  border: 1px solid var(--color-ink-line);
  border-radius: var(--radius-sm);
  color: var(--color-linen);
  text-align: center;
}
.p-node-sys { grid-column: 1 / -1; color: var(--color-sand); }
.p-foot {
  margin-top: var(--spacing-16);
  padding-top: var(--spacing-12);
  border-top: 1px solid var(--color-ink-line);
  color: var(--color-sand);
}

@media (max-width: 1179.98px) {
  .stack { --stack-inset: var(--spacing-20); }
  .layer {
    grid-template-columns: var(--stack-spine) minmax(0, 1fr);
    row-gap: var(--spacing-24);
    min-height: 640px;   /* clears the tallest natural entry ACROSS this range, measured at its narrow end */
    padding: var(--spacing-24) var(--stack-inset) var(--spacing-24) 0;
  }
  .layer:first-child { padding-top: calc(var(--spacing-24) + 1px); }
  .layer-text, .layer-view { grid-column: 2; padding-left: var(--stack-inset); }
  .layer-view { margin-left: 0; }
  .layer-body { max-width: 56ch; }
  .layer-foot { max-width: 56ch; }
  .layer-view { min-height: 0; }

  /* The time axis needs width. Stacked, it becomes a list, and the WAIT KEEPS
     ITS OWN ROW: the caption is a sibling of the run for exactly this reason,
     so hiding the run cannot delete the fact. */
  /* The axis ROTATES rather than disappearing. Hidden, the four days fell back
     onto their caption, which is the defect ruling AG exists to end; the wait
     is still physical, it is just measured downward now. */
  .lv-flow > .tl { height: auto; }
  /* Three explicit rows: a tick at day one, the run beside the wait, a tick at
     day five. Left to auto-placement all three landed in row one and the run
     measured the day-one paragraph. */
  .tl {
    grid-template-columns: 2px minmax(0, 1fr);
    grid-template-rows: auto auto auto;
    align-content: start;
    padding-top: 0;
    column-gap: var(--spacing-16);
  }
  .tl-mark { grid-column: 1; width: 16px; height: 2px; margin-left: -7px; align-self: start; }
  .tl-m1 { grid-row: 1; margin-top: 7px; }
  .tl-m2 { grid-row: 3; margin-top: 7px; }
  .tl-run {
    grid-column: 1;
    grid-row: 2;
    width: 1px;
    height: 100%;
    min-height: 48px;
    margin: 0 auto;
    background: var(--color-sand);
  }
  .tl-s1 { grid-row: 1; }
  .tl-gap { grid-row: 2; }
  .tl-s2 { grid-row: 3; }
  .tl-stop, .tl-gap { grid-column: 2; justify-self: stretch; margin: 0; }
  .tl-gap { align-self: center; padding: var(--spacing-20) 0; }
  .tl-stop { padding: 0; }
}
@media (max-width: 768px) {
  /* Wrapped, the line inherited space-between and was flung to the opposite
     edge, ending 29px above the perimeter with nothing at either end. Stacked,
     the label sits above the box and the line runs DOWN into its top edge. */
  .lv-private { flex-wrap: wrap; align-content: flex-start; justify-content: flex-start; align-items: flex-start; }
  .inbound-label { align-self: flex-start; }
  .inbound-line {
    align-self: flex-start;
    width: 1px;
    height: var(--spacing-16);
    margin: var(--spacing-8) 0 0 var(--spacing-12);
  }
  .perimeter { flex: 1 0 100%; margin-top: calc(var(--spacing-8) * -1); }
  .p-nodes { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* The row must be able to wrap from the moment the well narrows, not from the
   phone breakpoint. Between 481 and 619 it could not, and design.md's Turkish
   binding is explicit that overflow-wrap is the guaranteed floor so a long
   compound can never push a card open. This one pushed it open by 1900px. */
@media (max-width: 1179.98px) {
  .act-row {
    min-height: 44px;
    flex-wrap: wrap;
    gap: var(--spacing-8) var(--spacing-12);
  }
  .act-sys { min-width: 0; }
  .act-do { flex: 1 1 100%; }
  /* A named speaker beside its line needs width neither has at phone size:
     the turn and the outcome stack, label over text. */
  .lv-turn, .lv-outcome {
    display: block;
  }
  .lv-who, .lv-outcome .mono {
    display: block;
    margin-bottom: var(--spacing-4);
  }
  .lv-outcome .lv-ref { margin-left: 0; margin-top: var(--spacing-4); }
}
@media (max-width: 480px) {
  .stack { --stack-spine: 44px; --stack-inset: var(--spacing-16); }
  .stack-head { min-height: 36px; height: auto; }
  .layer {
    min-height: 792px;   /* clears the tallest natural entry across 360 to 480, not just at 480 */
    padding: var(--spacing-20) var(--stack-inset) var(--spacing-20) 0;
  }
  .layer:first-child { padding-top: calc(var(--spacing-20) + 1px); }
  .layer-foot { grid-template-columns: minmax(0, 1fr); gap: var(--spacing-8); }
  /* Nothing may clip mid glyph at phone width: the rows wrap and grow. */
  .act-row,
  .act-sys { min-width: 0; }
  .act-do { flex: 1 1 100%; }
  .source { margin-left: var(--spacing-12); }
  .p-nodes { grid-template-columns: minmax(0, 1fr); }
  /* A separator that wraps to the head of the next line separates nothing. */
  .layer-meta .vrule { display: none; }
  .layer-meta, .lv-call-meta { gap: 4px 16px; flex-wrap: wrap; }
}

/* Integration flow */
.integration-flow {
  display: flex;
  align-items: center;
  gap: 0;
  margin-top: var(--spacing-48);
}
.elia-node {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  width: 120px;
}
.elia-node-mark {
  width: 40px; height: 40px;
  border-radius: var(--radius-dot);
  background: var(--color-ember);
}
.elia-node-name { font-size: 16px; }
.integration-edges { flex: 1; height: 340px; min-width: 0; margin-left: -56px; }
.elia-node { position: relative; z-index: 1; }
.edge-base { fill: none; stroke: var(--color-ink-haze); stroke-width: 1; }
/* A 24px dash TRAVELLING the path, per the Integration Row spec, not a
   permanent full-length stroke. Built as a full-length dash it left six
   static Ember lines standing on the Linen band forever, which is decorative
   accent: a finished write path is neither an action nor a live state, which
   is ruling AB's own test. The dash retires when it lands; the Ink Haze base
   path is what remains, because the CONNECTION is permanent and the WRITE is
   the event. */
.edge-ember {
  fill: none;
  stroke: var(--color-ember);
  stroke-width: 1;
  stroke-dasharray: 24 var(--edge-length, 1000);
  stroke-dashoffset: var(--edge-length, 1000);
  opacity: 0;
}
.integration-flow.drawn .edge-ember {
  animation: integration-edge-draw var(--dur-draw) var(--ease-signal) 1 both;
  animation-delay: calc(var(--edge-i) * var(--stagger));
  opacity: 1;
  transition: opacity var(--dur-base) var(--ease-exit);
}
.integration-flow.drawn.spent .edge-ember { opacity: 0; }
.system-tiles {
  flex: none;
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 220px;
}
.system-tile {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  height: 56px;
  padding: 0 16px;
  box-sizing: border-box;
  background: var(--color-linen);
  border: 1px solid var(--color-linen-line);
  border-radius: var(--radius-sm);
}
.tile-name {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  line-height: var(--leading-micro);
  letter-spacing: var(--tracking-micro);
  font-weight: var(--weight-medium);
  color: var(--color-ink-slate);
}
.tile-cat { color: var(--color-ink-slate); }

@media (max-width: 768px) {
  .integration-flow { flex-direction: column; gap: var(--spacing-24); }
  .integration-edges, .elia-node { display: none; }
  .system-tiles { width: 100%; display: grid; grid-template-columns: 1fr 1fr; }
  .band-dark { padding: var(--spacing-64) var(--gutter); }
}
@media (max-width: 480px) {
  .system-tiles { grid-template-columns: 1fr; }
}

/* ---- Piece D: proof, close, footer ---- */
#kanit { padding-top: var(--spacing-160); padding-bottom: var(--spacing-160); }
.stat-row {
  display: flex;
  justify-content: center;
  gap: var(--spacing-64);
  margin-top: var(--spacing-64);
}
.stat-block { text-align: center; }
.stat-number {
  font-family: var(--font-display);
  font-size: var(--text-stat);
  line-height: var(--leading-stat);
  letter-spacing: var(--tracking-stat);
  font-weight: var(--weight-light);
  font-variant-numeric: tabular-nums;
  color: var(--color-linen);
  margin: 0;
}
.stat-desc {
  font-size: var(--text-body-sm);
  line-height: var(--leading-body-sm);
  letter-spacing: var(--tracking-body-sm);
  color: var(--color-ink-mist);
  margin: 12px 0 0;
}

.band-close { padding-top: var(--spacing-160); padding-bottom: var(--spacing-160); }
.band-close h2 {
  font-size: var(--text-heading-lg);
  line-height: var(--leading-heading-lg);
  letter-spacing: var(--tracking-heading-lg);
  font-weight: var(--weight-light);
}
.close-cta { margin-top: var(--spacing-48); }

/* Footer: Ink Deep, hairline top, zero Ember, zero motion. */
.footer {
  background: var(--color-ink-deep);
  border-top: 1px solid var(--color-ink-line);
  padding: var(--spacing-96) var(--gutter) var(--spacing-40);
}
.footer-grid {
  display: grid;
  /* Three, not five. Two of the five held nothing once the placeholder links
     were removed, and a heading with nothing under it is worse than no
     heading. design.md's Footer component is amended to match. */
  grid-template-columns: repeat(3, 1fr);
  gap: var(--spacing-32);
}
.footer-col { display: flex; flex-direction: column; gap: 10px; }
.footer-head {
  line-height: 1.36;   /* a display face must not inherit the body's 1.60 */
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: var(--weight-medium);
  color: var(--color-sand);
  margin: 0 0 4px;
}
.footer-col a {
  font-size: var(--text-body-sm);
  letter-spacing: var(--tracking-body-sm);
  color: var(--color-ink-mist);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-signal);
}
.footer-col a:hover { color: var(--color-linen); }
.footer-bottom {
  display: flex;
  align-items: center;
  gap: var(--spacing-20);
  margin-top: var(--spacing-48);
  padding-top: var(--spacing-20);
  border-top: 1px solid var(--color-ink-line);
}
.footer-wordmark { font-size: 16px; }
.footer-copy { font-size: var(--text-caption); letter-spacing: var(--tracking-caption); color: var(--color-ink-mist); }
.footer-build { margin-left: auto; color: var(--color-ink-mist); }
.footer-legal {
  font-size: var(--text-caption);
  letter-spacing: var(--tracking-caption);
  color: var(--color-ink-mist);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-signal);
}
.footer-legal:hover { color: var(--color-linen); }

@media (max-width: 768px) {
  .stat-row { flex-direction: column; gap: var(--spacing-40); }
  /* minmax(0,1fr), not 1fr: a bare 1fr floors at min-content, so the registered
     address pushed its column to 160px against the other's 120px and the two
     stopped being halves. The address wraps now instead of shoving. */
  .footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 480px) {
  /* One column on a phone. Two halves of a 360px screen give the registered
     address about 150px, which wraps it to five lines beside a column of
     three short links -- the address becomes the tallest thing in the footer
     by accident. */
  .footer-grid { grid-template-columns: minmax(0, 1fr); }
  /* Each bottom-row item on its own unbroken line: compressed legal links
     read as a rendering bug exactly where credibility is being claimed. */
  .footer-bottom { flex-direction: column; align-items: flex-start; gap: 10px; }
  .footer-bottom > * { white-space: nowrap; }
  .footer-build { margin-left: 0; }
}

/* ---- The intro transition ----
   Two named animations plus a CSS transition on the veil's mask radius.
   No new keyframe. The hero paints underneath from the first frame; this
   only covers it. Removed from the DOM the moment it ends or aborts. */
.intro {
  position: fixed;
  inset: 0;
  z-index: 60;
  pointer-events: none;
}
.intro-veil { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.intro-veil .veil-fill { fill: var(--color-sand); }

/* The Ink front. The hole grows, revealing the real hero beneath;
   the rim is the ring that sweeps to the edges. */
#intro-hole-circle, .rim-circle {
  r: 0;
  transition: r var(--intro-front, 900ms) var(--ease-exit);
}
.intro-rim {
  opacity: 1;
  transition: r var(--intro-front, 900ms) var(--ease-exit),
              transform var(--intro-front, 900ms) var(--ease-exit),
              opacity var(--intro-rim-fade, 420ms) linear;
}
.intro-rim.spent { opacity: 0; }
.intro-rim { stroke: var(--color-ember); stroke-width: 1; fill: none; }

/* Below 480 a centre circle covers the width long before the height, which
   shows a navy pill on cream bands. The front becomes a HORIZONTAL band,
   full width from the first frame, its two edges sweeping out through the
   top and bottom of a tall viewport. Full width from the start means no
   side margin can ever exist, so it cannot read as a slot or a pillarbox.
   Same causality, same two colours, still a transition, not a keyframe.
   The ring stays a ring above 480. */
#intro-hole-band, .rim-band {
  display: none;
  transform: scaleY(0);
  /* Off centre on purpose: two edges leaving in perfect mirror read as a
     letterbox opening. Offset, they read as a front. */
  transform-origin: 50% 44%;
  transition: transform var(--intro-front, 900ms) var(--ease-exit),
              opacity var(--intro-rim-fade, 420ms) linear;
}
.rim-band { stroke-width: 1; }
@media (max-width: 480px) {
  #intro-hole-circle, .rim-circle { display: none; }
  #intro-hole-band, .rim-band { display: block; }
}

.intro-dot {
  position: absolute;
  left: 50%; top: 50%;
  width: 40px; height: 40px;
  margin: -20px 0 0 -20px;
  border-radius: var(--radius-dot);
  background: var(--color-ember);
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-signal);
}
.intro-dot.landed { opacity: 1; }
/* The dot retires with its ring: neither outlives the call landing. */
.intro-dot.retiring { opacity: 0; }
.intro-dot.retiring::after { opacity: 0; }
.intro-dot.landed::after {
  content: "";
  position: absolute; inset: 0;
  border: 1px solid var(--color-ember);
  border-radius: var(--radius-dot);
  animation: call-ring-ping var(--dur-ping) var(--ease-emit) 1 both;
}

/* Hero content waits behind the veil; the canvas and the bars do not. */
/* The veil never delays the hero. Its eyebrow, headline and subhead paint
   from the first frame and the front reveals the real thing as it passes.
   Only the elements that carry Ember wait, so the budget holds at two types
   while the veil is up: the intro signal, and the waveform. */
.intro-active .nav,
.intro-active .hero-cta,
.intro-active .call-card { opacity: 0; }
.intro-reveal .nav,
.intro-reveal .hero-cta,
.intro-reveal .call-card { opacity: 1; transition: opacity var(--dur-base) var(--ease-signal); }

@media (prefers-reduced-motion: reduce) {
  .intro { display: none; }
}

/* Footer company facts. Human prose in Inter; the tax registry number is
   machine metadata and takes the mono voice, per the record-write precedent. */
.footer-fact {
  font-size: var(--text-body-sm);
  letter-spacing: var(--tracking-body-sm);
  color: var(--color-ink-mist);
}
a.footer-fact-id { text-decoration: none; }
a.footer-fact-id:hover .mono { color: var(--color-linen); }
.footer-fact-id .mono {
  color: var(--color-ink-mist);
  margin-left: var(--spacing-8);
  white-space: nowrap;
}

/* ================= The step rail =================
   The rail is pinned and the stops scroll past it. The active stop is a true
   state, the reader's own position, so it is allowed to change; it is a
   TRANSITION, not a loop, and costs no ambient period.
   The active mark is Linen against Ink Mist. Ember is not used here even
   where the budget would permit it: a reader crossing this section already
   passes the fixed nav CTA and a live console status, and a fourth accent
   on screen erodes the accent. Three is the ceiling, not the target. */

/* design.md centres content on dark bands. A step rail is structured by
   nature and cannot centre, so the band's PROSE entry centres and the
   apparatus below it stays left aligned. */
.rail-entry { text-align: center; display: flex; flex-direction: column; align-items: center; }
.band-dark h2.rail-title { max-width: 26ch; }   /* .band-dark h2 outranks a bare class: this was dead for four runs */
.rail-lede { margin-bottom: var(--spacing-64); max-width: 62ch; }

.rail-layout {
  display: grid;
  grid-template-columns: 160px minmax(0, 1fr);
  column-gap: var(--spacing-64);
  align-items: start;
}

.rail {
  position: sticky;
  top: 152px;                 /* clears the 80px nav with room to breathe */
  display: flex;
  gap: var(--spacing-20);
}

/* The track reports two things: where the reader is, and how far through
   the sequence they have come. The fill is the second of those. */
.rail-track {
  position: relative;
  width: 2px;
  flex: none;
  background: var(--color-ink-line);
}
.rail-fill {
  position: absolute;
  left: 0; top: 0;
  width: 2px;
  height: 0;
  background: var(--color-linen);
  transition: height var(--dur-slow) var(--ease-signal);
}
.rail-dot {
  position: absolute;
  left: 50%;
  top: 0;
  width: 8px; height: 8px;
  margin-left: -4px;
  margin-top: -3px;
  border-radius: var(--radius-sm);
  background: var(--color-linen);
  transition: top var(--dur-slow) var(--ease-signal);
}

.rail-stops { list-style: none; margin: 0; padding: 0; }
.rail-stop {
  display: flex;
  align-items: center;
  height: 64px;               /* tap target, and the rail's step unit */
  padding: 0;
  background: none;
  border: 0;
  cursor: pointer;            /* it does something, so it says so */
  color: var(--color-ink-mist);
  transition: color var(--dur-fast) var(--ease-signal);
}
.rail-stop .label {
  font-family: var(--font-body);
  font-size: var(--text-body-sm);
  line-height: var(--leading-body-sm);
  letter-spacing: var(--tracking-body-sm);
  font-weight: var(--weight-medium);
}
.rail-stop:hover { color: var(--color-sand); }
.rail-stop:focus-visible {
  outline: 2px solid var(--color-ember);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
.rail-stop.is-active {
  color: var(--color-linen);
}
/* 600 is permitted on button labels by the Inter spec, and these are buttons,
   so the active stop carries colour AND weight rather than colour alone. */
.rail-stop.is-active .label { font-weight: var(--weight-semi); }

/* ---- Steps ---- */
.rail-steps { display: flex; flex-direction: column; gap: 120px; }
/* Text left, console right. The console is beside the words it belongs to,
   not beneath them, so the reader sees the claim and its evidence at once. */
.rail-step {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  column-gap: var(--spacing-48);
  align-items: start;
}
.rail-step .console { grid-column: 2; grid-row: 1 / span 3; align-self: center; }
.step-eyebrow, .rail-step h3, .step-body { grid-column: 1; }
.step-eyebrow { color: var(--color-ink-mist); margin: 0 0 12px; }
.rail-step h3 {
  font-size: var(--text-heading-sm);
  line-height: var(--leading-heading-sm);
  letter-spacing: var(--tracking-heading-sm);
  font-weight: var(--weight-light);
  color: var(--color-linen);
  max-width: 20ch;
  margin: 0;
}
.step-body {
  font-size: var(--text-body);
  line-height: var(--leading-body);
  color: var(--color-ink-mist);
  max-width: 46ch;
  margin: 20px 0 0;
}

/* ================= The console =================
   Two nested surfaces, which is what makes it read as an application rather
   than a panel: an outer frame at Ink Elevated and an inner body at Ink.
   The separation is a surface step plus a 1px hairline. No shadow. */
.console {
  background: var(--color-ink-elevated);
  border: 1px solid var(--color-ink-line);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.console-head {
  display: flex;
  align-items: center;
  gap: var(--spacing-8);
  height: 36px;
  padding: 0 var(--spacing-16);
  border-bottom: 1px solid var(--color-ink-line);
}
.console-title { color: var(--color-sand); }
.console-head .status-pill { margin-left: auto; }
.console-timer { margin-left: auto; color: var(--color-sand); }
/* The console is a raised object on the page, and its interior wells are
   recessed INTO it. The body previously took the page colour, which made the
   middle of the console read as a hole cut in the page rather than as the
   inside of a window: chrome raised, content at page level. Inverted. */
.console-body {
  background: var(--color-ink-elevated);
  padding: var(--spacing-20);
  min-height: 268px;                  /* all four stops stand the same height */
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.console-foot {
  margin: 0;
  padding: 12px var(--spacing-16);
  border-top: 1px solid var(--color-ink-line);
  font-size: var(--text-caption);
  /* The caption step's OWN line-height. It set the size and the tracking from
     the caption row of the type scale and then let line-height inherit the
     body's 1.60, so this rendered 13px at 1.60 -- above the floor, so never a
     violation, but not the step it claims to be. Ruling AA makes the type
     scale the authority per step; a step is its four values together, not the
     three that happened to be written down. */
  line-height: var(--leading-caption);
  letter-spacing: var(--tracking-caption);
  color: var(--color-sand);
}

/* ---- Stop 1: the systems the agent is bound to ---- */
.link-map {
  position: relative;
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr) 208px;
  align-items: center;
  min-height: 132px;
}
/* A diagram node, per the Imagery rule: a 4px radius rectangle, never a
   circle. The circle is reserved for status dots, avatars and the mark. */
.link-node {
  display: grid;
  place-items: center;
  width: 56px; height: 36px;
  border-radius: var(--radius-sm);
  background: var(--color-sand-wash);
  border: 1px solid var(--color-ink-line);
  font-size: 16px;   /* the wordmark component supplies family and tone; 13 is the footer-header size */
}
.link-edges { width: 100%; height: 132px; overflow: visible; }
.link-base { fill: none; stroke: var(--color-ink-line); stroke-width: 1; }
.link-draw {
  fill: none;
  stroke: var(--color-ember);
  stroke-width: 1;
  stroke-dasharray: 24 1000;
  --edge-length: 1024;
}
.link-draw { opacity: 0; }
.console.is-live .link-draw {
  animation: integration-edge-draw var(--dur-draw) var(--ease-signal) 1 both;
  animation-delay: calc(var(--edge-i) * var(--stagger));
  /* The dash shows the direction of write while it travels. When the path is
     drawn the connection exists and the signal is over, so it leaves rather
     than sitting on the page as a permanent accent. */
  opacity: 1;
  transition: opacity var(--dur-base) var(--ease-exit);
}
.console.is-drawn .link-draw { opacity: 0; }
.link-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.link-list li {
  display: grid;
  grid-template-columns: minmax(0,1fr) auto;
  align-items: center;
  gap: 2px var(--spacing-8);
  padding: 8px 12px;
  background: var(--color-ink);
  border: 1px solid var(--color-ink-line);
  border-radius: var(--radius-sm);
}
.link-list .sys { color: var(--color-linen); }
.link-list .holds { grid-column: 1 / -1; font-size: var(--text-caption); letter-spacing: var(--tracking-caption); color: var(--color-ink-mist); }  /* on Ink: 4.79:1 */
.link-list .cat { color: var(--color-sand); }

/* ---- Stop 2: the taught process, at rest ---- */
.console-body.rules { display: grid; gap: 12px; }
.rule-row {
  padding: 12px 14px;
  background: var(--color-ink);
  border: 1px solid var(--color-ink-line);
  border-radius: var(--radius-sm);
}
.console.is-live .rule-row {
  animation: agent-line-reveal var(--dur-slow) var(--ease-signal) both;
  animation-delay: calc(var(--line-index) * var(--stagger));
}
.rule-head { display: flex; align-items: baseline; gap: var(--spacing-8); }
.rule-name {
  font-size: var(--text-body-sm);
  letter-spacing: var(--tracking-body-sm);
  font-weight: var(--weight-medium);
  color: var(--color-linen);
}
.rule-tag {
  margin-left: auto;
  color: var(--color-ink-mist);
  border: 1px solid var(--color-ink-line);
  border-radius: var(--radius-sm);
  padding: 2px 6px;
}


/* A status pill sitting ON an Ink Elevated console takes an Ink fill rather
   than the Ink Elevated one the component specifies for a dark band. Two
   reasons, and they agree: a pill the same colour as the surface under it has
   no separation at all, and Ink Mist on Ink Elevated measures 3.89:1 where
   the same colour on Ink measures 4.79:1. The surface step buys the contrast. */
.console .status-pill { background: var(--color-ink); }
.console .console-fields dd.is-empty { color: var(--color-sand); }   /* the placeholder is machine metadata, and Sand clears AA on Ink Elevated */
.rule-do {
  margin: 6px 0 0;
  font-size: var(--text-body-sm);
  line-height: var(--leading-body-sm);
  letter-spacing: var(--tracking-body-sm);
  color: var(--color-ink-mist);
}

/* ---- Stop 3: the call, and the fields filling as it runs ---- */
.console-body.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 200px;
  gap: var(--spacing-20);
}
.console-transcript { display: flex; flex-direction: column; gap: 12px; }
.console-fields {
  margin: 0;
  padding-left: var(--spacing-20);
  border-left: 1px solid var(--color-ink-line);
  display: grid;
  gap: 14px;
  align-content: start;
}
.console-fields div { display: grid; gap: 2px; }
.console-fields dt { color: var(--color-sand); }
.console-fields dd {
  margin: 0;
  /* Reserved. The empty state is an 11px mono placeholder in a 15.95px box and
     the filled state is 14px Inter in a 22.4px box, so the console grew 6.45px
     at phone width the moment KONU filled -- and everything below it moved. */
  min-height: var(--spacing-24);
  font-size: var(--text-body-sm);
  letter-spacing: var(--tracking-body-sm);
  color: var(--color-linen);
}
/* The empty state is a machine placeholder in every slot, so the row does not
   look ragged before it fills. Once filled, the face difference is meaningful:
   PLAKA and RANDEVU are machine values, KONU is the agent's own words. */
.console-fields dd:not(.mono).is-empty {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  line-height: var(--leading-micro);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-micro);
  color: var(--color-sand);
}
.console-fields dd.mono { font-size: var(--text-micro); letter-spacing: var(--tracking-micro); }

/* ---- Stop 4: the commit ---- */
/* Dark-register write row. The light-register component put Ink text on Ink
   Elevated at 1.23:1 and Ink Slate at 1.86:1; both were effectively invisible. */
.console .write-row {
  background: var(--color-ink);
  border-color: var(--color-ink-line);
}
.console .write-field {
  color: var(--color-linen);
  letter-spacing: var(--tracking-body-sm);
}
.console .write-system { color: var(--color-sand); }
.console .write-ref {
  color: var(--color-sand);
  background: var(--color-ink-elevated);
  border-color: var(--color-ink-line);
}
/* The record the write lands in, so the join key from the call reappears at
   the moment of the commit. */
.write-record {
  display: grid;
  /* auto-fit, not repeat(3): three equal columns of minmax(0,1fr) collapse to
     72px at 360 and then let their own contents hang out of them, which is
     invisible until a word is longer than 72px. Turkish fitted by luck --
     RANDEVU and YARIN are short. English does not: APPOINTMENT is 82px and
     the word "appointment" is 84px, so both the label and the value spilled
     their cell. The row now drops to two columns when three cannot hold their
     content, and above 332px of interior it is still the same three columns
     it always was. A cell is sized by what is in it, in either language. */
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
  gap: var(--spacing-8) var(--spacing-16);
  padding: 12px 14px;
  margin-bottom: 12px;
  background: var(--color-ink);
  border: 1px solid var(--color-ink-line);
  border-radius: var(--radius-sm);
}
.write-record div { display: grid; gap: 2px; }
.write-record dt { color: var(--color-sand); }
.write-record dd {
  margin: 0;
  color: var(--color-linen);
  font-size: var(--text-body-sm);
  letter-spacing: var(--tracking-body-sm);
}
.write-record dd.mono { font-size: var(--text-micro); letter-spacing: var(--tracking-micro); }

/* ---- Responsive ---- */
@media (max-width: 1024px) {
  .rail-layout { grid-template-columns: 1fr; row-gap: var(--spacing-40); }
  .rail {
    position: static;
    gap: var(--spacing-16);
  }
  .rail-track { display: none; }
  .rail-stops { display: flex; gap: var(--spacing-24); flex-wrap: wrap; }
  .rail-steps { gap: 80px; }
  .rail-step { grid-template-columns: 1fr; row-gap: var(--spacing-32); }
  .rail-step .console { grid-column: 1; grid-row: auto; }
  .step-body { max-width: 56ch; }
}
@media (max-width: 768px) {
  .console-body.split { grid-template-columns: 1fr; }
  .console-fields {
    padding-left: 0;
    padding-top: var(--spacing-16);
    border-left: 0;
    border-top: 1px solid var(--color-ink-line);
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .link-map { grid-template-columns: 56px minmax(0, 1fr); }
  .link-edges { display: none; }
  .link-list { grid-column: 1 / -1; margin-top: var(--spacing-16); }
}
@media (max-width: 480px) {
  /* The foot's terminal line grows from one wrapped line to two as the job
     completes, and the console grew 6px under it. Reserved, so the commit
     lands without the page moving.

     THE RESERVE WAS 64px AND THE TWO-LINE HEIGHT IS 66.49px, so it was 2.49px
     short and the console still moved on every commit -- in Turkish, before
     English existed. Measured constants drift the moment anything around them
     changes; this one had drifted from its own copy. Expressed in `lh` it is
     two lines of whatever line-height this element actually computes, plus its
     own padding and border, and it cannot be wrong in either language or at
     any type-scale change. English merely made it visible: it puts a third
     console foot on the two-line branch. */
  .console-foot { min-height: calc(2lh + 24px + 1px); box-sizing: border-box; }
  .rail-steps { gap: 64px; }
  .console-body { padding: var(--spacing-16); }
  .console-fields { grid-template-columns: 1fr; }
}

/* ---- The questions ----
   Left column asks, right column answers. Hairline separators, no cards:
   a question is not an object, it is a row. */
/* Centred on a dark band, per design.md. The two-column sticky arrangement
   was a light-register composition sitting on Ink. */
.faq-layout { display: block; }
.faq-intro {
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-bottom: var(--spacing-48);
}
.faq-intro h2 { margin-bottom: var(--spacing-16); }
.faq-list-wrap { max-width: 760px; margin: 0 auto; }
.faq-mail {
  display: inline-block;
  margin-top: var(--spacing-20);
  font-size: var(--text-body-sm);
  letter-spacing: var(--tracking-body-sm);
  color: var(--color-linen);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--color-ink-slate);
  transition: text-decoration-color var(--dur-fast) var(--ease-signal);
}
.faq-mail:hover { text-decoration-color: var(--color-linen); }

.faq-list { border-top: 1px solid var(--color-ink-line); }
.faq-item { transition: background-color var(--dur-base) var(--ease-signal); }
.faq-item { border-bottom: 1px solid var(--color-ink-line); }

.faq-q {
  display: flex;
  align-items: center;
  gap: var(--spacing-20);
  width: 100%;
  padding: var(--spacing-20) 0;
  background: none;
  border: 0;
  text-align: left;
  cursor: pointer;
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  color: var(--color-linen);
  transition: color var(--dur-fast) var(--ease-signal);
}
.faq-q:hover { color: var(--color-sand); }
.faq-q:focus-visible {
  outline: 2px solid var(--color-ember);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
.faq-q span:first-child { flex: 1; }

/* The sign is a plus that becomes a minus. One element, one rotation:
   the state is open or closed and the mark says which. */
.faq-sign {
  position: relative;
  flex: none;
  width: 12px; height: 12px;
}
.faq-sign::before,
.faq-sign::after {
  content: "";
  position: absolute;
  left: 0; top: 50%;
  width: 12px; height: 1px;
  background: var(--color-ink-mist);
  transition: transform var(--dur-base) var(--ease-signal),
              background-color var(--dur-fast) var(--ease-signal);
}
.faq-sign::after { transform: rotate(90deg); }
.faq-q[aria-expanded="true"] .faq-sign::after { transform: rotate(0deg); }
.faq-q[aria-expanded="true"] .faq-sign::before,
.faq-q[aria-expanded="true"] .faq-sign::after { background: var(--color-linen); }
/* The open row holds its state with a surface step and a weight step, so the
   state survives after the opening transition has finished. */
.faq-item:has(.faq-q[aria-expanded="true"]) {
  background: var(--color-sand-wash);
  border-radius: var(--radius-sm);
}
.faq-q[aria-expanded="true"] { font-weight: var(--weight-medium); }
.faq-item:has(.faq-q[aria-expanded="true"]) .faq-q,
.faq-item:has(.faq-q[aria-expanded="true"]) .faq-a > p { padding-left: var(--spacing-16); padding-right: var(--spacing-16); }

.faq-a {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-slow) var(--ease-signal);
}
.faq-a > p {
  overflow: hidden;
  margin: 0;
  font-size: var(--text-body-sm);
  line-height: var(--leading-body);
  letter-spacing: var(--tracking-body-sm);
  color: var(--color-sand);   /* the OPEN row's fill is Sand Wash, where Ink Mist measures 4.05:1 */
  max-width: 62ch;
}
.faq-q[aria-expanded="true"] + .faq-a { grid-template-rows: 1fr; }
.faq-q[aria-expanded="true"] + .faq-a > p { padding-bottom: var(--spacing-20); }

@media (max-width: 1024px) {
  .faq-intro { margin-bottom: var(--spacing-32); }
}

/* ---- The live queue ----
   A row of inbound call subjects where the movement is a real arrival: an
   entry lands, the row advances, the oldest leaves. Each entry encodes a call
   that arrived, so the motion is a state rather than a loop running for
   effect. Fixed slots and transform-only movement, so nothing on the page
   shifts position as entries arrive. */
.queue {
  position: relative;
  height: 40px;
  margin: calc(var(--spacing-32) * -1) 0 var(--spacing-64);
}
.queue-label {
  position: absolute;
  left: 0; top: 50%;
  transform: translateY(-50%);
  color: var(--color-ink-mist);
}
/* The mask lives on the TRACK, not the row: it was severing the label. */
.queue-track {
  position: absolute;
  inset: 0 0 0 96px;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, #000 0, #000 82%, transparent 100%);
          mask-image: linear-gradient(90deg, #000 0, #000 82%, transparent 100%);
}
.queue-item {
  position: absolute;
  top: 4px;              /* centred by geometry, never by transform */
  left: 0;
  display: flex;
  align-items: center;
  gap: var(--spacing-8);
  height: 32px;
  padding: 0 14px;
  white-space: nowrap;
  background: var(--color-ink-elevated);
  border: 1px solid var(--color-ink-line);
  border-radius: var(--radius-sm);
  font-size: var(--text-body-sm);
  letter-spacing: var(--tracking-body-sm);
  color: var(--color-linen);
  transition: left var(--dur-slow) var(--ease-signal),
              opacity var(--dur-base) var(--ease-exit);
}
.queue-item .mono { color: var(--color-sand); }   /* ruling T: Ink Mist is 3.89:1 on Ink Elevated */
.queue-item.is-arriving { animation: agent-line-reveal var(--dur-slow) var(--ease-signal) both; }
.queue-item.is-leaving { opacity: 0; }

@media (max-width: 768px) {
  .queue { margin-bottom: var(--spacing-48); }
  .queue-label { display: none; }
}

/* ---- Booking band ----
   The scheduler embed was built here and withdrawn: see the note in the
   markup. What remains is a clean band that sends the reader out. */
.booking-linkout { margin-top: var(--spacing-32); }


/* ---- Ruling T applied ----
   Ink Mist is certified against Ink and nowhere else. Every run below sits on
   Ink Elevated, where it measures 3.89:1, so it takes Sand at 8.47:1.
   The HAZIR deployment label is deliberately NOT in this list: ruling S gives
   it Ink Mist precisely to distinguish it from Sand, which is SAHADA. Those
   two rulings collide on this one element and the collision is recorded
   rather than resolved unilaterally. */
.call-card .call-card-timer,
.call-card .transcript-line.from-customer span:last-child,
.console .console-fields dd:not(.mono) { color: var(--color-sand); }

/* The ember dot is born at the band's own origin, never on bare Sand.
   Declared last on purpose: an identical-specificity rule earlier in the
   file loses the cascade, which is exactly how the first attempt failed. */
@media (max-width: 480px) {
  .intro-dot { top: 44%; }
}
