/* ─────────────────────────────────────────────
   UNENO Dashboard — Stylesheet
   ───────────────────────────────────────────── */

* { box-sizing: border-box; }

/* ── Utilities ── */
.no-scroll   { overflow: hidden; }
/*.text-mono   { font-family: 'IBM Plex Mono', ui-monospace, monospace !important; }*/
.search-icon-input { padding-left: 30px !important; }
.chevron-open { transform: rotate(180deg); }

/* Logo theme switching */
.logo-light { display: none; }
.logo-dark  { display: block; }
[data-theme="light"] .logo-light { display: block; }
[data-theme="light"] .logo-dark  { display: none; }

body {
  background: var(--color-bg);
  color: var(--color-ink);
  font-family: 'IBM Plex Sans', sans-serif;
}

/* ── Scrollbar ── */
/* Webkit (Chrome, Safari, Edge) */
::-webkit-scrollbar { width: 5px; height: 5px; }
::-webkit-scrollbar-track { background: var(--color-bg2); }
::-webkit-scrollbar-thumb { background: var(--color-border); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: var(--color-border2); }
/* Firefox only */
@-moz-document url-prefix() {
  * { scrollbar-width: thin; scrollbar-color: var(--color-border) var(--color-bg2); }
}

/* ── Custom scroll (for dynamically created containers like dropdowns) ── */
.custom-scroll {
  overflow-y: scroll !important;
  scrollbar-width: thin !important;
  scrollbar-color: var(--color-border) var(--color-bg2) !important;
}
.custom-scroll::-webkit-scrollbar { width: 5px !important; height: 5px !important; display: block !important; }
.custom-scroll::-webkit-scrollbar-track { background: var(--color-bg2) !important; border-radius: 4px !important; }
.custom-scroll::-webkit-scrollbar-thumb { background: var(--color-border) !important; border-radius: 4px !important; }
.custom-scroll::-webkit-scrollbar-thumb:hover { background: var(--color-border2) !important; }

/* ── Placeholder image background ──
   Uses the --placeholder-url CSS var so the asset swaps per theme
   (light variant on Light/Duotone, dark variant on Dark/Midnight Blue).
   Pair with aspect-ratio / fixed sizing and role="img" + aria-label on
   the host element for accessibility. */
.bg-placeholder {
  background-image: var(--placeholder-url);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

/* ── Sidebar links ──
   Monochrome active state: neutral bg + ink text + ink indicator bar.
   No blue accent — the sidebar is the primary nav, color is reserved for
   semantic states elsewhere. */
.sidebar-link { transition: all 0.15s; text-decoration: none; }
.sidebar-link:hover { background: var(--color-bg3); color: var(--color-ink); }
.sidebar-link.active {
  background: var(--color-bg3);
  color: var(--color-ink);
  position: relative;
}
.sidebar-link.active::before {
  content: '';
  position: absolute;
  left: 0;
  top: 6px;
  bottom: 6px;
  width: 2px;
  border-radius: 0 2px 2px 0;
  background: var(--color-ink);
}

/* ── Stat cards ── */
.stat-card { transition: transform 0.15s, border-color 0.15s; }
.stat-card:hover { transform: translateY(-2px); border-color: var(--color-border2); }

/* ── Subtle bottom shadow for card-like containers ──
   Targets the standard `bg-bg2 border rounded-{lg,md}` pattern used across all
   listing/detail/overview pages (rounded-lg = settings/detail cards, rounded-md =
   the table cards). Theme-aware via --shadow-card so dark themes get a slightly
   stronger value (otherwise invisible against the dark surface) and light themes
   use a soft blue-tinted lift. Per-theme overrides live in
   public/css/themes/{light,duotone}.css. */
/* Dark default — black at higher opacity so the shadow registers against the
   dark surface (3% blue on dark bg is invisible; light themes override below). */
:root { --shadow-card: 0 2px 3px rgba(0, 0, 0, 0.18), 0 2px 3px rgba(0, 0, 0, 0.18); }
.bg-bg2.border.rounded-lg,
.bg-bg2.border.rounded-md {
  box-shadow: var(--shadow-card);
}
/* Opt-out: a wrapper marked .no-inner-shadow suppresses the auto card shadow on
   its nested bg-bg2 cards — e.g. a settings-group's inner surface, which already
   sits inside an outer tray and needs no lift of its own. */
.no-inner-shadow .bg-bg2.border.rounded-lg,
.no-inner-shadow .bg-bg2.border.rounded-md {
  box-shadow: none;
}

/* ── Badges ──
   All colors derived from theme tokens via color-mix() — no hardcoded rgbas,
   so badges reflow correctly on both light and dark themes. */
.badge-blue   { background: color-mix(in srgb, var(--color-accent)  12%, transparent); color: var(--color-accent);  border: 1px solid color-mix(in srgb, var(--color-accent)  25%, transparent); }
.badge-green  { background: color-mix(in srgb, var(--color-accent3) 10%, transparent); color: var(--color-accent3); border: 1px solid color-mix(in srgb, var(--color-accent3) 25%, transparent); }
.badge-amber  { background: color-mix(in srgb, var(--color-accent4) 10%, transparent); color: var(--color-accent4); border: 1px solid color-mix(in srgb, var(--color-accent4) 25%, transparent); }
.badge-purple { background: color-mix(in srgb, var(--color-accent2) 10%, transparent); color: var(--color-accent2); border: 1px solid color-mix(in srgb, var(--color-accent2) 25%, transparent); }
.badge-red    { background: color-mix(in srgb, var(--color-danger)  10%, transparent); color: var(--color-danger);  border: 1px solid color-mix(in srgb, var(--color-danger)  25%, transparent); }
.badge-muted  { background: color-mix(in srgb, var(--color-muted)   12%, transparent); color: var(--color-muted);   border: 1px solid color-mix(in srgb, var(--color-muted)   20%, transparent); }
.badge-mono   { background: color-mix(in srgb, var(--color-ink)     8%, transparent); color: var(--color-ink);     border: 1px solid color-mix(in srgb, var(--color-ink)     15%, transparent); }

/* ── Progress bars ── */
.progress-bar  { height: 3px; border-radius: 99px; background: var(--color-border); overflow: hidden; }
.progress-fill { height: 100%; border-radius: 99px; transition: width 1s ease; width: var(--w, 0%); }

/* ── Nav icons ── */
.nav-icon { width: 16px; height: 16px; flex-shrink: 0; }

/* ── Animations ── */
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}
.fade-up { animation: fadeUp 0.4s ease forwards; opacity: 0; }
.delay-1 { animation-delay: 0.05s; }
.delay-2 { animation-delay: 0.10s; }
.delay-3 { animation-delay: 0.15s; }
.delay-4 { animation-delay: 0.20s; }
.delay-5 { animation-delay: 0.25s; }
.delay-6 { animation-delay: 0.30s; }

.pulse-dot { animation: pulse 2s infinite; }
@keyframes pulse {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0.4; }
}

/* ── Table rows ── */
.table-row { transition: background 0.1s; }
.table-row:hover { background: var(--color-bg3); }

/* ── Mobile sidebar overlay ── */
.sidebar-overlay { display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.6); z-index: 40; }
.sidebar-overlay.open { display: block; }

/* ── Modal bounce ── */
/* ── Modal transitions (bootstrap-style) ── */
.modal-overlay {
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  margin: 0;
  transition: opacity 0.15s linear;
}
.modal-overlay.modal-open {
  opacity: 1;
  pointer-events: auto;
}
.modal-wrapper {
  transition: opacity 0.15s linear;
}
.modal-wrapper .modal-box {
  transition: transform 0.3s ease-out;
  transform: translateY(-50px);
}
/* One standard modal size every modal inherits (no per-modal width utility). It is
   a column that scrolls its body before overflowing the viewport. Need a wider
   modal? Add the .modal-box-lg modifier — NOT a max-w-* utility, which this
   unlayered rule would override. */
.modal-box {
  width: 100%;
  max-width: 36rem;
  max-height: calc(100dvh - 4rem);
  display: flex;
  flex-direction: column;
}
.modal-box.modal-box-lg { max-width: 42rem; }

/* A modal's scrollable region: it grows to fill the box and scrolls before the box
   overflows the viewport, keeping the header + footer pinned. Put a modal's content
   in a `.modal-body` (with `flex-1 overflow-y-auto min-h-0` on the markup, and the
   form — if any — as `flex flex-col min-h-0 flex-1`). When the body actually
   overflows, resources/js/ui/modals.js adds `.is-scrolling`, which draws the
   separators so the sticky header/footer read as distinct from the scroll area. The
   scroll itself is pure CSS, so it works even without JS. Global to every modal. */
.modal-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.modal-box.is-scrolling .modal-body {
  border-top: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
}
.modal-box.is-scrolling .modal-header { padding-bottom: 1.25rem; }
.modal-box.is-scrolling .modal-footer { padding-top: 1.25rem; }

/* Row-actions kebab menu — a small floating dropdown positioned under its trigger
   by admins.js (fixed, so the table's overflow can't clip it). */
.action-dropdown {
  box-shadow: var(--shadow-dropdown, 0 6px 20px -6px rgba(0, 0, 0, 0.3));
}
.modal-wrapper.modal-open {
  opacity: 1;
  pointer-events: auto;
}
.modal-wrapper.modal-open .modal-box {
  transform: translateY(0);
}
.modal-bounce .modal-box {
  animation: modalBounce 0.5s ease;
}
@keyframes modalBounce {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.02); }
}

/* ── Submenus ── */
#orders-submenu,
#products-submenu,
#integrations-submenu { overflow: hidden; }

.submenu { display: none; }

.submenu.visible {
  display: block !important;
}

/* Animation only fires when the user actively toggles the menu open.
   On initial page load the .visible class is already set by Blade
   (no .opening class) — so no animation, no flicker. */
.submenu.visible.opening {
  animation: slideDown 0.2s ease forwards;
}

@keyframes slideDown {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ── Responsive ── */
@media (max-width: 768px) {
  /* v1.2.0: the app sidebar only (was `aside, aside#sidebar` — it turned EVERY <aside> on a phone into the off-screen
     drawer, so a page could never use one for its own content; the account's phone menu keeps its 300px on a phone — horizontal-nav.css). */
  aside#sidebar {
    position: fixed;
    left: -100%;
    top: 0; bottom: 0;
    z-index: 50;
    transition: left 0.25s ease;
    width: 300px !important;
  }
  aside#sidebar.open { left: 0; }
  .main-wrap { width: 100% !important; }
  .stats-grid { grid-template-columns: repeat(2, 1fr) !important; }
  .mid-grid   { grid-template-columns: 1fr !important; }
  .mid-grid .col-span-2 { grid-column: span 1 !important; }
  .footer-wrap  { display: none; }
  .header-title { display: none; }

  /* Sales Activity KPI — smaller on mobile */
  .sales-kpi-row { gap: 12px !important; }
  .sales-kpi-row .kpi-value { font-size: 18px !important; }

  /* Recent Orders — scrollable table */
  .table-scroll-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .table-scroll-wrap table { white-space: nowrap; min-width: 640px; }

  /* Low Stock + Pending Receptions — full width stack */
  .bottom-grid { grid-template-columns: 1fr !important; }
  .bottom-grid .nowrap-label { white-space: nowrap; }

  /* Orders by Status + Stock Progress — full width stack */
  .charts-grid { grid-template-columns: 1fr !important; }

  /* Search — expandable overlay on mobile */
  .search-field.open {
    display: block !important;
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 80;
    padding: 10px 12px;
    background: var(--color-bg);
    border-bottom: 1px solid var(--color-border);
  }
  .search-field.open input { width: 100% !important; }

  /* Notifications drawer — ensure it works on mobile */
  .notif-drawer { width: calc(100vw - 24px); }
}

@media (max-width: 480px) {
  .stats-grid { grid-template-columns: 1fr !important; }
}

/* ── Chart period select ── */
.chart-period-select { -webkit-appearance: none; }
.chart-period-select option { background: var(--color-bg2); color: var(--color-ink); }

/* ── Chart period buttons ── */
.chart-period-btn { cursor: pointer; border: none; background: none; }

html { background: var(--color-bg); }

/* ── Filter search input ── */
.filter-search-input { background: var(--color-bg3) !important; transition: border-color 0.15s, box-shadow 0.15s; }
.filter-search-input:hover { border-color: var(--color-border2) !important; }
.filter-search-input:focus-within {
  border-color: color-mix(in srgb, var(--color-ink) 40%, transparent) !important;
  box-shadow: 0 0 0 3px var(--focus-ring) !important;
}

/* ── User dropdown ── */
.user-dropdown {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: 240px;
  background: var(--color-bg2);
  border: 1px solid var(--color-border);
  border-radius: 10px;
  box-shadow: 0 16px 40px rgba(0,0,0,0.5);
  z-index: 100;
  overflow: hidden;
  opacity: 0;
  transform: translateY(-8px) scale(0.97);
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
}
.user-dropdown.open {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: all;
}
.user-dropdown-header {
  padding: 14px 16px 12px;
  display: flex;
  align-items: center;
  gap: 10px;
  border-bottom: 1px solid var(--color-border);
}
.user-avatar-lg {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--color-accent2);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 13px;
  font-weight: 700;
  color: white;
  flex-shrink: 0;
  position: relative;
}
.user-dropdown-section {
  padding: 6px 0;
  border-bottom: 1px solid var(--color-border);
}
.user-dropdown-section:last-child { border-bottom: none; }
.user-dropdown-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 16px;
  font-size: 12px;
  color: var(--color-muted);
  cursor: pointer;
  transition: background 0.1s, color 0.1s;
  text-decoration: none;
  border: none;
  background: none;
  width: 100%;
}
.user-dropdown-item:hover,
.user-dropdown-section .user-dropdown-item.active { background: var(--color-bg3); color: var(--color-ink); }
.user-dropdown-item.danger { color: var(--color-danger); }
.user-dropdown-item.danger:hover { background: color-mix(in srgb, var(--color-danger) 10%, transparent); color: var(--color-danger); }
.user-dropdown-item svg { flex-shrink: 0; opacity: 0.7; }
.user-dropdown-item:hover svg,
.user-dropdown-section .user-dropdown-item.active svg { opacity: 1; }
.user-dropdown-item .item-right { margin-left: auto; font-size: 10px; }

