
:root{
  --paper:#F5F2EB; --ink:#1B1A17; --soft:#3D3A34; --muted:#6B675F;
  --bg:var(--paper); --fg:var(--ink); --dim:var(--muted); --quiet:var(--soft);
  --rule:#E0DACD; --panel:#EDE8DE; --field:#FFFFFF;
  /* The walkthrough bubble sits on top of a dimmed page, so it cannot be the page's own
     background: on the dark theme that is #141311 on #141311 behind a scrim, and the
     panel has no edge. It gets a surface lifted well clear of the page, a border light
     enough to read against it, and a deeper scrim to sit on. */
  --tourbg:var(--bg); --tourline:var(--rule); --scrim:rgba(8,7,6,.68);
  /* The table question carries the three logo dots as a gradient. It is not the dots'
     own values: the bubble inverts by theme -- ink with paper text on paper, paper with
     ink text in the dark -- so each theme gets the three hues at a lightness its text
     can sit on. The quiet lines used to be var(--bg) at an opacity, which composited to
     4.0 against this gradient and was already at 3.4 against the flat dark bubble it
     replaces. They are solid mixes now, measured at 5.9 and up. */
  --tq1:oklch(0.30 0.09 155); --tq2:oklch(0.30 0.09 250); --tq3:oklch(0.30 0.09 305);
  --c57:oklch(0.48 0.13 155); --c812:oklch(0.48 0.13 250); --c1317:oklch(0.48 0.13 305);
  --tint57:oklch(0.94 0.035 155); --tint812:oklch(0.94 0.035 250); --tint1317:oklch(0.94 0.035 305);
  /* The card edge, which is the one place a band colour has to read as a COLOUR rather
     than as a darker line. On the dark theme the band is already light and chromatic and
     does that by itself; on paper, oklch 0.48 lands as a dark grey-blue, so the edge gets
     its own lighter, more saturated value. */
  --edge57:oklch(0.55 0.20 155); --edge812:oklch(0.55 0.20 250); --edge1317:oklch(0.55 0.20 305);
  --display:"Libre Caslon Display",Georgia,serif;
  --text:"Libre Caslon Text",Georgia,serif;
  --sans:"Instrument Sans",system-ui,-apple-system,sans-serif;
  color-scheme:light;
}
/* The system decides until the reader overrides it, and data-theme is how they do.
   The :not() guard is what lets an explicit "light" win against a dark OS. */
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){
  color-scheme:dark;
  --edge57:var(--c57); --edge812:var(--c812); --edge1317:var(--c1317);
  --bg:#141311; --fg:#F1EDE4; --dim:#A8A295; --quiet:#C9C3B5;
  --rule:#2E2C27; --panel:#1D1C19; --field:#221F1B;
  --tourbg:#2B2925; --tourline:#4F4B43; --scrim:rgba(0,0,0,.80);
  --tq1:oklch(0.90 0.045 155); --tq2:oklch(0.90 0.045 250); --tq3:oklch(0.90 0.045 305);
  --c57:oklch(0.78 0.12 155); --c812:oklch(0.76 0.12 250); --c1317:oklch(0.78 0.12 305);
  --tint57:oklch(0.26 0.04 155); --tint812:oklch(0.26 0.04 250); --tint1317:oklch(0.26 0.04 305);
}}
:root[data-theme="dark"]{
  color-scheme:dark;
  --edge57:var(--c57); --edge812:var(--c812); --edge1317:var(--c1317);
  --bg:#141311; --fg:#F1EDE4; --dim:#A8A295; --quiet:#C9C3B5;
  --rule:#2E2C27; --panel:#1D1C19; --field:#221F1B;
  --tourbg:#2B2925; --tourline:#4F4B43; --scrim:rgba(0,0,0,.80);
  --tq1:oklch(0.90 0.045 155); --tq2:oklch(0.90 0.045 250); --tq3:oklch(0.90 0.045 305);
  --c57:oklch(0.78 0.12 155); --c812:oklch(0.76 0.12 250); --c1317:oklch(0.78 0.12 305);
  --tint57:oklch(0.26 0.04 155); --tint812:oklch(0.26 0.04 250); --tint1317:oklch(0.26 0.04 305);
}

