/* Rushmore Academy motion system. Needs tokens.css. CSS first, GPU friendly (transform, opacity, filter and clip-path only).
   motion.js adds html.ra-js before first paint; every hidden state is scoped to it, so if the script fails everything is simply visible.
   Reduced motion (system setting or the settings panel) makes every reveal static and every scene still, but keeps the layers stacked.

   Reveal: add .reveal to an element. Hidden until it enters the viewport, then .is-in is added and it fades up over --d-reveal.
   data-reveal="fade|up|blur|clip|scale|left" picks the figure; the default is "up". Children of [data-stagger] get --i (0, 1, 2 ...)
   and start --stagger apart. [data-split] headings get each word wrapped in .w and the words arrive one after another.
   Counts: [data-count] numerals count up when revealed. Rules: .rule-draw draws from the left; .rule-caps draws from the center. */
:root {
  --ease-reveal: cubic-bezier(.22, 1, .36, 1);     /* movement: long, soft settle */
  --ease-fade: cubic-bezier(.4, .05, .3, 1);       /* opacity: no snap at the start, reads as a true fade */
  --d-reveal: 950ms; --d-move: 1150ms; --stagger: 90ms; --rv-y: 22px;
}
html.ra-js .reveal { opacity: 0; transform: translate3d(0, var(--rv-y), 0); transition: opacity var(--d-reveal) var(--ease-fade), transform var(--d-move) var(--ease-reveal), filter var(--d-move) var(--ease-fade), clip-path var(--d-move) var(--ease-reveal); transition-delay: calc(var(--i, 0) * var(--stagger)); }
html.ra-js .reveal[data-reveal="fade"] { transform: none; }
html.ra-js .reveal[data-reveal="left"] { transform: translate3d(-28px, 0, 0); }
html.ra-js .reveal[data-reveal="blur"] { filter: blur(10px); transform: translate3d(0, 10px, 0); }
html.ra-js .reveal[data-reveal="clip"] { clip-path: inset(0 0 100% 0); transform: translate3d(0, 12px, 0); }
html.ra-js .reveal[data-reveal="scale"] { transform: scale(1.04); transform-origin: 50% 60%; }
html.ra-js .reveal.is-in { opacity: 1; transform: none; filter: none; clip-path: inset(0 0 0 0); }
/* Words of a split heading arrive one by one, with a small rise. */
.w { display: inline-block; }
html.ra-js [data-split] .w { opacity: 0; transform: translate3d(0, .4em, 0); transition: opacity 800ms var(--ease-fade), transform 1000ms var(--ease-reveal); transition-delay: calc(var(--i, 0) * 70ms + var(--split-delay, 0ms)); }
html.ra-js [data-split].is-in .w, html.ra-js .is-in [data-split] .w { opacity: 1; transform: none; }
/* Rules that draw in */
html.ra-js .rule-draw { transform: scaleX(0); transform-origin: 0 50%; transition: transform 1200ms var(--ease-reveal) calc(var(--i, 0) * var(--stagger) + 120ms); }
html.ra-js .rule-draw.is-in, html.ra-js .is-in .rule-draw, html.ra-js .is-in.rule-draw { transform: scaleX(1); }
html.ra-js .rule-caps::before, html.ra-js .rule-caps::after { transform: scaleX(0); transition: transform 1100ms var(--ease-reveal) 200ms; }
html.ra-js .rule-caps::before { transform-origin: 100% 50%; } html.ra-js .rule-caps::after { transform-origin: 0 50%; }
html.ra-js .is-in .rule-caps::before, html.ra-js .is-in .rule-caps::after { transform: scaleX(1); }
/* Images fade up with a gentle settle from 1.04 */
html.ra-js .reveal-img { overflow: hidden; }
html.ra-js .reveal-img img, html.ra-js .reveal-img svg { transform: scale(1.04); transition: transform 1600ms var(--ease-reveal); }
html.ra-js .reveal-img.is-in img, html.ra-js .reveal-img.is-in svg { transform: none; }
/* Counting numerals keep their width while they change */
[data-count] { font-variant-numeric: lining-nums tabular-nums; }

