/* ==========================================================================
   lic-system.css — the shared design-system layer
   --------------------------------------------------------------------------
   LOAD LAST, after licorp.css or home.css:

       tokens.css  ->  licorp.css | home.css  ->  lic-system.css

   Why it exists. The site has two component stylesheets: licorp.css for the
   28 content pages and home.css for the homepage. Anything that belongs to
   both therefore had to be written twice -- and on 2026-07-28 a whole day of
   work went into licorp.css only, which meant the homepage's form showed its
   validation message in body ink at 1.47:1 because none of it reached that
   page. This file is the fix, and the first step of the merge: the shared
   layer lives here once, and every page loads it.

   It loads last on purpose. These rules were originally appended to the end of
   licorp.css and settle specificity ties by source order; putting the file
   before the component sheets would flip several of those ties, most visibly
   .btn:active losing to .btn:hover.

   What belongs here: anything both page families need -- interaction states,
   surface context, form validation, field notes, base components, the link
   hover system. What does not: page-family layout, which stays in licorp.css
   and home.css respectively.
   ========================================================================== */

/* ==========================================================================
   LINK HOVER SYSTEM (2026-07-28)
   --------------------------------------------------------------------------
   Navigation links hover to one of two colours, chosen by the background they
   sit on. This is not a style preference -- it is a contrast requirement:

     teal  #00d3f3   on white  1.81:1  FAILS      on dark navy 10.32:1  passes
     navy  #27336f   on white 11.74:1  passes     on dark navy  1.59:1  FAILS

   So neither colour can be used everywhere. The rule is:

     on a DARK background  -> --a-teal
     on a LIGHT background -> --navy

   Article body copy is the deliberate exception: prose links keep the mid-blue
   --a-blue-ink, which reads on white (7.46:1) without pulling the eye as hard
   as navy. Body copy is not navigation.

   This block is last in the file on purpose: it settles specificity ties by
   source order, so the intent here is the final word.
   ========================================================================== */

/* ---- navigation on dark backgrounds -> teal ---- */
.sector-hero a.back-link:hover,
.sector-hero a.back-link:focus-visible,
.cta-final a:not(.btn):hover,
.band a:hover {
  color:var(--a-teal);
}

/* ---- navigation on light backgrounds -> navy ---- */
.art-crumb a.back-link:hover,
.art-crumb a.back-link:focus-visible,
.load-more:hover,
.sub-nav a:hover,
.foot-grid a:hover,
.foot-legal a:hover,
.foot-privacy:hover,
nav.links > a:hover,
nav.links > .has-dropdown > a:hover,
.dropdown a:hover {
  color:var(--navy);
}

/* ---- article prose: the exception, left as a readable mid-blue ---- */
.art-body a:hover,
.text-link:hover {
  color:var(--a-blue-ink);
}

/* ==========================================================================
   INTERACTION STATES + BASE COMPONENTS (2026-07-28)
   --------------------------------------------------------------------------
   Everything below is documented and demonstrated in styleguide.html, which
   loads this file directly -- so the documentation cannot drift from it.

   Two rules govern this block:
     1. Every interactive element has all five states: default, hover, active,
        focus-visible, disabled. A control with only hover is half-built --
        keyboard users get no feedback and disabled state gets faked per page.
     2. Colour is chosen by the background it sits on, not by preference. Teal
        fails contrast on white (1.81:1); navy fails on dark navy (1.59:1).
   ========================================================================== */

/* ---------------------------------------------------------------- buttons --
   Three variants, split by the background they belong on:
     .btn-primary  navy fill      -> light backgrounds
     .btn-ghost    outlined       -> light backgrounds, secondary action
     .btn-light    white fill     -> dark backgrounds
   All three are pills, all three lift 1px on hover and settle on press.
   -------------------------------------------------------------------------- */
.btn {
  transition:transform var(--dur-fast) var(--ease-out),
             background var(--dur-base) var(--ease-out),
             border-color var(--dur-base) var(--ease-out),
             color var(--dur-base) var(--ease-out);
  min-height:40px;
}

.btn:active {
  transform:translateY(0);
}

.btn[disabled],
.btn.is-disabled,
button[disabled] {
  opacity:var(--state-disabled-opacity);
  pointer-events:none;
  transform:none;
}

/* secondary on light — previously had no surface feedback at all, so it lifted
   without acknowledging the pointer. Now the surface and border both respond. */
.btn-ghost:hover {
  background:var(--bg-soft);
  border-color:var(--navy);
  color:var(--navy);
}

/* secondary on dark */
.btn-light {
  background:#fff;
  color:var(--navy);
  border:1px solid transparent;
}

.btn-light:hover {
  background:#eef2fb;
  color:var(--navy);
}

/* On a dark surface the blue focus ring is too close to the background to read,
   so it switches to the accent. 10.3:1 against dark navy. */
