/* ─────────────────────────────────────────────────────────────────────────
   hero.css — §0 and the services list.

   02 §6 governs: enormous negative space, type left and the moving element
   right, hairline rules only, NO card grids, no gradients, no drop shadows on
   UI, no rounded badges. Blue appears only where current is flowing — the
   workflow packets, drawn on canvas — never on a button, link or heading.
   ───────────────────────────────────────────────────────────────────────── */

/* No bottom padding. The last section carries its own, and the footer adds
   its margin on top of that — a third slab here stacked them into most of a
   blank screen between the end card and the footer. */
#page {
  position: relative;
  z-index: var(--z-content);
  padding: 0 var(--s5);
  max-width: 1560px;
  margin: 0 auto;
}

/* ── hero ──────────────────────────────────────────────────────────────── */

/* Type left, the running workflow right, on white. The panel and the arc
   field behind it are both drawn LARGER than the hero and run off its foot
   and its right edge: the crop is the composition — a system caught
   mid-run, continuing past the fold — and not a sizing accident. `overflow`
   is what makes that safe to state in one place. */
.hero {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.98fr);
  gap: var(--s6);
  align-items: center;
  min-height: min(880px, 94svh);
  /* The floor clears the fixed header, which is 77px at its tallest (the
     CTA's 44px minimum plus its padding) — at 92px the badge slid under it. */
  padding-top: clamp(108px, 12vh, 144px);
  overflow: hidden;
}

.hero-type { position: relative; z-index: 2; padding-bottom: var(--s5); }

/* ── the badge ─────────────────────────────────────────────────────────── */
/* A hairline pill, not a filled chip: 02 §6 bans rounded badges with fills,
   and the only thing carrying colour here is the dot — which is the current,
   live, exactly as it is everywhere else on the site. */

.hero-badge {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: var(--eyebrow-size);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-60);
  border: var(--hairline);
  border-radius: 999px;
  padding: 8px var(--s3) 8px 14px;
  margin-bottom: var(--s4);
}

.hero-badge i {
  position: relative;
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--leaf);
}

/* The ring is a pseudo-element on the dot, so the pulse costs one composited
   layer and never moves the pill's own layout. */
.hero-badge i::after {
  content: '';
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 1px solid var(--leaf);
  animation: badge-pulse 2400ms var(--ease-out) infinite;
}

@keyframes badge-pulse {
  0%        { transform: scale(0.55); opacity: 0.9; }
  70%, 100% { transform: scale(1.5);  opacity: 0; }
}

/* ── the headline ──────────────────────────────────────────────────────── */

/* The break between the two lines is EXPLICIT (a <br> in hero.js), because
   the accent line and its underline are one unit and cannot be allowed to
   split across a wrap. The size is then set by what has to fit on line one —
   "AI systems that run" in the type column — rather than the other way
   round; at 5vw it stranded "run" on a line of its own. */
.hero .display {
  font-size: clamp(34px, 4.35vw, 74px);
  max-width: 20ch;
  margin-bottom: var(--s4);
}

/* The last line carries the current's green and a drawn underline. It is
   inline-block so the underline is positioned against the WORDS rather than
   the h1's own box, which is as wide as its longest line.

   SCOPED TO .hero DELIBERATELY. Bare `.hero-accent` also matched the service
   pages, which declare their own `.hero-accent` in service-detail.css using
   --leaf-ink. Every service shell loads service-detail.css BEFORE hero.css,
   so at equal specificity this rule won and repainted a 23–37px line in
   --leaf on white: 2.41:1, under the 3:1 WCAG AA floor for large text, and
   signal green used as body colour, which 02 §1 reserves for live current.
   --leaf-ink is the text-safe green and measures 5.28:1. */
.hero .hero-accent {
  position: relative;
  display: inline-block;
  color: var(--leaf);
}

.hero-underline {
  position: absolute;
  left: -1%;
  bottom: -0.16em;
  width: 103%;
  height: 0.26em;
  color: var(--leaf);
  overflow: visible;
  pointer-events: none;
}

