/*
 * UnifiWallet Payments — visual system.
 *
 * The direction is a technical drawing, not a crypto site. Everything about
 * this product's pitch is "you can verify this yourself": an immutable contract
 * with no admin key, funds that never enter our custody, a settlement you can
 * check on a block explorer. A blueprint reads as auditable. A dark page with a
 * neon accent reads as every other gateway in this market.
 *
 * One rule carries meaning throughout, and it is worth knowing before reading
 * any of the diagrams:
 *
 *     SOLID lines are money.
 *     DASHED lines are us.
 *
 * We build the transaction; we are never in the path of the funds. The diagrams
 * say that structurally rather than asserting it in a caption.
 */

:root {
  /* Blueprint ground: cool, faintly green, never cream. */
  --paper: #eff3f2;
  --card: #fbfcfc;
  --ink: #08191b;
  --ink-soft: #40595c;
  --ink-faint: #7d9497;

  /* Brand. Structure, links, and everything the gateway itself does. */
  --petrol: #0d5a61;
  --petrol-lift: #12787f;
  --petrol-wash: #dfeae9;

  /*
   * Reserved for one idea only: this cannot be undone.
   * Irreversible transfers, refused settlements, revocation. Using it anywhere
   * else would spend the one colour that makes a reader stop.
   */
  --alert: #9e2b25;
  --alert-wash: #f6e7e6;

  --rule: #ccd8d7;
  --rule-strong: #a8bcbb;

  /* Text that sits on a filled brand surface, and on the pale wash. */
  --on-accent: #ffffff;
  --on-wash: #0a3f44;

  /* Syntax highlighting, and the method colours that reuse it. */
  --tok-string: #0a5f52;
  --tok-number: #8a4b12;

  /* An outstanding decision, or a caveat worth stopping at. */
  --warn: #8a5512;
  --warn-bg: #faf0df;

  --display: 'Space Grotesk', 'IBM Plex Sans', system-ui, sans-serif;
  --body: 'IBM Plex Sans', system-ui, -apple-system, sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  --measure: 68ch;
  --shell: 1180px;
  --gutter: clamp(1.25rem, 4vw, 3rem);

  --step: 0.5rem;
  --radius: 3px;
}


/* ------------------------------------------------------------------ dark
 *
 * The same blueprint after dark rather than an inversion: the ground keeps its
 * green bias, petrol lifts enough to stay legible on it, and the alert red
 * stays the one colour that makes a reader stop.
 *
 * Declared in three places on purpose. The bare :root above is the complete
 * light palette; the media query serves the reader who has chosen nothing and
 * whose system is dark; the attribute serves the reader who pressed the button.
 * The `:not([data-theme="light"])` guard is what lets an explicit light choice
 * win on a dark system.
 */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper: #0d1416;
    --card: #141e20;
    --ink: #e6eeed;
    --ink-soft: #a3b6b6;
    --ink-faint: #7b9092;

    --petrol: #58bcc4;
    --petrol-lift: #7ad3da;
    --petrol-wash: #12282b;

    --alert: #ee8f89;
    --alert-wash: #2e1a19;

    --rule: #24322f;
    --rule-strong: #3a4e4e;

    --on-accent: #06181a;
    --on-wash: #b6d8d6;

    --tok-string: #64c9a9;
    --tok-number: #e0a866;

    --warn: #d9a552;
    --warn-bg: #2a2216;
  }
}

:root[data-theme="dark"] {
  --paper: #0d1416;
  --card: #141e20;
  --ink: #e6eeed;
  --ink-soft: #a3b6b6;
  --ink-faint: #7b9092;

  --petrol: #58bcc4;
  --petrol-lift: #7ad3da;
  --petrol-wash: #12282b;

  --alert: #ee8f89;
  --alert-wash: #2e1a19;

  --rule: #24322f;
  --rule-strong: #3a4e4e;

  --on-accent: #06181a;
  --on-wash: #b6d8d6;

  --tok-string: #64c9a9;
  --tok-number: #e0a866;

  --warn: #d9a552;
  --warn-bg: #2a2216;
}

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: 80px; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-size: 16px;
  line-height: 1.65;
  font-feature-settings: 'kern' 1;
  -webkit-font-smoothing: antialiased;
}

