/**
 * Recharge Desk — design system (tokens + layout + shared components)
 * Loaded after Bootstrap; overrides CSS variables for both themes.
 */

/* -------------------------------------------------------------------------- */
/* Global UI density (~80%) — not zoom: on body                             */
/* -------------------------------------------------------------------------- */
/*
 * Bootstrap 5 uses `rem` for typography, spacing, forms, buttons, modals,
 * tables, and utilities. Setting the root font-size to 80% of the browser
 * default compacts the whole UI proportionally, keeps media queries in `px`
 * (viewport) valid, and respects user font preferences (percentage scales with
 * the UA “medium” size). Fixed `px` radii below are converted to `rem` so
 * corners stay visually consistent with scaled type.
 */
html {
  font-size: 80%;
}

/* -------------------------------------------------------------------------- */
/* Theme-agnostic tokens (z-index, radii, transitions, fonts)                 */
/*                                                                            */
/* IMPORTANT: these must live at :root, NOT inside a theme selector. If they  */
/* only exist under [data-bs-theme="light"], then `var(--rd-z-sidebar)` is    */
/* undefined in dark mode and the whole `z-index` declaration becomes invalid */
/* -> the sidebar loses its 1040 stacking and renders under dashboard cards.  */
/* -------------------------------------------------------------------------- */
:root {
  --rd-font: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --rd-font-ar: "Cairo", "Inter", system-ui, sans-serif;

  --rd-radius-xs: 0.375rem;
  --rd-radius-sm: 0.625rem;
  --rd-radius-md: 0.875rem;
  --rd-radius-lg: 1.125rem;
  --rd-radius-xl: 1.375rem;

  --rd-z-sidebar: 1040;
  --rd-z-topbar: 1030;
  --rd-z-backdrop: 1025;
  --rd-z-sticky: 1020;

  --rd-transition-fast: 0.14s ease;
  --rd-transition: 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}

/* -------------------------------------------------------------------------- */
/* Tokens — light                                                             */
/* -------------------------------------------------------------------------- */
[data-bs-theme="light"] {
  color-scheme: light;

  --rd-shadow-xs: 0 1px 2px rgba(40, 10, 28, 0.05);
  --rd-shadow-sm: 0 2px 8px rgba(40, 10, 28, 0.07);
  --rd-shadow-md: 0 8px 24px rgba(40, 10, 28, 0.09);
  --rd-shadow-lg: 0 16px 48px rgba(40, 10, 28, 0.11);

  /* Brand neutrals carry a faint warm (rose/plum) undertone instead of
     the previous cool slate, so the whole shell reads as "this brand's
     light mode" rather than a generic SaaS gray. Lightness is kept
     within ~1% of the old values — only hue shifts, so existing
     contrast ratios are preserved. */
  --bs-body-bg: #ffffff;
  --bs-body-color: #19101a;
  --bs-secondary-bg: #ffffff;
  --bs-tertiary-bg: #f3edf1;
  --bs-border-color: rgba(70, 15, 45, 0.09);
  --bs-border-color-translucent: rgba(70, 15, 45, 0.11);
  --rd-card-border: rgba(70, 15, 45, 0.18);

  /* Brand accent — sampled from the Smile sim logo gradient (crimson
     #D23548 → deep violet #3F1D59) and tuned to clear WCAG AA (4.5:1)
     against both white and the body bg above. */
  --rd-accent: #c2255f;
  --rd-accent-hover: #9e1455;
  --rd-accent-muted: rgba(194, 37, 95, 0.12);
  --rd-accent-2: #6b2fa0;
  --rd-success: #059669;
  --rd-success-soft: rgba(5, 150, 105, 0.12);
  --rd-warning: #d97706;
  --rd-warning-soft: rgba(217, 119, 6, 0.14);
  --rd-danger: #dc2626;
  --rd-danger-soft: rgba(220, 38, 38, 0.1);
  --rd-info: #0284c7;
  --rd-info-soft: rgba(2, 132, 199, 0.12);

  --bs-primary: #c2255f;
  --bs-primary-rgb: 194, 37, 95;
  --bs-link-color: #c2255f;
  --bs-link-hover-color: #9e1455;
}

/* -------------------------------------------------------------------------- */
/* Tokens — dark (layered surfaces, not pure black)                           */
/* -------------------------------------------------------------------------- */
[data-bs-theme="dark"] {
  color-scheme: dark;

  --rd-shadow-xs: 0 1px 0 rgba(255, 255, 255, 0.04) inset;
  --rd-shadow-sm: 0 4px 16px rgba(0, 0, 0, 0.4);
  --rd-shadow-md: 0 12px 40px rgba(0, 0, 0, 0.5);
  --rd-shadow-lg: 0 20px 56px rgba(0, 0, 0, 0.6);

  /* Near-black with a whisper of plum instead of cool slate — mirrors
     the logo's black backdrop so dark mode feels like a continuation
     of the brand mark rather than a generic dark theme. */
  --bs-body-bg: #110c15;
  --bs-body-color: #ede7ec;
  --bs-secondary-bg: #1a131f;
  --bs-tertiary-bg: #221a29;
  --bs-border-color: rgba(238, 200, 220, 0.09);
  --bs-border-color-translucent: rgba(238, 200, 220, 0.11);

  /* Brand accent, brightened for AA contrast on the near-black bg
     above (same crimson→violet family as the light-mode tokens). */
  --rd-accent: #f2608a;
  --rd-accent-hover: #ff7aa2;
  --rd-accent-muted: rgba(242, 96, 138, 0.16);
  --rd-accent-2: #a06ae0;
  --rd-success: #34d399;
  --rd-success-soft: rgba(52, 211, 153, 0.14);
  --rd-warning: #fbbf24;
  --rd-warning-soft: rgba(251, 191, 36, 0.14);
  --rd-danger: #f87171;
  --rd-danger-soft: rgba(248, 113, 113, 0.12);
  --rd-info: #38bdf8;
  --rd-info-soft: rgba(56, 189, 248, 0.14);

  --bs-primary: #f2608a;
  --bs-primary-rgb: 242, 96, 138;
  --bs-link-color: #ff7aa2;
  --bs-link-hover-color: #ffb3c9;
}

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

/* Typography */
html[lang="ar"] body.rd-body,
html[lang="ar"] body.app-shell {
  font-family: var(--rd-font-ar);
}

html:not([lang="ar"]) body.rd-body,
html:not([lang="ar"]) body.app-shell {
  font-family: var(--rd-font);
}

body.rd-body,
body.app-shell {
  font-feature-settings: "kern" 1, "liga" 1;
  -webkit-font-smoothing: antialiased;
  letter-spacing: -0.01em;
}

.rd-heading-xl {
  font-size: clamp(1.35rem, 2vw, 1.65rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.2;
}

.rd-heading-lg {
  font-size: 1.125rem;
  font-weight: 600;
  letter-spacing: -0.015em;
}

.rd-text-muted {
  color: var(--bs-secondary-color) !important;
  font-size: 0.875rem;
}

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

.rd-label {
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--bs-secondary-color);
}

/* -------------------------------------------------------------------------- */
/* App layout — management                                                   */
/* -------------------------------------------------------------------------- */
.rd-app {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: auto 1fr;
  /* Own stacking context so the fixed sidebar/backdrop never get clipped or
     reordered by sibling stacking contexts created by the sticky topbar's
     backdrop-filter (Safari/iOS). */
  isolation: isolate;
}

@media (min-width: 992px) {
  .rd-app {
    grid-template-columns: minmax(14rem, 16.75rem) 1fr;
    grid-template-rows: 1fr;
  }
}

.rd-sidebar {
  position: fixed;
  /* Use physical properties — older Safari/iOS do not honor inset-block /
     inset-inline-* on `position: fixed` reliably, which left the sidebar
     un-anchored and effectively dumped it back into normal flow. */
  top: 0;
  bottom: 0;
  left: 0;
  right: auto;
  width: min(18rem, 88vw);
  z-index: var(--rd-z-sidebar);
  background: var(--bs-secondary-bg);
  border-right: 1px solid var(--bs-border-color);
  border-left: none;
  transform: translateX(-105%);
  transition: transform var(--rd-transition), box-shadow var(--rd-transition);
  padding: 1rem 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  box-shadow: var(--rd-shadow-md);
}

[dir="rtl"] .rd-sidebar {
  left: auto;
  right: 0;
  transform: translateX(105%);
  border-right: none;
  border-left: 1px solid var(--bs-border-color);
}

.rd-sidebar.is-open {
  transform: translateX(0);
}

@media (min-width: 992px) {
  .rd-sidebar {
    position: sticky;
    top: 0;
    bottom: auto;
    left: auto;
    right: auto;
    height: 100vh;
    transform: none !important;
    box-shadow: none;
    border-left: none;
    border-right: 1px solid var(--bs-border-color);
  }
  [dir="rtl"] .rd-sidebar {
    transform: none !important;
    border-right: none;
    border-left: 1px solid var(--bs-border-color);
  }
}

/* Mobile: make the sidebar surface clearly distinct from the page body in
   dark mode so it doesn't visually melt into the content underneath. */
@media (max-width: 991.98px) {
  [data-bs-theme="dark"] .rd-sidebar:not(:has(.rd-sidebar-nav--accordion)) {
    background: var(--bs-tertiary-bg);
  }
}

.rd-sidebar-backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--rd-z-backdrop);
  background: rgba(2, 6, 23, 0.45);
  backdrop-filter: blur(2px);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--rd-transition);
}

[data-bs-theme="dark"] .rd-sidebar-backdrop {
  /* The default 0.45 alpha is barely visible over an already-dark body,
     making the sidebar look like it's bleeding into the content. Bump it
     so the dim layer is unambiguous on mobile. */
  background: rgba(0, 0, 0, 0.65);
}

.rd-sidebar-backdrop.is-visible {
  opacity: 1;
  pointer-events: auto;
}

@media (min-width: 992px) {
  .rd-sidebar-backdrop {
    display: none !important;
  }
}

.rd-sidebar-brand {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.35rem 0.5rem 0.85rem;
  text-decoration: none;
  color: inherit;
  border-radius: var(--rd-radius-sm);
  transition: background var(--rd-transition-fast);
}

.rd-sidebar-brand:hover {
  background: var(--bs-tertiary-bg);
  color: inherit;
}

.rd-sidebar-brand-mark {
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--rd-radius-sm);
  background: linear-gradient(135deg, var(--rd-accent), var(--rd-accent-2));
  display: grid;
  place-items: center;
  color: #fff;
  font-weight: 800;
  font-size: 0.85rem;
  box-shadow: var(--rd-shadow-sm);
}

/* When the admin has uploaded a SiteBranding logo we replace the
   "R + text" stack with the wordmark itself, centered and capped to a
   sidebar-friendly height so a tall logo can't push the nav off-screen. */
.rd-sidebar-brand--logo {
  justify-content: center;
  padding: 0;
  margin: 0;
}

.rd-sidebar-brand-logo {
  display: block;
  width: 100%;
  max-width: 10rem;
  max-height: 3rem;
  height: auto;
  object-fit: contain;
}

