/* Page, text, focus, form controls and their states, the sidebar, sub-tabs, buttons. Loaded in the order web/index.html lists them; the order is the cascade. */
/* one global focus ring + reduced-motion reset (lazier + more complete than per-selector) */
/* The ring alone was rgba(59,91,219,.35) over white = 1.69:1, under the 3:1 that WCAG 1.4.11 asks of a
   focus indicator — and `box-shadow` is DISCARDED in Windows High Contrast, so with outline:none a
   forced-colors user had no focus indicator anywhere in the app. A real outline carries the contrast; the
   white inner shadow keeps it legible where the focused control sits on a tinted card. */
:focus-visible { outline:2px solid var(--accent); outline-offset:2px; box-shadow:0 0 0 4px #fff, var(--e-focus); border-radius:var(--r-sm); }
@media (forced-colors: active) { :focus-visible { outline:3px solid Highlight; outline-offset:2px; box-shadow:none; } }
/* Wizard step chips. Were inline-styled per render with no hover or focus affordance at all. */
.gw-chip { display:inline-flex; align-items:center; gap:6px; font:inherit; font-size:12.5px; font-weight:600;
  cursor:pointer; background:none; border:0; padding:6px 8px; border-radius:var(--r-sm);
  border-bottom:1px dashed transparent; }
.gw-chip:hover:not([disabled]) { border-bottom-color:var(--line-strong); }
.gw-chip[disabled] { cursor:default; }
.gw-chip-n { width:20px; height:20px; border-radius:50%; display:grid; place-items:center; font-size:11px; color:#fff; flex:0 0 auto; }
/* State lives on the control, not on a rail beside it. The left rails read as page decoration at a glance
   and sat 600px away from the box they described; colouring the box itself puts the signal where the eye
   already is. Tint only, never a width change: .gw-rows .field uses border-top for row separation, so a
   border here would shift the grid.
   !important because the base look is set by `#trkForm textarea` and friends, and an id beats any number
   of classes: without it the textareas stayed white while every input tinted. Same reason .trk-kind-sub
   below carries it. Locked and disabled controls are excluded so they keep reading as not-yours-to-fill,
   and so are the Subdomain/Redirect tints, which say WHICH kind of URL change this is and outrank a
   plain "done". */
/* .trk-datectl > input: the date box sits inside its calendar-button wrapper, one level down. */
.field.is-missing > :is(input, select, textarea):not(.ro-lock, :disabled, .trk-kind-sub, .trk-kind-redir),
.field.is-missing > .trk-datectl > input[data-mdy] {
  background:var(--bad-soft) !important; border-color:var(--bad-line) !important;
}
.field.is-filled-req > :is(input, select, textarea):not(.ro-lock, :disabled, .trk-kind-sub, .trk-kind-redir),
.field.is-filled-req > .trk-datectl > input[data-mdy] {
  background:var(--ok-soft) !important; border-color:var(--ok-line) !important;
}
/* Answered but optional stays neutral. A green wash on all 42 rows turns the page into a traffic light and
   the eye stops finding the blanks, which is the thing that actually matters. */
.field.is-missing.is-filled > :is(input, select, textarea):not(.ro-lock, :disabled, .trk-kind-sub, .trk-kind-redir),
.field.is-missing.is-filled-req > :is(input, select, textarea):not(.ro-lock, :disabled, .trk-kind-sub, .trk-kind-redir),
.field.is-missing.is-filled > .trk-datectl > input[data-mdy],
.field.is-missing.is-filled-req > .trk-datectl > input[data-mdy] {
  background:var(--bad-soft) !important; border-color:var(--bad-line) !important;   /* blocked wins */
}
/* Subdomain vs Redirect URL. Two different findings that used to render identically; the tint carries the
   distinction into the controls themselves so a filled row says which kind of change it is without the
   analyst re-reading the dropdown above it. */
.trk-kind-sub { background:#eef4ff !important; border-color:#9bb8f0 !important; color:#1e3a8a !important; }
.trk-kind-redir { background:#fdf2f8 !important; border-color:#eeaac9 !important; color:#8a1f5c !important; }
.trk-secttl .sect-left { float:right; font-weight:600; font-size:11.5px; color:var(--bad); text-transform:none; letter-spacing:0; }
.trk-secttl .sect-done { float:right; font-weight:600; font-size:11.5px; color:var(--ok,#0f6e56); text-transform:none; letter-spacing:0; }
@media (prefers-reduced-motion:reduce) {
  *,*::before,*::after { animation-duration:.001ms !important; animation-iteration-count:1 !important; transition-duration:.001ms !important; scroll-behavior:auto !important; }
}
/* The `hidden` ATTRIBUTE must beat any author display:. Three elements already defeated it
   (#hsPager, #trkVerticalWrap, #trkSaveBar) and stayed invisible only by being empty. Verified safe:
   nothing in this app is revealed by writing style.display onto an element that also carries `hidden`. */
[hidden] { display:none !important; }
.sr-only { position:absolute; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden;
           clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap; border:0; }
* { box-sizing:border-box; }
html { -webkit-text-size-adjust:100%; zoom:.81; }  /* keep in step with --zoom/--vw/--vh above */
body { margin:0; font-family:Inter,system-ui,Segoe UI,sans-serif; font-size:14px; line-height:1.55; color:var(--ink);
  background:radial-gradient(1200px 620px at 100% -10%, #e6ecfd 0%, transparent 55%), radial-gradient(900px 480px at -10% 100%, #eef2fe 0%, transparent 50%), var(--bg); background-attachment:fixed; }
a { color:var(--accent); text-decoration:none; }

/* ---------- sidebar ---------- */
.sidebar { position:fixed; top:0; left:0; width:var(--sidebar-w); height:var(--vh); background:var(--navy);
  display:flex; flex-direction:column; z-index:40; transition:transform .25s ease; border-right:1px solid var(--navy-line); }
.sidebar-brand { display:flex; align-items:center; gap:10px; padding:22px 20px 18px; cursor:pointer; border-radius:10px; transition:background .15s; }
.sidebar-brand:hover { background:var(--navy-2); }
.nav-label { display:flex; flex-direction:column; line-height:1.2; }
.nav-flag { font-size:9.5px; font-weight:700; letter-spacing:.05em; text-transform:uppercase; color:#6f8ef2; margin-top:2px; }  /* 5.13:1 on navy */
.sidebar-brand .mark { width:32px; height:32px; border-radius:9px; background:var(--grad); color:#fff; display:grid; place-items:center; font-size:15px; flex:none; box-shadow:0 4px 14px -2px rgba(59,91,219,.55); }
.sidebar-brand b { color:#fff; font-size:15px; font-weight:700; letter-spacing:-.01em; }
.sidebar-sec { padding:0 20px; margin:14px 0 6px; font-size:10.5px; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--navy-muted); }
nav.tabs { display:flex; flex-direction:column; gap:2px; padding:2px 12px; flex:1; }
nav.tabs a { position:relative; display:flex; align-items:center; gap:11px; padding:10px 12px; border-radius:10px; font-size:13.5px; font-weight:500; color:var(--navy-muted); cursor:pointer; white-space:nowrap; transition:background .15s, color .15s; }
nav.tabs a .ic { width:18px; height:18px; flex:none; display:grid; place-items:center; opacity:.85; }
nav.tabs a .ic svg { width:17px; height:17px; }
nav.tabs a:hover { color:#fff; background:var(--navy-2); }
nav.tabs a.active { color:#fff; background:var(--navy-3); font-weight:600; }
nav.tabs a.active::before { content:''; position:absolute; left:-12px; top:8px; bottom:8px; width:3px; border-radius:0 3px 3px 0; background:var(--accent2); box-shadow:0 0 10px 1px rgba(97,130,240,.7); }
nav.tabs a.active .ic { opacity:1; color:var(--accent2); }
.sidebar-foot { padding:16px 20px 20px; border-top:1px solid var(--navy-line); }
.conn { display:flex; align-items:center; gap:7px; font-size:12px; color:var(--navy-muted); white-space:nowrap; }
.conn .led { width:8px; height:8px; border-radius:50%; background:#4a5075; flex:none; }
.conn.live .led { background:var(--ok); box-shadow:0 0 0 3px rgba(14,159,110,.25); }
.conn.live { color:#c9f1de; }

/* mobile top bar + overlay */
.mobile-bar { display:none; position:sticky; top:0; z-index:30; background:var(--navy); color:#fff; align-items:center; gap:12px; padding:0 16px; height:56px; }
.mobile-bar .mark { width:28px; height:28px; border-radius:8px; background:var(--grad); display:grid; place-items:center; font-size:13px; flex:none; }
.hamburger { background:none; border:none; color:#fff; width:34px; height:34px; border-radius:8px; display:grid; place-items:center; cursor:pointer; }
.hamburger:hover { background:var(--navy-2); }
.sidebar-overlay { display:none; position:fixed; inset:0; background:rgba(15,17,30,.5); z-index:35; }

main { max-width:1080px; margin:0 auto; padding:30px 24px 70px; margin-left:calc(var(--sidebar-w) + max(0px, (var(--vw) - var(--sidebar-w) - 1080px) / 2)); }
.page { display:none; }
.page.active { display:block; animation:fade .18s ease; }
@keyframes fade { from { opacity:0; transform:translateY(4px); } to { opacity:1; transform:none; } }
.page-head { margin-bottom:22px; }
.page-head h1 { margin:0; font-size:26px; font-weight:700; letter-spacing:-.02em; color:var(--ink); }
.page-head p { margin:6px 0 0; color:var(--muted); max-width:64ch; }

.panel { background:var(--panel); border:1px solid var(--line); border-radius:var(--r-lg); padding:var(--s-6); margin-bottom:var(--s-5); box-shadow:var(--e-1); transition:box-shadow var(--t-med) var(--ease); }
.panel:hover { box-shadow:var(--e-2); }
.panel h2 { margin:0 0 3px; font-size:14px; font-weight:700; letter-spacing:-.01em; }
.panel .hint { margin:0 0 16px; color:var(--muted); font-size:12.5px; }
/* hero panel — single inset accent bar (scarcity = premium; use sparingly) */
.panel.hero { box-shadow:var(--e-2); position:relative; overflow:hidden; }
.panel.hero::before { content:''; position:absolute; top:0; left:0; right:0; height:3px; background:var(--grad); }
/* in-page segmented sub-tabs */
.subtabs { display:inline-flex; gap:4px; padding:4px; background:var(--line-soft); border:1px solid var(--line); border-radius:var(--r-md); margin-bottom:var(--s-5); }
.subtab { border:none; background:transparent; padding:8px 18px; border-radius:var(--r-sm); font:inherit; font-weight:600; font-size:13px; color:var(--muted); cursor:pointer; transition:background var(--t-fast), color var(--t-fast); }
.subtab:hover { color:var(--ink); }
.subtab.active { background:#fff; color:var(--accent); box-shadow:var(--e-1); }
.grid2 { display:grid; grid-template-columns:1fr 1fr; gap:18px; }
@media (max-width:720px){ .grid2 { grid-template-columns:1fr; } }

.field { display:flex; flex-direction:column; gap:5px; min-width:0; }
/* :not(.hint) because the hint under a control is also a direct span child, and the label's uppercase
   treatment turned every hint into a shouted sentence. .gw-rows below already excludes it the same way. */
.field > span:not(.hint) { font-size:11px; font-weight:600; letter-spacing:.04em; text-transform:uppercase; color:var(--muted); }
.field > span.hint { display:block; margin-top:5px; color:var(--muted); line-height:1.45; }
.trk-secttl { font-size:12px; font-weight:700; letter-spacing:.05em; text-transform:uppercase; color:var(--accent); margin:16px 0 8px; padding-bottom:5px; border-bottom:1px solid var(--line); }
/* Section title doubles as an action row when a section has a control (the Card refresh). */
.trk-secttl { display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.trk-secttl .msg { text-transform:none; letter-spacing:0; font-weight:500; }
.trk-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(230px,1fr)); gap:12px 14px; }
#trkForm textarea { width:100%; padding:10px 12px; border:1px solid var(--line-strong); border-radius:var(--r-md); font:inherit; background:#fff; color:var(--ink); resize:vertical; }
#trkTable th, #trkTable td { white-space:nowrap; }
#trkFilters select, #trkFilters input { width:auto; }
.field.trk-hl { background:rgba(255,192,0,.10); border:1px solid rgba(255,192,0,.45); border-radius:8px; padding:8px 9px; }
.field.trk-hl > span { color:#9a6b00; }
/* The one read-only look, shared by the standard form (trkRoInput) and the wizard (gwInput). A disabled
   <select> is greyed and dimmed by the UA, so it is pinned back to the readonly input's appearance. */
.ro-lock { background:var(--panel2,#f4f6fb); font-weight:600; }
select.ro-lock { color:var(--ink); opacity:1; cursor:not-allowed; }
.row { display:flex; gap:12px; flex-wrap:wrap; align-items:flex-end; }
input, select { width:100%; padding:10px 12px; border:1px solid var(--line-strong); border-radius:var(--r-md); font:inherit; background:#fff; color:var(--ink); transition:border-color var(--t-fast), box-shadow var(--t-fast); }
input:focus, select:focus { outline:0; border-color:var(--accent); box-shadow:var(--e-focus); }
input[type=file]{ padding:8px 10px; }
/* The rule above is written for text inputs and selects, and a radio or checkbox inherits it: width:100% plus
   10px of padding turns a 16px control into a full-width box. Every checkbox in here already fought that off
   with an inline width, which only works for the ones that remember to. Fix it once, at the source. */
input[type=radio], input[type=checkbox]{ width:auto; padding:0; }
.btn { display:inline-flex; align-items:center; justify-content:center; gap:7px; min-height:40px; padding:10px 16px; border:1px solid transparent; border-radius:var(--r-md); background:var(--accent); color:#fff; font:inherit; font-weight:600; font-size:13.5px; cursor:pointer; white-space:nowrap; transition:background var(--t-fast), box-shadow var(--t-fast), transform .06s; box-shadow:var(--e-accent); }
.btn:hover:not(:disabled){ background:var(--accent2); box-shadow:0 8px 22px -6px var(--accent-ring); }
.btn:active:not(:disabled){ background:var(--accent-press); transform:translateY(1px); box-shadow:var(--e-1); }
.btn:focus-visible{ box-shadow:var(--e-accent), var(--e-focus); }
.btn.ghost { background:#fff; color:var(--accent); border-color:var(--line-strong); box-shadow:var(--e-1); }
.btn.ghost:hover:not(:disabled){ background:var(--accent-soft); border-color:var(--accent-soft-2); }
.btn.ghost:active:not(:disabled){ transform:translateY(1px); }
.btn.mini { min-height:32px; padding:5px 11px; font-size:12px; border-radius:var(--r-sm); box-shadow:none; }
.btn.mini.ghost { box-shadow:none; }
/* A card slot that arrived from the Submit Card hand-off. Green = "this came from a generated card",
   which is the only way a slot is ever legitimately filled: the inputs are readonly. */
input.trk-auto { background:#eafaf1 !important; color:#0f6e56 !important; border-color:#7fd8b4 !important; font-weight:500; }
.btn.ghost.danger { color:var(--bad); border-color:var(--bad-line); }
.btn.ghost.danger:hover:not(:disabled) { background:var(--bad-soft); border-color:var(--bad); }
/* Sits after every .btn variant on purpose. `.btn:disabled` ties with `.btn.ghost` on specificity,
   so while it came first the ghost background and accent text won and a disabled ghost button
   still looked clickable - only cursor:not-allowed survived. */
.btn:disabled, .btn.ghost:disabled, .btn.ghost.danger:disabled { background:var(--line-strong); color:var(--faint); border-color:transparent; box-shadow:none; cursor:not-allowed; }
.msg { font-size:12.5px; color:var(--muted); margin:12px 0 0; min-height:1em; }
.mono { font-family:var(--mono); font-size:13px; word-break:break-all; }
code { font-family:var(--mono); font-size:12px; background:var(--line-soft); padding:1px 5px; border-radius:5px; }
