/* ==========================================================================
   CableTow explicit CSS overrides — cabletow-overrides.css
   --------------------------------------------------------------------------
   This file exists to hold !important declarations that are necessary to
   beat Blazor scoped-CSS specificity when the component's data-attribute
   is not applied to the rendered DOM element (a known Blazor WASM timing
   gap observed with Blazor WASM 10.0.6 / AdminLayout.razor, 2026-05-07).

   RULE: every !important declaration here MUST include:
     1. A TODO(F10) comment referencing the Blazor SDK version it was needed for.
     2. A re-test note so the rule is revisited on the next SDK upgrade.
     3. The fallback declaration in app.css (without !important) that covers
        the happy path when the scoped-CSS data-attribute lands correctly.

   Load order in index.html:
     1. bootstrap.min.css
     2. _content/Syncfusion.Blazor/styles/bootstrap5.css
     3. css/app.css                    ← plain fallback declarations
     4. css/cabletow-overrides.css     ← THIS FILE — !important overrides
     5. CableTow.Web.styles.css        ← scoped component CSS (when data-attr applies)

   F10 (plan 20-02): moved from app.css per brand audit finding D1-F10.
   ========================================================================== */

/* TODO(F10 — Blazor WASM 10.0.6): .ct-admin-sidebar gradient.
   AdminLayout.razor.css declares .admin-sidebar { background-image: gradient }
   as a scoped rule, but the data-* scope attribute was not applied to <aside>
   as of 2026-05-07. This !important override ensures the gradient renders
   regardless of whether the scoped bundle lands.
   Re-test: after upgrading Blazor SDK, inspect <aside> in DevTools — if
   data-v-* attribute is present and gradient renders, remove this rule.

   F27 27-08 retest (2026-05-26) — workaround REMAINS LOAD-BEARING.
   Migration attempted and reverted in-plan. Blazor target is still 10.0.6
   (no patch bump since the original observation). Rendered-DOM inspection
   confirmed scope attributes ARE applied to MainLayout chrome elements
   (e.g., `b-1utwjrmhcp` on `<header class="ct-header">`), but a clean
   visual verify against the admin <aside> specifically could NOT be
   completed in-session — the F22-RT-A standalone-dev-server asset-serving
   gap blocks `dotnet run --project CableTow.Web` from booting Demo mode
   (boot.json 404 via the bare-fingerprint middleware). Next empirical
   retest cadence: when the F24 24-06 AdminJourneyTests Playwright path
   can be extended with a getComputedStyle(<aside>).backgroundImage
   assertion in the single-Kestrel topology, OR after the next Blazor SDK
   minor/major bump (whichever comes first). F17-OD-E stays Open. */
.ct-admin-sidebar {
  background-image: linear-gradient(180deg, var(--ct-royal-blue) 0%, var(--ct-blue-dark) 70%) !important;
}

/* TODO(F10 — Blazor WASM 10.0.6): AdminNavMenu nav list layout + link card style.
   AdminNavMenu.razor.css scoped rules for .admin-nav / .admin-nav-list /
   .admin-nav-link were being beaten by Bootstrap's list-group defaults when
   the scope attribute didn't apply. These overrides pin the card-button layout.
   Re-test: after upgrading Blazor SDK, verify nav items render as cards without
   !important; if confirmed, remove these overrides. */
.admin-nav {
  padding: 1rem 0.5rem !important;
}
.admin-nav-list {
  list-style: none !important;
  margin: 0 !important;
  padding: 0 !important;
  display: flex !important;
  flex-direction: column !important;
  gap: 0.4rem !important;
}
.admin-nav-link {
  display: block !important;
  padding: 0.7rem 1rem !important;
  background: var(--ct-royal-blue) !important;
  color: var(--ct-off-white) !important;
  text-decoration: none !important;
  font-family: var(--ct-font-body) !important;
  font-size: 0.975rem !important;
  font-weight: 600 !important;
  border: 1px solid rgba(250, 247, 242, 0.18) !important;
  border-radius: var(--ct-radius-sm) !important;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease !important;
}
.admin-nav-link:hover,
.admin-nav-link:focus-visible {
  background-color: var(--ct-blue-dark) !important;
  border-color: var(--ct-gold) !important;
  color: var(--ct-off-white) !important;
}
.admin-nav-link.active {
  background-color: var(--ct-blue-dark) !important;
  color: var(--ct-gold) !important;
  border-color: var(--ct-gold) !important;
}

/* TODO(F23 — SfDialog responsive — Syncfusion inline-style specificity):
   SfDialog renders Width="420px" as an inline style attribute which wins over
   plain class selectors. The !important overrides here ensure the responsive
   constraint wins on 390px viewports (iPhone 14 frame).
   Re-test: after any Syncfusion SDK upgrade, verify dialog stays within viewport
   at 390px in Chrome DevTools; if the SF Width parameter is replaced by a CSS
   class in a future SDK, remove the !important here. */