/* Tighten the surrounding chrome when the brand is just a logo so the
   empty space above (sidebar padding) and below (gap + nav section header)
   doesn't visually dwarf the wordmark itself. */
.rd-sidebar:has(.rd-sidebar-brand--logo) {
  padding-top: 0.25rem;
  gap: 0.15rem;
}

.rd-sidebar-brand--logo + .rd-sidebar-nav .rd-nav-section:first-child {
  padding-top: 0.15rem;
}

.rd-sidebar-nav {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  flex: 1;
  overflow-y: auto;
  padding-block: 0.25rem;
}

.rd-nav-section {
  font-size: 0.65rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--bs-secondary-color);
  padding: 0.75rem 0.65rem 0.35rem;
}

.rd-nav-link {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.55rem 0.65rem;
  border-radius: var(--rd-radius-sm);
  color: var(--bs-body-color);
  text-decoration: none;
  font-size: 0.9rem;
  font-weight: 500;
  transition:
    background var(--rd-transition-fast),
    color var(--rd-transition-fast),
    transform var(--rd-transition-fast);
  border: 1px solid transparent;
}

.rd-nav-link:hover {
  background: var(--bs-tertiary-bg);
  color: inherit;
}

.rd-nav-link.is-active {
  background: var(--rd-accent-muted);
  color: var(--bs-primary);
  border-color: rgba(var(--bs-primary-rgb), 0.2);
  font-weight: 600;
}

.rd-nav-icon {
  flex: 0 0 auto;
  width: 1.25rem;
  height: 1.25rem;
  opacity: 0.85;
}

.rd-nav-link.is-active .rd-nav-icon {
  opacity: 1;
  color: var(--bs-primary);
}

.rd-nav-icon svg {
  width: 1.25rem;
  height: 1.25rem;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* -------------------------------------------------------------------------- */
/* Sidebar accordion nav — follows active theme, lilac highlights              */
/* -------------------------------------------------------------------------- */
/* Declare the palette on BOTH the sidebar (parent) and the nav itself so
   that rules targeting either side resolve the same variables. CSS custom
   properties inherit downward only — declaring them just on the child
   meant `.rd-sidebar:has(...) { background: var(--rd-nav-bw-bg) }`
   silently resolved to an invalid value (and the sidebar fell back to a
   transparent background).

   Active / hover / open-group accents reuse the global lilac (`--rd-accent`
   / `--bs-primary` — the same pill color used by the topbar's primary
   actions like "إدخال مبيعات"). Light mode keeps a white surface; the
   dark-mode bg is overridden below so it composites identically to the
   topbar (no visible seam). */
.rd-sidebar:has(.rd-sidebar-nav--accordion),
.rd-sidebar-nav--accordion {
  --rd-nav-bw-bg: #ffffff;
  --rd-nav-bw-surface: #f7f7f8;
  --rd-nav-bw-text: #111111;
  --rd-nav-bw-muted: #6b7280;
  --rd-nav-bw-border: rgba(17, 17, 17, 0.08);
  /* Match the pre-redesign sidebar: translucent lilac tint on hover/active,
     lilac text+icon on top of it (NOT a solid lilac pill with white text).
     Hover is a softer wash than the active state so the two read as
     distinct layers. */
  --rd-nav-bw-hover: color-mix(in srgb, var(--rd-accent-muted) 55%, transparent);
  --rd-nav-bw-active-bg: var(--rd-accent-muted);
  --rd-nav-bw-active-text: var(--bs-primary);
  --rd-nav-bw-active-border: rgba(var(--bs-primary-rgb), 0.2);
}

.rd-sidebar-nav--accordion {
  gap: 0.2rem;
}

/* Dark mode: bg matches the `.rd-topbar` formula
   (`color-mix(in srgb, var(--bs-secondary-bg) 88%, transparent)`) so the
   sidebar and topbar composite to the exact same color over `--bs-body-bg`
   and there is no visible seam where they meet. Text/border swap to the
   light-on-dark palette; the lilac active/hover accents inherit from the
   light-mode declaration above, and `--rd-accent` itself is already
   redefined by the global `[data-bs-theme="dark"]` block to `#f2608a`. */
[data-bs-theme="dark"] .rd-sidebar:has(.rd-sidebar-nav--accordion),
[data-bs-theme="dark"] .rd-sidebar-nav--accordion {
  --rd-nav-bw-bg: color-mix(in srgb, var(--bs-secondary-bg) 88%, transparent);
  --rd-nav-bw-surface: #141a22;
  --rd-nav-bw-text: #e8eaef;
  --rd-nav-bw-muted: #9ca3af;
  --rd-nav-bw-border: rgba(255, 255, 255, 0.08);
}

.rd-sidebar-nav--accordion .rd-nav-group {
  display: flex;
  flex-direction: column;
}

.rd-sidebar-nav--accordion .rd-nav-group + .rd-nav-group {
  margin-top: 0.1rem;
}

.rd-sidebar-nav--accordion .rd-nav-group-toggle {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  width: 100%;
  padding: 0.62rem 0.75rem;
  border: none;
  border-radius: 0.7rem;
  background: transparent;
  color: var(--rd-nav-bw-text);
  font-family: inherit;
  font-size: 0.92rem;
  font-weight: 600;
  text-align: start;
  cursor: pointer;
  transition:
    background var(--rd-transition-fast),
    color var(--rd-transition-fast);
}

.rd-sidebar-nav--accordion .rd-nav-group-toggle:hover {
  background: var(--rd-nav-bw-hover);
}

.rd-sidebar-nav--accordion .rd-nav-group-chevron {
  flex: 0 0 auto;
  width: 1rem;
  height: 1rem;
  display: grid;
  place-items: center;
  color: var(--rd-nav-bw-muted);
  transition: transform var(--rd-transition-fast);
}

.rd-sidebar-nav--accordion .rd-nav-group-chevron svg {
  width: 0.9rem;
  height: 0.9rem;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

[dir="rtl"] .rd-sidebar-nav--accordion .rd-nav-group-chevron svg {
  transform: scaleX(-1);
}

.rd-sidebar-nav--accordion .rd-nav-group.is-open .rd-nav-group-chevron {
  transform: rotate(90deg);
  color: var(--rd-accent);
}

[dir="rtl"] .rd-sidebar-nav--accordion .rd-nav-group.is-open .rd-nav-group-chevron {
  transform: rotate(-90deg);
}

/* When a section is expanded, tint the header (label + icon) lilac so the
   currently-open group is visually anchored to the active page below it. */
.rd-sidebar-nav--accordion .rd-nav-group.is-open .rd-nav-group-toggle {
  color: var(--rd-accent);
}

.rd-sidebar-nav--accordion .rd-nav-group.is-open .rd-nav-group-icon {
  color: var(--rd-accent);
  opacity: 1;
}

.rd-sidebar-nav--accordion .rd-nav-group-icon {
  flex: 0 0 auto;
  width: 1.15rem;
  height: 1.15rem;
  color: var(--rd-nav-bw-text);
  opacity: 0.72;
}

.rd-sidebar-nav--accordion .rd-nav-group-icon svg {
  width: 1.15rem;
  height: 1.15rem;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.rd-sidebar-nav--accordion .rd-nav-group-label {
  flex: 1;
  min-width: 0;
  letter-spacing: 0.005em;
}

/* Markup order is icon → label → chevron, which puts the chevron at the
   end of the row in both LTR and RTL. No `order` overrides needed. */

.rd-sidebar-nav--accordion .rd-nav-group-panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--rd-transition);
}

.rd-sidebar-nav--accordion .rd-nav-group.is-open .rd-nav-group-panel {
  grid-template-rows: 1fr;
}

.rd-sidebar-nav--accordion .rd-nav-group-panel-inner {
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: 0.12rem;
  min-height: 0;
  /* No padding / border while collapsed — they would otherwise show
     through the `grid-template-rows: 0fr` collapse and look like a stray
     1px line under the group toggle. */
  padding-block: 0;
  padding-inline-start: 0.55rem;
  margin-inline-start: 0.85rem;
  border-inline-start: 0 solid var(--rd-nav-bw-border);
}

.rd-sidebar-nav--accordion .rd-nav-group.is-open .rd-nav-group-panel-inner {
  padding-block: 0.15rem;
  border-inline-start-width: 1px;
}

.rd-sidebar-nav--accordion .rd-nav-link {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.52rem 0.7rem;
  border-radius: 0.625rem;
  font-size: 0.84rem;
  font-weight: 500;
  color: var(--rd-nav-bw-muted);
  border-color: transparent;
}

.rd-sidebar-nav--accordion .rd-nav-link:hover {
  background: var(--rd-nav-bw-hover);
  color: var(--rd-nav-bw-text);
}

.rd-sidebar-nav--accordion .rd-nav-link.is-active {
  background: var(--rd-nav-bw-active-bg);
  color: var(--rd-nav-bw-active-text);
  border-color: var(--rd-nav-bw-active-border);
  font-weight: 600;
}

.rd-sidebar-nav--accordion .rd-nav-link.is-active .rd-nav-icon {
  color: inherit;
  opacity: 1;
}

.rd-sidebar-nav--accordion .rd-nav-icon {
  flex: 0 0 auto;
  width: 1.1rem;
  height: 1.1rem;
  opacity: 0.65;
}

.rd-sidebar-nav--accordion .rd-nav-icon svg {
  width: 1.1rem;
  height: 1.1rem;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.rd-sidebar-nav--accordion .rd-nav-link.is-active .rd-nav-icon svg {
  stroke-width: 2;
}

/* Pinned quick-access section: a flat list of links above the accordions.
   Reuses .rd-nav-link styling for visual consistency but is slightly more
   prominent than nested sub-links (a touch larger, no inset border/padding
   from the panel-inner gutter) and is separated from the accordions below
   by a hairline divider. */
.rd-sidebar-nav--accordion .rd-nav-pinned {
  display: flex;
  flex-direction: column;
  gap: 0.12rem;
  padding-bottom: 0.5rem;
  margin-bottom: 0.4rem;
  border-bottom: 1px solid var(--rd-nav-bw-border);
}

.rd-sidebar-nav--accordion .rd-nav-link--pinned {
  padding: 0.58rem 0.75rem;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--rd-nav-bw-text);
}

.rd-sidebar-nav--accordion .rd-nav-link--pinned .rd-nav-icon {
  width: 1.15rem;
  height: 1.15rem;
  opacity: 0.78;
}

.rd-sidebar-nav--accordion .rd-nav-link--pinned .rd-nav-icon svg {
  width: 1.15rem;
  height: 1.15rem;
}

/* Flat sidebar panel — flush against the top + screen edge, no rounding,
   no floating drop-shadow. Just a hairline separator between the sidebar
   and the main content. Surface follows the active theme via the B&W
   tokens declared above. */
.rd-sidebar:has(.rd-sidebar-nav--accordion) {
  background: var(--rd-nav-bw-bg) !important;
  color: var(--rd-nav-bw-text);
  border: 0;
  border-radius: 0;
  padding: 1rem 0.75rem;
  box-shadow: none;
}

.rd-sidebar:has(.rd-sidebar-nav--accordion) .rd-sidebar-brand {
  color: var(--rd-nav-bw-text);
  padding: 0.25rem 0.55rem 0.95rem;
}

.rd-sidebar:has(.rd-sidebar-nav--accordion) .rd-sidebar-brand:hover {
  background: var(--rd-nav-bw-hover);
  color: var(--rd-nav-bw-text);
}

@media (min-width: 992px) {
  .rd-sidebar:has(.rd-sidebar-nav--accordion) {
    top: 0;
    align-self: stretch;
    height: 100vh;
    margin: 0;
    margin-inline-start: 0;
    margin-inline-end: 0;
    border-radius: 0;
    /* Hairline separator between sidebar and main content. RTL flips it to
       the left edge so the sidebar still sits flush against the screen
       edge on its outer side. */
    border-inline-end: 1px solid var(--rd-nav-bw-border);
    box-shadow: none;
  }

  [dir="rtl"] .rd-sidebar:has(.rd-sidebar-nav--accordion) {
    margin-inline-start: 0;
    margin-inline-end: 0;
    border-inline-end: 1px solid var(--rd-nav-bw-border);
    border-inline-start: 0;
  }
}

@media (max-width: 991.98px) {
  .rd-sidebar:has(.rd-sidebar-nav--accordion) {
    border-radius: 0;
    box-shadow: var(--rd-shadow-lg);
  }
}

.rd-sidebar-brand--logo + .rd-sidebar-nav--accordion {
  padding-top: 0.15rem;
}

.rd-main {
  min-width: 0;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.rd-topbar {
  position: sticky;
  top: 0;
  z-index: var(--rd-z-topbar);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.65rem 1rem;
  background: color-mix(in srgb, var(--bs-secondary-bg) 88%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--bs-border-color);
}

@media (min-width: 992px) {
  .rd-topbar {
    padding-inline: 1.35rem;
  }
}

.rd-topbar-meta {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

/* Topbar search — collapses to an icon button matching the bell /
 * theme-toggle, expands into a floating panel that mirrors the
 * .rd-user-menu-panel / .rd-notif-panel aesthetic so all three
 * popovers in the topbar feel like the same component family. */
.rd-search {
  position: relative;
  display: inline-flex;
  align-items: center;
}

.rd-search-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 2.1rem;
  padding: 0;
  border: 0;
  border-radius: var(--rd-radius-sm);
  background: transparent;
  color: var(--bs-body-color);
  cursor: pointer;
  transition:
    background var(--rd-transition-fast),
    color var(--rd-transition-fast);
}

.rd-search-toggle:hover,
.rd-search-toggle:focus-visible {
  background: var(--bs-tertiary-bg);
  color: var(--bs-body-color);
  outline: none;
}

.rd-search[data-rd-search-open="true"] .rd-search-toggle {
  background: var(--bs-tertiary-bg);
  color: var(--rd-accent);
}

.rd-search-panel {
  position: absolute;
  top: calc(100% + 0.5rem);
  /* Anchor the panel to the start edge of the toggle so it always opens
   * INTO the viewport: in LTR that's the toggle's left edge (panel
   * extends right); in RTL the start edge is on the right (panel
   * extends left). With the previous `inset-inline-end: 0` the panel
   * opened OUTWARD on Arabic mobile and got clipped against the
   * viewport edge. */
  inset-inline-start: 0;
  z-index: 1080;
  width: min(16.5rem, calc(100vw - 1rem));
  background: var(--bs-body-bg);
  color: var(--bs-body-color);
  border: 1px solid var(--bs-border-color);
  border-radius: var(--rd-radius-md);
  box-shadow: var(--rd-shadow-lg, 0 12px 32px rgba(0, 0, 0, 0.18));
  padding: 0.35rem;
  display: block;
  animation: rd-user-menu-in 0.12s ease-out;
}

.rd-search-panel[hidden] { display: none !important; }

/* The input field is a plain row that visually behaves like one of
 * the menu items — neutral background, soft border, accent ring on
 * focus. Avoids the busy "form-control" look from before. */
.rd-search-field {
  position: relative;
  display: flex;
  align-items: center;
  background: var(--bs-secondary-bg);
  border: 1px solid var(--bs-border-color);
  border-radius: var(--rd-radius-sm);
  padding: 0.22rem 0.45rem;
  gap: 0.4rem;
  transition: border-color var(--rd-transition-fast), box-shadow var(--rd-transition-fast);
}

.rd-search-field:focus-within {
  border-color: var(--rd-accent);
  box-shadow: 0 0 0 0.2rem color-mix(in srgb, var(--rd-accent) 18%, transparent);
}

.rd-search-field-icon {
  display: inline-flex;
  color: var(--bs-secondary-color);
  flex: 0 0 auto;
}

.rd-search-field-icon svg {
  width: 14px;
  height: 14px;
}

.rd-search-input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  background: transparent;
  outline: none;
  padding: 0.05rem 0;
  font-size: 0.82rem;
  color: var(--bs-body-color);
}

.rd-search-input::placeholder {
  color: var(--bs-secondary-color);
  opacity: 0.85;
}

/* Strip the WebKit "x" the search input renders by default — we
 * already handle clearing implicitly via Esc / click-outside. */
.rd-search-input::-webkit-search-decoration,
.rd-search-input::-webkit-search-cancel-button,
.rd-search-input::-webkit-search-results-button,
.rd-search-input::-webkit-search-results-decoration {
  display: none;
}

.rd-search-kbd {
  flex: 0 0 auto;
  font-size: 0.65rem;
  font-family: inherit;
  font-weight: 600;
  color: var(--bs-secondary-color);
  background: var(--bs-body-bg);
  border: 1px solid var(--bs-border-color);
  border-radius: 0.3rem;
  padding: 0.03rem 0.3rem;
  line-height: 1;
}

.rd-search-results {
  margin-top: 0.3rem;
  max-height: min(50vh, 18rem);
  overflow-y: auto;
}

.rd-search-results[hidden] { display: none !important; }

.rd-search-group + .rd-search-group {
  border-top: 1px solid var(--bs-border-color);
  margin-top: 0.35rem;
  padding-top: 0.4rem;
}

.rd-search-group-label {
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--bs-secondary-color);
  padding: 0.4rem 0.6rem 0.25rem;
}

