/* ═══════════════════════════════════════════════════════════════════════
   DOHENY ATELIER — SITE STYLESHEET
   One stylesheet for every page. Organized by scope, then by page:

     1. FONTS & DESIGN TOKENS ..... @font-face, brand colors, type variables
     2. BASE & UTILITIES .......... reset, body fade-in, .visually-hidden,
                                    image loading skeleton
     3. SHARED COMPONENTS ......... nav + mobile menu, footer, back-to-top,
                                    overlay scrollbar, cursor pill,
                                    client-logo marquee, work cards
     4. HOME (index.html) ......... splash, hero slideshow, tagline, services
     5. WORK LISTING (/work/) ..... project grid
     6. CASE STUDIES (/work/casestudy/<slug>/) — header, hero stack, Learn More
                                    panel, deliverables, More Work grid
     7. ABOUT (/about/) ........... hero, collage, founder, expertise, FAQ
     8. Q&A (/katedohenyqa/) ...... intro, pull quote, body
     9. COMING SOON (/comingsoon/)
    10. MOBILE ≤768px ............. every page's phone layout, one block,
                                    ordered to match the sections above

   Conventions: colors/fonts only via the :root variables in section 1.
   Desktop sizes use clamp(min, vw, max) so type/spacing stay fluid but
   bounded; the mobile block uses a raw-vw proportional ladder (see the
   notes there). Add new desktop rules with clamp(), and always add the
   matching rule to the mobile block in the same change.
   ═══════════════════════════════════════════════════════════════════════ */


/* ══════════════════════════════════════════════════════════════════════════
   1. FONTS & DESIGN TOKENS
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Fonts ─────────────────────────────────────────────── */
@font-face {
  font-family: 'Caslon540LTStd';
  src: url('fonts/Caslon540LTStd-Roman.otf') format('opentype');
  font-display: swap;   /* show fallback text immediately, swap in when loaded */
  font-weight: normal;
  font-style: normal;
}
@font-face {
  font-family: 'Caslon540LTStd';
  src: url('fonts/Caslon540LTStd-Italic.otf') format('opentype');
  font-display: swap;   /* show fallback text immediately, swap in when loaded */
  font-weight: normal;
  font-style: italic;
}
@font-face {
  font-family: 'EngraversGothicBT';
  src: url('fonts/Engravers Gothic BT.ttf') format('truetype');
  font-display: swap;   /* show fallback text immediately, swap in when loaded */
  font-weight: normal;
  font-style: normal;
}

/* ── Tokens ────────────────────────────────────────────── */
:root {
  --white:    #FFFFFF;
  --ecru:     #F5F3EF;
  --beige:    #CCC6BA;
  --graphite: #292929;

  /* RGB channel-lists mirroring the hex tokens above, for use in rgba() so that
     translucent colours (glass nav, hairline borders, shadows) invert with the
     theme instead of staying hardcoded. Keep these in sync with the hex vars. */
  --white-rgb:    255, 255, 255;
  --ecru-rgb:     245, 243, 239;
  --beige-rgb:    204, 198, 186;
  --graphite-rgb: 41, 41, 41;

  /* Logo recolour amounts for the brightness(0) invert() trick used on every
     transparent-PNG logo. In light mode logos read graphite; the dark-mode
     block below lifts them to ecru. */
  --logo-ink: 0.161;   /* invert() amount → graphite */

  --font-heading:   'aviano-didone', serif;
  --font-body:      'Caslon540LTStd', serif;
  --font-caps:      'EngraversGothicBT', sans-serif;

  --ls-heading:     0em;
  --ls-body:        -0.035em;
  --ls-caps:        0.2em;

  --lh-heading:     1;
  --lh-body:        1.45;
  --lh-caps:        1.9;
}

/* ── Dark mode ─────────────────────────────────────────────
   A manual, button-driven theme (js/theme.js sets data-theme on <html> and
   persists it to localStorage; an inline snippet in each page's <head> applies
   it before first paint to avoid a flash). Because nearly all colours route
   through the tokens above, dark mode is a token remap into an elevation scale
   anchored on graphite:
     • ecru  → graphite  (#292929)  — the default page surface
     • beige → #1B1917 — collapses onto the same recessed surface as white
     • white → #1B1917 — one step DARKER than graphite (Featured Works)
     • graphite (the ink) → light ecru so text/marks flip to light
   Photographs are never touched; only UI colours and the transparent-PNG
   logos invert. */
html[data-theme="dark"] {
  --white:    #1B1917;   /* recessed: darker than graphite */
  --ecru:     #292929;   /* default surface: graphite */
  --beige:    #1B1917;   /* collapses onto the same recessed surface as white */
  --graphite: #F5F3EF;   /* ink flips to light */

  --white-rgb:    27, 25, 23;
  --ecru-rgb:     41, 41, 41;
  --beige-rgb:    27, 25, 23;
  --graphite-rgb: 245, 243, 239;

  --logo-ink: 0.955;   /* invert() amount → ecru */
}

/* Smooth cross-fade when the theme flips. Scoped to colour properties so we
   don't animate layout, and disabled for reduced-motion users. (body handles
   its own transition — see the body rule — because it already animates opacity
   for the page fade-in and `transition` is not additive.) */
.nav, .mobile-menu, .works, .footer, .cursor-label-inner,
.cs-viewmore-btn, .service-item, .faq-item, .expertise-rule,
.nav-logo-img, .marquee-logo img, .footer-icon, .footer-social-link img {
  transition: background-color 0.5s ease, color 0.5s ease,
              border-color 0.5s ease, filter 0.5s ease;
}
@media (prefers-reduced-motion: reduce) {
  .nav, .mobile-menu, .works, .footer, .cursor-label-inner,
  .cs-viewmore-btn, .service-item, .faq-item, .expertise-rule,
  .nav-logo-img, .marquee-logo img, .footer-icon, .footer-social-link img {
    transition: none;
  }
}


/* ══════════════════════════════════════════════════════════════════════════
   2. BASE & UTILITIES
   Element reset, page fade-in (body.is-loaded, driven by js/transitions.js),
   screen-reader-only headings, and the beige pulse shown while images load.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Reset ─────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* NOTE: no `scroll-behavior: smooth` here — Lenis provides the smooth
   scrolling; the CSS version would double-animate programmatic scrolls
   (splash reset, back-to-top fallback) and fight Lenis. */
body {
  background-color: var(--ecru);
  color: var(--graphite);
  font-family: var(--font-body);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  opacity: 0;
  transition: opacity 0.4s ease,
              background-color 0.5s ease, color 0.5s ease;
}

/* Selection highlight inverts: the highlight takes the text colour and the
   text takes the background colour. `currentColor` can't be used here — inside
   ::selection it resolves to the pseudo's own `color`, not the element's — so
   the two themes are set explicitly. Default = dark text on light ground; the
   footer (dark ground, light text) flips it. */
::selection {
  background-color: var(--graphite);
  color: var(--ecru);
}
.footer ::selection {
  background-color: var(--ecru);
  color: var(--graphite);
}

body.is-loaded {
  opacity: 1;
}

/* Arrived from a mobile-menu tap: the menu panel is still covering the
   viewport and about to wipe up (see .mobile-menu in the mobile block), so
   this page has to be fully painted behind it — the entry fade would
   otherwise be caught mid-way as the panel lifts. */
html.menu-wipe-in body {
  opacity: 1;
  transition: none;
}
a { color: inherit; text-decoration: none; }
img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* ── A11y / SEO utility ────────────────────────────────── */
/* Visually hidden but exposed to screen readers & crawlers.
   Used for SEO headings on image-led pages — no visual effect. */
.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ── Image skeleton loading ─────────────────────────────── */
.img-loading {
  position: relative;
}
.img-loading img {
  color: transparent;
}
.img-loading::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--beige);
  animation: skeleton-pulse 1.8s ease-in-out infinite;
  pointer-events: none;
  z-index: 1;
}
@keyframes skeleton-pulse {
  0%, 100% { opacity: 0.5; }
  50%       { opacity: 1; }
}


/* ══════════════════════════════════════════════════════════════════════════
   3. SHARED COMPONENTS — used on every page (or several)
   Nav + mobile menu, footer, back-to-top donut, overlay scrollbar, the
   "View case study" cursor pill, the client-logo marquee (home + about),
   and the work-card styles shared by home / work listing / case studies.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Nav ───────────────────────────────────────────────── */
.nav {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  align-items: center;
  justify-items: center;
  padding: clamp(12px, 1.6vw, 20px) clamp(24px, 3.2vw, 40px);
  background: rgba(var(--ecru-rgb), 0.7);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
}

.nav-link {
  font-family: var(--font-caps);
  font-size: clamp(12px, 0.9vw, 14px);
  letter-spacing: var(--ls-caps);
  line-height: var(--lh-caps);
  text-transform: uppercase;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--graphite);
  position: relative;
  padding-bottom: 2px;
}

.nav-link::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 1px;
  background: var(--graphite);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s ease;
}

.nav-link:hover::after,
.nav-link.is-active::after {
  transform: scaleX(1);
}


.nav-logo {
  display: flex;
  justify-content: center;
  align-items: center;
}

.nav-logo-img {
  height: 36px;
  width: auto;
  object-fit: contain;
  display: block;
}

/* ── Mobile Menu (hidden on desktop) ───────────────────── */
.nav-hamburger {
  display: none;
}

.mobile-menu {
  display: none;
}

/* ── Footer ────────────────────────────────────────────── */
.footer {
  background: var(--graphite);
  padding: clamp(48px, 6.4vw, 80px) clamp(24px, 3.2vw, 40px) clamp(24px, 3.2vw, 40px);
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto auto;
  gap: 0;
  position: relative;
}

.footer-left {
  display: flex;
  align-items: flex-start;
}
.footer-icon {
  width: 170px;
  height: auto;
  object-fit: contain;
  opacity: 0.88;
}

.footer-right {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
}
.footer-headline {
  font-family: var(--font-body);
  font-size: clamp(32px, 3vw, 48px);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--ecru);
}
.footer-sub {
  font-family: var(--font-body);
  font-size: clamp(32px, 3vw, 48px);
  font-style: italic;
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--ecru);
  margin-bottom: clamp(12px, 1.28vw, 16px);
}
.footer-email {
  font-family: var(--font-body);
  font-size: clamp(13px, 1.2vw, 19px);
  line-height: var(--lh-body);
  color: var(--ecru);
  text-decoration: none;
  position: relative;
  padding-bottom: 2px;
  margin-bottom: clamp(14px, 1.92vw, 24px);
}
.footer-email::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 1px;
  background: var(--ecru);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s ease;
}
.footer-email:hover::after {
  transform: scaleX(1);
}
.footer-social {
  display: flex;
  gap: 12px;
  align-items: center;
}

.footer-social-link {
  display: flex;
  opacity: 0.7;
  transition: opacity 0.2s ease;
}

.footer-social-link:hover {
  opacity: 1;
}

.footer-social-link img {
  width: 18px;
  height: 18px;
  object-fit: contain;
}

.footer-copy {
  grid-column: 1 / -1;
  text-align: center;
  padding-top: clamp(36px, 4.8vw, 60px);
  font-family: var(--font-caps);
  font-size: clamp(9px, 0.65vw, 10px);
  letter-spacing: var(--ls-caps);
  line-height: var(--lh-caps);
  text-transform: uppercase;
  color: var(--ecru);
  opacity: 0.6;
}

/* ── Scroll-to-top progress button ─────────────────────────────────────────
   Pure-CSS progress indicator: a thin beige DONUT ring whose graphite fill
   sweeps clockwise from the top as the page scrolls, with a graphite arrow in
   the (transparent) centre hole. The fill is a scroll-driven animation (no JS
   drives it) — --cs-totop-fill is animated 0%→100% against the document's
   scroll timeline and used as the conic-gradient sweep on .cs-totop::before.
   Only the fade/roll-in is JS (casestudy.js adds .is-visible once you've
   scrolled a screenful, since Lenis suppresses native scroll events). No-ops on
   pages without the markup. Technique adapted from matuzo.at, restyled in DA
   brand tokens. */
