/* ==========================================================================
   pyapple-mcp — shared design system
   --------------------------------------------------------------------------
   One idea governs this page: colour means permission cost, and nothing else.
   The three route hues (framework / automation / database) are the
   only chroma in the design. They are introduced in the hero legend, they
   group the ledger, and they carry through to the API reference sidebar. If a
   thing on this page is coloured, it is telling you what that tool asks of
   your Mac.

   Type inverts the usual dev-docs arrangement: the monospace face is the
   display face, because the eight tools are monospace identifiers and that is
   the product's own vernacular. The serif is demoted to quiet asides.
   All faces are system faces — the page fetches nothing.
   ========================================================================== */

/* --- tokens ------------------------------------------------------------- */

:root {
  color-scheme: light;

  /* surfaces + ink */
  --paper:      #eef1f5;
  --card:       #ffffff;
  --card-sunk:  #f5f7fa;
  --ink:        #0d141b;
  --ink-body:   #2b3742;
  --ink-dim:    #55636f;
  /* Measured, not guessed: the previous #6f7d89 scored 3.73:1 against --paper,
     which fails AA for the slugs, table headers, type columns and serif asides
     that all use it. This value is 4.96:1 on paper and better on the cards. */
  --ink-faint:  #5c6975;
  --rule:       #d4dce4;
  --rule-soft:  #e3e9ef;

  /* route hues — the page's only chroma */
  --framework:     #0d6d51;
  --framework-bg:  #e2f1eb;
  --automation:    #27548f;
  --automation-bg: #e2ebf7;
  --database:      #9c4a12;
  --database-bg:   #f8e9dd;

  --shadow: 0 1px 2px rgba(13, 20, 27, .05), 0 8px 24px -12px rgba(13, 20, 27, .14);

  /* faces */
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, Roboto, "Helvetica Neue", Arial, sans-serif;
  --serif: ui-serif, "New York", Charter, Georgia, "Times New Roman", serif;

  /* measure */
  --page: 1080px;
  --gutter: clamp(1.25rem, 4vw, 3rem);
}

/* Dark, from the OS — but only while no manual choice has been made. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --paper:      #0c1117;
    --card:       #151b23;
    --card-sunk:  #10161d;
    --ink:        #e6ecf3;
    --ink-body:   #c2ccd7;
    --ink-dim:    #9dabb8;
    --ink-faint:  #8b98a4;
    --rule:       #242e39;
    --rule-soft:  #1c242d;

    --framework:     #55c9a0;
    --framework-bg:  #12302a;
    --automation:    #7db0ef;
    --automation-bg: #16283f;
    --database:      #ee9d55;
    --database-bg:   #35220f;

    --shadow: 0 1px 2px rgba(0, 0, 0, .5), 0 8px 24px -12px rgba(0, 0, 0, .7);
  }
}

/* The manual choice wins in both directions. */
:root[data-theme="dark"] {
  color-scheme: dark;

  --paper:      #0c1117;
  --card:       #151b23;
  --card-sunk:  #10161d;
  --ink:        #e6ecf3;
  --ink-body:   #c2ccd7;
  --ink-dim:    #9dabb8;
  --ink-faint:  #8b98a4;
  --rule:       #242e39;
  --rule-soft:  #1c242d;

  --framework:     #55c9a0;
  --framework-bg:  #12302a;
  --automation:    #7db0ef;
  --automation-bg: #16283f;
  --database:      #ee9d55;
  --database-bg:   #35220f;

  --shadow: 0 1px 2px rgba(0, 0, 0, .5), 0 8px 24px -12px rgba(0, 0, 0, .7);
}

/* --- base --------------------------------------------------------------- */

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

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink-body);
  font-family: var(--sans);
  font-size: 1.0625rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-wrap: break-word;
}

h1, h2, h3, h4 {
  color: var(--ink);
  margin: 0;
  line-height: 1.15;
  font-weight: 600;
}

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

a {
  color: var(--ink);
  text-decoration-color: var(--ink-faint);
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}
a:hover { text-decoration-color: currentColor; }

code, kbd, samp, pre { font-family: var(--mono); }

img, svg { max-width: 100%; }

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
  border-radius: 3px;
}

