
:root{
  /* ground and ink */
  /* The ground is a warm beige, and everything above it is a shade of it: the
     surface is the same hue lifted almost to white, the sunken ground the same
     hue pushed down. A neutral grey card on a warm ground reads as a foreign
     object pasted onto the page, which is what a mid-grey always is. */
  --bg:#E8E1D5;--surface:#FBF9F5;--sunken:#DDD4C4;
  --text:#1A1815;--muted-ink:#56514A;
  --border:#D5CCBB;--border-strong:#C1B6A3;
  /* The edge of anything you can type in or press.
     WCAG 2.2 AA 1.4.11 wants 3:1 for the boundary that identifies a control,
     and --border-strong is 1.8:1 on the surface: perfectly good as a hairline
     between two blocks of content, and not good enough to tell someone where an
     empty text field begins. This is the LIGHTEST value that clears 3:1 on all
     three grounds at once — 3.55:1 on the page, 4.39:1 on the surface and
     3.14:1 on the sunken ground — so a control edge is never heavier than it
     has to be to be findable. */
  --border-control:#7D7464;

  /* The action, and the one accent.

     Two roles, deliberately separated. --action is what a button that DOES
     something is filled with: near-black, because on a warm ground the most
     emphatic thing available is ink, and a saturated fill would be the loudest
     element on every page it appeared on. --accent is what a link, a focus ring
     and the current-page marker are drawn in: a deep slate blue, cool against
     the warm ground so it reads as deliberate rather than as a tint of it.

     Contrast, measured: --on-action on --action = 14.61:1. --accent on --bg =
     7.19:1, on --surface = 8.88:1, on --accent-soft = 7.46:1. */
  --action:#24211C;--action-hover:#3A342C;--on-action:#F7F4EE;
  --accent:#2C4A5E;--accent-hover:#21394A;
  --accent-soft:#DFE7EC;--accent-border:#B6C6D1;

  /* semantic, kept apart from the action and the accent */
  --success-ink:#2C6A46;--success-soft:#DCE9E0;--success-border:#B4CDBF;
  --warning-ink:#7D5A16;--warning-soft:#F0E7D2;--warning-border:#D9C89E;
  --danger-ink:#A3392B;--danger-soft:#F2DFDB;--danger-border:#DCB8B1;
  --info-ink:#2A5C63;--info-soft:#DDE8E9;--info-border:#B3CBCE;

  --focus:#2C4A5E;
  --code-bg:#F3EFE7;
  /* A scrim, not a shadow: it dims the page a modal has taken over from. */
  --scrim:rgba(26,24,21,.46);

  /* The only elevation on the site. A modal has to sit above the page it
     blocks, and a menu above the row it drops out of; nothing else floats. */
  --sh-modal:0 8px 40px rgba(26,24,21,.20);
  --sh-menu:0 4px 20px rgba(26,24,21,.14);

  /* An HTTP method is read before anything else on a reference page, so it is
     coloured by what it does rather than left as another grey chip. Both are
     existing inks: no new hue enters the palette to carry them. GET reads,
     so it takes the accent; POST creates, so it takes the success green. */
  --method-get:var(--accent);--method-get-soft:var(--accent-soft);
  --method-post:var(--success-ink);--method-post-soft:var(--success-soft);

  /* spacing scale. One ladder, so vertical rhythm is a choice made once. */
  --s1:4px;--s2:8px;--s3:12px;--s4:16px;--s5:20px;--s6:24px;--s7:28px;
  --s8:32px;--s10:44px;--s12:64px;--s14:80px;

  /* type scale */
  --t-xs:12px;--t-sm:13.5px;--t-cap:12.5px;--t-base:14.5px;--t-body:16px;
  --t-lg:18.5px;--t-h3:18px;--t-h2:23px;--t-h1:30px;--t-display:38px;
  --t-metric:34px;--t-metric-lg:44px;

  --r-sm:6px;--r-md:8px;--r-lg:10px;--r-pill:999px;
  /* The system stack, deliberately. A webfont costs a request, a render
     delay and a CSP exception, and buys a typeface most readers cannot
     name. This used to read "Inter, ..." with no @font-face and no link
     anywhere in the source, so every visitor got the fallback while the
     declaration claimed otherwise. */
  --font:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",
    Arial,sans-serif;
  --mono:ui-monospace,SFMono-Regular,Menlo,"DejaVu Sans Mono",Consolas,monospace;
  --measure:70ch;

  /* Motion, declared once so "how fast does this site feel" is one edit. */
  --ease:.15s cubic-bezier(.4,0,.2,1);
  --ease-slow:.25s cubic-bezier(.4,0,.2,1);

  /* layout metrics, shared by the shells and the rules that offset from them */
  /* --header is gone with the second chrome it measured. */
  --rail:248px;--topbar:56px;--content:960px;--page:1120px;
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
/* Focus Not Obscured (WCAG 2.2 AA, 2.4.11).
   ONE bar is pinned to the top of the viewport on every page now, so anything
   the browser scrolls to — the next element under Tab, a fragment link like
   /billing#invoices, a scrollIntoView from the search list — arrives underneath
   it unless the scroll container reserves its height. It used to reserve
   --header, the taller of the two bars back when there were two; there is only
   --topbar to clear now, and naming the bar that actually exists is what keeps
   this correct the next time its height changes. */
html{scroll-padding-top:calc(var(--topbar) + var(--s3))}
/* An author rule that sets display outranks the user-agent rule behind the
   hidden attribute, whatever its specificity. Every false banner on the
   dashboard — the deletion notice, the low-balance warning, the empty first-key
   box — was the alert component setting a display of its own and beating
   [hidden]. Stated once, up front, so no component can reintroduce it. */
[hidden]{display:none!important}
/* Sticky footer. The body is the column and main absorbs the slack, so a short
   page still puts the footer on the floor and a long one still scrolls. */
html{height:100%}
body{margin:0;background:var(--bg);color:var(--text);font-family:var(--font);
  font-size:var(--t-body);line-height:1.65;-webkit-font-smoothing:antialiased;
  min-height:100vh;min-height:100dvh;display:flex;flex-direction:column}
main{flex:1 0 auto}
footer.site{flex-shrink:0}
a{color:var(--accent);text-decoration:none}
a:hover{color:var(--accent-hover);text-decoration:underline;text-underline-offset:2px}
:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
h1,h2,h3,h4{font-weight:600;line-height:1.2;letter-spacing:-.02em;margin:0 0 var(--s3);
  text-wrap:balance}
h1{font-size:var(--t-h1);letter-spacing:-.03em}
h2{font-size:var(--t-h2);margin-top:var(--s10)}
h3{font-size:var(--t-h3);margin-top:var(--s7)}
h4{font-size:15.5px}
p{margin:0 0 var(--s4);max-width:var(--measure)}
ul,ol{padding-left:22px;margin:0 0 var(--s4);max-width:var(--measure)}
li{margin:0 0 var(--s2)}
.lede{font-size:var(--t-lg);color:var(--muted-ink);max-width:64ch;margin:0 0 var(--s7)}
.mut{color:var(--muted-ink)}
.small{font-size:var(--t-base)}
.center{text-align:center}
hr{border:0;border-top:1px solid var(--border);margin:var(--s7) 0}
/* The line under a page title that names the account or states the one fact the
   page assumes. It closed the gap to the first card by hand on four pages. */
.pagelead{color:var(--muted-ink);margin:0 0 var(--s6)}

/* ------------------------------------------------------------- layout --- */
.wrap{max-width:var(--page);margin:0 auto;padding:0 var(--s5)}
.wrap.narrow{max-width:760px}
/* A narrow column INSIDE a shell that already supplies the gutter. Settings and
   the auth pages used .wrap.narrow with padding:0 patched on in the markup. */
.pagenarrow{max-width:760px}
main{padding:var(--s8) 0 var(--s14)}
.skip{position:absolute;left:-9999px;top:0;background:var(--surface);padding:var(--s3) var(--s4);
  border-radius:var(--r-sm);z-index:100}
.skip:focus{left:var(--s4);top:var(--s2)}

/* ---------------------------------------------------------------- brand --- */
/* The lockup above the breakpoint, the bird below it. Both are vector and both
   declare their own box, so the bar reserves the right space before either
   lands and the page never shifts. */
.brand{display:flex;align-items:center;flex-shrink:0;color:var(--text)}
.brand:hover{text-decoration:none}
.brand .mark{display:block;height:22px;width:auto}
.brand .mark.compact{display:none;height:24px}


/* The footer sits on the floor on every device: the body is the flex column,
   main absorbs the slack, and margin-top:auto catches the shells that lay their
   own content out in a grid. */
footer.site{border-top:1px solid var(--border);background:var(--surface);padding:var(--s6) 0;
  margin-top:auto;color:var(--muted-ink);font-size:var(--t-base)}
footer.site .wrap{display:flex;flex-wrap:wrap;gap:var(--s2) var(--s6);align-items:center;
  justify-content:space-between}
footer.site nav{display:flex;flex-wrap:wrap;gap:var(--s1) var(--s5);align-items:center}
footer.site a{color:var(--muted-ink);padding:2px 0}
footer.site a:hover{color:var(--text)}
@media(max-width:640px){
  footer.site .wrap{flex-direction:column;align-items:flex-start;gap:var(--s3)}
  footer.site nav{gap:var(--s1) var(--s4)}
}

/* ---------------------------------------------------------------- rail --- */
/* ONE navigation component. The public documentation sidebar and the signed-in
   account rail render the same folders from the same function, so they must not
   be styled by two different rule sets — that is how Integrations came to be
   uppercase and third in one chrome and grey and last in the other. */

.rail details{margin:0 0 2px}
.rail summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:10px;
  padding:9px 10px;border-radius:var(--r-sm);color:var(--muted-ink);
  font-size:var(--t-base);font-weight:500}
