/* =====================================================================
   KeyIS — KeyView theme
   Brand palette + Bootstrap variable overrides + Sisolco.Dashboards
   variable overrides + dark sidebar / header chrome.
   ===================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap');

:root {
    /* KEYIS brand palette (per Brand Guidelines PDF) */
    --keyis-black: #000000;
    --keyis-slate-white: #edebe6;

    /* 4-stop rainbow — the signature device */
    --keyis-rule-red: #e9425c;
    --keyis-rule-yellow: #ffcf47;
    --keyis-rule-green: #75b94e;
    --keyis-rule-sky: #73caeb;

    /* Tonal variants of the brand sky — used for UI affordances (links,
       focus rings) where the rainbow sky stop is too light on white to
       pass WCAG AA. Same hue family; only the non-RAG rainbow stop is
       reused here so red/yellow/green stay reserved for status. */
    --keyis-link: #1c7ba8;
    --keyis-link-hover: #155f80;
    --keyis-rainbow: linear-gradient(90deg,
        var(--keyis-rule-red) 0%,
        var(--keyis-rule-yellow) 35%,
        var(--keyis-rule-green) 65%,
        var(--keyis-rule-sky) 100%);

    --keyis-font-sans: 'Roboto', Arial, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

    /* Bootstrap variable overrides — Serenity 10.x consumes Bootstrap 5,
       so widgets, buttons, badges, alerts, pagination etc. all read these. */
    --bs-primary: var(--keyis-black);
    --bs-primary-rgb: 0, 0, 0;
    --bs-secondary: #555555;
    --bs-secondary-rgb: 85, 85, 85;
    --bs-success: var(--keyis-rule-green);
    --bs-success-rgb: 117, 185, 78;
    --bs-info: var(--keyis-rule-sky);
    --bs-info-rgb: 115, 202, 235;
    --bs-warning: var(--keyis-rule-yellow);
    --bs-warning-rgb: 255, 207, 71;
    --bs-danger: var(--keyis-rule-red);
    --bs-danger-rgb: 233, 66, 92;

    --bs-body-bg: #ffffff;
    --bs-body-color: var(--keyis-black);
    --bs-body-font-family: var(--keyis-font-sans);
    --bs-body-font-weight: 300;
    --bs-border-radius: 4px;
    --bs-border-radius-sm: 2px;
    --bs-border-radius-lg: 6px;
    /* Bootstrap 5.3 renders links via `rgba(var(--bs-link-color-rgb), …)`,
       so the RGB partner MUST be set or anchors stay default blue. */
    --bs-link-color: var(--keyis-link);
    --bs-link-color-rgb: 28, 123, 168;
    --bs-link-hover-color: var(--keyis-link-hover);
    --bs-link-hover-color-rgb: 21, 95, 128;
    --bs-primary-text-emphasis: var(--keyis-black);

    /* Nav chrome (tabs, pills, navbar nav-link) must read as navigation,
       not as inline text links — so override Bootstrap's default of
       inheriting --bs-link-color and use brand black instead. */
    --bs-nav-link-color: var(--keyis-black);
    --bs-nav-link-hover-color: var(--keyis-link);

}

/* Library theme tokens — Sisolco.Dashboards (--sisolco-dashboard-*,
   --sisolco-mydashboards-*) and Sisolco.CustomForms / SurveyJS
   (--sjs-*). Both libraries now wrap their defaults in named CSS
   cascade layers (`@layer sisolco-dashboards-defaults`,
   `@layer sisolco-customforms-defaults`), so consumer overrides
   here — sitting in the implicit unnamed layer — always win without
   any specificity gymnastics. The old `html:root` workaround is no
   longer needed. */
