/* ===========================================================================
   Lab page, layered on style.css.

   Two tools, each opened the way the home page opens an app: a quiet line
   naming it, a two-tone heading, and one lit plate. The what it does plate
   bleeds off the right edge and carries the scan; the Aion plate bleeds off
   the left and carries the run, so the page alternates the way the home
   page's scenes do. Everything else sits on the ground between hairlines.

   Ported from the old landing.css (wid-*, aion-*). What was dropped on the
   way: the aurora and its drift, backdrop blur, the glow on bars and cells,
   mono uppercase labels and the teal numeral rails. Numbers are ink; teal is
   spent on the one bar, the one node and the one tag that carry a result.
   =========================================================================== */

.page--lab {
  /*
    The finding colour, the same pink the reports and the research figure use
    for "worth checking". Declared here because it is not a site token: it
    appears only where a report is being quoted.
  */
  --warn: #f07f96;
  --warn-rule: rgba(240, 127, 150, 0.38);
  --warn-tint: rgba(240, 127, 150, 0.08);
  --plate-ink: #0b1215;
}

/* ----------------------------------------------------------------- intro */

.lab-intro {
  padding-top: clamp(40px, 6vw, 84px);
}

.lab-intro h1 {
  max-width: 1180px;
  margin: 0;
  font-size: clamp(40px, 4.7vw, 68px);
  line-height: 1;
  letter-spacing: -0.04em;
}

.lab-intro__line {
  display: block;
}

@media (min-width: 1100px) {
  .lab-intro__line {
    white-space: nowrap;
  }
}

/* The page's contents: the two tools, divided by hairlines, not cards. */
.lab-index {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin: clamp(40px, 5vw, 64px) 0 0;
  border-top: 1px solid var(--line);
}

.lab-index li {
  margin: 0;
  padding: 0;
}

.lab-index li::before {
  content: none;
}

.lab-index a {
  display: block;
  height: 100%;
  margin-right: 28px;
  padding: 24px 28px 26px 0;
  border-right: 1px solid var(--line);
  color: var(--ink);
  text-decoration: none;
}

.lab-index li:last-child a {
  margin-right: 0;
  border-right: 0;
}

.lab-index__name {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.012em;
}

/* Points down the page: these are in-page links, not new pages. */
.lab-index__name::after {
  content: "\2193";
  color: var(--ink-3);
  font-weight: 500;
  transition: transform 0.18s var(--ease), color 0.18s var(--ease);
}

.lab-index a:hover .lab-index__name::after {
  color: var(--ink);
  transform: translateY(2px);
}

.lab-index__desc {
  display: block;
  max-width: 460px;
  margin-top: 10px;
  color: var(--ink-2);
  font-size: 15px;
  line-height: 1.5;
  transition: color 0.18s var(--ease);
}

.lab-index a:hover .lab-index__desc {
  color: var(--ink);
}

/* ------------------------------------------------------------- the tools */

.tool {
  padding-top: clamp(96px, 10vw, 140px);
  /* Arriving at /lab#what-it-does lands on the opening line, not on the padding. */
  scroll-margin-top: calc(48px - clamp(96px, 10vw, 140px));
}

/* The second tool opens under a hairline across the column. */
.tool + .tool::before {
  content: "";
  display: block;
  height: 1px;
  margin-bottom: clamp(88px, 9vw, 128px);
  background: var(--line);
}

.tool + .tool {
  padding-top: clamp(104px, 10vw, 140px);
  scroll-margin-top: calc(48px - clamp(104px, 10vw, 140px) - 1px - clamp(88px, 9vw, 128px));
}

/* The tool's name, then what the section is about, in the home page's
   appname idiom: sentence case, body size, no eyebrow. */
.tool__kicker {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 12px;
  margin: 0;
  color: #a7afb3;
  font-size: 15px;
  line-height: 1.4;
}

.tool__kicker b {
  color: var(--ink);
  font-weight: 600;
}

.tool h2 {
  margin: 24px 0 0;
  font-size: clamp(34px, 3.4vw, 48px);
  line-height: 1.02;
  letter-spacing: -0.034em;
}

