/* ==========================================================================
   newsletter.css — the subscription page. Loaded by newsletter.html and by
   nothing else; deleting that page, this sheet and js/newsletter.js removes
   the feature completely.

   WHAT THIS SHEET IS ALLOWED TO OWN. Almost nothing. The page is built out of
   components that already exist and are already reasoned about somewhere else:

     .brief-err / .brief-sent                          brief-form.css
     .btn / .btn-ghost / .btn-fill                      base.css
     .ins-mast / .ins-nav                               insights.css

   What is left, and the only thing declared below, is the shape of a form that
   reads as two steps rather than as a page of fields: the numbered step, the
   category grid, and the block that takes the address.

   WHAT THIS SHEET USED TO BE (client direction, 2026-08-31). Roughly twice
   this length, because the page asked three questions instead of one. Deleted
   with them: the market chip grid (02), the cadence pair and its drawn
   frequency rail (04), the whole preview panel — the specimen mail, the note
   grid, the empty-state recovery buttons, the overflow line (05) — and the
   pinned action bar with its summary tokens, its bar-height fitting and its
   hide-at-footer transform (06). Anything below that looks like a survivor of
   that page is one, and is noted where it sits.

   THE DISCIPLINE HUES ARE USED, AND THEY EARN IT. base.css's own rule for the
   --d-* set is that a second use has to make the mapping honestly rather than
   borrow the palette. Each cell in the grid IS one discipline — the same six,
   by the same names, from DISCIPLINES in data.js — so a reader who has seen
   the constellation on index reads this grid with no new vocabulary. The hue
   is a scrubbed wash on select, not a fill at rest: six saturated panels
   stacked in a grid would be the loudest thing on a page whose job is a form.
   ========================================================================== */


/* ==========================================================================
   01. The steps
   Two questions, each a <section> with its own heading, numbered. The numeral
   is the same device tools.css uses on .tl-step and for the same reason: it
   says how much is left, which is the single most useful thing a multi-part
   form can tell someone before they abandon it. Two steps is the floor at
   which numbering still earns its place — one would be a numeral counting
   itself.
   ========================================================================== */
.nl-step{padding:var(--sec-sm) 0}
/* The masthead already carries the page's top space, so the first step opens
   tighter than the rhythm below it. */
.nl-step:first-of-type{padding-top:var(--s10)}

.nl-step-h{display:flex;align-items:baseline;gap:var(--s4);margin:0}
.nl-num{
  flex:none;
  color:var(--purple-deep);font-size:15px;line-height:23px;font-weight:600;
  font-variant-numeric:tabular-nums;letter-spacing:.04em;
}
.nl-hint{
  margin:var(--s3) 0 0;
  color:var(--gray);font-size:15px;line-height:23px;max-width:62ch;
}

/* A heading and the line that answers it, on one baseline. The old preview
   panel introduced this row for its live match count; it survives here because
   the selected count is the same kind of thing — a number that changes without
   the focus moving, sitting where the reader is already looking. */
.nl-step-top{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:var(--s3)}
/* Tabular figures so the count does not shuffle its neighbours every time a
   card is clicked. It is announced; see aria-live in the markup.

   IT SITS BESIDE THE HEADING, NOT AT THE FAR EDGE, and the auto margin is what
   does it. .nl-step-top is space-between, which is right for the terms block
   below - a 450px caption at the opposite end reads as a note on the whole
   section - and wrong here: this is a 210px fragment, and space-between left it
   826px from the words it belongs to on a 1440 screen. A live number that far
   from its own heading reads as an unrelated thing at the edge of the page.

   AN AUTO MARGIN RATHER THAN A SECOND CLASS. In a flex row, auto margins absorb
   the free space before justify-content is applied, so this one pulls the count
   back against the heading while .nl-step-top keeps one definition and the
   terms block keeps the behaviour that suits it. The rule lives on the element
   that differs, which is the count. */
.nl-count{
  margin:0 auto 0 var(--s2);
  color:var(--purple-deep);font-size:15px;line-height:23px;font-weight:500;
  font-variant-numeric:tabular-nums;
}

