/* ==========================================================================
   Ayaan Agarwal, Portfolio
   Design tokens
   ========================================================================== */

:root {
  /* Canvas, cooled to a neutral paper */
  --bone:        #F2F2F0;
  --bone-2:      #E5E5E2;
  --paper:       #FAFAF9;

  /* Ink */
  --ink:         #1A1A18;
  --ink-2:       #3C3C38;
  --ink-3:       #6E6E68;
  --rule:        rgba(26, 26, 24, 0.14);
  --rule-soft:   rgba(26, 26, 24, 0.07);

  /* Accent: warm cream against the cool paper */
  --accent:      #6E5C3E;
  --accent-soft: rgba(176, 148, 96, 0.16);

  /* Type
     --display is the title face. Code Pro is not a webfont service font, so
     it is self-hosted from assets/fonts (see the @font-face block below);
     Jost is the closest free geometric fallback until those files are added. */
  --display: "Code Pro", "Jost", "Instrument Serif", "Times New Roman", serif;
  --sans:    "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --mono:    "JetBrains Mono", ui-monospace, "SFMono-Regular", monospace;

  /* Scale */
  --step--1: clamp(0.78rem, 0.76rem + 0.1vw, 0.84rem);
  --step-0:  clamp(0.96rem, 0.92rem + 0.2vw, 1.06rem);
  --step-1:  clamp(1.2rem, 1.1rem + 0.5vw, 1.45rem);
  --step-2:  clamp(1.6rem, 1.35rem + 1.2vw, 2.4rem);
  --step-3:  clamp(2.2rem, 1.6rem + 3vw, 4rem);
  --step-4:  clamp(3rem, 1.6rem + 6.5vw, 8.5rem);

  /* Layout */
  --gutter: clamp(1.25rem, 4vw, 5rem);
  --maxw: 1440px;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bone:      #121211;
    --bone-2:    #1C1C1A;
    --paper:     #171716;
    --ink:       #EDEDE8;
    --ink-2:     #C2C2BA;
    --ink-3:     #8A8A82;
    --rule:      rgba(237, 237, 232, 0.16);
    --rule-soft: rgba(237, 237, 232, 0.08);
    --accent:      #CDB489;
    --accent-soft: rgba(205, 180, 137, 0.15);
  }
}
:root[data-theme="dark"] {
  --bone:      #121211;
  --bone-2:    #1C1C1A;
  --paper:     #171716;
  --ink:       #EDEDE8;
  --ink-2:     #C2C2BA;
  --ink-3:     #8A8A82;
  --rule:      rgba(237, 237, 232, 0.16);
  --rule-soft: rgba(237, 237, 232, 0.08);
  --accent:      #CDB489;
  --accent-soft: rgba(205, 180, 137, 0.15);
}

/* ==========================================================================
   Base
   ========================================================================== */

/* ==========================================================================
   Code Pro, the title face

   Code Pro is a licensed retail font, not a webfont-service one, so it has to
   be self-hosted. Drop the woff2/woff files into assets/fonts/ under the names
   below and every title picks them up. Until then the stack falls through to
   Jost, which is the nearest free geometric.
   ========================================================================== */

@font-face {
  font-family: "Code Pro";
  src: url("../fonts/CodePro-Light.woff2") format("woff2"),
       url("../fonts/CodePro-Light.woff")  format("woff");
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Code Pro";
  src: url("../fonts/CodePro-Regular.woff2") format("woff2"),
       url("../fonts/CodePro-Regular.woff")  format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Code Pro";
  src: url("../fonts/CodePro-Bold.woff2") format("woff2"),
       url("../fonts/CodePro-Bold.woff")  format("woff");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--bone);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--step-0);
  line-height: 1.65;
  font-feature-settings: "kern", "liga", "calt";
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

a { color: inherit; }

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 400;
  line-height: 1.02;
  letter-spacing: -0.02em;
  margin: 0;
}

p { margin: 0 0 1.1em; max-width: 68ch; }

::selection { background: var(--ink); color: var(--bone); }

