﻿/* ============================================================================
   Theme
   ----------------------------------------------------------------------------
   Blazorise already ships a light palette on :root, so light is left to it and
   only dark is written here - the same shape as the one dark rule Blazorise
   ships itself, which keys on [data-theme=dark] and on prefers-color-scheme
   with an explicit light choice excluded.

   Three states, in cascade order:
     :root                       what Blazorise ships, which is light
     @media prefers dark         the operating system, while no choice is stored
     [data-theme=light|dark]     an explicit choice, which outranks both

   data-theme is put onto the html element by BaselineZInterop from local storage
   as it loads, and is absent entirely while the operating system decides.
   ============================================================================ */

:root {
    --b-vertical-bar-width: min(300px, max(200px, calc(20vw)));

    /* Brand, in both themes. --mui-dark stays the navy because it is Material's
       "dark" variant and other things ask it for a dark colour. */
    --mui-primary: #00ACD6;
    --mui-dark: #070E22;
    --mui-dark-container: #0A2136;
    --mui-dark-hover: #1b2133;
    --mui-on-dark: #FDF8FD;
    --mui-on-dark-container: #DFE3EC;
    --mui-outline-dark: #636777;
    --mui-outline-dark-variant: #2e3345;

    /* The tree view keeps its own variable, whose built-in fallback is a bootstrap
       blue left over from another provider. */
    --b-tree-view-primary: var(--mui-primary);

    /* The ink on the brand cyan, in both themes, because the cyan it sits on is
       the same colour in both. The shipped white was 2.67:1 and failed AA; this
       holds 5.07:1 at worst across the rest and hover states. */
    --mui-on-primary: #001f29;

    /* Hover has to stay on the brand hue too, or that ink is only readable at
       rest: the provider's own hover is an indigo left over from its palette,
       and no single ink reads on both that and the cyan. Light darkens the cyan;
       the dark rule below lightens it, each moving away from its own surface. */
    --mui-primary-hover: #0098bd;

    /* The hero scrim, as a bare triplet so both ends of its gradient can be the
       same colour at different alphas - fading to plain transparent fades to
       transparent black, which drags a light scrim through grey on the way out. */
    --bz-hero-scrim-rgb: 242 236 241;

    /* ---- the dark palette, named once and applied by the two rules below ----
       Surfaces are derived from the brand navy rather than Material's neutral
       grey, so the chrome keeps its identity when the theme changes. The
       semantic families sit at Material's dark tones: the colour at T80, its ink
       at T20, its container at T30 and that container's ink at T90. */
    --bz-dark-background: #0A1424;
    --bz-dark-on-background: #DFE3EC;
    --bz-dark-surface: #0A1424;
    --bz-dark-on-surface: #DFE3EC;
    --bz-dark-surface-variant: #1A2740;
    --bz-dark-on-surface-variant: #B9C1D4;
    --bz-dark-surface-dim: #070E22;
    --bz-dark-surface-bright: #26314A;
    --bz-dark-container-lowest: #050A18;
    --bz-dark-container-low: #0D1729;
    --bz-dark-container: #111C31;
    --bz-dark-container-high: #1A2740;
    --bz-dark-container-highest: #25334E;
    --bz-dark-outline: #7C879E;
    --bz-dark-outline-variant: #313D54;
    --bz-dark-active: rgb(255 255 255 / 0.12);
    --bz-dark-overlay: rgb(0 0 0 / 0.6);
    --bz-dark-light: #111C31;
    --bz-dark-light-hover: #1A2740;
    --bz-dark-on-light: #DFE3EC;
    --bz-dark-light-container: #1A2740;
    --bz-dark-on-light-container: #DFE3EC;
    --bz-dark-elevate1: 0px 1px 2px rgb(0 0 0 / 0.5), 0px 1px 3px rgb(0 0 0 / 0.35);
    --bz-dark-elevate2: 0px 2px 4px rgb(0 0 0 / 0.5), 0px 1px 5px rgb(0 0 0 / 0.35);
    --bz-dark-elevate3: 0px 4px 8px rgb(0 0 0 / 0.5), 0px 1px 3px rgb(0 0 0 / 0.35);
    --bz-dark-primary-hover: #35bee9;
    --bz-dark-primary-container: #004d62;
    --bz-dark-on-primary-container: #baeaff;
    --bz-dark-secondary: #c3c5dd;
    --bz-dark-secondary-hover: #d4d6ee;
    --bz-dark-on-secondary: #2d2f42;
    --bz-dark-secondary-container: #434559;
    --bz-dark-on-secondary-container: #dfe1f9;
    --bz-dark-tertiary: #e8bac9;
    --bz-dark-tertiary-hover: #facbda;
    --bz-dark-on-tertiary: #492533;
    --bz-dark-tertiary-container: #623b49;
    --bz-dark-on-tertiary-container: #ffd9e5;
    --bz-dark-error: #ffb4a5;
    --bz-dark-error-hover: #ffcbc1;
    --bz-dark-on-error: #690001;
    --bz-dark-error-container: #93000c;
    --bz-dark-on-error-container: #ffdad3;
    --bz-dark-success: #7fd9a1;
    --bz-dark-success-hover: #90eab1;
    --bz-dark-on-success: #00391d;
    --bz-dark-success-container: #00522d;
    --bz-dark-on-success-container: #9bf6bc;
    --bz-dark-warning: #eebf6c;
    --bz-dark-warning-hover: #ffd07f;
    --bz-dark-on-warning: #402d00;
    --bz-dark-warning-container: #5d4200;
    --bz-dark-on-warning-container: #ffdeaa;
    --bz-dark-info: #9ecaff;
    --bz-dark-info-hover: #bed9ff;
    --bz-dark-on-info: #003354;
    --bz-dark-info-container: #004a77;
    --bz-dark-on-info-container: #d1e4ff;
    --bz-dark-outline-primary: #165e7a;
    --bz-dark-outline-primary-variant: #112f43;
    --bz-dark-outline-secondary: #64697e;
    --bz-dark-outline-secondary-variant: #2b3244;
    --bz-dark-outline-tertiary: #766474;
    --bz-dark-outline-tertiary-variant: #323141;
    --bz-dark-outline-error: #826164;
    --bz-dark-outline-error-variant: #38303b;
    --bz-dark-outline-success: #457262;
    --bz-dark-outline-success-variant: #21363b;
    --bz-dark-outline-warning: #7c664a;
    --bz-dark-outline-warning-variant: #363133;
    --bz-dark-outline-info: #516b8d;
    --bz-dark-outline-info-variant: #24334a;
    --bz-dark-outline-light: #42495d;
    --bz-dark-outline-light-variant: #273045;
}

