/* BalanceProof — the API dashboard, and the accuracy banner on the home page.
   ---------------------------------------------------------------------------
   Same material as everything else: one soft grey sheet, things raised or
   pressed into it by light, and NO colour that is not carrying data. That rule
   is why the tier tiles and the usage meter are grey rather than the green and
   amber a billing screen usually reaches for -- on this site, saturation means
   a balance sheet, and a subscription state that borrowed it would compete with
   the drawings for the eye.

   The two exceptions are earned. The usage meter turns red at 100% because a
   spent allowance is the one state on this page that stops the API working, and
   "unlocked" goes blue because it is the thing somebody paid for. Everything
   else stays ink and grey.

   Loaded after company.css, whose tokens it uses. */

/* The `hidden` attribute only carries `display:none` from the UA stylesheet, so
   ANY author `display` rule beats it -- `.tabs{display:flex}` silently made
   `<div hidden>` visible, which showed the whole signed-in dashboard to signed-
   out visitors. Every panel on these pages is toggled by `hidden`, so the
   attribute is made to win once here rather than remembered at each rule. */
[hidden]{display:none!important}

/* ---- shared controls ---- */
.btn{font:600 14px/1 var(--disp);letter-spacing:.01em;color:var(--ink);
  background:var(--bg);border:0;border-radius:999px;padding:13px 22px;
  box-shadow:var(--up-sm);cursor:pointer;
  transition:box-shadow .18s,transform .1s}
.btn:hover{box-shadow:var(--up)}
.btn:active{transform:translateY(1px);box-shadow:var(--up-sm)}
.btn:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
.btn[disabled]{color:var(--dim);cursor:default;box-shadow:var(--in-sm)}
.btn.wide{width:100%;padding:16px 22px;font-size:15px}

/* A button that reads as prose, for the secondary escape hatches ("paste a
   key", "forget this key"). A real <button> rather than an <a href="#"> so it
   is announced as an action and does not push a junk history entry. */
.linkish{font:inherit;color:var(--ink);background:none;border:0;padding:0;
  cursor:pointer;border-bottom:1px solid var(--lo)}
.linkish:hover{border-bottom-color:var(--ink)}
.linkish:focus-visible{outline:2px solid var(--ink);outline-offset:2px}

.formnote{margin:12px 2px 0;font-size:13.5px;line-height:1.5;color:var(--ink2);
  min-height:1.2em}
.formnote.bad{color:var(--red);font-weight:500}
.formnote.good{color:var(--ink);font-weight:500}
.mail{color:var(--ink);text-decoration:none;border-bottom:1px solid var(--lo)}
.mail:hover{border-bottom-color:var(--ink)}

