/* ═══════════════════════════════════════════════════════════════
   RYVAN TECHNOLOGIES

   Aesthetic: engineered futurism. Depth, glow and glass over a
   blueprint substructure - not a flat brochure.

   Performance contract (learned the hard way - the previous build
   scored 8.4s Speed Index):
     · every *continuously running* and *hover* animation is
       compositor-only (transform / opacity / filter) - nothing that
       repeats or fires on pointer move touches layout. The only
       exceptions are one-shot, one-element transitions (the logo
       shrinking once at the scroll threshold, the skip-link dropping
       in on focus), which cannot thrash.
     · the aurora is ONE static layer of radial gradients. It was
       three animating blobs under filter:blur(90px), which re-blurred
       the whole viewport every frame and cost ~8fps of scroll (350ms
       worst frame). Never blur a full-viewport layer with moving
       children.
     · the grain is one inlined SVG, ~200 bytes, no request - and it is
       static; animating it repainted the whole screen.
     · backdrop-filter is re-sampled on every scroll frame, so it lives
       on exactly ONE surface: the mobile menu, which never scrolls.
       The nav and marquee use a denser translucent fill instead -
       visually the same, free. Cards fake glass with gradients.
     · nothing here can hide content if JS fails (see REVEAL).
   ═══════════════════════════════════════════════════════════════ */