/* An explicit light choice has to say so, or a dark system would still colour
   the form controls. */
:root[data-theme="light"] {
    color-scheme: light;
}

/* Dark, chosen. */
:root[data-theme="dark"] {
    color-scheme: dark;
    --bz-hero-scrim-rgb: 7 14 32;

    --mui-background: var(--bz-dark-background);
    --mui-on-background: var(--bz-dark-on-background);
    --mui-surface: var(--bz-dark-surface);
    --mui-on-surface: var(--bz-dark-on-surface);
    --mui-surface-variant: var(--bz-dark-surface-variant);
    --mui-on-surface-variant: var(--bz-dark-on-surface-variant);
    --mui-surface-dim: var(--bz-dark-surface-dim);
    --mui-surface-bright: var(--bz-dark-surface-bright);
    --mui-surface-container-lowest: var(--bz-dark-container-lowest);
    --mui-surface-container-low: var(--bz-dark-container-low);
    --mui-surface-container: var(--bz-dark-container);
    --mui-surface-container-high: var(--bz-dark-container-high);
    --mui-surface-container-highest: var(--bz-dark-container-highest);
    --mui-outline: var(--bz-dark-outline);
    --mui-outline-variant: var(--bz-dark-outline-variant);
    --mui-active: var(--bz-dark-active);
    --mui-overlay: var(--bz-dark-overlay);
    --mui-light: var(--bz-dark-light);
    --mui-light-hover: var(--bz-dark-light-hover);
    --mui-on-light: var(--bz-dark-on-light);
    --mui-light-container: var(--bz-dark-light-container);
    --mui-on-light-container: var(--bz-dark-on-light-container);
    --mui-elevate1: var(--bz-dark-elevate1);
    --mui-elevate2: var(--bz-dark-elevate2);
    --mui-elevate3: var(--bz-dark-elevate3);
    --mui-primary-hover: var(--bz-dark-primary-hover);
    --mui-primary-container: var(--bz-dark-primary-container);
    --mui-on-primary-container: var(--bz-dark-on-primary-container);
    --mui-secondary: var(--bz-dark-secondary);
    --mui-secondary-hover: var(--bz-dark-secondary-hover);
    --mui-on-secondary: var(--bz-dark-on-secondary);
    --mui-secondary-container: var(--bz-dark-secondary-container);
    --mui-on-secondary-container: var(--bz-dark-on-secondary-container);
    --mui-tertiary: var(--bz-dark-tertiary);
    --mui-tertiary-hover: var(--bz-dark-tertiary-hover);
    --mui-on-tertiary: var(--bz-dark-on-tertiary);
    --mui-tertiary-container: var(--bz-dark-tertiary-container);
    --mui-on-tertiary-container: var(--bz-dark-on-tertiary-container);
    --mui-error: var(--bz-dark-error);
    --mui-error-hover: var(--bz-dark-error-hover);
    --mui-on-error: var(--bz-dark-on-error);
    --mui-error-container: var(--bz-dark-error-container);
    --mui-on-error-container: var(--bz-dark-on-error-container);
    --mui-success: var(--bz-dark-success);
    --mui-success-hover: var(--bz-dark-success-hover);
    --mui-on-success: var(--bz-dark-on-success);
    --mui-success-container: var(--bz-dark-success-container);
    --mui-on-success-container: var(--bz-dark-on-success-container);
    --mui-warning: var(--bz-dark-warning);
    --mui-warning-hover: var(--bz-dark-warning-hover);
    --mui-on-warning: var(--bz-dark-on-warning);
    --mui-warning-container: var(--bz-dark-warning-container);
    --mui-on-warning-container: var(--bz-dark-on-warning-container);
    --mui-info: var(--bz-dark-info);
    --mui-info-hover: var(--bz-dark-info-hover);
    --mui-on-info: var(--bz-dark-on-info);
    --mui-info-container: var(--bz-dark-info-container);
    --mui-on-info-container: var(--bz-dark-on-info-container);
    --mui-outline-primary: var(--bz-dark-outline-primary);
    --mui-outline-primary-variant: var(--bz-dark-outline-primary-variant);
    --mui-outline-secondary: var(--bz-dark-outline-secondary);
    --mui-outline-secondary-variant: var(--bz-dark-outline-secondary-variant);
    --mui-outline-tertiary: var(--bz-dark-outline-tertiary);
    --mui-outline-tertiary-variant: var(--bz-dark-outline-tertiary-variant);
    --mui-outline-error: var(--bz-dark-outline-error);
    --mui-outline-error-variant: var(--bz-dark-outline-error-variant);
    --mui-outline-success: var(--bz-dark-outline-success);
    --mui-outline-success-variant: var(--bz-dark-outline-success-variant);
    --mui-outline-warning: var(--bz-dark-outline-warning);
    --mui-outline-warning-variant: var(--bz-dark-outline-warning-variant);
    --mui-outline-info: var(--bz-dark-outline-info);
    --mui-outline-info-variant: var(--bz-dark-outline-info-variant);
    --mui-outline-light: var(--bz-dark-outline-light);
    --mui-outline-light-variant: var(--bz-dark-outline-light-variant);
}

