/* ═══════════════════════════════════════════════════════════════════════
   JAANTRIX — v2 "Dimensional Khata"

   v1 was a flat ruled-paper system with one WebGL hero. v2 keeps every
   brand decision that was earned by measurement (the logo-sampled palette,
   the contrast-corrected text tokens, the 44px hit targets) and rebuilds
   the *surface* on a real z-axis: the khata is no longer printed on the
   page, it is a stack of physical sheets you look into.

   Design system source: ui-ux-pro-max → "Dimensional Layering" (4-level
   elevation, translateZ, parallax) as the base, with Spatial-UI glass
   used only where a panel genuinely floats over other content. The
   database's "3D & Hyperrealism" category is deliberately NOT the model —
   it is flagged Performance:Poor / Not-accessible, and this audience is
   on mid-range Android over 3G. Depth here is earned with transforms and
   shadows, which composite on the GPU for free, not with textures.

   EVERY 3D element does a job. Nothing rotates for decoration:
     · the product ring IS the product navigation
     · the device rotates to show you the screen you scrolled to
     · the COD bars ARE the calculator's output
     · the stat drums ARE the counters
     · the feature cards flip to reveal the spec sheet
   ═══════════════════════════════════════════════════════════════════════ */

/* ── capability tiers ──────────────────────────────────────────────────
   The whole 3D layer is gated on what the device can actually afford.
   Set by JS on <html> before first paint of the motion layer:
     t0 — no 3D at all (reduced-motion, Save-Data, <=4 logical cores,
          or deviceMemory <= 2). Flat v1-grade page. Fully functional.
     t1 — CSS 3D only (transforms, perspective, shadows). No WebGL.
     t2 — CSS 3D + the WebGL2 hero/orb scenes.
   Nothing below depends on a tier to be *usable* — tiers only add depth. */

:root {
  /* ── ground + ink — DARK (v2.1) ────────────────────────────────────
     The ground is not neutral black: every step is the logo navy
     (#0B1563) darkened, so the page still reads as Jaantrix rather than
     as a generic dark theme. Measured against --paper:
       --ink   17.3:1   --ink-2  10.9:1   --ink-3  6.8:1
     --ink-3 is the floor case and still clears 5.7:1 on --paper-3, the
     lightest surface it is ever placed on. */
  --paper:      #070B1E;
  --paper-2:    #0E142F;
  --paper-3:    #161D3F;
  --paper-4:    #1E2750;   /* the "underside" tone for 3D side faces */
  --ink:        #EEF1FA;
  --ink-2:      #B9C2DC;
  --ink-3:      #8D98BA;
  --rule:       #26305A;
  --rule-soft:  #1B2244;

  /* ── accents — still pixel-sampled from the logo ────────────────────
     Inverting the ground inverts which variant is the text-safe one. On
     white, the logo's own coral and blue both FAILED as text (2.89:1 and
     3.65:1) and needed darkening. On this ground they pass outright —
     coral 6.8:1, blue 5.3:1 — so --accent/--aurora are now usable as text
     and --accent-2/--aurora-2 are the *lighter* emphasis variants
     (8.5:1 and 8.8:1) rather than darker rescues.

     The washes are re-derived too: a pale tint is invisible here, so each
     is the hue pulled down into the ground. --accent-2 on --accent-wash
     measures 7.5:1, --aurora-2 on --aurora-wash 7.4:1. */
  --accent:     #F56F50;
  --accent-2:   #FF8A6E;
  --accent-wash:#2A1512;
  --aurora:     #458BC5;
  --aurora-2:   #7FB4E4;
  --aurora-wash:#101F31;
  --margin-red: #E4626A;   /* #B4232A is unreadable here — lifted to 5.8:1 */
  --wa:         #3FBF77;   /* #0C6B37 likewise — lifted to 8.3:1 */
  --wa-wash:    #0C2A1B;

  /* ── "on-" tokens ───────────────────────────────────────────────────
     Inverting the theme broke every filled button at once: --ink used to
     be the dark navy label on coral (5.6:1) and is now near-white, which
     drops to 2.5:1 on the same fill. Filled surfaces therefore carry
     their own label colour instead of borrowing --ink. Both are the dark
     end of their own hue, not black. */
  --on-accent:  #0B1563;   /* 5.6:1 on --accent — the logo's own pairing */
  --on-wa:      #04180C;   /* 8.0:1 on --wa */

  /* ── type ──────────────────────────────────────────────────────────── */
  --display: "Space Grotesk", "Segoe UI Variable Display", "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  --body: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI Variable Text", "Segoe UI", "Nirmala UI", "Noto Sans Bengali", Roboto, Helvetica, Arial, sans-serif;
  --bangla: "Nirmala UI", "Noto Sans Bengali", "SolaimanLipi", "Segoe UI", sans-serif;
  --mono: "Cascadia Mono", "SF Mono", Consolas, "Liberation Mono", ui-monospace, monospace;

  /* ── rhythm (density 5/10 — standard marketing spacing) ────────────── */
  --gutter: clamp(20px, 5vw, 56px);
  --maxw: 1180px;
  --r-sm: 8px; --r-md: 12px; --r-lg: 18px; --r-xl: 26px;

  /* ── dimensional layering ───────────────────────────────────────────
     Four elevation levels, as the style database specifies. Each is a
     tight contact shadow plus a wide ambient one — a single blurred
     shadow reads as a sticker, two read as an object above a surface.

     On a dark ground a drop shadow alone does almost nothing: dark-on-dark
     has nowhere to go. So every level here also carries a 1px inset rim of
     light along its top edge — the highlight a raised object catches. That
     rim, not the shadow, is what actually separates the layers now. */
  --e1: inset 0 1px 0 rgba(255,255,255,.05),
        0 1px 2px rgba(0,0,0,.4),  0 2px 6px -2px rgba(0,0,0,.5);
  --e2: inset 0 1px 0 rgba(255,255,255,.07),
        0 1px 2px rgba(0,0,0,.45), 0 8px 20px -8px rgba(0,0,0,.6);
  --e3: inset 0 1px 0 rgba(255,255,255,.09),
        0 2px 4px rgba(0,0,0,.5),  0 20px 44px -18px rgba(0,0,0,.7);
  --e4: inset 0 1px 0 rgba(255,255,255,.12),
        0 4px 8px rgba(0,0,0,.55), 0 40px 80px -32px rgba(0,0,0,.8);
  --shadow: var(--e2);   /* v1 alias, so carried-over rules still resolve */

  /* ── NEW: the z-axis ────────────────────────────────────────────────
     One perspective value per scale of object. Mixing arbitrary
     perspectives across a page is what makes CSS 3D look like clip art —
     these three are the only ones used. */
  --persp-near: 700px;    /* small objects: buttons, chips, flip cards */
  --persp-mid:  1200px;   /* cards, panels, the device */
  --persp-far:  2400px;   /* page-scale scenes: the product ring */
  --lift-1: 14px;
  --lift-2: 34px;
  --lift-3: 64px;

  /* ── NEW: glass — used only for panels that float OVER other content
     (the header, the ring's focused card). Never for body text panels:
     backdrop-filter behind long copy is a contrast risk the database
     flags, and this palette is too low-contrast to absorb it. */
  --glass-bg: color-mix(in srgb, var(--paper-2) 68%, transparent);
  --glass-brd: color-mix(in srgb, #FFFFFF 14%, transparent);
  --glass-blur: 18px;

  /* ── motion (tier 8/10 — "Complex": pin, scrub, spring, choreography) */
  --ease-out: cubic-bezier(.16, 1, .3, 1);
  --ease-elastic: cubic-bezier(.34, 1.56, .64, 1);
  --t-fast: .16s;
  --t-mid: .34s;
  --t-slow: .6s;
}

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-size: 16.5px;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;   /* 3D transforms can overhang; the page must never scroll sideways */
}

