/* ------------------------------------------------------------------
   Daniel Zan Baltazar, developer journey
   Stack: Bootstrap 5.3 grid + utilities, custom CSS on top.
   Theme: light only (by brief). One accent: yellow.
   Shape rule: buttons are pills, images and tiles are 12px.

   Motion rules:
   - Hidden "before reveal" states only apply when <html class="js">
     and the visitor has not asked for reduced motion.
   - Nothing that is observed or lazy-loaded is ever clipped or moved
     out of view: reveals use a curtain that slides off the image.
   - Only transform-family properties, opacity, clip-path and filter
     animate.
   ------------------------------------------------------------------ */

:root {
  --font-display: "Bricolage Grotesque", "Hanken Grotesk", system-ui, sans-serif;
  --font-body: "Hanken Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;

  --ink: #161512;
  --ink-2: #4a4842;
  --ink-3: #6b6860;
  --paper: #ffffff;
  --paper-2: #f7f5ee;
  --line: #e6e3d9;

  --yellow: #ffd60a;
  --yellow-deep: #f0c400;
  --yellow-soft: #fff1a8;
  --on-yellow-2: #5c4a00;

  --radius: 12px;
  --nav-h: 72px;

  /* Distance from the Bootstrap container's content edge to the viewport edge.
     Used for full-bleed pieces (hero photo, podcast reel). */
  --container: 1320px;
  --gutter: calc((100vw - var(--container)) / 2 + 0.75rem);

  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);

  /* Bootstrap hooks */
  --bs-body-font-family: var(--font-body);
  --bs-body-color: var(--ink);
  --bs-body-bg: var(--paper);
  --bs-link-color: var(--ink);
  --bs-link-hover-color: var(--ink);
  --bs-border-color: var(--line);
  --bs-font-sans-serif: var(--font-body);
}
@media (max-width: 1399.98px) { :root { --container: 1140px; } }
@media (max-width: 1199.98px) { :root { --container: 960px; } }
@media (max-width: 991.98px)  { :root { --container: 720px; } }
@media (max-width: 767.98px)  { :root { --container: 540px; } }
@media (max-width: 575.98px)  { :root { --gutter: 0.75rem; } }

html {
  scroll-padding-top: var(--nav-h);
  scrollbar-color: var(--ink-3) var(--paper-2);
}

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

body {
  font-family: var(--font-body);
  color: var(--ink);
  background: var(--paper);
  font-size: 1.0625rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}

/* Browser surfaces: selection, focus, links */
::selection { background: var(--yellow); color: var(--ink); }

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
  border-radius: 4px;
}

a {
  color: var(--ink);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  text-decoration-color: color-mix(in srgb, var(--ink) 40%, transparent);
  transition: text-decoration-color 160ms ease;
}
a:hover { text-decoration-color: var(--ink); }

img { max-width: 100%; height: auto; }

strong { font-weight: 600; }

.skip-link {
  position: absolute;
  top: -100%;
  left: 1rem;
  z-index: 1100;
  padding: 0.6rem 1rem;
  background: var(--yellow);
  color: var(--ink);
  border-radius: 999px;
  font-weight: 600;
  text-decoration: none;
}
.skip-link:focus { top: 1rem; }

.top-sentinel {
  position: absolute;
  top: 0;
  height: 1px;
  width: 1px;
}

/* Split words: wrapper clips, inner word rises. Padding keeps descenders. */
.w {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  padding-bottom: 0.14em;
  margin-bottom: -0.14em;
}
.wi { display: inline-block; }

/* Highlighter: a pseudo-element behind the word so it can draw in from the left */
.hl {
  position: relative;
  z-index: 0;
  background: none;
  color: inherit;
  padding: 0 0.05em;
  white-space: nowrap;
}
.hl::after {
  content: "";
  position: absolute;
  z-index: -1;
  left: 0;
  right: 0;
  bottom: 0.04em;
  height: 0.45em;
  background: var(--yellow);
  transform-origin: left;
}

/* ------------------------------------------------------------------
   Navigation
   ------------------------------------------------------------------ */

.site-nav {
  min-height: var(--nav-h);
  background: var(--paper);
  border-bottom: 1px solid transparent;
  transition: border-color 200ms ease;
  padding-block: 0.75rem;
}
.site-nav.is-scrolled,
.site-nav:has(.navbar-collapse.show) { border-bottom-color: var(--line); }

.site-nav .navbar-brand {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.0625rem;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.site-nav .navbar-collapse { position: relative; }

.site-nav .nav-link {
  color: var(--ink-2);
  font-weight: 500;
  padding-inline: 0.9rem;
  transition: color 160ms ease;
}
.site-nav .nav-link:hover,
.site-nav .nav-link:focus-visible { color: var(--ink); }
.site-nav .nav-link[aria-current="true"] {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--yellow);
  text-decoration-thickness: 2px;
  text-underline-offset: 0.4em;
}
/* One underline that slides between links (desktop, JS). The static
   underline above remains for mobile, no-JS and reduced motion. */
