/* =====================================================================
   PES Support — shared design system
   ---------------------------------------------------------------------
   This file is the single source of truth for design tokens (colors,
   spacing, radius, shadows) and every reusable component class (buttons,
   cards, tables, forms, badges, chips, modal, toast, sidebar/topbar
   layout). Page-specific rules belong in static/css/<app>/style.css and
   should only ever build on top of the classes defined here — never
   redefine a token.

   Theme switching uses the project's existing convention: the
   `data-bs-theme="light|dark"` attribute on <html>, persisted under the
   `pes-theme` localStorage key (see base.html / dashboard_base.html).
   ===================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Merriweather:wght@400;700;900&family=Noto+Sans:wght@400;500;600;700;800&display=swap');

:root{
  --primary:#00377B;
  --primary-600:#002A5E;
  --primary-100:#EEEEFD;
  --primary-text:var(--primary);
  --success:#17C671;
  --success-100:#E8FBF1;
  --warning:#FF9533;
  --warning-100:#FEF6E6;
  --danger:#F1416C;
  --danger-100:#FDEEF2;
  --info:#17A2E0;
  --info-100:#E8F8FE;
  --vip:#B8860B;
  --vip-100:#FBF3E0;

  --bg:#F5F6FB;
  --surface:#FFFFFF;
  --surface-2:#FAFBFE;
  --border:#E8EAF3;
  --text:#1B1E2B;
  --muted:#7C8098;
  --muted-2:#A1A5B7;
  --shadow: 0 2px 10px rgba(24,28,50,0.06), 0 1px 2px rgba(24,28,50,0.05);
  --shadow-lg: 0 12px 32px rgba(24,28,50,0.10);
  --radius: 8px;

  --sidebar-width: 264px;
  --sidebar-width-collapsed: 84px;
  --topbar-height: 70px;
}

html[data-bs-theme="dark"]{
  --bg:#14161F;
  --surface:#1B1E2B;
  --surface-2:#20222F;
  --border:#2A2D3D;
  --text:#EDEEF5;
  --muted:#8A8DA3;
  --muted-2:#63667A;
  --primary-100:#25264A;
  --success-100:#123326;
  --warning-100:#332A14;
  --danger-100:#3A1C28;
  --info-100:#122C38;
  --vip:#E0B84B;
  --vip-100:#332C15;
  --shadow: 0 2px 8px rgba(0,0,0,0.25);
  --shadow-lg: 0 16px 40px rgba(0,0,0,0.45);
  /* --primary itself stays the same navy in dark mode (buttons rely on
     that), but that navy is unreadable as body-copy text on a dark
     surface — this token is for text-color usages only. */
  --primary-text:#5EA3FF;
}

