/**
 * Cast: shared dark base.
 *
 * Loaded once ahead of every dark theme, so a theme only declares its deltas. Scoped
 * to `data-cast-scheme` so a theme's `data-cast-theme` rules win on declaration order.
 * Never `@import` this from a theme: with two dark themes loaded (as the preview
 * screens do), the second import re-declares the base after the first theme's
 * overrides and flattens it.
 *
 * Two layers: the inverted `--gray-*-hsl` ramp, which most of the CP follows
 * automatically, then a patch layer for the colours Craft hard-codes beyond reach of
 * any variable.
 *
 * `--white` and `--black` are left alone. Craft uses `--white` more often as ink on a
 * coloured fill (button labels, badge text, the lightswitch handle) than as a surface,
 * so swapping them breaks more than it fixes. Surfaces are patched individually.
 *
 * The opt-out reset that used to close this file now lives in `_stock.css`, which loads
 * for any theme rather than only dark ones.
 *
 * Worth knowing before reorganising what's left: a large share of the rules below set
 * nothing but `var()` values, so they aren't dark-specific at all — they're places Craft
 * wrote a literal where a custom property already existed, and pointing it back at the
 * property is right for any theme. `stone.css` repeats a handful of them for the same
 * reason on the light side. Hoisting those into a base that loads for every theme is a
 * separate job, and some are worth upstreaming to Craft rather than carrying here.
 */

html[data-cast-scheme="dark"] {
    color-scheme: dark;

    /* Inverted neutral ramp. Hue held at Craft's cool blue-grey. */
    --gray-050-hsl: 210, 24%, 10%;
    --gray-100-hsl: 210, 22%, 13%;
    --gray-150-hsl: 210, 20%, 16%;
    --gray-200-hsl: 209, 18%, 21%;
    --gray-300-hsl: 209, 15%, 30%;
    --gray-350-hsl: 210, 13%, 38%;
    --gray-400-hsl: 210, 11%, 47%;
    --gray-500-hsl: 211, 12%, 57%;
    --gray-550-hsl: 211, 14%, 64%;
    --gray-600-hsl: 211, 18%, 71%;
    --gray-700-hsl: 212, 24%, 80%;
    --gray-800-hsl: 212, 32%, 87%;
    --gray-900-hsl: 212, 44%, 93%;
    --gray-1000-hsl: 212, 60%, 97%;

    /* Cast's own surface tokens, so the patch layer has something to aim at and
       themes can retune every popover in one line. */
    --cast-surface: hsl(var(--gray-150-hsl));
    --cast-surface-hover: hsl(var(--gray-200-hsl));
    --cast-chip: hsl(var(--gray-200-hsl));
    --cast-chip-active: hsl(var(--gray-300-hsl));
    --cast-popover-outline: rgb(255 255 255 / 14%);
    --cast-popover-shadow: 0 0 0 1px var(--cast-popover-outline), 0 5px 20px rgb(0 0 0 / 45%);

    /* Surfaces that sit below the ramp's floor rather than on it. Code blocks drop under
       the pane they're in, and the image editor is Craft's one already-dark screen, so it
       gets pinned rather than inverted (see below). Both are held here so a theme can
       retint them from its ramp instead of restating the rules. */
    --cast-code-bg: hsl(210, 24%, 8%);
    --cast-editor-canvas: hsl(210, 24%, 8%);
    --cast-editor-rule: hsl(210, 22%, 4%);
    --cast-editor-btn: hsl(210, 14%, 26%);
    --cast-editor-btn-hover: hsl(210, 14%, 32%);
    --cast-editor-btn-active: hsl(210, 14%, 38%);

    /* General */
    --body-bg: hsl(var(--gray-050-hsl));
    --bg-color-hsl: var(--gray-050-hsl);
    --text-color: var(--gray-800);
    --light-text-color: var(--gray-550);
    --link-color: #7fb2ff;
    --focus-ring-color: #4ea3e0;

    /* Craft leans on shadows for pane separation, which read as mud on dark. Hairline
       rings instead. */
    --pane-bg: hsl(var(--gray-100-hsl));
    --pane-shadow: 0 0 0 1px hsl(var(--gray-200-hsl)), 0 2px 12px rgb(0 0 0 / 35%);
    --secondary-pane-bg: hsl(var(--gray-150-hsl));
    --secondary-pane-shadow: var(--pane-shadow);
    --slideout-footer-bg: hsl(var(--gray-150-hsl));
    --sidebar-bg: hsl(var(--gray-100-hsl));

    --modal-bg: hsl(var(--gray-150-hsl));
    --modal-shadow: 0 0 0 1px hsl(var(--gray-300-hsl)), 0 25px 100px rgb(0 0 0 / 65%);
    --login-modal-bg: hsl(var(--gray-150-hsl));
    --shade-bg: rgb(0 0 0 / 65%);

    /* Inputs */
    --input-bg: hsl(210, 22%, 15%);
    --input-border-color: hsla(212, 15%, 60%, 0.35);
    --fg-input: #8ba7c7;

    /* Craft's light status tints are far too bright as fills, so these are deep
       washes with the brighter hue kept for text and borders. */
    --bg-error: hsl(0, 45%, 18%);
    --bg-warning: hsl(35, 45%, 18%);
    --bg-success: hsl(174, 40%, 15%);
    --bg-notice: hsl(202, 45%, 18%);

    --fg-error: var(--red-400);
    --fg-warning: var(--amber-300);
    --fg-success: var(--teal-300);
    --fg-notice: var(--sky-300);
    --fg-subtle: var(--gray-550);

    --border-error: var(--red-800);
    --border-warning: var(--amber-800);
    --border-warning-emphasis: var(--amber-500);
    --border-success: var(--teal-800);
    --border-notice: var(--sky-800);
    --error-color-rgb: 248 113 113;

    /* Craft's hairlines are dark-on-light alpha blends, inverted here. */
    --border-hairline: rgb(255 255 255 / 12%);
    --border-hairline-medium: hsl(var(--gray-200-hsl));
    --border-hairline-dark: rgb(255 255 255 / 28%);

    /* Selection and focus */
    --bg-selection-light: hsl(var(--gray-200-hsl));
    --bg-selection-dark: hsl(var(--gray-300-hsl));
    --focus-outline-light: var(--blue-400);
    --focus-outline-medium: #4ea3e0;
    --focus-outline-dark: var(--blue-300);
}


