/* X.2.l.4.c — theme the filter widgets onto the L2 semantic tokens.
 *
 * Tom Select / Flatpickr / noUiSlider each ship their own base CSS
 * (linked in the page shell as ``{tom-select,flatpickr,nouislider}.min.css``);
 * those use fixed colours. This sheet loads AFTER them and rewrites
 * the colour-bearing rules in terms of the ``--color-*`` CSS variables
 * the page shell injects per L2 instance (``render.py`` :root <style>;
 * defaults from ``input.css``'s @theme). So a fresh L2 theme recolours
 * the widgets without rebuilding anything — same trick as the Tailwind
 * utilities.
 *
 * Not Tailwind-processed — plain CSS, served as ``/static/widgets-theme.css``.
 *
 * Accessibility (carries the X.2.l.4 rule): colour is never the only
 * indicator — chips have an ✕ remove affordance, the active dropdown
 * row is bold + tinted, the picker's "today" cell gets an outline (not
 * just a fill), the slider handles are circles with a border, and the
 * slider tooltips show the numeric values as text.
 */

/* ---------------------------------------------------------------- */
/* Tom Select — single + multi <select> enhancement                  */
/* ---------------------------------------------------------------- */
.ts-control {
  background: var(--color-surface);
  border: 1px solid var(--color-surface-border);
  color: var(--color-primary-fg);
  border-radius: 0.375rem;
  box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
}
.ts-wrapper.focus .ts-control {
  border-color: var(--color-accent);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-accent) 35%, transparent);
}
.ts-control input,
.ts-control input::placeholder {
  color: var(--color-secondary-fg);
}
.ts-dropdown {
  background: var(--color-surface);
  border: 1px solid var(--color-surface-border);
  color: var(--color-primary-fg);
  box-shadow: 0 4px 10px 0 rgb(0 0 0 / 0.12);
}
.ts-dropdown .option:hover,
.ts-dropdown .option.active,
.ts-dropdown .active {
  background: var(--color-link-tint);
  color: var(--color-primary-fg);
  font-weight: 600; /* a11y: not colour-only */
}
.ts-dropdown .optgroup-header {
  color: var(--color-secondary-fg);
}
/* Multi-select chips. */
.ts-wrapper.multi .ts-control > .item {
  background: var(--color-accent);
  color: var(--color-accent-fg);
  border: 1px solid var(--color-accent);
  border-radius: 0.25rem;
}
.ts-wrapper.multi .ts-control > .item.active {
  background: color-mix(in srgb, var(--color-accent) 80%, black);
}
.ts-wrapper.multi .ts-control > .item .remove {
  border-left-color: color-mix(in srgb, var(--color-accent-fg) 40%, transparent);
}
.ts-wrapper.multi .ts-control > .item .remove:hover {
  background: color-mix(in srgb, black 18%, var(--color-accent));
}

/*
 * 2026-06-12 — Tom Select clear_button positioning + visual override.
 *
 * Positioning fix: the vendor CSS positions the × via
 *   .plugin-clear_button.single .clear-button { right: max(--ts-pr-caret, 8px) }
 * which resolves to right: 8px, but the renderer copies Tailwind
 * utility classes from the original <select> onto .ts-wrapper (px-3
 * py-2 min-w-48 etc), and the cascade causes `left: 8px` to also be
 * applied to the clear-button. With both left + right set on a
 * position:absolute element, the browser stretches it horizontally,
 * rendering the × glyph at the LEFT edge of the picker. Pin left:auto
 * to keep the × on the right.
 *
 * Visual fix: the bare vendor styling renders the × small + flush
 * against the trailing text (no breathing room, no hover affordance).
 * Pad the input so text reserves space for the button; size + circle
 * the button so it reads as an obvious affordance with hover state.
 */
