/* ============================================================================
   ASTRAMIR — VISUALS
   Diagram components for the site. Consumes the semantic token layer only;
   never a primitive except inside SVG gradient stops, where the band has to
   be restated as stops (a CSS gradient cannot paint an SVG stroke).

   One grammar across every diagram:
     · hairlines are structure, in --color-rule-strong / --color-axis
     · the band is a 2px beam: the path a conclusion travels
     · the APERTURE (the only circle in the system) is where a person decides
     · CONVERGE draws inputs into a finding, once, on reveal
     · SWEEP runs once, around the learning loop only, and obeys the
       page's motion control through the token layer's safety net

   Every diagram is aria-hidden and paired with a real list (.viz-list) that
   screen readers always get and narrow screens see instead of the drawing.
   ========================================================================= */

.viz { position: relative; margin: 0; display: grid; gap: var(--space-6); }
.viz svg { display: block; inline-size: 100%; block-size: auto; overflow: visible; }
.viz figcaption { color: var(--color-ink-3); }

/* SVG type follows the site's type roles */
.viz svg text { font-family: var(--font-sans); fill: var(--color-ink); font-variation-settings: "wdth" 100, "wght" 500; }
.viz svg .t-head { font-size: 17px; font-variation-settings: "wdth" 100, "wght" 600; }
.viz svg .t-sub  { font-size: 15px; fill: var(--color-ink-3); font-variation-settings: "wdth" 100, "wght" 400; }
.viz svg .t-num  { font-size: 14px; fill: var(--color-accent); font-variation-settings: "wdth" 100, "wght" 600; letter-spacing: 0.04em; }
.viz svg .t-big  { font-size: 30px; fill: var(--color-ink-3); font-variation-settings: "wdth" 115, "wght" 300; letter-spacing: -0.01em; }
.viz svg .t-mono { font-family: var(--font-mono); font-size: 13px; fill: var(--color-ink-3); letter-spacing: 0.12em; font-variation-settings: "wdth" 87, "wght" 500; }
.viz svg .t-gate { font-size: 17px; fill: var(--color-accent); font-variation-settings: "wdth" 100, "wght" 600; }

.viz svg .axis   { fill: none; stroke: var(--color-rule-strong); stroke-width: 1.25; }
.viz svg .tick   { stroke: var(--color-ink-3); stroke-width: 1.5; }
.viz svg .beam   { fill: none; stroke-width: 2; }
.viz svg .iris   { fill: none; stroke: var(--color-accent-quiet); stroke-width: 1; }
.viz svg .aperture { fill: var(--color-ground-raised); stroke-width: 2; }
.viz svg .stop-1 { stop-color: var(--p-violet); }
.viz svg .stop-2 { stop-color: var(--p-indigo); }
.viz svg .stop-3 { stop-color: var(--p-azure); }
.viz svg .stop-4 { stop-color: var(--p-cyan); }

/* ---- The accessible list: always read, shown only on narrow screens ---- */
.viz-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-4); }
.viz-list li { display: grid; grid-template-columns: 2.25rem 1fr; gap: var(--space-2) var(--space-3); padding-block-start: var(--space-3); border-block-start: var(--hairline) solid var(--color-rule); }
.viz-list li > .label { color: var(--color-accent); padding-block-start: 0.2em; }
.viz-list li > span:last-child { color: var(--color-ink-2); }
.viz-list li > span:last-child b { color: var(--color-ink); font-weight: 600; display: block; }
.viz-list li.gate { border-block-start: var(--beam) solid transparent; border-image: var(--band) 1; }

/* The list is for screen readers at every width.

   Each diagram has a wide drawing and a tall drawing, and picks one by the
   space the diagram itself has (a container query), not by device width.
   The wide drawing needs about 960px to keep its smallest label near 11px;
   below that, the tall drawing is used. The tall drawing is 320 units wide,
   so it never shrinks on a 320px phone, and it stops growing at 380px so
   labels stay close to body-text size on tablets. */
