/* ─────────────────────────────────────────────────────────────
   InstallerHub board — the component library ("Vetted Blue").

   Mobile-first, one column, no framework, no build step. Every colour,
   size, radius, shadow and duration here reads from public_html/assets/
   tokens.css (loaded first) — there are no hand-written hex values below.
   See docs/DESIGN.md for the full system and how the future public
   website (installerhubuk.com) reuses the same tokens.

   Every class name the board's 30 views already depend on still works;
   everything below marked "new" is additive, for this pass and for the
   screen-by-screen agents that pick up board_rules next. Tables collapse
   to stacked cards below 700px. 44px touch targets throughout.
   ───────────────────────────────────────────────────────────── */

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--ih-bg);
  color: var(--ih-text);
  font-family: var(--ih-font-family);
  font-size: var(--ih-text-body);
  line-height: var(--ih-leading-body);
  font-weight: var(--ih-weight-regular);
}

a { color: var(--ih-accent); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3 { margin: 0 0 var(--ih-space-3); font-weight: var(--ih-weight-bold); color: var(--ih-text); }
h1 { font-size: var(--ih-text-h1); line-height: var(--ih-leading-h1); }
h2 { font-size: var(--ih-text-h2); line-height: var(--ih-leading-h2); }
h3 { font-size: var(--ih-text-h3); line-height: var(--ih-leading-h3); font-weight: var(--ih-weight-semibold); }

p { margin: 0 0 var(--ih-space-3); }

/* New — a plain muted-text utility (fixes a previously undefined class
   already emitted by board_settings.php's rejection-reason row). */
.ih-text-muted { color: var(--ih-text-muted); font-size: var(--ih-text-caption); line-height: var(--ih-leading-caption); }

/* Small inline icons — hand-written SVG only, sized to the surrounding text. */
.ih-icon { width: 1em; height: 1em; display: inline-block; vertical-align: -0.125em; flex-shrink: 0; }

/* ── Layout ──────────────────────────────────────────────────────────── */

/* Progressive widening (grafted from Fieldwork Blue): unchanged on phone/
   tablet, so wide tables (Settings' Trades, Sends' 8 columns) get real
   room on desktop instead of the old fixed 760px cap. */
.ih-main {
  max-width: 760px;
  margin: 0 auto;
  padding: var(--ih-space-4);
}
@media (min-width: 900px)  { .ih-main { max-width: 960px; } }
@media (min-width: 1200px) { .ih-main { max-width: 1100px; } }

.ih-public-main { padding-top: var(--ih-space-6); padding-bottom: var(--ih-space-6); }

/* ── Header and nav ──────────────────────────────────────────────────── */

/* Links to a section (#trades) land below the pinned header, not under it. */
html { scroll-padding-top: 140px; }

.ih-header {
  background: var(--ih-surface-raised);
  border-bottom: 1px solid var(--ih-border);
  box-shadow: var(--ih-shadow-sm);
  position: sticky;
  top: 0;
  z-index: 20;
}

.ih-header-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ih-space-3);
  padding: var(--ih-space-3) var(--ih-space-4);
  max-width: 1100px;
  margin: 0 auto;
}

.ih-brand {
  display: inline-flex;
  align-items: center;
  gap: var(--ih-space-2);
  font-weight: var(--ih-weight-bold);
  text-decoration: none;
  color: var(--ih-text);
  font-size: var(--ih-text-h3);
}
.ih-brand:hover { text-decoration: none; }
.ih-brand-mark { color: var(--ih-brand); flex-shrink: 0; }
/* The real InstallerHub logo (23 Sep 2026), replacing the old house SVG
   mark — about 30px, round, and never stretched off its own aspect ratio. */
.ih-brand-logo {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  object-fit: cover;
}

.ih-header-actions { display: flex; align-items: center; gap: var(--ih-space-1); }

.ih-logout-form { margin: 0; }

/* Phones: a CSS-only <details>/<summary> menu, closed until tapped, no JS.
   Wide screens: a separate horizontal tab bar (.ih-nav-wide). */
.ih-nav-toggle { border-top: 1px solid var(--ih-border); }

.ih-nav-summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: var(--ih-touch);
  padding: 0 var(--ih-space-4);
  font-size: var(--ih-text-body);
  font-weight: var(--ih-weight-medium);
  color: var(--ih-text);
}
.ih-nav-summary::-webkit-details-marker { display: none; }
.ih-nav-summary-label { display: inline-flex; align-items: center; gap: var(--ih-space-2); }
.ih-nav-chevron { transition: transform var(--ih-duration-fast) var(--ih-ease-standard); }
.ih-nav-toggle[open] .ih-nav-chevron { transform: rotate(180deg); }

.ih-nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--ih-space-1) var(--ih-space-2) var(--ih-space-3);
}

.ih-nav a {
  display: flex;
  align-items: center;
  min-height: var(--ih-touch);
  padding: 0 var(--ih-space-3);
  border-radius: var(--ih-radius-sm);
  text-decoration: none;
  color: var(--ih-text-muted);
  font-weight: var(--ih-weight-medium);
  font-size: var(--ih-text-body);
  white-space: nowrap;
}
.ih-nav a:hover, .ih-nav a:focus-visible { background: var(--ih-bg); color: var(--ih-text); text-decoration: none; }
.ih-nav a[aria-current="page"] { color: var(--ih-accent); font-weight: var(--ih-weight-semibold); }

/* The wide tab bar and the phone menu are two copies of the same links
   (layout.php); exactly one is shown at any width. */
.ih-nav-wide { display: none; }

@media (min-width: 700px) {
  .ih-nav-toggle { display: none; }
  .ih-nav.ih-nav-wide {
    display: flex !important;
    flex-direction: row;
    overflow-x: auto;
    gap: var(--ih-space-1);
    padding: 0 var(--ih-space-4) var(--ih-space-2);
    max-width: 1100px;
    margin: 0 auto;
  }
  .ih-nav a { flex: 0 0 auto; border-bottom: 3px solid transparent; border-radius: var(--ih-radius-sm) var(--ih-radius-sm) 0 0; }
  .ih-nav a[aria-current="page"] { border-bottom-color: var(--ih-brand); }
}

