/* ==========================================================================
   Tim LaBarge — Career Portfolio
   Design system: "Clean but bold"
   Space Grotesk display + Inter body, warm texture, color fields, motion.
   ========================================================================== */

/* Design tokens ----------------------------------------------------------- */
:root {
  /* Palette */
  --color-bg: #FAF9F6;          /* warm off-white, primary background */
  --color-text: #2B2B2B;        /* charcoal body text */
  --color-sage: #4A6B52;        /* primary accent, sage/forest green */
  --color-sage-tint: #DCE5DA;   /* light sage for section backgrounds */
  --color-terracotta: #A8654F;  /* key CTA / highlight */
  --color-gold: #C9A051;        /* small details, underlines, hovers */
  --color-lavender: #E4E0EA;    /* dusty lavender wash, very sparingly */

  --color-text-muted: #5A5A56;  /* secondary text on off-white */
  --color-sage-dark: #3B5642;   /* darker sage for hover states */
  --color-terracotta-dark: #8F5241;
  --color-cream: #F2EFE7;       /* slightly deeper warm tone for panels */

  /* Typography */
  --font-display: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI',
    sans-serif;
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
    Helvetica, Arial, sans-serif;

  /* Spacing scale */
  --space-xs: 0.5rem;
  --space-sm: 1rem;
  --space-md: 1.75rem;
  --space-lg: 3rem;
  --space-xl: 5.5rem;
  --space-2xl: 8rem;

  /* Layout */
  --max-width: 1160px;
  --max-width-narrow: 780px;
  --radius: 4px;
  --radius-lg: 10px;

  /* Motion */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --reveal-dist: 26px;
}

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

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--color-text);
  background-color: var(--color-bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  position: relative;
  overflow-x: hidden;
}

/* Warm grain / noise texture over the whole page. Fixed, non-interactive. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.05;
  mix-blend-mode: multiply;
  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='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Keep real content above the grain. */
.site-header,
main,
.site-footer {
  position: relative;
  z-index: 2;
}

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

a {
  color: var(--color-sage);
  text-decoration: none;
}

a:hover,
a:focus-visible {
  color: var(--color-sage-dark);
  text-decoration: underline;
  text-decoration-color: var(--color-gold);
  text-underline-offset: 3px;
}

:focus-visible {
  outline: 3px solid var(--color-gold);
  outline-offset: 3px;
}

main {
  flex: 1 0 auto;
}

/* Typography -------------------------------------------------------------- */
h1,
h2,
h3,
h4 {
  font-family: var(--font-display);
  line-height: 1.04;
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--color-text);
  margin: 0 0 var(--space-sm);
  text-wrap: balance;
}

h1 {
  font-size: clamp(2.75rem, 8vw, 5.75rem);
}

h2 {
  font-size: clamp(2rem, 5vw, 3.5rem);
}

h3 {
  font-size: 1.5rem;
  letter-spacing: -0.02em;
}

p {
  margin: 0 0 var(--space-sm);
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-display);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-sage);
  margin: 0 0 var(--space-md);
}

.eyebrow::before {
  content: '';
  width: 1.75rem;
  height: 2px;
  background: var(--color-gold);
}

/* Layout helpers ---------------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--max-width);
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 5vw, 2.75rem);
}

.section {
  padding-block: var(--space-xl);
  position: relative;
}

.section--tint {
  background-color: var(--color-sage-tint);
}

.section--sage {
  background-color: var(--color-sage);
  color: var(--color-bg);
}

.section--terracotta {
  background-color: var(--color-terracotta);
  color: var(--color-bg);
}

.section--narrow .container {
  max-width: var(--max-width-narrow);
}

/* Headings on solid color fields use the off-white for strong contrast. */
.section--sage h2,
.section--sage h3,
.section--terracotta h2,
.section--terracotta h3 {
  color: var(--color-bg);
}

/* Available to screen readers, removed from the visual layout. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  background: var(--color-sage);
  color: #fff;
  padding: var(--space-xs) var(--space-sm);
  z-index: 100;
  border-radius: 0 0 var(--radius) 0;
}

.skip-link:focus {
  left: 0;
}

/* Scroll progress indicator ----------------------------------------------- */
.scroll-progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 3px;
  width: 100%;
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--color-sage), var(--color-gold));
  z-index: 90;
  will-change: transform;
}

/* Buttons ----------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1;
  padding: 0.95rem 1.7rem;
  border-radius: var(--radius);
  border: 2px solid transparent;
  cursor: pointer;
  transition: background-color 0.18s ease, color 0.18s ease,
    border-color 0.18s ease, transform 0.18s var(--ease-out);
  text-decoration: none;
}

.btn:hover,
.btn:focus-visible {
  text-decoration: none;
  transform: translateY(-2px);
}

.btn--primary {
  background-color: var(--color-sage);
  color: var(--color-bg);
  border-color: var(--color-sage);
}

.btn--primary:hover,
.btn--primary:focus-visible {
  background-color: var(--color-sage-dark);
  border-color: var(--color-sage-dark);
  color: var(--color-bg);
}

.btn--accent {
  background-color: var(--color-terracotta);
  color: var(--color-bg);
  border-color: var(--color-terracotta);
}

.btn--accent:hover,
.btn--accent:focus-visible {
  background-color: var(--color-terracotta-dark);
  border-color: var(--color-terracotta-dark);
  color: var(--color-bg);
}

.btn--ghost {
  background-color: transparent;
  color: var(--color-sage);
  border-color: var(--color-sage);
}

.btn--ghost:hover,
.btn--ghost:focus-visible {
  background-color: var(--color-sage);
  color: var(--color-bg);
}

/* Buttons on color-field sections */
.section--sage .btn--ghost,
.section--terracotta .btn--ghost {
  color: var(--color-bg);
  border-color: var(--color-bg);
}

.section--sage .btn--ghost:hover,
.section--sage .btn--ghost:focus-visible {
  background-color: var(--color-bg);
  color: var(--color-sage);
}

.section--terracotta .btn--primary {
  background-color: var(--color-bg);
  color: var(--color-terracotta);
  border-color: var(--color-bg);
}

.section--terracotta .btn--primary:hover,
.section--terracotta .btn--primary:focus-visible {
  background-color: var(--color-text);
  border-color: var(--color-text);
  color: var(--color-bg);
}

.section--terracotta .btn--ghost:hover,
.section--terracotta .btn--ghost:focus-visible {
  background-color: var(--color-bg);
  color: var(--color-terracotta);
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
}

/* Site header / nav ------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background-color: rgba(250, 249, 246, 0.85);
  backdrop-filter: saturate(180%) blur(10px);
  border-bottom: 1px solid rgba(74, 107, 82, 0.14);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  padding-block: 0.9rem;
}

.brand {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.2rem;
  letter-spacing: -0.03em;
  color: var(--color-text);
}

.brand:hover,
.brand:focus-visible {
  color: var(--color-sage);
  text-decoration: none;
}

.primary-nav__toggle {
  display: none;
  background: none;
  border: 2px solid var(--color-sage);
  border-radius: var(--radius);
  color: var(--color-sage);
  padding: 0.4rem 0.7rem;
  font-family: var(--font-display);
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
}

.primary-nav__list {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  list-style: none;
  margin: 0;
  padding: 0;
}

.primary-nav__link {
  font-family: var(--font-display);
  color: var(--color-text);
  font-weight: 500;
  font-size: 1rem;
  padding-block: 0.25rem;
  border-bottom: 2px solid transparent;
}

.primary-nav__link:hover,
.primary-nav__link:focus-visible {
  color: var(--color-sage);
  text-decoration: none;
  border-bottom-color: var(--color-gold);
}

.primary-nav__link[aria-current='page'] {
  color: var(--color-sage);
  border-bottom-color: var(--color-sage);
}

/* Hero -------------------------------------------------------------------- */
.hero {
  position: relative;
  padding-block: clamp(4rem, 12vh, 9rem);
  overflow: hidden;
}

/* Layered organic shapes behind the hero type. */
.hero__backdrop {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

.hero__backdrop svg {
  position: absolute;
  bottom: -1px;
  left: 0;
  width: 100%;
  height: auto;
}

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

.hero__inner {
  max-width: 960px;
}

.hero h1 {
  margin-bottom: var(--space-md);
}

/* Kinetic hero: words animate in on load with a stagger. */
.hero h1 .word {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.5em);
  animation: word-in 0.7s var(--ease-out) forwards;
  animation-delay: calc(var(--i, 0) * 70ms);
}

@keyframes word-in {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Rotating word in the headline. */
.rotator {
  display: inline-grid;
  vertical-align: bottom;
}

.rotator__word {
  grid-area: 1 / 1;
  color: var(--color-terracotta);
  opacity: 0;
  transform: translateY(0.35em);
  transition: opacity 0.4s var(--ease-out), transform 0.4s var(--ease-out);
}

.rotator__word.is-active {
  opacity: 1;
  transform: translateY(0);
}

.rotator__word.is-leaving {
  opacity: 0;
  transform: translateY(-0.35em);
}

/* With no JS, show only the first word so the headline reads correctly. With
   JS the rotator controls visibility entirely (is-active / is-leaving), so this
   must NOT force the first word visible or it stacks under the rotating word. */
html:not(.js) .rotator__word:first-child {
  opacity: 1;
  transform: none;
}

.hero__subhead {
  font-size: clamp(1.15rem, 2vw, 1.4rem);
  color: var(--color-text-muted);
  max-width: 680px;
  margin-bottom: var(--space-lg);
}

/* Proof strip ------------------------------------------------------------- */
.proof {
  padding-block: var(--space-lg);
  border-block: 1px solid rgba(74, 107, 82, 0.16);
  background-color: var(--color-cream);
}

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

/* Full-bleed auto-scrolling track. The logo list is duplicated once in the
   markup so translateX(-50%) loops seamlessly; the duplicate copy is
   aria-hidden so screen readers only hear the real list once. Its links
   still have a real href, just tabindex="-1", so a logo stays clickable by
   mouse or touch once the marquee has scrolled the first copy out of view. */
.proof__track {
  width: 100%;
  overflow: hidden;
  margin-top: var(--space-sm);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}

.proof__logos {
  display: flex;
  align-items: center;
  gap: clamp(1.5rem, 5vw, 3.75rem);
  list-style: none;
  margin: 0;
  padding: 0;
  width: max-content;
  animation: proof-scroll 42s linear infinite;
}

.proof__track:hover .proof__logos,
.proof__track:focus-within .proof__logos {
  animation-play-state: paused;
}

@keyframes proof-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  .proof__logos {
    animation: none;
    flex-wrap: wrap;
    justify-content: center;
    width: auto;
  }

  .proof__logo[aria-hidden='true'] {
    display: none;
  }
}

.proof__logo {
  display: flex;
  align-items: center;
  height: 42px;
}

.proof__logo a {
  display: flex;
  align-items: center;
  height: 100%;
}

.proof__logo img {
  height: 34px;
  max-width: 152px;
  width: auto;
  object-fit: contain;
  filter: grayscale(1) contrast(0.95) brightness(0.8);
  mix-blend-mode: multiply;
  opacity: 0.8;
  transition: opacity 0.22s ease, filter 0.22s ease, transform 0.22s var(--ease-out);
}

.proof__logo:hover img,
.proof__logo:focus-within img {
  opacity: 1;
  filter: grayscale(0.1) contrast(1) brightness(1);
  transform: translateY(-2px);
}

/* Section heading block --------------------------------------------------- */
.section__head {
  max-width: 720px;
  margin-bottom: var(--space-lg);
}

/* Pillars ----------------------------------------------------------------- */
.pillars {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-md);
  margin-top: var(--space-lg);
  counter-reset: pillar;
}

.pillar {
  position: relative;
  background-color: var(--color-bg);
  border: 1px solid rgba(74, 107, 82, 0.18);
  border-radius: var(--radius-lg);
  padding: var(--space-md);
  overflow: hidden;
  transition: transform 0.25s var(--ease-out), border-color 0.25s ease,
    box-shadow 0.25s ease;
}