.nav-indicator {
  position: absolute;
  top: 0;
  left: 0;
  height: 2px;
  width: 100px; /* JS scales this to the label width */
  background: var(--yellow);
  border-radius: 1px;
  opacity: 0;
  pointer-events: none;
  transform-origin: left center;
  translate: 0 0;
  scale: 0 1;
  transition: translate 420ms var(--ease-out), scale 420ms var(--ease-out), opacity 200ms ease;
}
.site-nav.has-indicator .nav-link[aria-current="true"] { text-decoration: none; }
.site-nav.has-indicator .nav-indicator { opacity: 1; }

.site-nav .navbar-toggler {
  border: 0;
  padding: 0.25rem 0.4rem;
  font-size: 1.75rem;
  line-height: 1;
  color: var(--ink);
  box-shadow: none;
}
.site-nav .navbar-toggler:focus-visible { outline: 2px solid var(--ink); }
/* Hamburger and close glyph share one cell; the active one fades and turns in */
.toggler-icons {
  display: grid;
  width: 1em;
  height: 1em;
}
.toggler-icons .bi {
  grid-area: 1 / 1;
  display: grid;
  place-items: center;
  transition: opacity 160ms ease, rotate 220ms var(--ease-out);
}
.toggler-icons .bi-x-lg { font-size: 0.8em; opacity: 0; rotate: -45deg; }
.navbar-toggler[aria-expanded="true"] .bi-list { opacity: 0; rotate: 45deg; }
.navbar-toggler[aria-expanded="true"] .bi-x-lg { opacity: 1; rotate: 0deg; }

.nav-social .nav-link { font-size: 1.15rem; }

@media (min-width: 992px) {
  .nav-social { margin-left: 0.5rem; padding-left: 0.75rem; border-left: 1px solid var(--line); }
}
@media (max-width: 991.98px) {
  .site-nav .navbar-collapse { padding-block: 0.5rem 1rem; }
  .site-nav .nav-link { padding-inline: 0; padding-block: 0.55rem; font-size: 1.125rem; }
  .nav-indicator { display: none; }
}

/* ------------------------------------------------------------------
   Hero
   ------------------------------------------------------------------ */

.hero {
  min-height: 100dvh;
  padding-top: calc(var(--nav-h) + 2rem);
  padding-bottom: clamp(2rem, 4vh, 3rem);
  display: flex;
  align-items: flex-start;
  overflow-x: clip;
}
.hero > .container { display: flex; flex-direction: column; gap: clamp(1.5rem, 3.2vw, 2.75rem); }

.hero-title {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-weight: 800;
  text-transform: uppercase;
  font-size: clamp(2.4rem, 7.3vw, 5.6rem);
  line-height: 0.92;
  letter-spacing: -0.035em;
  margin: 0;
}
.hero-line { display: block; }

.hero-copy {
  display: grid;
  gap: 1.5rem;
  justify-items: start;
  align-content: start;
  padding-top: 0.25rem;
}

.hero-lead {
  font-size: clamp(1.125rem, 1.6vw, 1.375rem);
  line-height: 1.45;
  color: var(--ink-2);
  max-width: 38ch;
  margin: 0;
  text-wrap: balance;
}

.hero-figure {
  margin: 0;
  height: clamp(320px, 58vh, 600px);
}
.hero-figure .media { height: 100%; }
.hero-figure figcaption {
  font-size: 0.9rem;
  color: var(--ink-3);
  margin-top: 0.55rem;
  line-height: 1.45;
}
.hero-figure img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 52%;
  display: block;
}

/* Desktop: the photo runs to the right edge of the viewport */
@media (min-width: 992px) {
  .hero-figure { margin-right: calc(-1 * var(--gutter)); }
  .hero-figure .media { border-radius: var(--radius) 0 0 var(--radius); }
}

@media (max-width: 991.98px) {
  .hero { min-height: 0; padding-top: calc(var(--nav-h) + 1.5rem); }
  .hero-figure { height: clamp(260px, 60vw, 380px); }
}

/* Media box: rounded, clipped container for every photo. The curtain (::after)
   lives here so the image element itself is never clipped or moved. */
.media {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--paper-2);
  isolation: isolate;
}
.media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Primary button: pill, yellow surface, ink text.
   translate = magnetic pull (JS sets --mx/--my), transform = press. */
