/* Home: Powers of Ten, as a colourful studio.
   One camera pulls back from a molecule of insulin to the North Pacific and
   comes home to UCLA. Two modes:
   - live (html.is-live): the stage pins, the WebGL canvas fills it, and the
     beats scroll past while the scroll moves the camera;
   - still (no JavaScript, reduced motion, or no capable GPU): every beat is its
     own composed frame, a still rendered from the same scene.
   Page-level overrides of the system are marked "override". */

/* ---------------------------------------------------------------------------
   The scale readout (override: our own element, bottom-right, so it never sits
   under a beat's words, which live in the left column)
   --------------------------------------------------------------------------- */
.powers {
  position: fixed; right: var(--gutter); bottom: 22px; z-index: 40;
  display: flex; align-items: center; gap: 12px; pointer-events: none;
  font: 400 12px/1 var(--font-mono); letter-spacing: var(--track-mono);
  color: var(--powers-ink, var(--ink-fixed));
  transition: opacity var(--dur-ui) var(--ease-out), color var(--dur-ui) var(--ease-out);
}
.powers sup, .beat__scale sup { font-size: .68em; line-height: 0; vertical-align: .62em; letter-spacing: 0; }
.powers__n { font-weight: 500; font-size: 13px; letter-spacing: 0; min-width: 6.2ch; font-variant-numeric: tabular-nums; }
.powers__bar { position: relative; width: 132px; height: 2px; border-radius: 2px; background: color-mix(in srgb, currentColor 22%, transparent); }
.powers__bar::after {          /* a tick at every power of ten, 10⁻¹⁰ to 10⁸ */
  content: ""; position: absolute; left: 0; right: 0; top: -2px; height: 6px;
  background: repeating-linear-gradient(90deg, color-mix(in srgb, currentColor 45%, transparent) 0 1px, transparent 1px calc(100% / 18));
}
.powers__bar i { position: absolute; inset: 0; border-radius: 2px; background: currentColor; transform-origin: 0 50%; transform: scaleX(var(--scale, 0)); }
.powers__t { font: 500 13px/1 var(--font-body); letter-spacing: 0; min-width: 12ch; }
html:not(.is-live) .powers, .powers[data-off] { opacity: 0; }

/* override: past the film the scrolled header band is solid, in the colour of
   the page under it. Over the film it stays off (page.js), and a beat's words
   fade out as they pass under the header instead (.is-cut, below). */
