:root{
  /* Light-only design: without this, iOS/iPadOS dark mode paints native widget
     text (buttons, inputs, selects) white against our forced-white backgrounds. */
  color-scheme: light;
  --bg:#f6f7f9; --panel:#fff; --ink:#1c2430; --muted:#6b7684; --line:#e5e8ec;
  --brand:#212e40; --accent:#2f6fed; --ok:#1a7f4b; --err:#c0392b;
}
*{box-sizing:border-box}
body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  color:var(--ink);background:var(--bg);font-size:14px;line-height:1.5;}
a{color:var(--accent);text-decoration:none}
a:hover{text-decoration:underline}
.muted{color:var(--muted)}
.small{font-size:12.5px}
.ok{color:var(--ok)} .error{color:var(--err);font-weight:600}

/* layout */
.layout{display:flex;height:100vh;overflow:hidden}
/* Sidebar and main scroll independently: the left nav stays put while the page scrolls. */
.sidebar{width:250px;flex:0 0 250px;background:var(--brand);color:#fff;padding:0 0 24px;height:100vh;overflow-y:auto}
.brand{padding:20px 20px 16px}
.brand a{color:#fff;font-weight:700;font-size:16px;display:block;line-height:1.2}
.brand span{display:block;font-weight:400;font-size:12px;color:#aeb8c6;margin-top:2px}
.nav-label{padding:8px 20px;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:#8a97a8}
.entities a{display:block;padding:8px 20px;color:#d6dce4;border-left:3px solid transparent}
.entities a:hover{background:rgba(255,255,255,.06);text-decoration:none}
.entities a.active{background:rgba(255,255,255,.10);border-left-color:var(--accent);color:#fff}
.main{flex:1;min-width:0;height:100vh;overflow-y:auto;display:flex;flex-direction:column}
/* Narrow screens: the sidebar gets out of the way (QuickBooks-style) — it slides in as an
   overlay from the ☰ button instead of squeezing the content columns unreadable. */
.nav-toggle{display:none;background:none;border:1px solid var(--line);border-radius:7px;
  color:var(--ink);font-size:16px;line-height:1;padding:6px 10px;cursor:pointer;margin-right:10px}
.nav-scrim{display:none}
@media (max-width:1020px){
  .sidebar{position:fixed;left:0;top:0;bottom:0;z-index:40;transform:translateX(-100%);
    transition:transform .18s ease;box-shadow:0 0 30px rgba(10,16,28,.35)}
  .layout.nav-open .sidebar{transform:none}
  .layout.nav-open .nav-scrim{display:block;position:fixed;inset:0;z-index:39;background:rgba(15,22,34,.35)}
  .nav-toggle{display:inline-block}
  .topbar{padding:10px 16px}
  .content{padding:16px}
}
.topbar{display:flex;justify-content:space-between;align-items:center;padding:14px 28px;
  background:var(--panel);border-bottom:1px solid var(--line);position:sticky;top:0;z-index:5}
.crumb{font-weight:600}
.userbox{color:var(--muted);font-size:13px}
.content{padding:28px;max-width:1000px;width:100%}
.content-wide{max-width:none}
h1{font-size:20px;margin:0 0 4px}

/* dashboard cards */
.cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:16px;margin-top:18px}
.card{display:block;background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:18px;color:inherit}
.card:hover{border-color:var(--accent);box-shadow:0 2px 10px rgba(20,30,50,.06);text-decoration:none}
.card-title{font-weight:650;font-size:15px}
.card-meta{color:var(--muted);font-size:12.5px;margin-top:4px}
.card-links{color:var(--accent);font-size:12.5px;margin-top:12px}

/* report chrome */
.report-head{border-bottom:1px solid var(--line);margin-bottom:14px}
.tabs{display:flex;gap:4px;margin:12px 0 10px}
.tabs a{padding:7px 14px;border-radius:7px 7px 0 0;color:var(--muted)}
.tabs a.active{background:var(--panel);color:var(--ink);font-weight:600;border:1px solid var(--line);border-bottom-color:var(--panel)}
.daterow{display:flex;gap:14px;align-items:center;margin:0 0 14px;color:var(--muted)}
.daterow input{padding:5px 8px;border:1px solid var(--line);border-radius:6px;font:inherit}
.daterow button,.login-card button{background:var(--accent);color:#fff;border:0;border-radius:6px;padding:6px 14px;font:inherit;cursor:pointer}

/* tables */
/* The #e<id> anchor put the edit form under the header; keep it clear of it. */
.register tr.edit-row{scroll-margin-top:96px}
/* the bank's own text, shown for reference while editing — clearly not an input */
.inline-edit .readonly-field{background:#f3f5f8;color:var(--muted);cursor:default}
.ledger-table{width:100%;border-collapse:collapse;background:var(--panel);border:1px solid var(--line);border-radius:8px;overflow:hidden}
.ledger-table th,.ledger-table td{padding:8px 12px;border-bottom:1px solid var(--line);text-align:left;vertical-align:top}
.ledger-table thead th{background:#fbfcfd;font-size:12px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted)}
.ledger-table .n{text-align:right;font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1;white-space:nowrap}
/* all monetary figures share one tabular treatment for a consistent look */
.n,.amt,.stack-form .amt,.inline-edit .amt{font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}
.ledger-table .t{color:var(--muted);font-size:12.5px}
.ledger-table tfoot th{background:#fbfcfd;font-weight:700}
.ledger-table tr.section td{background:#f0f3f7;font-weight:650;text-transform:uppercase;font-size:12px;letter-spacing:.03em}
.ledger-table td.indent{padding-left:26px}
.ledger-table tr.subtotal td{font-weight:650;border-top:1px solid var(--line)}
.ledger-table tr.subtotal.grand td{border-top:2px solid var(--brand)}
.ledger-table td.memo{color:var(--muted);max-width:520px}
.nowrap{white-space:nowrap}

/* login */
.login-wrap{min-height:100vh;display:flex;align-items:center;justify-content:center;background:var(--brand)}
.login-card{background:#fff;border-radius:12px;padding:32px;width:320px;box-shadow:0 10px 40px rgba(0,0,0,.25);display:flex;flex-direction:column;gap:10px}
.login-brand{font-weight:700;font-size:20px;color:var(--brand)}
.login-sub{color:var(--muted);margin-bottom:8px}
.login-card label{display:flex;flex-direction:column;gap:4px;font-size:13px;color:var(--muted)}
.login-card input{padding:9px 10px;border:1px solid var(--line);border-radius:7px;font:inherit;color:var(--ink)}
.login-card button{margin-top:8px;padding:10px}

/* toolbar / chart of accounts / forms */
.toolbar{display:flex;justify-content:space-between;align-items:center;gap:12px;margin:0 0 14px;flex-wrap:wrap}
.filterbox{display:flex;gap:8px;align-items:center}
/* A view-filter checkbox sitting beside the filter box. Readable weight on purpose:
   the old muted-small link was hard to read and looked like static text. */
.check-inline{display:inline-flex;align-items:center;gap:6px;white-space:nowrap;
  color:var(--ink);font-size:13px;cursor:pointer}
.check-inline input{cursor:pointer}
.filterbox input[type=search]{height:36px;padding:0 10px;border:1px solid var(--line);
  border-radius:7px;font:inherit;min-width:240px;box-sizing:border-box}
/* Must look identical on an <a> and a <button>. Everywhere else .btn is a link, which
   has no border; the New Payee button is a real <button> and kept the browser's own
   border and inset shading, so it read as having a shadow the other buttons lacked. */
/* ONE button box for the whole site. Three classes do the same job -- .btn primary,
   .btn-light secondary, .save in the inline forms -- and they had drifted to four
   different heights (35, 36, 37, 39), while the Filter buttons carried no class at all
   and rendered as a 21px browser default next to a 35px New Payee. Colour and weight
   still vary by class; the box does not. 36px matches the inputs they sit beside. */
.btn,.btn-light,button.save,.inline-actions .save,.inline-actions .del,
.feed-head button,.filterbox button,.export-menu>summary{
  height:36px;padding:0 14px;border-radius:7px;font:inherit;font-size:14px;line-height:1;
  display:inline-flex;align-items:center;justify-content:center;white-space:nowrap;
  cursor:pointer;-webkit-appearance:none;appearance:none;box-sizing:border-box}
.btn{background:var(--accent);color:#fff;border:0;font-weight:600}
.btn:hover{text-decoration:none;filter:brightness(1.05)}
.ledger-table th.act,.ledger-table td.act{white-space:nowrap;text-align:right}
.ledger-table td.act a{margin-left:6px}
/* native pulldown menu */
.rowmenu{display:inline-block;position:relative}
.rowmenu>summary{list-style:none;cursor:pointer;color:var(--muted);padding:0 4px;border:1px solid var(--line);border-radius:5px;margin-left:4px}
.rowmenu>summary::-webkit-details-marker{display:none}
.rowmenu[open]>summary{background:#eef2f7}
.rowmenu .menu{position:absolute;right:0;top:120%;z-index:10;background:#fff;border:1px solid var(--line);
  border-radius:8px;box-shadow:0 6px 20px rgba(20,30,50,.12);min-width:160px;padding:4px}
.rowmenu .menu a{display:block;padding:7px 12px;border-radius:6px;color:var(--ink);text-align:left}
.rowmenu .menu a:hover{background:#f0f3f7;text-decoration:none}
.register td.act a{color:var(--accent)}

/* stacked forms */
.stack-form{max-width:900px;background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:22px}
.stack-form label{display:flex;flex-direction:column;gap:5px;font-size:13px;color:var(--muted);margin-bottom:14px}
.stack-form input,.stack-form select{padding:8px 10px;border:1px solid var(--line);border-radius:7px;font:inherit;color:var(--ink)}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:0 18px}
.stack-form .amt{text-align:right;font-variant-numeric:tabular-nums}
/* Journal-entry lines table: keep it inside the card (fixed layout so the account/debit/
   credit/memo inputs fill their cells instead of forcing the table wider than the panel). */
.stack-form table{table-layout:fixed}
.stack-form table input,.stack-form table select{width:100%;box-sizing:border-box;max-width:none}
.stack-form th:nth-child(1),.stack-form td:nth-child(1){width:34%}
.stack-form th:nth-child(2),.stack-form td:nth-child(2){width:18%}
.stack-form th:nth-child(3),.stack-form td:nth-child(3){width:18%}
.stack-form th:nth-child(4),.stack-form td:nth-child(4){width:30%}
.form-actions{display:flex;gap:14px;align-items:center;margin-top:8px}
.form-actions button{background:var(--accent);color:#fff;border:0;border-radius:7px;padding:9px 18px;font:inherit;cursor:pointer}

/* sidebar feature nav (replaces per-company list) */
.features a{display:block;padding:8px 20px;color:#d6dce4;border-left:3px solid transparent}
.features a:hover{background:rgba(255,255,255,.06);text-decoration:none}
.features a.active{background:rgba(255,255,255,.10);border-left-color:var(--accent);color:#fff}
/* top-bar company picker */
.company-picker{display:flex;align-items:center;gap:8px}
.picker-label{font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
.company-picker select{padding:6px 30px 6px 10px;border:1px solid var(--line);border-radius:8px;font:inherit;
  font-weight:600;color:var(--ink);background:#fff;max-width:340px}
/* status badges */
.badge{display:inline-block;font-size:11px;font-weight:700;letter-spacing:.03em;padding:2px 8px;border-radius:999px}
.badge-wait{background:#fdf0d5;color:#8a6d1a}
.badge-ok{background:#e2f3ea;color:var(--ok)}

/* sortable headers */
.ledger-table thead a.sorth{color:var(--muted);display:inline-flex;align-items:center;gap:4px}
.ledger-table thead a.sorth:hover{color:var(--ink);text-decoration:none}
.ledger-table thead .caret{color:var(--accent);font-size:10px}
/* pagination */
.pager{display:flex;justify-content:space-between;align-items:center;margin-top:12px;flex-wrap:wrap;gap:10px}
.pager-links{display:flex;gap:14px;align-items:center;font-size:13px}
.pager-links .disabled{color:#c4ccd6}
/* register account switcher */
.reg-title{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-top:4px}
.acct-switch{padding:6px 30px 6px 10px;border:1px solid var(--line);border-radius:8px;font:inherit;font-weight:600;max-width:420px}

/* inline register editing */
.edit-row td{background:#f3f7ff;box-shadow:inset 0 0 0 2px var(--accent)}
.inline-edit{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px 16px;align-items:end}
.inline-edit label{display:flex;flex-direction:column;gap:3px;font-size:11px;text-transform:uppercase;letter-spacing:.03em;color:var(--muted);min-width:0}
/* One explicit height for both, or a <select> sizes itself from its own intrinsics and
   comes out a different height from the inputs beside it — which is what made Account and
   Direction look wrong next to Date, Payee and Amount. */
.inline-edit input,.inline-edit select{height:36px;padding:0 8px;border:1px solid var(--line);
  border-radius:6px;font:inherit;line-height:normal;color:var(--ink);width:100%;
  box-sizing:border-box;background:#fff}
.inline-edit .wide{grid-column:auto}
.inline-edit .amt{text-align:right;font-variant-numeric:tabular-nums}
@media (max-width:760px){.inline-edit{grid-template-columns:repeat(2,minmax(0,1fr))}}
.inline-actions{display:flex;gap:10px;align-items:center;margin-top:12px}
.inline-actions .save{background:var(--accent);color:#fff;border:0;font-weight:600}
.inline-actions .del{background:#fff;color:var(--err);border:1px solid #eab8b2}
.inline-actions .btn-cancel{color:var(--muted)}
/* bank feeds */
.conn-bar{display:flex;flex-wrap:wrap;gap:12px;margin:18px 0 8px}
.conn-chip{display:flex;align-items:center;gap:10px;padding:10px 14px;border:1px solid var(--line);border-radius:9px;background:var(--card,#fff)}
.conn-chip button{background:var(--accent);color:#fff;border:0;border-radius:7px;padding:6px 12px;font:inherit;font-weight:600;cursor:pointer}
.feed-group{font-size:15px;margin:24px 0 8px}
.audit-detail{background:var(--card,#f6f7f9);border:1px solid var(--line);border-radius:6px;padding:8px;font-size:11px;overflow-x:auto;max-width:520px;white-space:pre-wrap}
/* bank transactions review */
/* Account tiles: a real grid, so every card is the same width and the rows line up.
   auto-fill + minmax lets the column count follow the window without leaving the last
   row ragged the way flex-wrap did. */
.tiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:10px;margin:14px 0}
.tile{display:flex;flex-direction:column;gap:2px;min-height:104px;padding:11px 13px;border:1px solid var(--line);border-radius:10px;text-decoration:none;color:var(--ink);background:var(--card,#fff)}
.tile.sel{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}
.tile-warn{border-color:#e6b8b8;background:#fffaf9}
.tile-top{display:flex;align-items:flex-start;justify-content:space-between;gap:6px}
/* one line each, ellipsised — long legal entity names must not reflow the grid */
.tile-name{font-weight:600;font-size:13px;line-height:1.3;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tile-sub{font-size:11px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tile-bal{margin-top:auto;font-size:17px;font-weight:600;font-variant-numeric:tabular-nums}
.tile-foot{font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums;display:flex;gap:6px;align-items:baseline;flex-wrap:wrap}
.tile-ok{color:var(--ok,#2a7a52)}
.tile-flag{color:#b4453c;font-weight:600}
.tile-badge{background:var(--accent);color:#fff;border-radius:999px;padding:0 7px;font-size:11px;flex:none}
/* daily balance-check exceptions */
.check-panel{border:1px solid #e6b8b8;background:#fffaf9;border-radius:10px;padding:12px 14px;margin:14px 0}
.check-head{font-weight:600;color:#b4453c;margin-bottom:6px}
.check-table{width:100%;border-collapse:collapse;margin-bottom:6px}
.check-table td{padding:3px 8px 3px 0;vertical-align:top;font-size:12.5px}
.check-table td.n{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.txn-tabs{display:flex;gap:4px;border-bottom:1px solid var(--line);margin:8px 0 4px}
.txn-tabs a{padding:8px 14px;text-decoration:none;color:var(--muted);border-bottom:2px solid transparent}
.txn-tabs a.on{color:var(--ink);font-weight:600;border-bottom-color:var(--accent)}
/* Desk chips: pick which set of books the tiles below show (personal vs the deal entities). */
.desk-chips{display:flex;gap:6px;flex-wrap:wrap;margin:0 0 10px}
.desk-chips a{padding:4px 12px;border:1px solid var(--line);border-radius:999px;text-decoration:none;
  color:var(--muted);font-size:12.5px;background:#fff}
.desk-chips a.on{color:#fff;background:var(--accent);border-color:var(--accent);font-weight:600}
.queue-head{margin:14px 0 2px;font-size:13.5px}
.bulk-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:14px 0 6px}
.btn-light{background:#fff;color:var(--ink);border:1px solid var(--line)}
.cat-in,.cat-sel{padding:5px 7px;border:1px solid var(--line);border-radius:6px;font:inherit;max-width:210px}
.rule-badge{display:inline-block;background:#e2f3ea;color:var(--ok);font-size:10px;font-weight:700;padding:1px 5px;border-radius:4px;margin-left:4px;vertical-align:middle}
.pair-badge{display:inline-block;background:#e2f3ea;color:var(--ok);font-size:10px;font-weight:700;letter-spacing:.03em;padding:1px 6px;border-radius:9px;margin-left:4px;vertical-align:middle}
/* Review queue: when the window is narrower than the table, scroll the table sideways in its
   own panel rather than crushing the Payee/Category inputs down to two visible characters. */
/* The rounded corners live on the SCROLLER, not the table. The table cannot clip itself
   (overflow:hidden there makes it the sticky action column's clipping ancestor, so the
   column stops pinning), and the scroller has to clip anyway. */
/* Flex so the runway below sits BESIDE the table and actually adds scrollable width;
   as a block sibling it would stack under the table and add nothing. */
.table-scroll{display:flex;align-items:flex-start;overflow-x:auto;border:1px solid var(--line);border-radius:8px;
  background:var(--panel)}
.table-scroll > table{border:0;border-radius:0;flex:0 0 auto}
.scroll-runway{flex:0 0 auto;width:0;align-self:stretch}
/* separate, not collapse: Chrome ignores position:sticky on a cell inside a
   border-collapse:collapse table, which is what the pinned action column needs. */
/* overflow:visible overrides .ledger-table's overflow:hidden (there for the rounded
   corners). With it hidden the TABLE becomes the sticky cell's clipping ancestor, so the
   pinned action column resolves against the table instead of the scroller and never
   sticks — the symptom was Approve rendering as "Appr..." off the right edge. */
/* --pin-w is the action column's width, read back by the script that decides whether to
   pin it. Declared once so the two cannot drift: the column used to say 96px and render
   113px, because the Approve button and its caret set a larger min-content width. */
/* min-width is what keeps the description readable when the pane gets narrow; it is NOT
   meant to force a scrollbar on a desktop. At 1000px it did exactly that — the columns'
   own natural minimum is 892px in a 972px pane — and the 28px of overflow it invented
   is what put the Approve button past the edge once the column stopped being pinned. */
.bank-queue{--pin-w:128px;min-width:940px;border-collapse:separate;border-spacing:0;
  overflow:visible}
.bank-queue th,.bank-queue td{border-bottom:1px solid var(--line)}
/* One column geometry for To review / Posted / Excluded, so switching tabs doesn't move the
   columns. max-width:0 with a percentage col width is the trick that makes a table cell
   actually honor its share and ellipsize instead of growing to fit its text. It also needs
   overflow:hidden: at iPad width the other columns' min-content demands squeezed the
   description cell to ~113px, and its memo input (which used to force min-width:220px)
   overflowed a cell that still clipped nothing, painting the bank text straight over the
   Spent and Received figures. The cell clips and the input shrinks with it; min-width on the
   table is what keeps the description readable, with .table-scroll handling the sideways pan. */
.bank-queue .c-sel{width:28px}
.bank-queue .c-date{width:88px}
/* The percentage columns have to leave room for the fixed ones, or the table computes
   wider than its container and the LAST column — the Approve button — is pushed off the
   right edge. Fixed columns now total 490px (a ninth was added for the row actions and
   the date grew for four-digit years), which is ~45% at the min-width below, so the
   percentages are sized to fit in what is left rather than the 74% they used to claim. */
.bank-queue .c-desc{width:24%}
.bank-queue .c-amt{width:92px}
.bank-queue .c-payee{width:12%}
.bank-queue .c-cat{width:17%}
.bank-queue .c-type{width:104px}
.bank-queue .c-rowact{width:var(--pin-w)}
/* The queue is deliberately wider than the pane and pans sideways, which is fine for the
   description — but not for the primary action: Approve was rendering as "Appr…" at the
   right edge and would be unreachable on an iPad without scrolling to find it. The action
   column sticks to the right instead, so it is always where you can press it. */
/* Pinned only while the table actually overflows by at least the pinned column's own
   width — the `pin-right` class, set by the script. A pinned column is an OVERLAY: it
   always covers whatever sits under the right edge, so pinning a table that nearly fits
   buys nothing and costs a column. That was the Type bug: the table overflowed its pane
   by 65px while the pinned column was 113px wide, so ~48px of Type sat underneath it at
   every scroll position and could not be reached at all. Below the threshold the column
   is ordinary and the whole row is readable; above it, there is by definition enough
   scrolling to bring any covered column out. */
.bank-queue.pin-right th.row-act-h,.bank-queue.pin-right td.row-act{position:sticky;right:0;
  z-index:2;background:var(--panel);box-shadow:-6px 0 6px -6px rgba(0,0,0,.12)}
/* The pinned column is an OVERLAY: it covers whatever table content happens to sit under
   the right edge. That is fine only if you can scroll that content out from under it. The
   table used to overflow its pane by less than the pinned column is wide (65px of scroll
   against a 113px column), so ~48px of the Type column was covered at EVERY scroll
   position — unreachable, not merely hidden. The trailing spacer is exactly as wide as
   the pinned column, which makes the scrollable distance at least the pinned width by
   construction, so every data column can always be scrolled clear. */
.bank-queue.pin-right tr:hover td.row-act{background:var(--panel)}
/* Register find-a-line box, same row as the period controls. */
.ctl-find{display:flex;align-items:flex-end;gap:10px}
/* Which sub-account a line sits on, in a parent's combined register. */
/* A parent standing in for its collapsed sub-accounts. */
.report-lines tr.collapsed-group td:first-child{font-weight:600}
.ctl-collapse{align-self:flex-end}
/* QuickBooks' CLR column: blank / * / R. Narrow, centred, quiet. */
.register .clr-col{width:28px;text-align:center;color:var(--muted);font-weight:700}
.register td.clr-col.is-recon{color:var(--ok)}
.sub-tag{display:inline-block;background:#eef2f8;color:var(--brand);font-size:10px;font-weight:700;padding:1px 6px;border-radius:9px;margin-left:5px;white-space:nowrap}
.ctl-find input[type=search]{min-width:190px}
/* Per-row Approve. Deliberately quieter than the bulk bar's primary button: the row
   action is a convenience, not the headline, and it sits next to live edit boxes where a
   loud button invites a misclick that posts to the books. Disabled until categorized. */
.bank-queue td.row-act{text-align:right}
/* While a row posts in place: dim it so the click clearly registered, and keep it
   non-interactive so a second click can't post it twice. */
.bank-queue tr.row-posting{opacity:.45;pointer-events:none}
.btn-row-approve{background:#fff;color:var(--ok);border:1px solid var(--ok);border-radius:6px;
  padding:4px 10px;font:inherit;font-size:12px;cursor:pointer;white-space:nowrap}
.btn-row-approve:hover:not(:disabled){background:var(--ok);color:#fff}
.btn-row-approve:disabled{color:var(--muted);border-color:var(--line);cursor:not-allowed}
/* The bank's raw text, folded away under the memo in the register. */
/* A row's second line: the things you need occasionally, off the line you read at a
   glance. Indented under the row and quieter than it, so the queue still scans as one
   row per transaction. */
.bank-queue tr.row-extra.is-hidden{display:none}
.bank-queue tr.row-extra > td{padding:0 10px 8px;border-top:0}
/* The expanded row, after QuickBooks Online's: the bank's full text, the memo, and the
   occasional actions — rather than a permanent second line of controls on every row. */
/* A grid, not a row of independent columns: every label sits on the first line and every
   value on the second, so the panel reads as two straight lines. As three stacked flex
   columns the labels lined up but the contents did not — a line of text, a textarea and a
   link are three different heights. `display:contents` lets each field's label and value
   join the parent grid instead of forming their own little column. */
.bank-queue .detail-panel{position:relative;background:#f7f9fc;border:1px solid var(--line);
  border-radius:8px;padding:12px 40px 12px 14px;margin:2px 0 8px 34px;
  display:grid;grid-template-columns:minmax(220px,1fr) minmax(220px,1fr);
  gap:5px 18px;align-items:center}
.bank-queue .panel-field{display:contents}
/* Nudged in by the input's own left padding so the label's text starts exactly above the
   text in the box beneath it — otherwise the label sits at the box EDGE and the value
   8px inside it, and the column reads as two slightly different left margins. */
.bank-queue .panel-label{grid-row:1;align-self:end;padding-left:9px;font-size:11px;
  text-transform:uppercase;letter-spacing:.03em;color:var(--muted);line-height:1.2}
.bank-queue .panel-value{padding-left:9px}
.bank-queue .panel-value{grid-row:2;align-self:center;font-size:13px;color:var(--ink);
  word-break:break-word;line-height:1.35}
.bank-queue .panel-field .memo-in{grid-row:2;align-self:center;max-width:none;margin:0;width:100%}
@media (max-width:860px){
  .bank-queue .detail-panel{grid-template-columns:1fr}
  .bank-queue .panel-label,.bank-queue .panel-value,
  .bank-queue .panel-field .memo-in{grid-row:auto}
}
.bank-queue .panel-close{position:absolute;top:6px;right:8px;background:none;border:0;
  font-size:18px;line-height:1;color:var(--muted);cursor:pointer}
.bank-queue .panel-close:hover{color:var(--ink)}
/* Action column: a primary button with the rare actions folded into a menu beside it. */
.bank-queue .act-group{display:flex;align-items:center;gap:2px;justify-content:flex-end}
.act-menu{position:relative}
.act-menu > summary{list-style:none;cursor:pointer;color:var(--muted);padding:4px 5px;
  border:1px solid transparent;border-radius:6px;font-size:12px}
.act-menu > summary::-webkit-details-marker{display:none}
.act-menu[open] > summary,.act-menu > summary:hover{border-color:var(--line);color:var(--ink)}
.act-menu .menu{position:absolute;right:0;top:100%;z-index:30;background:var(--panel);
  border:1px solid var(--line);border-radius:8px;box-shadow:0 6px 20px rgba(0,0,0,.12);
  min-width:140px;padding:4px;display:flex;flex-direction:column}
.act-menu .menu a,.act-menu .menu .menu-item{display:block;width:100%;text-align:left;
  background:none;border:0;padding:7px 10px;border-radius:6px;font:inherit;font-size:13px;
  color:var(--ink);text-decoration:none;cursor:pointer}
.act-menu .menu a:hover,.act-menu .menu .menu-item:hover:not(:disabled){background:#eef2f8}
.act-menu .menu .menu-item:disabled{color:var(--muted);cursor:not-allowed}
.register .bankdesc{display:inline}
.register .bankdesc summary{display:inline;color:var(--muted);font-size:11px;cursor:pointer;
  list-style:none;margin-left:6px;text-decoration:underline dotted}
.register .bankdesc summary::-webkit-details-marker{display:none}
.register .bankdesc span{display:block;color:var(--muted);font-size:11px;margin-top:2px}
.bank-queue .desc-static{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bank-queue td:nth-child(3){max-width:0;overflow:hidden}
/* On wide screens the queue's boxes grow with the page — no artificial caps. */
.bank-queue .cat-in{max-width:none}
.bank-queue .combo{max-width:none}
.bank-queue .payee-in{min-width:120px}
/* QB-style tidy rows: one line per transaction, vertically centered, and the editable
   fields read as plain text until you hover or click into them. */
.bank-queue td{vertical-align:middle;padding-top:5px;padding-bottom:5px}
.bank-queue .cat-in{border-color:transparent;background:transparent;text-overflow:ellipsis}
.bank-queue tr:hover .cat-in{border-color:var(--line);background:#fff}
.bank-queue .cat-in:focus{border-color:var(--accent);background:#fff;outline:none}
.desc-cell{display:flex;align-items:center;gap:6px}
.desc-cell .memo-in{flex:1 1 auto;margin:0}
/* Fixed sub-columns keep every row's picker the same width and line the badge and Split
   link up vertically down the queue. (Type has its own table column.) */
.cat-cell{display:grid;grid-template-columns:minmax(150px,1fr) 44px;gap:8px;align-items:center;white-space:nowrap}
/* The Posted tab renders the account as plain wrapping text and stays readable; To review
   showed it in a single-line <input>, so long names ellipsized with only a title= tooltip to
   recover them — and touch has no hover, so on an iPad they were simply unreadable. That
   input is purely a label and search box (the hidden field carries account_id), so the
   committed name renders as wrapping text and the input swaps in only while editing.
   Rows go multi-line for long names; that's the trade the owner chose for being able to read them. */
.combo-label{display:block;white-space:normal;overflow-wrap:anywhere;line-height:1.35;
  padding:5px 7px;border:1px solid transparent;border-radius:6px;cursor:text}
.combo-label:empty::before{content:"Search account…";color:#b3bcc7}
.bank-queue tr:hover .combo-label{border-color:var(--line);background:#fff}
.combo-label:focus{border-color:var(--accent);background:#fff;outline:none}
.combo:not(.editing) .combo-input{display:none}
.combo.editing .combo-label{display:none}
/* Payee gets the same read-in-the-row treatment: ~a quarter of real payees outrun this
   column, and touch has no hover for the title= to fall back on. It stays an <input> rather
   than the memo's textarea, because a textarea can't carry list= — that's the autocomplete. */
.payee-cell{position:relative}
/* Clamped to three lines like the memo: this column is the narrowest of the wrapping three,
   so the longest real payees ("Bank of America (Capital One cash rewards)") ran to four-plus
   lines and dragged the whole row with them. Three lines covers every payee in the book bar a
   couple, and those ellipsize rather than distorting the queue. */
.payee-label{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;line-clamp:3;
  overflow:hidden;white-space:normal;overflow-wrap:anywhere;line-height:1.35;
  /* No bottom padding: line-clamp clips at the PADDING box, so a bottom pad reveals a sliver
     of the fourth line under the ellipsis. The row's own td padding keeps the rhythm. */
  padding:5px 7px 0;border:1px solid transparent;border-radius:6px;cursor:text;min-height:29px}
.payee-label:empty::before{content:"Payee";color:#b3bcc7}
.bank-queue tr:hover .payee-label{border-color:var(--line);background:#fff}
.payee-label:focus{border-color:var(--accent);background:#fff;outline:none}
.payee-cell:not(.editing) .payee-in{display:none}
.payee-cell.editing .payee-label{display:none}
.cat-badge .pair-badge,.cat-badge .rule-badge{margin-left:0}
.cat-type{overflow:hidden;text-overflow:ellipsis}
.bank-queue .split-link{margin-left:0}
/* Chart of Accounts drag-to-reorder */
.drag-th,.drag-cell{width:26px;padding-left:8px;padding-right:0}
.drag-handle{cursor:grab;color:#b3bcc7;font-size:14px;user-select:none}
.drag-handle:hover{color:var(--muted)}
tr.dragging{opacity:.45}
tr.drop-ok td{border-top:2px solid var(--accent)}
.bank-queue .combo{min-width:180px}
/* The bank-description cell's single editable box (the memo, pre-filled with bank text).
   A textarea so long descriptions wrap and can be READ in the row: autosize() below grows it
   to fit, --memo-max-lines caps that at three, and anything longer scrolls inside the box.
   resize:none because the drag handle would fight the autosizing. */
/* Typed on the element, not just the class: the picker block's later `.cat-in{font:inherit}`
   has equal specificity and would otherwise reset the font-size and line-height this cap is
   measured in. --memo-lines is the cap; the padding/border term must match the box below. */
textarea.memo-in{display:block;width:100%;min-width:0;color:var(--ink);
  --memo-lines:3;font-size:13px;line-height:1.35;font-family:inherit;
  padding:5px 7px;resize:none;overflow-y:auto;
  max-height:calc(var(--memo-lines) * 1.35 * 13px + 12px)}
.memo-in::placeholder{color:#b3bcc7}
/* split categorization */
.split-link{margin-left:6px;white-space:nowrap}
.split-tag{display:inline-block;background:#eef2f8;color:var(--brand);font-size:12px;font-weight:600;padding:2px 8px;border-radius:9px;margin-right:4px}
.split-row td{background:#fbfcfd}
.split-editor{padding:4px 2px 8px}
.split-head{font-weight:600;margin-bottom:8px}
.split-line{display:flex;gap:8px;margin-bottom:6px;flex-wrap:wrap}
.ledger-table .split-line select{flex:2 1 260px;min-width:200px;padding:6px 8px;border:1px solid var(--line);border-radius:7px;font:inherit;color:var(--ink);background:#fff;max-width:none}
.split-line .split-amt{flex:0 1 110px;min-width:90px;text-align:right;width:auto}
.split-line .split-memo{flex:1 1 180px;min-width:140px;width:auto}
.split-actions{display:flex;gap:8px;align-items:center;margin-top:8px}
.split-actions .btn-light{text-decoration:none;color:var(--ink)}
.cat-state{display:inline-block;font-size:10px;font-weight:600;margin-left:4px;vertical-align:middle}
.cat-state.saving{color:var(--muted)}
.cat-state.saved{color:var(--ok)}
.cat-state.error{color:var(--err);cursor:pointer;text-decoration:underline}
/* Microsoft sign-in */
.ms-signin{display:flex;align-items:center;justify-content:center;gap:10px;width:100%;box-sizing:border-box;padding:10px;border:1px solid #8c8c8c;border-radius:6px;background:#fff;color:#5e5e5e;font-weight:600;text-decoration:none;margin-bottom:12px}
.ms-signin:hover{background:#f3f3f3}
.ms-logo{width:18px;height:18px;display:inline-block;background:linear-gradient(#f25022 0 0) 0 0/8px 8px no-repeat,linear-gradient(#7fba00 0 0) 10px 0/8px 8px no-repeat,linear-gradient(#00a4ef 0 0) 0 10px/8px 8px no-repeat,linear-gradient(#ffb900 0 0) 10px 10px/8px 8px no-repeat}
.login-or{text-align:center;color:#999;font-size:12px;margin:2px 0 12px;letter-spacing:.08em}
.login-note{text-align:center;color:#8a8a8a;font-size:12px;margin-top:6px}
.feed-section{margin-top:26px;padding-top:6px}
.feed-section + .feed-section{border-top:1px solid var(--line)}
.build-stamp{margin-top:22px;padding:12px 6px 4px;font-size:10.5px;line-height:1.5;color:var(--muted);opacity:.7}
.feed-head{display:flex;justify-content:space-between;align-items:center;gap:16px;margin-top:18px;flex-wrap:wrap}
.feed-head button,button.save{background:var(--accent);color:#fff;border:0;font-weight:600}
.ledger-table select{padding:5px 7px;border:1px solid var(--line);border-radius:6px;font:inherit;color:var(--ink);max-width:240px}

/* click-a-row-to-edit in the register */
.register tbody tr.clickable{cursor:pointer}
.register tbody tr.clickable:hover td{background:#f3f7ff}

/* report period + export controls */
.report-controls{display:flex;align-items:flex-end;gap:16px;flex-wrap:wrap;margin:8px 0 4px}
.report-controls .ctl{display:flex;flex-direction:column;gap:5px;font-size:11px;text-transform:uppercase;letter-spacing:.03em;color:var(--muted);line-height:1.3}
/* one uniform control height so the dropdown and calendar boxes line up on a single baseline */
.report-controls select,.report-controls input[type=date],.report-controls input[type=search],
.ctl-dates button,.ctl-find button,.report-controls a.btn-light{height:36px;box-sizing:border-box;border-radius:7px;font:inherit}
.report-controls select,.report-controls input[type=date],.report-controls input[type=search]{padding:0 10px;border:1px solid var(--line);color:var(--ink)}
/* anchors need the line-height to match a button's box */
.report-controls a.btn-light{display:inline-flex;align-items:center;padding:0 14px;text-decoration:none}
.report-controls select{min-width:190px}
.ctl-dates{display:flex;align-items:flex-end;gap:10px}
.ctl-dates button,.ctl-find button{background:var(--accent);color:#fff;border:0;padding:0 18px;cursor:pointer}
.export-menu>summary{border:1px solid var(--line);color:var(--ink);font-weight:600;background:#fff}
.export-menu[open]>summary{background:#eef2f7}

/* general ledger report */
.gl-acct{margin:0 0 22px}
.gl-acct-head{display:flex;align-items:baseline;gap:10px;margin:0 0 6px;padding-bottom:4px;border-bottom:2px solid var(--brand)}
.gl-acct-head a{font-weight:650;font-size:14px}
.gl-bb td,.gl-eb td{background:#fbfcfd;font-weight:600;color:var(--muted)}
.gl-eb td{border-top:1px solid var(--line)}

/* add-transaction menu */
.add-menu>summary{border:1px solid var(--accent);color:var(--accent);border-radius:7px;padding:7px 13px;font-weight:600;background:#fff;cursor:pointer}
.add-menu[open]>summary{background:var(--accent);color:#fff}

/* Reconcile page */
.rec-controls{display:flex;gap:14px;align-items:flex-end;flex-wrap:wrap;margin:16px 0}
.rec-controls label{display:flex;flex-direction:column;gap:4px;font-size:12px;color:var(--muted)}
.rec-controls input,.rec-controls select{height:36px;box-sizing:border-box;padding:4px 8px;border:1px solid var(--line);border-radius:6px;font:inherit;color:var(--ink)}
.rec-controls button{height:36px}
.rec-summary{max-width:560px}
.rec-summary td{padding:6px 10px}
.rec-summary td.n{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.rec-rule td{border-top:1px solid var(--line);font-weight:600}
.rec-total td{border-top:2px solid var(--ink);font-weight:700;font-size:15px}
.rec-ok td{color:var(--ok,#2a7a52)}
.rec-finish{display:flex;align-items:center;gap:14px;margin:14px 0 6px}
.rec-off td{color:#b4453c}
/* QB-style reconcile: difference banner + click-to-clear rows */
.rec-banner{display:flex;align-items:center;gap:14px;flex-wrap:wrap;background:var(--panel);
  border:1px solid var(--line);border-radius:10px;padding:14px 18px;margin:14px 0}
.rec-label{font-size:11.5px;color:var(--muted);text-transform:uppercase;letter-spacing:.04em}
.rec-num{font-size:19px;font-weight:650;font-variant-numeric:tabular-nums;white-space:nowrap}
.rec-op{font-size:18px;color:var(--muted)}
.rec-banner.rec-ok{border-color:#bfe3cf}
.rec-banner.rec-ok .rec-diff .rec-num{color:var(--ok)}
.rec-banner.rec-off .rec-diff .rec-num{color:#b4453c}
.rec-list .rec-row{cursor:pointer}
.rec-list .rec-row:hover td{background:#f4f7fb}
.rec-list .rec-row.saving{opacity:.55}
.rec-list td.rec-tick,.rec-list th.rec-tick{width:34px;text-align:center;padding-left:10px;padding-right:0}
.rec-row .tick{display:inline-block;width:22px;height:22px;line-height:20px;border:1.5px solid var(--line);
  border-radius:50%;color:#fff;font-weight:700;font-size:13px}
.rec-row.cleared .tick{background:var(--ok);border-color:var(--ok)}
.rec-row.cleared td{color:var(--muted)}
.rec-row.cleared td.n{color:var(--ink)}

/* Searchable category picker (Bank Transactions) */
.combo{position:relative;display:inline-block;width:100%;min-width:180px;max-width:280px}
.cat-in{padding:6px 9px;border:1px solid var(--line);border-radius:7px;font:inherit;color:var(--ink);width:100%}
.combo-list{position:absolute;z-index:30;left:0;right:0;top:100%;margin:3px 0 0;padding:4px;
  list-style:none;max-height:280px;overflow:auto;background:var(--panel);
  border:1px solid #cbd5e1;border-radius:8px;box-shadow:0 8px 24px rgba(20,30,50,.14)}
.combo-opt{padding:6px 9px;border-radius:6px;cursor:pointer;white-space:normal;overflow-wrap:anywhere;line-height:1.3;font-size:13px;color:var(--ink);display:flex;justify-content:space-between;align-items:baseline;gap:12px}
.combo-opt .opt-name{overflow-wrap:anywhere}
.combo-opt .opt-type{color:var(--muted);font-size:11.5px;white-space:nowrap;flex:0 0 auto}
.combo-opt:hover,.combo-opt.active{background:rgba(47,111,237,.10)}
.combo-opt.selected{font-weight:650}
.combo-opt.selected::after{content:" ✓";color:var(--ok)}

/* Settings page */
.settings-form fieldset{border:1px solid var(--line);border-radius:10px;padding:16px 18px;margin:0 0 16px;max-width:640px}
.settings-form legend{padding:0 6px;font-size:12px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted)}
.setting{display:flex;gap:10px;align-items:flex-start;cursor:pointer}
.setting input[type=checkbox]{margin-top:3px}
.setting span span{display:block}

/* Bank Feeds per-row auto-save indicator */
.save-state{font-size:12px;white-space:nowrap;color:var(--muted)}
.save-state.saving{color:var(--muted)}
.save-state.saved{color:var(--ok)}
.save-state.error{color:var(--err)}

/* Bank Transactions "Pull now" progress indicator */
.pull-status{font-size:12.5px;color:var(--muted)}
.pull-status.working::before{content:"";display:inline-block;width:9px;height:9px;margin-right:6px;
  border:2px solid var(--line);border-top-color:var(--accent);border-radius:50%;
  vertical-align:-1px;animation:pullspin .7s linear infinite}
@keyframes pullspin{to{transform:rotate(360deg)}}
.pull-status.done{color:var(--ok)}
.pull-status.error{color:var(--err)}

/* Bank Transactions: dim the queue briefly while an in-place tile/tab swap loads */
.bank-loading{opacity:.55}

/* Resizable queue columns (tracker#95 item 3 / the approver). The grip is a hit area on the right
   edge of each header cell, not a visible divider: the header already has a border there,
   and drawing a second line made the row look like a spreadsheet. It only shows up on
   hover, so the header stays quiet until you go looking for it. The last header is the
   sticky action column and gets no grip — there is nothing to its right to give width to. */
table[data-colresize] thead th{position:relative}
.col-grip{position:absolute;top:0;right:-4px;width:9px;height:100%;cursor:col-resize;
  z-index:3;background:transparent;touch-action:none}
.col-grip::after{content:"";position:absolute;top:4px;bottom:4px;left:4px;width:2px;
  border-radius:1px;background:transparent}
table[data-colresize] thead th:hover .col-grip::after,
.col-grip.dragging::after{background:var(--accent)}
/* While a drag is live the pointer must stay col-resize everywhere it travels, and text
   selection has to stop or the drag paints the header blue instead of moving the column. */
body.col-resizing{cursor:col-resize;user-select:none;-webkit-user-select:none}

/* Payees: the Chart of Accounts of names (tracker#95 item 1). */
.payees .p-name{width:40%}
.payees .p-uses{width:110px}
.payees .p-queued{width:110px}
.payees .p-note{width:auto}
.payees .p-act{width:80px}
.payees tr.retired-row td{color:var(--muted)}
/* The rename line sits under its row, so it must not read as another payee. */
.payees tr.rename-row > td{background:#f7f9fc;padding:10px 12px}
/* Not .inline-edit: that is a four-equal-column grid built for the register's editor, and
   it stretched a two-field form's buttons across half the page. These forms want their
   natural widths, in a row. An explicit [hidden] rule because a display: of any kind beats
   the hidden attribute, which is how the New Payee form came up already open. */
.payee-form{display:flex;align-items:flex-end;gap:12px;flex-wrap:wrap;margin:12px 0}
.payee-form[hidden]{display:none}
.payee-form label{display:flex;flex-direction:column;gap:3px;font-size:11px;
  text-transform:uppercase;letter-spacing:.03em;color:var(--muted)}
.payee-form input{height:36px;padding:0 8px;border:1px solid var(--line);border-radius:7px;
  font:inherit;color:var(--ink);min-width:220px}
.payees .merge-warn{color:#9a6700;max-width:420px;line-height:1.35}

/* The queue's Export sits at the far end of the bulk bar, away from the destructive
   actions it must not be confused with. */
.bulk-bar .bulk-export{margin-left:auto}

/* Payroll import: the account names are long and nested ("Payroll Expenses:Social
   Security - Employer Tax"), so the picker needs room or every line reads the same. */
.payroll-import select{min-width:330px;max-width:100%}
.payroll-import .gusto-type{color:var(--muted);font-size:12px}
