/* OmnyLLM — content layer over the WebGL world.
   The page is dark by design (it sits on a night scene), so there is a single
   color scheme. Contrast of text tokens against --bg: text 17:1, muted 8:1,
   dim 5:1. */

:root {
  --bg: #03070d;
  --bg-raise: #07101a;
  --text: #eef5fa;
  --muted: #9db2c3;
  --dim: #7a91a3;
  /* Page accent (buttons, eyebrows, headline gradient, links, marks). */
  --accent: #b7f8ff;
  --accent-soft: #dcfcff;
  --accent-start: #f2feff;
  --accent-end: #6be8e8;
  --accent-rgb: 183, 248, 255;
  /* 3D colour grammar, used by world captions and the scene legend:
     cyan is readable data on your side. */
  --cyan: #17c7ff;
  --cyan-soft: #72e7ff;
  --green: #41e6ad;
  --ice: #9edbff;
  --warn: #ffb45c;
  --line: rgba(160, 200, 230, 0.13);
  --line-strong: rgba(160, 210, 240, 0.24);
  --panel: rgba(6, 13, 22, 0.66);
  --panel-solid: rgba(6, 13, 22, 0.9);
  /* Halo for text that sits directly on the 3D world: a tight shadow for
     the letter edges plus a wide soft one that darkens the area around. */
  --read-shadow:
    0 1px 2px rgba(3, 7, 13, 0.7),
    0 0 8px rgba(3, 7, 13, 0.55),
    0 0 22px rgba(3, 7, 13, 0.5);
  /* Lighter, tighter halo for text inside unblurred panels (low tier): the
     panel tint already does most of the work. */
  --panel-read-shadow:
    0 1px 2px rgba(3, 7, 13, 0.6),
    0 0 6px rgba(3, 7, 13, 0.45);

  --font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-display: "Inter Tight", var(--font-sans);
  --font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  --max: 1200px;
  --gutter: clamp(16px, 4vw, 40px);
  --radius: 18px;
  --header-h: 68px;
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);

  color-scheme: dark;
}
/* With the menu collapsed (`html.nav-collapsed`, see the menu rules below and
   `initNav`) the bar holds only the logo and the icons, so it can be
   thinner. */
html.nav-collapsed { --header-h: 56px; }
/* Phones in landscape have little height to spare: thinner still. */
@media (orientation: landscape) and (max-height: 500px) and (pointer: coarse) {
  :root, html.nav-collapsed { --header-h: 44px; }
}

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: calc(var(--header-h) + 12px);
  /* No double-tap zoom (tapping the menu button twice zoomed the page on
     iPhone), while pinch zoom keeps working. */
  touch-action: manipulation;
}

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 1.0625rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img, svg, canvas { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
p { margin: 0; }
h1, h2, h3, h4 { margin: 0; font-weight: 600; }
ul, ol { margin: 0; padding: 0; }
[role="list"], .site-nav ul, .chips, .audit-log { list-style: none; }

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

.skip-link {
  position: fixed;
  top: 10px;
  left: 10px;
  z-index: 100;
  padding: 10px 16px;
  border-radius: 10px;
  background: var(--accent);
  color: #02121b;
  font-weight: 600;
  transform: translateY(-160%);
  transition: transform 0.2s var(--ease);
}
.skip-link:focus { transform: none; }

.wrap {
  width: min(100% - 2 * var(--gutter), var(--max));
  margin-inline: auto;
}

/* ------------------------------------------------------------------ */
/* Background layers                                                   */

.world-poster,
.world-canvas,
.world-scrim {
  position: fixed;
  inset: 0 0 auto 0;
  width: 100%;
  height: 100vh;
  height: 100lvh;
  pointer-events: none;
}

/* Static stand-in for the world: shown while the 3D world loads, without
   JS/WebGL, and on the "off" tier. It matches the watercolour render (cool
   grey-blue paper, grain, pencil-grey grid, a corridor of layer outlines)
   so the live world fades in without a jump in tone. */
.world-poster {
  z-index: 0;
  background:
    /* paper grain */
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.85 0 0 0 0 0.9 0 0 0 0 0.95 0 0 0 0.09 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"),
    /* soft light where the model sits */
    radial-gradient(70% 55% at 72% 48%, rgba(170, 190, 205, 0.22), transparent 70%),
    linear-gradient(180deg, #2a3138 0%, #475059 46%, #535c65 60%, #3a4148 100%);
}
.world-poster::before {
  /* pencil-grey ground grid in perspective */
  content: "";
  position: absolute;
  inset: 58% -40% 0 -40%;
  background-image:
    linear-gradient(rgba(215, 228, 238, 0.13) 1px, transparent 1px),
    linear-gradient(90deg, rgba(215, 228, 238, 0.13) 1px, transparent 1px);
  background-size: 72px 72px;
  transform: perspective(420px) rotateX(62deg);
  transform-origin: top center;
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 45%);
  mask-image: linear-gradient(180deg, transparent, #000 45%);
}
.world-poster::after {
  /* the model: a corridor of layer outlines receding to the right */
  content: "";
  position: absolute;
  right: 2%;
  top: 46%;
  width: 42vw;
  height: clamp(70px, 12vh, 120px);
  background: repeating-linear-gradient(
    90deg,
    rgba(215, 232, 242, 0.32) 0 1.5px,
    rgba(215, 232, 242, 0.04) 1.5px 2.2vw
  );
  border-block: 1px solid rgba(215, 232, 242, 0.18);
  transform: perspective(900px) rotateY(-42deg);
  transform-origin: left center;
  -webkit-mask-image: linear-gradient(90deg, #000 30%, transparent);
  mask-image: linear-gradient(90deg, #000 30%, transparent);
}

.world-canvas {
  z-index: 1;
  opacity: 0;
  transition: opacity 1.8s ease;
}
.world-ready .world-canvas { opacity: 1; }
.q-off .world-canvas { display: none; }

/* Keeps text readable over the brightest frames: darker on the reading
   side, open on the right where the world is framed. */
.world-scrim {
  z-index: 2;
  background:
    linear-gradient(90deg, rgba(3, 7, 13, 0.82) 0%, rgba(3, 7, 13, 0.55) 38%, rgba(3, 7, 13, 0.08) 72%, rgba(3, 7, 13, 0.18) 100%),
    linear-gradient(180deg, rgba(3, 7, 13, 0.5) 0%, transparent 18%, transparent 78%, rgba(3, 7, 13, 0.7) 100%);
}

@media (max-width: 820px) {
  .world-scrim {
    background:
      linear-gradient(180deg, rgba(3, 7, 13, 0.55) 0%, rgba(3, 7, 13, 0.4) 40%, rgba(3, 7, 13, 0.68) 100%);
  }
  /* Phones frame the model above the text. */
  .world-poster::after { right: 0; top: 16%; width: 78vw; height: 12vh; }
}

/* Captions projected onto the world: above the scrim, below the content. */
.world-labels {
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  overflow: hidden;
}
.world-label {
  position: absolute;
  left: 0;
  top: 0;
  opacity: 0;
  transition: opacity 0.5s ease;
  will-change: transform, opacity;
}
.world-label.is-visible { opacity: 1; }
.world-label::before {
  /* the anchor point */
  content: "";
  position: absolute;
  left: -3px;
  top: -3px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--cyan-soft);
  box-shadow: 0 0 10px var(--cyan);
}
.world-label::after {
  /* leader line up to the caption */
  content: "";
  position: absolute;
  left: 0;
  bottom: 3px;
  width: 1px;
  /* --lift is set per label when a caption is raised to clear a sibling. */
  height: calc(var(--lift, 32px) - 2px);
  background: linear-gradient(to top, rgba(114, 231, 255, 0.85), rgba(114, 231, 255, 0.15));
}
.world-label-box {
  position: absolute;
  left: -1px;
  /* --shift slides a caption that fits neither way back onto the screen. */
  margin-left: var(--shift, 0px);
  bottom: var(--lift, 32px);
  padding: 5px 10px;
  /* Same glass as the page panels (tint, frost, top highlight, light
     border), keeping the coloured edge that ties it to its leader line. */
  border: 1px solid rgba(190, 220, 240, 0.18);
  border-left: 1px solid var(--cyan-soft);
  border-radius: 0 8px 8px 0;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.02) 60%),
    linear-gradient(rgba(170, 190, 210, 0.06), rgba(170, 190, 210, 0.06)),
    rgba(8, 15, 24, 0.51);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.08),
    0 8px 22px rgba(0, 0, 0, 0.16);
  text-shadow: var(--panel-read-shadow);
  white-space: nowrap;
  font: 500 0.7rem/1.35 var(--font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text);
}
.world-label.is-flipped .world-label-box {
  left: auto;
  right: -1px;
  border-left: 1px solid var(--line-strong);
  border-right: 1px solid var(--cyan-soft);
  border-radius: 8px 0 0 8px;
  text-align: right;
}
/* Hung below the anchor, to clear a sibling caption above it. */
.world-label.is-below::after {
  top: 3px;
  bottom: auto;
  background: linear-gradient(to bottom, rgba(114, 231, 255, 0.85), rgba(114, 231, 255, 0.15));
}
.world-label.is-below .world-label-box {
  top: var(--lift, 32px);
  bottom: auto;
}
/* Ambient captions float over the GPU host: purple accent, lighter weight. */
/* Ambient captions (e.g. "Blind processing") are neutral grey, so they read
   as a quiet overlay rather than part of the scene's colour grammar. */
