/* ============================================================================
 * StyleSheet.css — CryptoPaymentGateway admin panel
 *
 * Purpose
 * ───────
 * A thin, focused custom layer that sits on top of Basecoat UI v0.3.11.
 * Basecoat already ships a complete design system (cards, buttons, inputs,
 * badges, tables, dialogs) via its CDN build.  This file only adds what
 * Basecoat doesn't cover: the application shell, dark-theme token overrides,
 * and a set of utility/component classes used by the HTML templates.
 *
 * Section map
 * ───────────
 *  .1   Web font import        — Inter + JetBrains Mono via Google Fonts.
 *  .2   Global typography      — Font-family, font-feature-settings, smoothing.
 *  .3   Dark-theme tokens      — HSL variable overrides on html.dark.
 *  .4   App shell layout       — Fixed sidebar + sticky topbar + centred column.
 *  .5   Sidebar internals      — Brand strip, nav links, user footer (flat only).
 *  .6   Page-level helpers     — Page section, header, form grids, split layout,
 *                                stat grid, network tabs.
 *  .7   Component styles       — Action pills, JSON diff viewer, pagination bar,
 *                                empty state, sort links.
 *  .8   Utility classes        — Flexbox, text, spacing, overflow helpers that
 *                                replace every inline style in the templates.
 *  .9   Sign-out button        — Destructive-tone header button.
 *  .10  Responsive breakpoints — Mobile sidebar drawer (< 768 px) and grid collapses.
 *  .11  Component fine-tuning  — Stat cards, kbd keys, component font overrides.
 *  .12  Select / option fix    — Dark-theme dropdown contrast.
 *  .13  Deployment page        — Progress bar, log console, stage timeline.
 *  .14  Wallet management      — Wallet Lists, Workers, status badges, dialogs.
 *  .15  Reports & money flow   — Report filters, KPI tiles, SVG bar chart and
 *                                the shared withdrawal money-flow diagram.
 *  .16  Vault float & top-up   — Float card on Withdrawals and its top-up dialog.
 * ============================================================================ */


/* ============================================================================
   .1  Type faces
       San Francisco is used wherever it exists (Apple platforms expose it via
       -apple-system / BlinkMacSystemFont). Inter is the fallback everywhere
       else: it is metrically close to SF Text, so the layout does not shift
       between an operator on a Mac and one on Linux.
   ============================================================================ */



/* ============================================================================
   .2  Design tokens — appearance-independent
       Everything the interface is built from lives here as a token: type,
       radii, elevation, motion, layout. Components never hard-code a value,
       so a theme is only ever a different set of numbers, never new rules.
   ============================================================================ */

:root {
  /* ── Type ─────────────────────────────────────────────────────────────── */
  --font-sans: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'SF Pro Display',
               'Inter', system-ui, 'Segoe UI', 'Roboto', 'Helvetica Neue',
               Arial, sans-serif;
  --font-mono: ui-monospace, 'SF Mono', 'SFMono-Regular', 'JetBrains Mono',
               'Menlo', 'Cascadia Mono', monospace;

  /* ── Shape ────────────────────────────────────────────────────────────── */
  /* 12px corners on surfaces, matching the curvature Apple uses for cards
     and sheets. Basecoat derives its smaller control radii from this. */
  --radius:        0.75rem;
  --radius-sm:     0.5rem;
  --radius-pill:   999px;

  /* ── Motion ───────────────────────────────────────────────────────────── */
  /* The decelerating curve Apple uses for sheets and transitions: quick to
     start, long settle, never a mechanical linear slide. */
  --ease-standard: cubic-bezier(0.32, 0.72, 0, 1);
  --ease-exit:     cubic-bezier(0.4, 0, 1, 1);
  --duration-fast: 0.15s;
  --duration-base: 0.25s;
  --duration-slow: 0.4s;

  /* ── Layout ───────────────────────────────────────────────────────────── */
  --layout-sidebar-width: 16rem;
  --layout-navbar-height: 3.75rem;
  --layout-content-max:   95rem;

  /* ── Materials ────────────────────────────────────────────────────────── */
  /* Translucent chrome. Apple's vibrancy is a blur plus a saturation boost so
     colour bleeds through the material rather than turning to grey mud. */
  --material-blur:       saturate(180%) blur(20px);
  --material-opacity:    0.72;

  /* ── Islands ──────────────────────────────────────────────────────────── */
  /* The chrome (sidebar, topbar) floats as rounded islands on the recessed
     canvas instead of being glued to the viewport edges — the layout language
     JetBrains' Islands UI and the newer VS Code shell converged on. The gap
     is the strip of canvas kept visible around every island; the radius is
     deliberately larger than --radius so the shell reads as a bigger surface
     than the cards sitting inside it. */
  --island-gap:    0.75rem;
  --island-radius: 1rem;
}

html,
body {
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* SF and Inter both read better very slightly tightened at UI sizes. */
  letter-spacing: -0.01em;
}

code,
pre,
kbd,
samp,
.font-mono {
  font-family: var(--font-mono);
  font-size: 0.675rem;
  font-feature-settings: 'liga' 0;
}

/* Respect a reduced-motion preference across every transition we introduce. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --duration-fast: 0.01s;
    --duration-base: 0.01s;
    --duration-slow: 0.01s;
  }
}


/* ============================================================================
   .3  Appearance: Light
       Apple's light system palette — a grouped grey canvas with white cards
       floating on it, rather than white-on-white. Applied by default and
       whenever html[data-theme="light"] is set.
   ============================================================================ */

:root,
html[data-theme='light'] {
  --background:               240 20% 97%;   /* systemGroupedBackground   */
  --foreground:               240 6% 10%;    /* label                    */
  --card:                     0 0% 100%;
  --card-foreground:          240 6% 10%;
  --popover:                  0 0% 100%;
  --popover-foreground:       240 6% 10%;
  --primary:                  211 100% 50%;  /* systemBlue               */
  --primary-foreground:       0 0% 100%;
  --secondary:                240 12% 94%;
  --secondary-foreground:     240 6% 10%;
  --muted:                    240 12% 94%;
  --muted-foreground:         240 4% 46%;    /* secondaryLabel           */
  --accent:                   240 12% 94%;
  --accent-foreground:        240 6% 10%;
  --border:                   240 10% 89%;   /* separator                */
  --input:                    240 10% 89%;
  --destructive:              4 100% 59%;    /* systemRed                */
  --destructive-foreground:   0 0% 100%;
  --success:                  135 54% 49%;   /* systemGreen              */
  --success-foreground:       0 0% 100%;
  --warning:                  35 100% 50%;   /* systemOrange             */
  --warning-foreground:       0 0% 100%;
  --info:                     211 100% 50%;
  --info-foreground:          0 0% 100%;
  --ring:                     211 100% 50%;

  /* Ink for text sitting on a tint of the same hue (badges, alerts). */
  --success-text:             135 62% 28%;
  --warning-text:             28 92% 32%;
  --destructive-text:         4 78% 44%;
  --info-text:                211 100% 40%;

  --shadow-color:             240 20% 40%;
  --shadow-strength:          0.10;
  --material-opacity:         0.72;
  color-scheme: light;
}


/* ============================================================================
   .4  Appearance: Dark
       Apple's dark system palette. Surfaces lift by getting lighter, not by
       gaining a heavier border, and the accents shift to their brighter dark
       variants so they keep contrast against a near-black canvas.

       `html.dark` is kept as an alias so any markup or third-party rule that
       still keys off the class continues to resolve to the same tokens.
   ============================================================================ */

html[data-theme='dark'],
html.dark {
  --background:               240 6% 6%;
  --foreground:               0 0% 96%;
  --card:                     240 5% 11%;    /* secondarySystemBackground */
  --card-foreground:          0 0% 96%;
  --popover:                  240 5% 13%;
  --popover-foreground:       0 0% 96%;
  --primary:                  211 100% 52%;  /* systemBlue (dark)         */
  --primary-foreground:       0 0% 100%;
  --secondary:                240 4% 17%;
  --secondary-foreground:     0 0% 96%;
  --muted:                    240 4% 15%;
  --muted-foreground:         240 5% 65%;
  --accent:                   240 4% 17%;
  --accent-foreground:        0 0% 96%;
  --border:                   240 4% 20%;
  --input:                    240 4% 20%;
  --destructive:              4 100% 61%;    /* systemRed (dark)          */
  --destructive-foreground:   0 0% 100%;
  --success:                  135 64% 50%;   /* systemGreen (dark)        */
  --success-foreground:       0 0% 100%;
  --warning:                  37 100% 52%;   /* systemOrange (dark)       */
  --warning-foreground:       240 6% 10%;
  --info:                     211 100% 62%;
  --info-foreground:          0 0% 100%;
  --ring:                     211 100% 52%;

  --success-text:             135 64% 62%;
  --warning-text:             37 100% 64%;
  --destructive-text:         4 100% 72%;
  --info-text:                211 100% 72%;

  --shadow-color:             240 30% 2%;
  --shadow-strength:          0.45;
  --material-opacity:         0.65;
  color-scheme: dark;
}


/* ============================================================================
   .5  Appearance: System
       Follows the operating system. The light values are already in force
       from .3, so only the dark case needs restating.
   ============================================================================ */

@media (prefers-color-scheme: dark) {
  html[data-theme='system'] {
    --background:               240 6% 6%;
    --foreground:               0 0% 96%;
    --card:                     240 5% 11%;
    --card-foreground:          0 0% 96%;
    --popover:                  240 5% 13%;
    --popover-foreground:       0 0% 96%;
    --primary:                  211 100% 52%;
    --primary-foreground:       0 0% 100%;
    --secondary:                240 4% 17%;
    --secondary-foreground:     0 0% 96%;
    --muted:                    240 4% 15%;
    --muted-foreground:         240 5% 65%;
    --accent:                   240 4% 17%;
    --accent-foreground:        0 0% 96%;
    --border:                   240 4% 20%;
    --input:                    240 4% 20%;
    --destructive:              4 100% 61%;
    --destructive-foreground:   0 0% 100%;
    --success:                  135 64% 50%;
    --success-foreground:       0 0% 100%;
    --warning:                  37 100% 52%;
    --warning-foreground:       240 6% 10%;
    --info:                     211 100% 62%;
    --info-foreground:          0 0% 100%;
    --ring:                     211 100% 52%;

    --success-text:             135 64% 62%;
  --warning-text:             37 100% 64%;
  --destructive-text:         4 100% 72%;
  --info-text:                211 100% 72%;

  --shadow-color:             240 30% 2%;
    --shadow-strength:          0.45;
    --material-opacity:         0.65;
    color-scheme: dark;
  }
}


/* ============================================================================
   .6  Accent
       An accent re-points --primary (and the focus ring that follows it) at a
       different Apple system colour. It is deliberately orthogonal to light /
       dark: each accent declares both variants, so switching appearance keeps
       the chosen colour and only swaps it for its correct-contrast sibling.

       Blue is the default and needs no attribute.
   ============================================================================ */

html[data-accent='purple'] {
  --primary: 281 68% 60%;  /* systemPurple */
  --ring:    281 68% 60%;
  --info:    281 68% 60%;
}
html[data-accent='purple'][data-theme='dark'],
html[data-accent='purple'].dark {
  --primary: 280 85% 65%;
  --ring:    280 85% 65%;
  --info:    280 85% 65%;
}

html[data-accent='indigo'] {
  --primary: 240 60% 55%;  /* systemIndigo */
  --ring:    240 60% 55%;
  --info:    240 60% 55%;
}
html[data-accent='indigo'][data-theme='dark'],
html[data-accent='indigo'].dark {
  --primary: 241 74% 66%;
  --ring:    241 74% 66%;
  --info:    241 74% 66%;
}

html[data-accent='teal'] {
  --primary: 189 68% 45%;  /* systemTeal */
  --ring:    189 68% 45%;
  --info:    189 68% 45%;
}
html[data-accent='teal'][data-theme='dark'],
html[data-accent='teal'].dark {
  --primary: 189 85% 55%;
  --ring:    189 85% 55%;
  --info:    189 85% 55%;
}

