/* ============================================================
   Steve Tamekuni — Portfolio
   Design system per context/portfolio-build-spec.md (Part 1)
   Visual target: Julia Wang (juliawang.net) — match closely.
   ============================================================ */

/* ---------- Fonts ----------
   Space Grotesk (display) + Geist (body/labels) loaded via
   Google Fonts <link> in each HTML <head>. Fallback stacks below. */

/* ============================================================
   1. TOKENS
   ============================================================ */
:root {
  /* Color — light mode (build this first, per spec) */
  --bg:            #FAFAF8;  /* warm near-white */
  --surface:       #FFFFFF;
  --text-primary:  #111111;  /* headings, titles */
  --text-body:     #555555;  /* body paragraphs */
  --text-muted:    #6B6B6B;  /* years, secondary metadata, captions, footer
                                — 5.33:1 on #FFF, 5.10:1 on --bg (WCAG AA) */
  --accent:        #4F46E5;  /* indigo — labels, links, active */
  --accent-hover:  #4338CA;
  --border:        #E8E8E5;  /* hairline card / image frames */
  --divider:       #D7D7D1;  /* horizontal separator lines — darker than frames */
  --badge-bg:      #111111;  /* "password protected" pill */
  --badge-text:    #FFFFFF;
  /* Tinted block behind a research finding, mixed into --surface (findings sit
     inside a .cs-figure). Resolves to #F4F4FD — 6.82:1 with --text-body,
     17.27:1 with --text-primary. */
  --finding-bg:    color-mix(in srgb, var(--accent) 6%, var(--surface));

  /* Typography */
  --font-display: "Space Grotesk", "Space Grotesk Fallback", system-ui, sans-serif;
  --font-body:    "Geist", "Geist Fallback", system-ui, sans-serif;

  /* Fluid type scale */
  --fs-hero:    clamp(2.75rem, 6vw, 4.5rem);   /* big hero headline */
  --fs-h1:      clamp(2.25rem, 4.5vw, 3.25rem);/* page titles */
  --fs-h2:      clamp(1.5rem, 2.5vw, 2rem);    /* section subheads */
  --fs-h3:      1.375rem;                        /* card titles */
  --fs-body-lg: 1.1875rem;                       /* lead paragraphs */
  --fs-body:    1.0625rem;
  --fs-small:   0.9375rem;
  --fs-label:   0.75rem;                          /* eyebrow / labels */

  /* Spacing rhythm — generous vertical air is the biggest "expensive" tell */
  --space-xs:  0.5rem;
  --space-sm:  1rem;
  --space-md:  2rem;
  --space-lg:  4rem;
  --space-xl:  7rem;   /* between major sections */
  --space-2xl: 10rem;

  /* Layout */
  --content-width: 1180px;
  --gutter: clamp(1.5rem, 5vw, 4rem);

  /* Radii */
  --radius-card: 14px;
  --radius-pill: 999px;
  --radius-btn: 8px;

  --label-tracking: 0.14em;
}

/* Light is the hard default (per build-spec: build light first, nail it).
   Dark is opt-in only — applied when the user clicks the toggle, which sets
   [data-theme="dark"] and is remembered. We intentionally do NOT auto-follow
   the OS `prefers-color-scheme: dark` setting, so the site always loads light
   regardless of the visitor's system theme. */
:root[data-theme="dark"] {
  --bg:           #0E0E10;
  --surface:      #17171A;
  --text-primary: #F5F5F3;
  --text-body:    #B4B4B0;
  --text-muted:   #8C8C88;  /* 5.30:1 on --surface, 5.71:1 on --bg (WCAG AA) */
  --accent:       #8B84FF;
  --accent-hover: #A29BFF;
  --border:       #2A2A2E;
  --divider:      #38383F;
  --badge-bg:     #F5F5F3;
  --badge-text:   #111111;
  /* Resolves to #252435 — 7.30:1 with --text-body, 13.92:1 with --text-primary. */
  --finding-bg:   color-mix(in srgb, var(--accent) 12%, var(--surface));
}

/* ============================================================
   2. RESET / BASE
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  background: var(--bg);
  color: var(--text-body);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  transition: background-color 0.3s ease, color 0.3s ease;
  /* Sticky footer: pin .footer below content on every page, short or long. */
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
body > main { flex: 1 0 auto; }
body > .footer { flex-shrink: 0; }

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

