/* ============================================================================
   PRECISION MINIMAL — page composition.
   Band styles only. Every value comes from precision.css tokens.
   ========================================================================= */

/* ---------------------------------------------------------------------------
   PRODUCT PANEL COMPATIBILITY
   ----------------------------------------------------------------------------
   `product.css` is shared with the earlier editions and is written against
   the original token names. This page ships a different token vocabulary, so
   the names it needs are aliased here rather than forking the stylesheet —
   one dark-interface subsystem, three page designs.

   The panel neutrals live here too: they belong to the panel subsystem, not
   to a page's palette, and the precision page does not load the original
   tokens file.
   ------------------------------------------------------------------------ */
.p-body-root {
  /* LIGHT PANELS. The same interface components, themed by overriding the
     panel tokens — no forked stylesheet. Every ink is verified on all three
     panel grounds, not just the lightest: the amber first chosen for the
     divergence state passed on white and failed on the sunken ground at
     4.29, and the green/amber pair had to be re-picked to stay separable
     without relying on hue. Ratios from tools/contrast.mjs. */
  --panel: #ffffff;
  --panel-raised: #f5f5f4;
  --panel-sunken: #ededec;
  --panel-line: rgba(0, 0, 0, 0.1);
  --panel-ink: #0a0a0a;        /* 19.80 · 18.15 · 16.90 */
  --panel-ink-muted: #52525b;  /*  7.73 ·  7.09 ·  6.60 */
  --panel-ink-faint: #66666f;  /*  5.68 ·  5.21 ·  4.85 */
  --panel-accent: #3b3e9e;     /*  8.87 ·  8.13          */
  --panel-accent-alt: #1d4e7a; /*  8.67 ·  7.94          */
  --panel-ok: #0f7b3d;         /*  5.36 ·  4.91 ·  4.57  */
  --panel-flag: #743e00;       /*  8.64 ·  7.37 ·  6.65  */

  /* Spacing names product.css expects, mapped to the 4px scale. */
  --space-3xs: var(--s-1);
  --space-2xs: var(--s-2);
  --space-xs: var(--s-3);
  --space-sm: var(--s-4);
  --space-md: var(--s-6);
  --space-lg: var(--s-8);

  /* Type names product.css expects. */
  --text-h4: 1rem;
  --text-sm: var(--text-small);
  --text-xs: 0.8125rem;
  --text-micro: var(--text-label);
  --leading-normal: 1.5;
  --leading-snug: 1.25;
  --tracking-mono: var(--tracking-label);

  /* Motion names product.css expects. */
  --duration-base: var(--base);
}

/* The shared components carry screen-reader-only spans under the original
   `.visually-hidden` name, which lives in base.css — a file this page does
   not load. Without this rule those spans render visibly, which showed up as
   "B/L — checked" and "— pending" printed next to the labels they describe. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------------------------------------------------------------------------
   NAV — transparent at rest, hairline and blur on scroll
   ------------------------------------------------------------------------ */
.p-nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background-color var(--base) var(--ease-out),
    border-color var(--base) var(--ease-out),
    backdrop-filter var(--base) var(--ease-out);
}

.p-nav.is-stuck {
  background: color-mix(in srgb, var(--canvas) 82%, transparent);
  backdrop-filter: blur(14px);
  border-bottom-color: var(--hairline);
}

.p-nav__inner {
  height: 64px;
  display: flex;
  align-items: center;
  gap: var(--s-6);
}

.p-nav__mark {
  font-weight: var(--weight-semibold);
  letter-spacing: -0.02em;
  color: var(--ink);
  text-decoration: none;
  flex: none;
}

/* The logo is sized by HEIGHT, with width auto, so a mark of any aspect ratio
   sits on the same optical baseline as the set type it replaces. The width and
   height attributes in the markup are there to reserve the box before the file
   arrives — without them the nav reflows on load, which on a fixed header
   shifts the whole page under the reader. */
.p-nav__mark--logo {
  display: flex;
  align-items: center;
}

