/* Sahi developer docs.
 *
 * The SAHI design system (design.sahi.com), reduced to what a reference site
 * needs — the same reduction apps/devconsole/ui/src/styles.css makes, with the
 * same tokens, so the console and the docs read as one property.
 *
 * That system is monochrome: black, white, and one purple that is only ever a
 * stroke or a tint, never a fill. Hairline borders do the work shadows would do
 * elsewhere. One 16px radius on containers; controls are full pills.
 *
 * design.sahi.com sets the two families' jobs: SAHI Season is the display face
 * for "headlines and hero experiences", SAHI Sans covers "navigation, body copy,
 * forms, data and buttons where information needs to be understood quickly". A
 * reference is almost entirely the latter, so Season appears only on page
 * titles and the lockup.
 *
 * No runtime JavaScript. Disclosure widgets are <details>, forced open at
 * desktop widths by CSS.
 */

/* ── Faces ────────────────────────────────────────────────────────────────
 * Served same-origin; the build rewrites these URLs to content-hashed names so
 * /assets/* can be cached immutably. Subsets: full ASCII plus the punctuation
 * the brand site needed. U+2026 is NOT among them — the build fails on a page
 * that uses a glyph the face lacks, because the alternative is a silent
 * fallback to the system font mid-word.
 */

@font-face {
  font-family: 'SAHI Sans';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('/assets/brand/sahi-sans-300.060f570c84.woff') format('woff');
}
@font-face {
  font-family: 'SAHI Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/brand/sahi-sans-400.918a393347.woff') format('woff');
}
@font-face {
  font-family: 'SAHI Sans';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/assets/brand/sahi-sans-500.bf40f0c467.woff') format('woff');
}
@font-face {
  font-family: 'SAHI Sans';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/assets/brand/sahi-sans-600.a78f463d51.woff') format('woff');
}
@font-face {
  font-family: 'SAHI Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/assets/brand/sahi-sans-700.71d464a6d8.woff') format('woff');
}
/* The variable face, as the brand site loads it: a real 300-900 axis, so no
   weight here is synthesised. */
@font-face {
  font-family: 'SAHI Season';
  font-style: normal;
  font-weight: 300 900;
  font-display: swap;
  src: url('/assets/brand/sahi-season-vf.fdef18fdda.woff2') format('woff2');
}

/* ── Tokens ───────────────────────────────────────────────────────────── */

:root {
  /* Ink ramp and the hairline that separates almost everything. */
  --ink: #0f0f0f;
  --ink-soft: #535353;
  --ink-mute: #727272;
  --line: rgba(15, 15, 15, 0.12);
  --line-soft: #f5f5f5;
  --paper: #ffffff;

  /* Capital Purple. Strokes and tints only. */
  --accent: #66033c;
  --accent-ring: rgba(102, 3, 60, 0.16);
  --accent-tint: rgba(102, 3, 60, 0.06);

  /* Status colours, as the console defines them: the brand system has no
     vocabulary for "this verb destroys data", and inventing one from the purple
     would read as decoration. Desaturated so they sit quietly. */
  --good: #0e8a4f;
  --danger: #c4342e;

  /* The sample panel. Grey rather than ink: a black slab beside white prose is
     a hard edge to read a long JSON body against, and the panel does not need
     darkness to read as a panel — its label strip and hairline do that. Still
     monochrome, so the brand position holds. */
  --slab: #f6f6f7;
  --slab-head: #eeeef0;
  --slab-ink: #24292f;
  --slab-mute: var(--ink-mute);

  --font-sans: 'SAHI Sans', system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif;
  --font-display: 'SAHI Season', 'Times New Roman', Georgia, serif;
  --font-mono: ui-monospace, 'SF Mono', SFMono-Regular, 'JetBrains Mono', Menlo, Consolas, monospace;

  --radius: 16px;

  --shell-max: 1600px;
  --gutter: clamp(16px, 4vw, 56px);
  --sidebar: 17.5rem;
  --samples: 26rem;
  --toc-rail: 15rem;
  --header-h: 72px;

  /* Prose caps its own measure. The shell is wide because the reference needs
     two columns; a 900px paragraph is worse than a 600px one. */
  --measure: 46rem;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 1.5rem);
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  text-wrap: pretty;
}

img,
svg {
  display: block;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
  text-decoration-color: var(--line);
  transition: text-decoration-color 0.15s ease;
}

a:hover {
  text-decoration-color: var(--accent);
}

.skip-link {
  position: absolute;
  left: -9999px;
  padding: 0.7rem 1.1rem;
  background: var(--ink);
  color: var(--paper);
  border-radius: 999px;
  z-index: 100;
  text-decoration: none;
}

