/* ==========================================================================
   MERIDIAN — Reset, atmosphere, typography, shared surfaces
   ========================================================================== */

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

html{
  /* Do NOT set `scroll-behavior: smooth` here. It corrupts ScrollTrigger.refresh():
     measurement scrolls land mid-animation and scrubs stick. Anchor smoothing is
     handled in JS. */
  background: var(--linen);
  -webkit-text-size-adjust: 100%;
}

body{
  margin: 0;
  background: var(--linen);
  color: var(--obsidian);
  font-family: var(--mono);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  overflow-x: hidden;
}

body.is-transitioning{ overflow: hidden; }

::selection{ background: var(--cobalt); color: var(--linen); }

h1, h2, h3, h4{
  font-family: var(--serif);
  font-weight: 500;
  margin: 0;
  line-height: var(--lh-head);
  text-wrap: balance;
}

p{ margin: 0; text-wrap: pretty; }
a{ color: inherit; text-decoration: none; }
img{ max-width: 100%; display: block; }

button{ font: inherit; color: inherit; background: none; border: none; padding: 0; }

/* ---- focus ------------------------------------------------------------- */

:where(a, button, input, textarea, [tabindex]):focus{ outline: none; }

:where(a, button, input, textarea, [tabindex]):focus-visible{
  outline: 2px solid var(--cobalt);
  outline-offset: 3px;
  border-radius: var(--radius);
}

.skip-link{
  position: fixed;
  top: 0; left: 50%;
  transform: translate(-50%, -140%);
  z-index: var(--z-cursor);
  padding: .8rem 1.4rem;
  background: var(--obsidian);
  color: var(--linen);
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  transition: transform var(--dur-fast) var(--ease-out-quart);
}
.skip-link:focus-visible{ transform: translate(-50%, 0); outline-offset: -4px; }

/* ---- atmosphere -------------------------------------------------------- */

#fluid-canvas{
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: var(--z-canvas);
  background: var(--linen);
}

.grain{
  position: fixed;
  inset: -10%;
  width: 120%;
  height: 120%;
  z-index: var(--z-atmosphere);
  pointer-events: none;
  opacity: .045;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  background-size: 180px 180px;
}

.vignette{
  position: fixed;
  inset: 0;
  z-index: var(--z-atmosphere);
  pointer-events: none;
  box-shadow: inset 0 0 22vw var(--obsidian-10);
}

main{
  position: relative;
  z-index: var(--z-content);
}

/* ---- shared type ------------------------------------------------------- */

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

.annotation{
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--obsidian-62);
  font-weight: 500;
}
.annotation--cobalt{ color: var(--cobalt); }

/* The bracket label is a named brand system, not a section eyebrow. It is set
   in the margin as a technical annotation wherever the column width allows. */
.margin-note{
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--obsidian-62);
}

.lede{
  font-size: var(--t-h4);
  line-height: 1.62;
  color: var(--obsidian-70);
  max-width: var(--measure);
}

.prose{
  font-size: var(--t-body);
  line-height: var(--lh-body);
  color: var(--obsidian-70);
  max-width: var(--measure);
}
.prose--fine{ font-size: var(--t-small); color: var(--obsidian-62); }

/* ---- panels (the fluid's solid obstacles) ------------------------------ */

.panel{
  position: relative;
  background: var(--panel);
  backdrop-filter: var(--panel-blur);
  -webkit-backdrop-filter: var(--panel-blur);
  border: 1px solid var(--obsidian-08);
  border-radius: var(--radius);
}
.panel--solid{
  background: var(--panel-solid);
  box-shadow: 0 1rem 2.4rem -1.4rem var(--obsidian-16);
}

/* ---- scene scaffolding ------------------------------------------------- */

.scene{
  position: relative;
  width: 100%;
  padding-inline: var(--edge);
}

.page-head{
  min-height: 62svh;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding-block: clamp(7rem, 14vh, 11rem) var(--gap-l);
  border-bottom: 1px solid var(--obsidian-08);
}
.page-head__title{
  font-size: var(--t-display);
  line-height: var(--lh-display);
  letter-spacing: var(--ls-display);
  margin-top: var(--gap-s);
}
.page-head__lede{ margin-top: var(--gap-s); max-width: 46ch; }

/* ---- kinetic type primitives ------------------------------------------- */

/* A masked line: the inner span slides up out of an overflow-hidden clip.
   Content is visible by default; JS opts in by adding [data-mask-ready]. */
.mask-line{ display: block; overflow: hidden; }
.mask-line > span{ display: inline-block; }

[data-mask-ready] .mask-line > span{ transform: translateY(105%); }

/* ---- reveal safety net -------------------------------------------------
   Nothing is gated on a class-triggered transition. If JS never runs, or the
   renderer is headless, content sits at its final state. JS sets the "from"
   state at runtime only when it is about to animate it. */

.scroll-cue{
  display: inline-flex;
  align-items: center;
  gap: .7rem;
  font-size: var(--t-micro);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--obsidian-62);
}
.scroll-cue__rail{
  width: 1px;
  height: 34px;
  background: var(--obsidian-18);
  position: relative;
  overflow: hidden;
}
.scroll-cue__rail::after{
  content: "";
  position: absolute;
  left: 0; top: -100%;
  width: 100%; height: 100%;
  background: var(--cobalt);
  animation: cue-drip 2.2s var(--ease-out-quart) infinite;
}
@keyframes cue-drip{
  0%   { top: -100%; }
  60%  { top: 100%; }
  100% { top: 100%; }
}

/* ---- rules ------------------------------------------------------------- */

.rule{
  height: 1px;
  background: var(--obsidian-12);
  transform-origin: left center;
  border: 0;
  margin: 0;
}

/* ---- shared handoff --------------------------------------------------- */

.handoff{
  padding-block: var(--gap-l) var(--gap-xl);
}

.handoff__link{
  display: inline-flex;
  align-items: baseline;
  gap: var(--gap-s);
  font-family: var(--serif);
  font-size: var(--t-h1);
  line-height: 1.1;
  letter-spacing: var(--ls-display);
  color: var(--obsidian);
}
.handoff__arrow{
  display: inline-block;
  font-family: var(--mono);
  font-size: .32em;
  transform: translateX(0);
  transition: transform var(--dur-mid) var(--ease-out-expo);
}
.handoff__link:hover .handoff__arrow{ transform: translateX(.9rem); }

.handoff__rule{
  margin-top: var(--gap-s);
  transform: scaleX(0);
  transform-origin: left center;
}
.handoff__link:hover + .handoff__rule{ transform: scaleX(1); }

/* ---- footer ------------------------------------------------------------ */

.site-foot{
  position: relative;
  z-index: var(--z-content);
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-s);
  align-items: baseline;
  justify-content: space-between;
  padding: var(--gap-m) var(--edge) var(--gap-s);
  margin-top: var(--gap-xl);
  border-top: 1px solid var(--obsidian-08);
  font-size: var(--t-micro);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--obsidian-62);
}
.site-foot a{ color: var(--obsidian-62); }
.site-foot a:hover{ color: var(--cobalt); }

@media (prefers-reduced-motion: reduce){
  .scroll-cue__rail::after{ animation: none; top: 0; opacity: .4; }
  *, *::before, *::after{
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