.pillar::after {
  counter-increment: pillar;
  content: '0' counter(pillar);
  position: absolute;
  top: 1rem;
  right: 1.25rem;
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 600;
  color: var(--color-gold);
  opacity: 0.8;
}

.pillar:hover {
  transform: translateY(-4px);
  border-color: var(--color-sage);
  box-shadow: 0 18px 40px -28px rgba(43, 43, 43, 0.5);
}

.pillar h3 {
  margin-bottom: 0.6rem;
  color: var(--color-sage);
  max-width: 90%;
}

.pillar p {
  margin-bottom: 0;
  color: var(--color-text);
}

/* Capabilities: clickable left list + dynamic right stage --------------- */
.capabilities {
  display: grid;
  grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr);
  gap: var(--space-lg);
  align-items: start;
  margin-top: var(--space-lg);
}

.cap-list {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.cap-item {
  display: flex;
  gap: 1.1rem;
  align-items: flex-start;
  text-align: left;
  width: 100%;
  background: transparent;
  border: 0;
  border-left: 3px solid transparent;
  border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
  padding: 1.15rem 1.25rem 1.15rem 1.35rem;
  cursor: pointer;
  color: var(--color-text);
  transition: background-color 0.22s ease, border-color 0.22s ease,
    transform 0.22s var(--ease-out);
  font-family: var(--font-body);
}

.cap-item:hover {
  background: rgba(74, 107, 82, 0.06);
}

.cap-item.is-active {
  background: var(--color-sage-tint);
  border-left-color: var(--color-sage);
}

.cap-item__num {
  font-family: var(--font-display);
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--color-gold);
  padding-top: 0.35rem;
  letter-spacing: 0.05em;
}

.cap-item.is-active .cap-item__num {
  color: var(--color-sage);
}

.cap-item__title {
  display: block;
  font-family: var(--font-display);
  font-size: 1.3rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--color-text);
  margin-bottom: 0.25rem;
}

.cap-item.is-active .cap-item__title {
  color: var(--color-sage-dark);
}

.cap-item__desc {
  display: block;
  font-size: 0.98rem;
  line-height: 1.55;
  color: var(--color-text-muted);
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-height 0.35s var(--ease-out), opacity 0.3s ease,
    margin-top 0.35s var(--ease-out);
}

.cap-item.is-active .cap-item__desc {
  max-height: 12rem;
  opacity: 1;
}

/* When JS is off, show every description so nothing is hidden. */
html:not(.js) .cap-item__desc {
  max-height: none;
  opacity: 1;
}

/* Right-hand dynamic stage */
.cap-stage {
  position: sticky;
  top: 90px;
  min-height: 360px;
}

.cap-panel {
  animation: cap-fade 0.4s var(--ease-out);
}

.cap-panel[hidden] {
  display: none;
}

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

.cap-demo {
  background: linear-gradient(160% 120% at 20% 0%, #21311f 0%, #16210f 100%);
  background: radial-gradient(130% 120% at 10% 0%, #22331f 0%, #172310 100%);
  border: 1px solid rgba(74, 107, 82, 0.5);
  border-radius: var(--radius-lg);
  padding: 1.5rem;
  min-height: 360px;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  box-shadow: 0 30px 60px -40px rgba(0, 0, 0, 0.7);
}

.cap-demo__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.cap-demo__chip {
  font-family: var(--font-display);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #0f1a0c;
  background: var(--color-gold);
  padding: 0.35rem 0.7rem;
  border-radius: 999px;
}

.cap-demo__tag {
  font-family: var(--font-display);
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--color-sage-tint);
}

.cap-demo__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1.25rem;
}

/* Demand: channel bars */
.cap-demo__channels {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1rem;
  align-items: end;
  height: 170px;
}

.cap-chan {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 0.6rem;
  height: 100%;
  font-family: var(--font-display);
  font-size: 0.85rem;
  color: var(--color-sage-tint);
}

.cap-chan i {
  display: block;
  width: 100%;
  height: var(--h, 40%);
  border-radius: 6px 6px 0 0;
  background: linear-gradient(180deg, var(--color-gold), var(--color-sage));
}

.cap-demo__out {
  display: flex;
  flex-direction: column;
  font-family: var(--font-display);
  font-size: 0.9rem;
  color: var(--color-sage-tint);
  border-top: 1px dashed rgba(220, 229, 218, 0.35);
  padding-top: 0.85rem;
}

.cap-demo__out strong {
  font-size: 1.4rem;
  color: var(--color-bg);
}

/* Content: search + sources */
.cap-demo__search {
  background: rgba(250, 249, 246, 0.06);
  border: 1px solid rgba(220, 229, 218, 0.3);
  border-radius: 8px;
  padding: 0.9rem 1.1rem;
  color: var(--color-bg);
  font-size: 1.05rem;
}

.cap-demo__answer {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}

.cap-demo__src {
  font-family: var(--font-display);
  font-size: 0.85rem;
  color: var(--color-bg);
  background: rgba(74, 107, 82, 0.55);
  border: 1px solid rgba(220, 229, 218, 0.35);
  border-radius: 999px;
  padding: 0.4rem 0.85rem;
}

/* PLG: funnel bars */
.cap-demo__funnel {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.cap-demo__funnel span {
  display: flex;
  align-items: center;
  height: 44px;
  width: var(--w, 100%);
  padding-left: 1rem;
  border-radius: 6px;
  font-family: var(--font-display);
  font-size: 0.95rem;
  color: var(--color-bg);
  background: linear-gradient(90deg, var(--color-sage), var(--color-terracotta));
}

/* Leader: team nodes */
.cap-demo__team {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  justify-content: center;
}

.cap-node {
  font-family: var(--font-display);
  font-size: 0.95rem;
  color: var(--color-bg);
  background: rgba(250, 249, 246, 0.08);
  border: 1px solid rgba(220, 229, 218, 0.35);
  border-radius: 999px;
  padding: 0.6rem 1.1rem;
}

/* Featured work card stats ------------------------------------------------- */
.metric__value {
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 5vw, 3.75rem);
  font-weight: 700;
  letter-spacing: -0.04em;
  color: var(--color-terracotta);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.metric__label {
  margin: 0.6rem 0 0;
  color: var(--color-text-muted);
  font-size: 1rem;
  max-width: 24ch;
}

.work-card__stat .metric__value {
  font-size: clamp(2rem, 3.4vw, 2.6rem);
}

.work-card__stat .metric__label {
  margin-top: 0.35rem;
  font-size: 0.92rem;
}

/* Tool-stack constellation ------------------------------------------------ */
.stack {
  position: relative;
  overflow: hidden;
  min-height: 720px;
  padding-block: var(--space-lg);
  background: radial-gradient(140% 100% at 15% 0%, #4c6f54 0%, #35492f 55%, #2c3d28 100%);
}

.stack .container {
  position: relative;
  z-index: 2;
  width: 100%;
}

/* Full-bleed knowledge-graph backdrop, no frame, spans the entire section. */
.stack__canvas-wrap {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  touch-action: pan-y;
}

.stack__canvas {
  display: block;
  width: 100%;
  height: 100%;
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.stack__nodes {
  position: absolute;
  inset: 0;
  z-index: 2;
}

/* Cluster grouping labels (JS-generated, positioned absolutely) */
.stack__group-label {
  position: absolute;
  transform: translate(-50%, -50%);
  z-index: 1;
  font-family: var(--font-display);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #d68e77;
  white-space: nowrap;
  pointer-events: none;
}

/* Accessible / no-JS fallback: grouped clusters as text */
.stack__fallback {
  position: relative;
  z-index: 2;
  list-style: none;
  margin: 0;
  padding: 1.75rem;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1.1rem;
  background: rgba(20, 32, 18, 0.35);
  border-radius: var(--radius-lg);
  backdrop-filter: blur(3px);
}

.stack__fallback li {
  color: var(--color-bg);
  font-size: 1rem;
  line-height: 1.5;
}

.stack__cluster-label {
  display: block;
  font-family: var(--font-display);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-gold);
  margin-bottom: 0.15rem;
}

/* With JS on wide screens, the animated constellation replaces the list. */
.js .stack__canvas-wrap[data-constellation] .stack__fallback {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.stack__node {
  --hover-influence: 0;
  position: absolute;
  transform: translate(-50%, -50%)
    scale(calc(1 + var(--hover-influence) * 0.12));
  cursor: default;
  transition: transform 0.2s var(--ease-out);
  z-index: 3;
}

.stack__node:hover,
.stack__node:focus-visible {
  transform: translate(-50%, -50%) scale(1.14);
  z-index: 6;
  outline: none;
}

/* Logo chip nodes: a circular tile with a small caption underneath. Content
   is not clipped to the circle (object-fit: contain inside an inset square)
   so wide wordmark logos stay fully legible. */
.stack__node--logo {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
}

.stack__node-chip {
  width: 60px;
  height: 60px;
  border-radius: 50%;
  background: var(--color-bg);
  border: 1px solid rgba(220, 229, 218, 0.4);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 11px;
  box-sizing: border-box;
  box-shadow: 0 10px 22px -14px rgba(0, 0, 0, 0.65);
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.stack__node--logo:hover .stack__node-chip,
.stack__node--logo:focus-visible .stack__node-chip {
  border-color: var(--color-gold);
  box-shadow: 0 18px 36px -14px rgba(0, 0, 0, 0.7);
}

.stack__node-chip img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  mix-blend-mode: multiply;
}

.stack__node-chip.no-blend img {
  mix-blend-mode: normal;
}

.stack__node-label {
  font-family: var(--font-display);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--color-sage-tint);
  text-align: center;
  white-space: nowrap;
  opacity: 0.9;
}

/* Text-only fallback pill for tools with no logo asset yet. */
.stack__node--text {
  display: inline-block;
  font-family: var(--font-display);
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--color-bg);
  background: rgba(250, 249, 246, 0.1);
  border: 1px solid rgba(220, 229, 218, 0.35);
  border-radius: 999px;
  padding: 0.5rem 1rem;
  white-space: nowrap;
  backdrop-filter: blur(2px);
  transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.stack__node--text:hover,
.stack__node--text:focus-visible {
  background: var(--color-gold);
  border-color: var(--color-gold);
  color: var(--color-text);
}

.stack .section__head h2,
.stack .eyebrow {
  color: var(--color-bg);
}

.stack .eyebrow {
  color: var(--color-sage-tint);
}

.stack .section__head p {
  color: var(--color-sage-tint);
}

/* Testimonial ------------------------------------------------------------- */
.testimonial {
  text-align: center;
}

.testimonial blockquote {
  margin: 0 auto;
  max-width: 900px;
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 3.4vw, 2.5rem);
  line-height: 1.28;
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--color-bg);
}

.testimonial cite {
  display: block;
  margin-top: var(--space-md);
  font-family: var(--font-body);
  font-style: normal;
  font-size: 1rem;
  color: var(--color-sage-tint);
}

.testimonial cite strong {
  color: var(--color-bg);
}

/* Closing CTA ------------------------------------------------------------- */
.cta-split {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-md);
  margin-top: var(--space-md);
}

.cta-card {
  background-color: rgba(250, 249, 246, 0.1);
  border: 1px solid rgba(250, 249, 246, 0.28);
  border-radius: var(--radius-lg);
  padding: var(--space-md);
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  align-items: flex-start;
}

.cta-card p {
  font-family: var(--font-display);
  font-size: 1.3rem;
  font-weight: 500;
  letter-spacing: -0.02em;
  margin: 0;
  color: var(--color-bg);
}

/* Resume callout (inner pages) -------------------------------------------- */
.resume-cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
  margin-top: var(--space-md);
}

.resume-cta p {
  margin: 0;
  color: var(--color-text-muted);
}