@property --cs-totop-fill {
  syntax: '<length-percentage>';
  inherits: false;
  initial-value: 0%;
}


.cs-totop {
  position: fixed;
  inset: auto 2rem 2rem auto;
  z-index: 900;

  display: grid;
  place-items: center;
  width: 3.25rem;
  height: 3.25rem;

  --totop-track: transparent;          /* ring: unfilled track (invisible) */
  --totop-fill:  var(--graphite);      /* ring: scroll-progress fill */
  color: var(--graphite);              /* arrow colour */
  border-radius: 50%;
  background: none;                    /* the middle hole is transparent */

  /* Hidden until scrolled; casestudy.js adds .is-visible. It rolls in from the
     right — parked fully off-screen, then travels in with a full spin. No fade;
     the motion alone reveals it. */
  visibility: hidden;
  transform: translateX(6rem) rotate(-360deg);
  transition: transform 0.9s cubic-bezier(0.22, 1, 0.36, 1), visibility 0.9s;
  cursor: pointer;
}

/* Over a dark section (e.g. the footer): render the ink white and blend it with
   the backdrop using `difference`. Wherever the button overlaps graphite it
   reads light (ecru-ish); wherever it still overlaps the light page it reads
   dark (graphite-ish) — the split follows the exact boundary as you scroll past
   it. Scoped to dark sections (casestudy.js toggles .on-dark) so it never
   inverts over the page's images. */
.cs-totop.on-dark {
  --totop-fill: #fff;
  color: #fff;
  mix-blend-mode: difference;
}

/* Donut ring: a thin beige track with a graphite progress fill that sweeps
   CLOCKWISE from the top (top → right → bottom → left) as the page scrolls.
   The centre is masked out, so the arrow shows through with no background. */
.cs-totop::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  --ring: 4px;                         /* ring thickness (relatively thin) */
  background: conic-gradient(from 0deg,
    var(--totop-fill) 0% var(--cs-totop-fill),
    var(--totop-track) var(--cs-totop-fill));
  /* Cut out the middle to leave a ring of --ring thickness. */
  -webkit-mask: radial-gradient(farthest-side, #0000 calc(100% - var(--ring)), #000 calc(100% - var(--ring)));
          mask: radial-gradient(farthest-side, #0000 calc(100% - var(--ring)), #000 calc(100% - var(--ring)));
  /* Scroll-driven fill — duration is ignored on a scroll timeline. */
  animation: cs-totop-progress linear;
  animation-timeline: scroll(root);
}

.cs-totop.is-visible {
  visibility: visible;
  transform: translateX(0) rotate(0deg);
}

.cs-totop.is-visible:hover {
  transform: translateY(-3px);
}

.cs-totop svg {
  display: block;
  width: 1.35rem;
  height: 1.35rem;
  stroke-width: 1.4px;                 /* thin arrow */
}

/* Accessible label, visually hidden (screen readers still announce it). */
.cs-totop span {
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  height: 1px;
  width: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap;
}

@keyframes cs-totop-progress {
  0%   { --cs-totop-fill: 0%; }
  100% { --cs-totop-fill: 100%; }
}

/* ── Theme toggle (sticky, every page) ─────────────────────
   Injected into every page by js/theme.js. Fixed bottom-left so it clears the
   bottom-right back-to-top control. Glass pill in brand colours that itself
   inverts with the theme; shows a sun in dark mode (tap → go light) and a moon
   in light mode (tap → go dark). */
.theme-toggle {
  position: fixed;
  left: 2rem;
  bottom: 2rem;
  z-index: 901;
  width: 3.25rem;
  height: 3.25rem;
  display: grid;
  place-items: center;
  padding: 0;
  border-radius: 50%;
  border: 1px solid rgba(var(--graphite-rgb), 0.28);
  background: rgba(var(--ecru-rgb), 0.7);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  color: var(--graphite);
  cursor: pointer;
  transition: background-color 0.5s ease, color 0.5s ease,
              border-color 0.5s ease, transform 0.3s ease;
}
.theme-toggle:hover { transform: scale(1.06); }
.theme-toggle svg {
  display: block;
  width: 1.25rem;
  height: 1.25rem;
  stroke-width: 1.4px;
}
/* Show the moon in light mode, the sun in dark mode. */
.theme-toggle .theme-toggle-sun  { display: none; }
html[data-theme="dark"] .theme-toggle .theme-toggle-moon { display: none; }
html[data-theme="dark"] .theme-toggle .theme-toggle-sun  { display: block; }

/* No scroll-driven-animation support (e.g. Safari): the ring stays a static
   beige donut (0% fill) — the scroll-to-top link still works everywhere. */

@media (prefers-reduced-motion: reduce) {
  .cs-totop,
  .cs-totop.is-visible,
  .cs-totop.is-visible:hover {
    transform: none;
    transition: visibility 0.2s;
  }
}

@media (max-width: 768px) {
  .cs-totop {
    inset: auto 1rem 1rem auto;
    width: 2.75rem;
    height: 2.75rem;
  }
}

/* ── Custom overlay scrollbar ───────────────────────────────────────────────
   A thin beige thumb over a transparent track, pinned to the right edge. It's
   created and driven by js/scrollbar.js: it reveals on scroll, fades out once
   scrolling stops, and reappears when the pointer nears the right edge; the
   thumb is draggable. The native scrollbar is hidden below (Lenis still does
   the actual scrolling). Skipped on touch devices, which have no persistent
   pointer. */
.da-scrollbar {
  position: fixed;
  top: 0;
  right: 0;
  width: 10px;                 /* hover/hit zone; the visible thumb is thinner */
  height: 100vh;
  z-index: 950;
  pointer-events: none;        /* never blocks page clicks... */
  opacity: 0;
  transition: opacity 0.35s ease;
}
.da-scrollbar.is-visible { opacity: 1; }

.da-scrollbar-thumb {
  pointer-events: auto;        /* ...except the thumb, which is draggable */
  position: absolute;
  top: 0;
  right: 2px;
  width: 4px;                  /* thin */
  border-radius: 4px;
  background: var(--beige);
  /* Hairline graphite ring keeps the beige thumb visible on beige sections;
     second layer is a slight drop shadow with reduced blur. */
  box-shadow:
    0 0 0 1px rgba(var(--graphite-rgb), 0.28),
    0 1px 2.5px rgba(var(--graphite-rgb), 0.22);
  cursor: grab;
}
.da-scrollbar-thumb:active { cursor: grabbing; }

/* Hide the native scrollbar site-wide — the overlay above replaces it. */
html {
  scrollbar-width: none;               /* Firefox */
  -ms-overflow-style: none;            /* legacy Edge */
}
html::-webkit-scrollbar,
body::-webkit-scrollbar {
  width: 0;
  height: 0;                           /* Chrome / Safari / Edge */
}

@media (prefers-reduced-motion: reduce) {
  .da-scrollbar { transition: opacity 0.12s ease; }
}

/* ── Custom cursor ─────────────────────────────────────── */
.cursor-label {
  position: fixed;
  top: 0;
  left: 0;
  pointer-events: none;
  z-index: 1000;
  transform: translate(calc(var(--cx, 0px) - 50%), calc(var(--cy, 0px) - 50%));
}

.cursor-label-inner {
  display: inline-block;
  background: var(--graphite);
  color: var(--white);
  font-family: var(--font-caps);
  font-size: clamp(9px, 0.6vw, 11px);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  padding: clamp(8px, 0.7vw, 10px) clamp(12px, 1.1vw, 16px);
  border-radius: 999px;
  white-space: nowrap;
  opacity: 0;
  transform: scale(0);
  transition: transform 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94), opacity 0.2s ease;
}

.cursor-label.visible .cursor-label-inner {
  opacity: 1;
  transform: scale(1);
}

.work-img-wrap:hover {
  cursor: none;
}

/* Touch devices of ANY size (incl. iPads >768px wide): there is no persistent
   pointer to follow, and a tap would leave the pill stuck on screen. */
@media (hover: none) {
  .cursor-label { display: none; }
}

/* ── Client logo marquee (CSS-only infinite scroll, right → left) ─ */
.logo-marquee {
  width: 50vw;              /* banner spans half the viewport… */
  margin: clamp(72px, 9.6vw, 120px) auto 0;     /* …and is centered */
  --marquee-scale: 0.55;    /* global size knob — smaller logos → shorter band */
}

.logo-marquee-viewport {
  overflow: hidden; /* clip the over-wide track */
}

.logo-marquee-track {
  display: flex;
  align-items: center;
  width: max-content;
  will-change: transform;
  animation: logo-marquee-scroll 32s linear infinite;
}

/* pause the scroll while hovering anywhere over the banner */
.logo-marquee:hover .logo-marquee-track {
  animation-play-state: paused;
}

/* The track holds two identical logo sets; sliding exactly one set-width
   (−50%) loops seamlessly. Each logo owns equal left/right padding, so the
   gap at the seam matches every other gap — no jump at the loop point. */
@keyframes logo-marquee-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

.marquee-logo {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 3vw;
  /* reserve the band height so the row never collapses to 0 before the
     images decode (the tallest mark, Kylie's 3-line lockup, sets it) */
  min-height: calc(60px * var(--marquee-scale, 0.8));
}

/* Optical-weight sizing (same principle as the About client wall): size by
   a per-logo target width so every mark reads at a comparable cap-height.
   --logo-w is set inline per logo so it travels with the image on reorder. */
.marquee-logo img {
  /* optical-weight sizing: each logo sized by target WIDTH (--logo-w, inline
     per logo) with height auto, so multi-line lockups read at a comparable
     cap-height instead of being crushed to equal box height */
  width: calc(var(--logo-w, 150px) * var(--marquee-scale, 0.8));
  height: auto;
  object-fit: contain;
  /* recolor every (transparent-PNG) logo: brightness(0) makes the opaque pixels
     black, then invert(--logo-ink) lifts black → graphite in light mode, ecru in
     dark mode (see the dark-theme block for the lifted invert amount) */
  filter: brightness(0) invert(var(--logo-ink));
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .logo-marquee-track { animation: none; }
}

/* ── Dark-mode logo recolouring ────────────────────────────
   These transparent-PNG marks are shown as-is in light mode (a dark logo on a
   light ground, or a light logo on the dark footer). In dark mode the grounds
   invert, so force each mark to the correct ink with the brightness(0)+invert
   trick: nav logo + splash logo → ecru (light) on the now-dark nav/splash;
   footer icon + social icons → graphite (dark) on the now-light footer. Photos
   are never targeted. */
html[data-theme="dark"] .nav-logo-img,
html[data-theme="dark"] .splash-logo {
  filter: brightness(0) invert(0.955);   /* → ecru */
}
html[data-theme="dark"] .footer-icon,
html[data-theme="dark"] .footer-social-link img {
  filter: brightness(0) invert(0.161);   /* → graphite */
}

/* ── Featured Works ────────────────────────────────────── */
.works {
  background: var(--white);
  padding: clamp(36px, 4.8vw, 60px) clamp(18px, 2.4vw, 30px) clamp(48px, 6.4vw, 80px);
}

.section-label {
  font-family: var(--font-caps);
  font-size: clamp(12px, 0.85vw, 14px);
  letter-spacing: var(--ls-caps);
  line-height: var(--lh-caps);
  text-transform: uppercase;
  color: var(--graphite);
  margin-bottom: clamp(17px, 2.24vw, 28px);
}

.works-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(12px, 1.6vw, 20px);
}

.work-img-wrap {
  width: 100%;
  aspect-ratio: 7 / 8;
  overflow: hidden;
  background: var(--ecru);
}
.work-img-wrap img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1);
  transition: transform 0.6s ease-in;
  will-change: transform;
  backface-visibility: hidden;
}
.work-item:hover .work-img-wrap img {
  transform: scale(1.03);
}

.work-title {
  font-family: var(--font-body);
  font-size: clamp(16px, 1.4vw, 22px);
  font-style: italic;
  font-weight: normal;
  line-height: var(--lh-body);
  margin-top: clamp(16px, 2vw, 30px);
  margin-bottom: clamp(4px, 0.4vw, 6px);
  color: var(--graphite);
  position: relative;
  display: inline-block;
  padding-bottom: 2px;
}

