/* ==========================================================================
   Fonts — Inter 4.1 (rsms/inter, GitHub release v4.1), self-hosted variable
   ========================================================================== */

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("assets/fonts/InterVariable.woff2") format("woff2");
}

@font-face {
  font-family: "Inter";
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url("assets/fonts/InterVariable-Italic.woff2") format("woff2");
}

/* ==========================================================================
   Design tokens
   Named after the Figma styles where one exists (Neutral 100–900,
   Warning 400, Text Md, Shadow Sm). Free-floating values from the frame were
   folded into the scales below.
   ========================================================================== */

:root {
  /* Color — neutral scale */
  --color-neutral-0: #ffffff;
  --color-neutral-50: #f7f7f3;   /* half-step between white and 100 */
  --color-neutral-100: #efefe8;
  --color-neutral-300: #b3b3ad;
  --color-neutral-400: #969691;
  --color-neutral-600: #60605d;
  --color-neutral-700: #464644;
  --color-neutral-800: #2e2e2d;  /* also the footer logo mark (set in logo-mark.svg) */
  --color-neutral-900: #181817;

  /* Color — accent */
  --color-warning-400: #fc8b2c;

  /* Color — semantic */
  --color-bg: var(--color-neutral-0);
  --color-surface: var(--color-neutral-0);
  --color-surface-sunken: var(--color-neutral-50);   /* trays behind cards */
  --color-text: var(--color-neutral-900);
  --color-text-body: var(--color-neutral-700);
  --color-text-muted: var(--color-neutral-600);
  --color-text-subtle: var(--color-neutral-400);
  --color-border: var(--color-neutral-100);
  --color-icon: var(--color-neutral-400);
  --color-primary: var(--color-warning-400);
  --color-on-primary: var(--color-neutral-0);
  --color-secondary: var(--color-neutral-100);
  --color-on-secondary: var(--color-neutral-800);
  --color-primary-hover: color-mix(in oklab, var(--color-primary), #000 6%);
  --color-secondary-hover: color-mix(in oklab, var(--color-secondary), var(--color-neutral-900) 5%);

  /* Color — client brand tiles (logo backgrounds) */
  --color-brand-bbb: #e9f3ff;
  --color-brand-owner1st: #051b42;
  --color-brand-button: #1178f9;

  /* Typography */
  --font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-size-md: 14px;
  --font-size-price: 20px;                          /* restrained pricing figures */
  --font-size-label: 12px;                          /* pricing labels */
  --line-height-price: 1.15;                        /* pricing figures */
  --letter-spacing-price: -0.02em;                  /* pricing figures */
  --font-weight-regular: 400;
  --font-weight-medium: 500;
  --line-height-auto: normal;    /* Figma "Auto" — Inter's own metrics (≈1.21) */
  --line-height-md: 17.9px;      /* Text Md */
  --line-height-prose: 1.55;     /* long-form reading (legal pages) */
  --letter-spacing-0: 0;

  /* Spacing */
  --space-3: 3px;
  --space-6: 6px;
  --space-8: 8px;
  --space-10: 10px;
  --space-12: 12px;
  --space-16: 16px;
  --space-18: 18px;
  --space-20: 20px;
  --space-22: 22px;
  --space-24: 24px;
  --space-32: 32px;
  --space-48: 48px;
  --space-72: 72px;
  --space-98: 98px;

  /* Radius */
  --radius-md: 8px;
  --radius-lg: 12px;
  --radius-xl: 18px;
  --radius-full: 100px;

  /* Shadow — "Shadow Sm". CSS paints the first shadow on top, so the
     1px drop sits above the hairline ring, same order as the Figma stack. */
  --shadow-ring: 0 0 0 1px var(--color-neutral-100);
  --shadow-drop-sm: 0 1px 1px 0 rgb(0 0 0 / 0.08);
  --shadow-sm: var(--shadow-drop-sm), var(--shadow-ring);
  /* "Shadow Lg" — cards. Same hairline ring under three soft drops,
     listed top layer first. */
  --shadow-lg:
    0 1px 1px 0 rgb(0 0 0 / 0.08),
    0 4px 8px -3px rgb(0 0 0 / 0.06),
    0 7px 28px -7px rgb(0 0 0 / 0.04),
    var(--shadow-ring);

  /* Layout */
  --gap-intro: 56px;                                /* hero, logo ticker, first section (Figma: 48) */
  --gap-section: 84px;                              /* between sections and to the footer (Figma: 72) */
  --container-width: 501px;
  --gutter: 16px;
  --page-pad-top: var(--space-98);
  --page-pad-bottom: var(--space-98);

  /* Component sizes */
  --button-height: 32px;
  --tile-size: 40px;
  --avatar-size: 24px;
  --section-icon-size: 18px;
  --row-height: 42px;
  --industry-label-width: 112px;
  --logo-strip-height: 55px;
  --ticker-gap: 48px;
  --ticker-logo-size: 1.08;                         /* all logos, relative to Figma; the 55px strip stays put */
  --ticker-duration: 40s;                           /* one loop ≈ 21px/s — unhurried */

  /* Motion — curves and budgets from Emil Kowalski's skills
     (github.com/emilkowalski/skills). Built-in CSS easings are too weak. */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);       /* enter / exit, press */
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);   /* on-screen movement */
  --ease-hover: ease;                               /* hover / color change */
  --duration-press: 160ms;
  --duration-hover: 150ms;
  --ease-enter: ease;                               /* Sonner: `ease` over `ease-out` for elegance */
  --duration-enter: 300ms;                          /* `ease`, Sonner-style, kept snappy */
  --stagger: 35ms;                                  /* 30–80ms; overlaps into one wave */
  --enter-distance: 6px;
  --enter-blur: 2px;                                /* softens the fade-in; keep < 20px */
  --press-scale: 0.97;
  --opacity-dimmed: 0.45;                           /* siblings during list hover */
  --ease-out-moderate: cubic-bezier(0.215, 0.61, 0.355, 1); /* easeOutCubic — moves at once, settles gently */
  --duration-accordion: 200ms;                      /* one value for open and close, so a swap stays in sync */
  --accordion-answer-lines: 3;                      /* every answer reserves the same height */
  --duration-dim: 280ms;                            /* list hover: unfolds evenly, still under 300ms */
}

