/* =====================================================================
   LEGAL -- the paired sheet for templates/legal.php

   Story 4 of `_bmad-output/specs/spec-contact-page/SPEC.md` (CAP-6). The
   plainest stylesheet in this theme, and deliberately so: a centred prose
   measure, the rhythm a long document needs between its headings, lists
   and paragraphs, and nothing else. There is no component here, no
   layout, no breakpoint and no drawing behind it.

   WHAT THIS SHEET DOES NOT DECIDE. It declares no colour VALUE -- no hex
   literal appears below. Every colour on this page resolves from a role
   site-interactive-states.css already decided against the white ground:
   `--ground-ink` for body text, the four `--state-link-*` roles for the
   links. If one of those values is wrong it is wrong everywhere and is
   fixed there, once.

   THE COLUMN IS LIFTED FROM contact.css:120-128, which lifted it from
   simple-stack.css:255, and both halves of the reasoning come with it
   rather than being re-derived here. It is a deliberate third copy and
   not an extraction: the three sheets load on mutually exclusive pages,
   so a shared file would be a fourth stylesheet in every bundle to save
   six lines in each.

   THERE IS NO PAIRED SCRIPT. functions.php's emitter guards the `js` key
   with `! empty()`, and the `project` archive has shipped css-only since
   v1.11.16 -- so a missing script is a supported shape rather than the
   silently-dropped-handle failure a missing SHEET would be. A legal
   document has no behaviour; shipping an empty file to satisfy a pattern
   would be a file to maintain and a request to make for nothing.
   ===================================================================== */

/* =====================================================================
   THE COLUMN

   `min(760px, 100% - 2 * var(--band-gutter, 15px))` is this codebase's
   prose measure. 760px is the measure itself; the second term is the
   gutter, and the `min()` is which of the two is binding at this viewport.
   A Page with no template takes the full site band as its measure and sets
   policy text across all of it, which is exactly what makes this file
   necessary.

   IT CHANGED FORM AT v1.14.0 AND THE REASON IS THE WHOLE LESSON HERE.
   It was `max-width: min(760px, var(--container, 760px))` plus
   `padding: 64px 15px 96px`, which is the same thing ONLY WHILE THE GUTTER
   IS A CONSTANT. `--band-gutter` now ramps to 56px at 1400, and under the
   old form a border-box `max-width` of 760 with 56px of padding inside it
   left a 648px measure -- the gutter eating 15% of a reading column it was
   never sized against. The gutter belongs OUTSIDE a narrow measure and
   INSIDE a full-width band; `width: min(measure, 100% - 2 * gutter)` is
   how you say that in one declaration, and it needs no horizontal padding
   at all.

   WHAT IT COMPUTES TO, AND NOTE THE DESKTOP ROW IS A RESTORATION:

     viewport   gutter   column    was (v1.13.41)
      390px      20px     350px     345px   -- inset now matches the chrome
      600px      24px     552px     570px
     1400px      56px     760px     730px   -- the full drawn measure, at last

   THE `--container` TERM WAS DROPPED, NOT LOST. It was there so the column
   could never outgrow the chrome band above it. `100%` subsumes it: the
   chrome's content width is `min(viewport, --container) - 2g` and this
   column is `min(760, viewport - 2g)`, so the column is never the wider of
   the two at any viewport -- by construction now, rather than by a dial
   whose mobile tier (748px) happened to sit just below 760. One fewer
   database value this rule depends on.

   THE 15px INSIDE THE `var()` IS NOT DECORATION, and the failure it guards
   is the same one the old fallback guarded, one level out: an unresolved
   custom property inside `min()` makes the whole function invalid at
   computed-value time, which drops `width` back to `auto` -- the column
   would silently go full-bleed, which is the one failure this rule exists
   to prevent. With the fallback it degrades to a flat 15px inset, i.e. to
   what shipped through v1.13.41.

   `box-sizing: border-box` IS RETAINED AND IS NO LONGER LOAD-BEARING
   HORIZONTALLY -- there is no horizontal padding left for it to govern. It
   stays for the vertical padding and for the next person who adds a
   border, and because Neve sets it globally anyway; this rule simply no
   longer depends on that global for its measure.
   ===================================================================== */
