/* Circuit: the shared Agreement Tracker layout with light and dark palettes. */
:root {
  color-scheme:light;
  /* BRAND-COLORS.md, copied exactly (ground rule 11; test/brand-colors.test.js). The role tokens below are these. */
  --df-navy:#131533;--df-violet:#5B3E84;--df-blue:#3C67A6;--df-teal:#29A4A6;--df-teal-ink:#1F7B7D;
  --df-blue-light:#678FC8;--df-violet-light:#9B7FC3;--df-page:#F4F5F9;--df-surface-dark:#1D2047;--df-text-dark:#E8EAF4;
  --brand:var(--df-navy);--brand-light:color-mix(in srgb,var(--df-navy) 82%,#fff);--accent:var(--df-teal-ink);--accent-hover:color-mix(in srgb,var(--df-teal-ink) 82%,var(--df-navy));
  --bg:var(--df-page);--surface:#fff;--surface2:#F2F3F8;--border:#DADDE8;--border-strong:#B8BDD1;
  --text:var(--df-navy);--text-muted:#545A78;--text-light:#5F6582;--purple:var(--df-violet);
  --font:system-ui,-apple-system,sans-serif;--radius:4px;
  --shadow:0 4px 16px #1315330a;--shadow-lg:0 16px 50px #13153320;
  --button-text:#fff;--warning:#81541a;--warning-bg:#fff3dd;
}
:root[data-circuit-theme=dark] {
  color-scheme:dark;
  --brand:var(--df-text-dark);--brand-light:color-mix(in srgb,var(--df-text-dark) 80%,var(--df-navy));--accent:var(--df-teal);--accent-hover:color-mix(in srgb,var(--df-teal) 80%,#fff);
  --bg:var(--df-navy);--surface:var(--df-surface-dark);--surface2:#252957;--border:#33376A;--border-strong:#4A4F85;
  --text:var(--df-text-dark);--text-muted:#A9ADCB;--text-light:#9DA2C2;--purple:var(--df-violet-light);
  --signed:#8ee0b8;--signed-bg:#173b32;--pending:#f0d294;--pending-bg:#403626;
  --paid:#b4cbff;--paid-bg:#253754;--expired:#bcc5d6;--expired-bg:#2b3345;
  --attention:#ffbbcc;--attention-bg:#48283e;--button-text:var(--df-navy);
  --warning:#f0ca8a;--warning-bg:#403326;--shadow:0 6px 24px #0001;--shadow-lg:0 16px 50px #0005;
}
body{font-size:14px;line-height:1.5}
button,input,select,textarea{font-family:var(--font-ui)}
button:focus-visible,a:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
header{background:var(--surface);color:var(--text);border-top:2px solid var(--purple);border-bottom:1px solid var(--border);box-shadow:none;min-height:70px;height:auto;padding:12px 28px;gap:18px;flex-shrink:0}
.header-title,.header-divider,.user-pill,.sign-out-btn{color:var(--text-muted)}
.header-title{font-size:13px;letter-spacing:.03em}
.user-pill{background:var(--surface2)}
.user-avatar{background:var(--accent);color:var(--button-text)}
#app>div[style*="text-align: center"]{background:var(--warning-bg)!important;color:var(--warning)!important;border-bottom:1px solid var(--border);font-size:12px}
.sign-out-btn{border-color:var(--border-strong);min-height:36px}
.sign-out-btn:hover{color:var(--text);border-color:var(--accent)}
.plan-badge{color:var(--purple);border-color:var(--purple);border-radius:3px;font-size:11px}
.auth-card>.appearance-control{margin:0 0 16px auto}
.appearance-control.appearance-compact{display:grid;place-items:center;width:34px;height:34px;flex-shrink:0;padding:0;border:1px solid var(--border-strong);border-radius:50%;background:var(--surface2);color:var(--text-muted);cursor:pointer}
.appearance-compact>span{display:flex;pointer-events:none}
.appearance-compact:hover{border-color:var(--accent);color:var(--text)}
.appearance-compact:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.auth-card{border-radius:6px;border-top:2px solid var(--purple)}
.auth-logo{background:#fff}
.auth-btn,.btn-primary,.split-btn-main{background:var(--accent);border-color:var(--accent);color:var(--button-text)}
.auth-btn:hover,.btn-primary:hover{background:var(--accent-hover)}
.tab-nav{padding:0 28px;background:var(--surface);gap:8px;overflow-x:auto;flex-shrink:0}
.tab-nav{scrollbar-width:none;-webkit-overflow-scrolling:touch}
.tab-nav::-webkit-scrollbar{display:none}
/* The grouped tabs (Review & follow-up, Reports) drop a menu below the bar, which a scrolling bar clips to nothing: it wraps instead (dry run, 2026-10-06). */
.tab-nav:has(.nav-group){overflow:visible;flex-wrap:wrap}
.tab-btn{font-size:13px;min-height:48px;white-space:nowrap}
.tab-btn.tab-active{color:var(--accent);border-bottom-color:var(--accent)}
.circuit-intro{position:relative;display:flex;align-items:center;justify-content:space-between;gap:20px;margin:16px 32px 18px;padding:24px 26px 20px;background:linear-gradient(120deg,var(--surface2),transparent);border:1px solid var(--border);border-top:2px solid var(--purple);border-radius:6px;flex-shrink:0}
.circuit-intro span{color:var(--purple);font-size:11px;letter-spacing:1.2px;font-weight:650}
.circuit-intro h1{font-size:28px;letter-spacing:-.8px;line-height:1.2;margin:7px 0}
.circuit-intro p{font-size:13px;color:var(--text-muted)}
.circuit-intro svg{width:240px;height:85px;color:var(--accent);opacity:.18}
.summary-strip{margin:0 32px 18px;padding:0;background:transparent;border:0;gap:14px;align-items:stretch;flex-wrap:wrap}
.stat{background:var(--surface);border:1px solid var(--border);border-top:2px solid var(--border-strong);border-radius:4px;padding:16px 22px;flex:1;min-width:130px}
.stat:nth-of-type(3){border-top-color:var(--purple)}
.stat:last-of-type{border-top-color:var(--accent)}
.stat-val{font-size:27px;letter-spacing:-.5px;font-weight:650;font-variant-numeric:tabular-nums}
.stat-label{font-size:12px;letter-spacing:.03em}
.stat-divider{display:none}
.toolbar{padding:14px 32px;gap:10px;background:var(--surface);border-block:1px solid var(--border);flex-wrap:wrap;flex-shrink:0}
.search-input,.filter-select{min-height:39px;font-size:13px;border-radius:4px}
.table-wrap{padding:20px 32px}
table{border-radius:4px;border:1px solid var(--border);box-shadow:var(--shadow)}
th{background:var(--surface2);color:var(--text-muted);font-size:12px;letter-spacing:.025em;padding:13px 16px}
thead tr{background:var(--surface2);color:var(--text-muted)}
th:hover,th.sorted{color:var(--text);background:var(--surface2)}
th.sorted{box-shadow:inset 0 -2px var(--accent);font-weight:650}
th .sort-icon{color:inherit;opacity:.8}
th.sorted .sort-icon{color:var(--accent);opacity:1}
tbody tr:hover,tbody tr.expanded{background:var(--surface2)}
td{padding:16px}
.vendor-name,.product-name,.amount-val{font-size:14px}
.vendor-doc,.product-detail,.amount-sub,.term-label{font-size:12px}
.badge,.renewal-badge{border-radius:3px;font-size:11px}
.detail-card,.notes-box,.modal,.analytics-card,.savings-card,.pdf-processing-card,.split-btn-menu{border-radius:4px;background:var(--surface);border-color:var(--border)}
.modal-header{border-top:2px solid var(--purple)}
.form-label{font-size:12px;color:var(--text-muted)}
.circuit-check{display:grid;grid-template-columns:18px minmax(0,1fr);align-items:start;gap:10px;font-size:14px;line-height:1.5;color:var(--text);cursor:pointer}
.circuit-check input{width:18px;height:18px;margin:2px 0 0;accent-color:var(--accent)}
#spend-choice{padding:16px;background:var(--surface2);border:1px solid var(--border);border-radius:4px;margin:8px 0 20px}
#spend-choice p{margin:8px 0 0 28px;color:var(--text-muted);font-size:12px;line-height:1.6}
.form-row.circuit-notice{grid-template-columns:1fr;gap:0;margin-bottom:16px}
.circuit-notice .form-group:first-child{max-width:240px}
#pipeline-outer article,#pipeline-container article,#tab-pipeline .pipeline-container article{background:var(--surface)!important;color:var(--text);border:1px solid var(--border)!important;border-left:3px solid var(--purple)!important;border-radius:4px!important;padding:18px 20px!important}
#pipeline-outer article p,#pipeline-container article p,#tab-pipeline .pipeline-container article p{color:var(--text-muted);margin-top:6px;font-size:13px}
#intake-panel{background:var(--surface)!important;color:var(--text);border:1px solid var(--border);border-radius:4px!important}
.form-input,.form-select,.form-textarea{background:var(--surface2);color:var(--text);font-size:14px;border-radius:4px}
.btn{border-radius:4px;min-height:36px}
.expiry-soon,.sv-hero-val.warn{color:var(--warning)}
.flag-box,.savings-empty,.ai-config-warn,.expiring-badge{background:var(--warning-bg);color:var(--warning);border-color:var(--warning)}
:root[data-circuit-theme=dark] .expiry-urgent{color:#ffb4b4}
:root[data-circuit-theme=dark] .pill-overdue{background:#4c1d1d;color:#fecaca}
:root[data-circuit-theme=dark] .pill-today{background:#422c0b;color:#fde68a}
/* The Obligations view's table hardcoded white, so its light-on-dark text vanished (dry run 3). */
:root[data-circuit-theme=dark] .ov-table{background:var(--surface);border-color:var(--border)}
:root[data-circuit-theme=dark] .savings-headline strong,:root[data-circuit-theme=dark] .sv-delta-pos,:root[data-circuit-theme=dark] .sv-hero-val.good{color:#8ee0b8}
:root[data-circuit-theme=dark] .sv-delta-neg{color:#ffb4b4}
:root[data-circuit-theme=dark] .field-extracted{background:#173b32!important;color:#d6f4e5!important}
:root[data-circuit-theme=dark] [style*="background:#fff"],:root[data-circuit-theme=dark] [style*="background: #fff"]{background:var(--surface2)!important;color:var(--text)!important}
:root[data-circuit-theme=dark] .notes-content{background:var(--surface2);color:var(--text)}
/* The Risk flags and Approval cards on an agreement hardcode a light palette (index.html says why);
   on the dark theme they were the only white boxes on the page (dry run, 2026-10-07). Each text
   color is re-pointed with its ground, so nothing here can put light text on white again. */
:root[data-circuit-theme=dark] .risk-box,:root[data-circuit-theme=dark] .approval-box{background:var(--surface);border-color:var(--border)}
:root[data-circuit-theme=dark] .risk-head,:root[data-circuit-theme=dark] .approval-head{background:var(--surface2);border-color:var(--border)}
:root[data-circuit-theme=dark] .risk-title,:root[data-circuit-theme=dark] .approval-title,:root[data-circuit-theme=dark] .risk-item-title,:root[data-circuit-theme=dark] .risk-fix,:root[data-circuit-theme=dark] .approval-box .detail-val{color:var(--text)}
:root[data-circuit-theme=dark] .risk-detail,:root[data-circuit-theme=dark] .risk-clear,:root[data-circuit-theme=dark] .risk-foot,:root[data-circuit-theme=dark] .approval-box .detail-key{color:var(--text-muted)}
:root[data-circuit-theme=dark] .risk-reads{color:var(--text-light)}
:root[data-circuit-theme=dark] .risk-fix-link:not(.act-btn){color:var(--accent)}
:root[data-circuit-theme=dark] .approval-note{color:var(--text);border-left-color:var(--border)}
:root[data-circuit-theme=dark] .approval-empty,:root[data-circuit-theme=dark] .approval-note-label,:root[data-circuit-theme=dark] .approval-foot{color:var(--text-muted)}
:root[data-circuit-theme=dark] .approval-foot{border-color:var(--border)}
:root[data-circuit-theme=dark] .risk-item,:root[data-circuit-theme=dark] .risk-foot{border-color:var(--border)}
@media(max-width:1050px){.circuit-intro svg{display:none}.tab-nav{padding-inline:12px}.tab-btn{padding-inline:10px;font-size:12px}}
/* The header's side padding and control gap tighten from 960px, as the Ticket Tracker's do (#259 A4b). */
@media(max-width:960px){header{padding-inline:16px}.header-right{gap:8px}}
@media(max-width:850px){
  header{padding:10px 16px;gap:10px}.header-left{min-width:0}.header-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.header-right{gap:8px}
  .circuit-intro{margin-inline:16px;padding:18px 16px}.circuit-intro h1{font-size:24px}
  .summary-strip{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));margin:0 16px 14px;gap:8px}.stat{padding:12px;min-width:0}.expiring-badge{grid-column:1/-1;margin-left:0;text-align:center}
  .toolbar{padding:12px 16px}.search-wrap{flex:1 0 100%;max-width:none}.filter-select{flex:1 1 145px;min-width:0}.toolbar-count{flex:1 0 100%;text-align:right}
  .table-wrap{padding:14px 16px}#contracts-table{min-width:760px}.tab-nav{padding:0 16px}
  .detail-grid,.form-row,.analytics-grid{grid-template-columns:1fr}.appearance-control{font-size:11px}
  .modal{width:calc(100% - 24px);max-height:94vh;padding:18px}.modal-footer{position:sticky;bottom:-18px;margin-inline:-18px;padding:12px 18px 18px;background:var(--surface);z-index:2;flex-wrap:wrap}.modal-footer .btn{flex:1 1 auto}
  .analytics-outer,.pipeline-outer,.savings-outer{padding:16px}
}
/* The header collapses at 600px in all four products (front-end parity, 2026-10-04; this was 560). */
@media(max-width:600px){.user-pill #user-name,.header-title,.header-divider{display:none}.user-pill{padding:5px}.header-mark img{max-width:54px}.sign-out-btn{padding-inline:9px;white-space:nowrap}.auth-card{padding:24px 18px}.stat-val{font-size:23px}.stat-label{font-size:10px}.toolbar>.archive-view-btn,.toolbar>.export-btn,.toolbar>.alert-btn,.split-btn-wrap{flex:1 1 calc(50% - 8px);min-width:0;justify-content:center}.split-btn-main{width:100%;min-width:0;padding-inline:8px;justify-content:center;font-size:12px}.toolbar-count{padding-right:2px}}
@media(max-height:700px){.circuit-intro{padding-block:12px}.circuit-intro svg{height:55px}.stat{padding-block:10px}}
@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation:none!important;transition:none!important}}
@media print{:root[data-circuit-theme]{color-scheme:light;--brand:var(--df-navy);--bg:#fff;--surface:#fff;--surface2:#F2F3F8;--text:var(--df-navy);--text-muted:#545A78;--text-light:#5F6582}.appearance-control,.circuit-intro{display:none}}
/* The Lite/Premium test switch (dev, qa, demo only). index.html styles it white-on-transparent for the
   pre-Circuit navy header; on Circuit's white light-mode header that was invisible (Matthew, 2026-09-24). */
.tier-switch{color:var(--text-muted);border-color:currentColor}.tier-switch:hover{background:var(--surface2);color:var(--text)}
/* Sign-in card, Matthew 2026-09-24: the product name larger and in the main ink, and the environment line as a
   yellow caution badge. The old brown (#784600) read 2.1:1 on the dark card. The badge is 11:1 in both modes and
   never shows empty: prod has no environment line. */
.auth-subtitle{font-size:1.05rem;font-weight:600;letter-spacing:.06em;color:var(--text)}
.auth-env{display:inline-block;margin:0 0 1rem;padding:.3rem .75rem;border:1px solid #d9a800;border-radius:6px;background:#ffd23f;color:#2b2100;font-size:.95rem;font-weight:800;letter-spacing:.04em}
.auth-env:empty,.auth-env[hidden]{display:none}
/* Sign-in card, Matthew 2026-09-24: the product name on the top row beside the appearance control, above the logo,
   and the DEV badge evenly spaced between the logo and the sign-in button. The control is pinned to the card's corner
   so the name can share its row; the name's side padding keeps it clear of the control, more on a phone,
   where the card's own padding is narrower. The logo owns the gap below it, so prod, which has no badge, keeps the same gap. */
.auth-card{position:relative;padding-top:1.6rem}
.auth-card>.appearance-control{position:absolute;top:1.1rem;right:1.1rem;margin:0}
.auth-card>.auth-subtitle{min-height:34px;display:flex;align-items:center;justify-content:center;margin:0 0 1rem;padding:0 16px;font-size:1.15rem}
.auth-card>.auth-logo-wrap{margin-bottom:1.4rem}
.auth-card>.auth-env{margin:0 0 1.4rem}
@media(max-width:600px){.auth-card>.auth-subtitle{padding:0 42px}}
/* The Premium tier badge, Matthew 2026-09-24 ("looks weird", seen on the Project Tracker): the
   pre-Circuit pages filled it dark green and the rule above colored its text Circuit purple, so
   Premium read purple on dark green; the Agreement Tracker never filled it, so Premium looked like
   Lite. Premium is the primary teal chip with the button text color, 5.0:1 in light and 5.9:1 in
   dark, and Lite keeps the violet outline. The same in all four products. In the navy header the
   shared:navy-header block below draws both in Teal (BRAND-COLORS.md). */
body[data-plan="premium"] .plan-badge{background:var(--accent);border-color:var(--accent);color:var(--button-text)}

/* Compact working headers: general update for Lite and Premium. */
.circuit-intro{padding:14px 20px;margin-bottom:12px;gap:12px}
.circuit-intro h1{font-size:22px;line-height:1.25;letter-spacing:-.4px;margin:0 0 4px}
.circuit-intro p{margin:0;font-size:14px;line-height:1.45}
.circuit-intro>div>span,.circuit-intro>svg{display:none}
@media(max-width:600px){
  .circuit-intro{padding:12px 16px;margin-bottom:10px}
  .circuit-intro h1{font-size:20px}
  .circuit-intro p{font-size:13px}
}

/* Keep the environment-only tier switch on its own row on narrow screens. Here from 800px, not 600
   as in the other three: this header carries a longer product name and the appearance control, and
   between 600 and 800 the switch, which never wraps inside itself, would otherwise run under the
   user pill (agreement-tracker#259 row A4b). The product name shortens before the pill drops a row. */
@media(max-width:800px){
  #app>header:not(.top),.brand-bar{flex-wrap:wrap;gap:8px;padding:10px 16px}
  .header-left,.brand-left{display:contents}
  .header-right{margin-left:auto;gap:6px;flex-shrink:0}
  .header-title{flex:1 1 0;max-width:max-content}
  .tier-switch{order:3;flex:1 0 100%;width:100%;margin:0;min-height:32px;
    white-space:normal;border-radius:6px;padding:6px 10px}
}

.workspace-tools{--workspace-line:var(--border);--workspace-panel:var(--surface);--workspace-accent:var(--accent)}

/* Native disclosure keeps secondary tools keyboard accessible. ⚙ Tools ▾ (dry run 5, 2026-10-08): a
   teal-outline button on the RIGHT of the bar; its panel drops down under it, right-aligned, over the
   content, so opening it never re-flows the bar or moves the button. */
.workspace-tools{flex:0 0 auto;min-width:0;position:relative}
.toolbar>.workspace-tools{order:99;margin-left:auto}
.workspace-tools>summary{cursor:pointer;list-style:none;display:inline-flex;align-items:center;min-height:40px;padding:8px 12px;
  border:1px solid var(--accent);border-radius:6px;background:var(--surface);
  color:var(--accent);font-size:14px;font-weight:600;line-height:22px;white-space:nowrap}
.workspace-tools>summary::-webkit-details-marker{display:none}
.workspace-tools>summary:hover,.workspace-tools[open]>summary{background:color-mix(in srgb,var(--accent) 12%,var(--surface))}
.workspace-tools>summary::marker{content:""}
.workspace-tools>summary:focus-visible{outline:2px solid var(--workspace-accent);outline-offset:3px}
.workspace-tools .workspace-tool-list{position:absolute;top:calc(100% + 6px);right:0;z-index:60;display:flex;flex-direction:column;align-items:stretch;gap:6px;
  min-width:220px;max-width:calc(100vw - 32px);padding:10px;border:1px solid var(--workspace-line);border-radius:6px;background:var(--workspace-panel);box-shadow:var(--shadow-lg)}
.workspace-tool-list>button,.workspace-tool-list>a{min-height:40px;justify-content:flex-start;white-space:nowrap}
.workspace-tool-list>[hidden]{display:none!important}

.circuit-intro{margin-inline:32px}
.summary-strip{gap:10px;margin-bottom:12px}
.stat{padding:10px 16px}
.stat-val{font-size:24px}
.toolbar{padding-block:12px;gap:8px}
.toolbar .search-wrap{min-width:180px}
.toolbar .split-btn-main,.toolbar .filter-select,.toolbar .search-input{min-height:40px}
/* One text size across the toolbar: buttons, links, search, selects and the count were 12.8 to 14px
   (dry run 3, 2026-10-07), the CRM's fix. */
.toolbar :is(button,a,select,input,summary),.toolbar .toolbar-count{font-size:14px}
@media(max-width:850px){.circuit-intro{margin-inline:16px}.stat{padding:8px 12px}}
@media(max-width:600px){
  .toolbar .search-wrap{flex:1 0 100%}
  .toolbar .filter-select{flex:1 1 calc(50% - 8px);font-size:14px}
  .toolbar>.split-btn-wrap{flex:1 0 calc(100% - 96px)}
  .toolbar .split-btn-main{font-size:14px}
  .stat-label{font-size:11px}
}

/* Phone workspaces keep the first useful record close to the controls. */
@media(max-width:640px){.circuit-intro p{display:none}.circuit-intro{padding-block:8px}.circuit-intro h1{margin:0;font-size:18px}}
@media(max-width:640px){.summary-strip{grid-template-columns:repeat(4,minmax(0,1fr));gap:5px}.summary-strip .stat{padding:7px 5px}.summary-strip .stat-val{font-size:20px}.summary-strip .stat-label{font-size:9px}.summary-strip .stat-note{font-size:9px}}

/* dialog-chrome -- every pop-up window, the same in all four products (test/dialog-chrome.test.js).
   Matthew, 2026-10-08: "I have to scroll all the way back up to the top and click the X in the
   corner to close this window". The title row and its close button stay at the top while the
   body scrolls under them; a window with nothing to save ends with a Close button of its own;
   Escape closes it; and every title is 1.3rem, 700, in the heading color. The header takes over
   the window's top padding, so it sticks to the very top edge with no strip above it. */
.modal{padding-top:0}
.modal-header,.dialog-head{position:sticky;top:0;z-index:5;background:var(--surface);border-bottom:1px solid var(--border)}
.modal-header{margin:0 -1.75rem 1.25rem;padding:1.25rem 1.75rem .75rem}
.detail-modal .modal-header{margin:0;padding:1rem 1.25rem .75rem}
.modal-title,.dialog-head h2{font-size:1.3rem;font-weight:700;line-height:1.3;letter-spacing:-.01em;color:var(--brand);min-width:0;overflow-wrap:anywhere}
.modal-close{flex-shrink:0;min-width:36px;min-height:36px;border-radius:var(--radius);font-size:1.2rem}
.modal-close:hover{color:var(--text);background:var(--surface2)}
.plan-dialog{padding-top:0}
.plans-head.dialog-head{margin:0 -1.5rem 1rem;padding:1.25rem 1.5rem .75rem}
.dialog-foot{display:flex;justify-content:flex-end;gap:.75rem;margin-top:1.25rem;padding-top:1rem;border-top:1px solid var(--border)}
.detail-modal .dialog-foot{margin:0;padding:.75rem 1.25rem 1.25rem}
@media(max-width:850px){.modal{padding:0 18px 18px}.modal-header{margin:0 -18px 14px;padding:14px 18px 10px}.detail-modal .modal-header{margin:0;padding:12px 14px 10px}.detail-modal .dialog-foot{padding:.75rem 14px 14px}}
@media(max-width:720px){.plans-head.dialog-head{margin:0 -1rem .75rem;padding:1rem 1rem .6rem}}
/* end dialog-chrome */
/* shared:ai-mark-dark -- identical in all four products (test/brand-colors.test.js). BRAND-COLORS.md's
   Violet light reads 4.6:1 on a dark card but 4.0:1 on the AI box's own violet tint, so in dark mode the
   AI marks take the same hue lightened, 5.7:1 there: the shade the file allows where text would fail. */
:root[data-circuit-theme=dark] :is(.ai-label,.ai-fill-note,.ai-filled,.ai-filled span,#entry-mode.entry-mode-filled){color:color-mix(in srgb,var(--df-violet-light) 75%,#fff)}
/* end shared:ai-mark-dark */
/* shared:navy-header -- identical in all four products (test/brand-colors.test.js, test/parity.test.js).
   Matthew, 2026-10-10 (BRAND-COLORS.md, ground rule 11): the top bar is Deep Navy in both modes, its
   text white, and its own accents -- the underline, the plan badge, the tier switch, the avatar and
   focus rings -- Teal. The selector is each product's top bar, the header that opens #app on the board
   and on the import page (the Project Tracker's brand bar), never a header.top card inside <main>
   (the Project Tracker's project card and its import page's title).
   Since 2026-10-10 (checklist item 95, "My big thing is consistency with all these apps") this block
   sets the whole header, not only its colors: every part's type, size, spacing and the three
   breakpoints, so no product rule can make one product's header read differently (the CRM's "/" was
   a different glyph from the Agreement Tracker's because the header inherited each page's own font
   stack). The anatomy and every value are DESIGN.md's "UI standard"; a product keeps only its own
   title text and its own placement on the page: whether the bar sticks, and the Project Tracker's bleeding out of .wrap.
   Values are the Agreement Tracker's, the reference, except where three products agreed. */
#app>header:first-child{background:var(--df-navy);color:#fff;border-top-color:var(--df-navy);border-bottom-color:var(--df-teal)}
#app>header:first-child :is(.header-title,.brand-title,.who,.user-pill,.sign-out-btn){color:#fff}
#app>header:first-child #header-title{font-family:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;font-size:.85rem;font-weight:400;letter-spacing:.06em;text-transform:uppercase;line-height:1.5;color:#fff}
#app>header:first-child :is(.header-divider,.brand-divider){color:rgba(255,255,255,.6)}
#app>header:first-child .user-pill{background:rgba(255,255,255,.1)}
#app>header:first-child .user-avatar{background:var(--df-teal);color:var(--df-navy)}
#app>header:first-child :is(.sign-out-btn,.btn,.appearance-control){background:transparent;color:#fff;border-color:rgba(255,255,255,.4)}
#app>header:first-child :is(.sign-out-btn,.btn,.appearance-control):hover{background:rgba(255,255,255,.08);color:#fff;border-color:var(--df-teal)}
#app>header:first-child .tier-switch{color:#fff;border-color:var(--df-teal)}
#app>header:first-child .tier-switch:hover{background:rgba(255,255,255,.12);color:#fff}
#app>header:first-child .plan-badge{background:transparent;border-color:var(--df-teal);color:var(--df-teal)}
body[data-plan="premium"] #app>header:first-child .plan-badge{background:var(--df-teal);border-color:var(--df-teal);color:var(--df-navy)}
#app>header:first-child :focus-visible{outline-color:var(--df-teal)}
#app>header:first-child{display:flex;align-items:center;justify-content:space-between;flex-wrap:nowrap;gap:18px;box-sizing:border-box;height:auto;min-height:70px;padding:12px 28px;box-shadow:none;border-width:2px 0 1px;border-style:solid;font-family:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;font-size:14px;font-weight:400;font-style:normal;line-height:1.5;letter-spacing:normal;text-transform:none}
#app>header:first-child .header-left{display:flex;align-items:center;gap:12px;min-width:0;margin:0;padding:0}
#app>header:first-child .header-mark{display:inline-flex;align-items:center;flex-shrink:0;margin:0;padding:0}
#app>header:first-child .header-mark img{display:block;height:34px;width:auto;max-width:none;margin:0;padding:0}
#app>header:first-child .header-divider{font-family:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;font-size:16px;font-weight:400;line-height:24px;letter-spacing:normal;margin:0;padding:0;opacity:1}
#app>header:first-child #header-title{margin:0;padding:0;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#app>header:first-child .plan-badge{display:inline-flex;align-items:center;box-sizing:border-box;min-height:0;margin:0;padding:1px 8px;border-width:1px;border-style:solid;border-radius:4px;font-family:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;font-size:10.5px;font-weight:700;line-height:16px;letter-spacing:.08em;text-transform:uppercase;white-space:nowrap;cursor:pointer}
#app>header:first-child .tier-switch:not([hidden]){display:inline-flex}
#app>header:first-child .tier-switch{align-items:center;box-sizing:border-box;min-height:0;width:auto;flex:0 1 auto;order:0;margin:0 0 0 6px;padding:1px 9px;border-width:1px;border-style:dashed;border-radius:999px;font-family:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;font-size:10px;font-weight:700;line-height:1.5;letter-spacing:.06em;text-transform:uppercase;white-space:nowrap;cursor:pointer;background:transparent}
#app>header:first-child .header-right{display:flex;align-items:center;gap:16px;flex-shrink:0;margin:0;padding:0}
#app>header:first-child [data-appearance]:not([hidden]){display:grid}
#app>header:first-child [data-appearance]{place-items:center;box-sizing:border-box;width:34px;height:34px;min-height:34px;flex:0 0 auto;margin:0;padding:0;border-width:1px;border-style:solid;border-radius:50%;font-family:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;font-size:14px;line-height:1.5;cursor:pointer}
#app>header:first-child .user-pill{display:flex;align-items:center;gap:8px;box-sizing:border-box;margin:0;padding:3.2px 12px 3.2px 4px;border:0;border-radius:999px;font-family:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;font-size:12.8px;font-weight:400;line-height:1.5;letter-spacing:normal;white-space:nowrap}
#app>header:first-child .user-avatar{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:22px;height:22px;margin:0;padding:0;border-radius:50%;font-size:10.4px;font-weight:700;line-height:1.5;letter-spacing:normal}
#app>header:first-child :is(#user-name,#who){font-size:12.8px;font-weight:400;line-height:1.5;color:#fff;max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#app>header:first-child .sign-out-btn{box-sizing:border-box;min-height:36px;margin:0;padding:4.8px 11.2px;border-width:1px;border-style:solid;border-radius:6px;font-family:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;font-size:12.48px;font-weight:400;line-height:1.5;letter-spacing:normal;white-space:nowrap;cursor:pointer}
/* When space runs short the header gives way in one order, the same in all four, and no part ever
   wraps its own text: first the tier switch takes its short label (data-short, "Lite · switch"),
   then the signed-in name goes and the avatar stays, then the title shortens with an ellipsis (the
   whole name is its title attribute), then below 800px the switch drops to a row of its own and
   below 600px the title and the "/" go. 1440px at 125% zoom is 1152px wide, at 150% 960px. */
@media(max-width:1180px){#app>header:first-child .tier-switch[data-short]{font-size:0;letter-spacing:0}#app>header:first-child .tier-switch[data-short]::after{content:attr(data-short);font-size:10px;letter-spacing:.06em}}
@media(max-width:1100px){#app>header:first-child #user-name{display:none}#app>header:first-child .user-pill:not(:has(.user-avatar)){display:none}#app>header:first-child .user-pill{padding:5px}}
@media(max-width:960px){#app>header:first-child{padding-inline:16px}#app>header:first-child .header-right{gap:8px}}
@media(max-width:850px){#app>header:first-child{padding:10px 16px;gap:10px}}
@media(max-width:800px){
#app>header:first-child{flex-wrap:wrap;gap:8px;padding:10px 16px}
#app>header:first-child .header-left{display:contents}
#app>header:first-child #header-title{flex:1 1 0;max-width:max-content}
#app>header:first-child .tier-switch{order:3;flex:1 0 100%;width:100%;margin:0;min-height:32px;border-radius:6px;padding:6px 10px;overflow:hidden;text-overflow:ellipsis}
#app>header:first-child .tier-switch[data-short]{font-size:10px;letter-spacing:.06em}
#app>header:first-child .tier-switch[data-short]::after{content:none}
#app>header:first-child .header-right{margin-left:auto;gap:6px;flex-shrink:0}
}
@media(max-width:600px){
#app>header:first-child .header-mark img{max-width:54px}
#app>header:first-child :is(#header-title,.header-divider){display:none}
#app>header:first-child .sign-out-btn{padding-inline:9px}
}
#app>header:first-child .user-pill:has(#who:empty){display:none}
/* end shared:navy-header */
/* shared:ui-standard -- identical in all four products (test/parity.test.js). Checklist item 95
   (Matthew, 2026-10-10: "look at the actual code for every screen, the text size, all those things...
   Let's make them all consistent", and "log that as the standard so it doesn't ever drift or change").
   Every part of the board that has an equivalent in another product, set whole: type, size, weight,
   line height, letter spacing, padding, border widths, radius and height, from DESIGN.md's "UI
   standard", which is this block in prose. Each rule names every product's own class for the part,
   so the block is the same text in all four. :not(#_) lifts a rule above any product rule without an
   id; the colors are DESIGN.md's (BRAND-COLORS.md, ground rule 11), as --ui-* so a product's own
   variable names do not matter. A state color (a red Overdue, a green Signed, a tile's strip) stays
   the product's: only the shape and the type are set here. */
:root{--ui-font:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;--ui-surface:#FFFFFF;--ui-surface-2:#F2F3F8;--ui-line:#DADDE8;--ui-ink:#131533;--ui-muted:#545A78;--ui-accent:var(--df-teal-ink);--ui-accent-tint:#EDF7F7;--ui-on-accent:#FFFFFF;--ui-warn:#81541A;--ui-crit:#A73546}
:root[data-circuit-theme=dark]{--ui-surface:#1D2047;--ui-surface-2:#252957;--ui-line:#33376A;--ui-ink:#E8EAF4;--ui-muted:#A9ADCB;--ui-accent:var(--df-teal);--ui-accent-tint:#182C47;--ui-on-accent:var(--df-navy);--ui-warn:#F0CA8A;--ui-crit:#FFB4C0}
html body{font-family:var(--ui-font);font-size:14px;line-height:1.5}
html body :is(#app,dialog):not(#_) :is(button,input,select,textarea,summary,h1,h2,h3,h4,p,span,div,td,th,label,a,strong,b,li,small,em){font-family:var(--ui-font)}
/* The page intro: the card that opens every board, its heading and its one-line lead. */
#app:not(#_) :is(.circuit-intro,#main>header.top){padding:14px 20px;gap:12px;margin-bottom:12px;align-items:center;flex-wrap:wrap;min-height:auto;flex-shrink:0;font-size:14px;line-height:1.5;background-image:linear-gradient(120deg,var(--ui-surface),transparent)}
#app:not(#_) :is(.circuit-intro h1,#main>header.top h1){font-size:22px;font-weight:700;line-height:1.25;letter-spacing:-.4px;margin:0 0 4px;min-height:0}
#app:not(#_) :is(.circuit-intro p,#main>header.top .sub){font-size:14px;font-weight:400;line-height:1.45;margin:0}
/* Summary tiles: a row of equal tiles (two a row on a phone), each the value above its label, then
   any note. */
#app:not(#_) :is(.summary-strip,.stats,.rollup:has(>.rollup-card),.report-headline):not([hidden]){display:grid}
#app:not(#_) :is(.summary-strip,.stats,.rollup:has(>.rollup-card),.report-headline){grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:10px;align-items:stretch;flex-shrink:0;padding:0;margin-bottom:12px;overflow:visible}
#app:not(#_) :is(.stat,.report-tile,.tile,.rollup-card):not([hidden]){display:flex}
#app:not(#_) :is(.stat,.report-tile,.tile,.rollup-card){flex-direction:column;align-items:stretch;gap:2px;padding:12px 16px;border-radius:8px;box-shadow:none;min-height:auto;text-align:left;font-size:14px;line-height:1.5}
#app:not(#_) .rollup-card>.rollup-main{display:flex;flex-direction:column;align-items:flex-start;gap:2px;text-align:left}
#app:not(#_) :is(.stat .stat-val,.report-tile strong,.tile .v,.rollup-card .n){order:1;flex:none;font-size:24px;font-weight:700;line-height:1.2;letter-spacing:-.5px;margin:0;min-height:0}
#app:not(#_) :is(.stat .stat-label,.report-tile>span,.tile .k,.rollup-card .q){order:2;flex:none;font-size:11px;font-weight:600;line-height:1.5;letter-spacing:.06em;text-transform:uppercase;margin:0;min-height:0;color:var(--ui-muted)}
#app:not(#_) :is(.tile .n,.tile .tile-hint,.rollup-card .sub){order:3}
/* Tables: the header row and the cells. */
#app:not(#_) :is(thead th){font-size:11px;font-weight:700;line-height:1.5;letter-spacing:.05em;text-transform:uppercase;white-space:normal;padding:8px 12px;border-width:0 0 1px;border-style:solid;border-color:var(--ui-line);background-color:var(--ui-surface-2);color:var(--ui-muted)}
#app:not(#_) :is(tbody td){font-size:14px;font-weight:400;line-height:1.5;padding:10px 12px;border-width:0 0 1px;border-style:solid;border-color:var(--ui-line);border-radius:0;box-shadow:none;text-align:start}
/* Pills: a flag (Overdue, Hard gate) and a status (Signed, Open); their colors are the state's. */
#app:not(#_) :is(.pill-overdue,.b.gate,.badge,.b.plain,.status-pill,.sev-chip){align-items:center;gap:4px;font-size:11px;font-weight:700;line-height:16px;letter-spacing:.04em;text-transform:uppercase;white-space:nowrap;padding:2px 8px;border-width:0;border-radius:4px;min-height:0}
/* Buttons: the primary action, the secondary ones (the Tools list) and the Tools menu itself. */
#app:not(#_) :is(.split-btn-main,button.small,button.primary,#add-task,#new-project,.workspace-tool-list button,.workspace-tools>summary,button.ghost){align-items:center;justify-content:center;gap:6px;min-height:40px;padding:8px 14px;border-width:1px;border-style:solid;border-radius:6px;font-size:14px;font-weight:400;line-height:1.5;letter-spacing:normal;white-space:nowrap;text-align:center}
#app:not(#_) :is(.split-btn-main,button.small.primary,button.primary,#add-task,#new-project){font-weight:600}
#app:not(#_) :is(.workspace-tool-list button,button.ghost){color:var(--ui-muted);border-color:var(--ui-line)}
#app:not(#_) .workspace-tools>summary{font-weight:600}
/* Row actions (Fix here, Assign to me), already one rule in all four (test/parity.test.js). */
#app:not(#_) .act-btn{min-height:32px;padding:4px 12px;border-width:1px;border-radius:6px;font-size:13px;font-weight:600;line-height:1.2}
/* Fields: search boxes and selects. A search box with an icon keeps its own left padding. */
#app:not(#_) :is(#search,#q-contacts,#q,#f-q,.filter-select,#pipeline select,#f-status,#f-queue){min-height:40px;padding-top:8px;padding-bottom:8px;padding-right:10px;border-width:1px;border-style:solid;border-color:var(--ui-line);border-radius:6px;background-color:var(--ui-surface-2);font-size:14px;line-height:1.5}
#app:not(#_) :is(#q-contacts,#q,#f-q,.filter-select,#pipeline select,#f-status,#f-queue){padding-left:10px}
/* View switches: the Agreement Tracker's and the CRM's tabs, the Agreement Tracker's tab groups, the
   Project Tracker's Board | Phases and the Ticket Tracker's work views are one control, a row of
   bordered buttons, the pressed one filled (Matthew, 2026-10-11: "yes buttons on all four"). Each
   keeps its own markup and keyboard behavior; a tab group's menu keeps its own look. */
#app:not(#_) :is(.tab-nav,nav.tabs,.segmented,#work-views){gap:4px;align-items:center}
#app:not(#_) :is(.tab-nav,nav.tabs){padding-block:8px}
#app:not(#_) .segmented{border:0;border-radius:0;overflow:visible;background:transparent}
#app:not(#_) :is(.tab-nav>.tab-btn,.tab-nav>.nav-group>summary,nav.tabs>button,.seg,#work-views>button){align-items:center;gap:6px;min-height:36px;margin:0;padding:6px 12px;border:1px solid var(--ui-line);border-radius:6px;background:var(--ui-surface);color:var(--ui-ink);box-shadow:none;font-size:14px;font-weight:400;line-height:1.5;white-space:nowrap}
#app:not(#_) :is(.tab-nav>.tab-btn.tab-active,.tab-nav>.nav-group:has(.tab-active)>summary,nav.tabs>button.active,.seg[aria-pressed="true"],#work-views>button[aria-current]){background:var(--ui-accent);border-color:var(--ui-accent);color:var(--ui-on-accent);font-weight:600}
#app:not(#_) :is(.tab-nav>.tab-btn,nav.tabs>button)::after{content:none}
/* Dialogs. */
dialog:not(#_){border-radius:10px;padding:0 24px 24px;line-height:1.5;color:var(--ui-ink);border-color:var(--ui-line);box-shadow:0 16px 50px rgba(19,21,51,.125)}
dialog:not(#_) .dialog-head button{border-radius:6px;padding:0 6px}
dialog:not(#_) .plan-name{margin:0 0 6px;line-height:1.5}
/* Toasts: one look in all four, the light panel (Matthew, 2026-10-11: "one color", after the tier
   switch's note of 2026-10-08), with a colored left edge for a kind that has one: done, warning, error. */
:is(.toast-container>.toast,#toast:not(:has(>.toast)):not(:empty),#toast>.toast):not(#_){font-size:13px;font-weight:400;line-height:1.5;white-space:pre-line;padding:10px 14px;border:1px solid var(--ui-line);border-left:4px solid var(--ui-line);border-radius:8px;background:var(--ui-surface-2);color:var(--ui-ink);box-shadow:0 16px 50px rgba(19,21,51,.125);min-height:0}
:is(.toast-container>.toast-success,#toast>.toast.ok):not(#_){border-left-color:var(--ui-accent)}
:is(.toast-container>.toast-warn,#toast>.toast.warn):not(#_){border-left-color:var(--ui-warn)}
:is(.toast-container>.toast-error,#toast>.toast.err):not(#_){border-left-color:var(--ui-crit)}
/* The site-access banner. */
#config-notice:not(#_){font-size:13px;line-height:1.5;text-align:left;border-radius:6px;margin-bottom:12px;min-height:0}
#config-notice-msg:not(#_){font-size:13px;line-height:1.5;text-align:left}
/* Empty states: one sentence, centered, muted, no box of its own. */
#app:not(#_) :is(.empty-state,td.empty){font-size:14px;line-height:1.5;padding:32px 24px;text-align:center;border-width:0;border-radius:0;box-shadow:none;background-color:transparent;color:var(--ui-muted)}
/* Import pages: the way back, the column, the heading and its lead, the cards, their labels, buttons
   and fields. The Project Tracker's page sits inside its .wrap, whose padding stands in for the column's. */
#app:not(#_)>.back-bar{display:flex;align-items:center;gap:10px;min-height:0;padding:5px 28px;margin-bottom:12px;font-size:14px;line-height:1.5;background:var(--ui-surface);border-bottom:1px solid var(--ui-line);box-shadow:0 4px 16px rgba(19,21,51,.04)}
#app:not(#_)>.back-bar a{display:inline-flex;align-items:center;min-height:28px;font-size:14px;font-weight:600;line-height:1.5;color:var(--ui-accent);text-decoration:none}
#app:not(.wrap):not(#_)>.back-bar~#main{box-sizing:border-box;max-width:1240px;margin-inline:auto;padding:22px 28px 80px}
#app.wrap:not(#_)>.back-bar~#main{box-sizing:border-box;max-width:1184px;margin-inline:auto;padding:22px 0 80px}
#app:has(>.back-bar):not(#_) #main>h1{font-size:22px;font-weight:700;line-height:1.25;letter-spacing:-.4px;margin:0 0 4px}
#app:has(>.back-bar):not(#_) #main>:is(.lead,.sub){font-size:14px;font-weight:400;line-height:1.45;margin:0 0 12px}
#app:has(>.back-bar):not(#_) #main .card{margin-top:18px;padding:18px 20px;border-radius:8px;box-shadow:none}
#app:has(>.back-bar):not(#_) #main .card>.fl{margin-bottom:8px;font-size:11px;font-weight:700;line-height:1.5;letter-spacing:.06em;text-transform:uppercase;color:var(--ui-muted)}
#app:has(>.back-bar):not(#_) #main :is(.btn,label.ghost,button.ghost,.filebtn,#xlsx-download,#validate,#import,#ai-generate){align-items:center;justify-content:center;gap:6px;min-height:40px;padding:8px 14px;border:1px solid var(--ui-line);border-radius:6px;background:var(--ui-surface);color:var(--ui-ink);font-size:14px;font-weight:400;line-height:1.5;letter-spacing:normal;white-space:nowrap;text-align:center}
#app:has(>.back-bar):not(#_) #main :is(.btn-primary,button.primary,#import,#ai-generate){background:var(--ui-accent);border-color:var(--ui-accent);color:var(--ui-on-accent);font-weight:600}
#app:has(>.back-bar):not(#_) #main :is(.btn,button):disabled{opacity:.45}
#app:has(>.back-bar):not(#_) #main :is(input:not([type=checkbox]):not([type=radio]):not([type=file]),select,textarea){font-size:14px}
#app:has(>.back-bar):not(#_) #main #ai-source{padding:10px 12px;border-radius:6px;line-height:1.5}
@media(max-width:850px){#app:not(#_)>.back-bar{padding-inline:16px}}
@media(max-width:640px){
#app:not(#_) :is(.circuit-intro,#main>header.top){padding:8px 16px;margin-bottom:10px}
#app:not(#_) :is(.circuit-intro h1,#main>header.top h1){font-size:18px;margin:0}
#app:not(#_) :is(.circuit-intro p,#main>header.top .sub){display:none}
#app:not(#_) :is(.stat,.report-tile,.tile,.rollup-card){padding:10px 12px}
#app:not(#_) :is(.stat .stat-val,.report-tile strong,.tile .v,.rollup-card .n){font-size:20px}
#app:not(#_) :is(.summary-strip,.stats,.rollup:has(>.rollup-card),.report-headline){grid-template-columns:repeat(2,minmax(0,1fr))}
#app:not(#_) :is(thead th,tbody td){padding:6px 8px}
#app:not(.wrap):not(#_)>.back-bar~#main{padding:16px 16px 64px}
#app.wrap:not(#_)>.back-bar~#main{padding:16px 0 64px}
}
/* end shared:ui-standard */
/* shared:environment-banner-and-plan-badge -- identical in all four products (test/design-md.test.js).
   Matthew, 2026-09-25: the Agreement Tracker's badge and the Project Tracker's banner did not match
   the others. The look is the Ticket Tracker's and the CRM's: banner, badge and header title. Each page keeps its own
   display rules (dev and qa only) and layout margins. */
html body .env-banner,html body .environment-banner{background:#fff3dd;color:#81541a;border:0;border-bottom:1px solid #ef9f27;border-radius:0;padding:6px;font-size:14px;font-weight:600;line-height:21px;letter-spacing:normal;text-transform:none;text-align:center}
html[data-circuit-theme=dark] body .env-banner,html[data-circuit-theme=dark] body .environment-banner{background:#403326;color:#f0ca8a}
html body .plan-badge{background:transparent;border:1px solid var(--purple);color:var(--purple);border-radius:4px;padding:1px 8px;font-size:10.5px;font-weight:700;line-height:16px;letter-spacing:.08em;text-transform:uppercase}
html body .header-title,html body .brand-title{font-size:.85rem;letter-spacing:.06em;font-weight:400;text-transform:uppercase}
/* end shared:environment-banner-and-plan-badge */