.rd-search-item {
  display: block;
  padding: 0.35rem 0.5rem;
  border-radius: var(--rd-radius-sm);
  color: var(--bs-body-color);
  text-decoration: none;
  cursor: pointer;
  transition: background var(--rd-transition-fast);
}

.rd-search-item:hover,
.rd-search-item[aria-selected="true"] {
  background: var(--bs-tertiary-bg);
  color: var(--bs-body-color);
  text-decoration: none;
}

.rd-search-item-label {
  font-weight: 600;
  font-size: 0.82rem;
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.rd-search-item-sublabel {
  font-size: 0.72rem;
  color: var(--bs-secondary-color);
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-top: 0.1rem;
}

.rd-search-empty,
.rd-search-hint {
  padding: 1.25rem 0.75rem;
  text-align: center;
  color: var(--bs-secondary-color);
  font-size: 0.85rem;
}

.rd-search-more {
  display: block;
  text-align: center;
  margin-top: 0.4rem;
  padding: 0.55rem;
  border-top: 1px solid var(--bs-border-color);
  color: var(--rd-accent);
  text-decoration: none;
  font-size: 0.85rem;
  font-weight: 600;
}

.rd-search-more:hover {
  background: var(--bs-tertiary-bg);
  text-decoration: none;
}

@media (max-width: 480px) {
  .rd-search-panel {
    inset-inline-start: 0;
    width: min(21rem, calc(100vw - 0.75rem));
  }
  .rd-search-input {
    font-size: 0.78rem;
  }
  .rd-search-item-label {
    font-size: 0.78rem;
  }
  .rd-search-kbd { display: none; }
}

.rd-menu-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--rd-radius-sm);
  border: 1px solid var(--bs-border-color);
  background: var(--bs-secondary-bg);
  color: inherit;
  transition: background var(--rd-transition-fast), border-color var(--rd-transition-fast);
}

.rd-menu-btn:hover {
  background: var(--bs-tertiary-bg);
}

@media (min-width: 992px) {
  .rd-menu-btn {
    display: none;
  }
}

.rd-content {
  flex: 1;
  padding: 1rem 1rem 2.5rem;
  max-width: 90rem;
  width: 100%;
  margin-inline: auto;
}

@media (min-width: 992px) {
  .rd-content {
    padding: 1.35rem 1.5rem 3rem;
  }
}

/* Page chrome */
.rd-page-header {
  margin-bottom: 1.35rem;
}

.rd-page-header h1,
.rd-page-header .rd-heading-xl {
  margin-bottom: 0.25rem;
}

/* Section tabs — settings */
.rd-section-tabs.nav-tabs {
  border-bottom: 1px solid var(--bs-border-color);
  gap: 0.15rem;
  flex-wrap: nowrap;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.rd-section-tabs .nav-link {
  border: none;
  border-bottom: 2px solid transparent;
  border-radius: var(--rd-radius-sm) var(--rd-radius-sm) 0 0;
  color: var(--bs-secondary-color);
  font-weight: 600;
  font-size: 0.875rem;
  padding: 0.55rem 0.9rem;
  white-space: nowrap;
  transition:
    color var(--rd-transition-fast),
    border-color var(--rd-transition-fast),
    background var(--rd-transition-fast);
}

.rd-section-tabs .nav-link:hover {
  color: var(--bs-body-color);
  border-bottom-color: color-mix(in srgb, var(--bs-primary) 35%, transparent);
  background: color-mix(in srgb, var(--bs-tertiary-bg) 65%, transparent);
}

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

/* Cards */
.rd-card {
  background: var(--bs-secondary-bg);
  border: 1px solid var(--rd-card-border, var(--bs-border-color));
  border-radius: var(--rd-radius-md);
  box-shadow: var(--rd-shadow-xs);
  transition: box-shadow var(--rd-transition), border-color var(--rd-transition-fast);
}

.rd-card:hover {
  box-shadow: var(--rd-shadow-sm);
}

.rd-card-body {
  padding: 1.1rem 1.2rem;
}

.rd-card-header {
  padding: 0.85rem 1.2rem;
  font-weight: 600;
  font-size: 0.9rem;
  border-bottom: 1px solid var(--bs-border-color);
  border-radius: var(--rd-radius-md) var(--rd-radius-md) 0 0;
  background: color-mix(in srgb, var(--bs-tertiary-bg) 55%, var(--bs-secondary-bg));
}

/* Stat KPI */
.rd-stat {
  position: relative;
  overflow: hidden;
}

.rd-stat::after {
  content: "";
  position: absolute;
  inset-inline-end: -20%;
  inset-block-start: -40%;
  width: 55%;
  height: 120%;
  background: radial-gradient(circle, var(--rd-accent-muted) 0%, transparent 70%);
  pointer-events: none;
  opacity: 0.9;
}

.rd-stat .rd-card-body {
  position: relative;
  z-index: 1;
}

.rd-stat-value {
  font-size: clamp(1.65rem, 3vw, 2.1rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.1;
}

.rd-stat-icon {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--rd-radius-sm);
  display: grid;
  place-items: center;
  flex-shrink: 0;
  background: var(--rd-accent-muted);
  color: var(--bs-primary);
  margin-bottom: 0.65rem;
}

.rd-stat-icon svg {
  width: 1.375rem;
  height: 1.375rem;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
}

/* Filter toolbar */
.rd-filter-bar .form-label {
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--bs-secondary-color);
  margin-bottom: 0.25rem;
}

