/* ============================================================================
   Material You — design system
   ----------------------------------------------------------------------------
   The pages are built from Bootstrap primitives (.card, .btn, .form-control,
   .table, .modal) plus a thin `sbx-` layer. So rather than rewrite 37 views,
   this file re-skins those primitives as M3 components: every page inherits the
   theme without touching its markup.

   Colour roles come from the tenant seed (App\Support\MaterialYou\ColorScheme)
   and land as --md-light-* / --md-dark-* custom properties on <html>. This file
   binds one set at a time to --md-sys-color-*, which is all any rule below
   reads — that indirection is what makes the dark toggle a class flip.

   Sections
     01 tokens · 02 base · 03 shell · 04 rail · 05 nav pane · 06 app bar
     07 buttons · 08 forms · 09 surfaces & bento · 10 tables · 11 pager
     12 empty states · 13 chips · 14 dialogs · 15 menus · 16 alerts
     17 toasts · 18 auth · 19 responsive
   ========================================================================= */

/* == 01 · tokens ========================================================== */

:root {
  /* Fallback scheme (seed #2ec4b6). The server overwrites these per tenant;
     they only matter for the split second before that, and for /login. */
  --md-light-primary: #006d65;
  --md-light-on-primary: #ffffff;
  --md-light-primary-container: #7efced;
  --md-light-on-primary-container: #001b18;
  --md-light-secondary: #406761;
  --md-light-on-secondary: #ffffff;
  --md-light-secondary-container: #c2ede7;
  --md-light-on-secondary-container: #001b18;
  --md-light-tertiary: #376286;
  --md-light-on-tertiary: #ffffff;
  --md-light-tertiary-container: #cbe6ff;
  --md-light-on-tertiary-container: #00182c;
  --md-light-error: #a0332d;
  --md-light-on-error: #ffffff;
  --md-light-error-container: #ffd8d3;
  --md-light-on-error-container: #330001;
  --md-light-surface: #f5fbfa;
  --md-light-on-surface: #131717;
  --md-light-surface-variant: #d8e6e4;
  --md-light-on-surface-variant: #3d4947;
  --md-light-surface-dim: #d6dbdb;
  --md-light-surface-bright: #f5fbfa;
  --md-light-surface-container-lowest: #ffffff;
  --md-light-surface-container-low: #eff5f4;
  --md-light-surface-container: #eaefee;
  --md-light-surface-container-high: #e4eae9;
  --md-light-surface-container-highest: #dee4e3;
  --md-light-outline: #6d7a78;
  --md-light-outline-variant: #bccac8;
  --md-light-inverse-surface: #2b2f2f;
  --md-light-inverse-on-surface: #edf2f1;
  --md-light-inverse-primary: #5fdfd1;
  --md-light-scrim: #000000;
  --md-light-shadow: #000000;

  --md-dark-primary: #5fdfd1;
  --md-dark-on-primary: #003732;
  --md-dark-primary-container: #005049;
  --md-dark-on-primary-container: #7efced;
  --md-dark-secondary: #a6d1ca;
  --md-dark-on-secondary: #0b3733;
  --md-dark-secondary-container: #274e49;
  --md-dark-on-secondary-container: #c2ede7;
  --md-dark-tertiary: #a1cbf3;
  --md-dark-on-tertiary: #00334f;
  --md-dark-tertiary-container: #1c4a6d;
  --md-dark-on-tertiary-container: #cbe6ff;
  --md-dark-error: #ffb4a8;
  --md-dark-on-error: #5f1410;
  --md-dark-error-container: #83291f;
  --md-dark-on-error-container: #ffd8d3;
  --md-dark-surface: #0e1211;
  --md-dark-on-surface: #dee4e3;
  --md-dark-surface-variant: #3d4947;
  --md-dark-on-surface-variant: #bccac8;
  --md-dark-surface-dim: #0e1211;
  --md-dark-surface-bright: #343938;
  --md-dark-surface-container-lowest: #090d0c;
  --md-dark-surface-container-low: #171b1b;
  --md-dark-surface-container: #1b1f1f;
  --md-dark-surface-container-high: #252a29;
  --md-dark-surface-container-highest: #303534;
  --md-dark-outline: #879492;
  --md-dark-outline-variant: #3d4947;
  --md-dark-inverse-surface: #dee4e3;
  --md-dark-inverse-on-surface: #2b2f2f;
  --md-dark-inverse-primary: #006d65;
  --md-dark-scrim: #000000;
  --md-dark-shadow: #000000;

  /* Type. Outfit/Manrope are the brand faces; the scale below is M3's. */
  --md-sys-font-brand: 'Outfit', 'Segoe UI', system-ui, sans-serif;
  --md-sys-font-plain: 'Manrope', 'Segoe UI', system-ui, sans-serif;

  --md-sys-typescale-headline-size: 1.5rem;
  --md-sys-typescale-title-large-size: 1.25rem;
  --md-sys-typescale-title-size: 1rem;
  --md-sys-typescale-body-size: 0.875rem;
  --md-sys-typescale-body-small-size: 0.8125rem;
  --md-sys-typescale-label-size: 0.875rem;
  --md-sys-typescale-label-small-size: 0.6875rem;

  /* Shape. M3's scale; text fields sit at `sm` rather than the spec's 4px —
     at this density the sharper corner reads as unfinished next to pill buttons. */
  --md-sys-shape-xs: 4px;
  --md-sys-shape-sm: 8px;
  --md-sys-shape-md: 12px;
  --md-sys-shape-lg: 16px;
  --md-sys-shape-xl: 28px;
  --md-sys-shape-full: 999px;

  /* State layers: M3 expresses interaction as an on-colour scrim, not a
     colour swap. Same opacities everywhere is what makes it feel coherent. */
  --md-sys-state-hover: 0.08;
  --md-sys-state-focus: 0.10;
  --md-sys-state-pressed: 0.10;

  /* Elevation. M3 leans on tonal surfaces; shadows stay faint and are used
     only where something genuinely floats (menus, dialogs, toasts). */
  --md-sys-elevation-1: 0 1px 2px rgb(0 0 0 / 0.08), 0 1px 3px 1px rgb(0 0 0 / 0.06);
  --md-sys-elevation-2: 0 1px 2px rgb(0 0 0 / 0.10), 0 2px 6px 2px rgb(0 0 0 / 0.07);
  --md-sys-elevation-3: 0 4px 8px 3px rgb(0 0 0 / 0.08), 0 1px 3px rgb(0 0 0 / 0.12);

  --md-sys-motion-short: 120ms cubic-bezier(0.2, 0, 0, 1);
  --md-sys-motion-medium: 220ms cubic-bezier(0.2, 0, 0, 1);

  /* Density. The app is data-dense: M3's default 56px controls waste a third
     of a laptop viewport, so every control is one step down from spec. */
  --md-density-control: 40px;
  --md-density-button: 38px;
  --md-density-row: 44px;

  color-scheme: light;
}