.world-label.is-ambient::before {
  background: #aab4bf;
  box-shadow: 0 0 10px rgba(170, 180, 191, 0.6);
}
.world-label.is-ambient::after {
  background: linear-gradient(to top, rgba(170, 180, 191, 0.8), rgba(170, 180, 191, 0.1));
}
.world-label.is-ambient .world-label-box {
  border-color: rgba(170, 180, 191, 0.3);
  border-left-color: #aab4bf;
  color: #dfe5eb;
}
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  html:not(.q-low) .world-label-box {
    background:
      linear-gradient(180deg, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0.015) 60%),
      rgba(6, 13, 22, 0.39);
    -webkit-backdrop-filter: blur(10px) saturate(140%);
    backdrop-filter: blur(10px) saturate(140%);
  }
}
.world-label.is-ambient.is-flipped .world-label-box {
  border-left-color: rgba(170, 180, 191, 0.3);
  border-right-color: #aab4bf;
}
/* Span labels mark a stretch of the world: a bracket between two projected
   points (positioned and rotated from Dart) with the caption centred above.
   The element itself stays at the origin; children carry the transforms. */
.world-label.is-span::before,
.world-label.is-span::after { display: none; }
.world-label-bracket {
  position: absolute;
  left: 0;
  top: 0;
  height: 0;
  border-top: 1px solid var(--cyan-soft);
  transform-origin: 0 100%;
}
.world-label.is-span .world-label-box {
  left: 0;
  top: 0;
  bottom: auto;
  border-radius: 8px;
  border-left-width: 1px;
}
.world-label.is-ambient .world-label-bracket {
  border-color: #aab4bf;
  box-shadow: 0 -4px 12px -6px rgba(170, 180, 191, 0.7);
  opacity: 0.6;
}
.world-label.is-ambient.is-span .world-label-box {
  border-color: rgba(170, 180, 191, 0.5);
}
.world-label-detail {
  display: block;
  font-weight: 400;
  letter-spacing: 0.02em;
  text-transform: none;
  color: var(--muted);
  white-space: pre; /* break only at explicit line breaks in captions */
}
/* Walkthrough text: the page is hidden, so captions explain a little more.
   Wraps (unlike the title and detail) within a readable width. */
.world-label-more {
  display: none;
  /* An explicit width: the caption box is absolutely positioned inside a
     zero-width label, so it would otherwise shrink to its narrowest line. */
  width: max-content;
  max-width: 30ch;
  margin-top: 5px;
  padding-top: 5px;
  border-top: 1px solid rgba(190, 220, 240, 0.14);
  font: 400 0.72rem/1.4 var(--font-sans);
  letter-spacing: 0;
  text-transform: none;
  white-space: normal;
  color: var(--text);
}
html.walkthrough .world-label-more { display: block; }
.world-label.is-flipped .world-label-more { margin-left: auto; }
@media (max-width: 560px) {
  .world-label-box { font-size: 0.62rem; padding: 4px 8px; }
  .world-label-more { max-width: 24ch; font-size: 0.68rem; }
}
/* Phones in landscape: too little height to stack two-line captions, so
   they show the title only (plus the walkthrough text, where the page text
   is hidden and there is room). */
@media (orientation: landscape) and (max-height: 500px) and (pointer: coarse) {
  .world-label-box { font-size: 0.62rem; padding: 4px 8px; }
  .world-label-detail { display: none; }
  .world-label-more { max-width: 26ch; margin-top: 3px; padding-top: 3px; }
}
@media (prefers-reduced-motion: reduce) {
  .world-label { transition: none; }
}
.q-off .world-labels { display: none; }

/* Captions that open a 3D tour: above the page content (so they can be
   clicked), clickable only while shown, and never over the open mobile
   menu. */
