/* ============================================================
   vrishvardhan.in
   Design system: "Manuscript & Ink"
   One stylesheet. No framework. No build step.
   ============================================================ */

/* ---------- 1. Tokens ---------- */

:root {
  /* Paper and ink. Warm, low-chroma, printed rather than screen-lit. */
  --paper:        #F7F4EC;
  --paper-deep:   #EFE9DD;
  --paper-edge:   #FCFAF5;
  --ink:          #1A1613;
  --ink-soft:     #4C443B;
  --ink-faint:    #736858;   /* 4.96:1 on paper. AA for the small text it carries. */
  --rule:         #DED4C2;
  --rule-fine:    #E9E1D3;
  /* Only for the border of a control whose border is its only affordance. */
  --rule-control: #8A7F70;
  /* The underline that tells a reader a thing is a link. Rubric, held back to
     half strength at rest so a paragraph with several links still reads calmly. */
  --rule-link:    rgba(142, 47, 28, 0.50);

  /* Rubrication. The red of a marginal note in a manuscript, not a UI accent. */
  --rubric:       #8E2F1C;
  --ochre:        #A8762C;
  --verdant:      #4C7A45;   /* status: live, correct */

  /* Type */
  --serif: "Newsreader", "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  --deva:  "Noto Serif Devanagari", "Nirmala UI", "Kohinoor Devanagari", serif;
  --ui:    system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  /* Measure and rhythm */
  --wrap: 74rem;
  --measure: 38rem;        /* body copy */
  --measure-lead: 44rem;   /* hero and section leads */
  --measure-wide: 52rem;   /* wide specification lists and tables */
  --gutter: clamp(1.25rem, 5vw, 4rem);
  --step: clamp(3rem, 6vw, 5.25rem);

  --dur: 480ms;
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* ---------- 2. Reset ---------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 6rem;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-size: clamp(1.0625rem, 0.99rem + 0.35vw, 1.1875rem);
  line-height: 1.62;
  font-weight: 380;
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg, video { max-width: 100%; height: auto; display: block; }
h1, h2, h3, h4, p, figure, blockquote, ul, ol { margin: 0; }
ul, ol { padding: 0; list-style: none; }

a { color: inherit; text-decoration: none; }

::selection { background: rgba(142, 47, 28, 0.14); }

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

/* ---------- 3. Utilities ---------- */

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

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

.skip {
  position: absolute; left: -999px; top: 0; z-index: 99;
  background: var(--ink); color: var(--paper);
  padding: 0.75rem 1.25rem; font-family: var(--ui); font-size: 0.875rem;
}
.skip:focus { left: 0; }

.deva { font-family: var(--deva); font-weight: 400; }
.iast { font-style: italic; color: var(--ink-soft); }

/* Small caps label. The only sans-serif on the page. */
.label {
  font-family: var(--ui);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.lead {
  font-size: clamp(1.1875rem, 1.05rem + 0.7vw, 1.5rem);
  line-height: 1.5;
  color: var(--ink-soft);
  font-weight: 350;
  max-width: var(--measure);
}

.prose > * + * { margin-top: 1.15em; }
.prose { max-width: var(--measure); }

/* Rhythm utilities. These replace the inline margin-top values the pages used to carry. */
.stack-sm { margin-top: 1.25rem; }
.stack    { margin-top: 1.5rem; }
.stack-md { margin-top: 1.75rem; }
.stack-lg { margin-top: clamp(2.5rem, 5vw, 3.5rem); }
.stack-xl { margin-top: clamp(2.5rem, 5vw, 4rem); }

.measure      { max-width: var(--measure); }
.measure-lead { max-width: var(--measure-lead); }
.measure-wide { max-width: var(--measure-wide); }

/* A single app icon shown at size, e.g. on a product page. */
.app-icon {
  border-radius: 22%;
  box-shadow: 0 0 0 1px var(--rule);
  max-width: 11rem;
}
/* A frame carrying only an app icon needs no mat and no border. */
.frame-bare { border: 0; background: none; }
/* Butt a second list directly against the one above it. */
.watch-continues { margin-top: -1px; }

/* ---------- 4. Headings ---------- */

h1, h2, h3 {
  font-weight: 400;
  line-height: 1.1;
  letter-spacing: -0.012em;
}

h1 {
  font-size: clamp(2.125rem, 1.45rem + 2.9vw, 3.5rem);
  line-height: 1.08;
  letter-spacing: -0.022em;
  text-wrap: balance;
}

h2 {
  font-size: clamp(1.75rem, 1.35rem + 1.7vw, 2.75rem);
  letter-spacing: -0.018em;
}

h3 {
  font-size: clamp(1.1875rem, 1.05rem + 0.6vw, 1.4375rem);
  letter-spacing: -0.008em;
}

/* Section opener: label above a hairline, heading below. */
.section {
  padding-block: var(--step);
  border-top: 1px solid var(--rule-fine);
}
.section:first-child { border-top: 0; }

.section-head {
  display: grid;
  gap: 0.9rem;
  margin-bottom: clamp(2rem, 4vw, 3.25rem);
}
.section-head .lead { margin-top: 0.35rem; }
.section-head.tight { margin-bottom: 1.65rem; }

/* ---------- 5. Masthead ---------- */

.masthead {
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--paper);
  border-bottom: 1px solid var(--rule-fine);
}
/* Only go translucent where the blur behind it will actually render. */
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .masthead {
    background: color-mix(in srgb, var(--paper) 92%, transparent);
    -webkit-backdrop-filter: saturate(1.1) blur(10px);
    backdrop-filter: saturate(1.1) blur(10px);
  }
}

.masthead-inner {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 2rem;
  padding-block: 1.05rem;
}

.wordmark { display: block; line-height: 1; }
.wordmark-name {
  display: block;
  font-size: 1.0625rem;
  letter-spacing: 0.055em;
  text-transform: uppercase;
  font-weight: 450;
}
.wordmark-sub {
  display: block;
  font-family: var(--deva);
  font-size: 0.8125rem;
  color: var(--ink-faint);
  margin-top: 0.3rem;
  letter-spacing: 0.01em;
}

.nav {
  display: flex;
  align-items: baseline;
  gap: clamp(1rem, 2vw, 1.85rem);
  font-size: 0.9375rem;
}