/* Bind the active scheme. Everything downstream reads only --md-sys-color-*. */
:root,
:root[data-theme='light'] {
  --md-sys-color-primary: var(--md-light-primary);
  --md-sys-color-on-primary: var(--md-light-on-primary);
  --md-sys-color-primary-container: var(--md-light-primary-container);
  --md-sys-color-on-primary-container: var(--md-light-on-primary-container);
  --md-sys-color-secondary: var(--md-light-secondary);
  --md-sys-color-on-secondary: var(--md-light-on-secondary);
  --md-sys-color-secondary-container: var(--md-light-secondary-container);
  --md-sys-color-on-secondary-container: var(--md-light-on-secondary-container);
  --md-sys-color-tertiary: var(--md-light-tertiary);
  --md-sys-color-on-tertiary: var(--md-light-on-tertiary);
  --md-sys-color-tertiary-container: var(--md-light-tertiary-container);
  --md-sys-color-on-tertiary-container: var(--md-light-on-tertiary-container);
  --md-sys-color-error: var(--md-light-error);
  --md-sys-color-on-error: var(--md-light-on-error);
  --md-sys-color-error-container: var(--md-light-error-container);
  --md-sys-color-on-error-container: var(--md-light-on-error-container);
  --md-sys-color-surface: var(--md-light-surface);
  --md-sys-color-on-surface: var(--md-light-on-surface);
  --md-sys-color-surface-variant: var(--md-light-surface-variant);
  --md-sys-color-on-surface-variant: var(--md-light-on-surface-variant);
  --md-sys-color-surface-dim: var(--md-light-surface-dim);
  --md-sys-color-surface-bright: var(--md-light-surface-bright);
  --md-sys-color-surface-container-lowest: var(--md-light-surface-container-lowest);
  --md-sys-color-surface-container-low: var(--md-light-surface-container-low);
  --md-sys-color-surface-container: var(--md-light-surface-container);
  --md-sys-color-surface-container-high: var(--md-light-surface-container-high);
  --md-sys-color-surface-container-highest: var(--md-light-surface-container-highest);
  --md-sys-color-outline: var(--md-light-outline);
  --md-sys-color-outline-variant: var(--md-light-outline-variant);
  --md-sys-color-inverse-surface: var(--md-light-inverse-surface);
  --md-sys-color-inverse-on-surface: var(--md-light-inverse-on-surface);
  --md-sys-color-inverse-primary: var(--md-light-inverse-primary);
  --md-sys-color-scrim: var(--md-light-scrim);

  color-scheme: light;
}

:root[data-theme='dark'] {
  --md-sys-color-primary: var(--md-dark-primary);
  --md-sys-color-on-primary: var(--md-dark-on-primary);
  --md-sys-color-primary-container: var(--md-dark-primary-container);
  --md-sys-color-on-primary-container: var(--md-dark-on-primary-container);
  --md-sys-color-secondary: var(--md-dark-secondary);
  --md-sys-color-on-secondary: var(--md-dark-on-secondary);
  --md-sys-color-secondary-container: var(--md-dark-secondary-container);
  --md-sys-color-on-secondary-container: var(--md-dark-on-secondary-container);
  --md-sys-color-tertiary: var(--md-dark-tertiary);
  --md-sys-color-on-tertiary: var(--md-dark-on-tertiary);
  --md-sys-color-tertiary-container: var(--md-dark-tertiary-container);
  --md-sys-color-on-tertiary-container: var(--md-dark-on-tertiary-container);
  --md-sys-color-error: var(--md-dark-error);
  --md-sys-color-on-error: var(--md-dark-on-error);
  --md-sys-color-error-container: var(--md-dark-error-container);
  --md-sys-color-on-error-container: var(--md-dark-on-error-container);
  --md-sys-color-surface: var(--md-dark-surface);
  --md-sys-color-on-surface: var(--md-dark-on-surface);
  --md-sys-color-surface-variant: var(--md-dark-surface-variant);
  --md-sys-color-on-surface-variant: var(--md-dark-on-surface-variant);
  --md-sys-color-surface-dim: var(--md-dark-surface-dim);
  --md-sys-color-surface-bright: var(--md-dark-surface-bright);
  --md-sys-color-surface-container-lowest: var(--md-dark-surface-container-lowest);
  --md-sys-color-surface-container-low: var(--md-dark-surface-container-low);
  --md-sys-color-surface-container: var(--md-dark-surface-container);
  --md-sys-color-surface-container-high: var(--md-dark-surface-container-high);
  --md-sys-color-surface-container-highest: var(--md-dark-surface-container-highest);
  --md-sys-color-outline: var(--md-dark-outline);
  --md-sys-color-outline-variant: var(--md-dark-outline-variant);
  --md-sys-color-inverse-surface: var(--md-dark-inverse-surface);
  --md-sys-color-inverse-on-surface: var(--md-dark-inverse-on-surface);
  --md-sys-color-inverse-primary: var(--md-dark-inverse-primary);
  --md-sys-color-scrim: var(--md-dark-scrim);

  color-scheme: dark;
}

/* == 02 · base ============================================================ */

* {
  box-sizing: border-box;
}

html,
body {
  min-height: 100%;
}

body.sbx-app {
  margin: 0;
  font-family: var(--md-sys-font-plain);
  font-size: var(--md-sys-typescale-body-size);
  line-height: 1.5;
  color: var(--md-sys-color-on-surface);
  background: var(--md-sys-color-surface);
  -webkit-font-smoothing: antialiased;
}

body.sbx-shell-page {
  overflow: hidden;
}

h1,
h2,
h3,
h4,
h5,
h6,
.card-title,
.modal-title {
  font-family: var(--md-sys-font-brand);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--md-sys-color-on-surface);
}

a {
  color: var(--md-sys-color-primary);
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

small,
.text-muted {
  color: var(--md-sys-color-on-surface-variant) !important;
}

hr,
.dropdown-divider {
  border-color: var(--md-sys-color-outline-variant);
  opacity: 1;
}

::selection {
  background: var(--md-sys-color-primary-container);
  color: var(--md-sys-color-on-primary-container);
}

/* One focus treatment for the whole app. M3 focus is a visible ring, never a
   removed outline. */
:focus-visible {
  outline: 3px solid color-mix(in srgb, var(--md-sys-color-primary) 60%, transparent);
  outline-offset: 2px;
}

/* The old theme painted animated blobs behind everything. M3 gets depth from
   tonal surfaces instead, so the layer is retired — kept as a no-op so any
   view still emitting the markup renders nothing. */
.sbx-atmosphere,
.sbx-blob {
  display: none !important;
}

/* Scrollbars, themed. Otherwise dark mode gets bright OS scrollbars. */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--md-sys-color-outline-variant) transparent;
}

*::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

*::-webkit-scrollbar-thumb {
  background: var(--md-sys-color-outline-variant);
  border: 3px solid transparent;
  border-radius: var(--md-sys-shape-full);
  background-clip: content-box;
}

*::-webkit-scrollbar-thumb:hover {
  background: var(--md-sys-color-outline);
  background-clip: content-box;
}

/* == 03 · shell =========================================================== */

.sbx-shell {
  --sbx-rail-col-size: 88px;
  --sbx-nav-col-size: 264px;
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: var(--sbx-rail-col-size) var(--sbx-nav-col-size) minmax(0, 1fr);
  height: 100vh;
  height: 100dvh;
  background: var(--md-sys-color-surface);
}

.sbx-shell > * {
  min-width: 0;
  min-height: 0;
}

/* The collapse/open state lives as a class on <body> (see soft-bento.js), and
   pre-paint on <html> so the columns don't visibly jump on every navigation. */
html.sbx-nav-collapsed-boot .sbx-shell,
body.sbx-nav-collapsed .sbx-shell {
  grid-template-columns: var(--sbx-rail-col-size) 0 minmax(0, 1fr);
}

html.sbx-nav-collapsed-boot .sbx-nav-pane,
body.sbx-nav-collapsed .sbx-nav-pane {
  opacity: 0;
  pointer-events: none;
  transform: translateX(-8px);
}

/* == 04 · navigation rail ================================================= */

.sbx-rail {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 12px 0;
  background: var(--md-sys-color-surface);
  overflow-y: auto;
  overflow-x: hidden;
}

