/* ==========================================================================
   AI Video Studio — built on the Ecom Solutions system (shaka.tel's design language).
   Every value resolves to a token in tokens.css.
   ========================================================================== */

@import url("tokens.css");

/* --------------------------------------------------------------------------
   1. Base
   -------------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 96px;
}

/* shaka hides scrollbars entirely — the scroll is the interface. */
html, body { -ms-overflow-style: none; scrollbar-width: none; }
html::-webkit-scrollbar, body::-webkit-scrollbar { display: none; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  font-weight: var(--w-light);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img, svg { display: block; max-width: 100%; }

/* The coverflow and the story deck are drag surfaces. A plain <img> under a
   drag gesture lifts the browser's native ghost image — the logo visibly
   peels off the card instead of the card swiping. draggable="false" on the
   elements covers Firefox; this covers WebKit's separate drag mechanism. */
img, video, svg,
.plan, .feature, .deck__card, .stack__card, .console, .hero__object {
  -webkit-user-drag: none;
}
/* Card surfaces are also non-selectable, so a drag that starts on their
   text cannot turn into a text-selection drag either. Body copy elsewhere
   stays selectable. */
.plan, .feature, .deck__card, .stack__card, .console, .hero__object { user-select: none; }
h1, h2, h3, h4, h5, p, figure, ul, ol { margin: 0; }
ul, ol { padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; color: inherit; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}

::selection { background: var(--accent); color: var(--ground); }

/* Readable by assistive tech, never drawn. */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: var(--s-16);
  top: -100px;
  z-index: 200;
  background: var(--ink);
  color: var(--ground);
  padding: var(--s-12) var(--s-24);
  border-radius: var(--r-pill);
  font-weight: var(--w-medium);
  transition: top var(--d-micro) var(--e-out);
}
.skip-link:focus { top: var(--s-16); }

/* --------------------------------------------------------------------------
   2. Layout
   -------------------------------------------------------------------------- */

.shell {
  width: 100%;
  max-width: var(--wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--s-64); }
.section--tight { padding-block: var(--s-48); }
/* A single ruled band (the stats) is a strip, not a block: the standard 120px
   on each side, on top of its neighbours' 120px, left it adrift in 240px of
   empty ground above and below. */
.section--band  { padding-block: var(--s-40); }
/* …and the sections either side of it give up a third of theirs on the
   facing edge, so the strip sits about 100px from each neighbour's content
   instead of 160. */
.section:has(+ .section--band) { padding-bottom: var(--s-40); }
.section--band + .section       { padding-top: var(--s-40); }

.section-head {
  display: flex;
  flex-direction: column;
  gap: var(--s-20);
  max-width: var(--measure);
  margin-bottom: var(--s-40);
}
.section-head--c { align-items: center; text-align: center; margin-inline: auto; }

/* --------------------------------------------------------------------------
   3. Type
   -------------------------------------------------------------------------- */

.hero-type {
  font-size: var(--t-hero);
  line-height: var(--lh-hero);
  letter-spacing: var(--tr-hero);
  font-weight: var(--w-medium);
  text-wrap: balance;
}

.display {
  font-size: var(--t-display);
  line-height: var(--lh-display);
  letter-spacing: var(--tr-display);
  font-weight: var(--w-medium);
  text-wrap: balance;
}

.subheading {
  font-size: var(--t-subheading);
  line-height: var(--lh-subheading);
  letter-spacing: var(--tr-subheading);
  font-weight: var(--w-medium);
}

.title { font-size: var(--t-title); line-height: var(--lh-title); font-weight: var(--w-medium); }

.lede {
  font-size: var(--t-lede);
  line-height: var(--lh-lede);
  font-weight: var(--w-light);
  color: var(--ink-80);
  text-wrap: pretty;
}

.body   { font-size: var(--t-body); line-height: var(--lh-body); color: var(--ink-50); }
.small  { font-size: var(--t-small); line-height: var(--lh-small); color: var(--ink-35); }
.dim    { color: var(--ink-35); }

.eyebrow {
  font-size: var(--t-body);
  line-height: var(--lh-body);
  font-weight: var(--w-regular);
  color: var(--ink-muted);
}

.grad-text {
  background: var(--grad-primary);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* --------------------------------------------------------------------------
   4. Buttons — pills, flat fills, no shadow
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-8);
  padding: var(--s-12) var(--s-32);
  border: 0;
  border-radius: var(--r-button);
  font-size: var(--t-body);
  font-weight: var(--w-regular);
  line-height: 1.5;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color var(--d-micro) var(--e-out),
              color var(--d-micro) var(--e-out),
              transform var(--d-micro) var(--e-out),
              opacity var(--d-micro) var(--e-out);
}
.btn:hover { transform: translateY(-1px); }

.btn--primary { background: var(--accent); color: var(--ground); }
.btn--primary:hover { background: var(--accent-hover); }

.btn--quiet {
  background: var(--ink-10);
  color: var(--ink);
}
.btn--quiet:hover { background: var(--ink-15); }

.btn--line {
  background: transparent;
  color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--ink-19);
}
.btn--line:hover { background: var(--ink-10); }

.btn--onlight { background: var(--ground); color: var(--ink); }
.btn--onlight:hover { background: #262626; }

.btn--lg { padding: var(--s-16) var(--s-40); font-size: var(--t-lede); }
.btn--block { width: 100%; }

/* --------------------------------------------------------------------------
   5. Header
   -------------------------------------------------------------------------- */

.masthead {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(13, 13, 13, 0.8);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  transition: background-color 0.3s var(--e-out);
}

.masthead__inner {
  display: flex;
  align-items: center;
  gap: var(--s-24);
  height: 76px;
}

.logo { display: inline-flex; align-items: center; flex-shrink: 0; }

/* Official artwork. The guide sets a 100px minimum for the full lockup;
   these render at 132px and 116px wide. */
.logo img { width: 132px; height: auto; }

/* Typographic wordmark until a real logo exists: a live REC dot and the
   name, with "Studio" dropped a weight so the line reads as two words. */
.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 19px;
  line-height: 1;
  font-weight: var(--w-medium);
  letter-spacing: -0.3px;
  color: var(--ink);
  white-space: nowrap;
}
.wordmark__rec {
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 4px rgba(255, 90, 60, .18);
  animation: rec-blink 2.4s ease-in-out infinite;
}
.wordmark__dim { font-weight: var(--w-light); color: var(--ink-80); }
@keyframes rec-blink { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) { .wordmark__rec { animation: none; } }
/* At phone width the header holds wordmark, CTA and menu button in ~358px;
   the wordmark gives way so the CTA label never runs into its arrow. */
@media (max-width: 480px) {
  .masthead .wordmark { font-size: 16px; gap: 8px; letter-spacing: -0.4px; }
  .masthead .wordmark__rec { width: 8px; height: 8px; box-shadow: 0 0 0 3px rgba(255, 90, 60, .18); }
  .masthead__actions > .btn { flex-shrink: 0; white-space: nowrap; }
}
.footer .logo img { width: 116px; }

.masthead__nav {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  margin-left: auto;
}

.navlink {
  padding: var(--s-8) var(--s-16);
  border-radius: var(--r-button);
  font-size: var(--t-body);
  font-weight: var(--w-light);
  color: var(--ink-50);
  white-space: nowrap;
  transition: color var(--d-micro) var(--e-out), background-color var(--d-micro) var(--e-out);
}
.navlink:hover { color: var(--ink); background: var(--ink-10); }

.masthead__actions { display: flex; align-items: center; gap: var(--s-8); }
.masthead__nav > .btn { display: none; }

.nav-toggle {
  display: none;
  background: transparent;
  border: 0;
  box-shadow: inset 0 0 0 1px var(--ink-19);
  border-radius: var(--r-button);
  padding: var(--s-8) var(--s-12);
  cursor: pointer;
  color: var(--ink);
}

/* --------------------------------------------------------------------------
   6. Hero
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  padding-block: var(--s-120) var(--s-48);
  overflow: hidden;
}

/* A single soft bloom of the accent ramp behind the headline. */
.hero::before {
  content: "";
  position: absolute;
  top: -30%;
  left: 62%;
  width: min(1000px, 110vw);
  aspect-ratio: 1.35;
  transform: translateX(-50%);
  background: radial-gradient(ellipse at 50% 50%, rgba(255, 90, 60, 0.22) 0%, transparent 65%),
              radial-gradient(ellipse at 58% 62%, rgba(43, 15, 10, 0.4) 0%, transparent 68%);
  filter: blur(10px);
  pointer-events: none;
}

/* Two columns: the copy was filling barely half the rail, leaving a dead
   zone on the right that the background bloom could not carry on its own. */
.hero__inner {
  position: relative;
  display: grid;
  grid-template-columns: 1.02fr 0.98fr;
  gap: var(--s-64);
  align-items: center;
}
/* Grid items default to min-width:auto; keep the guard so no future
   max-content child can force this column wide and push the visual off. */
.hero__inner > * { min-width: 0; }
.hero__text { display: flex; flex-direction: column; gap: var(--s-24); min-width: 0; }
.hero .lede { max-width: 34rem; }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--s-12); }

/* ---- hero visual ---- */
.hero__visual { position: relative; display: flex; justify-content: center; }

/* Bloom behind the object. On the wrapper rather than the image: the image
   is animated (a stacking context), so its own pseudo-element would paint
   above its pixels, not behind them. */
.hero__visual::before {
  content: "";
  position: absolute;
  inset: 4% 0 6%;
  border-radius: 50%;
  background: radial-gradient(50% 50% at 50% 52%, rgba(255, 90, 60, .5) 0%, transparent 72%);
  filter: blur(52px);
  pointer-events: none;
}

/* The hero object: a clay storefront cut out on alpha, floating on the
   bloom. It replaced a schematic "store card" — a UI mock beside a headline
   is the most templated hero there is, and the promise cards had already
   set the page's language as soft clay objects in brand blue. */
.hero__object {
  position: relative;
  width: min(100%, 540px);
  animation: hero-bob 9s ease-in-out infinite;
}
.hero__still {
  display: block;
  width: 100%;
  height: auto;
  filter: drop-shadow(0 44px 64px rgba(0, 0, 0, .58));
}
/* The loop sits exactly over the still and carries its own alpha. (A
   screen-blend on a black-ground clip was tried first: every ancestor with
   a transform is a stacking context, so the blend never reached the page
   ground and the clip showed as a box.) */
.hero__loop {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  pointer-events: none;
}
.hero__loop:not([data-playing]) { opacity: 0; }
.hero__loop[data-playing] { opacity: 1; transition: opacity .6s var(--e-out); }