/* Focus is visible and consistent. A payment console people cannot tab through
   is a payment console some people cannot use. */
:focus-visible {
  outline: 2px solid var(--petrol);
  outline-offset: 3px;
  border-radius: 2px;
}

a { color: var(--petrol); text-underline-offset: 0.18em; text-decoration-thickness: 1px; }
a:hover { color: var(--petrol-lift); }

h1, h2, h3, h4 { font-family: var(--display); font-weight: 600; line-height: 1.15; margin: 0; letter-spacing: -0.02em; }
h1 { font-size: clamp(2.4rem, 6vw, 4.1rem); letter-spacing: -0.035em; }
h2 { font-size: clamp(1.6rem, 3.2vw, 2.3rem); }
h3 { font-size: 1.18rem; letter-spacing: -0.01em; }
p { margin: 0 0 1.1em; max-width: var(--measure); }

code, kbd, samp { font-family: var(--mono); font-size: 0.875em; }

/* An inline code span is a value, not a decoration: tinted, never boxed in a
   way that breaks the line rhythm. */
:not(pre) > code {
  background: var(--petrol-wash);
  color: var(--on-wash);
  padding: 0.1em 0.34em;
  border-radius: var(--radius);
}

.shell { max-width: var(--shell); margin-inline: auto; padding-inline: var(--gutter); }
.stack > * + * { margin-top: calc(var(--step) * 3); }

/* An eyebrow states what KIND of thing follows. It earns its place only when
   the section is one of several of the same kind. */
.eyebrow {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 0.9rem;
}

.lede { font-size: 1.18rem; color: var(--ink-soft); max-width: 58ch; }

/* ---------------------------------------------------------------- masthead */

.masthead {
  position: sticky;
  top: 0;
  z-index: 20;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--rule);
}

.masthead__inner {
  display: flex;
  align-items: center;
  gap: 2rem;
  height: 62px;
}

.wordmark {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.02rem;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: 0.55rem;
  white-space: nowrap;
}

.wordmark__mark { width: 18px; height: 18px; flex: none; }
.wordmark span { color: var(--ink-faint); font-weight: 400; }

.masthead nav { margin-left: auto; display: flex; gap: 1.6rem; align-items: center; }
.masthead nav a {
  font-size: 0.9rem;
  color: var(--ink-soft);
  text-decoration: none;
}

/*
 * On a narrow screen the section links overflow the bar. They are not lost:
 * every documentation page carries its own navigation, and the footer lists
 * the lot. Keeping the one link into the docs and the panel button is what
 * fits and what somebody on a phone actually reaches for.
 */
@media (max-width: 760px) {
  .masthead nav a:not(:first-child):not(.button) { display: none; }
  .masthead nav { gap: 1rem; }
  .wordmark span { display: none; }
  .masthead .button { padding: 0.45rem 0.8rem; font-size: 0.86rem; }
}
/*
 * Narrower still. The theme and language controls joined this row, and on a
 * small phone the last docs link is what pushed the panel button off the edge.
 * The footer carries every link; nothing here is the only way to reach a page.
 */
@media (max-width: 540px) {
  .masthead nav a:not(.button) { display: none; }
  .masthead nav { gap: 0.5rem; }
  .chrome { margin-inline-start: 0.15rem; gap: 0.25rem; }
}
.masthead nav a:hover, .masthead nav a[aria-current] { color: var(--ink); }

.button {
  display: inline-block;
  font-family: var(--body);
  font-size: 0.92rem;
  font-weight: 500;
  padding: 0.55rem 1.1rem;
  border-radius: var(--radius);
  text-decoration: none;
  border: 1px solid var(--petrol);
  background: var(--petrol);
  color: var(--on-accent);
  white-space: nowrap;
  transition: background 140ms ease, border-color 140ms ease;
}
.button:hover { background: var(--petrol-lift); border-color: var(--petrol-lift); color: var(--on-accent); }
.button--quiet { background: transparent; color: var(--petrol); }
.button--quiet:hover { background: var(--petrol-wash); color: var(--petrol); }

/* -------------------------------------------------------------------- hero */

