/* ============================================================
   ClientBridgeUSA — design system
   Restrained and technical. Cool neutrals, one navy accent, a
   grotesk for headings and mono for labels and figures.
   No build step: this file is authored to be read and edited by hand.
   ============================================================ */

:root {
  /* ---- Colour ---------------------------------------------
     Cool neutrals, not cream. The previous warm paper (#fbfaf7)
     plus a serif read as a book jacket — the warmth is most of
     what made it feel like a candle shop rather than a software
     company. Same navy accent, colder ground under it. */
  --paper:        #f7f8fa;
  --paper-sunk:   #eef1f5;   /* alternating section bands */
  --surface:      #ffffff;
  --ink:          #12151a;   /* body + headings */
  --ink-soft:     #48505c;   /* secondary prose */
  /* #7c7c86 looked right but measured 3.96:1 on paper — under the
     4.5:1 floor for 13px eyebrows and captions. Darkened until it
     passes on both --paper and --paper-sunk. */
  --ink-mute:     #5c6672;   /* captions, meta, eyebrows */
  --rule:         #e1e6ec;   /* hairlines — never a heavy border */
  --rule-strong:  #c7d0da;

  /* The navy stays as the deep tone — it is the brand. What was
     missing is something bright to carry energy: --brand is the live
     accent for CTAs, links and highlights, with the navy behind it as
     the dark ground. One warm note (--spark) for small moments only. */
  /* Taken from the logo file, not chosen independently — the mark
     should drive the palette. They also measure better than the values
     they replaced: white on #0359E9 is 5.82:1 (was 5.17 on #2563EB),
     and #072E58 is 13.63:1 (was 11.43 on #1B3B5F). */
  --accent:       #072e58;   /* logo navy — dark bands, deep tone */
  --accent-deep:  #04203f;
  --accent-tint:  #eaf1fe;
  --accent-ring:  rgba(3, 89, 233, 0.35);

  --brand:        #0359e9;   /* logo blue — buttons, links, focus */
  --brand-hi:     #2b7bff;
  --brand-lo:     #0246b8;
  --spark:        #f59e0b;   /* used sparingly, for warmth */
  --grad:         linear-gradient(115deg, #0359e9 0%, #0a8fd6 55%, #22d3ee 100%);
  --grad-soft:    linear-gradient(115deg, rgba(3,89,233,0.10), rgba(34,211,238,0.10));

  /* Dark band tokens, so a full-bleed dark section is a class rather
     than a pile of overrides. */
  --night:        #04182f;   /* logo navy, darkened — same family */
  --night-2:      #0a2242;
  --night-ink:    #eef2f8;
  --night-soft:   #9fb0c9;
  --night-rule:   rgba(255,255,255,0.12);

  /* ---- Type ------------------------------------------------
     Sizes are fluid so nothing needs a media query just to stop a
     headline overflowing.
     Space Grotesk is a grotesk with engineered detailing — the
     flat-sided round letters and the single-storey 'a' read as
     technical without tipping into neon-startup. Inter carries the
     body text; the mono is used for eyebrows, labels and figures,
     which is what actually signals "software" to a reader. */
  --font-display: 'Space Grotesk', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-sans:    'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --font-mono:    'JetBrains Mono', ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;

  --text-xs:   0.8125rem;  /* 13px — the floor. Nothing smaller. */
  --text-sm:   0.9375rem;  /* 15px */
  --text-base: 1.0625rem;  /* 17px — body copy, generous on purpose */
  --text-lg:   1.1875rem;
  --text-xl:   clamp(1.35rem, 1.1rem + 0.8vw,  1.7rem);
  --text-2xl:  clamp(1.8rem,  1.3rem + 1.8vw,  2.6rem);
  --text-3xl:  clamp(2.3rem,  1.5rem + 3.4vw,  4.0rem);
  /* Display scale. The old cap of 4.4rem was article-sized; a hero
     headline is the loudest thing on the page or it is not a hero. */
  --text-4xl:  clamp(3rem,    1.6rem + 6.6vw,  6.5rem);

  /* ---- Space ---------------------------------------------- */
  --gap-1: 0.5rem;
  --gap-2: 0.875rem;
  --gap-3: 1.25rem;
  --gap-4: 2rem;
  --gap-5: 3rem;
  --gap-6: 4.5rem;
  --section-y: clamp(4.5rem, 3rem + 6vw, 8.5rem);

  --container: 74rem;
  --measure:   38rem;      /* max line length for prose */
  --radius:    4px;        /* barely there. Big radii read cheap. */
  --radius-lg: 8px;

  --shadow-sm: 0 1px 2px rgba(23, 23, 26, 0.05);
  --shadow-md: 0 12px 32px -12px rgba(23, 23, 26, 0.16);
}

/* ---- Reset ------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: 1.65;
  font-feature-settings: 'kern' 1, 'liga' 1;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.022em;   /* grotesks need tighter tracking than a serif */
  color: var(--ink);
  margin: 0;
  text-wrap: balance;
}
h1 { font-size: var(--text-4xl); letter-spacing: -0.032em; }
h2 { font-size: var(--text-3xl); }
h3 { font-size: var(--text-xl); letter-spacing: -0.01em; }
h4 { font-size: var(--text-lg); }

p { margin: 0; }
p.lede {
  font-size: var(--text-lg);
  color: var(--ink-soft);
  line-height: 1.6;
  max-width: var(--measure);
  text-wrap: pretty;
}

a { color: var(--brand); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--brand-lo); }

/* Every focusable thing gets a visible ring. Non-negotiable. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 3px;
  border-radius: 2px;
}

/* ---- Layout ----------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 4vw, 2.5rem);
  /* Grid and flex children default to min-width:auto and refuse to
     shrink below their content — which is how a page ends up
     scrolling sideways on a phone. Released here and on every
     column wrapper below. */
  min-width: 0;
}

