/* FiscalTrack — stylesheet
   Institutional green and warm neutrals. DM Sans for text, DM Mono for money.
   Brand colors are injected per tenant as --brand / --sb-start / --sb-end.
   -------------------------------------------------------------------------- */

:root {
  --green-900:#0d3320; --green-800:#1a6b4a; --green-700:#217a57;
  --green-100:#e8f5ee; --green-50:#f4faf7;

  /* The old --green-700 was #2d9e71, which is 3.36:1 against white: fine as a
     decorative fill, below AA the moment it carries text or a white label.
     Darkened to 5.6:1. The bright tone is kept as --green-accent for things
     that are never text. */
  --green-accent:#2d9e71;
  --navy-800:#0c447c;  --navy-100:#e6f1fb;
  --amber-800:#854f0b; --amber-100:#faeeda;
  --red-800:#a32d2d;   --red-100:#fcebeb;

  --gray-900:#1a1a1a; --gray-800:#2c2c2a; --gray-700:#464540;
  --gray-600:#5f5e5a; --gray-500:#6e6d67;

  /* --gray-400 is 3.6:1 and must never carry text. Kept for disabled states
     and icon strokes only; --gray-450 is the lightest that still passes. */
  --gray-450:#706f69; --gray-400:#888780;
  --gray-200:#d3d1c7; --gray-100:#f1efe8;

  /* Borders that define a control have to reach 3:1 under WCAG 1.4.11.
     --gray-200 is 1.5:1 and stays for decorative rules and table lines;
     --border-strong is for input, select and button edges, where somebody
     with low vision has to see where the field is. */
  --border-strong:#8a8880;

  /* Hover has to move AWAY from the surface, and which way that is depends on
     the theme. Reusing --gray-50 meant rows went lighter in the light theme
     and darker in the dark one, where the page is darker than the card, so
     hovering made a row recede instead of lift. */
  --hover:#f1efe8;
  --hover-strong:#e7e4da;
  --gray-50:#f8f7f4;  --white:#ffffff;

  /* Added because these were being referenced before they existed. An
     undefined custom property resolves to nothing, which meant the public
     store header was white text on no background at all. */
  --green-600:#1f7d55;
  --ink-900:#14211c;

  --brand:var(--green-800);
  --brand-accent:var(--green-700);
  --sb-start:var(--green-900);
  --sb-end:var(--green-800);

  --font-sans:'DM Sans',system-ui,-apple-system,'Segoe UI',sans-serif;
  --font-mono:'DM Mono','SFMono-Regular',Menlo,monospace;

  --radius-sm:4px; --radius-md:8px; --radius-lg:12px;
  --shadow-sm:0 1px 3px rgba(0,0,0,.06),0 1px 2px rgba(0,0,0,.04);
  --shadow-md:0 4px 12px rgba(0,0,0,.08);
  --shadow-lg:0 12px 32px rgba(0,0,0,.12);

  --sidebar-width:236px;
}

/* ── Dark mode ─────────────────────────────────────────────────────────────
   Follows the operating system by default, and can be overridden per person
   with data-theme on the root element.

   Not an inversion. Pure white on pure black causes halation, which is worse
   for people with astigmatism than the light theme was, so the surfaces are
   near-black and the text is off-white. Every pair below is checked by the
   same audit as the light theme.                                          */

/*
 * Dark follows the device ONLY when somebody has asked for that. The default
 * is light.
 *
 * Following the operating system automatically sounds respectful and is not:
 * plenty of people run a dark desktop and still expect a business application
 * to look like paper, and being handed a dark ledger they did not choose
 * reads as broken rather than considerate.
 */
@media (prefers-color-scheme: dark) {
  :root[data-theme="system"] {
    --gray-900:#f2f1ec; --gray-800:#e4e2db; --gray-700:#cfcdc5;
    --gray-600:#b0aea6; --gray-500:#a3a199; --gray-450:#9b9990;
    --gray-400:#8d8b83;
    /* Page, card and raised surface, with real distance between them. They
       were eight values apart, so a card did not read as a card. */
    --gray-200:#3f444a; --gray-100:#2b3036; --gray-50:#14161a;
    --white:#20242a;
    --hover:#2b3036; --hover-strong:#353b43;

    --green-900:#0a2418; --green-800:#5fce9f; --green-700:#7ddcb2;
    --green-600:#4dbd8c; --green-accent:#7ddcb2;
    --green-100:#183a2b; --green-50:#14261d;

    --navy-800:#8ec2f0; --navy-100:#152a3d;
    --amber-800:#e8b667; --amber-100:#3a2e18;
    --red-800:#f08d8d;   --red-100:#3d1f1f;

    --border-strong:#6f716d;
    --ink-900:#101314;

    --shadow-sm:0 1px 3px rgba(0,0,0,.5);
    --shadow-md:0 4px 12px rgba(0,0,0,.55);
    --shadow-lg:0 12px 32px rgba(0,0,0,.6);
  }
}

:root[data-theme="dark"] {
  --gray-900:#f2f1ec; --gray-800:#e4e2db; --gray-700:#cfcdc5;
  --gray-600:#b0aea6; --gray-500:#a3a199; --gray-450:#9b9990;
  --gray-400:#8d8b83;
  --gray-200:#3f444a; --gray-100:#2b3036; --gray-50:#14161a;
  --white:#20242a;
  --hover:#2b3036; --hover-strong:#353b43;

  --green-900:#0a2418; --green-800:#5fce9f; --green-700:#7ddcb2;
  --green-600:#4dbd8c; --green-accent:#7ddcb2;
  --green-100:#183a2b; --green-50:#14261d;

  --navy-800:#8ec2f0; --navy-100:#152a3d;
  --amber-800:#e8b667; --amber-100:#3a2e18;
  --red-800:#f08d8d;   --red-100:#3d1f1f;

  --border-strong:#6f716d;
  --ink-900:#101314;

  --shadow-sm:0 1px 3px rgba(0,0,0,.5);
  --shadow-md:0 4px 12px rgba(0,0,0,.55);
  --shadow-lg:0 12px 32px rgba(0,0,0,.6);
}