/* `non-scaling-stroke` is what lets the swoosh stretch to the width of the
   words without the stroke stretching with it; `pathLength="1"` normalises
   the dash maths so the draw-on needs no measured length. */
.hero-underline path {
  stroke: currentColor;
  stroke-width: 6;
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: draw-underline 760ms var(--ease-out) 560ms forwards;
}

@keyframes draw-underline { to { stroke-dashoffset: 0; } }

.hero-sub {
  font-weight: 500;
  font-size: clamp(16px, 1.35vw, 21px);
  max-width: 34ch;
  color: var(--ink-60);
  margin-bottom: var(--s5);
}

/* ── the two actions ───────────────────────────────────────────────────── */

.hero-actions { display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap; }

.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--s3);
  min-height: 56px;
  padding: 0 var(--s4);
  border-radius: 999px;
  font-family: var(--font-mono);
  font-size: var(--eyebrow-size);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: background 200ms var(--ease-out), color 200ms var(--ease-out),
              border-color 200ms var(--ease-out);
}

.pill-ghost { border: 1px solid var(--ink); color: var(--ink); }
.pill-ghost:hover { background: var(--ink); color: var(--page); }

/* Padded short on the right: the arrow badge supplies that side's inset. */
.pill-solid {
  background: var(--leaf);
  border: 1px solid var(--leaf);
  color: var(--ink);
  padding-right: 6px;
}

.pill-solid:hover { background: #17A857; border-color: #17A857; }

.pill-arrow {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--ink);
  color: var(--leaf);
  font-size: 15px;
  transition: transform 200ms var(--ease-out);
}

.pill-solid:hover .pill-arrow { transform: translateX(3px); }

/* ── which of the nine is running ──────────────────────────────────────── */
/* The panel states this in its own foot, and the foot is what the hero crops
   off. One dot per service says the same thing where it survives the crop. */

.hero-now {
  display: flex;
  align-items: center;
  gap: var(--s3);
  margin-top: var(--s5);
  padding-top: var(--s4);
  border-top: var(--hairline);
  max-width: 32ch;
}

.hero-now-label { color: var(--ink-60); letter-spacing: 0.14em; }

.hero-dots { display: flex; align-items: center; gap: 7px; }

.hero-dots i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--graphite);
  transition: background 300ms var(--ease-out), transform 300ms var(--ease-out);
}

.hero-dots i.is-on { background: var(--leaf); transform: scale(1.6); }

/* ── the live workflow: the phone-shaped sequence ──────────────────────── */

.hero-flow {
  position: relative;
  align-self: stretch;
  display: grid;
  place-items: end center;
  margin: 0;
  /* Out to the page's own edge, so the field is not visibly boxed. */
  margin-right: calc(var(--s5) * -1);
  min-width: 0;
}

/* CONCENTRIC WITH THE PANEL, by construction. The field is centred on the
   stage — which is the panel's own box — rather than positioned against the
   column, so there is no arrangement of columns, gaps or bleeds that can put
   the arcs anywhere but around the thing they belong to.

   Square, because a square box and a square viewBox is what makes the centre
   of the drawing land on the centre of the box. */
