/* ============================================================================
   DARK THEME
   Palette lifted from the release-notes mock (GitHub-dark family, orange accent).
   Everything is scoped under html[data-theme="dark"], so the light theme is
   untouched. The Syncfusion theme link is swapped separately to
   bootstrap5-dark.css by scripts/theme-switcher.js — Phase 2
   (docs/dark-theme/plan-dark-theme.md, P2.1) formally adopted this
   runtime-swap mechanism (no bootstrap5.3 attribute-based theme exists for
   the installed Syncfusion.Blazor.Themes version); the rules here retint
   Syncfusion's generic dark greys to this palette and counter the hardcoded
   light-theme overrides in site.css / Navbar.razor.

   Palette values themselves live in tokens.css (--surface/--text/--border/
   --accent/--status-*, light + dark) — load tokens.css before this file.
   ========================================================================== */

/* ------------------------------------------------------------------ page */

/* Blazor Server's built-in reconnection UI (#components-reconnect-modal) -- injected directly
   by blazor.server.js at runtime, not part of this app's markup/CSS at all, so it has never had
   any styling of its own here. Its background comes from the framework's own default (light,
   fixed), while its text inherited this app's dark-mode body color (light), producing
   near-invisible light-on-light text. data-theme is a plain <html> attribute set independently
   of the SignalR circuit (theme-switcher.js's pre-paint script), so it's still correctly present
   even while the connection itself is down. */
html[data-theme="dark"] #components-reconnect-modal {
    background-color: var(--surface-raised) !important;
    color: var(--text) !important;
}

html[data-theme="dark"] body {
    background-color: var(--surface) !important;
    color: var(--text);
    /* Phase 9 P9.3: light text on a dark surface renders visibly heavier than the same
       weight on a light surface (a browser anti-aliasing artifact, not an actual font-weight
       change) -- most pronounced at this app's 12px Nunito Sans base size. Antialiased
       smoothing is the standard correction; scoped to dark mode only since light mode's
       dark-on-light text doesn't have this perceived-bolding effect. */
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

html[data-theme="dark"] .main-content,
html[data-theme="dark"] .main-part {
    background-color: var(--surface);
}

/* Gap G3 (2026-08-19, plan-dark-theme-gap-remediation.md Step 4): this used to be
   `html[data-theme="dark"] h1, ... p { color: var(--text); }`, specificity (0,1,2) -- higher
   than a typical component-scoped rule like `.unauthorized-card h1 { color: #0f172a; }`
   (0,1,1), so it silently overrode heading/paragraph color on screens the dark-theme rollout
   never touched, leaving them half-applied (text flipped, background unchanged). Wrapping the
   tag list in :where() drops this rule's specificity to that of the bare `html[data-theme="dark"]`
   prefix, so any component-scoped rule with at least a class now wins regardless of load order. */
html[data-theme="dark"] :where(h1, h2, h3, h4, h5, h6, label, p) {
    color: var(--text);
}

html[data-theme="dark"] a:not(.btn):not(.nb-nav-item):not(.nav-link) {
    color: var(--accent);
}

/* This generic link-color rule's three :not() clauses each add class-level specificity
   (0,4,1 total), beating the job-card icon toolbar's own .event-template/.content-area
   .icons a { color: var(--jp-2)/--bjp-2 } rule (0,2,1) in JobsPage.razor/BasicJobsPage.razor,
   so those icons silently went amber (--accent) in dark mode instead of staying the fixed
   white --jp-2/--bjp-2 already renders in light mode. Job-card icons are meant to read the
   same white regardless of theme, same as the rest of that toolbar's iconography -- add
   .icons to the exclusion set with matching specificity to win back dark mode too. */
html[data-theme="dark"] .icons a:not(.btn):not(.nb-nav-item):not(.nav-link) {
    color: #fff;
}

html[data-theme="dark"] ::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}

html[data-theme="dark"] ::-webkit-scrollbar-track {
    background: var(--surface);
}

html[data-theme="dark"] ::-webkit-scrollbar-thumb {
    background: var(--surface-hover);
    border-radius: 5px;
}

/* --------------------------------------------------------- navbar chrome */
/* counters hardcoded #fff / slate greys in Navbar.razor's <style> block   */

html[data-theme="dark"] .nb-header {
    background: var(--surface-raised) !important;
    border-bottom: 1px solid var(--border) !important;
}

html[data-theme="dark"] .nb-divider-v {
    background: var(--border-strong) !important;
}

html[data-theme="dark"] .nb-portal-label {
    color: var(--text-faint) !important;
}

html[data-theme="dark"] .nb-portal-name,
html[data-theme="dark"] .nb-brand-group,
html[data-theme="dark"] .nb-dd-info {
    color: var(--text) !important;
}

html[data-theme="dark"] .nb-nav-item:not(.nb-nav-referral) {
    color: var(--text-secondary) !important;
}

html[data-theme="dark"] .nb-nav-item:hover:not(.nb-nav-referral) {
    background: var(--surface-inset) !important;
    color: var(--text) !important;
}

html[data-theme="dark"] .nb-nav-item.nb-nav-active:not(.nb-nav-referral),
html[data-theme="dark"] .nb-nav-item.active:not(.nb-nav-referral) {
    background: var(--accent-bg) !important;
    color: var(--accent) !important;
}

html[data-theme="dark"] .nb-avatar-btn:hover {
    background: var(--surface-inset) !important;
}

html[data-theme="dark"] .nb-verify-dot {
    background: var(--surface-raised) !important;
    border-color: var(--border-strong) !important;
}