/* In dark mode the brand green becomes a light tint, so a filled button needs
   dark text on it rather than white. */
@media (prefers-color-scheme: dark) {
  :root[data-theme="system"] .btn--primary,
  :root[data-theme="system"] .cart-pip,
  :root[data-theme="system"] .store-cart--full { color:#082016; }
}
:root[data-theme="dark"] .btn--primary,
:root[data-theme="dark"] .cart-pip,
:root[data-theme="dark"] .store-cart--full { color:#082016; }

/* The sidebar keeps its own dark gradient in both themes, so its text stays
   light regardless. */
:root[data-theme="dark"] .sidebar,
:root[data-theme="dark"] .store-bar { color:#fff; }


*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}

body{
  margin:0;background:var(--gray-50);color:var(--gray-900);
  font-family:var(--font-sans);font-size:15px;line-height:1.55;
  -webkit-font-smoothing:antialiased;
}

h1,h2,h3,h4{font-weight:700;letter-spacing:-.015em;margin:0}
a{color:var(--brand);text-decoration:none}
a:hover{text-decoration:underline}
.icon{flex:none;display:block}

.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.skip{position:absolute;left:-9999px;top:0;z-index:100;background:var(--brand);color:#fff;padding:10px 16px}
.skip:focus{left:0}
:where(a,button,input,select,textarea,[tabindex]):focus-visible{outline:2px solid var(--brand-accent);outline-offset:2px;border-radius:var(--radius-sm)}

/* ── layout ───────────────────────────────────────────────────────────── */

.app{display:flex;min-height:100vh}

.sidebar{
  width:var(--sidebar-width);flex:none;
  background:linear-gradient(170deg,var(--sb-start),var(--sb-end));
  color:rgba(255,255,255,.82);
  display:flex;flex-direction:column;
  position:sticky;top:0;height:100vh;
}

.brand{display:flex;align-items:center;gap:11px;padding:18px 16px;color:#fff}
.brand:hover{text-decoration:none}
.brand-mark{
  width:38px;height:38px;border-radius:var(--radius-md);flex:none;
  background:rgba(255,255,255,.16);border:1px solid rgba(255,255,255,.14);
  display:grid;place-items:center;font-weight:700;font-size:14px;letter-spacing:.02em;
}
.brand-text{display:grid;line-height:1.3;min-width:0}
.brand-text strong{font-size:15px}
.brand-text small{font-size:11.5px;color:rgba(255,255,255,.78);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.nav-scroll{flex:1;overflow-y:auto;padding:4px 10px 12px}
.nav-section{
  font-size:10.5px;font-weight:500;letter-spacing:.11em;text-transform:uppercase;
  /* Section headings were .42, which is 2.6:1 at the foot of the sidebar
     gradient. Raised to the same value as the nav links. */
  color:rgba(255,255,255,.78);padding:14px 8px 6px;
}
.nav{display:grid;gap:1px}
.nav-item{
  display:flex;align-items:center;gap:10px;padding:9px 10px;
  border-radius:var(--radius-md);color:rgba(255,255,255,.82);font-size:14px;
  transition:background .13s ease,color .13s ease;
}
.nav-item:hover{background:rgba(255,255,255,.16);color:#fff;text-decoration:none}
.nav-item.is-active{background:rgba(255,255,255,.24);color:#fff;font-weight:600}

.sb-user{
  display:flex;align-items:center;gap:10px;padding:12px 16px;
  border-top:1px solid rgba(255,255,255,.12);color:#fff;
}
.sb-user:hover{background:rgba(255,255,255,.14);text-decoration:none}
.sb-user-text{display:grid;line-height:1.3;min-width:0}
.sb-user-text strong{font-size:13.5px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sb-user-text small{font-size:11px;color:rgba(255,255,255,.78)}
.avatar{
  width:32px;height:32px;border-radius:50%;flex:none;
  background:rgba(255,255,255,.2);display:grid;place-items:center;
  font-size:12.5px;font-weight:700;
}

.main{flex:1;min-width:0}
.page{max-width:1280px;margin:0 auto;padding:26px 32px 72px}

.menu-toggle{
  display:none;position:sticky;top:10px;z-index:20;margin:10px 0 0 12px;
  width:40px;height:40px;border:1px solid var(--gray-200);border-radius:var(--radius-md);
  background:var(--white);color:var(--gray-600);cursor:pointer;place-items:center;
}

/* ── page header ──────────────────────────────────────────────────────── */

.page-head{display:flex;align-items:flex-start;justify-content:space-between;gap:20px;margin-bottom:22px;flex-wrap:wrap}
.page-head h1{font-size:27px;margin-bottom:3px}
.page-head p{margin:0;color:var(--gray-450);font-size:14.5px}
.head-actions{display:flex;gap:9px;flex-wrap:wrap}

.backlink{display:inline-flex;align-items:center;gap:7px;color:var(--gray-600);font-size:13.5px;margin-bottom:12px}
.backlink:hover{color:var(--brand);text-decoration:none}

.section-title{font-size:11.5px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--gray-600)}

/* ── stat cards ───────────────────────────────────────────────────────── */

.stats{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-bottom:20px}
.stat{
  border-radius:var(--radius-lg);padding:16px 18px;border:1px solid var(--gray-200);
  background:var(--white);min-height:104px;display:grid;align-content:space-between;
  box-shadow:var(--shadow-sm);
}
.stat-top{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}
.stat-label{font-size:11px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--gray-600)}
.stat-value{font-family:var(--font-mono);font-size:27px;font-weight:500;letter-spacing:-.02em}
.stat-chip{width:30px;height:30px;border-radius:var(--radius-md);display:grid;place-items:center}

/* Tinted from the tokens, never hard-coded. The expense and balance cards
   were on literal hex, so in dark mode they stayed light while the income
   card went dark: three cards side by side in two different themes. */
.stat--income{background:var(--green-50);border-color:var(--green-100)}
.stat--income .stat-value{color:var(--green-800)}
.stat--income .stat-chip{background:var(--green-100);color:var(--green-800)}

.stat--expense{background:var(--red-100);border-color:var(--red-100)}
.stat--expense .stat-value{color:var(--red-800)}
.stat--expense .stat-chip{background:var(--white);color:var(--red-800)}

.stat--balance{background:var(--navy-100);border-color:var(--navy-100)}
.stat--balance .stat-value{color:var(--navy-800)}
.stat--balance .stat-chip{background:var(--white);color:var(--navy-800)}
.stat--balance.is-negative .stat-value{color:var(--red-800)}

/* ── cards & tables ───────────────────────────────────────────────────── */

.card{background:var(--white);border:1px solid var(--gray-200);border-radius:var(--radius-lg);box-shadow:var(--shadow-sm);overflow:hidden}
.card-head{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:14px 20px;border-bottom:1px solid var(--gray-100)}
.card-count{font-size:12.5px;color:var(--gray-450)}
.card-body{padding:20px}
.stack{display:grid;gap:16px}
.grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px}

.table-scroll{overflow-x:auto}
table.data{width:100%;border-collapse:collapse;font-size:14px}
table.data th{
  text-align:left;font-size:10.5px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;
  color:var(--gray-450);padding:10px 12px;background:var(--gray-50);
  border-bottom:1px solid var(--gray-100);white-space:nowrap;
}
table.data td{padding:12px;border-bottom:1px solid var(--gray-100);color:var(--gray-800);vertical-align:middle}
table.data tbody tr:last-child td{border-bottom:0}
table.data tbody tr:hover{background:var(--hover)}
th.right,td.right{text-align:right}
th.first,td.first{padding-left:20px}
th.last,td.last{padding-right:20px}

.row-title{display:flex;align-items:center;gap:9px;color:var(--gray-900);font-weight:500}
.dot{width:8px;height:8px;border-radius:50%;flex:none}
.dot--income{background:var(--green-700)}
.dot--expense{background:var(--red-800)}

.mono{font-family:var(--font-mono);font-variant-numeric:tabular-nums;white-space:nowrap}
.amt--income{color:var(--green-800);font-weight:500}
.amt--expense{color:var(--red-800);font-weight:500}
.muted{color:var(--gray-450)}
.seq{font-family:var(--font-mono);font-size:12px;color:var(--gray-450)}

.chip{display:inline-flex;align-items:center;gap:6px;padding:3px 9px;border-radius:99px;background:var(--gray-100);color:var(--gray-600);font-size:12px;white-space:nowrap}
.chip-dot{width:6px;height:6px;border-radius:50%}
.chip--ok{background:var(--green-100);color:var(--green-800)}
.chip--warn{background:var(--amber-100);color:var(--amber-800)}
.chip--bad{background:var(--red-100);color:var(--red-800)}
.chip--info{background:var(--navy-100);color:var(--navy-800)}
.chip--void{background:var(--gray-100);color:var(--gray-450);text-decoration:line-through}

tr.is-void td{opacity:.55}

/* ── filters ──────────────────────────────────────────────────────────── */

.filterbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:16px}
.pill{
  display:inline-flex;align-items:center;gap:7px;padding:7px 15px;border-radius:99px;
  border:1px solid var(--gray-200);background:var(--white);color:var(--gray-600);
  font-size:13.5px;cursor:pointer;transition:all .13s ease;
}
.pill:hover{border-color:var(--gray-450);color:var(--gray-900);text-decoration:none}
.pill.is-active{background:var(--green-900);border-color:var(--green-900);color:#fff}
.pill-dot{width:7px;height:7px;border-radius:50%}

/* ── forms ────────────────────────────────────────────────────────────── */

.form-card{max-width:660px}
.form-grid{display:grid;gap:15px}
.form-row{display:grid;grid-template-columns:1fr 1fr;gap:13px;align-items:start}

/*
 * align-content:start is the whole fix for a family of alignment bugs.
 *
 * .field is a grid inside a grid. Grid children stretch to equal height by
 * default, so where one field carried a hint and its neighbour did not, the
 * neighbour had the same height to fill with one fewer row: its input grew
 * taller to take up the slack. Two inputs side by side, visibly different
 * heights, for no reason a person could see.
 *
 * Rows now take their natural height and pack to the top, so labels line up
 * with labels, inputs with inputs, and a hint simply hangs below.
 */
.field{display:grid;gap:5px;align-content:start}
.field>label{font-size:12.5px;color:var(--gray-600);font-weight:500}
.req{color:var(--red-800)}

.input,select.input,textarea.input{
  width:100%;padding:10px 12px;border:1px solid var(--border-strong);border-radius:var(--radius-md);
  background:var(--white);color:var(--gray-900);font:inherit;transition:border-color .13s,box-shadow .13s;
}
.input::placeholder{color:var(--gray-450)}
.input:focus{outline:none;border-color:var(--brand);box-shadow:0 0 0 3px rgba(26,107,74,.13)}
.input.has-error{border-color:var(--red-800)}
textarea.input{min-height:84px;resize:vertical}
select.input{
  appearance:none;padding-right:32px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' stroke='%23888780' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='m4 6 4 4 4-4'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 11px center;
}
.input.mono{font-family:var(--font-mono)}
.field-error{font-size:12px;color:var(--red-800)}
.field-hint{font-size:12px;color:var(--gray-450)}

/* A color picker does not want the full width of a form column. Sized to
   the swatch, with the field's own label still doing the aligning. */
.input[type="color"]{width:76px;height:40px;padding:4px;cursor:pointer}

/* Native date and time controls carry their own picker button, which makes
   them a hair taller than a text input unless the box sizing is pinned. */
.input[type="date"],.input[type="time"],.input[type="datetime-local"]{
  min-height:41px;line-height:1.2}

/* A textarea beside a single-line input will never match, so stop pretending:
   two rows is a deliberate size rather than an accident. */
.form-row textarea.input{min-height:82px}

.toggle{display:grid;grid-template-columns:1fr 1fr;background:var(--gray-100);border-radius:var(--radius-md);padding:3px;gap:3px}
.toggle input{position:absolute;opacity:0;pointer-events:none}
.toggle label{text-align:center;padding:8px;border-radius:var(--radius-sm);font-size:14px;font-weight:500;color:var(--gray-600);cursor:pointer;transition:all .13s}
.toggle input:checked+label{background:var(--white);box-shadow:var(--shadow-sm)}
.toggle input#kind-income:checked+label{color:var(--green-800)}
.toggle input#kind-expense:checked+label{color:var(--red-800)}

.check-row{display:flex;align-items:flex-start;gap:9px;font-size:14px;color:var(--gray-800)}
.check-row input{margin-top:3px;accent-color:var(--brand)}

.form-actions{display:flex;gap:9px;align-items:center;margin-top:4px;flex-wrap:wrap}

.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  padding:10px 17px;border-radius:var(--radius-md);border:1px solid transparent;
  font:inherit;font-weight:500;cursor:pointer;transition:all .13s;
}
.btn:hover{text-decoration:none}
.btn--primary{background:var(--brand);color:#fff}
.btn--primary:hover{background:var(--green-900)}
.btn--ghost{background:var(--white);border-color:var(--border-strong);color:var(--gray-600)}
.btn--ghost:hover{border-color:var(--gray-450);color:var(--gray-900)}
.btn--danger{background:var(--white);border-color:var(--red-100);color:var(--red-800)}
.btn--danger:hover{background:var(--red-100)}
.btn--sm{padding:6px 12px;font-size:13px}
.btn--wide{flex:1}

.icon-btn{border:0;background:none;padding:6px;border-radius:var(--radius-sm);color:var(--gray-450);cursor:pointer;display:inline-grid;place-items:center}
.icon-btn:hover{color:var(--red-800);background:var(--red-100)}

/* ── flashes & callouts ───────────────────────────────────────────────── */

.flash{padding:11px 15px;border-radius:var(--radius-md);margin-bottom:16px;font-size:14px;border:1px solid}
.flash--success{background:var(--green-100);border-color:var(--green-100);color:var(--green-900)}
.flash--error{background:var(--red-100);border-color:var(--red-100);color:var(--red-800)}

.callout{padding:14px 16px;border-radius:var(--radius-md);border:1px solid;display:flex;gap:11px;align-items:flex-start;font-size:14px}
.callout--ok{background:var(--green-50);border-color:var(--green-100);color:var(--green-900)}
.callout--warn{background:var(--amber-100);border-color:var(--amber-100);color:var(--amber-800)}
.callout--bad{background:var(--red-100);border-color:var(--red-100);color:var(--red-800)}
.callout strong{display:block;margin-bottom:2px}

.upsell{
  border:1px dashed #b9d6c8;background:var(--green-50);border-radius:var(--radius-lg);
  padding:24px;display:grid;gap:8px;justify-items:start;
}
.upsell .icon{color:var(--brand)}
.upsell h2{font-size:19px}
.upsell p{margin:0;color:var(--gray-600)}

.empty{text-align:center;padding:48px 24px;display:grid;gap:9px;justify-items:center}
.empty-mark{width:48px;height:48px;border-radius:var(--radius-lg);background:var(--green-100);color:var(--brand);display:grid;place-items:center}
.empty h2{font-size:17px;margin-top:4px}
.empty p{margin:0;color:var(--gray-450);max-width:46ch}

/* ── verification-specific ────────────────────────────────────────────── */

.variance{font-family:var(--font-mono);font-size:26px;font-weight:500}
.variance--ok{color:var(--green-800)}
.variance--bad{color:var(--red-800)}

.count-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-bottom:16px}
.count-box{border:1px solid var(--gray-200);border-radius:var(--radius-md);padding:14px;background:var(--white)}
.count-box .label{font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--gray-450);display:block;margin-bottom:4px}
.count-box .value{font-family:var(--font-mono);font-size:20px;font-weight:500}

.sig-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.sig{border:1px solid var(--gray-200);border-radius:var(--radius-md);padding:14px;background:var(--gray-50)}
.sig .label{font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--gray-450)}
.sig .name{font-weight:500;margin-top:3px}
.sig .when{font-size:12.5px;color:var(--gray-450)}

.hashline{font-family:var(--font-mono);font-size:11.5px;color:var(--gray-450);word-break:break-all}

/* ── charts ───────────────────────────────────────────────────────────── */

.chart-box{position:relative;height:280px;margin-top:4px}
.legend{display:flex;flex-wrap:wrap;gap:13px;justify-content:center;margin-top:10px;font-size:12.5px;color:var(--gray-600)}
.legend span{display:inline-flex;align-items:center;gap:6px}
.legend i{width:10px;height:10px;border-radius:3px}

/* ── plan matrix ──────────────────────────────────────────────────────── */

.tier-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-bottom:20px}
.tier{background:var(--white);border:1px solid var(--gray-200);border-radius:var(--radius-lg);padding:18px;display:grid;gap:5px;align-content:start}
.tier.is-current{border-color:var(--brand);box-shadow:0 0 0 3px rgba(26,107,74,.1)}
.tier h3{font-size:17px}
.tier .price{font-family:var(--font-mono);font-size:24px;font-weight:500}
.tier .price small{font-size:12.5px;color:var(--gray-450);font-family:var(--font-sans)}
.tier p{margin:0;font-size:13px;color:var(--gray-450)}
.tier .badge{justify-self:start;margin-top:5px;font-size:10.5px;font-weight:500;letter-spacing:.06em;text-transform:uppercase;background:var(--green-100);color:var(--green-800);padding:3px 8px;border-radius:var(--radius-sm)}

table.matrix{width:100%;border-collapse:collapse;font-size:13.5px}
table.matrix th,table.matrix td{padding:10px 12px;border-bottom:1px solid var(--gray-100);text-align:center}
table.matrix th:first-child,table.matrix td:first-child{text-align:left}
table.matrix thead th{font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--gray-450)}
.tick{color:var(--green-700);font-weight:700}
.cross{color:var(--gray-200)}