.hero { padding: clamp(3rem, 7vw, 5.5rem) 0 clamp(2.5rem, 6vw, 4rem); }
.hero h1 { max-width: 19ch; }
.hero .lede { margin-top: 1.5rem; font-size: 1.28rem; }
.hero__actions { display: flex; gap: 0.75rem; flex-wrap: wrap; margin-top: 2rem; }

/*
 * The transaction, as a ledger entry.
 *
 * This replaced two flowcharts. Boxes joined by arrows are what every payments
 * company draws, each arrow carries about one bit of information, and no amount
 * of styling rescues the form — so the form went. A merchant already reads
 * statements, and the claim this product makes is that you can check it on a
 * block explorer, which is closer to what an explorer actually shows you.
 *
 * Solid border is money. The last row is the whole argument as an auditable
 * number rather than a promise.
 */
.ledger { margin: clamp(2.5rem, 5vw, 3.5rem) 0 0; }

.ledger__tx {
  border: 1.5px solid var(--ink);          /* solid: this is the money */
  background: var(--card);
  border-radius: 3px;
  padding: clamp(1.1rem, 2.6vw, 1.75rem) clamp(1.1rem, 3vw, 2rem);
}

.ledger__head {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.5rem;
  align-items: baseline;
  justify-content: space-between;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--ink);
}
.ledger__label, .ledger__sig {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.ledger__label { color: var(--ink); }
.ledger__sig { color: var(--ink-faint); letter-spacing: 0.1em; }

.ledger__rows { margin: 0; }

/*
 * Amount right, party left, on one baseline. `align-items: baseline` is what
 * makes a ledger read as a ledger: the figures line up with the names rather
 * than floating in the middle of a two-line block.
 */
.ledger__row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 0.35rem 2rem;
  padding: 0.95rem 0;
  border-bottom: 1px solid var(--rule);
}
.ledger__row:last-of-type { border-bottom: 0; }

/*
 * FROM / TO sits in its own column beside the party, not above it, so the
 * figure lines up with the name it belongs to rather than with the eyebrow.
 */
.ledger__row dt {
  display: grid;
  grid-template-columns: 3.6rem 1fr;
  align-items: baseline;
  gap: 0.15rem 0;
  min-width: 0;
}
.ledger__dir { grid-column: 1; grid-row: 1; }
.ledger__who { grid-column: 2; grid-row: 1; }
.ledger__note { grid-column: 2; grid-row: 2; }

/*
 * Two cells, so the decimal points stack down the column. Right-aligning the
 * whole string instead would line up the last character of "USDC" and leave
 * the numbers ragged, which is the thing a ledger must not do.
 */
.ledger__row dd {
  margin: 0;
  display: grid;
  grid-template-columns: 7ch auto;
  align-items: baseline;      /* the unit sits on the figure's baseline */
  font-family: var(--mono);
  font-size: 1.05rem;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  text-align: end;
  white-space: nowrap;
}
.ledger__unit {
  font-size: 0.72em;
  color: var(--ink-faint);
  padding-inline-start: 0.5em;
  align-self: baseline;
}

