/* GitHub Pages styles for the zames_pro site.
  
   Why a hand-written stylesheet instead of a theme: jekyll-theme-primer is a
   GitHub-README look that gives a landing page no hierarchy (one narrow
   column, no hero, no cards). The site is one landing page plus a handful of
   doc pages, so a ~300-line sheet beats a theme dependency and a Jekyll
   plugin list. Everything is scoped to classes the layout emits, so a plain
   Markdown page without the layout keeps GitHub's default look. */

:root {
  --bg: #080b16;
  --bg-soft: #0d1223;
  --card: #101728;
  --card-hover: #151d33;
  --border: #1e2740;
  --text: #e8edf8;
  --muted: #93a0ba;
  --accent: #6ee7b7;
  --accent-2: #6aa8ff;
  --accent-3: #b78cff;
  --code-bg: #070a13;
  --radius: 16px;
  --max: 1120px;
}

@media (prefers-color-scheme: light) {
  :root {
    --bg: #ffffff;
    --bg-soft: #f6f8fc;
    --card: #ffffff;
    --card-hover: #f2f6ff;
    --border: #dde4f0;
    --text: #16202f;
    --muted: #5a6b85;
    --accent: #0f9d70;
    --accent-2: #1f6feb;
    --accent-3: #7c3aed;
    --code-bg: #0d1220;
  }
}

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

html {
  scroll-behavior: smooth;
  /* The header is 64px tall and sticky, so a jump to #install would put the
     heading UNDER it without this. */
  scroll-padding-top: 84px;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family:
    'Inter',
    -apple-system,
    BlinkMacSystemFont,
    'Segoe UI',
    Roboto,
    'Helvetica Neue',
    Arial,
    sans-serif;
  font-size: 17px;
  line-height: 1.7;
  letter-spacing: 0.002em;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a {
  color: var(--accent-2);
  text-decoration: none;
}

/* A keyboard user must SEE where they are: the default outline disappears on
   a dark background and a custom ring is the only reliable cue. */
:focus-visible {
  outline: 2px solid var(--accent-2);
  outline-offset: 2px;
  border-radius: 6px;
}

/* Keyboard users should be able to skip the header on every page. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 8px;
  z-index: 40;
  padding: 8px 14px;
  border-radius: 8px;
  background: var(--card);
  border: 1px solid var(--accent);
  color: var(--text);
  font-size: 14px;
}

.skip-link:focus {
  left: 16px;
}

a:hover {
  text-decoration: underline;
}

.wrap {
  width: 100%;
  max-width: var(--max);
  margin: 0 auto;
  padding: 0 24px;
}

/* ---------- header ---------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  backdrop-filter: saturate(140%) blur(14px);
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
}

.site-header .wrap {
  display: flex;
  align-items: center;
  gap: 20px;
  height: 64px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 700;
  font-size: 18px;
  color: var(--text);
  letter-spacing: -0.01em;
}

.brand:hover {
  text-decoration: none;
}

.brand img {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  object-fit: cover;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 18px;
  margin-left: auto;
  font-size: 14.5px;
}

.site-nav a {
  color: var(--muted);
}

.site-nav a:hover {
  color: var(--text);
  text-decoration: none;
}

.lang-switch {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: 999px;
  overflow: hidden;
}

.lang-switch a {
  padding: 3px 11px;
  font-size: 13px;
  color: var(--muted);
}

.lang-switch a.active {
  background: var(--accent);
  color: #06121a;
  font-weight: 600;
}

@media (max-width: 720px) {
  .site-nav {
    display: none;
  }
}

/* ---------- hero ---------- */

.hero {
  position: relative;
  /* The first screen is the whole pitch: a visitor has to see the headline,
     the install line and the start of the screenshot without scrolling. */
  padding: 84px 0 48px;
  text-align: center;
  overflow: hidden;
  /* A soft vignette instead of a hard edge: the hero fades into the page. */
  background:
    radial-gradient(
      ellipse 80% 60% at 50% -10%,
      color-mix(in srgb, var(--accent-2) 12%, transparent),
      transparent 70%
    ),
    linear-gradient(180deg, transparent 70%, var(--bg) 100%);
}

.hero > * {
  position: relative;
}

.hero-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg-soft);
  color: var(--muted);
  font-size: 13.5px;
}

.hero-badge strong {
  color: var(--accent);
}

