/* ===========================================================
   Oldworld Creative - global stylesheet
   Shared across index.html, about.html, contact.html, 404.html,
   and the case-study pages (ministry-of-defence.html,
   lloyds-banking-group.html, pearson-education.html, terraquest.html).
   =========================================================== */

/* ---------- TOKENS ---------- */
:root {
  /* LIGHT MODE - default */
  --cream: #F4EFE6;
  --cream-tint: #ECE5D6;
  --ink: #111111;
  --ink-soft: #2A2A2A;
  --mute: #6A6258;
  --rule: rgba(17, 17, 17, 0.1);
  --rule-strong: #111111;
  --accent: #C73100;
  /* Darker vermilion used for small accent text on the cream-tint
     backgrounds (footer, quote attribution). #C73100 on cream-tint
     is ~4.2:1 - short of AA 4.5:1 - so small-text uses there are
     swapped to this stronger value, which clears 5.6:1. */
  --accent-strong: #A82900;
  --accent-soft: #C9C2B6;
  /* Fixed cream that never flips - for case-study hover row text on vermilion bg */
  --cream-fixed: #F4EFE6;
  --serif: "Fraunces", "Times New Roman", serif;
  --sans: "Inter", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  --radius: 6px;
  --shadow-hover: 0 10px 28px rgba(17, 17, 17, 0.10), 0 2px 6px rgba(17, 17, 17, 0.06);
}

/* DARK MODE - applied via three triggers:
   1. The visible theme toggle's checkbox state (works without JS via :has)
   2. The JS-applied .theme-dark class on <html> (persisted choice or OS)
   3. The OS preference media query below (works without JS at all) - scoped
      with :not(.theme-light) so an explicit "light" choice still wins. */
body:has(.theme-toggle:checked),
html.theme-dark body {
  --cream: #181818;
  --cream-tint: #0A0A0A;
  --ink: #F4EFE6;
  --ink-soft: #C9C2B6;
  --mute: #888278;
  --rule: rgba(255, 255, 255, 0.08);
  --rule-strong: #F4EFE6;
  --accent-soft: #6A6258;
  --shadow-hover: 0 10px 28px rgba(0, 0, 0, 0.45), 0 2px 6px rgba(0, 0, 0, 0.30);
  /* Brighter vermilion in dark mode - gives 4.95:1 on dark cream so
     small-text accents clear AA. (Light mode uses the grounded #C73100
     for the same reason on its lighter background.) */
  --accent: #FF3D00;
  /* In dark mode the cream-tint is near-black, so the bright vermilion
     already clears 5.6:1 - no separate strong variant needed. */
  --accent-strong: #FF3D00;
}
@media (prefers-color-scheme: dark) {
  html:not(.theme-light) body {
    --cream: #181818;
    --cream-tint: #0A0A0A;
    --ink: #F4EFE6;
    --ink-soft: #C9C2B6;
    --mute: #888278;
    --rule: rgba(255, 255, 255, 0.08);
    --rule-strong: #F4EFE6;
    --accent-soft: #6A6258;
    --shadow-hover: 0 10px 28px rgba(0, 0, 0, 0.45), 0 2px 6px rgba(0, 0, 0, 0.30);
    --accent: #FF3D00;
    --accent-strong: #FF3D00;
  }
}

/* ---------- BASE ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

/* ---------- SKIP LINK ----------
   Sits at the very top of the document, off-screen by default and
   revealed when keyboard-focused. Lets users bypass the conformance
   bar, nav, and header to jump straight to main content. */