.ledger__dir {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.ledger__who { font-weight: 600; font-size: 1rem; color: var(--ink); }
.ledger__note { font-size: 0.85rem; color: var(--ink-soft); line-height: 1.45; }

/* The line the page is really making. A heavier rule above it, and the one
   figure on the page that is zero. */
.ledger__row--total {
  margin-top: 0.3rem;
  padding-bottom: 0;
  border-top: 1.5px solid var(--ink);
  border-bottom: 0;
}
/* No FROM/TO on this row, so the name starts in the second column with them. */
.ledger__row--total .ledger__who { grid-column: 2; }
.ledger__row--total .ledger__note { grid-column: 2; }
.ledger__row--total dd { color: var(--petrol); font-weight: 500; }

.ledger figcaption {
  margin-top: 1.1rem;
  padding-inline-start: 1.1rem;
  border-inline-start: 1.4px dashed var(--petrol);   /* dashed: this is us */
  font-size: 0.86rem;
  color: var(--ink-soft);
  max-width: 62ch;
}

/* Narrow: the figure drops under the party it belongs to. */
/*
 * Narrow: the figure stays on the party's line, where a statement keeps it.
 * Dropping it below the note instead left it stranded at the left margin with
 * nothing to line up against. Only the columns get tighter.
 */
@media (max-width: 560px) {
  .ledger__row { gap: 0.3rem 0.75rem; }
  .ledger__row dt { grid-template-columns: 2.5rem 1fr; }
  .ledger__row dd { grid-template-columns: auto auto; font-size: 0.95rem; }
  .ledger__dir { font-size: 0.62rem; letter-spacing: 0.1em; }
}

/* Eight items: two columns fill exactly, where the inherited auto-fit gives
   three and leaves a half-empty last row. */
.capabilities { margin-top: 2.75rem; }
@media (min-width: 760px) {
  /* Two classes deep on purpose: this block sits above `.grid--2` in the
     sheet, so at equal specificity the auto-fit columns would win. */
  .grid--2.capabilities {
    grid-template-columns: repeat(2, 1fr);
    column-gap: clamp(2rem, 4vw, 3.5rem);
  }
}
.capability { border-top: 1px solid var(--rule-strong); padding-top: 1.15rem; }
.capability h3 { margin-bottom: 0.5rem; font-size: 1.06rem; }
.capability p { color: var(--ink-soft); font-size: 0.95rem; margin: 0; }
.capability code { font-size: 0.86em; }

@media (prefers-reduced-motion: no-preference) {
  /*
   * Only ever put `.draw` on a solid stroke. It animates by setting
   * stroke-dasharray, which silently overwrites any dash pattern already
   * there — and in these diagrams the dash pattern is what says "this is not
   * the money". Dashed strokes fade in instead.
   */
  .draw { stroke-dasharray: var(--len, 1200); stroke-dashoffset: var(--len, 1200);
          animation: draw 1.1s cubic-bezier(.6,.05,.2,1) forwards; }
  .draw--2 { animation-delay: 0.28s; }
  .draw--3 { animation-delay: 0.5s; }
  .fade { opacity: 0; animation: fade 0.5s ease forwards; }
  .fade--1 { animation-delay: 0.8s; }
  .fade--2 { animation-delay: 0.95s; }
  .fade--3 { animation-delay: 1.1s; }
  @keyframes draw { to { stroke-dashoffset: 0; } }
  @keyframes fade { to { opacity: 1; } }
}

/* ---------------------------------------------------------------- sections */

.band { padding: clamp(3rem, 7vw, 5.5rem) 0; border-top: 1px solid var(--rule); }
.band--card { background: var(--card); }

.grid { display: grid; gap: clamp(1.5rem, 3vw, 2.5rem); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }

.claim { border-top: 2px solid var(--ink); padding-top: 1.1rem; }
.claim h3 { margin-bottom: 0.5rem; }
.claim p { color: var(--ink-soft); font-size: 0.96rem; margin: 0; }

/*
 * The lifecycle. These are the real status values the API returns, in the
 * order a payment moves through them — so the sequence is information rather
 * than decoration, and a developer can match each label to what they will
 * actually receive in a webhook.
 */
.lifecycle { display: flex; flex-wrap: wrap; gap: 0; margin-top: 2rem; }
.lifecycle__step { flex: 1 1 160px; border-top: 2px solid var(--rule-strong); padding: 1rem 1.2rem 0 0; }
.lifecycle__step:last-child { border-top-color: var(--ink); }
.lifecycle__state { font-family: var(--mono); font-size: 0.85rem; color: var(--ink); display: block; }
.lifecycle__step p { font-size: 0.88rem; color: var(--ink-soft); margin: 0.4rem 0 0; }

/* An irreversibility notice. The only place --alert is used. */
.irreversible {
  border-left: 3px solid var(--alert);
  background: var(--alert-wash);
  padding: 1.1rem 1.3rem;
  border-radius: 0 var(--radius) var(--radius) 0;
}
.irreversible strong { color: var(--alert); }
.irreversible p:last-child { margin-bottom: 0; }

/* ------------------------------------------------------------------- docs */

.docs { display: grid; grid-template-columns: 232px minmax(0, 1fr); gap: clamp(2rem, 5vw, 4rem); padding: 3rem 0 6rem; }
@media (max-width: 900px) { .docs { grid-template-columns: 1fr; } }

.docnav { font-size: 0.9rem; align-self: start; position: sticky; top: 82px; }
@media (max-width: 900px) { .docnav { position: static; border-bottom: 1px solid var(--rule); padding-bottom: 1.5rem; } }
.docnav h4 {
  font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--ink-faint); margin: 1.6rem 0 0.6rem; font-weight: 500;
}
.docnav h4:first-child { margin-top: 0; }
.docnav ul { list-style: none; margin: 0; padding: 0; }
.docnav li { margin: 0; }
.docnav a {
  display: block; padding: 0.28rem 0 0.28rem 0.75rem;
  color: var(--ink-soft); text-decoration: none; border-left: 2px solid var(--rule);
}
.docnav a:hover { color: var(--ink); border-left-color: var(--rule-strong); }
.docnav a[aria-current] { color: var(--petrol); border-left-color: var(--petrol); font-weight: 500; }

