/* ============================================================
   Conkrete — site.css (single source of truth for the design system)
   Tokens, chrome (nav/footer), and all page styles. Loaded by every
   page via inc/header.php. The six brand tokens are unchanged.
   ============================================================ */


/* ---------- SELF-HOSTED FONTS ----------
   The exact type DNA of the live site (Cormorant Garamond + Inter), served
   from our own origin (assets/fonts/*.woff2). This replaces the Google Fonts
   CDN <link> — same fonts, same feel, no third-party request, POPIA-clean.
   font-display:swap so text paints immediately in the fallback and swaps in. */
@font-face {
  font-family: "Cormorant Garamond";
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url("../fonts/cormorant-garamond-300.woff2") format("woff2");
}
@font-face {
  font-family: "Cormorant Garamond";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/cormorant-garamond-400.woff2") format("woff2");
}
@font-face {
  font-family: "Cormorant Garamond";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/cormorant-garamond-500.woff2") format("woff2");
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/inter-400.woff2") format("woff2");
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/inter-500.woff2") format("woff2");
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/inter-600.woff2") format("woff2");
}


/* ---------- TOKENS ---------- */
:root {
  --c-bone: #EFEBE4;
  --c-stone: #C9C2B6;
  --c-ash: #6E6A63;
  --c-graphite: #2B2A28;
  --c-coal: #141312;
  --c-rust: #8C4A2B;
  /* Accessible body-text variant of --c-ash for use on the bone background.
     ~4.6:1 on --c-bone (WCAG AA). The six brand tokens above are unchanged;
     --c-ash is retained for decorative/large-text and dark-section contexts. */
  --c-ash-readable: #5A5750;

  --f-serif: "Cormorant Garamond", "Times New Roman", serif;
  --f-sans: "Inter", system-ui, -apple-system, sans-serif;

  --s-1: 0.25rem; --s-2: 0.5rem; --s-3: 0.75rem; --s-4: 1rem;
  --s-5: 1.5rem; --s-6: 2rem; --s-7: 3rem; --s-8: 5rem; --s-9: 8rem;

  --container: 1280px;
  --section-y: clamp(4rem, 10vw, 8rem);
  --section-x: clamp(1.25rem, 5vw, 3rem);
}

/* ---------- RESET ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--f-sans);
  font-size: 1rem;
  line-height: 1.6;
  color: var(--c-graphite);
  background: var(--c-bone);
  overflow-x: hidden;   /* safety net against full-bleed overflow at small widths */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font-family: inherit; }

/* ---------- TYPOGRAPHY ---------- */
h1, h2, h3, h4 { font-family: var(--f-serif); font-weight: 400; margin: 0; line-height: 1.15; letter-spacing: -0.01em; }
h1 { font-size: clamp(1.782rem, 4.277vw, 3.564rem); font-weight: 300; }
h2 { font-size: clamp(1.426rem, 2.851vw, 2.138rem); }
h3 { font-size: 1.5rem; }
p { margin: 0; }
.eyebrow { font: 500 0.75rem/1 var(--f-sans); text-transform: uppercase; letter-spacing: 0.15em; color: var(--c-ash-readable); margin: 0 0 var(--s-4); }
.lede { font-size: 1.125rem; color: var(--c-ash-readable); max-width: 60ch; margin-top: var(--s-4); }

/* ---------- LAYOUT ---------- */
.section { padding: var(--section-y) var(--section-x); }
.container { max-width: var(--container); margin: 0 auto; width: 100%; }

/* ---------- BUTTONS ---------- */
.btn-primary, .btn-ghost {
  display: inline-block;
  padding: 0.9rem 1.75rem;
  font: 500 0.875rem/1 var(--f-sans);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.2s, color 0.2s, border-color 0.2s;
  text-align: center;
  border: 1px solid transparent;
}
.btn-primary { background: var(--c-graphite); color: var(--c-bone); }
.btn-primary:hover { background: var(--c-coal); }
.btn-ghost { background: transparent; color: var(--c-graphite); border-color: var(--c-graphite); }
.btn-ghost:hover { background: var(--c-graphite); color: var(--c-bone); }

/* ---------- IMAGE SLOTS ---------- */
.img-slot {
  position: relative;
  background:
    linear-gradient(135deg, var(--c-stone) 0%, var(--c-bone) 60%, var(--c-stone) 100%);
  background-size: 200% 200%;
  overflow: hidden;
  width: 100%;
}
.img-slot::before {
  content: "";
  display: block;
  padding-bottom: calc(100% / (var(--ratio, 1)));
}
.img-slot[data-ratio="1/1"]    { --ratio: 1; }
.img-slot[data-ratio="4/3"]    { --ratio: 1.333; }
.img-slot[data-ratio="3/2"]    { --ratio: 1.5; }
.img-slot[data-ratio="16/9"]   { --ratio: 1.778; }
.img-slot[data-ratio="3/4"]    { --ratio: 0.75; }
.img-slot[data-ratio="2/3"]    { --ratio: 0.667; }
.img-slot[data-ratio="21/9"]   { --ratio: 2.333; }
.img-slot::after {
  content: attr(data-img);
  position: absolute; inset: auto 0 0.5rem 0;
  text-align: center;
  font: 500 0.65rem/1 var(--f-sans);
  color: var(--c-ash);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.6;
}
/* height:auto is load-bearing. Slot images carry width/height attributes for
   CLS, and without this the attribute height wins, aspect-ratio is ignored,
   and the box renders at the intrinsic pixel height — which crops the image
   to an arbitrary shape. */
img.img-slot { object-fit: cover; aspect-ratio: var(--ratio); height: auto; }
img.img-slot::before, img.img-slot::after { display: none; }

/* ---------- NAV ---------- */
.site-nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  padding: var(--s-4) var(--section-x);
  background: rgba(239, 235, 228, 0.85);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s, background 0.3s;
}
.site-nav.is-scrolled { border-bottom-color: var(--c-stone); }
.nav-inner {
  max-width: var(--container);
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
}
.nav-brand {
  font-family: var(--f-serif);
  font-size: 1.5rem;
  font-weight: 400;
  letter-spacing: 0.02em;
  color: var(--c-graphite);
}
.nav-links {
  display: flex;
  gap: var(--s-6);
  list-style: none;
  margin: 0;
  padding: 0;
}
.nav-links a {
  font: 500 0.8rem/1 var(--f-sans);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--c-graphite);
  padding: var(--s-2) 0;
  position: relative;
}
.nav-links a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: var(--c-graphite);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.25s ease;
}
.nav-links a:hover::after { transform: scaleX(1); }
.nav-links a[aria-current="page"] { color: var(--c-graphite); }
.nav-links a[aria-current="page"]::after { transform: scaleX(1); }
.nav-cta { display: none; }
.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  background: transparent;
  border: none;
  cursor: pointer;
  padding: var(--s-2);
  color: var(--c-graphite);
}
.nav-toggle svg { width: 24px; height: 24px; }

@media (min-width: 960px) {
  .nav-cta { display: inline-block; padding: 0.6rem 1.25rem; font-size: 0.75rem; }
}

@media (max-width: 880px) {
  .nav-links {
    position: fixed;
    inset: 64px 0 auto 0;
    flex-direction: column;
    gap: 0;
    background: var(--c-bone);
    border-bottom: 1px solid var(--c-stone);
    padding: var(--s-5) var(--section-x) var(--s-6);
    transform: translateY(-110%);
    transition: transform 0.3s ease;
    box-shadow: 0 8px 24px rgba(0,0,0,0.04);
  }
  .nav-links.is-open { transform: translateY(0); }
  .nav-links li { border-bottom: 1px solid var(--c-stone); }
  .nav-links li:last-child { border-bottom: none; }
  .nav-links a { display: block; padding: var(--s-4) 0; }
  .nav-toggle { display: inline-flex; }
}

