h2.page-title { margin: 0 0 1.5rem; font-size: 1.6rem; letter-spacing: -0.01em; }
h2.section-title { margin: 1.5rem 0 0.5rem; font-size: 0.8rem; font-weight: 600;
                   text-transform: uppercase; letter-spacing: 0.08em;
                   color: var(--muted); }
table.kv, table.cost { border-collapse: collapse; width: 100%; margin: 0 0 1rem; }
table.kv th, table.kv td, table.cost th, table.cost td {
  padding: 0.4rem 0.6rem; border-bottom: 1px solid var(--border);
  text-align: left; vertical-align: top;
}
table.kv th { font-weight: 500; color: var(--muted); width: 40%; }
table.cost thead th { font-weight: 600; font-size: 0.85rem; color: var(--muted);
                      text-transform: uppercase; letter-spacing: 0.06em; }
table.cost tfoot td, table.cost tfoot th { font-weight: 600; border-top: 2px solid var(--border); border-bottom: none; }
table.kv .num, table.cost .num, td.num, th.num { text-align: right;
  font-variant-numeric: tabular-nums;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.9em; }
table.cost td .meta { color: var(--muted); font-size: 0.85em; }
.badge { display: inline-block; padding: 0.05em 0.4em; margin-left: 0.4em;
         border: 1px solid var(--border); border-radius: 0.6em;
         font-size: 0.75em; color: var(--muted);
         font-family: ui-sans-serif, system-ui, sans-serif; vertical-align: baseline; }
/* In tables a badge usually fills its cell alone, so the trailing-text
   left margin from the inline-with-meta case becomes a visible offset. */
table.cost .badge { margin-left: 0; }
.warn { border: 1px solid var(--border); background: var(--surface);
        padding: 0.6rem 0.8rem; border-radius: 0.4rem; margin: 0 0 1rem; }
.warn ul { margin: 0.4rem 0 0; padding-left: 1.2rem; }
.warn strong { font-weight: 600; }
/* Inline notice for one-shot positive feedback (e.g. "installed Slack").
   Same shape as .warn so they nest comfortably in the same column;
   the `ok` modifier tints the left border so the message reads as
   confirmation rather than caution at a glance. */
.notice { border: 1px solid var(--border); background: var(--surface);
          padding: 0.6rem 0.8rem; border-radius: 0.4rem; margin: 0 0 1rem;
          border-left: 3px solid var(--accent); }
.notice.ok { border-left-color: var(--ok); }
.badge.ok { color: var(--ok); border-color: rgba(46, 160, 67, 0.4); }
/* actions-row sits a primary button next to a short caption so the
   page header gives the user one clear next step plus the context
   to know what it does. Wraps on narrow viewports. */
.actions-row { display: flex; gap: 0.75rem; align-items: center;
               flex-wrap: wrap; margin: 0 0 1.5rem; }
.actions-row .muted { font-size: 0.9rem; }
/* admin-index is the /admin landing layout: a small list of links to
   subpages, each with a one-line description in .meta. */
ul.admin-index { list-style: none; padding: 0; margin: 0; }
ul.admin-index li { padding: 0.6rem 0; border-bottom: 1px solid var(--border); }
ul.admin-index li:last-child { border-bottom: none; }
ul.admin-index a strong { display: block; font-size: 1rem; }
ul.admin-index .meta { display: block; }
/* Same top-margin as a bare h2.section-title so section-rows
   (heading + action link) don't visually crowd the section above
   them. Without the top margin, "Workspaces" sat flush against the
   bottom of the Recent list. */
.section-row { display: flex; align-items: baseline;
               justify-content: space-between; gap: 1rem;
               margin: 1.5rem 0 0.5rem; }
.section-row > h2.section-title,
.section-row > h3.subsection-title { margin: 0; }
/* Pagination block at the foot of a listing (currently the /recent
   pages). One link, "Older ->", with breathing room above. */
.pagination { margin-top: 1.5rem; }
.section-action { font-size: 0.85rem; color: var(--muted);
                  text-decoration: none; }