.sbx-rail-logo {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  margin-bottom: 12px;
  border-radius: var(--md-sys-shape-md);
  background: var(--md-sys-color-primary-container);
  color: var(--md-sys-color-on-primary-container);
  overflow: hidden;
  flex: none;
}

.sbx-rail-logo:hover {
  text-decoration: none;
}

.sbx-rail-logo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.sbx-logo-fallback {
  font-family: var(--md-sys-font-brand);
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: 0.02em;
}

.sbx-rail-nav {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  width: 100%;
}

/* The M3 rail item: a pill indicator behind the icon, label underneath. The
   indicator is a pseudo-element so hover/active can cross-fade on it alone. */
.sbx-rail-link {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  width: 100%;
  padding: 6px 0 8px;
  color: var(--md-sys-color-on-surface-variant);
  text-decoration: none;
  transition: color var(--md-sys-motion-short);
}

.sbx-rail-link:hover {
  color: var(--md-sys-color-on-surface);
  text-decoration: none;
}

.sbx-rail-link i {
  position: relative;
  display: grid;
  place-items: center;
  width: 56px;
  height: 32px;
  font-size: 1.15rem;
  z-index: 1;
}

.sbx-rail-link i::before {
  position: relative;
  z-index: 1;
}

.sbx-rail-link i::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: var(--md-sys-shape-full);
  background: transparent;
  transition: background var(--md-sys-motion-medium);
}

.sbx-rail-link:hover i::after {
  background: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-hover) * 100%), transparent);
}

.sbx-rail-link.is-active {
  color: var(--md-sys-color-on-secondary-container);
}

.sbx-rail-link.is-active i::after {
  background: var(--md-sys-color-secondary-container);
}

.sbx-rail-link span {
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 600;
  letter-spacing: 0.02em;
  text-align: center;
}

.sbx-rail-link.is-active span {
  color: var(--md-sys-color-on-surface);
}

/* == 05 · nav pane ======================================================== */

.sbx-nav-pane {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 12px 12px 12px 0;
  overflow: hidden;
  transition: opacity var(--md-sys-motion-medium), transform var(--md-sys-motion-medium);
}

.sbx-pane-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 4px 8px 0;
}

.sbx-brand-link {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  color: inherit;
  text-decoration: none;
}

.sbx-brand-link:hover {
  text-decoration: none;
}

.sbx-brand-mark {
  flex: none;
  width: 10px;
  height: 10px;
  border-radius: var(--md-sys-shape-full);
  background: var(--md-sys-color-primary);
}

.sbx-brand-link span {
  min-width: 0;
}

.sbx-brand-link small {
  display: block;
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--md-sys-color-on-surface-variant) !important;
}

.sbx-brand-link strong {
  display: block;
  font-family: var(--md-sys-font-brand);
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--md-sys-color-on-surface);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Search field, M3 style: a full-round tonal container. */
.sbx-command-wrap {
  padding: 0 4px;
}

#sbx-command-input {
  width: 100%;
  height: var(--md-density-control);
  padding: 0 16px;
  border: 0;
  border-radius: var(--md-sys-shape-full);
  background: var(--md-sys-color-surface-container-high);
  color: var(--md-sys-color-on-surface);
  font-family: inherit;
  font-size: var(--md-sys-typescale-body-size);
}

#sbx-command-input::placeholder {
  color: var(--md-sys-color-on-surface-variant);
}

#sbx-command-input:focus {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 0;
}

.sbx-command-wrap small {
  display: block;
  margin: 6px 8px 0;
  font-size: var(--md-sys-typescale-label-small-size);
  color: var(--md-sys-color-on-surface-variant);
}

.sbx-command-wrap kbd {
  padding: 1px 5px;
  border-radius: var(--md-sys-shape-xs);
  background: var(--md-sys-color-surface-container-highest);
  color: var(--md-sys-color-on-surface-variant);
  font-family: ui-monospace, 'SFMono-Regular', monospace;
  font-size: 0.6875rem;
}

.sbx-nav-groups {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 0 4px 8px;
}

.sbx-group + .sbx-group {
  margin-top: 16px;
}

.sbx-group-head h2 {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 8px 12px;
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--md-sys-color-on-surface-variant);
}

.sbx-group-head h2 i {
  font-size: 0.875rem;
}

.sbx-group.is-search-hit .sbx-group-head h2 {
  color: var(--md-sys-color-primary);
}

.sbx-link-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* M3 navigation-drawer item: full-round, tonal when active. */
.sbx-link-list a {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 16px;
  border-radius: var(--md-sys-shape-full);
  color: var(--md-sys-color-on-surface-variant);
  text-decoration: none;
  transition: background var(--md-sys-motion-short), color var(--md-sys-motion-short);
}

.sbx-link-list a:hover {
  background: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-hover) * 100%), transparent);
  color: var(--md-sys-color-on-surface);
  text-decoration: none;
}

.sbx-link-list a.is-active {
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
}

.sbx-link-list a i {
  flex: none;
  font-size: 1.05rem;
}

.sbx-link-list a span {
  min-width: 0;
}

.sbx-link-list a strong {
  display: block;
  font-size: var(--md-sys-typescale-label-size);
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sbx-link-list a small {
  display: block;
  font-size: var(--md-sys-typescale-label-small-size);
  color: inherit !important;
  opacity: 0.75;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sbx-nav-noresult {
  margin: 16px 12px;
  font-size: var(--md-sys-typescale-body-small-size);
  color: var(--md-sys-color-on-surface-variant);
}

/* == 06 · top app bar + stage ============================================ */

/* The stage is the app's only vertical scroller. Its rounded container is the
   single biggest "this is Material" cue in the layout. */
.sbx-stage {
  display: flex;
  flex-direction: column;
  min-height: 0;
  margin: 8px 8px 8px 0;
  border-radius: var(--md-sys-shape-lg);
  background: var(--md-sys-color-surface-container-low);
  overflow: hidden;
}

.sbx-stage-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex: none;
  padding: 12px 20px;
  background: var(--md-sys-color-surface-container-low);
  border-bottom: 1px solid transparent;
  transition: border-color var(--md-sys-motion-short), background var(--md-sys-motion-short);
}

/* Only separate the bar from the content once the content actually scrolls
   under it — a permanent divider on a short page is just a stray line. */
.sbx-stage.has-scrolled .sbx-stage-header {
  border-bottom-color: var(--md-sys-color-outline-variant);
  background: var(--md-sys-color-surface-container);
}

.sbx-stage-title {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.sbx-overline {
  margin: 0;
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--md-sys-color-on-surface-variant);
}

.sbx-stage-title h1 {
  margin: 0;
  font-size: var(--md-sys-typescale-title-large-size);
  font-weight: 600;
  line-height: 1.25;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* M3 icon button: 40px target, circular state layer. */
.sbx-header-icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: var(--md-sys-shape-full);
  background: transparent;
  color: var(--md-sys-color-on-surface-variant);
  font-size: 1.1rem;
  cursor: pointer;
  transition: background var(--md-sys-motion-short), color var(--md-sys-motion-short);
}

.sbx-header-icon:hover {
  background: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-hover) * 100%), transparent);
  color: var(--md-sys-color-on-surface);
}

.sbx-stage-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
}

.sbx-header-actions-slot {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  justify-content: flex-end;
}

.sbx-account-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  height: var(--md-density-button);
  padding: 0 12px;
  border: 0;
  border-radius: var(--md-sys-shape-full);
  background: var(--md-sys-color-surface-container-high);
  color: var(--md-sys-color-on-surface);
  font-size: var(--md-sys-typescale-label-size);
  font-weight: 600;
  cursor: pointer;
  transition: background var(--md-sys-motion-short);
}

