
/* Typefaces: see the TYPEFACES block in :root and docs/brand/typography.md.
   Latin subsets (en dashes and curly quotes included). swap = text shows at
   once in the fallback and changes face when the file lands. */
@font-face{font-family:'Lexend';font-style:normal;font-weight:100 900;font-display:swap;
  src:url(/assets/fonts/lexend.woff2) format('woff2')}
@font-face{font-family:'Scope One';font-style:normal;font-weight:400;font-display:swap;
  src:url(/assets/fonts/scope-one.woff2) format('woff2')}
@font-face{font-family:'Caprasimo';font-style:normal;font-weight:400;font-display:swap;
  src:url(/assets/fonts/caprasimo.woff2) format('woff2')}
/* ---------------------------------------------------------------------------
   BRAND PALETTE -- from Brand_Colors_Chart.pdf, Darby + designer, 2026-09.
   Same colors as the Fraternal Youth cover.

   Weight, most to least:
     Azure Blue 7, Magenta 6, Cosmic Periwinkle 5, Teal 4,
     Light Periwinkle Blue 3, Golden Hour 2, Yellow 1.

   Azure and Magenta are too light for small text on off-white (3.4:1 and
   3.8:1; readable body text needs 4.5:1). So small text uses the -deep shades,
   and the true brand colors go on fills, borders and large display type, where
   3:1 is enough. Cosmic Periwinkle is the only brand color dark enough to be
   text as-is, which is why it carries the headings and the masthead.

   DERIVED, not on the chart: --azure-deep, --magenta-deep, --ink-soft,
   --ink-faint, and the dark-mode surfaces. Each was computed to pass 4.5:1 on
   every background it sits on. Worth the designer's sign-off.
   --------------------------------------------------------------------------- */
:root{
  /* base colors */
  --azure:#1D91C2;  --magenta:#D64A97;  --cosmic:#564786;  --golden:#F6D86B;
  --teal:#2BB6B2;   --peri:#8F9EF9;     --yellow:#F8E18F;
  /* supporting colors */
  --mint:#66DDAA;   --peri-light:#C5D1FA;
  /* DERIVED. Mint taken from 63% lightness / 64% saturation down to 50 / 55,
     and turned toward Teal (hue 154 -> 166). Mint glows against a saturated
     fill; Teal vanishes into one. This is the last stop between them: at
     2.46:1 on the magenta it is the dimmest edge that still reads. Anything
     darker measures at or below Teal's 2.12:1 and stops being a border. */
  --mint-deep:#39C6A5;
  /* DERIVED 2026-10-22 (Darby). Cosmic Periwinkle darkened, for the top bar,
     so the wordmark's Light Periwinkle Blue and Fresh Mint stand out on it:
     4.8:1 and 7.1:1 (on Cosmic they were 3.2 and 4.7). On the chart. */
  --cosmic-deep:#3A2F5E;
  /* DERIVED 2026-10-22 (Darby). Azure Blue lightened (6.3:1 on Cosmic Deep),
     what DARB turns on hover. On the chart. */
  --azure-light:#6EC6EE;
  --yellow-light:#FAEBB4;  --yellow-lighter:#FCF1D6;
  /* neutrals */
  --offwhite:#FAF9F6;  --charcoal:#2E2E2E;
  /* derived for readable text */
  --azure-deep:#17759C;  --magenta-deep:#C32C7F;
  /* DERIVED, for links only. Azure Deep passed at 4.9:1 but read thin in a
     serif paragraph. Same hue, lightness 35% -> 26%: 7.66:1 on Off-White,
     7.18:1 on Lighter Yellow. Buttons stay on Azure Deep. */
  --azure-ink:#115673;
  /* NEW 2026-11-08 (Darby): Top 10's pink on the nations map. Not on the chart
     yet; only used as a border and large label on Cosmic Deep (7.1:1). */
  --pink-light:#F28DC4;

  /* roles -- rules below use these, never the raw colors */
  --ink:var(--charcoal); --ink-soft:#55525E; --ink-faint:#6B6778;
  /* --paper-2 is the raised surface: price cards, the billing switch, embeds.
     White since 2026-10-23 (was Lighter Yellow) - Darby retired the yellow
     boxes. Callouts have their own fills, below. */
  --paper:var(--offwhite); --paper-2:#FFFFFF; --line:var(--peri-light);
  --link:var(--cosmic-deep); --link-hover:var(--magenta-deep);
  --accent:var(--azure-deep); --on-accent:#fff;
  --heading:var(--cosmic); --display-accent:var(--magenta); --label:var(--magenta-deep);
  /* Headline hierarchy: the three heaviest brand colors, one per level, then
     back to the anchor. Magenta (3.77:1) and Azure (3.39:1) only pass as
     LARGE type, so they are for h2 and h3 at their set sizes and nothing
     smaller. --heading stays Cosmic for the small uppercase labels. */
  --h1:var(--magenta); --h2:var(--azure); --h3:var(--cosmic); --h4:var(--label);
  --band:var(--cosmic-deep); --band-ink:var(--offwhite); --band-soft:var(--peri-light);
  --band-accent:var(--yellow-light);   /* menu hover + current page (2026-10-22, Darby; was Golden Hour) */
  --wordmark-darb:var(--peri); --wordmark-nation:var(--mint);
  --wordmark-darb-hover:var(--azure-light); --wordmark-nation-hover:var(--peri-light);
  /* The header's purple and its wordmark pairs, reused (2026-10-22, Darby):
     footer band, signup box, button and pill hovers, selected text.
     --band-faint is the dark-mode faint text, 5.9:1 on Cosmic Deep. */
  --band-faint:#ABA6BA;
  /* The nations map (2026-11-08, Darby): one color per section. Hope is gold,
     and so is DarbNation's own border: "a nation of hope". */
  --map-top10:var(--pink-light); --map-hope:var(--golden); --map-book:var(--peri);
  --map-blog:var(--peri-light); --map-music:var(--mint-deep); --map-vids:var(--azure-light);
  --map-memes:var(--mint); --map-border:var(--golden); --map-blank:var(--band-faint);
  --map-neighbor:var(--peri-light);
  /* Subscribe is an outlined button in the header, map and bar (2026-11-08
     night, Darby): the money link stands out from About / Contact. */
  --sub-btn:var(--golden); --sub-btn-ink:var(--cosmic-deep);
  --signup-fill:var(--cosmic-deep); --signup-head:var(--mint); --signup-ink:var(--peri-light);
  --signup-btn:var(--peri); --signup-btn-hover:var(--azure-light); --signup-btn-ink:var(--cosmic-deep);
  --hover-fill:var(--cosmic-deep); --hover-ink:var(--azure-light);
  /* Secondary buttons (Buy me a coffee, Amazon reviews, Headlines of Hope):
     Magenta Deep with white, 5.3:1 (2026-10-22, Darby). Same purple hover. */
  --btn2-fill:var(--magenta-deep); --btn2-ink:#fff;
  /* Third button (2026-10-30, Darby): white, Cosmic Deep words and edge -
     the /book sample link, so it differs from the azure and magenta ones.
     Same purple hover as every button. Stays white in dark mode. */
  --btn3-fill:#fff; --btn3-ink:var(--cosmic-deep); --btn3-line:var(--cosmic-deep);
  --rule:var(--magenta); --gold:var(--golden); --hover-border:var(--teal);
  /* The price tiers fill on hover, and must not be confused with the azure
     CTA buttons next to them -- a tier is a different kind of thing. Magenta
     is the second brand weight and carries white at 5.27:1. A tier with no
     link yet fills too, but with the soft neutral, never the action colour. */
  --tier-fill:var(--magenta-deep); --tier-ink:#fff;
  /* The edge on a hovered live tier. Against the magenta fill: Mint 3.13:1 but
     it glows, Teal 2.12:1 and you cannot see it, Mint Deep 2.46:1 and calm.
     This is the bottom of the useful range -- if it still reads too hot, the
     fix is a lighter edge or no edge, not a darker one. */
  --tier-edge:var(--mint-deep);
  --tier-off-fill:var(--line); --tier-off-ink:var(--ink);
  /* CALLOUTS (2026-10-23, Darby). Six boxes, one job each - the jobs are in
     docs/brand/brand-colors.md and posts/_guide.md. Every one has the same
     Cosmic Deep headline and a 5px edge. Magenta edge on the white Ask card
     ONLY, so magenta keeps meaning "this is the ask"; each tinted box takes
     the deep shade of its own fill (Darby, 2026-10-23 - first version had
     magenta on all five). Every edge is ~3:1 on its own fill, light and
     dark. Periwinkle Deep, Lilac, Lilac Deep, Sage and Sage Deep were added
     to the palette for these. Body text on every fill is 11:1+. */
  --co-head:var(--cosmic-deep);
  --co-ask:#FFFFFF;    --co-ask-line:var(--peri-light);  --co-ask-edge:var(--magenta);
  --co-note:#EEF1FE;   --co-note-line:var(--peri-light); --co-note-edge:#6E7EEB;
  --co-deeper:#E6F3FA; --co-deeper-line:#B9DEF1;         --co-deeper-edge:var(--azure);
  --co-heads:#F4ECFF;  --co-heads-line:#DCC9F7;          --co-heads-edge:#9B6BE0;
  --co-try:#EAF2E3;    --co-try-line:#C9DDB8;            --co-try-edge:#5E9A40;
  /* Warning (2026-10-23, Darby): Lighter Yellow box, gold edge, and a
     cherry-red title - Cherry #D2042D, 4.9:1 on the fill, so it passes as
     small bold text. The only red on the site; keep it to warnings. The
     edge is Golden Hour, the darkest yellow on the chart (Darby swapped out
     a burnt gold #D4AA2E the same day). It is softer than the others' ~3:1
     on purpose; the cherry title does the shouting. */
  --co-warn:var(--yellow-lighter); --co-warn-line:#F3DFA0; --co-warn-edge:var(--golden);
  --co-warn-head:#D2042D;
  /* POST-LIST HOVER (2026-10-23, Darby). Rows on /, /writing and /topics
     cycle through four title colors, and each subtitle takes a contrasting
     partner. Titles are large type (3:1 is enough); subtitles are small and
     pass 4.5:1. See HUE_ANCHOR for how a post gets its number. */
  /* Revised the same morning: Darby swapped the lilac/periwinkle pair for
     stronger colors and alternated the pink-blue rows with the
     purple-green ones. No orange, by Darby's choice. */
  --hue1-title:var(--magenta);  --hue1-sub:var(--azure-deep);    /* 3.8 / 4.9 */
  --hue2-title:var(--cosmic);   --hue2-sub:#137A76;              /* 7.6 / Teal Deep 4.9 */
  --hue3-title:var(--azure);    --hue3-sub:var(--magenta-deep);  /* 3.4 / 5.0 */
  --hue4-title:#1F7A55;         --hue4-sub:var(--cosmic);        /* Forest 5.0 / 7.6 */
  /* MEME TOPIC TILES (2026-11-02, Darby: Option A). Six brand fills, cycling:
     Cosmic Deep, Magenta Deep, Azure Deep, Cosmic, Golden Hour, Mint. White
     words on the first four (7.6-12:1 down to Azure Deep 4.9:1), Cosmic Deep
     on the two light ones (9:1+). Same fills in dark mode; --tile-edge gives
     the dark tiles an outline on Charcoal. */
  --tile1:var(--cosmic-deep); --tile2:var(--magenta-deep); --tile3:var(--azure-deep);
  --tile4:var(--cosmic); --tile5:var(--golden); --tile6:var(--mint);
  --tile-ink:#fff; --tile-ink-dark:var(--cosmic-deep); --tile-edge:transparent;
  /* MEME TOPIC TREE (2026-11-03, Darby: "Darby's mix" on the "Meme Topic
     Tree Options" canvas). Light boxes for topics with topics under them,
     periwinkle limbs, pink "N topics" toggles, and the name turns Magenta
     Deep while its row is hovered. Tints are DERIVED from Note blue; every
     text pair passes 4.5:1 on every fill it sits on, light and dark
     (name 10.7+, count 4.9+, pink 4.7+ light; 6.4 / 5.4 / 5.1+ dark). */
  --tree-par:#F4F6FE; --tree-par-line:#DCE2FB; --tree-hover:var(--co-note);
  --tree-on-line:var(--peri-light); --tree-limb:var(--peri);
  --tree-hot:var(--magenta-deep); --tree-count:var(--ink-faint);
  --max:44rem;
  /* ---- TYPEFACES (approved 2026-10-22) -----------------------------------
     docs/brand/typography.md. Three faces, each with one job, all served from
     /assets/fonts/ (static/fonts/ in the repo) so every device shows the same
     thing and nothing loads from Google.
       Caprasimo  the DarbNation wordmark, and nothing else
       Scope One  titles and headings, h1-h4. One weight only (400), so a
                  heading never asks for bold - the browser would fake it.
       Lexend     everything else: essay text, buttons, nav, prices, labels.
     Rules use these three role tokens, never a family name. */
  --font-wordmark:'Caprasimo',Georgia,serif;
  --font-title:'Scope One',Georgia,'Times New Roman',serif;
  --font-body:'Lexend',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
  /* The screenplay passage in the /book sample (2026-10-30, Darby): the
     device's own monospace, the one place a fourth face is allowed. */
  --font-mono:ui-monospace,'Cascadia Mono',Consolas,'Courier New',monospace;

  /* ---- SPACING SCALE -------------------------------------------------------
     Nine steps on a 4px base. Full reasoning in docs/brand/layout-spacing.md.

     No rule below this line uses a raw length for margin, padding or gap. If a
     gap needs a value that is not on this scale, the scale is wrong -- fix it
     here, once, rather than inventing a fortieth number in one component.

     The scale before this existed: 42 different values, so the space between
     any two things was whatever three unrelated rules happened to add up to. */
  --space-3xs:.25rem;  /*  4px  hairline: label to the thing it labels        */
  --space-2xs:.5rem;   /*  8px  inside a control                             */
  --space-xs:.75rem;   /* 12px  tight pair                                   */
  --space-s:1rem;      /* 16px  heading to its own paragraph                 */
  --space-m:1.5rem;    /* 24px  DEFAULT. paragraph to paragraph              */
  --space-l:2rem;      /* 32px  block to block down a page                   */
  --space-xl:3rem;     /* 48px  one section to the next                      */
  --space-2xl:4rem;    /* 64px  page top, and away from the footer           */
  --space-3xl:6rem;    /* 96px  reserved for the home hero                   */

  /* ---- TYPE SCALE (2026-10-22, docs/brand/typography.md) -----------------
     Nine named sizes. Nothing on the site is smaller than --text-fine (15px,
     Darby's floor). No rule below uses a raw font-size: if a size is not
     here, the scale is wrong -- fix it here, once. */
  --text-fine:.9375rem;   /* 15px  THE FLOOR. dates, captions, labels, fine print */
  --text-ui:1rem;         /* 16px  buttons, nav, form, checklists, card blurbs    */
  --text-body:1.0625rem;  /* 17px  essay text (16px on phones, see bottom)        */
  --text-lead:1.3125rem;  /* 21px  subtitles, page intros                         */
  --text-read:1.1875rem;  /* 19px  /book sample stories (18px on phones, Darby)   */
  --text-wordmark:1.8375rem; /* 29.4px the DarbNation masthead only (lead x1.4) */
  --text-wordmark-bar:1.5rem;   /* 24px  wordmark in the desktop bar after the map scrolls away */
  /* Phone header, stacked DARB over NATION, the same width (87px at 360+;
     caps since 2026-11-08 night - was Darb 34.2 / Nation 25). */
  --text-mark-darb:min(1.79rem,7.95vw);     /* 28.6px */
  --text-mark-nation:min(1.275rem,5.67vw);  /* 20.4px */
  /* Phone header (2026-11-08): links 18px at 360, 19 from 380; row three
     16 at 360, 17 from 383. Under 360 everything shrinks with the screen
     (wordmark too) and stops at the 15px floor. */
  --text-nav-phone:clamp(.9375rem,5vw,1.1875rem);
  --text-nav-phone-sm:clamp(.9375rem,4.45vw,1.0625rem);
  --nav-phone-gap:var(--space-2xs);   /* the least space between phone links; justify adds the rest */
  --text-ghost:13.64vw;   /* slim phone nav's ghost wordmark: Caprasimo "DARBNATION"
                             ink is 7.331em wide, so this spans the screen edge to edge
                             (16.81vw for "DarbNation", 5.949em, until 2026-11-08) */
  --text-h4:1.625rem;     /* 26px  h4, card titles (22 until 2026-10-22, Darby)   */
  --text-h3:1.9375rem;    /* 31px  h3 (27 until 2026-10-22)                       */
  --text-h2:2.25rem;      /* 36px  h2 (32 until 2026-10-22)                       */
  --text-price:2rem;      /* 32px  big prices - stayed put when headings grew     */
  --text-price-sm:1.6875rem; /* 27px prices on the small cards                   */
  --text-title:clamp(2.35rem,calc(5.5vw + .25rem),3.4rem);  /* 38-54px essay titles */
  --text-hero:clamp(2.85rem,calc(8vw + .25rem),4.75rem);    /* 46-76px pink headlines */

  --gutter:var(--space-m);      /* the page's left and right breathing room  */
  --flow-space:var(--space-m);  /* the default gap the flow engine applies   */
}
@media (prefers-color-scheme:dark){
  :root{ --ink:var(--offwhite); --ink-soft:#D9D5E2; --ink-faint:#ABA6BA;
         --paper:var(--charcoal); --paper-2:#38344A; --line:#4A4560;
         --link:var(--peri-light); --link-hover:var(--golden);
         --accent:var(--peri); --on-accent:var(--charcoal);
         --heading:var(--peri-light); --label:var(--teal);
         /* On Charcoal: Magenta 3.42:1, Teal 5.46:1, Lighter Periwinkle 8.97:1.
            Azure would pass too, but Teal is its own family and reads brighter. */
         --h1:var(--magenta); --h2:var(--azure); --h3:var(--peri-light);
         --h4:var(--label);
         /* Callouts on Charcoal: each fill is its light color's family,
            darkened. Off-White text 10.4:1+, Lighter Periwinkle heads 7.2:1+. */
         --co-head:var(--peri-light);
         --co-ask:#38344A;    --co-ask-line:#4A4560;
         --co-note:#353A5C;   --co-note-line:#4D5480;
         --co-deeper:#2B3F4D; --co-deeper-line:#3E5A6C;
         --co-heads:#3E3354;  --co-heads-line:#5A4A78;
         --co-try:#34402F;    --co-try-line:#4B5C43;
         /* Warning: yellow darkened; Cherry Light #FF7A8A heads, 4.5:1. */
         --co-warn:#3F3A2A;   --co-warn-line:#5C5438;
         --co-warn-head:#FF7A8A;
         /* Magenta and Azure titles keep their colors on Charcoal (3.4-3.8:1,
            large type). Cosmic and Forest vanish there, so they go to Light
            Periwinkle Blue (5.5) and Mint Deep. Subtitles go light: Azure
            Light 7.1, Teal 5.5, Magenta Light 5.9, Lighter Periwinkle 9.0. */
         --hue2-title:var(--peri);      --hue4-title:var(--mint-deep);
         --hue1-sub:var(--azure-light); --hue2-sub:var(--teal);
         --hue3-sub:#F08BC0;            --hue4-sub:var(--peri-light);
         --tile-edge:var(--line);
         /* Topic tree on the dark panel (#38344A): Magenta Deep vanishes
            there, so the pink goes to Magenta Lighter #F5A3CE (5.1:1+). */
         --tree-par:#3F3A55; --tree-par-line:#544D72; --tree-hover:#46405F;
         --tree-on-line:#6A6290; --tree-hot:#F5A3CE; --tree-count:#C4BFD2; }
}
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--paper);color:var(--ink);
  font-family:var(--font-body);font-size:var(--text-body);line-height:1.7;
  font-synthesis-weight:none;-webkit-font-smoothing:antialiased}