html[data-theme="dark"] .nb-dd {
    background: var(--surface-inset) !important;
    border-color: var(--border-strong) !important;
    box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5) !important;
}

html[data-theme="dark"] .nb-dd-rule {
    background: var(--border) !important;
}

html[data-theme="dark"] .nb-dd a,
html[data-theme="dark"] .nb-dd button,
html[data-theme="dark"] .nb-dd-item {
    color: var(--text-secondary) !important;
}

html[data-theme="dark"] .nb-dd a:hover,
html[data-theme="dark"] .nb-dd button:hover,
html[data-theme="dark"] .nb-dd-item:hover {
    background: var(--surface-hover) !important;
    color: var(--text) !important;
}

html[data-theme="dark"] .nb-mobile-drawer {
    background: var(--surface-raised) !important;
}

html[data-theme="dark"] .nb-dd-submenu {
    background: var(--surface-inset) !important;
    border-color: var(--border) !important;
}

/* -------------------------------------------------- bootstrap components */

html[data-theme="dark"] .card {
    background-color: var(--surface-raised) !important;
    border: 1px solid var(--border) !important;
    color: var(--text);
    box-shadow: none !important;
}

html[data-theme="dark"] .card-header,
html[data-theme="dark"] .card-footer {
    background-color: var(--surface-inset) !important;
    border-color: var(--border) !important;
    color: var(--text);
}

/* P3.4 was attempted 2026-08-05: tried removing these to see if Bootstrap 5.3's native
   [data-bs-theme="dark"] styling could replace them. Reverted — confirmed regression: site.css
   has its own UNCONDITIONAL `.form-control { background: rgb(254,254,254) }` rule (no theme
   scoping) that loads after Bootstrap but before this file, so it always beats Bootstrap's own
   color-mode CSS regardless of data-bs-theme. Only this file's override (loaded last) can win.
   Not fixable until Phase 4 removes/tokenizes that site.css literal — see
   dark-theme.technical.md and findings-todo.md. */
html[data-theme="dark"] .modal-content {
    background-color: var(--surface-raised) !important;
    border: 1px solid var(--border-strong) !important;
    color: var(--text);
}

/* SfSignature's canvas is deliberately left white (see the dark-theme-customer-portal-unpin
   branch's commit for reasoning: signatures are captured as black ink and are meant to look
   right when embedded into the actual printed/PDF paperwork afterward). Syncfusion's own
   bootstrap5-dark.css already frames it (border-color: #444c54, a solid opaque grey) -- but
   --border-strong is a *translucent white* overlay meant to sit on dark surfaces, invisible
   against a white canvas edge (translucent-white-on-white is a contradiction, same mistake as
   the original checkbox border). Used --text-secondary instead: opaque, reads clearly against
   both the white canvas and the dark page around it. */
html[data-theme="dark"] .e-signature {
    border: 1px solid var(--text-secondary) !important;
    border-radius: 6px;
}

/* CustomerPortalPageNew.razor's own .bg-blue rule (Submit Purchase Form button) lost the
   cascade to this file's generic html[data-theme="dark"] .form-control rule (specificity
   0,2,0) despite both using !important -- the button carries both .form-control and .bg-blue
   classes, and bare .bg-blue is only 0,1,0. Repeating it here with .form-control in the
   selector matches that specificity so this one wins instead. */
html[data-theme="dark"] .bg-blue.form-control {
    background-color: var(--accent) !important;
    color: var(--text-on-accent) !important;
    border-color: var(--accent) !important;
}

/* Bootstrap's .alert-* family had zero dark-theme coverage anywhere in the app -- relies
   entirely on Bootstrap 5.3's own [data-bs-theme="dark"] alert theming, which computes very
   low-contrast text-on-background for at least .alert-info (reported: CustomerPortalPageNew's
   "Process completed" alert-info box, text nearly invisible against its own background).
   Retinted to this app's status tokens (tinted bg + saturated status color for text/border),
   the same "status colors as tinted chips" pattern used throughout the dark palette. Used
   across both customer-portal pages (CustomerPortalPageNew, TowPortalPage) and internal-app
   dialogs (TowServiceJobDetailDialog, TowServiceEditDialog). */
html[data-theme="dark"] .alert-info {
    background-color: var(--status-info-bg) !important;
    border-color: var(--status-info) !important;
    color: var(--status-info) !important;
}

html[data-theme="dark"] .alert-success {
    background-color: var(--status-success-bg) !important;
    border-color: var(--status-success) !important;
    color: var(--status-success) !important;
}

html[data-theme="dark"] .alert-warning {
    background-color: var(--status-warning-bg) !important;
    border-color: var(--status-warning) !important;
    color: var(--status-warning) !important;
}

html[data-theme="dark"] .alert-danger {
    background-color: var(--status-error-bg) !important;
    border-color: var(--status-error) !important;
    color: var(--status-error) !important;
}

html[data-theme="dark"] .alert-info h1,
html[data-theme="dark"] .alert-info h2,
html[data-theme="dark"] .alert-info h3,
html[data-theme="dark"] .alert-info p,
html[data-theme="dark"] .alert-success h1,
html[data-theme="dark"] .alert-success h2,
html[data-theme="dark"] .alert-success h3,
html[data-theme="dark"] .alert-success p,
html[data-theme="dark"] .alert-warning h1,
html[data-theme="dark"] .alert-warning h2,
html[data-theme="dark"] .alert-warning h3,
html[data-theme="dark"] .alert-warning p,
html[data-theme="dark"] .alert-danger h1,
html[data-theme="dark"] .alert-danger h2,
html[data-theme="dark"] .alert-danger h3,
html[data-theme="dark"] .alert-danger p {
    color: inherit !important;
}

