/* ══════════════════════════════════════════════════════════
   andyday.design — one stylesheet for every page
   ══════════════════════════════════════════════════════════ */

/* ══════════════════════════════════════════════════════════
   1. TOKENS  — mirrors the Figma variable set exactly
   ══════════════════════════════════════════════════════════ */
:root {
  /* Colour — from Figma `colour/*` variables */
  --bg:           #f5f4f2;
  --surface:      #ffffff;
  --ink:          #2e3039;
  --ink-muted:    #7b7b7b;
  --line:         #e2e0dc;
  --inverse-bg:   #2e3039;
  --inverse-ink:  #f5f4f2;
  --line-inverse: rgba(255,255,255,0.15);

  /* Type families */
  --font-display: 'Montserrat', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-body:    'Montserrat', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  /* Type scale — fluid. min = mobile, max = the Figma desktop value.
     Figma: Display/L 112 · Display/M 72 · Body/L 20 · Body/M 16 · Body/S 14 · Label/Caps 12 */
  --display-l: clamp(3.25rem, 1.5rem + 7.2vw, 7rem);
  --display-m: clamp(2.5rem, 1.4rem + 4.6vw, 4.5rem);
  --body-l:    clamp(1.0625rem, 0.98rem + 0.4vw, 1.25rem);
  --body-m:    1rem;
  --body-s:    0.875rem;
  --label:     0.75rem;

  /* Spacing */
  --gutter:  clamp(1.5rem, 1rem + 2.5vw, 3rem);   /* Figma: 48px */
  --pad-top: clamp(2rem, 1rem + 5.6vw, 6rem);     /* Figma: 96px at 1440 */

  /* Layout */
  --rail:  98px;
  --rail-mobile: 64px;
  --offset-top: 0px;       /* height of anything fixed above the content */

  /* Motion */
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --dur:  0.6s;
}

/* ══════════════════════════════════════════════════════════
   2. RESET + BASE
   ══════════════════════════════════════════════════════════ */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
h1, h2, h3, p, figure, ul { margin: 0; }
ul { padding: 0; list-style: none; }
img { display: block; max-width: 100%; height: auto; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: var(--offset-top);
}
/* Splash or menu up — the page underneath stays put */
html.has-splash,
html.menu-open { overflow: hidden; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--body-m);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* Visible keyboard focus — never remove this */
:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 4px;
}

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* Type helpers */
.display-l { font-family: var(--font-display); font-size: var(--display-l); line-height: 0.9;  letter-spacing: -0.04em;  font-weight: 400; }
.display-m { font-family: var(--font-display); font-size: var(--display-m); line-height: 0.95; letter-spacing: -0.035em; font-weight: 400; }
.body-l    { font-size: var(--body-l); line-height: 1.55; letter-spacing: -0.01em; }
.label     {
  font-size: var(--label); font-weight: 500; line-height: 1.2;
  letter-spacing: 0.08em; text-transform: uppercase;
}

/* ══════════════════════════════════════════════════════════
   3. MONOGRAM
   Real artwork from assets/icons/Monogram_DARK.svg, inlined once as a
   <symbol> and reused. Letters inherit `currentColor`, so the same
   mark serves the light rail, the dark menu and the splash.
   ══════════════════════════════════════════════════════════ */
.monogram {
  display: block;              /* it's a <span> — without this, width/height are ignored */
  position: relative;
  width: var(--mono-size);
  height: var(--mono-size);
  flex: none;
  color: var(--ink);
}
.rail__logo { display: block; }
.monogram.is-inverse { color: var(--inverse-ink); }

.monogram__mark {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  fill: currentColor;
}

/* ── Animated variant — the hero ────────────────────────────
   A sliding-tile puzzle. Seven tiles, two blank cells; tiles shuffle
   into the blanks then reverse back home, once, on load. Tiles are <g>
   elements moved by CSS transform, so the whole thing is GPU-composited.
   Tune SHUFFLE_MOVES / MOVE_DURATION in the script at the foot of the file. */
.monogram--anim .monogram__mark { position: static; }
.monogram--anim .tile {
  transition: transform var(--tile-dur, 600ms) cubic-bezier(0.4, 0, 0.2, 1);
  will-change: transform;
}
/* Dropped once the animation finishes — no reason to hold a compositor layer */
.monogram--anim.is-settled .tile { will-change: auto; }

/* ══════════════════════════════════════════════════════════
   4. SPLASH  — Figma "Splash". Portrait, light monogram, once per session
   ══════════════════════════════════════════════════════════ */
.splash { display: none; }
.has-splash .splash {
  display: grid;
  place-items: center;
  position: fixed;
  inset: 0;
  z-index: 60;
  background: #111;
  cursor: pointer;
  transition: opacity 0.7s var(--ease);
}
.splash.is-leaving { opacity: 0; }