section[id] { scroll-margin-top: 72px; }
main { padding-top: 64px; }

/* ---------- FOOTER ---------- */
.site-footer {
  background: var(--c-graphite);
  color: var(--c-stone);
  padding: var(--s-8) var(--section-x) var(--s-5);
}
.footer-inner {
  max-width: var(--container);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-7);
}
@media (min-width: 720px) {
  .footer-inner { grid-template-columns: 2fr 1fr 1fr 1fr; }
}
.footer-brand h3 {
  font-family: var(--f-serif);
  font-size: 1.75rem;
  color: var(--c-bone);
  margin-bottom: var(--s-3);
}
.footer-brand p { max-width: 36ch; font-size: 0.95rem; color: var(--c-stone); }
.footer-col h4 {
  font: 500 0.75rem/1 var(--f-sans);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--c-bone);
  margin-bottom: var(--s-4);
}
.footer-col ul { list-style: none; padding: 0; margin: 0; }
.footer-col li { margin-bottom: var(--s-3); }
.footer-col a {
  color: var(--c-stone);
  font-size: 0.9rem;
  transition: color 0.2s;
}
.footer-col a:hover { color: var(--c-bone); }
.footer-base {
  max-width: var(--container);
  margin: var(--s-7) auto 0;
  padding-top: var(--s-5);
  border-top: 1px solid rgba(239, 235, 228, 0.15);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
  justify-content: space-between;
  font-size: 0.8rem;
  color: rgba(239, 235, 228, 0.6);
}

/* ---------- A11Y ---------- */
:focus-visible {
  outline: 2px solid var(--c-rust);
  outline-offset: 3px;
  box-shadow: 0 0 0 4px rgba(140, 74, 43, 0.15);
}
.site-footer :focus-visible,
.landing-materials :focus-visible,
.landing-cta :focus-visible,
.landing-hero :focus-visible {
  outline-color: var(--c-bone);
  box-shadow: 0 0 0 4px rgba(239, 235, 228, 0.2);
}
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--c-graphite);
  color: var(--c-bone);
  padding: var(--s-3) var(--s-4);
  z-index: 200;
}
.skip-link:focus { left: var(--s-4); top: var(--s-4); }

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

