@charset "UTF-8";
/* ── docs.css — FULL-WIDTH, GitHub-style public documentation shell.
 *
 * Ported from the approved prototype docs/design/prototypes/css/docs.public.css
 * (prototype `.pb-docs-*` / `.pb-api-*` classes translated to production `.ev-docs-*`
 * / `.ev-docs-api-*` naming). Layers over site.css tokens (--accent, --neutral-*,
 * --radius=3px, semantic status tokens, --sp-*) and reuses components.css
 * (.ev-input for the search field, .ev-link visual language for content links).
 *
 * Design rules (locked): --radius (3px) everywhere; accent yellow on DARK
 * surfaces only (code blocks) — never on white; full-bleed layout, no centered
 * max-width column. The rails pin to the screen edges; the article fills the
 * space between with clamp() gutters. ─────────────────────────────────────── */
/* ── Prism theme — NONE imported on purpose ───────────────────────────────────
 * Prism's stock theme is LIGHT: text-shadow:0 1px white on every character, token
 * colours 905 / 07a / 690 / slategray, and .token.operator on a translucent
 * white block — all of it painted over our near-black code surface. The prototype
 * uses a hand-tuned DARK palette instead (docs.public.css:220-224), which is
 * declared below against Prism's own token classes. Importing a stock theme here
 * would also re-introduce `pre[class*="language-"] { padding: 1em }`, doubling the
 * inset on top of our own 16px. ─────────────────────────────────────────────── */
/* ── Full-bleed public chrome (docs pages only) ───────────────────────────────
 * Prototype docs.public.css:23-30: the nav and footer drop their max-width and
 * adopt the docs shell's clamp() gutters, "so the logo lines up with the sidebar
 * and the auth actions line up with the ToC". Without this, above 1152px the
 * chrome sits inset from the rails it is supposed to align with.
 *
 * Scoped by the SAME modifier classes the prototype uses (.pb-nav--wide /
 * .pb-footer--wide -> .ev-nav--wide / .ev-footer--wide), which _Layout emits when
 * _DocsLayout sets ViewData["WideChrome"]. Scoping by an explicit modifier rather
 * than by "docs.css only loads on docs pages" keeps the rules honest about what
 * they apply to, and lets any future full-width page opt in.
 *
 * No `!important` anywhere: _Layout OMITS Bootstrap's `.justify-content-between`
 * on wide pages, so there is no !important utility left to out-shout. This file
 * previously had to declare `justify-content: flex-start !important` purely to
 * win that fight. ── */
.ev-nav--wide > .ev-container,
.ev-footer--wide > .ev-container {
  max-width: none;
  padding: 0 clamp(24px, 4vw, 64px);
}

/* Group the logo + primary links together on the left; push auth actions right
   (prototype .pb-nav--wide .pb-nav-inner / .pb-nav-right). */
.ev-nav--wide > .ev-container {
  justify-content: flex-start;
  gap: 40px;
}

.ev-nav--wide > .ev-container > #ev-nav-auth {
  margin-left: auto;
}

/* ── Shell — full-bleed (no max-width cap) ────────────────────── */
.ev-docs-shell {
  padding: 0 clamp(24px, 4vw, 64px) 96px;
}

/* ── Top utility bar — sidebar toggle (tablet/mobile) + breadcrumbs ── */
.ev-docs-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 0;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--neutral-100);
}

.ev-docs-menu-btn {
  display: none; /* tablet/mobile only (media queries flip it on) */
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  flex-shrink: 0;
  background: var(--white);
  border: 1px solid var(--neutral-200);
  border-radius: var(--radius);
  color: var(--neutral-700);
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}

.ev-docs-menu-btn:hover {
  background: var(--neutral-50);
  border-color: var(--neutral-300);
}

.ev-docs-menu-btn svg {
  width: 17px;
  height: 17px;
}

/* Breadcrumbs */
.ev-docs-breadcrumbs {
  display: flex;
  align-items: center;
  gap: 7px;
  flex-wrap: wrap;
  font-size: var(--fs-meta);
  color: var(--neutral-500);
  margin: 0;
  min-width: 0;
}

.ev-docs-breadcrumb-home {
  color: var(--neutral-600);
  text-decoration: none;
}

.ev-docs-breadcrumb-home:hover {
  color: var(--neutral-900);
  text-decoration: underline;
}

.ev-docs-breadcrumb-sep {
  color: var(--neutral-300);
}

.ev-docs-breadcrumb-category {
  color: var(--neutral-600);
}

.ev-docs-breadcrumb-current {
  color: var(--neutral-900);
  font-weight: 500;
}

/* ── Grid: sidebar | article | toc ─────────────────────────────── */
.ev-docs-grid {
  display: grid;
  grid-template-columns: 256px minmax(0, 1fr) 232px;
  grid-template-areas: "sidebar article toc";
  gap: 0 clamp(32px, 3.5vw, 64px);
  align-items: start;
}

/* ── LEFT: nav rail ────────────────────────────────────────────── */
/* Sticky, no inner scroll — if the menu is taller than the viewport the page
   itself grows (matches the prototype). */
.ev-docs-sidebar {
  grid-area: sidebar;
  position: sticky;
  top: 64px; /* below the 64px sticky public nav */
  padding: 28px 8px 24px 0;
}

/* Overlay-only chrome (title + close) — hidden until the rail becomes a panel. */
.ev-docs-sidebar-head {
  display: none;
}

