/* ============================================================================
 * EPAL GROUP ERP  ·  css/components.css
 * ----------------------------------------------------------------------------
 * COMPOSITE UI — the reusable building blocks every module renders with:
 * page headers, cards, KPI tiles, stat rows, progress/rings, kanban board,
 * modals, toasts, popovers, command palette, empty/gate states, timeline.
 * ==========================================================================*/

/* ---------------------------------------------------------- Page header */
/* TIGHT, FIXED HEADER BLOCK (owner 2026-07-15, second pass): the head must be
   exactly as tall as its own content and never taller — the owner marked the
   old block as mostly empty space. Every part is therefore pinned to ONE line
   so the block cannot grow with the text, and long content shrinks/ellipses
   instead ("if there are many text or items, just reduce those items size"):
     · .page-title row  = 29  (eyebrow sits INLINE before the icon + title;
                               eyebrow nowrap — a wrapping eyebrow is what used
                               to make Consolidated Finance's head 10px taller)
     · sub margin       =  4
     · .page-sub        = 21  (single line, ellipsis, full text on hover)
                          --
                          54  → min-height 56 with a hair of slack.
   Because nothing here can wrap, the block measures the same on every screen
   and the section-nav lands at the same Y — the earlier guarantee, now at half
   the height. Actions stay nowrap so they can never drop to their own row. */
.page-head { display: flex; align-items: center; justify-content: space-between; gap: 18px; margin-bottom: 10px;
  flex-wrap: nowrap; min-height: 56px; }
.page-head > *:first-child { min-width: 0; }
.page-title { font-size: var(--fs-h2); font-weight: 700; letter-spacing: -.02em; display: flex; align-items: center; gap: 12px;
  flex-wrap: nowrap; min-width: 0; white-space: nowrap; overflow: hidden; }
.page-title .eyebrow { flex: 0 0 auto; font-family: var(--font-sans); font-size: var(--fs-tiny); font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--accent); white-space: nowrap; }
.page-sub { color: var(--text-dim); font-size: var(--fs-small); line-height: 1.55; margin-top: 4px; max-width: min(760px, 46vw);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-height: 21px; }
.page-actions { display: flex; align-items: center; gap: 10px; flex-wrap: nowrap; flex: 0 0 auto; }
@media (max-width: 720px) {                      /* phones: let it breathe again */
  .page-head { flex-wrap: wrap; min-height: 0; align-items: flex-start; margin-bottom: 14px; }
  .page-sub { min-height: 0; white-space: normal; max-width: none; }
  .page-actions { flex-wrap: wrap; }
}

/* --------------------------------------------------------------- Cards */
.card {
  background: linear-gradient(180deg, color-mix(in srgb, var(--surface-hi) 20%, var(--surface)), var(--surface));
  border: 1px solid var(--border); border-radius: var(--r-lg);
  box-shadow: var(--shadow-card), inset 0 1px 0 var(--hairline); position: relative; overflow: hidden; transition: border-color var(--t), box-shadow var(--t), transform var(--t);
}
.card.hover:hover { border-color: var(--card-hover); box-shadow: var(--shadow), inset 0 1px 0 var(--hairline); transform: translateY(-2px); }
.card.sel { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }   /* selected (e.g. the open bank account) */
.card-pad { padding: 20px; }
.card-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 16px 20px; border-bottom: 1px solid var(--border); }
/* A long title must yield space, not shove the header's action icons out of
   the card (the card clips overflow, so pushed-out actions vanish). The title
   shrinks; the row-actions keep their full width and stay inside the card. */
.card-head > h3 { min-width: 0; }
.card-head .row-actions { flex: none; }
.card-head h3 { font-size: var(--fs-lead); font-weight: 700; display: flex; align-items: center; gap: 9px; }
.card-head h3 i { color: var(--accent); }
.card-head .card-sub { font-size: var(--fs-tiny); color: var(--text-mute); font-weight: 400; }
.card-body { padding: 18px 20px; }
.card-foot { padding: 12px 20px; border-top: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; }
.glass { background: var(--glass); backdrop-filter: blur(20px); border: 1px solid var(--glass-brd); }
.card-accent::before { content:''; position: absolute; inset: 0 auto 0 0; width: 3px; background: var(--accent); }

/* --------------------------------------------------------------- KPI tiles */
.grid-auto { display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
/* HOUSE RULE: KPI cards are the SAME (slim) size everywhere — ~30% smaller than
   the old cards. They used to fit as many as possible on one row; they now stop
   at five (see the cap below).
   HOUSE CAP: at most FIVE KPIs abreast (owner review 2026-07-15). Consolidated
   Finance was running 7 in one row and Manage Loan 6; they technically fit, but
   every label then wrapped to two lines ("BLENDED MARGIN", "OVERDUE TO COLLECT",
   "COLLECTED · 2026-07") and the row read ragged. A KPI strip is meant to be
   scannable at a glance — past ~5 it stops being a glance.
   The cap is enforced by the column MINIMUM, not by counting: each track is at
   least one-fifth of the row, so auto-fit can never lay out a sixth. --kpi-cols
   is the knob — a screen with exactly 6 facts can set it to 3 for a balanced
   3+3 rather than a ragged 5+1. Below ~150px per card it drops to fewer
   columns and wraps, as before. */
.kpi-grid {
  --kpi-gap: 12px; --kpi-cols: 5; --kpi-min: 150px;
  display: grid; gap: var(--kpi-gap); margin-bottom: 16px;
  grid-template-columns: repeat(auto-fit, minmax(
    max(var(--kpi-min), (100% - (var(--kpi-cols) - 1) * var(--kpi-gap)) / var(--kpi-cols)), 1fr));
}
/* compact + slim are kept as aliases (same size as the base now) for back-compat. */
.kpi-grid.kpi-compact, .kpi-grid.kpi-slim { gap: var(--kpi-gap); margin-bottom: 16px; }
/* kpi-onerow: keep every KPI on ONE row (equal widths). It still honours the
   five-abreast cap above — a strip with more than five now wraps rather than
   shaving each card thinner, which is what made the labels wrap. */
.kpi-grid.kpi-onerow { grid-auto-flow: row; }
@media (max-width: 880px) { .kpi-grid.kpi-onerow { --kpi-cols: 2; } }
/* clickable slab-tier cards (commission) — filter the ledger on tap */
.grid-auto.kpi-compact { gap: 18px; }
.tier-card { cursor: pointer; text-align: left; width: 100%; background: var(--surface);
  transition: border-color var(--t-fast), box-shadow var(--t-fast), transform var(--t-fast); }
.tier-card:hover { border-color: var(--border-strong); transform: translateY(-1px); }
.tier-card.active { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.section-label.mt-0 { margin-top: 0; }
.kpi-card {
  display: flex; flex-direction: column;
  /* a whisper of accent light off the top-right (behind the jewel icon) over a
     faint top-lit surface gradient — the surface reads as lit, not painted. */
  background:
    radial-gradient(130% 90% at 90% -30%, color-mix(in srgb, var(--accent) 9%, transparent), transparent 55%),
    linear-gradient(180deg, color-mix(in srgb, var(--surface-hi) 30%, var(--surface)), var(--surface));
  border: 1px solid var(--border); border-radius: var(--r-lg);
  padding: 15px 16px; min-height: 118px; position: relative; overflow: hidden;   /* house rule: ~30% smaller, uniform everywhere */
  box-shadow: var(--shadow-card), inset 0 1px 0 var(--hairline);
  transition: transform var(--t) var(--e-out), box-shadow var(--t) var(--e-out), border-color var(--t);
}
/* a single fine luminous hairline along the top edge — the premium detail that
   replaces the old cheap corner "glow". */
.kpi-card::before {
  content:''; position: absolute; inset: 0 0 auto 0; height: 1px; opacity: .5;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--accent) 55%, transparent) 32%,
    color-mix(in srgb, var(--epal-soft, var(--accent)) 65%, transparent) 68%, transparent);
  transition: opacity var(--t);
}
.kpi-card:hover { transform: translateY(-3px); box-shadow: var(--shadow), inset 0 1px 0 var(--hairline); border-color: var(--border-strong); }
.kpi-card:hover::before { opacity: .95; }
.kpi-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
/* Same correction as the table headers (owner review 2026-07-15): 10.5px +
   uppercase + .09em tracking + --text-mute stacked four legibility taxes on the
   one element that has to TELL YOU WHAT THE NUMBER IS. 12px, tracking eased to
   .07em (wide tracking costs more width the bigger the type gets — this keeps
   the label's footprint about where it was), and --text-dim for contrast. */
.kpi-label { font-size: var(--fs-tiny); color: var(--text-dim); font-weight: 600; letter-spacing: .07em; text-transform: uppercase; }
/* Jewel chip: deep royal→abyss gradient with a light "ink" icon, an inset top
   highlight and a soft coloured cast — reads as enamel/metal, not a flat pastel. */
.kpi-ico {
  width: 42px; height: 42px; border-radius: 13px; display: grid; place-items: center;
  font-size: var(--fs-h3); color: #dbe4f8; flex: none;
  background: linear-gradient(155deg, var(--epal-accent, var(--accent)) 0%, var(--epal-deep, var(--accent)) 60%, var(--epal-navy, var(--accent)) 100%);
  border: 1px solid rgba(255,255,255,.14);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.30),
    inset 0 -10px 16px -10px rgba(0,0,0,.55),
    0 8px 18px -8px color-mix(in srgb, var(--epal-royal, var(--accent)) 70%, transparent);
}
/* The hero number: near-foreground (NEVER brand-coloured), semibold not black,
   tight optical tracking, tabular figures — reads as a considered financial value,
   its confidence from size + contrast + tracking rather than heavy weight. */
.kpi-value { font-size: var(--fs-h1); font-weight: 700; letter-spacing: -.03em; line-height: 1.02;
  color: var(--text); font-variant-numeric: tabular-nums; }
.kpi-foot { display: flex; align-items: center; gap: 8px; margin-top: 11px; font-size: var(--fs-tiny); }
.kpi-trend { display: inline-flex; align-items: center; gap: 3px; font-weight: 700; padding: 2px 7px; border-radius: 999px; }
.kpi-trend.up { color: var(--good); background: var(--good-soft); }
.kpi-trend.down { color: var(--bad); background: var(--bad-soft); }
.kpi-trend.flat { color: var(--text-dim); background: var(--surface-3); }
/* Trend sparkline lives in its OWN full-width band, bled to the card's bottom edge,
   pushed down by margin-top:auto. It NEVER crosses the number. The line is
   monochrome brand (see charts.js); semantics live only in the trend chip above. */