/* ==========================================================================
   Base
   ========================================================================== */

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* Always reserve the scrollbar's space, so a short page (no scrollbar)
     centres its content in exactly the same place as a long one. */
  scrollbar-gutter: stable;
  scroll-behavior: smooth; /* in-page links (footer → sections) glide */
}

/* Jump targets land with breathing room above them, not flush to the top. */
[id] {
  scroll-margin-top: var(--space-48);
}

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

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-auto);
  letter-spacing: var(--letter-spacing-0);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

h1,
h2,
h3 {
  margin: 0;
  font: inherit;
}

p,
ul,
li,
blockquote,
figure {
  margin: 0;
  padding: 0;
}

ul {
  list-style: none;
}

img,
svg {
  display: block;
}

a {
  color: inherit;
  text-decoration: none;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ==========================================================================
   Layout
   ========================================================================== */

.page {
  width: min(var(--container-width), 100% - var(--gutter) * 2);
  margin-inline: auto;
  padding-block: var(--page-pad-top) var(--gap-section); /* to the footer, same as between sections */
  display: flex;
  flex-direction: column;
  gap: var(--gap-intro); /* hero → logo ticker → first section */
}

/* Inner pages open with just the logo, so the content can sit closer —
   the hero's own logo-to-copy gap. */
.page--inner {
  gap: var(--space-32);
}

.sections {
  display: flex;
  flex-direction: column;
  gap: var(--gap-section);
}

/* ==========================================================================
   Hero
   ========================================================================== */

.hero {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-32);
}

.hero__logo {
  width: 123.529px;
  height: 21px;
}