.btn-start {
  --bs-btn-padding-y: 0.95rem;
  --bs-btn-padding-x: 1.6rem;
  --bs-btn-font-size: 1.0625rem;
  --bs-btn-font-weight: 600;
  --bs-btn-color: var(--ink);
  --bs-btn-bg: var(--yellow);
  --bs-btn-border-color: var(--yellow);
  --bs-btn-hover-color: var(--ink);
  --bs-btn-hover-bg: var(--yellow-deep);
  --bs-btn-hover-border-color: var(--yellow-deep);
  --bs-btn-active-color: var(--ink);
  --bs-btn-active-bg: var(--yellow-deep);
  --bs-btn-active-border-color: var(--yellow-deep);
  --bs-btn-focus-box-shadow: none;
  --bs-btn-border-radius: 999px;
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  white-space: nowrap;
  translate: var(--mx, 0px) var(--my, 0px);
  transition: translate 320ms var(--ease-out), transform 160ms var(--ease-out), background-color 160ms ease;
}
.btn-start .bi {
  font-size: 1.1em;
  transition: transform 200ms var(--ease-out);
}
.btn-start:active { transform: scale(0.97); }
.btn-start:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

@media (hover: hover) and (pointer: fine) {
  .btn-start:hover .bi-arrow-right { transform: translateX(3px); }
}

/* ------------------------------------------------------------------
   Story: sticky rail + chapters
   ------------------------------------------------------------------ */

/* Anchor targets rely on the root's scroll-padding alone; a second offset here
   would leave a stripe of the previous section under the nav. */
.story {
  padding-block: clamp(4rem, 8vw, 7rem) clamp(3rem, 6vw, 5rem);
}

.rail {
  position: sticky;
  top: calc(var(--nav-h) + 2rem);
  display: grid;
  gap: 0.5rem;
  padding-bottom: 2rem;
}

.rail-year {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-weight: 800;
  font-size: clamp(4rem, 9vw, 8rem);
  line-height: 1;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  white-space: nowrap;
}
/* Odometer digits: each slot clips, old digit rolls out, new rolls in */
.digit {
  display: inline-block;
  position: relative;
  height: 1em;
  overflow: hidden;
  vertical-align: top;
}
.digit .d { display: inline-block; will-change: transform; }
.digit .d + .d { position: absolute; left: 0; top: 0; }

.rail-label {
  font-size: 1.0625rem;
  color: var(--ink-2);
  min-height: 1.6em;
}

/* Chapter index: every year, the current one marked. Doubles as navigation. */
.rail-index {
  position: relative;
  display: grid;
  margin-top: 1.5rem;
  padding-left: 1.9rem;
}
.rail-index a {
  display: block;
  width: max-content;
  padding-block: 0.3rem;
  font-size: 1rem;
  font-weight: 500;
  line-height: 1.4;
  color: var(--ink-3);
  text-decoration: none;
  font-variant-numeric: tabular-nums;
  transition: color 200ms ease;
}
.rail-index a:hover,
.rail-index a:focus-visible,
.rail-index a[aria-current="true"] { color: var(--ink); }

.rail-marker {
  position: absolute;
  left: 0;
  top: 0;
  width: 1.125rem;
  height: 2rem;
  display: grid;
  align-items: center;
  pointer-events: none;
  translate: 0 0;
  transition: translate 520ms var(--ease-out);
}
.rail-marker::before {
  content: "";
  display: block;
  height: 3px;
  background: var(--yellow);
  border-radius: 2px;
}

/* Stepped progress bar (mobile only, JS-driven) */
.rail-progress {
  display: none;
  height: 2px;
  background: var(--line);
  border-radius: 2px;
  overflow: hidden;
}
.rail-progress span {
  display: block;
  width: 100%;
  height: 100%;
  background: var(--yellow);
  transform-origin: left;
  transform: scaleX(0.2);
  transition: transform 600ms var(--ease-out);
}

@media (max-width: 991.98px) {
  /* The column sticks (its parent row spans all chapters); the rail itself is static. */
  .story .col-lg-4 {
    position: sticky;
    top: var(--nav-h);
    z-index: 5;
  }
  .rail {
    position: static;
    grid-template-columns: auto 1fr;
    align-items: baseline;
    column-gap: 1rem;
    row-gap: 0;
    padding: 0.75rem 0 0;
    margin-bottom: 1.5rem;
    background: var(--paper);
  }
  .rail-year { font-size: 2.25rem; }
  .rail-label { font-size: 0.95rem; }
  .rail-index { display: none; }
  /* The progress track doubles as the bar's bottom rule */
  .rail-progress {
    display: block;
    grid-column: 1 / -1;
    margin-top: 0.6rem;
    width: 100%;
  }
  /* Anchor jumps clear the sticky year bar as well as the nav
     (scoped so it wins over the base .chapter rule declared later) */
  .story .chapter { scroll-margin-top: 4.5rem; }
}

.chapter {
  padding-block: clamp(2rem, 4vw, 3.5rem);
  display: grid;
  gap: clamp(1.5rem, 2.5vw, 2.25rem);
  scroll-margin-top: 8px; /* keeps the chapter's top rule clear of the nav hairline */
}
.chapter + .chapter {
  border-top: 1px solid var(--line);
  margin-top: clamp(1rem, 3vw, 2.5rem);
}

