/* =====================================================================
   JOIN FORM
   =====================================================================

   THE FIELD BOUNDARY IS THE BORDER'S JOB AND THE FILL CANNOT TAKE IT
   OVER. Measured: the white field fill reaches only 1.0600 against the
   page ground, so it carries no boundary at all. The --ink border
   measures 13.9920 against the same ground, against the 3:1 a UI
   component boundary needs. SOFTENING THE BORDER RE-BREAKS IT.

   THE SUBMIT IS FILLED --ground-fill WITH --ground-page TEXT, 13.9920.
   DO NOT REUSE .btn HERE: filled --pill with white text measures 4.1669
   against a 4.5 threshold and fails. That was measured on this design,
   not assumed from another. .btn.ghost also clears at 13.9920 and stays
   available.

   outline-offset IS LEGIBILITY, NOT A CONTRAST REQUIREMENT — stated
   precisely so the next reader is not misled in either direction.
   Measured both adjacencies: the ring reaches 3.9310 against the section
   ground and 3.5594 against the adjacent border, so it clears 3:1 WITH
   OR WITHOUT the offset. What the 2px buys is a paper gap between two
   dark edges that would otherwise read as one thick border. Removing it
   costs legibility, not compliance.
   ===================================================================== */

/* =====================================================================
   THE FORM BAND — renders inside <footer> on every page
   =====================================================================

   .jband REPLACES .close, WHICH LIVED IN css/pages/home.css. A shared
   partial cannot depend on a page-scoped stylesheet: utilities.html does
   not load home.css, so the section would have rendered unstyled there.
   Everything this component needs is now in this file.

   IT MUST RESET font-size AND color. footer{} sets 13px and
   --on-page-muted for the footer's own small print; without this reset
   the form's heading and copy inherit both, and the h2 — which has no
   colour of its own — would render at the muted value against --paper.
   Tokens only; no literal is introduced.

   HORIZONTAL PADDING IS 34px, MATCHING EVERY OTHER SECTION. It was
   zeroed while this band lived inside <footer>, which supplied its own
   34px; out of the footer there is no padding anywhere and the form ran
   edge to edge. Measured before this was corrected: the copy and form
   columns were 320px wide in a 320px viewport, i.e. full bleed with the
   text against both screen edges, and 1180px inside a 1199px viewport. */
.jband{
  padding-left:34px;padding-right:34px;
  padding-top:76px;padding-bottom:56px;
  font-size:16.5px;
  color:var(--on-page);
}
.jband .in{max-width:1180px;margin:0 auto}

/* TWO COLUMNS ABOVE 920px, ONE AT 920 AND BELOW. 920 is the breakpoint
   .pivot .in and .hero .in already switch at — no new breakpoint is
   introduced. The two-column form is the BASE and the stack is the
   override, matching the shape those two rules already use. */
.jcols{display:flex;gap:5vw;align-items:flex-start}
.jcol-copy{flex:1 1 0;min-width:0}
.jcol-form{flex:1 1 0;min-width:0}
@media(max-width:920px){
  /* align-items:stretch is REQUIRED here, not cosmetic. The base rule sets
     flex-start, which in a COLUMN container is a cross-axis (horizontal)
     alignment — the children then size to their content instead of the
     column. Measured without it: the form column rendered 412px inside an
     852px container at 920, and 392px inside 492px at 560, leaving dead
     space to the right and making the form NARROWER stacked than it was
     before the move. */
  .jcols{flex-direction:column;gap:0;align-items:stretch}
}

.jform{margin-top:30px;max-width:680px;text-align:left}
.jf-legend{font-size:13px;color:var(--on-page-body);margin-bottom:4px}
.jf-req{color:var(--on-page)}

.jrow{display:flex;gap:20px;flex-wrap:wrap}
.jf{flex:1 1 260px;margin-top:18px;display:flex;flex-direction:column}
.jf-wide{flex-basis:100%}
.jf label{
  font-family:var(--mono);font-size:9.5px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--on-page);margin-bottom:7px;
}
.jf input,.jf select,.jf textarea{
  font-family:var(--sans);font-size:15.5px;
  color:var(--on-field);
  background:var(--ground-field);
  border:1.5px solid var(--on-page);
  border-radius:6px;padding:11px 13px;width:100%;
}
.jf textarea{min-height:104px;resize:vertical}

