/* ============================================
   BOS Professional Docs — site.css (CHROME ONLY)
   Header, sidebar nav, breadcrumb, footer, layout, tokens.
   Do not put documentation-content styling here — see content.css.
   ============================================ */

/* ============================================
   1. TOKENS — locked monochrome spec
   ============================================ */
:root {
  --gray-950: #050505;
  --gray-900: #0c0c0c;
  --gray-800: #262626;
  --gray-700: #404040;
  --gray-600: #525252;
  --gray-500: #6b6b6b;
  --gray-400: #a3a3a3;
  --gray-300: #d4d4d4;
  --gray-200: #e5e5e5;
  --gray-100: #f0f0f0;
  --gray-50: #f7f7f7;

  --background: #ffffff;
  --background-alt: var(--gray-50);
  --foreground: var(--gray-900);
  --muted: var(--gray-50);
  --muted-foreground: var(--gray-500);
  --border: var(--gray-200);
  --border-strong: var(--gray-300);
  --primary: var(--gray-900);
  --primary-dark: var(--gray-950);
  --primary-foreground: #ffffff;

  --destructive: #b91c1c;
  --destructive-bg: rgba(220, 38, 38, 0.1);
  --destructive-foreground: #ffffff;

  /* The Info callout's color - a deliberate, explicit deviation from the
     monochrome spec (alongside --destructive and --accent), not derived
     from the logo like --accent. Light blue (#0277bd, ~4.8:1 on white)
     so it stays distinct from the green --accent Navigation callout. See
     project-docs/Stylesheet.md. */
  --info: #0277bd;
  --info-bg: rgba(2, 119, 189, 0.08);

  /* Sampled from the real BOS Professional logo (the green square icon
     mark, Sources/BP logo - Icon.jpg -> RGB(0,155,64) / #009B40). That
     raw value only clears WCAG AA at large-text sizes (h1's 30px bold
     is fine at ~3.8:1, but the Navigation callout's 12px bold label and
     the 15px sidebar__group-heading both need 4.5:1 on white) - so this
     is the same hue darkened (R0 G127 B52) to ~5.1:1 contrast on white,
     the smallest deepening that clears the 4.5:1 bar with a safety
     margin. Used in exactly four places: the h1 heading colour, the
     Navigation callout (content.css .callout--navigation), sidebar group
     headings (.sidebar__group-heading), and editable-field cells
     (content.css td.field-editable, added 2026-10-05) - nowhere else.
     See CLAUDE.md "Styling rule". */
  --accent: #007f34;
  --accent-bg: rgba(0, 127, 52, 0.08);

  /* Callout background tints for Note and Important - a few shades
     lighter than the border/label color so callout text stays easily
     readable. --note-bg tints --muted-foreground (gray); --important-bg
     tints --foreground itself (deliberately the lowest alpha of the
     five, since --foreground is much darker/more neutral than the other
     four callout colors and would otherwise read as a near-solid fill).
     Ported from bos-ent-docs; --accent-bg above is this site's own green. */
  --note-bg: rgba(107, 107, 107, 0.08);
  --important-bg: rgba(12, 12, 12, 0.06);

  --font-body: "Roboto", system-ui, -apple-system, "Segoe UI", Arial, sans-serif;
  --font-mono: ui-monospace, "SFMono-Regular", "Consolas", "Liberation Mono", Menlo, monospace;

  --space-xs: 0.25rem;
  --space-sm: 0.5rem;
  --space-md: 1rem;
  --space-lg: 2rem;
  --space-xl: 3rem;

  /* Desktop and tablet only - this project doesn't support phone-width
     viewports. --breakpoint-md is the supported floor (not a mobile
     cutoff); --breakpoint-lg is where the "On this page" TOC gets
     promoted from an inline block into its own third grid column. */
  --breakpoint-md: 768px;
  --breakpoint-lg: 1100px;
  --header-height: 4.75rem;
  --sidebar-width: 17rem;
  --toc-width: 14rem;
}