.shell {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Visually hidden, still read aloud. The page's real <h1> lives here now
   that the hero is gone. */
.vh {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip {
  position: absolute; left: -9999px;
  background: var(--ink); color: var(--bone);
  padding: 0.75rem 1rem; z-index: 999;
}
.skip:focus { left: 1rem; top: 1rem; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* ==========================================================================
   Nav
   ========================================================================== */

.nav {
  position: sticky; top: 0; z-index: 100;
  background: color-mix(in srgb, var(--bone) 86%, transparent);
  backdrop-filter: saturate(160%) blur(14px);
  border-bottom: 1px solid var(--rule-soft);
}
.nav__in {
  display: flex; align-items: center; gap: 1.5rem;
  min-height: 68px;
}
.nav__mark {
  font-family: var(--display);
  font-size: var(--step-1);
  letter-spacing: -0.02em;
  text-decoration: none;
  margin-right: auto;
  white-space: nowrap;
}
.nav__mark span { color: var(--accent); }

.nav__links { display: flex; gap: 1.75rem; align-items: center; }
.nav__links a {
  font-size: var(--step--1);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink-2);
  position: relative;
  padding-block: 0.4rem;
  transition: color 0.3s var(--ease);
}
.nav__links a::after {
  content: ""; position: absolute; left: 0; bottom: 0;
  width: 100%; height: 1px; background: currentColor;
  transform: scaleX(0); transform-origin: right;
  transition: transform 0.45s var(--ease);
}
.nav__links a:hover, .nav__links a[aria-current] { color: var(--ink); }
.nav__links a:hover::after, .nav__links a[aria-current]::after {
  transform: scaleX(1); transform-origin: left;
}

.nav__toggle {
  display: none;
  background: none; border: 1px solid var(--rule);
  color: inherit; border-radius: 99px;
  padding: 0.5rem 0.9rem; cursor: pointer;
  font: inherit; font-size: var(--step--1);
  letter-spacing: 0.06em; text-transform: uppercase;
}

.theme-btn {
  background: none; border: 1px solid var(--rule); color: inherit;
  width: 34px; height: 34px; border-radius: 99px; cursor: pointer;
  display: grid; place-items: center; flex: none;
  transition: border-color 0.3s var(--ease), transform 0.3s var(--ease);
}
.theme-btn:hover { border-color: var(--ink); transform: rotate(-20deg); }

@media (max-width: 860px) {
  .nav__toggle { display: inline-block; }
  .nav__links {
    position: fixed; inset: 68px 0 auto 0;
    flex-direction: column; align-items: flex-start;
    gap: 0; padding: 1rem var(--gutter) 2rem;
    background: var(--bone);
    border-bottom: 1px solid var(--rule);
    transform: translateY(-120%);
    transition: transform 0.5s var(--ease);
  }
  .nav__links[data-open="true"] { transform: translateY(0); }
  .nav__links a { font-size: var(--step-1); text-transform: none; letter-spacing: 0; padding-block: 0.7rem; width: 100%; }
}

/* ==========================================================================
   Hero
   ========================================================================== */

.hero {
  min-height: calc(100svh - 68px);
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: center;
  padding-block: clamp(2.5rem, 6vw, 5rem);
}

.hero__name {
  font-size: var(--step-4);
  line-height: 0.88;
  margin-bottom: 1.5rem;
}
.hero__name em { font-style: italic; color: var(--accent); }

.hero__eyebrow {
  font-family: var(--mono);
  font-size: var(--step--1);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 1.75rem;
  display: flex; align-items: center; gap: 0.75rem;
}
.hero__eyebrow::after {
  content: ""; height: 1px; flex: 1; background: var(--rule); max-width: 140px;
}

/* Rotating word / image pairs */
.rotator { display: flex; flex-wrap: wrap; gap: 0.6rem 1.1rem; align-items: baseline; }
.rot-word {
  font-family: var(--display);
  font-size: var(--step-2);
  color: var(--ink-3);
  background: none; border: 0; padding: 0; cursor: pointer;
  letter-spacing: -0.01em;
  transition: color 0.5s var(--ease), opacity 0.5s var(--ease);
  position: relative;
}
.rot-word::after {
  content: ""; position: absolute; left: 0; bottom: -4px; height: 1px; width: 100%;
  background: var(--accent); transform: scaleX(0); transform-origin: left;
  transition: transform 0.6s var(--ease);
}
.rot-word[aria-selected="true"] { color: var(--ink); }
.rot-word[aria-selected="true"]::after { transform: scaleX(1); }
.rot-sep { color: var(--ink-3); font-family: var(--display); font-size: var(--step-2); }

.hero__actions { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 2.5rem; }

/* Image frame */
.frame {
  position: relative;
  aspect-ratio: 4 / 5;
  background: var(--bone-2);
  border: 1px solid var(--rule-soft);
  overflow: hidden;
}
.frame__stack { position: absolute; inset: 0; }
.frame__stack figure {
  position: absolute; inset: 0; margin: 0;
  opacity: 0; transform: scale(1.06);
  transition: opacity 1s var(--ease), transform 1.6s var(--ease);
}
.frame__stack figure[data-active="true"] { opacity: 1; transform: scale(1); }
.frame__stack img {
  width: 100%; height: 100%; object-fit: cover;
  filter: grayscale(1) contrast(1.04);
}
.frame__caption {
  position: absolute; left: 0; bottom: 0; right: 0;
  padding: 1.5rem 1.25rem 1.1rem;
  background: linear-gradient(to top, rgba(0,0,0,0.65), transparent);
  color: #fff;
  font-family: var(--mono);
  font-size: var(--step--1);
  letter-spacing: 0.16em; text-transform: uppercase;
}

/* Placeholder look for missing images */
.ph {
  width: 100%; height: 100%;
  display: grid; place-items: center;
  background:
    repeating-linear-gradient(45deg, var(--rule-soft) 0 1px, transparent 1px 11px),
    var(--bone-2);
  color: var(--ink-3);
  font-family: var(--mono); font-size: var(--step--1);
  letter-spacing: 0.1em; text-align: center; padding: 1rem;
  text-transform: uppercase;
}

/* The hero this block styled is gone. Its .frame override survived and was
   still clamping the About portrait's height at narrow widths, which broke
   the aspect ratio by squashing the picture against a full-width column. */

/* ==========================================================================
   Buttons
   ========================================================================== */

.btn {
  display: inline-flex; align-items: center; gap: 0.55rem;
  font-size: var(--step--1); letter-spacing: 0.1em; text-transform: uppercase;
  font-family: var(--mono);
  text-decoration: none;
  padding: 0.85rem 1.4rem;
  border: 1px solid var(--ink);
  border-radius: 99px;
  background: transparent; color: var(--ink);
  cursor: pointer;
  transition: background 0.4s var(--ease), color 0.4s var(--ease), transform 0.3s var(--ease);
}
.btn:hover { background: var(--ink); color: var(--bone); transform: translateY(-2px); }
.btn--solid { background: var(--ink); color: var(--bone); }
.btn--solid:hover { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn--ghost { border-color: var(--rule); color: var(--ink-2); }
.btn--ghost:hover { border-color: var(--ink); background: transparent; color: var(--ink); transform: translateY(-2px); }

/* ==========================================================================
   Sections
   ========================================================================== */

/* One divider rule between every pair of sections. The first section on the
   page carries none, so nothing sits directly under the nav border. */
.section { padding-block: clamp(4rem, 10vw, 9rem); border-top: 1px solid var(--rule); scroll-margin-top: 68px; }
.section--flush, .section:first-of-type { border-top: 0; }

/* The landing section. It sits directly under the nav with no heading above
   it, so the tall section padding would read as the page failing to start. */
.section--home {
  border-top: 0;
  padding-top: clamp(1.5rem, 3vw, 2.75rem);
  padding-bottom: clamp(3rem, 7vw, 6rem);
}

.section__head {
  display: grid; grid-template-columns: auto 1fr; gap: 1.25rem;
  align-items: baseline; margin-bottom: clamp(2rem, 5vw, 4rem);
}
.section__num {
  font-family: var(--mono); font-size: var(--step-2);
  font-weight: 500; line-height: 1;
  color: var(--accent); letter-spacing: 0.06em;
}
.section__title { font-size: var(--step-3); }
.section__lede { color: var(--ink-2); font-size: var(--step-1); max-width: 56ch; margin: 1.25rem 0 0; }

/* About */
.about { display: grid; grid-template-columns: 0.8fr 1.2fr; gap: clamp(2rem, 6vw, 5rem); align-items: start; }
/* The portrait is sized from the viewport, not from the column width, so the
   Inquirer / Creator / Advocate line under it lands above the fold on a
   laptop instead of below it. Height is the definite dimension and the width
   follows from the aspect ratio, so the crop never changes; justify-self lets
   the column shrink to whatever width that leaves. */
.about__media { position: sticky; top: 88px; }
.about .frame {
  aspect-ratio: 3 / 4;
  /* Width is the definite dimension and height follows from the ratio, so the
     crop is never squashed. The width asked for is whatever a 56svh-tall
     portrait would need; on a narrow screen the column is smaller than that
     and wins instead. */
  width: min(100%, calc(min(56svh, 560px) * 3 / 4));
  height: auto;
  margin-inline: auto;
}
.about__trio {
  font-family: var(--display);
  /* Sized to sit on one line under the portrait; it reads as a single phrase
     and breaking it across two lines loses that. */
  font-size: clamp(1.1rem, 1.85vw, 1.7rem);
  white-space: nowrap;
  line-height: 1.15;
  letter-spacing: -0.01em;
  text-align: center;
  color: var(--ink);
  margin: 1.25rem 0 0;
  max-width: none;
}
.about__trio span { color: var(--accent); padding-inline: 0.15em; }
.about__body p { font-size: var(--step-1); line-height: 1.6; color: var(--ink-2); }
.about__body > p:first-child { margin-top: -0.35em; }
.about__body p:first-of-type { color: var(--ink); }
@media (max-width: 900px) {
  .about { grid-template-columns: 1fr; }
  .about__media { position: static; }
}

/* Entry (research / project block) */
.entry {
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: clamp(1.5rem, 4vw, 3.5rem);
  padding-block: clamp(2.5rem, 6vw, 4.5rem);
  border-top: 1px solid var(--rule-soft);
}
.entry:first-of-type { border-top: 0; }
.entry__meta { display: flex; flex-direction: column; gap: 1rem; }
.entry__index { font-family: var(--mono); font-size: var(--step-2); font-weight: 500; line-height: 1; color: var(--accent); letter-spacing: 0.06em; }
.entry__tag {
  font-family: var(--mono); font-size: var(--step--1); letter-spacing: 0.08em;
  color: var(--ink-3); text-transform: uppercase;
}
/* Partner and publication marks in the left rail.

   Two of these - IJHSR and Doctors For You - are dark artwork on a
   transparent ground, so on the dark canvas they were painting near-black on
   near-black and reading as a missing image. They get inverted there; the
   rest carry a light background of their own and are left alone. */
/* Logos are reproduced as issued - no grayscale, no fading. A partner's mark
   is their property, not a design element to retint. */
.entry__logo { max-width: 120px; }
.entry__logo--md { max-width: 130px; }
.entry__logo--lg { max-width: 150px; }

/* Nothing is painted behind a logo by default. Marks with a transparent
   ground stay transparent and sit straight on the canvas - Hebbian and
   Doctors For You included, even though they are dark artwork.

   IJHSR is the one exception, opted in per-logo below. Its navy is the
   darkest of the set and disappears completely on the dark canvas. The plate
   is applied in dark mode only: in light mode the page is already near-white,
   so a white box there would just draw a pale rectangle around the mark. */
.entry__logo--plate { border-radius: 3px; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .entry__logo--plate {
    background: #FFFFFF;
    padding: 0.5rem 0.6rem;
  }
}
:root[data-theme="dark"] .entry__logo--plate {
  background: #FFFFFF;
  padding: 0.5rem 0.6rem;
}

.entry__title { font-size: var(--step-2); margin-bottom: 0.9rem; }
.entry__title a { text-decoration: none; background-image: linear-gradient(var(--accent), var(--accent)); background-size: 0% 1px; background-repeat: no-repeat; background-position: 0 100%; transition: background-size 0.5s var(--ease); }
.entry__title a:hover { background-size: 100% 1px; color: var(--accent); }
.entry__abstract { color: var(--ink-2); }

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

/* Abstract disclosure */
.abstract { margin: 1.75rem 0; }
/* Sized as a proper button, since this is the main way into each paper. */
.abstract > summary {
  cursor: pointer; list-style: none;
  font-family: var(--mono); font-size: var(--step-0);
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-2);
  display: inline-flex; align-items: center; gap: 0.8rem;
  padding: 0.9rem 1.5rem;
  border: 1px solid var(--rule); border-radius: 99px;
  background: var(--paper);
  transition: color 0.3s var(--ease), background 0.4s var(--ease), border-color 0.3s var(--ease), transform 0.3s var(--ease);
}
.abstract > summary::-webkit-details-marker { display: none; }
.abstract > summary:hover { color: var(--bone); background: var(--ink); border-color: var(--ink); transform: translateY(-2px); }
.abstract > summary::after { content: "+"; font-size: 1.25em; line-height: 1; transition: transform 0.4s var(--ease); }
.abstract[open] > summary::after { transform: rotate(45deg); }
.abstract__body { margin-top: 1.25rem; border-left: 2px solid var(--rule); padding-left: 1.25rem; color: var(--ink-2); font-size: var(--step-0); }

/* Award / logo chips */
.chips { display: flex; flex-wrap: wrap; gap: 0.6rem; margin: 1.5rem 0 0; padding: 0; list-style: none; }
.chip {
  display: inline-flex; align-items: center; gap: 0.5rem;
  border: 1px solid var(--rule); border-radius: 99px;
  padding: 0.45rem 0.9rem;
  font-size: var(--step--1); color: var(--ink-2);
  background: var(--paper);
}
.chip img { width: 18px; height: 18px; object-fit: contain; border-radius: 3px; }
.chip--award { border-color: var(--accent-soft); background: var(--accent-soft); color: var(--accent); }

/* TB Pathshala intro film, set beside the opening prose rather than under
   it: the text column stops at 68ch and left a dead half-width otherwise. */
.tbp-lede {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: start;
}
.tbp-lede__text > p:last-child { margin-bottom: 0; }
.tbp-lede__video { margin: 0; }
.tbp-lede__video video {
  width: 100%; height: auto; display: block;
  aspect-ratio: 16 / 9;
  background: #000;
  border: 1px solid var(--rule-soft);
}
.tbp-lede__video figcaption {
  font-family: var(--mono); font-size: var(--step--1);
  color: var(--ink-3); margin-top: 0.7rem; letter-spacing: 0.04em;
}
@media (max-width: 860px) {
  .tbp-lede { grid-template-columns: 1fr; }
}

/* Stat row */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 1px; background: var(--rule-soft); border: 1px solid var(--rule-soft); margin: 2rem 0; }
.stat { background: var(--bone); padding: 1.5rem 1.25rem; }
.stat__n { font-family: var(--display); font-size: var(--step-2); line-height: 1; display: block; }
.stat__l { font-family: var(--mono); font-size: var(--step--1); color: var(--ink-3); letter-spacing: 0.08em; text-transform: uppercase; margin-top: 0.6rem; display: block; }

/* Media grid */
.grid { display: grid; gap: 1rem; margin-top: 2rem; }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }

