/*
 * Nuclear Resister — WordPress body-content styles (.nr-wp-content)
 * ===========================================================================
 *
 * THE ONE COPY of the editorial rules applied to WordPress `content.rendered`
 * HTML. Both templates that render a WP body link this file:
 *
 *   src/pages/[...slug].astro                    — interior pages
 *   src/pages/[year]/[month]/[day]/[slug].astro  — single posts
 *
 * Typography: Verdana throughout (device fonts, no webfonts). 16px floor,
 * non-negotiable. Navy links → Rust on hover/focus. Chronicle, not brochure.
 *
 * ---------------------------------------------------------------------------
 * WHY public/ AND NOT src/styles/
 * ---------------------------------------------------------------------------
 * These rules used to live in an Astro-scoped <style> block inside EACH of the
 * two templates. Astro scopes per component, so a rule in one template never
 * reaches the other — every shared rule had to be written twice and kept in
 * sync by hand — and it compiled the selectors to
 * `.nr-wp-content[data-astro-cid-<hash>] p`, where the hash changes whenever
 * the component changes.
 *
 * The Lowthian Editor's style bridge fetches the front end's content CSS and
 * injects it into the WordPress block-editor canvas, so what the client sees
 * while editing is what the visitor gets. That needs (a) a stable URL and
 * (b) selectors with no build hash in them. public/ is copied to dist/
 * verbatim, so this file is served at exactly /wp-content.css.
 *
 * Load ORDER for any consumer, including the bridge:
 *     /tokens.css   then   /wp-content.css
 * Every value below is a var(--nr-*); without the tokens file this stylesheet
 * renders as unstyled text. Do not inline a :root block here to avoid that —
 * the palette has one home (public/tokens.css) and this file is not it.
 *
 * ---------------------------------------------------------------------------
 * WHY EVERY SELECTOR IS `.nr-wp-content[class]` AND NOT `.nr-wp-content`
 * ---------------------------------------------------------------------------
 * `[class]` matches any element carrying a class attribute — which every
 * `.nr-wp-content` does by definition — so it selects exactly the same
 * elements. It is here for SPECIFICITY, and it is load-bearing.
 *
 * Astro's scoped output was `.nr-wp-content[data-astro-cid-x] p` = (0,2,1).
 * Written plainly, `.nr-wp-content p` is (0,1,1) — one class lighter. That
 * single step down is enough to lose a fight these rules currently win:
 * src/styles/global.css carries `.nr-wp-content .wp-caption-text` at (0,2,0),
 * which would then beat the `p` and `figcaption` rules below and change every
 * caption's margins on 1,282 pages carrying a wp-caption. `[class]` restores
 * the exact (0,2,x) the scoped selectors had, so the cascade lands where it
 * landed before the extraction. Measured, not assumed — the before/after
 * computed-style diff is what found it.
 *
 * If you add a rule here, keep the `[class]`.
 *
 * ---------------------------------------------------------------------------
 * WHAT IS DELIBERATELY *NOT* IN THIS FILE
 * ---------------------------------------------------------------------------
 * The two templates were never identical, and the difference is a decision
 * somebody made, not drift. Rules that change how content LOOKS on interior
 * pages only — chiefly the 480px image cap, which is subject to an OPEN
 * decision of Geoffrey's about whether to apply it to the ~975 posts too —
 * stay in [...slug].astro as scoped overrides on top of this file. Rules that
 * only stop content from overflowing a narrow viewport are shared and live
 * here.
 *
 * That is the test when you add a rule:
 *   changes how content LOOKS         → interior-only, and check the parked
 *                                       image-cap decision first
 *   stops content overflowing a narrow
 *   viewport / is already in both      → here
 *   is a BOX or LAYOUT property on the
 *   .nr-wp-content WRAPPER itself      → never here, see that rule's comment
 *                                       (the editor canvas owns that box)
 *
 * That third line is a hard rule, not a judgement call: the style bridge
 * rewrites the wrapper rule onto the editor canvas body, where WordPress's
 * theme.json layout already sets the column width. Box properties on
 * DESCENDANTS (p margins, the img max-width, figure spacing) are fine and
 * belong here — they space content inside the column rather than redefining
 * the column.
 *
 * Interior-only overrides currently in [...slug].astro: the image cap
 * (480px/70vh/object-fit + the sizes="auto" definite width), the container
 * padding + flow-root, the <table> rules, and the empty-page placeholder.
 * Do not "unify" any of them into this file without checking back — that
 * would ship a design change under cover of a refactor.
 *
 * Also NOT here: WordPress's alignment classes and the grey caption box
 * (.alignleft/.alignright/.aligncenter/.alignnone/.wp-caption/.wp-caption-text
 * and the float clearfix). Those live in src/styles/global.css because
 * .nr-wp-content appears on FIVE surfaces — these two templates plus
 * contact-us.astro, FutureActionsList.astro and InteriorPageLayout.astro —
 * and WordPress core classes have to work on all of them. This file is linked
 * by the two body templates ONLY; linking it anywhere else changes how those
 * other three surfaces render.
 *
 * Revisions:
 *   2026-08-15  Created. Extracted verbatim from the two templates' scoped
 *               <style> blocks — no value changed. Zero visual change
 *               verified by computed-style + bounding-box + pixel diff across
 *               40 pages at two viewports (see PKM/lena-journal.md).
 * ===========================================================================
 */