.wrap{max-width:var(--max);margin:0 auto;padding-inline:var(--gutter)}
.wide{max-width:64rem}
a{color:var(--link);text-underline-offset:.18em;text-decoration-thickness:.06em}
a:hover{color:var(--link-hover)}
/* Links in running text are bold. Not a bare `a`: a post-list row and a card
   are each one big link, and that would bold every word inside them. */
.prose a,p a,li a{font-weight:700}
img{max-width:100%;height:auto;display:block;border-radius:4px}
hr{border:0;border-top:1px solid var(--line);--flow-space:var(--space-xl)}
/* Substack wraps its rules in a bare <div>, which made the div the flow
   child and gave the line 24px instead of 48 (2026-10-22). */
.prose>div:not([class]):has(>hr:only-child){--flow-space:var(--space-xl)}
::selection{background:var(--azure-light);color:var(--cosmic-deep)}

/* Browser default margins inside imported Substack markup. Those wrappers nest
   -- a div holding a figure, an li holding a paragraph -- and a nested child's
   UA margin collapses up out of its wrapper and lands as a gap the scale never
   authorised. :where() scores zero specificity, so this reset loses to the
   flow rules right below it for anything that IS a direct child, and wins for
   everything nested, which is exactly the split we want. It also clears the
   40px side margin a browser puts on <figure>. */
.prose :where(p,ul,ol,li,figure,blockquote,pre,h1,h2,h3,h4,h5,h6){margin:0}

/* ---------------------------------------------------------------------------
   FLOW -- the one thing that puts space between two stacked elements.

   Heydon Pickering's owl selector carrying Andy Bell's --flow-space custom
   property. Inside a flow container nothing owns a bottom margin, so the gap
   between any two siblings is exactly one number and can never accumulate.
   Change the gap for one element by setting --flow-space ON THAT ELEMENT;
   custom properties cascade, so that element's own margin picks it up.

   Components below set margin:0 and keep only their internal padding. A
   component does not decide how much room it has around it. That is the
   page's decision, and the page makes it here.
   --------------------------------------------------------------------------- */
.flow,main,.article,.article header,.hero,.hero .wrap,.prose,.prose>div:not([class]),
.efoot,.efoot>section,.book>div,.pricing,footer.site .wrap,.share,.read-next{
  --flow-space:var(--space-m)}
.flow>*,main>*,.article>*,.article header>*,.hero>*,.hero .wrap>*,.prose>*,
.prose>div:not([class])>*,
.efoot>*,.efoot>section>*,.book>div>*,.pricing>*,footer.site .wrap>*,.ehead>*,
.share>*,.read-next>*{
  margin-block:0}
/* A component that is a flow child must never declare its own margin. A class
   selector scores (0,1,0) against the flow rule's (0,0,1), so a stray
   margin:0 on .note or .cards silently wins and collapses the gap to nothing.
   The reset above is the only margin a flow child gets. */
.flow>*+*,main>*+*,.article>*+*,.article header>*+*,.hero>*+*,.hero .wrap>*+*,
.prose>*+*,.prose>div:not([class])>*+*,.efoot>*+*,.efoot>section>*+*,.book>div>*+*,.pricing>*+*,
footer.site .wrap>*+*,.ehead>*+*,.share>*+*,.read-next>*+*{
  margin-block-start:var(--flow-space)}

/* Page-level blocks sit further apart than paragraphs do. */
main,.article{--flow-space:var(--space-l)}
/* A title stays close to its own words. */
.article header{--flow-space:var(--space-2xs)}

/* header */
.masthead{border-bottom:1px solid var(--band);background:var(--band);
  position:sticky;top:0;z-index:20;backdrop-filter:saturate(180%) blur(8px)}
.masthead .wrap{display:flex;align-items:center;gap:var(--space-m);
  padding-block:var(--space-xs)}
/* All caps since 2026-11-08 night (Darby): DARBNATION everywhere. The HTML
   keeps "DarbNation" (what screen readers and search read); CSS shouts it. */
.brand{font-family:var(--font-wordmark);font-weight:400;font-size:var(--text-wordmark);line-height:1.15;letter-spacing:.01em;
  text-decoration:none;white-space:nowrap;text-transform:uppercase}
.brand .darb{color:var(--wordmark-darb);transition:color .15s}
.brand .nation{color:var(--wordmark-nation);transition:color .15s}
/* Hovering either half changes both. */
.brand:hover .darb{color:var(--wordmark-darb-hover)}
.brand:hover .nation{color:var(--wordmark-nation-hover)}
/* Two rows of links (NAV in build.py), stacked, left edges lined up. */
.nav{margin-left:auto;display:flex;flex-direction:column;gap:var(--space-3xs)}
.nav-row{display:flex;gap:var(--space-s)}
.nav a{font-family:var(--font-body);font-size:var(--text-ui);font-weight:500;color:var(--band-soft);
  text-decoration:none;letter-spacing:.01em}
.nav a:hover,.nav a[aria-current]{color:var(--band-accent)}
/* Rows split in two on phones (NAV_PHONE_SPLIT, 2026-11-06, Darby): row
   one's seven links need a 429px screen. Wider, the two spans vanish (contents) and
   it's one line. Header and footer alike, each with its own gaps. */
.nav-part{display:contents}
@media(max-width:28rem){
  .nav-row.split{flex-direction:column}
  .nav-row.split .nav-part{display:flex}
  .nav .nav-row.split{gap:var(--space-3xs)}
  .nav .nav-row.split .nav-part{gap:var(--space-xs)}
  .foot-nav .nav-row.split{gap:var(--space-2xs)}
  .foot-nav .nav-row.split .nav-part{flex-wrap:wrap;gap:var(--space-s)}
}

/* hero. .plain is the section-page variant: no rule under it and no bottom
   padding, because the flow gap below already spaces it from what follows.
   Every section page used to carry that as an inline style. */
.hero{padding-block:var(--space-3xl) var(--space-xl);
  border-bottom:1px solid var(--line);--flow-space:var(--space-s)}
.hero.plain{border-bottom:0;padding-block:var(--space-2xl) 0}
.hero h1{font-family:var(--font-title);font-weight:400;letter-spacing:-.01em;color:var(--h1);
  font-size:var(--text-hero);line-height:1.02;--flow-space:var(--space-xs)}
.hero h1 em{font-style:normal;color:var(--display-accent)}
/* :not(.kicker): this rule outranked .kicker and drew the label at 20px. */
.hero p:not(.kicker){font-size:var(--text-lead);color:var(--ink-soft);max-width:34rem}
.hero .btn-row{--flow-space:var(--space-m)}
.kicker{font-family:var(--font-body);font-size:var(--text-fine);font-weight:700;letter-spacing:.16em;
  text-transform:uppercase;color:var(--label)}
/* "All writing ->" and friends: a quiet link trailing its list. */
.more-link{font-size:var(--text-ui);--flow-space:var(--space-m)}
/* The SoundCloud iframe on /music. display:block matters: an iframe is inline
   by default, so it sits on a text baseline and carries ~9px of descender
   space under it that no margin accounts for. That was the one gap on the
   whole site the scale could not explain. */
.sc-player{display:block;border-radius:8px}

/* signup */
.signup{background:var(--signup-fill);border:1px solid var(--signup-fill);border-radius:10px;
  padding:var(--space-m);color:var(--signup-ink)}
.signup h3{font-family:var(--font-title);font-weight:400;letter-spacing:-.01em;font-size:var(--text-h2);
  margin:0 0 var(--space-3xs);line-height:1.15;color:var(--signup-head)}
.signup p{font-family:var(--font-body);font-size:var(--text-ui);color:var(--signup-ink);
  margin:0 0 var(--space-xs)}
.signup a{color:var(--signup-head)} .signup a:hover{color:var(--signup-btn-hover)}
.signup .btn{background:var(--signup-btn);border-color:var(--signup-btn);color:var(--signup-btn-ink)}
.signup .btn:hover{background:var(--signup-btn-hover);border-color:var(--signup-btn-hover);
  color:var(--signup-btn-ink)}
.signup form{display:flex;gap:var(--space-2xs);flex-wrap:wrap}
/* /subscribe puts a checklist under the form; it sat flush against it. */
.step1 .signup{display:grid;gap:var(--space-s)}
.signup input[type=email]{flex:1 1 15rem;min-width:0;font:inherit;font-family:var(--font-body);
  font-size:var(--text-ui);padding:var(--space-2xs) var(--space-xs);border:1px solid var(--line);
  border-radius:7px;background:var(--paper);color:var(--ink)}
.signup input[type=email]:focus{outline:2px solid var(--signup-btn-hover);outline-offset:-1px;
  border-color:var(--signup-btn-hover)}
.btn{font-family:var(--font-body);font-size:var(--text-ui);font-weight:650;cursor:pointer;
  padding:var(--space-2xs) var(--space-m);border:1px solid var(--accent);border-radius:7px;
  background:var(--accent);color:var(--on-accent);text-decoration:none;display:inline-block;
  line-height:1.5;transition:background .15s,color .15s,border-color .15s}
.btn:hover,.btn.ghost:hover{background:var(--hover-fill);border-color:var(--hover-fill);color:var(--hover-ink)}
.btn.ghost{background:var(--btn2-fill);border-color:var(--btn2-fill);color:var(--btn2-ink)}
/* "Rather give once? [coffee]" - one line, a real gap before the button
   (2026-10-26, Darby). At 16px the pair is 342px and a 360px phone has 312,
   so under 34rem both drop to the 15px floor and the button's side padding
   to --space-2xs: 307px. Measured in Lexend. Under 360px the words wrap
   rather than push the page sideways. */
.coffee{display:flex;flex-wrap:nowrap;align-items:center;gap:var(--space-s)}
.coffee .btn{flex:none;white-space:nowrap}
@media(max-width:34rem){.coffee,.coffee .btn{font-size:var(--text-fine)}
  .coffee{gap:var(--space-xs)}.coffee .btn{padding-inline:var(--space-2xs)}}

