/* ---- custom dropdown (replaces native <select> rendering) ----
   Markup is built by custom-select.js: .custom-select wraps the hidden
   native select plus a .cs-trigger button and .cs-menu listbox. Colors
   come from the page's own vars (base.css or agent_bio.css); fallbacks
   cover pages that don't define --surface / --brass-light. */
.custom-select{ position:relative; }
/* When open, lift the whole select above sticky bars (e.g. the save bar,
   z-index:50) so its menu isn't painted underneath. The menu's own z-index is
   relative to this element, so the container must win the outer stacking. */
.custom-select.open{ z-index:60; }
.custom-select select.cs-native{
  position:absolute;
  opacity:0;
  width:1px; height:1px;
  margin:-1px; padding:0; border:0;
  pointer-events:none;
}
/* This file is shared by two palettes, so every colour falls back from the
   public bio page's token names to the dashboard's. Two of them were broken on
   the dashboard: --line there is a *width* from the UI kit (1.5px), which
   silently voided `border:1px solid var(--line)` and left every menu
   borderless, and --paper-dim/--brass are undefined, so the hard-coded
   parchment and brass below were painting on a blue dashboard.

   The dashboard's values must stay written at the point of use, NOT aliased
   to --cs-* on :root — custom properties substitute where they are *used*, and the page
   builder rescopes --paper/--hairline/--well to a light panel inside a dark
   root (page_builder_concept.css:86). Aliasing at :root freezes the dark
   values and paints a dark menu on that white panel.

   The --cs-* tokens that DO exist (--cs-line, --cs-hover-bg, --cs-current-*)
   are the other direction and are safe: each is an opt-IN a palette declares
   for itself, with the dashboard value as the var() fallback written here at
   the point of use. base.css sets them for base_app.html pages. Nothing in
   this file reads a page token that something else might alias for an
   unrelated widget -- which is the bug that produced this arrangement, since
   settings pages alias --brass to feed crm.css. */