/* A block heading inside a tool: the same two-tone voice, one size down. */
.wid-check__head h3,
.wid-pricing__head h3,
.aion-feature__body h3 {
  margin: 0;
  font-size: clamp(26px, 2.5vw, 36px);
  font-weight: 560;
  line-height: 1.06;
  letter-spacing: -0.03em;
}

/* Quiet spec rows: ink numbers over sentence-case labels, hairline dividers. */
.spec {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin: clamp(64px, 7vw, 96px) 0 0;
  border-top: 1px solid var(--line);
}

.spec > div {
  min-width: 0;
  padding: 22px 24px 0;
  border-left: 1px solid var(--line);
}

.spec > div:first-child {
  padding-left: 0;
  border-left: 0;
}

.spec b {
  display: block;
  color: var(--ink);
  font-size: clamp(24px, 2.2vw, 30px);
  font-weight: 560;
  line-height: 1.1;
  letter-spacing: -0.024em;
  font-variant-numeric: tabular-nums;
}

.spec span {
  display: block;
  margin-top: 8px;
  color: var(--ink-3);
  font-size: 14.5px;
  line-height: 1.45;
}

/* The lit plate, bled off the page edge on its own side (as on the home page). */
.wid-stage,
.aion-run {
  --bleed: calc(var(--gutter) + max(0px, (100vw - var(--max)) / 2));
}

/* ========================================================== what it does */

.wid-hero {
  display: grid;
  grid-template-columns: minmax(0, 480px) minmax(0, 1fr);
  column-gap: 58px;
  align-items: center;
}

.wid-lede {
  margin: 22px 0 0;
  font-size: 18px;
  line-height: 1.55;
}

.wid-lede strong {
  color: var(--ink);
  font-weight: 600;
}

.wid-actions {
  margin-top: 30px;
}

.wid-cmd {
  margin: 20px 0 0;
  color: var(--ink-3);
  font-size: 14px;
}

.wid-cmd code {
  padding: 0;
  background: none;
  box-shadow: none;
  color: #d5dbde;
  font-size: 13.5px;
}

/* ---- the plate, with the scanner's own graph as its field ---- */

.wid-stage {
  display: flex;
  align-items: center;
  min-height: 580px;
  margin-right: calc(-1 * var(--bleed));
  padding: 64px var(--bleed) 64px clamp(32px, 4.4vw, 64px);
  border-radius: 24px 0 0 24px;
}

.wid-map {
  position: absolute;
  z-index: 1;
  top: 50%;
  right: -24px;
  width: 640px;
  max-width: none;
  /* Centres the drawn part (y 58-675 of the 1000 box) on the plate. */
  transform: translateY(-37%);
  pointer-events: none;
}

.wid-map line {
  stroke: #a9e6d4;
}

.wid-map circle {
  fill: rgba(169, 230, 212, 0.13);
}

.wid-map circle.is-hot {
  fill: rgba(138, 240, 208, 0.34);
}

/*
  The graph draws itself in as the plate arrives - each edge a normalised
  dash, each with its own baked delay. Gated on .js, which the page sets before
  first paint: with scripting off the graph is simply already drawn.
*/
.js .wid-map line {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  transition: stroke-dashoffset 1.1s var(--ease);
}

.js .wid-stage.is-in .wid-map line {
  stroke-dashoffset: 0;
}

.js .wid-map circle {
  opacity: 0;
  transition: opacity 0.8s var(--ease);
}

.js .wid-stage.is-in .wid-map circle {
  opacity: 1;
}

/* ---- the scan, staged ---- */

.wid-scan {
  position: relative;
  z-index: 6;
  width: 100%;
  /* Narrower on a laptop, so the graph's busiest cluster stays in view. */
  max-width: clamp(420px, 34vw, 520px);
  padding: 24px 26px 22px;
  border-radius: 16px;
  background: var(--plate-ink);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.1), 0 50px 100px -30px rgba(0, 0, 0, 0.85),
    0 18px 36px -18px rgba(0, 0, 0, 0.6);
  font-family: var(--mono);
}

