/* ============================================================
   Design tokens
   ============================================================ */
:root {
  /* Palette: warm bone ground, near-black ink, rich green accent */
  --bg: #F3EFE3;
  --bg-alt: #EDE8DA;
  --card: #FBF9F3;
  --ink: #1C1B17;
  --ink-soft: #4A483E;
  --ink-faint: #6C685C;
  --accent: #146B34;
  --accent-bright: #12753A;
  --accent-soft: #DEEBDD;
  --rule: rgba(20, 107, 52, 0.42);
  --grid-line: rgba(20, 107, 52, 0.46);
  --line: #DAD3BF;
  --line-strong: #C7BE9F;

  /* Light cream specks, laid over the paper grain in the page's backdrop */
  --specks: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='s'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.1' numOctaves='2' seed='7' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 1  0 0 0 0 0.984  0 0 0 0 0.937  0 0 0 14 -8.0'/%3E%3C/filter%3E%3Crect width='100%' height='100%' filter='url(%23s)'/%3E%3C/svg%3E");

  /* Paper grain, reused by any section that needs it */
  --grain: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%27180%27%20height%3D%27180%27%3E%3Cfilter%20id%3D%27n%27%3E%3CfeTurbulence%20type%3D%27fractalNoise%27%20baseFrequency%3D%270.85%27%20numOctaves%3D%273%27%20stitchTiles%3D%27stitch%27%2F%3E%3CfeColorMatrix%20type%3D%27matrix%27%20values%3D%270%200%200%200%200%20%200%200%200%200%200%20%200%200%200%200%200%20%200%200%200%200.08%200%27%2F%3E%3C%2Ffilter%3E%3Crect%20width%3D%27100%25%27%20height%3D%27100%25%27%20filter%3D%27url%28%23n%29%27%2F%3E%3C%2Fsvg%3E");

  /* Type */
  --font-display: "Instrument Serif", Georgia, "Times New Roman", serif;
  --font-body: "Plus Jakarta Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;

  /* Spacing scale */
  --space-1: 8px;
  --space-2: 16px;
  --space-3: 24px;
  --space-4: 40px;
  --space-5: 64px;
  --space-6: 96px;
  --space-7: 144px;

  --max-width: 1280px;
  --radius: 2px;
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background-color: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* The page's texture: cream specks over a faint dark grain, on one layer
   fixed to the viewport beneath everything. z-index -1 puts it above the
   page colour but under all content, so text, photos, buttons and links
   draw clean on top. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image: var(--specks), var(--grain);
  /* Its own GPU layer: painted once, then just shown. Without this the
     browser repainted it (and everything over it) as the page scrolled. */
  will-change: transform;
}

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

a {
  color: inherit;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 1.05;
  margin: 0;
  letter-spacing: -0.01em;
}

p {
  margin: 0;
}

.wrap {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 var(--space-3);
}

/* ============================================================
   Nav: name on the left, links on the right, solid rule beneath.
   Translucent, so the hero grid (which runs up behind it) shows
   through faintly at the top of the page.
   ============================================================ */
.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  border-bottom: 1px solid var(--accent);
  /* Clear at the top of the page so the hero grid runs straight through the
     bar (a blur would smear its 1px lines away). script.js adds .is-scrolled
     once the page moves, bringing back a background so the links stay
     readable over content. */
  background: transparent;
  transition: background-color 0.2s ease;
}

/* Nearly opaque rather than blurred: a backdrop blur re-reads and blurs
   whatever scrolls beneath the bar on every frame. */
.nav.is-scrolled {
  background: rgba(243, 239, 227, 0.96);
}

.nav__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  height: 68px;
  padding: 0 clamp(24px, 4vw, 56px);
}