.nav a {
  position: relative;
  color: var(--ink-soft);
  padding-block: 0.15rem;
  transition: color 180ms var(--ease);
}
.nav a::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: -0.1rem;
  height: 1px; background: var(--rubric);
  transform: scaleX(0); transform-origin: left;
  transition: transform 260ms var(--ease);
}
.nav a:hover { color: var(--ink); }
.nav a:hover::after { transform: scaleX(1); }

.nav .nav-cta {
  color: var(--rubric);
  border: 1px solid color-mix(in srgb, var(--rubric) 35%, transparent);
  border-radius: 2px;
  padding: 0.3rem 0.85rem;
  transition: background 200ms var(--ease), color 200ms var(--ease);
}
.nav .nav-cta::after { display: none; }
.nav .nav-cta:hover { background: var(--rubric); color: var(--paper-edge); }

/* Current page */
body[data-nav="story"] .nav a[data-key="story"],
body[data-nav="scholarship"] .nav a[data-key="scholarship"],
body[data-nav="achievements"] .nav a[data-key="achievements"],
body[data-nav="products"] .nav a[data-key="products"],
body[data-nav="recognition"] .nav a[data-key="recognition"],
body[data-nav="media"] .nav a[data-key="media"],
body[data-nav="contact"] .nav a[data-key="contact"] { color: var(--ink); }

/* The Partner link is a button, so its current state is a fill, not a colour change. */
body[data-nav="partner"] .nav .nav-cta {
  background: var(--rubric);
  color: var(--paper-edge);
  border-color: var(--rubric);
}

body[data-nav="story"] .nav a[data-key="story"]::after,
body[data-nav="scholarship"] .nav a[data-key="scholarship"]::after,
body[data-nav="achievements"] .nav a[data-key="achievements"]::after,
body[data-nav="products"] .nav a[data-key="products"]::after,
body[data-nav="recognition"] .nav a[data-key="recognition"]::after,
body[data-nav="contact"] .nav a[data-key="contact"]::after,
body[data-nav="media"] .nav a[data-key="media"]::after { transform: scaleX(1); }

.nav-toggle {
  display: none;
  background: none; border: 0; padding: 0.5rem; cursor: pointer;
}
.nav-toggle-bars,
.nav-toggle-bars::before,
.nav-toggle-bars::after {
  display: block; width: 22px; height: 1px; background: var(--ink);
  transition: transform 260ms var(--ease), opacity 160ms linear;
}
.nav-toggle-bars::before, .nav-toggle-bars::after { content: ""; }
.nav-toggle-bars::before { transform: translateY(-7px); }
.nav-toggle-bars::after  { transform: translateY(6px); }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars { transform: rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars::before { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars::after { transform: rotate(-90deg); }

/* ---------- 6. Hero ---------- */

.hero {
  padding-block: clamp(3.5rem, 7vw, 6.5rem) clamp(3rem, 6vw, 5rem);
}

.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 0.65fr);
  gap: clamp(2.5rem, 5vw, 4.5rem);
  align-items: start;
}
/* Optical: drop the plate to meet the headline's cap height, not its line box. */
.hero-grid > figure { padding-top: .55rem; }

.hero-eyebrow {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.7rem;
  margin-bottom: 1.9rem;
}
.hero-eyebrow .dot {
  width: 3px; height: 3px; border-radius: 50%;
  background: var(--rubric); flex: none;
}

.hero h1 { max-width: 26ch; }
.hero h1 .line { display: block; }
.hero h1 .quiet { color: color-mix(in srgb, var(--ink) 52%, var(--paper)); }
.hero h1 em {
  font-style: italic;
  font-weight: 300;
}

.hero-sub {
  margin-top: 1.85rem;
  font-size: clamp(1.125rem, 1rem + 0.6vw, 1.375rem);
  line-height: 1.55;
  color: var(--ink-soft);
  font-weight: 350;
  max-width: 34rem;
}

.hero-actions {
  display: flex; flex-wrap: wrap; gap: 1.5rem 2rem;
  margin-top: 2.4rem;
  align-items: center;
}

/* Portrait frame: a printed plate, not a rounded card. */
.plate {
  position: relative;
  background: var(--paper-deep);
  border: 1px solid var(--rule);
  aspect-ratio: 4 / 5;
  overflow: hidden;
}
.plate img { width: 100%; height: 100%; object-fit: cover; }
.plate::after {
  content: "";
  position: absolute; inset: 0;
  box-shadow: inset 0 0 0 1px var(--paper-edge);
  pointer-events: none;
}
.plate-caption {
  margin-top: 0.85rem;
  font-size: 0.8125rem;
  color: var(--ink-faint);
  line-height: 1.45;
}

/* ---------- 7. Links and actions ---------- */

.link {
  position: relative;
  color: var(--ink);
  padding-bottom: 2px;
  border-bottom: 1px solid var(--rule-link);
  transition: border-color 200ms var(--ease), color 200ms var(--ease),
              box-shadow 200ms var(--ease);
}
/* The box-shadow lays a second rule directly under the border, so the
   underline thickens on hover without the text shifting. */
.link:hover {
  border-bottom-color: var(--rubric);
  color: var(--rubric);
  box-shadow: 0 1px 0 0 var(--rubric);
}

.link-arrow::after {
  content: "\2192";
  display: inline-block;
  margin-left: 0.45em;
  transition: transform 240ms var(--ease);
}
.link-arrow:hover::after { transform: translateX(4px); }

.btn {
  display: inline-flex; align-items: center; gap: 0.6rem;
  font-family: var(--serif); font-size: 1rem;
  padding: 0.7rem 1.4rem;
  border: 1px solid var(--ink);
  border-radius: 2px;
  background: var(--ink); color: var(--paper-edge);
  transition: background 220ms var(--ease), color 220ms var(--ease);
}
.btn:hover { background: transparent; color: var(--ink); }

.btn-quiet {
  background: transparent; color: var(--ink);
  border-color: var(--rule-control);
}
.btn-quiet:hover { background: var(--ink); color: var(--paper-edge); border-color: var(--ink); }

/* ---------- 8. Proof figures ---------- */

.figures {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}

.figures > .stat {
  display: grid;
  grid-template-rows: auto 1fr auto;   /* holds the notes to a common baseline */
  padding: clamp(1.6rem, 3vw, 2.4rem) clamp(1rem, 2vw, 1.75rem);
  border-left: 1px solid var(--rule-fine);
}
.figures > .stat:first-child { border-left: 0; padding-left: 0; }