.rd-filter-bar .form-control,
.rd-filter-bar .form-select {
  border-radius: var(--rd-radius-sm);
  font-size: 0.875rem;
}

/* Tables */
.rd-table-wrap {
  border-radius: var(--rd-radius-md);
  overflow: hidden;
  border: 1px solid var(--bs-border-color);
  background: var(--bs-secondary-bg);
}

.rd-table-wrap .table {
  margin-bottom: 0;
}

.rd-table-wrap thead th {
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--bs-secondary-color);
  background: var(--bs-tertiary-bg) !important;
  border-bottom: 1px solid var(--bs-border-color);
  white-space: nowrap;
}

.rd-table-wrap tbody td {
  vertical-align: middle;
  padding-block: 0.85rem;
  border-color: color-mix(in srgb, var(--bs-border-color) 70%, transparent);
}

.rd-table-wrap.table-responsive {
  border-radius: var(--rd-radius-md);
}

.rd-card > .table-responsive.rd-table-wrap {
  border: none;
  border-radius: 0;
  box-shadow: none;
  border-top: 1px solid var(--bs-border-color);
}

[data-bs-theme="light"] .rd-table-wrap .table-hover > tbody > tr:hover > * {
  --bs-table-hover-bg: rgba(194, 37, 95, 0.04);
}

[data-bs-theme="dark"] .rd-table-wrap .table-hover > tbody > tr:hover > * {
  --bs-table-hover-bg: rgba(255, 255, 255, 0.04);
}

/* Badges */
.rd-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.72rem;
  font-weight: 600;
  padding: 0.28rem 0.55rem;
  border-radius: 999px;
  letter-spacing: 0.02em;
}

.rd-badge--pending {
  background: var(--rd-warning-soft);
  color: var(--rd-warning);
}

[data-bs-theme="dark"] .rd-badge--pending {
  color: #fcd34d;
}

.rd-badge--paid {
  background: var(--rd-success-soft);
  color: var(--rd-success);
}

.rd-badge--cancelled {
  background: var(--rd-danger-soft);
  color: var(--rd-danger);
}

.rd-badge--neutral {
  background: var(--bs-tertiary-bg);
  color: var(--bs-secondary-color);
  border: 1px solid var(--bs-border-color);
}

/* Buttons */
.rd-btn-icon {
  width: 2.375rem;
  height: 2.375rem;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--rd-radius-sm);
}

.btn {
  border-radius: var(--rd-radius-sm);
  font-weight: 600;
  transition:
    background-color var(--rd-transition-fast),
    border-color var(--rd-transition-fast),
    color var(--rd-transition-fast),
    box-shadow var(--rd-transition-fast),
    transform 0.1s ease;
}

.btn:active:not(:disabled) {
  transform: translateY(1px);
}

.btn:focus-visible {
  box-shadow: 0 0 0 3px rgba(var(--bs-primary-rgb), 0.35);
}

.btn-primary {
  --bs-btn-bg: var(--rd-accent);
  --bs-btn-border-color: var(--rd-accent);
  --bs-btn-hover-bg: var(--rd-accent-hover);
  --bs-btn-hover-border-color: var(--rd-accent-hover);
}

/* Bootstrap's component CSS variables (--bs-btn-*, --bs-pagination-*,
 * --bs-dropdown-link-active-*, --bs-list-group-active-*,
 * --bs-nav-pills-link-active-bg, and the checked form-control colors)
 * are compiled to a literal `#0d6efd` in bootstrap.min.css rather than
 * pointing at the shared `--bs-primary` token — only `.btn-primary`
 * above got a manual re-point before this redesign, so every other
 * "primary" affordance (outline buttons, pagination, dropdowns,
 * checkboxes/switches, list-group active rows) kept rendering
 * Bootstrap's stock blue even after `--bs-primary` became the brand
 * rose. These re-point them to the live (theme-aware) brand tokens so
 * light/dark both stay on-brand everywhere, not just on solid
 * `.btn-primary` buttons. */
.btn-outline-primary {
  --bs-btn-color: var(--bs-primary);
  --bs-btn-border-color: var(--bs-primary);
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: var(--bs-primary);
  --bs-btn-hover-border-color: var(--bs-primary);
  --bs-btn-focus-shadow-rgb: var(--bs-primary-rgb);
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: var(--bs-primary);
  --bs-btn-active-border-color: var(--bs-primary);
  --bs-btn-disabled-color: var(--bs-primary);
  --bs-btn-disabled-border-color: var(--bs-primary);
}

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

.form-check-input:focus {
  box-shadow: 0 0 0 0.2rem rgba(var(--bs-primary-rgb), 0.25);
}

.page-link {
  --bs-pagination-active-bg: var(--bs-primary);
  --bs-pagination-active-border-color: var(--bs-primary);
}

.dropdown-item.active,
.dropdown-item:active {
  --bs-dropdown-link-active-bg: var(--bs-primary);
}

.list-group-item.active {
  --bs-list-group-active-bg: var(--bs-primary);
  --bs-list-group-active-border-color: var(--bs-primary);
}

.nav-pills {
  --bs-nav-pills-link-active-bg: var(--bs-primary);
}

.btn-outline-secondary {
  border-color: var(--bs-border-color);
}

/* Forms */
.form-control,
.form-select {
  border-radius: var(--rd-radius-sm);
  transition:
    border-color var(--rd-transition-fast),
    box-shadow var(--rd-transition-fast);
}

.form-control:focus,
.form-select:focus {
  border-color: rgba(var(--bs-primary-rgb), 0.55);
  box-shadow: 0 0 0 3px rgba(var(--bs-primary-rgb), 0.18);
}

/* Alerts / messages */
.rd-alert-stack .alert {
  border: none;
  border-radius: var(--rd-radius-sm);
  box-shadow: var(--rd-shadow-sm);
  animation: rd-fade-in 0.25s ease;
}

@keyframes rd-fade-in {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Theme toggle — shell variant (legacy paired buttons, kept so any
 * older surfaces that haven't been migrated still render sensibly). */
.rd-theme-toggle .btn {
  border-radius: var(--rd-radius-xs);
  font-weight: 600;
  font-size: 0.75rem;
  padding: 0.35rem 0.65rem;
}

.rd-theme-toggle .btn.active {
  background: var(--bs-primary);
  border-color: var(--bs-primary);
  color: #fff;
}

/* New single-icon theme toggle. Visually matches .rd-search-toggle and
 * .rd-notif-trigger so the topbar reads as one consistent row of
 * round icon buttons. The two SVGs (sun/moon) are both rendered into
 * the DOM and CSS swaps which one is visible based on the current
 * <html data-bs-theme>; clicking flips the theme via theme.js. */
.rd-theme-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 2.1rem;
  padding: 0;
  border: 0;
  border-radius: var(--rd-radius-sm);
  background: transparent;
  color: var(--bs-body-color);
  cursor: pointer;
  transition:
    background var(--rd-transition-fast),
    color var(--rd-transition-fast);
}

.rd-theme-btn:hover,
.rd-theme-btn:focus-visible {
  background: var(--bs-tertiary-bg);
  color: var(--bs-body-color);
  outline: none;
}

.rd-theme-icon { display: none; }

[data-bs-theme="light"] .rd-theme-icon-moon,
[data-bs-theme="dark"]  .rd-theme-icon-sun {
  display: block;
}

/* Employee shell */
.rd-employee-app {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--bs-body-bg);
}

.rd-employee-topbar {
  position: sticky;
  top: 0;
  z-index: var(--rd-z-topbar);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.55rem 0.85rem;
  padding-top: max(0.55rem, env(safe-area-inset-top));
  background: color-mix(in srgb, var(--bs-secondary-bg) 92%, transparent);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--bs-border-color);
}

.rd-employee-main {
  flex: 1;
  width: 100%;
  max-width: 35rem;
  margin-inline: auto;
  padding: 0.85rem 0.85rem calc(1rem + env(safe-area-inset-bottom));
}

@media (min-width: 768px) {
  .rd-employee-main {
    max-width: 40rem;
    padding: 1.15rem 1rem calc(1.25rem + env(safe-area-inset-bottom));
  }
}

