/* =========================================================================
   ROOMS — User Guide
   Theme ported from the andor app (src/styles/variables.scss + mixins.scss).
   Mobile-first: base rules target the smallest viewport, larger viewports are
   layered on top with min-width queries.
   ========================================================================= */

/* -------------------------------------------------------------------------
   Design tokens
   Colors are RGB triplets (not rgb() strings) so they can be used with an
   arbitrary alpha — the same convention the app uses.
   ------------------------------------------------------------------------- */

:root {
  /* Blue accent, sampled from a themed ROOMS instance (see the screenshots). */
  --accent: 74, 159, 216;
  --accent-deep: 33, 100, 158;
  --accent-soft: 138, 199, 236;

  --success: 0, 172, 110;
  /* --warning is per-theme: see the theme blocks below. The same amber cannot
     serve as label text on both a white and a near-black surface without
     failing contrast on one of them. */

  --border-radius: 0.75rem;
  --radius-sm: 0.5rem;
  --radius-lg: 1.25rem;

  --animation-duration: 0.2s;
  --animation-timefunc: ease;

  --content-max: 54rem;
  --toc-width: 15rem;
  --header-height: 3.75rem;

  --z-backdrop: -10;
  --z-base: 1;
  --z-sticky: 20;
  --z-lightbox: 100;

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

/* --- Light theme (default) ---------------------------------------------- */

:root,
:root[data-theme="light"] {
  color-scheme: light;

  --text: 20, 26, 34;
  --text-muted: 88, 100, 116;
  --accent-text: var(--accent-deep);
  /* Dark enough to clear 4.5:1 as label text on the light glass surface. */
  --warning: 140, 86, 0;

  --bg-image: url("assets/bg_light.webp");
  --logo-image: url("assets/logo_light.svg");

  /* Scrim over the wallpaper. The stock photos behind the glass are busy and
     bright; without a strong scrim, body text over them fails contrast. The
     image still reads through as texture, which is what the blur needs. */
  --scrim: linear-gradient(
    160deg,
    rgba(232, 240, 248, 0.9) 0%,
    rgba(244, 247, 250, 0.94) 45%,
    rgba(226, 238, 248, 0.9) 100%
  );

  /* Frosted glass knobs — consumed by .glass below. */
  --glass-veil-a: rgba(255, 255, 255, 0.72);
  --glass-veil-b: rgba(255, 255, 255, 0.5);
  --glass-border: rgba(255, 255, 255, 0.75);
  --glass-border-lit: rgba(255, 255, 255, 0.95);
  --glass-highlight: rgba(255, 255, 255, 0.9);
  --glass-shadow: 0 6px 18px rgba(24, 48, 78, 0.12);

  --hairline: rgba(20, 40, 70, 0.12);
  --code-bg: rgba(20, 40, 70, 0.07);
}

/* --- Dark theme ---------------------------------------------------------- */

:root[data-theme="dark"] {
  color-scheme: dark;

  --text: 235, 239, 242;
  --text-muted: 160, 172, 186;
  --accent-text: var(--accent-soft);
  --warning: 235, 172, 40;

  --bg-image: url("assets/bg_dark.webp");
  --logo-image: url("assets/logo_dark.svg");

  --scrim: linear-gradient(
    160deg,
    rgba(8, 13, 20, 0.93) 0%,
    rgba(12, 20, 31, 0.9) 45%,
    rgba(7, 12, 20, 0.94) 100%
  );

  /* The app's mixin uses a 0.12 → 0.04 white veil, tuned for short UI labels.
     A documentation page is mostly body copy, so the veil is strengthened
     here — same recipe, enough opacity to read a paragraph against. */
  --glass-veil-a: rgba(255, 255, 255, 0.1);
  --glass-veil-b: rgba(255, 255, 255, 0.035);
  --glass-border: rgba(255, 255, 255, 0.1);
  --glass-border-lit: rgba(255, 255, 255, 0.2);
  --glass-highlight: rgba(255, 255, 255, 0.08);
  --glass-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);

  --hairline: rgba(255, 255, 255, 0.12);
  --code-bg: rgba(255, 255, 255, 0.08);
}

/* -------------------------------------------------------------------------
   Reset & base
   ------------------------------------------------------------------------- */

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

html {
  scroll-behavior: smooth;
  /* Anchored headings must clear the sticky header. */
  scroll-padding-top: calc(var(--header-height) + 1rem);
}

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.65;
  color: rgb(var(--text));
  background: rgba(var(--text), 0); /* keeps the backdrop the only paint */
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* The wallpaper + scrim live on a fixed layer rather than on `body` so the
   glass panels have something stable to blur while the page scrolls. */
.backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--z-backdrop);
  background-image: var(--scrim), var(--bg-image);
  background-size: cover, cover;
  background-position: center, center;
  background-repeat: no-repeat, no-repeat;
  pointer-events: none;
}

img {
  max-width: 100%;
  height: auto;
}

a {
  color: rgb(var(--accent-text));
  text-decoration-color: rgba(var(--accent), 0.5);
  text-underline-offset: 0.15em;
}

a:hover {
  text-decoration-color: rgb(var(--accent));
}

code {
  font-family: var(--font-mono);
  font-size: 0.875em;
  padding: 0.1em 0.35em;
  border-radius: 0.3em;
  background: var(--code-bg);
}

h1,
h2,
h3,
h4 {
  line-height: 1.2;
  margin: 0;
  font-weight: 650;
  letter-spacing: -0.01em;
}

p {
  margin: 0 0 1rem;
}

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

ul {
  margin: 0 0 1rem;
  padding-left: 1.25rem;
}

li {
  margin-bottom: 0.35rem;
}

li:last-child {
  margin-bottom: 0;
}

:focus-visible {
  outline: 2px solid rgb(var(--accent));
  outline-offset: 2px;
  border-radius: 0.25rem;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* -------------------------------------------------------------------------
   Frosted glass — port of `@mixin frosted-glass` (andor/src/styles/mixins.scss)
   ------------------------------------------------------------------------- */

/*
 * The blur sits on an inset ::before while the drop shadow stays on the host.
 * That split is deliberate and carried over from the app: Chromium rasterizes
 * an element's shadow into its backdrop-filter render surface and can draw the
 * two a frame out of sync, so the shadow appears to detach and flicker
 * (crbug.com/41471914). Keeping them on separate boxes avoids it.
 *
 * The app additionally sets `isolation: isolate` to sever backdrop-filter
 * inheritance under glassy ancestors. This port uses `z-index: 0` instead —
 * enough of a stacking context to contain the negative-z pseudo, and no more.
 * `isolation: isolate` would form a *backdrop root*, and the blur here lives
 * on a pseudo *inside* the host, so the host would be cutting off its own
 * blur's backdrop. The app can isolate because its blur layer sits under a
 * genuinely nested surface; ours is the surface. (No .glass on this page is
 * nested inside another .glass, so there is no inheritance to sever anyway —
 * scene.css isolates `.scene`, which is where the replica's own blurs live.)
 *
 * Gotcha worth knowing before putting `.glass` on anything that fades:
 * `opacity` forms a backdrop root too — both a value below 1 and the
 * compositing promotion Chromium gives an element with a transitioning
 * opacity. Either way this ::before is left with nothing to sample and the
 * blur silently does not render, with no warning anywhere but the pixels. It
 * cost the crossfading step cards their frosted surface entirely; see
 * .scrolly__box in scene.css for the fix, and put the blur on a still box.
 */
.glass {
  position: relative;
  z-index: 0;
  border: 1px solid var(--glass-border);
  border-left-color: var(--glass-border-lit);
  border-radius: var(--border-radius);
  box-shadow: var(--glass-shadow);
}

.glass::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: linear-gradient(135deg, var(--glass-veil-a), var(--glass-veil-b));
  box-shadow: inset 0 1px 0 var(--glass-highlight);
  backdrop-filter: blur(12px) saturate(1.2);
  -webkit-backdrop-filter: blur(12px) saturate(1.2);
  pointer-events: none;
}

/* Accent gradient ring — port of `@mixin accent-ring-surface` + `masked-ring`.
   The ring is a masked overlay so it can carry a gradient a plain border
   cannot. Composes with .glass (which owns ::before) via ::after. */
.accent-ring::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(
    135deg,
    rgba(var(--accent), 0.55),
    rgba(var(--accent), 0.12) 40%,
    rgba(var(--accent), 0.3) 60%,
    rgba(var(--accent), 0.55)
  );
  -webkit-mask:
    linear-gradient(#fff 0 0) content-box,
    linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}

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

.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-height: var(--header-height);
  padding: 0.5rem 1rem;
  border-radius: 0;
  border-width: 0 0 1px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  color: inherit;
}

.brand__logo {
  display: block;
  width: 6.2rem;
  height: 1.4rem;
  background-image: var(--logo-image);
  background-repeat: no-repeat;
  background-position: left center;
  background-size: contain;
}