/* Search — reuses .ev-input (white field, neutral-300 border, black-glow focus);
   this only adds icon room, resets native search chrome, and strips the stray
   webkit clear button/decoration. */
.ev-docs-search {
  position: relative;
  margin-bottom: 24px;
}

.ev-docs-search-icon {
  position: absolute;
  left: 11px;
  top: 50%; /* centres against whatever the control height is */
  transform: translateY(-50%);
  width: 15px;
  height: 15px;
  color: var(--neutral-400);
  pointer-events: none;
  z-index: 1;
}

.ev-docs-search-input {
  width: 100%;
  padding: 0 12px 0 33px;
  -webkit-appearance: none;
  appearance: none;
}

.ev-docs-search-input::-webkit-search-cancel-button,
.ev-docs-search-input::-webkit-search-decoration {
  -webkit-appearance: none;
  display: none;
}

/* Search results dropdown (client-side search) */
.ev-docs-search-results {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  width: 100%;
  background: var(--white);
  border: 1px solid var(--neutral-200);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  z-index: 200;
  max-height: 360px;
  overflow-y: auto;
}

.ev-docs-search-result {
  display: block;
  padding: 10px 14px;
  text-decoration: none;
  color: var(--neutral-900);
  border-bottom: 1px solid var(--neutral-100);
  font-size: var(--fs-heading);
  transition: background 0.1s;
}

.ev-docs-search-result:last-child {
  border-bottom: none;
}

.ev-docs-search-result:hover {
  background: var(--neutral-50);
}

.ev-docs-search-result-title {
  font-weight: 500;
  display: block;
}

.ev-docs-search-result-category {
  font-size: var(--fs-caption);
  color: var(--neutral-500);
  margin-top: 2px;
  display: block;
}

.ev-docs-search-empty {
  padding: 14px;
  font-size: var(--fs-heading);
  color: var(--neutral-500);
  text-align: center;
}

/* Nav tree — the app's side-menu language (.ev-shell-nav): NO box / no border.
   A 3px accent bar on the left edge is the "you are here" marker —
   0 default, 30% on hover, 100% on active. */
.ev-docs-nav-category {
  margin-bottom: 18px;
}

.ev-docs-nav-category-label {
  display: block;
  font-family: "JetBrains Mono", monospace;
  font-size: var(--fs-9-5);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--neutral-400);
  padding: 0 22px 8px;
  white-space: nowrap;
}

.ev-docs-nav-items {
  list-style: none;
  margin: 0;
  padding: 0;
}

.ev-docs-nav-link {
  position: relative;
  display: block;
  padding: 8px 22px;
  font-size: var(--fs-body);
  font-weight: 400;
  line-height: 1.4;
  color: var(--neutral-600);
  text-decoration: none;
  white-space: nowrap;
  transition: color 0.12s;
}

.ev-docs-nav-link:hover {
  color: var(--neutral-900);
}

.ev-docs-nav-link.active {
  color: var(--neutral-900);
  font-weight: 500;
}

.ev-docs-nav-link::before {
  content: "";
  position: absolute;
  left: 0;
  top: 6px;
  bottom: 6px;
  width: 3px;
  background: var(--accent);
  border-radius: 0 var(--radius) var(--radius) 0;
  opacity: 0;
  transition: opacity 0.15s ease;
}

.ev-docs-nav-link:hover::before {
  opacity: 0.3;
}

.ev-docs-nav-link.active::before {
  opacity: 1;
}

/* ── CENTER: article ───────────────────────────────────────────── */
.ev-docs-article {
  grid-area: article;
  min-width: 0;
  padding: 28px 0 0;
}

/* Content typography */
.ev-docs-content {
  font-size: var(--fs-15-5);
  line-height: 1.75;
  color: var(--neutral-800);
}

.ev-docs-content > *:first-child {
  margin-top: 0;
}

.ev-docs-content h1 {
  font-family: "Geist", system-ui, sans-serif;
  font-size: var(--fs-docs-h1);
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--neutral-900);
  line-height: 1.15;
  margin: 0 0 12px;
}

.ev-docs-content h2 {
  font-family: "Geist", system-ui, sans-serif;
  font-size: var(--fs-title);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--neutral-900);
  line-height: 1.3;
  margin: 44px 0 12px;
  padding-top: 18px;
  border-top: 1px solid var(--neutral-100);
}

.ev-docs-content h3 {
  font-family: "Geist", system-ui, sans-serif;
  font-size: var(--fs-17);
  font-weight: 600;
  color: var(--neutral-900);
  line-height: 1.35;
  margin: 28px 0 8px;
}

/* h4–h6 lost their size when Bootstrap Reboot was dropped (issue 07): with no
 * font-size they fell back to the UA default (h4 1em, h5 .83em, h6 .67em of the
 * 15.5px body), so a markdown ### heading read barely larger than prose. Given an
 * explicit hierarchy under h3 (17px): h4 16 · h5 15 · h6 14 (issue 14). */
.ev-docs-content h4, .ev-docs-content h5, .ev-docs-content h6 {
  font-family: "Geist", system-ui, sans-serif;
  font-weight: 600;
  color: var(--neutral-900);
  line-height: 1.4;
  margin: 20px 0 6px;
}

.ev-docs-content h4 {
  font-size: var(--fs-16);
}

.ev-docs-content h5 {
  font-size: var(--fs-15);
}

.ev-docs-content h6 {
  font-size: var(--fs-14);
}