.hero h1 {
  margin: 26px 0 0;
  font-size: clamp(36px, 6.4vw, 64px);
  line-height: 1.06;
  letter-spacing: -0.035em;
  font-weight: 800;
  text-wrap: balance;
}

.hero h1 em {
  font-style: normal;
  background: linear-gradient(
    100deg,
    var(--accent),
    var(--accent-2) 55%,
    var(--accent-3)
  );
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.hero p.lead {
  max-width: 700px;
  margin: 22px auto 0;
  color: var(--muted);
  font-size: clamp(17px, 1.6vw, 19px);
  line-height: 1.65;
  text-wrap: pretty;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  margin-top: 30px;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 24px;
  border-radius: 12px;
  border: 1px solid var(--border);
  font-weight: 600;
  font-size: 15px;
  color: var(--text);
  background: var(--bg-soft);
  transition:
    transform 0.14s ease,
    background 0.14s ease,
    border-color 0.14s ease,
    box-shadow 0.14s ease;
}

.btn:hover {
  text-decoration: none;
  transform: translateY(-1px);
  background: var(--card-hover);
  border-color: color-mix(in srgb, var(--accent-2) 45%, var(--border));
  box-shadow: 0 10px 24px -14px rgba(0, 0, 0, 0.6);
}

.btn-primary {
  background: linear-gradient(100deg, var(--accent), var(--accent-2));
  border-color: transparent;
  color: #04140f;
  font-weight: 700;
  box-shadow: 0 12px 30px -16px
    color-mix(in srgb, var(--accent) 80%, transparent);
}

.btn-primary:hover {
  background: linear-gradient(100deg, var(--accent), var(--accent-2));
  filter: brightness(1.07);
  box-shadow: 0 16px 36px -16px
    color-mix(in srgb, var(--accent) 90%, transparent);
}

.install {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin-top: 28px;
  padding: 12px 14px 12px 20px;
  border: 1px solid color-mix(in srgb, var(--accent) 25%, var(--border));
  border-radius: 12px;
  background: var(--code-bg);
  font-family:
    ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
  font-size: 15px;
  color: #d7e0f0;
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, 0.02) inset,
    0 18px 40px -28px color-mix(in srgb, var(--accent) 60%, transparent);
}

.install .prompt {
  color: var(--accent);
  user-select: none;
}

.hero-shot {
  margin: 52px auto 0;
  max-width: 1000px;
  border: 1px solid color-mix(in srgb, var(--border) 80%, var(--accent-2));
  border-radius: 18px;
  overflow: hidden;
  background: var(--code-bg);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.04) inset,
    0 40px 90px -40px rgba(0, 0, 0, 0.85);
}

.hero-shot img {
  display: block;
  width: 100%;
  height: auto;
}

.hero-shot-link {
  display: block;
  cursor: zoom-in;
}

.hero-shot-caption {
  margin: 0;
  padding: 10px 16px;
  border-top: 1px solid var(--border);
  background: var(--bg-soft);
  color: var(--muted);
  font-size: 13.5px;
  text-align: center;
}

/* The demo screenshot is the only thing above the fold that needs a real
   click target: a hover cue plus the zoom-in cursor says it opens full size. */
.hero-shot-link:hover img,
.hero-shot-link:focus-visible img {
  transform: scale(1.004);
  transition: transform 0.2s ease;
}

/* The install one-liner is the most useful thing to copy on the whole site,
   so it gets a copy button like a <pre> block (site.js does the work). The
   button is a FLEX SIBLING, not an overlay: on a narrow screen an absolutely
   positioned button sat on top of the command text. */
.install {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  max-width: 100%;
}

.install .copy-btn {
  position: static;
  flex: none;
  opacity: 1;
}

/* ---------- sections ---------- */

section {
  padding: clamp(56px, 7vw, 88px) 0;
}

.section-head {
  max-width: 700px;
  margin: 0 auto 40px;
  text-align: center;
}

.section-head h2 {
  margin: 0;
  font-size: clamp(25px, 3.6vw, 34px);
  line-height: 1.2;
  letter-spacing: -0.022em;
  font-weight: 750;
}

.section-head p {
  margin: 12px 0 0;
  color: var(--muted);
  font-size: 16.5px;
  text-wrap: pretty;
}

.grid {
  display: grid;
  gap: 18px;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}

.card {
  position: relative;
  padding: 26px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: linear-gradient(
    170deg,
    color-mix(in srgb, var(--card) 92%, var(--bg-soft)),
    var(--card)
  );
  transition:
    background 0.18s ease,
    border-color 0.18s ease,
    transform 0.18s ease,
    box-shadow 0.18s ease;
}