.brand__sub {
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgb(var(--text-muted));
  padding-left: 0.6rem;
  border-left: 1px solid var(--hairline);
}

.theme-toggle {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.2rem;
  height: 2.2rem;
  padding: 0;
  cursor: pointer;
  color: inherit;
  border: 1px solid rgba(var(--accent), 0.4);
  border-radius: 50%;
  background: rgba(var(--accent), 0.14);
  transition:
    background var(--animation-duration) var(--animation-timefunc),
    border-color var(--animation-duration) var(--animation-timefunc);
}

.theme-toggle:hover {
  background: rgba(var(--accent), 0.26);
  border-color: rgba(var(--accent), 0.6);
}

.theme-toggle svg {
  width: 1.15rem;
  height: 1.15rem;
  fill: currentColor;
}

/* Only one of the two glyphs shows, decided by the active theme. */
:root[data-theme="dark"] .theme-toggle .icon-sun,
:root:not([data-theme="dark"]) .theme-toggle .icon-moon {
  display: none;
}

/* -------------------------------------------------------------------------
   Layout
   ------------------------------------------------------------------------- */

.layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
  max-width: 76rem;
  margin: 0 auto;
  padding: 1.5rem 1rem 4rem;
}

main {
  min-width: 0;
}

/* -------------------------------------------------------------------------
   Table of contents
   ------------------------------------------------------------------------- */

.toc {
  padding: 0.75rem 1rem;
  align-self: start;
}

.toc__toggle {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0;
  font: inherit;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgb(var(--text-muted));
  background: none;
  border: 0;
  cursor: pointer;
}

.toc__toggle::after {
  content: "";
  margin-left: auto;
  width: 0.5rem;
  height: 0.5rem;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translate(-0.15em, -0.15em);
  transition: transform var(--animation-duration) var(--animation-timefunc);
}

.toc--collapsed .toc__toggle::after {
  transform: rotate(-45deg) translate(-0.1em, 0.1em);
}

/* Static heading that replaces the toggle button once the TOC is a permanent
   sidebar (see the 80rem breakpoint). */
.toc__label {
  display: none;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgb(var(--text-muted));
}

/* Visible by default so the TOC still works if main.js never runs; the
   collapsed state is applied by script. */
.toc--collapsed .toc__body {
  display: none;
}

.toc__body {
  margin-top: 0.75rem;
}

.toc__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.toc__list--sub {
  margin: 0.25rem 0 0.75rem;
  padding-left: 0.75rem;
  border-left: 1px solid var(--hairline);
}

.toc__list a {
  display: block;
  padding: 0.25rem 0.5rem;
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
  line-height: 1.35;
  color: rgb(var(--text-muted));
  text-decoration: none;
  transition:
    background var(--animation-duration) var(--animation-timefunc),
    color var(--animation-duration) var(--animation-timefunc);
}

.toc__list--top > li > a {
  font-weight: 650;
  color: rgb(var(--text));
  margin-top: 0.35rem;
}

.toc__list a:hover {
  background: rgba(var(--accent), 0.12);
  color: rgb(var(--text));
}

.toc__list a[aria-current="true"] {
  background: rgba(var(--accent), 0.18);
  color: rgb(var(--accent-text));
  font-weight: 650;
}

/* -------------------------------------------------------------------------
   Hero
   ------------------------------------------------------------------------- */

.hero {
  padding: 1.75rem 1.25rem;
  margin-bottom: 2rem;
  text-align: center;
}

.hero h1 {
  font-size: clamp(1.75rem, 5vw, 2.6rem);
  margin-bottom: 0.75rem;
}

.hero__lead {
  font-size: 1.05rem;
  color: rgb(var(--text-muted));
  max-width: 40rem;
  margin: 0 auto 1.5rem;
}

.pillars {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.6rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.pillars li {
  margin: 0;
  padding: 0.35rem 0.9rem;
  font-size: 0.85rem;
  font-weight: 600;
  border-radius: 999px;
  color: rgb(var(--accent-text));
  background: rgba(var(--accent), 0.14);
  border: 1px solid rgba(var(--accent), 0.35);
}

/* -------------------------------------------------------------------------
   Sections & steps
   ------------------------------------------------------------------------- */

.section {
  margin-bottom: 3rem;
}

.section__head {
  margin-bottom: 1.5rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--hairline);
}

