/* Inter (variable) — closest free analogue to UT Futter Grotesk.
   Loaded as a full 100..900 axis so font-weight: 350 renders at exactly 350. */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap');

/* Global scale — renders the entire page at 80% of its native
   size, the exact same effect as setting browser zoom to 80%.
   Affects fonts, images, layout, viewport units — everything.
   Set on body (not html) so the document still occupies the full
   viewport and scrollbars behave normally. */
body { zoom: 0.8; }

/* ---------- Design tokens (from reference) ---------- */
:root {
  --c-light-white: #ffffff;
  --c-light-gray: #f0f0f0;
  --c-light-gray-muted: #9b9b9b;
  --c-light-midgray: #d6d6d6;
  --c-dark-black: #0b1215;
  --c-dark-gray: #333333;
  --c-chroma-red: #ff452c;
  --c-chroma-green: #48ea2d;

  /* Spacing scale */
  --s-025: 0.25rem;
  --s-050: 0.5rem;
  --s-100: 1rem;
  --s-150: 1.5rem;
  --s-200: 2rem;
  --s-250: 2.5rem;
  --s-300: 3rem;
  --s-400: 4rem;
  --s-500: 5rem;

  --main-inline-s: 1rem;
  --main-block-s: 1rem;

  /* Surfaces */
  --c-background: var(--c-dark-black);
  --c-text: var(--c-light-white);
  --c-text-muted: var(--c-light-gray-muted);
  --c-card-background: var(--c-dark-gray);
  --c-card-foreground: var(--c-light-white);
  --module-bg-color: #222;
  --module-bg-color-hover: #2e2e2e;

  /* Component */
  --site-border-radius: 0.625rem;
  --site-text-hover-opacity: 0.6;
  --nav-height: 3rem;
  --nav-padding-inline: 13px;
  --section-spacing: 60px;
  --project-spacing: var(--main-inline-s);

  color-scheme: dark;
}

/* Light theme — flip background + text. Toggled by JS adding
   `.theme-light` to <html>. Everything that reads from these tokens
   (body, wordmark, tagline, card title, card subtitle) flips with it. */
:root.theme-light {
  --c-background: #ffffff;
  --c-text: #000000;
  --c-text-muted: #555555;
  --c-card-foreground: #000000;
  color-scheme: light;
}

/* ---------- Reset ---------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  width: 100%;
  min-height: 100%;
  background: var(--c-background);
  color: var(--c-text);
  transition: background-color 0.3s ease, color 0.3s ease;
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
  -webkit-font-smoothing: antialiased;
  font-family: "UT FutterGrotesk", "Inter", "Helvetica Neue", system-ui, sans-serif;
  font-size: 13px;
  font-weight: 400;
  line-height: 1rem;
  letter-spacing: 0.02rem;
  /* ss09 is UT FG's set — silently ignored by Inter.
     cv11 = single-story `a` in Inter, gives a closer grotesk feel. */
  font-feature-settings: "ss09", "cv11";
  scroll-behavior: smooth;
  scrollbar-width: none;
  overflow-x: hidden;
}

body::-webkit-scrollbar { display: none; }

a { color: inherit; text-decoration: none; }
a:hover { opacity: var(--site-text-hover-opacity); transition: opacity 0.2s ease; }

img, video { display: block; max-width: 100%; height: auto; }

button {
  font: inherit;
  color: inherit;
  background: transparent;
  border: 0;
  cursor: pointer;
}

/* ---------- Layout ---------- */
.page {
  padding: var(--s-100) var(--main-inline-s) calc(var(--nav-height) + var(--s-300));
  max-width: 1800px;
  margin: 0 auto;
}

/* ---------- Intro ----------
   Reserves the top 50vh so the intro and the project grid each occupy
   roughly half the viewport on first load. The cards below are free to
   overflow past the fold. */
.intro {
  min-height: 52vh;
  text-align: center;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: var(--s-200);
  max-width: 130ch;
  margin: 0 auto;
}

.wordmark {
  font-size: clamp(1.08rem, 3.24vw, 1.35rem);
  line-height: 1.15;
  font-weight: 550;
  letter-spacing: 0.06em;
  margin: 0 0 38px;
  text-transform: uppercase;
  text-shadow: 0 0 0.4px currentColor;
  display: inline-block;
  transform: scaleY(1.05);
  transform-origin: center bottom;
}

.tagline {
  /* Mobile-only: how much smaller the description is than the wordmark.
     Used only inside the ≤600px / ≤480px media queries — desktop is unaffected. */
  --desc-shrink: 4px;
  font-size: clamp(1.08rem, 3.24vw, 1.35rem);
  line-height: 1.15;
  font-weight: 350;
  letter-spacing: 0.02em;
  text-align: center;
  margin: 0;
  max-width: 120ch;
  margin-inline: auto;
  text-shadow: 0 0 0.4px currentColor;
}

/* Mobile-only wordmark variant — hidden by default, shown at ≤600px */
.wordmark__mobile { display: none; }

/* ---------- Project grid ---------- */
/* Two-column. Each card gets `padding: 0 calc(spacing/2)` so the visual gap
   between cards is `--project-spacing`, mirroring the UPSET .project rule. */
.grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  /* Cards carry their own bottom margin (--s-200); this adds a touch
     more breathing room between rows only. */
  row-gap: 4px;
  align-items: start;
}

@media (max-width: 600px) {
  .grid { grid-template-columns: 1fr; }
}

/* ---------- Card ----------
   Structure (matches reference):
     .card  (positioning context, per-card --ratio)
       .card__link  (grid: "image" / "text")
         .card__media (padding-bottom: 100%/--ratio → height from width)
         .card__meta  (title + categories, plain text below image)
*/
.card {
  --ratio: 1.4;
  position: relative;
  margin-bottom: var(--s-200);
  padding: 0 calc(var(--project-spacing) / 2);
}

/* Per-card image proportions — tweak per project. The default --ratio: 1.4
   is set on .card above; modifier classes override per variant. */
.card--tall   { --ratio: 1.78; }
.card--small  { --ratio: 1.4;  }
.card--accent { --ratio: 1.75; }

/* "Case Study" pill, anchored to the image area's top-left. */
.card::before {
  content: attr(data-tag);
  position: absolute;
  top: var(--s-100);
  left: calc(var(--project-spacing) / 2 + var(--s-100));
  z-index: 2;
  padding: 6px 10px;
  font-size: 11px;
  letter-spacing: 0.04em;
  background: rgba(120, 120, 120, 0.55);
  color: var(--c-light-white);
  border-radius: 999px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.card__link {
  display: grid;
  grid-template-areas: "image" "text";
  gap: var(--s-100);
  width: 100%;
}

.card__link:hover { opacity: 1; }
.card__link:hover .card__media > * { transform: scale(1.015); }

/* Image area — height = width / ratio (UPSET pattern). */
.card__media {
  grid-area: image;
  position: relative;
  width: 100%;
  padding-bottom: calc(100% / var(--ratio));
  background: var(--c-card-background);
  border-radius: var(--site-border-radius);
  overflow: hidden;
}

/* Anything inside .card__media fills the box. */
.card__media > * {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transition: transform 0.6s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.card__media img,
.card__media video {
  object-fit: cover;
}

/* Iframe / video motion embeds (CompassStu intro, game loop). Sits at
   100% of the .card__media box. pointer-events:none lets clicks pass
   through to the parent card link. */
.card__motion {
  border: 0;
  background: #000;
  pointer-events: none;
  object-fit: cover;
}

.card__placeholder {
  display: grid;
  place-items: center;
  color: var(--c-text-muted);
  background:
    repeating-linear-gradient(45deg,
      rgba(255, 255, 255, 0.02) 0 12px,
      rgba(255, 255, 255, 0.04) 12px 24px),
    var(--module-bg-color);
}

.card__placeholder--portrait {
  background:
    radial-gradient(ellipse at 50% 30%, rgba(255, 255, 255, 0.08), transparent 60%),
    var(--module-bg-color);
}

.card__placeholder--light {
  background: var(--c-light-gray);
  color: var(--c-dark-black);
}

/* Accent (chartreuse/green) panel like the reference */
.card--accent .card__media--accent {
  background: var(--c-chroma-green);
  color: var(--c-dark-black);
  display: grid;
  place-items: center;
  padding: var(--s-200);
}

.card--accent .card__media { background: var(--c-chroma-green); }

.card__display {
  margin: 0;
  font-size: clamp(40px, 6vw, 88px);
  line-height: 0.95;
  font-weight: 500;
  letter-spacing: -0.02em;
  text-align: center;
  display: grid;
  gap: var(--s-050);
}

.card__display .flip {
  transform: rotate(180deg);
  display: inline-block;
}

/* ---------- About page ----------
   Editorial layout: small uppercase label heading + a vertical column of
   items at display body size. Left-aligned, padded to match the
   project-grid horizontal rhythm. */
.about {
  max-width: 1800px;
  margin: 0 auto var(--s-300);
  padding: 0 calc(var(--project-spacing) / 2);
  display: grid;
  grid-template-columns: minmax(0, 720px);
  gap: var(--s-300);
}

.about__heading {
  margin: 0 0 var(--s-150);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--c-text-muted);
}

.about__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--s-100);
}

.about__list li {
  font-size: clamp(1.08rem, 3.24vw, 1.35rem);
  font-weight: 350;
  letter-spacing: 0.02em;
  line-height: 1.3;
}

/* Card meta — plain text below the image (UPSET .project text area).
   Small left padding compensates for glyph left side bearing so the
   text optically aligns with the rounded media's left edge. */
.card__meta {
  grid-area: text;
  display: grid;
  gap: 4px;
  padding: 0 0 0 4px;
  background: transparent;
  color: var(--c-text);
}

.card__title {
  margin: 0;
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0.02em;
  color: var(--c-card-foreground);
}

.card__subtitle {
  margin: 0;
  font-size: 13px;
  color: var(--c-text-muted);
}

/* ---------- Project page ----------
   Layout (top → bottom):
     row 1: one full-width block (hero)
     row 2: one full-width block
     row 3: two half-width blocks
     row 4: one full-width block
   Each block is a placeholder box now — drop content/images in later.
*/
.page--project {
  padding: var(--s-100) var(--main-inline-s) calc(var(--nav-height) + var(--s-300));
  max-width: 1800px;
  margin: 0 auto;
}

/* Header band — mirrors the index intro: 52vh, flex-centered, room to breathe. */
.project__header {
  min-height: 52vh;
  text-align: center;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: var(--s-200);
  max-width: 130ch;
  margin: 0 auto;
}

/* Back pill — floats top-left over content so it's always reachable
   without breaking the centered header band. Same surface as the dock. */
.project__back {
  position: fixed;
  top: var(--s-200);
  left: var(--s-200);
  z-index: 40;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px 8px 10px;
  border-radius: 999px;
  background: rgba(18, 20, 22, 0.72);
  border: 1px solid rgba(255, 255, 255, 0.08);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.04) inset,
    0 8px 24px rgba(0, 0, 0, 0.35);
  font-size: 13px;
  letter-spacing: 0.02em;
  color: var(--c-light-white);
  transition: background 0.2s ease, transform 0.2s ease;
}

.project__back:hover { background: rgba(40, 42, 44, 0.78); opacity: 1; }
.project__back:active { transform: scale(0.97); }

/* Title — matches .wordmark styling on the index. */
.project__title {
  margin: 0 0 38px;
  font-size: clamp(1.08rem, 3.24vw, 1.35rem);
  line-height: 1.15;
  font-weight: 550;
  letter-spacing: 0.06em;
  text-shadow: 0 0 0.4px currentColor;
  display: inline-block;
  transform: scaleY(1.05);
  transform-origin: center bottom;
}

/* Meta — matches .tagline styling on the index. */
.project__meta {
  margin: 0;
  font-size: clamp(1.08rem, 3.24vw, 1.35rem);
  line-height: 1.15;
  font-weight: 350;
  letter-spacing: 0.02em;
  text-shadow: 0 0 0.4px currentColor;
}

.project-grid {
  display: grid;
  grid-template-columns: repeat(20, 1fr);
  gap: var(--project-spacing);
  max-width: 1800px;
  margin: 0 auto;
  padding: 0 calc(var(--project-spacing) / 2);
}

.project-block {
  position: relative;
  border-radius: var(--site-border-radius);
  overflow: hidden;
  background: var(--c-card-background);
}

/* Card numbering — adds a small numbered pill in the top-left of any
   project-grid block carrying a `data-num` attribute. Same pill surface
   as the "Case Study" tag on the index but tighter. Add `data-num="N"`
   to any .project-block (or wrapper with position:relative) to label it. */
.project-block[data-num],
.project-text__motion[data-num] { position: relative; }

.project-block[data-num]::before,
.project-text__motion[data-num]::before {
  content: attr(data-num);
  position: absolute;
  top: var(--s-100);
  left: var(--s-100);
  z-index: 3;
  min-width: 22px;
  height: 22px;
  padding: 0 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--c-light-white);
  background: rgba(0, 0, 0, 0.55);
  border-radius: 999px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  pointer-events: none;
}

/* Tech-stack icon row — three equal-size logo chips in a row. Light
   chip background so brand logos (designed for light) read cleanly;
   object-fit: contain keeps each logo whole regardless of its source
   dimensions or format (svg / png / jpg). */
.tech-icons {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-100);
  margin-top: var(--s-200);
}

.tech-icons__item {
  min-width: 0;            /* let grid columns shrink to fit, no overflow */
  aspect-ratio: 3 / 2;
  padding: var(--s-150);
  background: var(--c-light-gray);
  border-radius: var(--site-border-radius);
  overflow: hidden;
}

/* Fill the chip's content box exactly; object-fit: contain then scales
   each logo whole inside it — reliable regardless of source dimensions
   or whether the chip height came from aspect-ratio. */
.tech-icons__item img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* GLB model + in-game screenshot, stacked tight. Each stack spans half
   the project grid; two stacks sit per row. The model viewer uses a 5/3
   ratio (~20% shorter than a standard 4/3 card); the screenshot card
   sits directly below it with only a small gap. */
/* Overlap effect — pulls a project-block up into the preceding section.
   Reset to 0 at tablet/mobile (see responsive block below). */