.shot { margin: 0; }
.shot__img { position: relative; aspect-ratio: 4 / 3; overflow: hidden; background: var(--bone-2); border: 1px solid var(--rule-soft); }
.shot__img img { width: 100%; height: 100%; object-fit: cover; filter: grayscale(1); transition: filter 0.6s var(--ease), transform 1.2s var(--ease); }
.shot:hover .shot__img img { filter: grayscale(0); transform: scale(1.04); }
.shot figcaption { font-family: var(--mono); font-size: var(--step--1); color: var(--ink-3); margin-top: 0.7rem; letter-spacing: 0.04em; }

/* Video cards

   A row of titles told the reader nothing about what they were about to
   watch, so each link now leads with a still. Thumbnails are derived at
   runtime from the video's own URL (see main.js); a link can override that
   with data-poster when the derived frame is useless, which is the case for
   anything that fades in from black. */
.videos {
  list-style: none; padding: 0; margin: 1.75rem 0 0;
  display: grid; gap: 1.5rem 1.25rem;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}
.videos li { margin: 0; }
/* A lone video is not a grid of choices - it is the thing itself, so it gets
   a real player's worth of room instead of one narrow column. Drive embeds in
   particular add their own toolbar inside the frame, and at column width the
   film was left as a clipped sliver. */