a { color: inherit; text-decoration: none; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  color: var(--text-primary);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.02em;
}

p { text-wrap: pretty; }

::selection { background: var(--accent); color: #fff; }

/* ============================================================
   3. LAYOUT PRIMITIVES
   ============================================================ */
.container {
  width: 100%;
  max-width: var(--content-width);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--space-xl); }
.section--tight { padding-block: var(--space-lg); }

.divider {
  height: 1px;
  border: 0;
  background: var(--divider);
  margin: 0;
}

/* ============================================================
   4. TYPOGRAPHY HELPERS
   ============================================================ */
.label {
  font-family: var(--font-body);
  font-size: var(--fs-label);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: var(--label-tracking);
  color: var(--accent);
}

.eyebrow { /* same as .label, semantic alias for hero/case eyebrows */
  font-family: var(--font-body);
  font-size: var(--fs-label);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: var(--label-tracking);
  color: var(--accent);
  display: inline-block;
}

.text-muted { color: var(--text-muted); }
.lead { font-size: var(--fs-body-lg); color: var(--text-body); }

.link-arrow {
  color: var(--accent);
  font-weight: 500;
  transition: color 0.2s ease;
}
.link-arrow:hover { color: var(--accent-hover); }

/* ============================================================
   5. NAV
   ============================================================ */
.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid transparent;
}
.nav__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 72px;
}
.nav__wordmark {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.8125rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--text-primary);
}
.nav__links {
  display: flex;
  align-items: center;
  gap: 1.75rem;
  list-style: none;
  padding: 0;
}
.nav__link {
  font-size: var(--fs-small);
  color: var(--text-body);
  transition: color 0.2s ease;
}
.nav__link:hover { color: var(--text-primary); }

.btn-outline {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  padding: 0.5rem 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-btn);
  font-size: var(--fs-small);
  color: var(--text-primary);
  background: transparent;
  cursor: pointer;
  transition: border-color 0.2s ease, background-color 0.2s ease;
}
.btn-outline:hover { border-color: var(--text-muted); background: color-mix(in srgb, var(--text-primary) 4%, transparent); }

.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border: 1px solid transparent;
  border-radius: var(--radius-btn);
  background: transparent;
  color: var(--text-body);
  cursor: pointer;
  transition: color 0.2s ease, background-color 0.2s ease;
}
.theme-toggle:hover { color: var(--text-primary); background: color-mix(in srgb, var(--text-primary) 5%, transparent); }
.theme-toggle .moon { display: block; }
.theme-toggle .sun  { display: none; }
:root[data-theme="dark"] .theme-toggle .moon,
[data-prefers-dark] .theme-toggle .moon { display: none; }
:root[data-theme="dark"] .theme-toggle .sun,
[data-prefers-dark] .theme-toggle .sun  { display: block; }

/* ============================================================
   6. HERO (homepage)
   ============================================================ */
.hero { padding-block: clamp(3rem, 8vw, 6rem) var(--space-md); }
.hero__headline {
  font-size: var(--fs-hero);
  max-width: 16ch;
  margin-top: 1.25rem;
  letter-spacing: -0.03em;
  line-height: 1.12; /* slightly looser than the base 1.08 — matches juliawang.net */
}
.hero__subhead {
  font-size: var(--fs-body-lg);
  color: var(--text-body);
  max-width: 52ch;
  margin-top: 1.75rem;
}
.hero__colophon {
  font-size: var(--fs-small);
  color: var(--text-muted);
  margin-top: 1.75rem;
  line-height: 1.7;
}

/* ============================================================
   7. PREVIOUSLY AT
   ============================================================ */
.prev-at { padding-block: 1.5rem var(--space-lg); }
.prev-at__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: clamp(2rem, 4vw, 3.25rem);
  margin-top: 1.75rem;
}
/* Logos are black-on-transparent silhouettes; opacity gives the single grey tone. */
.prev-at__logo {
  display: block;
  width: auto;
  opacity: 0.42;
  transition: opacity 0.2s ease;
}
.prev-at__logo:hover { opacity: 0.72; }
/* Optically balanced heights (matched by eye, not by bounding box). */
.logo--meta         { height: 26px; }
.logo--zoom         { height: 19px; }
.logo--linkedin     { height: 27px; }
.logo--malwarebytes { height: 21px; }
.logo--elliemae     { height: 23px; }
.logo--ibm          { height: 29px; }
/* Dark mode: invert the black silhouettes to a light grey. */
:root[data-theme="dark"] .prev-at__logo,
[data-prefers-dark] .prev-at__logo { filter: invert(1); opacity: 0.55; }

