/* ═══════════════════════════════════════════════════════════
   MyPeptideApp — Content Pages (/blog, /calculator/*)
   ───────────────────────────────────────────────────────────
   Loaded AFTER lp-shared.css, which supplies the reset, the
   design tokens and the .lp-nav navbar. This file adds the
   editorial layer: page shell, article header, TOC, prose,
   callouts, comparison tables, FAQ, promo blocks and the
   dark footer.

   Every rule is scoped under `.doc` (set on <body> by
   templates/layouts/content.php), the same convention
   share.css uses with .share-public. The prototype's class
   names are deliberately generic (.head, .wrap, .content,
   .sec) and would otherwise collide with components.css the
   moment these two ever meet on one page.

   Custom properties stay on :root on purpose. They need to
   reach html{} for scroll-padding, and this file only ever
   loads on content pages, so there is nothing to collide with.

   Typography: two typefaces on purpose. Site chrome (navbar,
   footer) stays on the app's Inter via --font-sans. Editorial
   content runs on Instrument Sans via --font-content, set once
   on .page, with Instrument Serif italic as the headline
   accent. The footer is a sibling of .page in the layout, not
   a child, which is what keeps it on Inter.
   ═══════════════════════════════════════════════════════════ */

:root{
  --color-primary:#000;
  --color-primary-hover:#1a1a1a;
  --color-bg:#fff;
  --color-bg-secondary:#F9FAFB;
  --color-bg-tertiary:#F3F4F6;
  --color-border:#E5E7EB;
  --color-border-strong:#D1D5DB;
  --color-border-light:#F1F2F4;
  --color-text-primary:#111827;
  --color-text-secondary:#6B7280;
  --color-text-tertiary:#9CA3AF;
  --color-prose:#374151;

  /* recurring Qonto-style pastel palette (black text friendly) */
  --lav-bg:#E9E5FB; --lav-ac:#6C5CE0; --lav-ink:#4A3FB0;
  --peach-bg:#FCEAD7; --peach-ac:#D9822B; --peach-ink:#9A5B1E;
  --mint-bg:#DCF2E5; --mint-ac:#0E9F6E; --mint-ink:#0A7350;
  --rose-bg:#FBE3E1; --rose-ac:#E5484D; --rose-ink:#B22A2E;
  --card-soft:#F4F4F2;       /* warm neutral block surface */
  --own-bg:#F5F3FD;          /* highlighted row (our app)     */

  /* body type scale */
  --fs-body:1.03125rem;      /* 16.5px  main prose            */
  --fs-body-sm:.96875rem;    /* 15.5px  dense cards / columns */
  --block-ink:#171520;       /* heading text on pastel  */
  --block-body:#2C2935;      /* body text on pastel     */

  /* semantic (data) */
  --good:#059669; --bad:#DC2626;


  --r-card:8px;        /* soft promo cards / hero / images */
  --r-ctrl:8px;        /* controls (share buttons)         */
  --r-pill:9999px;     /* buttons stay pill (app style)    */

  --shadow-sm:0 1px 3px rgba(0,0,0,.06),0 1px 2px rgba(0,0,0,.04);
  --shadow-lg:0 10px 15px -3px rgba(0,0,0,.08),0 4px 6px -4px rgba(0,0,0,.04);

  --nav-h:72px;        /* must equal .lp-nav-inner height in lp-shared.css */
  --page-pad:24px;
  --ease:cubic-bezier(.16,1,.3,1);
}


/* Anchor offset for the fixed navbar. Everything else on html is already
   set by lp-shared.css, which always loads first. */
html{interpolate-size:allow-keywords;scroll-padding-top:calc(var(--nav-h) + 20px)}
body.doc{font-family:var(--font-sans);color:var(--color-text-primary);background:var(--color-bg);line-height:1.5;overflow-x:hidden}
/* lp-shared.css already ships `a { color: inherit; text-decoration: none }`
   for the whole site, so this rule only adds the hover transition.
   It must NOT restate color: `.doc a` scores (0,1,1) and would outrank
   `.lp-nav-cta` at (0,1,0), which is how the white button label turned
   black on content pages. */
.doc a{transition:color .15s}
.doc ul,.doc ol{list-style:none}
.doc img,.doc svg{display:block;max-width:100%}

.doc ::-webkit-scrollbar{width:8px;height:8px}
.doc ::-webkit-scrollbar-thumb{background:var(--color-border);border-radius:9999px}

/* ─── Nav ─────────────────────────────────────────────── */













/* ─── Page shell ──────────────────────────────────────── */
.doc .page{padding-top:var(--nav-h);font-family:var(--font-content)}
.doc .wrap{max-width:1230px;margin:0 auto;padding:0 var(--page-pad)}
.doc .crumbs{display:flex;align-items:center;gap:8px;font-size:.8125rem;line-height:1.35;color:var(--color-text-tertiary);
  padding:22px 0 0;flex-wrap:nowrap;overflow:hidden;min-width:0}
.doc .crumbs > *{white-space:nowrap;flex-shrink:0}
.doc .crumbs a:hover{color:var(--color-text-primary)}
.doc .crumbs .sep{opacity:.5}
.doc .crumbs .here{color:var(--color-text-secondary);flex:0 1 auto;min-width:2ch;overflow:hidden;text-overflow:ellipsis}

/* ─── Header (two-column hero: title left, illustration right) ──── */
.doc .head{display:grid;grid-template-columns:minmax(0,1fr) minmax(280px,418px);gap:60px;align-items:start;padding:22px 0 8px}
.doc .head-main{min-width:0;display:flex;flex-direction:column}
.doc .head h1{font-size:clamp(2.15rem,5vw,3.35rem);font-weight:800;letter-spacing:-.035em;line-height:1.05;margin:0;max-width:16ch;order:2}
.doc .meta{display:flex;align-items:center;flex-wrap:wrap;gap:8px 22px;font-size:.8125rem;color:var(--color-text-secondary);order:1;margin-bottom:18px}
.doc .meta .m{display:inline-flex;align-items:center;gap:7px}
.doc .meta svg{width:15px;height:15px;color:var(--color-text-tertiary)}

/* hero illustration card */
.doc .head-media{min-width:0}
.doc .hero-card{position:relative;background:var(--lav-bg);border-radius:16px;aspect-ratio:16/10;overflow:hidden;display:grid;place-items:center}
.doc .hero-card svg{width:88%;height:82%}