/* A real <fieldset> and a real <legend>, stripped. The grouping is what tells a
   screen reader that six checkboxes are one question; the border and the
   inline-shrink-to-fit legend are the two pieces of UA chrome that have to go
   before it can be laid out. */
.nl-fs{border:0;padding:0;margin:0;min-width:0}
.nl-fs legend{padding:0;width:100%}

/* An anchor landing under a heading rather than flush against the viewport
   edge. There is no fixed bar to clear any more — the offset is now only the
   ordinary breathing room a jumped-to heading wants. */
.nl-step{scroll-margin-top:var(--s8)}


/* ==========================================================================
   02. The categories
   Nine cells: the six disciplines in the order the constellation draws them,
   then the three cross-cutting editions. See newsletter.html for why the last
   three are not disciplines, and base.css for why they carry --e-* hues of
   their own rather than three more --d-*.

   THE WHOLE CELL IS THE LABEL. It was a <div> wrapping a label until the "see
   what is filed here" link was removed on 2026-08-31: an anchor cannot sit
   inside a <label>, so the cell had to hold the ground while the label held
   only the text above the link, and the selected wash had to be reached with
   :has() because a sibling selector could not climb back out to the wrapper.
   The link is gone and so is all of that. One element, one sibling selector, no
   :has() dependency, and the whole card is one hit target again.

   THE TYPE PAIR IS THE SAME ONE THE TERMS BLOCK USES, and that is a correction
   rather than a coincidence. These cards were 16/600 over 14/400 while the
   terms pills below them were 17/600 over 15/400 - so the page's PRIMARY
   CONTROL was set smaller than its own fine print. Two card type pairs on one
   page is drift whichever way round it is; matched, and with the icon, the
   colour and the position doing the rest, the categories read as the more
   important of the two without needing a bigger number.
   ========================================================================== */
/* THREE ACROSS, WHICH IS NOW THREE ROWS OF THREE. It was six in two rows until
   the watchlist, the tools and the network were added on 2026-08-31; the track
   count did not have to change, which is the useful property of picking a
   column count rather than dividing by the number of things. */
.nl-cats{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  /* --s4, not --s3. The cells carry a 24px radius, and a 12px gutter is half a
     radius: the curves of two neighbours nearly meet and the row reads as one
     ribbed surface rather than as six cards. */
  gap:var(--s4);margin-top:var(--s6);
}
@media (max-width:1000px){.nl-cats{grid-template-columns:repeat(2,minmax(0,1fr))}}

.nl-cat{position:relative;display:block}
/* Painted out rather than hidden: display:none would take it out of the tab
   order and off the accessibility tree. It stays a real checkbox, covering its
   own label, and every state below is driven from it. */
.nl-cat input{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:pointer}

.nl-cat-body{
  display:block;height:100%;
  /* Even on all four sides, which it was not: 20px top and 12px bottom was the
     asymmetry the removed link needed, and with the link gone it read as a card
     whose contents had slipped upwards. --s7 rather than --s6 because these are
     440px wide at full size and 24px of padding on that measure is tight. */
  padding:var(--s7);
  border-radius:var(--r-lg);
  background:var(--haze);
  transition:background-color 200ms ease-in-out;
}
.nl-cat input:hover + .nl-cat-body{background:var(--mist)}
/* The discipline's own colour, scrubbed to a wash. --hue is set per cell in the
   markup from the --d-*-rgb triples, which is the reason those triples are
   unpacked in base.css at all: one declaration here covers all six. */
.nl-cat input:checked + .nl-cat-body{background:rgb(var(--hue,144 79 255) / .18)}
.nl-cat input:focus-visible + .nl-cat-body{outline:var(--focus-w) solid var(--focus-c);outline-offset:var(--focus-off)}