/* The supplied mark is pure black on transparent, drawn for paper. On a
   #0a0c12 page it is very nearly invisible.

   `invert(1)` rather than a recoloured copy of the file, because inverting
   pure black gives pure white exactly, leaves the alpha channel alone, and
   keeps ONE source file that stays the artwork as delivered. It is only valid
   while the mark is monochrome — a coloured logo would come out as its
   negative, so this is a documented assumption, not a general technique.

   The lockup is 6.2:1, so 28px of height is 174px of width. max-width is 200
   rather than 180: at 180 the wordmark was being squeezed, and a logo that
   does not fit its own box is worse than one a few pixels wider. */
.p-nav__logo {
  display: block;
  height: 28px;
  width: auto;
  max-width: 200px;
  filter: invert(1);
}

@media (max-width: 34em) {
  .p-nav__logo { height: 22px; }
}

.p-nav__links {
  display: none;
  margin-inline: auto;
  gap: var(--s-8);
}

@media (min-width: 64em) {
  .p-nav__links { display: flex; }
}

.p-nav__links a {
  font-family: var(--font-mono);
  font-size: var(--text-label);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--ink-tertiary);
  text-decoration: none;
  transition: color var(--fast) var(--ease-out);
}

.p-nav__links a:hover,
.p-nav__links a.is-current { color: var(--ink); }

.p-nav .p-btn { margin-left: auto; }

@media (min-width: 64em) { .p-nav .p-btn { margin-left: 0; } }

/* The nav CTA label is content-driven and can be long. Withdrawn on narrow
   screens, where the identical CTA sits in the hero directly beneath. */
.p-nav .p-btn { display: none; }

@media (min-width: 34em) { .p-nav .p-btn { display: inline-flex; } }

/* ---------------------------------------------------------------------------
   BAND 01 · HERO
   Centred copy; the product frame runs wide beneath it.
   ------------------------------------------------------------------------ */
.p-hero__copy {
  text-align: center;
  padding-top: var(--s-24);
  padding-bottom: var(--s-16);
  display: flex;
  flex-direction: column;
  align-items: center;
}

@media (min-width: 64em) {
  .p-hero__copy { padding-top: var(--s-32); }
}

.p-hero__copy .p-eyebrow { justify-content: center; }

.p-hero__copy .p-display { max-width: 16ch; }

.p-hero__lede {
  margin-top: var(--heading-gap);
  max-width: 54ch;
}

.p-hero__ctas {
  margin-top: var(--cta-gap);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: var(--s-4) var(--s-8);
}

.p-hero__stage { padding-bottom: var(--s-24); }

/* --- Gradient tile ------------------------------------------------------
   A soft wash built from the supplied brand colours, with a faint dot field
   so a large flat gradient does not read as empty. The pastels are large,
   light, decorative fills carrying no text — the one thing they can do on a
   light canvas, where none of them reaches 3:1. */
.p-tile {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-lg);
  padding: clamp(16px, 0.5rem + 2.4vw, 48px);
  background: linear-gradient(
    145deg,
    var(--tile-a, #ececff) 0%,
    var(--tile-b, var(--fill-3)) 100%
  );
}

.p-tile::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: radial-gradient(rgba(255, 255, 255, 0.6) 1px, transparent 1px);
  background-size: 14px 14px;
  opacity: 0.5;
  pointer-events: none;
}

.p-tile > * { position: relative; }

.p-tile--hero { --tile-a: #ececff; --tile-b: var(--fill-3); }

/* --- The brand cycler ----------------------------------------------------
   This page does not load components.css — that stylesheet is written
   against the original token vocabulary and would drag in a second set of
   section, container and button rules. The cycler's structure is therefore
   defined here, against this page's tokens.

   Elevation is border, never shadow. */
.brand-cycler__frame {
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--surface);
  outline: 1px solid var(--hairline-strong);
}

.brand-cycler__chrome {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-6);
  /* Every value --identity can take is a supplied brand pastel, and --ink
     clears 7.8:1 on all four. */
  background: var(--identity, var(--surface-sunken));
  transition: background-color var(--base) var(--ease-out);
}

.brand-cycler__logo {
  width: 14px;
  height: 14px;
  border-radius: 4px;
  background: rgba(10, 10, 10, 0.5);
  flex: none;
}

