/* ══════════════════════════════════════════════════════════════════════════
   ESP Heroes — components and motion.
   No inline styles anywhere, so the page runs under a strict CSP with no
   'unsafe-inline'. Requires theme.css first.
   ══════════════════════════════════════════════════════════════════════ */

*,*::before,*::after{box-sizing:border-box}

html{
  scroll-behavior:smooth;
  /* the sticky nav must not cover the target of an in-page anchor */
  scroll-padding-top:6rem;
  -webkit-text-size-adjust:100%;
}

body{
  margin:0;
  background:var(--ink-000);
  color:var(--text);
  font-family:var(--font-body);
  font-size:var(--t-md);
  line-height:1.65;
  font-synthesis-weight:none;
  text-rendering:optimizeLegibility;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
  text-wrap:pretty;
}

img,picture,svg,video{display:block;max-width:100%}
button{font:inherit;color:inherit;background:none;border:0}

/* Focus: one ring, everywhere, never removed. */
:focus{outline:none}
:focus-visible{
  outline:2px solid var(--gold);
  outline-offset:3px;
  border-radius:var(--r-sm);
}
::selection{background:rgba(227,179,65,.28);color:var(--text)}

h1,h2,h3,h4{
  font-family:var(--font-display);
  font-weight:500;
  line-height:1.06;
  letter-spacing:-.02em;
  margin:0;
  text-wrap:balance;
}

p{margin:0}
a{color:var(--gold);text-decoration:none}

.u-visually-hidden{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}

.skip{
  position:absolute;top:-100px;left:var(--s-4);z-index:var(--z-intro);
  padding:.75rem 1.25rem;border-radius:var(--r-sm);
  background:var(--ink-200);color:var(--text);
  border:1px solid var(--gold);font-size:var(--t-sm);
  transition:top var(--d-ui) var(--ease-out);
}
.skip:focus{top:var(--s-4)}

.wrap{
  width:100%;max-width:var(--measure);
  margin-inline:auto;padding-inline:var(--gutter);
  position:relative;z-index:var(--z-content);
}

/* ═══════════════════════════════════════════════════════════════════════
   1 · AMBIENT FIELD — the aurora mesh behind everything
   Four blurred blobs on long, offset loops. Because they are heavily
   blurred and slow, they read as one shifting field rather than as four
   moving objects — which is how this stays "very animated" without
   tripping the excessive-motion rule.
   ═══════════════════════════════════════════════════════════════════════ */
.field{
  position:fixed;inset:0;z-index:var(--z-bg);
  pointer-events:none;overflow:hidden;
  /* Own compositor layer: the blobs never repaint the content above them. */
  contain:strict;
}
.field b{
  position:absolute;display:block;border-radius:50%;
  will-change:transform;
}
.field-1{
  top:-28vh;right:-14vw;width:78vw;height:78vw;
  background:radial-gradient(circle,rgba(227,179,65,.42),rgba(227,179,65,0) 62%);
  filter:blur(90px);
  animation:drift-a 30s var(--ease-in-out) infinite,breathe 13s ease-in-out infinite;
}
.field-2{
  bottom:-34vh;left:-20vw;width:70vw;height:70vw;
  background:radial-gradient(circle,rgba(140,123,224,.44),rgba(140,123,224,0) 60%);
  filter:blur(100px);
  animation:drift-b 42s var(--ease-in-out) infinite;
}
.field-3{
  top:34vh;left:26vw;width:52vw;height:52vw;
  border-radius:46% 54% 60% 40%/50% 44% 56% 50%;
  background:conic-gradient(from 0deg,rgba(91,200,216,.26),transparent 38%,rgba(227,179,65,.20) 68%,transparent);
  filter:blur(110px);opacity:.8;
  animation:spin 80s linear infinite;
}
.field-4{
  top:8vh;left:52vw;width:30vw;height:30vw;
  background:radial-gradient(circle,rgba(232,115,74,.30),rgba(232,115,74,0) 64%);
  filter:blur(80px);
  animation:drift-c 36s var(--ease-in-out) infinite;
}
/* Vignette — pins the corners down so text never floats on a bright patch. */
.field-vignette{
  position:absolute;inset:0;
  background:
    radial-gradient(125% 85% at 50% 0%,transparent 52%,rgba(8,7,11,.55) 100%),
    radial-gradient(90% 70% at 20% 110%,rgba(8,7,11,.7),transparent 62%);
}
/* Film grain — kills the banding that big blurred gradients show on 8-bit
   panels, and adds the print texture the editorial direction wants. */
