/* docs.css - presentation for docs.html, which renders the repository's own
   Markdown. vapor-chamber's api.css, adapted: the layout, the focus and
   scroll-spy behaviour and the syntax colours are that file's; the palette is
   the site's (assets/site.css's :root — Forest's neutrals with the mark's
   ember as the accent), mapped onto this file's own smaller set of names so
   the rules below did not have to change. */

:root {
  color-scheme: light dark;
  /* site.css token each one reads, in the comment. */
  --bg: #faf8f1;        /* --bg */
  --fg: #2c2a22;        /* --fg */
  --muted: #6d6857;     /* --muted */
  --line: #ddd5c3;      /* --border */
  --code-bg: #f2ede1;   /* --bg-subtle */
  --link: #e80c08;      /* --accent (ember) */
  --side: #f2ede1;      /* --bg-subtle */
  --accent: #e80c08;    /* --accent (ember) */
  --shadow: 0 1px 3px rgba(60, 50, 30, 0.12), 0 8px 24px rgba(60, 50, 30, 0.08);
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #161615;
    --fg: #ededec;
    --muted: #a1a09a;
    --line: #3e3e3a;
    --code-bg: #1b1b18;
    --link: #e80c08;
    --side: #1b1b18;
    --accent: #e80c08;
    --shadow: 0 0 0 1px rgba(62, 62, 58, 0.6), 0 8px 24px rgba(0, 0, 0, 0.5);
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: 15px/1.65 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
}

/* Underline on hover only, as GitHub does it. Not only convention: the
   Contents block on a page like `router` is 75 links in a row, and underlining
   them at rest renders as one continuous rule instead of a list. */
a { color: var(--link); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Focus, deliberately styled rather than left to the UA. The default ring is
   drawn tight against a link's own box, so on a sidebar row it traced the
   full-width anchor and on an inline Contents entry it cut between the icon
   and the name. :focus-visible only, so a mouse click never paints a ring
   while keyboard navigation always does - which matters more here than usual,
   since the whole page is navigable from the keyboard. */
:focus { outline: none; }

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

/* Inside the flush-edged lists the ring goes inward, or it is clipped by the
   scrolling column. */
.nav a:focus-visible, .toc a:focus-visible, .search-results a:focus-visible {
  outline-offset: -2px;
}

.stepper button:focus-visible, .search-trigger:focus-visible { outline-offset: 1px; }

/* The panel itself carries the focus affordance; a ring on the field inside
   it would be a box within a box. */
#search-input:focus-visible { outline: none; }

/* ---------- top bar ---------- */

.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: .55rem 1.25rem;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}

.brand {
  display: flex;
  align-items: center;
  gap: .5rem;
  font-weight: 650;
  color: var(--fg);
  text-decoration: none;
  white-space: nowrap;
}

.brand .logo-mark { width: 22px; height: 24px; flex: none; }

.topnav { margin-left: auto; display: flex; gap: 1.1rem; font-size: 13.5px; }
.topnav a { color: var(--muted); text-decoration: none; }
.topnav a:hover { color: var(--link); }

.search-trigger {
  display: flex;
  align-items: center;
  gap: .6rem;
  min-width: 15rem;
  padding: .35rem .6rem;
  font: inherit;
  font-size: 13px;
  color: var(--muted);
  background: var(--code-bg);
  border: 1px solid var(--line);
  border-radius: 7px;
  cursor: pointer;
}

.search-trigger:hover { border-color: var(--link); }
.search-trigger kbd {
  margin-left: auto;
  padding: 0 .35rem;
  font: inherit;
  font-size: 11px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--bg);
}

/* ---------- layout ---------- */

.shell {
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr) 220px;
  align-items: start;
}

.sidebar, .toc {
  position: sticky;
  /* Measured, not guessed. This was a hardcoded 49px against a bar that is
     really 53.23px, so the columns sat flush at rest and then slid 4.23px up
     UNDER the bar on the first scroll, while running the same 4.23px past the
     bottom of the viewport. api.js keeps --topbar-h in step with the real
     element, including when the top nav wraps or drops at narrow widths. */
  top: var(--topbar-h, 53px);
  height: calc(100vh - var(--topbar-h, 53px));
  overflow-y: auto;
  /* Reaching either end of a column stops there instead of handing the
     remaining scroll to the page underneath. Without this, running out of
     sidebar carried straight on into the article, so the column looked like
     it was dragging the content with it. */
  overscroll-behavior: contain;
  padding: 1.1rem 0;
  font-size: 13.5px;
}