/* LeadSourceEditPage.razor inline <style> hardcodes #ffffff */
html[data-theme="dark"] .sn-form-group {
    background-color: var(--surface-raised) !important;
    color: var(--text);
}

/* Phase 6: .sn-btn-light (site.css) uses --sn-btn-text-color (= --text-on-accent, an
   intentionally theme-invariant white) as its BACKGROUND, not foreground text -- a
   pre-existing misuse that only became visible once the surrounding dialogs went dark
   (Quote Accepted/Rejected/Pending/Pre-Quote Assessment buttons rendered solid white).
   Not fixed by changing the shared --sn-btn-text-color/--sn-btn-dark-background-color
   tokens themselves, since those are reused by other .sn-btn variants elsewhere; scoped
   override here instead, same pattern as every other "screen wrong in dark" fix. */
html[data-theme="dark"] .sn-btn-light {
    background-color: var(--surface-inset) !important;
    color: var(--text) !important;
    border-color: var(--border-strong) !important;
}

html[data-theme="dark"] .sn-btn-light:hover {
    background-color: var(--surface-hover) !important;
    color: var(--text) !important;
}

/* counters site.css .form-control background rgb(254,254,254) */
html[data-theme="dark"] .form-control,
html[data-theme="dark"] .form-select,
html[data-theme="dark"] input:not([type="checkbox"]):not([type="radio"]):not(.e-input),
html[data-theme="dark"] select,
html[data-theme="dark"] textarea {
    background-color: var(--surface-inset) !important;
    color: var(--text) !important;
    border-color: var(--border-strong) !important;
}

html[data-theme="dark"] .form-control:focus,
html[data-theme="dark"] .form-select:focus {
    border-color: var(--accent-bd) !important;
    box-shadow: 0 0 0 3px var(--accent-bg) !important;
}

/* Plain Bootstrap checkboxes/radios were excluded from the blanket .form-control rule above
   (checked state uses Bootstrap's own background-image + accent background, which the blanket
   rule would have overwritten) and were left with no dark-mode styling at all, falling back to
   Bootstrap's unthemed light-grey border -- scoped to :not(:checked) so the checked state stays
   untouched. Border lightened to --nb-text-faint, the navbar's own icon color token. */
html[data-theme="dark"] input[type="checkbox"].form-check-input:not(:checked),
html[data-theme="dark"] input[type="radio"].form-check-input:not(:checked) {
    background-color: var(--surface-inset) !important;
    border-color: var(--nb-text-faint) !important;
}

html[data-theme="dark"] ::placeholder {
    color: var(--text-faint) !important;
    opacity: 1;
}

/* Chrome autofill paints its own colors unless told otherwise */
html[data-theme="dark"] input:-webkit-autofill {
    -webkit-box-shadow: 0 0 0 1000px var(--surface-inset) inset !important;
    -webkit-text-fill-color: var(--text) !important;
}

html[data-theme="dark"] .table,
html[data-theme="dark"] table {
    color: var(--text);
}

html[data-theme="dark"] .table td,
html[data-theme="dark"] .table th {
    border-color: var(--border) !important;
}

/* Role/permissions matrix table (EditRolePermissions.razor.css) — hardcoded #f1f1f1 row
   borders read as a bright, crowded grid on a dark surface; retint to the border token. */
html[data-theme="dark"] .permissions-table tr {
    border-color: var(--border) !important;
}

html[data-theme="dark"] .permissions-table tr.perm-row:hover > * {
    background-color: var(--surface-hover) !important;
}

html[data-theme="dark"] .text-muted {
    color: var(--text-secondary) !important;
}

html[data-theme="dark"] .bg-white,
html[data-theme="dark"] .bg-light {
    background-color: var(--surface-raised) !important;
}

html[data-theme="dark"] .border,
html[data-theme="dark"] .border-top,
html[data-theme="dark"] .border-bottom,
html[data-theme="dark"] .border-start,
html[data-theme="dark"] .border-end {
    border-color: var(--border) !important;
}

/* ------------------------------------------------- syncfusion retinting */
/* bootstrap5-dark.css does the heavy lifting; these retint its generic    */
/* greys to the palette and counter light-theme overrides in site.css.     */

/* counters site.css hardcoded input border rgb(206,212,218) */
html[data-theme="dark"] .e-input-group input.e-input,
html[data-theme="dark"] .e-input-group.e-control-wrapper input.e-input,
html[data-theme="dark"] .e-input-group textarea.e-input,
html[data-theme="dark"] .e-input-group.e-control-wrapper textarea.e-input {
    border-color: var(--border-strong) !important;
    background: var(--surface-inset) !important;
    color: var(--text) !important;
}

html[data-theme="dark"] .e-input-group,
html[data-theme="dark"] .e-input-group.e-control-wrapper {
    background: var(--surface-inset) !important;
    color: var(--text) !important;
    border-color: var(--border-strong) !important;
}

html[data-theme="dark"] .e-float-text,
html[data-theme="dark"] .e-input-group .e-input-group-icon {
    color: var(--text-secondary) !important;
}

html[data-theme="dark"] .e-grid {
    background-color: var(--surface-raised) !important;
    border-color: var(--border) !important;
}

html[data-theme="dark"] .e-grid .e-headercell,
html[data-theme="dark"] .e-grid .e-headercontent,
html[data-theme="dark"] .e-grid .e-gridheader {
    background-color: var(--surface-inset) !important;
    color: var(--text) !important;
    border-color: var(--border) !important;
}

