/* ═══════════════════════════════════════════════════════════════════════════
   FORM-CONTROL ENHANCEMENT LAYER          ds-select.js + ds-datepicker.js skin
   ═══════════════════════════════════════════════════════════════════════════

   A SEPARATE, DELETABLE SHEET. Not appended to components.css on purpose
   (theme-strategy.md §3): components.css owns the STATIC design-system skin
   that a native `<select>` / `<input type="date">` wears with no JavaScript at
   all. This file owns only the extra paint the two scripted enhancers need.
   Delete one <link> plus three files and the admin falls all the way back to
   native controls that are already fully skinned and fully usable.

   Loaded UNGATED, admin-wide — see the comment above its <link> in
   theme::admin.head for why that differs from the route-gated phone/maps
   blocks.

   ── NO !important, ANYWHERE ─────────────────────────────────────────────────

   Every class here is ours: nothing in this file competes with Krayin's
   compiled Tailwind for the same element, because the elements are ones the
   enhancers created. The one place we touch a core-rendered element is the
   clipped native control, and that is done through an attribute selector we
   also own. If a rule in here ever seems to need !important, the widget is
   painting the wrong node.

   ── WHY THE CLIP HOOK IS AN ATTRIBUTE, NOT A CLASS ──────────────────────────

   Same reason components.css:497 hides the dial-code widget's core input via
   `[data-dialcode-enhanced="true"]` rather than `.sr-only`: the native
   controls we clip are Vue-managed. `control.blade.php` binds
   `:class="[errors.length ? 'border border-red-500' : '']"` on every coded
   `<select>`, so Vue rewrites that element's entire `class` attribute each
   time its error state flips — silently dropping any class added from outside
   Vue, and un-hiding the native control on top of our own widget. A data
   attribute Vue never binds survives the patch.

   That attribute is a STYLING HOOK ONLY. Neither script ever reads it to
   decide whether an element is already enhanced — that is tracked by element
   identity in a WeakSet, because Vue can and does carry data attributes onto
   re-rendered nodes and a data-flag produces duplicate widgets.

   ── TOKENS ONLY ─────────────────────────────────────────────────────────────

   Every colour, radius, duration and shadow below is a semantic token from
   tokens.css. Semantic tokens re-point under `.dark`; primitives do not. The
   two primitives that do appear (--green-200 on hover, the brand-green chevron
   data URI) are deliberate: both are copied verbatim from `.select` in
   components.css so the enhanced trigger is pixel-identical to the native
   control it replaces, in both themes.

   Spec: ds-spec.md §A (combobox), §B (calendar), §3 (motion).
   ═══════════════════════════════════════════════════════════════════════════ */


/* ───────────────────────────────────────────────────────── THE CLIPPED NATIVE

   Off-screen by POSITION and CLIP. Never display:none, never
   visibility:hidden — both remove the element from the tab order outright, and
   both natives have to stay reachable:

     · the combobox's <select> IS the focus target and the tab stop; the
       visible trigger is aria-hidden paint (interaction-spec.md §1.0),
     · the date field's <input type="date"> stops being the focus target but
       goes on being the element vee-validate binds, validates and posts.

   `pointer-events:none` on top of the clip so a stray click on the surviving
   1px box can never open the browser's own OS-drawn dropdown over our popup.
   Keyboard and assistive-technology focus are unaffected. */
[data-cx-native="select"],
[data-cx-native="date"] {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
  pointer-events: none;
}


/* ═════════════════════════════════════════ CONTROL A — COMBOBOX / LISTBOX ══ */

/* ── trigger ────────────────────────────────────────────────────────────────

   Pixel-identical to `.select` (components.css:114-124, :145-147): same 1px
   border, same --radius-md, same 9px/12px padding with 32px cleared on the
   right, same 500/13px type, same --fg-strong text, same chevron data URI at
   `right 11px center`. The height (~39px) therefore falls out of padding +
   border + line-box exactly as it does on the native control — it is not
   hardcoded, so a change to the type scale moves both together.

   It is a <span>, not a <button>: it carries aria-hidden="true" and
   tabindex="-1" and exists only to paint and to catch the mouse. The real
   control is the clipped <select> beside it. */