/* ── Language dropdown ── */
.lang-dropdown {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  min-width: 120px;
  background: var(--color-bg2);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.4);
  z-index: 100;
  overflow: hidden;
  opacity: 0;
  transform: translateY(-4px);
  pointer-events: none;
  transition: opacity 0.15s ease, transform 0.15s ease;
  padding: 4px;
}
.lang-dropdown.open {
  opacity: 1;
  transform: translateY(0);
  pointer-events: all;
}
.lang-dropdown-item {
  display: block;
  width: 100%;
  padding: 6px 12px;
  font-size: 12px;
  color: var(--color-muted);
  background: none;
  border: none;
  cursor: pointer;
  text-align: left;
  border-radius: 4px;
  transition: background 0.1s, color 0.1s;
}
.lang-dropdown-item:hover { background: var(--color-bg3); color: var(--color-ink); }
.lang-dropdown-item.active { color: var(--color-accent); }

/* ── Notifications drawer ── */
.notif-overlay {
  display: none;
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  background: rgba(0,0,0,0.4);
  z-index: 60;
}
.notif-overlay.open { display: block; margin: 0; }

.notif-drawer {
  position: fixed;
  top: 12px;
  right: -420px;
  bottom: 12px;
  width: 380px;
  max-width: calc(100vw - 24px);
  background: var(--color-bg2);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  box-shadow: -8px 4px 48px rgba(0,0,0,0.25), 0 0 0 1px rgba(0,0,0,0.05);
  z-index: 70;
  display: flex;
  flex-direction: column;
  transition: right 0.25s ease;
  overflow: hidden;
}
.notif-drawer.open { right: 12px; }

.notif-drawer-header {
  height: 56px;
  padding: 0 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid var(--color-border);
  flex-shrink: 0;
}

.notif-tabs {
  display: flex;
  gap: 2px;
  padding: 8px 16px;
  border-bottom: 1px solid var(--color-border);
  flex-shrink: 0;
}
.notif-tab {
  padding: 8px 10px;
  border-radius: 6px;
  font-size: 11px;
  font-family: 'IBM Plex Sans', sans-serif;
  color: var(--color-muted);
  background: transparent;
  border: none;
  cursor: pointer;
  transition: all 0.15s;
}
.notif-tab:hover { color: var(--color-ink); background: var(--color-bg3); }
.notif-tab.active { color: var(--color-accent); background: color-mix(in srgb, var(--color-accent) 12%, transparent); }

.notif-list {
  flex: 1;
  overflow-y: auto;
}

.notif-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--color-border);
  cursor: pointer;
  transition: background 0.1s;
  position: relative;
}
.notif-item:hover { background: var(--color-bg3); }
.notif-item:last-child { border-bottom: none; }

.notif-item.unread { background: color-mix(in srgb, var(--color-accent) 8%, transparent); }
.notif-item.unread:hover { background: color-mix(in srgb, var(--color-accent) 14%, transparent); }

.notif-dot {
  position: absolute;
  left: 6px;
  top: 18px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--color-accent);
}

.notif-icon {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.notif-icon-red    { background: color-mix(in srgb, var(--color-danger) 12%, transparent);   color: var(--color-danger); }
.notif-icon-blue   { background: color-mix(in srgb, var(--color-accent) 12%, transparent);  color: var(--color-accent); }
.notif-icon-green  { background: color-mix(in srgb, var(--color-accent3) 12%, transparent);  color: var(--color-accent3); }
.notif-icon-amber  { background: color-mix(in srgb, var(--color-accent4) 12%, transparent);  color: var(--color-accent4); }
.notif-icon-purple { background: color-mix(in srgb, var(--color-accent2) 12%, transparent); color: var(--color-accent2); }

.notif-content { flex: 1; min-width: 0; }

.notif-title {
  font-size: 12px;
  font-weight: 500;
  color: var(--color-ink);
  line-height: 1.3;
}
.notif-desc {
  font-size: 11px;
  color: var(--color-muted);
  line-height: 1.4;
  margin-top: 3px;
}
.notif-meta {
  font-size: 10px;
  font-family: 'IBM Plex Sans', sans-serif;
  color: var(--color-dim);
  margin-top: 4px;
}

.notif-drawer-footer {
  padding: 12px 16px 20px;
  border-top: 1px solid var(--color-border);
  text-align: center;
  flex-shrink: 0;
}

/* ─────────────────────────────────────────────
   Login Page
   ───────────────────────────────────────────── */

.login-card {
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.25), 0 1px 3px rgba(0, 0, 0, 0.15);
}

.login-input::placeholder { color: var(--color-dim); }

/* Monochrome primary auth button — ink bg + on-ink text.
   Self-contained so auth pages don't need inline Tailwind color utilities.
   Size is auth-card appropriate (larger than .primary-btn which is
   dashboard-density). Consumers just add layout classes like w-full. */
.login-btn {
  padding: 0.625rem 1rem;
  background: var(--color-ink);
  color: var(--color-on-ink);
  border: 1px solid var(--color-ink);
  border-radius: 0.5rem;
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: opacity 0.15s, transform 0.1s;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
}
.login-btn:hover:not(:disabled) { opacity: 0.9; }
.login-btn:active { transform: scale(0.985); }
.login-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-ink) 20%, transparent);
}
.login-btn:disabled {
  opacity: 0.5 !important;
  cursor: not-allowed !important;
  pointer-events: none;
}

.social-btn {
  cursor: pointer;
  font-family: 'IBM Plex Sans', sans-serif;
}
.social-btn:active {
  transform: scale(0.985);
}

.otp-input {
  caret-color: var(--color-accent);
}
.otp-input:focus {
  border-color: var(--color-accent);
}

.login-checkbox {
  appearance: none;
  -webkit-appearance: none;
  width: 14px;
  height: 14px;
  border: 1.5px solid var(--color-border);
  border-radius: 3px;
  background: var(--color-bg3);
  cursor: pointer;
  position: relative;
  transition: all 0.15s;
}
.login-checkbox:checked {
  background: var(--color-ink);
  border-color: var(--color-ink);
}
.login-checkbox:checked::after {
  content: '';
  position: absolute;
  left: 3.5px;
  top: 1px;
  width: 4px;
  height: 7px;
  border: solid var(--color-on-ink);
  border-width: 0 1.5px 1.5px 0;
  transform: rotate(45deg);
}

.login-logo-mark { fill: #ffffff; }

/* ── Login dark mode focus ── */
.login-input:focus {
  border-color: var(--color-border2) !important;
  box-shadow: 0 0 0 3px var(--focus-ring) !important;
}

/* ── Login input error state — must override :focus ── */
.login-input.border-red-500\/50,
.login-input.border-red-500\/50:focus,
.login-input.border-red-500\/50:active {
  border-color: color-mix(in srgb, var(--color-danger) 50%, transparent) !important;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-danger) 12%, transparent) !important;
  outline: none !important;
}
/* ── Subdomain group error — wraps input + suffix ── */
#subdomain-group.subdomain-error {
  outline: 1px solid color-mix(in srgb, var(--color-danger) 50%, transparent);
  outline-offset: -1px;
}

/* ── Pricing cards ── */
.pricing-card {
  transition: border-color 0.15s, transform 0.15s;
}
.pricing-card:hover {
  border-color: var(--color-border2);
  transform: translateY(-2px);
}
.pricing-card-popular {
  /* border handled inline (border-accent/30 idle, full accent on hover) */
}
.pricing-card-popular:hover {
  border-color: var(--color-accent) !important;
}
.pricing-card-current:hover {
  border-color: var(--color-ink) !important;
}
.billing-tab { cursor: pointer; }

/* ─────────────────────────────────────────────
   KTUI Select — Scrollbar overrides
   (Component overrides are in ktui-overrides.css)
   ───────────────────────────────────────────── */
.kt-select-wrapper .kt-select-options {
  scrollbar-width: thin;
  scrollbar-color: var(--color-border) var(--color-bg2);
}
.kt-select-wrapper .kt-select-options::-webkit-scrollbar { width: 5px; }
.kt-select-wrapper .kt-select-options::-webkit-scrollbar-track { background: var(--color-bg2); }
.kt-select-wrapper .kt-select-options::-webkit-scrollbar-thumb { background: var(--color-border); border-radius: 4px; }
.kt-select-wrapper .kt-select-options::-webkit-scrollbar-thumb:hover { background: var(--color-border2); }

/* ─────────────────────────────────────────────
   Orders Page
   ───────────────────────────────────────────── */

/* Filter pills */
.filter-pill {
  background: transparent;
  color: var(--color-muted);
  border: 1px solid transparent;
  cursor: pointer;
}
.filter-pill:hover {
  color: var(--color-ink);
  background: var(--color-bg3);
}
.filter-pill.active {
  background: color-mix(in srgb, var(--color-accent) 10%, transparent);
  color: var(--color-accent);
  border-color: color-mix(in srgb, var(--color-accent) 20%, transparent);
}

/* Order checkboxes */
.order-checkbox {
  appearance: none;
  -webkit-appearance: none;
  width: 14px;
  height: 14px;
  border: 1.5px solid var(--color-border);
  border-radius: 3px;
  background: var(--color-bg3);
  cursor: pointer;
  position: relative;
  transition: all 0.15s;
  flex-shrink: 0;
}
.order-checkbox:checked {
  background: var(--color-accent);
  border-color: var(--color-accent);
}
.order-checkbox:checked::after {
  content: '';
  position: absolute;
  left: 3.5px;
  top: 1px;
  width: 4px;
  height: 7px;
  border: solid #fff;
  border-width: 0 1.5px 1.5px 0;
  transform: rotate(45deg);
}

/* Expanded row */
.order-row.expanded { background: color-mix(in srgb, var(--color-accent) 40%, transparent); }

/* Detail row transition */
.order-detail-row .detail-inner {
  transition: max-height 0.3s ease;
}

/* Expanded row — is-expanded variant */
.order-row.is-expanded { background: color-mix(in srgb, var(--color-accent) 40%, transparent); }

/* Order row hover */
.order-row { cursor: default; transition: background 0.1s; }
.order-row:hover { background: var(--color-bg3); }

/* Product sub-table row */
.products-row { display: none; }
.products-row.open { display: table-row; }
.products-inner        { max-height: 0;      overflow: hidden; transition: max-height 0.28s ease; }
.products-inner.open   { max-height: 1500px; }

/* Expand / more buttons */
.btn-expand {
  width: 20px; height: 20px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 4px;
  border: 1px solid var(--color-border);
  background: transparent;
  color: var(--color-muted);
  cursor: pointer;
  transition: all 0.15s;
}
.btn-expand:hover { background: var(--color-bg3); color: var(--color-ink); border-color: var(--color-border2); }
.btn-expand.active { background: color-mix(in srgb, var(--color-accent) 10%, transparent); color: var(--color-accent); border-color: color-mix(in srgb, var(--color-accent) 30%, transparent); }
.btn-more {
  width: 20px; height: 20px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 4px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--color-muted);
  cursor: pointer;
  transition: all 0.15s;
}
.btn-more:hover { background: var(--color-bg3); color: var(--color-ink); border-color: var(--color-border); }

/* ── KTUI filter selects — compact variant ── */
.filter-kt .kt-select-wrapper .kt-select.kt-select-display {
  padding: 8px 10px !important;
  font-size: 12px !important;
  line-height: 18px !important;
  border-radius: 6px !important;
  min-width: 100px;
}
.filter-kt .kt-select-wrapper .kt-select-placeholder {
  font-size: 12px !important;
}
.filter-kt .kt-select-wrapper .kt-select-dropdown {
  border-radius: 6px !important;
  min-width: 140px;
}
.filter-kt .kt-select-wrapper .kt-select-option {
  padding: 8px 10px !important;
  font-size: 12px !important;
}

/* ── Full-width panel selects ── */
.filter-panel .kt-select-wrapper { width: 100% !important; }
.filter-panel .kt-select-wrapper .kt-select.kt-select-display { width: 100% !important; min-width: unset !important; }
.kt-date-range-full { width: 100% !important; }
.kt-date-range-full input { width: 100% !important; }

/* ── KTUI scrollbar fix ── */
.kt-scrollable,
.kt-select-options {
  scrollbar-width: none !important;
}
.kt-scrollable::-webkit-scrollbar,
.kt-select-options::-webkit-scrollbar { width: 5px !important; height: 5px !important; display: block !important; }
.kt-scrollable::-webkit-scrollbar-track,
.kt-select-options::-webkit-scrollbar-track { background: var(--color-bg2) !important; }
.kt-scrollable::-webkit-scrollbar-thumb,
.kt-select-options::-webkit-scrollbar-thumb { background: var(--color-border) !important; border-radius: 4px !important; }
.kt-scrollable::-webkit-scrollbar-thumb:hover,
.kt-select-options::-webkit-scrollbar-thumb:hover { background: var(--color-border2) !important; }

/* ── Export dropdown ── */
#export-dropdown { box-shadow: 0 8px 24px rgba(0,0,0,0.3); }

/* ── Filter select (native) ── */
.filter-select {
  -webkit-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12'%3E%3Cpath d='M3 4.5l3 3 3-3' stroke='%236b7a99' stroke-width='1.3' stroke-linecap='round' fill='none'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 8px center;
  padding-right: 26px !important;
  cursor: pointer;
}
.filter-select { transition: border-color 0.15s, box-shadow 0.15s; }
.filter-select:hover { border-color: var(--color-border2) !important; }
.filter-select:focus {
  border-color: color-mix(in srgb, var(--color-ink) 40%, transparent) !important;
  box-shadow: 0 0 0 3px var(--focus-ring) !important;
  outline: none !important;
}
.filter-select option { background: var(--color-bg2); color: var(--color-ink); }

