:root {
    --action-text: var(--text-primary);
    --action-text-active: var(--text-primary);
    --action-text-hover: var(--text-primary);
    --action-text-disabled: var(--text-disabled);
    --action-border: var(--divider);
    --action-border-active: var(--divider);
    --action-border-hover: var(--primary-main);
    --action-border-disabled: var(--divider);
    --action-background: var(--background-default);
    --action-background-active: var(--background-secondary);
    --action-background-hover: var(--background-hover);
    --action-background-disabled: var(--background-disabled);
    --action-shadow: none;
    --action-shadow-active: none;
    --action-shadow-hover: none;
    --action-shadow-disabled: none;
    --action-transition: var(--transition-style);
}

html {
    background-color: var(--background-default);
    color: var(--text-primary);
}

/* Color half of the global :focus-visible backstop (structure in
   tokens.css). */
:focus-visible {
    outline-color: var(--primary-main);
}

a {
    color: var(--primary-link);
    text-decoration: none;
    transition: var(--transition-style);
}

a:visited {
    /* --primary-link (not --primary-dark): the pale schemes' --primary-dark is
       still too light for AA on white. */
    color: var(--primary-link);
    transition: var(--transition-style);
}

a:hover {
    color: var(--secondary-main);
    transition: var(--transition-style);
}

a:active {
    color: var(--secondary-dark);
    transition: var(--transition-style);
}

/* Login card sits on --primary-dark; the global link color is illegible there
   in schemes where --primary-link is close to --primary-dark. */
.login-copyright a {
    color: var(--primary-contrastText);
}

/* The sign-in page: its button takes the brand band's roles and its card sits on
   a dimmed page. :where() keeps each rule no heavier than the bare selector it
   scopes, so it outranks exactly what it would unscoped. Structure in features.css. */
:root:where(.login-splash) {
    --action-text: var(--primary-contrastText);
    --action-text-active: var(--primary-contrastText);
    --action-text-hover: var(--primary-contrastText);
    --action-background: var(--primary-dark);
    --action-background-active: var(--primary-main);
    --action-background-hover: var(--primary-main);
}

html:where(.login-splash) {
    background-color: rgba(0, 0, 0, 0.5);
}

:where(.login-splash) main section {
    background-color: var(--primary-dark);
    color: var(--primary-contrastText);
    box-shadow: var(--shadow-3);
}

/* Mobile top app bar + drawer scrim. */
.mobile-bar {
    background-color: var(--background-secondary);
    color: var(--text-primary);
    box-shadow: var(--shadow-2);
}

.nav-scrim {
    background-color: rgba(0, 0, 0, 0.45);
}

/* Org brand zone: the org colour scheme's --primary-dark. */
nav.main-nav .nav-org {
    background-color: var(--primary-dark);
    color: var(--primary-contrastText);
}

nav.main-nav .nav-org-name {
    color: var(--primary-contrastText);
}

/* App tabs: muted by default; the current app gets the brand accent. */
nav.main-nav .nav-apptab {
    color: var(--text-secondary);
}

nav.main-nav .nav-apptab:hover {
    background-color: var(--background-hover);
}

/* Active app tab: the brand accent as a tint background + legible brand text,
   the same tinted-selection pattern used for the active nav item and site,
   legible across all 16 schemes incl. the pale ones. */
nav.main-nav .nav-apptab.active {
    background-color: var(--primary-tint);
    color: var(--primary-tint-text);
}

/* Identity/tab-zone and season-chooser band dividers. Width/style are set
   explicitly in features.css; these name the colour. */
nav.main-nav .nav-identity,
nav.main-nav .season-chooser {
    border-bottom-color: var(--divider);
}

/* Season picker reads as a nav row: muted glyphs + season name + the same hover
   wash as `menu li:hover`. */
nav.main-nav .season-chooser .season-chooser-icon,
nav.main-nav .season-chooser .season-chooser-caret,
nav.main-nav .season-chooser select {
    color: var(--text-secondary);
}

/* macOS Chromium/WebKit paint a native <select>'s text via -webkit-text-fill-color,
   which wins over `color` — without this the season name stays the default black. */
nav.main-nav .season-chooser select {
    -webkit-text-fill-color: var(--text-secondary);
}

nav.main-nav .season-chooser:hover {
    background-color: var(--background-tablerow);
}

/* Drag-to-resize handle: invisible until hovered/focused, then a brand-tint
   grab strip. */
nav.main-nav .nav-resize-handle:hover,
nav.main-nav .nav-resize-handle:focus-visible {
    background-color: var(--primary-tint);
}

/* Personal band divider. */
nav.main-nav menu.nav-personal {
    border-top-color: var(--divider);
}

/* User anchor + attached upward menu. No top divider here — the personal
   band above already carries one. */
nav.main-nav .profile-anchor {
    color: var(--text-primary);
}

nav.main-nav .profile-anchor:hover {
    background-color: var(--background-hover);
}

div.profile-menu .menu {
    background-color: var(--background-default);
    border-color: var(--divider);
    box-shadow: var(--shadow-6);
    color: var(--text-primary);
}

div.profile-menu .menu a:hover,
div.profile-menu .menu button.about-open:hover {
    background-color: var(--background-hover);
}

div.profile-menu .menu-debug {
    border-top-color: var(--divider);
    color: var(--text-secondary);
}

div.profile-menu .about-dialog {
    background-color: var(--background-default);
    border-color: var(--divider);
    color: var(--text-primary);
}

/* Product wordmark foot. */
nav.main-nav .nav-wordmark {
    color: var(--text-secondary);
}

/* --text-disabled composites to 3.34:1 on this nav's background — fails
   1.4.3. This label isn't a disabled control, so --text-secondary (4.74:1
   here) is the semantically correct token, not just a darker one. */
nav.main-nav .nav-wordmark-build {
    color: var(--text-secondary);
}

nav.main-nav {
    background-color: var(--background-secondary);
    color: var(--text-secondary);
    box-shadow: var(--shadow-1);

    /* Section heading labels + the hairline that separates groups. */
    menu li > span.nav-heading {
        color: var(--text-secondary);
    }

    menu li:has(> span.nav-heading):not(:first-child) {
        border-top-color: var(--divider);
    }

    /* Active nav item (current page): brand tint. Site groups keep their own
       left-stripe accent (below), so they're excluded. The higher specificity
       beats menu li:hover, so the active row stays tinted. */
    menu li.active:not(.site) {
        background-color: var(--primary-tint);
    }

    menu li.active:not(.site) > a {
        color: var(--primary-tint-text);
    }

    menu li:hover {
        background-color: var(--background-tablerow);
    }

    /* Empty-state / creation CTA inside a nav section. Same row shape as
       regular items; the secondary accent + visible
       plus glyph (regular items render an empty fa-solid placeholder)
       carries the "create" intent without an extra button shape. */
    menu li.cta-menu-link a.cta-link,
    menu li.cta-menu-link a.cta-link:visited {
        color: var(--secondary-main);
    }

    menu li.cta-menu-link a.cta-link:hover {
        color: var(--secondary-dark);
    }

    /* Site group active-site accent: a full-height left-edge stripe plus a
       brand-coloured name + globe mark the open site. The single-open
       accordion adds .active client-side. */
    menu li.site.active {
        box-shadow: inset 3px 0 0 0 var(--primary-main);
    }

    menu li.site.active > .siteheading {
        color: var(--primary-tint-text);
    }

    menu li.site.active > .siteheading i {
        color: var(--primary-main);
    }
}

main {
    table {
        border-color: var(--divider);

        th {
            border-bottom-color: var(--divider);
        }

        tbody td {
            border-bottom-color: var(--divider);
        }

        tbody tr:hover {
            background-color: var(--background-tablerow);
        }
    }

    .accordion {
        border-color: var(--divider);

        .accordion-content {
            border-color: var(--divider);
        }
    }

    aside.ensembleHomeQuickLinks {
        background-color: var(--background-default);
        color: var(--text-secondary);
        border-color: var(--divider);
    }
}

/* Standalone page bar (error / login-failure): the same brand zone the app
   shell's nav identity band uses, so the chrome reads as the same product. */
.standalone-bar {
    background-color: var(--primary-dark);
    color: var(--primary-contrastText);
    box-shadow: var(--shadow-2);
}

/* The org zone is a link sitting on the brand background, where the global
   link/:visited/:hover colours are illegible — outrank all three. */
.standalone-bar a.standalone-bar-org,
.standalone-bar a.standalone-bar-org:visited,
.standalone-bar a.standalone-bar-org:hover {
    color: var(--primary-contrastText);
}

footer {
    background-color: var(--background-default);
}

a.button,
span.button,
button,
input:not([type="file"]),
div.binary-file,
div.binary-attr-image,
textarea,
label.htmlEditor div.editorHolder,
label.htmlEditor div.htmlEditor-readonly-value {
    color: var(--action-text);
    -webkit-text-fill-color: var(--action-text); /* Safari: ensure text color applies */
    border-color: var(--action-border);
    background-color: var(--action-background);
    box-shadow: var(--action-shadow);

    transition: var(--action-transition);

    &:active,
    &:focus {
        color: var(--action-text-active);
        -webkit-text-fill-color: var(--action-text-active); /* Safari */
        border-color: var(--action-border-active);
        background-color: var(--action-background-active);
        box-shadow: var(--action-shadow-active);
    }

    &:hover {
        color: var(--action-text-hover);
        -webkit-text-fill-color: var(--action-text-hover); /* Safari */
        border-color: var(--action-border-hover);
        background-color: var(--action-background-hover);
        box-shadow: var(--action-shadow-hover);
    }
}

