/* House design tokens, single source of truth for every Direct Connect page.
 *
 * Every page links this file instead of redeclaring hex values in its own
 * <style> block. That duplication is what let a 2.53:1 contrast failure sit
 * unnoticed across four production pages: fixing one file changed nothing.
 * Change a value here and it lands everywhere on the next deploy.
 *
 * Reference doc: areas/operations/design-system.html
 * v2 direction:  deliverables/house-design-system-v2.md, applied across all
 *                 four pages on 25 Jul 2026 (corporate-density board pass).
 *
 * ACCESSIBILITY RULE: every value used for text meets WCAG AA (4.5:1) against
 * the background it sits on. Ratios are stated per token. Do not lighten a
 * text token without recomputing it.
 */
:root{
  /* ---- brand ---------------------------------------------------------- */
  --navy:#16224C;            /* 15.4:1 with white on it */
  --navy-2:#23315f;
  --ink-navy:#0f1733;
  --brand:#E8613C;           /* FILLS AND DECORATION ONLY. 3.38:1 with white
                                on it, 3.27:1 as text. Never put text on it
                                and never use it as text. */
  --brand-solid:#C94726;     /* the text-safe orange: 4.76:1 with white on it,
                                4.59:1 as text on --bg. Use for every button,
                                link and coloured label. */
  --brand-solid-h:#B23A1E;   /* hover for the above */
  --brand-2:#F3954E;         /* 6.74:1 on --navy. Light accent, on navy only. */

  /* ---- neutral ramp, navy tinted -------------------------------------- */
  /* n-400 is the lightest step allowed to carry text. It was #838ba0 in the
     first v2 draft, which measures 3.29:1 and fails, so it is darkened here. */
  --n-0:#ffffff;
  --n-25:#fafbfc;
  --n-50:#f2f4f7;
  --n-100:#e8eaf0;
  --n-200:#dbdee6;
  --n-300:#c2c7d3;           /* 1.69:1. Decorative dividers only. Never text, and
                                never the boundary of a form control. */
  --n-350:#858fa4;           /* 3.25:1 on --card, 3.14:1 on --bg. The lightest
                                step allowed on anything a person must find and
                                operate: input borders, control edges. WCAG
                                1.4.11 wants 3:1 there and --n-300 does not reach
                                it. */
  --n-400:#667085;           /* 4.80:1 on --bg. Lightest text-safe step. */
  --n-500:#5b6577;           /* 5.67:1 */
  --n-600:#434a5c;           /* 8.54:1 */
  --n-700:#333a4d;
  --n-800:#1f2536;           /* 14.7:1 */

  /* ---- semantic roles -------------------------------------------------- */
  --ink:var(--n-800);
  --mut:var(--n-500);
  --faint:var(--n-400);      /* small uppercase field labels. Still text. */
  --line:var(--n-200);       /* 1.35:1 on --card. A card edge is decoration, so
                                this is fine there and wrong on a control. */
  --line-strong:var(--n-350);/* the boundary of anything operable. See --n-350. */
  --bg:var(--n-25);
  --card:var(--n-0);
  --blue-d:#185FA5;          /* 6.30:1. tel and mailto links. */

  /* ---- status, text on its own background ------------------------------ */
  --status-new-bg:#eef0f4;    --status-new-txt:#434a5c;    --status-new-line:#c2c7d3;    /* 7.76:1 unclaimed */
  --status-active-bg:#E1F5EE; --status-active-txt:#04342C; --status-active-line:#5DCAA5; /* 12.1:1 claimed */
  --status-alert-bg:#FCEBEB;  --status-alert-txt:#8E2A2A;  --status-alert-line:#e8a5a5;  /* 7.25:1 escalated */
  --status-off-bg:#F1EFE8;    --status-off-txt:#3a3a36;    --status-off-line:#dedacb;    /* 9.93:1 closed */

  /* ---- spacing -----------------------------------------------------------
   * THERE WAS NO SPACING SCALE, AND THAT IS THE WHOLE STORY OF WHY THESE PAGES
   * READ AS EYE-TUNED RATHER THAN DESIGNED.
   *
   * Colour, type, radius, shadow and focus were all tokenised and genuinely
   * well kept: 214 font-size declarations across four files with zero hardcoded
   * pixel values and zero !important. Every padding, margin and gap was
   * hand-authored anyway. Measured before this file changed: 305 declarations,
   * 29 distinct pixel values, 63% of them off a 4px grid, and every one of the
   * ten integers from 5 to 14 in use.
   *
   * Ten consecutive integers inside a 10px band is the mechanical signature of
   * somebody nudging a number until it looked right, one component at a time,
   * with no rule to appeal to. Nobody can perceive 13px against 14px. What they
   * can perceive is that no two things line up, because 13 and 14 never resolve
   * to the same edge.
   *
   * Six steps. Each is at least 33% from its neighbour, which is the same
   * discipline the type scale already applies and for the same reason: steps
   * that close cannot be read as levels. Pick by role, never by eye.
   *
   *   --s-1  inside a control, between an icon and its label
   *   --s-2  between rows of one list, between a label and its value
   *   --s-3  cell padding, and the vertical half of a card header
   *   --s-4  card padding, and the horizontal half of everything
   *   --s-5  between cards about the same subject
   *   --s-6  between sections about different subjects
   *
   * 1px, 2px and 3px survive and are deliberately not on this scale. They are
   * hairlines, pill insets and knob offsets: they are the shape of a control
   * rather than the space around one, and rounding them to 4px would fatten
   * every pill in the product. */
  --s-1:4px; --s-2:8px; --s-3:12px; --s-4:16px; --s-5:24px; --s-6:32px;

  /* ---- layout ------------------------------------------------------------
   * The content column was 1160px, hardcoded in two places that had to agree
   * and nothing making them. The recovered width buys a right rail rather than
   * a wider reading measure: Twilio, the reference the client chose, does not
   * stretch content, it spends width on structure and keeps the column
   * measured. A 1600px page of 14px prose would be worse than the 1160px one. */
  --shell:1600px;
  --rail:268px;

  /* ---- shape and depth -------------------------------------------------- */
  --r-sm:8px; --r-md:12px; --r-lg:16px; --r-pill:999px;
  --sh-hover:0 6px 16px rgba(15,23,51,.10);
  --sh-modal:0 20px 48px rgba(15,23,51,.22);
  --focus-ring:0 0 0 3px rgba(22,34,76,.14); /* navy-tinted focus glow, pairs
                                with the border-color change on :focus. Not a
                                text pair, no AA ratio applies. */

  /* ---- type ------------------------------------------------------------- */
  --sans:'Inter',-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  --display:'Archivo','Inter',-apple-system,"Segoe UI",sans-serif;

  /* SIZE SCALE, mirrored from the canonical house system at
     areas/operations/house-design-system/tokens.css. Seven steps, every one at
     least 12% from its neighbour. These pages previously set sizes per file:
     17 of them, with three pairs inside 8% of each other and two inside 3%.
     Steps that close cannot be perceived as levels. Pick by role, never by eye. */
  --fs-label:11px;           /* uppercase micro labels, table headers, kickers.
                                THE FLOOR. 9.5px was the single most repeated
                                finding in the accessibility audit. */
  --fs-meta:12.5px;          /* timestamps, sublines, pill text, footnotes */
  --fs-body:14px;            /* body copy, table cells, the default */
  --fs-input:16px;           /* LOCKED. Below 16px iOS Safari zooms on focus. */
  --fs-title:18px;           /* card and section titles */
  --fs-page:24px;            /* page titles */
  --fs-stat:32px;            /* KPI numbers */

  --fw-body:400; --fw-med:500; --fw-semi:600; --fw-bold:700;
  --tr-label:.06em; --tr-tight:-.01em; --tr-tighter:-.02em;
  --lh-tight:1.15; --lh-snug:1.35; --lh-body:1.55;

  /* ---- legacy aliases --------------------------------------------------- */
  /* The pages were written against these names. Kept so the rules in each page
     keep working, and so the old failing values are overridden in one place.
     Prefer the canonical names above in anything new. */
  --navy2:var(--navy-2);
  --brand2:var(--brand-2);
  --teal-pale:var(--status-active-bg);
  --teal-l:var(--status-active-line);
  --teal-txt:var(--status-active-txt);
  --amber-l:var(--status-new-line);
  --amber-txt:var(--status-new-txt);
  --red-pale:var(--status-alert-bg);
  --red-txt:var(--status-alert-txt);
  --gray:var(--status-off-bg);
  --gray-txt:var(--status-off-txt);
}

