/* Page structure: the WebGL canvas, full-screen sections, the chapter grid, hero and finale.
   Loads after tokens.css and before components.css (order matters where specificity ties).
   Heights use svh (stable while a phone's URL bar slides), gutters respect notches (--pad-l/-r). */

#gl { position: fixed; inset: 0; width: 100%; height: 100vh; height: 100dvh; display: block; z-index: 0 }

main { position: relative; z-index: 10 }
section {
  position: relative; min-height: 100vh; min-height: 100svh; padding: 0 var(--pad-r) 0 var(--pad-l);
  display: flex; align-items: center;
}

/* Scroll-in reveal (ui.js adds .in). The .d* delays must stay after .reveal: its transition shorthand resets delay. */
.reveal {
  opacity: 0; transform: translateY(40px); filter: blur(8px);
  transition: opacity 1.2s cubic-bezier(.2,.7,.1,1), transform 1.2s cubic-bezier(.2,.7,.1,1), filter 1.2s;
}
.reveal.in { opacity: 1; transform: none; filter: none }
.d1 { transition-delay: .12s }
.d2 { transition-delay: .24s }
.d3 { transition-delay: .36s }
.d4 { transition-delay: .5s }

/* ---------- Hero ----------
   Three fixed bands, each placed on its own so its rect never depends on the others: the title in the
   upper third (top 14svh), the tagline capsule in the lower third, the scroll cue at the foot.
   The sphere is fitted into the space between title and capsule (measure with offsetTop/offsetHeight:
   the reveal's translateY is a transform and does not move them). */
#hero {
  display: block; text-align: center;
  --cue-line: 52px; --cue-gap: var(--s-3);
  --hero-foot: calc(var(--s-5) + var(--safe-b) + var(--cue-line) + var(--cue-gap) + 16px);   /* the scroll-cue zone */
}
#hero .kicker { justify-content: center }
/* the hero capsule and the finale sit on the brightest glow on the page (sphere, portal),
   so their grey steps up one notch to keep body text above 4.5:1 there */
#hero, #future { --grey: var(--grey-2) }
.title {
  position: absolute; left: var(--pad-l); right: var(--pad-r); top: 14svh;
  font-family: var(--display); font-weight: 600; font-size: clamp(48px,7vw,112px); line-height: 1;
  letter-spacing: -.045em; margin: 0; color: var(--white);
}
.title .ai {
  position: relative; display: inline-block; isolation: isolate;
  background: var(--grad-loop); background-size: 200% 100%; -webkit-background-clip: text; background-clip: text;
  color: transparent; animation: flow 8s linear infinite;
}
/* soft glow: a blurred copy of ".AI" behind itself. The empty alt text ("/ ''") keeps the copy out of the
   heading's accessible name; browsers without alt-text support keep the first declaration. */
.title .ai::after {
  content: attr(data-t); content: attr(data-t) / ""; position: absolute; inset: 0; background: inherit; background-size: inherit;
  -webkit-background-clip: text; background-clip: text; color: transparent; filter: blur(.32em); opacity: .45;
  z-index: -1; animation: inherit;
}
/* the capsule: centred, sized to its text, its bottom edge just above the hint */
.hero-glass {
  position: absolute; left: var(--pad-l); right: var(--pad-r); margin: 0 auto; width: fit-content; max-width: 540px;
  bottom: calc(var(--hero-foot) + var(--s-2) + 16px + var(--s-3));
}
#hero .hero-glass { padding: var(--s-5) var(--s-6) }   /* compact; outranks .glass */
.tagline {
  font-family: var(--body); font-weight: 600; letter-spacing: -.022em; font-size: 19px; line-height: 25px;
  max-width: 21em; margin: var(--s-2) auto 0; color: var(--grey);   /* breaks after "think." */
}
.tagline b { color: var(--white); font-weight: 600 }
.hint {
  position: absolute; left: var(--pad-l); right: var(--pad-r); bottom: calc(var(--hero-foot) + var(--s-2));
  font-family: var(--body); font-weight: 500; font-size: 13px; line-height: 16px; letter-spacing: -.01em;
  text-shadow: 0 1px 12px rgba(3,3,10,.9); color: rgba(235,235,245,.66);
}
.scroll-cue {
  position: absolute; bottom: calc(var(--s-5) + var(--safe-b)); left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: var(--cue-gap); white-space: nowrap;
  font-family: var(--body); font-weight: 500; font-size: 12px; line-height: 16px; letter-spacing: -.005em; color: var(--dim);
}
.scroll-cue .cue-line { width: 1px; height: var(--cue-line); background: linear-gradient(rgba(255,255,255,.5),transparent); position: relative; overflow: hidden }
.scroll-cue .cue-line::after {
  content: ""; position: absolute; top: -50%; left: 0; width: 1px; height: 50%; background: #fff;
  animation: drip 2s cubic-bezier(.7,0,.3,1) infinite;
}
@keyframes drip { to { top: 110% } }
/* one label row: "Scroll to begin" for pointers, "Swipe up to begin" on touch ("Swipe up" on the narrowest phones,
   where the longer label would run into the Chapters pill on the same row) */