.section-action:hover { color: var(--accent); }
h3.subsection-title { margin: 1.25rem 0 0.25rem; font-size: 0.95rem;
                      font-weight: 600; letter-spacing: -0.005em; }
h3.subsection-title a { color: inherit; text-decoration: none; }
h3.subsection-title a:hover { color: var(--accent); }
/* form-row lays out a short input form (e.g. Slack add-route) as a
   wrapping flex row so label-inputs stack with the submit button.
   Each label puts its caption above its control so the form reads
   top-to-bottom on narrow viewports without extra markup. */
form.form-row { display: flex; flex-wrap: wrap; gap: 0.75rem;
                align-items: flex-end; margin: 0.5rem 0 1.5rem; }
form.form-row label { display: flex; flex-direction: column; gap: 0.25rem;
                      font-size: 0.85rem; color: var(--muted); }
form.form-row input, form.form-row select {
  font: inherit; padding: 0.4rem 0.55rem;
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--bg); color: inherit; min-width: 12rem;
}
form.form-row [data-slack-form-error] { color: var(--danger); }
ul.docs { list-style: none; padding: 0; margin: 0; }
ul.docs li { padding: 0.75rem 0; border-bottom: 1px solid var(--border);
             display: flex; align-items: flex-start; justify-content: space-between; gap: 0.5rem; }
ul.docs li:last-child { border-bottom: none; }
ul.docs li > div:first-child { min-width: 0; flex: 1; }
ul.docs a { text-decoration: none; color: inherit; font-weight: 500; }
ul.docs a:hover { color: var(--accent); }
.meta { display: block; font-size: 0.85rem; color: var(--muted); margin-top: 0.15rem; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
details.doc-menu { position: relative; flex-shrink: 0; }
details.doc-menu > summary { list-style: none; cursor: pointer;
                             padding: 0.1rem 0.5rem; font-size: 1.25rem;
                             color: var(--muted); border-radius: 4px;
                             line-height: 1; user-select: none; }
details.doc-menu > summary::-webkit-details-marker { display: none; }
details.doc-menu > summary::marker { content: ""; }
details.doc-menu > summary:hover { background: var(--surface); color: inherit; }
.doc-menu-items { position: absolute; right: 0; top: calc(100% + 4px);
                  background: var(--bg-raised); border: 1px solid var(--border);
                  border-radius: 8px; padding: 0.25rem; z-index: 10;
                  min-width: 160px;
                  box-shadow: 0 4px 16px rgba(0,0,0,0.18); }
.doc-menu-items a,
.doc-menu-items button { display: block; width: 100%; text-align: left;
                         background: none; border: none; padding: 0.5rem 0.75rem;
                         font: inherit; color: inherit; cursor: pointer;
                         border-radius: 4px; text-decoration: none; }
.doc-menu-items a:hover,
.doc-menu-items button:hover { background: var(--surface); }
.doc-menu-items form { margin: 0; }
.doc-menu-items .danger { color: var(--danger); }
.doc-menu-items .danger:hover { background: rgba(204,51,51,0.12); }
/* Share menu trigger: icon in the nav, no details-marker. The
   popover panel reuses .popover-menu above. */
details.share-menu { position: relative; flex-shrink: 0;
                     display: inline-flex; align-items: center; }
details.share-menu > summary { list-style: none; cursor: pointer;
                               user-select: none; padding: 4px;
                               color: inherit; }
details.share-menu > summary::-webkit-details-marker { display: none; }
details.share-menu > summary::marker { content: ""; }
details.share-menu > summary:hover { color: var(--accent); }
/* Edit nav link is an SVG-only anchor; give it the same padded
   click target so it lines up with the share + gear summaries. */
header nav a[aria-label="Edit"] { display: inline-flex; align-items: center;
                                   padding: 4px; }
/* Listen button matches the other SVG-only nav affordances: same
   padding so it lines up, transparent background that picks up
   the surface tint on hover (same accent treatment as gear/share
   summaries), and an "active" state during playback. */
header nav button.nav-button {
  display: inline-flex; align-items: center; padding: 4px;
  background: transparent; border: 0; cursor: pointer; color: inherit;
  border-radius: 4px; line-height: 0;
}
header nav button.nav-button:hover { background: var(--surface); color: var(--accent); }
header nav button.nav-button.nav-button-active { color: var(--accent); }
/* Loading state: spin the SVG while the upstream TTS round-trip is
   in flight. tts.js swaps the play glyph for a partial-arc spinner
   glyph before the request goes out, and back to the play / stop
   glyph once the audio element starts playing. The animation lives
   on the SVG (not the button) so the hover background stays static. */
header nav button.nav-button.nav-button-loading { color: var(--accent); cursor: progress; }
header nav button.nav-button.nav-button-loading svg {
  animation: mds-tts-spin 0.9s linear infinite;
  transform-origin: center;
}
@keyframes mds-tts-spin { to { transform: rotate(360deg); } }
form.search-form { margin: 0 0 1.5rem; }
form.search-form input[type="search"] {
  width: 100%; font: inherit; padding: 0.55rem 0.85rem;
  background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
  color: inherit; box-sizing: border-box; outline: none;
  transition: border-color 0.15s, box-shadow 0.15s;
}
form.search-form input[type="search"]:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(17, 102, 238, 0.18);
}
.snippet { font-size: 0.9rem; color: var(--muted); margin-top: 0.25rem; line-height: 1.45; }
.snippet mark { background: rgba(255,220,0,0.35); color: inherit; padding: 0 0.1em; border-radius: 2px; }
.muted { color: var(--muted); }
.link { background: none; border: none; color: inherit; text-decoration: underline;
        cursor: pointer; padding: 0; font: inherit; }
