/* ============================================================================
   PLATFORM.CSS — Carrier vetting platform design system (single source of truth)
   Generated from Vetting Platform Interface Style Guide v2 (2026-07-14).
   Link this ONE file from every platform page:  <link rel="stylesheet" href="/css/platform.css">
   Rules baked in: neutrals carry structure; the four status hues are the ONLY
   saturated colors and always mean something; machine facts (MC/DOT, policy #s,
   timestamps, hashes) go in .mono; every row/tile/finding carries a 4px status
   spine; a verb keeps its name AND color through a whole flow. Never render a
   tenant or product name in customer-facing copy — the platform is "the platform."
   ============================================================================ */

/* Fonts — one import brings the whole type system. (For fastest paint you may
   instead keep the <link rel="preconnect"> + font stylesheet in each page <head>
   and delete this @import.) */
@import url("https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;600&family=IBM+Plex+Sans+Condensed:wght@600&family=IBM+Plex+Mono:wght@400;600&display=swap");


/* ============================================================================
   DESIGN TOKENS
   ============================================================================ */
:root{
  /* Chrome — dark app frame: topbar + nav rail */
  --chrome:#141E2E;       /* topbar + icon rail */
  --chrome-2:#1B2839;     /* chrome hover / raised */
  --chrome-line:#2A3A50;  /* chrome divider */
  --chrome-text:#B9C6D8;  /* chrome secondary text */

  /* Neutrals — anchored graphite ramp; panels pop off a darker field */
  --field:#3A5674;        /* desk base tone (deep slate-blue) */
  --desk-grid:rgba(255,255,255,.06);/* faint light grid on the dark desk */
  --desk-glow:rgba(255,255,255,.10); --desk-sheen:rgba(150,180,215,.22); --desk-depth:rgba(70,110,150,.28);/* soft center lift */
  --desk-cell:26px;                 /* grid cell size */
  --panel:#FFFFFF;        /* raised surface: cards, panels */
  --well:#F1F4F8;         /* insets: inputs, zebra — always LIGHTER than field */
  --bubble-ai:#E8F1FB;    /* assistant bubble fill */
  --bubble-ai-line:#C6DBF1;/* assistant bubble edge */
  --rule:#C9D1DC;         /* hairline border */
  --rule-strong:#AAB5C4;  /* structural divider */
  --ink:#0E1726;          /* primary text */
  --muted:#46536B;        /* secondary text — must stay readable */
  --faint:#7C8799;        /* labels, placeholders (non-essential only) */

  /* Primary — authoritative ink-blue: interactive, links, focus, active nav */
  --primary:#1A57A6;
  --primary-hover:#154A90;
  --primary-press:#113C77;
  --primary-tint:#DFEAF7;
  --primary-ring:rgba(26,87,166,.45);

  /* Status scale — the ONLY saturated colors. Reserved for meaning. */
  --pos:#177347;   --pos-tint:#D9EEE2;   /* clear / approve / active */
  --warn:#9A5300;  --warn-dot:#D98A06; --warn-tint:#F8E9CB; /* caution / medium */
  --crit:#AE1E12;  --crit-tint:#F9E2DE;  /* critical / high / decline / blocks */
  --neutral:#46536B; --neutral-tint:#E4E8EE; /* unknown / pending / n/a */

  /* Radius — tight and operational */
  --r-sm:4px;   /* inputs, buttons */
  --r-md:6px;   /* cards, panels */
  --pill:999px; /* status dots + pills only */

  /* Spacing — 4px grid */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px; --s6:32px;

  /* Type scale */
  --t-label:12px; --t-meta:13px; --t-body:14px; --t-sub:16px;
  --t-sec:19px;   --t-title:24px; --t-big:30px;

  /* Chrome dimensions */
  --newway:#305D94;           /* NewWay brand mark chip in the topbar */
  --topbar:48px; --rail:56px; /* product nav is icon-only; labels on hover */

  /* Elevation — whisper on panels, pop on true overlays */
  --shadow-panel:inset 2px 0 0 0 rgba(16,28,46,.6), inset 0 -2px 0 0 rgba(16,28,46,.6), inset 0 1px 0 0 rgba(255,255,255,.6), -7px 8px 14px -7px rgba(228,240,255,.6), -3px 4px 7px -4px rgba(205,228,255,.42);
  --shadow-pop:0 8px 28px rgba(14,23,38,.18), 0 1px 2px rgba(14,23,38,.12);

  /* Motion */
  --ease:cubic-bezier(.2,.6,.2,1); --fast:120ms; --med:160ms;

  /* Density */
  --row:36px; --row-compact:32px; --spine:4px; --tile:50px;
}