/* ==========================================================================
   Patch layer: Craft's hard-coded colours
   ========================================================================== */

/* --------------------------------------------------------------------------
   Popover surfaces. Craft paints menus, dropdowns, autosuggest results, and
   tooltips with a literal `#fff`, and their text with `#3f4d5a`.
   -------------------------------------------------------------------------- */

html[data-cast-scheme="dark"] .menu,
html[data-cast-scheme="dark"] .ui-datepicker,
html[data-cast-scheme="dark"] .ui-timepicker-wrapper,
html[data-cast-scheme="dark"] .autosuggest__results-container,
html[data-cast-scheme="dark"] .craft-tooltip > .inner,
html[data-cast-scheme="dark"] .craft-tooltip .arrow,
html[data-cast-scheme="dark"] .tooltip,
html[data-cast-scheme="dark"] .selectize-dropdown,
html[data-cast-scheme="dark"] body .selectize-dropdown-content,
html[data-cast-scheme="dark"] .selectize-dropdown .optgroup-header,
html[data-cast-scheme="dark"] #notifications .copied-elements-notification .notification-inner {
    background: var(--cast-surface);
}

/* Craft's 1px popover ring is invisible on dark, leaving menus as flat slabs. Faint
   light ring instead, with a deeper shadow. Skips `.craft-tooltip .arrow`, a rotated
   square that would ring its own diagonal. */
html[data-cast-scheme="dark"] .menu,
html[data-cast-scheme="dark"] .ui-datepicker,
html[data-cast-scheme="dark"] .ui-timepicker-wrapper,
html[data-cast-scheme="dark"] .autosuggest__results-container,
html[data-cast-scheme="dark"] .craft-tooltip > .inner,
html[data-cast-scheme="dark"] .tooltip,
html[data-cast-scheme="dark"] .selectize-dropdown,
html[data-cast-scheme="dark"] #notifications .copied-elements-notification .notification-inner {
    box-shadow: var(--cast-popover-shadow);
}

html[data-cast-scheme="dark"] .menu ul li .menu-item,
html[data-cast-scheme="dark"] .menu ul li .menu-option,
html[data-cast-scheme="dark"] .menu:not(.menu--disclosure) ul li a,
html[data-cast-scheme="dark"] .autosuggest__results-container .autosuggest__results-item,
html[data-cast-scheme="dark"] body .selectize-dropdown .optgroup-header,
html[data-cast-scheme="dark"] body .selectize-dropdown .option,
html[data-cast-scheme="dark"] body .selectize-dropdown [data-selectable],
html[data-cast-scheme="dark"] .selectize-dropdown,
html[data-cast-scheme="dark"] .selectize-dropdown .active,
html[data-cast-scheme="dark"] .selectize-dropdown .selected {
    color: var(--text-color);
}

html[data-cast-scheme="dark"] .autosuggest__results-container .autosuggest__results-before {
    color: var(--fg-subtle);
}

html[data-cast-scheme="dark"] .menu--disclosure ul li > .menu-item:hover,
html[data-cast-scheme="dark"] .menu--disclosure ul li > .menu-option:hover,
html[data-cast-scheme="dark"] .menu--disclosure ul li > a:not(.crumb-link):hover,
html[data-cast-scheme="dark"] .selectize-dropdown .active,
html[data-cast-scheme="dark"] .selectize-dropdown .selected,
html[data-cast-scheme="dark"] .selectize-dropdown .active:not(.selected) {
    background-color: var(--cast-surface-hover);
    color: var(--text-color);
}

/* --------------------------------------------------------------------------
   Form controls. `<select>` and selectize text is hard-coded to `#3f4d5a`.
   Checkbox and radio boxes are painted `#fbfcfe` while their tick is
   `--gray-900`, so the inverted ramp gives a near-white tick on a near-white box.
   -------------------------------------------------------------------------- */

html[data-cast-scheme="dark"] .select:not(.selectize) select,
html[data-cast-scheme="dark"] .selectize.select .selectize-input,
html[data-cast-scheme="dark"] .selectize-input,
html[data-cast-scheme="dark"] .selectize-input input,
html[data-cast-scheme="dark"] .multiselect > select {
    color: var(--text-color);
}

html[data-cast-scheme="dark"] .selectize-input,
html[data-cast-scheme="dark"] .selectize-control.single .selectize-input.input-active,
html[data-cast-scheme="dark"] .selectize-input.full,
html[data-cast-scheme="dark"] .selectize-control .selectize-input.disabled {
    background: var(--input-bg);
    border-color: var(--input-border-color);
}

/* Craft gives a select-shaped selectize `--button-bg` to match a native `<select>`.
   The rule above catches those too, so put them back. */
html[data-cast-scheme="dark"] .selectize.select .selectize-input {
    background: var(--button-bg);
}

html[data-cast-scheme="dark"] .selectize.select .selectize-input.dropdown-active,
html[data-cast-scheme="dark"] .selectize.select .selectize-input:hover {
    background: var(--button-bg--hover);
}

html[data-cast-scheme="dark"] div.checkbox:before,
html[data-cast-scheme="dark"] input.checkbox + label:before,
html[data-cast-scheme="dark"] div.radio:before,
html[data-cast-scheme="dark"] input.radio + label:before {
    background-color: var(--input-bg);
}