.stat-value {
  font-size: clamp(2.25rem, 1.6rem + 2.6vw, 3.5rem);
  line-height: 1;
  font-weight: 300;
  letter-spacing: -0.03em;
  font-variant-numeric: lining-nums tabular-nums;
}
.stat-value sup {
  font-size: 0.36em;
  vertical-align: super;
  letter-spacing: 0;
  color: var(--rubric);
  margin-left: 0.1em;
}
/* A small affix inside a figure: a plus sign, or a range word. */
.stat-value .affix { font-size: 0.5em; letter-spacing: 0; }

.stat-label {
  margin-top: 0.7rem;
  font-size: 0.9375rem;
  color: var(--ink-soft);
  line-height: 1.35;
}
.stat-note {
  margin-top: 0.35rem;
  font-size: 0.8125rem;
  color: var(--ink-faint);
  align-self: end;
}

/* ---------- 9. Product cards ---------- */

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
}

/* Two cards that belong together and read as a pair, Tamil and Telugu being
   the case this exists for. They stay two up all the way down to the phone,
   where the ordinary .cards grid collapses to a single column. */
.cards.cards-pair { grid-template-columns: 1fr 1fr; }

/* A lone card should not be stretched across the whole grid. */
.cards.cards-one { grid-template-columns: minmax(0, 1fr); max-width: 24rem; }

.card-icon {
  display: block;
  width: 56px; height: 56px;
  line-height: 0; font-size: 0;
  margin-bottom: 1.15rem;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 0 0 1px var(--rule);
}
.card-icon img { width: 100%; height: 100%; object-fit: cover; }
.card .card-icon { margin-top: 0; }

.card {
  display: flex; flex-direction: column;
  padding-top: 1.4rem;
  border-top: 2px solid var(--ink);
  transition: border-color 260ms var(--ease);
}
.card:hover { border-top-color: var(--rubric); }
.card:hover h3 { color: var(--rubric); }

.card h3 { transition: color 220ms var(--ease); margin-top: 0.75rem; }
/* A card title that is itself a link should say so, not rely on the card hover. */
.card h3 > a,
.card .card-title > a {
  border-bottom: 1px solid var(--rule-link);
  padding-bottom: 1px;
  transition: border-color 220ms var(--ease);
}
.card:hover h3 > a,
.card:hover .card-title > a { border-bottom-color: var(--rubric); }
.card p { margin-top: 0.8rem; color: var(--ink-soft); font-size: 1rem; }
.card .card-meta {
  margin-top: auto;
  padding-top: 1.5rem;
  font-size: 0.8125rem;
  color: var(--ink-faint);
  font-family: var(--ui);
  letter-spacing: 0.05em;
}
.card-status {
  display: inline-flex; align-items: center; gap: 0.45rem;
}
.card-status::before {
  content: ""; width: 5px; height: 5px; border-radius: 50%;
  background: var(--ochre);
}
.card-status.is-live::before { background: var(--verdant); }

/* A quotation is not a product. Same grid, quieter rule. */
.card.quote-card { border-top: 1px solid var(--rule); }
.card.quote-card:hover { border-top-color: var(--rule); }
.card.quote-card p { color: var(--ink); }
.card.quote-card .card-meta { color: var(--ink-faint); }

/* ---------- 10. Record list (recognition, achievements) ---------- */

.records { border-top: 1px solid var(--rule); }

.record {
  display: grid;
  grid-template-columns: 11rem minmax(0, 1fr) auto;
  gap: 1.5rem;
  align-items: baseline;
  padding-block: 1.5rem;
  border-bottom: 1px solid var(--rule-fine);
}

.record-date {
  font-family: var(--ui);
  font-size: 0.75rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-faint);
  padding-top: 0.35rem;
}
/* The column carries dates and, sometimes, a name. IAST must not be capitalised. */
.record-date.is-name {
  text-transform: none;
  font-variant: small-caps;
  letter-spacing: 0.04em;
  font-size: 0.875rem;
}
.record-title { font-size: 1.125rem; line-height: 1.35; }
.record-body { color: var(--ink-soft); font-size: 0.9375rem; margin-top: 0.35rem; }
.record-rank {
  font-size: 0.8125rem;
  font-family: var(--ui);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--rubric);
  white-space: nowrap;
}

/* Press kit: biography blocks, meant to be read and copied rather than skimmed. */
.bio { font-size: 1rem; color: var(--ink); line-height: 1.6; }
.bio + .bio { margin-top: 0.9rem; }

/* A contact sheet wants a common frame; editorial figures keep their own shape. */
.plate-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: clamp(1.25rem, 3vw, 2.25rem);
}
.plate-row .plate { aspect-ratio: 4 / 5; }

/* ---------- 11. Quote ---------- */

.pull {
  max-width: 46rem;
  font-size: clamp(1.375rem, 1.1rem + 1.3vw, 2rem);
  line-height: 1.38;
  font-weight: 300;
  font-style: italic;
  color: var(--ink);
  text-wrap: balance;
}
.pull-source {
  margin-top: 1.5rem;
  font-style: normal;
}

/* ---------- 12. Press strip ---------- */

.press {
  display: flex; flex-wrap: wrap;
  gap: 0.75rem clamp(1.75rem, 4vw, 3.5rem);
  align-items: baseline;
}
.press li {
  font-size: 1.0625rem;
  letter-spacing: 0.02em;
  color: var(--ink-faint);
}

/* ---------- 13. Two-door split ---------- */

.doors {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
}
.door {
  background: var(--paper);
  padding: clamp(2rem, 4vw, 3.25rem);
  display: flex; flex-direction: column; gap: 1rem;
  transition: background 260ms var(--ease);
}
.door:hover { background: var(--paper-edge); }
.door .lead { font-size: 1.0625rem; }
/* The foot is the element pinned to the bottom now, not whatever happens to be
   last: a door may carry a second link above it. */
.door > .door-foot { margin-top: auto; padding-top: 1.5rem; }
.door > :last-child:not(.door-foot) { margin-top: auto; padding-top: 1.5rem; }

/* ---------- 14. Motion ---------- */

/* Scoped to .js so the page is fully readable if JavaScript never runs. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.js [data-reveal].is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; scroll-padding-top: 6rem; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
  .js [data-reveal] { opacity: 1; transform: none; }
}

/* ---------- 15. Footer ---------- */