html[data-accent='green'] {
  --primary: 135 54% 42%;  /* systemGreen, darkened for button contrast */
  --ring:    135 54% 42%;
  --info:    135 54% 42%;
}
html[data-accent='green'][data-theme='dark'],
html[data-accent='green'].dark {
  --primary: 135 64% 45%;
  --ring:    135 64% 45%;
  --info:    135 64% 45%;
}

html[data-accent='orange'] {
  --primary: 28 100% 47%;  /* systemOrange, darkened for button contrast */
  --ring:    28 100% 47%;
  --info:    28 100% 47%;
}
html[data-accent='orange'][data-theme='dark'],
html[data-accent='orange'].dark {
  --primary: 32 100% 50%;
  --ring:    32 100% 50%;
  --info:    32 100% 50%;
}

html[data-accent='graphite'] {
  --primary: 240 4% 26%;   /* the monochrome option */
  --ring:    240 4% 26%;
  --info:    240 4% 40%;
}
html[data-accent='graphite'][data-theme='dark'],
html[data-accent='graphite'].dark {
  --primary: 0 0% 96%;
  --primary-foreground: 240 6% 10%;
  --ring:    0 0% 70%;
  --info:    0 0% 75%;
}

/* Accents that re-point --primary at a light colour need dark ink on top. */
html[data-accent='graphite'][data-theme='system'] {
  --primary-foreground: 0 0% 100%;
}
@media (prefers-color-scheme: dark) {
  html[data-accent='graphite'][data-theme='system'] {
    --primary: 0 0% 96%;
    --primary-foreground: 240 6% 10%;
    --ring:    0 0% 70%;
    --info:    0 0% 75%;
  }
  html[data-accent='purple'][data-theme='system'] {
    --primary: 280 85% 65%; --ring: 280 85% 65%; --info: 280 85% 65%;
  }
  html[data-accent='indigo'][data-theme='system'] {
    --primary: 241 74% 66%; --ring: 241 74% 66%; --info: 241 74% 66%;
  }
  html[data-accent='teal'][data-theme='system'] {
    --primary: 189 85% 55%; --ring: 189 85% 55%; --info: 189 85% 55%;
  }
  html[data-accent='green'][data-theme='system'] {
    --primary: 135 64% 45%; --ring: 135 64% 45%; --info: 135 64% 45%;
  }
  html[data-accent='orange'][data-theme='system'] {
    --primary: 32 100% 50%; --ring: 32 100% 50%; --info: 32 100% 50%;
  }
}


/* ============================================================================
   .7  Design-system bridge
       Basecoat 0.3.11 is a Tailwind v4 build: its components resolve colours
       through `var(--color-<name>)`, which it aliases to `var(--<name>)` and
       ships as complete oklch() colours.

       This project instead stores tokens as bare HSL triplets, because its own
       rules need the channels to compose alpha — `hsl(var(--success) / 0.1)`.
       A bare triplet is not a valid colour on its own, so Basecoat's own
       components could never consume these tokens; that is why buttons and
       alerts previously needed hardcoded `!important` colours to look right.

       The bridge below closes that gap once: every Basecoat colour alias is
       re-pointed at the triplet, wrapped back into a real `hsl()`. Because
       custom properties resolve at use time, this single block covers every
       theme — switching appearance changes the triplet and the alias follows.
       The whole component library now inherits the palette for free.
   ============================================================================ */

:root {
  --color-background:              hsl(var(--background));
  --color-foreground:              hsl(var(--foreground));
  --color-card:                    hsl(var(--card));
  --color-card-foreground:         hsl(var(--card-foreground));
  --color-popover:                 hsl(var(--popover));
  --color-popover-foreground:      hsl(var(--popover-foreground));
  --color-primary:                 hsl(var(--primary));
  --color-primary-foreground:      hsl(var(--primary-foreground));
  --color-secondary:               hsl(var(--secondary));
  --color-secondary-foreground:    hsl(var(--secondary-foreground));
  --color-muted:                   hsl(var(--muted));
  --color-muted-foreground:        hsl(var(--muted-foreground));
  --color-accent:                  hsl(var(--accent));
  --color-accent-foreground:       hsl(var(--accent-foreground));
  --color-destructive:             hsl(var(--destructive));
  --color-border:                  hsl(var(--border));
  --color-input:                   hsl(var(--input));
  --color-ring:                    hsl(var(--ring));

  /* Basecoat's sidebar family: this panel's sidebar is a card surface. */
  --color-sidebar:                 hsl(var(--card));
  --color-sidebar-foreground:      hsl(var(--card-foreground));
  --color-sidebar-accent:          hsl(var(--accent));
  --color-sidebar-accent-foreground: hsl(var(--accent-foreground));
  --color-sidebar-border:          hsl(var(--border));
  --color-sidebar-ring:            hsl(var(--ring));

  /* Scrollbars pick up the theme instead of staying translucent black. */
  --scrollbar-thumb: hsl(var(--muted-foreground) / 0.35);
}


/* ============================================================================
   .8  Elevation
       Layered soft shadows in the theme's own shadow colour, so cards read as
       lifted in light mode and as quietly separated in dark mode rather than
       stamped with a black halo.
   ============================================================================ */

:root {
  --shadow-sm:
    0 1px 2px hsl(var(--shadow-color) / calc(var(--shadow-strength) * 0.6));
  --shadow-md:
    0 2px 4px hsl(var(--shadow-color) / calc(var(--shadow-strength) * 0.5)),
    0 6px 16px hsl(var(--shadow-color) / calc(var(--shadow-strength) * 0.6));
  --shadow-lg:
    0 4px 8px hsl(var(--shadow-color) / calc(var(--shadow-strength) * 0.5)),
    0 16px 40px hsl(var(--shadow-color) / calc(var(--shadow-strength) * 0.8));
}

/* Page background never bleeds the wrong colour during font swap. */
html,
body {
  background-color: hsl(var(--background));
  color: hsl(var(--foreground));
}

/* Appearance changes are instant on the tokens but eased on the paint, so
   flipping the switcher settles rather than snapping. */
.app-shell,
.app-sidebar,
.app-topbar,
.card,
.app-footer {
  transition:
    background-color var(--duration-base) var(--ease-standard),
    border-color var(--duration-base) var(--ease-standard);
}


/* ============================================================================
   .4  App shell — floating islands on a recessed canvas
       The sidebar and topbar are rounded islands inset from the viewport by
       --island-gap, floating on the canvas rather than touching the edges.
       The main column flexes to fill the remaining space; an inner wrapper
       with max-width keeps the content centred on wide screens.
   ============================================================================ */

.app-shell {
  display: flex;
  flex-direction: row;
  min-height: 100dvh;
  width: 100%;
  background-color: hsl(var(--background));
}

.app-sidebar {
  flex: 0 0 var(--layout-sidebar-width);
  width: var(--layout-sidebar-width);
  position: sticky;
  top: var(--island-gap);
  height: calc(100dvh - 2 * var(--island-gap));
  margin: var(--island-gap) 0 var(--island-gap) var(--island-gap);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  padding: calc(var(--spacing) * 2);
  /* Vibrancy material: the canvas colour shows through a saturated blur,
     which is what separates an Apple sidebar from a flat grey panel. */
  background-color: hsl(var(--card) / var(--material-opacity));
  backdrop-filter: var(--material-blur);
  -webkit-backdrop-filter: var(--material-blur);
  border: 1px solid hsl(var(--border));
  border-radius: var(--island-radius);
  box-shadow: var(--shadow-sm);
  z-index: 30;
}

/* Browsers without backdrop-filter get the opaque surface instead of a
   washed-out translucent one. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .app-sidebar {
    background-color: hsl(var(--card));
  }
}

.app-main {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
}

/* Scrolled content must never peek through the canvas strip above the
   floating topbar: a sticky spacer paints the gap in canvas colour, sitting
   over the content (z: 19) but under the topbar island (z: 20). */
.app-main::before {
  content: "";
  display: block;
  position: sticky;
  top: 0;
  z-index: 19;
  height: var(--island-gap);
  margin-bottom: calc(-1 * var(--island-gap));
  background-color: hsl(var(--background));
}

.app-topbar {
  position: sticky;
  top: var(--island-gap);
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 1rem;
  height: var(--layout-navbar-height);
  margin: var(--island-gap) var(--island-gap) 0;
  padding-inline: 1.25rem;
  /* An island, not a strip: same card material as the sidebar, floating on
     the canvas so content slides underneath it into the gap. */
  background-color: hsl(var(--card) / var(--material-opacity));
  backdrop-filter: var(--material-blur);
  -webkit-backdrop-filter: var(--material-blur);
  border: 1px solid hsl(var(--border));
  border-radius: var(--island-radius);
  box-shadow: var(--shadow-sm);
}

/* Same fallback the sidebar gets: no blur support → opaque island. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .app-topbar {
    background-color: hsl(var(--card));
  }
}

.app-content {
  flex: 1 1 auto;
  /* Content cards line up with the topbar island's edges: one shared gap
     everywhere is what makes the layout read as a grid of islands. */
  padding: 1.25rem var(--island-gap) 2rem;
}

.app-content-inner {
  width: 100%;
  max-width: var(--layout-content-max);
  margin-inline: auto;
}

.app-footer {
  padding: 0.5rem 1.5rem 1rem;
  font-size: 0.75rem;
  color: hsl(var(--muted-foreground));
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem;
}


/* ============================================================================
   .5  Sidebar internals — flat menu, no accordions
   ============================================================================ */

.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  height: var(--layout-navbar-height);
  padding-inline: 1.125rem;
  border-bottom: 1px solid hsl(var(--border));
  flex-shrink: 0;
}

.sidebar-brand-logo {
  width: 2.125rem;
  height: 2.125rem;
  display: grid;
  place-items: center;
  border-radius: 0.5rem;
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  flex-shrink: 0;
}

.sidebar-brand-name {
  font-size: 0.875rem;
  font-weight: 600;
  color: hsl(var(--foreground));
  letter-spacing: -0.01em;
  line-height: 1.1;
}

.sidebar-brand-tag {
  font-size: 0.6875rem;
  color: hsl(var(--muted-foreground));
  margin-top: 0.125rem;
}

.sidebar-nav {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 0.875rem 0.625rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
}

.sidebar-section-label {
  font-size: 0.6875rem;
  font-weight: 600;
  color: hsl(var(--muted-foreground));
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 0.625rem 0.75rem 0.25rem;
}

.sidebar-link {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.5rem 0.75rem;
  border-radius: calc(var(--radius) - 2px);
  font-size: 0.8125rem;
  font-weight: 500;
  color: hsl(var(--muted-foreground));
  transition: color 120ms ease, background-color 120ms ease;
}

.sidebar-link [data-lucide],
.sidebar-link svg {
  width: 1rem;
  height: 1rem;
  flex-shrink: 0;
  color: currentColor;
}

.sidebar-link:hover {
  background-color: hsl(var(--accent));
  color: hsl(var(--accent-foreground));
}

.sidebar-link[aria-current="page"],
.sidebar-link.is-active {
  /* Accent-tinted pill, the island-era active state: follows the chosen
     accent through the token instead of a neutral grey fill. */
  background-color: hsl(var(--primary) / 0.12);
  color: hsl(var(--primary));
  font-weight: 600;
}

.sidebar-divider {
  height: 1px;
  background-color: hsl(var(--border));
  margin: 0.5rem 0.5rem;
  border: 0;
}

.sidebar-footer {
  border-top: 1px solid hsl(var(--border));
  padding: 0.75rem 0.875rem;
  display: flex;
  align-items: center;
  gap: 0.625rem;
  flex-shrink: 0;
}

