/* Extracted from platform.html — page-specific styles */

/* ===================================================================
   PLACEHOLDER STILL — body + center slate headline only
   =================================================================== */
.still {
  position: relative;
  border: 1px solid var(--hair);
  background: var(--bg-2);
  aspect-ratio: 5 / 4;
  overflow: hidden;
  display: flex; flex-direction: column;
}
.still-body {
  position: relative;
  flex: 1;
  overflow: hidden;
  background:
    radial-gradient(circle at 50% 45%, rgba(255,255,255,.05) 0%, transparent 62%),
    repeating-linear-gradient(135deg,
      var(--bg-2) 0px,
      var(--bg-2) 14px,
      var(--bg-3) 14px,
      var(--bg-3) 28px);
  box-shadow: inset 0 0 80px rgba(0,0,0,.35);
}
.section-light .still-body {
  background:
    radial-gradient(circle at 50% 45%, rgba(0,0,0,.04) 0%, transparent 62%),
    repeating-linear-gradient(135deg,
      var(--bg-2) 0px,
      var(--bg-2) 14px,
      var(--bg-3) 14px,
      var(--bg-3) 28px);
  box-shadow: inset 0 0 80px rgba(0,0,0,.10);
}

.still-slate {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  background: rgba(8,9,10,.86);
  border: 1px solid rgba(255,255,255,.10);
  color: #fff;
  padding: 18px 22px;
  text-align: center;
  min-width: 240px;
  max-width: 78%;
  z-index: 4;
}