.field-grain{
  position:absolute;inset:-200%;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.42'/%3E%3C/svg%3E");
  opacity:.30;mix-blend-mode:overlay;
  animation:grain 6s steps(6) infinite;
}

@keyframes drift-a{
  0%,100%{transform:translate3d(-4%,-3%,0) scale(1)}
  33%{transform:translate3d(7%,6%,0) scale(1.16)}
  66%{transform:translate3d(-3%,9%,0) scale(1.04)}
}
@keyframes drift-b{
  0%,100%{transform:translate3d(3%,7%,0) scale(1.08)}
  50%{transform:translate3d(-9%,-6%,0) scale(1.28)}
}
@keyframes drift-c{
  0%,100%{transform:translate3d(0,0,0) scale(1)}
  50%{transform:translate3d(-12%,10%,0) scale(1.22)}
}
@keyframes spin{to{transform:rotate(360deg) scale(1.2)}}
@keyframes breathe{0%,100%{opacity:.5}50%{opacity:.95}}
@keyframes grain{
  0%,100%{transform:translate(0,0)}     10%{transform:translate(-4%,-3%)}
  30%{transform:translate(3%,-4%)}      50%{transform:translate(-3%,4%)}
  70%{transform:translate(4%,3%)}       90%{transform:translate(-2%,2%)}
}

/* ═══════════════════════════════════════════════════════════════════════
   2 · CHROME — intro curtain, scroll rail, cursor
   ═══════════════════════════════════════════════════════════════════════ */

/* Intro curtain: one wipe on first paint, then it removes itself. */
.intro{
  position:fixed;inset:0;z-index:var(--z-intro);
  background:var(--ink-000);
  display:grid;place-items:center;
  animation:curtain 1.1s var(--ease-in-out) .45s forwards;
}
.intro-mark{
  font-family:var(--font-display);
  font-size:clamp(1.5rem,5vw,2.5rem);
  letter-spacing:.06em;color:var(--gold);
  animation:mark-in .8s var(--ease-out) both;
}
@keyframes curtain{to{transform:translateY(-101%)}}
@keyframes mark-in{
  from{opacity:0;transform:translateY(14px) scale(.96);filter:blur(8px)}
  to{opacity:1;transform:none;filter:none}
}
.intro[hidden]{display:none}

/* Scroll rail — a hairline that fills as you read. */
.rail{
  position:fixed;top:0;left:0;right:0;height:2px;
  z-index:var(--z-overlay);pointer-events:none;
  background:linear-gradient(90deg,var(--gold-deep),var(--gold),var(--cyan));
  transform:scaleX(0);transform-origin:0 50%;
  will-change:transform;
}
/* Where the browser supports it, the rail is driven by the scroll timeline
   itself — no JS, no scroll listener, runs off the main thread. The JS
   fallback below handles everything else. */
@supports (animation-timeline:scroll()){
  .rail{
    animation:rail-fill linear;
    animation-timeline:scroll(root block);
  }
  html.js .rail{transform:scaleX(0)}
}
@keyframes rail-fill{from{transform:scaleX(0)}to{transform:scaleX(1)}}

/* Cursor: a soft gold light that trails the pointer, plus a small ring that
   snaps to it. Fine pointers only — see the media query at the foot. */
.cursor-glow,.cursor-dot{
  position:fixed;top:0;left:0;z-index:var(--z-cursor);
  pointer-events:none;border-radius:50%;
  will-change:transform;
  /* Parked at 0,0 until the pointer first moves — without this the ring sits
     visibly in the top-left corner on load. app.js adds .cursor-live. */
  opacity:0;
}
body.cursor-live .cursor-glow{opacity:.5}
body.cursor-live .cursor-dot{opacity:1}
.cursor-glow{
  width:520px;height:520px;margin:-260px 0 0 -260px;
  background:radial-gradient(circle,rgba(227,179,65,.16),transparent 62%);
  filter:blur(34px);
  transition:transform .55s var(--ease-out),opacity var(--d-ui) ease;
}
.cursor-dot{
  width:34px;height:34px;margin:-17px 0 0 -17px;
  border:1px solid var(--gold-line);
  transition:transform .1s linear,width .3s var(--ease-spring),
             height .3s var(--ease-spring),margin .3s var(--ease-spring),
             background-color var(--d-ui) ease,border-color var(--d-ui) ease;
}
/* grows and fills when over anything interactive */
body.is-hovering .cursor-dot{
  width:64px;height:64px;margin:-32px 0 0 -32px;
  background:rgba(227,179,65,.14);
  border-color:var(--gold);
}

/* ═══════════════════════════════════════════════════════════════════════
   3 · NAV — glass that thickens on scroll
   ═══════════════════════════════════════════════════════════════════════ */
