/* ══════════════════════════════════════════════════════════════════════
   fmc-select — the themed option list that replaces the native <select>
   popup.  (2026-08-05, KP)

   WHY THIS EXISTS
   Opening a native <select> in dark mode paints one white frame before the
   list appears.  The popup is an operating-system window the browser
   creates, not part of the page, so its first frame lands before any of our
   colours reach it.  Every CSS lever was verified correct and the flash
   persisted anyway — the whole investigation is written up as KI-001 in
   docs/known-issues.md, with a matching note in fmc-hub-theme.css §4d-ii.
   The only fix is to stop using that window.

   WHAT THIS IS *NOT*
   It is not a replacement control.  The <select> stays in the DOM, visible,
   and styled by whatever page it lives on — .cm-select, .biw-select,
   .rm-select and a dozen others all keep working untouched, because the
   control was never the broken part.  Only the popup is ours.  So there is
   deliberately no `.fsel-button` in this file: there is nothing to style.

   Everything below is a --p-* token, so light is correct by construction
   and dark follows the same re-point as the rest of the Hub.  The one
   exception is the panel fill, which has to be OPAQUE rather than glass —
   see the note on .fsel-panel.
   ══════════════════════════════════════════════════════════════════════ */

/* The panel is appended to <body>, not to the field's container, and
   positioned from the select's bounding rect.  Selects live inside cards,
   tables and scroll wells with `overflow: hidden`, and a panel parented to
   the field would be clipped by every one of them.  Fixed positioning off
   the body is the only placement that cannot be cropped by an ancestor. */
.fsel-panel {
  position: fixed;
  z-index: 1400;              /* over the Hub's modals (1200) and nav (90) */
  box-sizing: border-box;
  min-width: 180px;
  max-height: 340px;
  overflow-y: auto;
  overscroll-behavior: contain;   /* stop the page scrolling behind the list */
  padding: 4px;
  border-radius: 14px;
  /* Opaque, unlike .pn-results which is glass. A translucent panel over
     arbitrary page content makes option text unreadable at exactly the
     moment you are trying to read it, and the whole point of this component
     is that the list is legible. Light fill is white; dark uses the solid
     rung of the ground ramp rather than --p-card, which is translucent. */
  background: #ffffff;
  border: 0.5px solid var(--p-glass-border);
  box-shadow: 0 18px 44px -18px rgba(20, 28, 43, 0.4),
              0 2px 8px -4px rgba(20, 28, 43, 0.25);
  /* Opens instantly. A transition here would reintroduce exactly the class
     of problem this component was built to remove: a frame where the list
     is on screen but not yet showing its real colours. */
  font: inherit;
}
/* On touch the panel itself takes focus, because focusing the <select> is what
   makes iOS present its own picker over this one (the whole story is in
   openFor in fmc-select.js). Focusing a container programmatically draws the
   browser's ring around the entire sheet - an amber rectangle around a list
   nobody tabbed to. Removing it loses nothing: the focus indicator here is the
   row, and .fsel-opt.is-active carries a teal ring of its own.  (2026-08-10) */
.fsel-panel:focus,
.fsel-panel:focus-visible { outline: none; }

html[data-hub-theme="dark"] body.portal-light.hub-theme-surface .fsel-panel {
  background: var(--d-panel-solid);
  border-color: var(--p-line-strong);
  box-shadow: 0 20px 48px -18px rgba(0, 0, 0, 0.66),
              0 2px 10px -4px rgba(0, 0, 0, 0.5);
}

/* ── Group heading, from <optgroup label> ──────────────────────────────
   Same register as .pn-results-group, so a grouped select reads like the
   customer search panel on the proposal page rather than like a new idea. */
.fsel-group {
  padding: 11px 12px 5px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--p-ink-3);
}
.fsel-group:first-child { padding-top: 6px; }

/* ── Options ── */
.fsel-opt {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 9px 12px;
  border-radius: 10px;
  font-size: 13.5px;
  line-height: 1.35;
  color: var(--p-ink);
  cursor: pointer;
  user-select: none;
}
.fsel-opt-label { min-width: 0; flex: 1 1 auto; overflow-wrap: anywhere; }

/* `is-active` is the keyboard cursor, `is-selected` is the committed value.
   They are different things and are shown differently: the cursor is a
   wash, the committed value is a tick plus weight. A list where the two
   look alike is a list you cannot arrow through. The inset ring rides
   along because the wash alone sat near 1.1:1 against the panel: fine as
   a hover, invisible as the only trace of where the keyboard is
   (2026-08-08). */
.fsel-opt.is-active {
  background: var(--p-teal-tint);
  box-shadow: inset 0 0 0 2px var(--p-teal-ring, rgba(0, 125, 113, .35));
}
.fsel-opt.is-selected { font-weight: 650; color: var(--p-teal-deep); }
.fsel-opt.is-selected .fsel-tick { opacity: 1; }
.fsel-tick {
  flex: 0 0 auto;
  width: 14px; height: 14px;
  opacity: 0;
  color: var(--p-teal-deep);
}
html[data-hub-theme="dark"] body.portal-light.hub-theme-surface .fsel-opt.is-selected,
html[data-hub-theme="dark"] body.portal-light.hub-theme-surface .fsel-tick {
  color: var(--p-teal);
}