.videos li:only-child { grid-column: 1 / -1; max-width: 640px; }
.videos a {
  display: flex; flex-direction: column; gap: 0.8rem;
  text-decoration: none; color: inherit;
  transition: transform 0.4s var(--ease);
}
.videos a:hover { transform: translateY(-3px); }

.videos__thumb {
  position: relative; display: block;
  aspect-ratio: 16 / 9; overflow: hidden;
  background: var(--bone-2); border: 1px solid var(--rule-soft);
}
.videos__thumb img {
  width: 100%; height: 100%; object-fit: cover;
  filter: grayscale(1); transition: filter 0.6s var(--ease), transform 1.2s var(--ease);
}
.videos a:hover .videos__thumb img { filter: grayscale(0); transform: scale(1.04); }

/* Play glyph: a disc from ::before, the triangle from ::after. */
.videos__play { position: absolute; inset: 0; display: grid; place-items: center; }
.videos__play::before {
  content: ""; width: 54px; height: 54px; border-radius: 50%;
  background: rgba(18, 18, 17, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.6);
  transition: background 0.4s var(--ease), transform 0.4s var(--ease);
}
.videos__play::after {
  content: ""; position: absolute;
  width: 0; height: 0; margin-left: 4px;
  border-left: 15px solid #fff;
  border-top: 9px solid transparent;
  border-bottom: 9px solid transparent;
}
.videos a:hover .videos__play::before { background: var(--accent); transform: scale(1.08); }