.wid-scan__cmd {
  display: flex;
  align-items: baseline;
  margin: 0 0 18px;
  color: #d5dbde;
  font-size: 13.5px;
}

.wid-scan__cmd::before {
  content: "$ ";
  color: var(--ink-3);
  white-space: pre;
}

.wid-scan__cmd i {
  display: inline-block;
  width: 7px;
  height: 14px;
  margin-left: 5px;
  align-self: center;
  background: var(--teal);
  opacity: 0;
}

.is-running .wid-scan__cmd i {
  animation: wid-caret 1.1s steps(1) infinite;
}

@keyframes wid-caret {
  0%, 49% { opacity: 0.85; }
  50%, 100% { opacity: 0; }
}

/* Which pass this is. The two labels trade places with the verdicts below. */
.wid-scan__pass {
  position: relative;
  margin-left: auto;
  font-family: var(--font);
  font-size: 13px;
  font-weight: 560;
  white-space: nowrap;
}

.wid-scan__p1 {
  color: var(--ink-3);
  opacity: 0;
}

.wid-scan__p2 {
  position: absolute;
  right: 0;
  top: 0;
  color: var(--warn);
}

.is-running .wid-scan__p1 { animation: wid-p1 9s var(--ease) infinite; }
.is-running .wid-scan__p2 { animation: wid-p2 9s var(--ease) infinite; }

@keyframes wid-p1 {
  0%, 3% { opacity: 0; }
  7%, 44% { opacity: 1; }
  50%, 100% { opacity: 0; }
}

@keyframes wid-p2 {
  0%, 50% { opacity: 0; }
  56%, 94% { opacity: 1; }
  100% { opacity: 0; }
}

.wid-scan__rows {
  position: relative;
  display: grid;
  gap: 10px;
}

/* The second pass, made visible: a hairline down the rows as they are re-read. */
.wid-scan__beam {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  z-index: 1;
  height: 1px;
  background: var(--teal);
  opacity: 0;
  pointer-events: none;
}

.is-running .wid-scan__beam {
  animation: wid-beam 9s var(--ease) infinite;
}

@keyframes wid-beam {
  0%, 41% { top: 0; opacity: 0; }
  44% { opacity: 0.7; }
  51% { top: calc(100% - 1px); opacity: 0.7; }
  53%, 100% { top: calc(100% - 1px); opacity: 0; }
}

.wid-row {
  position: relative;
  padding: 12px 15px;
  border-radius: 8px;
  background: #121a1e;
  box-shadow: inset 2px 0 0 var(--line-lit), inset 0 0 0 1px var(--line);
}

.wid-row__path {
  display: block;
  color: var(--ink);
  font-size: 13.5px;
  font-weight: 600;
}

.wid-row__fx {
  display: block;
  margin-top: 3px;
  color: var(--ink-3);
  font-family: var(--font);
  font-size: 14px;
}

.wid-row__fx b {
  color: var(--ink-2);
  font-weight: 600;
}

.is-running .wid-row {
  animation: wid-row 9s var(--ease) infinite;
  animation-delay: calc(var(--r) * 260ms);
}

@keyframes wid-row {
  0% { opacity: 0; transform: translateY(6px); }
  5%, 92% { opacity: 1; transform: none; }
  98%, 100% { opacity: 0; transform: translateY(6px); }
}

/* The guard, and its disappearance. At rest it is already struck through. */
.wid-guard {
  position: relative;
  color: var(--ink-3);
  text-decoration: none;
}

.wid-guard::after {
  content: "";
  position: absolute;
  left: -1px;
  right: -1px;
  top: 54%;
  height: 1px;
  background: var(--warn);
  transform: scaleX(1);
  transform-origin: 0 50%;
}

.is-running .wid-guard {
  animation: wid-guard 9s var(--ease) infinite;
}

@keyframes wid-guard {
  0%, 45% { color: var(--ink-2); }
  52%, 100% { color: var(--ink-3); }
}

.is-running .wid-guard::after {
  animation: wid-strike 9s var(--ease) infinite;
}