/* Placeholder page note --------------------------------------------------- */
.coming-soon {
  display: inline-block;
  margin-top: var(--space-sm);
  padding: 0.4rem 0.85rem;
  background-color: var(--color-sage-tint);
  color: var(--color-sage-dark);
  border-radius: 999px;
  font-family: var(--font-display);
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.04em;
}

.lede {
  font-size: clamp(1.15rem, 2vw, 1.4rem);
  color: var(--color-text-muted);
  max-width: 680px;
}

/* About page: pull-quote opener ------------------------------------------- */
.quote-hero {
  text-align: center;
  padding-block: var(--space-lg) var(--space-md);
}

.quote-hero__mark {
  font-family: var(--font-display);
  font-size: 4rem;
  line-height: 1;
  color: var(--color-gold);
  margin: 0;
}

.quote-hero__text {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 5vw, 3.25rem);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.15;
  max-width: 820px;
  margin: 0 auto;
}

/* About page: hit-list layout ---------------------------------------------- */
.about-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-lg);
  align-items: stretch;
}

.hit-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.hit-block p {
  margin: 0;
  font-size: 1.05rem;
}

.hit-block strong {
  font-family: var(--font-display);
  color: var(--color-sage);
}

/* About page: animated stat strip ------------------------------------------ */
.stat-strip {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-md);
  margin-top: var(--space-lg);
}

.stat-card {
  border-top: 2px solid var(--color-gold);
  padding-top: var(--space-sm);
}

.stat-card__from {
  margin: 0 0 0.15rem;
  font-family: var(--font-display);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}

.highlight-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  max-width: 780px;
  margin-top: var(--space-lg);
}

.highlight-list p {
  margin: 0;
  font-size: 1.05rem;
}

.highlight-list strong {
  font-family: var(--font-display);
  color: var(--color-terracotta);
}

/* About page: How I Lead, player/coach illustration pair -------------------
   The images have a transparent background (paper keyed out in processing,
   see CLAUDE.md) so they read as drawn straight onto the section's sage
   field rather than sitting in a separate photo frame. They cross-fade from
   coach to player as the section scrolls, driven by the --pc-mix custom
   property that /js/main.js writes on .player-coach (the <section> itself,
   0 = coach, 1 = player).

   The base rules below are the no-JS and reduced-motion view: .player-coach
   __media is a normal block, styled to match .container's own width and
   padding so it lines up with the rest of the page, holding both images side
   by side in normal flow, both fully visible, no absolute positioning, no
   scroll coupling.

   The scroll-linked treatment is layered on top inside a `.js` +
   `prefers-reduced-motion: no-preference` + wide-viewport query, so it can
   never strand the player image at opacity 0. There, .player-coach__media
   is a full-bleed sibling of .container (not nested inside it, same pattern
   as .stack) so the frame can borrow width beyond the container's
   max-width. .pc-frame becomes position: absolute against the <section>
   (.player-coach__media itself stays position: static and collapses to zero
   height, only .pc-frame is positioned, skipping straight to the section as
   its containing block) and does not move on scroll: playerCoach() in
   main.js sizes and positions it once (and on resize) so it spans from the
   "Player coach, literally." heading down through most of the second card
   row, flush against the section's right edge, clamped so it never overlaps
   the copy column. Only --pc-mix changes as the page scrolls. */
.player-coach {
  position: relative;
}

.player-coach__body {
  max-width: 640px;
}

.player-coach__media {
  max-width: var(--max-width);
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 5vw, 2.75rem);
}

.pc-frame {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-sm);
  margin: 0;
}

.pc-frame__img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: contain;
}

@media (prefers-reduced-motion: no-preference) and (min-width: 901px) {
  .js .player-coach {
    --pc-mix: 0;
  }

  .js .player-coach__media {
    max-width: none;
    margin-inline: 0;
    padding-inline: 0;
  }

  /* Sized and positioned entirely by playerCoach() in main.js, which writes
     top/height/width inline once measurements are available; the values
     here are just a sane starting point before that first measurement. */
  .js .pc-frame {
    display: block;
    position: absolute;
    top: 0;
    right: 0;
    height: 300px;
    width: 240px;
    /* The cross-fade's small scale/drift on the two images (below) can push
       a couple of percent past this box; clip it so it never creates
       horizontal overflow at the section's right edge. */
    overflow: hidden;
  }

  /* top/width/height are set per image by playerCoach() in main.js, since
     the coach and player no longer share one top offset (see the comment
     above playerCoach() for why); these are just a sane starting point
     before that first measurement lands. Both stay right-anchored so they
     line up with .pc-frame's own right-flush edge. */
  .js .pc-frame__img {
    position: absolute;
    right: 0;
    top: 0;
    width: 100%;
    height: 100%;
    aspect-ratio: auto;
    object-position: 50% 0%;
    will-change: opacity, transform;
  }

  .js .pc-frame__img--coach {
    opacity: calc(1 - var(--pc-mix));
    transform: translateY(calc(var(--pc-mix) * -2%)) scale(calc(1 + var(--pc-mix) * 0.04));
  }

  .js .pc-frame__img--player {
    opacity: var(--pc-mix);
    transform: translateY(calc((1 - var(--pc-mix)) * 2%)) scale(calc(1.04 - var(--pc-mix) * 0.04));
  }
}

/* About page: reusable icon card grid (How I Lead, Outside/Education) ----- */
.card-grid {
  display: grid;
  gap: var(--space-md);
  margin-top: var(--space-lg);
}

.card-grid--4 {
  grid-template-columns: repeat(4, 1fr);
}

.card-grid--2 {
  grid-template-columns: repeat(2, 1fr);
}

.card-grid--2x2 {
  grid-template-columns: repeat(2, 1fr);
}

.card-grid--5 {
  grid-template-columns: repeat(5, 1fr);
}

.icon-card {
  background-color: var(--color-bg);
  border: 1px solid rgba(74, 107, 82, 0.16);
  border-radius: var(--radius-lg);
  padding: var(--space-md);
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  transition: transform 0.22s var(--ease-out), box-shadow 0.22s var(--ease-out),
    border-color 0.22s ease;
}

.icon-card:hover,
.icon-card:focus-within {
  transform: translateY(-5px);
  box-shadow: 0 20px 36px -22px rgba(43, 43, 43, 0.32);
  border-color: var(--color-sage);
}

.icon-card__icon {
  width: 2rem;
  height: 2rem;
  color: var(--color-sage);
}

.icon-card__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.05rem;
  letter-spacing: -0.01em;
}

.icon-card__desc {
  margin: 0;
  color: var(--color-text-muted);
  font-size: 0.98rem;
}

/* Set-off symptom list inside an icon card, introduced by a "Sometimes this
   happens when:" label. The symptoms are the part a reader self-identifies
   with, so they are pulled out of the description instead of run into it.
   margin-top: auto pins the block to the bottom of the card, so the callouts
   line up across a row even when the descriptions above differ in length. */
.icon-card__when {
  margin: auto 0 0;
  padding-left: 0.85rem;
  border-left: 2px solid var(--color-gold);
  color: var(--color-text-muted);
  font-size: 0.9rem;
  line-height: 1.55;
}

.icon-card__when b {
  display: block;
  margin-bottom: 0.15rem;
  font-family: var(--font-display);
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-sage-dark);
}

/* The catch-all card that closes a grid of specific situations. Tinted so it
   reads as an invitation rather than a sixth symptom, since it is the only
   card in the set that describes no particular problem. */
.icon-card--invite {
  background-color: var(--color-sage-tint);
  border-color: var(--color-sage);
}

/* FAQ disclosure list ------------------------------------------------------ */
/* Native details/summary, so it is keyboard operable and fully readable with
   no JS at all. The open/close easing rides on ::details-content, which older
   engines simply drop, leaving an instant toggle rather than a broken one.
   interpolate-size is what lets block-size animate to auto; without support
   the panel still opens, just without the slide. */
/* Laid out as a 2x2 of cards rather than a stacked list. align-items: start
   is what keeps an opened panel from stretching its row partner to match. */
.faq {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: start;
  gap: var(--space-md);
  margin-top: var(--space-lg);
  interpolate-size: allow-keywords;
}

.faq__item {
  padding: 0 var(--space-md);
  background-color: var(--color-bg);
  border: 1px solid rgba(74, 107, 82, 0.22);
  border-radius: var(--radius-lg);
  transition: border-color 0.2s ease;
}

.faq__item:hover,
.faq__item[open] {
  border-color: var(--color-sage);
}

.faq__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: var(--space-sm) 0;
  cursor: pointer;
  list-style: none;
  font-family: var(--font-display);
  font-size: clamp(1.02rem, 1.5vw, 1.2rem);
  font-weight: 600;
  letter-spacing: -0.01em;
  transition: color 0.2s ease;
}

/* Safari still needs the vendor pseudo-element to drop the disclosure arrow. */
.faq__q::-webkit-details-marker {
  display: none;
}

.faq__q:hover,
.faq__item[open] > .faq__q {
  color: var(--color-sage);
}

.faq__q:focus-visible {
  outline: 2px solid var(--color-sage);
  outline-offset: 4px;
  border-radius: 2px;
}

/* Chevron, rotated to point down when the panel is open. */
.faq__q::after {
  content: '';
  flex: none;
  width: 0.62rem;
  height: 0.62rem;
  margin-right: 0.2rem;
  border-right: 2px solid var(--color-gold);
  border-bottom: 2px solid var(--color-gold);
  transform: translateY(-25%) rotate(-45deg);
  transition: transform 0.25s var(--ease-out);
}

.faq__item[open] > .faq__q::after {
  transform: translateY(-25%) rotate(45deg);
}

.faq__a {
  padding-bottom: var(--space-sm);
  color: var(--color-text-muted);
  font-size: 0.96rem;
}

.faq__a p {
  margin: 0;
}

@media (prefers-reduced-motion: no-preference) {
  .faq__item::details-content {
    block-size: 0;
    overflow: hidden;
    opacity: 0;
    transition: block-size 0.3s var(--ease-out), opacity 0.3s ease,
      content-visibility 0.3s allow-discrete;
    transition-behavior: allow-discrete;
  }

  .faq__item[open]::details-content {
    block-size: auto;
    opacity: 1;
  }
}

/* Small row of tool logos naming what actually ran in that channel. Sits
   between the title and the description, so it reads as a caption on the
   heading rather than decoration on the paragraph. */
.icon-card__logos {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
}

.icon-card__logos a {
  display: flex;
  border-radius: 50%;
}

.icon-card__logos a:focus-visible {
  outline: 2px solid var(--color-sage);
  outline-offset: 2px;
}

.icon-card__logos img {
  width: 26px;
  height: 26px;
  object-fit: contain;
  filter: grayscale(1) contrast(0.95) brightness(0.85);
  mix-blend-mode: multiply;
  transition: filter 0.2s ease;
}

.icon-card__logos a:hover img,
.icon-card__logos a:focus-visible img {
  filter: none;
}

.icon-card__logos .stack-row__text {
  width: 26px;
  height: 26px;
  font-size: 0.65rem;
  border-radius: 50%;
}

/* About page: coffee callout card ------------------------------------------ */
.cta-card__icon {
  width: 1.75rem;
  height: 1.75rem;
  color: var(--color-bg);
  opacity: 0.9;
}

/* Case study index cards -------------------------------------------------- */
.work-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-md);
  margin-top: var(--space-lg);
}

.work-card {
  display: block;
  position: relative;
  background-color: var(--color-bg);
  border: 1px solid rgba(74, 107, 82, 0.18);
  border-radius: var(--radius-lg);
  padding: var(--space-md);
  color: var(--color-text);
  overflow: hidden;
  transition: border-color 0.2s ease, transform 0.25s var(--ease-out),
    box-shadow 0.25s ease;
}

.work-card::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 4px;
  background: var(--color-gold);
  transform: scaleY(0);
  transform-origin: 0 0;
  transition: transform 0.28s var(--ease-out);
}