/* Derived from --tq2 so one set of rules serves both themes: on paper these step down
   toward the ink, in the dark they step down toward the paper. Percentages picked by
   rendering them over the gradient's worst stop and reading the pixels: 68% is 5.9:1,
   78% is 7.4:1, both clear of the 4.5 a 13px line needs. */
:root{
  --tqquiet:color-mix(in oklab, var(--bg) 68%, var(--tq2));
  --tqlabel:color-mix(in oklab, var(--bg) 78%, var(--tq2));
  --tqmid:color-mix(in oklab, var(--bg) 88%, var(--tq2));
}

/* The age is a document-level fact: one attribute on <html> colours and reveals
   the whole page, so switching it touches no element's inline style. */
html[data-band="5-7"]{--band:var(--c57); --bandtint:var(--tint57); --bandedge:var(--edge57)}
html[data-band="8-12"]{--band:var(--c812); --bandtint:var(--tint812); --bandedge:var(--edge812)}
html[data-band="13-17"]{--band:var(--c1317); --bandtint:var(--tint1317); --bandedge:var(--edge1317)}
[data-for]{display:none}
html[data-band="5-7"] [data-for="5-7"],
html[data-band="8-12"] [data-for="8-12"],
html[data-band="13-17"] [data-for="13-17"]{display:block}

*{box-sizing:border-box}
/* Clearance for the sticky header on an anchor jump, which has to be taller than the
   header or the target lands under it. It was 120px against a header of 138 on a phone
   and 160 on a tablet, so "Skip to the stories" put the first story 18px out of sight. */
html{scroll-padding-top:175px}
@media (max-width:640px){html{scroll-padding-top:150px}}
body{margin:0; background:var(--bg); color:var(--fg); font-family:var(--sans);
     font-size:14px; line-height:1.5; -webkit-font-smoothing:antialiased}
img{max-width:100%; display:block}
a{color:inherit}
.wrap{width:100%; max-width:var(--page,720px); margin:0 auto; padding-inline:20px}
body.wide{--page:1120px}      /* the front page: three stories abreast */
body.list{--page:880px}       /* the archive: a list, wider than prose but not by much */
.eyebrow{font-size:12px; font-weight:600; letter-spacing:.1em; text-transform:uppercase; color:var(--dim)}
.sep{opacity:.5; margin-inline:6px}
.skip{position:absolute; left:-9999px}
.skip:focus{left:20px; top:8px; z-index:40; background:var(--fg); color:var(--bg); padding:8px 14px; border-radius:3px}

/* ---- masthead ---------------------------------------------------- */
header{position:sticky; top:0; z-index:20; background:var(--bg); border-bottom:1px solid var(--rule)}
.bar{display:flex; align-items:center; justify-content:space-between; gap:16px; padding-block:14px}
/* render.py's wordmark(): three lines with the dots beneath, dot 45% of the type
   size and the gaps proportional to it, so the site and the slides carry one mark. */
.mark{display:inline-flex; flex-direction:column; align-items:flex-start; gap:9px;
      text-decoration:none; padding-block:2px}
.wm{font-family:var(--display); font-size:17px; line-height:1.0; letter-spacing:-.01em}
.dots{display:flex; gap:6px}
.dots i{width:8px; height:8px; border-radius:50%; display:block}
/* The mark is a stack now, so it is taller than it was, and the masthead is sticky.
   Scaled down on a phone to keep the whole sticky block near a seventh of the screen
   rather than a fifth: the pills below it are the part worth keeping on screen. */
