/*
 * Servido brand theme - overrides WowDash's default blue "primary" ramp
 * with the crimson from the Servido logo, bridges Bootstrap's own
 * (separately hardcoded) color variables into WowDash's dark-aware token
 * system, and adds a few small components WowDash doesn't ship with
 * (toast notifications, a styled confirm dialog).
 * Loaded after style.css. Ramp derived from the logo's measured brand
 * color rgb(171,28,57).
 */
:root {
  --primary-50: #F8EDEF;
  --primary-100: #F0D6DB;
  --primary-200: #E2B2BC;
  --primary-300: #D58E9C;
  --primary-400: #C35C70;
  --primary-500: #B53751;
  --primary-600: #AB1C39;
  --primary-700: #901931;
  --primary-800: #78162A;
  --primary-900: #601322;
  --primary-600-rgb: 171, 28, 57;

  --bg-color: var(--neutral-50);

  /* Bootstrap ships its own --bs-primary / --bs-body-* / --bs-border-color
     tokens, compiled from its default blue Sass theme - entirely separate
     from WowDash's --primary-*/--white/--black/--bg-color system above.
     Bridging them here means any plain Bootstrap class (.btn-primary,
     .table, .form-control:focus, checkboxes, links, badges) automatically
     follows the Servido theme and dark mode too, instead of only the
     WowDash-specific utility classes (.btn-primary-600 etc.) doing so. */
  --bs-primary: var(--primary-600);
  --bs-primary-rgb: var(--primary-600-rgb);
  --bs-link-color: var(--primary-600);
  --bs-link-color-rgb: var(--primary-600-rgb);
  --bs-link-hover-color: var(--primary-700);

  --bs-body-bg: var(--white);
  --bs-body-color: var(--text-secondary-light);
  --bs-emphasis-color: var(--text-primary-light);
  --bs-border-color: var(--border-color);
  --bs-border-color-translucent: var(--border-color);
  --bs-secondary-color: var(--text-secondary-light);
  --bs-tertiary-bg: var(--neutral-100);
}

[data-theme="dark"] {
  --primary-50: #2A1216;
}

.btn-primary {
  --bs-btn-color: #fff;
  --bs-btn-bg: var(--primary-600);
  --bs-btn-border-color: var(--primary-600);
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: var(--primary-700);
  --bs-btn-hover-border-color: var(--primary-700);
  --bs-btn-focus-shadow-rgb: var(--primary-600-rgb);
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: var(--primary-800);
  --bs-btn-active-border-color: var(--primary-800);
  --bs-btn-disabled-bg: var(--primary-300);
  --bs-btn-disabled-border-color: var(--primary-300);
}

.btn-outline-primary {
  --bs-btn-color: var(--primary-600);
  --bs-btn-border-color: var(--primary-600);
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: var(--primary-600);
  --bs-btn-hover-border-color: var(--primary-600);
  --bs-btn-focus-shadow-rgb: var(--primary-600-rgb);
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: var(--primary-600);
  --bs-btn-active-border-color: var(--primary-600);
}

.form-control:focus,
.form-select:focus {
  border-color: var(--primary-300);
  box-shadow: 0 0 0 0.25rem rgba(var(--primary-600-rgb), 0.15);
}

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

.form-check-input:focus {
  border-color: var(--primary-300);
  box-shadow: 0 0 0 0.25rem rgba(var(--primary-600-rgb), 0.15);
}

/* WowDash ties several utility classes directly to the primary-* variables,
   so the ramp swap above re-themes buttons, links, badges, and the active
   sidebar state automatically. These are the few spots that hardcode the
   old WowDash blue instead of referencing the variable. */
.text-primary-600 {
  color: var(--primary-600) !important;
}

.sidebar-menu .active-page > a,
.sidebar-menu li > a.active-page {
  background: var(--primary-600) !important;
}

/* WowDash's outline buttons are fully transparent inside, which reads as
   hollow/ghost controls next to the solid cards. Give them a soft tinted
   fill so they clearly look like buttons at rest; hover still fills solid
   via WowDash's own :hover rules. */
.btn-outline-primary-600 {
  background-color: rgba(var(--primary-600-rgb), 0.08) !important;
}

.btn-outline-danger-600 {
  background-color: rgba(239, 74, 0, 0.08) !important;
}

.btn-outline-success-600 {
  background-color: rgba(69, 179, 105, 0.1) !important;
}

.btn-outline-secondary {
  background-color: var(--neutral-100);
  color: var(--text-primary-light);
  border-color: var(--neutral-300);
}

.btn-outline-secondary:hover {
  background-color: var(--neutral-200);
  color: var(--text-primary-light);
  border-color: var(--neutral-400);
}

/* --- Toast notifications ---------------------------------------------- */
#servido-toasts {
  position: fixed;
  top: 24px;
  right: 24px;
  z-index: 1080;
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-width: 380px;
  width: calc(100% - 32px);
}

.servido-toast {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 16px;
  border-radius: 12px;
  background: var(--white);
  box-shadow: 0 12px 32px rgba(4, 6, 15, 0.16);
  border-inline-start: 4px solid var(--primary-600);
  animation: servido-toast-in 0.25s ease-out;
  color: var(--text-primary-light);
}

.servido-toast.is-leaving {
  animation: servido-toast-out 0.2s ease-in forwards;
}