.brand-cycler__mark {
  font-weight: var(--weight-semibold);
  font-size: var(--text-small);
  letter-spacing: -0.01em;
  color: var(--ink);
}

.brand-cycler__chrome-tail { margin-left: auto; display: flex; gap: 4px; }

.brand-cycler__chrome-tail i {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: rgba(10, 10, 10, 0.28);
}

.is-swapping .brand-cycler__mark {
  animation: p-mark-in var(--base) var(--ease-out);
}

@keyframes p-mark-in {
  from { opacity: 0; transform: translate3d(0, 5px, 0); }
  to { opacity: 1; transform: none; }
}

/* Controls need JavaScript, so they are withdrawn without it. */
.brand-cycler__controls {
  display: none;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2) var(--s-4);
  margin-top: var(--s-4);
}

.js .brand-cycler__controls { display: flex; }

.brand-cycler__controls-label { color: var(--ink-secondary); }

.brand-cycler__switches { display: flex; flex-wrap: wrap; gap: var(--s-2); }

.brand-cycler__switch {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: 6px 12px;
  border: 1px solid rgba(10, 10, 10, 0.12);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.76);
  font-family: var(--font-mono);
  font-size: var(--text-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--ink-secondary);
  transition: border-color var(--fast) var(--ease-out),
    background-color var(--fast) var(--ease-out),
    color var(--fast) var(--ease-out);
}

.brand-cycler__switch:hover { border-color: var(--ink); color: var(--ink); }

.brand-cycler__switch[aria-pressed='true'] {
  background: var(--surface);
  border-color: var(--ink);
  color: var(--ink);
}

.brand-cycler__dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--dot);
  border: 1px solid rgba(10, 10, 10, 0.14);
  flex: none;
}

.brand-cycler__caption {
  margin-top: var(--s-4);
  font-size: var(--text-small);
  color: var(--ink-secondary);
}

.brand-cycler__caption-lead {
  color: var(--ink);
  margin-right: var(--s-2);
}

.p-tile .panel { border-radius: 0; }

/* ---------------------------------------------------------------------------
   FACT STRIP — full-bleed band, contained content
   ------------------------------------------------------------------------ */
.p-factstrip {
  border-top: 1px solid var(--hairline-strong);
  border-bottom: 1px solid var(--hairline-strong);
  background: var(--surface-sunken);
  padding-block: var(--s-12);
}

.p-factstrip__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-8) var(--s-6);
}