form.editor { display: flex; flex-direction: column; gap: 1.25rem; }
form.editor label { display: flex; flex-direction: column; gap: 0.4rem; }
form.editor label > span { font-size: 0.8rem; text-transform: uppercase;
                           letter-spacing: 0.06em; color: var(--muted); font-weight: 600; }
form.editor input, form.editor textarea {
  width: 100%; font: inherit;
  padding: 0.65rem 0.85rem; color: inherit;
  background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
  outline: none; transition: border-color 0.15s, box-shadow 0.15s;
}
form.editor input:focus, form.editor textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(17, 102, 238, 0.18);
}
form.editor textarea {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 14px; line-height: 1.55;
  min-height: 60vh; resize: vertical; tab-size: 2;
}
form.editor .row { display: flex; gap: 0.6rem; align-items: center; justify-content: flex-end;
                   padding-top: 0.25rem; }
.error { color: var(--danger); padding: 0.6rem 0.85rem; border: 1px solid var(--danger);
         border-radius: var(--radius); background: rgba(204,51,51,0.08); margin-bottom: 1rem; }
.similar-docs { margin: 3rem 0 0; padding-top: 1.5rem;
  border-top: 1px solid var(--border); }
.similar-docs h2.section-title { margin-top: 0; }
.similar-docs ul { list-style: none; padding: 0; margin: 0; }
.similar-docs li { padding: 0.15rem 0; font-size: 0.95rem; }
.similar-docs a { color: inherit; text-decoration: none;
  display: block; padding: 0.2rem 0.35rem; border-radius: 4px; }
.similar-docs a:hover { background: var(--surface); color: var(--accent); }
/* Loading state: shimmer-skeleton lines fill the space the real
   list will occupy. similar.js swaps the LI children when the
   /similar fetch lands and drops the .is-loading class. */
.similar-docs.is-loading li.skeleton-line {
  height: 0.95rem; margin: 0.25rem 0.35rem; border-radius: 4px;
  background: linear-gradient(90deg,
    var(--surface) 0%, var(--border) 50%, var(--surface) 100%);
  background-size: 200% 100%;
  animation: mds-skeleton-pulse 1.5s linear infinite;
}
@keyframes mds-skeleton-pulse {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}
/* Honor reduced-motion: a static muted bar still communicates
   "something's loading" without the moving gradient. */
@media (prefers-reduced-motion: reduce) {
  .similar-docs.is-loading li.skeleton-line {
    background: var(--surface); animation: none;
  }
}
/* Docs site chrome. The breadcrumb sits above the article and
   the prev/next footer below; both stretch to the article's
   content width. */