.skip-link {
  position: absolute;
  left: 0.5rem;
  top: -4rem;
  z-index: 100;
  background: var(--card);
  color: var(--ink);
  padding: 0.6rem 1rem;
  border: 1px solid var(--rule);
  border-radius: 8px;
  font: 600 0.875rem/1 var(--sans);
  text-decoration: none;
  transition: top .16s ease;
}
.skip-link:focus { top: 0.5rem; }

/* An id kept alive after the section that owned it was rewritten. It occupies
   no space; the page's scroll-padding puts it under the sticky header. */
.anchor-alias { display: block; height: 0; }

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

/* --- layout ------------------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--page);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.band { padding-block: clamp(3.5rem, 7vw, 6rem); }
.band--sunk { background: var(--card-sunk); border-block: 1px solid var(--rule-soft); }

/* Section label: a mono slug and a hairline that runs to the margin. The rule
   is doing the work of a divider so the heading itself can stay quiet. */
.slug {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  margin: 0 0 1.75rem;
  font: 500 0.6875rem/1 var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.slug::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--rule);
}

.band-title {
  font-size: clamp(1.45rem, 1.1rem + 1.4vw, 2rem);
  letter-spacing: -0.02em;
  max-width: 24ch;
  margin-bottom: 0.85rem;
}

.band-lede {
  color: var(--ink-dim);
  max-width: 64ch;
  margin-bottom: 2.5rem;
}

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

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--paper);
  border-bottom: 1px solid var(--rule-soft);
}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .site-header {
    background: color-mix(in srgb, var(--paper) 86%, transparent);
    -webkit-backdrop-filter: saturate(180%) blur(14px);
    backdrop-filter: saturate(180%) blur(14px);
  }
}

.site-header .wrap {
  display: flex;
  align-items: center;
  gap: 1rem;
  min-height: 3.75rem;
}

.wordmark {
  font: 600 0.9375rem/1 var(--mono);
  letter-spacing: -0.02em;
  color: var(--ink);
  text-decoration: none;
  display: inline-flex;
  align-items: baseline;
  gap: 0.45rem;
  white-space: nowrap;
}
.wordmark .ver {
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
}

.site-nav {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: clamp(0.75rem, 2vw, 1.6rem);
}
.site-nav a {
  font-size: 0.875rem;
  color: var(--ink-dim);
  text-decoration: none;
  white-space: nowrap;
}
.site-nav a:hover,
.site-nav a[aria-current="page"] { color: var(--ink); }