.nav{
  position:sticky;top:0;z-index:var(--z-sticky);
  display:flex;align-items:center;gap:var(--s-5);
  padding:var(--s-4) var(--gutter);
  border-bottom:1px solid transparent;
  transition:background-color var(--d-slow) var(--ease-out),
             border-color var(--d-slow) ease,
             padding var(--d-slow) var(--ease-out),
             backdrop-filter var(--d-slow) ease;
}
.nav.is-stuck{
  background:var(--glass-veil);
  -webkit-backdrop-filter:var(--glass-blur);
          backdrop-filter:var(--glass-blur);
  border-bottom-color:var(--glass-edge-soft);
  padding-block:var(--s-3);
}
.brand{
  display:inline-flex;align-items:center;gap:.6rem;
  margin-right:auto;font-family:var(--font-display);
  font-size:1.2rem;letter-spacing:.01em;color:var(--text);
}
.brand svg{width:22px;height:22px;color:var(--gold);flex:none}
.brand em{font-style:italic;color:var(--gold)}

.nav-links{display:flex;align-items:center;gap:var(--s-5)}
.nav-link{
  position:relative;font-size:var(--t-sm);letter-spacing:.02em;
  color:var(--text-muted);padding-block:.35rem;
  transition:color var(--d-ui) ease;
}
/* underline grows from the left — colour change plus a transform, so no
   layout shift on hover */
.nav-link::after{
  content:'';position:absolute;left:0;right:0;bottom:0;height:1px;
  background:var(--gold);transform:scaleX(0);transform-origin:0 50%;
  transition:transform var(--d-ui) var(--ease-out);
}
.nav-link:hover,.nav-link:focus-visible{color:var(--text)}
.nav-link:hover::after,.nav-link:focus-visible::after{transform:scaleX(1)}

.lang{
  display:inline-flex;align-items:center;gap:2px;padding:3px;
  border:1px solid var(--glass-edge-soft);border-radius:var(--r-pill);
  background:rgba(255,255,255,.03);
}
.lang a{
  font-size:var(--t-xs);letter-spacing:.08em;text-transform:uppercase;
  padding:.35rem .7rem;border-radius:var(--r-pill);line-height:1;
  color:var(--text-dim);transition:color var(--d-ui) ease,background-color var(--d-ui) ease;
}
.lang a:hover{color:var(--text);background:rgba(255,255,255,.06)}
.lang a[aria-current="true"]{color:var(--ink-000);background:var(--gold);font-weight:600}

/* ═══════════════════════════════════════════════════════════════════════
   4 · BUTTONS
   ═══════════════════════════════════════════════════════════════════════ */
.btn{
  --btn-bg:transparent;
  position:relative;display:inline-flex;align-items:center;justify-content:center;
  gap:.6rem;cursor:pointer;
  /* 44px floor — the touch-target rule, enforced on every variant */
  min-height:48px;padding:.75rem 1.6rem;
  font-size:var(--t-sm);font-weight:500;letter-spacing:.02em;
  white-space:nowrap;
  border-radius:var(--r-pill);
  border:1px solid var(--gold-line);
  color:var(--gold);background:var(--btn-bg);
  overflow:hidden;isolation:isolate;
  transition:color var(--d-ui) ease,border-color var(--d-ui) ease,
             box-shadow var(--d-ui) ease,transform var(--d-fast) var(--ease-out);
}
.btn svg{width:1.05em;height:1.05em;flex:none;transition:transform var(--d-ui) var(--ease-out)}
/* fill sweeps up from the bottom rather than the button changing size */
.btn::before{
  content:'';position:absolute;inset:0;z-index:-1;
  background:var(--gold);
  transform:translateY(101%);
  transition:transform var(--d-ui) var(--ease-out);
}
.btn:hover,.btn:focus-visible{color:var(--ink-000);border-color:var(--gold)}
.btn:hover::before,.btn:focus-visible::before{transform:translateY(0)}
.btn:hover svg{transform:translate(3px,-3px)}
.btn:active{transform:translateY(1px)}

.btn-solid{background:var(--gold);color:var(--ink-000);border-color:var(--gold);font-weight:600}
.btn-solid::before{background:var(--gold-lift)}
.btn-solid:hover,.btn-solid:focus-visible{color:var(--ink-000)}

.btn-quiet{border-color:var(--glass-edge);color:var(--text-muted)}
.btn-quiet::before{background:rgba(255,255,255,.09)}
.btn-quiet:hover,.btn-quiet:focus-visible{color:var(--text);border-color:var(--glass-edge)}