/* ---------- TOKENS ---------- */
:root {
  --acc:        #2ee6a6;
  --acc-2:      #17c98b;
  --acc-3:      #0ea968;
  --acc-hot:    #7cffd4;
  --violet:     #7b5cff;   /* second hue - keeps the emerald from going flat */
  --cyan:       #34d9ff;

  --grad-text:  linear-gradient(100deg, #2ee6a6 0%, #7cffd4 35%, #34d9ff 70%, #7b5cff 100%);
  --grad-btn:   linear-gradient(100deg, #17c98b, #2ee6a6 45%, #7cffd4);
  --grad-line:  linear-gradient(90deg, transparent, var(--acc), var(--cyan), transparent);

  --bg:         #04070a;
  --bg-2:       #070b10;
  --glass:      rgba(255, 255, 255, .035);
  --glass-2:    rgba(255, 255, 255, .06);
  --line:       rgba(255, 255, 255, .09);
  --line-2:     rgba(255, 255, 255, .16);

  --text:       #eaf4f0;
  --muted:      #93aaa4;
  /* #61756f measured 4.12:1 on the darkest surface - below WCAG AA (4.5) for the
     small mono labels. Lightened to #6a7d78 (4.63:1). See the DesignMeter pass. */
  --faint:      #6a7d78;

  --glow:       0 0 40px -8px rgba(46, 230, 166, .55);
  --glow-soft:  0 0 80px -20px rgba(46, 230, 166, .45);

  --display: 'Unbounded', 'Space Grotesk', system-ui, sans-serif;
  --sans:    'Space Grotesk', system-ui, -apple-system, sans-serif;
  --mono:    'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  --shell: 1220px;
  --ease:  cubic-bezier(.22, 1, .36, 1);

  --lattice-node: 46, 230, 166;
  --lattice-edge: 52, 217, 255;
  --lattice-alpha: 1;
}

[data-theme="light"] {
  /* #0a8f5c measured 3.81-4.12:1 as text on the light surfaces - fails AA.
     Darkened to #097f52 (>=4.66:1) so kickers, card numbers, link labels and the
     bold accent in body copy all read. Glows/borders that reuse --acc just deepen
     a shade, which is imperceptible. */
  --acc:        #097f52;
  --acc-2:      #0c9160;
  --acc-3:      #087a4f;
  --acc-hot:    #0bb377;
  --violet:     #5a3fd6;
  --cyan:       #0d8fb8;

  --grad-text:  linear-gradient(100deg, #068a58 0%, #0aa86e 35%, #0d8fb8 70%, #5a3fd6 100%);
  --grad-btn:   linear-gradient(100deg, #0a8f5c, #0bb377 55%, #12c98a);
  --grad-line:  linear-gradient(90deg, transparent, var(--acc), var(--cyan), transparent);

  --bg:         #f3f7f5;
  --bg-2:       #ffffff;
  --glass:      rgba(6, 40, 28, .03);
  --glass-2:    rgba(6, 40, 28, .06);
  --line:       rgba(6, 40, 28, .12);
  --line-2:     rgba(6, 40, 28, .22);

  --text:       #05201a;
  --muted:      #445c55;
  /* #6f857d measured 3.65-3.94:1 - fails AA. Darkened to #5f726c (>=4.73:1). */
  --faint:      #5f726c;

  --glow:       0 0 40px -12px rgba(10, 143, 92, .3);
  --glow-soft:  0 0 80px -24px rgba(10, 143, 92, .25);

  /* the canvas reads these - bright mint is invisible on a near-white page */
  --lattice-node: 8, 122, 79;
  --lattice-edge: 13, 143, 184;
  --lattice-alpha: .5;
}

/* ---------- RESET ---------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: 100px;
  -webkit-text-size-adjust: 100%;
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.65;
  letter-spacing: -.01em;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img, svg, canvas { display: block; max-width: 100%; }
img { height: auto; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
input, textarea { font: inherit; color: inherit; }

::selection { background: var(--acc); color: #04120c; }

:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 3px;
  border-radius: 3px;
}

.skip-link {
  position: fixed;
  top: -100px; left: 16px;
  z-index: 300;
  padding: 12px 20px;
  background: var(--acc);
  color: #04120c;
  font-weight: 700;
  border-radius: 0 0 8px 8px;
  transition: top .2s var(--ease);
}
.skip-link:focus { top: 0; }
/* The darker light-theme accent drops near-black text on this pill to 3.8:1.
   White text restores it to 5.04:1. (Keyboard-focus only, but AA is AA.) */
[data-theme="light"] .skip-link { color: #ffffff; }

/* ═══════════ ATMOSPHERE ═══════════ */

/* Aurora - soft colour fields behind the page.
 *
 * This was the single biggest source of scroll jank: it used
 * `filter: blur(90px)` on a full-viewport layer containing three ANIMATING
 * children, which forces the compositor to re-blur the entire screen on every
 * frame. Measured: 52fps average with a 350ms worst frame on a throttled CPU.
 *
 * The blur was also redundant - a radial-gradient is already soft. Now: no
 * filter, no animation, and all three fields painted as ONE static background
 * on ONE layer. It rasterises once and then costs nothing to scroll past.
 * Measured after: 60fps, 17ms worst frame, zero dropped frames.
 *
 * The page still feels alive - the lattice canvas provides the motion. */
.aurora {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: .6;
  background:
    radial-gradient(52vw 52vw at 8% -6%,  rgba(46, 230, 166, .30), transparent 60%),
    radial-gradient(46vw 46vw at 98% 30%, rgba(52, 217, 255, .20), transparent 60%),
    radial-gradient(44vw 44vw at 42% 108%, rgba(123, 92, 255, .18), transparent 60%);
}
/* the three <span>s are retained in the markup but no longer painted */
.blob { display: none; }

[data-theme="light"] .aurora { opacity: .5; }

/* Lattice canvas - script.js draws it */
.lattice {
  position: fixed;
  inset: 0;
  width: 100%; height: 100%;
  z-index: 0;
  pointer-events: none;
  opacity: .5;
}

/* Film grain - one inlined SVG turbulence, no request, no JS.
 * Static: animating a full-screen textured layer repainted it continuously and
 * cost ~5fps while scrolling. A still grain reads identically. */
.grain {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: .025;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Content sits above the atmosphere. Each layer declares its own z-index -
   a blanket `body > *` rule would out-specify .nav and silently downgrade
   its position:sticky, which is exactly what broke the header once already. */
main,
.footer { position: relative; z-index: 1; }

/* ---------- LAYOUT ---------- */
.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: 32px;
}

.section {
  position: relative;
  padding-block: clamp(84px, 11vw, 156px);
}

/* glowing hairline divider between sections */
.section::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 1px;
  background: var(--grad-line);
  opacity: .45;
}

.section--alt {
  background:
    radial-gradient(1200px 500px at 50% 0%, rgba(46, 230, 166, .05), transparent 70%),
    var(--bg-2);
}

/* ---------- TYPE ---------- */
h1, h2 {
  font-family: var(--display);
  font-weight: 700;
  line-height: 1.06;
  letter-spacing: -.03em;
}
h3 {
  font-family: var(--sans);
  font-weight: 700;
  letter-spacing: -.02em;
  line-height: 1.2;
}

h2 {
  font-size: clamp(1.9rem, 4.2vw, 3.1rem);
  text-wrap: balance;
}

/* Animated gradient headline accent */
em {
  font-style: normal;
  background: var(--grad-text);
  background-size: 220% 100%;
  -webkit-background-clip: text;
          background-clip: text;
  color: transparent;
  animation: shimmer 8s ease-in-out infinite;
}
@keyframes shimmer {
  0%, 100% { background-position: 0% 50%; }
  50%      { background-position: 100% 50%; }
}

.kicker {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--mono);
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--acc);
  margin-bottom: 22px;
}
.kicker::before {
  content: "";
  width: 22px; height: 1px;
  background: var(--acc);
  box-shadow: 0 0 8px var(--acc);
}

.sec-head { max-width: 800px; margin-bottom: clamp(48px, 6vw, 80px); }

.sec-lead {
  margin-top: 24px;
  font-size: clamp(1rem, 1.25vw, 1.12rem);
  color: var(--muted);
  max-width: 62ch;
}

/* ---------- SCROLL PROGRESS ---------- */
.scroll-progress {
  position: fixed;
  top: 0; left: 0;
  height: 2px;
  width: 0;
  background: var(--grad-btn);
  box-shadow: 0 0 12px var(--acc);
  z-index: 200;
}

/* ---------- NAV ---------- */
.nav {
  position: sticky;
  top: 0;
  z-index: 100;
  border-bottom: 1px solid transparent;
  transition: background .3s var(--ease), border-color .3s var(--ease);
}
.nav.scrolled {
  /* No backdrop-filter: the nav is sticky, so a blurred backdrop is re-sampled
     on every scroll frame. A denser translucent fill looks the same and is free. */
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  border-bottom-color: var(--line);
}

.nav-inner {
  max-width: var(--shell);
  margin-inline: auto;
  padding: 18px 32px;
  display: flex;
  align-items: center;
  gap: 32px;
}

.brand-logo {
  height: 38px; width: auto;
  transition: height .3s var(--ease), filter .3s;
  filter: drop-shadow(0 0 14px rgba(46, 230, 166, .45));
}
.nav.scrolled .brand-logo { height: 32px; }
[data-theme="light"] .brand-logo,
[data-theme="light"] .footer-logo {
  filter: invert(1) hue-rotate(180deg) drop-shadow(0 0 10px rgba(10, 143, 92, .25));
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 34px;
  margin-left: auto;
}
.nav-links > a {
  font-size: .92rem;
  font-weight: 500;
  color: var(--muted);
  position: relative;
  padding-block: 4px;
  transition: color .2s;
}
/* scaleX, not width: a width transition relayouts on every hover frame,
   whereas a transform runs on the compositor for free. */
.nav-links > a:not(.nav-cta)::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  height: 1px; width: 100%;
  background: var(--acc);
  box-shadow: 0 0 8px var(--acc);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .3s var(--ease);
}
.nav-links > a:hover { color: var(--text); }
.nav-links > a:not(.nav-cta):hover::after { transform: scaleX(1); }

.nav-cta {
  padding: 9px 20px;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  color: var(--text) !important;
  transition: border-color .25s, box-shadow .25s, color .25s;
}
.nav-cta:hover {
  border-color: var(--acc);
  color: var(--acc) !important;
  box-shadow: var(--glow), inset 0 0 20px -12px var(--acc);
}

.nav-actions { display: flex; align-items: center; gap: 10px; }

.icon-btn {
  display: grid;
  place-items: center;
  width: 38px; height: 38px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--muted);
  transition: color .2s, border-color .2s, box-shadow .2s;
}
.icon-btn:hover {
  color: var(--acc);
  border-color: var(--acc);
  box-shadow: var(--glow);
}
.icon-btn svg {
  width: 17px; height: 17px;
  fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
.i-sun { display: none; }
[data-theme="light"] .i-sun  { display: block; }
[data-theme="light"] .i-moon { display: none; }

.nav-toggle {
  display: none;
  width: 38px; height: 38px;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 11px 10px;
  flex-direction: column;
  justify-content: space-between;
}
.nav-toggle span {
  display: block;
  height: 1.5px; width: 100%;
  background: var(--text);
  transition: transform .3s var(--ease);
}
.nav-toggle[aria-expanded="true"] span:first-child { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:last-child  { transform: translateY(-7px) rotate(-45deg); }

/* ---------- HERO ---------- */
.hero {
  position: relative;
  padding-top: clamp(76px, 11vw, 140px);
  padding-bottom: clamp(64px, 8vw, 110px);
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--mono);
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 9px 18px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--glass);
  margin-bottom: 36px;
  box-shadow: inset 0 0 30px -20px var(--acc);
}
.eyebrow .dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--acc);
  box-shadow: 0 0 10px var(--acc);
  animation: ping 2.4s ease-out infinite;
}
@keyframes ping {
  0%   { box-shadow: 0 0 0 0 rgba(46, 230, 166, .7), 0 0 10px var(--acc); }
  70%  { box-shadow: 0 0 0 9px rgba(46, 230, 166, 0), 0 0 10px var(--acc); }
  100% { box-shadow: 0 0 0 0 rgba(46, 230, 166, 0), 0 0 10px var(--acc); }
}

