/* =========================================================================
   Script2Learn - stylesheet
   -------------------------------------------------------------------------
   Structure adapted from the James_Branch rebuild: the page is a journey
   through a 3D space, not a stack of bands.

     CHAMBERS  - full viewport, transparent, the WebGL scene visible around
                 a single centred thought. Three of them: the opening line,
                 a one-line breath partway down, and the closing invitation.
     HALLS     - the readable rooms. Every actual product section (stats,
                 how it works, video, features, pricing, FAQ...) lives here,
                 on an opaque-enough ground that reading never competes with
                 the moving scene behind it.

   Palette matches the brand exactly (not a placeholder): --accent/--deep
   below are Script2Learn's real greens and teal, unchanged by this rebuild.
   ========================================================================= */

@font-face {
  font-family: 'DM Sans';
  font-style: normal; font-weight: 400 800; font-display: swap;
  src: url('fonts/dmsans-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
    U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
    U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'DM Sans';
  font-style: normal; font-weight: 400 800; font-display: swap;
  src: url('fonts/dmsans-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
    U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}

/* ---------- Tokens ------------------------------------------------------- */

:root {
  --deep:   #0B2C37;
  --deep-2: #0E3A44;
  --deep-3: #061C23;

  --accent:      #178650;
  --accent-deep: #0F6B3F;
  --accent-lift: #1EB16A;
  --accent-pale: #B9F2D8;

  /* --accent-lift as a BACKGROUND/border (buttons, focus rings) works in
     both themes unchanged - it's still on a dark surface behind it either
     way. As TEXT sitting directly on the page ground, it doesn't: bright
     enough to read on dark, too washed out at normal text size on light.
     --accent-text is the one to reach for for accent-colored text/labels;
     --accent-lift stays for backgrounds and borders. */
  --accent-text: var(--accent-lift);

  --on-deep:      #FFFFFF;
  --on-deep-body: #C2D4D9;
  --on-deep-soft: #9DB6BD;

  --hair:      rgba(var(--on-surface-rgb), 0.16);
  --hair-lift: rgba(var(--on-surface-rgb), 0.34);

  --hall:      rgba(9, 34, 43, 0.90);
  --hall-2:    rgba(var(--scrim-rgb), 0.92);
  --hall-light:   rgba(249, 250, 248, 0.96);
  --hall-light-2: rgba(244, 252, 248, 0.96);

  --ink:       #0B2C37;
  --ink-body:  #5E7A82;
  --ink-soft:  #5E7A82;
  --line:      rgba(11, 44, 55, 0.09);

  --r:      4px;
  --r-lg:   10px;
  --r-xl:   16px;
  --r-pill: 999px;

  --t-hero: clamp(2.4rem, 1.1rem + 4vw, 4.6rem);
  --t-say:  clamp(1.7rem, 1rem + 2.6vw, 3.2rem);
  --t-h2:   clamp(1.6rem, 1.05rem + 1.9vw, 2.4rem);
  --t-h3:   clamp(1.05rem, 0.98rem + 0.4vw, 1.2rem);
  --t-lead: clamp(1.05rem, 0.98rem + 0.42vw, 1.26rem);
  --t-sm:   0.9375rem;
  --t-xs:   0.8125rem;
  --track:  0.26em;

  --hall-y:  clamp(4.5rem, 2.5rem + 6vw, 9rem);
  --gutter:  clamp(1.35rem, 0.5rem + 3.5vw, 4rem);
  --inset:   clamp(0.6rem, -0.5rem + 3.2vw, 3rem);
  --shell:   1240px;
  --measure: 58ch;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --slow: 1s;
  --theme-fade: 0.5s ease;   /* matches scene.js's themeFade duration */

  /* Every rgba(var(--on-surface-rgb),X) "light wash / faint text on a dark surface"
     and rgba(var(--scrim-rgb),X) "dark scrim" in this file is written against one of
     these two, not the literal color - so the whole page recolors off two
     tokens instead of needing a light-mode override for every individual
     rule that happens to reach for white or near-black. */
  --on-surface-rgb: 255, 255, 255;
  --scrim-rgb: 6, 26, 33;
  --error: #FFB4A8;

  color-scheme: dark;
}

/* ---------- Light theme ---------------------------------------------------
   A genuine second scene, not an inverted one: night travel vs. daylight
   travel through the same space. scene.js re-colors the WebGL layer to
   match (fog, veils, motes, the particle text) - see setTheme() there. The
   accent greens are the one constant across both; everything built to read
   against them (--deep/--on-deep/--hall/--hair) gets its own values here so
   the whole page recolors through the existing token system rather than
   needing per-component light-mode rules. */
:root[data-theme="light"] {
  --deep:   #F7FAF9;
  --deep-2: #EEF5F0;
  --deep-3: #E3EEE7;

  --accent-pale: #0F6B3F;

  --on-deep:      #0B2C37;
  --on-deep-body: #4A6A72;
  --on-deep-soft: #5A7178;

  --hair:      rgba(11, 44, 55, 0.14);
  --hair-lift: rgba(11, 44, 55, 0.30);

  --hall:      rgba(255, 255, 255, 0.86);
  --hall-2:    rgba(244, 251, 247, 0.90);

  --on-surface-rgb: 11, 44, 55;
  --scrim-rgb: 247, 250, 249;
  --error: #C4362A;
  --accent-text: var(--accent-deep);

  color-scheme: light;
}

/* ---------- Reset -------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

/* Theme switch, cross-faded rather than snapped: every color/background
   swap when data-theme changes rides this transition. Applied broadly
   (not per-component) since the token swap touches nearly everything on
   the page at once - anything with its own more specific transition rule
   already (buttons, the mast settling) keeps that instead, the cascade
   just works normally here. Left off opacity/transform on purpose: this
   must never fight the scroll-driven opacity scene.js sets directly on
   the hero/closing headlines, or the reveal-on-scroll transform. */
*, *::before, *::after {
  transition: background-color var(--theme-fade), color var(--theme-fade),
              border-color var(--theme-fade), fill var(--theme-fade), stroke var(--theme-fade);
}
/* Reduced-motion already forces every transition-duration to ~0 near the
   bottom of this file (see the existing prefers-reduced-motion block) -
   that catches this rule too, so the switch is instant there rather than
   simulated as a fade nobody asked for. */

body {
  margin: 0;
  background: var(--deep);
  color: var(--on-deep-body);
  font-family: 'DM Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: 1rem; line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, video { max-width: 100%; height: auto; display: block; }
h1, h2, h3 { margin: 0; font-weight: 600; line-height: 1.14; letter-spacing: -0.028em; color: var(--on-deep); text-wrap: balance; }
h4 { margin: 0; }
p { margin: 0; }
a { color: inherit; }
ul, ol { margin: 0; padding: 0; list-style: none; }
button { font: inherit; }

:focus-visible { outline: 3px solid var(--accent-lift); outline-offset: 4px; border-radius: 2px; }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 300;
  background: var(--accent); color: #fff;    /* always on brand green */
  padding: 0.9rem 1.4rem; font-weight: 600;
}
.skip:focus { left: 0; }

/* ---------- The space ---------------------------------------------------- */

#bg { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 0; display: block; pointer-events: none; }
.mast, main, .foot { position: relative; z-index: 1; }

.no-webgl body,
html.no-webgl body {
  background:
    radial-gradient(70rem 50rem at 76% 8%, rgba(30, 177, 106, 0.16), transparent 62%),
    radial-gradient(60rem 44rem at 10% 82%, rgba(23, 134, 80, 0.13), transparent 60%),
    var(--deep);
  background-attachment: fixed;
}

.shell { width: 100%; max-width: var(--shell); margin-inline: auto; padding-inline: var(--gutter); }

/* ---------- Masthead ------------------------------------------------------ */

.mast {
  position: fixed; inset: 0 0 auto 0; z-index: 200;
  height: 76px; display: flex; align-items: center;
  transition: background var(--slow) var(--ease), backdrop-filter var(--slow) var(--ease), box-shadow var(--slow) var(--ease);
}
.mast__in { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; width: 100%; }
.mast.is-settled { background: rgba(var(--scrim-rgb), 0.82); backdrop-filter: blur(16px); box-shadow: 0 2px 20px rgba(0,0,0,0.15); }

.wordmark { display: inline-flex; align-items: center; gap: 0.6rem; text-decoration: none; color: var(--on-deep); font-size: 1.08rem; font-weight: 700; letter-spacing: -0.02em; }
.wordmark__badge { width: 30px; height: 30px; flex-shrink: 0; background: var(--accent); border-radius: 8px; display: flex; align-items: center; justify-content: center; }

.mast__nav { display: flex; gap: 2rem; }
.mast__nav a {
  font-size: var(--t-sm); text-decoration: none; color: var(--on-deep-body);
  padding-block: 0.35rem; border-bottom: 1px solid transparent;
  transition: color var(--slow) var(--ease), border-color var(--slow) var(--ease);
}
.mast__nav a:hover { color: var(--on-deep); border-bottom-color: var(--accent-text); }
.mast__actions { display: flex; align-items: center; gap: 10px; }
@media (max-width: 920px) { .mast__nav { display: none; } }

.mob-toggle { display: none; align-items: center; justify-content: center; width: 40px; height: 40px; background: none; border: none; cursor: pointer; flex-direction: column; gap: 5px; }
.mob-toggle span { display: block; width: 20px; height: 2px; background: var(--on-deep); border-radius: 2px; }
@media (max-width: 920px) { .mob-toggle { display: flex; } }

/* ---------- Theme toggle ---------------------------------------------------
   Shows the icon of the theme a click switches TO, not the current one -
   the sun is visible while dark (click for daylight), the moon while light
   (click for night). Both icons always exist in the DOM; [data-theme]
   toggles which is visible, so there's nothing to re-render on switch. */
.theme-toggle {
  display: flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 50%;
  background: transparent; border: 1px solid var(--hair);
  color: var(--on-deep); cursor: pointer; flex-shrink: 0;
  transition: background var(--slow) var(--ease), border-color var(--slow) var(--ease);
}
.theme-toggle:hover { background: rgba(var(--on-surface-rgb), 0.08); border-color: var(--hair-lift); }
.theme-toggle__moon { display: none; }
:root[data-theme="light"] .theme-toggle__sun { display: none; }
:root[data-theme="light"] .theme-toggle__moon { display: block; }

.theme-toggle--mobile {
  width: 100%; height: auto; border-radius: var(--r-lg);
  justify-content: flex-start; gap: 10px;
  padding: 13px 0; margin-top: 4px;
  border: none; border-bottom: 1px solid var(--hair);
  font-size: 16px; font-weight: 500; color: var(--on-deep);
}
.theme-toggle--mobile:hover { background: transparent; }

#mobile-nav {
  display: none;
  position: fixed; top: 76px; left: 0; right: 0; z-index: 199;
  background: rgba(var(--scrim-rgb), 0.98); backdrop-filter: blur(16px);
  border-bottom: 1px solid var(--hair);
  padding: 12px var(--gutter) 20px;
  flex-direction: column;
}
@media (min-width: 921px) { #mobile-nav { display: none !important; } }
#mobile-nav a { display: block; padding: 13px 0; font-size: 16px; font-weight: 500; color: var(--on-deep); text-decoration: none; border-bottom: 1px solid var(--hair); }
#mobile-nav .btn { margin-top: 14px; width: 100%; }

/* ---------- Buttons ------------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.4rem;
  white-space: nowrap; padding: 0.95rem 2.05rem;
  border-radius: var(--r-pill);
  font: inherit; font-size: var(--t-sm); font-weight: 600; letter-spacing: 0.015em;
  text-decoration: none; border: 1px solid transparent; cursor: pointer;
  transition: background var(--slow) var(--ease), border-color var(--slow) var(--ease),
              color var(--slow) var(--ease), transform 0.14s ease;
}
.btn:active { transform: translateY(1px); }
.btn--solid { background: var(--accent); color: #FFFFFF; }
.btn--solid:hover { background: var(--accent-lift); color: var(--deep-3); }
.btn--ghost { background: transparent; color: var(--on-deep); border-color: var(--hair); }
.btn--ghost:hover { background: rgba(var(--on-surface-rgb), 0.1); border-color: var(--hair-lift); }
.btn--sm { padding: 0.7rem 1.4rem; font-size: var(--t-xs); }

/* =========================================================================
   CHAMBERS
   ========================================================================= */

.chamber { position: relative; min-height: 100dvh; display: grid; place-items: center; text-align: center; padding: 7rem var(--gutter); }
.chamber::before {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(42rem 26rem at 50% 50%, rgba(var(--scrim-rgb), 0.82), rgba(var(--scrim-rgb), 0.35) 62%, transparent 100%);
  pointer-events: none;
}
.chamber__in { position: relative; z-index: 1; max-width: 52rem; }
.chamber h1 { font-size: var(--t-hero); letter-spacing: -0.032em; padding-bottom: 0.06em; }
.chamber .say { font-size: var(--t-say); font-weight: 600; letter-spacing: -0.03em; line-height: 1.24; color: var(--on-deep); max-width: 22ch; margin-inline: auto; }
.chamber__sub { margin: 1.5rem auto 0; font-size: var(--t-lead); line-height: 1.6; color: var(--on-deep-body); max-width: 46ch; }
.chamber__act { display: flex; flex-wrap: wrap; gap: 0.85rem; justify-content: center; margin-top: 2.4rem; }
.chamber__stats { display: flex; align-items: center; justify-content: center; gap: 28px; margin-top: 2.6rem; flex-wrap: wrap; }
.chamber__stat { display: flex; flex-direction: column; gap: 2px; }
.chamber__stat b { font-size: 26px; font-weight: 800; color: var(--on-deep); letter-spacing: -0.5px; }
.chamber__stat span { font-size: 12.5px; color: var(--on-deep-soft); }
.chamber__divider { width: 1px; height: 32px; background: var(--hair); }

.label { display: block; font-size: var(--t-xs); font-weight: 600; letter-spacing: var(--track); text-transform: uppercase; color: var(--accent-text); margin-bottom: 1.3rem; }

/* =========================================================================
   HALLS
   ========================================================================= */

.hall { position: relative; background: var(--hall); backdrop-filter: blur(20px) saturate(115%); padding-block: var(--hall-y); margin-inline: var(--inset); border: 1px solid var(--hair); border-radius: var(--r-lg); }
.hall + .hall { margin-top: var(--inset); }
.hall--dark { background: var(--hall-2); }
.hall--light { background: var(--hall-light); color: var(--ink-body); }
.hall--light-2 { background: var(--hall-light-2); color: var(--ink-body); }
.chamber + .hall { margin-top: var(--inset); }
.hall + .chamber { margin-top: var(--inset); }

@supports not (backdrop-filter: blur(4px)) {
  .hall { background: var(--deep); }
  .hall--dark { background: var(--deep-3); }
  .hall--light, .hall--light-2 { background: #F4F6F5; }
}

.hall .label { color: var(--accent-text); }
.hall--light .label, .hall--light-2 .label { color: var(--accent); }
.hall--light h2, .hall--light h3, .hall--light-2 h2, .hall--light-2 h3 { color: var(--ink); }
.hall--light .lede, .hall--light-2 .lede { color: var(--ink-body); }

.h2 { font-size: var(--t-h2); max-width: 20ch; }
.h2--centre { margin-inline: auto; text-align: center; max-width: 24ch; }
.lede { font-size: var(--t-lead); line-height: 1.6; color: var(--on-deep-body); max-width: var(--measure); margin-top: 1.15rem; }
.lede--centre { margin-inline: auto; text-align: center; }
.hall__head { margin-bottom: clamp(2.25rem, 1.5rem + 3vw, 3.5rem); }
.hall__head--centre { text-align: center; }
.hall__head--centre .lede { margin-inline: auto; }

/* ---------- Stat cards (Problem hall) ------------------------------------ */

.stat-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0; border: 1px solid var(--hair); border-radius: var(--r-lg); overflow: hidden; background: rgba(var(--on-surface-rgb),0.02); margin-top: clamp(2rem, 1.5rem + 2vw, 3rem); }
.stat-card { position: relative; padding: 2.5rem 2.3rem; border-right: 1px solid var(--hair); border-bottom: 1px solid var(--hair); }
.stat-card:nth-child(2n) { border-right: none; }
.stat-card:nth-last-child(-n+2) { border-bottom: none; }
.stat-card__tag { position: absolute; top: 18px; right: 22px; font-size: 10.5px; color: rgba(var(--on-surface-rgb),0.22); letter-spacing: 1px; }
.stat-card__num { font-size: clamp(2rem, 1.6rem + 1.4vw, 3.2rem); font-weight: 800; letter-spacing: -0.06em; color: var(--accent-text); line-height: 1; margin-bottom: 12px; }
.stat-card__label { font-size: 16px; font-weight: 600; color: var(--on-deep); margin-bottom: 8px; }
.stat-card__body { font-size: 13.5px; line-height: 1.6; color: var(--on-deep-body); margin-bottom: 10px; }
.stat-card__src { font-size: 11.5px; color: rgba(var(--on-surface-rgb),0.32); line-height: 1.5; }
@media (max-width: 720px) { .stat-grid { grid-template-columns: 1fr; } .stat-card { border-right: none !important; } .stat-card:not(:last-child) { border-bottom: 1px solid var(--hair) !important; } }

/* ---------- Comparison grid (why Script2Learn) ------------------------------ */

.comparison-grid { margin-top: clamp(2.5rem, 2rem + 2vw, 3.5rem); display: flex; flex-direction: column; gap: clamp(2rem, 1.5rem + 3vw, 3.5rem); }
.comparison-row { display: grid; grid-template-columns: 1fr auto 1fr; gap: clamp(1.5rem, 1rem + 2vw, 2.5rem); align-items: start; }
.comparison-col { padding: 2rem 2.2rem; background: rgba(var(--on-surface-rgb), 0.04); border: 1px solid var(--hair); border-radius: var(--r-lg); }
.comparison-col--highlight { background: rgba(var(--accent-rgb), 0.08); border-color: var(--accent); }
.comparison-col__title { font-size: 15px; font-weight: 700; color: var(--on-deep); margin-bottom: 1rem; letter-spacing: -0.01em; line-height: 1.3; }
.comparison-col__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.85rem; }
.comparison-col__list li { font-size: 14px; line-height: 1.55; color: var(--on-deep-body); padding-left: 1.5rem; position: relative; }
.comparison-col__list li::before { content: '—'; position: absolute; left: 0; color: var(--accent); font-weight: 700; }
.comparison-col--highlight .comparison-col__list li { color: var(--on-surface); font-weight: 500; }
.comparison-divider { display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 600; color: var(--on-deep-body); text-transform: uppercase; letter-spacing: 0.05em; height: 3rem; }
@media (max-width: 860px) { .comparison-row { grid-template-columns: 1fr; } .comparison-divider { display: none; } .comparison-col { border-top: 3px solid var(--accent); padding-top: 1.8rem; margin-top: 0.5rem; } .comparison-col--highlight { border-top-color: var(--accent-lift); } }

/* ---------- Stops (how the work runs) -------------------------------------- */

.stops { margin-top: clamp(2.25rem, 1.5rem + 3vw, 3.5rem); display: grid; }
.stop { display: grid; grid-template-columns: minmax(8rem, 14rem) minmax(0, 1fr); gap: clamp(1rem, 0.5rem + 2.5vw, 3.5rem); padding-block: 1.8rem; border-top: 1px solid var(--hair); align-items: start; }
.stop:last-child { border-bottom: 1px solid var(--hair); }
.stop__name { font-size: 17px; font-weight: 700; color: var(--on-deep); letter-spacing: -0.02em; }
.stop__body p { color: var(--on-deep-body); font-size: 14px; line-height: 1.7; max-width: 56ch; }
.stop__aside { display: inline-block; margin-top: 0.75rem; font-size: 12px; font-weight: 600; letter-spacing: 0.03em; color: var(--accent-text); border-left: 2px solid var(--accent); padding: 0.1rem 0 0.1rem 0.7rem; }
@media (max-width: 720px) { .stop { grid-template-columns: 1fr; gap: 0.35rem; } }

/* ---------- Step cards (How it works) ------------------------------------ */

.step-row { display: flex; gap: 20px; align-items: stretch; margin-top: clamp(2rem, 1.5rem + 2vw, 3rem); }
.step-card { flex: 1; background: rgba(var(--on-surface-rgb),0.03); border-radius: 14px; border: 1px solid var(--hair); padding: 2.2rem 2rem; }
.step-card__top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 28px; }
.step-card__icon { width: 46px; height: 46px; background: rgba(30,177,106,0.14); border-radius: 10px; display: flex; align-items: center; justify-content: center; }
.step-card__num { font-size: 38px; font-weight: 800; color: rgba(var(--on-surface-rgb),0.09); letter-spacing: -2px; }
.step-card h3 { font-size: 19px; margin-bottom: 10px; }
.step-card p { font-size: 14px; line-height: 1.7; color: var(--on-deep-body); }
.step-connector { display: flex; align-items: center; padding-top: 20px; flex-shrink: 0; color: rgba(var(--on-surface-rgb),0.3); }
.step-foot { text-align: center; font-size: 14px; color: var(--on-deep-soft); margin-top: 36px; }
@media (max-width: 820px) { .step-row { flex-direction: column; } .step-connector { display: none; } }