.theme-toggle {
  appearance: none;
  -webkit-appearance: none;
  border: 1px solid var(--rule);
  background: var(--card);
  color: var(--ink-dim);
  width: 2rem;
  height: 2rem;
  border-radius: 999px;
  display: grid;
  place-items: center;
  cursor: pointer;
  flex: none;
  padding: 0;
}
.theme-toggle:hover { color: var(--ink); border-color: var(--ink-faint); }
.theme-toggle svg { width: 15px; height: 15px; display: block; }
.theme-toggle .icon-dark { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-dark { display: block; }
:root[data-theme="dark"] .theme-toggle .icon-light { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .icon-dark { display: block; }
  :root:not([data-theme="light"]) .theme-toggle .icon-light { display: none; }
}

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

.hero { padding-block: clamp(2.75rem, 7vw, 5.5rem) clamp(3rem, 6vw, 4.5rem); }

.eyebrow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.9rem;
  margin: 0 0 1.6rem;
  padding: 0;
  list-style: none;
  font: 500 0.6875rem/1.4 var(--mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.eyebrow li { display: flex; align-items: center; gap: 0.9rem; }
.eyebrow li + li::before {
  content: "";
  width: 3px; height: 3px;
  border-radius: 50%;
  background: currentColor;
  opacity: .6;
  flex: none;
}

.hero h1 {
  font-family: var(--mono);
  font-size: clamp(1.9rem, 1.05rem + 3.2vw, 3.4rem);
  font-weight: 600;
  letter-spacing: -0.045em;
  line-height: 1.08;
  max-width: 18ch;
  margin-bottom: 1.5rem;
}
.hero h1 .quiet { color: var(--ink-faint); }

.hero-lede {
  font-size: clamp(1.0625rem, 1rem + 0.3vw, 1.1875rem);
  color: var(--ink-dim);
  max-width: 58ch;
  margin-bottom: 2.5rem;
}
.hero-lede strong { color: var(--ink); font-weight: 600; }

/* The legend. Eight identifiers, coloured by the route each one takes. It is
   both the product's contents page and the key to every colour that follows,
   so it earns its place above the fold. */
.legend {
  border: 1px solid var(--rule);
  border-radius: 14px;
  background: var(--card);
  box-shadow: var(--shadow);
  overflow: hidden;
  margin-bottom: 2.25rem;
}

.legend-row {
  display: grid;
  grid-template-columns: minmax(0, 17rem) minmax(0, 1fr);
  gap: 0.5rem 1.5rem;
  align-items: baseline;
  padding: 0.95rem 1.25rem;
  border-top: 1px solid var(--rule-soft);
}
.legend-row:first-child { border-top: 0; }

.legend-names {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 0.9rem;
  font: 600 0.9375rem/1.4 var(--mono);
  letter-spacing: -0.02em;
}
.legend-names a {
  color: var(--route);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.legend-names a:hover { border-bottom-color: currentColor; }

.legend-cost {
  font-size: 0.8125rem;
  color: var(--ink-dim);
  line-height: 1.5;
}
.legend-cost b { color: var(--route); font-weight: 600; }

/* --- route theming ------------------------------------------------------ */
/* Set once per element; every descendant reads --route and --route-bg. */

[data-route="framework"]  { --route: var(--framework);  --route-bg: var(--framework-bg); }
[data-route="automation"] { --route: var(--automation); --route-bg: var(--automation-bg); }
[data-route="database"]   { --route: var(--database);   --route-bg: var(--database-bg); }

.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.2rem 0.6rem 0.2rem 0.5rem;
  border-radius: 999px;
  background: var(--route-bg);
  color: var(--route);
  font: 600 0.6875rem/1.5 var(--mono);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
}
.chip::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}

/* --- the ledger --------------------------------------------------------- */

.ledger { display: flex; flex-direction: column; gap: 1.25rem; }

.route {
  border: 1px solid var(--rule);
  border-left: 3px solid var(--route);
  border-radius: 12px;
  background: var(--card);
  display: grid;
  grid-template-columns: 16rem minmax(0, 1fr);
  overflow: hidden;
}

.route-head {
  padding: 1.4rem 1.35rem;
  background: var(--card-sunk);
  border-right: 1px solid var(--rule-soft);
}
.route-head h3 {
  font-family: var(--mono);
  font-size: 1rem;
  letter-spacing: -0.02em;
  color: var(--route);
  margin: 0.8rem 0 0.5rem;
}
.route-cost {
  font-size: 0.8125rem;
  color: var(--ink-dim);
  line-height: 1.5;
  margin: 0;
}
.route-cost strong { color: var(--ink); font-weight: 600; }

.route-tools { list-style: none; margin: 0; padding: 0; }
.route-tools li {
  padding: 1.15rem 1.35rem;
  border-top: 1px solid var(--rule-soft);
}
.route-tools li:first-child { border-top: 0; }

.tool-name {
  font: 600 0.9375rem/1.3 var(--mono);
  letter-spacing: -0.02em;
  color: var(--ink);
  text-decoration: none;
  display: inline-block;
  margin-bottom: 0.3rem;
  border-bottom: 1px solid var(--rule);
}
.tool-name:hover { border-bottom-color: var(--route); color: var(--route); }

.tool-does {
  margin: 0;
  font-size: 0.9375rem;
  color: var(--ink-dim);
  line-height: 1.55;
}
/* Matches .route-cost strong. The automation row ends with a statement about
   the whole page rather than about a tool, and its opening clause has to carry
   the same weight the route-head's does. */
.tool-does strong { color: var(--ink); font-weight: 600; }
.tool-note {
  margin: 0.5rem 0 0;
  font-family: var(--serif);
  font-size: 0.9375rem;
  font-style: italic;
  line-height: 1.5;
  color: var(--ink-faint);
}

/* --- facts -------------------------------------------------------------- */

.facts {
  margin: 2.5rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 11.5rem), 1fr));
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
  border-radius: 12px;
  overflow: hidden;
}
.facts > div { background: var(--card); padding: 1.35rem 1.25rem; }
.facts dt {
  font: 600 1.45rem/1.1 var(--mono);
  letter-spacing: -0.035em;
  color: var(--ink);
  margin-bottom: 0.4rem;
}
.facts dd {
  margin: 0;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--ink-dim);
}

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