.e-dialog {
  max-width: min(560px, calc(100vw - 32px)) !important;
  width: auto !important;
}

@media (max-width: 479px) {
  .e-dialog {
    position: fixed !important;
    bottom: 0 !important;
    left: 0 !important;
    right: 0 !important;
    top: auto !important;
    max-width: 100% !important;
    width: 100% !important;
    border-radius: var(--ct-radius-lg) var(--ct-radius-lg) 0 0 !important;
    transform: none !important;
  }
  .e-dlg-overlay {
    align-items: flex-end !important;
  }
}

/* TODO(F34 — InstallBanner CTA button — Syncfusion SfButton inline-style specificity):
   SfButton renders its style via a class chain that can win over plain selectors.
   Gold background for the install CTA must override SF's primary-button theme.
   Re-test: after any Syncfusion SDK upgrade, verify banner CTA renders gold (#FFBB1C)
   not royal-blue (#343579) on the install banner. */
.ct-install-banner__btn--primary {
  background: var(--ct-gold) !important;
  color: var(--ct-near-black) !important;
  border-color: var(--ct-gold) !important;
}

/* F24 24-07 (F22-RT-F closer) — SfTextBox border-color cascade override.
   ----------------------------------------------------------------------
   Syncfusion's Bootstrap5 theme cascades a default border-color onto
   .e-input-group that wins over the F17-03 --bs-border-color → --ct-grey-dark
   token re-point. F22-RT-F (SfTextBoxBorderColorRuntimeTests) surfaced this
   bypass — computed border-color did NOT resolve to #4A4A4A on a rendered
   SfTextBox, breaking the F17-OD-A contrast contract.

   The :not(.e-success):not(.e-warning):not(.e-error) chain wins specificity
   ONLY when none of the three state classes are applied — i.e., for vanilla
   inputs. Do NOT widen the selector or it'll override legit success/warning/
   error painting (which Syncfusion's theme correctly emits for state inputs).

   F17-07 M2 contract pins:
     - idle:  --ct-grey-dark   = #4A4A4A (8.28:1 on --ct-off-white #FAF7F2)
     - focus: --ct-royal-blue  = #343579 (8.62:1 on --ct-off-white #FAF7F2)

   Re-test: after any Syncfusion SDK upgrade, run
   SfTextBoxBorderColorRuntimeTests in the E2E suite. If both assertions pass
   without these overrides, remove them and let the token chain do the work.
   The plain (non-!important) fallback in app.css :root carries the canonical
   --bs-border-color → --ct-grey-dark wire-up. */
.e-input-group:not(.e-success):not(.e-warning):not(.e-error) {
  border-color: var(--ct-grey-dark) !important;
}
.e-input-group:not(.e-success):not(.e-warning):not(.e-error).e-input-focus,
.e-input-group:not(.e-success):not(.e-warning):not(.e-error):focus-within {
  border-color: var(--ct-royal-blue) !important;
}

/* ==========================================================================
   F25 25-04 — Syncfusion contrast + state overrides
   --------------------------------------------------------------------------
   Closes axe-core `color-contrast` violations across Syncfusion-default
   surfaces flagged by 25-01's Violation Matrix (rows classified
   `syncfusion-cascade` + `color-contrast`).

   Pattern: F22-RT-F-proven high-specificity `:not()` chain idiom — wins
   the cascade ONLY in default state, so Syncfusion's success/warning/error
   theming continues to paint state inputs correctly.

   Token discipline: every declaration uses brand-palette tokens only.
   NO purple/violet/plum/lavender. NO pure white (`--ct-off-white`).
   NO pure black (`--ct-near-black`).

   Re-test cadence: rerun axe-core sweep after Syncfusion v-major bump;
   if a block passes without override, remove it.
   ========================================================================== */

/* TODO(F25 25-04 — Syncfusion SDK v33.2.4): SfDropDownList popup list-item
   contrast. Default Bootstrap5 theme paints idle text at a grey value that
   loses 4.5:1 against the popup surface for some scaled font sizes. Pin to
   `--ct-near-black` for normal items + Royal Blue surface w/ off-white text
   for hover/active state.
   Re-test: after Syncfusion v-major bump, verify `.e-ddl-popup .e-list-item`
   meets 4.5:1 against the popup background without this override. */
.e-ddl-popup .e-list-item:not(.e-disabled) {
  color: var(--ct-near-black) !important;
}
.e-ddl-popup .e-list-item.e-hover:not(.e-disabled),
.e-ddl-popup .e-list-item.e-active:not(.e-disabled),
.e-ddl-popup .e-list-item.e-item-focus:not(.e-disabled) {
  background-color: var(--ct-royal-blue) !important;
  color: var(--ct-off-white) !important;
}

/* TODO(F25 25-04 — Syncfusion SDK v33.2.4): SfTooltip default chrome.
   Default tip-content paints near-black-on-grey at small font sizes that
   loses contrast in WCAG SC 1.4.3. Pin to off-white text on near-black tip
   surface (16.95:1 — well above 4.5:1).
   Re-test: after Syncfusion v-major bump, verify `.e-tooltip-wrap .e-tip-content`
   passes without override. */