.sidebar-user-avatar {
  width: 2rem;
  height: 2rem;
  display: grid;
  place-items: center;
  border-radius: 9999px;
  background-color: hsl(var(--secondary));
  color: hsl(var(--secondary-foreground));
  font-size: 0.75rem;
  font-weight: 600;
  flex-shrink: 0;
  text-transform: uppercase;
}

.sidebar-user-info {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  line-height: 1.2;
}

.sidebar-user-email {
  font-size: 0.75rem;
  font-weight: 500;
  color: hsl(var(--foreground));
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sidebar-user-role {
  font-size: 0.6875rem;
  color: hsl(var(--muted-foreground));
}


/* ============================================================================
   .6  Page-level helpers
       Used by page templates for layout, grids, and the network tab switcher.
   ============================================================================ */

/* --- Page section wrapper — vertical stack of cards --- */
.page-section {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

/* --- Page header: title + supporting text + optional right-aligned controls --- */
.page-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.page-header h1 {
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.018em;
  line-height: 1.2;
}

.page-header p {
  font-size: 0.875rem;
  color: hsl(var(--muted-foreground));
  margin-top: 0.25rem;
}

/* --- Two-column grid used by the Smart Contract / Network form --- */
.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1.125rem;
}

.form-grid > .col-span-2 {
  grid-column: 1 / -1;
}

/* --- Stat grid for the dashboard cards --- */
.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1rem;
}

/* --- Network tabs (TRON / BSC switcher). Reuses Basecoat's tablist look. --- */
.network-tabs {
  display: inline-flex;
  gap: 0.25rem;
  padding: 0.25rem;
  background-color: hsl(var(--muted));
  border: 1px solid hsl(var(--border));
  border-radius: calc(var(--radius) - 2px);
}

.network-tab {
  display: inline-flex;
  align-items: center;
  gap: 0.4375rem;
  padding: 0.4375rem 0.875rem;
  border-radius: calc(var(--radius) - 4px);
  font-size: 0.8125rem;
  font-weight: 500;
  color: hsl(var(--muted-foreground));
  transition: color 120ms ease, background-color 120ms ease;
}

.network-tab [data-lucide] {
  width: 0.875rem;
  height: 0.875rem;
}

.network-tab:hover {
  color: hsl(var(--foreground));
}

.network-tab.is-active {
  background-color: hsl(var(--background));
  color: hsl(var(--foreground));
  font-weight: 600;
}


/* ============================================================================
   .7  Component styles
       Action pills, JSON diff viewer, pagination bar, empty state, sort links.
   ============================================================================ */

/* --- Compact action pill (used inside Audit Log rows) --- */
.action-pill {
  display: inline-flex;
  align-items: center;
  padding: 0.1875rem 0.5rem;
  border-radius: 0.375rem;
  font-size: 0.6875rem;
  font-weight: 600;
  font-family: var(--font-mono);
  letter-spacing: 0.02em;
  background-color: hsl(var(--secondary));
  color: hsl(var(--secondary-foreground));
  border: 1px solid hsl(var(--border));
}

.action-pill[data-tone="success"] {
  background-color: hsl(var(--success) / 0.12);
  color: hsl(var(--success));
  border-color: hsl(var(--success) / 0.3);
}

.action-pill[data-tone="destructive"] {
  background-color: hsl(var(--destructive) / 0.12);
  color: hsl(var(--destructive));
  border-color: hsl(var(--destructive) / 0.3);
}

.action-pill[data-tone="warning"] {
  background-color: hsl(var(--warning) / 0.12);
  color: hsl(var(--warning));
  border-color: hsl(var(--warning) / 0.3);
}

.action-pill[data-tone="info"] {
  background-color: hsl(var(--info) / 0.12);
  color: hsl(var(--info));
  border-color: hsl(var(--info) / 0.3);
}

/* --- JSON diff blocks on the Audit Log detail row --- */
.diff-row td {
  background-color: hsl(var(--muted) / 0.4);
}

.diff-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 0.75rem;
  padding: 0.75rem 1rem;
}

.diff-block {
  border: 1px solid hsl(var(--border));
  border-radius: 0.375rem;
  overflow: hidden;
  background-color: hsl(var(--background));
}

.diff-block[data-tone="old"] {
  border-color: hsl(var(--destructive) / 0.3);
}

.diff-block[data-tone="new"] {
  border-color: hsl(var(--success) / 0.3);
}

.diff-label {
  display: block;
  padding: 0.4375rem 0.625rem;
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border-bottom: 1px solid hsl(var(--border));
}

.diff-block[data-tone="old"] .diff-label {
  background-color: hsl(var(--destructive) / 0.08);
  color: hsl(var(--destructive));
}

.diff-block[data-tone="new"] .diff-label {
  background-color: hsl(var(--success) / 0.08);
  color: hsl(var(--success));
}

.diff-code {
  padding: 0.625rem 0.75rem;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  line-height: 1.55;
  color: hsl(var(--foreground));
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 16rem;
  overflow: auto;
  direction: ltr;
  text-align: left;
}


/* ============================================================================
   .9  Sign-out button
       Rendered in the top bar as a red, destructive-intent action. Styled
       separately from Basecoat's .btn classes so it doesn't inherit the
       primary accent colour.
   ============================================================================ */

/* --- Top-bar action group --- */
.topbar-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-shrink: 0;
}

/* --- Sign-out button: red accent so the destructive intent is unmistakable --- */
.btn-sign-out {
  /* Colour only — layout, sizing, focus ring and motion come from Basecoat's
     btn-sm-outline. A persistent header action wants the destructive tone
     without the shouting of a solid btn-destructive. */
  border-color: hsl(var(--destructive) / 0.4);
  background-color: hsl(var(--destructive) / 0.10);
  color: hsl(var(--destructive-text));
}

.btn-sign-out [data-lucide],
.btn-sign-out svg {
  width: 0.875rem;
  height: 0.875rem;
  flex-shrink: 0;
}

.btn-sign-out:hover {
  background-color: hsl(var(--destructive) / 0.18);
  border-color: hsl(var(--destructive) / 0.6);
}

/* --- Compact pagination bar --- */
.pagination-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.625rem 1rem;
  border-top: 1px solid hsl(var(--border));
  font-size: 0.8125rem;
  color: hsl(var(--muted-foreground));
}

.pagination-bar nav {
  display: inline-flex;
  gap: 0.25rem;
}

.pagination-bar a,
.pagination-bar span[data-state] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2rem;
  height: 2rem;
  padding: 0 0.5rem;
  border: 1px solid hsl(var(--border));
  border-radius: calc(var(--radius) - 2px);
  background-color: hsl(var(--background));
  color: hsl(var(--foreground));
  text-decoration: none;
  font-variant-numeric: tabular-nums;
  font-size: 0.8125rem;
  transition: background-color 100ms ease;
}

.pagination-bar a:hover {
  background-color: hsl(var(--accent));
}

.pagination-bar span[data-state="active"] {
  background-color: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
  border-color: hsl(var(--primary));
}

.pagination-bar span[data-state="disabled"] {
  opacity: 0.4;
  cursor: not-allowed;
}

/*
 * Disabled wallet-row checkboxes (zero balance — cannot be swept).
 * Applies visually distinct greyed-out treatment to make it clear the
 * box is not interactive, without affecting normal table checkboxes.
 */
input[type="checkbox"].wallet-row-chk:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  filter: grayscale(100%);
}

/* --- Inline form helper text --- */
.form-help {
  font-size: 0.75rem;
  color: hsl(var(--muted-foreground));
  margin-top: 0.25rem;
  line-height: 1.5;
}

/* --- Empty-state container used inside table card bodies --- */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  padding: 3rem 1rem;
  text-align: center;
}

.empty-state [data-lucide] {
  width: 2rem;
  height: 2rem;
  color: hsl(var(--muted-foreground) / 0.7);
}


/* ============================================================================
   .8  Utility classes
       Single-purpose classes that replace every inline style= attribute in
       the HTML templates.  Grouped by concern: layout, text, spacing, etc.
   ============================================================================ */

/* --- Layout / flexbox helpers --- */
.flex {
  display: flex;
}

.flex-col {
  flex-direction: column;
}

.flex-wrap {
  flex-wrap: wrap;
}

.flex-center {
  align-items: center;
}

.flex-end {
  justify-content: flex-end;
}

.flex-between {
  justify-content: space-between;
}

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

.gap-xs {
  gap: 0.25rem;
}

.gap-sm {
  gap: 0.5rem;
}

.my-sm {
  margin-block: 0.5rem;
}

.gap-md {
  gap: 0.75rem;
}

.gap-lg {
  gap: 1rem;
}

.gap-xl {
  gap: 1.25rem;
}

/* --- Text helpers --- */
.text-xs {
  font-size: 0.75rem;
}

.text-sm {
  font-size: 0.8125rem;
}

.text-muted {
  color: hsl(var(--muted-foreground));
}

.text-destructive {
  color: hsl(var(--destructive));
}

.text-success {
  color: hsl(var(--success));
}

.text-end {
  text-align: end;
}

.text-center {
  text-align: center;
}