.kpi-spark { position: relative; height: 52px; margin: 16px -22px -22px; margin-top: auto; }
.kpi-spark::before { content:''; position: absolute; left: 0; right: 0; top: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--border) 14%, var(--border) 86%, transparent); }
.kpi-spark canvas { display: block; }

/* Share launcher (Gmail / WhatsApp / Copy) */
.share-to { font-size: var(--fs-small); color: var(--text-dim); margin-bottom: 14px; }
.share-chans { display: flex; gap: 12px; margin-bottom: 18px; }
.share-chan { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 9px; padding: 16px 10px;
  border: 1px solid var(--border); border-radius: var(--r-md); background: var(--surface-2); cursor: pointer;
  transition: border-color var(--t), transform var(--t), box-shadow var(--t); }
.share-chan:hover { border-color: var(--border-strong); transform: translateY(-2px); box-shadow: var(--shadow-sm); }
.share-chan-ico { width: 42px; height: 42px; border-radius: 13px; display: grid; place-items: center; font-size: 20px; }
.share-chan-lbl { font-size: var(--fs-small); font-weight: 600; color: var(--text); }
.share-preview { border: 1px solid var(--border); border-radius: var(--r-md); overflow: hidden; }
.share-preview-h { padding: 10px 14px; background: var(--surface-2); font-weight: 700; font-size: var(--fs-small); border-bottom: 1px solid var(--border); }
.share-preview-b { padding: 14px; margin: 0; font-family: var(--font-mono); font-size: var(--fs-tiny); color: var(--text-dim);
  white-space: pre-wrap; max-height: 220px; overflow: auto; }

/* Image / photo picker (form field) — preview tile + upload/remove controls */
.img-picker { display: flex; align-items: center; gap: 14px; }
.img-picker-preview { width: 72px; height: 72px; flex: none; border-radius: var(--r-md); overflow: hidden;
  background: var(--surface-2); border: 1px solid var(--border); display: grid; place-items: center; }
.img-picker-preview.round { border-radius: 50%; }
.img-picker-preview img { width: 100%; height: 100%; object-fit: cover; }
.img-picker-ph { color: var(--text-mute); font-size: 26px; display: grid; place-items: center; }
.img-picker-ctrls { display: flex; flex-wrap: wrap; gap: 6px; }

/* Row action buttons — the canonical set: view · edit · delete │ print · WhatsApp · Gmail.
   Deliberately CALM: small, low-contrast at rest (they recede), colour + surface
   only on hover. Always a single horizontal line, left-aligned in the cell. */
.row-actions { display: inline-flex; flex-wrap: nowrap; align-items: center; gap: 1px; white-space: nowrap; justify-content: flex-start; }
.row-act { width: 24px; height: 24px; display: inline-grid; place-items: center; border-radius: 6px; flex: none;
  color: var(--text-mute); opacity: .7; border: 1px solid transparent; background: transparent; cursor: pointer;
  transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast), opacity var(--t-fast); }
.row-act:hover { opacity: 1; background: var(--surface-2); color: var(--accent); border-color: var(--border); }
.row-act:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; opacity: 1; }
.row-act i { font-size: 12.5px; line-height: 1; }
.row-act-danger:hover { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 30%, transparent); }
/* faint divider between the record group (view/edit/delete) and the send group */
.row-act-sep { flex: none; width: 1px; height: 12px; margin: 0 3px; background: var(--border); align-self: center; opacity: .7; }

/* Compact KPI STRIP — the small stat tiles above the task board, forced into a
   single scrollable row. Scoped to [data-strip] so no other dashboard changes. */
.kpi-grid[data-strip] { display: flex; gap: 12px; overflow-x: auto; padding-bottom: 2px; margin-bottom: 16px; }
.kpi-grid[data-strip] .kpi-card { flex: 1 1 0; min-width: 146px; min-height: 0; padding: 12px 15px; }
.kpi-grid[data-strip] .kpi-top { margin-bottom: 8px; }
.kpi-grid[data-strip] .kpi-label { font-size: var(--fs-micro); letter-spacing: .05em; }
.kpi-grid[data-strip] .kpi-ico { width: 30px; height: 30px; border-radius: 9px; font-size: 14px; }
.kpi-grid[data-strip] .kpi-value { font-size: var(--fs-h3); }

/* Small stat rows (inside cards) ------------------------------------------
   How the hairlines are drawn: the CONTAINER is painted --border and the 1px
   grid gap lets it show through between cells. Elegant, but it has a failure
   mode — any grid AREA with no .stat in it is not empty, it is a lit --border
   box. With auto-fit that happens the moment the count doesn't divide evenly
   into however many columns the width happened to produce (3 stats in a narrow
   card → 2+1 → one blank filled cell, visible in both themes).
   Two defences, because auto-fit alone can't be reasoned about:
     · .stat-2 pins the column count so the layout is DETERMINISTIC, not a
       function of the container's width;
     · the orphan rule spans a lone trailing stat across the full row, so an
       odd count fills its row instead of leaving a hole. Note that pinning to
       2 columns is NOT sufficient on its own — 3 stats in 2 columns still
       leaves the 4th area lit; it's the span that actually closes it. */
.stat-row { display: grid; gap: 1px; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); background: var(--border); border-radius: var(--r-md); overflow: hidden; }
.stat-row.stat-2 { grid-template-columns: repeat(2, 1fr); }
.stat-row.stat-2 .stat:last-child:nth-child(odd) { grid-column: 1 / -1; }
@media (max-width: 520px) {                      /* phones: one clean column */
  .stat-row.stat-2 { grid-template-columns: 1fr; }
}
.stat { background: var(--surface); padding: 14px 16px; }
.stat-label { font-size: var(--fs-tiny); color: var(--text-mute); font-weight: 600; }
.stat-value { font-size: var(--fs-h3); font-weight: 700; margin-top: 4px; }
/* .stat-compact — refined, smaller stat values for dense detail views (e.g. the
   bank-account statement header): a premium, restrained fintech feel instead of
   the big --fs-h3 headline number. Scoped, so other stat rows are unaffected. */
.stat-row.stat-compact .stat { padding: 12px 15px; }
.stat-row.stat-compact .stat-value { font-size: var(--fs-lead); font-weight: 600; margin-top: 3px; letter-spacing: .2px; }
.stat-row.stat-compact .stat-label { font-size: var(--fs-micro); letter-spacing: .4px; text-transform: uppercase; }

/* ============================ BANK ACCOUNT CARD ==========================
 * World-class account card (Master Accounts › Manage Banks). Each card wears its
 * bank's identity hue (--bank-hue, set per-card in view.js) as a left accent
 * RAIL + a faint corner glow + a gradient chip; the bank name (display face) and
 * the balance (tabular mono) are the two heroes. Refined status pill, hairline
 * footer, and premium micro-interactions: hover lift with a brand-tinted shadow,
 * the rail grows, a soft light sweep crosses the surface. Everything else stays
 * monochrome so it reads expensive, never busy. */
.bank-card { --bank-hue: var(--accent);
  /* CMYK-safe, muted derivation of the bank's hue — desaturated toward a neutral
     ink so the rail / chip / glow read as a PRINT colour, not neon. */
  --bank-ink: color-mix(in srgb, var(--bank-hue) 64%, #7c828c);
  position: relative; padding: 0; overflow: hidden; border-radius: 16px;
  background: radial-gradient(135% 95% at 100% 0%, color-mix(in srgb, var(--bank-ink) 9%, transparent), transparent 56%), var(--surface);
  box-shadow: 0 1px 2px rgba(7, 12, 30, .06), 0 3px 10px -5px rgba(7, 12, 30, .10);
  transition: transform .28s cubic-bezier(.2, .7, .2, 1), box-shadow .28s cubic-bezier(.2, .7, .2, 1), border-color .2s; }
.bank-card:hover { transform: translateY(-5px); border-color: color-mix(in srgb, var(--bank-ink) 42%, var(--border));
  box-shadow: 0 24px 46px -22px color-mix(in srgb, var(--bank-ink) 46%, rgba(7, 12, 30, .55)), 0 8px 18px -10px rgba(7, 12, 30, .20); }
.bank-card.sel { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent), 0 24px 46px -22px rgba(7, 12, 30, .30); }
/* brand accent rail down the left edge — thickens on hover / select */
.bank-card::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; z-index: 2;
  background: linear-gradient(180deg, var(--bank-ink), color-mix(in srgb, var(--bank-ink) 45%, transparent));
  transition: width .28s cubic-bezier(.2, .7, .2, 1); }
.bank-card:hover::before, .bank-card.sel::before { width: 6px; }
/* moving glaze — a soft white light with a bright glint core that sweeps across
   on hover (brighter + wider than a plain sheen, so it clearly reads on white). */
