/* DO NOT EDIT — copied from packages/shared/src/design/css/filter-bar.css
   by `npm run tokens`. Edit the source there, regenerate, commit both.
   A vitest in packages/shared fails if this file drifts from the source. */
/* /app filter dropdown control (Task 4). One `.fb-filter` block = one
 * trigger button + its popup panel. The bar that arranges several of these
 * left-to-right with search/sort and overflow paging is Task 5's job — this
 * sheet only styles the control itself, so it stays correct however Task 5
 * wraps it.
 *
 * Colours are tokens only (packages/shared/src/design/tokens.ts), reused via
 * the CSS custom properties tokens.css already defines. No new colour value
 * is introduced here.
 *
 * CONTROLLER RULING P1: these class names are frozen — Task 11 builds a React
 * FilterBar.tsx that emits the SAME class names and is styled by THIS sheet.
 * Do not rename anything here later in the plan. */

.fb-filter {
  position: relative;
  display: inline-block;
}

.fb-trigger {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--head); font-weight: 700;
  font-size: 0.62rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 8px 13px;
  border-radius: 8px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-dim);
  cursor: pointer;
  white-space: nowrap;
}

@media (hover: hover) {
  .fb-trigger:hover {
    color: var(--text);
    border-color: var(--border-hi);
    background: color-mix(in srgb, var(--cyan) 6%, var(--surface-2));
  }
}

.fb-trigger:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 2px;
}

.fb-trigger[aria-expanded='true'] {
  color: var(--text);
  border-color: var(--border-hi);
  background: color-mix(in srgb, var(--cyan) 10%, var(--surface-2));
}

.fb-trigger__count {
  font-family: var(--mono);
  color: var(--cyan);
}

.fb-panel {
  position: absolute;
  z-index: 30;
  top: calc(100% + 6px);
  left: 0;
  min-width: 220px;
  max-width: 320px;
  max-height: 320px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
  border-radius: 10px;
  background: var(--surface);
  border: 1px solid var(--border-hi);
  /* Token-derived, not a bare hex/rgba literal — same idiom as
     shops.css's .sh-detail-hero__logo shadow. */
  box-shadow: 0 12px 28px rgb(from var(--bg) r g b / 0.55);
}

.fb-panel[hidden] {
  display: none;
}

.fb-search-wrap {
  display: flex;
}

.fb-search {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--body);
  font-size: 0.74rem;
  padding: 7px 9px;
  border-radius: 6px;
  background: var(--input);
  border: 1px solid var(--border);
  color: var(--text);
}

.fb-search::placeholder {
  color: var(--muted);
}

@media (hover: hover) {
  .fb-search:hover {
    border-color: var(--border-hi);
  }
}

.fb-search:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 1px;
  border-color: var(--border-hi);
}

.fb-actions {
  display: flex;
  gap: 8px;
}

.fb-select-all,
.fb-deselect-all {
  flex: 1 1 auto;
  font-family: var(--head); font-weight: 700;
  font-size: 0.52rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 5px 8px;
  border-radius: 6px;
  background: var(--input);
  border: 1px solid var(--border);
  color: var(--text-dim);
  cursor: pointer;
}

@media (hover: hover) {
  .fb-select-all:hover,
  .fb-deselect-all:hover {
    color: var(--text);
    border-color: var(--border-hi);
  }
}

.fb-select-all:focus-visible,
.fb-deselect-all:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 2px;
}

.fb-options {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow-y: auto;
}

.fb-options__empty {
  font-size: 0.7rem;
  color: var(--muted);
  padding: 6px 4px;
}

.fb-option {
  border-radius: 6px;
}

.fb-option__row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 6px;
  border-radius: 6px;
  cursor: pointer;
  color: var(--text-dim);
}

@media (hover: hover) {
  .fb-option__row:hover {
    background: var(--surface-2);
    color: var(--text);
  }
}

.fb-option__checkbox:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 2px;
}

.fb-option__checkbox {
  flex: 0 0 auto;
  accent-color: var(--cyan);
}

.fb-option__value {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 0.74rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.fb-option__count {
  flex: 0 0 auto;
  font-family: var(--mono);
  font-size: 0.66rem;
  color: var(--muted);
}

.fb-range {
  display: flex;
  gap: 10px;
}

.fb-range__field {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 0.6rem;
  color: var(--text-dim);
}

.fb-range__label {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.5rem;
  color: var(--muted);
}

.fb-range__min,
.fb-range__max {
  font-family: var(--mono);
  font-size: 0.74rem;
  padding: 6px 8px;
  border-radius: 6px;
  background: var(--input);
  border: 1px solid var(--border);
  color: var(--text);
}

@media (hover: hover) {
  .fb-range__min:hover,
  .fb-range__max:hover {
    border-color: var(--border-hi);
  }
}

.fb-range__min:focus-visible,
.fb-range__max:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 1px;
  border-color: var(--border-hi);
}