.sbx-account-btn:hover,
.sbx-account-btn:focus {
  background: var(--md-sys-color-surface-container-highest);
  color: var(--md-sys-color-on-surface);
}

.sbx-account-btn::after {
  display: none;
}

.sbx-account-btn i {
  font-size: 1.15rem;
  color: var(--md-sys-color-on-surface-variant);
}

.sbx-stage-content {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 20px;
  scroll-behavior: smooth;
}

/* == 07 · buttons ========================================================= */

/* Bootstrap's variants map onto M3's emphasis ladder:
     .btn-primary          -> filled      (the one main action)
     .btn-secondary/-light -> tonal       (secondary action)
     .btn-outline-*        -> outlined    (low emphasis)
     .btn-link             -> text        (lowest)
   .btn-success/.btn-danger keep their semantic weight but wear M3 shapes. */
.btn {
  --md-btn-state: transparent;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: var(--md-density-button);
  padding: 0 20px;
  border: 0;
  border-radius: var(--md-sys-shape-full);
  font-family: var(--md-sys-font-plain);
  font-size: var(--md-sys-typescale-label-size);
  font-weight: 600;
  letter-spacing: 0.01em;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  overflow: hidden;
  transition: background var(--md-sys-motion-short), box-shadow var(--md-sys-motion-short),
    border-color var(--md-sys-motion-short), color var(--md-sys-motion-short);
}

/* The state layer, as its own paint pass. Tinting the background directly
   would have to be re-derived for all ten variants; this is derived once. */
.btn::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--md-btn-state);
  pointer-events: none;
  transition: background var(--md-sys-motion-short);
}

.btn > * {
  position: relative;
  z-index: 1;
}

.btn:hover {
  --md-btn-state: color-mix(in srgb, currentColor calc(var(--md-sys-state-hover) * 100%), transparent);
}

.btn:active {
  --md-btn-state: color-mix(in srgb, currentColor calc(var(--md-sys-state-pressed) * 100%), transparent);
}

.btn:disabled,
.btn.disabled {
  --md-btn-state: transparent;
  background: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent);
  border-color: transparent;
  color: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent);
  box-shadow: none;
  cursor: not-allowed;
  opacity: 1;
}

.btn-sm {
  height: 32px;
  padding: 0 14px;
  font-size: var(--md-sys-typescale-body-small-size);
  gap: 6px;
}

/* M3 icon button: square footprint, circular shape. This has to be opt-in via a
   class — `:has(> i:only-child)` looks like it would work, but :only-child only
   counts elements, so it also matches <button><i></i> Esporta</button> and
   crushes every labelled button into a circle. */
.btn-icon {
  width: var(--md-density-button);
  padding: 0;
}

.btn-icon.btn-sm {
  width: 32px;
  padding: 0;
}

.btn-lg {
  height: 48px;
  padding: 0 26px;
  font-size: 1rem;
}

.btn i {
  font-size: 1em;
}

/* Filled */
.btn-primary {
  background: var(--md-sys-color-primary);
  color: var(--md-sys-color-on-primary);
}

.btn-primary:hover,
.btn-primary:focus,
.btn-primary:active {
  background: var(--md-sys-color-primary);
  color: var(--md-sys-color-on-primary);
  box-shadow: var(--md-sys-elevation-1);
}

/* Tonal */
.btn-secondary,
.btn-light {
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
}

.btn-secondary:hover,
.btn-secondary:focus,
.btn-secondary:active,
.btn-light:hover,
.btn-light:focus,
.btn-light:active {
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
}

/* Outlined */
.btn-outline-primary,
.btn-outline-secondary,
.btn-outline-dark {
  background: transparent;
  border: 1px solid var(--md-sys-color-outline);
  color: var(--md-sys-color-primary);
}

.btn-outline-secondary,
.btn-outline-dark {
  color: var(--md-sys-color-on-surface-variant);
}

.btn-outline-primary:hover,
.btn-outline-primary:focus,
.btn-outline-primary:active {
  background: transparent;
  border-color: var(--md-sys-color-primary);
  color: var(--md-sys-color-primary);
}

.btn-outline-secondary:hover,
.btn-outline-secondary:focus,
.btn-outline-secondary:active,
.btn-outline-dark:hover,
.btn-outline-dark:focus,
.btn-outline-dark:active {
  background: transparent;
  border-color: var(--md-sys-color-on-surface-variant);
  color: var(--md-sys-color-on-surface);
}

/* Semantic fills */
.btn-success {
  background: var(--md-sys-color-primary);
  color: var(--md-sys-color-on-primary);
}

.btn-success:hover,
.btn-success:focus,
.btn-success:active {
  background: var(--md-sys-color-primary);
  color: var(--md-sys-color-on-primary);
  box-shadow: var(--md-sys-elevation-1);
}

.btn-danger {
  background: var(--md-sys-color-error);
  color: var(--md-sys-color-on-error);
}

.btn-danger:hover,
.btn-danger:focus,
.btn-danger:active {
  background: var(--md-sys-color-error);
  color: var(--md-sys-color-on-error);
  box-shadow: var(--md-sys-elevation-1);
}

.btn-outline-danger {
  background: transparent;
  border: 1px solid color-mix(in srgb, var(--md-sys-color-error) 60%, transparent);
  color: var(--md-sys-color-error);
}

.btn-outline-danger:hover,
.btn-outline-danger:focus,
.btn-outline-danger:active {
  background: transparent;
  border-color: var(--md-sys-color-error);
  color: var(--md-sys-color-error);
}

.btn-warning,
.btn-info {
  background: var(--md-sys-color-tertiary-container);
  color: var(--md-sys-color-on-tertiary-container);
}

.btn-warning:hover,
.btn-info:hover {
  background: var(--md-sys-color-tertiary-container);
  color: var(--md-sys-color-on-tertiary-container);
}

/* Text */
.btn-link {
  background: transparent;
  color: var(--md-sys-color-primary);
  text-decoration: none;
  padding: 0 12px;
}

.btn-link:hover {
  color: var(--md-sys-color-primary);
  text-decoration: none;
}

.btn-group > .btn {
  border-radius: 0;
}

.btn-group > .btn:first-child {
  border-radius: var(--md-sys-shape-full) 0 0 var(--md-sys-shape-full);
}

.btn-group > .btn:last-child {
  border-radius: 0 var(--md-sys-shape-full) var(--md-sys-shape-full) 0;
}

.btn-group > .btn:only-child {
  border-radius: var(--md-sys-shape-full);
}

/* == 08 · forms =========================================================== */

.form-label {
  display: block;
  margin-bottom: 6px;
  font-size: var(--md-sys-typescale-body-small-size);
  font-weight: 600;
  color: var(--md-sys-color-on-surface-variant);
}

/* M3 outlined text field. */
.form-control,
.form-select {
  width: 100%;
  min-height: var(--md-density-control);
  padding: 8px 14px;
  border: 1px solid var(--md-sys-color-outline);
  border-radius: var(--md-sys-shape-sm);
  background: transparent;
  color: var(--md-sys-color-on-surface);
  font-family: inherit;
  font-size: var(--md-sys-typescale-body-size);
  line-height: 1.4;
  transition: border-color var(--md-sys-motion-short), box-shadow var(--md-sys-motion-short),
    background var(--md-sys-motion-short);
}

.form-control::placeholder {
  color: var(--md-sys-color-on-surface-variant);
  opacity: 0.7;
}

.form-control:hover,
.form-select:hover {
  border-color: var(--md-sys-color-on-surface);
}