/* essay list */
.section-title{font-family:var(--font-body);font-size:var(--text-fine);font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;color:var(--heading);
  padding-bottom:var(--space-2xs);border-bottom:1px solid var(--line);
  --flow-space:var(--space-xl)}
.section-title+*{--flow-space:var(--space-2xs)}
/* The home page's "Start here": the one section title that is an invitation,
   not a label, so it is set as a headline with a real button under it. */
.section-title.lead{font-family:var(--font-title);font-size:var(--text-h2);font-weight:400;color:var(--h2);
  letter-spacing:-.01em;text-transform:none;line-height:1.1}
.section-title.lead+*{--flow-space:var(--space-s)}
.postlist{list-style:none;padding:0}
.postlist li{border-bottom:1px solid var(--line)}
/* weight 400: the row is one link, and "li a" links are bold - that made
   every subtitle bold and louder than its title (fixed 2026-10-22). */
.postlist a{display:block;padding-block:var(--space-m);text-decoration:none;color:inherit;font-weight:400}
/* The gap above a list is the flow gap. The first row must not add to it. */
.postlist li:first-child a{padding-block-start:0}
.postlist h3{font-family:var(--font-title);font-weight:400;letter-spacing:-.01em;font-size:var(--text-h3);
  line-height:1.25;margin:0 0 var(--space-3xs);transition:color .12s}
.postlist p{margin:0;color:var(--ink-soft);font-size:var(--text-ui);transition:color .12s}
/* Hover (2026-10-23, Darby): the title takes its row's color and thickens,
   the subtitle takes the partner color and goes to 500. Scope One has one
   weight, so the title is thickened with a hairline stroke in its own
   color - a deliberate exception to "never ask a title for bold", which
   is about the browser faking a weight. Keyboard focus gets the same. */
:is(.postlist,.rn-list) li{--row-title:var(--hue1-title);--row-sub:var(--hue1-sub)}
:is(.postlist,.rn-list) li.hue2{--row-title:var(--hue2-title);--row-sub:var(--hue2-sub)}
:is(.postlist,.rn-list) li.hue3{--row-title:var(--hue3-title);--row-sub:var(--hue3-sub)}
:is(.postlist,.rn-list) li.hue4{--row-title:var(--hue4-title);--row-sub:var(--hue4-sub)}
.postlist a:is(:hover,:focus-visible) h3{color:var(--row-title);-webkit-text-stroke:.022em currentColor}
.postlist a:is(:hover,:focus-visible) p{color:var(--row-sub);font-weight:500}
.postlist time{font-family:var(--font-body);font-size:var(--text-fine);font-weight:600;
  letter-spacing:.08em;text-transform:uppercase;color:var(--ink-faint);
  display:block;margin-bottom:var(--space-3xs)}

/* /top-10. The rank comes from CSS counters, so reordering TOP10 in build.py
   renumbers the page and nothing in the markup has to agree with itself. */
.top10-hero{width:100%;height:auto;border-radius:8px}
.ranklist{list-style:none;padding:0;counter-reset:rank}
/* The grid sits on the li, not on an anchor, so only the title is clickable.
   Exactly two grid children: the ::before counter, and one div holding the
   title and the hook. Put the h3 and the p in the grid directly and the hook
   drops onto a second row inside the number column. */
.ranklist li{border-bottom:1px solid var(--line);counter-increment:rank;
  display:grid;grid-template-columns:2.4rem minmax(0,1fr);gap:var(--space-s);
  padding-block:var(--space-m)}
.ranklist li:first-child{padding-block-start:0}
.ranklist li::before{content:counter(rank);font-family:var(--font-body);font-weight:800;
  font-size:var(--text-h3);line-height:1.15;letter-spacing:-.04em;color:var(--display-accent)}
.ranklist h3{font-family:var(--font-title);font-weight:400;letter-spacing:-.01em;font-size:var(--text-h4);
  line-height:1.25;margin:0 0 var(--space-3xs)}
.ranklist h3 a{color:var(--link);text-decoration:none}
.ranklist h3 a:hover{color:var(--link-hover);text-decoration:underline}
.ranklist p{margin:0;color:var(--ink-soft);font-size:var(--text-ui)}
@media(max-width:34rem){.ranklist li{grid-template-columns:1.9rem minmax(0,1fr);
    gap:var(--space-xs)}
  .ranklist li::before{font-size:var(--text-h4)}}

/* global essay furniture -- wording in posts/_site-copy.md */
/* .ehead is an Ask callout; the box itself comes from .callout below. */
.ehead a{color:var(--link);font-weight:700}
/* Set on the paragraphs, not the box: on .ehead it would also change the gap
   above the box, which belongs to the article. */
.ehead>*{--flow-space:var(--space-s)}
/* A divided block spends the flow gap above its rule and its own padding
   below it. Two numbers, both deliberate, neither one an accident. */
.efoot{padding-block-start:var(--space-xl);border-top:1px solid var(--line);
  --flow-space:var(--space-xl)}
.efoot>section+section{padding-block-start:var(--space-xl);
  border-top:1px solid var(--line)}
.efoot h2{font-family:var(--font-title);font-weight:400;letter-spacing:-.01em;
  font-size:var(--text-h2);line-height:1.15}
.efoot h2+*{--flow-space:var(--space-s)}
.efoot h2 a{color:var(--link);text-decoration:underline;
  text-decoration-thickness:.05em;text-underline-offset:.15em}
.efoot h2 a:hover{color:var(--link)}
.efoot p{color:var(--ink-soft);--flow-space:var(--space-s)}
.efoot img{border-radius:8px;--flow-space:var(--space-m)}
.scale-label{font-family:var(--font-body);font-size:var(--text-ui);font-weight:650;
  letter-spacing:.02em;--flow-space:var(--space-m)}
.scale-label+*{--flow-space:var(--space-2xs)}
.tiers{display:flex;flex-wrap:wrap;gap:var(--space-2xs)}
.tier{font-family:var(--font-body);font-weight:700;font-size:var(--text-ui);
  padding:var(--space-2xs) var(--space-xs);
  border:1px solid var(--line);border-radius:8px;text-decoration:none;color:var(--link);
  transition:background .15s,border-color .15s,color .15s,transform .15s,box-shadow .15s}
/* A live tier fills magenta, turns white, lifts 2px and takes a mint edge.
   Not the azure of the Buy Me a Coffee button beside it: same gesture,
   different colour, because it is a different thing.

   The edge is 1px, the border the tier already carries at rest, recoloured.
   No ring: 2px of turquoise on magenta read as heat however far the colour
   was dimmed, and the thinner line was what actually fixed it. Nothing here
   changes the box size either, so nothing shifts under the pointer. */
.tier:hover{border-color:var(--tier-edge);background:var(--tier-fill);
  color:var(--tier-ink);transform:translateY(-2px);
  box-shadow:0 5px 14px rgba(0,0,0,.2)}
.tier:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.tier:active{transform:translateY(0);box-shadow:none}
/* No payment link yet. Rendered flat so it never looks clickable -- and that
   has to include hover. .tier.off and .tier:hover score the same specificity
   (0,2,0), so .tier.off wins on source order and keeps its grey text, but
   nothing was cancelling .tier:hover's accent background. Grey on azure is
   1.06:1 in light mode and 1.06:1 in dark: the amount is invisible, on the
   exact element somebody is pointing at. A dead tier takes no hover at all. */
.tier.off{color:var(--ink-faint);cursor:default}
/* A tier with no link yet fills as well, so the gesture matches, but with the
   soft neutral instead of the brand colour and with no shadow and half the
   lift. Side by side the difference is obvious: one is saturated and floating,
   the other is flat and quiet. Text stays 8.97:1 light, 8.63:1 dark. */
.tier.off:hover{background:var(--tier-off-fill);border-color:var(--tier-off-fill);
  color:var(--tier-off-ink);transform:translateY(-1px);box-shadow:none}
/* A dead tier gets no edge and no ring. That is the tell: a live price wears a
   mint outline and floats, a price you cannot pay yet is flat and edgeless. */
@media(prefers-reduced-motion:reduce){
  .tier{transition:background .15s,border-color .15s,color .15s}
  .tier:hover,.tier.off:hover{transform:none}}

/* article */
.article{padding-block:var(--space-2xl) var(--space-s)}
.article h1{font-family:var(--font-title);font-weight:400;letter-spacing:-.01em;color:var(--h1);
  font-size:var(--text-title);line-height:1.06}
.article .sub{font-size:var(--text-lead);color:var(--ink-soft);line-height:1.45}
.meta{font-family:var(--font-body);font-size:var(--text-fine);font-weight:600;letter-spacing:.09em;
  text-transform:uppercase;color:var(--ink-faint)}
.prose h2{font-family:var(--font-title);font-weight:400;letter-spacing:-.01em;color:var(--h2);
  font-size:var(--text-h2);line-height:1.15;--flow-space:var(--space-xl)}
.prose h3{font-family:var(--font-title);font-weight:400;letter-spacing:-.01em;color:var(--h3);
  font-size:var(--text-h3);line-height:1.2;--flow-space:var(--space-l)}
.prose h4{font-family:var(--font-title);font-weight:400;letter-spacing:-.01em;font-size:var(--text-h4);
  line-height:1.3;color:var(--h4);--flow-space:var(--space-m)}
/* h5/h6 appear only in Headlines of Hope ("Animal edition", "Medical
   breakthroughs"): category labels inside a volume, so they are set as
   labels at the floor, not as a fifth heading size. */
.prose :is(h5,h6){font-family:var(--font-body);font-size:var(--text-fine);font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;line-height:1.4;color:var(--label);
  --flow-space:var(--space-l)}
/* Whatever follows a heading belongs to it, so it sits closer. */
.prose :is(h2,h3,h4)+*{--flow-space:var(--space-s)}
.prose :is(h5,h6)+*{--flow-space:var(--space-2xs)}
.prose ul,.prose ol{padding-left:var(--space-m)}
.prose li+li{margin-block-start:var(--space-2xs)}
/* Substack wraps every list item's text in a paragraph. The reset above
   flattens it; this is the gap between two of them in one item. */
.prose li>p+p{margin-block-start:var(--space-2xs)}
.prose blockquote{padding-left:var(--space-m);
  border-left:3px solid var(--rule);color:var(--ink-soft);font-style:italic;
  --flow-space:var(--space-l)}
/* Same reset, same fix: a quote with several paragraphs needs air between them. */
.prose blockquote>*+*{margin-block-start:var(--space-xs)}
.prose figure{--flow-space:var(--space-l)}
.prose figcaption{font-family:var(--font-body);font-size:var(--text-fine);color:var(--ink-faint);
  margin-top:var(--space-2xs);line-height:1.45;text-align:center}
.prose img{margin-inline:auto}
/* Emojis inside essays are Google Noto pictures (2026-10-23), sitting in the
   line like letters. Wins over the global img block rule and the flow rule
   (same specificity, later). */
.prose img.emoji{display:inline;width:auto;height:1.2em;margin:0;border-radius:0;
  vertical-align:-.2em}
/* Images side by side: a paragraph of two or more with no blank line between.
   Equal columns on a wide screen, one column on a phone. */
.prose .media-row{display:flex;gap:var(--space-m);align-items:center;
  --flow-space:var(--space-l)}
.prose .media-row>figure{flex:1 1 0;min-width:0}
.prose .media-row img,.prose .media-row video{width:100%}
@media(max-width:34rem){.prose .media-row{flex-direction:column;align-items:stretch;gap:var(--space-s)}}

/* headlines of hope */
/* .hoh-toc is a Go deeper callout (2026-10-23); its box comes from .callout. */
.hoh-toc h2{font-family:var(--font-body);font-size:var(--text-fine);font-weight:700;letter-spacing:.16em;
  text-transform:uppercase;margin:0}
.hoh-toc ul{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;
  gap:var(--space-2xs)}
.hoh-toc a{font-family:var(--font-body);font-size:var(--text-fine);font-weight:650;text-decoration:none;
  padding:var(--space-3xs) var(--space-xs);border:1px solid var(--line);border-radius:99px;
  background:var(--paper);color:var(--ink-soft)}
.hoh-toc a:hover{border-color:var(--hover-fill);background:var(--hover-fill);color:var(--hover-ink)}
.vol,.topic{scroll-margin-top:var(--space-xl)}
/* topic links: under a post's title, on /writing and on /topics */
.chips{list-style:none;padding:0;display:flex;flex-wrap:wrap;gap:var(--space-2xs)}
.chips a{font-family:var(--font-body);font-size:var(--text-fine);font-weight:650;text-decoration:none;
  padding:var(--space-3xs) var(--space-xs);border:1px solid var(--line);border-radius:99px;
  background:var(--paper);color:var(--ink-soft)}
.chips a:hover{border-color:var(--hover-fill);background:var(--hover-fill);color:var(--hover-ink)}
.article header .chips{--flow-space:var(--space-s)}
/* A mid-paragraph anchor, e.g. <span id="continue"></span>. It has no padding
   of its own, so it needs to clear the sticky masthead by itself. */
.prose span[id]{scroll-margin-top:var(--space-3xl)}
.prose h3.vol{border-top:1px solid var(--line);padding-block-start:var(--space-xl);
  --flow-space:var(--space-xl)}

/* video embeds -- see youtube_embed() in build.py */
.prose .embed{position:relative;aspect-ratio:16/9;border-radius:8px;
  overflow:hidden;background:var(--paper-2);border:1px solid var(--line);
  --flow-space:var(--space-l)}
.prose .embed.four-three{aspect-ratio:4/3}
.prose .embed iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
/* Only feed readers see this. They strip iframes, and a silent gap in the RSS
   is worse than a link. On the site the player is right there. */
.prose .embed-fallback{display:none}
/* a song (soundcloud_embed) and a video file served from this site */
.prose .embed-audio{--flow-space:var(--space-l)}
.prose video{display:block;width:100%;height:auto;border-radius:8px;
  background:var(--paper-2)}

/* cards */
.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));
  gap:var(--space-s)}
.card{border:1px solid var(--line);border-radius:10px;padding:var(--space-m);
  background:var(--paper-2);text-decoration:none;color:inherit;display:block}
.card:hover{border-color:var(--hover-border)}
.card h3{font-family:var(--font-title);font-weight:400;letter-spacing:-.01em;font-size:var(--text-h4);
  margin:0 0 var(--space-3xs);}
.card p{font-family:var(--font-body);font-size:var(--text-ui);color:var(--ink-soft);margin:0;line-height:1.5}
.card .tag{font-family:var(--font-body);font-size:var(--text-fine);font-weight:700;letter-spacing:.13em;
  text-transform:uppercase;color:var(--label);display:block;margin-bottom:var(--space-2xs)}
/* The featured card on /top-10: square animation left, words right. The image
   is square already, but object-fit keeps it square if it is ever swapped for
   something that is not. */
.card.feature{display:grid;grid-template-columns:9.5rem minmax(0,1fr);
  gap:var(--space-m);align-items:center}
.card.feature img{display:block;width:100%;aspect-ratio:1;object-fit:cover;
  border-radius:8px;background:var(--paper-2)}