/* ── Public site shell ──────────────────────────────────────────────── */

.ih-public-header { border-bottom: 1px solid var(--ih-border); background: var(--ih-surface); }
.ih-public-header-bar { display: flex; align-items: center; justify-content: space-between; max-width: 1100px; margin: 0 auto; padding: var(--ih-space-4); }
.ih-public-footer { border-top: 1px solid var(--ih-border); margin-top: var(--ih-space-8); }
.ih-public-footer-bar { max-width: 1100px; margin: 0 auto; padding: var(--ih-space-5) var(--ih-space-4); color: var(--ih-text-muted); font-size: var(--ih-text-caption); }

/* ── Flash messages ──────────────────────────────────────────────────── */

.ih-flash {
  display: flex;
  align-items: flex-start;
  gap: var(--ih-space-2);
  padding: var(--ih-space-3) var(--ih-space-4);
  border-radius: var(--ih-radius-md);
  box-shadow: var(--ih-shadow-md);
  margin-bottom: var(--ih-space-4);
  font-size: var(--ih-text-body);
}
.ih-flash-ok   { background: var(--ih-success-bg); color: var(--ih-success); }
.ih-flash-warn { background: var(--ih-warning-bg); color: var(--ih-warning); }
.ih-flash-bad, .ih-error {
  background: var(--ih-danger-bg);
  color: var(--ih-danger);
  padding: var(--ih-space-3) var(--ih-space-4);
  border-radius: var(--ih-radius-md);
}
.ih-error { display: block; margin-bottom: var(--ih-space-3); font-size: var(--ih-text-body); }
/* An error paragraph that starts `hidden` and is toggled by inline script
   (not a PHP conditional) — form_homeowner.php's #ih-form-error,
   form_installer.php's #ih-apply-error — must not render as an empty
   coloured bar before that script runs. `.ih-error { display: block }`
   otherwise ties the browser's default [hidden]{display:none} on
   specificity and wins because it loads later. */
.ih-error[hidden] { display: none; }
/* New — a fourth, neutral-informational flash variant alongside ok/warn/
   bad: reads as "for your information", not a success/warning/error state
   (board_queue.php's read-only explainer). */
.ih-flash-info { background: var(--ih-info-bg); color: var(--ih-info); }

/* ── Cards ───────────────────────────────────────────────────────────── */

.ih-card {
  background: var(--ih-surface);
  border: 1px solid var(--ih-border); /* decorative hairline, exempt under WCAG 1.4.11 — see docs/DESIGN.md */
  border-radius: var(--ih-radius-md);
  padding: var(--ih-space-4);
  margin-bottom: var(--ih-space-5);
}

.ih-card > h2:first-child, .ih-card > h3:first-child { margin-top: 0; }

.ih-card-list { display: flex; flex-direction: column; gap: var(--ih-space-3); }

/* ── Option cards (23 Sep 2026) ────────────────────────────────────────
   Two large picture-and-text radio cards — Settings → Automatic running's
   "Automatic" vs "Check each lead first" choice. The radio is a real,
   visible input (never hidden), so it stays keyboard- and screen-reader-
   accessible on its own; :has() adds the picked-card highlight as a
   progressive enhancement, and input:focus-visible (already styled
   globally, below) is the fallback where :has() is not supported. The
   radio sits inside a <span>, not as a direct child of the <label>, so it
   never matches the earlier ".ih-form label:has(> input...)" row rule. */
.ih-option-cards { display: flex; flex-wrap: wrap; gap: var(--ih-space-4); margin-bottom: var(--ih-space-4); }
.ih-option-card {
  flex: 1 1 240px;
  display: flex;
  flex-direction: column;
  gap: var(--ih-space-2);
  padding: var(--ih-space-3);
  border: 1.5px solid var(--ih-border-strong);
  border-radius: var(--ih-radius-md);
  background: var(--ih-surface);
  cursor: pointer;
  font-weight: var(--ih-weight-regular);
  color: var(--ih-text);
}
.ih-option-card-head { display: flex; align-items: center; gap: var(--ih-space-2); }
.ih-option-card-title { font-size: var(--ih-text-strong); font-weight: var(--ih-weight-semibold); color: var(--ih-text); }
.ih-option-card img { display: block; width: 100%; height: auto; aspect-ratio: 5 / 2; object-fit: cover; border: 1px solid var(--ih-border); border-radius: var(--ih-radius-sm); background: var(--ih-surface); }
.ih-option-card-line { font-size: var(--ih-text-caption); line-height: var(--ih-leading-caption); color: var(--ih-text-muted); }
.ih-option-card:has(input:checked) { border-color: var(--ih-accent); box-shadow: 0 0 0 1px var(--ih-accent); background: var(--ih-info-bg); }
@media (max-width: 639px) { .ih-option-cards { flex-direction: column; } }

/* A short plain numbered list ("What happens automatically") — ordinary
   markers (display:flex would suppress them), just the card's own
   spacing and body-text colour. */
.ih-help-steps { margin: var(--ih-space-2) 0 var(--ih-space-4); padding-left: var(--ih-space-5); color: var(--ih-text); }
.ih-help-steps li + li { margin-top: var(--ih-space-1); }

/* ── Page explainers (23 Sep 2026) ─────────────────────────────────────
   A closed-by-default disclosure with a small thumbnail, used at the top
   of a working page (Queue, Applications, a member's page) to show one
   of the illustration stickers as "how this works" without pushing the
   real content down — the summary row stays one compact line closed. */
