/* =====================================================================
   BUFONITE — home
   Colours sampled from the reference: page #080808, primary #172DCC.
   ===================================================================== */
:root {
  --bg: #080808;
  --bg-2: #0d0e10;
  --card: #111215;
  --card-2: #16181c;
  --line: rgba(255, 255, 255, 0.09);
  --line-2: rgba(255, 255, 255, 0.16);
  --text: #ffffff;
  --muted: #9ba0a8;
  --dim: #63676f;

  --blue: #172dcc;
  --blue-hi: #2440ec;
  --blue-soft: #5b7cff;
  --ice: #bcd0ff;
  --gold: #e6b85c;
  --gold-hi: #ffd98a;
  --red: #ff5a4f;

  --pad: clamp(20px, 4.7vw, 75px);
  --nav-h: clamp(76px, 6vw, 92px);
  --radius: 22px;
  --font: "Public Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: ui-monospace, "SFMono-Regular", "JetBrains Mono", Menlo, Consolas, monospace;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  color-scheme: dark;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scrollbar-gutter: stable; }
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: hidden; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
img { display: block; max-width: 100%; }
code { font-family: var(--mono); font-size: 0.9em; color: var(--ice); background: rgba(91, 124, 255, 0.1); padding: 0.1em 0.35em; border-radius: 6px; }
::selection { background: var(--blue); color: #fff; }
:focus-visible { outline: 2px solid var(--blue-soft); outline-offset: 3px; border-radius: 8px; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.container { width: 100%; max-width: 1600px; margin: 0 auto; padding-left: var(--pad); padding-right: var(--pad); }

/* ------------------------------------------------------------------ buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  height: 46px; padding: 0 22px;
  border-radius: 999px;
  font-weight: 600; font-size: 16px; letter-spacing: 0.005em; white-space: nowrap;
  transition: background-color 0.25s, color 0.25s, border-color 0.25s, transform 0.25s var(--ease-out);
}
.btn--blue { background: var(--blue); color: #fff; }
.btn--blue:hover { background: var(--blue-hi); }
.btn--ghost { border: 2px solid #fff; color: #fff; }
.btn--ghost:hover { background: #fff; color: var(--bg); }
.btn:active { transform: scale(0.97); }
.btn--lg { height: 56px; padding: 0 30px; font-size: 17px; }

/* ---------------------------------------------------------------------- nav */
.nav {
  position: fixed; inset: 0 0 auto 0; z-index: 50;
  transition: transform 0.5s var(--ease-out);
}
/* the frosted bar is a layer of its own that fades in: its blur never animates (a blur radius
   transitioning over the live coin canvas made the GPU rebuild and redo it every frame) */
.nav::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: rgba(8, 8, 8, 0.72);
  backdrop-filter: blur(18px) saturate(140%); -webkit-backdrop-filter: blur(18px) saturate(140%);
  opacity: 0; transition: opacity 0.4s;
}
.nav::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: var(--line); opacity: 0; transition: opacity 0.4s;
}
.nav.is-solid::before, .nav.is-solid::after { opacity: 1; }
.nav.is-hidden { transform: translateY(-100%); }
.nav__inner {
  height: var(--nav-h);
  display: flex; align-items: center; gap: clamp(18px, 2.2vw, 36px);
  padding: 0 var(--pad);
  max-width: 1600px; margin: 0 auto;
  transition: height 0.4s var(--ease-out);
}
.nav.is-solid .nav__inner { height: 84px; }

.logo { display: inline-flex; align-items: center; gap: 6px; color: #fff; flex: none; }
.logo__word { font-size: 38px; font-weight: 500; letter-spacing: -0.02em; line-height: 1; margin-top: -6px; }
/* the mark (same silhouette as the welcome screen), painted in currentColor through a mask */
.logo__mark {
  display: block; height: 46px; aspect-ratio: 493 / 740;
  background: currentColor;
  -webkit-mask: url(../assets/bufonite-mark.svg) center / contain no-repeat;
  mask: url(../assets/bufonite-mark.svg) center / contain no-repeat;
}
/* footer: mark + wordmark side by side */
.logo--lockup { gap: 12px; }
.logo--lockup .logo__mark { height: 42px; }

.nav__links { display: flex; align-items: center; gap: clamp(14px, 2.15vw, 34px); }
.nav__item { position: relative; }
.nav__link {
  display: inline-flex; align-items: center; gap: 6px;
  height: 46px;
  font-weight: 500; font-size: 16px; color: #fff;
  transition: opacity 0.2s;
}
.nav__link:hover { opacity: 0.75; }
.chev { width: 11px; height: 8px; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; transition: transform 0.3s var(--ease-out); }
.nav__item:hover .chev, .nav__item:focus-within .chev { transform: rotate(180deg); }

.dropdown {
  position: absolute; top: calc(100% + 6px); left: -18px;
  min-width: 270px; padding: 10px;
  background: rgba(17, 18, 21, 0.96);
  border: 1px solid var(--line);
  border-radius: 18px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(20px);
  opacity: 0; visibility: hidden; transform: translateY(8px);
  transition: opacity 0.25s, transform 0.35s var(--ease-out), visibility 0.25s;
}
.dropdown::before { content: ""; position: absolute; left: 0; right: 0; top: -14px; height: 14px; }
.nav__item:hover .dropdown, .nav__item:focus-within .dropdown { opacity: 1; visibility: visible; transform: none; }
.dropdown a { display: grid; gap: 2px; padding: 12px 14px; border-radius: 12px; transition: background-color 0.2s; }
.dropdown a:hover { background: rgba(255, 255, 255, 0.06); }
.dropdown b { font-weight: 600; font-size: 15px; }
.dropdown span { font-size: 13px; color: var(--muted); }

.nav__right { margin-left: auto; display: flex; align-items: center; gap: 12px; }
/* contract address plate: "CA" + the address in mono. Empty and disabled until js/ca.js has one;
   then a click copies it. It sits outside .nav__right so it stays in the bar on phones. */
.nav__ca {
  margin-left: auto; flex: none;
  display: inline-flex; align-items: center; gap: 10px;
  height: 46px; padding: 0 18px;
  border: 1px solid var(--line-2); border-radius: 999px;
  font-size: 14px; line-height: 1; color: #fff;
  transition: border-color 0.2s;
}
.nav__ca:disabled { cursor: default; }
.nav__ca:not(:disabled):hover { border-color: rgba(255, 255, 255, 0.42); }
.nav__ca-k { font-weight: 600; color: var(--muted); }
.nav__ca-v { min-width: 11ch; font-family: var(--mono); font-size: 13px; text-align: left; }
.nav__ca ~ .nav__right { margin-left: 0; }
.nav__social { display: inline-flex; align-items: center; justify-content: center; width: 46px; height: 46px; margin-right: 4px; color: #fff; transition: opacity 0.2s; }
.nav__social:hover { opacity: 0.75; }
.nav__social svg { width: 20px; height: 20px; fill: currentColor; }

.burger { display: none; margin-left: auto; width: 44px; height: 44px; border-radius: 50%; border: 1.5px solid var(--line-2); position: relative; }
.burger span { position: absolute; left: 13px; right: 13px; height: 1.5px; background: #fff; transition: transform 0.35s var(--ease-out); }
.burger span:first-child { top: 18px; }
.burger span:last-child { top: 24px; }
.nav.is-open .burger span:first-child { transform: translateY(3px) rotate(45deg); }
.nav.is-open .burger span:last-child { transform: translateY(-3px) rotate(-45deg); }

.sheet {
  display: none;
  position: fixed; inset: 76px 0 auto 0; z-index: -1;
  padding: 16px var(--pad) 28px;
  background: rgba(8, 8, 8, 0.96);
  backdrop-filter: blur(18px);
  border-bottom: 1px solid var(--line);
  flex-direction: column;
}
.sheet a:not(.btn) { padding: 14px 0; font-size: 22px; font-weight: 500; border-bottom: 1px solid var(--line); }
.sheet__cta { display: flex; gap: 10px; margin-top: 22px; }
.sheet__cta .btn { flex: 1; }

/* --------------------------------------------------------------------- hero */
.hero { position: relative; height: 230vh; height: 230svh; }
.hero__sticky {
  position: sticky; top: 0;
  height: 100vh; height: 100svh;
  overflow: hidden;
}
.hero__canvas {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: block;
  opacity: 0;
  transition: opacity 1.4s ease;
}
.hero__canvas.is-ready { opacity: 1; }
.no-webgl .hero__sticky::before {
  content: ""; position: absolute; left: 50%; top: 57%;
  width: min(70vh, 80vw); aspect-ratio: 1; transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle, transparent 38%, rgba(91, 124, 255, 0.35) 40%, rgba(230, 184, 92, 0.25) 55%, transparent 62%);
  filter: blur(6px);
}

.hero__copy {
  position: absolute; left: 0; right: 0; bottom: clamp(36px, 7vh, 90px);
  display: flex; flex-direction: column; align-items: center; text-align: center;
  padding: 0 var(--pad);
  pointer-events: none;
}
.hero__copy > * { pointer-events: auto; }
.eyebrow {
  margin: 0 0 18px;
  font-size: 13px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--muted);
}
.hero__title {
  margin: 0;
  font-size: clamp(40px, 6.1vw, 96px);
  line-height: 0.98;
  font-weight: 600;
  letter-spacing: -0.035em;
}
.line { display: block; overflow: hidden; padding-bottom: 0.08em; margin-bottom: -0.08em; }
.line > span { display: inline-block; will-change: transform; }

.paste {
  margin-top: clamp(22px, 3.4vh, 36px);
  display: flex; align-items: center; gap: 6px;
  width: min(560px, 100%);
  padding: 6px 6px 6px 22px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--line-2);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  transition: border-color 0.25s, background-color 0.25s;
}
.paste:focus-within { border-color: rgba(91, 124, 255, 0.8); background: rgba(23, 45, 204, 0.12); }
.paste input {
  flex: 1; min-width: 0;
  height: 46px;
  background: none; border: 0; outline: 0;
  color: #fff; font: inherit; font-size: 16px;
}
.paste input::placeholder { color: #7d828b; }
.paste__note { margin: 14px 0 0; font-size: 13px; color: var(--dim); min-height: 1.5em; }
.paste__note.is-error { color: #ff8a80; }
/* Check it: the brand blues drift slowly across the button. No glow, no extra colour. */
.paste .btn--blue {
  background: linear-gradient(110deg, var(--blue) 0%, var(--blue-hi) 34%, #4d6af6 50%, var(--blue-hi) 66%, var(--blue) 100%);
  background-size: 250% 100%;
  animation: check-drift 7s ease-in-out infinite alternate;
  transition: filter 0.25s, transform 0.25s var(--ease-out);
}
.paste .btn--blue:hover { filter: brightness(1.1); }
@keyframes check-drift { from { background-position: 0% 50%; } to { background-position: 100% 50%; } }

/* hook: wide screens only (16:9 / 16:10). coins.js lays the coin orbit out around it and
   main.js sets --hook-top / --hook-bottom / --hook-fs so the text fits inside the orbit. */
.hook { display: none; }
.hook__inner { width: max-content; text-align: center; will-change: transform, opacity; } /* its own layer: scaled/faded on scroll, never re-rastered */
.hook__eyebrow {
  margin: 0 0 clamp(16px, 2.4vh, 26px);
  font-size: 13px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--muted);
}
.hook__title {
  margin: 0;
  font-size: var(--hook-fs, clamp(44px, 4.6vw, 112px));
  line-height: 0.98;
  font-weight: 600;
  letter-spacing: -0.04em;
}
.hook__line { display: block; overflow: hidden; padding-bottom: 0.1em; margin-bottom: -0.1em; }
.hook__line > span { display: inline-block; white-space: nowrap; }
.hook__title em {
  font-style: normal;
  background: linear-gradient(180deg, #fff 30%, #8ea4e8);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.js .hook__line > span { animation: hook-rise 1.4s var(--ease-out) 0.15s both; }
.js .hook__line + .hook__line > span { animation-delay: 0.27s; }
.js .hook__eyebrow { animation: hook-fade 1.2s ease 0.5s both; }
/* under the welcome the hook waits at its first frame; it rises as the welcome leaves */
html.has-welcome .hook__line > span, html.has-welcome .hook__eyebrow { animation-play-state: paused; }
@keyframes hook-rise { from { transform: translateY(110%); } }
@keyframes hook-fade { from { opacity: 0; transform: translateY(10px); } }

@media (min-width: 1025px) and (min-aspect-ratio: 17/10) {
  .hero { height: 250vh; height: 250svh; }
  .hook {
    position: absolute; left: 0; right: 0;
    top: var(--hook-top, 104px); bottom: var(--hook-bottom, 28px);
    display: grid; place-items: center;
    pointer-events: none;
  }
}

.scroll-cue {
  position: absolute; left: 50%; bottom: 22px; transform: translateX(-50%);
  width: 1px; height: 44px; background: rgba(255, 255, 255, 0.12); overflow: hidden;
}
.scroll-cue span { position: absolute; left: 0; top: 0; width: 100%; height: 40%; background: rgba(255, 255, 255, 0.7); animation: cue 2.2s var(--ease-out) infinite; }
@keyframes cue { 0% { transform: translateY(-100%); } 100% { transform: translateY(260%); } }

/* ------------------------------------------------------------- generic type */
.section-title {
  margin: 0;
  font-size: clamp(34px, 4.6vw, 72px);
  line-height: 1.02;
  font-weight: 600;
  letter-spacing: -0.035em;
  max-width: 17ch;
}
.split .w { display: inline-block; overflow: hidden; vertical-align: top; padding-bottom: 0.1em; margin-bottom: -0.1em; }
.split .w > span { display: inline-block; will-change: transform; }
.lede { margin: 26px 0 0; max-width: 56ch; font-size: clamp(16px, 1.25vw, 19px); color: var(--muted); line-height: 1.6; }
.lede em { color: #fff; font-style: normal; }

/* ------------------------------------------------------------------- stages */
/* How a check works: an iMac (js/imac.js) runs a check. Its screen is HTML laid over the 3D screen
   (js/stages.js): one terminal, filling the screen, showing what `bufonite check` prints. As the check
   starts, the monitor moves to the left and a panel down the right side of the window (.sp) says what
   the running course does and what it found. Gold is kept for the finding and the grade only. */
.stages { position: relative; }
.stages__pin { position: relative; height: 100vh; height: 100svh; padding-top: calc(var(--nav-h) + 8px); overflow: hidden; }
.stages__stage { will-change: transform; }
.stages__body, .stages__head .section-title { will-change: transform; }
.stages__head { margin-bottom: clamp(16px, 3vh, 36px); }
.stages .section-title { max-width: none; }

/* the monitor: a WebGL canvas, and the screen's HTML laid over its 3D screen. Wide screens: js/stages.js
   sizes it for its place beside the panel and moves it (centred and a little smaller at first). */
.mon { position: relative; aspect-ratio: 65 / 52.8; max-width: 100%; margin: 0 auto; transform-origin: 0 0; }
@media (min-width: 1081px) { .js .mon { margin: 0; max-width: none; will-change: transform; } }
.mon__gl { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.mon__screen {
  position: absolute; left: 0; top: 0; transform-origin: 0 0;
  display: flex; flex-direction: column; overflow: hidden;
  color: #e9ecf3; font-size: 13px; font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", var(--font);
  /* a macOS-style wallpaper: a night-blue aurora, rays fanning up from below the dock */
  background:
    radial-gradient(38% 55% at 50% 112%, rgba(150, 178, 255, 0.6), rgba(150, 178, 255, 0) 70%),
    repeating-conic-gradient(from 300deg at 50% 118%, rgba(170, 192, 255, 0.06) 0deg 0.7deg, rgba(170, 192, 255, 0) 0.7deg 4deg),
    radial-gradient(75% 95% at 50% 125%, #2b4fe0 0%, rgba(43, 79, 224, 0) 62%),
    radial-gradient(80% 70% at 12% -5%, #0d1a52 0%, rgba(13, 26, 82, 0) 70%),
    linear-gradient(180deg, #040818 0%, #0a1546 55%, #13278a 100%);
}
.js .mon__gl, .js .mon__screen { opacity: 0; }
/* the screen and the monitor are one thing: neither shows until the monitor has drawn (js/stages.js adds .is-built) */
.js .mon:not(.is-built) > .mon__gl, .js .mon:not(.is-built) > .mon__screen { visibility: hidden; }
/* no JS: the screen sits where the monitor's would. Without WebGL, js/stages.js still places it (only the body is missing) */
html:not(.js) .mon__screen { left: 3.6%; top: 5.5%; width: 92.8%; height: 62%; opacity: 1; }
/* menu bar: our mark where the apple sits, the app's menus, status on the right */
.mon__menu { flex: none; display: flex; align-items: center; gap: 1.15em; height: 1.75em; padding: 0 0.9em; font-size: 0.78em; color: #eef1f7; background: rgba(10, 13, 28, 0.42); -webkit-backdrop-filter: blur(12px) saturate(150%); backdrop-filter: blur(12px) saturate(150%); }
.mon__menu b { font-weight: 700; }
.mon__status { margin-left: auto; display: flex; align-items: center; gap: 1em; }
.mon__status svg { width: 1.35em; height: 1.35em; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }
.mon__status circle, .mon__status .fill { fill: currentColor; stroke: none; }
.mon__logo { width: 0.85em; height: 1.2em; background: currentColor; -webkit-mask: url(../assets/bufonite-mark.svg) center / contain no-repeat; mask: url(../assets/bufonite-mark.svg) center / contain no-repeat; }
.mon__desk { flex: 1; min-height: 0; display: flex; padding: 1em 1.2em 4.6em; }

/* the terminal window, macOS dark, filling the desk above the Dock. Everything in em of the screen's font size. */
.win { min-width: 0; display: flex; flex-direction: column; overflow: hidden; border-radius: 0.75em; background: rgba(30, 30, 34, 0.86); -webkit-backdrop-filter: blur(18px) saturate(140%); backdrop-filter: blur(18px) saturate(140%); box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.55), inset 0 0 0 1px rgba(255, 255, 255, 0.09), 0 1.4em 3em rgba(0, 0, 0, 0.5); }
.term { flex: 1 1 0; background: rgba(14, 14, 16, 0.94); }
.win__bar { flex: none; position: relative; display: flex; align-items: center; gap: 0.5em; height: 2.3em; padding: 0 0.85em; background: rgba(255, 255, 255, 0.035); border-bottom: 1px solid rgba(0, 0, 0, 0.5); }
.win__bar i { flex: none; width: 0.8em; height: 0.8em; border-radius: 50%; background: #48494e; }
.win.is-key .win__bar i:nth-child(1) { background: #ff5f57; }
.win.is-key .win__bar i:nth-child(2) { background: #febc2e; }
.win.is-key .win__bar i:nth-child(3) { background: #28c840; }
.win__bar span { position: absolute; left: 5em; right: 5em; text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.85em; font-weight: 600; color: rgba(255, 255, 255, 0.45); }
.win.is-key .win__bar span { color: rgba(255, 255, 255, 0.78); }

/* the Dock */
.dock { position: absolute; left: 50%; bottom: 0.6em; font-size: 0.86em; transform: translateX(-50%); display: flex; align-items: center; gap: 0.55em; padding: 0.45em 0.55em; border-radius: 1.15em; background: rgba(40, 46, 70, 0.36); -webkit-backdrop-filter: blur(16px) saturate(150%); backdrop-filter: blur(16px) saturate(150%); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.14), 0 0.6em 1.6em rgba(0, 0, 0, 0.35); }
.dock__app { position: relative; display: grid; place-items: center; width: 2.9em; height: 2.9em; border-radius: 0.68em; font-style: normal; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.12), 0 0.15em 0.4em rgba(0, 0, 0, 0.35); }
.dock__app.is-open::after { content: ""; position: absolute; bottom: -0.4em; left: 50%; width: 0.22em; height: 0.22em; margin-left: -0.11em; border-radius: 50%; background: rgba(255, 255, 255, 0.75); }
.dock__app b { display: block; }
.dock__sep { width: 1px; height: 2.5em; margin: 0 0.15em; background: rgba(255, 255, 255, 0.22); }
.dock__app--files { background: linear-gradient(180deg, #6fd0ff, #1b84e6); }
.dock__app--files b { position: relative; width: 1.65em; height: 1.15em; margin-top: 0.2em; border-radius: 0.16em; background: #e3f2ff; }
.dock__app--files b::before { content: ""; position: absolute; left: 0; top: -0.24em; width: 0.7em; height: 0.3em; border-radius: 0.14em 0.14em 0 0; background: #e3f2ff; }
.dock__app--term { background: linear-gradient(180deg, #3b3c41, #18191c); }
.dock__app--term b { font-family: var(--mono); font-size: 0.95em; font-weight: 700; color: #e9ecf3; }
.dock__app--bufonite { background: linear-gradient(180deg, #2f4bf0, #172dcc); }
.dock__app--bufonite b { width: 1.15em; height: 1.65em; background: #fff; -webkit-mask: url(../assets/bufonite-mark.svg) center / contain no-repeat; mask: url(../assets/bufonite-mark.svg) center / contain no-repeat; }
.dock__app--notes { background: linear-gradient(180deg, #fff6c2, #ffd84a); }
.dock__app--notes b { width: 1.7em; height: 1.5em; background: repeating-linear-gradient(180deg, rgba(0, 0, 0, 0) 0 0.3em, rgba(120, 90, 10, 0.35) 0.3em 0.36em); }
.dock__app--settings { background: linear-gradient(180deg, #a5aab4, #5d626c); }
.dock__app--settings b { width: 1.5em; height: 1.5em; border-radius: 50%; border: 0.3em dotted #2a2d33; box-sizing: border-box; box-shadow: inset 0 0 0 0.22em #2a2d33; }
.dock__app--trash { background: rgba(255, 255, 255, 0.16); }
.dock__app--trash b { width: 1.3em; height: 1.6em; border-radius: 0.08em 0.08em 0.28em 0.28em; background: repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.8) 0 0.12em, rgba(255, 255, 255, 0.32) 0.12em 0.3em); }
/* the terminal: what `bufonite check` prints, drawn by the CLI's own UI code (js/cli-ui.js).
   A fixed grid of character cells, like a real terminal; js/stages.js sizes the type so about 62
   columns fit (48 on narrow screens) and keeps the last rows that fit. */
.cli { flex: 1; min-height: 0; margin: 0; padding: 0.9em 1.1em; overflow: hidden; font-family: var(--mono); font-size: 0.86em; line-height: 1.32; color: #e7e9ee; white-space: pre; }
.cli .ln { height: 1.32em; overflow: hidden; }
/* the line of the course the panel is describing, marked like a selection */
.cli .ln.is-focus { margin: 0 -1.1em; padding: 0 1.1em; background: rgba(255, 255, 255, 0.075); }
.cli .cell { display: inline-block; width: 1ch; height: 1.32em; vertical-align: top; text-align: center; font-style: normal; }
.cli .cell svg { display: block; width: 100%; height: 100%; fill: currentColor; }
/* box drawing as lines: solid across cells, rounded at the corners */
.cli .bx { position: relative; }
.cli .bx::before { content: ""; position: absolute; border: 0 solid currentColor; }
.cli .bx-h::before { left: 0; right: 0; top: 50%; border-top-width: 1px; }
.cli .bx-v::before { top: 0; bottom: 0; left: 50%; border-left-width: 1px; }
.cli .bx-tl::before { left: 50%; right: 0; top: 50%; bottom: 0; border-width: 1px 0 0 1px; border-top-left-radius: 0.45em; }
.cli .bx-tr::before { left: 0; right: 50%; top: 50%; bottom: 0; border-width: 1px 1px 0 0; border-top-right-radius: 0.45em; }
.cli .bx-bl::before { left: 50%; right: 0; top: 0; bottom: 50%; border-width: 0 0 1px 1px; border-bottom-left-radius: 0.45em; }
.cli .bx-br::before { left: 0; right: 50%; top: 0; bottom: 50%; border-width: 0 1px 1px 0; border-bottom-right-radius: 0.45em; }
.cli .t-text { color: #e7e9ee; }
.cli .t-muted { color: var(--muted); }
.cli .t-dim { color: #5d626b; }
.cli .t-strong { color: #fff; font-weight: 700; }
.cli .t-mark { color: #f5eee6; } /* the face in ASCII: the mark's own cream, as the CLI prints it */
.cli .t-blue { color: var(--blue-soft); }
.cli .t-ice { color: var(--ice); }
.cli .t-gold { color: var(--gold-hi); }
.cli .t-red { color: var(--red); }
.cli .t-cursor { display: inline-block; width: 1ch; background: #c9ccd3; }
.cli__probe { position: absolute; visibility: hidden; white-space: pre; }

/* the panel: what the running course does, beside the monitor. Wide screens: the full height of the
   window on its right side; js/stages.js sets its width (--sp-w), the gutter on its right (--sp-pr) and
   where its content starts (--sp-top, level with "How a check works"), and slides it in. One card at a
   time: they share one grid cell, so the panel keeps the tallest height and nothing jumps. */
.sp {
  position: absolute; top: 0; right: 0; bottom: 0; z-index: 1;
  width: var(--sp-w, 420px); padding: var(--sp-top, 120px) var(--sp-pr, 60px) 24px 40px;
  display: flex; flex-direction: column; gap: 28px;
  background: rgba(255, 255, 255, 0.028); border-left: 1px solid var(--line);
}
.js .sp { opacity: 0; will-change: transform, opacity; }
.sp__rail { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.sp__rail li { padding-top: 8px; border-top: 1px solid rgba(255, 255, 255, 0.12); font-size: 13px; line-height: 20px; color: var(--dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: color 0.35s var(--ease-out), border-color 0.35s var(--ease-out); }
.sp__rail li.is-done { color: var(--muted); border-color: rgba(255, 255, 255, 0.32); }
.sp__rail li.is-done.is-gold { border-color: var(--gold-hi); }
.sp__rail li.is-on { color: #fff; border-color: #fff; }
.sp__stack { display: grid; min-height: 0; }
.sp__card { grid-area: 1 / 1; min-width: 0; display: flex; flex-direction: column; gap: 18px; }
.js .sp__card { opacity: 0; transform: translateY(8px); pointer-events: none; transition: opacity 200ms var(--ease-out), transform 360ms var(--ease-out); }
.js .sp__card.is-on { opacity: 1; transform: none; pointer-events: auto; }
/* the course's name, set like the names in the block this panel replaced: semibold, shaded top to bottom */
.sp__name { margin: 0; font-size: clamp(36px, 3.2vw, 52px); font-weight: 600; letter-spacing: -0.04em; line-height: 1.04; background: linear-gradient(180deg, #fff 30%, #8ea4e8); -webkit-background-clip: text; background-clip: text; color: transparent; }
.sp__card--verdict .sp__name { background: none; color: #fff; }
.sp__grade { margin-right: 0.12em; color: var(--gold-hi); }
.sp__line { margin: 0; max-width: 32ch; font-size: 18px; line-height: 26px; color: #fff; }
.sp code { padding: 0; background: none; border-radius: 0; font-size: 0.9em; color: inherit; }
/* what this course found in the run on the monitor; it comes in when the terminal reports it */
.sp__run, .sp__most { margin: 0; display: grid; gap: 4px; padding-top: 12px; border-top: 1px solid var(--line); }
.sp__run dt, .sp__most dt { font-size: 13px; line-height: 20px; color: var(--muted); }
.sp__run dd, .sp__most dd { margin: 0; font-size: 15px; line-height: 22px; color: #fff; }
.sp__run dd { font-family: var(--mono); font-size: 13px; transition: opacity 240ms var(--ease-out); }
.sp__run.is-c dd:first-of-type { color: var(--gold-hi); }
.sp__run .sp__code { margin-top: 6px; padding: 8px 10px; border-radius: 8px; background: rgba(255, 255, 255, 0.045); font-size: 12.5px; color: #e7e9ee; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sp__code b { margin-right: 1.4ch; font-weight: 400; color: var(--dim); }
.js .sp__card:not(.is-done) .sp__run dd { opacity: 0; }
.js .sp__card:not(.is-done) .sp__run dt::after { content: "…"; }
.sp__most .is-c { color: var(--gold-hi); }
.sp__most .is-closed { color: var(--red); }
.sp__facts { margin: 0; display: grid; }
.sp__facts div { padding: 10px 0; border-top: 1px solid var(--line); }
.sp__facts dt { font-size: 14px; font-weight: 500; line-height: 20px; color: #fff; }
.sp__facts dd { margin: 2px 0 0; font-size: 14px; line-height: 21px; color: var(--muted); }
/* short windows: two facts, then one */
@media (min-width: 1081px) and (max-height: 860px) { .sp__facts div:nth-child(3) { display: none; } }
@media (min-width: 1081px) and (max-height: 700px) { .sp__facts div:nth-child(2) { display: none; } .sp__name { font-size: 36px; } }
/* no script: the panel sits under the monitor with every card open */
html:not(.js) .sp { position: static; width: auto; margin: 40px auto 0; max-width: 1600px; padding: 0 var(--pad); background: none; border: 0; }
html:not(.js) .sp__stack { gap: 48px; }
html:not(.js) .sp__card { grid-area: auto; }

/* narrower screens: the panel sits under the monitor (js/stages.js moves it there): the rail, the line,
   what this run found. No name (the rail has it), no facts. */
@media (max-width: 1080px) {
  .dock { display: none; }
  .mon__desk { padding: 1em 1.2em 1.2em; }
  .js .sp { position: static; width: auto; margin-top: 14px; padding: 0; gap: 12px; background: none; border: 0; }
  .js .sp__name, .js .sp__facts, .js .sp__most { display: none; }
  .js .sp__card { gap: 8px; }
  .js .sp__line { font-size: 14px; line-height: 20px; color: var(--muted); }
  .js .sp__run { padding-top: 0; border: 0; }
  .js .sp__run dt { display: none; }
}
@media (max-width: 720px) {
  .mon__menu { display: none; }
  .mon__desk { padding: 0.6em; }
  .win__bar { height: 2em; }
}
@media (prefers-reduced-motion: reduce) {
  .sp__rail li, .js .sp__card, .sp__run dd { transition: none; }
}

/* ------------------------------------------------------------------- grades */
/* How a grade comes out, to play with (js/grades.js). Left: the title, then findings the courses
   really report, each on a switch, grouped by course like a settings list. Right: one panel with what
   they come to. Along its top the four grades (the one they come to lit, with a rule in its colour; a
   click sets the switches to a skill that gets it), then that grade as the CLI's ASCII art in its
   terminal colour beside what the agent does, the sum, why, and the agent's reply. Wide: the panel
   stays in view beside the list. Narrow: it comes after the list, and a bar at the bottom of the
   screen carries the grade while you flip switches. No colour but the grade's and the switches' blue.
   Text in three roles: #fff, --muted, and --dim for what isn't lit or no longer counts. */
.grades { padding-top: clamp(100px, 14vh, 180px); padding-bottom: clamp(80px, 12vh, 140px); }
.grades__grid {
  display: grid; grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); grid-template-rows: auto 1fr;
  grid-template-areas: "head view" "list view"; column-gap: clamp(40px, 5vw, 96px); align-items: start;
}
.grades__head { grid-area: head; }
.grades__head .eyebrow { margin-bottom: 24px; font-size: 14px; font-weight: 500; letter-spacing: 0; text-transform: none; }
.grades__head .section-title { text-wrap: balance; }
.grades__head .lede { margin-top: 24px; max-width: 46ch; text-wrap: pretty; }
/* each grade's terminal colour (src/cli/ui.ts GRADE_TONE: A ice, B white, C gold, CLOSED red) */
.grades [data-grade="A"] { --tone: var(--ice); }
.grades [data-grade="B"] { --tone: #fff; }
.grades [data-grade="C"] { --tone: var(--gold-hi); }
.grades [data-grade="CLOSED"] { --tone: var(--red); }

/* the result: stays in view while the list beside it scrolls */
.gv {
  grid-area: view; position: sticky; top: calc(var(--nav-h) + 24px);
  container-type: inline-size; padding: 0 28px 28px;
  border-radius: 20px; background: var(--card); border: 1px solid var(--line);
}
/* the four grades: the lit one white, its letter and a rule under it in its colour */
.gv__scale { display: flex; justify-content: space-between; gap: 0 12px; margin: 0 -28px; padding: 0 28px; list-style: none; border-bottom: 1px solid var(--line); }
.gv__scale li { display: flex; }
.gv__scale button {
  position: relative; display: flex; align-items: baseline; gap: 8px; margin: 0; padding: 18px 0 16px;
  border: 0; background: none; font: 400 14px/20px var(--font); color: var(--dim); cursor: pointer;
  transition: color 160ms var(--ease-out);
}
.gv__scale b { font: 700 14px/20px var(--mono); }
.gv__scale button:hover { color: var(--muted); }
.gv__scale .is-on button { color: #fff; }
.gv__scale .is-on b { color: var(--tone); }
.gv__scale button::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; border-radius: 2px;
  background: var(--tone); transform: scaleX(0); transition: transform 240ms var(--ease-out);
}
.gv__scale .is-on button::after { transform: scaleX(1); }
.gv__scale button:focus-visible { outline: 2px solid var(--blue-soft); outline-offset: 4px; border-radius: 4px; }
/* the grade they come to, and what the agent does. A, B and C are plain big letters beside the line;
   CLOSED is the CLI's art (js/grade-art.js), sized to the panel: its 60 cells take the width and the
   line goes under it. 0.62em a cell covers the widest of the mono fallbacks. */
.gv__top { display: flex; flex-wrap: wrap; align-items: center; gap: 20px 32px; padding: 36px 0 32px; }
.gv__mark {
  flex: none; display: block; font-family: var(--mono); font-weight: 400; font-style: normal;
  font-size: min(26px, 100cqi / (var(--cells, 10) * 0.62)); line-height: 1.2; letter-spacing: 0; white-space: pre; color: var(--tone);
}
.gv__mark:not(:has(.gr__art)) { font: 600 88px/1 var(--font); letter-spacing: -0.04em; } /* A, B and C: the plain letter in its colour */
.gv__mark.is-new { animation: gv-mark 220ms var(--ease-out); }
@keyframes gv-mark { from { opacity: 0; } }
.gv__do { flex: 1 1 200px; margin: 0; font-size: clamp(26px, 2.3vw, 34px); font-weight: 600; line-height: 1.12; letter-spacing: -0.02em; text-wrap: balance; }
/* the sum: 100, minus each finding switched on, the score. The finding that sets the grade is white. */
.gv__sum { margin: 0; padding-top: 14px; border-top: 1px solid var(--line); }
.gv__sum > div { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 24px; align-items: baseline; padding: 5px 0; }
.gv__sum dt { min-width: 0; font-size: 15px; line-height: 22px; color: var(--muted); }
.gv__sum dd { margin: 0; font-family: var(--mono); font-size: 14px; line-height: 22px; color: #fff; font-variant-numeric: tabular-nums; white-space: nowrap; }
.gv__start dd { color: var(--muted); }
.gv__line dt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gv__line.is-key dt { color: #fff; }
.gv__line small { font-size: 13px; color: var(--dim); }
.gv__line.is-void dt, .gv__line.is-void dd, .gv__line.is-void small { color: var(--dim); text-decoration: line-through; text-decoration-color: rgba(255, 255, 255, 0.28); }
.js .gv__line.is-new { animation: gr-line 260ms var(--ease-out); }
.gv__sum > .gv__total { margin-top: 8px; padding-top: 12px; border-top: 1px solid var(--line-2); }
.gv__total dt { font-weight: 500; color: #fff; }
.gv__total dd { font-size: 18px; font-weight: 600; }
.gv__why { margin: 10px 0 0; font-size: 14px; line-height: 22px; color: var(--muted); text-wrap: pretty; }
/* what the agent tells you, from the advice BUFONITE gives it for this grade; the file:line it quotes
   is set in mono, the way the agent shows it */
.gv__agent { margin-top: 24px; padding-top: 20px; border-top: 1px solid var(--line); }
.gv__agent p { margin: 0; font-size: 16px; line-height: 24px; color: #fff; }
.gv__agent code { padding: 0; background: none; font-size: 14px; color: #fff; }
.gv__agent .gv__label { margin-bottom: 6px; font-size: 13px; line-height: 20px; color: var(--muted); }
.gv__agent .gv__ci { margin-top: 12px; font-size: 13px; line-height: 20px; color: var(--muted); }
.gv__agent .gv__ci code { font-size: 12px; color: var(--muted); }
/* a narrow panel names only the lit grade */
@container (max-width: 380px) {
  .gv__scale li:not(.is-on) button span { display: none; }
}

/* the report on the check page (js/check.js, pages.css .rp) lays out its result with these: all four
   grades as small ASCII art in one row, what the agent does, the sum, why, and the agent's reply. */
.gr { position: sticky; top: calc(var(--nav-h) + 24px); container-type: inline-size; }
.gr__scale {
  margin: 0; padding: 0; list-style: none; display: flex; flex-wrap: wrap; align-items: flex-end; gap: 20px 4ch;
  font-family: var(--mono); font-size: clamp(7px, 100cqi / 59.4, 10px);
}
.gr__scale li { display: grid; gap: 12px; justify-items: start; }
.gr__scale li > span { font-family: var(--font); font-size: 13px; line-height: 20px; color: var(--muted); transition: color 200ms var(--ease-out); }
.gr__scale li.is-on > span { color: #fff; }
.gr__mark { display: block; font-weight: 400; font-style: normal; line-height: 1.2; letter-spacing: 0; white-space: pre; color: #484b52; transition: color 200ms var(--ease-out); }
.gr__art { display: block; }
.gr__scale [data-grade="A"] { --tone: var(--ice); }
.gr__scale [data-grade="B"] { --tone: #fff; }
.gr__scale [data-grade="C"] { --tone: var(--gold-hi); }
.gr__scale [data-grade="CLOSED"] { --tone: var(--red); }
.gr__scale li.is-on .gr__mark { color: var(--tone); }
.gr__mark:not(:has(.gr__art)) { font: 600 40px/1 var(--font); }
.gr__do { margin: 48px 0 0; max-width: 18ch; font-size: clamp(30px, 2.6vw, 40px); font-weight: 600; line-height: 1.1; letter-spacing: -0.02em; text-wrap: balance; }
.gr__sum { margin: 32px 0 0; display: grid; }
.gr__sum > div { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 24px; align-items: baseline; padding: 12px 0; border-top: 1px solid var(--line); }
.gr__sum dt { min-width: 0; font-size: 15px; line-height: 20px; color: var(--muted); }
.gr__sum dd { margin: 0; font-family: var(--mono); font-size: 14px; line-height: 20px; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.gr__line dt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gr__line.is-key dt { color: #fff; }
.gr__line small { font-size: 13px; color: var(--muted); }
.gr__line dd { color: #fff; }
.gr__line.is-void dt, .gr__line.is-void dd, .gr__line.is-void small { color: var(--dim); text-decoration: line-through; text-decoration-color: rgba(255, 255, 255, 0.28); }
@keyframes gr-line { from { opacity: 0; transform: translateY(-4px); } }
.gr__sum > .gr__total { border-top-color: var(--line-2); }
.gr__total dt { font-weight: 500; color: #fff; }
.gr__total dd { font-size: 16px; font-weight: 500; color: #fff; }
.gr__why { margin: 16px 0 0; max-width: 46ch; font-size: 15px; line-height: 24px; color: var(--muted); }
.gr__agent { margin-top: 40px; padding: 20px 24px; border-radius: 16px; background: var(--card); border: 1px solid var(--line); }
.gr__agent p { margin: 0; font-size: 16px; line-height: 24px; color: #fff; }
.gr__agent code { padding: 0; background: none; font-size: 14px; color: #fff; }
.gr__agent .gr__label { margin-bottom: 4px; font-size: 13px; line-height: 20px; color: var(--muted); }
.gr__agent .gr__ci { margin-top: 12px; font-size: 13px; line-height: 20px; color: var(--muted); }
.gr__agent .gr__ci code { font-size: 12px; }

/* the findings: a settings-style list per course, each finding on a switch. The course name lines up
   with the text of its rows. */
.fx { grid-area: list; display: grid; gap: 32px; margin-top: clamp(48px, 7vh, 80px); }
.fx__group { margin: 0; padding: 0; border: 0; min-width: 0; }
.fx__group legend { float: left; width: 100%; display: flex; align-items: baseline; gap: 12px; margin-bottom: 8px; padding: 0 20px; }
.fx__group legend b { font-size: 15px; font-weight: 500; line-height: 22px; color: #fff; }
.fx__group legend span { font-size: 13px; line-height: 20px; color: var(--muted); }
.fx__list { clear: both; border-radius: 16px; background: var(--card); border: 1px solid var(--line); overflow: hidden; }
.fx__row {
  position: relative; display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; column-gap: 20px;
  padding: 16px 20px; cursor: pointer;
  transition: background-color 160ms var(--ease-out), opacity 200ms var(--ease-out);
}
.fx__row + .fx__row::before { content: ""; position: absolute; left: 20px; right: 0; top: 0; height: 1px; background: var(--line); }
.fx__row:hover { background: rgba(255, 255, 255, 0.025); }
.fx__row input { position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; pointer-events: none; }
.fx__text { display: grid; gap: 2px; min-width: 0; }
.fx__title { font-size: 15px; line-height: 22px; color: #fff; }
.fx__meta { font-size: 13px; line-height: 20px; color: var(--muted); }
.fx__loc { font-family: var(--mono); font-size: 12px; }
/* the price reads whether the switch is on or off: off it is what turning it on costs */
.fx__cost { min-width: 4ch; text-align: right; font-family: var(--mono); font-size: 14px; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; transition: color 160ms var(--ease-out); }
.fx__row input:checked ~ .fx__cost { color: #fff; }
.fx__row.is-void .fx__cost { color: var(--dim); text-decoration: line-through; } /* a leak sets the score to 0: the rest no longer count */
/* the switch */
.fx__sw { position: relative; flex: none; width: 44px; height: 26px; border-radius: 999px; background: rgba(255, 255, 255, 0.16); transition: background-color 180ms var(--ease-out); }
.fx__sw::after { content: ""; position: absolute; left: 3px; top: 3px; width: 20px; height: 20px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35); transition: transform 180ms var(--ease-out); }
.fx__row input:checked ~ .fx__sw { background: var(--blue-hi); }
.fx__row input:checked ~ .fx__sw::after { transform: translateX(18px); }
.fx__row input:focus-visible ~ .fx__sw { outline: 2px solid var(--blue-soft); outline-offset: 3px; }
/* the two-votes switch hangs off the finding above it, and waits while that one is off */
.fx__row--sub { padding-left: 44px; }
.fx__row + .fx__row--sub::before { left: 44px; }
.fx__row--sub .fx__title { font-size: 14px; }
.fx__row.is-off { cursor: default; opacity: 0.4; }
.fx__row.is-off:hover { background: none; }

/* narrow screens only: the grade at the bottom of the screen while the list scrolls */
.fx__peek { display: none; }

@media (max-width: 1080px) {
  .grades__grid { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; grid-template-areas: "head" "list" "view"; }
  .gv { position: static; margin-top: 56px; }
  .gr { position: static; }
  .fx__peek {
    position: sticky; bottom: 12px; z-index: 2;
    display: flex; align-items: center; gap: 12px; margin-top: -8px; padding: 12px 16px;
    border-radius: 16px; background: rgba(22, 24, 28, 0.97); border: 1px solid var(--line-2);
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.5);
    transition: opacity 200ms var(--ease-out), transform 260ms var(--ease-out);
  }
  .fx__peek.is-away { opacity: 0; transform: translateY(8px); pointer-events: none; }
  .fx__peek-mark { font-family: var(--mono); font-size: 15px; line-height: 22px; font-weight: 700; color: var(--tone); }
  .fx__peek span { min-width: 0; font-size: 15px; line-height: 22px; color: #fff; }
  .fx__peek .fx__peek-score { margin-left: auto; font-family: var(--mono); font-size: 14px; color: var(--muted); }
}
@media (max-width: 720px) {
  .gr__scale { font-size: clamp(7px, 100cqi / 36, 10px); } /* CLOSED (60 cells) on a row of its own */
  .gr__do { margin-top: 40px; font-size: 28px; }
  .gr__agent { padding: 16px; }
  .gv { margin-top: 48px; padding: 0 20px 20px; border-radius: 16px; }
  .gv__scale { margin: 0 -20px; padding: 0 20px; }
  .gv__top { padding: 28px 0 24px; gap: 16px 24px; }
  .gv__do { font-size: 26px; }
  .fx { margin-top: 40px; }
  .fx__group legend { padding: 0 16px; }
  .fx__row { column-gap: 12px; padding: 12px 16px; }
  .fx__row + .fx__row::before { left: 16px; }
  .fx__row--sub { padding-left: 32px; }
  .fx__row + .fx__row--sub::before { left: 32px; }
}
@media (prefers-reduced-motion: reduce) {
  .gr__mark, .gr__scale li > span, .gv__scale button, .gv__scale button::after,
  .fx__row, .fx__sw, .fx__sw::after, .fx__cost, .fx__peek { transition: none; }
  .js .gv__line.is-new { animation: none; }
}

/* -------------------------------------------------------------- grade pills */
.pill { display: inline-grid; place-items: center; min-width: 44px; height: 32px; padding: 0 12px; border-radius: 999px; font-size: 14px; font-weight: 700; letter-spacing: 0.02em; }
.pill--a { background: rgba(91, 124, 255, 0.16); color: #b9c8ff; }
.pill--b { background: rgba(255, 255, 255, 0.1); color: #fff; }
.pill--c { background: rgba(230, 184, 92, 0.16); color: var(--gold-hi); }
.pill--closed { background: var(--red); color: #160606; }

/* -------------------------------------------------------------------- setup */
/* one install section: pick where you use BUFONITE (agent or terminal), see that one block */
.setup { padding-top: clamp(80px, 12vh, 140px); border-top: 1px solid var(--line); }
.setup .install { border-top: 0; }
.setup .dev { padding-top: clamp(48px, 7vh, 80px); align-items: start; } /* both terminals start level with the title, so switching doesn't make them jump */
.setup .dev[hidden] { display: none; }
/* one slim row: name and its sub-label side by side */
.setup__switch { display: inline-grid; grid-template-columns: 1fr 1fr; column-gap: 6px; padding: 4px; border-radius: 999px; background: var(--card); border: 1px solid var(--line); }
.setup__switch button { height: 42px; padding: 0 30px; display: flex; align-items: baseline; justify-content: center; gap: 10px; line-height: 42px; border-radius: 999px; white-space: nowrap; color: var(--dim); transition: background-color 0.25s, color 0.25s; }
.setup__switch b { font-size: 15px; font-weight: 600; color: var(--muted); transition: color 0.25s; }
.setup__switch span { font-size: 13px; }
.setup__switch button:hover b { color: #fff; }
.setup__switch button.is-active { background: #fff; color: #6b7079; }
.setup__switch button.is-active b { color: var(--bg); }
@media (max-width: 720px) {
  .setup__switch { display: grid; width: 100%; }
  .setup__switch button { padding: 0 14px; }
  .setup__switch span { display: none; } /* no room for the sub-label: the block under it says it */
}

/* ---------------------------------------------------------------------- dev */
.dev { padding-top: clamp(80px, 12vh, 140px); padding-bottom: clamp(100px, 14vh, 180px); display: grid; grid-template-columns: 1fr 1.1fr; gap: clamp(40px, 6vw, 100px); align-items: center; }
.dev__tabs { margin-top: 34px; display: inline-flex; gap: 6px; padding: 5px; border-radius: 999px; background: var(--card); border: 1px solid var(--line); }
.dev__tabs button { height: 40px; padding: 0 22px; border-radius: 999px; font-weight: 600; color: var(--muted); transition: background-color 0.25s, color 0.25s; }
.dev__tabs button.is-active { background: #fff; color: var(--bg); }
.code { border-radius: var(--radius); background: #0b0c0f; border: 1px solid var(--line); overflow: hidden; box-shadow: 0 50px 120px -40px rgba(23, 45, 204, 0.55); }
.code__bar { display: flex; align-items: center; gap: 8px; padding: 14px 18px; border-bottom: 1px solid var(--line); }
.code__bar i { width: 11px; height: 11px; border-radius: 50%; background: #2a2c31; }
.code__bar span { margin-left: 10px; font-size: 13px; color: var(--dim); font-family: var(--mono); }
.code__body { margin: 0; padding: 26px 24px 30px; font-family: var(--mono); font-size: clamp(12.5px, 0.95vw, 14.5px); line-height: 1.75; color: #e7e9ee; overflow-x: auto; white-space: pre; }
.c-dim { color: #5d626b; }
.c-blue { color: var(--blue-soft); }
.c-gold { color: var(--gold-hi); }
.c-ice { color: var(--ice); }

/* ---------------------------------------------------------- mcp connector */
.install { border-top: 1px solid var(--line); }
.install__tabs { flex-wrap: wrap; border-radius: 26px; }
.install__tabs button { padding: 0 12px; font-size: 15px; } /* six clients in one row from ~1440px */
.code__copy, .code__action {
  height: 30px; padding: 0 14px; border-radius: 999px;
  display: inline-flex; align-items: center;
  font-size: 13px; font-weight: 600; white-space: nowrap;
  transition: background-color 0.2s, color 0.2s, border-color 0.2s;
}
.code__action { margin-left: auto; background: var(--blue); color: #fff; }
.code__action:hover { background: var(--blue-hi); }
.code__action[hidden] { display: none; }
.code__copy { border: 1px solid var(--line-2); color: #e7e9ee; }
.code__bar:not(:has(.code__action:not([hidden]))) .code__copy { margin-left: auto; } /* no action shown: Copy goes right */
.code__copy:hover { background: #fff; color: var(--bg); border-color: #fff; }
.code__chat { margin: 0 24px; padding: 20px 0 26px; border-top: 1px dashed var(--line-2); font-family: var(--mono); font-size: clamp(12.5px, 0.95vw, 14.5px); line-height: 1.75; color: #e7e9ee; }
.code__chat p { margin: 0; }
.install .code__body { white-space: pre-wrap; overflow-wrap: anywhere; }
.install .code__bar i { flex: none; }
.install .code__bar span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.install .code__copy, .install .code__action { flex: none; }
.code__call { padding-left: 2ch; }
.code__call::before { content: "↳ "; color: var(--blue-soft); }
.code__out { padding-left: 4ch; display: flex; align-items: center; gap: 10px; color: var(--muted); }
.code__out .pill { min-width: 30px; height: 22px; padding: 0 8px; font-size: 12px; }
.link { color: #fff; text-decoration: underline; text-decoration-color: var(--line-2); text-underline-offset: 3px; transition: text-decoration-color 0.2s; }
.link:hover { text-decoration-color: #fff; }

/* ---------------------------------------------------------------------- cta */
/* .finale wraps the CTA and the footer row and does the clipping. The glow hangs off the bottom of
   .finale (the .cta is left unpositioned on purpose), so the page ends where the CTA used to end
   and the glow sits exactly where it did. No rule on top: it runs straight on from the setup block. */
.finale { position: relative; overflow: hidden; }
.cta { padding: clamp(120px, 20vh, 240px) 0; } /* same space under the buttons as over the title; the footer row sits at the bottom */
.cta__glow {
  position: absolute; left: 50%; top: 100%; width: 140vw; height: 120vw; transform: translate(-50%, -38%);
  background:
    radial-gradient(closest-side, rgba(23, 45, 204, 0.55), transparent 70%),
    radial-gradient(closest-side at 30% 40%, rgba(230, 184, 92, 0.16), transparent 70%);
  pointer-events: none;
}
.cta__inner { position: relative; text-align: center; display: flex; flex-direction: column; align-items: center; }
.cta__title { margin: 0; font-size: clamp(42px, 6.8vw, 112px); line-height: 0.98; font-weight: 600; letter-spacing: -0.045em; max-width: 14ch; }
.cta__actions { margin-top: 44px; display: flex; gap: 12px; flex-wrap: wrap; justify-content: center; }

/* ------------------------------------------------------------------- footer */
/* one row at the bottom of the CTA: logo left, menus right. Positioned so it paints above the glow. */
.footer {
  position: relative;
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 18px 40px;
  padding-bottom: clamp(20px, 3vh, 32px); /* and the page ends just under it */
}
.footer__menus { display: flex; align-items: center; gap: clamp(18px, 2.6vw, 40px); }
.footer__menu { position: relative; }
.footer__trigger {
  display: inline-flex; align-items: center; gap: 7px; height: 44px;
  font-weight: 500; font-size: 16px; color: #cfd2d8;
  transition: color 0.2s;
}
.footer__trigger:hover, .footer__menu.is-open .footer__trigger { color: #fff; }
.footer__trigger .chev { transform: rotate(180deg); } /* points up: the menu opens upwards */
.footer__menu.is-open .chev { transform: none; }

/* the nav dropdown's panel, opening upwards; the last one hugs the right edge so it never leaves the page */
.dropup {
  position: absolute; bottom: calc(100% + 8px); left: -14px; z-index: 2;
  display: grid; min-width: 210px; padding: 8px;
  background: rgba(17, 18, 21, 0.96);
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  opacity: 0; visibility: hidden; transform: translateY(8px);
  transition: opacity 0.25s, transform 0.35s var(--ease-out), visibility 0.25s;
}
.footer__menu:last-child .dropup { left: auto; right: -14px; }
.footer__menu.is-open .dropup { opacity: 1; visibility: visible; transform: none; }
.dropup a { padding: 11px 14px; border-radius: 10px; font-size: 15px; font-weight: 500; color: #e7e9ee; white-space: nowrap; transition: background-color 0.2s, color 0.2s; }
.dropup a:hover, .dropup a:focus-visible { background: rgba(255, 255, 255, 0.06); color: #fff; }

/* -------------------------------------------------------- reveal start states */
.js .reveal-up { opacity: 0; transform: translateY(28px); }
.js .hero .reveal-fade { opacity: 0; transform: translateY(16px); }
.js .hero__title .line > span { transform: translateY(110%); }

/* --------------------------------------------------------------- responsive */
@media (max-width: 1180px) {
  .nav__links { display: none; }
  .grades__head { grid-template-columns: 1fr; }
  .grades__head .lede { justify-self: start; }
}
@media (max-width: 900px) {
  .dev { grid-template-columns: 1fr; }
}
@media (max-width: 720px) {
  :root { --radius: 18px; }
  .nav__right { display: none; }
  .burger { display: block; }
  .nav__ca { height: 44px; padding: 0 15px; }
  .nav__ca ~ .burger { margin-left: 0; }
  .sheet { display: flex; opacity: 0; visibility: hidden; transform: translateY(-10px); transition: opacity 0.3s, transform 0.4s var(--ease-out), visibility 0.3s; }
  .nav.is-open .sheet { opacity: 1; visibility: visible; transform: none; }
  .nav.is-open { background: rgba(8, 8, 8, 0.96); }
  .logo__word { font-size: 30px; }
  .logo__mark { height: 38px; }
  .logo--lockup .logo__mark { height: 34px; }
  .hero__copy { bottom: 28px; }
  .paste { padding-left: 16px; }
  .paste .btn { padding: 0 16px; }
}

@media (prefers-reduced-motion: reduce) {
  .scroll-cue span { animation: none; }
  .hero__canvas { transition: none; }
  .js .hook__line > span, .js .hook__eyebrow { animation: none; }
  .paste .btn--blue { animation: none; background-position: 50% 50%; }
}

/* ------------------------------------------------------------------ welcome */
/* Every load opens on the lockup, laid over the page; it swings in, holds and leaves by itself
   (js/welcome.js + main.js). While it's up the page is held still and the nav waits off-screen. */
.welcome {
  position: fixed; inset: 0; z-index: 60;
  background: var(--bg);
  overflow: hidden;
  will-change: opacity;
}
html:not(.has-welcome) .welcome:not(.is-leaving) { display: none; } /* deep link, no JS, or gone */
.welcome.is-leaving { pointer-events: none; }
.welcome__stage { position: absolute; inset: 0; will-change: transform, opacity; }
/* the swing-in is a transition of the canvas (the lockup in it holds still): it runs on the
   compositor, so the page being built on the main thread meanwhile can't make it stutter */
.welcome__gl {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block;
  opacity: 0; transform: perspective(2400px) rotateY(-22deg) scale(0.88);
  transition: opacity 0.8s ease, transform 1s cubic-bezier(0.33, 1, 0.68, 1); /* ease-out cubic, as the 3D swing was */
  will-change: transform, opacity;
}
.welcome__gl.is-ready { opacity: 1; transform: none; }
/* no WebGL (or it took too long): the same lockup, flat, in plain white */
.welcome__fallback {
  position: absolute; inset: 0; display: none;
  flex-direction: row; align-items: center; justify-content: center; gap: 2.4vw;
}
@media (max-aspect-ratio: 4/5) { .welcome__fallback { flex-direction: column; gap: 4vh; } }
.welcome.is-fallback .welcome__fallback { display: flex; animation: welcome-in 1.4s var(--ease-out) both; }
@keyframes welcome-in { from { opacity: 0; transform: scale(0.94); } }
@keyframes welcome-fade { from { opacity: 0; } }
.welcome__mark {
  height: min(38vh, 16vw); aspect-ratio: 493 / 740;
  background: var(--text);
  -webkit-mask: url(../assets/bufonite-mark.svg) center / contain no-repeat;
  mask: url(../assets/bufonite-mark.svg) center / contain no-repeat;
}
.welcome__word {
  font-size: min(15vw, 30vh); font-weight: 500; letter-spacing: -0.02em; line-height: 0.9;
  color: var(--text);
}
html.has-welcome { overflow: hidden; }
.has-welcome .nav { transform: translateY(-110%); opacity: 0; pointer-events: none; }
.nav { transition: transform 0.5s var(--ease-out), opacity 0.5s; }
@media (prefers-reduced-motion: reduce) {
  .welcome__gl { transition: opacity 0.5s ease; transform: none; }
  .welcome.is-fallback .welcome__fallback { animation: welcome-fade 0.6s ease both; }
}

/* ---------------------------------------------------------------- scrollbar */
/* A thin silver rail in place of the browser's default bar; it turns brand blue under the cursor. */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track, ::-webkit-scrollbar-corner { background: var(--bg); }
::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.2);
  border: 3px solid transparent; border-radius: 10px; background-clip: padding-box;
  min-height: 48px;
}
::-webkit-scrollbar-thumb:hover { background-color: rgba(255, 255, 255, 0.38); }
::-webkit-scrollbar-thumb:active { background-color: var(--blue-hi); }
::-webkit-scrollbar-button { display: none; }
/* Firefox has no pseudo-elements for this — the standard properties get it close. (Kept out of
   Chromium: there, setting them switches the ::-webkit-scrollbar styling above off.) */
@supports not selector(::-webkit-scrollbar) {
  html { scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, 0.22) var(--bg); }
}
