/* SPDX-License-Identifier: AGPL-3.0-only */
/* The structure every docs page shares (docs-build.ts `renderDoc`): the title and its one-line summary, the table of contents,
   the body and the footer. The standalone pages (docs.css) and the canvas reader (docs-reader.css) both load it, so it only
   uses the tokens both define (--fg, --fg-2, --text-secondary, --row, --fw-*, --ease-out) and no colour of its own.

   Measure: the text never runs wider than 70 characters of the page font, which is where a line of this monospace reads
   comfortably. Table of contents: where the page has room for it beside the text it is a sticky column on the right; where
   it does not (a phone, a window one column wide) it is one folded row under the summary. The page is the query container
   (`main` in docs.css, `.dr-scroll` in docs-reader.css). */
.doc { display: grid; grid-template-columns: minmax(0, 1fr); }
.doc-head, .doc-body { min-width: 0; max-width: 70ch; }
.doc .lede { margin: 0 0 1.5rem; color: var(--fg-2); font-size: 1.08em; font-weight: var(--fw-secondary); line-height: 1.6; }

/* Corner radii here are literal rem on purpose (ui-literal: #345): the standalone docs pages load only docs.css and this file, not the
   app's ui.css where --r-sm/--r-md/--r-lg live, so a token would resolve to nothing there. The values are the scale's steps
   (0.5rem, 0.75rem); change them together with packages/ui/styles.css. */
/* ---- Type for long reading ---------------------------------------------------------------------------------------------------
   One scale in `em` of the page's own body size (13 px, 16 px on touch), so the standalone page and the canvas window step
   the same way: title 1.7, section 1.3, sub-section 1.08, then the body. A section starts with a hairline and a generous gap, a
   sub-section with a gap only, so the eye finds the hierarchy before it reads a word. Spacing is on the 4 px grid (rem). */
.doc h1 { margin: 0 0 0.5rem; font-size: 1.7em; font-weight: var(--fw-label); line-height: 1.25; letter-spacing: -0.04em; }
.doc h2 { margin: 2.5rem 0 0.75rem; padding-top: 1.5rem; border-top: 1px solid rgb(from var(--fg) r g b / 0.1); font-size: 1.3em; font-weight: var(--fw-title); line-height: 1.3; letter-spacing: -0.02em; }
.doc h3 { margin: 1.75rem 0 0.5rem; font-size: 1.08em; font-weight: var(--fw-title); line-height: 1.35; }
.doc .doc-body > h2:first-child { padding-top: 0; border-top: 0; }
.doc :target { scroll-margin-top: 1rem; }

/* Inline code, and a fenced block. A block copies on a click (a double tap on a phone): the pointer says so, and the text gives way
   to the shared "Copied" confirmation (copy-feedback.ts `confirmInPlace`) in the same spot. Its rules are here because the
   standalone page does not load the app's stylesheet; in the app the same `.ui-copied` classes apply, scoped to `.doc-code`. */