.card:hover {
  background: var(--card-hover);
  border-color: color-mix(in srgb, var(--accent) 42%, var(--border));
  transform: translateY(-2px);
  box-shadow: 0 22px 44px -30px rgba(0, 0, 0, 0.75);
}

/* The docs grid uses <a class="card">: keep the text colour and drop the
   underline, otherwise a documentation link looks like a broken paragraph. */
a.card,
a.card:hover {
  color: var(--text);
  text-decoration: none;
}

a.card p {
  color: var(--muted);
}

.provider code,
.card code {
  word-break: break-word;
}

.card h3 {
  margin: 0 0 8px;
  font-size: 17.5px;
  line-height: 1.35;
  letter-spacing: -0.012em;
}

.card p {
  margin: 0;
  color: var(--muted);
  font-size: 15px;
  line-height: 1.6;
}

.card .icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  margin-bottom: 16px;
  border-radius: 12px;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 18%, transparent);
  font-size: 20px;
}

/* ---------- steps ---------- */

.steps {
  display: grid;
  gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  counter-reset: step;
}

.step {
  position: relative;
  padding: 24px 24px 24px 68px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--card);
  transition:
    border-color 0.18s ease,
    background 0.18s ease;
}

.step:hover {
  background: var(--card-hover);
  border-color: color-mix(in srgb, var(--accent-2) 35%, var(--border));
}

.step::before {
  counter-increment: step;
  content: counter(step);
  position: absolute;
  left: 20px;
  top: 20px;
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent-2) 18%, transparent);
  color: var(--accent-2);
  font-weight: 700;
  font-size: 14px;
}

.step h3 {
  margin: 0 0 6px;
  font-size: 16px;
}

.step p {
  margin: 0;
  color: var(--muted);
  font-size: 14.5px;
}

.step code {
  font-size: 13px;
}

/* ---------- providers ---------- */

.providers {
  display: grid;
  gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

.provider {
  padding: 26px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: linear-gradient(
    160deg,
    var(--card),
    color-mix(in srgb, var(--card) 70%, var(--bg-soft))
  );
  transition:
    border-color 0.18s ease,
    transform 0.18s ease,
    box-shadow 0.18s ease;
}

.provider:hover {
  border-color: color-mix(in srgb, var(--accent) 38%, var(--border));
  transform: translateY(-2px);
  box-shadow: 0 22px 44px -30px rgba(0, 0, 0, 0.75);
}

.provider h3 {
  margin: 0 0 4px;
  font-size: 17px;
}

.provider .tag {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 8px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 600;
  vertical-align: middle;
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  color: var(--accent);
}

.provider p {
  margin: 8px 0 0;
  color: var(--muted);
  font-size: 14.5px;
}

.provider code {
  font-size: 13px;
}

/* ---------- code blocks ---------- */

pre,
code {
  font-family:
    ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
}

code {
  padding: 2px 6px;
  border-radius: 6px;
  background: color-mix(in srgb, var(--accent-2) 12%, transparent);
  font-size: 0.9em;
}

pre {
  position: relative;
  padding: 18px 20px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--code-bg);
  color: #d7e0f0;
  overflow-x: auto;
  font-size: 14px;
  line-height: 1.6;
}

/* The scroll container is a child, so the copy button can sit OUTSIDE it:
   an absolute button inside an overflow-x <pre> scrolled away with the text. */
pre > .pre-scroll {
  overflow-x: auto;
  /* The button floats over the top-right corner of the scroll box. */
  margin: -6px -8px -6px 0;
  padding-right: 74px;
}

pre code {
  padding: 0;
  background: none;
  color: inherit;
  font-size: inherit;
}

/* ---------- docs pages ---------- */

.doc {
  padding: 44px 0 64px;
}

.doc .wrap {
  max-width: 860px;
}

.doc h1 {
  margin: 0 0 6px;
  font-size: clamp(28px, 4vw, 38px);
  letter-spacing: -0.025em;
}

.doc h2 {
  margin: 40px 0 12px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
  font-size: 23px;
  letter-spacing: -0.015em;
}

.doc h3 {
  margin: 26px 0 8px;
  font-size: 18px;
}

.doc h4 {
  margin: 20px 0 6px;
  font-size: 16px;
}

/* The doc body is wrapped in <div class="wrap" markdown="1"> so the page text
   keeps the same column as the header; without this the Markdown inside the
   div would lose its spacing. */