/* Year stays in the document for screen readers; the rail shows it visually. */
.chapter-year {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.chapter-title {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-weight: 700;
  font-size: clamp(1.85rem, 3.2vw, 2.75rem);
  line-height: 1.05;
  letter-spacing: -0.025em;
  margin: 0;
  text-wrap: balance;
  max-width: 22ch;
}

.chapter-body { max-width: 62ch; }
.chapter-body p { margin: 0 0 1rem; color: var(--ink-2); text-wrap: pretty; }
.chapter-body p:last-child { margin-bottom: 0; }
.chapter-body strong { color: var(--ink); }

/* Prologue (2022): no photographs, so the type carries the chapter */
.chapter-prologue { gap: clamp(1.25rem, 2vw, 1.75rem); }
.chapter-prologue .chapter-body { font-size: 1.125rem; max-width: 58ch; }
.pivot {
  margin: 0.5rem 0;
  max-width: 27ch;
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-weight: 700;
  font-size: clamp(1.7rem, 3.4vw, 2.9rem);
  line-height: 1.1;
  letter-spacing: -0.025em;
  text-wrap: balance;
}

.stat {
  display: flex;
  align-items: baseline;
  gap: 0.9rem;
  margin: 0;
  padding-left: 1rem;
  border-left: 1px solid var(--line);
}
.stat-number {
  position: relative;
  z-index: 0;
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-weight: 800;
  font-size: clamp(2.5rem, 4.5vw, 3.5rem);
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  padding-inline: 0.06em;
}
/* Highlighter bar behind the number; draws in on reveal */
.stat-number::after {
  content: "";
  position: absolute;
  z-index: -1;
  left: 0;
  right: 0;
  bottom: 0.02em;
  height: 0.42em;
  background: var(--yellow-soft);
  transform-origin: left;
}
.stat-label { color: var(--ink-2); }

/* Image mosaic */
.mosaic {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 0.75rem;
}
.tile { margin: 0; min-width: 0; }
.tile.framed .media { border: 1px solid var(--line); }
.tile.pos-left img { object-position: left center; }
.tile.pos-top img { object-position: center 12%; }
.tile.pos-face img { object-position: center 55%; }
.tile.pos-demo img { object-position: center 46%; }
.tile.pos-id img { object-position: center 62%; }
.tile.pos-office img { object-position: center 60%; }
.tile.pos-tv img { object-position: center 45%; }
.tile.pos-mid img { object-position: center 38%; }

.tile figcaption {
  font-size: 0.9rem;
  color: var(--ink-3);
  margin-top: 0.55rem;
  line-height: 1.45;
}

.span-12 { grid-column: span 12; }
.span-8 { grid-column: span 8; }
.span-7 { grid-column: span 7; }
.span-6 { grid-column: span 6; }
.span-5 { grid-column: span 5; }
.span-4 { grid-column: span 4; }
.span-3 { grid-column: span 3; }

.ar-16x9 img { aspect-ratio: 16 / 9; }
.ar-5x4 img { aspect-ratio: 5 / 4; }
.ar-strip img { aspect-ratio: 1400 / 308; }
.ar-github img { aspect-ratio: 1024 / 585; }
.ar-16x10 img { aspect-ratio: 16 / 10; }
.ar-21x9 img { aspect-ratio: 21 / 9; }
.ar-4x3 img { aspect-ratio: 4 / 3; }
.ar-7x5 img { aspect-ratio: 7 / 5; }
.ar-4x5 img { aspect-ratio: 4 / 5; }
.ar-2x3 img { aspect-ratio: 2 / 3; }
.ar-1x1 img { aspect-ratio: 1 / 1; }
.ar-8x9 img { aspect-ratio: 8 / 9; }
.ar-graph img { aspect-ratio: 1028 / 249; }

@media (max-width: 767.98px) {
  .span-8, .span-7, .span-6, .span-5 { grid-column: span 12; }
  .span-4, .span-3 { grid-column: span 6; }
  .ar-4x5 img, .ar-8x9 img { aspect-ratio: 4 / 3; }
  .ar-strip img { aspect-ratio: 16 / 9; }
}

/* ------------------------------------------------------------------
   Podcast: the yellow block
   ------------------------------------------------------------------ */

.podcast {
  background: var(--yellow);
  color: var(--ink);
  padding-block: clamp(4rem, 8vw, 7rem);
  overflow: hidden;
  timeline-scope: --reel;
}

.podcast ::selection { background: var(--ink); color: var(--yellow); }

.section-title {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-weight: 800;
  font-size: clamp(2.5rem, 5.6vw, 4.5rem);
  line-height: 0.98;
  letter-spacing: -0.035em;
  margin: 0 0 1rem;
  text-wrap: balance;
  max-width: 16ch;
}
.section-lead {
  font-size: clamp(1.0625rem, 1.4vw, 1.25rem);
  line-height: 1.5;
  max-width: 52ch;
  margin: 0;
  text-wrap: pretty;
}
.podcast .section-lead { color: var(--on-yellow-2); }

.podcast-head {
  display: grid;
  gap: 0.75rem;
  margin-bottom: clamp(2rem, 4vw, 3rem);
}
.reel-controls { display: flex; gap: 0.5rem; margin-top: 0.75rem; }

/* Desktop: arrows sit on the right, on the lead's baseline, where the reel ends */
@media (min-width: 992px) {
  .podcast-head {
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: 2rem;
    align-items: end;
  }
  .podcast-head .section-title,
  .podcast-head .section-lead { grid-column: 1; }
  .podcast-head .reel-controls {
    grid-column: 2;
    grid-row: 1 / span 2;
    margin: 0 0 0.25rem;
  }
}

.reel-btn {
  width: 46px;
  height: 46px;
  border-radius: 999px;
  border: 1.5px solid var(--ink);
  background: transparent;
  color: var(--ink);
  display: inline-grid;
  place-items: center;
  font-size: 1.15rem;
  transition: transform 160ms var(--ease-out), background-color 160ms ease, color 160ms ease, opacity 160ms ease;
}
.reel-btn:active { transform: scale(0.95); }
.reel-btn:disabled { opacity: 0.35; cursor: default; }
@media (hover: hover) and (pointer: fine) {
  .reel-btn:not(:disabled):hover { background: var(--ink); color: var(--yellow); }
}

.reel {
  list-style: none;
  margin: 0;
  padding: 0.5rem var(--gutter) 1rem;
  display: flex;
  gap: clamp(0.75rem, 1.5vw, 1.25rem);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--gutter);
  scroll-timeline-name: --reel;
  scroll-timeline-axis: inline;
  scrollbar-width: none;
  cursor: grab;
}
.reel::-webkit-scrollbar { display: none; }
.reel.is-dragging {
  cursor: grabbing;
  scroll-snap-type: none;
  user-select: none;
}
.reel.is-dragging .zoom { pointer-events: none; }