.world-actions { z-index: 4; }
html:has(.site-header.nav-open) .world-actions { display: none; }
.world-label-action[hidden] { display: none; }
/* A button, not a caption: no anchor dot or leader line, and the box sits
   at the element's origin (placed from Dart, centred on its anchor). */
.world-label.is-action::before,
.world-label.is-action::after { display: none; }
.world-label.is-action .world-label-box {
  left: 0;
  top: 0;
  bottom: auto;
  margin-left: 0;
  border-radius: 8px;
}
.world-label-action {
  border-color: rgba(var(--accent-rgb), 0.4);
  color: var(--text);
  cursor: pointer;
  transition: background-color 0.2s ease, border-color 0.2s ease;
}
.world-label-action::before {
  content: "▶";
  margin-right: 8px;
  color: var(--accent);
  font-size: 0.85em;
}
.world-label.is-visible .world-label-action { pointer-events: auto; }
.world-label-action:hover {
  border-color: rgba(var(--accent-rgb), 0.55);
  background-color: rgba(var(--accent-rgb), 0.12);
}

/* Everything above the background. */
.site-header, main, .site-footer { position: relative; z-index: 3; }

/* ------------------------------------------------------------------ */
/* Header                                                              */

.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 20;
  height: var(--header-h);
  padding-top: env(safe-area-inset-top);
  box-sizing: content-box;
  border-bottom: 1px solid transparent;
  transition: background-color 0.3s ease, border-color 0.3s ease;
}
/* The bar's glass lives on a ::before layer, not on the header itself: an
   element with backdrop-filter becomes a "backdrop root", and the mobile
   menu sheet inside the header could then only blur the header, never the
   page behind it. */
.site-header::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: transparent;
  transition: background-color 0.3s ease;
  pointer-events: none;
}
.site-header.is-scrolled,
.site-header.nav-open {
  border-bottom-color: var(--line);
}
.site-header.is-scrolled::before,
.site-header.nav-open::before {
  background: rgb(3 7 13 / 10%);
}
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .site-header.is-scrolled::before,
  .site-header.nav-open::before {
    -webkit-backdrop-filter: blur(16px) saturate(130%);
    backdrop-filter: blur(16px) saturate(130%);
  }
}
/* iOS status bar: with `viewport-fit=cover` the page runs under it, so the
   clock and battery would sit on raw content while the bar above is still
   transparent. A translucent strip, exactly the safe-area height, keeps them
   readable at every scroll position. Zero height (no strip) where there is no
   top inset, e.g. desktops and Android. */
.site-header::after {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: env(safe-area-inset-top, 0px);
  z-index: -1;
  background: rgb(3 7 13 / 38%);
  pointer-events: none;
}
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .site-header::after {
    background: rgb(3 7 13 / 24%);
    -webkit-backdrop-filter: blur(12px) saturate(130%);
    backdrop-filter: blur(12px) saturate(130%);
  }
}

.header-inner {
  height: 100%;
  display: flex;
  align-items: center;
  gap: 24px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.12rem;
  letter-spacing: 0.01em;
}
.brand-mark {
  position: relative;
  width: 28px;
  height: 28px;
  border: 1px solid rgba(var(--accent-rgb), 0.45);
  border-radius: 8px;
  background: rgba(var(--accent-rgb), 0.04);
  box-shadow: 0 0 14px rgba(var(--accent-rgb), 0.12);
  flex: none;
}
.brand-mark::before,
.brand-mark::after {
  content: "";
  position: absolute;
  transform: rotate(45deg);
}
/* Two nested diamonds; small radii so they stay diamonds, not circles. */
.brand-mark::before {
  inset: 7px;
  border: 1.5px solid var(--accent);
  border-radius: 2px;
}
.brand-mark::after {
  inset: 11px;
  background: var(--accent-end);
  border-radius: 1px;
  box-shadow: 0 0 6px var(--accent-end);
}

/* Spacing kept tight so the full row (logo, seven links, two buttons, the
   language globe and the full-screen icon) fits a 1200px screen in English;
   longer languages collapse the menu instead (`html.nav-collapsed`). */
.site-menu {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 10px;
}
.site-nav ul { display: flex; gap: 10px; }
/* One line each: a wrapped "How it / works" breaks the bar. */
.site-nav a,
.site-menu .btn { white-space: nowrap; }
/* "Request Access" in the bar; the full "Request OmnyLLM Access" in the
   collapsed menu, where there is room. */
.site-menu .label-full,
.nav-collapsed .site-menu .label-short { display: none; }
.nav-collapsed .site-menu .label-full { display: inline; }
.site-nav a {
  position: relative;
  color: var(--muted);
  font-size: 0.88rem;
  font-weight: 500;
  padding-block: 6px;
  transition: color 0.2s ease;
}
.site-nav a:hover,
.site-nav a[aria-current="true"] { color: var(--text); }
.site-nav a[aria-current="true"]::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  height: 1px;
  background: var(--accent);
}

.nav-toggle {
  display: none;
  margin-left: auto;
  width: 44px;
  height: 44px;
  /* Minimal: just the two lines, no box. The 44px button keeps the tap
     target; a soft shadow keeps the lines legible over the world. */
  border: 0;
  border-radius: 10px;
  background: none;
  color: var(--text);
  filter: drop-shadow(0 1px 2px rgba(3, 7, 13, 0.7));
  cursor: pointer;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  transition: color 0.2s ease;
}
.nav-toggle:hover,
.nav-open .nav-toggle {
  color: var(--accent);
}
.nav-toggle-bar {
  width: 18px;
  height: 1.5px;
  background: currentColor;
  transition: transform 0.25s var(--ease);
}
.nav-open .nav-toggle-bar:first-child { transform: translateY(3.75px) rotate(45deg); }
.nav-open .nav-toggle-bar:last-child { transform: translateY(-3.75px) rotate(-45deg); }

/* Language menu: a globe in the bar (after the menu on wide screens, next to
   the menu icon when it is collapsed), opening a list under the bar. */
.lang-menu {
  position: relative;
  order: 3;
  flex: none;
  /* Close to the request button: the row's 24px gap is for the menu. */
  margin-inline-start: -18px;
}
/* The page's `svg { max-width: 100% }` would let a crowded row squeeze the
   globe to nothing. */