.doc-lead {
  margin: 0 0 18px;
  color: var(--muted);
  font-size: 17px;
}

/* A breadcrumb above the title: "Home / Commands" makes it obvious which
   site and which section a deep doc page belongs to. */
.crumbs {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-bottom: 12px;
  color: var(--muted);
  font-size: 13.5px;
}

.crumbs a {
  color: var(--muted);
}

.crumbs a:hover {
  color: var(--text);
}

.crumbs span[aria-current] {
  color: var(--text);
}

.doc .wrap > :first-child {
  margin-top: 0;
}

.doc p,
.doc li {
  color: color-mix(in srgb, var(--text) 88%, var(--muted));
}

.doc ul,
.doc ol {
  padding-left: 22px;
}

.doc li {
  margin: 6px 0;
}

.doc table {
  width: 100%;
  border-collapse: collapse;
  margin: 18px 0;
  font-size: 14.5px;
}

/* The option tables are wide; on a phone they must scroll rather than push
   the whole page sideways. */
.doc table {
  display: block;
  overflow-x: auto;
}

.doc th,
.doc td {
  padding: 9px 12px;
  border: 1px solid var(--border);
  text-align: left;
  vertical-align: top;
}

.doc th {
  background: var(--bg-soft);
}

.doc blockquote {
  margin: 18px 0;
  padding: 10px 18px;
  border-left: 3px solid var(--accent);
  background: var(--bg-soft);
  border-radius: 0 8px 8px 0;
  color: var(--muted);
}

.doc img {
  max-width: 100%;
  height: auto;
  border-radius: 10px;
  border: 1px solid var(--border);
}

.doc hr {
  border: 0;
  border-top: 1px solid var(--border);
  margin: 32px 0;
}

.doc-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 40px;
  padding-top: 22px;
  border-top: 1px solid var(--border);
  font-size: 14.5px;
}

/* The copy above the body is a way OUT of a wrong page, so it sits right
   under the intro and has no divider of its own. */
.doc-nav-top {
  margin: 18px 0 30px;
  padding: 0;
  border-top: 0;
  font-size: 13.5px;
}

.doc-nav a {
  padding: 6px 13px;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--muted);
}

.doc-nav a:hover {
  color: var(--text);
  border-color: var(--accent);
  text-decoration: none;
}

/* ---------- footer ---------- */

.site-footer {
  margin-top: 72px;
  padding: 56px 0 44px;
  border-top: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
  background: var(--bg-soft);
  font-size: 14.5px;
  color: var(--muted);
}

.footer-grid {
  display: grid;
  gap: 28px;
  grid-template-columns: 1.4fr repeat(3, 1fr);
}

@media (max-width: 860px) {
  .footer-grid {
    grid-template-columns: 1fr 1fr;
  }
}

@media (max-width: 520px) {
  .footer-grid {
    grid-template-columns: 1fr;
  }
}

.site-footer h4 {
  margin: 0 0 10px;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text);
}

.site-footer ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.site-footer li {
  margin: 7px 0;
}

.site-footer a {
  color: var(--muted);
}

.site-footer a:hover {
  color: var(--text);
}

.site-footer .about p {
  margin: 10px 0 0;
  max-width: 320px;
}

.site-footer .fine {
  margin-top: 28px;
  padding-top: 18px;
  border-top: 1px solid var(--border);
  font-size: 13px;
  color: var(--muted);
}

/* ---------- narrow screens ---------- */

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

  .hero {
    padding: 44px 0 28px;
  }

  .hero p.lead {
    font-size: 16.5px;
  }

  section {
    padding: 40px 0;
  }

  .install {
    max-width: 100%;
    overflow-x: auto;
    font-size: 13px;
  }

  pre {
    font-size: 13px;
  }

  .doc h1 {
    font-size: 27px;
  }

  .site-footer {
    padding: 32px 0;
  }
}

/* ---------- mobile menu button ---------- */

/* Hidden on a wide screen: the links are visible there. Under 720px the nav
   becomes a dropdown (see the narrow-screen block below). */
.nav-toggle {
  display: none;
  margin-left: auto;
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: 9px;
  background: var(--bg-soft);
  cursor: pointer;
}

.nav-toggle span {
  display: block;
  width: 18px;
  height: 2px;
  margin: 3px 0;
  border-radius: 2px;
  background: var(--text);
}

/* ---------- copy button on a code block ---------- */