.ts-wrapper.plugin-clear_button .clear-button,
.ts-wrapper.plugin-clear_button.single .clear-button {
  left: auto;
  right: 0.375rem;
  /* Vertically center the absolute-positioned button regardless of the
   * .ts-control's height (which varies with the Tailwind py-* utility
   * copied onto .ts-wrapper). Override the vendor's fixed top: 8px. */
  top: 50%;
  transform: translateY(-50%);
  /* Larger, circular click target with subtle hover background. */
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 9999px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Hide the vendor's ⨯ text node (U+2A2F — a math operator whose ink
   * centers on the math-axis, not the line-box geometric center; visibly
   * floats above the text baseline). The replacement glyph is injected
   * via ::before below. ``font-size: 0`` is the standard trick (rather
   * than ``visibility: hidden`` on a child) — Tom Select sets the text
   * node directly on the button, not in a wrappable child element. */
  font-size: 0;
  color: var(--color-secondary-fg);
  transition: background-color 0.15s ease, color 0.15s ease, opacity 0.15s ease;
}
.ts-wrapper.plugin-clear_button .clear-button::before {
  /* U+2715 MULTIPLICATION X — canonical UI close glyph; font designers
   * center it as a standalone symbol (unlike U+2A2F which centers on
   * the math-axis). Optically aligns with surrounding text. */
  content: "\2715";
  font-size: 1.1rem;
  font-weight: 600;
  line-height: 1;
}
.ts-wrapper.plugin-clear_button .clear-button:hover {
  background: color-mix(in srgb, var(--color-danger, #C62828) 12%, transparent);
  color: var(--color-danger, #C62828);
}
/* Reserve right-padding inside .ts-control so text doesn't run under
 * the × button. Without this the selected-item text overlaps with
 * the click target. */
.ts-wrapper.plugin-clear_button .ts-control {
  padding-right: 1.75rem !important;
}

/* ---------------------------------------------------------------- */
/* Phase DA — Table cell decoration for drillable columns            */
/* ---------------------------------------------------------------- */
/* The App2 renderer paints these classes on <td> when the column's
 * Drillable resolves to a decoration kind. Decisions live in
 * common/tree/formatting.py::Drillable.visual_kind() — App2 + QS use
 * the same code path so the cue stays in parity.
 *
 *   .cell-accent       — column carries CLICK-only drill(s) (accent text)
 *   .cell-accent-menu  — column carries at least one MENU drill (accent
 *                        text + tint background; left-click on the cell
 *                        opens the menu via bootstrap.js::wireRowDrills)
 *
 * The tint hue mirrors the QS-side _tint_hex (10% accent / 90% white) —
 * by visual intent, not pixel: QS needs a solid hex while App2 uses
 * color-mix against transparent, which composites slightly differently.
 *
 * Convention exception (operator-locked at DA.0): a left-click on a
 * cell-accent-menu cell goes RIGHT (opens the menu drill) — breaks the
 * "left moves LEFT" rule because the explicit visual cue makes the
 * affordance discoverable. The row-level left-click stays inert (per
 * the row-drill MENU contract; see bootstrap.js commit 279c52c8). */
.cell-accent {
  color: var(--color-accent);
  font-weight: 500;
}
.cell-accent-menu {
  color: var(--color-accent);
  background: color-mix(in srgb, var(--color-accent) 10%, transparent);
  font-weight: 500;
  cursor: pointer;
  transition: background-color 0.15s ease;
}
.cell-accent-menu:hover {
  background: color-mix(in srgb, var(--color-accent) 20%, transparent);
}

/* ---------------------------------------------------------------- */
/* Flatpickr — date-range popover                                    */
/* ---------------------------------------------------------------- */
.flatpickr-calendar {
  background: var(--color-surface);
  box-shadow: 0 6px 18px 0 rgb(0 0 0 / 0.18);
}
.flatpickr-months .flatpickr-month,
.flatpickr-current-month .flatpickr-monthDropdown-months,
.flatpickr-current-month input.cur-year,
.flatpickr-weekday {
  color: var(--color-primary-fg);
}
.flatpickr-day {
  color: var(--color-primary-fg);
}

/* DM.3 — day-availability decoration (App2-only). The Daily Statement
 * Business Day picker marks the two INDEPENDENT per-day flags so
 * transaction-days and balance-days stay distinguishable in ANY theme.
 * Colour can't carry the distinction — a theme may resolve accent ≈
 * secondary-fg (sasquatch resolves BOTH green) — so the two channels are
 * FILL vs STROKE, which are theme-independent:
 *   - .has-transactions → soft accent FILL behind the day: postable
 *                         records present (the activity signal).
 *   - .has-balance      → accent RING (inset box-shadow) around the day:
 *                         an end-of-day balance is present.
 *   - .has-both → fill + ring · tx-only → fill only · balance-only
 *     (carry day) → ring only · no data → blank.
 * The fill is a pale 20% tint and the ring a full-strength stroke, so on
 * a both-day the ring still reads as a crisp line over the wash. The
 * fill rule sits ABOVE flatpickr's :hover/.today/.selected/.inRange
 * rules below so those interaction states still own the cell background;
 * the ring (box-shadow) overlays them. DECORATION not restriction —
 * every day stays clickable. Colours derive from theme tokens. */
.flatpickr-day.has-transactions {
  background: color-mix(in srgb, var(--color-accent) 20%, var(--color-surface));
}
.flatpickr-day.has-balance {
  box-shadow: inset 0 0 0 2px var(--color-accent);
}

.flatpickr-day:hover,
.flatpickr-day.prevMonthDay:hover,
.flatpickr-day.nextMonthDay:hover {
  background: var(--color-link-tint);
  border-color: var(--color-link-tint);
}
.flatpickr-day.today {
  border-color: var(--color-accent); /* a11y: outline, not a fill */
}
.flatpickr-day.today:hover {
  background: var(--color-link-tint);
  color: var(--color-primary-fg);
}
.flatpickr-day.selected,
.flatpickr-day.startRange,
.flatpickr-day.endRange,
.flatpickr-day.selected:hover,
.flatpickr-day.startRange:hover,
.flatpickr-day.endRange:hover {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-accent-fg);
}
.flatpickr-day.inRange,
.flatpickr-day.inRange:hover {
  background: var(--color-link-tint);
  border-color: var(--color-link-tint);
  box-shadow:
    -5px 0 0 var(--color-link-tint),
    5px 0 0 var(--color-link-tint);
}
.flatpickr-day.flatpickr-disabled,
.flatpickr-day.prevMonthDay,
.flatpickr-day.nextMonthDay {
  color: var(--color-secondary-fg);
}
span.flatpickr-weekday {
  color: var(--color-secondary-fg);
}

/* DM.3 — empty-state hint: a quiet one-line message the JS toggles
 * visible when the picked account has no activity in the visible
 * window. Muted, no icon, no border (the calendar still renders and all
 * days stay clickable). role="status" + visible text drive the e2e
 * locator, not this class. */
.day-picker-empty-window {
  margin-top: 0.25rem;
  font-size: 0.75rem;
  color: var(--color-secondary-fg);
}
.day-picker-empty-window[hidden] {
  display: none;
}

/* DM.3 — day-availability legend, appended to the flatpickr popup by
 * wireFlatpickrSingle's onReady. The swatches MIRROR the day-marker
 * channels so the key is unambiguous: filled = Transactions,
 * ring = Balance. Same theme tokens as the .has-* rules above. */
.day-picker-legend {
  display: flex;
  gap: 1rem;
  justify-content: center;
  align-items: center;
  margin-top: 0.25rem;
  padding: 0.4rem 0.5rem 0.2rem;
  border-top: 1px solid var(--color-surface-border);
  font-size: 0.75rem;
  color: var(--color-secondary-fg);
}
.legend-item {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
}
.legend-swatch {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  flex: 0 0 auto;
}
.legend-swatch.legend-tx {
  background: color-mix(in srgb, var(--color-accent) 20%, var(--color-surface));
}
.legend-swatch.legend-bal {
  box-shadow: inset 0 0 0 2px var(--color-accent);
}

/* ---------------------------------------------------------------- */
/* noUiSlider — two-handle numeric range                             */
/* ---------------------------------------------------------------- */
.noUi-target {
  background: var(--color-surface-border);
  border: none;
  box-shadow: none;
  border-radius: 0.25rem;
}
.noUi-horizontal {
  height: 6px;
}
.noUi-connect {
  background: var(--color-accent);
}
.noUi-horizontal .noUi-handle {
  width: 16px;
  height: 16px;
  right: -8px;
  top: -5px;
  border-radius: 9999px;
  background: var(--color-surface);
  border: 2px solid var(--color-accent); /* a11y: bordered circle */
  box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.2);
  cursor: pointer;
}
.noUi-handle::before,
.noUi-handle::after {
  display: none; /* drop the default grip lines */
}
.noUi-handle:focus {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 35%, transparent);
}
.noUi-tooltip {
  background: var(--color-primary-fg);
  color: var(--color-surface);
  border: none;
  border-radius: 0.25rem;
  font-size: 0.7rem;
  padding: 1px 6px;
}