.viz-list { position: absolute; inline-size: 1px; block-size: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.viz { container-type: inline-size; container-name: viz; }
.viz svg.viz-draw-mobile { display: none; max-inline-size: 380px; }
@container viz (max-width: 959px) {
  .viz svg.viz-draw { display: none; }
  .viz svg.viz-draw-mobile { display: block; }
}
/* Browsers without container queries fall back to the screen width. */
@supports not (container-type: inline-size) {
  @media (max-width: 1007px) {
    .viz svg.viz-draw { display: none; }
    .viz svg.viz-draw-mobile { display: block; }
  }
}

/* ---- CONVERGE: input paths draw into the finding, once ------------------ */
.js .viz.reveal .conv path { stroke-dasharray: 1; stroke-dashoffset: 1; }
.js .viz.reveal.in .conv path { animation: converge-draw var(--dur-slow) var(--ease-converge) forwards; }
.js .viz.reveal.in .conv path:nth-child(2) { animation-delay: 60ms; }
.js .viz.reveal.in .conv path:nth-child(3) { animation-delay: 120ms; }
.js .viz.reveal.in .conv path:nth-child(4) { animation-delay: 180ms; }
@keyframes converge-draw { to { stroke-dashoffset: 0; } }
:root.js[data-motion="reduced"] .viz.reveal .conv path { stroke-dashoffset: 0; animation: none; }
@media (prefers-reduced-motion: reduce) {
  :root.js:not([data-motion="full"]) .viz.reveal .conv path { stroke-dashoffset: 0; animation: none; }
}

/* ---- SWEEP: one measuring pass around the learning loop ----------------- */
.viz .sweep { fill: none; stroke-width: 3; stroke-linecap: round; stroke-dasharray: 70 930; stroke-dashoffset: 1000; }
.js .viz.reveal.in .sweep { animation: loop-sweep calc(var(--dur-sweep) * 3) var(--ease-sweep) infinite; }
@keyframes loop-sweep { to { stroke-dashoffset: 0; } }
/* Stopped, not sped up: when motion is reduced the pulse is simply absent. */
:root[data-motion="reduced"] .viz .sweep { display: none; }
@media (prefers-reduced-motion: reduce) {
  :root:not([data-motion="full"]) .viz .sweep { display: none; }
}

/* ---- Layers: the Operational Intelligence Layer ------------------------ */
.layers { margin: 0 0 var(--space-12); display: grid; gap: var(--space-4); }
.tier { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr)); gap: var(--space-3); }
.tier li {
  border: var(--hairline) solid var(--color-rule-strong); border-radius: var(--radius-edge);
  padding: var(--space-3) var(--space-4); background: var(--color-ground-raised);
  font-size: var(--text-small); color: var(--color-ink); font-variation-settings: "wdth" 100, "wght" 500;
}
.tier li small { display: block; color: var(--color-ink-3); font-size: var(--text-micro); font-variation-settings: "wdth" 100, "wght" 400; }
.tier-core {
  position: relative; display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--space-2) var(--space-6);
  padding: var(--space-6) var(--space-6);
  border-block: var(--beam) solid transparent; border-image: var(--band) 1;
  background: color-mix(in oklab, var(--color-accent) 5%, var(--color-ground-raised));
}
.tier-core .capability { font-size: var(--text-title); }
.tier-core .prose { color: var(--color-ink-2); }
.layers .tier-legend { display: flex; justify-content: space-between; }

/* ---- Levels: governance up the value chain ----------------------------- */
.levels { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-6); align-items: end; border-block-end: var(--hairline) solid var(--color-axis); }
.level {
  display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-6) var(--space-6) var(--space-6);
  border-block-start: var(--beam) solid transparent; border-image: var(--band) 1;
  background: var(--color-ground-raised);
}
.level:nth-child(1) { min-block-size: 13rem; }
.level:nth-child(2) { min-block-size: 17rem; }
.level:nth-child(3) { min-block-size: 21rem; }
.level .label { margin-block-start: auto; padding-block-start: var(--space-4); color: var(--color-accent); }
.level .prose { color: var(--color-ink-2); }
@media (max-width: 760px) {
  .levels { grid-template-columns: 1fr; border-block-end: 0; }
  .level:nth-child(n) { min-block-size: 0; }
}

