/* Hallmark · audited 2026-11-07 · system: project brand doc (custom, editorial) · nav: edge-aligned minimal · footer: inline single line
 * pre-emit critique: P5 H5 E4 S5 R5 V4
 */
/*
  Krishna Chauhan site styles. Brand system v3: indigo ink and haldi light.

  Composition rules (from studying calm, highly regarded personal research sites):
  1. The first screen is one sentence, set large, with one accent. Nothing competes with it.
  2. Every section uses the same two columns: a label on the left, content on the right.
  3. Hairlines and space separate things. Boxes and fills are rare.
  4. Light, not decoration: a soft haldi dawn at the top and bottom of the page.
  5. Motion arrives once, quietly, and never loops.

  Contrast on paper (#fbfaf7): ink 16.9, muted 7.9, indigo 10.0, indigo-deep 13.7, meaningful line 3.8.
  Ink on the haldi highlight (#f7e0ab): 13.6.
*/

@font-face {
  font-family: "KC Serif";
  src: url("/assets/fonts/kc-serif-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "KC Serif";
  src: url("/assets/fonts/kc-serif-italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "KC Sans";
  src: url("/assets/fonts/kc-sans-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "KC Sans";
  src: url("/assets/fonts/kc-sans-italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "KC Sans";
  src: url("/assets/fonts/kc-sans-bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

:root {
  color-scheme: light;

  --paper: #fbfaf7;
  --paper-lift: #fefdfa; /* under the grain, so paper plus grain averages out at --paper */
  --surface: #fdfdfb; /* tinted, never pure white */
  --on-accent: #fdfdfb;
  --mist: #f1f1f7;
  --ink: #15172b;
  --muted: #4a4d66;
  --indigo: #30348f;
  --indigo-deep: #1f2263;
  --indigo-wash: #e8e9f5;
  --line: #e6e4dd;
  --line-strong: #7a7e96;
  --haldi: #f2c14e;
  --haldi-hl: #f7e0ab;
  --haldi-deep: #c98a12;
  --focus: #30348f;
  --dawn: rgb(242 193 78 / 0.13); /* haldi light at the page edges */
  --dawn-faint: rgb(242 193 78 / 0.07);
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0,0,0,0,.08,0,0,0,0,.09,0,0,0,0,.17,.035,0,0,0,0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  --shadow-portrait: 0 40px 80px -48px rgb(31 34 99 / 0.45);
  --shadow-button: 0 12px 28px -16px rgb(48 52 143 / 0.8);

  --serif: "KC Serif", "Source Serif 4", Georgia, "Times New Roman", serif;
  --sans: "KC Sans", "Source Sans 3", system-ui, -apple-system, "Segoe UI", sans-serif;
  --text: 1.125rem;
  --small: 0.9375rem;
  --label: 0.8125rem;

  --radius: 4px;
  --wrap: 74rem;
  --gutter: clamp(1.25rem, 0.6rem + 2.6vw, 3rem);
  --label-col: 19rem;
  --col-gap: clamp(3rem, 1rem + 4vw, 6rem);
  --header-h: 4.25rem;

  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --fast: 160ms;
  --base: 240ms;
}

/* ---------- Base ---------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* paper with a faint tooth: a static tile under everything, never an overlay */
  background: var(--paper-lift) var(--grain);
}
body {
  position: relative; /* anchors the daylight and the closing glow to the whole page */
  margin: 0;
  background: none; /* the paper is html's, so the light layers can sit between the two */
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--text);
  line-height: 1.65;
  font-kerning: normal;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  overflow-wrap: break-word;
}
img,
svg {
  display: block;
  max-width: 100%;
}
img {
  height: auto;
}
h1,
h2,
h3 {
  margin: 0;
  font-weight: 400;
  overflow-wrap: break-word;
}
p {
  margin: 0;
  text-wrap: pretty;
}
ul,
ol,
dl,
dd,
figure {
  margin: 0;
  padding: 0;
}
ul[class],
ol[class] {
  list-style: none;
}
a {
  color: var(--indigo);
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
  text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
  transition: color var(--fast) ease, text-decoration-color var(--fast) ease;
}
a:hover {
  color: var(--indigo-deep);
  text-decoration-color: currentColor;
}
:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
  border-radius: 2px;
}
::selection {
  background: var(--haldi-hl);
  color: var(--ink);
}
.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.skip-link {
  position: absolute;
  left: 1rem;
  top: -4rem;
  z-index: 50;
  padding: 0.6rem 1rem;
  background: var(--indigo);
  color: var(--on-accent);
  border-radius: var(--radius);
  text-decoration: none;
}
.skip-link:focus {
  top: 1rem;
}
[id] {
  scroll-margin-top: 1.5rem;
}

/* ---------- Header ---------- */
/* Quiet edge-aligned header: no bar, no border, scrolls away with the page */
.site-header {
  position: relative;
  z-index: 2;
  view-transition-name: site-header;
}
.site-header__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.25rem 1.5rem;
  min-height: var(--header-h);
  padding-block: 0.85rem 0.5rem;
}
.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--serif);
  font-size: 1.1875rem;
  line-height: 1.2;
  color: var(--ink);
  text-decoration: none;
}
.wordmark:hover {
  color: var(--indigo);
}
.site-nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.1rem 1.5rem;
  list-style: none;
  margin: 0;
  padding: 0;
}
.site-nav a {
  position: relative;
  display: inline-block;
  padding-block: 0.4rem;
  color: var(--muted);
  font-size: 0.9375rem;
  text-decoration: none;
}
.site-nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0.2rem;
  height: 1.5px;
  background: var(--indigo);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--base) var(--ease-out);
}
.site-nav a:hover,
.site-nav a[aria-current="page"],
.site-nav a.is-active {
  color: var(--ink);
}
.site-nav a[aria-current="page"]::after,
.site-nav a.is-active::after {
  transform: scaleX(1);
}
@media (hover: hover) and (pointer: fine) {
  .site-nav a:hover::after {
    transform: scaleX(1);
  }
}
@media (max-width: 30rem) {
  .wordmark {
    font-size: 1.0625rem;
  }
  .site-nav ul {
    column-gap: 1rem;
  }
}

.progress {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 40;
  height: 2px;
  pointer-events: none;
}
.progress__bar {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--indigo), var(--haldi));
  transform: scaleX(0);
  transform-origin: left;
}

