/* The date-range control, and the Flatpickr calendar wearing this app's tokens.
 *
 * Load order matters: vendor/flatpickr.min.css first, this file after. The vendor sheet
 * is not edited (ticket 109 keeps it byte for byte upstream, licence in
 * vendor/flatpickr-LICENSE.md), so its blue defaults, its 307.875px fixed calendar and
 * its own type scale are overridden here instead. Every value below is a token; the
 * hardcode gate is pointed at this file and skips finance_app/static/vendor/ by a
 * path rule in scripts/lint_hardcodes.py.
 *
 * `date-range.js` sets data-state on the wrapper: loading, ready, error, disabled.
 */

.date-range{display:flex;flex-wrap:wrap;align-items:flex-end;gap:var(--space-8);min-width:0}

/* --- The preset row ------------------------------------------------------------- */
/* Three rows, always: the presets, then the field, then the status line. `0 0 100%`
 * rather than `1 1 100%` because Chrome measured the help line sharing a row with the
 * field at 1280px and dropping below it at 390px -- a status line that moves is a status
 * line an operator has to look for. */
.date-range-presets{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-8);flex:0 0 100%;min-width:0}
.date-range-presets .helper{margin:0 var(--space-6) 0 0}
.date-range-presets button{padding-inline:var(--space-14);font-size:var(--text-sm);min-height:var(--size-44)}
.date-range-presets button:hover{background:var(--color-action-secondary-hover)}
.date-range-presets button:active{background:var(--color-surface-sunken)}
.date-range-presets button:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}
/* Selected: the one preset the list is actually showing. TICKET 109 parked this on the
 * sunken surface, because the selected token was then a translucent gold wash and
 * verify_states reads an element's own background-color without compositing alpha: the
 * wash made the gate score the text against solid gold and report 2.06:1 for a pair that
 * renders near 14:1. Ticket 112 made --color-surface-selected the OPAQUE design-A value
 * (#f0fdf4), so the preset returns to the token that means "selected", and the gate now
 * measures what is on screen. Hover deepens the same wash one step -- surface.raised is
 * white in this theme, and a selected chip that turns white on hover reads as
 * deselection -- and moves the border to its -hover token. */
.date-range-presets button[aria-pressed=true]{background:var(--color-surface-selected);border-color:var(--color-action-primary);color:var(--color-text-primary)}
.date-range-presets button[aria-pressed=true]:hover{background:var(--color-surface-accent-chip);border-color:var(--color-action-primary-hover)}
.date-range-presets button[disabled]{opacity:var(--opacity-disabled);pointer-events:none}

/* --- The field ------------------------------------------------------------------ */
.date-range-field-label{display:block;font-size:var(--text-xs);color:var(--color-text-secondary);flex:0 0 100%}
.date-range-field{flex:0 1 var(--size-280);min-width:0}
.date-range-input{width:100%;min-height:var(--size-44);padding:var(--space-8) var(--space-12);
  border:1px solid var(--color-border-strong);border-radius:var(--radius-control);
  background:var(--color-surface-field);color:var(--color-text-primary);
  font-family:var(--font-sans);font-size:var(--text-sm);cursor:pointer}
.date-range-input:hover{border-color:var(--color-action-primary)}
.date-range-input:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}
.date-range-input[disabled]{opacity:var(--opacity-disabled);cursor:not-allowed}
/* `max-width:none` is load-bearing. app.css:61 caps every <p> at 78ch as a prose
 * measure; at 1280px that clamped this line to 561.6px, which is small enough to
 * share a flex row with the field, so the status line sat BESIDE the control on a
 * wide screen and BELOW it on a phone. Measured in Chrome, not assumed. */
.date-range-help{flex:0 0 100%;max-width:none;margin:var(--space-4) 0 0;
  font-size:var(--text-xs);color:var(--color-text-secondary)}
/* Error: the boundaries could not be read. The message says what to do, and the control
   keeps the range it last confirmed rather than showing a filter it is not applying.
   TICKET 154: the help line carries the state itself as well, because a caller may hand
   over its own line outside the control (the transactions page's line under its toolbar),
   where a rule keyed on the wrapper cannot reach it. */