/* THE FOCUS INDICATOR ALREADY HAS TWO GROUNDS, AND THAT IS THE HARDEST
   CONSTRAINT IN THE PALETTE. The same outline lands on the white field
   fill when a field is focused (4.1669) and on the submit's dark fill
   when the button is focused (3.5594) — two answers 0.6 apart, both
   against a 3.0 threshold, plus 3.9310 against the page ground.

   ANY VALUE PROPOSED FOR --focus MUST SATISFY ALL THREE. That is harder
   than any single text element faces: a text element sits on one ground
   and an indicator travels. AN INDICATOR IS NOT A COLOUR-STUDY SURFACE —
   this is why --focus is its own token and why a name-keyed palette swap
   must never be allowed to recolour it as a side effect. */
/* EXTENDED TO a ELEMENTS 2026-08-07. Links previously fell back to the
   UA default ring, Chrome's 1px #005FCC — measured 1.4363 against a .btn's
   own --pill fill and 2.4782 for a .cta-line on the plum band, both below
   3:1, and both a colour we do not control and that differs per browser.
   The authored ring already clears 3:1 against every ground it touches
   (4.1669 on the white field fill, 3.5594 on the submit's ink fill,
   3.9310 on the page ground). Width, colour and offset are unchanged.

   :focus-visible ONLY, never :focus — a plain :focus would put the ring on
   every mouse click as well as keyboard focus.

   PLACEMENT NOTE: this is a global selector living in a component file.
   Both pages load join-form.css so it applies everywhere, but base.css is
   where it belongs; moving it is a separate decision and was not made
   here. */
a:focus-visible,
.jf input:focus-visible,
.jf select:focus-visible,
.jf textarea:focus-visible,
.jf-submit:focus-visible{
  outline:3px solid var(--focus);
  outline-offset:2px;
}

.jf-submit{
  margin-top:26px;display:inline-block;
  padding:14px 30px;font-size:14.5px;font-weight:640;
  border-radius:8px;cursor:pointer;font-family:var(--sans);
  background:var(--ground-fill);
  color:var(--ground-page);
  border:1.5px solid var(--on-page);
}
.jf-note{margin-top:16px;font-size:13px;color:var(--on-page-body);max-width:54ch}

@media(max-width:640px){.jrow{gap:0}}

/* ---------------------------------------------------------------------
   ERROR AND SUCCESS STATES
   --------------------------------------------------------------------- */

/* THE ERROR IS NOT SIGNALLED BY COLOUR ALONE. Colour carries none of the
   information here: the message text states what is wrong, aria-invalid
   states it to assistive tech, and the thickened border gives a
   non-colour visual cue. A red border on its own fails for anyone who
   cannot distinguish it from the default, which is the most common
   accessibility defect in form design.
   --error takes its own token so the error red can be tuned against the
   page ground without touching anything else in the palette. */
.jf-err{
  margin-top:7px;font-size:13px;line-height:1.4;
  color:var(--error);
}
/* THE AUTHORED WIDTHS ARE NOT THE RENDERED WIDTHS, AND THE RENDERED PAIR
   IS WHAT CARRIES THE CUE. Authored 1.5px / 2.5px; Chrome rounds border
   width to whole device pixels, so what actually renders is 1px / 2px —
   measured identical at dpr 1 and dpr 2. The doubling is the non-colour
   signal. A later tidy of 2.5 to 2 would change nothing; a tidy of the
   BASE 1.5 to 2 would silently delete the cue and leave the error state
   signalled by colour alone, which no colour-contrast check would flag.
   Verify by reading both computed widths, not by reading these numbers. */
.jf input[aria-invalid="true"],
.jf select[aria-invalid="true"],
.jf textarea[aria-invalid="true"]{
  border-width:2.5px;
  border-color:var(--error);
}

/* The status line is the polite live region. It is authored empty and
   present in the markup — a live region created at the same instant as
   its text is not reliably announced. */
.jf-status{
  margin-top:14px;font-size:13.5px;min-height:1.2em;
  color:var(--on-page-body);
}

.jf-success{
  margin-top:30px;max-width:640px;
  padding:28px 30px;
  background:var(--ground-alt);
  border-left:4px solid var(--gold);
}
/* focus is moved here on success; the outline is what tells a keyboard
   user where they landed */
.jf-success:focus-visible{outline:3px solid var(--focus);outline-offset:3px}
.jf-success h3{font-family:var(--serif);font-size:clamp(20px,2.2vw,26px);font-weight:700}
.jf-success .body{margin-top:12px}