/* ─── Layout ──────────────────────────────────────────── */
.doc .layout{display:grid;grid-template-columns:290px minmax(0,1fr);gap:72px;align-items:start;padding:34px 0 10px}
.doc .side{position:sticky;top:calc(var(--nav-h) + 24px);max-height:calc(100vh - var(--nav-h) - 48px);display:flex;flex-direction:column;gap:20px;align-self:start}
.doc .toc{display:flex;flex-direction:column;min-height:0}
.doc .toc-h{flex-shrink:0;font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.09em;color:var(--color-text-tertiary);padding:0 0 12px 18px}
.doc .toc-list{position:relative;min-height:0;overflow-y:auto;border-left:1px solid var(--color-border);scrollbar-width:none;
  --t:#000;--b:#000;
  -webkit-mask-image:linear-gradient(to bottom,var(--t),#000 18px,#000 calc(100% - 18px),var(--b));
          mask-image:linear-gradient(to bottom,var(--t),#000 18px,#000 calc(100% - 18px),var(--b))}
.doc .toc-list::-webkit-scrollbar{width:0;height:0}
.doc .toc-list.fade-top{--t:transparent}
.doc .toc-list.fade-bot{--b:transparent}
.doc .toc-marker{position:absolute;left:-1px;top:0;width:2px;height:0;background:var(--color-primary);border-radius:2px;opacity:0;
  transition:transform .32s var(--ease),height .32s var(--ease),opacity .2s;will-change:transform,height}
.doc .toc-list a{display:block;padding:7px 0 7px 18px;font-size:.8125rem;line-height:1.4;color:var(--color-text-secondary);transition:color .18s}
.doc .toc-list a:hover{color:var(--color-text-primary)}
.doc .toc-list a.active{color:var(--color-text-primary);font-weight:600}
@media (prefers-reduced-motion:reduce){.doc .toc-marker{transition:opacity .2s}}

/* Qonto-style soft promo card: warm surface, centered copy, cropped app shot */
.doc .appcard{background:var(--card-soft);border:1px solid var(--color-border);border-radius:16px;overflow:hidden;text-align:center;flex-shrink:0}
.doc .appcard .ac-body{padding:26px 22px 26px;display:flex;flex-direction:column;align-items:center}
.doc .logo-mark{width:30px;height:30px;background:var(--color-primary);border-radius:7px;display:flex;align-items:center;justify-content:center;color:#fff;flex-shrink:0}
.doc .logo-mark svg{width:15px;height:15px}
.doc .appcard .mini-logo{display:flex;align-items:center;justify-content:center;gap:8px;font-weight:700;font-size:.8125rem;letter-spacing:-.01em;margin-bottom:16px;color:var(--color-text-secondary)}
.doc .appcard .mini-logo .logo-mark{width:22px;height:22px}.doc .appcard .mini-logo .logo-mark svg{width:11px;height:11px}
.doc .appcard .ac-t{font-size:1.375rem;font-weight:800;letter-spacing:-.03em;line-height:1.14;margin-bottom:10px;color:var(--color-text-primary);max-width:13ch}
.doc .appcard p{font-size:.875rem;color:var(--color-text-secondary);line-height:1.55;margin-bottom:16px;max-width:24ch}
.doc .appcard .ac-rating{font-size:.78rem;font-weight:600;line-height:1.4;color:var(--color-text-secondary);margin-bottom:18px}
.doc .appcard .ac-rating b{color:var(--color-text-primary);font-weight:700}
.doc .btn-block{display:flex;align-items:center;justify-content:center;gap:8px;width:100%;background:var(--color-primary);color:#fff;font-weight:600;font-size:.875rem;padding:13px 16px;border-radius:var(--r-pill);transition:background .15s,transform .15s}
.doc .btn-block:hover{background:var(--color-primary-hover);transform:translateY(-1px)}

/* ─── Content / prose ─────────────────────────── */
.doc .content{min-width:0;max-width:800px}
.doc .prose{font-size:var(--fs-body);line-height:1.7;color:var(--color-prose);text-wrap:pretty}
.doc .prose > p{margin:0 0 22px}
.doc .prose a.ref{font-size:.68rem;font-weight:600;vertical-align:super;color:var(--color-text-tertiary);padding:0 1px}
.doc .prose a.ref:hover{color:var(--color-primary)}
.doc .prose strong{font-weight:600;color:var(--color-text-primary)}

.doc .sec{scroll-margin-top:calc(var(--nav-h) + 24px)}
.doc .sec h2{font-size:clamp(1.5rem,3vw,1.875rem);font-weight:700;letter-spacing:-.025em;line-height:1.18;margin:48px 0 16px;color:var(--color-text-primary)}
.doc .sec h3{font-size:1.25rem;font-weight:700;letter-spacing:-.018em;margin:32px 0 12px;color:var(--color-text-primary)}
.doc .plist{font-size:var(--fs-body);line-height:1.65;text-wrap:pretty;color:var(--color-prose);display:flex;flex-direction:column;gap:18px;margin:6px 0 24px}
.doc .plist li{display:flex;gap:14px}
.doc .plist li::before{content:"";flex-shrink:0;width:5px;height:5px;border-radius:50%;background:var(--color-text-tertiary);margin-top:.6em}
.doc .plist strong{color:var(--color-text-primary)}

/* ─── Callout blocks (squared, solid pastel, left accent) ─ */
.doc .callout{padding:24px 26px;margin:30px 0;border-radius:0}
.doc .callout .c-h{display:flex;align-items:center;gap:10px;font-weight:700;font-size:1.0625rem;letter-spacing:-.01em;margin-bottom:14px;color:var(--block-ink)}
.doc .callout .c-h svg{width:19px;height:19px;flex-shrink:0}
.doc .callout ul{display:flex;flex-direction:column;gap:11px}
.doc .callout li{display:flex;gap:11px;font-size:var(--fs-body);line-height:1.58;color:var(--block-body)}
.doc .callout li svg{width:18px;height:18px;flex-shrink:0;margin-top:2px}
.doc .callout li .dot{width:6px;height:6px;border-radius:50%;background:var(--block-ink);flex-shrink:0;margin-top:8px}
.doc .callout p{font-size:var(--fs-body);line-height:1.62;text-wrap:pretty;color:var(--block-body)}
.doc .callout--key{background:var(--color-bg-tertiary);border-color:var(--lav-ac)} .doc .callout--key .c-h svg{color:var(--lav-ac)}

/* ─── Short answer (Qonto-style summary block, sticker art top right) ─ */
.doc .shortanswer{position:relative;background:var(--card-soft,#F4F4F2);padding:42px 40px 36px;margin:76px 0 46px}
.doc .shortanswer .sa-art{position:absolute;top:-44px;right:28px;width:142px;height:auto;pointer-events:none}
.doc .shortanswer .sa-h{font-size:clamp(1.5rem,3.2vw,1.9rem);font-weight:800;letter-spacing:-.032em;line-height:1.12;color:var(--block-ink);margin:0 0 24px;padding-right:150px;text-wrap:balance}
.doc .shortanswer ul{display:flex;flex-direction:column;gap:18px;max-width:62ch}
.doc .shortanswer li{position:relative;padding-left:22px;font-size:var(--fs-body);line-height:1.6;color:var(--block-body);text-wrap:pretty}
.doc .shortanswer li::before{content:"";position:absolute;left:3px;top:.66em;width:5px;height:5px;border-radius:50%;background:var(--block-ink)}
.doc .shortanswer strong{font-weight:600;color:var(--block-ink)}
.doc .shortanswer .sa-inline{color:var(--block-ink);font-weight:500;text-decoration:underline;text-underline-offset:3px;text-decoration-thickness:1px;text-decoration-color:rgba(23,21,32,.35);transition:text-decoration-color .15s}
.doc .shortanswer .sa-inline:hover{text-decoration-color:var(--block-ink)}
.doc .shortanswer .sa-link{display:inline-flex;align-items:center;gap:7px;margin-top:28px;font-size:.9375rem;font-weight:600;letter-spacing:-.005em;color:var(--block-ink);
  border-bottom:1px solid rgba(23,21,32,.35);padding-bottom:1px;transition:border-color .15s,opacity .15s}
.doc .shortanswer .sa-link:hover{border-bottom-color:var(--block-ink)}
.doc .shortanswer .sa-link svg{width:14px;height:14px;flex-shrink:0}
.doc .callout--caution{background:var(--lav-bg);border-color:var(--peach-ac)} .doc .callout--caution .c-h svg{color:var(--peach-ac)}
.doc .callout--risk{background:var(--rose-bg);border-color:var(--rose-ac)} .doc .callout--risk .c-h{color:var(--rose-ink)} .doc .callout--risk .c-h svg{color:var(--rose-ac)}

/* ─── Comparison table ────────────────────────────────── */
.doc .table-scroll{overflow-x:auto;overscroll-behavior-x:contain;margin:30px 0 10px;-webkit-overflow-scrolling:touch}
.doc table.cmp{width:100%;border-collapse:separate;border-spacing:0;min-width:760px;font-size:.9375rem;background:var(--color-bg)}

.doc table.cmp th,.doc table.cmp td{text-align:left;padding:16px 18px;border-bottom:1px solid var(--color-border);vertical-align:middle}
.doc table.cmp thead th{font-weight:600;font-size:.6875rem;text-transform:uppercase;letter-spacing:.075em;
  color:var(--color-text-tertiary);padding:14px 18px 13px;background:var(--color-bg);
  border-bottom:1px solid var(--color-border-strong);white-space:nowrap}

/* app column scrolls with the rest of the table */
.doc table.cmp .app{width:166px;min-width:166px;
  font-weight:600;font-size:.9375rem;line-height:1.35;color:var(--color-text-primary);
  text-wrap:balance;hyphens:none}

/* value cell: icon + short label */
.doc .cmp .v{display:inline-flex;align-items:center;gap:8px;line-height:1.4;white-space:nowrap;color:var(--color-prose)}
.doc .cmp .v svg{width:15px;height:15px;flex-shrink:0}
.doc .cmp .v.y svg{color:var(--good)}
.doc .cmp .v.p svg{color:var(--peach-ac)}
.doc .cmp .v.n{color:var(--color-text-tertiary)} .doc .cmp .v.n svg{color:var(--bad)}
.doc .cmp .v .q{color:var(--color-text-tertiary);font-size:.8125rem}

/* our row */
.doc table.cmp tr.own th,.doc table.cmp tr.own td{background:var(--own-bg)}
.doc table.cmp tr.own .app{color:var(--lav-ink)}
.doc table.cmp tbody tr:not(.own):hover th,.doc table.cmp tbody tr:not(.own):hover td{background:var(--color-bg-secondary)}
.doc .tbl-note{font-size:.8125rem;line-height:1.5;color:var(--color-text-tertiary);margin:0 0 26px}


/* app nudge → Qonto-style promo card.
   The card lives inside the 800px content column, so the mockup can only get
   bigger by taking space rather than by the card growing. Two moves do that:
   the right padding is dropped so the media column reaches the card edge, and
   the image is drawn wider than its column so it runs off that edge and gets
   clipped. The tablet reading past the frame is the point, not a side effect:
   it implies more app beyond the crop and roughly doubles the rendered UI. */
.doc .nudge{--nudge-pink:#F9DCE7;--nudge-bleed:132px;
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.14fr);gap:36px;align-items:center;
  background:var(--nudge-pink);color:var(--block-ink);border-radius:16px;
  padding:52px 0 52px 52px;margin:44px 0;overflow:hidden}
/* Deliberately not a vw clamp. Below 980px the sidebar drops out and this card
   gets wider, so a viewport-based size shrinks the headline exactly where the
   card grows. Fixed steps per breakpoint track the card instead. */
.doc .nudge .n-t{font-family:var(--font-content);font-weight:800;
  font-size:2.15rem;line-height:1.08;letter-spacing:-.03em;color:var(--block-ink);
  max-width:15ch;text-wrap:balance}
.doc .nudge .n-s{font-size:1.0625rem;line-height:1.55;color:var(--block-body);margin-top:16px;max-width:34ch;text-wrap:pretty}
.doc .nudge .n-btn{display:inline-flex;align-items:center;justify-content:center;margin-top:28px;
  background:var(--color-primary);color:#fff;font-weight:600;font-size:1.0625rem;
  padding:16px 30px;border-radius:var(--r-pill);white-space:nowrap;transition:background .15s,transform .15s}
.doc .nudge .n-btn:hover{background:var(--color-primary-hover);transform:translateY(-1px)}
.doc .nudge-media{display:block;width:calc(100% + var(--nudge-bleed));max-width:none;height:auto;
  aspect-ratio:1500 / 951;object-fit:contain;object-position:left center}
/* narrower viewports still run the two-column card, but there is no longer
   room to give away, so the bleed tapers off before the mobile stack */
@media (max-width:1180px){.doc .nudge{--nudge-bleed:104px;
  grid-template-columns:minmax(0,1fr) minmax(0,1.04fr)}}
@media (max-width:980px){.doc .nudge{--nudge-bleed:132px;
  grid-template-columns:minmax(0,1fr) minmax(0,1.14fr)}}
@media (max-width:820px){.doc .nudge{--nudge-bleed:88px;padding:46px 0 46px 44px;gap:30px}
  .doc .nudge .n-t{font-size:1.95rem}}

/* ─── FAQ ─────────────────────────────────────────────── */
.doc .faq{margin:18px 0;border-top:1px solid var(--color-border)}
.doc .faq details{border-bottom:1px solid var(--color-border)}
.doc .faq summary{list-style:none;cursor:pointer;display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:20px 2px;font-weight:600;font-size:1rem;letter-spacing:-.01em;color:var(--color-text-primary)}
.doc .faq summary::-webkit-details-marker{display:none}
.doc .faq summary .chev{width:20px;height:20px;flex-shrink:0;color:var(--color-text-tertiary);transition:transform .25s var(--ease)}
.doc .faq details[open] summary .chev{transform:rotate(180deg)}
.doc .faq .faq-a{padding:0 2px 22px;font-size:var(--fs-body);line-height:1.68;text-wrap:pretty;color:var(--color-prose)}

/* ─── Disclaimer ──────────────────────────────────────── */
.doc .disclaimer{margin:40px 0 8px;padding:18px 20px;background:var(--lav-bg);border-radius:0}
.doc .disclaimer p{font-size:.875rem;line-height:1.62;color:var(--block-body)}
.doc .disclaimer b{color:var(--block-ink)}
/* Same treatment as .sa-inline: this sits on a pastel block, so it uses
   --block-ink rather than --color-text-primary. Without it the link is
   indistinguishable from the body text around it. */
.doc .disclaimer a{color:var(--block-ink);text-decoration:underline;text-underline-offset:3px;
  text-decoration-thickness:1px;text-decoration-color:rgba(23,21,32,.35);
  transition:text-decoration-color .15s}
.doc .disclaimer a:hover{text-decoration-color:var(--block-ink)}

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


 


/* mobile TOC */
.doc .toc-mobile{display:none;border-top:1px solid var(--color-border);border-bottom:1px solid var(--color-border);margin:26px 0 30px}
.doc .toc-mobile summary{list-style:none;cursor:pointer;-webkit-tap-highlight-color:transparent;
  display:flex;align-items:center;justify-content:space-between;gap:14px;padding:15px 2px;
  font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.09em;
  color:var(--color-text-tertiary);transition:color .18s}
.doc .toc-mobile summary::-webkit-details-marker{display:none}
.doc .toc-mobile summary:hover,.doc .toc-mobile[open] summary{color:var(--color-text-secondary)}
.doc .toc-mobile summary .chev{width:16px;height:16px;flex-shrink:0;transition:transform .3s var(--ease)}
.doc .toc-mobile[open] summary .chev{transform:rotate(180deg)}
/* No left rail here. The rail belongs to the desktop sidebar, where it carries
   the scroll-position marker and therefore does something. In the collapsed
   mobile list it marks nothing, and the 17px indent it needed pushed the whole
   list out of line with the label above it. Numbers now sit on the same left
   edge as the summary, and the rows are tall enough to be a comfortable tap. */
.doc .toc-mobile ol{counter-reset:tc;margin:0 0 14px;display:flex;flex-direction:column}
.doc .toc-mobile li{counter-increment:tc}
.doc .toc-mobile a{display:flex;align-items:baseline;gap:14px;padding:12px 2px;
  font-size:.9375rem;line-height:1.4;color:var(--color-text-secondary);transition:color .18s}
.doc .toc-mobile a::before{content:counter(tc,decimal-leading-zero);flex-shrink:0;
  min-width:1.6em;font-size:.75rem;font-weight:600;font-variant-numeric:tabular-nums;letter-spacing:.02em;
  color:var(--color-text-tertiary);transition:color .18s}
.doc .toc-mobile a:hover,.doc .toc-mobile a:active{color:var(--color-text-primary)}
.doc .toc-mobile a:hover::before,.doc .toc-mobile a:active::before{color:var(--color-text-primary)}
@supports (interpolate-size:allow-keywords){
  .doc .toc-mobile::details-content{block-size:0;overflow:hidden;opacity:0;
    transition:block-size .34s var(--ease),opacity .24s ease,content-visibility .34s allow-discrete}
  .doc .toc-mobile[open]::details-content{block-size:auto;opacity:1}
}

.doc .doc-reveal{opacity:0;transform:translateY(16px);transition:opacity .6s var(--ease),transform .6s var(--ease)}
.doc .doc-reveal.in{opacity:1;transform:none}

/* ═══ Responsive ══════════════════════════════════════ */
@media (max-width:980px){
  .doc .crumbs{padding-top:18px}
  .doc .head{grid-template-columns:1fr;gap:26px;padding-top:30px}
  .doc .head h1{order:1}
  .doc .meta{order:2;margin:18px 0 0}
  .doc .hero-card{width:100%}
  .doc .layout{grid-template-columns:1fr;gap:0;padding:8px 0 10px}
  .doc .side{display:none}
  .doc .content{max-width:none}
  .doc .toc-mobile{display:block}
}
@media (max-width:640px){
  :root{--page-pad:18px}
  
  
  .doc .head h1{font-size:2rem}

  /* table runs edge to edge, first column keeps the prose indent */
  .doc .table-scroll{margin:26px calc(-1 * var(--page-pad)) 10px}
  .doc table.cmp{min-width:0;width:max-content}
  .doc table.cmp th,.doc table.cmp td{padding:15px 15px}
  .doc table.cmp thead th{padding:13px 15px 12px}
  .doc table.cmp tr > *:first-child{padding-left:var(--page-pad)}
  .doc table.cmp tr > *:last-child{padding-right:var(--page-pad)}
  .doc table.cmp .app{width:150px;min-width:150px}
  /* Stacked, and deliberately message first: the mockup used to sit on top and
     pushed the offer below the fold on a phone. The mockup keeps its original
     size here rather than taking the bleed the desktop card uses, so it stays
     inside the padding and the card closes with a normal floor. */
  .doc .nudge{--nudge-bleed:0px;
    grid-template-columns:1fr;text-align:center;padding:38px 24px 38px;gap:26px;margin:36px 0}
  .doc .nudge-copy{order:1}
  .doc .nudge-media{order:2;width:100%;max-width:none;margin:2px auto 0;
    object-position:center}
  .doc .nudge .n-t{margin-left:auto;margin-right:auto}
  .doc .nudge .n-s{margin-left:auto;margin-right:auto}
  .doc .nudge .n-btn{width:100%}
  .doc .nudge .n-t{font-size:clamp(1.85rem,7.2vw,2.3rem);max-width:17ch}

  /* full-bleed squared blocks edge-to-edge on mobile */
  .doc .callout,.doc .disclaimer,.doc .shortanswer{
    margin-left:calc(-1 * var(--page-pad));
    margin-right:calc(-1 * var(--page-pad));
    width:auto}
  /* art moves above the block, heading centres under it (Qonto pattern) */
  .doc .shortanswer{padding:42px var(--page-pad) 32px;margin:58px 0 40px}
  .doc .shortanswer .sa-art{width:104px;height:auto;top:-46px;right:14px;left:auto;transform:none}
  .doc .shortanswer .sa-h{padding-right:0;text-align:left;font-size:1.5rem;margin-bottom:22px}
  .doc .shortanswer ul{gap:20px;max-width:none}
  .doc .shortanswer li{font-size:var(--fs-body);line-height:1.62}
  .doc .shortanswer .sa-link{margin-top:24px}
}
@media (prefers-reduced-motion:reduce){
  .doc *{scroll-behavior:auto}
  .doc .doc-reveal{opacity:1;transform:none;transition:none}
}

/* ═══════════════════════════════════════════════════════════
   v4 ADDITIONS · mobile-first readability + comparison UI
   ═══════════════════════════════════════════════════════════ */

/* ---- prose rhythm: shorter blocks, more air between them ---- */
.doc .prose{max-width:68ch}
.doc .prose > p{margin:0 0 20px}
.doc .prose > p:last-child{margin-bottom:0}
.doc .lede{font-size:1.15rem;line-height:1.6;color:var(--color-text-primary);font-weight:450;max-width:60ch;margin:0 0 22px}



/* ---- app review blocks ---- */
.doc .appbox{border-top:1px solid var(--color-border);padding-top:26px;margin-top:34px}
.doc .appbox:first-of-type{border-top:0;padding-top:6px;margin-top:20px}
.doc .appbox h3{display:flex;align-items:baseline;flex-wrap:wrap;gap:0 10px;margin:0 0 10px}
.doc .appbox h3 .rank{font-size:.8125rem;font-weight:700;color:var(--color-text-tertiary);letter-spacing:.04em}
.doc .appbox .tagline{font-size:var(--fs-body);line-height:1.62;color:var(--color-prose);margin:0 0 16px;max-width:64ch;text-wrap:pretty}
.doc .specs{display:flex;flex-wrap:wrap;gap:7px;margin:0 0 18px}
.doc .spec{font-size:.8125rem;font-weight:500;line-height:1;padding:7px 11px;background:var(--color-bg-tertiary);color:var(--color-prose);white-space:nowrap}
.doc .spec.hl{background:var(--lav-bg);color:var(--lav-ink);font-weight:600}
.doc .pc{display:grid;grid-template-columns:1fr 1fr;gap:14px 26px;margin:0 0 4px}
.doc .pc h4{font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.07em;margin:0 0 9px;color:var(--color-text-tertiary)}
.doc .pc ul{display:flex;flex-direction:column;gap:8px}
.doc .pc li{position:relative;padding-left:20px;font-size:var(--fs-body-sm);line-height:1.55;color:var(--color-prose);text-wrap:pretty}
.doc .pc li::before{content:"";position:absolute;left:2px;top:.58em;width:8px;height:2px;background:var(--good)}
.doc .pc .con li::before{background:var(--peach-ac)}
.doc .verdict{margin:18px 0 0;padding:14px 16px;background:var(--color-bg-secondary);font-size:var(--fs-body-sm);line-height:1.6;color:var(--color-prose);text-wrap:pretty}
.doc .verdict b{color:var(--color-text-primary);font-weight:650}


/* ═══ MOBILE ═══ */
@media (max-width:640px){
  :root{--fs-body:1.0625rem;--fs-body-sm:1rem}
  .doc .prose{line-height:1.68}
  .doc .prose > p{margin:0 0 18px}
  .doc .lede{font-size:1.125rem}
  .doc .sec h2{margin:44px 0 14px;line-height:1.15}


  .doc .appbox{margin-top:30px;padding-top:24px}
  .doc .specs{gap:6px}

  .doc .verdict{padding:14px}
}



/* ═══════════════════════════════════════════════════════════
   v5 · TYPE + RHYTHM
   Instrument Sans everywhere. Instrument Serif italic as an
   accent, used five times on the whole page and nowhere else.
   Serif is weight 400 only, so it is never bolded.
   ═══════════════════════════════════════════════════════════ */
:root{
  /* Editorial faces. --font-sans is deliberately NOT touched: it stays
     Inter from lp-shared.css so the navbar and footer keep the app's
     typeface. Content opts into --font-content on .page below. */
  --font-content:'Instrument Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',sans-serif;
  --font-serif:'Instrument Serif','Iowan Old Style',Georgia,'Times New Roman',serif;
  --fs-body:1.0625rem;      /* 17px */
  --fs-body-sm:1rem;        /* 16px */
}

/* ── the accent. one per headline, two words at most ──
   1.07em compensates for the serif's smaller optical size next
   to the sans, and the tracking is reset because the tight
   headline spacing is wrong for an italic serif. */
.doc .ital{
  font-family:var(--font-serif);
  font-style:italic;
  font-weight:400;
  font-size:1.07em;
  letter-spacing:-.004em;
  padding-right:.03em;
}

/* ── headings ──────────────────────────────────────────── */
.doc .head h1{
  font-weight:500;
  font-size:clamp(2.4rem,5.6vw,3.75rem);
  letter-spacing:-.038em;
  line-height:1.06;
  max-width:15ch;
}
.doc .sec h2{
  font-weight:500;
  font-size:clamp(1.75rem,3.4vw,2.375rem);
  letter-spacing:-.032em;
  line-height:1.14;
  margin:84px 0 22px;
}
.doc .sec h3{
  font-weight:500;
  font-size:1.5rem;
  letter-spacing:-.026em;
  line-height:1.2;
  margin:56px 0 16px;
}
.doc .shortanswer .sa-h{
  font-weight:500;
  font-size:clamp(1.75rem,3.4vw,2.25rem);
  letter-spacing:-.032em;
  line-height:1.14;
}

/* ── body: shorter measure, more leading ───────────────── */
.doc .prose{max-width:62ch;line-height:1.78}
.doc .prose > p{margin:0 0 26px}
.doc .prose strong{font-weight:600}
/* `.prose > p:last-child{margin-bottom:0}` correctly stops a trailing gap
   inside the block, but it also removed the paragraph rhythm BETWEEN the
   prose block and the next sibling. A following .plist only carries a 10px
   top margin because it normally leans on the paragraph's 26px, so lists ended
   up glued to the paragraph above them. The block now carries that spacing
   itself. Adjacent margins collapse, so anything that already asks for more
   (headings, the nudge, callouts) is untouched. */
.doc .prose:not(:last-child){margin-bottom:26px}

/* ── opening line: the article's one hero moment ───────── */
.doc .lede{
  font-weight:400;
  font-size:clamp(1.375rem,2.6vw,1.75rem);
  line-height:1.34;
  letter-spacing:-.022em;
  color:var(--color-text-primary);
  max-width:22ch;
  margin:0 0 34px;
}

/* ── pull quote: no rule, no box, just the type and space ── */
.doc .pullquote{
  font-family:var(--font-serif);
  font-style:italic;
  font-weight:400;
  font-size:clamp(1.5rem,3vw,2rem);
  line-height:1.34;
  letter-spacing:-.008em;
  color:var(--color-text-primary);
  max-width:26ch;
  margin:64px 0 64px;
  text-wrap:pretty;
}

/* ── lists: more air between items ─────────────────────── */
.doc .plist{gap:22px;line-height:1.7;margin:10px 0 30px;max-width:62ch}
.doc .plist li::before{margin-top:.68em}

/* ── section rhythm ────────────────────────────────────── */
.doc .layout{padding-top:44px}
.doc .sec + .sec{margin-top:0}
.doc .shortanswer{margin:66px 0 56px}
.doc .shortanswer li{line-height:1.66}
.doc .shortanswer ul{gap:20px}

/* ═══════════════════════════════════════════════════════════
   APP REVIEW BLOCKS · rebuilt for calm
   Was: two columns of long bullets side by side. The eye had no
   entry point and every line carried the same weight. Now one
   column, one thing at a time, short lines, generous gaps.
   ═══════════════════════════════════════════════════════════ */
.doc .appbox{border-top:1px solid var(--color-border);padding-top:52px;margin-top:64px}
.doc .appbox:first-of-type{border-top:0;padding-top:8px;margin-top:34px}
.doc .appbox h3{display:block;margin:0 0 14px}
.doc .appbox h3 .rank{
  display:inline;font-family:var(--font-content);font-size:.75rem;font-weight:600;
  letter-spacing:.14em;color:var(--color-text-tertiary);
  margin:0 8px 0 0;vertical-align:.14em}
.doc .appbox .tagline{
  font-size:1.125rem;line-height:1.6;letter-spacing:-.012em;
  color:var(--color-prose);margin:0 0 26px;max-width:52ch}

.doc .specs{gap:8px;margin:0 0 34px}
.doc .spec{
  font-size:.8125rem;font-weight:500;letter-spacing:.005em;line-height:1;
  padding:8px 12px;background:transparent;border:1px solid var(--color-border);
  color:var(--color-text-secondary);border-radius:var(--r-pill)}
.doc .spec.hl{background:var(--lav-bg);border-color:transparent;color:var(--lav-ink);font-weight:600}

/* single column, the two groups separated by space rather than a rule */
.doc .pc{display:block;margin:0}
.doc .pc > div + div{margin-top:32px}
.doc .pc h4{
  font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.13em;
  margin:0 0 16px;color:var(--color-text-tertiary)}
.doc .pc ul{gap:14px;max-width:56ch}
.doc .pc li{
  padding-left:24px;font-size:var(--fs-body);line-height:1.6;
  color:var(--color-prose)}
.doc .pc li::before{left:0;top:.72em;width:11px;height:1.5px;background:var(--good);opacity:.85}
.doc .pc .con li::before{background:var(--peach-ac)}
.doc .pc a,.doc .plist a,.doc .faq .faq-a a{color:var(--color-text-primary);text-decoration:underline;text-underline-offset:3px;
  text-decoration-thickness:1px;text-decoration-color:var(--color-border-strong);
  transition:text-decoration-color .15s}
.doc .pc a:hover,.doc .plist a:hover,.doc .faq .faq-a a:hover{text-decoration-color:var(--color-text-primary)}

.doc .verdict{
  margin:34px 0 0;padding:22px 24px;background:var(--color-bg-secondary);
  font-size:var(--fs-body);line-height:1.65;max-width:58ch}
.doc .verdict b{font-weight:600}


/* ── misc type cleanup ─────────────────────────────────── */
.doc .head .meta{letter-spacing:.005em}
.doc .toc-h,.doc .pc h4{font-family:var(--font-content)}
.doc .faq summary{font-weight:500;letter-spacing:-.012em;font-size:1.0625rem;line-height:1.45}
.doc .faq .faq-a{font-size:var(--fs-body-sm);line-height:1.72}
.doc .nudge .n-t{font-weight:500;letter-spacing:-.032em}
.doc .appcard .ac-t{font-weight:500;letter-spacing:-.022em}
.doc .tbl-note{line-height:1.6;margin:2px 0 34px}
.doc .disclaimer p{line-height:1.7}
.doc table.cmp{font-family:var(--font-content)}

/* ═══ MOBILE ═══ */
@media (max-width:640px){
  :root{--fs-body:1.0625rem;--fs-body-sm:1rem}
  .doc .head h1{font-size:2.35rem;line-height:1.08;letter-spacing:-.034em;max-width:none}
  .doc .sec h2{margin:64px 0 18px;line-height:1.16}
  .doc .lede{font-size:1.5rem;line-height:1.26;max-width:none;margin-bottom:28px}
  .doc .prose{line-height:1.76}
  .doc .prose > p{margin:0 0 22px}
  .doc .prose:not(:last-child){margin-bottom:22px}
  /* `.doc .sec h3` and `.doc .appbox h3` score the same, so this mobile rule
     used to win purely on source order and pushed a 44px top margin onto every
     numbered app heading, on top of the box's own padding. The appbox selector
     below is scoped one level deeper so it wins everywhere instead. */
  .doc .sec h3{margin:44px 0 14px;font-size:1.375rem}
  .doc .sec .appbox h3{margin:0 0 14px}
  .doc .pullquote{font-size:1.5rem;line-height:1.32;margin:48px 0;max-width:none}
  .doc .plist{gap:20px}

  .doc .appbox{padding-top:40px;margin-top:48px}
  .doc .appbox .tagline{font-size:1.0625rem;margin-bottom:22px}
  .doc .specs{margin-bottom:28px}
  .doc .pc > div + div{margin-top:28px}
  .doc .pc ul{gap:14px}
  .doc .verdict{padding:20px;margin-top:28px}

}

/* ═══════════════════════════════════════════════════════════
   v6 · two block types removed, replaced with type and rules
   ═══════════════════════════════════════════════════════════ */


/* ── the chooser ───────────────────────────────────────────
   Was eight boxed cards in a grid, which repeated the same chrome
   eight times and put three of our own entries in a row. Now a
   definition list: the situation on the left, the answer on the
   right, hairlines doing the separating. Seven rows, five of them
   somebody else's app. */
.doc .chooser{margin:38px 0 12px;border-top:1px solid var(--color-border)}
.doc .ch-row{display:grid;grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);gap:8px 48px;
  padding:28px 0;border-bottom:1px solid var(--color-border);align-items:baseline}
.doc .chooser dt{font-size:1.1875rem;font-weight:500;letter-spacing:-.024em;line-height:1.32;
  color:var(--color-text-primary);text-wrap:balance}
.doc .chooser dd{font-size:var(--fs-body);line-height:1.66;color:var(--color-prose);max-width:46ch}
.doc .ch-app{display:block;font-weight:600;font-size:1.0625rem;letter-spacing:-.018em;
  color:var(--color-text-primary);margin-bottom:7px}
.doc .ch-row.is-own .ch-app{color:var(--lav-ink)}
.doc .ch-row:hover dt{color:var(--color-text-primary)}

@media (max-width:640px){
  .doc .chooser{margin:30px 0 8px}
  .doc .ch-row{grid-template-columns:1fr;gap:10px;padding:24px 0}
  .doc .chooser dt{font-size:1.125rem}
  .doc .chooser dd{max-width:none}
}

/* ═══════════════════════════════════════════════════════════
   v7 · article tail: who wrote it, what to read next
   ═══════════════════════════════════════════════════════════ */

/* ── author block ──────────────────────────────────────────
   Type and whitespace only, no rule and no box. The logo mark
   is the anchor. */
.doc .byline{display:grid;grid-template-columns:auto minmax(0,1fr);gap:20px;margin:84px 0 0;max-width:62ch}
.doc .byline-mark{width:44px;height:44px;display:flex;align-items:center;justify-content:center;
  background:var(--color-primary);color:#fff;border-radius:50%;flex-shrink:0}
.doc .byline-mark svg{width:21px;height:21px}
.doc .byline-label{font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.13em;
  color:var(--color-text-tertiary);margin:0 0 8px}
.doc .byline-name{font-size:1.0625rem;font-weight:600;letter-spacing:-.018em;
  color:var(--color-text-primary);margin:0 0 12px}
.doc .byline-body > p:last-child{font-size:var(--fs-body-sm);line-height:1.72;color:var(--color-prose);margin:0}
.doc .byline a{color:var(--color-text-primary);text-decoration:underline;text-underline-offset:3px;
  text-decoration-thickness:1px;text-decoration-color:var(--color-border-strong);transition:text-decoration-color .15s}
.doc .byline a:hover{text-decoration-color:var(--color-text-primary)}


@media (max-width:640px){
  .doc .byline{margin-top:64px;gap:16px;max-width:none}
  .doc .byline-mark{width:38px;height:38px}
  .doc .byline-mark svg{width:18px;height:18px}
}

/* ═══════════════════════════════════════════════════════════
   v8 · "Keep reading" as a full width rail
   Sits outside .wrap so it can bleed past the article column.
   The rail's inner padding is calculated to line up with the
   article text, then the last card runs off the right edge on
   purpose: the peek is the only affordance it needs.
   ═══════════════════════════════════════════════════════════ */
.doc .tail{
  --gut:max(var(--page-pad), calc((100vw - 1230px) / 2 + var(--page-pad)));
  border-top:1px solid var(--color-border);
  margin-top:72px;padding:52px 0 60px;
}
.doc .tail-h{font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.13em;
  color:var(--color-text-tertiary);margin:0 0 24px}

.doc .tail-rail{
  display:flex;gap:22px;
  overflow-x:auto;overscroll-behavior-x:contain;-webkit-overflow-scrolling:touch;
  scroll-snap-type:x proximity;
  padding:0 var(--gut) 6px;
  scroll-padding-left:var(--gut);
}
.doc .tail-rail{scrollbar-width:none;-ms-overflow-style:none}
.doc .tail-rail::-webkit-scrollbar{display:none}

.doc .rc{flex:0 0 300px;scroll-snap-align:start;display:block}
.doc .rc-img{
  display:grid;place-items:center;
  aspect-ratio:16/10;margin-bottom:18px;border-radius:16px;overflow:hidden}
.doc .rc-img svg{width:56px;height:56px}
.doc .rc-lav{background:var(--lav-bg);color:var(--lav-ac)}
.doc .rc-peach{background:var(--peach-bg);color:var(--peach-ac)}
.doc .rc-mint{background:var(--mint-bg);color:var(--mint-ac)}
.doc .rc-rose{background:var(--rose-bg);color:var(--rose-ac)}

.doc .rc-eye{display:block;font-size:.6875rem;font-weight:600;text-transform:uppercase;
  letter-spacing:.11em;color:var(--color-text-tertiary);margin-bottom:10px}
.doc .rc-t{display:block;font-size:1.125rem;font-weight:500;letter-spacing:-.022em;line-height:1.36;
  color:var(--color-text-primary);text-wrap:pretty}
.doc .rc:hover .rc-t{text-decoration:underline;text-underline-offset:4px;
  text-decoration-thickness:1px;text-decoration-color:var(--color-border-strong)}

@media (max-width:640px){
  .doc .tail{margin-top:56px;padding:40px 0 46px}
  .doc .tail-h{margin-bottom:20px}
  .doc .tail-rail{gap:16px;padding-bottom:4px}
  .doc .rc{flex-basis:230px}
  .doc .rc-img{margin-bottom:14px}
  .doc .rc-img svg{width:46px;height:46px}
  .doc .rc-t{font-size:1.0625rem}
}


/* ═══════════════════════════════════════════════════════════
   v9 · pull quotes reveal word by word
   The sentence assembles itself as it enters the reading zone,
   which is enough movement to make the eye stop without turning
   into a gimmick. Three per article, roughly one per 1000 words.

   No-JS safety: the words are visible by default. Only once the
   inline head script has added .js to <html> does the hidden
   start state apply, so the text can never end up invisible to a
   reader while still being present for a crawler.
   ═══════════════════════════════════════════════════════════ */
.doc html.js .pullquote > span{
  display:inline-block;
  opacity:0;
  transform:translateY(.34em);
  transition:opacity .44s var(--ease),transform .44s var(--ease);
  transition-delay:var(--d,0ms);
}
.doc html.js .pullquote.in > span{opacity:1;transform:none}

@media (prefers-reduced-motion:reduce){
  .doc html.js .pullquote > span{opacity:1;transform:none;transition:none;transition-delay:0s}
}

/* ═══════════════════════════════════════════════════════════
   v10 · footer
   A hard black terminus after the light CTA band. Four link
   groups plus a brand block, then a legal row.
   ═══════════════════════════════════════════════════════════ */
.doc .footer{
  --f-ink:#fff;
  --f-mute:rgba(255,255,255,.56);
  --f-dim:rgba(255,255,255,.38);
  --f-line:rgba(255,255,255,.12);
  background:#0A0A0C;color:var(--f-ink);
  border-top:0;padding:80px 0 44px;margin-top:0;
}
.doc .footer .wrap{max-width:1230px}

.doc .f-top{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.45fr);gap:64px;padding-bottom:56px}

.doc .f-logo{display:inline-flex;align-items:center;gap:10px;font-size:1.0625rem;font-weight:600;
  letter-spacing:-.024em;color:var(--f-ink)}
.doc .f-logo .logo-mark{width:28px;height:28px;background:#fff;color:#0A0A0C;
  display:flex;align-items:center;justify-content:center;border-radius:7px}
.doc .f-logo .logo-mark svg{width:16px;height:16px}
.doc .f-blurb{margin:20px 0 26px;font-size:.9375rem;line-height:1.65;color:var(--f-mute);max-width:38ch}

.doc .f-cta{display:inline-flex;align-items:center;gap:8px;height:42px;padding:0 20px;
  background:#fff;color:#0A0A0C;border-radius:var(--r-pill);
  font-size:.875rem;font-weight:600;letter-spacing:-.008em;transition:opacity .15s}
.doc .f-cta:hover{opacity:.85}
.doc .f-cta svg{width:14px;height:14px}






.doc .f-cols{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:40px 28px}
.doc .f-col{display:flex;flex-direction:column;align-items:flex-start}
.doc .f-h{font-size:.6875rem;font-weight:600;text-transform:uppercase;letter-spacing:.13em;
  color:var(--f-dim);margin:0 0 18px}
.doc .f-col a{font-size:.9063rem;line-height:1.35;color:var(--f-mute);padding:6px 0;transition:color .15s}
.doc .f-col a:hover{color:var(--f-ink)}

.doc .f-bottom{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:16px 32px;
  padding-top:30px;border-top:1px solid var(--f-line)}
.doc .f-copy{font-size:.8125rem;color:var(--f-dim);margin:0}
.doc .f-legal{display:flex;flex-wrap:wrap;gap:24px}
.doc .f-legal a{font-size:.8125rem;color:var(--f-dim);transition:color .15s}
.doc .f-legal a:hover{color:var(--f-ink)}

.doc .f-note{margin:26px 0 0;font-size:.75rem;line-height:1.6;color:rgba(255,255,255,.28);max-width:78ch}

@media (max-width:980px){
  .doc .f-top{grid-template-columns:1fr;gap:48px;padding-bottom:44px}
  .doc .f-blurb{max-width:46ch}
  .doc .f-cols{gap:36px 24px}
}
@media (max-width:640px){
  .doc .footer{padding:56px 0 36px}
  .doc .f-top{gap:40px;padding-bottom:36px}
  .doc .f-cols{grid-template-columns:repeat(2,minmax(0,1fr));gap:32px 20px}
  .doc .f-blurb{max-width:none;margin:18px 0 24px}
  
  .doc .f-bottom{flex-direction:column;align-items:flex-start;gap:14px;padding-top:26px}
  .doc .f-legal{gap:16px 20px}
}

.doc .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
/* ═══════════════════════════════════════════════════════════
   Article images
   Cards and the article hero both fall back to a pastel block
   with a line icon when an article has no image yet. Setting
   `image` in config/content.php swaps in a real photo without
   touching any markup: the box, the radius and the aspect
   ratio are already reserved here, so nothing shifts.
   ═══════════════════════════════════════════════════════════ */
.doc .rc-img img,
.doc .hero-card img{width:100%;height:100%;object-fit:cover;display:block}
.doc .rc-photo,
.doc .hero-photo{background:var(--color-bg-tertiary)}

/* ═══════════════════════════════════════════════════════════
   Hub · /blog
   Same publication as the articles: uppercase eyebrows, tight
   sans headline, pastel cards, squared blocks. The listing adds
   one thing on top, a horizontal lead card, so the newest piece
   does not sit in the grid looking like everything else.
   ═══════════════════════════════════════════════════════════ */
.doc .hub-head{padding:34px 0 0;max-width:62ch}
.doc .hub-eye{font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.13em;
  color:var(--color-text-tertiary);margin:0 0 16px}
.doc .hub-head h1{font-size:clamp(2.15rem,5vw,3.35rem);font-weight:800;letter-spacing:-.035em;
  line-height:1.05;margin:0;max-width:15ch}
.doc .hub-intro{margin:22px 0 0;font-size:1.15rem;line-height:1.6;color:var(--color-prose);
  max-width:56ch;text-wrap:pretty}

/* Lead card: art on the right so the headline still starts at the
   same optical line as the h1 above it. */
.doc .lead{display:grid;grid-template-columns:minmax(0,1fr) minmax(280px,46%);
  gap:56px;align-items:center;margin:56px 0 0;padding:0 0 52px;
  border-bottom:1px solid var(--color-border)}
.doc .lead-copy{min-width:0;display:flex;flex-direction:column;align-items:flex-start}
.doc .lead-eye{font-size:.6875rem;font-weight:600;text-transform:uppercase;letter-spacing:.11em;
  color:var(--color-text-tertiary);margin:0 0 14px}
.doc .lead-t{font-size:clamp(1.6rem,3vw,2.15rem);font-weight:600;letter-spacing:-.028em;
  line-height:1.16;margin:0;color:var(--color-text-primary);text-wrap:pretty}
.doc .lead:hover .lead-t{text-decoration:underline;text-underline-offset:5px;
  text-decoration-thickness:1px;text-decoration-color:var(--color-border-strong)}
.doc .lead-d{margin:16px 0 0;font-size:var(--fs-body);line-height:1.65;color:var(--color-prose);
  max-width:52ch;text-wrap:pretty}
.doc .lead-meta{display:flex;align-items:center;flex-wrap:wrap;gap:6px 18px;margin:22px 0 0;
  font-size:.8125rem;color:var(--color-text-tertiary)}
.doc .lead-media{min-width:0;aspect-ratio:16/10;border-radius:16px;overflow:hidden;
  display:grid;place-items:center}
.doc .lead-media svg{width:78px;height:78px}

/* Filter. Plain buttons, no JS framework: content.js toggles a
   data attribute on the grid and CSS does the hiding, so the
   markup for every card stays in the HTML for crawlers. */
.doc .hub-filter{display:flex;flex-wrap:wrap;gap:8px;margin:44px 0 0}
.doc .hub-filter button{font:inherit;font-size:.8125rem;font-weight:500;line-height:1;
  padding:9px 16px;border:1px solid var(--color-border);border-radius:var(--r-pill);
  background:transparent;color:var(--color-text-secondary);cursor:pointer;
  transition:border-color .15s,color .15s,background .15s}
.doc .hub-filter button:hover{color:var(--color-text-primary);border-color:var(--color-border-strong)}
.doc .hub-filter button[aria-pressed="true"]{background:var(--color-primary);
  border-color:var(--color-primary);color:#fff}
.doc .hub-filter button:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}

/* The hub used to get its bottom breathing room from the promo band that sat
   between the grid and the footer. With the band gone the grid needs to carry
   that space itself, otherwise the cards run straight into the black footer. */
.doc .hub-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:44px 28px;
  margin:36px 0 0;padding:0 0 72px}
.doc .hub-grid .rc{flex:none}
.doc .hub-grid .rc[hidden]{display:none}

.doc .hub-empty{margin:36px 0 72px;font-size:var(--fs-body);line-height:1.65;
  color:var(--color-text-secondary)}

@media (max-width:980px){
  .doc .lead{grid-template-columns:1fr;gap:28px;margin-top:44px;padding-bottom:44px}
  .doc .lead-copy{order:2}
  .doc .lead-media{order:1}
  .doc .hub-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:38px 24px}
}
@media (max-width:640px){
  .doc .hub-head{padding-top:26px}
  .doc .hub-head h1{font-size:2.35rem;line-height:1.08;max-width:none}
  .doc .hub-intro{font-size:1.0625rem;margin-top:18px}
  .doc .lead{gap:22px;margin-top:36px;padding-bottom:36px}
  .doc .lead-media svg{width:60px;height:60px}
  .doc .hub-filter{margin-top:32px;gap:7px}
  .doc .hub-grid{grid-template-columns:1fr;gap:34px;padding-bottom:48px}
}

/* ═══════════════════════════════════════════════════════════
   Keyboard focus
   Nothing in this file suppresses the browser's outline, but
   the default ring is thin against a white page and disappears
   over the dark footer. One consistent ring everywhere, only
   for keyboard users, so mouse clicks stay clean.
   ═══════════════════════════════════════════════════════════ */
.doc a:focus-visible,
.doc button:focus-visible,
.doc summary:focus-visible{
  outline:2px solid var(--color-primary);
  outline-offset:3px;
  border-radius:2px}
.doc .footer a:focus-visible{outline-color:#fff}

/* ═══════════════════════════════════════════════════════════
   Navbar on content pages
   Scoped under .doc, so /landing and /changelog keep the
   navbar exactly as it is. Two differences here, both from
   the article prototype:

   1. A hairline under the bar. Drawn as an inset shadow, not
      a border: a border would make the element 73px tall and
      put it out of step with --nav-h, the .page offset, the
      scroll anchor and the mobile menu's top:72px. A shadow
      paints the same line and costs no layout.

   2. The bar is widened from 1200px to the 1230px the article
      column uses, on the same --page-pad. Without this the
      wordmark sits 15px inboard of the breadcrumb directly
      beneath it, which reads as a misalignment rather than a
      choice.
   ═══════════════════════════════════════════════════════════ */
.doc .lp-nav{box-shadow:inset 0 -1px 0 var(--color-border-light)}
.doc .lp-nav-inner{max-width:1230px;padding:0 var(--page-pad)}

/* ═══════════════════════════════════════════════════════════
   Long-form guide components
   Added for the practitioner guides, which are step-driven
   rather than comparison-driven. Everything below reuses the
   existing tokens: no new colours, no new radii.
   ═══════════════════════════════════════════════════════════ */

/* ─── Numbered steps ──────────────────────────────────────
   The step number is a real element rather than a counter on
   the <ol>, because the heading has to carry the anchor and a
   list marker cannot be targeted by the TOC scroll spy.       */
.doc .step-n{display:inline-flex;align-items:center;justify-content:center;
  width:26px;height:26px;margin-right:12px;flex-shrink:0;
  background:var(--color-primary);color:#fff;border-radius:50%;
  font-size:.75rem;font-weight:700;letter-spacing:0;line-height:1;
  vertical-align:.14em}
.doc .sec h2 .step-n{vertical-align:.18em}

/* ─── Stat strip ──────────────────────────────────────────
   Three or four figures with a caption. Wraps to one column
   under 560px rather than shrinking the numbers, so the digits
   stay legible on a phone.                                    */
.doc .stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));
  gap:1px;background:var(--color-border);border:1px solid var(--color-border);
  margin:32px 0 12px}
.doc .stats > div{background:var(--color-bg);padding:24px 22px}
.doc .stats .s-n{display:block;font-size:clamp(1.75rem,5vw,2.25rem);font-weight:800;
  letter-spacing:-.04em;line-height:1;color:var(--color-text-primary);margin-bottom:10px}
.doc .stats .s-l{display:block;font-size:.9375rem;line-height:1.5;
  color:var(--color-prose);text-wrap:pretty}
.doc .stats .s-src{display:block;margin-top:10px;font-size:.75rem;line-height:1.4;
  color:var(--color-text-tertiary)}
.doc .stats .s-src a{border-bottom:1px solid var(--color-border-strong)}
.doc .stats .s-src a:hover{color:var(--color-text-primary)}

/* ─── Checklist ───────────────────────────────────────────
   Distinct from .plist: this is a thing you tick off, so it
   gets a box glyph and tighter spacing.                       */
.doc .checklist{display:flex;flex-direction:column;gap:13px;margin:8px 0 26px;
  font-size:var(--fs-body);line-height:1.6;color:var(--color-prose);text-wrap:pretty}
.doc .checklist li{display:flex;gap:13px}
.doc .checklist li::before{content:"";flex-shrink:0;width:17px;height:17px;margin-top:.24em;
  border:1.5px solid var(--color-border-strong);border-radius:4px;
  background:no-repeat center/10px 10px
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239CA3AF' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12.5 9.5 18 20 6'/%3E%3C/svg%3E")}
.doc .checklist strong{font-weight:600;color:var(--color-text-primary)}

/* ─── Sources ─────────────────────────────────────────────
   Editorial references. :target highlights the row you jumped
   to, so a superscript click lands somewhere visible instead
   of leaving the reader to scan a list of fourteen.           */
.doc .sources{margin:14px 0 0;padding:0;list-style:none;counter-reset:src}
.doc .sources li{counter-increment:src;position:relative;padding:11px 0 11px 34px;
  font-size:.875rem;line-height:1.55;color:var(--color-text-secondary);
  border-bottom:1px solid var(--color-border-light);text-wrap:pretty}
.doc .sources li::before{content:counter(src) ".";position:absolute;left:0;top:11px;
  font-size:.8125rem;font-weight:600;color:var(--color-text-tertiary)}
.doc .sources li:target{background:var(--own-bg);
  box-shadow:-10px 0 0 var(--own-bg),10px 0 0 var(--own-bg)}
.doc .sources a{color:var(--color-text-primary);border-bottom:1px solid var(--color-border-strong)}
.doc .sources a:hover{border-bottom-color:var(--color-text-primary)}
.doc .sources .s-pub{color:var(--color-text-tertiary)}

/* ─── Disclaimer ──────────────────────────────────────────
   Sits at the very end, under the sources. Deliberately plain:
   it is a legal notice, not a callout competing for attention. */
.doc .disclaimer{margin:34px 0 0;padding:18px 20px;background:var(--color-bg-secondary);
  border-left:2px solid var(--color-border-strong);
  font-size:.8125rem;line-height:1.6;color:var(--color-text-secondary);text-wrap:pretty}
.doc .disclaimer strong{color:var(--color-text-secondary);font-weight:600}

@media (max-width:640px){
  .doc .stats > div{padding:20px 18px}
  .doc .step-n{width:23px;height:23px;font-size:.6875rem;margin-right:9px}
}