.rail summary::-webkit-details-marker{display:none}
.rail summary::after{content:"";margin-left:auto;width:6px;height:6px;
  border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;
  transform:rotate(45deg);transition:transform var(--ease)}
.rail details[open]>summary::after{transform:rotate(-135deg)}
.rail summary:hover{background:var(--sunken);color:var(--text)}
.rail ul{list-style:none;margin:2px 0 var(--s2);padding:0 0 0 22px}
.rail li{margin:0}
.rail li a{display:block;padding:7px 10px;border-radius:var(--r-sm);font-size:14px;
  color:var(--muted-ink);border-left:2px solid transparent}
.rail li a:hover{background:var(--sunken);color:var(--text);text-decoration:none}
.rail li a[aria-current=page]{color:var(--text);font-weight:500;
  background:var(--sunken);border-left-color:var(--accent)}
/* One row per API: the name, its method and path beneath. No folder to open,
   because an API is one page. */
.rail .apiitem{display:flex;flex-direction:column;align-items:flex-start;gap:1px}
.rail .apiitem .name{font-size:14px;font-weight:600;color:var(--text)}
.rail .apiitem .route{font-family:var(--mono);font-size:11.5px;color:var(--muted-ink)}
.rail .apiitem .route b{color:var(--accent);font-weight:700}


/* ----------------------------------------------------- signed-in shell --- */
/* Every signed-in page navigates from one left rail. It scales to more APIs by
   growing a list rather than a header that runs out of horizontal room. */
.app{display:grid;grid-template-columns:1fr;grid-template-rows:auto 1fr;
  flex:1 0 auto;width:100%}
.app-side{background:var(--surface);border-right:1px solid var(--border);
  padding:var(--s5) var(--s3);display:flex;flex-direction:column;gap:2px;min-height:0}
/* Navigation takes the slack and scrolls; whatever is under it stays put. */
.railmain{flex:1 1 auto;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:2px;
  margin:0 calc(var(--s3) * -1);padding:0 var(--s3)}
.app-side>a{display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:var(--r-sm);
  color:var(--muted-ink);font-size:var(--t-base);font-weight:500}
.app-side>a:hover{background:var(--sunken);color:var(--text);text-decoration:none}
.app-side>a[aria-current=page]{background:var(--sunken);color:var(--text);font-weight:600;
  box-shadow:inset 2px 0 0 var(--accent)}
.railmain>a{display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:var(--r-sm);
  color:var(--muted-ink);font-size:var(--t-base);font-weight:500}
.railmain>a:hover{background:var(--sunken);color:var(--text);text-decoration:none}
.railmain>a[aria-current=page]{background:var(--sunken);color:var(--text);font-weight:600;
  box-shadow:inset 2px 0 0 var(--accent)}

/* The foot of the rail. Signed out it is the way in; signed in it is who you
   are. Either way it is the last thing in the column and it does not scroll. */
.railfoot{flex:0 0 auto;border-top:1px solid var(--border);margin:var(--s3) calc(var(--s3) * -1) 0;
  padding:var(--s4) var(--s3) var(--s1)}
.railfoot .btn{width:100%;justify-content:center}
.railfoot .mnote{margin-top:var(--s2);text-align:center;font-size:var(--t-xs)}
.app-main{min-width:0;padding:var(--s7) var(--s5) var(--s12)}
.app-main>.inner{max-width:var(--content);margin:0 auto}
/* The focus shell has no rail, so its content well is not competing with one.
   The landing page was rendering a 960px column inside a viewport twice that
   wide, which left the signup card about 420px to fit a field and a button
   into side by side. */