/* Focus doubles the border rather than adding a glow — that's the M3 tell. */
.form-control:focus,
.form-select:focus {
  border-color: var(--md-sys-color-primary);
  box-shadow: inset 0 0 0 1px var(--md-sys-color-primary);
  background: transparent;
  color: var(--md-sys-color-on-surface);
  outline: none;
}

.form-control:disabled,
.form-select:disabled,
.form-control[readonly] {
  background: color-mix(in srgb, var(--md-sys-color-on-surface) 4%, transparent);
  border-color: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent);
  color: color-mix(in srgb, var(--md-sys-color-on-surface) 55%, transparent);
}

.form-control-sm,
.form-select-sm,
.btn-sm + .form-control {
  min-height: 32px;
  padding: 4px 10px;
  font-size: var(--md-sys-typescale-body-small-size);
}

.form-select {
  padding-right: 36px;
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%236d7a78' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 14px;
  appearance: none;
}

:root[data-theme='dark'] .form-select {
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23879492' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
}

.form-select option {
  background: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface);
}

textarea.form-control {
  min-height: 88px;
  line-height: 1.55;
}

.form-text {
  font-size: var(--md-sys-typescale-label-small-size);
  color: var(--md-sys-color-on-surface-variant);
}

.invalid-feedback,
.text-danger {
  color: var(--md-sys-color-error) !important;
}

.form-control.is-invalid,
.form-select.is-invalid {
  border-color: var(--md-sys-color-error);
}

/* Checkboxes and radios.
   Bootstrap indents .form-check by 1.5em and pulls the input into that gutter
   with a negative margin. Widening the input (18px vs Bootstrap's 1em) eats the
   gutter and the label ends up touching the box, so the indent is restated here
   against the real control width. */
.form-check {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: auto;
  margin-bottom: 0;
  padding-left: 0;
}

.form-check .form-check-input {
  flex: none;
  margin-left: 0;
  margin-top: 0;
}

.form-switch {
  padding-left: 0;
}

.form-check-input {
  width: 18px;
  height: 18px;
  margin-top: 0.15em;
  border: 2px solid var(--md-sys-color-outline);
  border-radius: var(--md-sys-shape-xs);
  background-color: transparent;
  transition: background var(--md-sys-motion-short), border-color var(--md-sys-motion-short);
  cursor: pointer;
}

.form-check-input[type='radio'] {
  border-radius: var(--md-sys-shape-full);
}

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

.form-check-input:focus {
  border-color: var(--md-sys-color-primary);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--md-sys-color-primary) 18%, transparent);
  outline: none;
}

.form-check-label {
  font-size: var(--md-sys-typescale-body-size);
  color: var(--md-sys-color-on-surface);
  cursor: pointer;
}

/* M3 switch */
.form-switch .form-check-input {
  width: 44px;
  height: 26px;
  border-radius: var(--md-sys-shape-full);
  background-color: var(--md-sys-color-surface-container-highest);
  border-color: var(--md-sys-color-outline);
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2.4' fill='%236d7a78'/%3e%3c/svg%3e");
  background-position: left 3px center;
}

.form-switch .form-check-input:checked {
  background-color: var(--md-sys-color-primary);
  border-color: var(--md-sys-color-primary);
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3.2' fill='%23ffffff'/%3e%3c/svg%3e");
  background-position: right 3px center;
}

.input-group-text {
  border: 1px solid var(--md-sys-color-outline);
  background: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface-variant);
  border-radius: var(--md-sys-shape-sm);
  font-size: var(--md-sys-typescale-body-small-size);
}

/* Toolbar: the filter row that opens most pages. */
.sbx-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
}

.sbx-field {
  display: flex;
  flex-direction: column;
  flex: 1 1 180px;
  min-width: 0;
}

.sbx-field label,
.sbx-field .form-label {
  margin-bottom: 6px;
}

.sbx-field-wide {
  flex: 2 1 280px;
}

.sbx-field-narrow {
  flex: 0 1 150px;
}

.sbx-toolbar-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
  margin-left: auto;
}

.sbx-check-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
}

.sbx-check-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* == 09 · surfaces, panels, bento ========================================= */

/* Cards are the workhorse container. M3 "filled card": tonal surface, soft
   corner, no shadow — depth comes from the tone step against the stage. */
.card {
  border: 0;
  border-radius: var(--md-sys-shape-md);
  background: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface);
  box-shadow: none;
}

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 16px 20px;
  border-bottom: 1px solid var(--md-sys-color-outline-variant);
  background: transparent;
  font-family: var(--md-sys-font-brand);
  font-size: var(--md-sys-typescale-title-size);
  font-weight: 600;
  color: var(--md-sys-color-on-surface);
  border-radius: var(--md-sys-shape-md) var(--md-sys-shape-md) 0 0;
}

.card-body {
  padding: 20px;
}

.card-footer {
  padding: 14px 20px;
  border-top: 1px solid var(--md-sys-color-outline-variant);
  background: transparent;
  border-radius: 0 0 var(--md-sys-shape-md) var(--md-sys-shape-md);
}

.card-title {
  font-size: var(--md-sys-typescale-title-size);
  margin-bottom: 4px;
}

/* Panel: the bento tile. Same tonal logic as a card, but it owns its own
   header row and can span the grid. */
.sbx-panel {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
  padding: 20px;
  border-radius: var(--md-sys-shape-md);
  background: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface);
}

.sbx-panel-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.sbx-panel-head h3 {
  margin: 0;
  font-size: var(--md-sys-typescale-title-size);
  font-weight: 600;
}

.sbx-panel-head small {
  font-size: var(--md-sys-typescale-label-small-size);
}

.sbx-dashboard {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* The bento grid.
   Twelve columns, dense auto-flow, and spans that collapse in two steps. The
   point of a bento is that tiles differ in weight — so the span utilities are
   the layout's actual vocabulary, and every page uses the same twelve.
   `grid-auto-rows: minmax(0, auto)` + `dense` lets a small tile backfill the
   hole a wide one leaves, which is what stops the ragged bottom edge. */
.sbx-bento-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  /* A fixed row height is what makes the bento a bento: `sbx-row-2` only means
     "twice as tall" if a row has a size. It also gives Chart.js (which runs with
     maintainAspectRatio:false) the definite parent height it needs, instead of
     the two of them negotiating a height that grows on every resize. */
  grid-auto-rows: minmax(200px, auto);
  grid-auto-flow: row dense;
  gap: 16px;
}

.sbx-bento-grid > .sbx-span-3 {
  grid-column: span 3;
}

.sbx-bento-grid > .sbx-span-4 {
  grid-column: span 4;
}

.sbx-bento-grid > .sbx-span-5 {
  grid-column: span 5;
}

.sbx-bento-grid > .sbx-span-6 {
  grid-column: span 6;
}

.sbx-bento-grid > .sbx-span-7 {
  grid-column: span 7;
}

.sbx-bento-grid > .sbx-span-8 {
  grid-column: span 8;
}

.sbx-bento-grid > .sbx-span-9 {
  grid-column: span 9;
}

.sbx-bento-grid > .sbx-span-12 {
  grid-column: span 12;
}

/* Tall tiles: a bento that only varies width still reads as rows of boxes. */
.sbx-bento-grid > .sbx-row-2 {
  grid-row: span 2;
}

/* KPI strip. Auto-fit means it never leaves a lone orphan tile on a wide
   screen, and it degrades to 2-up then 1-up on its own. */
.sbx-kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
}

/* The KPI tile leads with the number: label small above, value large, action
   link below. Reading order matches scanning order. */
