/* ===========================================================================
   Kirrho Payroll — design system
   Theme is driven by a `data-theme` attribute on #app-root (light | dark).
   =========================================================================== */
:root {
  --primary: #FF6B35;
  --primary-2: #FF8C42;
  --secondary: #2E7D32;
  --secondary-2: #4CAF50;
  --brand-grad: var(--primary);  /* solid brand primary (enterprise; was a gradient) */
  --bg: #F7F8FA;
  --surface: #FFFFFF;
  --surface-2: #F1F3F6;
  --text: #1A1A1A;
  --muted: #6B7280;
  --border: #E5E7EB;
  --shadow: 0 1px 3px rgba(16, 24, 40, .08), 0 1px 2px rgba(16, 24, 40, .06);
  --shadow-lg: 0 12px 32px rgba(16, 24, 40, .12);
  --radius: 16px;
  --sidebar-w: 248px;
}

[data-theme="dark"] {
  --primary: #FF8C42;
  --primary-2: #FFA05C;
  --secondary: #4CAF50;
  --secondary-2: #66BB6A;
  --bg: #0E1116;
  --surface: #171B22;
  --surface-2: #1E242D;
  --text: #E6E8EB;
  --muted: #9AA4B2;
  --border: #2A313C;
  --shadow: 0 1px 3px rgba(0, 0, 0, .4);
  --shadow-lg: 0 12px 32px rgba(0, 0, 0, .5);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Inter, sans-serif;
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
}

#app-root { background: var(--bg); color: var(--text); min-height: 100vh; }

/* ----------------------------------------------------------------- Login -- */
.login-wrap {
  display: flex; align-items: center; justify-content: center;
  min-height: 100vh; padding: 1.25rem;
  background: var(--surface-2);
}
.login-card {
  width: 100%; max-width: 420px; padding: 2.5rem 2.25rem;
  border-radius: 20px; background: var(--surface);
  box-shadow: var(--shadow-lg); border: 1px solid var(--border);
}
.login-card .form-control {
  border-radius: 10px; padding: .7rem .9rem; background: var(--surface-2);
  border: 1px solid var(--border); color: var(--text);
}

/* Shared input sizing — one consistent padding/height/radius for every text/number/
   select input across the app (plain inputs, year inputs, and the date picker), so
   they match on desktop AND mobile. (.login-card .form-control above is more specific
   and keeps the login form's larger padding.) */
.form-control, .form-select {
  padding: .5rem .75rem; min-height: 40px; border-radius: 10px; font-size: .95rem;
}

/* --------------------------------------------------------------- Layout --- */
.app-frame { display: flex; min-height: 100vh; }

.sidebar {
  position: fixed; top: 0; left: 0;
  width: var(--sidebar-w); height: 100vh;
  background: var(--surface); border-right: 1px solid var(--border);
  display: flex; flex-direction: column; gap: .12rem;
  overflow-y: auto;
  /* Still scrollable if the nav is taller than the viewport, but with no visible
     scrollbar. */
  scrollbar-width: none; -ms-overflow-style: none;
  z-index: 15;
}
.sidebar::-webkit-scrollbar { width: 0; height: 0; display: none; }
.sidebar .brand { padding: 1.2rem .6rem 1rem; margin-bottom: .45rem;
  border-bottom: 1px solid var(--border); }
/* Mobile offcanvas brand gets the same divider + inset so it lines up with nav buttons.
   Less top padding than desktop because the offcanvas body already has its own padding. */
#mobile-nav .brand { padding: .8rem .6rem .6rem; margin-bottom: .35rem;
  border-bottom: 1px solid var(--border); display: flex; justify-content: center; }
#mobile-nav .brand img { height: 42px; }
#mobile-nav .nav { padding: 0 .5rem !important; }
#mobile-nav .nav-link { margin-left: .1rem !important; margin-right: .1rem !important; }
/* Faster mobile drawer open/close (default Bootstrap transition is ~0.35s). */
#mobile-nav .offcanvas { transition: transform .15s ease-out !important; }
#mobile-nav .offcanvas-backdrop { transition: opacity .15s ease-out !important; }
.sidebar .brand img { height: 42px; }
/* Nav group breathes a little under the logo; consistent gap between items. */
.sidebar > .nav { gap: .12rem; margin-top: .35rem; padding: 0 0.5rem !important; }
/* Divider + spacing above the Profile / Logout group pinned to the bottom. */
.sidebar .mt-auto { border-top: 1px solid var(--border); margin-top: .8rem; padding-top: .7rem; }
/* Nav containers span the full width. Keep the horizontal gutter on the nav group
   so nav-button edges line up with the brand divider; the bottom group stays
   edge-to-edge. */
.sidebar > .nav { width: 100%; }
.sidebar .mt-auto { width: 100%; padding-left: 0; padding-right: 0; }
.sidebar .nav-link { margin-left: .1rem !important; margin-right: .1rem !important; }

.main-col {
  flex: 1; min-width: 0;
  margin-left: var(--sidebar-w);
  padding-top: 70px;
  display: flex; flex-direction: column;
  min-height: 100vh;
}

.topbar {
  position: fixed; top: 0; left: var(--sidebar-w); right: 0; z-index: 20;
  height: 70px;
  display: flex; align-items: center; gap: .75rem;
  padding: .85rem 1.5rem; background: var(--surface);
  border-bottom: 1px solid var(--border);
  overflow: visible;
}
.topbar .page-title { font-weight: 700; font-size: 1.15rem; margin: 0; }
.topbar .spacer { flex: 1; }
.icon-btn {
  border: 1px solid var(--border); background: var(--surface-2); color: var(--text);
  width: 40px; height: 40px; border-radius: 10px; display: inline-flex;
  align-items: center; justify-content: center; cursor: pointer; transition: .15s;
}
.icon-btn:hover { border-color: var(--primary); color: var(--primary); }
.hamburger { display: none; }