/* Dark, asked for by the system, while no choice is stored. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        color-scheme: dark;
        --bz-hero-scrim-rgb: 7 14 32;

        --mui-background: var(--bz-dark-background);
        --mui-on-background: var(--bz-dark-on-background);
        --mui-surface: var(--bz-dark-surface);
        --mui-on-surface: var(--bz-dark-on-surface);
        --mui-surface-variant: var(--bz-dark-surface-variant);
        --mui-on-surface-variant: var(--bz-dark-on-surface-variant);
        --mui-surface-dim: var(--bz-dark-surface-dim);
        --mui-surface-bright: var(--bz-dark-surface-bright);
        --mui-surface-container-lowest: var(--bz-dark-container-lowest);
        --mui-surface-container-low: var(--bz-dark-container-low);
        --mui-surface-container: var(--bz-dark-container);
        --mui-surface-container-high: var(--bz-dark-container-high);
        --mui-surface-container-highest: var(--bz-dark-container-highest);
        --mui-outline: var(--bz-dark-outline);
        --mui-outline-variant: var(--bz-dark-outline-variant);
        --mui-active: var(--bz-dark-active);
        --mui-overlay: var(--bz-dark-overlay);
        --mui-light: var(--bz-dark-light);
        --mui-light-hover: var(--bz-dark-light-hover);
        --mui-on-light: var(--bz-dark-on-light);
        --mui-light-container: var(--bz-dark-light-container);
        --mui-on-light-container: var(--bz-dark-on-light-container);
        --mui-elevate1: var(--bz-dark-elevate1);
        --mui-elevate2: var(--bz-dark-elevate2);
        --mui-elevate3: var(--bz-dark-elevate3);
        --mui-primary-hover: var(--bz-dark-primary-hover);
        --mui-primary-container: var(--bz-dark-primary-container);
        --mui-on-primary-container: var(--bz-dark-on-primary-container);
        --mui-secondary: var(--bz-dark-secondary);
        --mui-secondary-hover: var(--bz-dark-secondary-hover);
        --mui-on-secondary: var(--bz-dark-on-secondary);
        --mui-secondary-container: var(--bz-dark-secondary-container);
        --mui-on-secondary-container: var(--bz-dark-on-secondary-container);
        --mui-tertiary: var(--bz-dark-tertiary);
        --mui-tertiary-hover: var(--bz-dark-tertiary-hover);
        --mui-on-tertiary: var(--bz-dark-on-tertiary);
        --mui-tertiary-container: var(--bz-dark-tertiary-container);
        --mui-on-tertiary-container: var(--bz-dark-on-tertiary-container);
        --mui-error: var(--bz-dark-error);
        --mui-error-hover: var(--bz-dark-error-hover);
        --mui-on-error: var(--bz-dark-on-error);
        --mui-error-container: var(--bz-dark-error-container);
        --mui-on-error-container: var(--bz-dark-on-error-container);
        --mui-success: var(--bz-dark-success);
        --mui-success-hover: var(--bz-dark-success-hover);
        --mui-on-success: var(--bz-dark-on-success);
        --mui-success-container: var(--bz-dark-success-container);
        --mui-on-success-container: var(--bz-dark-on-success-container);
        --mui-warning: var(--bz-dark-warning);
        --mui-warning-hover: var(--bz-dark-warning-hover);
        --mui-on-warning: var(--bz-dark-on-warning);
        --mui-warning-container: var(--bz-dark-warning-container);
        --mui-on-warning-container: var(--bz-dark-on-warning-container);
        --mui-info: var(--bz-dark-info);
        --mui-info-hover: var(--bz-dark-info-hover);
        --mui-on-info: var(--bz-dark-on-info);
        --mui-info-container: var(--bz-dark-info-container);
        --mui-on-info-container: var(--bz-dark-on-info-container);
        --mui-outline-primary: var(--bz-dark-outline-primary);
        --mui-outline-primary-variant: var(--bz-dark-outline-primary-variant);
        --mui-outline-secondary: var(--bz-dark-outline-secondary);
        --mui-outline-secondary-variant: var(--bz-dark-outline-secondary-variant);
        --mui-outline-tertiary: var(--bz-dark-outline-tertiary);
        --mui-outline-tertiary-variant: var(--bz-dark-outline-tertiary-variant);
        --mui-outline-error: var(--bz-dark-outline-error);
        --mui-outline-error-variant: var(--bz-dark-outline-error-variant);
        --mui-outline-success: var(--bz-dark-outline-success);
        --mui-outline-success-variant: var(--bz-dark-outline-success-variant);
        --mui-outline-warning: var(--bz-dark-outline-warning);
        --mui-outline-warning-variant: var(--bz-dark-outline-warning-variant);
        --mui-outline-info: var(--bz-dark-outline-info);
        --mui-outline-info-variant: var(--bz-dark-outline-info-variant);
        --mui-outline-light: var(--bz-dark-outline-light);
        --mui-outline-light-variant: var(--bz-dark-outline-light-variant);
    }
}

/* ----------------------------------------------------------------------------
   Theme-conditional content.
   bz-if-dark is shown while the page is dark, bz-if-light while it is light -
   so the theme switch offers the theme you are not in, and the logo comes in the
   version that reads on the background behind it.

   Every rule below only ever hides. Nothing is hidden by default and then
   un-hidden, because un-hiding means naming a display value, and the right one
   differs by element - inline-flex for a button, block for an image. Left to
   their own display values, one set of rules serves both.
   ---------------------------------------------------------------------------- */