.btn-lg{min-height:56px;padding-inline:2rem;font-size:var(--t-base)}
.btn svg.no-shift{transition:none}
.btn:hover svg.no-shift{transform:none}

/* ═══════════════════════════════════════════════════════════════════════
   5 · GLASS SURFACES
   ═══════════════════════════════════════════════════════════════════════ */
.pane{
  position:relative;
  background:var(--glass-pane),rgba(18,17,26,.55);
  -webkit-backdrop-filter:var(--glass-blur);
          backdrop-filter:var(--glass-blur);
  border:1px solid var(--glass-edge-soft);
  border-radius:var(--r-lg);
  overflow:hidden;
}
/* specular sheen along the top edge — what sells it as glass */
.pane::after{
  content:'';position:absolute;top:0;left:8%;right:8%;height:1px;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.42),transparent);
  pointer-events:none;
}

/* ═══════════════════════════════════════════════════════════════════════
   6 · SECTION FURNITURE
   ═══════════════════════════════════════════════════════════════════════ */
.section{padding-block:clamp(4rem,10vh,8.5rem);position:relative;z-index:var(--z-content)}
.section-tight{padding-block:clamp(2.5rem,6vh,5rem)}

.eyebrow{
  display:flex;align-items:center;gap:.85rem;
  font-family:var(--font-body);font-size:var(--t-xs);font-weight:500;
  letter-spacing:.2em;text-transform:uppercase;color:var(--gold);
  margin-bottom:var(--s-4);
}
.eyebrow::before{
  content:'';width:2.5rem;height:1px;background:var(--gold);
  transform-origin:0 50%;flex:none;
}
.eyebrow-num{
  font-variant-numeric:tabular-nums;color:var(--text-dim);
  margin-left:auto;letter-spacing:.12em;
}

.h-display{font-size:var(--t-3xl)}
.h-section{font-size:var(--t-2xl)}
.lede{
  font-size:var(--t-lg);line-height:1.7;color:var(--text-muted);
  max-width:var(--measure-text);
}

/* ═══════════════════════════════════════════════════════════════════════
   7 · HERO
   ═══════════════════════════════════════════════════════════════════════ */
.hero{
  position:relative;z-index:var(--z-content);
  padding-block:clamp(3rem,9vh,7rem) clamp(3rem,7vh,5.5rem);
}
.hero-grid{
  display:grid;grid-template-columns:minmax(0,1.4fr) minmax(0,.82fr);
  gap:clamp(2rem,5vw,5rem);align-items:center;
}
.hero h1{
  font-size:var(--t-4xl);line-height:.98;letter-spacing:-.035em;
  margin-left:-.05em;
}
.hero h1 em{
  font-style:italic;font-weight:400;
  background:linear-gradient(105deg,var(--gold-lift),var(--gold) 40%,var(--ember));
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;color:var(--gold);
}
/* Line-by-line mask reveal. Each line sits in a clipping box and slides up
   into it, so the type appears to rise out of the page rather than fade in. */
.line{display:block;overflow:hidden;padding-bottom:.06em}
.line > span{display:block;transform:translateY(110%);will-change:transform}
html.js .hero .line > span{animation:line-up 1.05s var(--ease-out) both}
html.js .hero .line:nth-of-type(1) > span{animation-delay:.10s}
html.js .hero .line:nth-of-type(2) > span{animation-delay:.20s}
html.js .hero .line:nth-of-type(3) > span{animation-delay:.30s}
@keyframes line-up{from{transform:translateY(110%)}to{transform:translateY(0)}}

.hero-sub{margin-top:var(--s-5);max-width:52ch}
.hero-actions{display:flex;flex-wrap:wrap;gap:var(--s-3);margin-top:var(--s-6)}
.hero-meta{
  display:flex;flex-wrap:wrap;gap:var(--s-5);margin-top:var(--s-6);
  padding-top:var(--s-5);border-top:1px solid var(--glass-edge-soft);
}
.hero-meta div{display:flex;flex-direction:column;gap:.15rem}
.hero-meta dt{font-size:var(--t-xs);letter-spacing:.16em;text-transform:uppercase;color:var(--text-dim)}
.hero-meta dd{
  margin:0;font-family:var(--font-display);font-size:1.55rem;color:var(--text);
  font-variant-numeric:tabular-nums;
}

/* fade-in-up for the supporting hero bits */
html.js .rise{animation:rise .9s var(--ease-out) both}
html.js .rise-1{animation-delay:.44s}
html.js .rise-2{animation-delay:.56s}
html.js .rise-3{animation-delay:.68s}
@keyframes rise{from{opacity:0;transform:translateY(26px)}to{opacity:1;transform:none}}