/* Scroll-driven progress under the reel; native scrollbar returns where unsupported */
.reel-progress {
  display: none;
  margin: 0.25rem var(--gutter) 0;
  height: 2px;
  background: rgba(22, 21, 18, 0.16);
  border-radius: 2px;
  overflow: hidden;
}
.reel-progress span {
  display: block;
  width: 25%;
  height: 100%;
  background: var(--ink);
  border-radius: 2px;
}
@supports (animation-timeline: scroll()) {
  .reel-progress { display: block; }
  .reel-progress span {
    animation: reel-thumb linear both;
    animation-timeline: --reel;
  }
  @keyframes reel-thumb {
    from { transform: translateX(0); }
    to   { transform: translateX(300%); }
  }
}
@supports not (animation-timeline: scroll()) {
  .reel { scrollbar-width: thin; scrollbar-color: var(--ink) transparent; }
  .reel::-webkit-scrollbar { display: block; height: 6px; }
  .reel::-webkit-scrollbar-thumb { background: var(--ink); border-radius: 999px; }
  .reel::-webkit-scrollbar-track { background: transparent; }
}

.ep {
  flex: 0 0 auto;
  width: clamp(272px, 30vw, 420px);
  scroll-snap-align: start;
}
.ep figure { margin: 0; }
.ep .zoom {
  border-radius: var(--radius);
  transition: transform 220ms var(--ease-out);
}
.ep img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: var(--radius);
  display: block;
  background: var(--paper);
  box-shadow: 0 1px 2px rgba(60, 44, 0, 0.18), 0 12px 28px -12px rgba(60, 44, 0, 0.35);
  transition: box-shadow 220ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .ep:hover .zoom { transform: translateY(-4px); }
  .ep:hover img { box-shadow: 0 2px 4px rgba(60, 44, 0, 0.18), 0 22px 36px -14px rgba(60, 44, 0, 0.4); }
}
.ep figcaption {
  display: grid;
  gap: 0.1rem;
  padding: 0.85rem 0.25rem 0;
}
.ep-num {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--on-yellow-2);
  font-variant-numeric: tabular-nums;
}
.ep-name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.2rem;
  letter-spacing: -0.015em;
  line-height: 1.2;
}
.ep-role { font-size: 0.95rem; color: var(--on-yellow-2); line-height: 1.4; }

/* ------------------------------------------------------------------
   Lessons
   ------------------------------------------------------------------ */

.lessons {
  background: var(--paper-2);
  padding-block: clamp(4rem, 8vw, 7rem);
}
.lessons-head { margin-bottom: clamp(2rem, 4vw, 3.5rem); }
.lessons .section-title { max-width: 18ch; }
.lessons .section-lead { color: var(--ink-2); }