/* ── login / installer ────────────────────────────────────────────────── */

.body--bare{display:grid;place-items:center;min-height:100vh;padding:24px;background:linear-gradient(170deg,var(--green-900),var(--green-800))}
.bare-wrap{width:100%;max-width:420px}
.login-card{background:var(--white);border-radius:var(--radius-lg);padding:28px;box-shadow:var(--shadow-lg)}
.login-brand{display:flex;align-items:center;gap:11px;margin-bottom:20px}
.login-brand .brand-mark{background:var(--brand);color:#fff;border:0}
.login-brand strong{display:block;font-size:16px}
.login-brand small{color:var(--gray-450);font-size:12.5px}

.setup{max-width:640px;margin:40px auto;padding:0 20px 60px}
.setup .card{margin-bottom:16px}
.step-list{display:grid;gap:10px;counter-reset:s;padding:0;margin:0;list-style:none}
.step-list li{display:flex;gap:11px;align-items:flex-start;font-size:14px;color:var(--gray-600)}
.step-list li::before{
  counter-increment:s;content:counter(s);
  width:22px;height:22px;border-radius:50%;flex:none;
  background:var(--green-100);color:var(--green-800);
  display:grid;place-items:center;font-size:11.5px;font-weight:700;
}
.check-list{display:grid;gap:7px;padding:0;margin:0;list-style:none;font-size:14px}
.check-list li{display:flex;gap:9px;align-items:flex-start}
.ok-mark{color:var(--green-700);font-weight:700}
.bad-mark{color:var(--red-800);font-weight:700}

/* ── responsive & print ───────────────────────────────────────────────── */

@media (max-width:920px){
  .stats,.form-row,.grid-2,.count-grid,.sig-grid{grid-template-columns:1fr}
  .tier-grid{grid-template-columns:1fr}
  .page{padding:20px 16px 60px}
  .menu-toggle{display:grid}
  .sidebar{position:fixed;z-index:30;left:0;top:0;transform:translateX(-100%);transition:transform .2s ease;box-shadow:var(--shadow-lg)}
  .sidebar.is-open{transform:none}
  .page-head h1{font-size:23px}
}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms !important;transition-duration:.001ms !important}
}