.ito-illustration {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.ito-still { border: none; }
/* The illustration is a cut-out with a transparent ground, so the still's
   diagonal placeholder stripes would show through it. Paint the body in the
   section colour instead (same reason `.distribute-still` paints itself black). */
.ito-still .still-body { background: var(--bg); box-shadow: none; }

/* Distribute section illustration */
.distribute-illustration {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.distribute-still { border: none; }
.distribute-still .still-body { background: #000; box-shadow: none; }

/* Activate section illustration */
.activate-illustration {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.section-light .activate-still { border: 0; outline: 0; }
.section-light .activate-still .still-body {
  background: var(--bg);
  box-shadow: none;
}

/* Measure section illustration */
.measure-illustration {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.measure-still { border: none; }
.measure-still .still-body { background: #000; box-shadow: none; }
.still-slate .slate-headline {
  font-family: 'Oswald', sans-serif;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: -.01em;
  font-size: clamp(16px, 1.4vw, 20px);
  line-height: 1.1;
  color: #fff;
}

/* ===================================================================
   COLLECT · hub-and-spoke ingest illustration
   (lives inside the Step-01 .still — replaces the slate placeholder)
   =================================================================== */
#step-collect .seq-band-inner {
  grid-template-columns: 1fr 1.3fr;
  gap: clamp(40px, 6vw, 96px);
}
@media (max-width: 1100px) {
  #step-collect .seq-band-inner { grid-template-columns: 1fr 1.2fr; }
}
@media (max-width: 960px) {
  #step-collect .seq-band-inner { grid-template-columns: 1fr; }
}

#step-collect .still {
  border: 0;
  background: transparent;
}
#step-collect .still-body {
  background: transparent;
  box-shadow: none;
}

.ingest {
  position: absolute; inset: 0;
  overflow: hidden;
}
.ingest-stage {
  position: absolute;
  left: 50%; top: 50%;
  width: 1400px;
  height: 1120px;
  transform: translate(-50%, -50%) scale(1);
  transform-origin: center;
  will-change: transform;
}

.ingest svg.web {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  overflow: visible;
}
.ingest .hub        { display: none; }
.ingest .hub-soft   { fill: none; stroke: rgba(255,255,255,.05); stroke-width: 1; }
.ingest .spoke      { stroke: rgba(255,255,255,.09); stroke-width: 1; fill: none; }
.ingest .spoke.thin { stroke: rgba(255,255,255,.06); }
.ingest .spoke.lit  { stroke: var(--accent); stroke-width: 1; opacity: 0; }
.ingest .pulse {
  fill: var(--accent);
  filter: drop-shadow(0 0 6px var(--accent));
  opacity: 0;
}

.ingest .hub-mark {
  position: absolute;
  left: 50%; top: 62.5%;
  transform: translate(-50%, -50%);
  width: 920px; height: 920px;
  border-radius: 50%;
  display: grid; place-items: center;
  z-index: 3;
  pointer-events: none;
}
.ingest .hub-mark img {
  width: 900px;
  height: auto;
  opacity: .96;
  transition: opacity 360ms ease;
}
.ingest .hub-mark .ring-bloom {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: 160px; height: 160px;
  border-radius: 50%;
  box-shadow: 0 0 0 0 rgba(182,245,0,.22);
  opacity: 0;
  pointer-events: none;
}
.ingest.bloomed .hub-mark img { opacity: 1; }
.ingest.bloomed .hub-mark .ring-bloom {
  animation: ingest-bloom 1.6s ease-out forwards;
}
@keyframes ingest-bloom {
  0%   { box-shadow: 0 0 0 0 rgba(182,245,0,.22); opacity: 1; }
  60%  { box-shadow: 0 0 0 28px rgba(182,245,0,0); opacity: .4; }
  100% { box-shadow: 0 0 0 40px rgba(182,245,0,0); opacity: 0; }
}

.ingest .node {
  position: absolute;
  width: 110px; height: 110px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  overflow: hidden;
  z-index: 2;
  transition: box-shadow 320ms ease;
}
.ingest .node .skeleton {
  position: absolute; inset: 0;
  background: #111110;
  border-radius: 50%;
  transition: opacity 320ms ease;
}
.ingest .node .skeleton::before {
  content: "";
  position: absolute; inset: 0;
  background: repeating-linear-gradient(
    135deg, transparent 0 8px, rgba(255,255,255,.02) 8px 9px);
}
.ingest .node .skeleton::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(110deg,
    transparent 30%, rgba(255,255,255,.045) 50%, transparent 70%);
  transform: translateX(-100%);
  animation: ingest-shimmer 2.4s ease-in-out infinite;
}
@keyframes ingest-shimmer {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(100%); }
}
.ingest .node .media {
  position: absolute; inset: 0;
  opacity: 0;
  transform: scale(1.06);
  transition: opacity 380ms ease-out, transform 800ms ease-out;
}
.ingest .node .media img {
  width: 100%; height: 100%; object-fit: contain;
}
.ingest .node .flash {
  position: absolute; inset: 0;
  background: var(--accent);
  mix-blend-mode: screen;
  opacity: 0; z-index: 4; pointer-events: none;
}
.ingest .node.arrived .skeleton { opacity: 0; }
.ingest .node.arrived .media    { opacity: 1; transform: scale(1); }
.ingest .node.firing .flash {
  animation: ingest-nodeflash 420ms ease-out forwards;
}
@keyframes ingest-nodeflash {
  0%   { opacity: 0; }
  22%  { opacity: .4; }
  100% { opacity: 0; }
}

.ingest .label {
  position: absolute;
  color: var(--text);
  font-family: 'Oswald', sans-serif;
  font-weight: 500;
  text-transform: uppercase;
  font-size: 22px;
  letter-spacing: .04em;
  line-height: 1.2;
  white-space: nowrap;
  z-index: 2;
  transition: color 300ms ease;
}
.ingest .label::before {
  content: "";
  display: inline-block;
  width: 8px; height: 8px;
  background: rgba(255,255,255,.22);
  margin-right: 10px;
  transform: translateY(-3px);
  transition: background 300ms ease;
}
.ingest .label.lit::before { background: var(--accent); }

/* ===================================================================
   HERO
   =================================================================== */
.hero {
  position: relative;
  min-height: 100vh;
  max-height: 100vh;
  overflow: hidden;
  padding-top: 64px;
  display: flex; flex-direction: column;
  border-bottom: 1px solid var(--hair);
}

.hero-grid {
  flex: 1;
  display: grid;
  grid-template-columns: 1fr 1.15fr;
  min-height: 72vh;
}
.hero-copy {
  position: relative;
  /* Left column of the hero grid; the right column (photo) bleeds to the edge.
     Left padding tracks the --max page frame so the hero text aligns to the
     nav (frame + 72px); equals 5vw below 1440 — unchanged. */
  padding: 7vh 5vw 7vh max(5vw, calc((100vw - var(--max)) / 2 + 72px));
  display: flex; flex-direction: column; justify-content: center;
}
.hero-eyebrow {
  display: inline-flex; align-items: center; gap: 12px;
  margin-bottom: 24px;
}
.hero-eyebrow .er { width: 36px; height: 1px; background: var(--accent); }
.hero-eyebrow .mono { color: var(--accent-ink); }
.hero-eyebrow .ix { color: var(--dim-2); margin-left: 4px; }

.hero h1.display {
  font-size: clamp(28px, 4vw, 60px);
  line-height: 1.0;
  letter-spacing: -.012em;
  margin-bottom: 22px;
}
.hero h1.display .l1,
.hero h1.display .l2 { display: block; }

.hero-sub {
  max-width: 520px;
  font-size: 17px;
  line-height: 1.5;
  color: var(--dim);
  margin-bottom: 28px;
}
.hero-sub strong { color: var(--text); font-weight: 500; }

.hero-ctas { display: flex; gap: 12px; }

.hero-still {
  position: relative;
  padding: 0;
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
  overflow: hidden;
}
.hero-still .still { aspect-ratio: 16 / 11; }
.hero-image {
  display: block;
  width: 100%;
  height: auto;
}

.hero-image.hero-print { position: relative; z-index: 1; }

/* ===================================================================
   HERO ENTRANCE ANIMATION  (ported from Solutions · Sports)
   Text — each line wipes in left→right, staggered top to bottom, with a
   layered per-word rise on the headline. Image — "prints" in left→right
   behind a glowing print-head bar that tracks the revealing edge.
   Auto-plays on load (animation-fill-mode: both holds the pre-state
   during the delay); fully disabled under reduced-motion.
   =================================================================== */
/* The settled state uses a NEGATIVE inset so it leaves room for glyph
   overshoot: the display faces' ink box is taller than their line box, so a
   settled `inset(0 0 0 0)` shaves the curve off the bottom of the big hero
   word (the flat-bottomed "S"). Only the right edge animates — the wipe.
   clip-path can't transition to `none`; `em` scales with the clamped sizes. */
@keyframes heroTextIn {
  from { clip-path: inset(-0.4em 100% -0.4em -0.4em); transform: translateX(-18px); }
  to   { clip-path: inset(-0.4em);                    transform: translateX(0); }
}
/* Layered word-rise on the headline — words fade up in sequence on top of
   the per-line wipe. Each line's words start at that line's wipe delay. */
@keyframes heroWordRise {
  from { opacity: 0; transform: translateY(0.5em); }
  to   { opacity: 1; transform: none; }
}
@keyframes heroPrintReveal {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}
@keyframes heroPrintBar {
  0%   { left: 0;    opacity: 0; }
  10%  { opacity: .55; }
  90%  { opacity: .55; }
  100% { left: 100%; opacity: 0; }
}

.hero-eyebrow,
.hero h1.display .l1,
.hero h1.display .l2,
.hero-sub,
.hero-ctas {
  animation: heroTextIn .7s cubic-bezier(.16,1,.3,1) both;
}
.hero-eyebrow         { animation-delay: .15s; }
.hero h1.display .l1  { animation-delay: .30s; }
.hero h1.display .l2  { animation-delay: .42s; }
.hero-sub             { animation-delay: .70s; }
.hero-ctas            { animation-delay: .84s; }

/* Headline words (split into .hw by platform.js; --i resets per line). */
.hero h1.display .hw {
  display: inline-block;
  animation: heroWordRise .6s cubic-bezier(.16,1,.3,1) both;
}
.hero h1.display .l1 .hw { animation-delay: calc(.30s + var(--i) * 70ms); }
.hero h1.display .l2 .hw { animation-delay: calc(.42s + var(--i) * 70ms); }

/* Image prints left→right, with a glowing print-head line tracking the edge. */
.hero-image.hero-print {
  animation: heroPrintReveal 1.5s cubic-bezier(.45,0,.12,1) .5s both;
}
.hero-still::after {
  content: "";
  position: absolute; top: 0; bottom: 0; left: 0;
  width: 1px;
  background: var(--accent);
  box-shadow: 0 0 7px 0 rgba(182,245,0,.35);
  opacity: 0;
  pointer-events: none;
  z-index: 2;
  animation: heroPrintBar 1.5s cubic-bezier(.45,0,.12,1) .5s both;
}

@media (prefers-reduced-motion: reduce) {
  .hero-eyebrow,
  .hero h1.display .l1,
  .hero h1.display .l2,
  .hero-sub,
  .hero-ctas,
  .hero-image.hero-print { animation: none; }
  .hero h1.display .hw { animation: none; }
  .hero-still::after { display: none; }
}

/* ===================================================================
   ARC PREVIEW
   =================================================================== */
.arc-preview {
  position: relative;
  padding: 8vh 0;
  text-align: center;
  overflow: hidden;
  border-top: 1px solid var(--hair);
  border-bottom: 1px solid var(--hair);
}
.arc-preview .bg-grid {
  position: absolute; inset: 0;
  background-image:
    linear-gradient(0deg, var(--hair) 1px, transparent 1px),
    linear-gradient(90deg, var(--hair) 1px, transparent 1px);
  background-size: 64px 64px;
  -webkit-mask-image: radial-gradient(ellipse at center, #000 26%, transparent 76%);
          mask-image: radial-gradient(ellipse at center, #000 26%, transparent 76%);
  opacity: .5;
  pointer-events: none;
}
.arc-preview .bg-bloom {
  position: absolute; inset: 0;
  background: radial-gradient(ellipse at center, rgba(182,245,0,.10) 0%, transparent 56%);
  pointer-events: none;
}
.arc-inner {
  position: relative; z-index: 1;
  max-width: var(--max);
  margin: 0 auto;
  padding: 0 min(5vw, 72px);
}
.arc-eyebrow {
  display: inline-flex; align-items: center; gap: 12px;
  color: var(--accent);
  margin-bottom: 22px;
}
.arc-title {
  font-family: 'Oswald', sans-serif;
  font-weight: 600;
  text-transform: uppercase;
  font-size: clamp(36px, 5.6vw, 84px);
  line-height: 1.06;
  letter-spacing: -.014em;
  text-align: center;
  color: var(--text);
}
.arc-title .line { display: block; }
.arc-title .line em { color: var(--text); }
.arc-title .line-wheel {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .3em;
  margin-top: .06em;
}
.arc-title .line-wheel .robots { display: inline-block; }

.arc-wheel {
  position: relative;
  display: inline-block;
  vertical-align: middle;
  height: 1.4em;
  line-height: 1;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 30%, #000 70%, transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0%, #000 30%, #000 70%, transparent 100%);
}
/* invisible sizer keeps the wheel as wide as the widest verb */
.arc-wheel-sizer {
  display: block;
  visibility: hidden;
  font: inherit;
  line-height: 1;
  white-space: nowrap;
  padding: 0 .04em;
}
.arc-wheel-track {
  position: absolute;
  left: 0; right: 0;
  top: 0;
  display: flex; flex-direction: column;
  align-items: center;
  /* initial: center verb 0 — wheel is 1.4em tall, verb is 1em, so .2em down */
  transform: translateY(.2em);
  transition: transform .22s var(--ease-out);
  will-change: transform;
}
.arc-verb {
  display: block;
  font: inherit;
  line-height: 1;
  height: 1em;
  white-space: nowrap;
  color: var(--dim-2);
  opacity: .25;
  transition: color .35s var(--ease), opacity .35s var(--ease), text-shadow .35s var(--ease);
}
.arc-verb.is-near    { opacity: .55; color: var(--dim); }
.arc-verb.is-active  {
  opacity: 1;
  color: var(--text);
  text-shadow: 0 0 22px rgba(182,245,0,.22);
}
.arc-verb.is-active.is-final {
  color: var(--accent);
  text-shadow: 0 0 26px rgba(182,245,0,.35);
}

/* ===================================================================
   SEQUENCE BAND
   =================================================================== */
.seq-band {
  position: relative;
  padding: 14vh 0;
  border-top: 1px solid var(--hair);
  overflow: hidden;
}
.seq-band:first-of-type { border-top: 0; }

/* paper-stack — sticky overlap so each verb section rises over the previous
   like a piece of paper sliding up to cover the one below. Applied only to
   the .seq-band verb sections (Collect, ITO, Distribute, Activate, Measure,
   Automate). The IQ Suite between stacks is a regular flow section. */
.paper-stack { position: relative; }
.paper-stack > .seq-band {
  position: sticky;
  top: 0;
  min-height: 100vh;
  background: var(--bg);
  border: 0;
  display: flex;
  align-items: center;
  box-shadow: 0 -16px 40px -28px rgba(0,0,0,.28);
}
.paper-stack > .seq-band.section-light {
  box-shadow: 0 -16px 40px -28px rgba(0,0,0,.10);
}
.paper-stack > .seq-band:first-of-type { box-shadow: none; }
.paper-stack > .seq-band > .seq-band-inner { width: 100%; }

@media (max-width: 960px) {
  .paper-stack > .seq-band {
    position: relative;
    min-height: 0;
    box-shadow: none;
    display: block;
  }
  .paper-stack > .seq-band:not(:first-of-type) { border-top: 1px solid var(--hair); }
}

.seq-band-inner {
  position: relative;
  max-width: var(--max);
  margin: 0 auto;
  padding: 0 min(5vw, 72px);
  display: grid;
  grid-template-columns: 1fr 1.05fr;
  gap: clamp(40px, 6vw, 96px);
  align-items: center;
}
.seq-band.flip .seq-band-inner { grid-template-columns: 1.05fr 1fr; }
.seq-band.flip .seq-copy  { order: 2; }
.seq-band.flip .seq-still { order: 1; }

/* drop-cap chapter numeral */
.seq-numeral {
  display: block;
  font-family: 'Oswald', sans-serif;
  font-weight: 600;
  font-size: clamp(72px, 8vw, 132px);
  line-height: 0.84;
  letter-spacing: -.022em;
  color: transparent;
  -webkit-text-stroke: 1px var(--hair-strong);
          text-stroke: 1px var(--hair-strong);
  margin-bottom: 22px;
  transition: -webkit-text-stroke-color .35s var(--ease), text-stroke-color .35s var(--ease), color .35s var(--ease);
  user-select: none;
}
.seq-numeral::after {
  content: '';
  display: block;
  width: 28px; height: 1px;
  background: var(--accent);
  margin-top: 14px;
}
.seq-band:hover .seq-numeral {
  -webkit-text-stroke-color: var(--accent);
          text-stroke-color: var(--accent);
}

.seq-copy { position: relative; z-index: 1; }
.seq-copy h2.display {
  font-size: clamp(48px, 6.8vw, 108px);
  letter-spacing: -.02em;
  line-height: 0.94;
  margin-bottom: 18px;
}
.seq-copy h2.display .stack { display: block; }
.seq-copy h2.display .stack + .stack { color: var(--dim); }
.seq-copy h2.display .stack + .stack + .stack { color: var(--dim-2); }
.seq-deck {
  display: block;
  font-family: 'Oswald', sans-serif;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: .04em;
  font-size: clamp(16px, 1.4vw, 20px);
  color: var(--dim);
  margin-bottom: 14px;
}
.seq-rule {
  display: block; width: 64px; height: 1px;
  background: var(--accent);
  margin: 18px 0 22px;
}
.seq-copy p {
  max-width: 520px;
  color: var(--dim);
  font-size: 17px;
  line-height: 1.5;
  margin-bottom: 16px;
}
.seq-copy p strong { color: var(--text); font-weight: 500; }
.seq-copy p em { color: var(--text); }

/* ===================================================================
   SEQ-BAND SCROLL REVEAL  (ported from Solutions · Sports)
   Each verb band's copy column + illustration WIPE in left→right (the same
   clip-path reveal as the hero) as the band scrolls in (.is-in added by
   platform.js, reveal-once). The band itself is sticky (paper-stack) — we
   wipe the INNER blocks, not the band, so the pin is never disturbed.
   Copy leads with a small slide; the illustration trails and uses a negative
   inset so its glows/shadows aren't cropped at the settled edge.
   =================================================================== */
.seq-band .seq-copy {
  transition: clip-path .9s cubic-bezier(.16,1,.3,1), transform .9s cubic-bezier(.16,1,.3,1);
}
.seq-band .seq-still {
  transition: clip-path 1.05s cubic-bezier(.16,1,.3,1);
}
.seq-band:not(.is-in) .seq-copy {
  clip-path: inset(0 100% 0 0);
  transform: translateX(-22px);
}
.seq-band:not(.is-in) .seq-still {
  clip-path: inset(-60px 100% -60px -60px);
}
.seq-band.is-in .seq-copy  { clip-path: inset(-24px); transform: translateX(0); }
.seq-band.is-in .seq-still { clip-path: inset(-60px); transition-delay: .15s; }

.deck-meta {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin-top: 22px;
}
.deck-meta .pill {
  display: inline-flex; align-items: center; gap: 8px;
  border: 1px solid var(--hair-strong);
  padding: 7px 12px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--dim);
}
.deck-meta .pill em { color: var(--text); font-weight: 500; }

.seq-still { position: relative; z-index: 1; }

/* scoreboard variant (Measure) ---------------------------------- */
.scoreboard {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  flex: 1;
}
.score-cell {
  position: relative;
  padding: 22px 22px 18px;
  border-right: 1px solid var(--hair);
  border-bottom: 1px solid var(--hair);
  display: flex; flex-direction: column; justify-content: space-between;
  min-height: 130px;
}
.score-cell:nth-child(2) { border-right: 0; }
.score-cell:nth-child(3),
.score-cell:nth-child(4) { border-bottom: 0; }
.score-cell:nth-child(4) { border-right: 0; }
.score-cell .sc-label { color: var(--dim-2); }
.score-cell .sc-num {
  font-family: 'Oswald', sans-serif;
  font-weight: 600;
  font-size: clamp(38px, 4.4vw, 60px);
  line-height: 1;
  letter-spacing: -.012em;
  color: var(--text);
  margin-top: 6px;
}
.score-cell .sc-delta { margin-top: 14px; color: var(--dim); }
.score-cell.is-accent .sc-num { color: var(--accent); }
.score-cell.is-accent .sc-delta { color: var(--accent); }
.score-cell.is-accent::before {
  content: '';
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 2px; background: var(--accent);
}

/* loop rosette (Automate) ------------------------------------- */
.loop-rosette {
  position: relative;
  width: 100%;
  max-width: 760px;
  margin: 0 auto;
  aspect-ratio: 1 / 1;
}
.rosette-svg {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  overflow: visible;
}

/* hex tiles — solid beige fill, white outline on all seven */
.rosette-hex {
  fill: #E4E4DC;
  stroke: #FFFFFF;
  stroke-width: 2;
  stroke-linejoin: miter;
}
.rosette-hex--center {
  fill: none;
  stroke: #FFFFFF;
  stroke-width: 2;
}

/* signal dots — colors set per-circle via inline fill attributes */
.rosette-signal--static { display: none; }
@media (prefers-reduced-motion: reduce) {
  .rosette-signal--motion { display: none; }
  .rosette-signal--static { display: block; }
}

/* HTML overlay */
.rosette-overlay {
  position: absolute; inset: 0;
  pointer-events: none;
}

.rosette-center-content {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center; justify-content: center;
  width: 22%;
}
/* render the logo file as a mask so its color is controlled by CSS,
   letting us use the section-light olive (#75932C) instead of the
   file's native lime. */
.rosette-center-content .rosette-mark {
  display: block;
  width: 100%;
  aspect-ratio: 290 / 58;
  background-color: #75932C;
  -webkit-mask: url('../images/platform/automate/greenfly-logo.svg') no-repeat center / contain;
          mask: url('../images/platform/automate/greenfly-logo.svg') no-repeat center / contain;
}

/* step label — sage number with verb stack underneath */
.rosette-step {
  position: absolute;
  transform: translate(-50%, -50%);
  width: 22%;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 12px;
  text-align: center;
}
.rosette-step .rosette-num {
  font-family: 'Oswald', sans-serif;
  font-weight: 600;
  font-size: clamp(20px, 2.2vw, 28px);
  line-height: 1;
  /* Was #B4CD6A — a pale lime that measured 1.52:1 on the cream this sits on,
     against the 3:1 large text needs. It was the last contrast failure on the
     site, six instances, one per step.
     --accent-ink is the token for accent-as-text on a light ground; inside
     this .section-light it resolves to green-900 #335614, 7.26:1. Using the
     token rather than the hex means it follows the palette if that decision
     ever moves.
     Clearing 3:1 was the requirement, but this clears 4.5:1 too, which
     matters here: the size is clamped down to 20px on narrow screens, below
     the 24px large-text cutoff, so a value that only cleared 3:1 would start
     failing on mobile. */
  color: var(--accent-ink);
  letter-spacing: -0.01em;
}
.rosette-step .rosette-verb {
  font-family: 'Oswald', sans-serif;
  font-weight: 600;
  font-size: clamp(10px, 0.95vw, 13px);
  letter-spacing: .18em;
  text-transform: uppercase;
  line-height: 1.02;
  color: #646461;
}
.rosette-step .rosette-verb + .rosette-verb { margin-top: 0; }

@media (max-width: 720px) {
  .loop-rosette { max-width: 100%; }
  .rosette-step { gap: 8px; }
  .rosette-step .rosette-num { font-size: 20px; }
  .rosette-step .rosette-verb { font-size: 10px; }
}

/* ===================================================================
   IQ SUITE
   =================================================================== */
.iq-suite {
  /* Gutter on the OUTER so the framed inners (header rule + card-grid border)
     align to the nav frame as a whole — putting padding on those bordered
     inners would leave their borders at the wider 1440 edge. Top divider
     stays full-bleed (border sits outside this padding). =5vw below 1440. */
  padding: 14vh max(5vw, calc((100vw - var(--max)) / 2 + 72px));
  border-top: 1px solid var(--hair);
}
.iq-header {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(40px, 6vw, 96px);
  align-items: end;
  padding-bottom: 32px;
  border-bottom: 1px solid var(--hair);
  margin-bottom: 56px;
  max-width: var(--max);
  margin-left: auto; margin-right: auto;
}
.iq-header .eyebrow {
  display: inline-flex; align-items: center; gap: 12px;
  margin-bottom: 18px;
  color: var(--accent-ink);
}
.iq-header h3.display {
  font-size: clamp(32px, 3.8vw, 52px);
  letter-spacing: -.014em;
}
.iq-header p {
  max-width: 540px;
  font-size: 17px;
  color: var(--dim);
  line-height: 1.5;
}
.iq-header p em { color: var(--text); }

.iq-grid {
  max-width: var(--max);
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0;
  border: 1px solid var(--hair);
}
.iq-card {
  display: flex;
  flex-direction: column;
  border-right: 1px solid var(--hair);
}
.iq-card:last-child { border-right: 0; }
.iq-specimen {
  position: relative;
  aspect-ratio: 4 / 3;
  border-bottom: 1px solid var(--hair);
  background: var(--bg-2);
  overflow: hidden;
}
.iq-specimen::before { display: none; }
.iq-bbox {
  position: absolute;
  left: 30%; top: 25%;
  width: 40%; height: 50%;
  border: 1px solid var(--accent);
  box-shadow: 0 0 0 4px rgba(182,245,0,.06);
  z-index: 2;
}
.iq-icon {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  z-index: 1;
}
/* Field-green hex callout, drawn as SVG so it stays crisp at any size and
   keeps a consistent stroke weight across breakpoints (matches Jazzy's
   intent from the baked-in versions but vector + responsive). */
.iq-hex-stroke {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  pointer-events: none;
  z-index: 2;
  overflow: visible;
}
.iq-hex-stroke path {
  fill: none;
  stroke: #B6F500;                /* Electric Green (brand anchor) — overrides section-light --accent */
  stroke-width: 4;
  stroke-linejoin: round;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

.iq-body {
  padding: 28px 28px 26px;
  display: flex; flex-direction: column;
}
.iq-name {
  font-family: 'Oswald', sans-serif;
  font-weight: 600;
  font-size: clamp(28px, 2.8vw, 40px);
  letter-spacing: -.012em;
  text-transform: uppercase;
  line-height: 1;
  margin-bottom: 16px;
}
.iq-name .iq-suffix { color: var(--accent); }
.iq-kicker {
  display: block;
  color: var(--dim-2);
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
  margin: -8px 0 14px;
}
.iq-card p {
  color: var(--dim);
  font-size: 16px;
  line-height: 1.5;
}
.iq-card p em { color: var(--text); }
.iq-meta {
  margin-top: auto;
  padding-top: 22px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
  border-top: 1px solid var(--hair);
}
.iq-meta .mc-k {
  display: block;
  color: var(--dim-2);
  margin-bottom: 4px;
}
.iq-meta .mc-v {
  display: block;
  font-family: 'Oswald', sans-serif;
  font-weight: 500;
  font-size: 16px;
  letter-spacing: -.006em;
  color: var(--text);
  text-transform: uppercase;
}

/* ===================================================================
   IQ-SUITE SCROLL REVEAL  (ported from Solutions · Sports)
   Header wipes in left→right, then the three IQ cards wipe in in sequence
   as the section scrolls in (.is-in added by platform.js, reveal-once).
   Cards use a negative inset so the green hex callouts that overflow the
   specimen aren't cropped at the settled edge. clip-path can't transition
   to/from `none`, so both the hidden and shown states are explicit insets.
   =================================================================== */
.iq-suite .iq-header {
  transition: clip-path .9s cubic-bezier(.16,1,.3,1), transform .9s cubic-bezier(.16,1,.3,1);
}
.iq-suite .iq-grid .iq-card {
  transition: clip-path .9s cubic-bezier(.16,1,.3,1);
}
.iq-suite .iq-grid .iq-card:nth-child(1) { transition-delay: .15s; }
.iq-suite .iq-grid .iq-card:nth-child(2) { transition-delay: .27s; }
.iq-suite .iq-grid .iq-card:nth-child(3) { transition-delay: .39s; }

.iq-suite:not(.is-in) .iq-header {
  clip-path: inset(0 100% 0 0);
  transform: translateX(-22px);
}
.iq-suite:not(.is-in) .iq-grid .iq-card {
  clip-path: inset(-40px 100% -40px -40px);
}
.iq-suite.is-in .iq-header  { clip-path: inset(-24px); transform: translateX(0); }
.iq-suite.is-in .iq-grid .iq-card { clip-path: inset(-40px); }

/* ===================================================================
   BUNDLES
   =================================================================== */
.bundles {
  padding: 14vh 0;
  border-top: 1px solid var(--hair);
}
.bundles-inner { max-width: var(--max); margin: 0 auto; padding: 0 min(5vw, 72px); }
.bundles-header {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(40px, 6vw, 96px);
  align-items: end;
  padding-bottom: 32px;
  border-bottom: 1px solid var(--hair);
  margin-bottom: 56px;
}
.bundles-header .eyebrow {
  display: inline-flex; align-items: center; gap: 12px;
  margin-bottom: 18px;
  color: var(--accent-ink);
}
.bundles-header h3.display {
  font-size: clamp(32px, 3.8vw, 52px);
  letter-spacing: -.014em;
}
.bundles-header p {
  max-width: 540px;
  font-size: 17px;
  color: var(--dim);
  line-height: 1.5;
}
.bundles-header p em { color: var(--text); }

.foundation {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 44px 44px 44px 48px;
  border: 1px solid var(--hair);
  border-left: 2px solid var(--accent);
  background: var(--bg-2);
  margin-bottom: 28px;
}
.foundation h4 {
  font-family: 'Oswald', sans-serif;
  font-weight: 600;
  font-size: clamp(22px, 1.8vw, 30px);
  letter-spacing: -.01em;
  text-transform: uppercase;
  margin-bottom: 12px;
}
.foundation p {
  color: var(--dim);
  font-size: 16px;
  line-height: 1.5;
}
.foundation p em { color: var(--text); }

.extensions {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
  margin-bottom: 64px;
}
.ext-card {
  position: relative;
  padding: 32px 28px 28px;
  border: 1px solid var(--hair);
  background: var(--bg-2);
  display: flex; flex-direction: column;
  transition: border-color .3s var(--ease), transform .3s var(--ease);
}
.ext-card:hover { border-color: var(--accent); transform: translateY(-2px); }
.ext-tag {
  display: inline-block;
  align-self: flex-start;
  padding: 4px 10px;
  margin-bottom: 18px;
  background: var(--accent);
  color: #0d0d0d;
  font-size: 10px;
  letter-spacing: .22em;
  font-weight: 600;
}
.ext-card h4 {
  font-family: 'Oswald', sans-serif;
  font-weight: 600;
  font-size: clamp(20px, 1.6vw, 28px);
  text-transform: uppercase;
  letter-spacing: -.008em;
  margin-bottom: 14px;
}
.ext-card p {
  color: var(--dim);
  font-size: 15px;
  line-height: 1.5;
}

.bundles-cta {
  display: flex; align-items: center; justify-content: center;
  gap: 24px;
}
.bundles-cta .bc-rule { flex: 1; height: 1px; background: var(--hair); max-width: 240px; }

/* ===================================================================
   BUNDLES SCROLL REVEAL  (ported from Solutions · Sports)
   Header → foundation → extension cards → CTA WIPE in left→right in sequence
   as the section scrolls in (.is-in added by platform.js, reveal-once).
   The reveal is pure `clip-path`, so it never touches the .ext-card:hover
   `transform` lift. Per-element delays live in the `transition` shorthand
   (on clip-path only), keeping the hover transition snappy.
   =================================================================== */
.bundles .bundles-header { transition: clip-path .9s cubic-bezier(.16,1,.3,1); }
.bundles .foundation     { transition: clip-path .9s cubic-bezier(.16,1,.3,1) .12s; }
.bundles .extensions .ext-card:nth-child(1) {
  transition: border-color .3s var(--ease), transform .3s var(--ease), clip-path .9s cubic-bezier(.16,1,.3,1) .24s;
}
.bundles .extensions .ext-card:nth-child(2) {
  transition: border-color .3s var(--ease), transform .3s var(--ease), clip-path .9s cubic-bezier(.16,1,.3,1) .34s;
}
.bundles .extensions .ext-card:nth-child(3) {
  transition: border-color .3s var(--ease), transform .3s var(--ease), clip-path .9s cubic-bezier(.16,1,.3,1) .44s;
}
.bundles .bundles-cta    { transition: clip-path .9s cubic-bezier(.16,1,.3,1) .54s; }

.bundles:not(.is-in) .bundles-header,
.bundles:not(.is-in) .foundation,
.bundles:not(.is-in) .extensions .ext-card,
.bundles:not(.is-in) .bundles-cta {
  clip-path: inset(0 100% 0 0);
}
/* Explicit revealed state — clip-path can't transition to/from `none`, so the
   shown state must be an inset() value for the wipe to animate. */
.bundles.is-in .bundles-header,
.bundles.is-in .foundation,
.bundles.is-in .extensions .ext-card,
.bundles.is-in .bundles-cta {
  clip-path: inset(-24px);
}

/* Reduced motion — show all revealed content immediately, no wipe. */
@media (prefers-reduced-motion: reduce) {
  .seq-band .seq-copy,
  .seq-band .seq-still,
  .iq-suite .iq-header,
  .iq-suite .iq-grid .iq-card,
  .bundles .bundles-header,
  .bundles .foundation,
  .bundles .extensions .ext-card,
  .bundles .bundles-cta {
    clip-path: none !important;
    transform: none !important;
    transition: none !important;
  }
}

/* ===================================================================
   CLOSING — homepage style
   =================================================================== */
.close {
  padding: 22vh 5vw 20vh;
  text-align: center;
  position: relative;
  overflow: hidden;
  border-top: 1px solid var(--hair);
}
.close::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at center, rgba(182,245,0,.06), transparent 60%);
  pointer-events: none;
}
.close-inner {
  position: relative;
  max-width: 1200px;
  margin: 0 auto;
}
.close-stack {
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: center;
}
.close-line {
  font-family: 'Oswald', sans-serif;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: -0.015em;
  font-size: clamp(40px, 6.6vw, 104px);
  line-height: 1;
  color: var(--dim);
  opacity: 0;
  transform: translateY(30px);
  transition: opacity .7s var(--ease-out), transform .7s var(--ease-out), color .5s var(--ease);
}
.close-line.reveal { opacity: 1; transform: translateY(0); }
.close-line.final {
  color: var(--text);
  margin-top: 28px;
}
.close-line.final .accent { color: var(--accent); }

.close-line.close-tagline {
  font-size: clamp(16px, 1.8vw, 22px);
  font-weight: 500;
  letter-spacing: .04em;
  color: var(--dim);
  margin-top: 24px;
}

.close-typing-line { color: var(--text); }
.typewriter {
  display: inline-block;
  white-space: nowrap;
}
.typewriter-word {
  color: var(--text);
  font-variant-ligatures: none;
}
.typewriter-caret {
  display: inline-block;
  width: .055em;
  height: .82em;
  margin-left: .06em;
  vertical-align: -0.06em;
  background: var(--accent);
  animation: typewriter-blink 1.05s steps(2, end) infinite;
}
@keyframes typewriter-blink {
  0%, 49%   { opacity: 1; }
  50%, 100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .typewriter-caret { animation: none; opacity: .6; }
}
.close-ctas {
  margin-top: 68px;
  display: flex;
  gap: 12px;
  justify-content: center;
  flex-wrap: wrap;
}

/* ===================================================================
   RESPONSIVE
   =================================================================== */
@media (max-width: 960px) {
  .hero-grid,
  .seq-band-inner,
  .iq-header,
  .bundles-header,
  .iq-card,
  .extensions,
  .iq-grid {
    grid-template-columns: 1fr;
  }
  .seq-band.flip .seq-copy  { order: 1; }
  .seq-band.flip .seq-still { order: 2; }
  /* The base `.seq-band.flip .seq-band-inner` 2-col rule (0,3,0) outranks the
     generic `.seq-band-inner { 1fr }` reflow above (0,1,0), so the flipped
     light bands stayed 2-up on mobile and squished their visual (the rosette).
     Restate the single-column reflow at matching specificity here. */
  .seq-band.flip .seq-band-inner { grid-template-columns: 1fr; }
  .hero-copy { border-right: 0; border-bottom: 1px solid var(--hair); }
  .iq-card { grid-template-columns: 1fr; }
  /* keep specimen at 4:3 at every breakpoint so the photo and the SVG hex
     crop identically — hex stays glued to the focal element on mobile too */
  .iq-specimen { border-right: 0; border-bottom: 1px solid var(--hair); }
  .foundation { padding: 32px; }
  .seq-numeral { font-size: clamp(56px, 12vw, 96px); }
}
@media (max-width: 720px) {
  .close { padding: 16vh 5vw 14vh; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0s !important;
    transition-duration: 0s !important;
  }
  html { scroll-behavior: auto; }
}