html[data-cast-scheme="dark"] .ui-datepicker-title select.ui-datepicker-year {
    background-color: var(--cast-chip);
    color: var(--text-color);
}

html[data-cast-scheme="dark"] input.range::-webkit-slider-runnable-track {
    background: hsl(var(--gray-300-hsl));
}

html[data-cast-scheme="dark"] input.range::-moz-range-track {
    background: hsl(var(--gray-300-hsl));
}

/* --------------------------------------------------------------------------
   Chips and tokens. Craft fills these `#e4edf6` with `#3f4d5a` text.
   -------------------------------------------------------------------------- */

html[data-cast-scheme="dark"] .token,
html[data-cast-scheme="dark"] .selectize.multiselect .selectize-input > .item,
html[data-cast-scheme="dark"] .selectize-control.multi .selectize-input > div {
    background-color: var(--cast-chip);
    color: var(--text-color);
}

html[data-cast-scheme="dark"] .token:focus,
html[data-cast-scheme="dark"] .selectize.multiselect .selectize-input > .item.active,
html[data-cast-scheme="dark"] .selectize-control.multi .selectize-input > div.active {
    background-color: var(--cast-chip-active);
    color: var(--text-color);
}

/* --------------------------------------------------------------------------
   White separator rings. They lift an element off a light page, but read as
   bright halos on a dark one, so they point at the surface behind instead.
   -------------------------------------------------------------------------- */

html[data-cast-scheme="dark"] .activity-container ul li .activity-btn .elementthumb {
    border-color: var(--pane-bg);
}

html[data-cast-scheme="dark"] .draft-notice .draft-icon,
html[data-cast-scheme="dark"] .content-notice .content-notice-icon {
    box-shadow: 0 1px 1px 1px var(--pane-bg);
}

html[data-cast-scheme="dark"] .element-index .source-path .btn.settings {
    box-shadow: 0 0 0 2px var(--pane-bg);
}

/* The dev mode stripe lays amber dashes over `--gray-900`, meaning near-black. Inverted,
   the gaps between the dashes turn white. */
html[data-cast-scheme="dark"] #devmode {
    background-color: hsl(var(--gray-050-hsl));
}

html[data-cast-scheme="dark"] #footer {
    border-block-start-color: var(--border-hairline);
}

/* Craft hard-codes a light-mode blue for footer links, which sinks into the canvas.
   Inheriting hands the theme's own link colour back. */
html[data-cast-scheme="dark"] #global-footer {
    --link-color: inherit;
}

/* The view mode and transform mode pickers illustrate their options with flat SVG artwork
   drawn for a white page, and there's no repainting a bitmap-shaped asset from CSS. Given
   a white card to sit on, each one reads as a picture of the CP rather than a bright patch
   torn out of it. `.mb-xs` is a margin utility, but every use of it in Craft is one of
   these images. */
html[data-cast-scheme="dark"] label > img.mb-xs {
    background-color: #fff;
    border-radius: var(--large-border-radius);
    padding: var(--s);
}

/* Craft draws these in the page colour, so they only appear on hover. Keep them
   invisible at rest, and hover to a lighter surface rather than the ramp's darkest step. */
html[data-cast-scheme="dark"] ul.icons li a {
    border-color: transparent;
}

html[data-cast-scheme="dark"] ul.icons li a:hover {
    background-color: var(--cast-surface);
    border-color: var(--cast-surface-hover);
}

/* --------------------------------------------------------------------------
   Light glows. Craft's ambient shadows are tinted `hsla(212,30%,85%,.5)`, which
   glows on a dark canvas instead of receding.
   -------------------------------------------------------------------------- */

html[data-cast-scheme="dark"] #trial-info {
    box-shadow: 0 0 0 1px hsl(var(--gray-300-hsl)), 0 2px 12px rgb(0 0 0 / 35%);
}

/* Sidebar meta blocks ask for `--gray-050`, which inverts to the page colour and leaves
   them flat. A step up separates each block from the canvas, as on light. */
html[data-cast-scheme="dark"] .details .meta:not(.read-only) {
    background-color: hsl(var(--gray-100-hsl)) !important;
}

html[data-cast-scheme="dark"] .details .meta.warning {
    box-shadow: 0 0 0 1px var(--border-warning-emphasis), 0 2px 12px rgb(0 0 0 / 35%);
}

html[data-cast-scheme="dark"] .fld-container .fld-workspace {
    box-shadow: inset 0 1px 3px -1px rgb(0 0 0 / 60%);
}

/* Every field draws a leading divider, so whichever one starts a row lands on top of the
   container's own edge. Both are `--border-hairline`, but as a translucent white the two
   stack into a brighter line — hence the opaque equivalent here, which looks the same
   alone and doesn't accumulate where it doubles up. */
html[data-cast-scheme="dark"] .flex-fields > :not(h2, hr, .line-break):before,
html[data-cast-scheme="dark"] .flex-fields > :not(h2, hr, .line-break):last-child:before {
    background-color: var(--border-hairline-medium);
}

/* --------------------------------------------------------------------------
   Draft notice. Every part of it is drawn in `--blue-800`, a dark navy meant to
   sit on white.
   -------------------------------------------------------------------------- */

html[data-cast-scheme="dark"] .draft-notice {
    color: var(--blue-300);
}

html[data-cast-scheme="dark"] .draft-notice .draft-icon {
    border-color: rgb(from var(--blue-300) r g b / 35%);
}

html[data-cast-scheme="dark"] .draft-notice .draft-icon:before {
    color: var(--blue-300) !important;
}

html[data-cast-scheme="dark"] .draft-notice .discard-changes-btn {
    border-color: var(--blue-400) !important;
    color: var(--blue-300) !important;
}

html[data-cast-scheme="dark"] .draft-notice .discard-changes-btn:focus,
html[data-cast-scheme="dark"] .draft-notice .discard-changes-btn:hover,
html[data-cast-scheme="dark"] .draft-notice .discard-changes-btn:active {
    border-color: var(--blue-300);
}

