/* multi-select-filter.css — shared by the vanilla and React bindings (same class names).
 *
 * Tokens: every colour/motion value maps to the house semantic tokens from
 * Factory/UI_STANDARDS.md §3 (bg-surface, text-muted, accent-primary, focus-ring ...) and the
 * motion tokens from projects/_shared/ui-effects/motion-tokens.css, with OKLCH fallbacks so the
 * file also works stand-alone. Override any --msf-* on :root or on a wrapper.
 * Motion: transform + opacity only (ui-transitions law 1), origin-aware (law 3), reduced-motion =
 * fade only (UI_STANDARDS §5). Rows are 36px on desktop (UI_STANDARDS §11 compact 32-40px) and
 * 44px on touch / in the phone sheet.
 */

:root {
  --msf-bg: var(--bg-elevated, oklch(99.5% 0.003 260));
  --msf-surface: var(--bg-surface, oklch(100% 0 0));
  --msf-subtle: var(--bg-subtle, oklch(96.2% 0.006 260));
  --msf-text: var(--text-primary, oklch(23% 0.02 260));
  --msf-muted: var(--text-muted, oklch(46% 0.02 260));
  --msf-border: var(--border-subtle, oklch(89% 0.008 260));
  --msf-border-strong: var(--border-strong, oklch(70% 0.012 260));
  --msf-accent: var(--accent-primary, oklch(50% 0.17 258));
  --msf-accent-soft: var(--accent-primary-soft, oklch(94.5% 0.035 258));
  --msf-on-accent: var(--text-inverted, oklch(99% 0 0));
  --msf-focus: var(--focus-ring, oklch(58% 0.18 258));
  --msf-error: var(--error, oklch(50% 0.19 27));
  --msf-shadow: 0 12px 32px -8px oklch(20% 0.02 260 / 0.22), 0 2px 6px oklch(20% 0.02 260 / 0.08);
  --msf-backdrop: oklch(15% 0.01 260 / 0.35);
  --msf-radius: 8px;
  --msf-radius-lg: 12px;
  --msf-z: 50;
  --msf-dur-fast: var(--motion-fast, 180ms);
  --msf-dur-base: var(--motion-base, 240ms);
  --msf-ease: var(--ease-snappy, cubic-bezier(0.22, 1, 0.36, 1));
  --msf-row-h: 36px;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --msf-bg: var(--bg-elevated, oklch(25% 0.014 260));
    --msf-surface: var(--bg-surface, oklch(20% 0.012 260));
    --msf-subtle: var(--bg-subtle, oklch(30% 0.014 260));
    --msf-text: var(--text-primary, oklch(95% 0.008 260));
    --msf-muted: var(--text-muted, oklch(74% 0.015 260));
    --msf-border: var(--border-subtle, oklch(36% 0.014 260));
    --msf-border-strong: var(--border-strong, oklch(52% 0.016 260));
    --msf-accent: var(--accent-primary, oklch(74% 0.13 258));
    --msf-accent-soft: var(--accent-primary-soft, oklch(34% 0.06 258));
    --msf-on-accent: var(--text-inverted, oklch(18% 0.02 260));
    --msf-focus: var(--focus-ring, oklch(76% 0.13 258));
    --msf-error: var(--error, oklch(72% 0.16 27));
    --msf-shadow: 0 16px 40px -8px oklch(0% 0 0 / 0.6), 0 2px 6px oklch(0% 0 0 / 0.4);
    --msf-backdrop: oklch(0% 0 0 / 0.5);
  }
}
:root[data-theme="dark"] {
  --msf-bg: var(--bg-elevated, oklch(25% 0.014 260));
  --msf-surface: var(--bg-surface, oklch(20% 0.012 260));
  --msf-subtle: var(--bg-subtle, oklch(30% 0.014 260));
  --msf-text: var(--text-primary, oklch(95% 0.008 260));
  --msf-muted: var(--text-muted, oklch(74% 0.015 260));
  --msf-border: var(--border-subtle, oklch(36% 0.014 260));
  --msf-border-strong: var(--border-strong, oklch(52% 0.016 260));
  --msf-accent: var(--accent-primary, oklch(74% 0.13 258));
  --msf-accent-soft: var(--accent-primary-soft, oklch(34% 0.06 258));
  --msf-on-accent: var(--text-inverted, oklch(18% 0.02 260));
  --msf-focus: var(--focus-ring, oklch(76% 0.13 258));
  --msf-error: var(--error, oklch(72% 0.16 27));
  --msf-shadow: 0 16px 40px -8px oklch(0% 0 0 / 0.6), 0 2px 6px oklch(0% 0 0 / 0.4);
  --msf-backdrop: oklch(0% 0 0 / 0.5);
}

