/* ============================================================================
   prototype-account.css  —  WellsAndSepticsPortal

   The small number of things the account pages need that the prototype has no
   class for, written in the prototype's own tokens.

   HAND-WRITTEN, and deliberately short. Everything the sign-in, registration,
   code-entry and password pages can borrow IS borrowed: .card, .fgrid, .fld,
   .s6/.s12, .lbl, .lbl .req, .inp, .ro, .hint, .hintline, .btn, .btn-primary,
   .btn-outline, .btn-neutral, .chip, .sec/.sec__hd/.sec__bd and the notice
   idiom (`card p-3 border-l-4` with the rule colour set inline) all come from
   prototype-final.css unchanged. This file adds only what is genuinely absent.

   WHY ANYTHING IS ABSENT AT ALL
   The prototype has no server behind it, so it has no server-side validation,
   no password field to unmask and no page that submits and comes back with
   errors on it. Those three things are what is here. Adding them to the
   prototype instead would be the better home for the first one, but the
   prototype is a generated import: a rule written into prototype-final.css is
   lost on the next re-import, silently.

   WHY THE VALIDATION RULES HANG OFF THE FRAMEWORK'S OWN CLASS NAMES
   ASP.NET writes `field-validation-error` / `field-validation-valid` onto the
   span an asp-validation-for renders, `input-validation-error` onto the input
   it refers to, and `validation-summary-errors` onto a summary. Styling those
   names rather than a class of our own means an error is styled wherever a
   view uses the tag helper, including views written later by somebody who
   never reads this file. A class of our own would have to be remembered on
   every field, and the day it is forgotten the message renders as ordinary
   grey hint text — which is to say, as though nothing were wrong.
   ========================================================================== */

/* ---- validation ---------------------------------------------------------- *
 * #b50909 is the prototype's own error red (.btn-danger, and the border it
 * puts on [aria-invalid="true"]), so an error here matches an error there.
 * Font weight rather than size does the work: the message sits under a field
 * at the reading floor, and shrinking it is the one change that would make it
 * harder to read at the moment it matters most. */
.field-validation-error {
  display: block;
  margin-top: .2rem;
  font-size: var(--fs-floor);
  line-height: var(--lh-body);
  font-weight: 600;
  color: #b50909;
  max-width: 82ch;
}

/* Valid = nothing at all, not merely invisible. `display:none` keeps the empty
   span from taking a line's worth of margin and shifting the field below it,
   which is what makes a form appear to jump when the first error clears. */
.field-validation-valid {
  display: none;
}

/* The same border and tint the prototype gives [aria-invalid="true"], applied
   to the class the framework sets, so the two routes to "this field is wrong"
   look identical. !important matches the prototype's own rule, which needs it
   to beat .inp's border declaration. */
.input-validation-error {
  border-color: #b50909 !important;
  background: #fef2f2;
}

.validation-summary-errors {
  font-size: var(--fs-floor);
  line-height: var(--lh-body);
  color: #b50909;
}
.validation-summary-errors ul {
  margin: .25rem 0 0;
  padding-left: 1.1rem;
}
.validation-summary-valid {
  display: none;
}

/* ---- password unmask ----------------------------------------------------- *
 * A row, not an absolutely-positioned eye inside the box. Two reasons: an icon
 * inside the field overlaps the browser's own password manager button on
 * Chrome and Safari, and a real <button> with real words is what a screen
 * reader can announce and a keyboard can reach in order. The old system used
 * USWDS's `usa-show-password`, which is the same shape — a text button beside
 * the field — so this is the familiar control, restyled. */
.pwmask {
  display: flex;
  align-items: stretch;
  gap: .4rem;
}
.pwmask > .inp {
  flex: 1 1 auto;
}
.pwmask__btn {
  flex: 0 0 auto;
  border: 1px solid var(--c-line);
  background: #f8fafc;
  color: var(--c-primary);
  border-radius: .25rem;
  padding: 0 .6rem;
  font-size: var(--fs-micro);
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
}
.pwmask__btn:hover {
  background: #f1f5f9;
}
.pwmask__btn:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

/* ---- the account page measure -------------------------------------------- *
 * The portal screen is a 1600px grid. A sign-in form is not: a single column
 * of short fields stretched across a wide monitor puts the label and its own
 * input at opposite ends of the eye's travel. These cap the measure instead of
 * each view repeating a max-width inline. */