/* --------------------------------------------------------------------------
   Panels and page chrome that paint their own background.
   -------------------------------------------------------------------------- */

html[data-cast-scheme="dark"] body.fixed-header #header {
    background-color: hsla(var(--gray-050-hsl), 0.75);
}

/* The selected tab's ring (`rgba(51,64,77,.1)`) vanishes on dark while its `--gray-200`
   spread glows, so the tab reads as a halo with no edge. Dark spread, faint light
   ring, calmer indicator. */
html[data-cast-scheme="dark"] .pane-tabs [role="tablist"] [role="tab"].sel {
    --highlight-color: var(--gray-400);

    background-color: var(--pane-bg) !important;
    box-shadow:
        inset 0 2px 0 var(--custom-text-color, var(--highlight-color)),
        0 0 0 1px var(--cast-popover-outline),
        0 2px 12px rgb(0 0 0 / 35%);
}

/* A slideout stacks three surfaces from three different tokens — the slideout itself
   (`--modal-bg`), its body and sidebar (a literal `--gray-100`), and the selected tab
   above them — so on dark the tab never quite lines up with the fields beneath it.
   Pinning all of them to `--pane-bg` makes the panel read as one surface. */
html[data-cast-scheme="dark"] .slideout {
    background-color: var(--pane-bg);
}

/* The details sidebar is the canvas its meta blocks sit on. Craft asks for `--gray-100`
   there, a step *down* from the blocks' `--gray-050`; inverted, that ordering flips and
   the two flatten into each other, so the canvas takes the darker step instead. */
html[data-cast-scheme="dark"] .slideout > .so-body.so-full-details,
html[data-cast-scheme="dark"] .slideout > .so-body > .so-sidebar {
    background-color: hsl(var(--gray-050-hsl)) !important;
}

/* Notes and other meta textareas: Craft flattens meta text inputs into the block they
   sit in, but a textarea keeps `--input-bg` and reads as a hole punched in it. */
html[data-cast-scheme="dark"] .details .meta textarea {
    background-color: transparent;
}

/* The notes field is a bare `.field` rather than a `.meta` block, so nothing lifts it off
   the canvas. Give it the same surface the blocks above it sit on. */
html[data-cast-scheme="dark"] .details .notes,
html[data-cast-scheme="dark"] .details .notes textarea {
    background-color: hsl(var(--gray-100-hsl));
}

/* Selected sources and pressed segmented buttons are painted `--gray-500`, a light step
   on the inverted ramp that glares against the chrome around it. A mid step still reads
   as selected under the white label without taking over the panel. */
html[data-cast-scheme="dark"] .sidebar nav li:not(.has-subnav) [data-source-item].sel,
html[data-cast-scheme="dark"] .sidebar nav li:not(.has-subnav) [data-source-item].active-drop-target,
html[data-cast-scheme="dark"] .sidebar nav li:not(.has-subnav) > a.sel,
html[data-cast-scheme="dark"] .sidebar nav li:not(.has-subnav) > a.active-drop-target,
html[data-cast-scheme="dark"] .btngroup--exclusive .btn[aria-pressed="true"]:not(.disabled, .loading, .dashed, [aria-disabled]) {
    background-color: hsl(var(--gray-350-hsl));
}

/* The asset preview backdrop asks for `--gray-900`, meaning "near-black" on Craft's ramp.
   Inverted, that turns into a white band behind the image. */
html[data-cast-scheme="dark"] .preview-thumb-container {
    background-color: hsl(var(--gray-050-hsl));
}

html[data-cast-scheme="dark"] .element-index .source-path .chevron-btns {
    background: var(--pane-bg);
}

html[data-cast-scheme="dark"] .element-index .source-path .chevron-btns:before {
    border-block-start-color: var(--pane-bg);
}

html[data-cast-scheme="dark"] .element-index .source-path .chevron-btns:after {
    border-block-end-color: var(--pane-bg);
}

html[data-cast-scheme="dark"] .element-deletion-modal .body .edm-blockers .edm-details .element-index {
    background-color: var(--pane-bg) !important;
}

html[data-cast-scheme="dark"] .datatablesorthelper,
html[data-cast-scheme="dark"] .editabletablesorthelper {
    background-color: var(--pane-bg);
}

html[data-cast-scheme="dark"] .meta > .flex-fields blockquote.note,
html[data-cast-scheme="dark"] .meta > .flex-fields h2 {
    background-color: var(--secondary-pane-bg);
}

/* Loading and progress shades assume a light page underneath. */
html[data-cast-scheme="dark"] .icon-picker-modal .body .icon-picker-modal--list.loading:after,
html[data-cast-scheme="dark"] .cp-image-controls .progress-shade {
    background-color: rgb(0 0 0 / 60%);
}

/* The element index veils itself in white while refreshing, which flashes a bright
   block over the pane. Fade toward the pane colour instead. */
html[data-cast-scheme="dark"] .elements.busy:after {
    background: hsla(var(--gray-100-hsl), 0.75);
}

/* Field layout designer: every surface in it is `var(--white)`. */
html[data-cast-scheme="dark"] .fld-tab .fld-tabcontent,
html[data-cast-scheme="dark"] .fld-tab .tabs .tab,
html[data-cast-scheme="dark"] .layoutdesigner .fld-library,
html[data-cast-scheme="dark"] .fld-element,
html[data-cast-scheme="dark"] .entry-type-group {
    background-color: var(--pane-bg);
}

html[data-cast-scheme="dark"] .fld-new-tab-btn {
    background: var(--secondary-pane-bg) !important;
}

/* A field card is the one element in there Craft doesn't ring, marking it as a field
   rather than a UI element by fill alone — `--gray-100` on the tab's white. Inverted,
   that token *is* the tab's own colour, so the cards disappear into it while the UI
   elements around them keep their ring. A step up puts the distinction back. */