.app-main>.inner.wide{max-width:var(--page)}

/* --------------------------------------------------------------- topbar --- */
/* Search and identity, on every signed-in page.
 *
 * It spans both columns rather than sitting inside the content well, because a
 * search box that starts where the article starts reads as part of the article.
 * The rail scrolls under it; the bar itself never moves.
 */
.topbar{grid-column:1/-1;position:sticky;top:0;z-index:40;display:flex;align-items:center;
  gap:var(--s3);height:var(--topbar);padding:0 var(--s4);background:var(--surface);
  border-bottom:1px solid var(--border)}
/* Opens the rail on a phone. Three lines, drawn in CSS, so there is no icon
   font to fail to load and no emoji standing in for one. */
.railtoggle{display:none;position:relative;width:36px;height:36px;padding:0;
  background:transparent;border:1px solid var(--border);border-radius:var(--r-sm);
  cursor:pointer;flex-shrink:0}
/* Three bars from one pseudo-element: no child elements to mistake for icons,
   and no background-image, which would mean a gradient. */
.railtoggle::before{content:"";position:absolute;left:50%;top:50%;width:16px;height:1.5px;
  margin:-1px 0 0 -8px;background:var(--text);border-radius:2px;
  box-shadow:0 -5px 0 var(--text),0 5px 0 var(--text)}
.railtoggle:hover{background:var(--sunken)}
/* Pushes what follows to the right edge on a page with no search field. */
.search-spacer{flex:1 1 auto}
.topnav{margin-left:auto;display:flex;align-items:center;gap:var(--s2);flex-shrink:0}
.topnav a:not(.btn){color:var(--muted-ink);font-size:var(--t-base);font-weight:500;
  padding:var(--s2) var(--s3);border-radius:var(--r-sm);white-space:nowrap}
.topnav a:not(.btn):hover{color:var(--text);background:var(--sunken);text-decoration:none}
/* The brand, top-left, in the signed-in chrome too.
   This used to be display:none above the mobile breakpoint, on the assumption
   that the rail carried the mark — and the rail stopped emitting one when the
   top bar was introduced, so a signed-in reader on a desktop got no logo
   anywhere on the page and no way back to the home page except the browser.
   The markup test could not see it: the anchor was in the HTML the whole time,
   hidden by a rule. */
.topbar .brand{flex-shrink:0}
.topbar .brand .mark{width:28px;height:28px}

/* --------------------------------------------------------------- search --- */
/* A combobox over the page registry, shipped inline with the page.
 *
 * Recognition over recall: everything the site can show you is one keystroke
 * and a substring away, and the results say what each destination IS — a guide,
 * an endpoint with its method and path — rather than listing bare titles.
 */
.search{position:relative;flex:1;max-width:520px}
/* The input[type=text] rule in the forms section is 0,1,1 and so was
   ".search input", which means source order decides — and the forms section is further down the
   sheet, so it was winning and the left padding that clears the magnifier never
   applied. The glyph sat on top of the placeholder. Matching the attribute here
   makes the intent explicit rather than dependent on where the rule happens to
   sit in the file. */
.search input[type=text]{width:100%;padding:7px var(--s3) 7px 34px;font-size:var(--t-base);
  border-radius:var(--r-md);background:var(--bg);border:1px solid var(--border-control)}
/* The magnifier is a ring and a handle in pure CSS. */
.search .glass{position:absolute;left:12px;top:50%;width:11px;height:11px;
  margin-top:-7px;border:1.5px solid var(--muted-ink);border-radius:50%;pointer-events:none}
.search .glass::after{content:"";position:absolute;right:-5px;bottom:-4px;width:5px;height:1.5px;
  background:var(--muted-ink);transform:rotate(45deg)}
/* The shortcut is a signifier: it tells you the key exists before you need it.
   Hidden once the field has focus, where it would be describing the state you
   are already in. */
.search kbd{position:absolute;right:10px;top:50%;transform:translateY(-50%);
  font-family:var(--font);font-size:11px;font-weight:600;color:var(--muted-ink);
  background:var(--surface);border:1px solid var(--border);border-bottom-width:2px;
  border-radius:var(--r-sm);padding:1px 6px;pointer-events:none}
.search input:focus~kbd{display:none}
.search .results{position:absolute;top:calc(100% + 6px);left:0;right:0;z-index:50;
  background:var(--surface);border:1px solid var(--border-strong);border-radius:var(--r-md);
  box-shadow:var(--sh-menu);max-height:60vh;overflow-y:auto;padding:var(--s1);margin:0;
  list-style:none}
.search .results li{margin:0}
.search .results a{display:flex;align-items:baseline;gap:var(--s2);padding:var(--s2) 10px;
  border-radius:var(--r-sm);color:var(--text);font-size:14px}
.search .results a:hover,.search .results a[data-active=true]{background:var(--sunken);
  text-decoration:none}
.search .results .rname{font-weight:500}
.search .results .rkind{margin-left:auto;font-size:var(--t-xs);color:var(--muted-ink);
  white-space:nowrap;flex-shrink:0}
.search .results .rroute{font-family:var(--mono);font-size:var(--t-xs);color:var(--muted-ink)}
.search .none{padding:var(--s3) 10px;color:var(--muted-ink);font-size:14px;margin:0}

/* ------------------------------------------------------------ user menu --- */
/* A <details> element, so it opens with no script at all. The account menu used
   to be a bare email in the rail and a sign-out button pinned to the floor
   below it, which put identity and the way out three hundred pixels apart. */
/* Identity at the FOOT of the rail, not in the top-right corner.
   It opens UPWARD, because there is nothing below it to open into. */
.usermenu{position:relative;flex:0 0 auto;border-top:1px solid var(--border);
  margin:var(--s3) calc(var(--s3) * -1) 0;padding:var(--s3) var(--s3) 0}
.usermenu>summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:var(--s3);
  padding:var(--s2);border-radius:var(--r-md);border:1px solid transparent;min-width:0}
.usermenu>summary::-webkit-details-marker{display:none}
.usermenu>summary:hover{background:var(--sunken)}
.usermenu[open]>summary{background:var(--sunken);border-color:var(--border)}
/* Initials, not a photograph we do not have and would not want. */
.avatar{width:26px;height:26px;border-radius:var(--r-pill);background:var(--accent-soft);
  border:1px solid var(--accent-border);color:var(--accent);display:grid;
  place-items:center;font-size:11px;font-weight:700;text-transform:uppercase;flex-shrink:0}
