/* ─────────────────────────────────────────────────────────────────────────
   VOXKART: COMBAT CIRCUIT — voxkartracing.com
   ─────────────────────────────────────────────────────────────────────────
   The palette is lifted off the trailer rather than invented: near-black
   ground, the wordmark's cyan-to-orange heat, curb yellow for anything you
   can press, and the cyan neon that rings the logo's infinity track. Edges
   are cut, not rounded, because every panel in the game is a sheared
   parallelogram — a site with soft corners would look like a different
   product's site.

   Static HTML and one stylesheet on purpose. The previous attempt was React +
   React Three Fiber with a live 3D garage, which is a lot of JavaScript to
   ship at somebody deciding whether to install a game. The hero here is the
   game's own alpha-channel logo loop over a still — it starts painting
   immediately and there is no framework between the visitor and the pitch.
   ───────────────────────────────────────────────────────────────────────── */

:root {
  /* PURE black, not near-black. The hero reel and the logo art both carry their
     own black surround; at #05070b those surrounds sat a few levels above the
     page and read as a faint rectangle. Matching the page to true black is what
     actually makes the video edge disappear — the mask then only has to soften
     the transition, not hide a mismatch. The panels above stay lifted so the
     layout still has structure. */
  --bg: #000000;
  --bg-2: #0a0e15;
  --panel: #0e131c;
  --line: #1e2836;
  --line-hot: #2c3b4f;
  --ink: #f2f5fa;
  --dim: #8595ab;
  --accent: #ffcc00;      /* curb yellow — anything you can press */
  --accent-ink: #1a1500;
  --cyan: #24d6ff;        /* the neon ring around the logo's track */
  --heat: #ff6b3d;        /* the wordmark's lower half */
  --pink: #ff4d6d;
  --good: #38e08b;
  --shell: clamp(16px, 5vw, 64px);
  --maxw: 1180px;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }

/* ── ambient voxel field ───────────────────────────────────────────────────
   Fixed behind everything, drawn by /voxel-bg.js. It is deliberately dim: it
   sits under body copy, so it has to read as texture, never as content. The
   canvas is inert to the pointer so it cannot eat a click on a link above it.
   Everything else on the page is lifted one layer so it always wins. */