.text-upper {
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.font-bold {
  font-weight: 700;
}

.font-semibold {
  font-weight: 600;
}

.font-medium {
  font-weight: 500;
}

.lh-tight {
  line-height: 1.2;
}

.tracking-tight {
  letter-spacing: -0.018em;
}

.no-wrap {
  white-space: nowrap;
}

.tabular-nums {
  font-variant-numeric: tabular-nums;
}

/* --- Overflow --- */
.overflow-x-auto {
  overflow-x: auto;
}

.overflow-hidden {
  overflow: hidden;
}

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

/* --- Spacing / sizing --- */
.mt-xs {
  margin-top: 0.125rem;
}

.mt-sm {
  margin-top: 0.25rem;
}

.mt-md {
  margin-top: 1rem;
}

.mt-lg {
  margin-top: 1.25rem;
}

.mb-md {
  margin-bottom: 1rem;
}

.mb-lg {
  margin-bottom: 1.75rem;
}

.p-0 {
  padding: 0;
}

.px-md {
  padding-inline: 0.75rem;
}

.py-sm {
  padding-block: 0.625rem;
}

.w-full {
  width: 100%;
}

.h-btn {
  height: 2.5rem;
}

.max-w-xs {
  max-width: 26rem;
}

.max-w-cell {
  max-width: 18rem;
}

/* --- Grid helpers --- */
.grid-2col {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

.grid-full {
  grid-column: 1 / -1;
}

/* --- Card sub-status grid (used in dashboard network cards) --- */
.status-mini-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
}

.status-mini-cell {
  padding: 0.625rem 0.75rem;
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  background-color: hsl(var(--muted) / 0.35);
}

.status-mini-label {
  font-size: 0.6875rem;
  color: hsl(var(--muted-foreground));
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.status-mini-value {
  margin-top: 0.25rem;
}

/* --- Card footer row (quick-link buttons) --- */
.btn,
.toggle-title,
.card > header h2 {
  text-transform: capitalize;
}

.card-footer-row {
  display: flex;
  gap: 0.5rem;
  padding-top: 0;
}

/*
 * Stat balance row — shown inside dashboard network stat cards when
 * wallet counts and total USDT are available.
 */
.stat-balance-row {
  margin-top: 0.5rem;
}

/*
 * Input icon wrapper — contains the leading icon and optional trailing toggle
 * button.  min-width: 0 is critical: without it a flex/grid child will refuse
 * to shrink below its intrinsic content width, causing overflow.
 */
.input-icon-wrap {
  position: relative;
  display: flex;
  align-items: center;
  min-width: 0;
}

/*
 * Masked / encrypted-key input variant.
 * Applies text truncation so a long Fernet-encrypted string shown in the
 * placeholder does not stretch the card.  Works alongside .input-with-icon-btn.
 */
.input-key-masked {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.input-icon {
  position: absolute;
  inset-inline-start: 0.625rem;
  width: 0.875rem;
  height: 0.875rem;
  color: hsl(var(--muted-foreground));
  pointer-events: none;
}

.input-icon-sm {
  position: absolute;
  inset-inline-start: 0.625rem;
  width: 0.75rem;
  height: 0.75rem;
  color: hsl(var(--muted-foreground));
  pointer-events: none;
}

.input-with-icon {
  padding-inline-start: 2rem;
}

.input-with-icon-btn {
  padding-inline: 2rem 2.5rem;
}

.input-toggle-btn {
  position: absolute;
  inset-inline-end: 0.25rem;
}

.input-otp {
  letter-spacing: 0.3em;
  font-size: 1rem;
}

/* --- Login page layout --- */
.login-page {
  min-height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem 1rem;
  background-color: hsl(var(--background));
}

.login-container {
  width: 100%;
  max-width: 26rem;
}

.login-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 1.75rem;
}

.login-brand-logo {
  width: 2.75rem;
  height: 2.75rem;
  font-size: 1rem;
}

.login-brand-title {
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -0.018em;
  line-height: 1.2;
}

.login-brand-sub {
  font-size: 0.8125rem;
  color: hsl(var(--muted-foreground));
  margin-top: 0.25rem;
}

.login-form {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.login-alert {
  margin-bottom: 1.25rem;
}

.alert h2 {
  text-transform: capitalize;
}

/*
 * Toned alerts.
 *
 * Each tone is derived entirely from its own token, so the same three rules
 * hold in every appearance: a low-alpha wash of the tone for the surface, a
 * slightly stronger one for the border, and the tone itself for the text.
 * `color-mix` pulls the text toward the theme's foreground just enough to
 * stay legible on a light canvas without going muddy on a dark one.
 */
.alert[data-tone="success"] {
  background-color: hsl(var(--success) / 0.10) !important;
  border: 1px solid hsl(var(--success) / 0.40) !important;
  color: hsl(var(--success-text)) !important;
}

.alert[data-tone="success"] [data-lucide],
.alert[data-tone="success"] svg,
.alert[data-tone="success"] h2,
.alert[data-tone="success"] section {
  color: inherit !important;
  stroke: currentColor !important;
}

.alert[data-tone="warning"] {
  background-color: hsl(var(--warning) / 0.10) !important;
  border: 1px solid hsl(var(--warning) / 0.40) !important;
  color: hsl(var(--warning-text)) !important;
}

.alert[data-tone="warning"] [data-lucide],
.alert[data-tone="warning"] svg,
.alert[data-tone="warning"] h2,
.alert[data-tone="warning"] section {
  color: inherit !important;
  stroke: currentColor !important;
}

.alert[data-tone="info"] {
  background-color: hsl(var(--info) / 0.10) !important;
  border: 1px solid hsl(var(--info) / 0.35) !important;
  color: hsl(var(--info-text)) !important;
}

.alert[data-tone="info"] [data-lucide],
.alert[data-tone="info"] svg,
.alert[data-tone="info"] h2,
.alert[data-tone="info"] section {
  color: inherit !important;
  stroke: currentColor !important;
}

.alert-destructive,
.alert[data-tone="destructive"],
.alert.login-alert {
  background-color: hsl(var(--destructive) / 0.12) !important;
  border: 1px solid hsl(var(--destructive) / 0.45) !important;
  color: hsl(var(--destructive-text)) !important;
}

.alert-destructive [data-lucide],
.alert-destructive svg,
.alert-destructive h2,
.alert-destructive section,
.alert[data-tone="destructive"] [data-lucide],
.alert[data-tone="destructive"] svg,
.alert[data-tone="destructive"] h2,
.alert[data-tone="destructive"] section,
.alert.login-alert [data-lucide],
.alert.login-alert svg,
.alert.login-alert h2,
.alert.login-alert section {
  color: inherit !important;
  stroke: currentColor !important;
}

/*
 * .login-submit — the "Continue" button on the login page.
 * Follows the accent like every other primary action.
 */
.login-submit {
  width: 100%;
  height: 2.75rem;
  font-weight: 600;
  margin-top: 0.25rem;
  background-color: hsl(var(--primary)) !important;
  color: hsl(var(--primary-foreground)) !important;
  border-color: hsl(var(--primary)) !important;
  transition: filter var(--duration-fast) var(--ease-standard),
              transform var(--duration-fast) var(--ease-standard);
}

.login-submit:hover {
  filter: brightness(1.08);
}

.login-submit:active {
  transform: scale(0.985);
  filter: brightness(0.94);
}

.login-footer {
  margin-top: 1.25rem;
  text-align: center;
  font-size: 0.75rem;
  color: hsl(var(--muted-foreground));
}

/* --- Dynamic breadcrumb inside the topbar --- */
.topbar-breadcrumb {
  display: flex;
  align-items: center;
  min-width: 0;
  overflow: hidden;
}

.breadcrumb-list {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem;
  margin: 0;
  padding: 0;
  font-size: 0.8125rem;
  color: hsl(var(--muted-foreground));
}

.breadcrumb-item {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}

.breadcrumb-link {
  color: hsl(var(--muted-foreground));
  text-decoration: none;
  white-space: nowrap;
  transition: color 120ms ease;
}

.breadcrumb-link:hover {
  color: hsl(var(--foreground));
}

.breadcrumb-muted {
  color: hsl(var(--muted-foreground));
  white-space: nowrap;
}

.breadcrumb-current {
  color: hsl(var(--foreground));
  font-weight: 500;
  white-space: nowrap;
}

.breadcrumb-separator {
  display: inline-flex;
  align-items: center;
  color: hsl(var(--muted-foreground));
  opacity: 0.5;
  flex-shrink: 0;
}

.breadcrumb-separator svg {
  width: 0.875rem;
  height: 0.875rem;
}

.topbar-left {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-width: 0;
  flex: 1;
}

/* --- Icon sizing inside badges and small spots --- */
.icon-xs {
  width: 0.75rem;
  height: 0.75rem;
}

.icon-sm {
  width: 0.875rem;
  height: 0.875rem;
}

.icon-md {
  width: 1rem;
  height: 1rem;
}

/* --- Diff viewer inline icon --- */
.diff-icon-inline {
  width: 0.75rem;
  height: 0.75rem;
  margin-inline-end: 0.25rem;
}

/*
 * Filter toolbar layout.
 * align-items: flex-end ensures every child aligns along the bottom of the
 * toolbar row so labelled and un-labelled items sit flush at the same baseline.
 */
.filter-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.5rem;
  padding: 0.875rem 1rem;
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  background-color: hsl(var(--card));
}

.filter-field-wrap--search {
  flex: 1 1 14rem;
  min-width: 12rem;
}

.filter-input-wrap {
  position: relative;
  display: flex;
  align-items: center;
}

.filter-input {
  padding-inline-start: 1.75rem;
  height: 2.25rem;
  width: 100%;
}

.filter-select {
  height: 2.25rem;
}

.filter-field-wrap {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  min-width: 9rem;
}

.filter-field-label {
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: hsl(var(--muted-foreground));
  margin: 0;
}

.filter-field-label + select {
  width: 100%;
}

.filter-submit-btn {
  align-self: flex-end;
}

/* --- Audit log table cell styles --- */
.cell-date {
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.cell-mono {
  font-family: var(--font-mono);
  font-size: 0.75rem;
}

.cell-entity-id {
  color: hsl(var(--muted-foreground));
  margin-inline-start: 0.25rem;
}

/* --- Table column widths (used in dashboard + audit log) --- */
.col-w-3 {
  width: 3rem;
}

.col-w-9 {
  width: 9rem;
}

.col-w-10 {
  width: 10rem;
}

.col-w-12 {
  width: 12rem;
}

/* --- Dashboard card header layout --- */
.stat-card-header-inner {
  flex: 1;
  min-width: 0;
}

/* --- Lucide icon sizing defaults --- */
[data-lucide] {
  width: 1rem;
  height: 1rem;
  stroke-width: 2;
  display: inline-block;
  vertical-align: -0.125em;
}

/* --- Toggle (checkbox-based) component --- */
.toggle-wrap {
  display: flex;
  align-items: flex-start;
  gap: 0.875rem;
  padding: 0.875rem;
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  background-color: hsl(var(--card));
}

.toggle-label {
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  margin: 0;
}

.toggle-input {
  width: 2.5rem !important;
  height: 1.375rem !important;
  appearance: none;
  position: relative;
  cursor: pointer;
  background-color: hsl(var(--secondary));
  border: 1px solid hsl(var(--border)) !important;
  border-radius: 9999px !important;
  transition: background-color 160ms ease;
  flex-shrink: 0;
}

.toggle-input::before {
  content: '';
  position: absolute;
  top: 50%;
  inset-inline-start: 2px;
  width: 1rem;
  height: 1rem;
  transform: translateY(-50%);
  background-color: hsl(var(--foreground));
  border-radius: 9999px;
  transition: inset-inline-start 160ms ease;
}

.toggle-input:checked {
  background-color: hsl(var(--success)) !important;
  border-color: hsl(var(--success)) !important;
}

.toggle-input:checked::before {
  inset-inline-start: calc(100% - 1.125rem);
  background-color: hsl(var(--success-foreground));
}

.toggle-body {
  flex: 1 1 auto;
  min-width: 0;
}

.toggle-title {
  font-size: 0.875rem;
  font-weight: 600;
  color: hsl(var(--foreground));
}

/* --- Badge variants --- */
.badge-success {
  background-color: hsl(var(--success) / 0.14);
  color: hsl(var(--success-text));
  border-color: hsl(var(--success) / 0.35);
}

.badge-muted {
  color: hsl(var(--muted-foreground));
}

.badge-network {
  min-width: 5rem;
}

/* --- Empty state text nodes --- */
.empty-state-title {
  font-size: 0.9375rem;
  font-weight: 600;
}

.empty-state-body {
  font-size: 0.8125rem;
  color: hsl(var(--muted-foreground));
  max-width: 28rem;
}

/*
 * Read-only input variant — used for fields that display database values
 * but must not be editable by the admin.  Selection remains enabled so
 * operators can copy locked addresses and keys.
 */
.input-readonly {
  opacity: 0.55;
  cursor: text;
  background-color: hsl(var(--muted) / 0.5) !important;
  color: hsl(var(--muted-foreground)) !important;
  -webkit-user-select: text;
  user-select: text;
}

.input-readonly:focus {
  outline: none;
  box-shadow: none;
}

/*
 * Small "Read-only" badge inline with a form label.
 */
.readonly-badge {
  font-size: 0.625rem;
  padding: 0.125rem 0.375rem;
  margin-inline-start: 0.5rem;
  vertical-align: middle;
}

/* --- Make Basecoat's .input and .btn honour Inter explicitly --- */
.input,
.textarea,
.select,
.btn,
.badge {
  font-family: var(--font-sans);
}

/* --- Wallet address rows stay LTR even inside an RTL ancestor (defensive) --- */
.font-mono.ltr-text {
  direction: ltr;
  text-align: start;
  unicode-bidi: plaintext;
}


/* ============================================================================
   .10  Responsive breakpoints
        Below 1024 px: layout grid collapses where needed.
        Below  768 px: the sidebar becomes an off-canvas drawer.
   ============================================================================ */

/* Small responsive collapses at 1024 px */

/* --- Burger button: hidden on desktop, revealed at the mobile breakpoint --- */
.sidebar-toggle-btn {
  display: none;
}

@media (max-width: 768px) {
  .sidebar-toggle-btn {
    display: inline-flex;
  }

  .app-sidebar {
    position: fixed;
    inset-block: 0;
    inset-inline-start: 0;
    /* The island keeps its inset margins as a drawer, so it has to travel
       its own width plus the left gap to fully clear the viewport. */
    transform: translateX(calc(-100% - var(--island-gap)));
    transition: transform 200ms ease;
  }

  .app-sidebar.is-open {
    transform: translateX(0);
    box-shadow: var(--shadow-lg);
  }

  .sidebar-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background-color: hsl(var(--shadow-color) / 0.5);
    z-index: 25;
  }

  .sidebar-backdrop.is-visible {
    display: block;
  }

  .app-content {
    padding: 1rem var(--island-gap) 1.5rem;
  }
}


/* ============================================================================
   .11  Component fine-tuning
        Low-priority overrides for Basecoat defaults, stat card header layout,
        the code key badge, and font-family consistency.
   ============================================================================ */

/* --- Stat-card header layout used on the dashboard --- */
.stat-card header {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
}

.stat-card header > [data-lucide] {
  width: 1.25rem;
  height: 1.25rem;
  color: hsl(var(--muted-foreground));
  margin-top: 0.125rem;
}

.stat-card .stat-label {
  font-size: 0.75rem;
  color: hsl(var(--muted-foreground));
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.stat-card .stat-value {
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.018em;
  line-height: 1.2;
}

/* --- Code badge for inline keys --- */
.kbd-key {
  display: inline-flex;
  align-items: center;
  padding: 0.125rem 0.4375rem;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  background-color: hsl(var(--muted));
  border: 1px solid hsl(var(--border));
  border-radius: 0.3125rem;
  color: hsl(var(--foreground));
}

/*
 * Truncating modifier for .kbd-key when the content is a long string.
 */
.kbd-key--truncate {
  display: inline-block;
  max-width: 15rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: middle;
}

/* --- Subtle sortable-column header link --- */
.sort-link {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  color: hsl(var(--muted-foreground));
  font-weight: 600;
  text-transform: uppercase;
  font-size: 0.6875rem;
  letter-spacing: 0.05em;
  transition: color 100ms ease;
}

.sort-link:hover {
  color: hsl(var(--foreground));
}

.sort-link.is-active {
  color: hsl(var(--foreground));
}

.sort-icon-inactive {
  opacity: 0.45;
  color: hsl(var(--muted-foreground));
}

.form-field label {
  margin-bottom: 0.6875rem;
  text-transform: capitalize;
}

:is(
  :is(.form, .field) :is(
    input[type=text]:not(:is(.select [data-popover]>header input[role=combobox], .command>header input, .dialog>*>header input)),
    input[type=email],
    input[type=password],
    input[type=number],
    input[type=file],
    input[type=tel],
    input[type=url],
    input[type=search]:not(:is(.select [data-popover]>header input[role=combobox], .command>header input, .dialog>*>header input)),
    input[type=date],
    input[type=datetime-local],
    input[type=month],
    input[type=week],
    input[type=time],
    textarea
  ),
  .input[type=text],
  .input[type=email],
  .input[type=password],
  .input[type=number],
  .input[type=file],
  .input[type=tel],
  .input[type=url],
  .input[type=search],
  .input[type=date],
  .input[type=datetime-local],
  .input[type=month],
  .input[type=week],
  .input[type=time],
  .textarea
)::placeholder {
  color: hsl(var(--muted-foreground));
}

/* --- Text selection inside editable form controls ---
   Basecoat sets display:flex on .input[...], which breaks native text
   highlighting in Chromium/Edge.  ::selection colours use hsl() so they
   work with our theme tokens (Basecoat's var(--color-primary) expects
   oklch values and renders an invisible highlight with our overrides).
 */
:is(
  .input[type=text],
  .input[type=email],
  .input[type=password],
  .input[type=number],
  .input[type=tel],
  .input[type=url],
  .input[type=search],
  .input[type=date],
  .input[type=datetime-local],
  .input[type=month],
  .input[type=week],
  .input[type=time],
  .textarea,
  .filter-input
) {
  display: inline-block;
  -webkit-user-select: text;
  user-select: text;
}

:is(
  .input[type=text],
  .input[type=email],
  .input[type=password],
  .input[type=number],
  .input[type=tel],
  .input[type=url],
  .input[type=search],
  .input[type=date],
  .input[type=datetime-local],
  .input[type=month],
  .input[type=week],
  .input[type=time],
  .textarea,
  .filter-input
)::selection {
  background-color: hsl(var(--primary) / 0.35);
  color: hsl(var(--foreground));
}


/* ============================================================================
   .12  Select / option contrast fix for dark theme
        Forces a dark background and light text on the dropdown widget.
   ============================================================================ */

html.dark select,
html.dark .select {
  color-scheme: dark;
  background-color: hsl(var(--card)) !important;
  color: hsl(var(--foreground)) !important;
  text-transform: capitalize;
}

html.dark select option,
html.dark .select option {
  background-color: hsl(240, 5%, 13%);
  color: hsl(var(--foreground));
}

html.dark select option:checked,
html.dark .select option:checked {
  background-color: hsl(var(--accent));
  color: hsl(var(--accent-foreground));
}


/* ============================================================================
   .13  Smart-Contract Deployment page
        Styles for the live-deployment panel: progress track/fill bar, the
        scrollable log console, the stage-timeline strip, and the result
        address display blocks.
   ============================================================================ */

/*
 * Progress track — the outer container that forms the grey rail.
 * The inner .deploy-fill div is animated by JavaScript (style.width).
 */
.deploy-track {
  background-color: hsl(var(--primary) / 0.2);
  position: relative;
  height: 0.5rem;
  width: 100%;
  overflow: hidden;
  border-radius: 9999px;
}

/* --- Progress fill — starts at 0% and advances on each stage SUCCESS event --- */
.deploy-fill {
  background-color: hsl(var(--primary));
  height: 100%;
  width: 0%;
  transition: width 400ms ease;
  border-radius: 9999px;
}

/* --- State modifiers applied by JavaScript when deployment finishes or fails --- */
.deploy-fill.is-error {
  background-color: hsl(var(--destructive));
}

.deploy-fill.is-done {
  background-color: hsl(var(--success));
}

/*
 * Accordion wrapper for the deploy-log console.
 */
.deploy-log-accordion {
  margin-top: 1rem;
}

/*
 * Scrollable monospace log console shown inside the accordion section.
 */
.deploy-log {
  background-color: hsl(var(--background));
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  padding: 0.875rem 1rem;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  line-height: 1.65;
  max-height: 20rem;
  overflow-y: auto;
  color: hsl(var(--foreground));
}

/* --- Log line colour variants --- */
.deploy-log .log-ok {
  color: hsl(var(--foreground));
}

.deploy-log .log-pending {
  color: hsl(var(--foreground));
}

.deploy-log .log-error {
  color: hsl(var(--destructive));
  font-weight: 500;
}

.deploy-log .log-done {
  color: hsl(var(--foreground));
  font-weight: 700;
}

/*
 * Stage-timeline strip — a vertical list of the four deployment stages.
 */
.stage-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 0.75rem;
}

.stage-item {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  font-size: 0.8125rem;
  color: hsl(var(--muted-foreground));
}

.stage-item.is-pending {
  color: hsl(var(--warning));
}

.stage-item.is-success {
  color: hsl(var(--success));
}

.stage-item.is-failed {
  color: hsl(var(--destructive));
}

.stage-item [data-lucide] {
  width: 1rem;
  height: 1rem;
  flex-shrink: 0;
}

/*
 * Result address display — shown after a successful deployment.
 */
.result-addr {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  word-break: break-all;
  padding: 0.375rem 0.625rem;
  background-color: hsl(var(--muted));
  border: 1px solid hsl(var(--border));
  border-radius: calc(var(--radius) - 2px);
  color: hsl(var(--foreground));
  line-height: 1.5;
}

/* --- Result card — flex column layout revealed by JS on 'done' event --- */
.deploy-result-card {
  display: none;
  flex-direction: column;
  gap: 1rem;
  margin-top: 1.25rem;
}

/*
 * Success state for the Deploy button after a successful deployment.
 */
.btn-deploy-success {
  background-color: hsl(var(--success) / 0.15) !important;
  color: hsl(var(--success)) !important;
  border-color: hsl(var(--success) / 0.45) !important;
  opacity: 1 !important;
  cursor: default;
}

.btn-deploy-success [data-lucide],
.btn-deploy-success svg {
  color: hsl(var(--success)) !important;
  stroke: hsl(var(--success)) !important;
}

/* --- Mainnet-danger badge used on the deployment page --- */
.badge-mainnet-danger {
  background-color: hsl(var(--destructive) / 0.15);
  color: hsl(var(--destructive-text));
  border-color: hsl(var(--destructive) / 0.4);
}

/*
 * Checklist component — used on the pre-flight checklist card.
 */
.checklist {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
}

.checklist-item {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
}

.checklist-body {
  flex: 1;
  min-width: 0;
}

.checklist-icon {
  flex-shrink: 0;
  margin-top: 0.0625rem;
}

.checklist-icon--ok {
  color: hsl(var(--success));
}

.checklist-icon--fail {
  color: hsl(var(--destructive));
}

.checklist-icon--warning {
  color: hsl(var(--warning));
}


/* ============================================================================
   .14  Wallet management
        All styles for the wallet table, status badges, sweep dialogs,
        worker progress bars, and the bulk-sweep summary boxes.
   ============================================================================ */

/* --- Wallet address cell: address + copy button on the same row --- */
.wallet-addr-cell {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  min-width: 0;
}

.wallet-addr-cell .font-mono {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 16rem;
}

/* --- Lifecycle / allocation status badges ---
 * .status-badge is the common wrapper.  Modifier classes encode both
 * the status family (lifecycle / allocation) and the specific value.
 */
.status-badge {
  display: inline-flex;
  align-items: center;
  padding: 0.1875rem 0.5rem;
  border-radius: 0.375rem;
  font-size: 0.6875rem;
  font-weight: 600;
  border: 1px solid transparent;
  white-space: nowrap;
}

/* Lifecycle — Creation Requested */
.status-badge--lifecycle-creation-requested {
  background-color: hsl(var(--muted) / 0.5);
  color: hsl(var(--muted-foreground));
  border-color: hsl(var(--border));
}

/* Lifecycle — Creation Failed (placeholder whose batch task failed) */
.status-badge--lifecycle-creation-failed {
  background-color: hsl(var(--destructive) / 0.12);
  color: hsl(var(--destructive-text));
  border-color: hsl(var(--destructive) / 0.3);
}

/* Lifecycle — Created */
.status-badge--lifecycle-created {
  background-color: hsl(var(--info) / 0.12);
  color: hsl(var(--info));
  border-color: hsl(var(--info) / 0.3);
}

/* Lifecycle — Awaiting Activation (TRON only) */
.status-badge--lifecycle-created-awaiting-activation {
  background-color: hsl(var(--warning) / 0.12);
  color: hsl(var(--warning));
  border-color: hsl(var(--warning) / 0.3);
}

/* Lifecycle — Activated */
.status-badge--lifecycle-activated {
  background-color: hsl(var(--success) / 0.12);
  color: hsl(var(--success));
  border-color: hsl(var(--success) / 0.3);
}

/* Allocation — Available (unassigned pool) */
.status-badge--alloc-available {
  background-color: hsl(var(--success) / 0.10);
  color: hsl(var(--success));
  border-color: hsl(var(--success) / 0.25);
}

/* Allocation — Assigned (permanent customer binding) */
.status-badge--alloc-assigned {
  background-color: hsl(var(--primary) / 0.12);
  color: hsl(var(--primary));
  border-color: hsl(var(--primary) / 0.3);
}

/* Allocation — Retired (clone of superseded contracts; never allocated) */
.status-badge--alloc-retired {
  background-color: hsl(var(--muted) / 0.5);
  color: hsl(var(--muted-foreground));
  border-color: hsl(var(--border));
  text-decoration: line-through;
}

/* Ledger — Deposit */
.status-badge--tx-deposit {
  background-color: hsl(var(--success) / 0.12);
  color: hsl(var(--success));
  border-color: hsl(var(--success) / 0.3);
}

/* Ledger — Withdrawal */
.status-badge--tx-withdrawal {
  background-color: hsl(var(--destructive) / 0.12);
  color: hsl(var(--destructive));
  border-color: hsl(var(--destructive) / 0.3);
}

.tx-hash-cell {
  display: inline-block;
  max-width: 12rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
}

.text-success {
  color: hsl(var(--success));
}

.text-destructive {
  color: hsl(var(--destructive));
}

/* --- Worker progress bars (Wallet Workers page) --- */
.worker-progress-list {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.worker-progress-item {
  padding: 0.875rem 1rem;
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  background-color: hsl(var(--muted) / 0.25);
}

.worker-progress-track {
  background-color: hsl(var(--primary) / 0.15);
  position: relative;
  height: 0.4375rem;
  width: 100%;
  overflow: hidden;
  border-radius: 9999px;
}

.worker-progress-fill {
  background-color: hsl(var(--primary));
  height: 100%;
  width: 0%;
  transition: width 600ms ease;
  border-radius: 9999px;
}

.worker-progress-fill.is-done {
  background-color: hsl(var(--success));
}

.worker-progress-fill.is-error {
  background-color: hsl(var(--destructive));
}

/* --- Task status action-pill variants --- */
.action-pill--done {
  background-color: hsl(var(--success) / 0.12);
  color: hsl(var(--success));
  border-color: hsl(var(--success) / 0.3);
}

.action-pill--failed {
  background-color: hsl(var(--destructive) / 0.12);
  color: hsl(var(--destructive));
  border-color: hsl(var(--destructive) / 0.3);
}

.action-pill--processing {
  background-color: hsl(var(--info) / 0.12);
  color: hsl(var(--info));
  border-color: hsl(var(--info) / 0.3);
}

/* --- Dialog styles ---
 * Native <dialog> element styling.  Basecoat styles .dialog-panel /
 * .dialog-header etc., but does NOT style the <dialog> element itself.
 */
/*
 * Basecoat's dialog model: `<dialog class="dialog">` is the full-viewport
 * stage, and its *direct child* is the floating panel — `.dialog > *` is
 * given `position: fixed`, centred with a translate, `display: flex` in a
 * column, and `max-height: calc(100% - 2rem)`.
 *
 * This file used to style the `<dialog>` element itself as the panel as well
 * (padding, max-width, border, shadow, its own scroll container). Both then
 * competed for the same job: the child won on position, which took it out of
 * flow, so the `<dialog>` collapsed to the height of its own padding and its
 * `overflow-y: auto` had nothing to scroll. Tall modals were simply cut off.
 *
 * So: let the dialog be the stage, and let Basecoat position the panel.
 */
dialog.dialog {
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  box-shadow: none;
  overflow: visible;
  color: hsl(var(--foreground));
}

/* The panel itself — Basecoat handles placement, we supply the surface. */
dialog.dialog > * {
  max-width: 32rem;
  min-height: 0;
  border-radius: var(--radius);
  border: 1px solid hsl(var(--border));
  background-color: hsl(var(--card));
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}

/* Wide variant used for the Bulk Sweep and access-editor dialogs */
dialog.dialog.dialog--wide > *,
dialog.dialog .dialog-panel--wide {
  max-width: 44rem;
}

/*
 * Scrolling: the panel is capped at the viewport, so the body is the part that
 * scrolls while the header and footer stay pinned. `min-height: 0` on every
 * flex ancestor is what actually lets the body shrink below its content — the
 * default `min-height: auto` on a flex item is exactly what makes long modals
 * overflow instead of scroll.
 *
 * Two markup shapes exist: some dialogs put the body and footer inside a
 * <form> under the panel, others place them directly under it. Both are
 * covered because the body is a flex item either way.
 */
dialog.dialog > * > form {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}

.dialog-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.dialog-header,
.dialog-footer {
  flex: 0 0 auto;
}

dialog.dialog::backdrop {
  background-color: hsl(var(--background) / 0.85);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

/*
 * Inner layout classes.
 * .dialog-panel kept as a passthrough so existing markup is not broken.
 */
.dialog-panel {
  display: flex;
  flex-direction: column;
  gap: 0;
  background-color: hsl(var(--background));
}

.dialog-panel--wide {
  max-width: 44rem;
}

/*
 * Header: strict single-row flex layout.
 */
.dialog-header {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  justify-content: space-between;
  width: 100%;
  gap: 1rem;
  margin-bottom: 1.5rem;
}

.dialog-close-btn {
  flex-shrink: 0;
  margin-top: -0.25rem;
  margin-right: -0.5rem;
}

.dialog-title {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 1.125rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.25;
  margin: 0;
  text-transform: capitalize;
}

.dialog-title [data-lucide] {
  width: 1rem;
  height: 1rem;
  flex-shrink: 0;
}

/* Body: vertically stacked form fields */
.dialog-body {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

/*
 * Footer: action buttons right-aligned, separated from the body by a
 * 1 px border and vertical padding.
 */
.dialog-footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.625rem;
  margin-top: 1.5rem;
  padding-top: 1rem;
  border-top: 1px solid hsl(var(--border));
}

/* Compact card used inside the single-sweep dialog to show wallet info */
.wallet-sweep-info {
  padding: 0.75rem 1rem;
  margin-bottom: 1rem;
  background-color: hsl(var(--muted) / 0.35);
}

.wallet-sweep-info hr {
  margin: 0.75rem 0;
}

/*
 * Destination address preview inside sweep dialogs.
 * Long TRON (T-prefix, 34 chars) and BSC (0x, 42 chars) addresses must
 * never be clipped — the admin must be able to read the full address for
 * verification before queuing a sweep.  break-all forces the string to
 * wrap at any character boundary so it is always fully visible.
 */
.sweep-dest-address {
  word-break: break-all;
  overflow-wrap: break-word;
  white-space: normal;
  line-height: 1.5;
  margin: 0;
  min-height: 1.25rem;
}

/* --- Bulk sweep network summary boxes --- */
.bulk-sweep-network-box {
  padding: 0.875rem 1rem;
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  background-color: hsl(var(--muted) / 0.25);
  margin-bottom: 1rem;
}

/* --- Pagination size form --- */
.pagination-size-form {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* --- Spacing helpers used inside wallet templates --- */
.mb-sm {
  margin-bottom: 0.375rem;
}

.mt-sm {
  margin-top: 0.375rem;
}

/* --- Destination radio-button group (Bulk Sweep dialog) ---
 * Two pill-shaped radio options rendered side-by-side.
 * The checked pill gets a primary-tinted border + background so it
 * reads as a clear selection indicator without native radio circle.
 */
.radio-group {
  display: flex;
  flex-direction: row;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.radio-option {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4375rem 0.875rem;
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  cursor: pointer;
  transition: background-color 100ms ease, border-color 100ms ease;
  user-select: none;
  flex: 1;
  min-width: 7rem;
}

.radio-option:has(input[type="radio"]:checked) {
  background-color: hsl(var(--primary) / 0.08);
  border-color: hsl(var(--primary) / 0.55);
}

.radio-option:hover {
  background-color: hsl(var(--accent));
}

.radio-option input[type="radio"] {
  accent-color: hsl(var(--primary));
  width: 1rem;
  height: 1rem;
  flex-shrink: 0;
  cursor: pointer;
}

.radio-option-label {
  font-size: 0.875rem;
  font-weight: 500;
  color: hsl(var(--foreground));
}

/* --- Destination address row inside the Bulk Sweep dialog ---
 * Provides a subtle inset background and border so the addresses are
 * visually separated per network without heavy visual noise.
 */
.bulk-dest-addr-row {
  padding: 0.5625rem 0.75rem;
  background-color: hsl(var(--muted) / 0.25);
  border-radius: calc(var(--radius) - 2px);
  border: 1px solid hsl(var(--border));
}

/* --- Security page feedback area ---
 * Vertical spacing above inline success/error alerts on /Setting/Security.
 */
.security-feedback-area {
  margin-block-end: var(--space-md, 1rem);
  min-height: 0;
}
.security-feedback-area:empty {
  display: none;
}

/* --- Workers History tab section header --- */
.page-section-header {
  margin-block-end: var(--space-sm, 0.75rem);
}
.page-section-title {
  font-size: var(--text-lg, 1.125rem);
  font-weight: 600;
  color: hsl(var(--foreground));
}

/* --- WebHook settings help panel --- */
.webhook-help p {
  line-height: 1.6;
}

.webhook-param-list {
  padding-inline-start: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.webhook-param-list code {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.8125rem;
}

.webhook-code-sample {
  padding: 0.75rem 1rem;
  border-radius: var(--radius);
  border: 1px solid hsl(var(--border));
  background-color: hsl(var(--muted) / 0.45);
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.75rem;
  line-height: 1.5;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-all;
}

/* --- Create Wallets fee estimate panel --- */
.create-fee-display {
  line-height: 1.55;
}

.create-fee-row + .create-fee-row {
  margin-top: 0.35rem;
}

.create-fee-loading {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: hsl(var(--foreground));
}

.create-fee-spinner {
  box-sizing: border-box;
  display: inline-block;
  width: 0.875rem;
  height: 0.875rem;
  border: 2px solid hsl(var(--muted-foreground) / 0.35);
  border-top-color: hsl(var(--info));
  border-radius: 50%;
  animation: create-fee-spin 0.7s linear infinite;
  flex-shrink: 0;
}

.sweep-mark-icon {
  color: hsl(var(--success));
  stroke: hsl(var(--success));
}

.alert[data-tone="info"] .create-fee-spinner {
  border-color: hsl(var(--info) / 0.28);
  border-top-color: hsl(var(--info));
}

html.dark .create-fee-spinner {
  border-color: hsl(var(--muted-foreground) / 0.45);
  border-top-color: hsl(var(--info));
}

@keyframes create-fee-spin {
  to { transform: rotate(360deg); }
}
.page-section-desc {
  margin-block-start: 0.25rem;
}

/* ==========================================================================
   USER MANAGEMENT  (/Setting/Users)
   Built from the same design tokens as the rest of the panel so the access
   editor reads as part of the system rather than a bolted-on screen.
   ========================================================================== */

/* Row action cluster: right-aligned, never wraps mid-cluster. */
.row-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.375rem;
  white-space: nowrap;
}

/* Account cell: avatar + name over email. */
.user-cell {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-width: 0;
}

.user-cell-body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.user-cell-name {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  font-weight: 500;
  line-height: 1.3;
}

.user-cell-email {
  font-size: 0.8125rem;
  color: hsl(var(--muted-foreground));
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Permission editor -------------------------------------------------------- */

.perm-section {
  margin-block-start: 1.25rem;
  padding-block-start: 1.25rem;
  border-block-start: 1px solid hsl(var(--border));
}

.perm-section-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-block-end: 0.875rem;
}

.perm-section-title {
  font-size: 0.9375rem;
  font-weight: 600;
  margin: 0;
}

.perm-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: 0.75rem;
  /* Groups hold wildly different numbers of permissions; without this the
     one-item group is stretched to match the tallest in its row. */
  align-items: start;
}

.perm-group {
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  padding: 0.75rem;
  margin: 0;
  min-width: 0;
}

.perm-group-legend {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding-inline: 0.375rem;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: hsl(var(--muted-foreground));
}

.perm-item {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: start;
  gap: 0.625rem;
  padding: 0.5rem;
  border-radius: calc(var(--radius) - 2px);
  cursor: pointer;
  transition: background-color 0.15s ease;
}

.perm-item:hover {
  background-color: hsl(var(--muted) / 0.5);
}

.perm-item.is-override {
  background-color: hsl(var(--info) / 0.08);
}

.perm-checkbox {
  margin-block-start: 0.1875rem;
  accent-color: hsl(var(--foreground));
  cursor: pointer;
}

.perm-checkbox:disabled {
  cursor: not-allowed;
  opacity: 0.6;
}

.perm-item-body {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  min-width: 0;
}

.perm-item-label {
  font-size: 0.875rem;
  line-height: 1.35;
}

.perm-item-help {
  font-size: 0.75rem;
  line-height: 1.4;
  color: hsl(var(--muted-foreground));
}

.perm-item-flag {
  align-self: center;
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 0.125rem 0.375rem;
  border-radius: 999px;
  color: hsl(var(--info));
  background-color: hsl(var(--info) / 0.14);
  white-space: nowrap;
}

.dialog-title-subject {
  font-weight: 500;
  color: hsl(var(--muted-foreground));
}

/* ==========================================================================
   FIRST-LOGIN ENROLMENT  (/Account/Setup)
   ========================================================================== */

.setup-container {
  max-width: 44rem;
}

.step-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  margin-inline-end: 0.5rem;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
  background-color: hsl(var(--foreground));
  color: hsl(var(--background));
}

.setup-qr-row {
  display: flex;
  gap: 1.5rem;
  align-items: flex-start;
  flex-wrap: wrap;
}

/* White plate keeps the QR high-contrast and scannable in the dark theme. */
.setup-qr-plate {
  flex: 0 0 auto;
  padding: 0.75rem;
  border-radius: var(--radius);
  background-color: #ffffff;
  line-height: 0;
}

.setup-qr-plate svg {
  display: block;
  width: 13.75rem;
  height: 13.75rem;
}

.setup-qr-side {
  flex: 1 1 16rem;
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
  min-width: 0;
}

.setup-actions {
  margin-block-start: 1.25rem;
}

/* ==========================================================================
   APPEARANCE SWITCHER
   A popover in the topbar holding two choices: appearance (light / dark /
   follow the system) and accent colour. The controls themselves are ordinary
   Basecoat buttons — only the popover shell, the segmented grouping and the
   colour dots are declared here, all from tokens.
   ========================================================================== */

.theme-menu-wrap {
  position: relative;
}

.theme-menu {
  position: absolute;
  inset-inline-end: 0;
  inset-block-start: calc(100% + 0.5rem);
  z-index: 50;
  width: 17rem;
  padding: 0.875rem;
  border-radius: var(--radius);
  border: 1px solid hsl(var(--border));
  background-color: hsl(var(--popover) / var(--material-opacity));
  backdrop-filter: var(--material-blur);
  -webkit-backdrop-filter: var(--material-blur);
  color: hsl(var(--popover-foreground));
  box-shadow: var(--shadow-lg);
  /* Sheets in Apple's UI scale up from slightly small as they fade in. */
  transform-origin: top right;
  animation: theme-menu-in var(--duration-base) var(--ease-standard);
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .theme-menu {
    background-color: hsl(var(--popover));
  }
}

@keyframes theme-menu-in {
  from { opacity: 0; transform: scale(0.96) translateY(-0.25rem); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}

.theme-menu[hidden] {
  display: none;
}

.theme-menu-label {
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: hsl(var(--muted-foreground));
  margin-block-end: 0.5rem;
}

.theme-menu-section + .theme-menu-section {
  margin-block-start: 1rem;
  padding-block-start: 1rem;
  border-block-start: 1px solid hsl(var(--border));
}

/* Segmented control: three buttons fused into one pill, as on iOS. */
.theme-segmented {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 0.25rem;
  padding: 0.25rem;
  border-radius: var(--radius-sm);
  background-color: hsl(var(--muted));
}

.theme-segment {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
  padding: 0.4rem 0.25rem;
  border: 0;
  border-radius: calc(var(--radius-sm) - 0.15rem);
  background-color: transparent;
  color: hsl(var(--muted-foreground));
  font-family: inherit;
  font-size: 0.75rem;
  font-weight: 500;
  cursor: pointer;
  transition:
    background-color var(--duration-fast) var(--ease-standard),
    color var(--duration-fast) var(--ease-standard),
    box-shadow var(--duration-fast) var(--ease-standard);
}

.theme-segment:hover {
  color: hsl(var(--foreground));
}

.theme-segment[aria-pressed="true"] {
  background-color: hsl(var(--card));
  color: hsl(var(--foreground));
  box-shadow: var(--shadow-sm);
}

.theme-segment svg,
.theme-segment [data-lucide] {
  width: 0.875rem;
  height: 0.875rem;
}

/* Accent swatches. */
.theme-swatches {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.theme-swatch {
  width: 1.75rem;
  height: 1.75rem;
  padding: 0;
  border-radius: var(--radius-pill);
  border: 2px solid transparent;
  background-color: hsl(var(--swatch));
  cursor: pointer;
  transition:
    transform var(--duration-fast) var(--ease-standard),
    box-shadow var(--duration-fast) var(--ease-standard);
}

.theme-swatch:hover {
  transform: scale(1.08);
}

.theme-swatch[aria-pressed="true"] {
  border-color: hsl(var(--background));
  box-shadow: 0 0 0 2px hsl(var(--swatch));
}

.theme-swatch:focus-visible {
  outline: 2px solid hsl(var(--ring));
  outline-offset: 2px;
}

/* Each dot paints its own colour, so the palette lives in one place. */
.theme-swatch[data-accent="blue"]     { --swatch: 211 100% 50%; }
.theme-swatch[data-accent="purple"]   { --swatch: 281 68% 60%; }
.theme-swatch[data-accent="indigo"]   { --swatch: 240 60% 55%; }
.theme-swatch[data-accent="teal"]     { --swatch: 189 68% 45%; }
.theme-swatch[data-accent="green"]    { --swatch: 135 54% 45%; }
.theme-swatch[data-accent="orange"]   { --swatch: 28 100% 50%; }
.theme-swatch[data-accent="graphite"] { --swatch: 240 4% 45%; }

@media (max-width: 640px) {
  .theme-menu {
    width: min(17rem, calc(100vw - 2rem));
  }
}

/* ==========================================================================
   PRESS FEEDBACK
   Basecoat supplies every button variant; the only thing added here is the
   momentary dim-and-shrink Apple uses to acknowledge a tap on a primary
   action. Written against the variant class directly, the way Basecoat
   models buttons.
   ========================================================================== */

.btn-primary,
.btn-sm-primary,
.btn-lg-primary,
.btn,
.btn-sm,
.btn-lg {
  transition: filter var(--duration-fast) var(--ease-standard),
              transform var(--duration-fast) var(--ease-standard);
}

.btn-primary:hover,
.btn-sm-primary:hover,
.btn-lg-primary:hover,
.btn:hover,
.btn-sm:hover,
.btn-lg:hover {
  filter: brightness(1.08);
}

.btn-primary:active,
.btn-sm-primary:active,
.btn-lg-primary:active,
.btn:active,
.btn-sm:active,
.btn-lg:active {
  transform: scale(0.985);
  filter: brightness(0.94);
}

/* ==========================================================================
   PUBLIC API REFERENCE  (/Developers)
   A documentation layout rather than an app shell: a sticky contents column
   and a measured reading width, built from the same tokens as everything else.
   ========================================================================== */

.docs-shell {
  display: flex;
  align-items: flex-start;
  min-height: 100dvh;
  background-color: hsl(var(--background));
}

.docs-nav {
  flex: 0 0 16rem;
  position: sticky;
  top: var(--island-gap);
  height: calc(100dvh - 2 * var(--island-gap));
  margin: var(--island-gap) 0 var(--island-gap) var(--island-gap);
  overflow-y: auto;
  padding: calc(var(--spacing) * 2);
  border: 1px solid hsl(var(--border));
  border-radius: var(--island-radius);
  box-shadow: var(--shadow-sm);
  background-color: hsl(var(--card) / var(--material-opacity));
  backdrop-filter: var(--material-blur);
  -webkit-backdrop-filter: var(--material-blur);
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .docs-nav { background-color: hsl(var(--card)); }
}

.docs-nav-links {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  margin-block-start: 1rem;
}

.docs-nav-links a {
  padding: 0.4rem 0.625rem;
  border-radius: var(--radius-sm);
  font-size: 0.8125rem;
  color: hsl(var(--muted-foreground));
  text-decoration: none;
  transition: background-color var(--duration-fast) var(--ease-standard),
              color var(--duration-fast) var(--ease-standard);
}

.docs-nav-links a:hover {
  background-color: hsl(var(--accent));
  color: hsl(var(--foreground));
}

.docs-content {
  flex: 1 1 auto;
  min-width: 0;
  /* ~75 characters: long enough for a code line, short enough to read. */
  max-width: 52rem;
  margin-inline: auto;
  padding: 2.5rem 1.75rem 4rem;
}

.docs-header {
  padding-block-end: 1.5rem;
  margin-block-end: 2rem;
  border-block-end: 1px solid hsl(var(--border));
}

.docs-header h1 {
  font-size: 2rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  margin: 0 0 0.5rem;
}

.docs-lede {
  font-size: 1.0625rem;
  line-height: 1.6;
  color: hsl(var(--muted-foreground));
  margin: 0 0 1rem;
}

.docs-content section {
  /* Offset for the in-page anchors so a heading is not hidden under the top. */
  scroll-margin-block-start: 1.5rem;
  margin-block-end: 3rem;
}

.docs-content h2 {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  flex-wrap: wrap;
  font-size: 1.25rem;
  font-weight: 650;
  letter-spacing: -0.015em;
  margin: 0 0 0.75rem;
}

.docs-content h3 {
  font-size: 0.9375rem;
  font-weight: 600;
  margin: 1.5rem 0 0.5rem;
  color: hsl(var(--muted-foreground));
}

.docs-content p {
  line-height: 1.65;
  margin: 0 0 0.875rem;
}

.docs-content code {
  padding: 0.1rem 0.3rem;
  border-radius: 0.25rem;
  background-color: hsl(var(--muted));
  font-size: 0.8125rem;
}

.docs-code {
  overflow-x: auto;
  padding: 0.875rem 1rem;
  margin: 0 0 1rem;
  border-radius: var(--radius);
  border: 1px solid hsl(var(--border));
  background-color: hsl(var(--muted) / 0.5);
}

.docs-code code {
  padding: 0;
  background: none;
  font-size: 0.8125rem;
  line-height: 1.6;
}

/* HTTP verb chips beside an endpoint heading. */
.docs-verb {
  padding: 0.15rem 0.45rem;
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.03em;
}

.docs-verb--get  { background-color: hsl(var(--info) / 0.15);    color: hsl(var(--info-text)); }
.docs-verb--post { background-color: hsl(var(--success) / 0.15); color: hsl(var(--success-text)); }

.docs-steps,
.docs-list {
  margin: 0 0 1rem;
  padding-inline-start: 1.25rem;
  line-height: 1.7;
}

.docs-steps li,
.docs-list li {
  margin-block-end: 0.5rem;
}

.docs-table {
  margin-block-end: 1rem;
}

.docs-table code {
  white-space: nowrap;
}

.docs-footer {
  padding-block-start: 1.5rem;
  border-block-start: 1px solid hsl(var(--border));
  font-size: 0.8125rem;
  color: hsl(var(--muted-foreground));
}

@media (max-width: 900px) {
  .docs-shell { flex-direction: column; }
  .docs-nav {
    position: static;
    height: auto;
    width: 100%;
    flex-basis: auto;
    border-right: 0;
    border-block-end: 1px solid hsl(var(--border));
  }
  .docs-nav-links {
    flex-direction: row;
    flex-wrap: wrap;
  }
  .docs-content { padding-inline: 1.25rem; }
}

/* ==========================================================================
   HOSTED PAYMENT PAGE  (/Pay/{token})
   A single-purpose page for someone who is not a user of this system and will
   see it once. Everything is sized for a phone held in one hand.
   ========================================================================== */

.pay-container {
  max-width: 26rem;
}

.pay-qr {
  display: flex;
  justify-content: center;
  margin-block: 1.25rem;
}

/* The amount is the one thing the payer must not misread, so it gets the
   weight normally reserved for a page title. */
.pay-amount {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 0.4rem;
  margin-block-end: 1.25rem;
}

.pay-amount-value {
  font-size: 2rem;
  font-weight: 650;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.pay-amount-unit {
  font-size: 0.9375rem;
  font-weight: 500;
  color: hsl(var(--muted-foreground));
}

.pay-status {
  margin-block-end: 0.5rem;
}

/* An expired link greys its own QR so a half-reading payer is less likely to
   scan it anyway. */
.pay-status[data-state="expired"] ~ .pay-qr .setup-qr-plate {
  filter: grayscale(1);
  opacity: 0.4;
}

@media (max-width: 420px) {
  .pay-qr .setup-qr-plate svg {
    width: 11rem;
    height: 11rem;
  }
  .pay-amount-value { font-size: 1.75rem; }
}

/* The payment address is read-only but must NOT look disabled — it is the one
   string the payer has to read or copy correctly, and the standard
   .input-readonly treatment (55% opacity, muted foreground) made it look like
   placeholder text. Keep the non-editable affordance, drop the fading. */
.pay-address {
  cursor: text;
  color: hsl(var(--foreground)) !important;
  background-color: hsl(var(--muted) / 0.4) !important;
  -webkit-user-select: all;
  user-select: all;
}

/* Basecoat styles the first element inside .alert as a title. The network
   warning is one sentence with emphasis in the middle, so it is wrapped in a
   paragraph to keep it flowing rather than being split into a heading. */
.pay-warning {
  margin: 0;
  line-height: 1.55;
}

/* ══════════════════════════════════════════════════════════════════════════
   Transactions page — totals strip and webhook delivery badges
   ══════════════════════════════════════════════════════════════════════════ */
.tx-summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 1rem 1.5rem;
  padding: 1rem 1.25rem;
  margin-bottom: 1rem;
}
.tx-summary-item { min-width: 0; }
.tx-summary-value {
  font-size: 1.25rem;
  font-weight: 600;
  line-height: 1.3;
  margin: 0.125rem 0;
}

/* Webhook — Delivered */
.status-badge--wh-delivered {
  background-color: hsl(var(--success) / 0.12);
  color: hsl(var(--success));
  border-color: hsl(var(--success) / 0.3);
}
/* Webhook — Pending / Delivering (retry in flight) */
.status-badge--wh-pending,
.status-badge--wh-delivering {
  background-color: hsl(var(--warning) / 0.12);
  color: hsl(var(--warning));
  border-color: hsl(var(--warning) / 0.3);
}
/* Webhook — Failed (all retries exhausted) */
.status-badge--wh-failed {
  background-color: hsl(var(--destructive) / 0.12);
  color: hsl(var(--destructive-text));
  border-color: hsl(var(--destructive) / 0.3);
}


/* ============================================================================
   .15  Reports & money flow
        Two things live here: the Reports page (filter chips, KPI tiles, the
        server-rendered SVG bar chart) and the "how a withdrawal works"
        diagram shared by Reports, Withdrawals and Withdrawal settings.

        Every colour is a token, so both themes come out right without a
        second rule set. The diagram is a plain ordered list: on a wide screen
        the steps sit in a row with a connector between them, and below the
        tablet breakpoint they stack and the connector turns vertical.
   ============================================================================ */

/* --- Badge variants the templates already ask for --- */
.badge-warning {
  background-color: hsl(var(--warning) / 0.14);
  color: hsl(var(--warning-text));
  border-color: hsl(var(--warning) / 0.35);
}

.badge-destructive {
  background-color: hsl(var(--destructive) / 0.12);
  color: hsl(var(--destructive-text));
  border-color: hsl(var(--destructive) / 0.3);
}

.badge-info {
  background-color: hsl(var(--info) / 0.12);
  color: hsl(var(--info-text));
  border-color: hsl(var(--info) / 0.3);
}

/* --- Filter chips --------------------------------------------------------- */
.report-filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md, 0.75rem);
  align-items: center;
  justify-content: space-between;
}

.report-filter-group {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
}

.report-chip {
  display: inline-flex;
  align-items: center;
  padding: 0.3125rem 0.75rem;
  border: 1px solid hsl(var(--border));
  border-radius: 999px;
  background-color: hsl(var(--card));
  color: hsl(var(--muted-foreground));
  font-size: 0.8125rem;
  font-weight: 500;
  text-decoration: none;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.report-chip:hover {
  color: hsl(var(--foreground));
  border-color: hsl(var(--muted-foreground) / 0.4);
}

.report-chip.is-active {
  background-color: hsl(var(--primary));
  border-color: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
}

/* --- Headline tiles ------------------------------------------------------- */
.report-kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: var(--space-md, 0.75rem);
}

.report-kpi {
  padding: 1rem 1.125rem;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  border-left: 3px solid hsl(var(--border));
}

.report-kpi[data-tone="success"]     { border-left-color: hsl(var(--success)); }
.report-kpi[data-tone="warning"]     { border-left-color: hsl(var(--warning)); }
.report-kpi[data-tone="destructive"] { border-left-color: hsl(var(--destructive)); }

.report-kpi-label {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: hsl(var(--muted-foreground));
}

.report-kpi-value {
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1.2;
  color: hsl(var(--foreground));
}

.report-kpi-unit {
  font-size: 0.8125rem;
  font-weight: 500;
  color: hsl(var(--muted-foreground));
}

.report-kpi-foot {
  font-size: 0.75rem;
  color: hsl(var(--muted-foreground));
}

/* --- Bar chart ------------------------------------------------------------ */
.report-chart-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
  margin-bottom: 0.75rem;
}

.report-legend-key {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.75rem;
  color: hsl(var(--muted-foreground));
}

.report-swatch {
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 2px;
  display: inline-block;
}

.report-swatch--in  { background-color: hsl(var(--success)); }
.report-swatch--out { background-color: hsl(var(--primary)); }

.report-chart-scroll {
  overflow-x: auto;
}

.report-chart {
  width: 100%;
  min-width: 20rem;
  height: 13rem;
}

.report-chart-base {
  stroke: hsl(var(--border));
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}

.report-bar--in  { fill: hsl(var(--success)); }
.report-bar--out { fill: hsl(var(--primary)); }

.report-chart-tick {
  fill: hsl(var(--muted-foreground));
  font-size: 10px;
  font-family: var(--font-mono);
}

.report-status-link {
  color: hsl(var(--foreground));
  text-decoration: none;
  border-bottom: 1px dotted hsl(var(--border));
}

.report-status-link:hover {
  color: hsl(var(--primary));
}

.report-split {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr));
  gap: var(--space-md, 0.75rem);
  align-items: start;
}

/* --- Money-flow diagram --------------------------------------------------- */
.flow-track {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1.25rem 1rem;
}

.flow-step {
  position: relative;
  padding: 0.875rem 1rem;
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  background-color: hsl(var(--card));
  border-top: 3px solid hsl(var(--muted-foreground) / 0.4);
}

.flow-step[data-tone="info"]        { border-top-color: hsl(var(--info)); }
.flow-step[data-tone="success"]     { border-top-color: hsl(var(--success)); }
.flow-step[data-tone="warning"]     { border-top-color: hsl(var(--warning)); }
.flow-step[data-tone="destructive"] { border-top-color: hsl(var(--destructive)); }

/* The connector: a chevron in the gutter between two steps. It is decorative,
   so it is drawn on ::after and never announced to a screen reader — the list
   order already carries the sequence. */
.flow-step::after {
  content: "";
  position: absolute;
  top: 50%;
  right: -0.75rem;
  width: 0.5rem;
  height: 0.5rem;
  border-top: 2px solid hsl(var(--muted-foreground) / 0.45);
  border-right: 2px solid hsl(var(--muted-foreground) / 0.45);
  transform: translateY(-50%) rotate(45deg);
}

.flow-step:last-child::after {
  content: none;
}

.flow-step-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.5rem;
}