:root[data-theme="dark"] {
  --dark-elevated: #1c1c1c;
  --background: var(--gray-950);
  --background-alt: var(--dark-elevated);
  --foreground: var(--gray-50);
  --muted: var(--dark-elevated);
  --muted-foreground: var(--gray-400);
  --border: var(--gray-800);
  --border-strong: var(--gray-700);
  --primary: var(--gray-50);
  --primary-dark: #ffffff;
  --primary-foreground: var(--gray-950);

  --destructive: #f87171;
  --destructive-bg: rgba(248, 113, 113, 0.14);
  --destructive-foreground: var(--gray-950);

  /* #0277bd is too dark on dark backgrounds - this lighter tint of the
     same light blue passes strongly while still reading as blue. */
  --info: #4fc3f7;
  --info-bg: rgba(79, 195, 247, 0.14);

  /* Same brand hue as the light-mode --accent, lightened (R0 G200 B83,
     keeping R at 0 and scaling G/B up proportionally) for
     ~9.2:1 contrast against --gray-950 - comfortably legible without
     reading as neon, the same margin bos-ent-docs used lightening
     #004090 -> #5b9bf5. */
  --accent: #00c853;
  --accent-bg: rgba(0, 200, 83, 0.14);

  /* See :root comment - same tints, bumped slightly (0.08->0.12,
     0.06->0.08) to stay visible against the near-black dark background. */
  --note-bg: rgba(163, 163, 163, 0.12);
  --important-bg: rgba(247, 247, 247, 0.08);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --dark-elevated: #1c1c1c;
    --background: var(--gray-950);
    --background-alt: var(--dark-elevated);
    --foreground: var(--gray-50);
    --muted: var(--dark-elevated);
    --muted-foreground: var(--gray-400);
    --border: var(--gray-800);
    --border-strong: var(--gray-700);
    --primary: var(--gray-50);
    --primary-dark: #ffffff;
    --primary-foreground: var(--gray-950);
    --destructive: #f87171;
    --destructive-bg: rgba(248, 113, 113, 0.14);
    --destructive-foreground: var(--gray-950);
    --info: #4fc3f7;
    /* Kept in sync with the :root[data-theme="dark"] block above, for
       the no-stored-preference OS-dark case. */
    --accent: #00c853;
    --info-bg: rgba(79, 195, 247, 0.14);
    --accent-bg: rgba(0, 200, 83, 0.14);
    --note-bg: rgba(163, 163, 163, 0.12);
    --important-bg: rgba(247, 247, 247, 0.08);
  }
}

