@charset "UTF-8";
/* ============================================================================
   ACTIVE FILTER PILLS — single source of truth.
   Canonical CSS for removable filter tokens (.filter-pill / .key / .val / .x),
   the "clear all" action (.clear-all), the width-collapse enter/leave helpers
   (.fp-clip) and the demo add/reset controls. Shared by comp-filter-pills.html
   and any future consumer. Pair with _filter-pills.js. Import AFTER
   colors_and_type.css + _chips.css. The host row must be a flex container; the
   active-filter row uses margin-based spacing (below) so a pill can animate its
   own footprint to 0. Contract: role="group" aria-label="Aktivní filtry" /
   "Navržené filtry" (the controller keys off these).
   ============================================================================ */

.row[aria-label="Aktivní filtry"] {
  /* ── Motion tokens (the compound-architecture contract) ───────────────────
     Read by _filter-pills.js at add/remove time (getComputedStyle on this active
     row) and applied per-instance via inline style by the playground Inspector /
     a preset. Declared here as the system DEFAULT. NEVER hardcode these in
     _filter-pills.js again — keeping them as tokens is what lets the motion
     governor scale them (playbackRate) and the Inspector retune them live with
     zero JS wiring. See notes/architecture.md "Compound architecture".
     --afp-dur: enter/leave box-collapse duration · --afp-ease: enter (expand-in)
     easing · --afp-collapse-ease: leave (collapse-out) easing. */
  --afp-dur: 240ms; /* @kind other */
  --afp-ease: cubic-bezier(0.16, 1, 0.3, 1); /* @kind other */
  --afp-collapse-ease: cubic-bezier(0.4, 0, 0.2, 1); /* @kind other */
  column-gap: 0;
}
.row[aria-label="Aktivní filtry"] > * { margin-right: 8px; }
.row[aria-label="Aktivní filtry"] > *:last-child { margin-right: 0; }
/* .label-sm, .kbd-hint and .help now live in the shared _help.css. */

/* ── Curtain elevation (fp26 · color sets fp27) ──────────────────────────────
   Present ONLY while the table-curtain is in flight: slideCurtain toggles
   `fp-sliding` on the slide element for the duration of the slide. A soft
   up-cast shadow from the moving top edge makes the table read as a sheet
   passing ABOVE the pills (the sticky-header idiom) instead of a hard line
   wiping them; it fades on landing via the `transition: box-shadow` consumers
   declare on their slide element. NOT the retired static "seam softener"
   (notes/decisions.md): at rest there is no shadow and the curtain remains pure
   paint-order.

   COLOR SETS — switched via `data-afp-shadow` on <body> (see the curtainShadow
   schema in _filter-pills.config.js; the Inspector drives it). Default (no
   attribute) = "panel": the "shadow" is EXACTLY the backdrop color behind the
   pills — no darkening, no alpha. It's a FEATHER, not an elevation shadow: over
   the bare background it's invisible (same color), and it only materializes
   where the table's edge passes over the pills, softly fading them out ahead of
   the opaque curtain. The backdrop is consumer-specific: the default is the
   canonical app backdrop --color-bg-page (what colors_and_type.css and
   data-preview paint <body> with); a consumer whose pills sit on a different
   surface sets --afp-backdrop on the row/stage (the comp-filter-pills card body
   is --color-bg-surface, e.g.). Both tokens are theme-remapped already, so no
   dark-mode override is needed here. "ink" is the original fp26 elevation look
   for A/B. */
