/* ==========================================================================
   LOCATIONS HUB -- DESIGN PREVIEW (template-location-hub-preview.php)
   Prefix: uq-lhp-   Markup: template-parts/location-hub-preview/*.php
   Data: inc/location-hub-preview.php   Behaviour: js/location-hub-preview.js

   ONE FAMILY WITH THE PROJECTS AND BLOG HUBS (client feedback, 2026-10-01:
   "same Hub/header design language", "Regions like Categories", "simple").
   Most of the page is drawn by the site's own components, which this file
   does NOT restyle:

     Hub header        css/hub.css        .uq-hub__header, .uq-hub-nav,
                                          .uq-hub__breadcrumbs, .uq-hub__title
     Popular cards     css/hub-card.css   .uq-hub-card (the Projects Hub card)
     Popular slider    style.css          .uq-related-projects (the Related
                                          Projects / Related Articles carousel)
     Closing CTA       style.css          .uq-article-end (the Blog / Service
                                          CTA, through cta.php)

   What is left here: the page shell, the gaps between sections, the card
   photo placeholder, the All Locations toolbar and directory, the map, and
   the two things the CTA needs that a Blog / Service page gives it.

   Every value is a token or a value those components already use -- the
   1200px container with 5vw gutters (the Hub header's), --uq-hub-border, the
   brand navy, the module title and description scales, the 10px card radius,
   and the Hub dropdown's #f4f6f8 / #eef3f9 tints for hover / selected. Navy is
   the accent; yellow appears only where the site already uses it -- the
   Service Area eyebrow pill and the CTA.

   The live /locations/ archive is not touched by this file, and nothing here
   is loaded anywhere but the preview template.

   style.css traps answered here:
   1. `main { float: right; width: 74% }` -- reset on main.uq-lhp (and by
      main.uq-hub-flex-page in css/hub.css).
   2. <p>, <a>, <li>, <input> and <button> are pinned to the body face with
      !important. Everything set in the heading face inside them is a <span>.
   3. `a` is yellow/600 and `a:hover` is (0,1,1); every link rule here is
      (0,2,0) or more.
   4. `h1-h6` are 700 navy with a 15px bottom margin and `p` has a 20px one:
      reset through :where() -- inside THIS file's sections only, so the Hub
      header's, the carousel's and the CTA's own margins are never reset.
   5. `input:focus` draws a cyan border and placeholders are navy site-wide:
      both answered on the search field.
   6. [hidden] is forced, because the Grid view sets `display: contents` on
      groups and lists, which would otherwise beat the UA's display: none.
   ========================================================================== */