@font-face {
  font-family: "Roboto";
  src: url("/assets/fonts/roboto-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Roboto";
  src: url("/assets/fonts/roboto-700.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* ============================================
   2. RESET / BASE
   ============================================ */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-padding-top: var(--space-md); }
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.5;
  color: var(--foreground);
  background: var(--background);
}
img { max-width: 100%; height: auto; display: block; }
h1, h2, h3, h4, p { margin: 0 0 var(--space-md); }
a { color: inherit; }

/* ============================================
   3. LAYOUT
   ============================================ */
.container {
  max-width: 1280px;
  margin-inline: auto;
  padding-inline: var(--space-md);
}

.site-body {
  display: flex;
  flex-direction: column;
  max-width: 1280px;
  margin-inline: auto;
}

/* Desktop and tablet only (no phone-width layout), responsive down to
   half an FHD screen (960px): sidebar + content is the baseline
   two-column grid at every supported width. The "On this page" TOC
   (.doc-layout--has-toc) is a real third grid column, but only once
   there's genuinely enough room for it (--breakpoint-lg) - below that,
   it's hidden outright rather than left to fall back into the
   two-column grid, which put it in the same column as (and, on a short
   page, visually on top of) the sidebar. A hidden TOC below is still a
   fully usable page: every page also has a real "On this page" is a
   convenience, not the only way to reach a section - direct links and
   scrolling both still work. */
.doc-layout {
  display: grid;
  grid-template-columns: var(--sidebar-width) minmax(0, 1fr);
  gap: var(--space-lg);
  align-items: start;
  padding-inline: var(--space-md);
  padding-block: var(--space-lg);
}

.doc-content-wrapper {
  min-width: 0;
  max-width: 48rem;
}

.doc-layout--has-toc .page-toc {
  display: none;
}

@media (min-width: 1100px) {
  .doc-layout--has-toc {
    grid-template-columns: var(--sidebar-width) minmax(0, 1fr) var(--toc-width);
  }
  .doc-layout--has-toc .page-toc {
    display: block;
    grid-column: 3;
    grid-row: 1;
    position: sticky;
    top: calc(var(--header-height) + var(--space-lg));
    /* Same independent-scroll fix as .sidebar above, for the rare page
       with enough headings that its TOC alone is taller than the
       viewport. */
    max-height: calc(100vh - var(--header-height) - var(--space-lg) * 2);
    overflow-y: auto;
    margin-bottom: 0;
  }
}

/* ============================================
   4. COMPONENTS
   ============================================ */

/* --- Skip link --- */
.skip-link {
  position: absolute;
  top: -3rem;
  left: var(--space-sm);
  background: var(--primary);
  color: var(--primary-foreground);
  padding: var(--space-sm) var(--space-md);
  z-index: 100;
  border-radius: 4px;
}
.skip-link:focus { top: var(--space-sm); }

/* --- Header --- */
.site-header {
  border-bottom: 1px solid var(--border);
  background: var(--background);
  position: sticky;
  top: 0;
  z-index: 20;
}
.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  height: var(--header-height);
  padding-inline: var(--space-md);
  max-width: 1280px;
  margin-inline: auto;
}
.site-header__logo {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  /* The source logo files (Sources/) are flat JPGs with an opaque white
     background baked in, not transparent artwork - the chip is still
     hardcoded white (not a theme token) so the logo's own white backing
     doesn't read as a mismatched box against a dark header in dark mode. */
  background: #ffffff;
  /* Matches .sidebar__link's own horizontal padding (--space-sm) so the
     visible wordmark lines up with the sidebar/content edge in both
     themes - see bos-professional-logo-v2.png below and CLAUDE.md
     "Header". */
  padding: var(--space-sm);
  border-radius: 4px;
  text-decoration: none;
}
/* bos-professional-logo-v2.png (734x262, tightly cropped to the ink -
   see CLAUDE.md "Header") rendered at 2.5rem tall comfortably fits
   inside --header-height (4.75rem) with breathing room above/below;
   width is auto to preserve its ~2.8:1 aspect ratio. */
.site-header__logo img { display: block; height: 2.5rem; width: auto; }

.site-header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  min-width: 0;
}

/* --- Feedback button (header) ---
   Always visible, every page - see CLAUDE.md "Feedback modal". Reuses
   the .btn/.btn-outline component. `font: inherit` (then restoring just
   the weight) copies .site-search__input's own box model exactly -
   same padding/border/line-height math - so the two sit at the same
   height by construction, not a coincidentally-matching hardcoded
   number that would drift if the base font size ever changed. */
.btn.site-header__feedback {
  flex-shrink: 0;
  padding: var(--space-xs) var(--space-md);
  font: inherit;
  font-weight: 600;
  white-space: nowrap;
}

/* --- Theme toggle ---
   Manual override of the automatic prefers-color-scheme default. Shows the
   icon for the mode you'd switch TO. No stored preference = follows the
   OS/browser setting (handled by the same media query as every other
   token); clicking sets an explicit data-theme and remembers it. */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border: 0;
  background: transparent;
  cursor: pointer;
  color: var(--foreground);
  flex-shrink: 0;
}
.theme-toggle svg { width: 1.25rem; height: 1.25rem; }
.theme-toggle__icon--dark { display: block; }
.theme-toggle__icon--light { display: none; }

:root[data-theme="dark"] .theme-toggle__icon--dark { display: none; }
:root[data-theme="dark"] .theme-toggle__icon--light { display: block; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle__icon--dark { display: none; }
  :root:not([data-theme="light"]) .theme-toggle__icon--light { display: block; }
}