/* The address and the plan, stacked. Both truncate rather than wrap: an email
   long enough to wrap would push the plan out of the rail entirely. */
.usermenu .who{display:flex;flex-direction:column;min-width:0;flex:1 1 auto;line-height:1.3}
.usermenu .mail{font-size:var(--t-sm);color:var(--text);font-weight:500;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.usermenu .plan{font-size:var(--t-xs);color:var(--muted-ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.usermenu .caret{width:5px;height:5px;flex-shrink:0;border-right:1.5px solid var(--muted-ink);
  border-bottom:1.5px solid var(--muted-ink);transform:rotate(-135deg) translate(-2px,-2px)}
.usermenu[open] .caret{transform:rotate(45deg) translate(-1px,-1px)}
/* Bottom, not top: the menu grows up out of the row it belongs to. */
.usermenu .menu{position:absolute;left:var(--s3);right:var(--s3);bottom:calc(100% + 6px);
  z-index:50;background:var(--surface);border:1px solid var(--border-strong);
  border-radius:var(--r-md);box-shadow:var(--sh-menu);padding:var(--s1)}
.usermenu .menu a{display:block;padding:var(--s2) 10px;border-radius:var(--r-sm);
  color:var(--text);font-size:14px}
.usermenu .menu a:hover{background:var(--sunken);text-decoration:none}
.usermenu form{margin:0}
/* Signing out is a form POST, not a click handler. It has to work when a script
   fails to load, which is exactly how it broke. */
.usermenu .out{display:block;width:100%;padding:var(--s2) 10px;border:0;
  border-radius:var(--r-sm);background:transparent;color:var(--danger-ink);font:inherit;
  font-size:14px;font-weight:500;text-align:left;cursor:pointer}
.usermenu .out:hover{background:var(--danger-soft)}

.crumbs{margin:0 0 var(--s6);font-size:13px}
.crumbs ol{list-style:none;display:flex;flex-wrap:wrap;gap:var(--s2);margin:0;padding:0;
  color:var(--muted-ink);max-width:none}
.crumbs li+li::before{content:"/";margin-right:var(--s2);color:var(--border-strong)}

/* --------------------------------------------------------------- cards --- */
/* Flat. A card is a surface with a border on it; nothing here floats. */
.card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);
  padding:var(--s7);margin:0 0 var(--s5)}
.card.flush{padding:0;overflow:hidden}
.card>h2,.card>h3{margin-top:0}
/* A card heading is a label on a panel, not a document heading, so it does not
   take the document scale. Every card in the app used to patch this inline. */
.card>h2{font-size:17px}
.cardhead{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);
  margin-bottom:var(--s4);flex-wrap:wrap}
.cardhead>*{margin:0}
.cardhead h2{font-size:17px}
/* A flush card owns no padding, so its own head and foot supply theirs. */
.card.flush>.cardhead{padding:var(--s6) var(--s6) 0;margin-bottom:var(--s4)}
.card.flush>.cardfoot{padding:var(--s4) var(--s6) var(--s6)}
.card.flush>.cardfoot>:last-child{margin-bottom:0}
.ctitle{font-size:var(--t-cap);font-weight:600;text-transform:uppercase;letter-spacing:.08em;
  color:var(--muted-ink);margin:0 0 var(--s3)}

.mnote{margin:var(--s2) 0 0;font-size:var(--t-base);color:var(--muted-ink)}
/* The one big number on a status module: the plan price, the checks remaining.
   The .metric tiles that used to surround it are gone — the dashboard answers
   one question in one module rather than spreading it across a row of cards —
   but the figure itself is still the largest thing on both pages. */
.mvalue{font-size:var(--t-metric);font-weight:600;letter-spacing:-.03em;line-height:1.1;margin:0;
  font-variant-numeric:tabular-nums}

/* ------------------------------------------------------------- buttons --- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--s2);
  border:1px solid transparent;border-radius:var(--r-md);padding:11px var(--s4);
  font-family:inherit;font-size:var(--t-base);font-weight:600;line-height:1.2;cursor:pointer;
  text-decoration:none;transition:background-color var(--ease),border-color var(--ease),
  color var(--ease)}
.btn:hover{text-decoration:none}
.btn:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.btn:disabled,.btn[aria-disabled=true]{opacity:.5;cursor:not-allowed}
.btn.primary{background:var(--action);color:var(--on-action);border-color:var(--action)}
.btn.primary:hover{background:var(--action-hover);border-color:var(--action-hover)}
.btn.secondary{background:var(--surface);color:var(--text);border-color:var(--border-control)}
.btn.secondary:hover{background:var(--sunken)}
.btn.danger{background:var(--danger-ink);color:var(--surface);border-color:var(--danger-ink)}
.btn.danger:hover{background:var(--text);border-color:var(--text)}
/* A ghost button is a text action, so it is signified as one. Muted grey with
   no underline made the whole alternate sign-in path on the login page read as
   a caption under the primary button, and made "Remove" in the saved-card table
   read as a column value rather than something you can press. */
.btn.ghost{background:transparent;color:var(--accent);font-weight:500;
  text-decoration:underline;text-underline-offset:3px}
.btn.ghost:hover{background:var(--sunken);color:var(--text);text-decoration:underline}
.btn.sm{padding:7px var(--s3);font-size:var(--t-sm);border-radius:var(--r-sm)}
.btn.lg{padding:var(--s3) var(--s6);font-size:var(--t-body)}
/* A full-width button must be BLOCK-level, not a 100%-wide inline one.
   The base rule is inline-flex, so width:100% alone left the button sitting on
   the baseline of an anonymous line box, which adds leading above it and
   descender space below. That phantom space is what made the "or" between the
   two sign-in options look like it was floating in a gap nobody asked for; the
   separator's own margins were never the problem. */
.btn.block{display:flex;width:100%}
.btnrow{display:flex;flex-wrap:wrap;gap:var(--s3);align-items:center}
/* A dialog's own actions sit at its trailing edge, where the eye leaves. */
.btnrow.end{justify-content:flex-end}
.btn.google{background:var(--surface);color:var(--text);border-color:var(--border-control)}
.btn.google svg{width:18px;height:18px}
/* The separator between the two ways in.
   A rule with the word set into it, rather than a word alone on a line: a
   centred "or" with space above and below reads as a gap in the form, where a
   ruled divider reads as the boundary between two alternatives — which is what
   it is. The rules are drawn with a flex sibling each side, so the word stays
   centred whatever its language renders as. */