.card.feature h3{font-size:var(--text-h4);line-height:1.25;margin:0 0 var(--space-3xs)}
.card.feature .more{display:inline-block;margin-top:var(--space-2xs);font-family:var(--font-body);
  font-size:var(--text-ui);font-weight:700;color:var(--link);transition:color .12s}
.card.feature:hover .more{color:var(--link-hover)}
@media(max-width:34rem){.card.feature{grid-template-columns:1fr;gap:var(--space-s)}
  .card.feature img{max-width:10rem}}

/* ---------------------------------------------------------------------------
   /subscribe -- the price page.

   The monthly/yearly switch is a checkbox and two sibling selectors. No
   JavaScript for prices: both are in the HTML and CSS shows one of them.
   A static site that needs a script to display a price is a static site with
   a way to fail, and this is the page that must never fail.

   Two steps: .step1 is the email form, .step2 (#plans) is the prices. Step 2
   shows when it is the #target, and step 1 steps aside. The only script on
   the page sets that hash after a signup; a plain link to #plans does the
   same with no script at all.
   --------------------------------------------------------------------------- */
.step1,.step2{display:flex;flex-direction:column;gap:var(--space-l)}
/* :where() on the whole selector, so this scores zero and loses to the flow
   rule. Without it, it scored (0,1,0), came later, and zeroed the gap between
   the pink headline and its paragraph on both steps (fixed 2026-10-22). */
:where(.step1,.step2) :where(p,ul){margin:0}
.step2{display:none}
.step2:target{display:flex}
.subscribe:has(.step2:target) .step1{display:none}
.step2 .done:empty{display:none}
.step2 .done{font-weight:700}
/* The perks every price shares, said once instead of five times. The free
   list under the email box wears the same checkmarks. */
/* .shared is an Ask callout (2026-10-23); its box comes from .callout. */
.shared .perks,.step1 .signup .perks{list-style:none;padding:0;
  font-family:var(--font-body);font-size:var(--text-ui);line-height:1.5;color:var(--ink-soft);
  display:grid;gap:var(--space-2xs)}
.shared .perks li,.step1 .signup .perks li{display:grid;
  grid-template-columns:1rem minmax(0,1fr);gap:var(--space-3xs)}
.shared .perks li::before,.step1 .signup .perks li::before{content:"\2713";
  color:var(--teal);font-weight:800}
/* On /subscribe the checklist sits inside the purple signup box. */
.step1 .signup .perks{color:var(--signup-ink)}
.step1 .signup .perks li::before{color:var(--signup-head)}
.pricing{--flow-space:var(--space-l)}
.billing{display:flex;justify-content:center}
.billing label{display:inline-flex;gap:var(--space-3xs);cursor:pointer;
  font-family:var(--font-body);font-size:var(--text-ui);font-weight:650;
  background:var(--paper-2);border:1px solid var(--line);border-radius:99px;
  padding:var(--space-3xs)}
.billing .seg{padding:var(--space-2xs) var(--space-m);border-radius:99px;
  color:var(--ink-soft);transition:background .15s,color .15s;white-space:nowrap}
.billing .seg small{font-size:var(--text-fine);font-weight:600;opacity:.85}
/* Monthly is the state the page loads in, so it wears the fill at rest and
   hands it over the moment the box is checked. */
.billing .seg.m{background:var(--accent);color:var(--on-accent)}
#billing-yearly:checked~.billing .seg.m{background:transparent;color:var(--ink-soft)}
#billing-yearly:checked~.billing .seg.y{background:var(--accent);color:var(--on-accent)}
#billing-yearly:focus-visible~.billing label{outline:2px solid var(--accent);
  outline-offset:2px}

.plans{display:grid;grid-template-columns:repeat(auto-fit,minmax(9rem,1fr));
  gap:var(--space-s);align-items:stretch}
.plans.ends{grid-template-columns:repeat(auto-fit,minmax(17rem,1fr))}
/* Three rungs (2026-10-22): one row of three, or one column on a phone --
   never two-and-an-orphan. */
.plans:not(.ends){grid-template-columns:repeat(3,minmax(0,1fr))}
@media(max-width:34rem){.plans:not(.ends){grid-template-columns:minmax(0,1fr)}}
.plan{display:flex;flex-direction:column;gap:var(--space-xs);
  border:1px solid var(--line);border-radius:10px;padding:var(--space-m);
  background:var(--paper-2)}
.plan :where(h3,p,ul,li){margin:0}
.plan.tight{padding:var(--space-s);align-items:stretch;text-align:center}
.plan.tight .price{font-size:var(--text-price-sm)}
.plan .name{font-family:var(--font-body);font-size:var(--text-ui);font-weight:750;
  letter-spacing:-.01em;color:var(--label)}
.plan .price{font-family:var(--font-body);font-weight:800;letter-spacing:-.04em;
  font-size:var(--text-price);line-height:1.05;color:var(--ink)}
.plan .per{font-size:var(--text-fine);font-weight:650;letter-spacing:0;color:var(--ink-faint)}
.plan .line{font-family:var(--font-body);font-size:var(--text-lead);font-weight:650;color:var(--ink)}
.plan .perks{list-style:none;padding:0;font-family:var(--font-body);font-size:var(--text-ui);
  line-height:1.5;color:var(--ink-soft);display:grid;gap:var(--space-2xs)}
.plan .perks li{display:grid;grid-template-columns:1rem minmax(0,1fr);
  gap:var(--space-3xs)}
.plan .perks li::before{content:"\2713";color:var(--teal);font-weight:800}
/* The action sits on the floor of the card, so a row of cards with different
   amounts of text still lines its buttons up. */
.plan .act{margin-block-start:auto;padding-block-start:var(--space-2xs)}
.plan .btn{display:block;width:100%;text-align:center}
/* One card forward, the way the old tier page marked a pick. Border and badge
   only -- the price is the same kind of thing as the four beside it. */
.plan.popular{border-color:var(--accent);box-shadow:0 5px 18px rgba(0,0,0,.1)}
.plan .badge{font-family:var(--font-body);font-size:var(--text-fine);font-weight:800;
  letter-spacing:.12em;text-transform:uppercase;color:var(--label)}
/* No Stripe link behind this price yet. Same rule as .tier.off: it renders
   flat, it never looks clickable, and it takes no hover. */
.plan .btn.off{background:var(--tier-off-fill);border-color:var(--tier-off-fill);
  color:var(--tier-off-ink);cursor:default;pointer-events:none}

/* Price swapping. Monthly is in the document flow, yearly is hidden, and the
   checkbox trades them. Both are real text either way, so a reader with CSS
   off sees two prices rather than none.

   The button swaps with the price, because monthly and yearly are two
   different Stripe links. Tying them to the same class is what stops a card
   ever showing a yearly price above a monthly checkout. */
.only-y{display:none}
#billing-yearly:checked~.plans .only-m,#billing-yearly:checked~.only-m{display:none}
#billing-yearly:checked~.plans .only-y,#billing-yearly:checked~.only-y{display:block}
@media(max-width:34rem){
  .billing label{width:100%}
  .billing .seg{flex:1;text-align:center;padding-inline:var(--space-2xs)}
}

.book{display:grid;grid-template-columns:minmax(0,14rem) minmax(0,1fr);
  gap:var(--space-xl);align-items:start;
  padding-block:var(--space-2xl) var(--space-s)}
.book h1{font-family:var(--font-title);font-weight:400;letter-spacing:-.01em;color:var(--h1);
  font-size:var(--text-title);line-height:1.05}
.book p{font-size:var(--text-body);color:var(--ink-soft);max-width:34rem;--flow-space:var(--space-s)}
.book img{border-radius:6px;box-shadow:0 8px 30px rgba(0,0,0,.16)}
.book .btn{margin-right:var(--space-2xs)}
/* Buy + Reviews side by side on phones too (2026-10-26, Darby). At full
   padding the pair is 358px; under 34rem the side padding drops a step, which
   makes it 306px and fits a 360px phone's 312px column. Wraps, with a gap,
   only below that. */
.book-btns{display:flex;flex-wrap:wrap;gap:var(--space-2xs)}
.book-btns .btn{margin-right:0}
@media(max-width:34rem){.book-btns .btn{padding-inline:var(--space-xs)}}
.book h2{font-family:var(--font-title);font-weight:400;letter-spacing:-.01em;color:var(--h2);
  font-size:var(--text-h2);line-height:1.08}
.book.ebook{border-top:1px solid var(--line);padding-block-start:var(--space-xl);
  --flow-space:var(--space-xl)}
/* The ebook cover's own title band: Golden Hour on Cosmic Periwinkle, 5.7:1. */
.soon{display:inline-block;font-family:var(--font-body);font-size:var(--text-fine);font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;background:var(--cosmic);
  color:var(--golden)!important;padding:var(--space-3xs) var(--space-xs);border-radius:99px}
/* Affiliate disclosure. Secondary, never faint -- the FTC wants it clear and
   conspicuous, so no opacity tricks and no shrinking this below .85rem. */
.fine{font-size:var(--text-fine);color:var(--ink-soft);max-width:30rem;--flow-space:var(--space-l)}
/* /subscribe's "Already subscribed?", "Most readers choose..." and "No thanks"
   are lines people act on, not fine print: body size (Darby, 2026-10-22). */
.subscribe .fine{font-size:var(--text-body);max-width:none}
@media(max-width:40rem){.book{grid-template-columns:1fr;gap:var(--space-m);
    padding-block-start:var(--space-xl)}
  .book>div:first-child{max-width:13rem}}
/* ---------------------------------------------------------------------------
   /book READING SAMPLE (2026-10-30, Darby). The first stories of the book,
   read on the page. Most readers arrive on a phone from an email, so the
   text is bigger than an essay's (--text-read: 18px phones, 19px desktop)
   and the line is held to about 65 characters. Titles stay Scope One at
   400 - the one-weight rule holds (Darby chose that over bold).
   Stories are separated by the site's one divider, the <hr>, with the same
   space above and below it.
   --------------------------------------------------------------------------- */
.book-page :focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:2px}
.book-page .signup :focus-visible{outline-color:var(--signup-btn-hover)}
.book-page .embed:focus-within{outline:2px solid var(--accent);outline-offset:3px}
.book .lead{font-size:var(--text-lead);color:var(--ink)}
.back-cover{max-width:28rem;margin-inline:auto}
.back-cover a{display:block}
.back-cover img{width:100%;border-radius:6px;box-shadow:0 8px 30px rgba(0,0,0,.16)}
.back-cover figcaption{font-size:var(--text-fine);color:var(--ink-faint);text-align:center;
  margin-top:var(--space-2xs)}
.sample{max-width:32em;margin-inline:auto;font-size:var(--text-read);line-height:1.6;
  --flow-space:var(--space-xl)}
.sample article{--flow-space:var(--space-m)}
.sample article>*{margin-block:0}
.sample article>*+*{margin-block-start:var(--flow-space)}
/* Same space under the divider as over it. Set as a margin, not as
   --flow-space: that would cascade into every paragraph of the story. */
.sample>hr+article{margin-block-start:var(--space-xl)}
.sample h2{font-size:var(--text-h2);line-height:1.15;--flow-space:var(--space-m)}
.sample h2+*{--flow-space:var(--space-s)}
.sample h2+.date{--flow-space:var(--space-3xs)}
.sample .date{font-size:var(--text-fine);font-weight:500;letter-spacing:.04em;
  color:var(--ink-faint)}
.sample .date+*{--flow-space:var(--space-m)}
.sample figure img{width:100%}
.sample figcaption{font-size:var(--text-fine)}
.sample .script{font-family:var(--font-mono);font-size:var(--text-ui);line-height:1.5;
  white-space:pre-wrap;overflow-wrap:anywhere;--flow-space:var(--space-2xs)}
.sample p:not(.script)+.script{--flow-space:var(--space-m)}
.sample .script+p:not(.script){--flow-space:var(--space-m)}
.sample .embed{--flow-space:var(--space-m)}
/* Signup boxes with the small cover: /book and the sample page (2026-11-05). */
.signup.with-cover{display:grid;grid-template-columns:minmax(0,1fr) 4.5rem;
  column-gap:var(--space-s);row-gap:var(--space-s);align-items:start}
/* Cover on the RIGHT (2026-11-05, Darby) so the heading, the line under it and
   the email box all share one left edge. Desktop: heading + line beside the
   cover. Phones: the line drops under the cover, full width. */
.signup.with-cover>.perk-cover{grid-column:2;grid-row:1/span 2;width:100%;border-radius:3px}
.signup.with-cover>h3{grid-column:1;grid-row:1;align-self:end;margin:0}
.signup.with-cover>.signup-under{grid-column:1;grid-row:2}
.signup.with-cover>:is(form,script){grid-column:1/-1}
.signup-under>:last-child{margin-bottom:0}
.signup .perk{font-weight:600}
/* The buy section */
.buy{--flow-space:var(--space-s);text-align:center;border-top:1px solid var(--line);
  padding-block-start:var(--space-xl)}
.buy>*{margin-block:0}
.buy>*+*{margin-block-start:var(--flow-space)}
/* Print vs. E-Book box on /book (2026-10-30, Darby): a Go deeper callout
   between the print and ebook sections, holding the sample link. */
.btn.light{background:var(--btn3-fill);border-color:var(--btn3-line);color:var(--btn3-ink)}
.btn.light:hover{background:var(--hover-fill);border-color:var(--hover-fill);color:var(--hover-ink)}
.formats{text-align:center;padding-block:var(--space-m)}
.formats h2{font-family:var(--font-title);font-weight:400;letter-spacing:-.01em;
  font-size:var(--text-h3);line-height:1.2;color:var(--co-head)}
.formats table{width:100%;max-width:30rem;margin-inline:auto;border-collapse:collapse;
  table-layout:fixed;font-size:var(--text-ui)}
.formats th{font-family:var(--font-body);font-size:var(--text-fine);font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;color:var(--co-head);
  padding:0 var(--space-2xs) var(--space-2xs)}
.formats td{padding:var(--space-2xs);border-top:1px solid var(--co-line)}
.formats th+th,.formats td+td{border-left:1px solid var(--co-line)}
.formats .price td{font-size:var(--text-lead);font-weight:700;color:var(--co-head)}
.formats .btn-row{margin-block-start:var(--space-m)}
.formats+.book.ebook{border-top:0;padding-block-start:0}
.buy-covers{display:flex;justify-content:center;gap:var(--space-m);--flow-space:var(--space-l)}
.buy-covers figure{margin:0;flex:0 1 11rem;min-width:0}
.buy-covers a{display:block;text-decoration:none}
.buy-covers img{width:100%;border-radius:6px;box-shadow:0 8px 30px rgba(0,0,0,.16)}
.buy-covers figcaption{font-family:var(--font-body);font-size:var(--text-ui);font-weight:700;
  color:var(--ink);margin-top:var(--space-2xs)}
.buy h2{font-family:var(--font-title);font-weight:400;letter-spacing:-.01em;color:var(--h2);
  font-size:var(--text-h2);line-height:1.15;--flow-space:var(--space-l)}
