/* ============================================================================
   Askowron — application styles.

   Everything here is authored by us. The design system's own files live in
   ds/ and are byte-identical copies of the handoff; never edit those.

   ADHERENCE CONTRACT (enforced by test/assets/design_system_test.rb):
     - no raw hex colours anywhere -> always var(--…) from ds/tokens/colors.css
     - font-family only via var(--font-display|mono|body)
     - every var(--…) referenced here must actually be defined, either by the
       design system's tokens or by the :root block below

   On raw px: the design system's own oxlint config bans them outright, but its
   component bundle is full of off-grid values with no matching token (11.5px
   NavLink, 9px button padding, 22px eyebrow rule). A literal ban is therefore
   unenforceable against a faithful transliteration, and rounding to the nearest
   token would quietly distort the design. Instead, the recurring ones are
   declared once below as component-scoped properties and referenced by var();
   one-off values stay inline next to the rule they belong to. The colour and
   font rules — the ones that actually protect the brand — are enforced strictly.
   ============================================================================ */

:root {
  /* --- Values transliterated from _ds_bundle.js that have no DS token --- */
  --btn-pad-y-sm: 9px;
  --btn-pad-x-sm: 16px;
  --btn-fs-sm: 11px;
  --btn-icon-sm: 16px;
  --btn-gap-sm: 8px;

  --btn-pad-y-md: 13px;
  --btn-pad-x-md: 24px;
  --btn-fs-md: 12px;
  --btn-icon-md: 18px;
  --btn-gap-md: 10px;

  --btn-pad-y-lg: 17px;
  --btn-pad-x-lg: 32px;
  --btn-fs-lg: 13px;
  --btn-icon-lg: 20px;
  --btn-gap-lg: 12px;

  --tracking-btn: 0.14em;
  --navlink-fs: 11.5px;
  --eyebrow-rule-w: 22px;
  --wordmark-fs: 18px;
  --wordmark-dot: 8px;

  --stat-fs-sm: 26px;
  --stat-fs-md: 38px;
  --stat-fs-lg: 52px;

  --iconbtn-size: 40px;
  --iconbtn-size-sm: 32px;

  --service-icon: 26px;
  --service-numeral: 38px;
  --service-title-fs: 22px;

  --card-pad: var(--space-6);
  --card-pad-lg: 28px;

  /* --- Fluid display sizes (replace the prototype's fixed desktop values) --- */
  --fs-hero: clamp(38px, 8.4vw, 84px);
  --fs-contact: clamp(30px, 5.6vw, 60px);
  --fs-h2: clamp(26px, 4vw, 44px);
  --fs-h3: clamp(20px, 2.4vw, 24px);
  --pad-x: clamp(20px, 4vw, 40px);
  --section-pad-y: clamp(64px, 9vw, 112px);
}

/* ---------------------------------------------------------------- document */

html {
  /* Native smooth anchor scrolling with the sticky nav accounted for. This is
     why the nav and rail can be plain crawlable <a href="#…"> elements instead
     of the prototype's onClick buttons. */
  scroll-behavior: smooth;
  scroll-padding-top: var(--nav-h);
  /* `clip`, not `hidden`: `hidden` breaks position:sticky on the header. */
  overflow-x: clip;
}

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

body { min-height: 100vh }

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

/* The design system's base.css resets `p` but not these, and the browser
   defaults are substantial: `figure` and `blockquote` both carry a 40px
   horizontal margin that visibly insets any card built on them. */
figure, blockquote, ol, ul { margin: 0 }
ol, ul { padding: 0; list-style: none }

/* Visible only to screen readers. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Skip link — first focusable element on the page. */
.skip-link {
  position: absolute;
  left: var(--space-4);
  top: calc(-1 * var(--space-20));
  z-index: 100;
  padding: var(--space-3) var(--space-5);
  background: var(--action-accent);
  color: var(--text-on-accent);
  font-family: var(--font-mono);
  font-size: var(--text-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  transition: top var(--dur-base) var(--ease-out);
}
.skip-link:focus {
  top: var(--space-4);
  color: var(--text-on-accent);
}

/* ------------------------------------------------------------------ layout */

/* The page is inset by the fixed rail on wide viewports. */
.page {
  position: relative;
  padding-left: var(--rail-w);
}

.shell {
  max-width: var(--page-max);
  margin: 0 auto;
  padding-inline: var(--pad-x);
}

.section { border-bottom: var(--border-hair) solid var(--border-subtle) }
.section--alt { background: var(--bg-section) }
.section__inner { padding-block: var(--section-pad-y) }

/* Long text in a grid cell otherwise refuses to shrink below its content. */
.section__inner > *,
[class*="__grid"] > * { min-width: 0 }

/* ============================================================================
   DESIGN SYSTEM COMPONENTS

   Each rule below is a 1:1 transliteration of the corresponding inline style
   object in _ds_bundle.js. That bundle is a compiled React build requiring
   window.React, so it is not shipped — but because every one of its style
   objects is written in terms of var(--token), transliterating them into
   classes is mechanical and lossless.

   React `hover`/`press` state becomes :hover/:active. No JavaScript is
   involved in any component's appearance.
   ============================================================================ */

.ds-icon { display: block; flex: 0 0 auto }

/* ------------------------------------------------------------------- Badge */

.ds-badge {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  gap: 7px;
  padding: 6px 12px;
  border: var(--border-hair) solid var(--oxide-tint-24);
  border-radius: var(--radius-pill);
  background: var(--oxide-tint-12);
  color: var(--oxide-400);
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}
.ds-badge--neutral {
  background: transparent;
  color: var(--text-muted);
  border-color: var(--border-subtle);
}
.ds-badge--square {
  padding: 5px 9px;
  border-radius: var(--radius-hair);
}
.ds-badge__dot {
  width: 5px; height: 5px;
  border-radius: var(--radius-pill);
  background: currentColor;
}

/* -------------------------------------------------------------------- Card */

.ds-card {
  position: relative;
  background: var(--surface-card);
  border: var(--border-hair) solid var(--border-subtle);
  border-radius: var(--radius-none);
  padding: var(--card-pad);
  box-shadow: var(--shadow-none);
  color: inherit;
  text-decoration: none;
  transition: background var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out);
}
.ds-card--pad-lg { padding: var(--card-pad-lg) }
.ds-card--accent { border-left: var(--rule-accent) solid var(--oxide-500) }
.ds-card--interactive { cursor: pointer }
.ds-card--interactive:hover {
  background: var(--surface-raised);
  border-color: var(--border-default);
}