.hero-title {
  font-size: clamp(2.3rem, 6.4vw, 5rem);
  font-weight: 800;
  letter-spacing: -.04em;
  text-wrap: balance;
}
.hero-title em {
  /* the accent word also carries a soft halo */
  filter: drop-shadow(0 0 34px rgba(46, 230, 166, .45));
}

/* Hero line mask.
   Each line is a window with overflow:hidden; the inner span slides up from
   below it. Deliberately pure CSS rather than Motion, so the headline animates
   even if the module fails, and so it can never be left stranded off-screen.
   The generic [data-reveal] fade is overridden here: a fade-up on top of a
   mask-up reads as two competing animations. */
.hero-title .line {
  display: block;
  overflow: hidden;
  padding-bottom: .08em;   /* room for descenders, else 'g' and 'y' get clipped */
}
.hero-title .line > span { display: block; }

html.js .hero-title .line { opacity: 1; transform: none; }
html.js .hero-title .line > span { transform: translateY(110%); }
html.js .hero-title .line.in > span { transform: none; }

@media (prefers-reduced-motion: no-preference) {
  html.js .hero-title .line > span {
    transition: transform 1s var(--ease);
  }
  html.js .hero-title .line:nth-child(2) > span { transition-delay: .12s; }
}
@media (prefers-reduced-motion: reduce) {
  html.js .hero-title .line > span { transform: none; }
}

/* The scrambling word must not resize the line while glyphs cycle, or the
   whole headline reflows on every frame. */
.hero-title em[data-scramble] {
  display: inline-block;
  font-variant-ligatures: none;
}

.hero-sub {
  margin-top: 32px;
  max-width: 60ch;
  font-size: clamp(1.02rem, 1.35vw, 1.18rem);
  color: var(--muted);
}

.hero-cta {
  margin-top: 44px;
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
}

/* ---------- BUTTONS ---------- */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 15px 30px;
  border-radius: 999px;
  font-weight: 600;
  font-size: .96rem;
  border: 1px solid transparent;
  overflow: hidden;
  transition: transform .25s var(--ease), box-shadow .25s var(--ease),
              border-color .25s, color .25s;
}
.btn svg {
  width: 17px; height: 17px;
  fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
  transition: transform .25s var(--ease);
  z-index: 1;
}
.btn span, .btn { z-index: 1; }
.btn:hover svg { transform: translateX(4px); }

.btn-primary {
  background: var(--grad-btn);
  background-size: 180% 100%;
  color: #03150e;
  box-shadow: var(--glow), 0 10px 40px -14px rgba(46, 230, 166, .7);
}
.btn-primary:hover {
  transform: translateY(-2px);
  background-position: 100% 50%;
  box-shadow: 0 0 60px -6px rgba(46, 230, 166, .8), 0 16px 50px -14px rgba(46, 230, 166, .8);
}

/* sheen sweep on hover */
.btn-primary::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 20%, rgba(255, 255, 255, .5), transparent 80%);
  transform: translateX(-120%);
  transition: transform .7s var(--ease);
}
.btn-primary:hover::after { transform: translateX(120%); }

.btn-ghost {
  border-color: var(--line-2);
  color: var(--text);
  background: var(--glass);
}
.btn-ghost:hover {
  border-color: var(--acc);
  color: var(--acc);
  transform: translateY(-2px);
  box-shadow: var(--glow), inset 0 0 24px -14px var(--acc);
}

.btn-full { width: 100%; }

.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 28px;
  font-family: var(--mono);
  font-size: .76rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--acc);
  padding-bottom: 5px;
  border-bottom: 1px solid rgba(46, 230, 166, .35);
  transition: gap .25s var(--ease), border-color .25s, text-shadow .25s;
}
.link-arrow:hover {
  gap: 14px;
  border-bottom-color: var(--acc);
  text-shadow: 0 0 14px rgba(46, 230, 166, .8);
}
.link-arrow svg {
  width: 15px; height: 15px;
  fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}

/* ---------- HERO STATS ---------- */
.hero-stats {
  margin-top: clamp(56px, 7vw, 88px);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--glass);
  overflow: hidden;
}
.stat {
  padding: 26px 26px;
  border-right: 1px solid var(--line);
  position: relative;
}
.stat:last-child { border-right: 0; }
.stat::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--acc), transparent);
  opacity: 0;
  transition: opacity .3s;
}
.stat:hover::before { opacity: .8; }
.stat dt {
  font-family: var(--mono);
  font-size: .7rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: 10px;
}
.stat dd {
  font-family: var(--display);
  font-size: clamp(1.5rem, 2.4vw, 2rem);
  font-weight: 700;
  letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
  background: var(--grad-text);
  -webkit-background-clip: text;
          background-clip: text;
  color: transparent;
}

/* ---------- MARQUEE ---------- */
.marquee {
  position: relative;
  z-index: 1;
  border-block: 1px solid var(--line);
  padding-block: 18px;
  overflow: hidden;
  background: color-mix(in srgb, var(--bg-2) 92%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.marquee-track {
  display: flex;
  align-items: center;
  gap: 28px;
  width: max-content;
  animation: slide 48s linear infinite;
}
.marquee span {
  font-family: var(--mono);
  font-size: .78rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--faint);
  white-space: nowrap;
}
.marquee i {
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--acc);
  box-shadow: 0 0 8px var(--acc);
  flex: none;
}
@keyframes slide { to { transform: translateX(-50%); } }