.buy p{max-width:34rem;margin-inline:auto}
/* Stacked at every width (Darby, 2026-10-30): the buy button on top. */
.buy .book-btns{flex-direction:column;align-items:center}
.buy .btn-row{--flow-space:var(--space-m)}
@media(max-width:34rem){
  .buy-covers{gap:var(--space-s)}
  .signup.with-cover{grid-template-columns:minmax(0,1fr) 3.5rem}
  .signup.with-cover>.perk-cover{grid-row:1}
  .signup.with-cover>h3{align-self:center}
  .signup.with-cover>.signup-under{grid-column:1/-1}
}
/* ---------------------------------------------------------------------------
   CALLOUTS (2026-10-23, Darby). One box, six jobs:
     .ask       white      support, subscribe, the book - asking for something
     .note      periwinkle editor's notes, warnings, updates, site notes
     .deeper    azure ice  series, related essays, sources, start here
     .heads-up  lilac      take a breath - a pause mid-essay (not warnings)
     .try       sage       steps a reader can do today
     .warning   yellow     warnings, content advisories - cherry-red title
   In a post: > [!ask] Title (Obsidian's callout syntax), see callouts().
   The 5px edge is the family resemblance - Darby liked it as a little 3-D
   lip. Magenta on Ask only; every other box wears its own deep shade.
   --------------------------------------------------------------------------- */
.callout{--co-bg:var(--co-ask);--co-line:var(--co-ask-line);--co-rim:var(--co-ask-edge);
  background:var(--co-bg);border:1px solid var(--co-line);
  border-left:5px solid var(--co-rim);border-radius:10px;
  padding:var(--space-s) var(--space-m);font-family:var(--font-body);
  font-size:var(--text-ui);line-height:1.6;color:var(--ink);font-style:normal}
.callout.note{--co-bg:var(--co-note);--co-line:var(--co-note-line);--co-rim:var(--co-note-edge)}
.callout.deeper{--co-bg:var(--co-deeper);--co-line:var(--co-deeper-line);--co-rim:var(--co-deeper-edge)}
.callout.heads-up{--co-bg:var(--co-heads);--co-line:var(--co-heads-line);--co-rim:var(--co-heads-edge)}
.callout.try{--co-bg:var(--co-try);--co-line:var(--co-try-line);--co-rim:var(--co-try-edge)}
.callout.warning{--co-bg:var(--co-warn);--co-line:var(--co-warn-line);--co-rim:var(--co-warn-edge);
  --co-head:var(--co-warn-head)}
/* Inside the box: paragraph to paragraph is --space-s, title to its words
   --space-xs. Set on the children, never on the box - on the box it would
   move the gap above it, which belongs to the page. */
.callout>*{margin-block:0}
.callout>*+*{margin-block-start:var(--space-s)}
.callout>.co-title+*{margin-block-start:var(--space-xs)}
.callout .co-title,.callout strong{color:var(--co-head)}
.callout .co-title{font-weight:700}
.prose .callout{--flow-space:var(--space-l)}

/* The footer is a band in the header's purple (2026-10-22, Darby). */
footer.site{background:var(--band);margin-top:var(--space-2xl);
  padding-block:var(--space-xl) var(--space-2xl);
  font-family:var(--font-body);font-size:var(--text-ui);color:var(--band-soft);
  --flow-space:var(--space-s)}
footer.site a{color:var(--band-soft);text-decoration:none}
/* Wordmark at the top of the footer, left-aligned over the links (2026-11-05,
   Darby). Same size and colors as the masthead; the purple band is what
   those colors were picked for. */
.foot-brand{display:inline-block}
footer.site a.foot-brand:hover{color:inherit}
.foot-nav{display:flex;flex-direction:column;gap:var(--space-2xs)}
.foot-nav .nav-row{flex-wrap:wrap}
footer.site a:hover{color:var(--wordmark-darb-hover)}
footer.site .fine{font-size:var(--text-fine);color:var(--band-soft);--flow-space:var(--space-s)}
footer.site .disclosure{font-size:var(--text-fine);color:var(--band-faint);--flow-space:var(--space-2xs)}
/* /subscribe lede bullets (2026-10-29, Darby): every bullet ONE line on a
   360px phone. At lead size they would wrap, so on phones they drop to
   --text-ui; SUBSCRIBE["lede_points"] says how long one may be. */
.hero .lede-points{font-family:var(--font-body);font-size:var(--text-lead);color:var(--ink-soft);
  padding-left:var(--space-m);--flow-space:var(--space-2xs)}
/* Under 360px the words wrap rather than push the page sideways, like the
   coffee line. Measured 2026-10-29: the longest bullet has 15px to spare at 360. */
@media(min-width:22.5rem){.hero .lede-points li{white-space:nowrap}}
.hero .lede-points li+li{margin-top:var(--space-3xs)}
@media(max-width:34rem){.hero .lede-points{font-size:var(--text-ui);padding-left:var(--space-s)}}
/* /contact (2026-10-29). One column of labelled fields. */
.contact-form{display:grid;gap:var(--space-s);max-width:36rem}
.contact-form label{display:grid;gap:var(--space-3xs);font-family:var(--font-body);
  font-size:var(--text-ui);font-weight:650;color:var(--ink)}
.contact-form label[hidden]{display:none}
.contact-form :is(input,select,textarea){font:inherit;font-weight:400;width:100%;min-width:0;
  padding:var(--space-2xs) var(--space-xs);border:1px solid var(--line);border-radius:7px;
  background:var(--paper);color:var(--ink)}
.contact-form textarea{resize:vertical}
.contact-form :is(input,select,textarea):focus{outline:2px solid var(--link);outline-offset:-1px;
  border-color:var(--link)}
.contact-form input[readonly]{color:var(--ink-soft);border-style:dashed}
.contact-form p{margin:0}
/* Connect on socials, under the form (2026-10-30, Darby). */
.contact-form{scroll-margin-top:var(--space-3xl)}
.connect{--flow-space:var(--space-s)}
.connect>*{margin-block:0}
.connect>*+*{margin-block-start:var(--flow-space)}
.connect h2{font-family:var(--font-title);font-weight:400;letter-spacing:-.01em;color:var(--h2);
  font-size:var(--text-h3);line-height:1.2}
.socials{list-style:none;padding:0;display:flex;flex-wrap:wrap;gap:var(--space-2xs)}
.socials a{display:grid;place-items:center;padding:var(--space-2xs);border-radius:7px;
  color:var(--link);transition:color .15s,background .15s}
.socials a:hover{color:var(--hover-ink);background:var(--hover-fill)}
.socials a:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.connect .lbl{color:var(--ink-soft)}
.connect p{font-size:var(--text-ui)}
.ct-field{display:grid;gap:var(--space-3xs)}
.ct-field>label{font-family:var(--font-body);font-size:var(--text-ui);font-weight:650;color:var(--ink)}
.ct-tools{display:flex;flex-wrap:wrap;gap:var(--space-3xs)}
.ct-tools[hidden],.ct-preview[hidden]{display:none}
.ct-tool{font-family:var(--font-body);font-size:var(--text-fine);line-height:1;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;min-width:2.5rem;
  padding:var(--space-2xs) var(--space-xs);color:var(--link);background:transparent;
  border:1px solid var(--line);border-radius:7px}
.ct-tool:hover{background:var(--hover-fill);border-color:var(--hover-fill);color:var(--hover-ink)}
.ct-tool.b{font-weight:800}.ct-tool.i{font-style:italic}
.ct-preview{font-family:var(--font-body);font-size:var(--text-ui);line-height:1.6;color:var(--ink-soft);
  white-space:pre-wrap;overflow-wrap:anywhere;border-left:3px solid var(--line);padding-left:var(--space-xs)}
.ct-list{margin:0;padding-left:var(--space-m);white-space:normal}
.ct-list li{white-space:pre-wrap}
.ct-preview::before{content:"Preview";display:block;font-size:var(--text-fine);font-weight:650;color:var(--ink-faint)}
.ct-status{font-family:var(--font-body);font-size:var(--text-ui);font-weight:700;color:var(--ink)}
.ct-status:empty{display:none}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
@media(max-width:760px){
  :root{--text-body:1rem;     /* 16px essay text on phones */
         --text-read:1.125rem}   /* 18px /book sample on phones - Darby's minimum */
  .hero{padding-block:var(--space-xl) var(--space-l)}
  .hero.plain{padding-block:var(--space-xl) 0}
  .masthead{position:static}
  /* Phone header (2026-11-08, Darby): wordmark stacked, Darb over Nation at
     the same width, links to its right in 4 / 3 / 3 rows: Top 10 · Hope ·
     Book · Blog / Music · Vids · Memes / Subscribe · About · Contact. */
  /* 16px sides here, not the page's 24: row three (Subscribe · About ·
     Contact, 16px) is the widest row, and beside the wordmark it only fits a
     360px phone with 10px between links on these sides (measured: 14px spare
     between wordmark and links at 360). */
  /* Tablets and big phones get the 390px phone's header as one block,
     centered; wider screens only add purple at the sides (2026-11-08 night,
     Darby). Under 390 it closes up until it looks like the 320 view. */
  .masthead .wrap{flex-direction:row;align-items:center;gap:var(--space-s);
    max-width:24.375rem;margin-inline:auto;
    padding-block:var(--space-2xs);padding-inline:var(--space-s)}
  .masthead .brand{display:flex;flex-direction:column;line-height:1.02;letter-spacing:0}
  .masthead .brand .darb{font-size:var(--text-mark-darb)}
  .masthead .brand .nation{font-size:var(--text-mark-nation)}
  /* Links spread across the rest of the screen, each row justified edge to
     edge (2026-11-08 night, Darby); as the screen narrows they close up. */
  .nav{flex:1;margin:0;min-width:0;gap:0}
  .masthead .nav-row.split{flex-direction:column}
  .masthead .nav-row.split .nav-part{display:flex}
  .nav .nav-row,.nav .nav-row.split .nav-part{gap:var(--nav-phone-gap);justify-content:space-between}
  .nav .nav-row.split{gap:0}
  .nav a{font-size:var(--text-nav-phone);line-height:1.4;letter-spacing:0;white-space:nowrap}
  /* Vids sits centered under Hope (2026-11-08 night, Darby), not halfway
     between Music and Memes. Row one is justified, so Hope's center is
     Top 10 + Hope/2 + a third of row one's free space; in Lexend 500 the
     words are Top 10 3.217em, Hope 2.617, Book 2.522, Blog 2.222 (10.578
     together), Music 2.806, Vids 2.133. Vids' left margin = Hope's center -
     Music - Vids/2 - the gap = 33.333% - 2.873em - gap. Memes stays right. */
  .masthead .nav-row.split .nav-part+.nav-part{justify-content:flex-start}
  .masthead .nav-row.split .nav-part+.nav-part>a:nth-child(2){
    margin-left:calc(33.333% - 2.873em - var(--nav-phone-gap))}
  .masthead .nav-row.split .nav-part+.nav-part>a:last-child{margin-left:auto}
  .nav>.nav-row:last-child a{font-size:var(--text-nav-phone-sm)}
  /* No dots between links (tried and dropped the same night - Darby: they
     cluttered it). The gap never drops under 8px, about twice a word space,
     so "Top 10" never reads as "Top" + "10 Hope". */
  .nav .nav-row{overflow-x:auto;-webkit-overflow-scrolling:touch;
    scrollbar-width:none}
  .nav .nav-row::-webkit-scrollbar{display:none}
  .vol{scroll-margin-top:var(--space-s)}
  .signup form{flex-direction:column;align-items:stretch}
  .signup input[type=email]{flex:0 0 auto;width:100%}
  .signup .btn{width:100%}
}

p,li,figcaption,blockquote,.rn-blurb{text-wrap:pretty}
h1,h2,h3,h4,h5,.sub,.rn-title,.kicker{text-wrap:balance}

.share{border-top:1px solid var(--line);padding-block-start:var(--space-m);--flow-space:var(--space-s)}
.share-h,.rn-h{font-family:var(--font-title);font-weight:400;letter-spacing:-.01em;
  font-size:var(--text-h3);line-height:1.15;color:var(--h3)}
.share-btns{display:flex;flex-wrap:wrap;gap:var(--space-2xs)}
.share-btns [hidden]{display:none}
.share-btns a,.share-btns button{font-family:var(--font-body);font-size:var(--text-fine);font-weight:650;
  text-decoration:none;cursor:pointer;line-height:1.5;display:inline-flex;align-items:center;
  justify-content:center;min-width:2.75rem;min-height:2.75rem;
  padding:var(--space-2xs) var(--space-xs);border:1px solid var(--line);border-radius:99px;
  background:var(--paper);color:var(--ink-soft)}
.share-btns a:hover,.share-btns button:hover,.share-btns :focus-visible{border-color:var(--hover-fill);
  background:var(--hover-fill);color:var(--hover-ink)}
.share-btns .share-native{border-color:var(--accent);background:var(--accent);color:var(--on-accent)}
.share-btns svg,.share-btns img{display:block}
.share-btns .done{border-color:var(--hover-fill);background:var(--hover-fill);color:var(--hover-ink)}
.read-next{--flow-space:var(--space-s)}
.rn-list{list-style:none;padding:0}
.rn-list li{border-bottom:1px solid var(--line)}
.rn-card{display:flex;align-items:flex-start;gap:var(--space-s);padding-block:var(--space-s);
  text-decoration:none;color:inherit;font-weight:400}
.rn-list li:first-child .rn-card{padding-block-start:0}
.rn-img{flex:0 0 auto;width:11rem;height:auto;border-radius:6px;background:var(--paper-2)}
.rn-text{display:flex;flex-direction:column;gap:var(--space-3xs);min-width:0}
.rn-title{font-family:var(--font-title);font-weight:400;letter-spacing:-.01em;font-size:var(--text-h4);
  line-height:1.2;color:var(--ink);transition:color .12s}
.rn-blurb{font-size:var(--text-ui);line-height:1.5;color:var(--ink-soft);transition:color .12s}
.rn-card:is(:hover,:focus-visible) .rn-title{color:var(--row-title);-webkit-text-stroke:.022em currentColor}
.rn-card:is(:hover,:focus-visible) .rn-blurb{color:var(--row-sub)}
@media(max-width:34rem){.rn-img{width:7rem}.rn-title{font-size:var(--text-lead)}
  .rn-blurb{font-size:var(--text-fine)}}

.meme-grid{list-style:none;padding:0;display:grid;gap:var(--space-s);align-items:start;
  grid-template-columns:repeat(auto-fill,minmax(min(100%,13rem),1fr))}
.meme-grid a{display:block;border-radius:8px;line-height:0}
.meme-grid img{display:block;width:100%;height:auto;border-radius:8px;border:1px solid var(--line);
  background:var(--paper-2);transition:border-color .12s}
.meme-grid a:is(:hover,:focus-visible) img{border-color:var(--hover-fill);
  box-shadow:0 0 0 2px var(--hover-fill)}