/* HSL fallback for browsers without OKLCH (UI_STANDARDS §3). Light palette only; dark degrades to it. */
@supports not (color: oklch(0% 0 0)) {
  :root {
    --msf-bg: var(--bg-elevated, hsl(220 20% 99%)); --msf-surface: var(--bg-surface, #fff);
    --msf-subtle: var(--bg-subtle, hsl(220 16% 95%)); --msf-text: var(--text-primary, hsl(222 22% 15%));
    --msf-muted: var(--text-muted, hsl(222 10% 40%)); --msf-border: var(--border-subtle, hsl(220 14% 86%));
    --msf-border-strong: var(--border-strong, hsl(220 10% 62%)); --msf-accent: var(--accent-primary, hsl(222 70% 45%));
    --msf-accent-soft: var(--accent-primary-soft, hsl(222 80% 95%)); --msf-on-accent: var(--text-inverted, #fff);
    --msf-focus: var(--focus-ring, hsl(222 80% 55%)); --msf-error: var(--error, hsl(4 70% 45%));
    --msf-shadow: 0 12px 32px -8px hsl(222 30% 10% / 0.22); --msf-backdrop: hsl(222 30% 8% / 0.35);
  }
}

/* ---- trigger --------------------------------------------------------------------------- */
.msf { position: relative; display: inline-flex; align-items: center; gap: 4px; flex-shrink: 0; color: var(--msf-text); font: inherit; }
.msf-trigger {
  display: inline-flex; align-items: center; gap: 8px; min-height: var(--msf-row-h); padding: 0 12px;
  border: 1px solid var(--msf-border); border-radius: var(--msf-radius); background: var(--msf-surface);
  color: var(--msf-text); font: inherit; font-size: 0.875rem; line-height: 1.2; cursor: pointer;
  transition: border-color var(--msf-dur-fast) var(--msf-ease), background-color var(--msf-dur-fast) var(--msf-ease), transform var(--msf-dur-fast) var(--msf-ease);
}
.msf-trigger:hover { border-color: var(--msf-border-strong); }
.msf-trigger:active { transform: scale(0.98); }
.msf-trigger:focus-visible, .msf-act:focus-visible, .msf-done:focus-visible,
.msf-twisty:focus-visible, .msf-search:focus-visible { outline: 2px solid var(--msf-focus); outline-offset: 2px; }
.msf-trigger:disabled { opacity: 0.45; cursor: not-allowed; transform: none; }
.msf-label { color: var(--msf-muted); }
.msf-summary { max-width: 11rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }
.msf-chev { width: 10px; height: 6px; flex-shrink: 0; opacity: 0.6; transition: transform var(--msf-dur-fast) var(--msf-ease); }
.msf-trigger[aria-expanded="true"] .msf-chev { transform: rotate(180deg); }
/* Active = accent border + tint AND the summary text changes, so colour is never the only signal. */
.msf.is-active .msf-trigger { border-color: var(--msf-accent); background: var(--msf-accent-soft); }

/* busy: hairline under the trigger (Meetup Filters.tsx 414-424). linear is right for progress. */
.msf-busy-bar { position: absolute; left: 0; right: 0; bottom: -3px; height: 2px; overflow: hidden; opacity: 0; pointer-events: none; }
.msf.is-busy .msf-busy-bar { opacity: 1; }
.msf.is-busy .msf-busy-bar::before { content: ""; position: absolute; inset: 0; width: 33%; background: var(--msf-accent); animation: msf-slide 1s linear infinite; }
@keyframes msf-slide { from { transform: translateX(-100%); } to { transform: translateX(300%); } }

/* header variant: a tiny ▾ in a <th>, visually 22px, hit area 44px via ::after */
.msf[data-variant="header"] { vertical-align: middle; margin-left: 2px; }
.msf[data-variant="header"] .msf-trigger { position: relative; min-height: 0; height: 22px; padding: 0 4px; gap: 2px; border-color: transparent; background: transparent; color: var(--msf-muted); }
.msf[data-variant="header"] .msf-trigger::after { content: ""; position: absolute; inset: -11px -8px; }
.msf[data-variant="header"] .msf-trigger:hover { color: var(--msf-text); background: var(--msf-subtle); }
.msf[data-variant="header"].is-active .msf-trigger { color: var(--msf-accent); background: var(--msf-accent-soft); }
.msf-badge { font-size: 0.7rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.msf-badge:empty { display: none; }

/* "i" — standing rule: every data control explains itself. It is an info-tip button: load info-tip.css
 * (.claude/skills/info-tip), which draws it with an exact 44x44 hit area (regression: 2026-10-14-hit-area-42px) and
 * puts its popover in <body> (never under the box, never widening the page). Here it keeps its 18px look through
 * info-tip's custom properties, which inherit, so stylesheet order never matters. */
.msf {
  --it-size: 18px;
  --it-btn-font: 11px;
  --it-btn-text: var(--msf-muted);
  --it-btn-border: var(--msf-border-strong);
}

/* ---- the box ----------------------------------------------------------------------------- */
.msf-backdrop { position: fixed; inset: 0; z-index: calc(var(--msf-z) - 1); background: var(--msf-backdrop); }
.msf-backdrop[hidden], .msf-panel[hidden] { display: none; }
.msf-panel {
  position: fixed; z-index: var(--msf-z); display: flex; flex-direction: column; gap: 4px;
  min-width: 15rem; max-width: min(22rem, calc(100vw - 16px)); max-height: 22rem; padding: 8px;
  border: 1px solid var(--msf-border); border-radius: var(--msf-radius-lg); background: var(--msf-bg);
  color: var(--msf-text); box-shadow: var(--msf-shadow); font-size: 0.875rem; text-align: left;
  font-weight: 400; text-transform: none; letter-spacing: normal; white-space: normal;
  transform-origin: top left; overscroll-behavior: contain;
}
.msf-panel[data-side="top"] { transform-origin: bottom left; }
.msf-panel[data-state="open"] { animation: msf-in var(--msf-dur-base) var(--msf-ease) both; }
.msf-panel[data-state="closing"] { animation: msf-out var(--msf-dur-fast) var(--msf-ease) both; pointer-events: none; }
@keyframes msf-in { from { opacity: 0; transform: translateY(-4px) scale(0.97); } to { opacity: 1; transform: none; } }
@keyframes msf-out { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(-4px) scale(0.97); } }

.msf-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 0 4px; }
.msf-title { font-size: 0.75rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--msf-muted); }
.msf-done { display: none; min-height: 44px; padding: 0 12px; border: 0; border-radius: var(--msf-radius); background: transparent; color: var(--msf-accent); font: inherit; font-weight: 600; cursor: pointer; }
.msf-infoline { margin: 0; padding: 0 4px; font-size: 0.75rem; line-height: 1.45; color: var(--msf-muted); }
.msf-infoline[hidden] { display: none; }