.or{display:flex;align-items:center;gap:var(--s3);text-align:center;
  font-size:var(--t-sm);color:var(--muted-ink);margin:var(--s4) 0;
  text-transform:uppercase;letter-spacing:.08em}
.or::before,.or::after{content:"";flex:1 1 auto;height:1px;background:var(--border)}

/* --------------------------------------------------------------- forms --- */
.field{margin-bottom:var(--s4)}
label{display:block;font-size:var(--t-base);font-weight:500;color:var(--text);
  margin-bottom:var(--s2)}
.hint{display:block;font-size:var(--t-sm);color:var(--muted-ink);margin-top:var(--s2)}
input[type=text],input[type=email],input[type=password],input[type=number],input[type=date],
select,textarea{width:100%;background:var(--surface);color:var(--text);
  border:1px solid var(--border-control);border-radius:var(--r-md);padding:11px var(--s3);
  font-family:inherit;font-size:var(--t-base);line-height:1.4;
  transition:border-color var(--ease),box-shadow var(--ease)}
/* A focused field keeps the site-wide outline. It used to remove it and put a
   3px pale ring in its place, which was 1.02:1 against the page — not
   a focus indicator, a suggestion of one. The border darkening is the extra
   affordance; the outline is the one that has to be there. */
input:focus,select:focus,textarea:focus{border-color:var(--accent)}
input[aria-invalid=true]{border-color:var(--danger-ink)}
textarea{min-height:90px;resize:vertical;font-family:var(--mono);font-size:var(--t-sm)}
.check{display:flex;align-items:flex-start;gap:var(--s3);font-size:var(--t-base);
  font-weight:400;cursor:pointer}
.check input{width:18px;height:18px;margin:2px 0 0;accent-color:var(--accent);flex-shrink:0}
.row{display:flex;gap:var(--s3);align-items:flex-start}
.row>*{flex:1}
.row>.btn{flex:0 0 auto}
/* A row that would rather wrap than squeeze. The signup field and its button
   sat side by side at any width, so on a narrow card the field shrank until an
   address no longer fit in it. Below the basis the button drops to its own
   line, full width, which is where a primary action belongs anyway. */
.row.wrap{flex-wrap:wrap}
.row.wrap>.field{flex:1 1 16rem;min-width:0}
.row.wrap>.btn{flex:1 1 auto}
/* A field on a single-line row carries no bottom margin: the row spaces it.
   Every such field in the app used to say style="margin:0" to get here. */
.row>.field{margin-bottom:0}
.split{display:grid;grid-template-columns:1fr;gap:var(--s4)}

/* A password you can look at. The button sits inside the field's own wrapper so
   it lands in the same place on every form. */
.pw{position:relative}
.pw input{padding-right:74px}
.reveal{position:absolute;right:6px;top:50%;transform:translateY(-50%);background:transparent;
  border:0;border-radius:var(--r-sm);padding:6px 10px;font:inherit;font-size:13px;font-weight:600;
  color:var(--muted-ink);cursor:pointer}
.reveal:hover{color:var(--text);background:var(--sunken)}

.strength{height:6px;border-radius:var(--r-pill);background:var(--border);overflow:hidden;
  margin-top:var(--s3)}
.strength i{display:block;height:100%;width:0;border-radius:var(--r-pill);
  background:var(--danger-ink);transition:width var(--ease-slow),background-color var(--ease-slow)}
.strength[data-level="1"] i{width:25%}
.strength[data-level="2"] i{width:50%;background:var(--warning-ink)}
.strength[data-level="3"] i{width:78%;background:var(--success-ink)}
.strength[data-level="4"] i{width:100%;background:var(--success-ink)}
.rules{list-style:none;padding:0;margin:var(--s3) 0 0;font-size:var(--t-sm);color:var(--muted-ink)}
.rules li{display:flex;align-items:center;gap:var(--s2);margin:0 0 var(--s1)}
.rules li::before{content:"\25CB";color:var(--muted-ink)}
.rules li[data-met=true]{color:var(--success-ink)}
.rules li[data-met=true]::before{content:"\25CF";color:var(--success-ink)}

/* -------------------------------------------------------------- alerts --- */
/* One quiet surface with a coloured mark, rather than a block of flat colour or
   a fade. The old solid-green panel shouted at the reader for the crime of
   succeeding. */
.alert{position:relative;border:1px solid var(--border);border-radius:var(--r-md);
  padding:var(--s3) var(--s4) var(--s3) 46px;margin:0 0 var(--s4);font-size:var(--t-base);
  background:var(--surface);color:var(--text);max-width:var(--measure)}
.alert::before{content:"\2022";position:absolute;left:var(--s3);top:13px;width:22px;height:22px;
  border-radius:var(--r-pill);display:grid;place-items:center;font-size:var(--t-xs);
  font-weight:700;line-height:1;background:var(--sunken);color:var(--muted-ink)}
.alert p{margin:0;color:var(--muted-ink);max-width:none}
.alert p+p{margin-top:var(--s2)}
.alert b{display:block;margin-bottom:3px;font-weight:600;color:var(--text)}
.alert .btn{margin-top:var(--s1)}
/* Success is text. A green panel with a tick in it treats "that worked" as an
   event worth interrupting the page for, and it sat flush against whatever it
   was confirming. */
.alert.ok{border:0;box-shadow:none;background:none;padding:0;margin:var(--s5) 0 0;
  color:var(--success-ink);font-weight:500}
.alert.ok::before{content:none}
.alert.ok p{color:var(--success-ink)}
.alert.warn{border-color:var(--warning-border);background:var(--warning-soft)}
.alert.warn::before{content:"!";background:var(--surface);color:var(--warning-ink)}
.alert.bad{border-color:var(--danger-border);background:var(--danger-soft)}
.alert.bad::before{content:"\00D7";font-size:15px;background:var(--surface);color:var(--danger-ink)}
.alert.info{border-color:var(--info-border);background:var(--info-soft)}
.alert.info::before{content:"i";font-style:italic;background:var(--surface);color:var(--info-ink)}

.badge{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:var(--r-pill);
  font-size:var(--t-cap);font-weight:600;white-space:nowrap}
.badge.ok{background:var(--success-soft);color:var(--success-ink)}
.badge.warn{background:var(--warning-soft);color:var(--warning-ink)}
.badge.bad{background:var(--danger-soft);color:var(--danger-ink)}
.badge.neutral{background:var(--sunken);color:var(--muted-ink)}
.badge.info{background:var(--info-soft);color:var(--info-ink)}

/* The verb, set apart from the noun. Monospace and boxed, because it is part of
   the request line and not a status word. */
.method{display:inline-block;font-family:var(--mono);font-size:var(--t-xs);font-weight:700;
  letter-spacing:.04em;padding:3px var(--s2);border-radius:var(--r-sm);flex-shrink:0}