.rd-employee-title {
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.rd-lang-select {
  font-size: 0.8rem;
  border-radius: var(--rd-radius-sm);
  max-width: 8.5rem;
}

/* Employee sales entry — desktop layout
 * Mobile/tablet: no-op (the page stacks exactly as before: form, then
 * recent entries, inside the standard .rd-employee-main column).
 * Desktop (lg+): the shell widens and the form + "recent entries"
 * become a two-column grid so the page uses the available width
 * instead of floating a narrow mobile widget in the center of a big
 * screen. The <form> itself is untouched — only its wrapping
 * containers change layout, so none of the sale-entry JS/HTMX wiring
 * is affected. */
@media (min-width: 992px) {
  .rd-employee-main.rd-employee-main--wide {
    max-width: 68rem;
  }

  .rd-sale-layout {
    display: grid;
    grid-template-columns: minmax(24rem, 30rem) 1fr;
    align-items: start;
    gap: 1.75rem;
  }

  .rd-sale-layout__side {
    position: sticky;
    top: 1.15rem;
    max-height: calc(100vh - 2.3rem);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
}

/* Employee form surface */
.rd-sale-form {
  background: var(--bs-secondary-bg);
  border: 1px solid var(--bs-border-color);
  border-radius: var(--rd-radius-lg);
  box-shadow: var(--rd-shadow-md);
  padding: 1rem 1rem 1.1rem;
}

@media (min-width: 576px) {
  .rd-sale-form {
    padding: 1.25rem 1.35rem 1.35rem;
  }
}

.rd-field-group {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.rd-field-group + .rd-field-group {
  margin-top: 1rem;
}

.rd-field-label {
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--bs-secondary-color);
}

/* HTMX */
.htmx-request .htmx-indicator {
  opacity: 1 !important;
}

.htmx-indicator {
  opacity: 0;
  transition: opacity var(--rd-transition);
}

/* Legacy Bootstrap compatibility: old `.card` / `.app-card` should still
   render like the Recharge Desk card, but new templates must use `.rd-card`. */
.app-shell .card,
.app-card {
  border-radius: var(--rd-radius-md);
  border: 1px solid var(--bs-border-color);
  box-shadow: var(--rd-shadow-xs);
  background: var(--bs-secondary-bg);
  color: var(--bs-body-color);
}

.app-shell .card-header,
.app-card .card-header {
  padding: 0.85rem 1.2rem;
  font-weight: 600;
  font-size: 0.9rem;
  background: color-mix(in srgb, var(--bs-tertiary-bg) 55%, var(--bs-secondary-bg));
  border-bottom: 1px solid var(--bs-border-color);
  border-radius: var(--rd-radius-md) var(--rd-radius-md) 0 0;
}

.app-shell .card-body {
  padding: 1.1rem 1.2rem;
}

.app-shell .card-footer,
.rd-card-footer {
  padding: 0.75rem 1rem;
  background: color-mix(in srgb, var(--bs-tertiary-bg) 22%, var(--bs-secondary-bg));
  border-top: 1px solid var(--bs-border-color);
  border-radius: 0 0 var(--rd-radius-md) var(--rd-radius-md);
}

.app-shell .rd-card.overflow-hidden > .table-responsive:not(.rd-table-wrap),
.app-shell .card.overflow-hidden > .table-responsive:not(.rd-table-wrap) {
  border-top: 1px solid var(--bs-border-color);
}

.app-shell .rd-card > .table-responsive:not(.rd-table-wrap) .table,
.app-shell .card > .table-responsive:not(.rd-table-wrap) .table {
  margin-bottom: 0;
}

.app-shell .rd-card > .table-responsive:not(.rd-table-wrap) .table thead th,
.app-shell .card > .table-responsive:not(.rd-table-wrap) .table thead th {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--bs-secondary-color);
  background: color-mix(in srgb, var(--bs-secondary-bg) 92%, var(--bs-tertiary-bg));
  border-bottom: 1px solid var(--bs-border-color);
  white-space: nowrap;
}

/* Login alignment */
.login-shell {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}

[data-bs-theme="light"] .login-shell {
  background:
    radial-gradient(ellipse 56.25rem 31.25rem at 10% -10%, rgba(194, 37, 95, 0.12), transparent 55%),
    radial-gradient(ellipse 43.75rem 25rem at 100% 100%, rgba(107, 47, 160, 0.1), transparent 50%),
    var(--bs-body-bg);
}

[data-bs-theme="dark"] .login-shell {
  background:
    radial-gradient(ellipse 50rem 30rem at 15% 0%, rgba(242, 96, 138, 0.14), transparent 55%),
    radial-gradient(ellipse 37.5rem 25rem at 95% 90%, rgba(160, 106, 224, 0.08), transparent 45%),
    var(--bs-body-bg);
}

.login-card {
  max-width: 26.25rem;
  width: 100%;
  border: 1px solid var(--bs-border-color);
  border-radius: var(--rd-radius-lg);
  box-shadow: var(--rd-shadow-lg);
  background: var(--bs-secondary-bg);
}

.login-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 0.5rem;
}

.login-brand-img {
  width: 100%;
  max-width: 13rem;
  max-height: 6rem;
  height: auto;
  object-fit: contain;
}

@media (min-width: 576px) {
  .login-brand-img {
    max-width: 15rem;
    max-height: 7rem;
  }
}

/* Empty state */
.empty-state {
  border: 1px dashed var(--bs-border-color);
  border-radius: var(--rd-radius-md);
  padding: 2rem 1.25rem;
  text-align: center;
  color: var(--bs-secondary-color);
  background: color-mix(in srgb, var(--bs-tertiary-bg) 40%, var(--bs-secondary-bg));
}

/* Sky reconcile — compact run strip + waiting steps */
.sky-rec-run__form {
  display: grid;
  gap: 0.75rem;
  align-items: start;
  grid-template-columns: 1fr;
}

@media (min-width: 768px) {
  .sky-rec-run__form {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(7rem, 0.85fr) auto;
    gap: 0.75rem;
    align-items: start;
  }
}

.sky-rec-run__field,
.sky-rec-run__cta {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.sky-rec-run__label {
  display: block;
  margin-bottom: 0.3rem;
  font-size: 0.82rem;
  font-weight: 600;
  line-height: 1.2;
  color: var(--bs-body-color);
  height: 1.2em;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.sky-rec-run__label--spacer {
  visibility: hidden;
  user-select: none;
}

.sky-rec-run__form .form-control,
.sky-rec-run__btn {
  height: 2.4rem;
  box-sizing: border-box;
}

.sky-rec-run__btn {
  min-width: 9.25rem;
  padding-inline: 1.1rem;
  font-weight: 700;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}

.sky-rec-run__hint {
  margin-top: 0.65rem;
  font-size: 0.78rem;
  line-height: 1.35;
  color: var(--bs-secondary-color);
}

.sky-rec-waiting {
  border-style: dashed;
  background: color-mix(in srgb, var(--bs-tertiary-bg) 55%, var(--bs-secondary-bg));
}

.sky-rec-waiting__lead {
  color: var(--bs-secondary-color);
  max-width: 36rem;
}

.sky-rec-waiting__steps {
  display: grid;
  gap: 0.75rem;
}

@media (min-width: 768px) {
  .sky-rec-waiting__steps {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1rem;
  }
}

.sky-rec-waiting__step {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  padding: 0.85rem 0.95rem;
  border-radius: var(--rd-radius-md);
  background: var(--bs-secondary-bg);
  border: 1px solid var(--bs-border-color);
  box-shadow: var(--rd-shadow-xs);
}

.sky-rec-waiting__num {
  flex: 0 0 auto;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 999px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--rd-accent);
  background: var(--rd-accent-muted);
}

/* Sticky save — employee */
.sticky-save {
  position: sticky;
  bottom: 0;
  z-index: var(--rd-z-sticky);
  margin-top: 0.5rem;
  padding: 0.65rem 0 calc(0.65rem + env(safe-area-inset-bottom));
  background: linear-gradient(180deg, transparent 0%, var(--bs-body-bg) 35%, var(--bs-body-bg) 100%);
}

.sticky-save .employee-save-sale-btn {
  border-radius: var(--rd-radius-md);
  padding: 0.85rem 1rem;
  font-size: 1.02rem;
  font-weight: 700;
  box-shadow: var(--rd-shadow-sm);
}

.employee-save-sale-btn:active {
  transform: scale(0.99);
}

/* List group inside cards — management */
.rd-list-flush .list-group-item {
  border-color: color-mix(in srgb, var(--bs-border-color) 80%, transparent);
}

.rd-list-flush .list-group-item-action:hover {
  background: var(--bs-tertiary-bg);
}

/* -------------------------------------------------------------------------- */
/* KPI & numeric semantics                                                    */
/* -------------------------------------------------------------------------- */
.kpi-success {
  color: var(--rd-success);
}

.kpi-warning {
  color: var(--rd-warning);
}

.kpi-danger {
  color: var(--rd-danger);
}

.kpi-info {
  color: var(--rd-info);
}

.kpi-muted {
  color: var(--bs-secondary-color);
}

.kpi-expense {
  color: color-mix(in srgb, var(--rd-danger) 72%, var(--bs-body-color));
}

.rd-stat-icon--success {
  color: var(--rd-success);
  background: var(--rd-success-soft);
}

.rd-stat-icon--warning {
  color: var(--rd-warning);
  background: var(--rd-warning-soft);
}

.rd-stat-icon--danger {
  color: var(--rd-danger);
  background: var(--rd-danger-soft);
}

.rd-stat-icon--info {
  color: var(--rd-info);
  background: var(--rd-info-soft);
}

.rd-stat-icon--muted {
  color: var(--bs-secondary-color);
  background: color-mix(in srgb, var(--bs-tertiary-bg) 85%, var(--bs-secondary-bg));
}

/* -------------------------------------------------------------------------- */
/* Data tables — shell, density, zebra, sticky header                        */
/* -------------------------------------------------------------------------- */
.rd-data-shell {
  max-height: min(70vh, 42rem);
  overflow: auto;
  border-radius: 0;
  -webkit-overflow-scrolling: touch;
}

.rd-table-modern {
  --rd-table-row-pad-y: 0.72rem;
  --rd-table-row-pad-x: 0.85rem;
  border-collapse: separate;
  border-spacing: 0;
}

.rd-table-modern thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--bs-secondary-color);
  background: color-mix(in srgb, var(--bs-secondary-bg) 92%, var(--bs-tertiary-bg));
  border-bottom: 1px solid var(--bs-border-color);
  box-shadow: 0 1px 0 color-mix(in srgb, var(--bs-border-color) 55%, transparent);
  padding: 0.65rem var(--rd-table-row-pad-x);
  white-space: nowrap;
}

.rd-table-modern tbody td {
  padding: var(--rd-table-row-pad-y) var(--rd-table-row-pad-x);
  border-bottom: 1px solid color-mix(in srgb, var(--bs-border-color) 55%, transparent);
  vertical-align: middle;
}

.rd-table-modern tbody tr {
  transition: background-color var(--rd-transition-fast);
}

.rd-table-modern tbody tr:nth-child(even) {
  background: color-mix(in srgb, var(--bs-tertiary-bg) 35%, transparent);
}

.rd-table-modern tbody tr:hover {
  background: color-mix(in srgb, var(--rd-accent-muted) 55%, var(--bs-secondary-bg));
}

.rd-table-modern .tabular-nums {
  font-variant-numeric: tabular-nums;
}

tr.rd-row-pending {
  box-shadow: inset 0.1875rem 0 0 0 var(--rd-warning);
}

.rd-mobile-row-card.is-pending {
  box-shadow: inset 0.1875rem 0 0 0 var(--rd-warning);
}

/* Smooth fade-out for in-place htmx removals (Mark paid / Delete). */
.rd-pending-group.htmx-swapping {
  opacity: 0;
  transition: opacity 200ms ease-out;
}