.msf-search {
  width: 100%; box-sizing: border-box; min-height: var(--msf-row-h); padding: 0 12px;
  border: 1px solid var(--msf-border); border-radius: var(--msf-radius); background: var(--msf-surface);
  color: var(--msf-text); font: inherit;
}
.msf-search::placeholder { color: var(--msf-muted); }
.msf-search[hidden] { display: none; }

.msf-acts { display: flex; gap: 4px; padding: 0 0 4px; border-bottom: 1px solid var(--msf-border); }
.msf-acts[hidden] { display: none; }
.msf-act {
  min-height: 32px; padding: 0 8px; border: 0; border-radius: var(--msf-radius); background: transparent;
  color: var(--msf-accent); font: inherit; font-size: 0.8125rem; font-weight: 500; cursor: pointer;
  transition: background-color var(--msf-dur-fast) var(--msf-ease);
}
.msf-act:hover:not(:disabled) { background: var(--msf-subtle); }
.msf-act:disabled { color: var(--msf-muted); opacity: 0.6; cursor: default; }
.msf-act[hidden] { display: none; }

.msf-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.msf-row {
  display: flex; align-items: center; gap: 10px; min-height: var(--msf-row-h); padding: 0 8px;
  border-radius: var(--msf-radius); cursor: pointer; user-select: none;
  transition: background-color var(--msf-dur-fast) var(--msf-ease);
}
.msf-row:hover { background: var(--msf-subtle); }
.msf-row:has(.msf-cb:focus-visible) { outline: 2px solid var(--msf-focus); outline-offset: -2px; }
.msf-row.is-disabled { opacity: 0.45; cursor: not-allowed; }
.msf-row.is-disabled:hover { background: transparent; }
.msf-cb { width: 16px; height: 16px; margin: 0; flex-shrink: 0; accent-color: var(--msf-accent); cursor: inherit; }
.msf-text { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.msf-note { color: var(--msf-muted); font-size: 0.75rem; }
.msf-row.is-stale .msf-text { font-style: italic; }
.msf-count { flex-shrink: 0; color: var(--msf-muted); font-size: 0.75rem; font-variant-numeric: tabular-nums; }

/* region > country tree */
.msf-ghead { display: flex; align-items: center; }
.msf-twisty {
  display: inline-grid; place-items: center; width: 28px; min-height: var(--msf-row-h); flex-shrink: 0; padding: 0;
  border: 0; border-radius: var(--msf-radius); background: transparent; color: var(--msf-muted); cursor: pointer;
}
.msf-twisty .msf-chev { transform: rotate(-90deg); }
.msf-twisty[aria-expanded="true"] .msf-chev { transform: none; }
.msf-grow { flex: 1 1 auto; font-weight: 600; }
.msf-kids { padding-left: 28px; }
.msf-kids[hidden] { display: none; }

.msf-empty, .msf-hint, .msf-error { margin: 0; padding: 4px; font-size: 0.75rem; line-height: 1.45; }
.msf-empty { color: var(--msf-muted); }
.msf-hint { color: var(--msf-muted); border-top: 1px solid var(--msf-border); padding-top: 8px; }
.msf-error { color: var(--msf-error); font-weight: 500; }
.msf-empty[hidden], .msf-hint[hidden], .msf-error[hidden] { display: none; }

.msf-sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

/* ---- phones: bottom sheet with a titled header and Done (Meetup FilterMenu.tsx 84-121) ---- */
.msf-panel.msf-sheet {
  left: 12px; right: 12px; bottom: 12px; top: auto; min-width: 0; max-width: none; max-height: 70vh;
  padding: 12px; border-radius: 16px; transform-origin: bottom center;
}
.msf-panel.msf-sheet[data-state="open"] { animation-name: msf-sheet-in; }
.msf-panel.msf-sheet[data-state="closing"] { animation-name: msf-sheet-out; }
@keyframes msf-sheet-in { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@keyframes msf-sheet-out { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(16px); } }
.msf-panel.msf-sheet .msf-done { display: inline-flex; align-items: center; }
.msf-panel.msf-sheet .msf-title { font-size: 0.875rem; text-transform: none; letter-spacing: normal; color: var(--msf-text); }
.msf-panel.msf-sheet .msf-search { font-size: 16px; } /* < 16px makes iOS zoom the page on focus */

@media (pointer: coarse), (max-width: 639.98px) {
  :root { --msf-row-h: 44px; }
  .msf-act { min-height: 44px; padding: 0 12px; }
  .msf-cb { width: 20px; height: 20px; }
  /* regression: 2026-10-14-hit-area-42px. Touch: the 18px "i" and the 22px header ▾ each answer a full 44x44, and
   * sit far enough from their neighbours that the hit areas do not overlap (a later .msf, being positioned, painted
   * over the "i" hit area and cut it to 38px wide; the old header inset -11px -8px gave 34x42). */
  .msf-info { margin-inline: 9px; }
  .msf[data-variant="header"] { margin-left: 12px; }
  .msf[data-variant="header"] .msf-trigger::after { inset: calc(50% - 22px); }
}

/* ---- reduced motion: fade only (UI_STANDARDS §5) ---- */
@media (prefers-reduced-motion: reduce) {
  .msf-panel[data-state="open"], .msf-panel.msf-sheet[data-state="open"] { animation-name: msf-fade-in; }
  .msf-panel[data-state="closing"], .msf-panel.msf-sheet[data-state="closing"] { animation-name: msf-fade-out; }
  .msf-chev, .msf-trigger { transition: opacity var(--msf-dur-fast) linear; }
  .msf-trigger:active { transform: none; }
  .msf-trigger[aria-expanded="true"] .msf-chev { transform: rotate(180deg); } /* state, not motion: it flips without animating */
  .msf.is-busy .msf-busy-bar::before { animation: none; width: 100%; opacity: 0.5; }
}
@keyframes msf-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes msf-fade-out { from { opacity: 1; } to { opacity: 0; } }