/* Phones (2026-11-03, Darby): one meme per row, full width, so every meme
   can be read without tapping into it. */
@media(max-width:34rem){.meme-grid{grid-template-columns:1fr;gap:var(--space-s)}}
/* Hover zoom (2026-11-03, Darby; MEMEVAULT's logic, MEME_ZOOM_JS): rest the
   mouse on a meme in a grid and the full picture fills the screen; move off
   the thumbnail and it goes. pointer-events:none, so a click still opens the
   meme's page. Mouse-and-hover screens only. */
@media (hover:hover) and (pointer:fine){.meme-grid img{cursor:zoom-in}}
.meme-zoom{position:fixed;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;
  background:rgb(0 0 0 / .72);pointer-events:none}
.meme-zoom[hidden]{display:none}
.meme-zoom img{max-width:94vw;max-height:94vh;width:auto;height:auto;object-fit:contain;
  border-radius:8px;box-shadow:0 12px 48px rgb(0 0 0 / .6);background:var(--paper-2)}
.memes .kicker a{color:inherit;text-decoration:none}
.memes .kicker a:hover{color:var(--link-hover)}
.meme-credit{font-size:var(--text-ui);color:var(--ink-soft)}
.memes .n{font-size:var(--text-fine);font-weight:600;color:var(--ink-faint)}
.chips a:hover .n{color:inherit}
/* Topic tiles (2026-11-02, Darby: Option A). Tiles and their hidden panels
   are siblings in one grid; a panel spans the row, and dense packing lets the
   tiles after it fill the tapped tile's row first - so an open panel lands
   right under that row at any width (4 across on a laptop, 2 on a phone). */
.mt{display:flex;flex-direction:column;gap:var(--space-s)}
.mt-top{display:flex;align-items:baseline;justify-content:space-between;gap:var(--space-xs) var(--space-s);
  flex-wrap:wrap}
.mt-top h2{margin:0}
.mt-top p{margin:0;font-size:var(--text-fine);color:var(--ink-faint)}
.mt-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(13.5rem,1fr));
  grid-auto-flow:row dense;gap:var(--space-s)}
.mt-tile{position:relative;overflow:hidden;isolation:isolate;min-height:9.5rem;border-radius:16px;
  padding:var(--space-s);display:flex;flex-direction:column;justify-content:space-between;
  gap:var(--space-m);text-decoration:none;font-weight:400;background:var(--tile-fill);
  color:var(--tile-ink);border:1px solid var(--tile-edge);
  transition:transform .18s ease,box-shadow .18s ease}
.mt-tile.tone1{--tile-fill:var(--tile1)}.mt-tile.tone2{--tile-fill:var(--tile2)}
.mt-tile.tone3{--tile-fill:var(--tile3)}.mt-tile.tone4{--tile-fill:var(--tile4)}
.mt-tile.tone5{--tile-fill:var(--tile5);--tile-ink:var(--tile-ink-dark);--tile-halo:var(--tile-halo-light)}
.mt-tile.tone6{--tile-fill:var(--tile6);--tile-ink:var(--tile-ink-dark);--tile-halo:var(--tile-halo-light)}
.mt-tile:hover{color:var(--tile-ink);transform:translateY(-3px);box-shadow:0 12px 26px rgb(58 47 94 / .25)}
.mt-tile:focus-visible{outline:3px solid var(--azure-light);outline-offset:3px}
.mt-tile[aria-expanded=true]{box-shadow:0 0 0 3px var(--paper),0 0 0 6px var(--link)}
.mt-name{position:relative;z-index:1;font-family:var(--font-title);font-weight:400;
  font-size:var(--text-h4);line-height:1.1;letter-spacing:-.01em}
.mt-count{position:relative;z-index:1;font-size:var(--text-fine);font-weight:600}
/* The picture is laid out at its HOVER size and shrunk at rest (2026-11-03,
   Darby: words looked pixelated). Browsers paint an image at its layout
   size and then stretch that bitmap for a transform, so growing a 108px
   picture 1.45x blurred it; shrinking a 157px one stays sharp. Same motion
   as before: 9.8rem x .69 = the old 6.75rem at rest, 1x on hover = the old
   1.45x. Radius and shadow are set at hover size for the same reason. */
.mt-tile img{position:absolute;z-index:0;right:-1rem;bottom:-1.375rem;width:auto;height:auto;
  transform-origin:100% 100%;
  max-width:9.8rem;max-height:10.15rem;border-radius:12px;transform:rotate(18deg) scale(.69);
  box-shadow:0 9px 26px rgb(0 0 0 / .35);transition:transform .25s ease}
/* Hover (2026-11-03, Darby): the reader has read the name by now, so the
   meme straightens, grows and slides its hidden corner into view - over the
   words if it has to - so the joke can land. An open tile keeps it there. */
.mt-tile:is(:hover,:focus-visible,[aria-expanded=true]) img{z-index:2;
  transform:translate(-1rem,-1.375rem) rotate(3deg);box-shadow:0 14px 38px rgb(0 0 0 / .45)}
/* ...and the words float on top of it (2026-11-03, Darby: "make the name
   hover over the meme so you can still see what it says"). A halo in the
   opposite shade keeps them readable on any picture: dark behind the white
   words, light behind the Cosmic Deep words on Golden Hour and Mint. Only
   while the meme is up - at rest the words sit on the plain fill. */
.mt-tile{--tile-halo:var(--tile-halo-dark);
  --tile-halo-dark:0 1px 2px rgb(0 0 0 / .95),0 0 5px rgb(0 0 0 / .85),0 0 12px rgb(0 0 0 / .6);
  --tile-halo-light:0 1px 2px rgb(255 255 255 / .95),0 0 5px rgb(255 255 255 / .9),0 0 12px rgb(255 255 255 / .7)}
.mt-name,.mt-count{transition:text-shadow .25s ease}
.mt-tile:is(:hover,:focus-visible,[aria-expanded=true]) :is(.mt-name,.mt-count){z-index:3;
  text-shadow:var(--tile-halo)}
/* While the meme is up the count drops the word "memes" (2026-11-03, Darby:
   it covered the joke) - "378" stays, the word comes back at rest. The
   tile's aria-label keeps the full "Politics, 378 memes" for screen readers. */
.mt-tile:is(:hover,:focus-visible,[aria-expanded=true]) .mt-w{display:none}
/* A name long enough to take two lines ("Declaration of Independence")
   gets a shorter meme, so the picture never sits on the words. */
.mt-tile.two img{max-height:8rem}
.mt-panel{grid-column:1/-1;display:flex;flex-direction:column;gap:var(--space-s);
  padding:var(--space-m);border:1px solid var(--line);border-radius:18px;background:var(--paper-2);
  box-shadow:0 10px 30px rgb(58 47 94 / .08)}
.mt-panel[hidden],.mt-branch[hidden]{display:none}
.mt-head{display:flex;align-items:center;justify-content:space-between;gap:var(--space-xs) var(--space-s);flex-wrap:wrap}
.mt-head>div{display:flex;flex-direction:column;gap:var(--space-3xs)}
.mt-head p,.mt-head h3{margin:0}
.mt-head h3{font-family:var(--font-title);font-weight:400;letter-spacing:-.01em;
  font-size:var(--text-h4);line-height:1.2;color:var(--h3)}
.mt-head .btn{white-space:nowrap}
.mt-head>.mt-acts{flex-direction:row;align-items:center;gap:var(--space-2xs);flex-wrap:wrap}
.mt-hbtn{font-family:var(--font-body);font-size:var(--text-fine);font-weight:600;line-height:1.35;
  cursor:pointer;padding:var(--space-2xs) var(--space-xs);border:1px solid var(--line);
  border-radius:10px;background:var(--paper-2);color:var(--link);
  transition:background .15s,color .15s,border-color .15s}
.mt-hbtn:hover{background:var(--hover-fill);border-color:var(--hover-fill);color:var(--hover-ink)}
/* The topic tree (2026-11-03, Darby: "Darby's mix" on the "Meme Topic Tree
   Options" canvas). An outline, A-Z, in three columns (one under 52rem).
   Every row is the topic's own link plus "N memes"; a topic with topics
   under it sits in a light box with a pink "N topics" toggle, and its
   topics hang off it on periwinkle limbs. Hovering a row turns the name
   Magenta Deep - not while the mouse is on the toggle, which goes dark
   blue instead. Branches are in the HTML from the start, hidden;
   MEME_TILES_JS only opens and closes them. --ind is one level's indent;
   the limb runs 18px in from the parent row's left edge. */
.mt-cols{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-3xs) var(--space-l);
  align-items:start}
.mt-tree,.mt-branch{--ind:1.875rem;list-style:none;margin:0;padding:0;display:flex;
  flex-direction:column;gap:var(--space-3xs)}
.mt-tree li{position:relative;display:flex;flex-direction:column;gap:var(--space-3xs)}
.mt-branch{margin-left:var(--ind)}
.mt-branch>li::before,.mt-branch>li:not(:last-child)::after{content:"";position:absolute;
  pointer-events:none;left:calc(18px - var(--ind));top:calc(-1 * var(--space-3xs));
  border:0 solid var(--tree-limb)}
.mt-branch>li::before{height:calc(20px + var(--space-3xs));width:calc(var(--ind) - 12px);
  border-left-width:2px;border-bottom-width:2px;z-index:1}
.mt-branch>li:last-child::before{border-bottom-left-radius:10px}
.mt-branch>li:not(:last-child)::after{bottom:0;border-left-width:2px}
/* The whole row is the topic's link (2026-11-03, Darby): the name's link
   stretches over the row box with ::after; the "N topics" toggle sits
   above it (z-index) and keeps its own click. One real <a> per topic, so
   nothing changes for Google or screen readers. */
.mt-row{position:relative;display:flex;align-items:center;justify-content:space-between;gap:var(--space-2xs);
  padding:var(--space-2xs) var(--space-2xs) var(--space-2xs) var(--space-xs);border-radius:10px;
  transition:background .15s,box-shadow .15s}
.mt-row:hover{background:var(--tree-hover)}
.mt-row.par{background:var(--tree-par);box-shadow:inset 0 0 0 1px var(--tree-par-line)}
.mt-row.par:hover,.mt-row:has(>.mt-tg[aria-expanded=true]){background:var(--tree-hover);
  box-shadow:inset 0 0 0 1px var(--tree-on-line)}
.mt-txt{display:block;min-width:0;font-size:var(--text-ui);line-height:1.5}
.mt-txt a{font-size:var(--text-ui);line-height:1.5;font-weight:600;text-decoration:none;
  color:var(--link);overflow-wrap:break-word}
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}
.mt-txt a::after{content:"";position:absolute;inset:0;border-radius:inherit}
.mt-row:hover:not(:has(.mt-tg:hover)) .mt-txt a,.mt-txt a:hover{color:var(--tree-hot)}
.mt-txt span{font-size:var(--text-fine);line-height:1.35;color:var(--tree-count);white-space:nowrap}
.mt-txt .mt-n{padding-inline-start:var(--space-2xs)}
.mt-tg{display:inline-flex;align-items:center;gap:var(--space-3xs);flex-shrink:0;
  padding:var(--space-3xs) var(--space-2xs);border:0;border-radius:8px;background:transparent;
  font-family:var(--font-body);font-size:var(--text-fine);font-weight:600;line-height:1.35;
  color:var(--tree-hot);cursor:pointer;white-space:nowrap;transition:background .15s,color .15s;
  position:relative;z-index:1}
.mt-tg:hover{background:var(--hover-fill);color:var(--hover-ink)}
.mt-tg svg{display:block;transition:transform .15s}
.mt-tg[aria-expanded=true] svg{transform:rotate(180deg)}
.mt-tg:focus-visible,.mt-hbtn:focus-visible,.mt-row:has(.mt-txt a:focus-visible){outline:3px solid var(--azure-light);
  outline-offset:2px}
.mt-txt a:focus-visible{outline:none}
@media(max-width:52rem){.mt-cols{grid-template-columns:minmax(0,40rem)}}
@media(max-width:34rem){
  .mt-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-xs)}
  /* Phones: name and count sit together at the top so the meme in the
     corner never covers the count; names drop to --text-read (18px here)
     so "Entertainment" fits a 360px phone's tile on one line. */
  .mt-tile{min-height:8.5rem;padding:var(--space-xs);border-radius:14px;justify-content:flex-start;
    gap:var(--space-3xs)}
  .mt-name{font-size:var(--text-read)}
  .mt-tile img{max-width:7rem;max-height:7rem;right:-.75rem;bottom:-1rem;transform:rotate(18deg) scale(.714)}
  .mt-tile.two img{max-height:7.7rem}
  .mt-tile:is(:hover,:focus-visible,[aria-expanded=true]) img{transform:translate(-.75rem,-1rem) rotate(3deg)}
  .mt-panel{padding:var(--space-s)}
  .mt-tree,.mt-branch{--ind:1.5rem}
  .mt-head .btn{width:100%;text-align:center;white-space:normal}}
/* Under a 360px phone (Darby's target) a long name may hyphenate rather
   than spill out of its tile. */
@media(max-width:22.4rem){.mt-name{hyphens:auto;overflow-wrap:break-word}}
@media (prefers-reduced-motion:reduce){.mt-tile,.mt-tile img,.mt-tg svg,.mt-row{transition:none}
  .mt-tile:hover{transform:none}}
.meme-page{padding-block-start:var(--space-xl)}
.meme-page .meme{--flow-space:var(--space-m)}
.meme-page .meme header{--flow-space:var(--space-2xs)}
.meme-page h1{font-family:var(--font-title);font-weight:400;letter-spacing:-.01em;
  font-size:var(--text-h2);line-height:1.15;color:var(--h1)}
.meme-fig{margin-inline:0;display:flex;flex-direction:column;gap:var(--space-xs)}
.meme-fig img{display:block;width:auto;max-width:100%;height:auto;max-height:85vh;
  margin-inline:auto;border-radius:8px;border:1px solid var(--line)}
.meme-fig figcaption{font-size:var(--text-ui);color:var(--ink-soft);line-height:1.6}
.meme-via{font-size:var(--text-ui);color:var(--ink-soft)}
.meme-more{--flow-space:var(--space-s)}
.signup-done{font-weight:600;color:var(--signup-head)}
.signup-done a{color:var(--signup-head)}
/* Topic search (2026-11-02): the box, its list of matches, "no match" line.
   Matches use the site's purple hover; typed letters are underlined. */
.meme-search{position:relative;max-width:34rem}
.meme-search input{width:100%;min-width:0;font:inherit;font-family:var(--font-body);
  font-size:var(--text-ui);padding:var(--space-xs) var(--space-s);border:1px solid var(--line);
  border-radius:7px;background:var(--paper-2);color:var(--ink);color-scheme:light dark}
.meme-search input::placeholder{color:var(--ink-faint);opacity:1}
.meme-search input:focus{outline:2px solid var(--link);outline-offset:-1px;border-color:var(--link)}
.ms-list{list-style:none;margin:var(--space-3xs) 0 0;padding:var(--space-3xs);position:absolute;
  left:0;right:0;top:100%;z-index:20;background:var(--paper-2);border:1px solid var(--line);
  border-radius:8px;box-shadow:0 8px 24px rgb(0 0 0 / .14);max-height:min(60vh,26rem);overflow:auto}