.code {
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 12px;
  overflow: hidden;
}

.code-head {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.55rem 0.6rem 0.55rem 1rem;
  border-bottom: 1px solid var(--rule-soft);
  background: var(--card-sunk);
}
.code-head .label {
  font: 500 0.6875rem/1.4 var(--mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.code pre {
  margin: 0;
  padding: 1rem 1.1rem;
  overflow-x: auto;
  font-size: 0.8438rem;
  line-height: 1.7;
  color: var(--ink-body);
  tab-size: 2;
}
/* One block wraps instead of scrolling, for the same reason the API page's
   signatures do: the permission string is the thing that section exists to
   show, and inside a half-width panel it was disappearing into a scroller
   nobody would think to drag. Terminal transcripts keep scrolling — their
   columns only line up unwrapped. */
.code--wrap pre { white-space: pre-wrap; overflow-wrap: anywhere; }

.code .prompt { color: var(--ink-faint); user-select: none; }
.code .key { color: var(--automation); }
.code .str { color: var(--framework); }
.code .cmt { color: var(--ink-faint); font-style: italic; }

.copy {
  margin-left: auto;
  appearance: none;
  -webkit-appearance: none;
  border: 1px solid var(--rule);
  background: var(--card);
  color: var(--ink-dim);
  border-radius: 7px;
  padding: 0.3rem 0.6rem;
  font: 500 0.75rem/1.3 var(--sans);
  cursor: pointer;
  flex: none;
}
.copy:hover { color: var(--ink); border-color: var(--ink-faint); }
.copy[data-copied="true"] { color: var(--framework); border-color: var(--framework); }

/* inline code inside prose */
p code, li code, dd code, .route-cost code, .legend-cost code {
  font-size: 0.875em;
  background: var(--card-sunk);
  border: 1px solid var(--rule-soft);
  border-radius: 5px;
  padding: 0.1em 0.35em;
  color: var(--ink);
}
.code pre code { background: none; border: 0; padding: 0; font-size: inherit; color: inherit; }

/* --- panels ------------------------------------------------------------- */

.split {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 23rem), 1fr));
  gap: 1.25rem;
  align-items: start;
}

.panel {
  border: 1px solid var(--rule);
  border-radius: 14px;
  background: var(--card);
  padding: 1.5rem;
}
.panel h3 {
  font-size: 1rem;
  letter-spacing: -0.01em;
  margin-bottom: 0.35rem;
}
.panel .panel-note {
  font-size: 0.875rem;
  color: var(--ink-dim);
  margin-bottom: 1.1rem;
}
.panel .code { margin-bottom: 0.9rem; }
.panel .code:last-child { margin-bottom: 0; }
.panel > p:last-child { margin-bottom: 0; }
.panel .after-note {
  font-size: 0.875rem;
  color: var(--ink-dim);
  margin: 0.9rem 0 0;
}

/* A filesystem path is too long to sit inline in a sentence — as an inline
   chip it split across two lines and stranded the full stop on its own. Give
   it its own block and let it break wherever it needs to. */
.panel .path {
  margin: 0 0 1.1rem;
}
.panel .path code {
  display: block;
  font-size: 0.8125rem;
  line-height: 1.6;
  padding: 0.5rem 0.7rem;
  background: var(--card-sunk);
  border: 1px solid var(--rule-soft);
  border-radius: 7px;
  color: var(--ink);
  overflow-wrap: anywhere;
}