:root {
    --sisolco-dashboard-rag-red: var(--keyis-rule-red);
    --sisolco-dashboard-rag-amber: var(--keyis-rule-yellow);
    --sisolco-dashboard-rag-green: var(--keyis-rule-green);
    --sisolco-dashboard-default: var(--keyis-rule-sky);

    /* Table header bg — library default is `rgba(108, 117, 125, 0.12)`
       (translucent) which, combined with the library's `position: sticky`
       header, lets body rows show through as the user scrolls. Pin an
       opaque tint in the same hue family so the sticky header reads as
       a solid band over the scrolling content. */
    --sisolco-dashboard-table-header-bg: #ebecee;

    --sisolco-dashboard-fg-on-rag: #ffffff;
    /* Amber needs dark text — yellow #ffcf47 fails WCAG against white.
       The library defaults this to #1a1a1a (1.11.0+); set explicitly
       so a future palette change can't silently regress. */
    --sisolco-dashboard-fg-on-rag-amber: #1a1a1a;
    --sisolco-dashboard-fg-default: var(--keyis-black);
    --sisolco-dashboard-fg-muted: #555555;

    /* Chart series palette — rainbow-inspired, first 4 deliberately
       avoid RAG semantics so a viewer doesn't mis-read "series 3 is
       green = good". Series 5-8 reintroduce RAG hues for high-cardinality
       charts where distinct colours matter more than strict separation. */
    --sisolco-dashboard-chart-1: var(--keyis-rule-sky);       /* sky */
    --sisolco-dashboard-chart-2: #41b6b0;                     /* brand teal — rainbow-adjacent */
    --sisolco-dashboard-chart-3: var(--keyis-link);           /* dark sky #1c7ba8 */
    --sisolco-dashboard-chart-4: #2b2b2b;                     /* dark slate (brand neutral) */
    --sisolco-dashboard-chart-5: var(--keyis-rule-green);
    --sisolco-dashboard-chart-6: var(--keyis-rule-yellow);
    --sisolco-dashboard-chart-7: var(--keyis-rule-red);
    --sisolco-dashboard-chart-8: #bfbfbf;                     /* mid-grey */

    --sisolco-dashboard-button-primary-bg: var(--keyis-black);
    --sisolco-dashboard-button-primary-fg: #ffffff;

    /* Multi-page dashboard nav strip — active tab/pill accent. */
    --sisolco-dashboard-page-nav-accent: var(--keyis-black);

    /* MyDashboards card grid + dialog actions (Sprint 30). Replaces
       the raw `.btn-primary` / `.btn-outline-secondary` on dashboard
       cards (Open / Edit / Copy / Share / Rename / Export / Import).
       Without these, the buttons inherit Bootstrap's `--bs-primary`
       which we already pinned to black; the dedicated var family
       lets the dashboard cards theme independently if we ever want
       to break from the global button colour. */
    --sisolco-mydashboards-action-primary-bg: var(--keyis-black);
    --sisolco-mydashboards-action-primary-fg: #ffffff;
    --sisolco-mydashboards-action-primary-border: var(--keyis-black);
    --sisolco-mydashboards-action-primary-bg-hover: #1f1f1f;

    --sisolco-mydashboards-action-secondary-bg: transparent;
    --sisolco-mydashboards-action-secondary-fg: #555555;
    --sisolco-mydashboards-action-secondary-border: #555555;
    --sisolco-mydashboards-action-secondary-bg-hover: #555555;
    --sisolco-mydashboards-action-secondary-fg-hover: #ffffff;

    --sisolco-mydashboards-focus-outline: var(--keyis-link);

    /* ---------------------------------------------------------------
       Sisolco.CustomForms 1.9.1+ — SurveyJS theme tokens.
       1.9.1 stopped inline-stamping the DefaultLight theme on the
       survey root. Instead it injects defaults into
       `@layer sisolco-customforms-defaults { :root { ... } }` once
       per page. Our overrides here sit in the implicit unnamed cascade
       layer and therefore beat the library defaults without
       `!important` and without scope hacks — cascade negotiation
       works as documented in patterns/theming.md path 1.

       The variable names below are the FLAT-tier semantic SurveyJS
       2.5.x set (no `--sjs-*-background-500` / `--sjs-layer-N-*`
       sub-tier — that's the Studio themes scheme; not in our build).
       The form RUNTIME (CustomFormEditorDialog -> `.sd-root-modern`)
       and the DESIGNER PREVIEW both read these. The DESIGNER CHROME
       (toolbox, properties panel, tab bar) uses the same names
       through the survey-creator package's own stylesheet, so this
       block covers both surfaces. */

    /* Primary action — buttons, focus rings, active states. */
    --sjs-primary-backcolor: var(--keyis-black);
    --sjs-primary-backcolor-light: rgba(0, 0, 0, 0.1);
    --sjs-primary-backcolor-dark: #1f1f1f;
    --sjs-primary-forecolor: #ffffff;
    --sjs-primary-forecolor-light: rgba(255, 255, 255, 0.85);

    /* Secondary action / chrome accents. */
    --sjs-secondary-backcolor: var(--keyis-black);
    --sjs-secondary-backcolor-light: rgba(0, 0, 0, 0.1);
    --sjs-secondary-forecolor: #ffffff;

    /* General surfaces / text. dim = page surface; dim-light/dark =
       alternating panels; forecolor = body text. */
    --sjs-general-backcolor: #ffffff;
    --sjs-general-backcolor-dark: #f5f5f5;
    --sjs-general-backcolor-dim: var(--keyis-slate-white);
    --sjs-general-backcolor-dim-light: #fafafa;
    --sjs-general-backcolor-dim-dark: #e5e5e5;
    --sjs-general-forecolor: rgba(0, 0, 0, 0.91);
    --sjs-general-forecolor-light: rgba(0, 0, 0, 0.55);
    --sjs-general-dim-forecolor: rgba(0, 0, 0, 0.91);
    --sjs-general-dim-forecolor-light: rgba(0, 0, 0, 0.55);

    /* Semantic status — RAG palette aligned with the brand. These
       variants communicate status, which IS the RAG contract. */
    --sjs-special-red: var(--keyis-rule-red);
    --sjs-special-red-light: rgba(233, 66, 92, 0.1);
    --sjs-special-red-forecolor: #ffffff;
    --sjs-special-green: var(--keyis-rule-green);
    --sjs-special-green-light: rgba(117, 185, 78, 0.1);
    --sjs-special-green-forecolor: #ffffff;
    --sjs-special-yellow: var(--keyis-rule-yellow);
    --sjs-special-yellow-light: rgba(255, 207, 71, 0.1);
    --sjs-special-yellow-forecolor: #1a1a1a;
    --sjs-special-blue: var(--keyis-link);
    --sjs-special-blue-light: rgba(28, 123, 168, 0.1);
    --sjs-special-blue-forecolor: #ffffff;

    /* Borders / dividers. */
    --sjs-border-default: #e5e5e5;
    --sjs-border-light: rgba(0, 0, 0, 0.08);
    --sjs-border-inside: #e5e5e5;

    /* Typography / spacing / shape. */
    --sjs-font-family: var(--keyis-font-sans);
    --sjs-corner-radius: 4px;
    --sjs-base-unit: 8px;

    /* SurveyJS 2.x designer canvas tint — see the scoped override
       below as well. Plain `:root` value here is fallback. */
    --sjs2-color-utility-surface-designer: var(--keyis-slate-white);
}