@media (max-width:640px){
  .mark{gap:6px}
  .wm{font-size:14px}
  .dots{gap:5px}
  .dots i{width:6px; height:6px}
  .bar{padding-block:11px}
  .ages{padding-block:10px}
}
/* Desktop takes the mark at 27px, which is the size render.py prints on every slide, so
   the site and the carousels carry one mark at one size rather than two sizes of a
   similar idea. The dot stays 45% of the type and the gap 50%, the proportions the mark
   has always had, so it scales as a unit. The phone keeps 14px: the sticky block there
   is sized to leave the pills on screen, and this would take 40px of it. */
@media (min-width:940px){
  .mark{gap:13px}
  .wm{font-size:27px}
  .dots{gap:10px}
  .dots i{width:12px; height:12px}
  /* The header is 198px here rather than 160, so the clearance grows with it. */
  html{scroll-padding-top:215px}
}
/* On a phone the prompt cannot share a line with three pills, so it takes one of its
   own and the sticky block grows by a fifth for a line nobody needs: the pills read
   "5-7 year old". Hidden from the eye, kept for a screen reader, which still gets the
   group's own label. */
@media (max-width:560px){
  .ages .lab{position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%);
             white-space:nowrap}
}
nav{display:flex; gap:18px; font-size:14px}
/* The three links are a group of their own so the walkthrough can spotlight all of
   them at once -- and so the theme toggle, which is not a destination, stays out of it. */
.nav-links{display:flex; align-items:center; gap:18px}
nav a{color:var(--dim); text-decoration:none}
nav a:hover,nav a[aria-current="page"]{color:var(--fg)}
/* In the masthead Share is a nav item, not a button: the same size, colour and hover as
   the links beside it. It keeps class="share" so the one share handler still finds it. */
nav .nav-share{font:inherit; font-size:14px; font-weight:400; line-height:inherit;
  padding:0; border:0; border-radius:0; background:none; color:var(--dim); cursor:pointer}
nav .nav-share:hover{color:var(--fg)}
nav .nav-share:focus-visible{outline:2px solid var(--fg); outline-offset:3px}
.theme{display:inline-flex; align-items:center; justify-content:center; width:30px; height:30px;
  padding:0; margin-left:-4px; border:0; border-radius:50%; background:transparent;
  color:var(--dim); cursor:pointer}
.theme:hover{color:var(--fg)}
.theme:focus-visible{outline:2px solid var(--fg); outline-offset:2px}
.bar nav{align-items:center}

/* ---- the age control: the whole idea of the site ------------------ */
.ages{display:flex; align-items:center; gap:10px; flex-wrap:wrap; padding-block:12px; border-top:1px solid var(--rule)}
.ages .lab{font-size:13px; color:var(--dim)}
.seg{display:flex; gap:6px}
.seg button{font-family:var(--sans); font-size:14px; font-weight:500; cursor:pointer; white-space:nowrap;
  padding:7px 16px; border-radius:999px; background:transparent; color:var(--dim); border:1.5px solid var(--rule)}
@media (max-width:440px){.ages{gap:8px} .seg{gap:5px} .seg button{padding:7px 11px; font-size:13px}}
.seg button:hover{color:var(--fg)}
.seg button[data-band="5-7"]{--band:var(--c57); --bandtint:var(--tint57)}
.seg button[data-band="8-12"]{--band:var(--c812); --bandtint:var(--tint812)}
.seg button[data-band="13-17"]{--band:var(--c1317); --bandtint:var(--tint1317)}
.seg button[aria-pressed="true"]{color:var(--band); border-color:var(--band); background:var(--bandtint)}
.seg button:focus-visible{outline:2px solid var(--band); outline-offset:2px}

/* ---- today -------------------------------------------------------- */
/* The lede under this headline explained the control sitting directly above it, so it
   was instructions for a button you can already see. Dropping it, and tightening here,
   is worth about 50px of a phone screen before the first story. */
.today{padding-block:26px 6px}
.today h1{font-family:var(--display); font-weight:400; font-size:clamp(28px,6vw,38px);
          line-height:1.1; margin:6px 0 0; text-wrap:balance}