.doc { min-width: 0; }
.doc h1 { font-size: clamp(1.9rem, 4vw, 2.6rem); margin-bottom: 0.75rem; }
.doc h2 { font-size: 1.42rem; margin: 2.8rem 0 0.9rem; padding-top: 1.4rem; border-top: 1px solid var(--rule); }
.doc h3 { margin: 2rem 0 0.6rem; }
.doc ul, .doc ol { max-width: var(--measure); padding-left: 1.2rem; }
.doc li { margin-bottom: 0.45rem; }
.doc table { border-collapse: collapse; width: 100%; margin: 1.4rem 0; font-size: 0.92rem; }
.doc th, .doc td { text-align: left; padding: 0.6rem 0.9rem 0.6rem 0; border-bottom: 1px solid var(--rule); vertical-align: top; }
.doc th { font-family: var(--mono); font-size: 0.74rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-faint); font-weight: 500; }
.doc td code { white-space: nowrap; }

.doc__foot { margin-top: 4rem; padding-top: 1.5rem; border-top: 1px solid var(--rule); display: flex; justify-content: space-between; gap: 1rem; font-size: 0.92rem; }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* The reference needs the extra column for samples next to the tables.
   Other pages stay on the reading measure. */
.docs--api { max-width: 1320px; }
.doc--api { max-width: none; }
.doc--api > p,
.doc--api > ul { max-width: var(--measure); }

.ref-tools { margin: 1.6rem 0 1.2rem; }
.ref-jumps {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem 0.9rem;
  margin-top: 0.85rem;
  font-size: 0.9rem;
}
.ref-jumps a { text-decoration: none; }
.op__body { overflow-x: auto; }
.op table { min-width: 32rem; }
.ref-search input {
  width: 100%;
  max-width: 42rem;
  min-height: 44px;
  font-family: var(--body);
  font-size: 1rem;
  padding: 0.65rem 0.9rem;
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--ink);
}
.ref-search input::placeholder { color: var(--ink-faint); }
.ref-empty { color: var(--ink-soft); }

.ref-index {
  list-style: none;
  margin: 1rem 0 1.6rem;
  padding: 0;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--card);
}
.ref-index li { margin: 0; border-top: 1px solid var(--rule); }
.ref-index li:first-child { border-top: 0; }
.ref-index a {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.7rem 0.95rem;
  min-height: 44px;
  text-decoration: none;
  color: var(--ink);
}
.ref-index a:hover { background: var(--petrol-wash); }
.ref-index a span:last-child { color: var(--ink-soft); font-size: 0.92rem; }
.ref-index code { color: var(--ink); }

.verb {
  font-family: var(--mono);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.18rem 0.42rem;
  border-radius: var(--radius);
  flex: none;
  min-width: 3.6rem;
  text-align: center;
}
.verb--get { background: var(--petrol-wash); color: var(--petrol); }
.verb--post { background: var(--ink); color: var(--paper); }
.verb--put, .verb--patch { background: var(--card); color: var(--ink); border: 1px solid var(--ink); }
.verb--delete { background: var(--card); color: var(--ink-soft); border: 1px dashed var(--rule-strong); }

