/* Google Fonts @import removed: it was an external, render-blocking request to
   Google's servers on every single page load (extra DNS + connection, sends
   visitor IP/UA to Google, and the browser can't paint anything until it
   finishes downloading). The font-family stacks below already fall back to
   solid, zero-network-cost system fonts (Segoe UI / -apple-system / Roboto /
   monospace), so the page now renders instantly with no external dependency. */

/* ---- DB. Ver 5.1 visual identity — "Aurora Canopy" (bright pass) ----
   Inspired by a spectrum gradient (magenta/ember -> amber -> chartreuse ->
   emerald -> teal -> cyan) instead of the earlier ink-navy + brass duotone.
   Every accent is tuned toward its brighter, higher-chroma end rather than
   a muted/dark shade -- including the sidebar, which is now a vivid teal-
   to-cyan panel instead of a near-black navy-green one. The warm ember-to-
   amber gradient is reserved for calls-to-action (primary buttons, login
   submit, the sidebar brand mark) so it still reads as "the thing to
   click." The background stays a bright, airy canvas with soft spectrum
   glows bleeding in from the corners. */
:root {
  --bg: #f6f8f4;
  --bg-grad:
    radial-gradient(circle at 6% -4%, rgba(255,72,110,0.16) 0%, transparent 62%),
    radial-gradient(circle at 100% 4%, rgba(255,171,45,0.20) 0%, transparent 66%),
    radial-gradient(circle at 18% 96%, rgba(20,184,221,0.20) 0%, transparent 70%),
    radial-gradient(circle at 92% 100%, rgba(100,120,212,0.16) 0%, transparent 66%),
    linear-gradient(180deg, #fafbf6 0%, #f6f8f4 40%, #f0f3ea 100%);
  --surface: rgba(255, 255, 255, 0.5);
  --surface-alt: rgba(246, 248, 241, 0.46);
  --surface-hover: rgba(235, 240, 227, 0.68);
  --surface-solid: #ffffff;
  --surface-alt-solid: #f2f5ee;
  --border: rgba(222, 228, 210, 0.65);
  --border-strong: rgba(206, 214, 189, 0.85);
  --glass-blur: 28px;
  --glass-edge: inset 0 1px 0 rgba(255, 255, 255, 0.65);
  --text: #1a1f2b;
  --text-muted: #686d63;
  --text-faint: #9a9d8f;

  --primary: #12b381;
  --primary-dark: #0c7d59;
  --primary-light: #dcf5ea;
  --primary-grad: linear-gradient(135deg, #12b381 0%, #2bd39c 55%, #6ee6bb 100%);

  --brass: #ff6a3d;
  --brass-dark: #d94f24;
  --brass-light: #fde7d5;
  --brass-grad: linear-gradient(135deg, #ff4d6a 0%, #ff8a3d 55%, #ffd23f 100%);

  --accent: #14b8dd;
  --accent-light: #d7f2f6;

  --green: #6dc22c;
  --green-light: #e6f4da;
  --green-grad: linear-gradient(135deg, #6dc22c, #9be05a);

  --amber: #e8850f;
  --amber-light: #fbe7d3;
  --amber-grad: linear-gradient(135deg, #e8850f, #ffab3d);

  --red: #e8507a;
  --red-light: #fbe1e8;
  --red-grad: linear-gradient(135deg, #e8507a, #ff7a9c);

  --purple: #6478d4;
  --purple-light: #e7eafa;
  --purple-grad: linear-gradient(135deg, #6478d4, #8ea0ec);

  --shadow-xs: 0 1px 2px rgba(31, 32, 20, 0.05);
  --shadow-sm: 0 4px 16px rgba(31, 32, 20, 0.08);
  --shadow-md: 0 12px 36px rgba(31, 32, 20, 0.12);
  --shadow-lg: 0 28px 70px rgba(24, 26, 16, 0.22);
  --shadow-glow: 0 8px 26px rgba(255, 106, 61, 0.38);

  --radius: 16px;
  --radius-sm: 10px;
  --radius-lg: 20px;
  --sidebar-w: 264px;

  /* Sidebar is a fixed teal-to-cyan chrome panel -- deliberately NOT tied to
     the light/dark theme toggle (same "always-consistent-brand-chrome"
     pattern the login screen already uses), so it stays the app's one
     constant visual anchor across both themes. It's a vivid, saturated
     gradient rather than a dark navy one, with a warm ember active-state
     to echo the flame side of the moodboard against the cool panel. */
  --sidebar-bg: linear-gradient(165deg,
    rgba(22,110,10,0.98) 0%,
    rgba(30,130,14,0.97) 40%,
    rgba(18,100,8,0.98) 72%,
    rgba(10,72,4,0.99) 100%);
  --sidebar-text: rgba(255, 255, 255, 0.95);
  --sidebar-text-muted: rgba(185, 240, 165, 0.78);
  --sidebar-border: rgba(255, 255, 255, 0.12);
  --sidebar-hover-bg: rgba(255, 255, 255, 0.08);
  --sidebar-active-bg: rgba(255, 210, 80, 0.18);
  --sidebar-active-text: #ffe97a;
}

/* ============ DARK THEME ============ */
html[data-theme="dark"] {
  --bg: #101a2a;
  --bg-grad:
    radial-gradient(circle at 4% -6%, rgba(255,138,61, 0.28) 0%, transparent 62%),
    radial-gradient(circle at 100% 2%, rgba(18,179,129, 0.34) 0%, transparent 66%),
    radial-gradient(circle at 16% 96%, rgba(20,184,221, 0.30) 0%, transparent 70%),
    radial-gradient(circle at 88% 100%, rgba(100,120,212, 0.26) 0%, transparent 66%),
    linear-gradient(180deg, #182440 0%, #101a2a 35%, #0d1422 100%);
  --surface: rgba(24, 33, 55, 0.48);
  --surface-alt: rgba(30, 40, 68, 0.44);
  --surface-hover: rgba(38, 50, 82, 0.62);
  --surface-solid: #182338;
  --surface-alt-solid: #1e2942;
  --border: rgba(45, 57, 87, 0.7);
  --border-strong: rgba(58, 72, 109, 0.85);
  --glass-edge: inset 0 1px 0 rgba(255, 255, 255, 0.06);
  --text: #edeff5;
  --text-muted: #9ba3c0;
  --text-faint: #6b7396;

  --primary-light: #133527;
  --primary-dark: #6ef0bc;
  --brass-dark: #ffab7a;
  --brass-light: #3a2214;
  --accent-light: #0e2e35;
  --green-light: #1e3113;
  --amber-light: #3a2712;
  --red-light: #3a1620;
  --purple-light: #1c2440;

  --shadow-xs: 0 1px 0 rgba(0, 0, 0, 0.25);
  --shadow-sm: 0 1px 0 rgba(0, 0, 0, 0.28);
  --shadow-md: 0 2px 0 rgba(0, 0, 0, 0.30);
  --shadow-lg: 0 3px 0 rgba(0, 0, 0, 0.32);
}
html[data-theme="dark"] body {
  background-image: var(--bg-grad);
  background-size: 100% 100%;
  background-repeat: no-repeat;
  background-attachment: fixed;
}
/* Personal wallpaper: when a user picks their own background image (see
   #wallpaper-overlay / applyWallpaper() in js/app.js), the image + an
   adjustable dark scrim (--wallpaper-dim, set inline by JS) replace the
   default gradient entirely -- but ONLY on body, so it shows through behind
   every glass panel/card exactly like the default gradient does. Personal,
   per-browser/device setting; not part of the app's shared admin branding. */
html body.has-wallpaper,
html[data-theme="dark"] body.has-wallpaper {
  background-image: linear-gradient(rgba(0,0,0,var(--wallpaper-dim,0.35)), rgba(0,0,0,var(--wallpaper-dim,0.35))), var(--wallpaper-img) !important;
  background-size: cover !important;
  background-position: center !important;
  background-repeat: no-repeat !important;
  background-attachment: fixed !important;
}
/* The login screen is deliberately ALWAYS light-themed, regardless of the app's own
   dark/light toggle (which only applies once you're signed in) -- a consistent, bright,
   professional first-impression screen rather than something that changes depending on
   whatever theme a previous session happened to leave in localStorage. Every dark-theme
   override below is explicitly cancelled back to the light-theme values for #login-screen. */
html[data-theme="dark"] #login-screen.login-wrap {
  background:
    radial-gradient(circle at 8% 8%, rgba(18,179,129,0.16), transparent 42%),
    radial-gradient(circle at 92% 12%, rgba(255,106,61,0.14), transparent 40%),
    radial-gradient(circle at 88% 92%, rgba(46,74,122,0.16), transparent 42%),
    radial-gradient(circle at 6% 90%, rgba(8,150,170,0.12), transparent 40%),
    linear-gradient(160deg, #fbfaf6 0%, #f4f2ea 45%, #efede1 100%);
}
html[data-theme="dark"] #login-screen .login-card {
  background: rgba(255,255,255,0.88);
  border: 1px solid rgba(255,255,255,0.8);
}
html[data-theme="dark"] #login-screen .login-brand h1,
html[data-theme="dark"] #login-screen .field label {
  color: #1a1f2b;
}
html[data-theme="dark"] #login-screen .login-brand p {
  color: #0a5f45;
  background: #dcf5ea;
}
html[data-theme="dark"] #login-screen .login-copyright {
  color: #686d63;
}
html[data-theme="dark"] #login-screen .field input {
  background: #f6f5ef;
  color: #1a1f2b;
  border-color: #e3e0d2;
}
html[data-theme="dark"] #login-screen .field input:focus {
  background: #fff;
  border-color: #e0602e;
}
html[data-theme="dark"] #login-screen .icon-btn {
  color: #686d63;
}
html[data-theme="dark"] .field input,
html[data-theme="dark"] .field select,
html[data-theme="dark"] .termin-field input,
html[data-theme="dark"] .termin-field select,
html[data-theme="dark"] .search-box input,
html[data-theme="dark"] #filter-status,
html[data-theme="dark"] #filter-booth-type,
html[data-theme="dark"] #orders-filter-status,
html[data-theme="dark"] #orders-filter-onsite,
html[data-theme="dark"] #lunchbox-orders-filter-status,
html[data-theme="dark"] #operational-filter-status,
html[data-theme="dark"] #price-list-filter-category,
html[data-theme="dark"] #price-list-filter-active,
html[data-theme="dark"] #activity-user-filter,
html[data-theme="dark"] .event-selector select,
html[data-theme="dark"] .picker-toolbar select {
  color: var(--text);
}
html[data-theme="dark"] .field input:focus,
html[data-theme="dark"] .field select:focus {
  background: var(--surface);
}
html[data-theme="dark"] .topbar {
  background: rgba(22, 30, 51, 0.78);
}
html[data-theme="dark"] .table tbody tr:hover {
  background: var(--surface-hover);
}
html[data-theme="dark"] ::-webkit-scrollbar-thumb { background: #384467; }
html[data-theme="dark"] ::-webkit-scrollbar-thumb:hover { background: #4a5787; }
html[data-theme="dark"] .toast { background: var(--surface); color: var(--text); }
html[data-theme="dark"] .modal { background: var(--surface-solid); }
html[data-theme="dark"] .booth-cell { background: var(--surface); color: var(--text); }
html[data-theme="dark"] .booth-cell.booked { background: var(--surface-alt); }
html[data-theme="dark"] .legend-swatch.available { background: var(--surface); }
html[data-theme="dark"] .theme-pill { background: var(--brass-light); color: #e8c583; }
html[data-theme="dark"] .booking-code-badge { color: #e8c583; border-color: rgba(232,197,131,0.22); }

* { box-sizing: border-box; }
::selection { background: var(--brass-light); color: var(--brass-dark); }

html, body {
  margin: 0; padding: 0;
  font-family: 'Inter', 'Segoe UI', -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif;
  background-image: var(--bg-grad);
  background-size: 100% 100%;
  background-repeat: no-repeat;
  background-attachment: fixed;
  color: var(--text);
  font-size: 14px;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  width: 100%;
  max-width: 100vw;
}

/* ============================================================
   PREMIUM GLASS THEME
   --surface / --surface-alt are translucent, so every panel built on
   them gets a frosted backdrop-blur here -- letting the ambient color
   blobs behind the app read as real glass instead of a flat wash.
   Booth-status cells, buttons, and badges keep solid brand color for
   legibility/scanability; everything else is glass. ---- */
.card,
.stat-card,
.mini-stat,
.table-card,
.dropdown-menu,
.search-box,
.btn-secondary,
.status-pill,
.event-selector select,
.theme-pill,
.field input,
.field select,
#event-prices-table .ep-price-input,
#event-prices-table .ep-onsite-price-input,
#filter-booth-type,
#orders-filter-status,
#orders-filter-onsite,
#lunchbox-orders-filter-status,
#operational-filter-status,
#price-list-filter-category,
#price-list-filter-active,
#activity-user-filter,
.import-preview-table,
.table th,
.boothmap-viewport,
.boothmap-hallzone,
.boothmap-focused,
.boothmap-tooltip {
  backdrop-filter: blur(var(--glass-blur)) saturate(108%);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(108%);
}
.card,
.stat-card,
.mini-stat,
.table-card,
.modal,
.dropdown-menu,
.search-box,
.boothmap-viewport,
.boothmap-hallzone,
.boothmap-focused {
  box-shadow: var(--shadow-sm), var(--glass-edge);
}
.sidebar, .topbar {
  backdrop-filter: blur(24px) saturate(108%);
  -webkit-backdrop-filter: blur(24px) saturate(108%);
}

h1, h2, h3, .brand-title, .stat-value, .modal-header h3 { font-family: 'Sora', 'Inter', sans-serif; letter-spacing: -0.01em; }

/* Safety net: never let any stray wide child (e.g. an un-wrapped table)
   force the whole page/viewport to stretch on mobile. Real fix is to wrap
   wide tables in .table-scroll, but this guards against future regressions. */
.app-shell { max-width: 100vw; overflow-x: hidden; }
.content { max-width: min(1400px, 100vw); overflow-x: hidden; }

button, input, select { font-family: inherit; font-size: inherit; }
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #cfccba; border-radius: 20px; }
::-webkit-scrollbar-thumb:hover { background: #b8b49d; }

/* ============ LOGIN ============ */
/* A soft, light, "premium SaaS" mesh-gradient backdrop -- multiple large, gently
   overlapping radial tints over a near-white base, rather than a single flat gradient. */
.login-wrap {
  position: relative;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px 20px;
  background:
    radial-gradient(circle at 8% 8%, rgba(18,179,129,0.18), transparent 42%),
    radial-gradient(circle at 92% 12%, rgba(255,106,61,0.16), transparent 40%),
    radial-gradient(circle at 88% 92%, rgba(46,74,122,0.16), transparent 42%),
    radial-gradient(circle at 6% 90%, rgba(8,150,170,0.13), transparent 40%),
    linear-gradient(160deg, #fbfaf6 0%, #f4f2ea 45%, #efede1 100%);
  overflow: hidden;
}
.login-bg-shapes { position: absolute; inset: 0; overflow: hidden; z-index: 0; }
.shape { position: absolute; border-radius: 50%; opacity: 0.5; filter: blur(30px); animation: blobDrift 12s ease-in-out infinite; }
.shape-1 { width: 480px; height: 480px; background: radial-gradient(circle, #c3cee2, transparent 70%); top: -160px; left: -140px; }
.shape-2 { width: 440px; height: 440px; background: radial-gradient(circle, #f4c199, transparent 70%); bottom: -180px; right: -130px; animation-delay: -4s; }
.shape-3 { width: 320px; height: 320px; background: radial-gradient(circle, #a9d4d3, transparent 70%); top: 40%; right: 8%; animation-delay: -7s; }

/* Decorative dot-grid texture removed -- background is gradient-only now. */
.login-wrap::before {
  content: none;
}

.login-card {
  position: relative;
  z-index: 1;
  background: rgba(255,255,255,0.86);
  backdrop-filter: blur(22px) saturate(108%);
  -webkit-backdrop-filter: blur(22px) saturate(108%);
  border-radius: 26px;
  box-shadow:
    0 1px 0 rgba(255,255,255,0.9) inset,
    0 32px 80px -16px rgba(18,179,129,0.20),
    0 10px 30px rgba(23,28,44,0.07);
  padding: 48px 44px 40px;
  width: 100%;
  max-width: 440px;
  border: 1px solid rgba(255,255,255,0.8);
  overflow: hidden;
}
/* A thin gradient accent bar along the very top edge of the card -- a small but
   noticeably more "designed" touch than a plain flat-white card. */
.login-card::before {
  content: '';
  position: absolute; top: 0; left: 0; right: 0; height: 4px;
  background: var(--brass-grad);
}
.login-brand { text-align: center; margin-bottom: 30px; }
.brand-icon {
  font-size: 34px; line-height: 1; margin: 0 auto 18px; width: 68px; height: 68px;
  display: flex; align-items: center; justify-content: center; border-radius: 19px;
  background: var(--brass-grad); box-shadow: 0 12px 28px -6px rgba(255,106,61,0.5), 0 2px 6px rgba(255,106,61,0.22);
}
.brand-icon svg { width: 60%; height: 60%; display: block; }
.brand-icon.small { font-size: 24px; width: 60px; height: 60px; border-radius: 16px; margin: 0 auto 12px; box-shadow: 0 6px 18px rgba(255,106,61,0.34); }
.brand-icon.small svg { width: 62%; height: 62%; }
.login-brand h1 { margin: 4px 0 5px; font-size: 25px; font-weight: 800; color: var(--text); letter-spacing: -0.02em; font-family: 'Sora', 'Inter', sans-serif; }
.login-brand p {
  margin: 0; display: inline-block; color: var(--primary-dark); font-size: 12px; font-weight: 800;
  letter-spacing: 0.05em; text-transform: uppercase; background: var(--primary-light);
  padding: 4px 12px; border-radius: 999px;
}

.login-copyright {
  position: fixed;
  right: max(18px, env(safe-area-inset-right));
  bottom: max(14px, env(safe-area-inset-bottom));
  z-index: 2;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-faint);
  text-align: right;
  pointer-events: none;
}

.field { margin-bottom: 10px; display: flex; flex-direction: column; gap: 4px; }
.field label { font-size: 11.5px; font-weight: 700; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; text-align: center; width: 100%; }
.field input, .field select {
  border: 1.5px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 8px 12px;
  background: var(--surface-alt);
  color: var(--text);
  outline: none;
  transition: border-color .15s, box-shadow .15s, background .15s;
  width: 100%;
  text-align: center;
}
.field input:focus, .field select:focus {
  border-color: var(--primary);
  background: #fff;
  box-shadow: 0 0 0 4px var(--primary-light);
}

/* Per-Event Prices modal (Master Price List / Lunchbox "Prices per Event" popup): the
   Price/Onsite Price fields live directly in table cells rather than inside a .field
   wrapper, so they need their own copy of the same input styling used everywhere else
   in the app -- without this they render as bare, unstyled default browser inputs. */
#event-prices-table .ep-price-input, #event-prices-table .ep-onsite-price-input {
  border: 1.5px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 8px 12px;
  background: var(--surface-alt);
  color: var(--text);
  outline: none;
  transition: border-color .15s, box-shadow .15s, background .15s;
}
#event-prices-table .ep-price-input:focus, #event-prices-table .ep-onsite-price-input:focus {
  border-color: var(--primary);
  background: #fff;
  box-shadow: 0 0 0 4px var(--primary-light);
}
.password-wrap { position: relative; display: flex; align-items: center; width: 100%; }
.password-wrap input { padding-right: 42px; }
.password-wrap .icon-btn { position: absolute; right: 4px; }

/* Login form gets slightly larger fields/labels/button to match the bigger login card.
   Label text and input text are centered (matching the app-wide centered theme), but the
   field/input container itself keeps its original full width -- only the text inside is centered. */
.login-card .field { margin-bottom: 19px; }
.login-card .field label { font-size: 11.5px; font-weight: 800; color: var(--text-muted); text-align: center; width: 100%; }
.login-card .field input {
  padding: 13px 16px; font-size: 15px; border-radius: 13px; border-width: 1.5px;
  transition: border-color .15s, box-shadow .15s, background .15s, transform .1s;
  text-align: center;
}
.login-card .field input:focus { box-shadow: 0 0 0 4px rgba(255,106,61,0.14); transform: translateY(-1px); }
.login-card .btn-block {
  padding: 14px 18px; font-size: 15px; border-radius: 13px; font-weight: 800;
  letter-spacing: 0.01em; margin-top: 6px;
  box-shadow: 0 10px 26px -6px rgba(255,106,61,0.55);
}
.login-card .btn-block:hover { box-shadow: 0 14px 32px -6px rgba(255,106,61,0.6); }
.login-card .password-wrap .icon-btn { font-size: 18px; }

/* ============ LOGIN SCREEN ANIMATIONS ============
   A small animejs.com-style choreography: the card springs in, the brand
   mark pops with overshoot, then copy and fields reveal in a staggered
   sequence. Pure CSS (no runtime dependency) so it stays reliable on the
   cPanel deploy -- toggling #login-screen between display:none/flex (see
   doLogout/bootstrap in app.js) naturally replays the sequence each time
   the screen reappears, since animations don't run while display:none. */
.login-card {
  animation: loginCardIn .75s cubic-bezier(.16,1,.3,1) both;
}
.login-brand .brand-icon {
  animation:
    iconPopIn .7s cubic-bezier(.34,1.56,.64,1) .15s both,
    iconGlowPulse 2.6s ease-in-out 1s infinite;
}
.login-brand h1 { animation: fadeSlideUp .6s cubic-bezier(.16,1,.3,1) .3s both; }
.login-brand p { animation: fadeSlideUp .6s cubic-bezier(.16,1,.3,1) .38s both; }
.login-card form > .field:nth-child(1) { animation: fadeSlideUp .6s cubic-bezier(.16,1,.3,1) .46s both; }
.login-card form > .field:nth-child(2) { animation: fadeSlideUp .6s cubic-bezier(.16,1,.3,1) .54s both; }
.login-card .btn-block { animation: fadeSlideUp .6s cubic-bezier(.16,1,.3,1) .64s both; }
.login-copyright { animation: fadeSlideUp .6s cubic-bezier(.16,1,.3,1) .78s both; }

/* Shimmering gradient bar along the card's top edge, panning slowly left-to-right. */
.login-card::before {
  background-size: 220% 100%;
  animation: gradientPan 5s linear infinite;
}

/* Floating backdrop blobs use blobDrift (declared on .shape above) which combines
   a vertical bob with a touch of scale/rotation so the drift feels more organic
   than a straight up-down bounce. */
@keyframes blobDrift {
  0%, 100% { transform: translateY(0) scale(1) rotate(0deg); }
  50% { transform: translateY(-24px) scale(1.06) rotate(6deg); }
}

/* A light sweep across the submit button on hover -- cheap, GPU-friendly, no JS. */
.login-card .btn-block { position: relative; overflow: hidden; }
.login-card .btn-block::after {
  content: '';
  position: absolute; top: 0; left: -60%; width: 45%; height: 100%;
  background: linear-gradient(120deg, transparent, rgba(255,255,255,0.55), transparent);
  transform: skewX(-20deg);
  transition: left .6s ease;
  pointer-events: none;
}
.login-card .btn-block:hover::after { left: 130%; }

/* Nudges the error banner into view with a quick shake -- re-triggers each time
   app.js flips it from display:none to display:block on a failed login. */
.login-card .alert-error {
  animation: shakeX .45s cubic-bezier(.36,.07,.19,.97);
}

@keyframes loginCardIn {
  from { opacity: 0; transform: translateY(28px) scale(.94); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes iconPopIn {
  from { opacity: 0; transform: scale(.4) rotate(-18deg); }
  to   { opacity: 1; transform: scale(1) rotate(0deg); }
}
@keyframes iconGlowPulse {
  0%, 100% { box-shadow: 0 12px 28px -6px rgba(255,106,61,0.5), 0 2px 6px rgba(255,106,61,0.22); }
  50%      { box-shadow: 0 14px 36px -4px rgba(255,106,61,0.72), 0 2px 10px rgba(255,106,61,0.34); }
}
@keyframes fadeSlideUp {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes gradientPan {
  0%   { background-position: 0% 0; }
  100% { background-position: 220% 0; }
}
@keyframes shakeX {
  10%, 90% { transform: translateX(-1px); }
  20%, 80% { transform: translateX(2px); }
  30%, 50%, 70% { transform: translateX(-4px); }
  40%, 60% { transform: translateX(4px); }
}

@media (prefers-reduced-motion: reduce) {
  .login-card,
  .login-brand .brand-icon,
  .login-brand h1,
  .login-brand p,
  .login-card form > .field,
  .login-card .btn-block,
  .login-copyright,
  .shape,
  .login-card::before,
  .login-card .alert-error {
    animation: none !important;
  }
}

.btn {
  border: none;
  border-radius: var(--radius-sm);
  padding: 11px 18px;
  font-weight: 700;
  font-size: 13.5px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  transition: transform .08s ease, box-shadow .2s, background .2s, opacity .15s, filter .15s;
  white-space: nowrap;
}
.btn:active { transform: translateY(1px) scale(0.99); }
.btn-primary { background: var(--brass-grad); color: #211705; box-shadow: var(--shadow-glow); }
.btn-primary:hover { filter: brightness(1.05); box-shadow: 0 10px 30px rgba(255,106,61,0.42); }
.btn-secondary { background: var(--surface); color: var(--text); border: 1.5px solid var(--border-strong); box-shadow: var(--shadow-xs); }
.btn-secondary:hover { background: var(--surface-hover); border-color: var(--primary); color: var(--primary-dark); }
.btn-ghost { background: transparent; color: var(--text-muted); border: 1.5px solid var(--border); }
.btn-ghost:hover { background: var(--surface-alt); color: var(--text); }
.btn-danger { background: var(--red-light); color: var(--red); border: 1.5px solid #fecaca; }
.btn-danger:hover { background: #fecaca; }
.btn-success { background: var(--green-grad); color: #fff; box-shadow: 0 8px 22px rgba(5,150,105,0.28); }
.btn-success:hover { filter: brightness(1.06); }
.btn-block { width: 100%; }
.btn:disabled { opacity: 0.55; cursor: not-allowed; filter: none; box-shadow: none; }
.btn-sm { padding: 6px 11px; font-size: 12px; border-radius: 8px; }

.icon-btn {
  background: transparent; border: none; cursor: pointer; font-size: 16px;
  color: var(--text-muted); padding: 7px 9px; border-radius: 8px; transition: background .15s, color .15s;
}
.icon-btn:hover { background: var(--surface-alt); color: var(--text); }
#refresh-view-btn { font-size: 18px; line-height: 1; }
#refresh-view-btn.spinning { animation: spin .7s linear infinite; }

.spinner {
  width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid rgba(255,255,255,0.4); border-top-color: #fff;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.alert { padding: 11px 14px; border-radius: var(--radius-sm); font-size: 13px; margin-bottom: 14px; font-weight: 500; text-align: center; }
.alert-error { background: var(--red-light); color: var(--red); border: 1px solid #fecaca; }
.alert-success { background: var(--green-light); color: var(--green); border: 1px solid #bbf7d0; }

.login-hint { margin-top: 26px; padding-top: 20px; border-top: 1px solid var(--border-strong); font-size: 12.5px; color: var(--text-muted); }
.login-hint strong { display: block; margin-bottom: 9px; color: var(--text); font-size: 12.5px; }
.hint-row { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; }
.tag { font-size: 10.5px; font-weight: 800; padding: 3px 9px; border-radius: 20px; text-transform: uppercase; letter-spacing: 0.02em; }
.tag-admin { background: var(--primary-light); color: var(--primary-dark); }
.tag-staff { background: var(--green-light); color: var(--green); }
.tag-finance { background: var(--amber-light); color: var(--amber); }
.tag-viewer { background: var(--purple-light); color: var(--purple); }

/* ============ APP SHELL ============ */
.app-shell { display: flex; min-height: 100vh; }

/* The sidebar is the app's one fixed identity element -- a navy panel with a
   faint blueprint dot-grid (echoing a floor-plan / booth layout) that stays
   constant across the light/dark theme toggle, same as the login screen's
   deliberately-always-light treatment above. */
.sidebar {
  width: var(--sidebar-w);
  background: var(--sidebar-bg);
  border-right: 1px solid rgba(255, 255, 255, 0.22);
  box-shadow: 0 0 0 rgba(10, 60, 10, 0),
    inset -1px 0 0 rgba(255,255,255,0.14),
    inset 0 1px 0 rgba(255,255,255,0.40);
  display: flex;
  flex-direction: column;
  padding: 26px 18px;
  position: sticky;
  top: 0;
  height: 100vh;
  transition: margin-left .2s ease;
  flex-shrink: 0;
  z-index: 20;
}
.sidebar::before {
  content: none;
}
.sidebar > * { position: relative; z-index: 1; }
.sidebar.collapsed { margin-left: calc(-1 * var(--sidebar-w)); }

/* Vertically centered against the topbar's own height/padding so the logo block and
   the page title sit on the same visual baseline instead of the logo looking
   cramped/high relative to it (a real spacing mismatch flagged via screenshot --
   the topbar uses 16px vertical padding around ~19px/24px-line-height text, so the
   brand row now targets a comparable overall height via its own padding). */
.sidebar-brand {
  display: flex; flex-direction: column; align-items: center; text-align: center; gap: 2px;
  padding: 6px 8px 24px; margin-bottom: 20px; position: relative;
  border-bottom: 1px solid transparent;
  border-image: linear-gradient(90deg, transparent, rgba(255,215,60,0.45), transparent) 1;
}
.sidebar-brand::before {
  content: ''; position: absolute; top: -20px; left: 50%; transform: translateX(-50%);
  width: 160px; height: 160px; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, rgba(255,215,60,0.18) 0%, transparent 68%);
}
.brand-text { line-height: 1.3; }
.brand-title { font-weight: 800; font-size: 15.5px; letter-spacing: -0.01em; color: var(--sidebar-text); }
.brand-sub { font-size: 11.5px; color: var(--sidebar-text-muted); font-weight: 600; margin-top: 1px; }

.nav-menu { display: flex; flex-direction: column; gap: 4px; flex: 1; }
.nav-item {
  display: flex; align-items: center; gap: 11px;
  padding: 11px 13px; border-radius: 12px;
  border: none; background: transparent; text-align: left;
  color: var(--sidebar-text-muted); cursor: pointer; font-weight: 600; font-size: 13.5px;
  transition: background .15s, color .15s, transform .1s;
  position: relative;
}
.nav-item:not(.active):hover { background: transparent; color: var(--sidebar-text); }
.nav-item.active {
  background: linear-gradient(90deg, rgba(255,210,60,0.18), rgba(255,210,60,0.06));
  color: var(--sidebar-active-text);
  box-shadow: 0 4px 18px rgba(0,0,0,0.22), inset 0 1px 0 rgba(255,230,100,0.20);
  border: 1px solid rgba(255,210,60,0.22);
}
.nav-item.active::before {
  content: ''; position: absolute; left: -16px; top: 50%; transform: translateY(-50%);
  width: 4px; height: 22px; border-radius: 0 6px 6px 0; background: linear-gradient(180deg, #ffe566, #f5a800);
  box-shadow: 0 0 10px rgba(255,200,40,0.80);
}
.nav-icon { font-size: 16px; width: 18px; text-align: center; }
.nav-badge { margin-left: auto; font-size: 10.5px; font-weight: 800; background: var(--brass); color: #211705; padding: 1px 7px; border-radius: 20px; }

.nav-group { display: flex; flex-direction: column; }
.nav-group-header { width: 100%; }
.nav-group-arrow { margin-left: auto; font-size: 11px; transition: transform .15s, color .15s; color: var(--sidebar-text-muted); }
.nav-group.expanded .nav-group-arrow { transform: rotate(90deg); color: #ffe566; }
.nav-group.has-active .nav-group-header { color: #ffe566; }
.nav-submenu { display: none; flex-direction: column; gap: 2px; padding: 4px 0 4px 14px; }
.nav-group.expanded .nav-submenu { display: flex; }
.nav-subitem { padding-left: 26px; font-size: 13px; }
.nav-subitem .nav-icon { font-size: 14.5px; }

.sidebar-footer {
  border-top: 1px solid transparent; border-image: linear-gradient(90deg, transparent, rgba(255,215,60,0.40), transparent) 1;
  padding-top: 16px; display: flex; flex-direction: column; gap: 10px;
}
.user-card { display: flex; align-items: center; gap: 11px; padding: 8px; border-radius: 12px; background: rgba(0,0,0,0.15); border: 1px solid rgba(255,215,60,0.22); backdrop-filter: blur(10px); }
.avatar {
  width: 38px; height: 38px; border-radius: 12px;
  background: var(--brass-grad); color: #211705; display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 14px; flex-shrink: 0; box-shadow: 0 4px 10px rgba(0,0,0,0.35);
}
.user-info { line-height: 1.3; overflow: hidden; }
.user-name { font-weight: 700; font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: var(--sidebar-text); }
.user-role { font-size: 11px; color: var(--sidebar-text-muted); text-transform: capitalize; font-weight: 600; }

/* Logout uses .btn-ghost by default, which is styled for the light main-content
   area (dark-muted text on a faint border) -- against the sidebar's teal/cyan
   panel that combination was nearly invisible. Give it its own high-contrast
   treatment: bright white text/icon on a clearly visible frosted chip, with a
   warm red tint on hover so its "exit" intent reads clearly too. */
.sidebar-footer #logout-btn {
  background: rgba(255, 255, 255, 0.14);
  color: #ffffff;
  border: 1.5px solid rgba(255, 255, 255, 0.32);
  font-weight: 800;
  letter-spacing: 0.01em;
  transition: background .15s, border-color .15s, color .15s, transform .08s;
}
.sidebar-footer #logout-btn:hover {
  background: rgba(255, 92, 92, 0.28);
  border-color: rgba(255, 140, 140, 0.55);
  color: #fff;
}
.sidebar-footer #logout-btn:active { transform: translateY(1px) scale(0.99); }

.main-area { flex: 1; display: flex; flex-direction: column; min-width: 0; }

.topbar {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 16px 20px; background: var(--surface); backdrop-filter: blur(24px) saturate(108%); -webkit-backdrop-filter: blur(24px) saturate(108%);
  border-bottom: 1px solid var(--border); z-index: 10;
  box-shadow: var(--glass-edge);
  padding-left: max(20px, env(safe-area-inset-left));
  padding-right: max(20px, env(safe-area-inset-right));
  /* Fixed (not sticky) so it reliably floats above the scrolling content on every
     browser/device -- position:sticky was inconsistent on some mobile browsers.
     --topbar-left/--topbar-width are kept in sync with the sidebar's real width
     (collapsed/expanded, desktop/mobile) by syncTopbarPosition() in app.js. */
  position: fixed; top: 0;
  left: var(--topbar-left, 264px);
  width: var(--topbar-width, calc(100% - 264px));
}
.topbar-title { font-weight: 800; font-size: 19px; letter-spacing: -0.02em; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex-shrink: 0; }
.topbar-actions { margin-left: auto; display: flex; align-items: center; gap: 14px; flex-wrap: wrap; min-width: 0; }

/* ---- Toolbar-in-topbar: on wide screens, each view's toolbar (search/filters/
   add button/etc.) is moved here by placeViewToolbar() so it sits beside the
   Event selector instead of taking up its own row above the table. ---- */
.topbar-toolbar-slot { flex: 1 1 340px; display: flex; align-items: center; min-width: 0; }
.topbar-toolbar-slot:empty { flex-basis: 0; }
.topbar-toolbar-slot .toolbar { margin-bottom: 0; gap: 8px; flex-wrap: wrap; width: 100%; }
.topbar-toolbar-slot .search-box { min-width: 160px; padding: 6px 11px; flex: 1 1 160px; }
.topbar-toolbar-slot select,
.topbar-toolbar-slot .btn { padding: 6px 11px; font-size: 12.5px; }
.topbar-toolbar-slot .dropdown-btn { padding: 6px 11px; font-size: 12.5px; }
.event-selector { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--text-muted); font-weight: 700; min-width: 0; }
.event-selector select {
  padding: 8px 12px; border-radius: 10px; border: 1.5px solid var(--border); background: var(--surface-alt); color: var(--text); font-weight: 600;
  min-width: 0; max-width: 42vw; overflow: hidden; text-overflow: ellipsis;
}
.theme-pill { background: var(--amber-light); color: var(--amber); padding: 7px 14px; border-radius: 20px; font-size: 12px; font-weight: 800; display:flex; align-items:center; gap:6px; flex-shrink: 0; }

/* ---- Small reusable dropdown menu (used to combine Import/Export-style action
   groups into a single button so toolbars take up less horizontal space) ---- */
.dropdown { position: relative; display: inline-flex; flex-shrink: 0; }
.dropdown-menu {
  position: absolute; top: calc(100% + 6px); right: 0; min-width: 190px;
  background: var(--surface); border: 1.5px solid var(--border); border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md), var(--glass-edge); padding: 6px; z-index: 40; display: none; flex-direction: column; gap: 2px;
}
.dropdown.open .dropdown-menu { display: flex; }
.dropdown-menu button {
  text-align: left; background: none; border: none; padding: 9px 11px; border-radius: 8px;
  font-size: 13px; font-weight: 600; color: var(--text); cursor: pointer; white-space: nowrap;
}
.dropdown-menu button:hover { background: var(--surface-alt); }

/* Reserve the space the now-fixed topbar no longer occupies in normal flow. */
.content { padding: calc(var(--topbar-h, 68px) + 24px) 20px 48px; max-width: 2200px; margin: 0 auto; width: 100%; }
.view { animation: fadeIn .25s ease; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }

/* ============ DASHBOARD ============ */
.stats-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; margin-bottom: 18px; }
.stats-grid-secondary { grid-template-columns: repeat(4, 1fr); }
.stat-card {
  background: var(--surface); border-radius: var(--radius); padding: 20px;
  display: flex; align-items: center; gap: 15px; box-shadow: var(--shadow-sm), var(--glass-edge); border: 1px solid var(--border);
  transition: transform .18s ease, box-shadow .18s ease;
  position: relative; overflow: hidden;
}
.stat-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
.stat-card::after { content:''; position:absolute; right:-30px; top:-30px; width:90px; height:90px; border-radius:50%; opacity:.08; }
.stat-icon { font-size: 24px; width: 52px; height: 52px; border-radius: 14px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; color: #fff; }
.stat-blue .stat-icon { background: var(--primary-grad); box-shadow: 0 6px 16px rgba(18,179,129,.32); }
.stat-blue::after { background: var(--primary); }
.stat-green .stat-icon { background: var(--green-grad); box-shadow: 0 6px 16px rgba(5,150,105,.28); }
.stat-green::after { background: var(--green); }
.stat-amber .stat-icon { background: var(--amber-grad); box-shadow: 0 6px 16px rgba(217,119,6,.28); }
.stat-amber::after { background: var(--amber); }
.stat-red .stat-icon { background: var(--red-grad); box-shadow: 0 6px 16px rgba(220,38,38,.28); }
.stat-red::after { background: var(--red); }
.stat-value { font-size: 26px; font-weight: 800; line-height: 1.1; letter-spacing: -0.01em; }
.stat-label { font-size: 12.5px; color: var(--text-muted); font-weight: 600; margin-top: 3px; }

.mini-stat {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 14px 18px; display: flex; align-items: center; justify-content: center; gap: 14px; box-shadow: var(--shadow-xs), var(--glass-edge);
}
button.mini-stat { width: 100%; text-align: center; color: inherit; }
.mini-stat-clickable { cursor: pointer; transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease; }
.mini-stat-clickable:hover { transform: translateY(-2px); box-shadow: var(--shadow-sm); border-color: var(--primary); }
.mini-stat-clickable.mini-stat-active { border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-light), var(--shadow-sm); }
.mini-stat-green.mini-stat-clickable.mini-stat-active { border-color: var(--green); box-shadow: 0 0 0 3px var(--green-light), var(--shadow-sm); }
.mini-stat-amber.mini-stat-clickable.mini-stat-active { border-color: var(--amber); box-shadow: 0 0 0 3px var(--amber-light), var(--shadow-sm); }
.mini-stat-red.mini-stat-clickable.mini-stat-active { border-color: var(--red); box-shadow: 0 0 0 3px var(--red-light), var(--shadow-sm); }
.mini-label { font-size: 12px; color: var(--text-muted); font-weight: 700; }
.mini-value { font-size: 19px; font-weight: 800; color: var(--primary-dark); }
.mini-stat-green .mini-value { color: var(--green); }
.mini-stat-blue .mini-value { color: var(--primary); }
.mini-stat-amber .mini-value { color: var(--amber); }
.mini-stat-red .mini-value { color: var(--red); }

/* ---- SQM Report ---- */
.sqm-report { display: flex; flex-direction: column; gap: 14px; }
.sqm-total { text-align: center; padding: 6px 0 10px; border-bottom: 1px solid var(--border); margin-bottom: 4px; }
.sqm-total-value { font-size: 28px; font-weight: 800; color: var(--text); letter-spacing: -0.02em; }
.sqm-total-label { font-size: 12px; color: var(--text-muted); font-weight: 700; margin-top: 2px; }
.sqm-bar-track { display: flex; height: 22px; border-radius: 12px; overflow: hidden; background: var(--surface-alt); }
.sqm-bar-seg { height: 100%; transition: width .5s cubic-bezier(.2,.8,.2,1); }
.sqm-bar-seg.confirmed { background: var(--green-grad); }
.sqm-bar-seg.booked { background: var(--primary-grad); }
.sqm-bar-seg.blocked { background: var(--red-grad); }
.sqm-bar-seg.available { background: var(--surface-alt); }
.sqm-legend { display: flex; flex-wrap: wrap; gap: 10px 18px; font-size: 12.5px; font-weight: 700; }
.sqm-legend-item { display: flex; align-items: center; gap: 7px; color: var(--text-muted); }
.sqm-legend-dot { width: 10px; height: 10px; border-radius: 3px; flex-shrink: 0; }
.sqm-legend-dot.confirmed { background: var(--green); }
.sqm-legend-dot.booked { background: var(--primary); }
.sqm-legend-dot.blocked { background: var(--red); }
.sqm-legend-dot.available { background: var(--border-strong); }
.sqm-legend-item strong { color: var(--text); font-weight: 800; }

.dashboard-grid { display: grid; grid-template-columns: 1.3fr 1fr; gap: 18px; margin: 18px 0; }

.card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow-sm), var(--glass-edge); margin-bottom: 18px;
}
.card-header { padding: 16px 18px; border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; }
.card-header h3 { margin: 0; font-size: 15px; font-weight: 800; letter-spacing: -0.01em; text-align: center; }
.card-body { padding: 18px 18px; }

/* Collapsible section titles (Dashboard's Payment Overview, Event Overview's
   per-event cards) get their label truly centered in the header row -- same
   treatment as the Sales Analytics accordion -- while the toggle icon stays
   pinned to the right. Plain, non-collapsible .card-header titles elsewhere
   are untouched (no flex-grow), so this only affects these two toggle rows. */
#dashboard-payment-header h3,
.overview-event-header h3 { flex: 1; }

/* ---- Event Overview (spreadsheet-style collapsible per-event booth grid) ---- */
.overview-event-header:hover { background: var(--surface-hover); }
.overview-event-header h3 { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 4px; }
.overview-toggle-icon { font-size: 16px; font-weight: 800; color: var(--text-faint); flex-shrink: 0; }
.overview-event-body { padding: 16px 20px 4px; }
.overview-plotted-badge {
  font-size: 11px; font-weight: 800; color: var(--primary-dark); background: var(--primary-light);
  padding: 3px 10px; border-radius: 20px; margin-left: 6px; white-space: nowrap;
}

.bar-chart { display: flex; flex-direction: column; gap: 12px; }
.bar-row { display: grid; grid-template-columns: 100px 1fr 34px; align-items: center; gap: 12px; font-size: 12.5px; }
.bar-track { background: var(--surface-alt); border-radius: 20px; overflow: hidden; height: 11px; }
.bar-fill { height: 100%; background: var(--primary-grad); border-radius: 20px; transition: width .5s cubic-bezier(.2,.8,.2,1); }
.bar-label { color: var(--text-muted); font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar-count { text-align: right; font-weight: 800; color: var(--text); }

.donut-wrap { display: flex; align-items: center; gap: 24px; flex-wrap: wrap; justify-content: center; }
.donut { width: 160px; height: 160px; border-radius: 50%; position: relative; flex-shrink: 0; }
.donut-center { position: absolute; inset: 22px; background: var(--surface); border-radius: 50%; display: flex; flex-direction: column; align-items: center; justify-content: center; box-shadow: inset 0 0 0 1px var(--border); }
.donut-center .dv { font-size: 22px; font-weight: 800; }
.donut-center .dl { font-size: 10.5px; color: var(--text-muted); font-weight: 700; text-transform: uppercase; }
.donut-legend { display: flex; flex-direction: column; gap: 10px; }
.legend-item { display: flex; align-items: center; gap: 9px; font-size: 12.5px; font-weight: 600; color: var(--text-muted); }
.legend-dot { width: 11px; height: 11px; border-radius: 4px; flex-shrink: 0; }
.legend-item b { color: var(--text); margin-left: auto; padding-left: 14px; }

/* ============ TABLE ============ */
.toolbar { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; flex-wrap: wrap; }
.toolbar-spacer { flex: 1; }
.search-box { display: flex; align-items: center; gap: 9px; background: var(--surface); border: 1.5px solid var(--border); border-radius: var(--radius-sm); padding: 9px 14px; min-width: 280px; box-shadow: var(--shadow-xs), var(--glass-edge); }
.search-box input { border: none; outline: none; background: transparent; flex: 1; color: var(--text); min-width: 0; text-overflow: ellipsis; }
#filter-status,
#filter-booth-type,
#orders-filter-status,
#orders-filter-onsite,
#lunchbox-orders-filter-status,
#operational-filter-status,
#price-list-filter-category,
#price-list-filter-active,
#activity-user-filter { padding: 10px 13px; border-radius: var(--radius-sm); border: 1.5px solid var(--border); background: var(--surface); color: var(--text); font-weight: 600; box-shadow: var(--shadow-xs); }

.table-card { padding: 0; overflow: hidden; }
.table-scroll { overflow-x: auto; }
.table { width: 100%; border-collapse: collapse; min-width: 900px; }
/* Activity Log's Details column now carries much longer, specific messages
   (e.g. full "Field: old -> new" diffs) -- let it wrap onto multiple lines
   and take up the remaining width, instead of forcing endless horizontal
   scroll / being clipped like a single-line cell. */
#activity-table { min-width: 640px; table-layout: fixed; }
/* This order-lines breakdown table is small (5 simple columns) and always lives inside
   an 800px-wide modal -- the generic .table's 900px min-width would force horizontal
   overflow/clipping here, so give it a much narrower min-width that actually fits. */
#order-detail-lines-table { min-width: 0; width: 100%; }
/* Manage Halls / Lunchbox order detail / Per-Event Prices tables: a handful of
   simple, short columns that always live inside a fixed-width modal -- the generic
   .table's 900px min-width forced horizontal overflow, hiding content (including the
   Save button) off-screen until the user scrolled sideways (confirmed real bug via
   screenshot -- the Save button needed scrolling to reach, easy to miss and look like
   "saving doesn't work" even though the underlying save itself succeeds fine). All
   three fit comfortably at the modal's own width instead. */
#manage-halls-table, #lunchbox-order-detail-lines-table, #event-prices-table { min-width: 0; width: 100%; }
#activity-table th:nth-child(1), #activity-table td.activity-time { width: 150px; }
#activity-table th:nth-child(2), #activity-table td.activity-user { width: 120px; }
#activity-table th:nth-child(3), #activity-table td.activity-action { width: 160px; }
#activity-table td.activity-details, #activity-table td:nth-child(4) { white-space: normal; word-break: break-word; line-height: 1.5; }
.table th {
  text-align: center; font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; font-weight: 800;
  color: var(--text-muted); background: var(--surface-alt); padding: 9px 13px; border-bottom: 1px solid var(--border);
  white-space: nowrap; position: sticky; top: 0;
}
.table td { padding: 8px 13px; border-bottom: 1px solid var(--border); font-size: 13px; vertical-align: middle; text-align: center; }
.table tbody tr { transition: background .12s; }
.table tbody tr:hover { background: #fafbff; }
.table tbody tr:last-child td { border-bottom: none; }

/* Per-Hall Report totals row — overridden by the elegant table block below */
#dashboard-hall-report-table tbody tr.hall-report-total-row td {
  font-weight: 800; border-top: 1.5px solid var(--border-strong);
}

/* Spreadsheet-style clickable/sortable column headers -- currently used only on the
   Booth Bookings table (Halls & Booths intentionally has no sort control). */
.table th.th-sortable { cursor: pointer; user-select: none; transition: color .12s, background .12s; }
.table th.th-sortable:hover { color: var(--primary-dark); background: var(--surface-hover); }
.table th.th-sortable.th-sort-active { color: var(--primary-dark); }
.th-sort-icon { display: inline-block; margin-left: 3px; font-size: 9px; color: var(--primary); }

/* Compact variant: much shorter row height, used for tables with a very large number of
   rows (e.g. Halls & Booths, which can have 200+ booth slots) so far more fit on screen
   at once without shrinking legibility too much. Paired with .table-scroll-tall below,
   which makes the container internally scrollable with a fixed viewport height instead
   of pushing the whole page down. */
.table-compact th { padding: 7px 12px; font-size: 10px; }
.table-compact td { padding: 5px 12px; font-size: 12px; line-height: 1.3; }
.table-compact .btn-sm { padding: 3px 9px; font-size: 11px; }
.table-compact .status-badge { padding: 2px 9px; font-size: 9.5px; }
.table-scroll-tall { max-height: 65vh; overflow-y: auto; }

/* Permanent, human-readable booking identifier (e.g. "HEB27-00001") shown on the
   Booth Bookings list and detail view -- a monospace "code" look makes it visually
   distinct from ordinary text and easy to scan/copy, matching how it appears as a
   plain text value in the Excel export (so the two representations feel consistent). */
.booking-code-badge {
  display: inline-block; font-family: 'JetBrains Mono', 'SF Mono', 'Consolas', 'Monaco', monospace; font-size: 11px; font-weight: 700;
  background: var(--brass-light); color: var(--brass-dark); padding: 3px 9px; border-radius: 7px; border: 1px solid rgba(255,106,61,0.25);
  letter-spacing: 0.02em; white-space: nowrap;
}

.status-badge { padding: 4px 11px; border-radius: 20px; font-size: 10.5px; font-weight: 800; text-transform: capitalize; display: inline-flex; align-items:center; gap:5px; }
.status-badge::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.status-confirmed { background: var(--green-light); color: var(--green); }
.status-pending { background: var(--amber-light); color: var(--amber); }
.status-cancelled { background: var(--red-light); color: var(--red); }
.status-booked { background: var(--primary-light); color: var(--primary-dark); }
.status-available { background: var(--accent-light); color: var(--accent); }

.payment-progress { display: flex; align-items: center; justify-content: center; gap: 8px; min-width: 110px; }
.payment-progress-track { flex: 1; height: 8px; border-radius: 20px; background: var(--surface-alt); overflow: hidden; }
.payment-progress-fill { height: 100%; border-radius: 20px; background: var(--green-grad); transition: width .4s ease; }
.payment-progress-label { font-size: 11px; font-weight: 800; color: var(--text-muted); white-space: nowrap; }
.payment-progress-label.complete { color: var(--green); }
.no-spk-label { font-size: 11px; color: var(--text-faint); font-style: italic; }
.termin-checkmarks { display: flex; flex-wrap: wrap; justify-content: center; gap: 5px; font-size: 11px; font-weight: 700; color: var(--text-muted); min-width: 140px; }

.payment-spk-info {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px;
  background: var(--surface-alt); border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 14px 16px; margin-bottom: 16px;
}
.payment-spk-info .spk-item { display: flex; flex-direction: column; gap: 2px; }
.payment-spk-info .spk-label { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; color: var(--text-faint); }
.payment-spk-info .spk-value { font-size: 13.5px; font-weight: 700; color: var(--text); }

/* Booth "View" detail modal -- same neutral card/label-value grid pattern as the
   Payment modal's SPK info panel, so it doesn't look like a different UI/theme. */
.view-detail-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px 18px;
}
.view-detail-grid .vd-section {
  grid-column: 1 / -1; font-size: 11.5px; font-weight: 800; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--primary-dark); border-bottom: 1px solid var(--border-strong);
  padding-bottom: 5px; margin-top: 6px;
}
.view-detail-grid .vd-section:first-child { margin-top: 0; }
.view-detail-grid .vd-item { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.view-detail-grid .vd-item.vd-wide { grid-column: span 3; }
.view-detail-grid .vd-label { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; color: var(--text-faint); }
.view-detail-grid .vd-value { font-size: 13.5px; font-weight: 700; color: var(--text); word-break: break-word; }
.view-detail-grid .vd-value.vd-muted { color: var(--text-faint); font-weight: 600; font-style: italic; }
@media (max-width: 720px) {
  .view-detail-grid { grid-template-columns: 1fr 1fr; }
  .view-detail-grid .vd-item.vd-wide { grid-column: span 2; }
}

/* Uses the same neutral card look as the rest of the app (white surface + a thin
   colored accent bar, matching the .nav-item.active pattern) instead of a flooded
   color background, so this doesn't look like a "different theme" from other views. */
.payment-summary-bar {
  display: flex; align-items: center; gap: 18px; background: var(--surface-alt); border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 12px 16px; margin-bottom: 18px; flex-wrap: wrap;
}
.payment-summary-bar .psum-item { display: flex; flex-direction: column; gap: 2px; text-align: center; align-items: center; }
.payment-summary-bar .psum-label { font-size: 10.5px; font-weight: 700; text-transform: uppercase; color: var(--text-faint); }
.payment-summary-bar .psum-value { font-size: 15px; font-weight: 800; color: var(--text); }
.payment-summary-bar .psum-mismatch .psum-label { color: var(--red); }
.payment-summary-bar .psum-mismatch-value { color: var(--red); }

.termin-card {
  display: flex; align-items: center; gap: 14px; padding: 14px 16px 14px 20px; border: 1.5px solid var(--border);
  border-radius: var(--radius-sm); margin-bottom: 10px; transition: border-color .15s, background .15s;
  background: var(--surface); position: relative; overflow: hidden;
}
.termin-card::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: transparent; }
.termin-card.paid::before { background: var(--green-grad); }
.termin-card.overdue::before { background: var(--red-grad); }
.termin-badge {
  width: 40px; height: 40px; border-radius: 12px; display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 13px; flex-shrink: 0; background: var(--surface-alt); color: var(--text-muted);
}
.termin-card.paid .termin-badge { background: var(--green-grad); color: #fff; }
.termin-card.overdue .termin-badge { background: var(--red-grad); color: #fff; }
.termin-body { flex: 1; display: grid; grid-template-columns: 1fr 1fr 1fr auto; gap: 10px; align-items: center; }
.termin-field { display: flex; flex-direction: column; gap: 3px; }
.termin-field label { font-size: 10px; font-weight: 700; text-transform: uppercase; color: var(--text-faint); }
.termin-field input, .termin-field select { padding: 7px 9px; border-radius: 8px; border: 1.5px solid var(--border); font-size: 12.5px; background: var(--surface); }
.termin-check { display: flex; align-items: center; gap: 8px; }
.termin-check input[type="checkbox"] { width: 18px; height: 18px; accent-color: var(--green); cursor: pointer; }
.termin-check label { font-size: 12px; font-weight: 700; color: var(--text-muted); cursor: pointer; }

/* ============ MULTI-BOOTH PICKER ============ */
.booth-picker-box { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 10px; width: 100%; }
.booth-tags {
  flex: 1; min-width: 200px; display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 10px;
  border: 1.5px solid var(--border); border-radius: var(--radius-sm); background: var(--surface-alt); min-height: 40px; align-items: center; justify-content: center;
}
.booth-tags-empty { color: var(--text-faint); font-size: 12.5px; font-style: italic; }
.booth-tag {
  display: inline-flex; align-items: center; gap: 6px; background: var(--primary-light); color: var(--primary-dark);
  font-size: 12px; font-weight: 700; padding: 4px 8px 4px 10px; border-radius: 20px;
}
.booth-tag button { border: none; background: transparent; color: var(--primary-dark); cursor: pointer; font-size: 13px; line-height: 1; padding: 0; }
.booth-tag button:hover { color: var(--red); }

.booth-type-options { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; width: 100%; }
.booth-type-pill {
  display: inline-flex; align-items: center; gap: 7px; padding: 9px 14px; border-radius: 10px;
  border: 1.5px solid var(--border); background: var(--surface-alt); font-weight: 600; font-size: 13px; cursor: pointer;
  transition: border-color .15s, background .15s, color .15s;
}
.booth-type-pill input { accent-color: var(--primary); width: 16px; height: 16px; cursor: pointer; }
.booth-type-pill:has(input:checked) { border-color: var(--primary); background: var(--primary-light); color: var(--primary-dark); }

.picker-toolbar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.picker-toolbar select { padding: 9px 12px; border-radius: var(--radius-sm); border: 1.5px solid var(--border); background: var(--surface); font-weight: 600; }
.picker-legend { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--text-muted); font-weight: 600; white-space: nowrap; }
.legend-swatch { width: 12px; height: 12px; border-radius: 4px; display: inline-block; margin-left: 8px; }
.legend-swatch:first-child { margin-left: 0; }
.legend-swatch.available { background: var(--surface); border: 1.5px solid var(--border-strong); }
.legend-swatch.selected { background: var(--primary); }
.legend-swatch.booked { background: var(--text-faint); }

.picker-summary { font-size: 12.5px; color: var(--text-muted); font-weight: 600; margin-bottom: 12px; }

.booth-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 8px;
  max-height: 340px; overflow-y: auto; padding: 4px;
}
.booth-cell {
  border: 1.5px solid var(--border-strong); border-radius: 8px; padding: 8px 6px; text-align: center;
  cursor: pointer; font-size: 11px; font-weight: 700; background: var(--surface); color: var(--text);
  transition: all .12s ease; user-select: none;
}
.booth-cell:hover { border-color: var(--primary); }
.booth-cell.selected { background: var(--primary); border-color: var(--primary); color: #fff; }
.booth-cell.booked { background: var(--surface-alt); border-color: var(--border); color: var(--text-faint); cursor: not-allowed; text-decoration: line-through; }
.booth-cell.blocked { background: var(--red-light); border-color: #fecaca; color: var(--red); cursor: not-allowed; }
.booth-cell .bc-size { display: block; font-size: 9.5px; font-weight: 500; opacity: 0.75; margin-top: 2px; }

.picker-pagination { display: flex; justify-content: center; gap: 6px; margin-top: 14px; flex-wrap: wrap; }
.picker-pagination button {
  border: 1px solid var(--border); background: var(--surface); border-radius: 8px; padding: 6px 11px; cursor: pointer; font-size: 12.5px; color: var(--text); font-weight: 700;
}
.picker-pagination button.active { background: var(--primary-grad); color: #fff; border-color: transparent; }
.picker-selected-count { font-size: 12.5px; font-weight: 700; color: var(--text-muted); }

.assigned-booths-cell { display: flex; flex-direction: column; gap: 2px; font-size: 11.5px; }
.assigned-booths-cell .more-badge { color: var(--text-faint); font-style: italic; }

/* ============ HALL CARDS (clickable, dashboard-stat style) ============ */
.hall-card-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: 10px; margin-bottom: 14px;
}
.hall-card {
  background: var(--surface); border-radius: var(--radius); padding: 10px 12px;
  display: flex; align-items: center; justify-content: center; gap: 9px; box-shadow: var(--shadow-sm); border: 1.5px solid var(--border);
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
  position: relative; overflow: hidden; cursor: pointer; text-align: center;
  color: var(--text); font-family: inherit;
}
.hall-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
.hall-card.active { border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-light), var(--shadow-md); }
.hall-card::after { content:''; position:absolute; right:-30px; top:-30px; width:90px; height:90px; border-radius:50%; opacity:.08; }
.hall-card .hall-icon {
  font-size: 15px; width: 32px; height: 32px; border-radius: 9px; display: flex; align-items: center; justify-content: center;
  flex-shrink: 0; color: #fff;
}
.hall-card .hall-body { min-width: 0; text-align: center; }
.hall-card .hall-value { font-size: 15px; font-weight: 800; line-height: 1.1; letter-spacing: -0.01em; white-space: nowrap; }
.hall-card .hall-label { font-size: 10.5px; color: var(--text-muted); font-weight: 700; margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.hall-card-c0 .hall-icon { background: var(--primary-grad); box-shadow: 0 6px 16px rgba(18,179,129,.32); } .hall-card-c0::after { background: var(--primary); }
.hall-card-c1 .hall-icon { background: var(--green-grad); box-shadow: 0 6px 16px rgba(5,150,105,.28); } .hall-card-c1::after { background: var(--green); }
.hall-card-c2 .hall-icon { background: var(--amber-grad); box-shadow: 0 6px 16px rgba(217,119,6,.28); } .hall-card-c2::after { background: var(--amber); }
.hall-card-c3 .hall-icon { background: var(--red-grad); box-shadow: 0 6px 16px rgba(220,38,38,.28); } .hall-card-c3::after { background: var(--red); }
.hall-card-c4 .hall-icon { background: var(--purple-grad); box-shadow: 0 6px 16px rgba(124,58,237,.28); } .hall-card-c4::after { background: var(--purple); }
.hall-card-c5 .hall-icon { background: linear-gradient(135deg, #0891b2, #22d3ee); box-shadow: 0 6px 16px rgba(8,145,178,.28); } .hall-card-c5::after { background: #0891b2; }
.hall-card-c6 .hall-icon { background: linear-gradient(135deg, #db2777, #f472b6); box-shadow: 0 6px 16px rgba(219,39,119,.28); } .hall-card-c6::after { background: #db2777; }
/* Event Overview's hall indicator reuses the same cards purely as a read-only
   breakdown (no click-to-filter there), so drop the pointer cursor/hover lift. */
.hall-card-static { cursor: default; }
.hall-card-static:hover { transform: none; box-shadow: var(--shadow-sm); }

/* ============ OPERATIONAL (contractor / product grouping / follow-up) ============
   Deliberately a card grid, not a table -- the whole point of this screen is to
   make follow-up urgency scannable at a glance (overdue vs. due soon vs. upcoming),
   which a left-edge color accent + badge communicates far faster than a text column. */
.op-summary-strip { display: flex; flex-wrap: wrap; gap: 9px; margin-bottom: 16px; }
.op-chip {
  display: flex; align-items: center; gap: 6px; padding: 7px 14px; border-radius: 999px;
  background: var(--surface); border: 1.5px solid var(--border); color: var(--text);
  font-weight: 800; font-size: 13px; cursor: pointer; transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
  font-family: 'Sora', 'Inter', sans-serif;
}
.op-chip span { font-weight: 600; font-size: 11.5px; color: var(--text-muted); }
.op-chip:hover { transform: translateY(-2px); box-shadow: var(--shadow-sm); }
.op-chip-active { border-color: currentColor; box-shadow: 0 0 0 3px rgba(255,106,61,0.15); }
.op-chip.op-fu-overdue { color: var(--red); } .op-chip.op-fu-overdue.op-chip-active { background: var(--red-light); }
.op-chip.op-fu-today { color: var(--amber); } .op-chip.op-fu-today.op-chip-active { background: var(--amber-light); }
.op-chip.op-fu-soon { color: var(--brass-dark); } .op-chip.op-fu-soon.op-chip-active { background: var(--brass-light); }
.op-chip.op-fu-upcoming { color: var(--green); } .op-chip.op-fu-upcoming.op-chip-active { background: var(--green-light); }
.op-chip.op-fu-none { color: var(--text-muted); } .op-chip.op-fu-none.op-chip-active { background: var(--surface-alt); }
.op-chip.op-chip-done { color: var(--purple); } .op-chip.op-chip-done.op-chip-active { background: var(--purple-light); }

.op-card-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px;
}
.op-card {
  background: var(--surface); border-radius: var(--radius); padding: 16px 18px;
  border: 1.5px solid var(--border); border-left-width: 5px; box-shadow: var(--shadow-sm);
  display: flex; flex-direction: column; gap: 12px; transition: transform .15s ease, box-shadow .15s ease;
}
.op-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.op-card-top { display: flex; align-items: flex-start; gap: 11px; }
.op-avatar {
  width: 40px; height: 40px; border-radius: 12px; flex-shrink: 0; display: flex; align-items: center; justify-content: center;
  background: var(--brass-grad); color: #211705; font-weight: 800; font-size: 14px; font-family: 'Sora', 'Inter', sans-serif;
  box-shadow: 0 4px 10px rgba(255,106,61,0.28);
}
.op-card-titles { flex: 1; min-width: 0; }
.op-contractor { font-weight: 800; font-size: 14.5px; font-family: 'Sora', 'Inter', sans-serif; letter-spacing: -0.01em; line-height: 1.25; }
.op-company { font-size: 11.5px; color: var(--text-muted); margin-top: 3px; display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.op-followup-badge {
  flex-shrink: 0; padding: 4px 10px; border-radius: 20px; font-size: 10px; font-weight: 800;
  white-space: nowrap; display: inline-flex; align-items: center; gap: 4px;
}
.op-card-body { display: flex; flex-direction: column; gap: 7px; }
.op-group-pill {
  align-self: flex-start; background: var(--surface-alt); border: 1px solid var(--border);
  color: var(--text); font-size: 11px; font-weight: 700; padding: 3px 10px; border-radius: 8px;
}
.op-group-pill-empty { color: var(--text-faint); font-weight: 500; font-style: italic; }
.op-followup-line { font-size: 12.5px; font-weight: 700; color: var(--text); }
.op-notes { font-size: 12px; color: var(--text-muted); line-height: 1.4; }
.op-card-footer { display: flex; gap: 8px; flex-wrap: wrap; padding-top: 8px; border-top: 1px solid var(--border); }

/* Left-edge accent + badge coloring, keyed off the same urgency bucket used in JS */
.op-card.op-fu-overdue { border-left-color: var(--red); }
.op-card.op-fu-overdue .op-followup-badge { background: var(--red-light); color: var(--red); }
.op-card.op-fu-today { border-left-color: var(--amber); }
.op-card.op-fu-today .op-followup-badge { background: var(--amber-light); color: var(--amber); }
.op-card.op-fu-soon { border-left-color: var(--brass); }
.op-card.op-fu-soon .op-followup-badge { background: var(--brass-light); color: var(--brass-dark); }
.op-card.op-fu-upcoming { border-left-color: var(--green); }
.op-card.op-fu-upcoming .op-followup-badge { background: var(--green-light); color: var(--green); }
.op-card.op-fu-none { border-left-color: var(--border-strong); }
.op-card.op-fu-none .op-followup-badge { background: var(--surface-alt); color: var(--text-muted); }
.op-card.op-card-done { border-left-color: var(--purple); opacity: 0.72; }
.op-card.op-card-done .op-contractor { text-decoration: line-through; text-decoration-color: var(--text-faint); }

@media (max-width: 640px) {
  .op-card-grid { grid-template-columns: 1fr; }
  .op-summary-strip { gap: 7px; }
  .op-chip { padding: 6px 11px; font-size: 12px; }
}

/* ============ STATUS PILL FILTER GROUP ============ */
.status-pill-group { display: flex; gap: 8px; flex-wrap: wrap; }
.status-pill {
  padding: 9px 15px; border-radius: 20px; border: 1.5px solid var(--border-strong); background: var(--surface);
  font-weight: 700; font-size: 12.5px; cursor: pointer; color: var(--text-muted); transition: all .15s ease; box-shadow: var(--shadow-xs);
}
.status-pill:hover { border-color: var(--primary); color: var(--primary-dark); }
.status-pill.active { background: var(--primary-grad); border-color: transparent; color: #fff; box-shadow: 0 4px 12px rgba(18,179,129,.3); }
.status-pill-available.active { background: var(--green-grad); box-shadow: 0 4px 12px rgba(5,150,105,.28); }
.status-pill-booked.active { background: var(--amber-grad); box-shadow: 0 4px 12px rgba(217,119,6,.28); }
.status-pill-blocked.active { background: var(--red-grad); box-shadow: 0 4px 12px rgba(220,38,38,.28); }

.halls-filter-clear { font-size: 12px; font-weight: 700; color: var(--primary); cursor: pointer; }

/* ============ BOOTH MAP (visual, read-only) ============ */
.boothmap-legend { display: flex; gap: 16px; align-items: center; font-size: 12.5px; font-weight: 700; color: var(--text-muted); flex-shrink: 0; }
.boothmap-legend-item { display: flex; align-items: center; gap: 6px; }
.boothmap-dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; flex-shrink: 0; }
.boothmap-dot.available { background: var(--green-grad); }
.boothmap-dot.booked { background: var(--amber-grad); }
.boothmap-dot.blocked { background: var(--red-grad); }

.boothmap-hall-count { font-size: 11px; font-weight: 700; color: var(--text-muted); margin-left: 6px; }
.boothmap-empty { padding: 40px 20px; text-align: center; color: var(--text-muted); font-weight: 600; }

/* ---- Floor-plan layout: halls laid out side by side, roughly matching a real venue
   plan (loading docks + drop-off on top, landmark rooms on the left, food court on
   the right, gates along the bottom). This is a close visual approximation, not a
   pixel-exact reproduction of the venue's official floor plan. ---- */
.boothmap-floorplan { overflow-x: auto; overflow-y: hidden; padding: 6px 4px 20px; }
.boothmap-floorplan-inner { display: inline-flex; flex-direction: column; gap: 10px; min-width: max-content; }

.boothmap-main-row { display: flex; align-items: stretch; gap: 10px; }

.boothmap-hallzone {
  border: 1.5px solid var(--border-strong); border-radius: 12px; background: var(--surface);
  padding: 8px; display: flex; flex-direction: column; gap: 6px; box-shadow: var(--shadow-xs), var(--glass-edge);
}
.boothmap-hall-rows { display: flex; flex-direction: column; gap: 4px; }
.boothmap-hall-row { display: flex; gap: 3px; flex-wrap: nowrap; }
.boothmap-aisle-gap { height: 10px; }

/* 5x2 blocks (5 columns, 2 rows) grouped into bands of exactly 3 blocks side by side --
   matching the venue's real booth clusters, which sit in fixed rows of 3 groups
   separated by aisles. Bands stack vertically underneath each other. */
.boothmap-hall-bands { display: flex; flex-direction: column; gap: 16px; }
.boothmap-hall-band { display: flex; gap: 14px; }
.boothmap-block { display: grid; grid-template-columns: repeat(5, 1fr); grid-auto-rows: min-content; gap: 3px; }

/* Freeform canvas: booths are positioned children (left/top set inline as % of this
   box, see boothMapCellHtml), not grid cells -- the box just needs an explicit size for
   percentages to resolve against. */
.boothmap-canvas {
  position: relative;
  width: 1100px; height: 760px;
  background:
    linear-gradient(var(--border) 1px, transparent 1px) 0 0 / 8px 8px,
    linear-gradient(90deg, var(--border) 1px, transparent 1px) 0 0 / 8px 8px;
  background-color: var(--surface-alt);
  border: 1.5px dashed var(--border-strong);
  border-radius: 8px;
  flex-shrink: 0;
}

.boothmap-canvas-empty {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  color: var(--text-muted);
  font-weight: 600;
  text-align: center;
  pointer-events: none; /* never intercept the drag/drop or click-to-place events meant for the canvas */
  width: 80%;
}

.boothmap-cell {
  position: absolute;
  left: 0; top: 0; /* overridden inline per booth */
  transform: translate(-50%, -50%);
  --bm-w: 34px;
  --bm-h: 30px;
  width: calc(var(--bm-w) * var(--bm-scale, 1));
  height: calc(var(--bm-h) * var(--bm-scale, 1));
  display: flex; align-items: center; justify-content: center;
  border-radius: 0;
  border: 1px solid rgba(255,255,255,0.18);
  font-size: 8px; font-weight: 800;
  color: #fff;
  transition: transform .12s ease, box-shadow .12s ease;
}
.boothmap-cell:hover { transform: translate(-50%, -50%) scale(1.35); box-shadow: var(--shadow-sm); z-index: 5; }
.boothmap-cell.available { background: var(--green-grad); }
.boothmap-cell.booked { background: var(--amber-grad); }
.boothmap-cell.blocked { background: var(--red-grad); }
.boothmap-cell.boothmap-dim { opacity: .22; }
.boothmap-cell.boothmap-highlight { outline: 2.5px solid var(--primary); outline-offset: 1px; transform: translate(-50%, -50%) scale(1.35); z-index: 6; }

/* Multi-booth: company holds more than 1 booth — red highlight */
.boothmap-cell.multi-booth {
  background: linear-gradient(135deg, #ef4444, #dc2626) !important;
  color: #fff !important;
  box-shadow: 0 0 0 2px rgba(239,68,68,0.45), 0 3px 10px rgba(220,38,38,0.40);
  z-index: 4;
}
.boothmap-cell.multi-booth:hover {
  background: linear-gradient(135deg, #f87171, #ef4444) !important;
  box-shadow: 0 0 0 3px rgba(239,68,68,0.65), 0 4px 14px rgba(220,38,38,0.55);
}
.boothmap-cell.in-group {
  outline: 2px solid rgba(220,38,38,0.80);
  outline-offset: -1px;
}

/* Shared tooltip element (positioned via JS on hover) -- a normal raised/floating card,
   not a flat "pressed" chip. Two centered lines: booth name above, exhibitor below. */
.boothmap-tooltip {
  display: none;
  position: fixed;
  z-index: 1000;
  background: var(--surface);
  border: 1.5px solid var(--border-strong);
  border-radius: 10px;
  padding: 8px 16px;
  box-shadow: var(--shadow-md);
  text-align: center;
  pointer-events: none;
  max-width: 220px;
}
.boothmap-tooltip .bmt-name { font-size: 12.5px; font-weight: 800; color: var(--text); text-align: center; }
.boothmap-tooltip .bmt-sub { font-size: 11px; font-weight: 600; color: var(--text-muted); margin-top: 3px; text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.boothmap-tooltip::before {
  content: '';
  position: absolute;
  top: 100%; left: 50%;
  transform: translateX(-50%);
  border: 7px solid transparent;
  border-top-color: var(--border-strong);
}
.boothmap-tooltip::after {
  content: '';
  position: absolute;
  top: 100%; left: 50%;
  transform: translateX(-50%) translateY(-1.5px);
  border: 6px solid transparent;
  border-top-color: var(--surface);
}

/* ---- Focused single-hall view (shown when a hall pill is clicked instead of "All
   Halls") -- a bigger, simpler grid dedicated to just that one hall. ---- */
.boothmap-focused { padding: 4px; }
.boothmap-focused-header { display: flex; align-items: center; gap: 14px; padding: 4px 4px 16px; flex-wrap: wrap; }
.boothmap-focused-header h3 { font-size: 16px; font-weight: 800; color: var(--text); margin: 0; }
/* Focused single-hall canvas: same freeform layout, just a bigger box and bigger cells */
.boothmap-focused-grid { max-width: 100%; }
.boothmap-focused-grid .boothmap-canvas { width: 2200px; height: 1300px; }
.boothmap-focused-grid .boothmap-cell {
  --bm-w: 56px;
  --bm-h: 48px;
  font-size: 12px;
  border-radius: 6px;
  flex-shrink: 0;
}

@media (max-width: 720px) {
  .boothmap-legend { width: 100%; justify-content: space-between; }
  .boothmap-cell { --bm-w: 28px; --bm-h: 26px; }
  .boothmap-focused-grid .boothmap-canvas { width: 100%; min-width: 1400px; height: 900px; }
  .boothmap-focused-grid .boothmap-cell { --bm-w: 44px; --bm-h: 40px; font-size: 10.5px; }
}
.halls-filter-clear:hover { text-decoration: underline; }

.booth-slot-link { color: var(--primary-dark); font-weight: 800; background: none; border: none; padding: 0; cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }
.booth-slot-link:hover { color: var(--primary); }

.role-badge { padding: 3px 10px; border-radius: 20px; font-size: 10.5px; font-weight: 800; text-transform: capitalize; }
.role-admin { background: var(--primary-light); color: var(--primary-dark); }
.role-staff { background: var(--green-light); color: var(--green); }
.role-finance { background: var(--amber-light); color: var(--amber); }
.role-viewer { background: var(--purple-light); color: var(--purple); }
.role-operational { background: var(--accent-light); color: var(--accent); }

.row-actions { display: flex; gap: 6px; justify-content: center; }
.row-actions button { font-size: 12px; padding: 6px 10px; }


.table-footer { display: flex; align-items: center; justify-content: space-between; padding: 13px 20px; border-top: 1px solid var(--border); font-size: 12.5px; color: var(--text-muted); font-weight: 600; }
.pagination { display: flex; gap: 6px; }
.pagination button {
  border: 1px solid var(--border); background: var(--surface); border-radius: 8px; padding: 6px 11px; cursor: pointer; font-size: 12.5px; color: var(--text); font-weight: 700;
}
.pagination button.active { background: var(--primary-grad); color: #fff; border-color: transparent; }

.empty-state { text-align: center; padding: 48px 20px; color: var(--text-muted); }
.empty-state .empty-icon { font-size: 34px; margin-bottom: 10px; }

/* ============ MODAL ============ */
.modal-overlay {
  position: fixed; inset: 0; background: rgba(15,20,35,0.5); backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center; z-index: 100; padding: 20px;
}
/* Lunchbox's "Manage Menus" modal can open a second modal on top of itself (Add/Edit
   Menu Item) -- without a higher z-index, two modal-overlays sitting at the identical
   z-index: 100 have their click-interception order become unreliable (whichever is
   later in DOM order should win, but this shouldn't be left to chance), so the nested
   one needs an explicit bump above the first. */
#lunchbox-item-modal-overlay { z-index: 110; }
/* Manage Halls can open Rename Hall on top of itself -- same nested-modal
   z-index bump reasoning as the lunchbox item modal above. */
#rename-hall-overlay { z-index: 110; }
/* Modals are deliberately a SOLID, opaque light (or dark) panel rather than the glass
   treatment used elsewhere -- stacking a blurred/translucent modal over the already-
   blurred backdrop made form fields read as washed-out gray instead of a crisp,
   readable dialog. No backdrop-filter here on purpose. */
.modal {
  background: var(--surface-solid); border-radius: 20px; width: 100%; max-width: 480px;
  box-shadow: var(--shadow-lg), var(--glass-edge); max-height: 88vh; display: flex; flex-direction: column; overflow: hidden;
  animation: modalPopBounce .38s cubic-bezier(.2,.9,.25,1.15) both;
}
.modal-lg { max-width: 800px; }
.modal-header { display: flex; align-items: center; justify-content: space-between; padding: 14px 22px; border-bottom: 1px solid var(--border); flex-shrink: 0; }
.modal-header h3 { margin: 0; font-size: 17px; font-weight: 800; }
.modal form { display: flex; flex-direction: column; min-height: 0; flex: 1; }
.modal-body { padding: 16px 22px; overflow-y: auto; min-height: 0; flex: 1; }
.modal-footer { padding: 12px 22px; border-top: 1px solid var(--border); display: flex; justify-content: center; gap: 10px; flex-shrink: 0; }

/* Form fields *inside* modals get a solid fill too (instead of the app-wide translucent
   .field input/select), so they stay crisp and readable against the now-opaque modal. */
.modal .field input,
.modal .field select,
.modal .field textarea,
.modal #event-prices-table .ep-price-input,
.modal #event-prices-table .ep-onsite-price-input,
.modal .va-library-box {
  background: var(--surface-alt-solid);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
.modal .field input:focus,
.modal .field select:focus,
.modal .field textarea:focus {
  background: var(--surface-solid);
}

/* ---- Per-category entrance animations ----
   Rather than every dialog using the same fade/scale, each family of modal gets a
   motion that matches what it's for: primary create/edit forms spring in with a
   little bounce; read-only detail panes rise calmly from below; drill-down/secondary
   dialogs (opened from within another modal) slide in from the side; bulk-data /
   import dialogs get a subtle 3D flip. */
@keyframes modalPopBounce {
  0%   { opacity: 0; transform: scale(.9) translateY(18px); }
  60%  { opacity: 1; transform: scale(1.015) translateY(-2px); }
  100% { opacity: 1; transform: scale(1) translateY(0); }
}
@keyframes modalSlideUp {
  from { opacity: 0; transform: translateY(38px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes modalSlideSide {
  from { opacity: 0; transform: translateX(48px) scale(.98); }
  to   { opacity: 1; transform: translateX(0) scale(1); }
}
@keyframes modalFlipIn {
  from { opacity: 0; transform: perspective(1000px) rotateX(-10deg) translateY(16px); }
  to   { opacity: 1; transform: perspective(1000px) rotateX(0deg) translateY(0); }
}

/* Read-only detail / view panes -- calmer rise, no bounce. */
#order-detail-overlay .modal,
#lunchbox-order-detail-overlay .modal,
#view-detail-overlay .modal,
#payment-modal-overlay .modal,
#event-prices-modal-overlay .modal {
  animation: modalSlideUp .34s cubic-bezier(.16,1,.3,1) both;
}
/* Drill-down / secondary dialogs opened from within another modal -- slide in sideways
   so they read as "one step deeper" rather than a fresh dialog. */
#rename-hall-overlay .modal,
#create-hall-overlay .modal,
#manage-halls-overlay .modal,
#lunchbox-menu-list-overlay .modal,
#edit-slot-overlay .modal,
#generate-inventory-overlay .modal,
#booth-picker-overlay .modal {
  animation: modalSlideSide .34s cubic-bezier(.16,1,.3,1) both;
}
/* Bulk-data / import / library dialogs -- a light 3D flip to signal "loading a
   different kind of view" rather than a simple record editor. */
#import-modal-overlay .modal,
#va-library-add-overlay .modal,
#va-library-import-overlay .modal {
  animation: modalFlipIn .4s cubic-bezier(.2,.85,.3,1) both;
}

@media (prefers-reduced-motion: reduce) {
  .modal { animation: none !important; }
}


.form-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px 14px; }
.field-wide { grid-column: span 3; }
.status-boothtype-row { display: grid; grid-template-columns: 1fr 2fr; gap: 8px 14px; align-items: start; }
.status-boothtype-row .booth-type-options { flex-wrap: nowrap; gap: 6px; }
.status-boothtype-row .booth-type-pill { flex: 1 1 0; padding: 9px 6px; font-size: 12px; white-space: nowrap; justify-content: center; gap: 4px; }
.field-span2 { grid-column: span 2; }
.field-section { grid-column: span 3; font-size: 11.5px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.04em; color: var(--primary-dark); border-bottom: 1px solid var(--border-strong); padding-bottom: 3px; margin-top: 4px; text-align: center; }
.form-row-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }

.dropzone {
  border: 2px solid var(--border-strong); border-radius: var(--radius-sm); padding: 30px 20px; text-align: center;
  color: var(--text-muted); cursor: pointer; transition: border-color .15s, background .15s; background: var(--surface-alt);
}
.dropzone:hover, .dropzone.dragover { border-color: var(--primary); background: var(--primary-light); color: var(--primary-dark); }
.dropzone .dz-icon { font-size: 30px; margin-bottom: 8px; }
.import-preview-table { max-height: 260px; overflow: auto; border: 1px solid var(--border); border-radius: 10px; margin-top: 14px; }

/* ============ TOAST ============ */
#toast-container { position: fixed; bottom: 22px; right: 22px; display: flex; flex-direction: column; gap: 10px; z-index: 999; }
.toast {
  background: var(--surface); border: 1px solid var(--border); border-left: 4px solid var(--primary);
  border-radius: 12px; padding: 13px 17px; box-shadow: var(--shadow-md); min-width: 270px; font-size: 13px; font-weight: 600;
  animation: toastIn .25s cubic-bezier(.2,.8,.2,1);
  display: flex; align-items: center; gap: 10px;
}
.toast.toast-success { border-left-color: var(--green); }
.toast.toast-error { border-left-color: var(--red); }
@keyframes toastIn { from {opacity:0; transform: translateX(24px);} to {opacity:1; transform: translateX(0);} }

/* ============ VIRTUAL ACCOUNT EDITABLE CELLS ============ */
.va-cell { min-width: 160px; text-align: center; }
#va-library-table th:nth-child(1), #va-library-table td.va-cell:nth-child(1) { width: 14%; min-width: 120px; }
#va-library-table th:nth-child(2), #va-library-table td.va-cell:nth-child(2) { width: 20%; min-width: 160px; }
#va-library-table th:nth-child(3), #va-library-table td.va-cell:nth-child(3) { width: 56%; min-width: 320px; }
.va-input {
  border: 1.5px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 8px 12px;
  background: var(--surface-alt);
  color: var(--text);
  outline: none;
  transition: border-color .15s, box-shadow .15s, background .15s;
  width: 100%;
  text-align: center;
}
.va-input:focus {
  border-color: var(--primary);
  background: #fff;
  box-shadow: 0 0 0 4px var(--primary-light);
}
.va-readonly { color: var(--text-muted); font-weight: 600; display: block; text-align: center; }

/* "Library" box on the booking form -- shows whether the typed Company Name is
   linked to an entry in the Virtual Account library (see the smart-match logic
   in app.js). Sized/bordered to match a normal .field input so it sits flush in
   the form grid, but isn't itself an editable input. */
.va-library-box {
  border: 1.5px dashed var(--border);
  border-radius: var(--radius-sm);
  padding: 8px 12px;
  background: var(--surface-alt);
  min-height: 37px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
}
.va-match-hint-idle { font-size: 11.5px; color: var(--text-faint); font-weight: 600; }
#va-match-hint.va-match-hint-linked { font-size: 11.5px; font-weight: 700; color: var(--green); }
#va-match-hint.va-match-hint-suggest { font-size: 11.5px; font-weight: 700; color: var(--text-muted); }

/* ============ RESPONSIVE ============ */
@media (max-width: 1100px) {
  .stats-grid, .stats-grid-secondary { grid-template-columns: repeat(2, 1fr); }
  .dashboard-grid { grid-template-columns: 1fr; }
  .form-grid { grid-template-columns: 1fr 1fr; }
  .field-wide { grid-column: span 2; }
  .field-span2 { grid-column: span 2; }
  .field-section { grid-column: span 2; }
  .payment-spk-info { grid-template-columns: 1fr 1fr; }
  .view-detail-grid { grid-template-columns: 1fr 1fr; }
  .view-detail-grid .vd-item.vd-wide { grid-column: span 2; }
}
@media (max-width: 900px) {
  .modal-lg { max-width: 92vw; }
  .termin-body { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 720px) {
  .sidebar {
    position: fixed; left: 0; top: 0; margin-left: calc(-1 * var(--sidebar-w)); box-shadow: var(--shadow-lg); z-index: 101;
    padding-left: max(16px, env(safe-area-inset-left));
  }
  .sidebar.open { margin-left: 0; }
  .stats-grid, .stats-grid-secondary { grid-template-columns: 1fr 1fr; }
  .form-grid { grid-template-columns: 1fr; }
  .field-wide, .field-section, .field-span2 { grid-column: span 1; }
  .topbar {
    left: 0; right: 0; width: auto;
    padding-left: max(16px, env(safe-area-inset-left)); padding-right: max(16px, env(safe-area-inset-right)); gap: 10px;
  }
  .topbar-title { font-size: 16px; }
  .topbar-actions { gap: 8px; flex-basis: 100%; justify-content: space-between; }
  .event-selector { flex: 1; min-width: 0; }
  .event-selector select { max-width: none; width: 100%; }
  .event-selector label { display:none; }
  .sidebar-backdrop.visible { display: block; }

  /* ---- Login screen: bigger card looks great on desktop but must shrink
     gracefully on phones so nothing overflows or gets cut off. ---- */
  .login-wrap {
    flex-direction: column; padding: 20px 16px 64px; align-items: center;
    justify-content: flex-start; padding-top: max(40px, env(safe-area-inset-top));
  }
  .login-card { padding: 32px 22px; border-radius: 22px; max-width: 100%; width: 100%; }
  .login-brand { margin-bottom: 26px; }
  .brand-icon { width: 64px; height: 64px; font-size: 28px; border-radius: 18px; margin-bottom: 12px; }
  .login-brand h1 { font-size: 24px; }
  .login-brand p { font-size: 13px; }
  .login-card .field input { padding: 12px 14px; font-size: 15px; }
  .login-copyright { position: static; margin-top: 18px; text-align: center; width: 100%; right: auto; bottom: auto; }

  /* ---- Content/cards get tighter side padding so nothing touches the edge ----
     NOTE: padding-top must keep reserving space for the fixed topbar (--topbar-h);
     a previous version of this rule reset all four sides and clipped content
     underneath the topbar. ---- */
  .content { padding: calc(var(--topbar-h, 116px) + 16px) 14px 40px; }
  .card-header, .card-body { padding: 14px 16px; }
  .toolbar { gap: 8px; }
  .search-box { min-width: 0; width: 100%; }
  #filter-status, #filter-booth-type, #orders-filter-status, #orders-filter-onsite, #lunchbox-orders-filter-status, #operational-filter-status, #price-list-filter-category, #price-list-filter-active, #activity-user-filter { width: 100%; }

  /* ---- Modals: near-fullscreen on phones instead of a small floating card ---- */
  .modal-overlay { padding: 0; align-items: flex-end; }
  .modal { max-width: 100%; width: 100%; max-height: 94vh; border-radius: 20px 20px 0 0; }
  .modal-lg { max-width: 100%; }
  .modal-header { padding: 16px 18px; }
  .modal-body { padding: 16px 18px; }
  .modal-footer { padding: 12px 18px; padding-bottom: max(12px, env(safe-area-inset-bottom)); flex-wrap: wrap; }
  .modal-footer .toolbar-spacer { flex-basis: 100%; order: 1; height: 0; }

  /* ---- Payment / termin cards stack cleanly in one column ---- */
  .termin-card { flex-direction: column; align-items: stretch; gap: 10px; }
  .termin-badge { align-self: flex-start; }
  .termin-body { grid-template-columns: 1fr 1fr; gap: 10px; }
  .payment-summary-bar, .payment-spk-info { grid-template-columns: 1fr; flex-direction: column; align-items: stretch; }
  .payment-spk-info { grid-template-columns: 1fr; }

  /* ---- View-detail modal collapses to a single readable column ---- */
  .view-detail-grid { grid-template-columns: 1fr; gap: 14px; }
  .view-detail-grid .vd-item.vd-wide { grid-column: 1; }

  /* ---- Booth picker grid: smaller cells so more fit without horizontal scroll ---- */
  .booth-grid { grid-template-columns: repeat(auto-fill, minmax(64px, 1fr)); max-height: 280px; }
  .picker-toolbar { flex-direction: column; align-items: stretch; }
  .picker-toolbar select { width: 100%; }
  .picker-legend { justify-content: flex-start; }

  /* ---- Hall summary cards: 2 per row instead of squeezing many into one row ---- */
  .hall-card-grid { grid-template-columns: repeat(2, 1fr); gap: 8px; }
  .hall-card { padding: 9px 10px; gap: 8px; }
  .hall-card .hall-icon { width: 30px; height: 30px; font-size: 14px; border-radius: 8px; }
  .hall-card .hall-value { font-size: 14px; }

  .form-row-2 { grid-template-columns: 1fr; }

  /* ---- Toasts: full-width with safe margins instead of a fixed 270px card that
     can overflow a narrow viewport ---- */
  #toast-container { left: 12px; right: 12px; bottom: max(12px, env(safe-area-inset-bottom)); }
  .toast { min-width: 0; width: 100%; }

  /* ---- Row action buttons wrap instead of forcing extra-wide table cells ---- */
  .row-actions { flex-wrap: wrap; }
  .table-footer { flex-direction: column; align-items: flex-start; gap: 10px; }
  .pagination { flex-wrap: wrap; }

  .status-pill-group { gap: 6px; }
  .status-pill { padding: 7px 12px; font-size: 12px; }

  /* ---- Activity Log: stack each row as a readable card instead of a cramped,
     horizontally-scrolling table -- details messages are now much longer/more
     specific (e.g. "Amount: 20,000,000 -> 25,000,000; Due Date: ... -> ...")
     so they need to wrap and breathe rather than being clipped off-screen. ---- */
  #activity-table { min-width: 0; }
  #activity-table thead { display: none; }
  #activity-table tbody, #activity-table tr { display: block; width: 100%; }
  #activity-table tr {
    border: 1px solid var(--border); border-radius: var(--radius-sm); margin-bottom: 10px;
    padding: 12px 14px; background: var(--surface);
  }
  #activity-table td {
    display: block; border: none; padding: 3px 0; font-size: 13px; white-space: normal; word-break: break-word;
  }
  #activity-table td.activity-time { font-size: 11px; color: var(--text-faint); font-weight: 700; order: 1; }
  #activity-table td.activity-action { order: 2; margin: 4px 0; }
  #activity-table td.activity-user { font-size: 11.5px; color: var(--text-muted); font-weight: 700; order: 3; }
  #activity-table td.activity-details { order: 4; line-height: 1.45; }
  #activity-table tr { display: flex; flex-direction: column; }

  /* ---- Prices per Event: same "stack each row as a card" treatment as Activity
     Log above -- two number inputs plus two action buttons genuinely can't fit
     side-by-side on a phone screen at a usable size, which is exactly the real bug
     reported (the Save button was pushed off-screen, requiring a sideways scroll
     that's very easy to miss/not realize is there -- looked like saving "didn't
     work" even though it actually did). Stacking removes the horizontal scroll
     entirely instead of just shrinking things further. ---- */
  #event-prices-table { min-width: 0; }
  #event-prices-table thead { display: none; }
  #event-prices-table tbody, #event-prices-table tr { display: block; width: 100%; }
  #event-prices-table tr {
    border: 1px solid var(--border); border-radius: var(--radius-sm); margin-bottom: 10px;
    padding: 12px 14px; background: var(--surface); display: flex; flex-direction: column; gap: 8px;
  }
  #event-prices-table td { display: block; border: none; padding: 0; }
  #event-prices-table td[data-label]::before {
    content: attr(data-label); display: block; font-size: 10.5px; font-weight: 800; text-transform: uppercase;
    letter-spacing: 0.04em; color: var(--text-muted); margin-bottom: 4px;
  }
  #event-prices-table td .ep-price-input, #event-prices-table td .ep-onsite-price-input { width: 100%; }
  #event-prices-table td.row-actions { flex-direction: row; flex-wrap: wrap; }
}
@media (max-width: 420px) {
  /* Very narrow phones (iPhone SE etc.): drop to a single stat column and
     shrink the booth-type/status pill rows further so nothing wraps oddly. */
  .stats-grid, .stats-grid-secondary { grid-template-columns: 1fr; }
  .hall-card-grid { grid-template-columns: 1fr; }
  .login-brand h1 { font-size: 21px; }
  .brand-icon { width: 56px; height: 56px; font-size: 24px; }
  .booth-type-options, .status-pill-group { gap: 6px; }
  .booth-type-pill { padding: 8px 12px; font-size: 12.5px; }
}
/* Short/landscape mobile screens: topbar text truncates further, event
   selector never grows wider than the remaining space, avoiding overflow. */
@media (max-height: 480px) and (orientation: landscape) {
  .topbar { padding: 10px max(16px, env(safe-area-inset-right)) 10px max(16px, env(safe-area-inset-left)); flex-wrap: nowrap; }
  .topbar-title { font-size: 15px; max-width: 30vw; }
  .topbar-actions { flex-basis: auto; flex-wrap: nowrap; }
  .event-selector select { max-width: 34vw; }
  .theme-pill { padding: 5px 10px; font-size: 11px; }
  .main-area { padding-left: env(safe-area-inset-left); }
  .modal-overlay { align-items: center; padding: 10px; }
  .modal { max-height: 92vh; border-radius: 16px; }
  .login-wrap { align-items: center; padding-top: 16px; }
  .login-copyright { position: static; margin-top: 10px; }
}
/* ---- Tablet portrait range (721px-1100px): a bit more breathing room than
   phones but still needs a few of the same modal/grid adjustments ---- */
@media (min-width: 721px) and (max-width: 1024px) {
  .modal-lg { max-width: 90vw; }
  .booth-grid { grid-template-columns: repeat(auto-fill, minmax(76px, 1fr)); }
  .hall-card-grid { grid-template-columns: repeat(3, 1fr); }
}
.sidebar-backdrop {
  display: none;
  position: fixed; inset: 0; z-index: 100;
  background: rgba(15,20,35,0.35);
  backdrop-filter: blur(1px);
}

/* ===== Enhanced Booth Map: Zoom + Status Filter ===== */
.boothmap-zoom-wrapper {
  transform-origin: top left;
  transition: transform .25s cubic-bezier(.4,0,.2,1), margin .25s cubic-bezier(.4,0,.2,1);
}
.boothmap-viewport {
  width: 100%; overflow: auto; padding: 16px 8px 24px;
  display: flex; align-items: safe center; justify-content: safe center;
  background: var(--surface-alt); border-radius: 12px; margin-top: 8px;
  position: relative;
  height: calc(100vh - 200px);
  min-height: 480px;
}
.boothmap-floorplan { overflow: visible; padding: 0; }
.boothmap-floorplan-inner {
  display: inline-flex; flex-direction: column; gap: 12px; min-width: max-content;
}
/* Bigger, more spacious container */
.boothmap-hallzone {
  padding: 12px; min-width: 240px;
  border-radius: 14px; border-width: 2px;
}
.boothmap-hallzone-title {
  font-size: 13px; font-weight: 800; letter-spacing: .02em; color: var(--text);
  text-align: center; padding: 2px 8px 8px; text-transform: uppercase;
}
.boothmap-cell {
  --bm-w: 38px;
  --bm-h: 34px;
  font-size: 8.5px; border-radius: 0;
  border: 1px solid rgba(255,255,255,0.15);
  transition: transform .12s ease, box-shadow .12s ease, opacity .2s ease;
  flex-shrink: 0;
}
.boothmap-cell:hover { transform: translate(-50%, -50%) scale(1.4); z-index: 5; }
/* Status colors for confirmed & pending */
.boothmap-cell.confirmed { background: var(--blue-grad); }
.boothmap-cell.pending { background: linear-gradient(135deg,#fde047,#ca8a04); }

/* Multi-booth highlight (overrides status color) */
.boothmap-cell.multi-booth {
  background: linear-gradient(135deg, #ef4444, #dc2626) !important;
  color: #fff !important;
  box-shadow: 0 0 0 2px rgba(239,68,68,0.50), 0 3px 10px rgba(220,38,38,0.45);
}
.boothmap-cell.multi-booth:hover {
  background: linear-gradient(135deg, #f87171, #ef4444) !important;
}

/* Cells inside a same-company group */
.boothmap-cell.in-group {
  outline: 2px solid rgba(220,38,38,0.80);
  outline-offset: -1px;
}

/* Spanning company label that floats over the whole group bounding box */
.boothmap-group-label {
  position: absolute;
  pointer-events: none;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 9px;
  font-weight: 800;
  color: #fff;
  text-align: center;
  text-shadow: 0 1px 3px rgba(0,0,0,0.60);
  letter-spacing: 0.03em;
  border: 2px solid rgba(220,38,38,0.85);
  border-radius: 6px;
  background: rgba(220,38,38,0.20);
  backdrop-filter: blur(2px);
  padding: 2px 4px;
  line-height: 1.2;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
/* Hidden when filtered out */
.boothmap-cell.filtered-out { opacity: .1; transform: translate(-50%, -50%) scale(.85); pointer-events: none; }

/* Pill dot for filter buttons */
.pill-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }

/* Toolbar label */
.toolbar-label {
  font-size: 11px; font-weight: 700; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: .05em; margin-right: 4px;
}

/* Status pill color variants */
.pill-available.active { background: var(--green-grad); }
.pill-booked.active { background: var(--amber-grad); }
.pill-confirmed.active { background: var(--blue-grad); }
.pill-pending.active { background: linear-gradient(135deg,#fde047,#ca8a04); }

/* Legend count */
.boothmap-legend-count { font-size: 10px; color: var(--text-muted); margin-left: 2px; }

/* Zoom buttons */
.zoom-btn { transition: all .15s ease; }
.zoom-btn:hover { background: var(--surface-alt); color: var(--blue); }
.zoom-btn:active { transform: scale(.95); }

/* Ensure CSS gradient variables exist */
:root {
  --blue: #2563eb;
  --blue-grad: linear-gradient(135deg, #60a5fa, #2563eb);
  --gold-grad: linear-gradient(135deg, #fde047, #ca8a04);
  --gold: #ca8a04;
  --gold-light: #fef9c3;
}

/* Compact legend - no text labels, just dots and counts */
.boothmap-legend-compact {
  gap: 12px !important;
  flex-shrink: 0;
}
.boothmap-legend-compact .boothmap-legend-item {
  gap: 4px;
}
.boothmap-legend-compact .boothmap-legend-count {
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
}

/* Ensure booth cell text is centered */
.boothmap-cell {
  text-align: center;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Make booth text unselectable */
.boothmap-cell {
  user-select: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  cursor: pointer;
}

/* Drag-to-pan cursor states */
.boothmap-viewport {
  cursor: grab;
}
.boothmap-viewport.dragging {
  cursor: grabbing;
}
.boothmap-viewport.dragging .boothmap-cell {
  pointer-events: none;
}

/* ---- Admin "Move Booths" mode: dragging individual cells anywhere on the canvas ---- */
#boothmap-reorder-toggle.active {
  background: var(--primary); border-color: var(--primary); color: #fff;
}
.boothmap-content-editmode .boothmap-cell.boothmap-draggable {
  cursor: grab;
  box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.55);
  touch-action: none; /* let pointer events drive dragging instead of touch-scroll */
}
.boothmap-content-editmode .boothmap-cell.boothmap-draggable:hover {
  transform: translate(-50%, -50%) scale(1.15);
  outline: 2px dashed var(--accent);
  outline-offset: 2px;
}
.boothmap-cell.boothmap-cell-dragging {
  opacity: .75;
  cursor: grabbing;
  z-index: 8;
  outline: 2.5px solid var(--accent);
  outline-offset: 2px;
  transition: none; /* no lag while actively dragging */
}
.boothmap-editmode-hint {
  font-size: 11.5px; font-weight: 700; color: var(--primary-dark); background: var(--primary-light);
  border-radius: 8px; padding: 6px 12px; margin: 0 0 10px; display: inline-flex; align-items: center; gap: 6px;
}

/* ---- Admin "Place Booth" mode: click-to-build, like dropping pieces on a floor plan ---- */
#boothmap-place-toggle.active {
  background: var(--primary); border-color: var(--primary); color: #fff;
}
.boothmap-content-placemode .boothmap-canvas {
  cursor: copy;
}
.boothmap-content-placemode .boothmap-cell {
  cursor: default; /* clicking an existing cell in place-mode never places a new one */
}
.boothmap-place-popup {
  position: fixed;
  z-index: 999;
  background: var(--surface);
  border: 1.5px solid var(--border-strong);
  border-radius: 12px;
  box-shadow: var(--shadow-lg, 0 12px 32px rgba(0,0,0,.22));
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 200px;
}
.boothmap-place-popup-title {
  font-size: 12.5px; font-weight: 700; color: var(--text); margin-bottom: 2px;
}
.boothmap-place-popup label {
  display: flex; flex-direction: column; gap: 3px;
  font-size: 11px; font-weight: 600; color: var(--text-muted);
}
.boothmap-place-popup input {
  font-size: 13px; padding: 6px 8px; border-radius: 7px; border: 1.5px solid var(--border-strong); background: var(--surface);
}
.boothmap-place-popup-actions {
  display: flex; justify-content: flex-end; gap: 8px; margin-top: 4px;
}

/* ---- Stock panel: booths pulled off the floorplan via "Clear Floorplan", waiting to
   be picked back up. Pinned to the right edge -- pinning it to the left instead used to
   overlap the canvas legend and whichever booths sit near the top-left of the floor. ---- */
.boothmap-floating-stock {
  position: absolute;
  top: 16px;
  right: 16px;
  z-index: 58;
  max-height: calc(100% - 32px);
  width: 190px;
  display: flex;
  flex-direction: column;
  background: rgba(255,255,255,0.97);
  backdrop-filter: blur(6px);
  border: 1.5px solid var(--border-strong);
  border-radius: 12px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.16);
  overflow: hidden;
}
.boothmap-stock-header {
  font-size: 13px; font-weight: 800; color: var(--text);
  padding: 10px 12px 2px;
  display: flex; align-items: center; gap: 6px;
}
.boothmap-stock-count {
  background: var(--primary); color: #fff; border-radius: 999px;
  font-size: 11px; font-weight: 800; padding: 1px 8px; margin-left: auto;
}
.boothmap-stock-hint {
  font-size: 10.5px; color: var(--text-muted); padding: 2px 12px 8px; line-height: 1.35;
}
.boothmap-stock-list {
  overflow-y: auto;
  padding: 0 10px 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.boothmap-stock-chip {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 7px 10px;
  border-radius: 8px;
  border: 1.5px solid var(--border-strong);
  background: var(--surface-alt);
  font-size: 12px; font-weight: 700; color: var(--text);
  cursor: grab;
  transition: box-shadow .12s, border-color .12s;
}
.boothmap-stock-chip:hover {
  border-color: var(--primary);
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.boothmap-stock-chip.armed {
  border-color: var(--primary);
  background: var(--primary-light);
  outline: 2px dashed var(--primary);
  outline-offset: 1px;
}
.boothmap-stock-chip-size {
  font-size: 10.5px; font-weight: 600; color: var(--text-muted);
}
/* While a stock chip is armed (click-to-place fallback), clicking empty floor space
   places it -- signal that with the same "drop something here" cursor as dragging. */
.boothmap-stock-armed .boothmap-canvas {
  cursor: copy;
}

/* Tooltip extra info line */
.bmt-extra {
  font-size: 10px;
  font-weight: 600;
  color: var(--text-muted);
  margin-top: 2px;
  text-align: center;
}

/* Legend in its own row below toolbar - no overlap */
.boothmap-legend-row {
  display: flex;
  gap: 16px;
  align-items: center;
  padding: 6px 20px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  font-size: 12px;
  font-weight: 700;
  color: var(--text-muted);
  flex-wrap: nowrap;
}
.boothmap-legend-row .boothmap-legend-item {
  display: flex;
  align-items: center;
  gap: 5px;
  white-space: nowrap;
}
.boothmap-legend-row .boothmap-legend-count {
  font-size: 11px;
  font-weight: 700;
}

/* Floating legend inside floorplan viewport */
#boothmap-content { position: relative; }

/* Size/Country filter dropdowns in the toolbar */
.toolbar-select {
  height: 34px;
  padding: 0 10px;
  border: 1.5px solid var(--border-strong);
  border-radius: 8px;
  background: var(--surface);
  color: var(--text);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
}
.toolbar-select:hover { border-color: var(--primary); }

/* Floating zoom controls -- pinned to the bottom-right corner of the floorplan area
   itself (a child of #boothmap-content, which never scrolls), so they stay in place
   no matter how far the floor plan is panned or zoomed inside .boothmap-viewport. */
.boothmap-floating-zoom {
  position: absolute;
  bottom: 16px;
  right: 16px;
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 0;
  background: var(--surface);
  border: 1.5px solid var(--border-strong);
  border-radius: 10px;
  box-shadow: 0 4px 14px rgba(0,0,0,0.18);
  overflow: hidden;
}
.boothmap-floating-zoom .zoom-btn {
  width: 36px; height: 36px; border: none; border-right: 1px solid var(--border-strong);
  background: var(--surface); font-size: 18px; font-weight: 800; cursor: pointer;
  display: flex; align-items: center; justify-content: center; color: var(--text);
}
.boothmap-floating-zoom .zoom-btn:last-of-type { border-right: 1px solid var(--border-strong); }
.boothmap-floating-zoom .zoom-level-display {
  height: 36px; padding: 0 12px; display: flex; align-items: center; font-size: 12px;
  font-weight: 700; color: var(--text-muted); background: var(--surface-alt); min-width: 52px;
  justify-content: center;
}
@media (max-width: 720px) {
  .boothmap-floating-zoom { bottom: 10px; right: 10px; }
  .boothmap-floating-zoom .zoom-btn { height: 32px; width: 32px; font-size: 15px; }
  .boothmap-floating-zoom .zoom-level-display { height: 32px; min-width: 44px; font-size: 11px; padding: 0 8px; }
}
.boothmap-floating-legend {
  position: absolute;
  top: 16px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 55;
  display: flex;
  gap: 22px;
  align-items: center;
  padding: 12px 26px;
  background: rgba(255,255,255,0.95);
  backdrop-filter: blur(6px);
  border: 1.5px solid var(--border-strong);
  border-radius: 14px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.12);
  font-size: 16px;
  font-weight: 800;
  color: var(--text-muted);
  pointer-events: none;
}
.boothmap-floating-legend .boothmap-legend-item {
  display: flex;
  align-items: center;
  gap: 8px;
  white-space: nowrap;
}
.boothmap-floating-legend .boothmap-dot {
  width: 16px;
  height: 16px;
}
.boothmap-floating-legend .boothmap-legend-count {
  font-size: 16px;
  font-weight: 800;
  color: var(--text);
}
@media (max-width: 720px) {
  .boothmap-floating-legend {
    gap: 12px;
    padding: 8px 14px;
    font-size: 12px;
    top: 10px;
    max-width: calc(100% - 20px);
    flex-wrap: wrap;
    justify-content: center;
  }
  .boothmap-floating-legend .boothmap-dot { width: 11px; height: 11px; }
  .boothmap-floating-legend .boothmap-legend-count { font-size: 12px; }
}

/* ========== Embedded tool workspace (tools open in-app, no new tab) ========== */
.tool-embed-overlay {
  position: fixed; inset: 0; z-index: 400;
  display: flex; flex-direction: column;
  background: var(--bg); background-image: var(--bg-grad);
  background-size: 100% 100%; background-repeat: no-repeat; background-attachment: fixed;
}
.tool-embed-header {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 18px; flex-shrink: 0;
  background: var(--surface);
  backdrop-filter: blur(var(--glass-blur)); -webkit-backdrop-filter: blur(var(--glass-blur));
  border-bottom: 1.5px solid var(--border);
  box-shadow: var(--shadow-xs);
}
.tool-embed-title { font-weight: 800; font-size: 14.5px; color: var(--text); letter-spacing: -0.01em; }
.tool-embed-overlay iframe {
  flex: 1 1 auto; width: 100%; border: none; background: transparent;
}
.tool-card-link { cursor: pointer; transition: transform .15s ease, box-shadow .15s ease; }
.tool-card-link:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }

/* ========== Booth Map: CorelDraw-style smart guides + selection ========== */
/* Magnetic alignment lines drawn while dragging a booth near a neighbor (or the
   canvas centre). Canvas-local pixels, so they scale with zoom automatically. */
.boothmap-guide {
  position: absolute;
  background: #ff2e88;
  box-shadow: 0 0 5px rgba(255, 46, 136, .65);
  z-index: 46;
  pointer-events: none;
}
.boothmap-guide.v { top: 0; width: 1.5px; height: 100%; }
.boothmap-guide.h { left: 0; height: 1.5px; width: 100%; }

/* The booth being snapped to flashes a dashed halo -- like CorelDraw highlighting
   the source object of a dynamic guide. */
.boothmap-cell.snapped-to {
  outline: 2.5px dashed #ff2e88;
  outline-offset: 1.5px;
  transform: translate(-50%, -50%) scale(1.18);
  z-index: 6;
}

/* Arrow-key nudge selection (click a booth in edit mode, then cursor keys move it). */
.boothmap-cell.boothmap-selected {
  outline: 2.5px solid var(--accent);
  outline-offset: 2px;
  box-shadow: 0 0 0 5px rgba(20, 184, 221, .18);
  z-index: 6;
}
.boothmap-cell.boothmap-selected::after {
  content: '';
  position: absolute;
  inset: -7px;
  border-radius: 7px;
  border: 1px dashed rgba(20, 184, 221, .55);
  animation: toolpulse 1.6s infinite;
  pointer-events: none;
}

/* ========== Booth Map: grouping, rubber-band multi-select, selection toolbar ========== */
/* Rubber-band marquee drawn while sweeping empty floor to multi-select booths. */
.boothmap-marquee {
  position: absolute;
  border: 1.5px dashed var(--accent);
  background: rgba(20, 184, 221, .12);
  z-index: 47;
  pointer-events: none;
  border-radius: 3px;
}
/* Booths currently caught inside the rubber band (live preview of the selection). */
.boothmap-cell.boothmap-band-hover {
  outline: 2.5px dashed var(--accent);
  outline-offset: 1px;
  transform: translate(-50%, -50%) scale(1.12);
  z-index: 6;
}

/* Persistent group membership: every member carries a ring + corner dot in its
   group's hue, so you can see at a glance which booths travel together. */
.boothmap-cell.boothmap-grouped {
  box-shadow: 0 0 0 2.5px hsl(var(--bm-group-hue, 262) 85% 60% / .95),
              0 0 8px hsl(var(--bm-group-hue, 262) 85% 60% / .45);
}
.boothmap-cell.boothmap-grouped::before {
  content: '';
  position: absolute;
  top: -5px; left: -5px;
  width: 9px; height: 9px;
  border-radius: 3px;
  background: hsl(var(--bm-group-hue, 262) 85% 55%);
  box-shadow: 0 1px 3px rgba(0,0,0,.35);
  pointer-events: none;
}

/* Floating selection toolbar (group / ungroup / clear), pinned top-left of
   #boothmap-content -- the free corner next to legend (top-center) and stock
   (top-right). Same "child of #boothmap-content" trick so canvas zoom ignores it. */
.boothmap-group-toolbar {
  position: absolute;
  top: 16px; left: 16px;
  z-index: 58;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 7px 10px;
  background: rgba(255,255,255,0.97);
  backdrop-filter: blur(6px);
  border: 1.5px solid var(--border-strong);
  border-radius: 12px;
  box-shadow: var(--shadow-md);
}
html[data-theme="dark"] .boothmap-group-toolbar { background: rgba(30,34,44,0.95); }
.bmgt-count { font-size: 12px; font-weight: 800; color: var(--text); white-space: nowrap; padding: 0 3px; }
.bmgt-btn {
  border: 1.5px solid var(--border-strong);
  background: var(--surface-alt-solid);
  color: var(--text);
  border-radius: 8px;
  font-size: 11.5px;
  font-weight: 800;
  padding: 5px 10px;
  cursor: pointer;
  font-family: inherit;
  white-space: nowrap;
}
.bmgt-btn:hover:not(:disabled) { border-color: var(--primary); color: var(--primary-dark); }
.bmgt-btn:disabled { opacity: .4; cursor: not-allowed; }
.bmgt-x { padding: 5px 8px; }

/* ---- All-Halls overview = exact proportional thumbnails of the focused map ----
   Booth positions are stored as % of their hall canvas, so the overview previously
   re-projected them onto a SMALLER canvas (1100x760, 38px cells vs the focused
   2200x1300, 56px cells) -- the same layout then resolved to different gaps, and the
   per-canvas auto-grow shoved rows apart ("booths became separated in overview").
   Render overview canvases at the SAME natural size/cell size as the focused view and
   CSS-scale the whole canvas down to the hall column instead; geometry stays
   pixel-identical to the focused hall map. boothmapFitOverviewThumbs() (JS) sets the
   scale + reserves the correct box height. Pointer handlers use the live render-box
   ratio (see boothmapLocalFromClient), so dragging in a thumbnail still lands right. */
.boothmap-hall-rows .boothmap-canvas {
  width: 2200px; height: 1300px;
  transform-origin: top left;
  flex-shrink: 0;
}
.boothmap-hall-rows .boothmap-cell {
  --bm-w: 56px; --bm-h: 48px;
  font-size: 10px; border-radius: 0;
}
.boothmap-hall-rows { overflow: hidden; flex-shrink: 0; }

/* ==========================================================================
   v23 (4.11) Payment group headers + Per-Event termin breakdown
   ========================================================================== */
.pe-evt-group-head { display:flex; align-items:baseline; gap:8px; margin:12px 0 6px; }
.pe-evt-group-name { font-weight:800; font-size:12.5px; color:var(--text); }
.pe-evt-group-count { font-size:11px; font-weight:700; color:var(--text-faint); }

.pe-section-title {
  font-weight:800; font-size:12.5px; color:var(--text); margin-bottom:8px;
}
.pe-event-card {
  border:1px solid var(--border-strong); border-radius:var(--radius-sm);
  background:var(--surface-alt); margin-bottom:10px; overflow:hidden;
}
.pe-event-head {
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  padding:9px 13px; background:var(--surface-hover);
  border-bottom:1px solid var(--border);
}
.pe-event-name { font-weight:800; font-size:13px; color:var(--text); }
.pe-event-meta { font-size:11px; font-weight:600; color:var(--text-muted); }
.pe-flag { font-size:10.5px; font-weight:800; padding:2px 8px; border-radius:999px; }
.pe-flag-red { color:var(--red); background:var(--red-light); }
.pe-flag-amber { color:var(--amber); background:var(--amber-light); }
.pe-termin-list { padding:4px 0; }
.pe-termin-row {
  display:flex; align-items:center; gap:8px 14px; flex-wrap:wrap;
  padding:6px 13px; font-size:12px;
}
.pe-termin-row + .pe-termin-row { border-top:1px dashed var(--border); }
.pe-termin-badge {
  display:inline-flex; align-items:center; justify-content:center;
  min-width:32px; height:20px; padding:0 6px; border-radius:6px;
  background:var(--accent-light); color:var(--accent);
  font-weight:800; font-size:11px;
}
.pe-termin-exh { font-weight:700; color:var(--text); min-width:80px; }
.pe-termin-paid { font-weight:600; color:var(--text-muted); }
.pe-termin-paid.complete { color:var(--primary-dark); font-weight:800; }
.pe-termin-money { font-weight:600; color:var(--text-muted); font-size:11.5px; }
.pe-termin-progress { display:inline-flex; align-items:center; gap:6px; margin-left:auto; }
.pe-bar {
  width:110px; height:7px; border-radius:99px; background:var(--border);
  overflow:hidden; display:inline-block;
}
.pe-bar-fill { display:block; height:100%; border-radius:99px; background:var(--green-grad); }
.pe-bar-label { font-size:10.5px; font-weight:800; color:var(--text-muted); min-width:30px; }
.pe-empty { padding:8px 13px; font-size:12px; color:var(--text-faint); }
@media (max-width:720px) {
  .pe-termin-progress { margin-left:0; }
  .pe-bar { width:80px; }
}

/* ==========================================================================
   Per-Hall Report — clean professional table
   ========================================================================== */
#dashboard-hall-report-table {
  min-width: 860px;
  border-collapse: collapse;
}

/* Group header row */
#dashboard-hall-report-table .hrp-group-row th {
  padding: 8px 12px;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  background: var(--surface-alt);
  border-bottom: 1px solid var(--border);
  text-align: center;
  position: static;
  vertical-align: middle;
}

/* Sub-header row */
#dashboard-hall-report-table .hrp-sub-row th {
  padding: 6px 10px;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--text-faint);
  background: var(--surface-alt);
  border-bottom: 2px solid var(--border-strong);
  text-transform: none;
  letter-spacing: 0;
  position: static;
}

/* Data cells */
#dashboard-hall-report-table td {
  padding: 8px 10px;
  font-size: 12.5px;
  white-space: nowrap;
  border-bottom: 1px solid var(--border);
  background: transparent;
  text-align: center;
  vertical-align: middle;
}

/* Hall name cell */
#dashboard-hall-report-table td:first-child {
  text-align: left;
  font-weight: 700;
  font-size: 13px;
  color: var(--text);
  padding-left: 14px;
}

/* Hover */
#dashboard-hall-report-table tbody tr:hover td {
  background: var(--surface-hover);
}

/* Column group dividers */
#dashboard-hall-report-table td.hrp-booth:first-of-type,
#dashboard-hall-report-table th.hrp-booth:first-of-type { border-left: 1px solid var(--border-strong); }
#dashboard-hall-report-table td.hrp-exh:first-of-type,
#dashboard-hall-report-table th.hrp-exh:first-of-type { border-left: 1px solid var(--border-strong); }

/* Totals row */
#dashboard-hall-report-table .hall-report-total-row td {
  font-weight: 800;
  font-size: 13px;
  background: var(--surface-alt) !important;
  border-top: 2px solid var(--border-strong);
  border-bottom: none;
}
html[data-theme="dark"] #dashboard-hall-report-table .hall-report-total-row td {
  background: rgba(255,255,255,0.04) !important;
}

/* ==========================================================================
   v24 (4.12) Dashboard report cleanup: "Stand Blocked" mini-card removed, so the
   stand-status row is a 3-up grid; Per-Hall Report no longer has blocked columns
   and its "Avail" sub-headers read "Available" (no 🟩 glyph).
   ========================================================================== */
#stand-status-cards { grid-template-columns: repeat(3, 1fr); }


/* ==========================================================================
   v25 (4.13) "GRAINIENT LIGHT" theme refresh
   Design reference: grainient.supply -- light-mode, paper-white canvases with big
   soft sky/azure/cyan mesh-gradient glows and that signature FILM GRAIN overlay.
   Strategy: the entire app was already token-driven, so this late-loading block
   re-declares the :root palette (later rule wins at equal specificity), paints a
   global feTurbulence grain layer, and re-skins the three fixed identity chrome
   pieces (login backdrop, sidebar gradient, CTA glow). Dark theme block above is
   deliberately untouched -- the toggle still works.
   ========================================================================== */
:root {
  /* Ambient canvas: paper white with layered sky/azure/ice glows (+ a faint peach
     warmth bleeding up from the bottom, echoing the warm CTA) */
  --bg: #f1f6fc;
  --bg-grad:
    radial-gradient(44% 52% at 4% -8%, rgba(186,223,255,0.78) 0%, rgba(186,223,255,0) 62%),
    radial-gradient(40% 46% at 102% -4%, rgba(165,243,252,0.66) 0%, rgba(165,243,252,0) 60%),
    radial-gradient(38% 44% at -6% 76%, rgba(147,197,253,0.55) 0%, rgba(147,197,253,0) 62%),
    radial-gradient(42% 46% at 104% 96%, rgba(125,211,252,0.55) 0%, rgba(125,211,252,0) 60%),
    radial-gradient(28% 30% at 72% -12%, rgba(216,180,254,0.34) 0%, rgba(216,180,254,0) 62%),
    radial-gradient(36% 38% at 46% 112%, rgba(254,215,170,0.42) 0%, rgba(254,215,170,0) 64%),
    linear-gradient(180deg, #fbfdff 0%, #eef4fb 44%, #f7fafd 100%);

  --surface: rgba(255, 255, 255, 0.62);
  --surface-alt: rgba(246, 250, 255, 0.55);
  --surface-hover: rgba(233, 242, 253, 0.78);
  --surface-solid: #ffffff;
  --surface-alt-solid: #f3f8fe;
  --border: rgba(205, 218, 243, 0.72);
  --border-strong: rgba(186, 203, 238, 0.90);

  --text: #172441;
  --text-muted: #5c6b90;
  --text-faint: #95a3c2;

  /* Azure -> sky -> ice gradient (takes the previous emerald primary's job) */
  --primary: #3a86ff;
  --primary-dark: #1e63d8;
  --primary-light: #e0edff;
  --primary-grad: linear-gradient(135deg, #3a86ff 0%, #38bdf8 58%, #7dd3fc 100%);

  /* Warm peach-coral stays THE call-to-action signature */
  --brass: #ff7e5f;
  --brass-dark: #e25c3d;
  --brass-light: #ffe9df;
  --brass-grad: linear-gradient(135deg, #ff7e5f 0%, #ffb36b 55%, #ffd68d 100%);

  --accent: #0ea5e9;
  --accent-light: #def4fd;

  --green: #1da87a;
  --green-light: #dcf5ec;
  --green-grad: linear-gradient(135deg, #1da87a, #3ed3a2);

  --amber: #e8850f;
  --amber-light: #fdeeda;

  --red: #ef3f6e;
  --red-light: #fdeaef;

  --purple: #7079e8;
  --purple-light: #e9ebfe;

  --shadow-xs: 0 1px 0 rgba(23, 45, 96, 0.06);
  --shadow-sm: 0 1px 0 rgba(23, 45, 96, 0.10);
  --shadow-md: 0 2px 0 rgba(23, 45, 96, 0.14);
  --shadow-lg: 0 3px 0 rgba(23, 45, 96, 0.18);
  --shadow-glow: 0 8px 26px rgba(255, 126, 95, 0.35);

  /* Sidebar chrome: deep lawn green + gold accent */
  --sidebar-bg: linear-gradient(165deg,
    rgba(22,110,10,0.98) 0%,
    rgba(30,130,14,0.97) 40%,
    rgba(18,100,8,0.98) 72%,
    rgba(10,72,4,0.99) 100%);
  --sidebar-active-bg: rgba(255, 210, 80, 0.18);
  --sidebar-active-text: #ffe97a;
}

/* --- The grainient signature: fixed film-grain layer over the whole app ------- */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 2147483400;
  pointer-events: none;
  opacity: 0.055;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23g)'/%3E%3C/svg%3E");
  background-size: 180px 180px;
}
html[data-theme="dark"] body::after { opacity: 0.045; mix-blend-mode: screen; }

/* --- Login: same mesh-gradient + floating orbs, retuned to sky/azure ---------- */
.login-wrap {
  background:
    radial-gradient(46% 58% at 12% -6%, rgba(185,222,255,0.85) 0%, rgba(185,222,255,0) 62%),
    radial-gradient(42% 52% at 96% 4%, rgba(164,243,252,0.80) 0%, rgba(164,243,252,0) 62%),
    radial-gradient(40% 50% at -4% 94%, rgba(147,197,253,0.62) 0%, rgba(147,197,253,0) 62%),
    radial-gradient(44% 52% at 100% 100%, rgba(125,211,252,0.60) 0%, rgba(125,211,252,0) 60%),
    radial-gradient(26% 30% at 78% 12%, rgba(216,180,254,0.42) 0%, rgba(216,180,254,0) 62%),
    radial-gradient(30% 34% at 30% 106%, rgba(254,215,170,0.45) 0%, rgba(254,215,170,0) 64%),
    linear-gradient(168deg, #fcfeff 0%, #eef4fb 50%, #f8fbfe 100%);
}
.shape-1 { background: radial-gradient(circle, #a5c8f8, transparent 70%); }
.shape-2 { background: radial-gradient(circle, #ffd0a8, transparent 70%); }
.shape-3 { background: radial-gradient(circle, #9ee6f5, transparent 70%); }
.login-card {
  background: rgba(255, 255, 255, 0.78);
  box-shadow:
    0 1px 0 rgba(255,255,255,0.92) inset,
    0 32px 80px -16px rgba(54,122,233,0.22),
    0 10px 30px rgba(23,45,96,0.08);
}

/* --- Small hardware polish: warm CTA hover glow + palette-matched scrollbars --- */
.btn-primary:hover { box-shadow: 0 10px 30px rgba(255,126,95,0.42); }
::-webkit-scrollbar-thumb { background: #c7d5ef; }
::-webkit-scrollbar-thumb:hover { background: #a9bce0; }


/* ==========================================================================
   v26 (4.14) "LIQUID GLASS" (iPhone-style) treatment + theme-aware sidebar
   1) Light theme gets the iOS "Liquid Glass" physics: deeper frost blur, a
      specular top highlight + inner refraction ring on every glass pane, a soft
      top->bottom sheen, and larger squircle radii across all surfaces.
   2) The sidebar is no longer one fixed bright gradient in both themes: it now
      FOLLOWS the theme -- bright azure->cyan in light, deep navy->petrol glass in
      dark (per request: "when change to dark theme i want left sidebar change
      colour too").
   ========================================================================== */
:root {
  /* deeper frost + more translucency = real Liquid Glass */
  --glass-blur: 6px;
  --surface: rgba(255, 255, 255, 0.92);
  --surface-alt: rgba(246, 250, 255, 0.90);
  --surface-hover: rgba(233, 242, 253, 0.95);
  /* specular edge: bright top highlight + faint all-round refraction ring */
  --glass-edge: inset 0 1px 0 rgba(255, 255, 255, 0.95), inset 0 0 0 1px rgba(255, 255, 255, 0.30);
  /* bigger squircle radii across the whole app */
  --radius: 22px;
  --radius-sm: 14px;
  --radius-lg: 28px;
}

/* Soft internal sheen on every pane: bright at the top (light source),
   evaporating toward the middle, faint reflective lift at the very bottom. */
.card, .stat-card, .mini-stat {
  background-image: linear-gradient(180deg,
    rgba(255, 255, 255, 0.55) 0%,
    rgba(255, 255, 255, 0.10) 38%,
    rgba(255, 255, 255, 0.20) 100%);
}

.sidebar, .topbar {
  backdrop-filter: blur(48px) saturate(200%) brightness(1.05);
  -webkit-backdrop-filter: blur(48px) saturate(200%) brightness(1.05);
}

/* Sidebar liquid sheen (diagonal light sweep), behind content (children z-index 1). */
.sidebar::before {
  content: "";
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(128deg,
    rgba(255, 255, 255, 0.13) 0%,
    rgba(255, 255, 255, 0.02) 30%,
    rgba(180, 255, 140, 0.03) 60%,
    rgba(255, 255, 255, 0.06) 85%,
    rgba(255, 255, 255, 0.00) 100%);
}

.btn-primary {
  box-shadow: var(--shadow-glow),
    inset 0 1px 0 rgba(255, 255, 255, 0.55),
    inset 0 -1px 0 rgba(140, 60, 20, 0.16);
}
.btn-secondary, .theme-pill {
  box-shadow: var(--shadow-xs), inset 0 1px 0 rgba(255, 255, 255, 0.90);
}
.login-card {
  background-image: linear-gradient(180deg,
    rgba(255, 255, 255, 0.65) 0%,
    rgba(255, 255, 255, 0.18) 40%,
    rgba(255, 255, 255, 0.30) 100%);
}

/* ================= DARK THEME: sidebar follows the theme =================== */
html[data-theme="dark"] {
  --sidebar-bg: linear-gradient(165deg,
    rgba(16, 26, 54, 0.97) 0%,
    rgba(18, 34, 72, 0.96) 45%,
    rgba(12, 58, 86, 0.96) 100%);
  --sidebar-active-bg: rgba(255, 158, 120, 0.22);
  --sidebar-active-text: #ffd9c4;
  --glass-edge: inset 0 1px 0 rgba(255, 255, 255, 0.16), inset 0 0 0 1px rgba(255, 255, 255, 0.06);
}
html[data-theme="dark"] .sidebar { border-right-color: rgba(120, 160, 255, 0.14); box-shadow: none; }
html[data-theme="dark"] .card, html[data-theme="dark"] .stat-card, html[data-theme="dark"] .mini-stat {
  background-image: linear-gradient(180deg,
    rgba(255, 255, 255, 0.10) 0%,
    rgba(255, 255, 255, 0.02) 38%,
    rgba(255, 255, 255, 0.05) 100%);
}
html[data-theme="dark"] .btn-secondary, html[data-theme="dark"] .theme-pill {
  box-shadow: var(--shadow-xs), inset 0 1px 0 rgba(255, 255, 255, 0.14);
}


/* ==========================================================================
   v29: Payment Reminders (wa.me) + Sales Analytics + Exhibitor Badges
   Liquid-Glass-consistent: translucent tints, soft radii, theme variables.
   ========================================================================== */

/* ---- Reminders: KPI strip ---- */
.rem-kpi-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(210px,1fr)); gap:14px; margin-bottom:18px; }
.rem-kpi { display:flex; gap:12px; align-items:center; justify-content:center; text-align:center; padding:16px 18px; border-radius:var(--radius-lg);
  background:linear-gradient(180deg, rgba(255,255,255,.5), rgba(255,255,255,.16));
  border:1px solid var(--border); box-shadow:var(--glass-edge), 0 10px 24px -14px rgba(30,60,110,.18); }
html[data-theme="dark"] .rem-kpi { background:linear-gradient(180deg, rgba(255,255,255,.09), rgba(255,255,255,.03)); }
.rem-kpi-icon { font-size:20px; width:40px; height:40px; flex:0 0 40px; display:flex; align-items:center; justify-content:center; border-radius:12px; background:rgba(255,255,255,.65); box-shadow:var(--glass-edge); }
html[data-theme="dark"] .rem-kpi-icon { background:rgba(255,255,255,.08); }
.rem-kpi-value { font-size:24px; font-weight:800; line-height:1.1; }
.rem-kpi-label { font-size:12px; font-weight:700; color:var(--text-muted); margin-top:2px; }
.rem-kpi-money { font-size:11.5px; font-weight:800; margin-top:5px; }
.rem-kpi-red .rem-kpi-value, .rem-kpi-red .rem-kpi-money { color:var(--red); }
.rem-kpi-amber .rem-kpi-value, .rem-kpi-amber .rem-kpi-money { color:var(--amber); }
.rem-kpi-yellow .rem-kpi-value, .rem-kpi-yellow .rem-kpi-money { color:#b8860b; }
html[data-theme="dark"] .rem-kpi-yellow .rem-kpi-value, html[data-theme="dark"] .rem-kpi-yellow .rem-kpi-money { color:var(--gold-light, #ffd479); }
.rem-kpi-neutral .rem-kpi-value, .rem-kpi-neutral .rem-kpi-money { color:var(--text-muted); }

/* ---- Reminders: aging bars ---- */
.rem-aging-row { display:grid; grid-template-columns:170px 1fr auto; gap:12px; align-items:center; padding:7px 0; }
.rem-aging-label { font-size:12.5px; font-weight:700; }
.rem-aging-track { height:14px; border-radius:99px; background:rgba(120,140,180,.14); overflow:hidden; box-shadow:inset 0 1px 3px rgba(30,60,110,.10); }
.rem-aging-fill { height:100%; border-radius:99px; transition:width .4s ease; box-shadow:inset 0 1px 0 rgba(255,255,255,.45); }
.rem-aging-num { font-size:12.5px; color:var(--text-muted); white-space:nowrap; }
.rem-aging-money { font-weight:800; color:var(--text); margin-left:4px; }

/* ---- Reminders: filter chips + status + WA buttons ---- */
.rem-filter-bar { display:flex; gap:8px; flex-wrap:wrap; align-items:center; padding:14px 16px; border-bottom:1px solid var(--border); }
.rem-chip { border:1px solid var(--border); background:rgba(255,255,255,.35); color:var(--text-muted);
  font-size:12px; font-weight:800; padding:7px 13px; border-radius:99px; cursor:pointer; transition:all .15s; box-shadow:var(--glass-edge); }
html[data-theme="dark"] .rem-chip { background:rgba(255,255,255,.06); }
.rem-chip:hover { transform:translateY(-1px); color:var(--text); }
.rem-chip.active { background:var(--primary-grad); color:#fff; border-color:transparent; box-shadow:0 6px 16px -6px rgba(58,134,255,.55); }
.termin-chip { display:inline-block; min-width:26px; text-align:center; padding:2px 8px; border-radius:8px; font-size:11.5px; font-weight:800;
  background:rgba(58,134,255,.12); color:var(--primary-dark); }
html[data-theme="dark"] .termin-chip { color:var(--primary-light); }
.rem-status { display:inline-block; padding:3px 10px; border-radius:99px; font-size:11.5px; font-weight:800; white-space:nowrap; }
.rem-st-overdue { background:var(--red-light); color:var(--red); }
.rem-st-today { background:var(--amber-light); color:var(--amber); }
.rem-st-soon { background:var(--amber-light); color:#b8860b; }
.rem-st-later30 { background:rgba(244,183,64,.16); color:#b8860b; }
.rem-st-none { background:rgba(120,140,180,.14); color:var(--text-muted); }
html[data-theme="dark"] .rem-st-soon, html[data-theme="dark"] .rem-st-later30 { color:var(--gold-light, #ffd479); }
.wa-btn { border:none; cursor:pointer; font-size:11.5px; font-weight:800; padding:7px 12px; border-radius:10px;
  background:linear-gradient(135deg,#25d366,#1ebe5b); color:#fff; box-shadow:0 6px 14px -6px rgba(37,211,102,.6), inset 0 1px 0 rgba(255,255,255,.4); transition:transform .12s; }
.wa-btn:hover { transform:translateY(-1px); }
.wa-copy { margin-left:6px; }
.wa-none { font-size:11px; color:var(--text-faint); font-weight:700; }

/* ---- Analytics: collapsible payment-method / Top companies accordion ---- */
.ana-accordion { display: flex; flex-direction: column; gap: 12px; margin-top: 16px; }
.ana-accordion-item {
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}
.ana-accordion-header {
  width: 100%;
  display: grid;
  grid-template-columns: 20px 1fr 20px;
  align-items: center;
  gap: 10px;
  padding: 16px 20px;
  background: none;
  border: none;
  cursor: pointer;
  font: inherit;
  font-weight: 800;
  font-size: 16px;
  color: var(--text);
  text-align: center;
}
.ana-accordion-header span:first-child { grid-column: 2; }
.ana-accordion-header:hover { background: var(--surface-alt); }
.ana-accordion-arrow {
  grid-column: 3;
  font-size: 13px;
  color: var(--text-muted);
  transition: transform 0.2s ease;
}
.ana-accordion-item.open .ana-accordion-arrow { transform: rotate(90deg); }
.ana-accordion-body {
  display: none;
  padding: 0 20px 18px;
  border-top: 1.5px solid var(--border);
}
.ana-accordion-item.open .ana-accordion-body { display: block; padding-top: 14px; }
.ana-accordion-list { display: flex; flex-direction: column; gap: 10px; }
.ana-accordion-row {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: 14px;
  align-items: center;
  padding: 10px 12px;
  border-radius: 10px;
  background: var(--surface-alt);
}
.ana-accordion-company { font-weight: 700; font-size: 13.5px; color: var(--text); }
.ana-accordion-meta { display: block; font-weight: 600; font-size: 11.5px; color: var(--text-muted); margin-top: 2px; }
.ana-accordion-amount { font-weight: 800; font-size: 13.5px; color: var(--text); white-space: nowrap; text-align: right; }
.ana-accordion-amount .ana-accordion-meta { text-align: right; }
.ana-accordion-date { font-weight: 600; font-size: 12px; color: var(--text-muted); white-space: nowrap; }

/* ---- Analytics ---- */
/* 5 equal columns so Collections/Termin/Payment methods/Additional Orders/Lunchbox
   Orders sit in one uniform row (same sizing approach as .ana-kpi-row above it);
   Top companies (.ana-card-wide) spans the full row underneath. */
.ana-grid { display:grid; grid-template-columns:repeat(5, 1fr); gap:16px; }
.ana-card { padding:20px; min-width:0; }
.ana-card-wide { grid-column:1 / -1; }
@media (max-width: 1200px) {
  .ana-grid { grid-template-columns:repeat(3, 1fr); }
}
@media (max-width: 900px) {
  .ana-grid { grid-template-columns:repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .ana-grid { grid-template-columns:1fr; }
}
.ana-title { margin:0 0 14px; font-size:15px; }
.ana-sub { margin:0 0 14px; font-size:12.5px; color:var(--text-muted); }
.ana-svg { display:block; overflow:visible; }
.ana-gridline { stroke:var(--border); stroke-width:1; }
.ana-tick { font-size:13px; fill:var(--text-muted); font-weight:700; }
.ana-val { font-weight:800; fill:var(--text); font-size:13.5px; }
.ana-donut-num { font-size:26px; font-weight:800; fill:var(--text); }
.ana-legend { display:flex; flex-wrap:wrap; gap:6px 16px; margin-top:10px; }
.ana-legend-col { flex-direction:column; gap:8px; margin-top:0; justify-content:center; }
.ana-legend-item { display:inline-flex; align-items:center; gap:7px; font-size:12px; color:var(--text-muted); font-weight:700; }
.ana-dot { width:10px; height:10px; border-radius:4px; display:inline-block; box-shadow:inset 0 1px 0 rgba(255,255,255,.45); }
.ana-donut-wrap { display:flex; gap:18px; align-items:center; flex-wrap:wrap; }
.ana-donut-wrap .ana-svg { flex:0 0 200px; }
.ana-lock { padding:30px 18px; text-align:center; font-size:13px; font-weight:700; color:var(--text-muted);
  border:1.5px dashed var(--border); border-radius:var(--radius); background:rgba(120,140,180,.06); }

/* funnel */
.ana-funnel-row { display:grid; grid-template-columns:76px 1fr 120px; gap:10px; align-items:center; padding:7px 0; grid-template-areas:"label track num" "label money money"; }
.ana-funnel-label { grid-area:label; font-size:12px; font-weight:800; color:var(--text-muted); }
.ana-funnel-track { grid-area:track; position:relative; height:16px; }
.ana-funnel-ghost { position:absolute; left:0; top:0; height:100%; border-radius:99px; background:rgba(58,134,255,.14); }
.ana-funnel-fill { position:absolute; left:0; top:0; height:100%; border-radius:99px; background:var(--primary-grad);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.5), 0 4px 10px -4px rgba(58,134,255,.5); z-index:1; transition:width .4s ease; }
.ana-funnel-num { grid-area:num; font-size:12px; color:var(--text-muted); white-space:nowrap; }
.ana-funnel-money { grid-area:money; font-size:11.5px; font-weight:800; margin-top:1px; }

/* top exhibitors */
.ana-top-row { display:grid; grid-template-columns:30px 1fr auto; gap:12px; align-items:center; padding:8px 0; border-bottom:1px dashed var(--border); }
.ana-top-row:last-child { border-bottom:none; }
.ana-top-rank { width:26px; height:26px; border-radius:9px; display:flex; align-items:center; justify-content:center;
  font-size:12px; font-weight:800; background:rgba(58,134,255,.12); color:var(--primary-dark); }
html[data-theme="dark"] .ana-top-rank { color:var(--primary-light); }
.ana-top-name { font-size:13px; font-weight:800; margin-bottom:5px; }
.ana-top-meta { font-size:11px; color:var(--text-muted); font-weight:600; }
.ana-top-track { position:relative; height:12px; }
.ana-top-fill { position:absolute; left:0; top:0; height:100%; border-radius:99px; background:rgba(58,134,255,.18); }
.ana-top-paid { position:absolute; left:0; top:0; height:100%; border-radius:99px; background:var(--primary-grad); box-shadow:inset 0 1px 0 rgba(255,255,255,.5); z-index:1; }
.ana-top-val { font-size:12.5px; font-weight:800; text-align:right; white-space:nowrap; }

/* ---- Badges ---- */
.badge-controls { padding:16px 20px; margin-bottom:16px; }
.badge-sheet { display:grid; grid-template-columns:repeat(auto-fill,minmax(300px,1fr)); gap:16px; }
.badge-card { position:relative; cursor:pointer; transition:transform .15s, opacity .15s; }
.badge-card:hover { transform:translateY(-2px); }
.badge-card.badge-off { opacity:.45; }
.badge-check { position:absolute; top:10px; right:10px; z-index:3; width:18px; height:18px; accent-color:var(--primary); }
.badge-inner { width:100%; max-width:340px; margin:0 auto; border-radius:20px; overflow:hidden;
  background:linear-gradient(175deg, rgba(255,255,255,.78), rgba(255,255,255,.38));
  border:1px solid var(--border); box-shadow:var(--glass-edge), 0 16px 34px -18px rgba(30,60,110,.30);
  display:flex; flex-direction:column; align-items:center; padding-bottom:14px; }
html[data-theme="dark"] .badge-inner { background:linear-gradient(175deg, rgba(30,42,70,.9), rgba(20,30,54,.75)); }
.badge-head { width:100%; display:flex; justify-content:space-between; align-items:center; gap:8px;
  padding:10px 14px; background:var(--primary-grad); color:#fff; }
.badge-event { font-size:10.5px; font-weight:800; letter-spacing:.4px; text-transform:uppercase; line-height:1.3; }
.badge-brand { font-size:10.5px; font-weight:900; letter-spacing:1.5px; padding:3px 8px; border-radius:8px;
  background:rgba(255,255,255,.22); box-shadow:inset 0 1px 0 rgba(255,255,255,.5); flex:0 0 auto; }
.badge-co { margin-top:16px; padding:0 14px; font-size:19px; font-weight:900; text-align:center; line-height:1.25; min-height:48px; display:flex; align-items:center; }
.badge-contact { font-size:12px; color:var(--text-muted); font-weight:700; margin-top:6px; display:flex; gap:6px; align-items:center; flex-wrap:wrap; justify-content:center; padding:0 12px; }
.badge-tag { font-size:10px; font-weight:800; padding:2px 8px; border-radius:99px; background:rgba(34,193,163,.14); color:#0f8a72; }
.badge-tag-int { background:rgba(160,107,255,.16); color:#7a4fd0; }
html[data-theme="dark"] .badge-tag { color:#5fe3c6; }
html[data-theme="dark"] .badge-tag-int { color:#c9b0ff; }
.badge-booth-row { display:flex; gap:8px; flex-wrap:wrap; justify-content:center; margin-top:12px; }
.badge-booth { font-size:20px; font-weight:900; letter-spacing:.5px; padding:6px 14px; border-radius:12px;
  background:var(--amber-grad); color:#3d2b00; box-shadow:0 6px 14px -6px rgba(244,183,64,.55), inset 0 1px 0 rgba(255,255,255,.55); }
.badge-qr { margin-top:14px; width:110px; height:110px; padding:8px; border-radius:14px; background:#fff;
  box-shadow:0 4px 12px -6px rgba(30,60,110,.25), inset 0 0 0 1px rgba(30,60,110,.08); }
.badge-qr svg { width:100%; height:100%; display:block; }
.badge-foot { margin-top:10px; font-size:10.5px; color:var(--text-faint); font-weight:700; letter-spacing:.3px; }

/* Badge printing: hide the whole app chrome, lay badges out 4 per A4 page. */
@media print {
  body.badge-printing { background:#fff !important; }
  body.badge-printing::after { display:none !important; } /* film grain off */
  body.badge-printing .sidebar, body.badge-printing .topbar, body.badge-printing .sidebar-backdrop,
  body.badge-printing .badge-controls, body.badge-printing #toast-stack,
  body.badge-printing .modal-overlay { display:none !important; }
  body.badge-printing .main-area, body.badge-printing .content, body.badge-printing #view-badges { display:block !important; margin:0 !important; padding:0 !important; overflow:visible !important; }
  body.badge-printing .badge-sheet { display:grid !important; grid-template-columns:85mm 85mm; gap:8mm 6mm; justify-content:center; padding:6mm; }
  body.badge-printing .badge-card { page-break-inside:avoid; break-inside:avoid; opacity:1 !important; }
  body.badge-printing .badge-card.badge-noprint { display:none !important; }
  body.badge-printing .badge-card.badge-off { opacity:1; }
  body.badge-printing .badge-check { display:none !important; }
  body.badge-printing .badge-inner { max-width:none; width:85mm; height:120mm; background:#fff !important; border:1px solid #b9c4d6;
    box-shadow:none; -webkit-print-color-adjust:exact; print-color-adjust:exact; color:#1c2740; }
  /* Printing forces the badge's own palette — even when the app is in dark theme,
     paper output always gets dark text on a white card. */
  body.badge-printing .badge-co { font-size:16pt; color:#141d33; }
  body.badge-printing .badge-contact { color:#5a6578; }
  body.badge-printing .badge-foot { color:#8a93a8; }
  body.badge-printing .badge-tag { color:#0f8a72; background:rgba(34,193,163,.15); }
  body.badge-printing .badge-tag-int { color:#7a4fd0; background:rgba(160,107,255,.16); }
  body.badge-printing .badge-booth { color:#3d2b00; }
  body.badge-printing .badge-qr { width:32mm; height:32mm; }
}
@page { size:A4 portrait; margin:8mm; }

/* v29b: inline PIC phone editing (manual + prefilled, VA-library style) */
.remp-phone-wrap { display:flex; align-items:center; gap:6px; margin-top:3px; }
.remp-phone { width:128px; font-size:11.5px; font-weight:600; padding:4px 8px; border-radius:8px;
  border:1px solid var(--border); background:rgba(255,255,255,.55); color:var(--text); outline:none;
  transition:border-color .15s, box-shadow .15s; }
html[data-theme="dark"] .remp-phone { background:rgba(255,255,255,.07); }
.remp-phone:focus { border-color:var(--primary); box-shadow:0 0 0 3px rgba(58,134,255,.18); }
.remp-phone::placeholder { color:var(--text-faint); font-weight:600; }
.remp-phone:disabled { opacity:.55; }
.remp-src { font-size:9.5px; font-weight:900; letter-spacing:.5px; text-transform:uppercase;
  padding:2px 7px; border-radius:99px; }
.remp-src-booking { background:rgba(34,193,163,.15); color:#0f8a72; }
.remp-src-manual { background:var(--amber-light); color:var(--amber); }
html[data-theme="dark"] .remp-src-booking { color:#5fe3c6; }

/* v29d: minimal badge (company + QR only) + plain-text WhatsApp button */
.badge-inner-min { padding:26px 20px 30px; justify-content:center; gap:0; }
.badge-inner-min .badge-co { margin-top:0; padding:0 10px; font-size:21px; min-height:64px; text-align:center; }
.badge-qr-big { margin-top:18px; width:150px; height:150px; }
@media print {
  body.badge-printing .badge-qr-big { width:44mm; height:44mm; }
  body.badge-printing .badge-inner-min .badge-co { font-size:17pt; min-height:0; margin-bottom:7mm; }
}

/* v29e: center-aligned reminder table + phone inputs */
#reminders-table th, #reminders-table td { text-align:center; }
.remp-phone-wrap { justify-content:center; }
.remp-phone { text-align:center; }
.badge-inner-min .badge-co { text-align:center; }

/* v32: tidy pass - center Contractor & GOP table text (same convention as
   Payment Reminders); unique/booking codes removed from its rows already. */
#operational-table th, #operational-table td { text-align: center; vertical-align: middle; }
#operational-table .row-actions { text-align: center; }

/* ==========================================================================
   v33 (4.27) requested polish pack
   ========================================================================== */

/* --- 1) Gradient lives ONLY on the sidebar (and login backdrop): the content
   canvas is a calm solid in both themes, so long tables/charts stay distraction
   free. theme-aware: soft paper in light, deep navy in dark. ---------------- */
html body,
html[data-theme="dark"] body,
.tool-embed-overlay {
  background-image: none !important;
}
html body { background-color: #f6f8fc; }
html[data-theme="dark"] body,
html[data-theme="dark"] .tool-embed-overlay { background-color: #0d1526; }

/* --- 2) Per-Hall Report: professional muted palette (works in both themes) --
   Old scheme was three loud tints (green/orange/cyan). New scheme: one quiet
   slate header band + feathersoft single-family tint per group, with neutral
   body cells. ------------------------------------------------------------- */
/* hrp percentage label and hall sub-line */
.hrp-pc { font-size:10px; font-weight:700; color:var(--text-faint); }
.hrp-hall-sub { font-size:10px; font-weight:600; color:var(--text-faint); margin-top:1px; }

/* --- 6) Booth Map floating status legend: hard-coded white pill was unreadable
   in dark mode (light text on white). Make both fill + text theme aware. ----- */
html[data-theme="dark"] .boothmap-floating-legend {
  background: rgba(20, 30, 52, 0.92);
  border-color: rgba(120, 150, 200, 0.35);
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.5);
}
html[data-theme="dark"] .boothmap-floating-legend,
html[data-theme="dark"] .boothmap-floating-legend .boothmap-legend-count {
  color: #e8ecf6;
}

/* --- 5) Payment Schedule modal: centered fields like the rest of the app; the
   new Payment Method dropdown + its "type manually" input match. ------------ */
#payment-termin-list .termin-card { display: flex; align-items: center; }
#payment-termin-list .termin-body { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); justify-items: center; text-align: center; }
#payment-termin-list .termin-field { align-items: center; text-align: center; width: 100%; }
#payment-termin-list .termin-field label { text-align: center; width: 100%; }
#payment-termin-list .termin-field input,
#payment-termin-list .termin-field select { text-align: center; width: 100%; }
#payment-termin-list .termin-check { grid-column: 1 / -1; justify-content: center; }
.termin-method-field { min-width: 190px; }
.termin-method-sel {
  padding: 7px 10px; border-radius: 10px; font-size: 12.5px; font-weight: 600;
  border: 1.5px solid var(--border-strong); background: var(--surface-solid, var(--surface));
  color: var(--text); text-align: center; cursor: pointer; width: 100%;
}
.termin-method-sel:disabled { opacity: .6; cursor: not-allowed; }
.termin-method-custom { margin-top: 6px; }

/* --- 8) Sales Analytics: larger, easier-to-read chart text ----------------- */
.ana-tick { font-size: 13px; }
.ana-val { font-size: 13.5px; }
.ana-legend-item { font-size: 13.5px; }
.ana-donut-num { font-size: 30px; }
.ana-funnel-label { font-size: 13.5px; }
.ana-funnel-num { font-size: 13.5px; }
.ana-funnel-money { font-size: 13px; }
.ana-funnel-row { grid-template-columns: 88px 1fr 140px; }
.ana-top-name { font-size: 14.5px; }
.ana-top-val { font-size: 14px; }
.ana-title { font-size: 16.5px; }
/* ============================================================
   v34 (4.28) - requested follow-up polish
   ============================================================ */

/* --- 1) Sales Analytics: chart text enlarged again (Collection by Month was
   still hard to read); Termin Collection now also names the Company count
   and the collected/planned money line is promoted to primary text. -------- */
.ana-tick { font-size: 15px; }
.ana-val { font-size: 15.5px; }
.ana-legend-item { font-size: 14.5px; }
.ana-donut-num { font-size: 32px; }
.ana-funnel-label { font-size: 14.5px; }
.ana-funnel-num { font-size: 14.5px; }
.ana-funnel-money { font-size: 15px; color: var(--text); }
.ana-funnel-co { display: block; font-size: 12.5px; font-weight: 700; color: var(--primary); margin-top: 3px; }
/* two-line label + longer "Company paid" text crushed the bar in the narrow
   card - give the bar its own full-width row instead. */
.ana-funnel-row { grid-template-columns: 1fr auto; grid-template-areas: "label num" "track track" "money money"; row-gap: 6px; }
.ana-funnel-track { height: 12px; }
.ana-funnel-num { text-align: right; }

/* --- 4) Activity Log: user dropdown centered in its toolbar both axes. The
   toolbar relocates into #topbar-toolbar-slot on desktop (placeViewToolbar),
   so the rule targets the toolbar itself, not its in-page position. --------- */
.activity-toolbar { justify-content: center; align-items: center; }
#activity-user-filter { text-align: center; min-width: 240px; cursor: pointer; }

/* ============================================================
   v35 (4.29) - Activity Log user-filter polish + event-based log
   ============================================================ */

/* --- 1) Activity user filter: bigger text (matches Termin Collection size) - */
#activity-user-filter { font-size: 14.5px; font-weight: 700; padding: 9px 14px; }

/* --- 2) "Payment method centered in frame": the Payment Methods donut centers
   within its analytics card, AND the Payment Method dropdown in the Payment
   Schedule modal gets its text optically centered inside its own frame
   (native arrow replaced by a balanced chevron + symmetric padding). ---------- */
.ana-donut-wrap { justify-content: center; }
.termin-field select.termin-method-sel {
  appearance: none; -webkit-appearance: none;
  text-align: center; text-align-last: center;
  padding: 7px 28px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='7'%3E%3Cpath d='M1 1l4.5 4.5L10 1' stroke='%238a93b2' stroke-width='1.8' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 10px center;
}

/* --- 3) Activity Log: user filter pinned to the far right of its bar, so on
   desktop it lands directly beside the Event picker like everyone expects. --- */
.activity-toolbar { justify-content: flex-end; }

/* ============================================================
   v36 (4.30) - Dropdown polish: unify every <select> to the
   app's rounded-pill (ellipse) style
   ------------------------------------------------------------
   The app already uses a fully-rounded "pill" shape for status
   pills, tags, badges and the login eyebrow (border-radius:
   999px), and it's live on the server. Every <select> dropdown
   across the app -- form fields, toolbar filters, the global
   event picker, the booth-map size/country filters, the hall
   picker, and the payment-method select -- was still using the
   smaller boxy --radius-sm corners. This bumps all of them to
   the same fully-rounded pill so dropdowns read as one visual
   family with the rest of the UI. (border-radius clamps to half
   the control's height, so 999px always yields a true pill/
   ellipse regardless of the select's own padding.) ------------ */
.field select,
.event-selector select,
.picker-toolbar select,
.toolbar-select,
.termin-field select,
#filter-status,
#filter-booth-type,
#orders-filter-status,
#orders-filter-onsite,
#lunchbox-orders-filter-status,
#operational-filter-status,
#cf-filter-paid,
#price-list-filter-category,
#price-list-filter-active,
#activity-user-filter {
  border-radius: 999px;
}
/* Pill selects read better with a touch more breathing room on the sides
   than their old boxy padding gave them. */
.field select,
.picker-toolbar select,
.toolbar-select,
.termin-field select,
#filter-status,
#filter-booth-type,
#orders-filter-status,
#orders-filter-onsite,
#lunchbox-orders-filter-status,
#operational-filter-status,
#cf-filter-paid,
#price-list-filter-category,
#price-list-filter-active,
#activity-user-filter {
  padding-left: 16px;
  padding-right: 16px;
}
/* The Payment Method select already swapped in a custom chevron with its
   own balanced padding -- keep that intact, just round its ends to match. */
.termin-field select.termin-method-sel { border-radius: 999px; }
/* The Import/Export toggle is a dropdown trigger too (not a plain button --
   scoped to .dropdown-btn only, so ordinary .btn-secondary buttons like
   Cancel are untouched), so it gets the same pill treatment. */
.dropdown-btn { border-radius: 999px; }

/* ===== Analytics KPI Row (5 compact indicator boxes) ===== */
.ana-kpi-row {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 12px;
  margin-bottom: 18px;
}
.ana-kpi-box {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 14px 16px;
  border-radius: 14px;
  color: #fff;
  font-weight: 700;
  box-shadow: 0 2px 8px rgba(0,0,0,0.08);
}
.ana-kpi-icon { font-size: 22px; }
.ana-kpi-data { display: flex; flex-direction: column; text-align: center; }
.ana-kpi-value { font-size: 20px; line-height: 1.2; }
.ana-kpi-label { font-size: 11.5px; opacity: 0.9; font-weight: 600; }
.ana-kpi-blue { background: linear-gradient(135deg, #2563eb, #1d4ed8); }
.ana-kpi-green { background: linear-gradient(135deg, #059669, #047857); }
.ana-kpi-amber { background: linear-gradient(135deg, #d97706, #b45309); }
.ana-kpi-teal { background: linear-gradient(135deg, #0d9488, #0f766e); }
.ana-kpi-purple { background: linear-gradient(135deg, #7c3aed, #6d28d9); }
@media (max-width: 900px) {
  .ana-kpi-row { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 500px) {
  .ana-kpi-row { grid-template-columns: 1fr; }
}

/* ===== Analytics Report Cards (Additional Orders / Lunchbox) ===== */
.ana-report-summary {
  display: flex;
  gap: 16px;
  margin-bottom: 14px;
  flex-wrap: wrap;
}
.ana-report-stat {
  font-size: 13px;
  color: var(--text-muted);
}
.ana-report-stat strong {
  font-size: 16px;
  color: var(--text);
}
.ana-report-table {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ana-report-row {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12.5px;
}
.ana-report-currency {
  font-weight: 700;
  min-width: 40px;
  color: var(--text-muted);
}
.ana-report-bar-wrap {
  flex: 1;
  height: 8px;
  background: var(--surface-alt);
  border-radius: 4px;
  overflow: hidden;
}
.ana-report-bar {
  height: 100%;
  background: var(--primary);
  border-radius: 4px;
  transition: width 0.3s;
}
.ana-report-amount {
  font-size: 11.5px;
  color: var(--text-muted);
  white-space: nowrap;
}

/* ===== Split Payment UI (table-like grid: headers + aligned rows) ===== */
.termin-split-section {
  margin-top: 10px;
  width: 100%;
  grid-column: 1 / -1;
}
.termin-split-toggle {
  font-size: 12.5px !important;
  padding: 5px 12px !important;
}
.termin-split-list {
  margin-top: 10px;
  padding: 14px 16px;
  background: var(--surface-alt);
  border-radius: 12px;
  border: 1.5px solid var(--border);
  overflow-x: auto;
}
/* Column header row */
.split-header {
  display: grid;
  grid-template-columns: 80px minmax(150px, 1.1fr) minmax(150px, 1.1fr) minmax(130px, 1fr) minmax(160px, 1fr) minmax(180px, 1.3fr) minmax(140px, 1fr) minmax(140px, 1fr) 90px 40px;
  gap: 10px;
  padding: 0 0 8px 0;
  border-bottom: 1.5px solid var(--border);
  margin-bottom: 8px;
  font-size: 11px;
  font-weight: 700;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.4px;
  min-width: 1360px;
  text-align: center;
}
/* Each split data row */
.split-row {
  display: grid;
  grid-template-columns: 80px minmax(150px, 1.1fr) minmax(150px, 1.1fr) minmax(130px, 1fr) minmax(160px, 1fr) minmax(180px, 1.3fr) minmax(140px, 1fr) minmax(140px, 1fr) 90px 40px;
  gap: 10px;
  align-items: center;
  margin-bottom: 8px;
  min-width: 1360px;
  text-align: center;
}
.split-label {
  font-size: 13px;
  font-weight: 700;
  color: var(--text-muted);
  text-align: center;
}
.split-row input[type="number"],
.split-row input[type="date"],
.split-row select,
.split-row input[type="text"] {
  width: 100%;
  padding: 7px 10px;
  font-size: 13px;
  border: 1.5px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  color: var(--text);
  box-sizing: border-box;
  text-align: center;
}
.split-row input:focus,
.split-row select:focus {
  border-color: var(--primary);
  outline: none;
  box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.15);
}
/* A split left blank (amount = 0) is flagged red and blocks the Save Splits button
   until a real amount is entered -- applies just as much when EDITING a
   previously-saved split down to blank as it does to a brand new row. */
.split-amount.split-amount-invalid {
  border-color: var(--red);
  background: var(--red-light);
}
.termin-split-save[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
}
.split-paid-label {
  font-size: 13px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  cursor: pointer;
  white-space: nowrap;
  font-weight: 600;
}
.split-paid-label input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: var(--green);
  cursor: pointer;
}
.split-remove {
  font-size: 13px !important;
  padding: 4px 8px !important;
  color: var(--danger) !important;
}
/* Action buttons row below splits */
.split-actions {
  display: flex;
  gap: 10px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1.5px solid var(--border);
}
/* Split summary bar (termin amount vs splits total vs remaining) */
.split-summary-bar {
  display: flex;
  gap: 20px;
  flex-wrap: wrap;
  align-items: center;
  padding: 10px 14px;
  margin-bottom: 10px;
  background: var(--surface);
  border-radius: 10px;
  border: 1.5px solid var(--border);
  font-size: 13px;
}
.split-summary-bar strong {
  font-size: 14px;
}
.split-summary-target {
  color: var(--text-muted);
}
.split-summary-total {
  color: var(--text);
}
.split-summary-progress-label {
  margin-left: auto;
  font-weight: 600;
  color: var(--text-muted);
}
.split-summary-progress-label strong {
  color: var(--text);
}
/* Payment-progress bar: two stacked readings --
   - .split-progress-fill (blue) = how much of the termin has been SCHEDULED
     across all entered splits, regardless of paid status.
   - .split-progress-fill-paid (green) = the subset of that already marked Paid.
   Splits are NOT required to sum to the termin amount -- these are running
   progress indicators, not a validation gate. */
.split-progress-track {
  position: relative;
  width: 100%;
  height: 8px;
  border-radius: 999px;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  overflow: hidden;
  margin-bottom: 14px;
}
.split-progress-fill {
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  border-radius: 999px;
  background: var(--primary, #2563eb);
  opacity: 0.35;
  transition: width 0.25s ease;
}
.split-progress-fill-paid {
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  border-radius: 999px;
  background: var(--green-grad, #059669);
  transition: width 0.25s ease;
  z-index: 1;
}
.split-progress-fill.complete,
.split-progress-fill-paid.complete {
  background: var(--green-grad, #059669);
}

/* ============================================================
   LOADING SCREEN  (matches video: dark bg, 4-square logo pop)
   ============================================================ */
.loading-screen {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: #0b1220;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 36px;
  /* fade-out handled by JS adding .ls-fade-out */
  transition: opacity 0.45s cubic-bezier(.4,0,.2,1);
}
.loading-screen.ls-fade-out {
  opacity: 0;
  pointer-events: none;
}

/* ---- Logo grid ---- */
.ls-logo {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
}

.ls-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  gap: 10px;
  width: 96px;
  height: 96px;
}

/* Each square: starts invisible + scaled down, pops in sequentially */
.ls-sq {
  border-radius: 12px;
  transform: scale(0.3);
  opacity: 0;
  animation: lsSquarePop 0.52s cubic-bezier(.34,1.56,.64,1) both;
  display: flex;
  align-items: center;
  justify-content: center;
}

.ls-sq-1 { background: #fff;                      animation-delay: 0.05s; }
.ls-sq-2 { background: rgba(255,255,255,0.45);     animation-delay: 0.20s; }
.ls-sq-3 { background: rgba(255,255,255,0.45);     animation-delay: 0.35s; }
.ls-sq-4 { background: #ffd23f;                    animation-delay: 0.50s; color: #0c7d59; }

/* Checkmark inside sq-4 */
.ls-check {
  width: 56%;
  height: 56%;
  opacity: 0;
  animation: lsCheckIn 0.35s cubic-bezier(.34,1.3,.64,1) 0.88s both;
}

/* Subtle shimmer pulse after all squares are in */
.ls-sq-1, .ls-sq-4 {
  animation-name: lsSquarePop, lsPulse;
  animation-duration: 0.52s, 2.2s;
  animation-timing-function: cubic-bezier(.34,1.56,.64,1), ease-in-out;
  animation-delay: 0.05s, 1.1s;
  animation-fill-mode: both, none;
  animation-iteration-count: 1, infinite;
}

/* Title & sub */
.ls-title {
  font-family: 'Sora', 'Inter', sans-serif;
  font-size: 22px;
  font-weight: 800;
  color: #ffffff;
  letter-spacing: -0.02em;
  opacity: 0;
  animation: lsFadeUp 0.55s cubic-bezier(.16,1,.3,1) 0.72s both;
}
.ls-sub {
  font-family: 'Sora', 'Inter', sans-serif;
  font-size: 12px;
  font-weight: 500;
  color: rgba(255,255,255,0.45);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-top: -14px;
  opacity: 0;
  animation: lsFadeUp 0.5s cubic-bezier(.16,1,.3,1) 0.84s both;
}

/* ---- Loading dots ---- */
.ls-dots {
  display: flex;
  gap: 7px;
}
.ls-dots span {
  display: block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(255,255,255,0.28);
  animation: lsDotBounce 1.2s ease-in-out 1.0s infinite both;
}
.ls-dots span:nth-child(2) { animation-delay: 1.15s; }
.ls-dots span:nth-child(3) { animation-delay: 1.30s; }

/* ---- Keyframes ---- */
@keyframes lsSquarePop {
  from { transform: scale(0.3); opacity: 0; }
  to   { transform: scale(1);   opacity: 1; }
}
@keyframes lsCheckIn {
  from { opacity: 0; transform: scale(0.5); }
  to   { opacity: 1; transform: scale(1); }
}
@keyframes lsPulse {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0.72; }
}
@keyframes lsFadeUp {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes lsDotBounce {
  0%, 80%, 100% { transform: translateY(0);    opacity: 0.28; }
  40%            { transform: translateY(-7px); opacity: 0.9; }
}