.method.get{background:var(--method-get-soft);color:var(--method-get)}
.method.post{background:var(--method-post-soft);color:var(--method-post)}

/* --------------------------------------------------------------- table --- */
.scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
table{width:100%;border-collapse:collapse;font-size:var(--t-base)}
th{text-align:left;font-size:var(--t-xs);font-weight:600;text-transform:uppercase;
  letter-spacing:.07em;color:var(--muted-ink);padding:var(--s3) var(--s4);
  border-bottom:1px solid var(--border-strong);white-space:nowrap;background:var(--sunken)}
td{padding:var(--s3) var(--s4);border-bottom:1px solid var(--border);vertical-align:middle}
tbody tr:last-child td{border-bottom:0}
tbody tr:hover{background:var(--sunken)}
.num{text-align:right;font-variant-numeric:tabular-nums}
.sub{display:block;font-size:13px;color:var(--muted-ink)}

/* ---------------------------------------------------------- components --- */
/* The track is bordered so the meter's full extent is visible, not only the
   part that is filled. Gold on the track is 1.57:1, which is under 1.4.11's
   3:1 — the balance is stated in text directly above and broken down in the
   list below, so the bar is a summary of something already readable rather
   than the only way to get it, but a fill with no visible end is a fill you
   cannot judge a proportion against. */
.meter{height:10px;border-radius:var(--r-pill);background:var(--border);overflow:hidden;
  border:1px solid var(--border-control);margin:var(--s3) 0 var(--s2)}
/* Zero by default. The fill is a block element, so without this a page whose
   script never ran would paint a full meter — and of the two ways that lie can
   fall, "you have plenty of quota left" is the expensive one. */
.meter i{display:block;width:0;height:100%;border-radius:var(--r-pill);
  background:var(--action);transition:width .4s}
.meter.low i{background:var(--danger-ink)}
.secret{display:flex;align-items:center;gap:var(--s3);background:var(--sunken);
  border:1px solid var(--border-strong);border-radius:var(--r-md);padding:var(--s3) var(--s4);
  font-family:var(--mono);font-size:var(--t-base);word-break:break-all;margin:var(--s3) 0}
.secret span{flex:1}

.block{position:relative;margin:0 0 var(--s6)}
pre{background:var(--code-bg);border:1px solid var(--border);border-radius:var(--r-md);
  padding:var(--s4);margin:0;overflow-x:auto;font-family:var(--mono);font-size:var(--t-sm);
  line-height:1.65}
code{font-family:var(--mono)}
p code,li code,td code{background:var(--sunken);border:1px solid var(--border);border-radius:4px;
  padding:1px 5px;font-size:13px}
/* Visible at rest. It used to sit at zero opacity until the block was hovered,
   which meant that on a phone — where there is no hover — the primary
   affordance of a documentation page did not exist. */
.copy{position:absolute;top:var(--s2);right:var(--s2);background:var(--surface);
  color:var(--muted-ink);border:1px solid var(--border);border-radius:var(--r-sm);
  padding:4px 9px;font:inherit;font-size:var(--t-xs);cursor:pointer;opacity:.65;
  transition:opacity var(--ease),color var(--ease)}
.block:hover .copy,.copy:hover,.copy:focus-visible{opacity:1;color:var(--text)}
.copy[data-state=copied]{color:var(--success-ink);border-color:var(--success-border);opacity:1}
.tabs{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 var(--s3)}
.tabs button{background:transparent;color:var(--muted-ink);border:1px solid var(--border);
  border-radius:var(--r-sm);padding:6px var(--s3);font:inherit;font-size:13px;cursor:pointer}
.tabs button:hover{background:var(--sunken);color:var(--text)}
.tabs button[aria-selected=true]{color:var(--text);background:var(--sunken);
  border-color:var(--border-strong);font-weight:600}
[data-snippet][hidden]{display:none}

/* ------------------------------------------------------------- plans --- */
/* Three cards, one row on a wide screen, stacked below the breakpoint. They
   replaced a grid of selectable price rungs and a dialog: there is no amount to
   choose any more, so there is nothing to select and nothing to confirm. */
.plans{display:grid;grid-template-columns:1fr;gap:var(--s4);margin:0 0 var(--s7)}
.plan{display:flex;flex-direction:column;margin:0}
.plan .mvalue{font-size:var(--t-metric-lg);margin:0 0 var(--s1)}
/* The interval rides on the price at reading size, so "£49/month" is one fact
   rather than a number and a separate label to pair up. */
.plan .per{font-size:var(--t-base);font-weight:400;color:var(--muted-ink);margin-left:2px}
.plan .ticks{flex:1}
.plan .btn{width:100%;justify-content:center;margin-top:var(--s5)}
.plan .mnote:last-child{margin-top:var(--s5)}
/* A feature list, marked with a typographic bullet from CSS rather than a
   glyph in the markup: the content is the feature, not the mark beside it. */
.ticks{list-style:none;margin:var(--s4) 0 0;padding:0;font-size:var(--t-base);
  display:flex;flex-direction:column;gap:var(--s2)}
.ticks li{margin:0;padding-left:var(--s5);position:relative;color:var(--muted-ink)}
.ticks li::before{content:"\2014";position:absolute;left:0;color:var(--border-strong)}

.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:var(--s3);
  margin:0 0 var(--s7)}
.grid a{display:block;border:1px solid var(--border);border-radius:var(--r-md);padding:var(--s4);
  background:var(--surface);color:var(--text);font-size:var(--t-base);font-weight:500;
  transition:border-color var(--ease),background-color var(--ease)}
.grid a:hover{border-color:var(--border-strong);background:var(--sunken);text-decoration:none}
.grid a span{display:block;color:var(--muted-ink);font-size:var(--t-sm);font-weight:400;
  margin-top:var(--s1)}
/* An endpoint card leads with its method, so the catalogue is scannable by what
   each call does rather than by what it is called. */
.grid a .route{display:flex;align-items:center;gap:var(--s2);margin-top:6px;
  font-family:var(--mono);font-size:var(--t-xs);color:var(--muted-ink);font-weight:400}

/* ---------------------------------------------------------------- docs --- */
.pagehead{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--s4);
  flex-wrap:wrap}
.pagehead h1{margin-bottom:10px}
/* The plan badge rides with the heading rather than at the top of the row, so
   it reads as an attribute of the page rather than a control beside it. */