@media print{
  .sidebar,.menu-toggle,.filterbar,.btn,.icon-btn,.head-actions{display:none !important}
  body{background:#fff}
  .card{box-shadow:none;border-color:#ccc;break-inside:avoid}
  .page{max-width:none;padding:0}

  /*
   * A printed report is handed round a board meeting and filed with an
   * auditor. Both rooms contain people who keep books somewhere else, so the
   * page should say what produced it.
   */
  .page::after{
    content:"Produced by FiscalTrack  ·  fiscaltrack.app";
    display:block;margin-top:26px;padding-top:10px;
    border-top:1px solid #bbb;
    font-family:var(--font-mono);font-size:9pt;color:#555;letter-spacing:.04em;
  }
  .qs,.hub-grid,.doc-side{display:none !important}
}

/* ── receipts ─────────────────────────────────────────────────────────── */

.receipt-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:16px;align-items:start}
.receipt{margin:0;border:1px solid var(--gray-200);border-radius:var(--radius-md);overflow:hidden;background:var(--white)}
.receipt>a{display:block;background:var(--gray-100);aspect-ratio:4/3;overflow:hidden}
.receipt img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .18s ease}
.receipt>a:hover img{transform:scale(1.03)}
.receipt-pdf{display:grid;place-items:center;gap:5px;height:100%;color:var(--gray-600);font-size:12px;font-weight:500;letter-spacing:.08em}
.receipt figcaption{padding:11px 12px;display:grid;gap:2px;font-size:12.5px}
.receipt figcaption strong{font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.receipt-detail{margin-top:6px}
.receipt-detail summary{cursor:pointer;color:var(--gray-450);font-size:11.5px}
.receipt-detail summary:hover{color:var(--brand)}
.receipt-detail .hashline{margin-top:5px}
.receipt-detail .field-hint{margin:6px 0 0}

.has-receipt{display:inline-grid;place-items:center;width:22px;height:22px;border-radius:var(--radius-sm);
  background:var(--green-100);color:var(--green-800)}
.no-receipt{color:var(--gray-200)}

.meter{height:6px;border-radius:99px;background:var(--gray-100);overflow:hidden;margin-top:6px}
.meter>i{display:block;height:100%;background:var(--brand);border-radius:99px}
.meter.is-full>i{background:var(--red-800)}
.warn-mark{color:var(--amber-800);font-weight:700}
.stat-note{font-size:11.5px;color:var(--gray-450);margin-top:2px}

/* ── import ───────────────────────────────────────────────────────────── */

.map-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:11px}
.map-item{display:grid;gap:4px;font-size:12.5px;color:var(--gray-600)}
tr.row--bad{background:#fdf6f6}
tr.row--bad:hover{background:#fbeeee}
tr.row--dupe{background:#fdfaf3}
tr.row--dupe:hover{background:#fbf5e9}

/* ── organization picker ──────────────────────────────────────────────── */

.org-list{display:grid;gap:8px}
.org-option{
  display:flex;align-items:center;gap:11px;width:100%;text-align:left;
  padding:12px 14px;border:1px solid var(--gray-200);border-radius:var(--radius-md);
  background:var(--white);font:inherit;cursor:pointer;transition:all .13s;
}
.org-option:hover{border-color:var(--brand);background:var(--green-50)}
.org-option.is-current{border-color:var(--brand);background:var(--green-50)}
.org-mark{
  width:36px;height:36px;border-radius:var(--radius-md);flex:none;
  background:var(--green-100);color:var(--green-800);
  display:grid;place-items:center;font-size:13px;font-weight:700;
}
.org-text{display:grid;line-height:1.35;min-width:0;flex:1}
.org-text strong{font-size:14.5px}
.org-text small{font-size:12px;color:var(--gray-450)}
.sb-switch{display:flex;align-items:center;gap:9px;padding:9px 16px;color:rgba(255,255,255,.72);
  font-size:12.5px;border-top:1px solid rgba(255,255,255,.1)}
.sb-switch:hover{background:rgba(255,255,255,.07);color:#fff;text-decoration:none}
.sb-switch small{display:block;font-size:11px;color:rgba(255,255,255,.75)}

/* ── multi-factor ─────────────────────────────────────────────────────── */

.mfa-enrol{display:flex;gap:22px;align-items:flex-start;flex-wrap:wrap}
.mfa-enrol .qr{width:180px;height:180px;background:var(--white);border:1px solid var(--gray-200);
  border-radius:var(--radius-md);padding:8px;display:grid;place-items:center}
.mfa-enrol .qr svg{width:100%;height:100%}
.mfa-secret{font-size:16px;letter-spacing:.06em;background:var(--gray-100);padding:9px 12px;
  border-radius:var(--radius-md);margin:5px 0;display:inline-block}
.recovery-codes{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:8px}
.recovery-codes code{font-family:var(--font-mono);font-size:14px;background:var(--gray-100);
  padding:9px 11px;border-radius:var(--radius-sm);text-align:center;letter-spacing:.04em}

/* ── in-application help ──────────────────────────────────────────────── */

.doc-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:13px}
.doc-card{background:var(--white);border:1px solid var(--gray-200);border-radius:var(--radius-md);
  padding:17px;text-decoration:none;color:var(--ink-900);display:flex;flex-direction:column;gap:5px;
  transition:box-shadow .12s,transform .12s}
.doc-card:hover{box-shadow:0 3px 14px rgba(16,24,40,.09);transform:translateY(-1px)}
.doc-card strong{font-size:15.5px}
.doc-card span{font-size:13.5px;color:var(--gray-600)}

.doc-layout{display:grid;grid-template-columns:1fr 220px;gap:32px;align-items:start}
.doc-body{background:var(--white);border:1px solid var(--gray-200);border-radius:var(--radius-md);
  padding:30px 34px;max-width:760px}
.doc-body h1{font-size:26px;margin:0 0 4px}
.doc-lede{color:var(--gray-600);margin:0 0 22px;font-size:15px}
.doc-body h2{font-size:19px;margin:30px 0 9px;padding-top:4px}
.doc-body h2:first-of-type{margin-top:8px}
.doc-body h3{font-size:16px;margin:22px 0 7px}
.doc-body h4{font-size:14.5px;margin:18px 0 6px;color:var(--gray-700)}
.doc-body p{line-height:1.65;margin:0 0 13px}
.doc-list{margin:0 0 14px;padding-left:22px}
.doc-list li{line-height:1.6;margin-bottom:5px}
.doc-body code{background:var(--gray-100);padding:1px 5px;border-radius:4px;
  font-family:var(--font-mono);font-size:13px}
.doc-code{background:var(--ink-900);color:#e8eef5;padding:14px 16px;border-radius:var(--radius-md);
  overflow-x:auto;margin:0 0 15px}
.doc-code code{background:none;color:inherit;font-size:12.5px;line-height:1.6}
.doc-note{border-left:3px solid var(--green-700);background:var(--gray-50);padding:11px 15px;
  border-radius:0 var(--radius-sm) var(--radius-sm) 0;margin:0 0 15px;font-size:14.5px}
.doc-table{margin:0 0 16px;font-size:14px}
.doc-body hr{border:0;border-top:1px solid var(--gray-200);margin:26px 0}
.doc-pager{display:flex;justify-content:space-between;gap:16px;margin-top:34px;
  padding-top:18px;border-top:1px solid var(--gray-200);font-size:14.5px}

.doc-side{position:sticky;top:22px;display:flex;flex-direction:column;gap:2px}
.doc-side-head{font-size:11.5px;text-transform:uppercase;letter-spacing:.07em;
  color:var(--gray-500);font-weight:600;margin-bottom:7px}
.doc-side a{font-size:13.5px;color:var(--gray-600);text-decoration:none;padding:5px 9px;
  border-radius:var(--radius-sm);border-left:2px solid transparent}
.doc-side a:hover{background:var(--hover);color:var(--gray-900)}
.doc-side a.is-here{color:var(--green-700);font-weight:600;border-left-color:var(--green-600);
  background:var(--gray-50)}

@media (max-width:900px){
  .doc-layout{grid-template-columns:1fr}
  .doc-side{position:static;flex-direction:row;flex-wrap:wrap;gap:6px}
  .doc-side-head{display:none}
  .doc-body{padding:22px 20px}
}

.sb-help{display:flex;align-items:center;gap:10px;padding:9px 13px;margin:0 10px 4px;
  border-radius:var(--radius-md);color:rgba(255,255,255,.78);text-decoration:none;font-size:14px}
.sb-help:hover{background:rgba(255,255,255,.16);color:#fff}

/* ── avatars and logos ────────────────────────────────────────────────── */

.avatar--sm{width:32px;height:32px;font-size:12px}
.avatar--md{width:40px;height:40px;font-size:14px}
.avatar--lg{width:88px;height:88px;font-size:28px}
img.avatar{object-fit:cover;background:var(--gray-200);display:block}

.brand-logo{max-width:132px;max-height:34px;width:auto;height:auto;object-fit:contain;display:block}

.avatar-edit{display:flex;gap:18px;align-items:center;flex-wrap:wrap}
.avatar-edit .avatar{flex:none}
.logo-preview{background:var(--gray-100);border:1px solid var(--gray-200);
  border-radius:var(--radius-md);padding:14px 16px;display:inline-flex;align-items:center;
  min-height:56px;margin-bottom:10px}
.logo-preview img{max-width:280px;max-height:70px;width:auto;height:auto;display:block}
.logo-preview--dark{background:var(--ink-900)}
.user-cell{display:inline-flex;align-items:center;gap:10px}

/* ── Accessibility ─────────────────────────────────────────────────────────
   The parts that are not about color: keyboard focus, motion, and what
   happens when somebody has turned the operating system's contrast up.    */

/* A focus ring that is visible on every background, including the dark
   sidebar and colored buttons. Two rings rather than one: the outer white
   halo means the inner dark ring is visible even on a dark surface.        */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 3px solid var(--brand);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
  box-shadow: 0 0 0 5px rgba(255,255,255,.9);
}
.sidebar :focus-visible,
.store-bar :focus-visible,
.cart-bar :focus-visible {
  outline-color: #fff;
  box-shadow: 0 0 0 5px rgba(0,0,0,.55);
}

/* Never remove focus without replacing it. Mouse users do not see this;
   keyboard users depend on it entirely. */
:focus:not(:focus-visible) { outline: none; }

/* Skip link: the first thing a screen reader or keyboard user meets, so they
   are not tabbing through the whole menu on every page. */
.skip-link {
  position:absolute; left:-9999px; top:0; z-index:100;
  background:var(--brand); color:#fff; padding:11px 18px;
  border-radius:0 0 var(--radius-md) 0; font-weight:600; text-decoration:none;
}
.skip-link:focus { left:0; }

/* Respect a stated preference for less movement. Vestibular disorders make
   transitions genuinely unpleasant, not merely distracting. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
  .tile:hover, .doc-card:hover { transform:none; }
}

/* Windows high contrast and forced-colors modes: let the system win, but
   make sure borders survive, since they are what defines a control there. */
@media (forced-colors: active) {
  .btn, .input, .card, .chip, .tile, .doc-card, .cart-bar {
    border:1px solid ButtonBorder;
  }
  .btn--primary { forced-color-adjust:none; background:Highlight; color:HighlightText; }
  :focus-visible { outline:3px solid Highlight; }
}

/* Status color is never the only signal. A chip that is red to one person is
   grey to another, so the text inside it always says what it means. */
.chip::before { content:""; }

/* Somebody zoomed to 200% is a supported case, not an edge case: WCAG 1.4.4
   requires it. Stop the sidebar eating the screen. */
@media (max-width:1100px) {
  .doc-layout { grid-template-columns:1fr; }
}

/* Touch targets. WCAG 2.5.8 asks for 24px minimum; 44px is the comfortable
   figure and matters most on the public store, used on phones. */
.btn, .icon-btn, .nav-item, .store-cart, .pill { min-height:38px; }
.btn--sm { min-height:32px; }
@media (max-width:620px) {
  .btn, .store-cart, .cart-bar-actions .btn { min-height:44px; }
}

/* ── theme control ── */
.theme-toggle{display:flex;gap:4px;background:var(--gray-100);border-radius:999px;padding:3px}
.theme-toggle button{flex:1;border:0;background:none;padding:7px 12px;border-radius:999px;
  font:inherit;font-size:13px;color:var(--gray-600);cursor:pointer;min-height:34px}
.theme-toggle button[aria-pressed="true"]{background:var(--white);color:var(--gray-900);
  font-weight:600;box-shadow:var(--shadow-sm)}

/* The reconciliation sum, laid out like the paper form it replaces */
.recon-sums td{padding:7px 10px}
.recon-sums .total-row td{border-top:2px solid var(--gray-200);padding-top:10px}

/* ── settings hub ─────────────────────────────────────────────────────── */

.hub-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(268px,1fr));gap:12px}
.hub-card{display:flex;gap:13px;align-items:flex-start;background:var(--white);
  border:1px solid var(--gray-200);border-radius:var(--radius-md);padding:16px;
  text-decoration:none;color:var(--gray-900);transition:box-shadow .12s,border-color .12s}
.hub-card:hover{border-color:var(--green-700);background:var(--hover);box-shadow:var(--shadow-sm);text-decoration:none}
.hub-icon{flex:none;width:36px;height:36px;border-radius:var(--radius-md);
  background:var(--green-100);color:var(--green-800);display:grid;place-items:center}
.hub-text{display:flex;flex-direction:column;gap:2px}
.hub-text strong{font-size:14.5px}
.hub-text small{font-size:12.5px;color:var(--gray-450);line-height:1.45}
.sb-help.is-active{background:rgba(255,255,255,.12);color:#fff}

/* ── first-run checklist ───────────────────────────────────────────────────
   A worksheet, not a banner. The numbered tally column down the left is the
   vernacular of the job: a thing you tick off with a pen.               */

.qs{background:var(--white);border:1px solid var(--gray-200);border-radius:var(--radius-md);
  border-top:3px solid var(--green-700);padding:22px 24px;margin-bottom:20px}
.qs-head{display:flex;gap:24px;justify-content:space-between;align-items:flex-start;flex-wrap:wrap}
.qs-lead{flex:1;min-width:260px}
.qs-eyebrow{font-family:var(--font-mono);font-size:11px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--gray-450)}
.qs-title{font-size:21px;margin:5px 0 6px;letter-spacing:-.01em}
.qs-sub{margin:0 0 14px;color:var(--gray-600);font-size:14.5px;line-height:1.55;max-width:60ch}

.qs-meter{display:flex;flex-direction:column;gap:7px;align-items:flex-end;min-width:112px}
.qs-count{font-family:var(--font-mono);font-size:27px;font-weight:500;color:var(--green-800);
  line-height:1}
.qs-count span{font-size:15px;color:var(--gray-450)}
.qs-bar{display:block;width:112px;height:5px;background:var(--gray-200);border-radius:99px;
  overflow:hidden}
.qs-bar i{display:block;height:100%;background:var(--green-700);border-radius:99px;
  transition:width .4s ease}

.qs-list{list-style:none;margin:18px 0 0;padding:0;border-top:1px solid var(--gray-200)}
.qs-step{display:flex;gap:13px;align-items:baseline;padding:9px 0;
  border-bottom:1px solid var(--gray-100)}
.qs-tick{flex:none;width:24px;height:24px;border-radius:50%;display:grid;place-items:center;
  font-family:var(--font-mono);font-size:11px;color:var(--gray-450);
  border:1px solid var(--gray-200);align-self:flex-start;margin-top:1px}
.qs-step.is-done .qs-tick{background:var(--green-100);border-color:var(--green-100);
  color:var(--green-800)}
.qs-body{display:flex;flex-wrap:wrap;gap:4px 10px;align-items:baseline;flex:1}
.qs-body a{font-size:14.5px;font-weight:500;text-decoration:none;color:var(--gray-900)}
.qs-body a:hover{color:var(--green-800);text-decoration:underline}
.qs-step.is-done .qs-body a{color:var(--gray-450);font-weight:400}
.qs-body small{font-family:var(--font-mono);font-size:11.5px;color:var(--gray-450)}
.qs-body em{font-style:normal;font-family:var(--font-mono);font-size:10.5px;
  letter-spacing:.06em;text-transform:uppercase;color:var(--gray-450);
  border:1px solid var(--gray-200);border-radius:99px;padding:1px 7px}
.qs-foot{margin:14px 0 0;font-size:13.5px}

@media (max-width:600px){
  .qs{padding:18px 16px}
  .qs-meter{align-items:flex-start;flex-direction:row;align-items:center;gap:12px}
  .qs-bar{width:90px}
}

/* ── filter bars ───────────────────────────────────────────────────────────
   The class was used on five pages and never defined, so .input's width:100%
   won and each control took a line of its own. A filter row should read as
   one row.                                                                */

.filter-bar{display:flex;flex-wrap:wrap;gap:9px;align-items:center;margin-bottom:16px}
.filter-bar .input{width:auto;min-width:170px;flex:0 1 auto}
.filter-bar .input[type="search"],.filter-bar .input[type="text"]{min-width:220px;flex:1 1 220px;max-width:340px}
.filter-bar .field-hint{margin:0}
.filter-bar label{font-size:12.5px;color:var(--gray-600)}

@media (max-width:560px){
  .filter-bar .input,.filter-bar .input[type="search"]{width:100%;max-width:none;flex-basis:100%}
}

/* Some rows genuinely want three across: an account, a date and a balance
   belong on one line. The default two-column grid wrapped the third onto its
   own row at full width, which read as a mistake. */
.form-row--3{grid-template-columns:repeat(3,1fr)}
@media (max-width:760px){.form-row--3{grid-template-columns:1fr}}

/* Attribution at the foot of the sidebar. Quiet, permanent, and a real link:
   a bookkeeper who moves districts should be able to find us again. */
.sb-by{display:block;padding:8px 13px 12px;margin:0 10px;font-size:11.5px;
  color:rgba(255,255,255,.42);text-decoration:none;letter-spacing:.02em}
.sb-by:hover{color:rgba(255,255,255,.72)}
.sb-by strong{font-weight:600}