.skip-link {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 1000;
  padding: 10px 16px;
  background: var(--ink);
  color: var(--cream);
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  border-radius: 4px;
  transform: translateY(-150%);
  transition: transform .15s ease;
}
.skip-link:focus {
  transform: translateY(0);
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
body {
  margin: 0;
  background: var(--cream-tint);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  min-height: 100vh;
  padding: 16px;
}
@media (min-width: 768px)  { body { padding: 20px 16px 16px; } }
@media (min-width: 1024px) { body { padding: 32px 24px 24px; } }
::selection { background: var(--accent); color: var(--cream); }
a { color: inherit; text-decoration: none; }
img, svg { display: block; max-width: 100%; }

/* ---------- HERO HOVER ---------- */
/* The hero/cover panel lifts gently on hover. */
.hero,
.cover { transition: box-shadow .35s ease; }
.hero:hover,
.cover:hover { box-shadow: var(--shadow-hover); }

/* ---------- GLOBAL FOCUS RING (WCAG 2.4.7) ----------
   Branded focus ring applied at all conformance levels - keyboard users
   need a visible focus indicator regardless of the WCAG toggle setting.
   The toggle only widens scope/contrast further at AA/AAA. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 2px;
}
/* The theme toggle's real input is visually hidden, so the focus ring
   has to be forwarded to the visible label pill. */
.theme-link:has(.theme-toggle:focus-visible) {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.theme-toggle:focus-visible { outline: none; }

/* ---------- TARGET SIZE (WCAG 2.5.8, AA, applied universally) ----------
   Every primary interactive element gets a 24×24 CSS px minimum hit area
   so AA target size passes at all conformance levels without requiring
   the WCAG toggle. The AAA toggle further upgrades these to 44×44. */
.nav-links a,
.top-link,
.back-link,
.nav-toggle {
  min-height: 24px;
  display: inline-flex;
  align-items: center;
}
.foot-col > a {
  min-height: 24px;
}
/* Footer-link top margin in A and AA - scoped to NOT-AAA so it doesn't
   stack with the AAA-specific margin-top on the same element. Negative
   value pulls the link text up to sit on the strapline's baseline. */
html:not(.wcag-aaa) .foot-col > a {
  margin-top: -17px;
}

/* ===========================================================
   WCAG AA OVERRIDES - only applied when the user toggles AA
   via the conformance bar (html.wcag-aa class).
   =========================================================== */

/* 1.4.3 Contrast - the brand vermilion (--accent) is now #C73100, which
   gives 4.7:1 on cream and clears AA normal text in default A as well.
   No AA-specific color override is needed. */

/* 1.4.11 Non-text contrast: conformance pill borders need 3:1. Applied
   at AA and inherited at AAA so the keyline doesn't visibly weaken when
   stepping up a level (1.4.11 is a Level AA criterion that still applies
   at AAA - there's no enhanced version, so the same darker rule is fine). */
html.wcag-aa .conformance-options,
html.wcag-aaa .conformance-options { border-color: var(--mute); }
html.wcag-aa .conformance-option,
html.wcag-aaa .conformance-option { border-right-color: var(--mute); }

/* 2.4.7 Focus visible + 2.5.8 Target Size are handled globally above -
   they apply at all conformance levels. */

/* 1.4.10 Reflow is now handled universally in the .top-bar rules above -
   the bar stacks vertically at narrow widths regardless of WCAG level. */

/* ===========================================================
   WCAG AAA OVERRIDES - only applied when the user toggles AAA
   via the conformance bar (html.wcag-aaa class).
   Brand-vermilion contrast tightening (AAA 1.4.6) is deferred
   until the branding palette is revisited.
   =========================================================== */

/* 2.3.3 Animation from Interactions - honour OS reduced-motion preference
   universally. The OS-level "Reduce motion" setting is an accessibility
   preference that applies regardless of the page's WCAG toggle, so this
   rule is not scoped to .wcag-aaa. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
}

/* 1.4.6 Contrast (Enhanced) - darken --mute so muted text clears 7:1
   on cream. Light mode: deeper warm grey; dark mode: lighter warm tan. */
html.wcag-aaa { --mute: #4A453D; }
html.wcag-aaa body:has(.theme-toggle:checked),
html.wcag-aaa.theme-dark body { --mute: #C8C2B0; }

/* 1.4.6 Contrast (Enhanced) - Option 1 accent split. Vermilion (4.7:1
   on cream) passes AA normal and AAA large text, but not AAA normal
   (7:1). For AAA mode, swap small-text uses of accent to var(--ink)
   so they clear AAA. Large headings, decorative graphics, hover
   backgrounds, and accent rules keep the vermilion. */
/* .brand i is no longer in this AAA swap: at 24px it qualifies as large
   text (≥18pt), where vermilion #C73100 on cream clears AAA's 4.5:1 with
   ~4.65:1 to spare. The foot-brand stays small (~17px) so it still needs
   the swap; same for the body-h italic which is normal-size text. */
/* .body-h .ital is no longer in this AAA swap: at 24px+ it qualifies
   as large text (≥18pt), where vermilion #C73100 on cream clears
   AAA's 4.5:1 with ~4.65:1. .foot-brand stays small (~18px = normal
   text, needs 7:1) so its italic still swaps to ink. */
html.wcag-aaa .foot-brand i {
  color: var(--ink);
}
html.wcag-aaa .service-no { color: var(--ink); }
/* The italic "Process" word in the Our Process heading sits on the
   dark ink panel (light mode) / the light cream panel (dark mode).
   The grounded --accent (#C73100) only reaches ~3.2:1 there which
   fails AAA large, so use the brighter dark-mode vermilion (#FF3D00)
   in every mode - clears 4.82:1 on ink and 5.0:1 on cream. */
.approach .section-h .ital {
  color: #FF3D00;
}

/* In AAA, the brand mark's italic "Creative" is ink by default. On hover
   the parent goes vermilion - the italic em needs the hover state too so
   both words shift together rather than just "Oldworld". The footer
   variant uses --accent-strong to clear contrast on cream-tint. */
html.wcag-aaa .foot-brand a:hover i {
  color: var(--accent-strong);
}

/* 2.5.5 Target Size (Enhanced) - small interactive elements grow to 44×44. */
html.wcag-aaa .nav-links a,
html.wcag-aaa .top-link,
html.wcag-aaa .back-link,
html.wcag-aaa .foot-col > a,
html.wcag-aaa .brand {
  min-height: 44px;
  padding: 10px 8px;
  display: inline-flex;
  align-items: center;
}
/* .nav-toggle gets the same AAA tap-area treatment but without the
   display: inline-flex - the toggle is display: none by default and
   only flipped to inline-flex at <768px via the .nav-collapsed rule.
   Forcing display here would make it appear at every viewport in AAA. */
html.wcag-aaa .nav-toggle {
  min-height: 44px;
  padding: 10px 8px;
}
/* Brand sits at the nav's left content edge - zero the AAA padding-left
   so it stays visually flush rather than shifting 8px in from the edge. */
html.wcag-aaa .brand { padding-left: 0; }
/* Footer LinkedIn: keep flex-row + right-align + top-align so the link
   text both right-aligns within its column and visually top-aligns
   with the tagline. min-height still gives a 44×44 click area below. */
html.wcag-aaa .foot-col > a {
  display: flex;
  justify-content: flex-end;
  align-items: flex-start;
  padding-top: 0;
  margin-top: 4px;
}
/* The footer pipe separator in AAA: reclaim its left gutter, which the
   AAA `padding: 10px 8px` shorthand would otherwise wipe out. The pipe's
   vertical position (top: 4px from the default rule) already aligns with
   the top-of-text in both 24px and 44px anchor heights. */
html.wcag-aaa .foot-col > a + a {
  padding-left: 22px;
}

/* 1.4.8 Visual Presentation - looser line-heights on tight headings so
   wrapped lines breathe more. */
html.wcag-aaa .hero-h,
html.wcag-aaa .cover-h,
html.wcag-aaa .section-h,
html.wcag-aaa .body-h,
html.wcag-aaa .foot-brand,
html.wcag-aaa .case-body h3,
html.wcag-aaa .next-title {
  line-height: 1.25;
}

/* 3.1.4 Abbreviations - <abbr title="..."> markup is added universally in
   the HTML (semantically helpful even at A/AA), but only AAA exposes the
   visual cue (dotted underline) and help cursor. The default rule only
   resets the browser's underline+help-cursor so body-copy abbreviations
   render at the exact same kerning and density as the surrounding text. */
abbr[title] {
  text-decoration: none;
  cursor: inherit;
}
/* Scoped letter-spacing/kerning reset: only abbreviations inside wide-
   tracking parents (uppercase eyebrows, the conformance bar, etc.) need
   to be pinned back to normal so the abbreviation doesn't visually
   stretch with the parent's tracking. Body-copy abbrs are NOT included -
   they inherit normal tracking from the paragraph and stay tight. */
.conformance-label abbr[title],
.case-meta abbr[title],
.quote-attr abbr[title],
.foot-tag abbr[title],
.clients-sector abbr[title] {
  letter-spacing: normal;
  word-spacing: normal;
  font-variant: normal;
  font-feature-settings: normal;
}
html.wcag-aaa abbr[title] {
  text-decoration: underline dotted;
  text-underline-offset: 3px;
  text-decoration-color: var(--mute);
  cursor: help;
}

/* ===========================================================
   WCAG CONFORMANCE BAR - sits at the very top of every page.
   Three segmented pills (A / AA / AAA) - each applies the
   matching level of overrides defined above when selected.
   =========================================================== */
.top-bar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: 10px 18px;
  background: var(--cream-tint);
  border-bottom: 0.5px solid var(--rule);
}
.top-bar > .conformance-bar { grid-column: 2; }
.top-bar > .theme-link {
  grid-column: 3;
  justify-self: end;
  /* Negative right margin pulls the toggle past the bar's own padding
     so its right edge sits flush with the card outer right edge below. */
  margin-right: -18px;
}
.conformance-bar {
  display: inline-flex;
  align-items: center;
  gap: 12px;
}
/* Mobile (sub-tablet) - WCAG block sits flush left, theme toggle flush
   right. align-items: start keeps the theme link top-aligned with the
   WCAG label rather than the centre of the (taller, on narrow phones)
   stacked block. */
@media (max-width: 767px) {
  .top-bar {
    grid-template-columns: auto 1fr;
    align-items: center;
    /* Zero L/R padding so WCAG sits flush to the left edge of the
       .page and the theme toggle flush to the right. Vertical padding
       (10px) is preserved from the default rule above. */
    padding-left: 0;
    padding-right: 0;
  }
  .top-bar > .conformance-bar {
    grid-column: 1;
    justify-self: start;
  }
  .top-bar > .theme-link {
    grid-column: 2;
    justify-self: end;
    margin-right: 0;
  }
}

/* Narrowest phones - WCAG label moves above its A/AA/AAA buttons so
   the left column stays compact. The wider mobile range keeps them
   inline on a single row. */
@media (max-width: 480px) {
  .top-bar > .conformance-bar {
    flex-direction: column;
    gap: 6px;
  }
}
.conformance-label {
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--mute);
}
.conformance-options {
  display: inline-flex;
  border: 1px solid var(--rule);
  border-radius: 999px;
  overflow: hidden;
}
.conformance-option {
  padding: 5px 12px;
  border: none;
  border-right: 1px solid var(--rule);
  background: transparent;
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--mute);
  cursor: pointer;
  transition: background .2s ease, color .2s ease;
}
.conformance-option:last-child { border-right: none; }
/* Active state is driven from the html.wcag-* class which the inline
   pre-render script in each <head> sets before first paint. Doing it
   this way avoids a flash where AA looks active before oldworld.js
   moves the indicator to the saved level. The matrix:
     saved 'a'   - no html.wcag-* class → A button active
     saved 'aa'  - html.wcag-aa         → AA button active
     saved 'aaa' - html.wcag-aaa        → AAA button active */
html:not(.wcag-aa):not(.wcag-aaa) .conformance-option[data-level="a"],
html.wcag-aa .conformance-option[data-level="aa"],
html.wcag-aaa .conformance-option[data-level="aaa"] {
  background: var(--ink);
  color: var(--cream);
  cursor: default;
}
/* Hover only colours the inactive options - same selector logic. */
html:not(.wcag-aa):not(.wcag-aaa) .conformance-option:not([data-level="a"]):hover,
html.wcag-aa .conformance-option:not([data-level="aa"]):hover,
html.wcag-aaa .conformance-option:not([data-level="aaa"]):hover {
  color: var(--ink);
}
@media (min-width: 768px) {
  .top-bar { padding: 12px 24px; }
  .top-bar > .theme-link { margin-right: -24px; }
  .conformance-bar { gap: 14px; }
  .conformance-label, .conformance-option { font-size: 11px; letter-spacing: 0.16em; }
  .conformance-option { padding: 6px 14px; }
}
@media (min-width: 1024px) {
  .top-bar { padding: 14px 32px; }
  .top-bar > .theme-link { margin-right: -32px; }
}

/* ---------- PAGE FRAME ---------- */
.page {
  background: var(--cream-tint);
  border-radius: var(--radius);
  overflow: hidden;
  margin: 0 auto;
  max-width: 720px;
}

/* ===========================================================
   NAV - index.html, about.html, contact.html, 404.html
   (case-study pages use the simpler .topbar below instead)
   =========================================================== */
.nav {
  background: var(--cream);
  display: flex;
  align-items: center;
  justify-content: space-between;
  position: relative;
  /* Asymmetric vertical padding to optically centre the text - serif
     ascenders make Fraunces sit visually high in a box that's centred
     by math. Adding a couple more px above pushes the glyphs down. */
  padding: 16px 18px 12px;
  border-bottom: 0.5px solid var(--rule);
}

/* ---------- MOBILE NAV TOGGLE ----------
   Progressive enhancement: without JS the nav stays inline at all
   widths. With JS, the .nav-collapsed class is added at page load,
   which at < 768px hides the inline links behind a "Menu" button. */
.nav-toggle {
  display: none;
  align-items: center;
  gap: 8px;
  background: none;
  border: 0;
  padding: 8px 4px;
  margin: 0;
  cursor: pointer;
  color: var(--ink);
  font-family: var(--sans);
}
.nav-toggle-text {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.nav-toggle-text[data-state="open"] { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle-text[data-state="closed"] { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle-text[data-state="open"] { display: inline; }
.nav-toggle-icon {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  width: 20px;
  height: 11px;
}
.nav-toggle-icon span {
  display: block;
  height: 1px;
  width: 100%;
  background: currentColor;
  transition: transform .2s ease, opacity .2s ease;
}
/* Hamburger morphs into a close-X when the menu is open. */
.nav-toggle[aria-expanded="true"] .nav-toggle-icon span:nth-child(1) { transform: translateY(5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle-icon span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle-icon span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }
.nav-toggle:hover { color: var(--accent); }

@media (max-width: 767px) {
  .nav.nav-collapsed .nav-toggle { display: inline-flex; }
  /* Default-closed: links hidden */
  .nav.nav-collapsed .nav-links { display: none; }

  /* Open: overlay fills the entire viewport. Body scroll is locked
     via :has() below. The brand + toggle button keep their natural
     positions but are raised above the overlay with z-index. */
  .nav.nav-collapsed .nav-toggle[aria-expanded="true"] + .nav-links {
    display: flex;
    position: fixed;
    inset: 0;
    z-index: 50;
    background: var(--cream);
    padding: 80px 24px 40px;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 8px;
    overflow-y: auto;
  }
  .nav.nav-collapsed:has(.nav-toggle[aria-expanded="true"]) .brand,
  .nav.nav-collapsed .nav-toggle[aria-expanded="true"] {
    position: relative;
    z-index: 60;
  }
  .nav.nav-collapsed .nav-toggle[aria-expanded="true"] + .nav-links a {
    font-family: var(--serif);
    font-weight: 400;
    font-size: 36px;
    line-height: 1.2;
    letter-spacing: -0.025em;
    color: var(--ink);
    text-align: center;
    padding: 10px 0;
    min-height: 56px;
  }
  .nav.nav-collapsed .nav-toggle[aria-expanded="true"] + .nav-links a:hover { color: var(--accent); }
  /* Lock background scroll while the overlay is open. */
  body:has(.nav-toggle[aria-expanded="true"]) { overflow: hidden; }
}
.brand {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--serif);
  font-weight: 500;
  font-size: 24px;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--ink);
  transition: color .25s ease;
}
.brand:hover { color: var(--accent); }
/* Logo text swap - the nav brand abbreviates to "OWC" at the narrowest
   viewport so it doesn't crowd the hamburger toggle. The footer brand
   always shows the full "Oldworld Creative" wordmark regardless of
   viewport, so .foot-brand .brand-short stays hidden throughout. */
.brand .brand-short,
.foot-brand .brand-short { display: none; }
@media (max-width: 480px) {
  .brand .brand-full { display: none; }
  .brand .brand-short { display: inline; }
}
.brand .dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--accent);
}
.brand i {
  font-style: italic;
  color: var(--accent);
  transition: color .25s ease;
}
.nav-links {
  display: flex;
  gap: 14px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.02em;
}
.nav-links a {
  position: relative;
  padding-bottom: 3px;
  transition: color .2s ease;
}
.nav-links a:hover { color: var(--accent); }

@media (min-width: 768px) {
  .nav { padding: 18px 24px 14px; }
  .brand { font-size: 28px; gap: 10px; }
  .brand .dot { width: 10px; height: 10px; }
  .nav-links { gap: 24px; font-size: 13px; }
}
@media (min-width: 1024px) {
  .nav { padding: 20px 32px 16px; }
  .brand { font-size: 32px; gap: 12px; }
  .brand .dot { width: 12px; height: 12px; }
  .nav-links { gap: 32px; font-size: 14px; }
}

/* ===========================================================
   TOPBAR + BACK LINK - case-study pages only
   =========================================================== */
.topbar {
  background: var(--cream);
  display: flex;
  align-items: center;
  padding: 14px 18px;
  border-bottom: 0.5px solid var(--rule);
}
.back-link {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink);
  cursor: pointer;
  transition: color .2s ease;
}
.back-link .arrow {
  font-family: var(--serif);
  font-style: italic;
  font-size: 22px;
  color: var(--accent);
  line-height: 1;
  transform: translateY(-1px);
  transition: transform .25s ease;
}
.back-link:hover { color: var(--accent); }
.back-link:hover .arrow { transform: translateX(-4px) translateY(-1px); }
@media (min-width: 768px) {
  .topbar { padding: 18px 32px; }
  .back-link { font-size: 12px; gap: 12px; letter-spacing: 0.16em; }
  .back-link .arrow { font-size: 24px; }
}