@keyframes wid-strike {
  0%, 46% { transform: scaleX(0); }
  54%, 96% { transform: scaleX(1); }
  100% { transform: scaleX(0); }
}

.wid-row--watch {
  background: linear-gradient(var(--warn-tint), var(--warn-tint)), #121a1e;
  box-shadow: inset 2px 0 0 var(--warn), inset 0 0 0 1px var(--line);
}

.is-running .wid-row--watch {
  animation: wid-row 9s var(--ease) infinite, wid-turn 9s var(--ease) infinite;
  animation-delay: calc(var(--r) * 260ms), 0s;
}

@keyframes wid-turn {
  0%, 50% {
    background: #121a1e;
    box-shadow: inset 2px 0 0 var(--line-lit), inset 0 0 0 1px var(--line);
  }
  56%, 94% {
    background: linear-gradient(var(--warn-tint), var(--warn-tint)), #121a1e;
    box-shadow: inset 2px 0 0 var(--warn), inset 0 0 0 1px var(--line);
  }
  100% {
    background: #121a1e;
    box-shadow: inset 2px 0 0 var(--line-lit), inset 0 0 0 1px var(--line);
  }
}

.wid-flag {
  display: block;
  margin-top: 9px;
  padding-top: 9px;
  border-top: 1px dashed var(--warn-rule);
  color: var(--warn);
  font-family: var(--font);
  font-size: 14px;
  font-weight: 560;
}

.is-running .wid-flag {
  animation: wid-flag 9s var(--ease) infinite;
}

@keyframes wid-flag {
  0%, 54% { opacity: 0; transform: translateY(-3px); }
  60%, 94% { opacity: 1; transform: none; }
  100% { opacity: 0; transform: translateY(-3px); }
}

/* The verdict. Both lines are in the markup; the finding is the one at rest. */
.wid-scan__status {
  position: relative;
  min-height: 1.5em;
  margin: 18px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.5;
}

.wid-scan__ok,
.wid-scan__bad {
  position: absolute;
  left: 0;
  top: 14px;
}

.wid-scan__ok {
  color: var(--ink-3);
  opacity: 0;
}

.wid-scan__bad {
  color: var(--warn);
  font-weight: 600;
}

.is-running .wid-scan__ok { animation: wid-ok 9s var(--ease) infinite; }
.is-running .wid-scan__bad { animation: wid-bad 9s var(--ease) infinite; }

@keyframes wid-ok {
  0%, 12% { opacity: 0; }
  18%, 44% { opacity: 1; }
  50%, 100% { opacity: 0; }
}

@keyframes wid-bad {
  0%, 56% { opacity: 0; }
  62%, 94% { opacity: 1; }
  100% { opacity: 0; }
}

/* ---- the covers: two reports, each with the top of the real report ---- */

.wid-covers {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 24px;
  margin-top: clamp(56px, 6vw, 80px);
}

.wid-cover {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 32px 36px 0;
  overflow: hidden;
  border-radius: 22px;
  background: var(--surface);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.06);
  transition: box-shadow 0.2s var(--ease);
}

.wid-cover:hover {
  box-shadow: inset 0 0 0 1px var(--line-lit);
}

.wid-cover__readout {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 7px;
  margin: 0;
  color: var(--ink-3);
  font-size: 14.5px;
  line-height: 1.4;
}

.wid-cover__readout b {
  color: var(--ink);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.wid-cover__readout em {
  color: var(--warn);
  font-style: normal;
  font-weight: 560;
}

.wid-cover__readout em::before {
  content: "\00B7";
  margin-right: 7px;
  color: var(--ink-3);
}

.wid-cover__readout em.is-clean {
  color: var(--teal);
}

.wid-cover__name {
  margin: 12px 0 0;
  font-size: 24px;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.02em;
}

.wid-cover__name a {
  color: var(--ink);
  text-decoration: none;
}

/* The primary link covers the card; the study link below sits above it. */
.wid-cover__name a::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
}

.wid-cover__desc {
  max-width: 60ch;
  margin: 12px 0 0;
  color: var(--ink-2);
  font-size: 15.5px;
  line-height: 1.55;
}