/* ----------------------------------------------------------------- Eyebrow */

.ds-eyebrow { display: flex; align-items: center; gap: var(--space-3) }
.ds-eyebrow__rule {
  width: var(--eyebrow-rule-w);
  height: 1px;
  background: var(--oxide-500);
  flex: 0 0 auto;
}
.ds-eyebrow__num {
  font-family: var(--font-mono);
  font-size: var(--text-label);
  letter-spacing: var(--tracking-label);
  color: var(--text-faint);
}
.ds-eyebrow__text {
  font-family: var(--font-mono);
  font-size: var(--text-label);
  line-height: var(--text-label-lh);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-accent);
}
.ds-eyebrow--muted .ds-eyebrow__text { color: var(--text-muted) }

/* ------------------------------------------------------------------ Button */

.ds-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--btn-gap-md);
  padding: var(--btn-pad-y-md) var(--btn-pad-x-md);
  font-family: var(--font-mono);
  font-size: var(--btn-fs-md);
  font-weight: var(--weight-body-medium);
  letter-spacing: var(--tracking-btn);
  text-transform: uppercase;
  text-decoration: none;
  border-radius: var(--radius-none);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.ds-btn--sm {
  gap: var(--btn-gap-sm);
  padding: var(--btn-pad-y-sm) var(--btn-pad-x-sm);
  font-size: var(--btn-fs-sm);
}
.ds-btn--lg {
  gap: var(--btn-gap-lg);
  padding: var(--btn-pad-y-lg) var(--btn-pad-x-lg);
  font-size: var(--btn-fs-lg);
}
.ds-btn--block { display: flex; width: 100% }

.ds-btn--primary {
  background: var(--action-accent);
  color: var(--text-on-accent);
  border: var(--border-hair) solid var(--action-accent);
}
.ds-btn--primary:hover {
  background: var(--action-accent-hover);
  border-color: var(--action-accent-hover);
  color: var(--text-on-accent);
}
.ds-btn--primary:active {
  background: var(--action-accent-press);
  border-color: var(--action-accent-press);
}

.ds-btn--secondary {
  background: transparent;
  color: var(--text-display);
  border: var(--border-hair) solid var(--border-default);
}
.ds-btn--secondary:hover {
  background: var(--surface-hover);
  border-color: var(--border-strong);
  color: var(--text-display);
}
.ds-btn--secondary:active {
  background: var(--ink-900);
  border-color: var(--border-strong);
}

.ds-btn--ghost {
  background: transparent;
  color: var(--text-body);
  border: var(--border-hair) solid transparent;
}
.ds-btn--ghost:hover { background: var(--surface-hover); color: var(--text-display) }
.ds-btn--ghost:active { background: var(--ink-900) }

.ds-btn:disabled, .ds-btn[aria-disabled="true"] {
  background: var(--surface-raised);
  color: var(--text-faint);
  border-color: var(--border-subtle);
  cursor: not-allowed;
}

/* -------------------------------------------------------------- IconButton */

.ds-iconbtn {
  width: var(--iconbtn-size);
  height: var(--iconbtn-size);
  display: grid;
  place-items: center;
  padding: 0;
  background: transparent;
  border: var(--border-hair) solid var(--border-subtle);
  border-radius: var(--radius-none);
  color: var(--text-muted);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.ds-iconbtn:hover { background: var(--surface-hover); border-color: var(--border-strong); color: var(--text-accent) }
.ds-iconbtn.is-active { border-color: var(--border-strong); color: var(--text-accent) }
.ds-iconbtn--bare { border-color: transparent }
.ds-iconbtn--bare:hover { background: transparent; border-color: transparent; color: var(--text-accent) }
.ds-iconbtn--sm { width: var(--iconbtn-size-sm); height: var(--iconbtn-size-sm) }

/* ----------------------------------------------------------------- NavLink */

.ds-navlink {
  position: relative;
  display: inline-block;
  padding: 6px 0;
  font-family: var(--font-mono);
  font-size: var(--navlink-fs);
  letter-spacing: var(--tracking-btn);
  text-transform: uppercase;
  text-decoration: none;
  color: var(--text-muted);
  transition: color var(--dur-fast) var(--ease-out);
}
.ds-navlink::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  height: 1px; width: 0;
  background: var(--oxide-500);
  transition: width var(--dur-base) var(--ease-out);
}
.ds-navlink:hover { color: var(--text-display) }
.ds-navlink:hover::after { width: 100% }
.ds-navlink.is-active { color: var(--text-accent) }
.ds-navlink.is-active::after { width: 100% }

/* ---------------------------------------------------------- SectionHeading */

.ds-heading {
  display: flex;
  flex-direction: column;
  gap: 18px;
  align-items: flex-start;
  text-align: left;
}
.ds-heading--center { align-items: center; text-align: center }
.ds-heading__title {
  font-size: var(--fs-h2);
  line-height: var(--text-h2-lh);
  margin: 0;
  max-width: 18ch;
}
.ds-heading--h1 .ds-heading__title { font-size: var(--fs-hero); line-height: var(--text-h1-lh) }
.ds-heading--h3 .ds-heading__title { font-size: var(--fs-h3); line-height: var(--text-h3-lh) }
.ds-heading__accent { color: var(--text-accent) }
.ds-heading__lede {
  font-size: var(--text-lg);
  line-height: var(--text-lg-lh);
  color: var(--text-body);
  max-width: 58ch;
}

/* -------------------------------------------------------------------- Stat */