.cta-final .btn:focus-visible,
.band .btn:focus-visible,
.sector-hero a:focus-visible {
  outline-color:var(--a-teal);
}

/* -------------------------------------------------------------- form fields --
   Vertical rhythm: label sits 6px above its own field, rows are 24px apart.
   The 1:4 ratio is what makes a label read as belonging to the field below it
   rather than floating between two. Do not equalise them.
   -------------------------------------------------------------------------- */
.lic-form input,
.lic-form select,
.lic-form textarea,
.cta-form input,
.cta-form textarea {
  transition:border-color var(--dur-base) var(--ease-out),
             background var(--dur-base) var(--ease-out),
             box-shadow var(--dur-base) var(--ease-out);
}

/* 44px is the touch-target floor, and it applies to single-line controls only.
   Textareas are taller than that by definition and their height is a per-page
   decision — the contact form wants 120px, the CTA form 76px. Including them
   here would set min-height:44px and, because this file loads last, silently
   shrink the CTA textarea from 76px. */
.lic-form input,
.lic-form select,
.cta-form input {
  min-height:44px;
}

/* Only the contact page's tall textarea. The .cta-form one is deliberately
   compact (76px, set per page family) and must not be overridden here — the
   shared layer loads last, so a value written here silently wins. */
.lic-form textarea {
  min-height:120px;
}

.lic-form input[disabled],
.lic-form select[disabled],
.lic-form textarea[disabled] {
  background:var(--bg-soft);
  color:var(--muted);
  cursor:not-allowed;
  opacity:1;
}

.lic-form input[aria-invalid="true"],
.lic-form select[aria-invalid="true"],
.lic-form textarea[aria-invalid="true"] {
  border-color:var(--tone-danger);
}

/* Sub-field notes are defined globally, in the FIELD NOTES block near the end
   of this file. They used to be scoped to .lic-form, which left them entirely
   unstyled inside .cta-form — the form that appears on 26 pages — where they
   inherited body ink at 1.47:1 on the navy background. */

/* ------------------------------------------------------------------ badge --
   Small non-interactive label. Mono, uppercase, squared like everything else.
   -------------------------------------------------------------------------- */
.lic-badge {
  display:inline-flex;
  align-items:center;
  gap:6px;
  font-family:var(--font-mono);
  text-transform:uppercase;
  letter-spacing:.1em;
  font-size:11px;
  font-weight:500;
  line-height:1;
  padding:6px 10px;
  color:var(--navy);
  background:var(--bg-soft);
  border:1px solid var(--line);
}

.lic-badge--accent {
  color:var(--a-blue-ink);
  background:var(--tone-info-bg);
  border-color:transparent;
}

.lic-badge--success {
  color:var(--tone-success);
  background:var(--tone-success-bg);
  border-color:transparent;
}

.lic-badge--warning {
  color:var(--tone-warning);
  background:var(--tone-warning-bg);
  border-color:transparent;
}

.lic-badge--danger {
  color:var(--tone-danger);
  background:var(--tone-danger-bg);
  border-color:transparent;
}

/* ----------------------------------------------------------- inline message --
   For form results, page-level notices, empty-state explanations. All four
   tones clear AA against their own background (4.5:1 to 6.7:1). The left rule
   carries the tone as well as the colour, so it does not rely on colour alone.
   -------------------------------------------------------------------------- */
.lic-note {
  display:flex;
  gap:12px;
  padding:14px 16px;
  border-left:3px solid var(--tone-info);
  background:var(--tone-info-bg);
  color:var(--tone-info);
  font-size:15px;
  line-height:1.55;
}

.lic-note p {
  margin:0;
}

.lic-note--success {
  border-left-color:var(--tone-success);
  background:var(--tone-success-bg);
  color:var(--tone-success);
}

.lic-note--warning {
  border-left-color:var(--tone-warning);
  background:var(--tone-warning-bg);
  color:var(--tone-warning);
}

.lic-note--danger {
  border-left-color:var(--tone-danger);
  background:var(--tone-danger-bg);
  color:var(--tone-danger);
}

/* ------------------------------------------------------------------ table --
   Squared, hairline rules, mono uppercase header. No zebra striping: on this
   palette it competes with the row borders and adds noise.
   -------------------------------------------------------------------------- */
.lic-table {
  width:100%;
  border-collapse:collapse;
  font-size:15px;
  line-height:1.5;
}

.lic-table caption {
  text-align:left;
  font-family:var(--font-mono);
  text-transform:uppercase;
  letter-spacing:.12em;
  font-size:11px;
  color:var(--muted);
  padding-bottom:10px;
}

.lic-table th {
  text-align:left;
  font-family:var(--font-mono);
  text-transform:uppercase;
  letter-spacing:.1em;
  font-size:11px;
  font-weight:500;
  color:var(--navy);
  padding:10px 14px 10px 0;
  border-bottom:1px solid var(--navy);
  white-space:nowrap;
}