html[data-theme="dark"] .e-grid .e-rowcell {
    background-color: var(--surface-raised) !important;
    color: var(--text-secondary) !important;
    border-color: var(--border) !important;
}

/* Requested: drop the alternating-row stripe (was .e-altrow below at a barely-visible 1.5%
   white overlay) so every row reads as one consistent dark tone, and make hover/selected the
   only two states that stand out -- mirroring light mode, where every row is already the same
   white and only hover/selection breaks from it. Hover previously used --surface-inset
   (#171b26), which is almost indistinguishable from the row base --surface-raised (#161b27) --
   switched to --surface-hover (#252d3f), the noticeably lighter "smoke" tone already used for
   hover states elsewhere in this file, and reused for the explicit selected-row override below
   since Syncfusion's own default selection color is Bootstrap blue, not this tone. */
html[data-theme="dark"] .e-grid .e-row:hover .e-rowcell {
    background-color: var(--surface-hover) !important;
    color: var(--text) !important;
}

html[data-theme="dark"] .e-grid .e-row.e-active .e-rowcell,
html[data-theme="dark"] .e-grid .e-rowcell.e-active {
    background-color: var(--surface-hover) !important;
    color: var(--text) !important;
}

html[data-theme="dark"] .e-pager,
html[data-theme="dark"] .e-toolbar,
html[data-theme="dark"] .e-toolbar .e-toolbar-items {
    background-color: var(--surface-raised) !important;
    color: var(--text-secondary) !important;
    border-color: var(--border) !important;
}

html[data-theme="dark"] .e-toolbar .e-tbar-btn,
html[data-theme="dark"] .e-toolbar .e-tbar-btn .e-tbar-btn-text {
    background: transparent !important;
    color: var(--text-secondary) !important;
}

html[data-theme="dark"] .e-dialog,
html[data-theme="dark"] .e-popup,
html[data-theme="dark"] .e-dropdownbase,
html[data-theme="dark"] .e-ddl.e-popup {
    background-color: var(--surface-inset) !important;
    border-color: var(--border-strong) !important;
    color: var(--text) !important;
}

/* Phase 6: SfGrid's ellipsis-tooltip widget (triggered by ClipMode.EllipsisWithTooltip on
   long cell text, e.g. AllCarsPage's "Car Details" column) renders in its own e-tooltip-wrap
   portal, not .e-popup/.e-dropdownbase -- none of the rules above reach it. Even Syncfusion's
   own bootstrap5-dark.css leaves this widget light-grey (#e9ecef), so this had zero dark
   coverage from any source. Arrow triangle color is drawn via border-side tricks per
   direction, so all four need retinting to match the new background. */
html[data-theme="dark"] .e-tooltip-wrap,
html[data-theme="dark"] .e-tooltip-wrap.e-popup {
    background-color: var(--surface-inset) !important;
    border-color: var(--border-strong) !important;
}

html[data-theme="dark"] .e-tooltip-wrap .e-tip-content {
    color: var(--text) !important;
}

/* JobsPage.razor/BasicJobsPage.razor's own Schedule TooltipTemplate markup (the "Po No./Trip &
   job no./Purchase Type/..." job-detail box) sets its own text color via --jp-2/--bjp-2, a
   category-palette var hardcoded to #fff in both files' :root block regardless of app theme --
   an element's own declared color always wins over the inherited .e-tip-content rule above, so
   this needs its own override rather than relying on that ancestor rule. The Schedule's hover
   tooltip has no dedicated wrapper class of its own -- EnableTooltip renders through the same
   shared SfTooltip widget as every other tooltip in the app (.e-tooltip-wrap), which is why the
   selector below targets that real class rather than the previous ".e-schedule-event-tooltip",
   which doesn't exist anywhere in Syncfusion's Schedule or Popups bundles and never matched --
   the reason this fix silently never took effect. */
html[data-theme="dark"] .e-tooltip-wrap .tooltip-wrap,
html[data-theme="dark"] .e-tooltip-wrap .tooltip-wrap .name {
    color: var(--text) !important;
}

/* Schedule's click-triggered Quick Info popup (.e-quick-popup-wrapper) is a completely separate
   Syncfusion widget from the hover tooltip above and ships with its own hardcoded light styling
   (background:#fff, color:#212529, header background:#fff) that neither Syncfusion's own
   bootstrap5-dark.css swap nor any existing rule here reaches. */
html[data-theme="dark"] .e-quick-popup-wrapper {
    background-color: var(--surface-inset) !important;
    border-color: var(--border-strong) !important;
    color: var(--text) !important;
}

html[data-theme="dark"] .e-quick-popup-wrapper .e-cell-popup .e-popup-header,
html[data-theme="dark"] .e-quick-popup-wrapper .e-event-popup .e-popup-header {
    background-color: var(--surface-inset) !important;
}

html[data-theme="dark"] .e-quick-popup-wrapper .e-date-time,
html[data-theme="dark"] .e-quick-popup-wrapper .e-location,
html[data-theme="dark"] .e-quick-popup-wrapper .e-time-zone,
html[data-theme="dark"] .e-quick-popup-wrapper .e-description,
html[data-theme="dark"] .e-quick-popup-wrapper .e-resource,
html[data-theme="dark"] .e-quick-popup-wrapper .e-date-time-details,
html[data-theme="dark"] .e-quick-popup-wrapper .e-location-details,
html[data-theme="dark"] .e-quick-popup-wrapper .e-time-zone-details,
html[data-theme="dark"] .e-quick-popup-wrapper .e-description-details,
html[data-theme="dark"] .e-quick-popup-wrapper .e-resource-details,
html[data-theme="dark"] .e-quick-popup-wrapper .e-subject-wrap .e-subject {
    color: var(--text) !important;
}

