/* ==========================================================================
   Cognnovate homepage
   Implements the "Cognnovate Homepage" design from Claude Design.
   Scoped to index.html only — other pages still use assets/css/style.css.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Design tokens
   Hex values are fallbacks for engines without oklch(); the @supports block
   below upgrades them to the design's original oklch values.
   -------------------------------------------------------------------------- */
:root {
  /* --- Surfaces & text ------------------------------------------------- */
  --bg: #faf9f6;
  --surface: #f4f2ee;
  --white: #fcfcfc;
  --ink: #232b3d;
  --body: #4e4a44;
  --muted: #605c55;
  --line: #e0ded9;
  --line-input: #92908d;      /* 3.00:1 on --bg (WCAG 1.4.11) */

  /* --- Accent ----------------------------------------------------------
     Three tokens, not one, because a single lightness cannot satisfy both
     the 3:1 non-text threshold and the 4.5:1 text threshold.
       --accent       decorative only: rules, focus ring, underline, shadow
       --accent-text  text on LIGHT surfaces — 4.83:1 on --bg, 4.99:1 on --white
       --accent-text-hover  6.79:1 on --bg
     Do NOT use these on --ink; coral measures 4.16:1 there and fails. A dark
     surface would need a lighter variant. */
  --accent: #e8573c;
  --accent-text: #c8393a;
  --accent-text-hover: #ac1922;

  /* --- Footer ----------------------------------------------------------- */
  --footer-text: #e5e3de;
  --footer-muted: #ada9a2;
  --footer-line: #47443f;
  --footer-faint: #8d8c88;    /* 4.50:1 on --ink (WCAG 1.4.3) */

  /* --- Type scale -------------------------------------------------------
     rem so the page honours the reader's browser font-size preference.
     Values are at parity with the previous px literals at a 16px root, so
     this centralises the scale without shifting any rendered text. */
  --text-eyebrow: 0.78125rem; /* 12.5px */
  --text-meta: 0.8125rem;     /* 13px   */
  --text-sm: 0.875rem;        /* 14px   */
  --text-nav: 0.90625rem;     /* 14.5px */
  --text-body: 0.9375rem;     /* 15px   */
  --text-body-lg: 1rem;       /* 16px   */
  --text-lede: 1.0625rem;     /* 17px   */
  --text-h3: 1.1875rem;       /* 19px   */
  --text-brand-sm: 1.25rem;   /* 20px   */
  --text-brand: 1.3125rem;    /* 21px   */
  --text-h2-xs: 1.625rem;     /* 26px   */
  --text-h2-sm: 1.6875rem;    /* 27px   */
  --text-h2: 2rem;            /* 32px   */
  --text-h2-lg: 2.125rem;     /* 34px   */
  --text-stat-sm: 2.375rem;   /* 38px   */
  --text-stat: 2.75rem;       /* 44px   */
  --text-hero: clamp(2.125rem, 3.9vw, 3.625rem);

  /* --- Spacing ----------------------------------------------------------- */
  --space-1: 0.25rem;   /* 4px  */
  --space-2: 0.5rem;    /* 8px  */
  --space-3: 0.75rem;   /* 12px */
  --space-4: 1rem;      /* 16px */
  --space-5: 1.25rem;   /* 20px */
  --space-6: 1.5rem;    /* 24px */
  --space-8: 2rem;      /* 32px */
  --space-11: 2.75rem;  /* 44px */
  --space-14: 3.5rem;   /* 56px */
  --space-16: 4rem;     /* 64px */
  --space-18: 4.5rem;   /* 72px */
  --space-20: 5rem;     /* 80px */
  --space-30: 7.5rem;   /* 120px */

  /* --- Motion, shape, layout --------------------------------------------- */
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --duration-fast: 0.2s;
  --duration-base: 0.35s;
  --duration-slow: 0.8s;
  --radius: 3px;
  --gutter: 48px;
  --max: 1440px;

  /* Measured from .site-header by home.js; this is the no-JS fallback. */
  --header-h: 93px;

  --shadow-btn: 0 14px 28px -10px rgba(232, 87, 60, 0.55);
  --shadow-btn-sm: 0 10px 24px -8px rgba(232, 87, 60, 0.5);
  --header-bg: rgba(250, 249, 246, 0.92);
}