.ih-explainer { margin-bottom: var(--ih-space-5); }
.ih-explainer-summary {
  display: flex;
  align-items: center;
  gap: var(--ih-space-2);
  list-style: none;
  cursor: pointer;
  padding: var(--ih-space-2) var(--ih-space-3);
  border: 1px solid var(--ih-border);
  border-radius: var(--ih-radius-md);
  background: var(--ih-surface);
  font-size: var(--ih-text-body);
  font-weight: var(--ih-weight-medium);
  color: var(--ih-text);
}
.ih-explainer-summary::-webkit-details-marker { display: none; }
.ih-explainer-summary img { width: 120px; height: 68px; object-fit: cover; border-radius: var(--ih-radius-sm); flex-shrink: 0; border: 1px solid var(--ih-border); }
@media (max-width: 480px) { .ih-explainer-summary img { width: 80px; height: 45px; } }
.ih-explainer-chevron { margin-left: auto; transition: transform var(--ih-duration-fast) var(--ih-ease-standard); flex-shrink: 0; }
.ih-explainer[open] .ih-explainer-chevron { transform: rotate(180deg); }
.ih-explainer-body { padding: var(--ih-space-3); border: 1px solid var(--ih-border); border-top: none; border-radius: 0 0 var(--ih-radius-md) var(--ih-radius-md); background: var(--ih-surface); }
.ih-explainer-body img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; border-radius: var(--ih-radius-sm); border: 1px solid var(--ih-border); }
.ih-explainer-caption { margin: var(--ih-space-2) 0 0; font-size: var(--ih-text-caption); line-height: var(--ih-leading-caption); color: var(--ih-text-muted); }

/* ── Page header (new) ──────────────────────────────────────────────── */

.ih-page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--ih-space-4);
  margin-bottom: var(--ih-space-6);
}
.ih-page-head h1 { margin-bottom: var(--ih-space-1); }
.ih-page-head-lead { margin: 0; color: var(--ih-text-muted); font-size: var(--ih-text-body); }
.ih-page-head-actions { display: flex; gap: var(--ih-space-2); flex-wrap: wrap; }
@media (max-width: 640px) {
  .ih-page-head-actions { width: 100%; }
  .ih-page-head-actions .ih-btn { flex: 1 1 auto; }
}

/* ── Section heading (new) ─────────────────────────────────────────── */

.ih-section-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--ih-space-3); margin-bottom: var(--ih-space-3); }
.ih-section-head h2, .ih-section-head h3 { margin: 0; }

/* ── Badges ──────────────────────────────────────────────────────────── */

.ih-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--ih-space-1);
  padding: 2px var(--ih-space-2);
  border-radius: var(--ih-radius-pill);
  font-size: var(--ih-text-caption);
  font-weight: var(--ih-weight-semibold);
  line-height: var(--ih-leading-caption);
  background: var(--ih-bg);
  color: var(--ih-text-muted);
  white-space: nowrap;
}
.ih-badge-ok   { background: var(--ih-success-bg); color: var(--ih-success); }
.ih-badge-warn { background: var(--ih-warning-bg); color: var(--ih-warning); }
.ih-badge-bad  { background: var(--ih-danger-bg);  color: var(--ih-danger); }
.ih-badge-info { background: var(--ih-info-bg);    color: var(--ih-info); } /* new — neutral statuses: "Waiting to send", "Reviewed" */

/* ── Buttons ─────────────────────────────────────────────────────────── */

.ih-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--ih-space-2);
  min-height: var(--ih-touch);
  padding: 0 var(--ih-space-4);
  border-radius: var(--ih-radius-sm);
  border: 1px solid var(--ih-border-strong);
  background: var(--ih-surface);
  color: var(--ih-text);
  font-family: inherit;
  font-size: var(--ih-text-button);
  font-weight: var(--ih-weight-semibold);
  line-height: var(--ih-leading-button);
  text-decoration: none;
  cursor: pointer;
  transition: background var(--ih-duration-fast) var(--ih-ease-standard), border-color var(--ih-duration-fast) var(--ih-ease-standard);
}
.ih-btn:hover { background: var(--ih-bg); text-decoration: none; }

.ih-btn-primary {
  background: var(--ih-accent);
  border-color: var(--ih-accent);
  color: var(--ih-accent-contrast);
}
.ih-btn-primary:hover { background: var(--ih-brand); border-color: var(--ih-brand); }

/* Routine, reversible negative actions (Fail, Decline) — outline, never a
   solid fill, so they read lighter than a genuinely irreversible action. */
.ih-btn-danger {
  background: var(--ih-surface);
  border-color: var(--ih-danger);
  color: var(--ih-danger);
}
.ih-btn-danger:hover { background: var(--ih-danger-bg); }

/* New — reserved for genuinely irreversible actions only: erase personal
   data, end membership, rotate the Make secret. Always behind a confirm
   step. Visually heavier than .ih-btn-danger so the two registers are
   never confused. */
.ih-btn-danger-solid {
  background: var(--ih-danger-solid);
  border-color: var(--ih-danger-solid);
  color: var(--ih-accent-contrast);
}
.ih-btn-danger-solid:hover { filter: brightness(0.92); }

/* New — a lower-emphasis variant sitting below the outline secondary. */
.ih-btn-ghost {
  background: transparent;
  border-color: transparent;
  color: var(--ih-accent);
}
.ih-btn-ghost:hover { background: var(--ih-bg); }

/* New — a smaller control for dense rows (table action cells, toolbars). */
.ih-btn-sm { min-height: 36px; padding: 0 var(--ih-space-3); font-size: var(--ih-text-caption); border-radius: var(--ih-radius-sm); }

.ih-link-btn {
  display: inline-flex;
  align-items: center;
  background: none;
  border: none;
  color: var(--ih-accent);
  min-height: var(--ih-touch);
  padding: 0 var(--ih-space-2);
  cursor: pointer;
  font-family: inherit;
  font-size: var(--ih-text-body);
}
.ih-link-btn:hover { text-decoration: underline; }

/* ── Forms ───────────────────────────────────────────────────────────── */

.ih-form { display: flex; flex-direction: column; gap: var(--ih-space-3); max-width: 480px; }