/* SurveyJS Creator's designer dialog still inline-stamps the full
   DefaultLight theme via `creator.theme = …` on `.svc-creator` (and
   `.svc-designer-surface` inside it). This is a separate path from
   the form runtime, which 1.9.1 fixed.

   The inline declarations include `--sjs-primary-backcolor:
   var(--sjs-primary-background-500, #19B394)` and ~1000 other
   tokens — they beat any non-`!important` stylesheet rule. The
   visible mint canvas tint comes from RULES on `.svc-tab-designer`
   / `.svc-creator__content-wrapper` (ANCESTORS of
   `.svc-designer-surface`) that read `--sjs2-color-utility-surface-
   designer` — so the override must sit on `.svc-creator` (an outer
   ancestor) for CSS-variable inheritance to reach those painters.

   The form runtime (`.sd-root-modern` outside the designer subtree)
   is NOT inline-stamped in 1.9.1, so the clean `:root` overrides
   above already cover it — this block doesn't touch that path. */
.svc-creator,
.svc-creator-popup {
    --sjs-primary-backcolor: var(--keyis-black) !important;
    --sjs-primary-backcolor-light: rgba(0, 0, 0, 0.1) !important;
    --sjs-primary-backcolor-dark: #1f1f1f !important;
    --sjs-primary-forecolor: #ffffff !important;

    --sjs-secondary-backcolor: var(--keyis-black) !important;
    --sjs-secondary-forecolor: #ffffff !important;

    --sjs-general-backcolor: #ffffff !important;
    --sjs-general-backcolor-dim: var(--keyis-slate-white) !important;
    --sjs-general-backcolor-dim-light: #fafafa !important;
    --sjs-general-backcolor-dim-dark: #e5e5e5 !important;
    --sjs-general-forecolor: rgba(0, 0, 0, 0.91) !important;
    --sjs-general-forecolor-light: rgba(0, 0, 0, 0.55) !important;
    --sjs-general-dim-forecolor: rgba(0, 0, 0, 0.91) !important;

    --sjs-special-red: var(--keyis-rule-red) !important;
    --sjs-special-red-forecolor: #ffffff !important;
    --sjs-special-green: var(--keyis-rule-green) !important;
    --sjs-special-green-forecolor: #ffffff !important;
    --sjs-special-yellow: var(--keyis-rule-yellow) !important;
    --sjs-special-yellow-forecolor: #1a1a1a !important;
    --sjs-special-blue: var(--keyis-link) !important;
    --sjs-special-blue-forecolor: #ffffff !important;

    --sjs-border-default: #e5e5e5 !important;
    --sjs-border-inside: #e5e5e5 !important;

    /* Designer-canvas mint tint (raw SurveyJS Studio palette token). */
    --sjs2-color-utility-surface-designer: var(--keyis-slate-white) !important;

    /* License-banner background (`.svc-creator__banner`) — reads
       `var(--ctr-page-banner-background-color, var(--sjs-secondary-
       background-500, #19b394))`. Neither outer var is set in the
       flat-tier theme JSON, so the fallback fires teal. Set the
       legacy "background-500" slot to brand black to retint it. */
    --sjs-secondary-background-500: var(--keyis-black) !important;
    --ctr-page-banner-background-color: var(--keyis-black) !important;
}

/* License-banner text — the library doesn't set `color` on
   `.svc-creator__banner`, so it inherits the (now dark) body colour
   and renders invisible against the brand-black banner background.
   Force white text. */
.svc-creator__banner,
.svc-creator__banner * {
    color: #ffffff !important;
}

/* ---------------------------------------------------------------
   Sisolco.QA 1.3.0+ — QA Flow Designer theme tokens.

   The QA library publishes its design tokens via the `--qa-*`
   custom-property family, scoped to `.qa-designer-root` (set on the
   cshtml host div) and `.qa-designer-root-mounted` (added by the
   designer mount script). The library DOES NOT use a named cascade
   layer, and its stylesheet (`QAFlowDesignerPage.css`) is `<link>`-ed
   from inside the view body — i.e. AFTER site.css in document order.
   That means same-specificity overrides on `.qa-designer-root` would
   lose to the library defaults on cascade order.

   To beat the library, we use the `:root .qa-designer-root` pattern
   (specificity 0,2,0 vs the library's 0,1,0) — the same workaround
   that USED to be needed for Dashboards/CustomForms before they
   adopted named cascade layers.

   Mapping rationale:
   - Surfaces use brand slate-white (#edebe6) for the canvas / body
     so the designer reads as part of the KeyIS visual system.
   - Accent collapses indigo onto brand-black, matching the
     `--sjs-primary-backcolor` and `--bs-primary` decisions taken in
     CustomForms/Bootstrap — the QA primary button now reads black.
   - Selection uses the brand link sky (`--keyis-link`) — a sky-family
     token that passes WCAG AA against white, distinguishing
     "selected" from "primary action".
   - Node kinds: status/start/document/content/approval/bypass keep
     their semantic palette but are recoloured from the brand's RAG
     stops (approval=green, bypass=red, document/content=yellow,
     start=sky) so flow diagrams read in the same colour language as
     RAG KPI tiles elsewhere in the app.
   - Bypass node is intentionally tied to `--keyis-rule-red`: bypass
     IS the destructive path of a QA flow, so red is semantically
     correct (matches the RAG contract documented on `.btn-danger`).
   --------------------------------------------------------------- */