/* ---- the key itself ---- */
.keyrow{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
/* Pressed into the sheet, like the search field: this is a value being held,
   not a control. `break-all` because a 43-character token has no spaces in it
   and would otherwise run off a phone. */
.keybox{flex:1;min-width:0;font:700 13px/1.5 var(--mono);color:var(--ink);
  background:var(--well);border-radius:var(--r1);padding:14px 16px;
  box-shadow:var(--in-sm);word-break:break-all}

/* ---- status tiles ---- */
.tiles{display:grid;grid-template-columns:1fr;gap:12px}
.tile{background:var(--bg);border-radius:var(--r2);box-shadow:var(--up-sm);
  padding:16px 18px;display:flex;flex-direction:column;gap:3px}
.tlabel{font-size:11.5px;font-weight:500;letter-spacing:.04em;
  text-transform:uppercase;color:var(--ink2)}
.tval{font:700 20px/1.2 var(--mono);color:var(--ink)}
.tval.good{color:var(--blue)}
.tval.muted{color:var(--ink2)}
.tsub{font-size:12.5px;color:var(--ink2)}

/* The same fraction as the tile above it, in a shape read without arithmetic. */
.meter{margin-top:14px;height:10px;border-radius:999px;background:var(--well);
  box-shadow:var(--in-sm);overflow:hidden}
.meter i{display:block;height:100%;border-radius:999px;background:var(--ink2);
  transition:width .3s ease}
.meter i.warn{background:var(--ink)}
.meter i.full{background:var(--red)}

/* ---- copyable example ---- */
.code{margin:0 0 16px;background:var(--well);border-radius:var(--r1);
  box-shadow:var(--in-sm);padding:16px 18px;overflow-x:auto}
.code code{font:400 12.5px/1.7 var(--mono);color:var(--ink);white-space:pre}
.sec-sub code{font-family:var(--mono);font-size:12.5px;
  background:var(--well);border-radius:6px;padding:2px 6px}

/* ---- the paywall dialog ---- */
.modal{position:fixed;inset:0;z-index:200;display:flex;align-items:center;
  justify-content:center;padding:20px;background:rgba(34,38,47,.45)}
.sheet{width:100%;max-width:440px;background:var(--bg);border-radius:var(--r3);
  box-shadow:var(--up-lg);padding:28px 24px 24px}
.sheet h2{margin:0 0 12px;font-size:21px;font-weight:600;letter-spacing:-.02em}
.sheet p{margin:0 0 16px;font-size:15px;line-height:1.6;color:var(--ink2)}
.paykey{font-size:12.5px}
.paykey code{display:block;margin-top:6px;font:700 12.5px/1.5 var(--mono);
  color:var(--ink);background:var(--well);border-radius:var(--r1);
  padding:12px 14px;box-shadow:var(--in-sm);word-break:break-all}

/* ---- the accuracy banner (home page) ---- */
/* Pressed rather than raised, and set in the mono face the figures use: this is
   a claim about numbers, so it is dressed as a reading and not as an ad. */
.acc{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 16px;
  margin:0 0 26px;padding:16px 18px;border-radius:var(--r2);
  background:var(--well);box-shadow:var(--in-sm)}
.acc-pair{display:flex;align-items:baseline;gap:8px}
.acc-k{font-size:12px;font-weight:500;letter-spacing:.02em;color:var(--ink2)}
.acc-v{font:700 16px/1 var(--mono);color:var(--ink2)}
.acc-pair.us .acc-k{color:var(--ink)}
.acc-pair.us .acc-v{color:var(--blue);font-size:19px}
.acc-why{flex-basis:100%;font-size:12.5px;line-height:1.5;color:var(--ink2)}
.acc-why a{color:var(--ink);text-decoration:none;border-bottom:1px solid var(--lo)}
.acc-why a:hover{border-bottom-color:var(--ink)}

@media(min-width:560px){
  .tiles{grid-template-columns:repeat(3,1fr)}
}
@media(max-width:359px){
  .sheet{padding:24px 18px 20px}
  .keybox{font-size:12px;padding:12px 14px}
}

/* ---- pricing (home page) ---- */
/* Three cards on the same sheet as everything else. The middle one is raised
   further rather than tinted, because tinting it would spend colour on a
   marketing emphasis and the only colour on this site is data. */
.plans{display:grid;grid-template-columns:1fr;gap:14px;margin-bottom:14px}
.plan{background:var(--bg);border-radius:var(--r2);box-shadow:var(--up-sm);
  padding:20px 20px 18px;display:flex;flex-direction:column;gap:4px}
.plan.feature{box-shadow:var(--up-lg)}
.plan-name{font-size:11.5px;font-weight:600;letter-spacing:.06em;
  text-transform:uppercase;color:var(--ink2)}
.plan-price{margin:2px 0 0;font:700 30px/1.05 var(--disp);letter-spacing:-.02em;
  color:var(--ink)}
.plan-price small{font:500 13px/1 var(--disp);color:var(--ink2);margin-left:3px;
  letter-spacing:0}
.plan-line{margin:6px 0 14px;font-size:14.5px;line-height:1.45;color:var(--ink2)}
.plan-cta{margin-top:auto;align-self:flex-start;font:600 13.5px/1 var(--disp);
  color:var(--ink);text-decoration:none;padding:12px 18px;border-radius:999px;
  box-shadow:var(--up-sm);transition:box-shadow .18s,transform .1s}
.plan-cta:hover{box-shadow:var(--up);transform:translateY(-1px)}
.plan-cta:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
.plan-note{margin:0;padding:0 4px;font-size:12.5px;line-height:1.55;color:var(--dim)}

/* ---- live demo output ---- */
/* Capped and scrollable: a full balance sheet is a few hundred lines of JSON,
   and letting it push the rest of the page below the fold would bury the very
   thing the demo is meant to sell. */
.code.json{max-height:340px;overflow:auto;margin-top:14px}
.code.json code{white-space:pre;font-size:11.5px;line-height:1.65}

/* ---- resend-key panel (dashboard) ---- */
.resend{margin-top:14px;padding:16px 18px;border-radius:var(--r2);
  background:var(--well);box-shadow:var(--in-sm)}
.resend p{margin:0 0 12px;font-size:14px;line-height:1.5;color:var(--ink2)}
.resend .formnote{margin-bottom:0}

@media(min-width:620px){
  /* Two-up at tablet width rather than four-across. Four cards at 620px are
     four columns of about 140px, which is narrower than the price on them --
     the bullets wrap to one word a line and the comparison the cards exist to
     make becomes unreadable. */
  .plans{grid-template-columns:repeat(2,1fr)}
}
@media(min-width:1000px){
  .plans{grid-template-columns:repeat(4,1fr)}
}

/* ---- signed-in bar ---- */
.whoami{display:flex;align-items:center;gap:10px;min-width:0}
.who-email{font-size:12.5px;color:var(--ink2);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;max-width:38vw}
.badge{font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink2);background:var(--well);box-shadow:var(--in-sm);
  border-radius:999px;padding:4px 9px}