.ih-form label {
  display: flex;
  flex-direction: column;
  gap: var(--ih-space-1);
  font-size: var(--ih-text-body);
  font-weight: var(--ih-weight-medium);
  color: var(--ih-text-muted);
  min-width: 0; /* flex-child auto min-size otherwise refuses to shrink below a long control's content */
}

/* A label whose only job is to pair one checkbox/radio with its text
   reads better as a row — matches the row markup already used throughout
   the app (form_homeowner.php's radios, upload.php's checkboxes, etc.). */
.ih-form label:has(> input[type="checkbox"]),
.ih-form label:has(> input[type="radio"]) {
  flex-direction: row;
  align-items: center;
  gap: var(--ih-space-2);
  font-weight: var(--ih-weight-regular);
  color: var(--ih-text);
}

.ih-form fieldset {
  border: 1px solid var(--ih-border);
  border-radius: var(--ih-radius-md);
  padding: var(--ih-space-3) var(--ih-space-4);
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--ih-space-2);
  min-width: 0; /* overrides the browser default fieldset min-width: min-content, which otherwise refuses to shrink below a long <select> option's intrinsic width and pushes the page wider than the phone viewport */
}
.ih-form legend { padding: 0 var(--ih-space-1); font-size: var(--ih-text-caption); font-weight: var(--ih-weight-medium); color: var(--ih-text-muted); }

.ih-form input,
.ih-form select,
.ih-form textarea,
input, select, textarea {
  min-height: var(--ih-touch);
  padding: var(--ih-space-2) var(--ih-space-3);
  border: 1px solid var(--ih-border-strong); /* the border IS the only cue here — 3.39:1, passes the 3:1 UI-boundary bar */
  border-radius: var(--ih-radius-sm);
  font-size: var(--ih-text-body); /* 16px floor: keeps iOS Safari from zooming on focus */
  font-family: inherit;
  color: var(--ih-text);
  background: var(--ih-surface);
}

.ih-form textarea, textarea { min-height: calc(var(--ih-touch) * 2); resize: vertical; }

select[multiple] { min-height: 120px; padding: var(--ih-space-2); }

input[type="file"] { min-height: auto; border: 1px dashed var(--ih-border-strong); padding: var(--ih-space-3); max-width: 100%; }

input[readonly] { background: var(--ih-bg); color: var(--ih-text-muted); }

/* Custom checkbox/radio — real inputs, CSS-only, no markup change needed
   anywhere in the app. */
input[type="checkbox"], input[type="radio"] {
  appearance: none;
  -webkit-appearance: none;
  width: 20px;
  height: 20px;
  min-width: 20px;
  min-height: 20px;
  padding: 0;
  border: 1.5px solid var(--ih-border-strong);
  border-radius: 4px;
  background: var(--ih-surface);
  display: inline-block;
  flex-shrink: 0;
  position: relative;
  cursor: pointer;
  vertical-align: middle;
}
input[type="radio"] { border-radius: 50%; }
input[type="checkbox"]:checked, input[type="radio"]:checked {
  background: var(--ih-accent);
  border-color: var(--ih-accent);
}
input[type="checkbox"]:checked::after {
  content: "";
  position: absolute;
  left: 6px; top: 2px;
  width: 5px; height: 10px;
  border-right: 2px solid var(--ih-accent-contrast);
  border-bottom: 2px solid var(--ih-accent-contrast);
  transform: rotate(45deg);
}
input[type="radio"]:checked::after {
  content: "";
  position: absolute;
  left: 50%; top: 50%;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--ih-accent-contrast);
  transform: translate(-50%, -50%);
}

/* The consent checkbox + its wording, as one readable row (form_homeowner.php). */
.ih-consent-label { display: flex; flex-direction: row; align-items: flex-start; gap: var(--ih-space-2); }
.ih-consent { font-size: var(--ih-text-caption); line-height: var(--ih-leading-caption); color: var(--ih-text-muted); }

/* New — form layout primitives for screen agents rebuilding a view's markup. */
.ih-field { display: flex; flex-direction: column; gap: var(--ih-space-1); margin-bottom: var(--ih-space-3); }
.ih-field-row { display: flex; flex-wrap: wrap; gap: var(--ih-space-3); }
.ih-field-row .ih-field { flex: 1 1 160px; margin-bottom: 0; }
.ih-help { margin: var(--ih-space-1) 0 0; font-size: var(--ih-text-caption); color: var(--ih-text-muted); }
.ih-check { display: flex; flex-direction: row; align-items: center; gap: var(--ih-space-2); font-size: var(--ih-text-body); color: var(--ih-text); font-weight: var(--ih-weight-regular); }

/* New — the multi-select-as-chips pattern (components spec): a real
   checkbox per option, visually hidden, its <label> styled as a toggle
   pill. Same field name/array submitted; screen agents adopt the markup
   when they rebuild a given view's multi-select. */
.ih-chip-list { display: flex; flex-wrap: wrap; gap: var(--ih-space-2); }
.ih-chip {
  display: inline-flex;
  align-items: center;
  min-height: var(--ih-touch);
  padding: 0 var(--ih-space-4);
  border-radius: var(--ih-radius-pill);
  border: 1px solid var(--ih-border-strong);
  background: var(--ih-surface);
  color: var(--ih-text);
  font-size: var(--ih-text-body);
  font-weight: var(--ih-weight-medium);
  cursor: pointer;
  user-select: none;
}
.ih-chip input[type="checkbox"], .ih-chip input[type="radio"] {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.ih-chip:has(input:checked) { background: var(--ih-accent); border-color: var(--ih-accent); color: var(--ih-accent-contrast); }
.ih-chip:has(input:focus-visible) { box-shadow: var(--ih-focus-ring); }

/* ── Toolbars and filter bars (new) ─────────────────────────────────── */

.ih-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--ih-space-3);
  background: var(--ih-surface);
  border: 1px solid var(--ih-border);
  border-radius: var(--ih-radius-md);
  padding: var(--ih-space-4);
  margin-bottom: var(--ih-space-5);
}
.ih-toolbar .ih-field { margin-bottom: 0; min-width: 140px; flex: 1 1 160px; }
.ih-toolbar .ih-btn { align-self: flex-end; }