.ds-stat { display: flex; flex-direction: column; gap: 6px }
.ds-stat__value {
  font-family: var(--font-mono);
  font-weight: var(--weight-body-medium);
  font-size: var(--stat-fs-md);
  line-height: 1;
  color: var(--text-display);
  letter-spacing: var(--tracking-display);
}
.ds-stat--sm .ds-stat__value { font-size: var(--stat-fs-sm) }
.ds-stat--lg .ds-stat__value { font-size: var(--stat-fs-lg) }
.ds-stat__suffix { color: var(--text-accent) }
.ds-stat__caption {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-muted);
  max-width: 22ch;
}

/* ------------------------------------------------- Figure (was Placeholder)

   The design system's Placeholder draws a captioned empty box because no
   photography shipped with the brief. We have real assets (a portrait and
   three headshots), so the same box carries an <img>; the caption is the
   fallback when it does not. */

.ds-figure {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 3;
  background: var(--surface-raised);
  border: var(--border-hair) solid var(--border-subtle);
  border-radius: var(--radius-media);
  display: grid;
  place-items: center;
  overflow: hidden;
}
.ds-figure--pill { border-radius: var(--radius-pill) }
.ds-figure__img {
  width: 100%; height: 100%;
  object-fit: cover;
  /* Brand book: photography is near-monochrome, never full colour. */
  filter: grayscale(1) contrast(1.08);
}
.ds-figure__caption {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-micro);
  text-transform: uppercase;
  color: var(--text-faint);
  text-align: center;
  padding: 0 var(--space-4);
}

/* ------------------------------------------------------------- ServiceCard */

.ds-service { height: 100%; overflow: hidden }
.ds-service__body { display: flex; flex-direction: column; gap: var(--space-4) }
.ds-service__icon { color: var(--text-muted); transition: color var(--dur-base) var(--ease-out) }
.ds-service:hover .ds-service__icon { color: var(--text-accent) }
.ds-service__title { font-size: var(--service-title-fs); line-height: 1.05 }
.ds-service__text {
  font-size: var(--text-sm);
  line-height: var(--text-sm-lh);
  color: var(--text-muted);
}
.ds-service__numeral {
  position: absolute;
  right: 18px; bottom: 10px;
  font-family: var(--font-mono);
  font-weight: var(--weight-body-medium);
  font-size: var(--service-numeral);
  color: var(--line-1);
  transition: color var(--dur-base) var(--ease-out);
  pointer-events: none;
}
.ds-service:hover .ds-service__numeral { color: var(--oxide-tint-24) }

/* ---------------------------------------------------------- TestimonialCard */

.ds-testimonial {
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 22px;
}
.ds-testimonial__mark {
  font-family: var(--font-display);
  font-size: var(--space-10);
  line-height: 0.6;
  color: var(--oxide-500);
  margin-bottom: 14px;
}
.ds-testimonial__quote {
  font-size: var(--text-base);
  line-height: 1.6;
  color: var(--text-body);
}
.ds-testimonial__footer {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  border-top: var(--border-hair) solid var(--border-subtle);
  padding-top: var(--space-4);
}
.ds-testimonial__avatar { width: 36px; height: 36px; flex: 0 0 36px; aspect-ratio: 1 }
.ds-testimonial__name {
  font-family: var(--font-mono);
  font-size: var(--text-label);
  letter-spacing: 0.08em;
  color: var(--text-display);
}
.ds-testimonial__role {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-faint);
  margin-top: 3px;
}

/* -------------------------------------------------------------------- Rail

   The prototype positions this `absolute` inside a full-document-height
   container, which parks the social icons ~15,000px down the page. The brand
   book says "a fixed 64px left rail persists on desktop" — that is what this
   is, and it is also what scroll-spy needs. */

.ds-rail {
  position: fixed;
  left: 0; top: 0; bottom: 0;
  width: var(--rail-w);
  border-right: var(--border-hair) solid var(--border-subtle);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  padding: 96px 0 28px;
  z-index: 40;
}
.ds-rail__list { display: flex; flex-direction: column; align-items: center; gap: 10px }
.ds-rail__item {
  padding: 2px 0;
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: 0.1em;
  color: var(--text-faint);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-out);
}
.ds-rail__item:hover { color: var(--text-muted) }
.ds-rail__item.is-active { color: var(--text-accent) }
.ds-rail__socials { display: flex; flex-direction: column; align-items: center; gap: 6px }
.ds-rail__rule {
  width: 1px; height: 56px;
  background: var(--border-subtle);
  margin-bottom: 10px;
}

/* ============================================================================
   PAGE SECTIONS

   Desktop layout, transliterated from the prototype. Breakpoints live in one
   block at the very bottom of this file.

   The prototype hardcodes raw hex colours and pixel padding inline; those are
   substituted back to tokens here. The adherence contract is the design
   system's own, and the prototype violates it for expedience.
   ============================================================================ */

/* ------------------------------------------------------------------ header */

.nav {
  position: sticky;
  top: 0;
  z-index: 60;
  height: var(--nav-h);
  border-bottom: var(--border-hair) solid var(--border-subtle);
}
/* The blurred veil lives on a pseudo-element, not on .nav itself. A
   backdrop-filter (like filter, transform and perspective) makes its element
   the containing block for position:fixed descendants — with it on .nav, the
   mobile menu panel resolved `inset: var(--nav-h) 0 0 0` against the 72px bar
   instead of the viewport and collapsed to nothing. */
.nav::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--veil-page);
  backdrop-filter: var(--blur-veil);
  -webkit-backdrop-filter: var(--blur-veil);
}
.nav__inner {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-8);
}
.nav__wordmark {
  display: flex;
  align-items: center;
  gap: 9px;
  font-family: var(--font-display);
  font-size: var(--wordmark-fs);
  letter-spacing: var(--tracking-display);
  text-transform: uppercase;
  color: var(--text-display);
  flex: 0 0 auto;
}
.nav__wordmark:hover { color: var(--text-display) }
/* The brand book is explicit that no logo exists; the mark is a solid oxide
   square drawn in CSS. Do not invent one. */
.nav__mark { width: var(--wordmark-dot); height: var(--wordmark-dot); background: var(--oxide-500) }