.work-card:hover,
.work-card:focus-visible {
  border-color: var(--color-sage);
  text-decoration: none;
  transform: translateY(-4px);
  box-shadow: 0 18px 40px -28px rgba(43, 43, 43, 0.5);
}

.work-card:hover::before,
.work-card:focus-visible::before {
  transform: scaleY(1);
}

.work-card h3 {
  color: var(--color-sage);
  margin-bottom: 0.4rem;
}

.work-card p {
  margin: 0;
  color: var(--color-text-muted);
}

.work-card__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.9rem;
}

.work-card__tag {
  font-family: var(--font-display);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--color-sage-dark);
  background-color: var(--color-sage-tint);
  border-radius: 999px;
  padding: 0.3rem 0.7rem;
}

/* Homepage bento showcase ------------------------------------------------- */
.work-grid--bento {
  grid-template-columns: 1.05fr 1fr;
  gap: var(--space-md);
}

.work-grid--bento .work-card {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.work-card__eyebrow {
  font-family: var(--font-display);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-sage);
}

.work-card__cta {
  font-family: var(--font-display);
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--color-sage);
}

.work-card__cta::after {
  content: ' \2192';
  transition: transform 0.25s var(--ease-out);
  display: inline-block;
}

.work-card:hover .work-card__cta::after,
.work-card:focus-visible .work-card__cta::after {
  transform: translateX(4px);
}

/* Hero card: terracotta color field */
.work-card--hero {
  grid-row: span 2;
  background-color: var(--color-terracotta);
  border-color: transparent;
  color: var(--color-bg);
  justify-content: space-between;
  padding: var(--space-lg) var(--space-md);
}

.work-card--hero .work-card__eyebrow {
  color: rgba(250, 249, 246, 0.85);
}

.work-card--hero .work-card__hero-metric {
  margin-top: auto;
}

.work-card--hero .metric__value {
  color: var(--color-bg);
  font-size: clamp(3.5rem, 7vw, 5.5rem);
}

.work-card--hero .metric__label {
  color: rgba(250, 249, 246, 0.9);
  max-width: 30ch;
  margin-top: 0.9rem;
  font-size: 1.05rem;
}

.work-card--hero .work-card__foot {
  margin-top: var(--space-md);
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.work-card--hero h3 {
  color: var(--color-bg);
  margin: 0;
}

.work-card--hero .work-card__cta {
  color: var(--color-gold);
}

.work-card--hero::before {
  display: none;
}

/* Wide closing card: sage color field */
.work-grid--bento .work-card--wide {
  grid-column: 1 / -1;
  flex-direction: row;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-md);
}

.work-card--sage {
  background-color: var(--color-sage);
  border-color: transparent;
  color: var(--color-bg);
}

.work-card--sage .work-card__eyebrow {
  color: var(--color-sage-tint);
}

.work-card--sage h3 {
  color: var(--color-bg);
  margin: 0.35rem 0 0.5rem;
}

.work-card--sage p {
  color: rgba(250, 249, 246, 0.9);
  max-width: 60ch;
}

.work-card--sage .work-card__cta {
  color: var(--color-gold);
  white-space: nowrap;
}

.work-card--sage::before {
  background: var(--color-gold);
}

@media (max-width: 820px) {
  .work-grid--bento {
    grid-template-columns: 1fr;
    grid-auto-rows: auto;
  }

  .work-grid--bento .work-card--hero,
  .work-grid--bento .work-card--wide {
    grid-column: auto;
    grid-row: auto;
  }

  .work-grid--bento .work-card--wide {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* Footer ------------------------------------------------------------------ */
.site-footer {
  background-color: var(--color-text);
  color: var(--color-bg);
  padding-block: var(--space-lg);
  margin-top: auto;
}

.site-footer a {
  color: var(--color-sage-tint);
}

.site-footer a:hover,
.site-footer a:focus-visible {
  color: #fff;
  text-decoration-color: var(--color-gold);
}

.site-footer__inner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
  justify-content: space-between;
  align-items: center;
}

.site-footer__nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
  list-style: none;
  margin: 0;
  padding: 0;
  font-family: var(--font-display);
}

.site-footer__meta {
  font-size: 0.9rem;
  color: var(--color-sage-tint);
  margin: 0;
}

/* ==========================================================================
   Case study pages
   Shared template used by every study under /the-work/. Hero + meta, numbered
   steps, figures, single-series charts, results field, stack row, prev/next.
   ========================================================================== */

/* Hero + metadata --------------------------------------------------------- */
.case-hero {
  padding-bottom: var(--space-lg);
}

.case-hero h1 {
  max-width: 16ch;
}

/* Client logo, linked to the company's own site. Lives inside the "Company"
   meta cell in place of the plain company name, with a one-line description
   underneath, rather than as a separate hero-level element. Logo-only, no
   visible label, so the accessible name comes from aria-label on the <a>. */
.case-hero__brand {
  display: inline-block;
  margin-bottom: 0.7rem;
  line-height: 0;
  border-radius: var(--radius);
  transition: opacity 0.2s ease;
}

.case-hero__brand:hover,
.case-hero__brand:focus-visible {
  opacity: 0.72;
}

.case-hero__brand:focus-visible {
  outline: 2px solid var(--color-sage);
  outline-offset: 4px;
}

.case-hero__brand img {
  height: 40px;
  width: auto;
  max-width: 220px;
  object-fit: contain;
}

.case-meta__sub {
  margin: 0;
  font-size: 0.98rem;
  color: var(--color-text-muted);
}

.case-hero .lede {
  max-width: 46ch;
}

.case-meta {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-md);
  margin: var(--space-lg) 0 0;
  padding-top: var(--space-md);
  border-top: 1px solid rgba(74, 107, 82, 0.22);
}

.case-meta div {
  margin: 0;
}

.case-meta dt {
  font-family: var(--font-display);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-sage);
  margin-bottom: 0.35rem;
}

.case-meta dd {
  margin: 0;
  font-size: 0.98rem;
  color: var(--color-text-muted);
}

/* Numbered steps ---------------------------------------------------------- */
.step {
  margin-top: var(--space-xl);
}

.step:first-child {
  margin-top: 0;
}

/* Number sits on its own line above the heading. Setting them side by side
   meant a two-line heading straddled the numeral with no shared alignment
   edge, which read as a mistake. Stacked, both share a left edge and a
   consistent vertical rhythm no matter how the heading wraps. */
.step__head {
  margin-bottom: var(--space-md);
}

.step__num {
  display: block;
  font-family: var(--font-display);
  font-size: 0.95rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.18em;
  color: var(--color-gold);
  margin-bottom: 0.7rem;
}

.step__num::after {
  content: '';
  display: block;
  width: 2.25rem;
  height: 2px;
  margin-top: 0.55rem;
  background-color: var(--color-gold);
}

.step__head h3 {
  margin: 0;
  max-width: 24ch;
  font-size: clamp(1.5rem, 3vw, 2rem);
  line-height: 1.15;
}

.step__body {
  max-width: 68ch;
}

.step__body p:last-child {
  margin-bottom: 0;
}

/* Figures ----------------------------------------------------------------- */
.figure {
  margin: var(--space-lg) 0 0;
}

.figure img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid rgba(74, 107, 82, 0.2);
  border-radius: var(--radius);
  background-color: #fff;
}

.figure figcaption {
  margin-top: 0.7rem;
  font-size: 0.86rem;
  line-height: 1.5;
  color: var(--color-text-muted);
}

/* Logo lockups arrive as transparent PNGs with no background of their own.
   The default figure treatment boxes them in a white card with a border,
   which reads as a screenshot of a logo. This variant drops the frame and
   centers the art on whatever field the section is using. */
/* Held to the same measure as .step__body so the art centers on the copy
   column instead of drifting into the empty right half of the container. */
.figure--plain {
  max-width: 68ch;
}

.figure--plain .figure__art {
  width: auto;
  max-width: min(100%, 420px);
  margin-inline: auto;
  border: 0;
  border-radius: 0;
  background-color: transparent;
}

.figure--plain figcaption {
  max-width: 52ch;
  margin-inline: auto;
  text-align: center;
}

.figure-grid {
  display: grid;
  gap: var(--space-md);
  margin: var(--space-lg) 0 0;
}

.figure-grid--2 { grid-template-columns: repeat(2, 1fr); }
.figure-grid--3 { grid-template-columns: repeat(3, 1fr); }

.figure-grid .figure {
  margin: 0;
}

.figure-grid .figure figcaption strong {
  color: var(--color-text);
}

/* Screenshot frame.
   These sources are archival captures at wildly different aspect ratios and
   modest pixel dimensions. Cropping them to a shared aspect (object-fit:
   cover) sliced headlines and forms in half, and stretching them past native
   size made them mushy. So: a fixed-height stage, object-fit: contain, and a
   browser chrome bar. Nothing is ever cropped, nothing is ever upscaled past
   1x, and the ragged set reads as a deliberate collection of product shots. */
.shot__frame {
  border: 1px solid rgba(74, 107, 82, 0.18);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background-color: #fff;
  box-shadow: 0 20px 44px -30px rgba(43, 43, 43, 0.5);
}

.shot__bar {
  display: flex;
  align-items: center;
  gap: 5px;
  height: 26px;
  padding-inline: 0.7rem;
  background-color: var(--color-cream);
  border-bottom: 1px solid rgba(74, 107, 82, 0.14);
}

.shot__bar span {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background-color: rgba(43, 43, 43, 0.16);
}

.shot__stage {
  height: var(--shot-h, 340px);
  padding: 0.75rem;
  background-color: #fff;
}

/* Fill the stage box and letterbox inside it. Sizing the image intrinsically
   and relying on max-height: 100% does not constrain reliably, since the
   percentage resolves against a track height the image itself is sizing. */
.shot__stage img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
  border: 0;
  border-radius: 0;
}

/* Dense captures (the audit grid) are only legible at roughly 1:1, so this
   variant drops the fixed stage and lets the image run at its natural size. */
.shot--full .shot__stage {
  height: auto;
  padding: 0;
}

.shot--full .shot__stage img {
  height: auto;
  object-fit: fill;
}

.shot figcaption {
  margin-top: 0.75rem;
}

.figure-grid--2 { --shot-h: 430px; }
.figure-grid--3 { --shot-h: 360px; }

/* Audit scorecard: the four-metric chain, as a diagram rather than a
   screenshot of the spreadsheet it came from. */
.chain {
  margin: var(--space-lg) 0 0;
  padding: var(--space-md);
  background-color: var(--color-cream);
  border: 1px solid rgba(74, 107, 82, 0.16);
  border-radius: var(--radius-lg);
}

.chain__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-md);
}

.chain__step {
  position: relative;
  padding: var(--space-sm);
  background-color: var(--color-bg);
  border: 1px solid rgba(74, 107, 82, 0.2);
  border-radius: var(--radius);
}

/* Connector arrow between cards, drawn in the gap. */
.chain__step + .chain__step::before {
  content: '';
  position: absolute;
  top: 50%;
  left: calc(var(--space-md) * -1);
  width: var(--space-md);
  height: 2px;
  background-color: rgba(74, 107, 82, 0.3);
}

.chain__step + .chain__step::after {
  content: '';
  position: absolute;
  top: 50%;
  left: -0.55rem;
  width: 7px;
  height: 7px;
  border-top: 2px solid rgba(74, 107, 82, 0.45);
  border-right: 2px solid rgba(74, 107, 82, 0.45);
  transform: translateY(-50%) rotate(45deg);
}

.chain__step--final {
  border-color: var(--color-terracotta);
  border-width: 2px;
}

.chain__num {
  display: block;
  font-family: var(--font-display);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  color: var(--color-sage);
  margin-bottom: 0.4rem;
}

.chain__step--final .chain__num {
  color: var(--color-terracotta);
}

.chain__step b {
  display: block;
  font-family: var(--font-display);
  font-size: 1.02rem;
  line-height: 1.2;
  letter-spacing: -0.01em;
  margin-bottom: 0.25rem;
}