.project-block--overlap {
  margin-top: calc(var(--s-500) * -1);
}

.glb-stack {
  grid-column: span 10;
  display: flex;
  flex-direction: column;
  gap: var(--s-050);
}

.glb-stack__model { aspect-ratio: 5 / 3; }
.glb-stack__shot  { aspect-ratio: 16 / 9; }

@media (max-width: 600px) {
  .glb-stack { grid-column: 1; }
}

/* SATS logo block — desktop shows the logo art at natural pixel size,
   vertically centred (object-fit: none). On mobile the natural size is
   far wider than the viewport, so it flips to contain (whole logo). */
.sats-logo-block > img {
  top: 50%;
  right: 0;
  bottom: auto;
  left: 0;
  height: auto;
  transform: translateY(-50%);
  object-fit: none;
}

@media (max-width: 600px) {
  .sats-logo-block > img {
    top: 0;
    height: 100%;
    transform: none;
    object-fit: contain;
  }
}

/* Tech badge row (Unity / C# logos) — inline 96px heights overflow a
   narrow viewport; shrink and allow wrapping on mobile. */
@media (max-width: 600px) {
  .tech-badges { flex-wrap: wrap; }
  .tech-badges img { height: 56px !important; }
}

/* Image credit — faint italic caption tucked in the bottom-right of a
   media block. No background box: kept deliberately subtle, just a
   shadow for legibility over varied imagery. */
.media-credit {
  position: absolute;
  right: var(--s-100);
  bottom: var(--s-050);
  z-index: 3;
  font-size: 10px;
  font-style: italic;
  letter-spacing: 0.02em;
  color: rgba(255, 255, 255, 0.5);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
  pointer-events: none;
}

/* Labeled card — grey header bar fused to the media block below. The
   two children share the same width and only the outer corners are
   rounded (label: top corners, media: bottom corners), so the pair
   reads as one unit. Negative top margin pulls the card up into the
   preceding section's bottom padding, tightening the visual gap. */
.labeled-card {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
}

.labeled-card__label {
  background: #888888;
  color: var(--c-light-white);
  padding: calc(var(--s-150) * 0.9) var(--s-200);
  border-top-left-radius: var(--site-border-radius);
  border-top-right-radius: var(--site-border-radius);
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.02em;
  text-align: center;
}

.labeled-card__media {
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}

/* ---------- Approach accordion (Card 11) ----------
   Centered title + intro, stacked accordion items below. Native
   <details>/<summary> for expand behaviour. Type scale and colour
   tokens mirror the project-text sections so this block reads as part
   of the same family — title at thesis scale, intro at subhead scale,
   accordion body at the same scale + muted colour as other body text.
   Item surface uses --c-card-background to sit in the same visual
   family as the project blocks above. */
.approach {
  grid-column: 1 / -1;
  padding: calc(var(--s-500) + var(--s-150)) var(--s-200);
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* Title — same scale as .project-text__thesis, with the same numbered
   prefix pattern used by .project-text__section-title (muted number +
   full-colour label). Flex-centered so the pair stays balanced. */
.approach__title {
  width: 100%;
  max-width: 920px;
  margin: 0 0 var(--s-300);
  display: flex;
  align-items: baseline;
  justify-content: flex-start;
  gap: var(--s-100);
  font-size: clamp(1.55rem, 3vw, 2.1rem);
  line-height: 1.2;
  font-weight: 400;
  letter-spacing: -0.012em;
  text-align: left;
  text-shadow: 0 0 0.4px currentColor;
}

.approach__num {
  color: var(--c-text-muted);
  font-variant-numeric: tabular-nums;
}

.approach__label {
  color: var(--c-text);
  font-weight: 500;
}

/* Intro — matches .project-text__subhead exactly. */
.approach__intro {
  width: 100%;
  max-width: 920px;
  margin: 0 0 var(--s-400);
  font-size: clamp(1.05rem, 1.42vw, 1.26rem);
  line-height: 1.5;
  font-weight: 350;
  letter-spacing: 0.005em;
  color: var(--c-text-muted);
  text-align: left;
}

.approach__list {
  width: 100%;
  max-width: 920px;
  display: flex;
  flex-direction: column;
  gap: var(--s-100);
}

/* Item surface — dark card grey in dark mode, light grey in light mode
   so the bars don't read as harsh dark blocks on a white page. */
.approach-item {
  background: var(--c-card-background);
  border-radius: var(--site-border-radius);
  overflow: hidden;
}

:root.theme-light .approach-item {
  background: #f0f0f0;
}

/* Hide native marker (cross-browser). */
.approach-item__head {
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-200);
  padding: var(--s-200);
  cursor: pointer;
  user-select: none;
}
.approach-item__head::-webkit-details-marker { display: none; }

/* Item title — same scale as project-text body, weight 500 for emphasis. */
.approach-item__title {
  font-size: clamp(1.1rem, 1.3vw, 1.26rem);
  line-height: 1.3;
  font-weight: 500;
  letter-spacing: 0.005em;
  color: var(--c-text);
}

/* Circular chevron button — auto-flips with theme so it always stands
   out from the bar surface (white-on-dark in dark mode, dark-on-light
   in light mode). */
.approach-item__icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--c-text);
  color: var(--c-background);
  transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
}

.approach-item[open] .approach-item__icon {
  transform: rotate(180deg);
}

.approach-item__body {
  padding: 0 var(--s-200) var(--s-200);
}

/* Body text — matches .project-text__body p exactly (same scale, weight,
   line-height, letter-spacing, colour). */
.approach-item__body p {
  margin: 0;
  font-size: clamp(1.1rem, 1.3vw, 1.26rem);
  line-height: 1.55;
  font-weight: 400;
  letter-spacing: 0.005em;
  color: var(--c-text-muted);
  max-width: 72ch;
}

@media (max-width: 600px) {
  .approach { padding: calc(var(--s-500) + var(--s-300)) var(--s-100) calc(var(--s-500) + var(--s-100)); }
  .approach-item__head { padding: var(--s-150); }
  .approach-item__body { padding: 0 var(--s-150) var(--s-150); }
}

.project-block--full { grid-column: 1 / -1; }
.project-block--half { grid-column: span 10; }
.project-block--60   { grid-column: span 12; }
.project-block--40   { grid-column: span 8; }

/* Default placeholder ratios per block. Override per-block below. */
.project-block--full { aspect-ratio: 16 / 9; }
.project-block--half { aspect-ratio: 4 / 3; }
.project-block--60   { aspect-ratio: 4 / 3; }
.project-block--40   { aspect-ratio: 4 / 3; }
.project-block--hero { aspect-ratio: 16 / 8; }

/* --auto: drop the fixed aspect-ratio so the block's height comes from
   its content (e.g. an image's natural proportions, no cropping). Other
   blocks in the same grid row stretch to match via default align-items. */
.project-block--auto { aspect-ratio: auto; }

/* --crop-top: shrink the block to 16:8.415 (6.5% shorter than 16:9). For a
   16:9 video sized via object-fit:cover, the height now overhangs by 6.5%;
   pinning object-position to the bottom crops exactly that 6.5% off the
   top — useful when a screen recording shows the browser chrome up top. */
.project-block--crop-top { aspect-ratio: 16 / 8.415; }
.project-block > video.project-block__video--crop-top {
  object-position: 50% 100%;
}
.project-block--auto > img,
.project-block--auto > video {
  position: static;
  width: 100%;
  height: auto;
  object-fit: initial;
}

.project-block .card__placeholder { width: 100%; height: 100%; }

/* ---------- Project text section ----------
   Two-column editorial spread, all left-aligned. 50/50 split.
     LEFT  → hero pitch: dominant display lead + smaller subhead.
     RIGHT → numbered section heading, body block, closing tagline
              (with a thin hairline divider above it as a "kicker").
   The hierarchy is carried by SIZE (lead > section title > tagline >
   body > subhead) and by COLOR (text vs text-muted) — not by piling
   on weights.

   Spans the full project-grid width — edge-to-edge with the images. */
.project-text {
  grid-column: 1 / -1;
  /* Uniform vertical padding so all numbered sections (.project-text,
     .approach, .proof-layer) produce a 12rem gap between siblings
     (5.5rem padding each side + 1rem grid gap). */
  padding: calc(var(--s-500) + var(--s-150)) var(--s-200);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: calc(var(--s-500) + var(--s-100));
  align-items: start;
}

/* Centered single-column variant — the block sits at the page's
   centerline, but the text inside reads left-aligned (matches the
   pattern used by Section 05). */
.project-text--center {
  justify-items: center;
}

.project-text__center {
  width: 100%;
  max-width: 920px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
}

/* Chapter divider — hairline at the top of a numbered section so the
   page reads as distinct chapters rather than one continuous column. */
.project-text--chapter {
  border-top: 1px solid color-mix(in srgb, var(--c-text) 12%, transparent);
}

/* Mirrored layout — swaps the two columns so the image/text sides
   alternate down the page (zigzag rhythm). A full-width section title
   (grid-column: 1 / -1) keeps its default order and stays on top. */
.project-text--flip .project-text__left  { order: 2; }
.project-text--flip .project-text__right { order: 1; }

/* Prevent long content (e.g. tile cards, prose with long titles)
   from forcing the column wider than its fr allocation. */
.project-text__left,
.project-text__right { min-width: 0; }

/* — LEFT column: hero pitch — */

.project-text__lead {
  margin: 0 0 var(--s-300);
  font-size: clamp(2.025rem, 4.86vw, 3.285rem);
  line-height: 1.05;
  font-weight: 400;
  letter-spacing: -0.025em;
  color: var(--c-text);
  text-shadow: 0 0 0.4px currentColor;
}

.project-text__subhead {
  margin: 0;
  font-size: clamp(1.05rem, 1.42vw, 1.26rem);
  line-height: 1.5;
  font-weight: 350;
  letter-spacing: 0.005em;
  color: var(--c-text-muted);
}

/* — RIGHT column: section heading — */

/* "01  Overview" : tabular number muted, label full-colour. Editorial
   "Chapter N — Title" pattern, baseline-aligned via flex/gap. Top
   margin creates separation from preceding content in the same column;
   collapsed to 0 when the title is the first child of its column. */
.project-text__section-title {
  display: flex;
  align-items: baseline;
  gap: var(--s-100);
  margin: var(--s-500) 0 var(--s-300);
  font-size: clamp(1.42rem, 2.23vw, 1.86rem);
  line-height: 1.2;
  font-weight: 400;
  letter-spacing: -0.008em;
}

.project-text__section-title:first-child { margin-top: 0; }

.project-text__num {
  color: var(--c-text-muted);
  font-variant-numeric: tabular-nums;
}

.project-text__label {
  color: var(--c-text);
  font-weight: 500;
}

/* Subsection title — used within a body block to chunk it into named
   parts (e.g. "6.1 The page"). Same num + label pattern as the section
   title, scaled down. Margin-top creates clear separation between
   subsections; first-child resets to 0. */
.project-text__subsection-title {
  display: flex;
  align-items: baseline;
  gap: var(--s-100);
  margin: var(--s-300) 0 var(--s-100);
  font-size: clamp(1rem, 1.2vw, 1.15rem);
  line-height: 1.3;
  font-weight: 500;
  letter-spacing: -0.005em;
  color: var(--c-text);
}

.project-text__body .project-text__subsection-title:first-child { margin-top: 0; }

.project-text__subsection-num {
  color: var(--c-text-muted);
  font-variant-numeric: tabular-nums;
  font-weight: 400;
}

/* — RIGHT column: body block — */

/* Paragraphs sit tight together so the block reads as one thought, not
   two separate items. */
.project-text__body {
  margin: 0 0 var(--s-300);
}

.project-text__body p {
  margin: 0 0 var(--s-050);
  font-size: clamp(1.1rem, 1.3vw, 1.26rem);
  line-height: 1.55;
  font-weight: 400;
  letter-spacing: 0.005em;
  color: var(--c-text-muted);
}

.project-text__body p:last-child { margin-bottom: 0; }

/* — RIGHT column: closing kicker — */

/* Thin hairline above + italic for the closing statement. Editorial
   "kicker" convention. */
.project-text__tagline {
  margin: 0;
  padding-top: var(--s-200);
  border-top: 1px solid color-mix(in srgb, var(--c-text) 14%, transparent);
  font-size: clamp(1.17rem, 1.62vw, 1.42rem);
  line-height: 1.35;
  font-weight: 400;
  font-style: italic;
  letter-spacing: 0.002em;
  color: var(--c-text);
  text-shadow: 0 0 0.4px currentColor;
}

/* Comparison block — editorial "What X / What Y" pattern. Hairline
   divider above (replaces the user's "—" separator). Muted label on
   the left, full-colour answer on the right, both at body size. */
.project-text__compare {
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: var(--s-200);
  row-gap: var(--s-100);
  margin: var(--s-300) 0 0;
  padding-top: var(--s-300);
  border-top: 1px solid color-mix(in srgb, var(--c-text) 14%, transparent);
}

.project-text__compare dt,
.project-text__compare dd {
  margin: 0;
  font-size: clamp(1.1rem, 1.3vw, 1.26rem);
  line-height: 1.5;
  font-weight: 400;
  letter-spacing: 0.005em;
}

.project-text__compare dt { color: var(--c-text-muted); }
.project-text__compare dd { color: var(--c-text); }

/* Thesis statement — short punchy claim that opens a numbered section.
   Sits below the section title and above the body. Bigger than body,
   smaller than the page-level hero lead. */
.project-text__thesis {
  margin: 0 0 var(--s-300);
  font-size: clamp(1.55rem, 3vw, 2.1rem);
  line-height: 1.2;
  font-weight: 400;
  letter-spacing: -0.012em;
  color: var(--c-text);
  text-shadow: 0 0 0.4px currentColor;
}

/* Three-layer pipeline / product pillars list. Each row pairs a
   prominent action label with a supporting description. Weight order
   is INVERTED from .project-text__compare: here labels lead and
   descriptions support. */
.project-text__pipeline {
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: var(--s-200);
  row-gap: var(--s-150);
  margin: var(--s-300) 0 0;
  padding-top: var(--s-300);
  border-top: 1px solid color-mix(in srgb, var(--c-text) 14%, transparent);
}