/* ============================================================
   8. WORK GRID + CARDS
   ============================================================ */
.work-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 2.5rem;
  margin-top: 2.5rem;
}

/* height:100% fills the stretched grid cell so cards in a row match height;
   margin-top:auto on the footer keeps tag/arrow rows aligned across the row
   even when descriptions differ in length. */
/* Card = ONE bordered container; image flush to the top/side edges, content padded below. */
.card {
  display: flex; flex-direction: column; height: 100%;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  overflow: hidden;
}

.card__media {
  position: relative;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* Gradient fills — deepened so the image area reads as a distinct region (match Julia). */
.card__media--g1 { background: linear-gradient(135deg, #D6CCF6 0%, #E6DEFA 45%, #CFEADB 100%); }
.card__media--g2 { background: linear-gradient(135deg, #CFE0FB 0%, #DCE6FB 50%, #E6D9FA 100%); }
.card__media--g3 { background: linear-gradient(135deg, #EAD9FF 0%, #7C5CFF 100%); }
:root[data-theme="dark"] .card__media { opacity: 0.92; }
/* Real screenshot thumbnails fill the media box; top-anchored so screen headers show. */
.card__media img { width: 100%; height: 100%; object-fit: cover; object-position: top; display: block; }

.placeholder-note {
  font-family: var(--font-body);
  font-size: var(--fs-small);
  font-weight: 500;
  color: #6B6B80;
  text-align: center;
  padding: 1rem 1.5rem;
  letter-spacing: 0.01em;
}
.placeholder-note::before { content: "▨  "; opacity: 0.6; }

.card__badge {
  position: absolute;
  top: 12px;
  right: 12px;
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  padding: 0.35rem 0.7rem;
  background: var(--badge-bg);
  color: var(--badge-text);
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-size: 0.625rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

.card__meta {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 1.4rem 1.5rem 0;
}
.card__company { /* uses .label */ }
.card__year { font-size: var(--fs-small); color: var(--text-muted); }

.card__title {
  font-size: 1.5rem;
  line-height: 1.15;
  margin-top: 0.5rem;
  padding: 0 1.5rem;
  color: var(--text-primary);
  transition: color 0.2s ease;
}
.card:hover .card__title { color: var(--accent); }

.card__desc {
  font-size: 0.9375rem;
  color: var(--text-body);
  margin-top: 0.6rem;
  padding: 0 1.5rem;
  line-height: 1.5;
}

.card__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: auto;
  padding: 1.25rem 1.5rem 1.5rem;
}
.tags { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.tag {
  font-size: 0.8125rem;
  color: var(--text-body);
  padding: 0.3rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
}
.card__arrow {
  font-size: 1.1rem;
  color: var(--text-muted);
  transition: transform 0.2s ease, color 0.2s ease;
}
.card:hover .card__arrow { transform: translateX(4px); color: var(--accent); }

/* ============================================================
   9. BACKGROUND SPLIT (homepage)
   ============================================================ */
.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 6vw, 5rem);
  align-items: start;
}
.split__lead {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-h2);
  color: var(--text-primary);
  letter-spacing: -0.02em;
  line-height: 1.15;
}
.split__body p + p { margin-top: 1rem; }
.split__body .link-arrow { display: inline-block; margin-top: 1.25rem; }

/* ============================================================
   10. FOOTER
   ============================================================ */
.footer { padding-block: var(--space-lg); }
.footer__inner {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 1rem;
}
.footer__copy {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--fs-small);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--text-muted);
}
.footer__links { display: flex; gap: 1.75rem; }
.footer__links a { font-size: var(--fs-small); color: var(--text-body); transition: color 0.2s ease; }
.footer__links a:hover { color: var(--text-primary); }
.footer__colophon { font-size: var(--fs-small); color: var(--text-muted); margin-top: 1rem; }

/* ============================================================
   11. ABOUT PAGE
   ============================================================ */
.back-link {
  display: inline-block;
  font-size: var(--fs-small);
  color: var(--text-body);
  margin-bottom: var(--space-md);
  transition: color 0.2s ease;
}
.back-link:hover { color: var(--text-primary); }

.about {
  display: grid;
  grid-template-columns: 320px 1fr;
  gap: clamp(2rem, 7vw, 6rem);
  align-items: start;
  padding-top: var(--space-md);
}
.about__sidebar { position: sticky; top: 100px; }
.about__name { font-size: 2.25rem; }
.about__role { margin-top: 0.75rem; }
.about__contact {
  list-style: none;
  padding: 0;
  margin-top: 1.5rem;
  font-size: var(--fs-body);
  color: var(--text-body);
  line-height: 2;
}
.about__contact a:hover { color: var(--accent); }
.about__resume { margin-top: 1.75rem; }

.about__body > p { font-size: var(--fs-body-lg); color: var(--text-body); }
.about__body > p + p { margin-top: 1.5rem; }

.about__group { margin-top: var(--space-lg); }
.about__group .divider { margin-bottom: var(--space-md); }
.about__subhead {
  font-size: 1.25rem;
  color: var(--text-primary);
  margin-top: var(--space-md);
}
.about__subhead + p { margin-top: 0.75rem; }
.edu-item { margin-top: var(--space-sm); }
.edu-item strong { color: var(--text-primary); font-weight: 600; }
.edu-item span { display: block; color: var(--text-muted); font-size: var(--fs-small); }

/* ============================================================
   12. CASE STUDY (Lauren's spine — Part 2)
   ============================================================ */
.case { }
.case__eyebrow { margin-bottom: 1.25rem; }
.case__title { font-size: var(--fs-h1); max-width: 20ch; }
.case__subtitle {
  font-size: var(--fs-body-lg);
  color: var(--text-body);
  max-width: 60ch;
  margin-top: 1.25rem;
}

.case__hero {
  aspect-ratio: 16 / 8;
  margin-top: var(--space-lg);
  border-radius: var(--radius-card);
  border: 1px solid var(--border);
  background: linear-gradient(135deg, #E8E4FF 0%, #F3ECFF 50%, #E4F5EC 100%);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Metadata row */
.case__meta {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 2rem;
  margin-top: var(--space-md);
  padding-block: var(--space-md);
  border-top: 1px solid var(--divider);
  border-bottom: 1px solid var(--divider);
}
/* 3-column variant — for studies with no Impact column (e.g., an unreleased vision).
   The base rule hard-codes 4; this overrides it. Responsive collapses still apply. */
.case__meta--3col { grid-template-columns: repeat(3, 1fr); }
.meta-col .label { display: block; margin-bottom: 0.6rem; }
.meta-col p { font-size: var(--fs-body); color: var(--text-primary); }
.meta-col ul { list-style: none; padding: 0; font-size: var(--fs-small); color: var(--text-body); }
.meta-col li { margin-bottom: 0.35rem; }

/* Prose block — the reading column inside a case study */
/* Reading column. 660px at 19px lands ~69 characters per line — inside the
   65–75 comfortable range, and matched to about.html so the site has one
   reading system rather than two. Was 720px at 17px (~85 chars).
   --wide and --bleed figures use absolute widths, so they are unaffected. */
.case__body {
  max-width: 660px;
  margin-inline: auto;
  font-size: var(--fs-body-lg);
}
.prose-section { padding-block: 2.5rem; }
/* When a figure/grid ends a section, don't stack its bottom margin on top of
   the section padding — kills the oversized text↔next-section gaps. */
.prose-section > .cs-figure:last-child,
.prose-section > .cs-grid-2:last-child,
.prose-section > .sysflow:last-child { margin-bottom: 0; }
.prose-section > .label { display: block; margin-bottom: 1.25rem; }
.prose-section h2 { font-size: var(--fs-h2); margin-bottom: 1rem; }
.prose-section h3 { font-size: 1.25rem; margin: var(--space-md) 0 0.75rem; }
.prose-section p { margin-bottom: 1rem; color: var(--text-body); }
.prose-section p:last-child { margin-bottom: 0; }

/* HOW MIGHT WE — set large, the pivot of the study */
.hmw {
  padding-block: 2.5rem;
  text-align: center;
}
.hmw .label { display: block; margin-bottom: 1.5rem; }
.hmw__q {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.75rem, 3.5vw, 2.75rem);
  color: var(--text-primary);
  letter-spacing: -0.02em;
  line-height: 1.15;
  max-width: 22ch;
  margin-inline: auto;
}

/* User quote callout */
.quote {
  padding-block: var(--space-md);
  border-left: 2px solid var(--accent);
  padding-left: 2rem;
  margin-block: var(--space-md);
}
.quote blockquote {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.375rem, 2.5vw, 1.875rem);
  color: var(--text-primary);
  line-height: 1.3;
  letter-spacing: -0.01em;
}
.quote cite { display: block; margin-top: 1rem; font-style: normal; font-size: var(--fs-small); color: var(--text-muted); }

/* Stat callouts — 2x2 */
.stats {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  overflow: hidden;
  margin-block: var(--space-md);
}
.stat { background: var(--bg); padding: 2rem; }
.stat__num { font-family: var(--font-display); font-weight: 700; font-size: 2.5rem; color: var(--text-primary); letter-spacing: -0.02em; }
.stat__label { font-size: var(--fs-small); color: var(--text-body); margin-top: 0.5rem; }

/* Principles list (APPROACH) */
.principles { list-style: none; padding: 0; margin-top: var(--space-sm); margin-bottom: 1.75rem; }
.principles li { padding-block: 1rem; border-top: 1px solid var(--divider); }
.principles li:last-child { border-bottom: 1px solid var(--divider); }
.principles strong { color: var(--text-primary); font-weight: 600; display: block; margin-bottom: 0.25rem; font-family: var(--font-display); }

/* Explorations grid — rejected directions = rigor */
.explorations {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
  margin-top: var(--space-sm);
}
.exploration__media {
  aspect-ratio: 4 / 3;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: color-mix(in srgb, var(--text-primary) 3%, var(--bg));
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 0.75rem;
}
.exploration h4 { font-size: var(--fs-body); font-weight: 600; margin-bottom: 0.25rem; }
.exploration p { font-size: var(--fs-small); color: var(--text-body); }

/* Feature section image slot (full-bleed within body) */
.figure {
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-card);
  border: 1px solid var(--border);
  background: color-mix(in srgb, var(--text-primary) 3%, var(--bg));
  display: flex;
  align-items: center;
  justify-content: center;
  margin-block: var(--space-md);
}

/* Real-screenshot figure — a hairline-framed frame that lets the image keep
   its own aspect ratio (screenshots here are wide filmstrips, not 16:9).
   On-system: warm surface, hairline border, card radius. */
.cs-figure {
  margin-block: var(--space-md);
  padding: clamp(0.75rem, 2vw, 1.5rem);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  overflow: hidden;
}
.cs-figure img {
  width: 100%;
  height: auto;
  border-radius: 6px;
}
.cs-figure figcaption {
  font-family: var(--font-body);
  font-size: var(--fs-small);
  color: var(--text-muted);
  text-align: center;
  margin-top: 0.9rem;
  line-height: 1.5;
}
:root[data-theme="dark"] .cs-figure img { opacity: 0.94; }

/* Opt-in: figures whose source image carries its own opaque white plate (a
   Figma export with a filled background rather than a transparent one). In
   dark mode that plate lands as a bare white slab with hard corners on the
   dark surface; the radius frames it as a deliberate white card instead.
   Deliberately NOT applied to .cs-figure img generally — five figures across
   collections/vision/zoom are genuinely transparent PNGs (the zoom
   imbalanced-agents pair is 4% transparent with real interior holes) and must
   keep showing the dark surface through them. */
:root[data-theme="dark"] .cs-figure--plate img {
  background: #FFFFFF;
  border-radius: 8px;
}

/* Research findings as markup, not a pasted screenshot — resolution-independent,
   on the site's type system, and the one figure that adapts to dark mode.
   Fills the prose measure (no --narrow): ~65 characters at 17px. */
.findings {
  display: grid;
  gap: 0.75rem;
  list-style: none;
  padding: 0;
  margin: 0;
}
.findings > li {
  background: var(--finding-bg);
  border-radius: 10px;
  padding: 1.5rem 1.75rem;
  font-size: var(--fs-body);
  line-height: 1.55;
  color: var(--text-body);
}
.findings > li strong {
  font-weight: 600;
  color: var(--text-primary);
}
@media (max-width: 600px) {
  .findings > li { padding: 1.25rem; }
}

/* Breakout: let a wide filmstrip figure escape the 720px reading column and
   center on the viewport, up to the content width. */
.cs-figure--wide {
  width: min(1000px, 92vw);
  margin-left: 50%;
  transform: translateX(-50%);
}

/* Full-bleed figure — wider than --wide, for dense wide artifacts (framework
   matrices, IA comparisons, multi-column boards) unreadable at 1000px. */
.cs-figure--bleed {
  width: min(1280px, 96vw);
  margin-left: 50%;
  transform: translateX(-50%);
}

/* Zoomable figure — for dense wide artifacts whose source resolution is higher
   than any inline width can show. Clicking opens the image at native size in a
   lightbox. JS wraps the <img> in the button and adds .is-zoomable, so the
   "click to enlarge" affordance only appears when the lightbox actually works. */
.cs-figure__zoom {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  border-radius: 6px;
}
.cs-figure__zoom:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
.cs-figure.is-zoomable figcaption::after {
  content: "Click to enlarge";
  display: block;
  margin-top: 0.5rem;
  font-size: 0.8125rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
}

/* Lightbox — a native <dialog> so Esc, focus trapping, and background inerting
   come for free. JS sets an explicit px width on the image (capped at a
   multiple of its inline width, see ZOOM_CAP in main.js); the container
   scrolls when that overflows. Centering uses margin:auto on the image, not
   justify/align on the flex container, which would clip the overflowing
   start edge. */
.lightbox {
  width: 100vw;
  max-width: 100vw;
  height: 100dvh;
  max-height: 100dvh;
  margin: 0;
  padding: 0;
  border: 0;
  background: var(--bg);
  color: var(--text-body);
  overflow: hidden;
}
.lightbox::backdrop { background: rgba(17, 17, 17, 0.9); }
.lightbox__scroll {
  display: flex;
  width: 100%;
  height: 100%;
  overflow: auto;
  padding: clamp(1rem, 4vw, 3.5rem);
  overscroll-behavior: contain;
}
.lightbox__img {
  display: block;
  margin: auto;          /* centers when it fits; never clips when it overflows */
  max-width: none;
  max-height: none;
  border-radius: 6px;
}
.lightbox__close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  z-index: 1;
  width: 2.5rem;
  height: 2.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-body);
  font-size: 1.5rem;
  line-height: 1;
  color: var(--text-primary);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 50%;
  cursor: pointer;
}
.lightbox__close:hover { color: var(--accent); border-color: var(--accent); }
.lightbox__close:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Lock the page behind the lightbox. */
html.has-lightbox, html.has-lightbox body { overflow: hidden; }