:root[data-theme="light"] .bz-if-dark {
    display: none;
}

@media (prefers-color-scheme: light) {
    :root:not([data-theme="dark"]) .bz-if-dark {
        display: none;
    }
}

:root[data-theme="dark"] .bz-if-light {
    display: none;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .bz-if-light {
        display: none;
    }
}

/* ----------------------------------------------------------------------------
   The default profile picture.
   A white figure on a transparent ground, which reads on a dark page and
   disappears on a light one. While the page is light it is drawn in grey
   instead. Matched on the file name, so a real photo is never recoloured - the
   default is swapped in by script when a photo fails to load, so nothing
   rendering it knows which of the two it is showing.
   ---------------------------------------------------------------------------- */

:root[data-theme="light"] img.bz-profile-picture[src*="DefaultAuthor"] {
    filter: brightness(0.45);
}

@media (prefers-color-scheme: light) {
    :root:not([data-theme="dark"]) img.bz-profile-picture[src*="DefaultAuthor"] {
        filter: brightness(0.45);
    }
}

/* A page header band, one step off the page surface. The one thing with no
   background utility behind it: the .bg-* set covers the semantic colours but
   not the surface ramp. */
.bz-page-header {
    background-color: var(--mui-surface-container);
    color: var(--mui-on-surface);
}