.servido-toast[data-type="success"] {
  border-inline-start-color: var(--success-main, #45B369);
}

.servido-toast[data-type="error"] {
  border-inline-start-color: var(--danger-main, #EF4A00);
}

.servido-toast .servido-toast-icon {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.1rem;
  background: rgba(var(--primary-600-rgb), 0.1);
  color: var(--primary-600);
}

.servido-toast[data-type="success"] .servido-toast-icon {
  background: rgba(69, 179, 105, 0.12);
  color: var(--success-main, #45B369);
}

.servido-toast[data-type="error"] .servido-toast-icon {
  background: rgba(239, 74, 0, 0.12);
  color: var(--danger-main, #EF4A00);
}

.servido-toast-body {
  flex: 1;
  font-size: 0.9rem;
  line-height: 1.4;
  padding-top: 6px;
}

.servido-toast-close {
  background: none;
  border: none;
  color: var(--text-secondary-light);
  cursor: pointer;
  padding: 4px;
  line-height: 1;
  opacity: 0.6;
}

.servido-toast-close:hover {
  opacity: 1;
}

@keyframes servido-toast-in {
  from {
    opacity: 0;
    transform: translateY(-8px) scale(0.98);
  }

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

@keyframes servido-toast-out {
  from {
    opacity: 1;
    transform: translateX(0);
  }

  to {
    opacity: 0;
    transform: translateX(24px);
  }
}

@media (max-width: 575.98px) {
  #servido-toasts {
    top: 12px;
    right: 12px;
    left: 12px;
    max-width: none;
    width: auto;
  }
}

/* --- Confirm dialog (replaces the native browser confirm()) ------------ */
.servido-confirm-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(10, 8, 12, 0.45);
  z-index: 1090;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  animation: servido-fade-in 0.15s ease-out;
}

@keyframes servido-fade-in {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

.servido-confirm-card {
  background: var(--white);
  border-radius: 16px;
  box-shadow: 0 24px 60px rgba(4, 6, 15, 0.28);
  max-width: 380px;
  width: 100%;
  padding: 28px 24px 20px;
  text-align: center;
  animation: servido-pop-in 0.2s cubic-bezier(0.2, 0.8, 0.3, 1.1);
}

@keyframes servido-pop-in {
  from {
    opacity: 0;
    transform: scale(0.92);
  }

  to {
    opacity: 1;
    transform: scale(1);
  }
}

.servido-confirm-icon {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: rgba(239, 74, 0, 0.12);
  color: var(--danger-main, #EF4A00);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.6rem;
  margin: 0 auto 16px;
}

.servido-confirm-message {
  color: var(--text-primary-light);
  font-size: 0.95rem;
  margin-bottom: 20px;
  line-height: 1.5;
}

.servido-confirm-actions {
  display: flex;
  gap: 10px;
}

.servido-confirm-actions .btn {
  flex: 1;
}

/* --- Help icon (click-to-toggle, see components/help-icon.blade.php) --- */

.servido-help {
  position: relative;
  display: inline-flex;
  vertical-align: middle;
}

.servido-help-trigger {
  display: inline-flex;
  align-items: center;
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  line-height: 1;
  font-size: 1.1rem;
  color: var(--text-secondary-light);
  cursor: pointer;
}

.servido-help-trigger:hover,
.servido-help-trigger:focus-visible {
  color: var(--primary-600, #487FFF);
}

.servido-help-popover {
  display: none;
  position: absolute;
  z-index: 1000;
  bottom: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%);
  width: max-content;
  max-width: 260px;
  background: var(--white);
  color: var(--text-primary-light);
  border-radius: 12px;
  box-shadow: 0 12px 32px rgba(4, 6, 15, 0.16);
  padding: 12px 14px;
  font-size: 0.8125rem;
  font-weight: 400;
  line-height: 1.45;
  text-align: start;
  white-space: normal;
  animation: servido-pop-in 0.15s cubic-bezier(0.2, 0.8, 0.3, 1.1);
}

.servido-help-popover.is-open {
  display: block;
}

.servido-help-popover::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: var(--white);
}

/* --- Onboarding step icon + accented card (Settings > Citaci kartica) --- */

.servido-step-icon {
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.35rem;
}

/* A colored left border on an otherwise plain white card reads as "this
   succeeded" without the loudness of a fully-tinted background - the same
   restraint .servido-toast already uses for its success/error accent. */
.servido-accent-success {
  border-inline-start: 4px solid var(--success-main, #45B369);
}

/* --- Sidebar collapse polish --------------------------------------------
   style.css already handles the actual show/hide/collapse logic via the
   .active / .sidebar-open classes toggled in servido-nav.js; it just never
   declared a transition on .sidebar itself (only .dashboard-main has one),
   so the collapse/expand and the mobile slide-in both used to snap
   instantly instead of animating. */
.sidebar {
  transition: inset-inline-start 0.3s ease, width 0.3s ease;
}

/* --- Information density -------------------------------------------------
   Default WowDash spacing (24px page-header margin, ~13px table cells, 24px
   card padding) is generous for a marketing-style dashboard demo but wastes
   space in a data-entry tool where the point is seeing more rows/fields at
   once. Tightened globally rather than per-page so it stays consistent. */
.mb-24 {
  margin-block-end: 16px !important;
}

.card-header,
.card-body,
.card-footer {
  padding: 0.75rem 1rem;
}

/* Every card-body/-header/-footer in this app is written with an explicit
   p-24 utility class (WowDash's own !important 24px padding), which would
   otherwise override the rule just above outright. */
.p-24 {
  padding: 1rem 1.25rem !important;
}

/* --- Sidebar footer section ---------------------------------------------
   Settings lives apart from the day-to-day workflow items (Nalozi/Klijenti/
   Vozila), so it's pinned to the bottom of the sidebar with a divider and a
   quieter, more muted treatment instead of matching the main nav's weight.
   The pinning itself must be margin-top:auto - an earlier fixed 12px value
   here silently cancelled the markup's mt-auto (same !important, later in
   the cascade) and left the item sitting right under the nav. Flex on the
   container is set here too rather than relying on utility classes. */
.sidebar-menu-area {
  display: flex;
  flex-direction: column;
}

.servido-sidebar-footer-menu {
  padding-top: 12px;
  margin-top: auto !important;
  border-top: 1px solid var(--border-color);
}

.servido-sidebar-footer-menu > li > a {
  color: var(--text-secondary-light) !important;
  opacity: 0.85;
}

.servido-sidebar-footer-menu > li > a:hover {
  opacity: 1;
}

.servido-sidebar-footer-menu > li > a.active-page {
  opacity: 1;
  color: #fff !important;
}

/* --- Responsive polish -------------------------------------------------- */
@media (max-width: 575.98px) {
  .card-header,
  .card-body {
    padding: 16px !important;
  }

  .servido-confirm-actions {
    flex-direction: column-reverse;
  }
}

/* --- Dashboard secondary quick-links -------------------------------------
   Klijenti/Vozila counts on the dashboard are deliberately just clickable
   cards, not the focal point (Nalozi is) - this hover state is what signals
   they're links at all. */
.servido-quick-link {
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.servido-quick-link:hover {
  border-color: var(--primary-300) !important;
  box-shadow: 0 4px 16px rgba(var(--primary-600-rgb), 0.08);
  transform: translateY(-2px);
}

/* --- Marketing site: feature cards -----------------------------------
   Same lift-on-hover idiom as .servido-quick-link above - these cards
   aren't clickable, but the subtle motion reads as "polished product",
   not "static brochure", on the public landing page. */
.servido-feature-card {
  transition: box-shadow 0.15s ease, transform 0.15s ease;
}

.servido-feature-card:hover {
  box-shadow: 0 8px 24px rgba(var(--primary-600-rgb), 0.1);
  transform: translateY(-3px);
}

/* --- Marketing site: section rhythm, scroll effects, nav polish ----------
   The page read as visually flat with every section on the same near-white
   body background - alternating a soft brand-tinted wash in via
   .section-tint (rather than plain gray) both creates rhythm and reinforces
   the crimson brand identity through sections that aren't the hero/CTA. */
.section-tint {
  background: linear-gradient(180deg, rgba(var(--primary-600-rgb), 0.06), rgba(var(--primary-600-rgb), 0.02));
}

/* Fade/slide-in on scroll - see servido-reveal.js. Gated behind html.js
   (flipped from html.no-js by an inline script at the very top of <head>,
   see layouts/marketing.blade.php) rather than hiding unconditionally:
   content must default to visible if JS never runs at all - a blocked
   script, a network hiccup, or simply this layout missing a required
   <script> tag one day, the same mistake already made once this session
   with iconify-icon.min.js - not just fail to animate. */
.js .reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

.js .reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  .js .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* Thin fixed bar that fills with scroll position - see servido-reveal.js. */
#scroll-progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 3px;
  width: 0%;
  background: linear-gradient(90deg, var(--primary-600), var(--primary-800));
  z-index: 1040;
  transition: width 0.1s ease-out;
}

/* Growing underline on hover, instead of just a color change - matches the
   "something responded to you" motion language used elsewhere on this page
   (servido-feature-card, servido-quick-link). */
.servido-nav-link {
  position: relative;
  padding-bottom: 2px;
}

.servido-nav-link::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -2px;
  width: 0;
  height: 2px;
  background: var(--primary-600);
  transition: width 0.2s ease;
}

.servido-nav-link:hover::after {
  width: 100%;
}

/* Full-page loading screen for wire:navigate transitions - see
   servido-page-loading.js. Sits above everything (including the sticky
   header's z-index: 1030) and fades in/out rather than snapping, so a fast
   navigation doesn't flash it harshly. pointer-events only enable while
   active, so it can't silently eat clicks the rest of the time. */
#page-loading-overlay {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.85);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease;
}

#page-loading-overlay.is-active {
  opacity: 1;
  pointer-events: auto;
}

.page-loading-tire {
  font-size: 64px;
  color: var(--primary-600);
  animation: servido-tire-spin 0.8s linear infinite;
}

@keyframes servido-tire-spin {
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .page-loading-tire {
    animation: none;
  }
}

/* Replaced by #page-loading-overlay above - one loading indicator during
   navigation, not this plus a competing default top bar. */
#nprogress {
  display: none !important;
}

/* Mobile header menu toggle - hamburger/close icon swap driven purely by
   the aria-expanded attribute Bootstrap's collapse JS already sets on the
   trigger button, no extra script needed. */
.servido-menu-icon-close {
  display: none !important;
}

[data-bs-toggle="collapse"][aria-expanded="true"] .servido-menu-icon-open {
  display: none !important;
}

[data-bs-toggle="collapse"][aria-expanded="true"] .servido-menu-icon-close {
  display: block !important;
}

/* Hero carousel indicator dots - custom small circles rather than
   Bootstrap's default wide bars (.carousel-indicators), so they read as
   "photo 1 of 3" dots and not as a video scrubber. */
.servido-hero-indicators button {
  width: 8px;
  height: 8px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.45);
  transition: background-color 0.2s ease, transform 0.2s ease;
}