.cx-combobox__trigger {
  display: flex;
  align-items: center;
  box-sizing: border-box;
  width: 100%;
  padding: 9px 32px 9px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  font: 500 13px var(--font-body);
  color: var(--fg-strong);
  background-color: var(--bg);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%2300a959' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
  cursor: pointer;
  user-select: none;
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}

.cx-combobox__trigger:hover { border-color: var(--green-200); }

/* FOCUS COSTS NO JAVASCRIPT.

   The trigger is the next element sibling of the select it decorates, so an
   adjacent-sibling selector paints the focus ring the moment the real control
   takes focus. `:focus-visible` covers keyboard arrival; `[aria-expanded]`
   covers the mouse path, where the browser has decided the focus was
   pointer-initiated and :focus-visible correctly does not match — but the
   popup is open and the field plainly needs to look active. ds-spec.md A.1
   gives focus and open the same treatment for exactly this reason. */
select[data-cx-native="select"]:focus + .cx-combobox__trigger,
select[data-cx-native="select"][aria-expanded="true"] + .cx-combobox__trigger {
  outline: none;
  border-color: var(--focus-outline, #00763d);
  box-shadow: 0 0 0 3px var(--focus-ring);
}

.cx-combobox__value {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Krayin's coded selects lead with `<option value="">Select …</option>`. That
   is a placeholder, and a placeholder is --fg-subtle, exactly as
   `.input::placeholder` is (components.css:125). */
.cx-combobox__trigger--placeholder .cx-combobox__value { color: var(--fg-subtle); }

.cx-combobox__trigger--disabled {
  color: var(--fg-muted);
  background-color: var(--bg-tint);
  border-color: var(--divider);
  cursor: not-allowed;
}

/* Mirrors vee-validate's error state off the native select's class attribute.
   --danger rather than the raw hex `.input--error` carries, so the dark theme
   is not left holding a light-mode-only pink. */
.cx-combobox__trigger--error { border-color: var(--danger); }

select[data-cx-native="select"]:focus + .cx-combobox__trigger--error,
select[data-cx-native="select"][aria-expanded="true"] + .cx-combobox__trigger--error {
  border-color: var(--danger);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger) 22%, transparent);
}

/* THE OPEN RING WHEN THE POPUP IS A SEARCH POPOVER.

   The two adjacent-sibling rules above key the open ring off the native
   select's [aria-expanded="true"]. A SEARCH instance demotes its native select
   to aria-expanded="false" while open — ds-select.js P2b: only the search
   input, the element the user actually drives, may advertise the expanded
   listbox — so that hook no longer fires. The enhancer adds
   `.cx-combobox__trigger--open` for the duration instead, and these two rules
   reproduce the EXACT green and danger rings the [aria-expanded="true"]
   selectors paint, so a Country/State trigger looks identical open whether or
   not search is on. A plain instance never gets the class. */
.cx-combobox__trigger--open {
  border-color: var(--focus-outline, #00763d);
  box-shadow: 0 0 0 3px var(--focus-ring);
}

.cx-combobox__trigger--open.cx-combobox__trigger--error {
  border-color: var(--danger);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger) 22%, transparent);
}