.section { padding-block: var(--section-y); }
.section--sunk { background: var(--paper-sunk); }
.section--ruled { border-top: 1px solid var(--rule); }

.stack   { display: flex; flex-direction: column; gap: var(--gap-3); min-width: 0; }
.stack-4 { display: flex; flex-direction: column; gap: var(--gap-4); min-width: 0; }

.grid { display: grid; gap: var(--gap-4); min-width: 0; }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); }

/* Exactly four items. auto-fit cannot be trusted here: whatever minimum
   you pick, some viewport lands on three columns and strands the fourth
   alone on its own row. Explicit counts go 1 -> 2 -> 4 and can never
   orphan. Use only for grids that really do hold four. */
.grid--quad { grid-template-columns: 1fr; }
@media (min-width: 48rem) { .grid--quad { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 72rem) { .grid--quad { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* ---- Section headers -------------------------------------- */
.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.06em;   /* mono is already wide; less tracking needed */
  text-transform: uppercase;
  color: var(--ink-mute);
  margin: 0 0 var(--gap-2);
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.eyebrow::before {
  content: '';
  width: 1.75rem;
  height: 1px;
  background: var(--rule-strong);
  flex: none;
}

.section-head { max-width: 46rem; margin-bottom: var(--gap-5); }
.section-head h2 { margin-bottom: var(--gap-2); }

/* ---- Buttons ----------------------------------------------
   44px minimum target on every interactive control. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  min-height: 44px;
  padding: 0.7rem 1.4rem;
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: 550;
  line-height: 1.2;
  border-radius: var(--radius);
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  transition: background-color 0.16s ease, border-color 0.16s ease, color 0.16s ease, transform 0.16s ease;
}
.btn:active { transform: translateY(1px); }

.btn--primary { background: var(--brand); color: #fff; }
.btn--primary:hover { background: var(--brand-lo); color: #fff; }

.btn--outline { background: transparent; color: var(--ink); border-color: var(--rule-strong); }
.btn--outline:hover { border-color: var(--ink); color: var(--ink); background: var(--surface); }

.btn--quiet { background: transparent; color: var(--brand); padding-inline: 0.25rem; }
.btn--quiet:hover { color: var(--brand-lo); }

.btn-row { display: flex; flex-wrap: wrap; gap: var(--gap-2); align-items: center; }

/* ---- Header ------------------------------------------------ */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: saturate(140%) blur(10px);
  border-bottom: 1px solid var(--rule);
}
.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap-3);
  min-height: 68px;
  min-width: 0;
}
/* The lockup: the real logo + the name as live text in the site's own
   display face, so the logo and the site share one typeface.
   Height-constrained with width:auto — the file is 2.41:1 and forcing
   a square on it would squash the span. The square marks in assets/
   are ONLY for slots that must be square (favicon, app icon, avatar);
   anywhere with horizontal room uses the real logo. */
.wordmark__mark {
  height: 28px;
  width: auto;
  flex: none;
}
.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--font-display);
  font-size: 1.2rem;
  font-weight: 600;
  letter-spacing: -0.035em;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}
.wordmark span { color: var(--accent); }

.nav { display: flex; align-items: center; gap: 0.35rem; }
/* :not(.btn) matters — a bare `.nav a` selector (0-1-1) outranks
   `.btn--primary` (0-1-0) and repaints the button's label in body
   grey on the navy fill, which is unreadable. The .btn component
   owns its own colours wherever it appears. */
.nav a:not(.btn) {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 0.7rem;
  /* Without this, "How it works" and "Who we serve" break onto two
     lines as soon as the bar gets tight — which it did the moment the
     logo mark took horizontal space. */
  white-space: nowrap;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--ink-soft);
  text-decoration: none;
  border-radius: var(--radius);
}
.nav a:not(.btn):hover { color: var(--ink); background: var(--paper-sunk); }
.nav a:not(.btn)[aria-current='page'] { color: var(--ink); font-weight: 600; }

.nav-toggle { display: none; }

@media (max-width: 66rem) {
  /* The old site hid the sidebar below 900px with nothing in its
     place. Here the same links move into a disclosure panel —
     one nav, not two. */
  .nav-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px; height: 44px;
    background: transparent;
    border: 1px solid var(--rule-strong);
    border-radius: var(--radius);
    color: var(--ink);
  }
  .nav {
    position: absolute;
    inset-inline: 0;
    top: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: var(--gap-2) clamp(1.25rem, 4vw, 2.5rem) var(--gap-3);
    background: var(--paper);
    border-bottom: 1px solid var(--rule);
    box-shadow: var(--shadow-md);
  }
  .nav[hidden] { display: none; }
  .nav a:not(.btn) { padding-inline: 0; border-bottom: 1px solid var(--rule); }
  .nav .btn { margin-top: var(--gap-2); }
}

/* ---- Hero -------------------------------------------------- */
.hero { padding-block: clamp(3.5rem, 2rem + 7vw, 7.5rem) var(--section-y); }
.hero h1 { max-width: 20ch; margin-bottom: var(--gap-3); }
.hero .lede { font-size: clamp(1.0625rem, 1rem + 0.4vw, 1.28rem); margin-bottom: var(--gap-4); }
.hero__note {
  margin-top: var(--gap-3);
  font-size: var(--text-sm);
  color: var(--ink-mute);
}

/* ---- Proof strip ------------------------------------------- */
.proof {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
  gap: 1px;
  background: var(--rule);
  border-block: 1px solid var(--rule);
  min-width: 0;
}
.proof__item { background: var(--paper); padding: var(--gap-4) var(--gap-3); min-width: 0; }
.proof__value {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 600;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  margin-bottom: 0.3rem;
}
.proof__label { font-size: var(--text-sm); color: var(--ink-soft); line-height: 1.5; }