html[data-theme="dark"] .e-quick-popup-wrapper .e-date-time-icon,
html[data-theme="dark"] .e-quick-popup-wrapper .e-location-icon,
html[data-theme="dark"] .e-quick-popup-wrapper .e-time-zone-icon,
html[data-theme="dark"] .e-quick-popup-wrapper .e-description-icon,
html[data-theme="dark"] .e-quick-popup-wrapper .e-resource-icon {
    color: var(--text-secondary) !important;
}

html[data-theme="dark"] .e-tooltip-wrap .e-arrow-tip-outer.e-tip-bottom {
    border-top-color: var(--surface-inset) !important;
}

html[data-theme="dark"] .e-tooltip-wrap .e-arrow-tip-outer.e-tip-top {
    border-bottom-color: var(--surface-inset) !important;
}

html[data-theme="dark"] .e-tooltip-wrap .e-arrow-tip-outer.e-tip-left {
    border-right-color: var(--surface-inset) !important;
}

html[data-theme="dark"] .e-tooltip-wrap .e-arrow-tip-outer.e-tip-right {
    border-left-color: var(--surface-inset) !important;
}

/* Syncfusion's SfTooltip widget (.e-tooltip-wrap/.e-popup) ships hardcoded to a dark chip
   (background-color:#212529) in its own LIGHT theme too -- by design, the same "floating dark
   tooltip on any surface" convention Bootstrap/VS Code/GitHub use, verified directly in
   bootstrap5.css. Every simple tooltip in the app (grid ellipsis tooltips, ToolbarItem
   TooltipText buttons like Jobs page's "Rearrange Job"/"Search & Cache"/"Force Fetch", the
   Jobs schedule hover tooltip above) inherits this, so it stays a dark box even while the rest
   of the app is in light mode. Requested explicitly: retint it to the same light tokens
   everything else already uses, mirroring the dark-mode rules above with the (already-default)
   light values from tokens.css's :root block. --text happens to equal Syncfusion's own #212529,
   so only the background/border actually need to move -- text color already looks correct by
   coincidence, but is set explicitly here for clarity and to survive any future token change. */
html[data-theme="light"] .e-tooltip-wrap,
html[data-theme="light"] .e-tooltip-wrap.e-popup {
    background-color: var(--surface-inset) !important;
    border-color: var(--border-strong) !important;
}

html[data-theme="light"] .e-tooltip-wrap .e-tip-content {
    color: var(--text) !important;
}

/* Same reasoning as the dark-mode .tooltip-wrap/.name override above: JobsPage.razor/
   BasicJobsPage.razor's own Schedule TooltipTemplate markup sets its own text color via
   --jp-2/--bjp-2 (hardcoded #fff), which an ancestor .e-tip-content rule can't reach. In light
   mode this was previously invisible-but-masked by Syncfusion's own dark tooltip background;
   now that the background above is retinted light, the hardcoded white text needs its own
   light-mode override too or it becomes white-on-near-white. */
html[data-theme="light"] .e-tooltip-wrap .tooltip-wrap,
html[data-theme="light"] .e-tooltip-wrap .tooltip-wrap .name {
    color: var(--text) !important;
}

html[data-theme="light"] .e-tooltip-wrap .e-arrow-tip-outer.e-tip-bottom {
    border-top-color: var(--surface-inset) !important;
}

html[data-theme="light"] .e-tooltip-wrap .e-arrow-tip-outer.e-tip-top {
    border-bottom-color: var(--surface-inset) !important;
}

html[data-theme="light"] .e-tooltip-wrap .e-arrow-tip-outer.e-tip-left {
    border-right-color: var(--surface-inset) !important;
}

html[data-theme="light"] .e-tooltip-wrap .e-arrow-tip-outer.e-tip-right {
    border-left-color: var(--surface-inset) !important;
}

html[data-theme="dark"] .e-dialog .e-dlg-header-content,
html[data-theme="dark"] .e-dialog .e-dlg-header,
html[data-theme="dark"] .e-dialog .e-footer-content {
    background-color: var(--surface-inset) !important;
    color: var(--text) !important;
    border-color: var(--border) !important;
}

/* 2026-08-13: .e-dlg-content (the dialog's actual body -- everything between the header and
   footer) was never covered by the .e-dialog rule above; it carries its own explicit
   background-color:#212529 straight from bootstrap5-dark.css that a same-specificity parent
   selector can't override, so every dialog's content area stayed at Syncfusion's default color
   regardless of the --surface-inset token. */
html[data-theme="dark"] .e-dialog .e-dlg-content {
    background-color: #1b202f !important;
}

html[data-theme="dark"] .e-dropdownbase .e-list-item {
    background-color: var(--surface-inset) !important;
    color: var(--text-secondary) !important;
}

html[data-theme="dark"] .e-dropdownbase .e-list-item.e-hover,
html[data-theme="dark"] .e-dropdownbase .e-list-item.e-active {
    background-color: var(--surface-hover) !important;
    color: var(--text) !important;
}

/* counters site.css accordion header #f8f8f8 */
html[data-theme="dark"] .e-accordion,
html[data-theme="dark"] .e-accordion .e-acrdn-item.e-select > .e-acrdn-header {
    background: var(--surface-raised) !important;
    color: var(--text-secondary) !important;
    border-color: var(--border) !important;
}