/* ── popover ────────────────────────────────────────────────────────────────

   Promoted from `.cx-statusmenu` (leads/index.blade.php:484-513), the
   role="listbox" popover this repo already ships and has already proven. Same
   surface, same radius, same elevation, same open keyframe — generalised into
   a reusable control rather than forked into a sibling.

   FIXED AND PORTALED TO <body>. `position:fixed` alone is not enough: a fixed
   element is still contained by an ancestor that establishes a containing
   block (any transform/filter/will-change), and it is still ordered by an
   ancestor stacking context. filter-panel.blade.php's docblock (~line 1348)
   spells the consequence out and names this control as the one that would hit
   it — the pinned filter rail is `position:sticky`, an unconditional stacking
   context at z-index 10002, so no z-index applied INSIDE the rail can beat the
   admin sidebar. Appending the list to document.body escapes every ancestor
   overflow and every ancestor stacking context at once, which is what a native
   dropdown does anyway. 10500 is the number the column menu and the view tabs
   already borrowed for the same reason.

   top/left come from the trigger's bounding rect, set by script on open. */
.cx-combobox__list {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 10500;
  box-sizing: border-box;
  min-width: 220px;
  max-width: calc(100vw - 16px);
  max-height: 60vh;
  margin: 0;
  padding: 6px;
  overflow-y: auto;
  list-style: none;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  transform-origin: top;
  animation: cx-combobox-in var(--dur-base) var(--ease);

  /* The popover is rendered at <body>, so it inherits body typography rather
     than the field's. Stated explicitly for the same reason the column menu
     states it: a menu is body text wherever it is anchored. */
  font: 500 13px var(--font-body);
  letter-spacing: normal;
  text-transform: none;

  /* ds-spec.md G5 — no scrollbar token exists; --ui-subtle is the non-text UI
     grey and re-points under .dark, so the thumb follows the theme. */
  scrollbar-width: thin;
  scrollbar-color: var(--ui-subtle) transparent;
}

.cx-combobox__list[hidden] { display: none; }

.cx-combobox__group {
  padding: 9px 10px 4px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.cx-combobox__option {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--fg-strong);
  font-weight: 500;
  text-align: start;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
}