.skip-link:focus {
  left: var(--gutter);
  top: 0.6rem;
}

/* ── Header ───────────────────────────────────────────────────────────── */

.topbar {
  position: sticky;
  top: 0;
  z-index: 30;
  background: rgba(255, 255, 255, 0.85);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}

.topbar-inner {
  max-width: var(--shell-max);
  margin: 0 auto;
  padding: 0 var(--gutter);
  height: var(--header-h);
  display: flex;
  align-items: center;
  gap: 1rem;
}

/* The lockup as design.sahi.com builds it: the Stride, then the property name
   alone in display caps. The word SAHI is not in it — the mark says SAHI, and
   repeating it in type would say it twice. DESIGN there, DEVELOPERS on the
   console, DOCS here. */
.lockup {
  display: flex;
  align-items: center;
  gap: 13px;
  flex: none;
  text-decoration: none;
}

.lockup img {
  height: 24px;
  flex: none;
}

.lockup span {
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1;
}

.topbar nav {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 14px;
}

/* Position is marked with a filled pill rather than an underline, the way the
   brand nav does it — it leaves the row's baseline alone. */
.topbar nav a {
  border-radius: 999px;
  padding: 9px 18px;
  color: var(--ink-mute);
  text-decoration: none;
  transition: background 0.15s ease, color 0.15s ease;
}

.topbar nav a:hover {
  background: var(--line-soft);
  color: var(--ink);
}

.topbar nav a[aria-current='page'] {
  background: var(--line-soft);
  color: var(--ink);
}

.env-badge {
  flex: none;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 3px 9px;
  border-radius: 999px;
  border: 1px solid var(--accent);
  color: var(--accent);
  background: var(--accent-tint);
}

/* ── Shell layout ─────────────────────────────────────────────────────── */

.layout {
  max-width: var(--shell-max);
  margin: 0 auto;
  padding: 0 var(--gutter);
  display: grid;
  grid-template-columns: var(--sidebar) minmax(0, 1fr);
  grid-template-areas: 'sidebar content';
  gap: 0 3.5rem;
  align-items: start;
}

/* Prose pages get a third column for their on-this-page rail. Reference pages
   do not: the sidebar already lists their endpoints, and their right-hand space
   belongs to the samples. */
.layout.has-toc {
  grid-template-columns: var(--sidebar) minmax(0, 1fr) var(--toc-rail);
  grid-template-areas: 'sidebar content toc';
}

.toc-rail {
  grid-area: toc;
  position: sticky;
  top: var(--header-h);
  max-height: calc(100vh - var(--header-h));
  overflow-y: auto;
  padding: 2.5rem 0 3rem;
}

.sidebar {
  grid-area: sidebar;
  position: sticky;
  top: var(--header-h);
  max-height: calc(100vh - var(--header-h));
  overflow-y: auto;
  padding: 2rem 0 4rem;
  border-right: 1px solid var(--line);
  margin-right: -1.75rem;
}

.content {
  grid-area: content;
  min-width: 0;
  padding: 2.5rem 0 7rem;
  /* Keeps the site footer off the fold on a short page, where it would
     otherwise ride up under two cards' worth of content. */
  min-height: 70vh;
}

@media (max-width: 66rem) {
  .layout,
  .layout.has-toc {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      'sidebar'
      'toc'
      'content';
    gap: 0;
  }

  .toc-rail {
    position: static;
    max-height: none;
    overflow: visible;
    padding: 0 0 0.5rem;
    border-bottom: 1px solid var(--line);
  }

  .sidebar {
    position: static;
    max-height: 70vh;
    overflow-y: auto;
    border-right: none;
    border-bottom: 1px solid var(--line);
    margin-right: 0;
    padding: 0.5rem 0 1rem;
  }

  .content {
    padding: 1.75rem 0 4rem;
  }
}

/* ── Disclosure ───────────────────────────────────────────────────────── */
/* One markup shape at both widths: collapsible on a phone, a plain open block
   on a desktop. */

.disclosure > summary {
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-mute);
  cursor: pointer;
  padding: 0.85rem 0;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.disclosure > summary::-webkit-details-marker {
  display: none;
}

.disclosure > summary::after {
  content: '';
  width: 6px;
  height: 6px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translateY(-2px);
  transition: transform 0.15s ease;
}

.disclosure[open] > summary::after {
  transform: rotate(-135deg) translateY(-1px);
}