/* ---- Record: a sample audit entry ------------------------------------- */
.record { gap: var(--space-4); box-shadow: var(--shadow-plate); }
.record-head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-4); padding-block-end: var(--space-3); border-block-end: var(--beam) solid transparent; border-image: var(--band) 1; }
.record dl { margin: 0; display: grid; grid-template-columns: minmax(7.5rem, auto) 1fr; gap: var(--space-3) var(--space-6); }
.record dt { margin: 0; }
.record dd { margin: 0; color: var(--color-ink); }
@media (max-width: 520px) { .record dl { grid-template-columns: 1fr; gap: var(--space-1); } .record dd { margin-block-end: var(--space-3); } }

/* ---- Forced colors: gradients vanish, so beams become solid rules ------ */
@media (forced-colors: active) {
  .viz svg .beam, .viz svg .aperture, .viz svg .axis, .viz svg .tick, .viz svg .iris { stroke: CanvasText; }
  .viz svg text { fill: CanvasText; }
  .viz .sweep { display: none; }
  .tier li, .level, .record { border-color: CanvasText; }
}

/* ---- Facts row alignment (site.css component) --------------------------
   Equal-height facts were stretching their rows, so descriptions of
   different lengths sat at different heights. Pin content to the top. */
.facts .fact { align-content: start; }

/* ============================================================================
   SCREEN — a product screenshot, framed as an instrument.
   The frame runs in OPERATE (dark) wherever it sits, because the product is
   an operating surface: the mode contract doing its job inside a Publish page.
   The caption stays in the page's own mode.

   Callout markers are small squares, never circles: the circle belongs to
   the aperture alone. Numbers are used only when they match the steps of the
   diagram above the screenshot; otherwise the screenshot takes a caption only.
   Positions are set per image with --x / --y (percent of the image).
   ========================================================================= */
.screen { margin: 0; display: grid; gap: var(--space-4); }
.screen-frame {
  position: relative;
  background: var(--color-ground);
  border: var(--hairline) solid var(--color-rule-strong);
  border-radius: var(--radius-plate);
  padding: var(--space-3);
  box-shadow: var(--shadow-lift);
}
.screen-frame::before {                       /* the band as the top edge */
  content: ""; position: absolute; inset-inline: var(--space-3); inset-block-start: 0;
  block-size: var(--beam); background: var(--band);
}
.screen-frame img { display: block; inline-size: 100%; block-size: auto; border-radius: var(--radius-edge); }

.callout {
  /* The band's resolved point: a disc sampling the bright end of the band
     (azure to cyan) with the numeral in ink, so it reads at 30px on any
     screen. The scrim ring separates it from busy pixels beneath. */
  position: absolute; left: var(--x); top: var(--y); transform: translate(-50%, -50%);
  inline-size: 1.9rem; block-size: 1.9rem;
  display: inline-grid; place-items: center;
  border-radius: 50%;
  background: var(--band); background-size: 300% 100%; background-position: 100% 0;
  color: var(--p-void-900);
  font-family: var(--font-mono); font-size: var(--text-micro); font-variation-settings: "wdth" 87, "wght" 600;
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--p-void-900) 60%, transparent);
}
.screen figcaption { display: grid; gap: var(--space-3); }
.callout-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr)); gap: var(--space-3) var(--space-6); }
.callout-list li { display: grid; grid-template-columns: 2rem 1fr; gap: var(--space-2); font-size: var(--text-small); color: var(--color-ink-2); }
.callout-list li .label { color: var(--color-accent); padding-block-start: 0.15em; }
/* A legend keyed by words rather than step numbers needs a wider first column. */
.callout-list.legend li { grid-template-columns: 5rem 1fr; }

/* On narrow screens the markers crowd the image; the numbered list carries
   the same information directly below it. */
@media (max-width: 620px) { .callout { display: none; } }

.screen-pair { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); gap: var(--space-8); }

@media (forced-colors: active) {
  .screen-frame { border-color: CanvasText; }
  .screen-frame::before { background: CanvasText; }
  .callout { border: 1px solid CanvasText; }
}