/* portrait */
.portrait{position:relative;margin:0}
.portrait-frame{
  position:relative;border-radius:var(--r-xl);overflow:hidden;
  border:1px solid var(--glass-edge);
  box-shadow:var(--shadow-lg);
  will-change:transform;
}
.portrait-frame img{
  width:100%;height:auto;transform:scale(1.02);
  filter:grayscale(.85) contrast(1.05) brightness(.95);
}
/* Duotone. The photo is shot on a pale studio background, so left alone it is
   a bright slab in a dark layout. Stripping it to greyscale and re-tinting
   through `color` blend pulls it into the gold/violet palette; the second
   layer sinks the bottom edge into the page. */
.portrait-frame::before{
  content:'';position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(155deg,var(--gold) 5%,#6E5FBF 95%);
  mix-blend-mode:color;opacity:.42;
}
.portrait-frame::after{
  content:'';position:absolute;inset:0;z-index:2;pointer-events:none;
  background:linear-gradient(180deg,rgba(227,179,65,.10),transparent 42%,rgba(8,7,11,.78));
}
.portrait-halo{
  position:absolute;inset:-16%;z-index:-1;border-radius:50%;
  background:radial-gradient(circle,rgba(227,179,65,.30),transparent 66%);
  filter:blur(50px);
  animation:breathe-slow 15s ease-in-out infinite;
}
@keyframes breathe-slow{
  0%,100%{transform:scale(1) translate(0,0);opacity:.75}
  50%{transform:scale(1.14) translate(-3%,3%);opacity:1}
}
/* floating credential chip */
.portrait-chip{
  position:absolute;z-index:3;bottom:-1.1rem;left:-1.1rem;
  display:flex;align-items:center;gap:.6rem;
  padding:.7rem 1.1rem;border-radius:var(--r-pill);
  background:var(--glass-veil);
  -webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);
  border:1px solid var(--glass-edge);
  font-size:var(--t-xs);letter-spacing:.1em;text-transform:uppercase;
  color:var(--text);box-shadow:var(--shadow-md);
  animation:bob 7s ease-in-out infinite;
}
.portrait-chip svg{width:15px;height:15px;color:var(--gold)}
@keyframes bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-9px)}}

/* ═══════════════════════════════════════════════════════════════════════
   8 · MARQUEE
   ═══════════════════════════════════════════════════════════════════════ */
.marquee{
  position:relative;z-index:var(--z-content);
  padding-block:var(--s-4);overflow:hidden;
  border-block:1px solid var(--glass-edge-soft);
  background:rgba(255,255,255,.015);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 10%,#000 90%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 10%,#000 90%,transparent);
}
.marquee-track{display:flex;width:max-content;animation:slide 46s linear infinite}
.marquee:hover .marquee-track{animation-play-state:paused}
.marquee-row{
  display:flex;align-items:center;gap:2.75rem;padding-right:2.75rem;
  font-size:var(--t-sm);letter-spacing:.18em;text-transform:uppercase;
  color:var(--text-dim);white-space:nowrap;
}
.marquee-row i{
  font-style:normal;color:var(--gold);font-size:.7em;
  transform:translateY(-1px);
}
@keyframes slide{to{transform:translateX(-50%)}}

/* ═══════════════════════════════════════════════════════════════════════
   9 · SPLIT — the "what is ESP" statement
   ═══════════════════════════════════════════════════════════════════════ */
.split{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);gap:clamp(2rem,5vw,5.5rem)}
.statement{
  font-family:var(--font-display);font-size:var(--t-xl);line-height:1.5;
  color:var(--text);max-width:var(--measure-text);
}
.statement strong{color:var(--gold);font-weight:500;font-style:italic}
.note{
  margin-top:var(--s-5);padding-left:var(--s-5);
  border-left:1px solid var(--gold-line);
  font-size:var(--t-base);line-height:1.75;color:var(--text-muted);
  font-style:italic;max-width:56ch;
}
.note cite{display:block;margin-top:.6rem;font-style:normal;font-size:var(--t-xs);
  letter-spacing:.16em;text-transform:uppercase;color:var(--text-dim)}

/* ═══════════════════════════════════════════════════════════════════════
   10 · METHOD — numbered glass cards
   ═══════════════════════════════════════════════════════════════════════ */