/* At desktop widths the disclosure is not a control, it is just a panel. Hiding
   the summary is not enough on its own — a <details> without [open] hides its
   content whatever you do to the summary — so the panel is forced open through
   ::details-content.

   The whole rule is guarded by @supports for a reason: without the guard, a
   browser that does not understand ::details-content would hide the summary and
   leave the navigation collapsed with nothing left to click. With it, such a
   browser simply keeps a working summary to open. The markup carries no [open]
   so that narrow screens start collapsed instead of burying the page under a
   screen and a half of navigation. */
@media (min-width: 66.0625rem) {
  @supports selector(::details-content) {
    .sidebar > .disclosure > summary,
    .toc-rail > .disclosure > summary {
      display: none;
    }

    .sidebar > .disclosure::details-content,
    .toc-rail > .disclosure::details-content {
      content-visibility: visible;
      block-size: auto;
    }
  }
}

/* ── Sidebar navigation ───────────────────────────────────────────────── */

.nav-group {
  margin-bottom: 1.75rem;
}

.nav-group-title {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin: 0 0 0.6rem 0.75rem;
}

.nav-group ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav-group a {
  display: block;
  padding: 0.4rem 0.75rem;
  border-radius: 999px;
  color: var(--ink-soft);
  font-size: 14.5px;
  line-height: 1.45;
  text-decoration: none;
  transition: background 0.15s ease, color 0.15s ease;
}

.nav-group a:hover {
  background: var(--line-soft);
  color: var(--ink);
}

.nav-group a[aria-current='page'] {
  background: var(--line-soft);
  color: var(--ink);
  font-weight: 500;
}

/* Endpoints under the page that documents them, named by what they do rather
   than by verb and path. Only the page being read lists its own, so there is no
   disclosure control and no count to label it with. */
.nav-endpoints {
  list-style: none;
  border-left: 1px solid var(--line);
  margin: 0.2rem 0 0.8rem 1.1rem;
  padding-left: 0.35rem;
}

.nav-endpoints li {
  margin: 0;
}

.nav-endpoints a {
  display: block;
  padding: 0.24rem 0.6rem;
  border-radius: 999px;
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--ink-mute);
  text-decoration: none;
}

.nav-endpoints a:hover {
  background: var(--line-soft);
  color: var(--ink);
}

/* ── On this page ─────────────────────────────────────────────────────── */

.toc-rail {
  font-size: 14px;
}

.toc-list {
  list-style: none;
  margin: 0;
  padding-left: 0.9rem;
  border-left: 1px solid var(--line);
}

.toc-list a {
  display: block;
  color: var(--ink-mute);
  padding: 0.16rem 0;
  text-decoration: none;
}

.toc-list a:hover {
  color: var(--ink);
}

.toc-h3 {
  padding-left: 0.9rem;
  font-size: 13px;
}

/* ── Content typography ───────────────────────────────────────────────── */

.content > * {
  max-width: var(--measure);
}

/* The display serif on the page title is what makes this read as SAHI rather
   than as generic developer furniture. */
.page-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(30px, 3.4vw, 40px);
  line-height: 1.12;
  letter-spacing: -0.015em;
  text-wrap: balance;
  margin: 0 0 0.6rem;
}

.page-eyebrow {
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-mute);
  margin: 0 0 0.55rem;
}

.page-lede {
  font-size: 17px;
  color: var(--ink-soft);
  text-wrap: balance;
  margin: 0 0 2.25rem;
}

.content h2 {
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.3;
  margin: 3.25rem 0 0.9rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
}

.content h3 {
  font-size: 17px;
  font-weight: 600;
  margin: 2.25rem 0 0.6rem;
}

.content h4 {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin: 1.75rem 0 0.5rem;
}

.content p {
  margin: 0.85rem 0;
}

.content ul,
.content ol {
  margin: 0.85rem 0;
  padding-left: 1.35rem;
}

.content li {
  margin: 0.3rem 0;
}

.content li::marker {
  color: var(--ink-mute);
}

.content hr {
  border: none;
  border-top: 1px solid var(--line);
  margin: 3rem 0;
}

.content blockquote {
  margin: 1.35rem 0;
  padding: 0.9rem 1.15rem;
  border: 1px solid var(--line);
  border-left: 2px solid var(--accent);
  border-radius: 0 var(--radius) var(--radius) 0;
  background: var(--accent-tint);
}

.content blockquote > :first-child {
  margin-top: 0;
}

.content blockquote > :last-child {
  margin-bottom: 0;
}

.heading-anchor {
  margin-left: 0.4rem;
  color: var(--ink-mute);
  font-weight: 400;
  text-decoration: none;
  opacity: 0;
  transition: opacity 0.12s ease;
}