/* Disabled state for form inputs (not buttons - those are styled separately) */
input:not([type="file"]):disabled,
div.binary-file,
div.binary-attr-image,
textarea:disabled,
select:disabled {
    color: var(--action-text-disabled);
    -webkit-text-fill-color: var(--action-text-disabled);
    border-color: var(--action-border-disabled);
    background-color: var(--action-background-disabled);
    box-shadow: var(--action-shadow-disabled);
}

.season-banner-switch {
    color: var(--primary-link);
    -webkit-text-fill-color: var(--primary-link);
}
.season-banner-switch:hover {
    color: var(--secondary-main);
    -webkit-text-fill-color: var(--secondary-main);
}

/* Copy-link buttons inside the binary-file editor read as inline link
   affordances, not form actions — strip the action background/border so
   they sit cleanly alongside the Download / Stream anchors, and pick up
   the same anchor colour so the row reads as a unified group.

   Must also reset -webkit-text-fill-color, since the global `button`
   rule above sets it to --action-text — and on WebKit it wins over
   `color` for text/icon-font rendering. */
.binary-file-download .button-icon[data-copy-url] {
    background: transparent;
    border-color: transparent;
    box-shadow: none;
    color: var(--primary-main);
    -webkit-text-fill-color: var(--primary-main);
}
.binary-file-download .button-icon[data-copy-url]:hover {
    background: transparent;
    border-color: transparent;
    box-shadow: none;
    color: var(--primary-dark);
    -webkit-text-fill-color: var(--primary-dark);
}

/* Icon buttons: muted glyphs that lift on hover. Must also reset
   -webkit-text-fill-color since the global button action rule sets it and
   WebKit prefers it over `color`. The -danger flavour (remove/favourite)
   lifts to the error color; .is-favourited holds it. */
.icon-button,
a.icon-button:visited {
    background: transparent;
    border-color: transparent;
    box-shadow: none;
    color: var(--text-secondary);
    -webkit-text-fill-color: var(--text-secondary);
}

.icon-button:hover {
    background: transparent;
    border-color: transparent;
    box-shadow: none;
    color: var(--text-primary);
    -webkit-text-fill-color: var(--text-primary);
}

.icon-button-danger:hover,
.icon-button-danger.is-favourited {
    color: var(--error-main);
    -webkit-text-fill-color: var(--error-main);
}

/* Rich text editor readonly/disabled state - divs don't support :disabled pseudo-class */
label.htmlEditor div.htmlEditor-readonly-value {
    color: var(--action-text-disabled);
    -webkit-text-fill-color: var(--action-text-disabled);
    border-color: var(--action-border-disabled);
    background-color: var(--action-background-disabled);
    box-shadow: var(--action-shadow-disabled);
}

/* Ensure listbox/dropdown items inherit the intended color in Safari */
select {
    box-shadow: var(--action-shadow);
    border-color: var(--action-border);

    &:active,
    &:focus {
        border-color: var(--action-border-active);
        box-shadow: var(--action-shadow-active);
    }

    &:hover {
        border-color: var(--action-border-hover);
        box-shadow: var(--action-shadow-hover);
    }

    &:disabled {
        border-color: var(--action-border-disabled);
        box-shadow: var(--action-shadow-disabled);
    }
}

select {

    color: var(--action-text);
    -webkit-text-fill-color: var(--action-text); /* Safari: ensure text color applies */
    background-color: var(--action-background);

    transition: var(--action-transition);

    &:active,
    &:active option,
    &:active optgroup,
    &:focus {
        color: var(--action-text-active);
        -webkit-text-fill-color: var(--action-text-active); /* Safari */
        background-color: var(--action-background-active);
    }

    &:hover,
    &:hover option,
    &:hover option:checked,
    &:hover optgroup {
        color: var(--action-text-hover);
        -webkit-text-fill-color: var(--action-text-hover); /* Safari */
        background-color: var(--action-background-hover);
    }

    &:disabled,
    &:disabled option,
    &:disabled optgroup {
        color: var(--action-text-disabled);
        -webkit-text-fill-color: var(--action-text-disabled); /* Safari */
        background-color: var(--action-background-disabled);
    }
}

button,
span.button,
a.button,
a:visited.button {
    border-color: transparent;
    box-shadow: none;

    &:hover:not(:disabled) {
        border-color: transparent;
        background-color: var(--action-background-hover);
        box-shadow: none;
    }

    &.primary {
        color: var(--primary-contrastText);
        -webkit-text-fill-color: var(--primary-contrastText);
        background-color: var(--primary-main);

        &:hover:not(:disabled) {
            background-color: var(--primary-dark);
        }
    }

    &.secondary {
        color: var(--secondary-contrastText);
        -webkit-text-fill-color: var(--secondary-contrastText);
        background-color: var(--secondary-main);

        &:hover:not(:disabled) {
            background-color: var(--secondary-dark);
        }
    }

    /* Semantic action buttons are OUTLINED, not solid-filled. Solid fill is
       reserved for the brand primary/secondary, so a destructive
       button never reads as the brand primary — critical for warm/red schemes
       where a solid --error-main button is indistinguishable from a solid
       --primary-main one. Colour identity stays via the border + legible -dark
       text; hover fills solid to confirm the action. Border width/style come
       from the button base (components.css); only colour lives here. */
    &.error {
        color: var(--error-dark);
        -webkit-text-fill-color: var(--error-dark);
        background-color: transparent;
        border-color: var(--error-main);

        &:hover:not(:disabled) {
            background-color: var(--error-main);
            color: var(--error-contrastText);
            -webkit-text-fill-color: var(--error-contrastText);
        }
    }

    &.warning {
        color: var(--warning-dark);
        -webkit-text-fill-color: var(--warning-dark);
        background-color: transparent;
        border-color: var(--warning-main);

        &:hover:not(:disabled) {
            background-color: var(--warning-main);
            color: var(--warning-contrastText);
            -webkit-text-fill-color: var(--warning-contrastText);
        }
    }

    &.info {
        color: var(--info-dark);
        -webkit-text-fill-color: var(--info-dark);
        background-color: transparent;
        border-color: var(--info-main);

        &:hover:not(:disabled) {
            background-color: var(--info-main);
            color: var(--info-contrastText);
            -webkit-text-fill-color: var(--info-contrastText);
        }
    }

    &.success {
        color: var(--success-dark);
        -webkit-text-fill-color: var(--success-dark);
        background-color: transparent;
        border-color: var(--success-main);

        &:hover:not(:disabled) {
            background-color: var(--success-main);
            color: var(--success-contrastText);
            -webkit-text-fill-color: var(--success-contrastText);
        }
    }

    /* The neutral outlined variant. The default button is a filled surface with a
       transparent border, which reads as "nothing" on a surface of the same colour
       and as "disabled" beside a greyed one — both of which happen in the
       registration inspect action area, where the whole action set is drawn on a
       panel and the inapplicable half is disabled. This one keeps the surface and
       spends a divider-coloured border and link-coloured text on saying it is a
       control, without claiming any of the four semantic meanings. */
    &.outline {
        color: var(--primary-link);
        -webkit-text-fill-color: var(--primary-link);
        background-color: transparent;
        border-color: var(--divider);

        &:hover:not(:disabled) {
            background-color: var(--action-background-hover);
            border-color: var(--action-border-hover);
        }
    }

    /* Disabled state - must come after color classes to override them.
       :not(.selected) so a selected-but-disabled segment (a committed toggle
       answer) keeps its selected accent instead of greying out. */
    &:disabled:not(.selected),
    &:disabled:hover:not(.selected) {
        color: var(--action-text-disabled);
        -webkit-text-fill-color: var(--action-text-disabled);
        background-color: var(--action-background-disabled);
        border-color: transparent;
        box-shadow: none;
    }
}

.rte-toolbar {
    background-color: var(--action-background-disabled);

    section {
        border-right-color: var(--divider);
    }

    span.rte-btn {
        color: var(--action-text);
        transition: var(--action-transition);

        &:active,
        &:focus,
        &.enabled {
            color: var(--action-text-active);
        }

        &:hover {
            color: var(--action-text-hover);
            border-color: var(--action-border-hover);
            background-color: var(--action-background-hover);
            box-shadow: var(--action-shadow-hover);
        }

        &:disabled,
        &.disabled {
            color: var(--action-text-disabled);
            border-color: var(--action-border-disabled);
            background-color: var(--action-background-active); /* same */
            box-shadow: var(--action-shadow-disabled);
        }
    }
}

span.label-text {
    background-color: var(--background-secondary);
    color: var(--text-secondary);
    border-color: var(--background-secondary);
    box-shadow: none;

    span.required {
        color: var(--error-dark);
    }
}

fieldset {
    border-color: var(--action-border);
    background-color: var(--action-background);

    legend {
        background-color: var(--background-secondary);
        color: var(--text-secondary);
        border-color: var(--background-secondary);
    }
}

div.help-text {
    color: var(--text-secondary);
}

/* Section cards in a .form-sheet: a hairline-bordered surface on the page,
   matching the system's hairline-first elevation (border, no shadow). */
.form-sheet .form-section {
    border-color: var(--divider);
    background-color: var(--background-default);
}

input[type=checkbox] {
    &:after {
        background-color: var(--error-light);
        color: var(--error-contrastText);

    }

    &:checked:after {
        background-color: var(--success-light);
        color: var(--error-contrastText);

    }
}