/* ---- Cards -------------------------------------------------
   Hairline + generous padding. No drop shadows on resting state:
   shadowed cards everywhere is the look we're moving away from. */
.card {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  padding: var(--gap-4);
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--gap-2);
}
.card__kicker {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

/* ---- Live vs unreleased -------------------------------------
   Four of these are sellable today and one is not. They were carrying
   identical visual weight, so the page gave a product in development
   the same billing as the ones that earn money. */
.card--live {
  position: relative;
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
/* Gradient edge — the same one used on the hero and the callout, so
   "this is live" is a colour the visitor has already learned. */
.card--live::before {
  content: '';
  position: absolute;
  top: 0; left: 0; bottom: 0;
  width: 3px;
  background: var(--grad);
}
.card--live .card__kicker {
  color: var(--brand-lo);
  display: flex;
  align-items: center;
  gap: 0.45rem;
}
.card--live .card__kicker::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--brand);
  flex: none;
  animation: live-pulse 2.2s ease-in-out infinite;
}
@keyframes live-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
@media (prefers-reduced-motion: reduce) {
  .card--live .card__kicker::before { animation: none; }
}

/* Deliberately quieter: no fill, no shadow, dashed edge, and no hover
   lift — nothing here invites a click, because there is nothing to buy
   yet. Text still meets contrast; quiet is not the same as unreadable. */
.card--soon {
  background: transparent;
  border-style: dashed;
  box-shadow: none;
}
.card--soon h3 { color: var(--ink-soft); }
.card p { color: var(--ink-soft); font-size: var(--text-sm); line-height: 1.6; }

/* ---- Numbered process -------------------------------------- */
.steps { counter-reset: step; display: grid; gap: 0; min-width: 0; }
.step {
  counter-increment: step;
  display: grid;
  grid-template-columns: 4.5rem 1fr;
  gap: var(--gap-3);
  padding-block: var(--gap-4);
  border-top: 1px solid var(--rule);
  min-width: 0;
}
.step:last-child { border-bottom: 1px solid var(--rule); }
.step::before {
  content: counter(step, decimal-leading-zero);
  font-family: var(--font-mono);
  font-size: var(--text-lg);
  font-weight: 500;
  color: var(--brand);
  font-variant-numeric: tabular-nums;
}
.step h3 { margin-bottom: 0.35rem; }
.step p { color: var(--ink-soft); font-size: var(--text-sm); max-width: var(--measure); }

@media (max-width: 34rem) {
  .step { grid-template-columns: 1fr; gap: var(--gap-1); }
}

/* ---- Pricing ----------------------------------------------- */
.plans { display: grid; gap: var(--gap-3); grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr)); min-width: 0; }
.plan {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  padding: var(--gap-4);
  display: flex;
  flex-direction: column;
  gap: var(--gap-3);
  min-width: 0;
}
.plan--featured { border-color: var(--brand); box-shadow: 0 24px 50px -30px rgba(37,99,235,0.55); }
.plan__name { font-family: var(--font-display); font-size: var(--text-xl); font-weight: 600; letter-spacing: -0.02em; }
.plan__price { font-family: var(--font-display); font-size: var(--text-lg); font-weight: 600; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.plan__price small { display: block; font-size: var(--text-sm); font-weight: 400; color: var(--ink-mute); letter-spacing: 0; }
.plan__desc { font-size: var(--text-sm); color: var(--ink-soft); }
.plan ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.55rem; }
.plan li {
  position: relative;
  padding-left: 1.5rem;
  font-size: var(--text-sm);
  color: var(--ink-soft);
  line-height: 1.5;
}
.plan li::before {
  content: '';
  position: absolute;
  left: 0; top: 0.55em;
  width: 0.5rem; height: 0.5rem;
  border-radius: 50%;
  background: var(--accent-tint);
  border: 1px solid var(--accent-ring);
}
.plan .btn { margin-top: auto; }

.tag {
  display: inline-block;
  align-self: flex-start;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--brand-lo);
  background: var(--accent-tint);
  border-radius: 999px;
  padding: 0.25rem 0.7rem;
}

/* ---- Industries -------------------------------------------- */
.tiles { display: grid; gap: 1px; background: var(--rule); border: 1px solid var(--rule); border-radius: var(--radius-lg); overflow: hidden; grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr)); min-width: 0; }
.tile { background: var(--surface); padding: var(--gap-4) var(--gap-3); min-width: 0; text-decoration: none; color: inherit; display: block; }
.tile:hover { background: var(--accent-tint); }
.tile h3 { font-size: var(--text-lg); margin-bottom: 0.3rem; }
.tile p { font-size: var(--text-sm); color: var(--ink-mute); }

/* ---- Page hero (interior pages) ---------------------------- */
.page-hero { padding-block: clamp(2.75rem, 2rem + 4vw, 5rem) clamp(2rem, 1.5rem + 3vw, 3.5rem); border-bottom: 1px solid var(--rule); }
.page-hero h1 { max-width: 18ch; margin-bottom: var(--gap-3); }
.page-hero .lede { max-width: 44rem; }

/* ---- Feature rows (alternating detail blocks) --------------- */
.feature {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
  gap: clamp(2rem, 1rem + 4vw, 4rem);
  align-items: start;
  padding-block: var(--gap-5);
  border-top: 1px solid var(--rule);
  min-width: 0;
}
.feature:first-of-type { border-top: 0; }
.feature__body { min-width: 0; }
.feature__body h2 { margin-bottom: var(--gap-2); }
.feature__body p { color: var(--ink-soft); max-width: var(--measure); }

/* Small illustrative panels — a mocked chat thread, a sequence
   timeline. Deliberately flat: these illustrate, they don't shout. */