/* --- Sidebar tree nav ---
   A grid column from 900px up (hideable with the header menu button), a
   slide-in drawer below that - see "Menu toggle + collapsible sidebar"
   below. */
.sidebar {
  display: block;
  position: sticky;
  top: calc(var(--header-height) + var(--space-lg));
  /* Bounds the sticky nav to the viewport space actually below it (minus
     a matching --space-lg breathing room at the bottom), and makes that
     bounded box its own scroll container. Without this, a nav list
     taller than the viewport just rides along with the page scroll once
     it hits the bottom of its sticky containing block (the grid cell,
     which - align-items: start - is exactly as tall as whichever column
     is taller) - so on a long content page there's no way to reach the
     nav's own lower items without first scrolling all the way to the
     bottom of the content column. overflow-y: auto here means a mouse
     wheel over the nav scrolls the nav (not the page) the moment the
     pointer is over it - no click-to-focus step needed - and Tab/arrow
     navigation between links scrolls it too, since it's a real
     scrollable ancestor. */
  max-height: calc(100vh - var(--header-height) - var(--space-lg) * 2);
  overflow-y: auto;
}
.sidebar__list {
  list-style: none;
  margin: 0;
  padding: 0;
}
/* Group headings (Getting Started, Accounting & Finance, ...) - a purely
   visual/navigational clustering above build.js's SIDEBAR_GROUPS, not
   another collapsible layer. Accent color is one of the four sanctioned
   uses of --accent (alongside H1, .callout--navigation and
   td.field-editable) - see Stylesheet.md.
   Title case + a thin bottom-border divider, not uppercase + letter-
   spacing: at a size matching the root menu items (see below), bold
   uppercase letter-spaced text read as heavy/shouty rather than as a
   section label - the divider does the "this is a section break" job
   instead, the same way content.css's h2 uses a border-top rule. */
.sidebar__group-heading {
  margin: var(--space-lg) 0 var(--space-sm);
  padding: 0 var(--space-sm) var(--space-xs);
  border-bottom: 1px solid var(--border);
  /* At least as large as the root-level menu items (.sidebar__link /
     .sidebar__group-link, 0.9375rem) - it was 0.75rem originally, which
     read as smaller/lower-priority than the items it groups. */
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--accent);
}
.sidebar__list:first-of-type + .sidebar__group-heading {
  margin-top: var(--space-sm);
}

.sidebar__group { margin-bottom: var(--space-xs); }
/* The category label is a real link to its own landing page (per the
   WAI-ARIA APG Disclosure pattern - see CLAUDE.md "Sidebar"); the toggle
   is a separate, small icon-only button beside it that only expands/
   collapses the sublist. Two independent controls, not one overloaded
   button - this is also what fixed the font-size mismatch bug (the old
   button used font: inherit and rendered a size larger than every other
   sidebar link). */
.sidebar__group-row {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}
.sidebar__group-row .sidebar__link { flex: 1; min-width: 0; }
.sidebar__group-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 2rem;
  height: 2rem;
  border: 0;
  background: transparent;
  cursor: pointer;
  border-radius: 4px;
}
.sidebar__group-toggle:hover,
.sidebar__group-toggle:focus-visible { background: var(--muted); }
.sidebar__group-toggle-icon {
  display: inline-block;
  width: 0.4rem;
  height: 0.4rem;
  border-right: 2px solid var(--muted-foreground);
  border-bottom: 2px solid var(--muted-foreground);
  transform: rotate(45deg);
  transition: transform 0.15s ease;
  flex-shrink: 0;
}
.sidebar__group[data-open="true"] .sidebar__group-toggle-icon {
  transform: rotate(-135deg);
}
.sidebar__sublist {
  list-style: none;
  margin: 0;
  padding: 0 0 var(--space-sm) var(--space-md);
  display: none;
}
.sidebar__group[data-open="true"] .sidebar__sublist { display: block; }
.sidebar__link {
  display: block;
  padding: var(--space-xs) var(--space-sm);
  text-decoration: none;
  color: var(--muted-foreground);
  border-radius: 4px;
  font-size: 0.9375rem;
}
.sidebar__link:hover,
.sidebar__link:focus-visible { background: var(--muted); color: var(--foreground); }
/* Every top-level item reads as a peer, whether it's a childless
   category link or a category-with-children's link (now beside its own
   separate toggle button, not part of it) - one shared rule, so there's
   only one place that can drift out of sync. */