@media (min-width: 48em) {
  .p-factstrip__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.p-factstrip__label { color: var(--ink-tertiary); display: block; margin-bottom: var(--s-2); }

.p-factstrip__value {
  font-size: var(--text-body);
  font-weight: var(--weight-medium);
  color: var(--ink);
  line-height: 1.35;
}

/* The ownership disclosure. Small, but never hidden. */
.p-factstrip__note {
  margin-top: var(--s-8);
  padding-top: var(--s-6);
  border-top: 1px solid var(--hairline);
  font-size: var(--text-small);
  line-height: 1.55;
  color: var(--ink-secondary);
  max-width: var(--measure);
}

/* ---------------------------------------------------------------------------
   BAND 02 · THESIS
   ------------------------------------------------------------------------ */
.p-thesis__lead { max-width: 62ch; }

.p-thesis__headline { max-width: 24ch; }

.p-thesis__lede { margin-top: var(--heading-gap); }

/* Asymmetric split — a narrow label column against a wide reading column.
   Even splits read as a template; uneven splits read as a decision. */
.p-problem {
  margin-top: var(--s-24);
  display: grid;
  gap: var(--s-6);
}

@media (min-width: 64em) {
  .p-problem {
    grid-template-columns: minmax(0, 4fr) minmax(0, 8fr);
    gap: var(--s-16);
  }
}

.p-problem__label { color: var(--accent); }

.p-problem__body { display: flex; flex-direction: column; gap: var(--s-8); }

/* The bold lead runs straight on into secondary ink in one paragraph —
   denser to skim than a heading stacked over a block, and much quieter. */
.p-problem__para {
  font-size: var(--text-lede);
  line-height: var(--leading-lede);
  letter-spacing: var(--tracking-lede);
  color: var(--ink-secondary);
  max-width: var(--measure);
}

.p-problem__para strong {
  color: var(--ink);
  font-weight: var(--weight-medium);
}

/* The one statement on the page that is centred and set large. It earns it
   by being the section's conclusion, not a heading. */
.p-statement {
  margin-top: var(--s-32);
  margin-inline: auto;
  max-width: 30ch;
  text-align: center;
  font-size: var(--text-h2);
  font-weight: var(--weight-medium);
  line-height: var(--leading-h2);
  letter-spacing: var(--tracking-h2);
  color: var(--ink-tertiary);
  text-wrap: balance;
}

.p-statement strong {
  color: var(--ink);
  font-weight: var(--weight-medium);
}

/* ---------------------------------------------------------------------------
   BAND 03 · CAPABILITIES
   ------------------------------------------------------------------------ */
.p-caps__head { text-align: center; margin-bottom: var(--s-16); }

.p-caps__label { color: var(--accent); margin-bottom: var(--eyebrow-gap); }

.p-caps__headline { max-width: 20ch; margin-inline: auto; }

.p-caps__lede { margin-top: var(--heading-gap); margin-inline: auto; }

.p-caps__stage { margin-bottom: var(--s-24); }

/* --- The showcase --------------------------------------------------------
   A light panel over a world map. The map is texture: low opacity, dot
   filled, aria-hidden, and carrying no route or port — a map that looks
   like a coverage map is a claim, and this page has none to make. */
.p-showcase {
  position: relative;
  margin: 0;
  border-radius: var(--radius-lg);
  border: 1px solid var(--hairline);
  background: var(--surface);
  overflow: hidden;
}

.p-showcase__map {
  position: absolute;
  inset: 0;
  color: var(--ink);
  opacity: 0.07;
  pointer-events: none;
}

.p-showcase__map svg { width: 100%; height: 100%; }

.p-showcase__panel {
  position: relative;
  padding: clamp(20px, 0.75rem + 2.4vw, 48px);
  display: flex;
  flex-direction: column;
  gap: var(--s-8);
}

.p-showcase__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  padding-bottom: var(--s-4);
  border-bottom: 1px solid var(--hairline);
}

.p-showcase__label { color: var(--accent); }
.p-showcase__ref { color: var(--ink-tertiary); }

.p-showcase__grid { display: grid; gap: var(--s-8); }

@media (min-width: 56em) {
  .p-showcase__grid {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    gap: var(--s-16);
    align-items: start;
  }
}

/* --- Timeline ------------------------------------------------------------ */
.p-showcase__timeline { display: grid; }

.p-showcase__milestone {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: var(--s-4);
  padding-block: 7px;
  position: relative;
}

.p-showcase__dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--hairline-strong);
  position: relative;
  z-index: 1;
}

.p-showcase__milestone:not(:last-child) .p-showcase__dot::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 100%;
  width: 1.5px;
  height: 14px;
  transform: translateX(-50%);
  background: var(--hairline-strong);
}

.p-showcase__milestone[data-state='done'] .p-showcase__dot,
.p-showcase__milestone[data-state='done'] .p-showcase__dot::after {
  background: var(--accent);
}

.p-showcase__milestone[data-state='current'] .p-showcase__dot {
  background: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-tint);
}

.p-showcase__milestone-name {
  font-size: var(--text-small);
  color: var(--ink-tertiary);
}

.p-showcase__milestone[data-state='done'] .p-showcase__milestone-name { color: var(--ink-secondary); }

.p-showcase__milestone[data-state='current'] .p-showcase__milestone-name {
  color: var(--ink);
  font-weight: var(--weight-medium);
}

/* --- Stats --------------------------------------------------------------- */
.p-showcase__stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s-2);
}

.p-showcase__stat {
  background: color-mix(in srgb, var(--surface-sunken) 85%, transparent);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-sm);
  padding: var(--s-3) var(--s-4);
}

.p-showcase__stat dt { color: var(--ink-tertiary); }

.p-showcase__stat dd {
  margin-top: 2px;
  font-size: var(--text-h3);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-h3);
  line-height: 1.15;
  color: var(--ink);
}