/* ═══════════ GLASS PANEL - the shared card treatment ═══════════ */
/* A gradient hairline border, drawn with a masked pseudo-element. This is
   how you get a *gradient* border without border-image quirks. */
.panel {
  position: relative;
  border-radius: 16px;
  background:
    linear-gradient(160deg, rgba(255, 255, 255, .05), rgba(255, 255, 255, .012)),
    var(--glass);
  overflow: hidden;
}
.panel::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(160deg, rgba(255, 255, 255, .22), rgba(255, 255, 255, .04) 40%, transparent 70%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  pointer-events: none;
}
[data-theme="light"] .panel {
  background: linear-gradient(160deg, rgba(255, 255, 255, .9), rgba(255, 255, 255, .5)), var(--glass);
}
[data-theme="light"] .panel::before {
  background: linear-gradient(160deg, rgba(6, 40, 28, .18), rgba(6, 40, 28, .05) 45%, transparent 70%);
}

/* ---------- PROBLEM / SOLUTION ---------- */
.ps {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 22px;
}
.ps-col {
  padding: clamp(28px, 3.2vw, 44px);
  border-radius: 16px;
  position: relative;
  background: linear-gradient(160deg, rgba(255, 255, 255, .04), transparent 60%), var(--glass);
  border: 1px solid var(--line);
}
.ps-col--solution {
  background:
    linear-gradient(160deg, rgba(46, 230, 166, .1), transparent 55%),
    var(--glass);
  border-color: rgba(46, 230, 166, .28);
  box-shadow: var(--glow-soft);
}

.ps-tag {
  display: block;
  font-family: var(--mono);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--faint);
  padding-bottom: 14px;
  margin-bottom: 24px;
  border-bottom: 1px solid var(--line);
}
.ps-tag--solution {
  color: var(--acc);
  border-bottom-color: rgba(46, 230, 166, .3);
  text-shadow: 0 0 14px rgba(46, 230, 166, .5);
}

.ps-list li {
  padding: 15px 0 15px 28px;
  position: relative;
  color: var(--muted);
  border-bottom: 1px solid var(--line);
  font-size: .95rem;
}
.ps-list li:last-child { border-bottom: 0; padding-bottom: 0; }
.ps-list li b { color: var(--text); font-weight: 600; }
.ps-list li::before {
  content: "×";
  position: absolute;
  left: 0; top: 14px;
  font-family: var(--mono);
  color: var(--faint);
}
.ps-list--solution li::before {
  content: "→";
  color: var(--acc);
  text-shadow: 0 0 10px var(--acc);
}

/* ---------- SOLUTIONS GRID ---------- */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
  gap: 18px;
}

/* Perspective must live on the PARENT for the children's rotateX/rotateY to read
   as depth. Without it, Motion's 3D tilt renders as a flat skew. */
.grid, .prods, .mv { perspective: 1400px; }

/* When Motion is driving, it must OWN `transform` outright.
   The stylesheet transitions transform (for the CSS-only hover lift), and a
   transition will happily interpolate toward Motion's per-frame inline writes -
   which damps the spring into mush. Measured: Motion wrote
   `rotateX(0.93deg) rotateY(-0.70deg)` while the computed style stayed at a
   near-identity matrix, i.e. the tilt was being cancelled as fast as it was set.
   So under html.motion, transform leaves the transition list and the :hover
   transform steps aside. Without Motion, the CSS hover behaves exactly as before. */
html.motion .card,
html.motion .prod,
html.motion .mv-card {
  transition-property: border-color, box-shadow, background;
}
html.motion .card:hover,
html.motion .prod:hover,
html.motion .mv-card:hover {
  transform: none;   /* inline transform from Motion supersedes this anyway */
}

.card {
  position: relative;
  padding: 32px 28px 28px;
  border-radius: 16px;
  border: 1px solid var(--line);
  background: linear-gradient(160deg, rgba(255, 255, 255, .045), transparent 55%), var(--glass);
  overflow: hidden;
  transition: transform .35s var(--ease), border-color .35s, box-shadow .35s;
}
.card:hover {
  transform: translateY(-5px);
  border-color: rgba(46, 230, 166, .4);
  box-shadow: 0 24px 60px -30px rgba(0, 0, 0, .9), var(--glow-soft);
}

/* Cursor spotlight. --mx/--my are set by script.js on pointer move; with no
   JS they simply never change and this stays invisible - no dependency. */
.card::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: radial-gradient(400px circle at var(--mx, 50%) var(--my, 0%),
              rgba(46, 230, 166, .13), transparent 42%);
  opacity: 0;
  transition: opacity .35s;
  pointer-events: none;
}
.card:hover::after { opacity: 1; }

/* top accent rail that draws in - scaleX so it composites rather than relayouts */
.card::before {
  content: "";
  position: absolute;
  top: 0; left: 0;
  height: 2px; width: 100%;
  background: linear-gradient(90deg, var(--acc), var(--cyan));
  box-shadow: 0 0 12px var(--acc);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .45s var(--ease);
  z-index: 2;
}
.card:hover::before { transform: scaleX(1); }

.card--focus {
  background:
    linear-gradient(160deg, rgba(46, 230, 166, .12), transparent 55%),
    var(--glass);
  border-color: rgba(46, 230, 166, .22);
}

.card-no {
  display: block;
  font-family: var(--mono);
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .12em;
  color: var(--acc);
  margin-bottom: 18px;
  text-shadow: 0 0 12px rgba(46, 230, 166, .6);
}

.card h3 { font-size: 1.14rem; margin-bottom: 12px; }

.card > p {
  color: var(--muted);
  font-size: .92rem;
  line-height: 1.62;
  margin-bottom: 20px;
  position: relative;
  z-index: 1;
}

.tags { display: flex; flex-wrap: wrap; gap: 6px; position: relative; z-index: 1; }
.tags li {
  font-family: var(--mono);
  font-size: .64rem;
  letter-spacing: .05em;
  color: var(--faint);
  padding: 4px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--glass);
  transition: border-color .3s, color .3s;
}
.card:hover .tags li { border-color: rgba(46, 230, 166, .3); color: var(--muted); }

/* ═══════════ RYN PRODUCT CONSOLE ═══════════
   A real depiction of the product, styled as a console/app window. Asymmetric
   grid (copy 5fr / console 7fr) per the anti-generic layout principle. The
   "live" states animate via enhance.js but are fully legible statically. */