.servido-hero-indicators button.active {
  background: #fff;
  transform: scale(1.25);
}

/* Floating "back to top" button - hidden until scrolled past the hero
   (toggled via servido-reveal.js), not just always-on clutter on a short
   page. */
#back-to-top {
  position: fixed;
  right: 24px;
  bottom: 24px;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: none;
  background: var(--primary-600);
  color: #fff;
  font-size: 1.25rem;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 14px rgba(var(--primary-600-rgb), 0.35);
  z-index: 1020;
  opacity: 0;
  transform: translateY(12px);
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease, background-color 0.15s ease;
}

#back-to-top.is-visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

#back-to-top:hover {
  background: var(--primary-700);
}

/* Lift-on-hover for marketing-site CTA buttons specifically - a dedicated
   class, not a blanket `.btn` rule, since servido-theme.css is loaded on
   every page in the app (tenant dashboard, admin panel included) and this
   session's testing has only covered the marketing site. */
.servido-btn-lift {
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.servido-btn-lift:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
}

/* --- Marketing site: 2026 reskin (Manrope, blurred header, dark footer,
   feature icon chips, pricing/FAQ cards, signup modal) -------------------
   Everything below is scoped to .servido-marketing (set on <body> only by
   layouts/marketing.blade.php) or to dedicated .servido-* classes, never to
   bare element/Bootstrap selectors - this file loads on every page in the
   app (tenant dashboard, admin panel included), and those still use Inter/
   WowDash's own card styling untouched. */
.servido-marketing {
  font-family: 'Manrope', 'Inter', sans-serif;
}

.servido-marketing h1,
.servido-marketing h2,
.servido-marketing h3,
.servido-marketing h4,
.servido-marketing h5,
.servido-marketing h6 {
  font-family: 'Manrope', 'Inter', sans-serif;
}

/* Sticky header goes from solid white to a translucent blur once the page
   has scrolled - set/cleared by servido-reveal.js's existing scroll
   listener (same one driving #scroll-progress/#back-to-top) rather than a
   new listener. Falls back to the plain solid header (already legible)
   when JS never runs, same no-js safety net as .reveal. */