.cx-combobox__option-label {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* `.is-active` is the aria-activedescendant highlight. It is NOT focus: DOM
   focus never leaves the select (interaction-spec.md §1.0), so there is no
   :focus-visible here to hang the highlight on and nothing ever calls .focus()
   on an option. Hover and the keyboard highlight paint identically on purpose
   — they are the same "this is the one you are about to pick" state. */
.cx-combobox__option:hover,
.cx-combobox__option.is-active { background: var(--control-hover-bg); }

.cx-combobox__option:active { background: var(--control-selected-bg); }

/* SELECTED IS FILL PLUS WEIGHT PLUS A CHECK — never a border. A brand-coloured
   border on a rounded element fails the repo's `border-accent-on-rounded`
   lint, and three redundant channels is what keeps the state legible to
   someone who cannot see the green (WCAG 1.4.1). aria-selected is the source
   of truth and it is set explicitly on every option, not just the chosen one. */
.cx-combobox__option[aria-selected="true"] {
  background: var(--control-selected-bg);
  font-weight: 600;
}

.cx-combobox__check {
  flex: none;
  width: 14px;
  height: 14px;
  color: var(--brand);
  visibility: hidden;
}

.cx-combobox__option[aria-selected="true"] .cx-combobox__check { visibility: visible; }

.cx-combobox__option[aria-disabled="true"] {
  color: var(--fg-muted);
  cursor: not-allowed;
}

.cx-combobox__option[aria-disabled="true"]:hover { background: transparent; }

.cx-combobox__empty {
  padding: 8px 10px;
  color: var(--fg-muted);
  font-weight: 500;
}

/* TASKS-RULINGS TK44.1 - the shared remote combobox (remote-combobox.js).
   `.cx-combobox__note` is its non-option status line (Searching..., no
   matches, search failed), a `role="presentation"` <li>; values carried over
   from the retired `.tk-combo-note`. A grouped result list nests one
   `ul[role="group"]` per group inside the listbox; the reset keeps the nested
   list flush with the options around it. */
.cx-combobox__note {
  padding: 8px 10px;
  font-size: 12.5px;
  color: var(--fg-muted);
}

.cx-combobox__list [role="group"] {
  margin: 0;
  padding: 0;
  list-style: none;
}


/* ── search popover ─────────────────────────────────────────────────────────

   A search instance (data-cx-search on, or the 13th option auto-enabling it)
   cannot put an <input> inside its role="listbox", so ds-select.js wraps the
   <ul> in this popover: a non-scrolling `.cx-combobox__search-row` header above
   the <ul>, which becomes the scroll body. The wrapper takes over every surface
   property the list wore on its own — border, radius, elevation, max-height,
   the open keyframe — and the nested list sheds them. Same portal-to-body, same
   10500, same rationale as `.cx-combobox__list` above; a non-search instance
   never gets this wrapper and is untouched. */
.cx-combobox__popover {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 10500;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  min-width: 220px;
  max-width: calc(100vw - 16px);
  max-height: 60vh;
  margin: 0;
  padding: 0;
  overflow: hidden;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  transform-origin: top;
  animation: cx-combobox-in var(--dur-base) var(--ease);

  /* Portalled to <body>, so it states its own typography rather than inheriting
     the field's — the same reason `.cx-combobox__list` does. */
  font: 500 13px var(--font-body);
  letter-spacing: normal;
  text-transform: none;
}

.cx-combobox__popover[hidden] { display: none; }

/* Inside the wrapper the <ul> is only the scroll body: it drops the fixed
   position, the chrome and its own max-height (the wrapper caps the height, the
   list flexes into what remains) and never animates a second time. It keeps its
   6px padding, its overflow and the themed scrollbar from the base rule above. */
.cx-combobox__popover > .cx-combobox__list {
  position: static;
  z-index: auto;
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
  max-width: none;
  max-height: none;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  animation: none;
}

/* The non-scrolling header. flex:none pins it while the list scrolls beneath;
   the divider separates it from the options. */
.cx-combobox__search-row {
  flex: none;
  padding: 8px;
  border-bottom: 1px solid var(--divider);
}

/* Same box model, border, radius and focus ring as `.cx-datepicker__input`,
   with a Lucide `search` glyph baked in as a stroke-only data-URI — the same
   technique as the trigger chevron, at `left 11px center` with 32px of left
   padding cleared for it. The glyph literal is --fg-muted (#5f6770); exactly
   like the chevron's brand green it does not re-point, and a mid-grey reads on
   both the light and dark surfaces. */
.cx-combobox__search {
  box-sizing: border-box;
  width: 100%;
  padding: 8px 12px 8px 32px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  font: 500 13px var(--font-body);
  color: var(--fg-strong);
  background-color: var(--bg);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%235f6770' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: left 11px center;
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}

.cx-combobox__search::placeholder { color: var(--fg-subtle); }

.cx-combobox__search:focus {
  outline: none;
  border-color: var(--focus-outline, #00763d);
  box-shadow: 0 0 0 3px var(--focus-ring);
}

/* THE SEARCH POPOVER'S POLITE LIVE REGION (role="status", aria-live="polite").

   Visually hidden by the standard clip technique — real CSS, never a Tailwind
   utility, and self-contained in this deletable sheet rather than borrowing the
   `.sr-only` that lives in components.css. It is a child of
   `.cx-combobox__popover` but a SIBLING of the role="listbox" <ul> (a status
   region must not be a listbox descendant), and ds-select.js writes it on every
   filter pass: the no-match label when a query filters everything out (WCAG 2.1
   AA 4.1.3 — otherwise silent to assistive tech), the surviving result count
   otherwise. */
.cx-combobox__status {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
  padding: 0;
  margin: -1px;
}


/* ═══════════════════════════════════════════ CONTROL B — POPUP CALENDAR ════ */

/* ── field shell ────────────────────────────────────────────────────────────

   `.date-field` / `.date-field__input` (modals.css:944-963) are the shipped DS
   skin for a native date input, and the visible text input wears both that
   class and this one. This sheet restates the recipe under its own class
   because modals.css is NOT loaded admin-wide — it is linked per-screen
   (leads view, the filter-panel modal) — and this enhancer IS admin-wide. On a
   page where both sheets load the declarations are identical, so nothing
   fights; on every other page this is the only copy.

   The shell is created only where one does not already exist; where core or
   the DS already provides `.date-field`, that element is reused in place and
   simply gains this class too. */
.cx-datepicker__field {
  position: relative;
  display: flex;
  align-items: center;
}

.cx-datepicker__input {
  width: 100%;
  box-sizing: border-box;
  padding: 9px var(--space-3) 9px 34px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  font: 500 13px var(--font-body);
  color: var(--fg-strong);
  background: var(--bg);
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}

.cx-datepicker__input:hover { border-color: var(--green-200); }

.cx-datepicker__input:focus {
  outline: none;
  border-color: var(--focus-outline, #00763d);
  box-shadow: 0 0 0 3px var(--focus-ring);
}

.cx-datepicker__input::placeholder { color: var(--fg-subtle); }

.cx-datepicker__input[aria-invalid="true"] { border-color: var(--danger); }

.cx-datepicker__input[aria-invalid="true"]:focus {
  border-color: var(--danger);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger) 22%, transparent);
}

.cx-datepicker__input:disabled {
  color: var(--fg-muted);
  background: var(--bg-tint);
  border-color: var(--divider);
  cursor: not-allowed;
}

/* THE GLYPH IS A REAL <button>. date-picker.blade.php's own docblock records
   that the rejected mockup used inert <span>s for its month controls and its
   footer links, so this control cannot repeat that anywhere — not on the nav,
   not on the footer, and not on the affordance that opens the thing.

   --brand-text rather than the --green-700 primitive `.date-field__icon` uses:
   identical in light mode, and it re-points to green-300 under .dark instead
   of leaving a dark-green glyph on a near-black field. */
.cx-datepicker__toggle {
  position: absolute;
  left: var(--space-3);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--brand-text);
  cursor: pointer;
}