/* THE MARK. See the head comment in newsletter.html for why this site now has
   content icons at all and what the set is allowed to be; what is here is only
   how it is drawn.

   NOT A NEW STROKE SPEC. 1.75 with round caps and joins on no fill is what
   base.css already declares three times over for every other icon on the site,
   and a 1.75 stroke on a 24 grid rendered at 24px is the same optical weight as
   the 1.75 on a 16 grid rendered at 16px in the header and the filter bar. The
   grid is bigger because a card has room a caret does not; the line is not.

   IT CARRIES THE DISCIPLINE'S OWN HUE AT REST, which is the one thing on the
   cell that does. Until now the --d-* colour appeared only once a card was
   ticked, so six categories sat in identical grey until the reader committed to
   one. A 24px mark is not a panel - the warning in this sheet's head comment is
   about six saturated FILLS - and at 1.75px on --haze it gives the grid a key
   without becoming the loudest thing on a page whose job is a form. */
.nl-cat-i{
  /* --s4 below it, not --s3. At 12px the mark sat on the name; the icon is a
     separate register from the type and needs to read as one. */
  display:block;width:24px;height:24px;margin-bottom:var(--s4);
  fill:none;stroke:currentColor;stroke-width:1.75;
  stroke-linecap:round;stroke-linejoin:round;
  color:rgb(var(--hue,144 79 255));
  transition:color 200ms ease-in-out;
}
/* Selected, the wash under the card is already that hue at 18%, so a mark in
   the same colour would be reading against itself. It goes to --plum with the
   name, which is the pairing the rest of the page uses for a chosen thing. */
.nl-cat input:checked + .nl-cat-body .nl-cat-i{color:var(--plum)}

.nl-cat-n{
  display:block;
  color:var(--slate);font-size:17px;line-height:25px;font-weight:600;letter-spacing:-.01em;
}
.nl-cat-d{
  /* --s2 held the description against the name at two sizes that were only 2px
     apart. At the corrected pair the gap can do its half of the separating. */
  display:block;margin-top:var(--s3);
  color:var(--gray);font-size:15px;line-height:23px;
}
.nl-cat input:checked + .nl-cat-body .nl-cat-n{color:var(--plum)}


/* ==========================================================================
   03. The address
   ONE FIELD, IN THE PAGE, and the reasoning for that is in newsletter.html:
   this used to be a pinned bar closing a 2,389px gap between the first tick
   and the button, and deleting two of the three questions deleted the gap.

   A FILLED PANEL, NOT A BARE ROW. It is the second of two steps and it has to
   read as a step, not as a footer that happened to land there. --haze is the
   same surface the category cells and the terms pills use, so the page is made
   of one material throughout.
   ========================================================================== */
.nl-sub .wrap{padding-bottom:var(--s4)}

.nl-sub-box{
  /* Even --s8 on all four sides. It was 28 top and bottom against 32 left and
     right, which is a difference too small to read as intentional and just
     enough to make the box look settled a little low in its own frame. */
  margin-top:var(--s5);padding:var(--s8);
  border-radius:var(--r-lg);background:var(--haze);
  max-width:44rem;
}

/* OUT OF THE BOX AND INTO THE HEADING'S SUB-LINE SLOT, which is step 01's
   .nl-hint position. It takes .nl-hint's exact type - 15/23 --gray, --s3 under
   the heading - because the slot has to mean one thing on both steps: a line
   saying what this step is about, before the control that does it. Two
   different sizes in the same position on two consecutive steps would be the
   page describing its own structure inconsistently.

   THE EMPHASIS MOVED TO THE <b>, WHICH IS WHERE IT BELONGS. It was carrying
   17/26 --slate to lead the panel it used to sit inside; the part that actually
   needs to be read at a glance is the list of categories, not "You get". */
.nl-sum{
  margin:var(--s3) 0 0;
  color:var(--gray);font-size:15px;line-height:23px;max-width:62ch;
}
.nl-sum b{font-weight:600;color:var(--plum)}

.nl-sub-row{display:block}
/* ABOVE THE FIELD, which is the arrangement the pinned bar could not have: a
   single row has no above. brief-form.css sets its labels the same way, in the
   same case and weight, so the two forms on this site read as one system. */
.nl-sub-row label{
  display:block;margin-bottom:var(--s2);
  font-size:12px;line-height:16px;font-weight:600;
  letter-spacing:.08em;text-transform:uppercase;color:var(--ash);
}
.nl-sub-act{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s3)}