/* ---------- Video ---------------------------------------------------------- */

.video-frame { border-radius: var(--r-xl); overflow: hidden; box-shadow: 0 20px 60px rgba(0,0,0,0.35); border: 1px solid var(--hair); margin-top: clamp(2rem, 1.5rem + 2vw, 3rem); }

/* ---------- Compare slider + timeline (Volume & speed) -------------------- */

.compare { position: relative; height: 230px; border-radius: var(--r-xl); overflow: hidden; border: 1px solid var(--hair); margin-top: clamp(2rem, 1.5rem + 2vw, 3rem); margin-bottom: 12px; touch-action: none; }
.compare__after { position: absolute; inset: 0; background: var(--deep-3); padding: 36px; display: flex; align-items: center; justify-content: flex-end; }
.compare__after-in { text-align: right; max-width: 320px; }
.compare__eyebrow { font-size: 12px; font-weight: 600; letter-spacing: 0.8px; text-transform: uppercase; margin-bottom: 16px; color: rgba(var(--on-surface-rgb),0.5); }
.compare__after .compare__eyebrow { color: rgba(var(--on-surface-rgb),0.5); }
.compare__num { font-size: 40px; font-weight: 800; letter-spacing: -1.5px; color: var(--on-deep); margin-bottom: 6px; }
.compare__sub { font-size: 15px; color: rgba(var(--on-surface-rgb),0.65); }
.compare__before { position: absolute; inset: 0; width: 50%; overflow: hidden; }
.compare__before-in { position: absolute; top: 0; left: 0; height: 100%; background: #fff; padding: 36px; box-sizing: border-box; display: flex; flex-direction: column; justify-content: center; }
.compare__before .compare__eyebrow { color: var(--ink-soft); }
.compare__before .compare__num { color: var(--ink); }
.compare__before .compare__sub { color: var(--ink-body); }
.compare__handle { position: absolute; top: 0; bottom: 0; left: 50%; width: 2px; background: #fff; box-shadow: 0 0 0 1px rgba(0,0,0,0.15); transform: translateX(-1px); pointer-events: none; }
.compare__grip { position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); width: 44px; height: 44px; border-radius: 50%; background: #fff; box-shadow: 0 4px 14px rgba(0,0,0,0.35); display: flex; align-items: center; justify-content: center; color: var(--ink); font-size: 15px; font-weight: 700; }
.compare__hint { text-align: center; font-size: 11px; letter-spacing: 1px; color: var(--on-deep-soft); text-transform: uppercase; margin-bottom: 28px; }
.compare__note { text-align: center; font-size: 12.5px; color: var(--on-deep-soft); margin-bottom: 36px; }

.math-banner { text-align: center; margin-bottom: 36px; padding: 22px 24px; border-radius: 14px; background: linear-gradient(135deg, var(--accent-deep), var(--accent-lift)); box-shadow: 0 16px 40px -12px rgba(23,134,80,0.5); }
.math-banner__eyebrow { color: rgba(var(--on-surface-rgb),0.8); font-size: 11px; letter-spacing: 1.5px; text-transform: uppercase; display: block; margin-bottom: 6px; }
.math-banner__line { color: #fff; font-size: 19px; font-weight: 800; letter-spacing: -0.3px; }

.timeline { position: relative; background: var(--deep-3); border-radius: var(--r-xl); padding: 48px 40px 40px; overflow: hidden; border: 1px solid var(--hair); }
.timeline__head { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 10px; margin-bottom: 44px; }
.timeline__head span { font-size: 11px; letter-spacing: 2px; text-transform: uppercase; }
.timeline__head span:first-child { color: var(--accent-text); }
.timeline__head span:last-child { color: rgba(var(--on-surface-rgb),0.28); font-size: 10.5px; letter-spacing: 1px; }
.timeline__stops { display: flex; gap: 16px; margin-bottom: 28px; }
.timeline__stop { flex: 1; text-align: left; opacity: 0.4; transition: opacity 0.3s var(--ease); }
.timeline__stop.is-active { opacity: 1; }
.timeline__stop:last-child { text-align: right; }
.timeline__stop-time { font-size: 10.5px; font-weight: 600; letter-spacing: 0.8px; text-transform: uppercase; margin-bottom: 8px; color: var(--accent-text); }
.timeline__stop-label { font-size: 16px; font-weight: 600; color: var(--on-deep); }
#timeline-track { position: relative; height: 3px; background: rgba(var(--on-surface-rgb),0.1); border-radius: 2px; }
#timeline-fill { position: absolute; top: 0; left: 0; height: 100%; width: 0%; background: var(--accent-lift); border-radius: 2px; }
#timeline-dot { position: absolute; top: 50%; left: 0%; width: 12px; height: 12px; border-radius: 50%; background: var(--accent-lift); box-shadow: 0 0 0 4px rgba(30,177,106,0.25); transform: translate(-50%, -50%); opacity: 0; transition: opacity 0.2s; }
@media (max-width: 720px) { .timeline__stops { flex-wrap: wrap; } .timeline__stop { flex: 0 0 45%; } }

/* ---------- Real output screenshots --------------------------------------- */

.output-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 28px; margin-top: clamp(2rem, 1.5rem + 2vw, 3rem); }
.output-frame { display: block; position: relative; border-radius: var(--r-xl); overflow: hidden; border: 1px solid var(--hair); aspect-ratio: 1400/900; }
.output-frame img { width: 100%; height: 100%; object-fit: contain; background: var(--deep-2); }
.output-cap { text-align: center; margin-top: 16px; font-size: 14px; font-weight: 600; color: var(--on-deep); }
.output-cap span { color: var(--accent-text); font-weight: 600; }
@media (max-width: 720px) { .output-grid { grid-template-columns: 1fr; } }

/* ---------- The range (what we build) --------------------------------------- */

/* THE ARC. "One source. Every format your people need it in." - so the
   formats are arranged around a single viewpoint rather than listed in a
   flat grid, and the layout carries the argument instead of just hosting
   it. Done in CSS 3D, deliberately NOT WebGL: the copy has to stay real
   HTML (readable, selectable, indexable - a services shopfront that can't
   be found isn't a shopfront), and the page's GPU budget is already spoken
   for by the scene behind it.

   One shared perspective on the container, not per-card, is what makes
   these read as one curved wall rather than eight separately-angled
   cards. */
.range-arc { perspective: 2000px; perspective-origin: 50% 45%; margin-top: clamp(2rem, 1.5rem + 2vw, 3rem); }
.range-arc__row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 22px; transform-style: preserve-3d; transform: rotateY(var(--arc-sweep, 0deg)); transition: transform 0.5s var(--ease); }
.range-arc__row + .range-arc__row { margin-top: 34px; }

.range-card { position: relative; }
.range-arc .range-card {
  transform: rotateY(var(--arc-rot, 0deg)) translateZ(var(--arc-z, 0px));
  transition: transform 0.25s ease-out;
}
/* A lift on hover instead of the cursor-tilt the other cards get - it
   needs no cursor-position math, which is the thing that isn't reliable
   inside a perspective/preserve-3d context. */
.range-arc .range-card:hover { transform: rotateY(var(--arc-rot, 0deg)) translateZ(calc(var(--arc-z, 0px) + 26px)); }
/* 16/9, not 4/3: every screenshot we show is 16:9 or wider, and a 4/3 frame
   with object-fit:cover was cropping ~25% off the sides - straight through
   the words in the UI being shown. Match the frame to the content. */
.range-card__img { position: relative; border-radius: var(--r-lg); overflow: hidden; border: 1px solid var(--hair); aspect-ratio: 16/9; background: var(--deep-2); }

/* For deliverables we have no genuine screenshot of, show a branded mark
   rather than a stand-in screenshot of something else. */
.range-card__img--mark {
  display: grid; place-items: center;
  background:
    radial-gradient(120% 120% at 78% 12%, rgba(30,177,106,0.20), transparent 60%),
    linear-gradient(155deg, var(--deep-2), var(--deep-3));
}
.range-card__img--mark svg { width: 34%; height: auto; color: var(--accent-lift); opacity: 0.85; }
.range-card__img img { width: 100%; height: 100%; object-fit: cover; }
.range-card__soon { position: absolute; top: 10px; left: 10px; z-index: 2; font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; padding: 4px 9px; border-radius: var(--r-pill); background: rgba(var(--scrim-rgb), 0.88); color: var(--on-deep); border: 1px solid var(--hair); }
.range-card h3 { margin-top: 14px; font-size: 15px; }
.range-card p { margin-top: 4px; font-size: 13px; line-height: 1.6; color: var(--on-deep-body); }

/* Below 950px the arc stops being an arc and becomes a grid: at two
   columns there isn't enough width for the curve to read as anything but
   skew, and edge-on cards are just harder to read. */
@media (max-width: 950px) {
  .range-arc { perspective: none; }
  .range-arc__row { grid-template-columns: repeat(2, 1fr); transform: none; }
  .range-arc .range-card { transform: none; }
}
@media (max-width: 560px) {
  .range-arc__row { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
  .range-arc { perspective: none; }
  .range-arc__row, .range-arc .range-card { transform: none !important; }
}

/* ---------- In and out (tag pills) ------------------------------------------- */

.tag-cols { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 1rem + 4vw, 5rem); margin-top: clamp(2rem, 1.5rem + 2vw, 3rem); }
.tag-cols h3 { font-size: 16px; padding-bottom: 14px; margin-bottom: 18px; border-bottom: 1px solid var(--hair-lift); }
.tag-cols > div > p { margin-top: 18px; font-size: 14px; color: var(--on-deep-body); max-width: 40ch; }
.tag-list { display: flex; flex-wrap: wrap; gap: 8px; }
.tag-pill { font-size: 13.5px; padding: 7px 14px; border: 1px solid var(--hair); border-radius: var(--r-pill); color: var(--on-deep); }
@media (max-width: 760px) { .tag-cols { grid-template-columns: 1fr; } }

/* ---------- Feature wow tiles ---------------------------------------------- */

.feat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--hair); border-radius: 14px; overflow: hidden; border: 1px solid var(--hair); }
.feat-card { background: var(--deep-2); padding: 30px; }
.feat-card__icon { width: 40px; height: 40px; background: rgba(30,177,106,0.14); border-radius: 9px; display: flex; align-items: center; justify-content: center; margin-bottom: 18px; }
.feat-card h3 { font-size: 15px; margin-bottom: 8px; }
.feat-card p { font-size: 13px; line-height: 1.65; color: var(--on-deep-body); }
@media (max-width: 920px) { .feat-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .feat-grid { grid-template-columns: 1fr; } }