html[data-theme="dark"] .e-accordion .e-acrdn-header .e-acrdn-header-content {
    color: var(--text-secondary) !important;
}

html[data-theme="dark"] .e-sidebar {
    background-color: var(--surface-raised) !important;
    border-color: var(--border) !important;
}

html[data-theme="dark"] .e-tab .e-tab-header,
html[data-theme="dark"] .e-tab .e-tab-header .e-toolbar-item .e-tab-wrap {
    background: var(--surface-raised) !important;
}

html[data-theme="dark"] .e-tab .e-tab-header .e-toolbar-item .e-tab-text {
    color: var(--text-secondary) !important;
}

html[data-theme="dark"] .e-tab .e-tab-header .e-toolbar-item.e-active .e-tab-text {
    color: var(--accent) !important;
}

/* .sn-tabs (e.g. CarTowPage's "Tow Records" SfTab) — site.css has its own unconditional
   hardcoded light-grey styling for this class that our generic .e-tab rules above don't
   reach; found live during Phase 3 testing (unrelated to Bootstrap, a Phase 2/Syncfusion gap). */
html[data-theme="dark"] .sn-tabs .e-toolbar {
    border-color: var(--border) !important;
}

html[data-theme="dark"] .sn-tabs .e-toolbar-items {
    background-color: var(--surface-raised) !important;
}

html[data-theme="dark"] .sn-tabs .e-toolbar-item .e-tab-text {
    color: var(--text-secondary) !important;
}

html[data-theme="dark"] .sn-tabs .e-toolbar-item.e-active {
    background-color: var(--surface-hover) !important;
}

html[data-theme="dark"] .sn-tabs .e-tab-header::before {
    background-color: var(--surface-raised) !important;
}

/* Unchecked border was --border-strong (13%-opacity white in dark mode -- barely visible
   against the dark surface). Lightened to --nb-text-faint, the navbar's own icon color
   token (e.g. .nb-subnav ul.setting-list li a span:first-child i), per explicit ask to match
   that icon color. */
html[data-theme="dark"] .e-checkbox-wrapper .e-frame {
    background-color: var(--surface-inset) !important;
    border-color: var(--nb-text-faint) !important;
}

html[data-theme="dark"] .e-checkbox-wrapper .e-frame.e-check {
    background-color: var(--accent) !important;
    border-color: var(--accent) !important;
    color: #0d1117 !important;
}

/* Google Places Autocomplete (geocomplete.js, address fields) -- the .pac-* dropdown is
   injected by Google's own script directly onto <body>, outside the Blazor render tree, and
   ships with fixed light styling (white background, black text) that Google doesn't theme. */
html[data-theme="dark"] .pac-container {
    background-color: var(--surface-inset) !important;
    border: 1px solid var(--border-strong) !important;
    box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5) !important;
}

html[data-theme="dark"] .pac-item {
    background-color: transparent !important;
    border-top-color: var(--border) !important;
    color: var(--text-secondary) !important;
}

html[data-theme="dark"] .pac-item-query {
    color: var(--text) !important;
}

html[data-theme="dark"] .pac-item:hover,
html[data-theme="dark"] .pac-item-selected {
    background-color: var(--surface-hover) !important;
}

html[data-theme="dark"] .pac-matched {
    color: var(--accent) !important;
}

/* Phase 5 (P5.2): SfRadioButton wasn't in Phase 2's component sweep. Syncfusion's own
   bootstrap5-dark.css already renders a functional dark radio (dark circle, bootstrap-blue
   #0d6efd when checked) -- retinted here to the app's accent for brand consistency, same
   pattern as the .e-checkbox-wrapper rules above.
   2026-08-13: confirmed the real native geometry by reading bootstrap5-dark.css directly out of
   the Syncfusion.Blazor.Themes NuGet package (not vendored in-repo, so it can't be grepped the
   normal way) -- ::before is the 14x14 outer ring (checked state fills it SOLID with the brand
   color), ::after is a 6x6 dot centered inside it at top:4px/left:4px (checked state reveals it
   via transform:scale(1), colored white natively for contrast against the filled ring). An
   earlier same-day pass here had this backwards (kept ::before hollow, tried to fill the tiny
   ::after dot with accent instead) -- reverted to match Syncfusion's actual "solid ring + small
   contrast dot" design, just retinted. Explicit position/size values re-assert Syncfusion's own
   geometry defensively (a live DevTools inspection reported computed top:14px on ::after, which
   matches neither this file nor the vendor CSS -- likely a stale cached copy of bootstrap5-dark
   .css in the browser; asserting the values here is harmless if that's the whole story, and a
   real fix if some other stylesheet is winning a specificity fight we haven't found). NOTE:
   ::before deliberately has no explicit `top` -- native bootstrap5-dark.css doesn't set one
   either (only `left:0`), letting the browser center the ring against the label's own line box;
   an earlier pass here added `top:0 !important`, which pinned the ring to the label's very top
   edge instead and threw off vertical alignment against the label text -- removed. */
html[data-theme="dark"] .e-radio + label::before {
    left: 0 !important;
    width: 14px !important;
    height: 14px !important;
    background-color: var(--surface-inset) !important;
    border-color: var(--border-strong) !important;
}

html[data-theme="dark"] .e-radio + label::after {
    top: 4px !important;
    left: 4px !important;
    width: 6px !important;
    height: 6px !important;
    border: none !important;
}

html[data-theme="dark"] .e-radio:checked + label::before {
    background-color: var(--accent) !important;
    border-color: var(--accent) !important;
}

html[data-theme="dark"] .e-radio:checked + label::after {
    background-color: var(--surface) !important;
}