.nav__links {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav__links li {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.nav__links li:not(:last-child)::after {
  content: "✦";
  font-size: 9px;
  color: var(--accent);
}

.nav__links a {
  text-decoration: none;
  font-size: 16px;
  color: var(--accent);
  opacity: 0.75;
  transition: opacity 0.2s ease;
}

.nav__links a:hover {
  opacity: 1;
}

.nav__links a.is-active {
  font-weight: 700;
  opacity: 1;
}

.nav__toggle {
  display: none;
  background: none;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  color: var(--accent);
  width: 40px;
  height: 40px;
  align-items: center;
  justify-content: center;
}

.nav__toggle svg {
  width: 18px;
  height: 18px;
}

/* ============================================================
   Buttons and links
   ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 14px 30px;
  border-radius: var(--radius);
  text-decoration: none;
  font-size: 15px;
  font-weight: 600;
  border: 1px solid var(--ink);
  transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #FFFFFF;
}

.btn--primary:hover {
  background: var(--accent-bright);
  border-color: var(--accent-bright);
}

.btn--ghost {
  background: transparent;
  color: var(--accent);
  border-color: var(--rule);
}

.btn--ghost:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: #FFFFFF;
}

.text-link {
  text-decoration: underline;
  text-decoration-color: var(--rule);
  text-underline-offset: 4px;
  text-decoration-thickness: 1px;
}

.text-link:hover {
  text-decoration-color: var(--accent);
}

/* Corner-tick frame around a button */
.tick-frame {
  position: relative;
  display: inline-block;
  padding: 11px;
}

.tick-frame__mark {
  position: absolute;
  width: 11px;
  height: 11px;
  border: 1px solid var(--accent);
}

.tick-frame__mark--tl { top: 0; left: 0; border-right: none; border-bottom: none; }
.tick-frame__mark--tr { top: 0; right: 0; border-left: none; border-bottom: none; }
.tick-frame__mark--bl { bottom: 0; left: 0; border-right: none; border-top: none; }
.tick-frame__mark--br { bottom: 0; right: 0; border-left: none; border-top: none; }

/* ============================================================
   Hero: centred, grid fading out toward the edges
   ============================================================ */
.hero {
  position: relative;
  /* Clip sideways only: the grid layer reaches up behind the nav. */
  overflow-x: clip;
  overflow-y: visible;
  display: flex;
  align-items: center;
  padding: clamp(64px, 10vh, 112px) 0 clamp(64px, 9vh, 96px);
}

/* The grid sits on its own layer so it can be masked without
   touching the paper grain or the content above it. */
/* The grid runs behind both the nav and the hero: the layer starts one nav
   height (68px) above the hero, and the nav is clear at the top of the page.
   Two parts, for smooth scrolling: .hero__grid holds the fade mask and
   stays put; .hero__grid-lines holds the lines and drifts with a transform,
   which the GPU moves without repainting anything. (The drift used to
   animate background-position, repainting this whole masked layer every
   frame, forever.) */
.hero__grid {
  position: absolute;
  inset: -68px 0 0 0;
  overflow: hidden;
  pointer-events: none;
  /* Two masks, intersected: lines soften toward the left and right edges,
     and fade out at the bottom into the Work section. No fade at the top, so
     the lines run through the nav bar at full strength. */
  -webkit-mask-image:
    linear-gradient(to right, transparent 0%, rgba(0, 0, 0, 0.3) 16%, #000 38%, #000 62%, rgba(0, 0, 0, 0.3) 84%, transparent 100%),
    linear-gradient(to bottom, #000 0%, #000 62%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(to right, transparent 0%, rgba(0, 0, 0, 0.3) 16%, #000 38%, #000 62%, rgba(0, 0, 0, 0.3) 84%, transparent 100%),
    linear-gradient(to bottom, #000 0%, #000 62%, transparent 100%);
  mask-composite: intersect;
}

/* One cell (116px) larger on the top and left, so drifting a cell down and
   right never uncovers an edge. The +58px / 116px offsets keep the lines
   centred on the page and starting at its top, as before. */
.hero__grid-lines {
  position: absolute;
  inset: -116px 0 0 -116px;
  background-image:
    linear-gradient(rgba(20, 107, 52, 0.34) 1px, transparent 1px),
    linear-gradient(to right, rgba(20, 107, 52, 0.34) 1px, transparent 1px);
  background-size: 116px 116px, 116px 116px;
  background-position: calc(50% + 58px) 116px;
}

.hero__inner {
  position: relative;
  z-index: 1;
  width: 100%;
  text-align: center;
}

.hero__title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(42px, 7.9vw, 120px);
  line-height: 1.06;
  letter-spacing: -0.02em;
  color: var(--accent);
  margin: 0 auto;
  text-wrap: balance;
}

/* Only the phrase is italic; each line is its own animated span. */
.hero__title em {
  font-style: italic;
  font-weight: 400;
}

.hero__subtitle {
  max-width: 50ch;
  margin: 36px auto 0;
  font-size: clamp(16px, 1.35vw, 19px);
  line-height: 1.55;
  color: var(--accent);
  text-wrap: balance;
}

.hero__subtitle strong {
  font-weight: 700;
}

.hero__actions {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  margin-top: 40px;
  flex-wrap: wrap;
}

/* ============================================================
   Section furniture
   ============================================================ */
section {
  padding: var(--space-6) 0;
}

.section-label {
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  opacity: 0.8;
  margin-bottom: var(--space-2);
  display: block;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  font-weight: 600;
}

.eyebrow::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  display: inline-block;
}

/* ============================================================
   Work: two ruled columns
   ============================================================ */
.work {
  padding: var(--space-5) 0 0;
}

.work__label {
  padding: 0 var(--space-3);
  max-width: var(--max-width);
  margin: 0 auto var(--space-3);
}

.work-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}

.work-col {
  display: block;
  padding: var(--space-4) var(--space-4) var(--space-5);
  text-decoration: none;
  color: inherit;
  transition: background 0.25s ease;
}

.work-col + .work-col {
  border-left: 1px solid var(--rule);
}

.work-col:hover {
  background: rgba(20, 107, 52, 0.04);
}

.work-col__dates {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  color: var(--accent);
  opacity: 0.85;
}

.work-col__title {
  font-family: var(--font-display);
  font-size: clamp(28px, 3.2vw, 44px);
  color: var(--accent);
  margin-top: var(--space-2);
}

.work-col__media {
  margin-top: var(--space-3);
  aspect-ratio: 16 / 10;
  min-height: 0;
}

.work-col__desc {
  margin-top: var(--space-3);
  font-size: 15px;
  color: var(--ink-soft);
  max-width: 48ch;
}

/* ============================================================
   About
   ============================================================ */
.about__grid {
  display: grid;
  grid-template-columns: 0.8fr 1.2fr;
  gap: var(--space-5);
  align-items: start;
}

.about__heading {
  font-size: clamp(32px, 4vw, 48px);
  color: var(--accent);
}

.about__copy {
  font-size: 18px;
  color: var(--ink-soft);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* ============================================================
   Footer: headline plus bordered link bar
   ============================================================ */
.footer {
  padding: var(--space-6) 0 var(--space-5);
}

.footer__headline {
  font-family: var(--font-display);
  font-size: clamp(32px, 5.4vw, 74px);
  color: var(--accent);
  margin-bottom: var(--space-4);
}

.footer__headline em {
  font-style: italic;
}

.linkbar {
  border: 1px solid var(--rule);
}

.linkbar__top {
  display: flex;
  justify-content: space-between;
  gap: var(--space-2);
  padding: 9px 16px;
  border-bottom: 1px solid var(--rule);
  font-size: 12px;
  color: var(--accent);
  opacity: 0.9;
}

.linkbar__row {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
}

.linkbar__cell {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 22px 24px;
  text-decoration: none;
  color: var(--accent);
  font-size: 16px;
  transition: background 0.2s ease;
}

.linkbar__cell + .linkbar__cell {
  border-left: 1px solid var(--rule);
}

.linkbar__cell:hover {
  background: rgba(20, 107, 52, 0.06);
}

.linkbar__cell svg {
  width: 20px;
  height: 20px;
  flex: none;
}

/* ============================================================
   Case study pages
   ============================================================ */
.cs-hero {
  padding-top: var(--space-6);
  padding-bottom: var(--space-5);
}

.cs-hero__back {
  font-size: 14px;
  color: var(--accent);
  text-decoration: none;
}

.cs-hero__title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(40px, 7vw, 84px);
  color: var(--accent);
  margin-top: var(--space-2);
  max-width: 20ch;
}

.cs-hero__dek {
  max-width: 56ch;
  font-size: 19px;
  color: var(--ink-soft);
  margin-top: var(--space-3);
}

.cs-meta {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-3);
  padding: var(--space-4) 0;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  margin-top: var(--space-5);
}

.cs-meta dt {
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 6px;
}

.cs-meta dd {
  margin: 0;
  font-size: 16px;
}

.cs-section {
  padding: var(--space-5) 0;
  border-bottom: 1px solid var(--line);
}

.cs-section:last-of-type {
  border-bottom: none;
}

.cs-section__grid {
  display: grid;
  grid-template-columns: 0.6fr 1.4fr;
  gap: var(--space-5);
  align-items: start;
}

.cs-section__label {
  font-size: 13px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.cs-section__heading {
  font-size: clamp(26px, 3vw, 36px);
  margin-top: 8px;
  color: var(--accent);
}

.cs-section__body {
  color: var(--ink-soft);
  font-size: 17px;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.cs-section__body ul {
  margin: 0;
  padding-left: 20px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.cs-media-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
}

.cs-media-grid .placeholder {
  aspect-ratio: 3 / 4;
}

.cs-next {
  padding: var(--space-6) 0;
}

.cs-next__link {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  text-decoration: none;
  color: inherit;
  padding: var(--space-4);
  border: 1px solid var(--rule);
  transition: background 0.2s ease;
}

.cs-next__link:hover {
  background: rgba(20, 107, 52, 0.05);
}

.cs-next__title {
  font-size: clamp(24px, 3vw, 34px);
  color: var(--accent);
}

/* ============================================================
   Placeholder media block
   ============================================================ */
.placeholder {
  background: repeating-linear-gradient(
    135deg,
    var(--bg-alt),
    var(--bg-alt) 10px,
    var(--card) 10px,
    var(--card) 20px
  );
  border: 1px dashed var(--line-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  color: var(--ink-faint);
  font-size: 13px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: var(--space-3);
  min-height: 200px;
}

/* ============================================================
   Reveal on scroll
   ============================================================ */
[data-reveal] {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

[data-reveal].is-visible {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
  html {
    scroll-behavior: auto;
  }
}

/* ============================================================
   Responsive
   ============================================================ */
@media (max-width: 860px) {
  .nav__links {
    position: fixed;
    inset: 68px 0 auto 0;
    background: var(--bg);
    border-bottom: 1px solid var(--rule);
    flex-direction: column;
    align-items: flex-start;
    padding: var(--space-3);
    gap: var(--space-2);
    transform: translateY(-8px);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease, transform 0.2s ease;
  }

  .nav__links.is-open {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
  }

  .nav__links li:not(:last-child)::after {
    display: none;
  }

  .nav__links a {
    font-size: 20px;
  }

  .nav__toggle {
    display: inline-flex;
  }

  section {
    padding: var(--space-5) 0;
  }

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

  .work-col + .work-col {
    border-left: none;
    border-top: 1px solid var(--rule);
  }

  .work-col {
    padding: var(--space-4) var(--space-3);
  }

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

  .linkbar__cell + .linkbar__cell {
    border-left: none;
    border-top: 1px solid var(--rule);
  }

  .about__grid,
  .cs-section__grid {
    grid-template-columns: 1fr;
    gap: var(--space-3);
  }

  .cs-meta {
    grid-template-columns: 1fr 1fr;
  }

  .cs-media-grid {
    grid-template-columns: 1fr;
  }

  .cs-next__link {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* ============================================================
   Case study extensions
   Components the real case studies need, built on the tokens
   above. Everything before this point is the reference
   stylesheet with only the two type tokens changed.
   ============================================================ */

/* Real cover images in the work columns, replacing the placeholders */
.work-col__media {
  overflow: hidden;
  border: 1px solid var(--rule);
  background: var(--card);
}

.work-col__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  display: block;
}

/* Figures ---------------------------------------------------- */
.figure {
  margin: 0;
  border: 1px solid var(--rule);
  background: var(--card);
  overflow: hidden;
}

.figure img { width: 100%; height: auto; display: block; }

.figure figcaption {
  font-size: 13px;
  color: var(--ink-faint);
  padding: 12px var(--space-2);
  border-top: 1px solid var(--rule);
  line-height: 1.45;
}

/* Embedded live prototypes ----------------------------------- */
.proto {
  margin: var(--space-3) 0 0;
  border: 1px solid var(--rule);
  background: var(--bg-alt);
  overflow: hidden;
}

.proto__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: 10px var(--space-2);
  border-bottom: 1px solid var(--rule);
  background: var(--card);
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.proto__bar strong { color: var(--accent); font-weight: 600; }

.proto iframe { display: block; width: 100%; border: 0; background: var(--card); }
.proto--phone iframe { height: 940px; }

.proto__note {
  font-size: 13px;
  color: var(--ink-faint);
  padding: 10px var(--space-2);
  border-top: 1px solid var(--rule);
  background: var(--card);
}

/* Fixed-width prototypes, scaled to fit by script.js */
.proto__fit { position: relative; width: 100%; overflow: hidden; background: var(--card); }
.proto__fit iframe { display: block; border: 0; }

/* Full-width block for the wide desktop prototypes */
.cs-wide { margin-top: var(--space-4); }

/* Stat row --------------------------------------------------- */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-3);
  margin: var(--space-3) 0 0;
}

.stat__num {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 46px;
  line-height: 1;
  color: var(--accent);
}

.stat__label { font-size: 14px; color: var(--ink-soft); margin-top: 8px; }
.stat__src { font-size: 12px; color: var(--ink-faint); margin-top: 8px; }

/* Pull quote ------------------------------------------------- */
.pullquote {
  margin: var(--space-3) 0;
  padding-left: var(--space-3);
  border-left: 2px solid var(--accent);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(21px, 2.4vw, 30px);
  line-height: 1.25;
  color: var(--accent);
}

.pullquote cite {
  display: block;
  margin-top: 12px;
  font-family: var(--font-body);
  font-style: normal;
  font-size: 14px;
  color: var(--ink-faint);
}

/* Outcome band ----------------------------------------------- */
.outcome {
  border: 1px solid var(--rule);
  border-left: 2px solid var(--accent);
  background: var(--accent-soft);
  padding: var(--space-3);
  margin: var(--space-3) 0 0;
}

.outcome__label {
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  font-weight: 700;
  margin-bottom: 8px;
  display: block;
}

.outcome p { color: var(--ink); }
.outcome ul { margin: 12px 0 0; padding-left: 20px; display: flex; flex-direction: column; gap: 6px; }

/* Before and after ------------------------------------------- */
.ba {
  display: grid;
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
  overflow: hidden;
  margin: var(--space-3) 0 0;
}

.ba__row { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--rule); }
.ba__cell { background: var(--card); padding: 14px var(--space-2); font-size: 15px; }
.ba__cell--before { color: var(--ink-faint); }
.ba__cell--after { color: var(--ink); }

.ba__head {
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--bg-alt);
}

/* Data table ------------------------------------------------- */
.table-wrap { overflow-x: auto; margin: var(--space-3) 0 0; }

.table { width: 100%; border-collapse: collapse; font-size: 15px; min-width: 520px; }

.table th,
.table td {
  text-align: left;
  padding: 12px var(--space-2);
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

.table th {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
  border-bottom-color: var(--rule);
}

.table td strong { color: var(--ink); }

/* Numbered cards --------------------------------------------- */
.steps { display: grid; gap: var(--space-2); margin: var(--space-3) 0 0; }

.step { border: 1px solid var(--rule); background: var(--card); padding: var(--space-3); }

.step__n {
  font-family: var(--font-body);
  font-size: 12px;
  color: var(--accent);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.step h4 {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 400;
  color: var(--accent);
  margin: 8px 0;
  line-height: 1.15;
}

.step p { color: var(--ink-soft); font-size: 15px; }

.steps--2 { grid-template-columns: 1fr 1fr; }
.steps--3 { grid-template-columns: repeat(3, 1fr); }

/* Disclosure ------------------------------------------------- */
.disclosure { border: 1px solid var(--rule); background: var(--card); margin: var(--space-3) 0 0; }

.disclosure > summary {
  cursor: pointer;
  padding: 14px var(--space-3);
  font-weight: 600;
  font-size: 15px;
  color: var(--accent);
  list-style: none;
  display: flex;
  align-items: center;
  gap: 10px;
}

.disclosure > summary::-webkit-details-marker { display: none; }
.disclosure > summary::before { content: "+"; font-size: 18px; line-height: 1; }
.disclosure[open] > summary::before { content: "\2212"; }

.disclosure__body {
  padding: var(--space-3);
  border-top: 1px solid var(--rule);
  color: var(--ink-soft);
  font-size: 16px;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* Source list ------------------------------------------------ */
.sources {
  font-size: 14px;
  color: var(--ink-faint);
  line-height: 1.55;
  margin: var(--space-3) 0 0;
  padding-left: 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* The back link takes its own line, so the eyebrow below it keeps the gap
   between its dot and its text (inline-flex, not block). */
.cs-hero__back { display: block; }
.cs-hero__eyebrow { display: inline-flex; margin-top: var(--space-3); }
.cs-section { scroll-margin-top: 80px; }

/* A 1440px prototype iframe would otherwise force its grid column wider than
   its fr share, which breaks the layout and makes the fit-to-width
   measurement in script.js read the inflated width. */
.cs-section__grid > *,
.cs-section__body,
.proto,
.proto__fit { min-width: 0; }

@media (max-width: 860px) {
  .steps--2,
  .steps--3 { grid-template-columns: 1fr; }
  .ba__row { grid-template-columns: 1fr; }
  .ba__head { display: none; }
  .proto--phone iframe { height: 780px; }
  .stat__num { font-size: 38px; }
}

/* About: heading above, then the photo and the copy side by side with
   their tops on the same line. The photo column is a fixed width so the
   image stays a sensible size rather than growing with the container. */
.about__grid {
  grid-template-columns: 320px 1fr;
  align-items: start;
  margin-top: var(--space-4);
}

.about__portrait img {
  width: 100%;
  height: auto;
  display: block;
  border: 1px solid var(--rule);
}

.about__copy { max-width: 62ch; }

@media (max-width: 860px) {
  .about__grid { grid-template-columns: 1fr; }
  .about__portrait { max-width: 260px; }
}

/* Featured project ------------------------------------------- */
/* YourNature is the priority piece, so it gets the wider column, a marker
   above the dates, and a faint tint that separates it from the second
   column without breaking the ruled grid. */
/* Sized so the two covers come out exactly the same height, which the shared
   subgrid row needs: YourNature's cover is 16:9 and YourShelf's is 16:10, so
   the featured column's content box is 10/9 the width of the other. 161px is
   both columns' side padding (4 x 40px) plus the 1px rule between them. With
   the old 1.18fr / 0.82fr split, YourShelf's cover left 100-175px of empty
   row beneath it. */
.work-grid {
  grid-template-columns: calc((100% - 161px) * 10 / 19 + 80px) 1fr;
}

.work-col--featured {
  background: rgba(20, 107, 52, 0.035);
}

.work-col--featured:hover {
  background: rgba(20, 107, 52, 0.07);
}

.work-col__flag {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: 5px 10px;
}

.work-col__flag::before {
  content: "";
  width: 6px;
  height: 6px;
  background: var(--accent);
  flex: none;
}

.work-col--featured .work-col__title {
  font-size: clamp(30px, 3.6vw, 50px);
}

@media (max-width: 860px) {
  .work-grid { grid-template-columns: 1fr; }
  .work-col--featured .work-col__title { font-size: clamp(28px, 3.2vw, 44px); }
}

/* The two covers are shot at different ratios, so each media slot matches its
   own image. Forcing one shared ratio either letterboxes the 16:9 cover or
   crops into the wordmark in its top corners. */
.work-col--featured .work-col__media {
  aspect-ratio: 16 / 9;
}

/* ── Work grid alignment ─────────────────────────────────────
   Three fixes, all about things lining up.
   ──────────────────────────────────────────────────────────── */

/* 1. The chip and the dates share one row, so the gap between them is a
      spacing token rather than whatever the inline layout happened to give. */
.work-col__meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}

.work-col__flag { margin-bottom: 0; }
.work-col__title { margin-top: 0; }

/* 2. "Selected work" sits in a centred container while the grid is full
      bleed, so it never lined up with the column beneath it. Match the
      column's own padding instead. */
.work__label {
  max-width: none;
  margin: 0 0 var(--space-3);
  padding: 0 var(--space-4);
}

/* 3. The two columns have titles of different sizes and lengths, so their
      covers started at different heights. Subgrid makes both columns share
      one set of rows, which puts the meta, title, cover and description of
      each on the same baseline across the grid. */
@supports (grid-template-rows: subgrid) {
  .work-grid {
    grid-template-rows: auto auto auto auto;
  }

  .work-col {
    display: grid;
    grid-row: span 4;
    grid-template-rows: subgrid;
    align-content: start;
  }
}

@media (max-width: 860px) {
  .work__label { padding: 0 var(--space-3); }

  /* Stacked on mobile there is nothing to align across, so each column
     goes back to normal flow. */
  @supports (grid-template-rows: subgrid) {
    .work-grid { grid-template-rows: none; }
    .work-col { display: block; grid-row: auto; }
  }
}

/* ============================================================
   Motion, chips and the case-study cursor
   Everything that moves is switched off under
   prefers-reduced-motion at the end of this block.
   ============================================================ */

/* Hero: each line rises out of its own mask, the subtitle and CTA
   follow through the existing [data-reveal] with a short stagger. */
.hero__line {
  display: block;
  animation: heroLineIn 0.9s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
.hero__line:nth-child(2) { animation-delay: 0.14s; }
.hero__line:nth-child(3) { animation-delay: 0.28s; }

/* Three lines on phones too: the longest ("not how we hope they will.") is
   8.5em wide, so size the headline to fit it between the 24px gutters. */
@media (max-width: 600px) {
  .hero__title { font-size: calc((100vw - 48px) / 8.6); }
}
.hero .hero__subtitle[data-reveal] { transition-delay: 0.32s; }
.hero .hero__actions[data-reveal] { transition-delay: 0.46s; }

@keyframes heroLineIn {
  from { opacity: 0; transform: translateY(0.45em); filter: blur(6px); }
  to   { opacity: 1; transform: none; filter: none; }
}

/* The hero grid drifts one cell diagonally, slowly enough to read as
   the page breathing rather than something asking to be watched. The lines
   repeat every 116px, so the loop is seamless. Paused while the hero is off
   screen (script.js adds .is-offscreen). */
.hero__grid-lines {
  animation: gridDrift 38s linear infinite;
  will-change: transform;
}
.hero.is-offscreen .hero__grid-lines {
  animation-play-state: paused;
}
@keyframes gridDrift {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(116px, 116px, 0); }
}

/* The grid also leans toward the pointer (script.js sets --gx/--gy on the
   grid itself, in px). Oversized so its edges never slide into view. */
.hero.has-parallax .hero__grid {
  inset: -116px -48px -48px; /* nav height + parallax travel */
  transform: translate3d(var(--gx, 0px), var(--gy, 0px), 0);
  will-change: transform;
}


/* Work cards: the cover eases in, the arrow nudges forward. */
.work-col__media img {
  transition: transform 0.7s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.work-col:hover .work-col__media img,
.work-col:focus-visible .work-col__media img {
  transform: scale(1.035);
}

/* Keyword chips */
.work-col__tags {
  list-style: none;
  margin: var(--space-3) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-self: start;
}
.work-col__tags li {
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  color: var(--accent);
  background: var(--accent-soft);
  border: 1px solid rgba(20, 107, 52, 0.18);
  border-radius: 999px;
  padding: 7px 11px;
}
/* Chips follow their card in, one after another. */
[data-reveal] .work-col__tags li {
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.4s ease, transform 0.4s ease;
}
[data-reveal].is-visible .work-col__tags li { opacity: 1; transform: none; }
[data-reveal].is-visible .work-col__tags li:nth-child(1) { transition-delay: 0.30s; }
[data-reveal].is-visible .work-col__tags li:nth-child(2) { transition-delay: 0.36s; }
[data-reveal].is-visible .work-col__tags li:nth-child(3) { transition-delay: 0.42s; }
[data-reveal].is-visible .work-col__tags li:nth-child(4) { transition-delay: 0.48s; }
[data-reveal].is-visible .work-col__tags li:nth-child(5) { transition-delay: 0.54s; }

/* Visible call to action, so touch screens (no hover, no cursor) still
   say the card opens something. */
.work-col__cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: var(--space-3);
  font-size: 14px;
  font-weight: 700;
  color: var(--accent);
  border-bottom: 1px solid var(--rule);
  padding-bottom: 3px;
  justify-self: start;
  align-self: start;
}
.work-col__arrow { transition: transform 0.25s ease; }
.work-col:hover .work-col__arrow,
.work-col:focus-visible .work-col__arrow { transform: translateX(4px); }

/* Two extra rows (chips, CTA) in the aligned subgrid. */
@supports (grid-template-rows: subgrid) {
  .work-grid { grid-template-rows: repeat(7, auto); }
  .work-col { grid-row: span 7; }
}
@media (max-width: 860px) {
  @supports (grid-template-rows: subgrid) {
    .work-grid { grid-template-rows: none; }
    .work-col { grid-row: auto; }
  }
}

/* Case-study cursor: a badge that trails the pointer over a card.
   script.js adds .has-view-cursor to <html> only for a fine pointer
   that can hover, so touch devices never see it. */
.view-cursor {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1000;
  pointer-events: none;
  width: 108px;
  height: 108px;
  margin: -54px 0 0 -54px;
  border-radius: 50%;
  background: var(--accent);
  color: #F6F3EA;
  display: none;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-size: 13px;
  font-weight: 700;
  line-height: 1.2;
  box-shadow: 0 10px 30px rgba(20, 107, 52, 0.28);
  transform: translate3d(-200px, -200px, 0) scale(0);
  will-change: transform;
}
.view-cursor span { max-width: 9ch; }
.has-view-cursor .view-cursor { display: flex; }
.has-view-cursor .work-col { cursor: none; }
.view-cursor.is-active span { animation: cursorLabelIn 0.3s ease both; }
@keyframes cursorLabelIn { from { opacity: 0; } to { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .hero__line,
  .hero__eyebrow,
  .hero__grid-lines { animation: none; }
  .work-col__media img,
  .work-col__arrow { transition: none; }
  .work-col:hover .work-col__media img { transform: none; }
  [data-reveal] .work-col__tags li { opacity: 1; transform: none; transition: none; }
}

/* ============================================================
   Homepage components (Sept 2026 refresh)
   ============================================================ */

/* Nav brand: name, with the role set small beside it */
.nav__brand {
  display: inline-flex;
  align-items: baseline;
  gap: 10px;
  font-size: 16px;
  color: var(--accent);
  text-decoration: none;
  white-space: nowrap;
}
.nav__role {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  opacity: 0.75;
}
@media (max-width: 420px) {
  .nav__role { display: none; }
}

/* The hero headline's first line is ~95% of the viewport wide at every size,
   so the hero drops the 1280px container cap to keep it on one line on wide
   screens. The subtitle has its own 50ch limit. */
.hero__inner { max-width: none; }

/* Hero eyebrow with a round dot */
.hero__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 32px;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--accent);
  animation: heroLineIn 0.9s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
.hero__eyebrow::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  flex: none;
}

/* Hero CTA */
.btn--hero {
  padding: 16px 44px;
  font-size: 15px;
  font-weight: 700;
}

/* Crosshair marks: at each corner a 20px horizontal and vertical line,
   centred on the corner, so each pokes 10px outside the button. */
.crosshair {
  position: relative;
  display: inline-block;
}
.crosshair__mark {
  position: absolute;
  width: 20px;
  height: 20px;
  pointer-events: none;
}
.crosshair__mark::before,
.crosshair__mark::after {
  content: "";
  position: absolute;
  background: var(--accent);
}
.crosshair__mark::before { left: 0; right: 0; top: 50%; height: 1px; margin-top: -0.5px; }
.crosshair__mark::after  { top: 0; bottom: 0; left: 50%; width: 1px; margin-left: -0.5px; }
.crosshair__mark--tl { top: -10px; left: -10px; }
.crosshair__mark--tr { top: -10px; right: -10px; }
.crosshair__mark--bl { bottom: -10px; left: -10px; }
.crosshair__mark--br { bottom: -10px; right: -10px; }

/* Work card meta: what kind of project, then the facts */
.work-col__facts {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  color: var(--accent);
}
.work-col__kind {
  font-size: 13px;
  font-weight: 600;
}
.work-col__sep { opacity: 0.5; }

/* The one-line finding under each cover. Full card width, upright. */
.work-col__insight {
  margin-top: var(--space-3);
  font-family: "Hanken Grotesk", var(--font-body);
  font-weight: 500;
  font-size: clamp(18px, 1.5vw, 21px);
  line-height: 1.4;
  letter-spacing: -0.005em;
  color: var(--accent);
  text-wrap: pretty;
}
.work-col__insight + .work-col__desc { margin-top: var(--space-2); }

/* About: location and tools lines under the paragraphs */
.about__facts {
  border-top: 1px solid var(--rule);
  padding-top: var(--space-2);
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 14px;
  color: var(--accent);
}

/* Footer link cells: label with a smaller detail line beneath */
.linkbar__text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.linkbar__detail {
  font-size: 13px;
  opacity: 0.75;
  overflow-wrap: anywhere;
}

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

/* ============================================================
   Footer wordmark: "Chugunov" in striped heavy type, IBM-logo
   style, only its top half showing where the page ends.
   Measured in Plus Jakarta Sans 800 at -0.04em tracking: the word
   is 4.76em wide, the cap top sits 0.15em below the line top and
   the x-height is 0.55em. The box shows from the top of the C to
   just past halfway down the lowercase letters.
   ============================================================ */
.footer {
  padding-bottom: 0;
}

.wordmark {
  container-type: inline-size;
  margin-top: var(--space-6);
  padding: 0 clamp(24px, 4vw, 56px);
  overflow: hidden;
  user-select: none;
  pointer-events: none;
}

.wordmark__text {
  display: block;
  /* Fill the width between the side gutters. cqw is the wordmark's own
     width, so a desktop scrollbar can't push it into overflow. */
  font-size: calc(100cqw / 4.76);
  height: 0.52em;
  font-family: var(--font-body);
  font-weight: 800;
  /* With ascent 1.04em and descent 0.22em, a 0.714 line box puts the
     baseline 0.767em down, so the C's top (0.757em) touches the box top.
     The 0.52em height then cuts just past halfway down the x-height. */
  line-height: 0.714;
  letter-spacing: -0.04em;
  text-indent: 0.02em;
  white-space: nowrap;
  text-align: center;
  overflow: hidden;
  /* Stripes clipped to the letters. Never thinner than 2px, so they stay
     crisp on phones where the type is small. */
  color: transparent;
  background-image: repeating-linear-gradient(
    to bottom,
    var(--accent) 0 max(2px, 0.013em),
    transparent max(2px, 0.013em) max(4px, 0.024em)
  );
  -webkit-background-clip: text;
  background-clip: text;
}

/* ============================================================
   Certifications: three ruled columns in the link-bar style.
   Each row opens its verified certificate on Uxcel.
   ============================================================ */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.certs__intro {
  margin-top: var(--space-2);
  max-width: 54ch;
  font-size: 16px;
  color: var(--ink-soft);
}

.certs__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin-top: var(--space-4);
  border: 1px solid var(--rule);
}

.certs__col + .certs__col {
  border-left: 1px solid var(--rule);
}

.certs__group {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin: 0;
  padding: 9px 16px;
  border-bottom: 1px solid var(--rule);
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
}

.certs__count {
  font-variant-numeric: tabular-nums;
  opacity: 0.7;
}

.certs__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.certs__list li + li {
  border-top: 1px solid rgba(20, 107, 52, 0.16);
}

.certs__item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: baseline;
  gap: 12px;
  padding: 14px 16px;
  text-decoration: none;
  color: var(--accent);
  transition: background 0.2s ease;
}

.certs__item:hover,
.certs__item:focus-visible {
  background: rgba(20, 107, 52, 0.06);
}

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

.certs__name {
  font-size: 15px;
  line-height: 1.35;
}

.certs__date {
  font-size: 12px;
  color: var(--ink-faint);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.certs__arrow {
  font-size: 13px;
  opacity: 0.55;
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.certs__item:hover .certs__arrow,
.certs__item:focus-visible .certs__arrow {
  opacity: 1;
  transform: translate(2px, -2px);
}

@media (max-width: 1024px) {
  .certs__grid { grid-template-columns: 1fr; }
  .certs__col + .certs__col {
    border-left: none;
    border-top: 1px solid var(--rule);
  }
}

@media (prefers-reduced-motion: reduce) {
  .certs__item,
  .certs__arrow { transition: none; }
  .certs__item:hover .certs__arrow,
  .certs__item:focus-visible .certs__arrow { transform: none; }
}

/* ============================================================
   Section rhythm: one gap between every pair of sections.
   Each section pads its top only; two stacked paddings made the
   gaps after About twice the gap above it (192px vs 96px).
   ============================================================ */
#about,
.certs {
  padding-bottom: 0;
}
.footer {
  padding-top: var(--space-6);
}
@media (max-width: 860px) {
  .footer { padding-top: var(--space-5); }
}