/* ---- Illustration: a designed image (not a product screen) ------------
   Sits in the page's own mode. No frame, no band: an illustration is
   context, not evidence, so it does not borrow the instrument treatment. */
.illustration { margin: 0 0 var(--space-12); display: grid; gap: var(--space-3); }
.illustration img { display: block; inline-size: 100%; block-size: auto; border-radius: var(--radius-plate); }
.illustration figcaption { color: var(--color-ink-3); }

/* ---- Portrait: leadership headshots ----------------------------------- */
.portrait { display: block; inline-size: 100%; block-size: auto; aspect-ratio: 1; object-fit: cover; border-radius: var(--radius-edge); margin-block-end: var(--space-4); background: var(--color-surface); }

/* ============================================================================
   ROUND 3 COMPONENTS
   All size themselves to the space they have (auto-fit grids or container
   queries), so the same markup serves a 320px phone and a wide desktop.
   ========================================================================= */

/* ---- Use cases: icon + one line --------------------------------------- */
.uses-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr)); gap: var(--space-6) var(--space-8); }
.use { display: grid; grid-template-columns: 2rem 1fr; gap: var(--space-3); align-items: start; padding-block-start: var(--space-4); border-block-start: var(--hairline) solid var(--color-rule); }
.use-icon { inline-size: 1.5rem; block-size: 1.5rem; color: var(--color-accent); margin-block-start: 0.1em; }
.use .heading { font-size: var(--text-body); margin: 0 0 var(--space-1); }
.use .prose { color: var(--color-ink-2); margin: 0; }

.sectors { margin-block-start: var(--space-12); display: grid; gap: var(--space-3); }
.sector-list { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-2); }
.sector-list li { border: var(--hairline) solid var(--color-rule-strong); border-radius: var(--radius-edge); padding: var(--space-2) var(--space-3); font-size: var(--text-small); color: var(--color-ink-2); background: var(--color-ground-raised); }

/* ---- Layers: 4-up on wide, 2-up on narrow ------------------------------ */
.layers { container-type: inline-size; }
.layers .tier { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@container (min-width: 700px) { .layers .tier { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* ---- Split with a record: stacks when narrow --------------------------- */
.record-split { display: grid; gap: var(--space-12); grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr)); align-items: start; }

/* ---- How agencies start: rail when narrow, row when wide --------------- */
.steps-wrap { container-type: inline-size; }
.steps { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-8); position: relative; }
.step { display: grid; grid-template-columns: 2.5rem 1fr; gap: var(--space-4); position: relative; }
.step .heading { margin: 0 0 var(--space-2); }
.step .prose { color: var(--color-ink-2); margin: 0; }
.step-mark {
  display: inline-grid; place-items: center; inline-size: 2.25rem; block-size: 2.25rem;
  border-radius: var(--radius-edge); background: var(--color-accent); color: var(--color-accent-ink);
  font-family: var(--font-mono); font-size: var(--text-micro); font-variation-settings: "wdth" 87, "wght" 600;
  position: relative; z-index: 1;
}
/* narrow: a vertical hairline joins the markers */
.step:not(:last-child)::before { content: ""; position: absolute; inset-inline-start: 1.125rem; inset-block: 2.25rem calc(-1 * var(--space-8)); border-inline-start: var(--hairline) solid var(--color-rule-strong); }
@container (min-width: 720px) {
  .steps { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-8); }
  .step { grid-template-columns: 1fr; gap: var(--space-4); }
  /* wide: the band runs across behind the markers */
  .step:not(:last-child)::before { inset-block: 1.125rem auto; inset-inline: 2.25rem calc(-1 * var(--space-8)); border-inline-start: 0; border-block-start: var(--beam) solid transparent; border-image: var(--band) 1; }
}

/* ---- Pillars paired with their enforcement ---------------------------- */
.pillars { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); gap: var(--space-6); }
.pillar { display: flex; flex-direction: column; gap: var(--space-3); }
.pillar .prose { margin: 0; }
.pillar .enforced { margin-block-start: auto; padding-block-start: var(--space-4); border-block-start: var(--beam) solid transparent; border-image: var(--band) 1; display: grid; gap: var(--space-2); }
.pillar .enforced .label { color: var(--color-accent); margin: 0; }
.pillar .enforced .prose { color: var(--color-ink-2); }