.chain__step span:last-child {
  font-size: 0.84rem;
  line-height: 1.4;
  color: var(--color-text-muted);
}

.chain__note {
  margin: var(--space-md) 0 0;
  font-size: 0.88rem;
  color: var(--color-text-muted);
}

.chain__note strong {
  color: var(--color-text);
}

/* Engagement path: the published three-step route into an offering, each
   step carrying its real duration. Rebuilt as markup rather than shipping
   the client's own slide artwork, so it lives in this site's palette and
   stays legible at any width. Same connector construction as .chain. */
.path {
  list-style: none;
  margin: var(--space-lg) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-md);
}

.path__step {
  position: relative;
  padding: var(--space-md);
  background-color: var(--color-cream);
  border: 1px solid rgba(74, 107, 82, 0.2);
  border-radius: var(--radius-lg);
}

.path__step + .path__step::before {
  content: '';
  position: absolute;
  top: 50%;
  left: calc(var(--space-md) * -1);
  width: var(--space-md);
  height: 2px;
  background-color: rgba(74, 107, 82, 0.3);
}

.path__step + .path__step::after {
  content: '';
  position: absolute;
  top: 50%;
  left: -0.55rem;
  width: 7px;
  height: 7px;
  border-top: 2px solid rgba(74, 107, 82, 0.45);
  border-right: 2px solid rgba(74, 107, 82, 0.45);
  transform: translateY(-50%) rotate(45deg);
}

.path__step--final {
  border-color: var(--color-terracotta);
  border-width: 2px;
}

/* Sequenced progression, opted into with [data-path-progress] so the CEI case
   study's static path is unaffected. JS adds .is-lit to each step in turn once
   the list is in view, which fades the card up and draws its incoming
   connector. Everything is gated behind html.js, so with no JS the steps are
   simply visible, same as the static version. */
html.js .path[data-path-progress] .path__step {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.5s ease, transform 0.5s var(--ease-out);
}

html.js .path[data-path-progress] .path__step.is-lit {
  opacity: 1;
  transform: none;
}

/* The connector belongs to the step it points into, so it draws as that step
   arrives. transform-origin follows the arrow direction, left to right on the
   three-column layout and top to bottom once stacked. */
html.js .path[data-path-progress] .path__step + .path__step::before {
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.45s var(--ease-out) 0.12s;
}

html.js .path[data-path-progress] .path__step.is-lit::before {
  transform: scaleX(1);
}

html.js .path[data-path-progress] .path__step + .path__step::after {
  opacity: 0;
  transition: opacity 0.3s ease 0.42s;
}

html.js .path[data-path-progress] .path__step.is-lit::after {
  opacity: 1;
}

/* Ambient sweep. A soft gold highlight travels card, connector, card,
   connector, card and then rests, so the route keeps reading left to right
   after the entrance has finished. Every element shares one 5.4s cycle and
   is offset by --glow-i * 0.45s, so the wave stays permanently in phase
   regardless of when each step was lit. The animation is applied whether or
   not JS ran, since a static path glowing is fine; the global reduced-motion
   block collapses all animation to a single 0.001ms pass, which removes it. */
/* A thin ring carries the sweep, since a pure halo is close to invisible
   against a cream card on a cream field. The blurred shadow underneath just
   gives the ring some depth. */
@keyframes path-glow-card {
  0%, 16%, 100% {
    box-shadow: 0 0 0 0 rgba(201, 160, 81, 0), 0 0 0 0 rgba(201, 160, 81, 0);
  }
  7% {
    box-shadow: 0 0 0 2px rgba(201, 160, 81, 0.55),
      0 6px 24px -4px rgba(201, 160, 81, 0.45);
  }
}

@keyframes path-glow-line {
  0%, 16%, 100% {
    background-color: rgba(74, 107, 82, 0.3);
  }
  7% {
    background-color: rgba(201, 160, 81, 0.85);
  }
}

@keyframes path-glow-arrow {
  0%, 16%, 100% {
    border-color: rgba(74, 107, 82, 0.45);
  }
  7% {
    border-color: rgba(201, 160, 81, 0.9);
  }
}

.path[data-path-progress] .path__step {
  animation: path-glow-card 5.4s ease-in-out infinite;
  animation-delay: calc(var(--glow-i, 0) * 0.45s);
}

.path[data-path-progress] .path__step + .path__step::before {
  animation: path-glow-line 5.4s ease-in-out infinite;
  animation-delay: calc((var(--glow-i, 0) - 1) * 0.45s);
}

.path[data-path-progress] .path__step + .path__step::after {
  animation: path-glow-arrow 5.4s ease-in-out infinite;
  animation-delay: calc((var(--glow-i, 0) - 0.8) * 0.45s);
}

/* The connector into a step fires one beat before the step itself, so the
   order along the route is card, line, card, line, card. */
.path[data-path-progress] .path__step:nth-child(1) { --glow-i: 0; }
.path[data-path-progress] .path__step:nth-child(2) { --glow-i: 2; }
.path[data-path-progress] .path__step:nth-child(3) { --glow-i: 4; }

.path__stamp {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xs);
  margin: 0 0 0.7rem;
}

.path__num {
  font-family: var(--font-display);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-sage);
}

.path__step--final .path__num {
  color: var(--color-terracotta);
}

/* The duration is the whole point of the diagram, so it gets the pill and
   the only solid color fill in the component. */
.path__dur {
  font-family: var(--font-display);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  white-space: nowrap;
  padding: 0.24rem 0.6rem;
  border-radius: 999px;
  background-color: var(--color-sage);
  color: var(--color-bg);
}

.path__step--final .path__dur {
  background-color: var(--color-terracotta);
}

.path__step b {
  display: block;
  font-family: var(--font-display);
  font-size: 1.14rem;
  line-height: 1.2;
  letter-spacing: -0.01em;
  margin-bottom: 0.4rem;
}

.path__note {
  display: block;
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--color-text-muted);
}

.path__caption {
  margin: var(--space-sm) 0 0;
  font-size: 0.86rem;
  line-height: 1.5;
  color: var(--color-text-muted);
}

/* Charts: shared shell ---------------------------------------------------- */
.chart {
  margin: var(--space-lg) 0 0;
  padding: var(--space-md);
  background-color: var(--color-cream);
  border: 1px solid rgba(74, 107, 82, 0.16);
  border-radius: var(--radius-lg);
  /* Self-contained ink: this card sits on a light surface regardless of the
     section wrapping it (including .section--terracotta, which sets an
     off-white ambient color that would otherwise go near-invisible here). */
  color: var(--color-text);
}

.chart__title {
  margin: 0 0 0.3rem;
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--color-text);
}

.chart__note {
  margin: 0 0 var(--space-md);
  font-size: 0.84rem;
  color: var(--color-text-muted);
}

.chart__note:last-child {
  margin: var(--space-sm) 0 0;
}

/* A note that captions the block above it rather than introducing one below. */
.variant-grid + .chart__note,
.readout + .chart__note,
.figure-grid + .chart__note {
  margin-top: var(--space-sm);
}

.chart-grid {
  display: grid;
  gap: var(--space-md);
  margin: var(--space-lg) 0 0;
  grid-template-columns: repeat(2, 1fr);
  align-items: start;
}

.chart-grid .chart {
  margin: 0;
  height: 100%;
}

/* Keyword ranking proof: grouped cards, big position number, no bar-chart
   semantics since a single point-in-time rank isn't a magnitude. */
.rank-groups {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
  margin-top: var(--space-lg);
}

.rank-group__title {
  margin: 0 0 var(--space-sm);
  font-family: var(--font-display);
  font-size: 1.02rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.rank-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: var(--space-sm);
}

.rank-card {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  background-color: var(--color-bg);
  border: 1px solid rgba(74, 107, 82, 0.16);
  border-radius: var(--radius-lg);
}

.rank-card__pos {
  flex: none;
  min-width: 2.9rem;
  font-family: var(--font-display);
  font-size: 1.4rem;
  font-weight: 700;
  color: var(--color-sage);
}

.rank-card__pos--top {
  color: var(--color-terracotta);
}

.rank-card__kw {
  margin: 0;
  font-size: 0.95rem;
}

/* Keyword ranking proof, rich variant: a mocked-up Google result card, not a
   screenshot. Deliberately borrows real Google chrome (the link blue, the
   breadcrumb gray, the pill-shaped search field) since the whole point is
   "this is recognizably a Google result", the one place on the site an
   external product's own color language is used instead of the palette. */
.serp-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: var(--space-md);
  margin-top: var(--space-sm);
}

.serp-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  padding: var(--space-md);
  background-color: var(--color-bg);
  border: 1px solid rgba(74, 107, 82, 0.16);
  border-radius: var(--radius-lg);
}

.serp-card__badge {
  position: absolute;
  top: -12px;
  right: var(--space-md);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.76rem;
  letter-spacing: 0.02em;
  color: var(--color-bg);
  background-color: var(--color-sage);
  border-radius: 999px;
  padding: 0.32rem 0.75rem;
  box-shadow: 0 6px 14px -7px rgba(43, 43, 43, 0.45);
}

.serp-card__badge--top {
  background-color: var(--color-terracotta);
}

.serp-card__query {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  background-color: var(--color-cream);
  border: 1px solid rgba(74, 107, 82, 0.14);
  border-radius: 999px;
  padding: 0.55rem 1rem;
  font-size: 0.92rem;
  color: var(--color-text);
}

.serp-card__query svg {
  width: 15px;
  height: 15px;
  color: var(--color-text-muted);
  flex-shrink: 0;
}

.serp-card__result {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.serp-card__result-head {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin-bottom: 0.15rem;
}

.serp-card__favicon {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  object-fit: contain;
  background-color: #fff;
  padding: 3px;
  box-shadow: 0 0 0 1px rgba(43, 43, 43, 0.08);
  flex-shrink: 0;
}

.serp-card__site {
  margin: 0;
  font-size: 0.82rem;
  font-weight: 600;
  color: #202124;
  line-height: 1.2;
}

.serp-card__url {
  margin: 0;
  font-size: 0.78rem;
  color: #4d5156;
  line-height: 1.2;
}

.serp-card__title {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1.05rem;
  font-weight: 600;
  line-height: 1.32;
  color: #1558d6;
}

.serp-card__desc {
  margin: 0;
  font-size: 0.86rem;
  line-height: 1.5;
  color: #474c50;
}

.serp-card__also {
  margin: 0;
  font-size: 0.8rem;
  color: var(--color-text-muted);
}

.serp-card__also strong {
  font-family: var(--font-display);
  color: var(--color-terracotta);
}

/* Charts: horizontal bars (one series, one hue, always direct-labeled) ----- */
.bars {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.bar__label {
  display: block;
  font-size: 0.88rem;
  margin-bottom: 0.3rem;
  color: var(--color-text);
}

.bar__row {
  display: flex;
  align-items: center;
  gap: 0.7rem;
}

.bar__track {
  flex: 1 1 auto;
  height: 14px;
  border-radius: 3px;
  background-color: rgba(74, 107, 82, 0.12);
  overflow: hidden;
}

.bar__fill {
  display: block;
  height: 100%;
  width: var(--pct, 0%);
  border-radius: 0 3px 3px 0;
  background-color: var(--color-sage);
  transform-origin: left center;
}

.bar__value {
  flex: none;
  min-width: 3.6rem;
  text-align: right;
  font-family: var(--font-display);
  font-size: 0.95rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--color-text);
}

.js .bar__fill {
  transform: scaleX(0);
  transition: transform 0.85s var(--ease-out);
  transition-delay: var(--bar-delay, 0ms);
}

.js .reveal.is-visible .bar__fill {
  transform: scaleX(1);
}

/* Charts: paired vertical bars (one metric, two points in time) ----------- */
/* For a before/after comparison a vertical pair reads faster than a
   horizontal bar pair, and putting the value directly above each column
   (rather than at the end of a fill) means the number is never rendered in
   a color meant for the bar itself. Self-contained ink throughout, same
   reasoning as .chart above. */
.duo-chart {
  margin: var(--space-lg) 0 0;
  padding: var(--space-md);
  background-color: var(--color-cream);
  border: 1px solid rgba(74, 107, 82, 0.16);
  border-radius: var(--radius-lg);
  color: var(--color-text);
}

.duo-chart__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-sm);
  flex-wrap: wrap;
}