:root .qa-designer-root,
:root .qa-designer-root-mounted {
    /* Surfaces — slate-white canvas, white surfaces. */
    --qa-bg: var(--keyis-slate-white);
    --qa-surface: #ffffff;
    --qa-surface-muted: #fafafa;
    --qa-canvas-bg: var(--keyis-slate-white);
    --qa-grid-color: #d8d3c9;
    --qa-divider: #e5e5e5;
    --qa-divider-strong: #bfbfbf;

    /* Text — brand black for body, dark grey for muted (matches the
       `--bs-secondary` decision). */
    --qa-text: var(--keyis-black);
    --qa-text-muted: #555555;
    --qa-text-subtle: #888888;

    /* Accent / focus — black primary, sky-link for selection. */
    --qa-accent: var(--keyis-black);
    --qa-accent-soft: rgba(0, 0, 0, 0.08);
    --qa-accent-strong: #1f1f1f;
    --qa-selected: var(--keyis-link);
    --qa-danger: var(--keyis-rule-red);
    --qa-danger-soft: rgba(233, 66, 92, 0.12);

    /* Buttons — white surface, subtle hover. */
    --qa-btn-bg: #ffffff;
    --qa-btn-bg-hover: #f5f5f5;
    --qa-btn-border: #d1d5db;
    --qa-btn-text: #2b2b2b;

    /* Node kinds — recoloured to the brand RAG palette so flow
       diagrams read in the same colour language as the rest of the
       app. */
    --qa-kind-status-fill: #ffffff;
    --qa-kind-status-stroke: #2b2b2b;
    --qa-kind-status-label: var(--keyis-black);

    --qa-kind-document-fill: rgba(255, 207, 71, 0.18);
    --qa-kind-document-stroke: #b88a1d;
    --qa-kind-document-label: #5c4108;

    --qa-kind-content-fill: rgba(255, 207, 71, 0.28);
    --qa-kind-content-stroke: #9d6614;
    --qa-kind-content-label: #5c4108;

    --qa-kind-approval-fill: rgba(117, 185, 78, 0.18);
    --qa-kind-approval-stroke: #4d8a33;
    --qa-kind-approval-label: #2f5520;

    --qa-kind-bypass-fill: rgba(233, 66, 92, 0.15);
    --qa-kind-bypass-stroke: var(--keyis-rule-red);
    --qa-kind-bypass-label: #6e1e2b;

    --qa-kind-start-fill: rgba(115, 202, 235, 0.22);
    --qa-kind-start-stroke: var(--keyis-link);
    --qa-kind-start-label: var(--keyis-link);

    /* Edges — `--qa-edge-highlight` / `--qa-edge-selected` cascade
       from the accent / selected tokens above, so they're left
       implicit. */
    --qa-edge: #888888;

    /* Radii — align with Bootstrap's `--bs-border-radius` family so
       QA cards read at the same shape as Bootstrap cards / inputs. */
    --qa-radius: var(--bs-border-radius-lg);
    --qa-radius-sm: var(--bs-border-radius);
}

/* The library's primary toolbar button (`.qa-tbtn-primary`) sets
   `color: #ffffff` inline in its rule — overrides above don't reach
   it because they only set custom properties; the rule's `color`
   property is a direct value. That's fine: brand-black background
   + white text is exactly the contract we want. No further override
   needed.

   Inline-styled surfaces in `QAStatusVisualisation.ts` (status pill
   badges in approval dialogs) use hard-coded hex values for bg/fg/
   border that bypass CSS variables entirely. Those are a library
   limitation; brand alignment for status pills requires a library
   change, not a consumer CSS override. */

/* QA Flow Designer — layout integration with Serenity's full-height
   page chrome.

   The library's `QAFlowDesigner.cshtml` view sets an INLINE style
   `style="height: calc(100vh - 120px); width: 100%"` on the root
   div. That's a hard-coded viewport-math approach that pre-dates
   the consuming app's chrome heights:

   - `100vh - 120px` assumes the app reserves exactly 120px of
     vertical space for chrome above the canvas. In KeyView the
     header is 48px and `section.content` has 1.25rem (20px) of
     padding on all sides, so the actual reserved space is closer
     to 88px (48 + 20 top padding + 20 bottom padding). Result: the
     canvas falls ~55px short of the section bottom on most viewport
     heights, exposing a strip of the (white) `s-main` underneath —
     reads visually as a "bar across the bottom of the screen" that
     a standard Serenity page wouldn't have.

   - Because the height is keyed off `100vh` (not the parent's flex
     box), a resize that changes the chrome layout (e.g. a wrapped
     toolbar growing taller, or the user expanding the page after a
     narrow-window load) doesn't get the canvas to refit cleanly.

   Serenity ships `section.content` with `display: flex; flex-direction:
   column; min-height: calc(100vh - 48px)` already — the standard
   way to fill the page below the sticky header is to make the
   designer root a flex child (`flex: 1 1 auto; min-height: 0`)
   so the section's flex layout owns the height calculation. We
   override the inline style here.

   Inline styles win against author stylesheets unless `!important`
   is used — hence the `!important` on every property that the
   cshtml inline-stamps. */
.qa-designer-root {
    height: auto !important;
    flex: 1 1 auto !important;
    min-height: 0 !important;
    align-self: stretch;
}