.ev-docs-content p {
  margin: 0 0 16px;
}

/* Lede — the intro paragraph, one size up and one tone lighter than body prose
   (prototype .pb-docs-lede, docs.public.css:130; used at public.docs.html:116 and
   public.api-reference.html:132).

   The prototype carries an explicit class, but neither producer of production
   content can emit one: guide bodies come from Markdig (plain <p>) and the
   API-reference lede is the spec's own description markdown. Both are, however,
   structurally identifiable — a guide lede is the paragraph directly after the
   <h1>; an endpoint lede is the paragraph directly after the meta pills (the h1
   there is nested inside .ev-docs-api-head, so `h1 + p` cannot reach it). */
.ev-docs-content > h1 + p,
.ev-docs-content > .ev-docs-api-meta + p {
  font-size: var(--fs-17);
  color: var(--neutral-600);
  line-height: 1.6;
  margin: 0 0 8px;
}

/* Content links — the CANONICAL inline link (components.css .ev-link): black bold
   TEXT + an accent UNDERLINE marker that thickens on hover. Auto-generated
   markdown links can't carry the .ev-link class, so the visual is matched here.
   Scoped to .ev-docs-content so nav / ToC / prev-next / buttons never inherit it;
   the download button is excluded so it can be a ghost button. */
.ev-docs-content a:not(.ev-docs-api-download):not(.ev-docs-api-reference-download) {
  color: var(--neutral-900);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
  transition: text-decoration-thickness 0.12s;
}

.ev-docs-content a:not(.ev-docs-api-download):not(.ev-docs-api-reference-download):hover {
  text-decoration-thickness: 2px;
}

.ev-docs-content ul, .ev-docs-content ol {
  padding-left: 22px;
  margin: 0 0 16px;
}

.ev-docs-content li {
  margin-bottom: 6px;
}

.ev-docs-content strong {
  font-weight: 600;
  color: var(--neutral-900);
}

/* Blockquote → info callout (replaces the old yellow-on-white box; rule: yellow
   on dark only). Markdown `>` renders <blockquote>. */
.ev-docs-content blockquote {
  margin: 22px 0;
  padding: 14px 16px;
  background: var(--info-bg);
  border: 1px solid var(--info-border);
  border-radius: var(--radius);
  color: var(--neutral-700);
  font-size: var(--fs-14);
  line-height: 1.6;
}

.ev-docs-content blockquote p {
  margin: 0;
}

.ev-docs-content blockquote p + p {
  margin-top: 10px;
}

.ev-docs-content blockquote a {
  color: var(--info-fg);
  text-decoration-color: var(--info-border);
}

/* Tables — bordered, tight first column */
.ev-docs-content table {
  width: 100%;
  max-width: 760px;
  border-collapse: collapse;
  font-size: var(--fs-heading);
  margin: 22px 0;
  border: 1px solid var(--neutral-200);
  border-radius: var(--radius);
  overflow: hidden;
}

.ev-docs-content thead {
  background: var(--neutral-50);
}

.ev-docs-content th {
  text-align: left;
  padding: 9px 14px;
  font-weight: 600;
  color: var(--neutral-700);
  border-bottom: 1px solid var(--neutral-200);
}

.ev-docs-content td {
  padding: 9px 14px;
  color: var(--neutral-700);
  vertical-align: top;
  border-bottom: 1px solid var(--neutral-100);
  line-height: 1.6;
}

.ev-docs-content tbody tr:last-child td,
.ev-docs-content tr:last-child td {
  border-bottom: none;
}

/* Tight first column (prototype docs.public.css:173-174). The prototype pairs the
   130px hint with `white-space: nowrap`, which is safe for ITS sample content but
   not for ours: guides/test-mode.md:22 has a 38-char unbreakable first cell in a
   3-column table and concepts/outcomes.md:36 a 27-char monospace token. With nowrap
   the table's min-content width exceeds the column on phone widths, and the table's
   `overflow: hidden` (needed to clip the 3px radius) then swallows the overflow with
   no scrollbar — the content becomes literally unreachable.

   `width: 130px` alone keeps the intended tight column (a table column width is a
   hint, and short cells render identically), while `overflow-wrap: anywhere` gives
   every cell a break opportunity. `anywhere` — unlike `break-word` — also shrinks
   the cell's MIN-CONTENT width, so the table can always fit its container and no
   clipping is possible at any viewport width, with or without JS. */
.ev-docs-content th:first-child,
.ev-docs-content td:first-child {
  width: 130px;
}

.ev-docs-content th,
.ev-docs-content td {
  overflow-wrap: anywhere;
}

/* Inline code is nowrap by design (below), but inside a cell that nowrap re-creates
   the overflow this rule exists to prevent — so it is relaxed here only. */
.ev-docs-content th code:not(pre > code),
.ev-docs-content td code:not(pre > code) {
  white-space: normal;
}

/* Inline code */
.ev-docs-content code:not(pre > code) {
  font-family: "JetBrains Mono", monospace;
  font-size: 0.84em;
  font-weight: 500;
  background: var(--neutral-100);
  color: var(--neutral-900);
  padding: 0.15em 0.4em;
  border-radius: var(--radius);
  border: 1px solid var(--neutral-200);
  white-space: nowrap;
}