.scroll-cue .cue-t, .scroll-cue .cue-s { display: none }
/* short screens: a shorter drip line keeps the capsule in the lower third */
@media (max-height:760px) { #hero { --cue-line: 24px; --cue-gap: var(--s-2) } }
/* touch: no pointer to steer with, so no hint; the cue says what to do */
@media (hover:none) {
  .hint { display: none }
  .hero-glass { bottom: calc(var(--hero-foot) + var(--s-4)) }
  .scroll-cue .cue-d { display: none }
  .scroll-cue .cue-t { display: block }
}
@media (hover:none) and (max-width:379px) {
  .scroll-cue .cue-t { display: none }
  .scroll-cue .cue-s { display: block }
}

/* ---------- Chapters: caption card bottom-left, sculpture fitted beside it by frames.js ---------- */
.chapter { align-items: flex-end; padding-bottom: calc(clamp(var(--s-8),11svh,var(--s-9)) + var(--safe-b)); overflow: clip }
/* desktop: a card never slides under the nav (72px tall). Where a card fits the screen this changes nothing (it sits
   at the foot); where it is taller (a 1366×657 laptop window, browser zoom), the section grows and its first stop
   (scroll.js) shows the card's top just below the nav instead of behind it. Short desktop screens take a little off
   the foot, so the chart cards still fit at 1280×720 and 1536×730. (Phones keep their own rules below; phones on
   their side override both, later in this file.) */
@media (min-width:821px) { .chapter { padding-top: calc(var(--s-8) + var(--s-4) + var(--safe-t)) } }
@media (min-width:821px) and (max-height:760px) { .chapter { padding-bottom: calc(var(--s-7) + var(--safe-b)) } }
/* a 1366×657 laptop window (the most common short one): the tallest chart card still fits in one stop */
@media (min-width:821px) and (max-height:700px) {
  .chapter { padding-bottom: calc(var(--s-4) + var(--safe-b)) }
  .copy .panel { margin-top: var(--s-4) }
}
.copy { position: relative; z-index: 2; max-width: 442px; width: 100%; }
/* The giant year: lit, not painted. Each era glows in its own light (ember fading to maroon for the 1950s,
   ice for the winters, steel for Deep Blue, cyan, violet, then Apple blue), brightest at the top and falling
   away like light through glass, with a soft halo and a slow breath. Bright enough to read, quiet enough
   never to compete with the sculpture or the card. Sized to the viewport's height too, so it fits above the
   card wherever it can; frames.js hides it where it would still crowd the card (and always on phones). */
.chapter { --era: 120,140,255; --era-hi: 215,222,255 }
#prologue   { --era: 125,118,255; --era-hi: 206,202,255 }
#turing     { --era: 150,30,52;   --era-hi: 255,172,124 }
#dartmouth  { --era: 160,36,56;   --era-hi: 255,182,130 }
#perceptron { --era: 172,48,58;   --era-hi: 255,196,142 }
#winters    { --era: 86,146,255;  --era-hi: 218,238,255 }
#deepblue   { --era: 52,92,214;   --era-hi: 196,214,255 }
#alexnet    { --era: 34,184,206;  --era-hi: 198,248,255 }
#alphago    { --era: 112,98,255;  --era-hi: 214,208,255 }
#attention  { --era: 41,151,255;  --era-hi: 196,226,255 }
#chatgpt    { --era: 46,196,160;  --era-hi: 204,255,236 }
#today      { --era: 41,151,255;  --era-hi: 222,238,255 }
.year-bg {
  position: absolute; top: clamp(var(--s-8),10svh,var(--s-9)); left: calc(var(--pad-l) + var(--card-px) - .06em);
  font-family: var(--display); font-weight: 200; font-variant-numeric: tabular-nums; font-size: clamp(96px,min(13vw,20svh),216px);
  letter-spacing: -.05em; line-height: 1;
  color: transparent;
  background: linear-gradient(180deg, rgba(var(--era-hi),.62) 0%, rgba(var(--era),.46) 48%, rgba(var(--era),.10) 100%);
  -webkit-background-clip: text; background-clip: text;
  filter: drop-shadow(0 0 22px rgba(var(--era),.38)) drop-shadow(0 0 3px rgba(var(--era-hi),.22));
  will-change: transform; animation: era-breathe 7s ease-in-out infinite;
  pointer-events: none; user-select: none; white-space: nowrap; z-index: 0; margin-top: 0;
}
@keyframes era-breathe { 0%, 100% { opacity: .82 } 50% { opacity: 1 } }
@media (prefers-reduced-motion: reduce) { .year-bg { animation: none; opacity: .9 } }

/* ---------- Finale ---------- */
#future { flex-direction: column; justify-content: center; text-align: center }
#future .copy { width: fit-content; max-width: min(980px,100%); margin: 0 auto }
#future .kicker { justify-content: center }
#future .lead { max-width: 460px; margin: 0 auto var(--s-6) }
/* desktop: exactly two lines, grey then white (the <br> is the only break) */
@media (min-width:821px) { #future .big { white-space: nowrap } }
footer {
  position: absolute; left: 0; right: 0; bottom: calc(var(--s-5) + var(--safe-b)); padding: 0 var(--pad-r) 0 var(--pad-l);
  display: flex; justify-content: center; gap: var(--s-7);
  font-family: var(--body); font-weight: 500; font-size: 12px; line-height: 16px; letter-spacing: -.005em; color: var(--grey-2);
}

/* ---------- Responsive ---------- */
/* tablet portrait and phones: the sculpture sits above the card */
@media (max-width:820px) {
  .chapter { padding-bottom: calc(var(--s-9) + var(--s-4) + var(--safe-b)) }
  .copy { max-width: 540px }
  footer { bottom: calc(var(--s-9) + var(--s-6) + var(--safe-b)); flex-direction: column; gap: var(--s-2); align-items: center }
}
@media (max-width:600px) {
  .copy { max-width: none }
}
/* tablets held upright (768–1024 wide): the card sits centred at the foot, a little wider, so no empty column is left
   beside it, and frames.js fits the sculpture large above it, centred between the side margins */
@media (min-width:768px) and (max-width:1024px) and (orientation:portrait) {
  .chapter { justify-content: center; padding-bottom: calc(var(--s-9) + var(--s-4) + var(--safe-b)) }
  .copy { max-width: 620px }
}
/* short phones (iPhone SE and smaller): a card never slides under the nav, and a chart chapter keeps the top
   40% of the screen for its sculpture. Its card then runs past the fold, so the section is taller than the
   screen and scroll.js gives it a second stop: first the sculpture with the start of the card, then the whole card. */
@media (max-width:820px) and (max-height:700px) and (orientation:portrait) {
  .chapter { padding-top: calc(var(--s-8) + var(--safe-t)); padding-bottom: calc(var(--s-8) + var(--safe-b)) }
  .chapter:has(.panel) { padding-top: calc(40svh + var(--safe-t)) }
  /* the finale: words and footer sit together at the foot (the footer joins the flow, on one line where it fits),
     clear of the Chapters pill, and the portal gets the space above them */
  #future { justify-content: flex-end; padding-top: calc(var(--s-8) + var(--safe-t)); padding-bottom: calc(var(--s-8) + var(--safe-b)) }
  #future .big { font-size: 34px; margin: var(--s-3) 0 var(--s-4) }
  #future .lead { margin-bottom: var(--s-5) }
  footer { position: static; padding: 0; margin-top: var(--s-5); flex-direction: row; flex-wrap: wrap; gap: var(--s-1) var(--s-4) }
}
/* the smallest phones (320×568): the engine's chart is its sculpture, eight rows that need more than the 40% above,
   so its card starts lower and runs past the fold (a second stop then shows all of it) */
@media (max-width:820px) and (max-height:600px) and (orientation:portrait) {
  #engine { padding-top: calc(52svh + var(--safe-t)) }
}
/* phones held upright: the portal rings the headline (frames.js), so the rest of the words step down below the ring.
   The gap under the headline is about the ring's radius less half the headline; the section's top padding leaves
   room for the ring above the kicker; the footer joins the flow so nothing reaches the Chapters pill. */
@media (max-width:600px) and (orientation:portrait) {
  #future { justify-content: center; padding-top: calc(clamp(var(--s-8), 50vw - 72px, 15svh) + var(--safe-t)); padding-bottom: calc(var(--s-8) + var(--safe-b)) }
  #future .big { margin-bottom: clamp(var(--s-5), calc(50vw - 82px), 150px) }
  #future footer { position: static; padding: 0; margin-top: var(--s-5); flex-direction: row; flex-wrap: wrap; gap: var(--s-1) var(--s-4) }
}
@media (max-width:734px) {
  .tagline { font-size: 17px; line-height: 22px }
}
/* narrow phones: a little more room inside the capsule keeps the first line whole */
@media (max-width:400px) {
  #hero .hero-glass { padding: var(--s-5) var(--s-4) }
  .tagline { font-size: 16px; line-height: 21px }
}
/* phone landscape: card on the left, sculpture beside it (frames.js picks the side with more room) */
@media (orientation:landscape) and (max-height:500px) {
  .chapter { padding-top: calc(var(--s-8) + var(--safe-t)); padding-bottom: calc(var(--s-3) + var(--safe-b)) }
  .copy { max-width: min(420px,50%) }
  #questions .copy { max-width: min(360px,50%) }   /* the questions run at 26px here: a narrower card keeps them filling it */
  #hero { --cue-line: 0px; --cue-gap: 0px }
  .scroll-cue .cue-line { display: none }
  .title { top: max(12svh, calc(var(--s-7) + var(--s-2) + var(--safe-t))); font-size: clamp(40px,12svh,56px) }
  #hero .hero-glass { padding: var(--s-3) var(--s-5) }
  .tagline { font-size: 15px; line-height: 20px }
  #future { padding-top: var(--s-7) }
  #future .lead { margin-bottom: var(--s-4) }
  footer { bottom: calc(var(--s-2) + var(--safe-b)); flex-direction: row; flex-wrap: wrap; gap: var(--s-1) var(--s-5) }
}