/* ---------- Buttons, chips ---------- */
.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.25rem;
}
.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 3rem;
  padding: 0.7rem 1.4rem;
  border: 1px solid transparent;
  border-radius: 999px;
  font: inherit;
  font-size: 1rem;
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: transform var(--fast) var(--ease-out), background-color var(--fast) ease, color var(--fast) ease,
    box-shadow var(--base) ease;
}
.button:active {
  transform: scale(0.97);
}
.button--primary {
  background: var(--indigo);
  color: var(--on-accent);
}
.button--primary:hover {
  background: var(--indigo-deep);
  color: var(--on-accent);
}
.button--secondary {
  border-color: var(--indigo);
  color: var(--indigo);
}
.button--secondary:hover {
  background: var(--indigo-wash);
}
.button--quiet {
  padding-inline: 0.25rem;
  color: var(--indigo);
}
.button--quiet:hover {
  color: var(--indigo-deep);
}
.arrow {
  display: inline-block;
  transition: transform 280ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .button:hover .arrow {
    transform: translateX(4px);
  }
}

.status {
  display: inline-flex;
  width: fit-content;
  max-width: 100%;
  padding: 0.1rem 0.6rem;
  border-radius: 999px;
  background: var(--mist);
  color: var(--indigo-deep);
  font-size: var(--label);
  line-height: 1.5;
}


.hl {
  background-image: linear-gradient(var(--haldi-hl), var(--haldi-hl));
  background-repeat: no-repeat;
  background-size: 100% 0.6em;
  background-position: 0 88%;
  padding-inline: 0.05em;
}

/* ---------- Hero ----------
   Portrait in the label column, name and story in the content column: the photo, the name
   and every section below share one alignment line. Flat paper, no ornaments. */
.hero {
  padding-block: clamp(2.5rem, 1.5rem + 4vw, 6rem) clamp(3.5rem, 2rem + 4vw, 6rem);
}
.hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.75rem;
}
.hero__figure {
  width: 11rem;
}
.hero__text {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-content: start;
  gap: 1.25rem;
}
.hero__title {
  font-family: var(--serif);
  font-size: min(clamp(2.5rem, 1.6rem + 3.4vw, 4.75rem), 12.5vw);
  line-height: 1.02;
  letter-spacing: -0.025em;
  color: var(--ink);
  margin-top: -0.08em;
}
.hero__lead {
  font-family: var(--serif);
  font-size: clamp(1.25rem, 1.1rem + 0.65vw, 1.625rem);
  line-height: 1.5;
  letter-spacing: -0.005em;
  max-width: 36em;
  color: var(--ink);
}
.accent {
  color: var(--indigo);
}
.hero__sub {
  color: var(--muted);
  font-size: var(--small);
  max-width: 56ch;
}
.hero .actions {
  margin-top: 0.5rem;
}
.portrait {
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--mist);
  aspect-ratio: 4 / 5;
}
.portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Phones: portrait and name side by side as one lockup, the story full width below,
   so the photo leads and the actions still sit on the first screen. */
@media (max-width: 39.99rem) {
  .hero__grid {
    grid-template-columns: minmax(0, min(8.5rem, 38%)) minmax(0, 1fr);
    grid-template-areas: "fig title" "lead lead" "sub sub" "actions actions";
    column-gap: 1rem;
    row-gap: 1.25rem;
  }
  .hero__text {
    display: contents;
  }
  .hero__figure {
    grid-area: fig;
    width: 100%;
  }
  .hero__title {
    grid-area: title;
    align-self: end;
    margin: 0 0 -0.1em;
    font-size: min(clamp(1.875rem, 1.1rem + 3.6vw, 2.375rem), 9vw);
    line-height: 1.04;
  }
  .hero__lead {
    grid-area: lead;
    font-size: 1.1875rem;
  }
  .hero__sub {
    grid-area: sub;
  }
  .hero .actions {
    grid-area: actions;
    margin-top: 0.25rem;
  }
}
@media (max-width: 22.5rem) {
  .hero {
    padding-top: 1.75rem;
  }
  .hero__lead {
    font-size: 1.0625rem;
  }
}
@media (min-width: 40rem) {
  .hero__grid {
    grid-template-columns: minmax(0, min(12rem, 32%)) minmax(0, 1fr);
    column-gap: 2.5rem;
    align-items: start;
  }
  .hero__figure {
    width: 100%;
  }
}
@media (min-width: 64rem) {
  /* The portrait takes the label column and most of the gap, so it is the larger presence while
     the name still starts on the content line every section below uses. */
  .hero__grid {
    grid-template-columns: minmax(0, calc(min(var(--label-col), 30%) + var(--col-gap) - 2.25rem)) minmax(0, 1fr);
    column-gap: 2.25rem;
  }
}

/* ---------- Greeting (first visit) ----------
   html.intro is set before paint, once per session, never with reduced motion or data-saver.
   The overlay shows the portrait full screen: the whole 4:5 photo, scaled to cover, with her
   face held in the upper part of the frame. Two lines rise into place. site.js then scales that
   same box down into the hero portrait's rect and removes the overlay. */
.hello {
  display: none;
}
/* Scroll is locked only while site.js runs the greeting, so the CSS failsafe never leaves the
   page unscrollable. */
html.intro-live {
  overflow: hidden;
  scrollbar-gutter: stable; /* no layout shift when the scrollbar returns */
}
.js.intro .hello {
  display: block;
  position: fixed;
  inset: 0;
  z-index: 100;
  overflow: hidden;
  container-type: size;
  animation: hello-failsafe 500ms ease 3.2s forwards; /* if site.js never runs */
}
.js.intro-live .hello {
  animation: none;
}
.js.intro-hand .hello {
  pointer-events: none;
}
.hello__paper,
.hello__scrim {
  position: absolute;
  inset: 0;
}
.hello__paper {
  background: var(--paper);
}
.hello__photo {
  --pw: max(100cqw, 80cqh);
  --ph: calc(var(--pw) * 1.25);
  position: absolute;
  left: calc((100cqw - var(--pw)) / 2);
  top: clamp(100cqh - var(--ph), 46cqh - var(--ph) * 0.28, 0px); /* face (28% down the photo) near 46% of the screen */
  width: var(--pw);
  height: var(--ph);
  overflow: hidden;
  transform-origin: 0 0;
}
.hello__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform-origin: 50% 28%;
}
/* The coat is white and sunlit: the scrim is dark enough behind the lines to keep paper text
   above 4.5:1 over the brightest part it covers. */