.lang-toggle svg { flex: none; max-width: none; }
.lang-menu[hidden] { display: none; }
.lang-toggle {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 44px;
  padding: 0 8px;
  border: 0;
  border-radius: 10px;
  background: none;
  color: var(--muted);
  filter: drop-shadow(0 1px 2px rgba(3, 7, 13, 0.7));
  cursor: pointer;
  transition: color 0.2s ease;
}
.lang-toggle:hover,
.lang-toggle[aria-expanded="true"] { color: var(--accent); }
.lang-code {
  font: 500 0.72rem/1 var(--font-mono);
  letter-spacing: 0.08em;
}
.lang-list {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 30;
  min-width: 200px;
  max-height: min(70vh, 560px);
  overflow-y: auto;
  padding: 6px;
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  background: rgba(8, 14, 22, 0.94);
  box-shadow: 0 14px 34px rgba(3, 7, 13, 0.45);
}
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .lang-list {
    background: rgb(3 7 13 / 55%);
    -webkit-backdrop-filter: blur(24px) saturate(130%);
    backdrop-filter: blur(24px) saturate(130%);
  }
}
.lang-list[hidden] { display: none; }
html[dir="rtl"] .lang-list { right: auto; left: 0; }
.lang-list button {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  width: 100%;
  padding: 9px 12px;
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--text);
  font: inherit;
  font-size: 0.92rem;
  text-align: start;
  cursor: pointer;
}
.lang-list button:hover,
.lang-list button:focus-visible { background: rgba(var(--accent-rgb), 0.08); }
.lang-list button[aria-current="true"] { color: var(--accent); }
.lang-list button[aria-current="true"]::after { content: "✓"; }
/* In the walkthrough the menu is hidden; the globe stays, at the end. */
html.walkthrough .lang-menu { margin-inline-start: auto; }

/* The collapsed menu. `html.nav-collapsed` is set by `initNav` below 1200px
   and whenever the links and buttons don't fit on one row, which depends on
   the language (German and Portuguese labels run much longer than English). */
.nav-collapsed .lang-menu { order: 0; margin-inline: auto -14px; }

/* Full screen: a plain icon after the globe, on desktop only (the script
   shows it where the Fullscreen API works and the pointer is fine). */
.fullscreen-toggle {
  order: 4;
  flex: none;
  display: inline-grid;
  place-items: center;
  width: 28px;
  height: 44px;
  /* Right next to the globe (whose own padding is the space between). */
  margin-inline-start: -26px;
  border: 0;
  border-radius: 10px;
  background: none;
  color: var(--muted);
  filter: drop-shadow(0 1px 2px rgba(3, 7, 13, 0.7));
  cursor: pointer;
  transition: color 0.2s ease;
}
.fullscreen-toggle svg { max-width: none; }
.fullscreen-toggle:hover,
.fullscreen-toggle[aria-pressed="true"] { color: var(--accent); }
.fullscreen-toggle .icon-collapse,
.fullscreen-toggle[aria-pressed="true"] .icon-expand { display: none; }
.fullscreen-toggle[aria-pressed="true"] .icon-collapse { display: block; }
.fullscreen-toggle[hidden] { display: none; }
.nav-collapsed .fullscreen-toggle { order: 0; margin-inline: 6px -8px; }
@media (max-width: 959px), (pointer: coarse) {
  .fullscreen-toggle { display: none; }
}
/* The globe's auto margin pushes both icons to the end; the toggle's own
   `margin-left: auto` would split the space and strand the globe mid-bar. */
.nav-collapsed .nav-toggle { display: inline-flex; margin-left: 0; }
.nav-collapsed .site-menu {
    display: flex;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 20px;
    padding: 12px var(--gutter) 24px;
    /* A continuation of the top bar: the bar's exact tint and saturation,
       with a stronger blur so page text behind the links melts into a
       soft wash. No border between bar and sheet. */
    background: rgb(3 7 13 / 10%);
    -webkit-backdrop-filter: blur(34px) saturate(130%);
    backdrop-filter: blur(34px) saturate(130%);
    border-bottom: 1px solid var(--line);
    border-radius: 0;
    /* Subtle drop shadow; the open clip-path below leaves room for it. */
    box-shadow: 0 10px 24px rgba(3, 7, 13, 0.28), 0 2px 6px rgba(3, 7, 13, 0.18);
    text-shadow: var(--panel-read-shadow);
    max-height: calc(100vh - var(--header-h));
    overflow-y: auto;
    /* Closed: rolled up into the bar. Opening unrolls it from the top and
       fades it in; visibility keeps the hidden links out of the tab order. */
    /* The clip extends past the sides and bottom so the drop shadow isn't
       cut off. */
    clip-path: inset(0 -40px 100% -40px);
    opacity: 0;
    visibility: hidden;
    transition:
      clip-path 0.24s ease-in,
      opacity 0.2s ease-in 0.04s,
      visibility 0s linear 0.24s;
}
.nav-collapsed .nav-open .site-menu {
    clip-path: inset(0 -40px -48px -40px);
    opacity: 1;
    visibility: visible;
    transition:
      clip-path 0.32s cubic-bezier(0.2, 0.7, 0.2, 1),
      opacity 0.22s ease-out,
      visibility 0s;
}
.nav-collapsed .site-menu .btn { text-shadow: none; }
/* Bar and sheet read as one surface: drop the bar's bottom line. */
.nav-collapsed .site-header.nav-open { border-bottom-color: transparent; }
/* Without backdrop-filter the bar's 10% tint can't carry text over the
   page, so the sheet falls back to a dense slate of the same look. */
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .nav-collapsed .site-menu { background: rgba(34, 41, 49, 0.94); }
}
@media (prefers-reduced-motion: reduce) {
  .nav-collapsed .site-menu,
  .nav-collapsed .nav-open .site-menu {
    transition: opacity 0.1s linear, visibility 0s linear 0.1s;
    clip-path: none;
  }
  .nav-collapsed .nav-open .site-menu { transition: opacity 0.1s linear, visibility 0s; }
}
.nav-collapsed .site-nav ul { flex-direction: column; gap: 0; }
.nav-collapsed .site-nav a {
  display: block;
  padding: 14px 2px;
  font-size: 1.05rem;
  border-bottom: 1px solid var(--line);
}
.nav-collapsed .site-nav a[aria-current="true"]::after { display: none; }

/* Landscape phones: a compact brand, toggle and menu to fit the thin bar. */
@media (orientation: landscape) and (max-height: 500px) and (pointer: coarse) {
  .nav-collapsed .brand { gap: 10px; font-size: 1rem; }
  .nav-collapsed .brand-mark { width: 24px; height: 24px; }
  .nav-collapsed .brand-mark::before { inset: 6px; }
  .nav-collapsed .brand-mark::after { inset: 9.5px; }
  .nav-collapsed .nav-toggle { height: 40px; }
  .nav-collapsed .site-menu { gap: 12px; padding-block: 4px 14px; }
  .nav-collapsed .site-nav a { padding-block: 9px; font-size: 0.98rem; }
}

