/*
    THE LOCATION CHOOSER  --  shared skin for the homepage hero and the search
    filter bar.

    Hand-written CSS, loaded with a filemtime cache-buster from the partial's
    @push('styles'). It is NOT part of any Vite entry and must not become one:
    the Shop package's vite config builds with emptyOutDir, and the live cars
    stylesheet on this box cannot be reproduced from source, so a build run for
    the property channel would empty the directory the other channel is served
    from.

    ------------------------------------------------------------------------
    WHAT THIS FILE OWNS AND WHAT IT LEAVES ALONE
    ------------------------------------------------------------------------

    It owns the panel: the sheet of districts that drops out of the field. It
    does NOT own the field. `.hzloc__input` sits beside the call site's own class
    -- `.hz-search__input` on the hero, `.hzp-input__field` on the filter bar --
    and those two keep every visual property they had, because the two fields are
    meant to look like the pages they are on rather than like each other. The
    only rule here that touches the input is the one that stops iOS drawing its
    own clear button over the panel's edge.

    `.hzloc` goes on the call site's EXISTING container -- .hz-search on the
    hero, .hzp-input on the bar -- rather than on a wrapper of the partial's own.
    Both are flex rows with the icon, the clear control and the submit button
    laid out as siblings of the field, and inserting a wrapper between them would
    have meant re-doing both layouts to gain nothing.

    ------------------------------------------------------------------------
    HOW IT OPENS, AND WHY IT IS CSS THAT DOES IT
    ------------------------------------------------------------------------

    :focus-within, which is the browser's, so the panel drops the instant the
    field takes focus -- before Vue mounts on #app and rebuilds everything inside
    it, and for a reader whose script never arrives at all. Every interactive
    feature that has broken on this channel broke by depending on a listener that
    the mount discarded; this one cannot, because opening was never a listener.

    data-hzloc-open is the script's override, and it exists for one case that CSS
    cannot express: Escape has to close the panel while focus STAYS in the field,
    and :focus-within is still true at that moment. "0" wins over the focus rule,
    "1" opens without focus being inside. The attribute is absent until the
    script has something to say, so the default state is the CSS one.
*/

.hzloc {
    /* The panel is absolute against this. Neither call site set it: .hzp-input
       already had it for its own clear button, .hz-search did not, and adding it
       to a flex row with no offsets changes nothing about the layout. */
    position: relative;
}

/*
    Safari and iOS draw a clear button inside type="search" that sits on top of
    the panel's top edge and swallows the first click. The field keeps its own
    clear affordance at both call sites -- a reset button on the hero, a link on
    the bar -- so nothing is lost by turning the platform one off.
*/
.hzloc__input::-webkit-search-decoration,
.hzloc__input::-webkit-search-cancel-button {
    -webkit-appearance: none;
    appearance: none;
}

/* ---------------------------------------------------------------------------
   The chip: the district that is applied
   ---------------------------------------------------------------------------

   The field came back blank on a filtered page and this is what fills it. The
   district is shown BESIDE the box rather than inside it as its value, because
   the box's value is submitted as `query` and the label is a translated word --
   putting one in the other is how the control this replaced ended up sending
   ?query=عبدون from Arabic and ?query=Abdoun from English for the same click.

   The chip is a sibling of the field in both call sites' existing flex rows,
   which is why nothing here needs :has() and why neither page's stylesheet is
   touched: `.hzloc__chip ~ .hzloc__input` reaches the field from the chip, and
   the chip is printed before it precisely so that it can.
   --------------------------------------------------------------------------- */

/* For a reader who cannot see the chip. It is what the field's
   aria-describedby points at, so the state is announced with the control it
   belongs to rather than being a stray phrase somewhere in the row. */
.hzloc__sr {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
}

/*
    In 'submit' mode the partial prints the chip empty and hidden and the script
    fills it in, because nothing reloads there to render it. [hidden] is a UA
    rule of display: none and the rule below sets display: inline-flex, which
    beats it on specificity -- without this restatement every homepage would
    show a blank pill sitting in the search field.
*/
.hzloc__chip[hidden] {
    display: none;
}