.flow-step-index {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.375rem;
  height: 1.375rem;
  border-radius: 999px;
  background-color: hsl(var(--muted));
  color: hsl(var(--muted-foreground));
  font-size: 0.6875rem;
  font-weight: 700;
}

.flow-step-icon {
  width: 1rem;
  height: 1rem;
  color: hsl(var(--muted-foreground));
}

.flow-step-title {
  font-size: 0.875rem;
  font-weight: 600;
  color: hsl(var(--foreground));
  margin: 0 0 0.25rem;
}

.flow-step-body {
  font-size: 0.8125rem;
  line-height: 1.5;
  color: hsl(var(--muted-foreground));
  margin: 0;
}

.flow-step-wallet {
  margin-top: 0.625rem;
  padding-top: 0.625rem;
  border-top: 1px dashed hsl(var(--border));
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  min-width: 0;
}

.flow-step-wallet-label {
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: hsl(var(--muted-foreground));
}

.flow-step-wallet-value {
  font-size: 0.75rem;
  color: hsl(var(--foreground));
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  direction: ltr;
  text-align: left;
}

a.flow-step-wallet-value {
  color: hsl(var(--primary));
  text-decoration: none;
}

a.flow-step-wallet-value:hover {
  text-decoration: underline;
}

.flow-step-wallet-value.is-missing {
  color: hsl(var(--muted-foreground));
  font-style: italic;
}