.duo-chart__title {
  margin: 0 0 0.3rem;
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--color-text);
}

.duo-chart__note {
  margin: 0;
  font-size: 0.84rem;
  color: var(--color-text-muted);
}

.duo-chart__delta {
  flex: none;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.92rem;
  color: var(--color-terracotta);
  background-color: rgba(168, 101, 79, 0.12);
  border-radius: 999px;
  padding: 0.3rem 0.85rem;
  white-space: nowrap;
}

.duo-chart__plot {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: var(--space-xl);
  margin-top: var(--space-lg);
}

.duo-bar {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 108px;
}

.duo-bar__value {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.3rem;
  color: var(--color-text);
  margin: 0 0 0.5rem;
  font-variant-numeric: tabular-nums;
}

.duo-bar__col {
  width: 100%;
  height: var(--h, 20px);
  min-height: 4px;
  border-radius: 8px 8px 3px 3px;
  background-color: var(--color-sage-tint);
  transform-origin: bottom center;
}

.duo-bar--end .duo-bar__col {
  background-color: var(--color-sage);
}

.duo-bar__label {
  margin-top: 0.6rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--color-text-muted);
}

.js .duo-bar__col {
  transform: scaleY(0);
  transition: transform 0.85s var(--ease-out);
  transition-delay: var(--bar-delay, 0ms);
}

.js .reveal.is-visible .duo-bar__col {
  transform: scaleY(1);
}

@media (max-width: 480px) {
  .duo-chart__plot {
    gap: var(--space-lg);
  }

  .duo-bar {
    width: 84px;
  }
}

/* Charts: year-over-year line comparison ----------------------------------- */
/* Same metric, two calendar years: one hue (sage), two lightness/weight
   steps rather than two categorical colors, since this is a magnitude
   comparison of one series over time, not two different things. */
.yoy-chart {
  margin: var(--space-lg) 0 0;
  padding: var(--space-md);
  background-color: var(--color-cream);
  border: 1px solid rgba(74, 107, 82, 0.16);
  border-radius: var(--radius-lg);
  color: var(--color-text);
}

.yoy-chart__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-sm);
  flex-wrap: wrap;
}

.yoy-chart__title {
  margin: 0 0 0.3rem;
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--color-text);
}

.yoy-chart__note {
  margin: 0;
  font-size: 0.84rem;
  color: var(--color-text-muted);
}

.yoy-chart__delta {
  flex: none;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.92rem;
  color: var(--color-terracotta);
  background-color: rgba(168, 101, 79, 0.12);
  border-radius: 999px;
  padding: 0.3rem 0.85rem;
  white-space: nowrap;
}

.yoy-chart__legend {
  display: flex;
  gap: var(--space-md);
  margin: var(--space-sm) 0 0;
  font-size: 0.85rem;
  color: var(--color-text-muted);
}

.yoy-chart__legend span {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
}

.yoy-chart__swatch {
  width: 16px;
  height: 3px;
  border-radius: 2px;
  display: inline-block;
  background-color: var(--yoy-swatch, var(--color-sage));
}

.yoy-chart__legend .yoy-chart__swatch--prev {
  --yoy-swatch: #86a98d;
}

.yoy-chart__plot {
  margin-top: var(--space-lg);
}

.yoy-chart__svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

.yoy-chart__grid line {
  stroke: rgba(74, 107, 82, 0.16);
  stroke-width: 1;
}

.yoy-chart__ylabels text,
.yoy-chart__xlabels text {
  font-family: var(--font-body);
  font-size: 13px;
  fill: var(--color-text-muted);
}