.pagehead>.badge{margin-top:6px}
.copypage{flex-shrink:0}
/* The request line: method, then the URL it is sent to. */
.routeline{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap;margin:0}
.routeline .url{font-family:var(--mono);font-size:var(--t-base);word-break:break-all}
/* One question, one answer, a hairline between. The answers are written to be
   liftable verbatim, which is what a featured snippet does with them. */
.faq{border-top:1px solid var(--border);padding:var(--s4) 0 0;margin:0 0 var(--s4)}
.faq h3{margin:0 0 var(--s2);font-size:16.5px}
.faq p{margin:0;color:var(--muted-ink)}

/* A filter over the rail, in both chromes. Typing narrows the folders to what
   matches; clearing restores them. */
.railsearch{margin:0 0 var(--s3)}
.railsearch input[type=text]{padding:7px var(--s3);font-size:14px}
.rail .norail{padding:var(--s3) 10px;margin:0;font-size:14px;color:var(--muted-ink)}

/* ------------------------------------------------------- usage status --- */
/* Named for the module, not for what the product once sold. The class was
   .credits, which is the kind of name a reader has to open the markup to
   interpret once the thing it names no longer exists. */
/* One module answering one question. The number is the largest thing on the
   page; the two sources sit under it with their meaning attached. */
.usage{margin-bottom:var(--s6)}
/* The split below the usage module: two summaries, side by side above the
   breakpoint and stacked below it. Both stretch, so their heads line up. */
.split>.card{margin-bottom:0;display:flex;flex-direction:column}
.usage .mvalue{font-size:var(--t-metric-lg);margin:0 0 var(--s1);overflow-wrap:anywhere}
.usage .meter{margin:var(--s2) 0 var(--s5)}
.sources{display:grid;grid-template-columns:1fr;gap:var(--s4) var(--s8);margin:0;
  padding-top:var(--s5);border-top:1px solid var(--border)}
/* A grid item's default min-width is auto, which is its CONTENT width, so a
   long value — a six-figure count, an unabbreviated plan name — pushes the
   column wider than its track and the row overflows the card to the left. That
   is what cut the left half off the metric this replaced. */
.sources>div{min-width:0}
.sources dd{overflow-wrap:anywhere}
.sources dt{font-size:var(--t-cap);font-weight:600;text-transform:uppercase;letter-spacing:.08em;
  color:var(--muted-ink);margin:0 0 var(--s1)}
.sources dd{margin:0;font-size:19px;font-weight:600;font-variant-numeric:tabular-nums}
.sources .mnote{margin:2px 0 0;font-size:13px}
.usage .btnrow{margin-top:var(--s5)}
/* ------------------------------------------------------- dashboard rows --- */
/* A quiet link in a card heading, for the page that owns the thing the card is
   summarising. Not a button: it is a way out, not the action. */
.ghostlink{font-size:var(--t-sm);font-weight:500;color:var(--accent);white-space:nowrap}

/* One key per row: what it is on the left, what it is doing on the right. */
.keyrow{display:flex;align-items:center;justify-content:space-between;gap:var(--s4);
  padding:var(--s3) 0;border-bottom:1px solid var(--border);min-width:0}
.keyrow:last-child{border-bottom:0;padding-bottom:0}
.keyrow-main{display:flex;flex-direction:column;gap:2px;min-width:0}
.keyrow-main b{font-size:var(--t-base);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.keyrow-main code{font-size:var(--t-xs);background:transparent;border:0;padding:0;
  color:var(--muted-ink)}
.keyrow-meta{display:flex;align-items:center;gap:var(--s3);flex-shrink:0}

/* The plan, in one line: what it is called and what it costs. */
.planline{margin:0 0 var(--s3);font-size:var(--t-lg)}
.planline b{font-weight:600}
.planline .mut{font-size:var(--t-base);font-weight:400}
#plan-body .ticks,#plan-body .btn{margin-top:var(--s4)}
#plan-body .btn{width:100%;justify-content:center}

/* The one thing to do next, when there is one. It sits under the meter because
   that is where the reader already is when they learn they need it. */
.nextstep{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s3);margin:0 0 var(--s7);
  padding:var(--s5) var(--s6);background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r-lg)}
.nextstep p{margin:0;flex:1;min-width:220px}
.nextstep b{display:block;font-weight:600}
.nextstep .mut{font-size:var(--t-base)}

/* --------------------------------------------------------- quickstart --- */
/* A numbered column, so "where am I" is answered by the shape of the page and
   not by reading. Each step owns one decision and nothing else. */
.steps{display:flex;flex-direction:column;gap:10px;margin:var(--s7) 0 var(--s10)}
.step{display:grid;grid-template-columns:36px minmax(0,1fr);gap:var(--s4);align-items:start}
.stepno{width:32px;height:32px;border-radius:var(--r-pill);display:grid;place-items:center;
  background:var(--action);color:var(--on-action);font-weight:700;font-size:15px;margin-top:2px}
.stepbody{min-width:0}
.step h2{margin:var(--s1) 0 10px;font-size:20px}
.step .card{margin-bottom:var(--s3)}
/* The try-it panel: key, language tabs, request, one button. */
.tryit .tabs{margin-top:var(--s4)}
.tryit textarea{margin-bottom:var(--s4)}
.tryit label{margin-top:0}
.failed{color:var(--danger-ink);margin:0}
/* Every console paints all three states. The result pane used to be an empty
   div, so "not run yet" and "the request failed silently" looked identical. */
.result{margin:var(--s3) 0 0;font-size:var(--t-base)}
.result .status{margin:0 0 var(--s2);font-size:var(--t-sm);color:var(--muted-ink)}
.result .status b{display:inline-block;padding:2px var(--s2);border-radius:var(--r-sm);
  font-family:var(--mono);margin-right:var(--s1)}
.result .status b.ok{background:var(--success-soft);color:var(--success-ink)}
.result .status b.bad{background:var(--danger-soft);color:var(--danger-ink)}
.result .idle{margin:0;color:var(--muted-ink)}

/* ------------------------------------------------------------- landing --- */
/* The hero is the first screen and should use it: the claim and the form sit
   side by side above the fold, and the demos below are proof rather than pitch.
   It used to be a single 18-character column with the strongest line on the
   page set as a muted 13px label above the headline. */
.hero{display:grid;grid-template-columns:1fr;gap:var(--s8);align-items:center;
  padding:var(--s6) 0 var(--s12)}
.hero h1{font-size:var(--t-display);letter-spacing:-.035em;margin:0 0 var(--s5);
  max-width:none;line-height:1.04}
/* The question the product answers, set apart from the claim that precedes it.
   Not italic for decoration: it is a different kind of sentence, and the accent
   marks it as the one the reader is meant to finish reading with. */
