/*
 * varnir.site homepage.
 *
 * Deliberately dark-only. `apps/scanner-web` is a token-driven app with a
 * real light/dark/system toggle because people work in it all day; this is
 * a single marketing page with one committed visual identity, and a
 * half-hearted light variant of a design built on glowing gradients over a
 * near-black ground reads worse than not offering one. `color-scheme: dark`
 * is declared so browser UI (scrollbars, form controls) matches rather than
 * flashing white.
 *
 * The accent hues are the same family as scanner-web's design tokens
 * (indigo primary, cyan/emerald/amber signals) so the two sites read as one
 * product, just pitched brighter here.
 */

:root {
  --ink: #f2f4fb;
  --ink-soft: #b5bcd4;
  --ink-mute: #7d859f;
  --ink-faint: #565d76;

  --bg: #07080d;
  --bg-raise: #0d0f18;
  --bg-tint: #0a0c14;
  --edge: #1e2233;
  --edge-soft: #171a28;

  --indigo: #7b86ff;
  --cyan: #22d3ee;
  --violet: #a855f7;
  --emerald: #34d399;
  --amber: #fbbf24;

  --shell: 1140px;
  --radius: 16px;

  --font: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Inter, Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;

  color-scheme: dark;
}

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

html {
  scroll-behavior: smooth;
  /* The sticky topbar would otherwise cover an anchored heading. */
  scroll-padding-top: 96px;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.65;
  letter-spacing: -0.005em;
  -webkit-font-smoothing: antialiased;
  /* Every decorative layer is fixed and offset - without this a wide orb
     can extend the document sideways on narrow screens. */
  overflow-x: hidden;
}

img,
svg {
  max-width: 100%;
}

a {
  color: inherit;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 0.75rem 1.25rem;
  background: var(--indigo);
  color: #06070c;
  font-weight: 600;
  border-radius: 0 0 10px 0;
}

.skip-link:focus-visible {
  left: 0;
}

:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 3px;
  border-radius: 4px;
}

.shell {
  width: 100%;
  max-width: var(--shell);
  margin: 0 auto;
  padding: 0 clamp(1.25rem, 5vw, 2.5rem);
}

.shell--narrow {
  max-width: 760px;
}

/* ───────────────────────── scroll progress ───────────────────────── */

.progress {
  position: fixed;
  inset: 0 0 auto 0;
  height: 2px;
  z-index: 60;
  background: transparent;
  pointer-events: none;
}

.progress span {
  display: block;
  height: 100%;
  width: 0;
  background: linear-gradient(90deg, var(--indigo), var(--cyan));
  box-shadow: 0 0 12px rgb(34 211 238 / 0.5);
}

/* ─────────────────────── parallax backdrop ───────────────────────── */

.backdrop {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}

/* A perspective-tilted grid that drifts as you scroll - the base "floor"
   of the whole page. */
