/* ============================================================================
   SHARED CUSTOM DROPDOWN
   ----------------------------------------------------------------------------
   The kingdom-style dropdown that started life on the search pages
   (page/search-kingdom.css) and in the search filter fragment
   (component/filter.css). It now lives here, unscoped, so the SAME look is
   used for every dropdown on the site — forms, popups, admin panels, the
   sort control, everything.

   Two ways to get it:

   1. Hand-written markup (what the search filter fragment does):

        <div class="dropdown" data-inline-drop="true">
          <input type="hidden" name="x">
          <div class="dropdown-toggle"><span class="val">Any</span><span class="arr">▾</span></div>
          <div class="dropdown-menu">
            <div data-value="">Any</div>
            …
          </div>
        </div>

   2. Automatic (everything else): just write a normal <select>.
      js/component/custom-select.js wraps every native <select> on the page in
      a `.dropdown.custom-select`, hides the real control and drives it from
      the pretty one. The <select> stays in the DOM, so th:field bindings, form
      serialization, `required` validation and existing onchange handlers all
      keep working untouched.

      Opt out with `data-no-custom-select` on the <select> (or on any ancestor).

   This file is linked globally from fragments/header.html.
   ========================================================================== */

/* ── the box ─────────────────────────────────────────────────────── */

.dropdown {
    position: relative;
    font-size: 13px;
}

.dropdown-toggle {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    background: var(--overlay-sm);
    border: var(--glass-border);
    padding: 10px 12px;
    border-radius: 9px;
    color: #fff;
    user-select: none;
    transition: background .15s, border-color .15s, box-shadow .15s;
}

.dropdown-toggle:hover { background: var(--overlay-md); }

.dropdown-toggle .lbl { color: var(--color-text-muted); }