.sbx-kpi-card {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 18px 20px;
  border-radius: var(--md-sys-shape-md);
  background: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface);
  transition: background var(--md-sys-motion-short);
}

.sbx-kpi-card small {
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--md-sys-color-on-surface-variant) !important;
}

.sbx-kpi-card strong {
  font-family: var(--md-sys-font-brand);
  font-size: 2rem;
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--md-sys-color-on-surface);
  font-variant-numeric: tabular-nums;
}

.sbx-kpi-card a {
  margin-top: 6px;
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 600;
  color: var(--md-sys-color-primary);
}

.sbx-kpi-card a:hover {
  text-decoration: underline;
}

/* Accent variant: for the one tile that should carry the eye first. */
.sbx-kpi-card.is-accent {
  background: var(--md-sys-color-primary-container);
  color: var(--md-sys-color-on-primary-container);
}

.sbx-kpi-card.is-accent small,
.sbx-kpi-card.is-accent strong,
.sbx-kpi-card.is-accent a {
  color: var(--md-sys-color-on-primary-container) !important;
}

.sbx-total {
  margin: 0;
  font-family: var(--md-sys-font-brand);
  font-size: 1.75rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

/* Inside a bento tile the grid row sets the height, so the chart just fills what
   is left. min-height:0 is load-bearing: without it the flex item refuses to
   shrink below its content and the tile grows past its row. */
.sbx-chart-wrap {
  position: relative;
  flex: 1;
  min-height: 0;
}

/* Standalone (outside the bento) there is no row to inherit from. */
.sbx-panel:not([class*='sbx-span-']) .sbx-chart-wrap,
.card .sbx-chart-wrap {
  min-height: 240px;
}

.sbx-chart-wrap canvas {
  width: 100% !important;
  height: 100% !important;
}

.sbx-chart-state {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: var(--md-sys-typescale-body-small-size);
  color: var(--md-sys-color-on-surface-variant);
  pointer-events: none;
}

/* Module/quick-link cards: the hub pages. */
.sbx-hub {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.sbx-module-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 16px;
}

.sbx-module-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 18px 20px;
  border-radius: var(--md-sys-shape-md);
  background: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface);
  text-decoration: none;
  transition: background var(--md-sys-motion-short);
}

.sbx-module-card:hover {
  background: var(--md-sys-color-surface-container-high);
  text-decoration: none;
}

.sbx-module-card i {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  margin-bottom: 4px;
  border-radius: var(--md-sys-shape-md);
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
  font-size: 1.15rem;
}

/* The hub views title these with an <h3>, so it has to be sized here — the
   browser default (1.17em, bolder) reads as a page heading, not a card label. */
.sbx-module-card strong,
.sbx-module-card h3 {
  margin: 0;
  font-family: var(--md-sys-font-brand);
  font-size: var(--md-sys-typescale-title-size);
  font-weight: 600;
  line-height: 1.3;
}

.sbx-module-card small,
.sbx-module-card p {
  margin: 0;
  font-size: var(--md-sys-typescale-body-small-size);
  line-height: 1.45;
  color: var(--md-sys-color-on-surface-variant) !important;
}

.sbx-quick-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* A two-line list item: label over hint. These are stacked, not opposed — with
   space-between the hint gets flung to the far edge and reads as a separate
   column. */
.sbx-quick-list a {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
  padding: 9px 14px;
  border-radius: var(--md-sys-shape-sm);
  color: var(--md-sys-color-on-surface);
  text-decoration: none;
  transition: background var(--md-sys-motion-short);
}

.sbx-quick-list a:hover {
  background: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-hover) * 100%), transparent);
  text-decoration: none;
}

.sbx-quick-list strong {
  display: block;
  font-size: var(--md-sys-typescale-label-size);
  font-weight: 600;
}

.sbx-quick-list small {
  display: block;
  font-size: var(--md-sys-typescale-label-small-size);
}

.sbx-split {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 16px;
}

.sbx-state-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.sbx-kicker {
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--md-sys-color-primary);
}

/* == 10 · tables ========================================================== */

/* Horizontal scroll is contained here, never on the page. The gradient hints
   (has-scroll-left/right) are set by sbx-ui.js. */
.sbx-table-wrap,
.table-responsive {
  position: relative;
  overflow-x: auto;
  border-radius: var(--md-sys-shape-sm);
}

/* soft-bento.js flags which edge still hides content. An inset shadow on the
   scroll container stays pinned to that edge while the table slides under it —
   which a positioned pseudo-element inside the scroller would not. */
.sbx-table-wrap.has-scroll-right,
.table-responsive.has-scroll-right {
  box-shadow: inset -14px 0 10px -10px color-mix(in srgb, var(--md-sys-color-on-surface) 30%, transparent);
}

.sbx-table-wrap.has-scroll-left,
.table-responsive.has-scroll-left {
  box-shadow: inset 14px 0 10px -10px color-mix(in srgb, var(--md-sys-color-on-surface) 30%, transparent);
}

.sbx-table-wrap.has-scroll-left.has-scroll-right,
.table-responsive.has-scroll-left.has-scroll-right {
  box-shadow: inset 14px 0 10px -10px color-mix(in srgb, var(--md-sys-color-on-surface) 30%, transparent),
    inset -14px 0 10px -10px color-mix(in srgb, var(--md-sys-color-on-surface) 30%, transparent);
}

.table {
  width: 100%;
  margin: 0;
  border-collapse: separate;
  border-spacing: 0;
  color: var(--md-sys-color-on-surface);
  font-size: var(--md-sys-typescale-body-size);
  --bs-table-bg: transparent;
  --bs-table-color: var(--md-sys-color-on-surface);
}

.table > thead > tr > th {
  position: sticky;
  top: 0;
  z-index: 2;
  padding: 12px 16px;
  border: 0;
  border-bottom: 1px solid var(--md-sys-color-outline-variant);
  background: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface-variant);
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  white-space: nowrap;
}

.table > tbody > tr > td {
  height: var(--md-density-row);
  padding: 10px 16px;
  border: 0;
  border-bottom: 1px solid var(--md-sys-color-outline-variant);
  background: transparent;
  color: var(--md-sys-color-on-surface);
  vertical-align: middle;
}

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

/* Row hover as a state layer, so it reads identically on every surface. */
.table > tbody > tr {
  transition: background var(--md-sys-motion-short);
}

.table > tbody > tr:hover > td {
  background: color-mix(in srgb, var(--md-sys-color-on-surface) 5%, transparent);
}

.table-sm > thead > tr > th,
.table-sm > tbody > tr > td {
  padding: 7px 12px;
  height: auto;
}

.table-warning,
.table-warning > td {
  background: var(--md-sys-color-tertiary-container) !important;
  color: var(--md-sys-color-on-tertiary-container) !important;
}

.table-danger,
.table-danger > td {
  background: var(--md-sys-color-error-container) !important;
  color: var(--md-sys-color-on-error-container) !important;
}

.sbx-cell-mono {
  font-family: ui-monospace, 'SFMono-Regular', 'Menlo', monospace;
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.sbx-cell-nowrap {
  white-space: nowrap;
}

.sbx-col-actions,
.col-actions {
  width: 1%;
  white-space: nowrap;
  text-align: right;
}

.sbx-col-actions .btn,
.col-actions .btn {
  padding: 0 10px;
}

/* Numeric columns read far faster right-aligned and tabular. */
.table .text-end,
td.text-end,
th.text-end {
  font-variant-numeric: tabular-nums;
}

/* == 11 · pager =========================================================== */

.sbx-pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 16px;
  font-size: var(--md-sys-typescale-body-small-size);
  color: var(--md-sys-color-on-surface-variant);
}