.section__eyebrow {
  display: block;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgb(var(--accent-text));
  margin-bottom: 0.35rem;
}

.section__head h2 {
  font-size: clamp(1.4rem, 3.5vw, 1.9rem);
}

.section__intro {
  margin-top: 0.6rem;
  color: rgb(var(--text-muted));
}

.step {
  position: relative;
  padding: 1.25rem;
  margin-bottom: 1.25rem;
}

.step__head {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.step__num {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.9rem;
  height: 1.9rem;
  padding: 0 0.4rem;
  font-size: 0.85rem;
  font-weight: 700;
  border-radius: 999px;
  color: #fff;
  background: linear-gradient(
    330deg,
    rgb(var(--accent-deep)) 0%,
    rgb(var(--accent)) 100%
  );
  box-shadow: 0 2px 8px rgba(var(--accent), 0.35);
}

.step__head h3 {
  font-size: 1.15rem;
}

.step__body > :last-child {
  margin-bottom: 0;
}

/* -------------------------------------------------------------------------
   Screenshots
   ------------------------------------------------------------------------- */

.shot {
  margin: 0 0 1.25rem;
  padding: 0.5rem;
  border-radius: var(--border-radius);
}

.shot__btn {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  border-radius: var(--radius-sm);
  line-height: 0;
}

.shot__btn img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-sm);
}

.shot figcaption {
  margin-top: 0.6rem;
  font-size: 0.85rem;
  line-height: 1.5;
  color: rgb(var(--text-muted));
  text-align: center;
}

/* Portrait captures (e.g. the full home screen) would otherwise run taller
   than the viewport and push the prose out of sight. */
.shot--tall .shot__btn img {
  width: auto;
  max-height: 34rem;
  margin: 0 auto;
}

/* The vertical view-switcher rail is 118px wide — shown at native scale. */
.shot--strip .shot__btn img {
  width: auto;
  max-height: 18rem;
  margin: 0 auto;
}

/* Small UI crops rendered inline in the prose, mid-sentence. */
.ui-chip {
  height: 1.7em;
  width: auto;
  vertical-align: -0.5em;
  margin: 0 0.15em;
  border-radius: 0.3em;
  box-shadow: 0 1px 4px rgb(0 0 0 / 0.25);
}

.ui-chip--wide {
  height: 1.7em;
  vertical-align: -0.5em;
}

/* -------------------------------------------------------------------------
   Callouts
   ------------------------------------------------------------------------- */

.callout {
  position: relative;
  margin: 1.25rem 0;
  padding: 0.9rem 1rem 0.9rem 1.1rem;
  border-radius: var(--border-radius);
  border-left: 3px solid rgb(var(--accent));
  background: rgba(var(--accent), 0.1);
  font-size: 0.95rem;
}

.callout:last-child {
  margin-bottom: 0;
}

.callout__title {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 700;
  font-size: 0.85rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin-bottom: 0.4rem;
  color: rgb(var(--accent-text));
}

.callout--note {
  border-left-color: rgb(var(--text-muted));
  background: rgba(var(--text), 0.06);
}

.callout--note .callout__title {
  color: rgb(var(--text-muted));
}

.callout--soon {
  border-left-color: rgb(var(--warning));
  background: rgba(var(--warning), 0.12);
}

.callout--soon .callout__title {
  color: rgb(var(--warning));
}

/* -------------------------------------------------------------------------
   "Coming soon" stubs
   ------------------------------------------------------------------------- */

.stub {
  padding: 1.25rem;
  margin-bottom: 1.25rem;
}

.stub__head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-bottom: 0.75rem;
}

.stub__head h3 {
  font-size: 1.1rem;
}

.badge {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border-radius: 999px;
  color: rgb(var(--warning));
  background: rgba(var(--warning), 0.16);
  border: 1px solid rgba(var(--warning), 0.4);
}

.stub__needs {
  margin-top: 0.75rem;
  font-size: 0.85rem;
  color: rgb(var(--text-muted));
}

/* -------------------------------------------------------------------------
   Legend (floor-plan key)
   ------------------------------------------------------------------------- */

.legend {
  list-style: none;
  margin: 1rem 0;
  padding: 0;
  display: grid;
  gap: 0.6rem;
}

.legend li {
  display: flex;
  align-items: flex-start;
  gap: 0.65rem;
  margin: 0;
  font-size: 0.95rem;
}

.legend__key {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.65rem;
  height: 1.65rem;
  border-radius: var(--radius-sm);
  background: rgba(var(--accent), 0.14);
  border: 1px solid rgba(var(--accent), 0.3);
  font-size: 0.9rem;
  line-height: 1;
}