/* ── Date range input ── */
.kt-date-range-input {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 10px !important;
  border: 1px solid var(--color-border) !important;
  border-radius: 6px !important;
  background: var(--color-bg3) !important;
  cursor: pointer;
  min-width: 210px;
}
.kt-date-range-input input {
  background: transparent !important;
  border: none !important;
  color: var(--color-ink) !important;
  font-size: 12px !important;
  outline: none !important;
  cursor: pointer;
  width: 100%;
  padding: 0 !important;
}
.kt-date-range-input input::placeholder { color: var(--color-dim) !important; }
.kt-date-range-input {
  transition: border-color 0.15s, box-shadow 0.15s;
}
.kt-date-range-input:hover { border-color: var(--color-border2) !important; }
.kt-date-range-input:focus-within {
  border-color: color-mix(in srgb, var(--color-ink) 40%, transparent) !important;
  box-shadow: 0 0 0 3px var(--focus-ring) !important;
  outline: none !important;
}

/* ── Flatpickr — compact sizing ── */
.flatpickr-calendar {
  font-size: 12px !important;
  border-radius: 8px !important;
  overflow: hidden;
  margin-top: 10px !important;
  padding: 0 !important;
  margin-left: -28px !important; /* range picker offset; overridden for single below */
  font-family: 'IBM Plex Sans', sans-serif !important;
  width: auto !important;
}
.flatpickr-calendar:not(.multiMonth) { margin-left: 0 !important; }
.flatpickr-calendar.arrowTop::before,
.flatpickr-calendar.arrowTop::after { display: none; }
.flatpickr-current-month { font-size: 11px !important; padding-top: 14px !important; }
.flatpickr-current-month .cur-month { font-size: 11px !important; font-weight: 500; letter-spacing: 0.02em; }
/* Year control: keep it visible + navigable (type / scroll / the up-down arrows).
   Previously the whole wrapper was hidden, which stripped year navigation from every date
   picker. Force the input's colour + width (it inherits, and the wrapper was collapsed),
   and keep the arrows faintly visible so the control is discoverable, not hover-only. */
.flatpickr-current-month .numInputWrapper { display: inline-block !important; width: 7ch !important; vertical-align: middle; }
.flatpickr-current-month input.cur-year {
  font-size: 11px !important;
  font-weight: 400 !important;
  color: var(--color-ink) !important;
  width: 100% !important;
  padding: 0 0 0 0.5ch !important;
}
.flatpickr-current-month .numInputWrapper span.arrowUp,
.flatpickr-current-month .numInputWrapper span.arrowDown { opacity: 0.45 !important; border-color: var(--color-border) !important; }
.flatpickr-current-month .numInputWrapper span.arrowUp:hover,
.flatpickr-current-month .numInputWrapper span.arrowDown:hover { opacity: 1 !important; }
.flatpickr-dark .flatpickr-current-month input.cur-year { color: var(--color-ink) !important; }
.flatpickr-current-month .flatpickr-monthDropdown-months { font-size: 11px !important; }
.flatpickr-months { height: 38px !important; }
.flatpickr-months .flatpickr-prev-month,
.flatpickr-months .flatpickr-next-month { padding: 8px 10px !important; top: 0 !important; height: 38px !important; display: flex !important; align-items: center !important; }
.flatpickr-months .flatpickr-prev-month svg,
.flatpickr-months .flatpickr-next-month svg { width: 12px !important; height: 12px !important; }
span.flatpickr-weekday { font-size: 9px !important; text-align: left !important; padding-left: 2px !important; }
.flatpickr-day {
  height: 28px !important;
  line-height: 28px !important;
  font-size: 11px !important;
  max-width: 28px !important;
  border-radius: 4px !important;
  margin: 1px !important;
  justify-content: center !important;
  text-align: center !important;
}
.dayContainer {
  min-width: 210px !important;
  max-width: 210px !important;
  padding: 2px 0 !important;
  justify-content: flex-start !important;
}
.flatpickr-day { flex-basis: 28px !important; }
.flatpickr-days { min-width: 210px !important; max-width: 210px !important; }
.flatpickr-calendar.multiMonth .flatpickr-days { min-width: 420px !important; max-width: 420px !important; }
.flatpickr-innerContainer { max-width: none !important; }
.flatpickr-rContainer { padding: 4px 0 !important; }
.flatpickr-weekdays { padding: 0 !important; width: 210px !important; }
.flatpickr-calendar.multiMonth .flatpickr-weekdays { width: 420px !important; }
.flatpickr-weekdaycontainer { min-width: 210px !important; max-width: 210px !important; }
.flatpickr-weekwrapper { display: none !important; }
.flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n+2) .flatpickr-day.inRange:nth-child(7n+1) { box-shadow: none !important; }

/* Month divider */
.dayContainer + .dayContainer { box-shadow: -1px 0 0 var(--color-border) !important; }

/* Flatpickr footer */
.flatpickr-footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 6px;
  padding: 15px 12px;
  border-top: 1px solid;
}
.flatpickr-footer .fp-btn {
  font-size: 9px;
  font-family: 'IBM Plex Sans', sans-serif;
  padding: 0px 8px;
  border-radius: 4px;
  border: 1px solid;
  cursor: pointer;
  transition: all 0.15s;
}

/* ─�� Flatpickr — dark theme (uses CSS variables) ── */
.flatpickr-dark.flatpickr-calendar {
  background: var(--color-bg2);
  border: 1px solid var(--color-border);
  /* Black-based shadow: subtle drop on light, invisible on dark
     (border handles separation there). Avoids the "glow" that an
     ink-based mix produces when ink is near-white in dark themes. */
  box-shadow: 0 12px 36px rgba(0, 0, 0, 0.25);
}
.flatpickr-dark .flatpickr-months,
.flatpickr-dark .flatpickr-month { background: var(--color-bg2); color: var(--color-ink); }
.flatpickr-dark .flatpickr-current-month .flatpickr-monthDropdown-months { background: var(--color-bg2); color: var(--color-ink); }
.flatpickr-dark .flatpickr-current-month input.cur-year { color: var(--color-ink); }
.flatpickr-dark .flatpickr-current-month .cur-month { color: var(--color-ink); }
.flatpickr-dark .flatpickr-months .flatpickr-prev-month,
.flatpickr-dark .flatpickr-months .flatpickr-next-month { color: var(--color-muted); fill: var(--color-muted); }
.flatpickr-dark .flatpickr-months .flatpickr-prev-month:hover,
.flatpickr-dark .flatpickr-months .flatpickr-next-month:hover { color: var(--color-ink) !important; fill: var(--color-ink) !important; background: transparent !important; }
.flatpickr-dark .flatpickr-months .flatpickr-prev-month:hover svg,
.flatpickr-dark .flatpickr-months .flatpickr-next-month:hover svg { fill: var(--color-ink) !important; }
.flatpickr-dark .flatpickr-weekdays { background: var(--color-bg2); }
.flatpickr-dark span.flatpickr-weekday { color: var(--color-dim); background: var(--color-bg2); }
.flatpickr-dark .flatpickr-day { color: var(--color-ink); border-color: transparent; }
/* Hover: subtle ink tint (matches filter/dropdown hover pattern) */
.flatpickr-dark .flatpickr-day:hover {
  background: var(--color-bg3);
  border-color: transparent;
  color: var(--color-ink);
}
/* Today: accent blue border — informational "this is today" signal */
.flatpickr-dark .flatpickr-day.today { border-color: var(--color-accent); }
/* Selected / range boundaries: ink fill (primary selection, monochrome direction) */
.flatpickr-dark .flatpickr-day.selected,
.flatpickr-dark .flatpickr-day.startRange,
.flatpickr-dark .flatpickr-day.endRange {
  background: var(--color-ink);
  border-color: var(--color-ink);
  color: var(--color-on-ink);
}
/* Range interior: subtle ink tint */
.flatpickr-dark .flatpickr-day.inRange {
  background: color-mix(in srgb, var(--color-ink) 10%, transparent);
  border-color: transparent;
  box-shadow: none;
  color: var(--color-ink);
}
.flatpickr-dark .flatpickr-day.today.inRange {
  background: color-mix(in srgb, var(--color-ink) 10%, transparent);
  border-color: var(--color-accent);
  color: var(--color-ink);
}
.flatpickr-dark .flatpickr-day.flatpickr-disabled,
.flatpickr-dark .flatpickr-day.prevMonthDay,
.flatpickr-dark .flatpickr-day.nextMonthDay { color: var(--color-dim); }
.flatpickr-dark .flatpickr-innerContainer .flatpickr-rContainer + .flatpickr-rContainer { border-left: 1px solid var(--color-border); }
.flatpickr-dark .flatpickr-footer { border-color: var(--color-border); }
.flatpickr-dark .fp-btn-reset { background: transparent; border-color: var(--color-border2); color: var(--color-ink); }
.flatpickr-dark .fp-btn-reset:hover { background: var(--color-bg3); color: var(--color-ink); border-color: var(--color-border2); }
.flatpickr-dark .fp-btn-apply { background: var(--color-ink); border-color: var(--color-ink); color: var(--color-on-ink); }
.flatpickr-dark .fp-btn-apply:hover { opacity: 0.9; }

/* ── Flatpickr — mobile single-month ── */
@media (max-width: 640px) {
  .flatpickr-calendar {
    width: calc(100vw - 32px) !important;
    max-width: calc(100vw - 32px) !important;
    left: 16px !important;
  }
  .flatpickr-month + .flatpickr-month { display: none !important; }
  .flatpickr-weekdaycontainer + .flatpickr-weekdaycontainer { display: none !important; }
  .dayContainer + .dayContainer { display: none !important; }
  .flatpickr-innerContainer, .flatpickr-rContainer { width: 100% !important; }
  .flatpickr-days, .flatpickr-weekdays { min-width: unset !important; max-width: 100% !important; width: 100% !important; }
  .flatpickr-weekdaycontainer, .dayContainer { min-width: unset !important; max-width: 100% !important; width: 100% !important; }
  .flatpickr-day { max-width: unset !important; flex-basis: calc(100% / 7 - 4px) !important; }
}

/* ── Form inputs — global style ── */
.form-input {
  width: 100%;
  padding: 0.625rem 0.875rem;
  background: var(--color-bg3);
  border: 1px solid var(--color-border);
  border-radius: 0.5rem;
  font-size: 13px;
  color: var(--color-ink);
  outline: none;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.form-input.input-sm { padding: 8px 0.875rem; }
.form-input::placeholder { color: var(--color-dim); }
.form-input:hover { border-color: var(--color-border2); }
.form-input:focus { border-color: color-mix(in srgb, var(--color-ink) 40%, transparent); box-shadow: 0 0 0 3px var(--focus-ring); }
.form-input.input-error { border-color: color-mix(in srgb, var(--color-danger) 50%, transparent) !important; box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-danger) 10%, transparent) !important; }
/* Inside `.input-group`, the inner `.form-input` has `border: none !important`,
   so the `.input-error` border lives on the GROUP itself. Propagate via :has()
   so JS keeps applying `.input-error` to the input — no DOM walk required. */
.input-group:has(> .form-input.input-error),
.input-group:has(.num-input > input.input-error) { border-color: color-mix(in srgb, var(--color-danger) 50%, transparent) !important; box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-danger) 10%, transparent) !important; }
.form-input:disabled,
.form-input[readonly] { opacity: 0.6; cursor: not-allowed; background: var(--color-bg3); }

/* ── Number input spinner (custom) ── */
input[type="number"] { -webkit-appearance: textfield; -moz-appearance: textfield; appearance: textfield; }
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; display: none; }
.num-input { position: relative; display: flex; width: 100%; }
.num-input > input[type="number"] { flex: 1; padding-right: 32px !important; }
.num-input-btns { position: absolute; right: 1px; top: 1px; bottom: 1px; display: flex; flex-direction: column; width: 28px; }
.num-input-btn { flex: 1; display: flex; align-items: center; justify-content: center; cursor: pointer; color: var(--color-dim); transition: color 0.1s; background: none; border: none; padding: 0; }
.num-input-btn:hover { color: var(--color-ink); }
.num-input-btn:first-child { border-radius: 0; }
.num-input-btn:last-child { border-radius: 0; }
.num-input-btn svg { width: 12px; height: 12px; }
.input-group .num-input-btns { border-left: 1px solid var(--color-border); }
.input-group .num-input-btn:first-child { border-radius: 0; }
.input-group .num-input-btn:last-child { border-radius: 0; }

/* ── Tom Select tags mode ── */
.ts-tags + .ts-wrapper.multi .ts-control,
.ts-wrapper.multi.ts-tags .ts-control { padding: 6px 10px !important; gap: 4px; min-height: 38px !important; }
.ts-tags + .ts-wrapper.multi .ts-control .item,
.ts-wrapper.multi.ts-tags .ts-control .item {
  background: color-mix(in srgb, var(--color-ink) 8%, transparent) !important;
  color: var(--color-ink) !important;
  border: 1px solid color-mix(in srgb, var(--color-ink) 12%, transparent) !important;
  border-radius: 4px !important;
  padding: 2px 6px !important;
  font-size: 12px !important;
  font-weight: 500 !important;
}
.ts-tags + .ts-wrapper.multi .ts-control .item,
.ts-wrapper.multi.ts-tags .ts-control .item { padding-right: 0 !important; }
.ts-tags + .ts-wrapper.multi .ts-control .item .remove,
.ts-wrapper.multi.ts-tags .ts-control .item .remove {
  color: var(--color-muted) !important;
  margin-left: 4px;
  border: none !important;
  transition: color 0.15s ease;
}
.ts-tags + .ts-wrapper.multi .ts-control .item .remove:hover,
.ts-wrapper.multi.ts-tags .ts-control .item .remove:hover { color: var(--color-danger) !important; }
.ts-tags + .ts-wrapper.multi .ts-control > input,
.ts-wrapper.multi.ts-tags .ts-control > input { font-size: 12px !important; }

/* Compact tom-select — matches an `.input-sm` row (e.g. a compact composer row).
   The `.single`/`.multi` qualifier out-specifies the themed control padding in
   tom-select-dark.css (which loads after this file at equal specificity). */
.ts-wrapper.single.ts-sm .ts-control,
.ts-wrapper.multi.ts-sm .ts-control { min-height: 0 !important; padding-top: 8px !important; padding-bottom: 8px !important; }