/* Fenced code blocks — dark surface (accent yellow is allowed here).
 *
 * Structure mirrors the prototype's .pb-docs-code (docs.public.css:195-219): an
 * outer box that owns the border/radius and does NOT scroll, a header bar across
 * the top separated by a border, and the code itself as the horizontal scroller
 * inside. Production has no wrapper element to play the part of .pb-docs-code —
 * guide blocks come from Markdig and endpoint examples from ApiEndpoint.cshtml —
 * so <pre> is the outer box, `pre::before` is the header bar, and `pre > code`
 * is the scroller. Keeping the scroll on <code> is what lets the header bar stay
 * put when a long line is scrolled sideways. */
.ev-docs-content pre {
  position: relative;
  margin: 20px 0;
  border-radius: var(--radius);
  border: 1px solid rgb(var(--white-rgb)/0.1);
  background: var(--dark-bg);
  overflow: hidden; /* clips the radius; the scroller is <code> */
}

.ev-docs-content pre > code {
  font-family: "JetBrains Mono", monospace;
  font-size: var(--fs-meta);
  line-height: 1.75;
  display: block;
  padding: 16px;
  overflow-x: auto;
  color: rgb(var(--white-rgb)/0.82);
  background: transparent;
  border: none;
}

/* Copy button (JS-injected) — sits at the right end of the header bar, mirroring
   the prototype's .pb-docs-code-head layout (lang left, copy right). */
.ev-docs-copy-btn {
  position: absolute;
  top: 9px;
  right: 12px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 8px;
  font-family: "Geist", system-ui, sans-serif;
  font-size: var(--fs-fine);
  font-weight: 500;
  color: var(--neutral-400);
  background: rgb(var(--white-rgb)/0.06);
  border: 1px solid rgb(var(--white-rgb)/0.12);
  border-radius: var(--radius);
  cursor: pointer;
  transition: color 0.15s, background 0.15s;
  line-height: 1.5;
}

.ev-docs-copy-btn:hover {
  color: var(--white);
  background: rgb(var(--white-rgb)/0.14);
}

.ev-docs-copy-btn.copied {
  color: var(--code-teal);
  border-color: rgb(var(--code-teal-rgb)/0.35);
}

/* ── Code-block header bar (prototype .pb-docs-code-head, docs.public.css:199-206)
 *
 * Was: an absolutely-positioned label at top:10px/left:16px over code with only
 * 16px of top padding — it overlapped the first line of code wherever it rendered.
 * Now it is a real bar in normal flow, so the code starts below it.
 *
 * The bar is emitted for EVERY block (the copy button lives in it), and its label
 * text comes from `data-lang` where the markup carries it — ApiEndpoint.cshtml
 * emits `<pre class="language-x" data-lang="x">`. Guide blocks do NOT: Markdig
 * puts `language-x` on the <code>, never on the <pre>, and emits no data-lang,
 * which is why the old `pre[class*="language-"]` selector never matched a single
 * guide block. The `:has(> code.language-*)` rules below close that gap in pure
 * CSS, so the label is correct with JS disabled; docs.js additionally mirrors the
 * <code> language onto the <pre> as data-lang so languages added to the content
 * tree in future are labelled without touching this file. */
.ev-docs-content pre::before {
  content: attr(data-lang);
  display: block;
  padding: 9px 16px;
  line-height: 21px;
  border-bottom: 1px solid rgb(var(--white-rgb)/0.08);
  font-family: "JetBrains Mono", monospace;
  font-size: var(--fs-nano);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--neutral-500);
}

/* No-JS language labels for the fence languages used in the guides. */
.ev-docs-content pre:has(> code.language-bash)::before {
  content: "bash";
}

.ev-docs-content pre:has(> code.language-json)::before {
  content: "json";
}

.ev-docs-content pre:has(> code.language-csharp)::before {
  content: "csharp";
}

.ev-docs-content pre:has(> code.language-php)::before {
  content: "php";
}

.ev-docs-content pre:has(> code.language-python)::before {
  content: "python";
}

.ev-docs-content pre:has(> code.language-typescript)::before {
  content: "typescript";
}

/* ── Prism token palette — the prototype's dark values (docs.public.css:220-224)
 * mapped onto Prism's own token classes. No stock theme is imported (see top of
 * file), so these are the only token colours in play. */
.ev-docs-content .token.comment,
.ev-docs-content .token.prolog,
.ev-docs-content .token.doctype,
.ev-docs-content .token.cdata {
  color: var(--neutral-500);
}

.ev-docs-content .token.punctuation {
  color: rgb(var(--white-rgb)/0.45);
}

.ev-docs-content .token.property,
.ev-docs-content .token.tag,
.ev-docs-content .token.constant,
.ev-docs-content .token.symbol,
.ev-docs-content .token.attr-name,
.ev-docs-content .token.builtin {
  color: var(--accent);
}

.ev-docs-content .token.boolean,
.ev-docs-content .token.number,
.ev-docs-content .token.function,
.ev-docs-content .token.class-name {
  color: var(--code-blue);
}

.ev-docs-content .token.string,
.ev-docs-content .token.char,
.ev-docs-content .token.attr-value,
.ev-docs-content .token.regex,
.ev-docs-content .token.inserted {
  color: var(--code-green);
}

.ev-docs-content .token.keyword,
.ev-docs-content .token.atrule,
.ev-docs-content .token.rule,
.ev-docs-content .token.important {
  color: var(--code-purple);
}

.ev-docs-content .token.deleted {
  color: var(--code-red);
}

/* Prism's stock theme puts a translucent white block behind operators/urls —
   explicitly neutralised so nothing paints a light box on the dark surface. */