.hello__scrim {
  background:
    radial-gradient(130% 75% at 0% 100%, color-mix(in srgb, var(--ink) 55%, transparent), transparent 70%),
    linear-gradient(to top, color-mix(in srgb, var(--ink) 80%, transparent), color-mix(in srgb, var(--ink) 62%, transparent) 34%, transparent 66%);
}
.hello__text {
  position: absolute;
  inset-inline: 0;
  bottom: calc(9cqh + env(safe-area-inset-bottom, 0px));
}
.hello__line {
  max-width: 14em;
  font-family: var(--serif);
  font-size: min(clamp(2.6rem, 1.3rem + 4.6vw, 5.75rem), 11.5cqw);
  line-height: 1.04;
  letter-spacing: -0.025em;
  color: var(--paper);
  text-wrap: balance;
}
.hello__line--hi {
  font-style: italic;
  margin-bottom: 0.06em;
}
.hello__dot {
  color: var(--haldi);
}
/* Each word rises out of a mask: clipped at its own bottom edge only */
.hello__w {
  display: inline-block;
  vertical-align: top;
  padding: 0 0.1em 0.16em 0;
  margin: 0 -0.1em -0.16em 0;
  clip-path: inset(-0.6em -0.6em 0 -0.6em);
}
.hello__wi {
  display: inline-block;
}
.js.intro .hello__photo img,
.js.intro .hello__scrim {
  opacity: 0;
}
.js.intro .hello__wi {
  transform: translateY(120%);
}
/* Hold the hero entrance until the handoff. A different animation name holds it, so when
   html.intro-hand lifts this rule the usual entrance starts from the beginning, stagger intact.
   Without site.js the hold releases itself just after the overlay's failsafe. */
.js.intro:not(.intro-hand) .hero__title .w,
.js.intro:not(.intro-hand) .hero [data-enter] {
  animation: hello-hold 600ms var(--ease-out) 3.3s both;
}
.js.intro-live:not(.intro-hand) .hero__title .w,
.js.intro-live:not(.intro-hand) .hero [data-enter] {
  animation: none;
  opacity: 0;
}
/* The photo lands in the portrait's box; the portrait's own entrance would be a second one */
.js.intro .hero__figure,
.js.intro .hero__figure img,
.js.intro-done .hero__figure,
.js.intro-done .hero__figure img {
  animation: none;
}
.js.intro-live .hero__figure {
  visibility: hidden;
}
@keyframes hello-failsafe {
  to {
    opacity: 0;
    visibility: hidden;
  }
}
@keyframes hello-hold {
  from {
    opacity: 0;
  }
}

/* ---------- WebGL stages (three.js + GSAP, see src/scene.js) ---------- */
.stage {
  position: relative;
}
.stage > canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
.stage--live > .stage__fallback {
  display: none;
}
.stage__caption {
  margin-top: 0.75rem;
  font-size: var(--label);
  color: var(--muted);
}

/* About: portrait beside the story */
.about-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 2rem;
}
@media (min-width: 64rem) {
  .about-layout {
    grid-template-columns: minmax(0, 1fr) minmax(0, 21rem);
    column-gap: 3rem;
    align-items: start;
  }
}

/* About figure: the internship year, one cell per week, grouped by specialty */
.rotations {
  --wk: var(--indigo);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1rem;
  padding: 1.5rem;
  border-radius: var(--radius);
  background: var(--mist);
}
.rotations__title {
  font-family: var(--serif);
  font-size: 1.1875rem;
  line-height: 1.3;
  color: var(--ink);
}
.rotations__grid {
  display: grid;
  grid-template-columns: repeat(13, minmax(0, 1fr));
  gap: 4px;
}
.week {
  aspect-ratio: 1 / 1;
  border-radius: 2px;
  background: var(--wk);
  transition: opacity 240ms ease;
}
.g0 { --wk: var(--indigo-deep); }
.g1 { --wk: color-mix(in srgb, var(--indigo) 86%, var(--paper)); }
.g2 { --wk: color-mix(in srgb, var(--indigo) 72%, var(--paper)); }
.g3 { --wk: color-mix(in srgb, var(--indigo) 60%, var(--paper)); }
.g4 { --wk: color-mix(in srgb, var(--indigo) 50%, var(--paper)); }
.g5 { --wk: color-mix(in srgb, var(--indigo) 41%, var(--paper)); }
.g6 { --wk: color-mix(in srgb, var(--indigo) 33%, var(--paper)); }
.g7 { --wk: color-mix(in srgb, var(--indigo) 25%, var(--paper)); }
.is-hl { --wk: var(--haldi); }
.rotations__legend {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.3rem;
  font-size: var(--label);
  line-height: 1.35;
}
.rotations__legend li {
  display: grid;
  grid-template-columns: 0.7rem minmax(0, 1fr) auto;
  align-items: baseline;
  column-gap: 0.6rem;
  cursor: default;
}
.swatch {
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 2px;
  background: var(--wk);
  transform: translateY(0.1em);
}
.rotations__name {
  color: var(--ink);
}
.rotations__weeks {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.rotations__legend .is-hl .rotations__name,
.rotations__legend .is-hl .rotations__weeks {
  color: var(--ink);
  font-weight: 700;
}
.rotations__note {
  font-size: var(--label);
  color: var(--muted);
}
/* point at a specialty in the list to see its weeks */
.rotations:has(.rotations__legend .g0:hover) .week:not(.g0),
.rotations:has(.rotations__legend .g1:hover) .week:not(.g1),
.rotations:has(.rotations__legend .g2:hover) .week:not(.g2),
.rotations:has(.rotations__legend .g3:hover) .week:not(.g3),
.rotations:has(.rotations__legend .g4:hover) .week:not(.g4),
.rotations:has(.rotations__legend .g5:hover) .week:not(.g5),
.rotations:has(.rotations__legend .g6:hover) .week:not(.g6),
.rotations:has(.rotations__legend .g7:hover) .week:not(.g7),
.rotations:has(.rotations__legend .g8:hover) .week:not(.g8) {
  opacity: 0.18;
}

/* Project diagrams (three.js scenes with HTML labels, see src/scene.js) */
.diagram {
  position: relative;
  overflow: hidden;
}
.diagram.stage--live {
  padding: 0;
}
.diagram__labels {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.diagram__label {
  position: absolute;
  left: 0;
  top: 0;
  font-family: var(--sans);
  font-size: 0.75rem;
  line-height: 1.2;
  letter-spacing: 0.01em;
  color: var(--ink);
  white-space: pre; /* labels may break on purpose, never by wrapping */
  will-change: transform;
}
.diagram__label.is-muted {
  color: var(--muted);
}
.diagram__label.is-accent {
  color: var(--indigo-deep);
  font-weight: 700;
}
/* leader lines from a structure to its label, as in an anatomy atlas */
.diagram__leads {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}
.diagram__leads line {
  stroke: var(--ink);
  stroke-opacity: 0.5;
  stroke-width: 1;
}
.diagram--small .is-minor {
  display: none; /* the smallest figures keep only the labels that carry the point */
}
.diagram--small .diagram__label {
  font-size: 0.6875rem;
}
.project-page__plate.stage--live {
  padding: 0;
}

/* ---------- At a glance ---------- */
.glance__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  border-top: 1px solid var(--line);
}
.glance__item {
  display: grid;
  align-content: start;
  gap: 0.25rem;
  padding: 1.25rem 0;
  border-bottom: 1px solid var(--line);
}
.glance dt,
.section__kicker,
.work__role-label,
.about__facts dt,
.pathway__date,
.honor__date,
.next-card__label {
  font-family: var(--sans);
  font-size: var(--label);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.glance__value {
  font-family: var(--serif);
  font-size: 1.5rem;
  line-height: 1.2;
  color: var(--indigo-deep);
  font-variant-numeric: lining-nums tabular-nums;
}
.glance__note {
  font-size: var(--small);
  line-height: 1.5;
  color: var(--muted);
  max-width: 34ch;
}
@media (min-width: 40rem) {
  .glance__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 2.5rem;
  }
}
@media (min-width: 64rem) {
  .glance__grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    column-gap: 2.5rem;
    border-bottom: 1px solid var(--line);
  }
  .glance__item {
    border-bottom: 0;
    padding-block: 1.75rem;
  }
}

