/* ══════════════════════════════════════════════════════════════════════════
   ShopCore Books — the finance design system
   ══════════════════════════════════════════════════════════════════════════

   A ledger is not a dashboard. The things this sheet has to get right are not
   the things a marketing page has to get right:

     · Figures must align. Every number is tabular-lined, right-aligned, and
       carries the same glyph width whatever the digit — so a column of money
       reads as a column and not as ransom-note typography.
     · Negatives must be unmistakable. Accountants read brackets, not minus
       signs, and colour is a second signal rather than the only one.
     · Density is the operator's choice. A clerk posting two hundred lines a
       day wants compact rows; a director reviewing a close wants air.
     · The dark theme is a second :root, never a second stylesheet.

   Read in five parts:
     1. Tokens      — colour, type, elevation, radius, motion, metrics
     2. Shell       — sidebar, top bar, content, command palette
     3. Controls    — button, field, badge, card, tab, modal, toast
     4. Ledger      — the grid, the money cell, the statement, the drilldown
     5. Utilities   — layout helpers and print
   ────────────────────────────────────────────────────────────────────────── */

/* ═══ 1. TOKENS ═══════════════════════════════════════════════════════════ */

:root {
  /* ── Brand ────────────────────────────────────────────────────────────
     ShopCore's navy stays the identity so the portals are recognisably one
     product. Books adds a ledger green as the accent it spends on emphasis:
     a posted state, a balanced total, the rail beside the open screen. */
  --brand:          #1B4F72;
  --brand-hover:    #16415E;
  --brand-pressed:  #10314A;
  --brand-tint:     #E9F1F8;
  --brand-tint-2:   #D2E3F1;
  --brand-on:       #FFFFFF;

  --accent:         #0F6B4F;   /* ledger green — balanced, posted, agreed */
  --accent-hover:   #0B5940;
  --accent-tint:    #E6F4EF;
  --accent-on:      #FFFFFF;

  /* ── Neutral ramp — layered surfaces ──────────────────────────────────
     canvas sits behind, layer floats on it, subtle is what a header or a
     footer inside a layer is painted with. */
  --canvas:        #F2F4F6;
  --layer:         #FFFFFF;
  --layer-alt:     #FAFBFC;
  --subtle:        #F4F6F8;
  --subtle-hover:  #ECEFF3;
  --pressed:       #E2E6EB;
  --disabled-bg:   #F0F1F3;

  --stroke-1: #D5DAE0;       /* control borders */
  --stroke-2: #E3E7EC;       /* dividers between rows and sections */
  --stroke-3: #EEF1F4;       /* the faintest rule that still reads */
  --stroke-strong: #B9C2CC;  /* a total rule, a grid frame */

  --fg-1: #14202B;   /* headings and the figures that matter */
  --fg-2: #46556A;   /* body and labels */
  --fg-3: #6A798E;   /* secondary, hints, meta */
  --fg-4: #93A1B3;   /* muted, placeholders, disabled */

  /* ── Status ───────────────────────────────────────────────────────────
     Three tokens each — a foreground that passes contrast on its own tint,
     the tint, and a border — so a badge, an alert and a chart legend can be
     the same green without agreeing by hand. */
  --ok-fg:   #0E6B33; --ok-bg:   #E8F7EE; --ok-br:   #B4E1C4;
  --warn-fg: #8A5A00; --warn-bg: #FFF6E5; --warn-br: #F2D8A2;
  --err-fg:  #B3261E; --err-bg:  #FDECEA; --err-br:  #F4C1BC;
  --info-fg: #12609E; --info-bg: #EAF3FB; --info-br: #B9D7EE;
  --plum-fg: #5B37B7; --plum-bg: #F1ECFC; --plum-br: #D5C5F1;
  --slate-fg:#4A5768; --slate-bg:#EEF1F4; --slate-br:#D8DEE5;

  /* ── The two colours a ledger actually needs ──────────────────────────
     Debit and credit are not "good" and "bad" — they are two sides. They
     get their own restrained pair so a trial balance does not read like a
     traffic light, and a genuine negative keeps the error red to itself. */
  --debit-fg:   #1D4F73;
  --credit-fg:  #7A4E14;
  --money-neg:  #B3261E;
  --money-zero: #93A1B3;

  /* ── Elevation ────────────────────────────────────────────────────────*/
  --shadow-2:  0 1px 2px rgba(16,24,40,.10), 0 0 2px rgba(16,24,40,.06);
  --shadow-4:  0 2px 4px rgba(16,24,40,.10), 0 0 2px rgba(16,24,40,.06);
  --shadow-8:  0 4px 8px rgba(16,24,40,.11), 0 0 2px rgba(16,24,40,.06);
  --shadow-16: 0 8px 16px rgba(16,24,40,.12), 0 0 2px rgba(16,24,40,.06);
  --shadow-28: 0 14px 28px rgba(16,24,40,.16), 0 0 8px rgba(16,24,40,.08);
  --shadow-64: 0 32px 64px rgba(16,24,40,.22), 0 0 8px rgba(16,24,40,.10);

  /* ── Shape ────────────────────────────────────────────────────────────*/
  --r-sm: 4px; --r-md: 6px; --r-lg: 8px; --r-xl: 12px; --r-2xl: 16px;
  --r-pill: 9999px;

  /* ── Type ─────────────────────────────────────────────────────────────*/
  --fs-micro:    10.5px;
  --fs-caption:  11.5px;
  --fs-sm:       12.5px;
  --fs-body:     13.5px;
  --fs-lg:       15px;
  --fs-subtitle: 17px;
  --fs-title-sm: 20px;
  --fs-title:    24px;
  --fs-display:  32px;
  --fs-figure:   28px;   /* the one number a card exists to show */

  --fw-regular: 400; --fw-medium: 500; --fw-semibold: 600; --fw-bold: 700;

  --font: 'Segoe UI Variable Text', 'Segoe UI', 'Inter', -apple-system,
          BlinkMacSystemFont, 'Helvetica Neue', Arial, sans-serif;
  --font-display: 'Segoe UI Variable Display', 'Segoe UI', 'Inter', sans-serif;

  /* Figures are set in a monospace with lining tabular numerals. This is the
     single most load-bearing decision in the sheet: it is what makes a
     column of money a column. */
  --font-mono: 'JetBrains Mono', 'Cascadia Mono', 'Consolas', 'SF Mono',
               ui-monospace, monospace;

  /* ── Motion ───────────────────────────────────────────────────────────*/
  --dur-faster: 90ms; --dur-fast: 140ms; --dur-normal: 200ms; --dur-slow: 320ms;
  --ease:       cubic-bezier(.33, 0, .67, 1);
  --ease-decel: cubic-bezier(0, 0, .2, 1);
  --ease-accel: cubic-bezier(.8, 0, 1, 1);

  /* ── Shell metrics ────────────────────────────────────────────────────*/
  --sidebar-w:           264px;
  --sidebar-w-collapsed: 56px;
  --topbar-h:            52px;
  --content-pad:         22px;

  /* ── Density ──────────────────────────────────────────────────────────
     Stamped on <html> before first paint, so an operator who works compact
     never watches the grid reflow. Comfortable is the default. */
  --row-h:      36px;
  --row-pad-y:  8px;
  --row-pad-x:  12px;
  --card-pad:   18px;
  --gap:        16px;
}

:root[data-density="compact"] {
  --row-h:     28px;
  --row-pad-y: 4px;
  --row-pad-x: 9px;
  --card-pad:  13px;
  --gap:       11px;
  --fs-body:   12.5px;
  --fs-sm:     11.5px;
}

:root[data-density="relaxed"] {
  --row-h:     44px;
  --row-pad-y: 12px;
  --row-pad-x: 16px;
  --card-pad:  24px;
  --gap:       20px;
}

/* ── Dark theme ─────────────────────────────────────────────────────────
   Only the tokens are redefined. Nothing below section 1 knows which theme
   it is in, which is the whole point of spending tokens rather than hexes. */
