/* ============================================================
Divlon Phish — themed Divlon Phish admin UI
Engine untouched. Linked AFTER divlon-phish.css; overrides the
visual layer (Bootstrap/Divlon Phish classes) only.

   Three themes (toggle = body class):
     soft   -> body.theme-soft     (DEFAULT, 261017/261018: curved content
                                     pane + dark red-to-black sidebar, red
                                     brand — mirrors Divlon-Comply's
                                     theme-soft corner-curve geometry)
     navy   -> body.theme-navy     (blue-tinted dark, red accent)
     black  -> body.theme-black    (pure black, red accent)

   261018: the White/light-mode theme was removed (deleted outright, not
   just hidden) and Soft became the default. All of Soft's shape language
   — rounded corners, the type scale, table header/row treatment, button
   softened shadows, the breadcrumb, the pane curve, the rounded active-nav
   pill — is now GLOBAL (every rule below applies to all three themes),
   driven entirely by each theme's own --d-* colour variables. The ONLY
   designed visual difference between the dark themes (Navy/Black) and
   Soft is the backdrop texture: Navy/Black keep the grid-line background,
   Soft has its own gradient wash (both still declared per-theme below,
   same as before). Where a rule needs a colour that only Soft defines
   (--d-sidebar-top/--d-sidebar-bottom, the gradient stops; --d-pane, the
   content pane's own surface colour), it falls back to each theme's
   existing --d-sidebar-bg / --d-panel-2 via CSS var() fallback syntax —
   on Navy/Black that makes the "gradient" collapse to the same flat
   colour they always had, so nothing about their sidebar actually
   changes, only panels/buttons/tables/type/breadcrumb/pane-curve do.
   ============================================================ */