/* ---------- Sections: label left, content right ---------- */
.section {
  padding-block: clamp(4rem, 2.5rem + 5vw, 8rem) 0;
}
#about {
  padding-top: clamp(3rem, 2rem + 3vw, 5rem);
}
#projects {
  padding-top: clamp(5rem, 3rem + 6vw, 9.5rem);
}
#honors {
  padding-top: clamp(3.5rem, 2.5rem + 3vw, 6rem);
}
.section__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.75rem;
}
.section__label {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-content: start;
  gap: 0.5rem;
}
.section__label h2 {
  font-family: var(--serif);
  font-size: clamp(1.625rem, 1.4rem + 0.8vw, 2rem);
  line-height: 1.15;
  letter-spacing: -0.012em;
}
.section__kicker {
  letter-spacing: 0.08em;
  text-transform: none;
  font-size: var(--small);
}
.section__body {
  min-width: 0;
}
@media (min-width: 64rem) {
  .section__grid {
    grid-template-columns: minmax(0, min(var(--label-col), 30%)) minmax(0, 1fr);
    column-gap: var(--col-gap);
  }
  .section__label {
    position: sticky;
    top: 2rem;
    align-self: start;
  }
}

/* About */
.about {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.25rem;
  max-width: 44rem;
}
.lead {
  font-family: var(--serif);
  font-size: clamp(1.3125rem, 1.15rem + 0.6vw, 1.625rem);
  line-height: 1.5;
  letter-spacing: -0.006em;
}
.about__facts {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1rem 2.5rem;
  margin-top: 0.75rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--line);
}
.about__facts div {
  display: grid;
  gap: 0.15rem;
}
@media (min-width: 40rem) {
  .about__facts {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* Projects */
.works {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  border-top: 1px solid var(--line);
}
.work {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.5rem;
  padding-block: 2.25rem;
  border-bottom: 1px solid var(--line);
}
.work__text {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-content: start;
  gap: 0.75rem;
}
.work__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.9rem;
  font-size: var(--small);
  color: var(--muted);
}
.work__title {
  font-family: var(--serif);
  font-size: clamp(1.5rem, 1.3rem + 0.8vw, 1.875rem);
  line-height: 1.2;
  letter-spacing: -0.01em;
  max-width: 26ch;
}
.work__title a {
  color: var(--ink);
  text-decoration: none;
}
.work__title a::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}
.work__summary {
  max-width: 58ch;
  color: var(--ink);
}
.work__role {
  font-size: var(--small);
  color: var(--muted);
  max-width: 58ch;
}
.work__role-label {
  margin-right: 0.4rem;
}
.work__more {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  align-items: center;
  margin-top: 0.25rem;
  color: var(--indigo);
  font-size: 1rem;
}
.work__figure {
  order: -1;
  display: grid;
  place-items: center;
  aspect-ratio: 4 / 3;
  padding: 1.25rem;
  border-radius: var(--radius);
  background: var(--mist);
}
.work__figure .motif {
  width: 100%;
}
.work:has(.work__title a:focus-visible) {
  outline: 3px solid var(--focus);
  outline-offset: 6px;
  border-radius: var(--radius);
}
.work__title a:focus-visible {
  outline: none;
}
@media (min-width: 48rem) {
  .work {
    grid-template-columns: minmax(0, 1fr) minmax(0, 24rem);
    column-gap: 2.5rem;
    align-items: center;
  }
  .work__figure {
    order: 0;
  }
}
@media (hover: hover) and (pointer: fine) {
  .work:hover .work__title a {
    color: var(--indigo-deep);
  }
  .work:hover .work__more .arrow,
  .next-card:hover .arrow,
  .contact__links a:hover .arrow {
    transform: translateX(5px);
  }
}

/* Decorative figures */
.motif {
  overflow: visible;
  color: var(--indigo);
}
.motif__edge,
.motif__field {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 0;
}
.motif__node {
  fill: var(--surface);
  stroke: currentColor;
  stroke-width: 1.6;
  transform-box: fill-box;
  transform-origin: center;
  transition: transform 320ms var(--ease-out);
}
.motif__node--accent,
.motif__target {
  fill: var(--haldi);
  stroke: var(--indigo-deep);
  stroke-width: 1.4;
  transform-box: fill-box;
  transform-origin: center;
}
.motif__head {
  fill: color-mix(in srgb, var(--surface) 75%, transparent);
  stroke: var(--line-strong);
  stroke-width: 1.4;
}
.motif__callosum {
  fill: var(--surface);
  stroke: var(--line-strong);
  stroke-width: 1;
}
.motif__winding {
  fill: none;
  stroke: var(--indigo-deep);
  stroke-width: 1.4;
}

/* Education and training */
.pathway-wrap {
  position: relative;
}
.pathway__rail {
  position: absolute;
  left: 6px;
  top: 0.6rem;
  bottom: 2.5rem;
  width: 2px;
  border-radius: 2px;
  background: var(--line);
  /* clip, not hidden: overflow: hidden makes the rail a scroll container, and the fill's view()
     timeline would then track the rail (which never scrolls) instead of the page, leaving the
     line stuck half full. hidden stays as the fallback where clip is unknown. */
  overflow: hidden;
  overflow: clip;
}
.pathway__fill {
  display: block;
  height: 100%;
  background: linear-gradient(var(--haldi) 0, var(--indigo) 6rem);
  transform-origin: top;
}
.pathway {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}
.pathway__item {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.3rem;
  padding: 0 0 2.75rem 2.25rem;
  max-width: 46rem;
}
.pathway__item::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.25rem;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--paper);
  border: 2px solid var(--line-strong);
  transition: background-color 500ms ease, border-color 500ms ease;
}
/* a milestone's dot fills when the rail's line reaches it (the middle of the screen), set by
   site.js, so the line and the dots always agree */