.legal-page {
	width: min(760px, 100% - 2 * var(--band-gutter, 15px));
	margin: 0 auto;
	box-sizing: border-box;
	padding: 64px 0 96px;
	font-family: var(--font-body);
	color: var(--ground-ink);
}

/* =====================================================================
   RHYTHM

   A policy page is a document rather than a composition: its whole visual
   job is to be scannable down a single column, which is spacing and
   almost nothing else.

   NO `font-size` ON ANY HEADING, and the omission is load-bearing. Neve's
   typography theme_mods bind `--h1fontsize`/`--h2fontsize` and their
   letter-spacing from an inline <style> this repo does not declare --
   CLAUDE.md's typography entry records that every heading on this site has
   been inheriting that tracking without anyone deciding it, and that the
   way to get this wrong is to measure a heading in a template and assume
   the number is the theme's. So size, weight and tracking are left to Neve
   on purpose here, exactly as contact.css:126-132 leaves them, and only
   the space around them is this sheet's. Do not add one without measuring
   a bare element of the same tag on a live page first.
   ===================================================================== */
.legal-page__title {
	font-family: var(--font-heading);
	margin: 0 0 12px;
}

/* The lead paragraph reads one step larger than the body under it -- the
   same single step of hierarchy contact.css:148-152 gives its intro, and
   for the same reason: it is what separates the sentence that says what
   the document is from the document. `:first-of-type` rather than a class,
   because the copy lives in the page's `post_content` and is edited in
   wp-admin, where a class is a thing the editor has to remember and
   document order is not. */
.legal-page > p:first-of-type {
	font-size: 21px;
	line-height: 1.5;
	margin-bottom: 32px;
}

.legal-page h2 {
	font-family: var(--font-heading);
	margin: 48px 0 16px;
}

.legal-page h3 {
	font-family: var(--font-heading);
	margin: 32px 0 12px;
}

.legal-page p {
	font-size: 18px;
	line-height: 1.6;
	margin: 0 0 20px;
}

/* THE LIST RESET IS PARTIAL AND THAT IS DELIBERATE, which is the opposite
   of the call contact.css:177-187 makes for its breadcrumb. That one kills
   the marker outright, because a breadcrumb rendered as a bullet list is
   wrong. Here the markers are wanted -- an enumeration of what the form
   collects reads as a list and should look like one -- so this block sets
   only the measure-relative indent and the rhythm, and leaves Neve's
   marker alone.

   `padding-left` rather than `margin-left`: the marker hangs in the
   padding, so an indent set as margin moves the marker out past the
   column's own left edge on a narrow viewport. */
.legal-page ul,
.legal-page ol {
	margin: 0 0 20px;
	padding-left: 24px;
	font-size: 18px;
	line-height: 1.6;
}

.legal-page li {
	margin: 0 0 8px;
}

.legal-page > :last-child {
	margin-bottom: 0;
}

/* =====================================================================
   LINKS

   FOUR RULES HERE RATHER THAN NONE, AND THE REASON IS A MEASUREMENT.
   site-interactive-states.css:2085-2094 owns inline body-copy links
   through `body .nv-content-wrap.entry-content a`, and its own comment
   names About and Blog as the pages that rule exists for. THAT WRAPPER
   IS NOT ON THIS PAGE. Measured live 2026-09-25 against
   dev.joetennis.com: `nv-content-wrap` appears ZERO times on /contact/
   and zero times on /about/, because a custom Page template replaces
   the markup Neve would have emitted around `the_content()`. So on a
   templated Page that group matches nothing, and an unowned anchor
   falls to Neve's own `a:hover, a:focus`, which tints to
   `--nv-secondary-accent` -- the `#2f5aae` blue CLAUDE.md records as a
   palette slot nobody decided, and which was already caught washing the
   About tab bar at v1.13.11.

   This is the "first element of type X on this page" hazard in its
   quieter form: not a new element, but an existing rule whose selector
   silently does not reach here. contact.css:210-247 made exactly this
   discovery first and carries exactly these four rules for it; this is
   the second page to need them and the pair is now the precedent rather
   than the exception. If a third arrives, promote the group by adding
   the roots to the selector list in site-interactive-states.css rather
   than making a third copy.

   NO VALUE IS RESTATED. All four rules read `--state-link-*` roles
   decided against the white ground in site-interactive-states.css:357-360
   and nothing below picks a colour.

   `:not(.button)` keeps a "Get in touch" CTA dropped into this page's
   content on the sitewide button rules rather than pulling it down to
   link ink -- the same guard the states sheet's own prose-link group
   carries, and the same reason.
   ===================================================================== */