.flow-owner {
  margin-top: 1.25rem;
  display: flex;
  gap: 0.75rem;
  padding: 0.875rem 1rem;
  border: 1px solid hsl(var(--destructive) / 0.3);
  border-radius: var(--radius);
  background-color: hsl(var(--destructive) / 0.06);
}

.flow-owner-icon {
  flex: 0 0 auto;
  width: 1.125rem;
  height: 1.125rem;
  margin-top: 0.125rem;
  color: hsl(var(--destructive-text));
}

.flow-notes {
  margin-top: 1rem;
  display: grid;
  gap: 0.5rem;
}

.flow-notes p {
  margin: 0;
  font-size: 0.8125rem;
  line-height: 1.55;
  color: hsl(var(--muted-foreground));
}

.flow-notes strong {
  color: hsl(var(--foreground));
}

/* --- Narrow screens: stack the steps, turn the connector downward --------- */
@media (max-width: 768px) {
  .flow-track {
    grid-template-columns: 1fr;
  }

  .flow-step::after {
    top: auto;
    right: 50%;
    bottom: -0.9rem;
    transform: translateX(50%) rotate(135deg);
  }

  .report-filters {
    flex-direction: column;
    align-items: stretch;
  }
}

/* --- Withdrawals page: settlement state strip ----------------------------- */
.settlement-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
  gap: var(--space-md, 0.75rem);
}