.ev-docs-content .token.operator,
.ev-docs-content .token.entity,
.ev-docs-content .token.url,
.ev-docs-content .token.variable {
  color: rgb(var(--white-rgb)/0.82);
  background: none;
  text-shadow: none;
}

/* ── Prev / Next — borderless, text-only ───────────────────────── */
.ev-docs-prev-next {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  margin-top: 48px;
  padding-top: 22px;
  border-top: 1px solid var(--neutral-200);
}

.ev-docs-prev-next-inner {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  width: 100%;
}

.ev-docs-prev-link,
.ev-docs-next-link {
  display: flex;
  flex-direction: column;
  gap: 5px;
  text-decoration: none;
  max-width: 48%;
}

.ev-docs-next-link {
  text-align: right;
  align-items: flex-end;
  margin-left: auto;
}

.ev-docs-prev-next-dir {
  display: flex;
  align-items: center;
  gap: 5px;
  font-family: "JetBrains Mono", monospace;
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--neutral-400);
}

.ev-docs-next-link .ev-docs-prev-next-dir {
  justify-content: flex-end;
}

.ev-docs-prev-next-dir svg {
  width: 13px;
  height: 13px;
}

.ev-docs-prev-next-label {
  font-size: var(--fs-14);
  font-weight: 500;
  color: var(--neutral-900);
}

.ev-docs-prev-link:hover .ev-docs-prev-next-label,
.ev-docs-next-link:hover .ev-docs-prev-next-label {
  text-decoration: underline;
  text-decoration-color: var(--accent);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}

/* ── RIGHT: on-this-page rail ──────────────────────────────────── */
.ev-docs-toc {
  grid-area: toc;
  position: sticky;
  top: 64px;
  max-height: calc(100vh - 64px);
  overflow-y: auto;
  padding-top: 28px;
  scrollbar-width: thin;
  scrollbar-color: var(--neutral-200) transparent;
}

.ev-docs-toc-inner {
  padding-left: 16px;
  border-left: 1px solid var(--neutral-200);
}

.ev-docs-toc-heading {
  font-family: "JetBrains Mono", monospace;
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--neutral-500);
  margin: 0 0 12px;
}

.ev-docs-toc-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.ev-docs-toc-item {
  margin-bottom: 3px;
}

.ev-docs-toc-level-3 {
  padding-left: 14px;
}

.ev-docs-toc-link {
  display: block;
  font-size: var(--fs-body);
  line-height: 1.4;
  color: var(--neutral-500);
  text-decoration: none;
  padding: 3px 0;
  transition: color 0.12s;
}

.ev-docs-toc-link:hover {
  color: var(--neutral-900);
}

.ev-docs-toc-link.active {
  color: var(--neutral-900);
  font-weight: 500;
}

/* ── Mobile-only "On this page" — inline ToC atop the article ───── */
.ev-docs-inthis {
  display: none;
} /* shown only ≤760px */
.ev-docs-inthis summary {
  list-style: none;
  cursor: pointer;
  padding: 11px 14px;
  font-family: "JetBrains Mono", monospace;
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--neutral-500);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.ev-docs-inthis summary::-webkit-details-marker {
  display: none;
}

.ev-docs-inthis summary::after {
  content: "";
  width: 7px;
  height: 7px;
  border-right: 2px solid var(--neutral-400);
  border-bottom: 2px solid var(--neutral-400);
  transform: rotate(45deg);
  transition: transform 0.15s;
}

.ev-docs-inthis[open] summary::after {
  transform: rotate(-135deg);
}

/* Scoped under .ev-docs-content on purpose. The accordion is spliced INTO the article
   body (see _DocsLayout), which puts it inside .ev-docs-content — where the prose rules
   `.ev-docs-content ul` / `.ev-docs-content li` (0,1,1) and the content-link rule
   `.ev-docs-content a:not(…)` (0,2,0) all out-specify a bare `.ev-docs-inthis-*` class
   (0,1,0). Unscoped, the ToC would inherit 22px list padding, 6px item margins and
   bold-black-with-accent-underline links. The prototype scopes the same rules under
   .pb-docs-body for exactly this reason (docs.public.css:403-408). */
.ev-docs-content .ev-docs-inthis-list {
  list-style: none;
  margin: 0;
  padding: 0 14px 12px;
}

.ev-docs-content .ev-docs-inthis-item {
  margin: 0;
}

.ev-docs-content .ev-docs-inthis-item.ev-docs-toc-level-3 a {
  padding-left: 14px;
}

.ev-docs-content .ev-docs-inthis-link {
  display: block;
  padding: 6px 0;
  font-size: var(--fs-14);
  font-weight: 400;
  color: var(--neutral-600);
  text-decoration: none;
}

.ev-docs-content .ev-docs-inthis-link:hover {
  color: var(--neutral-900);
}

.ev-docs-content .ev-docs-inthis-link.active {
  color: var(--neutral-900);
  font-weight: 500;
}

/* Backdrop (overlay sidebar) — shown only when the rail is a slide-in panel. */
.ev-docs-backdrop {
  display: none;
}

/* ═══ API reference — spec-driven component styles (for issue 03) ═══════════
 * Rendered from openapi.yaml into OUR components (no embedded viewer): method +
 * status badges from the semantic status tokens; schema/param tables reuse the
 * docs table language; examples use the dark code blocks above. */
/* Endpoint header — METHOD badge + monospace path */
.ev-docs-api-endpoint {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin: 0 0 var(--sp-3);
}