.today p{color:var(--dim); font-size:15px; margin:10px 0 0; max-width:46ch}

article{padding-block:34px; border-top:1px solid var(--rule)}
.cat{display:flex; align-items:center; gap:8px; flex-wrap:wrap}
.cat b{font-weight:600; color:var(--band)}
/* The news, in ink at medium weight, under a marker stroke. The sans/serif split still
   carries the hierarchy: sans is the reporting, the serif question underneath is the kid.
   The marker is one fixed yellow in both themes rather than the age colour, which is
   already carrying the question's quote marks, the rule beside the answer and the card's
   hover edge -- a fourth use of it would stop meaning anything. Read it as a division of
   labour: the age colour is the kid's half of the card, the marker is the news half.
   The stroke is an SVG stretched to the line box, not a rectangle, so its edges run a
   little off-square the way a pen does; box-decoration-break paints it onto every line
   of a headline that wraps, and the line-height gives two strokes room not to touch.
   Ink on this yellow holds in both themes, so the text colour is fixed alongside it. */
.hl{font-family:var(--sans); font-size:17px; font-weight:500; line-height:1.5; color:var(--fg);
    margin:10px 0 0; max-width:52ch}
.hl a{text-decoration:none; color:#1B1A17; padding:2px 7px; margin-left:-7px;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 20' preserveAspectRatio='none'%3E%3Cpath d='M1.4 3.4 C 26 1.1, 58 4.4, 98.7 1.9 L 99.3 17.1 C 71 19.8, 29 15.6, 0.7 18.4 Z' fill='%23F7E07A'/%3E%3C/svg%3E") 0 0 / 100% 100% no-repeat;
  box-decoration-break:clone; -webkit-box-decoration-break:clone}
.hl a:hover{text-decoration:underline; text-underline-offset:3px}
.q{font-family:var(--display); font-weight:400; font-size:clamp(30px,6.4vw,44px);
   line-height:1.04; letter-spacing:-.02em; margin:18px 0 0; text-wrap:balance}
.q .mk{color:var(--band)}
.a{font-family:var(--text); font-size:clamp(19px,3.6vw,21px); line-height:1.5; margin:16px 0 0;
   max-width:40ch; border-left:3px solid var(--band); padding-left:18px}
.src{font-size:13px; color:var(--dim); margin-top:18px; display:flex; gap:8px; flex-wrap:wrap; align-items:baseline}
.src a{text-decoration:underline; text-underline-offset:2px}
/* The three stories are cards: the whole card is the link, so it gets an edge to be
   the extent of. Border rather than a filled panel -- three filled blocks would shout
   over the type, which is the thing worth looking at. */
.stories{display:grid; gap:18px; margin-top:26px}
.stories article{border:1px solid var(--rule); border-radius:3px; padding:24px 22px;
  display:flex; flex-direction:column;
  transition:border-color .15s ease, background-color .15s ease}
.stories article.tappable{cursor:pointer}
.stories article:hover,
.stories article:focus-within{border-color:var(--bandedge); background:var(--panel)}
/* Stacked, not flowed: a long outlet name wraps the link onto a second line in one
   card and not the next, and two cards' footers stop lining up. Always two lines. */
.stories .src{margin-top:auto; padding-top:20px; flex-direction:column;
  align-items:flex-start; gap:7px}
/* The two links do different things, so they sit at opposite ends: the source leaves
   the site, the other goes further into it. */
.stories .src .more{align-self:flex-end}
.stories .hl a:hover{text-decoration:none}   /* the whole card is already the target */

/* Three abreast once there is room for three readable columns. The question steps
   down: 44px display type in a 340px column is a wall. */
