/* Phone field — canonical styling for the intl-tel-input picker that
 * contact-form.js mounts on <input type="tel" name="phone">.
 *
 * Vendored from peaceharbor/toolbox/contact-form (canonical). Do not edit in
 * site repos — change the toolbox first, then propagate.
 *
 * Adopted from gpfbc, which shipped the picker first and set the house style:
 * full-width wrapper, the separate dial code in body text, and a dropdown
 * that takes the site's own surface, text and divider rather than the
 * vendor's white-on-#ccc.
 *
 * THE CONTRACT IS FIVE REQUIRED --ph-phone-* VARIABLES. Set them on `:root`
 * — NOT on the form, see below — and map them to that site's tokens:
 *
 *   --ph-phone-surface   dropdown background          (site: card/field bg)
 *   --ph-phone-fg        dropdown text                (site: heading/body ink)
 *   --ph-phone-muted     dial code + dropdown arrow   (site: muted text)
 *   --ph-phone-border    dropdown + control border    (site: CONTROL edge)
 *   --ph-phone-ring      country-button focus ring    (site: focus colour)
 *
 * Two more are optional, and both have working defaults, which is why the
 * count above says five:
 *
 *   --ph-phone-radius    dropdown corner radius       (default 2px)
 *   --ph-phone-wash      row highlight / hover tint   (default: fg at 18%)
 *
 * Map --ph-phone-border to the site's CONTROL-edge token, not its decorative
 * divider. This is a UI component boundary under WCAG 1.4.11, and sites that
 * distinguish the two (phweb's --control-line vs --line) usually have the
 * decorative one sitting below 3:1 on purpose.
 *
 * Mapping to theme-aware tokens is what makes dark mode work: the vendor
 * palette is light-only, so on a dark surface the arrow misses UI contrast
 * and the row highlight is invisible. Every variable falls back to the
 * vendor's own light value, so a site that maps nothing renders exactly as
 * intl-tel-input ships — this file can never make a form worse than not
 * loading it.
 */

/* WHY THE DOUBLED SELECTORS BELOW (`:root:root`, `.iti.iti`)
 *
 * This file cannot win on source order, so it wins on specificity instead.
 * contact-form.js lazy-loads the picker and appends the vendor stylesheet
 * with `document.head.appendChild(css)` at interaction time — so
 * intlTelInput.css is ALWAYS the last sheet in the document, whatever the
 * page's own <link> order says. Every declaration here that collides with a
 * vendor declaration of equal specificity therefore loses the tie, silently.
 *
 * This is not hypothetical. Shipped 2026-09-16 with plain selectors, and on
 * 2026-09-18 designs.peaceharbor.com was rendering the dark-mode fullscreen
 * popup as cream country names on a white overlay — a ~1.1:1 contrast — which
 * is the exact failure the paragraph above claims this file prevents. The
 * vendor's `:root` had overridden all five mappings and its own
 * `.iti__dropdown-content { background-color: var(--iti-dropdown-bg) }` had
 * overridden ours, while our `color` (which the vendor never sets, so nothing
 * collided) sailed through. Half-applied is worse than not loading at all.
 *
 * Doubling a selector repeats its specificity without changing which elements
 * it matches: `:root:root` is (0,2,0) against the vendor's (0,1,0) and still
 * matches the same single element.
 *
 * THE RULE FOR THIS FILE: every selector is repeated until it outranks the
 * strongest vendor selector that reaches the same node. Not "only where a
 * collision exists today" — that was the first draft of this rule, and it is
 * a trap, because it makes correctness depend on a vendor stylesheet nobody
 * re-audits on upgrade. `.iti__selected-dial-code` is the worked example: the
 * vendor currently sets only `margin` on it, so a plain selector works, and
 * the day an upgrade adds `color` there the field goes silently wrong in the
 * one mode hardest to notice. Doubling costs a repeated class and buys
 * immunity from that, so it is unconditional.
 *
 * Two places deliberately do NOT take the highest rank available, each
 * explained at the rule: the inline dropdown's border, and the fullscreen
 * container's layout. Read those before "fixing" them.
 */
/* `:root`, NOT the form, and this is load-bearing. On a narrow viewport the
 * vendor swaps the inline dropdown for a fullscreen popup that it appends to
 * <body> — outside the form, and outside `.iti` itself. Anything scoped to
 * either silently stops applying exactly where the dropdown is biggest, which
 * in dark mode means cream country names on a white overlay. Declaring the
 * vendor's own variables at the root covers both paths. They are all
 * `--iti-`/`--ph-phone-` prefixed, so there is nothing to collide with.
 *
 * "Narrow" is the vendor's `useFullscreenPopup`, which is a mobile UA sniff
 * OR `window.innerWidth <= 500` — so a desktop window dragged under 500px
 * takes this path too, and is how to see it without a phone. It is read once
 * when the script loads, so resizing after load does not switch modes. */