.whoami .linkish{font-size:12.5px;color:var(--ink2)}

/* ---- tabs ---- */
/* Pressed into the sheet as a group, with the active tab raised out of it.
   Same light as everything else, so "which tab am I on" is answered by depth
   rather than by a colour that would compete with the drawings. */
.tabs{display:flex;gap:4px;margin:0 0 22px;padding:5px;border-radius:999px;
  background:var(--well);box-shadow:var(--in-sm);overflow-x:auto;
  scrollbar-width:none}
.tabs::-webkit-scrollbar{display:none}
.tab{flex:1;min-width:84px;font:600 13.5px/1 var(--disp);color:var(--ink2);
  background:none;border:0;border-radius:999px;padding:12px 14px;cursor:pointer;
  white-space:nowrap;transition:box-shadow .18s,color .18s}
.tab:hover{color:var(--ink)}
.tab.on{color:var(--ink);background:var(--bg);box-shadow:var(--up-sm)}
.tab:focus-visible{outline:2px solid var(--ink);outline-offset:2px}

.tval.sm{font-size:14px;word-break:break-all}
.panel .tiles{margin-top:16px}

/* ---- billing ---- */
.buyrow{display:grid;grid-template-columns:1fr;gap:14px;margin:18px 0 16px}
.buy{background:var(--bg);border-radius:var(--r2);box-shadow:var(--up-sm);
  padding:20px 20px 18px;display:flex;flex-direction:column;gap:4px}
.buy .plan-line{margin:6px 0 14px}
.buy .btn{align-self:flex-start}
.buy .btn[disabled]{color:var(--dim)}

@media(min-width:560px){
  .buyrow{grid-template-columns:1fr 1fr}
}
@media(min-width:900px){
  .buyrow-3{grid-template-columns:repeat(3,1fr)}
}

/* ---- navigation ---------------------------------------------------------- */
/* One bar, every page, rendered by the server. The collapse below is an
   enhancement: `html.nav-js` is set by nav.js, so a browser that never runs it
   keeps the full row of links rather than a menu with no way to open it. */