@media (min-width:940px){
  body.wide .stories{grid-template-columns:repeat(3,1fr); gap:24px}
  body.wide .stories .q{font-size:clamp(24px,2.3vw,31px); margin-top:14px}
  body.wide .stories .a{font-size:18px; margin-top:14px}
  body.wide .search{max-width:520px}
  body.wide .today h1{font-size:44px}
}
/* Where the card cannot be hovered, the age's colour has no way to appear, so the whole
   border carries it instead of the neutral hairline. The query asks about hover rather
   than width because that is the actual reason: a tablet cannot hover either, and a
   desktop window dragged narrow still can. The border rather than a tint, which washes a
   whole page of same-age cards, or a shadow, which is invisible on the dark theme. */
@media (hover:none){
  .stories article{border-color:var(--band)}
}
@media (prefers-reduced-motion:reduce){.stories article{transition:none}}
.more{font-size:14px; color:var(--band); text-decoration:none; font-weight:500}
.more:hover{text-decoration:underline; text-underline-offset:3px}

/* ---- table question ------------------------------------------------ */
/* Inverted, the way the carousel's last slide is. It is the only dark thing on a light
   page and the only light thing on a dark one, which is the point: everything else here
   is something to read, and this is something to answer. Keyed to --fg/--bg rather than
   to ink so it inverts in both themes instead of just the one. */
.table-q{background:linear-gradient(103deg,var(--tq1),var(--tq2) 52%,var(--tq3));
         color:var(--bg); border-radius:18px; padding:32px 30px 34px;
         margin-block:12px 22px; position:relative}
/* The tail. Two borders on an empty box: a flat top the width of the tail and a
   transparent right edge, which leaves a triangle hanging off the bottom-left corner.
   18px of bottom margin above keeps it from landing on whatever follows. */
.table-q::after{content:""; position:absolute; left:34px; bottom:-17px; width:0; height:0;
  border-top:18px solid var(--tq1); border-right:20px solid transparent}
.table-q .basis{font-size:14px; line-height:1.45; margin:10px 0 0; max-width:60ch}
.table-q .basis .lab{color:var(--tqquiet)}
.table-q .basis .hd{color:var(--tqmid)}
.table-q .eyebrow{color:var(--tqlabel)}
.table-q h2{font-family:var(--display); font-weight:400; font-size:clamp(24px,5vw,32px);
            line-height:1.12; margin:12px 0 0; text-wrap:balance; color:var(--bg)}
.table-q p{font-size:14px; color:var(--tqquiet); margin:16px 0 0}

/* ---- blocks: archive, follow --------------------------------------- */
section.block{padding-block:34px; border-top:1px solid var(--rule)}
.block h2{font-family:var(--display); font-weight:400; font-size:26px; margin:8px 0 0}
.block p{color:var(--dim); font-size:15px; margin:10px 0 0; max-width:48ch}
.search{display:flex; gap:8px; margin-top:16px; flex-wrap:wrap}
.search input{flex:1 1 220px; min-width:0; font-family:var(--sans); font-size:15px; padding:11px 14px;
  border-radius:3px; border:1.5px solid var(--rule); background:var(--field); color:var(--fg)}
.search button{font-family:var(--sans); font-size:15px; font-weight:500; padding:11px 20px;
  border-radius:3px; border:1.5px solid var(--fg); background:var(--fg); color:var(--bg); cursor:pointer}
.chips{display:flex; flex-wrap:wrap; gap:8px; margin-top:14px}
.chips button,.chips span{font-family:var(--sans); font-size:13px; color:var(--dim); border:1px solid var(--rule);
  border-radius:999px; padding:5px 12px; background:transparent; cursor:pointer}
.chips button:hover:not([disabled]){color:var(--fg)}
.chips button[disabled]{opacity:.38; cursor:default}
.chips button[aria-pressed="true"]{color:var(--band); border-color:var(--band); background:var(--bandtint)}
.note{font-size:13px; color:var(--dim); margin-top:10px; min-height:1.2em}
.ageask{border:0; margin:14px 0 0; padding:0; display:flex; flex-wrap:wrap; gap:8px; align-items:center}
.ageask legend{float:left; width:100%; font-size:13px; color:var(--dim); padding:0; margin-bottom:8px}
.agebox{display:inline-flex}
.agebox input{position:absolute; width:1px; height:1px; opacity:0; margin:0}
.agebox span{display:inline-block; font-size:14px; font-weight:500; cursor:pointer; white-space:nowrap;
  padding:7px 16px; border-radius:999px; border:1.5px solid var(--rule); color:var(--dim)}