/* Co-branded logo (?ref=…): the same mark and wordmark at exactly the same
   scale (the art is 4.05× larger, so 0.24706×), plus a "by …" line below.
   The logo's box grows by that line (11.365px), so the usual gap is kept
   below the full lockup and everything underneath moves down evenly. */
.hero__logo--cobrand {
  height: 32.3647px;
}

.hero__copy {
  display: flex;
  flex-direction: column;
  gap: var(--space-20);
  color: var(--color-text-body);
}

.hero__actions {
  display: flex;
  align-items: center;
  gap: var(--space-8);
}

/* ==========================================================================
   Button
   ========================================================================== */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: var(--button-height);
  padding-inline: var(--space-12);
  border-radius: var(--radius-md);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-md);
  white-space: nowrap;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  transition:
    transform var(--duration-press) var(--ease-out),
    background-color var(--duration-hover) var(--ease-hover);
}

/* Press feedback — ungated, :active is a real press on touch too */
.button:active {
  transform: scale(var(--press-scale));
}

/* Hover only where a real pointer can hover; touch fires false hovers */
@media (hover: hover) and (pointer: fine) {
  .button--primary:hover {
    background-color: var(--color-primary-hover);
  }

  .button--secondary:hover {
    background-color: var(--color-secondary-hover);
  }
}

.button:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

.button--primary {
  background: var(--color-primary);
  color: var(--color-on-primary);
}

.button--secondary {
  background: var(--color-secondary);
  color: var(--color-on-secondary);
}

/* ==========================================================================
   Client logo ticker
   Two identical sets side by side; the track slides left by exactly one set
   and loops, so the seam is invisible. Constant motion: `linear`, CSS
   keyframes (runs off the main thread). Edges fade over the outer 25%.
   Spacing is optical, not mechanical: each gap is set individually so
   every pair of logos reads the same distance apart (see below).
   ========================================================================== */

.logos {
  height: var(--logo-strip-height);
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 25%, #000 74.5192%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0%, #000 25%, #000 74.5192%, transparent 100%);
}

.ticker {
  color: var(--color-neutral-300); /* logo ink — the SVGs fill with currentColor */
  display: flex;
  width: max-content;
  height: 100%;
  animation: ticker var(--ticker-duration) linear infinite;
}

@keyframes ticker {
  to {
    transform: translateX(-50%);
  }
}

.ticker__set {
  display: flex;
  flex: none;
  height: 100%;
}

.ticker__item {
  flex: none;
  display: flex;
  align-items: center;
  height: 100%;
  /* Each logo owns the gap to its right neighbour (the last one's gap
     leads into the next loop), so every gap can be set on its own. */
  padding-right: var(--gap-after, var(--ticker-gap));
}

/* Logos are inline SVG, not <img>: browsers draw images at low quality
   while they animate, which pixelates them; inline vectors are drawn at full
   screen resolution. Each logo is written out in full in its own slot (no
   <use>/<symbol>, which Safari can mis-clip). */
.ticker__item svg {
  display: block;
  flex: none;
  overflow: visible;
}

/* Optical size balancing. At spec size GrowthBook and Owner 1st carry
   roughly twice the ink of Skaled and Interstaff, so they read bigger.
   Each logo is scaled a little toward the group's visual weight (a quarter
   of the way, so every logo stays within 8% of its Figma size). */
.ticker__item svg {
  width: calc(var(--logo-w) * var(--logo-scale, 1) * var(--ticker-logo-size));
  height: calc(var(--logo-h) * var(--logo-scale, 1) * var(--ticker-logo-size));
}

.ticker__item--skaled     { --logo-w: 75.6963px; --logo-h: 11.8px;    --logo-scale: 1.06; }
.ticker__item--owner1st   { --logo-w: 108.675px; --logo-h: 16.1px;    --logo-scale: 0.94; }
.ticker__item--bbb        { --logo-w: 48.2242px; --logo-h: 24.75px;   --logo-scale: 1; }
.ticker__item--interstaff { --logo-w: 103.807px; --logo-h: 18.179px;  --logo-scale: 1.04; }
.ticker__item--button     { --logo-w: 68px;      --logo-h: 17px;      --logo-scale: 1; }
.ticker__item--growthbook { --logo-w: 109.451px; --logo-h: 16.8525px; --logo-scale: 0.97; }

