/* ------------------------------------------------------------------
   Tomomi Martin: the one stylesheet for every page.

   Everything is a class. The only selectors that aren't are the reset at
   the top (tags need margins and box-sizing zeroed before classes take
   over), the content rules under .prose (paragraphs inside copy blocks),
   the data-placeholder audit, and the html-level state that the scripts
   set ([data-arrived], the hero's scrollbar handling). Each page links
   this file alone. No framework, no utility classes.

   Order: tokens, reset, type, shared chrome (header, footer, frames),
   hero, work page, about and project pages, page slide.
------------------------------------------------------------------ */
:root {
  /* Mist and navy: one palette for every page. Pale cool grey, deep navy type
     (it echoes her blazer), and the same navy for the hero's scrolling name,
     timeline dots and focus rings. */
  --paper: #e2e6ea;
  --ink: #15202d;
  --ink-soft: #3e4a58;
  --ink-faint: #56626f;
  --accent: #1f6a7a;                      /* tidewater teal: the one colour besides ink. Dots, rail, rule, labels, hover underlines */
  --accent-soft: rgba(31, 106, 122, 0.35); /* the timeline rail */
  --accent-wash: rgba(21, 32, 45, 0.06);
  --line: rgba(21, 32, 45, 0.28);
  --line-soft: rgba(21, 32, 45, 0.16);
  --ph-bg: rgba(31, 106, 122, 0.09);      /* logo and photo frames: a quiet teal wash on the mist */
  --ph-line: rgba(31, 106, 122, 0.14);
  --band: #d6dbe1;                        /* a slightly deeper mist for full-width bands */

  /* Site type: Helvetica Neue everywhere (light weight for display), mono for labels */
  --sans: "Helvetica Neue ME", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --serif: var(--sans); /* display face; kept under the old token name so page styles need no edits */
  --mono: "JetBrains Mono", ui-monospace, monospace;

  /* 1% of the width other pages lay out in (the hero gives back the scrollbar
     space, which would otherwise make its vw a little larger) */
  --vw: calc((100vw - var(--hero-sb, 0px)) / 100);   /* use this, never raw vw: it also holds steady through a page slide */
  --gutter: clamp(24px, calc(2.8 * var(--vw)), 40px);       /* one side margin for header, hero and content */
  --stage-gutter: var(--gutter);
  --header-h: 124px;                         /* fixed header: content starts below it */
  --measure: 620px;
  --page-max: 1040px;                        /* content column on every page but the hero */
  --radius: 14px;
  --radius-pill: 999px;

  --space-hero: 140px;
  --space-section: 140px;
  --ease: cubic-bezier(0.2, 0.6, 0.2, 1);

  /* Hero */
  --stage-bg: var(--paper);
  --footer-h: 136px;              /* desktop: rule sits just above this band */
  --rise: cubic-bezier(0.22, 1, 0.36, 1);
  --sweep: cubic-bezier(0.76, 0, 0.24, 1);
}

/* ------------------------------------------------------------------
   Base
------------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }
/* Always reserve the scrollbar's space, so pages that scroll and pages that
   don't (the hero, a page mid-slide) share one content width and never shift */