.hzloc__chip {
    /* Neither grows nor shrinks.
    
       It was shrinkable, on the theory that a box too small to type in is worse
       than a clipped word. Measured, that theory was wrong in both directions:
       the bar's location field is 294px at 1440, and the chip gave up its own
       name -- rendering "Abd..." -- next to 184px of empty box. The box is what
       should shrink. It has min-width: 0 and needs far less room to be typeable
       than a place name needs to be recognisable.

       max-width below is what stops that going too far the other way. */
    flex: 0 0 auto;

    display: inline-flex;
    align-items: center;
    gap: 2px;

    /* Half the row, at most. Nine district names are short and none of them
       reaches this, but the cap is what stops a long one from being the reason
       a reader cannot see what they are typing. */
    max-width: 50%;
    min-width: 0;

    padding-inline: 10px 3px;
    border-radius: 999px;
    background: #EAF1FF;
    color: #0745D9;
    font-size: 13px;
    font-weight: 600;
    line-height: 26px;
    white-space: nowrap;
}

.hzloc__chip-label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

.hzloc__chip-clear {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    color: inherit;
    text-decoration: none;
}

.hzloc__chip-clear svg {
    width: 12px;
    height: 12px;
}

.hzloc__chip-clear:hover {
    background: rgba(7, 69, 217, 0.18);
}

.hzloc__chip-clear:focus-visible {
    outline: 2px solid #0745D9;
    outline-offset: 1px;
}

/*
    The field, once a chip is in front of it.

    .hzp-input__field is width: 100%, which was right when it was the only thing
    in the box and would squeeze the chip to nothing now that it is not. The
    hero's field is already flex: 1 1 auto and this only restates it.
*/
.hzloc__chip:not([hidden]) ~ .hzloc__input {
    /* Basis 0, not auto. An <input> has an intrinsic width of about twenty
       characters, and with that as its flex basis the row was over-full before
       anything had been laid out -- which is what was squeezing the chip. From
       zero the box simply takes whatever the chip has not. */
    flex: 1 1 0;
    width: auto;
    min-width: 0;
}

/*
    The search bar's magnifier is positioned rather than laid out, and the field
    used to clear it with padding-inline-start: 36px. With a chip in front, the
    chip is the thing that has to clear it, and the field goes back to a normal
    gap from its new neighbour. .hzp-input has no column-gap of its own -- the
    hero's row does, which is why the hero needs neither of these rules.
*/
.hzp-input--go .hzloc__chip {
    margin-inline-start: 36px;
}

.hzp-input--go .hzloc__chip:not([hidden]) ~ .hzloc__input {
    padding-inline-start: 8px;
}

@media (forced-colors: active) {
    /* The tint is dropped in this mode, and the chip would read as loose text
       sitting in the field rather than as one removable thing. */
    .hzloc__chip {
        border: 1px solid CanvasText;
    }
}

/* ---------------------------------------------------------------------------
   The panel
   --------------------------------------------------------------------------- */

.hzloc__panel {
    position: absolute;
    z-index: 40;

    /* Logical properties throughout, so the panel hangs off the correct edge in
       Arabic without a single [dir="rtl"] override. The channel is RTL for half
       its readers and a left/right rule here would have been a bug in one of the
       two languages, found later. */
    inset-block-start: calc(100% + 6px);
    inset-inline-start: 0;
    inset-inline-end: 0;

    display: none;

    max-height: 320px;
    padding: 8px 0;
    overflow-y: auto;
    overscroll-behavior: contain;

    border: 1px solid #e2e5ec;
    border-radius: 12px;
    background: #ffffff;
    box-shadow: 0 12px 32px rgba(16, 20, 32, 0.14);

    text-align: start;
}

.hzloc:focus-within > .hzloc__panel {
    display: block;
}

/* The script's word, and it beats the focus rule above on both counts: it comes
   later and it is more specific. */
.hzloc[data-hzloc-open="1"] > .hzloc__panel {
    display: block;
}

.hzloc[data-hzloc-open="0"] > .hzloc__panel {
    display: none;
}