/* ---------------------------- reset / base ---------------------------- */
*{ box-sizing:border-box; }
html,body{ margin:0; padding:0; }
body{
  font-family:'Noto Sans',sans-serif;
  background:var(--bg);
  color:var(--text);
  -webkit-font-smoothing:antialiased;
  transition:background .25s ease,color .25s ease;
}
h1,h2,h3,h4,.brand{ font-family:'Merriweather',serif; }
h1,h2,h3,h4{ margin:0; color:var(--text); }
a{ color:inherit; text-decoration:none; }
button{ font-family:inherit; color:inherit; }
img{ max-width:100%; }
::selection{ background:var(--primary); color:#fff; }

/* Thin, theme-matching scrollbar everywhere (page scroll, table-wrap,
   dropdown menus) instead of the browser/OS's default chunky scrollbar. */
*{ scrollbar-width:thin; scrollbar-color:var(--border) transparent; }
::-webkit-scrollbar{ width:9px; height:9px; }
::-webkit-scrollbar-track{ background:transparent; }
::-webkit-scrollbar-thumb{ background-color:var(--border); border-radius:20px; }
::-webkit-scrollbar-thumb:hover{ background-color:var(--muted); }

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

.sidebar{
  width:var(--sidebar-width); flex-shrink:0; background:var(--bg);
  border-right:none;
  display:flex; flex-direction:column;
  position:fixed; top:0; left:0; bottom:0; z-index:40;
  transition:transform .25s ease, width .2s ease, background .25s ease;
}
.sidebar.collapsed{ width:var(--sidebar-width-collapsed); }
.sidebar.dark{ background:var(--primary); }

.main{
  margin-left:var(--sidebar-width); flex:1; display:flex; flex-direction:column;
  min-width:0; transition:margin-left .2s ease;
}
.sidebar.collapsed ~ .main{ margin-left:var(--sidebar-width-collapsed); }

.topbar{
  height:var(--topbar-height); background:var(--bg);
  display:flex; align-items:center; gap:16px; padding:0 26px;
  position:sticky; top:0; z-index:30;
}

.content{ padding:45px 30px 60px; max-width:1360px; width:100%; margin:0 auto; }

.content-shell{
  /* No isolation:isolate — that would trap descendant modals' z-index inside
     this element's own stacking context, so they could never paint above
     the sidebar/topbar (which sit outside it with their own z-index). */
  position:relative; margin:0 22px 22px; border:1px solid var(--border);
  border-radius:26px; box-shadow:var(--shadow-lg); overflow:hidden;
  flex:1; display:flex; flex-direction:column;
  /* Distinct from .card's solid --surface white/dark, so cards actually
     stand out instead of blending into the shell behind them. */
  background:linear-gradient(180deg, var(--surface-2) 0%, var(--bg) 100%);
}
.content-shell::before{
  content:""; position:absolute; top:-120px; right:-100px; width:320px; height:320px; z-index:0;
  background:radial-gradient(circle, color-mix(in srgb, var(--primary) 10%, transparent) 0%, transparent 70%);
  pointer-events:none;
}
.content-shell .content{ flex:1; position:relative; z-index:1; }

.overlay{ position:fixed; inset:0; background:rgba(0,0,0,.4); z-index:35; display:none; }
.overlay.show{ display:block; }

/* ------------------------------ sidebar -------------------------------- */
.sidebar-brand{ display:flex; align-items:center; gap:10px; padding:18px 22px 14px; }
.sidebar-brand img.logo-mark{ width:36px; height:36px; border-radius:10px; object-fit:contain; flex-shrink:0; }
.sidebar-brand img.logo-full{ height:34px; width:auto; display:block; }
.sidebar.collapsed .sidebar-brand{ padding:18px 0 14px; justify-content:center; }
.sidebar.collapsed .sidebar-brand img.logo-full{ display:none; }
.sidebar:not(.collapsed) .sidebar-brand img.logo-mark{ display:none; }
html[data-bs-theme="dark"] .sidebar-brand img.logo-full-light{ display:none; }
html:not([data-bs-theme="dark"]) .sidebar-brand img.logo-full-dark{ display:none; }

.sidebar-scroll{ flex:1; overflow-y:auto; padding:6px 14px 20px; }
.nav-heading{
  font-size:11px; font-weight:700; letter-spacing:.09em; color:var(--muted-2);
  text-transform:uppercase; padding:16px 12px 8px;
}
.sidebar.collapsed .nav-heading{ display:none; }

.nav-item{
  display:flex; align-items:center; gap:12px; width:100%;
  padding:9px 12px; margin:2px 0; border-radius:8px; border:none; background:transparent;
  color:var(--muted); font-size:14px; font-weight:500; text-align:left;
  cursor:pointer; position:relative; transition:background .15s ease,color .15s ease;
}
.nav-item svg{ width:18px; height:18px; flex-shrink:0; }
.nav-item:hover{ background:var(--surface-2); color:var(--text); }
.nav-item.active{ background:var(--primary-100); color:var(--primary-text); font-weight:700; }
.sidebar.dark .nav-item{ color:rgba(255,255,255,.82); }
.sidebar.dark .nav-item:hover{ background:rgba(255,255,255,.08); color:#fff; }
.sidebar.dark .nav-item.active{ background:rgba(255,255,255,.14); color:#fff; }
.sidebar.collapsed .nav-item{ justify-content:center; }
.sidebar.collapsed .nav-item span.label,
.sidebar.collapsed .nav-item .nav-badge,
.sidebar.collapsed .nav-group-btn svg.chev{ display:none; }
.sidebar.collapsed .nav-children{ display:none !important; }

.nav-badge{
  margin-left:auto; background:var(--danger); color:#fff; font-size:10.5px;
  font-weight:700; padding:1px 7px; border-radius:20px;
}
.nav-children{
  margin-left:14px; padding-left:14px; border-left:1px solid var(--border);
  display:flex; flex-direction:column; gap:2px; margin-bottom:6px;
}
.sidebar.dark .nav-children{ border-left-color:rgba(255,255,255,.14); }
.nav-children .nav-item{ padding:7px 10px; font-size:12.8px; }

.nav-group-btn svg.chev{ width:14px; height:14px; margin-left:auto; flex-shrink:0; }
.nav-new-btn{
  display:flex; align-items:center; gap:8px; width:100%; margin-top:2px;
  padding:7px 10px; border-radius:8px; border:1px dashed var(--primary-text); background:transparent;
  color:var(--primary-text); font-size:12.2px; font-weight:700; cursor:pointer;
}
.nav-new-btn svg{ width:12px; height:12px; flex-shrink:0; }
.sidebar.dark .nav-new-btn{ border-color:rgba(255,255,255,.4); color:rgba(255,255,255,.9); }
.nav-new-btn.active{ background:var(--primary); border-style:solid; border-color:var(--primary); color:#fff; }
.sidebar.dark .nav-new-btn.active{ background:rgba(255,255,255,.16); border-color:transparent; color:#fff; }

.sidebar-footer{ padding:14px; }
.sidebar.collapsed .sidebar-footer{ display:none; }
.upgrade-card{
  background:linear-gradient(135deg,var(--primary),#001F4A);
  border-radius:14px; padding:16px; color:#fff;
}
.upgrade-card h4{ margin:0 0 4px; font-size:14px; color:#fff; }
.upgrade-card p{ margin:0 0 12px; font-size:12px; opacity:.85; line-height:1.4; }
.upgrade-card button{
  background:#fff; color:var(--primary-600); border:none; border-radius:8px;
  padding:7px 12px; font-size:12.5px; font-weight:700; cursor:pointer; width:100%;
}
.sidebar-footer-note{ padding:10px 12px 0; font-size:11px; color:var(--muted); }
.sidebar.dark .sidebar-footer-note{ color:rgba(255,255,255,.5); }
.sidebar.collapsed .sidebar-footer-note{ display:none; }

/* ------------------------------- topbar -------------------------------- */
.search-box{
  flex:1; max-width:420px; display:flex; align-items:center; gap:10px;
  background:var(--surface-2); border:1px solid var(--border); border-radius:10px;
  padding:9px 14px; color:var(--muted); position:relative;
}
.search-box input[type=text]{
  border:none; background:transparent; outline:none; flex:1; padding:0;
  font-size:13.5px; color:var(--text); border-radius:0;
}
.search-box input[type=text]:focus{ border:none; background:transparent; }
.search-box svg{ width:16px; height:16px; flex-shrink:0; display:block; }
/* .icon-btn (defined later, under topbar-right) also sets display:flex —
   needs matching .icon-btn.search-mobile-btn specificity here to actually
   win, a plain .search-mobile-btn{display:none} would otherwise lose that
   tie-break regardless of viewport width. */
.icon-btn.search-mobile-btn{ display:none; }
@media(max-width:820px){ .icon-btn.search-mobile-btn{ display:flex; } }
.search-modal{ max-width:520px; }
.search-modal .search-box{ max-width:none; }

/* Dashboard topbar's own round-logo mark — only relevant on mobile, where
   the sidebar (which normally carries the brand) is off-canvas and hidden. */
.topbar-brand{ display:none; align-items:center; }
.topbar-brand img.logo-mark{ width:32px; height:32px; border-radius:8px; object-fit:contain; }
html[data-bs-theme="dark"] .topbar-brand img.logo-mark-light{ display:none; }
html:not([data-bs-theme="dark"]) .topbar-brand img.logo-mark-dark{ display:none; }
@media(max-width:820px){ .topbar-brand{ display:flex; } }

.topbar-right{ display:flex; align-items:center; gap:8px; margin-left:auto; }
.icon-btn{
  width:40px; height:40px; border-radius:8px; border:1px solid var(--border); background:var(--surface);
  display:flex; align-items:center; justify-content:center; cursor:pointer; color:var(--muted); position:relative;
  transition:background .15s ease,color .15s ease; flex-shrink:0;
}
.icon-btn:hover{ background:var(--surface-2); color:var(--text); }
.icon-btn svg{ width:18px; height:18px; }
.dot{
  position:absolute; top:8px; right:9px; width:7px; height:7px; border-radius:50%; background:var(--danger);
  border:1.5px solid var(--surface);
}
.user-chip{
  display:flex; align-items:center; gap:4px; padding:3px; border-radius:12px;
  border:1px solid var(--border); cursor:pointer; background:var(--surface); color:var(--text);
}
.avatar{
  width:32px; height:32px; border-radius:9px; background:linear-gradient(135deg,var(--primary),#001F4A);
  display:flex; align-items:center; justify-content:center; color:#fff; font-weight:700; font-size:13px; flex-shrink:0;
}
.user-chip svg{ flex-shrink:0; margin-right:4px; }

.theme-toggle{ display:flex; align-items:center; gap:6px; background:var(--surface-2); border-radius:10px; padding:4px; border:1px solid var(--border); }
.theme-toggle button{
  border:none; background:none; width:32px; height:32px; border-radius:7px; display:flex; align-items:center;
  justify-content:center; cursor:pointer; color:var(--muted);
}
.theme-toggle button svg{ width:16px; height:16px; }
.theme-toggle button.active{ background:var(--surface); color:var(--primary-text); box-shadow:var(--shadow); }

/* Compact variant used by the public header (see compact_theme_toggle in
   _topbar_actions.html) — same two buttons/mechanism, just sized down to
   fit the slimmer public navbar instead of the dashboard topbar's size. */
.theme-toggle.compact{ gap:2px; padding:3px; }
.theme-toggle.compact button{ width:26px; height:26px; border-radius:6px; }
.theme-toggle.compact button svg{ width:14px; height:14px; }

/* ---------------------------- public site header ------------------------ */
/* Rendered by main/base.html's {% block header %} — shared by every public
   page (home, public webforms, login, error pages), not just the home page. */

/* Secondary utility bar above the main navbar, cloned from news.pes.edu's
   cross-site strip — same real PES destinations regardless of which PES
   sub-site you're on. */
.public-utility-bar{ background:var(--primary-600); color:#fff; }
.public-utility-inner{
  width:100%; padding:6px 24px; display:flex; align-items:center; justify-content:space-between; gap:16px;
  font-size:12px;
}
.utility-back{ display:inline-flex; align-items:center; gap:4px; color:rgba(255,255,255,.85); font-weight:600; white-space:nowrap; }
.utility-back:hover{ color:#fff; }
.utility-back svg{ width:13px; height:13px; }
.utility-links{ display:flex; align-items:center; gap:16px; }
.utility-link{ display:inline-flex; align-items:center; gap:5px; color:rgba(255,255,255,.85); font-weight:600; white-space:nowrap; }
.utility-link:hover{ color:#fff; }
.utility-link svg{ width:13px; height:13px; }
.utility-divider{ width:1px; height:14px; background:rgba(255,255,255,.25); }
.utility-admissions-btn{
  display:inline-flex; align-items:center; gap:5px; padding:5px 14px; border-radius:999px;
  background:var(--warning); color:#fff; font-weight:700; white-space:nowrap; transition:filter .15s ease; font-size:11.5px;
}
.utility-admissions-btn:hover{ filter:brightness(1.06); }
.utility-admissions-btn svg{ width:13px; height:13px; }

.public-nav-link.active,
.public-nav-link.active:hover{ background:var(--primary); color:#fff; }

/* Full-width mega dropdown (per-campus quick links), cloned from
   news.pes.edu's "Browse by X" panels. Reparented to <body> and positioned
   with JS (see initMegaMenus in scripts.js) — same reasoning as the modal
   reparenting in initModals(): no ancestor's position/transform can then
   trap it away from spanning the full viewport width. */
.mega-panel{
  position:fixed; left:0; right:0; z-index:300; background:var(--surface); border-bottom:1px solid var(--border);
  box-shadow:var(--shadow-lg); display:none; max-height:80vh; overflow-y:auto;
}
.mega-panel.show{ display:block; animation:megaPanelIn .22s cubic-bezier(.22,.85,.32,1); }
@keyframes megaPanelIn{ from{ opacity:0; transform:translateY(-10px); } to{ opacity:1; transform:none; } }
@media (prefers-reduced-motion:reduce){ .mega-panel.show{ animation:none; } }
/* Background spans the full width (like the header above it); the actual
   content lines up with the header/page content's own max-width instead of
   stretching edge-to-edge. */
.mega-panel-inner{
  max-width:1180px; margin:0 auto; display:grid; grid-template-columns:270px 1fr; min-height:230px;
}
/* Left: the campus's own photo (or its brand color as a flat fallback)
   with its name overlaid — right: the quick-links grid. */
.mega-panel-visual{
  position:relative; padding:24px; display:flex; flex-direction:column; justify-content:flex-end;
  background-size:cover; background-position:center; color:#fff; overflow:hidden;
}
.mega-panel-visual::before{
  content:""; position:absolute; inset:0; background:linear-gradient(200deg, rgba(0,0,0,0) 30%, rgba(0,0,0,.68) 100%);
}
.mega-panel-visual-icon{
  position:relative; z-index:1; width:40px; height:40px; border-radius:11px; margin-bottom:auto;
  background:rgba(255,255,255,.2); backdrop-filter:blur(4px); display:flex; align-items:center; justify-content:center;
}
.mega-panel-visual-icon svg{ width:18px; height:18px; }
.mega-panel-visual-title{ position:relative; z-index:1; font-size:20px; font-weight:800; margin:0 0 4px; color:#fff; }
.mega-panel-visual-sub{ position:relative; z-index:1; font-size:12px; color:rgba(255,255,255,.82); }

.mega-panel-links{ padding:26px 0 30px 32px; }
.mega-panel-links-head{ display:flex; align-items:center; justify-content:space-between; margin-bottom:18px; }
.mega-panel-eyebrow{ font-size:11px; font-weight:800; letter-spacing:.8px; text-transform:uppercase; color:var(--muted); }
.mega-panel-close{
  width:32px; height:32px; border-radius:50%; border:1px solid var(--border); background:var(--surface);
  display:flex; align-items:center; justify-content:center; color:var(--muted); cursor:pointer; flex-shrink:0;
  transition:background .15s ease, color .15s ease, transform .15s ease;
}
.mega-panel-close:hover{ background:var(--surface-2); color:var(--text); transform:rotate(90deg); }
.mega-panel-close svg{ width:15px; height:15px; }
.mega-panel-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(200px,1fr)); gap:14px; padding-right:32px; }
.mega-item{
  display:flex; align-items:center; gap:12px; padding:16px 18px; border-radius:14px; border:1px solid var(--border);
  background:var(--surface); transition:border-color .2s ease, background .2s ease, transform .15s ease, box-shadow .2s ease;
}
.mega-item:hover{ border-color:var(--accent, var(--primary)); background:var(--surface-2); transform:translateY(-2px); box-shadow:var(--shadow); }
.mega-item-icon{
  width:40px; height:40px; border-radius:11px; flex-shrink:0; display:flex; align-items:center; justify-content:center;
  background:var(--accent-100, var(--primary-100)); color:var(--accent, var(--primary-text));
}
.mega-item-icon svg{ width:18px; height:18px; }
.mega-item-body{ min-width:0; display:flex; flex-direction:column; gap:2px; }
.mega-item-title{ font-size:13.5px; font-weight:700; color:var(--text); }
.mega-item-sub{ font-size:11.5px; color:var(--muted); }
@media(max-width:760px){
  .mega-panel-inner{ grid-template-columns:1fr; }
  .mega-panel-visual{ padding:20px 24px; min-height:110px; }
  .mega-panel-links{ padding:22px 24px 26px; }
  .mega-panel-grid{ padding-right:0; }
}

/* Full-screen search overlay toggled by #publicSearchToggleBtn (see
   initPublicSearchToggle in scripts.js) — cloned from news.pes.edu's dark
   glassmorphic command-palette search: this panel is deliberately always
   dark-navy-glass regardless of the site's own light/dark toggle, same as
   the hero section. Adapted with a "quick filters" row of campuses instead
   of their tag/press-note filters (no tag taxonomy in this app). */
.search-overlay{ position:fixed; inset:0; z-index:500; display:none; }
.search-overlay.show{ display:block; }
.search-overlay-backdrop{ position:absolute; inset:0; background:rgba(4,12,28,.65); backdrop-filter:blur(8px); }
body.search-overlay-open{ overflow:hidden; }
/* No card/box around this — just the field and the filter chips floating
   directly over the dimmed, blurred backdrop. */
.search-overlay-panel{
  position:relative; z-index:1; max-width:640px; margin:80px auto 0; padding:0 28px;
  animation:searchOverlayIn .22s cubic-bezier(.22,.85,.32,1);
}
@keyframes searchOverlayIn{ from{ opacity:0; transform:translateY(-16px); } to{ opacity:1; transform:none; } }
@media (prefers-reduced-motion:reduce){ .search-overlay-panel{ animation:none; } }
.search-overlay-head{ display:flex; align-items:center; justify-content:space-between; margin-bottom:20px; }
.search-overlay-brand{ display:flex; align-items:center; gap:8px; font-size:12.5px; font-weight:800; letter-spacing:.4px; text-transform:uppercase; color:#ffb648; }
.search-overlay-brand svg{ width:16px; height:16px; }
.search-overlay-close{
  display:flex; align-items:center; gap:8px; border:1px solid rgba(255,255,255,.16); background:rgba(255,255,255,.08);
  border-radius:8px; padding:6px 10px; cursor:pointer; color:rgba(255,255,255,.7);
}
.search-overlay-close:hover{ color:#fff; background:rgba(255,255,255,.14); }
.search-overlay-close svg{ width:14px; height:14px; }
.kbd{
  font-size:10.5px; font-weight:700; padding:2px 6px; border-radius:5px;
  background:rgba(255,255,255,.1); border:1px solid rgba(255,255,255,.18); color:rgba(255,255,255,.75);
}

.search-overlay-form{
  display:flex; align-items:center; gap:10px; background:#fff; border-radius:14px; overflow:hidden;
  padding:6px 6px 6px 16px; margin-bottom:22px; box-shadow:0 8px 20px rgba(0,0,0,.25);
}
.search-overlay-form svg{ width:18px; height:18px; color:var(--muted); flex-shrink:0; }
/* input[type=search] renders its own native rounded box + border in some
   browsers unless fully reset — left as-is it visually splits into two
   boxes (a small bordered one nested inside the pill), pushing the search
   icon out into the gap to its left. */
.search-overlay-form input{
  flex:1; min-width:0; border:none; outline:none; background:transparent; -webkit-appearance:none; appearance:none;
  box-shadow:none; font-size:15px; font-family:inherit; color:#1b1e2b; padding:8px 0;
}
.search-overlay-form input::-webkit-search-decoration,
.search-overlay-form input::-webkit-search-cancel-button,
.search-overlay-form input::-webkit-search-results-button,
.search-overlay-form input::-webkit-search-results-decoration{
  -webkit-appearance:none;
}
.search-overlay-submit{
  width:38px; height:38px; border-radius:10px; border:none; background:var(--primary); color:#fff;
  display:flex; align-items:center; justify-content:center; cursor:pointer; flex-shrink:0; transition:background .15s ease;
}
.search-overlay-submit:hover{ background:var(--primary-600); }
.search-overlay-submit svg{ width:16px; height:16px; }

.search-overlay-section-label{
  display:flex; align-items:center; gap:6px; font-size:11px; font-weight:800; letter-spacing:.6px; text-transform:uppercase;
  color:rgba(255,255,255,.55); margin-bottom:12px;
}
.search-overlay-section-label svg{ width:13px; height:13px; color:#ffb648; }
.search-overlay-filters{ display:flex; flex-wrap:wrap; gap:8px; }
.search-overlay-filter{
  display:inline-flex; align-items:center; gap:7px; padding:8px 14px; border-radius:999px;
  border:1px solid rgba(255,255,255,.14); background:rgba(255,255,255,.07);
  font-size:12.5px; font-weight:700; color:rgba(255,255,255,.85); transition:border-color .15s ease, background .15s ease;
}
.search-overlay-filter:hover{ border-color:rgba(255,255,255,.35); background:rgba(255,255,255,.14); }
.search-overlay-filter .dotc{ width:7px; height:7px; border-radius:50%; flex-shrink:0; }
.search-overlay-hint{ text-align:center; font-size:11.5px; color:rgba(255,255,255,.55); margin-top:20px; }
.search-overlay-hint .kbd{ margin:0 2px; }
@media(max-width:640px){
  .search-overlay-panel{ margin:16px 12px 0; padding:0 8px; }
}

.public-header{ position:sticky; top:0; z-index:40; background:var(--surface); border-bottom:1px solid var(--border); width:100%; }
.public-header-inner{
  width:100%; padding:10px 24px;
  display:grid; grid-template-columns:auto 1fr auto; align-items:center; gap:18px;
}
.public-nav-toggle{ display:none; }
.public-brand{ display:flex; align-items:center; gap:10px; }
.public-brand img.logo-full{ height:34px; width:auto; display:block; }
html[data-bs-theme="dark"] .public-brand img.logo-full-light{ display:none; }
html:not([data-bs-theme="dark"]) .public-brand img.logo-full-dark{ display:none; }
/* Round mark shown instead of the wordmark below 980px (see responsive
   section at the end of this file) — hidden on desktop by default. */
.public-brand img.logo-mark{ width:38px; height:38px; border-radius:10px; object-fit:contain; display:none; }
html[data-bs-theme="dark"] .public-brand img.logo-mark-light{ display:none; }
html:not([data-bs-theme="dark"]) .public-brand img.logo-mark-dark{ display:none; }

.public-nav{ display:flex; align-items:center; justify-content:center; gap:2px; flex-wrap:wrap; }
.public-nav-brand{ display:none; }

.drawer-close-btn{
  display:none; width:32px; height:32px; border-radius:8px; flex-shrink:0;
  border:1px solid var(--border); background:var(--surface-2); color:var(--muted);
  align-items:center; justify-content:center; cursor:pointer;
}
.drawer-close-btn:hover{ background:var(--surface); color:var(--text); }
.drawer-close-btn svg{ width:15px; height:15px; }
.public-nav-link{
  display:flex; align-items:center; gap:5px; padding:8px 16px; border-radius:9px; border:none; background:transparent;
  font-size:13.3px; font-weight:600; color:var(--text); cursor:pointer; white-space:nowrap; font-family:inherit;
}
.public-nav-link:hover{ background:var(--surface-2); color:var(--primary); }
.public-nav-link svg.chev{ width:12px; height:12px; opacity:.6; }
.public-header-right{ display:flex; align-items:center; gap:10px; justify-self:end; }

/* Below 980px the horizontal nav becomes a left-hand off-canvas drawer,
   toggled by #publicNavToggleBtn (see initPublicNav in scripts.js) — mirrors
   the dashboard sidebar's own off-canvas pattern so the two navbars behave
   the same way on mobile instead of the public one just disappearing. */
@media (max-width:980px){
  .public-nav-toggle{ display:flex; }
  .public-brand img.logo-full{ display:none; }
  .public-brand img.logo-mark{ display:block; }
  .public-nav{
    position:fixed; top:0; left:0; bottom:0; z-index:250; width:280px; max-width:82vw;
    background:var(--surface); flex-direction:column; align-items:stretch; gap:2px;
    padding:20px 14px 20px; overflow-y:auto; box-shadow:var(--shadow-lg);
    transform:translateX(-100%); transition:transform .25s ease;
  }
  .public-nav.open{ transform:translateX(0); }
  .public-nav-brand{
    display:flex; align-items:center; justify-content:space-between; gap:10px;
    padding:0 12px 18px; margin-bottom:10px; border-bottom:1px solid var(--border);
  }
  .public-nav-brand img.logo-full{ height:30px; width:auto; display:block; }
  html[data-bs-theme="dark"] .public-nav-brand img.logo-full-light{ display:none; }
  html:not([data-bs-theme="dark"]) .public-nav-brand img.logo-full-dark{ display:none; }
  .public-nav-brand .drawer-close-btn{ display:flex; }
  .public-nav-link{ width:100%; justify-content:space-between; }
  .public-nav .menu-wrap{ width:100%; }
}
@media (prefers-reduced-motion:reduce){ .public-nav{ transition:none; } }

/* --------------------------- dropdown menus ---------------------------- */
.menu-wrap{ position:relative; }
.menu-panel{
  position:absolute; top:calc(100% + 8px); right:0; width:280px; background:var(--surface);
  border:1px solid var(--border); border-radius:14px; box-shadow:0 20px 45px rgba(0,20,45,.16);
  z-index:41; display:none; overflow:hidden;
}
.menu-panel.left{ right:auto; left:0; }
.menu-panel.show{ display:block; }
.menu-panel-head{ display:flex; align-items:center; justify-content:space-between; padding:12px 16px; border-bottom:1px solid var(--border); }
.menu-panel-head h4{ margin:0; font-size:14.5px; font-weight:800; color:var(--primary-text); }
.menu-panel-head-actions{ display:flex; align-items:center; gap:10px; }
#notificationsMenu{ width:340px; }
.menu-item{
  width:100%; display:flex; align-items:center; gap:10px; border:none; background:transparent;
  border-radius:9px; padding:9px 10px; cursor:pointer; color:var(--text); font-size:13px; font-weight:600; text-align:left;
}
.menu-item:hover{ background:var(--surface-2); }
.menu-item.danger{ color:var(--danger); }
.menu-item svg{ width:15px; height:15px; flex-shrink:0; }
.menu-body{ padding:8px; }
.menu-divider{ height:1px; background:var(--border); margin:6px 4px; }

/* Profile summary shown at the top of the account dropdown (#profileMenu) —
   the topbar chip itself hides the name/email on mobile to save space, so
   this repeats avatar + name + username inside the dropdown on every size. */
.menu-profile-head{ display:flex; align-items:center; gap:12px; padding:16px; border-bottom:1px solid var(--border); }
.menu-profile-head .avatar{ width:42px; height:42px; border-radius:11px; font-size:15px; }
.menu-profile-head-text{ min-width:0; }
.menu-profile-head-text .name{ font-size:14px; font-weight:700; color:var(--text); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.menu-profile-head-text .username{ font-size:12px; color:var(--muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

.notif-row{
  display:flex; align-items:flex-start; gap:14px; padding:16px 20px; cursor:pointer;
  border-top:1px solid var(--border); position:relative; transition:background .15s ease;
  animation:notifRowIn .3s ease both;
}
@keyframes notifRowIn{ from{ opacity:0; transform:translateX(6px); } to{ opacity:1; transform:none; } }
@media (prefers-reduced-motion:reduce){ .notif-row{ animation:none; } }
.notif-row:first-child{ border-top:none; }
.notif-row:hover{ background:var(--surface-2); }
.notif-row.unread{ background:color-mix(in srgb, var(--warning) 8%, var(--surface)); }
.notif-row.unread:hover{ background:color-mix(in srgb, var(--warning) 14%, var(--surface)); }
.notif-row.unread::before{
  content:""; position:absolute; left:0; top:0; bottom:0; width:3px;
  background:linear-gradient(180deg, var(--warning), color-mix(in srgb, var(--warning) 60%, var(--danger)));
}
.notif-icon{
  width:36px; height:36px; border-radius:50%; flex-shrink:0; display:flex; align-items:center; justify-content:center;
  background:var(--surface-2); color:var(--muted); transition:background .15s ease, color .15s ease;
}
.notif-icon svg{ width:16px; height:16px; }
.notif-row.unread .notif-icon{ background:var(--warning-100); color:var(--warning); }
.notif-body{ flex:1; min-width:0; }
.notif-msg{ font-size:12.8px; font-weight:600; color:var(--text); line-height:1.4; }
.notif-row.unread .notif-msg{ font-weight:800; }
.notif-desc{ font-size:12px; color:var(--muted); line-height:1.55; margin-top:4px; }
.notif-time{ font-size:11px; color:var(--muted-2); margin-top:5px; display:flex; align-items:center; gap:7px; flex-wrap:wrap; }
.notif-unread-pill{
  flex-shrink:0; font-size:9px; font-weight:800; text-transform:uppercase; letter-spacing:.5px;
  background:var(--warning); color:#fff; padding:2px 7px; border-radius:20px; line-height:1.5;
}
.notif-read-tick{ flex-shrink:0; display:inline-flex; color:var(--success); opacity:.65; }
.notif-read-tick svg{ width:12px; height:12px; }
.notif-group-head{
  display:flex; align-items:center; gap:8px; font-size:11.5px; font-weight:800; text-transform:uppercase;
  letter-spacing:.5px; color:var(--muted); margin-bottom:12px;
}
.notif-group-count{
  background:var(--surface-2); border:1px solid var(--border); color:var(--muted);
  font-size:10.5px; font-weight:800; padding:1px 8px; border-radius:20px; letter-spacing:0; text-transform:none;
}
/* Full notifications page only — wraps the click-to-read button plus a
   separate row-actions column (Edit/Delete), which can't nest inside the
   button itself since a <button> can't contain other <button> elements. */
.notif-row-outer{ display:flex; align-items:stretch; }
.notif-row-outer.bordered{ border-top:1px solid var(--border); }
.notif-row-outer.unread{ background:color-mix(in srgb, var(--warning) 8%, var(--surface)); }
.notif-row-actions{ display:flex; align-items:center; gap:6px; padding-right:16px; flex-shrink:0; }
.menu-footer-btn{
  width:100%; border:none; border-top:none; background:transparent; color:var(--primary-text);
  font-weight:700; font-size:12.5px; padding:12px 0 10px; cursor:pointer; text-align:center; display:block;
}
.menu-footer-btn:hover{ text-decoration:underline; }

/* -------------------------------- pages -------------------------------- */
.page-head{
  position:relative;
  display:flex; align-items:center; justify-content:space-between; gap:20px; flex-wrap:wrap;
  margin-bottom:32px; padding:2px 0 26px 22px; border-bottom:1px solid var(--border);
  animation:pageHeadIn .45s cubic-bezier(.22,.85,.32,1) both;
}
.page-head::before{
  content:""; position:absolute; left:0; top:2px; bottom:26px; width:4px; border-radius:4px;
  background:linear-gradient(180deg, var(--primary-text) 0%, var(--info) 100%);
}
@keyframes pageHeadIn{ from{ opacity:0; transform:translateY(-8px); } to{ opacity:1; transform:translateY(0); } }
@media (prefers-reduced-motion:reduce){ .page-head{ animation:none; } }
.breadcrumb{
  font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.06em;
  color:var(--muted-2); margin-bottom:9px;
}
.breadcrumb b{ color:var(--primary-text); font-weight:800; }
.page-head h1{
  font-family:'Merriweather',serif; font-size:28px; font-weight:800; margin:0 0 7px; letter-spacing:-.02em;
  color:var(--text);
}
@supports ((background-clip:text) or (-webkit-background-clip:text)){
  .page-head h1{
    background:linear-gradient(120deg, var(--text) 40%, var(--primary-text) 150%);
    -webkit-background-clip:text; background-clip:text; color:transparent;
  }
}
.page-head .sub{ color:var(--muted); font-size:13.5px; }

/* Title + trailing actions header (webform builder, error log detail) — no
   background/card at all, just generous spacing and a thin colored accent
   bar echoing .page-head's own left bar, so it reads as part of the same
   design language without literally duplicating the panel treatment. The
   text block always keeps flex:1/min-width:0 so it's the one that shrinks
   first; trailing actions are grouped in .detail-header-actions so they
   wrap/stack as a unit instead of each button/badge wrapping independently. */
.detail-header{
  position:relative;
  display:flex; align-items:center; gap:24px; flex-wrap:wrap;
  margin-bottom:32px; padding:2px 0 26px 22px; border-bottom:1px solid var(--border);
  animation:detailHeaderIn .45s cubic-bezier(.22,.85,.32,1) both;
}
.detail-header::before{
  content:""; position:absolute; left:0; top:2px; bottom:26px; width:4px; border-radius:4px;
  background:linear-gradient(180deg, var(--primary-text) 0%, var(--info) 100%);
}
.detail-header.danger::before{ background:linear-gradient(180deg, var(--danger) 0%, var(--warning) 100%); }
@keyframes detailHeaderIn{ from{ opacity:0; transform:translateY(-8px); } to{ opacity:1; transform:translateY(0); } }
@media (prefers-reduced-motion:reduce){ .detail-header{ animation:none; } }
.detail-header > div:first-child{ flex:1; min-width:0; }
.detail-header-actions{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; flex-shrink:0; }

.detail-header .breadcrumb{ margin-bottom:9px; }

.detail-header-title-row{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin-bottom:7px; }
.detail-header h1{
  font-family:'Merriweather',serif; font-size:28px; font-weight:800; letter-spacing:-.02em; margin:0;
  color:var(--text);
}
@supports ((background-clip:text) or (-webkit-background-clip:text)){
  .detail-header h1{
    background:linear-gradient(120deg, var(--text) 35%, var(--primary-text) 160%);
    -webkit-background-clip:text; background-clip:text; color:transparent;
  }
}
.detail-header .text-sub{ color:var(--muted); font-size:13.5px; }

/* -------------------------------- buttons ------------------------------- */
.btn{
  display:inline-flex; align-items:center; gap:8px; border-radius:8px; border:1px solid transparent;
  padding:10px 16px; font-size:13.5px; font-weight:600; cursor:pointer; transition:all .15s ease;
}
.btn svg{ width:15px; height:15px; }
.btn-primary{ background:var(--primary); color:#fff; }
.btn-primary:hover{ background:var(--primary-600); }
.btn-accent{ background:var(--warning); color:#fff; box-shadow:0 6px 16px rgba(255,149,51,.28); }
.btn-accent:hover{ filter:brightness(0.95); }
/* Public webform submit button (and its builder live-preview mirror) — a
   distinct look from .btn-accent, which is used for admin-side actions
   (Export, Publish) elsewhere. */
.btn-form-submit{ background:linear-gradient(135deg, var(--primary), #001F4A); color:#fff; box-shadow:0 6px 16px color-mix(in srgb, var(--primary) 35%, transparent); }
.btn-form-submit:hover{ filter:brightness(1.08); }
.btn-outline{ background:var(--surface); border-color:var(--border); color:var(--text); }
.btn-outline:hover{ background:var(--surface-2); }
.btn-ghost{ background:transparent; color:var(--muted); border-color:transparent; }
.btn-ghost:hover{ color:var(--text); background:var(--surface-2); }
.btn-sm{ padding:7px 12px; font-size:12.5px; }
.btn-danger{ background:#fff; color:var(--danger); border:1px solid var(--danger-100); }
.btn-danger:hover{ background:var(--danger-100); }
.btn-danger-soft{ background:var(--danger-100); color:var(--danger); }
.btn:disabled{ opacity:.5; cursor:not-allowed; }
.btn-block{ width:100%; justify-content:center; }

/* --------------------------------- cards -------------------------------- */
.card{
  background:var(--surface); border:1px solid var(--border); border-radius:var(--radius);
  box-shadow:var(--shadow);
}
.card-head{ padding:24px 28px; border-bottom:1px solid var(--border); display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; }
.card-head h3{ margin:0; font-size:15.5px; }
.card-head .sub{ font-size:12px; color:var(--muted); margin-top:4px; }
.card-body{ padding:30px; }
/* Consistent padding for the templates' one-off "bare" cards (help center,
   webform builder detail boxes, change-password, error-log detail, FAQ
   manager panes, etc.) that don't use the .card-head/.card-body structure —
   previously each had its own ad-hoc inline padding (16/18/20/22/26px), so
   cards looked inconsistent from page to page. */
.compact-card{ padding:30px; }

.grid-stats{ display:grid; grid-template-columns:repeat(4,1fr); gap:18px; margin-bottom:24px; }
.settings-grid-stats-3{ grid-template-columns:repeat(3,1fr); }
.stat-card{
  padding:28px; position:relative; overflow:hidden; isolation:isolate;
  transition:transform .2s ease, box-shadow .2s ease;
}
.stat-card:hover{ transform:translateY(-4px); box-shadow:var(--shadow-lg); }
.stat-card::after{
  content:""; position:absolute; top:-34px; right:-34px; width:120px; height:120px; border-radius:50%; z-index:0;
  background:var(--stat-accent-100, var(--info-100)); opacity:.55;
}
.stat-card.brand{
  background:linear-gradient(135deg, var(--primary) 0%, var(--primary-600) 100%); border-color:var(--primary);
}
.stat-card.brand::after{ background:rgba(255,255,255,.1); }
.stat-top{ display:flex; align-items:center; justify-content:space-between; margin-bottom:14px; position:relative; z-index:1; }
.stat-icon{
  width:44px; height:44px; border-radius:12px; display:flex; align-items:center; justify-content:center; flex-shrink:0;
  position:relative; z-index:1; margin-bottom:14px;
  background:var(--stat-accent-100, var(--info-100)); color:var(--stat-accent, var(--primary));
}
.stat-card.brand .stat-icon{ background:rgba(255,255,255,.18); color:#fff; }
.stat-icon svg{ width:21px; height:21px; }
.stat-change{ font-size:12px; font-weight:700; padding:3px 8px; border-radius:20px; display:flex; align-items:center; gap:3px; }
.stat-change.up{ color:var(--success); background:var(--success-100); }
.stat-change.down{ color:var(--danger); background:var(--danger-100); }
.stat-label{ color:var(--muted); font-size:12.5px; font-weight:600; position:relative; z-index:1; margin-bottom:2px; }
.stat-value{ font-size:28px; font-weight:800; font-family:'Merriweather',serif; letter-spacing:-.02em; position:relative; z-index:1; }
.stat-card.brand .stat-label{ color:rgba(255,255,255,.7); }
.stat-card.brand .stat-value{ color:#fff; }

.grid-2col{ display:grid; grid-template-columns:2fr 1fr; gap:18px; margin-bottom:22px; align-items:stretch; }

/* ------------------------- axis-based bar chart (SVG) -------------------- */
.barchart-svg{ width:100%; height:auto; display:block; overflow:visible; }
.barchart-svg .gridline{ stroke:var(--border); stroke-width:1; }
.barchart-svg .axis-label{ font-size:10.5px; fill:var(--muted-2); font-family:'Noto Sans',sans-serif; }
.barchart-svg .bar-label{ font-size:10.5px; fill:var(--muted); font-family:'Noto Sans',sans-serif; }
.barchart-svg .bar-link{ cursor:pointer; }
.barchart-svg .bar-rect{ fill:var(--primary); transition:opacity .15s ease; }
.barchart-svg .bar-link:hover .bar-rect{ opacity:.8; }
.barchart-svg .bar-link:hover .bar-label{ fill:var(--text); font-weight:700; }
.barchart-svg .bar-value{ font-size:10.5px; font-weight:700; fill:var(--text); font-family:'Noto Sans',sans-serif; text-anchor:middle; }

/* ------------------------------ donut / ring ------------------------------ */
.ring-chart{ display:flex; flex-direction:column; align-items:center; justify-content:center; gap:18px; flex:1; height:100%; }
.ring{
  width:160px; height:160px; border-radius:50%; flex-shrink:0;
  display:flex; align-items:center; justify-content:center; position:relative;
}
.ring-svg{ width:100%; height:100%; transform:rotate(-90deg); overflow:visible; }
.ring-track{ fill:none; stroke:var(--border); stroke-width:22; }
.ring-arc{
  fill:none; stroke-width:22; stroke-linecap:butt; cursor:pointer;
  transition:stroke-width .15s ease, opacity .15s ease;
  transform-origin:80px 80px;
}
.ring-arc:hover{ stroke-width:26; opacity:.92; }
.ring-legend{ display:flex; flex-wrap:wrap; justify-content:center; gap:14px 20px; }
.ring-legend-row{ display:flex; align-items:center; gap:7px; font-size:12.5px; font-weight:600; color:var(--muted); }
.ring-legend-row .dotc{ width:9px; height:9px; border-radius:50%; flex-shrink:0; }

/* --------------------------------- tables -------------------------------- */
.table-wrap{ overflow-x:auto; }
table{ width:100%; border-collapse:collapse; }
th{
  text-align:left; font-size:11px; text-transform:uppercase; letter-spacing:.06em;
  color:var(--muted-2); font-weight:700; padding:13px 20px; white-space:nowrap;
  background:var(--surface-2);
}
tbody tr{ transition:background .12s ease; }
tbody tr:hover{ background:var(--surface-2); }
td{ padding:14px 20px; font-size:13.5px; border-top:1px solid var(--border); vertical-align:middle; }
tr td:first-child, tr th:first-child{ padding-left:20px; }
tr td:last-child, tr th:last-child{ padding-right:20px; }
input[type=checkbox]{ width:16px; height:16px; accent-color:var(--primary); cursor:pointer; flex-shrink:0; }
.row-title{ display:flex; align-items:center; gap:12px; }
.row-thumb{
  width:40px; height:40px; border-radius:9px; flex-shrink:0; background:var(--primary-100); color:var(--primary-text);
  display:flex; align-items:center; justify-content:center; font-weight:700; font-size:13px;
}
.row-title-text{ font-weight:600; font-size:13.5px; }
.row-sub{ font-size:12px; color:var(--muted); margin-top:3px; }
.row-actions{ display:flex; gap:6px; }
.icon-mini{
  width:30px; height:30px; border-radius:8px; display:flex; align-items:center; justify-content:center;
  color:var(--muted); cursor:pointer; border:1px solid transparent; background:transparent;
}
.icon-mini:hover{ background:var(--surface-2); color:var(--text); }
.icon-mini.danger:hover{ background:var(--danger-100); color:var(--danger); }
.icon-mini svg{ width:15px; height:15px; }
.table-empty{ padding:40px 20px; text-align:center; color:var(--muted); }

/* --------------------------------- badges -------------------------------- */
.badge{
  display:inline-flex; align-items:center; gap:5px; padding:4px 10px; border-radius:20px;
  font-size:11.5px; font-weight:700; white-space:nowrap;
}
.badge .dotc{ width:6px; height:6px; border-radius:50%; background:currentColor; flex-shrink:0; }
.badge-primary{ background:var(--primary-100); color:var(--primary-text); }
.badge-success{ background:var(--success-100); color:var(--success); }
.badge-warning{ background:var(--warning-100); color:#B7860F; }
html[data-bs-theme="dark"] .badge-warning{ color:var(--warning); }
.badge-danger{ background:var(--danger-100); color:var(--danger); }
.badge-info{ background:var(--info-100); color:var(--info); }
.badge-neutral{ background:var(--surface-2); color:var(--muted); }

/* status pills used across submissions/webforms */
.status-new{ background:var(--warning-100); color:#C05F0F; }
html[data-bs-theme="dark"] .status-new{ color:var(--warning); }
.status-contacted{ background:var(--info-100); color:var(--info); }
.status-qualified{ background:var(--primary-100); color:var(--primary-text); }
.status-closed{ background:var(--success-100); color:var(--success); }
.status-rejected{ background:var(--danger-100); color:var(--danger); }
.status-published{ background:var(--success-100); color:var(--success); }
.status-draft{ background:var(--surface-2); color:var(--muted); }

/* --------------------------------- forms --------------------------------- */
.form-grid{ display:grid; grid-template-columns:1fr 1fr; gap:0px 18px; }
.field{ margin-bottom:18px; display:flex; flex-direction:column; gap:7px; }
.field.full{ grid-column:1/-1; }

/* FAQ manager two-pane layout (templates/faqs/list.html) and the field
   editor's own sub-grids (templates/webforms/_field_row.html) — pulled out
   of inline style="grid-template-columns:…" so they can actually collapse
   at tablet/mobile widths (an inline style would otherwise always beat the
   media-query rules above, regardless of specificity). */
.faq-manager-grid{ display:grid; grid-template-columns:320px 1fr; gap:0 18px; align-items:start; }
.field-row-grid{ display:grid; grid-template-columns:1.4fr 1fr; gap:10px; }
.field-row-detail-grid{ display:grid; grid-template-columns:1fr 1fr 130px auto; gap:10px; margin-top:10px; align-items:end; }

/* 12-column dynamic field layout, driven by WebFormField.width (1-12) — used
   by the public submission page, the builder's live preview and the
   webforms "view" modal so a field with width=4 next to one with width=8
   sit side by side in the same row, matching a Bootstrap-style col-N grid. */
.dynamic-form-grid{ display:grid; grid-template-columns:repeat(12, 1fr); gap:16px 14px; }
.dynamic-form-grid .field{ margin-bottom:0; min-width:0; }
@media(max-width:640px){ .dynamic-form-grid .field{ grid-column:span 12 !important; } }
.field label{
  display:flex; font-size:11.5px; font-weight:800; text-transform:uppercase; letter-spacing:.4px;
  color:var(--muted); align-items:center; gap:6px;
}
.field .hint{ font-weight:500; text-transform:none; letter-spacing:0; color:var(--muted-2); font-size:11px; }

/* Info-icon hover tooltip — used next to field-builder labels to explain
   what to enter, instead of a permanent caption line under the row. */
.field-hint{
  display:inline-flex; align-items:center; justify-content:center; width:15px; height:15px;
  border-radius:50%; background:var(--surface-2); color:var(--muted-2); cursor:help; position:relative; flex-shrink:0;
}
.field-hint svg{ width:10px; height:10px; }
.field-hint:hover{ background:var(--primary-100); color:var(--primary-text); }
.field-hint::after{
  content:attr(data-tooltip); position:absolute; bottom:calc(100% + 9px); left:50%; transform:translateX(-50%);
  background:var(--text); color:var(--bg); font-size:11.5px; font-weight:500; line-height:1.45;
  padding:8px 10px; border-radius:8px; width:220px; white-space:normal; text-align:left;
  box-shadow:var(--shadow-lg); z-index:60; pointer-events:none; opacity:0; visibility:hidden;
  transition:opacity .12s ease;
}
.field-hint::before{
  content:""; position:absolute; bottom:calc(100% + 4px); left:50%; transform:translateX(-50%);
  border:5px solid transparent; border-top-color:var(--text); z-index:60; pointer-events:none;
  opacity:0; visibility:hidden; transition:opacity .12s ease;
}
.field-hint:hover::after, .field-hint:hover::before{ opacity:1; visibility:visible; }

/* ------------------------------ file/image upload ------------------------------ */
.upload-row{ display:flex; align-items:stretch; gap:14px; }
.upload-box{
  flex:1; min-width:0; display:flex; flex-direction:column; align-items:center; justify-content:center;
  text-align:center; gap:5px; padding:26px 18px; border:1.5px dashed var(--border); border-radius:14px;
  background:var(--surface-2); cursor:pointer;
  transition:border-color .15s ease, background .15s ease, transform .15s ease;
}
.upload-box:hover{
  border-color:var(--primary-text); background:color-mix(in srgb, var(--primary-text) 7%, var(--surface-2));
  transform:translateY(-1px);
}
.upload-box input[type=file]{ display:none; }
.upload-box .upload-icon-wrap{
  width:40px; height:40px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  background:var(--primary-100); color:var(--primary-text); margin-bottom:4px; transition:transform .2s ease;
}
.upload-box:hover .upload-icon-wrap{ transform:translateY(-2px) scale(1.05); }
.upload-box.has-file .upload-icon-wrap{ background:var(--success-100); color:var(--success); }
.upload-box .upload-title{
  font-size:13.5px; font-weight:700; color:var(--text); text-transform:none; letter-spacing:normal;
}
.upload-box .upload-hint{
  font-size:11.5px; font-weight:500; color:var(--muted); text-transform:none; letter-spacing:normal;
}
.upload-thumb-wrap{
  position:relative; width:80px; height:80px; flex-shrink:0; border-radius:12px; overflow:visible;
  display:none;
}
.upload-thumb-wrap.show{ display:block; }
.upload-thumb-wrap img,
.upload-thumb-wrap .upload-thumb-fallback{
  width:100%; height:100%; border-radius:12px; object-fit:cover; border:1px solid var(--border); background:var(--surface-2);
  display:flex; align-items:center; justify-content:center; color:var(--muted);
}
.upload-thumb-close{
  position:absolute; top:-7px; right:-7px; width:20px; height:20px; border-radius:50%;
  background:var(--text); color:var(--bg); border:2px solid var(--surface); display:flex; align-items:center;
  justify-content:center; cursor:pointer; padding:0;
}
.upload-thumb-close svg{ width:10px; height:10px; }

/* Base input/select/textarea styling — intentionally NOT scoped to .field so
   every text/date/select control looks consistent wherever it's used
   (filter bars, inline table forms, etc.), not only inside a labeled field. */
input[type=text],input[type=url],input[type=email],input[type=tel],
input[type=password],input[type=date],input[type=time],input[type=number],input[type=search],
textarea,select{
  padding:12px 14px; border-radius:8px; border:1.5px solid var(--border);
  background:var(--surface-2); color:var(--text); font-size:13.5px; font-family:inherit; outline:none;
  transition:border-color .15s ease, background .15s ease, box-shadow .15s ease;
}
.field input[type=text],.field input[type=url],.field input[type=email],.field input[type=tel],
.field input[type=password],.field input[type=date],.field input[type=time],.field input[type=number],
.field textarea,.field select{ width:100%; }
input[type=color]{ height:42px; padding:3px; border-radius:8px; border:1.5px solid var(--border); background:var(--surface-2); }
input[type=file]{ font-size:12.5px; }
input:hover,textarea:hover,select:hover{ border-color:color-mix(in srgb, var(--primary) 35%, var(--border)); }
input:focus,textarea:focus,select:focus{
  border-color:var(--primary); background:var(--surface);
  box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 15%, transparent);
}
textarea{ resize:vertical; min-height:80px; }

/* ---------------------------- custom select ------------------------------ */
/* Every <select> is progressively enhanced (see initCustomSelects in
   scripts.js) into this button+listbox pair, since a native <select>'s open
   options popup can't be restyled with CSS in any browser. */
.csel{ position:relative; display:inline-block; }
.field .csel{ display:block; width:100%; }
.csel-native{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden;
  clip:rect(0,0,0,0); white-space:nowrap; border:0; opacity:0;
}
.csel-trigger{
  width:100%; display:inline-flex; align-items:center; justify-content:space-between; gap:10px;
  padding:12px 14px; border-radius:8px; border:1.5px solid var(--border);
  background:var(--surface-2); color:var(--text); font-size:13.5px; font-family:inherit;
  cursor:pointer; text-align:left; transition:border-color .15s ease, background .15s ease, box-shadow .15s ease;
}
.csel-trigger:hover{ border-color:color-mix(in srgb, var(--primary) 45%, var(--border)); }
.csel.open .csel-trigger, .csel-trigger:focus-visible{
  border-color:var(--primary); background:var(--surface); outline:none;
  box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 15%, transparent);
}
.csel-trigger:disabled{ opacity:.6; cursor:not-allowed; }
/* .badge/.status-* selects (e.g. the per-row status dropdown) keep their
   pill color instead of the default trigger's gray box — .csel-trigger and
   .badge/.status-* are equal CSS specificity, so without this the trigger's
   own background (declared later in this file) would otherwise win. */
.csel-trigger.badge{ width:auto; border:none; padding:4px 10px; }
.csel-trigger.status-new{ background:var(--warning-100); color:#C05F0F; }
html[data-bs-theme="dark"] .csel-trigger.status-new{ color:var(--warning); }
.csel-trigger.status-contacted{ background:var(--info-100); color:var(--info); }
.csel-trigger.status-qualified{ background:var(--primary-100); color:var(--primary-text); }
.csel-trigger.status-closed{ background:var(--success-100); color:var(--success); }
.csel-trigger.status-rejected{ background:var(--danger-100); color:var(--danger); }
.csel-value{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.csel-chevron{ display:flex; flex-shrink:0; color:var(--muted); transition:transform .2s ease; }
.csel.open .csel-chevron{ transform:rotate(180deg); }
.csel-menu{
  /* Reparented to <body> and positioned with inline top/left/width by
     initCustomSelects() in scripts.js — position:absolute relative to .csel
     would otherwise get clipped by any ancestor with overflow:hidden/auto
     (e.g. a scrollable .modal), so it's a "portal" element like .modal-backdrop.
     z-index is above .modal-backdrop's 200 so it can float over an open modal. */
  position:fixed; min-width:100%; z-index:250;
  background:var(--surface); border:1px solid var(--border); border-radius:12px;
  box-shadow:0 16px 40px rgba(0,20,45,.18); padding:6px; max-height:260px; overflow-y:auto;
  list-style:none; margin:0;
  opacity:0; transform:translateY(-6px) scale(.98); pointer-events:none;
  transition:opacity .16s ease, transform .16s ease;
}
.csel-menu.open{ opacity:1; transform:none; pointer-events:auto; }
.csel-option{
  padding:9px 12px; border-radius:8px; font-size:13.3px; color:var(--text); cursor:pointer;
  display:flex; align-items:center; justify-content:space-between; gap:10px;
}
.csel-option:hover, .csel-option.active{ background:var(--surface-2); }
.csel-option.selected{ color:var(--primary-text); font-weight:700; }
.csel-option.selected::after{
  content:""; width:7px; height:12px; flex-shrink:0;
  border-right:2px solid var(--primary); border-bottom:2px solid var(--primary); transform:rotate(45deg) translateY(-1px);
}
.csel-option.disabled{ color:var(--muted); cursor:not-allowed; opacity:.6; }
.field .errors{ color:var(--danger); font-size:12px; font-weight:600; }
.req{ color:var(--danger); }
.form-footer{
  display:flex; justify-content:space-between; align-items:center; margin-top:10px; padding-top:20px;
  border-top:1px solid var(--border); flex-wrap:wrap; gap:10px;
}
.helptext{ color:var(--muted); font-size:12px; margin-top:2px; }
.non-field-errors{
  background:var(--danger-100); color:var(--danger); padding:10px 14px; border-radius:10px;
  font-size:13px; font-weight:600; margin-bottom:16px;
}

/* --------------------------------- chips --------------------------------- */
.chip-select{ display:flex; flex-wrap:wrap; gap:8px; }
.chip-row{ display:flex; flex-wrap:wrap; gap:8px; margin-bottom:18px; }
.chip-opt{
  padding:7px 14px; border-radius:20px; font-size:12.5px; font-weight:700; cursor:pointer;
  border:1.5px solid var(--border); background:var(--surface); color:var(--text); user-select:none;
  transition:all .15s ease; display:inline-flex; align-items:center; gap:6px;
}
.chip-opt.selected{ background:var(--primary); border-color:var(--primary); color:#fff; }
.chip-manage{
  display:inline-flex; align-items:center; gap:8px; padding:7px 8px 7px 13px; border-radius:20px;
  font-size:12.5px; font-weight:600; border:1px solid var(--border); background:var(--surface); color:var(--text);
}
.chip-manage .chip-del{
  width:18px; height:18px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  color:var(--muted); cursor:pointer; flex-shrink:0; border:none; background:transparent;
}
.chip-manage .chip-del:hover{ background:var(--danger-100); color:var(--danger); }
.chip-manage .chip-del svg{ width:11px; height:11px; }

/* --------------------------------- tabs ---------------------------------- */
.status-tabs{ display:flex; gap:6px; padding:5px; background:var(--surface-2); border:1px solid var(--border); border-radius:12px; flex-wrap:wrap; }
.status-tab{
  padding:8px 15px; border-radius:8px; font-size:12.5px; font-weight:700; color:var(--muted); cursor:pointer;
  display:flex; align-items:center; gap:6px; border:none; background:transparent;
}
.status-tab .cnt{ font-size:10.5px; background:var(--border); color:var(--muted); border-radius:20px; padding:1px 6px; }
.status-tab.active{ background:var(--surface); color:var(--text); box-shadow:var(--shadow); }
.status-tab.active .cnt{ background:var(--primary); color:#fff; }

/* -------------------------------- filters --------------------------------- */
.filter-bar{ padding:16px 18px; margin-bottom:16px; }
.filter-row{ display:flex; gap:10px; flex-wrap:wrap; align-items:center; }
.filter-row + .filter-row{ margin-top:12px; }
.filter-search{ position:relative; flex:1 1 220px; min-width:0; }
.filter-search svg{ position:absolute; left:10px; top:14px; color:var(--muted); width:14px; height:14px; }
.filter-search input{ width:100%; padding-left:30px !important; }

/* -------------------------------- modal ----------------------------------- */
.modal-backdrop{
  position:fixed; inset:0; background:rgba(6,15,32,.55); backdrop-filter:blur(4px);
  display:none; align-items:center; justify-content:center; z-index:200; padding:16px;
}
.modal-backdrop.show{ display:flex; animation:modalBackdropIn .2s ease both; }
@keyframes modalBackdropIn{ from{ opacity:0; } to{ opacity:1; } }
@media (prefers-reduced-motion:reduce){ .modal-backdrop.show{ animation:none; } }

.modal{
  background:var(--surface); border-radius:20px; width:92vw; max-width:560px; max-height:88vh;
  overflow-y:auto; overflow-x:hidden;
  box-shadow:0 40px 90px rgba(0,10,30,.45), 0 0 0 1px rgba(255,255,255,.06);
}
.modal-backdrop.show .modal{ animation:modalIn .32s cubic-bezier(.22,.85,.32,1) both; }
@keyframes modalIn{
  from{ opacity:0; transform:scale(.92) translateY(18px); }
  to{ opacity:1; transform:scale(1) translateY(0); }
}
@media (prefers-reduced-motion:reduce){ .modal-backdrop.show .modal{ animation:none; } }
.modal.wide{ max-width:560px; }
.modal.narrow{ max-width:440px; }

.modal-head{
  display:flex; align-items:center; justify-content:space-between; gap:12px; padding:22px 26px;
  position:sticky; top:0; z-index:2; border-radius:20px 20px 0 0; overflow:hidden;
  background:linear-gradient(135deg, var(--primary) 0%, var(--primary-600) 100%);
}
.modal-head::before{
  content:""; position:absolute; top:-60px; right:-40px; width:160px; height:160px; border-radius:50%;
  background:radial-gradient(circle, rgba(255,255,255,.16) 0%, transparent 70%); pointer-events:none;
}
.modal-head h3{ font-size:17px; font-weight:800; color:#fff; position:relative; z-index:1; }
.modal-close{
  border:none; background:rgba(255,255,255,.16); border-radius:8px; width:30px; height:30px; cursor:pointer;
  color:#fff; display:flex; align-items:center; justify-content:center; flex-shrink:0; position:relative; z-index:1;
  transition:background .15s ease, transform .2s ease;
}
.modal-close:hover{ background:rgba(255,255,255,.3); transform:rotate(90deg); }
.modal-body{ padding:30px; }

/* -------------------------------- flash messages ---------------------------- */
.messages-stack{ position:fixed; top:16px; right:16px; z-index:400; display:flex; flex-direction:column; gap:10px; max-width:360px; }
.alert{
  display:flex; align-items:flex-start; gap:10px; padding:12px 14px; border-radius:12px;
  font-size:13px; font-weight:600; box-shadow:var(--shadow-lg); background:var(--surface); border:1px solid var(--border);
}
.alert-success{ background:var(--success-100); color:var(--success); border-color:transparent; }
.alert-danger{ background:var(--danger-100); color:var(--danger); border-color:transparent; }
.alert-warning{ background:var(--warning-100); color:#B7860F; border-color:transparent; }
html[data-bs-theme="dark"] .alert-warning{ color:var(--warning); }
.alert-info,.alert-debug{ background:var(--info-100); color:var(--info); border-color:transparent; }
.alert-close{ margin-left:auto; background:none; border:none; cursor:pointer; color:inherit; opacity:.7; flex-shrink:0; }
.alert-close:hover{ opacity:1; }

/* -------------------------------- toast ------------------------------------ */
.toast{
  position:fixed; bottom:24px; right:24px; background:var(--text); color:var(--bg);
  padding:14px 18px; border-radius:10px; font-size:13.5px; font-weight:600;
  box-shadow:var(--shadow-lg); display:flex; align-items:center; gap:10px; z-index:300;
  transform:translateY(30px); opacity:0; transition:all .3s ease; pointer-events:none;
}
.toast.show{ transform:translateY(0); opacity:1; }
.toast svg{ width:16px; height:16px; color:var(--success); flex-shrink:0; }

/* ---------------------------------- back to top ------------------------------ */
.back-to-top{
  position:fixed; right:24px; bottom:90px; z-index:150; width:44px; height:44px; border-radius:50%;
  border:1px solid var(--border); background:var(--surface); color:var(--primary-text);
  display:flex; align-items:center; justify-content:center; cursor:pointer; box-shadow:var(--shadow-lg);
  opacity:0; transform:translateY(10px); pointer-events:none;
  transition:opacity .2s ease, transform .2s ease, background .15s ease;
}
.back-to-top.show{ opacity:1; transform:none; pointer-events:auto; }
.back-to-top:hover{ background:var(--surface-2); }
.back-to-top svg{ width:18px; height:18px; }
@media (prefers-reduced-motion:reduce){ .back-to-top{ transition:opacity .2s ease; } }
@media (max-width:640px){ .back-to-top{ right:16px; bottom:78px; width:40px; height:40px; } }

/* ------------------------------- switch/toggle ------------------------------ */
.switch{ position:relative; width:42px; height:24px; flex-shrink:0; display:inline-block; }
.switch input{ opacity:0; width:0; height:0; }
.slider{ position:absolute; inset:0; background:var(--border); border-radius:20px; cursor:pointer; transition:.2s; }
.slider:before{ content:""; position:absolute; width:18px; height:18px; left:3px; top:3px; background:#fff; border-radius:50%; transition:.2s; box-shadow:0 1px 3px rgba(0,0,0,.25); }
.switch input:checked + .slider{ background:var(--warning); }
.switch input:checked + .slider:before{ transform:translateX(18px); }
.switch input:disabled + .slider{ opacity:.5; cursor:not-allowed; }

/* -------------------------------- empty state -------------------------------- */
.empty-page{ display:flex; flex-direction:column; align-items:center; justify-content:center; padding:70px 20px; text-align:center; color:var(--muted); }
.empty-page svg{ width:52px; height:52px; margin-bottom:16px; opacity:.5; }
.empty-page h3{ color:var(--text); margin:0 0 6px; }
.empty-page p{ margin:0; font-size:13.5px; max-width:340px; }

/* -------------------------------- misc utils -------------------------------- */
.flex{ display:flex; }
.flex-col{ display:flex; flex-direction:column; }
.items-center{ align-items:center; }
.justify-between{ justify-content:space-between; }
.gap-6{ gap:6px; } .gap-8{ gap:8px; } .gap-10{ gap:10px; } .gap-14{ gap:14px; } .gap-18{ gap:18px; }
.mb-0{ margin-bottom:0 !important; }
.text-muted{ color:var(--muted); }
.text-sub{ font-size:12.5px; color:var(--muted); }
.w-full{ width:100%; }
.divider{ height:1px; background:var(--border); margin:14px 0; }

/* -------------------------------- auth page -------------------------------- */
.auth-shell{ min-height:100vh; display:flex; align-items:center; justify-content:center; background:var(--bg); padding:20px; }
.auth-card{ width:420px; max-width:100%; padding:40px 36px; text-align:center; }
.auth-card img.logo-full{ height:40px; width:auto; margin:0 auto 18px; display:block; object-fit:contain; }
html[data-bs-theme="dark"] .auth-card img.logo-full-light{ display:none; }
html:not([data-bs-theme="dark"]) .auth-card img.logo-full-dark{ display:none; }
.auth-card h1{ font-size:20px; margin-bottom:6px; }
.auth-card .sub{ font-size:13.5px; color:var(--muted); margin-bottom:26px; }
.auth-card form{ text-align:left; }
.auth-remember{ display:flex; align-items:center; justify-content:space-between; margin:-6px 0 18px; font-size:12.5px; }
.auth-remember label{ display:flex; align-items:center; gap:7px; color:var(--muted); font-weight:600; cursor:pointer; }

/* Sign in / forgot / reset / verify-otp pages opt into this richer look via
   an extra class — plain .auth-shell stays untouched since public_form.html
   (webform submission page) reuses it too and shouldn't get a dark banner.
   Deliberately light/airy (not the site-footer's dark gradient) so the two
   don't blend into one panel when a footer sits directly below the shell. */
.auth-shell-branded{
  position:relative; overflow:hidden; isolation:isolate;
  background:
    radial-gradient(ellipse 760px 520px at 10% 8%, color-mix(in srgb, var(--primary) 16%, transparent) 0%, transparent 62%),
    radial-gradient(ellipse 640px 520px at 92% 94%, color-mix(in srgb, var(--warning) 16%, transparent) 0%, transparent 62%),
    var(--bg);
}
.auth-shell-branded::before{
  content:""; position:absolute; inset:0; z-index:0; opacity:.7; pointer-events:none;
  background-image:radial-gradient(circle at 1px 1px, color-mix(in srgb, var(--text) 10%, transparent) 1px, transparent 0);
  background-size:26px 26px;
}
.auth-blob{
  position:absolute; border-radius:50%; filter:blur(80px); opacity:.28; z-index:0; pointer-events:none;
  animation:authBlobFloat 16s ease-in-out infinite alternate;
}
.auth-blob.b1{ width:340px; height:340px; background:#5ea3ff; top:-120px; left:-80px; }
.auth-blob.b2{ width:280px; height:280px; background:#ffb648; bottom:-100px; right:-60px; animation-duration:20s; animation-delay:-6s; }
.auth-blob.b3{ width:220px; height:220px; background:#7fe8c0; top:38%; right:6%; animation-duration:14s; animation-delay:-10s; }
@keyframes authBlobFloat{ 0%{ transform:translate(0,0) scale(1); } 100%{ transform:translate(26px,-20px) scale(1.1); } }
@media (prefers-reduced-motion:reduce){ .auth-blob{ animation:none; } }
@keyframes authCardIn{ from{ opacity:0; transform:translateY(20px) scale(.96); } to{ opacity:1; transform:none; } }

/* ------------------- sign-in / forgot-password swap card ------------------ */
/* Both forms live in the DOM at once (accounts/templates/user_auth.html);
   .auth-swap-link clicks just toggle .auth-right-active on #authSwapCard
   (see initAuthSwap in scripts.js) so the accent panel + forms slide across
   without a page reload. Falls back to a normal link navigation (server
   renders the right state via url_name) if JS never runs. */
.auth-card-split{
  position:relative; width:760px; max-width:100%; min-height:480px;
  display:flex; padding:0; overflow:hidden;
  animation:authCardIn .5s cubic-bezier(.22,.85,.32,1) both;
}
.auth-shell-branded .auth-card-split,
.auth-shell-branded .auth-static-split{
  box-shadow:0 30px 70px -10px rgba(20,30,60,.25), 0 8px 24px rgba(20,30,60,.12);
}
.auth-form-panel{
  position:absolute; top:0; left:0; width:50%; height:100%; padding:48px 46px;
  display:flex; flex-direction:column; justify-content:center; text-align:left;
  transition:transform .6s cubic-bezier(.65,0,.35,1), opacity .45s ease;
}
.auth-form-panel img.logo-full{ height:32px; width:auto; margin-bottom:18px; display:block; object-fit:contain; }
html[data-bs-theme="dark"] .auth-form-panel img.logo-full-light{ display:none; }
html:not([data-bs-theme="dark"]) .auth-form-panel img.logo-full-dark{ display:none; }
.auth-form-panel h1{ font-size:20px; margin-bottom:6px; }
.auth-form-panel .sub{ font-size:13.5px; color:var(--muted); margin-bottom:24px; }
.auth-panel-signin{ z-index:2; }
.auth-panel-forgot{ z-index:1; opacity:0; pointer-events:none; }
.auth-card-split.auth-right-active .auth-panel-signin{ transform:translateX(100%); opacity:0; pointer-events:none; z-index:1; }
.auth-card-split.auth-right-active .auth-panel-forgot{ transform:translateX(100%); opacity:1; pointer-events:auto; z-index:5; }

.auth-accent{
  position:absolute; top:0; left:50%; width:50%; height:100%; overflow:hidden; z-index:10;
  background:linear-gradient(150deg, #061428 0%, var(--primary-600) 55%, var(--primary) 100%);
  transition:transform .6s cubic-bezier(.65,0,.35,1);
}
.auth-accent::before{
  content:""; position:absolute; inset:0; z-index:0; opacity:.5; pointer-events:none;
  background-image:radial-gradient(circle at 1px 1px, rgba(255,255,255,.14) 1px, transparent 0);
  background-size:26px 26px;
}
.auth-accent-shape{ position:absolute; border-radius:50%; filter:blur(60px); opacity:.35; z-index:0; pointer-events:none; animation:authBlobFloat 16s ease-in-out infinite alternate; }
.auth-accent-shape.s1{ width:220px; height:220px; background:#5ea3ff; top:-70px; left:15%; }
.auth-accent-shape.s2{ width:180px; height:180px; background:#7fe8c0; bottom:-60px; right:5%; animation-duration:20s; animation-delay:-6s; }
.auth-card-split.auth-right-active .auth-accent{ transform:translateX(-100%); }

.auth-accent-panel{
  position:absolute; inset:0; z-index:1; padding:44px 38px;
  display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center;
  color:#fff; transition:opacity .35s ease, transform .45s ease;
}
.auth-accent-panel svg{ width:38px; height:38px; margin-bottom:16px; opacity:.9; }
.auth-accent-panel h2{ font-family:'Merriweather',serif; font-size:19px; margin-bottom:10px; }
.auth-accent-panel p{ font-size:13px; line-height:1.6; opacity:.85; margin-bottom:22px; }
.auth-accent-panel .btn{ background:transparent; border:1.5px solid rgba(255,255,255,.7); color:#fff; }
.auth-accent-panel .btn:hover{ background:rgba(255,255,255,.12); border-color:#fff; }
.auth-accent-signin{ opacity:1; transform:none; transition-delay:.2s; }
.auth-accent-forgot{ opacity:0; transform:translateY(10px); pointer-events:none; }
.auth-card-split.auth-right-active .auth-accent-signin{ opacity:0; transform:translateY(-10px); pointer-events:none; transition-delay:0s; }
.auth-card-split.auth-right-active .auth-accent-forgot{ opacity:1; transform:none; pointer-events:auto; transition-delay:.2s; }

@media (prefers-reduced-motion:reduce){
  .auth-card-split{ animation:none; }
  .auth-form-panel, .auth-accent, .auth-accent-panel, .auth-accent-shape{ transition:none; animation:none; }
}
@media (max-width:680px){
  .auth-card-split{ display:block; width:420px; min-height:0; }
  .auth-accent{ display:none; }
  .auth-form-panel{ position:static; width:100%; padding:40px 32px; transform:none !important; opacity:1 !important; pointer-events:auto !important; transition:none; }
  .auth-panel-forgot{ display:none; }
  .auth-card-split.auth-right-active .auth-panel-signin{ display:none; }
  .auth-card-split.auth-right-active .auth-panel-forgot{ display:flex; }
}

/* ------------- static split card (reset-password / verify-otp) ------------ */
/* Same two-tone look as .auth-card-split but no swap partner, so it's a
   plain flex layout instead of the absolutely-positioned sliding version. */
.auth-static-split{
  width:760px; max-width:100%; display:flex; overflow:hidden; padding:0;
  animation:authCardIn .5s cubic-bezier(.22,.85,.32,1) both;
}
.auth-static-form{ width:50%; padding:48px 46px; display:flex; flex-direction:column; justify-content:center; text-align:left; }
.auth-static-form img.logo-full{ height:32px; width:auto; margin-bottom:18px; display:block; object-fit:contain; }
html[data-bs-theme="dark"] .auth-static-form img.logo-full-light{ display:none; }
html:not([data-bs-theme="dark"]) .auth-static-form img.logo-full-dark{ display:none; }
.auth-static-form h1{ font-size:20px; margin-bottom:6px; }
.auth-static-form .sub{ font-size:13.5px; color:var(--muted); margin-bottom:24px; }
.auth-static-accent{
  width:50%; position:relative; overflow:hidden; isolation:isolate;
  background:linear-gradient(150deg, #061428 0%, var(--primary-600) 55%, var(--primary) 100%);
  display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center;
  padding:44px 38px; color:#fff;
}
.auth-static-accent::before{
  content:""; position:absolute; inset:0; z-index:0; opacity:.5; pointer-events:none;
  background-image:radial-gradient(circle at 1px 1px, rgba(255,255,255,.14) 1px, transparent 0);
  background-size:26px 26px;
}
.auth-static-accent > *{ position:relative; z-index:1; }
.auth-static-accent svg{ width:38px; height:38px; margin-bottom:16px; opacity:.9; }
.auth-static-accent h2{ font-family:'Merriweather',serif; font-size:19px; margin-bottom:10px; }
.auth-static-accent p{ font-size:13px; line-height:1.6; opacity:.85; }

@media (prefers-reduced-motion:reduce){ .auth-static-split{ animation:none; } .auth-static-accent .auth-accent-shape{ animation:none; } }
@media (max-width:680px){
  .auth-static-split{ display:block; width:420px; }
  .auth-static-accent{ display:none; }
  .auth-static-form{ width:100%; }
}

/* --------------------------- public webform hero --------------------------- */
/* Header banner on the public submission page (webforms/public_form.html):
   the form's own image with its name/description overlaid on it, if it has
   one — else the campus color as background with the same name/description
   printed directly on it. When a campus image exists, it appears as a small
   round badge (image case: overlapping the bottom of the banner; text case:
   sitting inline above the title). */
.form-hero{ position:relative; width:100%; min-height:150px; display:flex; align-items:center; justify-content:center; }
.form-hero-img{ width:100%; height:220px; object-fit:cover; display:block; }
.form-hero-overlay{
  position:absolute; left:0; right:0; bottom:0; padding:20px 34px 50px; z-index:1;
  background:linear-gradient(180deg, transparent 0%, rgba(0,0,0,.5) 45%, rgba(0,0,0,.88) 100%);
}
.form-hero-overlay h1{
  font-family:'Merriweather',serif; font-size:21px; font-weight:800; margin:0 0 6px;
  text-shadow:0 1px 4px rgba(0,0,0,.5);
}
.form-hero-overlay .form-hero-desc{ text-shadow:0 1px 3px rgba(0,0,0,.5); }
.form-hero-badge{
  position:absolute; right:24px; bottom:-40px; width:84px; height:84px; border-radius:18px; overflow:hidden;
  display:flex; align-items:center; justify-content:center; border:3px solid var(--surface); box-shadow:var(--shadow); z-index:2;
}
.form-hero-badge img{ width:100%; height:100%; object-fit:contain; }
.form-hero-body{ padding:32px 34px; }
.form-hero-body.has-badge{ padding-top:60px; }

/* Text-only hero — shown instead of an image when the webform has none: just
   the campus color as background with the webform's own text_color (set in
   the builder) so the title/description stay legible on it, no extra badge. */
.form-hero-text{ flex-direction:column; align-items:flex-start; justify-content:center; padding:30px 34px; }
.form-hero-text h1{ font-family:'Merriweather',serif; font-size:22px; font-weight:800; margin:0 0 8px; }
.form-hero-desc{ font-size:14px; line-height:1.55; opacity:.9; }

/* Shared with the homepage hero blobs (static/css/pages/style.css) — defined
   here too so the footer's floating blobs still animate on pages that don't
   load the homepage's stylesheet (login, public webforms, error pages). */
@keyframes heroBlobFloat{
  0%{ transform:translate(0,0) scale(1); }
  100%{ transform:translate(30px,-24px) scale(1.12); }
}

/* ------------------------------- site footer -------------------------------- */
.site-footer{
  position:relative; overflow:hidden; isolation:isolate;
  background:linear-gradient(160deg, #061428 0%, var(--primary-600) 55%, var(--primary) 100%);
  color:rgba(255,255,255,.82);
}
.site-footer::before{
  content:""; position:absolute; inset:0; z-index:0; opacity:.5;
  background-image:radial-gradient(circle at 1px 1px, rgba(255,255,255,.12) 1px, transparent 0);
  background-size:22px 22px;
}
.footer-blob{
  position:absolute; border-radius:50%; filter:blur(80px); opacity:.28; z-index:0;
  animation:heroBlobFloat 18s ease-in-out infinite alternate;
}
.footer-blob.f1{ width:360px; height:360px; background:#5ea3ff; top:-140px; left:-80px; }
.footer-blob.f2{ width:320px; height:320px; background:#7fe8c0; bottom:-160px; right:-60px; animation-duration:22s; animation-delay:-6s; }

.site-footer-inner{
  position:relative; z-index:1; max-width:1180px; margin:0 auto; padding:56px 24px 32px;
  display:grid; grid-template-columns:1.4fr 1fr 1fr 1fr; gap:28px;
}
.site-footer-col{ display:flex; flex-direction:column; gap:10px; font-size:13px; }
.site-footer-brand{ font-family:'Merriweather',serif; font-weight:800; font-size:16px; color:#fff; margin-bottom:2px; }
.site-footer-col p{ margin:0; color:rgba(255,255,255,.62); line-height:1.6; }
.site-footer-head{ font-size:11.5px; font-weight:800; text-transform:uppercase; letter-spacing:.6px; color:rgba(255,255,255,.4); margin-bottom:2px; }
.site-footer-col a{ color:rgba(255,255,255,.82); transition:color .2s ease, transform .2s ease; width:fit-content; }
.site-footer-col a:hover{ color:#7fe8c0; transform:translateX(3px); }
.site-footer-app{ display:flex; align-items:center; gap:8px; }
.site-footer-social{
  position:relative; z-index:1; max-width:1180px; margin:0 auto; padding:4px 24px 28px; display:flex; align-items:center; gap:14px;
  font-size:12.5px; color:rgba(255,255,255,.55); font-weight:600;
}
.site-footer-social a{
  width:36px; height:36px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  background:rgba(255,255,255,.08); border:1px solid rgba(255,255,255,.16); color:rgba(255,255,255,.75);
  backdrop-filter:blur(6px); transition:all .25s ease;
}
.site-footer-social a:hover{
  color:#fff; border-color:#7fe8c0; background:rgba(127,232,192,.18);
  transform:translateY(-3px); box-shadow:0 8px 20px rgba(127,232,192,.25);
}
.site-footer-bottom{
  position:relative; z-index:1; text-align:center; padding:18px 24px; font-size:11.5px; color:rgba(255,255,255,.5);
  border-top:1px solid rgba(255,255,255,.12);
}
.site-footer-bottom a{ color:rgba(255,255,255,.85); font-weight:700; text-decoration:underline; }
.site-footer-bottom a:hover{ color:#7fe8c0; }
@media (prefers-reduced-motion:reduce){ .footer-blob{ animation:none; } }
@media (max-width:820px){
  .site-footer-inner{ grid-template-columns:1fr 1fr; }
  .public-header-inner{ padding:12px 16px; gap:14px; }
}
@media (max-width:520px){
  .site-footer-inner{ grid-template-columns:1fr; padding:40px 18px 24px; }
  .site-footer-social{ padding:4px 18px 22px; }
  .site-footer-bottom{ padding:16px 18px; }
}

/* =====================================================================
   RESPONSIVE OVERRIDES — kept together at the very end of this file on
   purpose. CSS resolves same-specificity ties by source order, and almost
   every rule below shares its selector's specificity with that selector's
   own base definition earlier in this file (e.g. .grid-stats, .grid-2col,
   .stat-card, .modal, .page-head…). If these overrides lived earlier in
   the file (as an earlier pass of this file mistakenly had them, right
   after the layout section), the later base rule would always win the
   cascade regardless of viewport — silently no-opping the whole block on
   every screen size. Keep ANY new responsive rule added in the future
   down here too, after its target's base rule, or it will suffer the same
   fate.
   ===================================================================== */
@media(max-width:1100px){
  .grid-stats{ grid-template-columns:repeat(2,1fr); }
  .hero-grid{ grid-template-columns:1fr; }
  .grid-2col{ grid-template-columns:1fr; }
  .form-grid{ grid-template-columns:1fr; }
  .schedule-row{ grid-template-columns:1fr 1fr; }
  .mini-grid{ grid-template-columns:1fr; }
  .settings-grid-stats-3{ grid-template-columns:repeat(2,1fr) !important; }
  .faq-manager-grid{ grid-template-columns:220px 1fr !important; }
}
@media(max-width:820px){
  .sidebar{ transform:translateX(-100%); }
  .sidebar.open{ transform:translateX(0); }
  .main{ margin-left:0; }
  .sidebar.collapsed ~ .main{ margin-left:0; }
  /* Scoped to a direct .topbar child so this doesn't also hide the search
     form reused inside #mobileSearchModal (same .search-box class, but
     nested in a modal, not the topbar). */
  .topbar > .search-box{ display:none; }
  .sidebar-brand{ justify-content:space-between; }
  .sidebar-brand .drawer-close-btn{ display:flex; }
  .grid-stats{ grid-template-columns:1fr; }
  .settings-grid-stats-3{ grid-template-columns:1fr !important; }
  .content-shell{ margin:0 12px 12px; border-radius:20px; }
  .content{ padding:22px 18px 44px; }
  .faq-manager-grid{ grid-template-columns:1fr !important; }
  .field-row-detail-grid{ grid-template-columns:1fr 1fr !important; }
}
@media(max-width:640px){
  /* Shrink every icon/button in the topbar clusters (dashboard topbar AND
     the public header — logo, hamburger, theme toggle, quick actions, bell,
     avatar) so the whole row comfortably fits a phone screen instead of
     crowding/overflowing it. */
  .topbar{ padding:0 12px; gap:8px; }
  .topbar-right{ gap:3px; }
  .public-header-inner{ padding:10px 12px; gap:10px; }
  .public-header-right{ gap:3px; }
  .icon-btn{ width:32px; height:32px; border-radius:7px; }
  .icon-btn svg{ width:15px; height:15px; }
  .public-brand{ gap:6px; }
  .public-brand img.logo-mark{ width:38px; height:auto; border-radius:8px; }
  .theme-toggle{ padding:3px; gap:2px; }
  .theme-toggle button{ width:26px; height:26px; border-radius:6px; }
  .theme-toggle button svg{ width:13px; height:13px; }
  .avatar{ width:28px; height:28px; border-radius:7px; font-size:11.5px; }
  .topbar-divider{ display:none; }
  .dot{ width:6px; height:6px; top:6px; right:7px; }

  .public-utility-inner{ padding:7px 12px; gap:8px; }
  .utility-links a:not(.utility-admissions-btn) span{ display:none; }
  .utility-links{ gap:12px; }
  .utility-divider{ display:none; }
  .utility-back span{ display:none; }
  .utility-admissions-btn{ padding:6px 12px; }

  .page-head{ flex-direction:column; align-items:stretch; gap:14px; margin-bottom:22px; padding:2px 0 20px 16px; }
  .page-head h1{ font-size:22px; }
  .flex{ flex-wrap:wrap; }

  /* .compact-card marks the templates' one-off "bare" cards that carry their
     own inline padding directly on .card (not the .card-head/.card-body
     structured ones, which would break — the head's border would no longer
     span edge-to-edge if .card itself gained padding too). */
  .compact-card{ padding:14px !important; }
  .form-hero-body{ padding:22px 18px; }
  .form-hero-body.has-badge{ padding-top:48px; }
  .form-hero-overlay{ padding:16px 18px 40px; }
  .form-hero-text{ padding:22px 18px; }
  .card-head{ padding:14px 16px; }
  .card-body{ padding:14px; }
  .stat-card{ padding:16px; }
  .settings-card{ padding:2px 14px !important; }
  .filter-bar{ padding:12px 14px; }
  .empty-page{ padding:44px 16px; }

  .modal{ border-radius:16px; }
  .modal-head{ padding:16px 18px; }
  .modal-body{ padding:16px; }

  .notif-row-outer{ flex-wrap:wrap; }

  .form-grid{ gap:0; }
  .field-row-grid, .field-row-detail-grid{ grid-template-columns:1fr !important; }

  th, td{ padding:10px 12px; }
  .filter-row{ gap:8px; }
  .status-tabs{ width:100%; }
}
@media(max-width:480px){
  .content{ padding:16px 12px 36px; }
  .content-shell{ margin:0 8px 8px; border-radius:16px; }
  .grid-stats{ gap:12px; }
  .stat-value{ font-size:23px; }
  .modal-backdrop{ padding:10px; }
  .modal{ width:100%; }
}

/* .menu-panel (quick actions / notifications / profile dropdowns in the
   topbar) is normally position:absolute, anchored via right:0 to whichever
   icon-btn triggered it (see .menu-wrap). On a narrow phone the trigger
   sits close to the screen's right edge, so a 280–340px-wide panel
   anchored there overflows off the LEFT edge of the viewport and gets
   clipped — hence text like "Quick actions" reading as "k actions". Below
   640px it switches to position:fixed, which re-anchors it to the
   viewport itself instead of the trigger, so it can be pinned to a safe
   margin on both sides regardless of which icon opened it. */
@media(max-width:640px){
  .menu-panel{ position:fixed; top:calc(var(--topbar-height) + 8px); left:12px; right:12px; width:auto; max-width:none; }
  #notificationsMenu{ width:auto; }
}
/* .public-nav .menu-panel (campus dropdowns inside the mobile nav drawer)
   already gets its own static, full-width treatment — more specific than
   the rule above, so it isn't affected by it. */

@media(max-width:640px){
  .detail-header{ flex-direction:column; align-items:stretch; gap:14px; padding:2px 0 20px 16px; margin-bottom:24px; }
  .detail-header > div:first-child{ flex:none; }
  .detail-header-actions{ width:100%; }
}
