/* Shared primitives ported from the Pathwise Law design system.
   Used by both the marketing site and the maintenance splash — change a rule
   here and it moves in both places. Layout that belongs to one page only does
   not go in this file. */

/* ---- Wordmark (design-system Wordmark.jsx) ---- */
.wordmark {
  --wm: 34px; /* px size, set responsively via JS */
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  line-height: 1;
  font-family: var(--font-sans);
}
.wordmark__word {
  font-weight: 600;
  font-size: var(--wm);
  letter-spacing: 0.30em;
  margin-right: -0.30em;
  color: var(--navy-900);
}
.wordmark__law {
  display: flex;
  align-items: center;
  gap: calc(var(--wm) * 0.4);
  margin-top: calc(var(--wm) * 0.28);
  color: var(--blue-700);
  width: 100%;
}
.wordmark__rule {
  flex: 1;
  height: max(1px, calc(var(--wm) * 0.05));
  background: var(--slate-400);
}
.wordmark__law-text {
  font-size: calc(var(--wm) * 0.46);
  font-weight: 500;
  letter-spacing: 0.42em;
  text-indent: 0.42em;
}

/* Reversed, for navy surfaces. Brightening the dark mark does not work —
   the design system supplies a separate reversed treatment. */
.wordmark--light .wordmark__word { color: var(--paper-50); }
.wordmark--light .wordmark__law { color: var(--mist-200); }
.wordmark--light .wordmark__rule { background: var(--border-inverse); }

.eyebrow {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--blue-700);
}

/* ---- Input (design-system Input.jsx, size="lg") ---- */
.input {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-family: var(--font-sans);
  flex: 1;
  width: 100%;
}
.input__label {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-strong);
}
.input__box {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface-card);
  /* --border-strong (slate-400) clears WCAG 1.4.11 non-text contrast (3.1:1)
     against the white field; --border-default was only 1.36:1. */
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 13px 16px;
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast);
}
.input__box:focus-within {
  border-color: var(--blue-700);
  box-shadow: var(--shadow-focus);
}
.input.is-error .input__box { border-color: var(--danger-600); }
.input.is-error .input__box:focus-within { border-color: var(--danger-600); }
.input__box input {
  border: none;
  outline: none;
  background: transparent;
  font-family: inherit;
  font-size: 16px;
  color: var(--text-strong);
  width: 100%;
  padding: 0;
}
.input__msg { font-size: 12px; color: var(--danger-600); }
.input__hint { font-size: 12px; color: var(--text-muted); }

/* ---- Select / Textarea / Radio (design-system Select.jsx, Textarea.jsx,
   Radio.jsx) ----

   Two deliberate departures from the design-system source, both for the same
   reason the .input border above was changed:

   1. Borders are --border-strong, not the DS's --border-default. On the white
      field --border-default is 1.36:1 and fails WCAG 1.4.11 (3:1 for UI
      component boundaries); --border-strong clears it at 3.4:1.
   2. The DS Radio hides the native input (opacity 0, 0×0) and paints a <span>
      beside it, which leaves a keyboard user with no visible focus indicator —
      WCAG 2.4.7. These use appearance:none on the real control instead, so it
      keeps its own focus ring while looking identical.

   Everything else — sizes, colors, the 18px/9px radio geometry — is the DS's.
   The one further departure is the select caret, drawn as geometry rather than
   the DS's glyph; see the note on .select-wrap below. */
.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-family: var(--font-sans);
}
.field__label { font-size: 13px; font-weight: 600; color: var(--text-strong); }
.field__hint { font-size: 12px; color: var(--text-muted); }
.field__msg { font-size: 12px; color: var(--danger-600); }

/* The caret is a pseudo-element on a wrapper, matching the DS's positioned
   <span>. A background-image on the <select> renders identically and needs no
   wrapper, but axe then reports the control as "background color could not be
   determined due to a background image" — the contrast rule returns
   *incomplete* rather than pass. ci/a11y.mjs fails only on violations, so that
   would sail through CI while leaving the field permanently unverified. Keep
   the background a flat color.

   GEOMETRY, NOT THE DS'S U+25BE GLYPH (#74). That character is absent from
   Hanken Grotesk — measured, not assumed: the glyph's advance width is
   identical in Hanken and in Helvetica, so it was resolving through the
   fallback chain to whatever face the visitor's system happens to supply.
   Three consequences, all of them now gone:

     1. It looked different on every platform. It was the only part of the
        design system rendered by an arbitrary installed font rather than by
        the design system.
     2. It was the only thing on the site that did not rasterize
        deterministically — 8 px of drift on /contact at both viewports,
        against 0 px on the other 23 baselines. tests/visual/pages.spec.js
        carried maxDiffPixels purely to absorb it; that is now 0.
     3. Chrome exposed it to assistive technology as a bare text node,
        {role: "text", name: "▾"}, once per select. Decorative content that a
        screen reader may announce and cannot be asked to ignore — you cannot
        put aria-hidden on a pseudo-element. Borders are not text and add no
        node at all.

   8x4 is candidate C of five rendered for review, and a deliberate step up
   from the fallback glyph's 3.2x3.2 px of ink, which read as a smudge at 1x.
   Color and position are unchanged from the DS. Contrast is unaffected:
   --slate-500 on --surface-card measures 4.58:1, against the 3:1 that WCAG
   1.4.11 asks of a non-text indicator. */