/* Out of sight but still read aloud: the caption of a button that only shows
   its icon. */
.bz-visually-hidden {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}

/* The home hero lays its title over a photo, so it needs an opaque end to sit on
   and a clear end to let the picture through. Both stops are the same colour at
   different alphas: fading to a plain "transparent" fades to transparent *black*,
   which drags a light scrim through grey on the way out. */
.bz-hero-scrim {
    inset: 0;
    color: var(--mui-on-surface);
    background: linear-gradient(to right,
                                rgb(var(--bz-hero-scrim-rgb) / 1),
                                rgb(var(--bz-hero-scrim-rgb) / 0));
}

/* ----------------------------------------------------------------------------
   Reconnect dialog.
   Blazor only builds its own when it cannot find #components-reconnect-modal,
   and the one it builds is sealed in a shadow root with white hard-coded into
   it. Components/App.razor supplies the element so this can style it instead.
   Blazor never sets any style itself here - it only adds one of the state
   classes below, so every state has to be drawn from the class alone.
   ---------------------------------------------------------------------------- */

.bz-reconnect {
    position: fixed;
    inset: 0;
    z-index: 10000;
    display: none;
    align-items: center;
    justify-content: center;
    background: var(--mui-overlay);
}

/* Every state Blazor can put the dialog in. "retrying" is listed even though it
   only ever arrives on top of "show" - it is added without the other being
   removed - so that the dialog does not depend on that staying true. */
.bz-reconnect.components-reconnect-show,
.bz-reconnect.components-reconnect-retrying,
.bz-reconnect.components-reconnect-failed,
.bz-reconnect.components-reconnect-rejected,
.bz-reconnect.components-reconnect-resume-failed,
.bz-reconnect.components-reconnect-paused {
    display: flex;
}

.bz-reconnect-dialog {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    width: min(22rem, calc(100vw - 2rem));
    padding: 2rem;
    text-align: center;
    color: var(--mui-on-surface);
    background: var(--mui-surface-container-high);
    border: 1px solid var(--mui-outline-variant);
    border-radius: 0.75rem;
    box-shadow: var(--mui-elevate3);
}