/* --r-pill, NOT the --r-sm every other input on this site uses, and the
   difference is a rule rather than an exception: radius follows the row a
   control sits in. brief-form's fields are stacked in a column with the pill
   button BELOW them, so 4px against 24px never meet. This is the only place on
   the site where a field and a pill share a row at the same height, and a 4px
   field butted against a 24px button reads as two components from two systems.

   THE HEIGHT IS MEASURED, NOT ASSUMED. .btn is 12px padding on line-height
   normal and lands at 43px. box-sizing is border-box site-wide, so fixing the
   field at the same number also holds the row still when the invalid state
   thickens the border to 2px. */
.nl-sub-act input{
  flex:1 1 18rem;min-width:0;height:43px;
  padding:0 var(--s5);
  border:1px solid var(--line);border-radius:var(--r-pill);
  background:var(--white);
  color:var(--slate);font-family:var(--font);font-size:16px;line-height:24px;
  /* 16px is the floor that stops iOS Safari zooming the viewport on focus — the
     same reason brief-form.css gives for the same value. */
}
.nl-sub-act input::placeholder{color:var(--ash)}
.nl-sub-act input:focus-visible{
  outline:var(--focus-w) solid var(--focus-c);outline-offset:var(--focus-in);border-color:var(--focus-c);
}
/* Never colour alone: the invalid state carries a border, and the message in
   .nl-sub-err names what is wrong in words. */
.nl-sub-act input[aria-invalid="true"]{border-color:var(--red);border-width:2px}
.nl-sub-act .btn{flex:none;white-space:nowrap}

/* UNDER the row rather than replacing part of it, so the field it refers to
   does not move while it is being read. */
.nl-sub-err{margin:var(--s4) 0 0}

/* RED (client direction, 2026-08-31), on the --red-bg / --red-ink / --red set
   now declared in base.css. It was --pale purple, on the argument that picking
   nothing is a legal subscription and red would be accusing somebody of a
   mistake they had not made. Overruled, and the reason given was the better
   one: a panel that stops a submission has to read as a stop, and the purple
   did not.

   SO THE TWO STATES ARE SEPARATED BY SHAPE INSTEAD OF BY HUE. .brief-err four
   lines above is the same red and means something different - what you typed
   cannot be used - and the pair appear one after the other, not together, since
   the email is validated first. Left as identical panels the reader would learn
   that both are their fault, and the second one is not. So: .brief-err stays a
   compact --r-sm strip with one line of 15px. This is a padded --r-md block
   with a heading over a paragraph and a control under it. Same colour, two
   clearly different objects, and the words carry the rest.

   NO LEFT RULE (client direction, 2026-08-31). It carried the urgency while the
   panel was --pale purple and had to work without the colour; on --red-bg the
   surface does that job on its own and the rule was a second voice saying the
   same thing. THE RADIUS WENT BACK TO ONE VALUE WITH IT - the --r-sm/--r-md
   split existed only so the rule read as attached to the panel rather than
   drawn beside it, and with no rule there is nothing for a square corner to
   attach to. */
.nl-confirm{
  margin:var(--s4) 0 0;padding:var(--s5) var(--s6);
  border-radius:var(--r-md);
  background:var(--red-bg);
  color:var(--red-ink);font-size:15px;line-height:23px;
}
.nl-confirm p{margin:0}
/* Its own line, not a bold clause inside the sentence. The stop is one fact -
   nothing is picked - and the consequence is the sentence under it. */
.nl-confirm b{
  display:block;margin-bottom:var(--s1);
  font-size:16px;line-height:24px;font-weight:600;
}
/* .btn-ghost is the site's text-only action, so the way back is not a new
   component. It takes the panel's ink rather than the button's purple: a purple
   link inside a red block reads as belonging to the page behind it. */
.nl-confirm-go{margin-top:var(--s3);padding-top:6px;padding-bottom:6px;color:var(--red-ink)}
.nl-confirm-go:hover,.nl-confirm-go:focus-visible{color:var(--red)}