.footer {
  margin-top: var(--step);
  border-top: 1px solid var(--rule);
  padding-top: clamp(2.5rem, 5vw, 4rem);
  padding-bottom: 2.5rem;
}
.footer-inner {
  display: flex; flex-wrap: wrap; justify-content: space-between;
  gap: 2.5rem;
}
.footer-name { font-size: 1.125rem; letter-spacing: 0.04em; text-transform: uppercase; }
.footer-line { color: var(--ink-faint); font-size: 0.9375rem; margin-top: 0.4rem; }
.footer-nav {
  display: grid;
  grid-template-columns: repeat(2, minmax(8rem, auto));
  gap: 0.6rem 3rem;
  font-size: 0.9375rem;
}
.footer-nav a { color: var(--ink-soft); }
.footer-nav a:hover { color: var(--rubric); }
.footer-legal {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule-fine);
  font-size: 0.8125rem;
  color: var(--ink-faint);
}

/* ---------- 16. Responsive ---------- */

@media (max-width: 62rem) {
  .hero-grid { grid-template-columns: 1fr; }
  .hero-grid .plate { max-width: 26rem; }
  .cards { grid-template-columns: repeat(2, 1fr); gap: 2.25rem; }
  .figures { grid-template-columns: repeat(2, 1fr); }
  .figures > .stat:nth-child(3) { border-left: 0; padding-left: 0; }
  .figures > .stat:nth-child(n+3) { border-top: 1px solid var(--rule-fine); }
  .doors { grid-template-columns: 1fr; }
}

@media (max-width: 48rem) {
  .nav-toggle { display: block; align-self: center; }
  .masthead-inner { align-items: center; }
  .nav {
    position: fixed;
    inset: 0 0 auto;
    top: 4.6rem;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    background: var(--paper);
    border-bottom: 1px solid var(--rule);
    padding: 0 var(--gutter) 1.5rem;
    font-size: 1.25rem;
    transform: translateY(-8px);
    opacity: 0;
    pointer-events: none;
    visibility: hidden;   /* opacity alone leaves the links focusable and announced */
    transition: opacity 220ms var(--ease), transform 220ms var(--ease), visibility 0s 220ms;
  }
  .nav.is-open {
    opacity: 1; transform: none; pointer-events: auto;
    visibility: visible; transition-delay: 0s;
  }
  .nav a { width: 100%; padding-block: 0.85rem; border-bottom: 1px solid var(--rule-fine); }
  .nav a::after { display: none; }
  .nav .nav-cta {
    border: 0; padding: 0.85rem 0; margin-top: 0.25rem;
    color: var(--rubric); border-radius: 0;
  }
  .nav .nav-cta:hover { background: none; color: var(--rubric); }

  .cards { grid-template-columns: 1fr; }
  /* The hard line breaks are tuned to the desktop measure; let the phone wrap naturally. */
  .hero h1 .line { display: inline; }
  .hero-grid > figure { padding-top: 0; }
  .hero-eyebrow { flex-direction: column; align-items: flex-start; gap: 0.4rem; }
  .hero-eyebrow .dot { display: none; }

  .record { grid-template-columns: 1fr; gap: 0.4rem; }
  .record-date { padding-top: 0; }
  .record-rank { margin-top: 0.4rem; }
  .footer-nav { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 30rem) {
  .figures { grid-template-columns: 1fr; }
  .figures > .stat { border-left: 0; padding-left: 0; border-top: 1px solid var(--rule-fine); }
  .figures > .stat:first-child { border-top: 0; }
}

/* ---------- 17. Print ---------- */

@media print {
  .masthead, .nav, .nav-toggle, .footer-nav, .skip { display: none; }
  body { background: #fff; font-size: 11pt; }
  .section { page-break-inside: avoid; }

  /* The reveal leaves un-scrolled sections at opacity 0. On paper they must all show. */
  .js [data-reveal] { opacity: 1 !important; transform: none !important; }

  /* A printed page should carry the address of anything it cites. */
  main a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 8.5pt;
    color: #555;
    word-break: break-all;
  }

  .frame img, .plate img { max-height: 9cm; width: auto; }
  .screens { overflow: visible; flex-wrap: wrap; }
  .record, .watch li, .figure { page-break-inside: avoid; }
}

/* ---------- 18. Photographs ---------- */

.figure { margin: 0; }
.figure-caption {
  margin-top: 0.8rem;
  font-size: 0.8125rem;
  color: var(--ink-faint);
  line-height: 1.45;
  max-width: 34rem;
}

.frame {
  background: var(--paper-deep);
  border: 1px solid var(--rule);
  overflow: hidden;
}
.frame img { width: 100%; height: auto; display: block; }

.figure-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: clamp(1.25rem, 3vw, 2.25rem);
}

.figure-wide { max-width: 60rem; }

/* Lead figure beside text */
.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}
.split-narrow { grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr); }

/* ---------- 19. Specification list ---------- */

.spec {
  display: grid;
  grid-template-columns: 12rem minmax(0, 1fr);
  border-top: 1px solid var(--rule);
  margin: 0;
}
.spec dt {
  padding: 0.85rem 1rem 0.85rem 0;
  border-bottom: 1px solid var(--rule-fine);
  font-family: var(--ui);
  font-size: 0.75rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.spec dd {
  margin: 0;
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--rule-fine);
  color: var(--ink-soft);
}
.spec dd .mono {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.9em;
  color: var(--ink);
}

/* ---------- 20. Store links ---------- */

.stores { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 1.75rem; }
.store {
  display: inline-flex; align-items: center; gap: 0.5rem;
  border: 1px solid var(--rule-control);
  border-radius: 2px;
  padding: 0.6rem 1.1rem;
  font-size: 0.9375rem;
  color: var(--ink);
  transition: border-color 200ms var(--ease), background 200ms var(--ease);
}
.store:hover { border-color: var(--ink); background: var(--paper-edge); }

/* ---------- 21. Video and coverage list ---------- */

.watch { border-top: 1px solid var(--rule); }
.watch li { border-bottom: 1px solid var(--rule-fine); }
.watch a {
  display: grid;
  grid-template-columns: 6.75rem minmax(0, 1fr) auto;
  gap: 1.25rem;
  align-items: center;
  padding-block: 1rem;
  transition: background 200ms var(--ease);
}
.watch a.watch-row-text { grid-template-columns: minmax(0, 1fr) auto; }
.watch a:hover { background: var(--paper-edge); }
.watch a:hover .watch-title { color: var(--rubric); }
.watch a:hover .watch-thumb::before { background: rgba(142, 47, 28, 0.55); }

