@charset "UTF-8";
/* ==========================================================================
   Moneman — application stylesheet
   --------------------------------------------------------------------------
   Material-style dark-sidebar admin theme. Hand written, no build step:
   this file is served verbatim from public/assets/css/app.css and is loaded
   AFTER bootstrap.min.css so the overrides at the bottom win.

   Contents
     01  Design tokens
     02  Reset & base typography
     03  Application shell (sidebar / topbar / content)
     04  Off-canvas drawer
     05  Cards
     06  Stat cards
     07  Account cards
     08  Floating action button
     09  Page banners
     10  Amounts
     11  Chips
     12  Badges
     13  Key/value rows
     14  Progress
     15  Empty states
     16  Toolbars & filter bars
     17  Form fields (Material underline)
     18  Buttons
     19  Tables
     20  Dropzone
     21  Autocomplete
     22  Flash messages
     23  Bootstrap overrides (modal / dropdown / alert / pagination)
     24  Charts
     25  Utilities
     26  Responsive
     27  Print
     28  Theme switch (topbar user menu)
     29  Dark mode overrides
   ========================================================================== */

/* ==========================================================================
   01  Design tokens — contract §6. These are the single source of colour
   truth; GB.palette in app.js mirrors them so charts never drift.
   ========================================================================== */

:root {
  /* Geometry */
  --gb-sidebar-w: 260px;
  --gb-topbar-h: 56px;

  /* Surfaces */
  --gb-bg: #eceff1;
  --gb-surface: #ffffff;
  --gb-topbar: #f5f5f5;
  --gb-sidebar: #1f2429;
  --gb-sidebar-brand: #272d33;
  --gb-text: #37474f;
  --gb-text-muted: #78909c;
  --gb-border: #e0e4e7;

  /* Brand & semantics */
  --gb-primary: #8e24aa;
  --gb-primary-2: #ab47bc;
  --gb-primary-hover: #7b1fa2;
  --gb-primary-rgb: 142, 36, 170;
  --gb-primary-2-rgb: 171, 71, 188;
  --gb-primary-ink: #6a1b9a;
  --gb-expense: #f44336;
  --gb-income: #4caf50;
  --gb-exchange: #ff9800;
  --gb-info: #00bcd4;
  --gb-accent: #3949ab;
  --gb-pink: #e91e63;

  /* ---- Supplementary tokens (derived; not part of contract §6) ---------- */

  /* Tints used on dark backgrounds — the light green / light red money lines
     on the coloured stat cards, and the muted "Last month" tile. */
  --gb-income-light: #b9f6ca;
  --gb-expense-light: #ffcdd2;
  --gb-muted-tile: #607d8b;
  --gb-warning: #fb8c00;
  --gb-success: #43a047;
  --gb-danger: #e53935;

  /* Sidebar foreground */
  --gb-sidebar-fg: rgba(255, 255, 255, .9);
  --gb-sidebar-fg-dim: rgba(255, 255, 255, .62);
  --gb-sidebar-hover: rgba(255, 255, 255, .08);

  /* Radii */
  --gb-radius: 4px;
  --gb-radius-sm: 2px;
  --gb-radius-lg: 8px;
  --gb-radius-pill: 999px;

  /* Material elevation ladder */
  --gb-elev-1: 0 1px 3px rgba(0, 0, 0, .12), 0 1px 2px rgba(0, 0, 0, .24);
  --gb-elev-2: 0 3px 6px rgba(0, 0, 0, .16), 0 3px 6px rgba(0, 0, 0, .23);
  --gb-elev-4: 0 10px 20px rgba(0, 0, 0, .19), 0 6px 6px rgba(0, 0, 0, .23);
  --gb-elev-8: 0 14px 28px rgba(0, 0, 0, .25), 0 10px 10px rgba(0, 0, 0, .22);

  /* Typography */
  --gb-font: "Roboto", -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif;
  --gb-font-size: 13px;
  --gb-line: 1.5;

  /* Motion */
  --gb-ease: cubic-bezier(.4, 0, .2, 1);
  --gb-dur: 180ms;

  /* Layout rhythm */
  --gb-gutter: 20px;
  --gb-z-sidebar: 1040;
  --gb-z-scrim: 1035;
  --gb-z-topbar: 1030;
  --gb-z-calc: 1025;
  --gb-z-bottom-nav: 1032;
  --gb-z-selection-bar: 1033;

  /* ---- Theme-aware overlay tokens ----------------------------------------
     --gb-overlay-rgb is the RGB triplet behind every neutral hover/press tint
     (rgba(var(--gb-overlay-rgb), alpha)) — flipping it in dark mode turns
     every such tint from "darken toward text" into "lighten toward white"
     with no per-rule dark override needed. --gb-surface-alt/--gb-surface-hover
     are solid alt-surface tones (table head/foot, card footer, disabled
     pagination, button hover) that dark mode redefines below. */
  --gb-overlay-rgb: 55, 71, 79;
  --gb-surface-alt: #fafafa;
  --gb-surface-hover: #dfe4e7;
  color-scheme: light dark;
}

/* ==========================================================================
   01b  Dark mode — same tokens, dark values. Applied explicitly via
   data-theme="dark" on <html> (GB.initTheme() in app.js); "system" resolves
   to light/dark at runtime (prefers-color-scheme) and sets the same
   attribute, so this selector is the only dark switch the CSS needs.
   Sidebar stays the fixed near-black brand rail in both themes by design.
   ========================================================================== */

:root[data-theme="dark"] {
  --gb-bg: #23282d;
  --gb-surface: #2e343b;
  --gb-topbar: #262c32;
  --gb-text: #e7ebee;
  --gb-text-muted: #93a4ad;
  --gb-border: #3a4149;

  --gb-primary-ink: #ce93d8;
  --gb-primary-ink-hover: #e3b8ec;

  --gb-overlay-rgb: 255, 255, 255;
  --gb-surface-alt: #262b31;
  --gb-surface-hover: #363d45;

  color-scheme: dark;
}

:root[data-theme="light"] { color-scheme: light; }

/* ==========================================================================
   01c  Accent colours — user-selectable brand colour (profile settings).
   --------------------------------------------------------------------------
   Stored client-side only (localStorage `gb-accent`) and applied as
   data-accent="<key>" on <html> — GB.initAccentColor()/GB.applyAccentPreference()
   in app.js own the click handling + persistence; the inline pre-paint
   script (partials/theme-init.blade.php) mirrors just the attribute so the
   page never flashes the default purple first. Purple is listed here too
   (rather than left to fall back to the bare :root above) so resetting to
   it needs no special case in JS. Only --gb-primary/-2/-hover (+ their -rgb
   tint helpers and -ink text pairs) move; semantic colours (expense/income/
   etc.) and --gb-accent (a separate, unrelated indigo token) never do.
   ========================================================================== */