.navlinks{display:flex;align-items:center;gap:4px;flex-wrap:wrap;
  justify-content:flex-end}
.navtoggle{display:none}

.navlink{font-size:13px;font-weight:500;color:var(--ink2);text-decoration:none;
  background:none;border:0;font-family:var(--disp);cursor:pointer;
  padding:8px 14px;border-radius:999px;transition:box-shadow .18s,color .18s;
  white-space:nowrap}
.navlink:hover{color:var(--ink);box-shadow:var(--up-sm)}
.navlink:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
/* The active page is pressed into the sheet rather than coloured — the only
   colour on this site is data, and a nav item is not data. */
.navlink.on{color:var(--ink);font-weight:600;background:var(--well);
  box-shadow:var(--in-sm)}
.navlink.on:hover{box-shadow:var(--in-sm)}
/* Present, visibly unavailable, still reachable by keyboard. */
.navlink.off{color:var(--dim);cursor:default}
.navlink.off:hover{color:var(--dim);box-shadow:none}
.brand.on{color:var(--ink)}

.navnote{margin:0;padding:0 18px 10px;font-size:12.5px;color:var(--ink2);
  text-align:right}

.logout{display:inline;margin:0}

/* ---- collapsed, only once the script is here ---- */
@media(max-width:620px){
  .nav-js .navtoggle{display:flex;align-items:center;justify-content:center;
    width:40px;height:40px;flex:none;background:var(--bg);border:0;
    border-radius:999px;box-shadow:var(--up-sm);cursor:pointer}
  .nav-js .navtoggle:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
  .nav-js .navtoggle .bars,
  .nav-js .navtoggle .bars::before,
  .nav-js .navtoggle .bars::after{display:block;width:16px;height:2px;
    border-radius:2px;background:var(--ink);content:""}
  .nav-js .navtoggle .bars{position:relative}
  .nav-js .navtoggle .bars::before{position:absolute;top:-5px}
  .nav-js .navtoggle .bars::after{position:absolute;top:5px}

  .nav-js .navlinks{display:none;position:absolute;top:60px;right:18px;left:18px;
    z-index:60;flex-direction:column;align-items:stretch;gap:2px;
    background:var(--bg);border-radius:var(--r2);box-shadow:var(--up-lg);
    padding:10px}
  .nav-js .navlinks.open{display:flex}
  .nav-js .navlinks .navlink{text-align:left;padding:12px 14px}
  .nav-js .whoami{flex-wrap:wrap;padding:10px 14px 4px;gap:8px}
  .nav-js .who-email{max-width:100%}
  nav{position:sticky}
}

@media(max-width:620px){
  .who-email{max-width:30vw}
}

/* ---- grant banner ---- */
/* Pressed, not shouted. Something good happened; it does not need to be the
   loudest thing on a page whose whole point is the figures. */
.banner{display:flex;align-items:center;gap:12px;margin:0 0 20px;padding:14px 18px;
  border-radius:var(--r2);background:var(--well);box-shadow:var(--in-sm);
  font-size:14.5px;line-height:1.45;color:var(--ink)}
.banner-tick{flex:none;width:24px;height:24px;border-radius:999px;
  display:flex;align-items:center;justify-content:center;font-size:13px;
  color:var(--bg);background:var(--blue)}
.banner .linkish{margin-left:auto;flex:none;font-size:12.5px;color:var(--ink2)}

/* ---- quick start ---- */
.quickstart{margin:20px 0 0;padding-left:22px;font-size:14.5px;line-height:1.6;
  color:var(--ink2)}
.quickstart li{margin-bottom:10px}
.quickstart .code{margin:8px 0 0}

.planline{display:flex;flex-wrap:wrap;align-items:center;gap:8px 16px;
  margin:18px 0;padding:14px 16px;border-radius:var(--r1);background:var(--well);
  box-shadow:var(--in-sm);font-size:13.5px;color:var(--ink)}
.planline .linkish{font-size:13px;color:var(--ink2)}