.method{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,17rem),1fr));gap:var(--s-4)}
.method-card{
  padding:clamp(1.75rem,3vw,2.5rem);
  transition:transform var(--d-slow) var(--ease-out),
             border-color var(--d-slow) ease,box-shadow var(--d-slow) ease;
}
.method-card:hover{
  transform:translateY(-6px);
  border-color:var(--gold-line);
  box-shadow:var(--shadow-gold);
}
.method-card .num{
  font-family:var(--font-display);font-size:2.6rem;line-height:1;
  color:transparent;-webkit-text-stroke:1px var(--gold-line);
  transition:color var(--d-slow) ease,-webkit-text-stroke-color var(--d-slow) ease;
}
.method-card:hover .num{color:var(--gold-ghost);-webkit-text-stroke-color:var(--gold)}
.method-card h3{font-size:var(--t-xl);margin:var(--s-4) 0 var(--s-3)}
.method-card p{font-size:var(--t-base);line-height:1.7;color:var(--text-muted)}
.method-card svg{width:26px;height:26px;color:var(--gold);margin-bottom:var(--s-3)}

/* ═══════════════════════════════════════════════════════════════════════
   11 · PULL QUOTE
   ═══════════════════════════════════════════════════════════════════════ */
.quote-band{
  position:relative;z-index:var(--z-content);
  padding-block:clamp(4rem,9vh,7.5rem);
  border-block:1px solid var(--glass-edge-soft);
  background:
    radial-gradient(80% 120% at 85% -20%,rgba(140,123,224,.20),transparent 62%),
    radial-gradient(60% 100% at 10% 120%,rgba(227,179,65,.14),transparent 60%),
    rgba(13,12,18,.5);
}
.quote{
  font-family:var(--font-display);font-size:var(--t-3xl);
  line-height:1.18;letter-spacing:-.025em;max-width:20ch;margin:0;
  text-wrap:balance;
}
.quote em{font-style:italic;color:var(--gold)}
.quote-mark{
  font-family:var(--font-display);font-size:7rem;line-height:.6;
  color:var(--gold-line);display:block;margin-bottom:-.1em;
}
.quote-by{
  margin-top:var(--s-6);font-size:var(--t-xs);letter-spacing:.2em;
  text-transform:uppercase;color:var(--text-dim);
}

/* ═══════════════════════════════════════════════════════════════════════
   12 · PROGRAMS — tilting glass cards
   ═══════════════════════════════════════════════════════════════════════ */
.programs-head{
  display:flex;flex-wrap:wrap;gap:var(--s-5);
  align-items:flex-end;justify-content:space-between;
  margin-bottom:clamp(2rem,5vh,3.5rem);
}
/* Exactly four programs, so auto-fit is wrong here: at three columns it
   orphans the fourth card next to a column of empty space. A fixed 2x2 stays
   balanced at every desktop width and gives each card more presence. */
.cards{display:grid;grid-template-columns:1fr;gap:var(--s-4)}
@media (min-width:760px){
  .cards{grid-template-columns:repeat(2,minmax(0,1fr))}
}

.card{
  /* set by JS on pointermove; the card reads them, so no inline style strings */
  --mx:50%;--my:50%;--rx:0deg;--ry:0deg;
  display:flex;flex-direction:column;
  transform:perspective(1000px) rotateX(var(--rx)) rotateY(var(--ry));
  transform-style:preserve-3d;
  transition:transform var(--d-slow) var(--ease-out),
             border-color var(--d-slow) ease,box-shadow var(--d-slow) ease;
  will-change:transform;
}
.card:hover{border-color:var(--gold-line);box-shadow:var(--shadow-lg)}
/* the pointer spotlight, positioned from the same custom properties */
.card::before{
  content:'';position:absolute;inset:0;z-index:1;pointer-events:none;
  background:radial-gradient(20rem 20rem at var(--mx) var(--my),rgba(227,179,65,.16),transparent 70%);
  opacity:0;transition:opacity var(--d-slow) ease;
}
.card:hover::before{opacity:1}