.splash__media {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Darkening band across the lower third (Figma: 50% black, multiply) */
.splash::after {
  content: '';
  position: absolute;
  inset: auto 0 0 0;
  height: 34.3%;
  background: rgba(0,0,0,0.5);
  mix-blend-mode: multiply;
}
.splash .monogram {
  --mono-size: clamp(160px, min(38svh, 60vw), 344px);   /* Figma: 344 on a 900 frame */
  z-index: 1;
  color: #fff;                                          /* Monogram_LIGHT */
}

/* ══════════════════════════════════════════════════════════
   5. NAV RAIL  (closed state)
   ══════════════════════════════════════════════════════════ */
.rail {
  position: fixed;
  inset: 0 auto 0 0;
  z-index: 30;
  width: var(--rail);
  background: var(--bg);
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  padding: 40px 0;
}

.rail__logo { --mono-size: 56px; }

/* The || trigger — two 1px rules, 9px apart, 24px tall */
.rail__trigger {
  position: absolute;
  top: 50%;
  left: 50%;
  translate: -50% -50%;
  width: 24px;
  height: 24px;
  display: grid;
  place-items: center;
}
/* Centred by transform, not offsets — so the box can be any size
   (bigger touch target on mobile) without the mark drifting. */
.rail__trigger::before,
.rail__trigger::after {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  width: 1px;
  height: 24px;
  background: currentColor;
  transition: translate 0.4s var(--ease);
}
.rail__trigger::before { translate: calc(-50% - 4.5px) -50%; }
.rail__trigger::after  { translate: calc(-50% + 4.5px) -50%; }
.rail__trigger:hover::before { translate: calc(-50% - 6.5px) -50%; }
.rail__trigger:hover::after  { translate: calc(-50% + 6.5px) -50%; }

.rail__social { width: 20px; color: var(--ink); }
.rail__social svg { width: 100%; height: auto; fill: currentColor; }

/* ══════════════════════════════════════════════════════════
   6. FULL-SCREEN MENU  (open state)
   ══════════════════════════════════════════════════════════ */
.menu {
  position: fixed;
  inset: 0;
  z-index: 40;
  background: var(--inverse-bg);
  color: var(--inverse-ink);
  display: flex;
  /* Hidden by default — clipped, not display:none, so it can animate */
  visibility: hidden;
  opacity: 0;
  transition: opacity 0.45s var(--ease), visibility 0s linear 0.45s;
}
.menu.is-open {
  visibility: visible;
  opacity: 1;
  transition: opacity 0.45s var(--ease), visibility 0s;
}

.menu__rail {
  position: relative;
  flex: none;
  /* Must match .rail exactly, or the logo, ✕ and LinkedIn mark jump
     sideways as the menu opens. */
  width: var(--rail);
  border-right: 1px solid var(--line-inverse);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  padding: 40px 0;
}
.menu__rail .rail__logo { --mono-size: 56px; }
.menu__rail .rail__social { color: var(--inverse-ink); }

/* ✕ close — sits in the same optical slot as the || trigger */
.menu__close {
  position: absolute;
  top: 50%; left: 50%;
  translate: -50% -50%;
  width: 28px; height: 28px;
}
.menu__close::before,
.menu__close::after {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  width: 28px; height: 1px;
  background: currentColor;
  translate: -50% -50%;
  transition: rotate 0.4s var(--ease);
}
.menu__close::before { rotate: 45deg; }
.menu__close::after  { rotate: -45deg; }
.menu__close:hover::before { rotate: 135deg; }
.menu__close:hover::after  { rotate: 45deg; }

.menu__list {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-inline: clamp(1.5rem, 7vw, 112px);
}

.menu__item { overflow: hidden; }

.menu__link {
  display: flex;
  align-items: flex-end;
  gap: 40px;
  padding-block: 20px;
  /* Items rise in when the menu opens */
  translate: 0 100%;
  transition: translate 0.65s var(--ease);
}
.menu.is-open .menu__link { translate: 0 0; }
.menu.is-open .menu__item:nth-child(1) .menu__link { transition-delay: 0.08s; }
.menu.is-open .menu__item:nth-child(2) .menu__link { transition-delay: 0.16s; }
.menu.is-open .menu__item:nth-child(3) .menu__link { transition-delay: 0.24s; }

.menu__index {
  align-self: flex-end;
  color: var(--ink-muted);
  padding-bottom: 0.35em;
}

.menu__arrow {
  font-family: var(--font-display);
  font-size: var(--display-m);
  line-height: 0.95;
  opacity: 0;
  translate: -20px 0;
  transition: opacity 0.35s var(--ease), translate 0.35s var(--ease);
}
.menu__link:hover .menu__arrow,
.menu__link:focus-visible .menu__arrow { opacity: 1; translate: 0 0; }

/* ══════════════════════════════════════════════════════════
   7. PAGE — a normal vertical scroll, right of the rail
   ══════════════════════════════════════════════════════════ */
.page { margin-left: var(--rail); }

/* Every section is one screen tall (Figma: 900 on a 900 frame) */
.section {
  position: relative;
  min-height: calc(100svh - var(--offset-top));
  overflow: hidden;
  overflow: clip;                                 /* clip, not hidden: can't be scrolled by focus or scrollIntoView */
}

/* ── Hero ───────────────────────────────────────────────── */
/* Centred on the whole window, not just the space right of the rail:
   extra right padding equal to the rail pulls the centre line left by
   half the rail's width. */
.hero {
  --rail-offset: var(--rail);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(2.5rem, 7svh, 4rem);                 /* Figma: 64 */
  padding: var(--pad-top) calc(var(--gutter) + var(--rail-offset)) var(--pad-top) var(--gutter);
  text-align: center;
}
/* Figma: 406px. The min() guard trades width against height so the
   mark, intro and scroll cue always fit one screen without touching. */
.hero__logo { --mono-size: clamp(180px, min(30vw, 100svh - 360px), 406px); }

.hero__intro {
  max-width: 682px;
  color: var(--ink-muted);
}

.hero__scroll {
  position: absolute;
  left: calc(50% - var(--rail-offset) / 2);
  bottom: 36px;
  translate: -50% 0;
  font-weight: 600;
  letter-spacing: -0.005em;
  text-transform: uppercase;
  white-space: nowrap;
}
.hero__scroll .arrow { display: inline-block; transition: translate 0.4s var(--ease); }
.hero__scroll:hover .arrow { translate: 0 3px; }

/* ── Feature sections — full-bleed image, title low and centred ── */
.feature {
  display: flex;
  background: #111;
  color: var(--inverse-ink);
}
.feature__link {
  position: relative;
  flex: 1;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: var(--gutter) var(--gutter) 20.5svh;    /* Figma: title ends 185 above the foot */
}
.feature__media {
  position: absolute;
  inset: 0;
  overflow: hidden;
  overflow: clip;
}
/* Each image is cropped to match its Figma frame: cover the section,
   then scale/offset by the amounts the design uses. Scaling up from a
   cover fit never opens a gap, so this holds at any aspect ratio. */
.feature__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform-origin: var(--origin, 50% 50%);
  transform: translate(var(--tx, 0), var(--ty, 0)) scale(var(--s, 1));
  transition: filter 0.6s var(--ease);
}
#about   .feature__media img { --origin: 50% 0; --s: 1.347; }
#systems .feature__media img { --s: 1.529; --tx: 1.4%;  --ty: 12.1%; }
#brand   .feature__media img { --s: 1.189; --tx: 9.35%; --ty: -4.6%; }