@media (max-width: 1279px) {
  /* Without JS: a horizontally scrollable link row instead of a menu. */
  html:not(.has-js) .site-header { height: auto; }
  html:not(.has-js) .header-inner { flex-wrap: wrap; padding-block: 12px; }
  html:not(.has-js) .site-menu { width: 100%; overflow-x: auto; }
}

/* ------------------------------------------------------------------ */
/* Type, buttons, shared pieces                                        */

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent-soft);
}
.eyebrow::before {
  content: "";
  width: 28px;
  height: 1px;
  background: var(--accent);
}
.eyebrow-index { color: var(--dim); }

h1 {
  font-family: var(--font-display);
  font-size: clamp(2.6rem, 6.4vw, 5.6rem);
  line-height: 1;
  letter-spacing: -0.035em;
  margin-block: 22px 26px;
  text-wrap: balance;
}
h2 {
  font-family: var(--font-display);
  font-size: clamp(2rem, 4.4vw, 3.5rem);
  line-height: 1.05;
  letter-spacing: -0.03em;
  text-wrap: balance;
}
h3, h4 {
  font-family: var(--font-display);
  font-size: 1.25rem;
  line-height: 1.25;
  letter-spacing: -0.01em;
}
.accent-text {
  color: var(--accent-soft);
  background: linear-gradient(90deg, var(--accent-start), var(--accent-soft) 60%, var(--accent-end));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  /* A text-shadow would show through the transparent fill; a drop-shadow
     filter applies to the painted gradient instead. */
  text-shadow: none;
  filter: drop-shadow(0 1px 2px rgba(3, 7, 13, 0.65)) drop-shadow(0 0 14px rgba(3, 7, 13, 0.55));
}

/* Text that sits directly on the 3D world gets the reading halo. Panels,
   buttons and chips have their own background, so they opt out. */
.hero-copy,
.section-head,
.benefits,
.legend,
.uses-heading,
.contact-card,
.site-footer,
.scroll-cue {
  text-shadow: var(--read-shadow);
}
.btn,
.chips li {
  text-shadow: none;
}
/* Panels are light glass, so their text always gets the lighter halo: the
   world shows through, sharp on the low tier or without backdrop-filter. */
.panel {
  text-shadow: var(--panel-read-shadow);
}
.panel .btn {
  text-shadow: none;
}

.lede,
.section-lede {
  color: var(--muted);
  font-size: clamp(1.05rem, 1.4vw, 1.2rem);
  line-height: 1.6;
  max-width: 38em;
}

.actions { display: flex; flex-wrap: wrap; gap: 12px; }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 12px 22px;
  border-radius: 12px;
  border: 1px solid transparent;
  font-weight: 600;
  font-size: 0.95rem;
  line-height: 1.2;
  transition: background-color 0.2s ease, border-color 0.2s ease, transform 0.2s var(--ease);
}
.btn-small { min-height: 40px; padding: 8px 16px; font-size: 0.88rem; }
.btn-primary {
  background: var(--accent);
  color: #02121b;
}
.btn-primary:hover { background: var(--accent-soft); }
.btn-ghost {
  border-color: var(--line-strong);
  background: rgba(255, 255, 255, 0.03);
  color: var(--text);
}
.btn-ghost:hover { border-color: rgba(var(--accent-rgb), 0.5); background: rgba(var(--accent-rgb), 0.06); }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .btn:hover { transform: translateY(-1px); }
}

/* Glass panels: translucent tint over a blurred view of the world, with a
   faint top highlight. On the low tier they stay translucent but drop the
   blur, the only costly part over a live WebGL backdrop. A faint light
   frost stands in for the milky lift a blur gives, so they read like the
   blurred panels. Without backdrop-filter support, the same unblurred
   glass is used. */
.panel {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.02) 40%),
    linear-gradient(rgba(170, 190, 210, 0.06), rgba(170, 190, 210, 0.06)),
    rgba(8, 15, 24, 0.38);
  border: 1px solid rgba(190, 220, 240, 0.18);
  border-radius: var(--radius);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.08),
    0 18px 50px rgba(0, 0, 0, 0.28);
}
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  html:not(.q-low) .panel {
    background:
      linear-gradient(180deg, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0.015) 40%),
      rgba(6, 13, 22, 0.3);
    border-color: rgba(190, 220, 240, 0.18);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.08),
      0 18px 50px rgba(0, 0, 0, 0.28);
    -webkit-backdrop-filter: blur(22px) saturate(140%);
    backdrop-filter: blur(22px) saturate(140%);
  }
  /* Phones: lighter blur keeps scrolling smooth over the live canvas. */
  @media (pointer: coarse) {
    html:not(.q-low) .panel {
      background:
        linear-gradient(180deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.01) 40%),
        rgba(6, 13, 22, 0.42);
      -webkit-backdrop-filter: blur(12px) saturate(130%);
      backdrop-filter: blur(12px) saturate(130%);
    }
  }
}

/* ------------------------------------------------------------------ */
/* Sections                                                            */

.section {
  padding-block: clamp(96px, 16vh, 180px);
}
/* Phones and narrow screens: the world's captions live in the gaps between
   sections (the text fills the width), so the gaps are taller. */
@media (max-width: 959px) {
  .section {
    padding-block: clamp(136px, 24vh, 240px);
  }
}
.section-head {
  display: grid;
  gap: 18px;
  max-width: 760px;
  margin-bottom: clamp(40px, 6vh, 64px);
}

/* Hero */
.hero {
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-top: calc(var(--header-h) + 48px);
  /* Room for the scroll cue (bottom 28px, about 80px tall) under the copy,
     also when the copy is taller than the screen (phones). */
  padding-bottom: 128px;
  position: relative;
}
.hero-copy { max-width: 760px; }
.hero .lede { margin-bottom: 14px; }
/* The hero's closing line, in bold under the lede. */
.hero-tagline {
  margin-bottom: 34px;
  color: var(--text);
  font-size: clamp(1.05rem, 1.4vw, 1.2rem);
  font-weight: 600;
  line-height: 1.5;
}
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 36px;
}
.chips li {
  padding: 7px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(3, 7, 13, 0.5);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
.scroll-cue {
  position: absolute;
  left: 50%;
  bottom: 28px;
  transform: translateX(-50%);
  display: grid;
  justify-items: center;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--dim);
}
.scroll-cue::after {
  content: "";
  width: 1px;
  height: 36px;
  background: linear-gradient(180deg, var(--accent), transparent);
}
@media (prefers-reduced-motion: no-preference) {
  .scroll-cue::after { animation: cue 2.8s var(--ease) infinite; transform-origin: top; }
}
@keyframes cue {
  0% { transform: scaleY(0); opacity: 0; }
  30% { transform: scaleY(1); opacity: 1; }
  100% { transform: scaleY(1); opacity: 0; }
}
@media (max-height: 620px) { .scroll-cue { display: none; } }