/* Once the loop plays, the still goes — the two are framed a touch
   differently and screening one over the other double-exposes the shop.
   The still's drop shadow goes with it, so the wrapper paints a soft pool
   of shadow under the object instead. */
/* The shadow pool is painted first and the still and loop sit above it,
   so no negative z-index (and no isolation) is needed. */
.hero__object::before {
  content: "";
  position: absolute;
  left: 12%; right: 12%; bottom: 2%;
  height: 18%;
  border-radius: 50%;
  background: radial-gradient(50% 50% at 50% 50%, rgba(0, 0, 0, .6) 0%, transparent 72%);
  filter: blur(14px);
  opacity: 0;
  transition: opacity .6s var(--e-out);
  pointer-events: none;
}
.hero__still { position: relative; z-index: 1; }
.hero__loop { z-index: 2; }
.hero__object:has(.hero__loop[data-playing]) .hero__still { opacity: 0; transition: opacity .6s var(--e-out); }
.hero__object:has(.hero__loop[data-playing])::before { opacity: 1; }

/* Proof floats around the object at different depths: the checklist low-left
   on a slight tilt, the hours chip low-right leaning the other way. Each
   drifts on its own phase so the three read as separate things in space. */
.hero__proof {
  position: absolute;
  left: -4px;
  bottom: 10px;
  display: flex;
  flex-direction: column;
  gap: var(--s-8);
  padding: var(--s-12) var(--s-16);
  border-radius: 16px;
  background: var(--surface-2);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .07), 0 22px 44px rgba(0, 0, 0, .5);
  animation: hero-drift 9s ease-in-out -3s infinite;
}
.hero__proof-row {
  display: flex; align-items: center; gap: var(--s-12);
  font-size: var(--t-small); color: var(--ink-80); white-space: nowrap;
}
.hero__proof-row i {
  width: 16px; height: 16px; border-radius: 4px;
  background: var(--accent); color: #fff;
  display: grid; place-items: center; flex-shrink: 0;
}

@keyframes hero-bob    { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-12px); } }
@keyframes hero-drift  { 0%, 100% { transform: rotate(-1.5deg) translateY(0) } 50% { transform: rotate(-1.5deg) translateY(-9px) } }
@keyframes hero-drift2 { 0%, 100% { transform: rotate(2deg)    translateY(0) } 50% { transform: rotate(2deg)    translateY(7px) } }

.hero__float {
  position: absolute;
  right: -6px;
  bottom: 26px;
  background: var(--surface-3);
  border-radius: 16px;
  padding: var(--s-12) var(--s-16);
  display: flex; align-items: center; gap: var(--s-12);
  box-shadow: 0 18px 40px rgba(0, 0, 0, .45);
  animation: hero-drift2 9s ease-in-out infinite;
}
.hero__float b { font-size: var(--t-title); font-weight: var(--w-medium); }
.hero__float span { font-size: 12px; color: var(--ink-35); display: block; }

/* --------------------------------------------------------------------------
   7. Service coverflow
   -------------------------------------------------------------------------- */

/* Cards fan well past the viewport edge; clip rather than hide so the
   stage keeps its 3D rendering context. */
.coverflow {
  --card-w: 356px;
  margin-top: var(--s-16);
  overflow-x: clip;
  /* Full-bleed out of the container so the fan has room to spread. */
  width: 100vw;
  margin-inline: calc(50% - 50vw);
}

@media (min-width: 1400px) { .coverflow { --card-w: 412px; } }
@media (min-width: 1800px) { .coverflow { --card-w: 448px; } }

.coverflow__stage {
  position: relative;
  height: 592px;
  perspective: 1800px;
  perspective-origin: 50% 46%;
  touch-action: pan-y;
  cursor: grab;
  user-select: none;
}
.coverflow__stage.is-dragging { cursor: grabbing; }

.plan {
  position: absolute;
  top: 50%;
  left: 50%;
  width: var(--card-w);
  height: 560px;
  margin: -280px 0 0 calc(var(--card-w) / -2);
  display: flex;
  flex-direction: column;
  gap: var(--s-20);
  padding: var(--s-20);
  background: var(--surface-2);
  border-radius: var(--r-panel);
  transform-style: preserve-3d;
  transition: none;
  will-change: transform;
}

/* Corner pins, straight from the Jadore card */
.plan::before, .plan::after,
.plan .pin-l, .plan .pin-r {
  content: "";
  position: absolute;
  width: 4px; height: 4px;
  border-radius: 1px;
  background: var(--ink-19);
}
.plan::before { top: 13px; left: 13px; }
.plan::after  { top: 13px; right: 13px; }
.plan .pin-l  { bottom: 13px; left: 13px; }
.plan .pin-r  { bottom: 13px; right: 13px; }

.plan__art {
  position: relative;
  border-radius: var(--r-card);
  /* 1.4 was sized for a lockup and a prompt. With the mark plate between
     them the prompt was pushed past the bottom edge on five of six cards. */
  aspect-ratio: 1.18;
  padding: var(--s-16);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  overflow: hidden;
}

/* .plan__art is space-between with a lockup at the top and a prompt at the
   bottom, so every card had a hole through the middle — one card carried a
   bespoke SVG illustration and the other five carried nothing at all. The
   plate fills that hole with the one thing a service card has to say at a
   glance: which marketplace this is. Real marks, cropped from the client's
   own logo sheet and counter-rotated to level. */
/* The face is a soft-3D render of the service's own claim (a parcel through
   an open gate for dropshipping, a stocked rack for FBA, an approval gate for
   WFS…), generated on each card's ground colour with the upper-left left
   empty on purpose — that corner is where the real marketplace mark sits.
   The lockup and prompt stay as they were, painted straight on the render. */
.plan__face-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}
.plan__mark {
  position: absolute;
  left: var(--s-16);
  top: 14px;
  width: 33%;
  height: auto;
  z-index: 1;
}
/* Meta's mark is a 5:1 wordmark; matched on width it renders a third of the
   pills' height, so it gets more room. */
.plan[data-i="5"] .plan__mark { width: 44%; top: 18px; }




.plan__prompt { position: relative; display: flex; align-items: flex-end; justify-content: space-between; gap: var(--s-12); color: var(--plan-ink, #fff); }
.plan__prompt > span { min-width: 0; }
.plan__prompt b { display: block; font-size: var(--t-body); font-weight: var(--w-medium); line-height: 1.3; }
.plan__prompt span span { font-size: 13px; line-height: 1.3; display: block; opacity: 0.75; }

.plan__arrow {
  flex-shrink: 0;
  width: 40px; height: 40px;
  border-radius: var(--r-sm);
  background: var(--plan-ink, #fff);
  color: var(--plan-ink-inv, #0d0d0d);
  display: grid;
  place-items: center;
  transition: transform var(--d-micro) var(--e-out);
}
.plan:hover .plan__arrow { transform: translate(2px, -2px); }

.plan__body { display: flex; flex-direction: column; gap: var(--s-12); flex: 1; }
.plan__title { font-size: var(--t-heading); line-height: 1.15; letter-spacing: -0.5px; font-weight: var(--w-medium); }
.plan__desc {
  font-size: var(--t-body);
  color: var(--ink-50);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 4;
  line-clamp: 4;
  overflow: hidden;
}

.plan__action {
  align-self: flex-end;
  margin-top: auto;
  border: 0;
  border-radius: var(--r-pill);
  padding: var(--s-12) var(--s-24);
  font-size: var(--t-body);
  font-weight: var(--w-regular);
  color: var(--ground);
  background: var(--plan-accent, var(--accent-tint-2));
  cursor: pointer;
  transition: filter var(--d-micro) var(--e-out), transform var(--d-micro) var(--e-out);
}
.plan__action:hover { filter: brightness(1.08); transform: translateY(-1px); }

.plan[aria-hidden="true"] { pointer-events: none; }
.plan:not(.is-active) .plan__action { pointer-events: none; }

.coverflow__controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-24);
  margin-top: var(--s-40);
}

.cf-btn {
  width: 40px; height: 40px;
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--ink-35);
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: color var(--d-micro) var(--e-out), background-color var(--d-micro) var(--e-out);
}
.cf-btn:hover { color: var(--ink); background: var(--ink-10); }
.cf-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.cf-dots { display: flex; gap: var(--s-8); }
.cf-dot {
  width: 6px; height: 6px;
  padding: 0; border: 0;
  border-radius: var(--r-pill);
  background: var(--ink-19);
  cursor: pointer;
  transition: background var(--d-micro) var(--e-out), width var(--d-micro) var(--e-out);
}
.cf-dot[aria-current="true"] { background: var(--accent); width: 22px; }

/* Announced to assistive tech on change; never drawn. */
.cf-status {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.phase--flip .phase__text  { order: 2; }

.phase__text { display: flex; flex-direction: column; gap: var(--s-24); }

.tag {
  font-size: var(--t-small);
  padding: 2px var(--s-12);
  border-radius: var(--r-pill);
  background: var(--ink-10);
  color: var(--ink-50);
  white-space: nowrap;
}

.bar { height: 6px; border-radius: var(--r-pill); background: var(--ink-10); overflow: hidden; }
.bar span { display: block; height: 100%; border-radius: inherit; background: var(--grad-primary); }
.chart i.on { background: var(--grad-primary); }

/* --------------------------------------------------------------------------
   9. Cards, grids, lists
   -------------------------------------------------------------------------- */

.grid { display: grid; gap: var(--s-20); }
.grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.card {
  background: var(--surface-2);
  border-radius: var(--r-panel);
  padding: var(--s-24);
  display: flex;
  flex-direction: column;
  gap: var(--s-16);
  transition: background-color var(--d-micro) var(--e-out);
}
.card:hover { background: var(--surface-3); }

.ticks { display: flex; flex-direction: column; gap: var(--s-16); }

/* Seven items read better as two columns than one long run. */
.tick { display: grid; grid-template-columns: 20px 1fr; gap: var(--s-16); align-items: start; color: var(--ink-50); }
.tick svg { color: var(--accent); margin-top: 3px; }
.tick b { color: var(--ink); font-weight: var(--w-medium); }

/* The handle split. Same construction as the FAQ further down — heading
   holds a sticky left rail while the seven duties run past it as a ledger.
   The previous treatment was the seven duties as a two-column tick grid:
   at 14px with an orphaned last row it read as a footnote to its own
   heading rather than the substance of the section. */
.handle-layout {
  display: grid;
  grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
  gap: var(--s-48) var(--s-80);
  align-items: start;
}
.handle-layout__head {
  margin-bottom: 0;
  max-width: none;
  position: sticky;
  top: 120px;
}
@media (max-width: 900px) {
  .handle-layout { grid-template-columns: 1fr; }
  .handle-layout__head { position: static; max-width: var(--measure); }
}

/* Numbered list, shaka's "01." grey numerals */
.numlist { display: flex; flex-direction: column; }
.numlist li {
  display: grid;
  grid-template-columns: 56px 1fr;
  gap: var(--s-16);
  padding-block: var(--s-24);
  border-top: 1px solid var(--ink-10);
}
.numlist li:last-child { border-bottom: 1px solid var(--ink-10); }
.numlist .n { color: var(--ink-muted); }

/* Stats */
/* Milestone band. A label rail on the left, the figures pushed right across
   the remaining span, hairlines top and bottom. Rules rather than a panel:
   the story deck immediately below is already a --surface-1 slab, and two
   stacked slabs read as one heavy block. */
.stats {
  display: grid;
  grid-template-columns: minmax(0, 3fr) minmax(0, 9fr);
  gap: var(--s-32) var(--s-64);
  align-items: start;
  padding-block: var(--s-40);
  border-top: 1px solid var(--ink-10);
  border-bottom: 1px solid var(--ink-10);
}

.stats__head { display: flex; flex-direction: column; gap: var(--s-16); justify-content: center; min-height: 100%; }

.stats__title {
  font-size: clamp(20px, 2vw, 26px);
  line-height: 1.2;
  font-weight: var(--w-medium);
  letter-spacing: -0.01em;
  text-wrap: balance;
}

.stats__row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s-32);
}

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