.servido-header-blur {
  background: rgba(253, 251, 250, 0.92);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}

/* Custom "PRO" pill for feature cards - crimson-tinted like the rest of the
   brand accents, replacing WowDash's default amber .bg-warning-focus pill
   which read as a warning/alert rather than an upsell badge. */
.servido-pro-badge {
  background: var(--primary-50);
  color: var(--primary-600);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.03em;
  padding: 4px 10px;
  border-radius: 999px;
}

/* 48px rounded-square icon chip for the feature grid - deliberately not
   .servido-step-icon (kept circular, 44px) since that class is also used
   for the numbered "how it works" steps and Settings' onboarding icon. */
.servido-feature-icon {
  width: 48px;
  height: 48px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

/* Pricing card: "most popular" tier gets a solid brand border + lifted
   shadow so it reads as the recommended choice without needing the ribbon
   badge (below) to do all the work on its own. */
.servido-pricing-popular {
  border: 2px solid var(--primary-600) !important;
  box-shadow: 0 20px 50px rgba(var(--primary-600-rgb), 0.14);
}

.servido-pricing-ribbon {
  position: absolute;
  top: 0;
  right: 24px;
  transform: translateY(-50%);
  background: var(--primary-600);
  color: #fff;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.02em;
  padding: 6px 14px;
  border-radius: 999px;
}

/* FAQ accordion retheme: Bootstrap's own chevron/caret is swapped for a
   plain rotating chevron (matches the rest of the icon language on this
   page) via CSS only - the accordion-button markup/JS behavior is
   untouched, so keyboard/ARIA handling stays exactly what Bootstrap
   already provides.

   Two fixes layered on top of that original retheme:

   1. WowDash's own style.css draws a second icon - a circled plus/minus -
      via .accordion-button[aria-expanded=...]::after (three
      classes/attributes deep). That beats this file's plain
      .accordion-button::after on specificity alone, so "display: none"
      here was silently losing and both icons rendered. Every variant of
      that selector now gets !important, which wins regardless of
      specificity.

   2. WowDash puts a card's entire 20px padding on .accordion-item itself
      (style.css), not on .accordion-button - confirmed live, the button's
      real clickable box was only ~19px tall, centered inside a ~61px
      visual row. Clicking the question anywhere in that surrounding
      padding (i.e. most of the row except a thin strip roughly level with
      the arrow) silently did nothing. Fix: zero the item's own padding
      and move the identical amount onto the button and body instead -
      padding is part of an element's own hit box, margin/a parent's
      padding is not, so this makes the whole visual row clickable without
      moving anything on screen by even a pixel. */
.servido-faq-item {
  border: 1px solid var(--border-color) !important;
  border-radius: 14px !important;
  overflow: hidden;
  transition: border-color 0.2s ease;
  padding: 0 !important;
}

.servido-faq-item:hover {
  border-color: var(--primary-200) !important;
}

.servido-faq-item .accordion-button {
  box-shadow: none !important;
  background: none !important;
  padding: 20px !important;
}

.servido-faq-item .accordion-body {
  padding: 8px 20px 20px !important;
}

.servido-faq-item .accordion-button::after,
.servido-faq-item .accordion-button[aria-expanded="true"]::after,
.servido-faq-item .accordion-button[aria-expanded="false"]::after {
  display: none !important;
  content: none !important;
  border: 0 !important;
  background: none !important;
}

.servido-faq-chevron {
  flex-shrink: 0;
  transition: transform 0.2s ease;
}

.servido-faq-item .accordion-button:not(.collapsed) .servido-faq-chevron {
  transform: rotate(180deg);
}

/* Final CTA: full-bleed gradient section (the section itself is the
   colored surface) instead of a rounded card floating on a white
   background - matches the 2026 mockup's treatment. */
.servido-cta-gradient {
  background: linear-gradient(135deg, var(--primary-600), var(--primary-900));
}

/* --- Marketing site: blog post body ---------------------------------------
   Rendered straight from Quill's stored HTML (see BlogPostForm's editor and
   blog-show.blade.php) - Quill applies no typography of its own on the
   *read* side (only its own editor chrome), so headings/lists/blockquotes
   need real styles here or the article reads as one undifferentiated wall
   of text. */
.servido-blog-content {
  font-size: 1.0625rem;
  line-height: 1.75;
  color: var(--text-primary-light);
}

.servido-blog-content h1,
.servido-blog-content h2,
.servido-blog-content h3 {
  font-weight: 700;
  margin-top: 2rem;
  margin-bottom: 0.75rem;
}

.servido-blog-content p {
  margin-bottom: 1.25rem;
}

.servido-blog-content ul,
.servido-blog-content ol {
  margin-bottom: 1.25rem;
  padding-left: 1.5rem;
}

.servido-blog-content img {
  max-width: 100%;
  height: auto;
  border-radius: 12px;
  margin-block: 1rem;
}

.servido-blog-content a {
  color: var(--primary-600);
  text-decoration: underline;
}

.servido-blog-content blockquote {
  border-left: 3px solid var(--primary-600);
  padding-left: 1rem;
  color: var(--text-secondary-light);
  font-style: italic;
  margin-block: 1.25rem;
}

/* --- Signup modal --------------------------------------------------------
   Visibility is plain Alpine x-show (client-side, no network round trip to
   open) wrapping the Livewire form fields underneath - see
   signup-modal.blade.php. [x-cloak] prevents a one-frame flash of the
   unstyled/open modal before Alpine has initialized on first paint. */
[x-cloak] {
  display: none !important;
}

.servido-modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 1050;
  background: rgba(20, 12, 12, 0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

.servido-modal-card {
  background: #fff;
  border-radius: 20px;
  width: 100%;
  max-width: 520px;
  max-height: 90vh;
  overflow-y: auto;
  position: relative;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.35);
}

.servido-modal-close {
  position: absolute;
  top: 18px;
  right: 18px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: none;
  background: var(--primary-50);
  color: var(--primary-600);
  font-size: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.2s ease, background-color 0.2s ease;
}

.servido-modal-close:hover {
  transform: rotate(90deg);
  background: var(--primary-100);
}

/* Plan chips inside the modal - active state driven by a Livewire-bound
   class (server round trip on click is fine, there are only two chips and
   the rest of the form already round-trips on every keystroke via
   wire:model.live elsewhere on this page). */
.servido-plan-chip {
  padding: 9px 18px;
  border-radius: 999px;
  font-size: 13.5px;
  font-weight: 700;
  cursor: pointer;
  border: 1.5px solid var(--border-color);
  background: #fff;
  color: var(--text-secondary-light);
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.servido-plan-chip.is-active {
  border-color: var(--primary-600);
  background: var(--primary-600);
  color: #fff;
}

/* ==========================================================================
   Motion & depth pass
   The template out of the box is static - no hover feedback, no transitions,
   no sense that clicking something actually did anything until the next
   page finishes loading. This section is what makes it feel like a real
   product responding to you instead of a themed document.
   ========================================================================== */

*,
*::before,
*::after {
  scroll-behavior: smooth;
}

/* --- Buttons: press feedback + smoother color transitions --------------- */
.btn {
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease,
    transform 0.1s ease, box-shadow 0.15s ease;
}

.btn:active {
  transform: scale(0.97);
}

.btn-primary:hover,
.btn-primary-600:hover {
  box-shadow: 0 4px 14px rgba(var(--primary-600-rgb), 0.28);
}

/* --- Cards: the whole app is built from them, so a touch of depth on ---- */
.card {
  transition: box-shadow 0.2s ease, transform 0.2s ease, border-color 0.2s ease;
}

/* --- Table rows: hover highlight + smooth color transitions ------------- */
.table > tbody > tr {
  transition: background-color 0.12s ease;
}

.table > tbody > tr:hover > td {
  background-color: var(--neutral-50) !important;
}

[data-theme="dark"] .table > tbody > tr:hover > td {
  background-color: var(--dark-2) !important;
}

/* --- Row-action buttons: one color per action, table-wide -----------------
   Each action keeps the same meaning everywhere it appears (Nalozi/Klijenti/
   Vozila/Pregled): green = create, purple = view details, blue = edit,
   teal = print, gray = delete.

   Two different treatments per theme, not the same colors dropped onto both
   backgrounds:
   - Dark theme: solid fill, white text. Confirmed this reads well - five
     hues sharing the same HSL saturation (58%) and lightness (33%) so they
     read as one family rather than WowDash's original mismatched
     --success-main/--info-main/--neutral-600/etc (each tuned in isolation
     elsewhere in the theme, plus --neutral-600 specifically flips too light
     in dark mode since WowDash inverts the neutral ramp there - that's what
     made the old delete button unreadable).
   - Light theme: solid fill read as heavy/flat against a white page, so
     this uses a tinted background with colored text instead (no white text
     involved, so it isn't limited to colors dark enough for 4.5:1 against
     white - can sit much lighter and still pass contrast against its own
     text).
   Every pair below (dark theme bg/white text, light theme tint bg/colored
   text) was checked and clears WCAG AA's 4.5:1 minimum. */
.btn-action-create,
.btn-action-view,
.btn-action-edit,
.btn-action-print,
.btn-action-delete {
  border: none;
}

.btn-action-create {
  background-color: #DCFCE7;
  color: #166534;
}

.btn-action-create:hover,
.btn-action-create:active,
.btn-action-create:focus {
  background-color: #D1EFDB;
  color: #166534;
}

.btn-action-view {
  background-color: #F1E7FE;
  color: #6B21D6;
}

.btn-action-view:hover,
.btn-action-view:active,
.btn-action-view:focus {
  background-color: #E5DBF1;
  color: #6B21D6;
}

.btn-action-edit {
  background-color: #DCE9FE;
  color: #1D4ED8;
}

.btn-action-edit:hover,
.btn-action-edit:active,
.btn-action-edit:focus {
  background-color: #D1DDF1;
  color: #1D4ED8;
}

.btn-action-print {
  background-color: #D6F0F5;
  color: #0E6B80;
}

.btn-action-print:hover,
.btn-action-print:active,
.btn-action-print:focus {
  background-color: #CBE4E9;
  color: #0E6B80;
}

.btn-action-delete {
  background-color: #E9EAED;
  color: #434852;
}

.btn-action-delete:hover,
.btn-action-delete:active,
.btn-action-delete:focus {
  background-color: #DDDEE1;
  color: #434852;
}

[data-theme="dark"] .btn-action-create,
[data-theme="dark"] .btn-action-view,
[data-theme="dark"] .btn-action-edit,
[data-theme="dark"] .btn-action-print,
[data-theme="dark"] .btn-action-delete {
  color: #fff;
}

[data-theme="dark"] .btn-action-create {
  background-color: #238557;
}

[data-theme="dark"] .btn-action-create:hover {
  background-color: #1C6945;
}

[data-theme="dark"] .btn-action-create:active,
[data-theme="dark"] .btn-action-create:focus {
  background-color: #165537;
  color: #fff;
}

[data-theme="dark"] .btn-action-view {
  background-color: #472385;
}

[data-theme="dark"] .btn-action-view:hover {
  background-color: #381C69;
}

[data-theme="dark"] .btn-action-view:active,
[data-theme="dark"] .btn-action-view:focus {
  background-color: #2D1655;
  color: #fff;
}

[data-theme="dark"] .btn-action-edit {
  background-color: #234985;
}

[data-theme="dark"] .btn-action-edit:hover {
  background-color: #1C3969;
}

[data-theme="dark"] .btn-action-edit:active,
[data-theme="dark"] .btn-action-edit:focus {
  background-color: #162E55;
  color: #fff;
}

[data-theme="dark"] .btn-action-print {
  background-color: #237385;
}

[data-theme="dark"] .btn-action-print:hover {
  background-color: #1C5B69;
}

[data-theme="dark"] .btn-action-print:active,
[data-theme="dark"] .btn-action-print:focus {
  background-color: #164955;
  color: #fff;
}

[data-theme="dark"] .btn-action-delete {
  background-color: #4C515D;
}

[data-theme="dark"] .btn-action-delete:hover {
  background-color: #3C4049;
}

[data-theme="dark"] .btn-action-delete:active,
[data-theme="dark"] .btn-action-delete:focus {
  background-color: #30343B;
  color: #fff;
}

/* --- Sidebar nav: hover feedback -----------------------------------------
   Used to also nudge padding-inline-start and scale the icon on hover, but
   padding is a layout property - animating it forces a reflow on every
   frame, which reads as a small shake/jitter when the pointer moves quickly
   down the list. Color/background are compositor-only, so this stays
   smooth no matter how fast you move between items. */
.sidebar-menu > li > a {
  position: relative;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.sidebar-menu .active-page > a,
.sidebar-menu li > a.active-page {
  transition: background-color 0.2s ease;
}

/* --- Sidebar: locked (Premium-gated) nav items ----------------------------
   Grayed out and inert instead of navigating - no hover highlight, default
   cursor - since servido-ui.js intercepts the click and shows a toast
   rather than letting it act like a real link. */
.sidebar-menu-locked {
  opacity: 0.6;
  cursor: default;
}

.sidebar-menu-locked:hover {
  color: var(--text-secondary-light) !important;
}

/* --- Inline status select (work order table): borderless pill, so it ------
   needs its own caret rather than WowDash's default .form-select one, which
   sits flush against the edge (fine with a border, cramped without one) and,
   in dark mode, is a fixed dark-on-transparent PNG that disappears against
   these colored badge backgrounds. currentColor keeps the caret readable
   against every status color in both themes without per-status overrides. */
.status-select {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M2.5 4.5L6 8l3.5-3.5' stroke='currentColor' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") !important;
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 10px 10px;
  padding-inline-end: 28px;
}

[data-theme="dark"] .status-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M2.5 4.5L6 8l3.5-3.5' stroke='currentColor' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") !important;
}

/* --- Stat card icon circles: a little life on hover --------------------- */
.rounded-circle {
  transition: transform 0.2s ease;
}

.card:hover .rounded-circle {
  transform: scale(1.06);
}

/* --- Page content: fade in on every load, including wire:navigate --------
   Used to also rise up 6px (translateY), but that's a real position change
   right next to the sidebar - on every page click it read as a little
   shake/glitch rather than a polish touch. Plain opacity has no such side
   effect. */
.dashboard-main-body {
  animation: servido-page-in 0.2s ease-out;
}

@keyframes servido-page-in {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

/* --- Dashboard stat cards: staggered entrance --------------------------- */
.row-cols-lg-4 > .col,
.row-cols-lg-3 > .col {
  animation: servido-card-in 0.35s ease-out backwards;
}

.row-cols-lg-4 > .col:nth-child(1),
.row-cols-lg-3 > .col:nth-child(1) { animation-delay: 0.02s; }
.row-cols-lg-4 > .col:nth-child(2),
.row-cols-lg-3 > .col:nth-child(2) { animation-delay: 0.08s; }
.row-cols-lg-4 > .col:nth-child(3),
.row-cols-lg-3 > .col:nth-child(3) { animation-delay: 0.14s; }
.row-cols-lg-4 > .col:nth-child(4) { animation-delay: 0.2s; }

@keyframes servido-card-in {
  from {
    opacity: 0;
    transform: translateY(10px) scale(0.98);
  }

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

/* Deliberately NOT animating table rows in on every render: live search
   (wire:model.live on the search box) re-renders tbody on every keystroke,
   and Livewire doesn't guarantee node identity is preserved for every row
   across a filtered re-render the way it does for an untouched paginated
   list. A per-row entrance animation there risks replaying on each
   keystroke instead of once - a busy, glitchy feeling, the opposite of
   what "professional" means for a data table people search constantly.
   The hover highlight above is the safer signal that rows are alive. */

/* --- Badges: subtle pop when their value changes (status/paid toggles) - */
.badge {
  transition: background-color 0.2s ease, color 0.2s ease;
}

/* --- Loading state: dim + spinner cursor while a Livewire request is in
   flight, so acting on the page always gives immediate feedback. ---------
   Livewire toggles wire:loading purely via JS (it sets el.style.display
   directly - there's no server-rendered hidden state at all), so a plain
   [wire\:loading] element with no modifier sits fully visible until that JS
   runs. This default-hides it; Livewire's own inline style (higher
   specificity than this plain rule, and identical specificity to !important
   inline styles it sets later) still correctly shows it mid-request. Without
   this, "Sačuvaj izmene" and the spinner "Sačuvaj izmene…" render stacked
   next to each other at rest, permanently, instead of one replacing the
   other - exactly what was showing up in testing. This selector only
   matches the bare wire:loading attribute; wire:loading.remove and
   wire:loading.attr are distinct attribute names and are untouched. */
[wire\:loading] {
  display: none;
}

.servido-is-loading {
  pointer-events: none;
}

.btn[wire\:loading] {
  opacity: 0.7;
}

/* ==========================================================================
   Action-button row - shrink, don't wrap
   While the table is still a real <table> (>= md, before the card transform
   below takes over), the Akcije cell's buttons (Detalji/Izmeni/Stampanje/
   Obrisi) used to line-wrap onto a second line once the viewport got narrow,
   which threw off row height and left rows misaligned against each other.
   white-space:nowrap stops that wrap; the fluid clamp() sizing below shrinks
   padding/font/icon size instead, so the row narrows smoothly rather than
   reflowing - the same fix on every index table since .table-actions-cell is
   the shared marker for this exact cell.
   ========================================================================== */
@media (min-width: 768px) {
  .table-actions-cell {
    white-space: nowrap;
  }

  .table-actions-cell .btn {
    --bs-btn-padding-x: clamp(0.375rem, -0.5rem + 2vw, 0.75rem);
    --bs-btn-padding-y: clamp(0.1875rem, -0.05rem + 0.5vw, 0.375rem);
    --bs-btn-font-size: clamp(0.6875rem, 0.3rem + 0.7vw, 0.875rem);
    gap: clamp(4px, 1vw, 8px) !important;
  }

  .table-actions-cell .btn iconify-icon {
    font-size: clamp(0.875rem, 0.6rem + 0.5vw, 1.125rem) !important;
  }
}

/* ==========================================================================
   Mobile table -> card transform
   A wide data table sideways-scrolling on a phone is the one thing that
   never feels "professional" - it reads as an unadapted desktop layout,
   not a real mobile experience. Below the md breakpoint, any <table
   class="table-stack"> turns each row into its own card, with the column
   header (from each cell's data-label attribute) shown as a small label in
   front of the value instead of in a separate header row. No JS - it's a
   pure CSS reflow, so it can't drift out of sync with the table's real data.
   Every <td> in a .table-stack table needs data-label="Column Name" (empty
   string on purpose for the actions column - see below).
   ========================================================================== */
@media (max-width: 767.98px) {
  .table-stack thead {
    display: none;
  }

  .table-stack,
  .table-stack tbody,
  .table-stack tr {
    display: block;
    width: 100%;
  }

  /* No :has() here on purpose - every real data table in this app uses
     .table-stack, so there's never a reason for its wrapper to still
     allow horizontal scroll once rows have already reflowed into cards. */
  .table-responsive {
    overflow-x: visible;
  }

  .table-stack tr {
    margin-bottom: 12px;
    padding: 12px 14px;
    border: 1px solid var(--border-color);
    border-radius: 12px;
    background: var(--white);
  }

  .table-stack tr:last-child {
    margin-bottom: 0;
  }

  .table-stack td {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 6px 0 !important;
    border: none !important;
    background: transparent !important;
    text-align: end;
  }

  .table-stack td::before {
    content: attr(data-label);
    font-weight: 600;
    font-size: 0.8rem;
    color: var(--text-secondary-light);
    text-align: start;
    flex-shrink: 0;
  }

  /* The actions column: no "Akcije:" label needed, buttons get their own
     separated row at the bottom of the card instead of a label/value pair.
     A dedicated class rather than reusing .text-end - that's also the
     ordinary Bootstrap class for right-aligning a plain numeric cell (a
     price/total column), which must NOT be swept into this "no label,
     wrapping button row" treatment. */
  .table-stack td.table-actions-cell {
    justify-content: flex-start;
    flex-wrap: wrap;
    margin-top: 6px;
    padding-top: 10px !important;
    border-top: 1px solid var(--border-color) !important;
  }

  .table-stack td.table-actions-cell::before {
    content: none;
  }

  .table-stack td.table-actions-cell > * {
    margin-inline-end: 6px;
    margin-bottom: 6px;
  }

  /* Empty-state / "no results" rows span the full card width plainly, no
     label/value split. Needs its own class rather than a :has() structural
     selector, since :has() support can't be assumed on every mobile browser
     this needs to work on - see <x-empty-state>. */
  .table-stack tr.table-stack-empty-row {
    border: none;
    padding: 0;
  }

  .table-stack td[colspan] {
    display: block;
    text-align: center;
  }

  .table-stack td[colspan]::before {
    content: none;
  }

  /* A totals <tfoot> (e.g. the nalog line-items table) isn't part of the
     tbody row-stacking above, so it needs its own block/flex conversion -
     left as an actual table row otherwise, sitting inside a table that's
     now display:block, which browsers render inconsistently. */
  .table-stack tfoot,
  .table-stack tfoot tr {
    display: block;
    width: 100%;
  }

  .table-stack tfoot tr {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 14px;
    margin-top: 8px;
    border-top: 2px solid var(--border-color);
  }

  .table-stack tfoot th {
    display: block;
    border: none !important;
    padding: 0 !important;
    background: transparent !important;
  }

  /* Variant for tables whose cells hold real form inputs (the nalog print
     page's editable line-items table) rather than plain text - a label
     sitting beside a full-width input reads badly and the input's own
     100% width fights the flex layout above, so this stacks the label
     above the input instead. Combine with .table-stack (not instead of
     it) to keep the shared thead/tr/tfoot/empty-row handling. */
  .table-stack-form td {
    display: block;
    text-align: start;
  }

  .table-stack-form td[data-label]::before {
    content: attr(data-label);
    display: block;
    font-weight: 600;
    font-size: 0.8rem;
    color: var(--text-secondary-light);
    margin-bottom: 4px;
  }

  .table-stack-form td[style] {
    width: 100% !important;
  }
}

/* --- Page tour (x-page-tour): persistent help button + guided steps ----- */
.tour-help-btn {
  position: fixed;
  inset-block-end: 24px;
  inset-inline-end: 24px;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--primary-600);
  color: #fff;
  border: none;
  box-shadow: 0 4px 14px rgba(var(--primary-600-rgb), 0.35);
  font-size: 1.25rem;
  z-index: 1050;
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.tour-help-btn:hover {
  transform: scale(1.08);
  box-shadow: 0 6px 18px rgba(var(--primary-600-rgb), 0.45);
}

.tour-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(10, 8, 12, 0.5);
  z-index: 1060;
  animation: servido-fade-in 0.15s ease-out;
}

/* Lifted above the backdrop (rather than the backdrop being clipped around
   it) so it keeps working regardless of the target's own stacking context -
   no clip-path/mask math tied to a specific element's box. */
.tour-highlight {
  position: relative;
  z-index: 1061;
  outline: 3px solid var(--primary-600);
  outline-offset: 3px;
  border-radius: 8px;
}

.tour-tooltip {
  position: fixed;
  z-index: 1062;
  width: 320px;
  max-width: calc(100vw - 24px);
  background: var(--white);
  color: var(--text-primary-light);
  border-radius: 12px;
  box-shadow: 0 24px 60px rgba(4, 6, 15, 0.28);
  padding: 16px;
  font-size: 0.875rem;
  animation: servido-pop-in 0.2s cubic-bezier(0.2, 0.8, 0.3, 1.1);
}

.tour-tooltip h6 {
  margin-bottom: 0;
}

.tour-tooltip p {
  color: var(--text-secondary-light);
  line-height: 1.5;
}

.tour-tooltip-close {
  background: none;
  border: none;
  color: var(--text-secondary-light);
  cursor: pointer;
  padding: 2px;
  line-height: 1;
  flex-shrink: 0;
  opacity: 0.6;
}

.tour-tooltip-close:hover {
  opacity: 1;
}

.tour-step-count {
  font-size: 0.75rem;
  color: var(--text-secondary-light);
}

/* Respect users who've asked for less motion. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* Appointment calendar grid - hand-rolled month view (no FullCalendar/jQuery
   dependency) so it stays a plain server-rendered Blade/Livewire tree that
   morphdom can diff normally on every wire:click, same as the rest of the
   app. */
.servido-calendar-weekdays,
.servido-calendar-week {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
}

.servido-calendar-weekday {
  padding: 12px 8px;
  text-align: center;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--text-secondary-light);
  border-bottom: 1px solid var(--border-color);
}

.servido-calendar-day {
  min-height: 112px;
  padding: 8px;
  border-right: 1px solid var(--border-color);
  border-bottom: 1px solid var(--border-color);
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.servido-calendar-week .servido-calendar-day:first-child {
  border-left: 1px solid var(--border-color);
}

.servido-calendar-day.is-outside {
  background: var(--neutral-50);
  color: var(--text-secondary-light);
}

.servido-calendar-day.is-outside .servido-calendar-day-header span:first-child {
  color: var(--text-secondary-light);
  opacity: 0.6;
}

.servido-calendar-day.is-today {
  background: var(--primary-50);
}

.servido-calendar-day-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--text-primary-light);
}

.servido-calendar-day.is-today .servido-calendar-day-header span:first-child {
  color: var(--primary-600);
}

.servido-calendar-add-btn {
  background: none;
  border: none;
  padding: 0;
  line-height: 1;
  color: var(--text-secondary-light);
  opacity: 0;
  cursor: pointer;
  transition: opacity 0.1s ease;
}

.servido-calendar-day:hover .servido-calendar-add-btn {
  opacity: 1;
}

.servido-calendar-add-btn:hover {
  color: var(--primary-600);
}

.servido-calendar-day-events {
  display: flex;
  flex-direction: column;
  gap: 4px;
  overflow-y: auto;
}

.servido-calendar-event {
  display: block;
  width: 100%;
  text-align: left;
  background: var(--primary-50);
  color: var(--primary-700);
  border: none;
  border-radius: 6px;
  padding: 3px 6px;
  font-size: 0.75rem;
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
}

.servido-calendar-event:hover {
  background: var(--primary-100);
}

[data-theme="dark"] .servido-calendar-day.is-outside {
  background: rgba(255, 255, 255, 0.02);
}

[data-theme="dark"] .servido-calendar-day.is-today {
  background: var(--primary-50);
}

[data-theme="dark"] .servido-calendar-event {
  background: rgba(var(--primary-600-rgb), 0.25);
  color: #fff;
}

[data-theme="dark"] .servido-calendar-event:hover {
  background: rgba(var(--primary-600-rgb), 0.4);
}

@media (max-width: 575.98px) {
  .servido-calendar-day {
    min-height: 84px;
  }
}

/* Statistics bar rows - single-hue magnitude bars (one metric being compared
   across categories, not distinct series), so one consistent fill color
   throughout rather than a different hue per row. */
.servido-stat-bar-row + .servido-stat-bar-row {
  margin-top: 14px;
}

.servido-stat-bar-row-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 6px;
  gap: 8px;
}