.lesson-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.lesson {
  padding-block: clamp(1.5rem, 3vw, 2.25rem);
  display: grid;
  gap: 0.5rem 3rem;
}
.lesson + .lesson { border-top: 1px solid var(--line); }

/* Desktop: claim on the left, proof on the right, first lines aligned */
@media (min-width: 992px) {
  .lesson {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    align-items: start;
  }
  .lesson-proof { padding-top: 0.75rem; }
}

.lesson-claim {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-weight: 700;
  font-size: clamp(1.5rem, 2.7vw, 2.25rem);
  line-height: 1.12;
  letter-spacing: -0.025em;
  margin: 0;
  text-wrap: balance;
}
.lesson-proof {
  margin: 0;
  color: var(--ink-2);
  max-width: 52ch;
  text-wrap: pretty;
}

.lessons-cta { margin-top: clamp(2rem, 4vw, 3rem); }

/* ------------------------------------------------------------------
   Footer
   ------------------------------------------------------------------ */

.site-footer {
  padding-block: 3rem 2rem;
  border-top: 1px solid var(--line);
}
.footer-name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.25rem;
  letter-spacing: -0.015em;
  margin: 0 0 0.25rem;
}
.footer-role { margin: 0; color: var(--ink-2); max-width: 48ch; }

.footer-links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.75rem;
}
@media (min-width: 992px) { .footer-links { justify-content: flex-end; } }
.footer-links a {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 500;
  padding-block: 0.25rem;
  text-decoration: underline;
  text-decoration-color: transparent;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.3em;
}
.footer-links a:hover,
.footer-links a:focus-visible { text-decoration-color: var(--yellow); }

.footer-note {
  margin: 2.5rem 0 0;
  font-size: 0.9rem;
  color: var(--ink-3);
}

/* ------------------------------------------------------------------
   The wipe: the one authored moment (Start button)
   ------------------------------------------------------------------ */

.wipe {
  position: fixed;
  inset: 0;
  z-index: 1050;
  background: var(--yellow);
  pointer-events: none;
  opacity: 0;
  display: grid;
  place-items: center;
}
.wipe.is-active { pointer-events: auto; opacity: 1; }
.wipe-year {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-weight: 800;
  font-size: clamp(5rem, 20vw, 15rem);
  line-height: 1;
  letter-spacing: -0.05em;
  color: var(--ink);
  opacity: 0;
}

/* ------------------------------------------------------------------
   Clickable photos. Every image is a link to its full-size file (the
   no-JS fallback); with JS the link opens the viewer below instead.
   ------------------------------------------------------------------ */

.zoom {
  position: relative;
  display: block;
  height: 100%;
  border-radius: inherit;
  cursor: zoom-in;
  -webkit-tap-highlight-color: transparent;
}
/* Focus ring drawn above the photo (the transformed image would paint over an outline) */
.zoom::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  border-radius: inherit;
  box-shadow: inset 0 0 0 3px var(--yellow);
  opacity: 0;
  pointer-events: none;
}
.zoom:focus-visible { outline: none; }
.zoom:focus-visible::after { opacity: 1; }
/* Expand glyph, bottom right, on hover (fine pointers only; injected by JS) */
.zoom-hint {
  position: absolute;
  right: 0.6rem;
  bottom: 0.6rem;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  background: var(--paper);
  color: var(--ink);
  font-size: 0.9rem;
  box-shadow: 0 1px 2px rgba(22, 21, 18, 0.14), 0 8px 18px -8px rgba(22, 21, 18, 0.35);
  opacity: 0;
  scale: 0.9;
  pointer-events: none;
  transition: opacity 160ms ease, scale 220ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .zoom:hover .zoom-hint,
  .zoom:focus-visible .zoom-hint { opacity: 1; scale: 1; }
}

/* Page behind the viewer: no scrolling, no layout shift from the lost scrollbar */
html.lb-open { overflow: hidden; scroll-behavior: auto; }
html.lb-open body,
html.lb-open .site-nav { padding-right: var(--sbw, 0px); }

/* ------------------------------------------------------------------
   Image viewer: a native <dialog>. The photo morphs out of its tile
   and back into it (JS, Web Animations); the scrim and chrome fade
   with CSS. Dark scrim by design: the photos need the contrast.
   ------------------------------------------------------------------ */

.lightbox {
  --lb-top: 76px;     /* room for the close button */
  --lb-side: 96px;    /* room for the arrows */
  --lb-bottom: 92px;  /* the caption bar */
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--paper);
  overflow: hidden;
}
.lightbox::backdrop { background: transparent; }
.lightbox:focus-visible { outline: none; } /* focus rests on the viewer itself; the controls show their own rings */
.lightbox ::selection { background: var(--yellow); color: var(--ink); }