.grid-plane {
  position: absolute;
  left: -25%;
  right: -25%;
  top: -10%;
  height: 150%;
  background-image:
    linear-gradient(to right, rgb(123 134 255 / 0.07) 1px, transparent 1px),
    linear-gradient(to bottom, rgb(123 134 255 / 0.07) 1px, transparent 1px);
  background-size: 68px 68px;
  transform: perspective(680px) rotateX(58deg) scale(1.9);
  transform-origin: 50% 0%;
  mask-image: radial-gradient(ellipse 80% 55% at 50% 30%, #000 20%, transparent 78%);
  -webkit-mask-image: radial-gradient(ellipse 80% 55% at 50% 30%, #000 20%, transparent 78%);
  will-change: transform;
}

.orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  opacity: 0.42;
  will-change: transform;
}

.orb--indigo {
  width: 46vw;
  height: 46vw;
  min-width: 340px;
  min-height: 340px;
  top: -8vh;
  left: -6vw;
  background: radial-gradient(circle at 35% 35%, #4d5bff, transparent 68%);
}

.orb--cyan {
  width: 38vw;
  height: 38vw;
  min-width: 280px;
  min-height: 280px;
  top: 22vh;
  right: -8vw;
  background: radial-gradient(circle at 60% 40%, #0fb9d6, transparent 68%);
  opacity: 0.34;
}

.orb--violet {
  width: 42vw;
  height: 42vw;
  min-width: 300px;
  min-height: 300px;
  top: 62vh;
  left: 18vw;
  background: radial-gradient(circle at 50% 50%, #8b3ff5, transparent 70%);
  opacity: 0.26;
}

.vignette {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 120% 80% at 50% 0%, transparent 30%, rgb(7 8 13 / 0.75) 78%),
    linear-gradient(180deg, transparent 55%, var(--bg) 96%);
}

/* Fine grain over the gradients - stops the large soft blurs from banding
   on 8-bit displays. Inline SVG so there is no image request. */
.noise {
  position: absolute;
  inset: -50%;
  opacity: 0.035;
  background-image: 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.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ───────────────────────────── topbar ────────────────────────────── */

.topbar {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  gap: 1.5rem;
  padding: 0.9rem clamp(1.25rem, 5vw, 2.5rem);
  /* Deliberately transparent and un-blurred at rest. A blurred bar over
     the hero's gradient orbs draws a hard horizontal seam across the top
     of the page where the filter region ends - very visible against a
     soft gradient. Both only switch on once the bar is actually stuck,
     where the border-bottom makes that edge read as intentional. */
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background 0.3s ease, border-color 0.3s ease;
}

.topbar.is-stuck {
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  background: rgb(7 8 13 / 0.82);
  border-bottom-color: var(--edge-soft);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  font-weight: 700;
  letter-spacing: -0.03em;
  font-size: 1.15rem;
  margin-right: auto;
}

.brand__mark {
  width: 26px;
  height: 26px;
  flex: none;
}

.topnav {
  display: flex;
  gap: 1.75rem;
  font-size: 0.94rem;
  color: var(--ink-soft);
}

.topnav a {
  text-decoration: none;
  position: relative;
  padding-bottom: 2px;
  transition: color 0.2s ease;
}

.topnav a::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  height: 1px;
  width: 0;
  background: linear-gradient(90deg, var(--indigo), var(--cyan));
  transition: width 0.25s ease;
}

.topnav a:hover {
  color: var(--ink);
}

.topnav a:hover::after {
  width: 100%;
}

.topbar__actions {
  display: flex;
  gap: 0.6rem;
}

/* ─────────────────────────── mobile nav menu ─────────────────────── */

/* Hidden entirely above the breakpoint where .topnav and the ghost
   action buttons disappear - see the responsive section below. Markup
   is a native <details>/<summary>, so it exists and works with zero JS;
   main.js only layers on outside-click / Escape / on-select closing. */
.nav-menu {
  display: none;
}

.nav-menu__toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  flex: none;
  border-radius: 10px;
  border: 1px solid var(--edge);
  background: rgb(255 255 255 / 0.02);
  color: var(--ink-soft);
  list-style: none;
  cursor: pointer;
  transition: border-color 0.22s ease, background 0.22s ease, color 0.22s ease;
}

.nav-menu__toggle::-webkit-details-marker {
  display: none;
}

.nav-menu__toggle::marker {
  content: "";
}

.nav-menu__toggle:hover,
.nav-menu[open] > .nav-menu__toggle {
  border-color: #39405c;
  background: rgb(255 255 255 / 0.05);
  color: var(--ink);
}

/* Three bars drawn from one element + two pseudo-elements, so the same
   box can morph into an × when the menu is open rather than swapping
   icons. */
.nav-menu__bars,
.nav-menu__bars::before,
.nav-menu__bars::after {
  display: block;
  width: 18px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transition: transform 0.22s ease, opacity 0.22s ease, background 0.22s ease;
}

.nav-menu__bars {
  position: relative;
}

.nav-menu__bars::before,
.nav-menu__bars::after {
  content: "";
  position: absolute;
  left: 0;
}

.nav-menu__bars::before {
  top: -6px;
}

.nav-menu__bars::after {
  top: 6px;
}

.nav-menu[open] .nav-menu__bars {
  background: transparent;
}

.nav-menu[open] .nav-menu__bars::before {
  top: 0;
  transform: rotate(45deg);
}

.nav-menu[open] .nav-menu__bars::after {
  top: 0;
  transform: rotate(-45deg);
}

.nav-menu__panel {
  position: absolute;
  right: 0;
  top: calc(100% + 0.6rem);
  z-index: 5;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 200px;
  padding: 0.5rem;
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  background: var(--bg-raise);
  box-shadow: 0 20px 50px rgb(0 0 0 / 0.45);
}

.nav-menu__panel a {
  padding: 0.65rem 0.75rem;
  border-radius: 8px;
  font-size: 0.95rem;
  color: var(--ink-soft);
  text-decoration: none;
  transition: background 0.2s ease, color 0.2s ease;
}

.nav-menu__panel a:hover,
.nav-menu__panel a:focus-visible {
  background: rgb(255 255 255 / 0.05);
  color: var(--ink);
}

.nav-menu__sep {
  height: 1px;
  margin: 0.4rem 0.35rem;
  background: var(--edge-soft);
}

/* ───────────────────────────── buttons ───────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.6rem 1.05rem;
  border-radius: 10px;
  font-size: 0.92rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  border: 1px solid transparent;
  transition: transform 0.18s ease, background 0.22s ease, border-color 0.22s ease, box-shadow 0.22s ease;
}

.btn--lg {
  padding: 0.85rem 1.5rem;
  font-size: 1rem;
  border-radius: 12px;
}

.btn--solid {
  background: linear-gradient(135deg, #5f6bff, #4c5cf5 55%, #2f9fd6);
  color: #fff;
  box-shadow: 0 6px 24px rgb(76 92 245 / 0.32);
}

.btn--solid:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 34px rgb(76 92 245 / 0.45);
}

.btn--ghost {
  border-color: var(--edge);
  color: var(--ink-soft);
  background: rgb(255 255 255 / 0.02);
}

.btn--ghost:hover {
  border-color: #39405c;
  color: var(--ink);
  background: rgb(255 255 255 / 0.05);
  transform: translateY(-2px);
}

.btn__arrow {
  width: 17px;
  height: 17px;
  flex: none;
  transition: transform 0.2s ease;
}

.btn:hover .btn__arrow {
  transform: translateX(3px);
}

/* ────────────────────────────── hero ─────────────────────────────── */

main {
  position: relative;
  z-index: 1;
}

.hero {
  position: relative;
  min-height: calc(100svh - 62px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: clamp(4rem, 12vh, 9rem) 0 clamp(5rem, 14vh, 10rem);
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0 0 1.75rem;
  padding: 0.4rem 0.9rem 0.4rem 0.7rem;
  border: 1px solid var(--edge);
  border-radius: 999px;
  background: rgb(255 255 255 / 0.025);
  font-size: 0.82rem;
  color: var(--ink-soft);
  letter-spacing: 0.01em;
}

.dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--emerald);
  box-shadow: 0 0 0 0 rgb(52 211 153 / 0.6);
  animation: pulse 2.4s ease-out infinite;
}

@keyframes pulse {
  0% {
    box-shadow: 0 0 0 0 rgb(52 211 153 / 0.55);
  }
  70% {
    box-shadow: 0 0 0 9px rgb(52 211 153 / 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgb(52 211 153 / 0);
  }
}

.hero__title {
  margin: 0 0 1.6rem;
  /* The 2.2rem floor is measured, not guessed. The title's line breaks are
     hard <br>s, so its longest line ("AI agents can be") cannot reflow -
     at a 320px viewport that line renders 293px wide at a 2.6rem floor,
     against the 280px the shell's padding leaves. 2.2rem brings it to
     ~248px, with headroom for font fallback. Above ~360px the 7.2vw term
     takes over and this floor stops applying at all. */
  font-size: clamp(2.2rem, 7.2vw, 5.1rem);
  line-height: 1.03;
  letter-spacing: -0.045em;
  font-weight: 700;
  will-change: transform;
}

.grad {
  background: linear-gradient(100deg, #8b95ff 0%, #22d3ee 55%, #6ee7b7 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.grad-warn {
  background: linear-gradient(100deg, #fbbf24, #f97362);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.grad-good {
  background: linear-gradient(100deg, #34d399, #22d3ee);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.hero__lede {
  max-width: 58ch;
  margin: 0 0 2.4rem;
  font-size: clamp(1.05rem, 1.9vw, 1.28rem);
  color: var(--ink-soft);
}

.hero__lede em {
  font-style: normal;
  color: var(--ink);
  border-bottom: 1px solid rgb(123 134 255 / 0.45);
}

.hero__cta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
  margin-bottom: 3rem;
}

.hero__honesty {
  max-width: 62ch;
  margin: 0;
  padding: 1rem 1.25rem;
  border-left: 2px solid rgb(251 191 36 / 0.55);
  border-radius: 0 10px 10px 0;
  background: rgb(251 191 36 / 0.05);
  font-size: 0.94rem;
  color: var(--ink-mute);
}

.hero__honesty strong {
  color: var(--amber);
}

.scroll-hint {
  position: absolute;
  left: 50%;
  bottom: 2.2rem;
  transform: translateX(-50%);
  width: 22px;
  height: 34px;
  border: 1px solid var(--edge);
  border-radius: 12px;
  display: flex;
  justify-content: center;
  padding-top: 6px;
}

.scroll-hint span {
  width: 3px;
  height: 7px;
  border-radius: 2px;
  background: var(--ink-faint);
  animation: drop 1.9s ease-in-out infinite;
}

@keyframes drop {
  0%,
  100% {
    transform: translateY(0);
    opacity: 0;
  }
  30% {
    opacity: 1;
  }
  70% {
    transform: translateY(11px);
    opacity: 0;
  }
}

/* ──────────────────────────── sections ───────────────────────────── */

.section {
  position: relative;
  padding: clamp(5rem, 13vh, 9rem) 0;
}

.section--tinted {
  background: linear-gradient(180deg, transparent, rgb(13 15 24 / 0.75) 12%, rgb(13 15 24 / 0.75) 88%, transparent);
  border-top: 1px solid var(--edge-soft);
  border-bottom: 1px solid var(--edge-soft);
}

.section__num {
  margin: 0 0 1.1rem;
  font-family: var(--mono);
  font-size: 0.8rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.section__title {
  margin: 0 0 1.4rem;
  max-width: 20ch;
  font-size: clamp(2rem, 4.6vw, 3.15rem);
  line-height: 1.1;
  letter-spacing: -0.035em;
  font-weight: 700;
}

.section__lede {
  max-width: 66ch;
  margin: 0 0 3.5rem;
  font-size: clamp(1rem, 1.6vw, 1.15rem);
  color: var(--ink-soft);
}

.section__lede em {
  font-style: normal;
  color: var(--ink);
}

/* ──────────────────────────── problem ────────────────────────────── */

.problems {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1.15rem;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}

.problem {
  position: relative;
  padding: 1.9rem 1.6rem 1.6rem;
  border: 1px solid var(--edge-soft);
  border-radius: var(--radius);
  background: linear-gradient(180deg, rgb(255 255 255 / 0.028), rgb(255 255 255 / 0.008));
  transition: border-color 0.3s ease, transform 0.3s ease;
}

.problem:hover {
  border-color: rgb(251 191 36 / 0.28);
  transform: translateY(-3px);
}

.problem__idx {
  display: inline-block;
  margin-bottom: 0.9rem;
  font-family: var(--mono);
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  color: var(--amber);
  opacity: 0.75;
}

.problem h3 {
  margin: 0 0 0.7rem;
  font-size: 1.13rem;
  letter-spacing: -0.02em;
  line-height: 1.3;
}

.problem p {
  margin: 0;
  font-size: 0.96rem;
  color: var(--ink-mute);
}

/* ──────────────────────────── diagram ────────────────────────────── */

.diagram {
  margin: 0 0 4rem;
  padding: 2rem 1.5rem 1.5rem;
  border: 1px solid var(--edge-soft);
  border-radius: var(--radius);
  background: rgb(7 8 13 / 0.5);
  position: relative;
  overflow-x: auto;
}

.flow {
  width: 100%;
  min-width: 620px;
  height: auto;
  display: block;
}

.flow .node rect {
  fill: rgb(18 21 34 / 0.95);
  stroke: #2a3049;
  stroke-width: 1.5;
}

.flow .node--verify rect {
  stroke: rgb(123 134 255 / 0.5);
}

.flow .node--settle rect {
  stroke: rgb(52 211 153 / 0.55);
}

/* Cyan, deliberately not amber: amber is this page's "planned, not shipped"
   colour, and the held proposal is the one node in that diagram that IS
   shipped. Reading it as unbuilt would say the opposite of what it means. */
.flow .node--held rect {
  stroke: rgb(34 211 238 / 0.5);
}

.flow .node__title {
  fill: #eef1fa;
  font-family: var(--font);
  font-size: 15px;
  font-weight: 600;
  text-anchor: middle;
}

.flow .node__sub {
  fill: #7d859f;
  font-family: var(--mono);
  font-size: 11.5px;
  text-anchor: middle;
}

/* Dashes crawl along the wires, so the diagram reads as flow rather than
   as a static box-and-line drawing. */
.flow .wire {
  stroke-dasharray: 5 9;
  animation: crawl 1.6s linear infinite;
}

@keyframes crawl {
  to {
    stroke-dashoffset: -28;
  }
}

.diagram figcaption {
  margin-top: 1.4rem;
  font-size: 0.92rem;
  color: var(--ink-mute);
  max-width: 72ch;
}

/* Base `a` is colour: inherit, so a link in muted caption text would be
   invisible as one. */
.diagram figcaption em {
  font-style: normal;
  color: var(--ink-soft);
}

/* Base `a` is colour: inherit, so a link closing a lede reads as body text. */
.section__lede a {
  color: var(--cyan);
  text-decoration: none;
  border-bottom: 1px solid rgb(34 211 238 / 0.35);
}

.section__lede a:hover,
.section__lede a:focus-visible {
  border-bottom-color: var(--cyan);
}

.diagram figcaption a {
  color: var(--cyan);
  text-decoration: none;
  border-bottom: 1px solid rgb(34 211 238 / 0.35);
  white-space: nowrap;
}

.diagram figcaption a:hover,
.diagram figcaption a:focus-visible {
  border-bottom-color: var(--cyan);
}

.badge {
  display: inline-block;
  margin-bottom: 1.25rem;
  padding: 0.28rem 0.7rem;
  border-radius: 999px;
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.badge--planned {
  color: var(--amber);
  background: rgb(251 191 36 / 0.1);
  border: 1px solid rgb(251 191 36 / 0.3);
}

.badge--live {
  color: var(--emerald);
  background: rgb(52 211 153 / 0.1);
  border: 1px solid rgb(52 211 153 / 0.3);
}

/* ──────────────────────────── pillars ────────────────────────────── */

/* Two columns, not auto-fit: there are four pillars, and at desktop widths
   auto-fit resolves to three, leaving the fourth alone on a row with two
   empty cells beside it. 2x2 is the only balanced arrangement for four. */
.pillars {
  display: grid;
  gap: 1.15rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr));
}

.pillar {
  padding: 1.75rem 1.6rem;
  border: 1px solid var(--edge-soft);
  border-radius: var(--radius);
  background: linear-gradient(180deg, rgb(255 255 255 / 0.03), rgb(255 255 255 / 0.006));
  transition: border-color 0.3s ease, transform 0.3s ease;
}

.pillar:hover {
  border-color: rgb(123 134 255 / 0.3);
  transform: translateY(-3px);
}

.pillar h3 {
  margin: 0 0 0.75rem;
  font-size: 1.18rem;
  letter-spacing: -0.02em;
  line-height: 1.3;
}

.pillar p {
  margin: 0 0 0.85rem;
  font-size: 0.96rem;
  color: var(--ink-mute);
}

.pillar p:last-child {
  margin-bottom: 0;
}

.pillar em {
  font-style: normal;
  color: var(--ink-soft);
}

.pillar__detail {
  padding-top: 0.85rem;
  border-top: 1px solid var(--edge-soft);
  font-size: 0.9rem !important;
  color: var(--ink-faint) !important;
}

/* ───────────────────────────── cards ─────────────────────────────── */

.stack {
  display: grid;
  gap: 1.15rem;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}

.card {
  display: block;
  padding: 1.7rem 1.55rem;
  border: 1px solid var(--edge-soft);
  border-radius: var(--radius);
  background: linear-gradient(180deg, rgb(255 255 255 / 0.03), rgb(255 255 255 / 0.006));
  text-decoration: none;
  transition: border-color 0.3s ease, transform 0.3s ease, box-shadow 0.3s ease;
}

.card h3 {
  margin: 0 0 0.65rem;
  font-size: 1.1rem;
  letter-spacing: -0.02em;
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
}

.card p {
  margin: 0 0 1.1rem;
  font-size: 0.94rem;
  color: var(--ink-mute);
}

.card code {
  font-family: var(--mono);
  font-size: 0.86em;
  padding: 0.1em 0.35em;
  border-radius: 5px;
  background: rgb(123 134 255 / 0.12);
  color: #b9c0ff;
}

.card__meta {
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--ink-faint);
  letter-spacing: 0.01em;
}

.card__go {
  color: var(--cyan);
  font-size: 0.9rem;
  transition: transform 0.2s ease;
  display: inline-block;
}

.card--link:hover {
  border-color: rgb(34 211 238 / 0.38);
  transform: translateY(-3px);
  box-shadow: 0 14px 40px rgb(0 0 0 / 0.35);
}

.card--link:hover .card__go {
  transform: translate(3px, -3px);
}

.card--muted {
  opacity: 0.62;
}

/* ──────────────────────────── codeblock ──────────────────────────── */

.codeblock {
  margin: 0 0 2.5rem;
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  overflow: hidden;
  background: #06070c;
  box-shadow: 0 24px 70px rgb(0 0 0 / 0.5);
  will-change: transform;
}

.codeblock__bar {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.7rem 1rem;
  border-bottom: 1px solid var(--edge-soft);
  background: rgb(255 255 255 / 0.02);
}

.codeblock__dots {
  display: inline-flex;
  gap: 0.4rem;
}

.codeblock__dots i {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #262b3d;
}

.codeblock__name {
  font-family: var(--mono);
  font-size: 0.8rem;
  color: var(--ink-faint);
  margin-left: auto;
}

/* Language switcher. The filename is pushed to the right by the tabs'
   margin-left:auto above, so the bar reads: dots, tabs, filename. */
.codeblock__tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem;
}

.codeblock__tab {
  padding: 0.3rem 0.7rem;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--ink-faint);
  font: inherit;
  font-size: 0.78rem;
  line-height: 1.4;
  cursor: pointer;
  transition: color 0.18s ease, background-color 0.18s ease;
}

.codeblock__tab:hover {
  color: var(--ink);
  background: rgb(255 255 255 / 0.04);
}

.codeblock__tab.is-active {
  color: var(--ink);
  background: rgb(255 255 255 / 0.08);
}

/* Keyboard users get a visible ring; pointer users do not. */
.codeblock__tab:focus-visible {
  outline: 2px solid var(--accent, #67e8f9);
  outline-offset: 2px;
}

@media (max-width: 640px) {
  /* The filename is the first thing worth dropping: the active tab already
     says which language this is. */
  .codeblock__name {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .codeblock__tab {
    transition: none;
  }
}

.codeblock pre {
  margin: 0;
  padding: 1.5rem 1.4rem;
  overflow-x: auto;
  font-family: var(--mono);
  font-size: 0.85rem;
  line-height: 1.75;
  color: #d3d9ee;
  tab-size: 2;
}

.codeblock .c {
  color: #5d6480;
  font-style: italic;
}

.codeblock .k {
  color: #a78bfa;
}

.codeblock .f {
  color: #67e8f9;
}

.codeblock .s {
  color: #6ee7b7;
}

.build__cta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
}

/* ───────────────────────────── close ─────────────────────────────── */

.close {
  text-align: center;
  padding-bottom: clamp(6rem, 16vh, 11rem);
}

.close__title {
  margin: 0 0 1.5rem;
  font-size: clamp(2rem, 4.6vw, 3.15rem);
  line-height: 1.12;
  letter-spacing: -0.035em;
  font-weight: 700;
}

.close__body {
  margin: 0 auto 2.5rem;
  max-width: 60ch;
  font-size: clamp(1rem, 1.6vw, 1.15rem);
  color: var(--ink-soft);
}

.close__cta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
  justify-content: center;
}

/* ───────────────────────────── footer ────────────────────────────── */

.footer {
  position: relative;
  z-index: 1;
  border-top: 1px solid var(--edge-soft);
  background: rgb(5 6 10 / 0.85);
  padding: 2.75rem 0;
}

.footer__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.25rem 2rem;
}