.work-title::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 1px;
  background: var(--graphite);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s ease;
}

.work-item:hover .work-title::after {
  transform: scaleX(1);
}
.work-desc {
  font-family: var(--font-body);
  font-size: clamp(14px, 1.05vw, 18px);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
  opacity: 1;
  max-width: 80%;
}
.work-item:has(.work-img-wrap--tall) .work-desc {
  max-width: 90%;
}
.work-disclaimer {
  font-family: var(--font-caps);
  font-size: clamp(9px, 0.66vw, 11px);
  letter-spacing: var(--ls-caps);
  line-height: var(--lh-caps);
  text-transform: uppercase;
  color: var(--graphite);
  opacity: 0.55;
  margin-top: clamp(7px, 0.7vw, 11px);
}

.works-more {
  text-align: center;
  margin-top: clamp(29px, 3.84vw, 48px);
}
.view-more {
  font-family: var(--font-caps);
  font-size: clamp(12px, 0.85vw, 14px);   /* match .section-label ("More Work") beside it */
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;   /* match the other caps elements so the capital V isn't taller than the rest */
  color: var(--graphite);
  position: relative;
  padding-bottom: 1px;
}

.view-more::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 1px;
  background: var(--graphite);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s ease;
}

.view-more:hover::after {
  transform: scaleX(1);
}


/* ══════════════════════════════════════════════════════════════════════════
   4. HOME — index.html
   Splash screen, hero slideshow, tagline, services. (Animations for these
   live in js/main.js; the marquee above is CSS-only.)
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Splash ────────────────────────────────────────────── */
.splash {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background-color: var(--beige);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

/* The wrapper carries the entry fade/blur and the fly-to-nav transform, so the
   img itself is free to hold the dark-mode recolour filter below — GSAP writes
   an inline `filter` and would otherwise clobber it. */
.splash-logo-wrap {
  display: inline-block;
  opacity: 0;
}

.splash-logo {
  width: 280px;
  height: auto;
  object-fit: contain;
  display: block;
}

.splash-hint {
  position: absolute;
  bottom: 48px;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--font-caps);
  font-size: clamp(12px, 0.8vw, 13px);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--graphite);
  opacity: 0;
  white-space: nowrap;
}

/* ── Blink animation (splash logo) ─────────────────────── */
.blink-2 {
  animation: blink-2 2.7s infinite;
}

@keyframes blink-2 {
  0%    { opacity: 1; }
  6.5%  { opacity: 0.1; }
  13%   { opacity: 1; }
  19.5% { opacity: 0.1; }
  26%   { opacity: 1; }
  100%  { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .blink-2 { animation: none; }
}

/* ── Hero ──────────────────────────────────────────────── */
.hero {
  position: relative;
  width: 100%;
  height: 58vw;
  max-height: 780px;
  overflow: hidden;
  margin-top: 76px;   /* clears the fixed nav (~constant height) — not viewport-proportional */
}
.hero-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  opacity: 0;
  transition: opacity 0.25s ease;
  /* stacked images overlap — only the visible one should take the click */
  pointer-events: none;
}
.hero-img.hero-img--active {
  opacity: 1;
  pointer-events: auto;
  cursor: pointer;
}
/* the "View case study" / "Coming soon" pill replaces the real cursor — but
   only while the pill/preview is actually showing (JS toggles .cursor-hidden).
   Near the dots the effect is suppressed, so the real cursor returns. */
.hero.cursor-hidden .hero-img--active {
  cursor: none;
}

/* Dots nav — sits above the slides, centered near the bottom edge */
.hero-dots {
  position: absolute;
  left: 50%;
  bottom: clamp(16px, 2vw, 28px);
  transform: translateX(-50%);
  display: flex;
  gap: 10px;
  z-index: 3;
}
.hero-dot {
  width: 7px;
  height: 7px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: var(--ecru);
  opacity: 0.5;                       /* inactive dots are dimmed */
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  transition: opacity 0.25s ease, transform 0.25s ease;
}
.hero-dot:hover { opacity: 0.75; }
.hero-dot.is-active {
  opacity: 1;
  transform: scale(1.3);
}

/* Pause/play toggle — bottom-right, its baseline aligned with the dots row. */
.hero-toggle {
  position: absolute;
  right: clamp(18px, 3vw, 40px);
  bottom: clamp(16px, 2vw, 28px);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: none;
  background: none;
  color: var(--ecru);
  opacity: 1;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  transition: opacity 0.25s ease;
  z-index: 3;
}
.hero-toggle:hover { opacity: 0.6; }
.hero-toggle svg {
  width: 18px;
  height: 18px;
  fill: currentColor;
  display: block;
}

/* Cursor preview card — trails the pointer beneath the "View case study" pill
   on the home hero only (built in js/main.js, appended to <body>). */
.hero-preview {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 999;                 /* just under the pill (1000) */
  width: 210px;
  pointer-events: none;
  /* anchor point sits below the pill; centered on the cursor's x */
  transform: translate(calc(var(--cx, 0px) - 50%), calc(var(--cy, 0px) + 26px));
  transform-origin: top center;
  opacity: 0;
  transition: opacity 0.2s ease;
}
.hero-preview.visible {
  opacity: 1;
}
/* Scale lives on an inner wrapper so it doesn't multiply the outer translate
   (which would collapse the card toward the top-left as it grows/shrinks).
   Mirrors the cursor pill's two-element split. */
.hero-preview-inner {
  background: var(--white);
  padding: 10px;
  transform-origin: top center;
  transform: scale(0);
  transition: transform 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.hero-preview.visible .hero-preview-inner {
  transform: scale(1);
}
.hero-preview-thumb {
  width: 100%;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background: var(--ecru);
}
.hero-preview-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.hero-preview-title {
  font-family: var(--font-body);
  font-style: italic;
  font-weight: normal;
  font-size: 15px;
  line-height: 1.15;
  color: var(--graphite);
  margin: 12px 0 4px;
}
.hero-preview-desc {
  font-family: var(--font-body);
  font-size: 11px;
  line-height: 1.4;
  letter-spacing: var(--ls-body);
  color: var(--graphite);
  margin: 0;
}
@media (hover: none) {
  .hero-preview { display: none; }
}

/* ── Tagline ───────────────────────────────────────────── */
.tagline {
  background: var(--ecru);
  text-align: center;
  padding: clamp(108px, 14.4vw, 180px) clamp(24px, 3.2vw, 40px);
}
.tagline p {
  font-family: var(--font-body);
  font-size: clamp(30.8px, 2.57vw, 41.8px);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
  margin: 0;
}
/* "the Design Agency" opener; the italic D and A (via <em>) echo the
   Doheny Atelier initials. Gap separates it from the statement below.
   Needs `p.tagline-lead` to outrank `.tagline p { margin: 0 }` above. */
.tagline p.tagline-lead {
  margin-bottom: 2em;
  font-size: clamp(12px, 0.85vw, 14px);
  font-family: var(--font-caps);
  letter-spacing: var(--ls-caps);
  line-height: var(--lh-caps);
  text-transform: uppercase;
  font-style: normal;
}

/* ── Services ──────────────────────────────────────────── */
.services {
  background: var(--beige);
  padding: clamp(108px, 14.4vw, 180px) clamp(24px, 3.2vw, 40px) clamp(102px, 13.6vw, 170px);
}

.services-headline {
  font-family: var(--font-body);
  font-size: clamp(30.8px, 2.57vw, 41.8px);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
  max-width: 90%;
  margin-bottom: clamp(30px, 4.0vw, 50px);
}

.services-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(18px, 2.4vw, 30px) clamp(36px, 4.8vw, 60px);
}

.service-item {
  display: flex;
  align-items: baseline;
  gap: clamp(14px, 1.92vw, 24px);
  padding: clamp(12px, 1.6vw, 20px) 0;
  border-bottom: 1px solid rgba(var(--graphite-rgb), 0.25);
  opacity: 1;
  transition: border-color 0.4s ease;
}

.service-item:hover {
  border-color: rgba(var(--graphite-rgb), 0.7);
}

.service-name {
  font-family: var(--font-caps);
  font-size: clamp(12px, 1vw, 16px);
  letter-spacing: var(--ls-caps);
  line-height: var(--lh-caps);
  text-transform: uppercase;
  color: var(--graphite);
  white-space: nowrap;
  flex-shrink: 0;
}

/* Arrow affordance — sits next to each title at rest to signal "hover me",
   then drags to the right on hover as the description slides in behind it. */
.service-name::after {
  content: "\2192";
  display: inline-block;
  margin-left: 0.6em;
  color: var(--graphite);
  transform: translateX(0);
  transition: transform 0.45s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.service-item:hover .service-name::after {
  transform: translateX(9px);
}
@media (prefers-reduced-motion: reduce) {
  .service-name::after,
  .service-item:hover .service-name::after { transition: none; transform: none; }
}
.service-desc {
  font-family: var(--font-body);
  font-size: clamp(12px, 1vw, 16px);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
  opacity: 0;
  transform: translateX(-10px);
  transition: opacity 0.6s ease, transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.service-item:hover .service-desc {
  opacity: 1;
  transform: translateX(0);
}

/* Touch tablets (≥769px, no hover — iPad landscape/Pro): the hover-reveal
   above can never fire, which left every service description invisible.
   Show the descriptions statically, in their settled hover state. */
@media (hover: none) and (min-width: 769px) {
  .service-desc,
  .service-item:hover .service-desc {
    opacity: 1;
    transform: none;
  }
}


/* ══════════════════════════════════════════════════════════════════════════
   5. WORK LISTING — /work/
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Work Page ───────────────────────────────────────────── */
.work-page-grid {
  padding: clamp(112px, 11vw, 150px) clamp(24px, 5vw, 60px) clamp(80px, 10vw, 140px);
  background: var(--ecru);
  display: flex;
  flex-direction: column;
  gap: clamp(48px, 5.6vw, 80px);
}

#work-heading.work-page-heading {
  font-family: var(--font-heading);
  font-size: clamp(34px, 4.5vw, 72px);
  font-weight: normal;
  letter-spacing: var(--ls-heading);
  color: var(--graphite);

}

.work-page-subtext {
  font-family: var(--font-body);
  font-size: clamp(14px, 1.05vw, 18px);   /* kept identical to .work-desc so both read the same at every width */
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
  opacity: 1;
  margin-top: clamp(-8px, 0.4vw, 8px);
  margin-bottom: clamp(-64px, -5vw, -40px);

}

.work-row {
  display: grid;
  align-items: start;
  gap: clamp(12px, 1.4vw, 20px);
}

.work-row--asym {
  grid-template-columns: 60fr 38fr;
}

.work-row--equal {
  grid-template-columns: 1fr 1fr 1fr;
}

.work-row--asym-rev {
  grid-template-columns: 38fr 60fr;
}

.work-img-wrap--tall     { aspect-ratio: 1 / 1; }
.work-img-wrap--short    { aspect-ratio: 6 / 5; }
.work-img-wrap--wide     { aspect-ratio: 5 / 4; }
.work-img-wrap--portrait { aspect-ratio: 4 / 5; }

/* ── Work filters ────────────────────────────────────────────────────────────
   The default view keeps the hand-composed asymmetric rows. Selecting a filter
   adds .is-filtering to .work-rows: the individual .work-row grids become
   display:contents so every .work-item flows as a direct child of one uniform
   grid, and GSAP Flip (js/workfilter.js) animates the survivors into place. ── */
.work-rows {
  display: flex;
  flex-direction: column;
  gap: clamp(48px, 5.6vw, 80px);          /* the inter-row gap, moved off .work-page-grid */
}

.work-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: clamp(6px, 0.8vw, 14px);
  margin-top: clamp(10px, 1.2vw, 18px);
  font-family: var(--font-caps);
  font-size: clamp(12px, 0.85vw, 14px);
  letter-spacing: var(--ls-caps);
  line-height: var(--lh-caps);
  text-transform: uppercase;
  color: var(--graphite);
  /* Halve the filter→grid gap only. The .work-page-grid gap (clamp(48,5.6vw,80))
     also spaces heading/subtext, so pull the grid up by half that instead of
     touching the shared gap. */
  margin-bottom: clamp(-40px, -2.8vw, -24px);
}