/* ---------- LANDING ---------- */
  .landing-hero {
    position: relative;
    min-height: 100vh;
    min-height: 100svh;
    display: flex;
    align-items: flex-end;
    color: var(--c-bone);
    padding: 0;
    overflow: hidden;
  }
  .landing-hero .img-slot {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    /* placeholder uses the same bone/stone gradient as every other slot,
       so it's obvious where the hero image goes. When you swap the <div>
       for an <img>, this background is hidden by the photo. */
  }
  .landing-hero .img-slot::before { display: none; }
  .landing-hero .img-slot::after {
    /* show the slot label centred and large enough to read */
    inset: 50% 0 auto 0;
    transform: translateY(-50%);
    font-size: 0.85rem;
    color: var(--c-ash);
    opacity: 0.9;
    letter-spacing: 0.15em;
  }
  /* once a real <img> lands in the slot, hide the label */
  .landing-hero img.img-slot::after { display: none; }
  .landing-hero .hero-overlay {
    position: absolute;
    inset: 0;
    /* light overlay so the placeholder remains visible.
       When you swap in a real hero image, change this to:
       background: linear-gradient(180deg, rgba(20,19,18,0.35) 0%, rgba(20,19,18,0.45) 50%, rgba(20,19,18,0.8) 100%);
       (or just remove the .has-image class trick below) */
    background: linear-gradient(
      180deg,
      rgba(239, 235, 228, 0) 0%,
      rgba(239, 235, 228, 0) 40%,
      rgba(20, 19, 18, 0.55) 100%
    );
  }
  /* Once a real <img> is in place, a scrim kicks in for legibility. The hero
     plate is already a low-key studio, so a heavy scrim across the top just
     crushes the cast top into the room — weight it almost entirely to the
     bottom band, where the copy actually sits. */
  .landing-hero:has(img.img-slot) .hero-overlay {
    background: linear-gradient(
      180deg,
      rgba(20,19,18,0.10) 0%,
      rgba(20,19,18,0.22) 45%,
      rgba(20,19,18,0.74) 100%
    );
  }
  /* LIGHT HERO — the studio plate is a pale grey sweep, so the black scrim
     above would crush exactly the grey the piece is set in. Keep the backdrop,
     lift the lower band just enough to seat the copy, and leave the type dark.
     Overrides sit after the :has(img) rules further down. */
  .landing-hero.hero--light:has(img.img-slot) .hero-overlay {
    background: linear-gradient(
      180deg,
      rgba(239, 235, 228, 0) 40%,
      rgba(239, 235, 228, 0.38) 72%,
      rgba(239, 235, 228, 0.72) 100%
    );
  }
  .landing-hero .container {
    position: relative;
    padding: var(--s-9) var(--section-x) var(--s-8);
    width: 100%;
  }
  /* hero text — dark while placeholder shows, switches to bone once a real image is in place */
  /* graphite (not ash) so hero copy clears WCAG AA over the stone areas of the
     bone→stone placeholder gradient; the :has(img) rules below flip to bone once
     a real hero photo lands. */
  .landing-hero .eyebrow { color: var(--c-graphite); }
  .landing-hero h1 {
    max-width: 14ch;
    margin-bottom: var(--s-5);
    color: var(--c-graphite);
  }
  .landing-hero .hero-sub {
    font-size: 1.125rem;
    max-width: 44ch;
    color: var(--c-graphite);
    margin-bottom: var(--s-7);
  }
  .landing-hero .hero-ctas {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-3);
  }
  /* placeholder state: graphite primary button on bone background */
  .landing-hero .btn-primary {
    background: var(--c-graphite);
    color: var(--c-bone);
  }
  .landing-hero .btn-primary:hover { background: var(--c-coal); }
  .landing-hero .btn-ghost {
    color: var(--c-graphite);
    border-color: var(--c-graphite);
  }
  .landing-hero .btn-ghost:hover {
    background: var(--c-graphite);
    color: var(--c-bone);
    border-color: var(--c-graphite);
  }
  /* once a real image is in place, flip to the dark-bg styling */
  .landing-hero:has(img.img-slot) .eyebrow { color: rgba(239, 235, 228, 0.7); }
  .landing-hero:has(img.img-slot) h1 { color: var(--c-bone); }
  .landing-hero:has(img.img-slot) .hero-sub { color: rgba(239, 235, 228, 0.85); }
  .landing-hero:has(img.img-slot) .btn-primary {
    background: var(--c-bone);
    color: var(--c-graphite);
  }
  .landing-hero:has(img.img-slot) .btn-primary:hover { background: #fff; }
  .landing-hero:has(img.img-slot) .btn-ghost {
    color: var(--c-bone);
    border-color: rgba(239, 235, 228, 0.6);
  }
  .landing-hero:has(img.img-slot) .btn-ghost:hover {
    background: var(--c-bone);
    color: var(--c-graphite);
    border-color: var(--c-bone);
  }
  /* ...and back to dark type over the light plate. These follow the :has(img)
     block on purpose — same specificity, later wins. */
  /* graphite, not --c-ash-readable: that token is tuned for the bone body
     background and only reaches ~4.1:1 over the hero plate's mid-grey floor,
     which misses AA for 12px type. Graphite clears 8:1. */
  .landing-hero.hero--light:has(img.img-slot) .eyebrow { color: var(--c-graphite); }
  .landing-hero.hero--light:has(img.img-slot) h1 { color: var(--c-coal); }
  .landing-hero.hero--light:has(img.img-slot) .hero-sub { color: var(--c-graphite); }
  .landing-hero.hero--light:has(img.img-slot) .btn-primary {
    background: var(--c-graphite);
    color: var(--c-bone);
  }
  .landing-hero.hero--light:has(img.img-slot) .btn-primary:hover { background: var(--c-coal); }
  .landing-hero.hero--light:has(img.img-slot) .btn-ghost {
    color: var(--c-graphite);
    border-color: rgba(43, 42, 40, 0.5);
  }
  .landing-hero.hero--light:has(img.img-slot) .btn-ghost:hover {
    background: var(--c-graphite);
    color: var(--c-bone);
    border-color: var(--c-graphite);
  }
  .hero-scroll {
    position: absolute;
    left: 50%;
    bottom: var(--s-5);
    transform: translateX(-50%);
    color: var(--c-graphite);
    font: 500 0.7rem/1 var(--f-sans);
    letter-spacing: 0.2em;
    text-transform: uppercase;
    writing-mode: vertical-rl;
    padding-bottom: 40px;
  }
  .hero-scroll::after {
    content: "";
    position: absolute;
    left: 50%;
    bottom: 0;
    width: 1px;
    height: 32px;
    background: var(--c-ash);
    opacity: 0.5;
  }
  .landing-hero:has(img.img-slot) .hero-scroll { color: rgba(239, 235, 228, 0.6); }
  .landing-hero:has(img.img-slot) .hero-scroll::after { background: rgba(239, 235, 228, 0.4); opacity: 1; }

  /* story */
  .landing-story .story-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s-7);
    align-items: center;
  }
  @media (min-width: 880px) {
    .landing-story .story-grid {
      grid-template-columns: 5fr 6fr;
      gap: var(--s-9);
    }
  }
  .landing-story .story-text p {
    margin-bottom: var(--s-4);
    color: var(--c-ash-readable);
    max-width: 52ch;
  }
  .landing-story .story-text p:last-child { margin-bottom: 0; }

  /* materials */
  .landing-materials { background: var(--c-graphite); color: var(--c-bone); }
  .landing-materials .eyebrow { color: rgba(239, 235, 228, 0.6); }
  .landing-materials h2 { color: var(--c-bone); }
  .landing-materials .lede { color: rgba(239, 235, 228, 0.75); }
  .landing-materials .mat-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s-5);
    margin-top: var(--s-8);
  }
  @media (min-width: 720px) {
    .landing-materials .mat-grid { grid-template-columns: 1fr 1fr; gap: var(--s-6); }
  }
  .mat-card {
    border: 1px solid rgba(239, 235, 228, 0.15);
    padding: var(--s-6);
    display: flex;
    flex-direction: column;
  }
  @media (min-width: 720px) {
    .mat-card { padding: var(--s-7); }
  }
  .mat-card .mat-title {
    font-family: var(--f-serif);
    font-size: 3rem;
    font-weight: 300;
    line-height: 1;
    color: var(--c-bone);
    margin-bottom: var(--s-2);
  }
  .mat-card .mat-sub {
    font: 500 0.75rem/1 var(--f-sans);
    text-transform: uppercase;
    letter-spacing: 0.15em;
    color: rgba(239, 235, 228, 0.6);
    margin-bottom: var(--s-5);
  }
  .mat-card .mat-body {
    color: rgba(239, 235, 228, 0.85);
    margin-bottom: var(--s-5);
    max-width: 42ch;
  }
  .mat-card ul {
    list-style: none;
    padding: 0;
    margin: 0;
    border-top: 1px solid rgba(239, 235, 228, 0.15);
  }
  .mat-card li {
    padding: var(--s-3) 0;
    border-bottom: 1px solid rgba(239, 235, 228, 0.15);
    color: rgba(239, 235, 228, 0.85);
    font-size: 0.95rem;
    display: flex;
    align-items: center;
    gap: var(--s-3);
  }
  .mat-card li::before {
    content: "—";
    color: rgba(239, 235, 228, 0.85);
    font-weight: 500;
  }

  /* environmental */
  .landing-env { background: var(--c-bone); }
  .landing-env .env-stats {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s-5);
    margin: var(--s-8) 0 var(--s-7);
    border-top: 1px solid var(--c-stone);
    border-bottom: 1px solid var(--c-stone);
  }
  @media (min-width: 720px) {
    .landing-env .env-stats {
      grid-template-columns: repeat(3, 1fr);
      gap: 0;
    }
  }
  .env-stat {
    padding: var(--s-7) var(--s-5);
    text-align: left;
    border-bottom: 1px solid var(--c-stone);
  }
  .env-stat:last-child { border-bottom: none; }
  @media (min-width: 720px) {
    .env-stat {
      border-bottom: none;
      border-right: 1px solid var(--c-stone);
      padding: var(--s-7) var(--s-6);
    }
    .env-stat:last-child { border-right: none; }
  }
  .env-stat .stat-fig {
    font-family: var(--f-serif);
    font-size: clamp(2.5rem, 5vw, 3.75rem);
    font-weight: 300;
    line-height: 1;
    color: var(--c-graphite);
    margin-bottom: var(--s-3);
    letter-spacing: -0.02em;
  }
  .env-stat .stat-fig small {
    font-size: 0.45em;
    color: var(--c-ash-readable);
    margin-left: 0.25em;
  }
  .env-stat .stat-label {
    font: 500 0.75rem/1.3 var(--f-sans);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--c-ash-readable);
    max-width: 24ch;
  }
  .landing-env .env-close {
    max-width: 56ch;
    color: var(--c-ash-readable);
    font-size: 1.05rem;
  }
  .landing-env .env-close strong {
    color: var(--c-graphite);
    font-weight: 500;
  }

  /* product grid */
  .landing-products .prod-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--s-5);
    margin-bottom: var(--s-7);
  }
  .landing-products .prod-head h2 { max-width: 18ch; }
  .landing-products .prod-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s-5);
  }
  @media (min-width: 640px) {
    .landing-products .prod-grid { grid-template-columns: 1fr 1fr; }
  }
  @media (min-width: 960px) {
    .landing-products .prod-grid {
      grid-template-columns: repeat(6, 1fr);
    }
    .landing-products .prod-card:nth-child(1),
    .landing-products .prod-card:nth-child(2),
    .landing-products .prod-card:nth-child(3) { grid-column: span 2; }
    .landing-products .prod-card:nth-child(4),
    .landing-products .prod-card:nth-child(5) { grid-column: span 3; }
  }
  .prod-card {
    display: block;
    color: inherit;
    position: relative;
    transition: transform 0.4s ease;
  }
  .prod-card .img-slot { transition: filter 0.4s ease; }
  .prod-card:hover { transform: translateY(-4px); }
  .prod-card:hover .img-slot { filter: brightness(0.95); }
  .prod-card .prod-meta {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    margin-top: var(--s-4);
    gap: var(--s-4);
  }
  .prod-card .prod-name {
    font-family: var(--f-serif);
    font-size: 1.5rem;
    font-weight: 400;
  }
  .prod-card .prod-arrow {
    font: 500 0.75rem/1 var(--f-sans);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--c-ash-readable);
    transition: color 0.2s, transform 0.2s;
  }
  .prod-card:hover .prod-arrow {
    color: var(--c-graphite);
    transform: translateX(4px);
  }
  .prod-card .prod-teaser {
    color: var(--c-ash-readable);
    margin-top: var(--s-2);
    font-size: 0.95rem;
    max-width: 42ch;
  }

  /* social proof / testimonials */
  .landing-proof .proof-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s-6);
    margin-top: var(--s-8);
  }
  @media (min-width: 720px) {
    .landing-proof .proof-grid {
      grid-template-columns: repeat(3, 1fr);
      gap: var(--s-7);
    }
  }
  .proof-quote {
    display: flex;
    flex-direction: column;
    gap: var(--s-5);
    margin: 0;
    border-top: 1px solid var(--c-stone);
    padding-top: var(--s-5);
  }
  .proof-quote blockquote {
    margin: 0;
    font-family: var(--f-serif);
    font-weight: 400;
    font-size: 1.4rem;
    line-height: 1.3;
    color: var(--c-graphite);
  }
  .proof-quote figcaption {
    font: 500 0.75rem/1 var(--f-sans);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--c-ash-readable);
    margin-top: auto;
  }

  /* commission process */
  .landing-process .process-head { margin-bottom: var(--s-8); }
  .landing-process .process-head h2 { max-width: 18ch; }
  .landing-process .process-steps {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: 1fr;
  }
  @media (min-width: 720px) {
    .landing-process .process-steps { grid-template-columns: repeat(4, 1fr); }
  }
  .process-step {
    padding: var(--s-6) 0;
    border-top: 1px solid var(--c-stone);
  }
  @media (min-width: 720px) {
    .process-step {
      padding: var(--s-6) var(--s-5) var(--s-7) 0;
      margin-right: var(--s-5);
    }
  }
  .process-step .step-num {
    font-family: var(--f-serif);
    font-weight: 300;
    font-size: 2.5rem;
    line-height: 1;
    color: var(--c-graphite);
    margin-bottom: var(--s-4);
  }
  .process-step .step-name {
    display: block;
    font: 500 0.75rem/1 var(--f-sans);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--c-graphite);
    margin-bottom: var(--s-3);
  }
  .process-step .step-body {
    color: var(--c-ash-readable);
    font-size: 0.95rem;
    max-width: 28ch;
  }

  /* bottom CTA */
  .landing-cta {
    background: var(--c-graphite);
    color: var(--c-bone);
    text-align: center;
  }
  .landing-cta .eyebrow { color: rgba(239, 235, 228, 0.6); }
  .landing-cta h2 { color: var(--c-bone); }
  .landing-cta .lede {
    color: rgba(239, 235, 228, 0.75);
    margin: var(--s-4) auto var(--s-7);
    max-width: 48ch;
  }
  .landing-cta .btn-primary {
    background: var(--c-bone);
    color: var(--c-graphite);
  }
  .landing-cta .btn-primary:hover { background: #ffffff; }

/* ---------- LEGAL / CONTENT PAGE ---------- */
.legal { background: var(--c-bone); }
.legal .legal-inner { max-width: 760px; }
.legal .legal-head { margin-bottom: var(--s-7); }
.legal .legal-head h1 {
  font-size: clamp(1.604rem, 3.564vw, 2.495rem);
  margin-bottom: var(--s-4);
}
.legal .legal-updated {
  font: 500 0.75rem/1 var(--f-sans);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--c-ash-readable);
}
.legal .legal-lede {
  font-size: 1.125rem;
  color: var(--c-ash-readable);
  margin-top: var(--s-5);
  max-width: 62ch;
}
.legal section { margin-top: var(--s-7); }
.legal h2 { font-size: 1.75rem; margin-bottom: var(--s-4); }
.legal h3 {
  font-family: var(--f-sans);
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--c-graphite);
  margin: var(--s-5) 0 var(--s-3);
}
.legal p { color: var(--c-graphite); margin-bottom: var(--s-4); max-width: 68ch; }
.legal p:last-child { margin-bottom: 0; }
.legal ul { margin: 0 0 var(--s-4); padding-left: 0; list-style: none; max-width: 68ch; }
.legal li {
  position: relative;
  padding-left: var(--s-5);
  margin-bottom: var(--s-3);
  color: var(--c-graphite);
}
.legal li::before {
  content: "—";
  position: absolute;
  left: 0;
  color: var(--c-ash-readable);
}
.legal a {
  color: var(--c-rust);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.legal a:hover { color: var(--c-coal); }
.legal .legal-contact {
  margin-top: var(--s-7);
  padding: var(--s-6);
  border: 1px solid var(--c-stone);
}
.legal .legal-contact p { margin-bottom: var(--s-2); }

/* ---------- CONTACT ---------- */
.contact-section { background: var(--c-bone); }
.contact-head { max-width: 46ch; margin-bottom: var(--s-8); }
.contact-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-8);
}
@media (min-width: 880px) {
  .contact-grid { grid-template-columns: 5fr 7fr; gap: var(--s-9); align-items: start; }
}