/* 01 · Compare */
.compare {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  max-width: 900px;
  margin-bottom: 16px;
}
.compare-card {
  display: grid;
  gap: 10px;
  align-content: start;
  padding: 28px;
}
.compare-card > p:not([class]) { color: var(--muted); }
.compare-label {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
}
.sample {
  margin-top: 8px;
  padding: 12px 14px;
  border-radius: 10px;
  border: 1px dashed var(--line-strong);
  font-family: var(--font-mono);
  font-size: 0.85rem;
  color: #d7e6f1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sample-opaque { color: rgba(65, 230, 173, 0.75); letter-spacing: 0.1em; }
.status {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.status-warn { color: var(--warn); }
.status-ok { color: var(--green); }
.is-opaque { border-color: rgba(65, 230, 173, 0.3); }

.feature-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}
.feature { padding: 26px; display: grid; gap: 10px; align-content: start; }
.feature p { color: var(--muted); font-size: 0.98rem; }
.feature-icon {
  width: 36px;
  height: 36px;
  border-radius: 10px;
  border: 1px solid var(--line-strong);
  position: relative;
  margin-bottom: 6px;
}
.feature-icon::after {
  content: "";
  position: absolute;
  inset: 10px;
  border: 1px solid var(--accent);
}
.icon-blind::after { background: repeating-linear-gradient(90deg, var(--accent) 0 2px, transparent 2px 5px); border-color: transparent; }
.icon-custody::after { border-radius: 50%; border-color: var(--green); }
.icon-infra::after { inset: 9px 8px; border-radius: 2px; box-shadow: 0 -5px 0 -3px var(--accent); }

/* 02 · Pillars */
.pillars {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}
.pillar {
  padding: 30px;
  display: grid;
  gap: 12px;
  align-content: start;
  transition: border-color 0.4s ease;
}
.pillar p:not([class]) { color: var(--muted); }
.pillar-num {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--green);
}
.audit-log {
  margin-top: 8px;
  display: grid;
  gap: 6px;
  padding: 14px 16px;
  border-radius: 10px;
  background: rgba(0, 0, 0, 0.3);
  border: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--dim);
  overflow-x: auto;
}
.audit-log li { white-space: nowrap; }
.audit-log time { color: var(--muted); margin-right: 8px; }
.audit-log span { color: var(--cyan-soft); display: inline-block; min-width: 9ch; }

/* 03 · Pipeline */
.pipeline {
  list-style: none;
  display: grid;
  grid-template-columns: 1fr auto 1fr auto 1fr;
  align-items: center;
  padding: 28px;
  margin-bottom: clamp(40px, 6vh, 64px);
  max-width: 1040px;
}
.stage { display: grid; gap: 6px; align-content: start; text-align: center; padding: 10px; }
.stage-note { color: var(--muted); font-size: 0.9rem; line-height: 1.5; max-width: 22em; margin-inline: auto; }
.pipeline .stage:nth-child(2) { grid-column: 3; }
.pipeline .stage:nth-child(3) { grid-column: 5; }
.pipeline::before,
.pipeline::after {
  content: "";
  grid-row: 1;
  height: 1px;
  width: clamp(24px, 6vw, 80px);
  background: linear-gradient(90deg, var(--cyan), var(--green));
}
.pipeline::before { grid-column: 2; }
.pipeline::after { grid-column: 4; }
.stage-label {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dim);
}
.stage-title { font-family: var(--font-display); font-size: 1.12rem; font-weight: 600; }
.stage-core {
  border: 1px solid rgba(23, 199, 255, 0.4);
  border-radius: 14px;
  padding: 18px 20px;
  background: rgba(2, 5, 9, 0.45);
  box-shadow: 0 0 40px rgba(23, 199, 255, 0.08);
}

.legend {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 24px;
  margin: calc(-1 * clamp(40px, 6vh, 64px) + 20px) 0 clamp(40px, 6vh, 64px);
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.04em;
  color: var(--muted);
}
.legend li { display: inline-flex; align-items: center; gap: 10px; }
.legend-title {
  color: var(--dim);
  text-transform: uppercase;
  letter-spacing: 0.16em;
}
.swatch { width: 22px; height: 3px; border-radius: 2px; }
.swatch-clear { background: var(--cyan); box-shadow: 0 0 8px rgba(23, 199, 255, 0.6); }
.swatch-response { background: var(--green); box-shadow: 0 0 8px rgba(65, 230, 173, 0.6); }
.swatch-obfuscated {
  background: repeating-linear-gradient(90deg, #a66bff 0 3px, transparent 3px 5px, #7448c2 5px 7px, transparent 7px 9px);
  box-shadow: 0 0 8px rgba(166, 107, 255, 0.45);
}

.benefits {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 32px;
  max-width: 1000px;
}
/* The benefits list is also a camera stop (the output end of the model):
   leave scroll room after it so the view can settle there before Security. */
.has-js #blind-processing { padding-bottom: 45vh; }
/* Phones frame each subject above the text, but here the legend ran straight
   into the benefits list, so the output end (and its captions) had no free
   band at its own stop. The gap is that band: at the stop the list's top sits
   at 35% of the viewport and the legend has scrolled away above. */
@media (max-width: 959px) {
  .has-js .benefits { margin-top: 40vh; }
}
.benefits li {
  display: grid;
  gap: 8px;
  padding-top: 18px;
  border-top: 1px solid var(--line-strong);
}
.benefits p { color: var(--muted); font-size: 0.98rem; }

/* 04 · Deployment */
.deploy-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}
.deploy { padding: 30px; display: grid; gap: 10px; align-content: start; }
.deploy p:not([class]) { color: var(--muted); }
.deploy-sub { color: var(--accent-soft); font-weight: 500; }
.deploy-tag {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  justify-self: start;
  margin-bottom: 8px;
  padding: 5px 10px;
  border-radius: 999px;
  border: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--muted);
}
.dot { width: 6px; height: 6px; border-radius: 50%; background: var(--cyan); }
.dot-ice { background: var(--ice); }
.dot-green { background: var(--green); }