.chrome::before {
  -webkit-backdrop-filter: none; backdrop-filter: none;
  background: var(--chrome-bg, #fcf8f1);
}
.chrome[data-band-off]::before { opacity: 0; transition: none; }

/* ---------------------------------------------------------------------------
   The film and its stage
   --------------------------------------------------------------------------- */
.film { position: relative; isolation: isolate; }
.stage {
  position: absolute; inset: 0 0 auto; z-index: 0;
  height: 100dvh; overflow: hidden;   /* hit-testable on purpose: the shared header reads its ground colour through it */
  background: var(--stage-bg, var(--cobalt-tint));
}
.stage__poster, .stage__poster img { position: absolute; inset: 0; width: 100%; height: 100%; }
.stage__poster img { object-fit: cover; }
.stage__canvas { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; }
.is-live .stage { position: sticky; top: 0; margin-bottom: -100dvh; }
/* the words' side of the frame settles into the scene's own haze (its fog
   colour: live, the stage reports it; still, each beat names its own), so a
   busy scale never fights the type */
.stage { --stage-bg: var(--cobalt-tint); }
.beat--hero, .beat--cell { --haze: #e0e6ff; }
.beat--tray { --haze: #ffe3dc; }
.beat--room { --haze: #ffe9de; }
.beat--ucla { --haze: #ffe6c4; }
.beat--pacific { --haze: #15112b; }
.stage::after, .beat__still::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  --h: var(--stage-bg);
  background: linear-gradient(to right, color-mix(in srgb, var(--h) 62%, transparent) 0%, color-mix(in srgb, var(--h) 46%, transparent) 26%, color-mix(in srgb, var(--h) 0%, transparent) 50%);
}
.beat__still::after { --h: var(--haze); }
.is-live .stage.is-ready .stage__canvas { opacity: 1; }
.is-live .stage.is-ready .stage__poster { visibility: hidden; }

/* ---------------------------------------------------------------------------
   Beats: one or two lines each, in display type and colour
   --------------------------------------------------------------------------- */
.beat {
  position: relative; z-index: 1;
  min-height: 100dvh;
  display: grid; align-content: center;
  padding: calc(var(--chrome-h) + 24px) var(--gutter) 80px;
  color: var(--beat-ink, var(--ink-fixed));
}
.beat__text { display: grid; gap: 18px; justify-items: start; max-width: min(560px, 40vw); }
/* under the header the words fade out: clear above --cut (in their own box,
   set from the scroll by page.js), solid 44 px lower */
.is-live .beat__text.is-cut {
  -webkit-mask-image: linear-gradient(to bottom, transparent var(--cut), #000 calc(var(--cut) + 44px));
          mask-image: linear-gradient(to bottom, transparent var(--cut), #000 calc(var(--cut) + 44px));
}
.beat__title {
  font: 700 clamp(34px, 3.45vw, 60px)/1.02 var(--font-display);
  letter-spacing: -.03em; text-wrap: balance;
  color: var(--beat-title, var(--cobalt-deep));
}
.beat__text p { font-size: clamp(17px, 1.2vw, 20px); line-height: 1.5; max-width: 36ch; }
.beat__link {
  display: inline-flex; align-items: center; gap: 10px; min-height: 44px;
  font: 600 16px/1 var(--font-body); letter-spacing: -.005em; text-decoration: none;
  color: inherit;
}
.beat__link::after {
  content: ""; width: 22px; height: 12px; flex: none;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22 12'%3E%3Cpath d='M0 5.25h18.4L14.3 1.1 15.4 0l6 6-6 6-1.1-1.1 4.1-4.15H0z'/%3E%3C/svg%3E") no-repeat center / contain;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22 12'%3E%3Cpath d='M0 5.25h18.4L14.3 1.1 15.4 0l6 6-6 6-1.1-1.1 4.1-4.15H0z'/%3E%3C/svg%3E") no-repeat center / contain;
  transition: transform var(--dur-micro) var(--ease-out);
}
.beat__link:hover::after { transform: translateX(4px); }
.beat__link:hover { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: .3em; }
/* the scale in words, for the still frames and for screen readers */
.beat__scale {
  position: absolute; left: var(--gutter); bottom: 26px;
  font: 500 13px/1 var(--font-mono); letter-spacing: 0;
}
.beat__scale span { margin-left: 10px; font: 500 13px/1 var(--font-body); }
.is-live .beat__scale { position: absolute !important; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* the hero: the name, the tagline, the molecule's line */
.beat--hero { align-content: start; padding-top: calc(var(--chrome-h) + clamp(28px, 6dvh, 72px)); }
.beat--hero .beat__text { max-width: min(640px, 44vw); gap: 0; }
.hero__name {
  font: 700 clamp(64px, 9.6vw, 172px)/.84 var(--font-display);
  letter-spacing: -.055em; margin-left: -.045em;
  color: var(--cobalt-deep);
}
.hero__name span { display: block; }
.hero__tagline {
  margin-top: clamp(18px, 2.8dvh, 30px);
  font: 650 clamp(22px, 2vw, 34px)/1.1 var(--font-display); letter-spacing: -.025em;
  color: var(--ink-fixed);
}
.beat--hero .beat__text p.hero__line { margin-top: 14px; max-width: 31ch; color: var(--ink-soft); }
.beat--hero .beat__link { margin-top: 10px; }

/* each beat's colours, chosen against what the camera shows behind its words */
.beat--cell   { --beat-title: var(--cobalt-deep); }
.beat--tray   { --beat-title: var(--coral-deep); }
.beat--room   { --beat-title: var(--coral-deep); }
.beat--pacific { --beat-title: #ffffff; --beat-ink: #ffffff; }
.beat--ucla   { --beat-title: var(--marigold-deep); }
.beat--ucla .beat__title { font-size: clamp(44px, 5.1vw, 92px); max-width: 8.6ch; }

/* live: the beats spread out along the camera's journey */
.is-live .beat + .beat { margin-top: var(--gap, 60dvh); }
.is-live .beat--cell { --gap: 70dvh; }
.is-live .beat--tray { --gap: 70dvh; }
.is-live .beat--room { --gap: 45dvh; }
.is-live .beat--ucla { --gap: 125dvh; min-height: 125dvh; }
.is-live .beat--pacific { --gap: 50dvh; }
.is-live .beat:last-child { margin-bottom: 40dvh; }
.is-live .beat__still { display: none; }

/* still: each beat is its own frame */
.beat__still { position: absolute; inset: 0; z-index: -1; }
.beat__still img { width: 100%; height: 100%; object-fit: cover; }
html:not(.is-live) .beat--hero { min-height: 100dvh; }

/* ---------------------------------------------------------------------------
   Back to one metre: Bassel
   --------------------------------------------------------------------------- */
.me { position: relative; padding: clamp(96px, 12vw, 168px) 0 clamp(96px, 11vw, 150px); background: var(--paper); }
.me__grid {
  display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: clamp(40px, 7vw, 120px); align-items: center;
}
.me__photo { margin: 0; }
.me__frame {
  position: relative; aspect-ratio: 4 / 5; max-width: 460px;
  border-radius: 34px; overflow: hidden;
  background: var(--marigold);
  box-shadow: 0 2px 6px rgba(28, 24, 48, .08), 0 40px 80px -36px rgba(75, 43, 214, .42);
  transform: rotate(-2.5deg);
}
/* the portrait sits in a gold mat: the stole's own gold, framing a pale sky
   that would otherwise fade into the paper */
.me__frame img { position: absolute; inset: 10px; width: calc(100% - 20px); height: calc(100% - 20px); border-radius: 25px; object-fit: cover; }
.me__title {
  font: 700 clamp(48px, 6vw, 104px)/.92 var(--font-display); letter-spacing: -.045em;
  color: var(--cobalt-deep);
}
.me__list { display: grid; gap: 4px; margin-top: clamp(28px, 4vw, 48px); }
.me__item {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 8px clamp(16px, 1.5vw, 24px);
  padding: 18px 0; border-top: 2px solid var(--rule);
}
.me__item .sticker { width: clamp(40px, 3vw, 52px); height: auto; }
.me__item p { font: 600 clamp(20px, 1.7vw, 27px)/1.25 var(--font-display); letter-spacing: -.015em; text-wrap: pretty; }
.me__item .beat__link { color: var(--ink-fixed); }
.me__scale { position: static; grid-column: 1; margin-top: -8px; color: var(--ink-soft); }

/* ---------------------------------------------------------------------------
   Phone: the subject in the top of the frame, the words below it
   --------------------------------------------------------------------------- */
@media (max-width: 820px) {
  /* the scene settles into its own atmosphere toward the bottom, where the words are */
  .stage::after, .beat__still::after {
    background: linear-gradient(to top, var(--h) 0%, var(--h) 30%, color-mix(in srgb, var(--h) 0%, transparent) 60%);
  }
  .powers { right: auto; left: var(--gutter); top: calc(var(--chrome-h) - 6px); bottom: auto; gap: 10px; }
  .powers__bar { width: 64px; }
  .powers__t { min-width: 0; }
  .beat { align-content: end; padding: calc(var(--chrome-h) + 16px) var(--gutter) 64px; }
  .beat__text { max-width: none; }
  .beat__title { font-size: clamp(30px, 8.6vw, 40px); }
  .beat__text p { font-size: 17px; }
  .beat--hero { align-content: end; padding-bottom: 56px; }
  .beat--hero .beat__text { max-width: none; }
  .hero__name { font-size: clamp(64px, 21vw, 104px); }
  .beat__scale { bottom: 18px; }
  .me__grid { grid-template-columns: minmax(0, 1fr); }
  .me__frame { max-width: 320px; margin: 0 auto 0 8px; }
  .me__item { grid-template-columns: auto minmax(0, 1fr); }
  .me__item .beat__link { grid-column: 2; }
}