.project-text__pipeline dt,
.project-text__pipeline dd {
  margin: 0;
  font-size: clamp(1.1rem, 1.3vw, 1.26rem);
  line-height: 1.5;
  letter-spacing: 0.005em;
}

.project-text__pipeline dt {
  color: var(--c-text);
  font-weight: 500;
}

.project-text__pipeline dd {
  color: var(--c-text-muted);
  font-weight: 400;
}

/* Inline code — for table names, columns, paths inside body / pipeline copy.
   Subtle background pill so identifiers don't visually shout, just sit
   apart from the prose. */
.project-text__body code,
.project-text__pipeline code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
  font-size: 0.88em;
  padding: 0.1em 0.4em;
  background: color-mix(in srgb, var(--c-text) 7%, transparent);
  border-radius: 4px;
  color: var(--c-text);
  letter-spacing: 0;
}

/* Motion embed inside the right column — iframe wrapper. Background
   matches the page surface (no panel chrome) so the diagram reads as
   part of the page flow, not as a pasted GIF. Aspect-ratio is wider
   now that the diagram is just verbs + connectors (no descriptions). */
.project-text__motion {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  overflow: hidden;
}

.project-text__motion iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  background: transparent;
}

.project-text__motion img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@media (max-width: 800px) {
  .project-text {
    grid-template-columns: 1fr;
    gap: var(--s-400);
    padding: calc(var(--s-500) + var(--s-300)) var(--s-100) calc(var(--s-500) + var(--s-100));
  }
}

/* ---------- Section 08: The Proof Layer ----------
   Editorial paragraph with three emphasis tiers that stay in the page's
   restrained typographic family:
     • default text  — var(--c-text)        (main narrative)
     • __emp         — same colour, bold    (key concepts; weight, not hue)
     • __muted       — var(--c-text-muted)  (supporting / technical detail)
   Wrapped in a dark card surface (matches the image cards' --c-card-
   background) so it reads as a contained "moment" rather than text
   floating on the page bg. Closes with a CTA pill that borrows the
   dock's translucent-glass surface so it reads as native to the page. */
.proof-layer {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-300);
  align-items: center;
  padding: var(--s-500) var(--s-400);
  margin: calc(var(--s-500) + var(--s-150)) 0;
  background: var(--c-card-background);
  border-radius: var(--site-border-radius);
}

:root.theme-light .proof-layer {
  background: #f0f0f0;
}

.proof-layer__main {
  min-width: 0;
}

.proof-layer__visual {
  min-width: 0;
  display: flex;
  justify-content: center;
  align-items: center;
}

/* Same scale as .project-text__thesis so it sits in the same display
   tier as "We do not sell knowledge" / "Mastery is iterative". */
.proof-layer__body {
  margin: var(--s-400) 0;
  max-width: 50ch;
  font-size: clamp(1.55rem, 3vw, 2.1rem);
  line-height: 1.25;
  font-weight: 400;
  letter-spacing: -0.012em;
  color: var(--c-text);
  text-shadow: 0 0 0.4px currentColor;
}

/* Emphasis via weight, not colour — keeps the page's monochrome voice. */
.proof-layer__emp {
  font-weight: 600;
}

.proof-layer__muted {
  color: var(--c-text-muted);
}

/* CTA pill — matches the dock surface vocabulary:
   translucent grey + backdrop blur + thin white border. */
.proof-layer__cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 10px 10px 10px 20px;
  background: rgba(120, 120, 120, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.07);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  color: var(--c-light-white);
  border-radius: 999px;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.02em;
  text-decoration: none;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.04) inset,
    0 8px 24px rgba(0, 0, 0, 0.35);
  transition: background 0.2s ease,
              transform 0.2s ease,
              border-color 0.2s ease;
}

.proof-layer__cta:hover {
  background: rgba(40, 42, 44, 0.78);
  border-color: rgba(255, 255, 255, 0.12);
  opacity: 1; /* override the site-wide a:hover opacity fade */
}

.proof-layer__cta:active { transform: scale(0.97); }

/* Circular arrow nub — same form as the dock action button. */
.proof-layer__cta-arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.10);
  border: 1px solid rgba(255, 255, 255, 0.08);
  font-size: 13px;
  line-height: 1;
  transition: transform 0.25s cubic-bezier(0.2, 0.85, 0.3, 1);
}

.proof-layer__cta:hover .proof-layer__cta-arrow {
  transform: translateX(2px);
}

/* Rubric scoreboard — the right-side visual companion to the proof copy.
   Uses a translucent surface so it inherits theme adaptation via
   color-mix on var(--c-text). Bars animate in on first paint. */
.rubric-card {
  width: 100%;
  max-width: 720px;
  padding: var(--s-300);
  border-radius: 18px;
  background: color-mix(in srgb, var(--c-text) 4%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c-text) 10%, transparent);
  font-feature-settings: "tnum" 1, "lnum" 1;
}

.rubric-card__header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: var(--s-300);
}

.rubric-card__title {
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-text-muted);
}

.rubric-card__total {
  font-size: 40px;
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--c-text);
  font-variant-numeric: tabular-nums;
}

.rubric-card__rows {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.rubric-card__row {
  display: grid;
  grid-template-columns: 10.5rem 1fr 2.5ch;
  align-items: center;
  gap: 16px;
}

.rubric-card__label {
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--c-text-muted);
}

.rubric-card__bar {
  height: 6px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--c-text) 8%, transparent);
  overflow: hidden;
}

.rubric-card__fill {
  height: 100%;
  width: var(--score, 0%);
  border-radius: inherit;
  background: linear-gradient(
    90deg,
    color-mix(in srgb, var(--c-text) 55%, transparent),
    var(--c-text)
  );
  transform-origin: left center;
  animation: rubric-fill-loop 8s cubic-bezier(0.2, 0.85, 0.3, 1) infinite;
}

/* Stagger so the four bars fill in sequence each loop. */
.rubric-card__row:nth-child(1) .rubric-card__fill { animation-delay: 0s; }
.rubric-card__row:nth-child(2) .rubric-card__fill { animation-delay: 0.18s; }
.rubric-card__row:nth-child(3) .rubric-card__fill { animation-delay: 0.36s; }
.rubric-card__row:nth-child(4) .rubric-card__fill { animation-delay: 0.54s; }

/* Fill from 0 → full over ~2s, hold ~5.3s, fade out over ~0.5s.
   Opacity reset at 100% lands on a zero-width bar so the wrap is invisible. */
@keyframes rubric-fill-loop {
  0%   { transform: scaleX(0);   opacity: 1; }
  25%  { transform: scaleX(1);   opacity: 1; }
  91%  { transform: scaleX(1);   opacity: 1; }
  98%  { transform: scaleX(1);   opacity: 0; }
  100% { transform: scaleX(0);   opacity: 0; }
}

.rubric-card__value {
  font-size: 14px;
  font-weight: 500;
  text-align: right;
  color: var(--c-text);
  font-variant-numeric: tabular-nums;
  animation: rubric-value-fade 8s ease-out infinite;
}

.rubric-card__row:nth-child(1) .rubric-card__value { animation-delay: 0s; }
.rubric-card__row:nth-child(2) .rubric-card__value { animation-delay: 0.18s; }
.rubric-card__row:nth-child(3) .rubric-card__value { animation-delay: 0.36s; }
.rubric-card__row:nth-child(4) .rubric-card__value { animation-delay: 0.54s; }

/* Number fades in alongside its bar reaching full, fades with the reset. */
@keyframes rubric-value-fade {
  0%, 20%  { opacity: 0; }
  26%, 95% { opacity: 1; }
  100%     { opacity: 0; }
}

.rubric-card__verified {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: var(--s-300);
  padding-top: var(--s-200);
  border-top: 1px solid color-mix(in srgb, var(--c-text) 8%, transparent);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--c-text-muted);
}

.rubric-card__dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #48ea2d;
  box-shadow: 0 0 10px rgba(72, 234, 45, 0.55);
}

@media (prefers-reduced-motion: reduce) {
  .rubric-card__fill,
  .rubric-card__value {
    animation: none;
  }
  .rubric-card__fill { opacity: 1; transform: scaleX(1); }
  .rubric-card__value { opacity: 1; }
}

@media (max-width: 960px) {
  .proof-layer {
    grid-template-columns: 1fr;
    gap: var(--s-300);
    padding: calc(var(--s-500) + var(--s-100)) var(--s-100);
  }
  .proof-layer__visual { justify-content: flex-start; }
  .rubric-card { max-width: none; }
}

.project-block > img,
.project-block > video,
.project-block > iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border: 0;
}


@media (max-width: 600px) {
  .project-grid { grid-template-columns: 1fr; }
  .project-block--half,
  .project-block--60,
  .project-block--40 { grid-column: 1; aspect-ratio: 4 / 3; }
  .project-block--full,
  .project-block--hero { aspect-ratio: 4 / 3; }
}

/* ============================================================
   ABOUT PAGE — editorial sections built on the project-grid.
   Custom components below introduce typographic + spatial
   variety so the page reads as composed rather than uniform.
   ============================================================ */

/* DIVIDER — editorial section ornament: short hairline + small dot
   + short hairline, centered. Marks the transition from page header
   to body without imposing a full-width rule. */
.about-divider {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  margin: var(--s-200) 0 var(--s-100);
}

.about-divider::before,
.about-divider::after {
  content: "";
  display: block;
  width: 48px;
  height: 1px;
  background: color-mix(in srgb, var(--c-text) 22%, transparent);
}

.about-divider span {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--c-text) 38%, transparent);
}

/* HERO — full-bleed display moment. Stretched type, deep top
   padding so it reads as a title page rather than a section.
   Two-column at desktop: lead text on the left, contact CTA on the right. */
.about-hero {
  grid-column: 1 / -1;
  padding: var(--s-500) var(--s-200) var(--s-400);
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--s-400);
  align-items: end;
}

@media (max-width: 900px) {
  .about-hero {
    grid-template-columns: 1fr;
    gap: var(--s-300);
  }
}

/* HERO CTA — outlined ghost button that inverts to filled on hover.
   Tall, generously padded so it reads as a deliberate primary action,
   not a chip in the corner. Uses currentColor so children flip with
   the parent's color inversion. */
.about-hero__cta {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--s-300);
  padding: var(--s-300) var(--s-400);
  border-radius: var(--site-border-radius);
  background-color: transparent;
  background-image: linear-gradient(105deg, color-mix(in srgb, var(--c-text) 88%, var(--c-background)) 50%, transparent 50%);
  background-size: 220% 100%;
  background-position: 100% 0;
  background-repeat: no-repeat;
  color: var(--c-text);
  text-decoration: none;
  min-width: 440px;
  min-height: 200px;
  box-shadow: inset 0 0 0 1.5px var(--c-text);
  transition:
    transform 0.45s cubic-bezier(0.2, 0.85, 0.3, 1),
    background-position 0.9s cubic-bezier(0.65, 0, 0.35, 1),
    color 0.55s cubic-bezier(0.65, 0, 0.35, 1) 0.25s,
    box-shadow 0.9s cubic-bezier(0.65, 0, 0.35, 1);
}

/* Animations live on pseudo-elements so the button itself can
   transition cleanly on hover without animation snap-back. */
.about-hero__cta::before,
.about-hero__cta::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  transition: opacity 0.4s ease;
}

/* Breathing outer glow */
.about-hero__cta::after {
  box-shadow: 0 6px 18px -10px color-mix(in srgb, var(--c-text) 6%, transparent);
  animation: about-cta-breathe 2.6s ease-in-out infinite;
  z-index: -1;
}

/* Expanding ping ring */
.about-hero__cta::before {
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--c-text) 45%, transparent);
  animation: about-cta-ping 2.6s cubic-bezier(0.2, 0.8, 0.2, 1) infinite;
}

@keyframes about-cta-breathe {
  0%, 100% { box-shadow: 0 6px 18px -10px color-mix(in srgb, var(--c-text) 6%, transparent); }
  50%      { box-shadow: 0 26px 60px -10px color-mix(in srgb, var(--c-text) 42%, transparent); }
}

@keyframes about-cta-ping {
  0%        { box-shadow: 0 0 0 0 color-mix(in srgb, var(--c-text) 45%, transparent); }
  70%, 100% { box-shadow: 0 0 0 14px color-mix(in srgb, var(--c-text) 0%, transparent); }
}

.about-hero__cta:hover {
  background-position: 0% 0;
  color: var(--c-background);
  transform: translateY(-3px);
  box-shadow:
    inset 0 0 0 1.5px var(--c-text),
    0 28px 56px -20px color-mix(in srgb, var(--c-text) 30%, transparent);
}

.about-hero__cta:hover::before,
.about-hero__cta:hover::after {
  opacity: 0;
}

@media (prefers-reduced-motion: reduce) {
  .about-hero__cta::before,
  .about-hero__cta::after { animation: none; }
}

.about-hero__cta-status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.7;
  color: currentColor;
}

.about-hero__cta-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #48ea2d;
  box-shadow: 0 0 8px rgba(72, 234, 45, 0.6);
  animation: about-pulse 2.4s ease-in-out infinite;
}

.about-hero__cta-line {
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: var(--s-150);
  font-size: clamp(1.85rem, 2.6vw, 2.35rem);
  font-weight: 400;
  letter-spacing: -0.025em;
  line-height: 1.05;
  color: currentColor;
}

.about-hero__cta-arrow {
  display: inline-block;
  font-size: 0.9em;
  color: currentColor;
  transition: transform 0.35s cubic-bezier(0.2, 0.85, 0.3, 1);
}

.about-hero__cta:hover .about-hero__cta-arrow {
  transform: translate(6px, -6px);
}

.about-hero__lead {
  margin: 0;
  max-width: 22ch;
  font-family: var(--font-display, inherit);
  font-size: clamp(2.4rem, 5.6vw, 5rem);
  font-weight: 350;
  letter-spacing: -0.025em;
  line-height: 1.04;
  color: var(--c-text);
}

.about-hero__sub {
  margin: var(--s-300) 0 0;
  max-width: 48ch;
  font-size: clamp(1.05rem, 1.6vw, 1.3rem);
  font-weight: 400;
  letter-spacing: -0.005em;
  line-height: 1.45;
  color: var(--c-text-muted);
}