.agebox:nth-of-type(1) span{--band:var(--c57); --bandtint:var(--tint57)}
.agebox:nth-of-type(2) span{--band:var(--c812); --bandtint:var(--tint812)}
.agebox:nth-of-type(3) span{--band:var(--c1317); --bandtint:var(--tint1317)}
.agebox input:checked + span{color:var(--band); border-color:var(--band); background:var(--bandtint)}
.agebox input:focus-visible + span{outline:2px solid var(--band); outline-offset:2px}
@media (max-width:440px){.agebox span{padding:7px 12px; font-size:13px}}
.follow-card{display:flex; gap:16px; align-items:center; margin-top:16px; padding:18px 20px;
  background:var(--panel); border-radius:3px; flex-wrap:wrap}
.follow-card .at{font-family:var(--display); font-size:19px}
/* The handle and two buttons want 322px and a phone gives the card 310. Shortening the
   label to "Share" bought 31px of that and left 12 short, so the row still broke. The
   gap, the card's own padding and the buttons give up a few pixels each rather than one
   of them giving up a lot: at 360px it now needs 281 against 292 available. */
@media (max-width:480px){
  .follow-card{gap:10px; padding:16px 14px}
  .follow-card .at{font-size:17px}
  .follow-card .btn,.follow-card .share{padding:10px 14px}
}
.btn{display:inline-block; font-size:15px; font-weight:500; padding:10px 18px; border-radius:3px;
  border:1.5px solid var(--fg); background:var(--fg); color:var(--bg); text-decoration:none}

/* ---- archive ---------------------------------------------------------- */
.stories article.hidden{display:none}
.count{font-size:13px; color:var(--dim); margin-top:16px}
.more-row{display:flex; justify-content:center; padding-block:10px 40px}
.more-btn{font-family:var(--sans); font-size:15px; font-weight:500; cursor:pointer;
  padding:11px 26px; border-radius:999px; border:1.5px solid var(--rule);
  background:transparent; color:var(--fg)}
.more-btn:hover{border-color:var(--fg)}
.more-btn:focus-visible{outline:2px solid var(--fg); outline-offset:2px}
.more-btn[hidden]{display:none}

/* ---- a single post --------------------------------------------------- */
/* A post is an <article> too, but it opens the page: it takes neither the rule
   between stories nor the space that rule needs. */
.post{padding-block:0; border-top:0}
.post > .head{padding-block:26px 0}
.post > .lede{padding-block:0 8px}

.post h1{font-family:var(--display); font-weight:400; font-size:clamp(30px,6.2vw,42px);
         line-height:1.08; margin:10px 0 0; text-wrap:balance; letter-spacing:-.01em}
.post .summary{font-family:var(--text); font-size:clamp(17px,3.2vw,19px); line-height:1.55;
               margin:18px 0 0; max-width:44ch; color:var(--quiet)}
.script{font-family:var(--text); font-size:clamp(19px,3.6vw,22px); line-height:1.5; margin:16px 0 0;
        max-width:42ch; border-left:3px solid var(--band); padding-left:18px}
.chip{display:inline-flex; align-items:center; gap:8px; font-size:13px; font-weight:500; color:var(--quiet);
      background:var(--panel); border-radius:999px; padding:6px 14px; margin-top:6px}
/* .block .why, not .why: the note is a <p> inside section.block, so `.block p` above
   outranked a bare .why and its margin never applied. */
.block .why{font-size:14px; color:var(--dim); margin:16px 0 0; max-width:46ch}
/* Stacked, the label lands straight under the script's quote rule and reads as the
   last line of it. A line's worth of air makes it the note about the script instead.
   Above 1000px the script and the note are in separate columns already. */