/* The real player, once the card is pressed. It takes the still's place
   inside the same frame, so the grid never reflows. */
.videos__thumb iframe {
  position: absolute; inset: 0;
  width: 100%; height: 100%; border: 0;
}
/* A playing card is no longer a link to hover-lift. */
.videos a[data-playing="true"] { transform: none; cursor: default; }
.videos a[data-playing="true"] .videos__title { color: var(--ink); }

.videos__meta { display: flex; flex-direction: column; gap: 0.3rem; }
.videos__title {
  font-family: var(--display); font-size: var(--step-1);
  line-height: 1.15; letter-spacing: -0.01em;
  transition: color 0.4s var(--ease);
}
.videos a:hover .videos__title { color: var(--accent); }
.videos__badge {
  font-family: var(--mono); font-size: var(--step--1);
  color: var(--ink-3); letter-spacing: 0.1em; text-transform: uppercase;
}

/* Footer */
.footer { padding-block: clamp(3rem, 7vw, 5rem) 2.5rem; border-top: 1px solid var(--rule-soft); }
.footer__top { display: flex; flex-wrap: wrap; gap: 2rem; justify-content: space-between; align-items: flex-end; }
.footer__big { font-size: var(--step-3); max-width: 16ch; }
.footer__links { display: flex; flex-direction: column; gap: 0.5rem; }
.footer__links a { font-family: var(--mono); font-size: var(--step--1); letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-2); text-decoration: none; transition: color 0.3s var(--ease); }
.footer__links a:hover { color: var(--accent); }
.footer__bar { margin-top: 3rem; padding-top: 1.25rem; border-top: 1px solid var(--rule-soft); display: flex; flex-wrap: wrap; gap: 1rem; justify-content: space-between; align-items: center; font-family: var(--mono); font-size: var(--step--1); color: var(--ink-3); }
.footer__bar a { transition: color 0.3s var(--ease); }
.footer__bar a:hover { color: var(--accent); }

/* ==========================================================================
   Reveal animation
   ========================================================================== */

[data-reveal] { opacity: 0; transform: translateY(24px); }
[data-reveal].is-in {
  opacity: 1; transform: none;
  transition: opacity 0.9s var(--ease), transform 0.9s var(--ease);
  transition-delay: var(--d, 0ms);
}
@media (prefers-reduced-motion: reduce) {
  [data-reveal] { opacity: 1; transform: none; }
  .frame__stack figure { transition: opacity 0.2s linear; transform: none; }
}

/* Reading progress */
.progress {
  position: fixed; top: 0; left: 0; height: 2px; width: 100%;
  transform: scaleX(0); transform-origin: left;
  background: var(--accent); z-index: 200; pointer-events: none;
}

/* ==========================================================================
   Video card states
   ========================================================================== */

.videos a.is-playable .videos__badge { color: var(--accent); }
.videos a.is-pending { cursor: default; }
.videos a.is-pending:hover { transform: none; }
.videos a.is-pending .videos__title { color: var(--ink-3); }
.videos a.is-pending:hover .videos__title { color: var(--ink-3); }

