/* Pilara refine.css - presentational refinements over PIL-DES-001 (v1.4).
   Additive/override-only, loaded AFTER style.css. No new hues (semantic tokens
   alias existing S4 status tokens). No logic, fields or payloads touched.
   ASCII-only per DESIGN.md S11. Remove the one <link> to revert.

   SCOPE NOTE (ported onto main 2026-07-27): DESIGN.md v1.3 (2026-07-04) already
   shipped a universal :focus-visible ring, reduced-motion, 28px/700 KPI numbers
   and a --bg-raised sticky table-header band. Those rules were REMOVED from this
   file rather than duplicated - re-stating them here would only fight style.css.
   What remains is strictly what main does not already do. */

:root{
  /* Semantic ledger aliases - NOT new colours; alias existing S4 status tokens */
  --ledger-balanced: var(--st-done);        /* ties out / nil difference */
  --ledger-discrepancy: var(--st-overdue);  /* out of balance */
  --ledger-pending: var(--st-progress);     /* provisional / needs review */

  /* Derived interaction states (from existing tokens; no new hues) */
  --disabled-bg: color-mix(in srgb, var(--border) 55%, var(--bg-surface));
  --disabled-text: color-mix(in srgb, var(--text-secondary) 60%, white);
  --focus-ring: color-mix(in srgb, var(--brand) 35%, transparent);
}

/* ---------- A. Money alignment ----------
   style.css sets `td.num,th.num{font-variant-numeric:tabular-nums}` but leaves
   the cells LEFT-aligned, so decimal points do not line up down a column - the
   single biggest scan cost in a ledger. .amt is applied per-cell by an audited
   classifier that never touches a date or count column. */
td.amt, th.amt{ text-align:right; font-variant-numeric:tabular-nums; }
/* Opt-in blanket for a table whose every .num cell is a figure column. */
table.figures td.num, table.figures th.num{ text-align:right; }

/* Balanced / discrepancy figure treatment (aliases only) */
.is-nil{ color:var(--ledger-balanced); font-weight:600; }
.is-diff{ color:var(--ledger-discrepancy); font-weight:600; }

/* NOTE: total-row emphasis is deliberately NOT defined here. style.css already
   ships `tr.tb-total td{border-top:2px solid var(--text-secondary);font-weight:600}`
   and it is applied to 31 rows across 22 templates. Adding a competing .total
   class would fork the convention for no gain - use tb-total. */

/* Optional compact density for power users (opt-in) */
table.dense td{ height:44px; }

/* Balanced counterpart to the existing .metric.alert (which style.css already
   reddens). Only the "ties out" state is added here. */
.metric.ok .mv{ color:var(--ledger-balanced); }

/* ---------- B. Form states style.css does not define ---------- */
input[disabled], select[disabled], textarea[disabled],
button[disabled], .btn[disabled], [aria-disabled="true"]{
  background:var(--disabled-bg) !important;
  color:var(--disabled-text) !important;
  cursor:not-allowed;
  box-shadow:none;
}
input[aria-invalid="true"], select[aria-invalid="true"], textarea[aria-invalid="true"]{
  border-color:var(--st-overdue);
  outline-color:var(--st-overdue);
}
label:has(+ [required])::after,
label:has(+ * [required])::after{ content:" *"; color:var(--st-overdue); }

.formgrid.tight label{ margin-top:8px; }

/* ---------- C. Action hierarchy (DESIGN.md S11a, Principal-signed) ---------- */
/* Irreversible, client/SARS-facing commits stand clear of 36px utility buttons. */
.btn.commit, button.commit{
  height:40px; font-weight:600; padding:0 18px;
}
.btn.commit:focus-visible, button.commit:focus-visible{
  box-shadow:0 0 0 4px var(--focus-ring);
}
/* Destructive actions use status red as an ACTION - the second sanctioned S9
   exception (status colour otherwise stays pill-only). */
.btn.danger, button.danger{
  background:var(--st-overdue); color:#fff;
}
.btn.danger:hover, button.danger:hover{
  background:color-mix(in srgb, var(--st-overdue) 85%, black);
}

/* ---------- D. Loading / busy states (absent from style.css) ---------- */
.is-loading, button[aria-busy="true"], .btn[aria-busy="true"]{
  position:relative; color:transparent !important; pointer-events:none;
}
.is-loading::after, button[aria-busy="true"]::after{
  content:""; position:absolute; inset:0; margin:auto;
  width:14px; height:14px; border-radius:50%;
  border:2px solid rgba(255,255,255,.5); border-top-color:#fff;
  animation:pil-spin .6s linear infinite;
}
@keyframes pil-spin{ to{ transform:rotate(360deg); } }