/* THE FINE PRINT IS RULED OFF, which is the same device the terms cards use
   under their headings and .pcard-foot uses above its byline. Without it the
   note floated the same distance below the field as the field sat below its
   label, so a legal footnote read as a third step in the form. */
.nl-sub-note{
  margin:var(--s6) 0 0;padding-top:var(--s5);
  border-top:1px solid var(--line);
  color:var(--ash);font-size:14px;line-height:22px;
}

/* The confirmation replaces the box, so it takes the box's own footprint. */
.nl-sub .brief-sent{margin-top:var(--s6);max-width:44rem}


/* ==========================================================================
   04. The terms
   Four things a reader settles before typing an address, in full on the page
   rather than behind a control.

   NO ICONS, AND THAT IS A SYSTEMS DECISION RATHER THAN A TASTE ONE. This site
   has no content iconography anywhere — every SVG on the other twelve pages is
   functional UI, and not one card, list or section is illustrated. Four icons
   here would be a vocabulary invented for the smallest block on one page, and
   the particular four this block would want are the stock trust badges every
   mailing-list page already has.
   ========================================================================== */
.nl-terms{background:var(--offwhite)}
.nl-terms .wrap{padding-top:var(--sec-sm);padding-bottom:var(--sec-sm)}
/* Borrows .nl-step-top's row rather than declaring a second one. The note is
   NOT --purple-deep like the count in step 01: that colour is carrying live
   data up there, and reusing it on a fixed sentence would spend the page's one
   attention colour on something that never changes. --ash instead. */
.nl-terms-note{margin:0;color:var(--ash);font-size:15px;line-height:23px}

/* The GRID ITEM IS THE PAIR, not the term and the definition separately. A
   <dl> laid out as a grid puts every dt and every dd in its own cell, so four
   terms and four definitions ran across the columns in reading order and no
   definition sat under the term it belonged to. Each pair is wrapped in a div,
   which is what the spec allows a <dl> to contain for exactly this. */
.nl-terms-list{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));
  gap:var(--s3);margin:var(--s6) 0 0;
}
.nl-terms-list > div{
  padding:var(--s6);
  border-radius:var(--r-lg);
  background:var(--haze);
}
/* 17px against the 15px below it. At the same size as its own definition the
   term was not a heading, it was the first sentence of a paragraph — which is
   what left this block with nothing to scan.

   THE HAIRLINE IS WHY THIS IS NOT AN ICON. Four cards carrying two type styles
   and one flat fill read as a texture rather than four facts, which is the
   thing an icon was being asked to fix. The rule is the site's own device — the
   same 1px --line under .pcard-foot on every note card — so it gives each card
   the structure it was missing in a language the page already speaks. */
.nl-terms-list dt{
  color:var(--slate);font-size:17px;line-height:25px;font-weight:600;letter-spacing:-.01em;
  padding-bottom:var(--s3);border-bottom:1px solid var(--line);
}
.nl-terms-list dd{margin:var(--s3) 0 0;color:var(--gray);font-size:15px;line-height:23px}


/* ==========================================================================
   05. Responsive
   ========================================================================== */
@media (max-width:680px){
  .nl-sub-box{padding:var(--s6)}
  /* The button drops under the field rather than squeezing beside it: below
     this width a 18rem floor and a "Send me these notes" button cannot both sit
     in one row without the field falling under 20ch. */
  .nl-sub-act input{flex:1 1 100%}
  .nl-sub-act .btn{width:100%;text-align:center}
}

@media (max-width:640px){
  .nl-step-h{gap:var(--s3)}
  .nl-cats{grid-template-columns:1fr}
  /* One column means full-measure cards, where 28px of side padding starts
     eating the line length rather than framing it. */
  .nl-cat-body{padding:var(--s6)}
  .nl-step-top{flex-direction:column;gap:var(--s2)}
}


/* ==========================================================================
   06. Reduced motion
   The colour transitions are left alone, which is what base.css does for the
   same kind of state: they answer a click or a hover, and removing them would
   make the interaction feel unregistered rather than calmer. Nothing on this
   page moves in space any more — the one transform was the pinned bar sliding
   away at the footer, and the bar is gone — so there is nothing left here to
   switch off.
   ========================================================================== */