/* ---- comparison table ---- */
/* Scrolls inside its own box rather than widening the page: five rows of two
   columns still overflow a 320px phone once the words are real. */
.tablewrap{overflow-x:auto;margin:4px 0 18px;border-radius:var(--r2);
  background:var(--bg);box-shadow:var(--up-sm)}
.compare{width:100%;border-collapse:collapse;font-size:14px;min-width:320px}
.compare th,.compare td{padding:12px 14px;text-align:left;
  border-bottom:1px solid var(--lo)}
.compare thead th{font-size:11.5px;font-weight:600;letter-spacing:.05em;
  text-transform:uppercase;color:var(--ink2)}
.compare tbody th{font-weight:500;color:var(--ink2)}
.compare td{font-family:var(--mono);font-size:12.5px;color:var(--ink)}
.compare tr:last-child th,.compare tr:last-child td{border-bottom:0}
.compare .no{color:var(--dim)}

/* ---- login tabs ---- */
#login-tabs{margin-bottom:20px}
#pw-form .sfield+.slabel{margin-top:14px}
#pw-form .sfield{margin-bottom:0}
#setpw-form .sfield{margin-bottom:10px}

/* ---- disclaimer, footer links, acceptance ---- */
/* Stated where the numbers are, not only in a document nobody opens. Quiet:
   it is a standing fact about the whole site, not an alert. */
.disclaim{margin:0 0 22px;padding:0 4px;font-size:12.5px;line-height:1.5;
  color:var(--dim)}

.foot-links{display:block;margin-top:10px}
.foot-links a{color:var(--ink2);text-decoration:none;
  border-bottom:1px solid var(--lo);margin-right:14px}
.foot-links a:hover{color:var(--ink);border-bottom-color:var(--ink)}
.foot-disc{display:block;margin-top:8px;color:var(--dim);font-size:12px}

.accept{margin:14px 2px 0;font-size:13.5px;line-height:1.5;color:var(--ink2)}
.accept label{display:flex;align-items:flex-start;gap:9px;cursor:pointer}
.accept input{margin-top:3px;width:17px;height:17px;flex:none;accent-color:var(--ink)}
.accept a{color:var(--ink)}

/* ---- the legal documents ---- */
/* Prose measure, not the app's. These are read top to bottom rather than
   scanned, and a 56ch line is where that stops being work. */
.legal .doc{max-width:62ch}
.legal h2{margin:30px 0 10px;font-size:17px;font-weight:600;letter-spacing:-.01em}
.legal h2:first-child{margin-top:0}
.legal p,.legal li{font-size:15px;line-height:1.65;color:var(--ink2)}
.legal p{margin:0 0 14px}
.legal ul{margin:0 0 16px;padding-left:22px}
.legal li{margin-bottom:8px}
.legal strong{color:var(--ink)}
.legal a{color:var(--ink)}
/* The clauses somebody skimming must not miss. */
.legal .callout{padding:16px 18px;border-radius:var(--r2);background:var(--well);
  box-shadow:var(--in-sm);color:var(--ink)}

/* ---- the API reference ---- */
/* An endpoint is a signature and two sentences. Laid out as a list of pressed
   wells rather than a table, because the interesting column -- the path -- is
   the only one a reader scans, and a table would give it a third of the width
   and spend the rest on prose that is read once. */
.eps{display:grid;gap:12px;margin-top:4px}
.ep{padding:16px 18px;border-radius:var(--r2);background:var(--well);
  box-shadow:var(--in-sm)}