/* Scroll progress hairline: a gold thread along the top edge. JS writes --p; where scroll driven animations exist the browser drives it. */
.ra-progress { position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 90; background: var(--gold-bright, #D4AC55); transform-origin: 0 50%; transform: scaleX(var(--p, 0)); pointer-events: none; opacity: .9; }
@supports (animation-timeline: scroll()) { html.ra-js .ra-progress { animation: ra-progress linear both; animation-timeline: scroll(root); transform: none; } }
@keyframes ra-progress { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* Depth scenes. A scene is a box of absolutely positioned layers, near to far. Each .lyr carries data-depth (scroll speed ratio);
   motion.js moves .lyr (scroll), .lyr-tilt (pointer) and CSS moves .lyr-drift (ambient). Far layers are lighter, bluer, softer;
   near layers darker and crisper; the nearest and the farthest are slightly out of focus (depth of field). */
.scene-depth { position: relative; overflow: hidden; contain: layout paint style; }
.scene-depth .lyr, .scene-depth .lyr-tilt, .scene-depth .lyr-drift { position: absolute; inset: -6% 0 0 0; }
.scene-depth .lyr { will-change: transform; }
.scene-depth .art, .scene-depth .lyr-img { position: absolute; left: 0; right: 0; bottom: 0; width: 100%; height: 100%; }
.scene-depth .lyr-img { object-fit: cover; object-position: 50% 100%; }
.lyr-far { opacity: .9; } /* aerial perspective is baked into the art's colours; no live blur on big far layers (phones) */
.lyr-fog { opacity: .9; } .lyr-fog .lyr-drift { animation: ra-fog 90s ease-in-out infinite alternate; }
.lyr-fog:nth-of-type(2n) .lyr-drift { animation-duration: 70s; animation-direction: alternate-reverse; }
.lyr-frame .art, .lyr-frame .lyr-img { filter: blur(1.4px); } /* the one live blur: the nearest, smallest layer */
@keyframes ra-fog { from { transform: translate3d(-3%, 0, 0); } to { transform: translate3d(3%, 0, 0); } }
.tw-a { animation: ra-twinkle 5.5s ease-in-out infinite alternate; } .tw-b { animation: ra-twinkle 8s ease-in-out infinite alternate-reverse; }
@keyframes ra-twinkle { from { opacity: .55; } to { opacity: 1; } }
/* Light moving through the day: a warm glow that breathes, and soft rays that sweep very slowly. Opacity and transform only. */
.lyr-glow { opacity: 1; }
.lyr-glow .lyr-drift { animation: ra-breathe 14s ease-in-out infinite alternate; }
@keyframes ra-breathe { from { transform: translate3d(0, 0, 0) scale(1); } to { transform: translate3d(0, -2%, 0) scale(1.06); } }
.rays { position: absolute; left: 50%; top: 45%; width: 130vmax; height: 130vmax; margin: -65vmax 0 0 -65vmax; border-radius: 50%; background: repeating-conic-gradient(from 0deg, rgba(232, 197, 108, 0) 0deg 9deg, rgba(232, 197, 108, .08) 11deg 13deg, rgba(232, 197, 108, 0) 15deg 24deg); -webkit-mask-image: radial-gradient(circle, #000 0%, rgba(0, 0, 0, .5) 30%, transparent 62%); mask-image: radial-gradient(circle, #000 0%, rgba(0, 0, 0, .5) 30%, transparent 62%); opacity: calc(var(--p, 0) * .9); animation: ra-rays 240s linear infinite; }
@keyframes ra-rays { to { transform: rotate(360deg); } }
.kb { animation: ra-kb 48s ease-in-out infinite alternate; transform-origin: 50% 80%; }
@keyframes ra-kb { from { transform: scale(1); } to { transform: scale(1.06); } }
/* Far away birds: a few small strokes crossing very slowly */
.birds { position: absolute; left: -10%; top: 18%; width: 60px; height: 20px; opacity: .55; animation: ra-birds 150s linear infinite; }
@keyframes ra-birds { from { transform: translate3d(0, 0, 0); } 50% { transform: translate3d(60vw, -4vh, 0); } to { transform: translate3d(125vw, 2vh, 0); } }
/* In-flow scenes (full bleed, between sections): the sentence sits on the scene; the layers move with scroll. */
.scene-flow { height: clamp(380px, 64vh, 680px); background: #0B1119; color: #F4EFE4; }
.scene-flow .scene-copy { position: relative; z-index: 2; height: 100%; display: grid; place-content: center; text-align: center; padding: 0 var(--gutter, 24px); }
.scene-flow .scene-copy::before { content: ''; position: absolute; inset: 0; background: radial-gradient(ellipse 70% 60% at 50% 55%, rgba(5, 8, 14, .6), rgba(5, 8, 14, 0) 72%); z-index: -1; }
.scene-flow .vignette { position: absolute; inset: 0; z-index: 1; pointer-events: none; background: linear-gradient(180deg, rgba(5, 8, 14, .55), rgba(5, 8, 14, 0) 25%, rgba(5, 8, 14, 0) 75%, rgba(5, 8, 14, .6)); }

/* Sticky chapter markers: a hairline and a roman numeral that stays at the top of its chapter while it reads. */
.chapter { position: sticky; top: 0; z-index: 5; display: flex; align-items: center; gap: var(--s-4, 16px); padding: 10px 0; margin: 0 0 var(--s-6, 32px); background: color-mix(in srgb, var(--bg) 86%, transparent); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); font-family: var(--font-display); font-size: var(--fs-0); letter-spacing: var(--track-caps); text-transform: uppercase; color: var(--gold-text); font-weight: 600; }
.chapter::after { content: ''; flex: 1; border-top: 1px solid var(--line); }
.chapter .n { color: var(--muted); }

/* Hover states: a hairline that sweeps in under links, cards that lift on a soft shadow, gold buttons that fill. */
.u-sweep { text-decoration: none; background-image: linear-gradient(currentColor, currentColor); background-repeat: no-repeat; background-size: 0% 1px; background-position: 0 100%; transition: background-size 420ms var(--ease-reveal); padding-bottom: 2px; }
.u-sweep:hover, .u-sweep:focus-visible { background-size: 100% 1px; }
.lift { transition: transform 600ms var(--ease-reveal), box-shadow 600ms var(--ease-reveal), border-color 300ms var(--ease-fade); }
.lift:hover { transform: translate3d(0, -4px, 0); box-shadow: 0 24px 48px -28px rgba(21, 32, 43, .45), 0 0 0 1px var(--line-strong); }
.btn-gold, button.btn-gold { position: relative; overflow: hidden; transition: color 420ms var(--ease-fade), border-color 420ms var(--ease-fade), transform 500ms var(--ease-reveal), background-color 420ms var(--ease-fade); }
.magnet { will-change: transform; }

/* Accordion (FAQ): details whose height animates. motion.js drives the height; CSS owns the marker and the fade of the body. */
.acc { overflow: hidden; }
.acc .acc-body { opacity: 0; transform: translate3d(0, -6px, 0); transition: opacity 450ms var(--ease-fade) 120ms, transform 600ms var(--ease-reveal) 80ms; }
.acc[open] .acc-body { opacity: 1; transform: none; }
.acc summary::after { transition: transform 500ms var(--ease-reveal); }

/* Smooth anchors (base.css sets scroll-behavior; this offsets the fixed header) */
[id] { scroll-margin-top: calc(var(--top-h, 64px) + 12px); }

/* Reduced motion: visible, still, layered. Both the system preference and the settings panel. */
@media (prefers-reduced-motion: reduce) {
  html.ra-js .reveal, html.ra-js [data-split] .w, html.ra-js .rule-draw, html.ra-js .reveal-img img, html.ra-js .reveal-img svg { opacity: 1; transform: none; filter: none; clip-path: none; transition: none; }
  html.ra-js .rule-caps::before, html.ra-js .rule-caps::after { transform: none; transition: none; }
  .lyr-fog .lyr-drift, .tw-a, .tw-b, .lyr-glow .lyr-drift, .rays, .kb, .birds { animation: none; }
  html.ra-js .ra-progress { animation: none; transform: scaleX(var(--p, 0)); }
  .u-sweep, .lift, .btn-gold, .acc .acc-body, .acc summary::after { transition: none; }
  .lift:hover { transform: none; }
}
:root[data-motion="reduce"] .reveal, :root[data-motion="reduce"] [data-split] .w, :root[data-motion="reduce"] .rule-draw, :root[data-motion="reduce"] .reveal-img img, :root[data-motion="reduce"] .reveal-img svg { opacity: 1; transform: none; filter: none; clip-path: none; transition: none; }
:root[data-motion="reduce"] .rule-caps::before, :root[data-motion="reduce"] .rule-caps::after { transform: none; transition: none; }
:root[data-motion="reduce"] .lyr-fog .lyr-drift, :root[data-motion="reduce"] .tw-a, :root[data-motion="reduce"] .tw-b, :root[data-motion="reduce"] .lyr-glow .lyr-drift, :root[data-motion="reduce"] .rays, :root[data-motion="reduce"] .kb, :root[data-motion="reduce"] .birds { animation: none; }
html.ra-js:root[data-motion="reduce"] .ra-progress { animation: none; transform: scaleX(var(--p, 0)); }
:root[data-motion="reduce"] .u-sweep, :root[data-motion="reduce"] .lift, :root[data-motion="reduce"] .btn-gold, :root[data-motion="reduce"] .acc .acc-body { transition: none; }