:root[data-theme="dark"] {
  --brand:         #4A90C2;
  --brand-hover:   #5AA0D2;
  --brand-pressed: #3A80B2;
  --brand-tint:    #16283A;
  --brand-tint-2:  #1D3448;
  --brand-on:      #0B1620;

  --accent:        #3FAE86;
  --accent-hover:  #4FBE96;
  --accent-tint:   #122A22;
  --accent-on:     #08150F;

  --canvas:        #0D141B;
  --layer:         #141C25;
  --layer-alt:     #18212B;
  --subtle:        #1B2530;
  --subtle-hover:  #223040;
  --pressed:       #2A3846;
  --disabled-bg:   #1A222C;

  --stroke-1: #2C3947;
  --stroke-2: #232F3B;
  --stroke-3: #1C2733;
  --stroke-strong: #3E4E5F;

  --fg-1: #E8EDF2;
  --fg-2: #B4C0CD;
  --fg-3: #8593A3;
  --fg-4: #5F6D7D;

  --ok-fg:   #5FD08C; --ok-bg:   #10281A; --ok-br:   #1F4A31;
  --warn-fg: #E5B45C; --warn-bg: #2B2110; --warn-br: #4D3C1B;
  --err-fg:  #F08B84; --err-bg:  #2C1614; --err-br:  #542724;
  --info-fg: #6FB4E8; --info-bg: #10222F; --info-br: #1E3E56;
  --plum-fg: #B49BEC; --plum-bg: #201A33; --plum-br: #3A2F57;
  --slate-fg:#A0AEBE; --slate-bg:#1B2530; --slate-br:#2C3947;

  --debit-fg:  #7FB6DD;
  --credit-fg: #DFAE6C;
  --money-neg: #F08B84;
  --money-zero:#5F6D7D;

  --shadow-2:  0 1px 2px rgba(0,0,0,.40);
  --shadow-4:  0 2px 4px rgba(0,0,0,.44);
  --shadow-8:  0 4px 8px rgba(0,0,0,.48);
  --shadow-16: 0 8px 16px rgba(0,0,0,.52);
  --shadow-28: 0 14px 28px rgba(0,0,0,.58);
  --shadow-64: 0 32px 64px rgba(0,0,0,.66);
}

/* ═══ RESET ═══════════════════════════════════════════════════════════════ */

*, *::before, *::after { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--fs-body);
  line-height: 1.45;
  color: var(--fg-2);
  background: var(--canvas);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Lining tabular figures everywhere, so even body copy that quotes a total
     lines up with the total in the grid above it. */
  font-variant-numeric: tabular-nums lining-nums;
}

h1, h2, h3, h4, h5 {
  margin: 0;
  font-family: var(--font-display);
  color: var(--fg-1);
  font-weight: var(--fw-semibold);
  line-height: 1.25;
}

h1 { font-size: var(--fs-title); }
h2 { font-size: var(--fs-subtitle); }
h3 { font-size: var(--fs-lg); }

p { margin: 0 0 10px; }

a { color: var(--brand); text-decoration: none; }
a:hover { color: var(--brand-hover); text-decoration: underline; }

button { font: inherit; }

:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

::selection { background: var(--brand-tint-2); color: var(--fg-1); }

/* Scrollbars, restrained. A ledger screen has a lot of them. */
* { scrollbar-width: thin; scrollbar-color: var(--stroke-strong) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--stroke-1);
  border: 3px solid transparent;
  background-clip: content-box;
  border-radius: var(--r-pill);
}
*::-webkit-scrollbar-thumb:hover { background: var(--stroke-strong); background-clip: content-box; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ═══ 2. SHELL ════════════════════════════════════════════════════════════ */

.fx-shell { display: flex; height: 100vh; overflow: hidden; }

.fx-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;   /* without this a wide grid pushes the sidebar off screen */
}

.fx-content {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  padding: var(--content-pad);
  background: var(--canvas);
  scroll-behavior: smooth;
}

/* ── Sidebar ──────────────────────────────────────────────────────────── */

.fx-sidebar {
  width: var(--sidebar-w);
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  background: var(--layer);
  border-right: 1px solid var(--stroke-2);
  transition: width var(--dur-normal) var(--ease);
}

.fx-sidebar.collapsed { width: var(--sidebar-w-collapsed); }
.fx-sidebar.collapsed .fx-nav-label,
.fx-sidebar.collapsed .fx-logo-text,
.fx-sidebar.collapsed .fx-trade-badge,
.fx-sidebar.collapsed .fx-nav-section,
.fx-sidebar.collapsed .fx-nav-sub,
.fx-sidebar.collapsed .fx-user-info { display: none; }

.fx-logo {
  display: flex;
  align-items: center;
  gap: 10px;
  height: var(--topbar-h);
  padding: 0 14px;
  border-bottom: 1px solid var(--stroke-2);
  flex-shrink: 0;
}

.fx-logo-mark { width: 26px; height: 26px; flex-shrink: 0; }

.fx-logo-text { display: flex; flex-direction: column; line-height: 1.15; min-width: 0; }

.fx-logo-name {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: var(--fw-bold);
  color: var(--fg-1);
  letter-spacing: -.2px;
}

.fx-logo-sub {
  font-size: var(--fs-micro);
  font-weight: var(--fw-semibold);
  letter-spacing: .8px;
  text-transform: uppercase;
  color: var(--accent);
}

/* What trade the portal is speaking. Every noun below it comes from here. */
.fx-trade-badge {
  margin: 10px 14px 4px;
  padding: 4px 9px;
  font-size: var(--fs-micro);
  font-weight: var(--fw-semibold);
  letter-spacing: .5px;
  text-transform: uppercase;
  color: var(--brand);
  background: var(--brand-tint);
  border: 1px solid var(--brand-tint-2);
  border-radius: var(--r-pill);
  align-self: flex-start;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: calc(100% - 28px);
}

.fx-nav-scroll { flex: 1; overflow-y: auto; padding: 6px 8px 14px; }

.fx-nav-section {
  padding: 14px 8px 5px;
  font-size: var(--fs-micro);
  font-weight: var(--fw-bold);
  letter-spacing: .9px;
  text-transform: uppercase;
  color: var(--fg-4);
}

.fx-nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 7px 9px;
  border: 0;
  border-radius: var(--r-md);
  background: transparent;
  color: var(--fg-2);
  font-size: var(--fs-body);
  font-weight: var(--fw-medium);
  text-align: left;
  cursor: pointer;
  position: relative;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

.fx-nav-item:hover { background: var(--subtle-hover); color: var(--fg-1); text-decoration: none; }
.fx-nav-item:active { background: var(--pressed); }

.fx-nav-item svg { width: 17px; height: 17px; flex-shrink: 0; stroke-width: 1.7; }

.fx-nav-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* The selection rail. Fluent's idea and a good one: the active screen is
   marked at the edge rather than by painting the whole row, which stays
   legible when three levels of the menu are open at once. */
.fx-nav-item.active {
  background: var(--brand-tint);
  color: var(--brand);
  font-weight: var(--fw-semibold);
}

.fx-nav-item.active::before {
  content: '';
  position: absolute;
  left: -8px;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 18px;
  border-radius: 0 var(--r-pill) var(--r-pill) 0;
  background: var(--accent);
}

.fx-nav-item .fx-chevron {
  margin-left: auto;
  width: 14px;
  height: 14px;
  transition: transform var(--dur-fast) var(--ease);
  color: var(--fg-4);
}

.fx-nav-item.expanded .fx-chevron { transform: rotate(90deg); }

.fx-nav-sub {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-normal) var(--ease-decel);
}

.fx-nav-sub > div { overflow: hidden; }
.fx-nav-sub.open { grid-template-rows: 1fr; }

.fx-nav-sub-item {
  display: block;
  padding: 6px 9px 6px 36px;
  border-radius: var(--r-md);
  color: var(--fg-3);
  font-size: var(--fs-sm);
  position: relative;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

.fx-nav-sub-item:hover { background: var(--subtle-hover); color: var(--fg-1); text-decoration: none; }

.fx-nav-sub-item.active {
  color: var(--brand);
  font-weight: var(--fw-semibold);
  background: var(--brand-tint);
}

.fx-nav-sub-item.active::before {
  content: '';
  position: absolute;
  left: 20px;
  top: 50%;
  transform: translateY(-50%);
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
}

.fx-sidebar-user {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border-top: 1px solid var(--stroke-2);
  flex-shrink: 0;
}

.fx-user-avatar {
  width: 30px; height: 30px;
  flex-shrink: 0;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--brand);
  color: var(--brand-on);
  font-size: var(--fs-caption);
  font-weight: var(--fw-bold);
}

