/* Rhodex landing v3 — 2026-08-11. Same palette, more swing.
 *
 * Everything here is chosen to be loud on a big screen and cheap on a
 * phone. The rules that kept it honest:
 *   - animate transform and opacity only, never width/top/filter, so the
 *     compositor does the work and the main thread stays free
 *   - backdrop-filter on small elements only; a full-screen blur is what
 *     makes a mid-range Android stutter
 *   - the pointer spotlight and card tilt are desktop-only, gated behind
 *     (hover: hover) — a touch device pays nothing for them
 *   - all of it off under prefers-reduced-motion
 */

:root {
  --ink: #111111;
  --paper: #ffffff;
  --paper-warm: #faf8f2;
  --charcoal: #1b1b19;
  --signal: #f2b705;
  --signal-deep: #a9760a;
  --slate: #5a5a55;
  --line: #e4e1d6;
  --max: 1180px;
  --night: #0b0b0a;
  --night-2: #151513;
  --glass: rgba(255, 255, 255, 0.05);
  --glass-line: rgba(255, 255, 255, 0.1);
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

* { box-sizing: border-box; }

body.v3 {
  margin: 0; background: var(--paper); color: var(--ink);
  font-family: "Inter", -apple-system, BlinkMacSystemFont, Arial, sans-serif;
  -webkit-font-smoothing: antialiased; overflow-x: hidden;
}
.v3 .wrap { width: min(100% - 40px, var(--max)); margin-inline: auto; }
.v3 h1, .v3 h2, .v3 h3 { font-family: "Archivo Black", Impact, sans-serif; font-weight: 400; }
.v3 .mono { font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; }

/* Testing-period banner (testing-banner.js) — same rule as site-v3.css's.
   index.html loads this file, not site-v3.css, so the rule has to exist
   here too or the banner renders with no styling at all (the bug this
   fixes: browser-default white background, black text, no padding). */
#testing-banner {
  background: var(--signal); color: var(--night);
  font-size: 13.5px; font-weight: 600; line-height: 1.5;
  text-align: center; padding: 10px 20px;
}
#testing-banner a { color: var(--night); text-decoration: underline; font-weight: 700; white-space: nowrap; }
#testing-banner a:hover { text-decoration: none; }

/* ---------- scroll progress: a gold rule that fills as you read ---------- */
.v3 .progress {
  position: fixed; top: 0; left: 0; height: 3px; width: 100%; z-index: 90;
  background: var(--signal); transform: scaleX(0); transform-origin: 0 50%;
}