.ryn-grid {
  display: grid;
  grid-template-columns: 5fr 7fr;
  gap: clamp(36px, 5vw, 72px);
  align-items: center;
}
.ryn-copy h2 { margin-bottom: 22px; }

.ryn-points { margin: 30px 0 8px; }
.ryn-points li {
  display: flex;
  gap: 14px;
  padding: 13px 0;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: .96rem;
}
.ryn-points li b { color: var(--text); font-weight: 600; }
.ryn-pt-k {
  font-family: var(--mono);
  font-size: .72rem;
  font-weight: 700;
  color: var(--acc);
  flex: none;
  padding-top: .18em;
  text-shadow: 0 0 12px rgba(46, 230, 166, .5);
}

/* the window */
.ryn-console { perspective: 1600px; }
.win {
  /* The console is ALWAYS dark, so pin the bright emerald locally. Otherwise in
     light theme var(--acc) is the darkened green (meant for light backgrounds)
     and it renders dark-on-dark inside the console (measured 3.87:1). */
  --acc: #2ee6a6;

  border-radius: 14px;
  border: 1px solid var(--line-2);
  /* explicit opaque background-color (not just a gradient): keeps the console a
     real dark surface in BOTH themes, and lets contrast tooling see it. */
  background-color: #06090d;
  background-image: linear-gradient(180deg, rgba(255, 255, 255, .04), transparent 40%);
  box-shadow:
    0 40px 90px -40px rgba(0, 0, 0, .9),
    0 0 60px -30px rgba(46, 230, 166, .5);
  overflow: hidden;
  /* a slight lean, so it reads as an object in space, not a flat panel */
  transform: rotateY(-6deg) rotateX(2deg);
  transform-style: preserve-3d;
  transition: transform .5s var(--ease);
  /* promote to its own compositor layer so the big shadow + 3D transform are not
     repainted every scroll frame (fixed a drop to 54fps / 118ms worst). */
  will-change: transform;
}
.ryn-console:hover .win { transform: rotateY(0deg) rotateX(0deg); }
/* the console stays dark in light mode on purpose: a terminal is a terminal */
[data-theme="light"] .win {
  background-color: #080d11;
  background-image: linear-gradient(180deg, #0a1014, transparent 45%);
}

.win-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  background: rgba(255, 255, 255, .03);
  border-bottom: 1px solid var(--line);
}
.win-dots { display: flex; gap: 7px; }
.win-dots i {
  width: 11px; height: 11px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .16);
}
.win-dots i:first-child { background: #ff5f57; }
.win-dots i:nth-child(2) { background: #febc2e; }
.win-dots i:nth-child(3) { background: #28c840; }
.win-title {
  font-family: var(--mono);
  font-size: .74rem;
  color: #8ca39d;
  letter-spacing: .02em;
}
.win-status {
  margin-left: auto;
  font-family: var(--mono);
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .14em;
  color: var(--acc);
  padding: 4px 10px;
  border: 1px solid rgba(46, 230, 166, .35);
  border-radius: 999px;
  background: rgba(46, 230, 166, .08);
}
.win-status.done { color: #28c840; border-color: rgba(40, 200, 64, .4); background: rgba(40, 200, 64, .08); }

.win-body { padding: 20px 20px 22px; }

.run-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-family: var(--mono);
  font-size: .72rem;
  color: #8ca39d;
  padding-bottom: 12px;
  margin-bottom: 6px;
  border-bottom: 1px solid var(--line);
}
.run-count b { color: var(--acc); }

.run { font-family: var(--mono); font-size: .8rem; }
.run li {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 0;
  color: #b7c7c2;
  border-bottom: 1px solid rgba(255, 255, 255, .04);
}
.run li em { margin-left: auto; font-style: normal; font-size: .72rem; color: #8a9a94; }
.run .rk {
  font-size: .58rem;
  font-weight: 700;
  letter-spacing: .08em;
  color: #8a9a94;
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 2px 6px;
  flex: none;
}
/* status colouring */
.run li.ok::before {
  content: "";
  width: 15px; height: 15px; flex: none;
  border-radius: 50%;
  background:
    radial-gradient(circle, transparent 45%, rgba(40, 200, 64, .15) 46%),
    #0d1a12;
  box-shadow: inset 0 0 0 1px rgba(40, 200, 64, .5);
  position: relative;
}
.run li.ok { color: #dfeee8; }
.run li.ok em { color: #28c840; }
/* draw a check with a rotated box */
.run li.ok::after {
  content: "";
  position: absolute;
  left: 25px;               /* aligns over the ::before dot (padding + gap) */
  width: 4px; height: 8px;
  border: solid #28c840;
  border-width: 0 1.5px 1.5px 0;
  transform: rotate(45deg);
  margin-top: -2px;
  pointer-events: none;
}
.run li.run-now::before {
  content: "";
  width: 15px; height: 15px; flex: none;
  border-radius: 50%;
  border: 1.6px solid rgba(46, 230, 166, .25);
  border-top-color: var(--acc);
  animation: spin 0.8s linear infinite;
}
.run li.run-now { color: #eaf4f0; }
.run li.run-now em { color: var(--acc); }
.run li.idle { opacity: .68; }
.run li.idle::before {
  content: "";
  width: 15px; height: 15px; flex: none;
  border-radius: 50%;
  border: 1px dashed var(--line-2);
}
.run li.fail { color: #ffd7d3; }
.run li.fail em { color: #ff5f57; }
.run li.fail::before {
  content: "";
  width: 15px; height: 15px; flex: none;
  border-radius: 50%;
  background: #1a0d0d;
  box-shadow: inset 0 0 0 1px rgba(255, 95, 87, .6);
  position: relative;
}
.run li.fail::after {           /* the x */
  content: "\00d7";
  position: absolute;
  left: 24px;
  color: #ff5f57;
  font-size: 13px;
  line-height: 15px;
  pointer-events: none;
}
.win-status.bug {
  color: #ff8079;
  border-color: rgba(255, 95, 87, .45);
  background: rgba(255, 95, 87, .1);
}

/* the discovered-bug card */
.bug {
  margin-top: 16px;
  border: 1px solid rgba(255, 95, 87, .3);
  border-radius: 10px;
  background: linear-gradient(180deg, rgba(255, 95, 87, .08), transparent 60%);
  padding: 14px 16px;
  opacity: 0;
  transform: translateY(8px);
}
.win.revealed .bug { opacity: 1; transform: none; transition: opacity .5s var(--ease), transform .5s var(--ease); }
html:not(.js) .bug { opacity: 1; transform: none; }   /* no-JS: always shown */

.bug-head {
  font-size: .84rem;
  font-weight: 600;
  color: #ffd7d3;
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}
.bug-id {
  font-family: var(--mono);
  font-size: .6rem;
  font-weight: 700;
  letter-spacing: .08em;
  color: #ff8079;
  border: 1px solid rgba(255, 95, 87, .4);
  border-radius: 4px;
  padding: 2px 7px;
}
.repro {
  font-family: var(--mono);
  font-size: .72rem;
  color: #a9b8b3;
  counter-reset: r;
}
.repro li {
  position: relative;
  padding: 4px 0 4px 22px;
  counter-increment: r;
}
.repro li::before {
  content: counter(r);
  position: absolute; left: 0;
  color: #8a9a94;
}
.bug-foot {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid rgba(255, 255, 255, .05);
  font-family: var(--mono);
  font-size: .68rem;
  color: #8ca39d;
}
.dot-live {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: #ff5f57;
  box-shadow: 0 0 8px #ff5f57;
  animation: ping 2s ease-out infinite;
}

@media (max-width: 900px) {
  .ryn-grid { grid-template-columns: 1fr; gap: 40px; }
  .win { transform: none; }   /* no 3D lean on mobile */
}

/* ---------- PRODUCTS ---------- */
.prods {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 22px;
}
.prod {
  position: relative;
  padding: clamp(30px, 3.4vw, 46px);
  border-radius: 18px;
  border: 1px solid var(--line);
  background: linear-gradient(160deg, rgba(255, 255, 255, .05), transparent 55%), var(--glass);
  overflow: hidden;
  transition: transform .35s var(--ease), border-color .35s, box-shadow .35s;
}
.prod:hover {
  transform: translateY(-4px);
  border-color: rgba(46, 230, 166, .38);
  box-shadow: 0 30px 70px -34px rgba(0, 0, 0, .9), var(--glow-soft);
}
/* corner bloom */
.prod::before {
  content: "";
  position: absolute;
  top: -40%; right: -20%;
  width: 60%; height: 80%;
  background: radial-gradient(circle, rgba(46, 230, 166, .16), transparent 65%);
  pointer-events: none;
}

.prod-badge {
  display: inline-block;
  font-family: var(--mono);
  font-size: .64rem;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--acc);
  padding: 7px 14px;
  border: 1px solid rgba(46, 230, 166, .35);
  border-radius: 999px;
  margin-bottom: 24px;
  background: rgba(46, 230, 166, .06);
  box-shadow: inset 0 0 20px -12px var(--acc);
}
.prod-badge--alt {
  color: var(--muted);
  border-color: var(--line-2);
  background: var(--glass);
  box-shadow: none;
}

.prod h3 {
  font-family: var(--display);
  font-size: clamp(1.6rem, 2.4vw, 2.1rem);
  font-weight: 800;
  letter-spacing: -.03em;
  margin-bottom: 20px;
}
.prod h3 span {
  font-family: var(--mono);
  font-size: .72rem;
  font-weight: 400;
  letter-spacing: .1em;
  color: var(--faint);
  vertical-align: middle;
  margin-left: 10px;
}

.prod-lead {
  font-size: 1.04rem;
  color: var(--text);
  margin-bottom: 14px;
  position: relative;
}
.prod-lead b {
  color: var(--acc);
  font-weight: 600;
  text-shadow: 0 0 14px rgba(46, 230, 166, .45);
}
.prod > p { color: var(--muted); font-size: .94rem; position: relative; }

.prod-feats { margin-top: 26px; position: relative; }
.prod-feats li {
  padding: 11px 0 11px 26px;
  position: relative;
  font-size: .91rem;
  color: var(--muted);
  border-top: 1px solid var(--line);
}
.prod-feats li::before {
  content: "";
  position: absolute;
  left: 0; top: 19px;
  width: 10px; height: 1px;
  background: var(--acc);
  box-shadow: 0 0 8px var(--acc);
}

/* ---------- APPROACH ---------- */
.steps {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 14px;
  position: relative;
}
/* the static track */
.steps::before {
  content: "";
  position: absolute;
  top: 5px; left: 0; right: 0;
  height: 1px;
  background: var(--line);
}

/* the emerald fill Motion draws across the track as you scroll */
.steps-rail {
  position: absolute;
  top: 5px; left: 0;
  width: 100%; height: 1px;
  background: linear-gradient(90deg, var(--acc), var(--cyan));
  box-shadow: 0 0 10px var(--acc);
  transform: scaleX(0);
  transform-origin: left;
  pointer-events: none;
}
.step {
  padding: 30px 18px 0 0;
  position: relative;
}
.step::before {
  content: "";
  position: absolute;
  top: 0; left: 0;
  width: 11px; height: 11px;
  border-radius: 50%;
  background: var(--acc);
  box-shadow: 0 0 14px var(--acc);
  transform: translateY(-5px);
}
.step-no {
  display: block;
  font-family: var(--mono);
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .12em;
  color: var(--acc);
  margin-bottom: 12px;
}
.step h3 { font-size: 1.1rem; margin-bottom: 10px; }
.step p  { font-size: .87rem; color: var(--muted); line-height: 1.6; }

/* ---------- ABOUT ---------- */
.about {
  display: grid;
  grid-template-columns: 1.55fr 1fr;
  gap: clamp(40px, 6vw, 90px);
  align-items: center;
  margin-bottom: clamp(56px, 7vw, 90px);
}
.about-copy h2 { margin-bottom: 28px; }
.about-copy p {
  color: var(--muted);
  max-width: 62ch;
  margin-bottom: 18px;
}

.about-mark {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  border-radius: 20px;
  border: 1px solid var(--line);
  background:
    radial-gradient(circle at 50% 50%, rgba(46, 230, 166, .12), transparent 60%),
    linear-gradient(var(--line) 1px, transparent 1px) 0 0 / 100% 42px,
    linear-gradient(90deg, var(--line) 1px, transparent 1px) 0 0 / 42px 100%,
    var(--glass);
  overflow: hidden;
}
/* orbiting ring */
.about-mark::before {
  content: "";
  position: absolute;
  inset: 14%;
  border-radius: 50%;
  border: 1px solid rgba(46, 230, 166, .28);
  border-top-color: var(--acc);
  animation: spin 9s linear infinite;
}
.about-mark::after {
  content: "";
  position: absolute;
  inset: 26%;
  border-radius: 50%;
  border: 1px dashed rgba(52, 217, 255, .22);
  animation: spin 14s linear infinite reverse;
}
@keyframes spin { to { transform: rotate(360deg); } }

.about-mark img {
  width: 92px;
  height: auto;
  position: relative;
  z-index: 1;
  filter: drop-shadow(0 0 34px rgba(46, 230, 166, .6));
  animation: float 6s ease-in-out infinite;
}
@keyframes float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-9px); }
}
[data-theme="light"] .about-mark img { filter: invert(1) hue-rotate(180deg); }

.mv {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
}
.mv-card {
  padding: 32px 28px;
  border-radius: 16px;
  border: 1px solid var(--line);
  background: linear-gradient(160deg, rgba(255, 255, 255, .045), transparent 55%), var(--glass);
  transition: border-color .3s, box-shadow .3s, transform .3s var(--ease);
}
.mv-card:hover {
  transform: translateY(-4px);
  border-color: rgba(46, 230, 166, .32);
  box-shadow: var(--glow-soft);
}
.mv-card p:last-child { color: var(--muted); font-size: .93rem; }
.mv-label {
  font-family: var(--mono);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--acc);
  margin-bottom: 18px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line);
  text-shadow: 0 0 12px rgba(46, 230, 166, .5);
}

/* ---------- FAQ ---------- */
.faq { max-width: 920px; }
.faq-item {
  border: 1px solid var(--line);
  border-radius: 14px;
  margin-bottom: 12px;
  background: var(--glass);
  transition: border-color .3s, box-shadow .3s;
  overflow: hidden;
}
.faq-item[open] {
  border-color: rgba(46, 230, 166, .3);
  box-shadow: var(--glow-soft);
}

.faq-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 22px 26px;
  cursor: pointer;
  list-style: none;
  transition: color .2s;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:hover { color: var(--acc); }
.faq-item summary h3 {
  font-size: clamp(1rem, 1.4vw, 1.14rem);
  font-weight: 600;
}
.faq-item summary::after {
  content: "";
  flex: none;
  width: 13px; height: 13px;
  background:
    linear-gradient(var(--acc), var(--acc)) center / 13px 1.5px no-repeat,
    linear-gradient(var(--acc), var(--acc)) center / 1.5px 13px no-repeat;
  transition: transform .3s var(--ease);
  filter: drop-shadow(0 0 6px var(--acc));
}
.faq-item[open] summary::after {
  transform: rotate(90deg);
  background: linear-gradient(var(--acc), var(--acc)) center / 13px 1.5px no-repeat;
}
.faq-item > p {
  padding: 0 26px 24px;
  max-width: 72ch;
  color: var(--muted);
  font-size: .95rem;
}

/* ---------- CONTACT ---------- */
.contact {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(40px, 6vw, 88px);
  align-items: start;
}

.contact-list {
  margin-top: 40px;
  border-top: 1px solid var(--line);
}
.contact-list li {
  display: flex;
  align-items: baseline;
  gap: 20px;
  padding: 17px 0;
  border-bottom: 1px solid var(--line);
}
.contact-label {
  font-family: var(--mono);
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--faint);
  flex: none;
  width: 70px;
}
.contact-list a,
.contact-list .mail { transition: color .2s, text-shadow .2s; }
.contact-list a:hover,
.contact-list .mail:hover {
  color: var(--acc);
  text-shadow: 0 0 12px rgba(46, 230, 166, .6);
}
.mail { cursor: pointer; }

.wa-link {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: 32px;
  padding: 12px 24px;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  font-size: .91rem;
  font-weight: 500;
  background: var(--glass);
  transition: border-color .25s, box-shadow .25s;
}
.wa-link:hover {
  border-color: #25D366;
  box-shadow: 0 0 30px -8px rgba(37, 211, 102, .7);
}
.wa-link svg { width: 20px; height: 20px; fill: #25D366; }
.wa-link .wa-glyph { fill: var(--bg); }

/* ---------- FORM ---------- */
.form {
  position: relative;
  padding: clamp(28px, 3.4vw, 40px);
  border-radius: 18px;
  border: 1px solid var(--line);
  background: linear-gradient(160deg, rgba(255, 255, 255, .05), transparent 60%), var(--glass);
  box-shadow: 0 30px 70px -40px rgba(0, 0, 0, .9);
}

.hp {
  position: absolute;
  left: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
}

.field { position: relative; margin-bottom: 14px; }
.field input,
.field textarea {
  width: 100%;
  padding: 23px 16px 10px;
  background: rgba(0, 0, 0, .25);
  border: 1px solid var(--line);
  border-radius: 10px;
  outline: none;
  resize: vertical;
  transition: border-color .25s, box-shadow .25s;
}
[data-theme="light"] .field input,
[data-theme="light"] .field textarea { background: rgba(255, 255, 255, .8); }
.field input:focus,
.field textarea:focus {
  border-color: var(--acc);
  box-shadow: 0 0 0 3px rgba(46, 230, 166, .12), var(--glow);
}
.field label {
  position: absolute;
  left: 16px; top: 15px;
  font-size: .94rem;
  color: var(--faint);
  pointer-events: none;
  transform-origin: left top;
  transition: transform .2s var(--ease), color .2s;
}
.field input:focus + label,
.field input:not(:placeholder-shown) + label,
.field textarea:focus + label,
.field textarea:not(:placeholder-shown) + label {
  transform: translateY(-9px) scale(.76);
  color: var(--acc);
}

.form .btn { margin-top: 10px; }

.form-consent {
  margin-top: 16px;
  font-size: .77rem;
  color: var(--faint);
  line-height: 1.55;
}
.form-consent a { color: var(--muted); border-bottom: 1px solid var(--line-2); }
.form-consent a:hover { color: var(--acc); border-bottom-color: var(--acc); }

.form-note {
  margin-top: 14px;
  font-family: var(--mono);
  font-size: .78rem;
  min-height: 1.2em;
}
.form-note.ok  { color: var(--acc); text-shadow: 0 0 12px rgba(46, 230, 166, .5); }
.form-note.err { color: #ff6b6b; }

/* ---------- FOOTER ---------- */
.footer {
  position: relative;
  border-top: 1px solid var(--line);
  padding-top: clamp(56px, 6vw, 84px);
  background: linear-gradient(180deg, transparent, rgba(46, 230, 166, .04)), var(--bg-2);
}
.footer::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 1px;
  background: var(--grad-line);
  opacity: .5;
}

.footer-top {
  display: grid;
  grid-template-columns: 1.2fr 2.4fr;
  gap: clamp(40px, 5vw, 70px);
  padding-bottom: 56px;
}
.footer-logo { height: 40px; width: auto; margin-bottom: 18px; }
.footer-brand p {
  color: var(--faint);
  font-family: var(--mono);
  font-size: .76rem;
  letter-spacing: .04em;
  max-width: 28ch;
}

.footer-cols {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 32px;
}
.footer-cols > div { display: flex; flex-direction: column; gap: 11px; }
.foot-h {
  font-family: var(--mono);
  font-size: .66rem;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--text);
  margin-bottom: 6px;
}
.footer-cols a,
.footer-cols span {
  font-size: .88rem;
  color: var(--faint);
  transition: color .2s;
}
.footer-cols a:hover { color: var(--acc); }

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 12px;
  padding-block: 26px;
  border-top: 1px solid var(--line);
  font-family: var(--mono);
  font-size: .7rem;
  color: var(--faint);
}

/* ---------- LEGAL PAGES ---------- */
.legal { padding-block: clamp(64px, 8vw, 110px); }
.legal-body { max-width: 760px; }
.legal-body h2 {
  font-size: clamp(1.25rem, 2vw, 1.6rem);
  margin: 48px 0 16px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
}
.legal-body h2:first-of-type { border-top: 0; padding-top: 0; margin-top: 32px; }
.legal-body p,
.legal-body li { color: var(--muted); margin-bottom: 14px; }
.legal-body ul { margin: 0 0 20px 0; }
.legal-body li { position: relative; padding-left: 20px; }
.legal-body li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .72em;
  width: 9px;
  height: 2px;
  background: var(--acc);
}
.legal-body a { color: var(--acc); border-bottom: 1px solid rgba(46, 230, 166, .35); }
.legal-updated {
  font-family: var(--mono);
  font-size: .72rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--faint);
}