/* Collapsible filter cards — uses native <details>, zero JS for the toggle. */
.rd-filter-card > summary {
  list-style: none;
  cursor: pointer;
  user-select: none;
  padding: 0.625rem 1rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  font-weight: 600;
  color: var(--bs-body-color);
  border-radius: var(--rd-radius, 0.75rem);
}
.rd-filter-card > summary::-webkit-details-marker {
  display: none;
}
.rd-filter-card > summary::marker {
  content: "";
}
.rd-filter-card > summary:hover {
  background: color-mix(in srgb, var(--bs-body-color) 4%, transparent);
}
.rd-filter-card > summary:focus-visible {
  outline: 2px solid var(--rd-primary, #2563eb);
  outline-offset: 2px;
}
.rd-filter-summary-left {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
}
.rd-filter-chevron {
  flex-shrink: 0;
  transition: transform 200ms ease;
  color: var(--bs-secondary-color);
}
.rd-filter-card[open] .rd-filter-chevron {
  transform: rotate(180deg);
}
.rd-filter-card[open] > summary {
  border-bottom: 1px solid var(--bs-border-color);
  border-radius: var(--rd-radius, 0.75rem) var(--rd-radius, 0.75rem) 0 0;
}
.rd-filter-active-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.5rem;
  padding: 0.125rem 0.5rem;
  font-size: 0.75rem;
  font-weight: 600;
  border-radius: 999px;
  background: var(--rd-primary, #2563eb);
  color: #fff;
  line-height: 1;
}

.rd-row-high-value {
  background: color-mix(in srgb, var(--rd-success-soft) 40%, transparent) !important;
}

.rd-sort-link {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px dashed color-mix(in srgb, var(--bs-secondary-color) 45%, transparent);
}

.rd-sort-link:hover {
  color: var(--bs-link-color);
  border-bottom-color: var(--bs-link-color);
}

.rd-sort-link.is-active {
  font-weight: 700;
  border-bottom-style: solid;
  border-bottom-color: var(--bs-link-color);
}

.rd-table-dual {
  margin-bottom: 0;
}

.rd-mobile-stack {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.rd-mobile-row-card {
  border: 1px solid var(--bs-border-color);
  border-radius: var(--rd-radius-md);
  padding: 0.75rem 0.85rem;
  background: var(--bs-secondary-bg);
  box-shadow: var(--rd-shadow-xs);
}

.rd-mobile-row-card .rd-mobile-k {
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--bs-secondary-color);
}

.rd-mobile-row-card .rd-mobile-v {
  font-weight: 600;
}

/* Equal-width primary/secondary actions on narrow cards (approve + reject). */
.rd-mobile-action-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.5rem;
  align-items: stretch;
}

.rd-mobile-action-pair > form {
  min-width: 0;
}

.rd-copy-ref {
  cursor: pointer;
}

/* Filter bar above tables */
.rd-filter-bar {
  border-bottom: 1px solid var(--bs-border-color);
}

[data-bs-theme="dark"] .rd-filter-bar {
  border-color: var(--bs-border-color);
}

/* Pagination strip */
.rd-pagination {
  background: color-mix(in srgb, var(--bs-tertiary-bg) 25%, var(--bs-secondary-bg));
}

.rd-pagination .page-link {
  border-radius: var(--rd-radius-xs);
}

/* -------------------------------------------------------------------------- */
/* DataGrid shell — SaaS-style data regions                                   */
/* -------------------------------------------------------------------------- */
.rd-datagrid {
  position: relative;
}

.rd-datagrid.is-loading {
  pointer-events: none;
  opacity: 0.62;
  transition: opacity var(--rd-transition);
}

.rd-datagrid-toolbar {
  background: color-mix(in srgb, var(--bs-tertiary-bg) 30%, var(--bs-secondary-bg));
}

.rd-datagrid-sort {
  color: inherit;
  text-decoration: none;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  border-radius: var(--rd-radius-xs);
  padding: 0.1rem 0.2rem;
  margin: -0.1rem -0.2rem;
}

.rd-datagrid-sort:hover {
  color: var(--bs-link-color);
  background: color-mix(in srgb, var(--rd-accent-muted) 40%, transparent);
}

.rd-datagrid-sort.is-active {
  color: var(--bs-link-color);
}

.rd-datagrid-sort.is-asc::after {
  content: "↑";
  font-size: 0.65rem;
  opacity: 0.85;
}

.rd-datagrid-sort.is-desc::after {
  content: "↓";
  font-size: 0.65rem;
  opacity: 0.85;
}

.rd-datagrid-pagination__bar {
  background: color-mix(in srgb, var(--bs-tertiary-bg) 22%, var(--bs-secondary-bg));
}

.rd-datagrid-pagination__pages .page-item.active .page-link {
  background: var(--bs-primary);
  border-color: var(--bs-primary);
  color: #fff;
}

.rd-datagrid-per-page__link {
  padding: 0.1rem 0.35rem;
  border-radius: var(--rd-radius-xs);
  text-decoration: none;
  color: var(--bs-link-color);
  font-weight: 600;
}

.rd-datagrid-per-page__link:hover {
  background: var(--bs-tertiary-bg);
}

.rd-datagrid-per-page__link.is-active {
  background: color-mix(in srgb, var(--bs-primary) 18%, var(--bs-secondary-bg));
  color: var(--bs-body-color);
}

.rd-actions-details summary {
  list-style: none;
  cursor: pointer;
}

.rd-actions-details summary::-webkit-details-marker {
  display: none;
}

.rd-actions-details__panel {
  min-width: 10rem;
  /* position set via JS to fixed — escapes overflow:auto on .rd-data-shell */
  box-shadow: var(--rd-shadow-md);
}

.rd-actions-details[open] summary {
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--bs-primary) 35%, transparent);
  border-radius: var(--rd-radius-xs);
}

.rd-toast {
  position: fixed;
  bottom: 1.25rem;
  inset-inline: 50%;
  transform: translateX(-50%) translateY(0.75rem);
  z-index: 1080;
  padding: 0.55rem 1rem;
  border-radius: var(--rd-radius-md);
  background: var(--bs-secondary-bg);
  border: 1px solid var(--bs-border-color);
  color: var(--bs-body-color);
  font-size: 0.85rem;
  font-weight: 600;
  opacity: 0;
  transition: opacity 0.2s ease, transform 0.2s ease;
  pointer-events: none;
}

html[dir="rtl"] .rd-toast {
  transform: translateX(50%) translateY(0.75rem);
}

.rd-toast.is-visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

html[dir="rtl"] .rd-toast.is-visible {
  transform: translateX(50%) translateY(0);
}

/* -------------------------------------------------------------------------- */
/* iOS auto-zoom prevention on input focus                                    */
/* -------------------------------------------------------------------------- */
/*
 * iOS Safari/WebKit zooms the viewport whenever a focused form control has a
 * computed font-size below 16px. Because the root font-size here is scaled to
 * 80% (~12.8px), every Bootstrap input falls under that threshold and triggers
 * the zoom on every focus, which never reverts on blur. Force form controls to
 * at least 16px on small screens so iOS leaves the viewport alone, while
 * keeping the compact desktop sizing untouched. `pinch-to-zoom` stays enabled.
 *
 * `!important` is used because Bootstrap's `.input-group-sm > .form-control`
 * and `.form-control-sm` selectors otherwise outrank a plain `.form-control`
 * rule by specificity / load order, leaving the inputs at ~11px.
 */
@media (max-width: 768px) {
  .form-control,
  .form-control-sm,
  .form-select,
  .form-select-sm,
  .input-group-sm > .form-control,
  .input-group-sm > .form-select,
  .input-group-sm > .input-group-text,
  .input-group > .form-control,
  .input-group > .form-select,
  input[type="text"],
  input[type="number"],
  input[type="tel"],
  input[type="email"],
  input[type="password"],
  input[type="search"],
  input[type="url"],
  input[type="date"],
  input[type="datetime-local"],
  input[type="time"],
  textarea,
  select {
    font-size: 16px !important;
  }
}

/* -------------------------------------------------------------------------- */
/* Avatar + topbar profile menu                                               */
/* -------------------------------------------------------------------------- */
/* The avatar component is shared between the topbar trigger, the dropdown
 * header, and the standalone settings page. Sizes follow a small/md/lg
 * scale so the same markup works in every context. */
.rd-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--rd-accent), var(--rd-accent-2, var(--rd-accent)));
  color: #fff;
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.02em;
  overflow: hidden;
  flex: 0 0 auto;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.15);
}

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

.rd-avatar-sm { width: 2rem;   height: 2rem;   font-size: 0.78rem; }
.rd-avatar-md { width: 2.6rem; height: 2.6rem; font-size: 0.95rem; }
.rd-avatar-lg { width: 4rem;   height: 4rem;   font-size: 1.4rem;  }

/* Trigger: a clean pill with avatar + name + caret. <details>/<summary>
 * gives us a native click toggle, keyboard support and aria-expanded for
 * free without pulling in Bootstrap's dropdown JS. */
.rd-user-menu {
  position: relative;
}

.rd-user-menu > summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.25rem 0.55rem 0.25rem 0.3rem;
  border-radius: 999px;
  border: 1px solid var(--bs-border-color);
  background: var(--bs-secondary-bg);
  color: inherit;
  transition: background var(--rd-transition-fast), border-color var(--rd-transition-fast);
  user-select: none;
}

.rd-user-menu > summary::-webkit-details-marker { display: none; }
.rd-user-menu > summary::marker { content: ""; }

.rd-user-menu > summary:hover {
  background: var(--bs-tertiary-bg);
}

.rd-user-menu[open] > summary {
  border-color: var(--rd-accent);
  background: var(--bs-tertiary-bg);
}

.rd-user-menu-name {
  font-size: 0.85rem;
  font-weight: 600;
  max-width: 9rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rd-user-menu-caret {
  opacity: 0.65;
  transition: transform var(--rd-transition-fast);
}

.rd-user-menu[open] .rd-user-menu-caret {
  transform: rotate(180deg);
}

/* Panel: drops out of the trigger flush to the inline-end edge so it
 * works in both LTR and RTL without a separate ruleset. The fixed
 * z-index keeps it above the sticky topbar and any sibling content. */
.rd-user-menu-panel {
  position: absolute;
  top: calc(100% + 0.5rem);
  inset-inline-end: 0;
  z-index: 1080;
  min-width: 16rem;
  max-width: calc(100vw - 1rem);
  background: var(--bs-body-bg);
  color: var(--bs-body-color);
  border: 1px solid var(--bs-border-color);
  border-radius: var(--rd-radius-md);
  box-shadow: var(--rd-shadow-lg, 0 12px 32px rgba(0, 0, 0, 0.18));
  padding: 0.5rem;
  animation: rd-user-menu-in 140ms ease-out;
}

@keyframes rd-user-menu-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}

.rd-user-menu-header {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.6rem;
  border-radius: var(--rd-radius-sm);
  background: var(--bs-secondary-bg);
  margin-bottom: 0.35rem;
}

.rd-user-menu-identity {
  min-width: 0;
}