/* ---------- Brand profile horizontal scroll -------------------------------- */

.brand-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; margin-bottom: 24px; flex-wrap: wrap; }
.brand-head h3 { font-size: 26px; }
.brand-nav { display: flex; gap: 8px; flex-shrink: 0; }
.brand-nav button { width: 36px; height: 36px; border-radius: 50%; border: 1px solid var(--hair); background: transparent; color: var(--on-deep); cursor: pointer; font-size: 15px; }
.brand-nav button:hover { background: rgba(var(--on-surface-rgb),0.08); }
.brand-scroll { display: flex; gap: 18px; overflow-x: auto; scroll-snap-type: x mandatory; padding-bottom: 10px; -webkit-overflow-scrolling: touch; }
.brand-panel { flex: 0 0 320px; scroll-snap-align: start; background: rgba(var(--on-surface-rgb),0.03); border: 1px solid var(--hair); border-radius: 14px; padding: 28px; }
/* Always a solid dark-green card, in both themes - not a hall surface, so
   its text is fixed light rather than reaching for the theme tokens that
   everything else uses. Those tokens are what to use ON THE PAGE GROUND;
   this card is never the page ground. */
.brand-panel--final { background: var(--accent-deep); border-color: transparent; }
.brand-panel__tag { font-size: 12px; font-weight: 700; letter-spacing: 0.6px; text-transform: uppercase; margin-bottom: 12px; color: var(--accent-text); }
.brand-panel--final .brand-panel__tag { color: rgba(255,255,255,0.85); }
.brand-panel h4 { font-size: 18px; margin-bottom: 10px; color: var(--on-deep); }
.brand-panel--final h4 { color: #fff; }
.brand-panel p { font-size: 13.5px; line-height: 1.65; color: var(--on-deep-body); }
.brand-panel--final p { color: rgba(255,255,255,0.8); }

/* ---------- Template ingestion diagram -------------------------------------- */

.template-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 40px; align-items: center; }
.template-diagram { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.template-box { background: rgba(var(--on-surface-rgb),0.03); border: 1px dashed var(--hair-lift); border-radius: 12px; padding: 20px; text-align: center; }
.template-box__tag { font-size: 11px; font-weight: 600; color: var(--on-deep-soft); letter-spacing: 0.6px; text-transform: uppercase; margin-bottom: 10px; }
.template-box__swatch { aspect-ratio: 4/3; background: repeating-linear-gradient(45deg, rgba(var(--on-surface-rgb),0.05), rgba(var(--on-surface-rgb),0.05) 8px, transparent 8px, transparent 16px); border-radius: 8px; }
.template-box--dark { background: var(--deep-3); border: 1px solid var(--hair); }
.template-box--dark .template-box__tag { color: var(--accent-text); }
.template-box__img { aspect-ratio: 4/3; border-radius: 8px; overflow: hidden; border: 1px solid var(--hair); }
.template-box__img img { width: 100%; height: 100%; object-fit: cover; object-position: top; }
@media (max-width: 820px) { .template-grid { grid-template-columns: 1fr; } }

/* ---------- Package tiers --------------------------------------------------- */

.tiers-head { text-align: center; margin-bottom: 12px; }
.tiers-head h3 { font-size: 28px; margin-bottom: 10px; }
.tiers-head p { font-size: 15px; color: var(--on-deep-body); max-width: 560px; margin: 0 auto 40px; }
.tiers-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.tier { border: 1.5px solid var(--hair); border-radius: 14px; padding: 28px; }
.tier--featured { border-color: var(--accent-text); position: relative; box-shadow: 0 12px 32px rgba(23,134,80,0.18); }
.tier--featured::before { content: 'Most popular'; position: absolute; top: -12px; left: 50%; transform: translateX(-50%); background: var(--accent); color: #fff; font-size: 11px; font-weight: 700; letter-spacing: 0.4px; text-transform: uppercase; padding: 4px 14px; border-radius: 12px; }
.tier__name { font-size: 13px; font-weight: 700; color: var(--on-deep-soft); letter-spacing: 0.6px; text-transform: uppercase; margin-bottom: 10px; }
.tier--featured .tier__name { color: var(--accent-text); }
.tier__sub { font-size: 13px; color: var(--on-deep-body); margin-bottom: 18px; min-height: 36px; }
.tier ul { display: flex; flex-direction: column; gap: 10px; font-size: 13.5px; color: var(--on-deep); }
@media (max-width: 820px) { .tiers-grid { grid-template-columns: 1fr; } }

/* ---------- Use cases ------------------------------------------------------- */

.usecases-head { text-align: center; margin-bottom: 36px; }
.usecases-head h3 { font-size: 28px; }
.usecases-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 26px; }
.usecase h4 { font-size: 14px; font-weight: 700; color: var(--accent-text); margin-bottom: 12px; }
.usecase ul { display: flex; flex-direction: column; gap: 7px; font-size: 14px; color: var(--on-deep); }
.usecase--wide { grid-column: span 2; }
@media (max-width: 820px) { .usecases-grid { grid-template-columns: 1fr 1fr; } .usecase--wide { grid-column: span 2; } }
@media (max-width: 560px) { .usecases-grid { grid-template-columns: 1fr; } .usecase--wide { grid-column: span 1; } }

/* ---------- Technical grid --------------------------------------------------- */

.technical { background: rgba(var(--on-surface-rgb),0.03); border: 1px solid var(--hair); border-radius: var(--r-xl); padding: 36px; }
.technical__eyebrow { font-size: 12px; font-weight: 600; color: var(--on-deep-soft); letter-spacing: 1.2px; text-transform: uppercase; display: block; margin-bottom: 8px; }
.technical h3 { font-size: 20px; margin-bottom: 24px; }
.technical-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; font-size: 13.5px; color: var(--on-deep-body); line-height: 1.6; }
.technical-grid strong { color: var(--on-deep); display: block; margin-bottom: 2px; }
@media (max-width: 720px) { .technical-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 480px) { .technical-grid { grid-template-columns: 1fr; } }