.lic-table td {
  padding:13px 14px 13px 0;
  border-bottom:1px solid var(--line);
  color:var(--ink);
  vertical-align:top;
}

.lic-table tr:last-child td {
  border-bottom:0;
}

.lic-table td:last-child,
.lic-table th:last-child {
  padding-right:0;
}

/* ------------------------------------------------------------- pull quote --
   Editorial emphasis inside article body copy.
   -------------------------------------------------------------------------- */
.lic-quote {
  margin:32px 0;
  padding:0 0 0 22px;
  border-left:3px solid var(--a-teal);
  font-size:clamp(19px,1.8vw,23px);
  line-height:1.45;
  color:var(--ink);
  font-weight:500;
}

.lic-quote cite {
  display:block;
  margin-top:12px;
  font-family:var(--font-mono);
  font-size:12px;
  font-style:normal;
  text-transform:uppercase;
  letter-spacing:.1em;
  color:var(--muted);
}

/* ----------------------------------------------------------------- motion --
   Anyone who has asked their system to reduce motion gets no transforms and no
   transitions. Colour and focus feedback stay, because those carry meaning.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion:reduce) {
  .btn:hover,
  .btn:active,
  .ind-card:hover,
  .member:hover,
  .post-card:hover,
  .trust-item:hover {
    transform:none;
  }
}

/* ==========================================================================
   SURFACE CONTEXT (2026-07-28)
   --------------------------------------------------------------------------
   The container declares its surface; the components inside adapt. Two role
   names -- .btn-primary and .btn-ghost -- produce four appearances, so an
   author picks a role and never has to remember which palette a section needs.

     <div class="on-dark">
       <a class="btn btn-primary" href="…">Let's talk</a>
       <a class="btn btn-ghost"   href="…">Learn more</a>
     </div>

   The three dark surfaces that already exist are aliased below, so inside
   .cta-final, .band and .nf this happens automatically and `on-dark` is only
   needed by hand when a new dark section is built.

   Why a surface context rather than a fourth button class: the same split
   already governs link hover (dark -> teal, light -> navy) and the focus ring
   (dark -> teal). One container flag covers all of them, and covers whatever
   component is added next, instead of each one growing its own dark variant.

   Accessibility note. The border on the dark secondary is
   rgba(255,255,255,.55) -- 6.07:1 against #0D1430 and 4.71:1 against #27336F.
   The pre-existing nav treatment used .3, which is 2.66:1 and 2.44:1: below
   the 3:1 WCAG 1.4.11 minimum for a UI component boundary. .4 is the floor;
   .55 leaves margin on both surfaces without reading as a solid white outline.
   ========================================================================== */

/* NOTE (2026-08-03): `.on-dark` here means "this CONTAINER is a dark surface".
   The homepage nav used to toggle this same class name on <header class="nav">
   to mean "the nav is currently over the dark hero", which made the Contact us
   button turn white mid-scroll on a header that is forced white anyway. The nav
   now uses `nav-over-hero` instead. Do not reuse `on-dark` as a state flag. */
/* ---- primary on dark: white fill ---- */
.on-dark .btn-primary,
.cta-final .btn-primary,
.band .btn-primary,
.nf .btn-primary {
  background:#fff;
  color:var(--navy);
  /* border:0, not a transparent 1px: a transparent border still occupies 2px
     and would change the pill's dimensions where it was previously border:0. */
  border:0;
}

.on-dark .btn-primary:hover,
.cta-final .btn-primary:hover,
.band .btn-primary:hover,
.nf .btn-primary:hover {
  background:#eef2fb;
  color:var(--navy);
}

/* ---- secondary on dark: outlined ---- */
.on-dark .btn-ghost,
.cta-final .btn-ghost,
.band .btn-ghost,
.nf .btn-ghost {
  background:transparent;
  color:#fff;
  border:1px solid rgba(255,255,255,.55);
}

.on-dark .btn-ghost:hover,
.cta-final .btn-ghost:hover,
.band .btn-ghost:hover,
.nf .btn-ghost:hover {
  background:rgba(255,255,255,.12);
  border-color:#fff;
  color:#fff;
}

/* ---- .btn-light is the old name for "primary on dark". Kept so existing
        markup keeps working; prefer .btn-primary inside .on-dark. ---- */
.on-dark .btn-light,
.btn-light {
  background:#fff;
  color:var(--navy);
  border:0;
}

/* ---- focus ring and link hover follow the same surface split ---- */
.on-dark .btn:focus-visible,
.on-dark a:focus-visible {
  outline-color:var(--a-teal);
}

.on-dark a:not(.btn):hover {
  color:var(--a-teal);
}