.nav__links { display: flex; gap: var(--space-6); align-items: center }
.nav__locale {
  font-family: var(--font-mono);
  font-size: var(--btn-fs-sm);
  letter-spacing: var(--tracking-label);
  color: var(--text-faint);
  transition: color var(--dur-fast) var(--ease-out);
}
.nav__locale:hover { color: var(--text-display) }

.nav__actions { display: flex; align-items: center; gap: var(--space-3); flex: 0 0 auto }
.nav__toggle { display: none }
.nav__icon-close { display: none }
.nav__panel-cta { display: none }

/* --- the services dropdown ------------------------------------------------
   A disclosure, not a hover menu. Hover-only submenus have no keyboard
   equivalent and are a coin toss on touch, and these two links are the site's
   only paths to a page that is not the homepage. `data-open` is written by
   nav_controller; aria-expanded on the button is the same state for anyone
   not looking at the screen. */
.nav__services { position: relative }
.nav__services-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  background: none;
  border: 0;
  cursor: pointer;
}
.nav__chevron { transition: transform var(--dur-fast) var(--ease-out) }
.nav__services[data-open] .nav__chevron { transform: rotate(180deg) }
.nav__services[data-open] .nav__services-toggle { color: var(--text-display) }
.nav__services[data-open] .nav__services-toggle::after { width: 100% }

.nav__dropdown {
  position: absolute;
  top: calc(100% + var(--space-4));
  left: calc(-1 * var(--space-3));
  z-index: 70;
  min-width: 296px;
  margin: 0;
  padding: var(--space-2);
  list-style: none;
  background: var(--surface-card);
  border: var(--border-hair) solid var(--border-subtle);
  box-shadow: var(--shadow-panel);
  /* Hidden from pointer *and* keyboard until opened — a closed menu that still
     takes focus is worse than no menu. */
  visibility: hidden;
  opacity: 0;
  transform: translateY(calc(-1 * var(--space-2)));
  transition: opacity var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out),
              visibility var(--dur-base) var(--ease-out);
}
.nav__services[data-open] .nav__dropdown { visibility: visible; opacity: 1; transform: none }

/* No-JavaScript fallback. These are the only links to a page that is not the
   homepage, so a menu that needs a script to open is a menu that hides half
   the site. nav_controller stamps data-nav-js on connect, which switches this
   off — otherwise hover would open a menu whose aria-expanded said false.
   :focus-within, not :hover alone: the keyboard has to get there too. */
.nav:not([data-nav-js]) .nav__services:hover .nav__dropdown,
.nav:not([data-nav-js]) .nav__services:focus-within .nav__dropdown {
  visibility: visible;
  opacity: 1;
  transform: none;
}

.nav__dropdown-link {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-3) var(--space-4);
  color: var(--text-body);
  border-left: var(--rule-accent) solid transparent;
  transition: background var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.nav__dropdown-link:hover { background: var(--surface-hover); border-left-color: var(--border-accent) }
.nav__dropdown-link.is-active { background: var(--surface-raised); border-left-color: var(--border-accent) }
.nav__dropdown-title {
  font-family: var(--font-mono);
  font-size: var(--navlink-fs);
  letter-spacing: var(--tracking-btn);
  text-transform: uppercase;
  color: var(--text-display);
}
.nav__dropdown-link.is-active .nav__dropdown-title { color: var(--text-accent) }
.nav__dropdown-note {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  line-height: var(--text-sm-lh);
  color: var(--text-muted);
}

/* -------------------------------------------------------------------- hero */

.hero__grid {
  padding: 104px 0 88px;
  display: grid;
  grid-template-columns: 1.2fr 0.8fr;
  gap: var(--space-16);
  align-items: end;
}
.hero__lead { display: flex; flex-direction: column; gap: 30px }
.hero__title {
  font-size: var(--fs-hero);
  line-height: var(--text-hero-lh);
  max-width: 14ch;
}
.hero__lede {
  font-size: var(--text-lg);
  line-height: var(--text-lg-lh);
  color: var(--text-body);
  max-width: 52ch;
}
.hero__actions { display: flex; gap: var(--space-3); align-items: center; flex-wrap: wrap }
.hero__aside { display: flex; flex-direction: column; padding-bottom: 6px }

/* ---------------------------------------------------------------- hero art */

/* The decorative SVG that fills the hero's right-hand column — the cell arrow
   on the homepage, the climbed steps on a service page. Capped and pushed
   right: at the full 0.8fr the drawing outweighs the headline it sits beside. */
.hero-art {
  display: block;
  width: 100%;
  max-width: 400px;
  height: auto;
  margin-left: auto;
}
.hero-art__cell { fill: none; stroke: var(--border-subtle); stroke-width: 1 }
.hero-art__cell--lit { fill: var(--action-accent); stroke: none }
.hero-art__step { fill: var(--action-accent) }
.hero-art__step--muted { fill: var(--surface-raised) }
.hero-art__figure {
  fill: none;
  stroke: var(--text-display);
  stroke-width: 5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.hero-art__head { fill: var(--text-display) }

/* ----------------------------------------------------------------- clients */

.clients {
  padding-block: 36px;
  display: flex;
  /* baseline, not center: with a two-row list, centering would float the
     label between the rows instead of aligning it to the first one. */
  align-items: baseline;
  gap: var(--space-5) var(--space-10);
  flex-wrap: wrap;
}
.clients__label {
  font-family: var(--font-mono);
  font-size: var(--btn-fs-sm);
  letter-spacing: var(--tracking-micro);
  text-transform: uppercase;
  color: var(--text-faint);
  white-space: nowrap;
}
/* `flex: 1 1 0` with `min-width: 0` is what keeps the label company. Left at
   its default `auto` basis the list is as wide as all the names laid end to
   end, so adding one more name pushed the whole block onto its own row and
   orphaned the label. Now the list takes whatever width is left and wraps
   inside itself instead.

   Centring means a part-full final row sits under the middle of the list
   rather than hanging off the left edge — with ten names and counting, that
   last row is usually one or two items. */
.clients__list {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 14px 34px;
}
.clients__item {
  font-family: var(--font-mono);
  font-size: var(--btn-fs-lg);
  letter-spacing: var(--tracking-btn);
  text-transform: uppercase;
  color: var(--text-muted);
}

/* ---------------------------------------------------------------- services */

/* `.stack` is the same heading-then-content rhythm with no section of its own:
   the service pages' sections use it so their headings sit off their content
   the way the homepage's do. */
.services, .platform, .testimonials, .comparison, .results, .stack {
  display: flex;
  flex-direction: column;
  gap: 44px;
}
.services__grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-3) }
.services__tags {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-3);
  border-top: var(--border-hair) solid var(--border-subtle);
  padding-top: 14px;
}
.services__tag {
  font-family: var(--font-mono);
  font-size: var(--btn-fs-sm);
  letter-spacing: var(--tracking-micro);
  text-transform: uppercase;
  color: var(--text-faint);
}