.wid-cover__desc a {
  position: relative;
  z-index: 2;
}

.wid-cover .record__meta {
  margin-top: 18px;
}

.wid-cover__shot {
  margin-top: auto;
  padding-top: 34px;
}

.wid-cover__shot img {
  width: 100%;
  border-radius: 12px 12px 0 0;
  box-shadow: 0 30px 60px -30px rgba(0, 0, 0, 0.8), 0 0 0 1px rgba(255, 255, 255, 0.06);
}

/* ---- the pull request check ---- */

.wid-check {
  margin-top: clamp(104px, 10vw, 140px);
}

.wid-check__head {
  max-width: 680px;
}

.wid-check__head p,
.wid-pricing__head p {
  margin: 20px 0 0;
  color: var(--ink-2);
  font-size: 17px;
  line-height: 1.6;
}

.wid-check__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.08fr) minmax(0, 0.92fr);
  gap: 24px;
  align-items: stretch;
  margin-top: 48px;
}

/* Two panels of the same weight: the comment, and the file that produces it. */
.wid-pr,
.wid-setup {
  min-width: 0;
  margin: 0;
  padding: 26px 30px 28px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: #0e1215;
}

.wid-pr__label,
.wid-setup__label {
  margin: 0 0 18px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line);
  color: var(--ink-3);
  font-size: 14px;
  line-height: 1.4;
}

.wid-pr__body p {
  margin: 0 0 12px;
  color: var(--ink-2);
  font-size: 15px;
  line-height: 1.6;
}

.wid-pr__body b {
  color: var(--ink);
  font-weight: 600;
}

.wid-pr__body .wid-pr__title {
  color: var(--ink);
  font-size: 17px;
  font-weight: 600;
}

/* The finding, marked the way the scan marks one: a pink rule, no box. */
.wid-pr__warn {
  margin: 18px 0;
  padding: 4px 0 4px 18px;
  border-left: 2px solid var(--warn);
  color: var(--ink-2);
}

.wid-pr__body .wid-pr__warnhead {
  color: var(--warn);
  font-weight: 600;
}

.wid-pr__body .wid-pr__warn p:last-child {
  margin-bottom: 0;
}

.wid-pr__route code {
  color: var(--ink);
  font-size: 13px;
}

.wid-pr__where code {
  padding: 0;
  background: none;
  box-shadow: none;
  color: var(--ink-3);
  font-size: 12.5px;
}

.wid-pr__body .wid-pr__sub {
  margin: 0;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  color: var(--ink-3);
  font-size: 14px;
}

/* The file is the panel's content, not a box inside it. */
.wid-yaml {
  margin: 0;
  padding: 2px 0 6px;
  border: 0;
  border-radius: 4px;
  background: none;
  color: #c3cace;
  font-size: 13px;
  line-height: 1.75;
  tab-size: 2;
}

.wid-yaml code {
  white-space: pre;
}

/* ---- the three objections, as a hairline row ---- */

.wid-assure {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin: 56px 0 0;
  border-top: 1px solid var(--line);
}

.wid-assure li {
  margin: 0 28px 0 0;
  padding: 24px 28px 0 0;
  border-right: 1px solid var(--line);
  color: var(--ink-2);
  font-size: 15px;
  line-height: 1.55;
}

.wid-assure li:last-child {
  margin-right: 0;
  border-right: 0;
}

.wid-assure li::before {
  content: none;
}

.wid-assure b {
  display: block;
  margin-bottom: 8px;
  color: var(--ink);
  font-weight: 600;
}

/* ---- the scan is free, and so is the watching ---- */

.wid-pricing {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 560px);
  column-gap: clamp(48px, 6vw, 96px);
  align-items: start;
  margin-top: clamp(104px, 10vw, 140px);
}

.wid-pricing__head {
  max-width: 620px;
}

.wid-gratis__item {
  padding: 22px 0 26px;
  border-top: 1px solid var(--line);
}

.wid-gratis__item:last-child {
  border-bottom: 1px solid var(--line);
}