main.uq-lhp {
    --uq-lhp-navy: var(--uq-theme-primary, #104E8B);
    --uq-lhp-ink: #111111;
    --uq-lhp-text: rgba(0, 0, 0, 0.78);
    --uq-lhp-body: var(--uq-theme-text, #3F4B58);
    --uq-lhp-muted: #767676;
    --uq-lhp-line: var(--uq-theme-border, #e5e5e5);
    --uq-lhp-hover: #f4f6f8;
    --uq-lhp-selected: #eef3f9;
    --uq-lhp-radius: 10px;
    --uq-lhp-heading: var(--uq-site-font-heading, "UQ Site Roobert", Arial, sans-serif);
    --uq-lhp-sticky: calc(var(--uq-site-header-offset, 76px) + 16px);
    /* The gap between sections: Popular -> All Locations -> map -> CTA. */
    --uq-lhp-section: 64px;
    /* Above and below the grey divider under the Hub header: half the
       section gap each side, so description -> line -> next heading is the
       page's own section gap with the line in its middle (32 / 28 / 24). */
    --uq-lhp-after-header: calc(var(--uq-lhp-section) / 2);
    /* Section headings: clamp(32px, 2.8vw, 40px), then 32 / 28 / 24. Every
       step is already on the site: .uq-heading-h3 (40, 32), the Related
       Projects phone title (28) and .uq-heading-h2 on phones (24). They sit
       two rungs under the H1, which is lifted to the page-title rung in
       .uq-lhp-header below -- 1.4-1.5x at every width. At the module scale
       the H2s would EQUAL the Hubs' H1, and the client's rule written into
       style.css for the Related Projects title is that a section heading
       stays below the page H1: "equal is not below". */
    --uq-lhp-h2: clamp(32px, 2.8vw, 40px);

    display: block;
    float: none;
    clear: both;
    width: 100%;
    max-width: none;
    margin: 0;
    overflow-x: clip;
    background: #ffffff;
    color: var(--uq-lhp-text);
    font-family: var(--uq-site-font-body, Arial, sans-serif);
}

.uq-lhp [hidden] {
    display: none !important;
}

/* Element resets at (0,1,0) through :where(), for this file's own sections.
   Every component rule below is also (0,1,0) and later, so it wins, while the
   global element rules lose. */
:is(.uq-lhp-directory, .uq-lhp-area) :where(h2, h3, p, ul, ol) {
    margin: 0;
}

:is(.uq-lhp-directory, .uq-lhp-area) :where(ul, ol) {
    padding: 0;
    list-style: none;
}

:is(.uq-lhp-directory, .uq-lhp-area) :where(h2, h3) {
    color: var(--uq-lhp-ink);
    font-family: var(--uq-lhp-heading);
    font-weight: 500;
}

:is(.uq-lhp-directory, .uq-lhp-area) :where(li)::before {
    display: none;
    content: none;
}

.uq-lhp-directory :where(button) {
    margin: 0;
    font: inherit;
    color: inherit;
    -webkit-appearance: none;
    appearance: none;
}

/* The Hub's own focus ring: 2px brand navy. */
:is(.uq-lhp-directory, .uq-lhp-area) :focus-visible {
    outline: 2px solid var(--uq-lhp-navy);
    outline-offset: 2px;
}

.uq-lhp-icon {
    display: block;
    flex: none;
    width: 1em;
    height: 1em;
}

.uq-lhp-sr {
    position: absolute;
    overflow: hidden;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

/* The Hub header's box: 1200px inside 5vw gutters. */
.uq-lhp-container {
    width: 100%;
    max-width: calc(1200px + 10vw);
    margin-inline: auto;
    padding-inline: 5vw;
}

/* ---------- section headings ----------
   The Related Projects title's colour, weight, line-height and tracking --
   "Popular Locations" IS a .uq-related-projects__title -- at --uq-lhp-h2,
   one step under the Hub H1 (see the token). (0,3,0) on the Popular title
   beats the shared title scale and the module's own 479 step, both (0,2,0). */
.uq-lhp-title,
.uq-lhp .uq-lhp-popular .uq-related-projects__title {
    color: var(--uq-lhp-navy);
    font-size: var(--uq-lhp-h2);
    line-height: 1.1;
    letter-spacing: -0.02em;
    text-wrap: balance;
}

/* The count, faded like the Hub H1's "Locations /" root. */
.uq-lhp-title__count {
    opacity: 0.6;
}

/* The module description scale, as .uq-related-projects__description. */
.uq-lhp-copy {
    max-width: 860px;
    margin-top: 16px;
    color: var(--uq-lhp-body);
    font-size: var(--uq-module-description-size, 16px);
    font-weight: var(--uq-module-description-weight, 400);
    line-height: var(--uq-module-description-line-height, 1.4);
}

.uq-lhp-head {
    margin-bottom: 32px;
}

/* ==========================================================================
   Hub header (css/hub.css) -- two additions
   ========================================================================== */

/* THE H1, ONE RUNG UP (client feedback, 2026-10-01: the H1 and the section
   headings "feel too similar in size"). The Hubs' H1 reads the shared
   SECTION-title scale, --uq-module-title-* (48 / 40 / 36 / 32), so "Locations"
   sat one small step over "Popular Locations", "All Locations" and "Our
   Service Area": 1.2x at desktop.

   It now takes the page-title rung the Location Keyword Header already uses
   for the same reason (the long note on .uq-quo-showcase in style.css): the
   ladder's own numbers shifted one step up, clamp(48px, 4vw, 56px), then
   48 / 40 / 36. The section headings are not changed, so the H1 is 1.4-1.5x
   every H2 at every width:

                1440   1024   768   390
       H1         56     48    48    36      was 48 / 40 / 40 / 32
       H2         40     32    32    24      unchanged

   Only the four size tokens are overridden, and only inside this header, so
   the shared section-title rule in style.css still owns the H1's breakpoints
   and css/hub.css still owns everything else on it -- 500, 1.08, -0.035em,
   the navy, the 960px measure. The Blog and Projects Hubs are untouched. */
.uq-lhp-header {
    --uq-module-title-size: clamp(48px, 4vw, 56px);
    --uq-module-title-size-lg: 48px;
    --uq-module-title-size-md: 40px;
    --uq-module-title-size-sm: 36px;
}

/* THE DIVIDER (client feedback, 2026-10-02: "we need a gray line there ...
   just to separate them"). One 1px rule in the site's neutral border colour
   (--uq-theme-border, #e5e5e5) between the Hub header's H1 + description and
   the first section under it -- Popular Locations, or All Locations when
   there are no Popular cards to show.

   Drawn by the header's own container, so it needs no new markup and spans
   exactly the content width the Region row's hairline above it spans: 1200px
   inside the 5vw gutters, at every width. No colour, no weight, no ornament.

   BALANCED: --uq-lhp-after-header above it (from the description) and the
   same value below it (to the next section's heading, through that section's
   top padding). */
.uq-lhp-header > .uq-hub__container::after {
    content: "";
    display: block;
    height: 0;
    margin-top: var(--uq-lhp-after-header);
    border-top: 1px solid var(--uq-lhp-line);
}

/* With no Popular cards -- none configured, or none in the chosen Region --
   All Locations is the section under the divider, and takes the same gap. */
.uq-lhp-header + .uq-lhp-directory,
.uq-lhp-header + .uq-lhp-popular[hidden] + .uq-lhp-directory {
    padding-top: var(--uq-lhp-after-header);
}

/* ==========================================================================
   Popular Locations -- the Related Projects carousel + .uq-hub-card
   ========================================================================== */

/* Spacing. The module's own 64px top becomes the gap under the header's
   divider, its bottom padding hands over to the next section's, and its gutters
   follow the Hub header's 5vw at every width so every left edge on the page
   lines up (the module itself drops to 24 / 18px on phones).

   THE PEEK. --uq-rp-visible is the engine's own "cards across" token, and it
   is the only carousel value set here. The module's 3.15 / 2.2 / 1.35 / 1.12
   left 8-15% of the next card showing -- a thin clipped strip rather than a
   peek. 3.4 / 2.4 / 1.4 / 1.35 show a third of it instead (measured: 36%
   at 1440 and 1024, 36% at 768, 31% at 390). Every step is redeclared
   because this selector (0,2,0) outranks the module's own breakpoints. The
   script measures the rendered card, so paging follows with no change. */
.uq-lhp .uq-lhp-popular {
    --uq-rp-space-top: var(--uq-lhp-after-header);
    --uq-rp-space-bottom: 0px;
    --uq-rp-visible: 3.4;
    padding-right: 5vw;
    padding-left: 5vw;
}

/* Swipe. The engine reads pointer events, and with the default
   `touch-action: auto` the browser claims a sideways drag as a page pan and
   cancels them after the first move -- so on a phone the row never swipes
   (the same is true of the carousel on the live Project pages). pan-y keeps
   vertical scrolling and hands sideways drags to the script; it is the
   declaration .uq-how-it-works__viewport already uses for the same reason. */
.uq-lhp .uq-lhp-popular .uq-related-projects__viewport {
    touch-action: pan-y;
}

/* ---------- photo cards ----------
   A card's photo is drawn by the shared card itself (.uq-hub-card__image:
   16:9 cover crop, 10px radius, the slow zoom on hover), so nothing here
   restyles it. Until a photo is chosen for a card the frame holds this
   placeholder: the card's own neutral media ground (--uq-hc-media-bg) and a
   small photo glyph in the faint grey the disabled A-Z letters use. It takes
   .uq-hub-card__image too, so it fills the frame and zooms like a photo. */
.uq-hub-card--location .uq-lhp-photo-placeholder {
    display: grid;
    place-items: center;
    color: rgba(0, 0, 0, 0.22);
}

.uq-lhp-photo-placeholder svg {
    display: block;
    width: 40px;
    height: 40px;
}

/* A card whose Location has no Page (client feedback, 2026-10-03, point 4) is
   a <div class="uq-hub-card__link uq-hub-card__link--static"> (popular.php):
   the same card, minus what tells a visitor it is a link -- the photo's slow
   zoom and the title's underline on hover (css/hub-card.css, at (0,3,0)). */
.uq-lhp .uq-hub-card__link--static:hover .uq-hub-card__image {
    transform: none;
}

.uq-lhp .uq-hub-card__link--static:hover .uq-hub-card__title {
    text-decoration: none;
}

/* ==========================================================================
   All Locations
   ========================================================================== */

.uq-lhp-directory {
    padding-top: var(--uq-lhp-section);
    scroll-margin-top: var(--uq-lhp-sticky);
}

.uq-lhp-directory:focus {
    outline: 0;
}

/* ---------- toolbar: search left, List / Grid right ---------- */

.uq-lhp-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 16px 24px;
}

.uq-lhp-search {
    position: relative;
    display: none;
    flex: 0 1 420px;
    align-items: center;
    min-width: 0;
    margin: 0;
}

.uq-lhp--js .uq-lhp-search {
    display: flex;
}

.uq-lhp-search__icon {
    position: absolute;
    top: 50%;
    left: 15px;
    color: var(--uq-lhp-muted);
    font-size: 18px;
    pointer-events: none;
    transform: translateY(-50%);
}

.uq-lhp .uq-lhp-search__input,
.uq-lhp .uq-lhp-search__input:focus {
    width: 100%;
    height: 48px;
    margin: 0;
    padding: 0 44px 0 44px;
    border: 1px solid var(--uq-lhp-line);
    border-radius: 8px;
    background: #ffffff;
    box-shadow: none;
    color: var(--uq-lhp-ink);
    font-size: 16px;
    line-height: 1.4;
    -webkit-appearance: none;
    appearance: none;
}

.uq-lhp .uq-lhp-search__input:hover {
    border-color: #cfd6de;
}

.uq-lhp .uq-lhp-search__input:focus {
    border-color: var(--uq-lhp-navy);
    outline: 0;
    box-shadow: inset 0 0 0 1px var(--uq-lhp-navy);
}

.uq-lhp .uq-lhp-search__input::placeholder {
    color: var(--uq-lhp-muted);
    opacity: 1;
}

.uq-lhp-search__input::-webkit-search-cancel-button,
.uq-lhp-search__input::-webkit-search-decoration {
    -webkit-appearance: none;
    appearance: none;
}

.uq-lhp .uq-lhp-search__clear {
    position: absolute;
    top: 50%;
    right: 6px;
    display: grid;
    width: 36px;
    height: 36px;
    padding: 0;
    place-items: center;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: var(--uq-lhp-muted);
    cursor: pointer;
    font-size: 16px;
    transform: translateY(-50%);
}

.uq-lhp .uq-lhp-search__clear:hover {
    background: var(--uq-lhp-hover);
    color: var(--uq-lhp-ink);
}

.uq-lhp-view {
    display: none;
    flex: none;
    gap: 2px;
    padding: 3px;
    border: 1px solid var(--uq-lhp-line);
    border-radius: 8px;
    background: #ffffff;
}

.uq-lhp--js .uq-lhp-view {
    display: inline-flex;
}

.uq-lhp .uq-lhp-view__button {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 40px;
    padding: 0 14px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: var(--uq-lhp-ink);
    cursor: pointer;
    font-size: 15px;
    font-weight: 500;
    line-height: 1;
    transition: background-color 0.2s ease, color 0.2s ease;
}

.uq-lhp .uq-lhp-view__button .uq-lhp-icon {
    font-size: 16px;
}

.uq-lhp .uq-lhp-view__button:hover {
    background: var(--uq-lhp-hover);
}

.uq-lhp .uq-lhp-view__button[aria-pressed="true"] {
    background: var(--uq-lhp-selected);
    color: var(--uq-lhp-navy);
}

/* The keyboard ring: the section's 2px navy outline, drawn just inside the
   button's edge. At the section's 2px outward offset it ran into the switch's
   own grey border on the outer sides. A mouse click never shows it (see the
   List / Grid note in js/location-hub-preview.js). */
.uq-lhp .uq-lhp-view__button:focus-visible {
    outline-offset: -2px;
}

/* ---------- A-Z ----------
   Plain letters on one line, ruled off from the list like the Hub's category
   row. The selected letter takes the Hub dropdown's selected tint. */
.uq-lhp-az {
    display: none;
    align-items: center;
    justify-content: space-between;
    gap: 2px;
    margin-top: 20px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--uq-lhp-line);
}

.uq-lhp--js .uq-lhp-az {
    display: flex;
}

.uq-lhp .uq-lhp-az__button {
    flex: none;
    min-width: 32px;
    height: 34px;
    padding: 0 6px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: var(--uq-lhp-ink);
    cursor: pointer;
    font-size: 15px;
    font-weight: 500;
    line-height: 1;
    transition: background-color 0.2s ease, color 0.2s ease;
}

.uq-lhp .uq-lhp-az__button--all {
    padding: 0 12px;
}

.uq-lhp .uq-lhp-az__button:not(:disabled):hover {
    background: var(--uq-lhp-hover);
}

.uq-lhp .uq-lhp-az__button[aria-pressed="true"],
.uq-lhp .uq-lhp-az__button[aria-pressed="true"]:hover {
    background: var(--uq-lhp-selected);
    color: var(--uq-lhp-navy);
}

.uq-lhp .uq-lhp-az__button:disabled {
    color: rgba(0, 0, 0, 0.22);
    cursor: default;
}

/* ---------- status line ---------- */

.uq-lhp-status {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 16px;
    margin-top: 16px;
}

.uq-lhp-status__text {
    color: var(--uq-lhp-muted);
    font-size: 15px;
    line-height: 1.4;
}

.uq-lhp .uq-lhp-status__clear {
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--uq-lhp-navy);
    cursor: pointer;
    font-size: 15px;
    font-weight: 500;
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* ---------- the directory: List ----------
   An index: letter, then names. The negative bottom margin takes back the
   last group's own padding, so the gap to the map is the section gap. */
.uq-lhp-groups {
    margin-top: 28px;
    margin-bottom: -24px;
    column-count: 4;
    column-gap: 40px;
}

.uq-lhp-group {
    padding-bottom: 24px;
    break-inside: avoid;
}

.uq-lhp-group__letter {
    margin-bottom: 6px;
    color: var(--uq-lhp-navy);
    font-size: 20px;
    line-height: 1.2;
}

.uq-lhp .uq-lhp-entry,
.uq-lhp .uq-lhp-entry:hover {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 8px;
    padding: 5px 0;
    color: var(--uq-lhp-ink);
    font-size: 16px;
    font-weight: 400;
    line-height: 1.4;
    text-decoration: none;
}

.uq-lhp .uq-lhp-entry:hover {
    color: var(--uq-lhp-navy);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.uq-lhp-entry__text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.uq-lhp-entry__meta {
    display: none;
}

/* THE SITE'S SIMPLE LINK ARROW (client choice, 2026-10-01: "the simple
   arrow"), in GRID ONLY: the 16px stroked arrow a text link carries in Split
   Content, the Service Feature cards, the Contact Banner and Filterable Cards,
   with their hover -- the arrow slides 4px right. No box and no container.

   NOT IN LIST (client feedback, 2026-10-03: "arrow from the list ... should be
   removed. Only keep the arrow inside the grid cards"). List and Grid are one
   list switched by .uq-lhp--grid, so the arrow stays in the markup and List
   simply does not show it; the Grid rule below shows it again. The link itself
   is unchanged, so the whole row is still the link. */
.uq-lhp-entry__go {
    display: none;
    flex: 0 0 16px;
    width: 16px;
    height: 16px;
    transition: transform 0.25s ease;
}

.uq-lhp .uq-lhp-entry:hover .uq-lhp-entry__go {
    transform: translateX(4px);
}

/* ---------- the directory: Grid ----------
   The live Location Hub's tile (.uq-hub-location, css/hub.css), to the value:
   hairline, 10px radius and the 18px card-title type, plus the Region under
   the name. The arrow sits at the tile's right edge, in navy. */
.uq-lhp--grid .uq-lhp-groups {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 16px;
    margin-bottom: 0;
    column-count: auto;
}

.uq-lhp--grid .uq-lhp-group,
.uq-lhp--grid .uq-lhp-group__list {
    display: contents;
}

.uq-lhp--grid .uq-lhp-group__letter {
    display: none;
}

.uq-lhp.uq-lhp--grid .uq-lhp-entry,
.uq-lhp.uq-lhp--grid .uq-lhp-entry:hover {
    justify-content: space-between;
    gap: 14px;
    height: 100%;
    min-height: 64px;
    padding: 16px 20px;
    border: 1px solid var(--uq-lhp-line);
    border-radius: var(--uq-lhp-radius);
    background: #ffffff;
    text-decoration: none;
    transition: border-color 0.2s ease, color 0.2s ease;
}

.uq-lhp.uq-lhp--grid .uq-lhp-entry:hover {
    border-color: var(--uq-lhp-navy);
}

.uq-lhp--grid .uq-lhp-entry__name {
    font-family: var(--uq-lhp-heading);
    font-size: var(--uq-module-card-title-size, 18px);
    font-weight: var(--uq-module-card-title-weight, 500);
    line-height: var(--uq-module-card-title-line-height, 1.35);
    letter-spacing: var(--uq-module-card-title-letter-spacing, -0.015em);
    overflow-wrap: anywhere;
}

.uq-lhp--grid .uq-lhp-entry:hover .uq-lhp-entry__name {
    color: var(--uq-lhp-navy);
}

.uq-lhp--grid .uq-lhp-entry__meta {
    display: block;
    margin-top: 2px;
    color: var(--uq-lhp-muted);
    font-size: 14px;
    line-height: 1.4;
}

.uq-lhp--grid .uq-lhp-entry__go {
    display: block;
    color: var(--uq-lhp-navy);
}

/* NO PAGE, NO LINK (client feedback, 2026-10-03, point 4). A Location with no
   published Page of its own name is a <span class="uq-lhp-entry
   uq-lhp-entry--static"> (directory.php), not a link. Every rule above is
   class-based, so it sits in exactly the same row or tile; these take away
   only what a link does on hover -- the navy name and underline in List, the
   navy hairline and name in Grid. Its arrow is not printed at all, so a Grid
   tile shows one only when it goes somewhere. Same specificity as the hover
   rules they answer, and later, so source order settles it. */
.uq-lhp .uq-lhp-entry--static:hover {
    color: var(--uq-lhp-ink);
    text-decoration: none;
}

.uq-lhp.uq-lhp--grid .uq-lhp-entry--static:hover {
    border-color: var(--uq-lhp-line);
}

.uq-lhp--grid .uq-lhp-entry--static:hover .uq-lhp-entry__name {
    color: inherit;
}

/* ---------- empty state ---------- */

.uq-lhp-empty {
    margin-top: 28px;
    padding: 40px 24px;
    border: 1px solid var(--uq-lhp-line);
    border-radius: var(--uq-lhp-radius);
    text-align: center;
}

.uq-lhp-empty__title {
    color: var(--uq-lhp-ink);
    font-size: 18px;
    font-weight: 600;
    line-height: 1.35;
}

.uq-lhp-empty__copy {
    max-width: 460px;
    margin: 8px auto 0;
    color: var(--uq-lhp-body);
    font-size: 15px;
    line-height: 1.5;
}

.uq-lhp .uq-lhp-empty__button {
    margin-top: 20px;
    padding: 11px 20px;
    border: 1px solid var(--uq-lhp-navy);
    border-radius: 8px;
    background: #ffffff;
    color: var(--uq-lhp-navy);
    cursor: pointer;
    font-size: 15px;
    font-weight: 500;
    transition: background-color 0.2s ease, color 0.2s ease;
}

.uq-lhp .uq-lhp-empty__button:hover {
    background: var(--uq-lhp-navy);
    color: #ffffff;
}

/* ==========================================================================
   Service area: the Google Map
   ========================================================================== */

/* One section gap above the eyebrow, and one section gap from the map down
   to the CTA card -- 64 / 56 / 48, the gap between every section on the
   page. The CTA brings 32px of its own above the card (--uae-space-top, the
   Blog / Service default), so this side gives the rest. */
.uq-lhp-area {
    padding: var(--uq-lhp-section) 0 calc(var(--uq-lhp-section) - 32px);
}

.uq-lhp-area .uq-lhp-copy {
    max-width: 640px;
}

/* "SERVICE AREA" over the map heading (client feedback, 2026-10-01). The
   site's small-label step -- 11px / 700 / 0.08em, uppercase -- on the module
   eyebrows' yellow pill: .uq-service-comparison__service-eyebrow's accent
   variant in style.css, to the value (6px 12px, 999px, --uq-theme-accent,
   black). No icon. Block-level flex at fit-content rather than inline-flex,
   so no line box adds descender space under it (see the note on
   .uq-project-details__map-eyebrow), and 12px down to the heading, the gap
   the left-aligned module eyebrows keep (Reviews, Split Content, Service
   Feature). The same size at every width, as theirs is. */
.uq-lhp-eyebrow {
    display: flex;
    width: fit-content;
    margin: 0 0 12px;
    padding: 6px 12px;
    align-items: center;
    border-radius: 999px;
    background: var(--uq-theme-accent, #FDBB2F);
    color: #000000;
    font-size: 11px;
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

/* A plain frame: the hairline and the 10px card radius, no shadow. The tint
   shows until the tiles arrive, and the height is fixed, so nothing moves
   when the map loads. */
.uq-lhp-area__frame {
    position: relative;
    overflow: hidden;
    border: 1px solid var(--uq-lhp-line);
    border-radius: var(--uq-lhp-radius);
    background: #f4f6f8;
    isolation: isolate;
}

.uq-lhp-area__map {
    width: 100%;
    height: 480px;
}

/* Google's own tiles and icons must not be squeezed by any img max-width. */
.uq-lhp .uq-lhp-area__map img {
    max-width: none;
}

/* ---------- the info window (built by the script) ----------

   Google's popup, restyled for this map ONLY: every selector starts at
   .uq-lhp-area__map, which exists on this template alone, and this sheet
   loads on this template alone.

   The site-wide rule `.gm-style .gm-style-iw-c, .gm-style .gm-style-iw-d
   { padding: 0; box-shadow: none; border-radius: 5px }` in style.css (made
   for the old .acf-map popups, which pad their own .content) strips Google's
   padding and shadow. It is answered here at (0,3,0) rather than changed, so
   the Contact and Location maps keep it.

   Compact: 12px above the name, 16px at the sides, 14px below the link. The
   close button is a 32px target centred on the name's line; its negative
   bottom margin keeps it from pushing the Region line down. Google sizes the
   button and its icon inline, hence !important on those values only. */

.uq-lhp-area__map .gm-style .gm-style-iw-c {
    padding: 0;
    border-radius: var(--uq-lhp-radius);
    box-shadow: 0 8px 24px rgba(16, 24, 40, 0.16);
}

.uq-lhp-area__map .gm-style .gm-style-iw-chr {
    align-items: flex-start;
    padding: 12px 8px 0 16px;
}

.uq-lhp-area__map .gm-style .gm-style-iw-ch {
    padding-top: 0;
    padding-right: 12px;
}

.uq-lhp-area__map .gm-style .gm-style-iw-chr > .gm-ui-hover-effect {
    flex: none;
    width: 32px !important;
    height: 32px !important;
    margin: -6px 0 -10px !important;
    border-radius: 6px;
    opacity: 1;
    transition: background-color 0.2s ease;
}

.uq-lhp-area__map .gm-style .gm-style-iw-chr > .gm-ui-hover-effect:hover {
    background-color: var(--uq-lhp-hover) !important;
}

.uq-lhp-area__map .gm-style .gm-style-iw-chr > .gm-ui-hover-effect:focus-visible {
    outline-offset: -2px;
}

.uq-lhp-area__map .gm-style .gm-style-iw-chr > .gm-ui-hover-effect > span {
    width: 16px !important;
    height: 16px !important;
    margin: 8px !important;
    background-color: var(--uq-lhp-muted);
}

.uq-lhp-area__map .gm-style .gm-style-iw-d {
    padding: 2px 16px 14px;
}

.uq-lhp-iw__name {
    display: block;
    color: var(--uq-lhp-ink);
    font-family: var(--uq-lhp-heading);
    font-size: 16px;
    font-weight: 500;
    line-height: 20px;
    letter-spacing: -0.01em;
}

.uq-lhp-iw {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
    min-width: 140px;
}

.uq-lhp-iw__meta {
    color: var(--uq-lhp-muted);
    font-size: 13px;
    line-height: 18px;
    white-space: nowrap;
}

.uq-lhp .uq-lhp-iw__link,
.uq-lhp .uq-lhp-iw__link:hover {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: var(--uq-lhp-navy);
    font-size: 14px;
    font-weight: 600;
    line-height: 18px;
    text-decoration: none;
}

.uq-lhp .uq-lhp-iw__link:hover {
    text-decoration: underline;
    text-underline-offset: 3px;
}

.uq-lhp-iw__link .uq-lhp-icon {
    font-size: 14px;
    stroke-width: 2.2;
}

/* ==========================================================================
   Closing CTA: the Blog / Service CTA (.uq-article-end, style.css)
   ========================================================================== */

/* Everything about the card -- colours, pattern, title, button, padding,
   radius, width, the 767 / 420 steps -- is style.css's, untouched, except the
   title's SIZE, which is a step larger here (see below). A Blog or
   Service CTA gets two more things from its page, and this one gets them
   here, under its own modifier (template-parts/location-hub-preview/cta.php):

   1. The full-strength description. The component fades it to 0.7, and
      `.uq-article-end--service / --blog / --project` lift that back to 1.
   2. The module description scale. On a Blog or Service page the description
      reads --uq-module-description-* (16 / 400 / 1.4, 15px at 767) through
      the `.uq-flex-page :is(...)` whitelist in style.css, and this page's
      <main> is deliberately not .uq-flex-page. The same tokens, the same
      767 step and the same (0,2,0) as that rule. */
.uq-article-end--location-hub .uq-article-end__description {
    font-size: var(--uq-module-description-size, 16px);
    font-weight: var(--uq-module-description-weight, 400);
    line-height: var(--uq-module-description-line-height, 1.4);
    opacity: 1;
}

.uq-article-end--location-hub .uq-article-end__description :where(p, span, li, a, strong, em) {
    font-size: inherit !important;
    line-height: inherit !important;
}

@media screen and (max-width: 767px) {
    .uq-article-end--location-hub .uq-article-end__description {
        font-size: var(--uq-module-description-size-mobile, 15px);
    }
}

/* THE TITLE, A STEP LARGER (client feedback, 2026-10-03, point 5: "TITLE In
   the CTA I think should be a bit larger"). The component's
   clamp(23px, 2.2vw, 30px) scaled by about 1.13, so it is the same curve --
   it tops out at 1360 (the component's at 1364) and bottoms out at 1040
   (1045) -- one size up: 34 / 26 / 26 at 1440 / 1024 / 768, was 30 / 23 / 23.
   Phones take the Hubs' 479 step, as the section headings do: 24 at 390, the
   section headings' own phone size, so the title never outranks them. The
   6.4vw floor is the card: "Need a Roofer in Your Area?" needs about 12px of
   line per px of type, and a 360 card has 280px, so 24px would wrap "Area?"
   onto a line of its own there. At 360 it stays the old 23px on one line.
   Only the size: the face, the 500 weight, the 1.1 line-height, the
   letter-spacing, the 500px measure and the colour are the component's.
   Blog / Service CTAs keep 30px; (0,2,0) beats the component's (0,1,0). */
.uq-article-end--location-hub .uq-article-end__title {
    font-size: clamp(26px, 2.5vw, 34px);
}

@media (max-width: 479px) {
    .uq-article-end--location-hub .uq-article-end__title {
        font-size: clamp(23px, 6.4vw, 24px);
    }
}

/* THE BUTTON'S HOVER RING (client note, 2026-10-01: the yellow border looked
   uneven, "pushed into" the button). On hover the button is a white fill
   with a yellow ring, on the navy card. Two things made the ring look weak
   on the pill's rounded ends while the straight top and bottom stayed crisp:

   1. In style.css the white FILL is painted under the 1px yellow BORDER, all
      the way to the outer edge, so on the curves white leaks into the ring's
      outer pixels and navy into its inner ones. Here the two never overlap:
      the border keeps its 1px width -- so the size, the radius, the label
      and the arrow do not move -- but is transparent, the yellow under it
      is the button's own background (border box), and the fill is an inset
      shadow, which is clipped to the padding box, i.e. inside the ring.
   2. On a standard-density screen a 1px line cannot be drawn solidly round
      a 28px curve: it lands across two half-covered pixels (one olive, one
      cream) and fades, while the straights stay one solid pixel. Measured:
      the faintest point of the curve was 57% yellow. At 1.5dppx and below
      the ring is 1.5px instead -- a 0.5px yellow inset shadow inside it --
      which lifts that to 71% so the curve keeps the straights' weight. On
      2x screens and up the 1px ring already renders at full strength all
      the way round, so it stays exactly the Blog / Service 1px ring.

   On hover only the fill shadow changes colour; the ring is the same yellow
   in both states. Colours, the 180ms timing and the 2px lift are
   style.css's own; only the transitioned property moves from
   background-color to box-shadow. (0,2,0) and (0,3,0) beat the component's
   (0,1,0) and :hover (0,2,0). */
.uq-article-end--location-hub .uq-article-end__button {
    border-color: transparent;
    background: var(--uae-btn-bg, #000000);
    box-shadow: inset 0 0 0 100px var(--uae-btn-bg, #000000);
    transition: box-shadow 180ms ease, color 180ms ease, transform 180ms ease;
}

.uq-article-end--location-hub .uq-article-end__button:hover {
    background: var(--uae-btn-bg, #000000);
    box-shadow: inset 0 0 0 100px var(--uae-btn-hover-bg, #ffffff);
}

@media (max-resolution: 1.5dppx), (-webkit-max-device-pixel-ratio: 1.5) {
    .uq-article-end--location-hub .uq-article-end__button {
        box-shadow: inset 0 0 0 0.5px var(--uae-btn-bg, #000000), inset 0 0 0 100px var(--uae-btn-bg, #000000);
    }

    .uq-article-end--location-hub .uq-article-end__button:hover {
        box-shadow: inset 0 0 0 0.5px var(--uae-btn-bg, #000000), inset 0 0 0 100px var(--uae-btn-hover-bg, #ffffff);
    }
}

/* ==========================================================================
   Responsive -- the Hubs' 1199 / 991 / 767 / 479 ladder
   ========================================================================== */

@media (max-width: 1199px) {
    .uq-lhp-groups {
        column-count: 4;
        column-gap: 32px;
    }

    .uq-lhp--grid .uq-lhp-groups {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (max-width: 991px) {
    main.uq-lhp {
        --uq-lhp-section: 56px;
        --uq-lhp-h2: 32px;
    }

    .uq-lhp .uq-lhp-popular {
        --uq-rp-visible: 2.4;
    }

    .uq-lhp-copy {
        margin-top: 14px;
    }

    .uq-lhp-head {
        margin-bottom: 24px;
    }

    /* One line that scrolls sideways inside itself; the page never does. */
    .uq-lhp-az {
        justify-content: flex-start;
        overflow-x: auto;
        overscroll-behavior-x: contain;
        scrollbar-width: none;
        -webkit-overflow-scrolling: touch;
    }

    .uq-lhp-az::-webkit-scrollbar {
        display: none;
    }

    .uq-lhp-groups {
        column-count: 3;
    }

    .uq-lhp-area__map {
        height: 420px;
    }
}

@media (max-width: 767px) {
    main.uq-lhp {
        --uq-lhp-section: 48px;
        --uq-lhp-h2: 28px;
    }

    .uq-lhp .uq-lhp-popular {
        --uq-rp-visible: 1.4;
    }

    .uq-lhp-photo-placeholder svg {
        width: 32px;
        height: 32px;
    }

    .uq-lhp-copy {
        font-size: var(--uq-module-description-size-mobile, 15px);
    }

    /* The search takes the full row; List / Grid sits under it, on the left. */
    .uq-lhp-toolbar {
        gap: 12px;
    }

    .uq-lhp-search {
        flex: 1 1 100%;
    }

    .uq-lhp-groups {
        column-count: 2;
        column-gap: 24px;
    }

    .uq-lhp--grid .uq-lhp-groups {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 12px;
    }

    .uq-lhp.uq-lhp--grid .uq-lhp-entry,
    .uq-lhp.uq-lhp--grid .uq-lhp-entry:hover {
        min-height: 58px;
        padding: 14px 16px;
    }

    .uq-lhp-area__map {
        height: 380px;
    }
}

@media (max-width: 479px) {
    main.uq-lhp {
        --uq-lhp-h2: 24px;
    }

    .uq-lhp .uq-lhp-popular {
        --uq-rp-visible: 1.35;
    }

    .uq-lhp-group__letter {
        font-size: 18px;
    }

    .uq-lhp .uq-lhp-view__button {
        height: 38px;
        padding: 0 12px;
    }

    .uq-lhp.uq-lhp--grid .uq-lhp-entry,
    .uq-lhp.uq-lhp--grid .uq-lhp-entry:hover {
        gap: 8px;
        padding: 14px;
    }

    .uq-lhp-area__map {
        height: 340px;
    }
}

@media (max-width: 359px) {
    .uq-lhp--grid .uq-lhp-groups {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media (prefers-reduced-motion: reduce) {
    .uq-lhp-directory *,
    .uq-lhp-area * {
        transition: none !important;
    }
}