.acct {
  max-width: 34rem;
  margin: 0 auto;
}
.acct--wide {
  max-width: 52rem;
}
.acct h1 {
  margin: 0 0 .35rem;
}
.acct__lead {
  font-size: var(--fs-floor);
  line-height: var(--lh-body);
  color: var(--c-ink-muted);
  margin: 0 0 1rem;
  max-width: 82ch;
}

/* The action row under a form: primary on the left, the quieter way out on the
   right, wrapping to two lines on a phone rather than shrinking the button. */
.acct__acts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .75rem;
  margin-top: 1rem;
}
.acct__acts .btn {
  padding: .55rem 1.1rem;
}
/* 2 Oct 2026: a row with the way out on the LEFT and the primary on the RIGHT
   (the portal-wide action-row standard). Opt-in, so other account pages are unchanged. */
.acct__acts--split { justify-content: space-between; }
/* 2 Oct 2026: Profile sections 1-3 in one card, the Save at its end. */
.acct__profile-card { padding: 1rem 1.25rem; margin-bottom: 1.5rem; }
.acct__profile-card .acct__acts { border-top: 1px solid #dfe1e2; padding-top: 1rem; }

/* ---- the role choice ----------------------------------------------------- *
 * Three radios that decide what the whole rest of the form asks for, so they
 * are targets rather than dots: the label is the card, and the whole card is
 * clickable. The prototype has no radio-card of its own (it never asks anyone
 * to choose anything about themselves), so this is the one genuinely new
 * component on these pages — written in the prototype's tokens.
 *
 * :has(:checked) does the selected state in CSS with no script. If a browser
 * does not support :has, the native radio dot still shows which one is
 * selected — the styling is the reinforcement, not the information. */
.rolecard {
  display: flex;
  align-items: flex-start;
  gap: .55rem;
  cursor: pointer;
  border: 1px solid var(--c-line);
  border-radius: .5rem;
  background: #fff;
  padding: .7rem .75rem;
  margin-bottom: .5rem;
}
.rolecard:hover {
  background: #f8fafc;
}
.rolecard:has(input:checked) {
  border-color: var(--c-primary);
  box-shadow: inset 0 0 0 1px var(--c-primary);
  background: #f8fafc;
}

/* The focus ring goes on the CARD, not the 13px radio inside it, because the
   card is what a sighted keyboard user is looking at. */
.rolecard:has(input:focus-visible) {
  outline: none;
  box-shadow: var(--focus-ring);
}
.rolecard input {
  flex: 0 0 auto;
  margin-top: .2rem;
}
.rolecard__txt {
  font-size: var(--fs-floor);
  font-weight: 600;
  color: var(--c-ink);
  display: block;
}
.rolecard__note {
  font-size: var(--fs-micro);
  line-height: var(--lh-body);
  color: var(--c-ink-muted);
  display: block;
  margin-top: .1rem;
}

/* An option that is real but not yet available. Dimmed and not-allowed, and it
   keeps its explanation — deleting it would lose the fact that these people
   exist and ask to register, which is a requirement, not a leftover. */
.rolecard--unavailable {
  cursor: not-allowed;
  background: #f8fafc;
  opacity: .75;
}
.rolecard--unavailable:hover {
  background: #f8fafc;
}

/* A one-time code. Wide tracking and a monospaced face because it is read one
   character at a time and O/0 and l/1 have to be told apart. */
.otp {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--fs-body);
  font-weight: 700;
  letter-spacing: .35em;
  text-align: center;
  max-width: 12rem;
}

/* Larger, more legible account/profile text (user request, 21 Sep 2026).
   The account pages were reported as too small to read comfortably. These are
   SCOPED to .acct so they override brand.css's .lbl/.ro/.hint by specificity
   (0,0,2 beats brand's 0,0,1) regardless of stylesheet load order, and touch
   only the account area — no other page changes. Kept in rem so the A-/A/A+
   text-size control still scales them, and line-height is bumped with the size
   so the read-only value rows stay comfortable to read. */
.acct .lbl { font-size: var(--fs-body, 0.9375rem); }
.acct .ro  { font-size: 1rem; line-height: 1.55; }
.acct .hint,
.acct .hintline span { font-size: var(--fs-2xs, 0.875rem); }