section.alert {
    /* Toast treatment: a neutral surface card carries the message; the severity reads
       through a coloured left edge, the icon, and the countdown bar — not a full fill.
       Colour binds to tokens so dark mode flips for free. */
    background-color: var(--background-default);
    color: var(--text-secondary);
    box-shadow: var(--shadow-toast);

    .heading .title {
        color: var(--text-primary);
    }

    .heading a {
        color: var(--text-secondary);
        opacity: 0.55;

        &:hover {
            opacity: 1;
            color: var(--text-primary);
        }
    }

    &.alert-info {
        border-left-color: var(--info-main);

        .heading .icon { color: var(--info-main); }
        &::after { background-color: var(--info-main); }
    }

    &.alert-success {
        border-left-color: var(--success-main);

        .heading .icon { color: var(--success-main); }
        &::after { background-color: var(--success-main); }
    }

    &.alert-warning {
        border-left-color: var(--warning-main);

        .heading .icon { color: var(--warning-main); }
        &::after { background-color: var(--warning-main); }
    }

    &.alert-error {
        border-left-color: var(--error-main);

        .heading .icon { color: var(--error-main); }
        &::after { background-color: var(--error-main); }
    }

    /* Light alert variants - subtle backgrounds with borders */
    &.alert-info-light {
        background-color: color-mix(in srgb, var(--info-main), transparent 90%);
        border: 1px solid var(--info-main);
        color: var(--text-primary);

        .heading .icon { color: var(--info-main); }
        .heading .title { color: var(--info-dark); }
    }

    &.alert-success-light {
        background-color: color-mix(in srgb, var(--success-main), transparent 90%);
        border: 1px solid var(--success-main);
        color: var(--text-primary);

        .heading .icon { color: var(--success-main); }
        .heading .title { color: var(--success-dark); }
    }

    &.alert-warning-light {
        background-color: color-mix(in srgb, var(--warning-main), transparent 90%);
        border: 1px solid var(--warning-main);
        color: var(--text-primary);

        .heading .icon { color: var(--warning-main); }
        .heading .title { color: var(--warning-dark); }
    }

    &.alert-error-light {
        background-color: color-mix(in srgb, var(--error-main), transparent 90%);
        border: 1px solid var(--error-main);
        color: var(--text-primary);

        .heading .icon { color: var(--error-main); }
        .heading .title { color: var(--error-dark); }
    }
}


/* ****************************** RANDOM THINGS ****************************** */

.render-attributes {
    label {
        .name {
            color: var(--text-secondary);
        }
    }
}

.avatar-samples {
    img {
        border-color: var(--divider);
        background-color: var(--background-secondary);
    }
}

.spinner {
    border-color: var(--grey-400);
    background: linear-gradient(var(--secondary-light), var(--secondary-main), var(--secondary-dark));
    box-shadow: var(--shadow-1);
}

.spinner::before {
    background-color: var(--primary-dark);
    border-color: var(--grey-400);
    box-shadow: inset 0 0 10px -7px hsla(0, 0%, 100%, 0.075);
}

/* In-button spinner ring (structure in components.css). Default: dark ring for
   light buttons; brand-filled primary buttons get the contrast colour. */
button.htmx-request::after,
button.htmx-retrying::after,
form.htmx-request button[type="submit"]::after,
form.htmx-retrying button[type="submit"]::after,
form.htmx-request button:not([type])::after,
form.htmx-retrying button:not([type])::after {
    border-color: var(--primary-main);
    border-right-color: transparent;
}

.button.primary.htmx-request::after,
.button.primary.htmx-retrying::after,
form.htmx-request .button.primary[type="submit"]::after,
form.htmx-retrying .button.primary[type="submit"]::after {
    border-color: var(--primary-contrastText);
    border-right-color: transparent;
}

#htmx-progress::after {
    background-color: var(--primary-main);
}

.yes {
    color: var(--success-main);
}

.no {
    color: var(--error-main);
}

.attendance-expected-yes {
    color: var(--success-main);
}

.attendance-expected-no {
    color: var(--error-main);
}

/* --warning-main is 3.11:1 here — fails 1.4.3 on a status colour that
   carries meaning (RSVP). --warning-text (5.39:1 on white, 4.86:1 on the
   hovered table-row background this renders inside) is the AA-safe variant
   of the same swatch, checked against every surface it sits on, not just
   the resting-state background. */
.attendance-expected-maybe {
    color: var(--warning-text);
}

/* Performer Programme buckets reuse the Expected Attendance status palette,
   tinting the instrument and musician names (headings stay default). */
[data-programme-section="attending"] [data-programme-instrument-name],
[data-programme-section="attending"] [data-programme-name] {
    color: var(--success-main);
}

[data-programme-section="notAttending"] [data-programme-instrument-name],
[data-programme-section="notAttending"] [data-programme-name] {
    color: var(--error-main);
}

[data-programme-section="unconfirmed"] [data-programme-instrument-name],
[data-programme-section="unconfirmed"] [data-programme-name] {
    color: var(--warning-main);
}

/* Recorded-attendance "Present"/"Absent" locked answers: a soft success/error
   tint rather than a solid fill, matching the badge tint recipe so the dense
   attendance grid stays calm. Still unmistakably green/red.
   !important overrides the base disabled-button greying. */
button {
    &:disabled {
        &.attendance-actual-yes {
            background-color: color-mix(in srgb, var(--success-main), transparent 85%) !important;
            color: var(--success-dark) !important;
        }

        &.attendance-actual-no {
            background-color: color-mix(in srgb, var(--error-main), transparent 85%) !important;
            color: var(--error-dark) !important;
        }
    }
}

table.season-events {
    tr.past {
        color: var(--text-secondary);
    }
}

/* Mobile card layout (features.css): the card outline, and the eyebrow and
   control labels that replace the hidden table header, all read as metadata. */
@media screen and (max-width: 768px) {
    table.season-events tbody tr {
        border-color: var(--divider);
    }

    table.season-events tbody td:nth-last-child(4),
    table.season-events tbody td[data-label]::before {
        color: var(--text-secondary);
    }
}

/* Outbox mobile card layout (features.css): the card outline and the cell labels
   that replace the hidden table header, which read as metadata. */
@media screen and (max-width: 768px) {
    #outbox-pane tbody tr:not(.pagination-sentinel) {
        border-color: var(--divider);
    }

    #outbox-pane tbody td[data-label]::before {
        color: var(--text-secondary);
    }
}

.pill.attendance-not-tracked {
    display: inline-block;
    padding: 0.15rem 0.6rem;
    border-radius: var(--radius-pill);
    background-color: var(--background-secondary);
    color: var(--text-secondary);
    font-size: 0.85em;
    font-style: italic;
}

.text-disabled {
    color: var(--text-disabled);
}

/* Attendance grid: sticky cells need opaque backgrounds so scrolled content
   does not show through; mark and tally colours follow the
   present/absent/not-recorded semantics. */
.attendance-grid th,
.attendance-grid td {
    background-color: var(--background-default);
}

.attendance-grid thead th,
.attendance-grid tfoot th,
.attendance-grid tfoot td {
    background-color: var(--background-tablerow);
}

/* The roles-and-permissions matrices' sticky header cells need an opaque fill
   too, same reason as the attendance grid's. */
.help-matrix-scroll thead th {
    background-color: var(--background-tablerow);
}

.attendance-grid .att-instrument,
.attendance-grid .att-instrument-fill {
    background-color: var(--background-field);
}

.attendance-grid .att-present,
.att-tally-present {
    color: var(--success-main);
}

.attendance-grid .att-absent,
.att-tally-absent {
    color: var(--error-main);
}

.attendance-grid .att-none {
    color: var(--text-disabled);
}

.att-tally-none {
    color: var(--text-secondary);
}

code {
    background-color: var(--code-background);
    color: var(--code-text);
}

.tooltip {
    .tooltiptext {
        background-color: #555;
        color: var(--white);
    }

    .tooltiptext::after {
        border-color: #555 transparent transparent transparent;
    }
}

section.dues-summary,
section.dues-form {
    section.dues-payment {
        background-color: var(--background-secondary);
        color: var(--text-secondary);
    }
}

/* Stacked rows draw their own rule; the tiles take a tint to read as one strip. */
@media screen and (max-width: 768px) {
    .registrationProfileTable tbody tr {
        border-bottom-color: var(--divider);
    }

    .registrationProfileTable td.reg-tbl-pid,
    .registrationProfileTable td.reg {
        color: var(--text-secondary);
    }

    .registrationProfileTable td.reg {
        background-color: var(--background-tablerow);
    }
}

/* The inspect screen's action area (layout in features.css). */
.reg-action-area {
    border-color: var(--divider);
    background-color: var(--background-default);
}

.reg-action-group + .reg-action-group {
    border-left-color: var(--divider);
    border-top-color: var(--divider);
}

.reg-action-label {
    color: var(--text-secondary);
}

/* "This season asked nothing" in a completeness cell — quieter than the yes/no glyphs beside it,
   because it is the absence of a question rather than an answer to one. */
.reg-not-asked {
    color: var(--text-disabled);
}