.work-filter-label { opacity: 1; }

/* Inline custom dropdown (native <select> can't style option hover). */
.work-dropdown { position: relative; }

.work-dropdown-trigger {
  display: inline-flex;
  align-items: baseline;
  gap: clamp(6px, 0.6vw, 10px);
  font: inherit;
  letter-spacing: inherit;
  text-transform: uppercase;   /* buttons don't inherit it from .work-filter in every UA */
  color: var(--graphite);
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--graphite);
  padding: 0 2px clamp(2px, 0.3vw, 4px);
  cursor: pointer;
  transition: opacity .3s ease;
}
.work-dropdown-trigger:hover { opacity: .65; }

.work-dropdown-caret {
  width: clamp(9px, 0.8vw, 12px);
  height: auto;
  align-self: center;
  transition: transform .3s ease;
}
.work-dropdown-trigger[aria-expanded="true"] .work-dropdown-caret { transform: rotate(180deg); }

.work-dropdown-menu {
  position: absolute;
  top: calc(100% + clamp(8px, 0.8vw, 12px));
  left: 0;
  z-index: 5;
  min-width: max(100%, 180px);
  margin: 0;
  padding: clamp(6px, 0.5vw, 8px) 0;
  list-style: none;
  background: var(--ecru);
  border: 1px solid color-mix(in srgb, var(--graphite) 18%, transparent);
  border-radius: 8px;
  box-shadow: 0 12px 32px -12px color-mix(in srgb, var(--graphite) 40%, transparent);
  /* Closed state: fade + lift out, not interactive. JS toggles .is-open. */
  opacity: 0;
  transform: translateY(-6px);
  visibility: hidden;
  pointer-events: none;
  transition: opacity .25s ease, transform .25s ease, visibility 0s linear .25s;
}
.work-dropdown-menu.is-open {
  opacity: 1;
  transform: translateY(0);
  visibility: visible;
  pointer-events: auto;
  transition: opacity .25s ease, transform .25s ease, visibility 0s;
}

.work-dropdown-option {
  padding: clamp(8px, 0.7vw, 11px) clamp(16px, 1.4vw, 22px);
  white-space: nowrap;
  cursor: pointer;
  color: var(--graphite);
  transition: background-color .2s ease, color .2s ease;
}
/* Hover / keyboard-highlight state for the options — warm beige, not grey. */
.work-dropdown-option:hover,
.work-dropdown-option.is-highlighted,
/* Selected option stays full-opacity; the persistent highlight marks it. */
.work-dropdown-option.is-selected {
  background: var(--beige);
}

/* Filtering mode: collapse rows into one uniform grid. */
.work-rows.is-filtering {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(12px, 1.4vw, 20px);
}
.work-rows.is-filtering .work-row  { display: contents; }
.work-rows.is-filtering .work-img-wrap { aspect-ratio: 5 / 4; }   /* uniform cards */
.work-item.is-hidden { display: none; }

.work-filter-empty {
  font-family: var(--font-body);
  font-size: clamp(13px, 1.2vw, 18px);
  line-height: var(--lh-body);
  color: var(--graphite);
  opacity: .6;
}


/* ══════════════════════════════════════════════════════════════════════════
   6. CASE STUDY PAGES — /work/casestudy/<slug>/
   Shared by ALL case studies (behaviour in js/casestudy.js). New pages are
   generated from the da-casestudy skill template — edit here once and every
   case study picks it up.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Case-study header (title, intro, client/services meta) ── */
.cs-header {
  padding: clamp(108px, 14.4vw, 180px) clamp(24px, 3.2vw, 40px) clamp(36px, 4.8vw, 60px);
  background: var(--ecru);
}

.cs-title {
  font-family: var(--font-body);
  font-size: clamp(32px, 4.5vw, 72px);
  font-weight: normal;
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
  margin-bottom: clamp(24px, 3.2vw, 40px);
}

.cs-header-body {
  position: relative;
  min-height: 100px;
}

.cs-desc {
  width: 60%;
  display: flex;
  flex-direction: column;
  gap: clamp(12px, 1.28vw, 16px);
}

.cs-desc p {
  font-family: var(--font-body);
  font-size: clamp(13px, 1.06vw, 17px);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
  opacity: 1;
}

.cs-meta {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
}

.cs-meta-col {
  position: absolute;
  top: 0;
  display: flex;
  flex-direction: column;
  gap: clamp(14px, 1.92vw, 24px);
}

.cs-meta-col:first-child { left: var(--cs-col-client,   60%); }
.cs-meta-col:last-child  { left: var(--cs-col-services, 80%); }

.cs-meta-item {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.cs-meta-label {
  font-family: var(--font-caps);
  font-size: clamp(9px, 0.65vw, 10px);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--graphite);
  opacity: 0.5;
}

.cs-meta-value {
  font-family: var(--font-body);
  font-size: clamp(13px, 1.06vw, 17px);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
}

/* Hero image */
.cs-hero {
  width: 98%;
  aspect-ratio: 16 / 7;
  overflow: hidden;
  background: var(--ecru);
  margin: 0 auto;
}

.cs-2colimgrow {
  width: 98%;
  margin: 0 auto;
  display: flex;
  background: var(--ecru);
  gap: 1vw;
  align-items: flex-start;
}

.cs-2colimgrow-img {
  flex: 1;
  overflow: hidden;
  /* Height derives from width (instead of a fixed 80vh) so the row scales down
     proportionally when the hero column shrinks — like the other heroes. */
  aspect-ratio: 5 / 5;
}

.cs-2colimgrow-img img,
.cs-2colimgrow-img video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.cs-hero-video {
  aspect-ratio: 16 / 10;
}

/* Four-up social row: mirrors the 2-up row but with four cells. Each image is
   cropped ~10% in height and centered (10/9 box + object-fit: cover). */
.cs-4colimgrow {
  width: 98%;
  margin: 0 auto;
  display: flex;
  background: var(--ecru);
  gap: 1vw;
  align-items: flex-start;
}

.cs-4colimgrow-img {
  flex: 1;
  overflow: hidden;
  /* One shared ratio → all four cells are the same height (equal width + equal
     ratio). object-fit: cover crops the taller sources to match, centered. */
  aspect-ratio: 1200 / 2200;
}

.cs-4colimgrow-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center center;
}

/* Mechanical GIF: mirrors the first hero image row (16/7, full width) for
   consistency — object-fit:cover crops and centers to match the other rows. */
.cs-mechanical {
  width: 98%;
  margin: 0 auto;
  background: var(--ecru);
  aspect-ratio: 16 / 11;
  overflow: hidden;
}

.cs-mechanical img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center center;
}

/* Autoplay video: zoomed in ~5% and centred both axes within its frame. */
.cs-hero-video video {
  transform: scale(1.05);
  transform-origin: center center;
}

.cs-youtube-video {
  width: 95%;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: var(--ecru);
  margin: clamp(36px, 4.8vw, 60px) auto 5vw;
}

.cs-youtube-video iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

.cs-youtube-video video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Vertical (9/16) local campaign video — same page slot as .cs-youtube-video
   but sized for portrait footage instead of forcing it into a 16/10 crop. */
.cs-campaign-video {
  width: 28%;
  max-width: 420px;
  aspect-ratio: 9 / 16;
  overflow: hidden;
  background: var(--ecru);
  margin: clamp(12px, 1.6vw, 20px) auto 5vw;
}

.cs-campaign-video video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Per-page modifier: a wider campaign video (used on the Obagi page). Kept as a
   scoped class rather than inline styles so it can stay responsive — inline
   styles apply at every viewport and can't hold a media query. Desktop width
   here; mobile width lives in the ≤768px block below. */
.cs-campaign-video--wide {
  width: 35%;
  max-width: none;
  margin-top: 10px;
}

/* Two campaign videos side by side. Centres the pair and neutralises the base
   auto margins so the flex gap controls spacing instead. */
.cs-campaign-video-row {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  gap: 3%;
  margin: clamp(12px, 1.6vw, 20px) auto 5vw;
}

.cs-campaign-video-row .cs-campaign-video {
  margin: 0;
}

/* Click-to-load poster (facade) — a normal element so Lenis scrolls over it. */
.cs-youtube-facade {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  cursor: pointer;
  background: var(--graphite);
  overflow: hidden;
}

.cs-youtube-poster {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.cs-youtube-play {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  transition: transform 0.3s ease;
  pointer-events: none;
}
.cs-youtube-play svg { display: block; }
.cs-youtube-facade:hover .cs-youtube-play { transform: translate(-50%, -50%) scale(1.08); }

.cs-hero img,
.cs-hero video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center center;
}

/* ── Case Study: View-More expanding split ───────────────── */
/* Sized ~20% larger than a plain caps label so it reads clearly as a button
   while scrolling; font-weight 600 (semi-bold) gives it the same presence as
   the "Featured Works" label on the home page. */
.cs-viewmore-btn {
  margin-top: 5px;
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 5px 11px;
  background: rgba(var(--beige-rgb), 0.6);   /* beige, a little transparent */
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-family: var(--font-caps);
  font-size: clamp(11px, 0.78vw, 12px);
  font-weight: 600;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--graphite);
  transition: background 0.3s ease;
}
.cs-viewmore-btn:hover {
  background: rgba(var(--beige-rgb), 0.85);  /* slightly more opaque on hover */
}

.cs-viewmore-icon {
  display: inline-block;
  font-size: 1em;     /* same size as the label text beside it */
  font-weight: 600;   /* same stroke width as the label */
  line-height: 1;
  transition: transform 0.6s cubic-bezier(0.76, 0, 0.24, 1);
}
.cs-viewmore-btn.is-open .cs-viewmore-icon { transform: rotate(45deg); }

/* The toggle scrolls with the page from its spot under the description, then
   pins just below the nav (via .is-stuck, toggled in JS) so it stays reachable
   instead of scrolling out of view. */
.cs-viewmore-btn.is-stuck {
  position: fixed;
  left: clamp(24px, 3.2vw, 40px);   /* match .cs-header's fluid side padding */
  top: 115px;
  z-index: 20;
  margin-top: 0;
  opacity: 1;
}

/* Wrapper: left panel + hero column. Collapsed by default — the hero column
   fills 100% so the page looks untouched until "View More" is clicked. */
.cs-expand-wrap {
  display: flex;
  align-items: stretch;
  background: var(--ecru);
}

.cs-expand-panel {
  flex: 0 0 0%;            /* collapsed; widens to 50% to push the heroes over */
  min-width: 0;
  overflow: visible;
  background: var(--ecru);
  transition: flex-basis 0.8s cubic-bezier(0.76, 0, 0.24, 1);
}
.cs-expand-wrap.expanded .cs-expand-panel { flex-basis: 50%; }

.cs-expand-panel-inner {
  box-sizing: border-box;
  width: 50vw;             /* fixed so the copy doesn't reflow while animating */
  padding: clamp(18px, 2.4vw, 30px) clamp(24px, 3.2vw, 40px);
  background: var(--ecru); /* covers the heroes underneath as it slides in */
  display: flex;
  flex-direction: column;
  gap: clamp(12px, 1.44vw, 18px);
  /* Top-pinned sticky: copy sits at the top and stays in view (just below the
     nav) while the hero column scrolls past, releasing at the last hero. */
  position: sticky;
  top: calc(var(--nav-h, 80px) + 40px);
  /* Slides in from the left in sync with the panel widening (same duration +
     easing as flex-basis), so the copy's right edge tracks the images' left
     edge — it looks like it's following the images as they shrink right.
     Starts shifted fully left (off-screen) so it's hidden while collapsed. */
  transform: translateX(-100%);
  pointer-events: none;
  transition: transform 0.8s cubic-bezier(0.76, 0, 0.24, 1);
}
.cs-expand-wrap.expanded .cs-expand-panel-inner {
  transform: none;
  pointer-events: auto;
}