.ev-docs-api-method {
  font: 600 var(--fs-fine) "JetBrains Mono", monospace;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 4px 9px;
  border-radius: var(--radius);
  flex-shrink: 0;
}

.ev-docs-api-method--get {
  background: var(--info-bg);
  color: var(--info-fg);
  border: 1px solid var(--info-border);
}

.ev-docs-api-method--post {
  background: var(--ok-bg);
  color: var(--ok-fg);
  border: 1px solid var(--ok-border);
}

.ev-docs-api-method--put,
.ev-docs-api-method--patch {
  background: var(--warn-bg);
  color: var(--warn-fg);
  border: 1px solid var(--warn-border);
}

.ev-docs-api-method--delete {
  background: var(--bad-bg);
  color: var(--bad-fg);
  border: 1px solid var(--bad-border);
}

.ev-docs-api-path {
  font: 500 var(--fs-16) "JetBrains Mono", monospace;
  color: var(--neutral-900);
  word-break: break-all;
}

.ev-docs-api-path .var {
  color: var(--neutral-500);
}

/* Endpoint header — title (left) + download-spec ghost button (right) */
.ev-docs-api-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-4) var(--sp-5);
  flex-wrap: wrap;
  margin-bottom: var(--sp-3);
}

.ev-docs-api-head h1 {
  margin: 0;
}

.ev-docs-api-download {
  flex-shrink: 0;
}

.ev-docs-api-download svg {
  width: 15px;
  height: 15px;
}

/* Endpoint meta pills */
.ev-docs-api-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin: var(--sp-4) 0 var(--sp-2);
}

.ev-docs-api-pill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font: 500 var(--fs-sub) "Geist", system-ui, sans-serif;
  color: var(--neutral-600);
  background: var(--neutral-50);
  border: 1px solid var(--neutral-200);
  border-radius: var(--radius);
  padding: 5px 10px;
}

.ev-docs-api-pill svg {
  width: 13px;
  height: 13px;
  color: var(--neutral-500);
}

.ev-docs-api-pill code {
  font: 500 var(--fs-caption) "JetBrains Mono", monospace;
  color: var(--neutral-800);
  background: none;
  border: none;
  padding: 0;
}

/* Section heading inside an endpoint (Request body / Responses / …).
   Scoped under .ev-docs-content so its margin beats .ev-docs-content p (these are <p>). */
.ev-docs-content .ev-docs-api-h {
  font: 600 var(--fs-sub) "JetBrains Mono", monospace;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--neutral-500);
  margin: var(--sp-7) 0 var(--sp-4);
  padding-bottom: var(--sp-2);
  border-bottom: 1px solid var(--neutral-200);
}

.ev-docs-api-h-sub {
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
  color: var(--neutral-400);
}

/* Schema / parameter table */
.ev-docs-api-params {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 var(--sp-2);
  border: 1px solid var(--neutral-200);
  border-radius: var(--radius);
  overflow: hidden;
  table-layout: fixed;
}

/* Override the guide-page table cap (.ev-docs-content table { max-width:760px }). */
.ev-docs-content .ev-docs-api-params {
  max-width: none;
}

.ev-docs-api-params col.c-field {
  width: 24%;
}

.ev-docs-api-params col.c-type {
  width: 20%;
}

.ev-docs-api-params thead th {
  text-align: left;
  padding: 10px 16px;
  background: var(--neutral-50);
  border-bottom: 1px solid var(--neutral-200);
  font: 600 var(--fs-nano) "JetBrains Mono", monospace;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--neutral-500);
}

.ev-docs-api-params td {
  padding: 12px 16px;
  border-top: 1px solid var(--neutral-100);
  vertical-align: top;
}

.ev-docs-api-params tbody tr:first-child td {
  border-top: none;
}

.ev-docs-api-field {
  font: 500 var(--fs-body) "JetBrains Mono", monospace;
  color: var(--neutral-900);
  word-break: break-word;
}

.ev-docs-api-req {
  font: 600 var(--fs-9) "JetBrains Mono", monospace;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--bad-fg);
  margin-left: 6px;
}

.ev-docs-api-type {
  font: 400 var(--fs-meta) "JetBrains Mono", monospace;
  color: var(--neutral-600);
  word-break: break-word;
}

.ev-docs-api-constraint {
  display: block;
  font: 400 var(--fs-caption) "JetBrains Mono", monospace;
  color: var(--neutral-400);
  margin-top: 5px;
}

.ev-docs-api-desc {
  font-size: var(--fs-heading);
  color: var(--neutral-600);
  line-height: 1.6;
}

.ev-docs-api-desc code {
  font: 500 var(--fs-caption) "JetBrains Mono", monospace;
  background: var(--neutral-100);
  border: 1px solid var(--neutral-200);
  border-radius: var(--radius);
  padding: 0.1em 0.35em;
  color: var(--neutral-800);
  white-space: nowrap;
}

.ev-docs-api-enum {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 8px;
}

.ev-docs-api-enum code {
  font: 500 var(--fs-caption) "JetBrains Mono", monospace;
  background: var(--neutral-100);
  border: 1px solid var(--neutral-200);
  border-radius: var(--radius);
  padding: 1px 6px;
  color: var(--neutral-700);
}

/* A schema's own description, above its field table */
.ev-docs-content .ev-docs-api-schema-desc {
  font-size: var(--fs-heading);
  color: var(--neutral-600);
  line-height: 1.6;
  margin: 0 0 var(--sp-3);
}