.yoy-chart__line {
  fill: none;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.yoy-chart__line--prev {
  stroke: #86a98d;
  stroke-width: 2;
}

.yoy-chart__line--cur {
  stroke: var(--color-sage);
  stroke-width: 3;
}

/* Both lines draw themselves in when the chart scrolls into view, the
   current year drawing in just behind the prior year for a sense of one
   overtaking the other. */
.js .yoy-chart__line {
  stroke-dasharray: 1300;
  stroke-dashoffset: 1300;
}

.js .reveal.is-visible .yoy-chart__line--prev {
  transition: stroke-dashoffset 1.5s var(--ease-out);
  stroke-dashoffset: 0;
}

.js .reveal.is-visible .yoy-chart__line--cur {
  transition: stroke-dashoffset 1.5s var(--ease-out) 0.25s;
  stroke-dashoffset: 0;
}

/* Charts: growth curve ---------------------------------------------------- */
.growth {
  position: relative;
}

/* Holds the plot and, on narrow screens, scrolls it sideways so 26 weekly
   points stay legible instead of collapsing into a smear. */
.growth__plot {
  position: relative;
}

.growth__svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

.growth__grid line {
  stroke: rgba(74, 107, 82, 0.16);
  stroke-width: 1;
}

.growth__ylabels text,
.growth__xlabels text {
  font-family: var(--font-body);
  font-size: 13px;
  fill: var(--color-text-muted);
}

.growth__band {
  fill: rgba(201, 160, 81, 0.08);
}

.growth__area {
  fill: rgba(74, 107, 82, 0.14);
}

.growth__line {
  fill: none;
  stroke: var(--color-sage);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.growth__marker {
  stroke: var(--color-gold);
  stroke-width: 1.5;
  stroke-dasharray: 4 4;
}

.growth__peak {
  fill: var(--color-sage);
  stroke: var(--color-cream);
  stroke-width: 2;
}

.growth__peaklabel {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 600;
  fill: var(--color-text);
}

.growth__hits rect {
  fill: transparent;
}

/* The line draws itself in when the chart scrolls into view. */
.js .growth__line {
  stroke-dasharray: 2600;
  stroke-dashoffset: 2600;
}

.js .reveal.is-visible .growth__line {
  transition: stroke-dashoffset 1.9s var(--ease-out);
  stroke-dashoffset: 0;
}

.js .growth__area,
.js .growth__peak,
.js .growth__peaklabel,
.js .growth__marker,
.js .growth__band {
  opacity: 0;
  transition: opacity 0.6s ease 1s;
}

.js .reveal.is-visible .growth__area,
.js .reveal.is-visible .growth__peak,
.js .reveal.is-visible .growth__peaklabel,
.js .reveal.is-visible .growth__marker,
.js .reveal.is-visible .growth__band {
  opacity: 1;
}

/* Annotation sits over the chart, anchored to the late-April marker. */
.growth__annotation {
  position: absolute;
  left: 63.5%;
  top: 4%;
  width: min(30%, 15rem);
  padding-left: 0.7rem;
  border-left: 2px solid var(--color-gold);
  font-size: 0.84rem;
  line-height: 1.45;
  color: var(--color-text-muted);
}

/* Only meaningful once the plot is a scroll container, so hidden by default. */
.growth__hint {
  display: none;
  margin: 0.6rem 0 0;
  font-size: 0.8rem;
  color: var(--color-text-muted);
}

.growth__annotation strong {
  display: block;
  font-family: var(--font-display);
  color: var(--color-text);
}

.growth__tip {
  position: absolute;
  z-index: 3;
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -125%);
  padding: 0.45rem 0.65rem;
  border-radius: var(--radius);
  background-color: var(--color-text);
  color: var(--color-bg);
  font-size: 0.82rem;
  line-height: 1.35;
  white-space: nowrap;
  transition: opacity 0.15s ease;
}

.growth__tip.is-on {
  opacity: 1;
}

.growth__tip b {
  font-family: var(--font-display);
}

.growth__cursor {
  position: absolute;
  z-index: 2;
  width: 9px;
  height: 9px;
  margin: -4.5px 0 0 -4.5px;
  border-radius: 50%;
  background-color: var(--color-sage);
  box-shadow: 0 0 0 2px var(--color-cream);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease;
}

.growth__cursor.is-on {
  opacity: 1;
}

/* Every chart ships its numbers as a real table too. */
.chart__data {
  margin-top: var(--space-sm);
  font-size: 0.86rem;
}

.chart__data summary {
  cursor: pointer;
  color: var(--color-sage);
  font-family: var(--font-display);
  font-weight: 600;
}

.chart__data table {
  width: 100%;
  margin-top: 0.75rem;
  border-collapse: collapse;
}

.chart__data th,
.chart__data td {
  padding: 0.3rem 0.5rem;
  text-align: left;
  border-bottom: 1px solid rgba(74, 107, 82, 0.14);
}

/* Every data column right-aligns, whether the table has one number per row
   (last-child) or several (Month / 2023 / 2024 / YoY growth): any header
   after the first is a numeric column too, so it right-aligns to match. */
.chart__data td,
.chart__data thead th:not(:first-child) {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Vertical stacked bar (part-to-whole share of a fixed total) -------------- */
/* One hue, seven monotone lightness steps, largest share darkest. Generated
   and validated as an ORDINAL ramp (not categorical): fixed hue 151.5°
   matching --color-sage, OKLCH L stepped 0.70 -> 0.32, chroma 0.055 to match
   sage's own chroma. Passes lightness-monotone, adjacent-DeltaL >= 0.06, and
   light-end contrast >= 2:1 against the card surface (validate_palette.js
   --ordinal). Do not hand-tweak these hexes without re-running that check. */
.stackbar {
  display: flex;
  justify-content: center;
  margin: var(--space-lg) 0 var(--space-sm);
}

.stackbar__frame {
  position: relative;
  width: 150px;
}

.stackbar__bar {
  display: flex;
  flex-direction: column;
  gap: 2px;
  width: 150px;
  height: 420px;
}

.stackbar__seg {
  flex: var(--val) 1 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 0 0.4rem;
}

.stackbar__seg:first-child {
  border-top-left-radius: var(--radius-lg);
  border-top-right-radius: var(--radius-lg);
}

.stackbar__seg:last-child {
  border-bottom-left-radius: var(--radius-lg);
  border-bottom-right-radius: var(--radius-lg);
}

.stackbar__seg--1 { background-color: #1B3B24; }
.stackbar__seg--2 { background-color: #2C4C34; }
.stackbar__seg--3 { background-color: #3D5D45; }
.stackbar__seg--4 { background-color: #4E6F56; }
.stackbar__seg--5 { background-color: #608268; }
.stackbar__seg--6 { background-color: #73957B; }
.stackbar__seg--7 { background-color: #86A98D; }

/* Inline label: only the four largest segments have room for one. Always
   light text, since all four fall dark enough that light text is the only
   option clearing 4.5:1 (verified per-segment, not assumed). */
.stackbar__seg-label {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  color: var(--color-bg);
  line-height: 1.15;
}

.stackbar__seg-name {
  font-size: 0.74rem;
}

.stackbar__seg-value {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.05rem;
}

/* The three smallest segments (<=7%) have no room for inline text, so their
   label sits outside the bar, tied to its segment's vertical center by a
   short leader line. Position is a plain percentage of the bar's height,
   matching each segment's true center in the 0-100 stack (the 2px gaps are
   a few px total and don't shift these enough to matter). */
/* left + top only, height matches the bar. Width is deliberately auto: setting
   a right edge too would zero out the box (100% - 100% - 0), leaving the
   labels overflowing an invisible zero-width container with nothing to
   reserve their space in the page's normal flow. */
.stackbar__callouts {
  position: absolute;
  left: 100%;
  top: 0;
  height: 100%;
}

.stackbar__callout {
  position: absolute;
  left: 0;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  gap: 0.5rem;
  white-space: nowrap;
}

.stackbar__callout-line {
  width: 14px;
  height: 1px;
  background-color: rgba(74, 107, 82, 0.4);
  flex: none;
}

.stackbar__callout-label {
  font-size: 0.82rem;
  color: var(--color-text-muted);
}

.stackbar__callout-label b {
  font-family: var(--font-display);
  color: var(--color-text);
}

/* Plain legend for the three smallest segments, shown only below ~620px in
   place of the leader-line callouts. At a shorter mobile bar height those
   three anchor points (87 / 93.5 / 97%) sit too close together in absolute
   pixels for wrapped multi-line labels to avoid overlapping each other, and
   there's no shorter label text that fixes that. A plain key is the honest
   fallback once a segment is too small to point a line at legibly. */
.stackbar__legend {
  display: none;
  list-style: none;
  margin: var(--space-sm) 0 0;
  padding: 0;
}

.stackbar__legend li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.82rem;
  color: var(--color-text-muted);
}

.stackbar__legend li + li {
  margin-top: 0.35rem;
}

.stackbar__legend b {
  font-family: var(--font-display);
  color: var(--color-text);
}

.stackbar__legend-swatch {
  width: 10px;
  height: 10px;
  border-radius: 2px;
  flex: none;
}

/* The chart card's own padding eats into the width budget this needs, so a
   narrower bar keeps the figure inside a phone-width card. */
@media (max-width: 620px) {
  .stackbar {
    flex-direction: column;
    align-items: center;
  }

  .stackbar__frame,
  .stackbar__bar {
    width: 112px;
  }

  .stackbar__bar {
    height: 340px;
  }

  .stackbar__callouts {
    display: none;
  }

  .stackbar__legend {
    display: block;
  }
}

/* Multivariate test grid -------------------------------------------------- */
.variant-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-md);
  margin: var(--space-lg) 0 0;
}

.variant {
  margin: 0;
}

.variant__frame {
  aspect-ratio: 3 / 4;
  border-radius: var(--radius);
  padding: 0.9rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  color: var(--color-bg);
  overflow: hidden;
}

.variant__frame--cool {
  background: linear-gradient(170deg, #3d5a63 0%, #24424f 100%);
}

.variant__frame--warm {
  background: linear-gradient(170deg, #b9714f 0%, #8f4c33 100%);
}

.variant__logo {
  height: 6px;
  width: 42%;
  border-radius: 3px;
  background-color: rgba(250, 249, 246, 0.75);
}

.variant__headline {
  margin: 0.15rem 0 0;
  font-family: var(--font-display);
  font-size: 0.82rem;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.01em;
  text-transform: uppercase;
}

.variant__headline em {
  font-style: normal;
  color: var(--color-gold);
}

.variant__form {
  margin-top: auto;
  background-color: rgba(250, 249, 246, 0.94);
  border-radius: 2px;
  padding: 0.4rem;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.variant__form span {
  display: block;
  height: 5px;
  border-radius: 1px;
  background-color: rgba(43, 43, 43, 0.16);
}

/* Scoped so it wins over the generic field rule above. */
.variant__form .variant__cta {
  margin-top: 3px;
  height: 9px;
  border-radius: 1px;
  background-color: #d97b2e;
}

/* The circled network stats that ran below the form on every live variant. */
.variant__proof {
  display: flex;
  justify-content: space-between;
  gap: 0.3rem;
  padding-top: 0.6rem;
}

.variant__proof b {
  flex: 1 1 0;
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  border: 1px solid rgba(250, 249, 246, 0.55);
  border-radius: 50%;
  font-family: var(--font-display);
  font-size: 0.5rem;
  font-weight: 600;
  text-align: center;
  line-height: 1.1;
}

.variant figcaption {
  margin-top: 0.7rem;
  font-size: 0.84rem;
  line-height: 1.45;
  color: var(--color-text-muted);
}

.variant figcaption strong {
  display: block;
  font-family: var(--font-display);
  color: var(--color-text);
}

/* Dashboard-style stat readout -------------------------------------------- */
.readout {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-md);
  margin: 0;
  padding: var(--space-md);
  background-color: var(--color-bg);
  border: 1px solid rgba(74, 107, 82, 0.18);
  border-radius: var(--radius-lg);
}

.readout div {
  margin: 0;
}

.readout dt {
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: 0.2rem;
  order: 2;
}

.readout dd {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 3vw, 2rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
}

.readout div {
  display: flex;
  flex-direction: column;
}

.readout dd { order: 1; }

.readout .readout--lift dd {
  color: var(--color-sage);
}

/* Results on a full-bleed color field -------------------------------------- */
.result-list {
  list-style: none;
  margin: var(--space-lg) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-md);
}

.result-list li {
  padding-top: var(--space-sm);
  border-top: 2px solid rgba(250, 249, 246, 0.45);
}

.result-list .metric__value {
  color: var(--color-bg);
}

.result-list .metric__label {
  color: rgba(250, 249, 246, 0.86);
  margin: 0;
}

/* Stack row --------------------------------------------------------------- */
.stack-row {
  list-style: none;
  margin: var(--space-lg) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  align-items: flex-start;
}

.stack-row li {
  width: 6.75rem;
}

.stack-row a {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  text-decoration: none;
  border-radius: var(--radius);
}

.stack-row a:focus-visible {
  outline: 2px solid var(--color-sage);
  outline-offset: 4px;
}

/* Wide wordmarks and square marks share one box, so a wordmark is not shrunk
   to nothing just to fit a square. */
.stack-row img {
  width: 84px;
  height: 42px;
  object-fit: contain;
  filter: grayscale(1) contrast(0.95) brightness(0.85);
  mix-blend-mode: multiply;
  transition: filter 0.25s ease;
}

.stack-row a:hover img,
.stack-row a:focus-visible img {
  filter: none;
}

.stack-row a:hover span,
.stack-row a:focus-visible span {
  color: var(--color-sage-dark);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Fallback tile for a tool with no logo file, same footprint as the images. */
.stack-row__text {
  width: 84px;
  height: 42px;
  border-radius: var(--radius);
  display: grid;
  place-items: center;
  background-color: var(--color-sage-tint);
  color: var(--color-sage-dark);
  font-family: var(--font-display);
  font-size: 0.95rem;
  font-weight: 700;
}

.stack-row span {
  font-size: 0.78rem;
  text-align: center;
  color: var(--color-text-muted);
}

/* Prev / next case study --------------------------------------------------- */
.case-nav {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-md);
}

.case-nav__link {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding: var(--space-md);
  border: 1px solid rgba(74, 107, 82, 0.2);
  border-radius: var(--radius-lg);
  text-decoration: none;
  color: inherit;
  transition: transform 0.22s var(--ease-out), border-color 0.22s ease,
    box-shadow 0.22s var(--ease-out);
}

.case-nav__link:hover,
.case-nav__link:focus-visible {
  transform: translateY(-4px);
  border-color: var(--color-sage);
  box-shadow: 0 20px 36px -22px rgba(43, 43, 43, 0.32);
}

.case-nav__link--next {
  text-align: right;
}

.case-nav__dir {
  font-family: var(--font-display);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-sage);
}

.case-nav__title {
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

/* "The decision" two-column layout: prose left, attribution chart right. */
.decision-grid {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: var(--space-xl);
  align-items: start;
}

.decision-grid .step {
  margin-top: 0;
}

.decision-grid .chart {
  position: sticky;
  top: calc(var(--space-lg) + 60px);
  margin-top: 0;
}

@media (max-width: 900px) {
  .decision-grid {
    grid-template-columns: 1fr;
  }

  .decision-grid .chart {
    position: static;
    order: -1;
  }
}

/* Case study responsive ---------------------------------------------------- */
@media (max-width: 900px) {
  .case-meta {
    grid-template-columns: repeat(2, 1fr);
  }

  .chart-grid {
    grid-template-columns: 1fr;
  }

  .figure-grid--3 {
    grid-template-columns: repeat(2, 1fr);
  }

  .chain__list {
    grid-template-columns: repeat(2, 1fr);
  }

  /* Only the horizontal neighbours keep a connector once the chain wraps. */
  .chain__step:nth-child(3)::before,
  .chain__step:nth-child(3)::after {
    display: none;
  }

  .variant-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  /* The annotation would sit on top of the peak at this width, so it drops
     below the plot and loses its absolute anchoring. */
  .growth__annotation {
    position: static;
    width: auto;
    margin-top: var(--space-sm);
    border-left: 0;
    border-top: 2px solid var(--color-gold);
    padding: 0.6rem 0 0;
  }
}

@media (max-width: 720px) {
  .growth__plot,
  .qbars__plot {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  .growth__svg {
    min-width: 620px;
    overflow: hidden;
  }

  /* Seven columns need less room than 26 weekly points, but the axis labels
     still go unreadable if the 940-unit viewBox is squeezed into a phone. */
  .qbars__svg {
    min-width: 560px;
    overflow: hidden;
  }

  .growth__hint {
    display: block;
  }
}

@media (max-width: 620px) {
  .case-meta,
  .readout,
  .result-list,
  .case-nav,
  .figure-grid--2,
  .figure-grid--3,
  .chain__list {
    grid-template-columns: 1fr;
  }

  .chain__step + .chain__step::before,
  .chain__step + .chain__step::after {
    display: none;
  }

  .figure-grid--2,
  .figure-grid--3 {
    --shot-h: 380px;
  }

  .variant-grid {
    grid-template-columns: 1fr;
  }

  /* One per row, so cap the width rather than squash the aspect. A short
     frame clipped the network-stat circles off the bottom. */
  .variant__frame {
    max-width: 300px;
  }

  .variant figcaption {
    max-width: 300px;
  }

  .case-nav__link--next {
    text-align: left;
  }

  .step__head {
    flex-direction: column;
    gap: 0.2rem;
  }
}

/* Mountain dividers ------------------------------------------------------- */
.divider {
  display: block;
  width: 100%;
  height: auto;
  line-height: 0;
}

/* Reveal-on-scroll. Only hidden when JS is active, so no-JS shows everything. */
.js .reveal {
  opacity: 0;
  transform: translateY(var(--reveal-dist));
  transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: opacity, transform;
}

.js .reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* Rebrand film ------------------------------------------------------------ */
/* Full-bleed moment on the repositioning case study. The Agolo-to-Implicit
   logo animation plays as a muted, looping background video. The <video> is
   decorative, so the real before/after evidence is the .filmstrip wordmark
   pair below it, which is also the entire no-JS and reduced-motion view. */
.rebrand-film {
  position: relative;
  overflow: hidden;
  background: var(--color-cream);
}

.rebrand-film__video {
  display: block;
  width: 100%;
  max-width: 660px;
  height: auto;
  /* Generous top margin so the clip reads as its own beat rather than being
     crowded by the paragraph above it. */
  margin: var(--space-lg) auto 0;
  border-radius: var(--radius-lg);
}

/* Static evidence: the two wordmarks side by side with an arrow between. */
.filmstrip {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(1.5rem, 5vw, 4rem);
  margin-top: var(--space-lg);
}

.filmstrip__mark img {
  display: block;
  width: auto;
  height: clamp(28px, 4.4vw, 44px);
}

.filmstrip__mark figcaption {
  margin-top: 0.6rem;
  font-family: var(--font-body);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  text-align: center;
}

.filmstrip__arrow {
  flex: none;
  width: clamp(28px, 5vw, 56px);
  height: 2px;
  position: relative;
  background: var(--color-gold);
}

.filmstrip__arrow::after {
  content: "";
  position: absolute;
  right: 0;
  top: 50%;
  width: 9px;
  height: 9px;
  border-top: 2px solid var(--color-gold);
  border-right: 2px solid var(--color-gold);
  transform: translateY(-50%) rotate(45deg);
}

/* Screenshot frames ------------------------------------------------------- */
/* Page captures are 5,000-13,000px tall, so they are cropped to their hero
   region at build time and then clipped to a fixed aspect here. Top-anchored
   so the headline, the thing being evidenced, is always the visible part. */
.shot {
  margin: 0;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-cream);
  border: 1px solid rgba(74, 107, 82, 0.18);
  box-shadow: 0 18px 40px -28px rgba(43, 43, 43, 0.5);
}

.shot__chrome {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0.55rem 0.8rem;
  background: rgba(74, 107, 82, 0.07);
  border-bottom: 1px solid rgba(74, 107, 82, 0.14);
}

.shot__chrome span {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: rgba(74, 107, 82, 0.28);
}

.shot__chrome b {
  margin-left: 0.5rem;
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--color-text-muted);
}

.shot img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 340px;
  object-fit: cover;
  object-position: top center;
}

.shot figcaption {
  padding: 0.7rem 0.9rem 0.85rem;
  font-size: 0.82rem;
  line-height: 1.45;
  color: var(--color-text-muted);
  border-top: 1px solid rgba(74, 107, 82, 0.12);
}

.shot-pair {
  display: grid;
  gap: var(--space-md);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* .shot zeroes its own margin so a parent grid's gap can own the spacing.
   Stacked directly inside a step there is no such grid, so captures collide
   with each other and with the copy above them. Give them the same top
   rhythm .figure already carries. */
.step > .shot,
.step > .shot-pair {
  margin-top: var(--space-lg);
}

/* Positioning progression -------------------------------------------------- */
/* Alternating rows, one per version of the site. The headline of each version
   is quoted verbatim as the primary evidence and the capture backs it up. */
/* Each row is a whole version of the positioning, so they need clear air
   between them or the three read as one continuous block. */
.posline {
  display: grid;
  gap: var(--space-2xl);
}

.posrow {
  display: grid;
  gap: var(--space-md);
  grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
  align-items: center;
}

.posrow:nth-child(even) .posrow__copy {
  order: 2;
}

.posrow__stamp {
  display: inline-flex;
  align-items: baseline;
  gap: 0.5rem;
  margin: 0 0 0.7rem;
}

.posrow__version {
  font-family: var(--font-display);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-bg);
  background: var(--color-sage);
  padding: 0.22rem 0.5rem;
  border-radius: 3px;
}

.posrow__when {
  font-family: var(--font-body);
  font-size: 0.8rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

/* The verbatim headline from that version of the site. */
.posrow__headline {
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 2.5vw, 1.85rem);
  font-weight: 600;
  line-height: 1.18;
  letter-spacing: -0.02em;
  margin: 0 0 0.75rem;
  padding-left: 0.85rem;
  border-left: 3px solid var(--color-gold);
}

.posrow__note {
  margin: 0;
  color: var(--color-text-muted);
}

.posrow__note + .posrow__note {
  margin-top: 0.7rem;
}

/* Scope decision ---------------------------------------------------------- */
/* What the positioning committed to versus what it deliberately ruled out.
   The rejected column is the more persuasive half, so it gets equal weight. */
.scope-grid {
  display: grid;
  gap: var(--space-md);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.scope {
  padding: var(--space-md);
  border-radius: var(--radius-lg);
  background: var(--color-cream);
  border: 1px solid rgba(74, 107, 82, 0.18);
}

.scope--out {
  background: transparent;
  border-style: dashed;
}

.scope__title {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
  margin: 0 0 0.9rem;
}

/* Column icons, echoing the per-item check and slash markers below them so
   each column reads as committed or rejected before any of it is read. */
.scope__icon {
  flex: none;
  width: 1.35rem;
  height: 1.35rem;
  color: var(--color-sage);
}

.scope__icon--out {
  color: var(--color-text-muted);
  opacity: 0.75;
}

.scope__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.65rem;
}

.scope__list li {
  display: grid;
  grid-template-columns: 1.15rem minmax(0, 1fr);
  gap: 0.6rem;
  align-items: start;
  font-size: 0.94rem;
  line-height: 1.5;
}

.scope__list li::before {
  content: "";
  width: 1.15rem;
  height: 1.15rem;
  margin-top: 0.12rem;
  border-radius: 50%;
  background: var(--color-sage);
  /* Check mark, drawn so no icon font or image is needed. */
  clip-path: polygon(19% 52%, 33% 38%, 43% 48%, 68% 23%, 82% 37%, 43% 76%);
}

.scope--out .scope__list li::before {
  background: var(--color-text-muted);
  opacity: 0.55;
  /* Slash, distinguishing ruled-out from committed at a glance. */
  clip-path: polygon(22% 44%, 78% 44%, 78% 58%, 22% 58%);
}

.scope__list b {
  font-weight: 600;
}

.scope__list span {
  color: var(--color-text-muted);
}

/* Quarterly column chart --------------------------------------------------- */
/* Seven quarters with a 1,133x range, so columns rather than a line. A linear
   line would flatten the first five quarters into the baseline and lose the
   step changes, which are the whole point. */
.qbars {
  position: relative;
}

.qbars__plot {
  position: relative;
}

.qbars__svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

.qbars__grid line {
  stroke: rgba(74, 107, 82, 0.16);
  stroke-width: 1;
}

.qbars__ylabels text,
.qbars__xlabels text {
  font-family: var(--font-body);
  font-size: 13px;
  fill: var(--color-text-muted);
}

.qbars__values text {
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 600;
  fill: var(--color-text);
}

.qbars__bar {
  fill: var(--color-sage);
}

/* The Agolo quarter is held apart in a neutral tone: same axis, different
   company, and it is the baseline the rest of the chart argues against. */
.qbars__bar--agolo {
  fill: rgba(90, 90, 86, 0.45);
}

/* The v3 quarter is the payoff, so it carries the one terracotta accent. */
.qbars__bar--peak {
  fill: var(--color-terracotta);
}

.qbars__hits rect {
  fill: transparent;
}

/* Columns grow from the baseline when the chart scrolls into view. */
.js .qbars__bar {
  transform: scaleY(0);
  transform-origin: center bottom;
  transform-box: fill-box;
}

.js .reveal.is-visible .qbars__bar {
  transition: transform 1.1s var(--ease-out);
  transition-delay: var(--bar-delay, 0ms);
  transform: scaleY(1);
}

.js .qbars__values text {
  opacity: 0;
  transition: opacity 0.5s ease;
  transition-delay: var(--bar-delay, 0ms);
}

.js .reveal.is-visible .qbars__values text {
  opacity: 1;
}

/* Phase ribbon under the chart, tying quarters to site versions. */
.qphases {
  display: grid;
  grid-template-columns: 1fr 5fr 1fr;
  gap: 3px;
  margin-top: 0.7rem;
}

.qphase {
  padding: 0.45rem 0.6rem;
  border-radius: 3px;
  font-family: var(--font-body);
  font-size: 0.74rem;
  line-height: 1.3;
  text-align: center;
  color: var(--color-text-muted);
  background: rgba(74, 107, 82, 0.08);
}

.qphase b {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--color-text);
}

.qphase--agolo {
  background: rgba(90, 90, 86, 0.14);
}

.qphase--peak {
  background: rgba(168, 101, 79, 0.14);
}

/* Responsive -------------------------------------------------------------- */
@media (max-width: 860px) {
  .posrow {
    grid-template-columns: minmax(0, 1fr);
  }

  .posrow:nth-child(even) .posrow__copy {
    order: 0;
  }

  /* Stacked rows are already visually separated by the capture, so the full
     desktop gap becomes dead scrolling here. */
  .posline {
    gap: var(--space-xl);
  }

  .scope-grid,
  .shot-pair {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Stacked, the horizontal connectors point nowhere, so they rotate to sit
     in the vertical gap between steps. */
  .path {
    grid-template-columns: minmax(0, 1fr);
  }

  .path__step + .path__step::before {
    top: calc(var(--space-md) * -1);
    left: 50%;
    width: 2px;
    height: var(--space-md);
  }

  .path__step + .path__step::after {
    top: -0.55rem;
    left: 50%;
    transform: translateX(-50%) rotate(135deg);
  }

  /* Stacked, the connector runs top to bottom, so the draw has to scale on
     the other axis. Without this the 2px-wide rule would animate its width
     and never appear to grow. */
  html.js .path[data-path-progress] .path__step + .path__step::before {
    transform: scaleY(0);
    transform-origin: center top;
  }

  html.js .path[data-path-progress] .path__step.is-lit::before {
    transform: scaleY(1);
  }

  .qphases {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Reduced motion and no-JS both fall back to the static wordmark pair, so the
   before/after is never dependent on video playback. */
@media (prefers-reduced-motion: reduce) {
  .rebrand-film__video {
    display: none;
  }
}

html:not(.js) .rebrand-film__video {
  display: none;
}

/* Responsive -------------------------------------------------------------- */
@media (max-width: 720px) {
  .primary-nav__toggle {
    display: inline-block;
  }

  .primary-nav__list {
    display: none;
    position: absolute;
    top: 100%;
    right: 0;
    left: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background-color: var(--color-bg);
    border-bottom: 1px solid var(--color-sage-tint);
    padding: var(--space-sm) clamp(1.25rem, 5vw, 2.5rem);
  }

  .primary-nav__list.is-open {
    display: flex;
  }

  .primary-nav__link {
    padding-block: 0.75rem;
    border-bottom: 1px solid var(--color-sage-tint);
  }

  .site-header__inner {
    position: relative;
  }

  .pillars,
  .cta-split,
  .work-grid,
  .faq,
  .card-grid--2 {
    grid-template-columns: 1fr;
  }

  .card-grid--4,
  .card-grid--5 {
    grid-template-columns: 1fr;
  }

  .stat-strip {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 900px) and (min-width: 721px) {
  .stat-strip,
  .card-grid--4,
  .card-grid--5 {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Player/coach pair: below the enhanced-view breakpoint the section is just
   .container (body) followed by .player-coach__media in normal flow, so no
   layout override is needed to stack them, only a narrower cap on the media
   block so the pair reads better side by side until phone width. */
@media (max-width: 900px) {
  .player-coach__media {
    max-width: 620px;
  }
}

@media (max-width: 900px) and (min-width: 521px) {
  .pc-frame {
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-xs);
  }
}

@media (max-width: 1080px) and (min-width: 901px) {
  .card-grid--5 {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* Capabilities + stack responsive ----------------------------------------- */
@media (max-width: 860px) {
  .capabilities {
    grid-template-columns: 1fr;
    gap: var(--space-md);
  }

  .cap-stage {
    position: static;
    min-height: 0;
  }

  .cap-item__desc {
    max-height: none;
    opacity: 1;
  }
}

/* On narrow screens the animated knowledge graph is cramped, so show the
   clean grouped list instead, back in normal document flow. */
@media (max-width: 720px) {
  .js .stack__canvas-wrap[data-constellation] .stack__fallback {
    position: relative;
    width: auto;
    height: auto;
    padding: 1.5rem;
    margin: 0;
    overflow: visible;
    clip: auto;
    white-space: normal;
  }

  .stack__canvas-wrap[data-constellation] .stack__nodes,
  .stack__canvas-wrap[data-constellation] .stack__canvas {
    display: none;
  }

  .stack__canvas-wrap {
    position: relative;
    inset: auto;
  }

  .stack {
    min-height: 0;
    display: block;
  }
}

/* Reduced motion ---------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }

  .reveal {
    opacity: 1;
    transform: none;
  }

  .hero h1 .word,
  .rotator__word.is-active {
    opacity: 1;
    transform: none;
  }

  /* The engagement path resolves to its finished state. JS also lights every
     step immediately here, so this is a second guarantee rather than the
     mechanism. transform: none rather than a scale keeps it correct in both
     the three-column and the stacked orientation. */
  html.js .path[data-path-progress] .path__step {
    opacity: 1;
    transform: none;
  }

  html.js .path[data-path-progress] .path__step + .path__step::before {
    transform: none;
  }

  html.js .path[data-path-progress] .path__step + .path__step::after {
    opacity: 1;
  }
}
