/* =============================================================================
   BRIDGE - Dash core components (dcc) -> theme roles
   -----------------------------------------------------------------------------
   dcc.Slider / dcc.RangeSlider (rc-slider), dcc.Dropdown (react-select v1),
   dcc.Loading and dash_table.DataTable ship their own light-theme colors. Dash injects those styles at runtime,
   AFTER the files in assets/, so every rule here is prefixed with
   [data-bs-theme] to win on specificity instead of load order.

   Only var(--color-...) here. Module-specific dropdown styling (fields,
   options, chips) lives in the module CSS; how every multi-select behaves
   (one line, "N selected") is here, so all modules share it.
   ============================================================================= */

/* ---- Sliders --------------------------------------------------------------- */
/* Thin 2px line with a 12px ring. rc-slider centres everything on y = 7px of
   its 14px box: the line sits at 6-8px, the ring at 1-13px. */
[data-bs-theme] .rc-slider-rail,
[data-bs-theme] .rc-slider-track {
    height: 2px;
    margin-top: 1px;
}

[data-bs-theme] .rc-slider-rail {
    background-color: var(--color-border-strong);
}

[data-bs-theme] .rc-slider-track {
    background-color: var(--color-accent-strong);
}

/* Hollow ring: the center is painted with the panel color (not literally
   transparent, which would let the track line show through the ring). */
[data-bs-theme] .rc-slider-handle {
    width: 12px;
    height: 12px;
    margin-top: -4px;
    border-width: 2px;
    background-color: var(--color-surface);
    border-color: var(--color-accent-strong);
    opacity: 1;
}

[data-bs-theme] .rc-slider-handle:hover,
[data-bs-theme] .rc-slider-handle:active,
[data-bs-theme] .rc-slider-handle-dragging.rc-slider-handle-dragging.rc-slider-handle-dragging {
    border-color: var(--color-accent-hover);
    box-shadow: 0 0 0 4px var(--color-focus-ring);
}

[data-bs-theme] .rc-slider-dot {
    background-color: var(--color-text-strong);
    border-color: var(--color-border-strong);
}

[data-bs-theme] .rc-slider-dot-active {
    border-color: var(--color-accent-strong);
}

[data-bs-theme] .rc-slider-mark-text {
    color: var(--color-text-muted);
}

[data-bs-theme] .rc-slider-mark-text-active {
    color: var(--color-text);
}

[data-bs-theme] .rc-slider-tooltip-inner {
    background-color: var(--color-surface-raised);
    color: var(--color-text-strong);
    box-shadow: var(--shadow-raised);
}

[data-bs-theme] .rc-slider-disabled {
    background-color: transparent;
}

/* ---- Dropdown arrow (react-select v1) --------------------------------------- */
[data-bs-theme] .Select-arrow {
    border-top-color: var(--color-text-muted);
}

[data-bs-theme] .Select-arrow-zone:hover > .Select-arrow {
    border-top-color: var(--color-text);
}

[data-bs-theme] .is-open > .Select-control .Select-arrow {
    border-bottom-color: var(--color-text-muted);
}

/* ---- Dropdown inside an input group (label + field) --------------------------- */
/* Bootstrap squares the inner corners of an input group's direct children, so
   a label and its field meet on a flat edge and only the group's outer corners
   are round. A dcc.Dropdown draws its border one level deeper (.Select-control,
   inside a wrapper div), which Bootstrap doesn't reach, so its left corners
   stayed round against the label's flat edge. Same rule, one level deeper. */
[data-bs-theme] .input-group > :not(:first-child) .Select-control {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
}

[data-bs-theme] .input-group > :not(:last-child) .Select-control {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}

/* ---- Multi-select dropdowns: one line, every module --------------------------- */
/* Every multi-select keeps one row's height, whatever is selected (the Dash 4
   dropdown behaves the same, plans/dash-4-upgrade.md):
     - at rest: as many chips (each with its ×) as fit on the line; once
       they don't all fit, the ones that do and then "N selected", with every
       name in the tooltip. multi_select_fit.js measures the line;
     - with focus: the field opens over the rows below (every chip, the search
       box) and folds back to one line on blur. The row under it keeps its
       height, so nothing moves or overlaps.
   Keyed on the dropdown itself (.Select--multi) and on the wrapper that
   dp_select_multi / dd_data_source put around it, so current and future
   multi-selects all behave the same. --dd-multi-h is the resting height
   (a panel with taller rows sets its own). react-select v1 internals; the
   grouped dropdown (dpg-*) follows the same look in its module CSS. */

/* Lets multi_select_fit.js notice a field when it appears (animationstart),
   without watching the page. Changes nothing visible. */
@keyframes dd-fit-mount {
    from { outline-offset: 0; }
    to { outline-offset: 0; }
}

[data-bs-theme] .Select--multi .Select-control {
    animation: dd-fit-mount 1ms;
}

/* Beside its label. With an automatic basis the chips' full width pushed
   the field onto a line of its own under the label. */
[data-bs-theme] .input-group > .dp-select-multi-wrapper {
    flex: 1 1 0;
    min-width: 0;
}

/* A flex row, not react-select's table: the chips area takes what the ×
   and ▾ leave, and shrinks with the field. */
[data-bs-theme] .Select--multi .Select-control {
    display: flex;
    align-items: center;
    counter-reset: dd-selected;
}

[data-bs-theme] .Select--multi .Select-multi-value-wrapper {
    display: block;
    flex: 1 1 auto;
    min-width: 0;
}

/* Each chip on one line (× and name together), long names cut with "…". */
[data-bs-theme] .Select--multi .Select-value {
    counter-increment: dd-selected;
    display: inline-flex;
    max-width: calc(100% - 10px);
    white-space: nowrap;
}