/* ===========================================================
   HERO - index.html
   =========================================================== */
.hero {
  background: var(--cream);
  padding: 36px 18px;
  border-bottom-left-radius: var(--radius);
  border-bottom-right-radius: var(--radius);
}
.hero-h {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 45px;
  line-height: 1;
  letter-spacing: -0.025em;
  margin: 0;
  color: var(--ink);
}
.hero-h .ital {
  font-style: italic;
  color: var(--accent);
}
.hero-h .marked {
  position: relative;
  display: inline-block;
}
.hero-h .marked svg {
  position: absolute;
  left: -4px;
  right: -4px;
  bottom: -4px;
  width: calc(100% + 8px);
  height: 10px;
  overflow: visible;
}
/* CSS overrides the hardcoded SVG stroke colour so the brushstroke
   follows --accent through theme/mode switches (bright vermilion in
   dark mode, grounded vermilion in light, etc.). */
.hero-h .marked svg path { stroke: var(--accent); }
.hero-h .marked .stack-2,
.hero-h .marked .stack-3 {
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity .15s ease, transform .15s cubic-bezier(.5, 0, .2, 1);
}
.hero-h .marked .stack-2 { transition-delay: .05s; }
.hero-h .marked .stack-3 { transition-delay: .15s; }
.hero-h:hover .marked .stack-2,
.hero-h:hover .marked .stack-3 {
  opacity: 0.8;
  transform: translateY(0);
}
.hero-lede {
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-soft);
  margin: 26px 0 0;
  max-width: 640px;
}
.hero-lede strong { font-weight: 600; }