/* 05 · Engine */
.engine-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  gap: 16px;
  align-items: start;
}
.specs { margin: 0; padding: 8px 28px; }
.specs > div {
  display: grid;
  grid-template-columns: 9.5rem minmax(0, 1fr);
  gap: 16px;
  padding-block: 18px;
}
.specs > div + div { border-top: 1px solid var(--line); }
.specs dt {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--green);
  padding-top: 3px;
}
.specs dd { margin: 0; color: var(--muted); }
code {
  font-family: var(--font-mono);
  font-size: 0.88em;
  color: var(--text);
}
.engine-side { display: grid; gap: 16px; }
.stat { margin: 0; padding: 24px; display: grid; gap: 10px; }
.stat-value {
  font-family: var(--font-display);
  font-size: clamp(2.2rem, 4vw, 3rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--accent-soft);
}
.stat-value span { color: var(--text); font-size: 0.5em; letter-spacing: -0.01em; }
.stat figcaption { color: var(--muted); font-size: 0.95rem; }
.stat strong { color: var(--text); font-weight: 600; }

/* 06 · OmnyBit: stats, then the compare and feature patterns of 01. */
.ob-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
  max-width: 900px;
  margin-bottom: 16px;
}
.ob-stats .stat-value span { font-size: 0.42em; }
.feature-grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.icon-search::after { border-radius: 50%; inset: 9px; }
.icon-ops::after {
  content: "±";
  inset: 0;
  border: 0;
  display: grid;
  place-items: center;
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 1.05rem;
}
.icon-device::after {
  inset: 7px 12px;
  border-radius: 2px;
  background: linear-gradient(0deg, var(--accent) 0 68%, transparent 68%);
  border-color: var(--line-strong);
}
.ob-status {
  margin-top: 18px;
  max-width: 720px;
  color: var(--dim);
  font-size: 0.9rem;
}
.terminal { margin: 0; padding: 22px 24px; min-width: 0; }
.terminal figcaption {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
  margin-bottom: 14px;
}
.terminal pre {
  margin: 0;
  overflow-x: auto;
  font-size: 0.9rem;
  line-height: 1.9;
}
.prompt { color: var(--accent); user-select: none; -webkit-user-select: none; }

/* 06 · Uses */
.uses-heading {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dim);
  margin-bottom: 16px;
}
.uses {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
}
.uses + .uses-heading { margin-top: clamp(40px, 6vh, 56px); }
.uses-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.use h4 { font-size: 1.2rem; line-height: 1.25; }
.use { padding: 26px; display: grid; gap: 10px; align-content: start; }
.use p { color: var(--muted); font-size: 0.98rem; }
.use-num {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--accent-soft);
  margin-bottom: 18px;
}

/* 07 · Contact */
.contact { padding-block: clamp(120px, 24vh, 260px) clamp(96px, 16vh, 180px); }
.contact-card {
  display: grid;
  gap: 22px;
  max-width: 820px;
}
.contact-card .actions { margin-top: 8px; }

.site-footer {
  border-top: 1px solid var(--line);
  background: rgb(3 7 13 / 10%);
  padding-block: 36px calc(36px + env(safe-area-inset-bottom));
  color: var(--dim);
  font-size: 0.9rem;
}
.footer-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 32px;
}
.brand-footer { color: var(--text); font-size: 1rem; }
.copyright { margin-left: auto; }