/* Optical spacing. Gaps are set so every neighbouring pair reads the same
   distance apart, not so their boxes are equal. Measured like type kerning:
   for each 1px row of the strip, the open space between the two logos' ink
   (counting at most 10px of empty space past an edge), averaged over the
   rows either logo occupies. Each gap below brings its pair to the group
   average of ~55px optical. */
.ticker__item--skaled     { --gap-after: 51.5px; } /* → Owner 1st */
.ticker__item--owner1st   { --gap-after: 44px; }   /* → BBB */
.ticker__item--bbb        { --gap-after: 44.5px; } /* → Interstaff: torch and round mark leave open corners */
.ticker__item--interstaff { --gap-after: 47px; }   /* → Button */
.ticker__item--button     { --gap-after: 47.5px; } /* → GrowthBook: its solid mark sits close */
.ticker__item--growthbook { --gap-after: 46.5px; } /* → Skaled (next loop) */

/* Vertical optical offsets (raise logos whose bounding box sits low
   against the others' baselines). Bottom padding lifts a logo by half its
   value, since each logo is centred in the 55px strip. */
.ticker__item--bbb { padding-bottom: 3.4375px; }
.ticker__item--interstaff { padding-bottom: 2.5px; }
.ticker__item--button { padding-bottom: 6.5px; }
.ticker__item--growthbook { padding-bottom: 5px; }

/* ==========================================================================
   Section heading (icon + label)
   ========================================================================== */

.section {
  display: flex;
  flex-direction: column;
  gap: var(--space-22);
}

.section--industries {
  gap: var(--space-16);
}

.section--testimonials {
  gap: var(--space-8);
}

.section__title {
  display: flex;
  align-items: center;
  gap: var(--space-6);
  color: var(--color-text-muted);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-auto);
}

.section__icon {
  flex: none;
  width: var(--section-icon-size);
  height: var(--section-icon-size);
}

/* ==========================================================================
   Item list (case studies, services)
   ========================================================================== */

.items {
  display: flex;
  flex-direction: column;
  gap: var(--space-18);
}

.item {
  position: relative;
  isolation: isolate; /* keeps the hover gap-filler inside the row */
  display: flex;
  align-items: center;
  gap: var(--space-10);
}

.item__text {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-3);
  white-space: nowrap;
}

.item__title {
  color: var(--color-text);
  font-weight: var(--font-weight-medium);
}

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

/* Logo tile */
.tile {
  position: relative;
  flex: none;
  width: var(--tile-size);
  height: var(--tile-size);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--tile-bg, var(--color-surface));
}

.tile--shadow {
  overflow: visible;
  box-shadow: var(--shadow-sm);
}

.tile > img {
  position: absolute;
}

.tile__img--centered {
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  object-fit: cover;
}

.tile--bbb {
  --tile-bg: var(--color-brand-bbb);
}

.tile--bbb > img {
  top: 0.9453px;
  left: 0.9453px;
  width: 38.1094px;
  height: 38.1094px;
  object-fit: cover;
  mix-blend-mode: darken;
}

.tile--owner1st {
  --tile-bg: var(--color-brand-owner1st);
}

.tile--button {
  --tile-bg: var(--color-brand-button);
}

/* ==========================================================================
   Industries table
   ========================================================================== */

.industries__group {
  display: flex;
  align-items: flex-start;
  border-top: 1px solid var(--color-border);
}

.industries__label {
  flex: none;
  display: flex;
  align-items: center;
  width: var(--industry-label-width);
  height: var(--row-height);
  color: var(--color-text-subtle);
  font-weight: var(--font-weight-medium);
  white-space: nowrap;
}