@media (min-width: 768px) {
  .hero { padding: 48px 28px; }
  .hero-h { font-size: 60px; letter-spacing: -0.03em; }
  .hero-h .marked svg { bottom: -6px; height: 14px; }
  .hero-lede { font-size: 15px; margin-top: 32px; }
}
@media (min-width: 1024px) {
  .hero { padding: 56px 32px; }
  .hero-h { font-size: 76px; letter-spacing: -0.035em; }
  .hero-h .marked svg { bottom: -8px; height: 18px; left: -6px; right: -6px; width: calc(100% + 12px); }
  .hero-lede { font-size: 16px; margin-top: 44px; }
}

/* ===========================================================
   COVER HERO - about.html and case-study pages
   =========================================================== */
.cover {
  background: var(--cream);
  padding: 36px 18px;
  border-bottom-left-radius: var(--radius);
  border-bottom-right-radius: var(--radius);
}
/* When the cover ends with an image, tighten the bottom padding so
   the gap below the image matches the gap on its sides. */
.cover:has(.cover-art) { padding-bottom: 18px; }

/* Cover hero illustration */
.cover-art {
  margin: 0;
  background: var(--cream);
  border-radius: var(--radius);
  overflow: hidden;
}
.cover-art img {
  display: block;
  width: 100%;
  height: auto;
}
.cover-h {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 45px;
  line-height: 1;
  letter-spacing: -0.025em;
  margin: 0 0 14px;
  color: var(--ink);
}
.cover-h .ital { font-style: italic; color: var(--accent); }
.cover-tag {
  font-family: var(--serif);
  font-style: italic;
  font-size: 18px;
  line-height: 1.3;
  color: var(--ink-soft);
  margin: 0 0 28px;
  max-width: 540px;
}
/* External link inside .cover-tag - vermilion underline + the same
   north-east arrow glyph used on the footer LinkedIn link to signal
   "opens in a new tab". The arrow is upright (font-style: normal) so
   it doesn't lean with the surrounding italic body. */
.cover-tag a {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 0.5px;
  text-underline-offset: 3px;
  transition: color .2s ease;
}
.cover-tag a:hover { color: var(--accent-strong); }
.cover-tag a[target="_blank"]::after {
  content: "\2197";
  display: inline-block;
  font-family: var(--sans);
  font-style: normal;
  font-size: 0.8em;
  margin-left: 2px;
  line-height: 1;
  transition: transform .25s ease;
}
.cover-tag a[target="_blank"]:hover::after { transform: translate(2px, -2px); }

/* ---------- PLACEHOLDER NOTE ----------
   Quiet, centred message used in place of cards while a section is
   unfinished (e.g. "Case study coming soon."). No card chrome - just
   centred serif type with generous top/bottom breathing room so it
   sits as an aside between the surrounding cards. */
.stack .placeholder-note {
  text-align: center;
  margin: 56px 18px;
  font-family: var(--serif);
  font-weight: 400;
  font-size: 24px;
  line-height: 1.3;
  letter-spacing: -0.015em;
  color: var(--ink-soft);
}
.placeholder-note .ital {
  font-style: italic;
  color: var(--accent);
}
@media (min-width: 768px) {
  .stack .placeholder-note { font-size: 26px; margin: 72px 24px; }
}
@media (min-width: 1024px) {
  .stack .placeholder-note { font-size: 30px; margin: 88px 32px; }
}

/* ---------- INVERTED CARD VARIANT ----------
   Used for the case-study Project Details card so it visually echoes
   the Our Process panel on index. Dark ink fill + cream type in light
   mode; auto-inverts to a cream panel with dark type in dark mode
   because both background and text colours are token-driven. */