/* NOW badge — small pill with a live status dot. Goes inside the
   .proof-layer card on Section 02 to mark it as the live beat. */
.about-now-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px 6px 10px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--c-text) 6%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c-text) 10%, transparent);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-text-muted);
}

.about-now-badge__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #48ea2d;
  box-shadow: 0 0 8px rgba(72, 234, 45, 0.55);
  animation: about-pulse 2.4s ease-in-out infinite;
}

@keyframes about-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.55; }
}

/* META panel — labelled key/value list sitting on the right side
   of the Now card. Reads like a passport / spec sheet. */
.about-meta {
  display: flex;
  align-items: center;
  width: 100%;
}

.about-meta__list {
  margin: 0;
  padding: 0;
  width: 100%;
  max-width: 360px;
  display: flex;
  flex-direction: column;
  gap: 0;
}

.about-meta__row {
  display: grid;
  grid-template-columns: 5rem 1fr;
  align-items: baseline;
  gap: var(--s-150);
  padding: var(--s-150) 0;
  border-top: 1px solid color-mix(in srgb, var(--c-text) 8%, transparent);
}

.about-meta__row:last-child {
  border-bottom: 1px solid color-mix(in srgb, var(--c-text) 8%, transparent);
}

.about-meta__row dt {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--c-text-muted);
}

.about-meta__row dd {
  margin: 0;
  font-size: 14px;
  font-weight: 400;
  color: var(--c-text);
}

.about-meta__dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #48ea2d;
  margin-right: 8px;
  box-shadow: 0 0 8px rgba(72, 234, 45, 0.55);
  vertical-align: 1px;
}

/* MANIFESTO — full-bleed pull quote. The page's signature line.
   Two large lines stacked, an offset second line for typographic
   tension, and a small label below. */
.about-manifesto {
  grid-column: 1 / -1;
  padding: var(--s-500) var(--s-200);
  text-align: center;
}

.about-manifesto__line {
  margin: 0;
  font-size: clamp(2.4rem, 6vw, 5rem);
  font-weight: 350;
  letter-spacing: -0.03em;
  line-height: 1.02;
  color: var(--c-text);
}

.about-manifesto__line--alt {
  margin-top: 0.1em;
  font-style: italic;
  color: color-mix(in srgb, var(--c-text) 65%, transparent);
}

.about-manifesto__sub {
  margin: var(--s-300) 0 0;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--c-text-muted);
}

/* Small inline tag used inside Prior Work entries for date ranges. */
.about-tag {
  display: inline-block;
  margin-right: 10px;
  padding: 2px 8px;
  border-radius: 4px;
  background: color-mix(in srgb, var(--c-text) 8%, transparent);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--c-text-muted);
  vertical-align: 2px;
}

/* TOOLKIT — restructured: tool icon strip at the top (mastery signal),
   followed by capability blocks pairing tool stack with outcome.
   Single column flow; capability blocks are a 2-col grid. */
.about-toolkit {
  grid-column: 1 / -1;
  padding: var(--s-400) var(--s-200);
  display: flex;
  flex-direction: column;
  gap: var(--s-300);
}

.about-toolkit__head {
  display: flex;
  flex-direction: column;
  gap: var(--s-200);
}

.about-toolkit__lead {
  margin: 0;
  max-width: 60ch;
  font-size: clamp(1rem, 1.4vw, 1.18rem);
  font-weight: 400;
  letter-spacing: -0.005em;
  line-height: 1.5;
  color: var(--c-text-muted);
}

.about-toolkit__group {
  min-width: 0;
}

.about-toolkit__title {
  margin: 0 0 var(--s-200);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-text-muted);
}

/* Tool icon strip — at-a-glance kit. Each cell is icon + label. */
.about-toolkit__icons {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
  gap: var(--s-100);
}

.about-toolkit__icon {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-100);
  padding: var(--s-200) var(--s-100);
  border-radius: 12px;
  background: color-mix(in srgb, var(--c-text) 3%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c-text) 8%, transparent);
  opacity: 0;
  transform: translateY(8px);
  transition:
    opacity 0.45s cubic-bezier(0.2, 0.8, 0.2, 1),
    transform 0.3s cubic-bezier(0.2, 0.85, 0.3, 1),
    background 0.25s ease,
    box-shadow 0.25s ease;
  transition-delay: var(--d, 0ms);
}

.about-toolkit.is-revealed .about-toolkit__icon {
  opacity: 1;
  transform: translateY(0);
}

.about-toolkit__icon:hover {
  transform: translateY(-2px);
  background: color-mix(in srgb, var(--c-text) 6%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c-text) 16%, transparent);
  transition-delay: 0ms;
}

.about-toolkit__icon-img {
  width: 44px;
  height: 44px;
  border-radius: 8px;
  overflow: hidden;
  background: #ffffff;
  display: grid;
  place-items: center;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c-text) 6%, transparent);
}

.about-toolkit__icon-img img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 6px;
}

.about-toolkit__icon-name {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--c-text);
  text-align: center;
}

/* Capability blocks — tool stack + outcome line. */
.about-toolkit__capabilities {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-200) var(--s-300);
  margin-top: var(--s-150);
}

.about-toolkit__cap {
  padding: var(--s-200) 0 0;
  border-top: 1px solid color-mix(in srgb, var(--c-text) 12%, transparent);
}

.about-toolkit__cap-title {
  margin: 0 0 var(--s-100);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-text-muted);
}

.about-toolkit__cap-stack {
  margin: 0 0 6px;
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--c-text);
  letter-spacing: -0.005em;
  line-height: 1.4;
}

.about-toolkit__cap-desc {
  margin: 0;
  font-size: 0.88rem;
  line-height: 1.55;
  color: var(--c-text-muted);
}

@media (max-width: 720px) {
  .about-toolkit__capabilities { grid-template-columns: 1fr; }
}

.about-chips {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.about-chips li {
  padding: 7px 14px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--c-text) 4%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c-text) 10%, transparent);
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0.01em;
  color: var(--c-text);
}

.about-chips--accent li {
  background: color-mix(in srgb, var(--c-text) 10%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c-text) 18%, transparent);
  font-weight: 500;
}

/* CONTACT — closing signature card. Centered, bordered, three
   channels in a row. Each channel surfaces label + value with
   hover lift to invite the click. */
.about-contact {
  grid-column: 1 / -1;
  padding: var(--s-400) var(--s-200) var(--s-500);
  display: flex;
  justify-content: center;
}

.about-contact__card {
  width: 100%;
  max-width: 720px;
  padding: var(--s-400) var(--s-400) var(--s-300);
  border-radius: 22px;
  background: color-mix(in srgb, var(--c-text) 4%, transparent);
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--c-text) 10%, transparent),
    0 30px 60px -30px rgba(0, 0, 0, 0.4);
  text-align: center;
}

.about-contact__status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-text-muted);
}

.about-contact__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #48ea2d;
  box-shadow: 0 0 8px rgba(72, 234, 45, 0.55);
  animation: about-pulse 2.4s ease-in-out infinite;
}

.about-contact__line {
  margin: var(--s-200) 0 var(--s-300);
  font-size: clamp(2rem, 4.4vw, 3.4rem);
  font-weight: 350;
  letter-spacing: -0.025em;
  line-height: 1.05;
  color: var(--c-text);
}

/* Primary CTA inside the contact card — opens the same modal as the
   hero CTA. Outlined ghost button with hover invert. */
.about-contact__cta {
  display: inline-flex;
  align-items: center;
  gap: var(--s-100);
  margin: 0 auto var(--s-400);
  padding: 12px 24px;
  border: none;
  border-radius: 14px;
  background-color: transparent;
  color: var(--c-text);
  text-decoration: none;
  box-shadow: inset 0 0 0 1.5px var(--c-text);
  font: inherit;
  font-size: 0.95rem;
  font-weight: 500;
  letter-spacing: -0.005em;
  cursor: pointer;
  transition:
    background-color 1s ease,
    color 1s ease,
    transform 0.35s cubic-bezier(0.2, 0.85, 0.3, 1);
}

.about-contact__cta:hover {
  background-color: var(--c-text);
  color: var(--c-background);
  transform: translateY(-2px);
  opacity: 1;
}

.about-contact__cta-arrow {
  display: inline-block;
  font-size: 0.9em;
  transition: transform 0.35s cubic-bezier(0.2, 0.85, 0.3, 1);
}

.about-contact__cta:hover .about-contact__cta-arrow {
  transform: translate(4px, -4px);
}

.about-contact__channels {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-100);
  border-top: 1px solid color-mix(in srgb, var(--c-text) 8%, transparent);
  padding-top: var(--s-300);
}

.about-contact__channels a {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: var(--s-150) var(--s-100);
  border-radius: 12px;
  text-decoration: none;
  color: var(--c-text);
  transition: background 0.2s ease, transform 0.2s ease;
}

.about-contact__channels a:hover {
  background: color-mix(in srgb, var(--c-text) 6%, transparent);
  transform: translateY(-1px);
  opacity: 1;
}

.about-contact__label {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--c-text-muted);
}

.about-contact__value {
  font-size: 14px;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--c-text);
  font-variant-numeric: tabular-nums;
}

/* Light-mode adaptation: nudge the manifesto alt-line so it
   stays readable against the lighter background. */
:root.theme-light .about-manifesto__line--alt {
  color: color-mix(in srgb, var(--c-text) 55%, transparent);
}

@media (max-width: 800px) {
  .about-toolkit { grid-template-columns: 1fr; gap: var(--s-300); }
  .about-contact__channels { grid-template-columns: 1fr; }
  .about-meta__list { max-width: none; }
  .about-meta { justify-content: flex-start; }
}

/* ---------- Floating dock / nav ----------
   Two pills sit side-by-side: a nav group (Work / Fonts / About) and a
   standalone circular action button (theme toggle). Both share the same
   surface — translucent dark, blurred, soft drop shadow. */
.dock {
  position: fixed;
  bottom: max(var(--s-150), env(safe-area-inset-bottom, 0));
  left: 50%;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  z-index: 50;
}

.dock__group,
.dock__action {
  height: var(--nav-height);
  background: rgba(120, 120, 120, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.07);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.04) inset,
    0 8px 24px rgba(0, 0, 0, 0.35);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
}

.dock__group {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 8px;
  border-radius: 999px;
}

/* Nav link pills — text and active state. */
.dock__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: calc(var(--nav-height) - 16px);
  min-width: calc(var(--nav-height) - 16px);
  padding: 0 var(--nav-padding-inline);
  border-radius: 999px;
  font-size: 13px;
  letter-spacing: 0.02em;
  color: var(--c-light-white);
  transition:
    background 0.2s ease,
    color 0.25s ease,
    transform 0.2s ease;
}

.dock__link:hover {
  background: rgba(255, 255, 255, 0.08);
  opacity: 1;
}

.dock__link:focus-visible {
  outline: 2px solid rgba(255, 255, 255, 0.6);
  outline-offset: 2px;
}

.dock__link:active { transform: scale(0.97); }

.dock__link.is-active {
  background: var(--c-light-gray-muted);
  color: var(--c-light-white);
}

/* Standalone action button (theme toggle). */
.dock__action {
  width: var(--nav-height);
  display: inline-grid;
  place-items: center;
  border-radius: 50%;
  color: var(--c-light-white);
  cursor: pointer;
  transition:
    background 0.2s ease,
    transform 0.2s ease,
    border-color 0.2s ease;
}

.dock__action:hover {
  background: rgba(40, 42, 44, 0.78);
  border-color: rgba(255, 255, 255, 0.12);
}

.dock__action:focus-visible {
  outline: 2px solid rgba(255, 255, 255, 0.6);
  outline-offset: 2px;
}

.dock__action:active { transform: scale(0.94); }

.dock__icon {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: opacity 0.2s ease, transform 0.3s ease;
}

/* Show sun in dark theme, moon in light theme (light theme not yet wired). */
.dock__icon--moon { display: none; }
:root.theme-light .dock__icon--sun { display: none; }
:root.theme-light .dock__icon--moon { display: block; }

/* ---------- Small screens ---------- */
@media (max-width: 600px) {
  /* On phones, use one column and a friendlier landscape ratio for everything. */
  .card,
  .card--tall,
  .card--small,
  .card--accent { --ratio: 1.3; }
  /* Phones don't need a full 50vh intro band. */
  .intro { min-height: auto; padding-block: var(--s-300); }
  .project__header { min-height: auto; padding-block: var(--s-300); }
  .project__back { top: var(--s-100); left: var(--s-100); }
}

/* ---------- Page transitions ----------
   "翻书" / page-turn — every page-load runs a directional slide-in with
   a subtle 3D rotation, evoking a turning book page. Direction is set
   by a class on <html>:
     • .vt-forward → project / writing pages slide in from the RIGHT
       (you're going INTO the book — page comes from the next leaf).
     • .vt-back    → the index slides in from the LEFT (returning home
       — page comes back from the previous leaf).

   Pure CSS, runs on EVERY page load. No protocol or browser API
   requirements — visible identically on file://, localhost, deployed,
   refreshes, and navigations. The .dock sits outside .page so it stays
   anchored across the change. */
@keyframes pageTurnFromRight {
  0%   { opacity: 0;   transform: translateX(80px); clip-path: inset(0 0 100% 0); }
  18%  { opacity: 0.9;                              clip-path: inset(0 0 80% 0); }
  55%  {                                            clip-path: inset(0 0 0 0); }
  100% { opacity: 1;   transform: translateX(0);   clip-path: inset(0 0 0 0); }
}
@keyframes pageTurnFromLeft {
  0%   { opacity: 0;   transform: translateX(-80px); clip-path: inset(0 0 100% 0); }
  18%  { opacity: 0.9;                                clip-path: inset(0 0 80% 0); }
  55%  {                                              clip-path: inset(0 0 0 0); }
  100% { opacity: 1;   transform: translateX(0);     clip-path: inset(0 0 0 0); }
}

:root.vt-forward .page {
  animation: pageTurnFromRight 1.0s cubic-bezier(0.33, 0.05, 0.2, 1) both;
}
:root.vt-back .page {
  animation: pageTurnFromLeft 1.0s cubic-bezier(0.33, 0.05, 0.2, 1) both;
}