.ms-list a{display:block;padding:var(--space-2xs) var(--space-xs);border-radius:6px;
  text-decoration:none;color:var(--ink);font-family:var(--font-body);font-size:var(--text-ui);
  line-height:1.35}
.ms-name{font-weight:650}
.ms-list mark{background:none;color:inherit;text-decoration:underline;
  text-decoration-thickness:2px;text-underline-offset:3px}
.ms-sub{display:block;font-size:var(--text-fine);color:var(--ink-faint)}
.ms-list [aria-selected=true] a{background:var(--hover-fill);color:var(--hover-ink)}
.ms-list [aria-selected=true] :is(.n,.ms-sub){color:var(--band-faint)}
.ms-none{font-family:var(--font-body);font-size:var(--text-ui);color:var(--ink-soft);
  margin-block-start:var(--space-2xs)}
.ms-none a{color:var(--link)}
.prose .media-row>figure.ar20{flex-grow:0.2}.prose .media-row>figure.ar22{flex-grow:0.22}.prose .media-row>figure.ar24{flex-grow:0.24}.prose .media-row>figure.ar26{flex-grow:0.26}.prose .media-row>figure.ar28{flex-grow:0.28}.prose .media-row>figure.ar30{flex-grow:0.3}.prose .media-row>figure.ar32{flex-grow:0.32}.prose .media-row>figure.ar34{flex-grow:0.34}.prose .media-row>figure.ar36{flex-grow:0.36}.prose .media-row>figure.ar38{flex-grow:0.38}.prose .media-row>figure.ar40{flex-grow:0.4}.prose .media-row>figure.ar42{flex-grow:0.42}.prose .media-row>figure.ar44{flex-grow:0.44}.prose .media-row>figure.ar46{flex-grow:0.46}.prose .media-row>figure.ar48{flex-grow:0.48}.prose .media-row>figure.ar50{flex-grow:0.5}.prose .media-row>figure.ar52{flex-grow:0.52}.prose .media-row>figure.ar54{flex-grow:0.54}.prose .media-row>figure.ar56{flex-grow:0.56}.prose .media-row>figure.ar58{flex-grow:0.58}.prose .media-row>figure.ar60{flex-grow:0.6}.prose .media-row>figure.ar62{flex-grow:0.62}.prose .media-row>figure.ar64{flex-grow:0.64}.prose .media-row>figure.ar66{flex-grow:0.66}.prose .media-row>figure.ar68{flex-grow:0.68}.prose .media-row>figure.ar70{flex-grow:0.7}.prose .media-row>figure.ar72{flex-grow:0.72}.prose .media-row>figure.ar74{flex-grow:0.74}.prose .media-row>figure.ar76{flex-grow:0.76}.prose .media-row>figure.ar78{flex-grow:0.78}.prose .media-row>figure.ar80{flex-grow:0.8}.prose .media-row>figure.ar82{flex-grow:0.82}.prose .media-row>figure.ar84{flex-grow:0.84}.prose .media-row>figure.ar86{flex-grow:0.86}.prose .media-row>figure.ar88{flex-grow:0.88}.prose .media-row>figure.ar90{flex-grow:0.9}.prose .media-row>figure.ar92{flex-grow:0.92}.prose .media-row>figure.ar94{flex-grow:0.94}.prose .media-row>figure.ar96{flex-grow:0.96}.prose .media-row>figure.ar98{flex-grow:0.98}.prose .media-row>figure.ar100{flex-grow:1}.prose .media-row>figure.ar102{flex-grow:1.02}.prose .media-row>figure.ar104{flex-grow:1.04}.prose .media-row>figure.ar106{flex-grow:1.06}.prose .media-row>figure.ar108{flex-grow:1.08}.prose .media-row>figure.ar110{flex-grow:1.1}.prose .media-row>figure.ar112{flex-grow:1.12}.prose .media-row>figure.ar114{flex-grow:1.14}.prose .media-row>figure.ar116{flex-grow:1.16}.prose .media-row>figure.ar118{flex-grow:1.18}.prose .media-row>figure.ar120{flex-grow:1.2}.prose .media-row>figure.ar122{flex-grow:1.22}.prose .media-row>figure.ar124{flex-grow:1.24}.prose .media-row>figure.ar126{flex-grow:1.26}.prose .media-row>figure.ar128{flex-grow:1.28}.prose .media-row>figure.ar130{flex-grow:1.3}.prose .media-row>figure.ar132{flex-grow:1.32}.prose .media-row>figure.ar134{flex-grow:1.34}.prose .media-row>figure.ar136{flex-grow:1.36}.prose .media-row>figure.ar138{flex-grow:1.38}.prose .media-row>figure.ar140{flex-grow:1.4}.prose .media-row>figure.ar142{flex-grow:1.42}.prose .media-row>figure.ar144{flex-grow:1.44}.prose .media-row>figure.ar146{flex-grow:1.46}.prose .media-row>figure.ar148{flex-grow:1.48}.prose .media-row>figure.ar150{flex-grow:1.5}.prose .media-row>figure.ar152{flex-grow:1.52}.prose .media-row>figure.ar154{flex-grow:1.54}.prose .media-row>figure.ar156{flex-grow:1.56}.prose .media-row>figure.ar158{flex-grow:1.58}.prose .media-row>figure.ar160{flex-grow:1.6}.prose .media-row>figure.ar162{flex-grow:1.62}.prose .media-row>figure.ar164{flex-grow:1.64}.prose .media-row>figure.ar166{flex-grow:1.66}.prose .media-row>figure.ar168{flex-grow:1.68}.prose .media-row>figure.ar170{flex-grow:1.7}.prose .media-row>figure.ar172{flex-grow:1.72}.prose .media-row>figure.ar174{flex-grow:1.74}.prose .media-row>figure.ar176{flex-grow:1.76}.prose .media-row>figure.ar178{flex-grow:1.78}.prose .media-row>figure.ar180{flex-grow:1.8}.prose .media-row>figure.ar182{flex-grow:1.82}.prose .media-row>figure.ar184{flex-grow:1.84}.prose .media-row>figure.ar186{flex-grow:1.86}.prose .media-row>figure.ar188{flex-grow:1.88}.prose .media-row>figure.ar190{flex-grow:1.9}.prose .media-row>figure.ar192{flex-grow:1.92}.prose .media-row>figure.ar194{flex-grow:1.94}.prose .media-row>figure.ar196{flex-grow:1.96}.prose .media-row>figure.ar198{flex-grow:1.98}.prose .media-row>figure.ar200{flex-grow:2}.prose .media-row>figure.ar202{flex-grow:2.02}.prose .media-row>figure.ar204{flex-grow:2.04}.prose .media-row>figure.ar206{flex-grow:2.06}.prose .media-row>figure.ar208{flex-grow:2.08}.prose .media-row>figure.ar210{flex-grow:2.1}.prose .media-row>figure.ar212{flex-grow:2.12}.prose .media-row>figure.ar214{flex-grow:2.14}.prose .media-row>figure.ar216{flex-grow:2.16}.prose .media-row>figure.ar218{flex-grow:2.18}.prose .media-row>figure.ar220{flex-grow:2.2}.prose .media-row>figure.ar222{flex-grow:2.22}.prose .media-row>figure.ar224{flex-grow:2.24}.prose .media-row>figure.ar226{flex-grow:2.26}.prose .media-row>figure.ar228{flex-grow:2.28}.prose .media-row>figure.ar230{flex-grow:2.3}.prose .media-row>figure.ar232{flex-grow:2.32}.prose .media-row>figure.ar234{flex-grow:2.34}.prose .media-row>figure.ar236{flex-grow:2.36}.prose .media-row>figure.ar238{flex-grow:2.38}.prose .media-row>figure.ar240{flex-grow:2.4}.prose .media-row>figure.ar242{flex-grow:2.42}.prose .media-row>figure.ar244{flex-grow:2.44}.prose .media-row>figure.ar246{flex-grow:2.46}.prose .media-row>figure.ar248{flex-grow:2.48}.prose .media-row>figure.ar250{flex-grow:2.5}.prose .media-row>figure.ar252{flex-grow:2.52}.prose .media-row>figure.ar254{flex-grow:2.54}.prose .media-row>figure.ar256{flex-grow:2.56}.prose .media-row>figure.ar258{flex-grow:2.58}.prose .media-row>figure.ar260{flex-grow:2.6}.prose .media-row>figure.ar262{flex-grow:2.62}.prose .media-row>figure.ar264{flex-grow:2.64}.prose .media-row>figure.ar266{flex-grow:2.66}.prose .media-row>figure.ar268{flex-grow:2.68}.prose .media-row>figure.ar270{flex-grow:2.7}.prose .media-row>figure.ar272{flex-grow:2.72}.prose .media-row>figure.ar274{flex-grow:2.74}.prose .media-row>figure.ar276{flex-grow:2.76}.prose .media-row>figure.ar278{flex-grow:2.78}.prose .media-row>figure.ar280{flex-grow:2.8}.prose .media-row>figure.ar282{flex-grow:2.82}.prose .media-row>figure.ar284{flex-grow:2.84}.prose .media-row>figure.ar286{flex-grow:2.86}.prose .media-row>figure.ar288{flex-grow:2.88}.prose .media-row>figure.ar290{flex-grow:2.9}.prose .media-row>figure.ar292{flex-grow:2.92}.prose .media-row>figure.ar294{flex-grow:2.94}.prose .media-row>figure.ar296{flex-grow:2.96}.prose .media-row>figure.ar298{flex-grow:2.98}.prose .media-row>figure.ar300{flex-grow:3}.prose .media-row>figure.ar302{flex-grow:3.02}.prose .media-row>figure.ar304{flex-grow:3.04}.prose .media-row>figure.ar306{flex-grow:3.06}.prose .media-row>figure.ar308{flex-grow:3.08}.prose .media-row>figure.ar310{flex-grow:3.1}.prose .media-row>figure.ar312{flex-grow:3.12}.prose .media-row>figure.ar314{flex-grow:3.14}.prose .media-row>figure.ar316{flex-grow:3.16}.prose .media-row>figure.ar318{flex-grow:3.18}.prose .media-row>figure.ar320{flex-grow:3.2}.prose .media-row>figure.ar322{flex-grow:3.22}.prose .media-row>figure.ar324{flex-grow:3.24}.prose .media-row>figure.ar326{flex-grow:3.26}.prose .media-row>figure.ar328{flex-grow:3.28}.prose .media-row>figure.ar330{flex-grow:3.3}.prose .media-row>figure.ar332{flex-grow:3.32}.prose .media-row>figure.ar334{flex-grow:3.34}.prose .media-row>figure.ar336{flex-grow:3.36}.prose .media-row>figure.ar338{flex-grow:3.38}.prose .media-row>figure.ar340{flex-grow:3.4}.prose .media-row>figure.ar342{flex-grow:3.42}.prose .media-row>figure.ar344{flex-grow:3.44}.prose .media-row>figure.ar346{flex-grow:3.46}.prose .media-row>figure.ar348{flex-grow:3.48}.prose .media-row>figure.ar350{flex-grow:3.5}.prose .media-row>figure.ar352{flex-grow:3.52}.prose .media-row>figure.ar354{flex-grow:3.54}.prose .media-row>figure.ar356{flex-grow:3.56}.prose .media-row>figure.ar358{flex-grow:3.58}.prose .media-row>figure.ar360{flex-grow:3.6}.prose .media-row>figure.ar362{flex-grow:3.62}.prose .media-row>figure.ar364{flex-grow:3.64}.prose .media-row>figure.ar366{flex-grow:3.66}.prose .media-row>figure.ar368{flex-grow:3.68}.prose .media-row>figure.ar370{flex-grow:3.7}.prose .media-row>figure.ar372{flex-grow:3.72}.prose .media-row>figure.ar374{flex-grow:3.74}.prose .media-row>figure.ar376{flex-grow:3.76}.prose .media-row>figure.ar378{flex-grow:3.78}.prose .media-row>figure.ar380{flex-grow:3.8}.prose .media-row>figure.ar382{flex-grow:3.82}.prose .media-row>figure.ar384{flex-grow:3.84}.prose .media-row>figure.ar386{flex-grow:3.86}.prose .media-row>figure.ar388{flex-grow:3.88}.prose .media-row>figure.ar390{flex-grow:3.9}.prose .media-row>figure.ar392{flex-grow:3.92}.prose .media-row>figure.ar394{flex-grow:3.94}.prose .media-row>figure.ar396{flex-grow:3.96}.prose .media-row>figure.ar398{flex-grow:3.98}.prose .media-row>figure.ar400{flex-grow:4}.prose .media-row>figure.ar402{flex-grow:4.02}.prose .media-row>figure.ar404{flex-grow:4.04}.prose .media-row>figure.ar406{flex-grow:4.06}.prose .media-row>figure.ar408{flex-grow:4.08}.prose .media-row>figure.ar410{flex-grow:4.1}.prose .media-row>figure.ar412{flex-grow:4.12}.prose .media-row>figure.ar414{flex-grow:4.14}.prose .media-row>figure.ar416{flex-grow:4.16}.prose .media-row>figure.ar418{flex-grow:4.18}.prose .media-row>figure.ar420{flex-grow:4.2}.prose .media-row>figure.ar422{flex-grow:4.22}.prose .media-row>figure.ar424{flex-grow:4.24}.prose .media-row>figure.ar426{flex-grow:4.26}.prose .media-row>figure.ar428{flex-grow:4.28}.prose .media-row>figure.ar430{flex-grow:4.3}.prose .media-row>figure.ar432{flex-grow:4.32}.prose .media-row>figure.ar434{flex-grow:4.34}.prose .media-row>figure.ar436{flex-grow:4.36}.prose .media-row>figure.ar438{flex-grow:4.38}.prose .media-row>figure.ar440{flex-grow:4.4}.prose .media-row>figure.ar442{flex-grow:4.42}.prose .media-row>figure.ar444{flex-grow:4.44}.prose .media-row>figure.ar446{flex-grow:4.46}.prose .media-row>figure.ar448{flex-grow:4.48}.prose .media-row>figure.ar450{flex-grow:4.5}.prose .media-row>figure.ar452{flex-grow:4.52}.prose .media-row>figure.ar454{flex-grow:4.54}.prose .media-row>figure.ar456{flex-grow:4.56}.prose .media-row>figure.ar458{flex-grow:4.58}.prose .media-row>figure.ar460{flex-grow:4.6}.prose .media-row>figure.ar462{flex-grow:4.62}.prose .media-row>figure.ar464{flex-grow:4.64}.prose .media-row>figure.ar466{flex-grow:4.66}.prose .media-row>figure.ar468{flex-grow:4.68}.prose .media-row>figure.ar470{flex-grow:4.7}.prose .media-row>figure.ar472{flex-grow:4.72}.prose .media-row>figure.ar474{flex-grow:4.74}.prose .media-row>figure.ar476{flex-grow:4.76}.prose .media-row>figure.ar478{flex-grow:4.78}.prose .media-row>figure.ar480{flex-grow:4.8}.prose .media-row>figure.ar482{flex-grow:4.82}.prose .media-row>figure.ar484{flex-grow:4.84}.prose .media-row>figure.ar486{flex-grow:4.86}.prose .media-row>figure.ar488{flex-grow:4.88}.prose .media-row>figure.ar490{flex-grow:4.9}.prose .media-row>figure.ar492{flex-grow:4.92}.prose .media-row>figure.ar494{flex-grow:4.94}.prose .media-row>figure.ar496{flex-grow:4.96}.prose .media-row>figure.ar498{flex-grow:4.98}.prose .media-row>figure.ar500{flex-grow:5}