.industries__list {
  flex: 1 0 0;
  min-width: 0;
}

.industries__list li {
  display: flex;
  align-items: center;
  min-height: var(--row-height);
  color: var(--color-text);
}

.industries__list li:not(:last-child) {
  border-bottom: 1px solid var(--color-border);
}

/* The last group in the frame keeps a closing rule under its last row */
.industries__group:last-child .industries__list li:last-child {
  border-bottom: 1px solid var(--color-border);
}

/* ==========================================================================
   FAQs — accordion
   Same two-column layout as Industries. Only one answer is open at a time,
   and every answer reserves the same two-line height, so switching between
   questions moves height from one item to the other while the section's
   total height stays constant. Open and close share one duration and one
   curve, so the closing answer gives up exactly the height the opening one
   takes, frame by frame. The curve is a moderate ease-out: it starts moving
   immediately (no ease-in hesitation) and settles softly.
   The chevron turns on the same timing. Height is measured in JS, never
   animated to `auto`.
   ========================================================================== */

.faq {
  display: flex;
  align-items: flex-start;
}

.faq__title {
  flex: none;
  width: var(--industry-label-width);
  /* Match the question row's height (42px minus its 1px divider) so the
     "FAQs" text centres on the same line as the first question. The 18px
     icon then sits 0.5px higher than the 17px text, which reads as centred. */
  height: calc(var(--row-height) - 1px);
}

.faq__list {
  flex: 1 0 0;
  min-width: 0;
}

.faq__item:not(:last-child) {
  border-bottom: 1px solid var(--color-border);
}

.faq__trigger {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-16);
  width: 100%;
  padding: var(--space-12) 0;
  border: 0;
  background: none;
  color: var(--color-text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.faq__trigger:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
  border-radius: 2px;
}

.faq__chevron {
  flex: none;
  width: 18px;
  height: 18px;
  margin-block: -0.5px; /* 18px icon centred on the 17px text line */
  transition: transform var(--duration-accordion) var(--ease-out-moderate);
}

.faq__trigger[aria-expanded="true"] .faq__chevron {
  transform: rotate(180deg);
}

.faq__panel {
  overflow: hidden;
  opacity: 0;
  transition:
    height var(--duration-accordion) var(--ease-out-moderate),
    opacity var(--duration-accordion) var(--ease-out-moderate);
}

.js .faq__panel:not(.is-open) {
  height: 0;
}

.faq__panel.is-open {
  opacity: 1;
}

/* Without JS, panels can't be toggled — show every answer instead */
html:not(.js) .faq__panel[hidden] {
  display: block;
  opacity: 1;
}

.faq__answer {
  max-width: 336px;
  /* 18px below the question; the trigger's 12px bottom padding covers the rest */
  padding: calc(var(--space-18) - var(--space-12)) 0 var(--space-12);
  color: var(--color-text-muted);
  /* Reserve the longest answer's line count, so every answer opens to the same height */
  box-sizing: content-box;
  min-height: calc(var(--accordion-answer-lines) * 1lh);
}

/* ==========================================================================
   Title pair — a dark medium title over muted copy, 3px apart (the same
   pairing as a list item). Used by the CTA and the pricing intro.
   ========================================================================== */