.footer__brand {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--ink-soft);
}

.footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  margin-left: auto;
  font-size: 0.92rem;
  color: var(--ink-mute);
}

.footer__links a {
  text-decoration: none;
  transition: color 0.2s ease;
}

.footer__links a:hover {
  color: var(--ink);
}

.footer__note {
  flex-basis: 100%;
  margin: 0;
  padding-top: 1.25rem;
  border-top: 1px solid var(--edge-soft);
  font-size: 0.85rem;
  color: var(--ink-faint);
}

/* ────────────────────────── reveal on scroll ─────────────────────── */

/* Only applied once main.js confirms IntersectionObserver support and
   tags <html> - without JS, nothing is ever hidden.
 *
 * Kept deliberately short. A longer, more luxurious transition looked
 * better when stepping through the page slowly and much worse in the case
 * that actually matters - a fast scroll, where a section still fading in
 * a second after it entered the viewport reads as content failing to
 * load rather than as an effect. */
.js .reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.42s cubic-bezier(0.16, 1, 0.3, 1), transform 0.42s cubic-bezier(0.16, 1, 0.3, 1);
}

.js .reveal.is-in {
  opacity: 1;
  transform: none;
}

/* ───────────────────────────── responsive ────────────────────────── */

@media (max-width: 860px) {
  .topnav {
    display: none;
  }

  /* Scanner and Playground fold into the hamburger menu alongside the
     in-page anchors, rather than disappearing outright - Docs stays as
     the one link still surfaced directly in the topbar. */
  .topbar__actions .btn--ghost {
    display: none;
  }

  .nav-menu {
    display: block;
    position: relative;
  }
}

@media (max-width: 560px) {
  body {
    font-size: 16px;
  }

  .hero {
    min-height: auto;
    padding-top: 3.5rem;
  }

  .scroll-hint {
    display: none;
  }

  .diagram {
    padding: 1.5rem 1rem 1.25rem;
  }

  .footer__links {
    margin-left: 0;
    gap: 1rem;
  }
}

/* ───────────────────── reduced motion / print ────────────────────── */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }

  /* Reveals must not stay invisible when their transition is neutered -
     main.js also skips the observer entirely in this mode, this is the
     belt-and-braces half. */
  .js .reveal {
    opacity: 1;
    transform: none;
  }
}