:where(a) { color: var(--accent-2); text-decoration-thickness: 1px; text-underline-offset: 3px; }
:where(h1,h2,h3,h4) { font-family: var(--display); font-weight: 600; text-wrap: balance; margin: 0; letter-spacing: -.012em; }
:where(p) { margin: 0; }
:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 3px; border-radius: 3px; }
img, svg { max-width: 100%; }
button { font: inherit; }

.bn { font-family: var(--bangla); }
.wrap { max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gutter); }
.overflow-x { overflow-x: auto; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ══════════════════════════════════════════════════════════════════════
   SHARED TYPE
   ══════════════════════════════════════════════════════════════════════ */
.eyebrow {
  font-family: var(--mono); font-size: 11px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink-3); display: flex; align-items: center; gap: 9px;
}
.eyebrow::before { content: ""; width: 14px; height: 1px; background: var(--margin-red); flex: none; }
h1.hero-h { font-size: clamp(40px, 7vw, 80px); line-height: 1.02; letter-spacing: -.032em; }
h2.sec-h  { font-size: clamp(27px, 3.8vw, 42px); line-height: 1.1; letter-spacing: -.024em; }
h3.sub-h  { font-size: 20px; line-height: 1.3; }
.lede { font-size: clamp(17px, 2vw, 20px); line-height: 1.55; color: var(--ink-2); max-width: 62ch; }
.prose { max-width: 66ch; color: var(--ink-2); }
.prose p + p { margin-top: 1.05em; }
.muted { color: var(--ink-3); }
.num { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.sec-head { display: flex; flex-direction: column; gap: 14px; margin-bottom: 38px; max-width: 70ch; }

.grad-text {
  color: var(--aurora-2);   /* never invisible if background-clip:text is unsupported */
  background: linear-gradient(100deg, var(--accent-2) 0%, var(--aurora-2) 100%);
  -webkit-background-clip: text; background-clip: text;
}
@supports (background-clip: text) or (-webkit-background-clip: text) {
  .grad-text { color: transparent; }
}

section.band { border-top: 1px solid var(--rule); padding-block: clamp(52px, 7.5vw, 96px); position: relative; z-index: 1; background: var(--paper); }
section.band.tight { padding-block: clamp(36px, 5vw, 62px); }
section.band.wash { background: var(--accent-wash); }

/* ══════════════════════════════════════════════════════════════════════
   HEADER — a floating glass slab, the only element on layer 3
   ══════════════════════════════════════════════════════════════════════ */
header.site {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  border-bottom: 1px solid var(--rule);
  transition: box-shadow var(--t-mid) var(--ease-out), background var(--t-mid);
}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  header.site { background: var(--glass-bg); backdrop-filter: blur(var(--glass-blur)) saturate(160%); -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(160%); }
}
/* the header only *earns* its elevation once there is content beneath it */
header.site.is-lifted { box-shadow: var(--e3); }

.nav { display: flex; align-items: center; gap: 10px; height: 66px; }
.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; color: var(--ink); margin-right: auto; }
.mark { width: 32px; height: 32px; flex: none; display: block; }
.mark img { width: 100%; height: 100%; object-fit: contain; display: block; }
.brand b { font-family: var(--display); font-weight: 600; font-size: 17.5px; letter-spacing: -.02em; }
.brand span { font-family: var(--mono); font-size: 10px; letter-spacing: .13em; text-transform: uppercase; color: var(--ink-3); display: block; margin-top: -3px; }
/* the mark tips toward the pointer — a 32px object on --persp-near */
.brand .mark { perspective: var(--persp-near); }
.brand .mark img { transition: transform var(--t-mid) var(--ease-out); }
.brand:hover .mark img { transform: rotateY(18deg) rotateX(-8deg) translateZ(4px); }

.nav-links { display: flex; gap: 2px; align-items: center; }
.nav-links a {
  font-size: 14px; color: var(--ink-2); text-decoration: none; padding: 7px 11px;
  border-radius: 6px; position: relative;
  display: inline-flex; align-items: center; min-height: 44px;
  transition: color var(--t-fast), background var(--t-fast);
}
.nav-links a:hover { color: var(--ink); background: var(--paper-3); }
.nav-links a[aria-current="page"] { color: var(--accent-2); background: var(--accent-wash); }

@media (max-width: 1180px) {
  .nav { height: auto; flex-wrap: wrap; padding-block: 10px 0; row-gap: 4px; }
  .nav-links {
    order: 3; width: 100%; overflow-x: auto; padding-bottom: 8px;
    scrollbar-width: none; -webkit-overflow-scrolling: touch;
  }
  .nav-links::-webkit-scrollbar { display: none; }
  .nav-links a { white-space: nowrap; padding: 6px 10px; font-size: 13.5px; }
}

/* scroll-depth meter — a real read of how far into the document you are */
.scroll-depth {
  position: absolute; left: 0; bottom: -1px; height: 2px; width: 100%;
  transform: scaleX(0); transform-origin: left;
  background: linear-gradient(90deg, var(--accent), var(--aurora));
}

/* ══════════════════════════════════════════════════════════════════════
   BUTTONS — pressable objects, not painted rectangles
   ══════════════════════════════════════════════════════════════════════ */
.btn {
  display: inline-flex; align-items: center; gap: 7px; justify-content: center;
  font-family: var(--body); font-size: 14.5px; font-weight: 500; line-height: 1;
  padding: 12px 18px; border-radius: var(--r-sm); border: 1px solid transparent;
  text-decoration: none; cursor: pointer; min-height: 44px; position: relative;
  transform-style: preserve-3d; will-change: transform;
  /* transform is excluded on purpose — the magnetic spring owns it per frame */
  transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast), box-shadow var(--t-fast);
}
/* --on-accent, not --ink: on the dark theme --ink is near-white, which
   drops to 2.5:1 on coral. The logo's own navy holds 5.6:1 on both. */
.btn-primary { background: var(--accent); color: var(--on-accent); box-shadow: var(--e2); }
.btn-primary:hover { background: var(--accent-2); color: var(--on-accent); box-shadow: var(--e3); }
.btn-ghost { border-color: var(--rule); color: var(--ink); background: var(--paper-2); box-shadow: var(--e1); }
.btn-ghost:hover { border-color: var(--ink-3); background: var(--paper-3); box-shadow: var(--e2); }
.btn-wa { background: var(--wa); color: var(--on-wa); box-shadow: var(--e2); }
.btn-wa:hover { box-shadow: var(--e3); }
.btn-sm { padding: 9px 14px; font-size: 13.5px; min-height: 40px; }
.btn:active { box-shadow: var(--e1); }
.cta-row { display: flex; gap: 10px; flex-wrap: wrap; }

/* ══════════════════════════════════════════════════════════════════════
   THE 3D PRIMITIVES
   Three classes carry every dimensional effect on the site. Everything
   else composes them, so there is one place to tune the whole z-axis.
   ══════════════════════════════════════════════════════════════════════ */

/* a scene: establishes perspective for its children */
.scene      { perspective: var(--persp-mid); perspective-origin: 50% 40%; }
.scene-near { perspective: var(--persp-near); }
.scene-far  { perspective: var(--persp-far); perspective-origin: 50% 50%; }