.title-pair {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.title-pair__title {
  color: var(--color-text);
  font-weight: var(--font-weight-medium);
}

.title-pair__text {
  color: var(--color-text-muted);
}

/* ==========================================================================
   Call to action — closes a page with the hero's two buttons, 32px below
   its title pair (the hero's copy-to-buttons gap).
   ========================================================================== */

.section--cta {
  gap: var(--space-32);
}

.cta__actions {
  display: flex;
  align-items: center;
  gap: var(--space-8);
}

/* ==========================================================================
   Pricing — two small figures followed by plain service-style detail rows.
   ========================================================================== */

.section--pricing {
  gap: var(--space-22);
}

.pricing__intro {
  color: var(--color-text-body);
  line-height: var(--line-height-prose);
}

.pricing__figures {
  display: grid;
  grid-template-columns: minmax(0, calc(50% - var(--space-72))) minmax(0, 1fr);
  gap: var(--space-16);
  margin-block: var(--space-10);
}

@media (max-width: 420px) {
  .pricing__figures {
    grid-template-columns: minmax(0, calc(50% - var(--space-48))) minmax(0, 1fr);
  }
}

.pricing__figure {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-width: 0;
}

.pricing__figure-label,
.pricing__figure-detail {
  color: var(--color-text-muted);
  font-size: var(--font-size-label);
}

.pricing__figure-price {
  margin-block: var(--space-6) var(--space-3);
  color: var(--color-text);
  font-size: var(--font-size-price);
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-price);
  letter-spacing: var(--letter-spacing-price);
  font-variant-numeric: tabular-nums;
}

.pricing__figure-price span {
  color: var(--color-text-muted);
  font-size: var(--font-size-label);
  font-weight: var(--font-weight-regular);
  letter-spacing: var(--letter-spacing-0);
  white-space: nowrap;
}

@media (max-width: 360px) {
  .pricing__figures {
    grid-template-columns: max-content minmax(0, 1fr);
  }

  .pricing__figure-price span {
    display: block;
    margin-top: var(--space-3);
  }
}

.pricing__details {
  display: flex;
  flex-direction: column;
  gap: var(--space-32);
  margin-top: var(--space-10);
}

.pricing__stage h3 {
  color: var(--color-text);
  font-weight: var(--font-weight-medium);
}

.pricing__features {
  margin-top: var(--space-8);
  padding: 0;
  list-style: none;
  color: var(--color-text-body);
}

.pricing__features li {
  padding-block: var(--space-10);
  border-bottom: 1px solid var(--color-border);
  line-height: var(--line-height-md);
}

.pricing__features li:last-child {
  border-bottom: 0;
}

/* The logo links home on inner pages */
.hero__home {
  display: inline-block;
  border-radius: 2px;
}

.hero__home:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 4px;
}

/* ==========================================================================
   Legal pages (privacy, terms) — long-form reading in the same column.
   Section headings in the dark medium title style; body in Neutral 700 with
   a looser line height than UI text, since these are read, not scanned.
   ========================================================================== */

.legal {
  display: flex;
  flex-direction: column;
  gap: var(--space-32);
}

.prose__section {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  line-height: var(--line-height-prose);
  color: var(--color-text-body);
}

.prose__heading {
  color: var(--color-text);
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-auto);
}

.prose__link {
  color: var(--color-text);
  text-decoration: underline;
  text-decoration-color: var(--color-neutral-300);
  text-underline-offset: 2px;
  transition: text-decoration-color var(--duration-hover) var(--ease-hover);
}

@media (hover: hover) and (pointer: fine) {
  .prose__link:hover {
    text-decoration-color: currentColor;
  }
}

.prose__section strong {
  color: var(--color-text);
  font-weight: var(--font-weight-medium);
}

.prose__section ul {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.prose__section li {
  position: relative;
  padding-left: var(--space-16);
}

.prose__section li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 0.5lh; /* centred on the first line */
  width: 4px;
  height: 4px;
  border-radius: var(--radius-full);
  background: var(--color-text-subtle);
  transform: translateY(-50%);
}

/* ==========================================================================
   Case studies page — one section per client, headed like the home page's
   list rows (logo tile + name + one-line result), then the story in prose.
   ========================================================================== */

.cases {
  display: flex;
  flex-direction: column;
  gap: var(--space-48);
}

.case {
  display: flex;
  flex-direction: column;
  gap: var(--space-22);
  padding-top: var(--space-48);
  border-top: 1px solid var(--color-border);
}

.cases > .case:first-of-type {
  padding-top: 0;
  border-top: 0;
}

.case__header {
  display: flex;
  align-items: center;
  gap: var(--space-10);
}