.select-wrap { position: relative; display: flex; }
.select-wrap::after {
  content: '';
  position: absolute;
  right: 14px;
  top: 50%;
  transform: translateY(-50%);
  pointer-events: none;
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 4px solid var(--slate-500);
}
.select {
  appearance: none;
  width: 100%;
  font-family: inherit;
  font-size: 14px;
  color: var(--text-strong);
  background: var(--surface-card);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 10px 38px 10px 14px;
  outline: none;
  cursor: pointer;
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast);
}
.select:focus-visible { border-color: var(--blue-700); box-shadow: var(--shadow-focus); }
.field.is-error .select { border-color: var(--danger-600); }

.textarea {
  font-family: inherit;
  font-size: 14px;
  color: var(--text-strong);
  background: var(--surface-card);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 10px 14px;
  resize: vertical;
  outline: none;
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast);
}
.textarea:focus-visible { border-color: var(--blue-700); box-shadow: var(--shadow-focus); }
.field.is-error .textarea { border-color: var(--danger-600); }

.radio {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-sans);
  font-size: 14px;
  color: var(--text-body);
  cursor: pointer;
  /* 44px target — the prototype set this per-instance; it belongs on the
     control. */
  min-height: 44px;
}
.radio input[type='radio'] {
  appearance: none;
  margin: 0;
  width: 18px;
  height: 18px;
  flex: none;
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius-pill);
  background: var(--surface-card);
  cursor: pointer;
  display: grid;
  place-content: center;
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast);
}
.radio input[type='radio']::before {
  content: '';
  width: 9px;
  height: 9px;
  border-radius: var(--radius-pill);
  background: var(--navy-900);
  transform: scale(0);
  transition: transform var(--dur-fast);
}
.radio input[type='radio']:checked { border-color: var(--navy-900); }
.radio input[type='radio']:checked::before { transform: scale(1); }
.radio input[type='radio']:focus-visible { box-shadow: var(--shadow-focus); }

/* Checkbox — the same control as .radio with square geometry, for the multi
   select on /contact (#160). The tick is drawn with borders rather than a glyph
   ON PURPOSE: the ▾ on the select boxes is the one non-deterministic thing in
   the visual baselines because U+25BE falls back out of Hanken Grotesk, and a
   ✓ would have bought the same problem. Pure geometry renders identically. */
.checkbox {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-sans);
  font-size: 14px;
  color: var(--text-body);
  cursor: pointer;
  min-height: 44px;
}
.checkbox input[type='checkbox'] {
  appearance: none;
  margin: 0;
  width: 18px;
  height: 18px;
  flex: none;
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface-card);
  cursor: pointer;
  display: grid;
  place-content: center;
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast);
}
.checkbox input[type='checkbox']::before {
  content: '';
  width: 10px;
  height: 5px;
  margin-top: -3px;
  border-left: 2px solid var(--navy-900);
  border-bottom: 2px solid var(--navy-900);
  transform: rotate(-45deg) scale(0);
  transition: transform var(--dur-fast);
}
.checkbox input[type='checkbox']:checked { border-color: var(--navy-900); }
.checkbox input[type='checkbox']:checked::before { transform: rotate(-45deg) scale(1); }
.checkbox input[type='checkbox']:focus-visible { box-shadow: var(--shadow-focus); }

/* ---- Card (design-system Card.jsx, variant="default") ---- */
.card {
  font-family: var(--font-sans);
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-sm);
}
/* The DS's padding="xl" is a flat 40px. Kept at wide widths, stepped down on
   small screens: at 375px a fixed 40px leaves only ~255px of usable width
   inside the card, and the export has no responsive step because it was drawn
   against a desktop container. */
.card--xl { padding: clamp(24px, 5vw, 40px); }