.lb-scrim {
  position: absolute;
  inset: 0;
  background: rgba(22, 21, 18, 0.96);
  opacity: 0;
  transition: opacity 360ms var(--ease-out);
}
.lightbox.is-open .lb-scrim { opacity: 1; }
.lightbox.is-closing .lb-scrim { opacity: 0; transition-duration: 300ms; }
.lightbox.is-dragging .lb-scrim { transition: none; }

.lb-stage {
  position: absolute;
  inset: 0;
  padding: var(--lb-top) var(--lb-side) var(--lb-bottom);
  touch-action: none; /* swipe, pinch and pan are handled in JS */
  cursor: default;
}
.lb-fit {
  position: relative;
  width: 100%;
  height: 100%;
  display: grid;
  place-items: center;
}
.lb-figure {
  position: relative;
  margin: 0;
  clip-path: inset(0px 0px 0px 0px round 6px);
  transform-origin: center;
  will-change: transform;
  cursor: zoom-in;
}
.lb-figure.is-zoomed { cursor: grab; }
.lb-figure.is-panning,
.lb-figure.is-dragging { cursor: grabbing; }
.lb-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  user-select: none;
  -webkit-user-drag: none;
}

/* Hairline at the top while the sharper file is on its way */
.lb-progress {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  overflow: hidden;
  opacity: 0;
  transition: opacity 200ms ease;
}
.lb-progress span {
  display: block;
  width: 30%;
  height: 100%;
  background: var(--yellow);
  border-radius: 2px;
  transform: translateX(-100%);
}
.lightbox.is-loading .lb-progress { opacity: 1; }
.lightbox.is-loading .lb-progress span { animation: lb-indeterminate 1100ms var(--ease-in-out) infinite; }
@keyframes lb-indeterminate {
  from { transform: translateX(-100%); }
  to   { transform: translateX(334%); }
}

/* Chrome: the same pill buttons as the reel, inverted for the scrim */
.lb-btn {
  width: 46px;
  height: 46px;
  border-radius: 999px;
  border: 1.5px solid rgba(255, 255, 255, 0.5);
  background: transparent;
  color: var(--paper);
  display: inline-grid;
  place-items: center;
  font-size: 1.15rem;
  transition: transform 160ms var(--ease-out), background-color 160ms ease, color 160ms ease, border-color 160ms ease, opacity 160ms ease;
}
.lb-btn:active { transform: scale(0.95); }
.lb-btn:disabled { opacity: 0.3; cursor: default; }
.lb-btn:focus-visible { outline: 2px solid var(--yellow); outline-offset: 3px; }
@media (hover: hover) and (pointer: fine) {
  .lb-btn:not(:disabled):hover { background: var(--paper); color: var(--ink); border-color: var(--paper); }
}
.lb-close { position: absolute; top: 15px; right: 18px; }
.lb-prev,
.lb-next {
  position: fixed;
  top: 50%;
  translate: 0 -50%;
}
.lb-prev { left: 24px; }
.lb-next { right: 24px; }

.lb-close,
.lb-bar { opacity: 0; transition: opacity 260ms ease; }
.lightbox.is-open .lb-close,
.lightbox.is-open .lb-bar { opacity: 1; transition-delay: 180ms; }
.lightbox.is-closing .lb-close,
.lightbox.is-closing .lb-bar { opacity: 0; transition: opacity 140ms ease; }