.op {
  margin: 0 0 0.7rem;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--card);
  scroll-margin-top: 88px;
}
.ref-group { scroll-margin-top: 88px; }
.op[open] { border-color: var(--rule-strong); }

.op__sum {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.75rem 1rem;
  min-height: 48px;
  cursor: pointer;
  list-style: none;
}
.op__sum::-webkit-details-marker { display: none; }
.op__sum::marker { content: ''; }
.op__sum:hover { background: color-mix(in srgb, var(--petrol-wash) 55%, var(--card)); }
.op__path { font-size: 0.92rem; color: var(--ink); }
.op__lead { color: var(--ink-soft); font-size: 0.92rem; }

.op__body { padding: 0 1.1rem 1.3rem; border-top: 1px solid var(--rule); }
.op__body h3 { margin: 1.5rem 0 0.55rem; font-size: 1.02rem; }
.op__body h4 {
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 1.1rem 0 0.2rem;
  font-weight: 500;
}
.op__flags { color: var(--ink-soft); font-size: 0.92rem; }
.op__empty, .op__hint, .op__more { color: var(--ink-soft); font-size: 0.92rem; }
.op__url {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.7rem 0.9rem;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
}
.op__url code { font-size: 0.84rem; word-break: break-all; }
.op__copy {
  margin-left: auto;
  font-family: var(--mono);
  font-size: 0.75rem;
  padding: 0.4rem 0.7rem;
  min-height: 36px;
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--petrol);
  cursor: pointer;
}
.op__copy:hover { background: var(--petrol-wash); }

.op__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 0 2rem;
  align-items: start;
}
.op__grid .snippet,
.op__grid .snippet--bare { margin-top: 0.4rem; }

@media (min-width: 1101px) {
  .op__grid > div:last-child {
    position: sticky;
    top: 88px;
    max-height: calc(100vh - 110px);
    overflow: auto;
  }
}

@media (max-width: 1100px) {
  .op__grid { grid-template-columns: 1fr; }
}

@media (max-width: 900px) {
  .docs--api { max-width: var(--shell); }
}

/* ------------------------------------------------------------------- code */

.snippet { margin: 1.5rem 0; border: 1px solid var(--rule); border-radius: var(--radius); overflow: hidden; background: var(--card); }
.snippet__tabs { display: flex; gap: 0; border-bottom: 1px solid var(--rule); overflow-x: auto; }
.snippet__tab {
  font-family: var(--mono); font-size: 0.78rem; padding: 0.55rem 0.95rem;
  background: none; border: 0; border-bottom: 2px solid transparent;
  color: var(--ink-faint); cursor: pointer; white-space: nowrap;
}
.snippet__tab:hover { color: var(--ink); }
.snippet__tab[aria-selected='true'] { color: var(--petrol); border-bottom-color: var(--petrol); }
.snippet__panel[hidden] { display: none; }

pre {
  margin: 0; padding: 1.1rem 1.2rem; overflow-x: auto;
  font-family: var(--mono); font-size: 0.83rem; line-height: 1.7;
  background: var(--card); color: var(--ink);
  tab-size: 2;
}
.snippet--bare pre { border: 1px solid var(--rule); border-radius: var(--radius); }

/* Enough highlighting to read structure, and no more. A docs page is not an
   editor, and rainbow syntax colouring competes with the prose. */
.tok-c { color: var(--ink-faint); font-style: italic; }
.tok-s { color: var(--tok-string); }
.tok-k { color: var(--petrol); }
.tok-n { color: var(--tok-number); }

/* ----------------------------------------------------------------- footer */

.foot { border-top: 1px solid var(--rule); padding: 3rem 0; font-size: 0.9rem; color: var(--ink-soft); }
.foot__cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 2rem; }
.foot h4 { font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.13em; text-transform: uppercase; color: var(--ink-faint); margin: 0 0 0.7rem; font-weight: 500; }
.foot ul { list-style: none; margin: 0; padding: 0; }
.foot li { margin-bottom: 0.35rem; }
.foot a { color: var(--ink-soft); text-decoration: none; }
.foot a:hover { color: var(--ink); text-decoration: underline; }
.foot__note { margin-top: 2.5rem; padding-top: 1.5rem; border-top: 1px solid var(--rule); font-size: 0.84rem; color: var(--ink-faint); }