/* Home page case study rows link to their section on the case studies page */
.item__link {
  display: flex;
  align-items: center;
  gap: var(--space-10);
  color: inherit;
  border-radius: var(--radius-md);
}

.item__link:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 4px;
}

/* ==========================================================================
   Footer
   Mirrors the FAQ layout: a 112px brand column, then three equal-width link
   columns sharing the remaining width, so every column starts the same
   distance from the last. The logo's mark alone sits in the brand column,
   its top aligned with the tops of the headings' capital letters. Headings are the darkest text, links the muted
   grey; links darken on hover with the same fade as the buttons.
   ========================================================================== */

.site-footer {
  width: min(var(--container-width), 100% - var(--gutter) * 2);
  margin-inline: auto;
  padding-bottom: var(--page-pad-bottom);
}

.footer {
  display: flex;
  align-items: flex-start;
  padding-top: var(--space-22);
  border-top: 1px solid var(--color-border);
}

.footer__brand {
  flex: none;
  display: flex;
  align-items: flex-start;
  width: var(--industry-label-width);
}

.footer__logo {
  width: 28.5628px; /* the logo's mark alone (28.45 × 19.921), scaled to 20px tall */
  height: 20px;
  /* Optical alignment: the mark's top meets the top of the headings' capital
     letters, not the top of their line box. The headings' baseline sits 1em
     below the line top, and capitals rise 1cap from it. */
  margin-top: calc(1em - 1cap);
}

.footer__nav {
  flex: 1 0 0;
  min-width: 0;
  padding-left: var(--space-32); /* sets the columns in from the FAQ answer edge */
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  /* Columns start 135px apart (87px column + 48px gap), the same rhythm as
     before the 32px shift. */
  gap: var(--space-48);
}

.footer__heading {
  color: var(--color-text);
  font-weight: var(--font-weight-medium);
}

.footer__links {
  display: flex;
  flex-direction: column;
  gap: var(--space-10);
  margin-top: var(--space-12);
}

.footer__links a {
  color: var(--color-text-muted);
  transition: color var(--duration-hover) var(--ease-hover);
}

@media (hover: hover) and (pointer: fine) {
  .footer__links a:hover {
    color: var(--color-text);
  }
}

.footer__links a:focus-visible,
.footer__brand:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
  border-radius: 2px;
}

/* ==========================================================================
   List hover — focus the hovered row by dimming its siblings
   (case studies, services, industries). A moderate ease-out (shared with
   the accordion): it responds at once but spreads the change across the
   whole fade instead of front-loading it, so the dim has weight rather than
   a flick. Under 300ms — it fires tens of times per visit. Only on devices
   that can really hover. Dimming targets each row's contents, so it never fights
   the reveal transition on the row itself.
   ========================================================================== */

.item > *,
.industries__list li,
.industries__label {
  transition: opacity var(--duration-dim) var(--ease-out-moderate);
}

/* Rows show the regular arrow, not the text I-beam. Case studies are the
   only rows that will link out, so they get the hand. */
.item,
.industries__list li {
  cursor: default;
}

.items--linked .item {
  cursor: pointer;
}

@media (hover: hover) and (pointer: fine) {
  /* Fill the gap between rows so moving from one row to the next never
     drops the hover and flashes everything back to full opacity. */
  .item::before {
    content: "";
    position: absolute;
    inset: calc(var(--space-18) / -2) 0;
    z-index: -1; /* sits under the content, so text stays selectable */
  }

  .items:has(.item:hover) .item:not(:hover) > *,
  .industries:has(li:hover) .industries__list li:not(:hover),
  .industries:has(li:hover) .industries__group:not(:has(li:hover)) .industries__label {
    opacity: var(--opacity-dimmed);
  }
}

/* ==========================================================================
   Testimonials
   ========================================================================== */

.quote {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-12);
  padding-block: var(--space-22);
}

.quote:not(:last-child) {
  border-bottom: 1px solid var(--color-border);
}

.quote:last-child {
  padding-bottom: 0;
}