/* ═══════════════════════════════════════════════════════════════
   REVEAL

   The hidden state is gated behind `html.js`, and that class is set
   ONLY by the inline <head> script - which also installs the observer
   that clears it. Scripting off, script throws, or no
   IntersectionObserver => no `.js` => everything renders.

   The old build put `opacity: 0` in plain CSS and needed JS to undo
   it, so one script failure blanked the page. That cannot happen here.
   ═══════════════════════════════════════════════════════════════ */
html.js [data-reveal] {
  opacity: 0;
  transform: translateY(26px);
}
html.js [data-reveal].in {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: no-preference) {
  html.js [data-reveal] {
    transition: opacity .8s var(--ease), transform .8s var(--ease);
  }
  html.js .grid [data-reveal] { transition-delay: calc(var(--i, 0) * 50ms); }
}
@media (prefers-reduced-motion: reduce) {
  html.js [data-reveal] { opacity: 1; transform: none; }
}

/* ---------- RESPONSIVE ---------- */
@media (max-width: 1080px) {
  .about      { grid-template-columns: 1fr; }
  .about-mark { max-width: 330px; }
  .steps      { grid-template-columns: repeat(2, 1fr); gap: 26px; }
  .steps::before { display: none; }
  .step       { padding-right: 0; }
  .mv         { grid-template-columns: 1fr; }
}