.watch-thumb {
  display: block;
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--paper-deep);
  box-shadow: 0 0 0 1px var(--rule);
}
.watch-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
.watch-thumb::before {
  content: "";
  position: absolute; inset: 0; margin: auto;
  width: 1.85rem; height: 1.85rem;
  border-radius: 50%;
  background: rgba(26, 22, 19, 0.4);
  transition: background 200ms var(--ease);
}
.watch-thumb::after {
  content: "";
  position: absolute; z-index: 1;
  left: 50%; top: 50%;
  transform: translate(-38%, -50%);
  border-style: solid;
  border-width: 0.38rem 0 0.38rem 0.58rem;
  border-color: transparent transparent transparent var(--paper-edge);
}

.watch-source {
  display: block;
  font-family: var(--ui);
  font-size: 0.6875rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 0.3rem;
}
.watch-title { transition: color 200ms var(--ease); line-height: 1.4; }
.watch-note { display: block; font-size: 0.875rem; color: var(--ink-faint); margin-top: 0.2rem; }
.watch-meta {
  font-family: var(--ui);
  font-size: 0.75rem;
  color: var(--ink-faint);
  white-space: nowrap;
}

@media (max-width: 48rem) {
  .split, .split-narrow { grid-template-columns: 1fr; }
  .spec { grid-template-columns: 1fr; }
  .spec dt { border-bottom: 0; padding-bottom: 0.2rem; }
  .spec dd { padding-top: 0.2rem; }
  .watch a {
    grid-template-columns: 4.75rem minmax(0, 1fr);
    align-items: start;
    gap: 0.85rem;
    padding-block: 0.85rem;
  }
  .watch a.watch-row-text { grid-template-columns: 1fr; }
  /* The meta used to drop to a full width row of its own, which put "Dec 2025"
     at the far left under the thumbnail, reading as a stray line rather than as
     part of the row. It now sits beneath the title, in the text column. */
  .watch a { grid-template-areas: "thumb text" "thumb meta"; grid-template-rows: auto auto; }
  .watch-thumb { grid-area: thumb; }
  .watch a > span:not([class]) { grid-area: text; }
  .watch-meta { grid-area: meta; margin-top: 0.3rem; text-align: right; }
  .watch a.watch-row-text { grid-template-areas: "text" "meta"; }
  .watch-thumb::before { width: 1.5rem; height: 1.5rem; }
  .watch-thumb::after { border-width: 0.3rem 0 0.3rem 0.46rem; }
}

/* ---------- 22. Store links inside a card ---------- */

.card-stores {
  display: flex; flex-wrap: wrap; gap: 0.4rem 0.9rem;
  margin-top: 0.9rem;
  font-size: 0.875rem;
}
.card-stores a {
  color: var(--ink-soft);
  border-bottom: 1px solid var(--rule-link);
  padding-bottom: 1px;
  transition: color 180ms var(--ease), border-color 180ms var(--ease);
}
.card-stores a:hover { color: var(--rubric); border-color: var(--rubric); }
.card .card-stores + .card-meta { padding-top: 1.1rem; }

/* ---------- 23. Paired card icons ---------- */

.card-icons {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 1.15rem;
  line-height: 0;
}
.card .card-icons { margin-top: 0; }
.card-icons picture,
.card-icons img {
  display: block;
  width: 56px; height: 56px;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 0 0 1px var(--rule);
  object-fit: cover;
}

/* ---------- 24. Screenshot strip ---------- */

.screens {
  display: flex;
  gap: clamp(1rem, 2vw, 1.5rem);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding-bottom: 0.85rem;
  -webkit-overflow-scrolling: touch;
}
.screens .screen { flex: 0 0 auto; scroll-snap-align: start; }
/* Sized by height, not width: the captures come from two devices with different
   aspect ratios, and a common height reads as a shelf where a common width does not. */
.screens .screen,
.screens .screen .frame { height: clamp(18rem, 46vw, 25rem); }
.screens .screen .frame { border-radius: 0; display: flex; }
.screens .screen .frame picture { display: contents; }
.screens .screen .frame img { height: 100%; width: auto; }
.screens::-webkit-scrollbar { height: 6px; }
.screens::-webkit-scrollbar-track { background: var(--rule-fine); }
.screens::-webkit-scrollbar-thumb { background: var(--rule); }

/* ---------- 25. Quiz ---------- */

.quiz-name {
  display: block;
  width: 100%; max-width: 22rem;
  padding: 0.75rem 1rem;
  border: 1px solid var(--rule-control);
  background: var(--paper-edge);
  font-family: var(--serif); font-size: 1rem; color: var(--ink);
  margin-top: 1.5rem;
}
.quiz-name:focus-visible { outline: 2px solid var(--rubric); outline-offset: 2px; }

.quiz-meta {
  display: flex; justify-content: space-between;
  font-family: var(--ui); font-size: 0.75rem;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--ink-faint);
}

.quiz-progress {
  height: 2px; background: var(--rule-fine);
  margin-top: 0.75rem; overflow: hidden;
}
.quiz-progress-fill { height: 100%; background: var(--rubric); transition: width 300ms var(--ease); }

.quiz-options { display: grid; gap: 0.75rem; margin-top: 1.75rem; margin-bottom: 2rem; }
.quiz-option {
  text-align: left;
  padding: 0.9rem 1.15rem;
  border: 1px solid var(--rule-control);
  background: var(--paper-edge);
  font-family: var(--serif); font-size: 1rem; color: var(--ink);
  cursor: pointer;
  transition: border-color 180ms var(--ease), background 180ms var(--ease), opacity 180ms var(--ease);
}
.quiz-option:hover:not(:disabled) { border-color: var(--ink); }
.quiz-option:disabled { cursor: default; }
.quiz-option.is-correct {
  border-color: var(--verdant);
  background: color-mix(in srgb, var(--verdant) 10%, var(--paper-edge));
}
.quiz-option.is-incorrect {
  border-color: var(--rubric);
  background: color-mix(in srgb, var(--rubric) 8%, var(--paper-edge));
  color: var(--rubric);
}
.quiz-option.is-muted { opacity: 0.5; }

.quiz-result-score { display: flex; align-items: baseline; gap: 0.65rem; margin-top: 1.5rem; }

/* ---------- 26. Script specimen ---------- */