.cs-expand-title {
  font-family: var(--font-body);
  font-size: clamp(22px, 2vw, 32px);
  font-weight: normal;
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
  margin: 0;
}

.cs-expand-panel-inner p {
  font-family: var(--font-body);
  font-size: clamp(12px, 1vw, 16px);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
  opacity: 1;
  margin: 0;
}

.cs-contributors {
  /* extra breathing room so the contributor list reads as its own block,
     separate from the About-the-Project paragraphs above it */
  margin-top: 2vw;
}

.cs-contributors-list {
  list-style: none;
  margin: 0;
  padding: 0;
  /* two equal-width columns */
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: 2vw;
  row-gap: 1vw;
}

.cs-contributors-list li {
  font-family: var(--font-body);
  font-size: clamp(12px, 1vw, 16px);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
  opacity: 1;
  /* role on top, name(s) beneath */
  display: flex;
  flex-direction: column;
}

.cs-contributors-role {
  font-family: var(--font-caps);
  font-size: 0.8em;
  letter-spacing: var(--ls-caps);
  line-height: var(--lh-caps);
  text-transform: uppercase;
  font-weight: normal;
  opacity: 1;
  margin-bottom: 0.35em;
}

/* keep each person's full name intact; wrapping only happens between names */
.cs-name {
  white-space: nowrap;
}

.cs-hero-stack {
  flex: 1 1 auto;          /* takes the space the panel leaves */
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1vw;
}

/* ── Case Study: Deliverables ─────────────────────────────── */
.cs-deliverables {
  padding: clamp(48px, 6.4vw, 80px) clamp(24px, 3.2vw, 40px) clamp(84px, 11.2vw, 140px);
  background: var(--ecru);
  /* One grid for the whole section so the sticky headers share it as their
     containing block and can stack (rather than being trapped per-row) */
  display: grid;
  grid-template-columns: 35fr 65fr;
  column-gap: clamp(24px, 3.2vw, 40px);
  row-gap: clamp(19px, 2.56vw, 32px);
  align-items: start;
}

/* Flatten each row so its left/right become direct grid items of the section */
.cs-row {
  display: contents;
}

.cs-row-left {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--graphite);
  padding-top: clamp(12px, 1.28vw, 16px);
  padding-bottom: clamp(12px, 1.6vw, 20px);   /* breathing room below the title when collapsed/stacked */
  /* Header pins and STACKS: the next header pins below this one, which stays in
     view. The per-header `top` offset is set in casestudy.js (cumulative). */
  position: sticky;
  top: calc(var(--nav-h, 80px) + 24px);
  align-self: start;
  z-index: 1;             /* keep stacked headers above the scrolling images */
  background: var(--ecru);/* opaque so a pinned header doesn't show content behind it */
}

.cs-row-hdr {
  display: flex;
  align-items: baseline;
  gap: clamp(12px, 1.28vw, 16px);
  cursor: pointer;
  transition: opacity 0.3s ease;
}
.cs-row-hdr:hover {
  opacity: 0.6;
}

.cs-row-num {
  font-family: var(--font-caps);
  font-size: clamp(12px, 0.85vw, 14px);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--graphite);
}

.cs-row-label {
  font-family: var(--font-caps);
  font-size: clamp(12px, 0.85vw, 14px);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--graphite);
}

/* Collapsible block under each header (description + product list). The JS
   animates this whole block's height/padding/opacity as the card pins. */
.cs-row-body {
  overflow: hidden;
}

.cs-row-desc {
  font-family: var(--font-body);
  font-size: clamp(14px, 1.05vw, 17px);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
  opacity: 1;
}

.cs-row-products {
  padding-top: clamp(13px, 1.76vw, 22px);
}

.cs-row-products-title {
  display: block;
  font-family: var(--font-caps);
  font-size: clamp(10px, 0.7vw, 11px);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--graphite);
  margin-bottom: 12px;
}

.cs-row-products-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.cs-row-products-list li {
  font-family: var(--font-body);
  font-size: clamp(12px, 0.85vw, 14px);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
}

.cs-row-right {
  position: relative;
  /* Two stacked images define the row height now */
  display: flex;
  flex-direction: column;
  gap: clamp(14px, 1.92vw, 24px);
  overflow: hidden;
}

.cs-row-right img,
.cs-row-right video {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
}

/* Modifier: show a deliverable image at its full natural height instead of
   cropping it to the square card ratio (e.g. a tall sticker sheet). */
.cs-row-right img.cs-img-full {
  aspect-ratio: auto;
  height: auto;
  object-fit: contain;
}

/* Drop-in replacement for one .cs-row-right img: wraps several images that
   auto-advance with a crossfade (see /js/casestudy.js). Matches the sibling
   image's sizing so it slots into the same stacked layout. */
.cs-row-slideshow {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  overflow: hidden;
}

/* When the slideshow stands in for the mechanical frame it keeps that slot's
   wide 16/11 ratio rather than the square deliverable-card ratio. */
.cs-mechanical.cs-row-slideshow {
  aspect-ratio: 16 / 11;
}

.cs-row-slideshow img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transform: scale(1);
  transition: transform 0.4s ease;
}

.cs-row-slideshow img.is-active {
  opacity: 1;
}

/* Hovering pauses the auto-advance (see /js/casestudy.js) — zoom the visible
   frame slightly so the pause reads as an intentional response to the hover,
   not a stall. Gated to hover-capable (pointer) devices only: on touch screens
   a tap fires a sticky :hover, which would re-trigger the zoom on every slide
   change. Touch devices get no hover effect at all. */
@media (hover: hover) {
  .cs-row-slideshow:hover img.is-active {
    transform: scale(1.05);
  }
  /* The mechanical slideshow doesn't pause on hover (it fills the viewport, so
     the cursor is always over it) — so it gets no hover zoom either. */
  .cs-mechanical.cs-row-slideshow:hover img.is-active {
    transform: none;
  }
}

/* ── More Work (case-study footer grid) ── */
.more-work {
  background: var(--ecru);
  padding: clamp(18px, 2.4vw, 30px) clamp(24px, 3.2vw, 40px) clamp(60px, 8.0vw, 100px);
}

.more-work-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: clamp(17px, 2.24vw, 28px);
}

.more-work-head .section-label {
  margin-bottom: 0;
}

/* Expanding-panel hover gallery: one panel is large, the other two collapse to
   slivers (same height). Hovering a sliver makes it the active/large one; the
   state persists after the cursor leaves (driven by .is-active in JS). Scoped to
   .more-work so the homepage works-grid (a plain 3-up grid) is untouched. */
.more-work .works-grid {
  display: flex;
  gap: clamp(12px, 1.6vw, 20px);
  aspect-ratio: 25 / 9;   /* fixes the row height so it doesn't jitter while panels animate */
}
.more-work .work-item {
  flex: 1 1 0;            /* collapsed by default */
  min-width: 0;
  overflow: hidden;
  transition: flex-grow 0.7s cubic-bezier(0.76, 0, 0.24, 1);
}
.more-work .work-item.is-active {
  flex-grow: 3;           /* the large panel (~60% vs ~20% each for the slivers) */
}
.more-work .work-img-wrap {
  height: 100%;
  aspect-ratio: auto;     /* height comes from the flex row, not the base 7/8 */
}
/* The expand IS the hover feedback here, so drop the subtle image zoom. */
.more-work .work-item:hover .work-img-wrap img { transform: none; }


/* ══════════════════════════════════════════════════════════════════════════
   7. ABOUT — /about/
   ══════════════════════════════════════════════════════════════════════════ */

/* ── About Hero ─────────────────────────────────────────── */
.about-hero {
  padding: clamp(180px, 24.0vw, 300px) clamp(36px, 4.8vw, 60px) clamp(48px, 6.4vw, 80px);
  background: var(--ecru);
}

.about-hero-heading {
  font-family: var(--font-body);
  font-size: clamp(22px, 2vw, 32px);
  font-weight: normal;
  letter-spacing: var(--ls-body);
  line-height: 1.35;
  color: var(--graphite);
  max-width: 90%;
  /* Side padding pulls the text column in from the section edges so the
     paragraph reads at a comfortable measure instead of spanning the full
     width. (box-sizing:border-box, so this narrows the text, not the box.) */
  padding: 0 clamp(24px, 7vw, 160px);
  margin-left: auto;
  margin-right: auto;
  text-align: center;
}

/* ── About Image Collage ────────────────────────────────── */
/* Editorial collage: four tiles are absolutely positioned by % inside a
   centered fixed-ratio stage, so the whole composition scales as one unit.
   Arranged as a dense, overlapping 2×2 cluster (1↔2 top, 3↔4 bottom) with
   z-index + soft shadow for depth. */
.about-images {
  position: relative;
  width: 92%;
  margin: clamp(12px, 1.6vw, 20px) auto clamp(38px, 5.12vw, 64px);
  aspect-ratio: 5 / 5;
  background: var(--ecru);
}

.about-img-wrap {
  position: absolute;
  overflow: hidden;
}

.about-img-wrap img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Collage placement — dense, overlapping 2×2 cluster */
.about-img-wrap:nth-child(1) { left: 7%;  top: 4%;  width: 50%; height: 40%; z-index: 1; } /* Kylie — top-left, wide */
.about-img-wrap:nth-child(2) { left: 56%; top: 7%; width: 35%; height: 30%; z-index: 2; } /* Obagi — top-right, overlaps 1 */
.about-img-wrap:nth-child(3) { left: 12%; top: 50%; width: 40%; height: 40%; z-index: 2; } /* Nautica — bottom-left, tall */
.about-img-wrap:nth-child(4) { left: 50%; top: 40%; width: 34%; height: 34%; z-index: 3; } /* Kylie 2 — mid-right, overlaps 3 */


/* ── Founder ─────────────────────────────────────────────── */
.founder {
  background: var(--beige);
  padding: clamp(48px, 6.4vw, 80px) clamp(36px, 4.8vw, 60px) clamp(60px, 8.0vw, 100px);
}

.founder-text p.founder-label {
  font-family: var(--font-caps);
  font-size: clamp(13px, 1.2vw, 19px);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--graphite);
  /* Shift the label down out of the image-top alignment and closer to the body
     copy. Top+bottom margins sum to the old 48px so nothing below moves — the
     label just relocates into the gap. */
  margin-top: clamp(19px, 2.56vw, 32px);
  margin-bottom: clamp(12px, 1.28vw, 16px);
  text-align: right;
}

.founder-grid {
  display: grid;
  grid-template-columns: 0.7fr 1fr;
  gap: clamp(36px, 4.8vw, 60px);
  align-items: stretch;
}

.founder-text {
  display: flex;
  flex-direction: column;
  gap: clamp(14px, 1.92vw, 24px);
  text-align: right;
  width:87%;
  justify-self: end;  
}

.founder-text p {
  font-family: var(--font-body);
  font-size: clamp(16px, 1.5vw, 24px);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
}

.founder-link {
  font-family: var(--font-body);
  font-size: clamp(13px, 1.2vw, 19px);
  line-height: var(--lh-body);
  color: var(--graphite);
  position: relative;
  padding-bottom: 1px;
  align-self: flex-end;
  /* sit directly beneath the founder copy (the .founder-text flex gap),
     not pushed to the bottom of the stretched column */
}

.founder-link::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 1px;
  background: var(--graphite);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s ease;
}

.founder-link:hover::after {
  transform: scaleX(1);
}

.founder-photo {
  aspect-ratio: 7 / 8;
  overflow: hidden;
}

.founder-photo a {
  display: block;
  width: 100%;
  height: 100%;
}

.founder-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* ── Expertise ──────────────────────────────────────────── */
.expertise {
  background: var(--ecru);
  padding: clamp(60px, 8.0vw, 100px) clamp(36px, 4.8vw, 60px) 0;
  display: grid;
  grid-template-columns: 2fr 3fr;
  gap: clamp(48px, 6.4vw, 80px);
  align-items: start;
}

.expertise-left {
  position: sticky;
  top: 80px;
}