/* Belt-and-braces: ensure the sidebar header explicitly fills the
   viewport width regardless of body intrinsic-sizing quirks. The
   Serenity default sets `display: flex; height: 48px !important`
   but no width — a sticky element with no `width` derives its
   width from its containing block. On some browsers (particularly
   after a viewport resize when devtools dock state changes), the
   sticky element can latch onto its first-paint width and not
   refresh. Pinning `width: 100%` removes that ambiguity. */
.s-sidebar-header {
    width: 100%;
}

/* =====================================================================
   Typography — Roboto, light body / bold headings (per PDF page 4).
   ===================================================================== */
body {
    font-family: var(--keyis-font-sans);
    font-weight: 300;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
    font-family: var(--keyis-font-sans);
    font-weight: 700;
}

.btn { font-family: var(--keyis-font-sans); font-weight: 500; }

/* Step-gated wizard tabs — Bootstrap's default for .disabled on
   nav-tabs is just cursor + faded text; this adds a clearer
   "not yet reachable" cue. */
.nav-tabs .nav-link.disabled { opacity: 0.45; cursor: not-allowed; }

/* Bootstrap doesn't add `cursor: pointer` to `.nav-link`; anchors get
   it from the browser default, but the wizard step pills are <span>s
   and therefore don't. Restore the affordance for any enabled nav link. */
.nav-link:not(.disabled) { cursor: pointer; }

/* Native file input — Serenity's `.tool-button.add-file-button` has
   cursor: pointer, but the file input is layered on top of it without
   one (Chrome/Edge default is the I-beam). Make the whole "Select File"
   surface read as clickable. */
input[type="file"] { cursor: pointer; }

/* Bootstrap's `.btn-link` (link-styled button) reads --bs-link-color
   by default, which makes it render in our sky link colour — clashes
   visually with the rest of the (black) button palette. Reset to brand
   black; hover keeps the link sky as the affordance cue. */
.btn-link {
    --bs-btn-color: var(--keyis-black);
    --bs-btn-hover-color: var(--keyis-link);
}

/* Bootstrap 5.3 hardcodes hex values inside each `.btn-*` variant
   (e.g. `.btn-primary { --bs-btn-bg: #0d6efd; … }`) rather than reading
   from `--bs-primary`. So overriding the theme `--bs-primary` colour
   alone doesn't change button backgrounds — the per-component vars
   must be set explicitly. Map each variant to the brand palette.
   .btn-success/-warning/-danger DO use RAG colours intentionally:
   these variants communicate semantic status (affirmative/caution/
   destructive) which IS the RAG contract. */
.btn-primary {
    --bs-btn-bg: var(--keyis-black);
    --bs-btn-border-color: var(--keyis-black);
    --bs-btn-hover-bg: #1f1f1f;
    --bs-btn-hover-border-color: #1f1f1f;
    --bs-btn-active-bg: #2b2b2b;
    --bs-btn-active-border-color: #2b2b2b;
    --bs-btn-disabled-bg: var(--keyis-black);
    --bs-btn-disabled-border-color: var(--keyis-black);
}
.btn-secondary {
    --bs-btn-bg: #555555;
    --bs-btn-border-color: #555555;
    --bs-btn-hover-bg: #3a3a3a;
    --bs-btn-hover-border-color: #3a3a3a;
    --bs-btn-active-bg: #2b2b2b;
    --bs-btn-active-border-color: #2b2b2b;
    --bs-btn-disabled-bg: #555555;
    --bs-btn-disabled-border-color: #555555;
}
.btn-success {
    --bs-btn-bg: var(--keyis-rule-green);
    --bs-btn-border-color: var(--keyis-rule-green);
    --bs-btn-hover-bg: #5fa040;
    --bs-btn-hover-border-color: #5fa040;
    --bs-btn-active-bg: #4d8a33;
    --bs-btn-active-border-color: #4d8a33;
    --bs-btn-disabled-bg: var(--keyis-rule-green);
    --bs-btn-disabled-border-color: var(--keyis-rule-green);
}
.btn-info {
    --bs-btn-color: #1a1a1a;
    --bs-btn-bg: var(--keyis-rule-sky);
    --bs-btn-border-color: var(--keyis-rule-sky);
    --bs-btn-hover-color: #1a1a1a;
    --bs-btn-hover-bg: #5cb5da;
    --bs-btn-hover-border-color: #5cb5da;
    --bs-btn-active-color: #1a1a1a;
    --bs-btn-active-bg: #4ba2c8;
    --bs-btn-active-border-color: #4ba2c8;
    --bs-btn-disabled-color: #1a1a1a;
    --bs-btn-disabled-bg: var(--keyis-rule-sky);
    --bs-btn-disabled-border-color: var(--keyis-rule-sky);
}
.btn-warning {
    --bs-btn-color: #1a1a1a;
    --bs-btn-bg: var(--keyis-rule-yellow);
    --bs-btn-border-color: var(--keyis-rule-yellow);
    --bs-btn-hover-color: #1a1a1a;
    --bs-btn-hover-bg: #e6b835;
    --bs-btn-hover-border-color: #e6b835;
    --bs-btn-active-color: #1a1a1a;
    --bs-btn-active-bg: #cca22c;
    --bs-btn-active-border-color: #cca22c;
    --bs-btn-disabled-color: #1a1a1a;
    --bs-btn-disabled-bg: var(--keyis-rule-yellow);
    --bs-btn-disabled-border-color: var(--keyis-rule-yellow);
}
.btn-danger {
    --bs-btn-bg: var(--keyis-rule-red);
    --bs-btn-border-color: var(--keyis-rule-red);
    --bs-btn-hover-bg: #b22d44;
    --bs-btn-hover-border-color: #b22d44;
    --bs-btn-active-bg: #962238;
    --bs-btn-active-border-color: #962238;
    --bs-btn-disabled-bg: var(--keyis-rule-red);
    --bs-btn-disabled-border-color: var(--keyis-rule-red);
}