/* A band that steps out of the page's rhythm to show the eleven writing
   systems as writing, not as a list of names. Full width paper-deep, hairline
   ruled cells. Each cell names its own script in that script, so the band is a
   specimen and not a claim about one. */

.specimen {
  background: var(--paper-deep);
  border-block: 1px solid var(--rule);
  padding-block: clamp(3rem, 6vw, 5rem);
  /* No bottom margin: the section that follows brings its own top padding. */
  margin-block: clamp(3rem, 6vw, 5.25rem) 0;
}

/* Per-script fallback. Font stacks resolve character by character, so
   Devanagari takes Noto Serif Devanagari and every other script falls through
   to whatever the device carries for it. No extra web fonts are fetched. */
/* Eleven cells. The column counts are set rather than left to auto-fit so the
   last row is never a lonely remainder: 6+5, then 4+4+3, then 3s, then 2s. */
.specimen-grid {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
  margin-top: clamp(2rem, 4vw, 2.75rem);
}

.specimen-grid > li {
  background: var(--paper-deep);
  min-height: 7rem;
  position: relative;
  overflow: hidden;
}

/* The whole cell is the target. On a pointer, his handwriting in that script
   rises behind the name like ink showing through the paper; on a phone, where
   no hover exists, the tap simply opens the page at a size worth reading. */
.specimen-cell {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 0.75rem;
  height: 100%;
  padding: 1.05rem 1rem 0.95rem;
  transition: background 240ms var(--ease);
}
.specimen-cell:hover { background: rgba(252, 250, 245, 0.35); }

.specimen-wash {
  position: absolute;
  inset: 0;
  z-index: 0;
  opacity: 0;
  transition: opacity 460ms var(--ease), transform 900ms var(--ease);
  transform: scale(1.04);
  pointer-events: none;
}
.specimen-wash img { width: 100%; height: 100%; object-fit: cover; display: block; }
.specimen-grid > li:hover .specimen-wash { opacity: 0.42; transform: scale(1); }
/* The name has to firm up to full ink as the hand rises behind it. At
   --ink-faint over a dark pencil stroke it measures 2.7:1 and fails AA; at
   --ink it is 8:1 even in the worst case on these scans. */
.specimen-grid > li:hover .specimen-name { color: var(--ink); }

/* A corner mark, so the cell reads as something you can open. */
.specimen-cell::after {
  content: "";
  position: absolute;
  right: 0.6rem; bottom: 0.55rem;
  width: 0.4rem; height: 0.4rem;
  border-right: 1px solid var(--rubric);
  border-bottom: 1px solid var(--rubric);
  opacity: 0;
  transition: opacity 240ms var(--ease), transform 240ms var(--ease);
}
.specimen-grid > li:hover .specimen-cell::after { opacity: 1; transform: translate(2px, 2px); }

/* Eleven cells never fill a grid evenly. This twelfth is empty and hidden from
   assistive technology; it exists so the rule colour behind the grid does not
   show through the gap in the last row. 12 divides by 6, 4, 3 and 2, which are
   the four column counts this grid uses. */
.specimen-fill { min-height: 0 !important; }
.specimen-fill:hover { background: var(--paper-deep) !important; }

/* ---------- 33. The eleven manuscripts ---------- */

.manuscripts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: clamp(1.25rem, 3vw, 2rem);
  margin-top: clamp(2rem, 4vw, 3rem);
}
.manuscript { scroll-margin-top: 7rem; }
.manuscript .frame { transition: border-color 260ms var(--ease); }
.manuscript a:hover .frame { border-color: var(--rubric); }
.manuscript-script {
  display: block;
  font-family: var(--ui);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--rubric);
  margin-bottom: 0.2rem;
}

.specimen-glyph {
  font-family: "Noto Serif Devanagari", "Nirmala UI", "Kohinoor Devanagari", serif;
  font-size: clamp(1.35rem, 1.05rem + 1.1vw, 1.9rem);
  line-height: 1.4;
  color: var(--ink);
  font-weight: 400;
  overflow-wrap: anywhere;
}
/* The Roman cell is set in the page serif, since that is what it actually is. */
.specimen-glyph.is-roman {
  font-family: var(--serif);
  font-size: clamp(1.1rem, 0.95rem + 0.6vw, 1.4rem);
  letter-spacing: 0.01em;
}

.specimen-name {
  font-family: var(--ui);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* ---------- 27. Timeline ---------- */

/* Age in the margin, a ruled spine, the event against it. One row per year
   that has something in it, so the gaps are honest. */

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

.timeline > li {
  display: grid;
  grid-template-columns: 3.25rem minmax(0, 1fr);
  column-gap: clamp(1.1rem, 2.5vw, 1.75rem);
}

.timeline-age {
  font-family: var(--ui);
  font-size: clamp(1.35rem, 1.1rem + 0.7vw, 1.75rem);
  font-weight: 300;
  line-height: 1.15;
  color: var(--rubric);
  text-align: right;
  padding-top: 0.05rem;
  font-variant-numeric: lining-nums tabular-nums;
}
/* Repeated ages are set once. The second row in a year carries a rule instead,
   so the column reads as a scale and not as a stutter. */
.timeline-age.is-same {
  /* --rule would fail AA. This is the same faint ink the labels use, 4.96:1. */
  color: var(--ink-faint);
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding-top: 0.5rem;
}

.timeline-body {
  border-left: 1px solid var(--rule);
  padding-left: clamp(1.1rem, 2.5vw, 1.75rem);
  padding-bottom: clamp(1.6rem, 3vw, 2.4rem);
  position: relative;
}
.timeline-body::before {
  content: "";
  position: absolute;
  left: -4px; top: 0.62rem;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--rubric);
}
.timeline > li:last-child .timeline-body {
  border-left-color: transparent;
  padding-bottom: 0;
}

.timeline-title {
  font-size: clamp(1.0625rem, 1rem + 0.25vw, 1.1875rem);
  line-height: 1.45;
  color: var(--ink);
}
.timeline-note {
  margin-top: 0.3rem;
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--ink-soft);
}
/* A word on its own asked too little of the reader. The row now shows the
   still from the recording it links to, at the size of a postage stamp, and
   lifts when the pointer lands on it. */
.timeline-watch {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  margin-top: 0.6rem;
  font-family: var(--ui);
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
  transition: color 180ms var(--ease);
}
.timeline-watch-label {
  border-bottom: 1px solid var(--rule-link);
  padding-bottom: 1px;
  transition: border-color 180ms var(--ease);
}