.sidebar__list > li > .sidebar__link,
.sidebar__group-link {
  color: var(--foreground);
  font-weight: 600;
}
.sidebar__link[aria-current="page"] {
  color: var(--foreground);
  font-weight: 600;
  background: var(--muted);
}

/* --- Breadcrumb --- */
.breadcrumb {
  margin-bottom: var(--space-md);
  font-size: 0.875rem;
  color: var(--muted-foreground);
}
.breadcrumb__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
}
.breadcrumb__list li:not(:last-child)::after {
  content: "/";
  margin-left: var(--space-xs);
  color: var(--border-strong);
}
.breadcrumb__list a { text-decoration: none; }
.breadcrumb__list a:hover { text-decoration: underline; }

/* --- On-page "On this page" jump list (static, no scroll-spy) ---
   A narrow right-rail column at desktop width (--breakpoint-lg+);
   hidden below that - see .doc-layout--has-toc above. No background/
   border box (matches the minimal, no-decoration language callouts and
   the sidebar group headings also use) - just a heading with a thin
   bottom-border divider, same treatment as .sidebar__group-heading, at
   a smaller/muted scale appropriate to a page-local aid rather than a
   root nav peer. */
.page-toc {
  margin-bottom: var(--space-lg);
}
.page-toc__heading {
  margin: 0 0 var(--space-sm);
  padding-bottom: var(--space-xs);
  border-bottom: 1px solid var(--border);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--muted-foreground);
}
.page-toc__list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.page-toc__item { font-size: 0.9375rem; padding: var(--space-xs) 0; }
.page-toc__item--h3 { padding-left: var(--space-md); }
.page-toc__item a { display: block; color: var(--foreground); text-decoration: none; }
.page-toc__item a:hover { text-decoration: underline; }

/* --- Related topics ---
   Bottom-of-page nav for subpages that have no sidebar entry of their own
   (see tools/add-related-topics-nav.js). A plain,
   non-sequential list of sibling pages in the same folder, not a Prev/Next:
   CLAUDE.md documents that a literal Prev/Next was removed on purpose,
   since the only sibling order available (alphabetical) isn't a curated
   reading order and Prev/Next visually implies one. Sits inside
   .doc-content-wrapper (after </article>, so it's outside data-pagefind-body
   and never indexed), same heading treatment as .page-toc__heading above. */
.related-topics {
  margin-top: var(--space-lg);
  padding-top: var(--space-md);
  border-top: 1px solid var(--border);
}
.related-topics__heading {
  margin: 0 0 var(--space-sm);
  padding-bottom: var(--space-xs);
  border-bottom: 1px solid var(--border);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--muted-foreground);
}
.related-topics__list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
  gap: var(--space-xs) var(--space-md);
  list-style: none;
  margin: 0;
  padding: 0;
}
.related-topics__list a {
  display: block;
  color: var(--foreground);
  text-decoration: none;
  font-size: 0.9375rem;
}
.related-topics__list a:hover { text-decoration: underline; }
/* The curated "Related Topics" block (tools/convert-related-topics.js) -
   same look as the "More ..." block above it, but each row is a topic:
   "Label: link · link", with full-width section rows for larger groups. */