.fx-user-info { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }

.fx-user-name {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--fg-1);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.fx-user-role {
  font-size: var(--fs-micro);
  color: var(--fg-3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ── Top bar ──────────────────────────────────────────────────────────── */

.fx-topbar {
  height: var(--topbar-h);
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 16px;
  background: var(--layer);
  border-bottom: 1px solid var(--stroke-2);
}

.fx-topbar-title { display: flex; flex-direction: column; min-width: 0; line-height: 1.2; }
.fx-topbar-crumb { font-size: var(--fs-micro); color: var(--fg-4); text-transform: uppercase; letter-spacing: .6px; }
.fx-topbar-screen { font-size: var(--fs-body); font-weight: var(--fw-semibold); color: var(--fg-1); }

.fx-topbar-spacer { flex: 1; }

.fx-icon-btn {
  width: 32px; height: 32px;
  display: grid; place-items: center;
  border: 0;
  border-radius: var(--r-md);
  background: transparent;
  color: var(--fg-3);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

.fx-icon-btn:hover { background: var(--subtle-hover); color: var(--fg-1); }
.fx-icon-btn svg { width: 17px; height: 17px; stroke-width: 1.7; }

/* The scope pill: which set of books is on screen. It is deliberately the
   loudest control in the top bar — reading one branch's numbers under a
   label that says otherwise is the expensive mistake this portal can make. */
.fx-scope {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 32px;
  padding: 0 10px 0 8px;
  border: 1px solid var(--stroke-1);
  border-radius: var(--r-pill);
  background: var(--layer);
  color: var(--fg-1);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}

.fx-scope:hover { border-color: var(--brand); background: var(--brand-tint); }

.fx-scope-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--accent);
  flex-shrink: 0;
}

.fx-scope.group .fx-scope-dot { background: var(--plum-fg); }

.fx-scope-label { max-width: 190px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.fx-scope-kind {
  font-size: var(--fs-micro);
  font-weight: var(--fw-bold);
  letter-spacing: .5px;
  text-transform: uppercase;
  color: var(--fg-4);
}

/* The period the screen is reading. Second only to scope: a figure is
   meaningless without knowing which period produced it. */
.fx-period-pill {
  display: flex;
  align-items: center;
  gap: 7px;
  height: 32px;
  padding: 0 11px;
  border: 1px solid var(--stroke-1);
  border-radius: var(--r-pill);
  background: var(--layer);
  color: var(--fg-2);
  font-size: var(--fs-sm);
  cursor: pointer;
}

.fx-period-pill:hover { border-color: var(--brand); }
.fx-period-pill .fx-period-state { font-weight: var(--fw-semibold); }
.fx-period-pill.open   .fx-period-state { color: var(--ok-fg); }
.fx-period-pill.closed .fx-period-state { color: var(--warn-fg); }
.fx-period-pill.locked .fx-period-state { color: var(--err-fg); }

/* ── Search / command palette ─────────────────────────────────────────── */

.fx-omnibox {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 260px;
  height: 32px;
  padding: 0 10px;
  border: 1px solid var(--stroke-1);
  border-radius: var(--r-md);
  background: var(--subtle);
  color: var(--fg-4);
  font-size: var(--fs-sm);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}

.fx-omnibox:hover { border-color: var(--brand); background: var(--layer); }
.fx-omnibox svg { width: 15px; height: 15px; flex-shrink: 0; }
.fx-omnibox-hint { margin-left: auto; }

.fx-kbd {
  display: inline-block;
  padding: 1px 5px;
  border: 1px solid var(--stroke-1);
  border-bottom-width: 2px;
  border-radius: var(--r-sm);
  background: var(--layer);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  color: var(--fg-3);
  line-height: 1.4;
}

.fx-palette-backdrop {
  position: fixed; inset: 0;
  background: rgba(10,16,22,.42);
  backdrop-filter: blur(2px);
  z-index: 900;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  padding-top: 12vh;
  animation: fx-fade var(--dur-fast) var(--ease-decel);
}

.fx-palette {
  width: min(640px, calc(100vw - 32px));
  max-height: 62vh;
  display: flex;
  flex-direction: column;
  background: var(--layer);
  border: 1px solid var(--stroke-2);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-64);
  overflow: hidden;
  animation: fx-rise var(--dur-normal) var(--ease-decel);
}

.fx-palette-input {
  width: 100%;
  padding: 15px 18px;
  border: 0;
  border-bottom: 1px solid var(--stroke-2);
  background: transparent;
  color: var(--fg-1);
  font-size: var(--fs-lg);
  outline: none;
}

.fx-palette-list { overflow-y: auto; padding: 6px; }

.fx-palette-group {
  padding: 9px 12px 4px;
  font-size: var(--fs-micro);
  font-weight: var(--fw-bold);
  letter-spacing: .8px;
  text-transform: uppercase;
  color: var(--fg-4);
}

.fx-palette-item {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  padding: 9px 12px;
  border: 0;
  border-radius: var(--r-md);
  background: transparent;
  color: var(--fg-2);
  font-size: var(--fs-body);
  text-align: left;
  cursor: pointer;
}

.fx-palette-item:hover, .fx-palette-item.sel { background: var(--brand-tint); color: var(--brand); }
.fx-palette-item svg { width: 16px; height: 16px; flex-shrink: 0; color: var(--fg-4); }
.fx-palette-item.sel svg { color: var(--brand); }
.fx-palette-item .fx-palette-path { margin-left: auto; font-size: var(--fs-micro); color: var(--fg-4); }

.fx-palette-empty { padding: 28px; text-align: center; color: var(--fg-4); font-size: var(--fs-sm); }

/* ═══ 3. CONTROLS ═════════════════════════════════════════════════════════ */

/* ── Buttons ──────────────────────────────────────────────────────────── */

.fx-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  height: 32px;
  padding: 0 13px;
  border: 1px solid var(--stroke-1);
  border-radius: var(--r-md);
  background: var(--layer);
  color: var(--fg-1);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease),
              box-shadow var(--dur-fast) var(--ease);
}

.fx-btn:hover { background: var(--subtle-hover); text-decoration: none; }
.fx-btn:active { background: var(--pressed); }
.fx-btn svg { width: 15px; height: 15px; stroke-width: 1.8; }

.fx-btn:disabled, .fx-btn[disabled] {
  background: var(--disabled-bg);
  border-color: var(--stroke-2);
  color: var(--fg-4);
  cursor: not-allowed;
}

.fx-btn-primary {
  background: var(--brand);
  border-color: var(--brand);
  color: var(--brand-on);
}
.fx-btn-primary:hover { background: var(--brand-hover); border-color: var(--brand-hover); color: var(--brand-on); }
.fx-btn-primary:active { background: var(--brand-pressed); border-color: var(--brand-pressed); }

/* The button that posts. Posting is the irreversible act in this product, so
   it is the only one painted in the ledger green — a colour that appears
   nowhere else as a background. */
.fx-btn-post {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-on);
}
.fx-btn-post:hover { background: var(--accent-hover); border-color: var(--accent-hover); color: var(--accent-on); }