.reqs { margin: 0; padding: 0; }
.reqs > div {
  display: flex;
  gap: 1rem;
  padding: 0.6rem 0;
  border-top: 1px solid var(--rule-soft);
  font-size: 0.9375rem;
}
.reqs > div:first-child { border-top: 0; padding-top: 0; }
.reqs > div:last-child { padding-bottom: 0; }
.reqs dt {
  flex: none;
  width: 7rem;
  font: 500 0.75rem/1.75 var(--mono);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.reqs dd { margin: 0; color: var(--ink-body); min-width: 0; }

/* When the term is an identifier rather than a word, it keeps its own case.
   .reqs's uppercase is right for "macOS" and "Python"; applied to a flag it
   printed `--READ-ONLY`, which is not a thing anybody can type — the label
   stopped describing the setting and started misreporting it. */
.reqs--ident dt {
  text-transform: none;
  letter-spacing: 0;
  font-size: 0.8125rem;
  color: var(--ink);
}

/* --- the four classes --------------------------------------------------- */
/* Deliberately achromatic. The classes are orthogonal to the route hues — a
   `send` in mail and a `send` in messages cost different permissions — so
   giving them a colour would break the one rule this palette has. Order is the
   only ranking they get, and it is the order the code declares them in. */
.classes {
  margin: 0 0 0.9rem;
  padding: 0;
  border: 1px solid var(--rule);
  border-radius: 12px;
  background: var(--card);
  overflow: hidden;
}
.classes > div {
  display: grid;
  grid-template-columns: 6.5rem minmax(0, 1.6fr) minmax(0, 1fr);
  gap: 0.25rem 1.25rem;
  align-items: baseline;
  padding: 0.85rem 1.25rem;
  border-top: 1px solid var(--rule-soft);
}
.classes > div:first-child { border-top: 0; }
.classes dt {
  font: 600 0.9375rem/1.5 var(--mono);
  letter-spacing: -0.02em;
  color: var(--ink);
}
.classes dd { margin: 0; min-width: 0; }
.classes .means { color: var(--ink-dim); font-size: 0.9375rem; line-height: 1.55; }
/* The examples are identifiers, so they keep the monospace vernacular and stay
   quiet: they illustrate the class, they are not a list to be read across. */
.classes .eg {
  font: 500 0.8125rem/1.6 var(--mono);
  color: var(--ink-faint);
}
.classes-note {
  font-size: 0.8125rem;
  color: var(--ink-faint);
  max-width: 78ch;
  margin: 0 0 2.5rem;
}

/* --- read-only ledger --------------------------------------------------- */
/* The same job as .reqs — a term and its value — but the term here is a tool
   identifier, so it keeps the lowercase monospace vernacular and its own route
   colour rather than .reqs's uppercase label. The middle column is the count
   before and after, which is the whole claim of that section. */
.ro { margin: 0; padding: 0; }
.ro > div {
  display: grid;
  grid-template-columns: 7rem 4.75rem minmax(0, 1fr);
  gap: 0.2rem 0.9rem;
  align-items: baseline;
  padding: 0.5rem 0;
  border-top: 1px solid var(--rule-soft);
}
.ro > div:first-child { border-top: 0; padding-top: 0; }
.ro > div:last-child { padding-bottom: 0; }
.ro dt {
  font: 600 0.875rem/1.5 var(--mono);
  letter-spacing: -0.02em;
  /* The fallback is for the total row, which belongs to no route. */
  color: var(--route, var(--ink));
  min-width: 0;
}
.ro dd {
  margin: 0;
  font-size: 0.8125rem;
  line-height: 1.6;
  color: var(--ink-dim);
  min-width: 0;
}
.ro .ro-n { font-family: var(--mono); color: var(--ink-faint); white-space: nowrap; }
/* The total is the sentence the seven rows above add up to, so it is set off
   rather than styled as an eighth tool. */
.ro .ro-total {
  border-top: 1px solid var(--rule);
  margin-top: 0.4rem;
  padding-top: 0.8rem;
}
.ro .ro-total dt { color: var(--ink); }
.ro .ro-total .ro-n { color: var(--ink); font-weight: 600; }

/* The same component at a wider measure, and the reason is the middle column.
   `.ro-n` is deliberately `nowrap` — a before/after count broken across two
   lines stops reading as one quantity — so a value that does not fit its track
   overflows into the sentence beside it rather than wrapping inside it. 4.75rem
   was sized for "43 → 22"; the measurement tables carry phrases twice that
   long, "launched → not" and "10 of 1,303". Only the tracks change: the 560px
   rule below already collapses `.ro` to two columns with the sentence spanning
   underneath, and it applies here unaltered, so this needs no breakpoint of its
   own. Every table using it sits in a `.panel--wide`, which is what leaves the
   third column its room down to that breakpoint. */
.ro--wide > div { grid-template-columns: 7rem 9rem minmax(0, 1fr); }

/* A panel that carries an argument rather than a setting takes the full row,
   so the grid does not leave a hole beside it on an odd count. */
.panel--wide { grid-column: 1 / -1; }

/* --- exit statuses ------------------------------------------------------ */
/* Its own component rather than .reqs or .ro, and the reason is the first
   column. Both of those size their term for a word — .reqs sets it uppercase at
   7rem, .ro colours it by route at 7rem — and the term here is a single digit
   that a script compares against. Uppercasing it does nothing, 7rem of gutter
   for one character is most of a panel, and a route colour would be a lie:
   an exit status is not a door into your Mac.
   Achromatic for exactly the reason .classes is. The third column is the only
   one that is not obvious from the number, and it is the argument of the whole
   section: nothing but success ever writes to stdout. */
.exits {
  margin: 0 0 0.9rem;
  padding: 0;
  border: 1px solid var(--rule);
  border-radius: 12px;
  background: var(--card);
  overflow: hidden;
}
.exits > div {
  display: grid;
  grid-template-columns: 2rem minmax(0, 1.5fr) minmax(0, 1fr);
  gap: 0.25rem 1.25rem;
  align-items: baseline;
  padding: 0.8rem 1.25rem;
  border-top: 1px solid var(--rule-soft);
}
.exits > div:first-child { border-top: 0; }
.exits dt {
  font: 600 1rem/1.5 var(--mono);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.exits dd { margin: 0; min-width: 0; }
.exits .means { color: var(--ink-dim); font-size: 0.9375rem; line-height: 1.55; }
/* What is on stdout is a fact about a stream, so it keeps the monospace
   vernacular and stays quiet — it is read down the column, not across. */
.exits .out {
  font: 500 0.8125rem/1.6 var(--mono);
  color: var(--ink-faint);
}
/* The digit column never needs to move; it is the two prose columns that run
   out of room, and they give way in the same order .classes's do. */
@media (max-width: 820px) {
  .exits > div { grid-template-columns: 2rem minmax(0, 1fr); }
  .exits .out { grid-column: 2; }
}
@media (max-width: 560px) {
  .exits > div { padding: 0.75rem 1rem; gap: 0.15rem 0.9rem; }
}

/* --- the asymmetry ------------------------------------------------------ */
/* One request, two apps, two different amounts of platform. The shape is the
   point: a question at the top, two answers side by side, and the refusal that
   applies to both underneath. It carries the database route because both tools
   are on it — the colour is still saying what it always says. */
.asym {
  margin-top: 1.25rem;
  border: 1px solid var(--rule);
  border-left: 3px solid var(--route);
  border-radius: 14px;
  background: var(--card);
  overflow: hidden;
}
.asym-q {
  margin: 0;
  padding: 1.1rem 1.5rem;
  font-family: var(--serif);
  font-size: 1.125rem;
  line-height: 1.4;
  color: var(--ink);
  background: var(--card-sunk);
  border-bottom: 1px solid var(--rule-soft);
}
.asym-cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.asym-cols > section { padding: 1.35rem 1.5rem; }
.asym-cols > section + section { border-left: 1px solid var(--rule-soft); }
.asym-cols h3 {
  font: 600 0.9375rem/1.3 var(--mono);
  letter-spacing: -0.02em;
  color: var(--route);
  margin-bottom: 0.55rem;
}
.asym-cols p {
  margin: 0;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--ink-dim);
}
.asym-cols strong { color: var(--ink); font-weight: 600; }
.asym-foot {
  margin: 0;
  padding: 1.2rem 1.5rem 1.35rem;
  border-top: 1px solid var(--rule-soft);
  background: var(--card-sunk);
  font-family: var(--serif);
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--ink-faint);
}