html { scroll-behavior: smooth; scroll-padding-top: var(--header-h); -webkit-text-size-adjust: 100%; scrollbar-gutter: stable; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  letter-spacing: -0.02em;
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, p, ol, ul, dl, dd, figure { margin: 0; }
ol, ul { padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }
em { font-style: italic; }
img { max-width: 100%; display: block; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }

/* Inner pages sit in one centred column (the fixed header and the hero stay full width) */
.container { width: 100%; max-width: calc(var(--page-max) + 2 * var(--gutter)); margin-inline: auto; padding-inline: var(--gutter); }
.skip-link { position: absolute; left: -999px; top: 8px; padding: 8px 12px; background: var(--ink); color: var(--paper); border-radius: 8px; }
.skip-link:focus { left: 8px; z-index: 100; }

/* ------------------------------------------------------------------
   Type helpers
------------------------------------------------------------------ */
.eyebrow {
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: -0.02em;
  color: var(--accent);
}
.section-title {
  font-family: var(--serif);
  font-weight: 300;
  font-size: 36px;
  line-height: 1.09;
  letter-spacing: -0.04em;
}
.lede { font-size: 18px; line-height: 1.55; max-width: var(--measure); }
.prose p { max-width: var(--measure); }
.prose p + p { margin-top: 18px; }

/* ------------------------------------------------------------------
   Header
------------------------------------------------------------------ */
/* The hero's header, the same on every page. It is fixed, so only the page
   content scrolls (and slides) beneath it. Solid grey so content passes under
   it cleanly; see hero.css for the hero, where it sits on the stage. */
.site-header {
  position: fixed; top: 0; inset-inline: 0 var(--hero-sb, 0px); z-index: 110;
  display: flex; align-items: flex-start; justify-content: space-between;
  padding: 32px var(--stage-gutter) 24px;
  background: var(--paper);
  transition: background-color 0.3s var(--ease);  /* soft change when a slide lands on the hero */
  font-size: 14px; line-height: 1.5; letter-spacing: 0;
}
/* Soft edge below the header: scrolling content fades out under it instead
   of being cut off on a hard line. Eased stops so there is no visible band. */
.site-header::after {
  content: ""; position: absolute; top: 100%; left: 0; right: 0; height: var(--header-fade, 56px);
  pointer-events: none;
  background: linear-gradient(to bottom,
    rgb(226 230 234 / 1) 0%, rgb(226 230 234 / 0.87) 19%, rgb(226 230 234 / 0.64) 34%,
    rgb(226 230 234 / 0.4) 50%, rgb(226 230 234 / 0.19) 66%, rgb(226 230 234 / 0.06) 83%,
    rgb(226 230 234 / 0) 100%);
}
.site-header__brand { font-size: 18px; letter-spacing: 0.02em; line-height: 1; white-space: nowrap; }
.site-header__meta { display: flex; align-items: flex-start; gap: clamp(48px, calc(6.5 * var(--vw)), 96px); }
.site-header__column { display: flex; flex-direction: column; gap: 2px; }
.site-header__brand, .site-header__link { transition: color 0.3s var(--ease), opacity 0.3s var(--ease); }
.site-header__brand:hover, .site-header__link:hover { color: var(--accent); }
.site-header__brand:active, .site-header__link:active { opacity: 0.4; transition-duration: 0.08s; }

/* Buttons are plain text links on this site: no pills, no borders */
.btn { display: inline-flex; align-items: center; font-size: 15px; color: var(--ink); transition: opacity 0.3s var(--ease); }
.btn:hover { opacity: 0.6; }
.btn:active { opacity: 0.4; transition-duration: 0.08s; }

/* ------------------------------------------------------------------
   Placeholder frames (replace the inner label with an <img>)
------------------------------------------------------------------ */
.ph {
  position: relative;
  background: var(--ph-bg);
  border: 1px solid var(--ph-line);
  border-radius: var(--radius);
  overflow: hidden;
  display: grid;
  place-items: center;
}
.ph__img { width: 100%; height: 100%; object-fit: cover; }
.ph__label { font-family: var(--mono); font-size: 12px; letter-spacing: 0; color: var(--ink-faint); text-align: center; padding: 8px; }
.ph--portrait { aspect-ratio: 4 / 5; }
.ph--square { aspect-ratio: 1; }
.ph--landscape { aspect-ratio: 4 / 3; }
.ph--wide { aspect-ratio: 16 / 9; }
.ph--banner { aspect-ratio: 16 / 7; }
.logo { display: block; filter: brightness(0) invert(1); opacity: 0.92; }   /* paper silhouettes on the teal tile */
.ph--logo { background: var(--accent); border-color: transparent; }
.ph--logo .logo { width: auto; height: auto; max-width: 56%; max-height: 34%; object-fit: contain; }

/* ------------------------------------------------------------------
   Footer
------------------------------------------------------------------ */
.site-footer {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 24px;
  margin-top: 160px; padding-top: 48px; padding-bottom: 40px;
  font-size: 14px; line-height: 1.6;
  /* a full-width teal band; the text still lines up with the content column */
  max-width: none; background: var(--accent); color: var(--paper);
  padding-inline: max(var(--gutter), calc((100 * var(--vw) - var(--page-max)) / 2));
}
.site-footer__soft { color: var(--paper); opacity: 0.7; }

/* ------------------------------------------------------------------
   Back to top
------------------------------------------------------------------ */
.back-to-top {
  position: fixed; left: 50%; bottom: 28px; z-index: 40;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 12px;
  color: var(--ink); font-size: 14px; line-height: 1;
  transform: translate(-50%, 12px); opacity: 0; pointer-events: none;
  transition: opacity 0.25s var(--ease), transform 0.25s var(--ease);
}
.back-to-top__icon { width: 14px; height: 14px; }
.back-to-top.is-visible { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }

/* ------------------------------------------------------------------
   Placeholder audit (append ?placeholders to the URL)
------------------------------------------------------------------ */
.show-placeholders [data-placeholder] { outline: 1px dashed var(--accent); outline-offset: 3px; }

/* ------------------------------------------------------------------
   Responsive
------------------------------------------------------------------ */
/* Narrow windows: brand left; on the right, Work / About / Contact above
   LinkedIn / Email / Résumé, so every link stays in the header */
@media (max-width: 900px) {
  :root { --header-h: 84px; }
  .site-header { align-items: center; padding: 24px var(--stage-gutter) 16px; font-size: 13px; }
  .site-header::after { --header-fade: 40px; }
  .site-header__meta { flex-direction: column; align-items: flex-end; gap: 4px; }
  .site-header__year { display: none; }
  .site-header__column { flex-direction: row; gap: 18px; }
}
/* Smallest phones: tighten so the brand and links never touch */
@media (max-width: 380px) {
  .site-header { gap: 12px; }
  .site-header__brand { font-size: 16px; }
  .site-header__column { gap: 12px; }
}

@media (max-width: 760px) {
  :root { --space-hero: 96px; --space-section: 96px; }
  .section-title { font-size: 30px; }
  .site-footer { margin-top: 112px; padding-top: 36px; padding-bottom: 32px; font-size: 13px; }
  .back-to-top { bottom: 20px; }
}

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

/* ------------------------------------------------------------------
   Page slide (js/page-slide.js): during a page change the outgoing and
   incoming pages each sit in a full-screen panel and slide together.
------------------------------------------------------------------ */
.page-panel {
  position: fixed; inset: 0; z-index: 100;
  overflow: hidden;
  background: var(--paper);
  will-change: transform;
}
/* Leaving the hero (no scrollbar space) for a page that reserves it: lay the
   arriving page out at its final width so nothing shifts when it lands */
.page-panel:not(:has(> .stage)) { padding-right: var(--hero-sb, 0px); }

/* Arriving by slide: no entrance animation on top of it */
:root[data-arrived] .stage, :root[data-arrived] .stage__portrait, :root[data-arrived] .stage__figure, :root[data-arrived] .stage__rule { animation: none; }

/* ==================================================================
   Hero (home)
   ================================================================== */
/* ------------------------------------------------------------------
   Home: one full-viewport composition, no scroll.
   Matches the "Personal Showcase" reference: flat mist background, navy type,
   a slow name marquee behind a portrait cutout, quiet chrome in the corners.
------------------------------------------------------------------ */
.hero-page { height: 100%; overflow: hidden; }
/* The hero never scrolls, so it gives back the scrollbar space other pages keep
   (base.css) and the name runs edge to edge. --hero-sb is that width; the
   header, rule, footer and portrait step in by it to stay where they are on
   every other page. */
html:has(> .hero-page) { scrollbar-gutter: auto; --hero-sb: var(--scrollbar, 0px); }
.hero-page { background: var(--stage-bg); color: var(--ink); }

.stage {
  position: relative; height: 100dvh; width: 100%; overflow: hidden;
  background: var(--stage-bg);
  animation: stage-fade 0.8s ease-out both;
}

/* Marquee name (behind the portrait) ------------------------------- */
.stage__name {
  position: absolute; inset-inline: 0; top: 14vh; z-index: 1;
  overflow: hidden;
}
.stage__track {
  display: flex; width: max-content; white-space: nowrap;
  animation: marquee 30s linear infinite;
}
.stage__name-text {
  display: inline-block; padding-right: calc(6 * var(--vw));
  font-family: var(--sans); font-weight: 300;
  font-size: 26vh; line-height: 1; letter-spacing: -0.01em;   /* looser than body display type: at this size -0.03em ran r into t */
  color: var(--ink);
}

/* Portrait --------------------------------------------------------- */
.stage__figure { display: contents; margin: 0; }
.stage__portrait {
  position: absolute; z-index: 2;
  left: calc(50% - var(--hero-sb, 0px) / 2); bottom: 0;
  height: min(82vh, calc(56 * var(--vw)));        /* never wide enough to reach the corner chrome */
  width: auto; max-width: none;
  transform: translateX(-50%);
  pointer-events: none; user-select: none;
  animation: portrait-rise 1.1s var(--rise) 0.1s both;
}

/* Header (shared, in base.css) ------------------------------------
   On the desktop hero it sits straight on the stage, over the name, as in
   the reference; it fades in with the stage on a fresh load only. */
@media (min-width: 901px) {
  .hero-page .site-header { background: transparent; }
  .hero-page .site-header::after { display: none; }  /* the hero doesn't scroll under the header */
}
:root:not([data-arrived]) .hero-page .site-header { animation: stage-fade 0.8s ease-out both; }

/* Base band and footer --------------------------------------------- */
/* The old hairline rule, grown into a teal band the portrait stands on. It
   sits behind the portrait (z 2) and under the footer text (z 3), and still
   sweeps in from the left on a fresh load. Same colour as the inner pages'
   footer band, so every page ends the same way. */
.stage__rule {
  position: absolute; z-index: 1;
  inset-inline: 0 var(--hero-sb, 0px); bottom: 0;
  height: var(--footer-h); background: var(--accent);
  transform-origin: left; animation: rule-grow 1.1s var(--sweep) 0.6s both;
}
.stage__footer {
  position: absolute; inset-inline: 0 var(--hero-sb, 0px); bottom: 0; z-index: 3;
  display: flex; align-items: flex-end; justify-content: space-between; gap: 24px;
  padding: 0 var(--stage-gutter) 32px;
  font-size: 14px; line-height: 1.6; color: var(--paper);
}
.stage__blurb { max-width: 220px; }
.stage__blurb-line { font: inherit; margin: 0; }
.stage__blurb-line--soft { opacity: 0.7; }


/* Keyframes -------------------------------------------------------- */
@keyframes stage-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes portrait-rise {
  from { opacity: 0; transform: translate(-50%, 2.5vh); }
  to { opacity: 1; transform: translate(-50%, 0); }
}
@keyframes rule-grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* Responsive ------------------------------------------------------- */
@media (max-width: 900px) {
  /* Phones and narrow windows: a stacked column. The portrait box takes exactly
     the height that is left; its width follows from that height (aspect-ratio),
     so the crop always lands at the chest whatever the window shape. */
  /* Room for the fixed header's text; its bottom padding may overlap the name's margin */
  .stage { display: flex; flex-direction: column; padding-top: calc(var(--header-h) - 16px); padding-right: var(--hero-sb, 0px); }

  .stage__name { position: static; order: 2; flex: none; margin-top: 6vh; margin-right: calc(-1 * var(--hero-sb, 0px)); }
  .stage__name-text { font-size: min(15vh, calc(34 * var(--vw))); }

  .stage__footer { position: static; order: 3; flex: none; flex-direction: column; align-items: stretch; gap: 18px; margin-top: 4vh; padding: 4vh var(--stage-gutter); font-size: 13px; background: var(--accent); }
  .stage__blurb { max-width: none; }
  .stage__blurb-break { display: none; }

  .stage__rule { display: none; }   /* the footer carries the band when stacked */

  .stage__figure {
    display: block; order: 5;
    flex: 1 1 0; min-height: 300px;     /* exactly the leftover height */
    width: auto; max-width: 100%;
    aspect-ratio: 1.12 / 1;          /* width from height: head and shoulders fill the box */
    margin: 16px auto 0;
    overflow: hidden;
    animation: portrait-rise-stacked 1.1s var(--rise) 0.1s both;
  }
  .stage__portrait {
    position: static; display: block;
    width: 100%; height: 100%; max-width: none;
    object-fit: cover; object-position: top center;
    transform: none; animation: none;
  }
}
/* Windows too short to hold the column: the page scrolls, and the portrait moves
   up under the name so her whole face is in view on open. The box fades out at
   the bottom instead of ending in a hard edge; blurb, rule and buttons follow. */
@media (max-width: 900px) and (max-height: 760px) {
  .hero-page { height: auto; overflow: auto; }
  html:has(> .hero-page) { scrollbar-gutter: stable; --hero-sb: 0px; }
  .stage { height: auto; min-height: 100dvh; overflow: visible; }
  .stage__name { margin-top: 4vh; }
  .stage__figure {
    order: 3; flex: none; height: max(50vh, 300px); margin-top: 3vh;
    -webkit-mask-image: linear-gradient(to bottom, #000 70%, transparent 100%);
    mask-image: linear-gradient(to bottom, #000 70%, transparent 100%);
  }
  .stage__footer { order: 5; margin-top: 0; padding: 24px var(--stage-gutter) 32px; }
}
@keyframes portrait-rise-stacked {
  from { opacity: 0; transform: translateY(2.5vh); }
  to { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .stage, .stage__portrait, .stage__rule { animation-duration: 0.01ms; animation-delay: 0s; }
  .stage__track { animation: none; }
}

/* ==================================================================
   Work page
   ================================================================== */
/* ------------------------------------------------------------------
   Work page: one timeline. Years and rail on the left; each role on the
   right with its company mark in the photo box. No rules between rows.
------------------------------------------------------------------ */
.work-intro__title {
  font-family: var(--serif); font-weight: 300;
  font-size: clamp(44px, calc(6 * var(--vw)), 84px); line-height: 0.98; letter-spacing: -0.05em;
}
.work-intro__lede { margin-top: 28px; }

.tl { margin-top: 112px; }
.tl-item {
  display: grid;
  grid-template-columns: 128px 24px minmax(0, 1fr);
  column-gap: 24px;
  padding-bottom: 88px;
}
.tl-item:last-child { padding-bottom: 0; }
.tl-years { font-family: var(--mono); font-size: 13px; color: var(--accent); padding-top: 10px; white-space: nowrap; }

/* Rail: one continuous line through every entry (drawn on the row so it
   spans the gaps), with a dot per entry sitting on the line */
.tl-item, .tl-label { position: relative; }
.tl-item::before, .tl-label::before {
  content: ""; position: absolute; left: calc(128px + 24px + 11px); top: 18px; bottom: -18px;
  width: 2px; background: var(--accent-soft);
}
.tl-label::before { top: 18px; }  /* picks up where the entry above's tail ends: no doubled, darker segment */
.tl-item:last-child::before { display: none; }
.tl-rail { position: relative; }
.tl-rail::after {
  content: ""; position: absolute; left: 6px; top: 12px; width: 12px; height: 12px; border-radius: 50%;
  background: var(--accent);
}
.tl-item--edu .tl-rail::after { background: var(--paper); border: 2px solid var(--accent); width: 10px; height: 10px; left: 7px; top: 13px; }

.tl-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(260px, 38%);
  column-gap: 48px;
  align-items: start;
}
.tl-title {
  display: block;
  font-family: var(--serif); font-weight: 300;
  font-size: clamp(28px, calc(3 * var(--vw)), 42px); line-height: 1.06; letter-spacing: -0.045em;
  max-width: 15em;
}
.tl-meta { display: block; margin-top: 14px; font-size: 15px; color: var(--ink-soft); }
.tl-note { display: block; margin-top: 14px; max-width: 520px; font-size: 15px; line-height: 1.55; }
.tl-media { width: 100%; }
/* Only cards that link to a project page respond to hover; the plain
   entries (Alston, education) are static */
.tl-card--link .tl-title { transition: color 0.3s var(--ease), opacity 0.3s var(--ease); }
.tl-card--link:hover .tl-title { color: var(--accent); text-decoration: underline; text-underline-offset: 6px; text-decoration-thickness: 1px; }
.tl-card--link:active .tl-title { opacity: 0.6; }
/* ...and their image eases in a touch while the card is hovered (the frame clips it) */
.tl-card--link .tl-media .logo, .tl-card--link .tl-media .ph__img { transition: transform 0.7s var(--ease); }
.tl-card--link:hover .tl-media .logo, .tl-card--link:hover .tl-media .ph__img { transform: scale(1.06); }

/* Education: a quiet label, then smaller text-only entries */
.tl-label { padding: 0 0 40px calc(128px + 24px + 48px); }
.tl-item--edu { padding-bottom: 40px; }
.tl-item--edu .tl-card { grid-template-columns: minmax(0, 1fr); }
.tl-item--edu .tl-title { font-size: clamp(22px, calc(2 * var(--vw)), 28px); }
.tl-item--edu .tl-meta { margin-top: 8px; }

/* Responsive ------------------------------------------------------ */
@media (max-width: 1000px) {
  .tl-card { grid-template-columns: minmax(0, 1fr); row-gap: 24px; }
  .tl-media { order: -1; max-width: 420px; }
}
@media (max-width: 760px) {
  .tl { margin-top: 72px; }
  .tl-item { grid-template-columns: 24px minmax(0, 1fr); grid-template-areas: "rail years" "rail card"; column-gap: 16px; padding-bottom: 64px; }
  .tl-years { grid-area: years; padding-top: 0; }
  .tl-rail { grid-area: rail; }
  .tl-item::before, .tl-label::before { left: 11px; top: 10px; bottom: -10px; }
  .tl-label::before { top: 10px; }
  .tl-rail::after { top: 4px; }
  .tl-item--edu .tl-rail::after { top: 5px; }
  .tl-card { grid-area: card; margin-top: 12px; }
  .tl-label { padding: 0 0 32px 40px; }
}

/* ==================================================================
   About and project pages
   ================================================================== */
/* ------------------------------------------------------------------
   Shared page scaffolding (about + project pages)
------------------------------------------------------------------ */
.page { padding-top: calc(var(--header-h) + 40px); }  /* clear the fixed header */
.page__back {
  display: inline-flex; align-items: center; gap: 10px;
  margin-bottom: 40px; font-size: 16px; line-height: 1; color: var(--ink);
  transition: color 0.3s var(--ease);
}
.page__back:hover { color: var(--accent); }
.page__back:hover .page__back-icon { transform: translateX(-3px); }
.page__back-icon { width: 20px; height: 20px; flex: none; color: var(--accent); transition: transform 0.3s var(--ease); }
.page__title {
  font-family: var(--serif); font-weight: 300;
  font-size: clamp(36px, calc(4.6 * var(--vw)), 56px); line-height: 1.05; letter-spacing: -0.05em;
  max-width: 820px;
}
.page__lede { margin-top: 28px; }
.page__section { padding-top: 80px; }
.page__section-title { margin-bottom: 20px; }

/* ------------------------------------------------------------------
   About page: built on the Work page's grid so the two read as one site.
   The intro splits like a Work entry (text, then a 38% framed photo);
   every section after it is a full-width row with a small label on the
   left and its content beside it.
------------------------------------------------------------------ */
.about-intro {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(260px, 38%);
  column-gap: 48px;
  align-items: center;   /* text block sits at the photo's vertical middle */
}
.about-intro__title {
  font-family: var(--serif); font-weight: 300;
  font-size: clamp(44px, calc(6 * var(--vw)), 84px); line-height: 0.98; letter-spacing: -0.05em;
}
.about-intro__role { margin-top: 20px; font-size: 15px; color: var(--ink-soft); }
.about-intro__lede { margin-top: 28px; }
.about-intro__img { object-fit: contain; object-position: bottom; }

/* Rows span the full content width: a 200px label column, then the body */
.about-row {
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr);
  padding-top: 96px;
}
.about-intro + .about-row { padding-top: 128px; }
.about-row__label {
  font-family: var(--mono); font-weight: 400; font-size: 13px; letter-spacing: -0.02em;
  color: var(--accent); padding-top: 4px;
}
.about-row__body.prose p { max-width: none; font-size: 17px; line-height: 1.6; }  /* use the full row width */

.about-list { display: flex; flex-direction: column; gap: 18px; }
.about-list__item { font-size: 17px; line-height: 1.4; letter-spacing: -0.03em; }
.about-list__name { display: block; }
.about-list__meta { display: block; margin-top: 4px; font-family: var(--mono); font-size: 12px; letter-spacing: 0; color: var(--ink-soft); }
/* Two columns that read top to bottom, then across */
.about-list--columns { display: block; columns: 3; column-gap: 40px; }
.about-list--columns .about-list__item { break-inside: avoid; padding-bottom: 12px; }

/* ------------------------------------------------------------------
   Project pages
------------------------------------------------------------------ */
.project-facts { margin-top: 48px; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 24px; }
.project-facts__term { font-family: var(--mono); font-size: 12px; color: var(--accent); margin-bottom: 6px; }
.project-facts__value { font-size: 16px; letter-spacing: -0.03em; }
.project-hero { margin-top: 40px; }
.project-figures { margin-top: 32px; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; }
.figcaption { margin-top: 10px; font-size: 13px; color: var(--ink-soft); }
.project-next { margin-top: 120px; display: flex; flex-direction: column; gap: 10px; }
.project-next:hover .project-next__title { color: var(--accent); text-decoration: underline; text-underline-offset: 6px; text-decoration-thickness: 1px; }
.project-next__label { font-family: var(--mono); font-size: 12px; color: var(--accent); }
.project-next__title { font-family: var(--serif); font-weight: 300; font-size: clamp(30px, calc(3.4 * var(--vw)), 46px); letter-spacing: -0.045em; line-height: 1.04; }

/* Project list (West Yost): one row per project, the kind of infrastructure
   as a small label on the left, like the About page's rows */
.project-list__intro { max-width: var(--measure); margin-bottom: 8px; }
.project-list { display: flex; flex-direction: column; }
.project-list__row {
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr) minmax(220px, 30%);
  grid-template-areas: "type body photo";
  column-gap: 32px; align-items: start;
  padding-top: 48px;
}
.project-list__type { grid-area: type; }
.project-list__body { grid-area: body; }
.project-list__photo { grid-area: photo; }
.project-list__type { font-family: var(--mono); font-size: 12px; letter-spacing: 0; color: var(--accent); padding-top: 6px; }
.project-list__name { font-weight: 400; font-size: 20px; line-height: 1.25; letter-spacing: -0.035em; }
.project-list__meta { margin-top: 4px; font-family: var(--mono); font-size: 12px; letter-spacing: 0; color: var(--ink-soft); }
.project-list__desc { margin-top: 12px; max-width: 700px; font-size: 15px; line-height: 1.6; }

/* ------------------------------------------------------------------
   Responsive
------------------------------------------------------------------ */
@media (max-width: 1000px) {
  .about-list--columns { columns: 2; }
  .project-list__row { grid-template-columns: minmax(0, 1fr) minmax(200px, 36%); grid-template-areas: "type type" "body photo"; row-gap: 10px; }
  .project-list__type { padding-top: 0; }
  .project-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 760px) {
  .page { padding-top: calc(var(--header-h) + 48px); }
  .page__section { padding-top: 56px; }
  .about-intro { grid-template-columns: minmax(0, 1fr); row-gap: 40px; }
  .about-intro__photo { max-width: 360px; justify-self: center; width: 100%; }  /* stacked: portrait centred under the text */
  .about-row { grid-template-columns: minmax(0, 1fr); row-gap: 16px; padding-top: 64px; }
  .about-intro + .about-row { padding-top: 88px; }
  .about-row__label { padding-top: 0; }
  .about-list--columns { columns: 1; }
  .project-figures { grid-template-columns: 1fr; }
  .project-list__row { grid-template-columns: minmax(0, 1fr); grid-template-areas: "type" "photo" "body"; row-gap: 12px; padding-top: 40px; }
  .project-list__type { padding-top: 0; }
  .project-list__photo { max-width: 420px; }
  .project-next { flex-direction: column; }
}