/* Single portrait phone screenshots — show at device size, centered, not stretched. */
.cs-figure--phone { max-width: 360px; margin-inline: auto; }
/* Small/narrow graphics — cap width so they don't upscale to the full column. */
.cs-figure--narrow { max-width: 520px; margin-inline: auto; }

/* Exploration figures — illustrative texture, not read closely. Cap the height so
   a tall board doesn't dominate the (now post-opportunities) Explorations section. */
.cs-figure--explore img {
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 560px;
  margin-inline: auto;
}

/* Two-up figure grid (explorations shown side by side), breaks out wide. */
.cs-grid-2 {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.5rem;
  margin-block: var(--space-md);
  width: min(1000px, 92vw);
  margin-left: 50%;
  transform: translateX(-50%);
}
.cs-grid-2 .cs-figure { margin-block: 0; height: 100%; }
@media (max-width: 640px) { .cs-grid-2 { grid-template-columns: 1fr; } }

/* Inner grids for COMPOSED figures — placed inside a single .cs-figure so the
   set reads as one framed figure with one caption (not stacked loose images).
   align-items:start keeps mismatched aspect ratios from stretching. */
.cs-figrid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; align-items: start; }
.cs-figrid-2x2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1rem; align-items: start; }
@media (max-width: 720px) { .cs-figrid-3 { grid-template-columns: 1fr; } }
@media (max-width: 640px) { .cs-figrid-2x2 { grid-template-columns: 1fr; } }