.card.invert {
  background: var(--ink);
  color: var(--cream);
}
.card.invert .body-h { color: var(--cream); }
.card.invert .body-h .ital {
  /* Brighter vermilion (#FF3D00) reads at ~5:1 on the dark panel and
     ~5:1 on the cream panel - the only fixed colour we need here. */
  color: #FF3D00;
}
.card.invert .top-link { color: var(--cream); }
.card.invert .top-link .arrow { color: #FF3D00; }
.card.invert .top-link:hover { color: #FF3D00; }
.card.invert .specs dt { color: var(--accent-soft); }
.card.invert .specs dd { color: var(--cream); }
.card.invert .specs .spec.body dd { color: var(--accent-soft); }
/* AAA: the italic accent needs ≥7:1 - swap it to cream so it matches
   the rest of the heading at ~15:1, mirroring the Our Process pattern. */
/* .card.invert .body-h .ital no longer swapped in AAA: the bright
   #FF3D00 vermilion on ink clears AAA large at ~4.82:1. */

/* ---------- PROJECT SPECS GRID ---------- */
/* Used on case-study pages as a project-metadata card directly under the
   hero. Two-column stat-block grid for short fields (Client, Industry,
   Project time, Project delivery) with full-width rows for long-list
   fields (Location, Services, Expertise). Single column at mobile. */
.specs {
  display: grid;
  grid-template-columns: 1fr;
  column-gap: 28px;
  row-gap: 18px;
  margin: 0;
}
.specs .spec.full { grid-column: 1 / -1; }
.specs dt {
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--mute);
  margin: 0 0 6px;
}
.specs dd {
  font-family: var(--serif);
  font-style: italic;
  font-size: 21px;
  line-height: 1.35;
  color: var(--ink);
  margin: 0;
}
.specs .spec.body dd {
  font-family: var(--sans);
  font-style: normal;
  font-size: 16px;
  line-height: 1.55;
  color: var(--ink-soft);
}
@media (min-width: 768px) {
  .specs {
    grid-template-columns: repeat(2, 1fr);
    row-gap: 22px;
  }
}

/* Visually-hidden helper - text reachable by AT but not painted on screen.
   Used inside external links for the "(opens in new tab)" hint. */
.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;
}
@media (min-width: 768px) {
  .cover { padding: 56px 32px; }
  .cover:has(.cover-art) { padding-bottom: 32px; }
  .cover-h { font-size: 76px; letter-spacing: -0.035em; margin-bottom: 18px; }
  .cover-tag { font-size: 22px; margin-bottom: 36px; }
}

/* ===========================================================
   STACK + CARD - all pages
   =========================================================== */
.stack {
  background: var(--cream-tint);
  padding: 18px 0 9px;
}
.card {
  background: var(--cream);
  border-radius: var(--radius);
  overflow: hidden;
  padding: 28px 18px 24px;
  position: relative;
}

/* ---------- LEAD CARD VARIANT (Style E) ----------
   "An Introduction" lead card on case-study pages - same cream card
   chrome as the rest, but laid out as a two-column split: heading in a
   narrower left column, body running as a serif italic lede in the
   wider right column. Reads as a magazine pull-quote opener. Collapses
   to a single column at the smallest breakpoint. */
.card.lead {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
  align-items: start;
}
.card.lead .body-h { margin: 0; }
.card.lead .body-p {
  font-family: var(--serif);
  font-style: italic;
  font-size: 18px;
  line-height: 1.5;
}
@media (min-width: 768px) {
  .card.lead {
    grid-template-columns: 1fr 2fr;
    gap: 32px;
  }
  .card.lead .body-p { font-size: 20px; }
}
@media (min-width: 1024px) {
  .card.lead .body-p { font-size: 22px; }
}

/* Top-right anchor link, visible only when the card is hovered.
   Appears in the Recent Work and Design Services cards on index. */
.top-link {
  position: absolute;
  top: 28px;
  right: 18px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--mute);
  opacity: 0;
  transform: translateY(-2px);
  transition: opacity .25s ease, transform .25s ease, color .25s ease;
  pointer-events: none;
  z-index: 2;
}
.top-link .arrow {
  font-family: var(--serif);
  font-style: italic;
  font-size: 16px;
  color: var(--accent);
  line-height: 1;
  transition: transform .25s ease;
}
.top-link:hover .arrow { transform: translateY(-3px); }
.card:hover > .top-link,
.card:focus-within > .top-link {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.top-link:hover { color: var(--accent); }
/* Card spacing in the stack - every direct child of .stack gets a
   top margin separating it from the previous one. */
.stack > * + * { margin-top: 18px; }

@media (min-width: 768px) {
  .stack { padding: 24px 0 12px; }
  .card { padding: 32px 24px; }
  .stack > * + * { margin-top: 24px; }
  .top-link { top: 32px; right: 24px; font-size: 12px; }
}
@media (min-width: 1024px) {
  .stack { padding: 30px 0 15px; }
  .card { padding: 40px 32px 36px; }
  .stack > * + * { margin-top: 30px; }
  .top-link { top: 40px; right: 32px; }
}

/* ===========================================================
   SECTION HEADING - index.html
   =========================================================== */
.section-h {
  margin: 0 0 22px;
  font-family: var(--serif);
  font-weight: 400;
  font-size: 28px;
  line-height: 1.05;
  letter-spacing: -0.025em;
  color: var(--ink);
}
.section-h .ital {
  font-style: italic;
  color: var(--accent);
}
@media (min-width: 768px) {
  .section-h { font-size: 30px; margin-bottom: 28px; }
}
@media (min-width: 1024px) {
  .section-h { font-size: 36px; margin-bottom: 32px; letter-spacing: -0.03em; }
}

/* ===========================================================
   SERVICES - index.html
   =========================================================== */
.services-grid {
  border-top: 1.5px solid var(--rule);
}
.service {
  padding: 20px 0;
  border-bottom: 0.5px solid var(--rule);
}
.service:last-child { border-bottom: none; }
.service-no {
  margin: 0 0 12px;
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--accent);
  text-transform: uppercase;
}
.service h3 {
  margin: 0 0 8px;
  font-family: var(--serif);
  font-weight: 500;
  font-size: 22px;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--ink);
}
.service h3 em {
  font-style: italic;
}
/* :not(.service-no) so the generic body rule doesn't override the
   eyebrow paragraph (.service-no) - this is what lets .service-no
   keep its accent colour and tighter sizing without needing
   !important to fight back. */
.service p:not(.service-no) {
  margin: 0;
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-soft);
}
@media (min-width: 768px) {
  .services-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
  }
  .service {
    padding: 24px 18px 26px;
    border-bottom: none;
    border-right: 0.5px solid var(--rule);
  }
  .service:last-child { border-right: none; }
  .service:first-child { padding-left: 0; }
  .service:last-child { padding-right: 0; }
  .service-no { margin-bottom: 18px; font-size: 14px; color: var(--accent); }
  .service h3 { font-size: 22px; }
}
@media (min-width: 1024px) {
  .service { padding: 26px 22px 28px; }
  .service:first-child { padding-left: 0; }
  .service:last-child { padding-right: 0; }
  .service-no { margin-bottom: 22px; font-size: 14px; color: var(--accent); }
  .service h3 { font-size: 24px; margin-bottom: 10px; }
}

/* ===========================================================
   WORK LIST - index.html
   =========================================================== */