nav.docs-breadcrumb {
  color: var(--muted); font-size: 0.9em; margin: 0 0 0.5rem;
}
nav.docs-breadcrumb a { color: var(--muted); text-decoration: none; }
nav.docs-breadcrumb a:hover { color: var(--accent); }
nav.docs-footer {
  display: flex; justify-content: space-between; gap: 1rem;
  margin: 2rem 0 0; padding: 1rem 0 0; border-top: 1px solid var(--border);
  font-size: 0.95em;
}
nav.docs-footer span:empty { visibility: hidden; }
nav.docs-footer a { color: var(--accent); text-decoration: none; }
nav.docs-footer a:hover { text-decoration: underline; }
button.copy-chip {
  position: absolute; top: 0.4rem; right: 0.4rem;
  font: inherit; font-size: 0.72rem; line-height: 1.4;
  color: var(--muted); background: var(--bg-raised);
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 0.1rem 0.5rem; cursor: pointer;
  opacity: 0; transition: opacity 0.1s, color 0.1s;
}
article pre:hover button.copy-chip,
button.copy-chip:focus { opacity: 1; }
button.copy-chip:hover { color: var(--accent); }
/* Syntax highlighting (rehype-highlight / highlight.js classes). The
   palette below tracks GitHub's light theme; the dark block swaps
   it for GitHub's dark theme. The dark block applies for an
   explicit theme-dark selection AND for theme-auto when the OS
   prefers dark. */