/* ---------- FAQ -------------------------------------------------------------- */

.faq-list { display: flex; flex-direction: column; gap: 1px; background: var(--hair); border-radius: 14px; overflow: hidden; border: 1px solid var(--hair); margin-top: clamp(2rem, 1.5rem + 2vw, 3rem); }
.faq-item { background: var(--deep-2); padding: 26px 30px; }
.faq-item h3 { font-size: 15px; margin-bottom: 8px; }
.faq-item p { font-size: 14px; line-height: 1.65; color: var(--on-deep-body); }
.faq-item a { color: var(--accent-text); font-weight: 600; text-decoration: none; }
.faq-item a:hover { text-decoration: underline; }

/* ---------- Pricing card ------------------------------------------------------ */

.pricing-wrap { max-width: 620px; margin-inline: auto; }
.pricing-card { border: 1.5px solid var(--hair); border-radius: var(--r-xl); padding: 46px 42px; margin-top: clamp(2rem, 1.5rem + 2vw, 3rem); }
.pricing-top { display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: 30px; flex-wrap: wrap; gap: 16px; }
.pricing-plan { font-size: 13px; font-weight: 600; color: var(--accent-text); letter-spacing: 0.8px; text-transform: uppercase; margin-bottom: 8px; }
.pricing-price { font-size: 34px; font-weight: 800; letter-spacing: -1.5px; color: var(--on-deep); line-height: 1; }
.pricing-sub { font-size: 14px; color: var(--on-deep-body); margin-top: 8px; }
.pricing-badge { background: rgba(30,177,106,0.14); border: 1px solid rgba(30,177,106,0.3); border-radius: 8px; padding: 10px 16px; text-align: center; flex-shrink: 0; }
.pricing-badge div:first-child { font-size: 11px; font-weight: 600; color: var(--accent-text); letter-spacing: 0.5px; }
.pricing-badge div:last-child { font-size: 14px; font-weight: 700; color: var(--on-deep); white-space: nowrap; }
.pricing-rule { height: 1px; background: var(--hair); margin-bottom: 26px; }
.pricing-checks { display: grid; grid-template-columns: 1fr 1fr; gap: 13px; margin-bottom: 32px; }
.pricing-check { display: flex; align-items: center; gap: 10px; font-size: 14px; color: var(--on-deep); }
.pricing-check svg circle { fill: var(--accent-lift); }
@media (max-width: 560px) { .pricing-checks { grid-template-columns: 1fr; } }