.quote__text {
  color: var(--color-text);
}

.quote__author {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  color: var(--color-text-muted);
}

.avatar {
  position: relative;
  flex: none;
  width: var(--avatar-size);
  height: var(--avatar-size);
  border-radius: var(--radius-full);
  background: var(--color-surface);
  overflow: hidden;
}

.avatar--logo {
  box-shadow: var(--shadow-sm);
}

.avatar--logo img {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 17.168px;
  height: 17.168px;
  transform: translate(-50%, -50%);
  object-fit: cover;
}

.avatar--photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ==========================================================================
   Responsive
   The design is a single 501px column, so the work here is the gutter,
   vertical rhythm, and letting copy wrap once the column narrows.
   ========================================================================== */

@media (max-width: 560px) {
  :root {
    --page-pad-top: var(--space-48);
    --page-pad-bottom: var(--space-72);
  }

  .item__text {
    white-space: normal;
  }

  /* Softer edge fade in the narrower strip */
  .logos {
    -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 12%, #000 88%, transparent 100%);
    mask-image: linear-gradient(90deg, transparent 0%, #000 12%, #000 88%, transparent 100%);
  }

  .industries__list li {
    padding-block: var(--space-12);
  }
}

@media (max-width: 420px) {
  /* Stack the category label above its list */
  .industries__group {
    flex-direction: column;
  }

  .industries__label {
    width: auto;
  }

  .industries__list {
    width: 100%;
  }

  .industries__list li:first-child {
    border-top: 1px solid var(--color-border);
  }

  .faq,
  .footer {
    flex-direction: column;
  }

  .footer__brand {
    margin-bottom: var(--space-22);
  }

  .footer__nav {
    padding-left: 0;
    gap: var(--space-16); /* keep columns wide enough for "Case studies" */
  }

  .faq__title {
    width: auto;
  }

  .faq__list {
    width: 100%;
    border-top: 1px solid var(--color-border);
  }
}

/* ==========================================================================
   Motion — page load and scroll reveal
   One system for the whole page (main.js): once fonts are ready and the first
   frame is on screen, everything in view cascades top to bottom; sections
   further down cascade the same way when scrolled to. Decorative only —
   nothing waits on it. Hidden only once JS is confirmed (.js), with a
   failsafe in <head> that shows everything if main.js never runs.
   ========================================================================== */

.js [data-reveal-item] {
  opacity: 0;
  transform: translateY(var(--enter-distance));
  filter: blur(var(--enter-blur));
  transition:
    opacity var(--duration-enter) var(--ease-enter),
    transform var(--duration-enter) var(--ease-enter),
    filter var(--duration-enter) var(--ease-enter);
}

.js [data-reveal-item].is-visible {
  opacity: 1;
  transform: none;
  filter: none;
}

/* Home's case study links jump to a specific section. Make every item visible
   in the swap frame so the anchor never lands on an empty page. */
.js .reveal-immediate [data-reveal-item] {
  opacity: 1;
  transform: none;
  filter: none;
  transition: none;
}

/* Page-to-page navigation inside the site: the logo is the one element that
   stays put, so it skips its entrance and is simply there. */
.js.nav-internal .hero__brand {
  opacity: 1;
  transform: none;
  filter: none;
  transition: none;
}

/* Reduced motion: fewer and gentler, not zero. Keep the fades, drop movement. */
@media (prefers-reduced-motion: reduce) {
  .js [data-reveal-item] {
    transform: none;
    filter: none;
  }

  /* Ticker: hold still, centred */
  .ticker {
    animation: none;
    width: auto;
    justify-content: center;
  }

  .ticker__set[aria-hidden="true"] {
    display: none;
  }

  /* Accordion: keep the fade, drop the height change and the spin */
  .faq__panel {
    transition-property: opacity;
  }

  .faq__chevron {
    transition: none;
  }

  .button {
    transition: background-color var(--duration-hover) var(--ease-hover);
  }

  .button:active {
    transform: none;
  }
}