.work-list {
  border-top: 1.5px solid var(--rule);
}
.case {
  display: grid;
  grid-template-columns: 56px 1fr;
  gap: 14px;
  align-items: center;
  padding: 16px 14px;
  border-bottom: 0.5px solid var(--rule);
  cursor: pointer;
  transition: background .25s ease, color .25s ease;
}
.case:hover,
.case:focus-visible {
  background: var(--accent);
  color: var(--cream-fixed);
}
.case:hover .logo,
.case:focus-visible .logo {
  background: var(--cream);
}
.case:hover .logo .case-mark,
.case:focus-visible .logo .case-mark {
  color: var(--accent);
}
.case:hover .case-meta,
.case:focus-visible .case-meta {
  color: var(--cream-fixed);
  opacity: 0.85;
}
.case:hover h3,
.case:focus-visible h3 {
  color: var(--cream-fixed);
}
.logo {
  width: 52px;
  height: 52px;
  background: var(--cream-tint);
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
  transition: background .25s ease;
}
/* Brand mark sits inside .logo - SVG inherits color via currentColor so it
   swaps from ink → accent on hover/focus alongside the case background.
   Raster (img) marks keep their own colours via object-fit. */
.logo .case-mark {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  padding: 8%;
  box-sizing: border-box;
  color: var(--ink);
  object-fit: contain;
  transition: color .25s ease;
}
/* When the mark is a raster logo, give the logo container a clean white
   background so the file's own white surround reads as intentional. A
   1 px hairline frames each logo and reads against both the cream-tint
   card and the vermilion hover background. */
.logo.has-logo-img {
  background: #FFFFFF;
  border: 1px solid var(--rule);
  box-sizing: border-box;
}
.case:hover .logo.has-logo-img,
.case:focus-visible .logo.has-logo-img { background: #FFFFFF; }
.case-body h3 {
  margin: 0;
  font-family: var(--serif);
  font-weight: 500;
  font-size: 24px;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--ink);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
.case-body h3 .arrow {
  font-family: var(--serif);
  font-style: italic;
  font-size: 19px;
  flex-shrink: 0;
  transition: transform .25s ease;
}
.case:hover .case-body h3 .arrow,
.case:focus-visible .case-body h3 .arrow { transform: translateX(4px); }
/* Hide the separate end-arrow at mobile so it doesn't drop to a new row */
.case-arrow { display: none; }
.case-meta {
  margin: 4px 0 0;
  font-family: var(--sans);
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--mute);
}

@media (min-width: 768px) {
  .case {
    grid-template-columns: 72px 1fr 60px;
    gap: 20px;
    padding: 20px 20px;
  }
  .logo { width: 68px; height: 68px; }
  .case-body h3 { font-size: 28px; display: block; }
  .case-body h3 .arrow { display: none; }
  .case-meta { font-size: 12px; }
  .case-arrow {
    display: block;
    justify-self: end;
    font-family: var(--serif);
    font-style: italic;
    font-size: 24px;
    color: var(--ink);
    transition: color .25s ease, transform .25s ease;
  }
  .case:hover .case-arrow,
  .case:focus-visible .case-arrow { color: var(--cream-fixed); transform: translateX(4px); }
}
@media (min-width: 1024px) {
  .case {
    grid-template-columns: 88px 1fr 60px;
    gap: 24px;
    padding: 22px 24px;
  }
  .logo { width: 80px; height: 80px; border-radius: 6px; }
  .case-body h3 { font-size: 34px; letter-spacing: -0.03em; }
  .case-meta { font-size: 12px; margin-top: 6px; }
  .case-arrow { font-size: 26px; }
}

/* ===========================================================
   RECOVER LIST - 404.html
   Stacked list of recovery links shown on the 404 page. Each row
   uses the same hairline + arrow pattern as the case list, but
   stripped of the logo column.
   =========================================================== */
.recover-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1.5px solid var(--rule);
}
.recover-list li {
  border-bottom: 0.5px solid var(--rule);
}
.recover-list a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 14px;
  font-family: var(--serif);
  font-weight: 500;
  font-size: 20px;
  letter-spacing: -0.015em;
  color: var(--ink);
  text-decoration: none;
  transition: background .25s ease, color .25s ease, padding .25s ease;
}
.recover-list a:hover,
.recover-list a:focus-visible {
  background: var(--accent);
  color: var(--cream-fixed);
}
.recover-list .arrow {
  font-family: var(--serif);
  font-style: italic;
  font-size: 18px;
  flex-shrink: 0;
  transition: transform .25s ease;
}
.recover-list a:hover .arrow,
.recover-list a:focus-visible .arrow { transform: translateX(4px); }
@media (min-width: 768px) {
  .recover-list a { padding: 18px 20px; font-size: 24px; }
  .recover-list .arrow { font-size: 22px; }
}
@media (min-width: 1024px) {
  .recover-list a { padding: 20px 24px; font-size: 28px; }
}

/* ===========================================================
   CONTACT FORM - contact.html
   =========================================================== */
.contact-form { margin: 0; }
.contact-row { margin: 0 0 18px; }
.contact-row:last-child { margin-bottom: 0; }
.contact-label {
  display: block;
  margin: 0 0 6px;
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--mute);
}
.contact-input {
  width: 100%;
  padding: 10px 12px;
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.5;
  color: var(--ink);
  background: var(--cream-tint);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  transition: border-color .2s ease, background .2s ease;
  -webkit-appearance: none;
  appearance: none;
}
.contact-input:hover { border-color: var(--mute); }
.contact-input:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--cream);
}
textarea.contact-input {
  min-height: 140px;
  resize: vertical;
  font-family: var(--sans);
}
.contact-actions {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
  margin-top: 26px;
}
.contact-submit {
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 11px 22px;
  border: 1px solid var(--ink);
  border-radius: 999px;
  background: var(--ink);
  color: var(--cream);
  cursor: pointer;
  transition: background .25s ease, color .25s ease, border-color .25s ease;
}
.contact-submit:hover { background: var(--accent); border-color: var(--accent); }
.contact-submit:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.contact-note {
  margin: 0;
  font-family: var(--sans);
  font-size: 12px;
  line-height: 1.5;
  color: var(--mute);
  max-width: 280px;
}
.contact-honeypot {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}
/* Required-field indicator (WCAG 3.3.2 Labels or Instructions).
   The asterisk is decorative (aria-hidden) - the required state is
   communicated to assistive tech via the input's `required` attribute,
   and to sighted users via the visible "*" and the form-level note. */
.contact-required-note {
  margin: 0 0 22px;
  font-family: var(--sans);
  font-size: 12px;
  line-height: 1.5;
  color: var(--mute);
}
.contact-required-note .contact-asterisk { margin: 0 2px; }
.contact-asterisk {
  color: var(--accent);
  font-weight: 600;
  /* Sits inside .card (--cream background) where #C73100 clears AA 4.7:1. */
}
@media (min-width: 768px) {
  .contact-input { font-size: 16px; padding: 11px 14px; }
  .contact-actions { gap: 24px; }
}

/* ===========================================================
   CLIENT LOGO GRID - index.html "Our Clients" card
   =========================================================== */
.client-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.client-logo {
  margin: 0;
  background: var(--cream-tint);
  border-radius: 4px;
  aspect-ratio: 5 / 3;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--mute);
  text-align: center;
  padding: 8px;
  line-height: 1.3;
}
@media (min-width: 768px) {
  .client-grid { grid-template-columns: repeat(4, 1fr); gap: 14px; }
}
@media (min-width: 1024px) {
  .client-grid { gap: 16px; }
  .client-logo { font-size: 12px; }
}