/* ------------------------------------------------------ endpoint reference */

/*
 * One operation. Dense on purpose: this page is scanned for a path, not read
 * from the top, so the method and the path have to be findable at a glance and
 * everything else has to stay out of the way until the eye lands.
 */
.op { padding: 1.4rem 0 0.4rem; border-top: 1px solid var(--rule); }
.op:first-of-type { border-top: 0; }

.op__head { display: flex; align-items: baseline; gap: 0.7rem; margin: 0 0 0.5rem; flex-wrap: wrap; }

.op__method {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  padding: 0.16rem 0.44rem;
  border-radius: var(--radius);
  border: 1px solid currentColor;
  flex: none;
}
/* Read differs from write differs from delete, and the colour says which
   before the word is read. */
.op__method--get { color: var(--petrol); }
.op__method--post { color: var(--tok-string); }
.op__method--put, .op__method--patch { color: var(--tok-number); }
.op__method--delete { color: var(--alert); }

.op__path { font-size: 0.95rem; color: var(--ink); font-weight: 500; word-break: break-all; }
.op__summary { font-size: 0.98rem; color: var(--ink); margin-bottom: 0.5rem; }
.op p { font-size: 0.92rem; color: var(--ink-soft); margin-bottom: 0.5rem; }
.op__scope { font-family: var(--mono); font-size: 0.78rem; color: var(--ink-faint); }
.op__scope code { background: none; padding: 0; color: var(--petrol); }
.op table { margin: 0.9rem 0 1.2rem; font-size: 0.86rem; }
.op td:first-child { white-space: nowrap; }

/* The response, set apart from the request without becoming a second page. */
.op__returns { margin: 1rem 0 0.6rem; padding-left: 0.9rem; border-left: 2px solid var(--rule); }
.op__returns h4 { font-size: 0.9rem; font-weight: 500; color: var(--ink); margin: 0 0 0.35rem; }
.op__code {
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--tok-string);
  border: 1px solid currentColor;
  border-radius: var(--radius);
  padding: 0.1rem 0.36rem;
  margin-right: 0.4rem;
}
.op__shape { font-size: 0.86rem; color: var(--ink-faint); margin-bottom: 0.4rem; }
.op__returns table { margin-top: 0.6rem; }


/* --------------------------------------------------- standalone articles */

/*
 * The FAQ and the legal pages. Narrower than the documentation, because these
 * are read in paragraphs rather than scanned for a field name.
 */
.article { padding-block: 3.5rem 5rem; }
.article h1 { font-size: clamp(1.9rem, 4vw, 2.6rem); margin-bottom: 0.75rem; }
.article > .lede { margin-bottom: 2.5rem; }
.article--measure .doc { max-width: 68ch; }

/*
 * One question. Closed by default: forty open answers is a wall, and the
 * question is the part somebody is scanning for.
 */
.faq {
  border-bottom: 1px solid var(--rule);
}
.faq > summary {
  cursor: pointer;
  padding: 0.95rem 2rem 0.95rem 0;
  font-weight: 500;
  list-style: none;
  position: relative;
}
.faq > summary::-webkit-details-marker { display: none; }
.faq > summary::after {
  content: "+";
  position: absolute;
  right: 0.2rem;
  top: 0.85rem;
  font-family: var(--mono);
  color: var(--ink-faint);
  transition: transform 0.15s ease;
}
.faq[open] > summary::after { content: "−"; }
.faq > summary:hover { color: var(--accent); }
.faq > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.faq__body { padding: 0 0 1.1rem; max-width: 66ch; }
.faq__body p { margin-bottom: 0.7rem; }
.faq__body p:last-child { margin-bottom: 0; }

.doc__meta {
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--ink-faint);
  margin-bottom: 1.6rem;
}

/*
 * An outstanding decision, marked as one. A legal page that quietly invents a
 * governing law is worse than a legal page that says the question is open.
 */
.doc__todo {
  border-left: 2px solid var(--warn);
  background: var(--warn-bg);
  padding: 0.8rem 1rem;
  font-size: 0.95rem;
}