/* aside */
.contact-aside h2 { font-size: 1.75rem; margin-bottom: var(--s-2); }
.contact-aside .contact-lines { list-style: none; margin: var(--s-6) 0 0; padding: 0; }
.contact-aside .contact-lines li { margin-bottom: var(--s-5); }
.contact-aside .contact-lines .label {
  display: block;
  font: 500 0.7rem/1 var(--f-sans);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--c-ash-readable);
  margin-bottom: var(--s-2);
}
.contact-aside .contact-lines a { color: var(--c-graphite); }
.contact-aside .contact-lines a:hover { color: var(--c-rust); }
.contact-note {
  margin-top: var(--s-6);
  padding-top: var(--s-5);
  border-top: 1px solid var(--c-stone);
  color: var(--c-ash-readable);
  font-size: 0.95rem;
  max-width: 42ch;
}

/* form */
.form-required-note { font-size: 0.85rem; color: var(--c-ash-readable); margin-bottom: var(--s-6); }
.form-required-note .req { color: var(--c-rust); }
.form-row { display: grid; grid-template-columns: 1fr; gap: var(--s-5); }
@media (min-width: 560px) { .form-row.cols-2 { grid-template-columns: 1fr 1fr; } }
.form-field { margin-bottom: var(--s-5); }
.form-field label {
  display: block;
  font: 500 0.72rem/1 var(--f-sans);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--c-graphite);
  margin-bottom: var(--s-3);
}
.form-field .req { color: var(--c-rust); }
.form-field input,
.form-field select,
.form-field textarea {
  width: 100%;
  font-family: var(--f-sans);
  font-size: 1rem;
  line-height: 1.5;
  color: var(--c-graphite);
  background: var(--c-bone);
  border: 1px solid var(--c-stone);
  border-radius: 0;
  padding: 0.8rem 0.9rem;
  transition: border-color 0.2s;
  -webkit-appearance: none;
  appearance: none;
}
.form-field select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%232B2A28' stroke-width='1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.9rem center;
  padding-right: 2.5rem;
}
.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus { border-color: var(--c-graphite); }
.form-field textarea { min-height: 11rem; resize: vertical; }

/* POPIA consent */
.form-consent {
  display: flex;
  gap: var(--s-3);
  align-items: flex-start;
  margin: var(--s-6) 0;
  font-size: 0.95rem;
  color: var(--c-graphite);
  max-width: 62ch;
}
.form-consent input {
  margin-top: 0.2rem;
  width: 1.15rem;
  height: 1.15rem;
  flex-shrink: 0;
  accent-color: var(--c-graphite);
}
.form-consent a { color: var(--c-rust); text-decoration: underline; text-underline-offset: 2px; }
.form-consent a:hover { color: var(--c-coal); }
.form-consent .req { color: var(--c-rust); }