/* an object inside a scene: has real thickness for its children */
.obj {
  transform-style: preserve-3d;
  transition: transform var(--t-slow) var(--ease-out), box-shadow var(--t-slow) var(--ease-out);
}
.obj.is-live { transition: transform .1s linear; }   /* while the pointer drives it */

/* a layer floating above its parent's surface */
.z1 { transform: translateZ(var(--lift-1)); }
.z2 { transform: translateZ(var(--lift-2)); }
.z3 { transform: translateZ(var(--lift-3)); }

/* tier 0 flattens the entire z-axis in one rule */
html.t0 .scene, html.t0 .scene-near, html.t0 .scene-far { perspective: none; }
html.t0 .obj { transform: none !important; transform-style: flat; }
html.t0 .z1, html.t0 .z2, html.t0 .z3 { transform: none; }

/* ══════════════════════════════════════════════════════════════════════
   PANELS, GRIDS, CARDS
   ══════════════════════════════════════════════════════════════════════ */
.panel {
  background: var(--paper-2); border: 1px solid var(--rule); border-radius: var(--r-lg);
  box-shadow: var(--e2);
}

.grid { display: grid; gap: 18px; }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 960px) { .grid-3, .grid-4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) { .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; } }

.cell {
  background: var(--paper-2); border: 1px solid var(--rule); border-radius: var(--r-md);
  padding: 26px 24px; display: flex; flex-direction: column; gap: 10px;
  box-shadow: var(--e1);
  transition: box-shadow var(--t-mid) var(--ease-out), transform var(--t-mid) var(--ease-out), border-color var(--t-mid);
}
.cell h3 { font-size: 17.5px; font-family: var(--display); }
.cell p { font-size: 14.5px; color: var(--ink-2); line-height: 1.55; }
.cell .k { font-family: var(--mono); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-3); }
.cell a { padding-block: 4px; display: inline-block; }

/* hover lift — pointer devices only. Hover-only feedback on a touch
   device is dead weight, and this audience is mostly touch. */
@media (hover: hover) and (pointer: fine) {
  .cell:hover {
    transform: translateY(-4px);
    box-shadow: var(--e3);
    border-color: color-mix(in srgb, var(--accent) 40%, var(--rule));
  }
}

.chip {
  display: inline-flex; align-items: center; gap: 5px; font-family: var(--mono);
  font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  padding: 4px 9px; border-radius: 4px; border: 1px solid currentColor;
}
.chip-live { color: var(--wa); background: var(--wa-wash); border-color: color-mix(in srgb, var(--wa) 35%, transparent); }
.chip-soon { color: var(--ink-3); background: var(--paper-3); border-color: var(--rule); }
.chip-ink  { color: var(--accent-2); background: var(--accent-wash); border-color: color-mix(in srgb, var(--accent) 30%, transparent); }
.chip-wa   { color: var(--wa); background: var(--wa-wash); border-color: color-mix(in srgb, var(--wa) 35%, transparent); }

.feat-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 9px; }
.feat-list li { font-size: 14px; color: var(--ink-2); display: flex; gap: 9px; align-items: flex-start; line-height: 1.45; }
.feat-list li::before { content: "—"; color: var(--margin-red); font-family: var(--mono); flex: none; opacity: .7; }

/* ══════════════════════════════════════════════════════════════════════
   THE LEDGER — v2 gives it physical thickness.
   The ::after is the stack of sheets underneath the top one. It is the
   whole brand idea in four lines of CSS: a khata is not one page.
   ══════════════════════════════════════════════════════════════════════ */
.ledger {
  background: var(--paper-2); border: 1px solid var(--rule); border-radius: var(--r-md);
  box-shadow: var(--e3); position: relative;
}
.ledger::after {
  content: ""; position: absolute; inset: auto 10px -9px 10px; height: 9px;
  border: 1px solid var(--rule); border-top: 0; border-radius: 0 0 var(--r-md) var(--r-md);
  background: linear-gradient(var(--paper-2), var(--paper-3));
  z-index: -1;
}
.ledger-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 17px; border-bottom: 1px solid var(--rule); background: var(--paper-3);
  border-radius: var(--r-md) var(--r-md) 0 0;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3);
}
.ledger-row {
  display: grid; grid-template-columns: 1fr auto; gap: 14px; align-items: center;
  padding: 15px 17px; border-bottom: 1px solid var(--rule-soft);
}
.ledger-row:last-child { border-bottom: 0; }
.ledger-row .lr-label { font-size: 14.5px; font-weight: 500; }
.ledger-row .lr-sub { font-size: 12.5px; color: var(--ink-3); margin-top: 1px; }
.lr-val { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 14px; }

/* ══════════════════════════════════════════════════════════════════════
   HERO
   ══════════════════════════════════════════════════════════════════════ */
.hero { padding-block: clamp(60px, 8.5vw, 108px) clamp(44px, 5.5vw, 72px); position: relative; overflow: hidden; background: transparent; }
.hero::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: repeating-linear-gradient(to bottom, transparent 0 33px, var(--rule) 33px 34px);
  opacity: .38;
  mask-image: linear-gradient(to bottom, transparent, #000 22%, #000 62%, transparent);
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 22%, #000 62%, transparent);
}
/* the flat ruled texture would fight the WebGL grid — pull it back on t2 */
html.t2 .hero::before { opacity: .09; }
.hero > * { position: relative; }
.hero-grid { display: grid; grid-template-columns: 1.12fr .88fr; gap: clamp(32px, 5vw, 68px); align-items: center; }
@media (max-width: 960px) { .hero-grid { grid-template-columns: 1fr; } }
.hero-copy { display: flex; flex-direction: column; gap: 22px; align-items: flex-start; }

/* the hero ledger is the site's one hero-scale 3D object */
.hero-ledger { transform: rotateY(-13deg) rotateX(6deg); }
@media (max-width: 960px) { .hero-ledger { transform: none; } }

/* ══════════════════════════════════════════════════════════════════════
   THE SHOT HERO (home only)
   Structure adopted from the 21st "responsive hero banner": full-bleed
   photograph, glass pill nav, badge, centred two-line title, dual CTA,
   and a logo/credibility row. Rebuilt in this project's tokens rather
   than pasted — there is no React, Tailwind or shadcn here.
   ══════════════════════════════════════════════════════════════════════ */