.servido-stat-bar-row-head span:first-child {
  color: var(--text-primary-light);
  font-size: 0.875rem;
  font-weight: 500;
}

.servido-stat-bar-row-head span:last-child {
  color: var(--text-secondary-light);
  font-size: 0.8125rem;
  font-weight: 600;
  flex-shrink: 0;
}

.servido-stat-bar-track {
  height: 10px;
  border-radius: 6px;
  background: var(--neutral-100);
  overflow: hidden;
}

.servido-stat-bar-fill {
  height: 100%;
  min-width: 3px;
  border-radius: 6px;
  background: var(--primary-600);
}

/* Monthly arrivals - vertical columns instead of rows, same single-hue rule. */
.servido-stat-columns {
  display: flex;
  align-items: flex-end;
  gap: 12px;
  height: 140px;
}

.servido-stat-column {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  height: 100%;
  gap: 8px;
}

.servido-stat-column-value {
  color: var(--text-secondary-light);
  font-size: 0.8125rem;
  font-weight: 600;
}

.servido-stat-column-bar {
  width: 100%;
  max-width: 36px;
  min-height: 4px;
  border-radius: 6px 6px 2px 2px;
  background: var(--primary-600);
}

.servido-stat-column-label {
  color: var(--text-secondary-light);
  font-size: 0.75rem;
  text-transform: capitalize;
}