/* honeypot — visually removed but present in the DOM for bots to fill */
.hp {
  position: absolute;
  left: -9999px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* status notes — rendered server-side by contact.php only when there is a
   message to show (success or error), so they are visible by default. */
.form-note {
  display: block;
  padding: var(--s-4) var(--s-5);
  margin-bottom: var(--s-6);
  border: 1px solid;
  font-size: 0.95rem;
  scroll-margin-top: 88px;
}
.form-note--ok { border-color: var(--c-graphite); color: var(--c-graphite); background: var(--c-stone); }
.form-note--err { border-color: var(--c-rust); color: var(--c-rust); }

/* post-submit banner — revealed client-side after contact-send.php redirects
   back with ?sent=1|0. Mirrors .form-note styling. */
.form-status {
  display: block;
  padding: var(--s-4) var(--s-5);
  margin-bottom: var(--s-6);
  border: 1px solid;
  font-size: 0.95rem;
  scroll-margin-top: 88px;
}
.form-status[data-state="ok"] { border-color: var(--c-graphite); color: var(--c-graphite); background: var(--c-stone); }
.form-status[data-state="err"] { border-color: var(--c-rust); color: var(--c-rust); }
.form-status p { margin: 0; }
.form-status a { color: inherit; text-decoration: underline; }

/* small utility — kept in CSS so no inline style= is needed (strict CSP). */
.mt-8 { margin-top: var(--s-8); }

/* ---------- SHARED PAGE HEAD (work / care / studio) ---------- */
.page-intro { background: var(--c-bone); }
.page-head { max-width: 52ch; }

/* ---------- WORK (product lines) ---------- */
.work-line { border-top: 1px solid var(--c-stone); }
.work-line .work-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-7);
  align-items: center;
}
@media (min-width: 880px) {
  .work-line .work-grid { grid-template-columns: 1fr 1fr; gap: var(--s-9); }
  .work-line--flip .work-media { order: 2; }
}
.work-line .work-num {
  font-family: var(--f-serif);
  font-weight: 300;
  font-size: 1.25rem;
  color: var(--c-ash-readable);
}
.work-line h2 { margin: var(--s-2) 0 var(--s-4); }
.work-line .work-body p { color: var(--c-ash-readable); margin-bottom: var(--s-4); max-width: 48ch; }
.work-line .work-specs {
  list-style: none;
  padding: 0;
  margin: var(--s-5) 0 var(--s-6);
  border-top: 1px solid var(--c-stone);
  max-width: 42ch;
}
.work-line .work-specs li {
  padding: var(--s-3) 0;
  border-bottom: 1px solid var(--c-stone);
  color: var(--c-graphite);
  font-size: 0.95rem;
  display: flex;
  gap: var(--s-3);
}
.work-line .work-specs li::before { content: "—"; color: var(--c-ash-readable); }
.work-line .work-cta {
  font: 500 0.8rem/1 var(--f-sans);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--c-graphite);
  border-bottom: 1px solid var(--c-graphite);
  padding-bottom: var(--s-2);
  transition: color 0.2s, border-color 0.2s;
}
.work-line .work-cta:hover { color: var(--c-rust); border-color: var(--c-rust); }

/* ---------- PROSE (care guide) ---------- */
.prose { max-width: 720px; }
.prose > section { margin-top: var(--s-7); }
.prose h2 { font-size: 1.75rem; margin-bottom: var(--s-4); }
.prose p { color: var(--c-graphite); margin-bottom: var(--s-4); max-width: 68ch; }
.prose p:last-child { margin-bottom: 0; }
.prose strong { font-weight: 500; }
.prose ul { margin: 0 0 var(--s-4); padding-left: 0; list-style: none; max-width: 68ch; }
.prose li { position: relative; padding-left: var(--s-5); margin-bottom: var(--s-3); color: var(--c-graphite); }
.prose li::before { content: "—"; position: absolute; left: 0; color: var(--c-ash-readable); }
.prose a { color: var(--c-rust); text-decoration: underline; text-underline-offset: 2px; }
.prose a:hover { color: var(--c-coal); }

/* ---------- STUDIO (reading & watching) ---------- */
.studio-list {
  list-style: none;
  padding: 0;
  margin: var(--s-7) 0 0;
  border-top: 1px solid var(--c-stone);
  max-width: 820px;
}
.studio-item {
  padding: var(--s-6) 0;
  border-bottom: 1px solid var(--c-stone);
  display: grid;
  gap: var(--s-2);
}
.studio-item .studio-kind {
  font: 500 0.7rem/1 var(--f-sans);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--c-ash-readable);
}
.studio-item h3 { font-size: 1.5rem; }
.studio-item p { color: var(--c-ash-readable); max-width: 64ch; }
.studio-item .studio-by { color: var(--c-graphite); font-size: 0.95rem; }

/* in-text links inside a lede paragraph */
.lede a { color: var(--c-rust); text-decoration: underline; text-underline-offset: 2px; }
.lede a:hover { color: var(--c-coal); }

/* ---------- FAQ ---------- */
.faq-list {
  margin: var(--s-7) 0 0;
  border-top: 1px solid var(--c-stone);
  max-width: 760px;
}
.faq-item {
  padding: var(--s-6) 0;
  border-bottom: 1px solid var(--c-stone);
}
.faq-item h2 { font-size: 1.375rem; margin-bottom: var(--s-3); }
.faq-item p { color: var(--c-ash-readable); max-width: 68ch; }
.faq-item a { color: var(--c-rust); text-decoration: underline; text-underline-offset: 2px; }
.faq-item a:hover { color: var(--c-coal); }

/* ============================================================
   ADDITIONS FOR THE STATIC BUILD
   New components only — none of the rules above are restyled.
   Consent banner, improved Care layout, improved Studio grid,
   and a shared quiet closing band. All on the light bone system.
   ============================================================ */

/* ---------- CONSENT BANNER (light) ---------- */
.consent {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 150;
  background: var(--c-bone);
  border-top: 1px solid var(--c-stone);
  box-shadow: 0 -8px 28px rgba(20, 19, 18, 0.07);
  padding: var(--s-5) var(--section-x);
}
.consent[hidden] { display: none; }
.consent__inner {
  max-width: var(--container);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  align-items: flex-start;
}
@media (min-width: 880px) {
  .consent__inner {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-7);
  }
}
.consent__text {
  font-size: 0.9rem;
  line-height: 1.55;
  color: var(--c-ash-readable);
  max-width: 72ch;
  margin: 0;
}
.consent__text strong { color: var(--c-graphite); font-weight: 500; }
.consent__text a { color: var(--c-rust); text-decoration: underline; text-underline-offset: 2px; }
.consent__text a:hover { color: var(--c-coal); }
.consent__actions {
  display: flex;
  gap: var(--s-3);
  flex-shrink: 0;
  flex-wrap: wrap;
}
.consent__actions .btn-primary,
.consent__actions .btn-ghost { padding: 0.7rem 1.35rem; }
/* Footer "Cookie preferences" — a link-styled button, not a boxed one */
.link-btn {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  color: inherit;
  font: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.link-btn:hover { color: var(--c-bone); }

/* ---------- CARE (improved editorial layout) ---------- */
.care { background: var(--c-bone); }
.care-intro {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-7);
  align-items: start;
}
@media (min-width: 880px) {
  .care-intro { grid-template-columns: 7fr 5fr; gap: var(--s-9); }
}
.care-intro .page-head { max-width: 46ch; }
.care-intro .page-head .lede { margin-bottom: 0; }

/* The care plate is held to the width of the 7fr lede column above it rather
   than running full-bleed, so its right edge lines up with the copy and the
   21:9 band stops dominating the page. Full width below the 880px breakpoint,
   where .care-intro collapses to a single column anyway. */
.care-plate { display: block; }
@media (min-width: 880px) {
  .care-plate { max-width: calc((100% - var(--s-9)) * 7 / 12); }
}