/* ===========================================================
   APPROACH - index.html (process inset, nested in Services card)
   Single-column vertical flow with a leading vermilion arrow.
   =========================================================== */
.approach {
  background: var(--ink);
  color: var(--cream);
  padding: 28px 22px 26px;
  border-radius: var(--radius);
  margin-top: 22px;
}
.approach .section-h {
  color: var(--cream);
  font-size: 24px;
  margin-bottom: 20px;
}

.steps {
  position: relative;
  display: block;
  list-style: none;
  margin: 0;
  padding: 0;
}
/* Vermilion ribbon - fades in at the top and out at the bottom.
   Centred in the channel so the gap to numerals equals the gap to text. */
.steps::before {
  content: "";
  position: absolute;
  left: 50px;
  top: 0;
  bottom: 0;
  width: 6px;
  border-radius: 3px;
  background: linear-gradient(
    to bottom,
    transparent 0%,
    var(--accent) 30%,
    var(--accent) 70%,
    transparent 100%
  );
}
.step {
  display: grid;
  grid-template-columns: 40px 1fr;
  grid-template-areas:
    "num head"
    "num body";
  column-gap: 30px;
  align-items: baseline;
  padding: 8px 0 16px;
}
.step:last-child { padding-bottom: 24px; }
.step-no {
  grid-area: num;
  align-self: baseline;
  text-align: right;
  padding-right: 4px;
  margin: 0;
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: 22px;
  color: var(--cream);
  line-height: 1;
}
.step h4 {
  grid-area: head;
  margin: 0 0 6px;
  font-family: var(--serif);
  font-size: 17px;
  font-weight: 500;
  color: var(--cream);
  letter-spacing: -0.01em;
}
.step p:not(.step-no) {
  grid-area: body;
  margin: 0;
  font-family: var(--sans);
  font-size: 13px;
  line-height: 1.55;
  color: var(--accent-soft);
  max-width: 460px;
}
@media (min-width: 768px) {
  .approach { padding: 36px 28px 32px; margin-top: 26px; }
  .approach .section-h { font-size: 26px; margin-bottom: 24px; }
  .steps::before { left: 63px; }
  .step { grid-template-columns: 52px 1fr; column-gap: 32px; padding: 10px 0 20px; }
  .step-no { font-size: 22px; }
  .step h4 { font-size: 18px; }
  .step p:not(.step-no) { font-size: 13px; }
}
@media (min-width: 1024px) {
  .approach { padding: 44px 36px 40px; margin-top: 32px; }
  .approach .section-h { font-size: 30px; margin-bottom: 28px; }
  .step { padding-bottom: 24px; }
  .step-no { font-size: 24px; }
  .step h4 { font-size: 19px; margin-bottom: 8px; }
  .step p:not(.step-no) { font-size: 13.5px; line-height: 1.6; }
}

/* ===========================================================
   BODY TYPE - about.html and case-study pages
   =========================================================== */
.body-h {
  margin: 0 0 18px;
  font-family: var(--serif);
  font-weight: 400;
  font-size: 24px;
  line-height: 1.1;
  letter-spacing: -0.025em;
  color: var(--ink);
}
.body-h .ital { font-style: italic; color: var(--accent); }
.body-p {
  margin: 0 0 14px;
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink-soft);
}
.body-p:last-child { margin-bottom: 0; }
.body-p strong { font-weight: 600; color: var(--ink); }
@media (min-width: 768px) {
  .body-h { font-size: 28px; margin-bottom: 24px; }
  .body-p { font-size: 16px; margin-bottom: 16px; }
}

/* ===========================================================
   CLIENTS LIST - about.html
   =========================================================== */
.clients-list {
  list-style: none;
  margin: 0;
  padding: 0;
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.7;
  color: var(--ink-soft);
}
.clients-list li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 4px 0;
  border-bottom: 0.5px solid var(--rule);
}
.clients-sector {
  flex-shrink: 0;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--mute);
}
@media (min-width: 768px) {
  .clients-list {
    column-count: 2;
    column-gap: 32px;
    font-size: 15px;
  }
  .clients-list li { break-inside: avoid; }
  .clients-sector { font-size: 11px; letter-spacing: 0.16em; }
}

/* ===========================================================
   QUOTE - case-study pages
   =========================================================== */
.quote {
  padding: 36px 18px 32px;
  max-width: 520px;
  margin: 0 auto;
}
.quote-mark {
  display: block;
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: 60px;
  line-height: 0.6;
  color: var(--accent);
  margin-bottom: 16px;
}
.quote-text {
  margin: 0 0 18px;
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: 24px;
  line-height: 1.35;
  color: var(--ink);
  letter-spacing: -0.01em;
}
.quote-attr {
  margin: 0;
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--mute);
  font-weight: 600;
}
.quote-attr .slash {
  /* The quote block sits in the .stack on --cream-tint, so the small
     accent slash uses the stronger variant for AA contrast. */
  color: var(--accent-strong);
  margin-right: 6px;
}
@media (min-width: 768px) {
  .quote { padding: 52px 24px 48px; }
  .quote-mark { font-size: 80px; }
  .quote-text { font-size: 28px; margin-bottom: 22px; letter-spacing: -0.015em; }
  .quote-attr { font-size: 11px; letter-spacing: 0.16em; }
}

/* ===========================================================
   NEXT CASE STUDY - case-study pages
   =========================================================== */
.next-link {
  display: grid;
  grid-template-columns: 50px 1fr 40px;
  gap: 16px;
  align-items: center;
  padding: 22px 18px;
  background: var(--cream);
  border-radius: var(--radius);
  cursor: pointer;
  transition: background .25s ease, color .25s ease;
}
.next-link:hover { background: var(--accent); color: var(--cream-fixed); }
.next-link:hover .next-meta { color: var(--cream-fixed); opacity: 0.85; }
.next-link:hover .next-title { color: var(--cream-fixed); }
.next-link:hover .next-arrow { color: var(--cream-fixed); transform: translateX(4px); }
.next-meta {
  margin: 0;
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--mute);
  transition: color .25s ease;
}
.next-title {
  margin: 0;
  font-family: var(--serif);
  font-weight: 500;
  font-size: 26px;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--ink);
  transition: color .25s ease;
}
.next-arrow {
  justify-self: end;
  font-family: var(--serif);
  font-style: italic;
  font-size: 24px;
  color: var(--accent);
  transition: color .25s ease, transform .25s ease;
}
@media (min-width: 768px) {
  .next-link {
    grid-template-columns: 60px 1fr 60px;
    gap: 20px;
    padding: 28px 24px;
  }
  .next-meta { font-size: 11px; letter-spacing: 0.16em; }
  .next-title { font-size: 28px; }
  .next-arrow { font-size: 26px; }
}

/* ===========================================================
   FOOTER - all pages
   =========================================================== */