.bz-reconnect-dialog p {
    margin: 0;
}

.bz-reconnect-spinner {
    width: 2.75rem;
    height: 2.75rem;
    border: 0.25rem solid var(--mui-outline-variant);
    border-top-color: var(--mui-primary);
    border-radius: 50%;
    animation: bz-reconnect-spin 1.1s linear infinite;
}

@keyframes bz-reconnect-spin {
    to {
        transform: rotate(360deg);
    }
}

/* Nothing is shown until a state class says so, so each panel opts in. */
.bz-reconnect-rejoining,
.bz-reconnect-lost,
.bz-reconnect-halted,
.bz-reconnect-actions {
    display: none;
}

.components-reconnect-show .bz-reconnect-rejoining,
.components-reconnect-retrying .bz-reconnect-rejoining {
    display: block;
}

.components-reconnect-failed .bz-reconnect-lost,
.components-reconnect-rejected .bz-reconnect-lost,
.components-reconnect-resume-failed .bz-reconnect-lost {
    display: block;
}

.components-reconnect-paused .bz-reconnect-halted {
    display: block;
}

.components-reconnect-failed .bz-reconnect-actions,
.components-reconnect-rejected .bz-reconnect-actions,
.components-reconnect-resume-failed .bz-reconnect-actions,
.components-reconnect-paused .bz-reconnect-actions {
    display: flex;
    gap: 0.75rem;
    align-items: center;
}

/* There is nothing to spin through once the retrying has stopped. */
.components-reconnect-failed .bz-reconnect-spinner,
.components-reconnect-rejected .bz-reconnect-spinner,
.components-reconnect-resume-failed .bz-reconnect-spinner,
.components-reconnect-paused .bz-reconnect-spinner {
    display: none;
}

/* The counters are only filled in from the second attempt onward. */
.bz-reconnect-attempt {
    display: none;
    color: var(--mui-on-surface-variant);
    font-size: var(--mui-font-size-sm);
}

.components-reconnect-retrying .bz-reconnect-attempt {
    display: block;
    margin-top: 0.35rem;
}

.bz-reconnect-retry {
    font: inherit;
    padding: 0.4rem 1.25rem;
    color: var(--mui-on-primary);
    background: var(--mui-primary);
    border: 0;
    border-radius: 0.25rem;
    cursor: pointer;
}

.bz-reconnect-retry:hover {
    background: var(--mui-primary-hover);
}

.bz-reconnect-reload {
    color: var(--mui-primary);
}

@media (prefers-reduced-motion: reduce) {
    .bz-reconnect-spinner {
        animation-duration: 4s;
    }
}

/* ----------------------------------------------------------------------------
   Rich text editor (Quill, snow theme).

   quill.snow.css holds no custom properties at all - every colour in it is a
   literal - and Blazorise injects it into head at runtime, after this file, so
   an override of equal weight would lose on source order. Hence !important:
   the scope is still narrowed to the editor by the wrapper class, so nothing
   here can reach the rest of the page.

   Only the chrome is redirected. The .ql-color-* and .ql-bg-* classes and the
   swatches in the colour picker are the author's own choices, saved into the
   document, and stay the colours they claim to be. The code block keeps its own
   dark theme, which is a code block's convention in either scheme.

   The editing surface itself needs nothing: Quill leaves it transparent, so it
   already takes the page's background and text colour.
   ---------------------------------------------------------------------------- */

.b-richtextedit .ql-toolbar.ql-snow,
.b-richtextedit .ql-container.ql-snow {
    border-color: var(--mui-outline-variant) !important;
}

/* Toolbar glyphs are drawn as svg strokes and fills rather than text. */
.b-richtextedit .ql-snow .ql-stroke,
.b-richtextedit .ql-snow .ql-stroke-miter {
    stroke: var(--mui-on-surface-variant) !important;
}

.b-richtextedit .ql-snow .ql-fill,
.b-richtextedit .ql-snow .ql-stroke.ql-fill {
    fill: var(--mui-on-surface-variant) !important;
}