.wid-gratis__item h4 {
  margin: 0 0 8px;
  color: var(--ink);
  font-size: 17px;
  font-weight: 600;
}

.wid-gratis__item p {
  margin: 0;
  color: var(--ink-2);
  font-size: 15px;
  line-height: 1.6;
}

.wid-gratis__item .wid-gratis__cta {
  margin-top: 14px;
}

.wid-gratis__cta code {
  font-size: 13px;
}

.wid-caption {
  max-width: 68ch;
  margin: clamp(64px, 7vw, 96px) 0 0;
  color: var(--ink-3);
  font-size: 14px;
  line-height: 1.6;
}

.wid-caption b {
  color: var(--ink-2);
  font-weight: 600;
}

/* ================================================================= aion */

.aion-head {
  max-width: 920px;
}

.aion-head .lede {
  max-width: 62ch;
  margin: 22px 0 0;
  font-size: 18px;
  line-height: 1.55;
}

.aion-feature {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 540px);
  column-gap: clamp(48px, 6vw, 96px);
  align-items: start;
  margin-top: clamp(80px, 8vw, 112px);
}

.aion-feature__body {
  max-width: 62ch;
}

.aion-feature__body h3 {
  margin-bottom: 22px;
}

.aion-feature__body p {
  color: var(--ink-2);
}

.aion-feature__body .aion-feature__link {
  margin: 26px 0 0;
}

/* ---- the benchmark: the finding, not the syntax ---- */

.aion-bench {
  padding: 26px 30px 24px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: #0e1215;
}

.aion-bench__q {
  margin: 0 0 24px;
  color: var(--ink);
  font-size: 17px;
  font-weight: 600;
  line-height: 1.35;
}

.aion-bench__row {
  margin-bottom: 20px;
}

.aion-bench__label {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 10px;
  color: var(--ink-2);
  font-size: 14.5px;
  line-height: 1.4;
}

.aion-bench__label b {
  color: var(--ink);
  font-size: 15px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.aion-bench__row--win .aion-bench__label {
  color: var(--ink);
}

.aion-bench__track {
  position: relative;
  display: block;
  height: 12px;
  overflow: hidden;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.06);
}

.aion-bench__track i {
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--w);
  min-width: 6px;
  border-radius: 6px;
  background: #6d757c;
}

.aion-bench__row--win .aion-bench__track i {
  background: var(--teal);
}

.is-running .aion-bench__track i {
  animation: aion-fill 7s var(--ease) infinite;
}

.aion-bench__note {
  margin: 24px 0 0;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  color: var(--ink-3);
  font-size: 14px;
  line-height: 1.55;
}

.aion-bench__note b {
  color: var(--ink);
  font-weight: 600;
}

/* ---- the run, on the plate ---- */

/*
  A run, not an illustration. One program fans out to forty concurrent calls
  and comes back as a single answer, and the two meters beside it are the
  measured result of a real forty-file review. At rest every cell is done,
  the answer is in and the meters are full; lab.js plays the sequence only
  while it is on screen.
*/
.aion-run {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  grid-template-rows: auto auto;
  column-gap: clamp(40px, 5vw, 80px);
  align-items: center;
  margin: clamp(80px, 8vw, 112px) 0 0 calc(-1 * var(--bleed));
  padding: clamp(48px, 5vw, 72px) clamp(32px, 4.4vw, 64px) clamp(48px, 5vw, 72px) var(--bleed);
  border-radius: 0 24px 24px 0;
}

.aion-run > * {
  position: relative;
  z-index: 6;
}

.aion-run__stage {
  grid-row: 1 / span 2;
  display: grid;
  grid-template-columns: auto minmax(30px, 60px) minmax(0, 1fr) minmax(30px, 60px) auto;
  align-items: stretch;
}

.aion-node {
  align-self: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  min-width: 96px;
  padding: 16px 14px 14px;
  border-radius: 12px;
  background: var(--plate-ink);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.14), 0 24px 48px -24px rgba(0, 0, 0, 0.8);
}