/* Language picker (filled and shown by the script, lib/src/ui/i18n.dart). */
.lang-picker {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.85rem;
  color: var(--dim);
}
.lang-picker[hidden] { display: none; }
.lang-picker select {
  appearance: none;
  -webkit-appearance: none;
  min-height: 36px;
  padding: 6px 30px 6px 12px;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  background:
    linear-gradient(45deg, transparent 50%, var(--muted) 50%) right 15px center / 5px 5px no-repeat,
    linear-gradient(-45deg, transparent 50%, var(--muted) 50%) right 10px center / 5px 5px no-repeat,
    rgba(255, 255, 255, 0.04);
  color: var(--text);
  font: inherit;
  cursor: pointer;
}
.lang-picker select:hover { border-color: rgba(var(--accent-rgb), 0.5); }
/* The open list is drawn by the system: give it a readable dark ground. */
.lang-picker option { background: #0b1119; color: var(--text); }
html[dir="rtl"] .lang-picker select {
  padding: 6px 12px 6px 30px;
  background-position: left 10px center, left 15px center, 0 0;
}

/* ------------------------------------------------------------------ */
/* Right-to-left (Arabic)                                              */

/* Most of the layout mirrors on its own (flex rows, grids, auto margins).
   Two things must not: on wide screens the 3D camera frames each subject to
   the right of the text column, so the column stays on the left (its text
   still reads right to left); and the world's captions are placed in screen
   pixels, so their layer stays left-to-right (their text still reads right
   to left). */
@media (min-width: 960px) {
  html[dir="rtl"] :is(.hero-copy, .section-head, .contact-card, .benefits, .legend) {
    margin-left: 0;
    margin-right: auto;
  }
}
html[dir="rtl"] .world-labels { direction: ltr; }
html[dir="rtl"] .world-label-box { unicode-bidi: plaintext; }

/* Arabic is cursive: letter-spacing (the eyebrows, captions and tags use
   wide tracking) would break the joins between letters. */
html[lang="ar"] body * { letter-spacing: 0 !important; }

/* ------------------------------------------------------------------ */
/* Responsive                                                          */

@media (max-width: 1100px) {
  .uses { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .uses-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .engine-grid { grid-template-columns: 1fr; }
  .engine-side { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .deploy-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .feature-grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 820px) {
  .compare,
  .feature-grid,
  .ob-stats,
  .pillars,
  .deploy-grid,
  .engine-side,
  .uses-3,
  .benefits { grid-template-columns: 1fr; }
  .benefits { gap: 24px; }
  .pipeline {
    grid-template-columns: 1fr;
    justify-items: stretch;
    gap: 0;
  }
  .pipeline::before,
  .pipeline::after { display: none; }
  .pipeline .stage:nth-child(n) { grid-column: 1; }
  .pipeline .stage + .stage { margin-top: 28px; position: relative; }
  .pipeline .stage + .stage::before {
    content: "";
    position: absolute;
    left: 50%;
    top: -24px;
    width: 1px;
    height: 20px;
    background: linear-gradient(180deg, var(--cyan), var(--green));
  }
  .copyright { margin-left: 0; }
}

@media (max-width: 560px) {
  .uses { grid-template-columns: 1fr; }
  .compare-card, .feature, .pillar, .deploy, .use { padding: 22px; }
  .specs { padding: 4px 20px; }
  .specs > div { grid-template-columns: 1fr; gap: 6px; }
  .actions .btn { flex: 1 1 auto; }
}

/* ------------------------------------------------------------------ */
/* 3D walkthrough                                                      */

/* Entry buttons: `.btn` sets a display, which would override `hidden`. */
.walkthrough-open[hidden] { display: none; }
.walkthrough-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 14px;
}

/* The page text fades out and stops scrolling; the header stays (brand only)
   with its glass on, and the scrim lightens so the world reads clearly. */
html.walkthrough { overflow: hidden; }
main,
.site-footer {
  transition: opacity 0.45s ease, visibility 0s linear 0s;
}
html.walkthrough main,
html.walkthrough .site-footer {
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.45s ease, visibility 0s linear 0.45s;
}
html.walkthrough .site-menu,
html.walkthrough .nav-toggle { display: none; }
html.walkthrough .site-header { border-bottom-color: var(--line); }
html.walkthrough .site-header::before { background: rgb(3 7 13 / 10%); }
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  html.walkthrough .site-header::before {
    -webkit-backdrop-filter: blur(16px) saturate(130%);
    backdrop-filter: blur(16px) saturate(130%);
  }
}
.world-scrim { transition: opacity 0.6s ease; }
html.walkthrough .world-scrim { opacity: 0.45; }

/* The bar: a glass sheet along the bottom, like the top bar's. */
.walkthrough-bar {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 25;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px 24px;
  padding: 18px max(var(--gutter), calc((100vw - var(--max)) / 2))
    calc(16px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--line);
  background: rgb(3 7 13 / 55%);
  text-shadow: var(--panel-read-shadow);
}
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .walkthrough-bar {
    background: rgb(3 7 13 / 22%);
    -webkit-backdrop-filter: blur(20px) saturate(130%);
    backdrop-filter: blur(20px) saturate(130%);
  }
}
.walkthrough-bar[hidden] { display: none; }
@media (prefers-reduced-motion: no-preference) {
  .walkthrough-bar { animation: walk-in 0.4s var(--ease) both; }
}
@keyframes walk-in {
  from { opacity: 0; transform: translateY(12px); }
}
.walk-copy { min-width: 0; }
.walk-step {
  font: 500 0.72rem/1 var(--font-mono);
  letter-spacing: 0.18em;
  color: var(--accent);
}
.walk-title {
  margin-top: 6px;
  font: 600 clamp(1.15rem, 2vw, 1.45rem)/1.2 var(--font-display);
  color: var(--text);
}
.walk-text {
  margin-top: 6px;
  max-width: 62ch;
  color: var(--muted);
  font-size: 0.95rem;
  line-height: 1.5;
}
.walk-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
/* At the walkthrough's last stop: on to the OmnyBit presentation. */
.walk-tour { margin-inline-start: 8px; }
.walk-tour[hidden] { display: none; }
.walk-btn {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  border: 1px solid var(--line-strong);
  background: rgba(255, 255, 255, 0.04);
  color: var(--text);
  font-size: 1.1rem;
  cursor: pointer;
  transition: border-color 0.2s ease, background-color 0.2s ease, opacity 0.2s ease;
}
.walk-btn:hover:not(:disabled) {
  border-color: rgba(var(--accent-rgb), 0.5);
  background: rgba(var(--accent-rgb), 0.08);
}
.walk-btn:disabled { opacity: 0.35; cursor: default; }
.walk-exit { margin-inline-start: 8px; }
.walk-hint {
  grid-column: 1 / -1;
  font: 400 0.7rem/1.3 var(--font-mono);
  letter-spacing: 0.06em;
  color: var(--dim);
}
/* Touch screens: swipes, no keys — keep the hint short. */
@media (pointer: coarse) {
  .walk-hint { display: none; }
}
@media (max-width: 560px) {
  .walkthrough-bar { grid-template-columns: 1fr; padding-top: 14px; }
  .walk-text { font-size: 0.88rem; }
  .walk-controls { justify-content: space-between; }
  .walk-exit { margin-inline-start: auto; }
  /* A row of its own, above the arrows. */
  .walk-tour { order: -1; flex-basis: 100%; margin-inline-start: 0; }
}
/* Landscape phones: one compact row, so the world keeps the height. */
@media (orientation: landscape) and (max-height: 500px) and (pointer: coarse) {
  .walkthrough-bar {
    padding-top: 10px;
    padding-bottom: calc(10px + env(safe-area-inset-bottom));
    padding-inline: max(var(--gutter), env(safe-area-inset-left)) max(var(--gutter), env(safe-area-inset-right));
  }
  .walk-title { margin-top: 3px; font-size: 1.05rem; }
  .walk-text {
    margin-top: 3px;
    font-size: 0.82rem;
    line-height: 1.35;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
}

/* ------------------------------------------------------------------ */
/* Reveal on scroll (only once JS has opted in with .reveal)           */

[data-reveal] {
  transition: opacity 0.9s ease, transform 0.9s var(--ease);
}
.reveal [data-reveal]:not(.is-visible) {
  opacity: 0;
  transform: translateY(18px);
}
@media (prefers-reduced-motion: reduce) {
  .reveal [data-reveal]:not(.is-visible) { transform: none; }
  [data-reveal] { transition: opacity 0.3s linear; }
}

/* Hero entrance: CSS-only, so it never waits on the script. */
@media (prefers-reduced-motion: no-preference) {
  .hero-copy > * { animation: rise 1s var(--ease) both; }
  .hero-copy > :nth-child(2) { animation-delay: 0.08s; }
  .hero-copy > :nth-child(3) { animation-delay: 0.16s; }
  .hero-copy > :nth-child(4) { animation-delay: 0.24s; }
  .hero-copy > :nth-child(5) { animation-delay: 0.32s; }
}
@keyframes rise {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}

/* ------------------------------------------------------------------ */
/* ?debug overlay                                                      */

.debug-overlay {
  position: fixed;
  right: 12px;
  bottom: 12px;
  z-index: 50;
  padding: 8px 10px;
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.75);
  color: #9ef0c8;
  font: 11px/1.5 var(--font-mono);
  white-space: pre;
  cursor: copy;
  user-select: none;
  -webkit-user-select: none;
}
.debug-overlay:hover { background: rgba(0, 0, 0, 0.88); }
.debug-overlay[data-flash]::after {
  content: attr(data-flash);
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  border-radius: inherit;
  background: rgba(0, 0, 0, 0.9);
  color: #9ef0c8;
  font-weight: 600;
}

@media print {
  .world-poster, .world-canvas, .world-scrim, .scroll-cue, .nav-toggle,
  .walkthrough-open, .walkthrough-bar { display: none; }
  body { background: #fff; color: #000; }
  .site-header { position: static; }
}