.b-richtextedit .ql-snow .ql-picker,
.b-richtextedit .ql-snow .ql-picker-label {
    color: var(--mui-on-surface-variant) !important;
}

/* The tool under the pointer, or the one already applied. Quill draws both in a
   blue of its own; the brand colour says the same thing. */
.b-richtextedit :is(button:hover, button:focus, button.ql-active,
                    .ql-picker-label:hover, .ql-picker-label.ql-active,
                    .ql-picker-item:hover, .ql-picker-item.ql-selected) {
    color: var(--mui-primary) !important;
}

.b-richtextedit :is(button:hover, button:focus, button.ql-active,
                    .ql-picker-label:hover, .ql-picker-label.ql-active,
                    .ql-picker-item:hover, .ql-picker-item.ql-selected) :is(.ql-stroke, .ql-stroke-miter) {
    stroke: var(--mui-primary) !important;
}

.b-richtextedit :is(button:hover, button:focus, button.ql-active,
                    .ql-picker-label:hover, .ql-picker-label.ql-active,
                    .ql-picker-item:hover, .ql-picker-item.ql-selected) :is(.ql-fill, .ql-stroke.ql-fill) {
    fill: var(--mui-primary) !important;
}

/* Dropdowns and the link tooltip float above the page and need a surface. */
.b-richtextedit .ql-snow .ql-picker-options,
.b-richtextedit .ql-snow .ql-tooltip {
    color: var(--mui-on-surface) !important;
    background-color: var(--mui-surface-container-high) !important;
    border-color: var(--mui-outline-variant) !important;
    box-shadow: var(--mui-elevate2) !important;
}

.b-richtextedit .ql-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-label {
    border-color: var(--mui-outline-variant) !important;
    color: var(--mui-outline) !important;
}

.b-richtextedit .ql-snow .ql-tooltip input[type=text] {
    color: var(--mui-on-surface) !important;
    background-color: var(--mui-surface-container-lowest) !important;
    border-color: var(--mui-outline) !important;
}

.b-richtextedit .ql-snow .ql-tooltip a,
.b-richtextedit .ql-snow a {
    color: var(--mui-primary) !important;
}

.b-richtextedit .ql-snow .ql-tooltip a.ql-action::after {
    border-right-color: var(--mui-outline-variant) !important;
}

/* The swatch outline in the colour picker, which has to read against whichever
   colour is in the swatch rather than against the surface. */
.b-richtextedit .ql-toolbar.ql-snow .ql-color-picker .ql-picker-item.ql-selected,
.b-richtextedit .ql-toolbar.ql-snow .ql-color-picker .ql-picker-item:hover {
    border-color: var(--mui-on-surface) !important;
}

/* Content that quill styles on the author's behalf rather than the author
   choosing: the placeholder, list markers, quotes, inline code and table rules. */
.b-richtextedit .ql-editor.ql-blank::before {
    color: var(--mui-on-surface-variant) !important;
}

.b-richtextedit .ql-editor li[data-list=checked] > .ql-ui,
.b-richtextedit .ql-editor li[data-list=unchecked] > .ql-ui {
    color: var(--mui-on-surface-variant) !important;
}

.b-richtextedit .ql-snow .ql-editor blockquote {
    border-left-color: var(--mui-outline-variant) !important;
}

.b-richtextedit .ql-snow .ql-editor code {
    background-color: var(--mui-surface-container-high) !important;
}

.b-richtextedit .ql-editor td {
    border-color: var(--mui-outline) !important;
}

/* ----------------------------------------------------------------------------
   Svg charts.
   The chart draws its labels, ticks and legend at a fixed #333333, which is
   nearly the dark surface itself. Colouring the text here rather than through
   the chart's own font option is what lets it follow the theme: the option is
   set from C#, which cannot know which theme the browser is in.

   A css declaration outranks an svg presentation attribute, and !important
   covers the case where the chart writes an inline style instead. The series
   keep their own colours - those distinguish one line from another and are not
   the theme's to decide.
   ---------------------------------------------------------------------------- */

.bz-chart text {
    fill: var(--mui-on-surface) !important;
}

/* The tile's own surface, which the transparent placeholder glyph sits on when a
   project has no picture of its own. A real picture covers it. */