.e-tooltip-wrap .e-tip-content {
  background-color: var(--ct-near-black) !important;
  color: var(--ct-off-white) !important;
}
.e-tooltip-wrap .e-arrow-tip-inner {
  color: var(--ct-near-black) !important;
}

/* TODO(F25 25-04 — Syncfusion SDK v33.2.4): SfMenu chrome.
   Menu parent + popup items inherit Bootstrap5 theme variables that the
   F17-03 `--bs-border-color` re-point doesn't fully reach. Pin idle text to
   near-black; hover/focus to Royal Blue surface w/ off-white text.
   Re-test: after Syncfusion v-major bump, verify `.e-menu-item` text passes
   4.5:1 in idle + focus. */
.e-menu-container .e-menu-item:not(.e-disabled):not(.e-separator) {
  color: var(--ct-near-black) !important;
}
.e-menu-container .e-menu-item.e-focused:not(.e-disabled):not(.e-separator),
.e-menu-container .e-menu-item.e-selected:not(.e-disabled):not(.e-separator),
.e-menu-container .e-menu-item:hover:not(.e-disabled):not(.e-separator) {
  background-color: var(--ct-royal-blue) !important;
  color: var(--ct-off-white) !important;
}

/* TODO(F25 25-04 — Syncfusion SDK v33.2.4): SfSwitch wrapper off-state.
   Default Bootstrap5 theme paints the off-state track at `#e0e0e0` which
   loses 3:1 UI-component contrast against `--ct-off-white` page surface.
   Pin off-track to `--ct-grey-mid` (#999999 → 3.36:1 against --ct-off-white)
   and the on-track to Royal Blue (already brand-compliant).
   Re-test: after Syncfusion v-major bump, verify `.e-switch-inner.e-switch-off`
   meets 3:1 UI-component contrast. */
.e-switch-wrapper .e-switch-inner.e-switch-off,
.e-switch-wrapper:not(.e-switch-disabled) .e-switch-inner.e-switch-off {
  background-color: var(--ct-grey-mid) !important;
  border-color: var(--ct-grey-dark) !important;
}
.e-switch-wrapper .e-switch-inner.e-switch-active,
.e-switch-wrapper:not(.e-switch-disabled) .e-switch-inner.e-switch-active {
  background-color: var(--ct-royal-blue) !important;
  border-color: var(--ct-royal-blue) !important;
}

/* TODO(F25 25-04 — Syncfusion SDK v33.2.4): SfGrid header chrome contrast.
   Grid header text leaks default Bootstrap grey-on-tint that doesn't meet
   4.5:1 against the header background. Pin header text to `--ct-near-black`
   on the default tinted header surface.
   Re-test: after Syncfusion v-major bump, verify `.e-grid .e-headercell`
   header text passes 4.5:1. */
.e-grid .e-gridheader .e-headercell:not(.e-stackedheadercell),
.e-grid .e-gridheader .e-headercell .e-headercelldiv {
  color: var(--ct-near-black) !important;
}

/* TODO(F25 25-04 — Syncfusion SDK v33.2.4): SfDialog header text + close-X
   chrome. Default header text inherits a muted grey-on-tint that loses
   contrast at the small font size used in modal banners. Pin to near-black
   header text + gold close-icon glyph (with Royal Blue focus ring for
   keyboard a11y).
   Companion to F25-03-A — see `a11y-shim.js` for the aria-label injection
   on `.e-dlg-closeicon-btn` (CSS cannot inject aria-label; only paint).
   Re-test: after Syncfusion v-major bump, re-run axe-core sweep against
   the 5 SfDialog-bearing routes; if `color-contrast` passes without these
   overrides, remove. */
.e-dialog .e-dlg-header-content,
.e-dialog .e-dlg-header,
.e-dialog .e-dlg-header * {
  color: var(--ct-near-black) !important;
}
.e-dialog .e-dlg-header-content .e-dlg-closeicon-btn {
  color: var(--ct-near-black) !important;
  background-color: transparent !important;
}
.e-dialog .e-dlg-header-content .e-dlg-closeicon-btn:hover,
.e-dialog .e-dlg-header-content .e-dlg-closeicon-btn:focus-visible {
  color: var(--ct-royal-blue) !important;
  outline: 2px solid var(--ct-gold) !important;
  outline-offset: 2px !important;
}

/* TODO(F25 — prefers-reduced-motion — scoped-CSS specificity):
   Component-scoped CSS animations/transitions need !important to be overridden
   by the user's OS-level reduced-motion preference. The plain declarations in
   app.css cover global elements; the !important counterparts here cover
   component-scoped CSS that would otherwise beat the plain declarations.
   This is the canonical legitimate use of !important per plan 20-03 anti-goals. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