.date-range[data-state=error] .date-range-help,.date-range-help[data-state=error]{color:var(--color-feedback-error-text)}
.date-range[data-state=error] .date-range-input,.date-range[data-state=error] .date-range-select{border-color:var(--color-border-danger)}
/* Loading: an async read is in flight; aria-busy carries the same fact to a screen reader. */
.date-range[data-state=loading] .date-range-help,.date-range-help[data-state=loading]{color:var(--color-text-caption)}

/* --- TICKET 154: the compact form ------------------------------------------------
 * One native select of the server's presets beside the date field, the prototype's
 * "ช่วงวันโอน" and "วันเริ่มต้น - วันสิ้นสุด" (R09, TD-01). Two controls on ONE row where
 * the eight buttons took five rows on a phone; they drop under each other only when the
 * row is too narrow for both. Each is a label over its control, like every other filter
 * in a toolbar, so the pair lines up with its neighbours at the control's edge. */
.date-range[data-form=compact]{flex-wrap:wrap;align-items:flex-end;gap:var(--space-8) var(--space-12)}
.date-range-preset-field,.date-range-field-wrap{display:flex;flex-direction:column;gap:var(--space-6);min-inline-size:0}
/* The select is as wide as its longest preset and no wider; the field takes the rest of
   the row up to what two dates need, so "17/09/2026 ถึง 23/09/2026" is never cut off
   beside it on a phone (at 390 the select at half the row left the field too narrow). */
.date-range-preset-field{flex:0 1 auto}
.date-range-field-wrap{flex:1 1 var(--size-150);max-inline-size:calc(var(--size-280) + var(--size-72))}
.date-range-field-wrap[hidden]{display:none}
.date-range[data-form=compact] .date-range-field-label{flex:0 0 auto;font-size:var(--text-base);
  font-weight:var(--weight-medium);color:var(--color-text-secondary)}
.date-range[data-form=compact] .date-range-field{flex:0 0 auto}
.date-range-select{min-height:var(--size-44);padding:var(--space-8) var(--space-12);
  border:1px solid var(--color-border-strong);border-radius:var(--radius-control);
  background:var(--color-surface-field);color:var(--color-text-primary);
  font-family:var(--font-sans);font-size:var(--text-sm);cursor:pointer}
.date-range-select:hover{border-color:var(--color-action-primary)}
.date-range-select:active{background:var(--color-surface-sunken)}
.date-range-select:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}
.date-range-select[disabled]{opacity:var(--opacity-disabled);cursor:not-allowed}

/* --- Flatpickr, in this app's clothes -------------------------------------------- */
.flatpickr-calendar{font-family:var(--font-sans);font-size:var(--text-sm);
  background:var(--color-surface-card);color:var(--color-text-primary);
  border:1px solid var(--color-border-default);border-radius:var(--radius-card);
  box-shadow:var(--shadow-sm);z-index:var(--z-modal);
  /* The vendor sets the calendar to a fixed width, which is exactly what pushes a narrow
   * screen sideways. The desktop grid is left as upstream built it; only the ceiling is
   * added here, and the phone rules at the foot of this file take over below the
   * breakpoint. */
  max-width:calc(100vw - var(--space-24))}
.flatpickr-calendar.arrowTop::before,.flatpickr-calendar.arrowTop::after,
.flatpickr-calendar.arrowBottom::before,.flatpickr-calendar.arrowBottom::after{display:none}
.flatpickr-months,.flatpickr-months .flatpickr-month{background:transparent;color:var(--color-text-primary)}
/* The vendor month row is a fixed height with overflow:hidden, sized for its own 14px
 * Latin type. At this app's type scale, with Thai month names that carry both an
 * ascending vowel and a descending tone mark, "กันยายน" was sliced through the middle --
 * seen in the 390px screenshot, not deduced. The row is given a control-sized box and
 * the month becomes a centred flex line inside it instead of absolutely placed text. */