html[data-cast-scheme="dark"] .fld-element.fld-field {
    background-color: var(--cast-surface);
}

/* The tabs, their content, the library and the new-tab button are separated by a ring
   and a drop shadow struck in `rgba(31, 41, 51, …)` — a near-black that disappears into
   a dark canvas, leaving each of them edgeless. */
html[data-cast-scheme="dark"] .fld-tab .fld-tabcontent,
html[data-cast-scheme="dark"] .fld-tab .tabs .tab,
html[data-cast-scheme="dark"] .layoutdesigner .fld-library,
html[data-cast-scheme="dark"] .fld-new-tab-btn {
    box-shadow: 0 0 0 1px var(--border-hairline), 0 2px 5px -2px rgb(0 0 0 / 50%);
}

/* Same again for the card that follows the cursor while dragging. */
html[data-cast-scheme="dark"] .fld-element.draghelper {
    box-shadow: 0 1px 5px -1px rgb(0 0 0 / 50%);
}

/* A field's handle sits under its name as `.code`, meaning monospace rather than a code
   block — but it's a `<div>`, so the code-block fill below catches it and each card in
   the designer and its library ends up with a chip inside it. */
html[data-cast-scheme="dark"] .fld-element .code {
    background-color: transparent;
}

html[data-cast-scheme="dark"] .address-card {
    border-color: var(--border-hairline);
}

html[data-cast-scheme="dark"] .address-card:hover {
    background-color: var(--cast-surface);
    border-color: var(--border-hairline-dark);
}

html[data-cast-scheme="dark"] .address-card .address-card-label {
    background: var(--bg-notice);
    color: var(--fg-notice);
}

/* Vue admin tables, used by most Settings index screens. */
html[data-cast-scheme="dark"] .vue-admin-table-footer,
html[data-cast-scheme="dark"] .vuetable-pagination {
    background: var(--pane-bg) !important;
    border-top-color: var(--border-hairline);
}

html[data-cast-scheme="dark"] table thead th.sortable:hover {
    background-color: var(--cast-surface-hover);
}

/* --------------------------------------------------------------------------
   `.readable` regions (help text, plugin readmes, notes) set their own literal
   ink colours.
   -------------------------------------------------------------------------- */

html[data-cast-scheme="dark"] .readable .h1,
html[data-cast-scheme="dark"] .readable h1 {
    color: var(--text-color);
}

html[data-cast-scheme="dark"] .h6,
html[data-cast-scheme="dark"] h6,
html[data-cast-scheme="dark"] .readable .h6,
html[data-cast-scheme="dark"] .readable h6,
html[data-cast-scheme="dark"] .readable blockquote:not(.note) {
    color: var(--fg-subtle);
}

html[data-cast-scheme="dark"] .readable blockquote.note:not(.tip):not(.warning) {
    border-color: var(--border-error);
    color: var(--fg-error);
}

html[data-cast-scheme="dark"] .readable blockquote.note.tip {
    border-color: var(--border-notice);
    color: var(--fg-notice);
}

html[data-cast-scheme="dark"] .readable blockquote.note.warning:before {
    color: var(--fg-warning);
}

html[data-cast-scheme="dark"] .btn.caution.hover,
html[data-cast-scheme="dark"] .btn.caution:focus,
html[data-cast-scheme="dark"] .btn.caution:hover {
    background-color: var(--bg-error) !important;
    color: var(--fg-error);
}

/* --------------------------------------------------------------------------
   Prism, which Craft bundles with its stock light theme for syntax highlighting
   (email previews, the project config viewer).
   -------------------------------------------------------------------------- */

html[data-cast-scheme="dark"] code[class*="language-"],
html[data-cast-scheme="dark"] pre[class*="language-"] {
    color: var(--gray-800);
    text-shadow: none;
}

html[data-cast-scheme="dark"] :not(pre) > code[class*="language-"],
html[data-cast-scheme="dark"] pre[class*="language-"] {
    background: var(--cast-code-bg);
}

html[data-cast-scheme="dark"] .token.comment,
html[data-cast-scheme="dark"] .token.prolog,
html[data-cast-scheme="dark"] .token.doctype,
html[data-cast-scheme="dark"] .token.cdata {
    background: none;
    color: var(--gray-500);
}

html[data-cast-scheme="dark"] .token.punctuation {
    background: none;
    color: var(--gray-600);
}

html[data-cast-scheme="dark"] .token.boolean,
html[data-cast-scheme="dark"] .token.constant,
html[data-cast-scheme="dark"] .token.deleted,
html[data-cast-scheme="dark"] .token.number,
html[data-cast-scheme="dark"] .token.property,
html[data-cast-scheme="dark"] .token.symbol,
html[data-cast-scheme="dark"] .token.tag {
    background: none;
    color: #f0a1c8;
}

html[data-cast-scheme="dark"] .token.attr-name,
html[data-cast-scheme="dark"] .token.builtin,
html[data-cast-scheme="dark"] .token.char,
html[data-cast-scheme="dark"] .token.inserted,
html[data-cast-scheme="dark"] .token.selector,
html[data-cast-scheme="dark"] .token.string {
    background: none;
    color: #b5d97a;
}

html[data-cast-scheme="dark"] .language-css .token.string,
html[data-cast-scheme="dark"] .style .token.string,
html[data-cast-scheme="dark"] .token.entity,
html[data-cast-scheme="dark"] .token.operator,
html[data-cast-scheme="dark"] .token.url {
    background: none;
    color: #e0b57a;
}

html[data-cast-scheme="dark"] .token.atrule,
html[data-cast-scheme="dark"] .token.attr-value,
html[data-cast-scheme="dark"] .token.keyword {
    background: none;
    color: #7fc4e8;
}