[data-bs-theme] .Select--multi .Select-value-label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Same chip as the grouped dropdown's (.dpg-chip): compact, name first,
   × after it. react-select puts the × first behind a divider. */
[data-bs-theme] .Select--multi .Select-value {
    align-items: center;
    gap: 4px;
    margin-left: 4px;
    padding: 1px 4px 1px 6px;
    border-radius: 3px !important;
    background-color: var(--color-state-pressed) !important;   /* over ".Select div", which paints every div the field color */
    font-size: var(--text-sm) !important;
    line-height: 1.4 !important;
}

[data-bs-theme] .Select--multi .Select-value-label {
    padding: 0;
    font-size: var(--text-sm) !important;
}

[data-bs-theme] .Select--multi .Select-value-icon {
    order: 2;
    padding: 0 2px;
    border: 0 !important;
    font-weight: 600;
}

[data-bs-theme] .Select--multi .Select-value-icon:hover {
    background-color: transparent !important;
    color: var(--color-danger) !important;
}

[data-bs-theme] .Select--multi .Select-clear-zone,
[data-bs-theme] .Select--multi .Select-arrow-zone {
    flex: none;
}

/* The placeholder spans the whole control; stop it before the ▾. */
[data-bs-theme] .Select--multi .Select-placeholder {
    padding-right: 30px;
}

/* At rest: the chips on one line, centered in the field. */
[data-bs-theme] .Select--multi:not(.is-focused) .Select-multi-value-wrapper {
    white-space: nowrap;
    overflow: hidden;
    min-height: 0 !important;
    padding: 0 0 0 1px !important;
    line-height: 0;   /* the line box is the chips only, so the flex row centers them */
}

[data-bs-theme] .Select--multi:not(.is-focused) .Select-value {
    margin-top: 0;
    vertical-align: middle;
}

/* The idle search box is taken out of the line (an empty inline box still
   claims one). It stays focusable for the keyboard. */
[data-bs-theme] .Select--multi.has-value:not(.is-focused) .Select-input {
    position: absolute;
    width: 1px;
    height: 1px !important;
    overflow: hidden;
    opacity: 0;
}

/* Too many chips for the line: the ones that fit stay, the rest are taken
   out of the line (still laid out, invisible, so multi_select_fit.js can
   measure them) and "N selected" follows the last chip shown. */
[data-bs-theme] {
    --dd-badge-w: 80px;   /* room kept for "N selected" (up to "99 selected") */
}

[data-bs-theme] .Select--multi:not(.is-focused) .Select-multi-value-wrapper {
    position: relative;
}

[data-bs-theme] .Select--multi:not(.is-focused) .Select-value[data-dd-hidden] {
    position: absolute;
    top: 0;
    left: 0;
    visibility: hidden;
    pointer-events: none;
}

/* Not even one chip fits next to the badge: the first one is cut with "…". */
[data-bs-theme] .Select--multi:not(.is-focused) .Select-control[data-collapsed] .Select-value:first-child {
    max-width: calc(100% - var(--dd-badge-w));
}

[data-bs-theme] .Select--multi:not(.is-focused) .Select-control[data-collapsed] .Select-multi-value-wrapper::after {
    content: counter(dd-selected) " selected";
    display: inline-block;
    vertical-align: middle;
    margin-left: 6px;
    padding: 0 6px;
    border-radius: var(--bs-border-radius-sm);
    background-color: var(--color-accent-subtle);
    color: var(--color-field-text);
    font-size: var(--text-sm);
    line-height: 18px;
    white-space: nowrap;
}

/* With focus: the field floats over the rows below, at the same place and
   width. The dropdown's own box keeps the resting height, so the row does
   not grow. */
[data-bs-theme] .dash-dropdown:has(> .Select--multi) {
    position: relative;
}

[data-bs-theme] .dash-dropdown:has(> .Select--multi.is-focused) {
    height: var(--dd-multi-h, 30px);
}

[data-bs-theme] .dash-dropdown > .Select--multi.is-focused {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: 20;
}

[data-bs-theme] .Select--multi.is-focused .Select-multi-value-wrapper {
    padding-bottom: 5px !important;   /* chips carry a 5px top margin */
}

[data-bs-theme] .Select--multi.is-focused.has-value > .Select-control {
    box-shadow: var(--shadow-raised) !important;
}

/* ---- Loading spinner (dcc.Loading type="circle") ---------------------------- */
/* dcc.Loading paints the dots from its `color` prop through an injected
   <style>; this rule colors them from the theme, so layouts pass no color. */
[data-bs-theme] .dash-sk-circle .dash-sk-child::before {
    background-color: var(--color-accent);
}

/* ---- DataTable (dash_table) -------------------------------------------------- */
/* Default look for every DataTable: app font, body text, soft row lines, cells
   transparent on their panel. DataTable injects its own CSS after the assets
   (hence the .dash-table-container step) and writes borders inline (hence
   !important on the border color only). Tables with their own look (Decline
   Analysis, AI chat) override this with more specific rules in their module. */
[data-bs-theme] .dash-table-container .dash-spreadsheet-container .dash-spreadsheet-inner table {
    font-family: var(--font-sans);
    font-size: var(--text-base);
    font-variant-numeric: tabular-nums;
}

[data-bs-theme] .dash-table-container .dash-spreadsheet-container .dash-spreadsheet-inner th,
[data-bs-theme] .dash-table-container .dash-spreadsheet-container .dash-spreadsheet-inner td {
    background-color: transparent;
    color: var(--color-text);
    border-color: var(--color-border) !important;
}

[data-bs-theme] .dash-table-container .dash-spreadsheet-container .dash-spreadsheet-inner th {
    font-weight: 600;
}