.hero-field {
  position: absolute;
  left: 50%;
  top: 50%;
  translate: -50% -50%;
  width: 280%;
  aspect-ratio: 1;
  z-index: -1;
  pointer-events: none;
  /* Fades out all the way round instead of being cut off by the hero's edge,
     so the field reads as continuing past the page. It also keeps the arcs
     off the headline without a directional mask: by the time they reach the
     type column they have nothing left. */
  -webkit-mask-image: radial-gradient(closest-side, #000 52%, transparent 100%);
  mask-image: radial-gradient(closest-side, #000 52%, transparent 100%);
}

/* THE DRIFT. Scaling the whole SVG by exactly the radius ratio moves every
   ring onto its neighbour's starting radius, so the loop closes on an
   identical frame — there is no fade, no restart, and the arcs simply keep
   coming out from behind the panel. `scale` and not `transform`, so the
   centring `translate` above stays untouched. */
.hero-rings {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  color: var(--graphite);
  opacity: 0.72;
  animation: rings-drift 9s linear infinite;
}

@keyframes rings-drift { to { scale: 1.2; } }

/* THE CURRENT LEAVING THE PANEL. Three rings on one long cycle, started at
   thirds of it, so one is always on its way out. */
.hero-pulse {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 46%;
  aspect-ratio: 1;
  margin: -23% 0 0 -23%;
  border: 1px solid var(--leaf);
  border-radius: 50%;
  opacity: 0;
  animation: hero-pulse 7.2s var(--ease-out) infinite;
  animation-delay: var(--d, 0s);
}

@keyframes hero-pulse {
  0%   { scale: 0.28; opacity: 0; }
  10%  { opacity: 0.42; }
  100% { scale: 2.05; opacity: 0; }
}

/* The panel is held at the FOOT of the column and runs past it. It styles
   itself — see "THE PHONE-SHAPED SEQUENCE" in sections.css — because the
   same component also mounts in §02, and one of them having its own look
   would defeat the point of the visitor recognising it. */
.hero-screen {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: end center;
  width: 100%;
  margin-bottom: calc(var(--s7) * -1);
}

/* THE STAGE IS THE PANEL'S BOX — the field is centred against it, so it has
   to be the panel's size exactly and nothing larger.

   The cap on the third term is the panel's own height budget, not a width:
   at 9:16.6 a panel is 1.844× as tall as it is wide, so on a short laptop
   screen this is what stops it starting above the headline. The bleed past
   the hero's foot is fixed by the margin above, so growing the panel extends
   it UPWARD and never deepens the crop. */
.hero-stage {
  position: relative;
  width: min(384px, 88%, calc((100svh - 150px) / 1.844));
}

/* Positioned, so it paints over the field. An absolutely positioned sibling
   otherwise paints above a static one whatever the DOM order says. */
.hero-stage .phone { position: relative; z-index: 1; width: 100%; }


/* ── the nine services ─────────────────────────────────────────────────── */
/* Hairline-separated rows; each expands its own workflow, one at a time.  */

.services { border-top: var(--hairline); }

.services-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: var(--s4) 0 var(--s3);
}

.services-hint { color: var(--ink-60); letter-spacing: 0.10em; }

.service-list { list-style: none; }

.service-row { border-bottom: var(--hairline); }

.service-hit {
  display: grid;
  /* A fixed name column so every description starts on the same axis —
     an auto column sizes to AUTOMATION and leaves the rest ragged. */
  grid-template-columns: 3.25rem 13rem 1fr auto;
  gap: var(--s4);
  align-items: baseline;
  width: 100%;
  padding: var(--s4) 0;
  background: none;
  border: 0;
  text-align: left;
  cursor: pointer;
  font: inherit;
  color: inherit;
}

.service-bay { color: var(--ink-60); }

.service-name {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(19px, 1.9vw, 29px);
  letter-spacing: var(--display-tracking);
  text-transform: uppercase;
  white-space: nowrap;
}

.service-line {
  font-size: clamp(14px, 1.1vw, 17px);
  color: var(--ink-60);
}

.service-go {
  color: var(--ink-60);
  opacity: 0;
  letter-spacing: 0.14em;
  transition: opacity 180ms var(--ease-out);
}

.service-row.is-active .service-go,
.service-hit:hover .service-go,
.service-hit:focus-visible .service-go { opacity: 1; }

.service-row.is-active .service-line { color: var(--ink); }

/* The active marker is a hairline that thickens — green: current flowing. */
.service-row.is-active { box-shadow: inset 2px 0 0 0 var(--leaf); }

.service-row.is-active .service-hit { padding-left: var(--s3); }

.service-row.is-open .service-go { opacity: 1; color: var(--leaf-ink); }

/* ── the inline workflow panel — grid-rows so height animates cheaply ──── */

.service-panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 520ms var(--ease-inout);
}