.timeline-thumb {
  position: relative;
  display: block;
  flex: none;
  width: 4rem;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: 3px;
  background: var(--paper-deep);
  box-shadow: 0 0 0 1px var(--rule);
  transition: box-shadow 240ms var(--ease), transform 240ms var(--ease);
}
.timeline-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* The play mark, on the same construction as the .watch rows so the two read
   as the same idea at two sizes. */
.timeline-thumb::before {
  content: "";
  position: absolute; inset: 0; margin: auto;
  width: 1.15rem; height: 1.15rem;
  border-radius: 50%;
  background: rgba(26, 22, 19, 0.42);
  transition: background 200ms var(--ease);
}
.timeline-thumb::after {
  content: "";
  position: absolute; z-index: 1;
  left: 50%; top: 50%;
  transform: translate(-36%, -50%);
  border-style: solid;
  border-width: 0.24rem 0 0.24rem 0.36rem;
  border-color: transparent transparent transparent var(--paper-edge);
}

.timeline-watch:hover { color: var(--rubric); }
.timeline-watch:hover .timeline-watch-label { border-bottom-color: var(--rubric); }
.timeline-watch:hover .timeline-thumb {
  transform: translateY(-2px);
  box-shadow: 0 0 0 1px var(--rubric), 0 5px 12px -5px rgba(26, 22, 19, 0.35);
}
.timeline-watch:hover .timeline-thumb::before { background: rgba(142, 47, 28, 0.6); }

/* Narrow screens for the two components above, and for the paired cards. */
@media (max-width: 68rem) {
  .specimen-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

@media (max-width: 48rem) {
  .specimen-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .specimen-grid > li { min-height: 6rem; padding: 0.85rem 0.7rem 0.8rem; }
  .timeline > li { grid-template-columns: 2.4rem minmax(0, 1fr); }
  /* Two small cards side by side survive the phone, but the heading has to come
     down or a two word product name breaks across three lines in a half column. */
  .cards.cards-pair { gap: 1rem; }
  .cards.cards-pair .card p { font-size: 0.9375rem; }
  .cards.cards-pair .card-title { font-size: 1.25rem; }
  .cards.cards-pair .card-meta { font-size: 0.75rem; }
}

@media (max-width: 30rem) {
  .specimen-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---------- 28. Application page hero ---------- */

/* An app page opens the way a store listing does: the mark at listing size
   above the title, and one real screen beside it. A blown up icon in the
   right hand column reads as a placeholder, which is what it was. */

.app-mark {
  width: 64px; height: 64px;
  border-radius: 22%;
  box-shadow: 0 0 0 1px var(--rule);
  margin-bottom: 1.15rem;
}

.app-shot {
  max-height: 32rem;
  width: auto;
  margin-inline: auto;
  border-radius: 10px;
  box-shadow: 0 1px 2px rgba(26, 22, 19, 0.10),
              0 14px 34px -14px rgba(26, 22, 19, 0.30);
}

/* A numbered sequence, for a method that has an order to it. */
.steps { counter-reset: step; margin-top: clamp(2rem, 4vw, 2.75rem); }
.steps > li {
  counter-increment: step;
  display: grid;
  grid-template-columns: 2.5rem minmax(0, 1fr);
  column-gap: clamp(1rem, 2.5vw, 1.5rem);
  padding-block: 1.15rem;
  border-top: 1px solid var(--rule-fine);
}
.steps > li:last-child { border-bottom: 1px solid var(--rule-fine); }
.steps > li::before {
  content: counter(step);
  font-family: var(--ui);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--rubric);
  padding-top: 0.35rem;
}
.steps-title { font-size: 1.125rem; line-height: 1.4; }
.steps-note {
  margin-top: 0.25rem;
  font-size: 0.9375rem;
  color: var(--ink-soft);
  line-height: 1.5;
}

@media (max-width: 48rem) {
  .app-shot { max-height: 26rem; }
  .steps > li { grid-template-columns: 1.75rem minmax(0, 1fr); }
}

/* ---------- 29. Gateway ---------- */

/* A link into a page that holds a great deal. A bare arrow link did not carry
   enough weight for it, so this one shows what is behind it: three real screens
   fanned out, which spread apart when the pointer lands on them. */

.gateway {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(1rem, 2.5vw, 1.75rem);
  padding: clamp(1rem, 2.2vw, 1.35rem) clamp(1.1rem, 2.5vw, 1.5rem);
  border: 1px solid var(--rule);
  border-radius: 2px;
  background: var(--paper-edge);
  transition: border-color 240ms var(--ease), background 240ms var(--ease);
}
.gateway:hover { border-color: var(--rubric); background: var(--paper-deep); }

.gateway-shots { display: flex; align-items: center; }
/* The shots are wrapped in <picture>, so the flex items and the overlap and
   the transform all belong on the picture, not on the img inside it. An
   img:first-child selector would match nothing at all: <source> is first. */
.gateway-shots picture {
  display: block;
  line-height: 0;
  transition: transform 320ms var(--ease);
}
.gateway-shots picture + picture { margin-left: -1.15rem; }
.gateway-shots img {
  width: auto;
  height: 5.5rem;
  border-radius: 5px;
  background: var(--paper);
  box-shadow: 0 0 0 1px var(--rule), 0 3px 8px -3px rgba(26, 22, 19, 0.30);
}
/* The fan opens on hover. Reduced motion collapses every transition on the
   site to nothing, so this degrades to a static fan rather than a jump. */
.gateway:hover .gateway-shots picture:first-child { transform: translateX(-5px) rotate(-2.5deg); }
.gateway:hover .gateway-shots picture:last-child  { transform: translateX(5px) rotate(2.5deg); }

.gateway .label { display: block; margin-bottom: 0.4rem; }
.gateway-title {
  display: block;
  font-size: clamp(1.0625rem, 1rem + 0.3vw, 1.1875rem);
  line-height: 1.35;
  color: var(--ink);
}
.gateway-note {
  display: block;
  margin-top: 0.3rem;
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--ink-soft);
}
.gateway-arrow {
  font-size: 1.35rem;
  line-height: 1;
  color: var(--rubric);
  transition: transform 240ms var(--ease);
}
.gateway:hover .gateway-arrow { transform: translateX(5px); }