/* site.js injects it; a page without JS keeps the plain <pre>. */
/* The button itself (shared by a <pre> block and the hero install line): the
   LOOK lives here, the POSITION lives in the two context rules below. Without
   this split the install button inherited only `position: absolute` and lost
   its frame and padding — it rendered as a bare text link. */
.copy-btn {
  padding: 4px 10px;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: color-mix(in srgb, var(--card) 80%, transparent);
  color: var(--muted);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
  opacity: 0.7;
  transition:
    opacity 0.15s ease,
    color 0.15s ease;
}

.copy-btn:hover,
.copy-btn:focus-visible {
  opacity: 1;
}

pre .copy-btn {
  position: absolute;
  top: 8px;
  right: 8px;
}

pre .copy-btn.copied {
  color: var(--accent);
  border-color: var(--accent);
}

/* ---------- theme gallery ---------- */

/* Rendered at the top of <main> on every page
   (docs/_includes/theme-gallery.html). The tiles are real <a> links, so the
   grid degrades to 29 big screenshots; site.js upgrades a left click into a
   <dialog> lightbox. */
.theme-showcase {
  padding: 8px 0 40px;
}

.theme-showcase .section-head {
  margin-bottom: 24px;
}

.theme-gallery {
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  margin: 0;
  padding: 0;
  list-style: none;
}

/* The themes page lists all 29 palettes and is meant to be browsed, so the
   grid starts OPEN there. The same grid on a page that opts into a shorter
   block gets a collapsed state from site.js: with JS off the tiles stay
   visible instead of becoming an empty box. */
.theme-gallery.is-collapsed {
  max-height: 300px;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(180deg, #000 55%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 55%, transparent 100%);
}

.theme-toggle {
  display: block;
  /* No top margin: the button is the gallery's header, the grid follows it. */
  margin: 0 auto 14px;
  padding: 9px 22px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--card);
  color: var(--text);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition:
    border-color 0.15s ease,
    background 0.15s ease;
}

.theme-toggle:hover,
.theme-toggle:focus-visible {
  border-color: var(--accent);
  background: var(--card-hover);
}

/* site.js reveals the button and closes the grid together; the hidden
   attribute stays the source of truth for a JS-off page. */
.theme-toggle[hidden] {
  display: none;
}

.theme-tile {
  position: relative;
  display: block;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 11px;
  /* Paint the palette's own background before the PNG arrives: the first
     paint must already look like a palette, not like a broken image. */
  background: var(--tile-bg, var(--card));
  transition:
    transform 0.15s ease,
    border-color 0.15s ease,
    box-shadow 0.15s ease;
}

.theme-tile:hover,
.theme-tile:focus-visible {
  transform: translateY(-2px);
  border-color: var(--tile-accent, var(--accent));
  box-shadow: 0 14px 34px -18px var(--tile-accent, var(--accent));
  text-decoration: none;
}

.theme-tile img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 900 / 520;
  object-fit: cover;
}

/* The caption sits ON the palette background; a light palette needs dark
   text, a dark one light text (the tile carries its own `bg`). */