.hero-shot {
  position: relative; isolation: isolate; overflow: hidden;
  padding-block: clamp(56px, 9vw, 116px) clamp(48px, 6vw, 84px);
}
.hero-shot__img {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%; object-fit: cover; object-position: center;
}
/* The scrim is not decoration — it is the contrast floor, and it is a ramp
   rather than a flat wash for a measured reason.

   Sampling ten candidate photographs gave a counter-intuitive result: the
   luminance range that survives the scrim is ~0.15 for every one of them.
   It has to be — the coverage needed to hold text over a photo's brightest
   patch scales with that patch, so the surviving range is pinned by the
   contrast floor and not by the image. Picking a "better" photo buys
   nothing.

   What does move is the photo's MEDIAN, which decides whether that surviving
   range carries content or just a few highlights on black. The first choice
   here (photo-1521737604893) had a median of 0.103 and composited to 0.030 —
   near-invisible against a 0.004 ground. This one has a median of 0.524 and
   composites to 0.097, which reads as a photograph. Same scrim discipline,
   three times the visible signal.

   So the page stops asking for both. The photo is allowed to read only where
   large, near-white text sits — the badge and the h1, measured at 8–33% of
   the hero — and the wash goes fully solid before the lede begins at 35%.
   Below that line the hero is ordinary --paper, so the lede, the buttons,
   the ledger and the muted logo row keep the same contrast they have on
   every other page.

   0.62 is measured, not chosen by eye, and the measurement had to be done
   the browser's way to be right. Estimating this by blending LUMINANCES
   predicted 0.82 was the minimum. That was wrong by a wide margin: the
   browser blends sRGB CHANNELS and only then applies the nonlinear
   luminance curve, and because that curve is convex the real composite
   lands far darker than a linear blend suggests. Compositing per-pixel the
   way the browser does, over the worst pixel in the visible band:

     alpha 0.55 → 4.33:1     0.70 → 7.23:1
     alpha 0.62 → ~5.5:1     0.82 → 10.98:1  (the over-scrimmed first pass)

   0.62 clears the 4.5:1 body floor over the single brightest pixel, never
   mind the 3:1 this 76px headline actually needs, and passes ~3x more of
   the photograph than 0.82 did. Lower it further only with a fresh
   per-pixel measurement of the new image — every photo has its own curve.
   Moving the 34% stop down is not safe either: it slides the lede, which
   is --ink-2 and has no such headroom, back over the photograph. */
.hero-shot__scrim {
  position: absolute; inset: 0; z-index: -1;
  background:
    /* edge vignette — keeps the band from ending in a hard rectangle */
    radial-gradient(ellipse 90% 60% at 50% 12%, transparent 0%, rgba(7,11,30,.38) 100%),
    linear-gradient(180deg,
      rgba(7,11,30,.62) 0%,
      rgba(7,11,30,.62) 26%,
      rgba(7,11,30,.92) 31%,
      rgba(7,11,30,1)   34%,
      rgba(7,11,30,1)   100%);
}
.hero-shot .wrap { position: relative; z-index: 1; }
.hero-shot__mid { max-width: 60ch; margin-inline: auto; text-align: center; display: flex; flex-direction: column; align-items: center; }

/* badge — the component's pill, in brand tokens */
.hero-badge {
  display: inline-flex; align-items: center; gap: 10px; margin-bottom: 24px;
  padding: 6px 14px 6px 6px; border-radius: 999px;
  background: var(--glass-bg); border: 1px solid var(--glass-brd);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  box-shadow: var(--e2);
}
.hero-badge b {
  font-family: var(--mono); font-size: 10px; font-weight: 500; letter-spacing: .1em; text-transform: uppercase;
  background: var(--accent); color: var(--on-accent); border-radius: 999px; padding: 4px 10px;
}
.hero-badge span { font-size: 13.5px; font-weight: 500; color: var(--ink); }

.hero-shot h1 { font-size: clamp(38px, 6.4vw, 76px); line-height: 1.03; letter-spacing: -.032em; }
.hero-shot .lede { margin-top: 22px; margin-inline: auto; }
.hero-shot .cta-row { margin-top: 34px; justify-content: center; }

/* secondary CTA — the component's borderless "watch" link */
.btn-quiet {
  background: transparent; border-color: transparent; color: var(--ink);
  box-shadow: none;
}
.btn-quiet:hover { background: var(--paper-3); border-color: var(--rule); box-shadow: none; }
.btn svg { width: 16px; height: 16px; flex: none; }

/* the credibility row. Jaantrix is pre-launch and has no clients, so this
   is the real platform capability list rather than invented partner logos
   — the one part of the source component that could not be carried over
   honestly. Same grid, same rhythm, truthful content. */
.hero-logos { margin-top: clamp(48px, 6vw, 78px); }
.hero-logos p { font-size: 13px; color: var(--ink-3); text-align: center; }
.hero-logos ul {
  list-style: none; margin: 20px 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 12px;
}
@media (max-width: 860px) { .hero-logos ul { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 520px) { .hero-logos ul { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.hero-logos li {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 46px; padding: 10px 12px; border-radius: 999px; text-align: center;
  background: var(--glass-bg); border: 1px solid var(--glass-brd);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-2);
}

/* the 3D product ledger floats beneath the centred copy */
.hero-shot .scene { margin-top: clamp(40px, 5vw, 62px); }
.hero-shot .hero-ledger { max-width: 520px; margin-inline: auto; }

/* nav as a glass pill — the component's treatment, applied to the site's
   one real nav rather than adding a second one beside it */
@media (min-width: 1181px) {
  .nav-links {
    gap: 2px; padding: 4px; border-radius: 999px;
    background: color-mix(in srgb, var(--paper-3) 70%, transparent);
    border: 1px solid var(--glass-brd);
    backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  }
  .nav-links a { border-radius: 999px; }
  header.site .btn-primary { border-radius: 999px; }
}

/* ══════════════════════════════════════════════════════════════════════
   WebGL STAGE (tier 2 only)
   ══════════════════════════════════════════════════════════════════════ */
#gl-stage {
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  opacity: 0; transition: opacity .9s var(--ease-out);
}
#gl-stage.ready { opacity: 1; }
#gl-stage canvas { display: block; width: 100%; height: 100%; position: relative; z-index: 1; }
#gl-stage::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  /* stronger than the light build: a 22% tint that read as a soft pool on
     white is almost invisible against #070B1E */
  background:
    radial-gradient(ellipse 55% 45% at 22% 20%, color-mix(in srgb, var(--accent) 34%, transparent) 0%, transparent 70%),
    radial-gradient(ellipse 50% 40% at 82% 12%, color-mix(in srgb, var(--aurora) 30%, transparent) 0%, transparent 70%);
}
#gl-stage::after {
  content: ""; position: absolute; inset: 0; z-index: 2;
  background: linear-gradient(to bottom, var(--paper) 0%, transparent 17%, transparent 70%, var(--paper) 97%);
}
footer.site { position: relative; z-index: 1; }

/* ══════════════════════════════════════════════════════════════════════
   TRUST STRIP
   ══════════════════════════════════════════════════════════════════════ */
.trust-strip { border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); background: var(--paper-2); position: relative; z-index: 1; box-shadow: var(--e1); }
.trust-strip-inner { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; padding-block: 17px; justify-content: space-between; }
.trust-strip-label { font-family: var(--mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); white-space: nowrap; }
.trust-strip-items { display: flex; gap: 22px; flex-wrap: wrap; }
.trust-item { font-size: 13.5px; color: var(--ink-2); font-weight: 500; white-space: nowrap; display: flex; align-items: center; gap: 8px; }
.trust-item::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: var(--wa); flex: none; }

/* ══════════════════════════════════════════════════════════════════════
   FUNCTIONAL 3D #1 — THE PRODUCT RING
   A carousel on a real cylinder. It is the product navigation on the home
   page: drag it, arrow-key it, tab to a card and press Enter to open that
   product. On t0 it collapses to a plain responsive grid — same cards,
   same links, no rotation.
   ══════════════════════════════════════════════════════════════════════ */