/* Gradient up from the foot (Figma: 70% black → clear, multiply) */
.feature__media::after {
  content: '';
  position: absolute;
  inset: auto 0 0 0;
  height: 52%;
  background: linear-gradient(to top, rgba(0,0,0,0.7), rgba(0,0,0,0));
  mix-blend-mode: multiply;
}
.feature__title {
  position: relative;
  font-size: min(var(--display-l), 11vw);         /* "UX/UI/Systems" must fit a phone */
  text-align: center;
}

/* Hovering the title (or tabbing to the section) slides in the same
   arrow as the menu and drains the image to black and white. The arrow
   hangs off the right edge, so the title itself never shifts off-centre. */
.feature__arrow {
  position: absolute;
  left: 100%;
  bottom: 0;
  padding-left: 0.25em;
  pointer-events: none;                           /* only the words trigger it */
  opacity: 0;
  translate: -20px 0;
  transition: opacity 0.35s var(--ease), translate 0.35s var(--ease);
}
.feature__title:hover .feature__arrow,
.feature__link:focus-visible .feature__arrow { opacity: 1; translate: 0 0; }

.feature__link:has(.feature__title:hover) .feature__media img,
.feature__link:focus-visible .feature__media img { filter: grayscale(1); }

/* .feature--bw reverses it (About): black and white until hovered, focused,
   or — on phones / touch — scrolled into view (is-inview, set by site.js) */
.feature--bw .feature__media img { filter: grayscale(1); }
.feature--bw .feature__link:has(.feature__title:hover) .feature__media img,
.feature--bw .feature__link:focus-visible .feature__media img,
.feature--bw.is-inview .feature__media img { filter: none; }

/* ── Footer / Contact ───────────────────────────────────── */
.footer {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 4rem;
  background: var(--inverse-bg);
  color: var(--inverse-ink);
  padding: var(--pad-top) var(--gutter) 32px;
}
.footer__cols {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 48px;
  padding-bottom: 64px;
  border-bottom: 1px solid var(--line-inverse);
}
.footer__col h3 { color: var(--ink-muted); margin-bottom: 12px; }
.footer__col li + li { margin-top: 12px; }
.footer__col li { letter-spacing: -0.005em; }
.footer__col a:hover { color: var(--ink-muted); }

.footer__base {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1rem;
  padding-top: 64px;
  color: var(--ink-muted);
  font-size: var(--body-s);
  line-height: 1.55;
}
.footer__base a:hover { color: var(--inverse-ink); }

/* ══════════════════════════════════════════════════════════
   8. WORK OVERVIEW  — Figma "Work Overview" (work.html)
   ══════════════════════════════════════════════════════════ */

/* ── Intro: dark title panel + one image column per discipline ── */
.work-intro { display: flex; }

.work-intro__panel {
  flex: 0 0 clamp(300px, 33.4%, 448px);           /* Figma: 448 of 1342 */
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 3rem;
  padding: 64px var(--gutter);
  background: var(--inverse-bg);
  color: var(--inverse-ink);
}
.work-intro__panel p { letter-spacing: -0.005em; }