.theme-name {
  position: absolute;
  left: 8px;
  bottom: 8px;
  /* A palette name is the only label a tile has: it must stay readable on a
     light palette too, so the pill gets its own contrast. */
  padding: 3px 10px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--tile-bg, #000) 80%, transparent);
  color: color-mix(in srgb, var(--tile-accent, #fff) 85%, #fff);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  backdrop-filter: blur(4px);
}

.theme-tile.is-light .theme-name {
  background: rgba(255, 255, 255, 0.78);
  color: #1b2430;
}

.theme-more {
  margin: 16px 0 0;
  text-align: center;
  font-size: 14.5px;
}

/* ---------- lightbox ---------- */

.lightbox {
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--card);
  color: var(--text);
  max-width: min(1120px, 94vw);
}

.lightbox::backdrop {
  background: rgba(4, 8, 18, 0.72);
  backdrop-filter: blur(3px);
}

.lightbox figure {
  margin: 0;
}

.lightbox img {
  display: block;
  width: 100%;
  height: auto;
}

.lightbox-caption {
  padding: 8px 14px 12px;
  font-size: 13.5px;
  color: var(--muted);
  font-family:
    ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
}

.lightbox-close {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 1;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: color-mix(in srgb, var(--bg) 80%, transparent);
  color: var(--text);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

.lightbox-close:hover {
  background: var(--card-hover);
}

/* ---------- narrow screens: the menu becomes a dropdown ---------- */

@media (max-width: 720px) {
  .nav-toggle {
    display: block;
  }

  .site-nav.open {
    position: absolute;
    top: 64px;
    left: 0;
    right: 0;
    z-index: 30;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    padding: 12px 24px 18px;
    border-bottom: 1px solid var(--border);
    background: var(--bg);
    box-shadow: 0 24px 40px -28px rgba(0, 0, 0, 0.7);
  }

  .site-nav.open a {
    width: 100%;
    padding: 9px 0;
    border-bottom: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
  }
}

@media (max-width: 620px) {
  .theme-gallery {
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 8px;
  }

  .theme-showcase {
    padding-top: 0;
  }
}

/* ---------- motion and print ---------- */

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

  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}

@media print {
  .site-header,
  .site-footer,
  .theme-showcase,
  .lightbox,
  .copy-btn {
    display: none !important;
  }

  body {
    background: #fff;
    color: #000;
  }
}

/* ---------- changelog ---------- */

/* The changelog is 294 releases. It is NOT a normal doc page: the jump list
   and the per-release fold exist so a reader can reach one version instead of
   scrolling through 2800 lines. The grid keeps the version column narrow so a
   long release note still has a readable measure. */
.changelog-lead {
  margin: 0 0 18px;
  color: var(--muted);
}

.changelog-jump {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0 0 28px;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--bg-soft);
  font-size: 13px;
}

/* A year is a folded <details>: 316 versions in one flat list is exactly the
   endless pill wall the grouping exists to remove. The links inside keep the
   pill look, so an opened year reads like the old list. */
.ch-jump-year > summary {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 2px;
  cursor: pointer;
  list-style: none;
  color: var(--text);
  font-weight: 600;
}

.ch-jump-year > summary::-webkit-details-marker {
  display: none;
}

.ch-jump-year > summary::before {
  content: '▸';
  color: var(--muted);
  font-size: 11px;
  transition: transform 0.15s ease;
}

.ch-jump-year[open] > summary::before {
  transform: rotate(90deg);
}

.ch-jump-count {
  margin-left: auto;
  padding: 1px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--border) 60%, transparent);
  color: var(--muted);
  font-size: 11.5px;
  font-weight: 500;
}

.ch-jump-links {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 6px 0 10px 20px;
}

.changelog-jump a {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 3px 9px;
  border: 1px solid transparent;
  border-radius: 999px;
  color: var(--muted);
  /* A version is a value, not prose: the mono face makes v2.95.5 and v2.95.4
     distinguishable at a glance. */
  font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
}

.changelog-jump a:hover {
  border-color: var(--border);
  color: var(--text);
  text-decoration: none;
}

.changelog-jump time {
  color: color-mix(in srgb, var(--muted) 65%, transparent);
  font-size: 11.5px;
}

.ch-release {
  margin: 0 0 10px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--card);
}

/* A folded release still shows its version: <summary> is the header, so the
   closed state is a scannable list of versions, not 294 empty bars. */
.ch-release > summary {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 18px;
  cursor: pointer;
  list-style: none;
}

.ch-release > summary::-webkit-details-marker {
  display: none;
}

.ch-release > summary::before {
  content: '▸';
  color: var(--muted);
  font-size: 12px;
  transition: transform 0.15s ease;
}

.ch-release[open] > summary::before {
  transform: rotate(90deg);
}

.ch-release > summary h2 {
  margin: 0;
  font-size: 17px;
  font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
  font-weight: 650;
}

.ch-release > summary time {
  margin-left: auto;
  color: var(--muted);
  font-size: 13px;
}

.ch-release .ch-group {
  padding: 0 18px 6px;
}

.ch-release .ch-group h3 {
  margin: 12px 0 6px;
  color: var(--muted);
  font-size: 12.5px;
  text-transform: uppercase;
  letter-spacing: 0.07em;
}

.ch-release .ch-group ul {
  margin: 0;
  padding-left: 20px;
}

.ch-release .ch-group li {
  margin: 5px 0;
  color: color-mix(in srgb, var(--text) 88%, var(--muted));
  font-size: 15.5px;
}

/* The anchor target must not hide under the sticky header after a jump. */
.ch-release:target {
  border-color: color-mix(in srgb, var(--accent-2) 55%, var(--border));
}

.ch-empty {
  margin: 0;
  padding: 0 18px 14px;
  color: var(--muted);
}