.registrationProfileTable {
    .reg-tbl-started {
        border-left-color: var(--divider);
    }

    .reg-tbl-alumni,
    .reg-tbl-actions,
    .reg-tbl-first-aid {
        border-right-color: var(--divider);
    }

    /* The open row is attributed while its menu floats in the top layer: the panel
       covers whatever sits under it, so the row it acts on has to be findable
       without it. Keyed off the panel's own open marker, so nothing else has to
       be kept in step.

       The row wears both marks, never the cells. At phone width the row is a flex
       container of block cells with gaps between them, so a per-cell fill draws a
       box around each cell's own text rather than banding the row — and the edge
       lands beside whichever cell the DOM happens to put first, not at the row's
       start. The tinted completeness tiles keep their own fill either way. */
    tbody tr:has(ul.registrationCommandOptions:not(.gone)) {
        background-color: var(--primary-tint);
        box-shadow: inset var(--space-xs) 0 0 0 var(--primary-main);

        .openMenu {
            color: var(--primary-main);
            -webkit-text-fill-color: var(--primary-main);
        }
    }

    .registrationCommandButtons {
        /* The pointer wears the panel's own edge. */
        .openMenu::after {
            background-color: var(--background-secondary);
            border-color: var(--divider);
        }

        ul.registrationCommandOptions {
            background-color: var(--background-secondary);
            border-color: var(--divider);

            li {
                a.error, a:hover.error, a:visited.error {
                    color: var(--error-main);
                }
            }

            .reg-command-item a:hover {
                background-color: var(--background-hover);
            }

            li.closeMenu {
                border-color: var(--divider);

                a:hover {
                    color: var(--action-text-hover);
                }

                a,
                a:visited {
                    color: var(--action-text);
                }
            }
        }
    }
}

.favourited i.fa-heart,
button.favourited i.fa-heart {
    color: var(--error-main);
    -webkit-text-fill-color: var(--error-main);
}

.favourited:hover:not(:disabled) i.fa-heart,
button.favourited:hover:not(:disabled) i.fa-heart {
    color: var(--error-main);
    -webkit-text-fill-color: var(--error-main);
}

/* Webmail */
.webmail {
    border-color: var(--divider);
}

.webmail-folders {
    background-color: var(--background-secondary);
    border-right-color: var(--divider);
}

.webmail-folder {
    background-color: transparent;

    &:hover {
        background-color: var(--action-background-hover);
    }

    &.active {
        background-color: var(--primary-light);
        color: var(--primary-dark);
    }
}

.webmail-content {
    background-color: var(--background-default);
}

.webmail-empty {
    color: var(--text-secondary);
}

.message-row {
    border-bottom-color: var(--divider);

    &:hover {
        background-color: var(--action-background-hover);
    }
}

.message-row-icon {
    background-color: var(--background-secondary);
    color: var(--text-secondary);
}

.message-row-date {
    color: var(--text-secondary);
}

.message-row-subject {
    color: var(--text-secondary);
}

.message-view-toolbar {
    border-bottom-color: var(--divider);
    background-color: var(--background-secondary);
}

.message-view-header {
    border-bottom-color: var(--divider);
}

.message-view-meta {
    color: var(--text-secondary);

    strong {
        color: var(--text-primary);
    }
}

/* Per-message color-scheme toggle — structure in components.css. Strips the
   global button action chrome down to a quiet outlined pill that lifts on
   hover. */
.message-view-toolbar .message-color-scheme-toggle {
    background: transparent;
    color: var(--text-secondary);
    border-color: var(--divider);
}

.message-view-toolbar .message-color-scheme-toggle:hover {
    background-color: var(--background-hover);
    color: var(--text-primary);
}

/* Merged Communications page — structure in features.css. */
.compose-menu-item {
    color: var(--text-primary);

    &:hover {
        background-color: var(--action-background-hover);
    }
}

.compose-menu-hint {
    color: var(--text-secondary);
}

.webmail-folder-divider {
    border-top-color: var(--divider);
    color: var(--text-secondary);
}

/* The unread dot is the row's only accent, so it takes the primary colour;
   read rows hide it and keep its width. */
.message-row-unread {
    background-color: var(--primary-main);
}

.message-row-recipients {
    color: var(--text-secondary);
}

.webmail-scope-note {
    background-color: var(--background-secondary);
    color: var(--text-secondary);
}

/*
 * .message-view-body intentionally has no fixed background so the
 * surrounding webmail-content area picks up the active mode's
 * --background-default. The iframe inside (when reading sent emails)
 * loads a self-contained HTML document whose inline styles set their
 * own colours — that part can't be themed from the parent.
 */

@media screen and (max-width: 768px) {
    .webmail-folders {
        border-bottom-color: var(--divider);
    }

    /* The section label is a vertical rule on the folder strip. */
    .webmail-folder-divider {
        border-left-color: var(--divider);
    }
}

.roster-pending,
.rosterDisplay .pending {
    color: var(--action-text-disabled);
}

.roster-section-title {
    border-bottom-color: var(--divider);
}

/* Roster card detail block + subtitle read as quiet metadata. */
.roster-card-subtitle,
.roster-card-meta {
    color: var(--text-secondary);
}
.roster-card-meta {
    border-top-color: var(--divider);
}
.roster-card-meta-row i {
    color: var(--text-disabled);
}

.my-section {
    .profileDisplay {
        border-color: var(--divider);
    }
}

/* Card Component */
.card {
    background-color: var(--background-default);
    border-color: var(--divider);
}

.card-header {
    border-bottom-color: var(--divider);
}

/* Tinted tile + full-strength glyph (the badge tint recipe): primary-dark
   on primary-light read as blue-on-blue in most schemes. */
.card-icon {
    background-color: color-mix(in srgb, var(--primary-main), transparent 85%);
    color: var(--primary-main);
}

/* Chip Component — interactive states key off the element (a/button/label);
   span chips are static surfaces. */
.chip {
    background-color: var(--background-secondary);
    border-color: var(--divider);
    color: var(--text-primary);
}

.chip:visited {
    color: var(--text-primary);
}

a.chip:hover, button.chip:hover, label.chip:hover {
    background-color: var(--primary-light);
    border-color: var(--primary-main);
    color: var(--primary-dark);
}

.chip.selected,
.chip[aria-current="page"] {
    background-color: var(--primary-main);
    border-color: var(--primary-main);
    color: var(--primary-contrastText);
}

.chip.selected:hover,
.chip[aria-current="page"]:hover {
    background-color: var(--primary-main);
}

.chip-remove {
    color: var(--text-secondary);
}

.chip-remove:hover {
    color: var(--error-main);
}

/* "Favourited" chip heart (CMS search) — layout in components.css. */
.chip-favourite i {
    color: var(--error-main);
}

/* Quiet outlined badge tone (counts/metadata). */
.badge-outline {
    background-color: var(--background-secondary);
    border-color: var(--divider);
    color: var(--text-primary);
}

/* Button Group — hairline-bordered segmented control. The 1px flex gap
   reveals this --divider background between segments as dividers, and the
   same colour frames the group; opaque segment fills cover the rest. */
.button-group {
    border-color: var(--divider);
    background-color: var(--divider);
}

/* Selected segment carries the brand accent — the segmented control's "on"
   state. The shared disabled rule excludes .selected, so this
   wins even when the segment is disabled (a committed toggle answer). */
.button-group .selected {
    background-color: var(--primary-tint);
    color: var(--primary-tint-text);
    -webkit-text-fill-color: var(--primary-tint-text);
}

/* Search Bar */
.search-bar {
    background-color: var(--background-field);
}

.search-bar i {
    color: var(--text-secondary);
}

.search-bar input:focus-visible {
    outline-color: var(--primary-main);
}

/* The CMS toolbar search input dissolves into the bar (the bar already styles
   itself as a search box). Strip the global "action" chrome that otherwise
   paints the input on hover (darker bg + drop shadow) and focus/active
   (active bg + shadow + border). Keep it transparent over the bar's field
   colour, with no border or shadow, in every state. The id outranks the
   action rule's input:not([type="file"]):hover / :focus. */
#cms-toolbar-search-input,
#cms-toolbar-search-input:hover,
#cms-toolbar-search-input:focus,
#cms-toolbar-search-input:active {
    background-color: transparent;
    border-color: transparent;
    box-shadow: none;
}

.cms-toolbar-search-input:focus-visible {
    outline-color: var(--primary-main);
}

/*
 * JSON Editor Highlight Tokens.
 * The textarea's caret is `--text-primary`; the rendered text sits in the
 * <pre> overlay and consumes these per-token colors. Layout for the editor
 * itself lives in forms.css (.json-editor*).
 */
:root {
    --color-json-key: var(--primary-dark);
    --color-json-string: var(--success-main);
    --color-json-number: var(--secondary-dark);
    --color-json-boolean: var(--warning-main);
    --color-json-null: var(--text-disabled);
    --color-json-punct: var(--text-secondary);
    --color-json-error: var(--error-main);
    --color-json-match-bg: rgba(64, 128, 255, 0.18);
}

.json-editor__highlight code {
    color: var(--text-primary);
}

.json-editor__highlight .tok-key {
    color: var(--color-json-key);
    font-weight: var(--typography-fontWeightSemiBold);
}

.json-editor__highlight .tok-string {
    color: var(--color-json-string);
}

.json-editor__highlight .tok-number {
    color: var(--color-json-number);
}

.json-editor__highlight .tok-boolean {
    color: var(--color-json-boolean);
}

.json-editor__highlight .tok-null {
    color: var(--color-json-null);
    font-style: italic;
}

.json-editor__highlight .tok-punct {
    color: var(--color-json-punct);
}

.json-editor__highlight .tok-error {
    color: var(--color-json-error);
    text-decoration: underline wavy var(--color-json-error);
}

.json-editor__highlight .tok-match {
    background-color: var(--color-json-match-bg);
    border-radius: 2px;
}