/* -------------------------------------------------------------------------
   Footer
   ------------------------------------------------------------------------- */

.site-footer {
  max-width: 76rem;
  margin: 0 auto;
  padding: 1.5rem 1rem 3rem;
  font-size: 0.85rem;
  color: rgb(var(--text-muted));
  text-align: center;
}

/* -------------------------------------------------------------------------
   Lightbox
   ------------------------------------------------------------------------- */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--z-lightbox);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 2rem 1rem;
  background: rgb(0 0 0 / 0.8);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  cursor: zoom-out;
}

.lightbox[data-open="true"] {
  display: flex;
}

.lightbox img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  border-radius: var(--border-radius);
  box-shadow: 0 12px 48px rgb(0 0 0 / 0.6);
}

.lightbox__close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  width: 2.5rem;
  height: 2.5rem;
  font-size: 1.5rem;
  line-height: 1;
  color: #fff;
  cursor: pointer;
  background: rgb(255 255 255 / 0.12);
  border: 1px solid rgb(255 255 255 / 0.25);
  border-radius: 50%;
}

.lightbox__close:hover {
  background: rgb(255 255 255 / 0.22);
}

body.is-locked {
  overflow: hidden;
}

/* -------------------------------------------------------------------------
   Tablet — 50rem
   ------------------------------------------------------------------------- */

@media only screen and (min-width: 50rem) {
  .layout {
    padding: 2rem 1.5rem 4rem;
  }

  .hero {
    padding: 2.5rem 2rem;
  }

  .step,
  .stub {
    padding: 1.5rem;
  }

  .shot {
    padding: 0.75rem;
  }

  .legend {
    grid-template-columns: 1fr 1fr;
  }
}

/* -------------------------------------------------------------------------
   Desktop — 80rem. The TOC becomes a permanent sticky sidebar.
   ------------------------------------------------------------------------- */

@media only screen and (min-width: 80rem) {
  .layout {
    grid-template-columns: var(--toc-width) minmax(0, 1fr);
    gap: 2.5rem;
    align-items: start;
  }

  .toc {
    position: sticky;
    top: calc(var(--header-height) + 1.5rem);
    max-height: calc(100dvh - var(--header-height) - 3rem);
    overflow-y: auto;
  }

  .toc__toggle {
    display: none;
  }

  .toc__label {
    display: block;
  }

  /* The collapsed state is a mobile affordance only. */
  .toc--collapsed .toc__body {
    display: block;
  }

  main {
    max-width: var(--content-max);
  }
}

/* -------------------------------------------------------------------------
   Short viewports — the sticky sidebar must not outgrow the window.
   ------------------------------------------------------------------------- */

@media only screen and (max-height: 34rem) {
  .toc {
    position: static;
    max-height: none;
  }

  .shot--tall .shot__btn img {
    max-height: 20rem;
  }
}

/* -------------------------------------------------------------------------
   Motion & print
   ------------------------------------------------------------------------- */

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

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

@media print {
  .backdrop,
  .toc,
  .theme-toggle,
  .lightbox {
    display: none !important;
  }

  .glass {
    box-shadow: none;
    border-color: #ccc;
  }

  .glass::before {
    display: none;
  }

  body {
    color: #000;
  }
}

/* -------------------------------------------------------------------------
   Heading anchors

   A handle for copying a link to a section or a step. Hidden until the
   heading is hovered or the link itself is focused — always-on markers add
   visual noise to every heading for a feature used occasionally — but never
   `display: none`, so it stays in the tab order and reachable by keyboard.
   ------------------------------------------------------------------------- */

.anchor-link {
  margin-left: 0.4em;
  color: rgb(var(--accent));
  font-weight: 500;
  text-decoration: none;
  opacity: 0;
  transition: opacity 0.15s ease;
}

/* Generated rather than written into the DOM — see main.js. Keeping it out of
   heading.textContent is what stops it appearing in labels built from the
   heading, such as the step dots'. */
.anchor-link::before {
  content: "#";
}

h2:hover > .anchor-link,
h3:hover > .anchor-link,
.anchor-link:focus-visible {
  opacity: 1;
}

.anchor-link:hover {
  opacity: 1;
  text-decoration: underline;
}

/* Touch has no hover, so the handle would never appear. */
@media (hover: none) {
  .anchor-link {
    opacity: 0.55;
  }
}