.hero h1 em{font-style:normal;color:var(--accent)}
.hero .lede{font-size:19px;margin:0;max-width:52ch}
.herotext{min-width:0}
.getkey{border-color:var(--border-strong);margin:0}
.getkey h2{margin:0 0 var(--s2);font-size:21px}
.getkey .row{margin-top:var(--s4)}
/* The three facts, once, beneath the ask. Separated by rules rather than by
   ticks: a checkmark beside "no credit card required" is decoration pretending
   to be information. */
/* Separated by a trailing mark rather than a leading rule. A border-left on
   every item but the first is correct only while the row fits on one line: the
   moment the third fact wrapped, it began the new line with a vertical rule
   attached to nothing, which reads as a tick or a stray glyph. A separator that
   trails its own item stays attached to that item wherever the line breaks. */
.facts{list-style:none;display:flex;flex-wrap:wrap;gap:4px var(--s3);margin:var(--s5) 0 0;
  padding:0;font-size:var(--t-base);color:var(--muted-ink);max-width:none}
.facts li{margin:0;display:flex;gap:var(--s3)}
.facts li:not(:last-child)::after{content:"\00B7";color:var(--border-strong)}
.demos h2{margin-top:0}
/* Both demo cards are built the same way, so they line up: title, one line,
   one control row of equal height, one output pane of equal height, meta. */
.demo{display:flex;flex-direction:column;margin:0}
.demo h3{margin:0 0 6px;font-size:var(--t-body)}
.demo>p.small{margin:0 0 var(--s4);min-height:44px}
.demorow{display:flex;gap:var(--s3);align-items:center;margin:0 0 var(--s4);min-height:44px}
.demorow .field{flex:1;margin:0}
.demorow .btn{flex:0 0 auto}
.demo pre{background:var(--code-bg);min-height:132px;max-height:240px;overflow:auto;
  font-size:13px;flex:1}
.demometa{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center;
  gap:var(--s2);margin:var(--s3) 0 0;padding-top:var(--s3);border-top:1px solid var(--border);
  font-size:13px;color:var(--muted-ink);max-width:none}
.demometa code{background:var(--sunken);border:1px solid var(--border);border-radius:4px;
  padding:1px 6px;font-size:var(--t-cap)}

/* The danger zone is marked by its border and its button, not by a wash of
   colour behind the text. */
.zone{border-color:var(--danger-border)}
.zone>h2{color:var(--danger-ink)}

dialog{border:1px solid var(--border-strong);border-radius:var(--r-lg);box-shadow:var(--sh-modal);
  padding:var(--s7);max-width:460px;width:calc(100% - var(--s8));color:var(--text);
  background:var(--surface)}
dialog::backdrop{background:var(--scrim)}
dialog h3{margin-top:0}
dialog>h3.bad{color:var(--danger-ink)}

.filters{display:flex;flex-wrap:wrap;gap:var(--s3);align-items:flex-end;margin-bottom:var(--s4)}
.filters .field{margin:0;min-width:150px}
/* Question and answer, on the pricing page. A definition list would be more
   semantic if the questions were terms; they are headings, so they are. */
.qa{padding:var(--s6)}
.qa h3{font-size:var(--t-h3);margin:0 0 var(--s2)}
.qa h3+p{margin:0 0 var(--s6)}
.qa>p:last-child{margin-bottom:0}
.empty{text-align:center;padding:var(--s12) var(--s4);color:var(--muted-ink)}
.empty h3{color:var(--text);margin:0 0 var(--s2)}
.empty p{max-width:none}
.hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}

@media(prefers-reduced-motion:reduce){*{animation-duration:.01ms!important;
  transition-duration:.01ms!important}}

/* ---------------------------------------------------------- breakpoints --- */
/* ONE threshold for both chromes. The header used to collapse at 820px and the
   rail at 900px, so between the two the page was half mobile and half desktop. */
@media(max-width:900px){
  h1{font-size:27px}
  .hero h1{font-size:30px;max-width:20ch}
  .hero{padding:var(--s2) 0 var(--s8);gap:var(--s6)}
  .lede,.hero .lede{font-size:16.5px}
  td,th{padding:var(--s3)}
  /* The lockup gives way to the bird. Below this width the bar also carries a
     menu control and a search field, and a 7:1 lockup squeezed in beside them
     is lettering nobody can read. */
  .brand .mark.full{display:none}
  .brand .mark.compact{display:block}
  .topnav a:not(.btn){display:none}
  /* The rail becomes a drawer. It used to become a horizontal wrapping row of
     every destination plus four dropdown folders, which on a narrow screen was
     a block of navigation three rows deep above every page. */
  .railtoggle{display:flex}
  .app-side{position:fixed;top:0;left:0;bottom:0;width:min(86vw,var(--rail));z-index:60;
    overflow-y:auto;border-right:1px solid var(--border);box-shadow:var(--sh-modal);
    transform:translateX(-100%);transition:transform var(--ease-slow);visibility:hidden}
  .app-side[data-open=true]{transform:none;visibility:visible}
  /* The scrim is the affordance for closing it: tapping the page you can still
     see is what people try first. */
  .railscrim{position:fixed;inset:0;z-index:50;background:var(--scrim);border:0;
    padding:0;cursor:pointer}
  .app-main{padding:var(--s6) var(--s4) var(--s12)}
  .search kbd{display:none}
  .usermenu .menu{min-width:220px}
}
@media(min-width:901px){
  main{padding:var(--s12) 0 var(--s14)}
  h1{font-size:34px}
  .hero{grid-template-columns:1.05fr .95fr;gap:56px;padding:var(--s10) 0 var(--s12)}
  .hero h1{font-size:52px}
  .plans{grid-template-columns:repeat(3,1fr)}
  .split{grid-template-columns:1fr 1fr}
  .sources{grid-template-columns:1fr 1fr}
  .app{grid-template-columns:var(--rail) minmax(0,1fr)}
  /* The focus shell has no rail, so its single column spans the whole width. */
  .app.focus{grid-template-columns:minmax(0,1fr)}
  /* The rail starts under the bar and scrolls independently of it. */
  /* The rail is a full-height column: navigation scrolls, identity stays
     pinned to the floor. It cannot scroll as one block, or the account menu
     would sit below the fold on any page with enough reference rows. */
  .app-side{position:sticky;top:var(--topbar);height:calc(100vh - var(--topbar));
    height:calc(100dvh - var(--topbar));padding:var(--s6) var(--s3) var(--s3)}
  .app-main{padding:var(--s10) var(--s8) var(--s14)}
  .topbar{padding:0 var(--s6)}
  /* The drawer scrim has no job on a desktop, where the rail is always there. */
  .railscrim{display:none}
}