/* --- Progress track ------------------------------------------------------ */
.p-showcase__track {
  padding-top: var(--s-6);
  border-top: 1px solid var(--hairline);
  display: grid;
  gap: var(--s-3);
}

.p-showcase__lane {
  display: flex;
  justify-content: space-between;
  color: var(--ink-tertiary);
}

.p-showcase__bar {
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--surface-sunken);
  border: 1px solid var(--hairline);
  overflow: hidden;
}

.p-showcase__fill {
  display: block;
  height: 100%;
  width: var(--p, 0%);
  border-radius: inherit;
  background: var(--accent);
}

.p-showcase__note {
  position: relative;
  display: block;
  padding: var(--s-3) clamp(20px, 0.75rem + 2.4vw, 48px);
  border-top: 1px solid var(--hairline);
  color: var(--ink-tertiary);
  background: var(--surface-sunken);
}

/* --- Animation -----------------------------------------------------------
   The finished state above is the base. The primed state is applied by
   script only when it can be animated away, so JS-off and reduced-motion
   both land on the complete graphic. */
.js .p-showcase.is-primed .p-showcase__fill { width: 0; }

.js .p-showcase.is-playing .p-showcase__fill {
  width: var(--p, 0%);
  transition: width 1100ms var(--ease-out);
}

.js .p-showcase.is-primed .p-showcase__milestone { opacity: 0.25; }

.js .p-showcase.is-playing .p-showcase__milestone {
  opacity: 1;
  transition: opacity var(--base) var(--ease-out);
  transition-delay: calc(var(--i) * 110ms);
}

@media (prefers-reduced-motion: reduce) {
  .js .p-showcase .p-showcase__fill { width: var(--p, 0%); transition: none; }
  .js .p-showcase .p-showcase__milestone { opacity: 1; transition: none; }
}

/* --- Four functions ------------------------------------------------------ */
.p-functions {
  display: grid;
  gap: 1px;
  background: var(--hairline);
}