@supports (color: oklch(50% 0.1 250)) {
  :root {
    --bg: oklch(98% 0.006 90);
    --surface: oklch(96% 0.006 90);
    --white: oklch(99% 0 0);
    --ink: oklch(27% 0.045 262);
    --body: oklch(38% 0.012 90);
    --muted: oklch(45% 0.012 90);
    --line: oklch(89% 0.006 90);
    --line-input: oklch(65.5% 0.006 90);
    --accent: oklch(64% 0.17 25);
    --accent-text: oklch(56% 0.18 25);
    --accent-text-hover: oklch(48% 0.18 25);
    --footer-text: oklch(90% 0.006 90);
    --footer-muted: oklch(70% 0.006 90);
    --footer-line: oklch(35% 0.01 90);
    --footer-faint: oklch(64% 0.006 90);
  }
}

/* Derive the translucent values from their source tokens so they cannot
   drift when the palette changes. */
@supports (background: color-mix(in oklab, red 50%, transparent)) {
  :root {
    --shadow-btn: 0 14px 28px -10px color-mix(in oklab, var(--accent) 55%, transparent);
    --shadow-btn-sm: 0 10px 24px -8px color-mix(in oklab, var(--accent) 50%, transparent);
    --header-bg: color-mix(in oklab, var(--bg) 92%, transparent);
  }
}

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

/* The header is sticky, so anchor targets and focus moves must clear it.
   Without this, "Skip to content" lands behind the header and the target is
   entirely obscured (WCAG 2.2 SC 2.4.11 Focus Not Obscured). */
html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + var(--space-4));
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: 'Manrope', system-ui, -apple-system, 'Segoe UI', sans-serif;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; }

a {
  color: var(--accent-text);
  text-decoration: none;
  transition: color var(--duration-base);
}

a:hover { color: var(--accent-text-hover); }

h1, h2, h3 {
  font-family: 'Sora', system-ui, sans-serif;
  letter-spacing: -0.02em;
}

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

/* No overflow-x:hidden here on purpose. It previously masked a grid that
   overflowed below 340px rather than fixing it; the grids now use
   minmax(min(...)) so nothing overflows, and leaving the clip in place would
   hide the next such bug just as effectively. */
.shell {
  max-width: var(--max);
  margin: 0 auto;
  position: relative;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--ink);
  color: var(--white);
  padding: 12px 20px;
}

.skip-link:focus {
  left: 0;
  color: var(--white);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Honeypot. Deliberately NOT .sr-only — this must be hidden from real users
   and screen readers alike, while staying visible to naive bots. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* --------------------------------------------------------------------------
   Shared pieces
   -------------------------------------------------------------------------- */
.eyebrow {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-6);
}

.eyebrow__num {
  font-family: 'Sora', sans-serif;
  font-size: var(--text-meta);
  font-weight: 600;
  color: var(--muted);
}

.eyebrow__rule {
  width: 28px;
  height: 1px;
  background: var(--ink);
  flex: none;
}

.eyebrow__text {
  font-size: var(--text-eyebrow);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Section labels that are semantically headings but styled as eyebrows: the
   base h1-h3 rule would otherwise impose Sora and default margins. */
.eyebrow__heading {
  font-family: inherit;
  margin: 0;
  line-height: inherit;
}

.btn {
  display: inline-block;
  background: var(--ink);
  color: var(--white);
  padding: 15px 28px;
  border-radius: var(--radius);
  font-size: var(--text-body);
  font-weight: 600;
  border: none;
  cursor: pointer;
  font-family: inherit;
  transition:
    transform var(--duration-base) var(--ease),
    box-shadow var(--duration-base) var(--ease),
    background var(--duration-base),
    opacity var(--duration-fast);
}

.btn:hover {
  background: var(--accent);
  color: var(--white);
  transform: translateY(-3px);
  box-shadow: var(--shadow-btn);
}

.btn:active { transform: translateY(-1px); }

/* home.js disables the submit button while a message is in flight. Without
   this the button stayed full-contrast and looked clickable while inert. */
.btn:disabled,
.btn[aria-disabled='true'] {
  opacity: 0.55;
  cursor: not-allowed;
}

.btn:disabled:hover,
.btn[aria-disabled='true']:hover {
  background: var(--ink);
  transform: none;
  box-shadow: none;
}

.btn--sm { padding: 11px 22px; font-size: var(--text-nav); white-space: nowrap; }

.btn--sm:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-btn-sm);
}