.foot {
  background: var(--cream-tint);
  padding: 24px 18px 18px;
  color: var(--ink);
}
.foot-grid {
  padding-bottom: 14px;
  border-bottom: 0.5px solid var(--rule);
}
.foot-brand {
  margin: 0;
  font-family: var(--serif);
  font-size: 18px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--ink);
}
.foot-brand i {
  font-style: italic;
  /* Footer sits on --cream-tint, where the default --accent (#C73100)
     falls just short of AA 4.5:1. Swap to the stronger variant. */
  color: var(--accent-strong);
  transition: color .25s ease;
}
.foot-brand a {
  display: inline;
  margin: 0;
  font: inherit;
  letter-spacing: inherit;
  color: inherit;
  text-decoration: none;
  transition: color .25s ease;
}
.foot-brand a:hover { color: var(--accent-strong); }
.foot-tag {
  margin: 8px 0 0;
  font-family: var(--sans);
  font-size: 13px;
  color: var(--mute);
  line-height: 1.5;
}
.foot-col > a {
  display: flex;
  /* Top-align so each link's text baseline matches the first column's
     strapline (which starts at the top of its own line), rather than
     centring in the 24px target-size box and appearing to sit lower. */
  align-items: flex-start;
  justify-content: flex-end;
  gap: 8px;
  margin: 0;
  font-family: var(--sans);
  font-size: 13px;
  line-height: 1.55;
  color: var(--mute);
  transition: color .2s ease;
}
/* Inline footer nav - the second .foot-col is the links column; lay it
   out as a flex row so About / Contact / LinkedIn sit side-by-side, with
   thin vertical bars between them acting as "|" separators. */
.foot-col + .foot-col {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  row-gap: 4px;
}
/* At the smallest breakpoint the footer collapses to a single column,
   so the link column also left-aligns flush with the brand+strap above.
   Pipe separators are hidden and the desktop baseline-shift hack reset. */
@media (max-width: 767px) {
  .foot-col + .foot-col {
    flex-direction: column;
    align-items: flex-start;
    row-gap: 6px;
    /* Breathing room between the strapline above and the link list below
       now that the two columns stack vertically. */
    margin-top: 20px;
  }
  html:not(.wcag-aaa) .foot-col > a,
  html.wcag-aaa .foot-col > a {
    margin-top: 0;
  }
  /* The anchor itself is flex with justify-content: flex-end on desktop -
     reset to flex-start at mobile so the text-and-arrow run hugs the left
     edge rather than the right. */
  .foot-col > a {
    justify-content: flex-start;
  }
  /* Specificity-match both the A/AA and AAA scoped rules so the 22px
     pipe-gutter doesn't survive at mobile in either branch. */
  html:not(.wcag-aaa) .foot-col > a + a,
  html.wcag-aaa .foot-col > a + a {
    padding-left: 0;
  }
  /* AAA anchors carry padding: 10px 8px for the 44x44 tap area on
     desktop. At mobile with the column left-aligned, that 8px left pad
     visually indents the first link from the strap above - reset it.
     min-width keeps the shortest link ("About" ~33px text + 8px right
     pad = ~41px) at the 44px minimum required by 2.5.5 Target Size
     (Enhanced) once the left padding is gone. */
  html.wcag-aaa .foot-col > a {
    padding-left: 0;
    min-width: 44px;
  }
  /* Extra breathing room between strap and links in AAA mode - the
     larger 44px tap targets need a clearer gap from the body copy
     above to keep the hierarchy legible. */
  html.wcag-aaa .foot-col + .foot-col {
    margin-top: 32px;
  }
  .foot-col > a + a::before {
    display: none;
  }
}
.foot-col > a + a {
  position: relative;
  padding-left: 22px;
}
/* Decorative pipe - empty pseudo-element styled as a 1×12px vertical bar.
   No text content, so screen readers don't announce a "pipe" between
   each link. Pinned near the top of the anchor so it visually centres
   on the first text-line whether the anchor is 24px (default) or 44px
   (AAA target-size mode). */
.foot-col > a + a::before {
  content: "";
  position: absolute;
  left: 10px;
  top: 4px;
  width: 1px;
  height: 12px;
  background: var(--mute);
}
/* Current page link in the footer nav - slightly muted + non-interactive
   cue so the user can see where they are. aria-current="page" carries
   the AT semantics; this is the matching visual treatment. */
.foot-col > a[aria-current="page"] {
  color: var(--ink);
  cursor: default;
}
.foot-col > a[aria-current="page"]:hover { color: var(--ink); }
/* Only external links get the up-right arrow glyph. */
.foot-col > a[target="_blank"]::after {
  content: "\2197"; /* ↗ */
  font-size: 14px;
  line-height: 1;
  color: var(--mute);
  transition: transform .25s ease, color .25s ease;
}
.foot-col > a:hover { color: var(--accent-strong); }
.foot-col > a[target="_blank"]:hover::after { color: var(--accent-strong); transform: translate(2px, -2px); }
.foot-bottom {
  padding-top: 14px;
  font-family: var(--sans);
  font-size: 11px;
  color: var(--mute);
  line-height: 1.5;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
}
.foot-bottom .sep { display: none; }
.foot-copy { margin: 0; }

/* ---------- Theme toggle - text link ---------- */
.theme-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink);
  white-space: nowrap;
  flex-shrink: 0;
  transition: color .2s ease;
}
/* Visible-text label spans - two are present in markup; CSS toggles
   which is displayed. Real text in the DOM means the input's
   accessible name always matches what's on screen (2.5.3). */
.theme-link-text[data-state="light"] { display: none; }
body:has(.theme-toggle:checked) .theme-link-text[data-state="dark"] { display: none; }
body:has(.theme-toggle:checked) .theme-link-text[data-state="light"] { display: inline; }
html.theme-dark .theme-link-text[data-state="dark"] { display: none; }
html.theme-dark .theme-link-text[data-state="light"] { display: inline; }
.theme-link:hover { color: var(--accent-strong); }
.theme-toggle {
  position: absolute;
  inset: 0;
  opacity: 0;
  width: 1px;
  height: 1px;
  margin: 0;
  pointer-events: none;
}

@media (min-width: 768px) {
  .foot { padding: 32px 24px 22px; }
  .foot-grid {
    display: grid;
    /* Right column sizes to its links rather than a fixed 1fr share -
       in AAA mode each anchor gains 16px of horizontal padding for the
       44×44 tap area, which would otherwise force the row to wrap. */
    grid-template-columns: 1fr auto;
    gap: 28px;
    padding-bottom: 18px;
  }
  .foot-tag { max-width: 360px; line-height: 1.55; }
  .foot-bottom { padding-top: 18px; font-size: 11px; }
  .foot-bottom br { display: none; }
  .foot-bottom .sep { display: inline; padding: 0 6px; }
  .theme-link { font-size: 11px; }
  .foot-brand { font-size: 19px; }
  /* Right column top-padded so its first link aligns vertically with
     the start of the foot-tag in the left column. The extra +1px on
     each breakpoint accounts for the small font-metric gap between
     the serif brand line and the sans tag line in column 1. */
  .foot-col + .foot-col { padding-top: 28px; }
}
@media (min-width: 1024px) {
  .foot { padding: 36px 32px 24px; }
  .foot-grid { padding-bottom: 20px; }
  .foot-bottom { padding-top: 20px; }
  .foot-brand { font-size: 22px; }
  .foot-col + .foot-col { padding-top: 31px; }
}