.rd-user-menu-display {
  font-weight: 700;
  font-size: 0.95rem;
  line-height: 1.15;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rd-user-menu-handle {
  font-size: 0.75rem;
  color: var(--bs-secondary-color, var(--bs-body-color));
  opacity: 0.75;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rd-user-menu-divider {
  height: 1px;
  background: var(--bs-border-color);
  margin: 0.35rem 0.25rem;
}

/* Items are styled identically whether they are <a> or <button> so the
 * "Log out" form button visually matches the "Settings" link. */
.rd-user-menu-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  padding: 0.55rem 0.7rem;
  border-radius: var(--rd-radius-sm);
  background: transparent;
  border: 0;
  color: inherit;
  text-align: start;
  text-decoration: none;
  font-size: 0.9rem;
  font-weight: 500;
  cursor: pointer;
  transition: background var(--rd-transition-fast), color var(--rd-transition-fast);
}

.rd-user-menu-item:hover,
.rd-user-menu-item:focus-visible {
  background: var(--bs-tertiary-bg);
  color: var(--bs-body-color);
  text-decoration: none;
  outline: none;
}

.rd-user-menu-item svg {
  flex: 0 0 auto;
  opacity: 0.75;
}

.rd-user-menu-item--danger {
  color: var(--bs-danger, #dc3545);
}

.rd-user-menu-item--danger:hover,
.rd-user-menu-item--danger:focus-visible {
  background: color-mix(in srgb, var(--bs-danger, #dc3545) 12%, transparent);
  color: var(--bs-danger, #dc3545);
}

.rd-user-menu-item--danger svg {
  opacity: 0.9;
}

@media (max-width: 480px) {
  .rd-user-menu > summary { padding: 0.2rem; }
  .rd-user-menu-panel { min-width: 14rem; }
}

/* ---------------- Topbar notification bell ---------------- */
.rd-notif-trigger {
  position: relative;
  padding: 0.35rem 0.55rem !important;
  gap: 0 !important;
}

.rd-notif-trigger svg { display: block; transform-origin: 50% 4px; }

@keyframes rd-bell-ring {
  0%   { transform: rotate(0deg); }
  3%   { transform: rotate(-14deg); }
  6%   { transform: rotate(12deg); }
  9%   { transform: rotate(-10deg); }
  12%  { transform: rotate(8deg); }
  15%  { transform: rotate(-6deg); }
  18%  { transform: rotate(4deg); }
  21%  { transform: rotate(-2deg); }
  24%, 100% { transform: rotate(0deg); }
}

.rd-notif-trigger.is-active svg {
  animation: rd-bell-ring 2.4s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .rd-notif-trigger.is-active svg {
    animation: none;
  }
}

.rd-notif-badge {
  position: absolute;
  top: -3px;
  inset-inline-end: -3px;
  min-width: 1.05rem;
  height: 1.05rem;
  padding: 0 0.32rem;
  border-radius: 999px;
  background: var(--rd-danger, #dc3545);
  color: #fff;
  font-size: 0.65rem;
  font-weight: 700;
  line-height: 1.05rem;
  text-align: center;
  box-shadow: 0 0 0 2px var(--bs-secondary-bg);
}

.rd-notif-panel { min-width: 19rem; }

.rd-notif-header {
  display: block;
  padding: 0.35rem 0.6rem 0.5rem;
}

.rd-notif-item {
  display: flex;
  align-items: center;
  gap: 0.65rem;
}

.rd-notif-count {
  flex: 0 0 auto;
  min-width: 1.5rem;
  padding: 0 0.45rem;
  border-radius: 999px;
  background: var(--bs-tertiary-bg);
  color: var(--bs-secondary-color);
  font-size: 0.75rem;
  font-weight: 700;
  text-align: center;
  line-height: 1.4rem;
}

.rd-notif-count.is-active {
  background: color-mix(in srgb, var(--rd-danger, #dc3545) 14%, transparent);
  color: var(--rd-danger, #dc3545);
}

.rd-notif-empty {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.7rem 0.7rem;
  margin-top: 0.25rem;
  border-radius: var(--rd-radius-sm);
  background: var(--bs-tertiary-bg);
  color: var(--bs-secondary-color);
  font-size: 0.85rem;
}

.rd-notif-empty svg {
  color: var(--rd-success, #198754);
  opacity: 0.95;
}

/* Mini-charts on the management dashboard. The bar chart is built with
   inline DIVs so we avoid any external chart dependency and keep the
   strict CSP intact. Heights are set inline via {% widthratio %}. */
.rd-mini-chart {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-height: 220px;
  padding-top: 0.25rem;
}

/* Subtle horizontal grid lines (4 levels) sitting behind the bars. */
.rd-mini-chart-grid {
  position: absolute;
  inset: 0.25rem 0 1.75rem 0;
  display: grid;
  grid-template-rows: repeat(4, 1fr);
  pointer-events: none;
  z-index: 0;
}

.rd-mini-chart-grid > span {
  border-top: 1px dashed color-mix(in srgb, var(--bs-border-color) 60%, transparent);
  display: block;
}

.rd-mini-chart-bars {
  position: relative;
  display: flex;
  align-items: flex-end;
  gap: 6px;
  height: 180px;
  padding-block: 0.25rem;
  border-bottom: 1px solid var(--bs-border-color);
  z-index: 1;
}

.rd-mini-chart-bar-cell {
  position: relative;
  flex: 1 1 0;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  height: 100%;
  min-width: 0;
  cursor: default;
}

.rd-mini-chart-bar {
  width: 100%;
  max-width: 30px;
  min-height: 3px;
  background: linear-gradient(
    180deg,
    var(--bs-primary) 0%,
    color-mix(in srgb, var(--bs-primary) 45%, transparent) 100%
  );
  border-radius: 5px 5px 0 0;
  transition: filter 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}

.rd-mini-chart-bar-cell:hover .rd-mini-chart-bar,
.rd-mini-chart-bar-cell:focus-visible .rd-mini-chart-bar {
  filter: brightness(1.12) saturate(1.1);
  transform: translateY(-2px);
  box-shadow: 0 6px 14px color-mix(in srgb, var(--bs-primary) 32%, transparent);
}

.rd-mini-chart-bar-cell.is-today .rd-mini-chart-bar {
  background: linear-gradient(
    180deg,
    var(--rd-success, #16a34a) 0%,
    color-mix(in srgb, var(--rd-success, #16a34a) 45%, transparent) 100%
  );
}

.rd-mini-chart-bar-cell.is-empty .rd-mini-chart-bar {
  background: color-mix(in srgb, var(--bs-border-color) 70%, transparent);
}

/* Custom hover tooltip — replaces the native title attribute. */
.rd-mini-chart-tip {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%) translateY(4px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.15rem;
  padding: 0.4rem 0.6rem;
  border-radius: 0.5rem;
  background: var(--bs-body-color);
  color: var(--bs-body-bg);
  font-size: 0.72rem;
  line-height: 1.2;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s ease, transform 0.15s ease;
  z-index: 5;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.18);
}

.rd-mini-chart-tip::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 5px solid transparent;
  border-top-color: var(--bs-body-color);
}

.rd-mini-chart-tip__date {
  font-weight: 500;
  opacity: 0.75;
  font-size: 0.68rem;
}

.rd-mini-chart-tip__val {
  font-weight: 700;
  font-size: 0.85rem;
  letter-spacing: -0.01em;
}

.rd-mini-chart-bar-cell:hover .rd-mini-chart-tip,
.rd-mini-chart-bar-cell:focus-within .rd-mini-chart-tip {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* Edge cells: nudge the tooltip inward so it doesn't clip outside the chart. */
.rd-mini-chart-bars > .rd-mini-chart-bar-cell:first-child .rd-mini-chart-tip {
  left: 0;
  transform: translateY(4px);
}

.rd-mini-chart-bars > .rd-mini-chart-bar-cell:first-child:hover .rd-mini-chart-tip,
.rd-mini-chart-bars > .rd-mini-chart-bar-cell:first-child:focus-within .rd-mini-chart-tip {
  transform: translateY(0);
}

.rd-mini-chart-bars > .rd-mini-chart-bar-cell:first-child .rd-mini-chart-tip::after {
  left: 12px;
  transform: none;
}

.rd-mini-chart-bars > .rd-mini-chart-bar-cell:last-child .rd-mini-chart-tip {
  left: auto;
  right: 0;
  transform: translateY(4px);
}

.rd-mini-chart-bars > .rd-mini-chart-bar-cell:last-child:hover .rd-mini-chart-tip,
.rd-mini-chart-bars > .rd-mini-chart-bar-cell:last-child:focus-within .rd-mini-chart-tip {
  transform: translateY(0);
}

.rd-mini-chart-bars > .rd-mini-chart-bar-cell:last-child .rd-mini-chart-tip::after {
  left: auto;
  right: 12px;
  transform: none;
}

.rd-mini-chart-weekdays {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 6px;
  margin-top: 0.15rem;
  padding-bottom: 0.15rem;
}

.rd-mini-chart-wd {
  flex: 1 1 0;
  min-width: 0;
  text-align: center;
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--bs-secondary-color);
  line-height: 1;
}

.rd-mini-chart-header-text {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 0;
}

.rd-mini-chart-title {
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--bs-body-color);
  line-height: 1.25;
}

.rd-mini-chart-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.2rem 0.5rem;
  font-size: 0.78rem;
  color: var(--bs-secondary-color);
}

.rd-mini-chart-summary__lbl {
  font-weight: 500;
  margin-inline-end: 0.15rem;
}

.rd-mini-chart-summary__sep {
  opacity: 0.45;
  user-select: none;
}

.rd-mini-chart-summary__item .tabular-nums {
  font-weight: 600;
  color: var(--bs-body-color);
}

.rd-mini-chart-axis {
  display: flex;
  justify-content: space-between;
  font-size: 0.72rem;
  color: var(--bs-secondary-color);
  letter-spacing: 0.02em;
}

.rd-top-list {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.rd-top-item {
  display: grid;
  grid-template-columns: auto auto 1fr;
  align-items: center;
  gap: 0.7rem;
  padding: 0.55rem 0.6rem;
  border-radius: 0.7rem;
  background: var(--bs-tertiary-bg);
  border: 1px solid color-mix(in srgb, var(--bs-border-color) 60%, transparent);
  transition: background 120ms ease, border-color 120ms ease;
}

.rd-top-item:hover {
  background: color-mix(in srgb, var(--bs-tertiary-bg) 60%, var(--bs-body-bg));
  border-color: color-mix(in srgb, var(--bs-border-color) 90%, transparent);
}

/* Rank chip — gold/silver/bronze for top 3, neutral for the rest. */
.rd-top-rank {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.65rem;
  height: 1.65rem;
  border-radius: 50%;
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  background: var(--bs-secondary-bg, var(--bs-tertiary-bg));
  color: var(--bs-secondary-color);
  border: 1px solid color-mix(in srgb, var(--bs-border-color) 80%, transparent);
  flex: 0 0 auto;
}

.rd-top-item--rank-1 .rd-top-rank {
  background: linear-gradient(135deg, #fde68a, #f59e0b);
  color: #78350f;
  border-color: color-mix(in srgb, #f59e0b 50%, transparent);
  box-shadow: 0 1px 3px color-mix(in srgb, #f59e0b 35%, transparent);
}

.rd-top-item--rank-2 .rd-top-rank {
  background: linear-gradient(135deg, #e5e7eb, #9ca3af);
  color: #1f2937;
  border-color: color-mix(in srgb, #9ca3af 50%, transparent);
  box-shadow: 0 1px 3px color-mix(in srgb, #6b7280 35%, transparent);
}

.rd-top-item--rank-3 .rd-top-rank {
  background: linear-gradient(135deg, #fed7aa, #c2410c);
  color: #fff;
  border-color: color-mix(in srgb, #c2410c 50%, transparent);
  box-shadow: 0 1px 3px color-mix(in srgb, #c2410c 35%, transparent);
}

/* Letter avatar — color rotates per rank to mirror the supplier list look. */
.rd-top-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 0.6rem;
  font-weight: 700;
  font-size: 0.92rem;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  background: color-mix(in srgb, #c2255f 14%, transparent);
  color: #c2255f;
  border: 1px solid color-mix(in srgb, #c2255f 22%, transparent);
  flex: 0 0 auto;
}

.rd-top-item:nth-child(6n+2) .rd-top-avatar {
  background: color-mix(in srgb, #10b981 14%, transparent);
  color: #059669;
  border-color: color-mix(in srgb, #10b981 22%, transparent);
}

.rd-top-item:nth-child(6n+3) .rd-top-avatar {
  background: color-mix(in srgb, #f59e0b 16%, transparent);
  color: #b45309;
  border-color: color-mix(in srgb, #f59e0b 24%, transparent);
}

.rd-top-item:nth-child(6n+4) .rd-top-avatar {
  background: color-mix(in srgb, #ec4899 14%, transparent);
  color: #be185d;
  border-color: color-mix(in srgb, #ec4899 22%, transparent);
}

.rd-top-item:nth-child(6n+5) .rd-top-avatar {
  background: color-mix(in srgb, #06b6d4 14%, transparent);
  color: #0e7490;
  border-color: color-mix(in srgb, #06b6d4 22%, transparent);
}

.rd-top-item:nth-child(6n) .rd-top-avatar {
  background: color-mix(in srgb, #8b5cf6 14%, transparent);
  color: #7c3aed;
  border-color: color-mix(in srgb, #8b5cf6 22%, transparent);
}

[data-bs-theme="dark"] .rd-top-item:nth-child(6n+1) .rd-top-avatar { color: #f2608a; }
[data-bs-theme="dark"] .rd-top-item:nth-child(6n+2) .rd-top-avatar { color: #6ee7b7; }
[data-bs-theme="dark"] .rd-top-item:nth-child(6n+3) .rd-top-avatar { color: #fcd34d; }
[data-bs-theme="dark"] .rd-top-item:nth-child(6n+4) .rd-top-avatar { color: #f9a8d4; }
[data-bs-theme="dark"] .rd-top-item:nth-child(6n+5) .rd-top-avatar { color: #67e8f9; }
[data-bs-theme="dark"] .rd-top-item:nth-child(6n)   .rd-top-avatar { color: #c4b5fd; }

.rd-top-body {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  min-width: 0;
}

.rd-top-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  min-width: 0;
}

.rd-top-name {
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--bs-body-color);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.rd-top-profit {
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: -0.01em;
  color: var(--rd-success);
  white-space: nowrap;
  flex: 0 0 auto;
}

.rd-top-list-track {
  height: 5px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--bs-border-color) 55%, transparent);
  overflow: hidden;
}

.rd-top-list-fill {
  height: 100%;
  background: linear-gradient(
    90deg,
    var(--rd-success, #198754) 0%,
    color-mix(in srgb, var(--rd-success, #198754) 55%, transparent) 100%
  );
  border-radius: inherit;
}

/* ---------------- Customer invoice / statement layout ---------------
 * A unified letterhead + compact summary strip + inline signature
 * trio shared by customer_statement.html and
 * customer_detailed_invoice.html. Replaces the previous mix of
 * stacked Bootstrap rows + tall KPI cards that wasted ~25% of every
 * printed page on whitespace and oversized boxes. */

.rd-invoice-head {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  border: 1px solid var(--bs-border-color);
  border-radius: var(--rd-radius-md);
  padding: 0.85rem 1rem 0.7rem;
  background: var(--bs-body-bg);
}

/* Three-column grid so the logo can sit visually centred while the
 * document type / issue date hug the start edge (right in RTL, left
 * in LTR) on the SAME baseline. The empty spacer balances the start
 * column so the centre column stays geometrically centred regardless
 * of how long the doc label gets. */
.rd-invoice-head-top {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 0.75rem;
}

.rd-invoice-head-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 2.5rem;
}

.rd-invoice-head-logo {
  max-height: 64px;
  max-width: 240px;
  object-fit: contain;
}

.rd-invoice-head-title {
  font-weight: 700;
  font-size: 1.2rem;
  letter-spacing: 0.01em;
}

.rd-invoice-head-doc-row {
  display: flex;
  flex-direction: column;
  align-items: flex-start; /* "start" of the writing direction —
                              right in Arabic (RTL), left in English (LTR) */
  gap: 0.05rem;
  text-align: start;
  min-width: 0;
}

.rd-invoice-head-spacer {
  /* invisible, just balances the grid so the brand stays centred */
}

.rd-invoice-head-doc {
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: var(--bs-body-color);
}

.rd-invoice-head-issued {
  font-size: 0.78rem;
}

.rd-invoice-head-bottom {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.75rem 1.5rem;
  flex-wrap: wrap;
  padding-top: 0.5rem;
  margin-top: 0.15rem;
  border-top: 1px solid var(--bs-border-color);
  text-align: start;
}

.rd-invoice-head-customer,
.rd-invoice-head-period {
  display: inline-flex;
  align-items: baseline;
  gap: 0.45rem;
  flex-wrap: wrap;
}

.rd-invoice-head-period {
  text-align: end;
}

/* Compact summary strip — one row of label/value pairs with the
 * closing balance set apart by a left border so the headline number
 * still reads as a "total". */
.rd-invoice-summary {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  align-items: stretch;
  padding: 0.65rem 1rem;
  border: 1px solid var(--bs-border-color);
  border-radius: var(--rd-radius-md);
  background: var(--bs-body-bg);
}

.rd-invoice-summary--secondary {
  background: var(--bs-tertiary-bg);
}

.rd-invoice-summary-item {
  display: flex;
  flex-direction: column;
  gap: 0.05rem;
  min-width: 7.5rem;
}

.rd-invoice-summary-item .rd-label {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--bs-secondary-color);
}

.rd-invoice-summary-value {
  font-weight: 700;
  font-size: 1.1rem;
  line-height: 1.2;
}

.rd-invoice-summary-hint {
  font-size: 0.72rem;
  color: var(--bs-secondary-color);
}

.rd-invoice-summary-item--total {
  margin-inline-start: auto;
  padding-inline-start: 1rem;
  border-inline-start: 2px solid var(--bs-border-color);
  min-width: 9rem;
}

.rd-invoice-summary-item--total .rd-invoice-summary-value {
  font-size: 1.25rem;
}

/* Compact signature block — two columns separated by gap, each just
 * tall enough to write a name above a thin rule. */
.rd-invoice-sig {
  display: flex;
  gap: 2rem;
  margin-top: 1.5rem;
  padding-inline: 0.25rem;
}

.rd-invoice-sig-block {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

.rd-invoice-sig-rule {
  display: block;
  height: 1.6rem; /* leaves room for a real signature above the rule */
  border-bottom: 1px solid var(--bs-body-color);
}

.rd-invoice-sig-name {
  font-size: 0.85rem;
  font-weight: 600;
  min-height: 1.1em;
}

.rd-invoice-sig-block .rd-label {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--bs-secondary-color);
}

@media (max-width: 575.98px) {
  /* Stack the three columns: logo on top, doc info under it, spacer
   * collapses. Keeps the layout readable on narrow phones. */
  .rd-invoice-head-top {
    grid-template-columns: 1fr;
    text-align: center;
  }
  .rd-invoice-head-doc-row {
    align-items: center;
    text-align: center;
    order: 2;
  }
  .rd-invoice-head-brand { order: 1; }
  .rd-invoice-head-spacer { display: none; }
  .rd-invoice-head-bottom { flex-direction: column; align-items: flex-start; }
  .rd-invoice-head-period { text-align: start; }
  .rd-invoice-summary-item--total {
    margin-inline-start: 0;
    padding-inline-start: 0;
    border-inline-start: 0;
    border-top: 1px solid var(--bs-border-color);
    padding-top: 0.4rem;
  }
  .rd-invoice-sig { flex-direction: column; gap: 1.25rem; }
}

/* ---------------- Print mode (customer statement, future receipts) -----
 * @page { margin: 0 } is the key trick: in Chrome / Edge it removes
 * the auto-injected URL + page-number footer and the document-title
 * header. We then re-add visual margins via body padding so content
 * is not glued to the paper edge. Firefox / Safari still respect
 * the @page block but their default headers/footers are also
 * controllable from the print dialog. */
@media print {
  @page {
    size: A4 portrait;
    margin: 0;
  }
  html, body {
    background: #fff !important;
    color: #000 !important;
  }
  /* Trimmed from 1.5cm/1.2cm. The previous values were chosen to look
   * "safe" but they reserved nearly 2cm of dead space above the
   * letterhead. Modern home / office printers handle 0.8cm comfortably
   * and we still keep slightly larger top margin so the logo doesn't
   * touch the paper edge. */
  body {
    padding: 1cm 0.9cm 0.8cm !important;
    font-size: 11pt;
  }
  /* Hide app chrome the customer doesn't need on paper. */
  .rd-sidebar,
  .rd-topbar,
  .rd-mobile-tabbar,
  .d-print-none {
    display: none !important;
  }
  .rd-main, .rd-page, .rd-content {
    background: #fff !important;
    margin: 0 !important;
    padding: 0 !important;
  }
  .rd-card {
    border: 1px solid #999 !important;
    box-shadow: none !important;
    break-inside: avoid;
  }
  /* Cards that contain long paginated content (e.g. the detailed
   * invoice table) must be allowed to split across pages, otherwise
   * they push the whole table to the next page and leave page 1
   * nearly empty. */
  .rd-card.rd-print-flow {
    break-inside: auto;
  }
  .rd-card.rd-print-flow table {
    break-inside: auto;
  }
  .rd-card.rd-print-flow thead {
    display: table-header-group; /* repeat header on each page */
  }
  .rd-card.rd-print-flow tfoot {
    display: table-footer-group;
  }
  .rd-card.rd-print-flow tr {
    break-inside: avoid;
  }
  .table { color: #000 !important; }
  a { color: inherit !important; text-decoration: none !important; }

  /* Legacy print-only logo header. The current customer statement /
   * detailed invoice render the logo through .rd-invoice-head, which
   * keeps the brand, customer and period together; this rule is kept
   * for any other template still using the older partial. */
  .rd-print-brand {
    text-align: center;
    margin-bottom: 0.6rem;
    padding-bottom: 0.4rem;
    border-bottom: 1px solid #ccc;
  }
  .rd-print-brand-logo {
    max-height: 64px;
    max-width: 200px;
    object-fit: contain;
  }

  /* Tighter borders + ink-friendly background for invoice bands. */
  .rd-invoice-head,
  .rd-invoice-summary {
    border: 1px solid #888 !important;
    background: #fff !important;
    padding: 0.55rem 0.75rem !important;
    break-inside: avoid;
  }
  .rd-invoice-head { margin-bottom: 0.5rem !important; }
  .rd-invoice-summary { margin-bottom: 0.5rem !important; }

  .rd-invoice-summary-item--total {
    border-inline-start-color: #888 !important;
  }

  .rd-invoice-sig {
    margin-top: 1.25rem !important;
    break-inside: avoid;
  }
  .rd-invoice-sig-rule {
    border-bottom-color: #000 !important;
  }
}
