/* HALO — custom CSS. Only what Tailwind cannot express cleanly.
   Theme is driven by two rgb triplets on :root (--bg / --fg) tweened from JS. */

:root {
  --bg: 243 239 232;
  --fg: 14 14 13;
  --accent: 255 77 26;
  --ease-expo: cubic-bezier(.16, 1, .3, 1);
}

html {
  background: rgb(var(--bg));
  -webkit-text-size-adjust: 100%;
  scroll-behavior: auto;
}
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: hidden; }

body {
  background: rgb(var(--bg));
  color: rgb(var(--fg));
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-feature-settings: "ss01", "cv11";
}

::selection { background: rgb(var(--accent)); color: #0e0e0d; }
:focus-visible { outline: 2px solid rgb(var(--accent)); outline-offset: 3px; border-radius: 6px; }

/* ---------- film grain (fixed, blend-mode overlay, works on light + dark) ---------- */
.grain {
  position: fixed; inset: -50%; z-index: 90; pointer-events: none;
  width: 200%; height: 200%;
  opacity: .34; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n' x='0' y='0'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='.33 .33 .33 0 0  .33 .33 .33 0 0  .33 .33 .33 0 0  0 0 0 0 1'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  animation: grain 1.1s steps(6) infinite;
}
@keyframes grain {
  0% { transform: translate(0, 0); } 17% { transform: translate(-4%, 3%); }
  34% { transform: translate(3%, -5%); } 51% { transform: translate(-6%, -2%); }
  68% { transform: translate(5%, 4%); } 85% { transform: translate(-2%, 6%); } 100% { transform: translate(0, 0); }
}

/* ---------- loader ---------- */
#loader { clip-path: inset(0 0 0 0); animation: loaderFailsafe .5s ease 7s forwards; }
@keyframes loaderFailsafe { to { opacity: 0; visibility: hidden; } }

/* ---------- 3D stage layers ---------- */
#stage {
  position: fixed; left: 0; top: 0; width: 100%; height: 100vh; height: 100lvh;
  z-index: 2; pointer-events: none; visibility: hidden; opacity: 0;
  transition: opacity .9s var(--ease-expo);
}
#stage.is-on { visibility: visible; opacity: 1; }
#stage canvas { display: block; width: 100%; height: 100%; }

#fallback { position: fixed; inset: 0; z-index: 2; pointer-events: none; display: none; opacity: 0; transition: opacity .6s var(--ease-expo); }
html.no-webgl #fallback { display: block; }
html.no-webgl #fallback.is-on { opacity: 1; }
#fallback svg { position: absolute; left: 50%; top: 50%; width: min(58vw, 560px); transform: translate(-50%, -50%); animation: floaty 7s ease-in-out infinite; }
@keyframes floaty { 0%,100% { translate: 0 -8px; } 50% { translate: 0 10px; } }

/* ---------- split text (word mask reveal) ---------- */
.js [data-split]:not(.is-split) { visibility: hidden; }
.sw { display: inline-block; overflow: hidden; vertical-align: top; padding: .07em .06em .18em; margin: -.07em -.06em -.18em; }
.swi { display: inline-block; will-change: transform; }