.ring-sec { position: relative; overflow: hidden; }
.ring-stage {
  position: relative; height: 460px; margin-top: 28px;
  perspective: var(--persp-far); perspective-origin: 50% 45%;
  touch-action: pan-y;   /* horizontal drag is ours, vertical scroll stays the page's */
  cursor: grab;
}
.ring-stage.is-drag { cursor: grabbing; }
.ring {
  position: absolute; inset: 0; transform-style: preserve-3d;
  transition: transform .75s var(--ease-out);
}
.ring.is-live { transition: none; }
.ring-card {
  position: absolute; top: 0; left: 50%; width: 320px; margin-left: -160px;
  background: var(--paper-2); border: 1px solid var(--rule); border-radius: var(--r-lg);
  padding: 26px 24px; display: flex; flex-direction: column; gap: 12px; align-items: flex-start;
  box-shadow: var(--e2); backface-visibility: hidden;
  transition: box-shadow var(--t-slow) var(--ease-out), border-color var(--t-slow), opacity var(--t-slow);
  min-height: 400px;
}
.ring-card h3 { font-family: var(--display); font-size: 22px; letter-spacing: -.02em; }
.ring-card p { font-size: 14px; color: var(--ink-2); line-height: 1.55; }
.ring-card .rc-for { font-size: 12.5px; color: var(--ink-3); margin-top: auto; }
/* dim the cards facing away — a class, not aria-hidden: they stay real,
   focusable links in the accessibility tree, and tabbing to one rotates it
   to the front. Hiding them from assistive tech would make four of the five
   products unreachable without a mouse. */
.ring-card:not(.is-front) { opacity: .58; }
.ring-card.is-front {
  box-shadow: var(--e4);
  border-color: color-mix(in srgb, var(--accent) 55%, var(--rule));
  opacity: 1;
}
.ring-card .rc-mark {
  width: 46px; height: 46px; border-radius: 12px; display: grid; place-items: center;
  font-family: var(--display); font-weight: 700; font-size: 16px; color: var(--ink);
  background: linear-gradient(140deg, color-mix(in srgb, var(--rc-a) 34%, var(--paper-3)), color-mix(in srgb, var(--rc-b) 24%, var(--paper-3)));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.16), var(--e1);
}
.ring-ctrls { display: flex; gap: 8px; justify-content: center; align-items: center; margin-top: 24px; flex-wrap: wrap; }
.ring-ctrls .rdot {
  min-height: 40px; min-width: 46px; padding: 6px 11px; border-radius: 7px; cursor: pointer;
  font-family: var(--mono); font-size: 11px; letter-spacing: .1em; color: var(--ink-3);
  background: var(--paper-2); border: 1px solid var(--rule);
  transition: color var(--t-fast), border-color var(--t-fast), background var(--t-fast), box-shadow var(--t-fast);
}
.ring-ctrls .rdot:hover { color: var(--ink); border-color: var(--ink-3); }
.ring-ctrls .rdot[aria-selected="true"] { color: var(--accent-2); border-color: var(--accent); background: var(--accent-wash); box-shadow: var(--e1); }
.ring-hint { font-family: var(--mono); font-size: 11px; letter-spacing: .08em; color: var(--ink-3); text-transform: uppercase; text-align: center; margin-top: 14px; }

/* t0 / narrow: the ring becomes a grid. Cards keep every attribute. */
@media (max-width: 720px) {
  .ring-stage { height: auto; perspective: none; cursor: auto; }
  .ring { position: static; transform: none !important; display: grid; gap: 16px; }
  .ring-card { position: static; width: auto; margin: 0; min-height: 0; opacity: 1 !important; }
  .ring-ctrls, .ring-hint { display: none; }
}
html.t0 .ring-stage { height: auto; perspective: none; cursor: auto; }
html.t0 .ring { position: static; transform: none !important; display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
html.t0 .ring-card { position: static; width: auto; margin: 0; min-height: 0; opacity: 1 !important; }
html.t0 .ring-ctrls, html.t0 .ring-hint { display: none; }

/* ══════════════════════════════════════════════════════════════════════
   FUNCTIONAL 3D #2 — THE DEVICE
   A phone with actual thickness: front face, four rim faces, and a back.
   It rotates to face you as the walkthrough advances, so the rotation
   carries the step change rather than decorating it.
   ══════════════════════════════════════════════════════════════════════ */
.device-scene { perspective: var(--persp-mid); perspective-origin: 50% 45%; display: flex; justify-content: center; }
.device {
  width: 300px; max-width: 100%; position: relative; transform-style: preserve-3d;
  transform: rotateY(-16deg) rotateX(5deg);
  transition: transform var(--t-slow) var(--ease-out);
}
.device.is-live { transition: transform .1s linear; }
.device-face {
  background: var(--paper-2); border: 1px solid var(--rule); border-radius: 26px;
  overflow: hidden; box-shadow: var(--e4); position: relative; z-index: 2;
}
/* the rim: a slab pushed back on Z, wider than the face, reading as edge */
.device-rim {
  position: absolute; inset: 3px -3px -3px 3px; border-radius: 26px;
  background: linear-gradient(150deg, var(--paper-4), var(--rule));
  transform: translateZ(-14px); z-index: 1;
}
.ph-bar { background: var(--accent); color: var(--on-accent); padding: 15px 17px 17px; }
.ph-bar .t { font-size: 11px; opacity: .85; font-family: var(--mono); letter-spacing: .1em; text-transform: uppercase; }
.ph-bar .n { font-family: var(--bangla); font-size: 15px; font-weight: 600; margin-top: 3px; }
.ph-card { margin: -9px 13px 0; background: var(--paper-2); border: 1px solid var(--rule); border-radius: 11px; padding: 14px 15px; box-shadow: var(--e2); position: relative; }
.ph-card .lab { font-family: var(--bangla); font-size: 11.5px; color: var(--ink-3); }
.ph-card .amt { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 25px; letter-spacing: -.02em; margin-top: 2px; }
.ph-split { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 11px; padding-top: 11px; border-top: 1px solid var(--rule-soft); }
.ph-split div .s { font-family: var(--bangla); font-size: 10.5px; color: var(--ink-3); }
.ph-split div .v { font-family: var(--mono); font-size: 14px; font-variant-numeric: tabular-nums; }
.ph-list { padding: 15px 15px 17px; display: flex; flex-direction: column; }
.ph-list .r { display: flex; justify-content: space-between; align-items: center; padding: 9px 2px; border-bottom: 1px solid var(--rule-soft); gap: 10px; }
.ph-list .r:last-child { border-bottom: 0; }
.ph-list .r .nm { font-family: var(--bangla); font-size: 12.5px; }
.ph-list .r .vv { font-family: var(--mono); font-size: 12.5px; font-variant-numeric: tabular-nums; }
.pos { color: var(--wa); } .neg { color: var(--margin-red); }
.ph-off {
  margin: 0 13px 13px; background: var(--paper-3); border: 1px dashed var(--rule); border-radius: 7px;
  padding: 9px 11px; font-family: var(--mono); font-size: 10px; letter-spacing: .06em; color: var(--ink-2);
  display: flex; align-items: center; gap: 7px;
}
.dot { width: 6px; height: 6px; border-radius: 50%; background: var(--margin-red); flex: none; }

/* ══════════════════════════════════════════════════════════════════════
   FUNCTIONAL 3D #3 — THE FLIP CARD
   Front: what the product is. Back: the actual spec list. The flip is the
   disclosure mechanism, so it must be reachable by keyboard and it must
   toggle on click, not on hover (hover-only would hide content on touch).
   ══════════════════════════════════════════════════════════════════════ */
.flip { perspective: var(--persp-mid); }
.flip-inner {
  position: relative; transform-style: preserve-3d;
  transition: transform .68s var(--ease-out);
  min-height: 340px;
}
.flip.is-flipped .flip-inner { transform: rotateY(180deg); }
.flip-face {
  border: 1px solid var(--rule); border-radius: var(--r-md); background: var(--paper-2);
  padding: 26px 24px; display: flex; flex-direction: column; gap: 12px; align-items: flex-start;
  box-shadow: var(--e1); backface-visibility: hidden; -webkit-backface-visibility: hidden;
}
.flip-front { position: relative; min-height: 340px; }
.flip-back {
  position: absolute; inset: 0; transform: rotateY(180deg);
  background: var(--paper-2); overflow: auto;
}
.flip-back h4 { font-family: var(--mono); font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3); font-weight: 400; }
.flip-toggle {
  margin-top: auto; align-self: flex-start; cursor: pointer;
  background: transparent; border: 1px solid var(--rule); border-radius: 7px;
  padding: 9px 13px; min-height: 40px; font-size: 13px; color: var(--ink);
  display: inline-flex; align-items: center; gap: 7px;
  transition: border-color var(--t-fast), background var(--t-fast), color var(--t-fast);
}
.flip-toggle:hover { border-color: var(--accent); background: var(--accent-wash); color: var(--accent-2); }
.flip-toggle::after { content: "↻"; font-family: var(--mono); }
/* t0: no rotation — the back simply appears below the front */
html.t0 .flip-inner { transform: none !important; min-height: 0; }
html.t0 .flip-front { min-height: 0; }
html.t0 .flip-back { position: static; transform: none; margin-top: 14px; display: none; }
html.t0 .flip.is-flipped .flip-back { display: flex; }