.bank-card::after { content: ''; position: absolute; top: 0; left: -75%; width: 62%; height: 100%; z-index: 3; pointer-events: none;
  background: linear-gradient(105deg, transparent 12%, color-mix(in srgb, #fff 30%, transparent) 42%,
    color-mix(in srgb, #fff 55%, transparent) 50%, color-mix(in srgb, #fff 30%, transparent) 58%, transparent 88%);
  transform: skewX(-18deg); transition: left .7s ease; }
.bank-card:hover::after { left: 145%; }
.bank-card-top, .bank-card-hero, .bank-card-foot { position: relative; z-index: 1; }
.bank-card-top { display: flex; align-items: flex-start; gap: 12px; padding: 17px 18px 0 21px; }
.bank-card-ico { position: relative; width: 42px; height: 42px; border-radius: 13px; display: grid; place-items: center; flex: none;
  color: #fff; font-size: 18px; transition: transform .28s cubic-bezier(.2, .7, .2, 1);
  background: linear-gradient(145deg, color-mix(in srgb, var(--bank-ink) 84%, #fff), var(--bank-ink));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .34), 0 7px 15px -5px color-mix(in srgb, var(--bank-ink) 55%, transparent); }
.bank-card:hover .bank-card-ico { transform: translateY(-1px) scale(1.05); }
.bank-card-ico::after { content: ''; position: absolute; right: -3px; bottom: -3px; width: 12px; height: 12px; border-radius: 50%;
  border: 2.5px solid var(--surface); background: var(--text-mute); }
.bank-card-ico.is-active::after { background: var(--good); box-shadow: 0 0 0 3px color-mix(in srgb, var(--good) 22%, transparent); }
/* small company-identity badge on the chip — which sister concern owns this bank
   (Travels ✈ / IT cpu / Group hexagon / …), so each card is company-wise. */
.bank-card-coico { position: absolute; left: -5px; top: -5px; width: 18px; height: 18px; border-radius: 50%; z-index: 2;
  background: var(--surface); border: 1px solid var(--border); display: grid; place-items: center;
  font-size: 9.5px; line-height: 1; color: var(--text-dim); box-shadow: 0 1px 3px rgba(7, 12, 30, .18); }
.bank-card-id { flex: 1; min-width: 0; padding-top: 1px; }
.bank-card-name { font-family: var(--font-display); font-weight: 700; font-size: 15px; letter-spacing: -.2px; line-height: 1.25;
  color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bank-card-sub { font-size: var(--fs-micro); color: var(--text-mute); margin-top: 2px; font-weight: 500;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bank-card-status { flex: none; font-size: 10px; font-weight: 700; letter-spacing: .3px; padding: 4px 9px 4px 8px; border-radius: 999px;
  display: inline-flex; align-items: center; gap: 5px; border: 1px solid transparent; }
.bank-card-status::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor;
  box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 22%, transparent); }
.bank-card-status.is-active { color: var(--good); background: color-mix(in srgb, var(--good) 11%, transparent); border-color: color-mix(in srgb, var(--good) 24%, transparent); }
.bank-card-status.is-inactive { color: var(--text-mute); background: var(--surface-2); }
/* row actions float in as a frosted chip on hover / select — never reserve width */
.bank-card-actions { position: absolute; top: 14px; right: 14px; z-index: 4; display: flex; gap: 1px; flex: none;
  opacity: 0; transform: translateY(-4px); transition: opacity var(--t-fast), transform var(--t-fast);
  background: color-mix(in srgb, var(--surface) 85%, transparent); border: 1px solid var(--border); border-radius: 10px; backdrop-filter: blur(6px); }
.bank-card:hover .bank-card-actions, .bank-card.sel .bank-card-actions { opacity: 1; transform: none; }
@media (hover: none) { .bank-card-actions { opacity: 1; transform: none; } }
/* balance hero */
.bank-card-hero { padding: 15px 21px 15px; }
.bank-card-caprow { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.bank-card-caplabel { font-size: 9.5px; font-weight: 700; letter-spacing: .7px; text-transform: uppercase; color: var(--text-mute); }
/* net movement since opening — the accountant's at-a-glance trend */
.bank-card-delta { display: inline-flex; align-items: center; gap: 1px; flex: none; font-family: var(--font-mono);
  font-variant-numeric: tabular-nums; font-size: 11px; font-weight: 700; padding: 2px 8px 2px 5px; border-radius: 999px; }
.bank-card-delta.is-up { color: var(--good); background: color-mix(in srgb, var(--good) 13%, transparent); }
.bank-card-delta.is-down { color: var(--bad, #e0356e); background: color-mix(in srgb, var(--bad, #e0356e) 13%, transparent); }
.bank-card-delta.is-flat { color: var(--text-mute); background: var(--surface-2); }
.bank-card-bal { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 27px; font-weight: 700;
  line-height: 1.1; letter-spacing: -.8px; color: var(--text); margin-top: 5px; }
.bank-card-bal.text-bad { color: var(--bad, #e0356e); }
.bank-card-acct { font-size: var(--fs-micro); color: var(--text-mute); margin-top: 8px; font-family: var(--font-mono); letter-spacing: .3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* hairline footer */
.bank-card-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 11px 21px 12px;
  border-top: 1px solid color-mix(in srgb, var(--border) 85%, transparent);
  background: color-mix(in srgb, var(--surface-2) 45%, transparent); }
.bank-card-metric { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.bank-card-metric.right { align-items: flex-end; }
.bank-card-metric .k { font-size: 9px; text-transform: uppercase; letter-spacing: .5px; color: var(--text-mute); font-weight: 700; }
.bank-card-metric .v { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 12.5px; font-weight: 600;
  color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
@media (prefers-reduced-motion: reduce) {
  .bank-card, .bank-card::before, .bank-card::after, .bank-card-ico { transition: none; }
  .bank-card:hover { transform: none; } .bank-card:hover::after { left: -75%; } }

/* --------------------------- BANK SUMMARY (identity panel) -----------------
 * Replaces the row of four KPI tiles on Manage Banks with ONE company-branded
 * banking-summary panel (owner 2026-07-22): company identity + hero balance +
 * accounts / active / last-transaction facts. Same premium vocabulary as
 * .bank-card (company-hue rail, gradient icon chip, a soft glaze that sweeps on
 * hover) so the desk reads expensive and consistent. Deliberately sits at the
 * LEFT (max-width) — the right gutter is reserved for planned future content.
 * --bank-hue is set per-render in JS via style.setProperty (custom props can't
 * be set through el()'s style object). */
.bank-summary { --bank-hue: var(--accent); --bank-ink: color-mix(in srgb, var(--bank-hue) 64%, #7c828c);
  position: relative; overflow: hidden; border-radius: 16px; max-width: 620px; margin-bottom: 14px; border: 1px solid var(--border);
  background: radial-gradient(130% 100% at 100% 0%, color-mix(in srgb, var(--bank-ink) 10%, transparent), transparent 58%), var(--surface);
  box-shadow: 0 1px 2px rgba(7, 12, 30, .06), 0 6px 18px -9px rgba(7, 12, 30, .12);
  transition: transform .28s cubic-bezier(.2, .7, .2, 1), box-shadow .28s cubic-bezier(.2, .7, .2, 1), border-color .2s; }
.bank-summary:hover { transform: translateY(-3px); border-color: color-mix(in srgb, var(--bank-ink) 40%, var(--border));
  box-shadow: 0 22px 42px -22px color-mix(in srgb, var(--bank-ink) 44%, rgba(7, 12, 30, .55)), 0 8px 18px -10px rgba(7, 12, 30, .18); }
.bank-summary::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 5px; z-index: 2;
  background: linear-gradient(180deg, var(--bank-ink), color-mix(in srgb, var(--bank-ink) 45%, transparent)); }
.bank-summary::after { content: ''; position: absolute; top: 0; left: -75%; width: 60%; height: 100%; z-index: 3; pointer-events: none;
  background: linear-gradient(105deg, transparent 12%, color-mix(in srgb, #fff 26%, transparent) 42%,
    color-mix(in srgb, #fff 50%, transparent) 50%, color-mix(in srgb, #fff 26%, transparent) 58%, transparent 88%);
  transform: skewX(-18deg); transition: left .7s ease; }
.bank-summary:hover::after { left: 150%; }
.bank-summary-in { position: relative; z-index: 1; padding: 18px 22px 17px 24px; }
.bank-summary-head { display: flex; align-items: center; gap: 13px; }
.bank-summary-ico { width: 44px; height: 44px; border-radius: 13px; display: grid; place-items: center; flex: none; color: #fff; font-size: 19px;
  background: linear-gradient(145deg, color-mix(in srgb, var(--bank-ink) 84%, #fff), var(--bank-ink));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .34), 0 7px 15px -5px color-mix(in srgb, var(--bank-ink) 55%, transparent); }
.bank-summary-id { flex: 1; min-width: 0; }
.bank-summary-co { font-family: var(--font-display); font-weight: 700; font-size: 17px; letter-spacing: -.3px; line-height: 1.2; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bank-summary-sub { font-size: var(--fs-micro); color: var(--text-mute); margin-top: 2px; font-weight: 500; }
.bank-summary-hero { margin: 15px 0 2px; }
.bank-summary-bal { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 32px; font-weight: 700; line-height: 1.05; letter-spacing: -1px; color: var(--text); }
.bank-summary-bal.text-bad { color: var(--bad, #e0356e); }
.bank-summary-ballabel { font-size: 9.5px; font-weight: 700; letter-spacing: .7px; text-transform: uppercase; color: var(--text-mute); margin-top: 5px; }
/* 3-KPI row — the dividers are soft black "shadow-like" hairlines (owner
   2026-07-22: the red guide lines become black shadows), not flat borders. */
.bank-summary-facts { display: flex; margin-top: 13px; padding-top: 12px;
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--text) 7%, transparent), inset 0 3px 4px -3px color-mix(in srgb, var(--text) 14%, transparent); }
.bank-summary-fact { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; padding: 3px 10px; position: relative; border-radius: 9px; transition: background .15s; }
.bank-summary-fact:first-child { padding-left: 2px; }
.bank-summary-fact + .bank-summary-fact::before { content: ''; position: absolute; left: 0; top: 14%; bottom: 14%; width: 1px;
  background: color-mix(in srgb, var(--text) 10%, transparent); box-shadow: 1px 0 0 color-mix(in srgb, #fff 55%, transparent); }
.bank-summary-fact .k { font-size: 8.5px; text-transform: uppercase; letter-spacing: .2px; color: var(--text-mute); font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* ~30% larger count than before (was 14px) — owner ask */
.bank-summary-fact .v { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 18.5px; font-weight: 700; line-height: 1; color: var(--text); }
.bank-summary-fact.clik { cursor: pointer; }
.bank-summary-fact.clik:hover { background: color-mix(in srgb, var(--bank-ink) 9%, transparent); }
.bank-summary-fact.clik:hover .v { color: color-mix(in srgb, var(--bank-ink) 72%, var(--text)); }

/* LAST TRANSACTION mini-statement — id · amount+date · opening → closing.
   Clickable (opens the transaction). Same soft-shadow divider above it. */
/* Last transaction is now the RIGHT COLUMN of the card (owner 2026-07-22), a
   soft-shadow vertical hairline dividing it from the identity/balance column. */
.bank-summary-body { display: flex; align-items: stretch; }
.bank-summary-left { flex: 1; min-width: 0; padding-right: 18px; }
.bank-summary-last { flex: 1; min-width: 0; position: relative; cursor: pointer; border-radius: 10px; padding: 1px 4px 2px 18px; transition: background .15s; }
.bank-summary-last::before { content: ''; position: absolute; left: 0; top: 4%; bottom: 4%; width: 1px;
  background: color-mix(in srgb, var(--text) 10%, transparent); box-shadow: 1px 0 0 color-mix(in srgb, #fff 55%, transparent); }
.bank-summary-last:hover { background: color-mix(in srgb, var(--bank-ink) 8%, transparent); }
.bank-summary-last.is-empty { cursor: default; }
.bank-summary-dir.none { color: var(--text-mute); background: color-mix(in srgb, var(--text) 8%, transparent); }
.bank-summary-last-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.bank-summary-last-lbl { font-size: 9px; text-transform: uppercase; letter-spacing: .5px; color: var(--text-mute); font-weight: 700; }
.bank-summary-dir { font-size: 9.5px; font-weight: 800; letter-spacing: .4px; padding: 2px 8px; border-radius: 999px; }
.bank-summary-dir.in { color: var(--good); background: color-mix(in srgb, var(--good) 14%, transparent); }
.bank-summary-dir.out { color: var(--bad, #e0356e); background: color-mix(in srgb, var(--bad, #e0356e) 14%, transparent); }
.bank-summary-last-row { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-top: 5px; }
.bank-summary-last-amt { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 18px; font-weight: 700; color: var(--text); }
.bank-summary-last-amt.in { color: var(--good); } .bank-summary-last-amt.out { color: var(--bad, #e0356e); }
.bank-summary-last-date { font-size: 11px; color: var(--text-mute); font-weight: 600; white-space: nowrap; }
.bank-summary-last-ref { font-family: var(--font-mono); font-size: 10.5px; color: var(--text-dim); margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* the transaction id reads as a clickable mono chip (owner 2026-07-22) */
.txn-id-chip { font-family: var(--font-mono); font-size: 9.5px; font-weight: 700; letter-spacing: .2px; color: var(--bank-ink, var(--accent));
  background: color-mix(in srgb, var(--bank-ink, var(--accent)) 11%, transparent); border: 1px solid color-mix(in srgb, var(--bank-ink, var(--accent)) 22%, transparent);
  padding: 1px 6px; border-radius: 6px; margin-right: 3px; }
.bank-summary-last:hover .txn-id-chip { background: color-mix(in srgb, var(--bank-ink, var(--accent)) 18%, transparent); }
/* Opening / Closing on their OWN lines (owner 2026-07-22); Opening in a CMYK-
   muted blue, Closing muted-green when the balance went up / muted-red when down
   (never neon — mixed toward a neutral ink). */
.bank-summary-last-oc { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 11px; margin-top: 5px; line-height: 1.55; }
.bank-summary-last-oc .oc-open, .bank-summary-last-oc .oc-close { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.oc-open { color: color-mix(in srgb, var(--accent) 55%, #737b88); }
.oc-open b { color: color-mix(in srgb, var(--accent) 66%, #565f6c); font-weight: 700; }
.oc-close.up { color: color-mix(in srgb, var(--good) 56%, #737b88); }
.oc-close.up b { color: color-mix(in srgb, var(--good) 70%, #46515b); font-weight: 700; }
.oc-close.down { color: color-mix(in srgb, var(--bad, #e0356e) 56%, #737b88); }
.oc-close.down b { color: color-mix(in srgb, var(--bad, #e0356e) 70%, #46515b); font-weight: 700; }
.bank-summary-empty { margin-top: 14px; padding-top: 13px; font-size: 11.5px; color: var(--text-mute);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--text) 7%, transparent); }
@media (prefers-reduced-motion: reduce) { .bank-summary, .bank-summary::after { transition: none; } .bank-summary:hover { transform: none; } .bank-summary:hover::after { left: -75%; } }

/* --------------------- BANK SUMMARY ROW + CASH-FLOW COMPANION --------------
 * The summary panel + a companion cash-flow card sit in one flexing row; the
 * panel keeps its fixed left width, the companion fills the rest and matches
 * height. A 30-day mirrored in/out sparkline (green up = money in, red down =
 * money out) with In/Out totals + a net chip. */
.bank-summary-row { display: flex; gap: 14px; flex-wrap: wrap; align-items: stretch; margin-bottom: 14px; }
.bank-summary-row .bank-summary { margin-bottom: 0; flex: 0 0 auto; width: 100%; max-width: 620px; }
.bank-flow { flex: 1; min-width: 300px; position: relative; overflow: hidden; border-radius: 16px; border: 1px solid var(--border); background: var(--surface); cursor: pointer;
  box-shadow: 0 1px 2px rgba(7, 12, 30, .06), 0 6px 18px -9px rgba(7, 12, 30, .12); padding: 18px 20px; display: flex; flex-direction: column;
  transition: transform .2s cubic-bezier(.2, .7, .2, 1), box-shadow .2s, border-color .2s; }
.bank-flow:hover { transform: translateY(-2px); border-color: color-mix(in srgb, var(--accent) 32%, var(--border));
  box-shadow: 0 18px 36px -20px rgba(7, 12, 30, .34), 0 6px 14px -8px rgba(7, 12, 30, .16); }
.bank-flow-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.bank-flow-title { font-family: var(--font-display); font-weight: 700; font-size: 14px; color: var(--text); letter-spacing: -.2px; }
.bank-flow-sub { font-size: var(--fs-micro); color: var(--text-mute); margin-top: 2px; }
.bank-flow-net { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 13px; font-weight: 700; padding: 3px 9px; border-radius: 999px; white-space: nowrap; }
.bank-flow-net.is-up { color: var(--good); background: color-mix(in srgb, var(--good) 13%, transparent); }
.bank-flow-net.is-down { color: var(--bad, #e0356e); background: color-mix(in srgb, var(--bad, #e0356e) 13%, transparent); }
.bank-flow-spark { flex: 1; display: flex; align-items: center; margin: 16px 0 12px; min-height: 52px; color: var(--text); }
.bank-flow-spark svg { width: 100%; height: 52px; display: block; }
.bank-flow-foot { display: flex; gap: 20px; font-size: 11px; color: var(--text-dim); font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.bank-flow-dot { display: inline-block; width: 8px; height: 8px; border-radius: 2px; margin-right: 5px; vertical-align: -1px; }
.bank-flow-dot.in { background: #23c17e; } .bank-flow-dot.out { background: #f0506e; }
.bank-flow-empty { flex: 1; display: grid; place-items: center; color: var(--text-mute); font-size: 12px; text-align: center; }

/* ---- INDIVIDUAL-COMPANY DASHBOARD ROW (owner 2026-07-22) -----------------
 * One same-height row of cards: Main KPI · Cash Flow · Reconciliation · a right
 * column stacking the company balance + Hard Cash. Wraps on narrow screens.
 * Every card / number is clickable to its origin (accounts list / ledger). */
/* All four cards ride ONE line at ~80–100% zoom (owner 2026-07-22): they shrink
   to fit (min-width:0, browser zoom scales the text); only past ~100% zoom, when
   the viewport is narrower, do they wrap to another row. */
.bank-cards-row { display: flex; gap: 12px; flex-wrap: wrap; align-items: stretch; margin-bottom: 14px; }
@media (min-width: 1180px) { .bank-cards-row { flex-wrap: nowrap; } }
.bank-cards-row .bank-summary { flex: 3 1 340px; min-width: 0; max-width: none; margin-bottom: 0; }
.bank-cards-row .bank-flow { flex: 1 1 190px; min-width: 0; }
.bank-cards-row .bank-recon { flex: 1.2 1 220px; min-width: 0; }
.bank-cards-row .bank-ministack { flex: .8 1 160px; }

/* PIXEL-FIT (owner 2026-07-22): compact every element so the 4 cards fit their
   content tightly and read as one equal-height set; the KPI row pins to the
   bottom so the main card fills its height with no dead space. Browser zoom
   scales it all, so the ratio holds at 80/90/100%. */
.bank-cards-row .bank-summary-in { display: flex; flex-direction: column; justify-content: space-between; padding: 11px 15px 10px 17px; }
.bank-cards-row .bank-summary-head { gap: 9px; }
.bank-cards-row .bank-summary-ico { width: 34px; height: 34px; font-size: 15px; border-radius: 10px; }
.bank-cards-row .bank-summary-co { font-size: 14px; }
.bank-cards-row .bank-summary-sub { font-size: 9px; }
.bank-cards-row .bank-summary-hero { margin: 6px 0 0; }
.bank-cards-row .bank-summary-bal { font-size: 21px; }
.bank-cards-row .bank-summary-ballabel { font-size: 8px; margin-top: 2px; }
.bank-cards-row .bank-summary-last { padding-left: 13px; }
.bank-cards-row .bank-summary-last-amt { font-size: 14px; }
.bank-cards-row .bank-summary-last-row { margin-top: 4px; }
.bank-cards-row .bank-summary-last-ref, .bank-cards-row .bank-summary-last-oc { font-size: 9.5px; }
.bank-cards-row .bank-summary-last-ref { margin-top: 2px; }
.bank-cards-row .bank-summary-last-oc { margin-top: 3px; line-height: 1.45; }
.bank-cards-row .bank-summary-facts { margin-top: 8px; padding-top: 7px; }
.bank-cards-row .bank-summary-fact .v { font-size: 15px; }
.bank-cards-row .bank-summary-fact .k { font-size: 8px; }
.bank-cards-row .bank-flow { padding: 15px 15px 13px; }
.bank-cards-row .bank-flow-head { flex-wrap: wrap; gap: 4px 6px; }
.bank-cards-row .bank-flow-title { font-size: 13px; white-space: nowrap; }
.bank-cards-row .bank-flow-sub { font-size: 9px; }
.bank-cards-row .bank-flow-net { font-size: 11px; padding: 2px 7px; }
.bank-cards-row .bank-flow-spark { margin: 9px 0 8px; }
.bank-cards-row .bank-flow-foot { font-size: 10px; gap: 12px; }
.bank-cards-row .bank-recon .card-head { padding: 13px 14px 0; }
.bank-cards-row .bank-recon .card-head h3 { font-size: 11.5px; }
.bank-cards-row .bank-recon .card-body { padding: 11px 14px 13px; }
.bank-cards-row .bank-recon .stat-row { gap: 8px; }
.bank-cards-row .bank-recon .stat-value { font-size: 13.5px; }
.bank-cards-row .bank-recon .stat-label { font-size: 8.5px; }
.bank-cards-row .bank-mini { padding: 10px 13px; }

/* READABLE CAPTIONS IN THE ROW (owner 2026-07-29, arrows on "Payroll position ·
   July 2026", "last 0 months · paid vs still owed", "Sheet says owed"): "these
   are very less visible. make more black, and increase 20% size".
   The PIXEL-FIT block above had squeezed every caption to 8–9.5px — under the
   11px floor tokens.css itself calls "never go under" — and left them on
   --text-mute, the faintest text token. Each one below is ~20% larger and moves
   one step darker to --text-dim (which in the dark theme is one step LIGHTER —
   the token pair is contrast, not colour, so both themes gain the same
   visibility). Only the LABELS change; every figure keeps its size, so the four
   cards still ride one line at 90–100% zoom. */
.bank-cards-row .bank-summary-sub { font-size: 11px; }
.bank-cards-row .bank-summary-ballabel { font-size: 9.5px; }
.bank-cards-row .bank-summary-fact .k { font-size: 9.5px; }
.bank-cards-row .bank-summary-last-ref,
.bank-cards-row .bank-summary-last-oc { font-size: 11.5px; }
.bank-cards-row .bank-flow-sub { font-size: 11px; }
.bank-cards-row .bank-flow-foot { font-size: 12px; }
.bank-cards-row .bank-recon .card-head h3 { font-size: 13px; }
/* the bigger label WRAPS instead of ellipsing: "Salary payable (2100)" losing
   its account code to a "…" would have traded one legibility problem for another */
.bank-cards-row .bank-recon .stat-label,
.bank-cards-row .bank-recon-2x2 .stat-label { font-size: 10px; white-space: normal; line-height: 1.25; }
.bank-cards-row .bank-mini .xs { font-size: 12.5px; }
.bank-cards-row .bank-summary-sub,
.bank-cards-row .bank-summary-ballabel,
.bank-cards-row .bank-summary-fact .k,
.bank-cards-row .bank-summary-last-lbl,
.bank-cards-row .bank-summary-last-ref,
.bank-cards-row .bank-summary-last-oc,
.bank-cards-row .bank-flow-sub,
.bank-cards-row .bank-flow-foot,
.bank-cards-row .bank-recon .stat-label,
.bank-cards-row .bank-mini .text-mute { color: var(--text-dim); }

/* ── THE LAST-EVENT PANEL, TIDIED (owner 2026-07-29: "these text looks kind of
   messy, can you tidy them, without deleting any single one? reducing size,
   space whatever needed, but need to be visible") ─────────────────────────────
   On Master Payroll the panel showed "-৳ 12,861" wrapped under the OUT pill,
   "PAY-2026-07 Salary…" cut off, and "Owed staff ৳ 149,1…" losing its last two
   digits. Three separate causes, one symptom:

   1 · the money figure could BREAK MID-NUMBER, because only the date beside it
       was nowrap. base.css already states the rule — a money value must never
       fracture across lines — this panel simply never got it.
   2 · the ref and the opening/closing lines were `white-space: nowrap` +
       ellipsis, so in a half-width column they silently ATE their own content.
       An ellipsised balance is worse than a small one: "৳ 149,1…" is not a
       number, it is a rumour.
   3 · the READABLE CAPTIONS pass above lifted both lines to 11.5px, which is
       what pushed them past the edge in the narrowest column on the screen.

   So: figures never break, nothing ellipses (long text WRAPS and the panel grows
   by a line instead of hiding a digit), and the two lines come back to 11px —
   the floor tokens.css calls "never go under", so still the readable size the
   owner asked for, a half-step down to buy the room that makes it fit. Nothing
   is removed; everything is on screen. */
.bank-cards-row .bank-summary-last-amt { white-space: nowrap; }
/* if the amount and its date cannot share a line, the DATE drops whole to the
   next one — the figure never yields */
.bank-cards-row .bank-summary-last-row { flex-wrap: wrap; row-gap: 1px; gap: 8px; }
.bank-cards-row .bank-summary-last-ref,
.bank-cards-row .bank-summary-last-oc .oc-open,
.bank-cards-row .bank-summary-last-oc .oc-close {
  white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: anywhere;
}
.bank-cards-row .bank-summary-last-ref,
.bank-cards-row .bank-summary-last-oc { font-size: 11px; line-height: 1.35; }
.bank-cards-row .bank-summary-last-ref { margin-top: 3px; }
.bank-cards-row .bank-summary-last-oc { margin-top: 4px; }
/* the reference chip and every bold figure stay atomic while their line wraps */
.bank-cards-row .bank-summary-last-ref .txn-id-chip,
.bank-cards-row .bank-summary-last-oc b { white-space: nowrap; }
/* GIVE THE COLUMN THE WIDTH ITS CONTENT NEEDS. The two halves were flex:1 each —
   a straight 50/50 — but they never held equal amounts: the left is an icon, a
   name and one big figure, while the right is five lines including a reference
   and a memo. Wrapping was the symptom; a column too narrow for its job was the
   cause, and no amount of font-shaving fixes that. 42/58 lets the label, the
   amount and both balances sit on one line each, and brings the reference down
   to about two. 46/54 is the balance point: pushed further (42/58) the RIGHT
   column tidies but the left starts breaking "Payroll position · July 2026" over
   three lines, which just moves the mess across the divider. */
.bank-cards-row .bank-summary-left { flex: 0 1 46%; padding-right: 13px; }
.bank-cards-row .bank-summary-last { flex: 1 1 54%; padding-left: 11px; }
/* "LAST PAYROLL EVENT" is a heading, not prose — it holds one line */
.bank-cards-row .bank-summary-last-lbl { white-space: nowrap; letter-spacing: .3px; }

/* …and the fact keys under the divider stop truncating: "PAYROLL MON…" was
   eating its own word. They wrap instead — two short words on two lines beats
   one word with its ending cut off. */
.bank-cards-row .bank-summary-fact .k { white-space: normal; line-height: 1.2; }

.bank-summary-hero.clik { cursor: pointer; border-radius: 9px; transition: color .15s; }
.bank-summary-hero.clik:hover .bank-summary-bal { color: color-mix(in srgb, var(--bank-ink) 74%, var(--text)); }
.bank-recon-clik { cursor: pointer; transition: transform .18s cubic-bezier(.2,.7,.2,1), box-shadow .18s, border-color .18s; }
.bank-recon-clik:hover { transform: translateY(-2px); border-color: color-mix(in srgb, var(--accent) 30%, var(--border)); box-shadow: 0 14px 30px -18px rgba(7, 12, 30, .34); }
/* compact reconciliation inside the row: the 3 stats stack vertically (label
   above, value full-width so big numbers never clip); the long note hides. */
.bank-recon .card-head { flex-wrap: wrap; gap: 4px; }
.bank-recon .card-head h3 { font-size: 12.5px; line-height: 1.25; }
.bank-recon .card-head .badge { display: none; }   /* float already shown in the stat below — avoid overlap */
/* compact reconciliation = 2×2 grid of numbers split by a CROSS shadow divider
   (a vertical hairline between the columns + a horizontal one between the rows,
   meeting at the centre) — owner 2026-07-22. */
.bank-recon-2x2 { display: grid; grid-template-columns: 1fr 1fr; }
.bank-recon-2x2 .stat { position: relative; min-width: 0; display: flex; flex-direction: column; gap: 3px; padding: 8px 9px; }
.bank-recon-2x2 .stat:nth-child(odd) { padding-left: 2px; }
.bank-recon-2x2 .stat:nth-child(even)::before { content: ''; position: absolute; left: 0; top: 12%; bottom: 12%; width: 1px;
  background: color-mix(in srgb, var(--text) 10%, transparent); box-shadow: 1px 0 0 color-mix(in srgb, #fff 55%, transparent); }
.bank-recon-2x2 .stat:nth-child(n+3)::after { content: ''; position: absolute; top: 0; left: 5%; right: 5%; height: 1px;
  background: color-mix(in srgb, var(--text) 10%, transparent); box-shadow: 0 1px 0 color-mix(in srgb, #fff 55%, transparent); }
.bank-recon-2x2 .stat-label { font-size: 8px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bank-recon-2x2 .stat-value { font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bank-recon .card-body > p { display: none; }
.bank-recon .card-body { padding-top: 6px; }
/* a subtle 'why?' link on the float — opens the exact float-causing entries */
.float-why { display: inline-flex; align-items: center; gap: 3px; margin-top: 4px; padding: 0; background: none; border: none; cursor: pointer;
  font-size: 10px; font-weight: 700; color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
.float-why:hover { color: color-mix(in srgb, var(--accent) 75%, var(--text)); }
.bank-ministack { display: flex; flex-direction: column; gap: 14px; flex: 1 1 180px; min-width: 168px; }
.bank-mini { padding: 12px 15px; cursor: pointer; border-radius: 14px; border: 1px solid var(--border); background: var(--surface);
  box-shadow: 0 1px 2px rgba(7, 12, 30, .06); display: flex; flex-direction: column; justify-content: center; gap: 3px; flex: 1;
  transition: transform .18s cubic-bezier(.2,.7,.2,1), box-shadow .18s, border-color .18s; }
.bank-mini:hover { transform: translateY(-2px); border-color: color-mix(in srgb, var(--accent) 30%, var(--border)); box-shadow: 0 12px 26px -16px rgba(7, 12, 30, .32); }

/* Accounts grid (the individual bank cards) — owner 2026-07-22: 4 cards per row
   at 90–100% zoom, 5 at 80% (lower zoom = wider CSS viewport = one more column).
   auto-fit + a ~250px track makes the column count fall out of the width, so it
   holds the same ratio as the browser zooms. */
/* ACCOUNTS as a vertical side-label; only a sliver of gap above the cards */
.bank-accts-wrap { display: flex; align-items: stretch; gap: 8px; margin-top: 2px; }
.bank-accts-vlabel { flex: none; writing-mode: vertical-rl; transform: rotate(180deg); text-align: center;
  font-size: 10px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase; color: var(--text-mute);
  padding: 2px 1px; align-self: center; }
.bank-accts-host { flex: 1; min-width: 0; }
.bank-acct-grid { grid-template-columns: repeat(auto-fill, minmax(218px, 1fr)); gap: 16px; }
.bank-acct-grid .bank-card { max-width: 340px; }   /* a lone card must not balloon to full width (would blow up the cqw scale) */
/* PROPORTIONAL SCALING (owner 2026-07-22): each account card is a query
   container and every dimension is expressed in cqw (% of the card's OWN
   width), so width, height, spacing AND text all scale in one ratio. A narrower
   card (5-per-row) is a smaller copy of a wider one (4-per-row) — same look,
   just demoted/promoted in size. Calibrated to a ~250px base. */
.bank-acct-grid .bank-card { container-type: inline-size; min-width: 0; overflow: hidden; }
/* text reduced ~35% (owner 2026-07-22) — all in cqw so it stays proportional as
   the card scales; padding/icon trimmed to keep the card balanced, not sparse. */
/* text ~1.8× larger (owner 2026-07-22 — the 35% cut was too small to read);
   card WIDTH is grid-set and unchanged, padding trimmed a little so it doesn't
   balloon. Still cqw, so it stays proportional as the card scales. */
.bank-acct-grid .bank-card-top { padding: 5.2cqw 5.6cqw 0 6.4cqw; gap: 3.4cqw; }
.bank-acct-grid .bank-card-ico { width: 14cqw; height: 14cqw; font-size: 6.4cqw; border-radius: 4.2cqw; }
.bank-acct-grid .bank-card-ico::after { width: 4cqw; height: 4cqw; right: -1cqw; bottom: -1cqw; border-width: .9cqw; }
.bank-acct-grid .bank-card-coico { width: 6.4cqw; height: 6.4cqw; font-size: 3.2cqw; left: -1.7cqw; top: -1.7cqw; }
.bank-acct-grid .bank-card-name { font-size: 5.6cqw; }
.bank-acct-grid .bank-card-sub { font-size: 3.8cqw; margin-top: .6cqw; }
.bank-acct-grid .bank-card-status { font-size: 3.5cqw; padding: 1.2cqw 2.6cqw 1.2cqw 2.2cqw; gap: 1.4cqw; }
.bank-acct-grid .bank-card-status::before { width: 2.4cqw; height: 2.4cqw; }
.bank-acct-grid .bank-card-hero { padding: 4.4cqw 6.4cqw; }
.bank-acct-grid .bank-card-caplabel { font-size: 3.6cqw; }
.bank-acct-grid .bank-card-delta { font-size: 4.2cqw; padding: .6cqw 2.2cqw .6cqw 1.4cqw; }
.bank-acct-grid .bank-card-bal { font-size: 10cqw; margin-top: 1.4cqw; }
.bank-acct-grid .bank-card-acct { font-size: 3.8cqw; margin-top: 2.2cqw; }
.bank-acct-grid .bank-card-foot { padding: 3.6cqw 6.4cqw 4cqw; gap: 3.4cqw; }
.bank-acct-grid .bank-card-metric { gap: .8cqw; }
.bank-acct-grid .bank-card-metric .k { font-size: 3.4cqw; letter-spacing: .1cqw; }
.bank-acct-grid .bank-card-metric .v { font-size: 4.7cqw; }

/* --------------------- CATEGORISED EXPENSE ENTRY (Travels) ----------------
 * The guided expense capture: category cards (each pins a CoA head) → dependent
 * sub-category chips → details → a live journal preview. Premium, calm, branded
 * per category tone. */
.tv-exp-cats { display: grid; grid-template-columns: repeat(auto-fill, minmax(148px, 1fr)); gap: 10px; margin-bottom: 4px; }
.tv-exp-cat { --exp-tone: var(--accent); display: flex; flex-direction: column; align-items: flex-start; gap: 7px; text-align: left; position: relative;
  padding: 12px 13px; border-radius: 13px; border: 1px solid var(--border); background: var(--surface); cursor: pointer;
  transition: transform .16s cubic-bezier(.2, .7, .2, 1), box-shadow .16s, border-color .16s, background .16s; }
.tv-exp-cat:hover { transform: translateY(-2px); border-color: color-mix(in srgb, var(--exp-tone) 45%, var(--border));
  box-shadow: 0 12px 26px -16px color-mix(in srgb, var(--exp-tone) 42%, rgba(7, 12, 30, .4)); }
.tv-exp-cat.sel { border-color: var(--exp-tone); background: color-mix(in srgb, var(--exp-tone) 8%, var(--surface));
  box-shadow: 0 0 0 1px var(--exp-tone), 0 14px 30px -18px color-mix(in srgb, var(--exp-tone) 55%, transparent); }
.tv-exp-cat-ico { width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center; color: #fff; font-size: 16px;
  background: linear-gradient(145deg, color-mix(in srgb, var(--exp-tone) 82%, #fff), var(--exp-tone)); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .3); }
.tv-exp-cat-name { font-weight: 700; font-size: 12.5px; line-height: 1.2; color: var(--text); }
.tv-exp-cat-head { position: absolute; top: 10px; right: 11px; font-family: var(--font-mono); font-size: 9px; font-weight: 700; color: var(--text-mute);
  background: var(--surface-2); padding: 1px 5px; border-radius: 5px; }
.tv-exp-subhost { margin-top: 4px; }
.tv-exp-subs { display: flex; flex-wrap: wrap; gap: 7px; }
.tv-exp-sub { display: inline-flex; align-items: center; gap: 5px; padding: 6px 11px; border-radius: 999px; border: 1px solid var(--border);
  background: var(--surface); cursor: pointer; font-size: 12px; font-weight: 600; color: var(--text-dim); transition: background .14s, border-color .14s, color .14s; }
.tv-exp-sub:hover { border-color: color-mix(in srgb, var(--accent) 40%, var(--border)); }
.tv-exp-sub.sel { background: color-mix(in srgb, var(--accent) 13%, transparent); border-color: var(--accent); color: var(--text); }
.tv-exp-shared { font-size: 8.5px; font-weight: 800; letter-spacing: .3px; text-transform: uppercase; color: var(--warn, #d98324);
  background: color-mix(in srgb, var(--warn, #d98324) 15%, transparent); padding: 1px 5px; border-radius: 5px; }
.tv-exp-note { margin-top: 8px; font-size: 12px; color: var(--text-mute); background: color-mix(in srgb, var(--accent) 6%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 18%, transparent); border-radius: 9px; padding: 8px 11px; }
.tv-exp-live { margin-top: 12px; border: 1px dashed var(--border); border-radius: 11px; padding: 11px 13px; background: var(--surface-2); }
.tv-exp-live-t { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: var(--text-mute); margin-bottom: 7px; }
.tv-exp-live-l { display: flex; justify-content: space-between; gap: 12px; font-family: var(--font-mono); font-size: 12.5px; color: var(--text-dim); padding: 2px 0; }
.tv-exp-live-l .num { font-weight: 700; color: var(--text); }
/* Shared-cost split modal (Master Accounts → Operational Expenses → Shared Cost) */
.ma-shr-live { display: flex; flex-direction: column; gap: 8px; }
.ma-shr-row { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.ma-shr-jl { border-top: 1px solid var(--border); padding-top: 9px; margin-top: 2px; }
.ma-shr-jl .num { font-weight: 700; color: var(--text); }

/* ---------------------------- SEARCHABLE COMBOBOX ------------------------
 * The type-to-filter select (forms.js makeCombobox). Reads as a normal input; a
 * floating panel lists options and floats matches to the TOP as you type. */
.combo { position: relative; }
.combo-input { width: 100%; padding-right: 32px; cursor: text; }
.combo-caret { position: absolute; right: 11px; top: 50%; transform: translateY(-50%); color: var(--text-mute); font-size: 12px; cursor: pointer; }
.combo-panel { position: absolute; z-index: 60; left: 0; right: 0; top: calc(100% + 5px); max-height: 264px; overflow-y: auto;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md);
  box-shadow: 0 16px 38px -12px rgba(7, 12, 30, .32); padding: 5px; display: none; }
.combo.open .combo-panel { display: block; }
.combo-opt { padding: 8px 11px; border-radius: 8px; font-size: var(--fs-small); color: var(--text-dim); cursor: pointer;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.combo-opt.is-active { background: color-mix(in srgb, var(--accent) 13%, transparent); color: var(--text); }
.combo-opt.is-sel { font-weight: 700; color: var(--accent); }
.combo-empty { padding: 12px; text-align: center; color: var(--text-mute); font-size: var(--fs-small); }

/* Flag glyph — the real country flag, rendered via the bundled Twemoji Country
   Flags web font (tokens.css @font-face) so it shows as a proper flag image on
   every OS, Windows included. Just a sizing/alignment wrapper; the font does
   the rest. Slightly rounded to read as a flag, not a square emoji. */
.flag-emoji { display: inline-block; font-size: 1.15em; line-height: 1; vertical-align: -2px;
  border-radius: 2px; overflow: hidden; }
.flag-emoji.flag-unknown { color: var(--text-mute); font-size: 1em; }

/* --------------------------------------------------- Company performance */
.co-strip { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.co-perf { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); padding: 16px 18px; cursor: pointer;
  position: relative; overflow: hidden; transition: all var(--t) var(--e-out); border-top: 3px solid var(--co, var(--accent)); }
.co-perf:hover { transform: translateY(-3px); box-shadow: var(--shadow); border-color: var(--border-strong); }
.co-perf-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.co-perf-ico { width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center; color: #fff; font-size: 16px; background: var(--co, var(--accent)); }
.co-perf-name { font-weight: 700; font-size: var(--fs-body); }
.co-perf-rev { font-size: var(--fs-h3); font-weight: 700; font-variant-numeric: tabular-nums; }
.co-perf-meta { display: flex; align-items: center; justify-content: space-between; margin-top: 8px; font-size: var(--fs-tiny); color: var(--text-dim); }

/* --------------------------------------------------------- Progress / ring */
.progress { height: 8px; border-radius: 999px; background: var(--surface-3); overflow: hidden; }
.progress-bar { height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--accent), color-mix(in srgb, var(--accent) 60%, #fff));
  transition: width var(--t-slow) var(--e-out); }
.progress.thin { height: 5px; }
.meter { height: 6px; border-radius: 999px; background: var(--surface-3); overflow: hidden; }
.meter > span { display: block; height: 100%; border-radius: 999px; }
.meter .lvl-low { background: var(--good); } .meter .lvl-mid { background: var(--warn); } .meter .lvl-high { background: var(--bad); }
.ring { --p: 0; --sz: 88px; --c: var(--accent); width: var(--sz); height: var(--sz); border-radius: 50%; display: grid; place-items: center;
  background: conic-gradient(var(--c) calc(var(--p) * 1%), var(--surface-3) 0); position: relative; }
.ring::before { content:''; position: absolute; inset: 8px; border-radius: 50%; background: var(--surface); }
.ring-label { position: relative; font-weight: 700; font-size: var(--fs-h3); font-variant-numeric: tabular-nums; }

/* Extra-compact button — action rows that must fit on ONE line (payslip header). */
.btn-xxs { padding: 4px 9px; font-size: var(--fs-tiny); border-radius: 8px; line-height: 1.25; }
.btn-xxs .bi { font-size: 12px; }

/* Row flash — jumpTo() lands the user on the exact row and pulses it briefly. */
@keyframes rowFlash { 0%, 55% { background: color-mix(in srgb, var(--accent) 16%, transparent); } 100% { background: transparent; } }
.row-flash { animation: rowFlash 2.4s ease-out 1; }

/* --------------------------------------------------------------- Kanban */
.kanban { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(268px, 1fr); gap: 16px; overflow-x: auto; padding-bottom: 12px; align-items: start; }
.kb-col { background: color-mix(in srgb, var(--surface) 60%, var(--bg)); border: 1px solid var(--border); border-radius: var(--r-lg); display: flex; flex-direction: column; min-height: 120px; }
.kb-col.drag-over { border-color: var(--accent); box-shadow: var(--glow); }
.kb-col-head { display: flex; align-items: center; gap: 8px; padding: 13px 15px; border-bottom: 1px solid var(--border); position: sticky; top: 0; }
.kb-col-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--kb, var(--text-mute)); }
.kb-col-title { font-weight: 700; font-size: var(--fs-small); }
.kb-count { margin-left: auto; font-size: var(--fs-micro); font-weight: 700; color: var(--text-mute); background: var(--surface-3); padding: 1px 8px; border-radius: 999px; }
.kb-list { padding: 10px; display: flex; flex-direction: column; gap: 10px; min-height: 40px; }
.kb-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md); padding: 13px 14px;
  cursor: grab; transition: all var(--t-fast); position: relative; box-shadow: var(--shadow-sm);
}
.kb-card:hover { border-color: var(--border-strong); transform: translateY(-2px); box-shadow: var(--shadow); }
.kb-card:active { cursor: grabbing; }
.kb-card.dragging { opacity: .5; }
.kb-card.glow { border-color: var(--warn); box-shadow: 0 0 0 1px var(--warn), 0 0 22px -4px var(--warn); animation: pulseGlow 1.6s ease-in-out infinite; }
.kb-card.restricted { border-left: 3px solid var(--bad); }
.kb-card.redflag::after { content:'\F33A'; font-family: 'bootstrap-icons'; position: absolute; top: 10px; right: 12px; color: var(--bad); }
.kb-card-title { font-weight: 600; font-size: var(--fs-body); margin-bottom: 8px; line-height: 1.35; padding-right: 16px; }
.kb-card-labels { display: flex; gap: 5px; flex-wrap: wrap; margin-bottom: 8px; }
.kb-tag { font-size: var(--fs-micro); font-weight: 700; padding: 2px 7px; border-radius: 5px; text-transform: uppercase; letter-spacing: .03em; }
.kb-card-foot { display: flex; align-items: center; justify-content: space-between; margin-top: 10px; font-size: var(--fs-tiny); color: var(--text-mute); }
.kb-prog { display: flex; align-items: center; gap: 7px; margin-top: 8px; }
.kb-prog .progress { flex: 1; }
.kb-prog small { font-size: var(--fs-micro); font-weight: 700; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.admin-flag { display: inline-flex; align-items: center; gap: 4px; font-size: var(--fs-micro); font-weight: 800; text-transform: uppercase;
  color: var(--warn); background: var(--warn-soft); padding: 2px 7px; border-radius: 5px; }

/* Task phase rows (detail modal) */
.phase { display: flex; align-items: center; gap: 12px; padding: 11px 0; border-bottom: 1px solid var(--border); }
.phase:last-child { border-bottom: none; }
.phase-main { flex: 1; min-width: 0; }
.phase-name { font-weight: 600; font-size: var(--fs-small); }
.phase-time { font-size: var(--fs-tiny); color: var(--text-mute); font-family: var(--font-mono); }
.phase-time.running { color: var(--good); }
.phase-controls { display: flex; gap: 6px; }
.phase-controls .btn { padding: 5px 10px; }
.phase.done .phase-name { color: var(--text-mute); text-decoration: line-through; }

/* ---- Task board: phase assignee + priority + time/timeline chips ----------*/
.phase { flex-wrap: wrap; border-radius: 10px; padding: 11px 10px; margin: 0 -10px; }
.phase.running { background: color-mix(in srgb, var(--accent) 7%, transparent); }
/* time counting + timeline sit BESIDE each other as chips */
.phase-timerow { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 5px; }
.phase-time { display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px; border-radius: 999px;
  background: var(--surface-2); border: 1px solid var(--border); font-size: var(--fs-tiny); font-family: var(--font-mono); color: var(--text-mute); }
.phase-time.running { color: var(--good); border-color: color-mix(in srgb, var(--good) 45%, var(--border)); background: color-mix(in srgb, var(--good) 12%, transparent); }
.phase-range { display: inline-flex; align-items: center; padding: 3px 9px; border-radius: 999px; letter-spacing: -0.01em;
  background: var(--surface-2); border: 1px solid var(--border); font-size: var(--fs-micro); font-family: var(--font-mono); color: var(--text-mute); }
.phase-range.complete { color: var(--good); border-color: color-mix(in srgb, var(--good) 35%, var(--border)); background: color-mix(in srgb, var(--good) 9%, transparent); }
.phase-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.phase-field { display: inline-flex; align-items: center; gap: 5px; color: var(--text-mute); font-size: 12px; }
.phase-field .bi { font-size: 12px; }
.phase-assignee, .phase-priority {
  padding: 5px 8px; font-size: var(--fs-tiny); border-radius: 8px; max-width: 150px;
  background: var(--surface-2); border: 1px solid var(--border); color: var(--text);
}
.phase-priority.pri-high   { color: var(--bad, #f0506e); border-color: color-mix(in srgb, var(--bad, #f0506e) 45%, var(--border)); }
.phase-priority.pri-medium { color: #f4b740; border-color: color-mix(in srgb, #f4b740 45%, var(--border)); }
.phase-priority.pri-low    { color: var(--good, #23c17e); border-color: color-mix(in srgb, var(--good, #23c17e) 45%, var(--border)); }

/* ---- Fluid main progress fill (task detail) ------------------------------*/
.progress.progress-lg { height: 12px; }
.progress-bar.fluid { position: relative; overflow: hidden; transition: width 1.1s cubic-bezier(.22,.61,.36,1); }
.progress-bar.fluid::after {
  content:''; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.4), transparent);
  transform: translateX(-100%); animation: progShimmer 2.2s ease-in-out infinite;
}
@keyframes progShimmer { 0% { transform: translateX(-100%); } 60%, 100% { transform: translateX(220%); } }
@media (prefers-reduced-motion: reduce) { .progress-bar.fluid { transition: none; } .progress-bar.fluid::after { animation: none; } }

/* --------------------------------------------------------- Avatar stack */
.avatar-stack { display: flex; }
.avatar-stack .avatar { width: 28px; height: 28px; border-radius: 8px; font-size: var(--fs-micro); margin-left: -8px; border: 2px solid var(--surface); }   /* initials ARE text — they hold the 11px floor */
.avatar-stack .avatar:first-child { margin-left: 0; }

/* --------------------------------------------------------------- Timeline */
.timeline { position: relative; padding-left: 22px; }
.timeline::before { content:''; position: absolute; left: 6px; top: 4px; bottom: 4px; width: 2px; background: var(--border); }
.tl-item { position: relative; padding-bottom: 18px; }
.tl-item::before { content:''; position: absolute; left: -22px; top: 3px; width: 12px; height: 12px; border-radius: 50%;
  background: var(--surface); border: 2px solid var(--accent); }
.tl-item .tl-time { font-size: var(--fs-micro); color: var(--text-mute); }
.tl-item .tl-text { font-size: var(--fs-small); margin-top: 2px; }

/* --------------------------------------------------------------- Modals */
.modal-overlay { position: fixed; inset: 0; z-index: 200; display: grid; place-items: center; padding: 24px;
  background: var(--scrim); backdrop-filter: blur(6px); opacity: 0; transition: opacity var(--t); }
.modal-overlay.in { opacity: 1; }
.modal-box { width: 560px; max-width: 100%; max-height: 88vh; display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--r-xl); box-shadow: var(--shadow-lg);
  transform: translateY(14px) scale(.98); opacity: 0; transition: all var(--t) var(--e-out); }
.modal-overlay.in .modal-box { transform: none; opacity: 1; }
.modal-sm { width: 420px; } .modal-lg { width: 780px; } .modal-xl { width: 1040px; } .modal-cmd { width: 620px; align-self: flex-start; margin-top: 10vh; }
.modal-head { display: flex; align-items: center; justify-content: space-between; padding: 18px 22px; border-bottom: 1px solid var(--border); }
.modal-title { font-size: var(--fs-lead); font-weight: 700; display: flex; align-items: center; gap: 9px; }
.modal-title i { color: var(--accent); }
.modal-x { width: 32px; height: 32px; border-radius: 9px; font-size: 20px; color: var(--text-mute); display: grid; place-items: center; transition: all var(--t); }
.modal-x:hover { background: var(--surface-2); color: var(--text); }
.modal-body { padding: 22px; overflow-y: auto; }
.modal-foot { display: flex; justify-content: flex-end; gap: 10px; padding: 16px 22px; border-top: 1px solid var(--border); }

/* A table inside a modal has the LEAST width to work with, so force it to FIT:
   `table-layout: fixed` makes the table exactly the modal width — it can never
   overflow, so every column (incl. the last) stays visible with NO horizontal
   scrollbar at any zoom. Content wraps to share the space; numbers wrap; badges
   shrink. This is the definitive no-scroll guarantee for drill-down/detail lists. */
.modal-body .table-wrap { overflow: hidden; }
.modal-body table.tbl { table-layout: fixed; font-size: var(--fs-tiny); }
.modal-body .tbl th, .modal-body .tbl td { padding-left: 7px; padding-right: 7px; overflow-wrap: anywhere; word-break: break-word; }
/* let every otherwise-nowrap element WRAP so nothing spills past the fixed width */
.modal-body .tbl td.num, .modal-body .tbl th.num,
.modal-body .tbl td.nowrap, .modal-body .tbl .mono { white-space: normal; }
.modal-body .tbl .dt-actions { white-space: normal; width: auto; }
.modal-body .row-actions { flex-wrap: wrap; white-space: normal; justify-content: flex-start; }
.modal-body .tbl .badge { font-size: var(--fs-micro); padding: 2px 6px; white-space: normal; }

/* Form grid inside modals */
.form-grid { display: grid; gap: 0 16px; grid-template-columns: 1fr 1fr; }
.form-grid .col-2 { grid-column: span 2; }
.form-section-title { font-size: var(--fs-tiny); font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--accent);
  grid-column: span 2; margin: 8px 0 10px; padding-top: 8px; border-top: 1px solid var(--border); }
.form-section-title:first-child { border-top: none; padding-top: 0; }
@media (max-width: 560px){ .form-grid { grid-template-columns: 1fr; } .form-grid .col-2 { grid-column: span 1; } }

/* --------------------------------------------------------------- Toasts */
.toast-host { position: fixed; right: 20px; bottom: 20px; z-index: 300; display: flex; flex-direction: column; gap: 10px; }
.toast-item { display: flex; align-items: flex-start; gap: 11px; min-width: 280px; max-width: 380px; padding: 13px 15px;
  background: var(--surface-3); border: 1px solid var(--border-strong); border-radius: var(--r-md); box-shadow: var(--shadow-lg);
  transform: translateX(120%); opacity: 0; transition: all var(--t) var(--e-out); }
.toast-item.in { transform: none; opacity: 1; }
.toast-ico { font-size: 18px; margin-top: 1px; }
.toast-success .toast-ico { color: var(--good); } .toast-error .toast-ico { color: var(--bad); }
.toast-warning .toast-ico { color: var(--warn); } .toast-info .toast-ico { color: var(--info); }
.toast-title { font-weight: 700; font-size: var(--fs-small); }
.toast-msg { font-size: var(--fs-small); color: var(--text-dim); }
.toast-x { margin-left: auto; color: var(--text-mute); font-size: 18px; line-height: 1; }

/* --------------------------------------------------------------- Popovers */
.popover-layer { position: fixed; inset: 0; z-index: 150; }
.pop { width: 320px; background: var(--surface-2); border: 1px solid var(--border-strong); border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg); overflow: hidden; transform: translateY(-8px); opacity: 0; transition: all var(--t) var(--e-out); }
.pop.in { transform: none; opacity: 1; }
.pop-head { display: flex; align-items: center; justify-content: space-between; padding: 13px 16px; border-bottom: 1px solid var(--border); }
.pop-body { max-height: 380px; overflow-y: auto; }
.pop-empty { padding: 26px; text-align: center; color: var(--text-mute); font-size: var(--fs-small); }
.pop-notif { width: 360px; }
.notif { display: flex; gap: 11px; padding: 12px 16px; border-bottom: 1px solid var(--border); transition: background var(--t); }
.notif:hover { background: var(--surface-3); }
.notif.unread { background: color-mix(in srgb, var(--accent) 6%, transparent); }
.notif-ico { width: 30px; height: 30px; border-radius: 9px; display: grid; place-items: center; flex: none; font-size: 14px; background: var(--surface-3); }
.notif-ico.notif-warning { color: var(--warn); background: var(--warn-soft); }
.notif-ico.notif-success { color: var(--good); background: var(--good-soft); }
.notif-ico.notif-error { color: var(--bad); background: var(--bad-soft); }
.notif-ico.notif-info { color: var(--info); background: var(--info-soft); }
.notif-title { font-weight: 600; font-size: var(--fs-small); }
.notif-text { font-size: var(--fs-tiny); color: var(--text-dim); margin-top: 1px; }
.notif-time { font-size: var(--fs-micro); color: var(--text-mute); margin-top: 3px; }
.pop-user { width: 300px; }
.pop-userhead { display: flex; align-items: center; gap: 12px; padding: 16px; border-bottom: 1px solid var(--border); }
.pop-section-label { font-size: var(--fs-micro); font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--text-mute); padding: 12px 16px 6px; }
.viewas { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; padding: 0 12px 10px; }
.viewas-btn { display: flex; align-items: center; gap: 7px; padding: 8px 10px; border-radius: var(--r-sm); font-size: var(--fs-tiny); font-weight: 600;
  color: var(--text-dim); border: 1px solid var(--border); transition: all var(--t); }
.viewas-btn:hover { background: var(--surface-3); color: var(--text); }
.viewas-btn.active { background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent); border-color: var(--border-accent); }
.viewas-btn i { font-size: 13px; }
.pop-divider { height: 1px; background: var(--border); margin: 6px 0; }
.pop-link { display: flex; align-items: center; gap: 10px; width: 100%; padding: 11px 16px; font-size: var(--fs-small); font-weight: 500; color: var(--text-dim); transition: all var(--t); }
.pop-link:hover { background: var(--surface-3); color: var(--text); }
.pop-link.danger { color: var(--bad); }
.pop-link i { font-size: 15px; width: 18px; }

/* --------------------------------------------------------- Command palette */
.cmdk { display: flex; flex-direction: column; }
.cmd-box { display: flex; align-items: center; gap: 12px; padding: 6px 6px 14px; border-bottom: 1px solid var(--border); }
.cmd-search { font-size: 18px; color: var(--text-mute); }
.cmd-input { flex: 1; background: none; border: none; outline: none; font-size: var(--fs-lead); color: var(--text); }
.cmd-results { max-height: 52vh; overflow-y: auto; padding: 8px 0; }
.cmd-item { display: flex; align-items: center; gap: 12px; width: 100%; padding: 10px 14px; border-radius: var(--r-sm); text-align: left; transition: background var(--t-fast); }
.cmd-item.sel, .cmd-item:hover { background: var(--surface-3); }
.cmd-ico { width: 30px; height: 30px; border-radius: 9px; display: grid; place-items: center; background: var(--surface); border: 1px solid var(--border); }
.cmd-label { flex: 1; font-weight: 600; font-size: var(--fs-body); display: flex; flex-direction: column; }
.cmd-label small { font-weight: 400; font-size: var(--fs-tiny); color: var(--text-mute); }
.cmd-go { color: var(--text-mute); opacity: 0; }
.cmd-item.sel .cmd-go { opacity: 1; }

/* ------------------------------------------------------ Empty / Gate states */
.empty-state, .gate-state { display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center;
  padding: 60px 24px; color: var(--text-dim); }
.empty-state i { font-size: 40px; color: var(--text-mute); margin-bottom: 14px; }
/* Was the last off-scale text in the app: with no font-size of its own this fell
   through to the UA default for h3 (1.17em × 14px = 16.4px) — a stray size nobody
   chose, which is exactly what made the scale read as unresolved. */
.empty-state h3 { color: var(--text); margin-bottom: 6px; font-size: var(--fs-lead); }
.gate-state { min-height: 60vh; }
.gate-ico { width: 88px; height: 88px; border-radius: 26px; display: grid; place-items: center; font-size: 40px; margin-bottom: 20px;
  background: color-mix(in srgb, var(--accent) 12%, transparent); color: var(--accent); border: 1px solid var(--border-accent); }
.gate-state h2 { font-size: var(--fs-h3); margin-bottom: 8px; }
.gate-state p { max-width: 420px; margin-bottom: 20px; }

/* --------------------------------------------------------------- Boot splash */
#boot-splash { position: fixed; inset: 0; z-index: 999; display: grid; place-items: center; background: var(--bg);
  transition: opacity var(--t-slow); }
#boot-splash.gone { opacity: 0; pointer-events: none; }
.boot-logo { display: flex; flex-direction: column; align-items: center; gap: 18px; }
.boot-mark { width: 66px; height: 66px; border-radius: 20px; display: grid; place-items: center; font-family: var(--font-display);
  font-weight: 800; font-size: 30px; color: #dbe4f8; background: linear-gradient(135deg, var(--gold), #0A2472); box-shadow: 0 14px 40px -10px var(--gold);   /* logo mark, not type — off the scale by design */
  animation: floatY 2.4s var(--e-inout) infinite; }
.boot-name { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-h3); letter-spacing: .02em; }
.boot-bar { width: 160px; height: 3px; border-radius: 999px; background: var(--surface-3); overflow: hidden; }
.boot-bar::before { content:''; display: block; height: 100%; width: 40%; background: var(--gold); border-radius: 999px; animation: bootSlide 1.1s var(--e-inout) infinite; }

/* --------------------------------------------------- Section / list helpers */
.section-label { font-size: var(--fs-tiny); font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--text-mute); margin: 26px 0 12px; }
/* A section label straight after a KPI strip stacked its own 26px top margin on
   the strip's 16px bottom margin: ~42px of bare scene, landing exactly where the
   ambient scene is at its brightest, so it read as a gap rather than a rhythm
   (owner review 2026-07-15 — Chart of Accounts, Travels Expenses). The strip's
   margin is the whole of the space; the label adds none. This also makes the
   screens that hand-marked their label .mt-0 and the ones that didn't agree. */
.kpi-grid + .section-label { margin-top: 0; }
.data-list { display: flex; flex-direction: column; }
.data-row { display: flex; align-items: center; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--border); }
.data-row:last-child { border-bottom: none; }
/* A value keeps to its own side and wraps instead of running off the card —
   long ones (a purpose, a security note) used to push past the right edge. */
.data-row .data-v { text-align: right; min-width: 0; overflow-wrap: anywhere; }
/* Entity drill-downs (loan detail): facts grouped into two columns of short
   label→value pairs, so a value sits NEXT to its label instead of a metre
   away across an empty row. Collapses to one column in a narrow modal. */
.detail-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 0 28px; align-items: start; }
@media (max-width: 860px) { .detail-cols { grid-template-columns: 1fr; } }
.two-col { display: grid; grid-template-columns: 1.6fr 1fr; gap: 18px; align-items: start; }
.three-col { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
@media (max-width: 1100px){ .two-col, .three-col { grid-template-columns: 1fr; } }

/* placeholder scaffold cards */
.scaffold-grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }
.scaffold-card { display: flex; align-items: flex-start; gap: 13px; padding: 16px; border: 1px solid var(--border); border-radius: var(--r-lg);
  background: var(--surface); transition: all var(--t) var(--e-out); cursor: pointer; }
.scaffold-card:hover { border-color: var(--border-accent); transform: translateY(-2px); box-shadow: var(--shadow); }
.scaffold-ico { width: 40px; height: 40px; border-radius: 12px; display: grid; place-items: center; font-size: 18px; flex: none;
  background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent); }
.scaffold-card h4 { font-size: var(--fs-body); margin-bottom: 3px; }
.scaffold-card p { font-size: var(--fs-tiny); color: var(--text-mute); }
.build-banner { display: flex; align-items: center; gap: 12px; padding: 14px 18px; border-radius: var(--r-md); margin-bottom: 22px;
  background: color-mix(in srgb, var(--accent) 8%, transparent); border: 1px solid var(--border-accent); color: var(--text-dim); font-size: var(--fs-small); }
.build-banner i { color: var(--accent); font-size: 18px; }