@media (prefers-reduced-motion: reduce) {
  :root.vt-forward .page,
  :root.vt-back    .page { animation: none; }
}

/* ============================================================
   ABOUT — scroll reveals & micro-interactions
   Subtle entrance motion that extends the site's existing
   cubic-bezier vocabulary. Each effect is opt-in via attributes
   set in markup; JS toggles .is-revealed when in viewport.
   ============================================================ */

/* Generic section reveal: subtle lift + fade. */
[data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition:
    opacity 0.7s cubic-bezier(0.2, 0.8, 0.2, 1),
    transform 0.7s cubic-bezier(0.2, 0.8, 0.2, 1);
  will-change: opacity, transform;
}

[data-reveal].is-revealed {
  opacity: 1;
  transform: none;
}

/* HERO — word-by-word reveal on load. JS wraps each word in .word. */
.about-hero__lead .word {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.45em);
  transition:
    opacity 0.55s cubic-bezier(0.2, 0.8, 0.2, 1),
    transform 0.55s cubic-bezier(0.2, 0.8, 0.2, 1);
  transition-delay: var(--d, 0ms);
}

.about-hero__lead.is-revealed .word {
  opacity: 1;
  transform: none;
}

.about-hero__sub {
  opacity: 0;
  transform: translateY(10px);
  transition:
    opacity 0.6s cubic-bezier(0.2, 0.8, 0.2, 1),
    transform 0.6s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.about-hero__sub.is-revealed {
  opacity: 1;
  transform: none;
}

/* MANIFESTO — signature moment. "Integrate" gains an underline that
   draws across when scrolled into view, and the italic line warms up
   from muted to full text color. */
.about-manifesto__emphasis {
  position: relative;
  display: inline-block;
}

.about-manifesto__emphasis::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0.04em;
  height: 2px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 1.1s cubic-bezier(0.2, 0.8, 0.2, 1) 0.35s;
}

.about-manifesto.is-revealed .about-manifesto__emphasis::after {
  transform: scaleX(1);
}

.about-manifesto__line--alt {
  transition: color 0.9s cubic-bezier(0.2, 0.8, 0.2, 1) 0.25s;
}

.about-manifesto.is-revealed .about-manifesto__line--alt {
  color: var(--c-text);
}

/* TOOLKIT chips — staggered cascade on scroll-in + tactile hover. */
.about-chips li {
  opacity: 0;
  transform: translateY(8px);
  transition:
    opacity 0.45s cubic-bezier(0.2, 0.8, 0.2, 1),
    transform 0.45s cubic-bezier(0.2, 0.8, 0.2, 1),
    background 0.2s ease,
    box-shadow 0.2s ease;
  transition-delay: var(--d, 0ms);
  cursor: default;
}

.about-toolkit.is-revealed .about-chips li,
[data-reveal].is-revealed .about-chips li {
  opacity: 1;
  transform: translateY(0);
}

.about-chips li:hover {
  background: color-mix(in srgb, var(--c-text) 9%, transparent);
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--c-text) 22%, transparent),
    0 4px 12px -4px rgba(0, 0, 0, 0.25);
  transform: translateY(-2px);
  transition-delay: 0ms;
}

.about-chips--accent li:hover {
  background: color-mix(in srgb, var(--c-text) 16%, transparent);
}

@media (prefers-reduced-motion: reduce) {
  [data-reveal],
  .about-hero__lead .word,
  .about-hero__sub,
  .about-chips li {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .about-manifesto__emphasis::after {
    transform: scaleX(1);
    transition: none;
  }
  .about-manifesto__line--alt {
    color: var(--c-text);
    transition: none;
  }
}

/* ============================================================
   ABOUT — visual punctuation
   Editorial stats, process cards, portrait slot, and prior-work
   project tiles. Adds image/diagram rhythm to the text-heavy
   page without breaking the existing layout grammar.
   ============================================================ */

/* STATS — full-bleed editorial number row. Acts as visual
   punctuation between the hero and Section 01. */
.about-stats {
  grid-column: 1 / -1;
  padding: var(--s-300) var(--s-200) var(--s-300);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-200);
  border-top: 1px solid color-mix(in srgb, var(--c-text) 8%, transparent);
}

.about-stats__item {
  display: flex;
  flex-direction: column;
  gap: var(--s-100);
  position: relative;
}

/* Glance row — wide dt/dd block beneath the stats. Holds the inline
   detail that used to live in hover tooltips. Reads as an editorial
   caption to the three stat numbers above. */
.about-glance {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  column-gap: var(--s-300);
  row-gap: var(--s-100);
  padding: var(--s-200) var(--s-200) var(--s-400);
  margin: 0;
  border-bottom: 1px solid color-mix(in srgb, var(--c-text) 8%, transparent);
}

.about-glance__term {
  margin: 0;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-text-muted);
  align-self: baseline;
  padding-top: 5px;
}

.about-glance__def {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--c-text);
  letter-spacing: -0.005em;
  overflow-wrap: break-word;
}

@media (max-width: 720px) {
  .about-glance {
    grid-template-columns: 1fr;
    row-gap: var(--s-050);
    padding: var(--s-150) var(--s-150) var(--s-300);
  }
  .about-glance__term { padding-top: 0; }
  .about-glance__def { margin: 0 0 var(--s-100); }
}

.about-stats__num {
  font-family: var(--font-display, inherit);
  font-size: clamp(2.6rem, 6vw, 5rem);
  font-weight: 350;
  letter-spacing: -0.04em;
  line-height: 0.95;
  color: var(--c-text);
}

.about-stats__label {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-text-muted);
}

@media (max-width: 720px) {
  .about-stats { grid-template-columns: 1fr; }
}

/* PROCESS — Frame / Build / Operate as 3 visual cards.
   Replaces the plain pipeline dl in Section 01. */
.about-process {
  list-style: none;
  margin: var(--s-300) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-150);
}

.about-process__step {
  min-width: 0;
  padding: var(--s-200) var(--s-150);
  border-radius: 14px;
  background: color-mix(in srgb, var(--c-text) 4%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c-text) 10%, transparent);
  display: flex;
  flex-direction: column;
  gap: var(--s-100);
  transition: transform 0.35s cubic-bezier(0.2, 0.85, 0.3, 1),
              background 0.35s ease,
              box-shadow 0.35s ease;
}

@media (max-width: 1100px) {
  .about-process { grid-template-columns: 1fr; }
}

.about-process__step:hover {
  transform: translateY(-3px);
  background: color-mix(in srgb, var(--c-text) 7%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c-text) 18%, transparent),
              0 12px 28px -16px rgba(0, 0, 0, 0.45);
}

.about-process__head {
  display: flex;
  align-items: baseline;
  gap: var(--s-100);
  flex-wrap: wrap;
  min-width: 0;
}

.about-process__num {
  font-family: var(--font-display, inherit);
  font-size: 1.35rem;
  font-weight: 350;
  letter-spacing: -0.02em;
  color: var(--c-text-muted);
}

.about-process__title {
  font-size: 1.02rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--c-text);
  min-width: 0;
  overflow-wrap: break-word;
}

.about-process__body {
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--c-text-muted);
  min-width: 0;
  overflow-wrap: break-word;
  hyphens: auto;
}

/* PORTRAIT — square slot inside the Currently section's right column,
   above the meta list. Holds either an image or a stylized placeholder. */
.about-currently-visual {
  display: flex;
  flex-direction: column;
  gap: var(--s-250);
  align-items: center;
  justify-content: center;
  width: 100%;
  min-width: 0;
}

.about-portrait {
  width: 100%;
  max-width: 360px;
  aspect-ratio: 1;
  border-radius: 18px;
  background:
    radial-gradient(circle at 30% 30%,
      color-mix(in srgb, var(--c-text) 14%, transparent),
      color-mix(in srgb, var(--c-text) 4%, transparent) 65%);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c-text) 12%, transparent);
  display: grid;
  place-items: center;
  position: relative;
  overflow: hidden;
}

.about-portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.about-portrait__placeholder {
  font-family: var(--font-display, inherit);
  font-size: clamp(3rem, 7vw, 5rem);
  font-weight: 350;
  letter-spacing: -0.03em;
  color: color-mix(in srgb, var(--c-text) 55%, transparent);
}

/* PRIOR WORK tiles — image thumbnail + body, side-by-side per entry. */
.about-prior {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s-250);
}

.about-prior__item {
  display: grid;
  grid-template-columns: 140px minmax(0, 1fr);
  gap: var(--s-250);
  align-items: stretch;
  padding: var(--s-200);
  border-radius: 14px;
  background: color-mix(in srgb, var(--c-text) 3%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c-text) 8%, transparent);
  color: inherit;
  text-decoration: none;
  transition: transform 0.35s cubic-bezier(0.2, 0.85, 0.3, 1),
              background 0.35s ease,
              box-shadow 0.35s ease;
}

a.about-prior__item:hover {
  background: color-mix(in srgb, var(--c-text) 6%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c-text) 16%, transparent),
              0 12px 28px -16px rgba(0, 0, 0, 0.4);
  transform: translateY(-2px);
}

.about-prior__thumb {
  width: 140px;
  height: 140px;
  border-radius: 10px;
  overflow: hidden;
  background: color-mix(in srgb, var(--c-text) 8%, transparent);
  display: grid;
  place-items: center;
}

.about-prior__thumb img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
  padding: 8px;
  display: block;
}

.about-prior__thumb--fill img {
  object-fit: cover;
  padding: 0;
}

.about-prior__thumb--text {
  font-family: var(--font-display, inherit);
  font-size: 1.25rem;
  font-weight: 350;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: var(--c-text-muted);
  text-align: center;
  padding: var(--s-150);
}

.about-prior__body {
  display: flex;
  flex-direction: column;
  gap: var(--s-100);
  min-width: 0;
}

.about-prior__title {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--c-text);
  overflow-wrap: break-word;
}

.about-prior__date {
  margin: 0;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--c-text-muted);
}

.about-prior__desc {
  margin: var(--s-100) 0 0;
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--c-text-muted);
  overflow-wrap: break-word;
}

/* TIMELINE — vertical role-progression list (LinkedIn-style),
   used inside the Currently section to visualize Spring College
   promotions without burying them in prose. */
.about-timeline {
  margin: var(--s-300) 0 var(--s-200);
  padding: 0;
  list-style: none;
}

.about-timeline__header {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-text-muted);
  margin: 0 0 var(--s-150);
}

.about-timeline__item {
  position: relative;
  padding: 0 0 var(--s-250) var(--s-300);
  border-left: 2px solid color-mix(in srgb, var(--c-text) 10%, transparent);
}

.about-timeline__item:last-child {
  padding-bottom: 0;
  border-left-color: transparent;
}

.about-timeline__item::before {
  content: "";
  position: absolute;
  left: -8px;
  top: 4px;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--c-text) 30%, transparent);
  box-shadow: 0 0 0 4px var(--c-card-background);
}

.about-timeline__item--current::before {
  background: #48ea2d;
  box-shadow: 0 0 0 4px var(--c-card-background),
              0 0 10px rgba(72, 234, 45, 0.55);
  animation: about-pulse 2.4s ease-in-out infinite;
}

.about-timeline__title {
  margin: 0;
  font-size: 1.02rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--c-text);
}

.about-timeline__meta {
  margin: 6px 0 0;
  display: flex;
  gap: var(--s-100);
  align-items: center;
  flex-wrap: wrap;
}

.about-timeline__date {
  font-size: 12px;
  color: var(--c-text-muted);
  letter-spacing: 0.03em;
}

.about-timeline__duration {
  padding: 2px 8px;
  border-radius: 4px;
  background: color-mix(in srgb, var(--c-text) 8%, transparent);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--c-text-muted);
}

.about-timeline__location {
  font-size: 12px;
  color: var(--c-text-muted);
  opacity: 0.7;
}

/* CERTIFICATIONS — icon + body + arrow tile. Whole row clickable
   when the cert has a credential link. Mirrors the prior-work
   tile pattern for visual consistency. */
.about-certs {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s-100);
}

.about-cert {
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr) auto;
  gap: var(--s-200);
  align-items: center;
  padding: var(--s-150) var(--s-200);
  border-radius: 12px;
  background: color-mix(in srgb, var(--c-text) 3%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c-text) 8%, transparent);
  color: inherit;
  text-decoration: none;
  transition: transform 0.3s cubic-bezier(0.2, 0.85, 0.3, 1),
              background 0.3s ease,
              box-shadow 0.3s ease;
}

a.about-cert:hover {
  background: color-mix(in srgb, var(--c-text) 6%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c-text) 16%, transparent),
              0 8px 20px -12px rgba(0, 0, 0, 0.35);
  transform: translateY(-1px);
}

a.about-cert:hover .about-cert__arrow {
  transform: translate(2px, -2px);
  color: var(--c-text);
}

.about-cert__icon {
  width: 52px;
  height: 52px;
  border-radius: 10px;
  overflow: hidden;
  background: #ffffff;
  display: grid;
  place-items: center;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c-text) 6%, transparent);
}

.about-cert__icon img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.about-cert__body {
  min-width: 0;
}

.about-cert__title {
  margin: 0;
  font-size: 0.98rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--c-text);
  overflow-wrap: break-word;
  line-height: 1.3;
}

.about-cert__meta {
  margin: 4px 0 0;
  font-size: 12px;
  color: var(--c-text-muted);
  letter-spacing: 0.02em;
  overflow-wrap: break-word;
}

.about-cert__arrow {
  font-size: 13px;
  color: var(--c-text-muted);
  transition: transform 0.3s cubic-bezier(0.2, 0.85, 0.3, 1),
              color 0.3s ease;
  display: inline-block;
}

/* SCHOOL — full education card: logo + diploma headline + school + date.
   A single self-contained block; the diploma sits as the lead inside. */
.about-school {
  display: grid;
  grid-template-columns: 180px minmax(0, 1fr);
  gap: var(--s-300);
  align-items: center;
  margin-top: var(--s-300);
  padding: var(--s-300);
  border-radius: 18px;
  background: color-mix(in srgb, var(--c-text) 3%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c-text) 10%, transparent);
}

.about-school__icon {
  width: 180px;
  height: 110px;
  border-radius: 12px;
  overflow: hidden;
  background: #ffffff;
  display: grid;
  place-items: center;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c-text) 6%, transparent);
}