/* ---------- Final CTA form --------------------------------------------------- */

.chamber--final::before {
  background: linear-gradient(180deg, rgba(var(--scrim-rgb),0.05) 0%, rgba(var(--scrim-rgb),0.22) 44%, rgba(var(--scrim-rgb),0.82) 72%, rgba(var(--scrim-rgb),0.92) 100%);
}
/* Not sticky any more. A one-line email capture could be pinned; a full
   enquiry form cannot - at 800px tall the submit button fell below the
   fold and could not be reached while the section was pinned. Static also
   makes the closing particle morph correct: scene.js reads
   rect.top + scrollY as a document coordinate, which sticky breaks. */
/* Bottom-aligned, not centred: at full scroll the viewport shows the last
   900px of the page, and centring parked ~235px of dead space under the
   form, pushing the heading off the top. The assembled particle text has to
   be on screen at the moment the morph completes. */
.chamber--final { display: flex; align-items: flex-end; min-height: 115vh; padding-top: 8vh; padding-bottom: 0; }
/* The closing heading shares the last viewport with a five-field form and a
   160px footer, so it runs smaller here than in the other chambers - the
   assembled particle text has to be on screen at full scroll. */
.chamber--final .say { font-size: clamp(1.7rem, 1.2rem + 1.9vw, 2.5rem); max-width: 18ch; line-height: 1.12; }