/* ============================================================================
   BASE — reset, desk background, mono / condensed helpers
   ============================================================================ */
*{box-sizing:border-box}
strong,b{font-weight:600}
html{scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}*{animation-duration:.001ms!important;transition-duration:.001ms!important}}

body{
  margin:0;
  font-family:"IBM Plex Sans",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  font-size:var(--t-body); line-height:1.5; color:var(--ink);
  background-color:var(--field);
  background-image:
    linear-gradient(160deg, var(--desk-sheen), transparent 45%),
    radial-gradient(1200px 600px at 78% -10%, var(--desk-glow), transparent 60%),
    radial-gradient(900px 500px at 0% 100%, var(--desk-depth), transparent 55%),
    linear-gradient(var(--desk-grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--desk-grid) 1px, transparent 1px);
  background-size:auto, auto, auto, var(--desk-cell) var(--desk-cell), var(--desk-cell) var(--desk-cell);
  background-attachment:fixed;
  -webkit-font-smoothing:antialiased;
}
.mono{font-family:"IBM Plex Mono",ui-monospace,"SFMono-Regular",Menlo,monospace;font-variant-numeric:tabular-nums;}
.cond{font-family:"IBM Plex Sans Condensed","IBM Plex Sans",sans-serif;}


/* ============================================================================
   APP SHELL — product frame (icon rail + workspace)
   ============================================================================ */
/* Product frame: an icon-only nav rail down the left, bright workspace to the
   right. NO TOPBAR (removed 2026-07-21): it cost 48px of fixed chrome on every
   page to show a title the rail already conveys, and being page-local it drifted
   — three surfaces ended up with three different marks, type sizes and bar
   heights. Everything it held moved somewhere with a better claim to it: the
   brand mark and the broker name to the rail, list-scoped actions (TMS sync) to
   the header of the list they act on, and page titles into the content area
   where they scroll away instead of occupying permanent chrome. */
.appshell{display:grid;grid-template-columns:var(--rail) 1fr;min-height:100vh;}
.appshell .rail{align-self:stretch;}
.appshell .main{grid-column:2;}



/* ============================================================================
   TOPBAR — RETIRED 2026-07-21. Rules kept only because the dispatch-family
   pages (delivery/intransit/loaded) carry their own .topbar markup. Do not use
   on an .appshell page: the grid no longer reserves a row for it.
   ============================================================================ */