.cx-datepicker__toggle:focus-visible {
  outline: 2px solid var(--focus-outline, #00763d);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}

.cx-datepicker__toggle:disabled {
  color: var(--fg-muted);
  cursor: not-allowed;
}

.cx-datepicker__toggle svg {
  width: 16px;
  height: 16px;
}

/* Typed-entry failure message. Non-destructive: it appears beside what the
   user typed, it never replaces it (interaction-spec.md §2.4). */
.cx-datepicker__error {
  display: block;
  margin-top: var(--space-1);
  font-size: 11px;
  line-height: var(--lh-normal);
  color: var(--danger);
}


/* ── popover ────────────────────────────────────────────────────────────────
   Same shell as the combobox list, same portal-to-body rationale, same 10500.
   ds-spec.md B.1. */
.cx-datepicker__popover {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 10500;
  box-sizing: border-box;
  padding: var(--space-3);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  transform-origin: top;
  animation: cx-datepicker-in var(--dur-base) var(--ease);
  font: 500 13px var(--font-body);
  letter-spacing: normal;
  text-transform: none;
}

.cx-datepicker__popover[hidden] { display: none; }

.cx-datepicker__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}

.cx-datepicker__caption {
  flex: 1 1 auto;
  text-align: center;
  font: 600 13px var(--font-body);
  color: var(--fg-strong);
}

/* ds-spec.md B.4 — the 30px plain icon button already in components.css. The
   enhancer puts `btn-icon btn-icon--plain btn-icon--sm` on these nodes, so
   they are literally that component; only the SVG sizing is added here. */
.cx-datepicker__nav { flex: none; }

.cx-datepicker__nav svg {
  width: 15px;
  height: 15px;
}

.cx-datepicker__grid {
  border-collapse: separate;
  border-spacing: 2px;
  margin: 0;
}

.cx-datepicker__weekday {
  width: 34px;
  padding: 2px 0 6px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  /* --fg-muted, NOT --fg-subtle: these are text at 10px and --ui-subtle (which
     --fg-subtle aliases) is documented non-text-only. ds-spec.md B.2. */
  color: var(--fg-muted);
  text-align: center;
}

.cx-datepicker__cell { padding: 0; }

.cx-datepicker__day {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--fg-strong);
  font: 500 12.5px var(--font-body);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
}