/* ── Tables that collapse to cards on narrow screens ────────────────── */

/* .ih-table-stack is the same responsive table component as .ih-table,
   named explicitly for new markup — see docs/DESIGN.md. Both rely on a
   data-label attribute on every <td>, already present throughout the app. */
.ih-table, .ih-table-stack { width: 100%; border-collapse: collapse; }

.ih-table th, .ih-table td,
.ih-table-stack th, .ih-table-stack td {
  text-align: left;
  padding: var(--ih-space-2) var(--ih-space-2);
  border-bottom: 1px solid var(--ih-border);
  font-size: var(--ih-text-caption);
}

.ih-table th, .ih-table-stack th {
  color: var(--ih-text-muted);
  font-weight: var(--ih-weight-semibold);
  background: var(--ih-surface-raised);
}

@media (min-width: 700px) {
  .ih-table tbody tr:nth-child(even),
  .ih-table-stack tbody tr:nth-child(even) { background: var(--ih-bg); }
}

@media (max-width: 699px) {
  .ih-table thead, .ih-table-stack thead { display: none; }
  .ih-table, .ih-table tbody, .ih-table tr, .ih-table td,
  .ih-table-stack, .ih-table-stack tbody, .ih-table-stack tr, .ih-table-stack td { display: block; width: 100%; }
  .ih-table tr, .ih-table-stack tr {
    border: 1px solid var(--ih-border);
    border-radius: var(--ih-radius-md);
    margin-bottom: var(--ih-space-3);
    padding: var(--ih-space-2) var(--ih-space-3);
    background: var(--ih-surface);
  }
  .ih-table td, .ih-table-stack td {
    border-bottom: none;
    padding: var(--ih-space-2) 0;
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: var(--ih-space-3);
    text-align: right;
  }
  .ih-table td::before, .ih-table-stack td::before {
    content: attr(data-label);
    font-weight: var(--ih-weight-semibold);
    color: var(--ih-text-muted);
    flex: 0 0 auto;
    text-align: left;
  }
  /* Inline per-row forms/actions must never force the card wider than the
     viewport (board_rules: "inline forms that never overflow their card"). */
  .ih-table td form, .ih-table-stack td form { display: inline-flex; flex-wrap: wrap; gap: var(--ih-space-1); max-width: 60%; justify-content: flex-end; }
}

/* Any form dropped inside a card or list must stay inside it. */
.ih-card form, .ih-card-list form { max-width: 100%; }

/* ── Stat tiles (new) ────────────────────────────────────────────────── */

.ih-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: var(--ih-space-3); margin-bottom: var(--ih-space-5); }
.ih-stat { background: var(--ih-surface); border: 1px solid var(--ih-border); border-radius: var(--ih-radius-md); padding: var(--ih-space-3) var(--ih-space-4); }
.ih-stat-value { display: block; font-size: var(--ih-text-h1); line-height: var(--ih-leading-h1); font-weight: var(--ih-weight-bold); color: var(--ih-text); }
.ih-stat-label { display: block; margin-top: var(--ih-space-1); font-size: var(--ih-text-caption); line-height: var(--ih-leading-caption); font-weight: var(--ih-weight-medium); color: var(--ih-text-muted); }

/* ── Key-value lists (new) ──────────────────────────────────────────── */

.ih-dl { display: grid; grid-template-columns: max-content 1fr; gap: var(--ih-space-2) var(--ih-space-4); margin: 0; }
.ih-dl dt { font-size: var(--ih-text-caption); font-weight: var(--ih-weight-medium); color: var(--ih-text-muted); }
.ih-dl dd { margin: 0; min-width: 0; overflow-wrap: anywhere; font-size: var(--ih-text-body); color: var(--ih-text); }

/* .ih-dl-stack (Connections "Addresses to give Meta, Stripe and Make", 23
   Sep 2026): a dd here can run to a full sentence plus a link, sometimes
   a code list too — on a narrow screen the plain .ih-dl two-column grid
   squeezes that into a sliver next to a long dt (e.g. "Make.com –
   application HTTP module"), wrapping one word per line. Below 700px this
   modifier stacks dt above its own dd, full width, instead. */
@media (max-width: 699px) {
  .ih-dl-stack { grid-template-columns: 1fr; }
  .ih-dl-stack dt { margin-top: var(--ih-space-3); }
  .ih-dl-stack dt:first-child { margin-top: 0; }
}

/* ── Empty states (new) ─────────────────────────────────────────────── */

.ih-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--ih-space-2);
  padding: var(--ih-space-5);
  color: var(--ih-text-muted);
}
.ih-empty .ih-icon { width: 32px; height: 32px; opacity: 0.6; }

/* ── Timeline (new) ──────────────────────────────────────────────────── */

.ih-timeline { list-style: none; margin: 0; padding: 0 0 0 var(--ih-space-1); border-left: 2px solid var(--ih-border); }
.ih-timeline li { position: relative; padding: 0 0 var(--ih-space-4) var(--ih-space-4); font-size: var(--ih-text-caption); }
.ih-timeline li::before {
  content: "";
  position: absolute;
  left: -5px; top: 4px;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--ih-accent);
  box-shadow: 0 0 0 2px var(--ih-surface);
}
.ih-timeline li:last-child { padding-bottom: 0; }
.ih-timeline-when { display: block; color: var(--ih-text-muted); }

/* ── Tappable rows and item rows (new — leads/queue/today screens) ───── */

/* A whole work item as one tappable row — link + a short meta line, with
   a trailing chevron — instead of a small text link sitting inside a
   sentence. Used for Today's Awaiting approval / Unmatched /
   Under-supplied / Classification holds rows, and for a lead's Child
   leads list. Works as either an <a> (the usual case) or a plain <div>
   for a row that has nowhere to link. */
