/* One dark theme for long reading sessions.
   Surfaces step up in lightness: the sidebar is the deepest, the workspace a step lighter, cards a
   step above that, and controls (fields, selects, secondary buttons) the most raised, with a border
   that clears 3:1 against the surface around them so a field never has to be hunted for.
   Purple marks what you can act on and where you are. The filled purple is for buttons (white text
   on it clears 4.5:1); a lighter purple is for links, focus rings and the current tab. Semantic
   colors (success, danger, warning, info) always ride beside words, never alone. Gold is for dates
   and events only. Numbers and dates are set in the reading face; a monospace face made the app
   read like a terminal.
   Contrast figures beside the text colors are measured against --panel (WCAG 2.2 ratios).
   color-scheme tells the browser the page is dark, so its own scrollbars, checkboxes, radios,
   date pickers and list popups come out dark too. */
:root{
  color-scheme:dark;

  /* Surfaces, deepest first. */
  --nav:#0e1119;            /* the sidebar: deep charcoal navy */
  --topbar:#11151d;         /* the context bar, between the sidebar and the workspace */
  --bg:#141821;             /* the workspace */
  --panel:#1a1f2a;          /* cards, popups, menus */
  --panel-2:#1f2532;        /* table headers and a card's quieter band */
  --raised:#252c3a;         /* fields, selects, secondary buttons */
  --raised-hover:#2c3444;
  --hover:rgba(255,255,255,.05);

  /* Lines. */
  --border:rgba(255,255,255,.08);          /* between surfaces */
  --border-strong:rgba(255,255,255,.14);   /* menus and popups */
  --control-border:#6b7489;                /* fields and secondary buttons: 3.3:1 on --panel, 3.6:1 on --bg */
  --control-border-hover:#8a93a8;

  /* Text. */
  --text:#eef0f5;           /* 14.5:1, reading text */
  --text-2:#c3c8d3;         /* 9.8:1, secondary text and table headers */
  --muted:#a2a9b7;          /* 7.0:1, labels, meta, placeholders (5.9:1 on a field) */
  --muted2:#8b92a1;         /* 5.3:1, the faintest text; never on a raised field */
  --nav-text:#cdd2dc;       /* 12.4:1 on --nav */
  --nav-heading:#8f97a6;    /* 6.4:1 on --nav */

  /* Purple. */
  --accent:#6c5ce7;         /* filled buttons and picks; white text on it 4.9:1 */
  --accent-hover:#5e4fd6;   /* deeper on hover, so white text gains contrast (5.9:1) */
  --accent-text:#b3a8ff;    /* links, focus, the current tab's line: 7.8:1 on --panel */
  --accent-line:#a497ff;    /* the slim bar beside the current menu item: 6.3:1 on its tint */
  --accent-soft:rgba(108,92,231,.2);  /* selection: the current menu item, a picked row */
  --focus:#b3a8ff;

  /* Semantic, always with words. Each text color clears 6.5:1 on its own tint. */
  --success:#7ee2a8; --success-bg:rgba(47,191,113,.16); --success-line:rgba(47,191,113,.45);
  --danger:#ff9aa5;  --danger-bg:rgba(229,72,77,.16);   --danger-line:rgba(229,72,77,.5);
  --warning:#f3c46b; --warning-bg:rgba(232,162,58,.16);  --warning-line:rgba(232,162,58,.45);
  --info:#93c5fd;    --info-bg:rgba(59,130,246,.16);    --info-line:rgba(59,130,246,.45);
  --neutral-bg:rgba(255,255,255,.06); --neutral-line:rgba(255,255,255,.16);
  --accent2:#3dd6d0;        /* a data color (in favor, yea), not a second accent */

  --shadow:0 16px 40px rgba(0,0,0,.45);   /* popups and menus only */

  /* Type: Windows 11's own family, with optical sizes for text and for titles. */
  --font:"Segoe UI Variable Text","Segoe UI",system-ui,-apple-system,Roboto,Helvetica,Arial,sans-serif,"Segoe UI Emoji";
  --font-display:"Segoe UI Variable Display","Segoe UI",system-ui,-apple-system,Roboto,Helvetica,Arial,sans-serif;
  --mono:ui-monospace,SFMono-Regular,Menlo,Consolas,"Liberation Mono",monospace;
  --fs-label:12px;          /* section labels, table headers, tags */
  --fs-small:13px;          /* meta and help text */
  --fs-table:14px;
  --fs-body:15px;           /* reading text and navigation */
  --fs-card:17px;           /* card titles */
  --fs-h1:26px;             /* page headings */

  /* Space on a 4/8 rhythm, and restrained corners. */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:20px; --s6:24px; --s8:32px;
  --r-sm:6px; --r-md:8px; --r-lg:10px;

  --nav-w:248px;
  --topbar-h:60px;
}