/* Outline variants — same per-component hardcoded-hex problem as
   filled variants. Override so they read as branded buttons on light
   surfaces (notably the dashboard-card actions: Edit/Copy/Share/etc.). */
.btn-outline-primary {
    --bs-btn-color: var(--keyis-black);
    --bs-btn-border-color: var(--keyis-black);
    --bs-btn-hover-color: #ffffff;
    --bs-btn-hover-bg: var(--keyis-black);
    --bs-btn-hover-border-color: var(--keyis-black);
    --bs-btn-active-color: #ffffff;
    --bs-btn-active-bg: #1f1f1f;
    --bs-btn-active-border-color: #1f1f1f;
    --bs-btn-disabled-color: var(--keyis-black);
    --bs-btn-disabled-border-color: var(--keyis-black);
}
.btn-outline-secondary {
    --bs-btn-color: #555555;
    --bs-btn-border-color: #555555;
    --bs-btn-hover-color: #ffffff;
    --bs-btn-hover-bg: #555555;
    --bs-btn-hover-border-color: #555555;
    --bs-btn-active-color: #ffffff;
    --bs-btn-active-bg: #3a3a3a;
    --bs-btn-active-border-color: #3a3a3a;
    --bs-btn-disabled-color: #6c757d;
    --bs-btn-disabled-border-color: #6c757d;
}
.btn-outline-danger {
    --bs-btn-color: var(--keyis-rule-red);
    --bs-btn-border-color: var(--keyis-rule-red);
    --bs-btn-hover-color: #ffffff;
    --bs-btn-hover-bg: var(--keyis-rule-red);
    --bs-btn-hover-border-color: var(--keyis-rule-red);
    --bs-btn-active-color: #ffffff;
    --bs-btn-active-bg: #b22d44;
    --bs-btn-active-border-color: #b22d44;
    --bs-btn-disabled-color: var(--keyis-rule-red);
    --bs-btn-disabled-border-color: var(--keyis-rule-red);
}

/* Sisolco.Dashboards edit-mode form checkboxes (per-cell config dialog —
   e.g. the KPI tile's RAG-band toggle, click-intent enable toggles) ship
   with `width: auto` on `.sisolco-dashboard-form-control
   .sisolco-dashboard-form-checkbox-input`. That assumes the checkbox keeps
   its native intrinsic ~13px footprint, but Serenity Extensions'
   `common-theme.css` applies `border: 1px solid` + `box-sizing: border-box`
   to every `<input>`, which collapses the `width: auto` checkbox to ~1.3px
   — too narrow to show the tick. Pin an explicit 1em width/height so the
   checkbox renders at the same size as a Serenity grid checkbox. */
.sisolco-dashboard-form-control .sisolco-dashboard-form-checkbox-input,
.sisolco-dashboard-form-checkbox input[type="checkbox"] {
    width: 1em;
    height: 1em;
    min-width: 1em;
}

/* Amber RAG contrast is now handled by the library default rule
   `.sisolco-dashboard-kpi-tile.rag-amber { color: var(--sisolco-dashboard-
   fg-on-rag-amber, #1a1a1a) }` introduced in Sisolco.Dashboards 1.11.0.
   The `--sisolco-dashboard-fg-on-rag-amber` variable is set in `:root`
   above; no inline-style attribute matching needed. */

/* =====================================================================
   DARK CHROME — sidebar + sidebar header.
   The brand is grounded in black + slate-white; the chrome takes the
   black side, the data area takes the white side.
   ===================================================================== */
.s-sidebar,
.s-sidebar-pane {
    background-color: var(--keyis-black);
    color: #ffffff;
}

.s-sidebar-header {
    background-color: var(--keyis-black);
    color: #ffffff;
    border-bottom: 0;
}

/* Signature rainbow rule under the sidebar header — the brand's
   recurring device (PDF page 1, 2, 3 strapline). */
.s-sidebar-header::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 3px;
    background-image: var(--keyis-rainbow);
    background-repeat: no-repeat;
    background-size: 100% 100%;
    pointer-events: none;
}

.s-sidebar-header-title {
    color: #ffffff;
    font-weight: 500;
    letter-spacing: 0.02em;
}

.s-sidebar-header-link,
.s-sidebar-toggler {
    color: rgba(255, 255, 255, 0.78);
}
.s-sidebar-header-link:hover,
.s-sidebar-toggler:hover {
    color: #ffffff;
}

/* Sidebar search box — translucent surface against the black pane. */
.s-sidebar-search-input {
    background-color: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.18);
    color: #ffffff;
}
.s-sidebar-search-input::placeholder { color: rgba(255, 255, 255, 0.5); }
.s-sidebar-search-input:focus {
    background-color: rgba(255, 255, 255, 0.14);
    border-color: var(--keyis-rule-sky);
    color: #ffffff;
    outline: none;
    box-shadow: none;
}
.s-sidebar-search-icon { color: rgba(255, 255, 255, 0.5); }

/* Sidebar nav links — muted white inactive, full white on hover/active,
   left accent stripe in brand sky on the active item. */