/* ---- Button (design-system Button.jsx) ----

   Transcribed from the DS component rather than approximated. The base is its
   DEFAULT: variant="primary", size="md". Sizes and variants are modifiers, and
   full width is opt-in via .btn--full, because the DS default is inline-flex
   and fullWidth is a prop you pass.

   That is the inverse of what this file used to do. .btn was full-width at the
   lg size, and every button on the site had to opt out with .btn--auto — a
   shape inherited from the coming-soon splash, whose one button was full width.
   It made lg the de facto size everywhere and left no way to say "md".

   One deliberate addition: min-height 44px, which the DS does not specify.
   WCAG 2.5.8 asks for 24px targets and the prototype set 44 per-instance on
   several buttons; putting it on the control is where it belongs.

   The DS has no :active state, so neither does this. */
.btn {
  font-family: var(--font-sans);
  font-weight: 600;
  letter-spacing: 0.01em;
  font-size: 14px;
  padding: 11px 20px;
  border-radius: var(--radius-sm);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  cursor: pointer;
  background: var(--action-primary);
  color: var(--action-primary-text);
  border: 1px solid var(--action-primary);
  transition: background var(--dur-fast) var(--ease-standard),
              color var(--dur-fast) var(--ease-standard),
              border-color var(--dur-fast) var(--ease-standard),
              box-shadow var(--dur-fast) var(--ease-standard);
}
/* SPECIFICITY TRAP, read before adding a variant. This rule is (0,2,0) and a
   variant class is (0,1,0), so `border-color` here paints over any variant
   whose OWN :hover does not restate it — even though the variant sets a border
   at rest. A borderless variant therefore grew a navy border on hover, which is
   what happened to .btn--link on /services.

   Every variant below restates border-color in its :hover for that reason. If
   you add one, do the same. */
.btn:hover { background: var(--action-primary-hover); border-color: var(--action-primary-hover); }
.btn:focus-visible { box-shadow: var(--shadow-focus); outline: none; }

/* Sizes. Note the radius changes with the size in the DS: sm and md are
   --radius-sm, lg steps up to --radius-md. */
.btn--sm { font-size: 13px; padding: 8px 14px; gap: 7px; }
.btn--lg { font-size: 15px; padding: 14px 26px; gap: 9px; border-radius: var(--radius-md); }

/* fullWidth. */
.btn--full { display: flex; width: 100%; }

.btn--secondary {
  background: var(--action-secondary);
  color: var(--paper-50);
  border-color: var(--action-secondary);
}
.btn--secondary:hover {
  background: var(--action-secondary-hover);
  border-color: var(--action-secondary-hover);
}

.btn--outline {
  background: transparent;
  color: var(--navy-900);
  border-color: var(--border-strong);
}
/* The DS darkens the border to navy on hover, not just the fill. */
.btn--outline:hover { background: var(--surface-sunken); border-color: var(--navy-900); }

.btn--ghost {
  background: transparent;
  color: var(--navy-900);
  /* Transparent, not --border-default. A bordered ghost is an outline button;
     the DS distinguishes them precisely here. */
  border-color: transparent;
}
.btn--ghost:hover { background: var(--surface-sunken); border-color: transparent; }

.btn--link {
  background: transparent;
  color: var(--text-link);
  border-color: transparent;
  padding: 0;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.btn--link:hover { background: transparent; color: var(--text-link-hover); border-color: transparent; }

/* Ghost on navy. Not a DS variant — the prototype builds it by passing
   heroGhostProps to variant="ghost", and these are that object's values:
   paper text, a 35% paper border, and a 14% paper fill on hover. The DS ghost
   alone would put navy text on a navy hero. */
.btn--ghost-light {
  background: transparent;
  color: var(--paper-50);
  border-color: color-mix(in srgb, var(--paper-50) 35%, transparent);
}
.btn--ghost-light:hover {
  background: color-mix(in srgb, var(--paper-50) 14%, transparent);
  border-color: color-mix(in srgb, var(--paper-50) 35%, transparent);
}

/* ---- Success confirmation ---- */
.confirm {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 16px 20px;
  border: 1px solid var(--success-600);
  border-radius: 10px;
  background: var(--success-100);
  color: var(--success-600);
  font-size: 15px;
  font-weight: 500;
}
.confirm__dot { width: 8px; height: 8px; border-radius: 999px; background: var(--success-600); flex: none; }

/* Wordmark sizes. These are classes rather than an inline style="--wm:..."
   because style-src-attr inherits 'self' from style-src, so a rendered style
   attribute is blocked at the edge. */
.wordmark--sm { --wm: 20px; }
.wordmark--md { --wm: 28px; }

/* Eyebrow on navy. */
.eyebrow--light { color: var(--mist-200); }

/* NOTE: .btn--outline, .btn--link and .btn--lg were duplicated here, appended
   below the Success confirmation block by a later session. Being last, they won
   the cascade — which is how .btn--outline:hover kept forcing color:navy over
   the variant above, and why a secondary button on navy went unreadable on
   hover. All three now live once, with the rest of the buttons. */