@media (forced-colors: active) {
  .step-mark { border: 1px solid CanvasText; }
  .sector-list li, .use { border-color: CanvasText; }
}

/* ---- Narrowest phones: keep display headlines inside the screen -------- */
@media (max-width: 360px) { .hero .d1 { font-size: 12.5vw; } }

/* ---- Name: three parts that read as the name, left to right ----------- */
.name-parts { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr)); gap: var(--space-8); }
.name-part { display: grid; gap: var(--space-3); align-content: start; padding-block-start: var(--space-4); border-block-start: var(--beam) solid transparent; border-image: var(--band) 1; }
.name-part .part { font-size: var(--text-display-3); line-height: 1; color: var(--color-accent); font-variation-settings: "wdth" 118, "wght" 300; letter-spacing: 0.02em; }
.name-part .heading { margin: 0; }
.name-part .prose { margin: 0; color: var(--color-ink-2); }

/* ---- Formula: sized from the space it has ------------------------------
   Measured: the whole equation is about 24 times its font size wide; the
   bracketed half about 17 times. So the font size is set from the width of
   the formula's container, never from the device:
     - wide:   one row, as large as the display size allows
     - narrow: break after "=", sized so the bracket and Trust fit on row two
   The site stylesheet otherwise wraps wherever space runs out, which split
   the bracket on phones and tablets. */
.stack:has(> .formula) { container-type: inline-size; }
.formula { font-size: min(var(--text-display-3), 4cqi); }
@container (max-width: 759px) {
  .formula { font-size: min(var(--text-display-3), 5.6cqi); row-gap: 0.7em; }
  .formula > * { order: 4; }
  .formula > .term:first-child { order: 1; }
  .formula > .op:first-of-type { order: 2; }
  .formula::after { content: ""; flex-basis: 100%; block-size: 0; order: 3; }
}

/* ============================================================================
   TRUST HIERARCHY — three layers drawn as a stack.
   Law and policy is the foundation (solid ink), observed signal sits above
   it (raised, hairline), and AI inference sits on top (dashed outline): the
   layer trusted least. Widths step in toward the top on wide screens; on
   narrow ones the layers stack at full width and the shape comes from the
   fills and outlines alone.
   ========================================================================= */
.hierarchy-wrap { container-type: inline-size; }
.hierarchy { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-3); justify-items: center; }
.layer {
  inline-size: 100%;
  display: grid; gap: var(--space-3) var(--space-8);
  padding: var(--space-6) var(--space-8);
  border-radius: var(--radius-plate);
}
.layer .layer-tag { color: var(--color-accent); }
.layer h3 { margin: 0; }
.layer .prose { margin: 0; }
.layer .holds { display: grid; gap: var(--space-2); }
.layer .holds .label { color: var(--color-ink-3); }
.layer-inference { border: 1.5px dashed var(--color-rule-strong); background: transparent; }
.layer-signal { border: var(--hairline) solid var(--color-rule-strong); background: var(--color-ground-raised); }
.layer-law { background: var(--color-ground); border: var(--hairline) solid var(--color-rule); }
.layer-law::before { content: none; }
@container (min-width: 820px) {
  .layer { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); align-items: start; }
  .layer-inference { inline-size: 76%; }
  .layer-signal { inline-size: 88%; }
  .layer-law { inline-size: 100%; }
}
.hierarchy-axis { display: flex; justify-content: space-between; margin-block-start: var(--space-4); }
.hierarchy-close { margin-block-start: var(--space-8); max-inline-size: 60ch; }
@media (forced-colors: active) {
  .layer { border: 1px solid CanvasText; }
  .layer-inference { border-style: dashed; }
}
/* The site's heading style sets its colour from the page's run, so the dark
   foundation layer restates it from its own (operate) tokens. */
.layer[data-mode="operate"] .heading { color: var(--color-ink); }