/* Caret + selection on the transparent overlay textarea. The textarea's
   text/bg stay transparent (forced with !important in forms.css — the
   overlay pattern); only the caret and the selection highlight paint. */
.json-editor__input {
    caret-color: var(--text-primary);
}

.json-editor__input::selection {
    background: var(--primary-light);
    color: transparent;
    -webkit-text-fill-color: transparent;
}

.json-editor__format:focus {
    outline-color: var(--primary-main);
}

/* ============= CONTENT MODEL VISUALIZATION =============
   Color tokens, focus/dim/match states, dark-mode overrides for the
   subtype visualizer page (GET /core/subtype/visualize). Layout for
   the same components lives in components.css. Chrome comes from the
   system pieces (.badge/.chip/.card/.info-list/.row-item/.icon-button);
   only visualizer-specific states and the data-viz palette live here. */

:root {
  /* Sanctioned data-viz palette — entity-type coloring has no
     semantic-token equivalent. Attribute-type swatches (one per AttrType
     enum value plus REFERENCE) and per-classification accents, all based
     on palette tokens in light mode. */
  --cmv-type-string:    var(--blue-700);
  --cmv-type-text:      var(--blue-500);
  --cmv-type-integer:   var(--green-600);
  --cmv-type-decimal:   var(--teal-500);
  --cmv-type-boolean:   var(--purple-500);
  --cmv-type-datetime:  var(--orange-500);
  --cmv-type-binary:    var(--pink-500);
  --cmv-type-reference: var(--cyan-700);

  /* Per-classification accent — matches the badges in the cards. */
  --cmv-class-media-bg:      var(--pink-50);
  --cmv-class-media-fg:      var(--pink-800);
  --cmv-class-media-bd:      var(--pink-100);
  --cmv-class-webcontent-bg: var(--blue-50);
  --cmv-class-webcontent-fg: var(--blue-800);
  --cmv-class-webcontent-bd: var(--blue-100);
  --cmv-class-libcontent-bg: var(--green-50);
  --cmv-class-libcontent-fg: var(--green-800);
  --cmv-class-libcontent-bd: var(--green-100);
  --cmv-class-webpage-bg:    var(--orange-50);
  --cmv-class-webpage-fg:    var(--orange-900);
  --cmv-class-webpage-bd:    var(--orange-100);
  --cmv-class-system-bg:     var(--purple-50);
  --cmv-class-system-fg:     var(--purple-800);
  --cmv-class-system-bd:     var(--purple-100);
}

.cmv-root {
  color: var(--text-primary);
  background: var(--background-secondary);

  .cmv-search i { color: var(--text-secondary); }
  .cmv-search input[type="search"] {
    border-color: var(--divider);
    background: var(--background-default);
    color: var(--text-primary);
  }
  .cmv-search input[type="search"]:focus { border-color: var(--primary-main); }

  .cmv-heatmap .cmv-label,
  .cmv-unused  .cmv-label { color: var(--text-secondary); }
  .cmv-heatmap .cmv-label-hint,
  .cmv-unused  .cmv-label-hint { color: var(--text-disabled); }

  .cmv-type-legend { color: var(--text-secondary); border-bottom-color: var(--divider); }
  .cmv-type-legend .cmv-legend-meta { color: var(--text-disabled); }

  /* The visualizer canvas is background-secondary, the same surface the
     system chip uses — lift unselected chips to the default surface so
     they read as pills against the canvas. */
  .chip:not(.selected) { background-color: var(--background-default); }

  /* Span chips driven by [data-action] mirror the system a/button chip
     hover (the elements are spans — see components.css). */
  span.chip[data-action]:hover {
    background-color: var(--primary-light);
    border-color: var(--primary-main);
    color: var(--primary-dark);
  }
  .chip .cmv-count { background: color-mix(in srgb, currentColor 15%, transparent); }
  .chip .cmv-mono { color: var(--text-secondary); }
  .chip.selected .cmv-mono { color: color-mix(in srgb, currentColor 80%, transparent); }
  .cmv-reuse-chip.is-dim { opacity: 0.35; }
  .cmv-unused-chip { color: var(--text-secondary); }

  .cmv-card-header {
    background: linear-gradient(to bottom, var(--background-secondary), var(--background-default));
  }
  .cmv-card-name { color: var(--text-primary); }
  .cmv-card-code { color: var(--text-secondary); }
  .cmv-card-desc { color: var(--text-secondary); }
  .cmv-card-footer {
    background: var(--background-secondary);
    border-top-color: var(--divider);
    color: var(--text-secondary);
  }
  .cmv-card-footer .badge {
    background: var(--background-default);
    border-color: var(--divider);
    color: var(--text-primary);
  }

  .cmv-attr-row:hover {
    background: var(--background-hover);
    border-left-color: var(--primary-light);
  }
  .cmv-attr-row.is-match {
    background: color-mix(in srgb, var(--secondary-main) 12%, transparent);
    border-left-color: var(--secondary-main);
  }

  .cmv-card.is-dim { opacity: 0.32; filter: saturate(0.2); }
  .cmv-card.is-highlight { box-shadow: 0 0 0 2px var(--primary-main), var(--shadow-2); }
  .cmv-card.is-focused   { box-shadow: 0 0 0 2px var(--secondary-main), var(--shadow-3); }

  .cmv-group { border-color: var(--divider); }
  .cmv-group-header { color: var(--text-secondary); background: var(--background-secondary); border-color: var(--divider); }
  .cmv-group-header i { color: var(--secondary-main); }
  .cmv-group-header .cmv-group-code { color: var(--text-disabled); }
  .cmv-group.is-match { box-shadow: inset 3px 0 0 var(--secondary-main); }

  .cmv-type-icon { color: white; }
  .cmv-type-icon[data-type="STRING"]         { background: var(--cmv-type-string); }
  .cmv-type-icon[data-type="TEXT"]           { background: var(--cmv-type-text); }
  .cmv-type-icon[data-type="INTEGER"]        { background: var(--cmv-type-integer); }
  .cmv-type-icon[data-type="DECIMAL"]        { background: var(--cmv-type-decimal); }
  .cmv-type-icon[data-type="BOOLEAN"]        { background: var(--cmv-type-boolean); }
  .cmv-type-icon[data-type="DATETIME_ZONED"] { background: var(--cmv-type-datetime); }
  .cmv-type-icon[data-type="BINARY"]         { background: var(--cmv-type-binary); }
  .cmv-type-icon[data-type="REFERENCE"]      { background: var(--cmv-type-reference); }

  /* Required asterisk — matches the validation-error red used elsewhere. */
  .cmv-req { color: var(--red-500); }

  .cmv-attr-mono { color: var(--text-disabled); }

  /* Meta pills: badge-neutral carries the base; the bordered dot read
     and per-state tints are local. */
  .cmv-meta .badge,
  .cmv-legend-meta .badge { border-color: var(--divider); }
  .cmv-card-badge.is-many {
    background: color-mix(in srgb, var(--secondary-main) 10%, transparent);
    border-color: color-mix(in srgb, var(--secondary-main) 30%, transparent);
    color: var(--secondary-dark);
  }
  .cmv-reuse-dot.is-hot {
    background: color-mix(in srgb, var(--primary-main) 12%, transparent);
    border-color: color-mix(in srgb, var(--primary-main) 35%, transparent);
    color: var(--primary-dark);
  }
  .cmv-reuse-dot.is-cold { opacity: 0.55; }
  .cmv-value-dot {
    background: color-mix(in srgb, var(--cmv-type-integer) 12%, transparent);
    border-color: color-mix(in srgb, var(--cmv-type-integer) 35%, transparent);
    color: var(--cmv-type-integer);
  }
  .cmv-value-dot.is-zero { opacity: 0.5; background: var(--background-secondary); border-color: var(--divider); color: var(--text-disabled); }

  .cmv-class-badge {
    background: var(--background-secondary);
    border-color: var(--divider);
    color: var(--text-secondary);
  }
  .cmv-class-badge[data-class="media"]      { background: var(--cmv-class-media-bg);      color: var(--cmv-class-media-fg);      border-color: var(--cmv-class-media-bd); }
  .cmv-class-badge[data-class="webcontent"] { background: var(--cmv-class-webcontent-bg); color: var(--cmv-class-webcontent-fg); border-color: var(--cmv-class-webcontent-bd); }
  .cmv-class-badge[data-class="libcontent"] { background: var(--cmv-class-libcontent-bg); color: var(--cmv-class-libcontent-fg); border-color: var(--cmv-class-libcontent-bd); }
  .cmv-class-badge[data-class="webpage"]    { background: var(--cmv-class-webpage-bg);    color: var(--cmv-class-webpage-fg);    border-color: var(--cmv-class-webpage-bd); }
  .cmv-class-badge[data-class="system"]     { background: var(--cmv-class-system-bg);     color: var(--cmv-class-system-fg);     border-color: var(--cmv-class-system-bd); }

  .cmv-class-section h2 { color: var(--text-secondary); }
  .cmv-class-section h2::after { background: var(--divider); }

  .cmv-drawer { background: var(--background-default); border-left-color: var(--divider); }
  .cmv-drawer .cmv-empty { color: var(--text-secondary); }
  .cmv-drawer h3.cmv-kind { color: var(--text-secondary); }
  .cmv-drawer .cmv-entity-code,
  .cmv-drawer .cmv-entity-help {
    background: var(--background-secondary);
    border-color: var(--divider);
    color: var(--text-secondary);
  }
  .cmv-drawer .cmv-entity-help { border-left-color: var(--primary-light); }
  .cmv-drawer h4 { color: var(--text-secondary); }
  .cmv-drawer h4::after { background: var(--divider); }
  .cmv-drawer .cmv-icon-circle { background: var(--primary-main); color: var(--primary-contrastText); }
  .cmv-drawer .cmv-kv dt { color: var(--text-secondary); }
  .cmv-drawer .cmv-kv dd code { background: var(--background-secondary); }
  .cmv-drawer .cmv-used-by-list .row-item { background: var(--background-secondary); }
  .cmv-drawer .cmv-used-by-list .row-item:hover { background: var(--background-hover); border-color: var(--primary-light); }
  .cmv-drawer .cmv-used-by-list .cmv-via { color: var(--text-secondary); }
  .cmv-drawer .cmv-used-by-list .cmv-jump-code { color: var(--text-disabled); }
  .cmv-drawer .cmv-attr-fullrow {
    background: var(--background-secondary);
    color: var(--text-secondary);
  }
  .cmv-drawer .cmv-attr-fullrow:hover { background: var(--background-hover); border-color: var(--primary-light); }

  .cmv-no-results { color: var(--text-secondary); }
  .cmv-status-stats { color: var(--text-secondary); border-top-color: var(--divider); }
  .cmv-status-stats .cmv-stat strong { color: var(--text-primary); }

  .cmv-source-segment { background: var(--background-secondary); border-color: var(--divider); }
  .cmv-source-segment button { color: var(--text-secondary); background: transparent; }
  .cmv-source-segment button + button { border-left-color: var(--divider); }
  .cmv-source-segment button.is-active { background: var(--primary-main); color: var(--primary-contrastText); }
}