.skeleton{
  background:linear-gradient(90deg,
    var(--bg-app) 25%, var(--row-hover) 37%, var(--bg-app) 63%);
  background-size:400% 100%;
  animation:pil-shimmer 1.4s ease-in-out infinite;
  border-radius:var(--r-sm); color:transparent;
}
@keyframes pil-shimmer{ 0%{background-position:100% 0} 100%{background-position:0 0} }

/* Success / warning toasts (style.css ships only the overdue-red left bar) */
.toast.ok{ border-left-color:var(--st-done); }
.toast.warn{ border-left-color:var(--st-progress); }

/* Guard only the animations introduced above; style.css has its own
   prefers-reduced-motion block for its own motion. */
@media (prefers-reduced-motion: reduce){
  .is-loading::after, .skeleton{ animation:none; }
}

/* PIL-TB-COL-002 - the trial-balance column strip.
   Every column of the uploaded sheet is a card showing its heading, a few REAL values
   from the file, and the role the operator has given it. Sample values are shown because
   a heading alone does not tell anyone which "Amount" is which.
   Tokens only - no new colours (DESIGN.md S4), 8px grid (S5). */
.tb-cols{
  display:flex; gap:8px; overflow-x:auto; padding:8px 0 16px;
}
.tb-col{
  flex:0 0 auto; min-width:168px; max-width:240px;
  border:1px solid var(--border); border-radius:var(--r-lg);
  background:var(--bg-surface);
}
.tb-col-head{
  font-weight:600; padding:8px; border-bottom:1px solid var(--border);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.tb-col-sample{
  padding:8px; color:var(--text-secondary); font-size:.875rem;
  border-bottom:1px solid var(--border-subtle);
}
.tb-col-sample div{
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.tb-col-roles{ padding:8px; display:flex; flex-direction:column; gap:4px; }
/* The whole label is the hit area, so "click the column" is literally true and the
   keyboard reaches it - no JS, which keeps CSP script-src 'self' intact. */
.tb-role{
  display:flex; align-items:center; gap:8px; cursor:pointer;
  padding:4px 8px; border-radius:var(--r-sm); font-size:.875rem;
}
.tb-role:hover{ background:var(--row-hover); }
.tb-role:has(input:checked){
  background:var(--brand-soft); color:var(--brand); font-weight:600;
}
/* :has() is unsupported on older engines; the checkbox itself still shows state, so the
   screen degrades to plain-but-correct rather than to ambiguous. */
.tb-col:has(input:checked){ border-color:var(--brand); }

/* PIL-TB-MAP-002 - map against the live sheet. Two panes: the spreadsheet exactly as
   uploaded (left, scrolls), the mapping (right, sticky) - Excel stays closed.
   Tokens only (DESIGN.md S4), 8px grid (S5). */
.tb-map-split{ display:grid; grid-template-columns:minmax(320px,5fr) minmax(420px,7fr);
  gap:16px; align-items:start; }
@media (max-width:1100px){ .tb-map-split{ grid-template-columns:1fr; } }
.tb-sheet{ border:1px solid var(--border); border-radius:var(--r-lg);
  background:var(--bg-surface); max-height:72vh; overflow:auto; }
.tb-sheet-head{ position:sticky; top:0; background:var(--bg-raised); font-weight:600;
  padding:8px 12px; border-bottom:1px solid var(--border); z-index:1; }
.tb-sheet table{ width:100%; border-collapse:collapse; font-size:.8125rem; }
.tb-sheet td{ padding:2px 8px; border-bottom:1px solid var(--border-subtle);
  white-space:nowrap; max-width:220px; overflow:hidden; text-overflow:ellipsis; }
.tb-sheet .tbs-n{ color:var(--text-secondary); font-size:.75rem; text-align:right;
  border-right:1px solid var(--border); user-select:none; }
.tb-sheet .tbs-head td{ font-weight:700; background:var(--bg-raised); }
/* a row whose account still needs a mapping */
.tb-sheet .tbs-unmatched td{ background:color-mix(in srgb, var(--st-awaiting) 10%, white); }
/* the anchor flash: clicking r<N> in the mapping pane lands here and lights the row */
.tb-sheet tr:target td{ background:var(--brand-soft); }
.tb-mappane{ position:sticky; top:8px; }
#tbMap tr:target td{ background:var(--brand-soft); }
.tbs-rowlink{ font-size:.6875rem; margin-left:6px; color:var(--st-awaiting);
  text-decoration:none; border:1px solid var(--border); border-radius:var(--r-sm);
  padding:0 4px; }
.tbs-rowlink:hover{ background:var(--row-hover); }

/* PIL-CHART-WIRE-001 - the inline "+ New account" disclosure beside every account
   picker. Closed by default so it never competes with the task; native <details>, so
   no JS and CSP script-src 'self' is untouched. Tokens only, 8px grid. */
.addacct{ margin:8px 0 0; }
.addacct > summary{ cursor:pointer; font-size:.8125rem; color:var(--brand);
  padding:4px 0; list-style:none; }
.addacct > summary::-webkit-details-marker{ display:none; }
.addacct > summary:hover{ text-decoration:underline; }
.addacct[open] > summary{ font-weight:600; }
.addacct .toolbar{ margin-top:8px; padding:12px; border:1px solid var(--border);
  border-radius:var(--r-lg); background:var(--bg-raised); align-items:center; }
/* label text for screen readers only - the placeholder is not an accessible name */
.sr-only{ position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; }
/* ---------- G. Searchable account picker (acctpick.js) ----------
   An account <select> in a table cell is only as wide as the cell, so a real
   account label ("6610 Motor and fuel - delivery vehicles") is clipped and you
   cannot see what you are mapping to. Two fixes, in order:

     1. the NATIVE control gets a legible floor (min-width) so a no-JS browser,
        and the moment before the script runs, are already readable;
     2. acctpick.js replaces it with a button + a FIXED popup sized to its
        content, so the full label always reads regardless of the cell.

   No new hues: brand, status and neutral tokens only (S9 preserved). */

/* 1. Native floor. Scoped to [data-acct] so no other select is disturbed. */
select[data-acct]{ min-width:220px; }

/* 2. Enhanced control. */
.acctpick{ position:relative; display:block; }
/* The native select stays in the DOM - it is still the thing that POSTS - but is
   visually hidden. It must be CLIPPED, never display:none: a display:none control
   carrying `required` makes the browser refuse to submit with "not focusable" and
   no visible reason on the screen.

   The selector is deliberately NOT [data-acct]. Since PIL-UX-SEARCH-002 every long
   select is upgraded, and leaving this rule account-scoped would render the native
   control UNDERNEATH the new button on every one of them. */
.acctpick.acctpick-on > select{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}
/* PIL-UX-SEARCH-002. The account picker is a full-width form control and stays one.
   A GENERIC dropdown must keep the footprint of the native select it replaced: 18 of
   them sit inline in a toolbar or filter bar (the Jobs and Desk status pickers among
   them), where a 100%-wide, 200px-minimum block button would break the row. */
.acctpick-auto{ display:inline-block; width:auto; max-width:100%; vertical-align:middle; }
.acctpick-auto > .acctpick-btn{ width:auto; min-width:0; max-width:100%; }

.acctpick-btn{
  display:block; width:100%; min-width:200px; height:36px; padding:0 28px 0 10px;
  border:1px solid var(--border); border-radius:var(--r-sm);
  background:var(--bg-surface); font:400 13px/34px var(--font);
  color:var(--text-primary); text-align:left; cursor:pointer;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  transition:border-color var(--dur-1) var(--ease);
}
.acctpick-btn::after{
  content:""; position:absolute; right:10px; top:50%; width:0; height:0;
  margin-top:-2px; border:4px solid transparent; border-top-color:var(--text-secondary);
}
.acctpick-btn:hover{ border-color:var(--border-strong); }
.acctpick-btn[aria-expanded="true"]{
  border-color:var(--brand); box-shadow:0 0 0 3px color-mix(in srgb,var(--brand) 16%,transparent);
}
.acctpick-btn.is-empty{ color:var(--text-secondary); }
/* In-table controls sit at the 32px table-action height (S7). */
td .acctpick-btn, th .acctpick-btn{ height:32px; line-height:30px; }

.acctpick-pop{
  display:none; position:fixed; z-index:60; max-height:340px;
  background:var(--bg-surface); border:1px solid var(--border-strong);
  border-radius:var(--r-lg); box-shadow:var(--shadow-2); overflow:hidden;
  flex-direction:column;
}
.acctpick-pop.open{ display:flex; }
.acctpick-q{
  width:100%; height:36px; padding:0 10px; border:0;
  border-bottom:1px solid var(--border); border-radius:0;
  font:400 13px var(--font); color:var(--text-primary); background:var(--bg-raised);
}
.acctpick-q:focus{ outline:none; box-shadow:none; border-bottom-color:var(--brand); }
.acctpick-list{ flex:1 1 auto; min-height:0; overflow-y:auto; padding:4px 0; }
.acctpick-grp{
  padding:8px 12px 4px; font:600 11px var(--font); letter-spacing:.04em;
  text-transform:uppercase; color:var(--text-secondary);
}
.acctpick-opt{
  padding:7px 12px; font:400 13px var(--font); color:var(--text-primary);
  cursor:pointer; white-space:normal;         /* wrap - never clip an account name */
}
.acctpick-opt.on{ background:var(--brand-soft); }
.acctpick-opt[aria-selected="true"]{ font-weight:600; }
.acctpick-empty{
  padding:14px 12px; font:italic 400 13px var(--font); color:var(--text-secondary);
}
.acctpick-foot{
  display:flex; gap:16px; padding:8px 12px; border-top:1px solid var(--border);
  background:var(--bg-raised);
}
.acctpick-foot a{ font:500 12px var(--font); color:var(--brand); text-decoration:none; }
.acctpick-foot a:hover{ text-decoration:underline; }
/* in-picker "create & use it" (2026-08-07): the account you were searching for gets
   created right here and selected - no leaving the screen mid-reconciliation. */
.acctpick-add{ padding:10px 12px; border-top:1px solid var(--border); background:var(--bg-raised); }
.acctpick-add input, .acctpick-add select{ height:30px; font-size:12px; margin-top:6px; }
.acctpick-add-row{ display:flex; gap:8px; align-items:center; }
.acctpick-add-row select{ flex:1; }
.acctpick-add-msg{ font:400 11px var(--font); color:var(--text-secondary); margin-top:6px; }
.acctpick-add-msg.is-err{ color:var(--warn-text); }
.acctpick-add-go, .acctpick-add-cancel{
  margin-top:8px; height:28px; padding:0 10px; font:500 12px var(--font);
  border-radius:var(--r-sm); border:1px solid var(--border); cursor:pointer;
}
.acctpick-add-go{ background:var(--brand); border-color:var(--brand); color:#fff; }
.acctpick-add-cancel{ background:var(--bg-surface); color:var(--text-secondary); }

/* ---------- H. Bulk action bar (PIL-WF-001) ----------
   Tick cards on the board, then apply one change to all of them. The bar sits above
   the Kanban; the tick sits top-right on the card so it never covers the job name.
   Existing tokens only - no new hues. */
.bulkbar{
  background:var(--bg-raised); border:1px solid var(--border);
  border-radius:var(--r-lg); padding:10px 14px; margin:0 0 16px;
  align-items:center; flex-wrap:wrap; gap:10px;
}
.bulkbar select{ width:auto; min-width:190px; }
.jobcard{ position:relative; }
.jc-pick{
  position:absolute; top:8px; right:8px; margin:0; padding:0;
  display:flex; align-items:center; cursor:pointer;
}
.jc-pick input{ width:15px; height:15px; margin:0; cursor:pointer; accent-color:var(--brand); }
/* keep the job name clear of the tick */
.jobcard > a:first-of-type{ padding-right:22px; display:inline-block; }
/* Cash coding: the wrapper is now the flex child, and the "applied" confirmation
   tint has to land on the control that is actually visible. Same --st-done token
   style.css already uses for select.cc-applied - no new hue. */
.cc-split-row .acctpick{ flex:1 1 220px; }
.cc-acct .acctpick{ flex:1 1 220px; min-width:200px; }
/* ---------- H2. Capture review pane widths (PIL-CAP-001) ----------
   The document must be able to get BIGGER - up to essentially the whole screen with the
   form yielding - and "Whole page" must always be reachable. Three steps, remembered per
   browser: Split (default 50/50-ish), Wide (~2/3), Full (the form drops below). The pane
   buttons reuse the .on state the filter chips already use - no new hues. */
.split-review.pane-wide .sr-doc{ flex:3 1 560px; }
.split-review.pane-wide .sr-form{ flex:1 1 300px; }
.split-review.pane-full .sr-doc{ flex:1 1 100%; }
.split-review.pane-full .sr-form{ flex:1 1 100%; }
.split-review .tiny.on{
  border-color:var(--brand); color:var(--brand); font-weight:600;
}
/* In Full, give the document real height - the whole point is seeing it big. */
.split-review.pane-full #docScroll{ height:86vh; }

/* ---------- I. Time capture widget (WS-O Phase 0) ----------
   Lives in the top bar on every screen. Closed it is a small clock; open it is a popover
   over the page, so booking time never means navigating away from the work. Existing
   tokens only - the running state borrows the S4 in-progress amber as an ACCENT, not as a
   status pill, which S11a already sanctions for a live control. */
.timew{ position:relative; }
.timew > summary{
  list-style:none; cursor:pointer; display:flex; align-items:center; gap:6px;
  height:32px; padding:0 10px; border:1px solid var(--border); border-radius:var(--r-sm);
  background:var(--bg-surface); font:500 13px var(--font); color:var(--text-secondary);
}
.timew > summary::-webkit-details-marker{ display:none; }
.timew > summary:hover{ border-color:var(--border-strong); color:var(--text-primary); }
.timew > summary svg{ width:15px; height:15px; }
.timew.timew-running > summary{ border-color:var(--st-progress); color:var(--text-primary); }
.timew-run{ font-variant-numeric:tabular-nums; font-weight:600; color:var(--warn-text); }
.timew-body{
  position:absolute; right:0; top:calc(100% + 6px); z-index:60; width:340px;
  background:var(--bg-surface); border:1px solid var(--border-strong);
  border-radius:var(--r-lg); box-shadow:var(--shadow-2); padding:14px 16px 12px;
  text-align:left;
}
.timew-body label{ margin-top:10px; }
.timew-body label:first-of-type{ margin-top:0; }
.timew-row{ display:grid; grid-template-columns:1fr 1fr; gap:12px; }
.timew-check{ display:flex; align-items:center; gap:6px; margin-top:12px;
  font-size:13px; color:var(--text-primary); text-transform:none; }
.timew-check input{ width:15px; height:15px; margin:0; accent-color:var(--brand); }
.timew-actions{ display:flex; gap:8px; justify-content:flex-end; margin-top:12px; }
@media (max-width:640px){ .timew-body{ width:min(340px, calc(100vw - 32px)); } }

.acctpick-btn.cc-applied{
  border-color:var(--st-done); box-shadow:0 0 0 2px color-mix(in srgb,var(--st-done) 22%,transparent);
}

/* PIL-NAV-003 (Principal, 2026-08-18) - "when I click approve the screen shakes and
   starts from the top; I lose track of where I was".
   Every action on these screens is POST-redirect-GET (which is what stops a browser
   refresh re-approving a line), so the page DOES reload - but the redirect now carries
   the anchor of the row that was actioned. scroll-margin-top keeps that row clear of the
   sticky header instead of landing underneath it, and scroll-behavior makes the landing
   settle rather than snap. */
html{ scroll-behavior:smooth; }
@media (prefers-reduced-motion:reduce){ html{ scroll-behavior:auto; } }
.anchor-row{ scroll-margin-top:96px; }
tr.anchor-row:target > td{ background:color-mix(in srgb, var(--brand) 9%, white); }
tr.anchor-row:target > td:first-child{ box-shadow:inset 3px 0 0 0 var(--brand); }

/* PIL-NAV-000 (Principal, 2026-08-18) - "these must be clickable so I can dive deep and
   see which transactions". The cash-coding counters are now drill-downs; this marks the
   one currently driving the grid, so a narrowed grid can never be mistaken for the whole
   workspace. Uses the existing brand token - no new colour. */
a.metric.on{ border-color:var(--brand); box-shadow:inset 0 0 0 1px var(--brand); }
a.metric.on .mv{ color:var(--brand); }

/* PIL-RECON-SELECT-001 (Principal, 2026-08-18) - tick, pick, code. The bulk bar and the
   selection column on the recon and cash-coding screens. Existing tokens only, no new
   colour: the selected row uses the same brand tint the anchored row does. */
.bulkbar{ display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  padding:10px 12px; margin:0 0 8px; border:1px solid var(--border);
  border-radius:6px; background:var(--bg-app); }
.bulkbar .bulk-all,.bulkbar .bulk-learn{ display:inline-flex; align-items:center; gap:6px;
  font-size:.8125rem; font-weight:600; white-space:nowrap; cursor:pointer; }
.bulkbar .bulk-learn{ font-weight:500; color:var(--text-secondary); }
.bulkbar .cell-sub{ flex-basis:100%; }
.bulkbar button[disabled]{ opacity:.5; cursor:not-allowed; }
th.chk,td.chk{ width:32px; text-align:center; padding-left:8px; padding-right:0; }
th.chk input,td.chk input{ cursor:pointer; }
tr.row-selected > td{ background:color-mix(in srgb, var(--brand) 8%, white); }
.sr-only{ position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; }