@media (max-width: 34rem) {
  .gateway { gap: 0.9rem; padding: 0.9rem 1rem; }
  .gateway-shots img { height: 4.25rem; }
  .gateway-shots picture + picture { margin-left: -0.95rem; }
  .gateway-note { display: none; }
  .gateway-arrow { font-size: 1.1rem; }
}

/* ---------- 30. Reach, and what a phone can feel ---------- */

/* A text link stands 18 to 21px tall. That is a poor thing to hit with a thumb
   and below what WCAG 2.5.8 asks of a target. This lays an invisible pad over
   each one and moves nothing: the underline, the baseline and the rhythm of the
   paragraph are all untouched. ::before is used because .link-arrow already
   spends its ::after on the arrow. */
@media (pointer: coarse) {
  .link,
  .card-stores a,
  .footer-nav a,
  .card h3 > a,
  .card .card-title > a { position: relative; }

  .link::before,
  .card-stores a::before,
  .footer-nav a::before,
  .card h3 > a::before,
  .card .card-title > a::before {
    content: "";
    position: absolute;
    left: 0; right: 0;
    top: -12px; bottom: -12px;
  }
  /* .link-arrow spends its ::after on the arrow and .timeline-watch spends its
     ::before on the play triangle, so neither can take the pad above. The
     timeline marker is padded directly and pulled back by its own margin, so
     the row spacing does not change. */
  /* The thumbnail already stands 36px tall, so this only tops it up. */
  .timeline-watch { padding-block: 0.35rem; }
}

/* There is no hover on a phone, so every target needs a pressed state or it
   feels dead under the thumb. These are deliberately a shade stronger than the
   hover equivalents, because a press is brief. */
@media (hover: none) {
  .watch a:active { background: var(--paper-deep); }
  .watch a:active .watch-title { color: var(--rubric); }
  .watch a:active .watch-thumb::before { background: rgba(142, 47, 28, 0.55); }
  .gateway:active { border-color: var(--rubric); background: var(--paper-deep); }
  .gateway:active .gateway-shots picture:first-child { transform: translateX(-5px) rotate(-2.5deg); }
  .gateway:active .gateway-shots picture:last-child { transform: translateX(5px) rotate(2.5deg); }
  .gateway:active .gateway-arrow { transform: translateX(5px); }
  .door:active { background: var(--paper-deep); }
  .door:active .door-arrow { transform: translateX(5px); }
  .card:active { border-top-color: var(--rubric); }
  .card:active h3, .card:active .card-title { color: var(--rubric); }
  .link:active { color: var(--rubric); border-bottom-color: var(--rubric); }
  .btn:active, .store:active { transform: translateY(1px); }
  .record:active { background: var(--paper-edge); }
}

/* ---------- 31. Doors ---------- */

/* A door was a block of prose with a small link at the foot of it, which is a
   large piece of page carrying a very small target. The whole panel is now the
   link: the heading is the accessible name, the arrow answers, and a second
   link can still sit on top where a door leads to two places. */

.door { position: relative; }
.door-primary::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}
.door-secondary { position: relative; z-index: 2; }

/* The foot reads as the panel's action bar, so it takes a hairline above it and
   sits below anything else in the door. */
.door-foot {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-top: auto;
  padding-top: 1.15rem;
  border-top: 1px solid var(--rule-fine);
}
.door-cue {
  font-family: var(--ui);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--rubric);
}
/* A door may hold one further link. It has to read as the smaller of the two,
   or the secondary destination looks like the main one. */
.door-secondary { font-size: 0.9375rem; }
.door-arrow {
  font-size: 1.35rem;
  line-height: 1;
  color: var(--rubric);
  transition: transform 240ms var(--ease);
}
.door:hover .door-arrow { transform: translateX(5px); }
.door:hover .door-cue { color: var(--rubric); }
.door:focus-within { background: var(--paper-edge); }

/* ---------- 32. Scrollable strips ---------- */

/* The screen strips run to 2141px inside a 350px phone. Nothing said so. The
   wrapper fades whichever edge still has content behind it, and site.js keeps
   the two state classes honest as the strip is scrolled. */

.screens-wrap { position: relative; }
.screens-wrap::before,
.screens-wrap::after {
  content: "";
  position: absolute;
  top: 0; bottom: 0;
  width: clamp(1.75rem, 5vw, 3rem);
  pointer-events: none;
  opacity: 0;
  transition: opacity 240ms var(--ease);
  z-index: 2;
}
.screens-wrap::before {
  left: 0;
  background: linear-gradient(to right, var(--paper), transparent);
}
.screens-wrap::after {
  right: 0;
  background: linear-gradient(to left, var(--paper), transparent);
}
.screens-wrap.can-scroll-left::before  { opacity: 1; }
.screens-wrap.can-scroll-right::after { opacity: 1; }

.screens { scroll-snap-type: x proximity; }
.screens .screen { scroll-snap-align: center; }

.screens-hint {
  display: none;
  margin-top: 1rem;
  font-family: var(--ui);
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.screens-wrap.is-overflowing + .screens-hint { display: block; }
.screens-hint::after {
  content: "\2192";
  margin-left: 0.5em;
  display: inline-block;
  animation: nudge 2.4s var(--ease) infinite;
}
@keyframes nudge {
  0%, 62%, 100% { transform: translateX(0); }
  76%           { transform: translateX(4px); }
}
@media (prefers-reduced-motion: reduce) {
  .screens-hint::after { animation: none; }
}

@media (hover: none) {
  .timeline-watch:active { color: var(--rubric); }
  .timeline-watch:active .timeline-watch-label { border-bottom-color: var(--rubric); }
  .timeline-watch:active .timeline-thumb {
    box-shadow: 0 0 0 1px var(--rubric), 0 5px 12px -5px rgba(26, 22, 19, 0.35);
  }
  .timeline-watch:active .timeline-thumb::before { background: rgba(142, 47, 28, 0.6); }
}

@media (max-width: 34rem) {
  .timeline-thumb { width: 3.4rem; }
  .timeline-watch { gap: 0.55rem; }
}

@media (hover: none) {
  /* No hover to reveal the hand, so the tap target gets a permanent mark. */
  .specimen-cell::after { opacity: 0.5; }
  .specimen-grid > li:active .specimen-wash { opacity: 0.42; transform: scale(1); }
  .specimen-grid > li:active .specimen-name { color: var(--ink); }
  .specimen-grid > li:active .specimen-cell { background: rgba(252, 250, 245, 0.35); }
  .manuscript a:active .frame { border-color: var(--rubric); }
}