.card-media{position:relative;overflow:hidden;border-bottom:1px solid var(--glass-edge-soft)}
.card-media img{
  width:100%;height:auto;aspect-ratio:16/10;object-fit:cover;
  transition:transform 1.1s var(--ease-out),filter var(--d-slow) ease;
  filter:grayscale(.55) contrast(1.05);
}
.card:hover .card-media img{transform:scale(1.07);filter:grayscale(0) contrast(1)}
.card-media::after{
  content:'';position:absolute;inset:0;
  background:linear-gradient(180deg,transparent 40%,rgba(8,7,11,.9));
}
.card-index{
  position:absolute;top:var(--s-4);left:var(--s-4);z-index:2;
  font-family:var(--font-display);font-size:var(--t-sm);letter-spacing:.14em;
  padding:.35rem .8rem;border-radius:var(--r-pill);
  background:var(--glass-veil);border:1px solid var(--glass-edge);
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  color:var(--gold);
}
.card-body{padding:clamp(1.5rem,2.4vw,2rem);display:flex;flex-direction:column;flex:1}
.card-body h3{font-size:var(--t-xl);margin-bottom:var(--s-3)}
.card-blurb{font-size:var(--t-base);line-height:1.7;color:var(--text-muted);margin-bottom:var(--s-5)}
.card dl{display:grid;gap:.7rem;margin:auto 0 0;font-size:var(--t-sm)}
.card dl > div{
  display:grid;grid-template-columns:5.5rem 1fr;gap:var(--s-3);
  padding-top:.7rem;border-top:1px solid var(--glass-edge-soft);
}
.card dt{
  font-size:var(--t-xs);letter-spacing:.13em;text-transform:uppercase;
  color:var(--gold);padding-top:.15rem;
}
.card dd{margin:0;color:var(--text-muted);line-height:1.55}

/* ═══════════════════════════════════════════════════════════════════════
   13 · FAQ — native <details>, no JS needed
   ═══════════════════════════════════════════════════════════════════════ */
.faq{max-width:56rem}
.faq details{border-bottom:1px solid var(--glass-edge-soft)}
.faq summary{
  display:flex;align-items:center;justify-content:space-between;gap:var(--s-5);
  cursor:pointer;list-style:none;padding-block:clamp(1.1rem,2vw,1.6rem);
  font-family:var(--font-display);font-size:var(--t-xl);line-height:1.3;
  color:var(--text);transition:color var(--d-ui) ease;
}
.faq summary::-webkit-details-marker{display:none}
.faq summary:hover{color:var(--gold)}
.faq-icon{position:relative;width:20px;height:20px;flex:none}
.faq-icon::before,.faq-icon::after{
  content:'';position:absolute;inset:50% 0 auto;height:1px;
  background:var(--gold);transition:transform var(--d-slow) var(--ease-spring);
}
.faq-icon::after{transform:rotate(90deg)}
.faq details[open] .faq-icon::after{transform:rotate(0)}
.faq-answer{
  padding-bottom:clamp(1.1rem,2vw,1.6rem);
  font-size:var(--t-base);line-height:1.75;color:var(--text-muted);
  max-width:var(--measure-text);
}
/* animate the disclosure where the browser can size it for us */
@supports (interpolate-size:allow-keywords){
  .faq details::details-content{
    block-size:0;overflow:hidden;
    transition:block-size var(--d-slow) var(--ease-out),content-visibility var(--d-slow) allow-discrete;
  }
  .faq details[open]::details-content{block-size:auto}
}

/* ═══════════════════════════════════════════════════════════════════════
   14 · CTA
   ═══════════════════════════════════════════════════════════════════════ */
.cta{
  --mx:50%;--my:50%;
  padding:clamp(2rem,5vw,4.5rem);
  display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,.9fr);
  gap:clamp(2rem,4vw,4rem);align-items:center;
  border-color:var(--gold-line);
  background:
    radial-gradient(30rem 18rem at 88% -30%,rgba(227,179,65,.20),transparent 62%),
    var(--glass-pane),rgba(18,17,26,.6);
}
.cta::before{
  content:'';position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(24rem 24rem at var(--mx) var(--my),rgba(227,179,65,.13),transparent 70%);
  opacity:0;transition:opacity var(--d-slow) ease;
}
.cta:hover::before{opacity:1}
.cta h2{font-size:var(--t-2xl);margin-bottom:var(--s-4)}
.cta-actions{display:flex;flex-direction:column;gap:var(--s-3);position:relative;z-index:2}
.cta-actions .btn{width:100%;justify-content:space-between}
.cta-note{font-size:var(--t-xs);line-height:1.6;color:var(--text-dim);margin-top:.4rem}

/* ═══════════════════════════════════════════════════════════════════════
   15 · FOOTER
   ═══════════════════════════════════════════════════════════════════════ */
.footer{
  position:relative;z-index:var(--z-content);
  border-top:1px solid var(--glass-edge-soft);margin-top:var(--s-7);
}
.footer-row{
  display:flex;flex-wrap:wrap;gap:var(--s-4);
  justify-content:space-between;align-items:center;
  padding-block:var(--s-6);font-size:var(--t-sm);color:var(--text-dim);
}
.footer-links{display:flex;flex-wrap:wrap;gap:var(--s-5)}
.footer-links a{color:var(--text-muted);transition:color var(--d-ui) ease}
.footer-links a:hover{color:var(--gold)}