.lb-bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  min-height: var(--lb-bottom);
  padding: 1rem var(--lb-side) 1.25rem;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.5rem;
}
.lb-caption {
  margin: 0;
  display: grid;
  gap: 0.2rem;
  max-width: 64ch;
  font-size: 0.95rem;
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.84);
  text-wrap: pretty;
}
.lb-label {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.85rem;
  letter-spacing: 0.01em;
  color: var(--yellow);
  font-variant-numeric: tabular-nums;
}
.lb-label:empty { display: none; }
.lb-tools {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-shrink: 0;
}
.lb-count {
  margin: 0;
  font-size: 0.9rem;
  color: rgba(255, 255, 255, 0.62);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.lb-count:empty { display: none; }

@media (max-width: 767.98px) {
  .lightbox { --lb-top: 64px; --lb-side: 12px; --lb-bottom: 132px; }
  .lb-close { top: 10px; right: 12px; }
  .lb-bar {
    flex-direction: column;
    align-items: stretch;
    gap: 0.75rem;
    padding: 0.75rem 1rem calc(1rem + env(safe-area-inset-bottom, 0px));
  }
  .lb-caption { font-size: 0.9rem; max-width: none; }
  .lb-text {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .lb-prev,
  .lb-next { position: static; translate: none; width: 44px; height: 44px; }
  .lb-count { margin-right: auto; }
}

/* ------------------------------------------------------------------
   Motion: hidden states and entrances.
   Gated on html.js (set before first paint, dropped if main.js never
   reports in) and on the visitor not preferring reduced motion.
   ------------------------------------------------------------------ */

@media (prefers-reduced-motion: no-preference) {

  /* Nav settles in */
  .js .site-nav { animation: nav-in 700ms var(--ease-out) both; }
  @keyframes nav-in {
    from { opacity: 0; translate: 0 -6px; }
    to   { opacity: 1; translate: 0 0; }
  }

  /* Plain fade-up: paragraphs, stats, buttons, lesson rows */
  .js [data-reveal=""] {
    opacity: 0;
    translate: 0 18px;
    transition: opacity 700ms var(--ease-out), translate 700ms var(--ease-out);
    transition-delay: calc(var(--i, 0) * 70ms);
  }
  .js [data-reveal=""].is-in { opacity: 1; translate: 0 0; }

  /* Words rise one by one inside their clipped wrappers */
  .js [data-reveal="words"] .wi {
    translate: 0 112%;
    transition: translate 800ms var(--ease-out);
    transition-delay: calc(var(--w, 0) * 45ms);
  }
  .js [data-reveal="words"].is-in .wi { translate: 0 0; }

  /* Media: curtain slides down and off; the photo settles from a slight zoom */
  .js [data-reveal="media"] .media::after {
    content: "";
    position: absolute;
    inset: -1px;
    z-index: 2;
    background: var(--paper);
    transform-origin: bottom;
    transition: transform 900ms var(--ease-in-out);
    transition-delay: calc(var(--i, 0) * 90ms);
  }
  .js [data-reveal="media"].is-in .media::after { transform: scaleY(0); }
  .js [data-reveal="media"] .media img {
    scale: 1.14;
    transition: scale 1500ms var(--ease-out);
    transition-delay: calc(var(--i, 0) * 90ms);
  }
  .js [data-reveal="media"].is-in .media img { scale: 1; }
  /* Captions follow the photo, once the curtain is mostly off */
  .js [data-reveal="media"] figcaption {
    opacity: 0;
    transition: opacity 500ms ease;
    transition-delay: calc(var(--i, 0) * 90ms + 450ms);
  }
  .js [data-reveal="media"].is-in figcaption { opacity: 1; }
  /* The viewer may land on a tile that has not scrolled into view yet: reveal it at once */
  .js [data-reveal="media"].is-instant .media::after,
  .js [data-reveal="media"].is-instant .media img,
  .js [data-reveal="media"].is-instant figcaption { transition-duration: 0ms; transition-delay: 0ms; }

  /* Large photos keep a little zoom and drift with the scroll (CSS only) */
  @supports (animation-timeline: view()) {
    .js .hero-figure.is-in .media img,
    .js .tile.span-8.is-in:not(.framed) .media img,
    .js .tile.span-12.is-in:not(.framed) .media img,
    .js .tile.span-7.is-in:not(.framed) .media img { scale: 1.1; }

    .js .hero-figure .media img,
    .js .tile.span-8:not(.framed) .media img,
    .js .tile.span-12:not(.framed) .media img,
    .js .tile.span-7:not(.framed) .media img {
      animation: drift linear both;
      animation-timeline: view();
      animation-range: entry 0% exit 100%;
    }
    @keyframes drift {
      from { translate: 0 -4.5%; }
      to   { translate: 0 4.5%; }
    }
  }

  /* Reel posters slide in from the right, one after another */
  .js [data-reveal="list"] .ep {
    opacity: 0;
    translate: 40px 0;
    transition: opacity 700ms var(--ease-out), translate 700ms var(--ease-out);
    transition-delay: calc(var(--i, 0) * 60ms);
  }
  .js [data-reveal="list"].is-in .ep { opacity: 1; translate: 0 0; }

  /* Highlighters draw in after their text has landed */
  .js .stat-number::after {
    transform: scaleX(0);
    transition: transform 700ms var(--ease-out) 350ms;
  }
  .js .stat.is-in .stat-number::after { transform: scaleX(1); }

  .js .hl::after {
    transform: scaleX(0);
    transition: transform 600ms var(--ease-out) 300ms;
  }
  .js .is-in .hl::after { transform: scaleX(1); }
}

@media (prefers-reduced-motion: reduce) {
  .rail-progress span, .rail-marker, .nav-indicator { transition: none; }
  .ep img, .ep .zoom, .reel-btn, .btn-start, .lb-btn, .zoom-hint { transition: none; }
  .btn-start { translate: 0 0; }
  /* The viewer keeps its fades (they aid comprehension) but drops the delays and the loading sweep */
  .lb-scrim, .lb-close, .lb-bar { transition-duration: 160ms; transition-delay: 0ms; }
  .lightbox.is-loading .lb-progress span { animation: none; transform: none; width: 100%; opacity: 0.6; }
}