.pathway__item.is-reached::before {
  border-color: var(--indigo);
  background: var(--indigo);
}
.pathway__item--now::before,
.pathway__item--now.is-in::before {
  background: var(--haldi);
  border-color: var(--indigo-deep);
}
.pathway__item--now::after {
  content: "";
  position: absolute;
  left: 0;
  top: 0.25rem;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--haldi);
  opacity: 0;
}
.pathway__item--now .pathway__date {
  color: var(--indigo);
}
.pathway__title {
  font-family: var(--serif);
  font-size: clamp(1.3125rem, 1.15rem + 0.6vw, 1.625rem);
  line-height: 1.25;
}
.pathway__place {
  color: var(--muted);
}
.pathway__link {
  margin-top: 0.25rem;
}
.dash-list {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.4rem;
  list-style: none;
  padding: 0;
  margin: 0.35rem 0 0;
}
.dash-list li {
  position: relative;
  padding-left: 1.35rem;
}
.dash-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.82em;
  width: 0.65rem;
  height: 1px;
  background: var(--line-strong);
}

/* Honors */
.honors {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  border-top: 1px solid var(--line);
}
.honor {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.25rem;
  padding-block: 1.5rem;
  border-bottom: 1px solid var(--line);
}
.honor__title {
  font-family: var(--serif);
  font-size: clamp(1.25rem, 1.15rem + 0.4vw, 1.4375rem);
  line-height: 1.3;
}
.honor__detail {
  color: var(--muted);
  max-width: 60ch;
}
@media (min-width: 48rem) {
  .honor {
    grid-template-columns: minmax(0, 1fr) minmax(0, 11rem);
    column-gap: 2rem;
  }
  .honor__date {
    grid-column: 2;
    grid-row: 1;
    text-align: right;
    padding-top: 0.3rem;
  }
  .honor__detail {
    grid-column: 1;
  }
}

/* Contact */
.contact {
  position: relative;
  isolation: isolate;
  padding-bottom: clamp(5rem, 3rem + 6vw, 9rem);
}
.contact__body {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.5rem;
  max-width: 44rem;
}
.contact__lead {
  font-family: var(--serif);
  font-size: clamp(1.3125rem, 1.15rem + 0.6vw, 1.625rem);
  line-height: 1.5;
}
.contact__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 1.25rem;
}
.contact__email {
  font-family: var(--serif);
  font-size: clamp(1.375rem, 0.95rem + 1.9vw, 2.375rem);
  line-height: 1.2;
  color: var(--indigo-deep);
  text-decoration-color: var(--haldi);
  text-decoration-thickness: 2px;
  text-underline-offset: 0.24em;
  overflow-wrap: anywhere;
}
.contact__email:hover {
  color: var(--indigo);
}
.copy {
  display: inline-grid;
  min-height: 2.75rem;
  padding: 0.5rem 1.1rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: var(--small);
  cursor: pointer;
  transition: transform var(--fast) var(--ease-out), background-color var(--fast) ease;
}
.copy:hover {
  background: var(--indigo-wash);
}
.copy:active {
  transform: scale(0.97);
}
.copy__label {
  grid-area: 1 / 1;
  transition: opacity 200ms ease, filter 200ms ease, transform 200ms var(--ease-out);
}
.copy__label--done {
  opacity: 0;
  filter: blur(2px);
  transform: translateY(4px);
  color: var(--indigo);
}
.copy.is-done .copy__label--idle {
  opacity: 0;
  filter: blur(2px);
  transform: translateY(-4px);
}
.copy.is-done .copy__label--done {
  opacity: 1;
  filter: none;
  transform: none;
}
.contact__links {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  margin-top: 1rem;
  border-top: 1px solid var(--line);
}
.contact__links a {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  padding-block: 0.95rem;
  border-bottom: 1px solid var(--line);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 1.1875rem;
  text-decoration: none;
}
.contact__links a:hover {
  color: var(--indigo);
}
.contact__links .arrow {
  color: var(--indigo);
}

/* Footer */
.site-footer {
  font-size: var(--small);
  color: var(--muted);
}
.site-footer__inner {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.5rem 2rem;
  padding-block: 1.75rem 2.5rem;
}
.site-footer__inner::before {
  content: "";
  position: absolute;
  top: 0;
  left: var(--gutter);
  right: var(--gutter);
  height: 1px;
  background: var(--line);
}
.site-footer__name {
  color: var(--ink);
  font-family: var(--serif);
  font-size: 1.0625rem;
  margin-right: 0.75rem;
}

/* ---------- Project page ---------- */
.project-page {
  padding-block: clamp(2rem, 1.5rem + 2vw, 3.5rem) clamp(4rem, 3rem + 4vw, 7rem);
}
.back {
  margin-bottom: clamp(1.5rem, 1rem + 2vw, 2.75rem);
  font-size: var(--small);
}
.back a {
  text-decoration: none;
  color: var(--muted);
}
.back a:hover {
  color: var(--indigo);
}
.project-page__header {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 2rem;
  padding-bottom: clamp(2rem, 1.5rem + 2vw, 3.5rem);
  margin-bottom: clamp(2rem, 1.5rem + 2vw, 3.5rem);
  border-bottom: 1px solid var(--line);
}
.project-page__intro {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-content: start;
  gap: 1.1rem;
}
.project-page h1 {
  font-family: var(--serif);
  font-size: clamp(2.125rem, 1.5rem + 2.4vw, 3.5rem);
  line-height: 1.08;
  letter-spacing: -0.02em;
  max-width: 22ch;
}
.project-page__lead {
  font-family: var(--serif);
  font-size: clamp(1.1875rem, 1.05rem + 0.5vw, 1.4375rem);
  line-height: 1.5;
  color: var(--muted);
  max-width: 54ch;
}
.project-page__figure {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.75rem;
  align-content: start;
}
.project-page__plate {
  display: grid;
  place-items: center;
  aspect-ratio: 16 / 10;
  padding: 1.75rem;
  border-radius: var(--radius);
  background: var(--mist);
}
.project-page__plate .motif {
  width: min(100%, 26rem);
}
.fig-caption {
  font-size: var(--label);
  line-height: 1.5;
  color: var(--muted);
}
.fig-no {
  font-variant-caps: all-small-caps;
  letter-spacing: 0.08em;
  font-size: 1rem;
  color: var(--indigo);
  margin-right: 0.35rem;
}
@media (min-width: 60rem) {
  .project-page__header {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
    align-items: end;
    gap: 3.5rem;
  }
}
.project-page__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 2.5rem;
}
@media (min-width: 56rem) {
  .project-page__grid {
    grid-template-columns: minmax(0, 1fr) 20rem;
    grid-template-areas: "body facts";
    gap: 4.5rem;
    align-items: start;
  }
  .project-page__facts {
    grid-area: facts;
    position: sticky;
    top: 2rem;
  }
  .project-page__body {
    grid-area: body;
  }
}
.facts {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  font-size: var(--small);
}
.facts dt {
  font-size: var(--label);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}