/* Short viewports (most laptops) cannot fit heading + five fields + a 160px
   footer at once, so compress further rather than push the heading off the
   top - the morph has to land somewhere the reader can see. */
@media (max-height: 900px) {
  .chamber--final .say { font-size: clamp(1.45rem, 1rem + 1.4vw, 1.95rem); }
  .chamber--final .chamber__sub { font-size: 14px; }
  .cta-form { margin-top: 0.7rem; gap: 8px; padding: 15px; }
  .cta-form textarea { min-height: 56px; }
  .cta-form input, .cta-form select, .cta-form textarea { padding: 9px 13px; }
  .cta-submit { padding: 11px 26px; }
  .field-hint { display: none; }
}
@media (max-height: 840px) {
  .chamber--final { padding-top: 4vh; }
  .chamber--final .say { font-size: 1.4rem; max-width: 22ch; }
  .chamber--final .chamber__sub { font-size: 13px; margin-top: 0.5rem; }
  .cta-form { margin-top: 0.6rem; gap: 7px; padding: 13px; }
  .cta-form label { font-size: 12px; }
  .cta-form textarea { min-height: 48px; }
  .cta-form input, .cta-form select, .cta-form textarea { padding: 8px 12px; font-size: 14px; }
  .cta-submit { padding: 10px 26px; }
  .cta-confirm { margin-top: 8px; }
}
.chamber--final .chamber__in { position: static; margin: 0 auto; max-width: 38rem; padding-bottom: 0; }
.chamber--final::before { position: absolute; inset: 0; }