/* ── Tiptap Editor ── */
.tiptap-wrap { transition: border-color 0.15s, box-shadow 0.15s; }
.tiptap-wrap.tiptap-focused { border-color: color-mix(in srgb, var(--color-ink) 40%, transparent); box-shadow: 0 0 0 3px var(--focus-ring); }
.tiptap-content .tiptap { padding: 10px 14px; min-height: 150px; outline: none; color: var(--color-ink); font-size: 13px; line-height: 1.6; }
.tiptap-content .tiptap p { margin: 0 0 0.5em; }
.tiptap-content .tiptap p:last-child { margin-bottom: 0; }
.tiptap-content .tiptap h2 { font-size: 16px; font-weight: 600; margin: 0 0 0.5em; }
.tiptap-content .tiptap ul,
.tiptap-content .tiptap ol { padding-left: 1.5em; margin: 0 0 0.5em; }
.tiptap-content .tiptap li { margin-bottom: 0.2em; }
.tiptap-content .tiptap p.is-editor-empty:first-child::before { content: attr(data-placeholder); color: var(--color-dim); pointer-events: none; float: left; height: 0; }
[data-theme="light"] .tiptap-wrap { background-color: var(--color-white); }
[data-theme="light"] .tiptap-content .tiptap { background-color: var(--color-white); }

/* ── Input group (outer border wraps input + addon) ── */
.input-group { display: flex; align-items: stretch; padding: 4px; background: var(--color-bg3); border: 1px solid var(--color-border); border-radius: 0.5rem; transition: border-color 0.15s, box-shadow 0.15s; }
.input-group:focus-within { border-color: color-mix(in srgb, var(--color-ink) 40%, transparent); box-shadow: 0 0 0 3px var(--focus-ring); }
.input-group > .form-input,
.input-group > .num-input > input { border: none !important; background: transparent !important; border-radius: 0 !important; box-shadow: none !important; }
.input-group > .form-input { flex: 1; }
.input-group > .form-input:focus,
.input-group > .num-input > input:focus { box-shadow: none !important; }
.input-group > .num-input { flex: 1; }
.input-group > .num-input .num-input-btns { position: static; border: none; }
.input-group > .num-input .num-input-btn:first-child { border-radius: 0; border-bottom: none; }
.input-group > .num-input .num-input-btn:last-child { border-radius: 0; }
.input-group > .input-group-addon { display: inline-flex; align-items: center; padding: 0 12px; border: 1px solid var(--color-border); border-radius: 0.375rem; font-size: 12px; color: var(--color-dim); white-space: nowrap; }
.input-group.input-group-flat { padding: 0; overflow: hidden; }
.input-group.input-group-flat > .input-group-addon { border: none; border-left: 1px solid var(--color-border); border-radius: 0; padding: 0 10px; background: color-mix(in srgb, var(--color-bg3) 50%, transparent); }
/* Prefix variant — when the addon is the FIRST child, the separator
   needs to sit on its RIGHT edge (between addon and input), not the
   left edge (which would clash with the parent's outer border). */
.input-group.input-group-flat > .input-group-addon:first-child { border-left: none; border-right: 1px solid var(--color-border); }
.input-group > .ts-wrapper { min-width: 70px !important; width: 70px !important; flex-shrink: 0; }
.input-group > .ts-wrapper .ts-control { border: 1px solid var(--color-border) !important; border-radius: 0.375rem !important; background: transparent !important; box-shadow: none !important; }
[data-theme="light"] .input-group { background: var(--color-white); }
[data-theme="light"] .input-group > .ts-wrapper .ts-control { background: transparent !important; }

/* ── TomSelect error state ──
   `.input-error` cannot live on the underlying <select> when TomSelect
   is attached: Vue's reactive class binding would clobber TomSelect's
   imperatively-added `tomselected` class, which un-exempts the element
   from the FOUC-guard rule and re-renders the native browser select on
   top of the wrapper. Instead, the parent element gets a `.ts-error`
   modifier — this rule paints the visible `.ts-control` with the same
   danger ring used by `.form-input.input-error` above.

   `.ts-wrapper.single`/`.multi` qualifiers are required to outweigh the
   matching rule in `/public/css/tom-select-dark.css` (loaded later in
   `UserLayout.blade.php`) which uses the same specificity without our
   `.ts-error` prefix. Hover override below covers the same case so
   hovering the errored control keeps the red ring. */
.ts-error .ts-wrapper.single .ts-control,
.ts-error .ts-wrapper.multi .ts-control,
.ts-error .ts-wrapper.single .ts-control:hover,
.ts-error .ts-wrapper.multi .ts-control:hover {
  border-color: color-mix(in srgb, var(--color-danger) 50%, transparent) !important;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-danger) 10%, transparent) !important;
}

/* ── Native select ── */
.form-select {
  padding: 0.625rem 2rem 0.625rem 0.875rem;
  background: var(--color-bg3) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12'%3E%3Cpath d='M3 4.5l3 3 3-3' stroke='%236b7a99' stroke-width='1.3' stroke-linecap='round' fill='none'/%3E%3C/svg%3E") no-repeat right 10px center;
  border: 1px solid var(--color-border);
  border-radius: 0.5rem;
  font-size: 13px;
  color: var(--color-ink);
  outline: none;
  appearance: none;
  cursor: pointer;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.form-select.input-sm { padding: 8px 2rem 8px 0.875rem; }
.form-select:hover { border-color: var(--color-border2); }
.form-select:focus { border-color: color-mix(in srgb, var(--color-ink) 40%, transparent); box-shadow: 0 0 0 3px var(--focus-ring); }

/* ── Tooltip ── */
.tooltip-trigger { position: relative; display: inline-flex; }
.tooltip-content { position: fixed; background: #1a1a2e; color: #fff; font-size: 12px; font-weight: 400; line-height: 1.4; padding: 8px 12px; border-radius: 8px; max-width: 320px; white-space: normal; pointer-events: none; opacity: 0; transition: opacity 0.15s; z-index: 9999; text-transform: none; letter-spacing: 0; }
.tooltip-content::after { content: ''; position: absolute; top: 100%; left: 50%; transform: translateX(-50%); border: 5px solid transparent; border-top-color: #1a1a2e; }
.tooltip-content.tooltip-below::after { top: auto; bottom: 100%; border-top-color: transparent; border-bottom-color: #1a1a2e; }
.tooltip-trigger:hover .tooltip-content { opacity: 1; }

/* ── Required label asterisk ── */
label.required::after { content: ' *'; color: var(--color-danger); }

/* ── Toggle switch ── */
.toggle-switch { position: relative; display: inline-block; width: 36px; height: 20px; flex-shrink: 0; }
.toggle-switch input { opacity: 0; width: 0; height: 0; }
.toggle-switch .toggle-slider { position: absolute; inset: 0; background: var(--color-border); border-radius: 999px; cursor: pointer; transition: background 0.2s; }
.toggle-switch .toggle-slider::before { content: ''; position: absolute; left: 2px; top: 2px; width: 16px; height: 16px; background: var(--color-white); border-radius: 50%; transition: transform 0.2s; }
.toggle-switch input:checked + .toggle-slider { background: var(--color-accent); }
.toggle-switch input:checked + .toggle-slider::before { transform: translateX(16px); }


/* ── Action dropdown ── */
.action-dropdown { box-shadow: var(--shadow-dropdown, 0 4px 6px -1px rgba(0,0,0,.1), 0 2px 4px -2px rgba(0,0,0,.1)); }

/* ── Table headers ── */
.tbl-head th {
  font-size: 11px;
  font-family: 'IBM Plex Sans', sans-serif;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-tbl-head-text);
  font-weight: 500;
  padding: 12px 16px;
  background: var(--color-tbl-head-bg);
  border-bottom: 1px solid color-mix(in srgb, var(--color-border) 30%, transparent);
  white-space: nowrap;
}

/* Sort button in table headers — inherits the tbl-head font so the label keeps its uppercase
   styling; the sort indication is grey-on-grey (active triangle full, the other dimmed), never
   the accent colour. */
.th-sort { display: inline-flex; align-items: center; gap: 4px; cursor: pointer; user-select: none; font: inherit; color: inherit; text-transform: uppercase; letter-spacing: 0.06em; transition: color 0.15s; }
.th-sort:hover { color: var(--color-ink); }
.sort-icon { display: inline-flex; flex-direction: column; gap: 1px; opacity: 0.3; transition: opacity 0.15s; }
.th-sort:hover .sort-icon { opacity: 0.5; }
.sort-icon .arrow-up, .sort-icon .arrow-down { width: 0; height: 0; border-left: 3.5px solid transparent; border-right: 3.5px solid transparent; transition: opacity 0.15s; }
.sort-icon .arrow-up { border-bottom: 4px solid currentColor; }
.sort-icon .arrow-down { border-top: 4px solid currentColor; }
.th-sort.asc .sort-icon, .th-sort.desc .sort-icon { opacity: 1; }
.th-sort.asc .sort-icon .arrow-down, .th-sort.desc .sort-icon .arrow-up { opacity: 0.25; }

/* Table row hover */
.tbl-row-hover:hover { background: var(--color-bg3); }

/* Subtle section row background (matches tbl-head) */
.bg-section { background: var(--color-bg2); }

.tbl-body td {
  padding: 10px 16px;
  font-size: 13px;
  border-bottom: 1px solid var(--color-border);
  vertical-align: middle;
  white-space: nowrap;
}

/* ── Sub-table ── */
.products-row > td { padding: 0 !important; }

.sub-tbl th {
  font-size: 10px;
  font-family: 'IBM Plex Sans', sans-serif;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-muted);
  font-weight: 500;
  padding: 8px 16px;
  background: var(--color-bg3);
  border-bottom: 1px solid var(--color-border);
  white-space: nowrap;
  text-align: left;
}
.sub-tbl th:nth-child(5),
.sub-tbl th:nth-child(6),
.sub-tbl th:nth-child(7) { text-align: right; }
.sub-tbl th:nth-child(5) { width: 80px; }
.sub-tbl th:nth-child(6),
.sub-tbl th:nth-child(7) { width: 110px; }

.sub-tbl td {
  padding: 12px 16px;
  font-size: 13px;
  color: var(--color-muted);
  border-bottom: 1px solid var(--color-border);
  white-space: nowrap;
  vertical-align: middle;
}
.sub-tbl tbody tr:last-child td { border-bottom: none; }
.sub-tbl td:nth-child(5),
.sub-tbl td:nth-child(6),
.sub-tbl td:nth-child(7) { text-align: right; }
.sub-tbl td:nth-child(7) { color: var(--color-ink); }

/* ── Reusable: thumb — item image/placeholder box ── */
.thumb img { width: 100%; height: 100%; max-width: 100%; max-height: 100%; object-fit: contain; display: block; }

/* ── Reusable: link-dashed — inline link with dashed underline on hover ── */
.link-dashed { border-bottom: 1px dashed transparent; cursor: pointer; }
.link-dashed:hover { border-bottom-color: currentColor; }

/* ── Table grouped sub-header (e.g. Stock Flow) ── */
.col-group-label {
  text-align: center;
  border-bottom: 1px solid var(--color-border);
  padding-bottom: 4px !important;
  color: var(--color-dim);
}

.tbl-sub-head th {
  padding-top: 4px !important;
  padding-bottom: 8px !important;
  text-align: right;
}

/* ── Sortable column headers ── */
.sort {
  display: flex;
  align-items: center;
  gap: 4px;
  width: 100%;
  cursor: pointer;
  user-select: none;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  transition: color 0.15s;
}
.sort.sort-right { justify-content: flex-end; }
.sort:hover { color: var(--color-ink); }
.sort-icon {
  display: inline-flex;
  flex-direction: column;
  gap: 1px;
  opacity: 0.35;
  transition: opacity 0.15s;
}
.sort:hover .sort-icon { opacity: 0.6; }
.sort-icon .arrow-up,
.sort-icon .arrow-down {
  width: 0; height: 0;
  border-left: 3.5px solid transparent;
  border-right: 3.5px solid transparent;
  transition: opacity 0.15s;
}
.sort-icon .arrow-up { border-bottom: 4px solid currentColor; }
.sort-icon .arrow-down { border-top: 4px solid currentColor; }
.sort.asc { color: var(--color-accent); }
.sort.asc .sort-icon { opacity: 1; }
.sort.asc .sort-icon .arrow-up { opacity: 1; }
.sort.asc .sort-icon .arrow-down { opacity: 0.2; }
.sort.desc { color: var(--color-accent); }
.sort.desc .sort-icon { opacity: 1; }
.sort.desc .sort-icon .arrow-up { opacity: 0.2; }
.sort.desc .sort-icon .arrow-down { opacity: 1; }

/* ── Filters panel: always hidden on desktop ── */
@media (min-width: 768px) {
  #filters-panel { display: none !important; }
}

/* ─────────────────────────────────────────────
   Toast Notifications (Sonner-style)
   ───────────────────────────────────────────── */
.toast-container {
  position: fixed;
  top: 24px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 9999;
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: none;
  max-width: 380px;
  width: 100%;
}

.toast {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  background: var(--color-bg2);
  border: 1px solid var(--color-border);
  border-radius: 10px;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.35), 0 2px 6px rgba(0, 0, 0, 0.2);
  pointer-events: all;
  overflow: hidden;
  animation: toast-in 0.3s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

.toast-exit {
  animation: toast-out 0.2s ease forwards;
}

@keyframes toast-in {
  from { opacity: 0; transform: translateY(-12px) scale(0.96); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes toast-out {
  from { opacity: 1; transform: translateY(0) scale(1); }
  to   { opacity: 0; transform: translateY(-12px) scale(0.96); }
}

.toast-icon {
  flex-shrink: 0;
  margin-top: 1px;
}

/* Modal close icon button — rotate animates on hover-in only, snaps back on
   leave (no reverse animation). Unified across blade x-modal + Vue modals. */
.modal-close-btn {
  color: var(--color-muted);
  transition: color 0.15s ease;
  cursor: pointer;
  background: transparent;
  border: none;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.modal-close-btn:hover { color: var(--color-ink); }
.modal-close-btn svg { transition: none; }
.modal-close-btn:hover svg {
  transform: rotate(90deg);
  transition: transform 0.25s ease;
}
.modal-close-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-ink) 15%, transparent);
  border-radius: 4px;
}

/* Toast icons inherit their stroke/fill from `color` via currentColor so
   they reflow with the theme tokens (no hardcoded hexes in the JS). */
.toast-success .toast-icon { color: var(--color-accent3); }
.toast-error   .toast-icon { color: var(--color-danger); }
.toast-info    .toast-icon { color: var(--color-accent); }
.toast-warning .toast-icon { color: var(--color-accent4); }

.toast-content {
  flex: 1;
  min-width: 0;
}

.toast-message {
  font-size: 13px;
  font-weight: 400;
  color: var(--color-ink);
  line-height: 1.4;
  margin: 0;
}

.toast-description {
  font-size: 12px;
  color: var(--color-muted);
  line-height: 1.4;
  margin: 3px 0 0;
}

.toast-close {
  flex-shrink: 0;
  background: none;
  border: none;
  padding: 2px;
  color: var(--color-dim);
  cursor: pointer;
  border-radius: 4px;
  transition: color 0.15s, background 0.15s;
  margin-top: 0;
}
.toast-close:hover {
  color: var(--color-ink);
  background: rgba(255, 255, 255, 0.06);
}

/* ── Progress bar ── */
.toast-progress {
  position: absolute;
  bottom: 0;
  left: 0;
  height: 2px;
  border-radius: 0 0 0 10px;
  background: rgba(255, 255, 255, 0.15);
  animation: toast-progress linear forwards;
}
.toast-success .toast-progress { background: var(--color-accent3); }
.toast-error   .toast-progress { background: var(--color-danger); }
.toast-info    .toast-progress { background: var(--color-accent); }
.toast-warning .toast-progress { background: var(--color-accent4); }

.toast:hover .toast-progress {
  animation-play-state: paused;
}

@keyframes toast-progress {
  from { width: 100%; }
  to   { width: 0%; }
}

/* ── Type accents — subtle left border ── */
.toast-success { border-left: 3px solid var(--color-accent3); }
.toast-error   { border-left: 3px solid var(--color-danger); }
.toast-info    { border-left: 3px solid var(--color-accent); }
.toast-warning { border-left: 3px solid var(--color-accent4); }

/* ── Mobile ── */
@media (max-width: 480px) {
  .toast-container {
    top: 16px;
    left: 16px;
    right: 16px;
    transform: none;
    max-width: none;
  }
}

/* ── Sonner (vue-sonner) — monochrome override ── */
[data-sonner-toaster] {
  --normal-bg: var(--color-toast-bg) !important;
  --normal-text: var(--color-ink) !important;
  --normal-border: var(--color-border) !important;
  --success-bg: var(--color-toast-bg) !important;
  --success-text: var(--color-ink) !important;
  --success-border: var(--color-border) !important;
  --error-bg: var(--color-toast-bg) !important;
  --error-text: var(--color-ink) !important;
  --error-border: var(--color-border) !important;
  --info-bg: var(--color-toast-bg) !important;
  --info-text: var(--color-ink) !important;
  --info-border: var(--color-border) !important;
  --warning-bg: var(--color-toast-bg) !important;
  --warning-text: var(--color-ink) !important;
  --warning-border: var(--color-border) !important;
}
[data-sonner-toast] {
  font-size: 13px !important;
  /* Clip the ::before progress bar to the toast's rounded corners. */
  overflow: hidden !important;
}
[data-sonner-toast] [data-icon] { display: none !important; }
[data-sonner-toast][data-styled='true'] { padding: 16px !important; }

/* Progress bar (auto-dismiss countdown) — uses ::before so it doesn't
   collide with Sonner's ::after (used as a hover-gap spacer on expand).
   Stays visible during hover/expand; only paused, not reset. */
[data-sonner-toast][data-styled='true']::before {
  content: '' !important;
  position: absolute !important;
  top: auto !important;
  right: auto !important;
  left: 0 !important;
  bottom: 0 !important;
  height: 2px !important;
  width: 100% !important;
  background: var(--color-accent);
  transform-origin: left center;
  animation: prim-toast-progress 5s linear forwards;
  pointer-events: none;
  z-index: 1;
}
[data-sonner-toast][data-type='success']::before { background: var(--color-accent3); }
[data-sonner-toast][data-type='error']::before   { background: var(--color-danger); }
[data-sonner-toast][data-type='info']::before    { background: var(--color-accent); }
[data-sonner-toast][data-type='warning']::before { background: var(--color-accent4); }
[data-sonner-toaster]:hover [data-sonner-toast]::before {
  animation-play-state: paused;
}
@keyframes prim-toast-progress {
  from { transform: scaleX(1); }
  to   { transform: scaleX(0); }
}
[data-sonner-toast] [data-button],
.uno-toast-action,
.uno-toast-cancel {
  background: var(--color-ink) !important;
  color: var(--color-on-ink) !important;
  border: 1px solid var(--color-ink) !important;
  border-radius: 0.25rem !important;
  padding: 4px 10px !important;
  height: auto !important;
  font-size: 11px !important;
  font-weight: 500 !important;
  transition: opacity 0.15s ease !important;
  cursor: pointer !important;
}
[data-sonner-toast] [data-button]:hover,
.uno-toast-action:hover,
.uno-toast-cancel:hover {
  opacity: 0.9 !important;
}
[data-sonner-toast] [data-title] {
  font-weight: 500 !important;
  color: var(--color-ink) !important;
}
[data-sonner-toast] [data-description] {
  color: var(--color-muted) !important;
  font-size: 11px !important;
  margin-top: 2px !important;
}
[data-sonner-toast] [data-close-button] {
  background: var(--color-bg3) !important;
  border: 1px solid var(--color-border) !important;
  color: var(--color-muted) !important;
}
[data-sonner-toast] [data-close-button]:hover {
  color: var(--color-ink) !important;
  border-color: var(--color-border2) !important;
}
/* ─────────────────────────────────────────────
   UNENO UI — Global Style Overrides
   ───���───────────────────────────────────────── */

/* Default body surface + text color moved to resources/css/app.css @layer base
   so Tailwind utility overrides (.bg-bg3 on auth pages, etc.) win the cascade.
   Keeping unlayered body { } rules here broke layer precedence in Tailwind v4. */

/* ── Turnstile widget wrapper ── */
.turnstile-widget {
  width: 100%;
  overflow: hidden;
}

.turnstile-widget iframe {
    width: 100% !important;
}

/* ── Pagination ── */

/* ── Sidebar parent active state — just text color, no bg/border ── */
.sidebar-parent-active { color: var(--color-ink) !important; }
.sidebar-parent-active .nav-icon { color: var(--color-ink) !important; }

/* ── Link-styled buttons: pointer cursor ── */

/* ── Getting started checklist ── */
.getting-started-step {
  transition: border-color 0.15s, background 0.15s;
}
.getting-started-step:hover {
  border-color: var(--color-border2);
}

/* ── Empty state panels ── */
.empty-panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  text-align: center;
}

/* ── Card header ── */
.card-header { height: 3rem; display: flex; align-items: center; padding-left: 1rem; padding-right: 1rem; flex-shrink: 0; }

/* ── Custom Checkbox ────────────────────────── */
.custom-check {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  position: relative;
}
.custom-check input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.custom-check .checkmark {
  width: 16px;
  height: 16px;
  border-radius: 3px;
  border: 1.5px solid var(--color-border);
  background: var(--color-bg3);
  transition: all 0.15s ease;
  display: flex;
  align-items: center;
  justify-content: center;
}
.custom-check .checkmark .check-icon {
  width: 11px;
  height: 11px;
  color: transparent;
  stroke-width: 2.5;
  transition: color 0.15s ease, transform 0.15s ease;
  transform: scale(0);
}
.custom-check:hover .checkmark {
  border-color: var(--color-accent);
}
.custom-check input:checked + .checkmark {
  background: var(--color-accent);
  border-color: var(--color-accent);
}
.custom-check input:checked + .checkmark .check-icon {
  color: #fff;
  transform: scale(1);
}
.custom-check input:focus-visible + .checkmark {
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-ink) 20%, transparent);
}
.custom-check + span, .custom-check ~ span { cursor: pointer; }
.custom-check input:indeterminate + .checkmark {
  background: var(--color-accent);
  border-color: var(--color-accent);
}
.custom-check input:indeterminate + .checkmark .check-icon {
  display: none;
}
.custom-check input:indeterminate + .checkmark::after {
  content: '';
  width: 8px;
  height: 2px;
  background: #fff;
  border-radius: 1px;
}