/* ---------- header ---------- */
.v3 .nav {
  position: sticky; top: 0; z-index: 80;
  background: rgba(11, 11, 10, 0.7);
  backdrop-filter: saturate(160%) blur(12px); -webkit-backdrop-filter: saturate(160%) blur(12px);
  border-bottom: 1px solid rgba(255, 255, 255, 0.07);
}
.v3 .nav .wrap { display: flex; align-items: center; gap: 24px; height: 68px; }
.v3 .nav img { height: 38px; display: block; }
.v3 .nav .spacer { flex: 1; }
.v3 .nav a { color: rgba(255, 255, 255, 0.72); text-decoration: none; font-size: 14px; font-weight: 500; }
.v3 .nav a:hover { color: #fff; }
.v3 .nav .join { color: var(--night); background: var(--signal); padding: 9px 16px; border-radius: 999px; font-weight: 700; }
.v3 .nav-links { display: flex; gap: 22px; align-items: center; }
.v3 .nav-links a.phone { color: var(--signal); font-weight: 700; white-space: nowrap; }
@media (max-width: 900px) { .v3 .nav-links a:not(.join):not(.phone) { display: none; } }

/* ---------- hero ---------- */
.v3 .hero { position: relative; overflow: hidden; background: var(--night); color: #fff; padding: 74px 0 0; }
.v3 .hero::before, .v3 .hero::after {
  content: ""; position: absolute; border-radius: 50%; pointer-events: none; filter: blur(80px); opacity: 0.55;
}
.v3 .hero::before {
  width: 640px; height: 640px; top: -240px; left: -160px;
  background: radial-gradient(circle, rgba(242, 183, 5, 0.45), transparent 68%);
  animation: drift-a 24s var(--ease) infinite alternate;
}
.v3 .hero::after {
  width: 560px; height: 560px; right: -180px; top: 120px;
  background: radial-gradient(circle, rgba(169, 118, 10, 0.55), transparent 68%);
  animation: drift-b 29s var(--ease) infinite alternate;
}
@keyframes drift-a { to { transform: translate3d(110px, 80px, 0) scale(1.16); } }
@keyframes drift-b { to { transform: translate3d(-90px, -70px, 0) scale(1.12); } }

/* Pointer spotlight — desktop only. Driven by two CSS custom properties
   the script updates; no layout, no repaint of anything but this layer. */
@media (hover: hover) and (pointer: fine) {
  .v3 .spot {
    position: absolute; inset: 0; pointer-events: none; z-index: 1;
    background: radial-gradient(420px circle at var(--mx, 50%) var(--my, 30%), rgba(242, 183, 5, 0.16), transparent 62%);
    transition: opacity 0.4s;
  }
}
.v3 .spot { display: none; }
@media (hover: hover) and (pointer: fine) { .v3 .spot { display: block; } }

.v3 .grain {
  position: absolute; inset: 0; pointer-events: none; opacity: 0.38; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/></filter><rect width='140' height='140' filter='url(%23n)' opacity='0.5'/></svg>");
}

.v3 .hero .inner { position: relative; z-index: 2; display: grid; gap: 54px; grid-template-columns: 1.12fr 0.88fr; align-items: center; padding-bottom: 78px; }

/* Real WebGL 3D gem, injected by hero-3d.js — see that file for why raw
   WebGL instead of a library. Sits as an atmospheric accent behind/above
   the live-job card, not competing with it for attention. */
.v3 .hero canvas.hero3d {
  position: absolute; z-index: 1; pointer-events: none;
  top: 6%; right: 2%; opacity: 0.85;
  filter: drop-shadow(0 30px 60px rgba(242, 183, 5, 0.25));
}
@media (max-width: 940px) {
  .v3 .hero canvas.hero3d { top: -4%; right: -6%; opacity: 0.55; }
}

/* Homepage gem-break sequence, 2026-08-23 — hero-gem-break.js's DOM
   overlay (star streak, craftsmen/clients sparks, reform flash), laid
   over the same box canvas.hero3d occupies. All transitions, not
   keyframes: the script toggles a single .go class per element at the
   right phase, so one rule drives both "play" and the quiet reset at
   the top of the next cycle. */
.v3 .hero-gem-overlay { position: absolute; top: 6%; right: 2%; width: min(340px, 42%); aspect-ratio: 1; z-index: 3; pointer-events: none; }
@media (max-width: 940px) { .v3 .hero-gem-overlay { top: -4%; right: -6%; width: min(260px, 55%); } }

.v3 .hgb-burst { position: absolute; inset: 0; z-index: 2; }

/* The star's own full-hero layer — a real, legible left-to-right sweep
   across the whole hero, not a few pixels inside the 340px gem box
   (which is where it lived originally, and which meant most of its
   travel happened off-canvas — found live, via screenshot, when it
   was invisible for most of its own transition). left/top (not
   transform) so percentages resolve against the whole hero, giving a
   predictable, viewport-proportional start and landing point. */
.v3 .hero-star-layer { position: absolute; inset: 0; z-index: 4; pointer-events: none; }

/* Confined to the right half of the hero — the .inner grid's second
   (0.88fr) column, where the gem/live-card actually live. Found live,
   via screenshot: starting from the true left edge of the whole hero
   (where the headline text sits) put the star and its "Competition"
   label directly on top of "Your home, in safe hands." A shorter,
   clean sweep within the card's own half still reads as a real
   left-to-right strike without colliding with the copy. */
.v3 .hgb-star {
  position: absolute; top: 34%; left: 54%; width: 16px; height: 16px; border-radius: 50%;
  background: var(--signal); opacity: 0;
  box-shadow: 0 0 20px 6px rgba(242,183,5,0.9), 0 0 46px 14px rgba(242,183,5,0.5);
  transition: opacity 0.3s ease;
}
.v3 .hgb-star::before {
  content: ""; position: absolute; top: 50%; right: 100%; width: 90px; height: 3px;
  margin-top: -1.5px; border-radius: 3px;
  background: linear-gradient(to left, rgba(242,183,5,0.85), rgba(242,183,5,0));
}
.v3 .hgb-star.go { opacity: 1; left: 83%; top: 24%; transition: left 1.1s cubic-bezier(.3,0,.35,1), top 1.1s cubic-bezier(.3,0,.35,1), opacity 0.3s ease; }

.v3 .hgb-star-label {
  position: absolute; top: 46%; left: 54%; font-family: "IBM Plex Mono", monospace; font-size: 13px;
  letter-spacing: 0.1em; text-transform: uppercase; color: #fff; opacity: 0;
  white-space: nowrap; transform: translateY(4px);
  background: rgba(11,11,10,0.6); border: 1px solid rgba(255,255,255,0.22); border-radius: 999px;
  padding: 6px 14px; -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
  transition: opacity 0.4s ease, transform 0.4s ease;
}
.v3 .hgb-star-label.go { opacity: 1; transform: translateY(0); }

.v3 .hgb-mark {
  position: absolute; top: 50%; left: 50%; width: 40px; height: 40px; margin: -20px 0 0 -20px;
  display: grid; place-items: center;
  opacity: 0; transform: scale(0.5) rotate(-8deg);
  filter: drop-shadow(0 0 22px rgba(242,183,5,0.65));
  transition: opacity 1.6s ease, transform 1.6s cubic-bezier(.2,.9,.3,1);
}
.v3 .hgb-mark.go { opacity: 1; transform: scale(1); transition: opacity 1.8s ease 0.2s, transform 1.8s cubic-bezier(.2,.9,.3,1) 0.2s; }

/* "You hit us, we hit back" — the same star, run in reverse, once the
   gem has actually finished rebuilding. */
.v3 .hgb-counter {
  position: absolute; top: 50%; left: 50%; width: 10px; height: 10px; border-radius: 50%;
  background: var(--signal); opacity: 0; transform: translate(-50%, -50%) scale(0.3);
  box-shadow: 0 0 16px 5px rgba(242,183,5,0.9), 0 0 40px 12px rgba(242,183,5,0.45);
  transition: transform 0.5s cubic-bezier(.3,0,.35,1), opacity 0.5s ease;
}
.v3 .hgb-counter.go { opacity: 1; transform: translate(90%, -160%) scale(0.9); transition: transform 0.6s cubic-bezier(.2,.4,.3,1), opacity 0.7s ease 0.15s; }

@media (prefers-reduced-motion: reduce) {
  .v3 .hgb-star, .v3 .hgb-star-label, .v3 .hgb-mark, .v3 .hgb-counter, .v3 .hgb-burst { transition: none !important; opacity: 0 !important; }
}
@media (max-width: 940px) { .v3 .hero .inner { grid-template-columns: 1fr; gap: 38px; padding-bottom: 56px; } }

.v3 .pill { display: inline-flex; align-items: center; gap: 9px; border: 1px solid var(--glass-line); background: var(--glass); padding: 7px 14px; border-radius: 999px; color: rgba(255,255,255,0.84); }
.v3 .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--signal); animation: ping 2.6s ease-out infinite; }
@keyframes ping {
  0% { box-shadow: 0 0 0 0 rgba(242,183,5,0.6); }
  70% { box-shadow: 0 0 0 11px rgba(242,183,5,0); }
  100% { box-shadow: 0 0 0 0 rgba(242,183,5,0); }
}