.facts--panel {
  border-top: 1px solid var(--line);
}
.facts--panel div {
  display: grid;
  gap: 0.1rem;
  padding-block: 0.75rem;
  border-top: 1px solid var(--line);
}
.facts--panel div:first-child {
  border-top: 0;
}
.facts--panel div:last-child {
  padding-bottom: 0;
}
.prose {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1rem;
  max-width: 68ch;
}
.prose h2 {
  font-family: var(--serif);
  font-size: clamp(1.5rem, 1.3rem + 0.8vw, 1.875rem);
  line-height: 1.2;
  margin-top: 1.25rem;
}
.prose h2:first-child {
  margin-top: 0;
}
.note {
  padding-block: 0.9rem;
  border-block: 1px solid var(--line);
  color: var(--muted);
  font-size: var(--small);
}
.project-page__next {
  margin-top: clamp(4rem, 3rem + 4vw, 7rem);
}
.next-card {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.25rem;
  padding-block: 2rem;
  border-block: 1px solid var(--line);
}
.next-card__title {
  font-family: var(--serif);
  font-size: clamp(1.375rem, 1.2rem + 0.8vw, 1.875rem);
  line-height: 1.2;
  margin-block: 0.4rem 0.6rem;
}
.next-card__title a {
  color: var(--ink);
  text-decoration: none;
}
.next-card__title a::after {
  content: "";
  position: absolute;
  inset: 0;
}
.next-card__more {
  color: var(--indigo);
}
.next-card__figure {
  display: grid;
  place-items: center;
  padding: 1rem;
  border-radius: var(--radius);
  background: var(--mist);
}
.next-card__figure .motif {
  width: min(100%, 13rem);
}
.next-card:has(a:focus-visible) {
  outline: 3px solid var(--focus);
  outline-offset: 6px;
}
.next-card a:focus-visible {
  outline: none;
}
@media (min-width: 44rem) {
  .next-card {
    grid-template-columns: minmax(0, 1fr) 14rem;
    align-items: center;
  }
}

/* ---------- CV page ---------- */
.cv {
  padding-block: clamp(2rem, 1.5rem + 2vw, 3.5rem) clamp(4rem, 3rem + 4vw, 7rem);
}
.cv__header {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.6rem;
  padding-bottom: 2rem;
  border-bottom: 1px solid var(--line);
}
.cv__header > * {
  max-width: 52rem;
}
.cv__name {
  font-family: var(--serif);
  font-size: clamp(2.25rem, 1.6rem + 2.6vw, 3.5rem);
  line-height: 1.05;
  letter-spacing: -0.02em;
}
.cv__legal {
  color: var(--muted);
}
.cv__line {
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.25rem;
  color: var(--muted);
}
.cv__line--muted {
  font-family: var(--sans);
  font-style: normal;
  font-size: 1rem;
  overflow-wrap: anywhere;
}
.sep {
  color: var(--line-strong);
  margin-inline: 0.35rem;
}
.cv__actions {
  margin-top: 0.75rem;
}
.cv__section {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.75rem 3rem;
  padding-block: 2rem;
  border-bottom: 1px solid var(--line);
}
.cv__section h2 {
  font-size: var(--label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--indigo);
  padding-top: 0.3rem;
}
.cv__entries {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.5rem;
  max-width: 52rem;
}
.cv__entry {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.25rem;
}
.cv__entry-head {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.15rem 1.5rem;
}
.cv__entry h3 {
  min-width: 0;
  font-family: var(--serif);
  font-size: 1.25rem;
  line-height: 1.3;
  max-width: 40rem;
}
.cv__dates {
  font-size: var(--small);
  color: var(--muted);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.cv__place {
  color: var(--muted);
  font-size: var(--small);
}
.cv__details {
  font-size: 1rem;
}
.cv__pairs {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.2rem 1.5rem;
  max-width: 52rem;
}
.cv__pairs dt {
  font-family: var(--serif);
  font-size: 1.125rem;
}
.cv__pairs dd {
  margin-bottom: 0.75rem;
}
@media (min-width: 40rem) {
  .cv__pairs {
    grid-template-columns: 9rem minmax(0, 1fr);
  }
  .cv__pairs dd {
    margin-bottom: 0;
  }
}
@media (min-width: 52rem) {
  .cv__section {
    grid-template-columns: 12rem minmax(0, 1fr);
  }
}
.cv__asof {
  margin-top: 1.5rem;
  font-size: var(--small);
  color: var(--muted);
}

/* ---------- 404 ---------- */
.notfound {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1rem;
  padding-block: clamp(4rem, 3rem + 4vw, 7rem);
}
.notfound h1 {
  font-family: var(--serif);
  font-size: clamp(2.25rem, 1.6rem + 2.6vw, 3.5rem);
  line-height: 1.1;
}

/* =====================================================================
   Motion. Everything above renders complete and still. html.js is set
   inline before paint; html.reveal-ready by site.js.
   ===================================================================== */
@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }

  /* The headline arrives word by word, out of a soft blur */
  .js .hero__title .w {
    display: inline-block;
    max-width: 100%;
    animation: word-in 900ms var(--ease-out) both;
    animation-delay: calc(120ms + var(--w, 0) * 32ms);
  }
  .js .hero [data-enter] {
    animation: lift 900ms var(--ease-out) both;
    animation-delay: calc(650ms + var(--i, 0) * 110ms);
  }
  .js .hero__figure {
    animation: figure-in 1300ms var(--ease-in-out) 150ms backwards; /* no clip left behind: the portrait drifts on scroll */
  }
  .js .hero__figure img {
    animation: settle 1800ms var(--ease-out) 250ms both;
  }
  /* One orchestrated entrance (the hero). Below it, sections answer the scroll once each: titles
     rise word by word, figures settle and draw, the timeline fills, the highlight sweeps. Body
     text is never animated, so reading stays immediate. (Revised 8 Nov 2026: was hero only.) */
  .js .hl {
    transition: background-size 1000ms var(--ease-in-out) 350ms;
  }
  .reveal-ready .hl:not(.is-in) {
    background-size: 0% 0.6em;
  }

  /* The internship weeks fill in order when the figure enters */
  .rotations .week {
    transition: opacity 240ms ease, transform 520ms var(--ease-out);
  }
  .reveal-ready .rotations:not(.is-in) .week {
    opacity: 0;
    transform: scale(0.55);
  }
  .reveal-ready .rotations.is-in .week {
    transition-delay: calc(var(--c, 0) * 18ms), calc(var(--c, 0) * 18ms);
  }
  .reveal-ready .rotations.is-in:has(.rotations__legend li:hover) .week {
    transition-delay: 0ms;
  }

  /* Figures draw themselves */
  .motif__edge,
  .motif__field {
    transition: stroke-dashoffset 1000ms var(--ease-in-out);
    transition-delay: calc(300ms + var(--d, 0) * 110ms);
  }
  .motif__node,
  .motif__target {
    transition: transform 500ms var(--ease-out), opacity 500ms ease;
    transition-delay: calc(200ms + var(--d, 0) * 110ms);
  }
  .reveal-ready [data-reveal]:not(.is-in) .motif__edge,
  .reveal-ready [data-reveal]:not(.is-in) .motif__field {
    stroke-dashoffset: 1;
  }
  .reveal-ready [data-reveal]:not(.is-in) .motif__node,
  .reveal-ready [data-reveal]:not(.is-in) .motif__target {
    opacity: 0;
    transform: scale(0.85);
  }
  .js .project-page__plate .motif__edge,
  .js .project-page__plate .motif__field {
    animation: draw 1100ms var(--ease-in-out) both;
    animation-delay: calc(350ms + var(--d, 0) * 120ms);
  }
  .js .project-page__plate .motif__node,
  .js .project-page__plate .motif__target {
    animation: pop 600ms var(--ease-out) both;
    animation-delay: calc(250ms + var(--d, 0) * 120ms);
  }
  @media (hover: hover) and (pointer: fine) {
    .work:hover .motif__edge,
    .next-card:hover .motif__edge {
      animation: draw 700ms var(--ease-in-out) both;
      animation-delay: calc(var(--d, 0) * 70ms);
    }
    .work:hover .motif__field,
    .next-card:hover .motif__field {
      animation: pulse-out 900ms var(--ease-out) both;
      animation-delay: calc(var(--d, 0) * 90ms);
    }
    .work:hover .motif__node--accent,
    .work:hover .motif__target {
      transform: scale(1.3);
    }
  }

  .pathway__item--now.is-in::after {
    animation: ping 1800ms var(--ease-out) 400ms 3;
  }

  @supports (animation-timeline: view()) {
    .pathway__fill {
      animation: grow-y linear both;
      animation-timeline: view();
      animation-range: cover 50vh cover calc(100% - 50vh);
    }
    .progress__bar {
      animation: grow-x linear both;
      animation-timeline: scroll(root block);
    }
  }

  @view-transition {
    navigation: auto;
  }
  ::view-transition-old(root) {
    animation: vt-out 220ms var(--ease-out) both;
  }
  ::view-transition-new(root) {
    animation: vt-in 320ms var(--ease-out) both;
  }
  ::view-transition-group(*) {
    animation-duration: 420ms;
    animation-timing-function: var(--ease-in-out);
  }
}