.sidebar { background: var(--side); border-right: 1px solid var(--line); }
.toc { border-left: 1px solid var(--line); padding: 1.1rem .9rem; }

.sidebar h2, .toc h2 {
  margin: 0 1.1rem .55rem;
  font-size: 10.5px;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--muted);
}

.sidebar-head { display: flex; align-items: baseline; }
.sidebar-head h2 { margin-right: auto; }

.stepper { display: flex; gap: .2rem; margin-right: 1.1rem; }

.stepper button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 18px;
  padding: 0;
  color: var(--muted);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 4px;
  cursor: pointer;
}

/* The chevron is a stroked path, so it centres on the button rather than on a
   text baseline and keeps its weight independent of the font. */
.stepper svg {
  width: 11px;
  height: 11px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.stepper button:hover:not(:disabled) { color: var(--link); border-color: var(--link); }
.stepper button:disabled { opacity: .35; cursor: default; }

.toc h2 { margin-left: 0; }

.nav a {
  display: flex;
  /* Without this the default `stretch` leaves the fixed-height icon pinned to
     the top of a taller row: measured 3.14px above the label's centre. */
  align-items: center;
  gap: .5rem;
  padding: .28rem 1.1rem;
  color: var(--fg);
  text-decoration: none;
}

/* The name starts hard against its icon and the count is pushed to the right
   by this margin, NOT by justify-content: space-between. With three children
   that distributes the free space around the middle one, so every label
   floated at a different x and the sidebar had no left column at all. */
.nav .entry { margin-right: auto; }

.nav a:hover { background: var(--code-bg); }

/* Weight is faked with a horizontal text-shadow rather than set with
   font-weight. A real weight change re-measures the glyphs, so marking a row
   active widened its label and shifted the count column - and in the "On this
   page" list the scroll-spy re-marks a row on every scroll, so the whole
   column twitched while reading. The shadow thickens the strokes and leaves
   the metrics alone. currentColor, so it follows the theme and the kind hue
   without a second declaration. */
.fake-bold, .nav a.active .entry, .toc a.active .label {
  text-shadow: .04vh 0 currentColor;
}

.nav a.active {
  background: var(--code-bg);
  border-left: 3px solid var(--accent);
  padding-left: calc(1.1rem - 3px);
}

/* The file each row reads, so the site and the repository name the same thing. */
.nav .file { color: var(--muted); font: 11px/1 ui-monospace, SFMono-Regular, Menlo, monospace; }
.nav .entry { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.toc a {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .17rem .4rem;
  border-radius: 5px;
  color: var(--muted);
  text-decoration: none;
}

.toc a .label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* A ### under its ##: indented, which gives the grouping without any collapse state to get wrong. */
.toc a.sub { padding-left: 1.2rem; font-size: 12.5px; }
.toc a:hover { color: var(--link); background: var(--code-bg); }

/* The scroll-spy mark: the entry whose heading the reader is currently on.
   Weight comes from the .fake-bold shadow above, not font-weight. */
.toc a.active { color: var(--fg); background: var(--code-bg); }

main { min-width: 0; padding: 1.6rem 2.5rem 6rem; }
article { max-width: 62rem; }

.loading { color: var(--muted); padding: 1rem 1.25rem; }

/* ---------- rendered markdown ---------- */

article h1 {
  font-size: 1.85rem;
  margin: .2rem 0 .6rem;
  border-bottom: 1px solid var(--line);
  padding-bottom: .45rem;
}

article h2 {
  font-size: 1.3rem;
  margin-top: 2.6rem;
  border-bottom: 1px solid var(--line);
  padding-bottom: .3rem;
}

article h3 {
  font-size: 1.05rem;
  margin-top: 2.1rem;
  /* Same measured bar, plus a little air, so a deep link lands the heading
     below it instead of behind it. */
  scroll-margin-top: calc(var(--topbar-h, 53px) + .5rem);
}

/* Every heading is a jump target here, not only the ### symbols the API
   reference linked to. */
article h1, article h2 { scroll-margin-top: calc(var(--topbar-h, 53px) + .5rem); }

article hr { border: 0; border-top: 1px solid var(--line); margin: 2rem 0; }
article ul, article ol { padding-left: 1.4rem; }
article li { margin: .25rem 0; }

article code {
  background: var(--code-bg);
  padding: .12em .35em;
  border-radius: 3px;
  font: 13px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace;
}

article pre {
  background: var(--code-bg);
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: .8rem 1rem;
  overflow-x: auto;
}

article pre code { background: none; padding: 0; font-size: 12.5px; line-height: 1.55; }

article table {
  border-collapse: collapse;
  width: 100%;
  margin: 1rem 0;
  display: block;
  overflow-x: auto;
}

article th, article td {
  border: 1px solid var(--line);
  padding: .45rem .6rem;
  text-align: left;
  vertical-align: top;
  font-size: 13.5px;
}

article th { background: var(--code-bg); }

/* Zebra, kept deliberately faint: the overview table is 23 rows of three
   columns and the eye loses the row on the way across. Half the header tint
   is enough to track by and not enough to read as a highlight. */
article tbody tr:nth-child(even) { background: color-mix(in srgb, var(--code-bg) 55%, transparent); }

article blockquote {
  margin: 1rem 0;
  padding: .3rem 1rem;
  border-left: 3px solid var(--accent);
  color: var(--muted);
}

article .source {
  font-size: 12.5px;
  color: var(--muted);
}

/* Outbound marker. Sized in em so it tracks whatever text it trails, and
   nudged up to sit against the cap height rather than the baseline. */
.ext {
  width: .62em;
  height: .62em;
  margin-left: .22em;
  vertical-align: .04em;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: .7;
}

a.external:hover .ext { opacity: 1; }

/* Links that hold an inline code span keep the link colour on the code too,
   or a row of `--option` links reads as plain code. */
article a code { color: inherit; }

/* ---------- code tokens ----------
   vapor-chamber's values, unchanged: typedoc's own keyword blue and its
   kind hues. They are not palette tokens, and are kept rather than
   re-derived from ember and flame, which would be a new colour decision. */
.tok-comment { color: var(--muted); font-style: italic; }
.tok-keyword { color: #056bd6; }
.tok-string { color: #0f7a26; }
.tok-number { color: #7a6b16; }
.tok-type { color: #1f70c2; }
.tok-call { color: #5b31e0; }

@media (prefers-color-scheme: dark) {
  .tok-keyword { color: #3399ff; }
  .tok-string { color: #6ddc85; }
  .tok-number { color: #d8c452; }
  .tok-type { color: #8ac4ff; }
  .tok-call { color: #a280ff; }
}

/* ---------- search ---------- */

.search-modal {
  position: fixed;
  inset: 0;
  z-index: 40;
  background: rgba(10, 12, 15, .45);
  display: flex;
  justify-content: center;
  padding-top: 12vh;
}

.search-modal[hidden] { display: none; }

.search-panel {
  width: min(42rem, 92vw);
  height: fit-content;
  max-height: 70vh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 11px;
  box-shadow: var(--shadow);
  overflow: hidden;
}

#search-input {
  font: inherit;
  font-size: 15px;
  padding: .85rem 1rem;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: none;
  color: var(--fg);
  outline: none;
}

.search-results { overflow-y: auto; }

.search-results a {
  display: flex;
  align-items: baseline;
  gap: .6rem;
  padding: .45rem 1rem;
  color: var(--fg);
  text-decoration: none;
}

.search-results a:hover, .search-results a.active { background: var(--code-bg); }
.search-results .symbol { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; }
.search-results .where { margin-left: auto; color: var(--muted); font-size: 12px; }
.search-results .empty { padding: .9rem 1rem; color: var(--muted); font-size: 13.5px; }

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

@media (max-width: 1100px) {
  .shell { grid-template-columns: 230px minmax(0, 1fr); }
  .toc { display: none; }
}

@media (max-width: 760px) {
  .shell { grid-template-columns: minmax(0, 1fr); }
  .sidebar { position: static; height: auto; border-right: 0; border-bottom: 1px solid var(--line); }
  .topnav { display: none; }
  .search-trigger { min-width: 0; flex: 1; }
  main { padding: 1.2rem 1.1rem 4rem; }
}