/* --------------------------------------------------------------------------
   Status labels. Craft tints the pill to 15% of the status colour and sets its
   text to that hue's 900, a near-black meant for a light page. Each takes the
   300 shade instead, with the tint raised slightly to keep the pill readable.
   -------------------------------------------------------------------------- */

html[data-cast-scheme="dark"] .status-label {
    background-color: rgb(from var(--status-label-bg-color) r g b / 22%);
}

html[data-cast-scheme="dark"] .status-label.red {
    --status-label-text-color: var(--red-300);
}

html[data-cast-scheme="dark"] .status-label.amber {
    --status-label-text-color: var(--amber-300);
}

html[data-cast-scheme="dark"] .status-label.orange {
    --status-label-text-color: var(--orange-300);
}

html[data-cast-scheme="dark"] .status-label.yellow {
    --status-label-text-color: var(--yellow-300);
}

html[data-cast-scheme="dark"] .status-label.lime {
    --status-label-text-color: var(--lime-300);
}

html[data-cast-scheme="dark"] .status-label.green {
    --status-label-text-color: var(--green-300);
}

html[data-cast-scheme="dark"] .status-label.emerald {
    --status-label-text-color: var(--emerald-300);
}

/* Craft treats `teal` and `turquoise` as the same status — enabled elements use `teal`. */
html[data-cast-scheme="dark"] .status-label.teal,
html[data-cast-scheme="dark"] .status-label.turquoise {
    --status-label-text-color: var(--teal-300);
}

html[data-cast-scheme="dark"] .status-label.cyan {
    --status-label-text-color: var(--cyan-300);
}

html[data-cast-scheme="dark"] .status-label.sky {
    --status-label-text-color: var(--sky-300);
}

html[data-cast-scheme="dark"] .status-label.blue {
    --status-label-text-color: var(--blue-300);
}

html[data-cast-scheme="dark"] .status-label.indigo {
    --status-label-text-color: var(--indigo-300);
}

html[data-cast-scheme="dark"] .status-label.violet {
    --status-label-text-color: var(--violet-300);
}

html[data-cast-scheme="dark"] .status-label.purple {
    --status-label-text-color: var(--purple-300);
}

html[data-cast-scheme="dark"] .status-label.fuchsia {
    --status-label-text-color: var(--fuchsia-300);
}

html[data-cast-scheme="dark"] .status-label.pink {
    --status-label-text-color: var(--pink-300);
}

html[data-cast-scheme="dark"] .status-label.rose {
    --status-label-text-color: var(--rose-300);
}

/* `black` sets its text to a literal `--black`, which Cast leaves as true black. */
html[data-cast-scheme="dark"] .status-label.black {
    --status-label-text-color: var(--gray-800);
}

/* --------------------------------------------------------------------------
   Live Preview. Its two panels are painted `--white`, and their headers a fixed
   frosted light blue, so the whole frame stays light over a dark CP.
   -------------------------------------------------------------------------- */

html[data-cast-scheme="dark"] .lp-editor-container,
html[data-cast-scheme="dark"] .lp-preview-container {
    background-color: var(--pane-bg);
}

html[data-cast-scheme="dark"] .lp-editor-container > header,
html[data-cast-scheme="dark"] .lp-preview-container > header,
html[data-cast-scheme="dark"] .lp-preview-container .lp-preview-header {
    background-color: hsla(var(--gray-100-hsl), 0.75);
    box-shadow: 0 1px 0 var(--border-hairline);
}

/* The device-type icons are dark line art, drawn for a light toolbar. */
html[data-cast-scheme="dark"] .lp-preview-container .lp-preview-header .lp-device-type .btn:before,
html[data-cast-scheme="dark"] .lp-preview-container .lp-device-type__label:before {
    filter: invert(1);
}

/* Craft fills a Matrix block or a card with `--gray-050`. On light that's the step above
   white, so it rises off the pane it's inset into; inverted, the same token is the ramp's
   floor and it sinks below the pane instead, reading as a hole rather than a panel. A
   lift off the pane's own colour restores the relationship whatever a theme puts at the
   floor — and holds up where the pane is already black. Colour-coded ones keep their own
   fill, which is mixed over the pane below and lands lighter anyway. */