/* quick-reference summary card */
.care-summary {
  border: 1px solid var(--c-stone);
  padding: var(--s-6);
}
.care-summary h2 {
  font: 500 0.72rem/1 var(--f-sans);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--c-ash-readable);
  margin-bottom: var(--s-5);
}
.care-summary h3 {
  font: 500 0.72rem/1 var(--f-sans);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--c-graphite);
  margin: var(--s-5) 0 var(--s-3);
}
.care-summary h3:first-of-type { margin-top: 0; }
.care-summary ul { list-style: none; padding: 0; margin: 0; }
.care-summary li {
  position: relative;
  padding: var(--s-2) 0 var(--s-2) var(--s-5);
  color: var(--c-graphite);
  font-size: 0.95rem;
  border-bottom: 1px solid var(--c-stone);
}
.care-summary ul:last-of-type li:last-child { border-bottom: none; }
.care-summary li::before {
  content: "—";
  position: absolute;
  left: 0;
  color: var(--c-rust);
}

/* the six care topics as a card grid */
.care-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-5);
  margin-top: var(--s-8);
}
@media (min-width: 620px) {
  .care-grid { grid-template-columns: 1fr 1fr; gap: var(--s-6); }
}
@media (min-width: 960px) {
  .care-grid { grid-template-columns: repeat(3, 1fr); }
}
.care-card {
  border: 1px solid var(--c-stone);
  padding: var(--s-6);
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  background: var(--c-bone);
}
.care-card .care-num {
  font-family: var(--f-serif);
  font-weight: 300;
  font-size: 2.25rem;
  line-height: 1;
  color: var(--c-rust);
  letter-spacing: -0.01em;
}
.care-card h2 { font-size: 1.4rem; }
.care-card p { color: var(--c-ash-readable); font-size: 0.97rem; margin: 0; }
.care-card a { color: var(--c-rust); text-decoration: underline; text-underline-offset: 2px; }
.care-card a:hover { color: var(--c-coal); }

/* ---------- STUDIO (improved editorial grid) ---------- */
.studio-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-5);
  margin-top: var(--s-8);
}
@media (min-width: 720px) {
  .studio-grid { grid-template-columns: 1fr 1fr; gap: var(--s-6); }
}
@media (min-width: 980px) {
  .studio-grid { grid-template-columns: repeat(3, 1fr); }
}
.studio-card {
  border: 1px solid var(--c-stone);
  padding: var(--s-6);
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  background: var(--c-bone);
}
.studio-card .studio-kind {
  font: 500 0.7rem/1 var(--f-sans);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--c-rust);
}
.studio-card h2,
.studio-card h3 { font-size: 1.5rem; }
.studio-card .studio-by {
  color: var(--c-graphite);
  font-size: 0.9rem;
  font-weight: 500;
}
.studio-card .studio-note { color: var(--c-ash-readable); font-size: 0.97rem; margin: 0; }
/* featured first item spans the row and reads larger */
.studio-card--feature { gap: var(--s-5); }
.studio-card--feature h2 { font-size: 1.9rem; }
.studio-feature-head { display: flex; flex-direction: column; gap: var(--s-3); }
.studio-feature-body { display: flex; flex-direction: column; gap: var(--s-4); }
@media (min-width: 720px) {
  .studio-card--feature {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: 5fr 6fr;
    gap: var(--s-8);
    align-items: center;
    padding: var(--s-7);
  }
  .studio-card--feature h2 { font-size: clamp(2rem, 3.5vw, 2.75rem); }
}

/* ---------- SHARED QUIET CLOSING BAND (care / studio) ---------- */
.soft-cta {
  border-top: 1px solid var(--c-stone);
  margin-top: var(--s-8);
  padding-top: var(--s-7);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-5);
}
.soft-cta p {
  font-family: var(--f-serif);
  font-weight: 400;
  font-size: clamp(1.4rem, 2.5vw, 1.9rem);
  line-height: 1.25;
  color: var(--c-graphite);
  max-width: 26ch;
}
.soft-cta .work-cta { white-space: nowrap; }

/* ---- Studio: "Read the piece" modal essay (David Pye) --------------------- */
.reading-trigger {
  margin-top: var(--s-4);
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  min-height: 44px;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  font: 500 0.72rem/1 var(--f-sans);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--c-rust);
}
.reading-trigger span { transition: transform 0.25s ease; }
.reading-trigger:hover { color: var(--c-graphite); }
.reading-trigger:hover span { transform: translateX(3px); }
.reading-trigger:focus-visible { outline: 2px solid var(--c-rust); outline-offset: 3px; }

.reading-dialog {
  position: relative;
  width: min(680px, calc(100vw - 2rem));
  max-height: min(88vh, 920px);
  padding: 0;
  border: 1px solid var(--c-stone);
  border-radius: 2px;
  background: var(--c-bone);
  color: var(--c-graphite);
  box-shadow: 0 40px 90px -30px rgba(20, 19, 18, 0.55);
}
.reading-dialog::backdrop {
  background: rgba(20, 19, 18, 0.55);
  backdrop-filter: blur(2px);
}
.reading-dialog__inner {
  max-height: min(88vh, 920px);
  overflow-y: auto;
  padding: clamp(1.75rem, 4vw, 3rem);
}
.reading-dialog__close {
  position: absolute;
  top: 0.6rem;
  right: 0.6rem;
  z-index: 3;
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--c-bone);
  border: 1px solid var(--c-stone);
  border-radius: 50%;
  color: var(--c-graphite);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
}
.reading-dialog__close:hover {
  background: var(--c-graphite);
  color: var(--c-bone);
  border-color: var(--c-graphite);
}
.reading-dialog__close:focus-visible { outline: 2px solid var(--c-rust); outline-offset: 2px; }
.reading-dialog__title {
  margin: var(--s-2) 0 0;
  padding-right: 2.5rem;
  font-size: clamp(1.5rem, 3vw, 1.9rem);
}
.reading-dialog__by {
  margin: var(--s-2) 0 var(--s-5);
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--c-graphite);
}

.reading-article {
  max-width: 62ch;
  color: var(--c-graphite);
}
.reading-article p { margin: 0 0 var(--s-4); font-size: 1rem; line-height: 1.75; }
.reading-article p:last-child { margin-bottom: 0; }
.reading-article em { font-style: italic; }
.reading-article .reading-lead::first-letter {
  font-family: var(--f-serif);
  font-weight: 500;
  font-size: 3.1em;
  line-height: 0.78;
  float: left;
  margin: 0.06em 0.14em 0 0;
  color: var(--c-graphite);
}
.reading-sign {
  margin-top: var(--s-5);
  padding-top: var(--s-4);
  border-top: 1px solid var(--c-stone);
  font-family: var(--f-serif);
  font-style: italic;
  font-size: 1.25rem;
  line-height: 1.4;
}
.reading-sign span { display: block; }
.reading-sign .reading-sign__tag {
  font-family: var(--f-sans);
  font-style: normal;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--c-rust);
  margin-top: var(--s-3);
}
@media (prefers-reduced-motion: no-preference) {
  .reading-dialog[open] { animation: reading-pop 0.32s ease both; }
  .reading-dialog[open]::backdrop { animation: reading-fade 0.32s ease both; }
  @keyframes reading-pop { from { opacity: 0; transform: translateY(10px) scale(0.99); } to { opacity: 1; transform: none; } }
  @keyframes reading-fade { from { opacity: 0; } to { opacity: 1; } }
}

/* ---------- MEMORIAL SPEC (work.html #hermanus-cross) ----------
   A product page's worth of detail inside the Work page: one realistic plate,
   the dimensioned drawings, and the assembled angles. The drawing plates are
   authored on their own paper ground, so they sit on a plain bone card rather
   than the section background. */
.memorial-spec { border-top: 1px solid var(--c-stone); }
.memorial-spec .spec-head { max-width: 60ch; }
.memorial-spec figure { margin: 0; }
.memorial-spec figcaption {
  font: 500 0.75rem/1.5 var(--f-sans);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--c-ash-readable);
  margin-top: var(--s-3);
}
.memorial-spec img { display: block; width: 100%; height: auto; }

.spec-hero { margin-top: var(--s-7); }
.spec-hero img { border-radius: 2px; }