/* Nested object schema — its own full-width sub-table */
.ev-docs-content .ev-docs-api-subh {
  font: 500 var(--fs-sub) "JetBrains Mono", monospace;
  color: var(--neutral-600);
  margin: var(--sp-6) 0 var(--sp-2);
}

.ev-docs-api-subh .obj {
  color: var(--neutral-400);
}

/* Response codes — aligned code column + description */
.ev-docs-api-resp {
  border: 1px solid var(--neutral-200);
  border-radius: var(--radius);
  overflow: hidden;
}

.ev-docs-api-resp-row {
  display: flex;
  gap: var(--sp-4);
  padding: 12px 16px;
  border-top: 1px solid var(--neutral-100);
}

.ev-docs-api-resp-row:first-child {
  border-top: none;
}

.ev-docs-api-code {
  font: 600 var(--fs-sub) "JetBrains Mono", monospace;
  padding: 3px 0;
  border-radius: var(--radius);
  flex-shrink: 0;
  height: fit-content;
  width: 52px;
  text-align: center;
}

.ev-docs-api-code--ok {
  background: var(--ok-bg);
  color: var(--ok-fg);
  border: 1px solid var(--ok-border);
}

.ev-docs-api-code--info {
  background: var(--info-bg);
  color: var(--info-fg);
  border: 1px solid var(--info-border);
}

.ev-docs-api-code--warn {
  background: var(--warn-bg);
  color: var(--warn-fg);
  border: 1px solid var(--warn-border);
}

.ev-docs-api-code--bad {
  background: var(--bad-bg);
  color: var(--bad-fg);
  border: 1px solid var(--bad-border);
}

.ev-docs-api-resp-desc {
  font-size: var(--fs-heading);
  color: var(--neutral-600);
  line-height: 1.55;
  padding-top: 3px;
}

.ev-docs-api-resp-desc code {
  font: 500 var(--fs-caption) "JetBrains Mono", monospace;
  background: var(--neutral-100);
  border: 1px solid var(--neutral-200);
  border-radius: var(--radius);
  padding: 0.1em 0.35em;
  color: var(--neutral-800);
  white-space: nowrap;
}

.ev-docs-api-resp-desc > :last-child {
  margin-bottom: 0;
}

/* Error-shape heading — the status codes sharing one documented error body. Layout only: it
   keeps .ev-docs-api-subh's typography and reuses the .ev-docs-api-code badge from the Responses
   list, which needs an inline-block box here because it is not a flex child of a resp-row. */
.ev-docs-content .ev-docs-api-errh {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}

.ev-docs-api-errh .ev-docs-api-code {
  display: inline-block;
  width: auto;
  padding: 3px 7px;
}

/* Scalar (non-object) response payload — enum chips / wire-format block under its response row */
.ev-docs-api-scalar {
  margin-top: 8px;
}

.ev-docs-api-scalar > :last-child {
  margin-bottom: 0;
}

.ev-docs-api-scalar p {
  font-size: var(--fs-heading);
  color: var(--neutral-600);
  line-height: 1.55;
  margin: 8px 0 0;
}

.ev-docs-api-scalar pre {
  margin: 8px 0 0;
}