.stat__n {
  font-size: clamp(2.75rem, 6vw, 76px);
  line-height: .95;
  font-weight: var(--w-regular);
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}

/* The one spot of brand colour in the band. Raised as a true superscript
   rather than set inline, so the digits keep a common baseline across the
   row and the eye reads the numbers, not the qualifiers. */
.stat__sym {
  font-size: .44em;
  line-height: 1;
  font-weight: var(--w-medium);
  vertical-align: super;
  margin-left: .03em;
  color: var(--accent);
}

.stat__l { font-size: var(--t-body); color: var(--ink-50); }

@media (max-width: 900px) {
  .stats { grid-template-columns: 1fr; gap: var(--s-40); padding-block: var(--s-40); }
}
@media (max-width: 560px) {
  .stats__row { grid-template-columns: 1fr; gap: var(--s-24); }
}
.slot__tag {
  align-self: flex-start;
  font-size: var(--t-small);
  padding: 2px var(--s-12);
  border-radius: var(--r-pill);
  background: var(--ink-10);
  color: var(--ink-50);
}

/* --------------------------------------------------------------------------
   10. FAQ
   -------------------------------------------------------------------------- */

/* A single 720px column centred in a 1440px rail leaves half the screen empty
   on a wide display. Split it instead: the heading holds a left rail and
   sticks while the questions scroll past it, so both halves stay occupied.
   The answer text keeps its own reading measure inside the wider column. */
.faq-layout {
  display: grid;
  grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
  gap: var(--s-48) var(--s-80);
  align-items: start;
}

/* No max-width here: the 4fr track is already the measure, and a ch value
   would resolve against this element's font-size, not the heading's. */
.faq-layout__head {
  margin-bottom: 0;
  max-width: none;
  position: sticky;
  top: 120px;
}

.faq {
  display: flex;
  flex-direction: column;
}

.faq__item { border-top: 1px solid var(--ink-10); }
.faq__item:last-child { border-bottom: 1px solid var(--ink-10); }

.faq__item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-24);
  padding-block: var(--s-24);
  cursor: pointer;
  font-size: var(--t-subheading);
  font-weight: var(--w-medium);
  letter-spacing: var(--tr-subheading);
  list-style: none;
}
.faq__item summary::-webkit-details-marker { display: none; }
.faq__item summary:hover { color: var(--ink-80); }

.faq__sign {
  flex-shrink: 0;
  width: 28px; height: 28px;
  display: grid;
  place-items: center;
  color: var(--accent);
  transition: transform var(--d-micro) var(--e-out);
}
.faq__item[open] .faq__sign { transform: rotate(45deg); }
.faq__a { padding-bottom: var(--s-24); color: var(--ink-50); max-width: var(--measure); }

@media (max-width: 900px) {
  .faq-layout { grid-template-columns: 1fr; }
  .faq-layout__head { position: static; max-width: var(--measure); }
}

/* --------------------------------------------------------------------------
   11. Gradient CTA — the page's one bright moment, inverse of the ground
   -------------------------------------------------------------------------- */

/* The flat version ran #ffb8a6 -> #ff5a3c -> #d93d1f: three values with almost
   no tonal travel, so it read as a printed swatch. Depth here comes from a
   single implied light source — highlight top-left, shadow pooling bottom-right
   — over a gradient with real range from bright blue down into navy. */
.cta {
  border-radius: 28px;
  color: #fff;
  padding: var(--s-80) var(--s-48);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-24);
  overflow: hidden;
  position: relative;
  isolation: isolate;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 620' preserveAspectRatio='none'%3E%3Cpath d='M0,150 C240,60 420,250 720,205 C1020,160 1230,40 1440,120 L1440,300 C1230,230 1020,350 720,395 C420,440 240,250 0,340 Z' fill='%23ffffff' opacity='.07'/%3E%3Cpath d='M0,235 C260,340 480,120 760,175 C1040,230 1250,330 1440,255 L1440,430 C1250,505 1040,405 760,350 C480,295 260,515 0,410 Z' fill='%23cfdcff' opacity='.09'/%3E%3Cpath d='M0,95 C200,175 430,45 700,110 C970,175 1200,215 1440,160 L1440,235 C1200,290 970,250 700,185 C430,120 200,250 0,170 Z' fill='%23ffffff' opacity='.11'/%3E%3C/svg%3E") no-repeat top center / 100% 58%,
    radial-gradient(70% 90% at 10% 4%,   rgba(255,255,255,.14) 0%, transparent 46%),
    radial-gradient(85% 115% at 90% 100%, rgba(30, 6, 2,.72)    0%, transparent 62%),
    linear-gradient(135deg, #e0492d 0%, #b8321a 34%, #6e200f 68%, #2a0c06 100%);
  /* Lit top edge — the detail that separates a panel from a rectangle. */
  box-shadow: inset 0 1px 0 rgba(255,255,255,.34);
}

/* Fine grain, so the large flat area has tooth instead of banding. */
.cta::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: .16;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

.cta > * { position: relative; z-index: 1; }
.cta .display { text-wrap: balance; max-width: 20ch; }
.cta .lede { color: rgba(255, 255, 255, 0.86); max-width: 38rem; }
.cta__actions { display: flex; flex-wrap: wrap; gap: var(--s-12); justify-content: center; }
.cta .avatars i { background: rgba(13,13,13,0.14); box-shadow: 0 0 0 2px var(--accent-tint-2); }

/* --------------------------------------------------------------------------
   12. Forms
   -------------------------------------------------------------------------- */

.form { display: flex; flex-direction: column; gap: var(--s-40); }
.field { display: flex; flex-direction: column; gap: var(--s-8); }
.field__l { font-size: var(--t-body); color: var(--ink-80); }
.field__h { font-size: var(--t-small); color: var(--ink-35); }

.input {
  width: 100%;
  background: var(--surface-2);
  border: 0;
  box-shadow: inset 0 0 0 1px var(--ink-15);
  border-radius: var(--r-pill);
  padding: var(--s-16) var(--s-24);
  font-size: var(--t-body);
  font-weight: var(--w-light);
  color: var(--ink);
  transition: box-shadow var(--d-micro) var(--e-out);
}
.input::placeholder { color: var(--ink-35); }
.input:focus { outline: none; box-shadow: inset 0 0 0 1px var(--accent); }
textarea.input { border-radius: var(--r-panel); resize: vertical; }
select.input { appearance: none; cursor: pointer; }
select.input option { background: var(--surface-2); color: var(--ink); }

.field__err {
  font-size: var(--t-small);
  color: var(--ink);
  margin-top: var(--s-4);
}
.input[aria-invalid="true"] { box-shadow: inset 0 0 0 1px var(--ink-50); }

.fieldset { border: 0; padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--s-16); }
.fieldset__legend {
  padding: 0;
  font-size: var(--t-subheading);
  font-weight: var(--w-medium);
  letter-spacing: var(--tr-subheading);
}

.opts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-12); }
.opt {
  display: flex;
  align-items: center;
  gap: var(--s-12);
  padding: var(--s-16) var(--s-24);
  border-radius: var(--r-pill);
  background: var(--surface-2);
  box-shadow: inset 0 0 0 1px var(--ink-15);
  cursor: pointer;
  transition: background-color var(--d-micro) var(--e-out), box-shadow var(--d-micro) var(--e-out);
}
.opt:hover { background: var(--surface-3); }
.opt input { accent-color: var(--accent); width: 18px; height: 18px; flex-shrink: 0; cursor: pointer; }
.opt:has(input:checked) { box-shadow: inset 0 0 0 1px var(--accent); background: var(--surface-3); }
.opt:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.opt--wide { border-radius: var(--r-panel); align-items: flex-start; }

.row2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-20); }

.form-layout { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: var(--s-64); align-items: start; }
.form-aside { position: sticky; top: 100px; display: flex; flex-direction: column; gap: var(--s-20); }

/* --------------------------------------------------------------------------
   13. Footer
   -------------------------------------------------------------------------- */

/* The footer sat on the page's own ground, divided by a single hairline —
   the one place still using the device removed everywhere else in the audit.
   It now reads as a raised plate: its own surface, a soft scrim where the
   page meets it, and no line at all. */
.footer {
  position: relative;
  background: var(--surface-1);
  padding-block: var(--s-64) var(--s-32);
  margin-top: var(--s-48);
}

/* Gradual crossing rather than an edge. Sits above the footer, fading the
   page ground down into it. */
.footer::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -120px;
  height: 120px;
  pointer-events: none;
  background: linear-gradient(180deg, var(--ground) 0%, var(--surface-1) 100%);
}

/* A single lit edge where the plate catches light, same logic as the CTA. */
.footer::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 1px;
  background: linear-gradient(90deg,
    transparent 0%,
    rgba(255,255,255,.10) 22%,
    rgba(255, 90, 60,.28) 50%,
    rgba(255,255,255,.10) 78%,
    transparent 100%);
}
.footer__grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr 1.2fr; gap: var(--s-40); }
.footer__col { display: flex; flex-direction: column; gap: var(--s-16); }
.footer__h { font-size: var(--t-body); font-weight: var(--w-medium); }
.footer__links { display: flex; flex-direction: column; gap: var(--s-8); }
.footer__links a {
  font-size: var(--t-body);
  color: var(--ink-50);
  width: fit-content;
  transition: color var(--d-micro) var(--e-out);
}
.footer__links a:hover { color: var(--ink); }