.settlement-card {
  padding: 0.875rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  border-left: 3px solid hsl(var(--muted-foreground) / 0.35);
}

.settlement-card[data-tone="success"] { border-left-color: hsl(var(--success)); }
.settlement-card[data-tone="warning"] { border-left-color: hsl(var(--warning)); }

.settlement-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.settlement-card-net {
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: hsl(var(--foreground));
}

.settlement-card-body {
  margin: 0;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: hsl(var(--muted-foreground));
}

.settlement-card-vault {
  font-size: 0.75rem;
  color: hsl(var(--primary));
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  direction: ltr;
  text-align: left;
}

.settlement-card-warn {
  margin: 0;
  display: flex;
  align-items: flex-start;
  gap: 0.375rem;
  font-size: 0.75rem;
  line-height: 1.45;
  color: hsl(var(--destructive-text));
}

.withdrawal-missing-list {
  margin: 0.5rem 0 0;
  padding-inline-start: 1.1rem;
  display: grid;
  gap: 0.25rem;
}

/* --- Withdrawals page: the float card and its top-up dialog --------------- */
.vault-float .card-title {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.topup-block {
  display: grid;
  gap: 0.5rem;
  padding-top: 0.875rem;
  border-top: 1px solid hsl(var(--border));
}

.topup-block-title {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  margin: 0;
  font-size: 0.8125rem;
  font-weight: 600;
  color: hsl(var(--foreground));
}

.topup-address-row {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: flex-start;
}

.topup-qr {
  flex: 0 0 auto;
}

.topup-address-body {
  flex: 1 1 14rem;
  min-width: 0;
  display: grid;
  gap: 0.375rem;
  justify-items: start;
}

.topup-address {
  display: block;
  width: 100%;
  padding: 0.375rem 0.5rem;
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius-sm);
  background-color: hsl(var(--muted) / 0.5);
  font-size: 0.75rem;
  word-break: break-all;
  direction: ltr;
  text-align: left;
}