html[data-theme="dark"] .e-radio + label .e-label {
    color: var(--text) !important;
}

html[data-theme="dark"] .e-schedule,
html[data-theme="dark"] .e-schedule .e-schedule-table td,
html[data-theme="dark"] .e-schedule .e-schedule-table th {
    background-color: var(--surface-raised) !important;
    border-color: var(--border) !important;
    color: var(--text-secondary) !important;
}

/* ------------------------------------------- Phase 2 syncfusion additions */
/* P2.3 sweep found these controls had zero dark overrides — they rendered  */
/* using Syncfusion's own generic bootstrap5-dark.css greys instead of this */
/* app's palette. Same pattern as above: retint to tokens, don't touch      */
/* light mode. Live-verification of these pending a manual pass (see        */
/* dark-theme.test.report.md); rules follow Syncfusion's documented DOM     */
/* structure for each control.                                             */

/* SfToast */
html[data-theme="dark"] .e-toast-container .e-toast {
    background-color: var(--surface-raised) !important;
    color: var(--text) !important;
    border-color: var(--border) !important;
}

html[data-theme="dark"] .e-toast-container .e-toast-title {
    color: var(--text) !important;
}

html[data-theme="dark"] .e-toast-container .e-toast-content {
    color: var(--text-secondary) !important;
}

/* SfRichTextEditor (toolbar/chrome only — the editable body renders in an   */
/* iframe on some configurations and isn't reachable from this stylesheet). */
html[data-theme="dark"] .e-richtexteditor,
html[data-theme="dark"] .e-richtexteditor .e-rte-toolbar,
html[data-theme="dark"] .e-richtexteditor .e-rte-content,
html[data-theme="dark"] .e-richtexteditor .e-source-code {
    background-color: var(--surface-raised) !important;
    border-color: var(--border) !important;
    color: var(--text) !important;
}

html[data-theme="dark"] .e-richtexteditor .e-toolbar-item .e-tbar-btn,
html[data-theme="dark"] .e-richtexteditor .e-toolbar-item .e-tbar-btn-text {
    color: var(--text-secondary) !important;
}

/* SfUploader */
html[data-theme="dark"] .e-upload,
html[data-theme="dark"] .e-upload .e-file-select-wrap,
html[data-theme="dark"] .e-upload .e-upload-files {
    background-color: var(--surface-inset) !important;
    border-color: var(--border-strong) !important;
    color: var(--text) !important;
}

html[data-theme="dark"] .e-upload .e-file-name,
html[data-theme="dark"] .e-upload .e-file-size,
html[data-theme="dark"] .e-upload .e-file-status {
    color: var(--text-secondary) !important;
}

/* SfDatePicker / SfDateTimePicker popup calendar (the input chrome itself   */
/* already renders via the .e-input-group rules above). */
html[data-theme="dark"] .e-calendar,
html[data-theme="dark"] .e-datepicker.e-popup,
html[data-theme="dark"] .e-daterangepicker.e-popup {
    background-color: var(--surface-inset) !important;
    border-color: var(--border-strong) !important;
    color: var(--text) !important;
}

html[data-theme="dark"] .e-calendar .e-header .e-title,
html[data-theme="dark"] .e-calendar .e-content td.e-cell span.e-day {
    color: var(--text-secondary) !important;
}

html[data-theme="dark"] .e-calendar .e-content td.e-selected span.e-day {
    background-color: var(--accent) !important;
    color: #0d1117 !important;
}

html[data-theme="dark"] .e-calendar .e-content td.e-today span.e-day {
    border-color: var(--accent) !important;
}

/* SfSpinner — counters site.css's #sn-spinner white-panel background and    */
/* Style.css/site.css hardcoded green/orange stroke-fill colors that fight   */
/* the dark palette (found during the P2.3 sweep). */
html[data-theme="dark"] #sn-spinner .e-spinner-pane {
    background: rgba(13, 17, 23, 0.85) !important;
}

html[data-theme="dark"] .e-spinner-pane .e-spinner-inner .e-spin-bootstrap5,
html[data-theme="dark"] .e-spin-bootstrap {
    stroke: var(--accent) !important;
    fill: var(--accent) !important;
}

/* SfPdfViewer — single usage in the app (Components/ImageDialog.razor);     */
/* chrome-only retint, code-reviewed against Syncfusion's documented class   */
/* names but not live-verified (see dark-theme.test.report.md). */
html[data-theme="dark"] .e-pdfviewer {
    background-color: var(--surface-raised) !important;
}

html[data-theme="dark"] .e-pdfviewer .e-pv-toolbar {
    background-color: var(--surface-inset) !important;
    border-color: var(--border) !important;
}

/* ---------------------------------------------- Phase 8 pin-light, reversed 2026-08-22 */

/* Phase 8 (2026-08-13) pinned all 18 CustomerLayout (.app-wrapper1) routes light, countering
   every generic dark-theme.css rule for that subtree, with an explicit note to "revisit after
   internal rollout." That rollout point arrived with the 2026-08-22 default-theme flip
   (plan-dark-theme.md Phase 11 addendum) -- pinning customer-facing pages light was already
   producing a half-dark/half-light page (the counter-pass only covered *generic* Bootstrap/HTML,
   never the Syncfusion controls and .sn-* custom classes those same pages also use), and with
   Dark now the app-wide default that inconsistency is what most new users see first. Decision:
   un-pin -- .app-wrapper1 now follows dark-theme.css's generic rules like everywhere else. The
   removed block is preserved in git history; each route's own hardcoded-light literals (e.g.
   CustomerLayout.razor's base background, CustomerPortalPageNew.razor's .main-container/
   .bg-gray-50/.custom-text-area, CustomerPortalFileUpload.razor's .upload-box family) still
   need tokenizing per route -- tracked separately, not fixed by this removal alone. */