.expertise-label {
  font-family: var(--font-caps);
  font-size: clamp(13px, 1.2vw, 19px);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--graphite);
  margin-bottom: clamp(24px, 3.2vw, 40px);
}

.expertise-img-area {
  position: relative;
  aspect-ratio: 1 / 1;
  overflow: hidden;
}

.expertise-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.4s ease;
}

.expertise-img.active {
  opacity: 1;
}

/* Caption naming the active image, tucked into its bottom-right corner. */
.expertise-caption {
  font-family: var(--font-body);
  font-size: clamp(11px, 0.85vw, 13px);
  letter-spacing: var(--ls-body);
  line-height: 1.3;
  text-align: right;
  color: rgba(var(--graphite-rgb), 0.55);
}

.expertise-img-area .expertise-caption {
  position: absolute;
  right: clamp(10px, 1vw, 16px);
  bottom: clamp(10px, 1vw, 16px);
  max-width: 60%;
  opacity: 0;
  transition: opacity 0.4s ease;
  pointer-events: none;
}

.expertise-img-area .expertise-caption.active {
  opacity: 1;
}

.expertise-list {
  display: flex;
  padding-top:4vw;
  flex-direction: column;
}

.expertise-item {
  padding: clamp(17px, 2.24vw, 28px) 0;
  cursor: default;
}

.expertise-header {
  display: flex;
  align-items: center;
  gap: clamp(14px, 1.92vw, 24px);
  margin-bottom: 0;
}

.expertise-name {
  font-family: var(--font-caps);
  font-size: clamp(12px, 1vw, 16px);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--graphite);
  white-space: nowrap;
  transition: opacity 0.3s ease;
}

.expertise-rule {
  flex: 1;
  border: none;
  border-top: 1px solid rgba(var(--graphite-rgb), 0.25);
}

.expertise-desc {
  font-family: var(--font-body);
  font-size: clamp(14px, 1.25vw, 20px);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
  max-width: 640px;
  opacity: 0;
  max-height: 0;
  overflow: hidden;
  transition: opacity 0.3s ease, max-height 0.4s ease, margin-top 0.3s ease;
  margin-top: 0;
}

.expertise-item:hover .expertise-desc,
.expertise-item.is-open .expertise-desc {
  opacity: 1;
  max-height: 200px;
  margin-top: 14px;
}

.expertise-item-img { display: none; }

/* Expertise on touch TABLETS (iPad, etc.): the desktop layout reveals the shared
   image + each description on :hover, which a touch device can't trigger — so it
   collapsed to just the titles + a wall of white space. On any non-hover device
   ≥769px, show everything statically as a 2-column card grid (name, rule, desc,
   and the item's own image). Desktop (mouse) keeps its hover interaction; phones
   (≤768px) keep their own stacked layout in the mobile block below. */
@media (hover: none) and (min-width: 769px) {
  .expertise {
    grid-template-columns: 1fr;
    padding: clamp(72px, 9vw, 110px) clamp(32px, 5vw, 56px) clamp(48px, 7vw, 72px);
    gap: clamp(24px, 4vw, 40px);
  }
  .expertise-left { position: static; }
  .expertise-img-area { display: none; }          /* shared image can't cycle without hover */
  .expertise-list {
    padding-top: 0;
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: clamp(24px, 4vw, 48px);
    row-gap: clamp(36px, 6vw, 56px);
  }
  .expertise-item { padding: 0; }
  .expertise-header { flex-direction: column; align-items: stretch; gap: 10px; }
  .expertise-rule { flex: none; }                 /* full-width underline under the name */
  .expertise-name { white-space: normal; font-size: clamp(14px, 1.6vw, 18px); }
  .expertise-desc {                                /* reveal statically — no hover needed */
    opacity: 1;
    max-height: none;
    margin-top: 12px;
  }
  .expertise-item-img {                            /* each card shows its own image */
    display: block;
    position: relative;
    width: 100%;
    aspect-ratio: 4 / 3;
    overflow: hidden;
    margin-top: clamp(14px, 2vw, 20px);
  }
  .expertise-item-img img { width: 100%; height: 100%; object-fit: cover; }
  .expertise-item-img .expertise-caption {
    position: absolute;
    right: 10px;
    bottom: 10px;
    max-width: 60%;
    font-size: 11px;
  }
}

/* ── Client Logos ───────────────────────────────────────── */
.clients {
  background: var(--ecru);
  padding: 10% clamp(36px, 4.8vw, 60px) 15%;
}

/* "Our Clients" eyebrow above the marquee — expertise page only (about page
   has no label here, so this is scoped to .clients-label, not .clients). */
.clients-label {
  display: block;
  text-align: center;
  margin-bottom: clamp(24px, 3.2vw, 40px);
}

/* Expertise page only — the about page's .clients keeps its full 10% top
   padding (it follows a different, taller section); here it directly
   follows the mission/strategy cards, which already carry their own
   bottom padding, so the combined gap read as too tall. */
.clients--tight {
  padding-top: clamp(32px, 4vw, 56px);
  padding-bottom: clamp(56px, 7vw, 96px);
}

/* The client logos now render as the shared running marquee (markup in
   about/index.html; all the visual rules live in the .logo-marquee /
   .marquee-logo blocks near the top). Per-context tweaks: make the banner
   wider here (75vw vs the home page's 50vw), and drop the marquee's
   home-page top margin so the .clients section padding sets the rhythm. */
.clients .logo-marquee {
  width: 75vw; /* about page runs wider than the home page's 50vw */
  margin: 0 auto;
}

/* ── FAQ ────────────────────────────────────────────────── */
.faq {
  background: var(--beige);
  padding: clamp(60px, 8.0vw, 100px) clamp(36px, 4.8vw, 60px);
}

.faq-heading {
  font-family: var(--font-caps);
  font-size: clamp(13px, 1.2vw, 19px);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--graphite);
  margin-bottom: clamp(29px, 3.84vw, 48px);
}

.faq-list {
  display: flex;
  flex-direction: column;
}

.faq-item {
  border-top: 1px solid rgba(var(--graphite-rgb), 0.25);
}

.faq-item:last-child {
  border-bottom: 1px solid rgba(var(--graphite-rgb), 0.25);
}

.faq-question {
  display: flex;
  align-items: center;
  gap: clamp(12px, 1.6vw, 20px);
  padding: clamp(14px, 1.92vw, 24px) 0;
  cursor: pointer;
  list-style: none;
  font-family: var(--font-body);
  font-size: clamp(16px, 1.5vw, 24px);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
  user-select: none;
}

.faq-question::-webkit-details-marker { display: none; }

.faq-toggle {
  font-family: var(--font-body);
  font-size: clamp(14px, 1.3vw, 21px);
  line-height: var(--lh-body);
  flex-shrink: 0;
  width: 16px;
}

.faq-answer {
  font-family: var(--font-body);
  font-size: clamp(13px, 1.2vw, 19px);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
  padding: 0 0 clamp(17px, 2.24vw, 28px) clamp(22px, 2.88vw, 36px);
  max-width: 80%;
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity 0.3s ease, transform 0.3s ease;
}

.faq-answer a {
  text-decoration: underline;
  text-underline-offset: 2px;
}


/* ══════════════════════════════════════════════════════════════════════════
   8. Q&A — /katedohenyqa/
   Has its own ≤900px mobile block at the end of this section (the page
   breaks earlier than the site-wide 768px).
   ══════════════════════════════════════════════════════════════════════════ */

/* ══════════════════════════════════════════════════════════
   Q&A — Get to Know Kate
   ══════════════════════════════════════════════════════════ */
.qa {
  background: var(--ecru);
  color: var(--graphite);
}

/* ── Intro: text left, portrait right ─────────────────────── */
.qa-intro {
  display: grid;
  grid-template-columns: 44fr 56fr;
  grid-template-areas:
    "head figure"
    "body figure";
  align-items: stretch;
}

.qa-intro-head {
  grid-area: head;
  padding: clamp(120px, 16.0vw, 200px) clamp(38px, 5.12vw, 64px) clamp(24px, 3.2vw, 40px);
}

.qa-intro-body {
  grid-area: body;
  padding: 0 clamp(38px, 5.12vw, 64px) clamp(72px, 9.6vw, 120px);
}

.qa-intro-figure {
  grid-area: figure;
  margin: 0;
  padding: clamp(46px, 6.08vw, 76px) clamp(38px, 5.12vw, 64px) 0 0;
}

.qa-intro-figure img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.qa-eyebrow {
  font-family: var(--font-body);
  font-style: italic;
  font-size: clamp(20px, 1.8vw, 30px);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
  margin-bottom: clamp(14px, 1.92vw, 24px);
}

.qa-name {
  font-family: var(--font-body);
  font-weight: normal;
  font-size: clamp(38px, 3.2vw, 56px);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
  margin: 0 0 clamp(17px, 2.24vw, 28px);
}

.qa-name em {
  font-style: italic;
}

.qa-byline {
  font-family: var(--font-body);
  font-size: clamp(14px, 1.1vw, 18px);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
  margin-bottom: clamp(54px, 7.2vw, 90px);
}

/* ── Q&A blocks ───────────────────────────────────────────── */
.qa-block {
  margin-bottom: clamp(34px, 4.48vw, 56px);
}

.qa-block:last-child {
  margin-bottom: 0;
}

.qa-q {
  font-family: var(--font-caps);
  font-weight: normal;
  font-size: clamp(12px, 0.95vw, 15px);
  letter-spacing: var(--ls-caps);
  line-height: 1.4;
  text-transform: uppercase;
  color: var(--graphite);
  margin: 0 0 clamp(14px, 1.92vw, 24px);
}

.qa-a {
  font-family: var(--font-body);
  font-size: clamp(15px, 1.15vw, 19px);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
  margin: 0 0 clamp(12px, 1.6vw, 20px);
}

.qa-a:last-child {
  margin-bottom: 0;
}

/* ── Pull quote ───────────────────────────────────────────── */
.qa-quote {
  padding: clamp(72px, 9.6vw, 120px) clamp(38px, 5.12vw, 64px) clamp(60px, 8.0vw, 100px);
  text-align: center;
}

.qa-quote blockquote {
  font-family: var(--font-body);
  font-style: italic;
  font-size: clamp(26px, 2.8vw, 46px);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
  max-width: 60%;
  margin: 0 auto;
}

/* ── Body: portrait left, text right ──────────────────────── */
.qa-body {
  display: grid;
  grid-template-columns: 48fr 52fr;
  column-gap: clamp(38px, 5.12vw, 64px);
  align-items: stretch;
  padding: 0 clamp(38px, 5.12vw, 64px) clamp(96px, 12.8vw, 160px);
}

.qa-body-figure {
  margin: 0;
}

.qa-body-figure img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.qa-body-text {
  padding-top: clamp(24px, 3.2vw, 40px);
}

/* ── Mobile ───────────────────────────────────────────────── */
@media (max-width: 900px) {
  .qa-intro {
    grid-template-columns: 1fr;
    grid-template-areas:
      "head"
      "figure"
      "body";
  }
  .qa-intro-head {
    padding: 120px 24px 40px;
  }
  .qa-intro-figure {
    aspect-ratio: 4 / 5;
    padding: 0;
  }
  .qa-intro-body {
    padding: 40px 24px 60px;
  }

  .qa-eyebrow   { font-size: clamp(18px, 5vw, 30px); }
  .qa-name      { font-size: clamp(34px, 9vw, 58px); }
  .qa-byline    { font-size: clamp(14px, 3.6vw, 19px); margin-bottom: 56px; }
  .qa-q         { font-size: clamp(12px, 3.2vw, 15px); }
  .qa-a         { font-size: clamp(16px, 4vw, 20px); }

  .qa-quote {
    padding: 70px 24px 60px;
  }
  .qa-quote blockquote {
    font-size: clamp(24px, 6.5vw, 40px);
    max-width: 100%;
  }

  .qa-body {
    grid-template-columns: 1fr;
    column-gap: 0;
    row-gap: 40px;
    padding: 0 24px 90px;
  }
  .qa-body-figure {
    aspect-ratio: 4 / 5;
  }
  .qa-body-text {
    padding-top: 0;
  }
}