.doc code { padding: 1px 0.25rem; border-radius: 0.375rem; background: rgb(from var(--fg) r g b / 0.05); font: inherit; font-size: 0.93em; overflow-wrap: anywhere; }
.doc .doc-code { position: relative; margin: 0 0 1rem; }
.doc pre { margin: 0; overflow-x: auto; padding: 0.75rem 1rem; border-radius: 0.75rem; background: rgb(from var(--fg) r g b / 0.05); line-height: 1.6; cursor: pointer; -webkit-overflow-scrolling: touch; transition: background-color var(--t-press) ease; outline: none; }
@media (hover: hover) { .doc pre:hover { background: rgb(from var(--fg) r g b / 0.08); } }
.doc pre code { padding: 0; background: none; overflow-wrap: normal; transition: opacity var(--t-press) ease-out; }
.doc .doc-code[data-copied] pre code { opacity: 0; }
.doc .doc-code > .ui-copied { position: absolute; top: 0.75rem; left: 1rem; display: inline-flex; align-items: center; gap: 0.375rem; padding: 0; line-height: 1.6; white-space: nowrap; pointer-events: none; color: var(--fg); opacity: 0; transition: opacity var(--t-press) ease-out; }
.doc .doc-code[data-copied] > .ui-copied { opacity: 1; transition: opacity var(--t-pop) ease-out 40ms; }
.doc .doc-code[data-instant] pre code, .doc .doc-code[data-instant] > .ui-copied { transition: none; }
.doc .doc-code .ui-copied-icon { display: inline-grid; place-items: center; width: 0.875rem; height: 0.875rem; }
.doc .doc-code .ui-copied-icon svg { width: 0.875rem; height: 0.875rem; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
[data-focus-ring="on"] .doc pre:focus-visible { outline: 2px solid var(--focus-ring, var(--accent)); outline-offset: 2px; }

/* ---- Callouts ----------------------------------------------------------------------------------------------------------------
   Five tones from the alert syntax, and the quick-facts panel. A callout is a panel: a faint fill of its tone, a hairline of the
   same, an icon and a title on one centre line, then the text. The fill and hairline are the tone at low strength, so they read on
   ink and on paper alike; the title and text stay in the page's own colours (contrast), and only the icon carries the tone.
   Tones: note is neutral, tip is the "ok" colour, important is the accent, warning is amber, caution is red. */
.doc .callout { --tone: var(--fg-2); margin: 0 0 1rem; padding: 0.75rem 1rem; border: 1px solid color-mix(in oklab, var(--tone) 30%, transparent); border-radius: 0.75rem; background: color-mix(in oklab, var(--tone) 9%, transparent); }
.doc .callout-tip { --tone: var(--ok); }
.doc .callout-important { --tone: var(--accent); }
.doc .callout-warning { --tone: var(--warn); }
.doc .callout-caution { --tone: var(--danger); }
.doc .callout-facts { border-color: transparent; background: rgb(from var(--fg) r g b / 0.06); }
.doc .callout-title { display: flex; align-items: center; gap: 0.5rem; margin: 0 0 0.25rem; font-weight: var(--fw-label); line-height: 1.5; }
.doc .callout-title svg { flex: none; width: 1.0625rem; height: 1.0625rem; fill: none; stroke: var(--tone); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.doc .callout-facts .callout-title svg { stroke: var(--fg-2); }
.doc .callout > :last-child { margin-bottom: 0; }
.doc .callout ul, .doc .callout ol { margin-bottom: 0.5rem; }
@media (pointer: coarse) { .doc .callout-title svg { width: 1.25rem; height: 1.25rem; } }

/* ---- Reasoning: "Why it works this way" ---------------------------------------------------------------------------------------
   A folded section. The page says what is true; the reasoning is one tap away. The row is a 44 px target on touch, its chevron is
   drawn like the contents' (a font glyph would not centre), and the body opens by growing in height where the browser can animate
   it (Chromium); elsewhere it opens at once. */
.doc .why { margin: 0 0 1rem; border: 1px solid rgb(from var(--fg) r g b / 0.1); border-radius: 0.75rem; interpolate-size: allow-keywords; }
.doc .why summary { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; min-height: var(--row); box-sizing: border-box; padding: 0.375rem 1rem; font-weight: var(--fw-label); cursor: pointer; list-style: none; -webkit-tap-highlight-color: transparent; }
.doc .why summary::-webkit-details-marker { display: none; }
.doc .why summary::after { content: ""; flex: none; width: 0.4em; height: 0.4em; margin-right: 0.2em; border: solid var(--fg-2); border-width: 0 1.5px 1.5px 0; transform: translateY(-0.12em) rotate(45deg); transition: transform var(--t-pop) var(--ease-out); }
.doc .why[open] summary::after { transform: translateY(0.1em) rotate(-135deg); }
.doc .why-body { padding: 0 1rem 0.5rem; color: var(--fg-2); font-weight: var(--fw-secondary); }
.doc .why-body > :last-child { margin-bottom: 0.25rem; }
.doc .why::details-content { block-size: 0; overflow: clip; transition: block-size var(--t-pop) var(--ease-out), content-visibility var(--t-pop) allow-discrete; }
.doc .why[open]::details-content { block-size: auto; }
@media (prefers-reduced-motion: reduce) { .doc .why summary::after, .doc .why::details-content { transition: none; } }

/* ---- Quotes ------------------------------------------------------------------------------------------------------------------
   A quote is set apart by a rule and softer colour; with a caption (`> — Name`) the name sits under it, outside the words. */
.doc blockquote { margin: 0 0 1rem; padding: 0 0 0 1rem; border-left: 2px solid rgb(from var(--fg) r g b / 0.18); color: var(--fg-2); font-weight: var(--fw-secondary); }
.doc blockquote > :last-child { margin-bottom: 0; }
.doc .quote { margin: 0 0 1rem; }
.doc .quote blockquote { margin: 0; }
.doc .quote figcaption { margin-top: 0.5rem; padding-left: 1rem; color: var(--fg-2); font-size: var(--text-secondary); font-weight: var(--fw-secondary); }

/* ---- Citations ---------------------------------------------------------------------------------------------------------------
   A number in the text links to its source; the sources are listed under "References" with a link back to every place they were
   cited. On touch the number's hit area grows beyond its glyph (a pseudo-element), so the small number is still easy to tap. */
.doc .cite { position: relative; top: -0.35em; margin-left: 1px; font-size: 0.78em; line-height: 0; }
.doc .cite a { position: relative; padding: 0 0.125rem; border-radius: 0.25rem; color: var(--accent); font-weight: var(--fw-label); text-decoration: none; }
.doc .cite a::after { content: ""; position: absolute; inset: -0.5rem -0.375rem; }
@media (pointer: coarse) { .doc .cite a::after { inset: -0.875rem -0.75rem; } }
.doc .references { margin: 0 0 1rem; padding-left: 1.6em; color: var(--fg-2); font-size: var(--text-secondary); font-weight: var(--fw-secondary); }
.doc .references li { margin: 0.5rem 0; padding: 0.125rem 0.5rem 0.125rem 0.25rem; border-radius: 0.5rem; }
.doc .references li:target, .doc .cite a:target { background: rgb(from var(--fg) r g b / 0.08); }
.doc .references .back { display: inline-grid; place-items: center; width: 1.5rem; height: 1.25rem; margin-left: 0.25rem; vertical-align: -0.25rem; color: var(--fg-2); }
.doc .references .back svg { width: 0.875rem; height: 0.875rem; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
@media (pointer: coarse) { .doc .references .back { width: 2.75rem; height: 2.75rem; margin: -0.75rem -0.5rem -0.75rem 0; vertical-align: middle; } }

/* ---- Figures -----------------------------------------------------------------------------------------------------------------
   A picture of the product with a caption under it, and sometimes a clip. The picture is as wide as it was captured (its width
   attribute, in CSS pixels, so it is as sharp as the capture's 2x or 3x allows) and never wider than the text; its box starts on the
   text's left edge. A clip is laid exactly over the still (same crop, same size) and fades in once it plays. */
.doc .figure { margin: 1.5rem 0; }
.doc .figure-media { position: relative; display: block; width: fit-content; max-width: 100%; overflow: hidden; border: 1px solid rgb(from var(--fg) r g b / 0.1); border-radius: 0.75rem; line-height: 0; }
.doc .figure img { display: block; max-width: 100%; height: auto; }
.doc .figure-clip { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity var(--t-pop) var(--ease-out); pointer-events: none; }
.doc .figure-clip[data-playing] { opacity: 1; }
.doc figcaption { margin-top: 0.5rem; color: var(--fg-2); font-size: var(--text-secondary); font-weight: var(--fw-secondary); line-height: 1.5; }
/* A figure that has not been captured where the docs are built: its place, with the caption under it. */
.doc .figure-placeholder { display: grid; place-items: center; width: 100%; aspect-ratio: 16 / 9; max-height: 14rem; box-sizing: border-box; background: rgb(from var(--fg) r g b / 0.03); color: var(--fg-2); font-size: var(--text-secondary); font-weight: var(--fw-secondary); line-height: 1.5; }
@media (prefers-reduced-motion: reduce) { .doc .figure-clip { transition: none; } }

/* ---- Tables ------------------------------------------------------------------------------------------------------------------
   A table is a box with a header band and hairlines between rows; its first column names the row. The box scrolls by itself when
   a table is wider than the text (cells wrap, so only a table with long unbreakable words does). In a narrow canvas window each row stacks into a card instead (docs-reader.css). */
.doc .table { overflow-x: auto; margin: 0 0 1rem; border: 1px solid rgb(from var(--fg) r g b / 0.1); border-radius: 0.75rem; }
.doc table { width: 100%; margin: 0; border-collapse: collapse; }
.doc th, .doc td { padding: 0.5rem 0.75rem; border-bottom: 1px solid rgb(from var(--fg) r g b / 0.1); text-align: left; vertical-align: top; }
.doc th { background: rgb(from var(--fg) r g b / 0.04); color: var(--fg-2); font-weight: var(--fw-label); white-space: nowrap; }
.doc tbody tr:last-child td { border-bottom: 0; }
.doc td:first-child { font-weight: var(--fw-label); }
@media (hover: hover) { .doc tbody tr:hover td { background: rgb(from var(--fg) r g b / 0.03); } }

/* The footer: where a page names the decisions behind it. Quiet, set apart by a hairline, and never part of the contents. */
.doc .notes { margin-top: 3rem; padding-top: 1rem; border-top: 1px solid rgb(from var(--fg) r g b / 0.1); color: var(--fg-2); font-size: var(--text-secondary); font-weight: var(--fw-secondary); line-height: 1.6; }
.doc .notes > :last-child { margin-bottom: 0; }

/* Narrow: one folded row. Its text starts at the page's left edge, like the title above it. */
.doc .toc { margin: 0 0 1.5rem; }
.doc .toc-side { display: none; }
.doc .toc ol { margin: 0; padding: 0; list-style: none; }
.doc .toc li { margin: 0; }
.doc .toc ol ol { padding-left: 1rem; }
.doc .toc a { display: block; box-sizing: border-box; min-height: var(--row); padding: 0.25rem 0; color: var(--fg-2); font-weight: var(--fw-body); text-decoration: none; overflow-wrap: anywhere; }
.doc .toc a:hover { color: var(--fg); }
.doc .toc a:active { color: var(--fg); }
/* The section being read (doc-enhance.ts marks it `aria-current="location"` while the page scrolls). */
.doc .toc a[aria-current="location"] { color: var(--fg); font-weight: var(--fw-label); }
.doc .toc-fold { border-block: 1px solid rgb(from var(--fg) r g b / 0.1); }
.doc .toc-fold summary { display: flex; align-items: center; justify-content: space-between; min-height: var(--row); box-sizing: border-box; padding: 0.25rem 0; color: var(--fg); font-weight: var(--fw-label); cursor: pointer; list-style: none; -webkit-tap-highlight-color: transparent; }
.doc .toc-fold summary::-webkit-details-marker { display: none; }
/* The chevron is drawn, not typed: a font glyph would not centre on the text's line. */
.doc .toc-fold summary::after { content: ""; width: 0.4em; height: 0.4em; margin-right: 0.2em; border: solid currentColor; border-width: 0 1.5px 1.5px 0; transform: translateY(-0.12em) rotate(45deg); transition: transform var(--t-pop) var(--ease-out); }
.doc .toc-fold[open] summary::after { transform: translateY(0.1em) rotate(-135deg); }
.doc .toc-fold > ol { padding-bottom: 0.5rem; }
@media (prefers-reduced-motion: reduce) { .doc .toc-fold summary::after { transition: none; } }

/* Wide: the text and, to its right, the contents that stay in view while the page scrolls. */
@container (min-width: 52rem) {
  .doc { grid-template-columns: minmax(0, 70ch) 14rem; grid-template-rows: auto 1fr; grid-template-areas: "head toc" "body toc"; column-gap: 3rem; }
  .doc-head { grid-area: head; }
  .doc-body { grid-area: body; }
  .doc .toc { grid-area: toc; position: sticky; top: 1.5rem; align-self: start; max-height: calc(100dvh - 3rem); margin: 0; overflow-y: auto; overscroll-behavior: contain; }
  .doc .toc-fold { display: none; }
  .doc .toc-side { display: block; }
  .doc .toc-title { margin: 0 0 0.5rem; color: var(--fg); font-weight: var(--fw-label); }
  .doc .toc a { min-height: 0; padding: 0.25rem 0; }
  /* A track down the left of the rail, and a short bar on it at the section being read. Every entry has the same padding
     whether current or not, so nothing shifts when the highlight moves. */
  .doc .toc-side > ol { box-shadow: inset 1px 0 0 rgb(from var(--fg) r g b / 0.12); }
  .doc .toc-side ol ol { padding-left: 0; }
  .doc .toc-side a { padding-left: 0.75rem; transition: color var(--t-press) ease, box-shadow var(--t-press) ease; }
  .doc .toc-side ol ol a { padding-left: 1.5rem; }
  .doc .toc-side a[aria-current="location"] { box-shadow: inset 2px 0 0 var(--fg); }
}
@media (prefers-reduced-motion: reduce) { .doc .toc-side a { transition: none; } }

/* The list of pages under the front page: one row per page, the title over its one-line summary. */
.doc .pages { margin: 0 0 1rem; padding: 0; list-style: none; }
.doc .pages li { margin: 0; border-bottom: 1px solid rgb(from var(--fg) r g b / 0.1); }
.doc .pages a { display: flex; flex-direction: column; gap: 0.125rem; min-height: var(--row); box-sizing: border-box; padding: 0.625rem 0; text-decoration: none; transition: transform var(--t-press) var(--ease-out); }
.doc .pages a:active { transform: scale(0.98); }
.doc .pages strong { font-weight: var(--fw-label); }
.doc .pages span { color: var(--fg-2); font-size: var(--text-secondary); font-weight: var(--fw-secondary); }

/* The first heading of the body sits one summary-gap under the title block, not a section gap. */
.doc .doc-body > :first-child { margin-top: 0; }