/* ---------------------------------------------------------------------------
   The hero clips, and this is the already-established way out of it
   ---------------------------------------------------------------------------

   .hz-hero carries overflow: hidden so the cover-sized background photo is
   cropped to the band. An absolutely positioned panel inside it is cropped by
   the same rule -- measured on the homepage at 1440: the panel is 320px tall,
   the hero ends 163px below its top, so five of the nine districts were cut off
   with nothing on screen to say so. The panel passes every "is it visible" test
   throughout, because it has a real box; it is an ancestor doing the cropping.

   property.css already met this exact problem with the filter chips and solved
   it with `.hz-hero:has(details[data-hz-chip][open]) { overflow: visible }`.
   This is that rule for this control, written here rather than there so the
   homepage stylesheet -- which another session owns -- is not touched.

   Only `visible` is asserted, never `hidden`. Re-asserting hidden would mean
   competing with the chip rule for the case where a chip is open and the
   chooser merely has focus, and losing that race would clip the chips instead.
   Leaving the hero unclipped for as long as the field holds focus costs nothing:
   with the panel display: none there is nothing outside the hero to show.
*/
.hz-hero:has(.hzloc:focus-within),
.hz-hero:has(.hzloc[data-hzloc-open="1"]) {
    overflow: visible;
}

.hzloc__heading {
    margin: 0;
    padding: 4px 14px 8px;
    color: #8b929f;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

/* Arabic has no letter case and no tradition of tracked-out small caps; the
   transform does nothing there and the letter-spacing actively harms joined
   script by pulling the connections apart. */
[dir="rtl"] .hzloc__heading {
    letter-spacing: 0;
    text-transform: none;
}

.hzloc__list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.hzloc__item {
    margin: 0;
}

.hzloc__opt {
    display: block;
    padding: 9px 14px;
    border: 0;
    background: transparent;
    color: #1c2033;
    font-family: inherit;
    font-size: 14px;
    line-height: 1.35;
    text-align: start;
    text-decoration: none;
    cursor: pointer;
}

.hzloc__opt:hover {
    background: #f3f4f8;
}

/*
    The keyboard's position in the list, moved by the arrow keys.

    A class rather than :focus, because in the ARIA combobox pattern focus never
    leaves the text field -- the field owns aria-activedescendant and the option
    is only pointed at. Styling :focus would have meant moving focus, which takes
    the caret out of the field and breaks typing to narrow the list.
*/
.hzloc__opt.is-active {
    background: #EAF1FF;
    color: #0745D9;
}

/* Still drawn for the no-script path, where the options are ordinary links and
   Tab really does move through them. */
.hzloc__opt:focus-visible {
    outline: 2px solid #0745D9;
    outline-offset: -2px;
}

/* The district currently applied. Marked, not hidden: seeing which one is on is
   how a reader knows the filter is set at all. */
.hzloc__opt.is-on {
    font-weight: 600;
}

.hzloc__opt.is-on::after {
    content: "✓";
    float: inline-end;
    color: #0745D9;
}

.hzloc__opt--any {
    color: #0745D9;
}

/* Hidden by the script, which is the only thing that can know whether anything
   matched what was typed. */
.hzloc__item[hidden],
.hzloc__none[hidden] {
    display: none;
}

.hzloc__none {
    margin: 0;
    padding: 10px 14px;
    color: #6b7280;
    font-size: 13px;
    line-height: 1.4;
}

/* ---------------------------------------------------------------------------
   Handsets
   ---------------------------------------------------------------------------

   The panel is already pinned to both inline edges of the field, so it can never
   be wider than the field and can never be the cause of a sideways scroll. What
   changes at this width is only how much of the screen it is allowed to eat:
   320px of list on a 390px-tall-ish viewport with a keyboard up leaves nothing
   of the results behind it.
*/
@media (max-width: 767px) {
    .hzloc__panel {
        max-height: 250px;
    }

    .hzloc__opt {
        /* A 40px row is the smallest that is still comfortably tappable, and the
           list is nine entries, so the extra height costs one scroll at most. */
        padding: 11px 14px;
    }
}

/* ---------------------------------------------------------------------------
   Reduced motion / forced colours
   ---------------------------------------------------------------------------

   Nothing here animates, so there is no motion rule to write. Forced-colours
   mode drops the background tints that mark the active row, which would leave
   the arrow keys with no visible effect at all, so the marker is restated as a
   border the mode keeps.
*/
@media (forced-colors: active) {
    .hzloc__panel {
        border: 1px solid CanvasText;
    }

    .hzloc__opt.is-active {
        outline: 2px solid Highlight;
        outline-offset: -2px;
    }
}