.spec-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-6);
  margin-top: var(--s-7);
}
@media (min-width: 720px) {
  .spec-grid--drawings { grid-template-columns: repeat(3, 1fr); }
  .spec-grid--angles { grid-template-columns: repeat(3, 1fr); }
}
.spec-grid--drawings img {
  background: #F4F1EB;
  border: 1px solid var(--c-stone);
}

.spec-figures {
  margin-top: var(--s-8);
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-5) var(--s-8);
}
@media (min-width: 720px) { .spec-figures { grid-template-columns: repeat(2, 1fr); } }
.spec-figures dl { margin: 0; }
.spec-figures dt {
  font: 500 0.75rem/1 var(--f-sans);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--c-ash-readable);
  margin-bottom: var(--s-3);
}
.spec-figures dd { margin: 0 0 var(--s-5); }
.spec-figures table { width: 100%; border-collapse: collapse; font-size: 0.9375rem; }
.spec-figures th,
.spec-figures td {
  text-align: left;
  padding: var(--s-3) 0;
  border-bottom: 1px solid var(--c-stone);
  vertical-align: top;
}
.spec-figures th { font-weight: 500; color: var(--c-graphite); }
.spec-figures td { color: var(--c-ash-readable); }
.spec-figures td:last-child { text-align: right; font-variant-numeric: tabular-nums; }


/* ---- Downloadable document (brochures / material notes) ------------------
   A quiet, paper-like block offering a PDF. Used on work.html (memorial spec)
   and care.html. Deliberately not a card with a shadow — it reads as a sheet
   set down on the page, in keeping with the rest of the light system. */
.doc-download {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: var(--s-6) var(--s-7);
  margin-top: var(--s-7);
  padding: var(--s-6);
  background: var(--c-bone);
  border: 1px solid var(--c-stone);
}
.doc-download__body { max-width: 58ch; }
.doc-download__body .eyebrow { margin-bottom: var(--s-3); }
.doc-download h3 {
  font-size: clamp(1.25rem, 2.2vw, 1.6rem);
  font-weight: 400;
  margin-bottom: var(--s-3);
}
.doc-download p {
  color: var(--c-ash-readable);
  font-size: 0.9375rem;
  margin: 0;
}
.doc-download__action { text-align: right; }
.doc-download__meta {
  display: block;
  margin-top: var(--s-3);
  font: 400 0.75rem/1.4 var(--f-sans);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--c-ash-readable);
  font-variant-numeric: tabular-nums;
}
/* The link itself gets a 44px touch target via the button padding. The ghost
   variant keeps the page's primary CTA (enquire) visually dominant. */
.doc-download .btn-ghost { white-space: nowrap; }

@media (max-width: 720px) {
  .doc-download {
    grid-template-columns: 1fr;
    gap: var(--s-5);
  }
  .doc-download__action { text-align: left; }
  .doc-download .btn-ghost { display: block; text-align: center; }
}


/* ---- Journal (blog) ------------------------------------------------------
   Index cards and the article page. Text-only by design: imagery is withheld,
   and these read as considered notes rather than illustrated posts. */
.journal-list {
  display: grid;
  /* min() floor: never demand a track wider than the row itself, or the grid
     overflows and body{overflow-x:hidden} silently clips it at 320px. */
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  /* Rules come from the cards, not from a 1px gap over a stone background.
     The gap trick paints every EMPTY cell stone too, so any post count that
     does not divide the column count leaves grey blocks in the last row. */
  border-top: 1px solid var(--c-stone);
  border-left: 1px solid var(--c-stone);
}
@media (min-width: 940px) {
  /* three across: divides the current six posts into exact rows, and keeps the
     measure comfortable rather than squeezing four narrow columns in */
  .journal-list { grid-template-columns: repeat(3, 1fr); }
}
.journal-card {
  background: var(--c-bone);
  border-right: 1px solid var(--c-stone);
  border-bottom: 1px solid var(--c-stone);
  padding: var(--s-6);
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
}
.journal-card__meta,
.article-meta {
  flex-wrap: wrap;
  font: 400 0.75rem/1.4 var(--f-sans);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--c-ash-readable);
  display: flex;
  align-items: baseline;
  gap: var(--s-2);
  margin: 0;
}
.journal-card h2 {
  font-size: 1.5rem;
  font-weight: 400;
  line-height: 1.2;
  margin: 0;
}
.journal-card h2 a { color: var(--c-coal); }
.journal-card h2 a:hover { color: var(--c-rust); }
.journal-card p {
  color: var(--c-ash-readable);
  font-size: 0.9375rem;
  margin: 0;
  flex: 1 1 auto;
}
.journal-card__link {
  font: 500 0.8125rem/1 var(--f-sans);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--c-rust);
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}
.journal-card__link:hover { color: var(--c-coal); }

/* ---- Article ---- */
.article-head { max-width: 760px; }
.article-head .eyebrow a { color: var(--c-rust); }
.article-head .eyebrow a:hover { color: var(--c-coal); }
.article-head h1 { margin-bottom: var(--s-4); }
.article-meta {
  margin-top: var(--s-5);
  padding-top: var(--s-4);
  border-top: 1px solid var(--c-stone);
}
.journal-article .prose { margin-top: var(--s-7); }
.journal-article .prose h2 { font-size: 1.5rem; }
.journal-article .soft-cta { max-width: 860px; }
.journal-article .doc-download { max-width: 860px; }

.related {
  max-width: 860px;
  margin-top: var(--s-7);
  padding-top: var(--s-6);
  border-top: 1px solid var(--c-stone);
}
.related__title {
  font: 500 0.75rem/1 var(--f-sans);
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--c-ash-readable);
  margin: 0 0 var(--s-4);
}
.related ul { list-style: none; margin: 0; padding: 0; }
.related li { border-bottom: 1px solid var(--c-stone); }
.related li:first-child { border-top: 1px solid var(--c-stone); }
.related a {
  display: block;
  padding: var(--s-4) 0;
  font-family: var(--f-serif);
  font-size: 1.25rem;
  color: var(--c-graphite);
  min-height: 44px;
}
.related a:hover { color: var(--c-rust); }

/* Invisible marker ~60% down the article; the analytics dispatcher watches it. */
.blog-read-sentinel { height: 1px; width: 100%; }


/* ---- Touch targets -------------------------------------------------------
   Measured at a real 390px viewport, the site had 16–22 controls per page
   under 44px high — footer links sat at 17px, the inline CTAs at 24–29px.
   They are fine to click with a mouse and fiddly to hit with a thumb.

   Gated on EITHER a narrow viewport OR a coarse pointer. Pointer alone is the
   semantically right test — what matters is whether a finger is doing the
   tapping, not how wide the window is — but it also cannot be verified in a
   headless browser, which always reports a fine pointer. The width clause
   makes the rule testable and covers narrow windows; the pointer clause
   covers touch devices at any width. Desktop layout is untouched.

   Inline links inside running prose are deliberately NOT padded out — WCAG
   2.5.8 exempts text links in a sentence, and forcing 44px there would wreck
   the line rhythm of the Journal. */