/* ---------- cursor ---------- */
html.cursor-on, html.cursor-on * { cursor: none !important; }
html.cursor-on input, html.cursor-on textarea { cursor: text !important; }
#cursor { position: fixed; left: 0; top: 0; z-index: 9999; pointer-events: none; mix-blend-mode: difference; opacity: 0; transition: opacity .3s; }
#cursor.is-live { opacity: 1; }
#cursor .dot { position: absolute; left: -4px; top: -4px; width: 8px; height: 8px; border-radius: 99px; background: #fff; }
#cursor .ring {
  position: absolute; left: -22px; top: -22px; width: 44px; height: 44px; border-radius: 99px; border: 1px solid #fff;
  display: grid; place-items: center;
  transition: width .45s var(--ease-expo), height .45s var(--ease-expo), left .45s var(--ease-expo), top .45s var(--ease-expo), background-color .3s, transform .3s;
}
#cursor.is-hover .ring { width: 78px; height: 78px; left: -39px; top: -39px; background: #fff; }
#cursor.is-drag .ring { width: 92px; height: 92px; left: -46px; top: -46px; }
#cursor.is-down .ring { transform: scale(.82); }
#cursor .label { font: 500 10px/1 "JetBrains Mono", ui-monospace, monospace; letter-spacing: .16em; color: #fff; opacity: 0; text-transform: uppercase; transition: opacity .3s; }
#cursor.is-drag .label { opacity: 1; }
body.is-dragging { user-select: none; -webkit-user-select: none; }

/* ---------- nav ---------- */
#nav.is-solid { background: rgb(var(--bg) / .72); -webkit-backdrop-filter: blur(14px) saturate(1.3); backdrop-filter: blur(14px) saturate(1.3); }
#nav.is-hidden { transform: translateY(-105%); }
.nav-link { position: relative; }
.nav-link::after { content: ""; position: absolute; left: 0; right: 0; bottom: -5px; height: 1px; background: currentColor; transform: scaleX(0); transform-origin: right; transition: transform .5s var(--ease-expo); }
.nav-link:hover::after, .nav-link:focus-visible::after { transform: scaleX(1); transform-origin: left; }

#menu { clip-path: inset(0 0 100% 0); visibility: hidden; transition: clip-path .8s var(--ease-expo), visibility 0s .8s; }
#menu.is-open { clip-path: inset(0 0 0 0); visibility: visible; transition: clip-path .8s var(--ease-expo), visibility 0s 0s; }

/* ---------- chapter rail ---------- */
#rail { opacity: 0; transition: opacity .6s; }
#rail.is-on { opacity: 1; }
#rail a { position: relative; display: flex; align-items: center; justify-content: flex-end; gap: .75rem; padding: .35rem 0; }
#rail a span.tick { width: 14px; height: 1px; background: currentColor; opacity: .35; transition: width .5s var(--ease-expo), opacity .3s, background-color .3s; }
#rail a span.name { font: 500 10px/1 "JetBrains Mono", ui-monospace, monospace; letter-spacing: .14em; text-transform: uppercase; opacity: 0; transform: translateX(6px); transition: opacity .3s, transform .5s var(--ease-expo); }
#rail a:hover span.name, #rail a:focus-visible span.name { opacity: .8; transform: none; }
#rail a.is-active span.tick { width: 34px; opacity: 1; background: rgb(var(--accent)); }

/* ---------- exploded-view labels ---------- */
#leaders line { stroke: rgb(var(--fg)); stroke-width: 1; opacity: .55; stroke-dasharray: 1; stroke-dashoffset: 1; transition: stroke-dashoffset .9s var(--ease-expo); }
#leaders circle { fill: rgb(var(--accent)); opacity: 0; transition: opacity .4s; }
#leaders .is-on line { stroke-dashoffset: 0; }
#leaders .is-on circle { opacity: 1; }
.lbl { opacity: 0; transform: translateY(10px); transition: opacity .7s var(--ease-expo), transform .9s var(--ease-expo); }
.lbl.is-on { opacity: 1; transform: none; }

/* ---------- colour swatches ---------- */
.swatch { position: relative; width: 3.25rem; height: 3.25rem; border-radius: 99px; background: var(--c); box-shadow: inset 0 0 0 1px rgb(0 0 0 / .12), 0 10px 24px -12px rgb(0 0 0 / .45); transition: transform .5s var(--ease-expo); }
.swatch::after { content: ""; position: absolute; inset: -6px; border-radius: 99px; border: 1.5px solid rgb(var(--fg)); opacity: 0; transform: scale(.85); transition: opacity .3s, transform .5s var(--ease-expo); }
.swatch[aria-checked="true"]::after { opacity: 1; transform: none; }
.swatch:hover { transform: scale(1.08); }