.about-school__icon img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 12px;
  display: block;
}

.about-school__text {
  display: flex;
  flex-direction: column;
  gap: var(--s-100);
  min-width: 0;
}

.about-school__diploma {
  margin: 0 0 var(--s-100);
  font-size: clamp(1.5rem, 2.4vw, 2.1rem);
  font-weight: 400;
  letter-spacing: -0.022em;
  line-height: 1.1;
  color: var(--c-text);
}

.about-school__name {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1.2;
  color: var(--c-text);
}

.about-school__date {
  margin: 0;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-text-muted);
}

@media (max-width: 900px) {
  .about-school {
    grid-template-columns: 1fr;
    gap: var(--s-200);
    padding: var(--s-250);
  }
  .about-school__icon {
    width: 140px;
    height: 84px;
  }
}

/* COURSEWORK — numbered syllabus-style list. Each module is a row
   with an index number and small-caps subject; hairline dividers
   between rows give it an academic transcript feel. */
.about-coursework {
  margin-top: var(--s-300);
  padding-top: var(--s-250);
  border-top: 1px solid color-mix(in srgb, var(--c-text) 12%, transparent);
}

.about-coursework__label {
  display: flex;
  align-items: baseline;
  gap: var(--s-100);
  margin: 0 0 var(--s-200);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--c-text-muted);
}

.about-coursework__count {
  color: color-mix(in srgb, var(--c-text-muted) 70%, transparent);
}

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

.about-coursework__item {
  display: grid;
  grid-template-columns: 36px 1fr;
  gap: var(--s-150);
  align-items: center;
  padding: var(--s-150) 0;
  border-bottom: 1px solid color-mix(in srgb, var(--c-text) 8%, transparent);
  transition: padding-left 0.25s cubic-bezier(0.2, 0.85, 0.3, 1),
              background 0.25s ease;
}

.about-coursework__item:first-child {
  border-top: 1px solid color-mix(in srgb, var(--c-text) 8%, transparent);
}

.about-coursework__item:hover {
  padding-left: var(--s-100);
  background: color-mix(in srgb, var(--c-text) 3%, transparent);
}

.about-coursework__num {
  font-family: var(--font-display, inherit);
  font-size: 0.95rem;
  font-weight: 400;
  letter-spacing: 0.02em;
  color: color-mix(in srgb, var(--c-text-muted) 75%, transparent);
  font-variant-numeric: tabular-nums;
}

.about-coursework__name {
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--c-text);
  line-height: 1.2;
}

@media (max-width: 700px) {
  .about-prior__item {
    grid-template-columns: 1fr;
  }
  .about-prior__thumb {
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
  }
}

/* ============================================================
   COMPASS TUTOR CARD — mock chat interface used in Section 07.
   Shows quick-action chips, a sample exchange, and the verified
   guard line at the bottom. Self-contained dark-surface card.
   ============================================================ */

.tutor-card {
  background: color-mix(in srgb, var(--c-text) 4%, transparent);
  border: 1px solid color-mix(in srgb, var(--c-text) 10%, transparent);
  border-radius: var(--site-border-radius);
  padding: var(--s-200);
  display: flex;
  flex-direction: column;
  gap: var(--s-200);
}

.tutor-card__header {
  display: flex;
  align-items: center;
  gap: var(--s-100);
  flex-wrap: wrap;
}

.tutor-card__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #7c5cfc;
  flex-shrink: 0;
  animation: about-pulse 2.4s ease-in-out infinite;
}

.tutor-card__name {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--c-text);
}

.tutor-card__scope {
  font-size: 11px;
  color: var(--c-text-muted);
  margin-left: auto;
  text-align: right;
  line-height: 1.35;
}

.tutor-card__chips {
  display: flex;
  gap: var(--s-050);
  flex-wrap: wrap;
}

.tutor-card__chip {
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.01em;
  padding: 5px 13px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--c-text) 15%, transparent);
  background: color-mix(in srgb, var(--c-text) 4%, transparent);
  color: var(--c-text);
  cursor: default;
  user-select: none;
}

.tutor-card__exchange {
  display: flex;
  flex-direction: column;
  gap: var(--s-100);
}

.tutor-card__msg {
  font-size: clamp(0.8rem, 0.95vw, 0.9rem);
  line-height: 1.55;
  padding: var(--s-100) var(--s-150);
  max-width: 86%;
}

.tutor-card__msg--user {
  background: rgba(124, 92, 252, 0.1);
  border: 1px solid rgba(124, 92, 252, 0.2);
  color: var(--c-text);
  align-self: flex-end;
  border-radius: 12px 12px 3px 12px;
}

.tutor-card__msg--ai {
  background: color-mix(in srgb, var(--c-text) 5%, transparent);
  border: 1px solid color-mix(in srgb, var(--c-text) 8%, transparent);
  color: var(--c-text);
  align-self: flex-start;
  border-radius: 3px 12px 12px 12px;
}

.tutor-card__guard {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 11px;
  color: var(--c-text-muted);
  padding-top: var(--s-100);
  border-top: 1px solid color-mix(in srgb, var(--c-text) 8%, transparent);
}

.tutor-card__guard-icon {
  color: #22c55e;
  font-weight: 600;
  font-style: normal;
}

/* ============================================================
   SKILL MAP STATES — four-state legend used in Section 08.
   Locked / Available / In Progress / Mastered shown as a
   compact stacked list with a colour-coded dot per state.
   ============================================================ */

.skill-map-states {
  display: flex;
  flex-direction: column;
  gap: 0;
  margin-top: var(--s-250);
  border: 1px solid color-mix(in srgb, var(--c-text) 8%, transparent);
  border-radius: 10px;
  overflow: hidden;
}

.skill-state {
  display: grid;
  grid-template-columns: 10px 1fr auto;
  align-items: center;
  gap: var(--s-100);
  padding: var(--s-100) var(--s-150);
  border-bottom: 1px solid color-mix(in srgb, var(--c-text) 6%, transparent);
  font-size: clamp(0.78rem, 0.9vw, 0.88rem);
}

.skill-state:last-child { border-bottom: none; }

.skill-state__dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}

.skill-state__label {
  font-weight: 500;
  color: var(--c-text);
}

.skill-state__desc {
  font-size: 11px;
  color: var(--c-text-muted);
  text-align: right;
}

.skill-state--locked    .skill-state__dot { background: color-mix(in srgb, var(--c-text) 22%, transparent); }
.skill-state--available .skill-state__dot { background: #3b82f6; }
.skill-state--progress  .skill-state__dot { background: #f59e0b; }
.skill-state--mastered  .skill-state__dot { background: #22c55e; }

/* ============================================================
   LEARNING HUB LAYERS — four stacked AI output cards used in
   Section 10. Each row is number / title+body. A thin rule
   divides each layer. Role-fit block sits at the bottom of
   the left column.
   ============================================================ */

.learning-hub-layers {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.hub-layer {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--s-150);
  padding: var(--s-200) 0;
  border-bottom: 1px solid color-mix(in srgb, var(--c-text) 8%, transparent);
  align-items: baseline;
}

.hub-layer:first-child { padding-top: 0; }
.hub-layer:last-child  { border-bottom: none; }

.hub-layer__num {
  font-size: clamp(1.1rem, 1.3vw, 1.26rem);
  font-weight: 400;
  letter-spacing: 0.005em;
  color: var(--c-text-muted);
  font-variant-numeric: tabular-nums;
}

.hub-layer__title {
  font-size: clamp(1.1rem, 1.3vw, 1.26rem);
  font-weight: 500;
  letter-spacing: 0.005em;
  color: var(--c-text);
  margin: 0 0 var(--s-050);
  line-height: 1.5;
}

.hub-layer__body {
  font-size: clamp(1.1rem, 1.3vw, 1.26rem);
  line-height: 1.55;
  font-weight: 400;
  letter-spacing: 0.005em;
  color: var(--c-text-muted);
  margin: 0;
}

.hub-layer__feature {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-top: var(--s-050);
  font-size: 11px;
  font-weight: 500;
  color: rgba(124, 92, 252, 0.8);
  letter-spacing: 0.01em;
}

.hub-role-fit {
  margin-top: var(--s-300);
  padding: var(--s-200);
  background: color-mix(in srgb, var(--c-text) 4%, transparent);
  border: 1px solid color-mix(in srgb, var(--c-text) 9%, transparent);
  border-radius: 12px;
}

.hub-role-fit__title {
  font-size: clamp(0.88rem, 1.1vw, 1rem);
  font-weight: 600;
  color: var(--c-text);
  margin: 0 0 var(--s-050);
}

.hub-role-fit__roles {
  display: flex;
  flex-direction: column;
  gap: var(--s-050);
  margin-top: var(--s-100);
}

.hub-role-fit__role {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: var(--s-100);
  font-size: 12px;
}

.hub-role-fit__role-name {
  color: var(--c-text);
  font-weight: 500;
}

.hub-role-fit__bar-wrap {
  display: flex;
  align-items: center;
  gap: 7px;
}

.hub-role-fit__bar {
  width: 80px;
  height: 4px;
  background: color-mix(in srgb, var(--c-text) 10%, transparent);
  border-radius: 999px;
  overflow: hidden;
}

.hub-role-fit__fill {
  height: 100%;
  border-radius: 999px;
  background: #7c5cfc;
}

.hub-role-fit__pct {
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--c-text-muted);
  min-width: 3ch;
  text-align: right;
}

/* ============================================================
   PATHWAY ECOSYSTEM — tiered course track visual (Section 12).
   Card with a colored left-stripe per tier, matching hub-layer
   / hub-role-fit design language.
   ============================================================ */

.pathway-track {
  border: 1px solid color-mix(in srgb, var(--c-text) 9%, transparent);
  border-radius: 12px;
  overflow: hidden;
  background: color-mix(in srgb, var(--c-text) 2%, transparent);
}

.pathway-track__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--s-150) var(--s-200);
  background: color-mix(in srgb, var(--c-text) 5%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--c-text) 8%, transparent);
}

.pathway-track__domain {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--c-text);
}

.pathway-track__tag {
  font-size: 10px;
  color: var(--c-text-muted);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* Two-column: 3 px coloured stripe | content body */
.pathway-tier {
  display: grid;
  grid-template-columns: 3px 1fr;
  border-bottom: 1px solid color-mix(in srgb, var(--c-text) 6%, transparent);
}

.pathway-tier:last-child { border-bottom: none; }

.pathway-tier__stripe { /* filled by modifier below */ }
.pathway-tier--foundation   .pathway-tier__stripe { background: #6b7280; }
.pathway-tier--practitioner .pathway-tier__stripe { background: #3b82f6; }
.pathway-tier--specialist   .pathway-tier__stripe { background: #7c5cfc; }

.pathway-tier__body { padding: var(--s-200) var(--s-200) var(--s-250); }

/* Inline row: muted counter · coloured level label */
.pathway-tier__meta {
  display: flex;
  align-items: center;
  gap: var(--s-100);
  margin-bottom: var(--s-100);
}

.pathway-tier__num {
  font-size: 11px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--c-text-muted);
}

.pathway-tier__level {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.pathway-tier--foundation   .pathway-tier__level { color: #6b7280; }
.pathway-tier--practitioner .pathway-tier__level { color: #3b82f6; }
.pathway-tier--specialist   .pathway-tier__level { color: #7c5cfc; }

.pathway-tier__title {
  font-size: clamp(0.9rem, 1.1vw, 1rem);
  font-weight: 600;
  margin: 0 0 var(--s-100);
  color: var(--c-text);
  letter-spacing: -0.01em;
}

.pathway-tier__desc {
  font-size: clamp(0.82rem, 0.95vw, 0.9rem);
  color: var(--c-text-muted);
  margin: 0;
  line-height: 1.65;
}

/* Separator row between tiers */
.pathway-unlock {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: var(--s-100) var(--s-200);
  font-size: 11px;
  color: var(--c-text-muted);
  letter-spacing: 0.06em;
  border-bottom: 1px solid color-mix(in srgb, var(--c-text) 6%, transparent);
  background: color-mix(in srgb, var(--c-text) 3%, transparent);
}

/* ============================================================
   WRITING — Apple Newsroom-style article grid.
   3-up on desktop, 2-up on tablet, 1-up on mobile. Each card is
   media block + category kicker + headline + date. No card
   chrome (borders/shadows) — Apple's grid leans on whitespace.
   ============================================================ */
.newsroom {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  column-gap: var(--s-200);
  row-gap: var(--s-400);
  max-width: 1400px;
  margin: 0 auto;
  padding: var(--s-100) var(--s-200) calc(var(--nav-height) + var(--s-400));
}

.news-card { display: flex; flex-direction: column; }

.news-card__link {
  display: flex;
  flex-direction: column;
  gap: var(--s-100);
  text-decoration: none;
  color: inherit;
}

.news-card__link:hover { opacity: 1; }
.news-card__link:hover .news-card__media > * { transform: scale(1.025); }
.news-card__link:hover .news-card__title {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}

.news-card__media {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: var(--site-border-radius);
  overflow: hidden;
  background: var(--c-card-background);
  margin-bottom: var(--s-050);
}

.news-card__media > img,
.news-card__media > video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.5s ease;
}

.news-card__media--contain > img,
.news-card__media--contain > video {
  object-fit: contain;
}

.news-card__placeholder {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 80% at 30% 20%, rgba(255,255,255,0.06), rgba(255,255,255,0) 60%),
    var(--c-card-background);
  transition: transform 0.5s ease;
}

:root.theme-light .news-card__placeholder {
  background:
    radial-gradient(120% 80% at 30% 20%, rgba(0,0,0,0.04), rgba(0,0,0,0) 60%),
    #efefef;
}

.news-card__tag {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--c-text-muted);
}

.news-card__title {
  margin: 0;
  font-size: clamp(1.05rem, 1.55vw, 1.35rem);
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: -0.005em;
  color: var(--c-text);
}

.news-card__date {
  margin: 0;
  font-size: 12px;
  letter-spacing: 0.02em;
  color: var(--c-text-muted);
}

@media (max-width: 1024px) {
  .newsroom { grid-template-columns: repeat(2, 1fr); row-gap: var(--s-300); }
}

@media (max-width: 600px) {
  .newsroom {
    grid-template-columns: 1fr;
    row-gap: var(--s-200);
    padding: var(--s-100) var(--s-100) calc(var(--nav-height) + var(--s-300));
  }
}

/* ============================================================
   WRITING ARTICLE — long-form editorial reading layout.
   Narrow measure (~720px), generous line-height, serif title
   as a single editorial moment; sans-serif everywhere else to
   stay continuous with the rest of the site.
   ============================================================ */
.article {
  max-width: 792px;
  margin: 0 auto;
  padding: 8vh var(--s-200) calc(var(--nav-height) + var(--s-400));
}

.article__header {
  border-bottom: 1px solid color-mix(in srgb, var(--c-text) 14%, transparent);
  padding-bottom: var(--s-200);
  margin-bottom: var(--s-300);
}

.article__meta {
  font-size: 0.72rem;
  color: var(--c-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-bottom: var(--s-150);
}

.article__title {
  font-family: "Georgia", "Times New Roman", serif;
  font-size: clamp(1.9rem, 4vw, 2.8rem);
  font-weight: 400;
  line-height: 1.14;
  letter-spacing: -0.012em;
  color: var(--c-text);
  margin: 0;
}

.article__deck {
  font-size: 1.1rem;
  line-height: 1.55;
  color: var(--c-text);
  margin: var(--s-200) 0 0;
  font-weight: 400;
  letter-spacing: 0;
}

.article__body {
  font-size: 1.02rem;
  line-height: 1.72;
  letter-spacing: 0.01em;
  color: var(--c-text);
}

.article__body p {
  margin: 0 0 var(--s-150);
}

.article__body h2 {
  font-family: "Georgia", "Times New Roman", serif;
  font-size: 1.4rem;
  font-weight: 400;
  line-height: 1.25;
  letter-spacing: -0.005em;
  color: var(--c-text);
  margin: var(--s-400) 0 var(--s-100);
}

.article__body h3 {
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--c-text);
  margin: var(--s-300) 0 var(--s-100);
}

.article__body strong { font-weight: 600; color: var(--c-text); }
.article__body em { font-style: italic; }

.article__body blockquote {
  margin: var(--s-300) 0;
  padding-left: var(--s-150);
  border-left: 2px solid color-mix(in srgb, var(--c-text) 30%, transparent);
  font-style: italic;
  color: var(--c-text);
}

.article__body ul,
.article__body ol {
  margin: 0 0 var(--s-150);
  padding-left: 1.4rem;
}

.article__body li { margin-bottom: 0.45rem; }

.article__footer {
  margin-top: var(--s-500);
  padding-top: var(--s-200);
  border-top: 1px solid color-mix(in srgb, var(--c-text) 14%, transparent);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s-150);
  font-size: 0.85rem;
  color: var(--c-text-muted);
  letter-spacing: 0.02em;
}

.article__back-link {
  color: var(--c-text-muted);
  text-decoration: none;
  transition: color 0.2s ease;
}

.article__back-link:hover {
  color: var(--c-text);
  opacity: 1;
}

/* FIGURE — images sit inside the 720px reading column. Pair variant
   for portrait posters (2-up), stack variant for landscape captures. */
.article__figure {
  margin: var(--s-300) 0;
}

.article__figure img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: var(--site-border-radius);
  background: var(--c-card-background);
  box-shadow: 0 1px 0 color-mix(in srgb, var(--c-text) 6%, transparent);
}

.article__figure--pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-100);
}