@media (max-width:999px){.block .why{margin-top:37px}}
.why b{color:var(--band); font-weight:600; letter-spacing:.08em; text-transform:uppercase; font-size:12px;
       display:block; margin-bottom:4px}
.asks{margin-top:26px; background:var(--bandtint); border-radius:3px; padding:22px 20px}
.asks .lab{font-size:12px; font-weight:600; letter-spacing:.1em; text-transform:uppercase; color:var(--band)}
.asks dl{margin:0}
.asks dt{font-family:var(--display); font-size:20px; line-height:1.2; margin-top:16px; text-wrap:balance}
.asks dd{font-family:var(--text); font-size:16px; line-height:1.5; color:var(--quiet); margin:6px 0 0}
.asks dd:before{content:"Try: "; font-family:var(--sans); font-size:12px; font-weight:600;
                letter-spacing:.08em; text-transform:uppercase; color:var(--dim)}
.others{font-size:14px; color:var(--dim); margin-top:22px}
.others button{font:inherit; color:var(--fg); background:none; border:0; padding:0; cursor:pointer;
               text-decoration:underline; text-underline-offset:3px}
.ig{display:flex; gap:16px; align-items:center; margin-top:8px; flex-wrap:wrap}
.ig img{width:120px; border-radius:3px}
.ig .credit{font-size:12px; color:var(--dim); margin:10px 0 0; max-width:42ch}
.pager{display:flex; justify-content:space-between; gap:16px; padding-block:26px;
       border-top:1px solid var(--rule); font-size:14px}
.pager a{color:var(--dim); text-decoration:none; max-width:46%}
.pager a:hover{color:var(--fg)}
.pager .lab{display:block; font-size:12px; letter-spacing:.08em; text-transform:uppercase; margin-bottom:4px}

/* A text page takes the wide measure so its masthead matches every other page, and
   holds the reading column to what a reader can track. The rules between sections stop
   with the column: run to 1120 under a 480px column and the empty half looks like a
   layout that broke rather than a margin. */
body.text main.wrap > *{max-width:62ch}
.prose{max-width:60ch}

/* Wide screens: the dateline and headline span, and the summary and the age script sit
   side by side under them. Both columns take the same padding and the summary loses its
   top margin, so the two start on the same line rather than 18px apart. The rule that
   separated summary from ages when they were stacked moves under the headline, where it
   now separates one thing from two. */
@media (min-width:1000px){
  /* Two 410px columns and a 56px gutter. Everything below the article -- what went out,
     the pager, the follow card -- takes the same width, or the rules under a two-column
     story stop where the columns do not. */
  body.text main.wrap > *{max-width:876px}
  .post{display:grid; grid-template-columns:1fr 1fr; gap:0 56px; align-items:start}
  .post > .head{grid-column:1 / -1; border-bottom:1px solid var(--rule); padding-bottom:26px}
  .post > .lede{grid-column:1; grid-row:2; padding-block:30px 0}
  .post > section.block{grid-column:2; grid-row:2; padding-block:30px 0; border-top:0}
  .post > .lede .summary{margin-top:0}
  .post > .table-q{grid-column:1 / -1; grid-row:3; margin-top:36px}
}
.prose h2{font-family:var(--display); font-weight:400; font-size:24px; margin:34px 0 0}
.prose h3{font-family:var(--sans); font-size:14px; font-weight:600; letter-spacing:.04em;
  margin:24px 0 0; color:var(--band)}
.prose h3 .yr{color:var(--dim); font-weight:500; letter-spacing:0}
.prose .stage{border-left:2px solid var(--rule); padding-left:18px; margin-top:8px}
.prose .stage.b57{--band:var(--c57)} .prose .stage.b812{--band:var(--c812)}
.prose .stage.b1317{--band:var(--c1317)}
.prose .stage{border-left-color:var(--band)}
.prose p{font-size:15px; line-height:1.65; color:var(--quiet); margin:12px 0 0}
.prose a{text-decoration:underline; text-underline-offset:2px}