/* ══════════════════════════════════════════════════════════════════════
   FUNCTIONAL 3D #4 — THE STAT DRUMS
   Odometer cylinders. Each digit is a physical wheel that rolls to its
   value — the rotation IS the count-up, not an effect layered over it.
   ══════════════════════════════════════════════════════════════════════ */
.stat { display: flex; flex-direction: column; gap: 6px; }
.stat .l { font-family: var(--mono); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-3); }
.odo { display: flex; align-items: baseline; gap: 1px; font-family: var(--display); font-size: clamp(30px, 4vw, 44px); line-height: 1; letter-spacing: -.03em; color: var(--ink); }
.odo-digit {
  display: inline-block; width: .62em; height: 1.06em; overflow: hidden;
  perspective: 240px; position: relative;
}
.odo-reel {
  display: block; transform-style: preserve-3d;
  transition: transform 1.15s var(--ease-out);
  will-change: transform;
}
.odo-reel span { display: block; height: 1.06em; line-height: 1.06em; text-align: center; font-variant-numeric: tabular-nums; }
/* the curvature: the digit entering and leaving the window fades into the
   body of the drum, which is what separates a rolling cylinder from a list
   sliding behind a slot */
.odo-digit::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(var(--paper-2) 0%, transparent 26%, transparent 74%, var(--paper-2) 100%);
}
.odo-suffix { font-variant-numeric: tabular-nums; }
html.t0 .odo-reel { transition: none; }

/* ══════════════════════════════════════════════════════════════════════
   FUNCTIONAL 3D #5 — THE COD COST TOWER
   The calculator's output rendered as extruded 3D bars. Every face is
   driven by the same numbers as the ledger table beside it, so the chart
   is a second reading of real data, never a decoration. The table stays
   the accessible source of truth; the tower is aria-hidden.
   ══════════════════════════════════════════════════════════════════════ */
.tower-wrap {
  border: 1px solid var(--rule); border-radius: var(--r-md); background: var(--paper-2);
  padding: 22px 20px 18px; box-shadow: var(--e2);
}
.tower-head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 6px; }
.tower-head .th-t { font-family: var(--mono); font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3); }
.tower-stage {
  height: 250px; perspective: var(--persp-mid); perspective-origin: 50% 30%;
  display: flex; align-items: flex-end; justify-content: center; gap: clamp(26px, 7vw, 62px);
  padding-bottom: 30px; position: relative;
}
/* the ceiling marks 100% of the scale — the headroom above a bar is the
   distance to total loss, so it has to be labelled or it reads as padding.
   Sits at (stage height − padding − TOWER_MAX) = 250 − 30 − 190. */
.tower-ceiling {
  position: absolute; left: 8px; right: 8px; top: 30px;
  border-top: 1px dashed color-mix(in srgb, var(--margin-red) 45%, transparent);
  pointer-events: none;
}
.tower-ceiling span {
  position: absolute; right: 0; top: -16px;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--margin-red);
}
.tower-col { transform-style: preserve-3d; transform: rotateX(12deg) rotateY(-22deg); display: flex; flex-direction: column-reverse; align-items: center; position: relative; }
.tower-seg {
  width: 62px; position: relative; transform-style: preserve-3d;
  transition: height .55s var(--ease-out);
  background: var(--seg);
  border-top: 1px solid rgba(255,255,255,.22);
}
/* right face and top face — what makes it a solid, not a rectangle */
.tower-seg::before {
  content: ""; position: absolute; top: 0; right: 0; width: 20px; height: 100%;
  background: color-mix(in srgb, var(--seg) 68%, #000000);
  transform-origin: left; transform: rotateY(-90deg) translateX(0);
  right: -20px;
}
.tower-seg::after {
  content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 20px;
  background: color-mix(in srgb, var(--seg) 82%, #FFFFFF);
  transform-origin: bottom; transform: rotateX(90deg);
  top: -20px;
}
.tower-seg:not(:last-child)::after { display: none; }   /* only the top segment gets a lid */
.tower-label {
  position: absolute; bottom: -30px; left: 50%; transform: translateX(-50%);
  font-family: var(--mono); font-size: 10px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-3); white-space: nowrap; text-align: center;
}
.tower-total {
  position: absolute; top: -28px; left: 50%; transform: translateX(-50%);
  font-family: var(--mono); font-size: 13px; font-variant-numeric: tabular-nums; color: var(--ink);
  white-space: nowrap; font-weight: 500;
}
.tower-key { display: flex; gap: 16px; flex-wrap: wrap; justify-content: center; margin-top: 10px; }
.tower-key span { font-size: 12px; color: var(--ink-2); display: inline-flex; align-items: center; gap: 6px; }
.tower-key i { width: 10px; height: 10px; border-radius: 2px; display: inline-block; }
html.t0 .tower-col { transform: none; }
html.t0 .tower-seg::before, html.t0 .tower-seg::after { display: none; }

/* ══════════════════════════════════════════════════════════════════════
   FUNCTIONAL 3D #6 — THE CAPABILITY CYLINDER
   The marquee, wrapped onto a rotating drum. Purely a band of context, so
   it is aria-hidden and pauses on hover like the v1 marquee did.
   ══════════════════════════════════════════════════════════════════════ */
.cyl-band { border-block: 1px solid var(--rule); background: var(--paper-2); position: relative; z-index: 1; overflow: hidden; }
.marquee__row { display: flex; overflow: hidden; padding-block: 14px; }
.marquee__row + .marquee__row { border-top: 1px solid var(--rule-soft); }
.marquee__track {
  display: flex; flex: none; gap: 30px; padding-right: 30px; white-space: nowrap;
  font-family: var(--mono); font-size: 12px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-3);
  animation: slide-l 42s linear infinite;
}
.marquee__row--rev .marquee__track { animation: slide-r 52s linear infinite; }
.marquee__track span { display: inline-flex; align-items: center; gap: 30px; }
.marquee__track span::after { content: "+"; color: var(--margin-red); opacity: .7; }
.cyl-band:hover .marquee__track { animation-play-state: paused; }
@keyframes slide-l { to { transform: translateX(-50%); } }
@keyframes slide-r { from { transform: translateX(-50%); } to { transform: none; } }
/* the cylinder curvature: two shaded edges, so the band reads as a drum */
html:not(.t0) .cyl-band::before,
html:not(.t0) .cyl-band::after {
  content: ""; position: absolute; inset-block: 0; width: 90px; pointer-events: none; z-index: 2;
}
html:not(.t0) .cyl-band::before { left: 0; background: linear-gradient(90deg, var(--paper-3), transparent); }
html:not(.t0) .cyl-band::after { right: 0; background: linear-gradient(270deg, var(--paper-3), transparent); }