.ih-work-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ih-space-3);
  min-height: var(--ih-touch);
  padding: var(--ih-space-3) var(--ih-space-4);
  border: 1px solid var(--ih-border);
  border-radius: var(--ih-radius-md);
  background: var(--ih-surface);
  color: var(--ih-text);
}
a.ih-work-row { cursor: pointer; }
a.ih-work-row:hover { border-color: var(--ih-border-strong); background: var(--ih-bg); text-decoration: none; }
.ih-work-row-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; overflow-wrap: anywhere; }
.ih-work-row-title { font-weight: var(--ih-weight-semibold); color: var(--ih-text); }
.ih-work-row-chevron { color: var(--ih-text-muted); flex-shrink: 0; }

/* A row with context on the left and one action (often a small form) on
   the right — never lets the action get lost in a run-on sentence. Rows
   stack full width and the action drops below the context on phone. */
.ih-item-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--ih-space-2) var(--ih-space-3);
  padding: var(--ih-space-3) 0;
}
.ih-item-row + .ih-item-row { border-top: 1px solid var(--ih-border); }
.ih-item-row form { margin: 0; }

/* Small inline groupings — an icon with its text, or a run of short
   badges/links that should wrap together as one unit. */
.ih-inline { display: flex; align-items: center; gap: var(--ih-space-2); }
.ih-inline-wrap { display: flex; align-items: center; flex-wrap: wrap; gap: var(--ih-space-1) var(--ih-space-2); }

/* The single decision on a lead page — Approve and send — set apart from
   the routine secondary actions around it with a tinted panel, using the
   existing informational tint rather than a new colour. */
.ih-decision {
  margin-top: var(--ih-space-4);
  padding: var(--ih-space-4);
  border: 1px solid var(--ih-brand);
  border-radius: var(--ih-radius-md);
  background: var(--ih-info-bg);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--ih-space-2);
}
.ih-decision p { margin: 0; }

/* Visually separates a genuinely irreversible action from the routine
   actions above it — pairs with .ih-btn-danger-solid. Used on the
   lead page (Delete now/erasure) and the settings page (Rotate Make
   secret, in its own card). */
.ih-danger-zone {
  margin-top: var(--ih-space-4);
  padding-top: var(--ih-space-4);
  border-top: 1px solid var(--ih-danger-solid);
}
.ih-danger-zone form { margin: 0; }

/* ── Settings/Users/Import/Sends/Inbox/Account additions (new) ───────── */

/* A quick "jump to a section" row of small links at the top of a long
   settings-style page. */
.ih-jump {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ih-space-2);
}

/* A round initial avatar for the account identity block. */
.ih-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  min-width: 48px;
  border-radius: 50%;
  background: var(--ih-info-bg);
  color: var(--ih-info);
  font-weight: var(--ih-weight-bold);
  font-size: var(--ih-text-h3);
  flex-shrink: 0;
}

/* The one-time password-set link: shown once, sensitive, meant to be
   copied and sent — visually distinct from a routine readonly field. */
.ih-issued-link {
  display: flex;
  align-items: center;
  gap: var(--ih-space-2);
  border-left: 3px solid var(--ih-accent);
  background: var(--ih-info-bg);
  border-radius: var(--ih-radius-sm);
  padding: var(--ih-space-2) var(--ih-space-3);
}
.ih-issued-link input {
  flex: 1 1 auto;
  border-style: dashed;
  background: var(--ih-surface);
}

/* A chronological message list (Inbox) — lighter than a full card per
   message. */
.ih-msg { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0; }
.ih-msg-item { padding: var(--ih-space-3) 0; border-bottom: 1px solid var(--ih-border); }
.ih-msg-item:last-child { border-bottom: none; }
.ih-msg-meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ih-space-2); color: var(--ih-text-muted); font-size: var(--ih-text-caption); margin-bottom: var(--ih-space-1); }
.ih-msg-from { font-weight: var(--ih-weight-semibold); color: var(--ih-text); }
.ih-msg-text { margin: var(--ih-space-1) 0 var(--ih-space-2); font-size: var(--ih-text-body); color: var(--ih-text); }
.ih-msg-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ih-space-1); }

/* CSV paste areas read better in a monospace face — a system stack, no
   webfont. */
.ih-mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  font-size: var(--ih-text-caption);
}

/* A plain "Step X of Y" caption above a multi-step flow (CSV import). */
.ih-step { display: inline-flex; align-items: center; gap: var(--ih-space-1); color: var(--ih-text-muted); font-size: var(--ih-text-caption); font-weight: var(--ih-weight-semibold); text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: var(--ih-space-2); }

/* A clean label:value summary list, replacing a bare bulleted <ul> for
   import result counts. */
.ih-summary { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--ih-space-1); }
.ih-summary li { display: flex; justify-content: space-between; gap: var(--ih-space-3); padding: var(--ih-space-1) 0; border-bottom: 1px solid var(--ih-border); font-size: var(--ih-text-body); }
.ih-summary li:last-child { border-bottom: none; }

/* ── Public/auth screen additions (new) ───────────────────────────────── */

/* A single-purpose page (log in, choose password, forgotten password,
   an expired link) reads better as one narrow, centred card than the
   full page width every other .ih-card gets. */
.ih-auth-card { max-width: 440px; margin: 0 auto; }

/* Secondary help copy below a primary form action — visually separated
   so the one thing to do (the form above) stays the obvious next tap. */
.ih-auth-help { margin-top: var(--ih-space-4); padding-top: var(--ih-space-4); border-top: 1px solid var(--ih-border); }
.ih-auth-help p { margin: 0 0 var(--ih-space-2); color: var(--ih-text-muted); font-size: var(--ih-text-caption); line-height: var(--ih-leading-caption); }
.ih-auth-help p:last-child { margin-bottom: 0; }

/* A dead-end confirmation or "this link doesn't work" page: centred icon
   above the heading, generous breathing room, one link out. */