/* Shared primitives. Anything a page overrides locally still wins.
 * Button hierarchy: bare `button` is navy, for secondary and utility actions
 * (Save, Add rep, Sign out, Try again). `.btn-primary` is the solid orange,
 * reserved for the one conversion action per screen (Claim, Call now,
 * Connect me now, Send magic link). Orange used on every button reads as a
 * colour wash, not a considered accent, so it is rationed to one per screen. */
button,.btn-primary{
  font-family:var(--display);
  font-weight:600;
  background:var(--navy);
  border:1px solid var(--navy);
  color:#fff;
  border-radius:var(--r-sm);
  cursor:pointer;
}
button:hover{background:var(--navy-2);border-color:var(--navy-2)}
.btn-primary{background:var(--brand-solid);border-color:var(--brand-solid)}
.btn-primary:hover{background:var(--brand-solid-h);border-color:var(--brand-solid-h)}
button[disabled],.btn-primary[disabled]{opacity:.5;cursor:not-allowed}
button.ghost{background:var(--n-0);color:var(--navy);border-color:var(--line)}
button.ghost:hover{background:var(--n-50);border-color:var(--navy)}

/* ---- ONE SIZE FOR A VALUE, WHEREVER IT APPEARS -----------------------------
 *
 * A consultant's name rendered at 14px in a table cell and at 16px in the select
 * two rows below it: the same value, the same family, two sizes, on the same
 * screen. That is the "too many font variations" Chirag pointed at, and it was
 * not a choice anybody made. It fell out of the iOS rule below.
 *
 * THE 16px RULE IS REAL AND IT IS KEYED TO THE WRONG THING. iOS Safari zooms the
 * page when a text field under 16px takes focus, which on a one-handed tool is
 * genuinely disorienting, so the floor has to stay. But that behaviour only
 * exists on a touch device, and this rule applied the floor to every device,
 * which is what pushed desktop form text a step above every other value in the
 * product.
 *
 * So the floor moves to @media (pointer:coarse), where the problem actually is.
 * A phone still gets 16px and never zooms. A desktop gets --fs-body, so the name
 * in the field and the name in the cell are one treatment, which is what makes a
 * form read as part of the page rather than as something bolted onto it.
 *
 * This is the same reasoning as the 44px targets in shell.css and it is keyed on
 * the same query, for the same reason: the device is what decides, not the width
 * of the window. */