/* CustomerLayout.razor's own inline <style> hardcodes .app-wrapper1's background/border --
   the root wrapper for all 18 un-pinned routes above. */
html[data-theme="dark"] .app-wrapper1 {
    background-color: var(--surface) !important;
    border-right-color: var(--border) !important;
}

/* CustomerPortalPageNew.razor / ResaleAssessmentPage.razor each define these two classes in
   their own inline <style> (identical duplicated markup, no shared CSS file) -- no color/
   background coverage anywhere, un-themed since Phase 0. */
html[data-theme="dark"] .main-container {
    background: var(--surface-raised) !important;
}

html[data-theme="dark"] .bg-gray-50 {
    background-color: var(--surface-inset) !important;
}

/* CustomerLayoutNavbar.razor's <nav> sits on the shared .bg-green utility class (Style.css) --
   badges elsewhere in the app use the same class in tiny fixed-size chips, so it's never been
   given a dark variant. Here it's the full-width nav bar, and its own light-mode background is
   already fragile: Style.css declares `background: var(--surface-hover)` immediately followed
   by `background: -webkit-linear-gradient(to left, var(--util-purple-1), var(--util-purple-2))`
   (the fixed purple chip color, same in both themes per tokens.css) -- the vendor-prefixed
   legacy gradient function overriding the plain color. CustomerLayoutNavbar.razor's own
   .nb-theme-btn comment already flagged this ambient background as untrustworthy enough that
   the toggle button was given its own persistent chip rather than relying on it. Reported
   live as staying white regardless of theme rather than showing either intended color --
   scoped to .nav-bar so only this navbar usage of .bg-green is touched, not the badge usages
   elsewhere, and pinned to a plain solid dark surface rather than trying to theme the gradient. */
html[data-theme="dark"] .nav-bar.bg-green {
    background: var(--surface-raised) !important;
}

/* PpsrCertificate.razor's <embed type="Application/pdf"> is a fixed height:1000px box; on a
   narrow viewport the browser's simplified/no-toolbar PDF rendering leaves the space below the
   (now width-scaled-down, so shorter) page unfilled, defaulting to white rather than extending
   any dark chrome down to fill it -- reported as a white gap surviving under the actual PDF page
   in dark mode specifically at narrow widths (desktop's full native toolbar+sidebar mode already
   renders that area dark on its own, independent of this app, since it's the browser's own PDF
   viewer surface). This is an attempt only: an <embed>'s internal viewer is a browser-native
   surface, largely outside page CSS's reach, same as a native title-attribute tooltip -- Chrome's
   PDF.js-based viewer sometimes honors a background-color on the element for its unfilled
   margin, but there's no guarantee across browsers/viewport modes. */
html[data-theme="dark"] embed[type="Application/pdf"] {
    background-color: var(--surface-raised) !important;
}

/* CustomerPortalFileUpload.razor's own inline <style> -- the 3 document-upload dropzones
   (Driving License / Id Back / Rego Paper). No shared .sn-dropzone reuse, no dark coverage. */
html[data-theme="dark"] .upload-box {
    background-color: var(--surface-inset) !important;
    border-color: var(--border-strong) !important;
}

html[data-theme="dark"] .upload-box:hover {
    border-color: var(--accent) !important;
}

html[data-theme="dark"] .upload-icon,
html[data-theme="dark"] .upload-text {
    color: var(--text-secondary) !important;
}

/* Reversed, same session: the 2026-08-22 re-pin below forced the whole page (this rule's
   selector is `body`, not the embed itself) to stay light on the 5 PDF/document-mirror routes
   (PdfFrame, PdfSignatureViewPage, PpsrCertificate, SoldCarsFormPdfView, SASAggrementViewPage),
   reasoning it should match the "stay-light" precedent of printable quotes/print-mode. In
   practice that pin only ever affected the page chrome around the document -- the "Click here
   to download" banner text and the .page-content wrapper, both of which just inherit body's
   background/color with no explicit rule of their own -- since the actual document render
   (the <embed>/PDF viewer) is the browser's native PDF renderer and was never reachable by this
   app's CSS either way, pinned or not. That produced a half-themed page: the surrounding layout
   chrome (navbar/logo/toggle/scrollbar) already tracks the theme via .app-wrapper1's un-pin
   above, so toggling looked like it "worked" for the chrome while the banner/wrapper stayed
   stuck light, and the embedded PDF stayed the unavoidable white page in the middle either way.
   Explicitly requested: keep that unavoidable white PDF page, but let the page chrome/banner
   background go fully dark like every other route.

   Correction to this comment's own earlier claim: removing the `body:has()` rule alone did NOT
   fully undo the pin. A second, more specific block existed right below this comment --
   `.app-wrapper1:has(.pdf-mirror-page)` plus a full re-implementation of the light palette
   scoped to `.pdf-mirror-page` (headings, links, form controls, tables, cards, modals) --
   each one more specific than the generic dark rule it was shadowing (`.app-wrapper1`, `.card`,
   the heading :where() rule, etc.), so it kept winning even after the `body` rule was gone.
   Caught via the user inspecting computed styles in DevTools and asking directly why these
   were still hardcoded. That whole block is removed now too; `.pdf-mirror-page` is left on all
   5 pages' `PageContent` as a now-inert marker in case a narrower, non-body-wide use for it
   comes up again. */