/* ----------------------------------------------------------------- process */

.process__grid {
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;
  gap: 72px;
  align-items: start;
}
.process__steps { display: flex; flex-direction: column }
.process__step {
  display: grid;
  grid-template-columns: var(--rail-w) 1fr;
  gap: var(--space-6);
  padding-block: 26px;
  border-top: var(--border-hair) solid var(--border-subtle);
}
.process__step:last-child { border-bottom: var(--border-hair) solid var(--border-subtle) }
.process__number {
  font-family: var(--font-mono);
  font-size: var(--btn-fs-lg);
  letter-spacing: var(--tracking-label);
  color: var(--text-accent);
}
.process__body { display: flex; flex-direction: column; gap: 10px }
.process__title { font-size: var(--space-6); line-height: 1.02 }
.process__text {
  font-size: 15px;
  line-height: var(--text-base-lh);
  color: var(--text-muted);
  max-width: 62ch;
}

/* ---------------------------------------------------------------- platform */

.platform__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-3) }

/* -------------------------------------------------------------- comparison */

.comparison__table {
  width: 100%;
  border-collapse: collapse;
  border: var(--border-hair) solid var(--border-subtle);
  table-layout: fixed;
}
.comparison__table thead tr { background: var(--surface-card) }
.comparison__col {
  padding: var(--space-4) var(--space-5);
  font-family: var(--font-mono);
  font-size: var(--btn-fs-sm);
  font-weight: var(--weight-body);
  letter-spacing: var(--tracking-micro);
  text-transform: uppercase;
  color: var(--text-faint);
  text-align: center;
  border-left: var(--border-hair) solid var(--border-subtle);
  border-bottom: var(--border-hair) solid var(--border-subtle);
  width: 16%;
}
.comparison__col--mine { color: var(--text-accent) }
.comparison__label {
  padding: 18px var(--space-5);
  font-size: 15px;
  font-weight: var(--weight-body);
  color: var(--text-body);
  text-align: left;
  border-top: var(--border-hair) solid var(--border-subtle);
}
.comparison__cell {
  padding: 18px var(--space-5);
  text-align: center;
  font-family: var(--font-mono);
  font-size: 15px;
  color: var(--text-faint);
  border-left: var(--border-hair) solid var(--border-subtle);
  border-top: var(--border-hair) solid var(--border-subtle);
}
.comparison__cell--mine { background: var(--oxide-tint-12); color: var(--text-accent) }

/* The service pages reuse the table with prose in the cells rather than a
   verdict glyph. Wider columns, body font, ranged left — a centred sentence in
   mono is unreadable at this width. Everything else, including the collapse to
   cards at 560, is inherited. */
.comparison__table--text .comparison__col { width: 27%; text-align: left }
.comparison__table--text .comparison__cell {
  font-family: var(--font-body);
  font-size: 15px;
  line-height: var(--text-base-lh);
  color: var(--text-muted);
  text-align: left;
  vertical-align: top;
}
.comparison__table--text .comparison__cell--mine { color: var(--text-body) }
.comparison__link { color: inherit; border-bottom: var(--border-hair) solid currentColor }
.comparison__link:hover { color: var(--text-accent) }

/* ------------------------------------------------------------ testimonials */

.testimonials__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-3);
  align-items: stretch;
}
/* ----------------------------------------------------------------- results */

.results__panel { border: var(--border-hair) solid var(--border-subtle); background: var(--surface-card) }
.results__tabs {
  display: flex;
  border-bottom: var(--border-hair) solid var(--border-subtle);
  overflow-x: auto;
  scrollbar-width: none;
}
.results__tabs::-webkit-scrollbar { display: none }
.results__tab {
  padding: 18px 26px;
  background: transparent;
  border: none;
  border-right: var(--border-hair) solid var(--border-subtle);
  border-bottom: var(--border-thick) solid transparent;
  margin-bottom: -1px;
  font-family: var(--font-mono);
  font-size: var(--btn-fs-md);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-faint);
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease-out);
}
.results__tab:hover { color: var(--text-muted) }
.results__tab[aria-selected="true"] { color: var(--text-display); border-bottom-color: var(--oxide-500) }

.results__case { padding: var(--space-8) }
.results__peak { display: flex; align-items: baseline; gap: 28px; margin-bottom: 26px; flex-wrap: wrap }
.results__peak-value {
  font-family: var(--font-mono);
  font-size: var(--space-10);
  line-height: 1;
  color: var(--text-display);
  letter-spacing: var(--tracking-display);
}
.results__peak-caption {
  font-family: var(--font-mono);
  font-size: var(--btn-fs-sm);
  letter-spacing: var(--tracking-micro);
  text-transform: uppercase;
  color: var(--text-muted);
}
.results__chart { position: relative }
.results__svg { width: 100%; height: 280px; display: block; overflow: visible }
.results__grid { stroke: var(--border-subtle); stroke-width: 1 }
.results__area { fill: var(--oxide-tint-12) }
.results__line { fill: none; stroke: var(--oxide-500); stroke-width: var(--border-thick) }
.results__axis {
  position: relative;
  height: var(--space-5);
  margin-top: 14px;
  font-family: var(--font-mono);
  font-size: var(--btn-fs-sm);
  letter-spacing: var(--tracking-label);
  color: var(--text-faint);
}
/* Ticks are positioned from the data, not spaced evenly — the three series
   start in different months and run different lengths. */