.footer__bottom {
  margin-top: var(--s-48);
  padding-top: var(--s-24);
  border-top: 1px solid var(--ink-10);
  display: flex; flex-wrap: wrap; gap: var(--s-16);
  align-items: center; justify-content: center;
  text-align: center;
  font-size: var(--t-small);
  color: var(--ink-35);
}

.social { display: flex; gap: var(--s-8); }
.social a {
  width: 38px; height: 38px;
  border-radius: var(--r-sm);
  background: var(--ink-10);
  display: grid; place-items: center;
  color: var(--ink-50);
  transition: background-color var(--d-micro) var(--e-out), color var(--d-micro) var(--e-out);
}
.social a:hover { background: var(--ink-15); color: var(--ink); }

/* --------------------------------------------------------------------------
   14. Motion — shaka's vocabulary, reproduced with IntersectionObserver
   -------------------------------------------------------------------------- */

/* The signature entrance: rise from below while un-tilting on X. */
@keyframes rise {
  from { opacity: 0; transform: translateY(60%) perspective(50vw) rotateX(50deg); }
  to   { opacity: 1; transform: translateY(0) perspective(50vw) rotateX(0deg); }
}

/* Masked line reveal — words slide up inside an overflow-hidden line box. */
@keyframes word-up {
  from { transform: translateY(110%); }
  to   { transform: translateY(0); }
}