:root[data-accent="purple"] {
  --gb-primary: #8e24aa; --gb-primary-2: #ab47bc; --gb-primary-hover: #7b1fa2;
  --gb-primary-rgb: 142, 36, 170; --gb-primary-2-rgb: 171, 71, 188;
  --gb-primary-ink: #6a1b9a;
}
:root[data-theme="dark"][data-accent="purple"] { --gb-primary-ink: #ce93d8; --gb-primary-ink-hover: #e3b8ec; }

:root[data-accent="blue"] {
  --gb-primary: #1e88e5; --gb-primary-2: #42a5f5; --gb-primary-hover: #1976d2;
  --gb-primary-rgb: 30, 136, 229; --gb-primary-2-rgb: 66, 165, 245;
  --gb-primary-ink: #1565c0;
}
:root[data-theme="dark"][data-accent="blue"] { --gb-primary-ink: #90caf9; --gb-primary-ink-hover: #bbdefb; }

:root[data-accent="teal"] {
  --gb-primary: #00897b; --gb-primary-2: #26a69a; --gb-primary-hover: #00796b;
  --gb-primary-rgb: 0, 137, 123; --gb-primary-2-rgb: 38, 166, 154;
  --gb-primary-ink: #00695c;
}
:root[data-theme="dark"][data-accent="teal"] { --gb-primary-ink: #80cbc4; --gb-primary-ink-hover: #b2dfdb; }

:root[data-accent="green"] {
  --gb-primary: #43a047; --gb-primary-2: #66bb6a; --gb-primary-hover: #388e3c;
  --gb-primary-rgb: 67, 160, 71; --gb-primary-2-rgb: 102, 187, 106;
  --gb-primary-ink: #2e7d32;
}
:root[data-theme="dark"][data-accent="green"] { --gb-primary-ink: #a5d6a7; --gb-primary-ink-hover: #c8e6c9; }

:root[data-accent="orange"] {
  --gb-primary: #fb8c00; --gb-primary-2: #ffa726; --gb-primary-hover: #f57c00;
  --gb-primary-rgb: 251, 140, 0; --gb-primary-2-rgb: 255, 167, 38;
  --gb-primary-ink: #e65100;
}
:root[data-theme="dark"][data-accent="orange"] { --gb-primary-ink: #ffcc80; --gb-primary-ink-hover: #ffe0b2; }

:root[data-accent="red"] {
  --gb-primary: #e53935; --gb-primary-2: #ef5350; --gb-primary-hover: #d32f2f;
  --gb-primary-rgb: 229, 57, 53; --gb-primary-2-rgb: 239, 83, 80;
  --gb-primary-ink: #c62828;
}
:root[data-theme="dark"][data-accent="red"] { --gb-primary-ink: #ef9a9a; --gb-primary-ink-hover: #ffcdd2; }

:root[data-accent="pink"] {
  --gb-primary: #d81b60; --gb-primary-2: #ec407a; --gb-primary-hover: #c2185b;
  --gb-primary-rgb: 216, 27, 96; --gb-primary-2-rgb: 236, 64, 122;
  --gb-primary-ink: #ad1457;
}
:root[data-theme="dark"][data-accent="pink"] { --gb-primary-ink: #f48fb1; --gb-primary-ink-hover: #f8bbd0; }

:root[data-accent="indigo"] {
  --gb-primary: #3949ab; --gb-primary-2: #5c6bc0; --gb-primary-hover: #303f9f;
  --gb-primary-rgb: 57, 73, 171; --gb-primary-2-rgb: 92, 107, 192;
  --gb-primary-ink: #283593;
}
:root[data-theme="dark"][data-accent="indigo"] { --gb-primary-ink: #8c9eff; --gb-primary-ink-hover: #c5cae9; }

/* Alpine: hide un-initialised elements so drawers never flash open. */
[x-cloak] { display: none !important; }

/* ==========================================================================
   02  Reset & base typography
   ========================================================================== */

*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body.gb-body {
  margin: 0;
  min-height: 100vh;
  background: var(--gb-bg);
  color: var(--gb-text);
  font-family: var(--gb-font);
  font-size: var(--gb-font-size);
  line-height: var(--gb-line);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}


h1, h2, h3, h4, h5, h6 {
  margin: 0 0 .5rem;
  font-weight: 500;
  color: var(--gb-text);
  line-height: 1.3;
}

h1 { font-size: 22px; }
h2 { font-size: 19px; }
h3 { font-size: 17px; }
h4 { font-size: 15px; }
h5 { font-size: 14px; }
h6 { font-size: 13px; }

p { margin: 0 0 .75rem; }

a {
  color: var(--gb-primary);
  text-decoration: none;
  transition: color var(--gb-dur) var(--gb-ease);
}

a:hover { color: var(--gb-primary-2); text-decoration: none; }

hr {
  border: 0;
  border-top: 1px solid var(--gb-border);
  margin: 1rem 0;
  opacity: 1;
}

small, .gb-small { font-size: 11px; }

code, pre, .gb-mono {
  font-family: "Roboto Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* Keep focus visible everywhere — contract §6 accessibility rule. */
:focus-visible {
  outline: 2px solid var(--gb-primary-2);
  outline-offset: 2px;
}

.gb-visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Skip link for keyboard users. */
.gb-skip-link {
  position: absolute;
  left: 8px;
  top: -60px;
  z-index: 2000;
  padding: 10px 16px;
  border-radius: var(--gb-radius);
  background: var(--gb-primary);
  color: #fff;
  font-weight: 500;
  transition: top var(--gb-dur) var(--gb-ease);
}

.gb-skip-link:focus {
  top: 8px;
  color: #fff;
}

/* Material icon sizing helpers — the vendored font renders at 24px by default. */
.material-icons { vertical-align: middle; user-select: none; }
.material-icons.gb-i-14 { font-size: 14px; }
.material-icons.gb-i-16 { font-size: 16px; }
.material-icons.gb-i-18 { font-size: 18px; }
.material-icons.gb-i-20 { font-size: 20px; }
.material-icons.gb-i-24 { font-size: 24px; }
.material-icons.gb-i-32 { font-size: 32px; }
.material-icons.gb-i-48 { font-size: 48px; }
.material-icons.gb-i-64 { font-size: 64px; }

/* ==========================================================================
   03  Application shell
   --------------------------------------------------------------------------
   .gb-sidebar   fixed 260px dark rail, brand strip + nav
   .gb-main      offset content column
   .gb-topbar    56px sticky bar
   .gb-content   padded page area
   ========================================================================== */

.gb-sidebar {
  position: fixed;
  inset: 0 auto 0 0;
  width: var(--gb-sidebar-w);
  z-index: var(--gb-z-sidebar);
  display: flex;
  flex-direction: column;
  background-color: var(--gb-sidebar);
  color: var(--gb-sidebar-fg);
  box-shadow: 2px 0 6px rgba(0, 0, 0, .18);
  transition: transform var(--gb-dur) var(--gb-ease);
}

/* Brand strip — matches the topbar height so the two align across the fold. */
.gb-sidebar__brand {
  flex: 0 0 auto;
  height: var(--gb-topbar-h);
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 16px;
  background: var(--gb-sidebar-brand);
  color: #fff;
  border-bottom: 1px solid rgba(0, 0, 0, .25);
}

.gb-sidebar__brand:hover,
.gb-sidebar__brand:focus { color: #fff; }

.gb-sidebar__brand-icon {
  width: 24px;
  height: 24px;
  flex: 0 0 auto;
  display: block;
  object-fit: contain;
}

.gb-sidebar__wordmark {
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Sidebar body.
   The background photo at /assets/img/sidebar-bg.jpg is OPTIONAL: a flat
   near-opaque --gb-sidebar tint always paints over it, so a missing image is
   invisible rather than broken. That tint is written as a two-identical-stop
   linear-gradient because that is the only way CSS lets you flat-tint a
   background image — there is no wash and no glow, the rail is one colour. */
.gb-sidebar__body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 10px 0 24px;
  background-color: var(--gb-sidebar);
  background-image:
    linear-gradient(rgba(31, 36, 41, .94), rgba(31, 36, 41, .94)),
    url("../img/sidebar-bg.jpg");
  background-repeat: no-repeat;
  background-size: cover, cover;
  background-position: center, center;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, .22) transparent;
}

.gb-sidebar__body::-webkit-scrollbar { width: 6px; }
.gb-sidebar__body::-webkit-scrollbar-track { background: transparent; }
.gb-sidebar__body::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, .22);
  border-radius: var(--gb-radius-pill);
}

/* Signed-in user block above the nav. A flat panel, deliberately: it sits at
   the top of the rail where any wash or glow would be at its strongest, and a
   solid tile reads as "this is your account" far better than a tinted band. */
.gb-sidebar__user {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 11px 12px;
  margin: 2px 12px 12px;
  border-radius: var(--gb-radius-lg);
  background: rgba(255, 255, 255, .05);
  border: 1px solid rgba(255, 255, 255, .07);
}

/* Flat fill for the avatar in here only — .gb-avatar keeps its gradient
   everywhere else in the app (topbar, lists, profile header). */
.gb-sidebar__user .gb-avatar {
  background: var(--gb-primary-2);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .14);
}

.gb-sidebar__user-meta { min-width: 0; }

.gb-sidebar__user-name {
  display: block;
  font-size: 13px;
  font-weight: 500;
  color: #fff;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.gb-sidebar__user-role {
  display: block;
  font-size: 11px;
  color: var(--gb-sidebar-fg-dim);
  text-transform: uppercase;
  letter-spacing: .6px;
}

/* The corporate account the signed-in person belongs to. Rendered under their
   title because "which company's books am I looking at?" is the first thing
   somebody who works in two of them needs to know. */
.gb-sidebar__user-org {
  display: block;
  font-size: 11px;
  color: rgba(255, 255, 255, .38);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.gb-nav {
  list-style: none;
  margin: 0;
  padding: 0;
}

.gb-nav__section {
  padding: 16px 16px 6px;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .4);
}

.gb-nav__item { margin: 1px 0; }

.gb-nav__link {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  height: 40px;
  padding: 0 16px;
  color: var(--gb-sidebar-fg);
  font-size: 13px;
  font-weight: 400;
  white-space: nowrap;
  border-left: 3px solid transparent;
  transition: background-color var(--gb-dur) var(--gb-ease),
              color var(--gb-dur) var(--gb-ease),
              box-shadow var(--gb-dur) var(--gb-ease);
}

.gb-nav__link .material-icons {
  font-size: 18px;
  flex: 0 0 18px;
  opacity: .95;
}

.gb-nav__label {
  overflow: hidden;
  text-overflow: ellipsis;
}

.gb-nav__link:hover,
.gb-nav__link:focus {
  background: var(--gb-sidebar-hover);
  color: #fff;
}

.gb-nav__link:focus-visible {
  outline: 2px solid var(--gb-primary-2);
  outline-offset: -2px;
}

/* Active row: full-width accent gradient pill with a hint of elevation. */
.gb-nav__link.is-active {
  background: linear-gradient(90deg, var(--gb-primary), var(--gb-primary-2));
  color: #fff;
  font-weight: 500;
  border-left-color: rgba(255, 255, 255, .55);
  box-shadow: 0 1px 4px rgba(0, 0, 0, .35);
}

.gb-nav__link.is-active .material-icons { opacity: 1; }

.gb-nav__link.is-active:hover,
.gb-nav__link.is-active:focus {
  background: linear-gradient(90deg, var(--gb-primary), var(--gb-primary-2));
  color: #fff;
}

/* Counter pushed to the right edge of a nav row (unread alerts). */
.gb-nav__count {
  margin-left: auto;
  min-width: 20px;
  height: 18px;
  padding: 0 6px;
  border-radius: var(--gb-radius-pill);
  background: var(--gb-expense);
  color: #fff;
  font-size: 10px;
  font-weight: 500;
  line-height: 18px;
  text-align: center;
}

.gb-sidebar__footer {
  padding: 14px 16px 0;
  margin-top: 10px;
  border-top: 1px solid rgba(255, 255, 255, .07);
  font-size: 11px;
  color: rgba(255, 255, 255, .38);
}

/* ---- Main column --------------------------------------------------------- */

.gb-main {
  min-height: 100vh;
  margin-left: var(--gb-sidebar-w);
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.gb-topbar {
  position: sticky;
  top: 0;
  z-index: var(--gb-z-topbar);
  flex: 0 0 auto;
  height: var(--gb-topbar-h);
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 var(--gb-gutter);
  background: var(--gb-topbar);
  border-bottom: 1px solid var(--gb-border);
}

.gb-topbar__toggle {
  display: none;
  flex: 0 0 auto;
  margin-left: -8px;
}

.gb-topbar__title {
  margin: 0;
  font-size: 16px;
  font-weight: 500;
  color: var(--gb-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.gb-topbar__heading {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  min-width: 0;
}

/* Breadcrumb strip — only rendered when a page sets @section('breadcrumb'),
   stacked above .gb-topbar__title inside .gb-topbar__heading. */
.gb-breadcrumb { min-width: 0; }

.gb-breadcrumb ol {
  display: flex;
  align-items: center;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 12px;
  color: var(--gb-text-muted);
  overflow: hidden;
}

.gb-breadcrumb__item {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.gb-breadcrumb__item a {
  color: inherit;
  text-decoration: none;
}

.gb-breadcrumb__item a:hover { color: var(--gb-primary); text-decoration: underline; }

.gb-breadcrumb__item span[aria-current="page"] { color: var(--gb-text); }

.gb-breadcrumb__sep {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
}

.gb-breadcrumb__sep .material-icons { font-size: 14px; opacity: .5; }

.gb-topbar__spacer { flex: 1 1 auto; min-width: 0; }

.gb-topbar__actions {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: 0 0 auto;
}

/* Alert bell + count badge. */
.gb-bell {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--gb-text-muted);
  transition: background-color var(--gb-dur) var(--gb-ease), color var(--gb-dur) var(--gb-ease);
}

.gb-bell:hover,
.gb-bell:focus {
  background: rgba(var(--gb-overlay-rgb), .08);
  color: var(--gb-text);
}

.gb-bell .material-icons { font-size: 20px; }

.gb-bell.is-unread { color: var(--gb-primary); }

.gb-bell__count {
  position: absolute;
  top: 1px;
  right: 0;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: var(--gb-radius-pill);
  background: var(--gb-expense);
  color: #fff;
  font-size: 10px;
  font-weight: 500;
  line-height: 16px;
  text-align: center;
  box-shadow: 0 0 0 2px var(--gb-topbar);
}

/* Avatar + dropdown trigger. */
.gb-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  flex: 0 0 32px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--gb-primary), var(--gb-primary-2));
  color: #fff;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .5px;
  overflow: hidden;
  text-transform: uppercase;
}

.gb-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.gb-avatar--sm { width: 26px; height: 26px; flex-basis: 26px; font-size: 10px; }
.gb-avatar--lg { width: 64px; height: 64px; flex-basis: 64px; font-size: 22px; }
.gb-avatar--xl { width: 96px; height: 96px; flex-basis: 96px; font-size: 32px; }

.gb-usermenu {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 3px 6px 3px 3px;
  border: 0;
  border-radius: var(--gb-radius-pill);
  background: transparent;
  color: var(--gb-text);
  transition: background-color var(--gb-dur) var(--gb-ease);
}

.gb-usermenu:hover,
.gb-usermenu:focus { background: rgba(var(--gb-overlay-rgb), .08); }

.gb-usermenu::after { display: none; }

.gb-usermenu__name {
  font-size: 13px;
  font-weight: 500;
  max-width: 160px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.gb-usermenu__caret { font-size: 18px; color: var(--gb-text-muted); }

/* ---- Content ------------------------------------------------------------- */

.gb-content {
  flex: 1 1 auto;
  padding: var(--gb-gutter);
  background: var(--gb-bg);
  min-width: 0;
}

.gb-content > .gb-page-banner:first-child { margin-top: 0; }

.gb-page-head {
  display: flex;
  align-items: flex-end;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}

.gb-page-head__title { margin: 0; font-size: 20px; font-weight: 500; }

.gb-page-head__sub { margin: 2px 0 0; color: var(--gb-text-muted); font-size: 12px; }

.gb-page-head__actions { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; }

/* ==========================================================================
   04  Off-canvas drawer (< 992px) — Alpine toggles body.gb-drawer-open and
   .gb-sidebar.is-open; the scrim closes on click, Escape closes on window.
   ========================================================================== */

.gb-scrim {
  position: fixed;
  inset: 0;
  z-index: var(--gb-z-scrim);
  background: rgba(0, 0, 0, .5);
  border: 0;
  padding: 0;
  display: none;
}

@media (max-width: 991.98px) {
  .gb-sidebar {
    transform: translateX(-100%);
    visibility: hidden;
  }

  .gb-sidebar.is-open {
    transform: translateX(0);
    visibility: visible;
  }

  .gb-main { margin-left: 0; }

  .gb-topbar__toggle { display: inline-flex; }

  .gb-scrim { display: block; }

  .gb-content { padding: 14px; }

  /* Stop the page scrolling behind an open drawer. Scoped to this breakpoint so
     a viewport resize while the drawer is open cannot leave the desktop layout
     unscrollable. */
  body.gb-drawer-open { overflow: hidden; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: .01ms !important; animation-duration: .01ms !important; }
  html { scroll-behavior: auto; }
}

/* ==========================================================================
   05  Cards
   --------------------------------------------------------------------------
   .gb-card                white Material card, 4px radius, elevation 1
     .gb-card__header      title / subtitle row, optional right-hand actions
     .gb-card__title       15px 500
     .gb-card__subtitle    12px muted
     .gb-card__body        16px padding
     .gb-card__footer      hairline-topped footer strip
   Modifiers: --flush (body without padding), --accent (top colour rule)
   ========================================================================== */

.gb-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--gb-surface);
  border-radius: var(--gb-radius);
  box-shadow: var(--gb-elev-1);
  margin-bottom: var(--gb-gutter);
  overflow: hidden;
}

.gb-card--flat { box-shadow: none; border: 1px solid var(--gb-border); }

.gb-card--full { height: calc(100% - var(--gb-gutter)); }

.gb-card__header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--gb-border);
  min-height: 52px;
}

.gb-card__header--plain { border-bottom: 0; padding-bottom: 0; }

.gb-card__heading { min-width: 0; flex: 1 1 auto; }

.gb-card__title {
  margin: 0;
  font-size: 15px;
  font-weight: 500;
  color: var(--gb-text);
  display: flex;
  align-items: center;
  gap: 8px;
}

.gb-card__title .material-icons { font-size: 18px; color: var(--gb-text-muted); }

.gb-card__subtitle {
  margin: 2px 0 0;
  font-size: 12px;
  color: var(--gb-text-muted);
}

.gb-card__actions {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
}

.gb-card__body { padding: 16px; flex: 1 1 auto; min-width: 0; }

.gb-card--flush .gb-card__body { padding: 0; }

.gb-card__footer {
  padding: 10px 16px;
  border-top: 1px solid var(--gb-border);
  background: var(--gb-surface-alt);
  font-size: 12px;
  color: var(--gb-text-muted);
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.gb-card--accent::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: linear-gradient(90deg, var(--gb-primary), var(--gb-primary-2));
}

.gb-card--accent-expense::before { background: var(--gb-expense); }
.gb-card--accent-income::before { background: var(--gb-income); }
.gb-card--accent-exchange::before { background: var(--gb-exchange); }
.gb-card--accent-info::before { background: var(--gb-info); }

/* ==========================================================================
   06  Stat cards
   --------------------------------------------------------------------------
   The coloured dashboard tiles: This Year (--info / teal), This Month
   (--success / green), Last Month (--muted / blue-grey). White text, a 14px
   title, then Balance / Incomes / Expenses rows where income reads light
   green and expense light red so the sign is legible on a coloured ground.
   ========================================================================== */

.gb-stat-card {
  position: relative;
  display: block;
  padding: 16px;
  border-radius: var(--gb-radius);
  box-shadow: var(--gb-elev-1);
  margin-bottom: var(--gb-gutter);
  color: #fff;
  background: linear-gradient(135deg, var(--gb-primary), var(--gb-primary-2));
  overflow: hidden;
}

a.gb-stat-card { color: #fff; transition: box-shadow var(--gb-dur) var(--gb-ease); }
a.gb-stat-card:hover { color: #fff; box-shadow: var(--gb-elev-2); }

.gb-stat-card--info { background: linear-gradient(135deg, #00bcd4, #26c6da); }
.gb-stat-card--success { background: linear-gradient(135deg, #43a047, #66bb6a); }
.gb-stat-card--muted { background: linear-gradient(135deg, #546e7a, #78909c); }
.gb-stat-card--expense { background: linear-gradient(135deg, #e53935, #ef5350); }
.gb-stat-card--income { background: linear-gradient(135deg, #2e7d32, #4caf50); }
.gb-stat-card--exchange { background: linear-gradient(135deg, #f57c00, #ffa726); }
.gb-stat-card--accent { background: linear-gradient(135deg, #303f9f, #3949ab); }

/* A translucent watermark icon in the corner, purely decorative. */
.gb-stat-card__watermark {
  position: absolute;
  right: 8px;
  top: 8px;
  font-size: 64px;
  line-height: 1;
  color: rgba(255, 255, 255, .14);
  pointer-events: none;
}

.gb-stat-card__title {
  margin: 0 0 10px;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: .3px;
  color: #fff;
  display: flex;
  align-items: center;
  gap: 8px;
}

.gb-stat-card__title .material-icons { font-size: 18px; }

.gb-stat-card__rows {
  margin: 0;
  display: grid;
  gap: 4px;
}

.gb-stat-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  font-size: 13px;
  line-height: 1.6;
}

.gb-stat-row__label {
  color: rgba(255, 255, 255, .88);
  white-space: nowrap;
}

.gb-stat-row__value {
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

.gb-stat-row--balance .gb-stat-row__value { font-size: 17px; font-weight: 500; color: #fff; }
.gb-stat-row--income .gb-stat-row__value { color: var(--gb-income-light); }
.gb-stat-row--expense .gb-stat-row__value { color: var(--gb-expense-light); }

.gb-stat-card__footer {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid rgba(255, 255, 255, .22);
  font-size: 11px;
  color: rgba(255, 255, 255, .82);
  display: flex;
  align-items: center;
  gap: 6px;
}

.gb-stat-card__footer .material-icons { font-size: 14px; }

/* ==========================================================================
   07  Account cards
   --------------------------------------------------------------------------
   Coloured 36px rounded-square currency badge on the left, the account name,
   a big right-aligned balance, a footer line carrying the base-currency
   equivalent in small grey text, and a .gb-fab in the top-right corner.
   ========================================================================== */

.gb-account-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--gb-surface);
  border-radius: var(--gb-radius);
  box-shadow: var(--gb-elev-1);
  margin-bottom: var(--gb-gutter);
  transition: box-shadow var(--gb-dur) var(--gb-ease);
}

.gb-account-card:hover { box-shadow: var(--gb-elev-2); }

.gb-account-card.is-inactive { opacity: .62; }

.gb-account-card__main {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 60px 12px 16px;
  min-width: 0;
}

.gb-account-card__meta { min-width: 0; flex: 1 1 auto; }

.gb-account-card__name {
  display: block;
  font-size: 14px;
  font-weight: 500;
  color: var(--gb-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.gb-account-card__name:hover { color: var(--gb-primary); }

.gb-account-card__type {
  display: block;
  font-size: 11px;
  color: var(--gb-text-muted);
  text-transform: uppercase;
  letter-spacing: .5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.gb-account-card__balance {
  display: block;
  margin-top: 8px;
  font-size: 22px;
  font-weight: 400;
  line-height: 1.25;
  text-align: right;
  color: var(--gb-text);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding: 0 16px;
}

.gb-account-card__footer {
  margin-top: 10px;
  padding: 8px 16px;
  border-top: 1px solid var(--gb-border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  font-size: 11px;
  color: var(--gb-text-muted);
}

.gb-account-card__equivalent {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.gb-account-card__main > .gb-fab {
  position: absolute;
  top: 12px;
  right: 12px;
}

/* The coloured square currency badge, also used standalone in lists. */
.gb-currency-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex: 0 0 36px;
  border-radius: var(--gb-radius);
  background: var(--gb-text-muted);
  color: #fff;
  font-size: 15px;
  font-weight: 500;
  line-height: 1;
  box-shadow: var(--gb-elev-1);
  overflow: hidden;
}

.gb-currency-badge--sm { width: 26px; height: 26px; flex-basis: 26px; font-size: 12px; }
.gb-currency-badge--lg { width: 48px; height: 48px; flex-basis: 48px; font-size: 20px; }

.gb-currency-badge__code {
  font-size: 9px;
  letter-spacing: .5px;
  text-transform: uppercase;
}

/* ==========================================================================
   08  Floating action button — 40px indigo circle, elevation 2 → 4 on hover
   ========================================================================== */

.gb-fab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  flex: 0 0 40px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--gb-accent);
  color: #fff;
  box-shadow: var(--gb-elev-2);
  cursor: pointer;
  transition: box-shadow var(--gb-dur) var(--gb-ease),
              background-color var(--gb-dur) var(--gb-ease),
              transform var(--gb-dur) var(--gb-ease);
}

.gb-fab .material-icons { font-size: 22px; color: #fff; }

.gb-fab:hover,
.gb-fab:focus {
  background: #303f9f;
  color: #fff;
  box-shadow: var(--gb-elev-4);
}

.gb-fab:active { transform: translateY(1px); box-shadow: var(--gb-elev-2); }

.gb-fab--sm { width: 32px; height: 32px; flex-basis: 32px; }
.gb-fab--sm .material-icons { font-size: 18px; }

.gb-fab--primary { background: var(--gb-primary); }
.gb-fab--primary:hover, .gb-fab--primary:focus { background: var(--gb-primary-hover); }
.gb-fab--income { background: var(--gb-success); }
.gb-fab--income:hover, .gb-fab--income:focus { background: #2e7d32; }
.gb-fab--expense { background: var(--gb-danger); }
.gb-fab--expense:hover, .gb-fab--expense:focus { background: #c62828; }

/* A page-level FAB pinned to the bottom-right on small screens. */
.gb-fab--fixed {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 1020;
  width: 52px;
  height: 52px;
}

.gb-fab--fixed .material-icons { font-size: 26px; }

/* ==========================================================================
   08b  Selection bar — fixed strip summing the checked table rows
   ========================================================================== */

.gb-selection-bar {
  position: fixed;
  left: 50%;
  bottom: 18px;
  z-index: var(--gb-z-selection-bar);
  transform: translateX(-50%);
  max-width: calc(100% - 36px);
}

.gb-selection-bar[hidden] { display: none; }

.gb-selection-bar__inner {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 10px 10px 18px;
  background: var(--gb-surface);
  border: 1px solid var(--gb-border);
  border-radius: var(--gb-radius-pill);
  box-shadow: var(--gb-elev-4);
  white-space: nowrap;
}

.gb-selection-bar__count {
  font-size: 13px;
  color: var(--gb-text-muted);
}

.gb-selection-bar__total {
  font-size: 14px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--gb-text);
}

.gb-selection-bar__total.is-income { color: var(--gb-income); }
.gb-selection-bar__total.is-expense { color: var(--gb-expense); }

/* Room for the phone bar, same as .gb-content does for page content. */
@media (max-width: 991.98px) {
  .gb-selection-bar { bottom: calc(56px + 12px + env(safe-area-inset-bottom, 0px)); }
}

/* ==========================================================================
   09  Page banners
   --------------------------------------------------------------------------
   Coloured strip carrying the page title, a subtitle and a right-aligned
   action slot. The colour tracks the active action type:
   --expense red / --income green / --exchange orange / --info teal /
   --primary purple (default).
   ========================================================================== */

.gb-page-banner {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  padding: 14px 18px;
  margin-bottom: var(--gb-gutter);
  border-radius: var(--gb-radius);
  box-shadow: var(--gb-elev-1);
  color: #fff;
  background: linear-gradient(90deg, var(--gb-primary), var(--gb-primary-2));
  --gb-banner-ink: var(--gb-primary-ink);
}

.gb-page-banner--primary { background: linear-gradient(90deg, var(--gb-primary), var(--gb-primary-2)); --gb-banner-ink: var(--gb-primary-ink); }
.gb-page-banner--expense { background: linear-gradient(90deg, #e53935, #ef5350); --gb-banner-ink: #c62828; }
.gb-page-banner--income { background: linear-gradient(90deg, #388e3c, #4caf50); --gb-banner-ink: #2e7d32; }
.gb-page-banner--exchange { background: linear-gradient(90deg, #f57c00, #ffa726); --gb-banner-ink: #e65100; }
.gb-page-banner--info { background: linear-gradient(90deg, #0097a7, #00bcd4); --gb-banner-ink: #00707d; }
.gb-page-banner--accent { background: linear-gradient(90deg, #303f9f, #3949ab); --gb-banner-ink: #283593; }
.gb-page-banner--muted { background: linear-gradient(90deg, #546e7a, #78909c); --gb-banner-ink: #37474f; }

.gb-referral-code {
  font-family: ui-monospace, monospace;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: .04em;
}

.gb-plan-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 10px 16px;
  margin-bottom: var(--gb-gutter);
  border-radius: var(--gb-radius);
  background: var(--gb-warning);
  color: #fff;
  font-size: 13px;
}

.gb-plan-banner .material-icons { font-size: 18px; }

.gb-plan-banner a {
  color: #fff;
  font-weight: 600;
  text-decoration: underline;
  margin-left: auto;
}

.gb-page-banner__icon {
  flex: 0 0 40px;
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--gb-radius);
  background: rgba(255, 255, 255, .18);
}

.gb-page-banner__icon .material-icons { font-size: 22px; color: #fff; }

.gb-page-banner__text { flex: 1 1 240px; min-width: 0; }

.gb-page-banner__title {
  margin: 0;
  font-size: 18px;
  font-weight: 500;
  color: #fff;
  letter-spacing: .2px;
}

.gb-page-banner__subtitle {
  margin: 2px 0 0;
  font-size: 12px;
  color: rgba(255, 255, 255, .88);
}

.gb-page-banner__actions {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

/* Buttons dropped into a banner read as light-on-colour. The banner keeps the
   same gradient in both themes, so these pairs are deliberately fixed rather
   than token-driven — a dark-mode --gb-text would vanish on the white fill.

   Secondary actions darken the banner rather than lightening it: a white
   scrim only lifts white text from 3.6:1 to 3.7:1 at the light end of a
   gradient, whereas .38 black clears AA on every variant (4.7:1 on the
   lightest, --exchange; 8.9:1 on --primary). The white border is what still
   reads them as buttons. */
.gb-page-banner__actions .gb-btn {
  background: rgba(0, 0, 0, .38);
  border: 1px solid rgba(255, 255, 255, .72);
  color: #fff;
  box-shadow: none;
}

.gb-page-banner__actions .gb-btn:hover,
.gb-page-banner__actions .gb-btn:focus {
  background: rgba(0, 0, 0, .5);
  border-color: #fff;
  color: #fff;
}

/* The banner's own call to action — a solid white pill inked in the banner's
   own hue (--gb-banner-ink, set per variant above). */
.gb-page-banner__actions .gb-btn--primary,
.gb-page-banner__actions .gb-btn--light {
  background: #fff;
  border-color: #fff;
  color: var(--gb-banner-ink, #37474f);
  box-shadow: var(--gb-elev-1);
}

.gb-page-banner__actions .gb-btn--primary:hover,
.gb-page-banner__actions .gb-btn--primary:focus,
.gb-page-banner__actions .gb-btn--light:hover,
.gb-page-banner__actions .gb-btn--light:focus {
  background: #eceff1;
  border-color: #eceff1;
  color: var(--gb-banner-ink, #37474f);
}

/* ==========================================================================
   10  Amounts — colour is never the only carrier of meaning, so callers pair
   these with a +/- sign or a type label (contract §6 accessibility).
   ========================================================================== */

.gb-amount {
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  white-space: nowrap;
  color: var(--gb-text);
}

.gb-amount--expense { color: var(--gb-expense); }
.gb-amount--income { color: var(--gb-income); }
.gb-amount--exchange { color: var(--gb-exchange); }
.gb-amount--muted { color: var(--gb-text-muted); font-weight: 400; }
.gb-amount--lg { font-size: 18px; }
.gb-amount--xl { font-size: 24px; font-weight: 400; }
.gb-amount--sm { font-size: 12px; }

/* ==========================================================================
   11  Chips — action types and statuses
   ========================================================================== */

.gb-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  max-width: 100%;
  height: 22px;
  padding: 0 9px;
  border: 0;
  border-radius: var(--gb-radius-pill);
  background: #eceff1;
  color: #546e7a;
  font-size: 11px;
  font-weight: 500;
  line-height: 22px;
  letter-spacing: .3px;
  white-space: nowrap;
  vertical-align: middle;
}

.gb-chip .material-icons { font-size: 13px; }

.gb-chip__label { overflow: hidden; text-overflow: ellipsis; }

.gb-chip--expense { background: rgba(244, 67, 54, .12); color: #c62828; }
.gb-chip--income { background: rgba(76, 175, 80, .14); color: #2e7d32; }
.gb-chip--exchange { background: rgba(255, 152, 0, .16); color: #e65100; }
.gb-chip--primary { background: rgba(var(--gb-primary-rgb), .12); color: var(--gb-primary-ink); }
.gb-chip--info { background: rgba(0, 188, 212, .14); color: #00838f; }
.gb-chip--accent { background: rgba(57, 73, 171, .12); color: #283593; }
.gb-chip--success { background: rgba(67, 160, 71, .14); color: #2e7d32; }
.gb-chip--warning { background: rgba(251, 140, 0, .16); color: #ef6c00; }
.gb-chip--danger { background: rgba(229, 57, 53, .12); color: #c62828; }
.gb-chip--muted { background: #eceff1; color: var(--gb-text-muted); }
.gb-chip--pink { background: rgba(233, 30, 99, .12); color: #ad1457; }

/* Solid variants for statuses that must shout (overdue, cancelled). */
.gb-chip--solid { color: #fff; }
.gb-chip--solid.gb-chip--expense,
.gb-chip--solid.gb-chip--danger { background: var(--gb-danger); color: #fff; }
.gb-chip--solid.gb-chip--income,
.gb-chip--solid.gb-chip--success { background: var(--gb-success); color: #fff; }
.gb-chip--solid.gb-chip--exchange,
.gb-chip--solid.gb-chip--warning { background: var(--gb-warning); color: #fff; }
.gb-chip--solid.gb-chip--info { background: #0097a7; color: #fff; }
.gb-chip--solid.gb-chip--primary { background: var(--gb-primary); color: #fff; }
.gb-chip--solid.gb-chip--muted { background: var(--gb-text-muted); color: #fff; }

.gb-chip--sm { height: 18px; line-height: 18px; font-size: 10px; padding: 0 7px; }
.gb-chip--lg { height: 26px; line-height: 26px; font-size: 12px; padding: 0 12px; }

/* A chip that is also a link/button. */
a.gb-chip,
button.gb-chip { cursor: pointer; transition: filter var(--gb-dur) var(--gb-ease); }
a.gb-chip:hover,
button.gb-chip:hover { filter: brightness(.94); }

/* ==========================================================================
   12  Badges — small pill counters
   ========================================================================== */

.gb-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 6px;
  border-radius: var(--gb-radius-pill);
  background: var(--gb-text-muted);
  color: #fff;
  font-size: 10px;
  font-weight: 500;
  line-height: 1;
  vertical-align: middle;
}

.gb-badge--primary { background: var(--gb-primary); }
.gb-badge--expense, .gb-badge--danger { background: var(--gb-expense); }
.gb-badge--income, .gb-badge--success { background: var(--gb-income); }
.gb-badge--exchange, .gb-badge--warning { background: var(--gb-exchange); }
.gb-badge--info { background: var(--gb-info); }
.gb-badge--accent { background: var(--gb-accent); }
.gb-badge--muted { background: #cfd8dc; color: #546e7a; }
.gb-badge--outline {
  background: transparent;
  border: 1px solid var(--gb-border);
  color: var(--gb-text-muted);
}

/* ==========================================================================
   13  Key/value rows — detail pages
   ========================================================================== */

.gb-kv {
  margin: 0;
  display: grid;
  grid-template-columns: minmax(120px, 34%) 1fr;
  gap: 0;
}

.gb-kv__label,
.gb-kv__value {
  padding: 9px 0;
  border-bottom: 1px solid var(--gb-border);
  min-width: 0;
  margin: 0;
}

.gb-kv__label {
  color: var(--gb-text-muted);
  font-size: 12px;
  padding-right: 12px;
  font-weight: 400;
}

.gb-kv__value {
  color: var(--gb-text);
  font-size: 13px;
  word-break: break-word;
}

.gb-kv__label:last-of-type,
.gb-kv__value:last-of-type { border-bottom: 0; }

.gb-kv--tight .gb-kv__label,
.gb-kv--tight .gb-kv__value { padding-top: 5px; padding-bottom: 5px; }

.gb-kv--plain .gb-kv__label,
.gb-kv--plain .gb-kv__value { border-bottom: 0; }

@media (max-width: 575.98px) {
  .gb-kv { grid-template-columns: 1fr; }
  .gb-kv__label { padding-bottom: 0; border-bottom: 0; }
  .gb-kv__value { padding-top: 2px; }
}

/* ==========================================================================
   14  Progress — debt / loan completion
   ========================================================================== */

.gb-progress {
  position: relative;
  height: 6px;
  border-radius: var(--gb-radius-pill);
  background: var(--gb-border);
  overflow: hidden;
}

.gb-progress__bar {
  display: block;
  height: 100%;
  width: 0;
  border-radius: inherit;
  background: var(--gb-primary);
  transition: width 320ms var(--gb-ease);
}

.gb-progress--lg { height: 10px; }
.gb-progress--sm { height: 4px; }

.gb-progress__bar--income, .gb-progress__bar--success { background: var(--gb-income); }
.gb-progress__bar--expense, .gb-progress__bar--danger { background: var(--gb-expense); }
.gb-progress__bar--exchange, .gb-progress__bar--warning { background: var(--gb-exchange); }
.gb-progress__bar--info { background: var(--gb-info); }
.gb-progress__bar--accent { background: var(--gb-accent); }
.gb-progress__bar--muted { background: var(--gb-text-muted); }

.gb-progress-wrap { display: block; }

.gb-progress-wrap__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 4px;
  font-size: 11px;
  color: var(--gb-text-muted);
}

.gb-progress-wrap__value { font-variant-numeric: tabular-nums; font-weight: 500; }

/* ==========================================================================
   15  Empty states
   ========================================================================== */

.gb-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 40px 20px;
  color: var(--gb-text-muted);
}

.gb-empty__icon {
  font-size: 56px;
  line-height: 1;
  color: #cfd8dc;
  margin-bottom: 12px;
}

.gb-empty__title {
  margin: 0 0 4px;
  font-size: 15px;
  font-weight: 500;
  color: var(--gb-text);
}

.gb-empty__message {
  margin: 0;
  font-size: 12px;
  max-width: 420px;
}

.gb-empty__actions { margin-top: 16px; display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; }

.gb-empty--sm { padding: 22px 16px; }
.gb-empty--sm .gb-empty__icon { font-size: 36px; margin-bottom: 8px; }

/* ==========================================================================
   16  Toolbars & filter bars
   ========================================================================== */

.gb-toolbar {
  display: flex;
  align-items: flex-end;
  gap: 12px;
  flex-wrap: wrap;
  padding: 12px 16px;
  margin-bottom: var(--gb-gutter);
  background: var(--gb-surface);
  border-radius: var(--gb-radius);
  box-shadow: var(--gb-elev-1);
}

.gb-toolbar--plain { box-shadow: none; background: transparent; padding: 0; }

.gb-toolbar__item { flex: 0 1 200px; min-width: 140px; }
.gb-toolbar__item--grow { flex: 1 1 220px; }
.gb-toolbar__item--sm { flex: 0 1 140px; min-width: 110px; }

.gb-toolbar__actions {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding-bottom: 2px;
}

.gb-toolbar__title {
  font-size: 12px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .6px;
  color: var(--gb-text-muted);
  flex: 0 0 auto;
  padding-bottom: 10px;
}

/* The toolbar's fields sit lower than plain text, so nudge the actions. */
.gb-toolbar .gb-field { margin-bottom: 0; }

@media (max-width: 575.98px) {
  .gb-toolbar__item,
  .gb-toolbar__item--grow,
  .gb-toolbar__item--sm { flex: 1 1 100%; }
  .gb-toolbar__actions { margin-left: 0; width: 100%; }
}

/* ==========================================================================
   17  Form fields — Material underline
   --------------------------------------------------------------------------
   Markup contract (see resources/views/components/field.blade.php):

     <div class="gb-field">
       <div class="gb-field__control">
         <input class="gb-field__input" id="…" placeholder=" ">
         <label class="gb-field__label" for="…">Label</label>
         <span class="gb-field__bar"></span>
       </div>
       <p class="gb-field__help">…</p>
       <p class="gb-field__error">…</p>
     </div>

   The label starts life as placeholder text sitting on the input baseline and
   floats to 11px above it when the field is focused or filled. Three things
   can float it:
     * :focus-within                      — while the control has focus
     * .gb-field--filled                  — toggled by GB.initFields()
     * input:not(:placeholder-shown)       — CSS-only safety net for text
                                             inputs (needs placeholder=" ")
   `--float` forces the floated state for controls that always render their
   own value chrome (date/time pickers, selects).
   ========================================================================== */

.gb-field {
  position: relative;
  display: block;
  margin-bottom: 14px;
  min-width: 0;
}

.gb-field__control {
  position: relative;
  display: block;
  padding-top: 16px;
}

/* :not(.ts-wrapper) on .gb-field__select here for the same reason as the
   caret rule below: Tom Select copies the native <select>'s classes onto its
   wrapper div, and this rule's own padding/border would otherwise stack on
   top of the enhanced control's own (see "Fancy selects"), doubling the
   border line and inflating the field's height. */
.gb-field__input,
.gb-field__select:not(.ts-wrapper),
.gb-field__textarea {
  display: block;
  width: 100%;
  margin: 0;
  padding: 6px 0 8px;
  border: 0;
  border-bottom: 1px solid var(--gb-border);
  border-radius: 0;
  background: transparent;
  color: var(--gb-text);
  font-family: inherit;
  font-size: 13px;
  line-height: 20px;
  box-shadow: none;
  transition: border-color var(--gb-dur) var(--gb-ease);
  appearance: none;
  -webkit-appearance: none;
}

.gb-field__input:focus,
.gb-field__select:focus,
.gb-field__textarea:focus {
  outline: 0;
  box-shadow: none;
  border-bottom-color: var(--gb-primary);
}

/* Hide the browser placeholder: the floating label plays that role. A
   single space is used as the placeholder so :placeholder-shown works. */
.gb-field__input::placeholder,
.gb-field__textarea::placeholder { color: transparent; }

.gb-field__input:focus::placeholder,
.gb-field__textarea:focus::placeholder { color: #b0bec5; }

.gb-field__textarea { resize: vertical; min-height: 72px; line-height: 1.5; }

/* Compact variant for a field embedded in a dense table row (e.g. the
   statement-import review grid): no floating-label space reserved — the
   column header already labels it — and tight vertical rhythm so a few
   hundred rows don't balloon the page. */
.gb-field--table { margin-bottom: 0; }
.gb-field--table .gb-field__control { padding-top: 0; }
.gb-field--table .gb-field__input,
.gb-field--table .gb-field__select:not(.ts-wrapper) { padding: 4px 0; font-size: 13px; }
.gb-field--table .gb-field__label { display: none; }

/* <x-checkbox-field> has no wrapper-class prop of its own, so this reaches
   it structurally wherever it ends up inside a table cell. */
.gb-table .gb-check { margin-bottom: 0; }

/* table-layout:auto treats a <th width> as a hint only and is free to hand
   leftover row width to whichever column it likes — on the statement-import
   review grid that put almost all of it into Amount, stretching a short
   right-aligned number across a huge blank cell. Fixed layout makes the
   declared widths binding; the one column left unset (Description) absorbs
   what remains. */
.gb-table--fixed { table-layout: fixed; }

/* :not(.ts-wrapper) matters here: Tom Select copies the original <select>'s
   classes onto its wrapper div, so a plain .gb-field__select rule would also
   paint this native caret on top of the one drawn for the enhanced control
   (see the "Fancy selects" section), producing two overlapping arrows. */
.gb-field__select:not(.ts-wrapper) {
  padding-right: 22px;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--gb-text-muted) 50%),
    linear-gradient(135deg, var(--gb-text-muted) 50%, transparent 50%);
  background-position: right 7px top 50%, right 2px top 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  cursor: pointer;
}

.gb-field__select[multiple] {
  background-image: none;
  padding-right: 0;
  min-height: 96px;
}

.gb-field__label {
  position: absolute;
  left: 0;
  top: 22px;
  margin: 0;
  max-width: 100%;
  color: var(--gb-text-muted);
  font-size: 13px;
  line-height: 20px;
  pointer-events: none;
  transform-origin: left top;
  transition: transform var(--gb-dur) var(--gb-ease),
              color var(--gb-dur) var(--gb-ease),
              font-size var(--gb-dur) var(--gb-ease);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The animated focus underline that grows from the centre. */
.gb-field__bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: var(--gb-primary);
  transform: scaleX(0);
  transform-origin: center;
  transition: transform var(--gb-dur) var(--gb-ease), background-color var(--gb-dur) var(--gb-ease);
  pointer-events: none;
}

.gb-field:focus-within .gb-field__bar { transform: scaleX(1); }

/* ---- Floated label states ------------------------------------------------ */

.gb-field:focus-within .gb-field__label,
.gb-field--filled .gb-field__label,
.gb-field--float .gb-field__label,
.gb-field__input:not(:placeholder-shown) ~ .gb-field__label,
.gb-field__textarea:not(:placeholder-shown) ~ .gb-field__label {
  top: 0;
  font-size: 11px;
  line-height: 14px;
}

.gb-field:focus-within .gb-field__label { color: var(--gb-primary); }

/* Required marker. */
.gb-field__label .gb-field__req { color: var(--gb-expense); margin-left: 2px; }

/* ---- Help & error -------------------------------------------------------- */

.gb-field__help,
.gb-field__error {
  margin: 4px 0 0;
  font-size: 11px;
  line-height: 1.4;
}

.gb-field__help { color: var(--gb-text-muted); }
.gb-field__error { color: var(--gb-expense); display: none; }

.gb-field--error .gb-field__error { display: block; }

.gb-field--error .gb-field__input,
.gb-field--error .gb-field__select,
.gb-field--error .gb-field__textarea { border-bottom-color: var(--gb-expense); }

.gb-field--error .gb-field__label { color: var(--gb-expense); }
.gb-field--error .gb-field__bar { background: var(--gb-expense); }
.gb-field--error:focus-within .gb-field__label { color: var(--gb-expense); }

/* ---- Disabled / readonly ------------------------------------------------- */

.gb-field__input:disabled,
.gb-field__select:disabled,
.gb-field__textarea:disabled,
.gb-field__input[readonly] {
  color: var(--gb-text-muted);
  border-bottom-style: dashed;
  cursor: not-allowed;
  background: transparent;
}

/* ---- Suffix / prefix (currency symbol on money fields) ------------------- */

.gb-field--has-suffix .gb-field__input { padding-right: 46px; }
.gb-field--has-prefix .gb-field__input { padding-left: 22px; }

.gb-field__suffix,
.gb-field__prefix {
  position: absolute;
  bottom: 8px;
  font-size: 12px;
  font-weight: 500;
  color: var(--gb-text-muted);
  pointer-events: none;
  line-height: 20px;
  max-width: 44px;
  overflow: hidden;
  white-space: nowrap;
}

.gb-field__suffix { right: 0; text-align: right; }
.gb-field__prefix { left: 0; }

/* "Otomatik dolduruldu" — a field the receipt scan wrote into. Sits in the
   label's own row (top: 0) but on the right, so it never fights the label
   for space; removed the moment the field is touched (see GB.initReceiptScan
   markAutoFilled() -> clear()). */
.gb-receipt-scan__badge {
  position: absolute;
  top: 0;
  right: 0;
  pointer-events: none;
}

/* Money inputs read as figures. */
.gb-field--money .gb-field__input {
  text-align: right;
  font-variant-numeric: tabular-nums;
  padding-right: 46px;
}

/* Strip the spinner from number inputs — money is typed, not nudged. */
.gb-field__input[type="number"] { -moz-appearance: textfield; }
.gb-field__input[type="number"]::-webkit-outer-spin-button,
.gb-field__input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* Date & time controls keep their native picker but lose the chrome. */
.gb-field__input[type="date"],
.gb-field__input[type="datetime-local"],
.gb-field__input[type="time"],
.gb-field__input[type="month"] { min-height: 34px; }

.gb-field__input[type="date"]::-webkit-calendar-picker-indicator,
.gb-field__input[type="datetime-local"]::-webkit-calendar-picker-indicator,
.gb-field__input[type="time"]::-webkit-calendar-picker-indicator {
  opacity: .5;
  cursor: pointer;
}

.gb-field__input[type="color"] {
  height: 34px;
  padding: 2px 0;
  cursor: pointer;
}

.gb-field__input[type="file"] {
  padding-top: 4px;
  font-size: 12px;
}

/* ---- Checkbox / radio ---------------------------------------------------- */

.gb-check {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin-bottom: 12px;
  min-height: 20px;
}

.gb-check__input {
  flex: 0 0 16px;
  width: 16px;
  height: 16px;
  margin: 2px 0 0;
  accent-color: var(--gb-primary);
  cursor: pointer;
}

.gb-check__body { min-width: 0; }

.gb-check__label {
  display: block;
  margin: 0;
  font-size: 13px;
  color: var(--gb-text);
  cursor: pointer;
}

.gb-check__help {
  display: block;
  margin: 1px 0 0;
  font-size: 11px;
  color: var(--gb-text-muted);
}

.gb-check__error {
  display: block;
  margin: 2px 0 0;
  font-size: 11px;
  color: var(--gb-expense);
}

.gb-check--inline { display: inline-flex; margin-right: 18px; }

/* Same native input + accent-color as .gb-check__input, sized for a table
   cell instead of a form row (no label, no bottom margin). */
.gb-table-select {
  width: 16px;
  height: 16px;
  margin: 0;
  accent-color: var(--gb-primary);
  cursor: pointer;
  vertical-align: middle;
}

/* ---- Colour field: 8 predefined swatches + a genuine custom colour ------- */

.gb-color-field { margin-bottom: 14px; }

.gb-color-field__label {
  /* Explicit: this caption is in normal flow. .gb-field__label, which it used
     to also carry, is absolute — and with no positioned ancestor here it
     escaped to the top-left corner of the card. */
  position: static;
  display: block;
  margin: 0 0 8px;
  color: var(--gb-text-muted);
  font-size: 13px;
  line-height: 20px;
}

.gb-color-field__swatches {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.gb-color-field__swatch {
  position: relative;
  width: 32px;
  height: 32px;
  flex: 0 0 32px;
  border-radius: 50%;
  border: 2px solid transparent;
  background: var(--gb-swatch);
  padding: 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .18);
  transition: transform var(--gb-dur) var(--gb-ease), border-color var(--gb-dur) var(--gb-ease);
}

.gb-color-field__swatch:hover { transform: scale(1.08); }

.gb-color-field__swatch:focus-visible {
  outline: 2px solid var(--gb-primary-2);
  outline-offset: 2px;
}

.gb-color-field__swatch.is-active {
  border-color: #fff;
  box-shadow: 0 0 0 2px var(--gb-swatch), 0 1px 3px rgba(0, 0, 0, .3);
}

.gb-color-field__swatch .material-icons {
  font-size: 16px;
  color: #fff;
  text-shadow: 0 1px 1px rgba(0, 0, 0, .35);
}

/* The "custom" swatch: a conic rainbow ring until a custom colour is picked,
   then it shows that colour like any other swatch. The real <input
   type="color"> sits on top, fully transparent, so a click opens the native
   picker while the swatch itself stays perfectly round. */
.gb-color-field__swatch--custom {
  background:
    var(--gb-swatch, transparent) no-repeat center / cover,
    conic-gradient(from 0deg, #f44336, #ff9800, #ffeb3b, #4caf50, #00bcd4, #3949ab, #8e24aa, #e91e63, #f44336);
}

.gb-color-field__swatch--custom.is-active { background: var(--gb-swatch); }

.gb-color-field__native {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
  border: 0;
  padding: 0;
}

/* A row of radios rendered as a segmented type picker (expense/income/…). */
.gb-segment {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 14px;
}

.gb-segment__option { position: relative; }

.gb-segment__input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}

.gb-segment__label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 14px;
  border: 1px solid var(--gb-border);
  border-radius: var(--gb-radius-pill);
  background: var(--gb-surface);
  color: var(--gb-text-muted);
  font-size: 12px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .4px;
  cursor: pointer;
  transition: all var(--gb-dur) var(--gb-ease);
}

.gb-segment__label .material-icons { font-size: 16px; }

.gb-segment__input:checked + .gb-segment__label {
  background: var(--gb-primary);
  border-color: var(--gb-primary);
  color: #fff;
}

.gb-segment__input:focus-visible + .gb-segment__label {
  outline: 2px solid var(--gb-primary-2);
  outline-offset: 2px;
}

.gb-segment__input:checked + .gb-segment__label.is-expense { background: var(--gb-expense); border-color: var(--gb-expense); }
.gb-segment__input:checked + .gb-segment__label.is-income { background: var(--gb-income); border-color: var(--gb-income); }
.gb-segment__input:checked + .gb-segment__label.is-exchange { background: var(--gb-exchange); border-color: var(--gb-exchange); }

/* Field grid used by every form page. */
.gb-form-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 0 18px;
}

.gb-col-12 { grid-column: span 12; }
.gb-col-10 { grid-column: span 10; }
.gb-col-9 { grid-column: span 9; }
.gb-col-8 { grid-column: span 8; }
.gb-col-7 { grid-column: span 7; }
.gb-col-6 { grid-column: span 6; }
.gb-col-5 { grid-column: span 5; }
.gb-col-4 { grid-column: span 4; }
.gb-col-3 { grid-column: span 3; }
.gb-col-2 { grid-column: span 2; }

@media (max-width: 767.98px) {
  .gb-col-10, .gb-col-9, .gb-col-8, .gb-col-7,
  .gb-col-6, .gb-col-5, .gb-col-4, .gb-col-3, .gb-col-2 { grid-column: span 12; }
}

/*
 * Wide screens buy COLUMNS, not width.
 *
 * A 12-column grid on an unbounded page turns a pair of fields into two 900px
 * boxes, which is the shape this whole section exists to prevent. Past 1500px
 * every span shrinks by roughly a third instead: a pair becomes a trio, a trio
 * becomes a quartet, and a field stays in the 350–550px band where it is
 * actually read. The page gets shorter rather than the inputs getting fatter.
 *
 * Form pages only — a report or a statement wants its full width.
 */
@media (min-width: 1600px) {
  .gb-content--form .gb-col-12 { grid-column: span 8; }
  .gb-content--form .gb-col-10 { grid-column: span 7; }
  .gb-content--form .gb-col-9 { grid-column: span 6; }
  .gb-content--form .gb-col-8 { grid-column: span 5; }
  .gb-content--form .gb-col-7 { grid-column: span 5; }
  .gb-content--form .gb-col-6 { grid-column: span 4; }
  .gb-content--form .gb-col-5 { grid-column: span 3; }
  .gb-content--form .gb-col-4 { grid-column: span 3; }

  /* A swatch row and a checkbox pair are laid out by their own content; taking
     columns off them only makes the swatches wrap. */
  .gb-content--form .gb-col-12.gb-col--keep { grid-column: span 12; }
}

/* One more step, or a 2560px monitor puts the fields back at ~590px — most of
   the way back to the sprawl this section exists to stop. Four to a row keeps
   every field inside the same 280–490px band the narrower breakpoints hold. */
@media (min-width: 2200px) {
  .gb-content--form .gb-col-12 { grid-column: span 6; }
  .gb-content--form .gb-col-10 { grid-column: span 5; }
  .gb-content--form .gb-col-9 { grid-column: span 5; }
  .gb-content--form .gb-col-8 { grid-column: span 4; }
  .gb-content--form .gb-col-7 { grid-column: span 4; }
  .gb-content--form .gb-col-6 { grid-column: span 3; }
  .gb-content--form .gb-col-5 { grid-column: span 3; }
  .gb-content--form .gb-col-4 { grid-column: span 2; }

  .gb-content--form .gb-col-12.gb-col--keep { grid-column: span 12; }
}

/* ==========================================================================
   29  Form pages — the readable column
   ==========================================================================
   Nothing used to cap a page's width, so a 12-column grid spread across every
   pixel the monitor had. On a 2000px screen "Amount" was a 530px box holding
   eight characters, "Description" was 1660px wide, and a field's label sat a
   thousand pixels from the next thing worth reading.

   The cap is on the CONTENT COLUMN rather than on the card, so the page banner
   narrows with the form instead of towering over it. Listings, reports and
   statements do not carry the class: there, width is doing something.

   1080px is chosen from what it makes the columns: col-6 ≈ 510px, col-4 ≈ 335px,
   col-3 ≈ 245px — and it is also just enough for the split action form's two
   panes (≈ 680 + 340).
   ========================================================================== */

/* Centred, not left-anchored. A capped column pinned to the left of a 2000px
   monitor leaves 900px of empty grey on one side, which reads as a page that
   failed to finish loading rather than as a deliberate measure.

   The cap is deliberately loose: a form page fills the monitor it is opened on.
   What keeps it readable is NOT this number but the span rules below — extra
   width buys extra COLUMNS, never fatter fields. Tighten this one number if a
   form ever wants to be a narrow measure again. */
/* `width: 100%` is load-bearing: .gb-content is a column-flex item, and an
   auto inline margin makes such an item shrink-to-fit its content instead of
   filling its parent. Without it the page silently sized itself to whatever
   the form happened to contain. */
.gb-content--form { width: 100%; max-width: 2280px; margin-inline: auto; }

/* ---------------------------------------------- The split (two-pane) form -- */

/* Main entry path on the left, the optional things on the right: attachments
   and the two flags that most transactions never touch. It uses the horizontal
   room rather than merely refusing it, and takes a screenful of height out of
   the page. Below 992px it is one column again, secondary content last. */
.gb-form-split {
  display: grid;
  /* The secondary pane is sized in pixels, not in fractions: a drop zone and
     two checkboxes get no better at 700px, so every pixel past its ceiling
     belongs to the entry path on the left. */
  grid-template-columns: minmax(0, 1fr) minmax(260px, 380px);
  gap: 0 24px;
  align-items: start;
}

/* A divider, not a panel. Filling and bordering it made a box inside the card
   it already sits in, and two nested containers is heavier than the secondary
   content inside them deserves. */
.gb-form-aside {
  padding-left: 24px;
  border-left: 1px solid var(--gb-border);
}

.gb-form-aside__title {
  margin: 0 0 10px;
  color: var(--gb-text-muted);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .6px;
  text-transform: uppercase;
}

.gb-form-aside__group + .gb-form-aside__group {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--gb-border);
}

/* Stacked, the divider has to move from the side to the top or it points at
   nothing. */
@media (max-width: 991.98px) {
  .gb-form-split { grid-template-columns: minmax(0, 1fr); }

  .gb-form-aside {
    margin-top: 6px;
    padding-left: 0;
    padding-top: 16px;
    border-left: 0;
    border-top: 1px solid var(--gb-border);
  }
}

.gb-form-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--gb-border);
}

.gb-form-actions--end { justify-content: flex-end; }

.gb-fieldset {
  border: 0;
  padding: 0;
  margin: 0 0 8px;
}

.gb-fieldset__legend {
  display: block;
  width: 100%;
  padding: 0 0 8px;
  margin: 0 0 12px;
  border-bottom: 1px solid var(--gb-border);
  font-size: 12px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .8px;
  color: var(--gb-text-muted);
  float: none;
}

/* ==========================================================================
   18  Buttons
   --------------------------------------------------------------------------
   Uppercase, 500 weight, .5px tracking, 2px radius. No ripple, but a clear
   press: the elevation drops and the button moves 1px down on :active.
   ========================================================================== */

.gb-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 34px;
  padding: 0 16px;
  border: 0;
  border-radius: var(--gb-radius-sm);
  background: var(--gb-bg);
  color: var(--gb-text);
  font-family: inherit;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .5px;
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: var(--gb-elev-1);
  transition: background-color var(--gb-dur) var(--gb-ease),
              box-shadow var(--gb-dur) var(--gb-ease),
              color var(--gb-dur) var(--gb-ease),
              transform 60ms var(--gb-ease);
  user-select: none;
}

.gb-btn .material-icons { font-size: 17px; }

.gb-btn:hover { background: var(--gb-surface-hover); color: var(--gb-text); box-shadow: var(--gb-elev-2); }
.gb-btn:active { transform: translateY(1px); box-shadow: none; }
.gb-btn:disabled,
.gb-btn.is-disabled {
  opacity: .55;
  cursor: not-allowed;
  box-shadow: none;
  pointer-events: none;
}

.gb-btn--primary { background: var(--gb-primary); color: #fff; }
.gb-btn--primary:hover, .gb-btn--primary:focus { background: var(--gb-primary-hover); color: #fff; }

.gb-btn--success { background: var(--gb-success); color: #fff; }
.gb-btn--success:hover, .gb-btn--success:focus { background: #2e7d32; color: #fff; }

.gb-btn--danger { background: var(--gb-danger); color: #fff; }
.gb-btn--danger:hover, .gb-btn--danger:focus { background: #c62828; color: #fff; }

.gb-btn--info { background: var(--gb-info); color: #fff; }
.gb-btn--info:hover, .gb-btn--info:focus { background: #0097a7; color: #fff; }

.gb-btn--accent { background: var(--gb-accent); color: #fff; }
.gb-btn--accent:hover, .gb-btn--accent:focus { background: #303f9f; color: #fff; }

.gb-btn--warning { background: var(--gb-warning); color: #fff; }
.gb-btn--warning:hover, .gb-btn--warning:focus { background: #ef6c00; color: #fff; }

.gb-btn--dark { background: #455a64; color: #fff; }
.gb-btn--dark:hover, .gb-btn--dark:focus { background: #37474f; color: #fff; }

.gb-btn--light { background: var(--gb-surface); color: var(--gb-text); }
.gb-btn--light:hover, .gb-btn--light:focus { background: var(--gb-topbar); color: var(--gb-text); }

.gb-btn--flat {
  background: transparent;
  box-shadow: none;
  color: var(--gb-primary);
}

.gb-btn--flat:hover, .gb-btn--flat:focus {
  background: rgba(var(--gb-primary-rgb), .08);
  box-shadow: none;
  color: var(--gb-primary);
}

.gb-btn--flat.gb-btn--danger {
  background: transparent;
  color: var(--gb-danger);
}

.gb-btn--flat.gb-btn--danger:hover, .gb-btn--flat.gb-btn--danger:focus {
  background: rgba(229, 57, 53, .08);
  color: var(--gb-danger);
}

.gb-btn--flat.gb-btn--muted { color: var(--gb-text-muted); }
.gb-btn--flat.gb-btn--muted:hover { background: rgba(var(--gb-overlay-rgb), .07); color: var(--gb-text); }

.gb-btn--outline {
  background: transparent;
  box-shadow: none;
  border: 1px solid var(--gb-border);
  color: var(--gb-text);
}

.gb-btn--outline:hover, .gb-btn--outline:focus { background: var(--gb-topbar); box-shadow: none; }

.gb-btn--sm { height: 28px; padding: 0 11px; font-size: 11px; }
.gb-btn--sm .material-icons { font-size: 15px; }

.gb-btn--lg { height: 40px; padding: 0 22px; font-size: 13px; }

.gb-btn--block { width: 100%; }

.gb-btn--icon-only { width: 34px; padding: 0; }
.gb-btn--icon-only.gb-btn--sm { width: 28px; }

.gb-btn-group {
  display: inline-flex;
  gap: 6px;
  flex-wrap: wrap;
  align-items: center;
}

/* Round icon button, used in table rows and card headers. */
.gb-btn-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  flex: 0 0 32px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--gb-text-muted);
  cursor: pointer;
  transition: background-color var(--gb-dur) var(--gb-ease), color var(--gb-dur) var(--gb-ease);
}

.gb-btn-icon .material-icons { font-size: 18px; }

.gb-btn-icon:hover,
.gb-btn-icon:focus { background: rgba(var(--gb-overlay-rgb), .09); color: var(--gb-text); }

.gb-btn-icon:active { background: rgba(var(--gb-overlay-rgb), .16); }

.gb-btn-icon--sm { width: 26px; height: 26px; flex-basis: 26px; }
.gb-btn-icon--sm .material-icons { font-size: 16px; }

.gb-btn-icon--primary { color: var(--gb-primary); }
.gb-btn-icon--primary:hover { background: rgba(var(--gb-primary-rgb), .1); color: var(--gb-primary); }
.gb-btn-icon--danger { color: var(--gb-danger); }
.gb-btn-icon--danger:hover { background: rgba(229, 57, 53, .1); color: var(--gb-danger); }
.gb-btn-icon--info { color: #0097a7; }
.gb-btn-icon--info:hover { background: rgba(0, 188, 212, .12); color: #0097a7; }
.gb-btn-icon--light { color: rgba(255, 255, 255, .9); }
.gb-btn-icon--light:hover { background: rgba(255, 255, 255, .16); color: #fff; }

.gb-btn-icon:disabled { opacity: .4; pointer-events: none; }

/* A form that only wraps a destructive button must not disturb the layout. */
.gb-inline-form { display: inline; margin: 0; }

/* ==========================================================================
   19  Tables
   --------------------------------------------------------------------------
   .gb-table-wrap  overflow-x container — required on every table
   .gb-table       13px Material data table
   .gb-table--hover, .gb-table--sticky, .is-numeric cells right aligned
   ========================================================================== */

.gb-table-wrap {
  width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.gb-table-wrap--tall { max-height: 460px; overflow-y: auto; }

.gb-table {
  width: 100%;
  margin: 0;
  border-collapse: collapse;
  font-size: 13px;
  color: var(--gb-text);
  background: transparent;
}

.gb-table th,
.gb-table td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--gb-border);
  text-align: left;
  vertical-align: middle;
}

.gb-table thead th {
  font-size: 11px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .6px;
  color: var(--gb-text-muted);
  background: var(--gb-surface-alt);
  white-space: nowrap;
  border-bottom: 1px solid var(--gb-border);
}

.gb-table tbody tr:last-child td { border-bottom: 0; }

.gb-table--hover tbody tr { transition: background-color 120ms var(--gb-ease); }
.gb-table--hover tbody tr:hover { background: rgba(var(--gb-overlay-rgb), .045); }

.gb-table--striped tbody tr:nth-child(odd) { background: rgba(var(--gb-overlay-rgb), .02); }
.gb-table--striped.gb-table--hover tbody tr:hover { background: rgba(var(--gb-overlay-rgb), .065); }

.gb-table--sticky thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  box-shadow: inset 0 -1px 0 var(--gb-border);
}

.gb-table--compact th,
.gb-table--compact td { padding: 6px 10px; }

.gb-table .is-numeric,
.gb-table th.is-numeric,
.gb-table td.is-numeric {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.gb-table .is-actions,
.gb-table th.is-actions,
.gb-table td.is-actions {
  text-align: right;
  white-space: nowrap;
  width: 1%;
}

.gb-table .is-center { text-align: center; }
.gb-table .is-narrow { width: 1%; white-space: nowrap; }
.gb-table .is-select { width: 1%; white-space: nowrap; text-align: center; padding-right: 4px; }

.gb-table tr.is-selected > td { background: rgba(var(--gb-overlay-rgb), .06); }
.gb-table--striped tr.is-selected:nth-child(odd) > td,
.gb-table--hover tr.is-selected:hover > td { background: rgba(var(--gb-overlay-rgb), .09); }
.gb-table .is-truncate {
  max-width: 240px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.gb-table tfoot td,
.gb-table tfoot th {
  font-weight: 500;
  background: var(--gb-surface-alt);
  border-top: 2px solid var(--gb-border);
  border-bottom: 0;
}

.gb-table__meta {
  display: block;
  font-size: 11px;
  color: var(--gb-text-muted);
  line-height: 1.35;
}

.gb-table__cell-main {
  display: flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
}

.gb-table caption {
  caption-side: top;
  padding: 0 12px 8px;
  font-size: 11px;
  color: var(--gb-text-muted);
  text-align: left;
}

/* Sortable column headers. */
.gb-table__sort {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  color: inherit;
  text-transform: inherit;
  letter-spacing: inherit;
  font: inherit;
}

.gb-table__sort:hover { color: var(--gb-primary); }
.gb-table__sort .material-icons { font-size: 14px; opacity: .55; }
.gb-table__sort.is-active { color: var(--gb-primary); }
.gb-table__sort.is-active .material-icons { opacity: 1; }

/* A row highlighted because it is overdue / needs attention. */
.gb-table tbody tr.is-overdue { background: rgba(244, 67, 54, .05); }
.gb-table tbody tr.is-muted td { color: var(--gb-text-muted); }

/* ==========================================================================
   20  Dropzone
   --------------------------------------------------------------------------
   Dashed 2px border, a large cloud-upload icon behind the prompt, an --active
   state while a drag hovers, and a file list underneath with per-file name,
   size and a remove button.
   ========================================================================== */

.gb-dropzone { margin-bottom: 14px; }

.gb-dropzone__area {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-height: 132px;
  padding: 20px;
  border: 2px dashed #b0bec5;
  border-radius: var(--gb-radius);
  background: var(--gb-surface-alt);
  color: var(--gb-text-muted);
  text-align: center;
  cursor: pointer;
  transition: border-color var(--gb-dur) var(--gb-ease),
              background-color var(--gb-dur) var(--gb-ease),
              color var(--gb-dur) var(--gb-ease);
}

.gb-dropzone__area:hover { border-color: var(--gb-primary-2); background: rgba(var(--gb-primary-2-rgb), .06); }

.gb-dropzone__area:focus-visible {
  outline: 2px solid var(--gb-primary-2);
  outline-offset: 2px;
}

.gb-dropzone__icon {
  font-size: 44px;
  line-height: 1;
  color: #b0bec5;
  transition: color var(--gb-dur) var(--gb-ease), transform var(--gb-dur) var(--gb-ease);
}

.gb-dropzone__prompt {
  margin: 0;
  font-size: 13px;
  font-weight: 500;
  color: var(--gb-text);
}

.gb-dropzone__hint { margin: 0; font-size: 11px; }

.gb-dropzone__input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
}

.gb-dropzone--active .gb-dropzone__area,
.gb-dropzone__area.gb-dropzone--active {
  border-color: var(--gb-primary);
  background: rgba(var(--gb-primary-2-rgb), .14);
  color: var(--gb-primary);
}

.gb-dropzone--active .gb-dropzone__icon {
  color: var(--gb-primary);
  transform: translateY(-2px);
}

.gb-dropzone__error {
  margin: 6px 0 0;
  font-size: 11px;
  color: var(--gb-expense);
  min-height: 0;
}

.gb-dropzone__error:empty { display: none; }

.gb-dropzone__list {
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
  display: grid;
  gap: 6px;
}

.gb-dropzone__list:empty { display: none; }

.gb-file {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 10px;
  border: 1px solid var(--gb-border);
  border-radius: var(--gb-radius);
  background: var(--gb-surface);
  min-width: 0;
}

.gb-file__icon { font-size: 20px; color: var(--gb-text-muted); flex: 0 0 20px; }

.gb-file__meta { min-width: 0; flex: 1 1 auto; }

.gb-file__name {
  display: block;
  font-size: 12px;
  color: var(--gb-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.gb-file__size { display: block; font-size: 11px; color: var(--gb-text-muted); }

.gb-file__actions { display: flex; align-items: center; gap: 2px; flex: 0 0 auto; }

.gb-file--existing { background: var(--gb-surface-alt); }

/* "Fişten oku" — sits right under the dropzone. Hidden entirely (no markup
   at all, not just this CSS) when Gemini is not configured or when editing
   an existing action, see $showReceiptScan in actions/_form.blade.php. */
.gb-receipt-scan__btn { margin-top: 10px; }
.gb-receipt-scan__btn .spinner-border { width: 14px; height: 14px; border-width: 2px; }

.gb-receipt-scan__message {
  margin: 8px 0 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--gb-text-muted);
}

.gb-receipt-scan__message:empty { display: none; }
.gb-receipt-scan__message--success { color: var(--gb-success, #2e7d32); }
.gb-receipt-scan__message--error { color: var(--gb-expense); }
.gb-receipt-scan__message--suggestion { color: var(--gb-text); }
.gb-receipt-scan__message .gb-btn { margin-left: 4px; vertical-align: middle; }

/* The attachment rows on their own, outside the upload control — the detail
   page's list. Same grid; the dropzone variants below only re-space it. */
.gb-file-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 6px;
}

.gb-file-list:empty { display: none; }

/* Files already stored on the server, listed under the freshly picked ones.
   Deliberately a different class from .gb-dropzone__list, which GB.dropzone()
   owns and rewrites on every change. */
.gb-dropzone__existing {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
  display: grid;
  gap: 6px;
}

.gb-dropzone__existing:empty { display: none; }

/* ==========================================================================
   21  Autocomplete (payer/payee + category typeahead, free text allowed)
   ========================================================================== */

.gb-autocomplete { position: relative; }

.gb-autocomplete__menu {
  position: absolute;
  z-index: 1055;
  left: 0;
  right: 0;
  top: 100%;
  margin-top: 2px;
  max-height: 244px;
  overflow-y: auto;
  padding: 4px 0;
  background: var(--gb-surface);
  border-radius: var(--gb-radius);
  box-shadow: var(--gb-elev-2);
  list-style: none;
  display: none;
}

.gb-autocomplete__menu.is-open { display: block; }

.gb-autocomplete__option {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  font-size: 13px;
  color: var(--gb-text);
  cursor: pointer;
  min-width: 0;
}

.gb-autocomplete__option:hover,
.gb-autocomplete__option.is-active { background: rgba(var(--gb-primary-2-rgb), .14); color: var(--gb-primary); }

.gb-autocomplete__option .material-icons { font-size: 16px; color: var(--gb-text-muted); }
.gb-autocomplete__option.is-active .material-icons { color: var(--gb-primary); }

.gb-autocomplete__label {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.gb-autocomplete__hint {
  font-size: 11px;
  color: var(--gb-text-muted);
  flex: 0 0 auto;
}

.gb-autocomplete__empty {
  padding: 8px 12px;
  font-size: 12px;
  color: var(--gb-text-muted);
}

.gb-autocomplete__create { font-style: italic; }

/* ==========================================================================
   22  Flash messages — the four levels used by partials/flash.blade.php
   ========================================================================== */

.gb-flash {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 11px 40px 11px 14px;
  margin-bottom: 14px;
  border-radius: var(--gb-radius);
  border-left: 4px solid var(--gb-text-muted);
  background: var(--gb-surface);
  box-shadow: var(--gb-elev-1);
  font-size: 13px;
  color: var(--gb-text);
}

.gb-flash__icon { font-size: 19px; flex: 0 0 19px; color: var(--gb-text-muted); }

.gb-flash__body { flex: 1 1 auto; min-width: 0; }

.gb-flash__title { display: block; font-weight: 500; margin-bottom: 1px; }

.gb-flash__list { margin: 4px 0 0; padding-left: 18px; }

.gb-flash__close {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--gb-text-muted);
  cursor: pointer;
}

.gb-flash__close:hover { background: rgba(var(--gb-overlay-rgb), .09); color: var(--gb-text); }
.gb-flash__close .material-icons { font-size: 16px; }

.gb-flash--success { border-left-color: var(--gb-income); background: #f1f8f2; }
.gb-flash--success .gb-flash__icon { color: var(--gb-success); }

.gb-flash--error { border-left-color: var(--gb-expense); background: #fdf2f1; }
.gb-flash--error .gb-flash__icon { color: var(--gb-danger); }

.gb-flash--warning { border-left-color: var(--gb-exchange); background: #fff8ef; }
.gb-flash--warning .gb-flash__icon { color: var(--gb-warning); }

.gb-flash--info { border-left-color: var(--gb-info); background: #eff9fb; }
.gb-flash--info .gb-flash__icon { color: #0097a7; }

/* Validation error summary (partials/errors.blade.php). */
.gb-errors {
  border-left-color: var(--gb-expense);
  background: #fdf2f1;
}

.gb-errors__list { margin: 4px 0 0; padding-left: 18px; }
.gb-errors__list li { margin-bottom: 1px; }

/* ==========================================================================
   23  Bootstrap 5 overrides — modal / dropdown / alert / pagination / tooltip
   --------------------------------------------------------------------------
   Loaded after bootstrap.min.css so these win without !important except
   where Bootstrap itself uses a utility-level declaration.
   ========================================================================== */

/* ---- Dropdown ------------------------------------------------------------ */

.dropdown-menu {
  border: 0;
  border-radius: var(--gb-radius);
  box-shadow: var(--gb-elev-2);
  padding: 4px 0;
  font-size: 13px;
  color: var(--gb-text);
  min-width: 190px;
}

.dropdown-item {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 14px;
  color: var(--gb-text);
  font-size: 13px;
}

.dropdown-item .material-icons { font-size: 17px; color: var(--gb-text-muted); }

.dropdown-item:hover,
.dropdown-item:focus {
  background: rgba(var(--gb-primary-2-rgb), .14);
  color: var(--gb-primary);
}

.dropdown-item:hover .material-icons,
.dropdown-item:focus .material-icons { color: var(--gb-primary); }

.dropdown-item:active { background: rgba(var(--gb-primary-2-rgb), .35); color: var(--gb-primary); }

.dropdown-item.is-danger { color: var(--gb-danger); }
.dropdown-item.is-danger .material-icons { color: var(--gb-danger); }
.dropdown-item.is-danger:hover,
.dropdown-item.is-danger:focus { background: #fdecea; color: var(--gb-danger); }

.dropdown-divider { margin: 4px 0; border-top-color: var(--gb-border); }

.dropdown-header {
  padding: 8px 14px 4px;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: .8px;
  text-transform: uppercase;
  color: var(--gb-text-muted);
}

/* A user card at the top of the avatar dropdown. */
.gb-dropdown-user {
  padding: 10px 14px 12px;
  border-bottom: 1px solid var(--gb-border);
  margin-bottom: 4px;
}

.gb-dropdown-user__name { display: block; font-size: 13px; font-weight: 500; }
.gb-dropdown-user__email {
  display: block;
  font-size: 11px;
  color: var(--gb-text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Form inside a dropdown (the log-out POST). */
.dropdown-menu form { margin: 0; }
.dropdown-menu form .dropdown-item {
  width: 100%;
  border: 0;
  background: transparent;
  text-align: left;
  font-family: inherit;
  cursor: pointer;
}

/* ---- Modal --------------------------------------------------------------- */

.modal-content {
  border: 0;
  border-radius: var(--gb-radius);
  box-shadow: var(--gb-elev-8);
  color: var(--gb-text);
}

.modal-header {
  padding: 14px 18px;
  border-bottom: 1px solid var(--gb-border);
  align-items: center;
}

.modal-title {
  font-size: 16px;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 8px;
}

.modal-title .material-icons { font-size: 20px; }

.modal-body { padding: 18px; font-size: 13px; }

.modal-footer {
  padding: 10px 14px;
  border-top: 1px solid var(--gb-border);
  gap: 8px;
}

.modal-footer > * { margin: 0; }

.modal-backdrop { background-color: #000; }
.modal-backdrop.show { opacity: .5; }

.modal-header .btn-close { --bs-btn-close-focus-shadow: none; }

.gb-modal--danger .modal-title { color: var(--gb-danger); }
.gb-modal--danger .modal-title .material-icons { color: var(--gb-danger); }

.gb-modal--preview .modal-title { min-width: 0; }
.gb-modal--preview .modal-title span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.gb-preview-body {
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #0d0f12;
  min-height: 240px;
  max-height: 78vh;
  overflow: auto;
}

.gb-preview-media { display: block; }

.gb-preview-media--image {
  max-width: 100%;
  max-height: 78vh;
  object-fit: contain;
}

.gb-preview-media--video {
  width: 100%;
  max-height: 78vh;
}

.gb-preview-media--pdf {
  width: 100%;
  height: 78vh;
  border: 0;
  background: #fff;
}

/* ---- Bootstrap alerts (used by third-party markup / mail previews) ------- */

.alert {
  border: 0;
  border-left: 4px solid var(--gb-text-muted);
  border-radius: var(--gb-radius);
  box-shadow: var(--gb-elev-1);
  font-size: 13px;
  padding: 11px 14px;
  color: var(--gb-text);
}

.alert-success { border-left-color: var(--gb-income); background: #f1f8f2; color: #1b5e20; }
.alert-danger { border-left-color: var(--gb-expense); background: #fdf2f1; color: #b71c1c; }
.alert-warning { border-left-color: var(--gb-exchange); background: #fff8ef; color: #e65100; }
.alert-info { border-left-color: var(--gb-info); background: #eff9fb; color: #006064; }
.alert-secondary { border-left-color: var(--gb-text-muted); background: #f6f8f9; }

.alert .btn-close { --bs-btn-close-focus-shadow: none; }

/* ---- Pagination ---------------------------------------------------------- */

.gb-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 12px 16px;
}

.gb-pagination__summary {
  font-size: 12px;
  color: var(--gb-text-muted);
  font-variant-numeric: tabular-nums;
}

.gb-pagination nav { margin-left: auto; }

.gb-pagination .pagination { margin: 0; flex-wrap: wrap; gap: 3px; }

/* Laravel's Bootstrap-5 paginator renders a "Showing … results" block we
   already provide ourselves, so hide its duplicate on wide screens. */
.gb-pagination .pagination + p,
.gb-pagination .d-none.d-sm-flex .small { display: none; }

.page-link {
  min-width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 9px;
  border: 1px solid var(--gb-border);
  border-radius: var(--gb-radius-sm);
  background: var(--gb-surface);
  color: var(--gb-text);
  font-size: 12px;
  font-weight: 500;
  box-shadow: none;
  transition: background-color var(--gb-dur) var(--gb-ease), color var(--gb-dur) var(--gb-ease);
}

.page-link:hover {
  background: rgba(var(--gb-primary-2-rgb), .14);
  border-color: rgba(var(--gb-primary-2-rgb), .35);
  color: var(--gb-primary);
}

.page-link:focus {
  box-shadow: 0 0 0 2px rgba(var(--gb-primary-2-rgb), .35);
  color: var(--gb-primary);
}

.page-item.active .page-link {
  background: var(--gb-primary);
  border-color: var(--gb-primary);
  color: #fff;
}

.page-item.disabled .page-link {
  background: var(--gb-surface-alt);
  border-color: var(--gb-border);
  color: #b0bec5;
}

.page-item:first-child .page-link,
.page-item:last-child .page-link { border-radius: var(--gb-radius-sm); }

/* ---- Tooltips & popovers ------------------------------------------------- */

/* Pins the arrow to the same fixed dark colour as .tooltip-inner below —
   the arrow reads --bs-tooltip-bg directly, which is var(--bs-emphasis-color)
   and flips white the moment data-bs-theme="dark" is set. */
.tooltip { --bs-tooltip-bg: rgba(38, 50, 56, .94); }

.tooltip-inner {
  /* Fixed dark bubble in both themes — Bootstrap's own --bs-tooltip-color is
     tied to --bs-body-bg, so without this it goes near-black-on-near-black
     the moment data-bs-theme="dark" flips that variable. */
  background: rgba(38, 50, 56, .94);
  color: #fff;
  border-radius: var(--gb-radius);
  font-size: 11px;
  padding: 5px 9px;
  max-width: 240px;
}

.tooltip.show { opacity: 1; }

.popover {
  border: 0;
  border-radius: var(--gb-radius);
  box-shadow: var(--gb-elev-2);
  font-family: var(--gb-font);
  font-size: 12px;
}

.popover-header {
  background: var(--gb-surface-alt);
  border-bottom: 1px solid var(--gb-border);
  font-size: 12px;
  font-weight: 500;
}

/* ---- Bootstrap form controls that slip through (native date pickers, etc.) */

.form-control:focus,
.form-select:focus {
  border-color: var(--gb-primary-2);
  box-shadow: 0 0 0 .15rem rgba(var(--gb-primary-2-rgb), .2);
}

.form-check-input:checked {
  background-color: var(--gb-primary);
  border-color: var(--gb-primary);
}

.form-check-input:focus { box-shadow: 0 0 0 .15rem rgba(var(--gb-primary-2-rgb), .25); }

/* ---- Nav tabs (report pages) -------------------------------------------- */

.nav-tabs {
  border-bottom: 1px solid var(--gb-border);
  gap: 2px;
}

.nav-tabs .nav-link {
  border: 0;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  padding: 9px 14px;
  color: var(--gb-text-muted);
  font-size: 12px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .5px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.nav-tabs .nav-link .material-icons { font-size: 16px; }

.nav-tabs .nav-link:hover { color: var(--gb-text); border-bottom-color: var(--gb-border); }

.nav-tabs .nav-link.active {
  background: transparent;
  color: var(--gb-primary);
  border-bottom-color: var(--gb-primary);
}

/* ==========================================================================
   24  Charts
   --------------------------------------------------------------------------
   Chart.js is responsive but needs a sized parent; .gb-chart provides it and
   each modifier fixes a height so the card does not jump while loading.
   ========================================================================== */

.gb-chart {
  position: relative;
  width: 100%;
  height: 280px;
}

.gb-chart canvas { display: block; width: 100% !important; }

.gb-chart--xs { height: 140px; }
.gb-chart--sm { height: 200px; }
.gb-chart--md { height: 280px; }
.gb-chart--lg { height: 340px; }
.gb-chart--xl { height: 420px; }

.gb-chart-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  margin-top: 10px;
  font-size: 11px;
  color: var(--gb-text-muted);
}

.gb-chart-legend__item { display: inline-flex; align-items: center; gap: 6px; }

.gb-chart-legend__swatch {
  width: 10px;
  height: 10px;
  border-radius: 2px;
  flex: 0 0 10px;
}

/* ==========================================================================
   25  Misc application blocks
   ========================================================================== */

/* ---- Simple list rows (upcoming debts / instalments / recent actions) ---- */

.gb-list { list-style: none; margin: 0; padding: 0; }

.gb-list__item {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--gb-border);
  min-width: 0;
}

.gb-list__item:last-child { border-bottom: 0; }

.gb-list--hover .gb-list__item { transition: background-color 120ms var(--gb-ease); }
.gb-list--hover .gb-list__item:hover { background: rgba(var(--gb-overlay-rgb), .045); }

.gb-list__icon {
  width: 32px;
  height: 32px;
  flex: 0 0 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--gb-bg);
  color: var(--gb-text-muted);
}

.gb-list__icon .material-icons { font-size: 18px; }

.gb-list__icon--expense { background: rgba(244, 67, 54, .12); color: #c62828; }
.gb-list__icon--income { background: rgba(76, 175, 80, .14); color: #2e7d32; }
.gb-list__icon--exchange { background: rgba(255, 152, 0, .16); color: #e65100; }

.gb-list__body { flex: 1 1 auto; min-width: 0; }

.gb-list__title {
  display: block;
  font-size: 13px;
  color: var(--gb-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.gb-list__meta {
  display: block;
  font-size: 11px;
  color: var(--gb-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.gb-list__value { flex: 0 0 auto; text-align: right; }

/* ---- Currency rate strip ------------------------------------------------- */

.gb-rate-strip {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding: 12px 16px;
  -webkit-overflow-scrolling: touch;
}

.gb-rate {
  flex: 0 0 auto;
  min-width: 118px;
  padding: 9px 12px;
  border: 1px solid var(--gb-border);
  border-radius: var(--gb-radius);
  background: var(--gb-surface);
}

.gb-rate__code {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 500;
  color: var(--gb-text);
}

.gb-rate__value {
  display: block;
  margin-top: 2px;
  font-size: 15px;
  font-variant-numeric: tabular-nums;
  color: var(--gb-text);
}

.gb-rate__age { display: block; font-size: 10px; color: var(--gb-text-muted); }

.gb-rate__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--gb-income);
  flex: 0 0 7px;
}

.gb-rate.is-stale { border-color: #ffe0b2; background: #fffaf3; }
.gb-rate.is-stale .gb-rate__dot { background: var(--gb-exchange); }

/* ---- Section heading inside a card body --------------------------------- */

.gb-section-title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 12px;
  font-size: 12px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .8px;
  color: var(--gb-text-muted);
}

.gb-section-title::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background: var(--gb-border);
}

/* ---- Guest / auth layout ------------------------------------------------- */

.gb-guest {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 32px 16px;
  background-color: #1f2429;
  background-image:
    radial-gradient(90% 60% at 50% 0%, rgba(var(--gb-primary-2-rgb), .3) 0%, rgba(var(--gb-primary-2-rgb), 0) 62%),
    linear-gradient(160deg, #2b323a 0%, #1f2429 48%, #14181c 100%);
}

.gb-guest__brand {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 22px;
  color: #fff;
}

.gb-guest__brand:hover, .gb-guest__brand:focus { color: #fff; }

.gb-guest__brand img { width: 32px; height: 32px; display: block; object-fit: contain; }

.gb-guest__wordmark {
  font-size: 22px;
  font-weight: 500;
  letter-spacing: 3px;
  text-transform: uppercase;
}

.gb-guest__card {
  width: 100%;
  max-width: 400px;
  background: var(--gb-surface);
  border-radius: var(--gb-radius);
  box-shadow: var(--gb-elev-8);
  overflow: hidden;
}

.gb-guest__head {
  padding: 18px 24px 0;
}

.gb-guest__title { margin: 0; font-size: 18px; font-weight: 500; }

.gb-guest__subtitle {
  margin: 4px 0 0;
  font-size: 12px;
  color: var(--gb-text-muted);
}

.gb-guest__body { padding: 14px 24px 22px; }

.gb-guest__footer {
  padding: 12px 24px;
  border-top: 1px solid var(--gb-border);
  background: var(--gb-surface-alt);
  font-size: 12px;
  color: var(--gb-text-muted);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
}

/* First-run "load the sample dataset?" offer. */
.gb-onboarding__list {
  margin: 12px 0;
  padding-left: 20px;
  color: var(--gb-text);
  line-height: 1.9;
}

.gb-onboarding__note {
  margin: 0 0 4px;
  font-size: 12px;
  color: var(--gb-text-muted);
}

.gb-onboarding__actions {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--gb-border);
}

.gb-onboarding__actions .gb-check { margin-bottom: 12px; }

/* Explanatory paragraph inside a guest card — the "check your inbox" copy and
   the note under the sign-up form. */
.gb-guest__note {
  margin: 0 0 14px;
  font-size: 12px;
  line-height: 1.6;
  color: var(--gb-text-muted);
}

.gb-guest__note:last-child { margin-bottom: 0; }

/* A form whose only control should read as the footer's link, not as a button
   — the "sign out" escape hatch on the verify-your-e-mail page. */
.gb-guest__linkform { display: inline; margin: 0; }

.gb-guest__linkform button {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: var(--gb-primary);
  cursor: pointer;
  text-decoration: underline;
}

.gb-guest__linkform button:hover { color: var(--gb-primary-2); }

.gb-guest__meta {
  margin-top: 18px;
  font-size: 11px;
  color: rgba(255, 255, 255, .5);
  text-align: center;
}

.gb-guest__meta a { color: rgba(255, 255, 255, .78); }
.gb-guest__meta a:hover { color: #fff; }

/* ==========================================================================
   26  Utilities — a deliberately small set; Bootstrap covers the rest.
   ========================================================================== */

.gb-muted { color: var(--gb-text-muted) !important; }
.gb-text { color: var(--gb-text) !important; }
.gb-text-primary { color: var(--gb-primary) !important; }
.gb-text-expense { color: var(--gb-expense) !important; }
.gb-text-income { color: var(--gb-income) !important; }
.gb-text-exchange { color: var(--gb-exchange) !important; }
.gb-text-info { color: #0097a7 !important; }

.gb-numeric { font-variant-numeric: tabular-nums; text-align: right; }
.gb-nowrap { white-space: nowrap; }
.gb-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.gb-break { word-break: break-word; overflow-wrap: anywhere; }

.gb-mb-0 { margin-bottom: 0 !important; }
.gb-mb-1 { margin-bottom: 6px !important; }
.gb-mb-2 { margin-bottom: 12px !important; }
.gb-mb-3 { margin-bottom: 20px !important; }
.gb-mt-1 { margin-top: 6px !important; }
.gb-mt-2 { margin-top: 12px !important; }
.gb-mt-3 { margin-top: 20px !important; }

.gb-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--gb-gutter);
}

.gb-grid {
  display: grid;
  gap: var(--gb-gutter);
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  margin-bottom: var(--gb-gutter);
}

.gb-grid--wide { grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }
.gb-grid--tight { gap: 12px; }

/* ---- Dashboard header rate ticker ----------------------------------------- */

.gb-rate-ticker {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: var(--gb-gutter);
}

.gb-rate-ticker__item {
  display: flex;
  align-items: baseline;
  gap: 6px;
  padding: 7px 14px;
  background: var(--gb-surface);
  border-radius: var(--gb-radius-pill);
  box-shadow: var(--gb-elev-1);
}

.gb-rate-ticker__code {
  font-size: 12px;
  font-weight: 500;
  color: var(--gb-text-muted);
}

.gb-rate-ticker__value {
  font-size: 14px;
  font-weight: 600;
  color: var(--gb-text);
}
.gb-grid > .gb-card,
.gb-grid > .gb-stat-card,
.gb-grid > .gb-account-card { margin-bottom: 0; }

.gb-stack { display: grid; gap: 10px; }
.gb-inline { display: inline-flex; align-items: center; gap: 6px; }
.gb-spread { display: flex; align-items: center; justify-content: space-between; gap: 12px; }

/* ---- Aging report bucket boxes (item 17) ---------------------------------- */

a.gb-stat-card.is-selected {
  outline: 3px solid var(--gb-text);
  outline-offset: -3px;
}

.gb-divider { height: 1px; background: var(--gb-border); margin: 14px 0; }

.gb-scroll-y { overflow-y: auto; max-height: 320px; }

.gb-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--gb-text-muted);
  flex: 0 0 8px;
}

.gb-dot--income { background: var(--gb-income); }
.gb-dot--expense { background: var(--gb-expense); }
.gb-dot--exchange { background: var(--gb-exchange); }

/* A colour swatch used by category / account colour pickers. */
.gb-swatch {
  display: inline-block;
  width: 14px;
  height: 14px;
  border-radius: 3px;
  border: 1px solid rgba(0, 0, 0, .12);
  vertical-align: middle;
  flex: 0 0 14px;
}

/* ==========================================================================
   27  Responsive & print
   ========================================================================== */

@media (max-width: 767.98px) {
  :root { --gb-gutter: 14px; }

  .gb-topbar { padding: 0 12px; gap: 8px; }
  .gb-topbar__title { font-size: 15px; }
  .gb-usermenu__name { display: none; }

  .gb-page-banner { padding: 12px 14px; }
  .gb-page-banner__title { font-size: 16px; }
  .gb-page-banner__actions { margin-left: 0; width: 100%; }

  .gb-account-card__balance { font-size: 19px; }
  .gb-card__header { padding: 12px 14px; }
  .gb-card__body { padding: 14px; }
  .gb-table th, .gb-table td { padding: 9px 10px; }
  .gb-chart, .gb-chart--md { height: 230px; }
  .gb-chart--lg, .gb-chart--xl { height: 280px; }
}

@media (max-width: 400px) {
  .gb-btn { padding: 0 12px; }
  .gb-stat-card__watermark { display: none; }
}

/* --------------------------------------------------------------- Secondary text */

/* A muted second line inside a table cell — the debt description under its title. */
.gb-cell__note {
  display: block;
  margin-top: 2px;
  font-size: 12px;
  line-height: 1.4;
  color: var(--gb-text-muted);
}

/* Free prose on a detail page: the debt description under its figures. */
.gb-note {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--gb-border);
}

.gb-note__label {
  display: block;
  margin-bottom: 4px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--gb-text-muted);
}

.gb-note__body {
  margin: 0;
  font-size: 13px;
  line-height: 1.55;
  color: var(--gb-text);
  white-space: pre-line;
}

/* ---------------------------------------------------------------- Account groups */

/* Heading that separates one account group from the next on the accounts page. */
.gb-section-heading {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 10px;
  font-size: 13px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--gb-text-muted);
}

.gb-section-heading:not(:first-child) { margin-top: var(--gb-gutter); }


/*
 * A group carries a user-chosen colour that no variant class can know about,
 * so the chip is tinted through a custom property set inline. Two classes plus
 * the attribute out-specify `.gb-chip--solid.gb-chip--<variant>`, which would
 * otherwise repaint it with the variant's background.
 */
.gb-chip.gb-chip--solid[style*="--gb-chip-color"] {
  background: var(--gb-chip-color);
  color: #fff;
}

@media print {
  .gb-sidebar,
  .gb-topbar,
  .gb-scrim,
  .gb-calc,
  .gb-bottom-nav,
  .gb-search,
  .gb-rates,
  .gb-fab,
  .gb-toolbar__actions,
  .gb-pagination,
  .gb-flash__close,
  .gb-page-banner__actions,
  .no-print { display: none !important; }

  html, body { background: #fff !important; }

  .gb-main { margin-left: 0; }
  .gb-content { padding: 0; padding-bottom: 0; background: #fff; }

  .gb-card,
  .gb-account-card,
  .gb-stat-card {
    box-shadow: none;
    border: 1px solid #cfd8dc;
    break-inside: avoid;
  }

  .gb-stat-card,
  .gb-page-banner { color: #000; background: #fff !important; }
  .gb-stat-card .gb-stat-row__label,
  .gb-stat-card__title,
  .gb-page-banner__title,
  .gb-page-banner__subtitle { color: #000; }
  .gb-stat-row--income .gb-stat-row__value { color: #1b5e20; }
  .gb-stat-row--expense .gb-stat-row__value { color: #b71c1c; }

  .gb-table-wrap { overflow: visible; }
  .gb-table--sticky thead th { position: static; }

  /* Keep a data row whole across a page break, and repeat the header
     row on every printed page so a long ledger stays readable. */
  .gb-table tr { page-break-inside: avoid; break-inside: avoid; }
  .gb-table thead { display: table-header-group; }

  a[href]::after { content: ""; }
}

/* ==========================================================================
   Fancy selects — Tom Select reskinned to match the Material underline field
   ==========================================================================
   Every .gb-field__select is progressively enhanced into a searchable Tom
   Select control by GB.initSelects() (public/assets/js/app.js). The plain
   <select> stays the real form field underneath; only its visual chrome is
   replaced. .gb-field--tomselect / .gb-field--float are added by that same
   JS the moment a field is enhanced. */

.gb-field--tomselect .ts-wrapper {
  width: 100%;
}

/* GB.initSelects() hides the original <select> by setting its inline
   `style.display = "none"` once `new TomSelect(...)` finishes constructing
   (public/assets/js/app.js). If that constructor throws partway through —
   after the .ts-wrapper replacement markup is already inserted but before
   the original element is hidden — the failure is swallowed silently and
   both the native select's own selected-option text and Tom Select's
   rendered value are left painted on top of each other in the same
   .gb-field__control box. Enforcing the hide here in CSS, rather than
   relying solely on the JS library's own inline style, guarantees the
   native select can never show through, exactly like the existing
   :not(.ts-wrapper) guards above fix the same double-paint failure mode
   for the border/padding and caret. */
.gb-field--tomselect select.gb-field__select {
  display: none !important;
}

/*
 * tom-select.css itself sets `.ts-control, .ts-wrapper.single.input-active
 * .ts-control { background: #fff; }` — the second selector (4 classes) beats
 * our own `.gb-field--tomselect .ts-control` (2 classes) the moment a field
 * is focused and becomes typeable, so the control flashes back to a white
 * box mid-interaction. Unscoped and !important so it wins over every state
 * class tom-select toggles (focus / input-active / dropdown-active / …),
 * for every Tom Select field, not just the one this was first noticed on.
 */
.ts-control {
  background: transparent !important;
}

.gb-field--tomselect .ts-control {
  position: relative;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px;
  width: 100%;
  min-height: auto;
  margin: 0;
  padding: 14px 22px 8px 0;
  border: 0;
  border-bottom: 1px solid var(--gb-border);
  border-radius: 0;
  box-shadow: none;
  color: var(--gb-text);
  font-family: inherit;
  font-size: 13px;
  line-height: 20px;
  cursor: pointer;
  transition: border-color var(--gb-dur) var(--gb-ease);
}

.gb-field--tomselect .ts-wrapper.focus .ts-control {
  border-bottom-color: var(--gb-primary);
  box-shadow: none;
}

.gb-field--error.gb-field--tomselect .ts-control { border-bottom-color: var(--gb-expense); }

.gb-field--tomselect .ts-wrapper.disabled .ts-control {
  background: transparent;
  color: var(--gb-text-muted);
  cursor: not-allowed;
}

.gb-field--tomselect .ts-control > input {
  background: transparent;
  border: 0;
  box-shadow: none;
  color: var(--gb-text);
  font-family: inherit;
  font-size: 13px;
}

.gb-field--tomselect .ts-control > input::placeholder {
  color: var(--gb-text-muted);
  opacity: 1;
}

/* A little caret on the right where the native <select> arrow used to be. */
.gb-field--tomselect .ts-wrapper.single .ts-control::after {
  content: '';
  position: absolute;
  right: 2px;
  top: 50%;
  width: 8px;
  height: 8px;
  margin-top: -5px;
  border-right: 2px solid var(--gb-text-muted);
  border-bottom: 2px solid var(--gb-text-muted);
  transform: rotate(45deg);
  pointer-events: none;
}

/* Selected "chip" in a multiple select. */
.gb-field--tomselect .ts-wrapper.multi .ts-control > div {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin: 2px 4px 2px 0;
  padding: 2px 8px;
  border-radius: var(--gb-radius-pill, 999px);
  background: var(--gb-primary);
  color: #fff;
  font-size: 12px;
  line-height: 18px;
}

.gb-field--tomselect .ts-wrapper.multi .ts-control > div.active {
  background: var(--gb-primary-hover);
}

.gb-field--tomselect .ts-control .remove {
  margin-left: 2px;
  border-left: 0;
  color: rgba(255, 255, 255, .8);
}

.gb-field--tomselect .ts-control .remove:hover { color: #fff; background: transparent; }

/* Dropdown menu. */
.ts-dropdown {
  margin-top: 4px;
  border: 0;
  border-radius: var(--gb-radius, 4px);
  background: var(--gb-surface);
  box-shadow: var(--gb-elev-3, 0 4px 16px rgba(0, 0, 0, .18));
  font-family: inherit;
  font-size: 13px;
  z-index: 1060;
}

.ts-dropdown .ts-dropdown-content { padding: 4px 0; }

.ts-dropdown [data-selectable].option,
.ts-dropdown .no-results,
.ts-dropdown .create {
  padding: 8px 14px;
  color: var(--gb-text);
}

.ts-dropdown .no-results,
.ts-dropdown .create { color: var(--gb-text-muted); }

.ts-dropdown .option.active {
  background: rgba(var(--gb-primary-rgb), .1);
  color: var(--gb-primary);
}

.ts-dropdown .optgroup-header {
  padding: 6px 14px 4px;
  color: var(--gb-text-muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .4px;
}

@media (max-width: 991.98px) {
  .gb-field--tomselect .ts-control { padding-right: 20px; }
}

/* ============================================================================
   Permission matrix (organisation user forms)
   ==========================================================================*/

/* The BCRUD grid, the one-click templates and the account whitelist. Rendered
   inside a card, so it carries no panel chrome of its own. */
.gb-permissions__intro { margin-bottom: 14px; }

.gb-permissions__templates {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 8px 0 4px;
}

.gb-permissions__templates-label {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .6px;
  text-transform: uppercase;
  color: var(--gb-text-muted);
  margin-right: 4px;
}

/* Module name plus its sidebar glyph, so a row is recognisable as the menu
   entry it governs. */
.gb-permissions__module {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  white-space: nowrap;
}

.gb-permissions__module .material-icons {
  font-size: 18px;
  color: var(--gb-text-muted);
}

/* A verb this module does not offer. A dash, never an unticked box: an empty
   checkbox would imply the right could be granted. */
.gb-permissions__na {
  color: var(--gb-border);
  user-select: none;
}

.gb-permissions__divider td {
  background: var(--gb-surface-alt, #fafafa);
  padding-top: 14px !important;
  padding-bottom: 8px !important;
}

.gb-permissions__group {
  display: block;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .8px;
  text-transform: uppercase;
  color: var(--gb-text-muted);
}

/* 18px hit target, centred in its cell — 80 of these sit in one table, so they
   have to be scannable in a column. */
.gb-matrix__box {
  width: 17px;
  height: 17px;
  margin: 0;
  accent-color: var(--gb-primary);
  cursor: pointer;
  vertical-align: middle;
}

.gb-permissions__accounts {
  margin: 22px 0 0;
  padding: 16px 0 0;
  border: 0;
  border-top: 1px solid var(--gb-border);
}

.gb-radio {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 8px 0;
  font-size: 13px;
  cursor: pointer;
}

.gb-radio input {
  width: 16px;
  height: 16px;
  margin: 0;
  accent-color: var(--gb-primary);
  cursor: pointer;
}

.gb-permissions__account-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 6px 18px;
  margin: 10px 0 0 25px;
  transition: opacity .15s ease;
}

/* Dimmed while "every account" is selected: the ids are ignored server-side in
   that state, and a live-looking list that means nothing is a lie. */
.gb-permissions__account-list.is-disabled {
  opacity: .4;
  pointer-events: none;
}

.gb-check-inline {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 13px;
  cursor: pointer;
}

.gb-check-inline > span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

/* A heading between two blocks of one long form — "Permissions" above the BCRUD
   matrix. Lighter than a card of its own, which would break the single-submit
   shape of the form. */
.gb-form-section {
  margin: 26px 0 12px;
  padding-top: 18px;
  border-top: 1px solid var(--gb-border);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: .4px;
  text-transform: uppercase;
  color: var(--gb-text-muted);
}

/* A line of prose with an action pinned to its right — the "invitation pending,
   resend it" notice. */
.gb-inline-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  font-size: 13px;
}

/* The read-only summary on the invitation page: who this account is for, and
   who invited them. Shown rather than editable — the details were decided by the
   administrator who sent the link. */
.gb-invitation {
  display: grid;
  gap: 10px;
  margin: 0 0 22px;
  padding: 14px 16px;
  background: var(--gb-surface-alt, #fafafa);
  border-radius: var(--gb-radius, 6px);
}

.gb-invitation dt {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .6px;
  text-transform: uppercase;
  color: var(--gb-text-muted);
}

.gb-invitation dd {
  margin: 2px 0 0;
  font-size: 14px;
  color: var(--gb-text);
  word-break: break-word;
}

/* ==========================================================================
   28  Topbar utilities — search, rates, calculator, phone bar
   ==========================================================================
   Four small pieces of chrome that share one job: putting the numbers and the
   destinations a bookkeeper reaches for all day inside the frame, instead of
   two clicks into a settings page or a separate application.

   None of them is a page. All four hide when printing (§27).
   ========================================================================== */

/* ------------------------------------------------------------------ Search */

.gb-search {
  position: relative;
  flex: 1 1 220px;
  max-width: 380px;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  height: 34px;
  padding: 0 10px;
  background: var(--gb-surface);
  border: 1px solid var(--gb-border);
  border-radius: var(--gb-radius-pill);
  transition: border-color var(--gb-dur) var(--gb-ease), box-shadow var(--gb-dur) var(--gb-ease);
}

.gb-search:focus-within {
  border-color: var(--gb-primary);
  box-shadow: 0 0 0 3px rgba(var(--gb-primary-rgb), .12);
}

.gb-search__icon {
  flex: 0 0 auto;
  font-size: 18px;
  color: var(--gb-text-muted);
}

.gb-search__input {
  flex: 1 1 auto;
  min-width: 0;
  height: 100%;
  border: 0;
  background: transparent;
  color: var(--gb-text);
  font-family: inherit;
  font-size: 13px;
  outline: none;
}

.gb-search__input::placeholder { color: var(--gb-text-muted); }

/* Chrome and Safari paint their own clear button on type="search"; ours is Esc. */
.gb-search__input::-webkit-search-decoration,
.gb-search__input::-webkit-search-cancel-button { -webkit-appearance: none; }

/* The "/" affordance, retired the moment the field is in use. */
.gb-search__hint {
  flex: 0 0 auto;
  padding: 1px 5px;
  border: 1px solid var(--gb-border);
  border-radius: var(--gb-radius-sm);
  background: var(--gb-bg);
  color: var(--gb-text-muted);
  font-family: inherit;
  font-size: 11px;
  line-height: 1.4;
}

.gb-search:focus-within .gb-search__hint { display: none; }

.gb-search__panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  z-index: var(--gb-z-topbar);
  max-height: min(70vh, 460px);
  overflow-y: auto;
  padding: 6px 0;
  background: var(--gb-surface);
  border: 1px solid var(--gb-border);
  border-radius: var(--gb-radius-lg);
  box-shadow: var(--gb-elev-4);
}

.gb-search__group + .gb-search__group { border-top: 1px solid var(--gb-border); }

.gb-search__group-label {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  padding: 8px 14px 4px;
  color: var(--gb-text-muted);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .6px;
  text-transform: uppercase;
}

.gb-search__group-label .material-icons { font-size: 15px; }

.gb-search__message {
  margin: 0;
  padding: 14px;
  color: var(--gb-text-muted);
  font-size: 13px;
  text-align: center;
}

.gb-search__all {
  display: block;
  padding: 9px 14px;
  border-top: 1px solid var(--gb-border);
  color: var(--gb-primary);
  font-size: 12px;
  font-weight: 500;
  text-align: center;
  text-decoration: none;
}

.gb-search__all:hover,
.gb-search__all:focus { background: var(--gb-bg); }

/* The phone stand-in: one icon, straight to the results page. */
.gb-search__compact { display: none; }

/* ------------------------------------------------------- Result rows (shared) */

/* Used by both the dropdown and search/index — one look for one kind of row. */
.gb-result-list { margin: 0; padding: 0; list-style: none; }

.gb-result__link {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 14px;
  color: var(--gb-text);
  text-decoration: none;
}

.gb-result__link:hover,
.gb-result__link:focus,
.gb-result__link.is-highlighted {
  background: var(--gb-bg);
  color: var(--gb-text);
}

.gb-result__text { flex: 1 1 auto; min-width: 0; }

.gb-result__title {
  display: block;
  font-size: 13px;
  line-height: 1.35;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.gb-result__subtitle {
  display: block;
  margin-top: 1px;
  color: var(--gb-text-muted);
  font-size: 11.5px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.gb-result__meta {
  flex: 0 0 auto;
  color: var(--gb-text-muted);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* On the full results page the rows are separated; in the dropdown they are not. */
.gb-card .gb-result + .gb-result .gb-result__link { border-top: 1px solid var(--gb-border); }
.gb-card .gb-result__link { padding-left: var(--gb-gutter); padding-right: var(--gb-gutter); }

/* ------------------------------------------------------------------- Rates */

.gb-rates {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
}

.gb-rate {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  background: var(--gb-surface);
  border: 1px solid var(--gb-border);
  border-radius: var(--gb-radius-pill);
  color: var(--gb-text);
  font-size: 12px;
  line-height: 1.5;
  text-decoration: none;
  white-space: nowrap;
}

a.gb-rate:hover,
a.gb-rate:focus {
  border-color: var(--gb-primary);
  color: var(--gb-primary);
}

.gb-rate__symbol { color: var(--gb-text-muted); font-weight: 500; }
.gb-rate__value { font-variant-numeric: tabular-nums; }

/* A rate the engine has not refreshed is shown, but never shown as fresh. */
.gb-rate.is-stale {
  border-style: dashed;
  border-color: var(--gb-warning);
  color: var(--gb-warning);
}

.gb-rate.is-stale .gb-rate__symbol { color: var(--gb-warning); }
.gb-rate__stale { font-size: 13px; }

/* -------------------------------------------------------------- Calculator */

/* A window, not a bar. The point of the shape is that it can be dragged next to
   the column being added up — the docked bar it replaced put the answer at the
   bottom of the screen while the figures were at the top.
   JS owns left/top (clamped to the viewport, remembered per browser); the
   right/bottom here are only the position it first appears in. */
.gb-calc {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: var(--gb-z-calc);
  width: 296px;
  max-width: calc(100vw - 24px);
  background: var(--gb-surface);
  border: 1px solid var(--gb-border);
  border-radius: var(--gb-radius-lg);
  box-shadow: var(--gb-elev-8);
  overflow: hidden;
}

.gb-calc__bar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 5px 5px 11px;
  background: var(--gb-sidebar);
  color: #fff;
  cursor: move;
  user-select: none;
  touch-action: none;
}

.gb-calc__bar.is-dragging { cursor: grabbing; }

.gb-calc__bar-icon { font-size: 17px; color: var(--gb-sidebar-fg-dim); }

.gb-calc__bar-title {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .3px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.gb-calc__bar-btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 0;
  border-radius: var(--gb-radius);
  background: transparent;
  color: var(--gb-sidebar-fg);
  cursor: pointer;
}

.gb-calc__bar-btn:hover,
.gb-calc__bar-btn:focus { background: var(--gb-sidebar-hover); color: #fff; }
.gb-calc__bar-btn .material-icons { font-size: 17px; }
.gb-calc__bar-btn.is-active { background: var(--gb-sidebar-hover); color: #fff; }

/* ------- Tape: what a second calculator window would have been for --------- */

.gb-calc__tape-wrap { border-bottom: 1px solid var(--gb-border); background: var(--gb-bg); }

.gb-calc__tape {
  max-height: 124px;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  list-style: none;
}

.gb-calc__tape-item { display: block; }

.gb-calc__tape-btn {
  display: flex;
  align-items: baseline;
  gap: 10px;
  width: 100%;
  padding: 4px 11px;
  border: 0;
  background: transparent;
  color: var(--gb-text);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}

.gb-calc__tape-btn:hover,
.gb-calc__tape-btn:focus { background: var(--gb-surface); }

.gb-calc__tape-expr {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--gb-text-muted);
  font-size: 11px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.gb-calc__tape-value {
  flex: 0 0 auto;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

.gb-calc__tape-clear {
  display: block;
  width: 100%;
  padding: 3px 11px 5px;
  border: 0;
  background: transparent;
  color: var(--gb-text-muted);
  font-family: inherit;
  font-size: 10.5px;
  text-align: right;
  cursor: pointer;
}

.gb-calc__tape-clear:hover { color: var(--gb-danger); }

/* ---------------------------------------------------------------- Display -- */

.gb-calc__entry { padding: 9px 11px 6px; }

.gb-calc__input {
  width: 100%;
  height: 30px;
  border: 0;
  border-bottom: 1px solid var(--gb-border);
  background: transparent;
  color: var(--gb-text);
  font-family: inherit;
  font-size: 15px;
  text-align: right;
  outline: none;
}

.gb-calc__input:focus { border-bottom-color: var(--gb-primary); }

.gb-calc__result {
  display: block;
  min-height: 26px;
  padding-top: 3px;
  color: var(--gb-primary);
  font-size: 19px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  text-align: right;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.gb-calc__result.is-error { color: var(--gb-text-muted); font-size: 12px; font-weight: 400; }

.gb-calc__actions {
  display: flex;
  gap: 6px;
  padding: 0 11px 10px;
}

.gb-calc__action {
  flex: 1 1 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  height: 29px;
  padding: 0 8px;
  border: 1px solid var(--gb-border);
  border-radius: var(--gb-radius);
  background: var(--gb-surface);
  color: var(--gb-text);
  font-family: inherit;
  font-size: 11.5px;
  cursor: pointer;
}

.gb-calc__action .material-icons { font-size: 15px; }
.gb-calc__action:hover:not(:disabled) { border-color: var(--gb-primary); color: var(--gb-primary); }
.gb-calc__action:disabled { opacity: .45; cursor: default; }

.gb-calc__action--primary:not(:disabled) {
  border-color: var(--gb-primary);
  background: var(--gb-primary);
  color: #fff;
}

.gb-calc__action--primary:not(:disabled):hover { background: var(--gb-primary-2); color: #fff; }

/* ---------------------------------------------------------------- Keypad --- */

.gb-calc__keypad { border-top: 1px solid var(--gb-border); background: var(--gb-bg); }

/* The row the keypad exists for: one tap instead of four keystrokes. */
.gb-calc__shortcuts {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 8px 8px 0;
}

.gb-calc__shortcut {
  padding: 3px 9px;
  border: 1px solid var(--gb-border);
  border-radius: var(--gb-radius-pill);
  background: var(--gb-surface);
  color: var(--gb-text);
  font-family: inherit;
  font-size: 11.5px;
  cursor: pointer;
}

.gb-calc__shortcut:hover { border-color: var(--gb-primary); color: var(--gb-primary); }

.gb-calc__shortcut--vat {
  border-color: rgba(var(--gb-primary-rgb), .35);
  color: var(--gb-primary);
}

.gb-calc__grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 4px;
  padding: 8px;
}

.gb-calc__key {
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--gb-border);
  border-radius: var(--gb-radius);
  background: var(--gb-surface);
  color: var(--gb-text);
  font-family: inherit;
  font-size: 14px;
  cursor: pointer;
}

.gb-calc__key:hover { border-color: var(--gb-primary); color: var(--gb-primary); }
.gb-calc__key:active { background: var(--gb-bg); }
.gb-calc__key .material-icons { font-size: 16px; }
.gb-calc__key--op { background: var(--gb-bg); }
.gb-calc__key--danger { color: var(--gb-danger); }
.gb-calc__key--danger:hover { border-color: var(--gb-danger); color: var(--gb-danger); }

/* -------------------------------------------------------------- Phone bar */

.gb-bottom-nav { display: none; }

.gb-bottom-nav__link {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  min-width: 0;
  padding: 6px 2px;
  border: 0;
  background: none;
  color: var(--gb-text-muted);
  font-family: inherit;
  font-size: 10px;
  text-decoration: none;
}

.gb-bottom-nav__link .material-icons { font-size: 21px; }
.gb-bottom-nav__link.is-active { color: var(--gb-primary); }

.gb-bottom-nav__label {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.gb-bottom-nav__write {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  margin: -16px 4px 0;
  background: var(--gb-primary);
  border-radius: 50%;
  box-shadow: var(--gb-elev-2);
  color: #fff;
}

.gb-bottom-nav__write .material-icons { font-size: 24px; color: #fff; }
.gb-bottom-nav__write:hover,
.gb-bottom-nav__write:focus { background: var(--gb-primary-2); color: #fff; }

/* ------------------------------------------------------------- Breakpoints */

/* The rates are the first thing to go: they are a convenience, and the title
   plus the search field have a better claim on a narrow bar. */
@media (max-width: 1199.98px) {
  .gb-rates { display: none; }
}

/* At the same width the sidebar becomes a drawer, the search field becomes an
   icon, and the phone bar appears. */
@media (max-width: 991.98px) {
  .gb-search { display: none; }
  .gb-search__compact { display: inline-flex; }

  .gb-bottom-nav {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: var(--gb-z-bottom-nav);
    height: 56px;
    display: flex;
    align-items: center;
    justify-content: space-around;
    padding: 0 4px;
    background: var(--gb-surface);
    border-top: 1px solid var(--gb-border);
    box-shadow: 0 -2px 10px rgba(0, 0, 0, .08);
    padding-bottom: env(safe-area-inset-bottom, 0);
  }

  /* Room for the phone bar. The calculator is a sheet on top of the page
     rather than part of the flow, so it adds nothing here. */
  .gb-content { padding-bottom: calc(56px + var(--gb-gutter) + env(safe-area-inset-bottom, 0px)); }

  /* No window to drag on a phone: the calculator is a full-width sheet sitting
     on the phone bar. JS clears its inline left/top below this width, so these
     four edges are the only thing positioning it. */
  .gb-calc {
    left: 0;
    right: 0;
    bottom: 56px;
    top: auto;
    width: auto;
    max-width: none;
    border-radius: var(--gb-radius-lg) var(--gb-radius-lg) 0 0;
    border-left: 0;
    border-right: 0;
    border-bottom: 0;
  }

  .gb-calc__bar { cursor: default; }
  .gb-calc__tape { max-height: 96px; }
}

@media (max-width: 767.98px) {
  .gb-calc__result { font-size: 17px; }
}

/* ==========================================================================
   28  Theme switch (topbar user menu)
   --------------------------------------------------------------------------
   A three-way segmented control — System / Light / Dark — dropped into the
   avatar dropdown (partials/topbar.blade.php). GB.initTheme() in app.js
   toggles .is-active and aria-pressed on click; the switch itself needs no
   dark-mode entry below since every colour here is already a token.
   ========================================================================== */

.gb-theme-switch {
  display: flex;
  gap: 4px;
  padding: 4px 10px 10px;
}

.gb-theme-switch__btn {
  flex: 1 1 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 30px;
  padding: 0;
  border: 1px solid var(--gb-border);
  border-radius: var(--gb-radius);
  background: transparent;
  color: var(--gb-text-muted);
  cursor: pointer;
  transition: background-color var(--gb-dur) var(--gb-ease),
              border-color var(--gb-dur) var(--gb-ease),
              color var(--gb-dur) var(--gb-ease);
}

.gb-theme-switch__btn .material-icons { font-size: 18px; }

.gb-theme-switch__btn:hover {
  background: rgba(var(--gb-overlay-rgb), .06);
  color: var(--gb-text);
}

.gb-theme-switch__btn.is-active {
  background: var(--gb-primary);
  border-color: var(--gb-primary);
  color: #fff;
}

/* ==========================================================================
   29  Dark mode overrides
   --------------------------------------------------------------------------
   Section 01 flips the surface/text/border tokens for data-theme="dark"; most
   of the app follows for free. The rules below are the exceptions: pairs
   where a component hardcodes a *solid* tinted background + solid text
   colour (chips, badges, alerts, flash, hover tints) rather than deriving
   them from tokens, so light mode is untouched here and dark mode gets its
   own hand-picked pair. Brand hues (--gb-primary/--gb-expense/etc.) stay
   identical in both themes — only their light-surface companions change.
   ========================================================================== */

/* ---- Links (§02) — --gb-primary itself stays fixed (buttons/FABs need the
   strong, saturated purple), but as body text on the dark surface it only
   clears ~2.1:1 contrast — well under WCAG AA. Links get their own lighter
   shade instead of touching the shared brand token.

   At (0,2,1) this rule outranks the (0,1,0)/(0,2,0) colours that button-like
   anchors set for themselves, so in dark mode every <a class="gb-btn"> —
   x-btn renders an <a> whenever it gets an href — came out lilac instead of
   white: #ce93d8 on the filled purple is 2.4:1, and on a banner gradient
   worse still. The :not(:where(…)) hands those families back their own
   colour without changing this rule's weight for prose links (:where()
   contributes nothing), so every other anchor keeps the shade it has. */
:root[data-theme="dark"] a:not(:where(.gb-btn, .gb-btn-icon, .gb-fab, .gb-stat-card, .gb-chip)) { color: var(--gb-primary-ink); }
:root[data-theme="dark"] a:not(:where(.gb-btn, .gb-btn-icon, .gb-fab, .gb-stat-card, .gb-chip)):hover { color: var(--gb-primary-ink-hover); }

/* The two button colours that were only legible *because* of the rule above:
   both name --gb-primary as text on the page surface, which is 2.1:1 on the
   dark ground — so a <button> (no href, so no `a` rule to bail it out) has
   always been too faint here. They get the same lighter purple explicitly.

   :where() on the theme keeps these at one class, exactly the weight of the
   light-mode declarations they stand in for, so they slot into the existing
   cascade instead of jumping it: .gb-btn--flat.gb-btn--danger still wins with
   its red, and .gb-page-banner__actions .gb-btn still wins with its white. */
:where(:root[data-theme="dark"]) .gb-btn--flat,
:where(:root[data-theme="dark"]) .gb-btn--flat:hover,
:where(:root[data-theme="dark"]) .gb-btn--flat:focus,
:where(:root[data-theme="dark"]) .gb-btn-icon--primary,
:where(:root[data-theme="dark"]) .gb-btn-icon--primary:hover { color: var(--gb-primary-ink); }

/* ---- Sidebar (§04) — the rail is the same dark surface in both themes, so
   its links keep the rail's own white palette, .is-active included. */
:root[data-theme="dark"] .gb-sidebar a,
:root[data-theme="dark"] .gb-sidebar a:hover,
:root[data-theme="dark"] .gb-sidebar a:focus { color: #fff; }

/* ---- Chips (§11) — neutral + one pair per semantic colour ------------- */
:root[data-theme="dark"] .gb-chip { color: #a7b6bf; }
:root[data-theme="dark"] .gb-chip--expense { background: rgba(244, 67, 54, .18); color: #ff8a80; }
:root[data-theme="dark"] .gb-chip--income { background: rgba(76, 175, 80, .2); color: #81c995; }
:root[data-theme="dark"] .gb-chip--exchange { background: rgba(255, 152, 0, .2); color: #ffb74d; }
:root[data-theme="dark"] .gb-chip--primary { background: rgba(var(--gb-primary-2-rgb), .22); color: var(--gb-primary-ink); }
:root[data-theme="dark"] .gb-chip--info { background: rgba(0, 188, 212, .2); color: #4dd0e1; }
:root[data-theme="dark"] .gb-chip--accent { background: rgba(57, 73, 171, .25); color: #8c9eff; }
:root[data-theme="dark"] .gb-chip--success { background: rgba(67, 160, 71, .2); color: #81c995; }
:root[data-theme="dark"] .gb-chip--warning { background: rgba(251, 140, 0, .2); color: #ffb74d; }
:root[data-theme="dark"] .gb-chip--danger { background: rgba(229, 57, 53, .18); color: #ff8a80; }
:root[data-theme="dark"] .gb-chip--pink { background: rgba(233, 30, 99, .2); color: #f48fb1; }

/* ---- Badges (§12) ------------------------------------------------------- */
:root[data-theme="dark"] .gb-badge--muted { background: #333b42; color: #a7b6bf; }

/* ---- Empty state icon (§15) — dimmer than muted text, same idea as light - */
:root[data-theme="dark"] .gb-empty__icon { color: #4a545c; }

/* ---- List icons (§25) — same pairs as the matching chip ---------------- */
:root[data-theme="dark"] .gb-list__icon--expense { background: rgba(244, 67, 54, .18); color: #ff8a80; }
:root[data-theme="dark"] .gb-list__icon--income { background: rgba(76, 175, 80, .2); color: #81c995; }
:root[data-theme="dark"] .gb-list__icon--exchange { background: rgba(255, 152, 0, .2); color: #ffb74d; }

/* ---- Bootstrap alerts (§23) --------------------------------------------- */
:root[data-theme="dark"] .alert-success { background: #16281a; color: #8bd99b; }
:root[data-theme="dark"] .alert-danger { background: #2c1616; color: #ff9d94; }
:root[data-theme="dark"] .alert-warning { background: #2c210f; color: #ffc069; }
:root[data-theme="dark"] .alert-info { background: #0f2429; color: #6bd9e8; }
:root[data-theme="dark"] .alert-secondary { background: var(--gb-surface-alt); }

/* ---- Flash messages & validation summary (§22) -------------------------- */
:root[data-theme="dark"] .gb-flash--success { background: #16281a; }
:root[data-theme="dark"] .gb-flash--error { background: #2c1616; }
:root[data-theme="dark"] .gb-flash--warning { background: #2c210f; }
:root[data-theme="dark"] .gb-flash--info { background: #0f2429; }
:root[data-theme="dark"] .gb-errors { background: #2c1616; }

/* ---- Dropdown / pagination / autocomplete / dropzone hover tints ------- */
:root[data-theme="dark"] .dropdown-item:hover,
:root[data-theme="dark"] .dropdown-item:focus { background: rgba(var(--gb-primary-2-rgb), .2); }
:root[data-theme="dark"] .dropdown-item:active { background: rgba(var(--gb-primary-2-rgb), .3); }
:root[data-theme="dark"] .dropdown-item.is-danger:hover,
:root[data-theme="dark"] .dropdown-item.is-danger:focus { background: rgba(229, 57, 53, .18); }

:root[data-theme="dark"] .page-link:hover { background: rgba(var(--gb-primary-2-rgb), .2); border-color: rgba(var(--gb-primary-2-rgb), .4); }
:root[data-theme="dark"] .page-item.active .page-link { color: #fff; }

:root[data-theme="dark"] .gb-autocomplete__option:hover,
:root[data-theme="dark"] .gb-autocomplete__option.is-active { background: rgba(var(--gb-primary-2-rgb), .2); }

:root[data-theme="dark"] .gb-dropzone__area:hover { background: rgba(var(--gb-primary-2-rgb), .1); }
:root[data-theme="dark"] .gb-dropzone--active .gb-dropzone__area,
:root[data-theme="dark"] .gb-dropzone__area.gb-dropzone--active { background: rgba(var(--gb-primary-2-rgb), .2); }

/* The older §28-topbar .gb-rate (currency-strip variant): stale amber wash. */
:root[data-theme="dark"] .gb-rate.is-stale { border-color: rgba(255, 152, 0, .4); background: rgba(255, 152, 0, .12); }