/* --- prompts ------------------------------------------------------------ */

.prompts {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
  gap: 1rem;
}
.prompts li {
  border: 1px solid var(--rule);
  border-left: 3px solid var(--route, var(--rule));
  border-radius: 10px;
  background: var(--card);
  padding: 1.1rem 1.25rem;
}
.prompts .said {
  font-family: var(--serif);
  font-size: 1.0625rem;
  line-height: 1.5;
  color: var(--ink);
  margin: 0 0 0.7rem;
}
.prompts .used {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 0.5rem;
  font: 500 0.75rem/1.5 var(--mono);
  color: var(--ink-faint);
  margin: 0;
}
/* Each mark carries its OWN route, not the card's. A request that reaches
   contacts and messages costs two different permissions, and the whole claim
   of this palette is that the colour says which — so inheriting one colour
   for both would be the page contradicting itself. The card's left border is
   the most expensive route in the request. */
.prompts .used b { color: var(--route); font-weight: 600; }

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

.site-footer {
  border-top: 1px solid var(--rule);
  padding-block: 2.5rem 3.5rem;
  font-size: 0.875rem;
  color: var(--ink-dim);
}
.footer-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem 3rem;
  justify-content: space-between;
  align-items: start;
}
.footer-grid nav { display: flex; flex-wrap: wrap; gap: 0.4rem 1.5rem; }
.site-footer a { color: var(--ink-dim); }
.site-footer a:hover { color: var(--ink); }
.site-footer .colophon {
  margin-top: 1.75rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule-soft);
  font-size: 0.8125rem;
  color: var(--ink-faint);
  max-width: 70ch;
}