.article__figure--stack {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-100);
}

.article__figure figcaption {
  grid-column: 1 / -1;
  margin-top: var(--s-050);
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--c-text-muted);
  letter-spacing: 0.01em;
  font-style: italic;
}

@media (max-width: 600px) {
  .article {
    padding: var(--s-300) var(--s-150) calc(var(--nav-height) + var(--s-300));
  }
  .article__body { font-size: 1rem; }
  .article__footer { flex-direction: column; align-items: flex-start; }
  .article__figure--pair { grid-template-columns: 1fr; }
}

/* ============================================================
   CONTACT MODAL — popup with direct contact info + form.
   Triggered by the hero CTA. Editorial card language;
   form fields cascade in with subtle motion.
   ============================================================ */
.contact-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s-200);
  background: color-mix(in srgb, var(--c-background) 72%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.35s ease;
}

.contact-overlay.is-open {
  opacity: 1;
  pointer-events: auto;
}

.contact-modal {
  position: relative;
  width: 100%;
  max-width: 920px;
  max-height: calc(100vh - 4rem);
  overflow-y: auto;
  padding: var(--s-400);
  background: color-mix(in srgb, var(--c-text) 5%, var(--c-background));
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--c-text) 12%, transparent),
    0 30px 60px -24px rgba(0, 0, 0, 0.5);
  border-radius: var(--site-border-radius);
  transform: translateY(20px) scale(0.97);
  opacity: 0;
  transition:
    transform 0.5s cubic-bezier(0.2, 0.85, 0.3, 1),
    opacity 0.35s ease;
}

.contact-overlay.is-open .contact-modal {
  transform: translateY(0) scale(1);
  opacity: 1;
}

.contact-modal__close {
  position: absolute;
  top: var(--s-200);
  right: var(--s-200);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: none;
  border-radius: 999px;
  background: transparent;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c-text) 14%, transparent);
  color: var(--c-text-muted);
  cursor: pointer;
  transition:
    background 0.25s ease,
    color 0.25s ease,
    transform 0.3s cubic-bezier(0.2, 0.85, 0.3, 1);
  z-index: 2;
}

.contact-modal__close:hover {
  background: color-mix(in srgb, var(--c-text) 10%, transparent);
  color: var(--c-text);
  transform: rotate(90deg);
}

.contact-modal__close svg {
  width: 14px;
  height: 14px;
}

.contact-modal__header {
  display: flex;
  flex-direction: column;
  gap: var(--s-150);
  margin-bottom: var(--s-300);
  padding-right: var(--s-300);
}

.contact-modal__status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px 6px 10px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--c-text) 6%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c-text) 12%, transparent);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--c-text-muted);
  align-self: flex-start;
}

.contact-modal__status::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #48ea2d;
  box-shadow: 0 0 8px rgba(72, 234, 45, 0.55);
  animation: about-pulse 2.4s ease-in-out infinite;
}

.contact-modal__title {
  margin: 0;
  font-family: var(--font-display, inherit);
  font-size: clamp(1.8rem, 3.6vw, 2.6rem);
  font-weight: 350;
  letter-spacing: -0.028em;
  line-height: 1.05;
  color: var(--c-text);
}

.contact-modal__grid {
  display: grid;
  grid-template-columns: 40fr 60fr;
  gap: var(--s-400);
  align-items: start;
}

@media (max-width: 720px) {
  .contact-modal { padding: var(--s-300); }
  .contact-modal__grid { grid-template-columns: 1fr; gap: var(--s-300); }
  .contact-modal__header { padding-right: var(--s-200); }
}

/* Left: direct contact info */
.contact-modal__info {
  display: flex;
  flex-direction: column;
  gap: var(--s-200);
  padding-top: var(--s-100);
}

.contact-modal__info-row {
  display: flex;
  flex-direction: column;
  gap: 6px;
  opacity: 0;
  transform: translateY(8px);
  transition:
    opacity 0.45s ease,
    transform 0.45s cubic-bezier(0.2, 0.85, 0.3, 1);
  transition-delay: var(--d, 0ms);
}

.contact-overlay.is-open .contact-modal__info-row {
  opacity: 1;
  transform: translateY(0);
}

.contact-modal__info-label {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-text-muted);
}

.contact-modal__info-value {
  font-size: 0.98rem;
  color: var(--c-text);
  letter-spacing: -0.005em;
}

.contact-modal__info-value a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, var(--c-text) 20%, transparent);
  transition: border-color 0.25s ease;
}

.contact-modal__info-value a:hover {
  border-color: var(--c-text);
}

/* Right: form */
.contact-modal__form {
  display: flex;
  flex-direction: column;
  gap: var(--s-150);
}

.contact-modal__field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  opacity: 0;
  transform: translateY(8px);
  transition:
    opacity 0.45s ease,
    transform 0.45s cubic-bezier(0.2, 0.85, 0.3, 1);
  transition-delay: var(--d, 0ms);
}

.contact-overlay.is-open .contact-modal__field {
  opacity: 1;
  transform: translateY(0);
}

.contact-modal__field-label {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-text-muted);
}

.contact-modal__optional {
  text-transform: none;
  letter-spacing: 0.02em;
  opacity: 0.7;
}

.contact-modal__input,
.contact-modal__textarea {
  width: 100%;
  padding: 11px 14px;
  background: color-mix(in srgb, var(--c-text) 3%, transparent);
  border: none;
  border-radius: 8px;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c-text) 12%, transparent);
  color: var(--c-text);
  font-family: inherit;
  font-size: 0.95rem;
  letter-spacing: -0.005em;
  transition: box-shadow 0.25s ease, background 0.25s ease;
}

.contact-modal__input:focus,
.contact-modal__textarea:focus {
  outline: none;
  background: color-mix(in srgb, var(--c-text) 6%, transparent);
  box-shadow: inset 0 0 0 1.5px var(--c-text);
}

.contact-modal__textarea {
  resize: vertical;
  min-height: 110px;
  font-family: inherit;
  line-height: 1.5;
}

.contact-modal__submit {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-100);
  margin-top: var(--s-100);
  padding: 12px 24px;
  border: none;
  background-color: transparent;
  color: var(--c-text);
  box-shadow: inset 0 0 0 1.5px var(--c-text);
  border-radius: 12px;
  font-family: inherit;
  font-size: 0.95rem;
  font-weight: 500;
  letter-spacing: -0.005em;
  cursor: pointer;
  align-self: flex-start;
  transition:
    background-color 1s ease,
    color 1s ease,
    transform 0.3s cubic-bezier(0.2, 0.85, 0.3, 1);
}

.contact-modal__submit:hover {
  background-color: var(--c-text);
  color: var(--c-background);
  transform: translateY(-2px);
}

.contact-modal__submit-arrow {
  display: inline-block;
  transition: transform 0.3s cubic-bezier(0.2, 0.85, 0.3, 1);
}

.contact-modal__submit:hover .contact-modal__submit-arrow {
  transform: translate(4px, -4px);
}

.contact-modal__submit:disabled,
.contact-modal__submit.is-loading {
  cursor: progress;
  opacity: 0.7;
}

.contact-modal__submit.is-loading .contact-modal__submit-arrow {
  animation: contact-submit-spin 1s linear infinite;
}

@keyframes contact-submit-spin {
  to { transform: rotate(360deg); }
}

.contact-modal__error {
  margin: 0;
  padding: 10px 14px;
  border-radius: 8px;
  background: color-mix(in srgb, #f87171 14%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, #f87171 30%, transparent);
  font-size: 0.88rem;
  line-height: 1.45;
  color: color-mix(in srgb, #f87171 80%, var(--c-text));
  letter-spacing: -0.005em;
}

/* Success state */
.contact-modal__success {
  display: none;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: var(--s-400) 0 var(--s-300);
  gap: var(--s-200);
}

.contact-modal.is-success .contact-modal__header,
.contact-modal.is-success .contact-modal__grid {
  display: none;
}

.contact-modal.is-success .contact-modal__success {
  display: flex;
  animation: contact-success-in 0.6s cubic-bezier(0.2, 0.85, 0.3, 1);
}

@keyframes contact-success-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

.contact-modal__success-icon {
  width: 56px;
  height: 56px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: color-mix(in srgb, #48ea2d 14%, transparent);
  color: #48ea2d;
  font-size: 26px;
  box-shadow:
    0 0 0 6px color-mix(in srgb, #48ea2d 8%, transparent),
    0 0 20px color-mix(in srgb, #48ea2d 25%, transparent);
}

.contact-modal__success-title {
  margin: 0;
  font-family: var(--font-display, inherit);
  font-size: clamp(1.5rem, 3vw, 2rem);
  font-weight: 350;
  letter-spacing: -0.025em;
  color: var(--c-text);
}

.contact-modal__success-body {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--c-text-muted);
}

@media (prefers-reduced-motion: reduce) {
  .contact-modal,
  .contact-modal__info-row,
  .contact-modal__field { transition: none; }
  .contact-modal.is-success .contact-modal__success { animation: none; }
}

/* ============================================================
   WIP OVERLAY — "Coming soon" modal for unfinished case studies.
   Built on the site's editorial card language: soft text-mix
   surface, hairline inset border, pulsing live status dot.
   ============================================================ */
.wip-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s-200);
  background: color-mix(in srgb, var(--c-background) 70%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}

.wip-overlay.is-open {
  opacity: 1;
  pointer-events: auto;
}

.wip-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--s-200);
  padding: var(--s-400);
  background: color-mix(in srgb, var(--c-text) 5%, var(--c-background));
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--c-text) 12%, transparent),
    0 30px 60px -24px rgba(0, 0, 0, 0.5);
  border-radius: var(--site-border-radius);
  max-width: 460px;
  width: 100%;
  transform: translateY(12px);
  transition:
    transform 0.4s cubic-bezier(0.2, 0.85, 0.3, 1),
    opacity 0.3s ease;
}

.wip-overlay.is-open .wip-card {
  transform: translateY(0);
}

/* Status pill — same pattern as the Now badge / hero CTA dot.
   Reinforces "this is live, just in progress". */
.wip-card__tag {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px 6px 10px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--c-text) 6%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c-text) 12%, transparent);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--c-text-muted);
  align-self: flex-start;
}

.wip-card__tag::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #48ea2d;
  box-shadow: 0 0 8px rgba(72, 234, 45, 0.55);
  animation: about-pulse 2.4s ease-in-out infinite;
}

.wip-card__title {
  margin: 0;
  font-family: var(--font-display, inherit);
  font-size: clamp(2rem, 4.4vw, 2.8rem);
  font-weight: 350;
  letter-spacing: -0.028em;
  line-height: 1.05;
  color: var(--c-text);
}

.wip-card__body {
  margin: 0;
  max-width: 38ch;
  font-size: 0.98rem;
  line-height: 1.55;
  color: var(--c-text-muted);
  letter-spacing: -0.005em;
}