/* ------------------------------------------------------- header controls */

.chrome { display: inline-flex; align-items: center; gap: 0.35rem; margin-inline-start: 0.5rem; }

.chrome__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2rem;
  height: 2rem;
  padding: 0 0.45rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: transparent;
  color: var(--ink-soft);
  font-family: var(--mono);
  font-size: 0.78rem;
  cursor: pointer;
  line-height: 1;
}
.chrome__btn:hover { color: var(--petrol); border-color: var(--rule-strong); }
.chrome__btn:focus-visible { outline: 2px solid var(--petrol); outline-offset: 2px; }

.chrome__icon { display: inline-flex; }
.chrome__lang { position: relative; }
.chrome__menu {
  position: absolute;
  inset-inline-end: 0;
  top: calc(100% + 0.35rem);
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 4px;
  padding: 0.3rem;
  /* Ten languages in one column is a 300px curtain over the page. Two columns
     of five sit under the button and stay scannable. */
  display: grid;
  grid-template-columns: repeat(2, minmax(7.6rem, 1fr));
  gap: 0.15rem 0.25rem;
  max-height: 70vh;
  overflow-y: auto;
  z-index: 40;
  box-shadow: 0 6px 20px rgb(8 25 27 / 12%);
}
/* `display: grid` above outranks the browser's own [hidden] rule, so the menu
   has to be told again — otherwise it is open on every page load. */
.chrome__menu[hidden] { display: none; }
.chrome__menu a {
  padding: 0.4rem 0.6rem;
  border-radius: 3px;
  font-size: 0.9rem;
  color: var(--ink);
  text-decoration: none;
}
.chrome__menu a:hover { background: var(--petrol-wash); color: var(--on-wash); }
.chrome__menu a[aria-current] { color: var(--petrol); font-weight: 500; }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/*
 * Chinese and Japanese.
 *
 * Neither of the site's Latin faces carries CJK, so the browser substitutes per
 * character. Naming the platform faces first keeps a page in one typeface
 * instead of a patchwork, and the line-height opens up: CJK glyphs fill their
 * em box, and prose set at the Latin leading reads as a solid block.
 */
:root:lang(zh) body, :root:lang(ja) body,
:root:lang(zh) h1, :root:lang(ja) h1,
:root:lang(zh) h2, :root:lang(ja) h2,
:root:lang(zh) h3, :root:lang(ja) h3 {
  font-family: 'IBM Plex Sans', 'PingFang SC', 'Hiragino Sans', 'Noto Sans CJK SC',
    'Microsoft YaHei', 'Yu Gothic', system-ui, sans-serif;
}
:root:lang(zh), :root:lang(ja) { line-height: 1.9; }

/* ----------------------------------------------------------------- rtl */

/*
 * Persian and Arabic. Most of the layout is already direction-agnostic because
 * it uses logical properties; these are the places that are not.
 */
/*
 * The one thing that is not about direction: script. IBM Plex Sans and Space
 * Grotesk carry no Arabic glyphs, so without this every Persian and Arabic page
 * renders in whatever serif the machine happens to have. IBM Plex Sans Arabic
 * is the same family in the right script, so the pages still look related.
 */
[dir="rtl"] body,
[dir="rtl"] h1, [dir="rtl"] h2, [dir="rtl"] h3, [dir="rtl"] h4 {
  font-family: "IBM Plex Sans Arabic", "IBM Plex Sans", system-ui, sans-serif;
}
[dir="rtl"] { line-height: 1.85; }

[dir="rtl"] .doc ul,
[dir="rtl"] .doc ol { padding-left: 0; padding-right: 1.2rem; }
[dir="rtl"] .faq > summary { padding: 0.95rem 0 0.95rem 2rem; }
[dir="rtl"] .faq > summary::after { right: auto; left: 0.2rem; }
[dir="rtl"] .doc__todo,
[dir="rtl"] .irreversible { border-left: 0; border-right: 2px solid var(--alert); }

/* Latin stays left-to-right inside a right-to-left paragraph. */
[dir="rtl"] code, [dir="rtl"] pre { direction: ltr; text-align: left; unicode-bidi: embed; }