.legal-page a:not(.button) {
	color: var(--state-link-rest-fg);
	border-radius: var(--shape-link-radius);
	font-weight: 400;
	text-decoration: none;
	--linkdeco: none; /* Neve renders `text-decoration: var(--linkdeco)`. */
}

/* THE REST STATE CARRIES NO UNDERLINE, so WCAG 1.4.1 falls back to colour
   alone -- and the comparison it makes is against the SURROUNDING BODY
   TEXT, not the page.

   THAT COMPARISON DOES NOT CURRENTLY PASS, AND THIS SHEET IS NOT THE PLACE
   IT IS FIXED. `--state-link-rest-fg` (#0b6b78) measures **2.85:1** against
   `--ground-ink` (#16191d), under the 3:1 floor.
   site-interactive-states.css:2084 states 3.39:1 and calls the white ground
   "already passed"; 3.39:1 is #0b6b78 against pure BLACK, not against this
   site's body ink. The dark ground beside it was properly re-derived
   (#0f8c9d, 3.24:1); the white one was assumed.

   NOTHING IS CHANGED HERE ON THAT ACCOUNT, deliberately, and the reason is
   that the DERIVATION is what is wrong rather than this page. Underlining
   `.legal-page` links at rest would close the cases on this page and leave
   the bad figure in that sheet for the next white-ground page to inherit --
   one page looking fine standing in for a sheet that is wrong.

   THE POPULATION IS SMALL AND IT IS WORTH KNOWING HOW SMALL, because the
   sitewide-sounding version of this note would overstate it. Counted live
   2026-09-25, prose links inside <main> on every white-ground page: /about/
   has none, /contact/ has two, and this page has four. The ones that
   actually fail 1.4.1's test are the MID-SENTENCE ones here -- a link that
   is its own paragraph has no surrounding text to be compared against --
   and one of those is the address a visitor uses to ask for their message
   to be deleted.

   deferred-work.md carries this with three candidate fixes, one of which is
   the narrow `.legal-page` underline. It is Joe's to look at, because its
   cost is visible rather than technical: it would make this page's links
   look different from /contact/'s two, on adjacent pages. This comment
   exists so the next person reading it does not re-derive "3.39:1, fine"
   from the sheet that says so.

   The hover underline below is therefore carrying more weight than it was
   designed to: it is the second channel, and at present it is the only one
   that clears anything. */
.legal-page a:not(.button):hover {
	color: var(--state-link-hover-fg);
	text-decoration: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 2px;
	--linkdeco: underline;
}

.legal-page a:not(.button):focus-visible {
	color: var(--state-link-focus-fg);
	text-decoration: underline;
	--linkdeco: underline;
	outline: 2px solid var(--state-link-focus-ring);
	outline-offset: 2px;
}

/* An address is not a sentence and must not be broken like one. A long
   `mailto:` label wrapping mid-address reads as two addresses; on a narrow
   viewport `overflow-wrap: anywhere` is the escape hatch that keeps it
   from overflowing the column instead. Same rule, same reason, as
   contact.css:253-255. */
.legal-page a[href^="mailto:"] {
	overflow-wrap: anywhere;
}