.ep-sig{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.ep-m{font:700 10.5px/1 var(--mono);letter-spacing:.09em;color:var(--ink2);
  padding:5px 8px;border-radius:var(--r1);background:var(--bg);
  box-shadow:var(--up-sm);flex:none}
.ep-p{font-family:var(--mono);font-size:13.5px;color:var(--ink);
  overflow-wrap:anywhere}
.ep-auth{margin:9px 0 0;font-size:12px;color:var(--dim)}
.ep-b{margin:7px 0 0;font-size:14px;line-height:1.6;color:var(--ink2);
  max-width:64ch}
.ep-b code{font-family:var(--mono);font-size:12.5px;color:var(--ink)}
.api-cta{display:flex;gap:10px;flex-wrap:wrap;margin-top:4px}
/* A second action that must not read as a second choice of equal weight. */
.btn.ghost{box-shadow:var(--in-sm);color:var(--ink2)}
.btn.ghost:hover{box-shadow:var(--in-sm);color:var(--ink)}
.api-code{white-space:pre;overflow-x:auto}

/* ---- the "you have no password" nudge ---- */
/* Loud enough to be seen on arrival, quiet enough not to read as a problem:
   nothing is wrong with a magic-link account, there is just a faster way in. */
.banner.nopw{display:flex;align-items:center;gap:16px;flex-wrap:wrap;
  margin:0 0 18px}
.banner.nopw p{margin:0;flex:1 1 260px;font-size:14px;line-height:1.55;
  color:var(--ink2)}
.banner.nopw strong{color:var(--ink)}

/* ---- plan bullets ---------------------------------------------------------
   What a plan DOES, under what it costs. The list is the differentiator: a
   price and a call limit tell somebody who has never bought market data
   nothing about whether static or live is the thing they need, and these four
   lines are the answer. Unbulleted -- a disc marker on a card this small reads
   as a form, and the indent it costs is width the sentences need. */
.plan-bullets{list-style:none;margin:0 0 16px;padding:0;display:grid;gap:7px}
.plan-bullets li{position:relative;padding-left:15px;font-size:13px;
  line-height:1.45;color:var(--ink2)}
.plan-bullets li::before{content:"";position:absolute;left:0;top:.55em;
  width:5px;height:5px;border-radius:999px;background:var(--dim)}
.plan-name .badge{margin-left:8px;vertical-align:1px}

/* ---- dataset vs API, side by side -----------------------------------------
   The photograph and the window, stated once above everything priced. Two
   halves rather than a table because at this point the reader has not yet
   decided WHICH -- they are still finding out that there is a which. */
.split{display:grid;grid-template-columns:1fr;gap:14px;margin-bottom:4px}
.split-half{background:var(--bg);border-radius:var(--r2);box-shadow:var(--up-sm);
  padding:22px 22px 20px}
.split-lede{margin:6px 0 0;font:700 26px/1.1 var(--disp);letter-spacing:-.02em;
  color:var(--ink)}
.split-body{margin:10px 0 0;font-size:14.5px;line-height:1.6;color:var(--ink2)}
.split-for{margin:12px 0 0;font-size:13.5px;line-height:1.5;color:var(--ink2)}
.split-for b{color:var(--ink)}
@media(min-width:760px){
  .split{grid-template-columns:1fr 1fr;gap:18px}
}

/* A third column is one more than the two-column comparison was built for, so
   the header carries the price as a second line rather than widening. */
.compare-3 thead th small{display:block;margin-top:3px;font-size:11px;
  font-weight:400;letter-spacing:0;text-transform:none;color:var(--dim)}
.compare .yes{color:var(--blue)}

/* ---- FAQ ------------------------------------------------------------------
   <details>, so the four answers cost nothing to skip and nothing to open.
   The first is open on render: it is the question the pricing page exists to
   answer, and nobody should have to click to find out the two products differ. */
.faq{display:grid;gap:10px}
.faq-item{background:var(--bg);border-radius:var(--r2);box-shadow:var(--up-sm);
  padding:4px 20px}
.faq-item summary{cursor:pointer;list-style:none;padding:16px 0;
  font:600 15px/1.4 var(--disp);color:var(--ink)}
.faq-item summary::-webkit-details-marker{display:none}
.faq-item summary::after{content:"+";float:right;margin-left:14px;
  font-weight:400;color:var(--dim)}
.faq-item[open] summary::after{content:"\2212"}
.faq-item summary:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
.faq-a{padding:0 0 16px;max-width:68ch}
.faq-a p{margin:0 0 12px;font-size:14.5px;line-height:1.65;color:var(--ink2)}
.faq-a p:last-child{margin-bottom:0}
.faq-a strong{color:var(--ink)}
.faq-a .code{margin:12px 0}

/* ---- the static-snapshot warning ------------------------------------------
   The one property that decides whether the dataset is the right purchase, so
   it is amber rather than blue: this is not a confirmation, it is a caveat a
   buyer must read BEFORE paying. Still pressed rather than shouted -- the site
   spends colour on data, and this is the only exception it makes. */
.banner.warn{align-items:flex-start}
/* --yellow is the site's existing warning tint, used on the drawings. The
   glyph goes to ink rather than the usual --bg: white on #F3C218 is well under
   any contrast floor, and this is the one banner that has to be read. */
.banner.warn .banner-tick{background:var(--yellow);color:var(--ink);margin-top:1px}
.banner.warn strong{color:var(--ink)}
.banner.live .banner-tick{background:var(--blue)}

/* ---- worked examples ---- */
.exlabel{margin:18px 0 6px;font-size:11.5px;font-weight:600;letter-spacing:.06em;
  text-transform:uppercase;color:var(--ink2)}
.sec-head.sub{margin-top:26px}
.sec-head.sub h3{margin:0;font:700 19px/1.2 var(--disp);letter-spacing:-.01em;
  color:var(--ink)}

/* ---- the dataset page's two plain lists ---- */
.collist{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:8px}
.collist li code{font-family:var(--mono);font-size:12.5px;color:var(--ink);
  background:var(--well);box-shadow:var(--in-sm);border-radius:999px;
  padding:7px 13px;display:inline-block}
.notelist{margin:0;padding-left:20px;display:grid;gap:12px;font-size:14.5px;
  line-height:1.6;color:var(--ink2);max-width:70ch}
.notelist b{color:var(--ink)}

/* ---- /blog ---------------------------------------------------------------
   Prose, not product. Narrower measure than the rest of the site because a
   700-word argument is read line by line and a 90-character line loses the
   reader's place on every return sweep. */
.post-list{list-style:none;margin:0;padding:0;display:grid;gap:18px}
.post-item{background:var(--bg);border-radius:var(--r2);box-shadow:var(--up-sm);
  padding:22px 24px}
.post-link{font:600 20px/1.3 var(--disp);color:var(--ink);text-decoration:none;
  letter-spacing:-.01em}
.post-link:hover{text-decoration:underline}
.post-desc{margin:8px 0 0;font-size:14.5px;line-height:1.55;color:var(--ink2);
  max-width:66ch}
.post-meta{margin:10px 0 0;font-family:var(--mono);font-size:12px;color:var(--dim)}
.post-meta a{color:var(--ink2)}

.prose{max-width:68ch;margin:0 0 8px}
.prose p{margin:0 0 18px;font-size:17px;line-height:1.7;color:var(--ink2)}
.prose .lede{font-size:20px;line-height:1.55;color:var(--ink)}
.prose h2{margin:38px 0 14px;font:600 25px/1.25 var(--disp);letter-spacing:-.015em;
  color:var(--ink);text-wrap:balance}
.prose strong{color:var(--ink);font-weight:600}
.prose code{font-family:var(--mono);font-size:.86em;color:var(--ink)}
.prose a{color:var(--ink);text-decoration:underline;text-underline-offset:2px}
/* The one line in the post that IS the argument. Given its own air rather
   than a pull-quote's decoration -- the sentence is short enough to carry
   itself. */
.prose .pull{font:600 24px/1.4 var(--disp);color:var(--ink);margin:26px 0;
  padding-left:18px;border-left:3px solid var(--yellow);max-width:34ch}
/* Code blocks run wider than the measure, because wrapping a curl command is
   worse than scrolling one. */
.prose .code{max-width:none;margin:0 0 22px}
.post .cta{margin-top:36px}