/* ---- BLACK ---- */
:root,
body.theme-black{
  --d-bg:#0c0c0c;
  --d-panel:rgba(10,10,10,0.92);
  --d-panel-2:#0e0e0e;
  --d-border:#1c1c1c;
  --d-border-soft:rgba(255,255,255,0.06);
  --d-border-strong:#2e2e2e;
  --d-input-bg:#111111;
  --d-input-bg-blur:rgba(17,17,17,0.82);
  --d-input-border:#1e1e1e;
  --d-text:#e6e6e6;
  --d-text-strong:#ffffff;
  --d-muted:#9a9a9a;
  --d-red:#ea384c;
  --d-red-2:#b83535;
  /* Derived red tokens (Phase 8 D-01/D-02): --d-red-rgb powers rgba()
     alpha washes/shadows without re-stating the hex; --d-grad-primary is
     the shared 135deg brand gradient (.btn-primary/.btn-blue) extracted
     to one definition so every consumer stays in sync if the brand red
     is ever retuned. Same literal values in all three theme blocks,
     since --d-red is #ea384c everywhere today. */
  --d-red-rgb:234,56,76;
  --d-grad-primary:linear-gradient(135deg,#ea384c 0%,#b83535 100%);
  /* Alert/flash accent tokens (Phase 8 D-17): same derived-token pattern as
     --d-red-rgb above (hex + its -rgb companion, co-located, defined in
     all three theme blocks) so .alert-success/.alert-warning/.alert-info
     never fall back to a hardcoded literal outside this block. Same
     literal values across all three themes, matching how --d-red itself
     is identical in every theme block today. */
  --d-green:#2e7d32;
  --d-green-rgb:46,125,50;
  --d-amber:#b8860b;
  --d-amber-rgb:184,134,11;
  --d-blue:#1f6feb;
  --d-blue-rgb:31,111,235;
  --d-grid:rgba(255,255,255,0.04);
  --d-navbar-bg:#0a0a0a;
  --d-sidebar-bg:#0a0a0a;
  /* Pane surface, distinct from --d-bg (261018): without a visible gap
     between backdrop and pane colour the curve/fillet is invisible —
     --d-panel-2 was nearly identical to --d-bg here. A touch lighter so
     the curve actually reads, same way Soft's --d-pane works. */
  --d-pane:#131313;
  --d-sidebar-border:#2e2e2e;
  --d-sidebar-text:#d1d5db;
  --d-active-bg:#ea384c;
  --d-active-text:#ffffff;
  --d-nav-btn-border:rgba(255,255,255,0.16);
  --d-chart-red:#ea384c;
  --d-chart-fill:rgba(234,56,76,0.18);
  /* Shape system (261018, was Soft-only): shared by all three themes. */
  --d-r-sm:8px;
  --d-r-md:10px;
  --d-r-lg:14px;
  --d-r-xl:24px;
  /* Spacing scale (Phase 8 D-04, net-new): theme-independent, so defined
     once here rather than duplicated into the navy/soft blocks (matching
     how the --d-r-* radius scale above is itself only declared once).
     Snapped to read cleanly against that 8/10/14/24 radius rhythm,
     modeled on Divlon-Comply's 8px label-gap / 16px row-gap / 24px
     modal-padding structural pattern (re-themed values only, per D-01 —
     no Comply hex was copied). */
  --d-space-xs:4px;
  --d-space-sm:8px;
  --d-space-md:16px;
  --d-space-lg:24px;
  --d-space-xl:32px;
}
/* Reusable field wrapper (D-04), powered by the spacing scale above.
   Consumed by Phase 8's later form-spacing/login/pill-toggle plans
   (08-04/08-05) — defined once here, not per-template. */
.dp-field{margin-bottom:var(--d-space-md);}
.dp-field label{display:block;margin-bottom:var(--d-space-xs);}

/* Reusable segmented pill-toggle (D-08): two ordinary small buttons in a
   flex row, NOT a true pill shape (radius matches --d-r-md, the same
   token every other button uses) — Divlon-Comply's own source uses the
   same button-radius despite the "pill" name. A hidden-but-focusable
   native radio/checkbox backs each .dp-seg-btn for a11y/form-submission;
   position:absolute + opacity:0 keeps it tabbable (unlike display:none,
   which would drop it from the tab order and the toggle's underlying
   form value with it). First concrete adoption lands in 08-07. */
.dp-segment{display:flex;gap:var(--d-space-sm);}
.dp-seg-btn{
  position:relative;display:inline-flex;align-items:center;justify-content:center;
  padding:4px 12px;font-size:13px;font-weight:500;line-height:20px;
  border:1px solid var(--d-border);border-radius:var(--d-r-md);
  background:transparent;color:var(--d-text);cursor:pointer;
  transition:background-color .15s,color .15s,border-color .15s;
}
.dp-seg-btn:hover{border-color:var(--d-red);color:var(--d-text-strong);}
.dp-seg-btn[aria-pressed="true"]{background:var(--d-red);color:#fff;border-color:var(--d-red);}
.dp-seg-input{position:absolute;opacity:0;width:0;height:0;}

/* Scoped header layout for the training-picker Swal.fire dialog (D-11):
   the only one of the 37 dialogs that needs a row header (title left,
   difficulty selector right) instead of the shared column/centered
   .swal2-header base. Applied via customClass in 08-07 — never global. */
.dp-training-header{flex-direction:row!important;justify-content:space-between!important;align-items:center!important;}

/* ---- NAVY (blue-tinted dark, red accent) ---- */
body.theme-navy{
  --d-bg:#1a1f2c;
  --d-panel:rgba(22,27,39,0.92);
  --d-panel-2:#161b27;
  --d-border:#2a3650;
  --d-border-soft:rgba(255,255,255,0.05);
  --d-border-strong:#2a3650;
  --d-input-bg:#1c2333;
  --d-input-bg-blur:rgba(28,35,51,0.82);
  --d-input-border:#2a3650;
  --d-text:#f1f5f9;
  --d-text-strong:#ffffff;
  --d-muted:#94a3b8;
  --d-red:#ea384c;
  --d-red-2:#d02d40;
  --d-red-rgb:234,56,76;
  --d-grad-primary:linear-gradient(135deg,#ea384c 0%,#b83535 100%);
  --d-green:#2e7d32;
  --d-green-rgb:46,125,50;
  --d-amber:#b8860b;
  --d-amber-rgb:184,134,11;
  --d-blue:#1f6feb;
  --d-blue-rgb:31,111,235;
  --d-grid:rgba(255,255,255,0.035);
  --d-navbar-bg:#121621;
  --d-sidebar-bg:#121621;
  /* Pane surface (261018): --d-panel-2 was DARKER than --d-bg here (wrong
     direction for a curve to read against), so the sidebar also darkened
     a notch to keep it visibly separate from the now-lighter pane. */
  --d-pane:#20263b;
  --d-sidebar-border:#2a3650;
  --d-sidebar-text:#cbd5e1;
  --d-active-bg:#ea384c;
  --d-active-text:#ffffff;
  --d-nav-btn-border:rgba(255,255,255,0.16);
  --d-chart-red:#ea384c;
  --d-chart-fill:rgba(234,56,76,0.18);
}

/* ---- SOFT (DEFAULT) — curved, dark red-to-black sidebar, red brand ----
   Content area (navbar/panels/forms/tables) is light with dark graphite
   text; the sidebar is its own opaque dark red-to-black gradient
   (--d-sidebar-top/--d-sidebar-bottom) with light text, same light-on-dark
   pattern as Navy/Black. --d-pane is the content pane's own background
   (distinct from --d-bg) so the corner-fillet curve has a visible edge to
   read against. */
body.theme-soft{
  --d-bg:#f2f1f2;
  --d-pane:#fcfbfb;
  --d-panel:#ffffff;
  --d-panel-2:#f4f2f3;
  --d-border:rgba(36,26,28,0.08);
  --d-border-soft:rgba(36,26,28,0.05);
  --d-border-strong:rgba(36,26,28,0.14);
  --d-input-bg:#ffffff;
  /* 0.82-alpha white + blur(16px) — same depth/opacity as Divlon-Comply's
     .auth-card frosted surface (src/styles/globals.css), reused here for
     form inputs instead of a login card. */
  --d-input-bg-blur:rgba(255,255,255,0.82);
  --d-input-border:rgba(36,26,28,0.14);
  --d-text:#3a2e30;
  --d-text-strong:#241a1c;
  --d-muted:#8a7679;
  --d-red:#ea384c;
  --d-red-2:#d02d40;
  --d-red-rgb:234,56,76;
  --d-grad-primary:linear-gradient(135deg,#ea384c 0%,#b83535 100%);
  --d-green:#2e7d32;
  --d-green-rgb:46,125,50;
  --d-amber:#b8860b;
  --d-amber-rgb:184,134,11;
  --d-blue:#1f6feb;
  --d-blue-rgb:31,111,235;
  --d-grid:transparent;
  --d-navbar-bg:rgba(255,255,255,0.6);
  --d-sidebar-top:#3d0f17;
  --d-sidebar-bottom:#0d0607;
  --d-sidebar-bg:#1f0a0d;
  --d-sidebar-border:rgba(255,255,255,0.08);
  --d-sidebar-text:#e9dade;
  --d-active-bg:#ea384c;
  --d-active-text:#ffffff;
  --d-nav-btn-border:rgba(36,26,28,0.12);
  --d-chart-red:#ea384c;
  --d-chart-fill:rgba(234,56,76,0.14);
}
/* Login wordmark is a pure-white PNG; invert to black on Soft's light
   auth shell (Navy/Black keep it white-on-dark, no invert needed). */
body.theme-soft .auth-logo img{filter:invert(1);}
/* mail-only.png is a white line-art PNG (transparent bg) designed to read
   against Black/Navy's dark auth background. D-03 switched login.html to
   render on Soft's light background, which left this decorative graphic
   white-on-near-white and effectively invisible (reported live by the
   user post-deploy). Same fix as the wordmark above: invert the white
   strokes to dark on Soft, chained with the existing red drop-shadow glow
   (login.html's own .auth-mail rule sets filter:drop-shadow(...) alone;
   this selector's higher specificity wins and must re-specify it, not
   just add invert, or the glow would be lost). */
body.theme-soft .auth-mail{filter:invert(1) drop-shadow(0 0 30px rgba(var(--d-red-rgb),0.18));}

@keyframes flicker{0%,100%{opacity:1}92%{opacity:1}93%{opacity:.4}94%{opacity:1}96%{opacity:.6}97%{opacity:1}}

/* ---------------- scrollbar ---------------- */
/* Universal — unprefixed ::-webkit-scrollbar applies to every scrollable
   element on every page (sidebar, modals, textareas, overflowing tables,
   the document itself). Red brand accent across all three themes now
   (the old light-mode periwinkle-blue variant was removed with that
   theme). Track is 8px with a 1.5px transparent inset (border +
   background-clip:padding-box) so the thumb has a little breathing room
   without drifting far from the scrollable element's true edge. Thumb
   fades to transparent at both ends (18%/82%) and brightens + widens
   that band on hover (14%/86%).

   The root/page scrollbar belongs to <html>, not <body> — divlon-theme.js
   mirrors the theme class onto <html> too, so the default rule below
   (unprefixed ::-webkit-scrollbar) already covers it regardless of which
   element the scrollbar actually belongs to.

   IMPORTANT: scrollbar-width/scrollbar-color must NOT be set on any
   element that also has -webkit-scrollbar-* rules. Per spec, a UA that
   supports the standard scrollbar-color/width properties (which now
   includes current Safari, not just Firefox) will silently DISCARD all
   ::-webkit-scrollbar-* styling on that element the moment
   scrollbar-color/width computes to anything but "auto" — the gradient/
   fade/inset thumb never renders, only a flat scrollbar-color fill does.
   Firefox has zero ::-webkit-scrollbar support, so it's the ONLY engine
   that should ever see scrollbar-color — gate it behind @supports so
   Chrome/Safari never see it. */
@supports not selector(::-webkit-scrollbar) {
  *{scrollbar-width:thin;}
  body{scrollbar-color:var(--d-red) transparent;}
}

::-webkit-scrollbar{width:8px;height:8px;}
::-webkit-scrollbar-track{background:transparent;}
::-webkit-scrollbar-thumb{
  background:linear-gradient(to bottom,transparent 0%,rgba(var(--d-red-rgb),0.65) 18%,rgba(var(--d-red-rgb),0.65) 82%,transparent 100%);
  background-clip:padding-box;
  border:1.5px solid transparent;
  border-radius:9999px;
}
::-webkit-scrollbar-thumb:horizontal{
  background:linear-gradient(to right,transparent 0%,rgba(var(--d-red-rgb),0.65) 18%,rgba(var(--d-red-rgb),0.65) 82%,transparent 100%);
  background-clip:padding-box;
}
::-webkit-scrollbar-thumb:hover{
  background:linear-gradient(to bottom,transparent 0%,var(--d-red) 14%,var(--d-red) 86%,transparent 100%);
  background-clip:padding-box;
}

/* ---------------- base ---------------- */
body{
  background-color:var(--d-bg)!important;
  background-image:
    linear-gradient(var(--d-grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--d-grid) 1px, transparent 1px)!important;
  background-size:30px 30px!important;
  color:var(--d-text)!important;
  font-family:'Source Sans Pro',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif!important;
}
/* Soft's backdrop: neutral soft wash instead of the grid-line texture —
   the one deliberate visual difference from Navy/Black's backdrop.
   background-attachment:fixed was removed (not just left off): it forces
   a recomposite of this gradient on every scroll frame, stacked on the
   navbar's own backdrop-filter:blur — real cost on every page. Default
   (scroll-with-content) is cheaper and the gradient already fades out
   well before the fold on any page with real content. */
body.theme-soft{
  background-color:var(--d-bg)!important;
  background-image:
    radial-gradient(1200px 820px at 0% 0%, rgba(20,16,17,0.035), transparent 60%),
    radial-gradient(1000px 700px at 100% 0%, rgba(20,16,17,0.03), transparent 55%)!important;
  -webkit-font-smoothing:antialiased;
}
h1,h2,h3,h4,h5,h6,.panel-title{color:var(--d-text-strong)!important;}
body.theme-soft h1,body.theme-soft h2{font-weight:600!important;letter-spacing:-.01em;}
a{color:var(--d-red)!important;}
a:hover{color:var(--d-red-2)!important;}
.text-muted{color:var(--d-muted)!important;}

/* ---------------- major headings (Pentest weight scale) ---------------- */
.page-header{font-size:20px!important;font-weight:600!important;margin:0 0 18px!important;padding-bottom:10px!important;border-bottom:1px solid var(--d-border)!important;letter-spacing:-.01em;}
.page-header small{font-size:13px!important;color:var(--d-muted)!important;font-weight:400!important;}
h1{font-size:20px!important;font-weight:600!important;}
h2{font-size:16px!important;font-weight:600!important;}
h3{font-size:14px!important;font-weight:600!important;}
h4{font-size:14px!important;font-weight:600!important;}
h5{font-size:13px!important;font-weight:600!important;}
h6{font-size:12px!important;font-weight:600!important;}

/* ---------------- navbar brand lockup (icon + DIVLON AUTOMATED / PHISHING PLATFORM) ---------------- */
.navbar .navbar-brand.brand-lockup{
  display:flex!important;align-items:center!important;gap:8px!important;
  height:60px!important;line-height:normal!important;padding:0 0 0 24px!important;text-decoration:none!important;
}
.navbar .brand-lockup .brand-icon{width:32px;height:32px;border-radius:var(--d-r-sm);display:block;flex:0 0 auto;}
.navbar .brand-lockup .brand-text{display:flex;flex-direction:column;line-height:1.15;}
.navbar .brand-lockup .brand-title{font-size:13px;font-weight:800;letter-spacing:.02em;color:var(--d-text-strong)!important;}
.navbar .brand-lockup .brand-sub{font-size:10px;font-weight:600;letter-spacing:.12em;color:var(--d-muted)!important;text-transform:uppercase;}

/* ---------------- navbar (60px, Pentest header height) ---------------- */
.navbar-inverse{background-color:var(--d-navbar-bg)!important;border-color:var(--d-border)!important;border-bottom:1px solid var(--d-border-strong)!important;min-height:60px!important;}
.navbar-inverse .navbar-brand,
.navbar-inverse .navbar-nav>li>a{color:var(--d-text)!important;background-color:transparent!important;}
.navbar-inverse .navbar-nav>li>a:hover,
.navbar-inverse .navbar-nav>li>a:focus{color:var(--d-red)!important;}
.navbar-brand{font-weight:600!important;letter-spacing:.5px;height:60px!important;line-height:60px!important;padding-top:0!important;padding-bottom:0!important;}
body{padding-top:60px!important;}
.sidebar{top:61px!important;}
/* 261019: .sidebar is position:fixed (Bootstrap's dashboard pattern,
   gophish.css), so it always renders pinned to the viewport's left edge
   regardless of page scroll. gophish.css never sets overflow-x on body —
   whenever any admin page's content (a wide DataTable despite scrollX, a
   long dropdown, an unbreakable string) pushes the document even slightly
   wider than the viewport, the whole <body> becomes horizontally
   scrollable/swipeable as one unit. Because the fixed sidebar's own space
   is otherwise indistinguishable from scrolled-past body content, dragging
   that scroll makes the ENTIRE card (title, filters, table, pagination)
   appear to slide left together, revealing the sidebar underneath — looks
   like the whole page is being dragged, not a table overflowing (reported
   repeatedly: Training Leaderboard page, 2026-10-19). This is a body-level
   bug, not something fixable per-table: hiding the body's own horizontal
   overflow here fixes it for every admin page at once, present and future,
   without touching any element's intentional OWN horizontal scroll (e.g.
   the Leaderboard DataTable's scrollX container keeps scrolling internally
   exactly as intended — this only clips overflow at the body boundary). */
body{overflow-x:hidden!important;}
html{overflow-x:hidden!important;}
/* navbar right: separate profile + logout (were flush inside .btn-group) */
/* User-reported (live): the admin/logout cluster sits lower than the
   theme-switch pills beside it. .theme-switch-item explicitly centers
   itself (height:60px + flex + align-items:center) but this plain <li>
   never did -- it just inherited Bootstrap's default nav <li> padding,
   which happened to roughly line up against the OLD taller default .btn
   height. The new compact .btn height (08 button-sizing fix) exposed the
   gap. Center every navbar-right <li> the same way, not just this one. */
.navbar-right>li{display:flex!important;align-items:center!important;height:60px!important;}
.navbar-right #navbar-dropdown{display:inline-flex!important;align-items:center!important;gap:10px!important;}
.navbar-right #navbar-dropdown>.btn{margin:0!important;border-radius:var(--d-r-sm)!important;border:1px solid var(--d-nav-btn-border)!important;}

/* Breadcrumb ("Divlon Phish › <page>", base.html) — all themes now.
   Sits on the sidebar-coloured portion of the navbar; on Navy/Black the
   navbar is already the same flat colour as the sidebar (no fade needed).
   Soft additionally fades its navbar from the sidebar colour into glass
   over the content pane (below), since Soft's navbar/sidebar colours
   actually differ.
   Base hide rule MUST come before the media query: both now share the
   same .topbar-crumb specificity (0,1,0) since this was generalized off
   body.theme-soft, so whichever is declared LAST wins at matching
   viewports — if the hide rule came after, it would always win and the
   crumb would never show on any theme/width (the actual regression hit
   here when this was generalized). */
.topbar-crumb{display:none;}
@media (min-width:768px){
  .navbar-header{display:flex;align-items:center;}
  .topbar-crumb{
    display:inline-flex;
    align-items:center;
    gap:10px;
    height:60px;
    margin-left:36px;
    padding-left:28px;
    border-left:1px solid rgba(255,255,255,0.14);
    font-size:14px;
  }
  .topbar-crumb-root{color:var(--d-sidebar-text);font-weight:500;}
  .topbar-crumb-sep{color:rgba(255,255,255,0.32);font-size:12px;}
  .topbar-crumb-current{color:#ffffff;font-weight:600;}
}
/* Soft-only: the portion of the navbar sitting directly above the
   sidebar picks up the sidebar's own dark gradient colour and fades into
   the glass over the content pane, so the two read as one continuous
   surface instead of a light bar sitting on top of a disconnected dark
   column. Stops are fixed px, generous enough for brand + breadcrumb at
   normal window widths (same "long fade" approach Divlon-Comply's own
   topbar-crumb uses — see its CSS comment on --crumb-fade). Below 768px
   there's no sidebar column, so the bar stays plain glass and the crumb
   hides (covered by the shared rule above). Navy/Black don't need this:
   their navbar and sidebar are already the same flat colour. */
@media (min-width:768px){
  body.theme-soft .navbar-inverse{
    background-image:linear-gradient(90deg, var(--d-sidebar-top) 0, var(--d-sidebar-top) 480px, var(--d-navbar-bg) 680px)!important;
  }
  body.theme-soft .navbar .brand-lockup .brand-title{color:#f5e9ea!important;}
  body.theme-soft .navbar .brand-lockup .brand-sub{color:var(--d-sidebar-text)!important;}
}
/* Soft: glass blur over the neutral backdrop. Navy/Black don't need
   blur — there's no light content behind their navbar to blur. */
body.theme-soft .navbar-inverse{
  -webkit-backdrop-filter:blur(16px) saturate(140%);
  backdrop-filter:blur(16px) saturate(140%);
  border-bottom:1px solid var(--d-border)!important;
  box-shadow:0 1px 2px rgba(20,16,17,0.04);
}
@supports not (backdrop-filter:blur(1px)){
  body.theme-soft .navbar-inverse{background-color:var(--d-panel)!important;}
}
@media (prefers-reduced-transparency:reduce){
  body.theme-soft .navbar-inverse{background-color:var(--d-panel)!important;-webkit-backdrop-filter:none;backdrop-filter:none;}
}

/* ---------------- theme switcher (positioned top-right, like Divlon-Pentest header) ---------------- */
.theme-switch-item{display:flex!important;align-items:center;height:60px;}
.theme-switch{display:inline-flex!important;align-items:center;margin:0 14px 0 0!important;}
.theme-switch .theme-btn{
  width:30px;height:30px;padding:0!important;margin:0!important;
  display:inline-flex!important;align-items:center;justify-content:center;
  border-radius:var(--d-r-sm)!important;
  background:var(--d-panel-2)!important;border:1px solid var(--d-border)!important;
  color:var(--d-muted)!important;font-size:13px!important;line-height:1!important;
}
.theme-switch .theme-btn + .theme-btn{border-left:0!important;margin-left:4px!important;}
.theme-switch .theme-btn:hover{color:var(--d-text)!important;}
/* On Navy/Black, --d-text is a near-white (#e6e6e6 / #f1f5f9), so the
   generic hover rule above already reads fine. On the default Soft theme
   --d-text is #3a2e30 (near-black, it's the body-text color for a LIGHT
   background) — hovering a theme-btn there turned its icon almost black
   against the button's dark panel background, unreadable. Force white on
   Soft specifically rather than changing --d-text's meaning everywhere. */
body.theme-soft .theme-switch .theme-btn:hover{color:#fff!important;}
.theme-switch .theme-btn.active{background:var(--d-red)!important;border-color:var(--d-red)!important;color:#fff!important;}

/* ---------------- sidebar ----------------
   Opaque gradient background, same rule for all three themes: on Navy/
   Black, --d-sidebar-top/--d-sidebar-bottom aren't defined, so the
   var() fallback resolves both gradient stops to the SAME flat
   --d-sidebar-bg colour they always had — a 0%-to-100% gradient between
   two identical colours renders as a flat fill, so nothing visually
   changes there. Soft defines both stops explicitly, so it alone gets an
   actual dark red-to-black gradient. The sidebar itself stays a flat,
   square-edged rectangle in all three themes — only the content pane
   (.main, below) curves. Items are inset 8px from the sidebar edges
   (Pentest nav px-2); metrics mirror .sidebar-item: 14px text, 16px
   icons, 12px icon gap, ~38px tall. */
.sidebar{
  background:linear-gradient(180deg, var(--d-sidebar-top, var(--d-sidebar-bg)) 0%, var(--d-sidebar-bottom, var(--d-sidebar-bg)) 100%)!important;
  border-right:1px solid var(--d-sidebar-border)!important;
}
.sidebar .nav-sidebar>li>a,
.sidebar a{color:var(--d-sidebar-text)!important;display:flex!important;align-items:center!important;margin:1px 8px!important;padding:9px 12px!important;border-radius:var(--d-r-md)!important;font-size:14px!important;font-weight:400!important;line-height:20px!important;transition:background-color .15s,color .15s!important;}
.sidebar .nav-sidebar>li>a i.fa{width:20px;text-align:center;margin-right:12px;font-size:16px;flex:0 0 auto;}
/* Hover: translucent light-on-dark wash — works consistently regardless
   of each theme's own dark sidebar shade, unlike a per-theme flat
   override colour. */
.sidebar .nav-sidebar>li>a:hover,
.sidebar a:hover{background-color:rgba(255,255,255,0.08)!important;color:#ffffff!important;}
/* Active item: rounded red pill (261018: was a sharp corner-bracket
   marker on Navy/Black, dashed-viewfinder motif — unified to the same
   rounded pill Soft already used, since shape is now shared across
   themes). */
.sidebar .nav-sidebar>li.active>a{
  background-color:var(--d-active-bg)!important;
  color:var(--d-active-text)!important;
  font-weight:500!important;
  border-radius:var(--d-r-md)!important;
  box-shadow:0 2px 10px -2px rgba(var(--d-red-rgb),0.55);
}
.sidebar .nav-sidebar>li.active>a:hover{
  background-color:var(--d-active-bg)!important;
  color:var(--d-active-text)!important;
}
/* Sidebar group labels: neutral "DIVLON MODULES" + red-muted "SUPER ADMIN"
   (Pentest pattern: 10px/600/uppercase/wide tracking, icon at 60% red). */
.nav-group-label{color:#6b7280!important;font-size:10px!important;font-weight:600!important;letter-spacing:.08em!important;padding:6px 12px 6px 20px!important;text-transform:uppercase;}
.nav-group-label-admin{color:rgba(var(--d-red-rgb),0.6)!important;display:flex!important;align-items:center!important;gap:5px!important;}
.nav-group-label-admin i.fa{font-size:10px;line-height:1;flex:0 0 auto;}
/* Sidebar separators: keep them tight and inside the item gutter */
.sidebar .nav-sidebar>li>hr{margin:10px 16px!important;border:0;border-top:1px solid var(--d-sidebar-border)!important;}

/* ---------------- mobile sidebar drawer ----------------
   The stock Bootstrap dashboard template (static/css/dashboard.css) hides
   .sidebar unconditionally below 768px with no mobile equivalent - the
   hamburger button only ever drove the small .navbar-collapse (theme
   switcher + account menu), so the whole site nav was unreachable on
   phones/tablets. body.sidebar-open is toggled by the same hamburger
   button (divlon-theme.js) independently of Bootstrap's own collapse
   classes, since this theme's Flat UI CSS forces
   .navbar-collapse.collapse{display:none!important} between 768-1300px. */
@media (max-width:767px){
  body.sidebar-open .sidebar{
    display:block!important;
    position:fixed;
    left:0;right:0;bottom:0;
    width:100%;
    padding:16px 12px;
    overflow-y:auto;
    z-index:1040;
    border-radius:0!important;
  }
}

/* ---------------- content pane (.main) ----------------
   The curve lives here, not on the sidebar, in all three themes. On
   Navy/Black the fillet colour falls back to --d-sidebar-bg (their flat
   colour), same fallback trick as the sidebar gradient above — the
   curve still reads as "the sidebar flowing into the pane" even though
   there's no gradient to speak of there. --d-pane falls back to
   --d-panel-2 so Navy/Black get a sensible pane surface without needing
   their own dedicated variable. */
@media (min-width:768px){
  .main{
    position:relative;
    background-color:var(--d-pane, var(--d-panel-2))!important;
    min-height:calc(100vh - 60px);
    border-top-left-radius:var(--d-r-xl);
    box-shadow:-1px 0 0 var(--d-border), 0 8px 24px -16px rgba(0,0,0,0.12);
  }
  /* Fillet: paints the notch OUTSIDE the pane's curve in the sidebar's
     own (near-top-stop) colour, masked to a quarter circle, so the
     sidebar reads as flowing into the curve. Same technique as the
     Divlon-Comply reference screenshot (their --r-3xl is 24px, matching
     --d-r-xl here). The mask's transparent-to-opaque band is a soft 2px
     (not a 0.5px hairline) so the arc anti-aliases smoothly instead of
     showing a seam at normal zoom. */
  .main::before{
    content:"";
    position:absolute;
    top:0;left:0;
    width:var(--d-r-xl);
    height:var(--d-r-xl);
    pointer-events:none;
    background:color-mix(in srgb, var(--d-sidebar-top, var(--d-sidebar-bg)) 85%, var(--d-sidebar-bottom, var(--d-sidebar-bg)));
    -webkit-mask:radial-gradient(circle at 100% 100%, transparent calc(var(--d-r-xl) - 1.5px), #000 calc(var(--d-r-xl) + 0.5px));
    mask:radial-gradient(circle at 100% 100%, transparent calc(var(--d-r-xl) - 1.5px), #000 calc(var(--d-r-xl) + 0.5px));
  }
}

/* ---------------- table horizontal-scroll containment (globally fixed) ----
   Several tables (Browser Fingerprinting, Users & Groups, Campaigns, …)
   are wider than the viewport at normal zoom and had no scrollable
   wrapper of their own, so the browser scrolled the WHOLE content pane
   (or even the page) horizontally instead of just the table — dragging
   the card/pane along with it rather than keeping it in place. Giving
   just the table's direct container its own horizontal scroll (and nothing
   else) fixes it: the card/pane stays put, only the table's own content
   scrolls under your cursor. :has() is well supported in all evergreen
   browsers; this is an internal admin tool. */
.row:has(> table.table),
.row:has(> table[id]),
.panel-body:has(> table),
.dp-panel:has(> table){
  overflow-x:auto;
  -webkit-overflow-scrolling:touch;
}

/* ---------------- panels / cards ---------------- */
.panel{background-color:var(--d-panel)!important;border-color:var(--d-border)!important;border-radius:var(--d-r-lg)!important;box-shadow:0 1px 2px rgba(0,0,0,0.04), 0 8px 24px -14px rgba(0,0,0,0.12);}
.panel-default>.panel-heading{background-color:var(--d-panel-2)!important;color:var(--d-text-strong)!important;border-color:var(--d-border)!important;border-top-left-radius:var(--d-r-lg)!important;border-top-right-radius:var(--d-r-lg)!important;}
.panel-body{background-color:var(--d-panel)!important;}
.panel-title{font-size:14px!important;}
.well,.jumbotron{background-color:var(--d-panel-2)!important;border-color:var(--d-border)!important;color:var(--d-text)!important;border-radius:var(--d-r-lg)!important;}

/* ---------------- buttons (rounded, soft shadow, Divlon-Pentest palette) ---------------- */
/* Comply-scale compact buttons (user-reported: "buttons still this big"
   post-Phase-8 -- 08-02/08-03 only recolored/radius'd buttons, never sized
   them down). Comply's own button component uses exactly 3 heights (~32/
   28/36px) with 4-5px vertical / 12-14px horizontal padding and a 13px
   label -- Bootstrap 3's default .btn{padding:6px 12px;font-size:14px}
   plus its ~1.43 line-height renders visibly chunkier. Height math below
   targets ~32px for the default size: 5+5 padding + 20 line-height + 2
   border = 32px. */
.btn{border-radius:var(--d-r-sm)!important;transition:all .15s!important;padding:5px 14px!important;font-size:13px!important;line-height:20px!important;}
.btn-sm,.btn-group-sm>.btn{padding:3px 10px!important;font-size:12px!important;line-height:18px!important;}
.btn-lg,.btn-group-lg>.btn{padding:7px 18px!important;font-size:15px!important;line-height:22px!important;}
.btn-xs{padding:1px 6px!important;font-size:11px!important;line-height:16px!important;}
.btn-group>.btn,
.btn-group>.btn-group{margin:0!important;border-radius:var(--d-r-sm)!important;}
/* User-reported (live): buttons read too curved -- --d-r-md (10px) was
   too round next to Comply's flatter 8px button radius. Unify every
   button-like element (incl. SweetAlert2's own, which independently set
   --d-r-md on .swal2-cancel and inherited the vendored .25em/4px default
   on .swal2-confirm -- inconsistent with each other and with .btn) onto
   --d-r-sm (8px, matches Comply's spec exactly). */
.swal2-styled,.swal2-cancel,.swal2-confirm{border-radius:var(--d-r-sm)!important;}
.btn-primary{
  background:var(--d-grad-primary)!important;
  border:0!important;color:#fff!important;
  font-weight:500!important;font-size:14px!important;
  box-shadow:0 4px 14px -4px rgba(var(--d-red-rgb),0.38)!important;
}
.btn-primary:hover,.btn-primary:focus,.btn-primary:active{
  background:linear-gradient(135deg,#d23043 0%,#9c2b2b 100%)!important;
  color:#fff!important;box-shadow:0 6px 18px -4px rgba(var(--d-red-rgb),0.48)!important;
}
.btn-default{background-color:var(--d-panel-2)!important;border:1px solid var(--d-border)!important;color:var(--d-text)!important;border-radius:var(--d-r-md)!important;}
.btn-default:hover{background-color:color-mix(in srgb, var(--d-panel-2) 80%, var(--d-text-strong) 10%)!important;color:var(--d-text-strong)!important;}
.btn-success{background-color:#2e7d32!important;border-color:#2e7d32!important;}
/* Delete used the same solid-red-gradient family as .btn-primary (View
   Results, Copy, New Campaign, Save…), so a destructive action was one
   misclick away from looking identical to a safe one on every list page.
   Ghost/outline style keeps the red = danger signal but visually quiets
   it relative to the glowing solid CTAs; fills solid only on hover as an
   "about to act" cue. */
.btn-danger{background:transparent!important;border:1.5px solid var(--d-red)!important;color:var(--d-red)!important;box-shadow:none!important;border-radius:var(--d-r-md)!important;}
.btn-danger:hover,.btn-danger:focus,.btn-danger:active{background:var(--d-red)!important;color:#fff!important;}
.btn-info{background-color:#1f6feb!important;border-color:#1f6feb!important;}
/* .btn-blue (Complete, Refresh, etc. — a vendored gophish.css class, NOT
   Bootstrap's .btn-info) shipped as a fixed #428bca on every theme —
   off-brand on the dark themes, where red is the identity color
   everywhere else. Match .btn-primary's red gradient on Navy/Black. */
body.theme-black .btn-blue,body.theme-navy .btn-blue{
  background:var(--d-grad-primary)!important;
  border:0!important;color:#fff!important;
  box-shadow:0 4px 14px -4px rgba(var(--d-red-rgb),0.38)!important;
}
body.theme-black .btn-blue:hover,body.theme-navy .btn-blue:hover,
body.theme-black .btn-blue:focus,body.theme-navy .btn-blue:focus,
body.theme-black .btn-blue:active,body.theme-navy .btn-blue:active{
  background:linear-gradient(135deg,#d23043 0%,#9c2b2b 100%)!important;
  color:#fff!important;box-shadow:0 6px 18px -4px rgba(var(--d-red-rgb),0.48)!important;
}

/* ---------------- forms ---------------- */
label,.control-label{color:var(--d-muted)!important;font-size:12px!important;font-weight:600!important;}
.form-control{
  background-color:var(--d-input-bg)!important;border:1px solid var(--d-input-border)!important;
  color:var(--d-text)!important;border-radius:var(--d-r-sm)!important;font-size:14px!important;
}
/* Frosted inputs, matching Divlon-Comply's .auth-card depth exactly:
   0.82-alpha background + backdrop-filter:blur(16px), same @supports
   feature-query fallback (opaque --d-input-bg, no blur, for browsers
   without backdrop-filter) so older browsers still get a fully readable
   solid input instead of a half-applied translucent one. */
@supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .form-control{
    background-color:var(--d-input-bg-blur)!important;
    -webkit-backdrop-filter:blur(16px);
    backdrop-filter:blur(16px);
  }
}
body.theme-black .form-control,body.theme-navy .form-control{color:#fff!important;}
.form-control:focus{border-color:rgba(var(--d-red-rgb),0.5)!important;box-shadow:0 0 0 2px rgba(var(--d-red-rgb),0.15)!important;}
.form-control::placeholder{color:var(--d-muted)!important;}
.form-control::-webkit-input-placeholder{color:var(--d-muted)!important;}
.input-group-addon{background-color:var(--d-input-bg)!important;border-color:var(--d-input-border)!important;color:var(--d-muted)!important;border-radius:var(--d-r-sm)!important;}

/* ---------------- tables: muted uppercase header, compact aligned rows, quiet hover ----
   Header: small muted uppercase labels on a faint panel-2 band. Body text
   is sized to match the rest of the UI chrome (14px, same as
   tabs/buttons/inputs) across all three themes.

   Row-height bug (real layout fix, not just styling): the engine renders
   each row's date cell and its action-button group as plain text/
   Bootstrap's `.pull-right` float, with no nowrap guard. Once there's
   less spare column width than the engine's own cramped defaults
   assumed, both wrap — the date breaks across two lines and the
   edit/copy/delete buttons stack into two rows instead of staying
   inline, reading as distorted/misaligned rows. Forcing nowrap on every
   cell except the name/title column (which is fine to wrap) and turning
   `.pull-right` into a non-wrapping flex row fixes both at the source. */
.table{background-color:transparent!important;color:var(--d-text)!important;}
.table>thead>tr>th{
  background-color:var(--d-panel-2)!important;
  color:var(--d-muted)!important;
  font-size:11px!important;
  font-weight:700!important;
  text-transform:uppercase;
  letter-spacing:.06em;
  border-bottom:1px solid var(--d-border)!important;
  padding:10px 16px!important;
  white-space:nowrap;
}
.table>thead>tr>th:first-child{border-top-left-radius:var(--d-r-sm);}
.table>thead>tr>th:last-child{border-top-right-radius:var(--d-r-sm);}
.table>tbody>tr>td{
  padding:10px 16px!important;
  border-color:var(--d-border-soft)!important;
  color:var(--d-text)!important;
  font-size:14px!important;
  vertical-align:middle!important;
  white-space:nowrap;
}
.table>tbody>tr>td:first-child{white-space:normal;}
.table .pull-right{
  display:flex!important;
  flex-wrap:nowrap!important;
  float:none!important;
  gap:6px;
  justify-content:flex-end;
}
.table .pull-right .btn{white-space:nowrap;flex:0 0 auto;}
.table-striped>tbody>tr:nth-of-type(odd){background-color:rgba(127,127,127,0.03)!important;}
.table-hover>tbody>tr:hover{background-color:var(--d-panel-2)!important;}
.dataTables_wrapper .dataTables_filter input,
.dataTables_wrapper .dataTables_length select{
  background-color:var(--d-input-bg)!important;border:1px solid var(--d-input-border)!important;
  color:var(--d-text)!important;border-radius:var(--d-r-sm)!important;
}
/* These two selectors already out-specificity the plain .form-control
   blur rule above (DataTables' own CSS needed beating at a higher
   specificity than .form-control alone gives), so the blur needs its own
   copy at the same specificity or the table search box and length
   select would stay solid while every other input went frosted. */
@supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .dataTables_wrapper .dataTables_filter input,
  .dataTables_wrapper .dataTables_length select{
    background-color:var(--d-input-bg-blur)!important;
    -webkit-backdrop-filter:blur(16px);
    backdrop-filter:blur(16px);
  }
}
body.theme-black .dataTables_wrapper .dataTables_filter input,body.theme-navy .dataTables_wrapper .dataTables_filter input,
body.theme-black .dataTables_wrapper .dataTables_length select,body.theme-navy .dataTables_wrapper .dataTables_length select{color:#fff!important;}
/* "Show [N] entries" — the label text and the number input/select sat on
   different baselines (no shared flex alignment), reading as crooked.
   DataTables wraps it as `<label>Show <input/select> entries</label>` all
   on one line; flex + a fixed line-height on the control is what actually
   centers an inline form control against surrounding inline text. */
.dataTables_wrapper .dataTables_length{display:flex!important;align-items:center!important;gap:6px;}
.dataTables_wrapper .dataTables_length select,
.dataTables_wrapper .dataTables_length input{line-height:normal;vertical-align:middle;margin:0;}

/* ---- Users & Groups table: Name column was squeezed to the narrowest
   width while # of Members/Modified Date (short, fixed-format content)
   got the most space, because DataTables locks each column's width at
   init time using pre-theme metrics. Rebalanced to fit this table's
   actual columns (Name 42%, Members 16%, Modified 26%, actions 16%). ---- */
#groupTable th:nth-child(1),
#groupTable td:nth-child(1){width:42%!important;}
#groupTable th:nth-child(2),
#groupTable td:nth-child(2){width:16%!important;}
#groupTable th:nth-child(3),
#groupTable td:nth-child(3){width:26%!important;}
#groupTable th:nth-child(4),
#groupTable td:nth-child(4){width:16%!important;}

/* ---- DataTables header/body column desync (Dashboard "Recent Campaigns") ----
   DataTables recalculates column widths with its own JS (autoWidth) after
   the page loads, and sets header and body cell widths SEPARATELY —
   verified live via getBoundingClientRect: a header cell rendered ~117px
   while its own column's body cells rendered ~32px, sliding the header's
   "reported" and "status" columns visually out of alignment with the
   body underneath them (the gap/"distortion" a column tooltip's hover
   drew the eye to). Pinning BOTH the <th> and its corresponding <td>s (by
   position, since DataTables doesn't carry the .color-* class onto <td>)
   to the exact same explicit width removes any room for the header and
   body to diverge, regardless of what DataTables' own width JS does
   afterward.

   table-layout:fixed is load-bearing here, not cosmetic: in the default
   table-layout:auto, width/min-width/max-width on a cell are only
   ADVISORY hints to the browser's column-width algorithm — if content
   elsewhere in that column (or an absolutely-positioned DataTables sort-
   arrow icon inside the <th>) wants more room, the browser widens the
   column past max-width anyway (verified live: computed max-width 52px,
   computed width 57.6px — the two are allowed to disagree in auto mode).
   This is also what let hovering a column's tooltip visibly shift the
   whole table: Bootstrap's tooltip, appended to <body>, can toggle the
   page's vertical scrollbar, which changes the table's available width
   and re-triggers this same "soft" auto-layout recalculation — nothing
   about the table should move just because something unrelated was
   hovered. table-layout:fixed makes column widths strictly follow the
   header row's CSS widths instead, with no re-negotiation based on
   content or container size, so every column — pinned or not — stays
   put regardless of what's hovered elsewhere on the page. */
.dash-campaign-table{table-layout:fixed;}
/* table-layout:fixed alone wasn't enough: it only holds a column firm if
   ITS width is pinned. Name/Created Date/Status/Actions had no CSS pin
   (only the 5 icon columns did), so DataTables' own resize-triggered JS
   was still free to shrink them on hover (still re-rendering inline
   widths on that event; fixed layout just stopped it from ALSO blowing
   past the icon columns' max-width). Pinning every column removes any
   width DataTables can still rewrite. */
/* Name widened from 23% to 31% to absorb the width freed from Status
   below — on a wide viewport that used to sit empty between the Status
   badge and the view/delete buttons (measured live: a 70px-max "In
   progress"/"Completed" badge inside a 307px-wide column at a 1617px
   table — ~240px of dead space doing nothing). Now it goes to Name,
   which was wrapping onto 2 lines for longer campaign names. */
.dash-campaign-table th:nth-child(1), .dash-campaign-table td:nth-child(1){width:31%!important;}
.dash-campaign-table th:nth-child(2), .dash-campaign-table td:nth-child(2){width:17%!important;}
/* Status ("In progress"/"Completed") was pinned to 17% (previously 12%,
   widened once to stop the ellipsis safety net below from truncating
   the badge text itself on hover-triggered reflow — see git history).
   The badge text tops out at ~70px even at a 1617px table width, so 17%
   (~275px) left a large dead gap between the badge and the Actions
   column's buttons. Narrowed to 9% — still comfortable room above the
   badge's real width — and the reclaimed 8 points went to Name above. */
.dash-campaign-table th:nth-child(8), .dash-campaign-table td:nth-child(8){width:9%!important;}
.dash-campaign-table th:nth-child(9), .dash-campaign-table td:nth-child(9){width:16%!important;}
/* Safety net: table-layout:fixed + white-space:nowrap doesn't clip
   overflowing content by default — text that doesn't fit the pinned
   width spills visibly into the next column instead (the "Created
   Date" overlap bug). Truncate with an ellipsis instead. Status badges
   are exempted: a badge that gets ellipsis-truncated ("I…") reads as
   broken in a way a truncated date/name doesn't — it should keep its
   real width instead of ever needing to clip.
*/
.dash-campaign-table th,.dash-campaign-table td{overflow:hidden;text-overflow:ellipsis;}
.dash-campaign-table td:nth-child(8){overflow:visible;text-overflow:clip;}
.dash-campaign-table td:nth-child(8) .label{white-space:nowrap;}
/* Column-header/status tooltips (Bootstrap .tooltip, data-toggle="tooltip")
   shipped in whatever grey/navy Bootstrap default happened to apply —
   tilted to the red brand instead, same family as .swal2-confirm/.btn-primary. */
.tooltip-inner{background-color:#3d0f17!important;color:#fff!important;border-radius:var(--d-r-sm)!important;padding:6px 10px!important;font-size:12px!important;}
.tooltip.top .tooltip-arrow,.tooltip.bottom .tooltip-arrow,.tooltip.left .tooltip-arrow,.tooltip.right .tooltip-arrow{border-top-color:#3d0f17!important;}
.tooltip.top .tooltip-arrow{border-top-color:#3d0f17!important;}
.tooltip.bottom .tooltip-arrow{border-bottom-color:#3d0f17!important;}
.tooltip.left .tooltip-arrow{border-left-color:#3d0f17!important;}
.tooltip.right .tooltip-arrow{border-right-color:#3d0f17!important;}
table.dataTable th.color-sent, .dash-campaign-table td:nth-child(3),
table.dataTable th.color-opened, .dash-campaign-table td:nth-child(4),
table.dataTable th.color-clicked, .dash-campaign-table td:nth-child(5),
table.dataTable th.color-success, .dash-campaign-table td:nth-child(6),
table.dataTable th.color-reported, .dash-campaign-table td:nth-child(7){
  width:52px!important;
  min-width:52px!important;
  max-width:52px!important;
  padding-left:4px!important;
  padding-right:4px!important;
  text-align:center!important;
}

/* ---------------- labels / badges (spacing so they never touch text) ---------------- */
.label{color:#fff!important;margin:0 3px!important;border-radius:var(--d-r-sm)!important;}
.label-primary{background-color:var(--d-red)!important;}
.label-default{background-color:#333!important;}
.label-success{background-color:#2e7d32!important;}
.label-danger{background-color:var(--d-red)!important;}
.label-info{background-color:#1f6feb!important;}
.label-warning{background-color:#b8860b!important;}
.badge{margin:0 3px!important;}
.api_heading{background-color:var(--d-panel-2)!important;color:var(--d-text-strong)!important;}

/* ---------------- alerts (Phase 8 D-17) ----------------
   Replaces the old flat/solid Bootstrap-adjacent fill with a quieter
   soft-tinted background + a 4px colored left-border accent, matching
   the Divlon-Comply reference's restrained notification treatment.
   Token-driven via rgba(var(--d-X-rgb),alpha) so the same rule works
   across all three themes without a per-theme override block (the old
   body.theme-soft .alert-* overrides are gone — the alpha wash blends
   correctly against both the dark themes' near-black page background
   and Soft's light one, same way --d-red-rgb-based rules elsewhere never
   needed a Soft-specific duplicate). Applies identically to flash toasts
   (.dp-flash-stack .alert, see below) and static inline banners like
   campaigns.html's empty-state hints — both are plain .alert-* markup,
   so this single rule covers both use cases by construction. */
.alert{
  border-radius:var(--d-r-md)!important;
  border:1px solid transparent!important;
  border-left-width:4px!important;
  padding:var(--d-space-sm) var(--d-space-md)!important;
  display:flex!important;
  align-items:center!important;
  gap:var(--d-space-sm)!important;
  text-align:left!important;
  color:var(--d-text)!important;
}
.alert .fa{flex:0 0 auto!important;font-size:16px!important;}
.alert-success{
  background-color:rgba(var(--d-green-rgb),0.1)!important;
  border-color:rgba(var(--d-green-rgb),0.35)!important;
  border-left-color:var(--d-green)!important;
}
.alert-success .fa{color:var(--d-green)!important;}
.alert-danger{
  background-color:rgba(var(--d-red-rgb),0.08)!important;
  border-color:rgba(var(--d-red-rgb),0.35)!important;
  border-left-color:var(--d-red)!important;
}
.alert-danger .fa{color:var(--d-red)!important;}
.alert-warning{
  background-color:rgba(var(--d-amber-rgb),0.1)!important;
  border-color:rgba(var(--d-amber-rgb),0.35)!important;
  border-left-color:var(--d-amber)!important;
}
.alert-warning .fa{color:var(--d-amber)!important;}
.alert-info{
  background-color:rgba(var(--d-blue-rgb),0.1)!important;
  border-color:rgba(var(--d-blue-rgb),0.35)!important;
  border-left-color:var(--d-blue)!important;
}
.alert-info .fa{color:var(--d-blue)!important;}

/* ---------------- flash toast stack (D-17) ----------------
   flashes.html (08-09) wraps its one-shot post-action messages in
   .dp-flash-stack so they float as a fixed, dismissible toast stack
   instead of rendering as inline page content. Static .alert-info
   banners (campaigns.html empty-state hints) never get this wrapper —
   they stay plain inline markup and only inherit the .alert-* restyle
   above, by construction (they don't use flashes.html at all).
   z-index:1055 is deliberately one below SweetAlert2's own
   .swal2-container (z-index:1060, static/css/sweetalert2.min.css) so a
   toast never floats on top of an open modal dialog. */
.dp-flash-stack{
  position:fixed;
  top:76px;
  right:20px;
  z-index:1055;
  display:flex;
  flex-direction:column;
  gap:var(--d-space-sm);
  max-width:360px;
}
.dp-flash-stack .alert{
  box-shadow:0 4px 12px rgba(0,0,0,0.12);
  animation:dp-flash-in .25s ease-out;
}
.dp-flash-stack .alert.dp-flash-closing{
  animation:dp-flash-out .2s ease-in forwards;
}
.dp-flash-close{
  margin-left:auto;
  flex:0 0 auto;
  background:transparent;
  border:none;
  padding:0 2px;
  font-size:18px;
  line-height:1;
  color:var(--d-text);
  opacity:0.6;
  cursor:pointer;
}
.dp-flash-close:hover,.dp-flash-close:focus{opacity:1;}
@keyframes dp-flash-in{
  0%{opacity:0;transform:translateY(-8px) translateX(8px);}
  100%{opacity:1;transform:translateY(0) translateX(0);}
}
@keyframes dp-flash-out{
  0%{opacity:1;transform:translateX(0);}
  100%{opacity:0;transform:translateX(16px);}
}

/* ---------------- modals ----------------
   Background stays theme-driven: Navy/Black keep the dark --d-sidebar-bg
   panel (their intended look, unchanged). Soft overrides it below — its
   --d-sidebar-bg is now the dark red-to-black sidebar colour specifically,
   so every modal was inheriting a near-black maroon panel instead of a
   light one (inputs read "light" individually but sat inside a dark
   card, which is what read wrong). Radius/shadow/blur are shared. */
.modal-content{
  background-color:var(--d-sidebar-bg)!important;
  border:1px solid var(--d-border-strong)!important;
  color:var(--d-text)!important;
  border-radius:var(--d-r-lg)!important;
  box-shadow:0 12px 36px -12px rgba(0,0,0,0.35);
}
body.theme-soft .modal-content{
  background-color:var(--d-panel)!important;
  border-color:var(--d-border)!important;
  box-shadow:0 12px 36px -12px rgba(20,16,17,0.3);
}
.modal-header{border-bottom:1px solid var(--d-border)!important;}
.close{color:var(--d-text)!important;opacity:.8!important;}
/* Blur feature: frosted modal backdrop (the dimmed layer behind a modal)
   in every theme, matching the Divlon-Comply reference's glassy dialog
   backdrop instead of a flat dark scrim. */
.modal-backdrop{
  background-color:rgba(0,0,0,0.35)!important;
  -webkit-backdrop-filter:blur(32px) saturate(150%);
  backdrop-filter:blur(32px) saturate(150%);
}
body.theme-soft .modal-backdrop{background-color:rgba(20,16,17,0.28)!important;}
/* Dark-theme seam: the navbar is opaque (not blurred — there's no light
   content behind it to blur) with its own 1px border-bottom. With the
   modal backdrop blurred underneath it, that crisp opaque edge sitting
   right above the soft blur read as a hard line cutting through it.
   Bootstrap adds .modal-open to <body> for as long as any modal is open;
   drop the navbar's border then so the blur runs unbroken under it. */
body.modal-open .navbar-inverse{border-bottom-color:transparent!important;}

/* ---------------- dropdown ---------------- */
.dropdown-menu{background-color:var(--d-panel-2)!important;border-color:var(--d-border)!important;border-radius:var(--d-r-md)!important;overflow:hidden;}
.dropdown-menu>li>a{color:var(--d-text)!important;}
.dropdown-menu>li>a:hover{background-color:var(--d-red)!important;color:#fff!important;}

/* ---------------- nav tabs (Active / Archived -> transparent red) ----------------
   Sized to match the rest of the type scale (14px/500 weight) instead of
   the engine's own larger default, and rounded at the top corners. */
.nav-tabs{border-bottom-color:var(--d-border)!important;}
.nav-tabs>li>a{
  color:var(--d-muted)!important;
  border-radius:var(--d-r-sm) var(--d-r-sm) 0 0!important;
  font-size:14px!important;
  font-weight:500!important;
  padding:8px 16px!important;
}
.nav-tabs>li.active>a,
.nav-tabs>li.active>a:focus,
.nav-tabs>li.active>a:hover{
  background-color:rgba(var(--d-red-rgb),0.15)!important;
  border-color:var(--d-red)!important;
  border-bottom-color:transparent!important;
  color:var(--d-text-strong)!important;
  border-radius:var(--d-r-sm) var(--d-r-sm) 0 0!important;
}

/* ---------------- pagination ---------------- */
.pagination>li>a,.pagination>li>span{background-color:var(--d-panel-2)!important;border-color:var(--d-border)!important;color:var(--d-text)!important;border-radius:var(--d-r-sm)!important;}
.pagination>.active>a,
.pagination>.active>a:focus,
.pagination>.active>a:hover{background-color:var(--d-red)!important;border-color:var(--d-red)!important;color:#fff!important;}

/* ---------------- footer ---------------- */
footer>p{color:var(--d-muted)!important;}

/* ---------------- dashboard charts (transparent canvas; line recolored in JS) ---------------- */
#overview_chart, #sent_chart, #opened_chart, #clicked_chart,
#submitted_data_chart, #email_reported_chart{background:transparent!important;}
canvas{background:transparent!important;}

/* ---------------- Highcharts timeline text (campaign stat labels: "Email Sent", etc.) ---------------- */
/* GoPhish renders these as SVG <text> with a dark default fill (rgb 51,51,51) — invisible on dark themes. */
body.theme-black .highcharts-container svg text.highcharts-title,
body.theme-navy  .highcharts-container svg text.highcharts-title{
  fill: var(--d-text)!important;
  color: var(--d-text)!important;
}

/* ---------------- local documentation pages ---------------- */
.divlon-doc{line-height:1.6;}
.divlon-doc h1{font-size:20px;margin:8px 0 18px;border-bottom:1px solid var(--d-border);padding-bottom:10px;}
.divlon-doc h2{font-size:16px;margin:26px 0 12px;color:var(--d-red);}
.divlon-doc h3{font-size:14px;margin:20px 0 10px;}
.divlon-doc p{margin:0 0 12px;color:var(--d-text);}
.divlon-doc ul{margin:0 0 14px 20px;}
.divlon-doc li{margin:4px 0;}
.divlon-doc code{background:rgba(127,127,127,.18);padding:1px 5px;border-radius:var(--d-r-sm);font-size:13px;}
.divlon-doc pre.doc-code{background:#11161c;border:1px solid var(--d-border);padding:12px 14px;border-radius:var(--d-r-md);overflow:auto;color:#cfe3ff;}
.divlon-doc pre.doc-code code{background:none;padding:0;}
.divlon-doc hr{border:0;border-top:1px solid var(--d-border);margin:24px 0;}
body.theme-soft .divlon-doc code{background:#eef2f6;}
body.theme-soft .divlon-doc pre.doc-code{background:#f4f6f9;color:#1f2937;border-color:#d0d5dd;}
.divlon-doc-footer{margin-top:28px;padding-top:14px;border-top:1px solid var(--d-border);color:var(--d-text);opacity:.65;font-size:13px;}
.divlon-doc-footer p{margin:2px 0;}

/* ---------------- docs shell (User Guide two-column layout) ---------------- */
.doc-shell{display:flex;gap:32px;align-items:flex-start;margin-top:8px;}
.doc-nav{flex:0 0 220px;position:sticky;top:76px;align-self:flex-start;max-height:calc(100vh - 96px);overflow-y:auto;padding-right:4px;}
.doc-nav .doc-group-label{color:var(--d-muted);font-size:10px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;margin:20px 0 6px;padding-left:10px;}
.doc-nav .doc-group-label:first-child{margin-top:0;}
/* !important required: the global `a{color:var(--d-red)!important}` base
   link rule otherwise wins over these regardless of source order, so every
   resting-state nav link rendered red instead of just the active one. */
.doc-nav a{display:block;padding:6px 10px;margin:1px 0;font-size:13px;color:var(--d-sidebar-text)!important;border-left:2px solid transparent;text-decoration:none;transition:background-color .15s,color .15s,border-color .15s;}
.doc-nav a:hover{background:var(--d-panel-2);color:var(--d-text-strong)!important;text-decoration:none;}
.doc-nav a.active{background:var(--d-panel-2);color:var(--d-red)!important;border-left-color:var(--d-red);font-weight:600;}
/* Soft-only: .doc-nav lives in the light content pane, not the actual
   dark sidebar, so it can't use --d-sidebar-text (a LIGHT colour meant
   for a dark background) without going near-invisible. Navy/Black keep
   dark panels where --d-sidebar-text already reads fine. Same class of
   fix for the dashboard chart legend and the compare-modal rules list,
   which sit in the same light panels. */
body.theme-soft .doc-nav a{color:var(--d-muted)!important;}
body.theme-soft .doc-nav a:hover{color:var(--d-text-strong)!important;}
body.theme-soft .doc-nav a.active{color:var(--d-red)!important;}
body.theme-soft .dp-legend-item{color:var(--d-text)!important;}
body.theme-soft .cmp-rules li{color:var(--d-text)!important;}
.doc-content{flex:1 1 auto;min-width:0;max-width:760px;}
.doc-crumb{display:inline-flex;align-items:center;gap:6px;font-family:'Courier New',monospace;font-size:12px;background:var(--d-panel-2);border:1px solid var(--d-border);padding:6px 12px;border-radius:var(--d-r-xl);color:var(--d-muted);margin-bottom:22px;}
.doc-crumb .doc-crumb-current{color:var(--d-red);font-weight:600;}
/* Numbered walkthrough steps — a real <ol> with a circular counter badge
   instead of the browser's default marker, so multi-paragraph steps (a
   heading + explanation) still read as one numbered unit. */
.doc-steps{list-style:none;margin:0 0 18px;padding:0;counter-reset:doc-step;}
.doc-steps>li{position:relative;padding:0 0 16px 34px;counter-increment:doc-step;}
.doc-steps>li:last-child{padding-bottom:0;}
.doc-steps>li::before{content:counter(doc-step);position:absolute;left:0;top:1px;width:22px;height:22px;line-height:22px;text-align:center;background:var(--d-red);color:#fff;font-size:12px;font-weight:700;border-radius:50%;}
.doc-steps>li>strong:first-child{display:block;color:var(--d-text-strong);margin-bottom:2px;}
/* Arrow-bulleted list for enumerating options/choices (scan types, field
   lists) instead of a plain browser bullet. */
.doc-arrow-list{list-style:none;margin:0 0 16px;padding:0;}
.doc-arrow-list>li{position:relative;padding:2px 0 2px 18px;margin:4px 0;}
.doc-arrow-list>li::before{content:"▸";position:absolute;left:0;color:var(--d-red);font-size:12px;}
/* Field reference — <dt> = the exact form-field label as it appears on the
   module's page, <dd> = what it does. Keeps docs traceable to the actual UI
   instead of paraphrasing form labels into prose. */
.doc-fields{margin:0 0 18px;}
.doc-fields dt{font-family:'Courier New',monospace;font-size:13px;color:var(--d-text-strong);background:rgba(127,127,127,.14);display:inline-block;padding:2px 7px;border-radius:var(--d-r-sm);margin-top:10px;}
.doc-fields dd{margin:4px 0 0;color:var(--d-text);}
.doc-callout{border:1px solid var(--d-border);border-left:3px solid var(--d-red);background:var(--d-panel-2);padding:12px 16px;margin:0 0 18px;font-size:14px;color:var(--d-text);border-radius:var(--d-r-md);}
.doc-callout strong{color:var(--d-text-strong);}
/* One topic visible at a time — clicking a nav item is a page-to-page
   jump, not a scroll within one long document. */
.doc-section{display:none;}
.doc-section.active{display:block;}
@media (max-width:900px){
  .doc-shell{display:block;}
  .doc-nav{position:static;max-height:none;margin-bottom:24px;flex-basis:auto;}
}

/* ---------------- SweetAlert2 ----------------
   Global chrome so every Swal.fire() call site (37 of them across
   static/js/src/app/*.js) picks up branded icon/title/cancel/footer
   styling automatically, instead of each call site re-styling itself
   inline. .swal2-header's own flex-direction (column, centered) is a
   shared base for all of them and stays untouched here on purpose — the
   one dialog needing a row layout (training-picker) gets a scoped
   .dp-training-header override via customClass, not a global change. */
.swal2-popup{background-color:var(--d-panel)!important;color:var(--d-text)!important;border-radius:var(--d-r-lg)!important;padding:var(--d-space-lg)!important;}
/* User-requested (live): "no sweet alert, the kind used in Comply" -- a
   plain modal (title + left-aligned description + footer), not the
   centered icon-above-title "alert" look. Hiding the icon removes its
   layout box entirely (display:none), so .swal2-header's remaining
   children (title/description) no longer need to make room for it. */
.swal2-icon{display:none!important;}
.swal2-header{align-items:flex-start!important;}
.swal2-content{text-align:left!important;}
.swal2-title{text-align:left!important;font-size:16px!important;font-weight:600!important;color:var(--d-text-strong)!important;margin:0 0 var(--d-space-sm)!important;padding:0!important;}
.swal2-actions{justify-content:flex-end!important;gap:var(--d-space-sm)!important;margin-top:var(--d-space-lg)!important;}
/* Vendored swal2-styled default is padding:.625em 2em + font-size:1.0625em
   -- same oversized-button complaint as .btn above, same Comply-scale fix
   (user-reported, live screenshot of the Resend Campaign confirm dialog). */
.swal2-styled{margin:0!important;padding:5px 14px!important;font-size:13px!important;font-weight:600!important;}
.swal2-cancel{background-color:var(--d-panel-2)!important;border:1px solid var(--d-border)!important;color:var(--d-text)!important;border-radius:var(--d-r-md)!important;box-shadow:none!important;}
.swal2-cancel:hover,.swal2-cancel:focus{background-color:color-mix(in srgb, var(--d-panel-2) 80%, var(--d-text-strong) 10%)!important;color:var(--d-text-strong)!important;}
.swal2-confirm{background-color:var(--d-red)!important}
.swal2-confirm:hover,.swal2-confirm:focus{background-color:#d12e40!important}
/* Warning/error icons pick up the brand red; success/info/question stay
   on SweetAlert2's stock colours (research Open-Q2: keep success a
   distinct positive green, not red-on-red with the destructive icons). */
.swal2-icon.swal2-warning{border-color:var(--d-red)!important;color:var(--d-red)!important;}
.swal2-icon.swal2-error{border-color:var(--d-red)!important;}
.swal2-icon.swal2-error .swal2-x-mark-line-left,
.swal2-icon.swal2-error .swal2-x-mark-line-right{background-color:var(--d-red)!important;}

/* ============================================================
   Divlon feature layer (divlon-features.js)
   ============================================================ */

/* ---------------- loader (corner-bracket ring + percentage) ---------------- */
/* No !important here: the engine hides #loading with an inline display:none,
   which must win over this rule. */
#loading{display:flex;justify-content:center;padding:70px 0;}
.dl-wrap{display:flex;flex-direction:column;align-items:center;gap:14px;}
.dl-box{position:relative;width:72px;height:72px;display:flex;align-items:center;justify-content:center;}
.dl-c{position:absolute;width:10px;height:10px;border:0 solid var(--d-red);animation:dl-pulse 1.6s ease-in-out infinite;}
.dl-tl{top:0;left:0;border-top-width:2px;border-left-width:2px;}
.dl-tr{top:0;right:0;border-top-width:2px;border-right-width:2px;animation-delay:.4s;}
.dl-br{bottom:0;right:0;border-bottom-width:2px;border-right-width:2px;animation-delay:.8s;}
.dl-bl{bottom:0;left:0;border-bottom-width:2px;border-left-width:2px;animation-delay:1.2s;}
@keyframes dl-pulse{
  0%,100%{opacity:.25;transform:scale(1);}
  50%{opacity:1;transform:scale(1.35);filter:drop-shadow(0 0 6px rgba(var(--d-red-rgb),.8));}
}
.dl-pct{font-size:15px;font-weight:700;color:var(--d-text-strong);letter-spacing:.02em;font-variant-numeric:tabular-nums;}
.dl-label{font-size:10px;font-weight:700;letter-spacing:.3em;text-transform:uppercase;color:var(--d-muted);animation:flicker 3s ease-in-out infinite;}

/* ---------------- dashboard gauges ---------------- */
.dp-gauges{display:flex!important;flex-wrap:wrap;justify-content:space-around;align-items:flex-start;margin:6px 0 22px!important;gap:12px;}
.dp-gauge-block{display:flex;flex-direction:column;align-items:center;min-width:120px;}
.gauge-wrap{position:relative;width:112px;height:112px;}
.gauge-ring{
  position:absolute;inset:0;border-radius:50%;
  background:conic-gradient(var(--c,var(--d-red)) calc(var(--p,0)*1%),var(--d-border-strong) 0);
  -webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 9px),#000 calc(100% - 8px));
          mask:radial-gradient(farthest-side,transparent calc(100% - 9px),#000 calc(100% - 8px));
  filter:drop-shadow(0 0 10px rgba(var(--d-red-rgb),.18));
  transition:background .6s ease;
}
/* count sits OUTSIDE the masked ring element (a mask hides children too) */
.gauge-count{
  position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  font-size:24px;font-weight:700;color:var(--d-text-strong);pointer-events:none;
}
.gauge-label{margin-top:10px;font-size:13px;font-weight:500;color:var(--d-text-strong);}
.gauge-pct{font-size:11px;color:var(--d-muted);margin-top:2px;font-variant-numeric:tabular-nums;}

/* ---------------- Divlon panels + legacy containers ---------------- */
.dp-panel{
  position:relative;background:var(--d-panel);border:1px solid var(--d-border);
  padding:16px;margin-bottom:20px;border-radius:var(--d-r-lg);
  box-shadow:0 1px 2px rgba(0,0,0,0.04), 0 8px 24px -14px rgba(0,0,0,0.12);
}
.dp-panel-title{
  display:flex;align-items:center;gap:8px;margin:0 0 12px;
  font-size:12px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--d-text-strong);
}
.dp-panel-icon{color:var(--d-red);}
.dp-panel-sub{text-transform:none;font-weight:400;font-size:12px;color:var(--d-muted);letter-spacing:.02em;}
.dp-panel-meta{margin-left:auto;text-transform:none;font-weight:400;font-size:11px;color:var(--d-muted);}
.dp-legacy{display:none!important;}
/* The engine chart carries its own Highcharts title; the panel header replaces it. */
#overview_panel_body .highcharts-title{display:none;}
.dp-recent-header h2{font-size:16px!important;text-transform:uppercase;letter-spacing:.06em;}

/* click-trends date-range picker (30d/3mo/1yr presets + custom range popover) */
.dp-trends-controls{display:flex;align-items:center;justify-content:flex-end;position:relative;margin-bottom:12px;}
.dp-range-pills{display:inline-flex;gap:6px;flex-wrap:wrap;}
.dp-range-pill{
  background:var(--d-input-bg);border:1px solid var(--d-input-border);color:var(--d-muted);
  font-size:11px;font-weight:600;letter-spacing:.02em;padding:5px 12px;border-radius:var(--d-r-sm);
  cursor:pointer;transition:background-color .15s,border-color .15s,color .15s;
}
.dp-range-pill:hover{border-color:var(--d-red);color:var(--d-text);}
.dp-range-pill.active{background:var(--d-red);border-color:var(--d-red);color:#fff;}
.dp-range-pill-cal{display:inline-flex;align-items:center;gap:6px;}
.dp-range-popover{
  position:absolute;top:calc(100% + 6px);right:0;z-index:20;
  background:var(--d-panel-2);border:1px solid var(--d-border-strong);border-radius:var(--d-r-md);
  padding:12px;display:flex;align-items:flex-end;gap:10px;flex-wrap:wrap;
  box-shadow:0 8px 24px rgba(0,0,0,.4);
}
.dp-range-popover[hidden]{display:none;}
.dp-range-popover-label{font-size:10px;text-transform:uppercase;letter-spacing:.06em;color:var(--d-muted);display:block;margin-bottom:4px;}
.dp-range-date{background:var(--d-input-bg);border:1px solid var(--d-input-border);color:var(--d-text);
  font-size:12px;padding:5px 8px;border-radius:var(--d-r-sm);color-scheme:dark;}
body.theme-soft .dp-range-date{color-scheme:light;}
.dp-range-apply{background:var(--d-red);border:1px solid var(--d-red);color:#fff;font-size:11px;font-weight:600;
  padding:7px 14px;border-radius:var(--d-r-sm);cursor:pointer;transition:background-color .15s;}
.dp-range-apply:hover{background:var(--d-red-2);}

/* chart legend under the trends panel */
.dp-legend{display:flex;justify-content:center;align-items:center;gap:22px;padding-top:8px;flex-wrap:wrap;}
.dp-legend-item{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--d-sidebar-text);}
.dp-dot{width:10px;height:10px;border-radius:50%;display:inline-block;box-shadow:0 0 6px rgba(255,255,255,.25);}
.dp-dot-total{background:#f8f9fa;}
body.theme-soft .dp-dot-total{background:#1e2d40;}
.dp-legend-rules{margin-left:auto;font-size:11px;color:var(--d-muted);cursor:pointer;}
.dp-legend-rules:hover{color:var(--d-red);}

/* ---------------- campaign comparison ---------------- */
/* Checkbox + name live in one flex row (.cmp-row) so they always share the
   same vertical center, regardless of the table row's line-height — relying
   on vertical-align alone left the checkbox floating above the name text. */
.cmp-row{display:flex;align-items:center;}
.cmp-check{
  appearance:none;-webkit-appearance:none;-moz-appearance:none;
  position:relative;width:16px;height:16px;flex:0 0 auto;
  margin:0 12px 0 0!important;padding:0!important;
  border:1.5px solid var(--d-muted)!important;border-radius:3px!important;
  background:var(--d-input-bg)!important;cursor:pointer;
  transition:background-color .15s,border-color .15s;
}
.cmp-check:hover{border-color:var(--d-red)!important;}
.cmp-check:checked{background:var(--d-red)!important;border-color:var(--d-red)!important;}
.cmp-check:checked::after{
  content:"\f00c";font-family:FontAwesome;font-weight:400;font-size:10px;line-height:1;color:#fff;
  position:absolute;top:2px;left:2px;
}
td.cmp-cell{vertical-align:middle!important;}
.cmp-loading{text-align:center;padding:36px 0;color:var(--d-muted);}
.cmp-table th,.cmp-table td{vertical-align:middle!important;border-color:var(--d-border-soft)!important;}
.cmp-table th:first-child,.cmp-table td.cmp-label{width:150px;}
/* table-layout:fixed: with 2-4 campaign columns of varying name length and
   no table-layout set, the browser's auto layout squeezed the header <th>s
   below their nowrap-text preferred width once the names together exceeded
   the modal's available space — the generic .table>thead>tr>th rule forces
   white-space:nowrap with no overflow:hidden, so the squeezed text just
   rendered past its own column boundary into the next header (the
   "overlapping campaign names" bug). Fixed layout makes every un-pinned
   column split the remaining width evenly instead, so it can't happen
   regardless of how many campaigns are being compared (2-4). */
.cmp-table{table-layout:fixed;}
.cmp-name{display:flex;align-items:center;gap:7px;font-size:14px;font-weight:600;color:var(--d-text-strong);}
.cmp-dot{width:9px;height:9px;border-radius:50%;flex:0 0 auto;}
/* min-width:0 overrides the flex-item default (auto, i.e. "never shrink
   below content size") so the name can actually truncate to its fixed-
   layout column width instead of forcing the column wider or overflowing
   it — same fixed-layout-needs-an-explicit-overflow-plan lesson as
   .dash-campaign-table. title= on the element (see divlon-features.js)
   keeps the full name reachable on hover once it's truncated. */
.cmp-name-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;flex:1 1 auto;}
.cmp-sub{font-size:11px;color:var(--d-muted);font-weight:400;margin-top:2px;}
.cmp-label{font-size:12px;font-weight:600;color:var(--d-muted);text-transform:uppercase;letter-spacing:.04em;}
.cmp-val{font-size:14px;font-weight:600;color:var(--d-text-strong);margin-bottom:4px;font-variant-numeric:tabular-nums;}
.cmp-bar{height:5px;background:var(--d-input-bg);border-radius:var(--d-r-sm);overflow:hidden;}
.cmp-bar span{display:block;height:100%;border-radius:var(--d-r-sm);transition:width .4s ease;}
.cmp-best td{background:rgba(46,204,113,.07)!important;}
tr.cmp-best{background:rgba(46,204,113,.07)!important;}
.cmp-rules{background:var(--d-panel-2);border:1px solid var(--d-border);padding:12px 14px;margin-top:14px;border-radius:var(--d-r-md);}
.cmp-rules-title{font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:rgba(var(--d-red-rgb),.75);margin-bottom:8px;}
.cmp-rules ul{margin:0 0 8px;padding-left:18px;}
.cmp-rules li{font-size:12px;color:var(--d-sidebar-text);margin:3px 0;}
.cmp-reason-n{display:inline-block;min-width:20px;text-align:center;background:rgba(var(--d-red-rgb),.18);color:#ff8f9c;border-radius:3px;font-size:11px;font-weight:700;padding:1px 5px;margin-right:4px;}
body.theme-soft .cmp-reason-n{color:#b91c33;background:rgba(var(--d-red-rgb),.12);}
.cmp-rules-note{font-size:11px;color:var(--d-muted);}

/* Dark themes: Select2's closed box AND its open dropdown popup both
   render their own WHITE surface that the rest of this theme never touched.
   Genuinely darken both surfaces on the two dark themes so no white box
   survives (New Campaign's Template/Landing Page/Sending Profile/Groups
   pickers, and every other select2 instance app-wide); Soft is untouched
   since white is already correct there. */
body.theme-black .select2-container--bootstrap .select2-selection,
body.theme-navy .select2-container--bootstrap .select2-selection{
  background-color:var(--d-input-bg)!important;
  border-color:var(--d-input-border)!important;
}
body.theme-black .select2-container--bootstrap .select2-selection__rendered,
body.theme-navy .select2-container--bootstrap .select2-selection__rendered,
body.theme-black .select2-container--bootstrap .select2-selection__placeholder,
body.theme-navy .select2-container--bootstrap .select2-selection__placeholder{
  color:var(--d-text)!important;
}
body.theme-black .select2-dropdown,
body.theme-navy .select2-dropdown{
  background-color:var(--d-panel-2)!important;
  border-color:var(--d-border-strong)!important;
}
body.theme-black .select2-results__option,
body.theme-navy .select2-results__option,
body.theme-black .select2-search__field,
body.theme-navy .select2-search__field{
  background-color:var(--d-panel-2)!important;
  color:var(--d-text)!important;
}
/* Multi-select "chip" tags (Groups picker) - the vendor CSS hardcodes a
   white pill (background:#fff) per selected item, separate from the box
   background handled above. */
body.theme-black .select2-selection__choice,
body.theme-navy .select2-selection__choice{
  background-color:var(--d-panel)!important;
  border-color:var(--d-border-strong)!important;
  color:var(--d-text)!important;
}
/* CKEditor's Source textarea view is a separate, still-white surface this
   dark pass deliberately leaves alone (out of scope here) - keep its
   dark-on-white contrast fix as it was. */
body.theme-black .cke_source,
body.theme-navy .cke_source{color:#1f2328!important;}
.select2-container--bootstrap .select2-selection{border-radius:var(--d-r-sm)!important;}
.select2-dropdown{border-radius:var(--d-r-sm)!important;}
.select2-selection__choice{border-radius:var(--d-r-sm)!important;}

/* Off-brand Bootstrap "-primary" blue (#337ab7 family) leaking through on
   widgets/components that only .btn-primary/.label-primary were themed
   for. Same fix pattern as .btn-primary/.label-primary above: swap the
   stock blue for the brand red. Deliberately NOT touching .btn-info/
   .label-info - those keep a distinct blue accent on purpose. */
.checkbox-primary input[type=checkbox]:checked+label::before,
.checkbox-primary input[type=radio]:checked+label::before,
.radio-primary input[type=radio]:checked+label::before,
.radio-primary input[type=radio]+label::after,
.radio-primary input[type=radio]:checked+label::after{
  background-color:var(--d-red)!important;border-color:var(--d-red)!important;
}
/* .radio (checkbox.css, the vendored awesome-bootstrap-checkbox library) never
   vertically centers its circle against the label text - unlike its sibling
   .checkbox, which has a hardcoded `margin-top:5px` nudge baked in for that
   exact purpose, .radio label::before/::after have NO top offset at all.
   Center both pseudo-elements independently via top:50%+translateY so it's
   exact regardless of label font-size/line-height.

   ::after (the inner dot) is how checkbox.css shows/hides the checked state
   at all - unchecked sits at transform:scale(0,0), :checked flips it to
   scale(1,1). Composing translateY with that same scale (rather than
   overwriting it) keeps the checked/unchecked toggle working. */
.radio label::before{top:50%!important;margin-top:0!important;transform:translateY(-50%);}
.radio label::after{top:50%!important;margin-top:0!important;transform:translateY(-50%) scale(0);}
.radio input[type="radio"]:checked+label::after{transform:translateY(-50%) scale(1);}
.panel-primary{border-color:var(--d-red)!important;}
.panel-primary>.panel-heading{background-color:var(--d-red)!important;border-color:var(--d-red)!important;color:#fff!important;}
.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:var(--d-red)!important;}
.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:var(--d-red)!important;}
.dropdown-menu>.active>a,
.dropdown-menu>.active>a:focus,
.dropdown-menu>.active>a:hover{background-color:var(--d-red)!important;}
.select2-container--bootstrap .select2-results__option--highlighted[aria-selected]{background-color:var(--d-red)!important;color:#fff!important;}
.select2-container--bootstrap.select2-container--focus .select2-selection,
.select2-container--bootstrap.select2-container--open .select2-selection{
  border-color:var(--d-red)!important;
  box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(var(--d-red-rgb),.5)!important;
}
.select2-container--bootstrap .select2-dropdown{border-color:var(--d-red)!important;}
.bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:var(--d-red)!important;}
.bootstrap-datetimepicker-widget table td.active,
.bootstrap-datetimepicker-widget table td.active:hover,
.bootstrap-datetimepicker-widget table td span.active{background-color:var(--d-red)!important;color:#fff!important;text-shadow:none!important;}

/* ---------------- Landing Pages card grid ----------------
   .preview-card is page-scoped CSS (landing_pages.html) with its own
   hardcoded 6px radius — override to match the shared --d-r-lg rounding. */
.preview-card{border-radius:var(--d-r-lg)!important;}
.preview-card-thumb{border-top-left-radius:var(--d-r-lg)!important;border-top-right-radius:var(--d-r-lg)!important;}

@media print{
  body.theme-soft{background-image:none!important;}
  .main::before{display:none;}
  .navbar-inverse,
  .sidebar,
  .main,
  .panel{
    background:#fff!important;-webkit-backdrop-filter:none;backdrop-filter:none;box-shadow:none!important;
  }
  body.theme-soft .sidebar{color:#241a1c;}
}