.pagination {
  display: flex;
  align-items: center;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.page-link {
  display: grid;
  place-items: center;
  min-width: 36px;
  height: 36px;
  padding: 0 10px;
  border: 0;
  border-radius: var(--md-sys-shape-full);
  background: transparent;
  color: var(--md-sys-color-on-surface-variant);
  font-size: var(--md-sys-typescale-label-size);
  font-weight: 600;
  transition: background var(--md-sys-motion-short), color var(--md-sys-motion-short);
}

.page-link:hover {
  background: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-hover) * 100%), transparent);
  color: var(--md-sys-color-on-surface);
  text-decoration: none;
}

.page-item.active .page-link {
  background: var(--md-sys-color-primary);
  color: var(--md-sys-color-on-primary);
}

.page-item.disabled .page-link {
  color: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent);
  background: transparent;
  pointer-events: none;
}

/* == 12 · empty & error states =========================================== */

/* An empty table should explain itself, not just go blank. */
.sbx-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 44px 24px;
  text-align: center;
  color: var(--md-sys-color-on-surface-variant);
  font-size: var(--md-sys-typescale-body-size);
}

.sbx-empty-state i {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  margin-bottom: 4px;
  border-radius: var(--md-sys-shape-full);
  background: var(--md-sys-color-surface-container-highest);
  color: var(--md-sys-color-on-surface-variant);
  font-size: 1.5rem;
}

.sbx-empty-state strong {
  font-family: var(--md-sys-font-brand);
  font-size: var(--md-sys-typescale-title-size);
  color: var(--md-sys-color-on-surface);
}

.sbx-empty-error {
  color: var(--md-sys-color-error);
}

.sbx-empty-error i {
  background: var(--md-sys-color-error-container);
  color: var(--md-sys-color-on-error-container);
}

/* sbx-ui.js injects loading/empty/error as a full-width row inside <tbody>.
   It's a message, not a record: no row hover, no divider. */
.sbx-state-row > td,
.sbx-state-row:hover > td {
  background: transparent !important;
  border-bottom: 0;
  padding: 0;
  height: auto;
}

/* The loading state is a spinner + label on one line, not a stacked column. */
.sbx-empty-state:has(.spinner-border) {
  flex-direction: row;
  justify-content: center;
  padding: 32px 24px;
}

.spinner-border {
  color: var(--md-sys-color-primary);
}

/* == 13 · chips & badges ================================================== */

/* Status pills. Bootstrap's colour utilities are remapped onto container
   roles so a `bg-success` badge stays legible in dark mode. */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 5px 10px;
  border-radius: var(--md-sys-shape-sm);
  background: var(--md-sys-color-surface-container-highest);
  color: var(--md-sys-color-on-surface-variant);
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  white-space: nowrap;
}

.badge.bg-primary,
.badge.text-bg-primary {
  background: var(--md-sys-color-primary-container) !important;
  color: var(--md-sys-color-on-primary-container) !important;
}

.badge.bg-success,
.badge.text-bg-success {
  background: var(--md-sys-color-primary-container) !important;
  color: var(--md-sys-color-on-primary-container) !important;
}

.badge.bg-secondary,
.badge.text-bg-secondary {
  background: var(--md-sys-color-secondary-container) !important;
  color: var(--md-sys-color-on-secondary-container) !important;
}

.badge.bg-info,
.badge.text-bg-info,
.badge.bg-warning,
.badge.text-bg-warning {
  background: var(--md-sys-color-tertiary-container) !important;
  color: var(--md-sys-color-on-tertiary-container) !important;
}

.badge.bg-danger,
.badge.text-bg-danger {
  background: var(--md-sys-color-error-container) !important;
  color: var(--md-sys-color-on-error-container) !important;
}

.badge.bg-light,
.badge.bg-dark {
  background: var(--md-sys-color-surface-container-highest) !important;
  color: var(--md-sys-color-on-surface-variant) !important;
}

/* == 14 · dialogs ========================================================= */

.modal-content {
  border: 0;
  border-radius: var(--md-sys-shape-xl);
  background: var(--md-sys-color-surface-container-high);
  color: var(--md-sys-color-on-surface);
  box-shadow: var(--md-sys-elevation-3);
}

.modal-header {
  align-items: center;
  padding: 20px 24px 12px;
  border-bottom: 0;
}

.modal-title {
  font-size: var(--md-sys-typescale-headline-size);
  font-weight: 600;
}

.modal-body {
  padding: 8px 24px 20px;
}

.modal-footer {
  gap: 8px;
  padding: 8px 24px 20px;
  border-top: 0;
}

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

.modal-dialog-scrollable > .modal-content > .modal-body {
  overflow-y: auto;
}

.modal-backdrop.show {
  background: var(--md-sys-color-scrim);
  opacity: 0.4;
}

.btn-close {
  border-radius: var(--md-sys-shape-full);
  opacity: 0.7;
}

.btn-close:hover {
  opacity: 1;
}

:root[data-theme='dark'] .btn-close {
  filter: invert(1) grayscale(1);
}

.modal-wide .modal-dialog,
.modal-95w {
  max-width: 95vw;
}

.modal-sm-plus {
  max-width: 460px;
}

/* == 15 · menus =========================================================== */

.dropdown-menu {
  padding: 8px;
  border: 0;
  border-radius: var(--md-sys-shape-md);
  background: var(--md-sys-color-surface-container-high);
  color: var(--md-sys-color-on-surface);
  box-shadow: var(--md-sys-elevation-2);
  min-width: 200px;
}

.dropdown-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border-radius: var(--md-sys-shape-sm);
  color: var(--md-sys-color-on-surface);
  font-size: var(--md-sys-typescale-body-size);
  font-weight: 500;
}

.dropdown-item:hover,
.dropdown-item:focus {
  background: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-hover) * 100%), transparent);
  color: var(--md-sys-color-on-surface);
}

.dropdown-item.active,
.dropdown-item:active {
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
}

.dropdown-header {
  padding: 8px 12px;
  color: var(--md-sys-color-on-surface);
  font-size: var(--md-sys-typescale-label-size);
  font-weight: 700;
}

/* == 16 · alerts & banners =============================================== */

/* Block, not flex: an alert is a paragraph that may happen to start with an
   icon. Forcing flex turns every inline <strong> into a flex item that shrinks
   and wraps mid-phrase. Views that genuinely want a row add Bootstrap's
   `d-flex` themselves. */
.alert {
  display: block;
  padding: 14px 18px;
  border: 0;
  border-radius: var(--md-sys-shape-md);
  background: var(--md-sys-color-surface-container-highest);
  color: var(--md-sys-color-on-surface);
  font-size: var(--md-sys-typescale-body-size);
}

.alert > i:first-child {
  margin-right: 8px;
}

.alert.d-flex > i:first-child {
  margin-right: 0;
}

.alert-info,
.alert-primary {
  background: var(--md-sys-color-tertiary-container);
  color: var(--md-sys-color-on-tertiary-container);
}

.alert-success {
  background: var(--md-sys-color-primary-container);
  color: var(--md-sys-color-on-primary-container);
}

.alert-warning {
  background: var(--md-sys-color-tertiary-container);
  color: var(--md-sys-color-on-tertiary-container);
}

.alert-danger {
  background: var(--md-sys-color-error-container);
  color: var(--md-sys-color-on-error-container);
}

/* == 17 · toasts (snackbars) ============================================= */