.work-intro__col {
  position: relative;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  overflow: clip;
  background: #111;
  color: var(--inverse-ink);
  container-type: inline-size;                    /* title scales with the column */
}
/* Same crop technique as the homepage features: cover, then scale/offset.
   object-fit clips the photo to the <img> box BEFORE the transform, so a
   translate can only use the slack the scale adds — (s − 1) / 2 each way —
   or the column's background shows through. Bigger shifts go in --pos
   (object-position), which picks the crop without moving the box. */
.work-intro__col img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--pos, 50% 50%);
  transform-origin: 50% 50%;
  transform: translate(var(--tx, 0), var(--ty, 0)) scale(var(--s, 1));
  filter: grayscale(1);                           /* black and white until hovered */
  transition: filter 0.6s var(--ease);
}
.work-intro__col--systems img { --s: 1.52;  --tx: -5.5%; --ty: 17%; }
.work-intro__col--brand   img { --s: 1.181; --pos: 38.5% 50%; --ty: -5.4%; }

/* Dark band through the middle (Figma: clear → 70% black → clear, multiply) */
.work-intro__col::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(0,0,0,0), rgba(0,0,0,0.7) 50%, rgba(0,0,0,0));
  mix-blend-mode: multiply;
}
.work-intro__title {
  position: absolute;
  z-index: 1;
  top: 49.7%;                                     /* Figma: 447 of 900 */
  left: 0;
  right: 0;
  padding-inline: var(--gutter);                  /* 48px on desktop */
  font-size: min(2.6075rem, 9.33cqi);             /* Figma: 41.72px in a 447 column */
  line-height: 0.9;
  letter-spacing: -0.04em;
  text-align: left;
  pointer-events: none;                           /* only the words themselves are a hover target */
}
.work-intro__label {
  position: relative;                             /* anchors the arrow */
  pointer-events: auto;
}
/* The label is an inline box (font ascent + descent tall); `line-height:
   normal` gives the arrow that same box from the same top edge, so the two
   share a baseline and the arrow sits on the middle of the caps. */
.work-intro__label .feature__arrow {
  top: 0;
  bottom: auto;
  line-height: normal;
}

/* Hover: arrow in, and the black-and-white image comes into colour
   (the reverse of the homepage sections) */
.work-intro__label:hover .feature__arrow,
.work-intro__col:focus-visible .feature__arrow { opacity: 1; translate: 0 0; }

.work-intro__col:has(.work-intro__label:hover) img,
.work-intro__col:focus-visible img,
.work-intro__col.is-inview img { filter: none; }  /* is-inview: phones/touch, set by site.js */

/* ── Project lists — one per discipline ─────────────────── */
.work-list {
  background: var(--surface);
  padding: 64px var(--gutter);
}
.work-list__title {
  font-size: 2rem;                                /* Figma Heading/M: 32 */
  font-weight: 400;
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin-bottom: 48px;
}
.work-list__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 48px;
}