@media (prefers-reduced-motion: reduce) {
  .pathway__fill {
    transform: none !important;
  }
}

@keyframes word-in {
  from {
    opacity: 0;
    transform: translateY(0.3em);
    filter: blur(6px);
  }
}
@keyframes underline {
  from {
    background-size: 0% 0.07em;
  }
}
@keyframes lift {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
}
@keyframes figure-in {
  from {
    clip-path: inset(100% 0 0 0 round var(--radius));
  }
  to {
    clip-path: inset(0 0 0 0 round var(--radius));
  }
}
@keyframes settle {
  from {
    transform: scale(1.08);
  }
}
@keyframes ping {
  0% {
    opacity: 0.7;
    transform: scale(1);
  }
  100% {
    opacity: 0;
    transform: scale(3);
  }
}
@keyframes failsafe {
  to {
    opacity: 1;
    transform: none;
  }
}
@keyframes draw {
  from {
    stroke-dashoffset: 1;
  }
  to {
    stroke-dashoffset: 0;
  }
}
@keyframes pop {
  from {
    opacity: 0;
    transform: scale(0.85);
  }
}
@keyframes pulse-out {
  0% {
    stroke: currentColor;
  }
  35% {
    stroke: var(--haldi-deep);
  }
  100% {
    stroke: currentColor;
  }
}
@keyframes grow-y {
  from {
    transform: scaleY(0);
  }
  to {
    transform: scaleY(1);
  }
}
@keyframes grow-x {
  from {
    transform: scaleX(0);
  }
  to {
    transform: scaleX(1);
  }
}
@keyframes vt-out {
  to {
    opacity: 0;
  }
}
@keyframes vt-in {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
}

/* ---------- Forced colours ---------- */
@media (forced-colors: active) {
  .facts--panel,
  .status,
  .copy,
  .work__figure,
  .project-page__plate {
    border: 1px solid CanvasText;
  }
  .hl {
    background: none;
    text-decoration: underline;
  }
}

/* ---------- Print (the CV page is meant to print) ---------- */
@media print {
  body::before,
  body::after {
    display: none !important;
  }
  .section--night {
    --ink: #000;
    --muted: #333;
    --indigo: #000;
    --line: #ccc;
    background: #fff !important;
    color: #000;
    margin: 0;
    padding-bottom: 0;
  }
  @page {
    size: A4;
    margin: 14mm 14mm 16mm;
  }
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }
  [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
  }
  html,
  body {
    background: #fff;
  }
  body {
    font-size: 10pt;
    line-height: 1.45;
    color: #000;
  }
  .site-header,
  .site-footer,
  .skip-link,
  .hello,
  .progress,
  .cv__actions,
  .back,
  .project-page__next {
    display: none !important;
  }
  .wrap {
    max-width: none;
    padding: 0;
  }
  .cv {
    padding: 0;
  }
  .cv__name {
    font-size: 20pt;
  }
  .cv__line {
    font-size: 11pt;
  }
  .cv__header {
    padding-bottom: 8pt;
  }
  .cv__section {
    grid-template-columns: 32mm minmax(0, 1fr);
    gap: 4pt 8mm;
    padding-block: 8pt;
  }
  .cv__section h2 {
    font-size: 8.5pt;
    color: #000;
  }
  .cv__entry h3 {
    font-size: 10pt;
  }
  .cv__dates,
  .cv__place,
  .cv__details,
  .cv__pairs,
  .cv__asof {
    font-size: 9.5pt;
  }
  .cv__entries {
    gap: 7pt;
  }
  .cv__entry {
    break-inside: avoid;
  }
  a {
    color: inherit;
    text-decoration: none;
  }
}