/* ── Task 5: the bar (search -> sort -> filters, with overflow paging) ──
 * Everything above this point styles ONE `.fb-filter` dropdown (Task 4,
 * frozen per CONTROLLER RULING P1 above — nothing above this comment is
 * touched by Task 5). These `fb-bar*` classes are new, additive names for
 * the layer that arranges several of them plus a caller's own search/sort
 * markup left to right and pages the filters region when it overflows.
 *
 * `.fb-bar-filters-viewport` is deliberately `overflow: visible`, NEVER
 * `hidden` — see filter-bar.js's own header comment on why any ancestor of
 * `.fb-filter` with `overflow: hidden` clips the open `.fb-panel` (Task 4)
 * to the row's height instead of letting it float below. Paging moves
 * `.fb-bar-filters-track` with `margin-left` (fix round 1, R1 — see that
 * rule's own comment for why this replaced `transform: translateX()`), and
 * horizontal containment of the off-page filters that move creates is a
 * `clip-path` on the viewport (fix round 1, R2), never `overflow: hidden`
 * — that would be exactly the panel-clipping bug this comment opens with. */

/* The `clip-path` on `.fb-bar-filters-viewport` below creates a STACKING
 * CONTEXT, which traps `.fb-panel`'s `z-index: 30` inside the viewport.
 * Without a positioned level here, the viewport paints atomically beside
 * later siblings (`#cx-results`, the shops/events lists) and every open
 * dropdown renders BEHIND the results grid. Do not delete this as
 * redundant — the clip-path is load-bearing (see its own comment) and
 * cannot be removed to fix this instead. */
.fb-bar {
  position: relative;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

/* I7 (measured in headless Chrome, not reasoned): `flex: 0 0 auto` sized this
   slot shrink-to-fit from its content's INTRINSIC width -- 303px on Shops.
   Its caller's own row then laid out against a flex-basis that exceeded that
   (`.sh-search-wrap`/`.ev-search-wrap` are `flex: 1 1 260px` and sit beside a
   113px "Use my location" button; 260 + 113 > 303), so `flex-wrap: wrap`
   pushed the button onto a SECOND LINE at every desktop width and the bar
   rendered 80px tall instead of 34px, with the filter row vertically centred
   against it. The same rule capped `.lb-search-wrap` on both codex bars at its
   `min-width: 180px`, so that field never reached its own `max-width: 320px`
   either. Growing and shrinking restores every caller's declared intent:
   Shops/Events 303 -> 420px on one 34px row, codex 180 -> 320px.
   Fix round 2, M-4: `min-width: 0` is NOT what stops this slot from
   overflowing the bar -- it is what PERMITS the slot's own content to
   overflow the slot. Without it, a flex item floors at its content's
   min-content width and refuses to shrink past that; with it, the slot can
   shrink smaller than what's inside it. At 480px the codex slot measures
   116px while `#cx-search` (`.lb-search-wrap` keeps `min-width: 180px`)
   stays 180px -- the search input overflows its own slot's boundary rather
   than forcing the slot (and the bar) wider. Keep the declaration; it is
   what makes the I7 shrink possible at all. Measured at 1024/1440/1920; see
   the batch ledger's "I7 MEASURED" entry for the full before/after table.
   Fix round 2, M-3: that measurement -- and the "one 34px row" claim above
   -- holds at /app's SUPPORTED widths only (>=1024px; `.tdtt-aside` goes
   `display: none` below 1024px and /app hands off to /m). The two-row wrap
   this fix cures RETURNS below ~700px: `.sh-toolbar__row`/`.ev-filterbar__row`
   still `flex-wrap: wrap`, and `flex: 1 1 260px` plus a 113px geo button
   still exceeds the slot once it narrows that far. Left alone deliberately
   -- out of /app's supported range, not a residual bug in this fix. */
.fb-bar-search {
  flex: 1 1 auto;
  min-width: 0;
}

.fb-bar-sort {
  flex: 0 0 auto;
}

.fb-bar-filters {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  flex: 1 1 auto;
}

.fb-bar-filters-viewport {
  overflow: visible;
  /* Fix round 1, C1/R2: hard HORIZONTAL containment for the off-page
   * filters `.fb-bar-filters-track`'s `margin-left` pushes out of view —
   * without this they painted on top of `.fb-bar-search`/`.fb-bar-sort`
   * (later in DOM order, so later in paint order) and over the Next arrow,
   * intercepting clicks meant for the bar's own controls. `overflow: hidden`
   * can't be used for this (see the file-level comment above and
   * filter-bar.js's — it clips `.fb-panel` to the row's height). `clip-path`
   * clips independently per edge: `0 0 ... 0` is normal clipping at the top/
   * right/left edges, `-600px` on the BOTTOM extends the clip region 600px
   * past the box's own height so `.fb-panel` (Task 4: max-height 320px, 6px
   * below the row) is never touched by it. */
  clip-path: inset(0 0 -600px 0);
  min-width: 0;
  flex: 1 1 auto;
}

.fb-bar-filters-track {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: 0; /* set inline, per page, by relayoutBar() in filter-bar.js */
  transition: margin-left 0.15s ease;
}

@media (prefers-reduced-motion: reduce) {
  .fb-bar-filters-track {
    transition: none;
  }
}

/* Fix round 1, I2: without an explicit `flex: 0 0 auto`, `.fb-filter`
 * (Task 4: `display: inline-block`, no flex properties of its own) becomes a
 * flex item here with the default `flex-shrink: 1` — meaning every filter
 * would silently SHRINK to fit the viewport instead of overflowing it, and
 * overflow paging would never trigger at all. It currently happens to work
 * by accident because `.fb-trigger` (Task 4, frozen) sets `white-space:
 * nowrap`, which keeps `min-width: auto` (the shrink floor) at the
 * trigger's full text width — remove that `nowrap` anywhere (e.g. a future
 * Task 11 trigger) and paging disappears with no test able to catch it,
 * since this harness does no real layout. Explicit here so it no longer
 * depends on that accident. */
.fb-bar-filters-track > .fb-filter {
  flex: 0 0 auto;
}

.fb-bar-arrow {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 30px;
  padding: 0;
  border-radius: 6px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-dim);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
}