/* Secondary action: same footprint, no fill. Used by the consent decline
   button, where an equally-weighted pair would be a dark pattern in reverse. */
.btn--ghost {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--line-input);
}

.btn--ghost:hover {
  background: var(--surface);
  color: var(--ink);
  border-color: var(--ink);
  transform: none;
  box-shadow: none;
}

/* --------------------------------------------------------------------------
   Consent banner
   -------------------------------------------------------------------------- */
.consent {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 200;
  background: var(--white);
  border-top: 1px solid var(--line);
  box-shadow: 0 -8px 24px -18px rgba(0, 0, 0, 0.4);
}

.consent__inner {
  max-width: var(--max);
  margin: 0 auto;
  padding: var(--space-5) var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  flex-wrap: wrap;
}

.consent__copy { flex: 1 1 32ch; }

.consent__title {
  font-family: 'Sora', sans-serif;
  font-size: var(--text-body);
  font-weight: 600;
  color: var(--ink);
  margin: 0 0 var(--space-1);
}

.consent__text {
  font-size: var(--text-sm);
  line-height: 1.6;
  color: var(--body);
  margin: 0;
  max-width: 74ch;
}

.consent__actions {
  display: flex;
  gap: var(--space-3);
  flex-shrink: 0;
}

@media (max-width: 720px) {
  .consent__inner {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-4);
  }

  .consent__actions > .btn { flex: 1; text-align: center; }
}

/* Animated underline used by nav links and text links */
.ulink { position: relative; }

.ulink::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -3px;
  width: 100%;
  height: 1.5px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.4s var(--ease);
}

.ulink:hover::after { transform: scaleX(1); }

.section {
  padding: var(--space-30) var(--gutter);
  border-bottom: 1px solid var(--line);
}

.section__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-6);
  margin-bottom: var(--space-14);
  flex-wrap: wrap;
}

.section__title {
  font-size: var(--text-h2);
  font-weight: 700;
  margin: 0;
}

.section__note {
  font-size: var(--text-sm);
  color: var(--muted);
  margin: 0;
}

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */
.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 26px var(--gutter);
  position: sticky;
  top: 0;
  background: var(--header-bg);
  backdrop-filter: blur(8px);
  z-index: 50;
  border-bottom: 1px solid var(--line);
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--ink);
}

.brand:hover { color: var(--ink); }

.brand img {
  width: 40px;
  height: 40px;
  object-fit: contain;
}

.brand__name {
  font-family: 'Sora', sans-serif;
  font-weight: 700;
  font-size: var(--text-brand);
  letter-spacing: -0.02em;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 40px;
}

.site-nav a:not(.btn) {
  color: var(--ink);
  font-size: var(--text-nav);
  font-weight: 500;
}

.site-nav a:not(.btn):hover { color: var(--ink); }

.nav-toggle {
  display: none;
  background: none;
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: 9px 11px;
  cursor: pointer;
  color: var(--ink);
}

.nav-toggle__bar {
  display: block;
  width: 20px;
  height: 2px;
  background: currentColor;
  transition: transform 0.3s var(--ease), opacity 0.2s;
}

.nav-toggle__bar + .nav-toggle__bar { margin-top: 5px; }

.nav-toggle[aria-expanded='true'] .nav-toggle__bar:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded='true'] .nav-toggle__bar:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded='true'] .nav-toggle__bar:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */
.hero {
  display: grid;
  grid-template-columns: minmax(360px, 1.05fr) minmax(320px, 1fr);
  gap: var(--space-18);
  padding: 128px var(--gutter) 100px;
  border-bottom: 1px solid var(--line);
}