.s-sidebar-link {
    color: rgba(255, 255, 255, 0.72);
    border-left: 3px solid transparent;
}
.s-sidebar-link:hover {
    color: #ffffff;
    background-color: rgba(255, 255, 255, 0.06);
}
.s-sidebar-item.active > .s-sidebar-link {
    color: #ffffff;
    background-color: rgba(255, 255, 255, 0.08);
    border-left-color: var(--keyis-rule-sky);
    font-weight: 500;
}

.s-sidebar-icon { color: inherit; }
.s-sidebar-menu-toggle { color: inherit; opacity: 0.6; }

/* Submenu (nested ul) — slightly darker rail. */
.s-sidebar-menu .s-sidebar-menu {
    background-color: rgba(0, 0, 0, 0.4);
}

/* Sidebar menu must scroll when taller than the pane. The library pins
   .s-sidebar-pane (a flex column) top:0/bottom:0 but gives neither the pane
   nor the menu any overflow, so a deep tree / short viewport pushes items
   below the fixed bottom with no way to reach them. Let the search box keep
   its natural height and the menu take the rest and scroll. Target the outer
   <ul> by id — nested submenus share .s-sidebar-menu, so the id avoids them. */
#s-sidebar-menu {
    flex: 1 1 auto;
    min-height: 0;        /* allow the flex child to shrink below content height */
    overflow-y: auto;
    overflow-x: hidden;
}

/* =====================================================================
   LIGHT CONTENT — main data area stays on white.
   ===================================================================== */
.s-main {
    background-color: var(--bs-body-bg);
    color: var(--bs-body-color);
}

/* =====================================================================
   MODAL HEADER — mirror the dark sidebar pattern.
   Only applied to Bootstrap modals (`.modal-header`), where the
   container has no outer border so the black band reads cleanly to
   the corner radius. Serenity `.panel-titlebar` dialogs sit inside a
   white-bordered `.s-Panel` and the contrast at the corners looks
   broken, so they keep the default light titlebar treatment.
   The brand rainbow rule sits along the bottom edge — signature
   device. The modal body stays light. */
.modal-header {
    background-color: var(--keyis-black);
    color: #ffffff;
    border-bottom: 0;
    position: relative;
}
.modal-header::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 3px;
    background-image: var(--keyis-rainbow);
    background-repeat: no-repeat;
    background-size: 100% 100%;
    pointer-events: none;
}