.fx-btn-danger {
  background: var(--err-fg);
  border-color: var(--err-fg);
  color: #fff;
}
.fx-btn-danger:hover { filter: brightness(1.08); color: #fff; }

.fx-btn-ghost { background: transparent; border-color: transparent; color: var(--fg-2); }
.fx-btn-ghost:hover { background: var(--subtle-hover); color: var(--fg-1); }

.fx-btn-subtle { background: var(--subtle); border-color: transparent; }
.fx-btn-subtle:hover { background: var(--subtle-hover); }

.fx-btn-sm { height: 26px; padding: 0 9px; font-size: var(--fs-caption); }
.fx-btn-sm svg { width: 13px; height: 13px; }
.fx-btn-lg { height: 38px; padding: 0 18px; font-size: var(--fs-body); }
.fx-btn-block { width: 100%; }
.fx-btn-icon { width: 32px; padding: 0; }
.fx-btn-icon.fx-btn-sm { width: 26px; }

.fx-btn-group { display: inline-flex; }
.fx-btn-group .fx-btn { border-radius: 0; margin-left: -1px; }
.fx-btn-group .fx-btn:first-child { border-radius: var(--r-md) 0 0 var(--r-md); margin-left: 0; }
.fx-btn-group .fx-btn:last-child { border-radius: 0 var(--r-md) var(--r-md) 0; }
.fx-btn-group .fx-btn.sel { background: var(--brand-tint); border-color: var(--brand); color: var(--brand); z-index: 1; }

/* ── Fields ───────────────────────────────────────────────────────────── */

.fx-field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }

.fx-label {
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
  color: var(--fg-2);
  display: flex;
  align-items: center;
  gap: 5px;
}

.fx-label .req { color: var(--err-fg); }

.fx-hint { font-size: var(--fs-micro); color: var(--fg-4); }
.fx-error-text { font-size: var(--fs-micro); color: var(--err-fg); font-weight: var(--fw-medium); }

/* Inside a grid cell an input has to fit the row rather than set its height —
   an editable quantity or rate column otherwise pushes every row taller than
   the ones around it. */
.fx-input-sm, .fx-select.fx-input-sm {
  height: 26px;
  padding: 0 7px;
  font-size: var(--fs-caption);
}

.fx-input, .fx-select, .fx-textarea {
  width: 100%;
  height: 32px;
  padding: 0 10px;
  border: 1px solid var(--stroke-1);
  border-radius: var(--r-md);
  background: var(--layer);
  color: var(--fg-1);
  font-family: var(--font);
  font-size: var(--fs-body);
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}

.fx-textarea { height: auto; min-height: 68px; padding: 8px 10px; resize: vertical; line-height: 1.5; }

.fx-input:hover, .fx-select:hover, .fx-textarea:hover { border-color: var(--stroke-strong); }

.fx-input:focus, .fx-select:focus, .fx-textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-tint);
}

.fx-input:disabled, .fx-select:disabled, .fx-textarea:disabled {
  background: var(--disabled-bg);
  color: var(--fg-4);
  cursor: not-allowed;
}

.fx-input.invalid, .fx-select.invalid { border-color: var(--err-fg); }
.fx-input.invalid:focus { box-shadow: 0 0 0 3px var(--err-bg); }

.fx-input::placeholder { color: var(--fg-4); }

/* Any field that holds money or a code is set in the ledger face and right
   aligned, wherever it appears — a form, a grid cell, a filter. */
.fx-input.money, .fx-input.num {
  font-family: var(--font-mono);
  text-align: right;
  font-variant-numeric: tabular-nums lining-nums;
  letter-spacing: -.2px;
}

.fx-input.code { font-family: var(--font-mono); letter-spacing: .3px; }

.fx-select {
  appearance: none;
  padding-right: 28px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%236A798E' stroke-width='1.8'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 9px center;
  background-size: 14px;
}

.fx-input-group { display: flex; align-items: stretch; }

.fx-input-addon {
  display: flex;
  align-items: center;
  padding: 0 10px;
  border: 1px solid var(--stroke-1);
  background: var(--subtle);
  color: var(--fg-3);
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
  white-space: nowrap;
}

.fx-input-group .fx-input-addon:first-child { border-radius: var(--r-md) 0 0 var(--r-md); border-right: 0; }
.fx-input-group .fx-input-addon:last-child { border-radius: 0 var(--r-md) var(--r-md) 0; border-left: 0; margin-left: -1px; }
.fx-input-group .fx-input:first-child { border-radius: var(--r-md) 0 0 var(--r-md); }
.fx-input-group .fx-input:last-child { border-radius: 0 var(--r-md) var(--r-md) 0; }

/* Checkbox and switch */
.fx-check { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: var(--fs-sm); }
.fx-check input { width: 15px; height: 15px; accent-color: var(--brand); cursor: pointer; margin: 0; }

.fx-switch { display: inline-flex; align-items: center; gap: 9px; cursor: pointer; font-size: var(--fs-sm); }
.fx-switch input { position: absolute; opacity: 0; pointer-events: none; }

.fx-switch-track {
  width: 34px; height: 18px;
  flex-shrink: 0;
  border-radius: var(--r-pill);
  background: var(--stroke-strong);
  position: relative;
  transition: background var(--dur-fast) var(--ease);
}

.fx-switch-track::after {
  content: '';
  position: absolute;
  top: 2px; left: 2px;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: #fff;
  box-shadow: var(--shadow-2);
  transition: transform var(--dur-fast) var(--ease);
}

.fx-switch input:checked + .fx-switch-track { background: var(--accent); }
.fx-switch input:checked + .fx-switch-track::after { transform: translateX(16px); }

/* ── Cards and sections ───────────────────────────────────────────────── */

.fx-card {
  background: var(--layer);
  border: 1px solid var(--stroke-2);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-2);
  overflow: hidden;
}

.fx-card-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px var(--card-pad);
  border-bottom: 1px solid var(--stroke-2);
  background: var(--layer-alt);
}

.fx-card-title { font-size: var(--fs-body); font-weight: var(--fw-semibold); color: var(--fg-1); }
.fx-card-sub { font-size: var(--fs-micro); color: var(--fg-3); }
.fx-card-actions { margin-left: auto; display: flex; align-items: center; gap: 7px; }
.fx-card-body { padding: var(--card-pad); }
.fx-card-body.flush { padding: 0; }

.fx-card-foot {
  padding: 11px var(--card-pad);
  border-top: 1px solid var(--stroke-2);
  background: var(--layer-alt);
  display: flex;
  align-items: center;
  gap: 8px;
}

/* ── Page header ──────────────────────────────────────────────────────── */

.fx-page-head {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  margin-bottom: var(--gap);
  flex-wrap: wrap;
}

.fx-page-title { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.fx-page-title h1 { font-size: var(--fs-title-sm); letter-spacing: -.3px; }
.fx-page-lede { font-size: var(--fs-sm); color: var(--fg-3); max-width: 74ch; }
.fx-page-actions { margin-left: auto; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* ── Toolbar / filter bar ─────────────────────────────────────────────── */

.fx-toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 12px;
  background: var(--layer);
  border: 1px solid var(--stroke-2);
  border-radius: var(--r-lg);
  margin-bottom: var(--gap);
  flex-wrap: wrap;
}

.fx-toolbar .fx-input, .fx-toolbar .fx-select { height: 30px; font-size: var(--fs-sm); width: auto; min-width: 130px; }
.fx-toolbar-sep { width: 1px; align-self: stretch; background: var(--stroke-2); margin: 0 2px; }
.fx-toolbar-spacer { flex: 1; }

.fx-search {
  position: relative;
  display: flex;
  align-items: center;
  min-width: 200px;
  flex: 1;
  max-width: 340px;
}

.fx-search svg {
  position: absolute;
  left: 9px;
  width: 15px; height: 15px;
  color: var(--fg-4);
  pointer-events: none;
}

.fx-search .fx-input { padding-left: 30px; height: 30px; }

/* A filter that is on says so. An operator who cannot see why the grid is
   short is an operator who reports a bug that is a filter. */
.fx-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 24px;
  padding: 0 4px 0 9px;
  border: 1px solid var(--brand-tint-2);
  border-radius: var(--r-pill);
  background: var(--brand-tint);
  color: var(--brand);
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
}

.fx-chip button {
  display: grid; place-items: center;
  width: 16px; height: 16px;
  border: 0; border-radius: 50%;
  background: transparent;
  color: inherit;
  cursor: pointer;
  opacity: .7;
}
.fx-chip button:hover { opacity: 1; background: var(--brand-tint-2); }

/* ── Badges ───────────────────────────────────────────────────────────── */

.fx-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 8px;
  border-radius: var(--r-pill);
  border: 1px solid transparent;
  font-size: var(--fs-micro);
  font-weight: var(--fw-semibold);
  letter-spacing: .2px;
  white-space: nowrap;
  line-height: 1.6;
}