@media (max-width: 30rem) {
  .button {
    max-width: 100%;
    white-space: normal;
    text-align: center;
  }
}

/* Reflow guard: grid and flex children may shrink below their longest word,
   so enlarged text wraps instead of pushing the page sideways. */
.glance__item > *,
.section__body > *,
.section__body > * > *,
.works-layout > *,
.about-layout > * {
  min-width: 0;
}

/* =====================================================================
   Light and rhythm (8 Nov 2026)
   Daylight at the top of every page, a warm glow where the page ends, the projects on a
   night band where the 3D figures read as lit, and the scroll-linked motion that goes with it.
   ===================================================================== */

/* Daylight from the upper left, and the close's warm glow. They sit between html's paper and
   the content (z-index -1 in the root stacking context), so text is never tinted. */
body::before,
body::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  z-index: -1;
  pointer-events: none;
}
body::before {
  top: -3rem; /* headroom for the drift, so its top edge never shows */
  height: calc(min(120vh, 72rem) + 3rem);
  background:
    radial-gradient(62% 58% at 12% 6%, var(--dawn), transparent 72%),
    radial-gradient(42% 40% at 92% 0%, var(--dawn-faint), transparent 70%);
}
body::after {
  bottom: 0;
  height: min(95vh, 60rem);
  background: radial-gradient(70% 72% at 24% 100%, var(--dawn), transparent 74%);
}

/* Section titles: rendered complete; under motion they rise word by word as the section enters */
.section__label h2 .w {
  display: inline-block;
  max-width: 100%;
}

/* Underline that draws from the left under link text */
.u {
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 1px;
  padding-bottom: 1px;
}

@media (hover: hover) and (pointer: fine) {
  .work:hover .work__more .u,
  .next-card:hover .next-card__more .u,
  .button:hover .u {
    background-size: 100% 1px;
  }
}

/* ---------- The night band (projects) ----------
   The section redefines the colour tokens, so its text, chips, rules, figure labels and the
   three.js figures themselves (scene.js reads the stage's tokens) all switch to night inks. */
.section--night {
  --ink: #f2f0ea;
  --muted: #b2b5cd;
  --indigo: #9ca2ff; /* treatment node and links: bluer than the grey nodes */
  --indigo-deep: #dcdeff;
  --indigo-wash: rgb(255 255 255 / 0.08);
  --line: rgb(255 255 255 / 0.13);
  --line-strong: #878ba6;
  --mist: #1c1f3d;
  --focus: var(--haldi);
  position: relative;
  margin-top: clamp(4rem, 2.5rem + 5vw, 8rem);
  padding-bottom: clamp(4.5rem, 3rem + 5vw, 8.5rem);
  background: #15172b; /* the day ink, as the night's ground */
  color: var(--ink);
}
#projects.section--night {
  padding-top: clamp(4.5rem, 3rem + 5vw, 8.5rem);
}
.section--night ::selection {
  color: #15172b;
}
.section--night .work__figure {
  background:
    radial-gradient(70% 62% at 50% 60%, rgb(242 193 78 / 0.1), transparent 72%),
    var(--mist);
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.05);
}

/* Shared-element morph between the home rows and the project pages: titles keep their own
   size and crossfade in place while their box moves, instead of being stretched */
.work__title,
.project-page h1,
.next-card__title {
  view-transition-class: vt-title;
}
::view-transition-old(*.vt-title),
::view-transition-new(*.vt-title) {
  height: 100%;
  object-fit: none;
  object-position: left top;
}

@media (prefers-reduced-motion: no-preference) {
  /* The daylight breathes, slowly: opacity and a small vertical drift, compositor only */
  body::before {
    animation: daylight 18s var(--ease-in-out) infinite alternate;
    will-change: opacity, transform;
  }

  .section__label .w {
    transition:
      opacity 600ms var(--ease-out),
      transform 900ms var(--ease-out),
      filter 600ms var(--ease-out);
    transition-delay: calc(var(--w, 0) * 45ms);
  }
  .section__label .section__kicker {
    transition:
      opacity 600ms var(--ease-out) 240ms,
      transform 900ms var(--ease-out) 240ms;
  }
  .reveal-ready .section__label:not(.is-in) .w {
    opacity: 0;
    transform: translateY(0.35em);
    filter: blur(6px);
  }
  .reveal-ready .section__label:not(.is-in) .section__kicker {
    opacity: 0;
    transform: translateY(8px);
  }

  /* Milestone titles ease in from the rail (was a GSAP tween in scene.js) */
  .pathway__title {
    transition:
      opacity 900ms var(--ease-out),
      transform 900ms var(--ease-out);
  }
  .reveal-ready .pathway__item:not(.is-in) .pathway__title {
    opacity: 0.3;
    transform: translateX(-10px);
  }

  /* Project figures settle into place as their row enters */
  .work__figure {
    transition:
      opacity 900ms var(--ease-out),
      transform 1200ms var(--ease-out);
  }
  .reveal-ready .work:not(.is-in) .work__figure {
    opacity: 0;
    transform: translateY(32px) scale(0.97);
  }

  @media (hover: hover) and (pointer: fine) {
    .u {
      transition: background-size 320ms var(--ease-out);
    }

    /* Depth while scrolling, desktop only: the portrait trails the page a little and the
       project figures drift against their text. `translate` composes with the entrances,
       which use `transform`. */
    @supports (animation-timeline: view()) {
      .hero .portrait {
        animation: portrait-drift linear both;
        animation-timeline: scroll(root block);
        animation-range: 0 100vh;
      }
      .work__figure {
        animation: figure-drift linear both;
        animation-timeline: view();
        animation-range: cover;
      }
    }
  }
}

@keyframes daylight {
  from {
    opacity: 0.75;
    transform: translateY(-1.5%);
  }
  to {
    opacity: 1;
    transform: translateY(1.5%);
  }
}
@keyframes portrait-drift {
  to {
    translate: 0 3.5rem;
  }
}
@keyframes figure-drift {
  from {
    translate: 0 1.75rem;
  }
  to {
    translate: 0 -1.75rem;
  }
}