/* ══════════════════════════════════════════════════════════════════════════
   8.5 EXPERTISE — /expertise/
   "What we do" intro: large Caslon page title on the left, two stacked cards
   on the right — each a caps eyebrow (mission / strategy) beside a body para.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Heading (full-bleed so the title never wraps mid-phrase) ── */
.wwd-hero {
  background: var(--ecru);
  padding: clamp(150px, 18vw, 240px) clamp(36px, 4.8vw, 72px) clamp(56px, 7vw, 112px);
}

.wwd-title {
  font-family: var(--font-heading);
  font-weight: normal;
  font-size: clamp(34px, 4.5vw, 72px);   /* match the /work/ "Work" heading */
  letter-spacing: var(--ls-heading);
  line-height: var(--lh-heading);
  text-transform: lowercase;
  color: var(--graphite);
}

/* ── What We Do cards (kept in the right column, under the heading) ── */
.wwd {
  background: var(--ecru);
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  column-gap: clamp(32px, 4vw, 72px);
  align-items: start;
  padding: 0 clamp(36px, 4.8vw, 72px) clamp(48px, 6vw, 100px);
}

.wwd-cards {
  grid-column: 2;
  display: flex;
  flex-direction: column;
  gap: clamp(48px, 6vw, 88px);
}

.wwd-card {
  display: grid;
  grid-template-columns: 0.45fr 1fr;
  column-gap: clamp(6px, 0.8vw, 14px);
  align-items: start;
}

.wwd-label {
  font-family: var(--font-caps);
  font-size: clamp(12px, 0.85vw, 14px);
  letter-spacing: var(--ls-caps);
  /* Match the body line-height so the eyebrow's first line tops-aligns with
     the paragraph's first line (the caps default lh of 1.9 would drop it). */
  line-height: var(--lh-body);
  text-transform: uppercase;
  color: var(--graphite);
}

.wwd-body {
  font-family: var(--font-body);
  font-size: clamp(15px, 1.15vw, 19px);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
  max-width: 48ch;
}

/* ── Contact page ── lead paragraph under the "let's connect" H1, then the
      "Reach out at…" line set close beneath it. Lives on the ecru hero. ── */
.contact-lead {
  font-family: var(--font-body);
  font-size: clamp(17px, 1.5vw, 26px);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
  width: 80vw;
  max-width: 80vw;
  margin-top: clamp(24px, 2.6vw, 44px);
}

.contact-cta-line {
  font-family: var(--font-body);
  font-size: clamp(17px, 1.5vw, 26px);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
  margin-top: clamp(8px, 0.8vw, 14px);
}

.contact-cta-email {
  color: var(--graphite);
  text-decoration: underline;
  text-underline-offset: 0.15em;
  transition: opacity 0.25s ease;
}
.contact-cta-email:hover { opacity: 0.6; }

/* ── Industries / Services (section heading, then two equal columns; per
      column: caps title on its own row, list flush to the column's right
      edge at 60% width) ── */
.ind-serv {
  background: var(--ecru);
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: clamp(32px, 4vw, 72px);
  row-gap: clamp(40px, 5vw, 72px);
  padding: clamp(28px, 3.5vw, 56px) clamp(36px, 4.8vw, 72px) clamp(96px, 12vw, 200px);
}

.ind-serv-heading {
  grid-column: 1 / -1;
  font-family: var(--font-heading);
  font-weight: normal;
  font-size: clamp(28px, 3.6vw, 58px);   /* slightly smaller than .wwd-title */
  letter-spacing: var(--ls-heading);
  line-height: var(--lh-heading);
  text-transform: lowercase;
  color: var(--graphite);
}

.ind-serv-col {
  display: flex;
  flex-direction: column;
  gap: clamp(12px, 1.4vw, 22px);
}

/* Nudge the Industries column (first col) very slightly right of the grid edge */
.ind-serv-col:first-of-type {
  padding-left: clamp(6px, 0.8vw, 12px);
}

/* Services column only: three independent title+list groups (Strategy /
   Design / Content) stacked inside one .ind-serv-col. Same gap value as
   .ind-serv-col so title-to-list and group-to-group spacing stay equal. */
.ind-serv-group {
  display: flex;
  flex-direction: column;
  gap: clamp(12px, 1.4vw, 22px);
}

.ind-serv-title {
  font-family: var(--font-caps);
  font-weight: normal;
  font-size: clamp(12px, 0.85vw, 14px);
  letter-spacing: var(--ls-caps);
  /* match the list's line-height so the title tops-align with the first item */
  line-height: var(--lh-body);
  text-transform: uppercase;
  color: var(--graphite);
  flex: none;
}

.ind-serv-list {
  width: 65%;          /* 65% of the column... */
  margin-left: auto;   /* ...pushed flush to the column's right edge */
  list-style: none;
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: clamp(6px, 0.7vw, 12px);
}

.ind-serv-list li {
  font-family: var(--font-body);
  font-size: clamp(15px, 1.15vw, 19px);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
}


/* ══════════════════════════════════════════════════════════════════════════
   9. COMING SOON — /comingsoon/
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Coming Soon ─────────────────────────────────────────── */
.coming-soon {
  height: calc(100vh - 76px);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--ecru);
}

.coming-soon-text {
  font-family: var(--font-body);
  font-style: italic;
  font-size: clamp(16px, 1.5vw, 24px);
  letter-spacing: var(--ls-body);
  line-height: var(--lh-body);
  color: var(--graphite);
  opacity: 1;
}