/* The List/Diagram tab bar is a sibling of .cmv-root in the template,
   not a descendant — keep these un-nested. */
.cmv-tab-bar { border-bottom-color: var(--divider); }
.cmv-tab-bar a { color: var(--text-secondary); }
.cmv-tab-bar a:hover { color: var(--text-primary); }
.cmv-tab-bar a.is-active { color: var(--primary-main); border-bottom-color: var(--primary-main); }

/* When the OS reports dark mode, retint the per-classification badges so
   they don't blow out against the dark background. Sanctioned data-viz
   palette: the fg values are palette tokens; the bg/bd values are deep
   tints with no palette-token equal and stay literal here (colors.css)
   only. */
@media (prefers-color-scheme: dark) {
  :root {
    --cmv-class-media-bg:      #4a1d2c;
    --cmv-class-media-fg:      var(--pink-100);
    --cmv-class-media-bd:      #6e2940;
    --cmv-class-webcontent-bg: #1c3450;
    --cmv-class-webcontent-fg: var(--blue-100);
    --cmv-class-webcontent-bd: #2a4870;
    --cmv-class-libcontent-bg: #1c3a23;
    --cmv-class-libcontent-fg: var(--green-100);
    --cmv-class-libcontent-bd: #2a5530;
    --cmv-class-webpage-bg:    #4a2b14;
    --cmv-class-webpage-fg:    var(--orange-100);
    --cmv-class-webpage-bd:    #6e3f20;
    --cmv-class-system-bg:     #3a1e44;
    --cmv-class-system-fg:     var(--purple-100);
    --cmv-class-system-bd:     #532864;
  }
}
/* ============= END CONTENT MODEL VISUALIZATION ============= */

/* Filter-pill selection states merged into the system .chip (above). */

/* ============= STRING TYPE-AHEAD + TAG CHIPS =============
   The box mirrors the standard input's action coloring; the inner input is
   transparent so the box reads as a single outlined field. */
.string-typeahead-box {
  color: var(--action-text);
  border-color: var(--action-border);
  background-color: var(--action-background);
  box-shadow: var(--action-shadow);
  transition: var(--action-transition);
}
.string-typeahead-box:focus-within {
  border-color: var(--action-border-active);
  background-color: var(--action-background-active);
  box-shadow: var(--action-shadow-active);
}
/* The action-active tokens above don't move enough to read as a focus
   indicator (border-color is unchanged from rest state). Add an explicit
   keyboard-focus ring on the box, which owns the outline. */
.string-typeahead-box:has(.string-typeahead-input:focus-visible) {
  outline-color: var(--primary-main);
}
.string-typeahead-box.error {
  border-color: var(--error-main);
}
/* Inspect (readonly) mode: render disabled like other fields — the div can't
   use :disabled, so mirror the disabled input tokens (cf. the RTE readonly
   treatment). */
.string-typeahead-box.string-typeahead--readonly {
  color: var(--action-text-disabled);
  border-color: var(--action-border-disabled);
  background-color: var(--action-background-disabled);
  box-shadow: var(--action-shadow-disabled);
}
/* The inner input is decoration-free — the box draws the field. The
   data-attribute lifts specificity above the global input rule's nested
   `&:focus`/`&:hover` (which compile to a high-specificity `:is(...)` chain),
   so a focused input doesn't pick the filled `--action-background-active`. */
.string-typeahead-box .string-typeahead-input[data-cms-typeahead-input],
.string-typeahead-box .string-typeahead-input[data-cms-typeahead-input]:hover,
.string-typeahead-box .string-typeahead-input[data-cms-typeahead-input]:focus {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
}
/* Tag values are system chips; only the plain (non-chip) variant re-colors,
   reading as text rather than a pill. */
.string-typeahead--plain .chip {
  background: none;
  color: var(--action-text);
}
/* Invalid entry (failed the editor's allowedRegex). */
.string-typeahead-box:has(.string-typeahead-input.is-invalid) {
  border-color: var(--error-main);
}

/* Guided combobox suggestion panel: an elevated dropdown over the field, with
   most-used-first options, usage-count pills, and a primary-accented
   "create new" affordance. */
.string-typeahead-panel {
  background: var(--background-default);
  border-color: var(--action-border);
  box-shadow: var(--shadow-toast);
  color: var(--text-primary);
}
.string-typeahead-panel-head {
  color: var(--text-secondary);
}
.string-typeahead-option {
  color: var(--text-primary);
}
.string-typeahead-option.is-active {
  background: var(--background-hover);
}
.string-typeahead-option.is-applied .string-typeahead-option-label {
  color: var(--text-secondary);
}
.string-typeahead-tick {
  color: var(--primary-main);
}
.string-typeahead-count {
  background: var(--background-secondary);
  color: var(--text-secondary);
}
/* Matched-substring emphasis as the author filters. */
.string-typeahead-option-label mark {
  background: transparent;
  color: var(--primary-main);
  font-weight: 700;
}
/* "Create new tag" row — primary accent signals a deliberate, new value. */
.string-typeahead-option--create {
  color: var(--primary-main);
  font-weight: var(--typography-fontWeightSemiBold);
}
.string-typeahead-option--create .string-typeahead-tick {
  color: var(--primary-main);
}
.string-typeahead-new {
  background: var(--primary-light);
  color: var(--primary-dark);
}
.string-typeahead-empty {
  color: var(--text-secondary);
}
/* ============= END STRING TYPE-AHEAD + TAG CHIPS ============= */

/* ============= INQUIRIES — attention colours ============= */
/* Color-coded attention model (doc §10.3). Buckets bind on data-cms-an so the
   colour is themeable here without any invented data-* attribute. Grey = your
   active; Green = others' active; Red = stale (yours or others' or pool);
   Pool = unassigned pending; Closed = terminal. */
.inquiry-dot[data-cms-an="GREY"] i,
.inquiry-badge[data-cms-an="GREY"] i { color: var(--text-secondary); }
.inquiry-dot[data-cms-an="GREEN"] i,
.inquiry-badge[data-cms-an="GREEN"] i { color: var(--success-main); }
.inquiry-dot[data-cms-an="RED"] i,
.inquiry-badge[data-cms-an="RED"] i { color: var(--error-main); }
.inquiry-dot[data-cms-an="POOL"] i,
.inquiry-badge[data-cms-an="POOL"] i { color: var(--warning-main); }
.inquiry-dot[data-cms-an="CLOSED"] i { color: var(--text-disabled); }

/* Thread entry sides: org reply, public visitor, internal note. */
.inquiry-entry { border-color: var(--divider); }
.inquiry-entry[data-cms-an="NOTE"] { background-color: color-mix(in srgb, var(--warning-main), transparent 92%); }
.inquiry-entry[data-cms-an="NOTE"] .inquiry-entry-tag { color: var(--warning-dark); }
.inquiry-entry[data-cms-an="ORG"] { background-color: color-mix(in srgb, var(--primary-main), transparent 94%); }
.inquiry-redacted { color: var(--text-disabled); }

.inquiry-status[data-cms-an="RED"] { color: var(--error-main); }
.inquiry-status[data-cms-an="GREEN"] { color: var(--success-main); }
/* ============= END INQUIRIES ============= */

/* Restricted-status icons. Shared by the CMS side-nav page tree and the page
   form: a silver lock for a restricted item, a red
   octagon for a public page that references restricted items. The octagon
   overrides the side-nav trailing-icon dimming so the warning stays vivid. */
.icon-restricted { color: silver; }
.icon-config-warning { color: var(--error-main); opacity: 1; }
.field-status { color: var(--text-secondary); }

/* ============================================================================
   Coloring relocated from forms.css. Structure stays with the owning
   feature; these sections mirror the source feature order.
   ============================================================================ */

/* ===== Field-level validation errors =====
   Atoms render class="error" on the input + a sibling .field-error span.
   Border colour shift gives the visual flag; the span carries the message.
   `.binary-file` and `.htmlEditor .editorHolder` already carry a 1px border
   via the global input-styling rule, so border-color alone flips them;
   `.icon-picker-container` signals via outline (shape in forms.css). */