.related-topics__rows {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
  gap: var(--space-xs) var(--space-lg);
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.9375rem;
}
.related-topics__rows a {
  color: var(--foreground);
  text-decoration: none;
}
.related-topics__rows a:hover { text-decoration: underline; }
.related-topics__label { font-weight: 600; }
.related-topics__wide { grid-column: 1 / -1; }
.related-topics__section {
  grid-column: 1 / -1;
  margin-top: var(--space-xs);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--muted-foreground);
}
.related-topics__note,
.related-topics__sep { color: var(--muted-foreground); }
/* The "Learn More" block (tools/learn-more.js, BOS docs' format): one
   column, each row "Topic: description" - topic linked in bold, the
   description muted (.related-topics__note). */
.related-topics__rows--single { grid-template-columns: 1fr; }
.related-topics--learn-more .related-topics__rows a { font-weight: 600; }

/* --- Feedback modal ---
   Trigger is the "Feedback" button in the header (site.css
   .site-header__feedback above) - always visible, every page. Opens
   directly to the form if text was already selected on the page;
   otherwise opens to a prompt (.feedback-prompt) suggesting the user
   select the relevant text first, or continue without it. */
.feedback-modal {
  width: min(32rem, calc(100vw - 2 * var(--space-md)));
  max-height: min(85vh, 42rem);
  padding: 0;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  background: var(--background);
  color: var(--foreground);
}
.feedback-modal::backdrop {
  background: rgba(0, 0, 0, 0.5);
}
.feedback-modal__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-md);
  padding: var(--space-lg) var(--space-lg) 0;
}
.feedback-modal__header h2 { margin: 0; font-size: 1.25rem; }
.feedback-prompt {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  padding: var(--space-md) var(--space-lg) var(--space-lg);
}
.feedback-prompt p { margin: 0; color: var(--muted-foreground); }
.feedback-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  padding: var(--space-md) var(--space-lg) var(--space-lg);
  overflow-y: auto;
}
/* The plain [hidden] attribute needs an explicit rule here: an author
   stylesheet's own `display` declaration always wins over the
   UA stylesheet's default `[hidden] { display: none }`, regardless of
   selector specificity or source order - so without this, toggling
   .hidden in JS (feedback-prompt/feedback-form/a .form-group) would do
   nothing visually, since .feedback-prompt/.feedback-form/.form-group
   above already set their own `display`. */
.feedback-prompt[hidden],
.feedback-form[hidden],
.form-group[hidden] {
  display: none;
}
.feedback-modal__close {
  flex-shrink: 0;
  width: 2rem;
  height: 2rem;
  border: 0;
  background: transparent;
  color: var(--muted-foreground);
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
  border-radius: 4px;
}
.feedback-modal__close:hover,
.feedback-modal__close:focus-visible { background: var(--muted); color: var(--foreground); }