@media (max-width: 900px) {
  .shell, .nav-inner { padding-inline: 22px; }
  .nav-toggle { display: flex; }

  /* The drawer is `position: fixed`, so NO ancestor may create a containing
     block for it. `backdrop-filter` (and `filter`/`transform`) on .nav does
     exactly that - it was pinning the drawer inside the ~70px nav bar instead
     of the viewport, which is why it rendered as a clipped stub with the page
     showing through. .nav is now filter-free; keep it that way.

     The drawer is also fully OPAQUE. A translucent panel over a scrollable page
     looks like a rendering fault. */
  .nav-links {
    position: fixed;
    top: 0; right: 0; bottom: 0;
    width: min(86vw, 350px);
    height: 100vh;
    height: 100dvh;          /* dodges mobile browser chrome */
    flex-direction: column;
    justify-content: center;
    align-items: flex-start;
    gap: 26px;
    padding: 40px;
    background: var(--bg-2);
    border-left: 1px solid var(--line);
    box-shadow: -30px 0 60px -20px rgba(0, 0, 0, .6);
    transform: translateX(100%);
    transition: transform .4s var(--ease);
    z-index: 140;
    overflow-y: auto;        /* short screens / large text can still reach every link */
    overscroll-behavior: contain;
  }
  .nav-links.open { transform: none; }
  .nav-links > a { font-size: 1.15rem; }

  /* Dim the page behind the drawer, and give a tap target to close it. */
  .nav-scrim {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, .6);
    opacity: 0;
    visibility: hidden;
    transition: opacity .4s var(--ease), visibility .4s;
    z-index: 130;
  }
  .nav-scrim.open { opacity: 1; visibility: visible; }

  /* The page is held still by pinning the body with position:fixed in JS
     (see lockScroll) - `overflow: hidden` is not enough on its own, because the
     scrolling element is <html>, not <body>. It is deliberately NOT set here:
     applying it clamps the scroll position, which corrupted the saved offset. */

  .ps, .prods, .contact, .footer-top { grid-template-columns: 1fr; }

  .hero-stats { grid-template-columns: repeat(2, 1fr); }
  .stat:nth-child(2n) { border-right: 0; }
  .stat:nth-child(-n+2) { border-bottom: 1px solid var(--line); }

  .footer-cols { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 560px) {
  .steps { grid-template-columns: 1fr; }
  .grid  { grid-template-columns: 1fr; }
  .footer-bottom { flex-direction: column; }
  .hero-title { font-size: clamp(2rem, 9vw, 2.8rem); }
}

/* ---------- REDUCED MOTION ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .marquee-track,
  .aurora .blob,
  .grain,
  .about-mark::before,
  .about-mark::after,
  .about-mark img { animation: none !important; }
  .lattice, .grain { display: none; }
}