*{box-sizing:border-box}
html{scrollbar-color:#394152 var(--bg); -webkit-text-size-adjust:100%; text-size-adjust:100%}
body{
  margin:0;
  min-height:100vh;
  font-family:var(--font);
  font-size:var(--fs-body);
  line-height:1.55;
  background:var(--bg);
  color:var(--text);
}

a{color:inherit}
:focus-visible{outline:2px solid var(--focus); outline-offset:2px}
input[type=checkbox], input[type=radio]{accent-color:var(--accent)}

/* Read by screen readers, not shown. */
.sr-only{position:absolute !important; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0}

/* Line icons from the sprite in _Icons.cshtml; they take the color of the text beside them. */
.icon{width:18px; height:18px; flex:none; fill:none; stroke:currentColor; stroke-width:1.75; stroke-linecap:round; stroke-linejoin:round}
.icon-sm{width:16px; height:16px}

/* ---- The shell: a sidebar that stays put, a context bar, and the workspace. ---- */
.app-shell{display:grid; grid-template-columns:var(--nav-w) minmax(0, 1fr); min-height:100vh}

.app-nav{
  position:sticky; top:0;
  height:100vh;
  display:flex; flex-direction:column;
  background:var(--nav);
  border-right:1px solid var(--border);
}

.brand{
  display:flex; flex-direction:column; align-items:center; gap:6px;
  margin:8px 12px 0; padding:16px 12px 14px;
  border-radius:var(--r-md);
  text-decoration:none;
}
.brand:hover{background:var(--hover)}
.brand-logo{display:block; width:100%; max-width:180px; height:auto}
.brand-sub{font-size:var(--fs-label); color:var(--nav-heading); letter-spacing:.02em}
.nav-close{display:none}

/* The menu scrolls on its own when the window is short, so every destination stays reachable. */
.nav{
  flex:1 1 auto; min-height:0;
  display:flex; flex-direction:column;
  overflow-y:auto; overscroll-behavior:contain;
  padding:12px 12px 0;
  scrollbar-width:thin; scrollbar-color:#2c3341 transparent;
}
.nav-group{margin-top:var(--s6)}
/* Group headings say what follows; they are not links, so they are small, quiet and set in
   capitals (by the stylesheet only; the markup stays in sentence case). */
.nav-section{
  margin:0 0 6px; padding:0 12px;
  font-size:12px; line-height:16px; font-weight:600;
  letter-spacing:.07em; text-transform:uppercase;
  color:var(--nav-heading);
}
.nav-list{list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:2px}
.nav-item{
  position:relative;
  display:flex; align-items:center; gap:12px;
  min-height:40px; padding:8px 12px;
  border-radius:var(--r-md);
  color:var(--nav-text);
  text-decoration:none;
  font-size:var(--fs-body); font-weight:500; line-height:1.3;
  transition:background-color .12s ease, color .12s ease;
}
.nav-item .icon{color:#9aa2b1}
.nav-label{flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.nav-item:hover{background:rgba(255,255,255,.06); color:var(--text)}
.nav-item:hover .icon{color:var(--text)}
/* Inside the item, so the menu's scroll box never clips it. */
.nav-item:focus-visible{outline:2px solid var(--focus); outline-offset:-2px}
.nav-item.active{background:var(--accent-soft); color:var(--text); font-weight:600}
.nav-item.active .icon{color:var(--accent-text)}
.nav-item.active::before{
  content:''; position:absolute; left:0; top:9px; bottom:9px;
  width:3px; border-radius:0 3px 3px 0;
  background:var(--accent-line);
}
.nav-footer{
  margin-top:auto;
  padding:16px 12px 16px;
  border-top:1px solid var(--border);
  margin-left:-12px; margin-right:-12px;
  padding-left:24px; padding-right:24px;
}
.nav-firm-label{font-size:var(--fs-label); color:var(--nav-heading)}
.nav-firm{font-size:14px; font-weight:600; color:var(--nav-text); overflow-wrap:anywhere}
.nav-group:last-of-type{margin-bottom:var(--s6)}

@media (prefers-reduced-motion: reduce){
  .nav-item{transition:none}
}

.muted{color:var(--muted); font-size:var(--fs-small)}
/* Tabular figures in the reading face, so numbers still line up in columns. A long path or key
   breaks where it must rather than pushing the page sideways on a phone. */
.mono{font-family:var(--font); font-variant-numeric:tabular-nums; font-size:var(--fs-small); color:var(--text); overflow-wrap:anywhere}
.small{font-size:var(--fs-small); color:var(--muted)}

.app-main{display:flex; flex-direction:column; min-width:0}

/* The context bar: what the work is filed under (session and client) on the left, the person's own
   menu on the right. It stays in view while the page scrolls. */
.topbar{
  position:sticky; top:0; z-index:60;
  display:flex; align-items:center; gap:var(--s4);
  height:var(--topbar-h);
  padding:0 var(--s6);
  background:var(--topbar);
  border-bottom:1px solid var(--border);
}
.topbar-context{display:flex; align-items:center; gap:var(--s6); flex:1 1 auto; min-width:0}
.topbar-utilities{display:flex; align-items:center; gap:var(--s2); margin-left:auto; flex:none}

.ctx{display:flex; align-items:center; gap:var(--s2); min-width:0; margin:0}
.ctx-label{font-size:var(--fs-label); font-weight:600; color:var(--muted); white-space:nowrap}
.ctx select.ctx-select{
  width:auto; min-width:0; height:36px; min-height:36px; padding:0 10px;
  font-size:14px; font-weight:500;
}
.ctx-session .ctx-select{width:clamp(200px, 22vw, 320px)}
.ctx-client .ctx-select{width:clamp(170px, 16vw, 250px)}
/* No working client yet. So much is filed under one (positions, notes, contacts, reports) that the
   empty picker asks to be filled: the action purple on a dashed edge, like the empty "Add a client"
   slot, with its words in the link purple (6.6:1 on a field) and its label to match. The first page
   of a visit without one also glows briefly (site.js adds is-nudging), unless motion is reduced. */
.ctx-select.is-unset{
  color:var(--accent-text); font-weight:600;
  border:1px dashed var(--accent-text); background:rgba(108,92,231,.14);
}
.ctx-select.is-unset:hover{background:rgba(108,92,231,.22); border-color:var(--accent-line)}
.ctx-select.is-unset option{color:var(--text); font-weight:400}
.ctx-client.is-unset .ctx-label{color:var(--accent-text)}
@keyframes ctx-nudge{
  0%, 100%{box-shadow:0 0 0 0 rgba(179,168,255,0)}
  50%{box-shadow:0 0 0 5px rgba(179,168,255,.35)}
}
.ctx-select.is-unset.is-nudging{animation:ctx-nudge 1.6s ease-in-out 3}
@media (prefers-reduced-motion: reduce){
  .ctx-select.is-unset.is-nudging{animation:none}
}
/* The working client decides where notes and contacts are filed, so once chosen it is set off in
   the selection purple. */
.ctx-select.has-client{border-color:var(--accent-text); background:#2a2752}
.ctx-link{
  display:inline-flex; align-items:center; gap:8px; height:36px; padding:0 12px;
  border:1px dashed var(--control-border); border-radius:var(--r-md);
  color:var(--text); text-decoration:none; font-size:14px; font-weight:500;
}
.ctx-link:hover{background:var(--hover); border-color:var(--control-border-hover)}
.ctx-apply{height:36px}
/* Apply turns into the primary action once a different session is picked. */
.ctx-session.is-pending .ctx-apply{background:var(--accent); border-color:var(--accent); color:#fff}
.ctx-session.is-pending .ctx-apply:hover{background:var(--accent-hover); border-color:var(--accent-hover)}

/* The person's menu: account, settings, reload and sign out. */
.account-menu{position:relative}
.account-trigger{
  display:inline-flex; align-items:center; gap:8px;
  height:40px; padding:0 10px 0 5px;
  font:inherit; font-size:14px; font-weight:500; color:var(--text);
  background:transparent; border:1px solid transparent; border-radius:var(--r-md);
  cursor:pointer;
}
.account-trigger:hover{background:var(--hover); border-color:var(--border)}
.account-trigger[aria-expanded="true"]{background:var(--raised); border-color:var(--control-border)}
.account-trigger .icon{color:var(--muted)}
.avatar{
  display:inline-grid; place-items:center;
  width:30px; height:30px; border-radius:50%;
  background:var(--accent-soft); border:1px solid rgba(164,151,255,.5);
  color:var(--text); font-size:12px; font-weight:700; letter-spacing:.02em;
}
.account-trigger-name{max-width:160px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.menu{
  position:absolute; right:0; top:calc(100% + 6px); z-index:80;
  min-width:248px; padding:6px;
  background:var(--panel);
  border:1px solid var(--border-strong); border-radius:var(--r-lg);
  box-shadow:var(--shadow);
}
.menu[hidden]{display:none}
.menu-header{padding:8px 10px 10px; margin-bottom:6px; border-bottom:1px solid var(--border)}
.menu-title{font-size:14px; font-weight:600; color:var(--text); overflow-wrap:anywhere}
.menu-sub{font-size:var(--fs-label); color:var(--muted); overflow-wrap:anywhere}
.menu-item{
  display:flex; align-items:center; gap:10px;
  width:100%; min-height:38px; padding:8px 10px;
  font:inherit; font-size:14px; color:var(--text-2); text-align:left; text-decoration:none;
  background:none; border:0; border-radius:var(--r-sm);
  cursor:pointer;
}
.menu-item .icon{color:var(--muted)}
.menu-item:hover, .menu-item:focus-visible{background:rgba(255,255,255,.07); color:var(--text)}
.menu-item:hover .icon, .menu-item:focus-visible .icon{color:var(--text)}
.menu-item:focus-visible{outline:2px solid var(--focus); outline-offset:-2px}
.menu-item[aria-current]{color:var(--text); font-weight:600}
.menu-item[aria-current] .icon{color:var(--accent-text)}
.menu-sep{height:1px; margin:6px 0; background:var(--border)}
.menu-form{margin:0}

.topbar-link{
  font:inherit; font-size:14px;
  color:var(--muted);
  background:transparent;
  border:1px solid transparent;
  padding:7px 10px;
  border-radius:var(--r-md);
  white-space:nowrap;
  cursor:pointer;
  text-decoration:none;
}
.topbar-link:hover, .topbar-link.active{color:var(--text); background:var(--hover)}

.workspace{padding:var(--s6); min-width:0}
.workspace:focus{outline:none}

/* The page's own heading, at the top of the workspace, with an optional line under it saying what
   the page is for (so the first card doesn't have to repeat the page's name to say it). */
.page-head{display:flex; flex-direction:column; gap:6px; margin:0 0 var(--s5)}
.page-lede{margin:0; max-width:96ch; font-size:var(--fs-body); line-height:1.55; color:var(--text-2)}
.page-title{
  margin:0;
  font-family:var(--font-display); font-size:var(--fs-h1); font-weight:600;
  line-height:1.2; letter-spacing:-.015em;
  color:var(--text);
}

.card{
  border:1px solid var(--border);
  background:var(--panel);
  border-radius:var(--r-lg);
}

.card-header{padding:16px 20px; border-bottom:1px solid var(--border)}
.card-title{font-family:var(--font-display); font-size:var(--fs-card); font-weight:600; line-height:1.3}
.card-sub{font-size:var(--fs-small); color:var(--muted); margin-top:4px; line-height:1.5}
.card-body{padding:20px}

.grid-2{
  display:grid;
  grid-template-columns: 1.3fr .9fr;
  gap:16px;
  align-items:start;
}

@media (max-width: 1100px){
  .grid-2{grid-template-columns:1fr}
}

/* Fields: raised off the card, with an edge that is easy to find. */
.input, select{
  width:100%;
  font:inherit; font-size:14px; line-height:20px;
  color:var(--text);
  background:var(--raised);
  border:1px solid var(--control-border);
  padding:8px 12px;
  min-height:38px;
  border-radius:var(--r-md);
}
.input::placeholder, textarea::placeholder{color:var(--muted); opacity:1}
.input:hover, select:hover{border-color:var(--control-border-hover)}
.input:focus, select:focus{border-color:var(--focus); outline:2px solid var(--focus); outline-offset:1px}
textarea.input{line-height:1.5}

select option, select optgroup{
  background:var(--raised);
  color:var(--text);
}

/* A list box keeps showing its picks after it loses focus: without this, the rule above paints
   a picked option like the rest once the browser drops its focused highlight. The gradient
   covers that highlight too, so a pick looks the same focused or not. */
select[multiple] option:checked{
  background:var(--accent) linear-gradient(var(--accent), var(--accent));
  color:#fff;
}

.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  font:inherit; font-size:14px; font-weight:600; line-height:20px;
  color:#fff;
  background:var(--accent);
  border:1px solid var(--accent);
  padding:8px 16px;
  border-radius:var(--r-md);
  cursor:pointer;
  transition:background-color .12s ease, border-color .12s ease;
}
.btn:hover{background:var(--accent-hover); border-color:var(--accent-hover); color:#fff}
.btn:disabled{opacity:.5; cursor:not-allowed}
.btn:disabled:hover{background:var(--accent); border-color:var(--accent)}

.table{
  width:100%;
  border-collapse:separate;
  border-spacing:0;
}

.table th, .table td{padding:12px 14px; border-bottom:1px solid var(--border); font-size:var(--fs-table); line-height:1.45}
.table th{
  color:var(--text-2); background:var(--panel-2);
  font-weight:600; font-size:var(--fs-label); letter-spacing:.02em;
  text-align:left; white-space:nowrap;
}
.table thead th{border-bottom-color:var(--border-strong)}
.table tbody tr:last-child td{border-bottom:0}
.table tbody tr:hover td{background:var(--hover)}
.table tr.selected td{background:var(--accent-soft)}

/* The bill list: the bill as people say it ("HB 1466"), and its legal title cut to two lines so
   the list scans; the full title shows on hover and in the bill's popup. */
#billsTable tbody tr{cursor:pointer}
#billsTable td{vertical-align:top}
.bill-name{font-weight:600; white-space:nowrap; font-variant-numeric:tabular-nums}
.bill-title{display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden}

.badge{
  display:inline-flex;
  align-items:center;
  gap:6px;
  padding:2px 8px;
  border-radius:var(--r-sm);
  border:1px solid var(--neutral-line);
  background:var(--neutral-bg);
  font-size:var(--fs-label);
  line-height:18px;
  color:var(--text-2);
}

/* A status or role in words, tinted by what it means. The words carry the meaning; the tint only
   helps the eye group them. Long statuses wrap rather than spill. */
.tag{
  display:inline-block; max-width:100%;
  padding:1px 8px;
  border-radius:var(--r-sm);
  border:1px solid var(--neutral-line);
  background:var(--neutral-bg);
  color:var(--text-2);
  font-size:var(--fs-label); font-weight:600; line-height:18px;
  white-space:normal; overflow-wrap:anywhere;
}
.tag-success{color:var(--success); background:var(--success-bg); border-color:var(--success-line)}
.tag-danger{color:var(--danger); background:var(--danger-bg); border-color:var(--danger-line)}
.tag-warning{color:var(--warning); background:var(--warning-bg); border-color:var(--warning-line)}
.tag-info{color:var(--info); background:var(--info-bg); border-color:var(--info-line)}
.tag-accent{color:var(--accent-text); background:var(--accent-soft); border-color:rgba(164,151,255,.45)}

/* A section's label: small, semibold, and quieter than the card title above it. */
.section-title{font-size:var(--fs-label); font-weight:600; letter-spacing:.02em; color:var(--text-2); margin:0 0 8px 0}
.kv{display:grid; grid-template-columns: 140px minmax(0, 1fr); gap:10px 16px; font-size:14px}
.kv > *{min-width:0; overflow-wrap:anywhere}
.k{color:var(--muted)}
.v{color:var(--text)}

/* A boxed item: testimony entries, roll-call cells. */
.tl-item{padding:12px 14px; border:1px solid var(--border); border-radius:var(--r-lg); background:rgba(255,255,255,.02)}
.tl-date{font-size:var(--fs-label); color:var(--muted); font-variant-numeric:tabular-nums}
.tl-date > span + span{margin-left:12px; color:var(--muted2)}
.tl-desc{margin-top:2px; font-size:14px}

/* The action timeline is a sequence, so it reads as one: a rail with a dot for each action, the
   newest filled. */
.timeline{display:flex; flex-direction:column; position:relative; padding-left:24px}
.timeline::before{content:''; position:absolute; left:6px; top:12px; bottom:12px; width:2px; border-radius:1px; background:rgba(255,255,255,.08)}
.timeline > .tl-item{position:relative; padding:6px 0 14px; border:0; border-radius:0; background:none}
.timeline > .tl-item::before{
  content:''; position:absolute; left:-22px; top:11px; width:10px; height:10px; border-radius:50%;
  background:var(--panel); border:2px solid var(--muted2);
}
.timeline > .tl-item:first-child::before{background:var(--accent-text); border-color:var(--accent-text)}

.split-votes{display:grid; grid-template-columns:1fr 1fr; gap:12px}
@media (max-width: 1100px){.split-votes{grid-template-columns:1fr}}

.vote-header{display:flex; justify-content:space-between; align-items:center; margin-bottom:8px}
.vote-title{font-weight:600}
.vote-meta{font-size:var(--fs-label); color:var(--muted); font-variant-numeric:tabular-nums}

/* Elections page helpers */
.grid2{display:grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap:10px}
.grid4{display:grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap:10px}
@media (max-width: 900px){
  .grid4{grid-template-columns: repeat(2, minmax(0,1fr))}
}
.lbl{display:block; font-size:var(--fs-label); color:var(--muted); margin-bottom:6px}
.in{width:100%; padding:10px 12px; border-radius:var(--r-md); border:1px solid var(--control-border); background:var(--raised); color:var(--text)}
.tbl{width:100%; border-collapse:collapse}
.tbl th, .tbl td{padding:10px 10px; border-top:1px solid var(--border); font-size:var(--fs-table)}
.tbl th{color:var(--text-2); font-weight:600; font-size:var(--fs-label); text-align:left}
.tbl tr.winner td{background:#0e2110}
.tbl tr.winner td:first-child{border-left:3px solid #4ade80; font-weight:700}
.tbl tr.failed td{background:#271010}
.tbl tr.failed td:first-child{border-left:3px solid #ef4444}
.tbl tr:not(.winner):not(.failed) td:first-child{border-left:3px solid transparent}

/* Bill status pills */
.status-pill{display:inline-block; padding:1px 8px; border-radius:var(--r-sm); font-size:var(--fs-label); font-weight:600; line-height:18px}
.status-pill-passed{background:var(--success-bg); color:var(--success); border:1px solid var(--success-line)}
.status-pill-failed{background:var(--danger-bg); color:var(--danger); border:1px solid var(--danger-line)}
.status-pill-pending{background:var(--neutral-bg); color:var(--text-2); border:1px solid var(--neutral-line)}
.status-pill[hidden]{display:none}
.status-text-passed{color:var(--success); font-size:var(--fs-small)}
.status-text-failed{color:var(--danger); font-size:var(--fs-small)}

/* Party color badges */
.party-badge{display:inline-block; padding:1px 8px; border-radius:var(--r-sm); font-size:var(--fs-label); font-weight:600; line-height:18px}
.party-rep{background:rgba(220,60,60,.18); color:#ffa0a0; border:1px solid rgba(220,60,60,.45)}
.party-dem{background:rgba(55,120,255,.18); color:#a3c1ff; border:1px solid rgba(55,120,255,.45)}
.party-lib{background:rgba(255,190,0,.16); color:#ffd060; border:1px solid rgba(255,190,0,.4)}
.party-ind{background:rgba(160,170,185,.14); color:#c3cbd8; border:1px solid rgba(160,170,185,.35)}
.party-other{background:var(--neutral-bg); color:var(--text-2); border:1px solid var(--neutral-line)}

.winner-star{color:#f5c518; margin-right:5px; font-size:var(--fs-label)}

/* Bill tracking (workspace) */
.tracked-star{color:#f5c518; text-align:center}

/* AI analysis panel (V7 BillSummary) */
/* Model-written, so it sits in its own tinted panel rather than reading as the bill's own text.
   Its lines stop at about 100 characters, which a 1,100px popup would otherwise run well past;
   the headline and the paragraph share one edge. */
.ai-summary{
  margin:16px 0;
  padding:14px 18px;
  border:1px solid rgba(138,126,240,.2);
  border-radius:var(--r-lg);
  background:rgba(138,126,240,.06);
}
.ai-summary-head{display:flex; align-items:baseline; gap:10px; margin-bottom:8px; flex-wrap:wrap}
.ai-summary-title{font-size:var(--fs-small); font-weight:600; color:var(--accent-text)}
.ai-summary-meta{font-size:var(--fs-label); color:var(--muted); margin-left:auto}
.ai-summary-short{font-size:15px; font-weight:600; line-height:1.5; margin-bottom:8px; max-width:50rem}
.ai-summary-long{font-size:14px; line-height:1.65; color:var(--text-2); max-width:50rem}
.ai-summary-confidence{margin-top:10px; font-size:var(--fs-label); color:var(--muted)}

/* Analysis describes superseded text — loud enough not to be trusted blindly. */
.ai-summary-stale{
  font-size:var(--fs-label); font-weight:600;
  padding:1px 8px; border-radius:var(--r-sm);
  background:var(--warning-bg); color:var(--warning); border:1px solid var(--warning-line);
}
.ai-summary-stale-note{
  font-size:var(--fs-label); line-height:1.5; color:var(--warning);
  background:rgba(245,158,11,.07); border:1px solid rgba(245,158,11,.25);
  border-radius:var(--r-md); padding:7px 10px; margin-bottom:10px;
}

/* Awaiting generation — keeps the section's place visible without shouting. */
.ai-summary-empty{
  border-color:rgba(255,255,255,.08);
  border-left-color:rgba(255,255,255,.18);
  background:rgba(255,255,255,.02);
}
.ai-summary-empty .ai-summary-title{color:var(--muted)}
.ai-summary-placeholder{font-size:var(--fs-label); color:var(--muted); font-style:italic}

/* How a bill did in testimony, at a glance. The three colors were checked against the panel for
   color-blind readers; the gray is dark on purpose, because at the teal's brightness the two
   read as one color. Every number is printed above the bar, so color never carries it alone. */
.testimony-result{
  margin-bottom:14px;
  padding:14px 16px 12px;
  border:1px solid var(--border);
  border-radius:var(--r-lg);
  background:rgba(0,0,0,.15);
}
.testimony-stats{display:grid; grid-template-columns:repeat(3, 1fr); gap:12px; margin-bottom:10px}
.testimony-stat-label{display:flex; align-items:center; gap:6px; font-size:var(--fs-label); color:var(--muted)}
.testimony-stat-figure{display:flex; flex-wrap:wrap; align-items:baseline; gap:0 8px}
.testimony-stat:nth-child(2) > *{justify-content:center}
.testimony-stat:nth-child(3) > *{justify-content:flex-end}
.testimony-stat-value{font-size:30px; font-weight:600; line-height:1.2}
.testimony-stat-share{font-size:var(--fs-small); color:var(--muted)}
/* A side nobody took stays readable but steps back, so the eye lands on the sides people did. */
.testimony-stat.is-zero .testimony-stat-value{color:var(--muted2)}
.testimony-swatch{width:10px; height:10px; border-radius:3px; flex-shrink:0}
.testimony-bar{display:flex; gap:2px; height:14px; border-radius:4px; overflow:hidden}
.testimony-bar > div{flex-basis:0; min-width:4px}
.testimony-favor{background:#0da8a3}
.testimony-neutral{background:#545d6d}
.testimony-opposed{background:#ec485c}
.testimony-total{margin-top:8px; font-size:var(--fs-label); color:var(--muted)}

/* Position pills — NDSC color contract:
   support=green / oppose=red / neutral=gray / monitor=blue.
   (Priority has no pill: /Tracked renders it as an inline editable select.) */
.pos-pill{display:inline-block; padding:1px 8px; border-radius:var(--r-sm); font-size:var(--fs-label); font-weight:600; line-height:18px}
.pos-support{background:var(--success-bg); color:var(--success); border:1px solid var(--success-line)}
.pos-oppose{background:var(--danger-bg); color:var(--danger); border:1px solid var(--danger-line)}
.pos-neutral{background:var(--neutral-bg); color:var(--text-2); border:1px solid var(--neutral-line)}
.pos-monitor{background:var(--info-bg); color:var(--info); border:1px solid var(--info-line)}

/* Client workspace (Clients, Contact Log, the legislator profile's client card). */
.client-bar{display:flex; align-items:center; gap:8px; margin:0}
.flash{
  margin-bottom:12px; padding:10px 14px; border-radius:var(--r-md); font-size:14px;
  border:1px solid rgba(245,197,24,.35); background:rgba(245,197,24,.07);
}
.flash-danger{border-color:var(--danger-line); background:var(--danger-bg)}
.btn-small{padding:5px 12px; font-size:13px; line-height:18px; border-radius:var(--r-sm)}
.btn-quiet, .btn-secondary{background:var(--raised); border-color:var(--control-border); color:var(--text); font-weight:500}
.btn-quiet:hover, .btn-secondary:hover{background:var(--raised-hover); border-color:var(--control-border-hover); color:var(--text)}
.btn-danger{background:var(--danger-bg); border-color:var(--danger-line); color:#ffc2c8}
.btn-danger:hover{background:rgba(229,72,77,.26); border-color:var(--danger-line); color:#ffd4d8}
.inline-form{display:inline; margin:0}
.row-actions{display:flex; flex-wrap:wrap; gap:8px; align-items:center}
.form-grid{display:grid; grid-template-columns:repeat(auto-fit, minmax(220px, 1fr)); gap:12px}
.form-field{display:flex; flex-direction:column; gap:4px}
.form-field label{font-size:var(--fs-label); font-weight:600; color:var(--muted)}
.form-field textarea{min-height:84px; resize:vertical}
.form-actions{display:flex; gap:8px; align-items:center; margin-top:12px; flex-wrap:wrap}

/* A compact line in place of an empty card: what is missing, and the one thing to do about it. */
.notice{
  display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  padding:10px 12px 10px 16px;
  border:1px solid var(--border); border-radius:var(--r-lg);
  background:var(--panel);
  font-size:14px; color:var(--text-2);
}
.notice > .icon{color:var(--muted)}
.notice-text{flex:1 1 240px; min-width:0}
.notice-action{flex:none}

/* Modal dialogs (the contact report): the browser's default is a white box on a dark page. */
dialog.dialog{
  width:min(560px, calc(100vw - 32px));
  max-height:calc(100vh - 48px);
  overflow:auto;
  color:var(--text);
  background:var(--panel);
  border:1px solid var(--border-strong);
  border-radius:12px;
  padding:18px 20px;
  box-shadow:var(--shadow);
  overscroll-behavior:contain;
  scrollbar-color:#3a3e4c transparent;
}
dialog.dialog::backdrop{background:rgba(6,8,12,.66)}
/* The page behind an open popup stays put. Rolling the wheel at the popup's top or bottom used to
   scroll the bill list underneath. The gutter keeps the page from shifting sideways when its
   scrollbar goes away. */
html:has(dialog.dialog[open]){overflow:hidden; scrollbar-gutter:stable}
/* The contact form: two columns of fields, so wider than the report. */
dialog.dialog-wide{width:min(880px, calc(100vw - 32px))}
/* One bill: everything about it, so as wide as the screen allows. The head stays in view while
   a long bill scrolls, so Close is always there; it carries the dialog's top padding itself. */
dialog.dialog-bill{width:min(1100px, calc(100vw - 32px)); padding-top:0}
/* The top of a bill: what it does in plain words, its legal title under that, then a band of the
   facts people look for first, side by side so they use the popup's width. */
.bill-overview{margin:0 0 18px}
.bill-lead{
  font-family:var(--font-display); font-size:17px; font-weight:500; line-height:1.45; max-width:50rem;
  display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden;
}
.bill-legal-title{
  margin-top:6px; font-size:var(--fs-small); line-height:1.55; color:var(--muted); max-width:50rem;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
.bill-lead.is-open, .bill-legal-title.is-open{display:block; overflow:visible}
.link-btn{font:inherit; font-size:var(--fs-small); color:var(--accent-text); background:none; border:0; padding:0; margin-top:4px; cursor:pointer}
.link-btn:hover{text-decoration:underline}
.bill-facts{
  display:flex; flex-wrap:wrap; margin-top:16px;
  border:1px solid var(--border); border-radius:var(--r-lg); background:rgba(255,255,255,.025);
}
.bill-fact{flex:1 1 200px; padding:12px 16px; min-width:0}
.bill-fact-wide{flex:2 1 320px}
.bill-fact + .bill-fact{border-left:1px solid var(--border)}
.bill-fact-label{font-size:var(--fs-label); font-weight:600; color:var(--muted); margin-bottom:4px}
.bill-fact-value{font-size:14.5px}
.bill-fact-note{font-size:var(--fs-label); color:var(--muted); margin-top:2px; font-variant-numeric:tabular-nums}
.dialog-title-row{display:flex; align-items:center; gap:12px; flex-wrap:wrap}
.dialog-head .card-title{font-size:20px; letter-spacing:-.01em}
.sponsor-others{margin-top:4px; line-height:1.7}

/* Tabs: a line under the row, and the current tab unmistakable: bright text, heavier weight and a
   thick purple bar under it, with its count tinted to match. */
.tab-nav{display:flex; gap:4px; flex-wrap:wrap; border-bottom:1px solid var(--border); margin-bottom:16px}
.tab-btn{
  position:relative;
  display:inline-flex; align-items:center; gap:8px;
  font:inherit; font-size:14px; font-weight:500; color:var(--muted);
  background:none; border:0; border-radius:var(--r-sm) var(--r-sm) 0 0;
  padding:12px 14px; margin-bottom:-1px;
  cursor:pointer; transition:color .12s ease, background-color .12s ease;
}
.tab-btn::after{
  content:''; position:absolute; left:8px; right:8px; bottom:0; height:3px;
  border-radius:3px 3px 0 0; background:transparent;
}
.tab-btn:hover{color:var(--text); background:var(--hover)}
.tab-btn.active, .tab-btn[aria-selected="true"]{color:var(--text); font-weight:600}
.tab-btn.active::after, .tab-btn[aria-selected="true"]::after{background:var(--accent-text)}
.tab-btn:focus-visible{outline:2px solid var(--focus); outline-offset:-2px}
.tab-count{
  min-width:22px; padding:0 7px; border-radius:999px;
  background:var(--neutral-bg); color:var(--text-2);
  font-size:var(--fs-label); font-weight:600; line-height:18px; text-align:center;
  font-variant-numeric:tabular-nums;
}
.tab-btn.active .tab-count, .tab-btn[aria-selected="true"] .tab-count{background:var(--accent-soft); color:var(--text)}

/* A row of filters over a list: a search field taking the room, the toggles beside it, wrapping
   on a narrow screen. */
.toolbar{display:flex; flex-wrap:wrap; align-items:flex-end; gap:12px 16px; margin-bottom:12px}
.toolbar-search{flex:1 1 280px; max-width:560px; min-width:0}
.toolbar-filter{display:flex; flex-direction:column; min-width:0}
.field-label{display:block; font-size:var(--fs-label); font-weight:600; color:var(--muted); margin-bottom:6px}
.input-with-icon{position:relative}
.input-with-icon > .icon{position:absolute; left:12px; top:50%; transform:translateY(-50%); color:var(--muted); pointer-events:none}
.input-with-icon > .input{padding-left:38px}
.result-count{font-size:var(--fs-small); color:var(--muted); margin:0 0 10px; font-variant-numeric:tabular-nums}

/* Toggle buttons that act as one control (All / Prime / Co-sponsor). The picked one is filled. */
.segmented{
  display:inline-flex; flex-wrap:wrap; gap:2px; padding:3px;
  background:var(--bg); border:1px solid var(--control-border); border-radius:var(--r-md);
}
.segmented-btn{
  display:inline-flex; align-items:center; gap:6px;
  min-height:30px; padding:4px 12px;
  font:inherit; font-size:13px; font-weight:500; color:var(--text-2); white-space:nowrap;
  background:transparent; border:0; border-radius:var(--r-sm);
  cursor:pointer;
}
.segmented-btn:hover{color:var(--text); background:var(--hover)}
.segmented-btn[aria-pressed="true"]{background:var(--accent); color:#fff; font-weight:600}
.segmented-btn .seg-count{font-variant-numeric:tabular-nums; color:var(--muted)}
.segmented-btn[aria-pressed="true"] .seg-count{color:#fff}
.segmented-btn:focus-visible{outline:2px solid var(--focus); outline-offset:1px}

/* Version Compare tab: one row per version with a From and a To pick. */
.version-picker th.pick, .version-picker td.pick{width:44px; text-align:center}
.version-picker td{vertical-align:top}
.version-picker input[type=radio]{width:16px; height:16px; margin:2px 0 0; accent-color:var(--accent); color-scheme:dark; cursor:pointer}
.version-picker tr:has(input:checked) td{background:var(--accent-soft)}
.version-picker .version-lc{font-size:11px; color:var(--muted); margin-top:2px}
/* Each version says what reaching it did: an amendment is tagged "Changed the wording" (the info
   blue, with its words); a reprint is quieter and tagged "Reprint, no change", so the amendments
   stand out. */
.version-picker .version-reprint{color:var(--muted)}
.version-picker .version-tag{margin-left:8px; vertical-align:1px}
.version-picker td.version-pdf{text-align:right; white-space:nowrap}
.version-compare-head{
  display:flex; justify-content:space-between; align-items:center; gap:12px; flex-wrap:wrap;
  margin:14px 0 10px; padding:10px 14px;
  border:1px solid var(--border); border-radius:var(--r-lg); background:rgba(0,0,0,.15);
}
.version-compare-pair{font-size:14px; font-weight:600}

/* Two versions side by side (BillCompare), each PDF in its own frame. */
.compare-title{max-width:120ch}
.compare-picker{display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-bottom:14px}
.compare-picker select{max-width:420px}
/* Each pane spans two shared rows, so a label that wraps on one side doesn't push its PDF lower
   than the other one. */
.compare-panes{display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); grid-template-rows:auto 1fr; gap:6px 14px}
.compare-pane{display:grid; grid-row:span 2; grid-template-rows:subgrid}
.compare-pane-head{display:flex; align-items:baseline; gap:10px; flex-wrap:wrap; font-size:var(--fs-small)}
.compare-frame{
  display:block; width:100%; height:calc(100vh - 260px); min-height:480px;
  border:1px solid var(--border); border-radius:var(--r-lg); background:#fff;
}
@media (max-width: 1000px){
  .compare-panes{grid-template-columns:1fr; grid-template-rows:none}
  .compare-pane{grid-row:auto; grid-template-rows:auto 1fr}
}
.dialog-head{
  position:sticky;
  top:0;
  z-index:1;
  display:flex;
  justify-content:space-between;
  align-items:flex-start;
  gap:16px;
  margin:0 -20px 14px;
  padding:18px 20px 12px;
  background:var(--panel);
  border-bottom:1px solid var(--border);
}

/* A term with a definition: a dotted underline says there's one, and it shows on hover or when
   the term has keyboard focus. The definition is real text inside the term, so a screen reader
   reads it too. */
.term{position:relative; border-bottom:1px dotted rgba(235,232,241,.55); cursor:help}
.term:focus-visible{outline:none; border-bottom-color:var(--accent-text)}
.term-tip{
  position:absolute; left:0; bottom:calc(100% + 8px); z-index:30;
  width:max-content; max-width:min(340px, 80vw);
  padding:9px 12px; border-radius:var(--r-md);
  background:#2b3140; color:var(--text); border:1px solid var(--border-strong);
  box-shadow:0 12px 32px rgba(0,0,0,.45);
  font-size:var(--fs-small); font-weight:400; line-height:1.5; text-align:left; white-space:normal;
  visibility:hidden; opacity:0; transform:translateY(4px); pointer-events:none;
  transition:opacity .12s ease, transform .12s ease, visibility .12s;
}
.term:hover .term-tip, .term:focus-visible .term-tip{visibility:visible; opacity:1; transform:none}
@media (prefers-reduced-motion: reduce){ .term-tip{transition:none; transform:none} }

/* The contact log's filter bar: fields side by side, wrapping on a narrow screen. */
.filter-bar{display:flex; flex-wrap:wrap; gap:10px; align-items:flex-end; margin-bottom:12px}
.filter-bar .filter-search{flex:1 1 240px}
.filter-bar select.input, .filter-bar input[type="date"].input{width:auto; min-width:150px}
.filter-check{display:flex; gap:6px; align-items:center; font-size:14px; color:var(--text); padding-bottom:10px; white-space:nowrap}
.filter-actions{display:flex; gap:10px; align-items:center; padding-bottom:6px}

/* The Bills page: three pickers sharing the width, with the tracking box beside them. */
.bills-filters{display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)) auto; gap:10px; align-items:end}
@media (max-width: 1100px){ .bills-filters{grid-template-columns:1fr 1fr} }
.filter-chips{margin-top:12px; display:flex; align-items:center; gap:8px; flex-wrap:wrap}
.filter-chip{display:inline-block; padding:2px 10px; border-radius:var(--r-sm); font-size:var(--fs-label); font-weight:600; background:var(--accent-soft); color:var(--text)}
.filter-chips a{font-size:var(--fs-small); color:var(--muted); text-decoration:none}
.filter-chips a:hover{color:var(--text); text-decoration:underline}
/* A score column with nothing to show: scored but irrelevant, or not scored yet. */
.score-na{text-align:center; font-size:var(--fs-small); color:var(--muted2); cursor:help}
.pager{display:flex; flex-wrap:wrap; gap:8px; align-items:center; margin-top:12px; font-size:var(--fs-small); color:var(--muted)}
.pager-sizes{margin-left:auto; display:flex; gap:6px; align-items:center}
.label-chip{
  display:inline-block; padding:1px 8px; border-radius:var(--r-sm); font-size:var(--fs-label); font-weight:600;
  line-height:18px; color:var(--text); white-space:nowrap;
}
.label-chips{display:flex; flex-wrap:wrap; gap:4px}
.note-item{padding:12px 0; border-bottom:1px solid var(--border)}
.note-item:last-child{border-bottom:0}
.note-body{white-space:pre-wrap; overflow-wrap:anywhere; font-size:14px; line-height:1.55}
.note-meta{font-size:var(--fs-label); color:var(--muted); margin-top:4px; display:flex; gap:10px; align-items:center; flex-wrap:wrap}
.note-item details summary{cursor:pointer; color:var(--muted); font-size:var(--fs-small)}
.followup-due{color:#f59e0b; font-weight:600}
.nav-count{margin-left:auto; min-width:20px; padding:1px 7px; border-radius:999px; background:#f59e0b; color:#111; font-size:var(--fs-label); font-weight:700; text-align:center; line-height:18px}

/* Sign-in pages: one card in the middle of the screen, no shell. */
.auth-body{display:grid; place-items:center; min-height:100vh; padding:24px}
.auth-shell{width:100%; max-width:440px; display:flex; flex-direction:column; align-items:center; gap:18px}
/* The logo is about four times as wide as it is tall, so it needs the width to be read. */
.auth-brand img{width:min(320px, 100%); height:auto}
.auth-card{width:100%}
.auth-card .card-body{display:flex; flex-direction:column; gap:12px}
.auth-card .input{width:100%}
.auth-check{display:flex; align-items:center; gap:8px; font-size:14px; color:var(--text-2)}
.auth-foot{font-size:var(--fs-small); color:var(--muted)}
/* The shell's sign-out form sits in the person's menu. */
.topbar-form{display:inline; margin:0}
.logo-preview{max-width:260px; max-height:120px; background:#fff; padding:10px; border-radius:var(--r-lg)}
a.btn{text-decoration:none}
/* Admin and Firm pages: a temporary password shown once, row actions, the day's log. */
.temp-password-box{border-color:rgba(111,98,224,.45); background:var(--accent-soft)}
.temp-password{margin-top:8px; font-size:20px; font-weight:600; letter-spacing:.08em; font-variant-numeric:tabular-nums; user-select:all}
.row-actions form{margin:0; display:inline}
.log-view{margin:0; padding:12px; border-radius:var(--r-lg); background:rgba(0,0,0,.28); font-size:var(--fs-label); line-height:1.45; white-space:pre-wrap; overflow-wrap:anywhere; max-height:520px; overflow:auto; color:var(--text)}
/* The perspective editor: a weight per group, with optional subject areas. */
.input-narrow{width:110px}
.weights-table td{vertical-align:top}
.weights-table details summary{cursor:pointer}
.scope-grid{display:grid; grid-template-columns:repeat(auto-fill, minmax(220px, 1fr)); gap:4px 12px; margin:8px 0}
.scope-option{display:flex; align-items:center; gap:6px; font-size:var(--fs-small)}
.preview-grid{display:grid; grid-template-columns:1fr 1fr; gap:16px}
@media (max-width: 1100px){ .preview-grid{grid-template-columns:1fr} }
/* The Error page's exception, development only. */
.error-details{white-space:pre-wrap; overflow-wrap:anywhere; font-size:var(--fs-label); line-height:1.45; max-height:320px; overflow:auto; color:var(--muted); margin:8px 0 0}
/* Bills list: the bill name is a real link (keyboard reachable); it reads like the cell did. */
.bill-link{color:inherit; text-decoration:none}
.bill-link:hover, .bill-link:focus-visible{text-decoration:underline}
.bill-link:focus-visible{outline:2px solid var(--focus); outline-offset:2px; border-radius:4px}
/* Beside every save that files under a client: where it goes and the perspective it is scored through. */
.filing-under{display:flex; flex-wrap:wrap; gap:4px 10px; align-items:baseline; font-size:var(--fs-small); color:var(--muted); margin:0 0 8px}
.filing-under strong{color:var(--text); font-weight:600}
.filing-under a{color:var(--accent-text); text-decoration:none}
.filing-under a:hover, .filing-under a:focus-visible{text-decoration:underline}

/* Keyboard: a skip link for people tabbing from the top, visible only while it has focus. */
.skip-link{position:absolute; left:-9999px; top:8px; z-index:200; padding:8px 12px; border-radius:var(--r-md); background:var(--accent); color:#fff; text-decoration:none; font-weight:600}
.skip-link:focus{left:8px}

/* The Menu button and the dimmed page behind the open drawer (narrow windows only). */
.nav-toggle{
  display:none; align-items:center; gap:8px;
  height:38px; padding:0 12px;
  font:inherit; font-size:14px; font-weight:600; color:var(--text);
  background:var(--raised); border:1px solid var(--control-border); border-radius:var(--r-md);
  cursor:pointer; white-space:nowrap;
}
.nav-backdrop{position:fixed; inset:0; z-index:110; background:rgba(0,0,0,.55)}
.topbar-left{display:flex; align-items:center; gap:12px; min-width:0}

/* Medium windows: a narrower menu and the person's name folded into the avatar; just above the
   drawer width the context labels are read by screen readers but not shown, so the bar stays on
   one line. */
@media (max-width: 1280px){
  .account-trigger-name{display:none}
}
@media (max-width: 1180px){
  :root{--nav-w:224px}
  .topbar-context{gap:var(--s4)}
}
@media (max-width: 940px){
  .topbar .ctx-label{position:absolute; width:1px; height:1px; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap}
}

/* Phone and narrow windows: the menu becomes a drawer behind a Menu button, the context bar
   stacks, and wide tables scroll inside their own box instead of widening the whole page. */
@media (max-width: 900px){
  .app-shell{grid-template-columns:1fr; min-height:100vh}
  .app-nav{
    position:fixed; top:0; bottom:0; left:0; height:auto;
    width:min(300px, 86vw); z-index:120;
    transform:translateX(-100%); visibility:hidden;
    transition:transform .2s ease, visibility 0s linear .2s;
    box-shadow:var(--shadow);
  }
  body.nav-open .app-nav{transform:none; visibility:visible; transition:transform .2s ease, visibility 0s}
  .nav-close{
    display:inline-flex; align-items:center; justify-content:center;
    position:absolute; top:10px; right:10px; width:36px; height:36px;
    color:var(--text); background:transparent; border:1px solid var(--border-strong); border-radius:var(--r-md);
    cursor:pointer;
  }
  .nav-toggle{display:inline-flex}
  .topbar{position:static; height:auto; flex-wrap:wrap; padding:10px 16px; gap:10px}
  .topbar-utilities{order:1}
  .topbar-context{order:2; flex:1 1 100%; flex-direction:column; align-items:stretch; gap:8px}
  .topbar .ctx-label{position:static; width:64px; height:auto; margin:0; overflow:visible; clip:auto; flex:none}
  .ctx{width:100%}
  .ctx-session .ctx-select, .ctx-client .ctx-select{flex:1 1 auto; width:auto}
  .ctx-link{width:100%; justify-content:center}
  .workspace{padding:16px}
  .page-head{margin-bottom:var(--s4)}
  .page-title{font-size:24px}
  .card-header, .card-body{padding:14px 16px}
  .table{display:block; overflow-x:auto; -webkit-overflow-scrolling:touch}
  .bills-filters, .grid4, .grid2, .form-grid, .kv{grid-template-columns:1fr}
  .pager-sizes{margin-left:0}
  /* 16px stops phones zooming the page when a field takes focus. */
  .input, select, textarea{font-size:16px}
}
@media (prefers-reduced-motion: reduce){ .app-nav{transition:none} }
/* Shared editing: what someone else saved while you were editing, and an item's earlier versions. */
.conflict-box{margin:8px 0; padding:10px 12px; border-radius:var(--r-lg); border:1px solid var(--danger-line); background:var(--danger-bg); font-size:var(--fs-small); color:var(--text)}
.conflict-box .note-body{color:var(--text)}
.history-item{padding:6px 0; border-top:1px solid var(--border); font-size:var(--fs-small)}
.history-item .small{color:var(--muted); margin-bottom:2px}