.panel {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  overflow: hidden;
  min-width: 0;
}
.panel__bar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.7rem var(--gap-3);
  border-bottom: 1px solid var(--rule);
  background: var(--paper-sunk);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-mute);
}
.panel__body { padding: var(--gap-3); display: flex; flex-direction: column; gap: var(--gap-2); }

.bubble { max-width: 85%; padding: 0.65rem 0.9rem; border-radius: var(--radius-lg); font-size: var(--text-sm); line-height: 1.5; }
.bubble--them { background: var(--paper-sunk); color: var(--ink); align-self: flex-start; border-bottom-left-radius: 2px; }
.bubble--us { background: var(--accent); color: #fff; align-self: flex-end; border-bottom-right-radius: 2px; }
.bubble__who { display: block; font-size: var(--text-xs); color: var(--ink-mute); margin-bottom: 0.25rem; }
.bubble--us .bubble__who { color: rgba(255,255,255,0.75); }

/* ---- Timeline ---------------------------------------------- */
.timeline { display: grid; gap: 0; min-width: 0; }
.timeline__row {
  display: grid;
  grid-template-columns: 7.5rem 1fr;
  gap: var(--gap-3);
  padding-block: var(--gap-3);
  border-top: 1px solid var(--rule);
  min-width: 0;
}
.timeline__row:last-child { border-bottom: 1px solid var(--rule); }
.timeline__when {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--brand);
  font-variant-numeric: tabular-nums;
}
.timeline__what h3 { font-size: var(--text-lg); margin-bottom: 0.2rem; }
.timeline__what p { font-size: var(--text-sm); color: var(--ink-soft); max-width: var(--measure); }
@media (max-width: 34rem) { .timeline__row { grid-template-columns: 1fr; gap: 0.25rem; } }

/* ---- Comparison table --------------------------------------
   Scrolls inside its own container rather than pushing the page
   sideways — the wrapper must be the thing that overflows. */
.table-wrap { overflow-x: auto; border: 1px solid var(--rule); border-radius: var(--radius-lg); background: var(--surface); min-width: 0; }
.table-wrap table { border-collapse: collapse; width: 100%; min-width: 40rem; font-size: var(--text-sm); }
.table-wrap th, .table-wrap td { padding: 0.85rem var(--gap-3); text-align: left; border-bottom: 1px solid var(--rule); }
.table-wrap thead th {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-mute);
  background: var(--paper-sunk);
  white-space: nowrap;
}
.table-wrap tbody th { font-weight: 500; color: var(--ink); }
.table-wrap td { color: var(--ink-soft); }
.table-wrap tr:last-child th, .table-wrap tr:last-child td { border-bottom: 0; }

/* ---- The comparison column that matters ---------------------
   This table is the closing argument on the services page — the block
   that answers "why not a cheaper agency or a template builder". It was
   rendering as a neutral spreadsheet where all three columns looked
   equally plausible. Ours now reads as the answer. */
.table-wrap th.col-us-head {
  background: var(--brand);
  color: #fff;
  font-weight: 600;
  letter-spacing: 0.04em;
}
.table-wrap .col-us {
  background: var(--accent-tint);
  color: var(--ink);
  font-weight: 600;
  /* Inset edges rather than borders, so the column reads as a single
     continuous band down the table instead of stacked cells. */
  box-shadow: inset 1px 0 0 var(--accent-ring), inset -1px 0 0 var(--accent-ring);
}
/* A tick before each of our values. Decorative, so it is hidden from
   assistive tech — the cell text already says what it says. */
.table-wrap .col-us::before {
  content: '';
  display: inline-block;
  width: 0.85em;
  height: 0.85em;
  margin-right: 0.45rem;
  vertical-align: -0.08em;
  background: var(--brand);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M6.2 12.5 2 8.3l1.4-1.4 2.8 2.8 6.4-6.4L14 4.7z'/%3E%3C/svg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M6.2 12.5 2 8.3l1.4-1.4 2.8 2.8 6.4-6.4L14 4.7z'/%3E%3C/svg%3E") no-repeat center / contain;
}
.table-wrap tbody tr:hover .col-us { background: #dfeafe; }

/* ---- FAQ (native disclosure — no JS) ------------------------ */
.faq { border-top: 1px solid var(--rule); min-width: 0; }
.faq details { border-bottom: 1px solid var(--rule); }
.faq summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--gap-3);
  min-height: 44px;
  padding-block: var(--gap-3);
  cursor: pointer;
  font-weight: 600;
  font-size: var(--text-lg);
  font-family: var(--font-display);
  list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: '+';
  font-family: var(--font-sans);
  font-size: 1.4rem;
  font-weight: 400;
  color: var(--ink-mute);
  flex: none;
  line-height: 1;
}
.faq details[open] summary::after { content: '−'; }
.faq details p { padding-bottom: var(--gap-3); color: var(--ink-soft); font-size: var(--text-sm); max-width: var(--measure); }

/* ---- Forms -------------------------------------------------- */
.form-grid { display: grid; gap: var(--gap-3); grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); min-width: 0; }
.field { display: flex; flex-direction: column; gap: 0.4rem; min-width: 0; }
.field--full { grid-column: 1 / -1; }
.field label { font-size: var(--text-sm); font-weight: 550; color: var(--ink); }
.field .req { color: var(--accent); }
.field input, .field select, .field textarea {
  font-family: var(--font-sans);
  font-size: var(--text-base);   /* 16px+ stops iOS zooming the page on focus */
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius);
  padding: 0.7rem 0.85rem;
  min-height: 44px;
  width: 100%;
  min-width: 0;
}
.field textarea { min-height: 9rem; resize: vertical; line-height: 1.6; }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--brand); }
.field input::placeholder, .field textarea::placeholder { color: var(--ink-mute); }
.form-note { font-size: var(--text-sm); color: var(--ink-mute); }