.hero__kicker {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: 28px;
}

.hero h1 {
  font-size: var(--text-hero);
  line-height: 1.06;
  font-weight: 700;
  letter-spacing: -0.03em;
  margin: 0 0 28px;
  max-width: 15ch;
}

.hero__lede {
  font-size: var(--text-lede);
  line-height: 1.65;
  color: var(--body);
  margin: 0 0 40px;
  max-width: 46ch;
}

.hero__actions {
  display: flex;
  gap: 28px;
  align-items: center;
  flex-wrap: wrap;
}

.hero__link {
  color: var(--ink);
  font-size: var(--text-body);
  font-weight: 600;
}

/* Text, so it needs the 4.5:1 token even in the hover state. */
.hero__link:hover { color: var(--accent-text-hover); }

.hero__media {
  width: 100%;
  height: 460px;
  border: 1px solid var(--line);
  object-fit: contain;
  background: var(--surface);
  display: block;
  animation: float 5s ease-in-out infinite;
}

@keyframes float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-10px); }
}

/* --------------------------------------------------------------------------
   Stats
   -------------------------------------------------------------------------- */
.stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  padding: 0 var(--gutter);
  border-bottom: 1px solid var(--line);
}

.stat {
  padding: var(--space-11) var(--space-8);
  border-right: 1px solid var(--line);
  position: relative;
}

.stats .stat:first-child { padding-left: 0; }
.stats .stat:last-child { padding-right: 0; border-right: none; }

.stat::before {
  content: '';
  position: absolute;
  top: 44px;
  left: 32px;
  width: 36px;
  height: 3px;
  border-radius: 2px;
  background: var(--accent);
}

.stats .stat:first-child::before { left: 0; }

.stat__num {
  font-family: 'Sora', sans-serif;
  font-size: var(--text-stat);
  font-weight: 700;
  letter-spacing: -0.02em;
  margin-top: 14px;
  /* Fixed-width digits stop the number jittering while it counts up. */
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum';
}

.stat__label {
  font-size: var(--text-nav);
  color: var(--muted);
  margin-top: 8px;
}

/* --------------------------------------------------------------------------
   About
   -------------------------------------------------------------------------- */
.about {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-18);
  align-items: center;
  padding: var(--space-30) var(--gutter);
  border-bottom: 1px solid var(--line);
}

.about h2 {
  font-size: var(--text-h2-lg);
  font-weight: 700;
  margin: 0 0 22px;
  line-height: 1.2;
}

.about p {
  font-size: var(--text-body-lg);
  line-height: 1.75;
  color: var(--body);
  margin: 0 0 18px;
}

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

.about__media {
  width: 100%;
  height: 400px;
  border: 1px solid var(--line);
  object-fit: cover;
  display: block;
}

/* --------------------------------------------------------------------------
   Approach — three bordered columns
   -------------------------------------------------------------------------- */
.approach {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  border-top: 1px solid var(--line);
}

.approach__item {
  padding: var(--space-8);
  border-right: 1px solid var(--line);
}

.approach__item:first-child { padding-left: 0; }
.approach__item:last-child { padding-right: 0; border-right: none; }

.approach__item h3 {
  font-size: var(--text-h3);
  font-weight: 600;
  margin: 0 0 12px;
}

.approach__item p {
  font-size: var(--text-body);
  line-height: 1.65;
  color: var(--body);
  margin: 0;
}

/* --------------------------------------------------------------------------
   Services — bordered grid
   -------------------------------------------------------------------------- */
.services {
  display: grid;
  /* min() keeps the track from exceeding the container below ~340px. */
  grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
  border-top: 1px solid var(--line);
  border-left: 1px solid var(--line);
}

.service {
  position: relative;
  padding: 36px;
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  transition: background 0.22s var(--ease);
}

/* Motion review #4: the same coral accent bar as the work cards. No lift here
   — the tiles share borders in a contiguous grid, so a lift would break the
   ruled alignment. */