.sbx-toast-stack {
  position: fixed;
  left: 50%;
  bottom: 24px;
  z-index: 1090;
  display: flex;
  flex-direction: column;
  gap: 8px;
  transform: translateX(-50%);
  pointer-events: none;
}

/* M3 snackbar: inverse surface, so it stands clear of any page behind it. */
.sbx-toast {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 280px;
  max-width: min(560px, 92vw);
  padding: 14px 16px;
  border-radius: var(--md-sys-shape-xs);
  background: var(--md-sys-color-inverse-surface);
  color: var(--md-sys-color-inverse-on-surface);
  box-shadow: var(--md-sys-elevation-3);
  font-size: var(--md-sys-typescale-body-size);
  pointer-events: auto;
  animation: md-toast-in var(--md-sys-motion-medium) both;
}

.sbx-toast.is-leaving {
  animation: md-toast-out var(--md-sys-motion-short) both;
}

.sbx-toast-success {
  color: var(--md-sys-color-inverse-primary);
}

.sbx-toast-error {
  color: var(--md-sys-color-error);
}

.sbx-toast-close {
  margin-left: auto;
  border: 0;
  border-radius: var(--md-sys-shape-full);
  width: 28px;
  height: 28px;
  background: transparent;
  color: var(--md-sys-color-inverse-primary);
  cursor: pointer;
}

.sbx-toast-close:hover {
  background: color-mix(in srgb, var(--md-sys-color-inverse-on-surface) 12%, transparent);
}

@keyframes md-toast-in {
  from {
    opacity: 0;
    transform: translateY(12px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes md-toast-out {
  to {
    opacity: 0;
    transform: translateY(8px);
  }
}

/* == 18 · auth ============================================================ */

body.sbx-app.sbx-login-page {
  background: var(--md-sys-color-surface);
  overflow: auto;
}

/* Login ships without a brand panel, so the default is a single centred column.
   A two-column split only kicks in if a spotlight is actually present —
   otherwise the card would sit centred in the left half of an empty page. */
.sbx-auth-layout {
  display: grid;
  grid-template-columns: 1fr;
  min-height: 100vh;
  min-height: 100dvh;
}

.sbx-auth-layout:has(.sbx-auth-spotlight) {
  grid-template-columns: 1fr 1fr;
}

/* The marketing half. A tonal primary-container panel is the M3 way to say
   "brand" without a gradient. */
.sbx-auth-spotlight {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 20px;
  padding: 48px 56px;
  background: var(--md-sys-color-primary-container);
  color: var(--md-sys-color-on-primary-container);
}

.sbx-auth-spotlight h1,
.sbx-auth-spotlight h2 {
  color: var(--md-sys-color-on-primary-container);
  font-size: 2.25rem;
  line-height: 1.15;
  margin: 0;
}

.sbx-auth-bullets {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.sbx-auth-bullets div {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: var(--md-sys-typescale-body-size);
}

.sbx-auth-card {
  display: grid;
  place-items: center;
  padding: 32px 24px;
  background: var(--md-sys-color-surface);
}

.sbx-auth-card .card {
  width: 100%;
  max-width: 400px;
  background: var(--md-sys-color-surface-container-low);
}

.sbx-password-wrap {
  position: relative;
}

.sbx-password-wrap .form-control {
  padding-right: 84px;
}

/* The toggle's label is a word ("Mostra"/"Nascondi"), not an icon — so it's an
   M3 text button sized to its text, not a fixed circular icon button. */
.sbx-password-toggle {
  position: absolute;
  right: 5px;
  top: 50%;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  height: 30px;
  padding: 0 12px;
  border: 0;
  border-radius: var(--md-sys-shape-full);
  background: transparent;
  color: var(--md-sys-color-primary);
  font-family: inherit;
  font-size: var(--md-sys-typescale-label-small-size);
  font-weight: 700;
  cursor: pointer;
}

.sbx-password-toggle:hover {
  background: color-mix(in srgb, var(--md-sys-color-primary) calc(var(--md-sys-state-hover) * 100%), transparent);
}

/* == 19 · overlay, misc, responsive ====================================== */

.sbx-overlay {
  position: fixed;
  inset: 0;
  z-index: 40;
  background: var(--md-sys-color-scrim);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--md-sys-motion-medium), visibility var(--md-sys-motion-medium);
}

/* Only the drawer needs a scrim, and only while it's actually over content. */
body.sbx-nav-open .sbx-overlay {
  opacity: 0.4;
  visibility: visible;
}

@media (min-width: 993px) {
  .sbx-overlay {
    display: none;
  }
}

.sbx-mobile-only {
  display: none !important;
}

.bug-report-iframe {
  width: 100%;
  height: min(70vh, 720px);
  border: 0;
  border-radius: var(--md-sys-shape-md);
  background: var(--md-sys-color-surface-container-lowest);
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Tablet: the section pane is the first thing to go — the rail already names
   every section, so nothing becomes unreachable. */
@media (max-width: 1200px) {
  .sbx-shell {
    --sbx-nav-col-size: 232px;
  }

  .sbx-bento-grid > .sbx-span-3,
  .sbx-bento-grid > .sbx-span-4,
  .sbx-bento-grid > .sbx-span-5 {
    grid-column: span 6;
  }

  .sbx-bento-grid > .sbx-span-7,
  .sbx-bento-grid > .sbx-span-8,
  .sbx-bento-grid > .sbx-span-9 {
    grid-column: span 12;
  }
}

@media (max-width: 992px) {
  .sbx-shell {
    grid-template-columns: 1fr;
  }

  .sbx-rail {
    display: none;
  }

  /* Below the rail breakpoint the pane becomes a modal drawer. The desktop
     collapse preference must not leak in here — on mobile the only thing that
     opens or closes the drawer is body.sbx-nav-open. */
  .sbx-nav-pane,
  body.sbx-nav-collapsed .sbx-nav-pane,
  html.sbx-nav-collapsed-boot .sbx-nav-pane {
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 50;
    width: min(300px, 86vw);
    padding: 12px;
    background: var(--md-sys-color-surface-container-low);
    border-radius: 0 var(--md-sys-shape-lg) var(--md-sys-shape-lg) 0;
    transform: translateX(-100%);
    transition: transform var(--md-sys-motion-medium);
    opacity: 1;
    pointer-events: auto;
    box-shadow: var(--md-sys-elevation-3);
  }

  body.sbx-nav-open .sbx-nav-pane {
    transform: translateX(0);
  }

  body.sbx-nav-collapsed .sbx-shell,
  html.sbx-nav-collapsed-boot .sbx-shell {
    grid-template-columns: 1fr;
  }

  .sbx-stage {
    margin: 0;
    border-radius: 0;
  }

  .sbx-mobile-only {
    display: grid !important;
  }

  .sbx-nav-toggle-desktop {
    display: none !important;
  }

  .sbx-auth-layout {
    grid-template-columns: 1fr;
  }

  .sbx-auth-spotlight {
    display: none;
  }
}

@media (max-width: 768px) {
  .sbx-stage-header {
    padding: 10px 14px;
  }

  .sbx-stage-content {
    padding: 14px;
  }

  .sbx-bento-grid > [class*='sbx-span-'] {
    grid-column: span 12 !important;
  }

  .sbx-bento-grid > .sbx-row-2 {
    grid-row: span 1;
  }

  .sbx-kpi-grid {
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  }

  .sbx-kpi-card strong {
    font-size: 1.6rem;
  }

  .sbx-toolbar-actions {
    margin-left: 0;
    width: 100%;
  }

  .sbx-toolbar-actions .btn {
    flex: 1;
  }

  .card-body {
    padding: 16px;
  }

  .sbx-account-btn span {
    display: none;
  }
}