/* ---- Prose (legal pages) ------------------------------------ */
.prose { max-width: 44rem; min-width: 0; }
.prose h2 { font-size: var(--text-2xl); margin-top: var(--gap-5); margin-bottom: var(--gap-2); }
.prose h3 { margin-top: var(--gap-4); margin-bottom: var(--gap-1); }
.prose p, .prose li { color: var(--ink-soft); }
.prose p { margin-bottom: var(--gap-2); }
.prose ul, .prose ol { margin: 0 0 var(--gap-3); padding-left: 1.3rem; display: flex; flex-direction: column; gap: 0.45rem; }
.prose a { color: var(--accent); }
.prose > *:first-child { margin-top: 0; }

.toc { background: var(--paper-sunk); border: 1px solid var(--rule); border-radius: var(--radius-lg); padding: var(--gap-3) var(--gap-4); margin-bottom: var(--gap-5); }
.toc ol { margin: 0; padding-left: 1.2rem; columns: 2; column-gap: var(--gap-4); }
.toc li { margin-bottom: 0.4rem; break-inside: avoid; }
@media (max-width: 34rem) { .toc ol { columns: 1; } }

.notice {
  border-left: 3px solid var(--brand);
  background: var(--accent-tint);
  padding: var(--gap-3) var(--gap-4);
  border-radius: 0 var(--radius) var(--radius) 0;
  margin-bottom: var(--gap-4);
}
.notice h3 { font-size: var(--text-lg); margin-bottom: 0.35rem; }
.notice p { margin-bottom: 0; }

/* ---- Contact methods ---------------------------------------- */
.methods { display: grid; gap: var(--gap-3); grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); min-width: 0; }
.method {
  display: block;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  padding: var(--gap-3) var(--gap-4);
  text-decoration: none;
  color: inherit;
  min-width: 0;
}
.method:hover { border-color: var(--brand); background: var(--accent-tint); }
.method__label { font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase; color: var(--ink-mute); margin-bottom: 0.35rem; }
/* overflow-wrap, not word-break: word-break splits mid-word wherever it
   runs out of room, which turned the email into "hello@clientbridgeu /
   sa.com". overflow-wrap prefers a legal break opportunity first, and
   the markup carries a <wbr> after the @ so the split lands there. */
.method__value {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 600;
  margin-bottom: 0.2rem;
  overflow-wrap: break-word;
  hyphens: none;
}
.method__note { font-size: var(--text-sm); color: var(--ink-soft); }