.bz-tile {
    background-color: var(--mui-surface-container-highest);
}

/* ----------------------------------------------------------------------------
   Tile captions, over each tile's own picture. Mixed from the surface rather
   than carried as a colour of its own, so it follows the theme with no token to
   switch, and stays opaque enough for the ink to read over any photograph.
   ---------------------------------------------------------------------------- */

.bz-tile-caption {
    background: color-mix(in srgb, var(--mui-surface-container) 88%, transparent);
    color: var(--mui-on-surface);
}

/* ----------------------------------------------------------------------------
   The home page's marketing carousel, one height whichever slide is showing.
   The carousel already stacks its slides in one place - each floats with a
   negative margin over the one before - but it takes the ones not showing out
   of the layout with display: none, so the panel was as tall as the current
   slide and the page below it moved every time a slide with more or less copy
   came round. Keeping them all in the layout makes the tallest one decide.
   Hidden rather than merely faded out, so a slide nobody can see cannot be
   clicked, tabbed into or read aloud; the ones the carousel is moving between
   stay visible, which is what keeps the crossfade.
   ---------------------------------------------------------------------------- */

.bz-marketing .mui-carousel > .mui-carousel-slides > .mui-carousel-slide {
    display: block;
    visibility: hidden;
}

.bz-marketing .mui-carousel > .mui-carousel-slides > .mui-carousel-slide:is(.mui-carousel-slide-active, .mui-carousel-slide-next, .mui-carousel-slide-prev) {
    visibility: visible;
}

/* ----------------------------------------------------------------------------
   The unread dot, wherever one is shown: beside a project in the sidebar, on a
   project tile, on a presentation that has moved on. One mark, so it is read as
   one thing.

   The ring is what lets it sit on a photograph, and it is the ink colour rather
   than a light or a dark of its own - which makes it dark on a light theme and
   light on a dark one with no token to switch and nothing to keep in step.

   Sized here rather than on the component, because a width given in markup is
   written as an inline style and would win against this rule. A tile has room
   for the larger one; a dot beside a line of text does not.
   ---------------------------------------------------------------------------- */

.bz-unread-dot {
    width: 14px;
    height: 14px;
    padding: 0;
    border: 2px solid var(--mui-on-surface);
}

.bz-unread-dot.bz-unread-dot-lg {
    width: 20px;
    height: 20px;
}

/* ============================================================================
   Component corrections
   ============================================================================ */

/* The bar's own colours.
   The provider only ever emits a contrast class for Dark, and that one is tied
   to the "dark" colour variant rather than to the surface - its light-bar rule
   is not reachable from ThemeContrast at all. A bar left without a contrast
   class sets none of these itself, so they are set here instead, from the
   surface tokens, which is what the provider's own light rule does and what
   makes the bar follow the theme. Only the selected item differs from that
   rule: the provider marks it with the secondary colour, the brand reads
   better. */
.mui-bar {
    --mui-bar-drawer-width: var(--b-vertical-bar-width);
    --mui-bar-bg: var(--mui-surface-container-low);
    --mui-bar-menu-bg: var(--mui-surface-container);
    --mui-bar-color: var(--mui-on-surface);
    --mui-bar-muted-color: var(--mui-on-surface-variant);
    --mui-bar-outline: var(--mui-outline-variant);
    --mui-bar-hover-bg: color-mix(in srgb, var(--mui-on-surface) 10%, transparent);
    --mui-bar-active-bg: color-mix(in srgb, var(--mui-primary) 22%, transparent);
    --mui-bar-active-color: var(--mui-on-surface);
}

.mui-bar-dropdown-item > span {
    min-width: 0;
}

.mui-chip {
    --mui-chip-padding: unset;
    --mui-chip-size: unset;
    --mui-chip-close-size: unset;
}

.mui-button:hover:not(:active):not(.mui-button-active) {
    background-size: unset;
}

.mui-table,
.mui-table-responsive {
    --mui-surface-container-lowest: transparent;
}

.b-richtextedit > .b-richtextedit-editor.ql-container {
    height: 100%;
}

.mui-heading-6 {
    font-size: 1.25rem;
}