:root:root {
  --iti-dropdown-bg: var(--ph-phone-surface, #fff);
  --iti-border-color: var(--ph-phone-border, #ccc);
  --iti-arrow-color: var(--ph-phone-muted, #555);
  --iti-dialcode-color: var(--ph-phone-muted, #999);
  /* Derived from the text colour rather than a fixed black alpha, so the tint
   * adapts to the theme with no extra required mapping: dark ink at 18% on a
   * light surface, cream at 18% on a dark one. 18% and not the vendor's 5%
   * because this is the ONLY thing the vendor draws to say which row the
   * keyboard is on — and even 18% is about 1.7:1, which is why the highlight
   * rule further down adds a shape affordance rather than leaning on tint. */
  --iti-hover-color: var(--ph-phone-wash,
    color-mix(in oklab, var(--ph-phone-fg, #000) 18%, transparent));
}

/* The wrapper the vendor puts around the <input>. `:not(.iti--container)` is
 * not decoration: in fullscreen mode the body-appended popup ALSO carries
 * class `iti`, and the vendor lays it out with
 * `.iti--fullscreen-popup.iti--container { display: flex; … }` — which is
 * (0,2,0), the same weight as `.iti.iti`. Today the vendor sheet loads last
 * and wins that tie, but SPEC.md offers a critical-path <link> that puts it
 * FIRST, and in that configuration a bare `.iti.iti { display: block }` would
 * beat the flex rule and break the popup's layout. Excluding the container
 * makes the rule say what it always meant. */
.iti.iti:not(.iti--container) {
  width: 100%;
  display: block;
}

/* separateDialCode:true renders the dial code beside the flag, outside the
 * input, so it does not inherit the input's colour. */
.iti__selected-dial-code.iti__selected-dial-code {
  color: var(--ph-phone-muted, #999);
}

/* Covers both the inline dropdown and the fullscreen popup: the vendor uses
 * this same content node in each.
 *
 * `border` is the one property here that loses, to the vendor's
 * `.iti--inline-dropdown .iti__dropdown-content` (also (0,2,0), later sheet),
 * and only on the inline path. That is fine and deliberate: the vendor's
 * border reads `var(--iti-border-color)`, which `:root:root` above has
 * already pointed at `--ph-phone-border`, so it draws the colour we wanted
 * anyway. We could outrank it — the cascade resolves per PROPERTY, so doing
 * so would not disturb the `position`/`z-index`/`margin`/`box-shadow` that
 * live only on the vendor rule — but there is nothing to gain. */
.iti__dropdown-content.iti__dropdown-content {
  background: var(--ph-phone-surface, #fff);
  color: var(--ph-phone-fg, inherit);
  border: 1px solid var(--ph-phone-border, #ccc);
  border-radius: var(--ph-phone-radius, 2px);
}

/* The search box inside the dropdown. The vendor sets width, radius and
 * `border-width: 0` and NOTHING else (`.iti__search-input`), so its colours
 * come from the UA. That works only while the site declares
 * `color-scheme: light dark` — the modern-web baseline requires it, but a
 * form should not silently depend on a mandate in another document. Without
 * it the UA paints a light field, and the `color` inherited from the dropdown
 * puts cream text on it: the original bug, one node over. The vendor already
 * draws the separator via `.iti__search-input + .iti__country-list`, so this
 * sets colour only. */
.iti__search-input.iti__search-input {
  background: var(--ph-phone-surface, #fff);
  color: var(--ph-phone-fg, inherit);
}

/* WHICH ROW THE KEYBOARD IS ON.
 *
 * The vendor sets `.iti__country { outline: none }`, so arrowing through the
 * list has exactly one indicator: `background-color: var(--iti-hover-color)`
 * on `.iti__country.iti__highlight`. A translucent wash of the text colour
 * cannot reach 3:1 against the row it sits on without becoming a slab — at
 * 18% it is roughly 1.7:1 — so tint alone does not satisfy WCAG 1.4.11 for a
 * non-text state indicator, on either floor.
 *
 * The inset bar carries the contrast instead. It reuses --ph-phone-ring,
 * which the site has already chosen to be visible as a focus ring, so it
 * clears 3:1 against the dropdown surface by construction, and it is a shape
 * rather than a hue — legible to a low-vision or colour-blind user for whom
 * an 18% tint is not.
 *
 * (0,3,0) to outrank the vendor's (0,2,0) `.iti__country.iti__highlight`. */
.iti__country.iti__country.iti__highlight {
  box-shadow: inset 3px 0 0 0 var(--ph-phone-ring, Highlight);
}

/* The country control is a <button>. Site focus rules almost always target
 * input/select/textarea, so without this it tabs to a bare UA ring and looks
 * unlike every other control in the form. */
.iti__selected-country.iti__selected-country:focus-visible {
  outline: 2px solid var(--ph-phone-ring, Highlight);
  outline-offset: 1px;
}