.service-row.is-open .service-panel { grid-template-rows: 1fr; }

/* Inset matches the open row's shifted hit, clear of the green marker. */
.service-panel-clip { overflow: hidden; min-height: 0; padding-left: var(--s3); }

.service-panel-head {
  display: flex;
  gap: var(--s3);
  align-items: baseline;
  padding: var(--s3) 0 var(--s2);
}

.panel-bay { color: var(--leaf-ink); }

.panel-name { font-weight: 700; letter-spacing: 0.10em; }

.service-panel-flow { padding-bottom: var(--s4); }


@media (prefers-reduced-motion: reduce) {
  .service-panel { transition: none; }
}

/* ── reveal ────────────────────────────────────────────────────────────── */

body[data-hero-ready] .hero-type > *,
body[data-hero-ready] .hero-flow { animation: rise 620ms var(--ease-out) backwards; }

body[data-hero-ready] .hero-type > *:nth-child(1) { animation-delay: 40ms; }
body[data-hero-ready] .hero-type > *:nth-child(2) { animation-delay: 90ms; }
body[data-hero-ready] .hero-type > *:nth-child(3) { animation-delay: 160ms; }
body[data-hero-ready] .hero-type > *:nth-child(4) { animation-delay: 230ms; }
body[data-hero-ready] .hero-type > *:nth-child(5) { animation-delay: 300ms; }
body[data-hero-ready] .hero-flow { animation-delay: 200ms; }

@keyframes rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

/* ── breakpoints ───────────────────────────────────────────────────────── */

@media (max-width: 1000px) {
  /* Stacked, the panel sits under the type and there is no second column for
     the field to be struck from — so it centres behind the panel instead,
     and the crop comes off the foot alone. */
  .hero {
    grid-template-columns: 1fr;
    gap: var(--s5);
    min-height: auto;
    padding-top: var(--s7);
  }
  .hero .display { max-width: 18ch; }
  .hero-flow { margin-right: 0; align-self: auto; }
  .hero-screen { margin-bottom: calc(var(--s6) * -1); }
  .hero-stage { width: min(352px, 68%, calc((100svh - 150px) / 1.844)); }
}

@media (max-width: 720px) {
  #page { padding: 0 var(--s3); }
  .hero-actions { gap: var(--s2); }
  .pill { min-height: 52px; padding: 0 var(--s3); gap: var(--s2); }
  .pill-solid { padding-right: 6px; }
  .pill-arrow { width: 40px; height: 40px; }
  .hero-stage { width: min(270px, 80%); }
  /* Side by side, the hint and the eyebrow each wrap to two lines and
     interleave. Stack them. */
  .services-head { display: block; }
  .services-hint { margin-top: var(--s1); }
  .service-hit {
    grid-template-columns: 2.6rem 1fr;
    grid-template-areas: 'bay name' '.   line';
    gap: var(--s2) var(--s3);
    padding: var(--s3) 0;
  }
  .service-bay { grid-area: bay; }
  .service-name { grid-area: name; }
  .service-line { grid-area: line; }
  .service-go { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  body[data-hero-ready] .hero-type > *,
  body[data-hero-ready] .hero-flow { animation: none; }
  /* The pulse goes entirely; the underline keeps its drawn shape but is
     simply THERE, rather than animating on. base.css crushes every duration
     to 0.01ms, which would leave a `forwards` fill mid-draw if the offset
     were still 1 at rest. */
  .hero-badge i::after { animation: none; opacity: 0; }
  .hero-underline path { animation: none; stroke-dashoffset: 0; }
  /* The field holds still and the pulses go entirely. base.css crushes every
     duration to 0.01ms, which for an infinite loop is not "stopped" — it is
     the same motion running as fast as the compositor will allow. */
  .hero-rings { animation: none; }
  .hero-pulse { animation: none; opacity: 0; }
}