.cs-trigger{
  width:100%;
  display:flex; align-items:center; justify-content:space-between;
  gap:8px;
  padding:9px 11px;
  font-family:inherit;
  font-size:14px;
  color: var(--ink);
  /* --well before --paper: on dashboard pages --surface is undefined and the
     trigger sits in field rows whose real <input>s are --well-filled — falling
     to --paper gave the one dropdown in the row a different fill. */
  background: var(--surface, var(--well, var(--paper, #fff)));
  border:1px solid var(--cs-line, var(--hairline, var(--line)));
  border-radius: var(--radius-input, 8px);
  cursor:pointer;
  text-align:left;
}
/* --accent terminates each chain: outside the bio page and the settings crm
   bridge, --brass/--brass-light are undefined, and an unterminated chain made
   border-color/outline-color fall to currentColor (ink) on every other page. */
.cs-trigger:hover{ border-color: var(--brass-light, var(--brass, var(--accent))); }
.cs-trigger:focus-visible{ outline:2px solid var(--brass-light, var(--brass, var(--accent))); outline-offset:0; }
.custom-select.open .cs-trigger{ border-color: var(--brass, var(--accent)); }
.cs-trigger .cs-label{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.cs-trigger svg{
  width:14px; height:14px; flex-shrink:0;
  fill:none; stroke:currentColor; stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round;
  color: var(--ink-soft, #666);
  transition: transform 0.15s ease;
}
.custom-select.open .cs-trigger svg{ transform: rotate(180deg); }
.cs-menu{
  /* position:fixed (JS sets top/left/min-width from the trigger's
     getBoundingClientRect() on open) rather than absolute-under-the-trigger:
     a fixed descendant's containing block is the viewport, not any scrolling
     or overflow:hidden ancestor, so the menu paints unclipped no matter what
     scrollable container (a .cal-dialog, a scrollable panel, ...) it opens
     inside of. custom-select.js repositions it on every open; see
     positionMenu() there for the open-up flip. */
  position:fixed;
  z-index:30;
  margin:0; padding:5px;
  list-style:none;
  background: var(--surface, var(--paper, #fff));
  border:1px solid var(--cs-line, var(--hairline, var(--line)));
  border-radius: var(--radius-input, 8px);
  box-shadow: 0 8px 24px rgba(15,23,42,0.16);
  max-height:220px;
  overflow-y:auto;
  /* min-width is set from the trigger's real width in JS (percentage widths
     would resolve against the viewport now, not the trigger). Grows for
     options longer than the current selection (e.g. the compact reminder
     select), capped so it never spans most of a narrow viewport. */
  width:max-content;
  max-width:min(340px, 85vw);
}
.cs-option{
  display:flex; align-items:center; gap:8px;
  padding:8px 10px;
  font-size:13.5px;
  font-weight:600;
  border-radius:6px;
  cursor:pointer;
  white-space:nowrap;
}
/* Same story as the current-row rule below: this read `--paper-dim` with a
   `--well` fallback, and settings pages alias BOTH to the flat --well, so the
   hover tint came out identical to the surface it sits on and nothing
   appeared to happen. The dashboard default is now the app's real hover token
   (--well-hover, what .iqx-per-item:hover uses); the bio page names its own. */
.cs-option:hover{ background: var(--cs-hover-bg, var(--well-hover)); }
/* The current row used to read `var(--brass, transparent)`, using --brass as a
   "which palette am I on?" sentinel: filled brass on the public bio page,
   nothing on the dashboard. That sentinel stopped being reliable. Settings
   pages alias `--brass: var(--accent)` on :root to feed crm.css's timeline
   widget (ui_concept/partials/_settings_styles.html) -- invisible from here,
   and it turned every settings dropdown's current row into exactly the solid
   accent fill the comment below said not to ship.

   So the palette now states its intent instead of being sniffed. The default
   is the dashboard treatment (the soft wash + accent ink that
   .iqx-per-item.active uses); agent_bio.css opts into the filled brass row
   explicitly. Nothing here reads a token another page may alias for an
   unrelated widget. */
.cs-option[aria-selected="true"]{
  background: var(--cs-current-bg, var(--accent-wash));
  color: var(--cs-current-ink, var(--accent));
  font-weight:700;
}
/* With no brass palette — i.e. on the dashboard — the current row is marked
   the way .bk-select-opt.current and .iq-status-opt.current already mark
   theirs: bold plus an accent check, not a filled row. A solid fill in
   --accent would put its white label at roughly 2.6:1. */
.cs-option[aria-selected="true"]::after{
  content:"\2713";
  margin-left:auto;
  font-size:.9em;
  color: var(--cs-current-check, var(--cs-current-ink, var(--accent)));
}

/* ---- phones: the menu becomes a bottom sheet ----
   A popover anchored to the trigger gives the font pickers six visible rows of
   seventy-five on a 390px screen, in a box narrower than the field that opened
   it. Docked to the bottom edge the same list gets real height and sits under
   the thumb. Applies to every upgraded <select>, since they are one component.
   custom-select.js adds .cs-sheet and skips its popover positioning; the class
   is what stops the inline left/top it writes on wider screens from leaking
   in here. */
.cs-scrim{ display:none; }

@media (max-width: 720px){
  .custom-select.cs-sheet .cs-menu{
    top:auto; bottom:0; left:0; right:0;
    width:auto; min-width:0; max-width:none;
    /* dvh so the sheet fits the viewport you can actually see while the
       browser's URL bar is showing, not the taller URL-bar-hidden one. */
    max-height:min(70vh, 560px);
    max-height:min(70dvh, 560px);
    padding:8px 12px calc(12px + env(safe-area-inset-bottom, 0px));
    border-width:1px 0 0;
    border-radius:22px 22px 0 0;
    box-shadow:0 -8px 40px rgba(0,0,0,.18);
    overscroll-behavior:contain;
    transform:translateY(100%);
    transition:transform .28s cubic-bezier(.32,.72,0,1);
    z-index:var(--z-modal, 500);
  }
  .custom-select.cs-sheet.open .cs-menu{ transform:translateY(0); }
  /* While a finger is on the sheet the transform is rewritten inline each
     frame (sheet_swipe.js), so the easing has to come off or the drag trails
     the touch. */
  .custom-select.cs-sheet .cs-menu.dragging{ transition:none; }

  /* The scrim lives inside .custom-select rather than on <body> on purpose:
     the menu often opens inside a panel that is already its own stacking
     context (the page builder's settings drawer is one), and a body-level
     scrim would paint over the menu instead of behind it. */
  .custom-select.cs-sheet .cs-scrim{
    display:block;
    position:fixed; inset:0;
    background:rgba(9,9,11,.45);
    opacity:0; transition:opacity .2s ease;
    z-index:calc(var(--z-modal, 500) - 1);
  }
  .custom-select.cs-sheet.open .cs-scrim{ opacity:1; }

  /* Thumb-sized rows, and long option labels wrap instead of being clipped. */
  .cs-sheet .cs-option{
    padding:13px 12px;
    font-size:15px;
    white-space:normal;
  }
}
@media (max-width: 720px) and (prefers-reduced-motion: reduce){
  .custom-select.cs-sheet .cs-menu,
  .custom-select.cs-sheet .cs-scrim{ transition:none; }
}