/* ---------------------------------------------------------------- */
/* ctxmenu — row-level "⋯" / right-click drill popup                  */
/* ---------------------------------------------------------------- */
/* ctxmenu has no CSS file: it injects its own ``<style id="ctxmenu">``
 * into <head> at runtime, *after* this sheet has loaded — so every
 * colour rule here needs ``!important`` to win the cascade. (Layout /
 * sizing rules from its injected sheet are fine; we only override the
 * palette.) Same per-L2-theme ``--color-*`` story as the widgets above. */
.ctxmenu {
  background: var(--color-surface) !important;
  border: 1px solid var(--color-surface-border) !important;
  box-shadow: 0 4px 12px 0 rgb(0 0 0 / 0.18) !important;
  border-radius: 0.375rem !important;
  font-size: 0.8rem;
}
.ctxmenu li {
  color: var(--color-primary-fg) !important;
}
.ctxmenu li a,
.ctxmenu li span {
  color: inherit !important;
}
.ctxmenu li.interactive:hover {
  background: var(--color-link-tint) !important;
  color: var(--color-primary-fg) !important;
  font-weight: 600; /* a11y: not colour-only */
}
.ctxmenu li.disabled {
  color: var(--color-secondary-fg) !important;
}
.ctxmenu li.heading {
  color: var(--color-secondary-fg) !important;
  font-weight: 600;
}
.ctxmenu li.divider {
  border-bottom: 1px solid var(--color-surface-border) !important;
}
.ctxmenu li.submenu::after {
  border-left-color: var(--color-secondary-fg) !important;
}