.fx-badge-ok    { color: var(--ok-fg);    background: var(--ok-bg);    border-color: var(--ok-br); }
.fx-badge-warn  { color: var(--warn-fg);  background: var(--warn-bg);  border-color: var(--warn-br); }
.fx-badge-err   { color: var(--err-fg);   background: var(--err-bg);   border-color: var(--err-br); }
.fx-badge-info  { color: var(--info-fg);  background: var(--info-bg);  border-color: var(--info-br); }
.fx-badge-plum  { color: var(--plum-fg);  background: var(--plum-bg);  border-color: var(--plum-br); }
.fx-badge-slate { color: var(--slate-fg); background: var(--slate-bg); border-color: var(--slate-br); }
.fx-badge-brand { color: var(--brand);    background: var(--brand-tint); border-color: var(--brand-tint-2); }

.fx-badge-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex-shrink: 0; }

/* ── Tabs ─────────────────────────────────────────────────────────────── */

.fx-tabs {
  display: flex;
  gap: 2px;
  border-bottom: 1px solid var(--stroke-2);
  margin-bottom: var(--gap);
  overflow-x: auto;
}

.fx-tab {
  padding: 9px 14px;
  border: 0;
  border-bottom: 2px solid transparent;
  background: transparent;
  color: var(--fg-3);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}

.fx-tab:hover { color: var(--fg-1); }
.fx-tab.active { color: var(--brand); border-bottom-color: var(--brand); font-weight: var(--fw-semibold); }
.fx-tab .fx-tab-count {
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: var(--r-pill);
  background: var(--subtle);
  font-size: var(--fs-micro);
  color: var(--fg-3);
}
.fx-tab.active .fx-tab-count { background: var(--brand-tint); color: var(--brand); }

/* ── Modal ────────────────────────────────────────────────────────────── */

.fx-modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(10,16,22,.46);
  backdrop-filter: blur(2px);
  z-index: 800;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  animation: fx-fade var(--dur-fast) var(--ease-decel);
}

.fx-modal {
  width: 100%;
  max-width: 560px;
  max-height: calc(100vh - 48px);
  display: flex;
  flex-direction: column;
  background: var(--layer);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-64);
  overflow: hidden;
  animation: fx-rise var(--dur-normal) var(--ease-decel);
}

.fx-modal.sm { max-width: 420px; }
.fx-modal.lg { max-width: 820px; }
.fx-modal.xl { max-width: 1140px; }
.fx-modal.full { max-width: calc(100vw - 48px); }

.fx-modal-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 15px 20px;
  border-bottom: 1px solid var(--stroke-2);
}

.fx-modal-title { font-size: var(--fs-subtitle); font-weight: var(--fw-semibold); color: var(--fg-1); }
.fx-modal-sub { font-size: var(--fs-caption); color: var(--fg-3); }
.fx-modal-body { padding: 20px; overflow-y: auto; flex: 1; }
.fx-modal-foot {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 13px 20px;
  border-top: 1px solid var(--stroke-2);
  background: var(--layer-alt);
}
.fx-modal-foot .spacer { flex: 1; }

/* ── Alerts ───────────────────────────────────────────────────────────── */

.fx-alert {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 11px 14px;
  border: 1px solid;
  border-radius: var(--r-md);
  font-size: var(--fs-sm);
  margin-bottom: var(--gap);
}

.fx-alert svg { width: 17px; height: 17px; flex-shrink: 0; margin-top: 1px; }
.fx-alert-body { flex: 1; min-width: 0; }
.fx-alert-title { font-weight: var(--fw-semibold); margin-bottom: 2px; }

.fx-alert-ok   { color: var(--ok-fg);   background: var(--ok-bg);   border-color: var(--ok-br); }
.fx-alert-warn { color: var(--warn-fg); background: var(--warn-bg); border-color: var(--warn-br); }
.fx-alert-err  { color: var(--err-fg);  background: var(--err-bg);  border-color: var(--err-br); }
.fx-alert-info { color: var(--info-fg); background: var(--info-bg); border-color: var(--info-br); }

/* ── Toasts ───────────────────────────────────────────────────────────── */

.fx-toasts {
  position: fixed;
  right: 18px; bottom: 18px;
  z-index: 950;
  display: flex;
  flex-direction: column;
  gap: 9px;
  max-width: 380px;
}

.fx-toast {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--stroke-2);
  border-left: 3px solid var(--brand);
  border-radius: var(--r-md);
  background: var(--layer);
  box-shadow: var(--shadow-16);
  font-size: var(--fs-sm);
  animation: fx-slide-in var(--dur-normal) var(--ease-decel);
}

.fx-toast.ok   { border-left-color: var(--ok-fg); }
.fx-toast.warn { border-left-color: var(--warn-fg); }
.fx-toast.err  { border-left-color: var(--err-fg); }

.fx-toast-title { font-weight: var(--fw-semibold); color: var(--fg-1); }
.fx-toast-body { color: var(--fg-2); }
.fx-toast button { margin-left: auto; }

/* ── Empty, loading, void ─────────────────────────────────────────────── */

.fx-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 46px 24px;
  color: var(--fg-3);
}

.fx-empty-icon {
  width: 46px; height: 46px;
  display: grid; place-items: center;
  border-radius: var(--r-xl);
  background: var(--subtle);
  color: var(--fg-4);
  margin-bottom: 13px;
}

.fx-empty-icon svg { width: 23px; height: 23px; }
.fx-empty h3 { font-size: var(--fs-lg); margin-bottom: 5px; }
.fx-empty p { font-size: var(--fs-sm); max-width: 46ch; margin-bottom: 15px; }

.fx-void { text-align: center; padding: 80px 24px; }
.fx-void-code { font-family: var(--font-mono); font-size: 56px; font-weight: var(--fw-bold); color: var(--stroke-1); }
.fx-void h2 { margin: 6px 0 8px; }
.fx-void p { color: var(--fg-3); margin-bottom: 20px; }

.fx-spinner {
  width: 18px; height: 18px;
  border: 2px solid var(--stroke-1);
  border-top-color: var(--brand);
  border-radius: 50%;
  animation: fx-spin .7s linear infinite;
}

.fx-loading { display: flex; align-items: center; justify-content: center; gap: 10px; padding: 40px; color: var(--fg-3); font-size: var(--fs-sm); }

/* Skeleton rows, so a slow ledger looks like it is arriving rather than like
   it is broken. */
.fx-skel {
  background: linear-gradient(90deg, var(--subtle) 25%, var(--subtle-hover) 37%, var(--subtle) 63%);
  background-size: 400% 100%;
  animation: fx-shimmer 1.4s ease infinite;
  border-radius: var(--r-sm);
  height: 11px;
}

@keyframes fx-spin { to { transform: rotate(360deg); } }
@keyframes fx-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes fx-rise { from { opacity: 0; transform: translateY(10px) scale(.99); } to { opacity: 1; transform: none; } }
@keyframes fx-slide-in { from { opacity: 0; transform: translateX(18px); } to { opacity: 1; transform: none; } }
@keyframes fx-shimmer { from { background-position: 100% 50%; } to { background-position: 0 50%; } }

/* ═══ 4. LEDGER ═══════════════════════════════════════════════════════════ */

.fx-grid-wrap {
  background: var(--layer);
  border: 1px solid var(--stroke-2);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--shadow-2);
}

.fx-grid-scroll { overflow-x: auto; overflow-y: auto; max-height: var(--grid-max-h, none); }

.fx-grid { width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--fs-sm); }

.fx-grid thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  padding: var(--row-pad-y) var(--row-pad-x);
  background: var(--layer-alt);
  border-bottom: 1px solid var(--stroke-1);
  color: var(--fg-3);
  font-size: var(--fs-micro);
  font-weight: var(--fw-bold);
  letter-spacing: .6px;
  text-transform: uppercase;
  text-align: left;
  white-space: nowrap;
  user-select: none;
}