.form-honeypot { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.form-group { display: flex; flex-direction: column; gap: var(--space-xs); }
.form-group label { font-size: 0.875rem; font-weight: 600; }
.form-group .required { color: var(--destructive); }
.form-group input,
.form-group textarea {
  padding: var(--space-sm);
  border: 1px solid var(--border-strong);
  border-radius: 4px;
  background: var(--background);
  color: var(--foreground);
  font: inherit;
  resize: vertical;
}
.form-group input[readonly] { color: var(--muted-foreground); background: var(--muted); }

.feedback-form__actions {
  display: flex;
  gap: var(--space-sm);
}
.feedback-status {
  margin: 0;
  font-size: 0.875rem;
  color: var(--muted-foreground);
  min-height: 1.25em;
}
.feedback-status--success { color: var(--foreground); font-weight: 600; }
.feedback-status--error { color: var(--destructive); }

/* --- Image lightbox ---
   Clicking any doc-content figure image (assets/js/main.js) opens it
   here at full/native size - images are scaled down to the content
   column's width in place (see content.css .doc-content figure img),
   so this is how a reader gets back to a legible full-size view. A
   <dialog> built once and reused for every click, same pattern as the
   feedback modal: showModal() gives focus-trapping/top-layer/Escape for
   free, and backdrop-click-to-close needs one manual listener. */
.lightbox {
  padding: 0;
  border: 0;
  background: transparent;
  max-width: 95vw;
  max-height: 95vh;
}
.lightbox::backdrop {
  background: rgba(0, 0, 0, 0.85);
}
.lightbox img {
  display: block;
  max-width: 95vw;
  max-height: 95vh;
  width: auto;
  height: auto;
  cursor: zoom-out;
}

/* --- Search (header box - submits to /search/) --- */
.site-search { flex: 1; min-width: 0; max-width: 26rem; margin: 0; }
.site-search__input {
  width: 100%;
  padding: var(--space-xs) var(--space-sm);
  border: 1px solid var(--border-strong);
  border-radius: 4px;
  background: var(--background);
  color: var(--foreground);
  font: inherit;
}

/* --- Search results page (/search/) ---
   Two columns; stacked (results first) at phone width - see "Phone
   width" below. */
.doc-layout.search-layout {
  grid-template-columns: 14rem minmax(0, 1fr);
}
.search-filters__heading {
  font-size: 1rem;
  font-weight: 700;
  margin: 0 0 var(--space-sm);
}
.search-filters__list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.search-filters__item label {
  display: flex;
  align-items: baseline;
  gap: var(--space-xs);
  padding: var(--space-xs) 0;
  cursor: pointer;
  font-size: 0.9375rem;
}
.search-filters__label { flex: 1; }
.search-filters__count { color: var(--muted-foreground); font-size: 0.8125rem; }
.search-filters__item--empty .search-filters__label,
.search-filters__item--empty .search-filters__count {
  color: var(--muted-foreground);
  opacity: 0.6;
}

.search-heading { margin-bottom: var(--space-xs); }
.search-toolbar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin-bottom: var(--space-lg);
}
.search-status { color: var(--muted-foreground); }
.search-sort {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-size: 0.875rem;
  color: var(--muted-foreground);
  flex-shrink: 0;
}
.search-sort select {
  padding: var(--space-xs) var(--space-sm);
  border: 1px solid var(--border-strong);
  border-radius: 4px;
  background: var(--background);
  color: var(--foreground);
  font: inherit;
  font-size: 0.875rem;
}

.search-results-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}
.search-result-card {
  display: block;
  padding: var(--space-md);
  border: 1px solid var(--border);
  border-radius: 6px;
  text-decoration: none;
  color: inherit;
}
.search-result-card:hover,
.search-result-card:focus-visible {
  border-color: var(--border-strong);
  background: var(--muted);
}
.search-result-card__title {
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--foreground);
  margin: 0 0 var(--space-xs);
}
.search-result-card__url {
  display: block;
  font-size: 0.8125rem;
  color: var(--muted-foreground);
  margin-bottom: var(--space-xs);
}
.search-result-card__excerpt {
  font-size: 0.9375rem;
  color: var(--muted-foreground);
  line-height: 1.5;
  margin: 0;
}
.search-result-card__excerpt mark {
  background: none;
  color: var(--foreground);
  font-weight: 700;
}

/* --- Buttons --- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
  padding: 0.75rem 1.5rem;
  border-radius: 4px;
  font-weight: 600;
  font-family: var(--font-body);
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
}
.btn-primary { background: var(--primary); color: var(--primary-foreground); }
.btn-primary:hover { background: var(--primary-dark); }
/* A button-styled link inside an article (e.g. the 404 page's "Go to the
   documentation home page") must not pick up content.css's link colour -
   that made its text the same colour as the button. */
.doc-content a.btn { text-decoration: none; }
.doc-content a.btn-primary,
.doc-content a.btn-primary:hover { color: var(--primary-foreground); }
.btn-outline { background: transparent; border-color: var(--border-strong); color: var(--foreground); }
.btn-outline:hover { border-color: var(--primary); }

/* --- Footer ---
   Just the copyright line - the old Browse/Contact/blurb columns were
   superfluous (this page's own header/sidebar already cover finding
   things and reporting an issue) and were removed. */
.site-footer {
  background: var(--background-alt);
  margin-top: var(--space-xl);
  border-top: 1px solid var(--border);
}
.site-footer__bottom {
  padding-block: var(--space-sm);
  padding-inline: var(--space-md);
  font-size: 0.875rem;
  color: var(--muted-foreground);
  max-width: 1280px;
  margin-inline: auto;
}