/* A disabled <option> is usually a placeholder ("Pick a company…"). Shown,
   because it explains the list, but not selectable. */
.fsel-opt.is-disabled {
  color: var(--p-ink-3);
  cursor: default;
  font-style: italic;
}
.fsel-opt.is-disabled.is-active { background: transparent; box-shadow: none; }

/* ── Filter ───────────────────────────────────────────────────────────
   Appears only past FILTER_MIN options (see fmc-select.js). A search box
   over a three-item Yes/No/Maybe picker is clutter; over the 90-odd rows on
   Onboarding Settings it is the difference between usable and not. */
.fsel-filterwrap {
  position: sticky; top: 0; z-index: 1;
  padding: 4px 4px 6px;
  background: inherit;
}
.fsel-filter {
  width: 100%;
  box-sizing: border-box;
  padding: 8px 11px;
  font: inherit;
  font-size: 13px;
  color: var(--p-ink);
  background: var(--p-glass-strong);
  border: 0.5px solid var(--p-line-strong);
  border-radius: 9px;
}
.fsel-filter::placeholder { color: var(--p-ink-3); }
.fsel-filter:focus {
  outline: none;
  border-color: var(--p-teal-ring);
  box-shadow: 0 0 0 3px var(--p-teal-tint);
}
html[data-hub-theme="dark"] body.portal-light.hub-theme-surface .fsel-filter {
  background: var(--d-void-2);
}

.fsel-empty {
  padding: 14px 13px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--p-ink-3);
}

/* ── Touch ────────────────────────────────────────────────────────────
   KP chose the custom list on every device, so on a phone it becomes a
   bottom sheet rather than a small panel pinned under the field. A finger
   reaches the bottom of the screen; a 200px list floating mid-page next to
   the keyboard is the thing native pickers exist to avoid. Rows go to 44px,
   the iOS minimum target.

   The positioning half of this lives in fmc-select.js, which reads the same
   `(pointer: coarse)` query — change one, change the other. */
@media (pointer: coarse) {
  .fsel-panel {
    border-radius: 18px 18px 0 0;
    /* dvh, not vh: the sheet holds the filter input, and against the large
       viewport the on-screen keyboard pushed the list's tail out of reach
       (2026-08-08). Older engines fall back to the vh line above it. */
    max-height: 62vh;
    max-height: 62dvh;
    padding: 6px 6px calc(8px + env(safe-area-inset-bottom, 0px));
    box-shadow: 0 -14px 40px -12px rgba(20, 28, 43, 0.4);
  }
  .fsel-opt { min-height: 44px; padding: 11px 14px; font-size: 15px; }
  .fsel-group { padding: 13px 14px 6px; }
  .fsel-filter { padding: 11px 13px; font-size: 15px; }
}

/* The backdrop exists on touch only. On a desktop, clicking away closes the
   list and a scrim would be visual noise; on a phone the sheet needs
   something to dim behind it and to catch the dismissing tap. */
.fsel-scrim {
  position: fixed; inset: 0;
  z-index: 1399;
  background: rgba(12, 18, 28, 0.42);
  display: none;
}
@media (pointer: coarse) { .fsel-scrim.is-open { display: block; } }

/* ── App entrance (2026-08-11, KP: "smoother") ────────────────────────
   In the native app the sheet was simply THERE - one frame closed, the
   next frame open - and the scrim with it. A short rise-and-fade takes
   the edge off. Gated on body.in-native-app, so the website keeps the
   deliberate instant open described at the top of this file; and these
   animate transform and opacity ONLY - every colour is final from the
   first frame, so the no-unthemed-frame rule this module was built
   around still holds. The exit stays instant on purpose: a picked
   option should feel committed, and close() removes both nodes in the
   same tick. The curve is the Hub's own spring (sr-compose,
   sa-customize). */
body.in-native-app .fsel-panel {
  animation: fselRise 200ms cubic-bezier(0.2, 0.9, 0.3, 1.05);
}
body.in-native-app .fsel-scrim.is-open {
  animation: fselFade 160ms ease-out;
}
@keyframes fselRise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes fselFade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Honour the OS setting. The list still opens instantly either way; this
   covers the app's rise-and-fade above (panel and scrim both). */
@media (prefers-reduced-motion: reduce) {
  .fsel-panel, .fsel-scrim { animation: none !important; }
}

/* ── Popover box reset (2026-08-07) ─────────────────────────────────
   When the panel opens inside a modal <dialog> the script promotes the
   pair into the top layer as manual popovers (see openFor). The UA
   popover stylesheet would otherwise stretch them: it sets inset: 0,
   margin: auto, a border and fit-content sizing. The panel's placement
   is inline top/left/width from place(), so only the box properties the
   panel's own rules do not set are neutralized here; the scrim keeps
   its own inset: 0 from above, which as an author rule already beats
   the UA sheet. Nothing here changes how either renders outside a
   modal. */
.fsel-panel[popover] {
  inset: auto;
  margin: 0;
  height: auto;
  color: inherit;
}
.fsel-scrim[popover] {
  margin: 0;
  border: 0;
  padding: 0;
  width: auto;
  height: auto;
  color: inherit;
}