.fb-bar-arrow[hidden] {
  display: none;
}

@media (hover: hover) {
  .fb-bar-arrow:hover {
    color: var(--text);
    border-color: var(--border-hi);
    background: color-mix(in srgb, var(--cyan) 6%, var(--surface-2));
  }
}

.fb-bar-arrow:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 2px;
}

/* Fix round 1, R3: the panel of the LAST filter on the current page opens
 * right-aligned instead of Task 4's frozen default (`.fb-panel { left: 0 }`
 * above) — once `.fb-bar-filters-viewport` clips horizontally (see its own
 * comment above), a left-aligned panel on that filter would hang its own
 * right edge off that same clip boundary. Additive: it overrides the base
 * rule for one compound selector rather than editing it, so Task 4's frozen
 * `.fb-panel` rule is untouched. Applied to the STABLE `.fb-filter` wrapper
 * by filter-bar.js's relayoutBar(), not to `.fb-panel` itself, because
 * Task 4's repaint() regenerates the panel node from scratch on every
 * open/close/toggle/select-all — a class set directly on it would vanish on
 * the filter's very next interaction. The wrapper is never replaced, so a
 * class there survives, and needs only a scoped selector to reach the panel
 * inside it. */
.fb-filter.fb-filter--align-end .fb-panel {
  left: auto;
  right: 0;
}

/* R9.3 (fix round 1): the bar's own always-visible reset affordance. New,
 * additive class name — permitted under CONTROLLER RULING P1. Styled to
 * match `.fb-trigger` (same family of control, on the same row) rather than
 * `.fb-bar-arrow`, since it carries visible text, not just a glyph. */
/* Companion to the `hidden` attribute the bar toggles on this button (fix
   round 2, C1). `.fb-bar-arrow` needs the same rule at its own `[hidden]`
   selector above because it declares `display: inline-flex`, and an
   author-origin `display` beats the UA stylesheet's `[hidden]` rule. This
   button declares no `display` today, so it would hide correctly without
   this -- but only BY OMISSION: the first person to add `display: flex`
   here (the natural move when putting an icon beside the label) would make
   Clear permanently visible with no filters active, a half-regression of
   C1. Nothing in the test harness can catch that -- the fake DOM has no
   layout engine, and every assertion checks the `hidden` ATTRIBUTE, never
   computed display. */
.fb-bar-clear[hidden] {
  display: none;
}

.fb-bar-clear {
  flex: 0 0 auto;
  font-family: var(--head); font-weight: 700;
  font-size: 0.62rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 8px 13px;
  border-radius: 8px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-dim);
  cursor: pointer;
  white-space: nowrap;
}

@media (hover: hover) {
  .fb-bar-clear:hover {
    color: var(--text);
    border-color: var(--border-hi);
    background: color-mix(in srgb, var(--magenta) 8%, var(--surface-2));
  }
}

.fb-bar-clear:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 2px;
}