@media (min-width: 40em) {
  .p-functions { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 72em) {
  .p-functions { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* The card fill is the PAGE ground, not a surface. The capabilities band used
   to be sunken, which put the six cards on #0e111a while the page ran #0a0c12
   — close enough to look like a mistake rather than a band, and visible as a
   tone change at the section's edge.

   The fill still has to be painted rather than left transparent: the grid
   above carries `background: var(--hairline)` and shows through its own 1px
   gaps to draw the separators, so a transparent card would let that 10% white
   wash flood the whole tile instead of just the lines between them. */
.p-functions__item {
  background: var(--canvas);
  padding: var(--s-8) var(--s-6) var(--s-8) 0;
}

@media (min-width: 40em) {
  .p-functions__item { padding-inline: var(--s-6); }
  .p-functions__item:first-child { padding-inline: 0 var(--s-6); }
}

@media (min-width: 72em) {
  .p-functions__item { padding-inline: var(--s-6); }
  .p-functions__item:first-child { padding-inline: 0 var(--s-6); }
  .p-functions__item:last-child { padding-inline: var(--s-6) 0; }
}

.p-functions__title {
  font-size: var(--text-h3);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-h3);
  line-height: var(--leading-h3);
  margin-bottom: var(--s-3);
}

.p-functions__line {
  color: var(--ink-secondary);
  font-size: var(--text-body);
  line-height: var(--leading-body);
}

.p-caps__note { margin-top: var(--s-8); max-width: var(--measure); }

/* ---------------------------------------------------------------------------
   BAND 04 · THE AI LAYER
   Entirely greyscale. The accent budget is spent elsewhere, and a band with
   no colour in it is what lets the copy carry the section.
   ------------------------------------------------------------------------ */
.p-ai__head { text-align: center; margin-bottom: var(--s-24); }

.p-ai__label { color: var(--ink-tertiary); margin-bottom: var(--eyebrow-gap); }

.p-ai__headline { max-width: 22ch; margin-inline: auto; }

.p-ai__lede { margin-top: var(--heading-gap); margin-inline: auto; }

.p-ai__grid { display: grid; gap: var(--s-12) var(--s-6); }

@media (min-width: 44em) { .p-ai__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 72em) { .p-ai__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.p-ai__card { display: flex; flex-direction: column; gap: var(--s-6); }

/* Border and background, never a shadow. */
.p-ai__stage {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md);
  padding: var(--s-4);
  color: var(--ink);
}

.p-ai__copy {
  font-size: var(--text-body);
  line-height: var(--leading-body);
  color: var(--ink-secondary);
}

.p-ai__copy strong { color: var(--ink); font-weight: var(--weight-medium); }

/* --- The mocks ----------------------------------------------------------
   Everything is currentColor at varying opacity, so a single ink change
   restyles all four and nothing can drift into colour. */
.p-mock__svg { width: 100%; height: auto; display: block; }

.p-mock__outline {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  opacity: 0.28;
}

.p-mock__bar { fill: currentColor; opacity: 0.2; }
.p-mock__bar--label { opacity: 0.12; }
.p-mock__solid { fill: currentColor; opacity: 0.75; }
.p-mock__track { stroke: currentColor; stroke-width: 1.5; opacity: 0.16; }
.p-mock__node-ring { fill: var(--surface); stroke: currentColor; stroke-width: 1.5; opacity: 0.32; }
.p-mock__plate { fill: currentColor; opacity: 0.16; }
/* The base plate is the accumulated record — the darkest of the four. */
.p-mock__plate:first-child { opacity: 0.42; }
.p-mock__ring { fill: none; stroke: currentColor; stroke-width: 1.5; opacity: 0; }

.p-mock__progress {
  stroke: currentColor;
  stroke-width: 3;
  stroke-linecap: round;
  opacity: 0.7;
}

/* --- Finished states are the base; the animation is applied on top ------- */
.js .p-ai__card.is-primed .p-mock__row,
.js .p-ai__card.is-primed .p-mock__node,
.js .p-ai__card.is-primed .p-mock__plate { opacity: 0; }

.js .p-ai__card.is-primed .p-mock__flag { opacity: 0; transform: scale(0.7); }

.js .p-ai__card.is-primed .p-mock__progress {
  stroke-dasharray: 192;
  stroke-dashoffset: 192;
}

.js .p-ai__card.is-playing .p-mock__row {
  opacity: 1;
  transition: opacity var(--base) var(--ease-out);
  transition-delay: calc(var(--i) * 90ms);
}

.js .p-ai__card.is-playing .p-mock__flag {
  opacity: 1;
  transform: none;
  transition: opacity var(--base) var(--ease-out), transform var(--base) var(--ease-out);
  transition-delay: 520ms;
}

.js .p-ai__card.is-playing .p-mock__node {
  opacity: 1;
  transition: opacity var(--base) var(--ease-out);
  transition-delay: calc(var(--i) * 200ms);
}

.js .p-ai__card.is-playing .p-mock__progress {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 900ms var(--ease-out);
}

.js .p-ai__card.is-playing .p-mock__plate {
  opacity: 0.16;
  transition: opacity var(--slow) var(--ease-out), transform var(--slow) var(--ease-out);
  transition-delay: calc(var(--i) * 110ms);
}

.js .p-ai__card.is-playing /* The base plate is the accumulated record — the darkest of the four. */
.p-mock__plate:first-child { opacity: 0.42; }

.js .p-ai__card.is-primed .p-mock__plate { transform: translateY(14px); }
.js .p-ai__card.is-playing .p-mock__plate { transform: none; }

/* The confirm control breathes once, so "waiting on a person" reads. */
.js .p-ai__card.is-playing .p-mock__ring { animation: mock-ring 1800ms var(--ease-out) 400ms 2; }

@keyframes mock-ring {
  0% { opacity: 0.5; transform: scale(1); }
  70% { opacity: 0; transform: scale(1.06); }
  100% { opacity: 0; transform: scale(1.06); }
}

.p-mock__confirm { transform-box: fill-box; transform-origin: center; }
.p-mock__ring { transform-box: fill-box; transform-origin: center; }

@media (prefers-reduced-motion: reduce) {
  .js .p-ai__card .p-mock__row,
  .js .p-ai__card .p-mock__node,
  .js .p-ai__card .p-mock__flag { opacity: 1; transform: none; }
  .js .p-ai__card .p-mock__plate { opacity: 0.16; transform: none; }
  .js .p-ai__card /* The base plate is the accumulated record — the darkest of the four. */
.p-mock__plate:first-child { opacity: 0.42; }
  .js .p-ai__card .p-mock__progress { stroke-dashoffset: 0; }
  .js .p-ai__card .p-mock__ring { animation: none; }
}

/* ---------------------------------------------------------------------------
   BAND 05 · TECHNICAL
   A spec sheet. Horizontal rules only — never a vertical one.
   ------------------------------------------------------------------------ */
.p-tech__head { margin-bottom: var(--s-16); }

.p-tech__label { color: var(--ink-tertiary); margin-bottom: var(--eyebrow-gap); }

.p-tech__headline { max-width: 20ch; }

.p-tech__rows { display: grid; }

.p-tech__row {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-2) var(--s-6);
  padding-block: var(--s-8);
  border-top: 1px solid var(--hairline-strong);
  align-items: baseline;
}

.p-tech__row:last-child { border-bottom: 1px solid var(--hairline-strong); }

@media (min-width: 64em) {
  /* Asymmetric: the index sits in the gutter, title against body at 4/8. */
  .p-tech__row {
    grid-template-columns: 3rem minmax(0, 4fr) minmax(0, 8fr);
    gap: var(--s-8);
    padding-block: var(--s-12);
  }
}

.p-tech__num { color: var(--accent); }

.p-tech__title { color: var(--ink); }

.p-tech__body {
  color: var(--ink-secondary);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  max-width: var(--measure);
}

@media (max-width: 63.99em) {
  .p-tech__title { grid-column: 2; }
  .p-tech__body { grid-column: 2; }
}

/* ---------------------------------------------------------------------------
   BAND 06 · CTA — one statement, one button
   ------------------------------------------------------------------------ */
.p-cta { text-align: center; }

/* "Your brand. Your lanes." then "Our engine", which takes two settings.

   BALANCING IS OFF FOR THIS ONE HEADING. `.p-h2` sets `text-wrap: balance`,
   and balance does not fill lines greedily — it picks the split it considers
   most even, which here is "Your brand." over "Your lanes. Our engine" at
   11 characters against 22. That was the same result at every measure from
   16ch to 23ch: the width was not the thing choosing the break, so no amount
   of tuning it could have worked, and it looked exactly like a measure that
   would not take.

   With balance off the measure decides again, and anything from 16ch to 23ch
   gives the requested break. 20ch sits in the middle of that band rather than
   at either edge.

   Where the break MAY fall is still the content file's business: it makes the
   spaces inside each phrase non-breaking, so no measure can split one. On a
   narrow phone this simply becomes three lines, which is a wrap and not a
   defect. */
.p-cta__statement {
  max-width: 20ch;
  margin-inline: auto;
  text-wrap: wrap;
}

.p-cta__lede { margin-top: var(--heading-gap); margin-inline: auto; }

.p-cta__action { margin-top: var(--cta-gap); }

/* An unfilled slot, marked. No contact route was supplied, so the button
   resolves to # and says so rather than pretending to work. */
.p-slot {
  display: inline-flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: baseline;
  gap: var(--s-2);
  margin-top: var(--s-12);
  padding: var(--s-2) var(--s-4);
  border: 1px dashed var(--hairline-strong);
  border-radius: var(--radius-sm);
  color: var(--ink-tertiary);
  text-transform: none;
  letter-spacing: 0;
}

.p-slot__label {
  font-family: var(--font-mono);
  font-size: var(--text-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--ink-secondary);
}

/* ---------------------------------------------------------------------------
   BAND 07 · FOOTER
   ---------------------------------------------------------------------------
   The mark and who owns it, then the three questions a footer on this page has
   to answer: what else is in the stack, how to reach anyone, and who Rhombuz
   is. A rule, then the legal row and the tagline.

   THE PREVIOUS FOOTER'S RULES ARE GONE, NOT KEPT. It had a two-column top, a
   groups grid, a pending state and a dashed tag, none of which any template
   still emitted. Dead CSS for element classes slips past the orphaned-class
   check, which only walks modifiers, so it survives exactly as long as nobody
   looks.

   EVERY COLUMN IS A <nav> WITH ITS OWN LABEL. Three unlabelled link lists in a
   row are three identical "navigation" landmarks to anyone moving by landmark;
   the headings give them names and cost nothing visually, since the heading IS
   the column title the design already draws.
   ------------------------------------------------------------------------ */
.p-footer {
  border-top: 1px solid var(--hairline-strong);
  padding-top: var(--s-16);
  padding-bottom: var(--s-8);
  background: var(--surface-sunken);
}

/* One grid holds the mark, the byline and the three lists. Narrow, it is a
   single column and everything stacks in source order. */
.p-footer__grid {
  display: grid;
  gap: var(--s-12);
  padding-bottom: var(--s-16);
}

@media (min-width: 34em) {
  .p-footer__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-8); }
  .p-footer__mark,
  .p-footer__byline { grid-column: 1 / -1; }
}