@keyframes fade-up {
  from { opacity: 0; transform: translateY(28px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes pop {
  from { opacity: 0; transform: scale(0.8) translateY(20%); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}

@keyframes scale-in {
  from { transform: scale(0); }
  to   { transform: scale(1); }
}

/* Idle state — set before the observer fires */
.js [data-anim] { opacity: 0; }
[data-anim].in { opacity: 1; }

[data-anim="rise"].in    { animation: rise var(--d-enter) var(--e-out) both; }
[data-anim="fade"].in    { animation: fade-up var(--d-text) var(--e-out) both; }
[data-anim="pop"].in     { animation: pop 0.6s var(--e-in) both; }
[data-anim="scale"].in   { animation: scale-in 0.8s var(--e-out) both; }

/* Split headline: each word gets its own masked line */
.split-line { display: block; overflow: hidden; }
.split-word { display: inline-block; transform: translateY(110%); }
.js [data-anim="split"] { opacity: 1; }
[data-anim="split"].in .split-word { animation: word-up var(--d-text) var(--e-out) both; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .feature { opacity: 1; transform: none; animation: none; }
  a.feature:hover .feature__img { transform: none; }
  .hero__object { animation: none; }
  .hero__loop { display: none; }
  .hero__proof { animation: none; transform: rotate(-1.5deg); }
  .hero__float { animation: none; transform: rotate(2deg); }
  [data-anim], [data-anim].in { opacity: 1 !important; animation: none !important; }
  .split-word { transform: none !important; animation: none !important; }
  .plan { transition: none; }
  .btn:hover { transform: none; }
}

/* --------------------------------------------------------------------------
   15. Responsive
   -------------------------------------------------------------------------- */

@media (max-width: 1000px) {
  .grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .phase--flip .phase__text, .phase--flip .phase__media { order: 0; }
  .form-layout { grid-template-columns: 1fr; gap: var(--s-40); }
  .form-aside { position: static; }
  .footer__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-32); }
  .footer__col:first-child { grid-column: 1 / -1; }
}

@media (max-width: 940px) {
  .masthead__nav { display: none; }
  .nav-toggle { display: inline-flex; margin-left: auto; }
  /* Kept visible: hiding it left ~75% of the page scroll with no CTA at all,
     and stripped apply.html's only labelled way out. Compacted instead. */
  .masthead__actions > .btn {
    padding: var(--s-8) var(--s-16);
    font-size: var(--t-small);
  }
  .masthead__actions > .btn.btn--well { padding-right: var(--s-40); }
  .masthead__actions > .btn .btn__well { width: 28px; }

  .masthead__nav.open {
    display: flex;
    position: absolute;
    top: 76px; left: 0; right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: var(--s-4);
    background: var(--ground);
    border-bottom: 1px solid var(--ink-10);
    padding: var(--s-16) var(--gutter) var(--s-24);
  }
  .masthead__nav.open .navlink { padding: var(--s-12) var(--s-16); font-size: var(--t-lede); }
  .masthead__nav.open > .btn { display: inline-flex; margin-top: var(--s-12); }

  .coverflow { --card-w: 300px; }
  .coverflow__stage { height: 528px; perspective: 1200px; }
  .plan { height: 504px; margin-top: -252px; }
}

@media (max-width: 900px) {
  .hero__inner { grid-template-columns: 1fr; gap: var(--s-48); }
  /* The chip goes static here so it sits under the card instead of hanging
     off its corner — but .hero__visual is a row flex, so static made it a
     second COLUMN and squeezed the card from 340px down to 221. Stacking the
     wrapper is what the static chip always needed. */
  .hero__visual { order: 2; flex-direction: column; align-items: center; }
  .hero__text { order: 1; }
  /* animation, not just transform: an animated transform beats a plain
     declaration, so `transform: none` alone never took effect here. */
  .hero__object { width: min(100%, 340px); animation: none; }
  .hero__proof { position: static; transform: none; animation: none; margin-top: var(--s-16); }
  .hero__float { position: static; transform: none; animation: none; margin-top: var(--s-12); }
}

@media (max-width: 640px) {
  .section { padding-block: var(--s-48); }
  .section--tight { padding-block: var(--s-40); }
  .hero { padding-block: var(--s-64) var(--s-48); }
  .grid--2, .grid--3, .grid--4 { grid-template-columns: 1fr; }
  .stats { grid-template-columns: 1fr; gap: var(--s-32); }
  .opts, .row2 { grid-template-columns: 1fr; }
  .footer__grid { grid-template-columns: 1fr; }
  .cta { padding: var(--s-56) var(--s-24); }
  .hero__actions .btn { width: 100%; }
  .numlist li { grid-template-columns: 40px 1fr; }

  /* Coverflow flattens into a snap-scroller on touch. */
  .coverflow__stage {
    height: auto;
    perspective: none;
    display: flex;
    gap: var(--s-16);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    padding-bottom: var(--s-16);
    cursor: default;
    touch-action: auto;
  }
  .plan {
    position: relative;
    top: auto; left: auto;
    margin: 0;
    flex: 0 0 86%;
    height: auto;
    transform: none !important;
    opacity: 1 !important;
    filter: none !important;
    scroll-snap-align: center;
    transition: none;
  }
  .plan[aria-hidden="true"] { pointer-events: auto; }
  .plan:not(.is-active) .plan__action { pointer-events: auto; }
  .cf-btn { display: none; }
  /* The dots cannot control a native snap-scroller and a swipe never updates
     them — hiding them stops the UI claiming a position it does not track. */
  .cf-dots { display: none; }
}


/* --------------------------------------------------------------------------
   16. Brand pattern
   The brand guide's pattern is a stepped bracket derived from the logo's E.
   Used as a quiet structural motif, never as a busy fill.
   -------------------------------------------------------------------------- */

.bracket {
  position: absolute;
  width: 180px;
  height: 128px;
  border: 1px solid var(--accent);
  border-right: 0;
  opacity: 0.22;
  pointer-events: none;
}

/* Hidden once the layout narrows enough for it to touch the text column. */
@media (max-width: 1180px) { }


/* --------------------------------------------------------------------------
   16b. Marketplace arc
   The client's own composed graphic — an arc of marketplace marks closing on
   the Ecom Solutions pill. It is one raster, so it is placed rather than
   rebuilt: splitting the pills apart would lose the arrangement, and the
   arrangement is the design. Capped at 860px so the 1537px source lands at
   roughly 2x on the widest display it will ever occupy.
   -------------------------------------------------------------------------- */

.channels { display: flex; justify-content: center; }

.channels img {
  width: 100%;
  max-width: 860px;
  height: auto;
}

@media (max-width: 640px) {
  /* Below this the pill wordmarks stop being legible before the image stops
     fitting, so the limit is readability rather than width. */
  .channels img { min-width: 300px; }
}


/* --------------------------------------------------------------------------
   17. Story deck
   A fan of overlapping portrait cards. The overlap is expressed once, as a
   fraction of card width, rather than as seven hand-tuned offsets — so the
   fan tightens with the viewport instead of overflowing it. Each card's
   resting rotation, lift and scale live in custom properties, which lets the
   hover rule restate the transform without repeating the numbers; changing a
   card's angle then means editing one value, not three rules.
   -------------------------------------------------------------------------- */

.deck-panel {
  background: var(--surface-1);
  border-radius: 28px;
  padding: var(--s-56) var(--s-40) var(--s-56);
}

.deck-panel .section-head { margin-bottom: var(--s-32); }

/* Cards later in the DOM paint over earlier ones, which is exactly the
   left-under-right stacking the fan wants — so there is no z-index ladder
   here, only the single lift applied on hover. */
.deck {
  --card-w: clamp(140px, 15.5vw, 236px);
  --overlap: calc(var(--card-w) * -0.25);
  display: flex;
  justify-content: center;
  align-items: center;
  padding-block: var(--s-40) var(--s-24);
}

.deck__card {
  --rot: 0deg;
  --ty: 0px;
  --sc: 1;
  --i: 0;
  --frame: var(--accent);

  position: relative;
  flex: 0 0 var(--card-w);
  width: var(--card-w);
  min-width: 0;
  aspect-ratio: 3 / 4;
  margin-inline-start: var(--overlap);
  border-radius: var(--r-panel);
  overflow: hidden;
  /* The frame is drawn as a spread shadow rather than a border so it sits
     outside the radius without eating into the image box. */
  box-shadow: 0 0 0 4px var(--frame), 0 18px 40px rgba(0, 0, 0, .45);

  /* The base rule is the FINISHED fan, so a page whose JS never ran shows the
     .sequence and .stack__card use. Only the hidden state is gated. */
  transform: translateY(var(--ty)) rotate(var(--rot)) scale(var(--sc));
  transition:
    transform var(--d-micro) var(--e-out),
    box-shadow var(--d-micro) var(--e-out);
}

.js .deck__card { opacity: 0; }

/* The entrance is an animation rather than a transition on purpose. Staggering
   a transition means leaving transition-delay set on the resting state, and
   that delay then also applies on hover-out — the card would hang for up to
   420ms before dropping back. An animation carries its own delay and hands the
   transform back afterwards.

   fill-mode is `backwards`, never `forwards`: backwards holds the FROM frame
   through the delay so cards stay hidden until their turn, while leaving the
   final transform to the base rule. Holding the TO frame would pin the
   transform and the hover lift would have nothing left to move. */
@keyframes deck-in {
  from { opacity: 0; transform: translateY(28px) rotate(0deg) scale(.94); }
  to   { opacity: 1; transform: translateY(var(--ty)) rotate(var(--rot)) scale(var(--sc)); }
}

.deck__card:first-child { margin-inline-start: 0; }

/* Resting fan, symmetric about the middle. Frames run the brand tint ladder
   out from the centre; a spectrum of unrelated hues would read as a different
   brand's deck. Full --accent is deliberately absent here so it belongs to the
   CTA card alone.

   The lift follows a parabola rather than even steps. Cards fanned about a
   common pivot with a constant rotation step sit on a curve whose outer rise
   is roughly triple the inner one — stepping it evenly flattens the arc at
   exactly the ends where a fan should curl hardest, and the outer cards then
   look like they slipped rather than swung. */
.deck__card:nth-child(1) { --rot: -5deg; --ty:  24px; --i: 0; --frame: #ffe0d6; }
.deck__card:nth-child(2) { --rot: -3deg; --ty:   4px; --i: 1; --frame: #ffb8a6; }
.deck__card:nth-child(3) { --rot: -1deg; --ty:  -6px; --i: 2; --frame: #ff8a70; }
.deck__card:nth-child(4) { --rot:  1deg; --ty:  -6px; --i: 3; --frame: #ff8a70; }
.deck__card:nth-child(5) { --rot:  3deg; --ty:   4px; --i: 4; --frame: #ffb8a6; }
.deck__card:nth-child(6) { --rot:  5deg; --ty:  24px; --i: 5; --frame: #ffe0d6; }

.deck.in .deck__card {
  opacity: 1;
  animation: deck-in .85s var(--e-out) backwards;
  animation-delay: calc(var(--i) * 70ms);
}

/* focus-within, not just hover: the CTA card is a link, and a keyboard user
   tabbing onto it should get the same lift a pointer user gets. */
.deck.in .deck__card:hover,
.deck.in .deck__card:focus-within {
  z-index: 5;
  /* Lift and scale are balanced so the card's BOTTOM edge never rises. A
     16px lift against a 1.04 scale moved it up 10px, and a pointer sitting
     in that band lost the card the moment it moved — hover ended, the card
     dropped back under the pointer, and it oscillated. Scaling 1.06 pushes
     the bottom down by slightly more than the 6px lift raises it, at every
     card size the clamp produces, so the pointer is never orphaned. */
  transform: translateY(calc(var(--ty) - 6px)) rotate(var(--rot)) scale(calc(var(--sc) * 1.06));
  box-shadow: 0 0 0 4px var(--frame), 0 30px 62px rgba(0, 0, 0, .62);
}

.deck__card img,
.deck__card video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Scrim under the name. Stops at 62% so the face stays lit. */
.deck__card::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top,
    rgba(0, 0, 0, .88) 0%, rgba(0, 0, 0, .38) 34%, transparent 62%);
}

/* The next card covers the right ~25% of this one, so the label is held out
   of that strip. Left to run the full width it gets sliced mid-word, which
   reads as a bug rather than as depth. */
.deck__name {
  position: absolute;
  z-index: 1;
  left: var(--s-16);
  right: 28%;
  bottom: var(--s-16);
  font-size: clamp(15px, 1.6vw, 23px);
  font-weight: var(--w-medium);
  line-height: 1.12;
  color: #fff;
  text-wrap: balance;
}

/* Nothing overlaps the last photo card on small screens, where the fan has
   been unstacked into a row. */
@media (max-width: 900px) { .deck__name { right: var(--s-16); } }

.deck__play {
  position: absolute;
  z-index: 1;
  top: var(--s-12);
  left: var(--s-12);
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: rgba(255, 255, 255, .92);
  color: var(--ground);
}
.deck__play svg { margin-left: 2px; }

/* The last card breaks the pattern deliberately: solid brand fill, tilted
   against the drift of the others and lifted clear of them, so the eye lands
   on the one card that is actually a control. */
.deck__card--cta {
  /* Against the drift, not the next rung of it. At +7deg this was simply
     card 7 of the same fan, only larger; leaning it the other way is what
     makes it read as a separate object set down on top of the deck. */
  --rot: -6deg;
  --ty: -18px;
  --sc: 1.07;
  --i: 6;
  --frame: #fff;
  /* The face is the clay storefront again — door open, light on — rendered
     portrait with its lower third left empty for the copy. The solid blue
     stays as the ground under the render and for the moment before it
     loads; white on it is 4.51:1. */
  background: var(--accent-action);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: var(--s-8);
  padding: var(--s-20) var(--s-12) var(--s-20);
  text-align: center;
  text-decoration: none;
}
/* Pulled up so the shop sits high and its plinth clears the copy; the
   render's empty top is what gets cropped. A soft run of the card's blue
   over the lower band keeps the text on solid colour whatever the render
   is doing behind it. */
.deck__cta-art {
  position: absolute;
  left: 0; right: 0;
  top: -16%;
  height: 116%;
  width: 100%;
  object-fit: cover;
  object-position: 50% 0;
  z-index: 0;
}
.deck__card--cta::before {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 46%;
  background: linear-gradient(to top, #3a1208 0%, rgba(58, 18, 8, .85) 55%, transparent 100%);
  z-index: 1;
}
.deck__cta-title, .deck__cta-btn, .deck__cta-note { position: relative; z-index: 2; }
.deck__card--cta::after { content: none; }

/* Everywhere else the global --accent ring reads fine; here it would be drawn
   on top of this card's own blue frame. White, pushed clear of the 4px ring. */
.deck__card--cta:focus-visible {
  outline-color: #fff;
  outline-offset: 6px;
}

.deck__cta-title {
  font-size: clamp(17px, 1.75vw, 25px);
  font-weight: var(--w-medium);
  line-height: 1.08;
  color: #fff;
}
/* Full white, no alpha — see the note on the card background. Hierarchy
   against the title comes from size and weight instead. */
.deck__cta-note {
  font-size: var(--t-small);
  font-weight: var(--w-light);
  line-height: 1.35;
  color: #fff;
}
.deck__cta-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--s-8);
  max-width: 100%;
  padding: var(--s-8) var(--s-12);
  border-radius: var(--r-button);
  background: var(--ground);
  color: var(--ink);
  font-size: var(--t-small);
  font-weight: var(--w-medium);
  /* nowrap made this a fixed 175px pill inside a 132px card on mobile, and
     the card's overflow:hidden sliced both ends off the label. */
  text-align: center;
}
.deck__card--cta:hover .deck__cta-btn { background: #262626; }

/* Below the fan's comfortable width the rotations collide and the row runs
   past the panel, so the deck stops being a fan and becomes a snap row. */
@media (max-width: 900px) {
  .deck {
    --card-w: 164px;
    justify-content: flex-start;
    gap: var(--s-12);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    padding-inline: var(--s-24);
    /* overflow-x:auto silently makes overflow-y:auto too, so the block
       padding is what stops the row clipping each card's drop shadow. */
    padding-block: var(--s-40);
  }
  .deck::-webkit-scrollbar { display: none; }
  .deck:focus-visible { outline-offset: -2px; }

  /* :nth-child(n) matches every card and, crucially, carries the same
     specificity as the :nth-child(1..6) resting rules above — a bare
     .deck__card here loses to them and the row keeps its desktop tilt. */
  .deck__card:nth-child(n) {
    --rot: 0deg;
    --ty: 0px;
    --sc: 1;
    margin-inline-start: 0;
    scroll-snap-align: center;
  }
  .deck.in .deck__card:hover,
  .deck.in .deck__card:focus-within {
    transform: translateY(0) rotate(0deg) scale(1);
  }

  .deck-panel { padding-inline: 0; }
  .deck-panel .section-head { padding-inline: var(--s-24); }
}

@media (prefers-reduced-motion: reduce) {
  .deck__card { transition: none; }
  .deck.in .deck__card { animation: none; }
  .deck.in .deck__card:hover,
  .deck.in .deck__card:focus-within {
    transform: translateY(var(--ty)) rotate(var(--rot)) scale(var(--sc));
  }
}


/* --------------------------------------------------------------------------
   17b. Shared playful entrance keyframes
   Originally written for the marketplace mosaic; that block is gone but these
   are still driven by the pillar, feature and sequence reveals below.
   -------------------------------------------------------------------------- */

/* ---- shaka's playful entrance set ---- */
@keyframes fade-in-opacity { from { opacity: 0; } to { opacity: 1; } }

@keyframes rubberband {
  0%   { transform: scaleX(1); }
  35%  { transform: scaleX(1.09) scaleY(0.85); }
  55%  { transform: scaleX(0.9) scaleY(1); }
  75%  { transform: scaleX(1.05) scaleY(0.95); }
  100% { transform: scaleX(1) scaleY(1); }
}
@keyframes shake {
  30%      { transform: scale(1.1); }
  40%, 60% { transform: rotate(-10deg) scale(1.1); }
  50%      { transform: rotate(10deg) scale(1.1); }
  70%      { transform: rotate(0deg) scale(1.1); }
  100%     { transform: scale(1); }
}
@keyframes swing {
  20%  { transform: rotate(10deg); }
  60%  { transform: rotate(-5deg); }
  100% { transform: rotate(0deg); }
}
@keyframes flip {
  0%   { transform: perspective(400px) translateZ(50px) rotateY(180deg); animation-timing-function: ease-in; }
  50%  { transform: perspective(400px); animation-timing-function: ease-in; }
  100% { transform: perspective(400px) rotateY(0deg); animation-timing-function: ease-in; }
}
@keyframes rotate-in-up-left {
  0%   { transform-origin: left bottom; transform: rotate(90deg); opacity: 0; }
  100% { transform-origin: left bottom; transform: rotate(0); opacity: 1; }
}
@keyframes drop-in {
  from { opacity: 0; transform: translateY(-100%); }
  to   { opacity: 1; transform: translateY(0); }
}






/* --------------------------------------------------------------------------
   19. Promise cards
   Three cards, but not the template three: the schematic face runs
   edge-to-edge instead of sitting as an inset rounded panel inside a rounded
   card (the panel-in-a-panel double frame is the single loudest generated-
   design tell), the row steps down left to right instead of sitting on one
   baseline, and each face is a soft-3D render of its promise — message
   bubbles, a rising chart, a sealed card — generated to the card's own
   ground colour so the image and the panel read as one surface.
   -------------------------------------------------------------------------- */

.features { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-20); }

/* The step makes the row read as three placed objects rather than one
   stamped component. Killed below 1000px where the grid goes 2-up. */
.feature:nth-child(2) { margin-top: var(--s-32); }
.feature:nth-child(3) { margin-top: var(--s-64); }

.feature {
  background: var(--surface-2);
  border-radius: var(--r-panel);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: background-color var(--d-micro) var(--e-out), transform var(--d-micro) var(--e-out), box-shadow var(--d-micro) var(--e-out);
}
a.feature:hover {
  background: var(--surface-3);
  transform: translateY(-5px);
  box-shadow: 0 26px 54px rgba(0, 0, 0, .42);
}

/* Full bleed: the face is the card's top, not a picture pinned inside it. */
.feature__media {
  aspect-ratio: 1 / 0.74;
  padding: var(--s-24);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--s-16);
  overflow: hidden;
  position: relative;
}
.feature__media--grad  { background: var(--grad-corner); }
.feature__media--light { background: #f6efeb; }
.feature__media--deep  { background: var(--grad-deep); box-shadow: inset 0 -1px 0 var(--ink-10); }

/* Ghost index in the face's corner — the "three things" count, carried the
   same way the phase cards carry theirs. */
.feature__no {
  position: absolute;
  top: 2px;
  right: 14px;
  font-size: 64px;
  font-weight: var(--w-light);
  line-height: 1.3;
  letter-spacing: -2px;
  opacity: .16;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}
.feature__media--grad .feature__no,
.feature__media--deep .feature__no { color: #fff; }
.feature__media--light .feature__no { color: var(--deep); opacity: .12; }

.feature__body { display: flex; flex-direction: column; gap: var(--s-12); flex: 1; padding: var(--s-20) var(--s-20) var(--s-16); }
.feature__title { font-size: var(--t-subheading); font-weight: var(--w-medium); letter-spacing: -0.3px; }
.feature__desc  { color: var(--ink-50); flex: 1; }


.feature__go {
  align-self: flex-end;
  width: 34px; height: 34px;
  display: grid; place-items: center;
  color: var(--ink-50);
  transition: color var(--d-micro) var(--e-out), transform var(--d-micro) var(--e-out);
}
a.feature:hover .feature__go { color: var(--ink); transform: translateX(3px); }

/* ---- face image ---- */
.feature__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .9s var(--e-out);
}
a.feature:hover .feature__img { transform: scale(1.045); }
.feature__no { z-index: 1; }

/* ---- reveal ---- */
.js .feature { opacity: 0; transform: translateY(18px); }
.features.in .feature { animation: fade-up .7s var(--e-out) forwards; }
.features.in .feature:nth-child(2) { animation-delay: .12s; }
.features.in .feature:nth-child(3) { animation-delay: .24s; }

@media (max-width: 1000px) {
  .features { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .feature:nth-child(2), .feature:nth-child(3) { margin-top: 0; }
}
@media (max-width: 640px)  { .features { grid-template-columns: 1fr; } }

/* --------------------------------------------------------------------------
   20. Pillars
   Tinted cards, media panel above centred copy. The three grounds are the
   brand blue and navy blended into the page ground at different ratios, so
   they read as one family rather than three new accents.
   -------------------------------------------------------------------------- */

.pillars { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-24); }
.roster i.out { background: rgba(43, 15, 10, 0.18); }

@media (max-width: 1000px) { }
@media (max-width: 640px)  { }


/* --------------------------------------------------------------------------
   21. Sequence panel
   Schematic stack on one side, heading plus a stepped list on the other.
   The active step is marked by a solid rule; the rest sit back.
   -------------------------------------------------------------------------- */

.sequence {
  background: var(--surface-1);
  border-radius: 28px;
  padding: var(--s-64) var(--s-48);
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: var(--s-64);
  align-items: center;
}

@media (max-width: 1000px) {
}
@media (max-width: 560px) {
}


/* --------------------------------------------------------------------------
   22. Bento
   Mixed-weight mosaic: a tall feature tile, tinted panels, a stat block and
   quiet dark cells. Replaces the flat six-tile grid.
   -------------------------------------------------------------------------- */

.bento {
  display: grid;
  grid-template-columns: 1.15fr 1fr 1fr;
  grid-auto-rows: minmax(150px, auto);
  gap: var(--s-16);
  margin-top: var(--s-48);
}

.bx {
  border-radius: 22px;
  padding: var(--s-24);
  background: var(--surface-2);
  display: flex;
  flex-direction: column;
  gap: var(--s-16);
  transition: background-color var(--d-micro) var(--e-out);
}
.bx:hover { background: var(--surface-3); }
.chip-plan.on { background: var(--ground); color: var(--ink); }
.rail i.on { background: var(--accent); }

@media (max-width: 1000px) {
}
@media (max-width: 640px) {
}


/* --------------------------------------------------------------------------
   23. Staggered entrances for the panel sections
   Each child enters on its own delay with its own motion, matching the way
   the mosaic reveals. A single fade on the container flattens all of it.
   -------------------------------------------------------------------------- */

/* ---- Pillars ---- */
.js .pillars .pillar { opacity: 0; }
.pillars.in .pillar:nth-child(1) { animation: fade-in-opacity .2s forwards, flip .5s; animation-delay: .15s; }
.pillars.in .pillar:nth-child(2) { animation: fade-in-opacity .2s forwards, rubberband .5s; animation-delay: .45s; }
.pillars.in .pillar:nth-child(3) { animation: fade-in-opacity .2s forwards, swing .45s; animation-delay: .75s; transform-origin: top center; }

/* Panel contents settle in after the card lands */
.pillars.in .pillar .slat,
.pillars.in .pillar .roster { opacity: 0; animation: fade-up .5s var(--e-out) forwards; }
.pillars.in .pillar:nth-child(1) .slat:nth-of-type(1) { animation-delay: .5s; }
.pillars.in .pillar:nth-child(1) .slat:nth-of-type(2) { animation-delay: .6s; }
.pillars.in .pillar:nth-child(1) .slat:nth-of-type(3) { animation-delay: .7s; }
.pillars.in .pillar:nth-child(1) .slat:nth-of-type(4) { animation-delay: .8s; }
.pillars.in .pillar:nth-child(2) .slat { animation-delay: .8s; }
.pillars.in .pillar:nth-child(2) .slat:nth-of-type(2) { animation-delay: .9s; }
.pillars.in .pillar:nth-child(2) .slat:nth-of-type(3) { animation-delay: 1s; }
.pillars.in .pillar:nth-child(3) .slat,
.pillars.in .pillar:nth-child(3) .roster { animation-delay: 1.1s; }

/* ---- Bento ---- */
.js .bento .bx { opacity: 0; }
.bento.in .bx { animation: fade-in-opacity .3s forwards, fade-up .6s var(--e-out) forwards; }
.bento.in .bx--intro   { animation-delay: .1s; }
.bento.in .bx--feature { animation-delay: .55s; animation-name: fade-in-opacity, scale-in; animation-duration: .3s, .5s; transform-origin: left center; }
.bento.in .bx--wide    { animation-delay: .3s; }
.bento.in .bx--tint    { animation-delay: .8s; }
.bento.in .bx--mid     { animation-delay: .45s; }
.bento.in .bx--tall    { animation-delay: .65s; }
.bento.in .bx--stat    { animation-delay: 1s; animation-name: fade-in-opacity, rubberband; animation-duration: .3s, .5s; }

/* ---- Sequence ---- */
/* Only the opacity track carries `forwards`. The motion tracks must NOT —
   each screen has a base transform that positions it in the fan, and these
   keyframes all end on identity, so holding their last frame would flatten
   the arrangement. Letting them expire hands the transform back to CSS. */
.js .sequence .screen { opacity: 0; }
.sequence.in .screen--back  { animation: fade-in-opacity .3s forwards, rotate-in-up-left .4s; animation-delay: .2s; transform-origin: left bottom; }
.sequence.in .screen--front { animation: fade-in-opacity .25s forwards, rise .9s var(--e-out); animation-delay: .45s; }
.sequence.in .screen--side  { animation: fade-in-opacity .3s forwards, swing .4s; animation-delay: .8s; transform-origin: top center; }
.sequence.in .steps-list li { animation: fade-up .5s var(--e-out) forwards; }
.sequence.in .steps-list li:nth-child(1) { animation-delay: .7s; }
.sequence.in .steps-list li:nth-child(2) { animation-delay: .85s; }
.sequence.in .steps-list li:nth-child(3) { animation-delay: 1s; }

@media (prefers-reduced-motion: reduce) {
  .sequence .screen, .sequence .steps-list li,
  .pillars.in .pillar .slat, .pillars.in .pillar .roster {
    opacity: 1 !important;
    animation: none !important;
  }
}


/* --------------------------------------------------------------------------
   25. Stacking phases
   Each phase is position:sticky with a slightly larger top offset than the
   one before, so they pile up as you scroll. Grounds run dark -> brand ->
   light, so the stack visibly brightens as the engagement progresses.
   -------------------------------------------------------------------------- */

.stack {
  display: flex;
  flex-direction: column;
  gap: var(--s-24);
  max-width: 940px;      /* narrower than the rail — the stack reads better tight */
  margin-inline: auto;
}

.stack__card {
  position: sticky;
  overflow: hidden;
  border-radius: 28px;
  padding: var(--s-32) var(--s-40);
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: var(--s-32);
  align-items: center;
  min-height: 300px;
  /* Snappy: quick, slightly overshooting settle rather than a slow fade.
     Idle state is scoped to .js so a script failure leaves cards visible. */
  transition: opacity .32s ease-out, transform .42s cubic-bezier(.2,1.5,.4,1);
}
.js .stack__card { opacity: 0; transform: translateY(28px) scale(.965); }
.stack__card.on { opacity: 1; transform: none; }
/* After the entrance settles, scroll drives transform/opacity inline every
   frame — the 0.42s entrance transition would rubber-band behind it. */
.stack.settled .stack__card { transition: none; transform-origin: 50% 0; }
.stack__card > * { min-width: 0; }

.stack__card:nth-child(1) { top: 104px; }
.stack__card:nth-child(2) { top: 128px; }
.stack__card:nth-child(3) { top: 152px; }

/* Radial highlight behind the visual gives each card dimension; a flat fill
   read as a dead rectangle. */
.stack__card--1 {
  background:
    radial-gradient(120% 150% at 82% 18%, rgba(255, 138, 112,.34) 0%, transparent 58%),
    linear-gradient(140deg, #2e1d19 0%, #1c1210 100%);
}
.stack__card--2 {
  background:
    radial-gradient(120% 150% at 82% 18%, rgba(255,255,255,.30) 0%, transparent 58%),
    linear-gradient(140deg, #ff6e52 0%, #d93d1f 100%);
}
.stack__card--3 {
  background:
    radial-gradient(120% 150% at 82% 18%, rgba(255,255,255,.75) 0%, transparent 60%),
    linear-gradient(140deg, #ffc9b8 0%, #ff9f85 100%);
}

.stack__text { display: flex; flex-direction: column; gap: var(--s-12); align-items: flex-start; }

.stack__labelrow { display: flex; align-items: center; gap: var(--s-12); }

.stack__label {
  display: inline-flex;
  align-items: center;
  font-size: var(--t-small);
  font-weight: var(--w-medium);
  letter-spacing: .08em;
  text-transform: uppercase;
  padding: var(--s-4) var(--s-12);
  border-radius: var(--r-pill);
}

/* Where the reader is in the sequence, without reading anything: three
   segments, filled up to the current phase. currentColor, so it follows
   each card's ink — white on the dark pair, navy on the pale one. */
.stack__meter { display: flex; align-items: center; gap: 5px; color: currentColor; }
.stack__meter i {
  width: 14px; height: 3px;
  border-radius: 2px;
  background: currentColor;
  opacity: .22;
}
.stack__meter i.is-on { opacity: .9; width: 22px; }
.stack__title { font-size: var(--t-heading); line-height: 1.12; letter-spacing: -.6px; font-weight: var(--w-medium); }
.stack__lede  { font-size: var(--t-body); line-height: 1.5; max-width: 30rem; }
.stack__you   { font-size: var(--t-small); opacity: .7; margin-top: var(--s-4); }

.stack__card--1 { color: #fff; }
.stack__card--2 { color: var(--deep); }
.stack__card--1 .stack__label { background: rgba(255,255,255,.12); color: #fff; }
.stack__card--2 .stack__label { background: rgba(43,15,10,.12); color: var(--deep); }
.stack__card--1 .stack__lede { color: rgba(255,255,255,.78); }
.stack__card--2 .stack__lede { color: rgba(43,15,10,.78); }
.stack__card--2 .stack__fact { background: rgba(43,15,10,.1); }

.stack__card--3 { color: var(--deep); }
.stack__card--3 .stack__label { background: rgba(43, 15, 10,.12); color: var(--deep); }
.stack__card--3 .stack__lede  { color: rgba(43, 15, 10,.75); }

/* ---- Phase art slot ----
   Inline SVG animated with CSS. This used to be a lottie-web mount point with
   the SVG as a fallback, but the mounted player rendered placeholder JSON over
   the top and the artifact build's CSP blocks the CDN anyway. The SVG is the
   artwork now: no library, no network call, nothing to fall back from. */
.phase-art {
  position: relative;
  width: 100%;
  aspect-ratio: 1;
  max-width: 300px;
  margin-inline: auto;
  display: grid;
  place-items: center;
}
.phase-art svg { display: block; width: 100%; height: 100%; }

/* Built-in animation. Pure SVG + CSS, no library, so it runs on the local
   site, a deployed site and inside an artifact alike. Drops out the moment a
   real Lottie file mounts. */
.phase-art__svg { position: absolute; inset: 0; width: 100%; height: 100%; }

/* Phase art — a seller console, one per phase, carrying the real
   marketplace's official mark on its own white card (the client-supplied
   ~bgwhite SVG set), sitting in the console's top bar.

   The panel is a plain translucent fill, not backdrop-filter: these cards are
   position:sticky and already composite a gradient per scroll frame, and a
   live backdrop blur on top of that is the one thing guaranteed to drop
   frames on the stack. */
.console {
  --panel:      rgba(255, 255, 255, .13);
  --panel-edge: rgba(255, 255, 255, .26);
  --panel-ink:  #fff;
  --panel-dim:  rgba(255, 255, 255, .38);

  position: absolute;
  inset: 6% 2%;
  display: flex;
  flex-direction: column;
  gap: 7%;
  padding: 7% 7% 8%;
  border-radius: 18px;
  background: var(--panel);
  box-shadow:
    inset 0 1px 0 var(--panel-edge),
    0 18px 40px rgba(0, 0, 0, .28);
  /* A shallow tilt reads as a screen sitting in space; anything past about
     16deg and the mark's wordmark starts to smear. */
  transform: perspective(900px) rotateY(-13deg) rotateX(7deg);
  transform-origin: 50% 50%;
}

/* Card three runs on a pale ground, so the glass inverts to a solid panel. */
.stack__card--3 .console {
  --panel:      rgba(255, 255, 255, .86);
  --panel-edge: rgba(255, 255, 255, .9);
  --panel-ink:  var(--deep);
  --panel-dim:  rgba(43, 15, 10, .3);
  box-shadow: 0 18px 40px rgba(40, 10, 4, .22);
}

.console__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.console__mark {
  height: 44px;
  width: auto;
}

.console__chip {
  font-size: 9px;
  font-weight: var(--w-medium);
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--panel-ink);
  opacity: .72;
  padding: 3px 8px;
  border-radius: var(--r-pill);
  background: var(--panel-edge);
  white-space: nowrap;
}

/* ---- phase 1: a setup checklist completing ---- */
.console__rows { display: flex; flex-direction: column; gap: 11%; flex: 1; justify-content: center; }
.console__row  { display: flex; align-items: center; gap: 9px; }

.console__tick {
  flex: 0 0 auto;
  width: 17px; height: 17px;
  border-radius: 6px;
  display: grid;
  place-items: center;
  background: var(--panel-edge);
  color: var(--panel-ink);
  animation: cs-tick 5s cubic-bezier(.3, 0, .2, 1) infinite;
  animation-delay: calc(var(--i) * .5s);
}
.console__tick svg { width: 10px; height: 10px; }

.console__line {
  height: 7px;
  border-radius: 4px;
  background: var(--panel-ink);
  opacity: .3;
  transform-origin: 0% 50%;
  animation: cs-line 5s cubic-bezier(.3, 0, .2, 1) infinite;
  animation-delay: calc(var(--i) * .5s);
}

/* ---- phase 2: order rows ticking over ---- */
.console__ops { display: flex; flex-direction: column; gap: 9%; flex: 1; justify-content: center; }
.console__op  { display: flex; align-items: center; gap: 8px; }
.console__opk { height: 6px; border-radius: 3px; background: var(--panel-ink); opacity: .28; flex: 1; }
.console__opv {
  height: 12px;
  border-radius: 4px;
  background: var(--panel-ink);
  opacity: .85;
  transform-origin: 100% 50%;
  animation: cs-val 4.6s cubic-bezier(.3, 0, .2, 1) infinite;
  animation-delay: calc(var(--i) * .34s);
}

.console__live {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 9px;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--panel-ink);
  opacity: .8;
}
.console__pulse {
  width: 6px; height: 6px;
  border-radius: 2px;
  background: currentColor;
  animation: cs-pulse 1.9s ease-in-out infinite;
}

/* ---- phase 3: catalogue widening, then a trend ---- */
.console__grid {
  flex: 1;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 1fr;
  gap: 6px;
}
.console__cell {
  border-radius: 5px;
  background: var(--panel-ink);
  opacity: .25;
  transform-origin: 50% 50%;
  animation: cs-cell 4.8s cubic-bezier(.3, 0, .2, 1) infinite;
  animation-delay: calc(var(--i) * .09s);
}
.console__trend { display: flex; align-items: flex-end; gap: 5px; height: 26px; }
.console__tb {
  flex: 1;
  border-radius: 3px 3px 1px 1px;
  background: var(--panel-ink);
  opacity: .7;
  transform-origin: 50% 100%;
  animation: cs-tb 4.8s cubic-bezier(.3, 0, .2, 1) infinite;
  animation-delay: calc(var(--i) * .11s);
}

@keyframes cs-tick  { 0%, 10% { opacity: .3; transform: scale(.8) }  22%, 82% { opacity: 1; transform: scale(1) }  94%, 100% { opacity: .3; transform: scale(.8) } }
@keyframes cs-line  { 0%, 10% { transform: scaleX(.15) }             24%, 82% { transform: scaleX(1) }              94%, 100% { transform: scaleX(.15) } }
@keyframes cs-val   { 0%, 8%  { transform: scaleX(.1); opacity: .3 } 22%, 78% { transform: scaleX(1); opacity: .85 } 92%, 100% { transform: scaleX(.1); opacity: .3 } }
@keyframes cs-pulse { 0%, 100% { opacity: .25 } 50% { opacity: 1 } }
@keyframes cs-cell  { 0%, 6%  { transform: scale(.3); opacity: 0 }   22%, 76% { transform: scale(1); opacity: .25 }  92%, 100% { transform: scale(.3); opacity: 0 } }
@keyframes cs-tb    { 0%, 8%  { transform: scaleY(.12) }             26%, 78% { transform: scaleY(1) }               94%, 100% { transform: scaleY(.12) } }

@media (prefers-reduced-motion: reduce) {
  .console * { animation: none !important; }
  .console__line, .console__opv { transform: none; }
  .console__cell { transform: none; opacity: .25; }
  .console__tb { transform: none; }
}

@media (max-width: 1000px) {
  .stack__card { grid-template-columns: 1fr; gap: var(--s-24); padding: var(--s-32); min-height: 0; }
  .stack__card:nth-child(1),
  .stack__card:nth-child(2),
  .stack__card:nth-child(3) { top: 92px; }
  .phase-art { max-width: 220px; }
}

@media (max-height: 700px), (prefers-reduced-motion: reduce) {
  .stack__card { position: static; }
}
@media (prefers-reduced-motion: reduce) {
  .stack__card { opacity: 1; transform: none; transition: none; }
  .phase-art__svg * { animation: none !important; }
}


/* --------------------------------------------------------------------------
   26. Well button
   A pill with an inset accent square on the right holding an arrow. On hover
   a fill sweeps out from behind that square to cover the pill.

   The sweep is a scaleX transform, not a width animation — width forces a
   layout pass every frame, which is what made the first version stutter.
   The fill's right edge stays hidden behind the well, so the horizontal
   squash that scaleX would normally do to the pill radius is never visible.
   -------------------------------------------------------------------------- */

.btn--well {
  position: relative;
  overflow: hidden;
  padding-right: 60px;
  isolation: isolate;
  /* The generic button lift is cancelled — the sweep carries the motion. */
  transition: none;
}
.btn--well.btn--lg { padding-right: 72px; }
.btn--well:hover, .btn--well:focus-visible { transform: none; }

.btn__label {
  position: relative;
  z-index: 3;
  transition: color .4s cubic-bezier(.33,1,.68,1);
}

/* Edge to edge. An inset left a band of the button's own background framing
   the fill — barely visible on the blue button, but a heavy near-black ring
   on the dark .btn--onlight variant. The button's overflow:hidden clips this
   to the pill, so no radius of its own is needed. */
.btn__fill {
  position: absolute;
  z-index: 1;
  inset: 0;
  border-radius: inherit;
  background: var(--accent-tint-3);
  transform: scaleX(0);
  transform-origin: 100% 50%;
  transition: transform .4s cubic-bezier(.33,1,.68,1);
  will-change: transform;
}

.btn__well {
  position: absolute;
  z-index: 2;
  top: 5px;
  right: 5px;
  bottom: 5px;
  width: 38px;
  border-radius: var(--r-pill);
  background: var(--accent-tint-3);
  color: var(--deep);
  display: grid;
  place-items: center;
}
.btn--lg .btn__well { width: 46px; top: 6px; right: 6px; bottom: 6px; }

.btn__well svg {
  transition: transform .4s cubic-bezier(.33,1,.68,1);
  will-change: transform;
}

.btn--well:hover .btn__fill,
.btn--well:focus-visible .btn__fill { transform: scaleX(1); }

.btn--well:hover .btn__label,
.btn--well:focus-visible .btn__label { color: var(--deep); }

.btn--well:hover .btn__well svg,
.btn--well:focus-visible .btn__well svg { transform: translateX(3px); }

/* This variant sits on the blue CTA panel, so it must sweep AWAY from blue —
   filling with the brand blue made the button dissolve into its own ground.
   Near-black at rest, white when swept: both read hard against the panel. */
.btn--onlight .btn__fill,
.btn--onlight .btn__well { background: #fff; }
.btn--onlight .btn__well { color: var(--deep); }
.btn--onlight:hover .btn__label,
.btn--onlight:focus-visible .btn__label { color: var(--deep); }

@media (prefers-reduced-motion: reduce) {
  .btn__fill, .btn__label, .btn__well svg { transition: none; }
  .btn--well:hover .btn__fill, .btn--well:focus-visible .btn__fill { transform: scaleX(0); }
  .btn--well:hover .btn__label, .btn--well:focus-visible .btn__label { color: inherit; }
}


/* --------------------------------------------------------------------------
   27. Stack card detail
   -------------------------------------------------------------------------- */

/* Oversized step numeral, clipped by the card — gives scale and reads as a
   step marker before you have read a word. */
.stack__ghost {
  position: absolute;
  left: -18px;
  bottom: -64px;
  font-size: 200px;
  line-height: .8;
  font-weight: var(--w-bold);
  letter-spacing: -8px;
  color: currentColor;
  opacity: .07;
  pointer-events: none;
  user-select: none;
}

.stack__text { position: relative; z-index: 2; }

/* Two short facts give the card body without returning to paragraphs. */
.stack__facts { display: flex; flex-wrap: wrap; gap: var(--s-8); margin-top: var(--s-4); }
.stack__fact {
  display: inline-flex;
  align-items: baseline;
  gap: var(--s-8);
  padding: var(--s-8) var(--s-16);
  border-radius: var(--r-pill);
  font-size: var(--t-small);
  background: rgba(255,255,255,.12);
}
.stack__fact b { font-weight: var(--w-medium); }
.stack__fact span { opacity: .7; }
.stack__card--3 .stack__fact { background: rgba(43, 15, 10,.1); }

/* Soft halo so the animation is seated rather than floating in dead space. */
.stack__visual { position: relative; z-index: 2; display: grid; place-items: center; }
.stack__visual::before {
  content: "";
  position: absolute;
  width: 78%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255,255,255,.22) 0%, transparent 68%);
}
.stack__card--3 .stack__visual::before {
  background: radial-gradient(circle, rgba(255,255,255,.85) 0%, transparent 68%);
}
.phase-art { max-width: 250px; }

@media (max-width: 1000px) {
  .stack__ghost { font-size: 150px; bottom: -46px; }
  .phase-art { max-width: 200px; }
}


/* --------------------------------------------------------------------------
   28. Legal pages
   Narrow measure, quiet hierarchy, generous leading. Nothing decorative —
   these pages are read, not scanned.
   -------------------------------------------------------------------------- */

.legal { padding-block: var(--s-80) var(--s-120); }
.legal__inner { max-width: 46rem; margin-inline: auto; }

.legal__head { display: flex; flex-direction: column; gap: var(--s-16); margin-bottom: var(--s-40); }
.legal__meta { font-size: var(--t-small); color: var(--ink-35); }

/* Draft banner — these are starting points, not cleared documents. */
.legal__notice {
  border-radius: var(--r-card);
  background: rgba(255, 90, 60, .1);
  box-shadow: inset 0 0 0 1px rgba(255, 90, 60, .35);
  padding: var(--s-20) var(--s-24);
  display: flex;
  gap: var(--s-16);
  margin-bottom: var(--s-48);
}
.legal__notice svg { color: var(--accent); flex-shrink: 0; margin-top: 2px; }
.legal__notice p { font-size: var(--t-small); color: var(--ink-80); line-height: 1.6; }
.legal__notice b { color: var(--ink); font-weight: var(--w-medium); }

.legal__toc {
  display: flex; flex-wrap: wrap; gap: var(--s-8);
  margin-bottom: var(--s-56);
  padding-bottom: var(--s-32);
  border-bottom: 1px solid var(--ink-10);
}
.legal__toc a {
  font-size: var(--t-small);
  color: var(--ink-50);
  padding: var(--s-4) var(--s-12);
  border-radius: var(--r-pill);
  background: var(--ink-10);
  transition: color var(--d-micro) var(--e-out), background-color var(--d-micro) var(--e-out);
}
.legal__toc a:hover { color: var(--ink); background: var(--ink-15); }

.legal__body { display: flex; flex-direction: column; gap: var(--s-48); }

.legal__section { display: flex; flex-direction: column; gap: var(--s-16); scroll-margin-top: 110px; }
.legal__section h2 {
  font-size: var(--t-subheading);
  font-weight: var(--w-medium);
  letter-spacing: -.2px;
  color: var(--ink);
}
.legal__section p,
.legal__section li { color: var(--ink-50); line-height: 1.7; }
.legal__section strong { color: var(--ink-80); font-weight: var(--w-medium); }
.legal__section a { color: var(--accent); }

.legal__list { display: flex; flex-direction: column; gap: var(--s-12); padding-left: var(--s-20); }
.legal__list li { list-style: disc; }
.legal__list li::marker { color: var(--ink-35); }

.legal__table { width: 100%; border-collapse: collapse; font-size: var(--t-small); }
.legal__table th, .legal__table td {
  text-align: left; padding: var(--s-12) var(--s-16);
  border-bottom: 1px solid var(--ink-10); vertical-align: top;
}
.legal__table th { color: var(--ink-80); font-weight: var(--w-medium); }
.legal__table td { color: var(--ink-50); }
.legal__scroll { overflow-x: auto; }

@media (max-width: 640px) {
  .legal { padding-block: var(--s-56) var(--s-80); }
  .legal__body { gap: var(--s-40); }
}


/* --------------------------------------------------------------------------
   29. Job board
   Three filters over a list grouped by department. Filtering is live and
   the result count is announced, so keyboard and screen-reader users get
   the same feedback as everyone else.
   -------------------------------------------------------------------------- */

.jobs { display: flex; flex-direction: column; gap: var(--s-32); }

.jobs__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-12);
  padding-bottom: var(--s-24);
  border-bottom: 1px solid var(--ink-10);
}

.jobs__filter {
  appearance: none;
  background: var(--ink-10);
  border: 0;
  border-radius: var(--r-pill);
  padding: var(--s-12) var(--s-40) var(--s-12) var(--s-20);
  font-size: var(--t-small);
  font-weight: var(--w-medium);
  color: var(--ink);
  cursor: pointer;
  /* chevron */
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--s-16) center;
  transition: background-color var(--d-micro) var(--e-out);
}
.jobs__filter:hover { background-color: var(--ink-15); }
.jobs__filter option { background: var(--surface-2); color: var(--ink); }
.jobs__filter[data-active="true"] { background-color: var(--accent); color: #fff; }

.jobs__clear {
  background: none; border: 0; cursor: pointer;
  font-size: var(--t-small); color: var(--ink-35);
  padding: var(--s-8) var(--s-12); border-radius: var(--r-pill);
  transition: color var(--d-micro) var(--e-out);
}
.jobs__clear:hover { color: var(--ink); }
.jobs__count { margin-left: auto; font-size: var(--t-small); color: var(--ink-35); }

.jobs__group { display: flex; flex-direction: column; gap: var(--s-4); margin-bottom: var(--s-40); }
.jobs__group h3 {
  font-size: var(--t-small);
  font-weight: var(--w-medium);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--s-12);
}

.job {
  display: grid;
  grid-template-columns: 1fr auto auto 28px;
  align-items: center;
  gap: var(--s-20);
  padding: var(--s-20) var(--s-8);
  border-top: 1px solid var(--ink-10);
  transition: background-color var(--d-micro) var(--e-out);
}
.jobs__group .job:last-child { border-bottom: 1px solid var(--ink-10); }
.job:hover { background: var(--ink-10); }
.job:hover .job__title { transform: translateX(4px); }
.job__title { display: inline-block; transition: transform var(--d-micro) var(--e-out); }

.job__title { font-size: var(--t-lede); font-weight: var(--w-medium); color: var(--ink); }
.job__desc  { font-size: var(--t-small); color: var(--ink-35); margin-top: 2px; }
.job__meta  {
  font-size: var(--t-small); color: var(--ink-50);
  padding: var(--s-4) var(--s-12);
  border-radius: var(--r-pill);
  background: var(--ink-10);
  white-space: nowrap;
}
.job__go { color: var(--ink-35); display: grid; place-items: center; transition: color var(--d-micro) var(--e-out), transform var(--d-micro) var(--e-out); }
.job:hover .job__go { color: var(--ink); transform: translateX(3px); }

.jobs__empty {
  padding: var(--s-56) var(--s-24);
  text-align: center;
  color: var(--ink-35);
  border: 1px dashed var(--ink-15);
  border-radius: var(--r-panel);
}

@media (max-width: 760px) {
  .job { grid-template-columns: 1fr auto; row-gap: var(--s-8); }
  .job__go { display: none; }
  .jobs__count { margin-left: 0; width: 100%; }
}


/* Secondary action inside the CTA panel */
.cta .btn--sub {
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
  transition: background-color var(--d-micro) var(--e-out);
}
.cta .btn--sub:hover { background: rgba(255, 255, 255, 0.24); }

@media (max-width: 640px) { .cta { padding: var(--s-64) var(--s-24); } }