[data-theme="dark"] .servido-stat-bar-track {
  background: rgba(255, 255, 255, 0.06);
}

/* Stat-tile icon accents - same tint-background-plus-saturated-icon
   technique as .btn-action-* (a light tint behind a dark, saturated icon
   color clears WCAG AA without being limited to hues dark enough to carry
   white text), reused here so the KPI row isn't a wall of neutral gray. */
.servido-stat-icon-blue {
  background-color: #DCE9FE;
  color: #1D4ED8;
}

.servido-stat-icon-purple {
  background-color: #F1E7FE;
  color: #6B21D6;
}

.servido-stat-icon-teal {
  background-color: #D6F0F5;
  color: #0E6B80;
}

.servido-stat-icon-brand {
  background-color: var(--primary-50);
  color: var(--primary-700);
}

[data-theme="dark"] .servido-stat-icon-blue {
  background-color: #234985;
  color: #fff;
}

[data-theme="dark"] .servido-stat-icon-purple {
  background-color: #472385;
  color: #fff;
}

[data-theme="dark"] .servido-stat-icon-teal {
  background-color: #237385;
  color: #fff;
}

/* --primary-700 (dark maroon) on the dark-mode --primary-50 (near-black)
   background is ~1.9:1 - nearly invisible. A lighter step of the same ramp
   clears WCAG AA (~6.6:1) while staying visibly "the brand color". */
[data-theme="dark"] .servido-stat-icon-brand {
  color: var(--primary-200);
}

/* Sidebar - fuller nav spacing
   The nav list is intentionally short (6 top-level items + 2 settings
   links), which read as sparse/empty against the sidebar's full-height
   background. More breathing room between nav rows so the list reads as
   "spaced out by design" rather than "not enough content". */
.sidebar-menu li + li {
  margin-block-start: 0.25rem;
}

.sidebar-menu li a {
  padding-block: 0.75rem;
}

.servido-sidebar-footer-menu {
  padding-block-start: 0.75rem;
  border-block-start: 1px solid var(--neutral-200);
}