.hljs-comment, .hljs-quote { color: #6a737d; font-style: italic; }
.hljs-keyword, .hljs-selector-tag, .hljs-literal, .hljs-section,
.hljs-doctag, .hljs-type, .hljs-name, .hljs-strong { color: #d73a49; }
.hljs-string, .hljs-attr, .hljs-template-tag, .hljs-template-variable,
.hljs-addition, .hljs-meta-string { color: #032f62; }
.hljs-number, .hljs-symbol, .hljs-bullet, .hljs-link, .hljs-deletion,
.hljs-variable { color: #005cc5; }
.hljs-built_in, .hljs-builtin-name, .hljs-class .hljs-title,
.hljs-title.class_, .hljs-title.function_, .hljs-function .hljs-title { color: #6f42c1; }
.hljs-attribute, .hljs-subst, .hljs-formula, .hljs-regexp { color: #e36209; }
.hljs-tag { color: #22863a; }
.hljs-meta, .hljs-meta .hljs-keyword { color: #735c0f; }
.hljs-emphasis { font-style: italic; }
html.theme-dark .hljs-comment, html.theme-dark .hljs-quote { color: #8b949e; }
html.theme-dark .hljs-keyword, html.theme-dark .hljs-selector-tag,
html.theme-dark .hljs-literal, html.theme-dark .hljs-section,
html.theme-dark .hljs-doctag, html.theme-dark .hljs-type,
html.theme-dark .hljs-name, html.theme-dark .hljs-strong { color: #ff7b72; }
html.theme-dark .hljs-string, html.theme-dark .hljs-attr,
html.theme-dark .hljs-template-tag, html.theme-dark .hljs-template-variable,
html.theme-dark .hljs-addition, html.theme-dark .hljs-meta-string { color: #a5d6ff; }
html.theme-dark .hljs-number, html.theme-dark .hljs-symbol,
html.theme-dark .hljs-bullet, html.theme-dark .hljs-link,
html.theme-dark .hljs-deletion, html.theme-dark .hljs-variable { color: #79c0ff; }
html.theme-dark .hljs-built_in, html.theme-dark .hljs-builtin-name,
html.theme-dark .hljs-class .hljs-title, html.theme-dark .hljs-title.class_,
html.theme-dark .hljs-title.function_,
html.theme-dark .hljs-function .hljs-title { color: #d2a8ff; }
html.theme-dark .hljs-attribute, html.theme-dark .hljs-subst,
html.theme-dark .hljs-formula, html.theme-dark .hljs-regexp { color: #ffa657; }
html.theme-dark .hljs-tag { color: #7ee787; }
html.theme-dark .hljs-meta, html.theme-dark .hljs-meta .hljs-keyword { color: var(--warn); }
@media (prefers-color-scheme: dark) {
  html.theme-auto .hljs-comment, html.theme-auto .hljs-quote { color: #8b949e; }
  html.theme-auto .hljs-keyword, html.theme-auto .hljs-selector-tag,
  html.theme-auto .hljs-literal, html.theme-auto .hljs-section,
  html.theme-auto .hljs-doctag, html.theme-auto .hljs-type,
  html.theme-auto .hljs-name, html.theme-auto .hljs-strong { color: #ff7b72; }
  html.theme-auto .hljs-string, html.theme-auto .hljs-attr,
  html.theme-auto .hljs-template-tag, html.theme-auto .hljs-template-variable,
  html.theme-auto .hljs-addition, html.theme-auto .hljs-meta-string { color: #a5d6ff; }
  html.theme-auto .hljs-number, html.theme-auto .hljs-symbol,
  html.theme-auto .hljs-bullet, html.theme-auto .hljs-link,
  html.theme-auto .hljs-deletion, html.theme-auto .hljs-variable { color: #79c0ff; }
  html.theme-auto .hljs-built_in, html.theme-auto .hljs-builtin-name,
  html.theme-auto .hljs-class .hljs-title, html.theme-auto .hljs-title.class_,
  html.theme-auto .hljs-title.function_,
  html.theme-auto .hljs-function .hljs-title { color: #d2a8ff; }
  html.theme-auto .hljs-attribute, html.theme-auto .hljs-subst,
  html.theme-auto .hljs-formula, html.theme-auto .hljs-regexp { color: #ffa657; }
  html.theme-auto .hljs-tag { color: #7ee787; }
  html.theme-auto .hljs-meta, html.theme-auto .hljs-meta .hljs-keyword { color: var(--warn); }
}
/* Server-rendered wrapper that turns wide tables into a horizontally-
   scrollable region instead of letting them push the whole page
   sideways. `overflow-y: visible` keeps the `.table-live` sticky
   thead bound to the page scroll context rather than this wrapper
   (modern browsers honor the explicit visible-on-the-other-axis form
   per CSS Overflow Level 3). */
.table-scroll { overflow-x: auto; overflow-y: visible; max-width: 100%; }

/* Live-table wrapper / sticky header. Cells get extra left padding
   so column body content lines up with the label in the header,
   leaving the ⋮ glyph in a gutter to the label's left. */
.table-live { margin: 1.5rem 0; }
.table-live table thead {
  position: sticky; top: 0; background: var(--bg); z-index: 5;
}
.table-live table thead th { background: var(--bg); padding: 0; }
.table-live table td { padding-left: 1.3rem; }
/* Toolbar (hidden until something is active). */
.table-live .table-toolbar {
  display: none; align-items: center; gap: 0.5rem;
  margin-bottom: 0.5rem; flex-wrap: wrap;
  font-size: 0.85rem; color: var(--muted);
}
.table-live.has-controls .table-toolbar { display: flex; }
.toolbar-chips { display: flex; gap: 0.4rem; flex-wrap: wrap; flex: 1; }
.toolbar-actions { display: flex; gap: 0.4rem; }
.chip {
  display: inline-flex; align-items: center; gap: 0.3rem;
  padding: 0.1rem 0.4rem 0.1rem 0.6rem;
  font-size: 0.78rem; color: inherit; line-height: 1.5;
  background: var(--surface);
  border: 1px solid var(--border); border-radius: 999px;
}
.chip-x {
  font: inherit; font-size: 0.85rem;
  background: none; border: none; color: var(--muted);
  cursor: pointer; padding: 0 0.15rem;
  line-height: 1; border-radius: 50%;
}
.chip-x:hover { color: var(--accent); }
.toolbar-btn {
  font: inherit; font-size: 0.78rem;
  background: transparent; color: inherit;
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 0.15rem 0.5rem; cursor: pointer;
}
.toolbar-btn:hover { background: var(--surface); }
.toolbar-btn.reset { color: var(--muted); }
/* Column-header popover. */
.table-live details.col-menu { position: relative; }
.table-live details.col-menu > summary {
  list-style: none; cursor: pointer; user-select: none;
  padding: 0.4rem 0.6rem 0.4rem 1.3rem;
  display: flex; align-items: center; gap: 0.3rem;
}
.table-live details.col-menu > summary::-webkit-details-marker { display: none; }
.table-live details.col-menu > summary::marker { content: ""; }
.table-live details.col-menu > summary:hover { background: var(--surface); }
.table-live details.col-menu[open] > summary { background: var(--surface); }
.table-live .th-label { font-weight: 600; }
.table-live .sort-indicator { color: var(--accent); font-size: 0.85em; }
.table-live .col-menu-glyph {
  position: absolute; left: 0.4rem; top: 50%;
  transform: translateY(-50%);
  color: inherit; font-size: 1.1em; line-height: 1;
  opacity: 0.7; transition: color 0.1s, opacity 0.1s;
}
.table-live details.col-menu > summary:hover .col-menu-glyph,
.table-live details.col-menu[open] > summary .col-menu-glyph {
  color: var(--accent); opacity: 1;
}
.table-live .col-menu-panel {
  position: absolute; left: 0; top: calc(100% + 2px);
  background: var(--bg-raised); border: 1px solid var(--border);
  border-radius: 8px; padding: 0.25rem; z-index: 20;
  min-width: 200px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.18);
  display: flex; flex-direction: column;
}
.table-live .col-menu-panel button.menu-item {
  display: flex; align-items: center; gap: 0.4rem;
  font: inherit; font-size: 0.85rem;
  background: none; border: none; color: inherit;
  padding: 0.4rem 0.6rem; cursor: pointer; border-radius: 4px;
  text-align: left; width: 100%;
}
.table-live .col-menu-panel button.menu-item:hover { background: var(--surface); }
.table-live .col-menu-panel button.menu-item.active { color: var(--accent); }
.table-live .col-menu-panel button.menu-item > span:first-child {
  width: 1em; color: var(--muted); font-size: 0.9em; text-align: center;
}
.table-live .col-menu-panel button.menu-item.active > span:first-child { color: var(--accent); }
.table-live .col-menu-panel hr {
  border: none; border-top: 1px solid var(--border);
  margin: 0.25rem 0;
}
.table-live .col-menu-panel input.col-filter {
  font: inherit; font-size: 0.85rem;
  margin: 0.25rem; padding: 0.3rem 0.5rem;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); color: inherit;
}
/* Group header redesign: chevron + label + value + count badge. */
.table-live tr.group-header td {
  background: var(--surface);
  cursor: pointer; user-select: none;
  padding: 0.5rem 0.6rem;
}
.table-live tr.group-header td > .group-row {
  display: flex; align-items: center; gap: 0.5rem;
}
.table-live .group-chevron { color: var(--muted); font-size: 0.75em; width: 1em; flex-shrink: 0; }
.table-live .group-label { color: var(--muted); font-size: 0.85em; }
.table-live .group-value { font-weight: 500; }
.table-live .group-count {
  margin-left: auto; flex-shrink: 0;
  font-size: 0.75em; color: var(--muted);
  background: var(--bg); padding: 0.05rem 0.5rem;
  border-radius: 999px; border: 1px solid var(--border);
}
nav.toc { font-size: 0.85rem; line-height: 1.5; }
nav.toc ul { list-style: none; padding: 0; margin: 0; }
nav.toc li { padding: 0.15rem 0; }
nav.toc a { color: inherit; text-decoration: none; display: block; padding: 0.05rem 0.25rem;
            border-radius: 4px; }
nav.toc a:hover { background: var(--surface); color: var(--accent); }
nav.toc a.toc-active { color: var(--accent); background: var(--surface); font-weight: 500; }
nav.toc li[data-depth="2"] { padding-left: 0.85rem; }
nav.toc li[data-depth="3"] { padding-left: 1.7rem; }
nav.toc li[data-depth="4"] { padding-left: 2.55rem; }
nav.toc li[data-depth="5"], nav.toc li[data-depth="6"] { padding-left: 3.4rem; }
/* Popover variant lives inside the header's <details>. */
details.toc-toggle { position: relative; flex-shrink: 0;
                     display: inline-flex; align-items: center; }
details.toc-toggle > summary { list-style: none; cursor: pointer;
                               padding: 4px; color: var(--muted);
                               border-radius: 4px; user-select: none; }
details.toc-toggle > summary::-webkit-details-marker { display: none; }
details.toc-toggle > summary::marker { content: ""; }
details.toc-toggle > summary:hover { background: var(--surface); color: inherit; }
.toc-popover { position: absolute; right: 0; top: calc(100% + 4px);
               background: var(--bg-raised); border: 1px solid var(--border);
               border-radius: 8px; padding: 0.5rem 0.75rem; z-index: 10;
               min-width: 220px; max-width: 320px;
               box-shadow: 0 4px 16px rgba(0,0,0,0.18); }
/* Scroll the UL, not the popover. With `position: absolute` on the
   popover, applying `max-height` + `overflow-y: auto` directly on
   it parks the scroll origin in the middle of a tall child, so the
   first ~half of the TOC is unreachable from scrollTop=0. The
   sidebar variant doesn't see this because it's `position: fixed`.
   Moving the scroll container down one level avoids the interaction. */
.toc-popover > ul { max-height: 70vh; overflow-y: auto; }
/* Sidebar variant: floats in the left margin in sidebar mode.
   Visibility is gated on .toc-sidebar-fits, which a small JS helper
   toggles based on viewport width and the current content-width
   preset. "Full" width never fits (no max-width, no left gutter). */
aside.toc-sidebar { position: fixed; top: 4.5rem; left: 1rem;
                    max-width: 240px; max-height: calc(100vh - 6rem);
                    overflow-y: auto; padding: 0.5rem 0.75rem;
                    border-right: 1px solid var(--border);
                    display: none; }
html.toc-mode-sidebar.toc-sidebar-fits aside.toc-sidebar { display: block; }
html.toc-mode-sidebar.toc-sidebar-fits details.toc-toggle { display: none; }
@media (max-width: 600px) {
  body { margin: 1rem auto; }
  header { margin-bottom: 1.5rem; }
  h2.page-title { font-size: 1.35rem; }
}

/* Slides mode. The body becomes a stack of viewport-sized panels;
   slides.js toggles a `.active` class on the visible one and uses
   `aria-hidden` for the rest. Only the active panel is in the flow,
   so wide slide content can scroll inside without nudging the
   header or footer. */
body.slides-mode { max-width: none; margin: 0; padding: 0; }
body.slides-mode header { padding: 0.5rem 1rem; margin: 0;
                          border-bottom: 1px solid var(--border); }
body.slides-mode article { max-width: none; margin: 0; padding: 0; line-height: 1.5; }
body.slides-mode section.slide {
  display: none;
  box-sizing: border-box;
  min-height: calc(100vh - 3.25rem);
  padding: 3rem clamp(1rem, 8vw, 6rem);
  font-size: clamp(1rem, 1.6vw, 1.4rem);
  overflow: auto;
}
body.slides-mode section.slide.active { display: block; }
body.slides-mode section.slide h1 { font-size: 2.4em; margin-top: 0; }
body.slides-mode section.slide h2 { font-size: 1.8em; margin-top: 0; }
body.slides-mode section.slide h3 { font-size: 1.4em; }
body.slides-mode section.slide pre {
  font-size: 0.85em;
  max-height: 70vh;
}
body.slides-mode .slide-progress {
  position: fixed; bottom: 0.5rem; right: 0.75rem;
  font-size: 0.8rem; color: var(--muted);
  font-variant-numeric: tabular-nums;
  background: var(--bg); padding: 0.15rem 0.5rem;
  border: 1px solid var(--border); border-radius: 999px;
  user-select: none;
}
/* The sidebar TOC has nowhere to live next to a full-viewport slide
   panel; the popover form (header icon) still works for jump-to-slide
   navigation. In sidebar-preference mode, the default rule hides the
   popover icon -- override it so slides always get the header
   affordance regardless of the user's TOC setting. */
body.slides-mode aside.toc-sidebar { display: none; }
html.toc-mode-sidebar.toc-sidebar-fits body.slides-mode details.toc-toggle {
  display: inline-flex;
}
/* Fullscreen hides the page chrome so the slide owns the whole
   screen. requestFullscreen runs on documentElement, so :fullscreen
   matches <html>. */
html:fullscreen body.slides-mode header { display: none; }
html:fullscreen body.slides-mode section.slide { min-height: 100vh; }

/* Inline doc-edit mode. The editor-client script swaps the article
   for a CodeMirror host + a small toolbar + an optional warn-style
   banner for conflicts; layout-wise it sits inside the article's
   parent so the surrounding chrome (TOC, similar docs) stays put. */
.inline-edit-wrapper { display: flex; flex-direction: column; gap: 1.25rem; margin: 0 0 1rem; }
.inline-edit-wrapper .cm-host-inline { width: 100%; }
.inline-edit-toolbar { display: flex; gap: 0.5rem; justify-content: flex-end; }
.inline-edit-banner:empty { display: none; }
.inline-edit-banner {
  border: 1px solid var(--border); background: var(--surface);
  padding: 0.5rem 0.7rem; border-radius: 0.4rem; font-size: 0.9rem;
}
.inline-edit-banner.warn { border-left: 3px solid var(--warn); }
.inline-edit-banner .link {
  background: none; border: none; color: var(--accent);
  cursor: pointer; padding: 0; font: inherit; text-decoration: underline;
}


/* Print stylesheet. Reduce the page to just the doc body: no
   header chrome, no popovers, no TOC sidebar, no similar-docs
   footer, no per-block copy chips. The browser's print preview
   inherits the screen palette by default; we force black text on
   white so dark-mode and high-contrast themes don't ghost out on
   paper. */
@media print {
  html, body {
    background: #fff !important;
    color: #000 !important;
    font-size: 11pt;
  }
  header,
  aside.toc-sidebar,
  .similar-docs,
  details.share-menu,
  details.toc-toggle,
  details.settings,
  details.user-menu,
  nav.docs-breadcrumb,
  nav.docs-footer,
  button.copy-chip,
  a.heading-anchor,
  a.section-copy,
  .inline-edit-banner,
  .inline-edit-toolbar,
  [data-mds-edit],
  [data-tts-url] {
    display: none !important;
  }
  main, body > article {
    margin: 0;
    padding: 0;
    max-width: none;
  }
  article a {
    color: #000;
    text-decoration: underline;
  }
  article pre, article code {
    background: #f4f4f4 !important;
    color: #000 !important;
    border: 1px solid #ddd;
  }
  /* Keep a heading attached to the paragraph(s) that follow it
     rather than dangling alone at the bottom of a printed page. */
  article h1, article h2, article h3, article h4, article h5, article h6 {
    page-break-after: avoid;
    break-after: avoid;
  }
  article pre, article table, article img, article figure {
    page-break-inside: avoid;
    break-inside: avoid;
  }
}


/* Debug panel in the settings popover (rendered only on doc pages,
   where paginated.js wires its controls). The textarea max-height
   keeps the dump from blowing the popover past the viewport on
   phones; the textarea itself is selectable + scrollable so the
   user can paste the dump even when clipboard.writeText is blocked
   by Safari. */
.settings .diag {
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border-color, currentColor);
  opacity: 0.85;
}
.settings .diag summary { cursor: pointer; font-size: 0.85em; }
.settings .diag .diag-body {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-top: 0.5rem;
  font-size: 0.8em;
}
.settings .diag .diag-run {
  font-size: 0.85em;
  padding: 0.25rem 0.5rem;
  align-self: flex-start;
}
.settings .diag .diag-output {
  width: 100%;
  box-sizing: border-box;
  height: 8em;
  max-height: 25vh;
  overflow: auto;
  resize: vertical;
  white-space: pre;
  font: 10px/1.3 ui-monospace, monospace;
  padding: 0.4rem;
  background: rgba(127, 127, 127, 0.12);
  border: 1px solid rgba(127, 127, 127, 0.3);
  border-radius: 4px;
  color: inherit;
}
.settings .diag .diag-status {
  font-size: 0.8em;
  min-height: 1em;
  word-wrap: break-word;
}