/* ==========================================================================
   FORM VALIDATION STATE (2026-07-28)
   --------------------------------------------------------------------------
   Driven by lic-forms.js, which adds .is-invalid to the wrapping .lf-field
   and aria-invalid to the control. Include that script on any page with a
   form; there is no per-form setup.

   Three signals, never colour alone: the label and border change colour, a
   message appears under the field, and the control carries aria-invalid with
   aria-describedby pointing at the message.

   The error colour follows the same surface rule as everything else. On dark
   surfaces #c0392b is 3.33:1 — below AA — so it switches to
   --tone-danger-on-dark (7.93:1).
   ========================================================================== */

.lf-field.is-invalid label,
.lf-check.is-invalid {
  color:var(--tone-danger);
}

.lf-field.is-invalid input,
.lf-field.is-invalid select,
.lf-field.is-invalid textarea,
.lic-form input.invalid,
.lic-form select.invalid,
.lic-form textarea.invalid,
.cta-form input.invalid,
.cta-form textarea.invalid {
  border-color:var(--tone-danger);
}

.lf-field.is-invalid input:focus,
.lf-field.is-invalid select:focus,
.lf-field.is-invalid textarea:focus {
  border-color:var(--tone-danger);
  box-shadow:0 0 0 3px rgba(192,57,43,.18);
}

/* empty message nodes must not add space before they have anything to say */
.lf-error:empty {
  display:none;
}

/* ---- the same states on a dark surface ---- */
.on-dark .lf-field.is-invalid label,
.cta-form .lf-field.is-invalid label,
.on-dark .lf-check.is-invalid,
.cta-form .lf-check.is-invalid,
.on-dark .lf-error,
.cta-form .lf-error {
  color:var(--tone-danger-on-dark);
}

.on-dark .lf-field.is-invalid input,
.on-dark .lf-field.is-invalid select,
.on-dark .lf-field.is-invalid textarea,
.cta-form .lf-field.is-invalid input,
.cta-form .lf-field.is-invalid textarea {
  border-color:var(--tone-danger-on-dark);
}

.on-dark .lf-field.is-invalid input:focus,
.cta-form .lf-field.is-invalid input:focus,
.cta-form .lf-field.is-invalid textarea:focus {
  border-color:var(--tone-danger-on-dark);
  box-shadow:0 0 0 3px rgba(255,138,128,.22);
}

.on-dark .lf-hint,
.cta-form .lf-hint {
  color:rgba(255,255,255,.68);
}

/* ---- form-level status line ---- */
.cta-form .lf-status.err,
.on-dark .lf-status.err {
  color:var(--tone-danger-on-dark);
}

.cta-form .lf-status.ok,
.on-dark .lf-status.ok {
  color:#7ee2b8;
}

/* ==========================================================================
   FIELD NOTES (2026-07-28)
   --------------------------------------------------------------------------
   One treatment for everything that sits under, or just above, a form field.
   Three tones, same geometry:

     .req-note   the "* = required" legend above a form   — accent
     .lf-hint    helper text under a field                — warning
     .lf-error   validation message under a field          — danger

   Defined globally, NOT scoped to a form class. They were previously declared
   only inside .lic-form, which meant that in .cta-form -- the form on 26 pages
   -- they had no styling at all and inherited body ink: #131C24 on #27336F is
   1.47:1, effectively invisible. That is the bug this block fixes.

   Every tone has a dark-surface counterpart, because the light-surface values
   fail AA on navy: danger #C0392B is 3.33:1 and warning #8A5A00 is 1.98:1.
   ========================================================================== */

.req-note,
.lf-hint {
  display:block;
  font-family:var(--font-mono);
  text-transform:uppercase;
  letter-spacing:.1em;
  font-weight:500;
  line-height:1.45;
}

/* .req-note keeps the 10px it shipped with — it is a one-word legend. Helper
   text gets 11px: it carries a short sentence, and 10px mono uppercase is tight
   for that. Same voice, one step apart. */
.lf-hint {
  margin-top:6px;
  font-size:11px;
  color:var(--tone-warning);
}

/* The validation message stays sentence-case sans: it carries a whole sentence,
   and mono uppercase at that length is markedly slower to read. */
.lf-error {
  display:block;
  margin-top:6px;
  font-family:var(--font-sans);
  text-transform:none;
  letter-spacing:normal;
  font-size:13px;
  font-weight:400;
  line-height:1.5;
  color:var(--tone-danger);
}

/* ---- on dark surfaces ---- */
.on-dark .lf-hint,
.cta-form .lf-hint {
  color:var(--tone-warning-on-dark);
}

.on-dark .lf-error,
.cta-form .lf-error {
  color:var(--tone-danger-on-dark);
}

.on-dark .req-note,
.cta-form .req-note {
  color:var(--a-teal);
}