input.error,
textarea.error,
select.error,
.css-editor.error,
.json-editor.error,
.input-date.error,
.input-datetime.error,
.input-date-zoned.error,
.input-time-zoned.error,
.input-datetime-zoned.error,
.input-timestamp.error,
.zone-typeahead-input.error,
.binary-file.error,
.htmlEditor.error .editorHolder {
    border-color: var(--error-main);
}

.icon-picker-container.error {
    outline-color: var(--error-main);
}

.field-error,
.error-text {
    color: var(--error-main);
}

/* ===== Icon picker coloring ===== */
.icon-picker-preview {
    border-color: var(--divider);
    background: var(--background-field);
    color: var(--text-primary);
}

.icon-picker-preview .no-icon {
    color: var(--text-secondary);
}

/* Full-viewport scrim behind the picker dialog. */
.icon-picker-modal {
    background: var(--scrim-heavy);
}

.icon-picker-controls {
    border-bottom-color: var(--divider);
}

/* Transparent base border-color fills the 1px hover-affordance slot
   reserved in forms.css so the hover border doesn't shift layout. */
.icon-picker-item {
    border-color: transparent;
    color: var(--text-primary);
}

.icon-picker-item:hover {
    background: var(--background-hover);
    border-color: var(--divider);
}

.icon-picker-item span {
    color: var(--text-secondary);
}

.icon-picker-more,
.icon-picker-no-results {
    color: var(--text-secondary);
}

/* ===== Zone picker combobox ===== */
.zone-typeahead-suggestions {
    background: var(--background-default);
    color: var(--text-primary);
    border-color: var(--divider);
}

.zone-typeahead-section-label {
    color: var(--text-secondary);
}

/* Options are plain list rows — strip the global button action chrome. */
.zone-typeahead-option {
    background: none;
    color: var(--text-primary);
}

.zone-typeahead-option:hover,
.zone-typeahead-option.highlighted {
    background: var(--background-hover);
}

/* ===== Timestamp atoms ===== */
.timestamp-edit {
    border-left-color: var(--info-main);
}

.timestamp-meta {
    color: var(--text-secondary);
}

/* Overrides the global `code` coloring (above) by specificity — the UTC
   caption code chip uses the field surface, not the code surface. */
.timestamp-utc-caption code {
    background: var(--background-field);
    color: var(--text-primary);
}

.timestamp-inspect .timestamp-wallclock small {
    color: var(--text-secondary);
}

.timestamp-inspect .timestamp-utc-caption {
    color: var(--text-secondary);
}

/* ===== File input ::file-selector-button coloring =====
   input[type="file"] is excluded from the global action rule, so the
   pseudo-button carries its own surface + hover. */
input[type="file"]::file-selector-button {
    background: var(--background-secondary);
    color: var(--text-primary);
}

input[type="file"]::file-selector-button:hover {
    background: var(--background-hover);
}

/* ===== Status pill + dirty/draft save states ===== */
.status-pill {
    border-color: var(--divider);
    background-color: var(--background-secondary);
}

.dirty-indicator {
    color: var(--text-primary);
}

.dirty-indicator[data-state="dirty"] {
    color: var(--warning-main);
    border-color: var(--warning-main);
    background-color: color-mix(in srgb, var(--warning-main), transparent 92%);
}

.dirty-indicator[data-state="saved"],
.draft-save-status.saved {
    color: var(--success-main);
    border-color: var(--success-main);
    background-color: color-mix(in srgb, var(--success-main), transparent 92%);
}

.draft-save-status.failed,
.draft-save-status.error {
    color: var(--error-main);
    border-color: var(--error-main);
    background-color: color-mix(in srgb, var(--error-main), transparent 92%);
}

/* Promote the submit button while the form is dirty (structure/transition in
   forms.css). Must stay AFTER the global button color rules: the hover rule
   ties the action `&:hover:not(:disabled)` at (0,4,1) specificity, so source
   order inside this file is what resolves it to the primary promotion. */
button[type="submit"][data-dirty="true"],
input[type="submit"][data-dirty="true"] {
    color: var(--primary-contrastText);
    -webkit-text-fill-color: var(--primary-contrastText);
    background-color: var(--primary-main);
}

button[type="submit"][data-dirty="true"]:hover:not(:disabled),
input[type="submit"][data-dirty="true"]:hover:not(:disabled) {
    background-color: var(--primary-dark);
}

/* Attachment budget warning: colour only; .status-pill carries the structure. */
.attachments-budget-warning {
    color: var(--warning-text);
    border-color: var(--warning-main);
    background-color: color-mix(in srgb, var(--warning-main), transparent 92%);
}

/* ===== Draft email compose ===== */
.draft-save-status {
    color: var(--text-secondary);
}

/* Unstyled subject input that visually replaces the email's <h2> subject;
   the dashed/solid border-style flip stays in forms.css. */
.message-view .message-view-subject input[name="subject"] {
    border-color: var(--divider);
    background-color: transparent;
    color: var(--text-primary);
}

.message-view .message-view-subject input[name="subject"]:focus {
    border-color: var(--primary-main);
}

/* ===== Dynamic page address ===== */
.slug-fieldset .optional-flag {
    color: var(--text-secondary);
}

/* ============================================================================
   Coloring relocated from components.css.
   ============================================================================ */

/* ===== Accordion coloring ===== */
.accordion .accordion-label:hover {
    background: var(--action-background-active);
}

input.accordion-check:checked + .accordion-label {
    background: var(--action-background-active);
}

/* ===== Info list + muted text utility coloring ===== */
.info-list-left dt {
    color: var(--text-secondary);
}

.text-muted {
    color: var(--text-disabled);
}

/* ===== CMS info page coloring ===== */
.info-page .info-section {
    border-bottom-color: var(--divider);
}

.info-page .status-description {
    background-color: var(--background-secondary);
}

.info-page .publishing-controls .help-text {
    color: var(--text-secondary);
}

/* ===== Badge semantic variants =====
   Kept after .badge-outline (above) so an element carrying both classes
   resolves the equal-specificity tie to the semantic variant, matching the
   pre-relocation file order. Shape lives in components.css. */
.badge-neutral {
    background-color: var(--background-secondary);
    color: var(--text-secondary);
}

.badge-info {
    background-color: color-mix(in srgb, var(--info-main), transparent 85%);
    color: var(--info-dark);
}

.badge-success {
    background-color: color-mix(in srgb, var(--success-main), transparent 85%);
    color: var(--success-dark);
}

.badge-warning {
    background-color: color-mix(in srgb, var(--warning-main), transparent 85%);
    color: var(--warning-dark);
}

.badge-error {
    background-color: color-mix(in srgb, var(--error-main), transparent 85%);
    color: var(--error-dark);
}

/* Count chip: a soft brand tint by default — informational
   section counts (the registration-status accordions) stay calm but visible
   (layout in features.css). A neutral grey vanished against the accordion
   header's --background-secondary surface. In the sidebar nav the chip is a
   genuine "awaiting your action" notification, so there it gets the full
   brand accent. */
.count-chip {
    background-color: var(--primary-tint);
    color: var(--primary-tint-text);
}

nav.main-nav .count-chip {
    background-color: var(--primary-main);
    color: var(--primary-contrastText);
}

/* Overlay badge: solid paper surface — never a tint — so
   the media-type glyph stays legible over arbitrary thumbnail content in
   both color schemes. Placed after the semantic variants for the same
   equal-specificity reason as above, though semantic variants don't apply
   to overlays. */
.badge-overlay {
    background-color: var(--background-default);
    color: var(--text-primary);
}

/* ===== CMS page tree coloring =====
   Was --text-disabled (3.34:1 here, fails 1.4.3) — phantom segments are
   plain muted text, not a disabled control, so --text-secondary (4.74:1)
   is both correct and compliant in both modes. */
nav.main-nav menu li.page-tree-item .page-tree-phantom {
    color: var(--text-secondary);
}

nav.main-nav menu li.page-tree-item .page-tree-toggle:focus-visible {
    outline-color: var(--primary-main);
}

/* ===== CMS preview coloring =====
   Iframe canvas priming — intentionally white in BOTH light and dark modes:
   the framed site brings its own theme, and a white canvas avoids a dark
   flash while the document loads. */
.preview-iframe {
    background-color: var(--white);
}

/* ===== Row + drag grammar coloring =====
   .entity-chooser-selection (the chooser editor's "current pick" box) shares
   the row surface recipe exactly — merged here instead of duplicated in the
   chooser section below. */
.row-item,
.entity-chooser-selection {
    background: var(--background-default);
    color: var(--text-primary);
    border-color: var(--divider);
}

/* Drop position indicators — inset primary edges / outline. */
.row-item.drop-before {
    box-shadow: inset 0 2px 0 0 var(--primary-main);
}

.row-item.drop-after {
    box-shadow: inset 0 -2px 0 0 var(--primary-main);
}

.row-item.drop-into {
    box-shadow: inset 0 0 0 2px var(--primary-main);
}

/* ===== Drag & drop coloring ===== */
.drag-source-list,
.drag-target-list {
    border-color: var(--divider);
    background: var(--background-secondary);
}

.drag-target-list.drag-over {
    border-color: var(--primary-main);
    background: var(--background-hover);
}

.drag-item.group-item {
    border-left-color: var(--info-main);
}

/* Insertion marker: primary bar with a background-hover halo so it stays
   visible over row borders. */