input,select,textarea{font-size:var(--fs-body)}
@media (pointer:coarse){
  input,select,textarea{font-size:16px}
}

/* ---- toggle switch --------------------------------------------------------
 * For boolean settings in dense admin tables (per-rep notify by email, notify
 * by SMS, call bridge access, and similar). Markup:
 *   <label class="switch"><input type="checkbox"><span class="track"></span></label>
 * Off = neutral grey track (--n-300), on = navy fill, so it reads as a state
 * change on the neutral ramp, not a second accent colour competing with
 * --brand-solid. Decorative control, no text contrast ratio applies, but the
 * on/off tracks (--n-300, --navy) sit well past the 3:1 non-text minimum
 * against the white knob and the --card background either side of it. */
.switch{position:relative;display:inline-block;width:32px;height:19px;flex:none;vertical-align:middle}
.switch input{position:absolute;inset:0;opacity:0;margin:0;cursor:pointer;width:100%;height:100%}
.switch .track{position:absolute;inset:0;background:var(--n-300);border-radius:var(--r-pill);transition:background .15s;pointer-events:none}
.switch .track::before{content:"";position:absolute;top:2px;left:2px;width:15px;height:15px;border-radius:50%;background:#fff;transition:transform .15s;box-shadow:0 1px 2px rgba(15,23,51,.3)}
.switch input:checked + .track{background:var(--navy)}
.switch input:checked + .track::before{transform:translateX(13px)}
.switch input:focus-visible + .track{box-shadow:var(--focus-ring)}
.switch input:disabled + .track{opacity:.45;cursor:not-allowed}

/* Compact checkbox, for a single boolean in a form (not a table column). */
.chk{width:16px;height:16px;accent-color:var(--navy);cursor:pointer;vertical-align:middle}

/* Inline label plus value, for a stated fact about the record on screen
 * (an owner, a threshold, a named contact). Not a status pill, not a banner,
 * no background or border: it reads as information, not an alert. */
/* A stated fact about the record on screen, and the most repeated text block in
   the product. It carried no measure at all, so inside a full width card it ran
   to about 170 characters a line, and capping it at 78ch fixed that and
   overcorrected: 78ch of 12.5px type is about 480px, so on a 1600px shell the
   card grew to 1100px and the paragraph did not, leaving a stubby grey column
   under a full width heading. A measure is meant to be invisible. That one drew
   attention to itself, which is the same failure as no measure at all, in the
   other direction.

   THE REFERENCE MOCK SETTLES THE STYLING AND THE REAL FIX IS NOT STYLING.
   deliverables/mock-console.html keeps this at --fs-meta and 78ch, and it never
   looks narrow there, because every paragraph in the mock is ONE OR TWO LINES.
   The stubby column only appears when a 50 word paragraph is poured into a 480px
   measure and stacks four deep under a full width heading. So the size stays
   where the mock has it and the paragraphs get shorter, which is what section
   9.5 of the brief asks for anyway.

   THE CAP IS SET SO A SHORTENED INTRO FITS ON ONE LINE, and that is the whole
   reasoning behind the number. Once the paragraphs came down to twenty odd
   words, the measure was doing nothing but forcing a break in the middle of a
   sentence that had room to finish, which leaves a ragged second line and a
   half empty card. A break the reader can see no reason for is worse than a
   long line: the eye stops at it and looks for the cause.

   128ch is about 890px here, which is where a twenty five word sentence lands.
   It still bites on the genuinely long ones and on anything a future session
   adds without shortening, which is the job it is actually for.

   min(100%, 128ch) rather than a bare 128ch, so the cap never exceeds its
   container and the paragraph cannot set the width of a narrow card. */
.factline{font-size:var(--fs-meta);color:var(--mut);margin:0 0 var(--s-3);
  line-height:var(--lh-body);max-width:min(100%,128ch);text-wrap:balance}
.factline b{color:var(--ink);font-weight:var(--fw-semi)}