.modal-title { color: #ffffff; }

/* Close button — Bootstrap's `.btn-close` is a dark SVG mask;
   invert for visibility on the black band. */
.modal-header .btn-close {
    color: rgba(255, 255, 255, 0.78);
    filter: invert(1) grayscale(1) brightness(2);
}
.modal-header .btn-close:hover { color: #ffffff; }

/* =====================================================================
   MOBILE DIALOGS — full-screen below the library's 760px breakpoint.

   On a narrow viewport Serenity opens entity/property dialogs IN-PAGE as a
   flex panel (`.s-Panel.flex-layout` → `.panel-titlebar` / `.panel-body` /
   `.panel-footer`) appended into `section.content`, NOT as a floating
   jQuery-UI `.ui-dialog`. The panel has no height cap (`max-height: none`),
   so a tall form grows the panel past the screen bottom while `.panel-body`
   (`overflow: visible`) never scrolls and the page itself doesn't scroll to
   it — the footer (Save/Cancel) and lower fields become unreachable. This is
   the primary mobile bug.

   Fix: pin the panel to the viewport (`position: fixed; inset: 0; 100dvh`)
   and let `.panel-body` own the scroll (`overflow-y: auto; min-height: 0`).
   100dvh tracks the real visible height as mobile browser chrome shows/hides.
   The small message-box family is excluded so a short confirm/alert isn't
   blown up full-screen. The panel is `position: static` in flow, so the
   fixed override does NOT need `!important` to win on the positioning
   properties, but z-index lifts it above the sticky header (z 11). */
@media (max-width: 760px) {
    .s-Panel.flex-layout:not(.s-MessageDialog):not(.s-AlertDialog):not(.s-ConfirmDialog):not(.s-InformationDialog):not(.s-SuccessDialog):not(.s-WarningDialog) {
        position: fixed;
        inset: 0;
        margin: 0;
        width: 100vw;
        max-width: 100vw;
        height: 100dvh;
        max-height: 100dvh;
        border-radius: 0;
        z-index: 1050;
    }
    .s-Panel.flex-layout > .panel-body {
        overflow-y: auto;
        min-height: 0;        /* allow the flex body to shrink and scroll */
    }

    /* Fallback for the floating jQuery-UI dialog path, in case a config /
       device opens a dialog as `.ui-dialog` rather than the in-page panel.
       jQuery UI writes inline top/left/width/height/position, so each needs
       !important here. Same message-box exclusion. */
    .ui-dialog:not(.s-MessageDialog):not(.s-AlertDialog):not(.s-ConfirmDialog):not(.s-InformationDialog):not(.s-SuccessDialog):not(.s-WarningDialog) {
        position: fixed !important;
        top: 0 !important;
        left: 0 !important;
        width: 100vw !important;
        max-width: 100vw !important;
        height: 100dvh !important;
        max-height: 100dvh !important;
        border-radius: 0 !important;
        display: flex !important;
        flex-direction: column !important;
    }
    .ui-dialog:not(.s-MessageDialog):not(.s-AlertDialog):not(.s-ConfirmDialog):not(.s-InformationDialog):not(.s-SuccessDialog):not(.s-WarningDialog) > .ui-dialog-content {
        flex: 1 1 auto !important;
        height: auto !important;
        min-height: 0 !important;
        overflow: auto !important;
    }
    /* Tabbed dialogs: let the active tab panel shrink so its body scrolls. */
    .ui-tabs-panel {
        min-height: 0;
    }
}

/* Serenity grids / SleekGrid bake link colours into specific selectors
   that don't all read --bs-link-color. Belt-and-braces: pull every
   anchor inside the data area into the brand palette, with the rainbow
   red as the hover. Sidebar anchors are unaffected because the sidebar
   rules above target `.s-sidebar-link` / `.s-sidebar-header-link`
   directly and have higher specificity. */
.s-main a,
.s-main a:visited,
.slick-cell a,
.s-DataGrid a,
.s-EditLink,
a.s-EditLink {
    color: var(--keyis-link);
    text-decoration: none;
}
.s-main a:hover,
.slick-cell a:hover,
.s-DataGrid a:hover,
.s-EditLink:hover,
a.s-EditLink:hover {
    color: var(--keyis-link-hover);
    text-decoration: underline;
}

/* Anchors styled as buttons (`<a class="btn ...">`) must opt OUT of the
   link colour rule above — they're buttons by intent, so they should
   read the Bootstrap btn colour vars set by the variant class. Without
   this, link-buttons render as sky-blue text on a black/outline
   background, which looks broken.

   `.sisolco-mydashboards-action` is excluded because Sisolco.Dashboards
   1.11.0 sets its own `color: var(--sisolco-mydashboards-action-*-fg)`;
   this rule has higher specificity and would clobber it with
   `var(--bs-btn-color)` which is unset for that variant. */
.s-main a.btn:not(.sisolco-mydashboards-action),
.s-main a.btn:not(.sisolco-mydashboards-action):visited {
    color: var(--bs-btn-color);
    text-decoration: none;
}
.s-main a.btn:not(.sisolco-mydashboards-action):hover {
    color: var(--bs-btn-hover-color);
    text-decoration: none;
}

/* =====================================================================
   Preserved from the previous site.css.
   ===================================================================== */
.s-site-logo-img {
    content: url(images/KeyIS_Symbol_AW_RGB_White.png);
}

.s-TranslationGrid input.custom-text {
    width: 100%;
    height: 23px;
    padding: 0 3px;
}

.s-PermissionCheckEditor {
    min-height: 450px;
}

/* =====================================================================
   Projects module — Milestone/Deliverable Forecast-date RAG banding.
   The `rag-red` / `rag-amber` / `rag-green` classes are emitted by the
   ForecastDateFormatter (Modules/Projects/Shared/ForecastDateFormatter.tsx),
   a three-band tolerance comparison of the forecast date against a reference
   date: later than target beyond DaysTolerance (red), within ±DaysTolerance
   of target (amber), earlier than target beyond DaysTolerance (green).
   Background tints are derived from the brand RAG palette already defined in
   :root above, so they automatically follow any theme change. Padding + radius
   keep the chip readable inside the SleekGrid cell.
   ===================================================================== */
.slick-cell .rag-red,
.slick-cell .rag-amber,
.slick-cell .rag-green {
    display: inline-block;
    padding: 1px 6px;
    border-radius: var(--bs-border-radius-sm);
}
.slick-cell .rag-red   { background-color: rgba(233, 66, 92, 0.18); color: #6e1e2b; }
.slick-cell .rag-amber { background-color: rgba(240, 173, 78, 0.22); color: #7a5300; }
.slick-cell .rag-green { background-color: rgba(117, 185, 78, 0.20); color: #2f5520; }

/* Form-level RAG tint on date inputs — the dialog's date editor wraps an <input>; we
   apply rag-* on the <input> directly so the chip-style background reads inside the
   form field while the cursor is in the value. The class is toggled by the dialog
   based on the forecast/target comparison. */
input.rag-red   { background-color: rgba(233, 66, 92, 0.18); }
input.rag-amber { background-color: rgba(240, 173, 78, 0.22); }
input.rag-green { background-color: rgba(117, 185, 78, 0.20); }

/* =====================================================================
   Dashboards — Table widget row-level RAG wash.
   The Sisolco.Dashboards Table widget stamps `row-rag-{red|amber|green}`
   on each <tr> when a tile has UseRagColouring=true (resolved from the
   provider's `rag` envelope), but the library ships NO paint for those
   classes — only the per-cell `.rag-pill` is styled. Without this block
   the row tint never appears even though the class is present. Supply the
   wash here, derived from the brand RAG palette (the --sisolco-dashboard-
   rag-* tokens set in :root) so it follows any theme change.

   Specificity note: the doubled `.sisolco-dashboard-table` lifts these
   rules to (0,3,3) so the wash beats the library's later-loaded zebra
   rule `tbody tr:nth-child(2n) td` (0,2,3) on every row, while the equal-
   specificity hover rule `tbody tr.clickable:hover td` (0,3,3, loaded
   after site.css) still wins so clickable rows keep their hover feedback.
   ===================================================================== */
.sisolco-dashboard-table.sisolco-dashboard-table tbody tr.row-rag-red   > td { background-color: color-mix(in srgb, var(--sisolco-dashboard-rag-red)   14%, transparent); }
.sisolco-dashboard-table.sisolco-dashboard-table tbody tr.row-rag-amber > td { background-color: color-mix(in srgb, var(--sisolco-dashboard-rag-amber) 18%, transparent); }
.sisolco-dashboard-table.sisolco-dashboard-table tbody tr.row-rag-green > td { background-color: color-mix(in srgb, var(--sisolco-dashboard-rag-green) 16%, transparent); }
