/* =====================================================================
   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;
	/* THE REST UNDERLINE IS READ, NOT RESTATED, since 2026-10-03. This
	   rule hard-coded `none` on both properties until then, which meant
	   this page could not be fixed by moving the ground role -- see
	   site-interactive-states.css's block on
	   --state-link-rest-decoration. Do not put a literal back here. */
	text-decoration: var(--state-link-rest-decoration);
	--linkdeco: var(--state-link-rest-decoration); /* Neve renders `text-decoration: var(--linkdeco)`. */
	/* Stated at rest so hovering changes the underline's THICKNESS only
	   (auto -> 2px) rather than also shifting its position. */
	text-underline-offset: 2px;
}

/* THE REST STATE NOW CARRIES AN UNDERLINE, FIXED 2026-10-03 BY JOE, and
   this block is kept rather than deleted because it is the record of a
   figure that was wrong in the shared sheet for four months.

   WHAT WAS WRONG. With a bare rest state, WCAG 1.4.1 falls back to colour
   alone and compares against the SURROUNDING BODY TEXT rather than the
   page. `--state-link-rest-fg` (#0b6b78) measures **2.85:1** against
   `--ground-ink` (#16191d), under the 3:1 floor.
   site-interactive-states.css said 3.39:1 and called the white ground
   "already passed" -- but 3.39:1 is that teal against pure BLACK, not
   against this site's body ink. The dark ground beside it had been
   properly re-derived; the white one was assumed and carried forward, so
   the sheet told every reader it passed. (Line number dropped
   deliberately -- it had already drifted once. Grep the sheet for 3.39.)

   HOW IT WAS FIXED, AND WHY THE INK DID NOT MOVE. #0b6b78 against the
   #ffffff page was never in doubt at 6.20:1; the only failing comparison
   was the colour-only one against prose, and that comparison applies ONLY
   while the rest state is bare. Restoring the underline supplies the
   non-colour carrier 1.4.1 actually asks for, so the ink floor stops
   applying and the teal stays. The dark ground had taken the same move one
   day earlier for the opposite ink (#ffffff, 1.23:1 against its prose).

   THE FIX WAS NOT APPLIED HERE. It is one value on the ground role,
   `--state-link-rest-decoration`, and this sheet now READS it -- the rest
   rule above used to hard-code `none`, which is why moving the role alone
   would have underlined every white-ground page except this one and
   /contact/, the only two that had the problem. Do not restate the
   literal.

   WHAT THE OBJECTION TO FIXING IT USED TO BE, recorded because it was a
   real cost and it was accepted rather than refuted: a narrow
   `.legal-page` underline would have made this page's links look
   different from /contact/'s two on an adjacent page. Moving the ground
   role instead costs nothing of the kind -- both pages changed together,
   and so did every other white-ground page.

   THE POPULATION, counted live 2026-10-03, prose links inside <main> on
   every white-ground page: /about/ has none, /contact/ has two, this page
   has four. Five of the six are MID-SENTENCE, which is where the test
   actually bites -- a link that is its own paragraph has no surrounding
   text to be compared against. The sharpest case was here:

     "If you would like your message deleted, email
      contact2026@joetennis.com and ask."

   the address a visitor uses to ask for their message to be deleted.

   THE HOVER UNDERLINE IS NO LONGER CARRYING THIS ALONE, which is the
   practical change. Rest has colour plus an underline; hover moves BOTH
   the colour (to #000000) and the thickness (auto -> 2px). */
.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;
}