/* Container.
 *
 * ===========================================================================
 * NO BOX OR LAYOUT PROPERTIES ON THIS RULE. EVER. Not max-width, margin,
 * padding, width, display, float or position. Typography, colour and
 * inherited properties only.
 * ===========================================================================
 * Two independent reasons, either one sufficient:
 *
 *   1. THE EDITOR CANVAS (Wade, 2026-08-15). The style bridge rewrites this
 *      wrapper rule onto the block editor's canvas BODY, and WordPress's
 *      theme.json layout already owns the column width there (1092/1140). A
 *      box property here constrains that canvas a second time and the
 *      editor's column stops matching the live one — which defeats the whole
 *      point of the client editing against the front end's own CSS.
 *
 *   2. THE TWO TEMPLATES DISAGREE ABOUT THE BOX ANYWAY. Interior pages put
 *      padding + display:flow-root on this div; posts take their padding from
 *      the .nr-post wrapper instead. Anything box-shaped put here would
 *      double it on every post.
 *
 * If the front end genuinely needs a box property on this wrapper, it goes in
 * the template as a scoped rule and gets raised with whoever owns the editor
 * bridge — it does not come here and it does not get silently dropped.
 * Currently scoped in [...slug].astro for exactly this reason:
 * `padding: var(--nr-space-8) 0 var(--nr-space-10)` and `display: flow-root`.
 *
 * overflow-wrap is fine and belongs here: it is an INHERITED text property,
 * not a box property, it constrains nothing about the column, and it is here
 * for a measured a11y reason —
 *
 * Two decades of pasted body copy contain strings with no soft wrap
 * opportunity — bare URLs printed as link text, and runs of &nbsp; from
 * Outlook-pasted copy. Either one sets a line box wider than a 320px viewport
 * and scrolls the whole page sideways. The rendered a11y gate measured this in
 * POSTS: one post's bare URL reached 458px against a 320px viewport, and an
 * Outlook &nbsp; run produced an 845px line box. overflow-wrap is INHERITED,
 * so declaring it on the container covers every descendant without repeating
 * it per element; break-word rather than anywhere, so ordinary words still
 * wrap at ordinary places and only an otherwise-unbreakable run gets split.
 * Added to both templates 2026-08-06 alongside the .wp-caption rule below —
 * same defect class. */
.nr-wp-content[class] {
  overflow-wrap: break-word;
}

/* Headings within WP content — h2 down to h6.
 * h1 is OUTSIDE this div: interior pages get theirs from InteriorPageLayout,
 * posts from .nr-post__title. WP body content starts at h2. */
.nr-wp-content[class] h2,
.nr-wp-content[class] h3,
.nr-wp-content[class] h4,
.nr-wp-content[class] h5,
.nr-wp-content[class] h6 {
  font-family: var(--nr-font-body);
  font-weight: var(--nr-weight-bold);
  color: var(--nr-news-headline);
  line-height: var(--nr-leading-headline);
  margin: var(--nr-space-8) 0 var(--nr-space-4);
}

.nr-wp-content[class] h2 {
  font-size: clamp(1.25rem, 2.5vw, 1.5rem); /* ≥20px */
}

.nr-wp-content[class] h3 {
  font-size: clamp(1.125rem, 2vw, 1.25rem); /* ≥18px */
}

.nr-wp-content[class] h4,
.nr-wp-content[class] h5,
.nr-wp-content[class] h6 {
  font-size: 1rem; /* 16px — at the floor */
}