.results__tick { position: absolute; top: 0; transform: translateX(-50%) }
.results__tick:first-child { transform: none }
.results__tick:last-child { transform: translateX(-100%) }
.results__body {
  margin-top: 26px;
  font-size: 15px;
  line-height: var(--text-base-lh);
  color: var(--text-muted);
  max-width: 88ch;
}

/* ------------------------------------------------------------------- about */

/* Two rows: the heading sits alone above, then the portrait and the copy
   start together on the second row. The left column is sized to the portrait
   so the gutter stays the gutter. */
.about__grid {
  display: grid;
  grid-template-columns: minmax(0, 360px) minmax(0, 1fr);
  grid-template-areas:
    "heading ."
    "portrait body";
  column-gap: 72px;
  row-gap: 28px;
  align-items: start;
}
.about__heading { grid-area: heading }
.about__portrait { grid-area: portrait; max-width: 100% }
.about__body { grid-area: body; display: flex; flex-direction: column; gap: var(--space-5) }
.about__paragraph {
  font-size: 17px;
  line-height: var(--text-base-lh);
  color: var(--text-body);
  max-width: 66ch;
}
.about__paragraph strong { color: var(--text-display); font-weight: var(--weight-body-bold) }

/* ============================================================================
   SERVICE PAGE SECTIONS

   Only the service pages use these. The sections that could be built out of
   what the homepage already has — the numbered process list, the comparison
   table, the portrait grid — reuse those classes instead of appearing here.
   ============================================================================ */

/* --------------------------------------------------------------- checklist */

/* One list, three uses: the two audience columns and the preparation grid.
   The icon carries the polarity, so the copy does not have to. */
.checklist { display: flex; flex-direction: column; gap: 14px }
.checklist__item {
  display: grid;
  grid-template-columns: 18px 1fr;
  gap: var(--space-3);
  align-items: start;
  font-size: 15px;
  line-height: var(--text-base-lh);
  color: var(--text-muted);
}
/* Optical: the glyph's bar sits above the first line's x-height otherwise. */
.checklist__icon { color: var(--text-accent); margin-top: 4px }
.checklist--against .checklist__icon { color: var(--text-faint) }
.checklist--split {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 14px var(--space-16);
}

/* ---------------------------------------------------------------- audience */

.audience__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-3);
  align-items: start;
}
.audience__col { display: flex; flex-direction: column; gap: var(--space-6) }
.audience__title { font-size: var(--fs-h3); line-height: var(--text-h3-lh) }

/* ----------------------------------------------------------------- pricing */

/* Heading left, the priced panel right — the same split as the process grid,
   so the two sections read as one page rather than two templates. */
.pricing__grid {
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;
  gap: 72px;
  align-items: start;
}
.pricing__panel { display: flex; flex-direction: column; gap: var(--space-6); align-items: flex-start }
/* The hero's stat captions are two or three words and are capped at 22ch. This
   one is a sentence, and at that cap it breaks across three lines. */
.pricing__panel .ds-stat__caption { max-width: 46ch }
.pricing__note {
  font-size: 15px;
  line-height: var(--text-base-lh);
  color: var(--text-muted);
  max-width: 56ch;
}
.pricing__actions { display: flex; gap: var(--space-3); align-items: center; flex-wrap: wrap }

/* --------------------------------------------------------------------- faq */

/* Native <details>: the answers are in the DOM, they expand with JavaScript
   off, and find-in-page reaches them. No JS involved anywhere here. */
.faq__list { display: flex; flex-direction: column; border-top: var(--border-hair) solid var(--border-subtle) }
.faq__item { border-bottom: var(--border-hair) solid var(--border-subtle) }
.faq__question {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  padding-block: var(--space-5);
  cursor: pointer;
  /* Both are needed: the standard property, and the WebKit pseudo-element that
     predates it and still wins in Safari. */
  list-style: none;
}
.faq__question::-webkit-details-marker { display: none }
/* <summary> is not in the base stylesheet's focus-visible list — it is neither
   a link, a button, nor tabindex'd — so it needs the ring spelled out. */
.faq__question:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px }
.faq__question-text {
  /* An h3 for the outline and for parity with the FAQPage JSON-LD, but not in
     the display face: a question set in uppercase Anton is unreadable. */
  font-family: var(--font-body);
  font-size: 17px;
  font-weight: var(--weight-body);
  line-height: var(--text-base-lh);
  letter-spacing: normal;
  text-transform: none;
  color: var(--text-display);
  transition: color var(--dur-fast) var(--ease-out);
}
.faq__question:hover .faq__question-text { color: var(--text-accent) }
.faq__icon { color: var(--text-faint); transition: transform var(--dur-base) var(--ease-out) }
.faq__item[open] .faq__icon { transform: rotate(180deg) }
.faq__answer {
  padding-bottom: var(--space-5);
  font-size: 15px;
  line-height: var(--text-base-lh);
  color: var(--text-muted);
  max-width: 76ch;
}

/* -------------------------------------------------------------- newsletter */

.newsletter__grid {
  padding-block: 88px;
  display: grid;
  grid-template-columns: 1.3fr 0.7fr;
  gap: 56px;
  align-items: center;
}
.newsletter__lead { display: flex; flex-direction: column; gap: var(--space-5) }
.newsletter__title { font-size: var(--fs-h2); line-height: var(--text-h2-lh); max-width: 24ch }
.newsletter__text {
  font-size: var(--text-base);
  line-height: var(--text-base-lh);
  color: var(--text-muted);
  max-width: 56ch;
}
.newsletter__action { display: flex; justify-content: flex-end }

/* ----------------------------------------------------------------- contact */

.contact__panel {
  padding: 72px var(--gutter);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 26px;
  text-align: center;
}
.contact__title { font-size: var(--fs-contact); line-height: var(--text-h1-lh); max-width: 20ch }
.contact__text {
  font-size: 17px;
  line-height: var(--text-base-lh);
  color: var(--text-muted);
  max-width: 52ch;
}
.contact__actions { display: flex; gap: var(--space-3); align-items: center; margin-top: 6px; flex-wrap: wrap }