/* Back to top + slim nav (2026-11-05, Darby; TOTOP_JS). Nothing shows while
   reading or scrolling down. Scroll UP on purpose (60px+) and, 3+ screens
   deep, a small "Top" pill shows bottom-right; on phones a one-line nav
   also slides down from the top (the real masthead isn't sticky there).
   Scrolling down hides both. Fat-finger guards: a tap in the first 350 ms
   after either shows up does nothing (it's usually a thumb stopping a
   fling), and after the jump "Back to where you were" sits in the same
   spot for 5 s. Buttons, not #top links, so the browser's Back still works. */
.totop-box{position:fixed;right:var(--space-s);bottom:var(--space-s);z-index:30;
  display:grid;justify-items:end;align-items:end;pointer-events:none}
.totop{grid-area:1/1;display:inline-flex;align-items:center;gap:var(--space-2xs);min-height:44px;
  padding:var(--space-2xs) var(--space-s);border:1px solid var(--band-faint);border-radius:99px;
  background:var(--band);color:var(--band-ink);font-family:var(--font-body);font-size:var(--text-ui);
  font-weight:600;line-height:1;white-space:nowrap;cursor:pointer;
  box-shadow:0 4px 16px rgb(0 0 0 / .28);touch-action:manipulation;-webkit-tap-highlight-color:transparent;
  opacity:0;transform:translateY(var(--space-s));visibility:hidden;pointer-events:none;
  transition:opacity .18s,transform .18s,visibility 0s .18s}
.totop.on{opacity:1;transform:none;visibility:visible;pointer-events:auto;
  transition:opacity .18s,transform .18s}
/* "Top" is twice the size (2026-11-05, Darby: more noticeable on the way
   up). "Back to where you were" stays small so it fits a 360px phone. */
.totop:not(.back){min-height:88px;gap:var(--space-s);padding:var(--space-s) var(--space-l);
  font-size:var(--text-price);border-width:2px;box-shadow:0 6px 24px rgb(0 0 0 / .32)}
/* A quarter smaller on phones (2026-11-07, Darby: "a little too big now").
   66px tall, 24px words, all on the spacing scale. Desktop keeps 88/32. */
@media(max-width:760px){
  .totop:not(.back){min-height:66px;gap:var(--space-xs);padding:var(--space-xs) var(--space-m);
    font-size:calc(var(--text-price) * .75)}
}
.totop .ar{color:var(--wordmark-nation);font-weight:700}
.totop:hover{color:var(--hover-ink)}
.totop:focus-visible{outline:2px solid var(--wordmark-nation);outline-offset:2px}
.peek{display:none}
@media(max-width:760px){
  .peek{display:flex;align-items:center;position:fixed;top:0;left:0;right:0;z-index:25;
    min-height:calc(var(--text-ghost) * .9);overflow:hidden;
    padding:var(--space-2xs) var(--space-xs);background:var(--band);
    box-shadow:0 2px 12px rgb(0 0 0 / .25);
    transform:translateY(-110%);visibility:hidden;transition:transform .2s,visibility 0s .2s}
  .peek.on{transform:none;visibility:visible;transition:transform .2s}
  /* Ghost wordmark (2026-11-05, Darby): DarbNation behind the links, D's ink
     flush with the left edge and n's with the right at any phone width (the
     -.04em cancels Caprasimo's left side bearing). Faded so the links lead. */
  .peek-ghost{position:absolute;left:0;top:50%;transform:translate(-.04em,-50%);
    font-family:var(--font-wordmark);font-weight:400;font-size:var(--text-ghost);line-height:1;
    white-space:nowrap;opacity:.11;pointer-events:none;user-select:none;text-transform:uppercase}  /* 11%: Darby's pick of 15/11/7, 2026-11-05 */
  .peek-ghost .darb{color:var(--wordmark-darb)}
  .peek-ghost .nation{color:var(--wordmark-nation)}
  /* Links sit 6px low (2026-11-05, Darby): 4px centers their lowercase letters
     on the ghost's (measured 3.4-4.5px at 320-430), then Darby asked 2px more. */
  .peek-links{position:relative;flex:1;min-width:0;display:flex;justify-content:space-between;
    transform:translateY(calc(var(--space-3xs) * 1.5));
    gap:var(--space-2xs);overflow-x:auto;scrollbar-width:none}  /* under 360px it scrolls sideways, never shrinks or wraps */
  .peek-links::-webkit-scrollbar{display:none}
  .peek a{font-family:var(--font-body);font-size:var(--text-fine);font-weight:500;color:var(--band-soft);
    text-decoration:none;white-space:nowrap;padding-block:var(--space-2xs);
    text-shadow:0 0 .35em var(--band),0 1px 2px var(--band)}
  .peek a:hover,.peek a[aria-current]{color:var(--band-accent)}
}
@media(prefers-reduced-motion:reduce){.totop,.totop.on,.peek,.peek.on{transition:none}}

/* The nations map: the desktop masthead (2026-11-08, Darby; nav_map_html()
   in build.py, geometry in docs/nav-map/map5.json). Phones keep the plain
   header. The band is full-bleed; the SVG is drawn at 1280 wide and stays
   that size, centered, down to 1024 (the gutters crop). Under 1024 the
   wordmark and Subscribe/About/Contact would hit the page gutter, so it
   scales: (screen - 2 gutters) / 976, the width from the wordmark's left
   edge to the stack's right edge. */
.nmap{display:none}
.mapbar{display:none}
@media(min-width:761px){
  .masthead.has-map{position:static;backdrop-filter:none}
  .masthead.has-map .mast-row{display:none}
  .nmap{display:flex;justify-content:center;overflow:hidden;line-height:0}
  .nm{flex:none;display:block;overflow:visible;height:auto;
    width:min(80rem,calc((100% - 2 * var(--gutter)) * 1280 / 976))}
  .nm-world{fill:none;stroke:var(--map-neighbor);stroke-width:1;pointer-events:none}
  .nm-blank{fill:none;stroke:var(--map-blank);stroke-opacity:.8;stroke-width:1;
    stroke-dasharray:4 3;pointer-events:none}
  .nm-depth{pointer-events:none}
  .nm-depth use{fill:none}
  .nm-depth .r1{stroke:var(--c);stroke-opacity:.2;stroke-width:35.2}   /* ring 17px in */
  .nm-depth .e1{stroke:var(--band);stroke-width:32.8}
  .nm-depth .r2{stroke:var(--c);stroke-opacity:.38;stroke-width:19.2}  /* ring 9px in */
  .nm-depth .e2{stroke:var(--band);stroke-width:16.8}
  .nm .nat{cursor:pointer;outline:none;-webkit-tap-highlight-color:transparent}
  .nm .hit{fill:transparent;stroke:none;fill-rule:evenodd}
  .nm .tube{fill:none;stroke:var(--c);stroke-width:4;stroke-opacity:.8;transition:stroke-opacity .15s}
  .nm .glow{fill:none;stroke:var(--c);stroke-width:2;opacity:0;pointer-events:none;
    filter:drop-shadow(0 0 4px var(--c)) drop-shadow(0 0 10px var(--c));transition:opacity .15s}
  .nm .nat:is(:hover,:focus-visible,[aria-current]) .tube{stroke-opacity:1}
  .nm .nat:is(:hover,:focus-visible,[aria-current]) .glow{opacity:1}
  /* The band-colored outline stops contour lines short of the letters, like
     a printed map's labels (2026-11-08 night, Darby: words ran into rings). */
  .nm .nat text{font-family:var(--font-body);font-weight:500;text-anchor:middle;fill:var(--c);
    pointer-events:none;paint-order:stroke;stroke:var(--band);stroke-width:5px;stroke-linejoin:round}
  .nm-stack{outline:none}
  .nm-stack text{font-family:var(--font-body);font-weight:500;text-anchor:end;fill:var(--band-soft);
    transition:fill .15s}
  .nm-stack:is(:hover,:focus-visible,[aria-current]) text{fill:var(--band-accent)}
  .nm-stack:focus-visible text,.nm .nat:focus-visible text{text-decoration:underline}
  .nm-sub-box{fill:transparent;stroke:var(--sub-btn);stroke-width:1.5;transition:fill .15s}
  .nm-sub text{fill:var(--sub-btn)}
  .nm-sub:is(:hover,:focus-visible,[aria-current]) .nm-sub-box{fill:var(--sub-btn)}
  .nm-sub:is(:hover,:focus-visible,[aria-current]) text{fill:var(--sub-btn-ink);text-decoration:none}
  .nm-mark{outline:none}
  .nm-mark text{font-family:var(--font-wordmark);font-weight:400}
  .nm-mark .darb{fill:var(--wordmark-darb);transition:fill .15s}
  .nm-mark .nation{fill:var(--wordmark-nation);transition:fill .15s}
  .nm-mark:is(:hover,:focus-visible) .darb{fill:var(--wordmark-darb-hover)}
  .nm-mark:is(:hover,:focus-visible) .nation{fill:var(--wordmark-nation-hover)}
  /* DarbNation's outer border: faint gold at rest, neon gold while the
     wordmark is hovered. The wordmark comes first in the SVG (first Tab
     stop) and the border last (drawn on top), hence :has(). */
  .nm-dn{fill:none;stroke:var(--map-border);stroke-opacity:.4;stroke-width:1.5;pointer-events:none;
    transition:stroke-opacity .15s,filter .15s}
  .nm:has(.nm-mark:is(:hover,:focus-visible)) .nm-dn{stroke-opacity:1;stroke-width:2.5;
    filter:drop-shadow(0 0 5px var(--map-border)) drop-shadow(0 0 12px var(--map-border))}

  /* After the map scrolls away: a one-line bar fades in (NAVMAP_JS). Wordmark,
     the seven sections, then Subscribe · About · Contact on the right. */
  .mapbar{display:block;position:fixed;top:0;left:0;right:0;z-index:20;background:var(--band);
    box-shadow:0 2px 12px rgb(0 0 0 / .25);opacity:0;visibility:hidden;
    transition:opacity .2s,visibility 0s .2s}
  .mapbar.on{opacity:1;visibility:visible;transition:opacity .2s}
  .mapbar .wrap{display:flex;align-items:center;gap:var(--space-m);padding-block:var(--space-2xs)}
  .mapbar .brand{font-size:var(--text-wordmark-bar)}
  .mb-nav{flex:1;min-width:0;display:flex;align-items:center;gap:var(--space-m)}
  .mb-row{display:flex;align-items:center;gap:var(--space-s)}
  .mb-admin{margin-left:auto}
  .mb-nav a{font-family:var(--font-body);font-size:var(--text-ui);font-weight:500;color:var(--band-soft);
    text-decoration:none;letter-spacing:.01em;white-space:nowrap}
  .mb-nav a:hover,.mb-nav a[aria-current]{color:var(--band-accent)}
}
/* 761-900: the bar's links tighten so the line still fits. Under 840 the
   ten words need 15px (the floor) and 8px gaps: at 761 that's 699px of a
   713px line (measured). */
@media(min-width:761px) and (max-width:900px){
  .mapbar .wrap,.mb-nav{gap:var(--space-s)}
  .mb-row{gap:var(--space-xs)}
}
@media(min-width:761px) and (max-width:840px){
  .mapbar .wrap,.mb-nav{gap:var(--space-xs)}
  .mb-row{gap:var(--space-2xs)}
  .mb-nav a{font-size:var(--text-fine);letter-spacing:0}
}
/* Contact gets the same center from 370px up, so Hope / Vids / Contact make
   one column. Row three is the smaller size, so Hope's center is written in
   row one's size: 33.333% + .9991 x that size; About 2.969em, Contact
   3.869em. Narrower, the Subscribe button leaves no room: row three stays
   justified there, Contact within ~4px of the column. */
@media(min-width:370px) and (max-width:760px){
  .masthead .nav>.nav-row:last-child{justify-content:flex-start}
  .masthead .nav>.nav-row:last-child>a:nth-child(2){
    margin-left:calc(33.333% + .9991 * var(--text-nav-phone) - 4.903em - var(--nav-phone-gap))}
  .masthead .nav>.nav-row:last-child>a:last-child{margin-left:auto}
}
/* Under 345 the phone header shrinks as one piece, like zooming out on the
   345 view (Darby, 2026-11-08 night: words may go under 15px on tiny screens
   so it doesn't look tight). Was 320 until the Subscribe button, which needs
   ~20px more on the bottom row. Bottom row ~14px at 320, 13 at 300. */
@media(max-width:344.98px){
  :root{--text-nav-phone:5vw;--text-nav-phone-sm:4.348vw;--nav-phone-gap:2.319vw;--sub-btn-pad:2.319vw}
  .masthead .wrap{gap:4.638vw;padding-inline:4.638vw}
}
/* The bar's wordmark: DARBNATION is 23% wider than DarbNation, so it steps
   down where the bar is tight. */
@media(min-width:761px) and (max-width:1000px){:root{--text-wordmark-bar:1.25rem}}
@media(min-width:761px) and (max-width:860px){:root{--text-wordmark-bar:1.125rem}}  /* 18px: room for the Subscribe button */
/* Subscribe as an outlined button (2026-11-08 night, Darby), phone header
   and desktop bar. Same 7px corners as the site's buttons; fills gold on
   hover. Its box adds no height to its row. */
:is(.masthead .nav,.mb-nav) a.sub-btn{border:1.5px solid var(--sub-btn);border-radius:7px;
  color:var(--sub-btn);padding:0 var(--sub-btn-pad,var(--space-2xs));line-height:1.25;
  transition:background .15s,color .15s}
:is(.masthead .nav,.mb-nav) a.sub-btn:is(:hover,:focus-visible,[aria-current]){background:var(--sub-btn);color:var(--sub-btn-ink)}
.mb-nav a.sub-btn{--sub-btn-pad:var(--space-xs);padding-block:var(--space-3xs)}
@media(max-width:900px){.mb-nav a.sub-btn{--sub-btn-pad:var(--space-2xs)}}
.masthead .nav>.nav-row:last-child{align-items:center}
@media(prefers-reduced-motion:reduce){.mapbar,.mapbar.on,.nm .tube,.nm .glow,.nm-dn,.sub-btn{transition:none}}