.aion-node b {
  color: var(--ink);
  font-size: 28px;
  font-weight: 560;
  line-height: 1;
  letter-spacing: -0.03em;
}

.aion-node span {
  color: var(--ink-2);
  font-size: 13.5px;
  line-height: 1.2;
}

/* At rest the answer is in: the one node that carries the result is lit. */
.aion-node--out {
  box-shadow: 0 0 0 1px var(--teal), 0 24px 48px -24px rgba(0, 0, 0, 0.8);
}

.is-running .aion-node--out {
  animation: aion-land 7s var(--ease) infinite;
}

@keyframes aion-land {
  0%, 58% { box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.14), 0 24px 48px -24px rgba(0, 0, 0, 0.8); }
  70%, 92% { box-shadow: 0 0 0 1px var(--teal), 0 24px 48px -24px rgba(0, 0, 0, 0.8); }
  100% { box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.14), 0 24px 48px -24px rgba(0, 0, 0, 0.8); }
}

.aion-wires {
  width: 100%;
  height: 100%;
  min-height: 84px;
  overflow: visible;
}

.aion-wires path {
  fill: none;
  stroke: rgba(255, 255, 255, 0.22);
  stroke-width: 1.2;
  vector-effect: non-scaling-stroke;
}

.is-running .aion-wires path {
  stroke: var(--teal-lit);
  stroke-dasharray: 4 8;
  animation: aion-wire 7s linear infinite;
}

/* Out-bound wires carry first; the return leg carries after the fan is done. */
@keyframes aion-wire {
  0% { stroke-dashoffset: 0; opacity: 0.2; }
  12%, 52% { opacity: 0.8; }
  100% { stroke-dashoffset: -240; opacity: 0.2; }
}

.aion-wires--back path {
  animation-delay: 0.9s;
}

/* The forty calls. At rest, every one has returned. */
.aion-fan {
  display: grid;
  grid-template-columns: repeat(10, minmax(0, 1fr));
  gap: 6px;
  padding: 0 clamp(8px, 1.4vw, 18px);
}

.aion-fan i {
  display: block;
  aspect-ratio: 1;
  border-radius: 3px;
  background: rgba(138, 240, 208, 0.2);
  box-shadow: inset 0 0 0 1px rgba(138, 240, 208, 0.42);
}

/*
  Each cell is one model call. They fire in a staggered wave rather than in
  unison because forty concurrent calls do not return at the same instant,
  and a wave shows the concurrency that a simultaneous flash would hide.
*/
.is-running .aion-fan i {
  animation: aion-cell 7s var(--ease) infinite;
  animation-delay: calc(var(--i) * 42ms);
}

@keyframes aion-cell {
  0%, 6% {
    background: rgba(255, 255, 255, 0.04);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1);
  }
  14% {
    background: rgba(138, 240, 208, 0.7);
    box-shadow: inset 0 0 0 1px var(--teal-lit);
  }
  30%, 60% {
    background: rgba(138, 240, 208, 0.2);
    box-shadow: inset 0 0 0 1px rgba(138, 240, 208, 0.42);
  }
  78%, 100% {
    background: rgba(255, 255, 255, 0.04);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1);
  }
}

/* ---- the ledger ---- */

.aion-ledger {
  align-self: end;
  display: grid;
  gap: 22px;
}

.aion-meter {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "k v" "bar bar";
  align-items: baseline;
  column-gap: 16px;
  row-gap: 10px;
}

.aion-meter__k {
  grid-area: k;
  color: #b9c3c4;
  font-size: 14.5px;
}

.aion-meter__v {
  grid-area: v;
  color: var(--ink);
  font-size: 14.5px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.aion-meter__bar {
  grid-area: bar;
  position: relative;
  display: block;
  height: 12px;
  overflow: hidden;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.08);
}

.aion-meter__bar i {
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--w);
  min-width: 6px;
  border-radius: 6px;
  background: #dce2e5;
}

.aion-meter--kept .aion-meter__bar i {
  background: var(--teal-lit);
}

.is-running .aion-meter__bar i {
  animation: aion-fill 7s var(--ease) infinite;
}