/* ---------- Contact form -----------------------------------------------------
   A real enquiry form, not an email capture: the heading above it asks people
   what isn't coming together, so there has to be somewhere to answer. Labels
   are visible rather than placeholder-only - placeholders vanish on focus and
   leave people guessing what a field wanted. */

.cta-form {
  width: 100%; margin-top: 0.9rem; display: flex; flex-direction: column;
  gap: 10px; text-align: left;
  /* the scene keeps moving behind this, so the form needs its own ground */
  background: rgba(var(--scrim-rgb), 0.55);
  border: 1px solid var(--hair); border-radius: var(--r-lg);
  padding: 18px; backdrop-filter: blur(14px) saturate(1.1);
  -webkit-backdrop-filter: blur(14px) saturate(1.1);
}

.field-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }

.field label {
  font-size: 13px; font-weight: 600; letter-spacing: 0.01em;
  color: rgba(var(--on-surface-rgb), 0.72);
}

.cta-form input,
.cta-form select,
.cta-form textarea {
  width: 100%; font-family: inherit; font-size: 15px; color: var(--on-deep);
  background: rgba(var(--on-surface-rgb), 0.08);
  border: 1.5px solid var(--hair); border-radius: 10px;
  padding: 11px 14px; transition: border-color 0.16s, background 0.16s;
}
.cta-form textarea { resize: vertical; min-height: 66px; line-height: 1.5; }
.cta-form select { appearance: none; cursor: pointer; padding-right: 40px;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 20px) calc(50% + 2px), calc(100% - 15px) calc(50% + 2px);
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; }