.flatpickr-months{align-items:center}
.flatpickr-months .flatpickr-month{height:var(--size-40);overflow:visible}
.flatpickr-months .flatpickr-prev-month,.flatpickr-months .flatpickr-next-month{height:var(--size-40)}
.flatpickr-current-month{height:var(--size-40);padding:0;display:flex;align-items:center;
  justify-content:center;gap:var(--space-4);line-height:var(--leading-normal);
  font-size:var(--text-md);font-weight:var(--weight-medium)}
.flatpickr-current-month input.cur-year{color:var(--color-text-primary);font-weight:var(--weight-medium)}
.flatpickr-current-month .flatpickr-monthDropdown-months{background:var(--color-surface-card);color:var(--color-text-primary)}
.flatpickr-current-month .flatpickr-monthDropdown-months .flatpickr-monthDropdown-month{background:var(--color-surface-card);color:var(--color-text-primary)}
/* TICKET 110, one rule, for the reason ticket 109 already recorded about the selected
   preset: Flatpickr hovers both of these with `rgba(0,0,0,0.05)`, verify_states reads an
   element's own background without compositing alpha, and so it measures black under
   near-black text and fails a control that is in fact perfectly readable. Both hovers are
   an OPAQUE token instead, which is what the rest of this file already does. */
.flatpickr-current-month .flatpickr-monthDropdown-months:hover,
.flatpickr-current-month .numInputWrapper:hover{background:var(--color-surface-sunken)}
.flatpickr-months .flatpickr-prev-month,.flatpickr-months .flatpickr-next-month{fill:var(--color-text-secondary);color:var(--color-text-secondary)}
.flatpickr-months .flatpickr-prev-month:hover svg,.flatpickr-months .flatpickr-next-month:hover svg{fill:var(--color-action-primary)}
.flatpickr-weekdays{background:transparent}
span.flatpickr-weekday{background:transparent;color:var(--color-text-secondary);font-weight:var(--weight-medium)}
.flatpickr-day{color:var(--color-text-primary);border-radius:var(--radius-control);border-color:transparent}
.flatpickr-day:hover{background:var(--color-surface-sunken);border-color:var(--color-border-idle)}
.flatpickr-day.today{border-color:var(--color-action-primary)}
.flatpickr-day.selected,.flatpickr-day.startRange,.flatpickr-day.endRange,
.flatpickr-day.selected:hover,.flatpickr-day.startRange:hover,.flatpickr-day.endRange:hover{
  background:var(--color-action-primary);border-color:var(--color-action-primary);
  color:var(--color-action-primary-text)}
.flatpickr-day.inRange,.flatpickr-day.inRange:hover{background:var(--color-surface-selected);
  border-color:var(--color-surface-selected);box-shadow:none}
.flatpickr-day.prevMonthDay,.flatpickr-day.nextMonthDay,.flatpickr-day.flatpickr-disabled{color:var(--color-text-caption)}
.flatpickr-day:focus-visible,.flatpickr-monthDropdown-months:focus-visible,
.flatpickr-current-month input.cur-year:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}

/* A phone: the calendar is inside the viewport, and the week is seven equal columns
   rather than the vendor's fixed-width grid, which would push the page sideways. */
@media (max-width:700px){
  .date-range[data-form=buttons] .date-range-field{flex-basis:100%}
  .date-range-presets button{flex:1 1 auto}
  .flatpickr-calendar .flatpickr-rContainer,.flatpickr-calendar .flatpickr-days,
  .flatpickr-calendar .dayContainer{width:100%;min-width:0;max-width:100%}
  .flatpickr-calendar .flatpickr-innerContainer{display:block}
  .flatpickr-calendar .flatpickr-day{flex-basis:14.2857%;max-width:14.2857%}
}

/* Reduced motion. The vendor sheet opens the calendar with fpFadeInDown, a fade plus a
 * translate; under reduce the translate goes and the calendar is simply there. No content
 * depends on the animation, so nothing is lost by stopping it. */
@media (prefers-reduced-motion: reduce){
  .flatpickr-calendar,.flatpickr-calendar.animate.open,.flatpickr-calendar.animate.arrowTop,
  .flatpickr-calendar.animate.arrowBottom{animation:none}
  .date-range button,.date-range-input,.date-range-select{transition:none}
}