.service::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: 3px;
  background: var(--accent);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 0.22s var(--ease);
}

.service:hover { background: var(--surface); }
.service:hover::before { transform: scaleY(1); }

.service__num {
  font-family: 'Sora', sans-serif;
  font-size: var(--text-meta);
  font-weight: 600;
  color: var(--accent-text);
  margin-bottom: 18px;
}

.service h3 {
  font-size: var(--text-h3);
  font-weight: 600;
  margin: 0 0 10px;
}

.service p {
  font-size: var(--text-nav);
  line-height: 1.65;
  color: var(--body);
  margin: 0;
}

/* --------------------------------------------------------------------------
   Work: the case-study grid. Cards are text-only by design. The only client
   imagery available was stock photography, and stock photos presented as
   client work would undercut the very thing the section exists to prove.
   -------------------------------------------------------------------------- */
/* Cards draw their own hairline instead of the grid painting one behind them.
   The painted-background trick only looks right when the items exactly fill
   every row: any short final row shows the backing colour through the empty
   cells as a solid slab. box-shadow is used rather than a border so the
   hairline costs no layout width and cannot reintroduce the sub-340px
   overflow noted at the top of this file. */
.work {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1px;
}

/* Five cards: a plain auto-fit grid leaves the 5th card stretched across a
   full row with a large empty area beside its text. Lay them out as an
   explicit 3 + 2 instead (six tracks: three span-2 cards, then two span-3
   cards) so every row is filled edge to edge. Collapses to a single column
   below 981px, matching the rest of the page. */
@media (min-width: 981px) {
  .work { grid-template-columns: repeat(6, 1fr); }
  .work__card:nth-child(-n + 3) { grid-column: span 2; }
  .work__card:nth-child(n + 4) { grid-column: span 3; }
}

.work__card {
  position: relative;
  background: var(--bg);
  box-shadow: 0 0 0 1px var(--line);
  overflow: hidden;
}

/* Motion review #4: hover feedback via a coral accent bar that wipes down the
   left edge, plus a soft drop shadow for depth. The bar lives on ::before — an
   element the scroll-reveal transition does not touch — so it animates cleanly
   at 220ms without fighting the card's one-time entrance transform. The global
   prefers-reduced-motion rule collapses it to instant. */
.work__card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: 3px;
  background: var(--accent);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 0.22s var(--ease);
  z-index: 1;
}

.work__card:hover {
  box-shadow:
    0 0 0 1px var(--line),
    0 16px 30px -20px color-mix(in oklab, var(--ink) 35%, transparent);
}

.work__card:hover::before { transform: scaleY(1); }

/* Branded banner header: a shared soft coral glow + dot field (identical on
   every card for cohesion) with a per-industry line icon centred on top. */
.work__media {
  height: 148px;
  display: grid;
  place-items: center;
  border-bottom: 1px solid var(--line);
  background:
    radial-gradient(130px 130px at 82% 22%,
      color-mix(in oklab, var(--accent) 16%, transparent), transparent 70%),
    radial-gradient(color-mix(in oklab, var(--ink) 8%, transparent) 1.2px,
      transparent 1.2px) 0 0 / 16px 16px,
    var(--surface);
}

.work__icon { width: 58px; height: 58px; }