/* Homeowner/Business audience toggle, 2026-08-15 — swaps the hero's
   headline/tagline/sub/primary-CTA via hero-audience.js. Same visual
   language as .pill (glass panel, gold accent) so it reads as part of
   the hero rather than a bolted-on control. */
.v3 .audience-toggle { display: inline-flex; margin: 16px 0 0; border: 1px solid var(--glass-line); background: var(--glass); border-radius: 999px; padding: 4px; gap: 2px; }
.v3 .audience-toggle button { border: none; background: transparent; color: rgba(255,255,255,0.68); font-weight: 700; font-size: 13px; padding: 8px 18px; border-radius: 999px; cursor: pointer; transition: background .2s ease, color .2s ease; font-family: inherit; }
.v3 .audience-toggle button:hover { color: #fff; }
.v3 .audience-toggle button[aria-pressed="true"] { background: var(--signal); color: var(--night); }

.v3 .hero h1 { font-size: clamp(44px, 7vw, 88px); line-height: 0.94; letter-spacing: -0.03em; margin: 20px 0 0; }

/* Gold text with a light sweep travelling across it — the "swing" without
   a single extra byte of JavaScript. */
.v3 .shine {
  background: linear-gradient(100deg, var(--signal-deep) 0%, var(--signal) 28%, #fff3c4 46%, var(--signal) 62%, var(--signal-deep) 100%);
  background-size: 260% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: sweep 6.5s linear infinite;
}
@keyframes sweep { from { background-position: 160% 0; } to { background-position: -60% 0; } }

.v3 .hero .tagline { font-size: clamp(15px, 1.6vw, 17px); font-weight: 700; color: var(--signal); letter-spacing: -0.01em; margin: 18px 0 0; }
.v3 .hero .sub { font-size: clamp(16px, 1.9vw, 19px); line-height: 1.62; max-width: 50ch; color: rgba(255,255,255,0.72); margin: 22px 0 32px; }

.v3 .btns { display: flex; gap: 13px; flex-wrap: wrap; }
.v3 .btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  padding: 16px 28px; border-radius: 12px; text-decoration: none; font-weight: 700; font-size: 15px;
  border: 1px solid transparent; transition: transform 0.18s var(--ease), box-shadow 0.18s var(--ease), background 0.18s;
}
.v3 .btn.gold { background: var(--signal); color: var(--night); box-shadow: 0 12px 34px -12px rgba(242,183,5,0.7); }
.v3 .btn.gold:hover { transform: translateY(-3px); box-shadow: 0 18px 44px -14px rgba(242,183,5,0.85); }
.v3 .btn.ghost { border-color: var(--glass-line); color: #fff; background: var(--glass); }
.v3 .btn.ghost:hover { transform: translateY(-3px); background: rgba(255,255,255,0.1); }
.v3 .btn.dark { background: var(--night); color: #fff; }
.v3 .btn.outline { border-color: rgba(27,27,25,0.34); color: var(--night); }

/* ---------- live job card, now it actually advances ---------- */
.v3 .live {
  border: 1px solid var(--glass-line);
  background: linear-gradient(180deg, rgba(255,255,255,0.08), rgba(255,255,255,0.02));
  border-radius: 20px; padding: 20px;
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  /* Round-2 owner ask: the ticker sat level with the gem, competing with
     the advisor panel that opens in the right column's upper band. Sitting
     it at the bottom of its grid cell puts its top edge level with the
     "I'm a craftsman" button row. */
  align-self: end;
  transition: opacity 0.3s var(--ease), filter 0.3s var(--ease);
}
/* When the advisor panel is open the ticker recedes — it stops competing
   for attention (gem-advisor.js sets .gxa-body-advisor-open on <body>). */
body.gxa-body-advisor-open.v3 .live {
  opacity: 0.28;
  filter: saturate(0.4);
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .v3 .live { transition: none; }
}
.v3 .live .head { display: flex; justify-content: space-between; color: rgba(255,255,255,0.55); }
.v3 .row { display: flex; gap: 13px; padding: 13px 0; border-bottom: 1px solid rgba(255,255,255,0.06); opacity: 0.42; transition: opacity 0.5s var(--ease); }
.v3 .row:last-child { border-bottom: 0; }
.v3 .row.on { opacity: 1; }
.v3 .tick {
  width: 22px; height: 22px; border-radius: 50%; flex: none; margin-top: 2px; display: grid; place-items: center;
  font-size: 11px; font-weight: 700; background: rgba(255,255,255,0.06); color: rgba(255,255,255,0.4);
  border: 1px solid rgba(255,255,255,0.13); transition: all 0.45s var(--ease);
}
.v3 .row.on .tick { background: rgba(242,183,5,0.18); color: var(--signal); border-color: rgba(242,183,5,0.5); transform: scale(1.06); }
.v3 .row b { display: block; font-size: 14px; color: #fff; font-weight: 600; }
.v3 .row span { font-size: 12.5px; color: rgba(255,255,255,0.52); }

/* ---------- kinetic band: the thing people actually remember ---------- */
.v3 .band {
  background: var(--signal); color: var(--night); overflow: hidden;
  padding: 16px 0; border-block: 2px solid var(--night); position: relative; z-index: 3;
}
.v3 .track { display: flex; gap: 44px; width: max-content; animation: roll 26s linear infinite; }
.v3 .track span {
  font-family: "Archivo Black", Impact, sans-serif; font-size: clamp(20px, 3.4vw, 34px);
  letter-spacing: -0.01em; white-space: nowrap; display: flex; align-items: center; gap: 44px;
}
.v3 .track span::after { content: "◆"; font-size: 0.5em; opacity: 0.55; }
@keyframes roll { to { transform: translate3d(-50%, 0, 0); } }

/* ---------- demo activity: honest pre-launch placeholder, see index.html.
   Distinct on purpose from ".stats" below — that section shows nothing
   until real data exists; this one is explicitly labelled fake so the
   two are never confused with each other. ---------- */
.v3 .demo-activity { text-align: center; }
.v3 .demo-tag { margin: 0 auto 30px; border-style: dashed; }
.v3 .demo-grid { display: flex; justify-content: center; gap: 22px; flex-wrap: wrap; }
.v3 .demo-card {
  border: 1px solid var(--glass-line);
  background: linear-gradient(180deg, rgba(255,255,255,0.07), rgba(255,255,255,0.02));
  border-radius: 18px; padding: 30px 42px; min-width: 220px;
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  transform: perspective(900px) rotateX(var(--tiltY, 0deg)) rotateY(var(--tiltX, 0deg));
  transition: transform 0.35s var(--ease);
}
.v3 .demo-num {
  font-family: "IBM Plex Mono", ui-monospace, monospace; font-weight: 600;
  font-size: clamp(36px, 6vw, 56px); color: var(--signal); line-height: 1; letter-spacing: -0.01em;
}
.v3 .demo-label { margin-top: 8px; color: rgba(255,255,255,0.62); font-size: 13.5px; letter-spacing: 0.02em; }
.v3 .demo-note {
  max-width: 62ch; margin: 30px auto 0; font-size: 13.5px; line-height: 1.75; color: rgba(255,255,255,0.5);
  border-top: 1px dashed rgba(255,255,255,0.16); padding-top: 22px;
}
.v3 .demo-note strong { color: rgba(255,255,255,0.72); }

/* ---------- demo review toasts, see index.html ---------- */
.v3 .toast-stack {
  position: fixed; left: 18px; bottom: 18px; z-index: 70; display: flex; flex-direction: column-reverse; gap: 10px;
  width: min(300px, calc(100vw - 36px)); pointer-events: none;
}
.v3 .toast {
  pointer-events: auto; background: var(--night); color: #fff; border: 1px solid var(--glass-line);
  border-radius: 14px; padding: 13px 14px; box-shadow: 0 20px 44px -18px rgba(0,0,0,0.6);
  opacity: 0; transform: translateY(14px); transition: opacity 0.4s var(--ease), transform 0.4s var(--ease);
  display: grid; grid-template-columns: 1fr auto; gap: 2px 8px; align-items: start;
}
.v3 .toast.show { opacity: 1; transform: none; }
.v3 .toast-stars { grid-column: 1; font-size: 12px; color: var(--signal); letter-spacing: 0.1em; }
.v3 .toast-text { grid-column: 1; font-size: 13px; line-height: 1.4; }
.v3 .toast-tag { grid-column: 1; margin-top: 3px; color: rgba(255,255,255,0.42); font-size: 9.5px; letter-spacing: 0.09em; text-transform: uppercase; }
.v3 .toast-close {
  grid-column: 2; grid-row: 1 / span 3; background: none; border: none; color: rgba(255,255,255,0.5);
  font-size: 17px; line-height: 1; cursor: pointer; padding: 2px; font-family: inherit;
}
.v3 .toast-close:hover { color: #fff; }

/* ---------- live counters: hidden until real data exists, see index.html ---------- */
.v3 .stats { text-align: center; opacity: 0; transition: opacity 0.6s var(--ease); }
.v3 .stats.show { opacity: 1; }
.v3 .stats .pill { margin: 0 auto 34px; }
.v3 .stat-row { display: flex; justify-content: center; gap: 64px; flex-wrap: wrap; }
.v3 .stat-num {
  font-family: "IBM Plex Mono", ui-monospace, monospace; font-weight: 600;
  font-size: clamp(40px, 7vw, 68px); color: var(--signal); line-height: 1; letter-spacing: -0.01em;
}
.v3 .stat-label { margin-top: 10px; color: rgba(255,255,255,0.62); font-size: 14px; letter-spacing: 0.02em; }

/* ---------- sections ---------- */
.v3 .sec { padding: 96px 0; position: relative; }
.v3 .sec.warm { background: var(--paper-warm); border-block: 1px solid var(--line); }
.v3 .sec.dark { background: var(--night); color: #fff; }
.v3 .sec.dark .lead { color: rgba(255,255,255,0.66); }
.v3 .eyebrow { color: var(--signal-deep); }
.v3 .sec.dark .eyebrow { color: var(--signal); }
.v3 .sec h2 { font-size: clamp(32px, 5vw, 56px); line-height: 1.0; letter-spacing: -0.025em; margin: 14px 0 16px; }
.v3 .lead { font-size: 17px; line-height: 1.65; color: var(--slate); max-width: 58ch; margin: 0; }

.v3 .cards { display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); margin-top: 42px; }
.v3 .card {
  border: 1px solid var(--line); border-radius: 18px; padding: 26px; background: var(--paper); position: relative; overflow: hidden;
  transition: transform 0.24s var(--ease), box-shadow 0.24s var(--ease), border-color 0.24s;
}
.v3 .sec.dark .card { background: rgba(255,255,255,0.035); border-color: var(--glass-line); }
.v3 .sec.dark .card p { color: rgba(255,255,255,0.6); }
/* A gold line that traces in along the top edge on hover. */
.v3 .card::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 2px; background: var(--signal);
  transform: scaleX(0); transform-origin: 0 50%; transition: transform 0.34s var(--ease);
}
.v3 .card:hover::before { transform: scaleX(1); }
@media (hover: hover) and (pointer: fine) {
  .v3 .card:hover { transform: translateY(-6px); box-shadow: 0 26px 54px -30px rgba(17,17,17,0.45); }
}
.v3 .card h3 { font-size: 19px; margin: 12px 0 8px; }
.v3 .card p { margin: 0; color: var(--slate); font-size: 14.5px; line-height: 1.6; }
.v3 .num { font-family: "IBM Plex Mono", monospace; font-size: 34px; color: var(--signal); font-weight: 600; }
.v3 .stars { color: var(--signal); font-size: 18px; letter-spacing: 2px; margin-bottom: 10px; }

/* Oversized outlined numeral behind each step — depth without an image. */
.v3 .ghostnum {
  position: absolute; right: 14px; bottom: -18px; font-family: "Archivo Black", sans-serif; font-size: 96px;
  line-height: 1; color: transparent; -webkit-text-stroke: 1.5px rgba(242,183,5,0.28); pointer-events: none;
}

/* ---------- areas ---------- */
.v3 .areas { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 34px; }
.v3 .areas a {
  border: 1px solid var(--line); border-radius: 999px; padding: 10px 18px; text-decoration: none;
  color: var(--ink); font-size: 14px; font-weight: 500; background: var(--paper);
  transition: border-color 0.18s, transform 0.18s var(--ease), background 0.18s;
}
.v3 .areas a:hover { border-color: var(--signal); background: #fffdf4; transform: translateY(-2px); }

/* ---------- close ---------- */
.v3 .close { background: var(--signal); padding: 84px 0; text-align: center; position: relative; overflow: hidden; }
.v3 .close h2 { font-size: clamp(34px, 5.6vw, 62px); margin: 0 0 14px; color: var(--night); letter-spacing: -0.03em; }
.v3 .close p { color: rgba(27,27,25,0.78); margin: 0 auto 30px; max-width: 46ch; font-size: 17px; }

/* ---------- footer ---------- */
.v3 footer.f { background: var(--night); color: rgba(255,255,255,0.62); padding: 58px 0 30px; }
.v3 footer.f img { height: 30px; }
.v3 footer.f .cols { display: grid; gap: 34px; grid-template-columns: 1.4fr repeat(3, 1fr); margin-bottom: 36px; }
@media (max-width: 780px) { .v3 footer.f .cols { grid-template-columns: 1fr 1fr; } }
.v3 footer.f h4 { color: #fff; font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase; margin: 0 0 14px; }
.v3 footer.f a { display: block; color: rgba(255,255,255,0.62); text-decoration: none; font-size: 14px; margin-bottom: 9px; }
.v3 footer.f a:hover { color: var(--signal); }
.v3 footer.f .base { border-top: 1px solid rgba(255,255,255,0.08); padding-top: 22px; display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; font-size: 13px; }

/* ---------- explainer: 30-second "how Rhodex works" player, 2026-08-22 ----------
   Homepage section, right after the hero. Same real gem/type/colour system
   as everywhere else on the site — not a new visual language. */
.v3 .explainer-frame {
  max-width: 920px; margin: 40px auto 0; border-radius: 18px; overflow: hidden;
  box-shadow: 0 30px 70px -30px rgba(0,0,0,0.5); background: var(--night);
}
.v3 .explainer-stage { position: relative; width: 100%; aspect-ratio: 16/9; overflow: hidden; background: var(--night); }
.v3 .explainer-stage::before {
  content: ""; position: absolute; width: 640px; height: 640px; top: -220px; right: -160px;
  border-radius: 50%; filter: blur(90px); opacity: 0.55; pointer-events: none;
  background: radial-gradient(circle, rgba(242,183,5,0.45), transparent 68%);
  transition: opacity 1.1s var(--ease), transform 1.1s var(--ease);
}
.v3 .explainer-stage::after {
  content: ""; position: absolute; inset: 0; opacity: 0.3; mix-blend-mode: overlay; pointer-events: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/></filter><rect width='140' height='140' filter='url(%23n)' opacity='0.5'/></svg>");
}
.v3 .explainer-stage[data-beat="0"]::before { opacity: 0.22; transform: scale(0.85); }
.v3 .explainer-stage[data-beat="1"]::before { opacity: 0.65; transform: scale(1.08); }
.v3 canvas.explainer-gem {
  position: absolute; z-index: 1; top: 50%; right: 6%; transform: translateY(-50%);
  filter: drop-shadow(0 30px 60px rgba(242,183,5,0.3)); transition: opacity 0.9s var(--ease), filter 0.9s var(--ease);
}
.v3 .explainer-beats { position: absolute; z-index: 2; inset: 0; display: flex; align-items: center; }
.v3 .explainer-beat {
  position: absolute; left: 6%; right: 40%; opacity: 0; transform: translateY(18px);
  transition: opacity 0.65s var(--ease), transform 0.65s var(--ease); pointer-events: none;
}
.v3 .explainer-beat.active { opacity: 1; transform: translateY(0); }
.v3 .explainer-beat .k {
  font-family: "IBM Plex Mono", monospace; font-size: clamp(10px,1.3vw,12px); letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--signal); display: block; margin-bottom: 10px;
}
.v3 .explainer-beat h3 {
  font-family: "Archivo Black", Impact, sans-serif; font-weight: 400; letter-spacing: -0.01em; color: #fff;
  font-size: clamp(20px,3.6vw,34px); line-height: 1.1; margin: 0 0 12px; text-wrap: balance;
}
.v3 .explainer-beat p { color: rgba(255,255,255,0.72); font-size: clamp(12px,1.5vw,15px); line-height: 1.55; margin: 0; max-width: 46ch; }
.v3 .explainer-beat ul { margin: 4px 0 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 7px; }
.v3 .explainer-beat li {
  font-size: clamp(12px,1.5vw,14.5px); color: rgba(255,255,255,0.85); display: flex; align-items: center; gap: 9px;
  opacity: 0; transform: translateX(-8px); transition: opacity 0.5s var(--ease), transform 0.5s var(--ease);
}
.v3 .explainer-beat.active li { opacity: 1; transform: translateX(0); }
.v3 .explainer-beat.active li:nth-child(1) { transition-delay: 0.15s; }
.v3 .explainer-beat.active li:nth-child(2) { transition-delay: 0.32s; }
.v3 .explainer-beat.active li:nth-child(3) { transition-delay: 0.49s; }
.v3 .explainer-beat.active li:nth-child(4) { transition-delay: 0.66s; }
.v3 .explainer-beat li .check {
  width: 16px; height: 16px; border-radius: 50%; background: var(--signal); flex: none;
  display: grid; place-items: center; font-size: 10px; color: var(--night); font-weight: 700;
}
.v3 .explainer-beat.cta { left: 0; right: 0; display: flex; flex-direction: column; align-items: center; text-align: center; padding: 0 8%; }
.v3 .explainer-beat.cta p { text-align: center; }
.v3 .explainer-leaf { display: block; width: clamp(28px,4vw,40px); height: clamp(28px,4vw,40px); margin-bottom: 14px; }
.v3 .explainer-beat.cta .wordmark { font-family: "Archivo Black", Impact, sans-serif; font-size: clamp(24px,4.6vw,38px); color: #fff; letter-spacing: -0.02em; margin-bottom: 6px; }
.v3 .explainer-beat.cta .wordmark span { color: var(--signal); }
.v3 .explainer-beat.cta .explainer-tag { font-family: "IBM Plex Mono", monospace; font-size: 12px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--signal-deep); margin-bottom: 20px; }
.v3 .explainer-cta-btn {
  display: inline-flex; align-items: center; gap: 8px; padding: 13px 24px; border-radius: 12px;
  background: var(--signal); color: var(--night); font-weight: 700; font-size: 14px;
  box-shadow: 0 14px 34px -14px rgba(242,183,5,0.7); text-decoration: none;
}
.v3 .explainer-chrome { display: flex; align-items: center; gap: 12px; padding: 12px 16px; background: #050504; }
.v3 .explainer-track { flex: 1; height: 3px; border-radius: 999px; background: rgba(255,255,255,0.14); overflow: hidden; }
.v3 .explainer-track > i { display: block; height: 100%; width: 0%; background: var(--signal); border-radius: 999px; }
.v3 .explainer-timecode { font-family: "IBM Plex Mono", monospace; font-size: 11.5px; color: rgba(255,255,255,0.6); font-variant-numeric: tabular-nums; min-width: 74px; }
.v3 .explainer-replay {
  font-family: "IBM Plex Mono", monospace; font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: #fff;
  background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.16); border-radius: 8px; padding: 6px 12px; cursor: pointer;
}
.v3 .explainer-replay:hover { background: rgba(255,255,255,0.14); }
@media (prefers-reduced-motion: reduce) {
  .v3 .explainer-beat, .v3 .explainer-beat li { transition: none; }
}

/* ---------- reveal ---------- */
.v3 .reveal { opacity: 0; transform: translateY(24px); transition: opacity 0.7s var(--ease), transform 0.7s var(--ease); }
.v3 .reveal.in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .v3 *, .v3 *::before, .v3 *::after { animation: none !important; transition: none !important; }
  .v3 .reveal { opacity: 1; transform: none; }
  .v3 .row { opacity: 1; }
  .v3 .progress { display: none; }
}