.fx-grid thead th.sortable { cursor: pointer; }
.fx-grid thead th.sortable:hover { color: var(--fg-1); background: var(--subtle-hover); }
.fx-grid thead th .fx-sort { margin-left: 4px; opacity: .55; }
.fx-grid thead th.sorted { color: var(--brand); }
.fx-grid thead th.sorted .fx-sort { opacity: 1; }

.fx-grid tbody td {
  padding: var(--row-pad-y) var(--row-pad-x);
  border-bottom: 1px solid var(--stroke-3);
  color: var(--fg-2);
  height: var(--row-h);
  vertical-align: middle;
}

.fx-grid tbody tr { transition: background var(--dur-faster) var(--ease); }
.fx-grid tbody tr:hover { background: var(--subtle); }
.fx-grid tbody tr.sel { background: var(--brand-tint); }

/* The head of a detail panel — what the record is on the left, its standing on
   the right. Used at the top of the dialogs that open one payroll run, one
   receipt, one asset. */
.fx-detail-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--stroke-2);
}

/* Rows that need calling out.

   Used across the payables, payroll, tax and analysis screens to mark the row
   somebody is meant to act on — a bill past due, a run that has not fired, an
   invoice that never reached the authority. The tints are the same tokens the
   badges use, so the two agree, and they are laid over the hover colour rather
   than under it so hovering a flagged row still reads as hovering. */
.fx-grid tbody tr.fx-row-err  { background: var(--err-bg); }
.fx-grid tbody tr.fx-row-warn { background: var(--warn-bg); }
.fx-grid tbody tr.fx-row-ok   { background: var(--ok-bg); }

.fx-grid tbody tr.fx-row-err:hover,
.fx-grid tbody tr.fx-row-warn:hover,
.fx-grid tbody tr.fx-row-ok:hover { filter: brightness(0.97); }

/* A detail row belonging to the one above it: the account breakdown behind a
   cost centre, and anything else that expands in place. Set back and quieter,
   so the parent rows still read as the list. */
.fx-grid tbody tr.fx-subrow { background: var(--subtle); }
.fx-grid tbody tr.fx-subrow td { border-top: none; font-size: var(--fs-caption); }

.fx-grid tbody tr.clickable { cursor: pointer; }
.fx-grid tbody tr:last-child td { border-bottom: 0; }

/* Zebra is off by default — with tabular figures and a 1px rule it is noise.
   It earns its place only on a wide statement, where the eye has to travel. */
.fx-grid.zebra tbody tr:nth-child(even) { background: var(--layer-alt); }
.fx-grid.zebra tbody tr:nth-child(even):hover { background: var(--subtle); }

/* A row that is not yet posted reads as provisional. */
.fx-grid tbody tr.draft td { color: var(--fg-3); font-style: italic; }
.fx-grid tbody tr.void td { color: var(--fg-4); text-decoration: line-through; }

.fx-grid tfoot td {
  padding: var(--row-pad-y) var(--row-pad-x);
  background: var(--layer-alt);
  border-top: 2px solid var(--stroke-strong);
  color: var(--fg-1);
  font-weight: var(--fw-bold);
  position: sticky;
  bottom: 0;
  z-index: 2;
}

/* A column of money. This is the class the whole sheet exists for. */
.fx-num, .fx-grid td.fx-num, .fx-grid th.fx-num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums lining-nums;
  text-align: right;
  letter-spacing: -.3px;
  white-space: nowrap;
}

.fx-num.neg { color: var(--money-neg); }
.fx-num.zero { color: var(--money-zero); }
.fx-num.dr { color: var(--debit-fg); }
.fx-num.cr { color: var(--credit-fg); }
.fx-num.strong { font-weight: var(--fw-semibold); color: var(--fg-1); }

/* The currency, when it is not the reporting one, is set small and ahead of
   the figure so a foreign-currency line cannot be mistaken for a local one. */
.fx-cur {
  font-size: var(--fs-micro);
  font-weight: var(--fw-semibold);
  color: var(--fg-4);
  margin-right: 4px;
}

.fx-code {
  font-family: var(--font-mono);
  font-size: var(--fs-caption);
  letter-spacing: .2px;
  color: var(--fg-2);
}

.fx-grid td.fx-acct { white-space: nowrap; }
.fx-acct-code { font-family: var(--font-mono); font-size: var(--fs-caption); color: var(--fg-3); margin-right: 7px; }
.fx-acct-name { color: var(--fg-1); font-weight: var(--fw-medium); }

/* Indentation for a chart of accounts. The tree is the account structure — an
   operator should read the hierarchy without expanding anything. */
.fx-lvl-1 { padding-left: 0; }
.fx-lvl-2 { padding-left: 20px; }
.fx-lvl-3 { padding-left: 40px; }
.fx-lvl-4 { padding-left: 60px; }
.fx-lvl-5 { padding-left: 80px; }

.fx-grid tr.group-row td {
  background: var(--subtle);
  font-weight: var(--fw-semibold);
  color: var(--fg-1);
}

.fx-grid tr.total-row td {
  border-top: 1px solid var(--stroke-strong);
  border-bottom: 3px double var(--stroke-strong);
  font-weight: var(--fw-bold);
  color: var(--fg-1);
  background: var(--layer-alt);
}

.fx-grid tr.subtotal-row td {
  border-top: 1px solid var(--stroke-1);
  font-weight: var(--fw-semibold);
  color: var(--fg-1);
}

/* ── Journal line editor ──────────────────────────────────────────────── */

.fx-je {
  border: 1px solid var(--stroke-2);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--layer);
}

.fx-je table { width: 100%; border-collapse: separate; border-spacing: 0; }
.fx-je th {
  padding: 7px 9px;
  background: var(--layer-alt);
  border-bottom: 1px solid var(--stroke-1);
  font-size: var(--fs-micro);
  font-weight: var(--fw-bold);
  text-transform: uppercase;
  letter-spacing: .6px;
  color: var(--fg-3);
  text-align: left;
}

.fx-je td { padding: 3px 4px; border-bottom: 1px solid var(--stroke-3); }
.fx-je td .fx-input, .fx-je td .fx-select { height: 28px; border-color: transparent; background: transparent; }
.fx-je td .fx-input:hover, .fx-je td .fx-select:hover { border-color: var(--stroke-1); background: var(--layer); }
.fx-je td .fx-input:focus, .fx-je td .fx-select:focus { background: var(--layer); }
.fx-je tr:hover td { background: var(--subtle); }

/* The balance strip. A journal that does not balance cannot post, so the
   difference is stated permanently rather than discovered on save. */
.fx-je-balance {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 10px 14px;
  background: var(--layer-alt);
  border-top: 1px solid var(--stroke-1);
  font-size: var(--fs-sm);
  flex-wrap: wrap;
}

.fx-je-balance .item { display: flex; flex-direction: column; gap: 1px; }
.fx-je-balance .k { font-size: var(--fs-micro); text-transform: uppercase; letter-spacing: .5px; color: var(--fg-4); }
.fx-je-balance .v { font-family: var(--font-mono); font-size: var(--fs-body); font-weight: var(--fw-semibold); color: var(--fg-1); }
.fx-je-balance .diff.ok { color: var(--ok-fg); }
.fx-je-balance .diff.bad { color: var(--err-fg); }
.fx-je-balance .spacer { flex: 1; }

/* ── KPI cards ────────────────────────────────────────────────────────── */

.fx-kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: var(--gap);
  margin-bottom: var(--gap);
}

.fx-kpi {
  position: relative;
  padding: var(--card-pad);
  background: var(--layer);
  border: 1px solid var(--stroke-2);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-2);
  overflow: hidden;
  transition: box-shadow var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}

.fx-kpi.clickable { cursor: pointer; }
.fx-kpi.clickable:hover { box-shadow: var(--shadow-8); transform: translateY(-1px); }

/* A hairline in the card's own colour, rather than a coloured card. The
   figure should be the loud thing, not the container. */
.fx-kpi::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: var(--kpi-accent, var(--brand));
}

.fx-kpi-label {
  font-size: var(--fs-micro);
  font-weight: var(--fw-bold);
  letter-spacing: .7px;
  text-transform: uppercase;
  color: var(--fg-4);
  margin-bottom: 7px;
}