/* WIDE: THE MARK ABOVE, THE LISTS TO ITS RIGHT, AND THE BYLINE ON THEIR LINE.

   Two rows. The mark takes the first on its own; the byline and all three
   lists share the second, which is what puts the column titles at the same
   height as "by Rhombuz Applied" — they are in the same row, so there is
   no offset to maintain. `align-items: baseline` then settles the last of it:
   the byline is set in the sans at one size and the titles in the mono at
   another, so aligning their boxes would still leave the text sitting on two
   different lines. Aligning their FIRST BASELINES puts the words on one.

   The leading track holds nothing, which is what moves the lists to the right
   while leaving the space under the wordmark open. A track rather than a
   margin so the mark's share of the row and the lists' share stay one
   declaration, with no second value to keep in step. */
@media (min-width: 56em) {
  .p-footer__grid {
    grid-template-columns: minmax(0, 1.2fr) repeat(3, minmax(0, 1fr));
    align-items: baseline;
    row-gap: var(--s-4);
  }

  .p-footer__mark { grid-column: 1; grid-row: 1; }
  .p-footer__byline { grid-column: 1; grid-row: 2; }
  .p-footer__col { grid-row: 2; }
  .p-footer__col:first-of-type { grid-column: 2; }
}

.p-footer__mark {
  display: inline-block;
  font-weight: var(--weight-semibold);
  letter-spacing: -0.02em;
  color: var(--ink);
  text-decoration: none;
  font-size: var(--text-h3);
}