.wip-card__close {
  position: absolute;
  top: var(--s-200);
  right: var(--s-200);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: none;
  border-radius: 999px;
  background: transparent;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c-text) 14%, transparent);
  color: var(--c-text-muted);
  cursor: pointer;
  transition:
    background 0.25s ease,
    color 0.25s ease,
    transform 0.25s cubic-bezier(0.2, 0.85, 0.3, 1);
}

.wip-card__close:hover {
  background: color-mix(in srgb, var(--c-text) 10%, transparent);
  color: var(--c-text);
  transform: rotate(90deg);
}

.wip-card__close svg {
  width: 14px;
  height: 14px;
}

/* ============================================================
   RESPONSIVE DESIGN — Unified breakpoints

   Architecture:
   • Desktop (> 768px)  — body { zoom: 0.8 } stays on; all
     sizes were designed against this 80 % visual scale.
   • Tablet / mobile (≤ 768px) — zoom removed; content renders
     at 100 % native scale, which is correct for touch devices.
     clamp() values scale naturally; the few that are too large
     at full scale get explicit overrides below.

   Breakpoints:
     1024px  tablet landscape
      768px  tablet portrait  ← zoom turned off here
      600px  mobile
      480px  small phone
   ============================================================ */

/* ── 1024px — tablet landscape ────────────────────────────── */
@media (max-width: 1024px) {
  .intro           { min-height: 46vh; }
  .project__header { min-height: 42vh; }
}

/* ── 768px — tablet portrait; zoom normalised ─────────────── */
@media (max-width: 768px) {

  /* GLOBAL: disable desktop-only visual zoom.
     body { zoom: 0.8 } was set to preview at 80 % on a laptop.
     On touch devices every pixel should be a real pixel. */
  body { zoom: 1; }

  /* ---- Index ---- */
  .intro {
    min-height: 38vh;
    padding: var(--s-200) var(--s-150);
  }

  /* ---- About hero ---- */
  /* 440px hardcoded min-width overflows every phone and most tablets */
  .about-hero__cta {
    min-width: 0;
    width: 100%;
    max-width: 520px;
    min-height: 160px;
    padding: var(--s-250) var(--s-300);
  }

  /* Hero lead: recalibrated clamp for 100 % scale */
  .about-hero__lead {
    font-size: clamp(2rem, 5.5vw, 3.8rem);
  }

  /* ---- Project pages ---- */
  .project__header {
    min-height: 34vh;
    padding: var(--s-200) var(--s-150);
  }

  /* The 800px rule stacks project-text but keeps ~8rem top padding —
     at zoom:1 that is 104px. Also some sections set grid-template-
     columns inline (e.g. "60fr 40fr") which the 800px rule silently
     ignores. !important fixes both. */
  .project-text {
    grid-template-columns: 1fr !important;
    padding: var(--s-400) var(--s-200) var(--s-300);
    gap: var(--s-300);
  }

  /* Flip modifier: restore natural reading order */
  .project-text--flip .project-text__left,
  .project-text--flip .project-text__right {
    order: unset;
  }

  /* Approach: reduce the 7+ rem top padding the desktop rule sets */
  .approach {
    padding: var(--s-400) var(--s-200) var(--s-300);
  }

  /* Proof layer: tighter inline padding */
  .proof-layer {
    padding: var(--s-400) var(--s-200);
  }

  /* Overlap blocks: negative margin creates overlap effect on desktop;
     reset at tablet so they don't crash into content above */
  .project-block--overlap {
    margin-top: 0;
  }

  /* Slide embeds (brand-overview banners): the inner pages are fixed
     desktop compositions that clip badly at narrow widths. Render the
     iframe at a fixed desktop width and let script.js scale it down to
     the wrapper — same artwork, proportionally smaller. 518.57px =
     1100px x (9.9 / 21), matching the wrapper's aspect ratio. */
  .slide-embed > iframe {
    width: 1100px;
    height: 518.57px;
    transform-origin: top left;
  }
}

/* ── 600px — mobile ────────────────────────────────────────── */
@media (max-width: 600px) {

  /* ---- Index: mobile-only intro format ---- */
  .wordmark__desktop { display: none; }
  .wordmark__mobile  { display: inline; }

  /* Shrink the description so the wordmark reads as the dominant line. */
  .tagline {
    font-size: calc(clamp(1.08rem, 3.24vw, 1.35rem) - var(--desc-shrink));
  }

  /* ---- Index ---- */
  .intro {
    padding: var(--s-150) var(--s-100);
  }

  /* Atelier card: grid-row: span 2 is meaningless in 1-col grid.
     Inline style requires !important to override. */
  .card--accent {
    grid-row: auto !important;
  }

  /* ---- About ---- */
  .about-hero {
    padding: var(--s-200) var(--s-100);
  }

  .about-hero__lead {
    font-size: clamp(1.6rem, 8vw, 2.4rem);
  }

  .about-hero__sub {
    font-size: clamp(0.9rem, 3.8vw, 1.1rem);
    margin-top: var(--s-150);
  }

  /* Stats: single column below tablet */
  .about-stats {
    grid-template-columns: 1fr;
  }

  /* Stat numbers: allow bigger vw scaling on small screens */
  .about-stats__num {
    font-size: clamp(2rem, 11vw, 3.5rem);
  }

  /* Contact channels / card */
  .about-contact__channels {
    grid-template-columns: 1fr;
  }

  .about-contact__card {
    padding: var(--s-200) var(--s-150);
  }

  /* ---- Project header ----
     Shrink the subtitle (meta) under the project title by 4px on mobile,
     across all project pages. Desktop untouched. */
  .project__meta {
    font-size: calc(clamp(1.08rem, 3.24vw, 1.35rem) - 4px);
  }

  /* ---- Project text ----
     Mobile type scale. The original mobile block shrank only the lead,
     section-title and body — leaving the subhead, subsection-title,
     pipeline lists and accordion body at desktop size, so they floated
     ABOVE the reduced body and even the section title. These rules
     complete the scale into one clean descending hierarchy:
       lead › section-title › subsection-title › body = subhead = pipeline. */
  .project-text {
    padding: var(--s-200);
    gap: var(--s-200);
  }

  .project-text__lead {
    font-size: clamp(1.5rem, 7vw, 2.2rem);
  }

  /* Section heading ("01 Overview") — clearly leads its section, with a
     tighter top gap so it groups with the content it introduces rather
     than floating in an 80px void above it. */
  .project-text__section-title {
    font-size: clamp(1.2rem, 5.2vw, 1.5rem);
    margin: var(--s-250) 0 var(--s-150);
  }

  /* Subsection heading (H4) — sits above body, kept bold + full-colour. */
  .project-text__subsection-title {
    font-size: clamp(1rem, 4.3vw, 1.12rem);
    margin: var(--s-200) 0 var(--s-050);
  }

  /* Body tier — body copy, intro subhead, pipeline lists and accordion
     body all share one size so supporting text never outweighs headings. */
  .project-text__subhead,
  .project-text__body p,
  .project-text__body li,
  .project-text__pipeline dt,
  .project-text__pipeline dd,
  .approach-item__body p {
    font-size: clamp(0.9rem, 3.9vw, 1rem);
    line-height: 1.55;
  }

  /* Approach: tighter padding (this block is later in the file,
     so it naturally overrides the earlier 600px rule) */
  .approach {
    padding: var(--s-250) var(--s-100);
  }

  .approach__title {
    font-size: clamp(1.25rem, 5.5vw, 1.7rem);
  }

  .approach-item__head {
    padding: var(--s-100) var(--s-150);
    font-size: clamp(0.95rem, 4vw, 1.15rem);
  }

  .approach-item__body {
    padding: 0 var(--s-150) var(--s-150);
  }

  /* Proof layer */
  .proof-layer {
    padding: var(--s-250) var(--s-100);
    margin: var(--s-200) 0;
  }

  .proof-layer__body {
    font-size: clamp(1.2rem, 4.5vw, 1.65rem);
    margin: var(--s-200) 0;
  }

  /* Project grid: stacked media blocks need a readable seam between
     them — 8px made consecutive images blur into one block, leaving
     no sense of where a section starts or ends. */
  .project-grid {
    gap: var(--s-100);
  }

  /* Chapter sections: extra breathing room above the existing hairline
     so each numbered section announces itself in a single column. */
  .project-text--chapter {
    margin-top: var(--s-200);
  }

  /* ---- Writing ---- */
  .news-card__title {
    font-size: clamp(0.95rem, 4.2vw, 1.2rem);
  }

  /* ---- Article long-form ---- */
  .article {
    padding-top: 5vh;
    padding-inline: var(--s-100);
  }

  /* ---- Contact modal ---- */
  .contact-overlay {
    padding: var(--s-100);
  }

  .contact-modal {
    padding: var(--s-200);
    border-radius: var(--site-border-radius);
  }

  .contact-modal__close {
    top: var(--s-100);
    right: var(--s-100);
  }

  /* ---- Project pages ---- */

  /* Force 40/60 split blocks (inline grid-column/aspect-ratio) to fill width */
  .project-block--40,
  .project-block--60 {
    grid-column: 1 !important;
    aspect-ratio: 4 / 3 !important;
  }

  /* Ensure project-block elements inside text sections are full-width */
  .project-text .project-block {
    width: 100%;
  }

  /* Fix spacing: trailing body margin should be smaller than the grid gap
     between stacked columns, so inter-section gaps feel wider than
     inter-paragraph gaps */
  .project-text__body {
    margin-bottom: var(--s-100);
  }

  /* Tighten section title top margin accordingly */
  .project-text__section-title {
    margin-top: var(--s-150);
  }

  /* Stack pipeline dt/dd: title on top, description below */
  .project-text__pipeline {
    grid-template-columns: 1fr;
  }

  /* ── CompassStu — mobile type & spacing pass ─────────────────
     Scoped to .page--compassstu so it can't leak to ie100/about,
     which share the .project-text* system. Desktop is untouched
     (this whole block lives inside max-width: 600px).

     Why: desktop sizes were tuned for body{zoom:0.8}; mobile resets
     to zoom:1, and the @600 query above re-tuned only some roles —
     leaving the tagline/pipeline/cards LARGER than the section
     heading and the tutor/skill micro-text SMALLER than body. This
     restores one clean descending scale:
       thesis > heading > sub-heads/card-titles > body≈tagline≈pipeline > micro-labels */

  /* Tier 1 — section statement */
  .page--compassstu .project-text__thesis {
    font-size: clamp(1.4rem, 6vw, 1.85rem);
    margin-bottom: var(--s-150);
  }

  /* Tier 2 — section heading (num + label inherit this size) */
  .page--compassstu .project-text__section-title {
    font-size: clamp(1.18rem, 5vw, 1.5rem);
    margin: var(--s-200) 0 var(--s-150);
  }

  /* Tier 4 — closing kicker: was bigger than the heading */
  .page--compassstu .project-text__tagline {
    font-size: clamp(0.98rem, 4vw, 1.12rem);
    padding-top: var(--s-150);
  }

  /* Tier 4 — pipeline / compare lists: drop to body level, tighten hairline */
  .page--compassstu .project-text__pipeline,
  .page--compassstu .project-text__compare {
    padding-top: var(--s-200);
    margin-top: var(--s-200);
  }
  .page--compassstu .project-text__pipeline dt,
  .page--compassstu .project-text__pipeline dd,
  .page--compassstu .project-text__compare dt,
  .page--compassstu .project-text__compare dd {
    font-size: clamp(0.92rem, 3.9vw, 1.02rem);
  }

  /* Stack the compare list like the pipeline (label on top, answer below)
     instead of a cramped max-content/1fr split in a single narrow column. */
  .page--compassstu .project-text__compare {
    grid-template-columns: 1fr;
    row-gap: var(--s-050);
  }
  .page--compassstu .project-text__compare dd {
    margin-bottom: var(--s-100);
  }

  /* Tier 3 — sub-headings within a body block */
  .page--compassstu .project-text__subsection-title {
    font-size: clamp(1rem, 4.2vw, 1.12rem);
    margin: var(--s-200) 0 var(--s-100);
  }

  /* Tier 4 — hero subhead */
  .page--compassstu .project-text__subhead {
    font-size: clamp(0.95rem, 4vw, 1.08rem);
  }

  /* CompassStu-only cards — normalise the scatter (some > body, some < body).
     Tier 3 card titles ~0.98rem; Tier 4 card body ~0.9rem; Tier 5 legend ~0.8rem. */
  .page--compassstu .hub-layer__title,
  .page--compassstu .pathway-tier__title { font-size: 0.98rem; }
  .page--compassstu .hub-layer__num { font-size: 0.9rem; }
  .page--compassstu .hub-layer__body,
  .page--compassstu .pathway-tier__desc,
  .page--compassstu .tutor-card__msg { font-size: 0.9rem; line-height: 1.55; }
  .page--compassstu .skill-state__label { font-size: 0.85rem; }
  .page--compassstu .skill-state__desc { font-size: 0.8rem; }
}

/* ── 480px — small phone ───────────────────────────────────── */
@media (max-width: 480px) {

  /* Intro: minimal height */
  .intro {
    min-height: 22vh;
    padding: var(--s-100) var(--s-050);
  }

  /* Wordmark + tagline: slightly smaller on very narrow screens.
     Tagline sized down (var --desc-shrink) so the wordmark dominates. */
  .wordmark {
    font-size: clamp(0.95rem, 4.8vw, 1.15rem);
  }
  .tagline {
    font-size: calc(clamp(0.95rem, 4.8vw, 1.15rem) - var(--desc-shrink));
  }

  .wordmark { margin-bottom: var(--s-150); }

  /* About hero: smallest phones */
  .about-hero__lead {
    font-size: clamp(1.4rem, 9vw, 2rem);
  }

  /* Dock: tighter pill at 375px and below */
  .dock__group {
    gap: 1px;
    padding: 6px;
  }

  .dock__link {
    font-size: 11.5px;
    padding: 0 9px;
    min-width: 34px;
  }

  /* WIP overlay */
  .wip-card {
    padding: var(--s-200) var(--s-150);
    max-width: calc(100vw - var(--s-150));
    border-radius: var(--site-border-radius);
  }
}