.work__icon .ico,
.work__icon .ico-a {
  fill: none;
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.work__icon .ico { stroke: var(--ink); }
.work__icon .ico-a { stroke: var(--accent); }
.work__icon .ico-a-fill { fill: var(--accent); }

.work__body { padding: var(--space-6); }

.work__meta {
  font-size: var(--text-eyebrow);
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: 8px;
}

.work__body p {
  font-size: var(--text-body);
  line-height: 1.6;
  margin: 0;
}

.work__title {
  font-size: var(--text-h3);
  margin: 0 0 var(--space-3);
}

/* The quote lives inside the card it belongs to rather than in a separate
   testimonials strip, so a reader never sees praise detached from the work it
   refers to. Set quieter than the body copy: it supports the result, it is not
   the headline. */
.work__quote {
  margin: var(--space-5) 0 0;
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
}

.work__quote p {
  font-size: var(--text-sm);
  line-height: 1.7;
  color: var(--muted);
  margin: 0;
}

.work__quote p::before { content: '\201C'; }
.work__quote p::after { content: '\201D'; }

/* --------------------------------------------------------------------------
   Clients
   -------------------------------------------------------------------------- */
.clients-section {
  padding: var(--space-20) var(--gutter);
  border-bottom: 1px solid var(--line);
}

/* Rendered as an <h2> for document structure, but keeps the eyebrow styling:
   the base h1-h3 rule would otherwise impose Sora and a default top margin. */
.clients-section__label {
  font-family: inherit;
  font-size: var(--text-eyebrow);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 36px;
}

.commitments {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
  gap: 1px;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Same hairline treatment as .work, and for the same reason: at wide viewports
   this grid resolves to five columns for four items, so the fifth cell was
   showing the backing colour as a solid block. */
.commitments li {
  background: var(--bg);
  box-shadow: 0 0 0 1px var(--line);
  padding: var(--space-6);
}

.commitments h3 {
  font-size: var(--text-h3);
  font-weight: 600;
  margin: 0 0 var(--space-3);
}

.commitments p {
  font-size: var(--text-body);
  line-height: 1.65;
  color: var(--body);
  margin: 0;
}

.clients {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(120px, 100%), 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
}

.clients__cell {
  background: var(--bg);
  padding: var(--space-5);
  display: flex;
  align-items: center;
  justify-content: center;
}

.clients__cell img {
  width: 100%;
  height: 40px;
  object-fit: contain;
  display: block;
}

/* --------------------------------------------------------------------------
   Contact
   -------------------------------------------------------------------------- */
.contact {
  padding: var(--space-30) var(--gutter);
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;
  gap: var(--space-18);
  align-items: start;
}

.contact h2 {
  font-size: var(--text-h2);
  font-weight: 700;
  margin: 0 0 20px;
}

.contact__lede {
  font-size: var(--text-body-lg);
  line-height: 1.65;
  color: var(--body);
  margin: 0 0 36px;
}

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

.contact__row {
  padding-top: 20px;
  border-top: 1px solid var(--line);
}

.contact__key {
  font-size: var(--text-eyebrow);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin-bottom: 6px;
}

.contact__val {
  font-size: var(--text-body);
  line-height: 1.5;
}

.contact-form {
  border: 1px solid var(--line);
  padding: 40px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.contact-form__note {
  font-size: var(--text-eyebrow);
  color: var(--muted);
  margin: 0;
}

.contact-form__pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}

.contact-form input[type='text'],
.contact-form input[type='email'],
.contact-form textarea {
  width: 100%;
  padding: 13px 14px;
  border: 1px solid var(--line-input);
  border-radius: 0;
  font-size: var(--text-body);
  font-family: inherit;
  color: var(--ink);
  background: var(--white);
  transition: border-color 0.25s;
}

.contact-form input:focus,
.contact-form textarea:focus { border-color: var(--accent); }

.contact-form textarea { resize: vertical; }

.contact-form__legend {
  font-size: var(--text-meta);
  font-weight: 600;
  color: var(--body);
  margin-bottom: 10px;
  padding: 0;
}

.contact-form fieldset {
  border: none;
  padding: 0;
  margin: 0;
}

.choices {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.choice {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-sm);
  border: 1px solid var(--line-input);
  padding: var(--space-2) var(--space-3);
  cursor: pointer;
  transition: border-color var(--duration-fast), background var(--duration-fast);
}

.choice:hover { border-color: var(--accent); }

/* A selected chip was visually identical to an unselected one, leaving the
   13px native checkbox as the only indication of state. */
.choice:has(input:checked) {
  border-color: var(--accent);
  background: var(--surface);
}

.choice input { accent-color: var(--accent); }

.form-status {
  font-size: var(--text-nav);
  line-height: 1.5;
  margin: 0;
}

.form-status[data-state='error'] { color: var(--accent-text); }

/* Success is a deliberate confirmation, not a throwaway line: a leading check,
   medium weight, and a quiet rise-in. It stays in ink rather than green so the
   single coral accent keeps its meaning (attention/error) — the check glyph and
   copy carry the "done" signal. home.js clears it after a few seconds. */
.form-status[data-state='ok'] {
  display: flex;
  align-items: baseline;
  gap: 8px;
  color: var(--ink);
  font-weight: 600;
  animation: form-status-in var(--duration-fast, 0.2s) ease-out;
}

.form-status[data-state='ok']::before {
  content: '';
  flex: none;
  align-self: center;
  width: 16px;
  height: 16px;
  background: var(--accent);
  /* A check mark, masked so it inherits the accent as a crisp glyph. */
  -webkit-mask: no-repeat center / 12px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
          mask: no-repeat center / 12px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
}

/* Fades out when home.js flags the message for dismissal. */
.form-status.is-leaving {
  opacity: 0;
  transition: opacity 0.4s ease;
}

@keyframes form-status-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .form-status[data-state='ok'] { animation: none; }
  .form-status.is-leaving { transition: none; }
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */
.site-footer {
  background: var(--ink);
  color: var(--footer-text);
  padding: var(--space-16) var(--gutter) var(--space-8);
}

.site-footer__grid {
  display: grid;
  grid-template-columns: 1.3fr 1fr 1fr 1.1fr;
  gap: 40px;
  padding-bottom: 40px;
  border-bottom: 1px solid var(--footer-line);
}

.site-footer .brand,
.site-footer .brand:hover { color: var(--white); }

.site-footer .brand { margin-bottom: 14px; }

.site-footer .brand img { width: 34px; height: 34px; }

.site-footer .brand__name { font-size: var(--text-brand-sm); color: var(--white); }

.site-footer__blurb {
  font-size: var(--text-sm);
  line-height: 1.65;
  color: var(--footer-muted);
  margin: 0 0 20px;
  max-width: 34ch;
}

.social {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
}

/* Each social link carries its platform's logo before the label, so it reads at
   a glance even if the wordmark alone doesn't. Icons are masked SVGs painted in
   currentColor, so they follow the footer link colour and its hover. The right
   glyph is chosen from the href — no per-link markup needed. */
.social a {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

.social a::before {
  content: '';
  flex: none;
  width: 15px;
  height: 15px;
  background: currentColor;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-position: center;
          mask-position: center;
  -webkit-mask-size: contain;
          mask-size: contain;
}

.social a[href*="twitter"]::before,
.social a[href*="x.com"]::before {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z'/%3E%3C/svg%3E");
}

.social a[href*="facebook"]::before {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z'/%3E%3C/svg%3E");
}

.social a[href*="instagram"]::before {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 100 12.324 6.162 6.162 0 000-12.324zM12 16a4 4 0 110-8 4 4 0 010 8zm6.406-11.845a1.44 1.44 0 100 2.881 1.44 1.44 0 000-2.881z'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 100 12.324 6.162 6.162 0 000-12.324zM12 16a4 4 0 110-8 4 4 0 010 8zm6.406-11.845a1.44 1.44 0 100 2.881 1.44 1.44 0 000-2.881z'/%3E%3C/svg%3E");
}

.social a[href*="linkedin"]::before {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.225 0z'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.225 0z'/%3E%3C/svg%3E");
}

.site-footer a {
  color: var(--footer-muted);
  font-size: var(--text-sm);
}

.site-footer a:hover { color: var(--white); }

.site-footer__heading {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--white);
  margin-bottom: 14px;
}

.site-footer__links {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.site-footer__contact {
  font-size: var(--text-sm);
  line-height: 1.7;
  color: var(--footer-muted);
}

.site-footer__bottom {
  padding-top: 24px;
  font-size: var(--text-meta);
  color: var(--footer-faint);
  text-align: center;
}

/* --------------------------------------------------------------------------
   Scroll reveal
   -------------------------------------------------------------------------- */
/* Elements are hidden only once JS has confirmed it can reveal them again:
   home.js adds .js to <html> immediately before it starts observing. If the
   script 404s, throws, or is blocked, no .js class is ever set and the page
   renders fully visible instead of blank. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(24px) scale(0.98);
  filter: blur(6px);
  transition:
    opacity var(--duration-slow) var(--ease),
    transform var(--duration-slow) var(--ease),
    filter var(--duration-slow) var(--ease);
  transition-delay: var(--reveal-delay, 0s);
}

.js [data-reveal].is-revealed {
  opacity: 1;
  transform: translateY(0) scale(1);
  filter: blur(0px);
}

/* Motion review #7: the contact submit button dips on press, then confirms
   with a popping checkmark and a "Sent" label (home.js toggles .is-sent when
   JotForm accepts the message). Reinforces the status line so the send reads
   as real. */
.contact-form button[type='submit']:active:not(:disabled) {
  transform: scale(0.97);
}

.contact-form button.is-sent .btn__check {
  display: inline-block;
  margin-right: 6px;
  animation: popCheck 0.4s var(--ease) both;
}

@keyframes popCheck {
  0%   { transform: scale(0.5); opacity: 0; }
  60%  { transform: scale(1.15); opacity: 1; }
  100% { transform: scale(1); }
}

/* --------------------------------------------------------------------------
   Responsive — the source design was desktop-only; these are additions
   -------------------------------------------------------------------------- */
@media (max-width: 1100px) {
  .site-footer__grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 980px) {
  :root { --gutter: 32px; }

  .hero {
    grid-template-columns: 1fr;
    gap: 48px;
    padding: var(--space-20) var(--gutter) var(--space-18);
  }

  .hero h1 { max-width: 100%; }
  .hero__media { height: 340px; }

  .about {
    grid-template-columns: 1fr;
    gap: 40px;
    padding: var(--space-20) var(--gutter);
  }

  .about__media { height: 300px; }

  .contact {
    grid-template-columns: 1fr;
    gap: 48px;
    padding: var(--space-20) var(--gutter);
  }

  .section { padding: var(--space-20) var(--gutter); }

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

  .stat,
  .stats .stat:first-child,
  .stats .stat:last-child {
    padding: var(--space-8) 0;
    border-right: none;
    border-bottom: 1px solid var(--line);
  }

  .stats .stat:last-child { border-bottom: none; }
  .stat::before,
  .stats .stat:first-child::before { left: 0; top: 32px; }

  /* The stacked border treatment below assumes one item per row. */
  .approach { grid-template-columns: 1fr; }

  .approach__item,
  .approach__item:first-child,
  .approach__item:last-child {
    padding: 28px 0;
    border-right: none;
    border-bottom: 1px solid var(--line);
  }

  .approach__item:last-child { border-bottom: none; }
}

@media (max-width: 900px) {
  .nav-toggle { display: block; }

  .site-nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--bg);
    border-bottom: 1px solid var(--line);
    padding: 8px var(--gutter) 24px;
    display: none;
  }

  .site-nav.is-open { display: flex; }

  .site-nav a:not(.btn) {
    padding: 14px 0;
    border-bottom: 1px solid var(--line);
    font-size: var(--text-body-lg);
  }

  .site-nav .btn {
    margin-top: 18px;
    text-align: center;
  }

  /* The underline sweep reads as a glitch in a stacked list. */
  .site-nav .ulink::after { display: none; }
}

@media (max-width: 720px) {
  :root { --gutter: 20px; }

  .site-header { padding: 18px var(--gutter); }
  .hero { padding: var(--space-14) var(--gutter); }
  .hero__media { height: 240px; }
  .about h2 { font-size: var(--text-h2-sm); }
  .section__title,
  .contact h2 { font-size: var(--text-h2-xs); }
  .service { padding: 28px; }
  .contact-form { padding: var(--space-6); }
  .contact-form__pair { grid-template-columns: 1fr; }
  .site-footer { padding: 48px var(--gutter) 28px; }
  .site-footer__grid { grid-template-columns: 1fr; gap: 32px; }
  .stat__num { font-size: var(--text-stat-sm); }
}

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

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

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

  .hero__media { animation: none; }
}