/* The form is the primary path now; the booking link and the phone reveal sit
   under it as the two ways of skipping it. Left-aligned inside a panel that is
   otherwise centred — a centred label above a full-width input reads as
   decoration, and the eye loses the column it is filling in. */
.contact__form { width: 100%; max-width: 560px; text-align: left; margin-top: var(--space-2) }
.contact__alt {
  display: flex;
  gap: var(--space-3);
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  margin-top: var(--space-2);
}
.contact__alt-note {
  width: 100%;
  text-align: center;
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  line-height: var(--text-micro-lh);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: var(--space-1);
}

.contact-form { width: 100% }

/* The 422 and 429 states. Accent border rather than a red one: the system has
   exactly one saturated colour, and inventing a second for form errors would
   be the first crack in that. */
.contact-form__notice {
  border: var(--border-hair) solid var(--border-accent);
  padding: var(--space-4);
  margin-bottom: var(--space-5);
  font-size: var(--text-sm);
  line-height: var(--text-sm-lh);
  color: var(--text-body);
}

/* Compact variant, on the offer pages: says whose name and address are about
   to be sent, because they are filled in from a record rather than by hand. */
.contact-form__as {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  line-height: var(--text-micro-lh);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: var(--space-5);
}

.contact-form__submit { margin-top: var(--space-6) }

/* Both halves occupy the same slot: the served state is the tel: link, and the
   controller swaps the button in front of it once JavaScript is available. */
.phone-reveal { display: inline-flex }
.phone-reveal [hidden] { display: none }

/* -------------------------------------------------------------- ds: fields */

.ds-field { margin-bottom: var(--space-5) }
.ds-field:last-of-type { margin-bottom: 0 }

.ds-field__label {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  line-height: var(--text-micro-lh);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: var(--space-2);
}
.ds-field__req { color: var(--text-accent); margin-left: var(--space-1) }

.ds-field__control {
  width: 100%;
  background: var(--surface-input);
  border: var(--border-hair) solid var(--border-subtle);
  border-radius: 0;
  color: var(--text-display);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--text-base-lh);
  padding: var(--space-3);
  /* 120ms on colour, per the system's animation scale. Nothing moves. */
  transition: border-color 120ms var(--ease-out, ease);
}
.ds-field__control::placeholder { color: var(--text-muted); opacity: 1 }
.ds-field__control:hover { border-color: var(--border-default) }

/* Never removed, always visible — the system's focus rule. */
.ds-field__control:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
  border-color: var(--border-accent);
}

textarea.ds-field__control { resize: vertical; min-height: 132px }

/* The native arrow is drawn by the platform in the platform's blue-grey, which
   is the one colour in the system nobody chose. Suppressed, and the system's own
   stroked chevron laid over the space it leaves. */
.ds-field__select { position: relative; display: block }
select.ds-field__control { appearance: none; padding-right: var(--space-10) }

.ds-field__chevron {
  position: absolute;
  right: var(--space-3);
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-muted);
  pointer-events: none;
  transition: color 120ms var(--ease-out);
}
select.ds-field__control:focus-visible + .ds-field__chevron { color: var(--text-accent) }

.ds-field__control--invalid { border-color: var(--border-accent) }

.ds-field__hint,
.ds-field__error {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  line-height: var(--text-micro-lh);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  margin-top: var(--space-2);
}
.ds-field__hint { color: var(--text-muted) }
.ds-field__error { color: var(--text-accent) }

/* The honeypot. Not display:none and not type=hidden — bots skip both and fill
   what looks like a real input. Taken out of the layout, out of the tab order
   and out of the accessibility tree, so no person ever meets it. */
.ds-field--trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* The submitted-form summary at the top of a failed post. */
.contact__errors {
  width: 100%;
  max-width: 560px;
  text-align: left;
  border: var(--border-hair) solid var(--border-accent);
  padding: var(--space-4);
  font-size: var(--text-sm);
  line-height: var(--text-sm-lh);
  color: var(--text-body);
}

/* ------------------------------------------------------------------ footer */

.footer { border-top: var(--border-hair) solid var(--border-subtle) }
.footer__inner {
  padding-block: var(--space-8);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  flex-wrap: wrap;
}
.footer__copy {
  font-family: var(--font-mono);
  font-size: var(--text-label);
  letter-spacing: var(--tracking-btn);
  color: var(--text-faint);
}
.footer__socials { display: flex; gap: var(--space-2); align-items: center }

/* ============================================================================
   BREAKPOINTS

   The prototype ships exactly one media query — max-width: 1400px, which only
   hides the rail. Every grid below it is a fixed desktop layout, so on a phone
   the page scrolls horizontally. With mobile-first indexing that is
   disqualifying for this client in particular.

   All max-width, matching the design system's own direction. Largest first.

   The literal pixel values here are the one legitimate exception to using
   tokens: custom properties cannot be used in a media query prelude without
   @custom-media, which has no browser support.
   ============================================================================ */

/* --- 1400: the rail stops fitting beside a 1240px page --------------------- */
@media (max-width: 1400px) {
  .ds-rail { display: none }
  .page { padding-left: 0 }
}

/* --- 1080: three columns stop working -------------------------------------- */
@media (max-width: 1080px) {
  .platform__grid,
  .testimonials__grid { grid-template-columns: repeat(2, 1fr) }
  /* An orphaned third card looks like a mistake; let it span instead. */
  .platform__grid > :last-child { grid-column: 1 / -1 }

  .services__tags { grid-template-columns: repeat(2, 1fr); row-gap: var(--space-3) }

  .hero__grid { grid-template-columns: 1fr; gap: var(--space-12); align-items: start }
  /* One column: the drawing sits under the CTAs, left-aligned with them rather
     than pinned to a right edge that no longer exists. */
  .hero-art { margin-left: 0 }

  .process__grid,
  .pricing__grid { grid-template-columns: 1fr; gap: var(--space-12) }
  /* One column: heading, portrait, copy, in source order. */
  .about__grid {
    grid-template-columns: 1fr;
    grid-template-areas: "heading" "portrait" "body";
    gap: var(--space-12);
  }
  /* A full-width 3/4 portrait becomes a slab. */
  .about__portrait { max-width: 320px }

  .comparison__col { padding: var(--space-3) var(--space-4) }
  .comparison__label,
  .comparison__cell { padding: var(--space-4) }

  /* The audience columns are prose, not cards of equal weight; side by side
     they drop to about 30 characters a line. */
  .audience__grid { grid-template-columns: 1fr }
  .checklist--split { gap: 14px var(--space-10) }
}