/* ── Custom Number Input ────────────────────── */

/* ── Button System ────────────────────────────
   Monochrome-primary spec (v0.9.0.0 refresh).
   Hierarchy:
     primary-btn  → ink bg + white text (default create/save)
     secondary-btn → transparent + border (cancel/back/neutral)
     ghost-btn    → transparent, hover-only bg (low-weight actions)
     accent-btn   → blue bg + white text (informational CTA — rare)
     destructive-btn → red outline → filled (delete/cancel)
   ───────────────────────────────────────────── */
.primary-btn {
  padding: 0.375rem 0.75rem;
  background: var(--color-ink);
  color: var(--color-on-ink);
  font-size: 13px;
  font-weight: 500;
  border-radius: 0.375rem;
  transition: all 0.15s ease;
  cursor: pointer;
  border: 1px solid var(--color-ink);
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
}
.primary-btn:hover:not(:disabled) { opacity: 0.9; }
.primary-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-ink) 20%, transparent);
}
.primary-btn:disabled { opacity: 0.4; cursor: not-allowed; }

.secondary-btn {
  padding: 0.375rem 0.75rem;
  background: transparent;
  color: var(--color-muted);
  font-size: 13px;
  font-weight: 400;
  border-radius: 0.375rem;
  border: 1px solid var(--color-border);
  transition: all 0.15s ease;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
}
.secondary-btn:hover:not(:disabled) {
  color: var(--color-ink);
  border-color: var(--color-border2);
  background: var(--color-bg3);
}
.secondary-btn:focus-visible {
  outline: none;
  border-color: color-mix(in srgb, var(--color-ink) 40%, transparent);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.secondary-btn:disabled { opacity: 0.4; cursor: not-allowed; }

.ghost-btn {
  padding: 0.375rem 0.5rem;
  background: transparent;
  color: var(--color-muted);
  font-size: 13px;
  font-weight: 400;
  border-radius: 0.375rem;
  border: 1px solid transparent;
  transition: all 0.15s ease;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
}
.ghost-btn:hover:not(:disabled) {
  color: var(--color-ink);
  background: var(--color-bg3);
}
.ghost-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.ghost-btn:disabled { opacity: 0.4; cursor: not-allowed; }

/* Informational / accent CTA — use sparingly (link-style call to action).
   Most buttons should be .primary-btn (ink) instead. */
.accent-btn {
  padding: 0.375rem 0.75rem;
  background: var(--color-accent);
  color: #fff;
  font-size: 13px;
  font-weight: 500;
  border-radius: 0.375rem;
  transition: all 0.15s ease;
  cursor: pointer;
  border: 1px solid var(--color-accent);
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
}
.accent-btn:hover:not(:disabled) { opacity: 0.9; }
.accent-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 25%, transparent);
}
.accent-btn:disabled { opacity: 0.4; cursor: not-allowed; }

/* Outline CTA that solidifies on hover — reads as a quiet bordered button at
   rest (ink label, subtle border) and fills to the primary (ink) look on hover.
   Used for the account-hub app cards; reuse anywhere a low-emphasis-at-rest /
   high-emphasis-on-intent action fits. */
.outline-btn {
  padding: 0.3125rem 0.6875rem; /* between btn-sm and the default size */
  background: color-mix(in srgb, var(--color-bg3) 50%, transparent);
  color: var(--color-ink);
  font-size: 13px;
  font-weight: 500;
  border-radius: 0.375rem;
  border: 1px solid var(--color-border);
  transition: all 0.15s ease;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
}
.outline-btn:hover:not(:disabled) {
  background: var(--color-ink);
  color: var(--color-on-ink);
  border-color: var(--color-ink);
}
.outline-btn:focus-visible {
  outline: none;
  border-color: color-mix(in srgb, var(--color-ink) 40%, transparent);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.outline-btn:disabled { opacity: 0.4; cursor: not-allowed; }

/* Destructive button (delete, cancel, remove) */
.destructive-btn {
  padding: 0.375rem 0.75rem;
  background: transparent;
  color: var(--color-danger);
  font-size: 13px;
  font-weight: 400;
  border-radius: 0.375rem;
  border: 1px solid color-mix(in srgb, var(--color-danger) 40%, transparent);
  transition: all 0.15s ease;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
}
.destructive-btn:hover:not(:disabled) {
  background: var(--color-danger);
  color: #fff;
  border-color: var(--color-danger);
}
.destructive-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-danger) 25%, transparent);
}
.destructive-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

/* Toggle switch — a role=switch BUTTON that reflects an on/off state (the admin
   Apps enable/disable control). It does NOT mutate in place: clicking it opens a
   confirm modal; .switch-on reflects the active state after the round-trip. Styled
   to match the peer/sr-only checkbox switch on the features & limits page so both
   surfaces read identically (track 36×20, white 14px knob, accent when on). */
.switch {
  position: relative;
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  width: 2.25rem;   /* 36 */
  height: 1.25rem;  /* 20 */
  padding: 0;
  border-radius: 9999px;
  border: 1px solid var(--color-border);
  background: var(--color-bg3);
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}
.switch-knob {
  position: absolute;
  top: 50%;
  margin-top: -0.4375rem;   /* -7px — half the knob; vertically centred at any track height */
  left: 2px;
  width: 0.875rem;  /* 14 */
  height: 0.875rem;
  border-radius: 9999px;
  background: #fff;
  transition: transform 0.15s ease;
}
.switch-on {
  background: var(--color-accent);
  border-color: var(--color-accent);
}
.switch-on .switch-knob {
  transform: translateX(1rem);  /* 16 — symmetric 2px gap at both ends */
}
.switch:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--focus-ring);
}