#voxel-bg {
  position: fixed; inset: 0; z-index: 0;
  pointer-events: none;
  /* Fades out toward the bottom so the footer stays quiet. */
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 72%, transparent 100%);
          mask-image: linear-gradient(180deg, #000 0%, #000 72%, transparent 100%);
}
body > header, body > section, body > footer { position: relative; z-index: 1; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 16px/1.6 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
/* `height: auto` is not tidying — without it the images are STRETCHED.
   The <img> tags carry width/height attributes (which is right: they reserve
   the box and stop the page jumping as shots load), but `max-width: 100%`
   shrinks only the WIDTH. The attribute height then stands, so at any viewport
   narrower than 1180px every screenshot is squashed vertically. */
img, video { max-width: 100%; height: auto; display: block; }
a { color: var(--cyan); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Italic condensed caps is the game's own voice — the HUD, the buttons and the
   wordmark are all in it. */
h1, h2, h3, .kicker, .btn { font-style: italic; font-weight: 800; letter-spacing: .01em; }
h1 { font-size: clamp(38px, 7vw, 82px); line-height: .96; margin: 0 0 18px; text-transform: uppercase; }
h2 { font-size: clamp(26px, 4vw, 44px); line-height: 1.05; margin: 0 0 14px; text-transform: uppercase; }
h3 { font-size: 19px; margin: 0 0 8px; text-transform: uppercase; }
p { margin: 0 0 14px; color: #cfd8e4; }
.lead { font-size: clamp(17px, 2vw, 20px); color: #dbe3ee; max-width: 62ch; }

.kicker {
  display: inline-block; font-size: 11px; letter-spacing: .28em;
  text-transform: uppercase; color: var(--cyan); margin-bottom: 12px;
  font-style: normal; font-weight: 700;
}
.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 var(--shell); }
section { padding: clamp(56px, 9vw, 120px) 0; position: relative; }

/* ── the cut edge, everywhere ──────────────────────────────────────────── */
.cut { clip-path: polygon(14px 0, 100% 0, calc(100% - 14px) 100%, 0 100%); }

/* ── buttons ───────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; gap: 10px; justify-content: center;
  padding: 15px 30px; min-height: 54px; font-size: 15px; text-transform: uppercase;
  border: 1px solid var(--line-hot); background: var(--panel); color: var(--ink);
  cursor: pointer; position: relative; overflow: hidden;
  clip-path: polygon(12px 0, 100% 0, calc(100% - 12px) 100%, 0 100%);
  transition: transform .16s cubic-bezier(.34,1.56,.64,1), background .16s;
}
.btn:hover { background: #16202e; text-decoration: none; transform: translateY(-2px); }
.btn:active { transform: translateY(1px) scale(.985); }
.btn.primary {
  background: linear-gradient(180deg, #ffe066, var(--accent) 45%, #e8a400);
  color: var(--accent-ink); border-color: #ffe066; font-weight: 900;
}
/* The same marching voxel sparks the game's gold buttons carry. Hard stops, no
   blend — the arc has to read as cubes, not as a neon tube. */
.btn.primary::after {
  content: ''; position: absolute; inset: 0; pointer-events: none; clip-path: inherit;
  background-image:
    repeating-linear-gradient(90deg, #bff6ff 0 5px, transparent 5px 13px),
    repeating-linear-gradient(90deg, #bff6ff 0 5px, transparent 5px 13px);
  background-size: 100% 2px, 100% 2px;
  background-position: 0 0, 0 100%;
  background-repeat: no-repeat;
  mix-blend-mode: screen; opacity: .85;
  animation: spark 1.15s linear infinite;
}
@keyframes spark { to { background-position: 13px 0, -13px 100%; } }
.btn .sub { font-size: 10px; opacity: .7; font-style: normal; letter-spacing: .12em; }

/* ── nav ───────────────────────────────────────────────────────────────── */
header.nav {
  position: sticky; top: 0; z-index: 50;
  background: #000000d9; backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.nav-in { display: flex; align-items: center; gap: 22px; height: 62px; }
.nav-mark { display: flex; align-items: center; gap: 10px; font-weight: 900; font-style: italic; letter-spacing: .02em; }
.nav-mark b { color: var(--accent); }
.nav-links { margin-left: auto; display: flex; gap: 22px; align-items: center; }
.nav-links a { color: var(--dim); font-size: 13px; letter-spacing: .1em; text-transform: uppercase; font-weight: 700; }
.nav-links a:hover { color: var(--ink); text-decoration: none; }
@media (max-width: 720px) { .nav-links a.hide-sm { display: none; } }

/* ── hero ──────────────────────────────────────────────────────────────── */
.hero { padding-top: clamp(30px, 6vw, 64px); text-align: center; overflow: hidden; }
/* A slow chequered drift far behind everything: the flag from the logo,
   dimmed until it is texture rather than pattern. */
.hero::before {
  content: ''; position: absolute; inset: -20% -10% auto; height: 130%;
  background-image: repeating-conic-gradient(#ffffff08 0 25%, transparent 0 50%);
  background-size: 34px 34px;
  mask-image: radial-gradient(ellipse 70% 55% at 50% 30%, #000 0%, transparent 72%);
  animation: drift 26s linear infinite; pointer-events: none;
}
@keyframes drift { to { background-position: 340px 0; } }
.hero-glow {
  position: absolute; left: 50%; top: -10%; width: min(900px, 120vw); aspect-ratio: 1;
  transform: translateX(-50%);
  background: radial-gradient(circle, #24d6ff26 0%, #24d6ff00 62%);
  pointer-events: none;
}
/* ── hero reel ─────────────────────────────────────────────────────────────
   The old hero was a "transparent" logo WebM. It was not transparent: tagged
   ALPHA_MODE=1, but composite it over magenta and no magenta shows — the alpha
   plane is fully opaque. It was a solid dark rectangle on a dark page, which is
   the black box that kept coming back; re-baking the alpha never fixed it
   because alpha was never the mechanism.

   The replacement is the game's own loop, and it blends by construction
   instead: the page is true black, the clip's surround is black, and the mask
   below feathers all four edges so there is no boundary left to notice. Two
   gradients are INTERSECTED (mask-composite) rather than layered — layering
   them would union the opaque regions and square the corners back up, which is
   the whole thing we are trying to avoid.

   No colour grade here. The saturation complaint was about the old logo
   render; this is real gameplay footage and filtering it would only dull it. */
.hero-logo {
  position: relative;
  width: min(680px, 92%);
  margin: 0 auto 6px;
  aspect-ratio: 640 / 358;
}
.hero-logo video, .hero-logo img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: contain;
  /* 1. Crush the clip's background to true black. The pair is solved, not
        guessed: out = ((in*b) - .5)*c + .5, fixed so the measured background
        (7-16/255, and uneven corner to corner, which is why an edge showed)
        lands on 0 while the artwork's midtone (136) comes back near 120 — the
        slight dim that also takes the heat out of a very hot render.
     2. screen then drops pure black entirely, because screening with 0 leaves
        the backdrop untouched. That is what removes the rectangle, and it only
        works because the page ground is now true black too.
     3. saturate() last: the source is near-clipping orange with a cyan glow
        that reads as electric blue.
     The poster gets the identical treatment or the hero visibly shifts colour
     the instant the video finishes decoding. */
  filter: saturate(.66) brightness(.89) contrast(1.13);
  mix-blend-mode: screen;
}
/* The wordmark is in the footage, so the h1 sits under it as a compact line
   rather than repeating the logo at headline size. It is real visible text —
   not hidden — because a heading a visitor cannot see is a heading Google is
   entitled to discount. */
.hero-title {
  font-size: clamp(15px, 2.2vw, 22px);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--dim);
  margin: 0 0 14px;
}
.hero p.lead { margin-left: auto; margin-right: auto; }
.hero-cta { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; margin-top: 26px; }
.hero-note { margin-top: 16px; font-size: 13px; color: var(--dim); }

/* ── stat strip ────────────────────────────────────────────────────────── */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 1px; background: var(--line); border: 1px solid var(--line); }
.stat { background: var(--bg-2); padding: 22px 18px; text-align: center; }
.stat b { display: block; font-size: clamp(26px, 4vw, 40px); font-style: italic; color: var(--accent); line-height: 1; }
.stat span { font-size: 11px; letter-spacing: .18em; text-transform: uppercase; color: var(--dim); }

/* ── trailer ───────────────────────────────────────────────────────────── */
.tv { position: relative; border: 1px solid var(--line-hot); background: #000; }
.tv video { width: 100%; display: block; }
/* Cinematic bars, as the trailer itself has. */
.tv::before, .tv::after {
  content: ''; position: absolute; left: 0; right: 0; height: 8px;
  background: linear-gradient(90deg, transparent, var(--cyan), transparent); opacity: .5;
}
.tv::before { top: -1px; } .tv::after { bottom: -1px; }

/* ── feature grid ──────────────────────────────────────────────────────── */
.grid { display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.card {
  background: linear-gradient(180deg, var(--panel), #0a0e15);
  border: 1px solid var(--line); padding: 26px 24px; position: relative;
  clip-path: polygon(16px 0, 100% 0, calc(100% - 16px) 100%, 0 100%);
}
.card::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--cyan); opacity: .8; }
.card.gold::before { background: var(--accent); }
.card.heat::before { background: var(--heat); }
.card p { margin: 0; color: #b9c4d3; font-size: 15px; }
.card .ico { font-size: 22px; margin-bottom: 10px; display: block; }

/* ── screenshots, in a phone ───────────────────────────────────────────── */
.shots { display: grid; gap: 22px; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); }
.phone {
  border: 3px solid #1b2432; border-radius: 20px; background: #000;
  padding: 7px; box-shadow: 0 24px 60px -24px #000, 0 0 0 1px #2c3b4f inset;
  position: relative;
}
.phone img { border-radius: 12px; }
.phone figcaption {
  margin-top: 10px; font-size: 12px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--dim); text-align: center;
}
/* The speaker slot, so the frame reads as a handset and not a border. */
.phone::after {
  content: ''; position: absolute; left: 12px; top: 50%; width: 4px; height: 34px;
  transform: translateY(-50%); border-radius: 3px; background: #131a24;
}

/* ── platforms ─────────────────────────────────────────────────────────── */
.plat { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.plat .card { text-align: center; }
.plat .state { font-size: 11px; letter-spacing: .18em; text-transform: uppercase; color: var(--dim); }
.plat .state.soon { color: var(--accent); }

/* ── FAQ ───────────────────────────────────────────────────────────────── */
details.faq { border: 1px solid var(--line); background: var(--bg-2); margin-bottom: 10px; }
details.faq summary { padding: 18px 22px; cursor: pointer; font-weight: 700; list-style: none; }
details.faq summary::-webkit-details-marker { display: none; }
details.faq summary::before { content: '+ '; color: var(--cyan); font-weight: 900; }
details.faq[open] summary::before { content: '– '; }
details.faq .body { padding: 0 22px 20px; color: #b9c4d3; }

/* ── prose (dev / legal pages) ─────────────────────────────────────────── */
.prose { max-width: 74ch; }
.prose h2 { margin-top: 44px; }
.prose h3 { margin-top: 28px; color: var(--cyan); }
.prose ul { color: #cfd8e4; padding-left: 20px; }
.prose li { margin-bottom: 8px; }
.prose code { background: #121a26; padding: 2px 6px; font-size: 13px; color: var(--accent); }
.prose table { width: 100%; border-collapse: collapse; margin: 18px 0; font-size: 14px; }
.prose th, .prose td { border: 1px solid var(--line); padding: 9px 12px; text-align: left; }
.prose th { background: var(--bg-2); color: var(--cyan); font-size: 12px; letter-spacing: .1em; text-transform: uppercase; }
.updated { font-size: 13px; color: var(--dim); }

/* ── timeline (development page) ───────────────────────────────────────── */
.tl { border-left: 2px solid var(--line-hot); padding-left: 24px; margin: 26px 0; }
.tl-item { position: relative; padding-bottom: 26px; }
.tl-item::before {
  content: ''; position: absolute; left: -31px; top: 6px; width: 12px; height: 12px;
  background: var(--cyan); clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}
.tl-item h3 { margin-bottom: 4px; }
.tl-item .when { font-size: 11px; letter-spacing: .16em; text-transform: uppercase; color: var(--accent); }

footer {
  border-top: 1px solid var(--line); padding: 40px 0 60px; color: var(--dim); font-size: 13px;
}
footer .foot { display: flex; gap: 20px; flex-wrap: wrap; align-items: center; }
footer a { color: var(--dim); }
footer .sp { margin-left: auto; }

@media (prefers-reduced-motion: reduce) {
  .hero::before, .btn.primary::after { animation: none; }
  html { scroll-behavior: auto; }
}