h2:hover > .heading-anchor,
h3:hover > .heading-anchor,
h4:hover > .heading-anchor,
.endpoint-title:hover > .heading-anchor,
.heading-anchor:focus {
  opacity: 1;
}

/* ── Code ─────────────────────────────────────────────────────────────── */

code {
  font-family: var(--font-mono);
  font-size: 0.855em;
  background: var(--line-soft);
  border: 1px solid var(--line);
  border-radius: 5px;
  padding: 0.1em 0.34em;
  overflow-wrap: break-word;
}

a code {
  color: inherit;
}

/* Blocks in the prose column. The sample panel is distinguished by its label
   strip rather than by a different surface, so these can stay quiet. */
.content pre {
  background: var(--line-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1rem 1.15rem;
  overflow-x: auto;
  margin: 1.1rem 0;
  font-size: 13px;
  line-height: 1.6;
}

pre code {
  background: none;
  border: none;
  padding: 0;
  font-size: inherit;
  white-space: pre;
}

/* ── Endpoint blocks ──────────────────────────────────────────────────── */
/* Two columns: the contract on the left, its samples on the right, the samples
   sticky within their own row. Stripe's arrangement, reached without any
   scroll-syncing JavaScript — each endpoint owns its panel rather than one
   panel tracking the whole page. */

.endpoint {
  max-width: none;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, var(--samples));
  gap: 0 3rem;
  padding-top: 2rem;
  margin: 3.5rem 0 0;
  border-top: 1px solid var(--line);
}

.endpoint-body {
  min-width: 0;
  max-width: var(--measure);
}

.endpoint-body > *:first-child {
  margin-top: 0;
}

.endpoint-samples {
  min-width: 0;
  position: sticky;
  top: calc(var(--header-h) + 1.5rem);
  align-self: start;
}

@media (max-width: 82rem) {
  .endpoint {
    grid-template-columns: minmax(0, 1fr);
    gap: 1.5rem;
  }

  .endpoint-samples {
    position: static;
  }
}

.endpoint-title {
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0 0 0.75rem;
  padding: 0;
  border: none;
}

/* Method and path. The verb is a hairline pill — stroke and tint, never a
   fill, so it stays inside the brand's rule about colour. */
.endpoint-route {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin: 0 0 0.9rem;
  padding: 0.5rem 0.65rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--paper);
  width: fit-content;
  max-width: 100%;
}

.verb {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.07em;
  padding: 2px 9px;
  border-radius: 999px;
  border: 1px solid currentColor;
  flex: none;
}

.verb-get {
  color: var(--ink-soft);
}
.verb-post {
  color: var(--good);
}
.verb-put,
.verb-patch {
  color: var(--accent);
}
.verb-delete {
  color: var(--danger);
}
.verb-wss {
  color: var(--ink);
}

.endpoint-path {
  font-family: var(--font-mono);
  font-size: 13.5px;
  color: var(--ink);
  overflow-wrap: anywhere;
  padding-right: 0.4rem;
}

.endpoint-scope {
  font-size: 12.5px;
  color: var(--ink-mute);
  margin: 0 0 1.1rem;
}

.endpoint-scope code {
  font-size: 12px;
}

/* ── Attributes ───────────────────────────────────────────────────────── */
/* Parameter and field tables are rebuilt as a definition list. A four-column
   markdown table is unreadable at this width and reads as a document; this is
   the shape an API reference uses. */

.attributes {
  margin: 0.75rem 0 1.75rem;
  border-top: 1px solid var(--line);
}

.attribute {
  border-bottom: 1px solid var(--line);
  padding: 0.85rem 0;
}

.attribute-head {
  display: flex;
  align-items: baseline;
  gap: 0.55rem;
  flex-wrap: wrap;
}

.attribute-name {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
}

.attribute-type {
  font-size: 12px;
  color: var(--ink-mute);
  font-family: var(--font-mono);
}

.attribute-flag {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 1px 7px;
  border-radius: 999px;
  border: 1px solid currentColor;
}

.attribute-flag.is-required {
  color: var(--accent);
}

.attribute-flag.is-optional {
  color: var(--ink-mute);
}

.attribute-desc {
  margin: 0.35rem 0 0;
  font-size: 14.5px;
  color: var(--ink-soft);
}

.attribute-desc > :first-child {
  margin-top: 0;
}

.attribute-desc > :last-child {
  margin-bottom: 0;
}

/* ── Sample panel ─────────────────────────────────────────────────────── */