.ih-state-card { text-align: center; padding: var(--ih-space-6) var(--ih-space-4); }
.ih-state-card h1 { margin-top: var(--ih-space-3); }
.ih-state-card p { max-width: 46ch; margin-left: auto; margin-right: auto; }
.ih-state-icon-wrap {
  display: inline-flex; align-items: center; justify-content: center;
  width: 56px; height: 56px; border-radius: 50%;
  background: var(--ih-info-bg);
}
.ih-state-icon-wrap.ih-state-icon-ok { background: var(--ih-success-bg); }
.ih-state-icon-wrap .ih-icon { width: 28px; height: 28px; }
.ih-state-icon-wrap.ih-state-icon-ok .ih-icon { color: var(--ih-success); }
.ih-state-icon-wrap:not(.ih-state-icon-ok) .ih-icon { color: var(--ih-info); }

/* "What happens next" steps for a multi-stage public flow (apply then
   upload documents then review). Reuses the visual language of
   .ih-timeline rather than inventing a new rail. */
.ih-steps { list-style: none; margin: var(--ih-space-4) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--ih-space-3); text-align: left; }
.ih-steps li { display: flex; align-items: flex-start; gap: var(--ih-space-3); }
.ih-step-num {
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--ih-info-bg); color: var(--ih-info);
  font-size: var(--ih-text-caption); font-weight: var(--ih-weight-semibold);
}
.ih-steps li.ih-step-done .ih-step-num { background: var(--ih-success-bg); color: var(--ih-success); }

/* A short trust strip under a public form's intro — plain reassurance
   copy, no invented statistics, same card system as everywhere else. */
.ih-trust-row { display: flex; flex-wrap: wrap; gap: var(--ih-space-4); margin: var(--ih-space-4) 0 var(--ih-space-5); padding: var(--ih-space-3) var(--ih-space-4); background: var(--ih-surface); border: 1px solid var(--ih-border); border-radius: var(--ih-radius-md); }
.ih-trust-row > div { display: flex; align-items: center; gap: var(--ih-space-2); font-size: var(--ih-text-caption); color: var(--ih-text-muted); }
.ih-trust-row .ih-icon { color: var(--ih-accent); width: 18px; height: 18px; }

/* Section grouping inside a long public form (contact details / the job /
   consent) without changing a single field. Flex column + gap so the
   fields inside a section keep the same rhythm .ih-form gives its direct
   children even though they now sit one level deeper. */
.ih-form-section { display: flex; flex-direction: column; gap: var(--ih-space-3); }
.ih-form-section + .ih-form-section { margin-top: var(--ih-space-1); padding-top: var(--ih-space-4); border-top: 1px solid var(--ih-border); }
.ih-form-section-title { margin: 0; font-size: var(--ih-text-caption); font-weight: var(--ih-weight-semibold); color: var(--ih-text-muted); text-transform: uppercase; letter-spacing: 0.04em; }

/* A short "already received" document checklist (upload.php). */
.ih-doc-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--ih-space-2); }
.ih-doc-list li { display: flex; align-items: center; gap: var(--ih-space-2); font-size: var(--ih-text-body); }
.ih-doc-list .ih-icon { color: var(--ih-success); flex-shrink: 0; }

/* The approve page's candidate list: name first, the two detail fragments
   muted below it, each candidate its own tappable-looking row. */
.ih-candidate-list { list-style: none; margin: 0 0 var(--ih-space-4); padding: 0; display: flex; flex-direction: column; gap: var(--ih-space-2); }
.ih-candidate-list li { padding: var(--ih-space-3); border: 1px solid var(--ih-border); border-radius: var(--ih-radius-md); background: var(--ih-surface); }
.ih-candidate-name { display: block; font-size: var(--ih-text-strong); font-weight: var(--ih-weight-semibold); color: var(--ih-text); }
.ih-candidate-meta { display: block; margin-top: 2px; font-size: var(--ih-text-caption); color: var(--ih-text-muted); }

/* ── Focus, motion and print ────────────────────────────────────────── */

a:focus-visible, button:focus-visible, summary:focus-visible,
input:focus-visible, select:focus-visible, textarea:focus-visible,
.ih-btn:focus-visible, .ih-link-btn:focus-visible, .ih-chip:has(input:focus-visible) {
  outline: none;
  box-shadow: var(--ih-focus-ring);
  border-radius: var(--ih-radius-sm);
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

@media print {
  .ih-header, .ih-nav-toggle, .ih-nav-wide, .ih-btn, .ih-link-btn, .ih-public-footer, form { display: none !important; }
  body { background: var(--ih-surface); color: var(--ih-text); }
  .ih-card { border: 1px solid var(--ih-border-strong); box-shadow: none; break-inside: avoid; }
  a { color: var(--ih-text); text-decoration: underline; }
}

/* ── Board data grid (Builder E2, /board/data, 23 Sep 2026) ───────────
   An Airtable-like read-only grid over Members/Memberships/Leads/
   Applications/Sends/Payments. Unlike .ih-table (which stacks into a
   card per row below 700px — right for a short record list, wrong for a
   wide grid where scanning several columns at once is the whole point),
   this keeps its real table shape at every width and instead sits inside
   a horizontally scrolling wrapper, so the row/column grid can be
   scanned sideways without the page itself ever scrolling sideways on a
   phone. Same tokens as everywhere else on the board — no new colours,
   nothing hard-coded. This is the only block this file's owner (Builder
   E2) appends; every rule above this comment belongs to other views. */
.ih-data-tabs { display: flex; flex-wrap: wrap; gap: var(--ih-space-4); border-bottom: 1px solid var(--ih-border); margin-bottom: var(--ih-space-5); }
.ih-data-tab { padding: var(--ih-space-2) 0; color: var(--ih-text-muted); font-weight: var(--ih-weight-semibold); font-size: var(--ih-text-body); text-decoration: none; border-bottom: 3px solid transparent; }
.ih-data-tab:hover { color: var(--ih-text); }
.ih-data-tab-active { color: var(--ih-accent); border-bottom-color: var(--ih-brand); }

.ih-data-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; border: 1px solid var(--ih-border); border-radius: var(--ih-radius-md); background: var(--ih-surface); margin-bottom: var(--ih-space-4); }
.ih-data-scroll table.ih-table { min-width: 640px; margin: 0; }
.ih-data-scroll table.ih-table thead { display: table-header-group; }
.ih-data-scroll table.ih-table tbody { display: table-row-group; }
.ih-data-scroll table.ih-table tr { display: table-row; border: 0; margin: 0; padding: 0; background: none; }
.ih-data-scroll table.ih-table th, .ih-data-scroll table.ih-table td { display: table-cell; text-align: left; white-space: nowrap; }
.ih-data-scroll table.ih-table td::before { content: none; }
.ih-data-scroll table.ih-table th a { color: inherit; text-decoration: none; }
.ih-data-scroll table.ih-table th a:hover { color: var(--ih-accent); }