/* Topbar unmapped-users alert: amber so orphaned device users stand out. */
.unmapped-alert { color: #f5a524; border-color: #f5a52455; text-decoration: none; }
.unmapped-alert:hover { border-color: #f5a524; color: #f5a524; }

/* Work-window countdown (topbar, employees). Same shape as the alert above but a text pill
   rather than a square: .icon-btn is a fixed 40x40 and would clip "2h 15m left".
   `--secondary-2` rather than a literal #2E7D32 so the green lifts in dark mode. */
.timer-chip {
  display: inline-flex; align-items: center; white-space: nowrap;
  height: 40px; padding: 0 .8rem; border-radius: 10px;
  border: 1px solid color-mix(in srgb, var(--secondary-2) 35%, transparent);
  background: color-mix(in srgb, var(--secondary-2) 10%, transparent);
  color: var(--secondary-2); font-weight: 600; font-size: .86rem;
  /* Ticking digits change width in a proportional face; without this the chip — and every
     control to its left — shimmers once a second. */
  font-variant-numeric: tabular-nums;
}
@media (max-width: 640px) {
  /* Matches the .icon-btn shrink in the same breakpoint so the row stays level. */
  .timer-chip { height: 36px; padding: 0 .6rem; font-size: .78rem; }
}
@media (max-width: 380px) {
  /* Tightest phones: the icon is decorative, the number is not. */
  .timer-chip i { display: none; }
  .timer-chip { padding: 0 .45rem; }
}

/* Theme toggle is now an icon-btn in the topbar, see .icon-btn above. */

/* Notification bell (topbar, managers) */
.notif-menu { display: inline-flex; position: relative; }
.notif-toggle { padding: 0 !important; background: var(--surface-2) !important;
  color: var(--text) !important; box-shadow: none !important; }
.notif-toggle:hover, .notif-toggle:focus { border-color: var(--primary) !important;
  color: var(--primary) !important; }
.notif-menu, .notif-toggle { overflow: visible !important; }
.topbar { overflow: visible; }
.notif-bell { position: relative; display: inline-flex; align-items: center;
  justify-content: center; width: 100%; height: 100%; overflow: visible; }
/* Count sits above the top-right corner of the bell so both read clearly. */
.notif-badge {
  position: absolute; top: -9px; right: -9px; min-width: 18px; height: 18px;
  padding: 0 5px; border-radius: 999px; background: #e5484d; color: #fff;
  font-size: .68rem; font-weight: 700; line-height: 18px; text-align: center;
  box-shadow: 0 0 0 2px var(--surface); z-index: 20;
}
.notif-menu .dropdown-menu {
  width: 360px; max-width: calc(100vw - 24px); max-height: 65vh; overflow-y: auto;
  padding: 0; background: var(--surface); border: 1px solid var(--border);
  border-radius: 14px; box-shadow: 0 12px 32px rgba(0,0,0,.16);
}
.notif-menu .dropdown-item { white-space: normal; }

/* Sticky title row, so the list still reads as "notifications" once scrolled. */
.notif-head {
  position: sticky; top: 0; z-index: 2; display: flex; align-items: center;
  justify-content: space-between; gap: .5rem; padding: .6rem .85rem;
  background: var(--surface); border-bottom: 1px solid var(--border);
  border-radius: 14px 14px 0 0; font-weight: 700; font-size: .85rem;
  /* The menu is a Bootstrap dropdown, whose default text colour is near-black —
     it would vanish on the dark surface, so take the colour from the theme. */
  color: var(--text);
}
.notif-head-count { font-size: .7rem; font-weight: 600; color: var(--muted); }
.notif-head-right { display: flex; align-items: center; gap: .6rem; }
.notif-mark-read {
  border: none; background: none; padding: 0; margin: 0;
  font-size: .72rem; font-weight: 600; color: var(--primary);
  cursor: pointer;
}
.notif-mark-read:hover, .notif-mark-read:focus {
  color: var(--primary); text-decoration: underline; outline: none;
}

/* One notification. The left stripe carries the status colour; unread items get a
   tinted background so the state reads without hunting for a dot. */
.notif-menu .notif-item {
  padding: .6rem .85rem .6rem .7rem; border-left: 3px solid transparent;
  border-bottom: 1px solid var(--border);
}
.notif-menu .notif-item:last-child { border-bottom: none; }
.notif-menu .notif-item:hover, .notif-menu .notif-item:focus {
  background: var(--surface-2); color: inherit;
}
.notif-menu .notif-amber { border-left-color: #F59E0B; background: rgba(245,158,11,.06); }
.notif-menu .notif-green { border-left-color: var(--secondary-2); background: rgba(46,125,50,.06); }
.notif-menu .notif-red   { border-left-color: #DC2626; background: rgba(220,38,38,.06); }
.notif-menu .notif-item-read { background: transparent; opacity: .62; }

.notif-row { display: flex; align-items: flex-start; gap: .6rem; }
.notif-ico {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: .82rem; margin-top: .1rem;
}
.notif-ico-amber { background: rgba(245,158,11,.16); color: #D97706; }
.notif-ico-green { background: rgba(46,125,50,.14); color: var(--secondary-2); }
.notif-ico-red   { background: rgba(220,38,38,.14); color: #EF4444; }
.notif-body { min-width: 0; flex: 1 1 auto; }
.notif-line1 { display: flex; align-items: center; gap: .4rem; }
.notif-name {
  font-weight: 600; font-size: .87rem; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
.notif-line1 .pill { flex: 0 0 auto; margin-left: auto; }
.notif-line2 {
  font-size: .76rem; color: var(--muted); margin-top: .1rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.notif-time { font-size: .7rem; color: var(--muted); margin-top: .15rem; opacity: .85; }

.notif-empty-item { opacity: 1 !important; }
.notif-empty { text-align: center; padding: 1.6rem .85rem; color: var(--muted); }
.notif-empty i { font-size: 1.6rem; opacity: .45; }
.notif-empty-title { font-weight: 600; color: var(--text); margin-top: .5rem; font-size: .87rem; }
.notif-empty-sub { font-size: .75rem; margin-top: .15rem; }

.notif-more {
  text-align: center; color: var(--primary); border-top: 1px solid var(--border);
  padding: .55rem .85rem; font-size: .82rem;
}
[data-theme="dark"] .notif-menu .dropdown-menu,
[data-theme="dark"] .notif-head { background: var(--surface); }
[data-theme="dark"] .notif-menu .notif-item:hover { background: var(--surface-2); }

/* Phone: anchor the bell dropdown under the icon but center the panel on the
   screen, so the left/right margin (12px each) stays equal. */
@media (max-width: 640px) {
  .notif-menu .dropdown-menu {
    position: absolute !important;
    top: calc(100% + 8px) !important; left: 50% !important;
    right: auto !important; bottom: auto !important;
    transform: translateX(-80%) !important;
    width: min(360px, calc(100vw - 24px));
    max-width: calc(100vw - 24px);
    max-height: min(520px, calc(100vh - 48px));
    margin: 0;
    z-index: 1100;
  }
  .notif-ico { width: 26px; height: 26px; font-size: .74rem; }
  .notif-name { font-size: .82rem; }
}

/* Personal month calendar (employee "My Attendance") */
.pm-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; margin-top: 8px; }
.pm-head { text-align: center; font-weight: 700; font-size: .72rem; color: var(--muted);
  padding: 2px 0; }
.pm-cell { min-height: 54px; border: 1px solid var(--border); border-radius: 10px;
  padding: 6px 8px; display: flex; flex-direction: column; justify-content: space-between;
  cursor: pointer; transition: .12s; background: var(--surface-2); }
.pm-cell:hover { border-color: var(--primary); transform: translateY(-1px); }
.pm-empty { border: none; background: transparent; cursor: default; }
.pm-empty:hover { transform: none; }
.pm-day-num { font-weight: 600; font-size: .82rem; }
.pm-day-ico { align-self: flex-end; font-size: .95rem; }
.pm-present { background: rgba(46,125,50,.10); border-color: rgba(46,125,50,.30); }
.pm-late { background: rgba(245,158,11,.12); border-color: rgba(245,158,11,.35); }
.pm-early { background: rgba(147,51,234,.12); border-color: rgba(147,51,234,.35); }
.pm-absent { background: rgba(220,38,38,.10); border-color: rgba(220,38,38,.30); }
.pm-off { background: transparent; opacity: .6; }
.pm-off_worked { background: rgba(13,148,136,.14); border-color: rgba(13,148,136,.40); }
.pm-future { background: transparent; opacity: .45; border-style: dashed; }
/* Previous month's trailing days shown in the first week — muted, not clickable. */
.pm-outside { opacity: .4; cursor: default; }
.pm-outside:hover { border-color: var(--border); transform: none; }
@media (max-width: 640px) { .pm-cell { min-height: 44px; padding: 4px 5px; } }

/* Leave grid "Days" column: render the newline-joined weekday+date list as lines. */
.leave-days-cell { white-space: pre-line; line-height: 1.45; padding-top: 6px !important;
  padding-bottom: 6px !important; }

/* ---- Date picker (dcc.DatePickerSingle) — styled to match .form-control ---- */
.app-datepicker, .app-datepicker .SingleDatePicker { width: 100%; display: block; }
.app-datepicker .SingleDatePickerInput {
  width: 100%; background: var(--surface); border: 1px solid var(--border);
  border-radius: 10px; }
.app-datepicker .DateInput { width: 100%; background: transparent; border-radius: 10px; }
.app-datepicker .DateInput_input {
  width: 100%; font-size: .95rem; font-weight: 400; line-height: 1.4;
  padding: .5rem .75rem; background: transparent; color: var(--text);
  border: none; border-bottom: 2px solid transparent; border-radius: 10px; }
.app-datepicker .DateInput_input__focused { border-bottom-color: var(--primary); }
.app-datepicker .DateInput_input::placeholder { color: var(--muted); }
[data-theme="dark"] .app-datepicker .SingleDatePickerInput { background: var(--surface-2); }
[data-theme="dark"] .app-datepicker .DateInput_input { color: var(--text); }
/* Calendar popup — anchored directly under the clicked input, as a popover. */
.SingleDatePicker_picker { z-index: 1300 !important; }
.app-datepicker .DayPicker__withBorder {
  box-shadow: var(--shadow-lg); border-radius: 12px; }
/* On phones, dock the calendar as a bottom sheet so it can't be clipped inside a
   scrolling modal and stays thumb-reachable. */
@media (max-width: 640px) {
  .SingleDatePicker_picker {
    position: fixed !important; top: auto !important; bottom: 0 !important;
    left: 0 !important; right: 0 !important; width: 100% !important;
    display: flex; justify-content: center;
    background: var(--surface); box-shadow: 0 -6px 24px rgba(0,0,0,.28);
    border-top: 1px solid var(--border); padding: .4rem 0 .6rem; }
}
.CalendarDay__selected, .CalendarDay__selected:hover, .CalendarDay__selected:active {
  background: var(--primary) !important; border-color: var(--primary) !important; color: #fff; }
.CalendarDay__today { font-weight: 700; color: var(--primary); }
/* Selected day that is also today: keep the number white so it stays visible on
   the solid orange selected background (the later .CalendarDay__today color would
   otherwise win and render orange-on-orange). */
.CalendarDay__selected.CalendarDay__today,
.CalendarDay__selected.CalendarDay__today:hover,
.CalendarDay__selected.CalendarDay__today:active { color: #fff; }
.DayPickerKeyboardShortcuts_show { display: none !important; }
[data-theme="dark"] .DayPicker, [data-theme="dark"] .CalendarMonthGrid,
[data-theme="dark"] .CalendarMonth, [data-theme="dark"] .DayPicker_transitionContainer,
[data-theme="dark"] .DayPicker_focusRegion {
  background: var(--surface) !important; color: var(--text); }
[data-theme="dark"] .CalendarMonth_caption, [data-theme="dark"] .DayPicker_weekHeader {
  color: var(--text); }
[data-theme="dark"] .CalendarDay__default {
  background: var(--surface); color: var(--text); border-color: var(--border); }
[data-theme="dark"] .CalendarDay__default:hover {
  background: var(--surface-2); border-color: var(--primary); color: var(--text); }
[data-theme="dark"] .DayPickerNavigation_button__default {
  background: var(--surface-2); border-color: var(--border); }

.page { padding: 1.75rem; }
.page { overflow-x: hidden; }  /* never let a wide child push the whole page sideways */
/* AG grids + plain tables scroll inside their own card on small screens */
/* Neutral full-viewport boot loader shown on first paint (hard refresh) until the
   clientside auth toggle decides login vs. dashboard — prevents the login-form flash.
   Solid app background so nothing behind it shows through. */
.boot-loader {
  position: fixed;
  inset: 0;
  z-index: 3000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg, #f5f6f8);
}

.ag-root-wrapper { max-width: 100%; }
.render-table-wrap, .dbc-table-wrap, .data-table { overflow-x: auto; }
.page .table { min-width: 0; }
/* AG grid keeps its own horizontal scrollbar; the wrapper must let it scroll
   rather than push the page sideways. */
.ag-root-wrapper, .ag-center-cols-viewport, .ag-body-viewport { overflow-x: auto; }
/* Notification dropdown must never exceed the viewport on a phone. */
.notif-menu .dropdown-menu { min-width: min(300px, 88vw); max-width: min(360px, 92vw); }
@media (max-width: 991px) {
  .sidebar { display: none; }
  .hamburger { display: inline-flex; }
  .page { padding: 1.15rem; }
  /* Topbar spans the full viewport on mobile; main column sits below it. */
  .topbar { left: 0; height: 60px; padding: .7rem .8rem; }
  .main-col { margin-left: 0; padding-top: 60px; }
  /* Mobile sidebar backdrop: keep the element (so clicking outside closes the
     offcanvas) but make it invisible — no dim overlay over the page. */
  .offcanvas-backdrop, .offcanvas-backdrop.show { background: transparent !important; }
  /* Make the offcanvas body a full-height flex column so the `.mt-auto` on the
     My Profile + Logout group pushes them to the BOTTOM of the sidebar on mobile
     (same as desktop), instead of sitting directly under the nav items. */
  #mobile-nav .offcanvas-body { display: flex; flex-direction: column; }
}
/* Desktop uses the sticky sidebar for navigation; the mobile offcanvas must NEVER
   render here. Hard-hide it (and any stray backdrop) so a stray is_open can't ever
   slide the mobile menu in over the desktop page. */
@media (min-width: 992px) {
  #mobile-nav, #mobile-nav.offcanvas, #mobile-nav.show { display: none !important; }
  .offcanvas-backdrop { display: none !important; }
}
@media (max-width: 640px) {
  .section-head { flex-wrap: wrap; gap: .5rem; }
  .section-head > div { flex-wrap: wrap; }
  /* Account Details header: the heading and the Employment Details button wrap onto separate
     lines on a phone, where justify-content:space-between no longer pushes anything right. */
  .acct-head > .btn { margin-left: auto; }
  /* Attendance report card: the filters go full width on phones, so Preview lands on its
     own line — keep it hard right rather than dropping back to flex-start. */
  .att-report-head > div { width: 100%; }
  /* direct child only: the Apply button lives inside month_selector's own bar and must
     stay where it is. */
  .att-report-head > div > .btn { margin-left: auto; }
  .modal-body { max-height: 78vh; overflow-y: auto; }
  /* Table pagination controls (#1): keep them on-screen on phones. */
  .ag-paging-panel {
    flex-wrap: wrap; justify-content: center; gap: .1rem .35rem;
    height: auto !important; min-height: 0 !important;
    padding: .45rem .4rem !important; font-size: .76rem; line-height: 1.4;
  }
  .ag-paging-panel .ag-paging-row-summary-panel { margin: 0 .3rem; }
  .ag-paging-panel .ag-paging-page-size { margin-right: .3rem; }
  /* the device-table Prev/Next pager */
  .pg-bar { flex-wrap: wrap; justify-content: center !important; row-gap: .35rem; }
  /* stacked dropdowns/inputs in toolbars go full width so they don't overflow */
  .section-head .Select, .section-head .dash-dropdown { min-width: 130px; }
  /* Many filter dropdowns / year inputs carry an inline fixed px width
     (e.g. width:220px). On phones that overflows the row — force them full
     width (!important beats the inline style) so they stack cleanly. */
  .page .Select, .page .dash-dropdown,
  .page input[type="number"], .page input[type="date"] {
    width: 100% !important; max-width: 100% !important; min-width: 0 !important;
  }
  /* Compact the topbar so its action cluster (sync + alerts + bell + avatar)
     fits without overflowing. The topbar is fixed-height on mobile, so it must
     stay on one line; hide the Sync label to make room. */
  .topbar { gap: .4rem; flex-wrap: nowrap; }
  .sync-text { display: none; }
  .topbar .spacer { min-width: 1rem; }
  .topbar .page-title { font-size: 1rem; }
  .icon-btn { width: 36px; height: 36px; }
  /* Per-Employee section-head: when the Preview & Export button wraps to its
     own line, push it to the right instead of leaving it at flex-start. */
  .section-head > .btn:last-child { margin-left: auto; }
}
@media (max-width: 480px) {
  /* On the tightest phones the breadcrumb carries the page name, so the topbar
     title can step aside to make room for the actions. */
  .topbar .page-title { display: none; }
  .page { padding: .9rem; }
  /* Toolbars wrap under the heading instead of forcing horizontal overflow.
     (Button GROUPS like the Sync split-control must stay on one line, so they
     are intentionally not wrapped.) */
  .section-head > div { width: 100%; }
}

/* ------------------------------------------------------------------- Nav -- */
.nav-link {
  color: var(--text) !important; border-radius: 10px !important;
  padding: .6rem .8rem !important; font-weight: 500; display: flex;
  align-items: center; gap: .7rem; transition: .15s; margin: 1px 0;
}
.nav-link:hover { background: var(--surface-2) !important; color: var(--primary) !important; }
.nav-link.active {
  background: var(--primary) !important; color: #fff !important;
  box-shadow: 0 2px 6px rgba(255,107,53,.25);
}
/* Icons: fixed width so labels line up; the markup's me-2 margin is replaced by the
   flex gap so icon↔label spacing is uniform. */
.nav-link i { width: 20px; text-align: center; font-size: .98rem; margin-right: 0 !important; }

/* ----------------------------------------------------------------- Cards -- */
.card {
  border-radius: var(--radius) !important; border: 1px solid var(--border) !important;
  background: var(--surface) !important; color: var(--text) !important;
  box-shadow: var(--shadow); transition: transform .15s, box-shadow .15s;
}
.card:hover { box-shadow: var(--shadow-lg); }
/* Consistent internal spacing for every card. */
.card > .card-body { padding: 1.4rem 1.5rem !important; }
.card h5 { line-height: 1.3; }

/* Even vertical rhythm between stacked rows/cards. */
.page > .row { margin-bottom: .25rem; }
.page .card { margin-bottom: 1rem; }

.stat-card { position: relative; overflow: hidden; }
.stat-card > .card-body { padding: 1.5rem 1.5rem !important; }
.stat-card .stat-icon {
  position: absolute; right: 1.25rem; top: 1.25rem; width: 46px; height: 46px;
  border-radius: 13px; display: flex; align-items: center; justify-content: center;
  font-size: 1.15rem; color: #fff;
}
.stat-card .stat-label { color: var(--muted); font-size: .8rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .05em; padding-right: 3.25rem; }
.stat-card .stat-value { font-size: 2.1rem; font-weight: 800; line-height: 1.1; margin-top: .5rem; }
/* Text/time values (e.g. Today's Status "Not checked in", Check In/Out times) use a smaller
   font so they fit without wrapping the card taller than its numeric siblings. Combined with
   .stat-card.h-100 (equal height in a row), every card in the row matches. */
.stat-card .stat-value.stat-value-sm { font-size: 1.15rem; font-weight: 700; line-height: 1.3;
  margin-top: .6rem; }

/* Phones: two stat cards per row leave little width, so trim padding, shrink the corner
   icon (and the label's reserved space for it), and scale the value fonts down so labels
   like "Hours Worked" and values like "Not checked in" fit without spilling below. */
@media (max-width: 640px) {
  .stat-card > .card-body { padding: .8rem .7rem !important; }
  .stat-card .stat-icon { width: 30px; height: 30px; right: .55rem; top: .55rem;
    font-size: .82rem; border-radius: 9px; }
  .stat-card .stat-label { font-size: .66rem; padding-right: 1.9rem; letter-spacing: .02em; }
  .stat-card .stat-value { font-size: 1.45rem; margin-top: .3rem; }
  .stat-card .stat-value.stat-value-sm { font-size: .98rem; margin-top: .35rem; }
}

/* Reports page: block icon badge with proper spacing (not the corner stat badge). */
.report-icon {
  width: 52px; height: 52px; border-radius: 14px;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 1.3rem; margin: 0 0 1rem;
}
.bg-grad   { background: var(--primary); }
.bg-orange { background: #FF6B35; }
.bg-green  { background: #2E7D32; }
.bg-amber  { background: #F59E0B; }
.bg-red    { background: #DC2626; }
.bg-blue   { background: #2563EB; }

/* ---------------------------------------------------------------- Tables -- */
.dash-table-container { --dt-border: var(--border); }
.data-table table { width: 100%; border-collapse: collapse; }
.data-table th {
  text-align: left; font-size: .76rem; text-transform: uppercase; letter-spacing: .05em;
  color: var(--muted); padding: .8rem 1rem; border-bottom: 1px solid var(--border);
}
.data-table td { padding: .85rem 1rem; border-bottom: 1px solid var(--border); font-size: .92rem;
  vertical-align: middle; }
.data-table tr:last-child td { border-bottom: none; }
.data-table tr:hover td { background: var(--surface-2); }
/* Long unbroken strings must wrap inside plain-table cells instead of
   stretching columns (the container already scrolls horizontally). */
.data-table td { word-wrap: break-word; overflow-wrap: anywhere; }
/* Reusable truncate-with-ellipsis; full text is revealed by a native title
   tooltip. Ellipsis forces nowrap, so it overrides the wrap rule above. */
.text-ellipsis {
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
}

.pill { display: inline-block; padding: .13rem .5rem; border-radius: 999px;
  font-size: .72rem; font-weight: 600; line-height: 1.35; white-space: nowrap; }
.pill-green { background: rgba(46,125,50,.14); color: var(--secondary-2); }
.pill-amber { background: rgba(245,158,11,.16); color: #D97706; }
.pill-red   { background: rgba(220,38,38,.14); color: #EF4444; }
.pill-muted { background: var(--surface-2); color: var(--muted); }
.pill-blue  { background: rgba(37,99,235,.14); color: #2563EB; }
.pill-purple { background: rgba(147,51,234,.14); color: #9333EA; }
[data-theme="dark"] .pill-blue { color: #60A5FA; }
[data-theme="dark"] .pill-purple { color: #C084FC; }

/* --------------------------------------------------------------- Buttons -- */
.btn-primary { background: var(--primary) !important; border: none !important;
  font-weight: 600; box-shadow: 0 2px 6px rgba(255,107,53,.22); }
.btn-primary:hover { filter: brightness(.95); }
.btn-outline-secondary { color: var(--text) !important; border-color: var(--border) !important; }

/* Bootstrap's default blue leaks through anywhere the palette is not stated: switches, and
   outline-primary buttons like the topbar Sync control. In an orange/green app that reads
   as a third, unexplained accent colour. Point them at the theme tokens instead. */
.btn-outline-primary {
  color: var(--primary) !important;
  border-color: color-mix(in srgb, var(--primary) 55%, transparent) !important;
  background: transparent !important; font-weight: 600;
}
.btn-outline-primary:hover, .btn-outline-primary:focus-visible {
  color: #fff !important; background: var(--primary) !important;
  border-color: var(--primary) !important;
}

/* Switches and checkboxes: the "on" state is the brand colour, in both themes. */
.form-check-input:checked {
  background-color: var(--primary) !important;
  border-color: var(--primary) !important;
}
.form-check-input:focus {
  border-color: color-mix(in srgb, var(--primary) 60%, transparent) !important;
  box-shadow: 0 0 0 .2rem color-mix(in srgb, var(--primary) 25%, transparent) !important;
}
/* An "off" switch must still read as a control. Bootstrap fills the track with white, which
   on a white card is invisible except for its hairline border (measured 1.0:1 against the
   surface), and on a dark card the pale default disappears the other way. Tint the track
   from the text token so both themes get a track you can actually see. */
.form-check-input:not(:checked) {
  background-color: color-mix(in srgb, var(--text) 12%, transparent);
  border-color: color-mix(in srgb, var(--text) 22%, transparent);
}
[data-theme="dark"] .form-check-input:not(:checked) {
  background-color: color-mix(in srgb, var(--text) 22%, transparent);
  border-color: color-mix(in srgb, var(--text) 30%, transparent);
}

/* Corrective actions (Undo Paid). Amber is this app's caution colour — see .pill-amber and
   .lv-pending — so it reads as "reverses something" without red's alarm, and it does not
   compete with Generate (orange) or Mark Paid (green) sitting beside it. */
.btn-outline-warning {
  color: #B45309 !important;
  border-color: color-mix(in srgb, #F59E0B 55%, transparent) !important;
  background: transparent !important;
  font-weight: 600;
}
.btn-outline-warning:hover, .btn-outline-warning:focus-visible {
  color: #92400E !important;
  border-color: #F59E0B !important;
  background: rgba(245, 158, 11, .12) !important;
}
.btn-outline-warning:focus-visible { outline: 2px solid rgba(245,158,11,.45); outline-offset: 1px; }
.btn-outline-warning:disabled { opacity: .55; }
[data-theme="dark"] .btn-outline-warning {
  /* #B45309 is unreadable on a dark surface; lift to the lighter amber. */
  color: #FBBF24 !important;
}
[data-theme="dark"] .btn-outline-warning:hover {
  color: #FDE68A !important; background: rgba(245, 158, 11, .18) !important;
}

.section-head { display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; margin-bottom: 1.5rem; flex-wrap: wrap; }
.section-head h3 { margin: 0; font-weight: 700; }
.page > h3 { margin-bottom: 1.5rem; font-weight: 700; }
/* Status pills render identically inside AG-grid cells and render_table cells. */
.pill { margin: 0; vertical-align: middle; }
.ag-cell .pill { margin: 0; }
.data-table td .pill { margin: 0; }
.btn { padding: .5rem 1.05rem; }
.stat-icon.mb-2 { margin-bottom: .85rem !important; }

/* Bootstrap surface overrides for dark mode */
[data-theme="dark"] .form-control,
[data-theme="dark"] .form-select { background: var(--surface-2); color: var(--text); border-color: var(--border); }
[data-theme="dark"] .form-control::placeholder { color: var(--muted); }
[data-theme="dark"] .modal-content { background: var(--surface); color: var(--text); }
[data-theme="dark"] .modal-header, [data-theme="dark"] .modal-footer { border-color: var(--border); }
/* Long reason/remark text inside modal bodies must wrap, never overflow. */
.modal-body { word-wrap: break-word; overflow-wrap: anywhere; }
[data-theme="dark"] .offcanvas { background: var(--surface); color: var(--text); }
[data-theme="dark"] .card { background: var(--surface); color: var(--text); border-color: var(--border); }
[data-theme="dark"] .dropdown-menu { background: var(--surface-2); border-color: var(--border); }
[data-theme="dark"] .dropdown-item { color: var(--text); }
[data-theme="dark"] .dropdown-item:hover, [data-theme="dark"] .dropdown-item:focus {
  background: var(--surface); color: var(--primary); }
[data-theme="dark"] .table { color: var(--text); }
/* Bootstrap semantic text colors are too dark on the dark surface — brighten them
   (used by the device-health counts, sync-runs table, and elsewhere). */
[data-theme="dark"] .text-success { color: #4ADE80 !important; }
[data-theme="dark"] .text-danger  { color: #F87171 !important; }
[data-theme="dark"] .text-warning { color: #FBBF24 !important; }
[data-theme="dark"] .pill-amber { color: #FBBF24; }

/* Alerts (dbc.Alert) — Bootstrap's light pastels are near-white on the dark
   surface (worst on color="light" info banners). Retint with a transparent
   brand/semantic wash + a readable border so they sit on the dark theme. */
[data-theme="dark"] .alert-light,
[data-theme="dark"] .alert-secondary {
  background: var(--surface-2); color: var(--text); border-color: var(--border); }
[data-theme="dark"] .alert-info {
  background: rgba(59,130,246,.14); color: #93C5FD; border-color: rgba(59,130,246,.4); }
[data-theme="dark"] .alert-success {
  background: rgba(34,197,94,.14); color: #4ADE80; border-color: rgba(34,197,94,.4); }
[data-theme="dark"] .alert-warning {
  background: rgba(245,158,11,.14); color: #FBBF24; border-color: rgba(245,158,11,.4); }
[data-theme="dark"] .alert-danger {
  background: rgba(239,68,68,.14); color: #F87171; border-color: rgba(239,68,68,.4); }
[data-theme="dark"] .alert-primary {
  background: rgba(255,107,53,.14); color: #FF9B6B; border-color: rgba(255,107,53,.4); }
[data-theme="dark"] .alert a, [data-theme="dark"] .alert .alert-link { color: inherit; }

/* Toasts (flash messages) — readable in both themes. */
.toast { box-shadow: var(--shadow-lg); border-radius: 12px; }
[data-theme="dark"] .toast { background: var(--surface); color: var(--text); border-color: var(--border); }
[data-theme="dark"] .toast .toast-header { background: var(--surface-2); color: var(--text);
  border-bottom-color: var(--border); }
[data-theme="dark"] .toast .toast-body { color: var(--text); }
[data-theme="dark"] .toast .btn-close { filter: invert(1) grayscale(1) brightness(1.6); }

/* Confirmation modal (delete / undo / sync yes-no) — polished + eye-catching. */
.confirm-modal .modal-content { border: none; border-radius: 16px; overflow: hidden;
  border-top: 5px solid var(--primary); }
.confirm-modal .modal-header { border-bottom: none; padding-bottom: .25rem; }
.confirm-modal .modal-title { display: flex; align-items: center; gap: .6rem; font-weight: 700; }
.confirm-icon { width: 42px; height: 42px; border-radius: 12px; flex: 0 0 42px;
  display: inline-flex; align-items: center; justify-content: center; font-size: 1.15rem;
  color: #fff; background: #F59E0B; }
.confirm-modal .modal-body { color: var(--muted); padding-top: .25rem; }
.confirm-modal .modal-footer { border-top: none; }
.confirm-modal .modal-footer .btn { min-width: 96px; font-weight: 600; }

/* dcc.Dropdown (react-select) control: match .form-control / datepicker so every
   filter input shares the same 10px rounded corners and 40px height (no squarer box). */
.Select-control { border-radius: 10px !important; min-height: 40px !important; }
.Select--single .Select-control .Select-value,
.Select-control .Select-placeholder { line-height: 38px !important; }
.Select-input { height: 38px !important; }

/* dcc.Dropdown (react-select) — dark theme. Without this the menu is white-on-white. */
[data-theme="dark"] .Select-control,
[data-theme="dark"] .Select.is-focused > .Select-control {
  background: var(--surface-2) !important; border-color: var(--border) !important; color: var(--text); }
[data-theme="dark"] .Select-menu-outer,
[data-theme="dark"] .VirtualizedSelectFocusedOption { background: var(--surface-2) !important;
  border-color: var(--border) !important; color: var(--text); }
[data-theme="dark"] .Select-option { background: var(--surface-2) !important; color: var(--text) !important; }
[data-theme="dark"] .Select-option.is-focused { background: var(--surface) !important; }
[data-theme="dark"] .Select-option.is-selected { background: rgba(255,107,53,.22) !important; }
[data-theme="dark"] .Select-value-label,
[data-theme="dark"] .Select--single > .Select-control .Select-value .Select-value-label,
[data-theme="dark"] .Select-input > input { color: var(--text) !important; }
[data-theme="dark"] .Select-placeholder,
[data-theme="dark"] .Select--single > .Select-control .Select-placeholder { color: var(--muted) !important; }
[data-theme="dark"] .Select--multi .Select-value {
  background: rgba(255,107,53,.18); border-color: var(--primary); color: var(--text); }
[data-theme="dark"] .Select-arrow { border-color: var(--muted) transparent transparent; }
[data-theme="dark"] .is-open .Select-arrow { border-color: transparent transparent var(--muted); }
.text-muted { color: var(--muted) !important; }

/* ---- Brand logo (horizontal Kirrhosoft mark) ---- */
.brand-logo { max-height: 40px; width: auto; max-width: 100%; object-fit: contain; display: block; }
.brand { display: flex; align-items: center; justify-content: center; }
/* Clickable brand logo (sidebar/offcanvas) → dashboard. */
.brand-link { display: inline-flex; align-items: center; cursor: pointer; transition: opacity .15s; margin-right: 1rem; }
.brand-link:hover { opacity: .8; }
/* Logo shown on the dashboard body greeting. */
.dash-greeting .brand-logo { max-height: 38px; margin-bottom: .35rem; }
.login-logo { display: flex; justify-content: center; }
.login-logo .brand-logo { max-height: 48px; }
/* The wordmark is dark; on dark surfaces sit it on a small light chip so it stays legible. */
[data-theme="dark"] .brand-logo {
  background: #fff; border-radius: 8px; padding: 5px 9px;
}

/* ---- Reports preview modal ---- */
.report-modal .modal-content { border: none; border-radius: 16px; overflow: hidden;
  border-top: 4px solid var(--primary); }
.report-modal .modal-title { display: flex; align-items: center; gap: .6rem; font-weight: 700; }
.report-modal-icon { width: 38px; height: 38px; border-radius: 10px; flex: 0 0 38px;
  display: inline-flex; align-items: center; justify-content: center; color: #fff;
  background: var(--primary); font-size: 1rem; }
.report-modal .modal-body { padding: 1.25rem 1.5rem; }
.report-preview-head { display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; margin-bottom: .85rem; flex-wrap: wrap; }
.report-count-chip { background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 999px; padding: .3rem .8rem; font-weight: 700; font-size: .82rem; color: var(--text); }
.report-preview-table { border: 1px solid var(--border); border-radius: 12px; overflow-x: auto; }
.report-preview-table .data-table th { background: var(--surface-2); position: sticky; top: 0; }
.report-modal .modal-footer { gap: .5rem; }
/* On phones the three export actions wrap into a ragged 1-then-2 arrangement. Stack them
   full width instead, so each is an unambiguous target and the order reads top to bottom. */
@media (max-width: 480px) {
  .report-modal .modal-footer { flex-direction: column; align-items: stretch; }
  .report-modal .modal-footer .btn { width: 100%; margin: 0; }
}

/* Field picker (include/exclude columns before CSV/PDF export) — Reports + Analytics.
   The native checkboxes are hidden and each option is styled as a toggle chip. */
.field-picker { background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 14px; padding: .8rem .9rem; margin-bottom: 1rem; }
.field-picker-bar { display: flex; align-items: center; gap: .5rem; margin-bottom: .65rem; }
.field-picker-ico { color: var(--primary); font-size: .9rem; }
.field-picker-label { font-weight: 700; font-size: .74rem; text-transform: uppercase;
  letter-spacing: .05em; color: var(--text); }
.field-picker-count { font-size: .75rem; color: var(--muted); font-weight: 600; }
.field-picker-actions { margin-left: auto; display: flex; align-items: center; gap: .25rem; }
.field-picker-act { border: 1px solid var(--border); background: var(--surface);
  color: var(--muted); border-radius: 8px; padding: .2rem .55rem; font-size: .76rem;
  font-weight: 600; cursor: pointer; transition: all .15s ease; }
.field-picker-act:hover { border-color: var(--primary); color: var(--primary); }

/* Toggle chips */
.field-chips { display: flex; flex-wrap: wrap; gap: .45rem; padding: 0; }
.field-chips .form-check { margin: 0; padding: 0; min-height: 0; display: inline-flex; }
.field-chips .form-check-input { position: absolute; opacity: 0; width: 0; height: 0;
  margin: 0; pointer-events: none; }
.field-chips .form-check-label { display: inline-flex; align-items: center; gap: .4rem;
  padding: .34rem .72rem; border: 1px solid var(--border); border-radius: 999px;
  background: var(--surface); color: var(--muted); font-size: .82rem; font-weight: 500;
  cursor: pointer; transition: all .15s ease; user-select: none; line-height: 1.2; }
.field-chips .form-check-label::before { content: "+"; font-weight: 700; font-size: .82rem;
  opacity: .5; transition: all .15s ease; }
.field-chips .form-check-label:hover { border-color: var(--primary); color: var(--primary); }
.field-chips .form-check-input:checked + .form-check-label {
  background: var(--primary); border-color: var(--primary); color: #fff; font-weight: 600;
  box-shadow: 0 2px 7px rgba(255,107,53,.30); }
.field-chips .form-check-input:checked + .form-check-label::before {
  content: "\2713"; opacity: 1; }
.field-chips .form-check-input:focus-visible + .form-check-label {
  outline: 2px solid var(--primary); outline-offset: 2px; }
[data-theme="dark"] .field-chips .form-check-input:checked + .form-check-label { color: #fff; }

/* ---- Sync split-control (button + caret dropdown) ---- */
.btn-group > .dropdown > .dropdown-toggle-split { padding-left: .5rem; padding-right: .5rem; }
.btn-group > .dropdown .dropdown-menu { min-width: 220px; }
.dropdown-toggle-split::after { margin-left: 0; }

/* ---- App footer (copyright) ---- */
.app-footer { margin-top: auto; padding: 1.1rem 1.5rem; text-align: center;
  color: var(--muted); font-size: .82rem; border-top: 1px solid var(--border); }
.app-footer .app-footer-sep { opacity: .7; }
.main-page { flex: 1 0 auto; }
.main-col { display: flex; flex-direction: column; min-height: 100vh; }

/* ---- Settings page: horizontal tabs + single visible panel ---- */
.settings-tabs {
  display: flex; flex-wrap: nowrap; gap: .15rem; margin-bottom: 1.4rem;
  border-bottom: 2px solid var(--border); overflow-x: auto;
  -webkit-overflow-scrolling: touch; scrollbar-width: thin;
}
.settings-tabs .settings-navlink {
  color: var(--muted) !important; cursor: pointer; white-space: nowrap;
  padding: .72rem 1.1rem !important; font-weight: 600; display: flex; align-items: center;
  border: none !important; border-radius: 10px 10px 0 0 !important;
  border-bottom: 2px solid transparent !important; margin-bottom: -2px;
  background: transparent !important; transition: .15s;
}
.settings-tabs .settings-navlink:hover {
  color: var(--primary) !important; background: var(--surface-2) !important;
}
.settings-tabs .settings-navlink.active {
  color: var(--primary) !important; background: transparent !important;
  border-bottom-color: var(--primary) !important; box-shadow: none !important;
}
.settings-tabs .settings-navlink i { width: 18px; text-align: center; }
.settings-content { min-width: 0; }
/* Right-align every Save button inside Settings tabs on desktop. */
.settings-content .action-right-sm { display: flex; justify-content: flex-end; }
/* Always right-aligned, every width. Deliberately NOT a change to `.action-right-sm`, which is
   phone-only outside Settings on purpose — widening it would also move Add Bonus, bulk office
   hours and the payroll actions on desktop. */
.action-right { display: flex; justify-content: flex-end; }
@media (max-width: 768px) {
  .settings-tabs .settings-navlink { padding: .6rem .85rem !important; }
}

/* ---- Payroll Rules deduction sub-cards ---- */
.policy-subcard {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 1px 2px rgba(0,0,0,.04), 0 4px 12px rgba(0,0,0,.04);
  transition: transform .12s ease, box-shadow .12s ease, border-color .12s ease;
}
.policy-subcard:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 10px rgba(0,0,0,.06), 0 10px 24px rgba(0,0,0,.06);
  border-color: rgba(255,107,53,.35);
}
.policy-subcard .card-body { padding: 1.1rem 1.15rem !important; }
.policy-subcard .card-title,
.policy-subcard h6 { color: var(--text); letter-spacing: -.01em; }
[data-theme="dark"] .policy-subcard { background: var(--surface-2); }

.policy-limit-card {
  background: linear-gradient(135deg, rgba(255,107,53,.08), rgba(255,107,53,.02));
  border: 1px solid rgba(255,107,53,.25);
  border-radius: 14px;
  box-shadow: 0 1px 2px rgba(0,0,0,.04), 0 4px 12px rgba(0,0,0,.04);
}
.policy-limit-card .card-body { padding: 1.1rem 1.15rem !important; }
[data-theme="dark"] .policy-limit-card {
  background: linear-gradient(135deg, rgba(255,107,53,.10), rgba(255,107,53,.03));
  border-color: rgba(255,107,53,.35);
}

@media (max-width: 991.98px) {
  .policy-subcard, .policy-limit-card { margin-bottom: .75rem; }
}

/* ---- Payroll detail summary tiles ---- */
.pay-tile { border-radius: 10px; padding: .8rem 1rem; text-align: center; border: 1px solid; }
.pay-tile-label { font-size: .72rem; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; opacity: .8; }
.pay-tile-value { font-size: 1.25rem; font-weight: 800; margin-top: .2rem; }
.pay-tile.tile-green { background: rgba(46,125,50,.10); border-color: rgba(46,125,50,.4); color: #2E7D32; }
.pay-tile.tile-red { background: rgba(198,40,40,.10); border-color: rgba(198,40,40,.4); color: #C62828; }
.pay-tile.tile-orange { background: rgba(255,107,53,.12); border-color: rgba(255,107,53,.5); color: #FF6B35; }
[data-theme="dark"] .pay-tile.tile-green { color: #66BB6A; }
[data-theme="dark"] .pay-tile.tile-red { color: #EF5350; }
[data-theme="dark"] .pay-tile.tile-orange { color: #FF9E7A; }

/* ---- Payslip Breakdown modal (redesigned) ---- */
.pay-detail-body { padding: 1.25rem 1.4rem 1.5rem !important; }
.pay-detail-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: .75rem; padding: 1rem 1.15rem; margin-bottom: 1.1rem;
  border-radius: 12px; border: 1px solid var(--border);
  background: linear-gradient(135deg, rgba(255,107,53,.10), rgba(255,107,53,.02));
}
.pay-detail-name { font-size: 1.2rem; font-weight: 800; line-height: 1.1; }
.pay-detail-period { font-size: .85rem; color: var(--muted); margin-top: .2rem; }
.pay-sec { margin: 0 !important; }
.pay-sec > .card-body { padding: 1rem 1.15rem !important; }
.pay-sec-title { font-weight: 700; margin-bottom: .6rem; font-size: .95rem; }
/* Inner tables in the modal sit flush with the card padding. */
.pay-detail .data-table { margin: 0; }
.pay-detail .data-table table { width: 100%; }
@media (max-width: 640px) {
  .pay-detail-body { padding: 1rem !important; }
  .pay-detail-head { flex-wrap: wrap; padding: .85rem 1rem; }
  .pay-detail-name { font-size: 1.05rem; }
}

/* ---- Leave action button (LeaveActionButton cell renderer) ---- */
.lv-action-btn { border: none; border-radius: 6px; padding: 3px 12px; font-size: .78rem;
  font-weight: 700; cursor: pointer; color: #fff; line-height: 1.4; }
.lv-action-review { background: #FF6B35; }
.lv-action-undo { background: var(--surface-2); color: var(--text); border: 1px solid var(--border); }
.lv-action-btn:hover { opacity: .9; }
.ag-theme-quartz .ag-cell.ag-action, .ag-theme-quartz-dark .ag-cell.ag-action {
  display: flex; align-items: center; }

/* ---- AG Grid status pill (StatusPill cell renderer) ----
   The pill is a self-contained <span>; keep it tight (auto width, not stretched)
   and vertically centred in the cell so it never "spreads" across the row. */
.ag-theme-quartz .ag-cell .pill,
.ag-theme-quartz-dark .ag-cell .pill {
  width: auto; max-width: 100%; align-self: center; vertical-align: middle;
}
/* Give the pill's cell a flex box so the span centres both ways. */
.ag-theme-quartz .ag-cell:has(> .pill),
.ag-theme-quartz-dark .ag-cell:has(> .pill) {
  display: flex; align-items: center;
}

/* ---- Attendance calendar ---- */
.cal-legend { display: flex; flex-wrap: wrap; gap: 1rem; align-items: center;
  margin: .25rem 0 1rem; font-size: .85rem; }
.cal-legend .cal-legend-icon { font-size: 1rem; }
.ag-cal { text-align: center; cursor: pointer; font-size: 1rem; padding: 0 !important; }
.ag-cal-h { justify-content: center; }
.ag-cal-h .ag-header-cell-label { justify-content: center; }
/* Week starts on Sunday: a divider on each Sunday column (cell + header) marks
   the start of a new week across the horizontal day strip. */
.ag-cal-wk { border-left: 2px solid var(--primary) !important; }
/* Leading cells = previous month's trailing days (dimmed so they read as
   "not this month" while still showing the real status colour/dot). */
.ag-cal-pad { opacity: .45; cursor: default; }
.ag-cal-pad-h { opacity: .6; }
.ag-cal-pad-h .ag-header-cell-text { font-style: italic; }

/* ---- Monthly Summary (att-grid): per-column semantic colours (value + header),
   matching the attendance stat cards. Brighter tones in dark theme so mid-tone
   colours stay legible on the dark grid surface. ---- */
.ag-cell.att-c-green,  .ag-header-cell.att-c-green  .ag-header-cell-text { color: #2E7D32; font-weight: 600; }
.ag-cell.att-c-amber,  .ag-header-cell.att-c-amber  .ag-header-cell-text { color: #B45309; font-weight: 600; }
.ag-cell.att-c-red,    .ag-header-cell.att-c-red    .ag-header-cell-text { color: #DC2626; font-weight: 600; }
.ag-cell.att-c-blue,   .ag-header-cell.att-c-blue   .ag-header-cell-text { color: #2563EB; font-weight: 600; }
.ag-cell.att-c-orange, .ag-header-cell.att-c-orange .ag-header-cell-text { color: #EA580C; font-weight: 600; }
.ag-cell.att-c-teal,   .ag-header-cell.att-c-teal   .ag-header-cell-text { color: #0D9488; font-weight: 600; }
.ag-cell.att-c-net { color: #2E7D32; font-weight: 700; }
[data-theme="dark"] .ag-cell.att-c-green,  [data-theme="dark"] .ag-header-cell.att-c-green  .ag-header-cell-text,
[data-theme="dark"] .ag-cell.att-c-net  { color: #66BB6A; }
[data-theme="dark"] .ag-cell.att-c-amber,  [data-theme="dark"] .ag-header-cell.att-c-amber  .ag-header-cell-text { color: #FBBF24; }
[data-theme="dark"] .ag-cell.att-c-red,    [data-theme="dark"] .ag-header-cell.att-c-red    .ag-header-cell-text { color: #F87171; }
[data-theme="dark"] .ag-cell.att-c-blue,   [data-theme="dark"] .ag-header-cell.att-c-blue   .ag-header-cell-text { color: #60A5FA; }
[data-theme="dark"] .ag-cell.att-c-orange, [data-theme="dark"] .ag-header-cell.att-c-orange .ag-header-cell-text { color: #FB923C; }
[data-theme="dark"] .ag-cell.att-c-teal,   [data-theme="dark"] .ag-header-cell.att-c-teal   .ag-header-cell-text { color: #2DD4BF; }

/* Mobile: tighten ALL tables + page chrome so data isn't crowded out by
   padding, and lay filter bars out as one even row. Desktop is untouched. */
@media (max-width: 640px) {
  /* Less page/card chrome → more width for the data. */
  .page { padding: .7rem; }
  .card > .card-body { padding: .8rem; }

  /* Denser AG-Grid tables (system-wide): trim cell padding, grid spacing,
     header height and font so more columns/rows are visible. */
  .ag-theme-quartz, .ag-theme-quartz-dark {
    --ag-cell-horizontal-padding: 6px;
    --ag-grid-size: 4px;
    --ag-font-size: 12px;
    --ag-header-height: 40px;
    --ag-row-height: 38px;
  }
  /* Denser HTML render_table tables. */
  .data-table th, .data-table td { padding: .45rem .55rem; font-size: .8rem; }

  /* Filter bars (month/year/apply, etc.): two fields per row, evenly sized with
     consistent gaps and a uniform height. A lone trailing field (e.g. the 3rd of
     three, or a single Apply button) spans the full width on its own row. */
  .filter-bar { display: grid !important; grid-template-columns: 1fr 1fr;
    column-gap: .8rem !important; row-gap: .7rem !important; gap: .7rem .8rem !important;
    width: 100%; align-items: end;
    margin-left: 0 !important; margin-right: 0 !important; --bs-gutter-x: 0 !important; }
  .filter-bar > *, .filter-bar .col, .filter-bar [class*="col-"] {
    width: 100% !important; min-width: 0 !important;
    margin: 0 !important; padding-left: 0 !important; padding-right: 0 !important; }
  .filter-bar > *:last-child:nth-child(odd),
  .filter-bar > .col:last-child:nth-child(odd),
  .filter-bar > [class*="col-"]:last-child:nth-child(odd) { grid-column: 1 / -1; }
  .filter-bar .Select-control, .filter-bar input, .filter-bar .btn,
  .filter-bar .form-control, .filter-bar .form-select { min-height: 40px; }
  /* Apply (and any filter button) fills its grid cell so it matches the width of the
     adjacent input/dropdown (e.g. Analytics Month + Apply, and Year + Apply). */
  .filter-bar .btn {
    width: 100% !important; height: 40px !important; padding: .5rem .75rem !important;
    display: inline-flex !important; align-items: center; justify-content: center; }
  /* The rule above zeroes column gutters, but must NOT strip the inner padding of
     actual input fields — re-assert it so year/number/date inputs keep their padding
     on mobile (matches desktop). */
  .filter-bar input, .filter-bar .form-control, .filter-bar .form-select,
  .filter-bar .DateInput_input {
    padding: .5rem .75rem !important; }
  /* Date-range pickers (e.g. Leave Breakdown From/To): give them the SAME 40px
     height and comfortable vertical padding as the dropdown/button so the fields
     line up and don't look cramped on phones. */
  .filter-bar .app-datepicker, .filter-bar .SingleDatePicker,
  .filter-bar .SingleDatePickerInput, .filter-bar .DateInput { width: 100% !important; }
  .filter-bar .SingleDatePickerInput {
    min-height: 40px; display: flex; align-items: center; }
  .filter-bar .DateInput_input {
    min-height: 40px; padding: .5rem .75rem !important; }
  /* Labels inside Bootstrap column filter bars (e.g. Per-Employee Analytics) must
     not add extra vertical space that breaks alignment with simple filter bars. */
  .filter-bar label, .filter-bar .form-label {
    margin-bottom: .25rem; font-size: .8rem; }
  /* Leave Breakdown: one filter field per row on phones (each spans full width). */
  .filter-bar-stack { grid-template-columns: 1fr !important; }
  /* Employee dropdown fills the row like the date/apply fields (no desktop 200px). */
  .filter-bar-stack .lb-emp-w, .filter-bar-stack .lb-emp-w .Select { width: 100% !important; }
  /* Any dropdown in a filter bar fills its cell (beats inline px widths) so stacked
     rows (e.g. Payroll → Download Payslip) are all the same full width. */
  .filter-bar .dash-dropdown, .filter-bar .Select { width: 100% !important; }

  /* Dashboard quick actions (Add Employee / Run Payroll / Attendance / Holidays):
     equal-width buttons, two per row (2×2). */
  .qa-actions { display: grid !important; grid-template-columns: 1fr 1fr;
    gap: .5rem !important; width: 100%; }
  .qa-actions .btn { width: 100%; }

  /* Holidays actions: keep Year + Seed BD Public + Add on ONE row (Year compact,
     Seed flexes, Add sizes to content). */
  .hol-actions { display: grid !important; grid-template-columns: 100px 1fr auto;
    gap: .5rem !important; width: 100%; align-items: stretch; }
  .hol-actions > * { width: 100% !important; margin: 0 !important; min-width: 0; }
  .hol-actions input, .hol-actions .form-control, .hol-actions .btn {
    min-height: 40px; padding: .5rem .75rem; }
  .hol-actions .btn { height: 40px; display: inline-flex; align-items: center; justify-content: center; }

  /* Push a bare action button to the right edge on phones only — used where a
     permanent right-align would look wrong on desktop (Add Bonus sits beside the
     year field; the Settings save buttons follow their form). Not `.filter-bar`,
     so the button keeps its content width instead of stretching. */
  .action-right-sm { display: flex; justify-content: flex-end; }
  /* Payslip preview iframe inside a fullscreen modal: let it fill the body.
     On desktop the modal is xl-sized so 75vh is fine; on mobile the fullscreen
     modal should use flex to give the iframe all remaining space. */
  .modal-fullscreen-md-down .modal-body { flex: 1; display: flex; }
  .modal-fullscreen-md-down .modal-body iframe {
    flex: 1; height: auto !important; width: 100% !important; }
}
/* Status-tinted calendar cells (mirrors the employee month view) so the admin
   grid is scannable at a glance. Emoji is kept for colour-blind redundancy. */
.ag-cal.cal-present { background: rgba(46,125,50,.12); }
.ag-cal.cal-late    { background: rgba(245,158,11,.15); }
.ag-cal.cal-early   { background: rgba(147,51,234,.15); }
.ag-cal.cal-absent  { background: rgba(220,38,38,.12); }
.ag-cal.cal-off     { background: transparent; opacity: .55; }
.ag-cal.cal-offwork { background: rgba(13,148,136,.18); }
[data-theme="dark"] .ag-cal.cal-present { background: rgba(74,222,128,.16); }
[data-theme="dark"] .ag-cal.cal-late    { background: rgba(251,191,36,.16); }
[data-theme="dark"] .ag-cal.cal-early   { background: rgba(192,132,252,.18); }
[data-theme="dark"] .ag-cal.cal-absent  { background: rgba(248,113,113,.16); }
[data-theme="dark"] .ag-cal.cal-offwork { background: rgba(45,212,191,.20); }

/* Keep every control in a filter bar on ONE row on desktop. A .app-datepicker is
   width:100% (so it fills a form column), which inside a flex filter-bar forces each
   picker onto its own line — pin them to a compact fixed width here. Mobile (<=640px)
   still stacks them via the 2-col grid rule above. */
@media (min-width: 641px) {
  .filter-bar .app-datepicker { width: auto; display: inline-block; }
  .filter-bar .app-datepicker .SingleDatePickerInput,
  .filter-bar .app-datepicker .DateInput,
  .filter-bar .app-datepicker .DateInput_input { width: 150px; }
  /* Leave Breakdown employee dropdown: compact fixed width on desktop only. */
  .lb-emp-w { width: 200px; }
  /* Payroll → Download Payslip: fixed widths on desktop only (mobile stacks full-width). */
  .ps-emp-w { width: 280px; }
  .ps-month-w { width: 140px; }
}

/* Leave Breakdown table — related status colours (value + header). */
.lv-applied  { color: var(--primary); font-weight: 600; }
.lv-approved { color: #2E7D32; font-weight: 600; }
.lv-rejected { color: #DC2626; font-weight: 600; }
.lv-pending  { color: #B45309; font-weight: 600; }
[data-theme="dark"] .lv-approved { color: #66BB6A; }
[data-theme="dark"] .lv-rejected { color: #F87171; }
[data-theme="dark"] .lv-pending  { color: #FBBF24; }

/* ---- Empty states (tables + grids) ---- */
.empty-state { display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: .5rem; padding: 2.25rem 1rem; text-align: center; }
.empty-state-icon { font-size: 2rem; color: var(--muted); opacity: .55; }
.empty-state-text { color: var(--muted); font-size: .92rem; }
.ag-empty-state { display: flex; flex-direction: column; align-items: center;
  gap: .5rem; color: var(--muted); padding: 1rem; }
.ag-empty-state i { font-size: 1.9rem; opacity: .5; }

/* Number-input spin buttons are near-invisible on the dark surface — brighten. */
[data-theme="dark"] input[type="number"]::-webkit-inner-spin-button,
[data-theme="dark"] input[type="number"]::-webkit-outer-spin-button {
  filter: invert(0.85); }

/* ---- Breadcrumbs ---- */
.breadcrumb-bar { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  padding: .7rem 1.75rem 0; font-size: .85rem; }
.breadcrumb-bar .bc-link { color: var(--primary); text-decoration: none; }
.breadcrumb-bar .bc-link:hover { text-decoration: underline; }
.breadcrumb-bar .bc-current { color: var(--muted); font-weight: 600; }
.breadcrumb-bar .bc-sep { color: var(--muted); }
@media (max-width: 991px) { .breadcrumb-bar { padding: .6rem 1.15rem 0; } }

/* ---- AG Grid: link + action cells ---- */
.ag-link { color: var(--primary); font-weight: 600; cursor: pointer; }
.ag-link:hover { text-decoration: underline; }
.ag-action { cursor: pointer; text-align: center; font-size: 1.05rem; }
.ag-theme-quartz, .ag-theme-quartz-dark {
  --ag-font-family: inherit; --ag-border-radius: 10px;
  --ag-header-background-color: var(--surface-2);
}
.ag-theme-quartz { --ag-active-color: var(--primary); }

/* ---- Avatars ---- */
.avatar-img { border-radius: 50%; object-fit: cover; border: 2px solid var(--border); }
.avatar-initials {
  border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
  background: var(--brand-grad); color: #fff; font-weight: 700;
}

/* ---- Top-bar user chip ---- */
.user-chip {
  display: flex; align-items: center; gap: .6rem; text-decoration: none;
  padding: .25rem .6rem .25rem .3rem; border-radius: 999px; border: 1px solid var(--border);
  color: var(--text); transition: .15s; margin-left: .15rem;
}
.user-chip:hover { border-color: var(--primary); color: var(--text); }
.user-chip-text { display: flex; flex-direction: column; line-height: 1.1; }
.user-chip-name { font-weight: 600; font-size: .88rem;
  max-width: 12rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.user-chip-role { font-size: .72rem; color: var(--muted);
  max-width: 12rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 640px) { .user-chip-text { display: none; }
  .user-chip { border: none; padding: 0; gap: 0; margin-left: 0; } }

/* Loading spinners (dcc.Loading): overlay a centred spinner while keeping the
   underlying content visible (dimmed) instead of blanking the page. The default
   (container) variant centres the spinner inside its own box so tables/forms show
   feedback right where the data updates; the .kirrho-loading-page variant pins the
   spinner to the CENTRE OF THE VIEWPORT (fixed) for full-page navigation. */
.kirrho-loading { min-height: 48px; position: relative; }
.kirrho-loading .dash-spinner {
  position: absolute !important; top: 50%; left: 50%;
  transform: translate(-50%, -50%) scale(1.15); z-index: 1200;
}
.kirrho-loading .dash-spinner * {
  border-color: var(--primary) transparent var(--primary) transparent !important;
}
/* Full-page / navigation loader: fixed to the viewport centre so it reads as a
   system-wide transition regardless of scroll position. */
.kirrho-loading-page { min-height: 60vh; }
.kirrho-loading-page .dash-spinner {
  position: fixed !important; top: 50%; left: 50%;
  transform: translate(-50%, -50%) scale(1.4); z-index: 1200;
}
._dash-loading-callback, .dash-loading { color: var(--primary); }
/* Button spinner spacing */
.btn .spinner-border-sm { width: 1rem; height: 1rem; vertical-align: -0.15em; }

/* Thin indeterminate progress bar across the very top of the screen, shown briefly
   on navigation for lightweight feedback without blanking the page. */
.nav-progress {
  position: fixed; top: 0; left: 0; right: 0; height: 3px;
  z-index: 2400; overflow: hidden; pointer-events: none;
  background: transparent; display: none;
}
.nav-progress.active { display: block; }
.nav-progress::before {
  content: ""; position: absolute; top: 0; left: -40%; width: 40%; height: 100%;
  background: linear-gradient(90deg, transparent, var(--primary), transparent);
  border-radius: 3px;
  animation: nav-progress-slide 0.35s ease-in-out infinite;
}
@keyframes nav-progress-slide {
  0% { left: -40%; }
  100% { left: 100%; }
}


/* --------------------------------------------- Role permission matrix (Settings) -- */
/* Seventy-odd switches, so the grid is grouped by module and collapsed by default.
   `grid-template-columns` is set inline-free here: one flexible label column and a fixed
   column per role, so the switches line up under their headings across every group. */
.perm-matrix { display: flex; flex-direction: column; gap: .25rem; }
.perm-row {
  display: grid; grid-template-columns: minmax(12rem, 1fr) repeat(3, 7.5rem);
  align-items: center; gap: .5rem; padding: .35rem .5rem; border-radius: 8px;
}
.perm-row:hover { background: var(--surface-2); }
.perm-head { font-weight: 700; border-bottom: 1px solid var(--border); border-radius: 0;
  position: sticky; top: 0; background: var(--surface); z-index: 1; }
.perm-head-label { color: var(--muted); font-size: .82rem; text-transform: uppercase;
  letter-spacing: .03em; }
.perm-label { font-size: .88rem; }
.perm-cell { display: flex; justify-content: center; }

.perm-group { border: 1px solid var(--border); border-radius: 10px; overflow: hidden; }
.perm-group + .perm-group { margin-top: .4rem; }
.perm-group > summary {
  cursor: pointer; padding: .6rem .75rem; font-weight: 600; list-style: none;
  background: var(--surface-2); display: flex; align-items: center; gap: .5rem;
}
.perm-group > summary::-webkit-details-marker { display: none; }
/* A caret that turns, so open/closed reads without hunting for the triangle. */
.perm-group > summary::before {
  content: "\25B8"; display: inline-block; transition: transform .12s ease;
  color: var(--muted);
}
.perm-group[open] > summary::before { transform: rotate(90deg); }
.perm-group > summary:hover { background: color-mix(in srgb, var(--primary) 8%, var(--surface-2)); }
.perm-group-title { font-size: .92rem; }
.perm-group-body { padding: .35rem .5rem .5rem; }
/* Hidden by the filter box; `!important` because the row is a grid when visible. */
.perm-row.perm-hidden { display: none !important; }

/* Below this the three role columns cannot fit beside the label: at 320px the row needed
   134px more than it had, and the last role's switch sat off-screen where it could not be
   reached at all. Stack instead of scrolling sideways — a settings screen should not need
   a swipe to reach a control. Each switch is captioned with its role, because a column
   heading is nowhere near its switch once the columns are gone. */
@media (max-width: 720px) {
  .perm-head { display: none; }
  .perm-row { display: block; padding: .5rem .25rem; }
  .perm-row + .perm-row { border-top: 1px solid var(--border); }
  .perm-label { font-size: .85rem; font-weight: 600; padding-left: 0 !important;
    margin-bottom: .35rem; }
  .perm-group-body .perm-row .perm-label { padding-left: 0 !important; }
  .perm-cell {
    display: inline-flex; align-items: center; gap: .35rem;
    margin: 0 1.1rem .15rem 0; justify-content: flex-start;
  }
  .perm-cell::before {
    content: attr(data-role); font-size: .74rem; color: var(--muted);
    white-space: nowrap;
  }
}

/* --------------------------------------------------------------- Audit Log -- */
.audit-meta { display: flex; flex-wrap: wrap; gap: 1rem; margin-bottom: 1rem; }
.audit-meta-item { display: flex; flex-direction: column; gap: .15rem; }
.audit-meta-label { font-size: .7rem; text-transform: uppercase; letter-spacing: .04em;
  color: var(--muted); font-weight: 600; }
.audit-meta-value { font-size: .9rem; font-weight: 600; color: var(--text); }

.audit-section-title { font-size: .85rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; color: var(--muted); margin: 1.25rem 0 .5rem; }

/* What Changed - inline diff cards */
.audit-diff-list { display: flex; flex-direction: column; gap: .75rem; }
.audit-diff-card {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: .65rem;
  padding: .75rem 1rem;
  box-shadow: 0 1px 2px rgba(0,0,0,.04);
}
.audit-diff-field-wrap { margin-bottom: .5rem; }
.audit-diff-field {
  font-size: .8rem;
  font-weight: 700;
  color: var(--primary);
  background: color-mix(in srgb, var(--primary) 10%, transparent);
  padding: .2rem .5rem;
  border-radius: .35rem;
}
.audit-diff-values {
  display: flex;
  align-items: center;
  gap: .75rem;
}
.audit-diff-side {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: .15rem;
}
.audit-diff-label {
  font-size: .65rem;
  text-transform: uppercase;
  letter-spacing: .06em;
  font-weight: 700;
  color: var(--muted);
}
.audit-diff-old-value {
  color: #DC2626;
  text-decoration: line-through;
  opacity: .9;
  word-break: break-word;
}
.audit-diff-new-value {
  color: #15803D;
  font-weight: 600;
  word-break: break-word;
}
.audit-diff-arrow {
  flex: 0 0 auto;
  width: 2rem;
  height: 2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--muted);
  font-size: .85rem;
}
[data-theme="dark"] .audit-diff-old-value { color: #F87171; }
[data-theme="dark"] .audit-diff-new-value { color: #66BB6A; }

/* Full snapshot cards (Previous / Updated Data) */
.audit-data-card {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: .65rem;
  overflow: hidden;
  height: 100%;
  display: flex;
  flex-direction: column;
}
.audit-data-card-header {
  padding: .55rem .85rem;
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
  font-size: .75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--muted);
}
.audit-data-card-body {
  padding: .85rem;
  flex: 1 1 auto;
  overflow: auto;
  max-height: 360px;
}

/* Legacy table diff (kept for any callers) */
.audit-diff-table { width: 100%; border-collapse: collapse; font-size: .85rem; }
.audit-diff-table th { text-align: left; padding: .5rem .6rem; background: var(--surface-2);
  color: var(--muted); font-weight: 600; border-bottom: 1px solid var(--border); }
.audit-diff-table td { padding: .5rem .6rem; border-bottom: 1px solid var(--border);
  vertical-align: top; word-break: break-word; }
.audit-diff-table tr.changed td { background: rgba(245,158,11,.06); }
.audit-diff-table .diff-field { font-weight: 600; color: var(--text); width: 30%; }
.audit-diff-table .diff-old { color: #DC2626; text-decoration: line-through; }
.audit-diff-table .diff-new { color: #2E7D32; font-weight: 600; }
[data-theme="dark"] .audit-diff-table .diff-old { color: #F87171; }
[data-theme="dark"] .audit-diff-table .diff-new { color: #66BB6A; }

.audit-json { background: var(--surface-2); border: 1px solid var(--border);
  border-radius: .5rem; padding: .75rem; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: .8rem; white-space: pre-wrap; word-break: break-word; max-height: 320px; overflow: auto; }
.audit-empty { color: var(--muted); font-style: italic; font-size: .85rem; }

.audit-value-wrap { background: var(--surface-2); border: 1px solid var(--border);
  border-radius: .5rem; padding: .75rem; }
.audit-value-table { width: 100%; border-collapse: collapse; font-size: .85rem; }
.audit-value-table th { text-align: left; padding: .4rem .5rem; background: var(--surface-3);
  color: var(--text); font-weight: 600; border-bottom: 1px solid var(--border); }
.audit-value-table td { padding: .4rem .5rem; border-bottom: 1px solid var(--border);
  vertical-align: top; }
.audit-value-table tr:last-child td { border-bottom: none; }
.audit-value-table .audit-key { font-size: .8rem; color: var(--primary); background: transparent; }
.audit-list { margin: 0; padding-left: 1.25rem; }
.audit-list-item { margin-bottom: .15rem; }
.audit-summary { background: rgba(13, 202, 240, .08); border: 1px solid rgba(13, 202, 240, .25);
  border-radius: .5rem; padding: .6rem .75rem; font-size: .85rem; color: var(--text); }

.audit-filters { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-end;
  gap: .75rem; margin-bottom: 1rem; }
.audit-filters-left { display: flex; flex-wrap: wrap; gap: .75rem; flex: 1 1 auto; align-items: flex-end; }
.audit-filters-right { display: flex; flex-wrap: wrap; gap: .75rem; flex: 0 0 auto; align-items: flex-end; }
.audit-search-input { min-width: 220px; flex: 1 1 220px; }
.audit-target-select { min-width: 200px; flex: 1 1 200px; }
.audit-filters .form-control, .audit-filters .Select-control { min-width: 160px; }
.audit-filters-right .Select-control { width: 160px; }

/* Holiday form mode switch spacing */
.hol-date-mode { margin-top: .25rem; }