/* ══ Tablet-and-below (≤1200): left rail → slide-in overlay; ToC stays a right rail ══ */
@media (max-width: 1200px) {
  .ev-docs-grid {
    grid-template-columns: minmax(0, 1fr) 232px;
    grid-template-areas: "article toc";
  }
  .ev-docs-menu-btn {
    display: inline-flex;
  }
  .ev-docs-sidebar {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 60;
    width: min(320px, 86vw);
    height: 100dvh;
    background: var(--white);
    border-right: 1px solid var(--neutral-200);
    box-shadow: var(--shadow-lg);
    padding: 0;
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: var(--neutral-300) transparent;
    transform: translateX(-100%);
    transition: transform 0.22s cubic-bezier(0.2, 0.7, 0.3, 1);
  }
  .ev-docs-sidebar.open {
    transform: none;
  }
  .ev-docs-sidebar-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--white);
    padding: 15px 16px;
    border-bottom: 1px solid var(--neutral-200);
    font: 600 var(--fs-body) "Geist", system-ui, sans-serif;
    color: var(--neutral-900);
  }
  .ev-docs-sidebar-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    background: none;
    border: none;
    cursor: pointer;
    color: var(--neutral-500);
    border-radius: var(--radius);
  }
  .ev-docs-sidebar-close:hover {
    background: var(--neutral-100);
    color: var(--neutral-900);
  }
  .ev-docs-sidebar-close svg {
    width: 18px;
    height: 18px;
  }
  .ev-docs-sidebar .ev-docs-search {
    margin: 16px 16px 20px;
  }
  .ev-docs-sidebar .ev-docs-nav-tree {
    padding-bottom: 24px;
  }
  .ev-docs-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 55;
    background: rgb(var(--black-rgb)/0.4);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s;
  }
  .ev-docs-backdrop.open {
    opacity: 1;
    pointer-events: auto;
  }
}
/* ══ Phone (≤800): single column; ToC → "On this page" atop the article ══ */
@media (max-width: 800px) {
  .ev-docs-shell {
    padding: 0 20px 64px;
  }
  .ev-docs-grid {
    grid-template-columns: 1fr;
    grid-template-areas: "article";
  }
  .ev-docs-toc {
    display: none;
  }
  .ev-docs-inthis {
    display: block;
    margin: 2px 0 26px;
    border: 1px solid var(--neutral-200);
    border-radius: var(--radius);
    background: var(--neutral-50);
  }
  .ev-docs-article {
    padding-top: 14px;
  }
  .ev-docs-prev-next-inner {
    flex-direction: column;
  }
  .ev-docs-prev-link,
  .ev-docs-next-link {
    max-width: 100%;
  }
  .ev-docs-next-link {
    text-align: left;
    align-items: flex-start;
    margin-left: 0;
  }
  .ev-docs-next-link .ev-docs-prev-next-dir {
    justify-content: flex-start;
  }
  /* API-ref: head stacks; schema tables collapse to blocks */
  .ev-docs-api-head {
    flex-direction: column;
  }
  .ev-docs-api-head .ev-docs-api-download {
    align-self: flex-start;
  }
  .ev-docs-api-params {
    table-layout: auto;
  }
  .ev-docs-api-params thead {
    display: none;
  }
  .ev-docs-api-params, .ev-docs-api-params tbody, .ev-docs-api-params tr, .ev-docs-api-params td {
    display: block;
    width: auto;
  }
  .ev-docs-api-params tbody tr {
    border-top: 1px solid var(--neutral-100);
    padding: 10px 4px;
  }
  .ev-docs-api-params tbody tr:first-child {
    border-top: none;
  }
  .ev-docs-api-params td {
    border-top: none;
    padding: 2px 12px;
  }
  .ev-docs-api-params td:first-child {
    padding-top: 0;
  }
  /* Column labels — OWNER DECISION, overruling the original design.
   * The prototype hid thead and stacked the cells with no labels, which left a phone
   * reader with three bare values (a name, a type, some prose) and nothing saying which
   * column each came from. The owner ruled that the labels are worth the ink here; the
   * prototype (docs.public.css) has been updated to match, so the two stay in sync.
   *
   * Styled as a quiet caption, not a heading: the same 9.5px mono/uppercase/neutral
   * treatment as .ev-docs-nav-category-label, so it reads as structure and never competes
   * with the value beneath it. Painted from the attribute, so there is no duplicate
   * markup to keep in step and the desktop table is untouched. */
  .ev-docs-api-params td::before {
    content: attr(data-label);
    display: block;
    margin-bottom: 3px;
    font-family: "JetBrains Mono", monospace;
    font-size: var(--fs-9-5);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--neutral-400);
  }
  /* A cell with no label (a future column, a spacer) must not paint an empty caption box. */
  .ev-docs-api-params td:not([data-label])::before {
    content: none;
  }
}
/* ═══════════════════════════════════════════════════════════════════════════
   API REFERENCE — RESTORED SPEC CONTENT
   Appended block. Everything here supports content that the server-rendered
   reference now surfaces and previously dropped; it adds no new visual language,
   only the layout the restored markup needs.
   ═══════════════════════════════════════════════════════════════════════════ */
/* Descriptions may carry AUTHORED block structure (a markdown list, several
   paragraphs, a fenced block). DocMarkdown.Inline used to flatten all of it into
   one run-on line, so a description inside a table cell was always a bare text
   node. VerifyStatus and VerifySubStatus — the two most important enums on the
   API — are authored as lists, so cells must lay one out properly. */
.ev-docs-content .ev-docs-api-desc p,
.ev-docs-content .ev-docs-api-schema-desc p,
.ev-docs-content .ev-docs-api-resp-desc p {
  margin: 0 0 var(--sp-2);
}

.ev-docs-content .ev-docs-api-desc p:last-child,
.ev-docs-content .ev-docs-api-schema-desc p:last-child,
.ev-docs-content .ev-docs-api-resp-desc p:last-child {
  margin-bottom: 0;
}

.ev-docs-content .ev-docs-api-desc ul,
.ev-docs-content .ev-docs-api-desc ol,
.ev-docs-content .ev-docs-api-schema-desc ul,
.ev-docs-content .ev-docs-api-schema-desc ol,
.ev-docs-content .ev-docs-api-resp-desc ul,
.ev-docs-content .ev-docs-api-resp-desc ol {
  margin: var(--sp-2) 0 0;
  padding-left: 18px;
}

.ev-docs-content .ev-docs-api-desc li,
.ev-docs-content .ev-docs-api-schema-desc li,
.ev-docs-content .ev-docs-api-resp-desc li {
  margin: 0 0 4px;
  line-height: 1.55;
}

.ev-docs-content .ev-docs-api-desc li:last-child,
.ev-docs-content .ev-docs-api-schema-desc li:last-child,
.ev-docs-content .ev-docs-api-resp-desc li:last-child {
  margin-bottom: 0;
}

/* .ev-docs-api-schema-desc became a <div> so an authored list is not nested inside a
   <p>; it keeps the type it had as a paragraph. */
.ev-docs-content div.ev-docs-api-schema-desc {
  font-size: var(--fs-heading);
  color: var(--neutral-600);
  line-height: 1.6;
  margin: 0 0 var(--sp-3);
}

/* The media type a response answers with (text/plain, text/event-stream,
   application/json). Selected by the projection and then discarded, so a reader
   could not tell an SSE stream from JSON. Muted, on its own line under the text. */
.ev-docs-api-media {
  display: block;
  margin-top: 4px;
  font-family: "JetBrains Mono", monospace;
  font-size: var(--fs-caption);
}