@media (max-width: 719px), (hover: none) and (pointer: coarse) {

  /* footer navigation — the worst offenders at 17px */
  .footer-col li { margin-bottom: 0; }
  .footer-col a,
  .footer-col li > span {
    display: flex;
    align-items: center;
    min-height: 44px;
  }

  /* primary nav drawer */
  .nav-links a {
    display: flex;
    align-items: center;
    min-height: 48px;
  }

  /* arrow CTAs: .work-cta, journal cards, the cookie-preferences button */
  .work-cta,
  .journal-card__link,
  .link-btn,
  .reading-trigger,
  .doc-download .btn-ghost {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* related-post list on Journal articles */
  .related a { min-height: 48px; display: flex; align-items: center; }

  /* form controls */
  .form-field input,
  .form-field select { min-height: 48px; }
  .form-consent input[type="checkbox"] {
    width: 24px;
    height: 24px;
    flex: none;
  }
  .form-consent { align-items: center; }

  /* consent banner: the two decision buttons were 38px */
  .consent__actions .btn-primary,
  .consent__actions .btn-ghost { min-height: 44px; }

  /* the brand wordmark is the route home from every page */
  .nav-brand { display: inline-flex; align-items: center; min-height: 44px; }

  /* contact page: email / phone / social sat at 20px */
  .contact-lines li { display: flex; align-items: baseline; flex-wrap: wrap; }
  .contact-lines a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* Journal: card headings and the breadcrumb back to the index */
  .journal-card h2 a,
  .article-head .eyebrow a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* footer base row: the cookie button and its separator */
  .footer-bar { row-gap: var(--s-2); }
}

/* ===================================================================
   PHONE LAYOUT PASS
   Everything below 720px. Desktop is deliberately untouched: the audit
   found no horizontal overflow at 320/360/390/430, so the layout was
   structurally sound — the problems were all about what sits on top of
   what, and how much screen the hero and the consent bar were eating.
   =================================================================== */

/* ---- 1. Stack the hero instead of overlaying it -------------------
   The hero was a full-bleed picture at 100svh with the eyebrow, headline,
   lede and both CTAs laid over it. On a phone that meant the piece filled
   the entire first screen, the copy sat on top of the table itself, and
   the two CTAs were pushed to the bottom edge where the consent bar
   covered them — so the primary call to action was invisible on load.

   Stacked, nothing overlaps: a band of the piece on top, copy below it on
   flat bone. The mobile source is a 3:5 reframe with the table in its top
   third and empty bone beneath (that emptiness existed to seat the
   overlaid copy), so the band is cropped to 5:4 and the crop pulled up so
   it lands on the piece rather than the blank floor under it.
   The 14% is measured, not guessed: the subject occupies rows 362-650 of
   the 1800px source, centre 506 (28.1%); scaled to a 390px width that
   centre sits 183px down a 650px image, and 14% of the 390px of overflow
   is what puts it in the middle of a 260px band.
   3:2 rather than something taller because the band height decides whether
   the CTAs clear the consent bar: at 5:4 the hero copy ran long enough that
   "Explore the work" sat underneath it on a 844px screen, which is the same
   invisible-CTA problem the stacking was meant to solve. */
@media (max-width: 719px) {
  .landing-hero {
    display: block;
    min-height: 0;
    overflow: visible;
  }
  .landing-hero picture { display: block; }
  .landing-hero img.img-slot {
    position: static;
    width: 100%;
    height: auto;
    aspect-ratio: 3 / 2;
    object-fit: cover;
    object-position: center 14%;
  }
  /* The scrim's only job was seating copy over the photo. With the copy
     moved below, it has nothing to darken but the piece. */
  .landing-hero .hero-overlay { display: none; }
  .landing-hero .container {
    padding: var(--s-5) var(--section-x) var(--s-6);
  }
  .landing-hero h1 { max-width: 18ch; }
  .landing-hero .hero-sub { margin-bottom: var(--s-4); }
  /* The vertical "Scroll" rail is absolutely positioned to the bottom of a
     full-height hero; in a stacked one it lands on the copy. */
  .hero-scroll { display: none; }
}

/* The two hero CTAs share one row so the primary one clears the consent bar.
   Stacked they needed 100px and "Explore the work" ended up underneath it;
   in a row they need 44px and both sit above it.
   386px, not 360px: the two labels have a combined min-content width of about
   385px including the gap, and because they are `nowrap` they overflow their
   boxes rather than shrinking them. Setting this threshold at 360 pushed the
   document 25px wider than the viewport on a Galaxy S (360) and 10px on an
   iPhone SE 2/3 and 6/7/8 (375) — the page panned sideways and the second
   label was clipped. Anything narrower than the labels keeps the stack. */
@media (min-width: 386px) and (max-width: 719px) {
  .landing-hero .hero-ctas { flex-direction: row; flex-wrap: nowrap; }
  .landing-hero .hero-ctas > * {
    flex: 1;
    text-align: center;
    padding-left: 0.5rem;
    padding-right: 0.5rem;
    white-space: nowrap;
  }
}
@media (max-width: 385px) {
  .landing-hero .hero-ctas { flex-direction: column; align-items: stretch; }
  .landing-hero .hero-ctas > * { text-align: center; }
}

/* ---- 2. Give the consent bar less of the screen ------------------
   At 390x844 the bar was 215px — a quarter of the viewport, permanently,
   until dismissed. Same words, tighter setting, and the two buttons share
   a row so the block is roughly half the height it was. */
@media (max-width: 719px) {
  .consent { padding: var(--s-4) var(--section-x); }
  .consent__inner { gap: var(--s-3); }
  .consent__text { font-size: 0.8rem; line-height: 1.45; }
  .consent__actions { width: 100%; flex-wrap: nowrap; }
  .consent__actions .btn-primary,
  .consent__actions .btn-ghost {
    flex: 1;
    text-align: center;
    padding: 0.65rem 0.5rem;
    white-space: nowrap;
  }
}

/* ---- 3. Trim the scroll ------------------------------------------
   The homepage ran 10,264px on a 390px phone — a little over twelve
   screens, and only 18% of that was image. The section rhythm was tuned
   for desktop; at phone width the same clamp floor left very tall bands of
   empty bone between short paragraphs. Pulling the floor from 4rem to
   2.75rem keeps the airiness without the dead scrolling. */
@media (max-width: 719px) {
  :root { --section-y: clamp(2.75rem, 9vw, 8rem); }
}

/* ---- 4. Short screens ---------------------------------------------
   An iPhone SE is 320x568. The consent bar alone was 32% of that, and the
   hero band, headline, lede and CTAs cannot all fit above it — no amount
   of tuning changes that arithmetic, so this block does not pretend to:
   it just stops the first screen being mostly banner. Band flattened to
   2:1 (crop recomputed to 19% for the shorter box), tighter hero rhythm,
   smaller consent type. On these screens the CTAs still sit below the bar
   until it is dismissed, which is inherent to a persistent bottom bar. */
@media (max-width: 719px) and (max-height: 720px) {
  .landing-hero img.img-slot {
    aspect-ratio: 2 / 1;
    object-position: center 19%;
  }
  .landing-hero .container { padding: var(--s-4) var(--section-x) var(--s-5); }
  .landing-hero h1 { margin-bottom: var(--s-4); }
  .landing-hero .hero-sub { font-size: 1rem; margin-bottom: var(--s-3); }
  .consent { padding: var(--s-3) var(--section-x); }
  .consent__text { font-size: 0.75rem; line-height: 1.4; }
}

/* ---- 5. Stop the consent bar sitting on the hero CTAs -------------
   The bar is fixed to the bottom of the viewport and the hero seats its
   copy at the bottom of a 100svh block, so the two met exactly: at 1024,
   1366, 1440 and 1920 the 116px bar covered BOTH hero buttons completely
   on every first visit. The phone pass fixed this below 720px by stacking;
   above 720px it had never been fixed at all.
   Reserve the bar's height inside the hero while the bar is on screen. It
   carries [hidden] once dismissed, so the padding disappears with it and
   the hero returns to its intended full-bleed composition. (:has() is
   already load-bearing in this stylesheet — the hero's whole colour scheme
   keys off .landing-hero:has(img.img-slot).) */
@media (min-width: 720px) {
  body:has(.consent:not([hidden])) .landing-hero .container {
    padding-bottom: calc(var(--s-8) + 132px);
  }
}