/* When the mark is a logo the type styling has nothing to style, and the
   inline-block link would otherwise carry the descender space of a font size
   it is not using. */
.p-footer__mark--logo {
  font-size: 0;
  line-height: 0;
}

/* The supplied logo is monochrome and drawn for a light ground, so it is
   inverted here exactly as the nav inverts it. Same asset, same treatment. */
.p-footer__logo {
  display: block;
  height: 30px;
  width: auto;
  filter: invert(1);
}

.p-footer__byline {
  margin: var(--s-3) 0 0;
  font-size: var(--text-small);
}

.p-footer__byline { color: var(--accent); }

.p-footer__col-title {
  font-family: var(--font-mono);
  font-size: var(--text-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  font-weight: var(--weight-regular);
  color: var(--accent);
  margin: 0 0 var(--s-6);
}

.p-footer__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--s-4);
}

.p-footer__list a,
.p-footer__list span {
  color: var(--ink-secondary);
  text-decoration: none;
  font-size: var(--text-small);
  transition: color var(--fast) var(--ease-out);
}

.p-footer__list a:hover { color: var(--ink); }

.p-footer__legal {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-6);
  justify-content: space-between;
  align-items: baseline;
  padding-top: var(--s-6);
  border-top: 1px solid var(--hairline);
  color: var(--ink-tertiary);
  font-size: var(--text-small);
}

.p-footer__copy,
.p-footer__tagline { margin: 0; }


/* The bridge above the key message: it names what kind of problem the
   previous band described, so the aspiration lands as a consequence rather
   than as a slogan. Set quieter than the headline it introduces. */
.p-caps__bridge {
  font-size: var(--text-lede);
  line-height: var(--leading-lede);
  color: var(--ink-tertiary);
  max-width: 44ch;
  margin: 0 auto var(--s-6);
}