/* ---- Two-lane journey diagram: how Apply Connect is used, both sides ----
   Original, in-system replacement for third-party marketing collateral.
   Icon steps per lane; the admin's notification setting links down to the
   applicant's outcome (same bell icon) to show the dependency. */
.sysflow { margin-block: var(--space-md); }
.sysflow__card {
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--surface);
  padding: clamp(1.5rem, 3.5vw, 2.75rem);
}
/* swim lane: role label sits to the LEFT, so it never adds vertical space
   between the lanes — keeps the dependency link symmetric. */
.sysflow__lane {
  display: grid;
  grid-template-columns: 116px 1fr;
  align-items: center;
  column-gap: clamp(1rem, 3vw, 2rem);
}
.sysflow__role { margin: 0; }
/* fixed arrow columns so the lanes and the dependency link align exactly */
.sysflow__steps,
.sysflow__depends-track {
  display: grid;
  grid-template-columns: 1fr 40px 1fr 40px 1fr;
  align-items: start;
}
.sysflow__step {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.7rem;
}
.sysflow__badge {
  width: 48px; height: 48px;
  flex: 0 0 auto;
  border-radius: 50%;
  border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center;
  color: var(--text-primary);
}
.sysflow__badge svg { width: 22px; height: 22px; }
.sysflow__step p {
  font-size: var(--fs-small);
  color: var(--text-body);
  line-height: 1.4;
  max-width: 19ch;
  min-height: 2.8em;          /* equal step heights → arrows stay aligned */
}
.sysflow__step--key .sysflow__badge {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.sysflow__step--key p { color: var(--text-primary); font-weight: 500; }
.sysflow__arrow {
  align-self: start;
  margin-top: 13px;           /* vertically center on the 48px badge */
  text-align: center;
  color: var(--text-muted);
  font-size: 1.05rem;
}
/* dependency link — aligned under the key (last) step, inside the steps area */
.sysflow__depends {
  display: grid;
  grid-template-columns: 116px 1fr;
  column-gap: clamp(1rem, 3vw, 2rem);
  margin-block: 0.4rem;
}
.sysflow__depends-track { grid-column: 2; }
.sysflow__depends-link {
  grid-column: 5;
  justify-self: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  color: var(--accent);
  text-align: center;
}
.sysflow__depends-line {
  width: 0;
  height: 0.8rem;
  border-left: 1px dashed var(--accent);
}
.sysflow__depends-tag {
  font-family: var(--font-body);
  font-size: var(--fs-small);
  font-weight: 500;
  line-height: 1.3;
  color: var(--accent);
  max-width: 20ch;
}
.sysflow__depends-arrow { font-size: 0.95rem; line-height: 1; color: var(--accent); }
.sysflow > figcaption {
  font-family: var(--font-body);
  font-size: var(--fs-small);
  color: var(--text-muted);
  text-align: center;
  margin-top: 1.1rem;
  line-height: 1.5;
}
@media (max-width: 680px) {
  .sysflow__lane { grid-template-columns: 1fr; row-gap: 0.85rem; }
  .sysflow__steps,
  .sysflow__depends-track { grid-template-columns: 1fr; gap: 0.5rem; }
  .sysflow__depends { grid-template-columns: 1fr; }
  .sysflow__depends-track { grid-column: 1; }
  .sysflow__depends-link { grid-column: 1; }
  .sysflow__step p { min-height: 0; }
  .sysflow__arrow { margin: 0; justify-self: center; transform: rotate(90deg); }
}

/* ============================================================
   13. RESPONSIVE
   ============================================================ */
@media (max-width: 860px) {
  .work-grid { grid-template-columns: 1fr; }
  .split { grid-template-columns: 1fr; }
  .about { grid-template-columns: 1fr; }
  .about__sidebar { position: static; }
  .case__meta { grid-template-columns: repeat(2, 1fr); }
  .explorations { grid-template-columns: 1fr; }
  .stats { grid-template-columns: 1fr; }
}

@media (max-width: 560px) {
  .nav__links { gap: 1rem; }
  .nav__link--hide-sm { display: none; }
  .case__meta { grid-template-columns: 1fr; }
}