/* Body text */
.nr-wp-content[class] p {
  font-family: var(--nr-font-body);
  font-size: var(--nr-text-body); /* 16px */
  line-height: var(--nr-leading-body);
  color: var(--nr-news-body);
  margin: 0 0 var(--nr-space-5);
}

/* Links — Navy default, Rust on hover/focus, underline always. */
.nr-wp-content[class] a {
  color: var(--nr-news-headline);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* text-decoration is restated here only because the interior template's copy
   restated it. It is the same value the base rule above already sets, so it
   changes nothing either way — kept so the two originals collapse to one file
   with no value dropped. */
.nr-wp-content[class] a:hover,
.nr-wp-content[class] a:focus {
  color: var(--nr-rust);
  text-decoration: underline;
}

/* Focus ring — WCAG 2.4.7 visible focus indicator. 3px Rust on white is
   5.14:1, past the 3:1 floor for a focus indicator. */
.nr-wp-content[class] a:focus-visible {
  outline: 3px solid var(--nr-rust);
  outline-offset: 2px;
  border-radius: 2px;
}

/* Lists */
.nr-wp-content[class] ul,
.nr-wp-content[class] ol {
  font-family: var(--nr-font-body);
  font-size: var(--nr-text-body);
  color: var(--nr-news-body);
  line-height: var(--nr-leading-body);
  margin: 0 0 var(--nr-space-5);
  padding-left: var(--nr-space-8);
}

.nr-wp-content[class] li {
  margin-bottom: var(--nr-space-2);
}

/* Images — the SHARED baseline: fit the column, keep the aspect ratio, centre
 * a standalone photo. This is the post template's rule, which is the
 * uncapped behaviour every .nr-wp-content surface had before 2026-08-06.
 * [...slug].astro overrides max-width/max-height/object-fit on top of it for
 * interior pages only; that cap is a parked decision (see this file's header
 * and the img block in that template).
 *
 * :not([class*="align"]) is load-bearing, not tidiness. This selector is
 * (0,2,1) and outranks the (0,2,0) alignment rules in global.css, so without
 * the exclusion the `margin: ... auto` below silently zeroes the float gutter
 * and body text sits flush against the photo. 622 bare <img class="alignleft">
 * in the built site hit this. Alignment margins are global.css's job. */
.nr-wp-content[class] img:not([class*='align']) {
  max-width: 100%;
  height: auto;
  display: block;
  margin: var(--nr-space-6) auto;
}

.nr-wp-content[class] img[class*='align'] {
  max-width: 100%;
  height: auto;
}

/* Same exclusion, same reason — 1,178 aligned <figure> elements. */
.nr-wp-content[class] figure:not([class*='align']) {
  margin: var(--nr-space-6) 0;
}

/* WP caption divs — WordPress writes a hard inline `style="width: 310px"` on
 * every one of them (1,173 of the 1,174 in the content snapshot carry an
 * inline width; 813 of those are the 310px case). Nothing overrode it, so 21
 * of 40 sampled POSTS scrolled horizontally at a 320px viewport. A stylesheet
 * max-width beats an inline width with no !important needed: inline style wins
 * on `width`, but `max-width` is a different property and clamps the used
 * value whatever set `width`.
 *
 * This rule was ALREADY mirrored into both templates on purpose, while the
 * image cap directly above deliberately was not. That was never an
 * inconsistency to tidy up: this one is pure overflow containment — no visual
 * size change above ~330px, wanted everywhere — whereas the cap changes how
 * big a photo LOOKS, which is the open decision. Its being shared is not
 * licence to share the cap. */
.nr-wp-content[class] .wp-caption {
  max-width: 100%;
}

.nr-wp-content[class] figcaption {
  font-family: var(--nr-font-body);
  font-size: var(--nr-text-body);
  color: var(--nr-news-date);
  text-align: center;
  margin-top: var(--nr-space-2);
}

/* Blockquotes */
.nr-wp-content[class] blockquote {
  border-left: 4px solid var(--nr-rust);
  margin: var(--nr-space-6) 0;
  padding: var(--nr-space-3) var(--nr-space-6);
  font-style: italic;
  color: var(--nr-news-body);
}

/* Horizontal rule */
.nr-wp-content[class] hr {
  border: none;
  border-top: 1px solid #ccc;
  margin: var(--nr-space-8) 0;
}