.fx-kpi-value {
  font-family: var(--font-mono);
  font-size: var(--fs-figure);
  font-weight: var(--fw-bold);
  color: var(--fg-1);
  letter-spacing: -1px;
  line-height: 1.1;
  font-variant-numeric: tabular-nums lining-nums;
}

.fx-kpi-value .cur { font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--fg-4); margin-right: 4px; letter-spacing: 0; }
.fx-kpi-value.neg { color: var(--money-neg); }

.fx-kpi-meta { display: flex; align-items: center; gap: 7px; margin-top: 7px; font-size: var(--fs-micro); color: var(--fg-3); }

.fx-delta { display: inline-flex; align-items: center; gap: 3px; font-weight: var(--fw-semibold); }
.fx-delta.up { color: var(--ok-fg); }
.fx-delta.down { color: var(--err-fg); }
.fx-delta.flat { color: var(--fg-4); }
.fx-delta svg { width: 12px; height: 12px; }

/* ── Sparkline / bars / meters ────────────────────────────────────────── */

.fx-spark { display: block; width: 100%; height: 34px; margin-top: 10px; overflow: visible; }
.fx-spark path.line { fill: none; stroke: var(--kpi-accent, var(--brand)); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.fx-spark path.area { fill: var(--kpi-accent, var(--brand)); opacity: .10; stroke: none; }

.fx-meter { height: 6px; border-radius: var(--r-pill); background: var(--subtle); overflow: hidden; }
.fx-meter-fill { height: 100%; border-radius: var(--r-pill); background: var(--brand); transition: width var(--dur-slow) var(--ease-decel); }
.fx-meter-fill.ok { background: var(--ok-fg); }
.fx-meter-fill.warn { background: var(--warn-fg); }
.fx-meter-fill.err { background: var(--err-fg); }

/* An ageing bar: five buckets, one row, read left to right as they get older. */
.fx-aging { display: flex; height: 9px; border-radius: var(--r-pill); overflow: hidden; background: var(--subtle); }
.fx-aging span { display: block; height: 100%; }
.fx-aging .b0 { background: var(--ok-fg); }
.fx-aging .b1 { background: #6FA8DC; }
.fx-aging .b2 { background: var(--warn-fg); }
.fx-aging .b3 { background: #D98346; }
.fx-aging .b4 { background: var(--err-fg); }

/* A variance bar reads from a centre line, because over and under budget are
   opposite directions and not two lengths. */
.fx-var { position: relative; height: 14px; background: var(--subtle); border-radius: var(--r-sm); }
.fx-var::before { content: ''; position: absolute; left: 50%; top: 0; bottom: 0; width: 1px; background: var(--stroke-strong); }
.fx-var span { position: absolute; top: 3px; bottom: 3px; border-radius: 2px; }
.fx-var span.over  { background: var(--err-fg); left: 50%; }
.fx-var span.under { background: var(--ok-fg); right: 50%; }

/* ── Statements ───────────────────────────────────────────────────────── */

/* A financial statement is a document, not a grid: it wants a measure, a
   heading block and rules that mean something. */
.fx-statement {
  background: var(--layer);
  border: 1px solid var(--stroke-2);
  border-radius: var(--r-lg);
  padding: 30px 34px;
  box-shadow: var(--shadow-2);
  max-width: 1000px;
  margin: 0 auto;
}

.fx-statement-head { text-align: center; margin-bottom: 22px; padding-bottom: 16px; border-bottom: 2px solid var(--stroke-strong); }
.fx-statement-org { font-family: var(--font-display); font-size: var(--fs-title-sm); font-weight: var(--fw-bold); color: var(--fg-1); }
.fx-statement-name { font-size: var(--fs-lg); font-weight: var(--fw-semibold); color: var(--fg-1); margin-top: 3px; }
.fx-statement-period { font-size: var(--fs-sm); color: var(--fg-3); margin-top: 3px; }
.fx-statement-scope { font-size: var(--fs-caption); color: var(--fg-4); margin-top: 5px; }

.fx-statement table { width: 100%; border-collapse: collapse; font-size: var(--fs-body); }
.fx-statement td { padding: 5px 8px; }
.fx-statement td.fx-num { width: 150px; }

.fx-statement tr.section td {
  padding-top: 18px;
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: var(--fw-bold);
  color: var(--fg-1);
}

.fx-statement tr.line td.label { padding-left: 20px; color: var(--fg-2); }
.fx-statement tr.line:hover { background: var(--subtle); cursor: pointer; }

.fx-statement tr.subtotal td { border-top: 1px solid var(--stroke-1); font-weight: var(--fw-semibold); color: var(--fg-1); }
.fx-statement tr.total td {
  border-top: 1px solid var(--stroke-strong);
  border-bottom: 3px double var(--stroke-strong);
  font-weight: var(--fw-bold);
  color: var(--fg-1);
  font-size: var(--fs-lg);
}

.fx-statement tr.spacer td { height: 10px; padding: 0; }

.fx-statement-foot { margin-top: 24px; padding-top: 12px; border-top: 1px solid var(--stroke-2); font-size: var(--fs-micro); color: var(--fg-4); display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; }

/* ── Drilldown panel ──────────────────────────────────────────────────── */

.fx-drill {
  position: fixed;
  top: 0; right: 0; bottom: 0;
  width: min(720px, 100vw);
  background: var(--layer);
  border-left: 1px solid var(--stroke-2);
  box-shadow: var(--shadow-64);
  z-index: 700;
  display: flex;
  flex-direction: column;
  animation: fx-slide-panel var(--dur-normal) var(--ease-decel);
}

@keyframes fx-slide-panel { from { transform: translateX(100%); } to { transform: none; } }

.fx-drill-head { display: flex; align-items: center; gap: 12px; padding: 15px 20px; border-bottom: 1px solid var(--stroke-2); }
.fx-drill-body { flex: 1; overflow-y: auto; padding: 20px; }
.fx-drill-foot { padding: 13px 20px; border-top: 1px solid var(--stroke-2); background: var(--layer-alt); display: flex; gap: 8px; }

/* ── Detail lists ─────────────────────────────────────────────────────── */

.fx-details { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 14px 22px; margin: 0; }
.fx-detail { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.fx-detail dt { font-size: var(--fs-micro); font-weight: var(--fw-semibold); letter-spacing: .5px; text-transform: uppercase; color: var(--fg-4); }
.fx-detail dd { margin: 0; font-size: var(--fs-body); color: var(--fg-1); word-break: break-word; }
.fx-detail dd.fx-num { text-align: left; }

/* ── Timeline / audit trail ───────────────────────────────────────────── */

.fx-timeline { position: relative; padding-left: 22px; }
.fx-timeline::before { content: ''; position: absolute; left: 6px; top: 4px; bottom: 4px; width: 1px; background: var(--stroke-2); }
.fx-tl-item { position: relative; padding-bottom: 16px; }
.fx-tl-item::before {
  content: '';
  position: absolute;
  left: -20px; top: 4px;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--layer);
  border: 2px solid var(--stroke-strong);
}
.fx-tl-item.ok::before { border-color: var(--ok-fg); }
.fx-tl-item.err::before { border-color: var(--err-fg); }
.fx-tl-when { font-size: var(--fs-micro); color: var(--fg-4); }
.fx-tl-what { font-size: var(--fs-sm); color: var(--fg-1); font-weight: var(--fw-medium); }
.fx-tl-who { font-size: var(--fs-caption); color: var(--fg-3); }

/* ── Checklist (period close) ─────────────────────────────────────────── */

.fx-checklist { display: flex; flex-direction: column; }
.fx-check-item {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding: 11px 4px;
  border-bottom: 1px solid var(--stroke-3);
}
.fx-check-item:last-child { border-bottom: 0; }
.fx-check-mark {
  width: 20px; height: 20px;
  flex-shrink: 0;
  display: grid; place-items: center;
  border-radius: 50%;
  border: 1.5px solid var(--stroke-1);
  color: transparent;
  margin-top: 1px;
}
.fx-check-item.done .fx-check-mark { background: var(--ok-fg); border-color: var(--ok-fg); color: #fff; }
.fx-check-item.blocked .fx-check-mark { border-color: var(--err-fg); color: var(--err-fg); }
.fx-check-item.done .fx-check-what { color: var(--fg-3); text-decoration: line-through; }
.fx-check-what { font-size: var(--fs-sm); color: var(--fg-1); font-weight: var(--fw-medium); }
.fx-check-why { font-size: var(--fs-caption); color: var(--fg-3); }

/* ── Pagination ───────────────────────────────────────────────────────── */

.fx-pager {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border-top: 1px solid var(--stroke-2);
  background: var(--layer-alt);
  font-size: var(--fs-caption);
  color: var(--fg-3);
  flex-wrap: wrap;
}
.fx-pager .spacer { flex: 1; }
.fx-pager-pages { display: flex; gap: 3px; }
.fx-pager-pages button {
  min-width: 27px; height: 27px;
  padding: 0 6px;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--fg-2);
  font-size: var(--fs-caption);
  cursor: pointer;
}
.fx-pager-pages button:hover { background: var(--subtle-hover); }
.fx-pager-pages button.active { background: var(--brand); border-color: var(--brand); color: var(--brand-on); font-weight: var(--fw-semibold); }
.fx-pager-pages button:disabled { color: var(--fg-4); cursor: not-allowed; background: transparent; }

/* ── Sign-in ──────────────────────────────────────────────────────────── */

.fx-login-shell {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 24px;
  background:
    radial-gradient(1100px 620px at 12% -8%, var(--brand-tint) 0%, transparent 62%),
    radial-gradient(900px 520px at 108% 108%, var(--accent-tint) 0%, transparent 58%),
    var(--canvas);
}

.fx-login-card {
  width: min(880px, 100%);
  display: grid;
  grid-template-columns: 340px 1fr;
  background: var(--layer);
  border: 1px solid var(--stroke-2);
  border-radius: var(--r-2xl);
  box-shadow: var(--shadow-28);
  overflow: hidden;
}

.fx-login-brand {
  padding: 40px 32px;
  background: linear-gradient(160deg, var(--brand) 0%, var(--brand-pressed) 72%, var(--accent) 190%);
  color: #fff;
  display: flex;
  flex-direction: column;
}

.fx-login-logo { width: 42px; height: 42px; margin-bottom: 18px; filter: brightness(0) invert(1); }
.fx-login-brand-title { font-family: var(--font-display); font-size: var(--fs-title); font-weight: var(--fw-bold); letter-spacing: -.4px; }
.fx-login-brand-sub { font-size: var(--fs-caption); font-weight: var(--fw-bold); letter-spacing: 1.4px; text-transform: uppercase; opacity: .78; margin-top: 2px; }
.fx-login-rule { width: 40px; height: 2px; background: rgba(255,255,255,.4); margin: 20px 0; }
.fx-login-copy { font-size: var(--fs-sm); line-height: 1.65; opacity: .88; }
.fx-login-points { margin-top: auto; padding-top: 26px; display: flex; flex-direction: column; gap: 9px; font-size: var(--fs-caption); opacity: .84; }
.fx-login-point { display: flex; align-items: center; gap: 8px; }
.fx-login-point svg { width: 14px; height: 14px; flex-shrink: 0; }

.fx-login-form { padding: 40px 38px; display: flex; flex-direction: column; }
.fx-login-head { font-family: var(--font-display); font-size: var(--fs-title-sm); font-weight: var(--fw-semibold); color: var(--fg-1); }
.fx-login-sub { font-size: var(--fs-sm); color: var(--fg-3); margin-bottom: 22px; }

@media (max-width: 720px) {
  .fx-login-card { grid-template-columns: 1fr; }
  .fx-login-brand { padding: 26px 28px; }
  .fx-login-points { display: none; }
}

/* ═══ 5. UTILITIES ════════════════════════════════════════════════════════ */

.fx-row { display: flex; align-items: center; gap: 8px; }
.fx-row.wrap { flex-wrap: wrap; }
.fx-col { display: flex; flex-direction: column; gap: 8px; }
.fx-stack { display: flex; flex-direction: column; gap: var(--gap); }
.fx-spacer { flex: 1; }

.fx-grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: var(--gap); }
.fx-grid-3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: var(--gap); }
.fx-grid-4 { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--gap); }
.fx-form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 14px; }
.fx-span-2 { grid-column: span 2; }
.fx-span-full { grid-column: 1 / -1; }