/* ══════════════════════════════════════════════════════════════════════
   PINNED / SCROLL-SCRUBBED WALKTHROUGH
   ══════════════════════════════════════════════════════════════════════ */
.steps-pin { position: relative; background: var(--paper); z-index: 1; height: 320vh; border-top: 1px solid var(--rule); }
@media (max-width: 900px) { .steps-pin { height: 260vh; } }
.steps-sticky {
  position: sticky; top: 66px; min-height: calc(100vh - 66px);
  display: flex; flex-direction: column; justify-content: center;
  padding-block: clamp(28px, 5vh, 56px); overflow: hidden;
}
.steps-body { display: grid; grid-template-columns: 32px 1fr 320px; gap: clamp(20px, 3.5vw, 48px); align-items: center; }
@media (max-width: 940px) { .steps-body { grid-template-columns: 28px 1fr; } .steps-visual { display: none; } }

.steps-rail { position: relative; width: 3px; background: var(--rule); border-radius: 3px; height: 200px; justify-self: center; }
.steps-rail-fill {
  /* always 100% tall and revealed via scaleY — animating height would
     re-render the gradient against a shrinking box every frame and always
     show the full accent→aurora range regardless of progress */
  position: absolute; inset-inline: 0; top: 0; height: 100%; border-radius: 3px;
  background: linear-gradient(to bottom, var(--accent), var(--aurora));
  transform: scaleY(0); transform-origin: top; transition: transform .45s var(--ease-out);
}
.steps-rail-dot {
  position: absolute; left: 50%; width: 11px; height: 11px; border-radius: 50%;
  background: var(--aurora); transform: translate(-50%, -50%); top: 0;
  box-shadow: 0 0 0 5px var(--aurora-wash), var(--e1); transition: top .45s var(--ease-out);
}

.steps-stack { position: relative; min-height: 300px; }
.step-panel {
  position: absolute; inset: 0; display: flex; flex-direction: column; gap: 12px; align-items: flex-start;
  opacity: 0; transform: translateY(18px) rotateX(6deg); transform-origin: 50% 0;
  pointer-events: none;
  transition: opacity .5s var(--ease-out), transform .5s var(--ease-out);
}
.step-panel.is-on { opacity: 1; transform: none; pointer-events: auto; }
.step-count { font-family: var(--mono); font-size: 12px; letter-spacing: .14em; color: var(--ink-3); }
.step-count b { color: var(--accent-2); font-weight: 500; font-size: 22px; letter-spacing: -.02em; }
.step-panel h3 { font-size: clamp(24px, 3.4vw, 36px); line-height: 1.14; letter-spacing: -.022em; }
.step-panel p { font-size: 16px; color: var(--ink-2); max-width: 46ch; }

/* in normal flow, not absolutely positioned — an absolute dot row overlapped
   panel content on narrow viewports whenever the copy wrapped past the
   stack's min-height (a real bug found in v1) */
.steps-dots { display: flex; gap: 8px; justify-content: center; margin-top: 26px; }
.steps-dots button {
  font-family: var(--mono); font-size: 11px; letter-spacing: .1em; color: var(--ink-3);
  background: var(--paper-2); border: 1px solid var(--rule); border-radius: 7px;
  padding: 6px 11px; cursor: pointer; min-height: 40px; min-width: 46px;
  transition: color var(--t-fast), border-color var(--t-fast), background var(--t-fast), box-shadow var(--t-fast);
}
.steps-dots button:hover { color: var(--ink); border-color: var(--ink-3); }
.steps-dots button.is-active { color: var(--accent-2); border-color: var(--accent); background: var(--accent-wash); box-shadow: var(--e1); }
.steps-visual { justify-self: center; }
.step-screen { display: none; }
.step-screen.is-on { display: block; animation: pop .5s var(--ease-out); }
@keyframes pop { from { opacity: 0; transform: translateY(10px) scale(.985); } to { opacity: 1; transform: none; } }

/* ══════════════════════════════════════════════════════════════════════
   PRODUCTS / PRICING / FAQ / BLOG / FORM / FOOTER
   ══════════════════════════════════════════════════════════════════════ */
.prod-orb-wrap { display: flex; flex-direction: column; align-items: center; gap: 16px; }
.prod-orb {
  width: 190px; height: 190px; border-radius: 50%; display: grid; place-items: center;
  position: relative; transform-style: preserve-3d;
  background: var(--paper-2);
  background-image:
    radial-gradient(circle at 32% 26%, color-mix(in srgb, var(--orb-a) 72%, transparent) 0%, transparent 62%),
    radial-gradient(circle at 70% 76%, color-mix(in srgb, var(--orb-b) 52%, transparent) 0%, transparent 60%);
  box-shadow:
    inset -14px -18px 40px -18px rgba(0,0,0,.75),
    inset 12px 14px 30px -14px rgba(255,255,255,.20),
    0 0 70px -16px color-mix(in srgb, var(--orb-a) 60%, transparent),
    var(--e3);
}
.prod-orb-mark { font-family: var(--display); font-weight: 700; font-size: 40px; letter-spacing: -.02em; color: var(--ink); transform: translateZ(24px); }
.prod-orb-name { font-family: var(--display); font-weight: 600; font-size: 16.5px; color: var(--ink); }

.price-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; align-items: start; perspective: var(--persp-mid); }
@media (max-width: 860px) { .price-grid { grid-template-columns: 1fr; } }
.tier {
  background: var(--paper-2); border: 1px solid var(--rule); border-radius: var(--r-lg);
  padding: 30px 26px; display: flex; flex-direction: column; gap: 16px; box-shadow: var(--e1);
  transition: transform var(--t-mid) var(--ease-out), box-shadow var(--t-mid) var(--ease-out);
}
/* the recommended tier is literally closer to you */
.tier.feature {
  background: var(--accent-wash);
  border-color: color-mix(in srgb, var(--accent) 45%, var(--rule));
  box-shadow: var(--e4);
  transform: translateZ(40px) scale(1.02);
}
@media (max-width: 860px) { .tier.feature { transform: none; } }
html.t0 .tier.feature { transform: none; }
.tier .tn { font-family: var(--mono); font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3); }
.tier .tp { font-family: var(--display); font-size: 38px; letter-spacing: -.03em; font-variant-numeric: tabular-nums; display: flex; align-items: baseline; gap: 5px; }
.tier .tp small { font-family: var(--body); font-size: 13px; color: var(--ink-3); font-weight: 400; letter-spacing: 0; }