.cta-form input:focus,
.cta-form select:focus,
.cta-form textarea:focus {
  outline: none; border-color: var(--accent-text);
  background: rgba(var(--on-surface-rgb), 0.12);
}
.cta-form ::placeholder { color: rgba(var(--on-surface-rgb), 0.38); }

.cta-form [aria-invalid="true"] { border-color: var(--error); }

.field-hint  { font-size: 12.5px; color: rgba(var(--on-surface-rgb), 0.45); }
.field-error { font-size: 12.5px; color: var(--error); }

.cta-submit {
  width: 100%; background: var(--accent); color: #fff; border: none;
  padding: 13px 26px; border-radius: 10px; font-size: 15px; font-weight: 700;
  cursor: pointer; font-family: inherit; letter-spacing: -0.3px;
  transition: background 0.18s; margin-top: 4px;
}
.cta-submit:hover { background: var(--accent-lift); }
.cta-submit:disabled { opacity: 0.65; cursor: default; }

.cta-confirm { font-size: 13px; color: rgba(var(--on-surface-rgb),0.45); margin-top: 16px; }

@media (max-width: 560px) { .field-grid { grid-template-columns: 1fr; } }

/* ---------- Footer ------------------------------------------------------- */

.foot { background: var(--deep-3); color: var(--on-deep-body); padding-block: 3.2rem 2.25rem; border-top: 1px solid var(--hair); }
.foot__row { display: flex; align-items: center; justify-content: space-between; gap: 20px; flex-wrap: wrap; }
.foot__links { display: flex; align-items: center; gap: 24px; flex-wrap: wrap; }
.foot a { font-size: 13px; color: rgba(var(--on-surface-rgb),0.4); text-decoration: none; }
.foot a:hover { color: var(--on-deep); }
.foot__copy { font-size: 13px; color: rgba(var(--on-surface-rgb),0.25); }

/* ---------- Reveal --------------------------------------------------------- */

.rise { opacity: 0; transform: translateY(24px); transition: opacity var(--slow) var(--ease), transform var(--slow) var(--ease); }
.rise.is-in { opacity: 1; transform: none; }
.no-js .rise { opacity: 1; transform: none; }

.count-up { font-variant-numeric: tabular-nums; }

/* ---------- Tilt-on-hover --------------------------------------------------
   The rotation itself is set inline by site.js on mousemove (a continuous,
   cursor-tracked value doesn't belong in a CSS rule). This class only owns
   what's static: the fast, snappy transition back to flat on mouseleave
   (deliberately NOT var(--slow) - that's tuned for the once-ever scroll
   reveal these same cards use, and would make hover feel laggy), and the
   lift so the tilt actually reads as depth rather than a flat rotation. */
/* site.js sets --tilt-x/--tilt-y rather than writing `transform` inline,
   so a card that already has a transform of its own (the arc cards) can
   compose both instead of having one overwrite the other. */
.tilt-card {
  transform: perspective(700px) rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg));
  transition: transform 0.15s ease-out, box-shadow 0.15s ease-out;
}
.tilt-card.is-tilting { box-shadow: 0 18px 36px rgba(0,0,0,0.16); }
@media (prefers-reduced-motion: reduce) { .tilt-card { transition: none; } }

@media (prefers-reduced-motion: reduce) {
  .rise { opacity: 1; transform: none; transition: none; }
  .btn:active { transform: none; }
  * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

:target, section[id] { scroll-margin-top: 90px; }