/* ---- share + first-visit walkthrough ---------------------------------- */
.share{font:inherit; font-size:15px; font-weight:500; cursor:pointer; padding:10px 18px;
  border-radius:3px; border:1.5px solid var(--rule); background:transparent; color:var(--fg)}
.share:hover{border-color:var(--fg)}
.share:focus-visible{outline:2px solid var(--fg); outline-offset:2px}

/* The dim is the hole's own box-shadow, so the panel itself is only the highlight.
   The backdrop is a separate full-screen layer, because a shadow does not take a
   click: without it a reader could tap a story card straight through the tour. */
.tour{position:fixed; inset:0; z-index:60}
.tour-hole{position:absolute; border-radius:6px; pointer-events:none;
  box-shadow:0 0 0 9999px var(--scrim); transition:top .2s ease, left .2s ease,
  width .2s ease, height .2s ease}
.tour-hole.none{box-shadow:0 0 0 9999px var(--scrim); width:0; height:0; top:50%; left:50%}
.tour-bub{position:absolute; width:min(340px, calc(100vw - 32px)); background:var(--tourbg);
  color:var(--fg); border:1px solid var(--tourline); border-radius:4px; padding:20px 20px 14px;
  box-shadow:0 14px 44px rgba(0,0,0,.34)}
.tour-bub.mid{position:fixed; top:50%; left:50%; transform:translate(-50%,-50%); text-align:left}
.tour-n{font-size:12px; font-weight:600; letter-spacing:.1em; text-transform:uppercase;
  color:var(--dim); margin:0}
.tour-h{font-family:var(--display); font-weight:400; font-size:24px; margin:10px 0 0}
/* pre-line so a step written as two paragraphs stays two paragraphs: the text is set
   with textContent, and a real newline is the only break that survives that. */
.tour-t{font-size:15px; line-height:1.55; color:var(--quiet); margin:10px 0 0;
  white-space:pre-line}
.tour-act{display:flex; align-items:center; gap:10px; margin-top:18px}
.tour-act .sp{flex:1}
.tour-skip{font:inherit; font-size:14px; background:none; border:0; color:var(--dim);
  cursor:pointer; padding:8px 4px; text-decoration:underline; text-underline-offset:3px}
.tour-skip:hover{color:var(--fg)}
.tour-next{font:inherit; font-size:15px; font-weight:500; cursor:pointer; padding:10px 20px;
  border-radius:3px; border:1.5px solid var(--fg); background:var(--fg); color:var(--bg)}
/* Back and Share are the same quiet button. Their edge is the bubble's, not the page's:
   --rule against the lifted dark surface is all but invisible. */
.tour-back{font:inherit; font-size:15px; font-weight:500; cursor:pointer; padding:10px 16px;
  border-radius:3px; border:1.5px solid var(--tourline); background:transparent; color:var(--fg)}
.tour-back:hover,.tour-bub .share:hover{border-color:var(--fg)}
.tour-bub .share{border-color:var(--tourline)}
.tour-next:focus-visible,.tour-skip:focus-visible,
.tour-back:focus-visible{outline:2px solid var(--fg); outline-offset:2px}
@media (prefers-reduced-motion:reduce){.tour-hole{transition:none}}

/* The footer sits outside <main>, beside the header rather than inside the article.
   It was the last child of main.wrap, which meant the 62ch cap the prose pages put on
   their article caught the footer too and it stopped short of the masthead above it.
   Its own .wrap now takes the page width, the way the header's does. */
/* The rule goes on the block inside the wrap, not the wrap: .wrap carries 20px of
   inline padding, so a border on it would overhang the content above by 20px a side. */
footer .wrap > div{border-top:1px solid var(--rule); padding-block:28px 40px}
footer{font-size:13px; color:var(--dim)}
footer a{text-decoration:underline; text-underline-offset:2px}
@media (prefers-reduced-motion:no-preference){.q,.a,.script{transition:opacity .18s ease}}