/* Destructive button active state (full red background) */
.destructive-btn-active,
.destructive-btn-active:hover {
  background: var(--color-danger);
  color: #fff;
  border-color: var(--color-danger);
}

/* Button size modifiers — declared after all button classes so they win
   the cascade for padding/font-size on any button variant. */
.btn-sm { padding: 0.25rem 0.625rem; font-size: 12px; }
.btn-lg { padding: 0.5rem 1rem;      font-size: 14px; }

/* Avatar border — matches card background for clean cutout */
.border-card { border-color: var(--color-bg2); }

/* ── Image Input Component ──────────────────── */
.image-input-wrap {
  position: relative;
  display: inline-block;
}
.image-input {
  border-radius: 50%;
  background: var(--color-bg3);
  border: 2px dashed var(--color-border);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  overflow: hidden;
  position: relative;
  transition: border-color 0.2s ease;
}
.image-input:hover {
  border-color: var(--color-accent);
}
.image-input-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
}
.image-input-initials {
  color: var(--color-muted);
  font-weight: 600;
  letter-spacing: 0.05em;
  user-select: none;
}
.image-input-overlay {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  opacity: 0;
  transition: opacity 0.2s ease;
}
.image-input:hover .image-input-overlay {
  opacity: 1;
}
.image-input-remove {
  position: absolute;
  top: -2px;
  right: -2px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--color-danger);
  color: #fff;
  border: 2px solid var(--color-bg2);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: transform 0.15s ease, background 0.15s ease;
  z-index: 2;
}
.image-input-remove.hidden {
  display: none;
}
.image-input-remove:hover {
  transform: scale(1.1);
  background: color-mix(in srgb, var(--color-danger) 85%, black);
}

/* ════════════════════════════════════════════════════════════════════════════════════════
   v1.1.0 — the "uno" list design (Core admin → Rechnungen, 16.10.2026). Opt-in: nothing
   below changes a page until it uses these classes (or sits inside .card-uno).
   ════════════════════════════════════════════════════════════════════════════════════════ */

/* ── .btn-uno — a button SIZE between the default (~33px) and .btn-sm (28px): 31px. Pairs
   with a type class (.primary-btn btn-uno). The md 13px text on a whole-pixel 19px line, a
   15px icon (odd size = a crisp plus at 1×), padding 4 top / 6 bottom (mostly-lowercase
   labels sit optically low when box-centred → the content rides 1px higher). A leading icon
   brings ~3px of its own blank space (Lucide's 24-grid inset) → 3px less padding before it. */
.btn-uno { padding: 4px 14px 6px; font-size: 13px; line-height: 19px; gap: 5px; border-radius: 9999px; }
.btn-uno:has(> svg:first-child) { padding-left: 11px; }
.btn-uno svg { width: 15px; height: 15px; flex-shrink: 0; }

/* ── .card-uno — a list page as ONE card: a light grey title band (title · count · actions),
   then a white body laid onto the frame's left / right / bottom border (-1px, so the lines
   merge and its top corners curve into the grey). The frame carries the card shadow; the
   body has none. Replaces the page sub-header + the separate table card. */
.card-uno {
  --uno-band: color-mix(in srgb, var(--color-bg3) 50%, var(--color-bg2));
  --uno-field: var(--color-bg3);
  background: var(--uno-band);
  border: 1px solid var(--color-border);
  border-radius: 0.5rem;
  box-shadow: var(--shadow-card);
}
.card-uno-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 16px; }
.card-uno-body {
  margin: 0 -1px -1px;
  overflow: hidden;
  background: var(--color-bg2);
  border: 1px solid var(--color-border);
  border-radius: 0.5rem;
}

/* Fields inside the card (filters + the footer's per-page select): pills on the grey field
   fill, no border at rest — the filters are secondary, they must not draw the eye first. The
   light border shows on hover, the dark border + ring on focus (the normal .form-input /
   .ts-control / .kt-date-range-input focus rules). Placeholders a step darker (muted). The
   :root prefix outranks the light theme's white-field !important rules (loaded later). */
:root .card-uno .form-input { border-radius: 9999px; background: var(--uno-field) !important; }
:root .card-uno .ts-wrapper:is(.single, .multi) .ts-control { border-radius: 9999px !important; background-color: var(--uno-field) !important; }
:root .card-uno .kt-date-range-input { border-radius: 9999px !important; background: var(--uno-field) !important; }
:root .card-uno .form-input:not(:hover):not(:focus),
:root .card-uno .ts-wrapper:is(.single, .multi):not(.focus) .ts-control:not(:hover),
:root .card-uno .kt-date-range-input:not(:hover):not(:focus-within) { border-color: transparent !important; }
:root .card-uno .form-input::placeholder,
:root .card-uno .kt-date-range-input input::placeholder { color: var(--color-muted) !important; }
:root .card-uno .ts-wrapper .ts-control .item[data-value=""] { color: var(--color-muted) !important; }

/* ── .filters-uno — the search + filters strip in a .card-uno body. Below 1024px: search
   fills the row next to a round filter toggle (a count dot = active filters); the toggle
   opens the panel below, one filter per row, full width, „Zurücksetzen“ centred at the
   bottom. From 1024px: one row (search 240 · fields 160 · date 190), the toggle hidden. */
.filters-uno { padding: 16px; border-bottom: 1px solid var(--color-border); }
.filters-uno > form { width: 100%; }
.filters-uno-search { flex: 1 1 0; min-width: 0; }
.filters-uno-toggle {
  position: relative; display: inline-flex; flex-shrink: 0; align-self: stretch; align-items: center; justify-content: center;
  width: 38px; border-radius: 9999px; background: var(--uno-field, var(--color-bg3)); color: var(--color-muted);
  border: 1px solid transparent; cursor: pointer; transition: border-color 0.15s, color 0.15s;
}
.filters-uno-toggle svg { width: 15px; height: 15px; }
.filters-uno-toggle:hover { border-color: var(--color-border2); color: var(--color-ink); }
.filters-uno-toggle:focus-visible { outline: none; border-color: color-mix(in srgb, var(--color-ink) 40%, transparent); box-shadow: 0 0 0 3px var(--focus-ring); }
.filters-uno-toggle[data-active],
.filters-uno-toggle[aria-expanded="true"] { color: var(--color-ink); }
.filters-uno-count {
  position: absolute; top: -3px; right: -3px; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 9999px;
  background: var(--color-ink); color: var(--color-on-ink); font-size: 10px; font-weight: 500; line-height: 16px; text-align: center;
}
.filters-uno-panel { display: none; width: 100%; flex-direction: column; gap: 12px; }
.filters-uno-panel[data-open] { display: flex; }
.filters-uno-field { width: 100%; }
.filters-uno-field .kt-date-range-input { display: flex; width: 100%; box-sizing: border-box; min-width: 0; }
.filters-uno-field .kt-date-range-input input { min-width: 0; }   /* shrinks instead of pushing the pill wider */
.filters-uno-reset { display: block; width: 100%; padding: 4px 0; text-align: center; }
@media (min-width: 1024px) {
  .filters-uno-search { flex: 0 0 240px; }
  .filters-uno-toggle { display: none; }
  .filters-uno-panel,
  .filters-uno-panel[data-open] { display: contents; }
  .filters-uno-field { width: 160px; }
  .filters-uno-field--date { width: 190px; }
  .filters-uno-reset { display: inline; width: auto; padding: 0; margin-left: 8px; }   /* 20px from the last field */
}

/* ── .fp-uno — the date-range calendar of a .card-uno (tagged by Core's flatpickr init): a
   white rounded panel, round day cells (grey on hover, the chosen days black, the days
   between grey, today ringed), round month arrows, plus a quick-range list beside the
   calendar (above it on a phone) with the select rows + ✓. It opens BELOW the field (the
   field fills in live while picking a range). */
.flatpickr-calendar.fp-uno {
  background: var(--color-bg2) !important;
  border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent) !important;
  border-radius: 14px !important;
  box-shadow: 0 12px 32px rgba(8, 13, 25, 0.10), 0 2px 6px rgba(8, 13, 25, 0.04) !important;
  margin-top: 6px !important;
}
:root .flatpickr-calendar.fp-uno { margin-top: 6px !important; }   /* outranks Core's tighter .uneno-fp gap */
.flatpickr-calendar.fp-uno.open { display: inline-grid !important; grid-template-columns: auto auto; grid-template-rows: auto 1fr; }
/* v1.1.4 (Safari): flatpickr fixes its box at 307.875px; Chrome grows it around presets + days, Safari kept the narrow
   box and let the days overflow — placement then measured the narrow box and the panel ran off the window. The box
   takes its content's width in every engine (side by side only from 640px — on a phone the presets sit above). */
@media (min-width: 640px) {
  .flatpickr-calendar.fp-uno.open { width: max-content !important; max-width: calc(100vw - 16px); }
}
.fp-uno .fp-uno-presets {
  grid-column: 1; grid-row: 1 / 3; min-width: 168px; padding: 6px;
  border-right: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
  display: flex; flex-direction: column; gap: 1px; text-align: left;
}
.fp-uno > :not(.fp-uno-presets) { grid-column: 2; }
.fp-uno .fp-uno-presets button {
  position: relative; display: block; width: 100%; text-align: left; cursor: pointer;
  padding: 8px 34px 8px 12px; border-radius: 10px; font-size: 13px; line-height: 19px; color: var(--color-ink); background: transparent;
}
.fp-uno .fp-uno-presets button:hover,
.fp-uno .fp-uno-presets button:focus-visible { background: var(--color-bg3); outline: none; }
.fp-uno .fp-uno-presets button[aria-pressed="true"]::after {
  content: ''; position: absolute; right: 12px; top: 50%; width: 14px; height: 14px; transform: translateY(-50%);
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center / contain no-repeat;
}
.fp-uno .fp-uno-presets hr { margin: 4px 6px; border: 0; border-top: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent); }
.fp-uno .flatpickr-months { position: relative; padding: 4px 6px 0 !important; }   /* the ‹ › arrows anchor here, not on the panel */
.fp-uno .flatpickr-current-month,
.fp-uno .flatpickr-current-month .cur-month,
.fp-uno .flatpickr-current-month input.cur-year { font-size: 13px !important; color: var(--color-ink) !important; }
.fp-uno .flatpickr-prev-month,
.fp-uno .flatpickr-next-month { border-radius: 9999px; margin: 4px; height: 30px !important; width: 30px; padding: 0 !important; justify-content: center; }
.fp-uno .flatpickr-prev-month:hover,
.fp-uno .flatpickr-next-month:hover { background: var(--color-bg3); }
.fp-uno .flatpickr-prev-month:hover svg,
.fp-uno .flatpickr-next-month:hover svg { fill: var(--color-ink) !important; }
.fp-uno span.flatpickr-weekday { font-size: 10px !important; color: var(--color-dim) !important; text-align: center !important; padding-left: 0 !important; }
.fp-uno .flatpickr-innerContainer { padding: 0 8px 8px; }
.fp-uno .flatpickr-day {
  border-radius: 9999px !important; font-size: 12px !important; color: var(--color-ink) !important;
  border: 1px solid transparent !important; box-shadow: none !important;
}
.fp-uno .flatpickr-day.prevMonthDay,
.fp-uno .flatpickr-day.nextMonthDay { color: var(--color-dim) !important; }
.fp-uno .flatpickr-day:hover { background: var(--color-bg3) !important; }
.fp-uno .flatpickr-day.today { border-color: var(--color-border2) !important; }
.fp-uno .flatpickr-day.inRange { background: var(--color-bg3) !important; }
.fp-uno .flatpickr-day.selected,
.fp-uno .flatpickr-day.startRange,
.fp-uno .flatpickr-day.endRange { background: var(--color-ink) !important; color: var(--color-on-ink) !important; border-color: var(--color-ink) !important; }
@media (max-width: 639px) {
  .flatpickr-calendar.fp-uno.open { grid-template-columns: auto; }
  .fp-uno .fp-uno-presets { grid-column: 1; grid-row: auto; border-right: 0; border-bottom: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent); }
  .fp-uno > :not(.fp-uno-presets) { grid-column: 1; }
  .fp-uno .flatpickr-months { width: 100%; }
  /* The phone calendar stays full width with big touch cells (the 640px rule above) — as
     40px circles, 7 per row exactly: each gets (1/7 of the row − 40px) / 2 on each side. */
  .fp-uno .dayContainer { justify-content: flex-start !important; }
  .fp-uno .flatpickr-day {
    max-width: 40px !important; height: 40px !important; line-height: 40px !important; flex: 0 0 40px !important;
    margin: 2px calc(100% / 14 - 20px) !important;
  }
}

/* ── v1.1.1 (Alin 17.10, the Rechnungen review) — the .card-uno table, still opt-in (other tables keep the rules above):
   the head reads regular, in sentence case (the labels come that way), 12px, normal tracking — .tbl-head th sets
   500 · uppercase · 11px · 0.06em; the colour stays --color-tbl-head-text. A hovered row takes the card's band colour
   (half of bg3) — bg3 is the filter fields' grey and made a hovered row read as heavy as a control. */
.card-uno .tbl-head th { font-weight: 400; text-transform: none; letter-spacing: 0; font-size: 12px; }
.card-uno .table-row:hover { background: var(--uno-band); }

/* ════════════════════════════════════════════════════════════════════════════════════════
   v1.1.2 (Alin 17.10, the admin shell pass — Core test notes #18–#24): the frame marks, our lime, one avatar
   colour, the account menu in the uno look. Appended, so the rules above stay as they were.
   ════════════════════════════════════════════════════════════════════════════════════════ */

/* ── The frame marks (Alin 17.10, the website's line) ──
   uneno.eu frames its column with hairlines and puts a "+" where a divider crosses the frame. The
   admin shell already has the lines (sidebar edge, header bottom, footer top) → a "+" where they
   meet binds it to the website. 11px, two steps darker than the line (Alin: one darker than the website), centred on the 1px lines; it
   rides on the header/footer, so it follows the sidebar when it collapses. Desktop only (on a
   phone the sidebar is off-canvas — no edge to cross). */