@keyframes aion-fill {
  0%, 46% { width: 0; }
  66%, 92% { width: var(--w); }
  100% { width: 0; }
}

.aion-run__note {
  align-self: start;
  margin: 26px 0 0;
  padding-top: 18px;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  color: #b9c3c4;
  font-size: 15px;
  line-height: 1.55;
}

.aion-run__note b {
  color: var(--ink);
  font-weight: 600;
}

/* ----------------------------------------------------------- responsive */

/* Below this the scan would cover most of the field, so the hero stacks. */
@media (max-width: 1280px) {
  .wid-hero {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 48px;
  }
  .wid-hero__copy {
    max-width: 620px;
  }
  .wid-stage {
    min-height: 0;
    margin-left: calc(-1 * var(--gutter));
    margin-right: calc(-1 * var(--gutter));
    padding: 56px var(--gutter);
    border-radius: 0;
  }
  .wid-scan {
    max-width: 520px;
  }
  .wid-map {
    right: 2%;
    width: 600px;
  }
}

@media (max-width: 1180px) {
  .aion-run {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: none;
    row-gap: 40px;
  }
  .aion-run__stage {
    grid-row: auto;
  }
  .aion-ledger {
    max-width: 620px;
  }
  .aion-run__note {
    max-width: 620px;
    margin-top: -14px;
  }
}

@media (max-width: 1000px) {
  .aion-feature,
  .wid-pricing {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 48px;
  }
  .wid-map {
    right: -12%;
  }
  .aion-run {
    margin-left: calc(-1 * var(--gutter));
    margin-right: calc(-1 * var(--gutter));
    padding: 48px var(--gutter);
    border-radius: 0;
  }
  .wid-covers,
  .wid-check__grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 760px) {
  .lab-index {
    grid-template-columns: minmax(0, 1fr);
  }
  .lab-index a {
    margin-right: 0;
    padding: 22px 0;
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }
  .spec {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .spec > div {
    padding: 20px 0 20px 20px;
  }
  .spec > div:nth-child(odd) {
    padding-left: 0;
    padding-right: 16px;
    border-left: 0;
  }
  .spec > div:nth-child(n + 3) {
    border-top: 1px solid var(--line);
  }
  .wid-assure {
    grid-template-columns: minmax(0, 1fr);
  }
  .wid-assure li {
    margin-right: 0;
    padding: 22px 0;
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }
  .wid-assure li:last-child {
    border-bottom: 0;
  }
}

/* The wires need horizontal room to read as a fan; without it they are
   noise, so the stage stacks and they go. */
@media (max-width: 720px) {
  .aion-run__stage {
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
    row-gap: 18px;
  }
  .aion-wires {
    display: none;
  }
  .aion-fan {
    width: 100%;
    padding: 0;
  }
}

@media (max-width: 640px) {
  /* The scan fills the width here, so the field gets its own band above it. */
  .wid-stage {
    padding: 180px var(--gutter) 40px;
  }
  .wid-scan {
    padding: 20px 18px 18px;
  }
  .wid-map {
    top: -20px;
    right: -6%;
    width: 440px;
    transform: none;
  }
  .wid-cover {
    padding: 26px 24px 0;
  }
  .wid-pr,
  .wid-setup {
    padding: 22px 20px 24px;
  }
  /* The file still scrolls sideways inside its panel; smaller type shows more of each line. */
  .wid-yaml {
    font-size: 12px;
  }
  .aion-bench {
    padding: 22px 20px 20px;
  }
}

/* The graph arrives already drawn; style.css stops every animation, so each
   sequence rests in its finished state. */
@media (prefers-reduced-motion: reduce) {
  .js .wid-map line {
    stroke-dashoffset: 0;
  }
  .js .wid-map circle {
    opacity: 1;
  }
}

@media print {
  .wid-stage,
  .aion-run {
    margin-left: 0;
    margin-right: 0;
    border-radius: 0;
  }
  .js .wid-map line {
    stroke-dashoffset: 0;
  }
  .js .wid-map circle {
    opacity: 1;
  }
}