/* --- Menu toggle + collapsible sidebar ---
   The header's menu (hamburger) button shows/hides the sidebar
   (assets/js/main.js). Two modes, split at 900px:
   - Wide (900px+): the sidebar is a grid column, shown by default. The
     button collapses it (html.sidebar-collapsed, remembered in
     localStorage and applied before first paint by the <head> script),
     giving the content the full width.
   - Compact (under 900px - phones, portrait tablets, a narrowed desktop
     window): the sidebar is hidden by default and the button slides it
     in as a drawer over the content (html.sidebar-open, not remembered),
     with a backdrop that closes it. --header-height is set from the
     header's real height by main.js in this mode, since the phone header
     wraps onto two rows. */
.menu-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  margin-inline-start: calc(var(--space-sm) * -1);
  border: 0;
  border-radius: 4px;
  background: transparent;
  cursor: pointer;
  color: var(--foreground);
  flex-shrink: 0;
}
@media (hover: hover) {
  .menu-toggle:hover { background: var(--muted); }
}
.menu-toggle svg { width: 1.5rem; height: 1.5rem; }
/* Logo stays next to the menu button; the actions keep to the right. */
.site-header__logo { margin-inline-end: auto; }

@media (min-width: 900px) {
  .sidebar-collapsed .doc-layout:not(.search-layout) {
    grid-template-columns: minmax(0, 1fr);
  }
  .sidebar-collapsed .sidebar { display: none; }
}
@media (min-width: 1100px) {
  .sidebar-collapsed .doc-layout--has-toc {
    grid-template-columns: minmax(0, 1fr) var(--toc-width);
  }
  .sidebar-collapsed .doc-layout--has-toc .page-toc { grid-column: 2; }
}

.sidebar-backdrop {
  position: fixed;
  inset: var(--header-height) 0 0 0;
  z-index: 14;
  background: rgba(0, 0, 0, 0.4);
}

@media (max-width: 899.98px) {
  .doc-layout:not(.search-layout) { grid-template-columns: minmax(0, 1fr); }
  .sidebar {
    position: fixed;
    top: var(--header-height);
    bottom: 0;
    left: 0;
    z-index: 15;
    width: min(20rem, 85vw);
    max-height: none;
    padding: 0 var(--space-md) var(--space-lg);
    background: var(--background);
    border-right: 1px solid var(--border);
    overscroll-behavior: contain;
    transform: translateX(-100%);
    visibility: hidden;
    transition: transform 0.2s ease, visibility 0s linear 0.2s;
  }
  .sidebar-open .sidebar {
    transform: none;
    visibility: visible;
    transition: transform 0.2s ease;
  }
  .sidebar-open body { overflow: hidden; }
}
@media (prefers-reduced-motion: reduce) {
  .sidebar, .sidebar-open .sidebar { transition: none; }
}

/* --- Phone width (under 600px) ---
   The header wraps: menu button, logo, Feedback and theme toggle on the
   first row, the search box full width on the second (the actions
   wrapper steps aside with display: contents so its children can be
   placed individually). Search results come before the filters. */
@media (max-width: 599.98px) {
  .site-header__inner {
    flex-wrap: wrap;
    height: auto;
    column-gap: var(--space-sm);
    row-gap: var(--space-sm);
    padding-block: var(--space-sm);
  }
  .site-header__actions { display: contents; }
  .site-header__logo img { height: 2rem; }
  .site-search { order: 1; flex: 1 1 100%; max-width: none; }
  .btn.site-header__feedback { padding-inline: var(--space-sm); }
  .doc-layout { padding-block: var(--space-md); }
  .doc-layout.search-layout { grid-template-columns: minmax(0, 1fr); }
  .search-layout .search-filters { order: 1; }
}

/* ============================================
   5. UTILITIES
   ============================================ */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
.text-center { text-align: center; }