/* --- 820: two columns stop working; the nav no longer fits ----------------- */
@media (max-width: 820px) {
  .services__grid,
  .platform__grid,
  .testimonials__grid { grid-template-columns: 1fr }
  .platform__grid > :last-child { grid-column: auto }

  .hero__grid { padding: var(--space-16) 0 var(--space-12) }
  .newsletter__grid { grid-template-columns: 1fr; gap: var(--space-8); padding-block: var(--space-20) }
  .newsletter__action { justify-content: flex-start }

  .contact__panel { padding: var(--space-12) var(--space-6) }
  .checklist--split { grid-template-columns: 1fr }
  .results__case { padding: var(--space-5) }
  .results__svg { height: 200px }

  /* Mobile navigation: the links become a full-height panel behind a toggle. */
  .nav__toggle { display: grid }
  .nav__links {
    position: fixed;
    inset: var(--nav-h) 0 0 0;
    z-index: 60;
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: 0;
    padding: var(--space-6) var(--pad-x);
    background: var(--bg-page);
    border-top: var(--border-hair) solid var(--border-subtle);
    overflow-y: auto;
    /* Hidden from pointer *and* keyboard until opened — a visually offscreen
       menu that still takes focus is worse than no menu. */
    visibility: hidden;
    opacity: 0;
    transform: translateY(calc(-1 * var(--space-2)));
    transition: opacity var(--dur-base) var(--ease-out),
                transform var(--dur-base) var(--ease-out),
                visibility var(--dur-base) var(--ease-out);
  }
  .nav[data-nav-open] .nav__links { visibility: visible; opacity: 1; transform: none }

  .nav__links .ds-navlink,
  .nav__locale {
    display: block;
    width: 100%;
    padding: var(--space-4) 0;
    font-size: var(--btn-fs-lg);
    border-bottom: var(--border-hair) solid var(--border-subtle);
  }
  .nav__links .ds-navlink::after { display: none }

  /* In the panel the dropdown stops floating and becomes a nested list. The
     selectors carry .nav__links so they outrank the .nav__links .ds-navlink
     rule above, which the toggle also matches. */
  .nav__links .nav__services { position: static; width: 100% }
  .nav__links .nav__services-toggle {
    display: flex;
    width: 100%;
    justify-content: space-between;
    padding: var(--space-4) 0;
    font-size: var(--btn-fs-lg);
    border-bottom: var(--border-hair) solid var(--border-subtle);
  }
  .nav__links .nav__dropdown {
    position: static;
    min-width: 0;
    padding: 0 0 var(--space-2) var(--space-4);
    background: transparent;
    border: 0;
    box-shadow: none;
    transform: none;
    /* display, not visibility: a collapsed list still occupying its height
       leaves a gap in the middle of the panel. */
    display: none;
  }
  .nav__links .nav__services[data-open] .nav__dropdown {
    display: block;
    visibility: visible;
    opacity: 1;
  }
  .nav__links .nav__dropdown-link { padding: var(--space-3) var(--space-4) }

  .nav[data-nav-open] .nav__icon-open { display: none }
  .nav[data-nav-open] .nav__icon-close { display: block }

  body[data-nav-open] { overflow: hidden }
}

/* --- 560: the comparison grid has to become cards -------------------------- */
@media (max-width: 560px) {
  .shell { padding-inline: var(--gutter-tight) }

  .hero__actions .ds-btn,
  .pricing__actions .ds-btn,
  .contact__actions .ds-btn { flex: 1 1 auto; justify-content: center }

  .services__tags { grid-template-columns: 1fr }

  /* The numeral moves above the title so the text gets the full width. */
  .process__step { grid-template-columns: 1fr; gap: var(--space-2) }

  .results__svg { height: 160px }
  .results__peak { gap: var(--space-3) }
  .results__tab { padding: var(--space-4) var(--space-5) }

  /* The comparison table stops being a grid and becomes one card per row.
     Same DOM, same semantics — the column name is supplied from data-col,
     which is populated from t() so the copy stays translatable. */
  .comparison__table,
  .comparison__table thead,
  .comparison__table tbody,
  .comparison__table tr,
  .comparison__table th,
  .comparison__table td { display: block; width: auto }

  .comparison__table thead { display: none }
  .comparison__table { border: none }

  .comparison__table tbody tr {
    border: var(--border-hair) solid var(--border-subtle);
    margin-bottom: var(--space-3);
  }
  .comparison__label {
    border-top: none;
    border-bottom: var(--border-hair) solid var(--border-subtle);
    background: var(--surface-card);
  }
  .comparison__cell {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    border-left: none;
    border-top: none;
    text-align: left;
    padding: var(--space-3) var(--space-5);
  }
  .comparison__cell::before {
    content: attr(data-col);
    font-family: var(--font-mono);
    font-size: var(--btn-fs-sm);
    letter-spacing: var(--tracking-micro);
    text-transform: uppercase;
    color: var(--text-faint);
  }
  .comparison__cell--mine::before { color: var(--text-accent) }

  /* A sentence and its column label cannot share a line at this width, so the
     text variant stacks the label above the cell instead of opposing it. */
  .comparison__table--text .comparison__cell {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-1);
  }
}

/* --- 560, continued: the nav bar can no longer hold the CTA ---------------- */
@media (max-width: 560px) {
  .nav__actions .ds-btn { display: none }
  .nav__panel-cta { display: block; width: 100%; padding-top: var(--space-5) }
  .nav__panel-cta .ds-btn { width: 100%; justify-content: center }
}