/* ---------- CSS 3D spec ring ---------- */
.ring3d-scene { perspective: 1500px; perspective-origin: 50% 35%; touch-action: pan-y; }
.ring3d { --w: clamp(190px, 21vw, 280px); --r: calc(var(--w) * 1.12); position: relative; width: var(--w); height: calc(var(--w) * 1.32); margin-inline: auto; transform-style: preserve-3d; will-change: transform; }
.ring3d .card3d { position: absolute; inset: 0; transform: rotateY(calc(var(--i) * 60deg)) translateZ(var(--r)); backface-visibility: hidden; -webkit-backface-visibility: hidden; }

/* ---------- tilt cards ---------- */
[data-tilt] { transform-style: preserve-3d; will-change: transform; }
.tilt-glare { position: absolute; inset: 0; border-radius: inherit; pointer-events: none; opacity: 0; transition: opacity .4s; background: radial-gradient(420px circle at var(--mx, 50%) var(--my, 0%), rgb(255 255 255 / .55), transparent 62%); mix-blend-mode: soft-light; }
[data-tilt]:hover .tilt-glare { opacity: 1; }

/* ---------- faq ---------- */
.faq-panel { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .6s var(--ease-expo); }
.faq-panel > div { overflow: hidden; }
.faq-item.is-open .faq-panel { grid-template-rows: 1fr; }
.faq-item .plus::before, .faq-item .plus::after { content: ""; position: absolute; left: 50%; top: 50%; width: 14px; height: 1.5px; background: currentColor; transform: translate(-50%, -50%); transition: transform .5s var(--ease-expo); }
.faq-item .plus::after { transform: translate(-50%, -50%) rotate(90deg); }
.faq-item.is-open .plus::after { transform: translate(-50%, -50%) rotate(0deg); }

/* ---------- tables ---------- */
.spec-row { transition: background-color .35s, padding .5s var(--ease-expo); }
.spec-row:hover { background: rgb(var(--accent) / .09); }
.cmp-bar { transform-origin: left; }

/* ---------- misc ---------- */
.stroke-text { -webkit-text-stroke: 1.5px rgb(var(--fg) / .55); color: transparent; }
.no-scrollbar::-webkit-scrollbar { display: none; }
.no-scrollbar { scrollbar-width: none; }
.odo { display: inline-block; overflow: hidden; height: 1em; line-height: 1; vertical-align: bottom; }
.odo > span { display: block; will-change: transform; }

@media (max-width: 1023px) {
  .lbl { display: none; }
  #leaders { display: none; }
}

/* large displays: scale the rem-based type system */
@media (min-width: 2000px) { html { font-size: 17.5px; } }
@media (min-width: 2500px) { html { font-size: 20px; } }
@media (min-width: 3400px) { html { font-size: 26px; } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; scroll-behavior: auto !important; }
  .grain { animation: none; }
  #loader { animation-delay: 1s; }
}

/* ---------- opaque section scopes: local theme variables so they never flash while the page theme tweens ---------- */
.scope-bone { --bg: 243 239 232; --fg: 14 14 13; background: rgb(var(--bg)); color: rgb(var(--fg)); }
.scope-paper { --bg: 235 229 218; --fg: 14 14 13; background: rgb(var(--bg)); color: rgb(var(--fg)); }
.scope-ink { --bg: 14 14 13; --fg: 243 239 232; background: rgb(var(--bg)); color: rgb(var(--fg)); }
.scope-signal { --bg: 255 77 26; --fg: 14 14 13; background: rgb(var(--bg)); color: rgb(var(--fg)); }

/* if the JS bundle never runs, never leave headlines invisible */
.js [data-split]:not(.is-split) { animation: splitFailsafe 0s 6s forwards; }
@keyframes splitFailsafe { to { visibility: visible; } }