.sample {
  background: var(--slab);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  margin-bottom: 1rem;
}

.sample-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.55rem 1rem;
  background: var(--slab-head);
  border-bottom: 1px solid var(--line);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--slab-mute);
}

.sample-lang {
  font-family: var(--font-mono);
  letter-spacing: 0.04em;
  text-transform: none;
}

.sample pre {
  margin: 0;
  padding: 0.95rem 1rem 1.1rem;
  background: none;
  border: none;
  border-radius: 0;
  overflow-x: auto;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--slab-ink);
}

.sample pre code {
  color: inherit;
}

/* ── Tables ───────────────────────────────────────────────────────────── */
/* Kept for genuine tables — enum values, close codes, column layouts. Scrolls
   inside its own box so the page never scrolls sideways. */

.table-scroll {
  overflow-x: auto;
  margin: 1.15rem 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.table-scroll table {
  border-collapse: collapse;
  width: 100%;
  margin: 0;
  font-size: 14px;
}

.table-scroll th,
.table-scroll td {
  border-bottom: 1px solid var(--line);
  padding: 0.6rem 0.9rem;
  text-align: left;
  vertical-align: top;
}

.table-scroll tr:last-child td {
  border-bottom: none;
}

.table-scroll th {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-mute);
  background: var(--line-soft);
  white-space: nowrap;
}

.table-scroll code {
  white-space: nowrap;
  background: none;
  border: none;
  padding: 0;
}

/* ── Index cards ──────────────────────────────────────────────────────── */

.card-grid {
  max-width: none;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(19rem, 100%), 1fr));
  gap: 1rem;
  margin: 2rem 0;
  padding: 0;
  list-style: none;
}

.card {
  position: relative;
  margin: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.25rem 1.35rem;
  transition: border-color 0.15s ease, transform 0.15s ease;
}

.card:hover {
  border-color: var(--ink);
  transform: translateY(-2px);
}

/* The whole box is the target, not just the heading. The heading's link stretches
   over the card with a pseudo-element rather than the card being wrapped in one
   big <a>: this way the link's accessible name stays the heading text, instead of
   the kicker, the summary and every route chip being read out as a single label.
   The card is the containing block, so `inset: 0` covers exactly it.
   Each card holds one link, so there is nothing for the overlay to swallow. */
.card h2 a::after,
.card h3 a::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: var(--radius);
}

/* Keyboard focus lands on the heading link, which sits inside the box; without
   this the only feedback is a ring around a few words of a card that is entirely
   clickable. Nothing is suppressed — the link keeps its own focus ring too. */
.card:focus-within {
  border-color: var(--ink);
}

.card-kicker {
  display: block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin-bottom: 0.4rem;
}

.card h2,
.card h3 {
  margin: 0 0 0.35rem;
  padding: 0;
  border: none;
  font-size: 17px;
  font-weight: 600;
}

.card h2 a,
.card h3 a {
  text-decoration: none;
}

.card p {
  margin: 0;
  color: var(--ink-soft);
  font-size: 14.5px;
}

.card-routes {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  margin: 0.7rem 0 0;
  padding: 0;
  list-style: none;
}

.card-routes li {
  margin: 0;
  font-size: 12px;
  color: var(--ink-soft);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 2px 9px;
}

/* ── Footer ───────────────────────────────────────────────────────────── */

.page-footer {
  margin-top: 4.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
  font-size: 13.5px;
  color: var(--ink-mute);
}

.page-footer a {
  color: var(--ink-soft);
}

.site-footer {
  border-top: 1px solid var(--line);
  margin-top: 2rem;
}

.site-footer-inner {
  max-width: var(--shell-max);
  margin: 0 auto;
  padding: 2rem var(--gutter);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  font-size: 13px;
  color: var(--ink-mute);
}

/* ── SDK method blocks ────────────────────────────────────────────────── */
/* The same block as an endpoint: the chip names what the call is, the path
   slot holds the short call, and the full signature sits beneath as a slab. */

.verb-method,
.verb-function {
  color: var(--accent);
}
.verb-property {
  color: var(--ink-soft);
}
.verb-class {
  color: var(--ink);
}

/* `.content pre` sets the prose-column block and `pre code` pins
   `white-space: pre`; both are overridden here so a long signature wraps
   inside the column instead of scrolling. */
.content .endpoint-signature {
  margin: 0 0 0.9rem;
  padding: 0.7rem 0.9rem;
  background: var(--slab);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--slab-ink);
  overflow-x: visible;
}

.content .endpoint-signature code {
  color: inherit;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