.drag-placeholder {
    background: var(--primary-main);
    box-shadow: 0 0 0 2px var(--background-hover);
}

.drag-handle {
    color: var(--text-secondary);
}

/* ===== Modal + popover coloring ===== */
.modal {
    background: var(--background-default);
    color: var(--text-primary);
    border-color: var(--divider);
}

/* Dialog scrim. */
.modal::backdrop {
    background: var(--scrim);
}

.modal-header {
    border-bottom-color: var(--divider);
}

.modal-header h3 {
    color: var(--text-primary);
}

.modal-body {
    color: var(--text-primary);
}

.modal-footer {
    border-top-color: var(--divider);
}

.profile-switch-modal .profile-switch-row {
    border-top-color: var(--divider);
}

.profile-switch-modal .profile-switch-roles {
    color: var(--text-secondary);
}

.popover {
    background: var(--background-default);
    border-color: var(--divider);
}

/* ===== CMS media file-dropzone ===== */
.file-dropzone {
    border-color: var(--divider);
    background: var(--background-field);
}

.file-dropzone.dragover {
    border-color: var(--primary-main);
    background: var(--background-field);
}

.file-dropzone-hint,
.file-dropzone-or,
.file-dropzone-size-hint {
    color: var(--text-secondary);
}

.file-dropzone-filename {
    color: var(--text-primary);
}

.file-dropzone-error {
    color: var(--error-main);
}

/* ===== CMS dashboard coloring ===== */
.dashboard-widget {
    background: var(--background-default);
}

.dashboard-widget-title {
    border-bottom-color: var(--divider);
    color: var(--text-primary);
}

.dashboard-widget-title i {
    color: var(--primary-main);
}

.dashboard-row + .dashboard-row {
    border-top-color: var(--divider);
}

.dashboard-row-link {
    color: var(--text-primary);
}

.dashboard-row-link:hover,
.dashboard-row-link:focus-visible {
    background: var(--background-hover);
}

.dashboard-row-icon,
.dashboard-row-date {
    color: var(--text-secondary);
}

.dashboard-empty {
    color: var(--text-secondary);
}

.dashboard-avatar-img {
    border-color: var(--divider);
}

.dashboard-avatar-name {
    color: var(--text-primary);
}

/* ===== Ensemble home dashboard coloring ===== */
.dashboard-stat {
    background: var(--background-secondary);
    border-color: var(--divider);
}

.dashboard-stat-link {
    color: var(--text-primary);
}

.dashboard-stat-link:hover,
.dashboard-stat-link:focus-visible {
    background: var(--background-hover);
}

.dashboard-stat-icon {
    color: var(--primary-main);
}

.dashboard-stat-figure {
    color: var(--text-primary);
}

.dashboard-stat-label,
.dashboard-action-go,
.dashboard-event-when {
    color: var(--text-secondary);
}

.dashboard-action-error .dashboard-row-icon {
    color: var(--error-main);
}

.dashboard-action-warning .dashboard-row-icon {
    color: var(--warning-main);
}

.dashboard-action-info .dashboard-row-icon {
    color: var(--info-main);
}

/* ===== Group-info popover content ===== */
.group-info-header h4,
.group-info-description {
    color: var(--text-primary);
}

.group-info-description.muted,
.group-info-attrs li.muted,
.group-info-attrs-heading {
    color: var(--text-secondary);
}

.group-info-attrs li {
    border-bottom-color: var(--divider);
}

/* ===== Placeholder glyph boxes =====
   Media-list thumb, chooser tile icon, and multi-row thumb all share one
   muted field surface for the no-image glyph. */
.media-thumb-img,
.entity-chooser-tile-icon,
.entity-chooser-tile-thumb-box,
.entity-chooser-display-thumb,
.ec-row-thumb {
    background: var(--background-field);
    color: var(--text-secondary);
}

/* ===== Enhanced entity chooser ===== */
.entity-chooser-host {
    background: var(--background-default);
    border-left-color: var(--divider);
}

/* Grab-affordance tint while hovering/dragging the resize handle; the
   opacity is part of the tint (40% primary), not structure. */
.entity-chooser-resize-handle:hover,
body.entity-chooser-resizing .entity-chooser-resize-handle {
    background: var(--primary-main);
    opacity: 0.4;
}

.entity-chooser-header,
.entity-chooser-controls {
    border-bottom-color: var(--divider);
}

/* Quiet outlined toggle. Note: when rendered as a <button>, the global
   action rules' :hover/:focus chains out-specify these class rules (both
   before and after relocation) — these set the resting surface only. */
.entity-chooser-filter-toggle {
    background: transparent;
    border-color: var(--divider);
    color: var(--text-primary);
}

.entity-chooser-filter-toggle:hover {
    background: var(--background-field);
}

.entity-chooser-filter-caret,
.entity-chooser-filter-label,
.entity-chooser-sort-icon,
.entity-chooser-sort-label {
    color: var(--text-secondary);
}

.entity-chooser-loading,
.entity-chooser-empty,
.entity-chooser-error {
    color: var(--text-secondary);
}

/* Must stay after the muted grid-state rule above (same specificity). */
.entity-chooser-error {
    color: var(--error-main);
}

/* Tile selection grammar: the 2px border carries selection (structure +
   transparent baseline stay in components.css); backgrounds lift on hover. */
.entity-chooser-tile {
    background: var(--background-default);
}

.entity-chooser-tile:hover {
    border-color: var(--divider);
    background: var(--background-field);
}

.entity-chooser-tile.selected {
    border-color: var(--primary-main);
    background: var(--background-field);
}

.entity-chooser-tile-name {
    color: var(--text-primary);
}

/* Preview flavour is inert: no hover lift, never a selection border. Must
   stay after the :hover/.selected rules above — it wins the equal-
   specificity border-color tie against :hover by source order. */
.entity-chooser-tile.entity-chooser-tile-preview {
    border-color: transparent;
}

.entity-chooser-tile.entity-chooser-tile-preview:hover {
    background: var(--background-default);
    border-color: transparent;
}

/* Opaque disc under the tile favourite heart. Must stay after the
   .icon-button:hover recipe (above): the toggle is an icon-button, and this
   (0,2,0) rule wins the background tie on hover by source order, keeping
   the disc opaque over the tile. */
.entity-chooser-tile > .ec-fav-toggle {
    background: var(--background-default);
}

.entity-chooser-footer {
    border-top-color: var(--divider);
}

.entity-chooser-strip-identity {
    color: var(--text-primary);
}

.entity-chooser-strip-identity .chevron {
    color: var(--text-secondary);
}

.entity-chooser-strip-pill-dot {
    background: var(--primary-main);
}

/* Editor-field text around the selection box (the box surface itself is
   merged into the .row-item recipe above). */
.entity-chooser-selection:empty::before {
    color: var(--text-secondary);
}

.entity-chooser-selection-name,
.entity-chooser-display-name {
    color: var(--text-primary);
}

.entity-chooser-display-label {
    color: var(--text-secondary);
}

/* Mobile bottom-sheet flavour (structure in components.css). */
@media (max-width: 640px) {
    .entity-chooser-host {
        border-top-color: var(--divider);
    }

    .entity-chooser-sidebar.collapsed .entity-chooser-strip::before {
        background: var(--divider);
    }
}

/* ===== Web-safe color editor =====
   Swatch borders are neutral black overlays so every swatch colour gets the
   same subtle edge in both modes; no token maps to a fixed-alpha black
   overlay, so the literals are intentional. */
.web-safe-color-swatch {
    border-color: rgba(0, 0, 0, 0.1);
}

/* :focus-visible must stay after [aria-selected] (same specificity): a
   focused selected swatch shows the primary focus ring, not the black
   selection ring. */
.web-safe-color-swatch[aria-selected="true"] {
    outline-color: var(--black);
}

.web-safe-color-swatch:focus-visible {
    outline-color: var(--primary-main);
}

.web-safe-color-swatch-readonly {
    border-color: rgba(0, 0, 0, 0.2);
}

/* ===== Multi-value chooser rows ===== */
.ec-row-drag-handle,
.ec-row-meta {
    color: var(--text-secondary);
}

.ec-row-name {
    color: var(--text-primary);
}

.entity-chooser-selected {
    border-top-color: var(--divider);
}

.entity-chooser-selected-head {
    color: var(--text-secondary);
}

/* ===== Navigation tree editor ===== */
ul.nav-tree-children {
    border-left-color: var(--divider);
}

.nav-tree-warning {
    color: var(--warning-main);
}

.nav-action-panel {
    border-color: var(--divider);
    background: var(--background-field);
}

/* Rich-text embed chip states. */
.ec-chip .ec-chip-fmt {
    color: var(--text-secondary);
}
.ec-chip.ec-chip-missing {
    border-color: var(--error-main);
    color: var(--error-main);
}
.ec-chip-inspect {
    color: var(--text-secondary);
}
.ec-chip-inspect:hover {
    color: var(--primary-link);
}
/* Selected state: while the chip is the active selection, tint
   the whole atom with the app's selection colour so it reads "selected" like
   highlighted text. Suppress the chip's own native text-selection highlight so
   only this single tint shows (no doubling over the chip background). */
.ec-chip-selected {
    background: var(--primary-light);
}
.ec-chip::selection,
.ec-chip ::selection {
    background: transparent;
}
.ec-format-menu-item {
    background: transparent;
}
.ec-format-menu-hint {
    color: var(--text-secondary);
}
.ec-format-menu-item:hover {
    background: var(--background-field);
}
.ec-format-menu-remove {
    color: var(--error-main);
}