/* ── Long unbroken text (23 Sep 2026) ──────────────────────────────────
   Real research logs full web addresses in the timeline and cards; without
   this a single long URL widened the whole page on a 390 px phone. */
.ih-card { overflow-wrap: break-word; }
.ih-timeline li, .ih-card-list, .ih-dl dd { overflow-wrap: anywhere; min-width: 0; }

/* ── Information widget (23 Sep 2026) ──────────────────────────────────
   The "i" button rendered by ih_info() (app/_help.php) — sits inline
   after a heading, label or button so Josh can hover (desktop) or tap
   (phone) to read what the thing does. Behaviour (toggle on tap, one
   open at a time, close on outside click/Escape/scroll) is
   public_html/assets/info.js. Tokens only, nothing hand-written below.

   .ih-info is an inline positioning anchor only — it never affects the
   surrounding line's height or wrapping, so it is safe straight after
   an <h1>/<h2>/<h3>, a <label> or a <button>. */
.ih-info { position: relative; display: inline-block; line-height: 0; vertical-align: middle; margin-left: var(--ih-space-1); }

.ih-info-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: var(--ih-text-muted);
  color: var(--ih-surface);
  font: italic 600 12px Georgia, "Times New Roman", serif;
  line-height: 1;
  cursor: pointer;
}
/* An invisible 32px+ hit area around an 18px visible circle, for thumbs —
   the pseudo-element overflows the button's own box but clicks landing on
   it still target the button, so this does not change the button's
   layout size or push neighbouring text. */
.ih-info-btn::after {
  content: "";
  position: absolute;
  inset: -7px;
}
.ih-info-btn:hover, .ih-info-btn:focus-visible { background: var(--ih-accent); }
.ih-info-btn:focus-visible {
  outline: none;
  box-shadow: var(--ih-focus-ring);
}

.ih-info-tip {
  display: none;
  position: absolute;
  top: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 40; /* above card content and the sticky header (z-index: 20), so a tip opened near the top of the page is never hidden behind either */
  width: max-content;
  max-width: min(320px, 80vw);
  padding: var(--ih-space-3);
  background: var(--ih-surface-raised);
  border: 1px solid var(--ih-border);
  border-radius: var(--ih-radius-md);
  box-shadow: var(--ih-shadow-md);
  font-size: var(--ih-text-caption);
  line-height: var(--ih-leading-caption);
  font-weight: var(--ih-weight-regular);
  color: var(--ih-text);
  text-align: left;
  white-space: normal;
  cursor: auto;
}
/* Centred under the button is a pragmatic static choice, not a collision
   check — there is no JS positioning dependency here. In practice this
   is safe: every ih_info() call sits inside .ih-main's padded column, and
   the narrow-screen rule below replaces this bubble with a fixed panel
   that is always fully on screen regardless of where the button sits. */

@media (hover: hover) {
  .ih-info:hover .ih-info-tip, .ih-info:focus-within .ih-info-tip { display: block; }
}
.ih-info.is-open .ih-info-tip { display: block; }

@media (max-width: 699px) {
  /* Tap-opened only (.is-open) — hover-and-bubble above does not apply on
     a touch device. A fixed panel near the bottom is always fully on
     screen, whatever the button's own position was. */
  .ih-info.is-open .ih-info-tip {
    position: fixed;
    top: auto;
    left: 16px;
    right: 16px;
    bottom: 16px;
    transform: none;
    width: auto;
    max-width: none;
    max-height: 60vh;
    overflow-y: auto;
    z-index: 50;
  }
}

@media print {
  .ih-info-btn { display: none !important; }
}

/* Automatic vetting (24 Sep 2026): the register-check rows on Today and
   the one-line-per-item Vetting card on an application. */
.ih-register-check {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--ih-space-2) var(--ih-space-3);
  padding: var(--ih-space-3) 0;
}
.ih-register-check + .ih-register-check { border-top: 1px solid var(--ih-border); }
.ih-register-check-actions { display: flex; flex-wrap: wrap; gap: var(--ih-space-2); align-items: center; }
.ih-register-check-actions form { display: flex; gap: var(--ih-space-2); align-items: center; margin: 0; }
.ih-register-check-actions input[type="text"] { min-width: 0; width: 12rem; max-width: 100%; }
.ih-vetting-row {
  display: flex;
  gap: var(--ih-space-3);
  align-items: flex-start;
  padding: var(--ih-space-2) 0;
}
.ih-vetting-row + .ih-vetting-row { border-top: 1px solid var(--ih-border); }
.ih-vetting-row .ih-badge { flex-shrink: 0; min-width: 7.5rem; text-align: center; }
.ih-vetting-row-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; overflow-wrap: anywhere; }
@media (max-width: 560px) {
  .ih-vetting-row { flex-direction: column; gap: var(--ih-space-1); }
  .ih-vetting-row .ih-badge { min-width: 0; }
}

/* The one-tap link after the number has moved (24 Sep 2026): it would send
   from Josh's own WhatsApp, so it carries a plain warning. */
.ih-wa-me-warning { display: block; margin-top: var(--ih-space-1); color: var(--ih-danger, #9b2c2c); font-size: 0.875rem; }