html[data-cast-scheme="dark"] :is(.matrixblock, .card):not(.chromeless, .hairline) {
    background-color: var(--custom-bg-color, color-mix(in srgb, var(--pane-bg) 92%, #fff));
}

/* The ring around one is `--gray-200`, which inverts to a step that barely clears the
   fill it now encloses. The next one up holds the edge without it shouting. Colour-coded
   blocks are left to the accent ring set in the section below. */
html[data-cast-scheme="dark"] :is(.matrixblock, .card):not(.chromeless, [style*="--custom-"]):before {
    box-shadow: inset 0 0 0 1px hsl(var(--gray-300-hsl));
}

/* --------------------------------------------------------------------------
   Colour-coded elements. An entry type, category group, or component with a
   colour gets it inline, as four fixed shades of that hue: a `050` wash for the
   background, `100` for a titlebar, `200` for the border, and `900` — near-black
   — for text. Only the border shade survives inversion, so the rest are rebuilt
   from it, which keeps the hue while the surfaces follow the theme.
   -------------------------------------------------------------------------- */

/* Inline styles, so these have to be important to land. `--custom-border-color` is
   deliberately left alone: it's the accent the others are mixed from, and redefining it
   here would leave those mixes resolving against their own result. */
html[data-cast-scheme="dark"] [style*="--custom-"] {
    --custom-bg-color: color-mix(in srgb, var(--custom-border-color, transparent) 12%, var(--pane-bg)) !important;
    --custom-titlebar-bg-color: color-mix(in srgb, var(--custom-border-color, transparent) 20%, var(--pane-bg)) !important;
    --custom-sel-bg-color: color-mix(in srgb, var(--custom-border-color, transparent) 35%, var(--pane-bg)) !important;
    --custom-sel-titlebar-bg-color: color-mix(in srgb, var(--custom-border-color, transparent) 45%, var(--pane-bg)) !important;
    --custom-text-color: var(--custom-border-color, var(--text-color)) !important;
}

/* Selected sits a step above the resting tint rather than jumping to a solid fill, which
   on a Matrix block would swamp the fields inside it. */
html[data-cast-scheme="dark"] [style*="--custom-"].sel {
    --custom-bg-color: color-mix(in srgb, var(--custom-border-color, transparent) 22%, var(--pane-bg)) !important;
    --custom-titlebar-bg-color: color-mix(in srgb, var(--custom-border-color, transparent) 30%, var(--pane-bg)) !important;
}

/* The outline is an inset ring on a pseudo-element, not a border, and at full strength
   it's the loudest thing on the block. The variable itself keeps the full shade, so the
   mixes above still have an accent to work from. */
html[data-cast-scheme="dark"] [style*="--custom-"]:not(.chromeless):before {
    box-shadow: inset 0 0 0 1px rgb(from var(--custom-border-color, transparent) r g b / 40%);
}

/* --------------------------------------------------------------------------
   CodeMirror, which the JSON field and a few settings screens run on. Craft
   points `.CodeMirror` at `--input-bg` in its own stylesheet, then loads
   CodeMirror's after it, where the same selector paints the editor `#fff` — so
   the field lands white on every dark theme. Its default syntax theme is a set
   of dark inks chosen for that white ground, so the tokens are rebuilt too.
   -------------------------------------------------------------------------- */

html[data-cast-scheme="dark"] .CodeMirror {
    background: var(--input-bg);
    color: var(--text-color);
}

html[data-cast-scheme="dark"] .CodeMirror-gutter-filler,
html[data-cast-scheme="dark"] .CodeMirror-scrollbar-filler {
    background-color: var(--input-bg);
}

html[data-cast-scheme="dark"] .CodeMirror-gutters {
    background-color: hsl(var(--gray-100-hsl));
    border-inline-end-color: var(--border-hairline);
}

html[data-cast-scheme="dark"] .CodeMirror-linenumber {
    color: var(--light-text-color);
}

html[data-cast-scheme="dark"] .CodeMirror-cursor {
    border-inline-start-color: var(--text-color);
}

html[data-cast-scheme="dark"] .CodeMirror-selected {
    background: var(--bg-selection-light);
}

html[data-cast-scheme="dark"] .CodeMirror-focused .CodeMirror-selected {
    background: var(--bg-selection-dark);
}

html[data-cast-scheme="dark"] .CodeMirror-activeline-background {
    background: hsl(var(--gray-150-hsl));
}

html[data-cast-scheme="dark"] div.CodeMirror span.CodeMirror-matchingbracket {
    color: var(--green-300);
}

/* The tokens, at the 300 step of the hue each one carries on light. */
html[data-cast-scheme="dark"] .cm-s-default .cm-header,
html[data-cast-scheme="dark"] .cm-s-default .cm-def,
html[data-cast-scheme="dark"] .cm-s-default .cm-attribute,
html[data-cast-scheme="dark"] .cm-s-default .cm-link {
    color: var(--blue-300);
}

html[data-cast-scheme="dark"] .cm-s-default .cm-keyword,
html[data-cast-scheme="dark"] .cm-s-default .cm-builtin {
    color: var(--purple-300);
}

html[data-cast-scheme="dark"] .cm-s-default .cm-atom {
    color: var(--indigo-300);
}

html[data-cast-scheme="dark"] .cm-s-default .cm-quote,
html[data-cast-scheme="dark"] .cm-s-default .cm-tag,
html[data-cast-scheme="dark"] .cm-s-default .cm-number {
    color: var(--green-300);
}

html[data-cast-scheme="dark"] .cm-s-default .cm-variable-2 {
    color: var(--sky-300);
}

html[data-cast-scheme="dark"] .cm-s-default .cm-type,
html[data-cast-scheme="dark"] .cm-s-default .cm-variable-3 {
    color: var(--teal-300);
}

html[data-cast-scheme="dark"] .cm-s-default .cm-comment,
html[data-cast-scheme="dark"] .cm-s-default .cm-string-2 {
    color: var(--orange-300);
}

html[data-cast-scheme="dark"] .cm-s-default .cm-string {
    color: var(--red-300);
}

html[data-cast-scheme="dark"] .cm-s-default .cm-meta,
html[data-cast-scheme="dark"] .cm-s-default .cm-qualifier,
html[data-cast-scheme="dark"] .cm-s-default .cm-bracket,
html[data-cast-scheme="dark"] .cm-s-default .cm-hr {
    color: var(--light-text-color);
}

html[data-cast-scheme="dark"] .cm-s-default .cm-error {
    color: var(--fg-error);
}

/* --------------------------------------------------------------------------
   CKEditor. The plugin already maps most of CKEditor's `--ck-*` variables onto
   Craft's tokens, so the editor follows a theme on its own — except the toolbar
   and floating panels, which it pins to `--white`. Its declarations are
   `!important` on `:root`, so these are too, and win on specificity.
   -------------------------------------------------------------------------- */

html[data-cast-scheme="dark"] {
    --ck-color-toolbar-background: var(--cast-surface) !important;
    --ck-color-panel-background: var(--cast-surface) !important;
    --ck-color-dropdown-panel-background: var(--cast-surface) !important;

    /* Dialogs reach for `--ck-custom-background`, which nothing defines. */
    --ck-color-dialog-background: var(--cast-surface) !important;
    --ck-color-dialog-form-header-border: var(--border-hairline) !important;
}

/* Buttons floating over an asset preview. `--ui-control-bg` is a light wash once the
   ramp inverts, so they bleach out against the image instead of sitting on it. */
html[data-cast-scheme="dark"] .image-actions .btn,
html[data-cast-scheme="dark"] .cp-image-controls .btn {
    --ui-control-bg-color: rgb(0 0 0 / 55%);
    --ui-control-hover-bg-color: rgb(0 0 0 / 70%);
    --ui-control-active-bg-color: rgb(0 0 0 / 80%);
    --ui-control-color: #fff;

    color: #fff;
}

/* --------------------------------------------------------------------------
   Image editor. Craft's one already-dark screen, but it gets there by reaching
   for the dark end of the ramp — `--gray-900` for the canvas, `--gray-1000` for
   its rules, `--gray-600` for buttons. Inverted, the whole modal turns white, so
   it's pinned to fixed values rather than tracking a theme.
   -------------------------------------------------------------------------- */

html[data-cast-scheme="dark"] .modal.imageeditor {
    background-color: var(--cast-editor-canvas);
    color: #fff;
}

html[data-cast-scheme="dark"] .modal.imageeditor .body .tabs,
html[data-cast-scheme="dark"] .modal.imageeditor .body .tabs ul li {
    border-color: var(--cast-editor-rule);
}

/* The straightening rule fades its ends out to `--gray-900`, so the fade has to be
   restated against the canvas colour above. */
html[data-cast-scheme="dark"] .slide-rule .overlay {
    background-image: linear-gradient(
        to right,
        var(--cast-editor-canvas) 0,
        rgb(0 0 0 / 0%) 15%,
        rgb(0 0 0 / 0%) 85%,
        var(--cast-editor-canvas) 100%
    );
}

html[data-cast-scheme="dark"] .modal.imageeditor .btn:not(.submit, .noborder) {
    background-color: var(--cast-editor-btn);
    color: #fff;
}

html[data-cast-scheme="dark"] .modal.imageeditor .btn:not(.submit, .noborder):hover {
    background-color: var(--cast-editor-btn-hover);
}

html[data-cast-scheme="dark"] .modal.imageeditor .btn:not(.submit, .noborder).active {
    background-color: var(--cast-editor-btn-active);
}

/* --------------------------------------------------------------------------
   Per-screen strays: light rules and insets in the CSS Craft ships with
   individual utilities and settings screens.
   -------------------------------------------------------------------------- */

/* System messages (Settings → Email) */
html[data-cast-scheme="dark"] .message .subject {
    border-block-end-color: var(--border-hairline);
}

html[data-cast-scheme="dark"] .message .body {
    color: var(--gray-600);
}

html[data-cast-scheme="dark"] table.editable tbody tr th ~ td:not(:first-child) {
    border-inline-start-color: var(--border-hairline);
}

html[data-cast-scheme="dark"] .user-permissions h3:has(+ .select-all) {
    border-inline-end-color: var(--border-hairline);
}

html[data-cast-scheme="dark"] .user-permissions ul ul li:before {
    border-block-start-color: var(--border-hairline);
}

html[data-cast-scheme="dark"] .route-settings .uri-tokens {
    box-shadow: inset 0 1px 3px -1px rgb(0 0 0 / 60%);
}

html[data-cast-scheme="dark"] div.user-photo-controls .progress-shade {
    background-color: rgb(0 0 0 / 60%);
}

/* The icon preview is painted `--gray-050` and edged with `--input-border`, a variable
   Craft never defines, so it lands on the ramp's darkest step with whatever border the
   browser falls back to — lighter than the buttons alongside it. */
html[data-cast-scheme="dark"] .icon-picker--icon {
    background: var(--input-bg);
    border: 1px solid var(--input-border-color);
}

/* Selectize's own stylesheet predates Craft's variables entirely. */
html[data-cast-scheme="dark"] .selectize-input,
html[data-cast-scheme="dark"] .selectize-dropdown,
html[data-cast-scheme="dark"] .selectize-input.dropdown-active:before,
html[data-cast-scheme="dark"] .selectize-dropdown.plugin-dropdown_header .selectize-dropdown-header,
html[data-cast-scheme="dark"] .selectize-control.plugin-remove_button .item .remove {
    border-color: var(--input-border-color);
}

/* --------------------------------------------------------------------------
   Craft embeds a few light-mode raster assets (the sidebar logo lockup, some
   empty states) with no CSS hook. Taking the edge off beats shipping dark
   duplicates.
   -------------------------------------------------------------------------- */

html[data-cast-scheme="dark"] #global-sidebar .system-name img,
html[data-cast-scheme="dark"] .zilch img {
    filter: brightness(0.85) contrast(1.05);
}

/* Craft also puts `.code` on form controls (handle fields, template pickers) where it
   means monospace, not code block. Those are excluded so they keep the input
   background and match the text fields beside them.

   `.light` goes with them. Craft pairs the two on a muted monospace label rather than a
   block — a colour field's `#` prefix, a menu item's description — and puts it on an
   editable table's cells for a monospace column. A block fill behind any of them is a
   grey slab in the middle of a control. */
html[data-cast-scheme="dark"] pre,
html[data-cast-scheme="dark"] .code:not(input, textarea, select, .text, .light, td, th) {
    background-color: var(--cast-code-bg);
    color: var(--gray-800);
}

/* Monospace form controls stay on the input background, so a handle or template field
   matches the text fields beside it. */
html[data-cast-scheme="dark"] input.code,
html[data-cast-scheme="dark"] textarea.code,
html[data-cast-scheme="dark"] select.code,
html[data-cast-scheme="dark"] .code > input.text,
html[data-cast-scheme="dark"] .code > textarea {
    background-color: var(--input-bg);
}

/* Craft drops the background on a `<pre>` that fills a pane (the project config viewer)
   so the pane's own padding surrounds it. Repainting it leaves a mismatched gutter. */
html[data-cast-scheme="dark"] .pane pre,
html[data-cast-scheme="dark"] .pane pre code {
    background-color: transparent;
}