/* ══════════════════════════════════════════════════════════════════════════
   10. MOBILE — every page, ≤768px
   The single phone-layout block. Type sizes here are a proportional raw-vw
   ladder (display ~6.5–7.5vw, leads ~5.5vw, body ~4vw, labels 3–3.6vw).
   When you add a section above, add its mobile rules here in the same spot
   in the order (sections appear in the same order as the desktop rules).
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Responsive: Mobile ≤768px ──────────────────────────── */
@media (max-width: 768px) {

  /* Cursor pill — hide on touch */
  .cursor-label { display: none; }

  /* Splash */
  .splash-logo { width: 180px; }
  .splash-hint { font-size: 3vw; bottom: 36px; }

  /* Nav */
  .nav {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 16px 24px;
    position: fixed;
    top: 0; left: 0; right: 0;
  }
  .nav-link { display: none; }
  .nav-hamburger {
    display: flex;
    flex-direction: column;
    gap: 6px;
    background: none;
    border: none;
    cursor: pointer;
    padding: 4px;
    position: absolute;
    right: 24px;
    top: 50%;
    transform: translateY(-50%);
  }
  .nav-hamburger span {
    display: block;
    width: 22px;
    height: 1px;
    background: var(--graphite);
  }

  /* Mobile menu overlay */
  .mobile-menu {
    display: flex;
    position: fixed;
    inset: 0;
    z-index: 500;
    background: var(--beige);
    flex-direction: column;
    align-items: center;
    justify-content: center;
    transform: translateY(-100%);
    transition: transform 0.45s cubic-bezier(0.76, 0, 0.24, 1);
  }
  .mobile-menu.open {
    transform: translateY(0);
  }
  /* Wipe-in on arrival. The inline head snippet sets .menu-wipe-in before
     first paint whenever this page was opened from the menu, so the panel is
     already covering and wipes up to reveal THIS page — the panel never lifts
     on the page you tapped from. Deliberately an animation, not the .open
     transition: it needs to run off the page load with no JS to start it, so
     the reveal still happens if mobile.js fails. mobile.js drops the class on
     animationend — it has to, because a filled animation outranks
     .mobile-menu.open's transform and would leave the panel stuck off-screen. */
  html.menu-wipe-in .mobile-menu {
    animation: menu-wipe-up 0.45s cubic-bezier(0.76, 0, 0.24, 1) both;
  }
  @keyframes menu-wipe-up {
    from { transform: translateY(0); }
    to   { transform: translateY(-100%); }
  }
  .mobile-menu-close {
    position: absolute;
    top: 20px;
    right: 24px;
    width: 36px;
    height: 36px;
    background: none;
    border: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .mobile-menu-close span {
    position: absolute;
    width: 20px;
    height: 1px;
    background: var(--graphite);
  }
  .mobile-menu-close span:first-child { transform: rotate(45deg); }
  .mobile-menu-close span:last-child  { transform: rotate(-45deg); }
  .mobile-nav {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 36px;
  }
  .mobile-nav a {
    font-family: var(--font-caps);
    font-size: 4.5vw;
    letter-spacing: var(--ls-caps);
    text-transform: uppercase;
    color: var(--graphite);
  }

  /* Hero */
  .hero {
    height: 70vw;
    max-height: none;
    margin-top: 68px;
    background-color: var(--ecru);
  }

  /* Tagline */
  .tagline {
    padding: 80px 28px;
  }
  /* Statement copy sits just above body size; balance prevents an orphan word
     (e.g. "and remembering." breaking apart onto its own lines). */
  .tagline p { font-size: 7.5vw; line-height: 1.25; text-wrap: balance; }
  /* Match the higher-specificity desktop rule (.tagline p.tagline-lead) and
     size the caps eyebrow to the same 3vw as .section-label ("Featured Works")
     below it, mirroring how both are 0.85vw on desktop. */
  .tagline p.tagline-lead { font-size: 3vw; }

  /* Client logo marquee */
  /* 50vw is too cramped on a phone — span the content width instead */
  .logo-marquee { width: auto; margin-top: 72px; --marquee-scale: 0.5; }
  .marquee-logo { padding: 0 7vw; }
  .logo-marquee-track { animation-duration: 22s; }

  /* Works */
  .works { padding: 48px 24px 60px; }
  .section-label { font-size: 3vw; }
  .works-grid {
    grid-template-columns: 1fr;
    gap: 36px;
  }
  /* No hover on touch — stack the More Work panels full-width, no expand. */
  .more-work .works-grid {
    flex-direction: column;
    aspect-ratio: auto;
    gap: 36px;
  }
  .more-work .work-item { flex: none; }
  .more-work .work-item.is-active { flex-grow: 0; }
  .more-work .work-img-wrap { aspect-ratio: 7 / 8; height: auto; }
  .work-title { font-size: 5.5vw; }
  .work-desc  { font-size: 4vw; max-width: 100%; }
  .work-disclaimer { font-size: 2.6vw; margin-top: 2vw; }
  .view-more  { font-size: 3vw; }   /* match .section-label on mobile */
  .works-more { margin-top: 40px; }

  /* Work page — collapse every row to a single column, fluid gutters + rhythm */
  .work-page-grid {
    padding: clamp(88px, 22vw, 112px) clamp(20px, 6vw, 28px) clamp(56px, 14vw, 72px);
    gap: clamp(28px, 7vw, 40px);
  }
  /* match the ID-specificity of the base rule so this actually wins */
  #work-heading.work-page-heading { margin-bottom: 0; }
  .work-page-subtext { margin-top: clamp(-16px, -3.5vw, -8px); margin-bottom: 0; font-size: 4vw; }  /* match .work-desc's mobile size */
  /* Shrink + tighten the filter caps so the label and dropdown sit on one line
     instead of the dropdown wrapping awkwardly below on narrow phones. Also
     pull the filter up toward the subtext and push the grid down so the
     dropdown underline isn't crowding the first project. */
  .work-filter {
    font-size: 10px;
    letter-spacing: 1.5px;
    margin-top: -10px;
    margin-bottom: -2px;
  }
  .work-row--asym,
  .work-row--equal,
  .work-row--asym-rev { grid-template-columns: 1fr; }
  .work-row { gap: clamp(28px, 7vw, 40px); }
  .work-rows { gap: clamp(28px, 7vw, 40px); }
  /* Two-up filtered grid on phones — three columns is too tight. */
  .work-rows.is-filtering { grid-template-columns: repeat(2, 1fr); }

  /* Services */
  .services { padding: 80px 24px; }
  .services-headline {
    font-size: 7.5vw;
    max-width: 100%;
    margin-bottom: 40px;
  }
  .services-grid {
    grid-template-columns: 1fr;
    gap: 0;
  }
  .service-item {
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
    padding: 16px 0;
  }
  .service-name { font-size: 3.6vw; white-space: normal; }
  .service-desc {
    font-size: 3.6vw;
    opacity: 1;
    transform: none;
  }
  .service-item:hover .service-desc {
    opacity: 1;
    transform: none;
  }

  /* Footer */
  .footer {
    grid-template-columns: 1fr;
    padding: 60px 24px 40px;
    gap: 40px;
  }
  .footer-right {
    align-items: flex-start;
    text-align: left;
  }
  .footer-headline { font-size: 6.5vw; }
  .footer-sub      { font-size: 6.5vw; }
  .footer-email    { font-size: 3.5vw; }
  .footer-copy     { font-size: 3vw; padding-top: 40px; }
  .footer-icon     { width: 160px; }

  /* Coming Soon — bump the centered text up from the tiny desktop 1.5vw */
  .coming-soon-text { font-size: 6vw; }

  /* About Hero */
  .about-hero { padding: 150px 24px 60px; }
  .about-hero-heading {
    font-size: 4.8vw;
    line-height: var(--lh-body);
    max-width: 100%;
    padding: 0;   /* full content width on phones; the section's 24px inset is enough */
  }

  /* About Images — collage collapses to a staggered 2-column grid.
     Selectors carry the section class so they outrank the desktop
     `.about-img-wrap:nth-child()` placement rules. */
  .about-images {
    position: static;
    aspect-ratio: auto;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    padding: 24px;
  }
  .about-images .about-img-wrap {
    position: static;
    left: auto;
    top: auto;
    width: auto;
    height: auto;
    aspect-ratio: 3/4;
  }
  .about-images .about-img-wrap:nth-child(even) { margin-top: 36px; } /* offset for collage feel */

  /* About Copy */
  .about-copy { padding: 60px 24px; }
  .about-copy p {
    font-size: 4vw;
    max-width: 100%;
    line-height: 1.2;
  }

  /* Founder */
  .founder { padding: 60px 24px 80px; }
  .founder-grid {
    grid-template-columns: 1fr;
    gap: 36px;
  }
  .founder-text {
    text-align: left;
    padding-left: 0;
    order: 2;
    width: 100%;
    justify-self: start;
  }
  .founder-photo { order: 1; }
  .founder-text p.founder-label {
    text-align: left;
    font-size: 3.5vw;
    margin-bottom: 24px;
  }
  .founder-text p { font-size: 4vw; line-height: var(--lh-body); }
  .founder-link {
    font-size: 4vw;
    align-self: flex-start;
  }

  /* Expertise */
  .expertise {
    grid-template-columns: 1fr;
    padding: 60px 24px;
    gap: 0;
  }
  .expertise-left { position: static; }
  .expertise-img-area { display: none; }
  .expertise-label {
    font-size: 3.5vw;
    margin-bottom: 24px;
  }
  .expertise-list { padding-top: 0; }
  .expertise-name {
    font-size: 3.5vw;
    white-space: normal;
  }
  .expertise-desc {
    font-size: 3.4vw;
    line-height: var(--lh-body);
    letter-spacing: var(--ls-body);
    opacity: 1;
    max-height: 500px;
    margin-top: 12px;
  }
  .expertise-item-img {
    display: block;
    width: 100%;
    aspect-ratio: 1/1;
    overflow: hidden;
    margin-top: 16px;
  }
  .expertise-item-img img {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  /* Clients */
  .clients { padding: 60px 24px; }
  .clients--tight { padding-top: 32px; padding-bottom: 56px; }
  .clients .logo-marquee { width: auto; } /* keep the about banner full-width on mobile — the 75vw is desktop-only */

  /* FAQ */
  .faq { padding: 60px 24px; }
  .faq-heading  { font-size: 3.5vw; margin-bottom: 32px; }
  .faq-question { font-size: 4.2vw; }
  .faq-answer   { font-size: 3.8vw; line-height: var(--lh-body); max-width: 100%; padding-left: 28px; }
  .faq-toggle   { font-size: 4.2vw; }

  /* ── Case Study (Kylie) ─────────────────────────────────── */
  /* Header */
  .cs-header { padding: 110px 24px 40px; }
  .cs-title { font-size: 7.5vw; line-height: var(--lh-body); margin-bottom: 28px; }
  .cs-header-body {
    min-height: 0;
    display: flex;
    flex-direction: column;
  }

  /* Unwrap .cs-desc so its paragraph and the View More button become direct
     flex children of the header body — lets us order the button after the
     Services meta instead of right under the description. */
  .cs-desc { display: contents; }
  .cs-desc p { order: 1; width: 100%; font-size: 4vw; line-height: var(--lh-body); }

  /* Meta drops out of its absolute, nav-aligned columns into normal flow */
  .cs-meta {
    order: 2;
    position: static;
    margin-top: 32px;
    display: flex;
    flex-direction: column;
    gap: 28px;
  }
  .cs-meta-col,
  .cs-meta-col:first-child,
  .cs-meta-col:last-child {
    position: static;
    left: auto;
  }
  .cs-meta-label { font-size: 3vw; }
  .cs-meta-value { font-size: 3.8vw; }

  /* View More: simple in-flow toggle, no slide/sticky animation.
     order:3 + align-self places it at the bottom of the header, under Services. */
  .cs-viewmore-btn {
    order: 3;
    align-self: flex-start;
    margin-top: 28px;
    font-size: 3.6vw;   /* ~20% larger, matching the desktop bump */
    gap: 10px;
    padding: 5px 10px;
  }
  .cs-viewmore-icon { font-size: 1em; }   /* same size as the label beside it */
  .cs-viewmore-btn.is-stuck { position: static; left: auto; top: auto; margin-top: 5px; }

  .cs-expand-wrap { flex-direction: column; }

  /* View More panel slides down/up: grid-template-rows 0fr→1fr animates to the
     content's natural height (no magic numbers). The inner is the collapsing
     track — overflow:hidden + min-height:0, with vertical padding applied only
     when open so it shuts completely to 0. */
  .cs-expand-panel {
    flex: 0 0 auto;
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.55s cubic-bezier(0.76, 0, 0.24, 1);
  }
  .cs-expand-wrap.expanded .cs-expand-panel { grid-template-rows: 1fr; }
  .cs-expand-panel-inner {
    width: 100%;
    position: static;
    transform: none;
    pointer-events: auto;
    overflow: hidden;
    min-height: 0;
    gap: 14px;
    padding: 0 24px;
    opacity: 0;
    transition: padding 0.55s cubic-bezier(0.76, 0, 0.24, 1),
                opacity 0.4s ease;
  }
  .cs-expand-wrap.expanded .cs-expand-panel-inner {
    padding: 24px 24px 28px;
    opacity: 1;
  }
  .cs-expand-title { font-size: 6vw; }
  .cs-expand-panel-inner p { font-size: 4vw; line-height: var(--lh-body); }
  .cs-contributors { margin-top: 10vw; }
  .cs-contributors-list { column-gap: 4vw; row-gap: 4vw; }
  .cs-contributors-list li { font-size: 4vw; line-height: var(--lh-body); }

  /* Hero stack */
  .cs-hero { width: 100%; aspect-ratio: 4 / 3; }
  /* Match the 16:9 source so object-fit:cover doesn't crop the sides tight —
     a 4/3 box was too tall for the wide video. */
  .cs-hero-video { aspect-ratio: 16 / 9; }
  .cs-hero-stack { gap: 12px; }
  .cs-2colimgrow { width: 100%; flex-direction: column; gap: 12px; }
  /* Social row wraps to a 2×2 grid on mobile instead of four thin slivers. */
  .cs-4colimgrow { width: 100%; flex-wrap: wrap; gap: 12px; }
  .cs-4colimgrow-img { flex: 1 1 calc(50% - 6px); }

  .cs-youtube-video { width: 100%; aspect-ratio: 16 / 10; margin: 40px auto; }
  .cs-campaign-video { width: 60%; margin: 20px auto; }
  .cs-campaign-video--wide { width: 72%; }
  /* Two-up row: each video shares the width so the pair fits side by side. */
  .cs-campaign-video-row .cs-campaign-video--wide { width: 46%; }

  /* Deliverables: single column, header stacked above the images (no sticky
     stacking / collapse — that JS is disabled on mobile) */
  .cs-deliverables {
    grid-template-columns: 1fr;
    padding: 56px 24px 80px;
    row-gap: 56px;
  }
  .cs-row { display: block; }
  .cs-row-left {
    position: static;
    top: auto;
    padding-bottom: 18px;
    margin-bottom: 20px;
  }
  .cs-row-body { overflow: visible; }
  /* Headers aren't interactive on mobile (the click-to-scroll JS is off) —
     drop the pointer cursor and hover fade, and disable pointer events entirely
     so a tap can't trigger a scroll-jump even if a stale listener is attached
     (e.g. page loaded wide then narrowed without a reload). */
  .cs-row-hdr {
    gap: 12px;
    margin-bottom: 16px;
    cursor: default;
    pointer-events: none;
  }
  .cs-row-hdr:hover { opacity: 1; }
  .cs-row-num,
  .cs-row-label { font-size: 3.2vw; }
  .cs-row-desc { font-size: 4.2vw; }
  .cs-row-products-title { font-size: 3vw; }
  .cs-row-products-list li { font-size: 3.8vw; }
  .cs-row-right { gap: 12px; }

  /* Expertise — What We Do (full-width heading, then cards; cards stack label/body) */
  .wwd-hero { padding: 150px 24px 40px; }
  /* .wwd-title keeps its desktop clamp on mobile to match the /work/ heading */
  .wwd {
    grid-template-columns: 1fr;
    padding: 0 24px 72px;
  }
  .wwd-cards { grid-column: auto; gap: 40px; }
  .wwd-card {
    grid-template-columns: 1fr;
    row-gap: 12px;
  }
  .wwd-label { font-size: 3vw; }
  .wwd-body  { font-size: 4vw; max-width: 100%; }

  /* Contact — lead + CTA stack full-width */
  /* Cap the vw scale so the body copy stays well below the ~34px H1 at the
     768px top edge of this breakpoint (raw 4.4vw would hit ~34px there). */
  .contact-lead { font-size: clamp(16px, 4.4vw, 21px); width: 100%; max-width: 100%; margin-top: 24px; }
  .contact-cta-line { font-size: clamp(16px, 4.4vw, 21px); margin-top: 12px; }

  /* Industries / Services — stack the two columns; title over a full-width list.
     Extra top padding here (not on the shared .clients bottom padding) since
     .clients also backs the about page's FAQ section with different spacing needs. */
  .ind-serv {
    grid-template-columns: 1fr;
    row-gap: 44px;
    padding: 28px 24px 72px;
  }
  .ind-serv-heading { font-size: 7vw; }   /* was 9vw — nearly matched the H1 (wwd-title is ~9vw-equivalent at this width) */
  /* Single-column stack: Industries / Design / Strategy / Content read as equal
     sections. 44px between sections (matches the grid row-gap between the two
     cols) so every section — including the groups inside the 2nd col — is
     evenly separated; title→list inside a section stays tight at 12px. */
  .ind-serv-col {
    flex-direction: column;
    gap: 44px;
  }
  .ind-serv-col:first-of-type { padding-left: 0; }   /* left-align Industries with the others */
  .ind-serv-group {
    flex-direction: column;
    gap: 12px;
  }
  .ind-serv-title { font-size: 3vw; }
  .ind-serv-list  { width: 100%; margin-left: 0; }
  .ind-serv-list li { font-size: 4vw; }

  /* Disable all hover effects on touch */
  .nav-link:hover::after          { transform: scaleX(0); }
  .view-more:hover::after         { transform: scaleX(0); }
  .founder-link:hover::after      { transform: scaleX(0); }
  .work-item:hover .work-title::after { transform: scaleX(0); }
  .work-item:hover .work-img-wrap img { transform: none; }
  .work-img-wrap:hover            { cursor: auto; }
  .service-item:hover             { border-color: rgba(var(--graphite-rgb), 0.25); }
}