.project-card {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.project-card__media {
  position: relative;
  aspect-ratio: 275 / 528;                        /* Figma card image at 1440 */
  overflow: hidden;
  overflow: clip;
  background: var(--bg);
}
.project-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.project-card__tags {
  position: absolute;
  top: 0;
  right: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 4px;
  padding: 12px;
}
.project-card__tags li {
  display: flex;
  align-items: center;
  height: 20px;
  padding-inline: 8px;
  border-radius: 4px;
  background: var(--surface);
}
.project-card__title {
  font-size: 1.25rem;                             /* Figma: 20 */
  font-weight: 400;
  line-height: 1.15;
  letter-spacing: -0.02em;
}
.project-card__link { display: flex; flex-direction: column; gap: 12px; }
.project-card__link .project-card__media img { transition: scale 0.6s var(--ease); }
.project-card__link:hover .project-card__media img { scale: 1.03; }
.project-card__link:hover .project-card__title { text-decoration: underline; text-underline-offset: 0.15em; text-decoration-thickness: 1px; }
.project-card__client { color: var(--ink-muted); letter-spacing: -0.005em; }
.project-card__discipline { font-size: var(--label); letter-spacing: -0.005em; }

/* ── 4×2 list that fits one screen (UX/UI/Systems) ──────────
   The section is one screen tall; images flex to share what's left
   after the heading and card text. Each card is a subgrid spanning an
   image row and a text row, so all images in a row are the same height
   even when a title wraps. Desktop only — phones scroll as normal. */
@media (min-width: 901px) {
  .work-list--fit {
    height: max(100svh, 680px);
    display: flex;
    flex-direction: column;
    padding-block: 48px;
  }
  .work-list--fit .work-list__title { margin-bottom: 32px; }
  .work-list--fit .work-list__grid {
    flex: 1;
    min-height: 0;
    grid-template-rows: minmax(0, 1fr) auto minmax(0, 1fr) auto;
    gap: 32px 48px;
  }
  .work-list--fit .project-card {
    grid-row: span 2;
    display: grid;
    grid-template-rows: subgrid;
    row-gap: 12px;
  }
  /* A linked card passes the same two rows through its link (not
     display:contents, which would lose the keyboard focus outline) */
  .work-list--fit .project-card__link {
    grid-row: 1 / span 2;
    display: grid;
    grid-template-rows: subgrid;
    row-gap: 12px;
  }
  .work-list--fit .project-card__media { aspect-ratio: auto; min-height: 0; }
}

/* ══════════════════════════════════════════════════════════
   8b. COMING SOON  — Figma "Coming very soon" (coming-soon.html)
   The splash composition, held: portrait, white monogram that keeps
   reassembling itself, and the essentials in the darkened lower band.
   ══════════════════════════════════════════════════════════ */
.soon {
  position: relative;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  background: #111;
  color: #fff;
  overflow: hidden;
  overflow: clip;
}
.soon__media {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Darkening band across the lower third (Figma: 50% black, multiply) */
.soon::after {
  content: '';
  position: absolute;
  inset: auto 0 0 0;
  height: 34.3%;
  background: rgba(0,0,0,0.5);
  mix-blend-mode: multiply;
}

.soon__mark {
  position: relative;
  z-index: 1;
  flex: 1;
  display: grid;
  place-items: center;
  --mono-size: clamp(160px, min(38svh, 60vw), 344px);   /* Figma: 344 on a 900 frame */
}
.soon__mark .monogram { color: #fff; }                /* Monogram_LIGHT */

.soon__info {
  position: absolute;
  z-index: 2;                                         /* above the band */
  inset: auto 0 0 0;
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 2rem;
  padding: 0 var(--gutter) clamp(2rem, 5svh, 3rem);
}
.soon__label { color: rgba(255,255,255,0.7); margin-bottom: 12px; }
.soon__title {
  font-size: 2rem;                                    /* Heading/M */
  font-weight: 400;
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin-bottom: 16px;
}
.soon__text {
  max-width: 440px;
  color: rgba(255,255,255,0.8);
  letter-spacing: -0.005em;
}
.soon__contact { text-align: right; }
.soon__contact a {
  display: block;
  font-size: var(--body-l);
  line-height: 1.55;
  letter-spacing: -0.01em;
}
.soon__contact a:hover { color: rgba(255,255,255,0.7); }

/* ══════════════════════════════════════════════════════════
   8c. CASE STUDY  — Figma "Digital Project / Notification System"
   A template: every project page uses these same classes.
   The Figma hero is drawn at 1920 and scaled ×1.43 from the 1342 content
   width; values here are the 1342 originals. The body column is native.
   ══════════════════════════════════════════════════════════ */
.case { background: var(--surface); }

/* ── Hero ───────────────────────────────────────────────── */
.case-hero {
  position: relative;
  min-height: calc(100svh - var(--offset-top));
  display: flex;
  flex-direction: column;
  background: radial-gradient(ellipse 90% 110% at 62% 30%, #4d4d4d 0%, #1f1f1f 100%);
  color: var(--inverse-ink);
  font-family: var(--font-body);
  overflow: hidden;
  overflow: clip;
}
.case-hero__head {
  position: relative;
  z-index: 1;                                     /* the title sits over the UI image */
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 3rem;
  padding: var(--pad-top) var(--gutter) 48px;
}
.case-hero__eyebrow {
  font-size: 0.875rem;                            /* Figma: 20 at 1920 */
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-bottom: 24px;
}
.case-hero__title {
  max-width: 9.5em;
  font-size: clamp(2.75rem, 1rem + 5.4vw, 5.6rem); /* Figma: 128 at 1920 → 90 */
  font-weight: 400;
  line-height: 0.9;
  letter-spacing: -0.04em;
}
.case-hero__intro {
  max-width: 500px;
  font-size: var(--body-l);
  line-height: 1.55;
  letter-spacing: -0.01em;
}
/* The product UI, right of centre and allowed to bleed off the edge */
.case-hero__ui {
  position: absolute;
  top: 68px;
  left: 40.2%;
  width: 56.3%;                                   /* Figma: 1081 of 1920 */
  height: auto;
}
.case-hero__meta {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 32px;
  margin: 0 var(--gutter);
  padding: 16px 0 48px;
  border-top: 1px solid var(--line);
}
.case-hero__meta dt {
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-bottom: 10px;
}
.case-hero__meta dd { margin: 0; font-size: 0.875rem; line-height: 1.6; }

/* ── Body column ────────────────────────────────────────── */
.case-body {
  display: flex;
  flex-direction: column;
  gap: 64px;
  max-width: calc(914px + 2 * var(--gutter));     /* Figma: 914 column */
  margin: 0 auto;
  padding: 96px var(--gutter) 128px;
  color: var(--ink-muted);
  font-family: var(--font-body);
  font-size: var(--body-l);
  line-height: 1.55;
}
.case-body > hr { width: 100%; margin: 0; border: 0; border-top: 1px solid var(--line); }

.case-heading { display: flex; flex-direction: column; gap: 12px; }
.case-eyebrow {
  font-size: 1.5rem;
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(46,48,57,0.4);
}
.case-title {
  font-size: clamp(2rem, 1.4rem + 2vw, 3rem);     /* Figma: 48 */
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: 0.02em;
  color: var(--ink);
}

/* Lists, paragraphs and tables inside the narrative use Montserrat */
.case-copy { font-family: var(--font-body); letter-spacing: -0.01em; }
.case-copy ul, .case-copy ol { margin: 0; padding-left: 30px; }
.case-copy ul { list-style: disc; }
.case-copy p + ul, .case-copy ul + p, .case-copy ol + p, .case-copy p + ol { margin-top: 0; }
.case-copy ul + p, .case-copy ol + p { margin-top: 1.55em; }

/* ── Numbered cards (problems, principles) ──────────────── */
.case-cards {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(var(--cols, 2), 1fr);
  gap: 40px;
  align-items: start;
}
.case-cards--3 { --cols: 3; align-items: stretch; }
.case-card {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 24px;
  border-radius: 12px;
  background: rgba(46,48,57,0.1);
}
.case-card__num {
  height: 34px;                                   /* cap height — trims the line box like Figma */
  display: flex;
  align-items: flex-end;
  font-size: 3rem;
  font-weight: 300;
  line-height: 1;
  color: rgba(46,48,57,0.2);
}
.case-card__title { display: block; font-size: 1.5rem; font-weight: 700; }

/* ── Persona ────────────────────────────────────────────── */
.case-persona {
  display: grid;
  grid-template-columns: 297px 1fr;
  gap: 48px;
  align-items: start;
}
.case-persona__profile { display: flex; flex-direction: column; gap: 24px; }
.case-tag {
  align-self: flex-start;
  padding: 4px 8px;
  background: var(--ink);
  color: var(--inverse-ink);
  font-size: 1.25rem;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.case-persona__who { display: flex; align-items: center; gap: 16px; }
.case-persona__who img { width: 74px; height: 74px; border-radius: 50%; }
.case-persona__name { font-size: 1.5rem; font-weight: 600; line-height: 1.2; white-space: nowrap; }
.case-persona__details { display: grid; grid-template-columns: 100px 1fr; gap: 16px; margin: 0; }
.case-persona__details dt {
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.2;
  text-transform: uppercase;
  color: #6d7280;
  padding-top: 0.2em;
}
.case-persona__details dd { margin: 0; font-weight: 500; line-height: 1.2; }
.case-persona__story { display: flex; flex-direction: column; gap: 48px; }

/* ── Quote card ─────────────────────────────────────────── */
.case-quote {
  margin: 0;
  padding: 24px 24px 24px calc(24px + 0.45em);
  border-radius: 12px;
  background: rgba(46,48,57,0.05);
  color: var(--ink);
  font-size: 1.5rem;
  line-height: 1.6;
  letter-spacing: -0.02em;
  text-indent: -0.45em;                           /* hanging opening quote mark */
}
.case-quote cite {
  font-style: normal;
  font-size: var(--body-l);
  color: var(--ink-muted);
  letter-spacing: 0;
}
.case-quote cite.is-block { display: block; text-indent: 0; }

/* ── Figures with a caption bar ─────────────────────────── */
.case-figure { margin: 0; }
.case-figure__frame {
  position: relative;
  aspect-ratio: var(--ratio);
  overflow: hidden;
  overflow: clip;
}
/* Each image keeps the crop it has in Figma: --w/--h size, --x/--y offset */
.case-figure__frame img {
  position: absolute;
  left: var(--x, 0);
  top: var(--y, 0);
  width: var(--w, 100%);
  height: var(--h, 100%);
  max-width: none;
}
.case-figure figcaption {
  display: flex;
  align-items: center;
  min-height: 32px;
  padding: 4px 16px;
  background: rgba(46,48,57,0.7);
  color: #dedcd7;
  font-family: var(--font-body);
  font-size: var(--body-s);
  line-height: 1.55;
}
/* Research collage: two screenshots, the second overlapping the first */
.case-collage { position: relative; aspect-ratio: 914 / 747; }
.case-collage__a,
.case-collage__b { position: absolute; left: 0; width: 100%; overflow: hidden; overflow: clip; }
.case-collage__a { top: 0; height: 76.1%; }
.case-collage__b { top: 53.65%; height: 46.25%; }
.case-collage img { position: absolute; left: 0; top: 0; max-width: none; }
.case-collage__a img { width: 100%; height: 100%; object-fit: cover; }
.case-collage__b img { width: 104.37%; height: 182.26%; }

/* ── Tables (logic matrix, results) ─────────────────────── */
.case-table-wrap { overflow-x: auto; }
.case-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-body);
  letter-spacing: -0.01em;
  text-align: left;
}
.case-table th {
  padding: 0 16px 25px 0;
  font-size: var(--body-m);
  font-weight: 400;
  line-height: 1.6;
  letter-spacing: -0.005em;
  vertical-align: bottom;
}
.case-table td { padding: 25px 16px 25px 0; vertical-align: top; }
.case-table tr + tr td,
.case-table thead + tbody td { border-top: 0.5px solid var(--ink-muted); }
.case-table th:last-child,
.case-table td:last-child { padding-right: 0; }
.case-table--matrix th:nth-child(1), .case-table--matrix th:nth-child(4) { width: 240px; }
.case-table--matrix th:nth-child(2), .case-table--matrix th:nth-child(3) { width: 100px; }
.case-table--results td { vertical-align: middle; }
.case-table--results th:last-child,
.case-table--results td:last-child { text-align: right; width: 100px; }

/* Up/down result arrow — the Figma icon as a mask, so it takes the ink colour */
.case-arrow {
  display: inline-block;
  width: 24px;
  height: 24px;
  vertical-align: middle;
  background: var(--ink);
  -webkit-mask: url("../images/work/notification-system/arrow-down.svg") center / contain no-repeat;
          mask: url("../images/work/notification-system/arrow-down.svg") center / contain no-repeat;
}
.case-arrow.is-up { rotate: 180deg; }

/* ── Wide image rows — break out of the column ──────────── */
.case-wide {
  align-self: center;
  width: min(1578px, calc(100vw - var(--rail) - 2 * var(--gutter)));
  display: grid;
  grid-template-columns: repeat(var(--cols, 2), 1fr);
  gap: 31px 40px;
}
.case-wide--3 { --cols: 3; gap: 31px 32px; }
.case-wide .case-figure__frame { --ratio: 769 / 483; }
.case-wide--3 .case-figure__frame { --ratio: 1444 / 907; }
.case-wide .case-figure__frame img { --y: -5.62%; --h: 105.62%; }

.case-shot { width: 100%; height: auto; }

/* ── Previous / next case study (assets/js/case-pager.js) ── */
.case-pager {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: end;
  gap: 32px;
  max-width: calc(914px + 2 * var(--gutter));
  margin: 0 auto;
  padding: 0 var(--gutter) 96px;
}
.case-pager::before {                             /* rule, aligned to the column */
  content: '';
  grid-column: 1 / -1;
  border-top: 1px solid var(--line);
  margin-bottom: 32px;
}
.case-pager__all {
  grid-column: 2;
  grid-row: 2;
  font-size: var(--label);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
  padding-bottom: 0.3em;
}
.case-pager__all:hover { color: var(--ink); }
.case-pager__link { display: flex; flex-direction: column; gap: 6px; }
.case-pager__link--prev { grid-column: 1; grid-row: 2; }
.case-pager__link--next { grid-column: 3; grid-row: 2; text-align: right; align-items: flex-end; }
.case-pager__dir {
  font-size: var(--label);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.case-pager__arrow { display: inline-block; transition: translate 0.4s var(--ease); }
.case-pager__link--prev:hover .case-pager__arrow { translate: -4px 0; }
.case-pager__link--next:hover .case-pager__arrow { translate: 4px 0; }
.case-pager__title {
  font-size: 1.5rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.case-pager__link:hover .case-pager__title { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.15em; }
.case-pager__client { color: var(--ink-muted); }

/* ── Section indicator (assets/js/case-progress.js) ─────────
   One short line per section on the right edge, vertically centred.
   The current section's line is longer and solid. Flips to light
   over the dark hero and footer. */
.case-progress {
  position: fixed;
  z-index: 25;                                    /* under the rail (30) and menu (40) */
  right: 24px;
  top: 50%;
  translate: 0 -50%;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  color: var(--ink);
  transition: color 0.4s var(--ease);
}
.case-progress.is-inverse { color: var(--inverse-ink); }
.case-progress button {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  width: 32px;
  height: 20px;                                   /* a usable hit area for a 1px line */
}
.case-progress button::before {
  content: '';
  width: 10px;
  height: 2px;
  background: currentColor;
  opacity: 0.35;
  transition: width 0.4s var(--ease), opacity 0.4s var(--ease);
}
.case-progress button:hover::before { opacity: 0.7; }
.case-progress button.is-active::before { width: 22px; opacity: 1; }

/* ── Animated screen (assets/js/accounts-animation.js) ──────
   A 1440×900 stage scaled to the column. The poster image shows until
   the vector art has loaded, and stays if scripts fail. */
.case-anim {
  position: relative;
  margin: 0;
  aspect-ratio: 1440 / 900;
  overflow: hidden;
  overflow: clip;
  background: #f2f2f2;
  box-shadow: 0 4px 12px rgba(0,0,0,0.12);
}
.case-anim__poster { width: 100%; height: 100%; object-fit: cover; }
.case-anim.is-ready .case-anim__poster { visibility: hidden; }

.case-anim__toggle {
  position: absolute;
  right: 12px;
  bottom: 12px;
  z-index: 1;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: rgba(46,48,57,0.6);
  color: #fff;
  opacity: 0;
  transition: opacity 0.3s var(--ease), background 0.2s var(--ease);
}
.case-anim:hover .case-anim__toggle,
.case-anim__toggle:focus-visible,
.case-anim__toggle.is-paused { opacity: 1; }
.case-anim__toggle:hover { background: rgba(46,48,57,0.85); }
/* Pause: two bars. Play: a triangle. */
.case-anim__toggle::before,
.case-anim__toggle::after {
  content: '';
  position: absolute;
  top: 12px;
  width: 4px;
  height: 12px;
  background: currentColor;
}
.case-anim__toggle::before { left: 12px; }
.case-anim__toggle::after  { left: 20px; }
.case-anim__toggle.is-paused::after { display: none; }
.case-anim__toggle.is-paused::before {
  left: 14px;
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 6px 0 6px 10px;
  border-color: transparent transparent transparent currentColor;
  background: none;
}
@media (hover: none) { .case-anim__toggle { opacity: 1; } }

/* ══════════════════════════════════════════════════════════
   9. RESPONSIVE — below 900px the rail becomes a top bar
   ══════════════════════════════════════════════════════════ */
@media (max-width: 900px) {
  :root { --offset-top: var(--rail-mobile); }

  .rail {
    inset: 0 0 auto 0;
    width: 100%;
    height: var(--rail-mobile);
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
    padding: 0 var(--gutter);
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }
  .rail__logo { --mono-size: 36px; }
  /* Must stay `relative`, not `static` — the two 1px rules are absolutely
     positioned children and would otherwise anchor to the whole bar.
     Both buttons get a 44px box: matching centres, and a real touch target. */
  .rail__trigger,
  .menu__close { position: relative; top: auto; left: auto; translate: none; width: 44px; height: 44px; }
  .rail__social { display: none; }

  .menu { flex-direction: column; }
  .menu__rail {
    width: 100%;
    height: var(--rail-mobile);
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
    padding: 0 var(--gutter);
    border-right: 0;
    border-bottom: 1px solid var(--line-inverse);
  }
  .menu__rail .rail__logo { --mono-size: 36px; }
  .menu__list { padding-block: clamp(2rem, 10vw, 4rem); }
  .menu__link { gap: 20px; }

  .page { margin-left: 0; padding-top: var(--rail-mobile); }
  .hero { --rail-offset: 0px; }                   /* rail is a top bar — nothing to offset */

  .footer__cols { grid-template-columns: repeat(2, 1fr); gap: 2.5rem 1.5rem; }

  .work-intro { flex-wrap: wrap; }
  .work-intro__panel { flex: 1 0 100%; padding-block: 3rem; }
  .work-intro__col { flex: 1 0 100%; min-height: 50svh; }   /* stacked, one above the other */
  /* One full-width card per row; landscape images so eight cards
     don't turn into an endless scroll */
  .work-list__grid { grid-template-columns: 1fr; gap: 2.5rem; }
  .project-card__media { aspect-ratio: 4 / 3; min-height: 0; }   /* min-height: 0 so a tall image can't stretch the box */

  /* Coming soon: the copy joins the flow under the mark, and a taller
     gradient replaces the band so every line stays legible */
  .soon__info {
    position: relative;
    flex-direction: column;
    align-items: flex-start;
    gap: 1.5rem;
  }
  .soon__contact { text-align: left; }
  .soon::after {
    height: 65%;
    background: linear-gradient(to top, rgba(0,0,0,0.8) 40%, rgba(0,0,0,0));
  }
  .soon__title { font-size: 1.625rem; }

  /* Case study hero, in reading order: eyebrow + title, image, intro,
     project info. The head wrapper steps aside (display: contents) so its
     children and the image can be ordered as one stack. */
  .case-hero__head { display: contents; }
  .case-hero__head > div { order: 1; position: relative; z-index: 1; padding: var(--pad-top) var(--gutter) 2rem; }
  .case-hero__ui { order: 2; position: relative; top: auto; left: auto; width: 100%; padding: 0 var(--gutter); margin-bottom: 2rem; }
  .case-hero__intro { order: 3; padding: 0 var(--gutter); margin-bottom: 2.5rem; }
  .case-hero__meta { order: 4; grid-template-columns: 1fr; gap: 20px; }
  .case-body { padding-top: 64px; gap: 48px; }
  .case-cards, .case-cards--3 { --cols: 1; gap: 24px; }
  .case-persona { grid-template-columns: 1fr; gap: 32px; }
  .case-wide { width: 100%; --cols: 1; }
  .case-wide--3 { --cols: 2; gap: 16px; }
  .case-table--matrix { min-width: 560px; }
  /* A tall phone crop is already close in on the face — drop the desktop zoom */
  #about .feature__media img { --s: 1; }
  /* Tuck the indicator into the 24px gutter so it never sits on the text */
  .case-pager { grid-template-columns: 1fr 1fr; gap: 24px 16px; padding-bottom: 64px; }
  .case-pager__link--prev { grid-column: 1; grid-row: 2; }
  .case-pager__link--next { grid-column: 2; grid-row: 2; }
  .case-pager__all { grid-column: 1 / -1; grid-row: 3; justify-self: center; }
  .case-pager__title { font-size: 1.125rem; }
  .case-progress { right: 4px; }
  .case-progress button { width: 20px; height: 16px; }
  .case-progress button::before { width: 8px; }
  .case-progress button.is-active::before { width: 16px; }
}

/* Short landscape phones — stop the hero overflowing */
@media (max-height: 520px) {
  .hero__logo { --mono-size: 140px; }
}

/* ══════════════════════════════════════════════════════════
   10. REDUCED MOTION
   ══════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
  .menu__link { translate: 0 0; }
  /* The monogram holds its assembled state — the JS sequence never starts */
}