.topbar{
  position:sticky;top:0;z-index:40;
  height:var(--topbar);display:flex;align-items:center;gap:var(--s3);
  padding:0 var(--s4);background:var(--chrome);color:#fff;
  border-bottom:1px solid var(--chrome-line);
}
.topbar__mark{width:26px;height:26px;border-radius:5px;background:var(--newway);
  display:grid;place-items:center;color:#fff;flex:0 0 auto;}
.topbar__title{font-weight:600;font-size:var(--t-body);letter-spacing:-.01em;}
.topbar__sub{color:var(--chrome-text);font-size:var(--t-meta);}
.topbar__spacer{flex:1}
.topbar__meta{color:var(--chrome-text);font-size:var(--t-meta);}


/* ============================================================================
   NAV RAIL — dark chrome, icon-only, labels on hover. Markup + inventory are
   injected by /js/platform-nav.js into <nav class="sidebar" id="platform-rail">.
   Active item is marked with .active (a --primary spine). Edit the rail in the
   JS, not here — this is styling only.
   ============================================================================ */
.sidebar{width:var(--rail);flex-shrink:0;background:var(--chrome);display:flex;flex-direction:column;
  align-items:center;height:100vh;position:sticky;top:0;z-index:300;}
.sidebar-brand{width:var(--rail);height:var(--topbar);flex-shrink:0;display:flex;align-items:center;
  justify-content:center;border-bottom:1px solid var(--chrome-line);}
/* Broker identity, pinned to the foot of the rail. It never changes during a
   session — it is a "you are in the right tenant" indicator, not something you
   read — so it belongs in quiet permanent chrome rather than a prominent bar.
   Initials show at rest; the full name appears on hover, like the nav labels. */
.sidebar-tenant{margin-top:auto;width:var(--rail);flex-shrink:0;padding:var(--s3) 0;
  display:flex;align-items:center;justify-content:center;position:relative;
  border-top:1px solid var(--chrome-line);color:var(--chrome-text);
  font:600 var(--t-label)/1 "IBM Plex Sans Condensed";letter-spacing:.04em;cursor:default;}
.sidebar-tenant__full{position:absolute;left:calc(100% + 8px);white-space:nowrap;
  background:var(--chrome-2);color:#fff;padding:5px 9px;border-radius:var(--r-sm,4px);
  font:400 var(--t-meta)/1 "IBM Plex Sans";opacity:0;pointer-events:none;
  transition:opacity .12s ease;z-index:320;}
.sidebar-tenant:hover .sidebar-tenant__full{opacity:1;}

/* Page heading INSIDE the content area — replaces the retired topbar title.
   It scrolls away with the content instead of holding fixed chrome.

   LIGHT INK ON PURPOSE. This heading sits on the dark app background, NOT on a
   white tile, so --ink (near-black) renders 2.4:1 against it and --muted a
   useless 1.0:1 — measured, not guessed. The title was white in the old dark
   topbar; moving it into the content area is what made the colour wrong.
   Anything added to .page-head must stay light for the same reason. */
/* Indented to the tiles' INNER content edge rather than their outer border, so
   the title reads as heading the working area instead of floating beside it:
   var(--s4) tile padding + 1px border + the 2px tile inset. Title, section
   labels and field text then share one vertical line. */
.page-head{margin:0 0 var(--s4);padding-left:calc(var(--s4) + 3px);}
.page-head__title{font-weight:600;font-size:var(--t-title);letter-spacing:-.01em;color:#fff;}
.sidebar-brand .brand-logo{width:26px;height:26px;flex-shrink:0;border-radius:5px;}
/* The CarrierBasis mark carries its own fills (white tile, ember fold, two-tone
   CB) — do NOT override path fills here; the old rule painted the retired
   single-path NewWay gear. */
.sidebar .nav-items{display:flex;flex-direction:column;flex:1;width:100%;padding:var(--s2) 0;gap:2px;}
.sidebar .nav-item{position:relative;width:var(--rail);height:52px;display:flex;align-items:center;
  justify-content:center;text-decoration:none;color:var(--chrome-text);
  transition:background var(--fast) var(--ease),color var(--fast) var(--ease);}
.sidebar .nav-item:hover{background:var(--chrome-2);color:#fff;}
.sidebar .nav-item.active{color:#fff;background:var(--chrome-2);}
.sidebar .nav-item.active::before{content:'';position:absolute;left:0;top:8px;bottom:8px;width:3px;
  background:var(--primary);border-radius:0 2px 2px 0;}
.sidebar .nav-item svg{width:20px;height:20px;fill:currentColor;}
/* NEW-FEATURE FLAG on a rail item (added 2026-07-31).
   Deliberately NOT one of the four status hues: on this product a red or amber
   mark means a compliance state, and putting one beside a nav icon would read
   as "something is wrong" rather than "something is new". The icon brightens to
   the same white it already uses for hover/active, and the dot is a light
   neutral tint that reads clearly on the dark chrome without claiming meaning.
   Retire by deleting `badge` from the item in platform-nav.js. */
.sidebar .nav-item--flagged{color:#fff;}
.sidebar .nav-item__badge{position:absolute;top:12px;right:12px;width:7px;height:7px;
  border-radius:var(--pill);background:var(--primary-tint);
  box-shadow:0 0 0 2px var(--chrome);pointer-events:none;}
.sidebar .nav-item--flagged:hover .nav-item__badge,
.sidebar .nav-item--flagged.active .nav-item__badge{box-shadow:0 0 0 2px var(--chrome-2);}
.sidebar .nav-item::after{content:attr(data-label);position:absolute;left:calc(var(--rail) + 8px);top:50%;
  transform:translateY(-50%) translateX(-4px);background:var(--ink);color:#fff;font:600 11px/1 "IBM Plex Sans";
  letter-spacing:0.3px;padding:5px 10px;border-radius:var(--r-sm);white-space:nowrap;pointer-events:none;opacity:0;
  transition:opacity var(--fast) var(--ease),transform var(--fast) var(--ease);z-index:1000;box-shadow:var(--shadow-pop);}
.sidebar .nav-item:hover::after{opacity:1;transform:translateY(-50%) translateX(0);}


/* ============================================================================
   LAYOUT — workspace content area + master/detail panes
   ============================================================================ */
.main{padding:var(--s6) clamp(var(--s4),3vw,56px);max-width:1720px;margin:0 auto;width:100%;}
.lede{max-width:70ch;} /* prose stays measured even when the container goes wide */
section{margin-bottom:var(--s6);scroll-margin-top:calc(var(--topbar) + 12px);}
.pane{display:grid;gap:var(--s3);}
/* Independent scroll regions (sticky floating right card). The pane is a grid;
   it fills the viewport and each column owns its own vertical scroll so the
   carrier list scrolls without pushing #detail out of view. The single
   full-height row (minmax(0,1fr)) is what lets a taller-than-viewport column
   overflow INTO its own scrollbar rather than growing the row past the pane;
   flex:1 would be a no-op here since this is grid, not flex. */
.pane--split{grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);grid-template-rows:minmax(0,1fr);
  height:100vh;height:100dvh;overflow:hidden;} /* master + detail on wide */
.pane--split>section{min-height:0;overflow-y:auto;}
/* Stacked single column: revert to normal document flow so the two panels don't
   each grow a scrollbar inside a clipped, fixed-height pane. */
@media(max-width:1180px){
  .pane--split{grid-template-columns:1fr;grid-template-rows:none;height:auto;overflow:visible;}
  .pane--split>section{overflow-y:visible;}
}


/* ============================================================================
   SECTION FURNITURE — eyebrow, headings, divider, grid, card, note
   ============================================================================ */
.eyebrow{font:600 var(--t-label)/1 "IBM Plex Sans Condensed";text-transform:uppercase;
  letter-spacing:.1em;color:var(--primary);margin:0 0 var(--s2);}
.h-sec{font-size:var(--t-title);font-weight:600;letter-spacing:-.02em;margin:0 0 var(--s2);}
.h-sub{font-size:var(--t-sub);font-weight:600;margin:var(--s5) 0 var(--s3);letter-spacing:-.01em;}
.lede{color:var(--muted);max-width:64ch;margin:0 0 var(--s4);}
.divider{height:1px;background:var(--rule);border:0;margin:var(--s6) 0;}
.grid{display:grid;gap:var(--s3);}
.two{grid-template-columns:1fr 1fr;}
.three{grid-template-columns:repeat(3,1fr);}
@media(max-width:760px){.two,.three{grid-template-columns:1fr}}

.card{background:var(--panel);border:1px solid var(--rule);border-radius:var(--r-md);padding:var(--s4);box-shadow:var(--shadow-panel);}
.note{font-size:var(--t-meta);color:var(--muted);}


/* ============================================================================
   BUTTONS — the grammar: color is assigned by consequence
   ============================================================================ */
.btn{font-family:inherit;font-size:var(--t-body);font-weight:600;line-height:1;
  border-radius:var(--r-sm);padding:10px 14px;border:1px solid transparent;cursor:pointer;
  transition:background var(--fast) var(--ease),border-color var(--fast) var(--ease);
  display:inline-flex;align-items:center;gap:var(--s2);}
.btn:focus-visible{outline:2px solid var(--primary-ring);outline-offset:2px;}
.btn--primary{background:var(--primary);color:#fff;}
.btn--primary:hover{background:var(--primary-hover);}
.btn--primary:active{background:var(--primary-press);}
.btn--approve{background:var(--pos);color:#fff;}
.btn--approve:hover{filter:brightness(.93);}
.btn--decline{background:var(--panel);color:var(--crit);border-color:var(--crit);}
.btn--decline:hover{background:var(--crit-tint);}
.btn--secondary{background:var(--panel);color:var(--ink);border-color:var(--rule-strong);}
.btn--secondary:hover{background:var(--well);}
.btn--ghost{background:transparent;color:var(--primary);padding:9px 8px;}
.btn--ghost:hover{background:var(--primary-tint);}
.btn[disabled]{opacity:.45;cursor:not-allowed;pointer-events:none;}
.btn-spinner{width:13px;height:13px;border:2px solid rgba(255,255,255,.4);border-top-color:#fff;
  border-radius:50%;animation:spin .7s linear infinite;}
@keyframes spin{to{transform:rotate(360deg)}}
.btnrow{display:flex;flex-wrap:wrap;gap:var(--s2);align-items:center;}


/* ============================================================================
   PILLS / STATUS
   ============================================================================ */
.pill{display:inline-flex;align-items:center;gap:6px;font-size:var(--t-label);font-weight:600;
  letter-spacing:.02em;padding:3px 9px 3px 7px;border-radius:var(--pill);border:1px solid transparent;}
.pill .dot{width:6px;height:6px;border-radius:var(--pill);flex:0 0 auto;}
.pill--pos{background:var(--pos-tint);color:var(--pos);border-color:#B7DCC6;}.pill--pos .dot{background:var(--pos);}
.pill--warn{background:var(--warn-tint);color:var(--warn);border-color:#EBD2A0;}.pill--warn .dot{background:var(--warn-dot);}
.pill--crit{background:var(--crit-tint);color:var(--crit);border-color:#EFBFB7;}.pill--crit .dot{background:var(--crit);}
.pill--neutral{background:var(--neutral-tint);color:var(--neutral);border-color:var(--rule);}.pill--neutral .dot{background:var(--neutral);}


/* ============================================================================
   DATA TABLE — dense, spine-led, mono facts
   ============================================================================ */
.table-wrap{border:1px solid var(--rule);border-radius:var(--r-md);overflow:hidden;background:var(--panel);}
table.data{width:100%;border-collapse:collapse;font-size:var(--t-body);}
table.data thead th{position:sticky;top:0;background:var(--well);text-align:left;
  font:600 var(--t-label)/1 "IBM Plex Sans Condensed";text-transform:uppercase;letter-spacing:.06em;
  color:var(--muted);padding:8px var(--s3);border-bottom:1px solid var(--rule-strong);}
table.data td{padding:0 var(--s3);height:var(--row);border-bottom:1px solid var(--rule);
  border-left:var(--spine) solid transparent;}
table.data td:not(:first-child){border-left:0;}
table.data tbody tr:last-child td{border-bottom:0;}
table.data .num{text-align:right;font-family:"IBM Plex Mono",monospace;font-variant-numeric:tabular-nums;}
table.data tr:hover td{background:var(--well);}
.spine-pos{border-left-color:var(--pos)!important;}
.spine-warn{border-left-color:var(--warn-dot)!important;}
.spine-crit{border-left-color:var(--crit)!important;}
.spine-neutral{border-left-color:var(--rule-strong)!important;}


/* ============================================================================
   CHECKLIST TILES — sources & verifications (rail pattern)
   ============================================================================ */
.tile{display:flex;align-items:center;gap:var(--s3);min-height:var(--tile);padding:7px var(--s4);
  border-top:1px solid var(--rule);border-left:var(--spine) solid transparent;cursor:pointer;}
.tile:first-of-type{border-top:0;}
.tile:hover{background:var(--well);}
.tile--done{border-left-color:var(--pos);background:var(--pos-tint);}
.tile--pend{border-left-color:var(--warn-dot);background:var(--warn-tint);}
.tile__body{display:flex;flex-direction:column;gap:1px;min-width:0;}
.tile__name{font-weight:600;}
.tile__sub{font-size:var(--t-label);color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.tile--done .tile__sub{color:var(--pos);}
.tile--pend .tile__sub{color:var(--warn);}
.ring{width:22px;height:22px;border-radius:var(--pill);flex:0 0 auto;display:grid;place-items:center;
  color:#fff;font-size:12px;font-weight:600;}
.ring--pos{background:var(--pos);}
.ring--warn{background:var(--warn-dot);}
.ring--hollow{background:transparent;border:2px solid var(--rule-strong);}
.tile__tag{margin-left:auto;font:600 10px/1 "IBM Plex Sans Condensed";text-transform:uppercase;letter-spacing:.05em;
  color:var(--faint);background:var(--panel);border:1px solid var(--rule);border-radius:3px;padding:3px 6px;flex:0 0 auto;}
.tile--done .tile__tag{color:var(--pos);border-color:#B7DCC6;}
.tile__act{margin-left:auto;font-size:var(--t-meta);color:var(--primary);font-weight:600;flex:0 0 auto;}


/* ============================================================================
   FINDINGS
   ============================================================================ */
.finding{background:var(--panel);border:1px solid var(--rule);border-radius:var(--r-md);
  border-left:var(--spine) solid var(--rule-strong);padding:var(--s3) var(--s4);margin-bottom:var(--s2);}
.finding--crit{border-left-color:var(--crit);}
.finding--warn{border-left-color:var(--warn-dot);}
.finding--pos{border-left-color:var(--pos);}
.finding__head{display:flex;align-items:center;gap:var(--s2);flex-wrap:wrap;}
.finding__title{font-weight:600;font-size:var(--t-body);}
.finding__body{color:var(--muted);font-size:var(--t-meta);margin-top:var(--s1);}
.tag{font:600 var(--t-label)/1 "IBM Plex Sans Condensed";text-transform:uppercase;letter-spacing:.05em;
  padding:3px 7px;border-radius:var(--r-sm);}
.tag--block{background:var(--crit-tint);color:var(--crit);}


/* ============================================================================
   VERDICT / DECISION BAND
   ============================================================================ */
.verdict{display:grid;grid-template-columns:var(--spine) 1fr auto;background:var(--panel);
  border:1px solid var(--rule);border-radius:var(--r-md);overflow:hidden;}
.verdict__cap{background:var(--pos);}
.verdict--crit .verdict__cap{background:var(--crit);}
.verdict--warn .verdict__cap{background:var(--warn-dot);}
.verdict__main{padding:var(--s4);}
.verdict__label{font:600 var(--t-label)/1 "IBM Plex Sans Condensed";text-transform:uppercase;
  letter-spacing:.08em;color:var(--faint);}
.verdict__value{font-size:var(--t-sec);font-weight:600;margin:2px 0 var(--s2);letter-spacing:-.01em;}
.verdict__rec{color:var(--muted);font-size:var(--t-meta);}
.verdict__side{padding:var(--s4);border-left:1px solid var(--rule);display:flex;
  flex-direction:column;gap:var(--s1);justify-content:center;min-width:190px;}
.kv{display:flex;justify-content:space-between;gap:var(--s4);font-size:var(--t-meta);}
.kv span:first-child{color:var(--faint);}
.kv .mono{color:var(--muted);}


/* ============================================================================
   CASEFILE HEADER
   ============================================================================ */
.casefile{background:var(--panel);border:1px solid var(--rule);border-radius:var(--r-md);
  padding:var(--s4);display:flex;align-items:center;gap:var(--s4);flex-wrap:wrap;}
.casefile__id{font-family:"IBM Plex Mono",monospace;font-size:var(--t-title);font-weight:600;letter-spacing:-.02em;}
.casefile__name{color:var(--muted);}
.casefile__facts{display:flex;gap:var(--s5);margin-left:auto;flex-wrap:wrap;}
.fact{display:flex;flex-direction:column;gap:2px;}
.fact__k{font:600 var(--t-label)/1 "IBM Plex Sans Condensed";text-transform:uppercase;letter-spacing:.06em;color:var(--faint);}
.fact__v{font-family:"IBM Plex Mono",monospace;font-size:var(--t-meta);}


/* ============================================================================
   INPUTS
   ============================================================================ */
.field{display:flex;flex-direction:column;gap:6px;margin-bottom:var(--s3);}
.field label{font:600 var(--t-label)/1 "IBM Plex Sans Condensed";text-transform:uppercase;letter-spacing:.06em;color:var(--muted);}
.input{font-family:inherit;font-size:var(--t-body);color:var(--ink);background:var(--well);
  border:1px solid var(--rule-strong);border-radius:var(--r-sm);padding:8px 10px;width:100%;}
.input::placeholder{color:var(--faint);}
.input:focus{outline:none;background:var(--panel);border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-ring);}
.input--mono{font-family:"IBM Plex Mono",monospace;}


/* ============================================================================
   TOAST / EMPTY / ERROR
   ============================================================================ */
.toast{display:inline-flex;align-items:center;gap:var(--s2);background:var(--panel);
  border:1px solid var(--rule);border-left:var(--spine) solid var(--pos);border-radius:var(--r-md);
  padding:var(--s3) var(--s4);box-shadow:var(--shadow-pop);font-size:var(--t-meta);}
.empty{border:1px dashed var(--rule-strong);border-radius:var(--r-md);padding:var(--s6);
  text-align:center;color:var(--muted);background:var(--panel);}
.empty h4{margin:0 0 var(--s1);color:var(--ink);font-size:var(--t-body);}
.errbar{background:var(--crit-tint);border:1px solid #EFC4BE;border-left:var(--spine) solid var(--crit);
  border-radius:var(--r-md);padding:var(--s3) var(--s4);font-size:var(--t-meta);color:#7A1810;}


/* ============================================================================
   SEGMENTED · TABS · CHIPS
   ============================================================================ */
.seg{display:inline-flex;border:1px solid var(--rule-strong);border-radius:var(--r-sm);overflow:hidden;}
.seg button{font:600 var(--t-meta)/1 "IBM Plex Sans";padding:7px 12px;border:0;background:var(--panel);
  color:var(--muted);cursor:pointer;border-right:1px solid var(--rule);}
.seg button:last-child{border-right:0;}
.seg button[aria-selected="true"]{background:var(--primary-tint);color:var(--primary);}
.tabs{display:flex;gap:var(--s4);border-bottom:1px solid var(--rule);}
.tabs a{padding:0 0 var(--s2);color:var(--muted);text-decoration:none;font-size:var(--t-body);
  border-bottom:2px solid transparent;margin-bottom:-1px;}
.tabs a[aria-current]{color:var(--primary);border-bottom-color:var(--primary);font-weight:600;}
.chip{display:inline-flex;align-items:center;gap:6px;background:var(--well);border:1px solid var(--rule);
  border-radius:var(--r-sm);padding:4px 8px;font-size:var(--t-meta);color:var(--muted);}


/* ============================================================================
   AI CHAT — embedded panel, scoped assistant
   ============================================================================ */
.chatx{background:var(--panel);border:1px solid var(--rule);border-radius:var(--r-md);
  box-shadow:var(--shadow-panel);overflow:hidden;display:flex;flex-direction:column;}
.cx-head{display:flex;align-items:center;gap:var(--s2);padding:10px var(--s3);border-bottom:1px solid var(--rule);}
.cx-title{font-weight:600;font-size:var(--t-sub);}
.scope{display:inline-flex;align-items:center;gap:5px;font:600 11px/1 "IBM Plex Sans Condensed";
  text-transform:uppercase;letter-spacing:.05em;color:var(--primary);background:var(--primary-tint);
  padding:4px 8px;border-radius:var(--pill);border:1px solid #BCD3EE;}
.scope .dot{width:6px;height:6px;border-radius:var(--pill);background:var(--primary);}
.cx-sealed{margin-left:auto;font-size:var(--t-label);color:var(--faint);}
.cx-composer{display:flex;align-items:center;gap:var(--s2);padding:var(--s2) var(--s3);border-bottom:1px solid var(--rule);}
.cx-input{flex:1;background:var(--well);border:1px solid var(--rule-strong);border-radius:var(--pill);
  padding:7px 14px;color:var(--faint);font-size:var(--t-meta);}
.cx-send{background:var(--primary);color:#fff;border:0;border-radius:var(--pill);
  height:32px;padding:0 14px;font:600 var(--t-meta) "IBM Plex Sans";cursor:pointer;}
.cx-meta{display:flex;align-items:center;gap:var(--s2);padding:6px var(--s3) 0;}
.cx-meta .cond{font:600 10px/1 "IBM Plex Sans Condensed";text-transform:uppercase;letter-spacing:.07em;color:var(--faint);}
.cx-meta i{flex:1;height:1px;background:var(--rule);}
.cx-body{padding:var(--s2) var(--s3) var(--s3);display:flex;flex-direction:column;gap:6px;
  background:var(--panel);max-height:300px;overflow:auto;}
.brow{display:flex;gap:6px;align-items:flex-end;}
.brow--op{justify-content:flex-end;}
.ai-avatar{width:20px;height:20px;border-radius:var(--pill);background:var(--primary-tint);
  border:1px solid #BCD3EE;color:var(--primary);display:grid;place-items:center;
  font:600 9px "IBM Plex Sans";flex:0 0 auto;}
.bubble{padding:6px 11px;font-size:var(--t-meta);line-height:1.4;max-width:74%;}
.b-ai{background:var(--bubble-ai);border:1px solid var(--bubble-ai-line);border-radius:12px 12px 12px 4px;}
.b-op{background:var(--primary);color:#fff;border-radius:12px 12px 4px 12px;}
.tstamp{font-family:"IBM Plex Mono",monospace;font-size:10px;color:var(--faint);flex:0 0 auto;padding-bottom:2px;}
.brow--op .tstamp{order:-1;}
.cx-refs{display:flex;flex-wrap:wrap;gap:5px;margin-top:6px;}
.refchip{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:600;
  padding:2px 7px 2px 6px;border-radius:var(--pill);}
.refchip .dot{width:5px;height:5px;border-radius:var(--pill);}
.refchip--crit{background:var(--crit-tint);color:var(--crit);}.refchip--crit .dot{background:var(--crit);}
.refchip--pos{background:var(--pos-tint);color:var(--pos);}.refchip--pos .dot{background:var(--pos);}
.sysline{display:flex;justify-content:center;}
.sysline span{font:600 10px/1 "IBM Plex Sans Condensed";text-transform:uppercase;letter-spacing:.06em;
  color:var(--muted);background:var(--neutral-tint);border:1px solid var(--rule);border-radius:var(--pill);padding:3px 9px;}
.guard{background:var(--neutral-tint);border:1px solid var(--rule);border-left:var(--spine) solid var(--neutral);
  border-radius:var(--r-sm);padding:var(--s2) var(--s3);font-size:var(--t-meta);color:var(--muted);}
.guard strong{color:var(--ink);}


/* ============================================================================
   TMS CHIP — carrier ↔ TMS linkage state (carriers.html v4). Reads the
   tms_snapshot the refresh/sync writes: found:true → in (active) or inactive,
   found:false → out, found:null → unavailable. Empty snapshot = no chip.
   Border hexes match the pill--* family above.
   ============================================================================ */
.chip--tms-in{background:var(--pos-tint);color:var(--pos);border-color:#B7DCC6;}
.chip--tms-inactive{background:var(--warn-tint);color:var(--warn);border-color:#EBD2A0;}
.chip--tms-out{background:var(--neutral-tint);color:var(--neutral);border-color:var(--rule);}
.chip--tms-none{background:var(--well);color:var(--faint);border-color:var(--rule);border-style:dashed;}

/* Document expiry chips (CP5) — reuse the chip base with status tints. */
.chip--exp-warn{background:var(--warn-tint);color:var(--warn);border-color:#EBD2A0;}
.chip--exp-crit{background:var(--crit-tint);color:var(--crit);border-color:#EFBFB7;}

/* ═══════════════════════════════════════════════════════════════════════════
   TILES — rules learned the hard way. Read before styling any panel.
   ═══════════════════════════════════════════════════════════════════════════

   1. NEVER replace box-shadow on a tile.
      --shadow-panel is not decoration, it IS the platform's tile signature:
      a dark left spine, a bottom edge, a white top highlight, and a pale blue
      outer glow. Setting `box-shadow: 0 1px 2px rgba(...)` on .card or any
      tile-like element silently strips all of it and the surface stops looking
      like this product. Set background / border / radius freely; leave the
      shadow to the variable.

   2. INNER SECTIONS OF A TILE MUST BE TRANSPARENT.
      Four of the five shadows above are INSET, and CSS paints inset shadows
      BENEATH child backgrounds. So a child that fills a tile edge-to-edge with
      its own background erases the spine, the bottom edge and the top
      highlight — the tile renders with no visible border and nothing in the
      stylesheet looks wrong. Use .tile-inner (or set background:transparent)
      on any section that sits directly inside a tile, and divide sections with
      rules rather than with their own backgrounds.

   Both of these cost real debugging time on carriers.html and
   compliance-files.html before they were understood. */

.tile-inner{background:transparent;border:0;border-radius:0;box-shadow:none;}
/* Content sitting hard against the inset edges looks clipped; 2px on the left
   and bottom keeps it clear of the spine without visibly shifting anything. */
.tile-pad-inset{padding:0 0 2px 2px;}

/* ═══════════════════════════════════════════════════════════════════════════
   FRAMED SECTION STRIPS — and why the margins are asymmetric
   ═══════════════════════════════════════════════════════════════════════════

   A full-bleed colored strip pressed flush against a 1px panel border gets
   ANTIALIASED INTO that border and erases it. This layout lands panels on
   half-pixel boundaries (measured: a rail panel's left edge at x=1421.5 at 100%
   zoom, DPR 1), so the border and the strip share a physical pixel and the
   border loses. The stylesheet looks correct; the rasterization isn't. This
   produced a recurring "the left border is missing" bug that reading CSS could
   never find.

   The cure: give the strip its own frame and leave a hairline of panel surface
   beside it, applying the inset at the SECTION CONTAINER so every row, tile and
   form inside inherits it.

   The left/right values are DELIBERATELY UNEQUAL (2px / 1px). The half-pixel
   layout rounds the right-hand gap wider, so equal margins look unequal on
   screen. Do not "fix" this to be symmetric — it will look wrong again. */

.strip-inset{padding-left:2px;padding-right:1px;}
/* Same inset, but added to a section that already has a 14px gutter: the
   shorthand must carry BOTH or the gutter is silently clobbered. */
.strip-inset-padded{padding:12px 15px 12px 16px;}