.fp-sliding {
  --afp-curtain-shadow: var(--afp-backdrop, var(--color-bg-page, #f3f7fc));
  box-shadow: 0 -14px 22px -12px var(--afp-curtain-shadow);
}
body[data-afp-shadow="ink"] .fp-sliding { --afp-curtain-shadow: rgb(15 23 42 / 0.30); }
body[data-afp-shadow="ink"][data-theme="dark"] .fp-sliding { --afp-curtain-shadow: rgb(0 0 0 / 0.6); }
body[data-afp-shadow="none"] .fp-sliding { box-shadow: none; }



/* ── filter pills ────────────────────────────────────────────────────── */
.filter-pill {
  display: inline-flex; align-items: center;
  padding: 4px 12px;                       /* symmetric — suggested rows get real right padding */
  background: var(--color-bg-raised);
  border: 1px solid var(--color-border-default);
  border-radius: 999px;
  font: 500 12.5px/1 var(--font-sans);
  color: var(--color-fg-default);
  cursor: pointer; user-select: none;
  -webkit-appearance: none; appearance: none;
  text-align: left; white-space: nowrap; flex: none;
  transition: border-color 120ms ease-out, background 120ms ease-out, color 120ms ease-out, box-shadow 140ms ease-out;
}

/* leading glyph (e.g. bookmark on suggested pills) */
.filter-pill > i.bi { font-size: 13px; line-height: 1; margin-right: 6px; margin-left: -2px; }

/* Optical vertical centering: caps-heavy pill text reads high inside a
   line-height:1 flex line (no descender mass below). Nudge the text + leading
   icon down 1px so it sits on the true centre and lines up with the × glyph. */
.filter-pill > i.bi,
.filter-pill .key,
.filter-pill .val { transform: translateY(1px); }

/* category key + value — asymmetric spacing:
   wide gap between LABEL and VALUE, tight gap between VALUE and × */
.filter-pill .key {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--color-fg-tertiary); font-weight: 500;
  margin-right: 8px;                       /* ↑ label → value */
}
.filter-pill .val { font-weight: 500; }
.filter-pill.is-active .val { font-weight: 600; }

/* hover */
.filter-pill:hover,
.filter-pill[data-state="hover"] {
  border-color: var(--gov-color-primary-500);
  color: var(--gov-color-primary-700);
  background: var(--gov-color-primary-50);
}
.filter-pill:hover .key,
.filter-pill[data-state="hover"] .key,
.filter-pill[data-demo="hover"] .key { color: var(--gov-color-primary-500); }
.filter-pill[data-demo="hover"] {
  border-color: var(--gov-color-primary-500);
  color: var(--gov-color-primary-700);
  background: var(--gov-color-primary-50);
}

/* pressed — the whole suggested pill is a button.
   .is-pressing mirrors native :active for Enter (which fires click without
   painting :active the way held Space does). */
button.filter-pill:active,
button.filter-pill.is-pressing,
.filter-pill[data-state="pressed"],
.filter-pill[data-demo="pressed"] {
  background: var(--gov-color-primary-100);
  border-color: var(--gov-color-primary-700);
  color: var(--gov-color-primary-700);
  box-shadow: inset 0 1px 2px rgba(12,24,56,0.10);
}
.filter-pill[data-state="pressed"] .key,
.filter-pill[data-demo="pressed"] .key { color: var(--gov-color-primary-500); }

/* selected / applied (suggested toggle) */
.filter-pill[aria-pressed="true"] {
  background: var(--gov-color-primary-50);
  border-color: var(--gov-color-primary-500);
  color: var(--gov-color-primary-700);
}

/* active filter token */
.filter-pill.is-active {
  background: var(--gov-color-primary-50);
  border-color: var(--gov-color-primary-500);
  color: var(--gov-color-primary-700);
  padding-right: 4px;                      /* tight right — the × supplies the optical gap */
}
.filter-pill.is-active .key { color: var(--gov-color-primary-500); opacity: 0.85; }
/* Active-token hover — the rest active state and the generic pill hover are BOTH
   blue-50, so an active pill had no hover feedback. Step up to blue-100 fill +
   blue-600 border + blue-600 key so hovering an applied filter reads as live.
   Text stays blue-700 (NOT blue-800: blue-800 has no dark remap → invisible navy
   on dark; blue-700 flips to a light blue). Higher specificity than
   `.filter-pill:hover`, so order-independent. */
.filter-pill.is-active:hover,
.filter-pill.is-active[data-state="hover"] {
  background: var(--gov-color-primary-100);
  border-color: var(--gov-color-primary-600);
  color: var(--gov-color-primary-700);
}
.filter-pill.is-active:hover .key,
.filter-pill.is-active[data-state="hover"] .key { color: var(--gov-color-primary-600); opacity: 1; }

/* × remove button */
.filter-pill .x {
  all: unset; box-sizing: border-box;
  flex: none; width: 18px; height: 18px;
  margin-left: 2px;                        /* ↓ value → × */
  border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  color: currentColor; cursor: pointer;
  user-select: none; -webkit-user-select: none;   /* controls never text-select */
  transition: background 110ms ease-out;
}
.filter-pill .x i.bi {
  font-size: 15px; line-height: 1;
  /* No display override here. The global `.bi { display:inline-flex; align/justify
     :center }` (colors_and_type.css @layer reset) collapses the <i> to the glyph
     and centres the ::before inside the 18×18 dot. A bespoke `display:block`
     used to reinstate the inline line-box strut (<i> measured 15×16.458 vs the
     15×15 glyph), so the × rode high and off-centre. The button is already
     flex-centred, so the now-glyph-sized <i> lands dead-centre. See pitfalls
     "Iconography / glyph alignment": never re-add per-component glyph nudges. */
  opacity: 0.72; transition: opacity 110ms ease-out;
}
.filter-pill .x:hover,
.filter-pill .x.is-focus,
.filter-pill .x[data-state="hover"] { background: var(--gov-color-primary-200); }
.filter-pill .x:active,
.filter-pill .x[data-state="pressed"] { background: var(--gov-color-primary-300); }
.filter-pill .x:hover i.bi,
.filter-pill .x.is-focus i.bi,
.filter-pill .x[data-state="hover"] i.bi { opacity: 1; }
/* the × is keyboard-reachable, but the ring blooms on the whole pill (below);
   so suppress the button's own ring and show the dot instead */
.filter-pill .x:focus-visible { box-shadow: none; outline: none; background: var(--gov-color-primary-300); }
.filter-pill .x:focus-visible i.bi { opacity: 1; }
/* Dark — the dot must sit a step ABOVE the active-pill hover bg (primary-100) to
   read. Hover uses primary-200 (remapped translucent in dark). primary-300 is NOT
   remapped (stays opaque mid-blue → a solid chip), so pin the pressed/focused dot
   to a translucent tint that stays in the dark overlay system. */
body[data-theme="dark"] .filter-pill .x:active,
body[data-theme="dark"] .filter-pill .x[data-state="pressed"],
body[data-theme="dark"] .filter-pill .x:focus-visible { background: rgba(82, 142, 210, 0.46); }

/* animated focus ring — system bloom-in recipe (220ms expo-out in, 140ms out).
   Pill itself when it IS the focusable button (suggested) → :focus-visible.
   Active token → ring blooms when its inner × is keyboard-focused.
   Playground / docs → .is-focus. */
.filter-pill:focus-visible,
.filter-pill:has(.x:focus-visible),
.filter-pill.is-focus {
  outline: none;
  box-shadow: var(--shadow-focus);
  border-color: var(--gov-color-primary-500);
  /* Pills are flex siblings; the active token carries its own fill, so lift the
     focused pill above neighbours (z-index works on flex items w/o position). */
  z-index: 1;
  transition: box-shadow 220ms cubic-bezier(0.16, 1, 0.3, 1), border-color 140ms ease-out, background 120ms ease-out, color 120ms ease-out;
}
/* Truly-focused pill lifts above forced-focus siblings (playground / docs row
   force .is-focus on several pills) so its real ring paints on top. */
.filter-pill:focus-visible,
.filter-pill:has(.x:focus-visible) { z-index: 2; }

/* clear-all ghost action */
.clear-all {
  all: unset; box-sizing: border-box; cursor: pointer;
  user-select: none; -webkit-user-select: none;   /* controls never text-select */
  flex: none; white-space: nowrap;        /* all:unset re-enables wrap + shrink — stop "Zrušit vše" wrapping when the row is tight/mid-animation */
  font: 500 12.5px/1 var(--font-sans);
  color: var(--gov-color-primary-500);
  padding: 4px 10px; border-radius: var(--radius-sm);
  /* Match the pill's OUTER height BY CONSTRUCTION (fp30): the text-only
     clear-all came to ~23px vs the pill's ~27px, so a line it occupied ALONE was
     shorter than a pill line — row-height deltas (and curtain travel) changed by
     a few px depending on which item wrapped last. Same anatomy instead of a
     magic number (DPR rounding makes hard-coded px drift): an 18px zero-width
     strut (≡ the pill's .x button) + the pill's 4px vertical padding + a
     transparent 1px border (≡ the pill's). Keep in sync with .filter-pill/.x. */
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid transparent;
  transition: background 120ms ease-out, color 120ms ease-out, box-shadow 140ms ease-out;
}
.clear-all::before { content: ''; width: 0; height: 18px; flex: none; }
.clear-all:hover,
.clear-all[data-state="hover"] { background: var(--gov-color-primary-50); color: var(--gov-color-primary-700); }
.clear-all:active,
.clear-all[data-state="pressed"] { background: var(--gov-color-primary-100); color: var(--gov-color-primary-700); }
.clear-all:focus-visible,
.clear-all.is-focus {
  outline: none; box-shadow: var(--shadow-focus);
  transition: box-shadow 220ms cubic-bezier(0.16, 1, 0.3, 1), background 120ms ease-out, color 120ms ease-out;
}
.clear-all[hidden] { display: none; }

/* ── enter / leave animation ─────────────────────────────────────────────
   Driven entirely in JS by WAA (so the playground speed control's playbackRate
   loop scales them). Pills/buttons collapse their WIDTH in-flow (opacity + a
   feather mask), so siblings reflow smoothly with NOTHING going position:absolute
   — no overlap, no FLIP jump, no content shift. This `fp-clip` helper makes the
   collapse clean: the element clips its overflow, and its children keep natural
   size (flex:none) so the content slides out behind the mask instead of the flex
   algorithm squishing the text as the box narrows. */
.filter-pill.fp-clip,
.clear-all.fp-clip,
.reset-row.fp-clip { overflow: hidden; display: inline-flex; align-items: center; }
.filter-pill.fp-clip > *,
.reset-row.fp-clip > * { flex: 0 0 auto; }
.filter-pill.is-leaving { pointer-events: none; }

/* demo-only restore control — brings the cleared filters back without reload */
.reset-row {
  all: unset; box-sizing: border-box; cursor: pointer;
  user-select: none; -webkit-user-select: none;   /* controls never text-select */
  display: inline-flex; align-items: center; gap: 5px;
  flex: none; white-space: nowrap;
  font: 500 12px var(--font-sans);
  color: var(--color-fg-tertiary);
  padding: 4px 10px; border-radius: var(--radius-sm);
  margin-left: 2px;
  transition: background 120ms ease-out, color 120ms ease-out, box-shadow 140ms ease-out;
}
.reset-row i.bi { font-size: 12.5px; transform: translateY(0.5px); }
.reset-row:hover,
.reset-row[data-state="hover"] { background: var(--gov-color-neutral-100); color: var(--color-fg-secondary); }
.reset-row:active,
.reset-row[data-state="pressed"] { background: var(--gov-color-neutral-200); }
.reset-row:focus-visible,
.reset-row.is-focus {
  outline: none; box-shadow: var(--shadow-focus);
  transition: box-shadow 220ms cubic-bezier(0.16, 1, 0.3, 1), background 120ms ease-out, color 120ms ease-out;
}

/* demo-only ADD control — inserts a sample pill (with the make-room animation) */
.add-row {
  all: unset; box-sizing: border-box; cursor: pointer;
  user-select: none; -webkit-user-select: none;   /* controls never text-select */
  display: inline-flex; align-items: center; gap: 5px;
  flex: none; white-space: nowrap;
  font: 500 12px var(--font-sans);
  color: var(--gov-color-primary-600);
  padding: 4px 10px; border-radius: var(--radius-sm);
  transition: background 120ms ease-out, color 120ms ease-out, box-shadow 140ms ease-out;
}
.add-row i.bi { font-size: 12px; }
.add-row:hover,
.add-row[data-state="hover"] { background: var(--gov-color-primary-50); color: var(--gov-color-primary-700); }
.add-row:active,
.add-row[data-state="pressed"] { background: var(--gov-color-primary-100); }
.add-row:focus-visible,
.add-row.is-focus {
  outline: none; box-shadow: var(--shadow-focus);
  transition: box-shadow 220ms cubic-bezier(0.16, 1, 0.3, 1), background 120ms ease-out, color 120ms ease-out;
}

/* Reduced motion is handled system-wide in colors_and_type.css — no local
   block (this component used to zero ALL durations including the focus ring,
   which was the inconsistency). */