.calc-grid { display: grid; grid-template-columns: 1.02fr .98fr; gap: clamp(24px, 4vw, 48px); align-items: start; }
@media (max-width: 940px) { .calc-grid { grid-template-columns: 1fr; } }
.calc-inputs { display: flex; flex-direction: column; gap: 16px; }
.calc-inputs-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.calc-reset {
  font-family: var(--mono); font-size: 11px; letter-spacing: .07em; text-transform: uppercase;
  color: var(--accent-2); background: var(--accent-wash); border: 1px solid color-mix(in srgb, var(--accent) 32%, transparent);
  border-radius: 7px; padding: 8px 12px; cursor: pointer; min-height: 40px;
}
.calc-reset:hover { background: color-mix(in srgb, var(--accent) 16%, var(--accent-wash)); }
.calc-field-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px 16px; }
@media (max-width: 560px) { .calc-field-grid { grid-template-columns: 1fr; } }
.calc-results { display: flex; flex-direction: column; gap: 18px; }
.calc-savings { gap: 8px; }
.calc-savings .tp { font-size: 28px; }

.faq { border-top: 1px solid var(--rule); }
.faq details { border-bottom: 1px solid var(--rule); }
.faq summary {
  padding: 18px 2px; cursor: pointer; font-family: var(--display); font-size: 18px;
  display: flex; justify-content: space-between; gap: 16px; align-items: center; list-style: none;
  min-height: 48px;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; font-family: var(--mono); color: var(--accent-2); font-size: 20px; flex: none; }
.faq details[open] summary::after { content: "–"; }
.faq .fa { padding: 0 2px 20px; color: var(--ink-2); font-size: 15px; max-width: 72ch; }

.post-list { border-top: 1px solid var(--rule); }
.post-item {
  display: grid; grid-template-columns: 120px 1fr auto; gap: 24px; align-items: baseline;
  padding: 24px 14px; border-bottom: 1px solid var(--rule); text-decoration: none; color: inherit;
  border-radius: var(--r-sm);
  transition: background var(--t-fast), transform var(--t-fast) var(--ease-out), box-shadow var(--t-fast);
}
.post-item:hover { background: var(--paper-2); transform: translateX(6px); box-shadow: var(--e1); }
.post-item:hover .pt { color: var(--accent-2); }
@media (max-width: 760px) { .post-item { grid-template-columns: 1fr; gap: 8px; } }
.post-item .pd { font-family: var(--mono); font-size: 11.5px; color: var(--ink-3); letter-spacing: .06em; }
.pt { font-family: var(--display); font-size: 21px; line-height: 1.25; letter-spacing: -.018em; }
.post-item .px { font-size: 14px; color: var(--ink-3); margin-top: 5px; max-width: 68ch; display: block; }
.post-item .pk { font-family: var(--mono); font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); white-space: nowrap; }

.article { max-width: 68ch; }
.article h2 { font-size: 26px; margin-top: 1.8em; margin-bottom: .5em; }
.article h3 { font-size: 20px; margin-top: 1.5em; margin-bottom: .4em; }
.article p { margin-bottom: 1.05em; color: var(--ink-2); }
.article ul { color: var(--ink-2); padding-left: 1.2em; margin-bottom: 1.05em; }
.article li { margin-bottom: .4em; }
.article a { padding-block: 4px; display: inline-block; }
.article blockquote {
  margin: 1.6em 0; padding: 4px 0 4px 20px; border-left: 3px solid var(--margin-red);
  font-family: var(--display); font-size: 19px; line-height: 1.45; color: var(--ink);
}

.form { display: flex; flex-direction: column; gap: 15px; max-width: 520px; }
.field { display: flex; flex-direction: column; gap: 6px; }
.field label { font-family: var(--mono); font-size: 10.5px; letter-spacing: .13em; text-transform: uppercase; color: var(--ink-3); }
.field input, .field textarea, .field select {
  font-family: var(--body); font-size: 15px; color: var(--ink); background: var(--paper-2);
  border: 1px solid var(--rule); border-radius: 8px; padding: 12px 13px; width: 100%;
  min-height: 44px;
  box-shadow: inset 0 1px 3px rgba(0,0,0,.45);
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.field textarea { min-height: 110px; resize: vertical; }
.field input:focus, .field textarea:focus, .field select:focus {
  outline: 2px solid var(--accent-2); outline-offset: 1px; border-color: transparent;
}

footer.site { border-top: 1px solid var(--rule); background: var(--paper-2); }
.foot { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 32px; padding-block: 52px 30px; }
@media (max-width: 800px) { .foot { grid-template-columns: 1fr 1fr; } }
.foot h4 { font-family: var(--mono); font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3); font-weight: 400; margin-bottom: 12px; }
.foot ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; }
.foot a { font-size: 14px; color: var(--ink-2); text-decoration: none; display: inline-block; padding-block: 6px; }
.foot a:hover { color: var(--accent-2); }
.foot-bottom {
  border-top: 1px solid var(--rule); padding-block: 18px; display: flex; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; font-family: var(--mono); font-size: 11px; color: var(--ink-3); letter-spacing: .04em;
}

.skip-link {
  position: absolute; left: 8px; top: -60px; z-index: 100;
  background: var(--accent-2); color: var(--on-accent); padding: 11px 16px; border-radius: 7px;
  font-size: 14px; text-decoration: none; transition: top .18s;
}
.skip-link:focus { top: 8px; }

/* ══════════════════════════════════════════════════════════════════════
   REVEALS
   Every "starts hidden" rule is scoped to html.motion, which the motion
   script sets on itself. With JS off the page is plain HTML at full
   opacity, not a blank screen.
   ══════════════════════════════════════════════════════════════════════ */
.page { position: relative; z-index: 1; background: transparent; }

/* Opacity-only: a translateY/translateZ offset here was moving each
   element's rendered box after first paint, which the Layout Instability
   API counts as a shift regardless of whether the move is "just" a
   transform. That was the site's entire measured CLS (0.78) — every
   above-the-fold reveal firing within a frame or two of load. Fading in
   place keeps the reveal without moving any box. */
html.motion [data-reveal] {
  opacity: 0;
  transition: opacity .5s var(--ease-out);
  transition-delay: var(--d, 0ms);
}
html.motion [data-reveal].is-in { opacity: 1; }

.words { display: block; }
.word-mask { display: inline-block; overflow: hidden; vertical-align: bottom; padding-bottom: .06em; }
html.motion .word-mask > span {
  display: inline-block; opacity: 0;
  transition: opacity .6s var(--ease-out); transition-delay: var(--d, 0ms);
}
html.motion .is-lit .word-mask > span { opacity: 1; }

/* cursor halo — desktop pointers only. No second dot and no `cursor:none`;
   hiding the system pointer is a real usability cost for a decorative gain. */
#cur-ring {
  position: fixed; top: 0; left: 0; z-index: 90; pointer-events: none; border-radius: 50%;
  width: 32px; height: 32px; border: 1px solid var(--accent); opacity: 0;
  transition: width .25s var(--ease-out), height .25s var(--ease-out), opacity .3s, background .25s;
}
html.cursor-on #cur-ring { opacity: .55; }
html.cursor-on.cur-lg #cur-ring { width: 54px; height: 54px; background: var(--accent-wash); opacity: .8; }
@media (hover: none), (pointer: coarse) { #cur-ring { display: none; } }

@keyframes breathe { 0%, 100% { opacity: .55; transform: scale(1); } 50% { opacity: 1; transform: scale(1.12); } }
.dot { animation: breathe 2.4s ease-in-out infinite; }

/* ══════════════════════════════════════════════════════════════════════
   REDUCED MOTION — the tier-0 contract, enforced in CSS as well as JS
   ══════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
  [data-reveal] { opacity: 1 !important; transform: none !important; }
  .word-mask > span { transform: none !important; }
  #gl-stage { opacity: .45 !important; }
  .ring, .device, .tower-col, .flip-inner, .obj { transform: none !important; }
}