@media (min-width: 768px) {
  .frame-mark-bottom::after,
  .frame-mark-top::before {
    content: '';
    position: absolute;
    left: -6px;
    z-index: 1;
    width: 11px;
    height: 11px;
    pointer-events: none;
    --frame-mark: color-mix(in srgb, var(--color-border2), var(--color-dim) 30%);
    background:
      linear-gradient(var(--frame-mark), var(--frame-mark)) center / 1px 100% no-repeat,
      linear-gradient(var(--frame-mark), var(--frame-mark)) center / 100% 1px no-repeat;
  }
  .frame-mark-bottom::after { bottom: -5px; }
  .frame-mark-top::before { top: -5px; }
}

/* ── Our lime (Alin 17.10) ──
   #CDEA45 (the app-icon accent) reads yellow on the dark themes → a greener step there, the same lime family.
   Used by the no-results / empty-list icon. */
:root {
  --uno-lime: #CDEA45;
}

/* ── One avatar colour (Alin 17.10) ──
   The initials sit on our base blue everywhere; the dropdown's large avatar (.user-avatar-lg, shared by admin +
   account) was violet (accent2 — the theme's rare secondary) while the header buttons beside it were blue. */
.user-avatar-lg {
  background: var(--color-accent);
}

/* ── The account menu in the uno look (Alin 17.10) ──
   Beside the language list, the same family as the uno selects: a white 14px panel with the soft shadow (was 10px +
   a heavy black one), rounded rows inset from the edge (was edge to edge), 13px ink text (was 12px muted), the
   icons a step quieter, a grey row under the pointer / on the current settings section. The header (avatar · name ·
   email) and the lines between the groups stay. Shared by admin + account. */
.user-dropdown {
  border-color: color-mix(in srgb, var(--color-border) 70%, transparent);
  border-radius: 14px;
  box-shadow: 0 12px 32px rgba(8, 13, 25, 0.10), 0 2px 6px rgba(8, 13, 25, 0.04);
}
.user-dropdown-header {
  padding-inline: 18px;   /* the avatar lines up with the row icons (6px inset + 12px) */
}
.user-dropdown-section {
  padding: 6px;
}
.user-dropdown-item {
  padding: 8px 12px;
  border-radius: 10px;
  font-size: 13px;
  color: var(--color-ink);
}
.user-dropdown-item svg {
  color: var(--color-muted);
  opacity: 1;
}
.user-dropdown-item:hover svg,
.user-dropdown-section .user-dropdown-item.active svg {
  color: var(--color-ink);
}
.user-dropdown-item.danger svg {
  color: currentColor;
}

/* ════════════════════════════════════════════════════════════════════════════════════════
   v1.1.3 — collected in Core while converting (Alin 17.–18.10): the list card without filters, the FORM card (the
   settings + account settings), 12px card corners. Still opt-in — only .card-uno / .card-uno-form pages change.
   ════════════════════════════════════════════════════════════════════════════════════════ */

/* ── A list card without filters: the table head goes white (Alin 17.10) ──
   With the filters strip the head's grey reads as the table's start (white strip between band and head); without it
   (Administratoren) the grey band and the grey head touched and read as one thick grey bar. A body that doesn't open
   with .filters-uno gives its head the card's white — automatic, no per-page switch. v1.1.4: a `.card-uno-strip` (any
   strip between band and head, e.g. the account's recurring templates over its invoices) keeps the grey head too. */
.card-uno-body:not(:has(> .filters-uno, > .card-uno-strip)) .tbl-head th {
  background: var(--color-bg2);
}

/* ── A FORM card (.card-uno-form — the settings + account settings, Alin 18.10) ──
   The uno card's anatomy (grey band · white body) + a save foot in the frame BELOW the body (the band again, so the
   body sits between title and save). Its fields keep the FORM look — white + border, 8px — not the filter pills the
   list card gives every field (filters are secondary; a form is the content). */
.card-uno-form { --uno-field: var(--color-bg3); }
[data-theme="light"] .card-uno-form,
[data-theme="duotone"] .card-uno-form { --uno-field: var(--color-white); }
:root .card-uno-form .form-input { border-radius: 0.5rem; }
:root .card-uno-form .ts-wrapper:is(.single, .multi) .ts-control { border-radius: 0.5rem !important; }
:root .card-uno-form .form-input:not(:hover):not(:focus),
:root .card-uno-form .ts-wrapper:is(.single, .multi):not(.focus) .ts-control:not(:hover) { border-color: var(--color-border) !important; }
:root .card-uno-form .form-input::placeholder { color: var(--color-dim) !important; }
.card-uno-form > .card-uno-body { margin-bottom: 0; }
/* A form card without a save foot (Zwei-Faktor, Darstellung): the body merges into the frame's bottom edge again. */
.card-uno-form > .card-uno-body:last-child { margin-bottom: -1px; }
.card-uno-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 16px; }

/* ── The uno card's corners: 12px (Alin 18.10, was 8px) ── every card — lists and settings alike. The frame and the
   white body both, so the body (which shares the frame's edge on 3 sides) stays concentric. Fields, buttons and the
   info pill keep theirs. */
.card-uno,
.card-uno-body { border-radius: 0.75rem; }

/* ════════════════════════════════════════════════════════════════════════════════════════
   v1.1.4 — the end of the admin design pass (Alin 18.–19.10, collected in Core while converting): the row ⋮ menu, the
   switch, a closed modal, the uno dialogs, the date picker's field, the dashboard (summary card, chart tooltip, a filter
   outside a card, the pill select before tom-select). Appended, so the rules above stay as they were (the strip's grey
   head and the calendar's width sit with their own rules above).
   ════════════════════════════════════════════════════════════════════════════════════════ */

/* ── A CLOSED modal backdrop is hidden, not just transparent ── the base rule only fades it to opacity 0, so the dark
   full-screen layer stayed in the page: Safari tints its toolbar from fixed elements at the top and kept it dark after
   the modal closed, until a reload. `visibility` flips after the 0.15s fade-out (and at once on open), so both fades
   are unchanged. Every modal opens/closes via `.modal-open`. */
.modal-overlay:not(.modal-open) {
  visibility: hidden;
  transition: opacity 0.15s linear, visibility 0s linear 0.15s;
}
.modal-overlay.modal-open {
  visibility: visible;
  transition: opacity 0.15s linear, visibility 0s;
}

/* ── The row ⋮ menu in the uno look (Alin 18.10) ── the account menu's family: 14px panel, a lighter edge + the soft
   shadow, 6px inset, 10px rows, the icon muted → ink under the pointer; the separator full width; the ⋮ trigger round
   (its grey circle on hover / while open). The selector carries .bg-bg2.border to outrank the flat card shadow its
   markup would otherwise catch (.bg-bg2.border.rounded-lg); the light themes take their dropdown shadow (light.css). */
.action-dropdown {
  border-color: color-mix(in srgb, var(--color-border) 70%, transparent);
  border-radius: 14px;
  padding: 6px;
}
.action-dropdown.bg-bg2.border {
  box-shadow: 0 12px 32px rgba(8, 13, 25, 0.10), 0 2px 6px rgba(8, 13, 25, 0.04);
}
.action-dropdown > :is(button, a) {
  padding: 8px 12px;
  border-radius: 10px;
}
.action-dropdown > :is(button, a):hover svg {
  color: var(--color-ink);
}
.action-dropdown > .text-danger:hover svg,
.action-dropdown > :is(button, a).text-danger svg {
  color: currentColor;
}
.action-dropdown > .h-px {
  margin-inline: -6px;
}
.action-trigger {
  border-radius: 9999px;
}

/* ── The switch's off state (Alin 18.10) ── a solid border2 track — the bordered bg3 track vanished on white; the knob
   gets a hairline shadow so it reads on both. */
.switch:not(.switch-on) {
  background: var(--color-border2);
  border-color: transparent;
}
.switch-knob {
  box-shadow: 0 1px 2px rgba(8, 13, 25, 0.15);
}

/* ── A date picker's field is not „locked“ (Alin 19.10) ── flatpickr marks its visible field readonly (it opens the
   calendar instead of typing), and `.form-input[readonly]` greys it out with a no-entry cursor. `.fp-field` on the
   picker's input keeps the normal field. */
.form-input.fp-field[readonly] {
  opacity: 1;
  cursor: pointer;
}

/* ══ The uno dialogs (Alin 18.10) ══ two kinds: a SHEET for a dialog that creates or edits a record (full height on the
   right, the uno card's anatomy — grey band · white body that scrolls · save foot in the band) and a CONFIRM for a
   dialog that asks you to decide (one white box in the middle). Opt-in: `.uno-dialog` on the modal wrapper,
   `.uno-backdrop` on its overlay. */

/* The backdrop follows the theme, each with a 4px blur that quiets the page behind it: light / duotone a soft grey veil
   (white read as a wash-out), dark a neutral black, midnight its own navy ink. */
.modal-overlay.uno-backdrop {
  background: rgba(0, 0, 0, 0.55);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}
[data-theme="midnight-blue"] .modal-overlay.uno-backdrop { background: rgba(8, 13, 25, 0.55); }
[data-theme="light"] .modal-overlay.uno-backdrop,
[data-theme="duotone"] .modal-overlay.uno-backdrop { background: #0000001a; }

.uno-dialog .modal-box {
  --uno-band: color-mix(in srgb, var(--color-bg3) 50%, var(--color-bg2));
  border-radius: 12px;
  border: 1px solid var(--color-border);
}
.uno-dialog-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; flex-shrink: 0; }
.uno-dialog-title { font-size: 14px; font-weight: 500; line-height: 20px; color: var(--color-ink); }
.uno-dialog-sub { margin-top: 2px; font-size: 12px; line-height: 18px; color: var(--color-muted); }
.uno-dialog-foot { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-shrink: 0; }
/* The × — round, its grey circle on hover (the row ⋮ trigger's family). */
.uno-dialog-close {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 28px; height: 28px; margin: -4px -6px -4px 0; border-radius: 9999px;
  color: var(--color-muted); cursor: pointer; transition: background-color 0.15s, color 0.15s;
}
.uno-dialog-close:hover { background: var(--color-bg3); color: var(--color-ink); }
.uno-dialog-close:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--focus-ring); }
.uno-dialog-close svg { width: 16px; height: 16px; }