/* ═══════════════════════════════════════════════════════════════════════
   16 · SCROLL REVEAL
   Preferred path is the native scroll-driven timeline: it runs off the main
   thread and needs no observer. The .js/[data-reveal] path is the fallback
   for browsers without it, released by app.js.
   ═══════════════════════════════════════════════════════════════════════ */
html.js [data-reveal]{opacity:0;transform:translateY(28px)}
html.js [data-reveal].shown{
  opacity:1;transform:none;
  transition:opacity var(--d-fluid) var(--ease-out),transform var(--d-fluid) var(--ease-out);
}

@supports (animation-timeline:view()){
  html.js.native-scroll [data-reveal]{
    opacity:1;transform:none;
    animation:reveal-in linear both;
    animation-timeline:view();
    animation-range:entry 5% cover 26%;
  }
  html.js.native-scroll [data-reveal].shown{transition:none}
}
@keyframes reveal-in{
  from{opacity:0;transform:translateY(34px)}
  to{opacity:1;transform:none}
}

/* ═══════════════════════════════════════════════════════════════════════
   17 · RESPONSIVE
   Checked at 375 / 768 / 1024 / 1440.
   ═══════════════════════════════════════════════════════════════════════ */
@media (max-width:1024px){
  .hero-grid{grid-template-columns:minmax(0,1.2fr) minmax(0,.9fr);gap:2.5rem}
  .split{grid-template-columns:1fr;gap:2rem}
  .cta{grid-template-columns:1fr}
}
/* The hero column gets too narrow for the display type before the nav runs
   out of room, so the two collapse at different widths. */
@media (max-width:1000px){
  .hero-grid{grid-template-columns:1fr}
  .portrait{max-width:22rem;margin-inline:auto;order:-1}
  .hero h1{margin-left:0}
  .quote{max-width:none}
}
@media (max-width:820px){
  .nav-links{display:none}
}
@media (max-width:520px){
  body{font-size:var(--t-base)}      /* never below 16px on mobile */

  /* The nav carries brand + language + CTA on one line at 375px, so every
     piece is trimmed to fit rather than allowed to wrap. */
  .nav{gap:var(--s-2);padding-inline:var(--s-4)}
  .brand{font-size:1rem;gap:.4rem}
  .brand svg{width:18px;height:18px}
  .lang a{padding-inline:.55rem;font-size:.6875rem}
  .nav .btn{padding-inline:.9rem;font-size:.75rem}
  /* Substantive copy comes back up to the 16px floor. The uppercase micro
     labels (.eyebrow, dt, .card-index, .quote-by) stay small on purpose —
     they are labels, not reading text. */
  .card dd,
  .footer-links a,
  .marquee-row{font-size:1rem}
  .card-blurb,.faq-answer,.cta-note{font-size:1rem}
  .hero-meta{gap:var(--s-4)}
  .hero-actions .btn{width:100%}
  .card dl > div{grid-template-columns:1fr;gap:.2rem}
  .footer-row{justify-content:flex-start}
  .portrait-chip{left:50%;transform:translateX(-50%);bottom:-1.4rem;white-space:nowrap}
  @keyframes bob{0%,100%{transform:translateX(-50%) translateY(0)}50%{transform:translateX(-50%) translateY(-9px)}}
}

/* Coarse pointers get no cursor ornament and no tilt. */
@media (pointer:coarse),(hover:none){
  .cursor-glow,.cursor-dot{display:none}
  .card{transform:none}

  /* 44px minimum touch target on every tap-able thing. These read fine as
     compact text links under a mouse, but a finger needs the target — so the
     floor is applied here rather than globally, and it grows the hit area
     with padding instead of the type size, which would break the layout. */
  .lang a,
  .footer-links a,
  .nav-link,
  .brand{
    min-height:44px;
    display:inline-flex;
    align-items:center;
  }
  .lang a{padding-inline:1rem}
  .lang{padding:0}
  .footer-links{gap:var(--s-2) var(--s-5)}
  .footer-links a{padding-block:.5rem}
  /* summary is already tall via its own padding, but pin the floor anyway */
  .faq summary{min-height:44px}
}

/* ═══════════════════════════════════════════════════════════════════════
   18 · REDUCED MOTION
   The whole ornament layer switches off, and — critically — anything that
   starts hidden is forced visible, so no content can be stranded.
   ═══════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
  .intro{display:none}
  .field b,.field-grain{animation:none}
  .cursor-glow,.cursor-dot{display:none}
  .line > span{transform:none !important}
  html.js [data-reveal],
  html.js.native-scroll [data-reveal]{opacity:1 !important;transform:none !important;animation:none !important}
  .card{transform:none !important}
  .marquee-track{animation:none;transform:none}
}