.cx-datepicker__day:hover { background: var(--control-hover-bg); }

.cx-datepicker__day:focus-visible {
  outline: 2px solid var(--focus-outline, #00763d);
  outline-offset: 2px;
}

.cx-datepicker__day--outside { color: var(--fg-muted); }

/* TODAY IS A COLOUR PLUS A DOT, never a ring. A brand-coloured border on a
   rounded 34px square is precisely what `border-accent-on-rounded` fails, and
   a dot survives being the only thing a user can distinguish. The accessible
   name also carries ", Today" — see the enhancer. */
.cx-datepicker__day--today { color: var(--brand-text); font-weight: 700; }

.cx-datepicker__dot {
  width: 3px;
  height: 3px;
  border-radius: var(--radius-pill);
  background: currentColor;
}

/* Selected is a filled square on --brand-strong (AA in both themes) with
   --fg-on-brand text. Last in the cascade so it wins over today/outside. */
.cx-datepicker__day--selected,
.cx-datepicker__day--selected:hover {
  background: var(--brand-strong);
  color: var(--fg-on-brand);
  font-weight: 700;
}

.cx-datepicker__day[aria-disabled="true"] {
  color: var(--ui-subtle);
  cursor: not-allowed;
}

.cx-datepicker__day[aria-disabled="true"]:hover { background: transparent; }

.cx-datepicker__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--divider);
}

/* Real <button>s, for the same reason the nav chevrons are. */
.cx-datepicker__action {
  padding: 4px 6px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  font: 600 12.5px var(--font-body);
  cursor: pointer;
}

.cx-datepicker__action:focus-visible {
  outline: 2px solid var(--focus-outline, #00763d);
  outline-offset: 2px;
}

.cx-datepicker__action--today { color: var(--brand-text); }

.cx-datepicker__action--clear { color: var(--fg-muted); }

.cx-datepicker__action--clear:hover { color: var(--fg); }


/* ═══════════════════════════════════════════════════════════════ MOTION ════

   Transform and opacity ONLY. Animating width/height/top/left fails the repo's
   `layout-transition` lint, and on a popover it also re-runs layout on every
   frame of an interaction the user is waiting on.

   Open animates; CLOSE DOES NOT. `[hidden] { display:none }` is instant, which
   is the shipped `.cx-statusmenu` behaviour and the right one: a dismissal the
   user has already decided on should not be something they wait out.

   The month-to-month swap inside an already-open calendar is deliberately NOT
   animated at all — see interaction-spec.md §3. Repeated PageUp/PageDown must
   not queue transitions, and the live region's timing must not depend on one. */
@keyframes cx-combobox-in {
  from { opacity: 0; transform: translateY(-6px) scale(.97); }
  to   { opacity: 1; transform: none; }
}

@keyframes cx-datepicker-in {
  from { opacity: 0; transform: translateY(-6px) scale(.97); }
  to   { opacity: 1; transform: none; }
}

/* tokens.css:494-500 already zeroes --dur-* and forces animation-duration to
   .01ms under reduced motion, so both keyframes are neutralised before this
   block is read. It is stated anyway, matching statusmenu:513: the guarantee
   should be legible in the file that owns the animation, not inferred from a
   global rule three sheets away. */
@media (prefers-reduced-motion: reduce) {
  .cx-combobox__list,
  .cx-combobox__popover,
  .cx-datepicker__popover { animation: none; }

  .cx-combobox__option,
  .cx-datepicker__day { transition: none; }
}