.dropdown-toggle .val {
    font-weight: 700;
    flex: 1;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dropdown-toggle .arr {
    font-size: 11px;
    color: var(--color-text-subtle);
    transition: transform .2s;
    margin-left: auto;
}

.dropdown.open .dropdown-toggle .arr { transform: rotate(180deg); }

/* keyboard focus gets the same gold ring the inputs use */
.dropdown-toggle:focus-visible {
    outline: none;
    border-color: var(--color-gold, #ffd700);
    box-shadow: var(--shadow-gold, 0 0 20px rgba(255, 215, 0, .3));
}

/* ── the menu ────────────────────────────────────────────────────── */

.dropdown-menu {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    min-width: 100%;
    background: var(--menu-bg);
    border: var(--panel-border);
    border-radius: 11px;
    overflow: hidden;
    z-index: 50;
    box-shadow: var(--shadow-menu);
    opacity: 0;
    transform: translateY(-6px);
    pointer-events: none;
    transition: opacity .18s, transform .18s;
}

.dropdown.open .dropdown-menu {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}

.dropdown-menu div {
    padding: 10px 14px;
    cursor: pointer;
    font-weight: 600;
    color: var(--color-text-muted);
    transition: background .12s, color .12s;
}

/* A suggestion row may carry a display-only hint (the medium type beside a
   series title). It must read as secondary, because unlike the title it is NOT
   part of what gets searched. Lives here, not in filter.css, because the
   character form uses the same menu and does not load the filter panel. */
.suggest-menu .suggest-hint {
    margin-left: 0.5rem;
    opacity: 0.6;
    font-size: 0.85em;
    font-weight: 400;
}

.dropdown-menu div:hover { background: var(--overlay-sm); color: #fff; }
.dropdown-menu div.sel { color: #fff; background: var(--gradient-primary); }

/* the sort control hangs off the right edge */
.dropdown.sort-drop .dropdown-menu { left: auto; right: 0; min-width: 180px; }

/* ── enhanced native <select> ────────────────────────────────────── */

.custom-select {
    /* the wrapper stands in for the <select> it replaced, so it inherits the
       full-width behaviour every form stylesheet assumes for form controls */
    display: block;
    width: 100%;
    min-width: 0;
}

/* The real <select> is kept in the DOM (that is the whole point) but taken out
   of the layout and made invisible. It is deliberately NOT `display: none` and
   NOT `visibility: hidden`: browsers refuse to report a constraint violation on
   a control they consider unfocusable, so a `required` select inside a hidden
   container would silently block submit with "An invalid form control is not
   focusable" in the console. Zero opacity keeps it reportable, and the bubble
   still points at the right place because the element covers the toggle. */
.custom-select > .custom-select__native {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    border: 0;
    background: transparent;
    opacity: 0;
    pointer-events: none;
    -webkit-appearance: none;
    appearance: none;
}

.custom-select .dropdown-menu {
    /* option lists here can be long (continents, languages, enum values) */
    max-height: 260px;
    overflow-y: auto;
    overscroll-behavior: contain;
}

/* flip above the toggle when there is no room below (long forms, modals) */
.custom-select.drop-up .dropdown-menu {
    top: auto;
    bottom: calc(100% + 6px);
    transform: translateY(6px);
}

.custom-select.drop-up.open .dropdown-menu { transform: translateY(0); }

/* an empty-valued option (the "Choose…" / "Any" placeholder) reads as muted */
.custom-select.is-placeholder .dropdown-toggle .val {
    font-weight: 600;
    color: var(--color-text-subtle);
}

.custom-select.is-disabled { opacity: .55; }
.custom-select.is-disabled .dropdown-toggle { cursor: not-allowed; }
.custom-select.is-disabled .dropdown-toggle:hover { background: var(--overlay-sm); }

/* <optgroup> label — a plain caption, not a pickable row */
.custom-select .dropdown-menu .dropdown-group {
    padding: 9px 14px 5px;
    font-size: .78em;
    font-weight: 800;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--color-text-subtle);
    cursor: default;
    background: none;
}

.custom-select .dropdown-menu .dropdown-group:hover {
    background: none;
    color: var(--color-text-subtle);
}

.custom-select .dropdown-menu .dropdown-option.is-disabled {
    opacity: .4;
    cursor: not-allowed;
}

.custom-select .dropdown-menu .dropdown-option.is-disabled:hover {
    background: none;
    color: var(--color-text-muted);
}

/* keyboard cursor (arrow keys) — distinct from the selected row */
.custom-select .dropdown-menu .dropdown-option.active {
    background: var(--overlay-md);
    color: #fff;
}

.custom-select .dropdown-menu .dropdown-option.active.sel {
    background: var(--gradient-primary);
}

/* ── contextual sizing ───────────────────────────────────────────────
   The compact 13px kingdom size is right for filter sidebars and toolbars,
   but inside a `.form-group` the dropdown sits in a column of 1rem inputs
   (see base/form.css) and has to match their rhythm. Match the neighbours
   rather than forcing one size everywhere.

   Deliberately keyed on `.form-group` and not on `.modal-body`: every form
   popup wraps its controls in `.form-group` anyway, while `.modal-body` also
   covers toolbars like the admin user-management filter row, which should stay
   compact.

   SCOPE FIX: these were keyed on `.custom-select`, i.e. only the wrappers
   js/component/custom-select.js builds around a native <select>. A dropdown
   written by hand in the markup - the continent/country pair on the event form
   (item-forms/cp-event.html) and in the "Suggest an event" popup, which copy
   `.dropdown.filter-drop` from fragments/filter.html - therefore kept the 13px
   SEARCH FILTER look while sitting between 1rem form inputs. `.custom-select`
   is itself a `.dropdown`, so keying on `.dropdown` covers both and any future
   hand-written control gets the right size for free: a dropdown takes the style
   of the page it is on, not of the panel its markup was copied from. */

.form-group .dropdown { font-size: 1rem; }

.form-group .dropdown > .dropdown-toggle {
    padding: 1rem;
    border: 2px solid var(--border-color);
    border-radius: var(--radius-md);
    font-size: 1rem;
    font-family: inherit;
}

.form-group .dropdown > .dropdown-toggle:hover { background: var(--overlay-md); }

.form-group .dropdown.open > .dropdown-toggle,
.form-group .dropdown > .dropdown-toggle:focus-visible {
    border-color: var(--color-gold, #ffd700);
    box-shadow: var(--shadow-gold, 0 0 20px rgba(255, 215, 0, .3));
    background: var(--overlay-md);
}

.form-group .dropdown .dropdown-toggle .val { font-weight: 600; }

.form-group .dropdown .dropdown-menu div { font-size: .95rem; }

/* the results toolbar sort control keeps its own pill size */
.sort-dropdown .custom-select > .dropdown-toggle {
    padding: 0.7rem 1rem;
    border: 2px solid rgba(255, 255, 255, 0.3);
    border-radius: 8px;
    font-size: medium;
}

/* RESPONSIVE FIX: iOS zooms the page when a control smaller than 16px is
   focused. The toggle is a div so it never triggers that, but keep the menu
   comfortably tappable on phones. */
@media (max-width: 768px) {
    .custom-select .dropdown-menu div { padding: 12px 14px; }
    .custom-select .dropdown-menu { max-height: 50vh; }
}

/* A hand-written dropdown in a form has the same long option lists (countries,
   continents) that .custom-select caps above, and the same no-room-below
   problem in a modal - but none of custom-select.js's scrolling or flipping,
   because that script only manages the wrappers it built. Give the menu the cap
   here so the country list scrolls inside the popup instead of running off it. */
.form-group .dropdown:not(.custom-select) .dropdown-menu {
    max-height: 260px;
    overflow-y: auto;
    overscroll-behavior: contain;
}