/* --- responsive --------------------------------------------------------- */

/* The header carries more links than the bar can hold all the way down, so they
   shed in three steps. The numbers are measured rather than chosen: with every
   link showing, the bar needs 933px, and with the -md group gone it needs 691px
   — sweeping every width from 360 to 1440 found the bar overflowing across
   641–690 and 901–932, two bands that 1440/1180/820/560/390 step straight over.
   Each breakpoint sits clear of its measured floor.

   What drops when: the -md group is the three in-page anchors also spelled out
   and linked in the prose, so nothing becomes unreachable; -sm is the newest
   section and the one a first-time reader needs least; below 640 every in-page
   anchor goes and only Reference and GitHub remain. */
@media (max-width: 980px) {
  .site-nav .nav-hide-md { display: none; }
}
@media (max-width: 780px) {
  .site-nav .nav-hide-sm { display: none; }
}

/* Two columns of prose need about 22rem each before the words start breaking
   badly; below that the answers stack and the divider becomes a horizontal
   rule so the pairing survives. */
@media (max-width: 760px) {
  .asym-cols { grid-template-columns: minmax(0, 1fr); }
  .asym-cols > section + section {
    border-left: 0;
    border-top: 1px solid var(--rule-soft);
  }
}

@media (max-width: 860px) {
  .route { grid-template-columns: minmax(0, 1fr); }
  .route-head {
    border-right: 0;
    border-bottom: 1px solid var(--rule-soft);
    padding: 1.15rem 1.15rem 1.25rem;
  }
  .route-head h3 { margin-top: 0.65rem; }
  .route-tools li { padding: 1rem 1.15rem; }
}

@media (max-width: 640px) {
  .legend-row {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.45rem;
    padding: 1rem 1.05rem;
  }
  /* The header has to survive 320px. In-page anchors are reachable by
     scrolling, so at phone width it keeps only the other page and the toggle;
     the rest of these links are all repeated in the footer. */
  .site-nav { gap: 0.9rem; }
  .site-nav .nav-hide { display: none; }
  .wordmark .ver { display: none; }
  .facts dt { font-size: 1.3rem; }
  .reqs > div { flex-direction: column; gap: 0.1rem; }
  .reqs dt { width: auto; }
}

/* The class table's third column holds identifiers that cannot be hyphenated,
   so it is the first thing to drop to its own line; the meaning follows at the
   width where two columns of prose stop being two columns. */
@media (max-width: 820px) {
  .classes > div { grid-template-columns: 6.5rem minmax(0, 1fr); }
  .classes .eg { grid-column: 2; }
}
@media (max-width: 560px) {
  .classes > div { grid-template-columns: minmax(0, 1fr); gap: 0.15rem; }
  .classes .eg { grid-column: 1; }
}

/* Its own breakpoint, because the .ro grid runs out of room well before the
   400px one: three columns inside a panel leave the last of them under 90px,
   which is narrower than the operation names it has to hold. */
@media (max-width: 560px) {
  .ro > div { grid-template-columns: minmax(0, 1fr) auto; }
  .ro dd:last-child { grid-column: 1 / -1; }
}

@media (max-width: 400px) {
  .site-nav .nav-hide-xs { display: none; }
}

/* --- motion ------------------------------------------------------------- */

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

@media print {
  .site-header, .theme-toggle, .copy { display: none; }
  body { background: #fff; }
}