/* ---- Callout ----------------------------------------------- */
.callout {
  background: var(--accent);
  /* Gradient over the navy, so the closing block is the brightest
     thing on the page rather than another flat slab. The solid
     colour above is the fallback if the gradient is unsupported. */
  background-image: var(--grad);
  color: #fff;
  border-radius: 14px;
  padding: clamp(2rem, 1rem + 4vw, 4rem);
  min-width: 0;
}
.callout h2, .callout p { color: #fff; }
.callout p { color: rgba(255,255,255,0.82); max-width: var(--measure); }
.callout .btn--primary { background: #fff; color: var(--accent); }
.callout .btn--primary:hover { background: #f0eee9; color: var(--accent-deep); }
.callout .btn--outline { color: #fff; border-color: rgba(255,255,255,0.4); }
.callout .btn--outline:hover { background: rgba(255,255,255,0.1); border-color: #fff; color: #fff; }

/* ---- Footer ------------------------------------------------ */
.site-footer { border-top: 1px solid var(--rule); padding-block: var(--gap-6) var(--gap-4); font-size: var(--text-sm); }

/* One grid, not a grid nested inside half of another grid. The old
   markup put a three-column grid inside the right half of a two-column
   one, so each link column only ever got ~520px — below the 17rem
   minimum, which collapsed all three into a single stacked column on
   every ordinary laptop.
   Explicit counts: 1 up to 48rem, then the brand takes its own row
   above three link columns, then all four sit in one row at 72rem. */
.site-footer__grid {
  display: grid;
  gap: var(--gap-4);
  grid-template-columns: 1fr;
  align-items: start;
  min-width: 0;
}
@media (min-width: 48rem) {
  .site-footer__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .site-footer__brand { grid-column: 1 / -1; }
}
@media (min-width: 72rem) {
  .site-footer__grid { grid-template-columns: 1.3fr repeat(3, minmax(0, 1fr)); gap: var(--gap-5); }
  .site-footer__brand { grid-column: auto; }
}
.site-footer h4 {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin-bottom: var(--gap-2);
}
.site-footer ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.site-footer a { color: var(--ink-soft); text-decoration: none; }
.site-footer a:hover { color: var(--ink); text-decoration: underline; }
.site-footer__bottom {
  margin-top: var(--gap-5);
  padding-top: var(--gap-3);
  border-top: 1px solid var(--rule);
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-2);
  justify-content: space-between;
  color: var(--ink-mute);
  font-size: var(--text-xs);
}

/* ============================================================
   BIG / BRIGHT / MOVING
   Everything below is what makes the page pull rather than sit.
   ============================================================ */

/* ---- Scroll reveal -----------------------------------------
   Elements start slightly low and transparent, then settle when
   they enter the viewport. Driven by IntersectionObserver.

   ⚠ The default state is VISIBLE. The hidden state is only applied
   by script, so if JS fails or never runs the page still reads —
   a reveal system that hides content by default is one broken
   script away from a blank page. */
[data-reveal].is-armed {
  opacity: 0;
  transform: translateY(22px);
}
[data-reveal].is-in {
  opacity: 1;
  transform: none;
  transition: opacity 0.62s cubic-bezier(0.22, 0.61, 0.36, 1),
              transform 0.62s cubic-bezier(0.22, 0.61, 0.36, 1);
}
/* Stagger children of a group so a grid arrives in sequence. */
[data-reveal-group].is-in > * { transition-delay: calc(var(--i, 0) * 70ms); }

@media (prefers-reduced-motion: reduce) {
  [data-reveal].is-armed { opacity: 1; transform: none; }
  [data-reveal].is-in { transition: none; }
}

/* ---- Dark full-bleed band ----------------------------------- */
.band {
  background: var(--night);
  color: var(--night-ink);
  padding-block: var(--section-y);
  position: relative;
  overflow: hidden;
  min-width: 0;
}
.band h1, .band h2, .band h3, .band h4 { color: var(--night-ink); }
.band p, .band li { color: var(--night-soft); }
.band .eyebrow { color: var(--night-soft); }
.band .eyebrow::before { background: rgba(255,255,255,0.28); }
.band .card {
  background: var(--night-2);
  border-color: var(--night-rule);
}
.band .card h3 { color: var(--night-ink); }
.band .card p { color: var(--night-soft); }
.band .btn--outline { color: var(--night-ink); border-color: rgba(255,255,255,0.32); }
.band .btn--outline:hover { background: rgba(255,255,255,0.08); border-color: #fff; color: #fff; }
/* :not(.btn) again — the same trap as `.nav a`. A bare `.band a`
   (0-1-1) outranks `.btn--primary` (0-1-0) and repaints the button
   label sky-blue on blue, which measured 3.1:1. Buttons own their
   own colours; only prose links get the light blue. */
.band a:not(.btn) { color: #7dd3fc; }
.band a:not(.btn):hover { color: #bae6fd; }

/* Components that appear inside a dark band need their own treatment —
   the light-mode panel, timeline and bubble styles all assume a pale
   ground. Grouped here rather than scattered so a band stays one class. */
.band .panel { background: var(--night-2); border-color: var(--night-rule); }
.band .panel__bar {
  background: rgba(255, 255, 255, 0.05);
  border-bottom-color: var(--night-rule);
  color: var(--night-soft);
}
.band .feature { border-top-color: var(--night-rule); }
.band .timeline__row { border-top-color: var(--night-rule); }
.band .timeline__row:last-child { border-bottom-color: var(--night-rule); }
.band .timeline__what h3 { color: var(--night-ink); }
.band .timeline__what p { color: var(--night-soft); }
/* The brand blue is too dark to sit on navy; the timeline labels take
   the lighter tint used for links inside a band. */
.band .timeline__when { color: #7dd3fc; }
.band .bubble--them { background: rgba(255, 255, 255, 0.08); color: var(--night-ink); }
.band .bubble__who { color: var(--night-soft); }
.band .timeline--rail::before { background: var(--night-rule); }
/* The brand blue is a dark navy itself, so the drawn fill would all but
   vanish against the band. On dark it runs bright-blue to cyan. */
.band .timeline--rail::after { background: linear-gradient(to bottom, #2b7bff, #22d3ee); }
.band .timeline--rail .timeline__row::before {
  background: var(--night-2);
  border-color: var(--night-rule);
}
.band .timeline--rail .timeline__row.is-in::before {
  background: #22d3ee;
  border-color: #22d3ee;
}

/* A soft light source behind the band, so it is not a flat slab. */
.band::before {
  content: '';
  position: absolute;
  top: -30%; left: 50%;
  width: min(120rem, 160%);
  aspect-ratio: 2 / 1;
  transform: translateX(-50%);
  background: radial-gradient(closest-side, rgba(37,99,235,0.30), transparent 72%);
  pointer-events: none;
}
.band > * { position: relative; }

/* ---- Gradient text / rules ---------------------------------- */
.grad-text {
  background: var(--grad);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  /* Fallback for anything that cannot clip to text. */
  -webkit-text-fill-color: transparent;
}
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .grad-text { color: var(--brand); -webkit-text-fill-color: currentColor; }
}

/* margin-inline: 0 matters — the UA stylesheet centres <hr> with auto
   margins, which floated this rule into the middle of the band. */
.rule-grad { height: 3px; border: 0; background: var(--grad); border-radius: 2px; margin-inline: 0; }

/* ---- Hero, enlarged ----------------------------------------- */
.hero--big { padding-block: clamp(4rem, 2rem + 9vw, 9rem) clamp(3rem, 2rem + 5vw, 6rem); }
.hero--big h1 { max-width: 16ch; margin-bottom: var(--gap-3); line-height: 0.98; }
.hero--big .lede { font-size: clamp(1.1rem, 1rem + 0.65vw, 1.45rem); max-width: 40rem; }

/* ---- Cards that respond ------------------------------------- */
.card--lift {
  transition: transform 0.22s cubic-bezier(0.22, 0.61, 0.36, 1),
              box-shadow 0.22s ease,
              border-color 0.22s ease;
  will-change: transform;
}
.card--lift:hover {
  transform: translateY(-4px);
  box-shadow: 0 18px 40px -22px rgba(11, 18, 32, 0.45);
  border-color: var(--brand);
}
@media (prefers-reduced-motion: reduce) {
  .card--lift:hover { transform: none; }
}
/* Touch devices get no hover state at all — a sticky :hover on tap
   looks like a stuck button. */
@media (hover: none) {
  .card--lift:hover { transform: none; box-shadow: none; border-color: var(--rule); }
}

/* ---- Big figure band ---------------------------------------- */
.figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
  gap: var(--gap-4);
  min-width: 0;
}
.figure__num {
  font-family: var(--font-display);
  font-size: clamp(2.6rem, 1.6rem + 3.4vw, 4.2rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
  margin-bottom: 0.35rem;
}
.figure__label { font-size: var(--text-sm); color: var(--night-soft); max-width: 15rem; }

/* ---- Marquee-ish capability strip --------------------------- */
.strip {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  min-width: 0;
}
.chip {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.03em;
  padding: 0.4rem 0.8rem;
  border-radius: 999px;
  border: 1px solid var(--rule);
  background: var(--surface);
  color: var(--ink-soft);
  white-space: nowrap;
}
.band .chip { background: rgba(255,255,255,0.06); border-color: var(--night-rule); color: var(--night-ink); }

/* ---- Founder block ------------------------------------------
   A face, a name and a reason. On a page whose job is trust, this is
   the part a wary buyer actually weighs. */
.founder {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--gap-4);
  align-items: center;
  min-width: 0;
}
@media (min-width: 42rem) {
  .founder { grid-template-columns: 13rem minmax(0, 1fr); gap: clamp(1.5rem, 1rem + 3vw, 3rem); }
}
.founder__photo {
  width: 100%;
  max-width: 13rem;
  aspect-ratio: 1;
  border-radius: 12px;
  object-fit: cover;
  border: 1px solid var(--rule);
  /* width/height are set on the element too, so the box is reserved
     before the file arrives and the text below does not jump. */
}
.founder__name {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 600;
  letter-spacing: -0.02em;
  margin-bottom: 0.15rem;
}
.founder__role {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin-bottom: var(--gap-2);
}
.founder__body { min-width: 0; }
.founder__body p + p { margin-top: var(--gap-2); }

/* ---- Industry picker ----------------------------------------
   Pick a trade, see what the assistant sounds like in it. Same tab
   pattern as the hero showcase but user-driven only — no auto-advance,
   because someone choosing their own industry is expressing intent and
   rotating underneath them would fight it.

   Fail-safe as everywhere else: every panel is visible until .is-live
   is added by script, and the tab strip is hidden until then. */
.picker { min-width: 0; }
.picker__tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: var(--gap-3);
  min-width: 0;
}
.picker:not(.is-live) .picker__tabs { display: none; }

.picker__tab {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.03em;
  min-height: 44px;
  padding: 0 0.9rem;
  border-radius: 999px;
  border: 1px solid var(--rule-strong);
  background: var(--surface);
  color: var(--ink-soft);
  cursor: pointer;
  white-space: nowrap;
  transition: background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}
.picker__tab:hover { color: var(--ink); border-color: var(--ink); }
.picker__tab[aria-selected='true'] { background: var(--brand); border-color: var(--brand); color: #fff; }
.picker__tab:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; }

.band .picker__tab {
  background: rgba(255, 255, 255, 0.06);
  border-color: var(--night-rule);
  color: var(--night-ink);
}
.band .picker__tab:hover { border-color: #fff; }
/* On the band the selected chip goes solid white — the brand blue is
   too close to the background to read as "chosen". */
.band .picker__tab[aria-selected='true'] { background: #fff; border-color: #fff; color: var(--accent); }

.picker.is-live .picker__stage { display: grid; }
.picker.is-live .picker__panel {
  grid-area: 1 / 1;
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px);
  transition: opacity 0.35s ease, transform 0.35s ease;
}
.picker.is-live .picker__panel.is-active { opacity: 1; visibility: visible; transform: none; }
.picker:not(.is-live) .picker__panel + .picker__panel { margin-top: var(--gap-3); }

@media (prefers-reduced-motion: reduce) {
  .picker.is-live .picker__panel { transition: none; }
}

/* ---- Timeline with a rail that draws as you scroll -----------
   Uses scroll-driven CSS animation (animation-timeline: view()), so
   the line is tied to scroll position rather than to a JS listener —
   no scroll handler, no jank, and it runs off the main thread.

   ⚠ The DEFAULT is a fully drawn line. The animation only starts it at
   zero inside @supports, so a browser without scroll-driven animations
   shows a complete rail rather than an empty one. Same principle as the
   reveals: the un-enhanced state has to look finished, not broken. */
.timeline--rail { position: relative; padding-left: 2.6rem; }

.timeline--rail::before,
.timeline--rail::after {
  content: '';
  position: absolute;
  left: 0.82rem;
  top: 0.4rem;
  bottom: 0.4rem;
  width: 2px;
  border-radius: 2px;
}
.timeline--rail::before { background: var(--rule); }          /* track */
.timeline--rail::after {
  background: var(--brand);                                    /* fill  */
  transform-origin: top center;
  transform: scaleY(1);
}

@supports (animation-timeline: view()) {
  .timeline--rail::after {
    transform: scaleY(0);
    animation: rail-draw linear both;
    animation-timeline: view();
    animation-range: entry 30% cover 65%;
  }
}
@keyframes rail-draw { to { transform: scaleY(1); } }

/* A node per row, sitting on the rail. */
.timeline--rail .timeline__row { position: relative; }
.timeline--rail .timeline__row::before {
  content: '';
  position: absolute;
  left: -2.05rem;
  top: 1.5rem;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--surface);
  border: 2px solid var(--rule-strong);
  z-index: 1;
}
.timeline--rail .timeline__row.is-in::before {
  background: var(--brand);
  border-color: var(--brand);
  transition: background-color 0.3s ease, border-color 0.3s ease;
}

@media (prefers-reduced-motion: reduce) {
  .timeline--rail::after { transform: scaleY(1); animation: none; }
}
@media (max-width: 34rem) {
  .timeline--rail { padding-left: 2rem; }
  .timeline--rail::before, .timeline--rail::after { left: 0.5rem; }
  .timeline--rail .timeline__row::before { left: -1.72rem; }
}

/* ---- Live activity stream -----------------------------------
   Rows arrive one after another, then hold. Demonstrates the product
   rather than describing it — this is what the dashboard actually
   looks like when the AI is working.

   Fail-safe again: rows are visible by default and only hidden once
   .is-armed is added by script. */
.stream__row { transition: opacity 0.5s ease, transform 0.5s ease; }
.stream.is-armed .stream__row { opacity: 0; transform: translateY(10px); }
.stream.is-armed .stream__row.is-shown { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .stream.is-armed .stream__row { opacity: 1; transform: none; }
}

/* ---- Hero showcase (rotating capability panel) --------------
   Fixed headline on the left, this on the right. The headline never
   moves, so the one message a visitor must leave with is always
   readable — only the demonstration beside it cycles.

   ⚠ FAIL-SAFE, same rule as the scroll reveals: with no JS every panel
   is simply visible, stacked down the page. The single-panel behaviour
   is switched on by adding .is-live, which only script does. A broken
   script degrades to "shows everything", never to "shows nothing". */
.hero__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(2rem, 1rem + 4vw, 4rem);
  align-items: center;
  min-width: 0;
}
/* Only split once there is genuinely room for two columns. At 62rem the
   copy column was ~470px and the display headline fragmented into five
   lines. */
@media (min-width: 72rem) {
  .hero__grid { grid-template-columns: minmax(0, 1.08fr) minmax(0, 1fr); }
  /* A display headline sized for full width is too big for half of it.
     Capped here rather than globally, so the single-column hero on a
     phone keeps its full scale. */
  .hero--big .hero__copy h1 { font-size: clamp(2.8rem, 1.2rem + 3.4vw, 4.3rem); }
}
.hero__copy { min-width: 0; }

.showcase { min-width: 0; }

.showcase__stage { min-width: 0; }
/* Grid stacking rather than absolute positioning: the stage keeps the
   height of its tallest panel, so nothing jumps as slides change. */
.showcase.is-live .showcase__stage { display: grid; }
.showcase.is-live .showcase__panel {
  grid-area: 1 / 1;
  opacity: 0;
  visibility: hidden;
  transform: translateY(8px);
  transition: opacity 0.45s ease, transform 0.45s ease;
}
.showcase.is-live .showcase__panel.is-active {
  opacity: 1;
  visibility: visible;
  transform: none;
}
/* Not live: panels just stack, each labelled. */
.showcase:not(.is-live) .showcase__panel + .showcase__panel { margin-top: var(--gap-3); }

/* ---- Tab strip with the filling bar ------------------------- */
.showcase__tabs {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.4rem;
  margin-top: var(--gap-3);
  min-width: 0;
}
.showcase:not(.is-live) .showcase__tabs { display: none; }

.showcase__tab {
  position: relative;
  display: block;
  width: 100%;
  min-height: 44px;
  /* Top padding carries the 3px the border used to occupy, so the strip
     keeps its old rhythm. */
  padding: calc(0.6rem + 3px) 0.15rem 0.5rem;
  /* ⚠ The grey track is a BACKGROUND, not a border-top, and the fill bar
     sits at top:0 rather than top:-2px. That is load-bearing: this element
     needs `overflow: hidden` for the label ellipsis, overflow clips to the
     PADDING box, and anything drawn in the border area above it is clipped
     away completely. The bar was `top: -2px` over a 2px border-top and was
     therefore invisible on every build that shipped. Don't move it back. */
  background-color: transparent;
  background-image: linear-gradient(var(--rule), var(--rule));
  background-repeat: no-repeat;
  background-size: 100% 3px;
  background-position: 0 0;
  border: 0;
  color: var(--ink-mute);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  text-align: left;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: color 0.2s ease;
}
.showcase__tab:hover { color: var(--ink); }
/* The selected tab gets a darker track, so the unfilled remainder reads as
   "time left" rather than as an inactive tab. */
.showcase__tab[aria-selected='true'] {
  color: var(--ink);
  background-image: linear-gradient(var(--rule-strong), var(--rule-strong));
}
.showcase__tab:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* The bar sits on the 2px rule above each tab. Its animation is what
   actually times the carousel — the script advances on animationend,
   so pausing the animation pauses the rotation. One clock, not two. */
.showcase__bar {
  position: absolute;
  top: 0;
  left: 0;
  height: 3px;
  width: 0;
  /* Solid, not var(--grad): a gradient background is sized to the element,
     so it would compress as the bar grows and shift colour while filling. */
  background: var(--brand);
  border-radius: 0 3px 3px 0;
  box-shadow: 0 0 10px rgba(3, 89, 233, 0.45);
}
.showcase__tab[aria-selected='true'] .showcase__bar {
  animation: sc-fill var(--dwell, 6s) linear forwards;
}
.showcase.is-paused .showcase__tab[aria-selected='true'] .showcase__bar {
  animation-play-state: paused;
}
@keyframes sc-fill { from { width: 0; } to { width: 100%; } }

/* Reduced motion: no rotation at all, and the bar sits full rather
   than animating. The tabs still work as manual controls. */
@media (prefers-reduced-motion: reduce) {
  .showcase__tab[aria-selected='true'] .showcase__bar { animation: none; width: 100%; }
  .showcase.is-live .showcase__panel { transition: none; }
}

@media (max-width: 34rem) {
  .showcase__tabs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---- Utilities --------------------------------------------- */
.muted { color: var(--ink-mute); }
/* A line break that only applies once there is room for it. */
.hide-sm { display: none; }
@media (min-width: 48rem) { .hide-sm { display: inline; } }
.measure { max-width: var(--measure); }
.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: 0.5rem; top: -3rem;
  background: var(--ink); color: #fff;
  padding: 0.6rem 1rem; border-radius: var(--radius);
  z-index: 100; transition: top 0.15s ease;
}
.skip-link:focus { top: 0.5rem; color: #fff; }