/* SHEET — 480px (wide 640px) on the right, 12px from every edge, full height; a phone = the full screen. */
.uno-dialog--sheet { align-items: stretch; justify-content: flex-end; padding: 12px; }
.uno-dialog--sheet .modal-box {
  width: 100%; max-width: 480px; height: calc(100dvh - 24px); max-height: none;
  background: var(--uno-band);
  box-shadow: 0 16px 48px rgba(8, 13, 25, 0.14), 0 2px 8px rgba(8, 13, 25, 0.05);
  transform: translateX(32px);
  transition: transform 0.2s ease-out;
}
.uno-dialog--sheet .modal-box.uno-dialog-box--wide { max-width: 640px; }
.uno-dialog--sheet.modal-open .modal-box { transform: none; }
.uno-dialog--sheet .uno-dialog-head { padding: 16px; }
/* The white body laid onto the frame (like .card-uno-body) — the part that scrolls; the band above + below stays. */
.uno-dialog--sheet .modal-body {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  margin: 0 -1px; padding: 20px 16px;
  background: var(--color-bg2);
  border: 1px solid var(--color-border); border-radius: 12px;
}
.modal-box.uno-dialog-box.is-scrolling .modal-body { border-top: 1px solid var(--color-border); border-bottom: 1px solid var(--color-border); }
.uno-dialog--sheet .uno-dialog-foot { padding: 12px 16px; }
.uno-dialog--sheet .modal-box > form { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
@media (max-width: 639px) {
  .uno-dialog--sheet { padding: 0; }
  .uno-dialog--sheet .modal-box { max-width: none; height: 100dvh; border-radius: 0; border: 0; }
  .uno-dialog--sheet .modal-box.uno-dialog-box--wide { max-width: none; }
}

/* CONFIRM — one white box in the middle, the header menu's soft shadow, no bands. */
.uno-dialog--confirm { align-items: center; justify-content: center; padding: 16px; }
.uno-dialog--confirm .modal-box {
  width: 100%; max-width: 440px;
  background: var(--color-bg2);
  border-color: color-mix(in srgb, var(--color-border) 70%, transparent);
  box-shadow: 0 12px 32px rgba(8, 13, 25, 0.10), 0 2px 6px rgba(8, 13, 25, 0.04);
  transform: translateY(8px) scale(0.98);
  transition: transform 0.18s ease-out;
}
.uno-dialog--confirm.modal-open .modal-box { transform: none; }
.uno-dialog--confirm .uno-dialog-head { padding: 20px 20px 0; }
.uno-dialog--confirm .modal-body { padding: 8px 20px 0; font-size: 13px; line-height: 20px; color: var(--color-muted); }
.uno-dialog--confirm .uno-dialog-foot { padding: 20px; }

@media (prefers-reduced-motion: reduce) {
  .uno-dialog .modal-box,
  .uno-dialog.modal-open .modal-box { transform: none; transition: none; }
}
/* Red = only what can't be undone (deleting, ending with data deletion, throwing away typed input) — and then FILLED,
   so the decision is unmistakable. A reversible action (deactivate, archive, withdraw) is the ink primary. */
.uno-dialog .destructive-btn { background: var(--color-danger); border-color: var(--color-danger); color: #fff; font-weight: 500; }
.uno-dialog .destructive-btn:hover:not(:disabled) { background: color-mix(in srgb, var(--color-danger) 88%, #000); border-color: transparent; }

/* ── A filter field OUTSIDE a list card (Alin 19.10 — the dashboard's period in its heading row) ── `.uno-filter` gives
   a date field + a select the list card's pill: the grey field fill, no border at rest. */
.uno-filter { --uno-field: var(--color-bg3); }
:root .uno-filter .kt-date-range-input { border-radius: 9999px !important; background: var(--uno-field) !important; }
:root .uno-filter .kt-date-range-input:not(:hover):not(:focus-within) { border-color: transparent !important; }
:root .uno-filter .ts-wrapper:is(.single, .multi) .ts-control { border-radius: 9999px !important; background-color: var(--uno-field) !important; }
:root .uno-filter .ts-wrapper:is(.single, .multi):not(.focus) .ts-control:not(:hover) { border-color: transparent !important; }

/* ── A pill select BEFORE tom-select takes it over (Alin 19.10) ── until the page has loaded, the native <select> showed
   the browser's own look and jumped when tom-select replaced it. It wears the same pill from the first paint — the
   field fill, tom-select's padding + chevron, 40px (38px as .input-sm) — muted while its empty option is chosen, like
   tom-select's placeholder item. In a list card and in a `.uno-filter`. */
:root :is(.card-uno, .uno-filter) select[data-tom-select]:not(.tomselected) {
  -webkit-appearance: none;
  appearance: none;
  box-sizing: border-box;
  height: 40px;
  padding: 10px 28px 10px 14px;
  font: inherit;
  font-size: 13px;
  line-height: 18px;
  color: var(--color-ink);
  background: var(--uno-field) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12'%3E%3Cpath d='M3 4.5l3 3 3-3' stroke='%236b7a99' stroke-width='1.3' stroke-linecap='round' fill='none'/%3E%3C/svg%3E") no-repeat right 10px center / 10px 10px;
  border: 1px solid transparent;
  border-radius: 9999px;
}
:root :is(.card-uno, .uno-filter) select[data-tom-select].input-sm:not(.tomselected) { height: 38px; padding-top: 9px; padding-bottom: 9px; }
:root :is(.card-uno, .uno-filter) select[data-tom-select]:not(.tomselected):has(option[value=""]:checked) { color: var(--color-muted); }

/* ── The summary card (.card-uno-hero, Alin 19.10 — the dashboard's Überblick) ── the WHITE body carries everything (title,
   subtitle, figures); the grey frame shows only as the foot under it (no band on top — the body lies on the frame's top
   edge; pair with .card-uno-form for the foot). Over the body's top lies a PIXEL GRID — 2px squares every 3px, each its
   own random shade like a dot matrix — painted by the app on a canvas `.card-uno-hero-grid` at the card's size; the
   canvas carries the fade + the strength, its `color` is the grey the script paints with. */
.card-uno-hero > .card-uno-body { position: relative; margin-top: -1px; }
.card-uno-hero-grid {
  position: absolute;
  inset: 0 0 auto;
  height: 140px;
  pointer-events: none;
  border-radius: inherit;
  color: var(--color-muted);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, rgba(0, 0, 0, 0.6) 45%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0%, rgba(0, 0, 0, 0.6) 45%, transparent 100%);
}
[data-theme="dark"] .card-uno-hero-grid,
[data-theme="midnight-blue"] .card-uno-hero-grid { opacity: 0.6; }
.card-uno-hero > .card-uno-body > :not(.card-uno-hero-grid) { position: relative; }

/* ── The charts' tooltip (.uno-chart-tip, Alin 19.10) ── the uno look instead of ApexCharts' default: one white box with
   the menus' border + shadow, the full date as its title, a row per series — a dot, the label muted, the value right
   (tabular). ApexCharts' own wrapper stays invisible; the box is the app's (a tooltip `custom` renderer). */
.apexcharts-tooltip:has(.uno-chart-tip) {
  background: transparent !important;
  border: 0 !important;
  box-shadow: none !important;
}
.uno-chart-tip {
  min-width: 190px;
  padding: 10px 12px;
  background: var(--color-bg2);
  border: 1px solid var(--color-border);
  border-radius: 10px;
  box-shadow: var(--shadow-dropdown, 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1));
  font-size: 13px;
  line-height: 20px;
}
.uno-chart-tip-title { margin-bottom: 4px; font-size: 12px; color: var(--color-muted); }
.uno-chart-tip-row { display: flex; align-items: center; gap: 8px; }
.uno-chart-tip-dot { width: 8px; height: 8px; flex-shrink: 0; border-radius: 9999px; }
.uno-chart-tip-dot--success { background: var(--color-status-success, var(--color-accent3)); }
.uno-chart-tip-dot--warning { background: var(--color-status-warning, var(--color-accent4)); }
.uno-chart-tip-dot--danger { background: var(--color-status-danger, var(--color-danger)); }
.uno-chart-tip-dot--danger-soft { background: var(--color-status-danger-soft, color-mix(in srgb, var(--color-danger) 60%, var(--color-bg))); }
.uno-chart-tip-dot--neutral { background: var(--color-dim); }   /* e.g. a comparison line */
.uno-chart-tip-label { color: var(--color-muted); }
.uno-chart-tip-value { margin-left: auto; padding-left: 20px; color: var(--color-ink); font-weight: 500; font-variant-numeric: tabular-nums; }

/* ════════════════════════════════════════════════════════════════════════════════════════
   v1.1.5 — the account pass (Alin 20.10, collected in Core while converting the customer surface): the website's
   frame + „+“ divider, a button in a uno card's grey foot, the settings nav's danger row, the danger card, a plan
   card keeping its border on hover. Appended, so the rules above stay as they were.
   ════════════════════════════════════════════════════════════════════════════════════════ */

/* ── The account frame (the website's look, uneno.eu `.section-divider`) ──
   Two hairlines frame the 1400px column the whole page height; a full-width divider closes the header and every
   band, with a „+“ where it crosses the frame. On a narrow screen the lines sit 10px in. No `position` on .uno-frame (an
   unlayered one would beat the markup's `relative` / `sticky` utilities) — the host sets it. */
.uno-frame { --uno-frame-x: max(10px, calc((100% - 1400px) / 2)); }
.uno-frame::before {
  content: '';
  position: absolute;
  inset-block: 0;
  left: var(--uno-frame-x);
  right: var(--uno-frame-x);
  border-inline: 1px solid var(--color-border);
  pointer-events: none;
}
.uno-divider {
  position: relative;
  height: 1px;
  background: var(--color-border);
  --uno-frame-x: max(10px, calc((100% - 1400px) / 2));
}
.uno-divider::before,
.uno-divider::after {
  content: '';
  position: absolute;
  top: 0;
  z-index: 1;
  width: 11px;
  height: 11px;
  translate: -50% -50%;
  /* a shade darker than the lines (the website: #c3c8d4 on #e2e5ec) — the „+“ has to read */
  --uno-mark: color-mix(in srgb, var(--color-border2), var(--color-dim) 40%);
  background:
    linear-gradient(var(--uno-mark), var(--uno-mark)) center / 1px 100% no-repeat,
    linear-gradient(var(--uno-mark), var(--uno-mark)) center / 100% 1px no-repeat;
  pointer-events: none;
}
.uno-divider::before { left: calc(var(--uno-frame-x) + 0.5px); }
.uno-divider::after { left: calc(100% - var(--uno-frame-x) - 0.5px); }
/* The last band's divider gives way to the footer's own: the line sits ON the footer, the free space stays inside the
   page above it — whatever follows the last band (a dialog, a script). */
main > .uno-divider:not(:has(~ section)) { display: none; }

/* ── A button in a uno card's grey foot (the account's app cards): on the frame's grey the outline button's own
   half-grey fill disappears — it takes the body's white (hover unchanged — ink). */
.card-uno-foot .outline-btn:not(:hover) { background: var(--color-bg2); }

/* ── The settings section nav's danger row („Konto löschen“ — red, as in the account menu): red at rest, on hover and
   when active (its bar too) — beats .sidebar-link's hover/active ink. */
.sidebar-link.danger,
.sidebar-link.danger:hover,
.sidebar-link.danger.active { color: var(--color-danger); }
.sidebar-link.danger:hover,
.sidebar-link.danger.active { background: color-mix(in srgb, var(--color-danger) 10%, transparent); }
.sidebar-link.danger.active::before { background: var(--color-danger); }

/* ── The danger card (an app's „Meine Daten löschen“): the whole uno card red — red edges + a light-red ground (its
   band + foot), the white body laid on it without a head band (so it meets the frame's top edge too), the red outline
   button on WHITE until hover fills it. */
.card-uno.card-uno-danger {
  --uno-band: color-mix(in srgb, var(--color-danger) 5%, var(--color-bg2));
  border-color: color-mix(in srgb, var(--color-danger) 30%, transparent);
}
.card-uno-danger > .card-uno-body { border-color: color-mix(in srgb, var(--color-danger) 30%, transparent); }
.card-uno-danger > .card-uno-body:first-child { margin-top: -1px; }
.card-uno-danger .destructive-btn:not(:hover) { background: var(--color-bg2); }

/* ── Plan cards keep THEIR border on hover (the .pricing-card hover above swapped it — the plain + offer cards went grey,
   the trial card black): the card's mark is its border, hover only lifts it. The app's status tokens, else their
   palette colour. */
.pricing-card.border-border:hover { border-color: var(--color-border) !important; }
.pricing-card.border-ink:hover { border-color: var(--color-ink) !important; }
.pricing-card.border-status-warning:hover { border-color: var(--color-status-warning, var(--color-accent4)) !important; }
.pricing-card.border-status-success:hover { border-color: var(--color-status-success, var(--color-accent3)) !important; }
.pricing-card.border-accent:hover { border-color: var(--color-accent) !important; }

/* ════════════════════════════════════════════════════════════════════════════════════════
   v1.2.0 — the end of the Suite design pass (Alin 21.–23.10, collected in the Suite's + Core's app.css while converting):
   the table line, the same table on every screen (the pinned actions column), the detail page's two columns, a form
   card's date range, a sheet's table head, the tooltip's blue dot, a select in a card's band. Appended, so the rules
   above stay as they were. Moved from the apps' layered CSS: where a rule there was `!important` (a layered !important
   beat the unlayered CDN), the :root prefix here gives it the same win.
   ════════════════════════════════════════════════════════════════════════════════════════ */

/* ── The table line (Alin 15.10): a thin line between CELLS, not only between rows, at 30 % of the border colour ──
   every .tbl-head + .table-row (Core's admin + account, the Suite's lists). :where() = no weight: every other rule on a
   cell (the head's line, a row's line) still wins, as it did while this lived in the apps' layered CSS. */
:where(.tbl-head > th:not(:last-child), .table-row > td:not(:last-child)) {
  border-right-style: solid;
  border-right-width: 1px;
  border-color: color-mix(in oklab, var(--color-border) 30%, transparent);
}

/* ── The same table on every screen (Alin 22.10) ── a table keeps its desktop columns on a phone too: every cell stays
   on one line, so a long name widens the table and a small screen scrolls it sideways (the card's overflow-x-auto). A
   table that keeps a phone layout opts out with [data-phone-layout]. */
.card-uno table:not([data-phone-layout]) :is(th, td),
.uno-dialog-box table :is(th, td) {
  white-space: nowrap;
}
/* The actions column (⋮ · a builder's ↑ ↓ ×) = .tbl-actions, pinned to the right edge — the row's own fill + a line on
   its left in every row, the head cell included (it keeps the head's fill), so the rest slides under it. The line is a
   real element, not a box-shadow: Safari paints no shadow on a sticky table cell. On a desk the table's own line, on a
   small screen (where the table scrolls under it) full strength. The cell before it drops its own right border. */
.tbl-actions {
  position: sticky;
  right: 0;
  z-index: 1;
  background: var(--color-bg2);
}
.tbl-actions::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 1px;
  background: color-mix(in srgb, var(--color-border) 30%, transparent);
}
@media (max-width: 639px) {
  .tbl-actions::before { background: var(--color-border); }
}
.tbl-head > th:has(+ .tbl-actions),
.table-row > td:has(+ .tbl-actions) {
  border-right-width: 0;
}
/* The pinned cells sit a layer up, so Safari let them paint over the footer's top line — the scroll box is its own
   stacking layer, so they can only cover what's inside the table. */
.overflow-x-auto:has(.tbl-actions) { isolation: isolate; }
.card-uno .table-row:hover > .tbl-actions { background: var(--uno-band); }

/* ── A detail page's two columns (Alin 22.10 — „all right sides should be equal“) ── the main cards left, the side cards
   in ONE fixed 450px column right, from 1280px; below, one column. */
.detail-columns {
  display: grid;
  grid-template-columns: repeat(1, minmax(0, 1fr));
  align-items: flex-start;
  gap: 1.25rem;
}
@media (min-width: 1280px) {
  .detail-columns { grid-template-columns: minmax(0, 1fr) 450px; }
}

/* ── The date-range field in a FORM card (Alin 21.10 — the export builder's Zeitraum) ── a form field like its
   neighbours (8px corner, the border at rest, the field fill, 13px), not the list card's filter pill. */
:root .card-uno-form .kt-date-range-input {
  border-radius: 0.5rem !important;
  background: var(--uno-field) !important;
  padding: 10px 0.875rem !important;
}
:root .card-uno-form .kt-date-range-input:not(:hover):not(:focus-within) { border-color: var(--color-border) !important; }
:root .card-uno-form .kt-date-range-input:hover { border-color: var(--color-border2) !important; }
:root .card-uno-form .kt-date-range-input:focus-within { border-color: color-mix(in srgb, var(--color-ink) 40%, transparent) !important; }
:root .card-uno-form .kt-date-range-input input { font-size: 13px !important; }

/* ── A table inside a uno SHEET (Alin 21.10 — „Spalten bearbeiten“) ── the card's table head (sentence case, 12px,
   regular, on white), not the old uppercase grey bar. */
:root .uno-dialog-box .tbl-head th {
  font-size: 12px !important;
  font-weight: 400 !important;
  text-transform: none !important;
  letter-spacing: 0 !important;
  background: var(--color-bg2) !important;
}

/* ── The tooltip's blue dot (Alin 22.10 — the Finanzen chart's „Gestellt“) ── */
.uno-chart-tip-dot--info { background: var(--color-status-info, var(--color-accent)); }

/* ── A select in a card's BAND (Alin 22.10) ── in a card body a select is the grey field with its border on hover only;
   on the grey band that vanished — in the band it is white with its border always there, like the band's buttons. */
:root .card-uno .card-uno-head .ts-wrapper:is(.single, .multi) .ts-control { background-color: var(--color-bg2) !important; }
:root .card-uno .card-uno-head .ts-wrapper:is(.single, .multi):not(.focus) .ts-control:not(:hover) { border-color: var(--color-border) !important; }