.fx-mt-0 { margin-top: 0; } .fx-mt-1 { margin-top: 6px; } .fx-mt-2 { margin-top: 12px; } .fx-mt-3 { margin-top: 20px; }
.fx-mb-0 { margin-bottom: 0; } .fx-mb-1 { margin-bottom: 6px; } .fx-mb-2 { margin-bottom: 12px; } .fx-mb-3 { margin-bottom: 20px; }

.fx-muted { color: var(--fg-3); }
.fx-faint { color: var(--fg-4); }
.fx-strong { font-weight: var(--fw-semibold); color: var(--fg-1); }
.fx-sm { font-size: var(--fs-sm); }
.fx-xs { font-size: var(--fs-caption); }
.fx-micro { font-size: var(--fs-micro); }
.fx-right { text-align: right; }
.fx-center { text-align: center; }
.fx-nowrap { white-space: nowrap; }
.fx-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fx-hidden { display: none !important; }

.fx-divider { height: 1px; background: var(--stroke-2); margin: var(--gap) 0; border: 0; }

/* ── Responsive shell ─────────────────────────────────────────────────── */

@media (max-width: 1024px) {
  .fx-sidebar {
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 600;
    transform: translateX(-100%);
    box-shadow: var(--shadow-28);
  }
  .fx-sidebar.open { transform: none; }
  .fx-omnibox { display: none; }
}

@media (max-width: 640px) {
  :root { --content-pad: 12px; }
  .fx-page-actions { width: 100%; }
  .fx-statement { padding: 20px 16px; }
  .fx-scope-kind { display: none; }
}

/* ── Print ────────────────────────────────────────────────────────────────
   A statement is printed and filed. What leaves this portal on paper has to be
   the statement and nothing else: no sidebar, no toolbar, no buttons, and
   black on white whatever theme the screen was in. */

@media print {
  :root, :root[data-theme="dark"] {
    --layer: #fff; --layer-alt: #fff; --canvas: #fff; --subtle: #fff;
    --fg-1: #000; --fg-2: #1a1a1a; --fg-3: #444; --fg-4: #666;
    --stroke-1: #999; --stroke-2: #bbb; --stroke-3: #ddd; --stroke-strong: #444;
    --debit-fg: #000; --credit-fg: #000; --money-neg: #000;
    --shadow-2: none; --shadow-4: none; --shadow-8: none;
  }

  .fx-sidebar, .fx-topbar, .fx-toolbar, .fx-page-actions, .fx-toasts,
  .fx-pager, .fx-tabs, .fx-btn, .fx-drill, .fx-modal-backdrop,
  .fx-palette-backdrop, #blazor-error-ui { display: none !important; }

  .fx-shell { display: block; height: auto; overflow: visible; }
  .fx-content { overflow: visible; padding: 0; }
  .fx-card, .fx-grid-wrap, .fx-statement { border: 0; box-shadow: none; padding: 0; max-width: none; }

  .fx-grid thead th { background: #fff; border-bottom: 1px solid #444; color: #000; }
  .fx-grid tbody tr { break-inside: avoid; }
  thead { display: table-header-group; }
  tfoot { display: table-footer-group; }

  @page { margin: 14mm; }
}

/* Blazor's own error strip, restyled so a disconnect does not look like a
   crash in somebody else's product. */
#blazor-error-ui {
  display: none;
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 1000;
  padding: 11px 18px;
  background: var(--warn-bg);
  border-top: 2px solid var(--warn-fg);
  color: var(--warn-fg);
  font-size: var(--fs-sm);
  box-shadow: var(--shadow-16);
}

#blazor-error-ui .reload { color: var(--warn-fg); font-weight: var(--fw-semibold); text-decoration: underline; margin-left: 10px; }
#blazor-error-ui .dismiss { float: right; cursor: pointer; padding: 0 6px; }
