/* ==========================================================================
   HomePezzo — vendor archive + single vendor profile (SO8, v0.1.180)
   --------------------------------------------------------------------------
   Scope: the gd_vendor surfaces only.
     * archive / category archive — body.post-type-archive-gd_vendor and
       body.geodir-page-cpt-gd_vendor (GeoDirectory sets both);
     * single vendor profile — body.single-gd_vendor.
   Loaded only on those requests (see includes/hp-enqueue.php), so nothing here
   can reach /places/, /guides/, /search/, the homepage or the account pages.

   The vendor ARCHIVE deliberately adds almost nothing: /vendors/ already
   inherits the whole completed directory system from homepezzo-archive.css,
   every rule of which is keyed to `body.geodir-archive` — a class the vendor
   archive carries. Verified inherited, not re-declared here: the 1200px/24px
   measure, the v0.1.177 search panel, the utility band, the 20px grid gaps and
   3/4-column breakpoints, the empty-badge and empty-location suppressions, the
   card focus ring, the empty-results panel and the v0.1.179 36px results
   bottom spacing.

   Element class names (hpg-*) come from the two Bricks templates created in
   this release; `hp-vendor-*` names come from the shortcodes in
   includes/hp-shortcodes-vendor.php.
   ========================================================================== */

/* ── Archive header: match Template 36 / 128 rhythm ───────────────────────
   The section is white on the warm canvas, same as the places and guides
   headers. It carries no bottom border for the same reason T36's is
   suppressed in homepezzo-archive.css — it would read as a second divider
   directly above the search panel. */

body.post-type-archive-gd_vendor .hpg-vah_crumb,
body.geodir-page-cpt-gd_vendor .hpg-vah_crumb {
    margin-bottom: 16px;
}

/* The subtitle is the CPT's own description and is the last element in the
   header, so it closes the block rather than spacing into a button row. */

body.post-type-archive-gd_vendor .hpg-vah_sub,
body.geodir-page-cpt-gd_vendor .hpg-vah_sub {
    max-width: 60ch;
}

/* Tighter header at tablet and below, matching the directory's own rhythm. */

@media (max-width: 991.98px) {

    body.post-type-archive-gd_vendor .hpg-vah01,
    body.geodir-page-cpt-gd_vendor .hpg-vah01 {
        padding-top: 40px !important;
        padding-bottom: 40px !important;
    }

    body.post-type-archive-gd_vendor .hpg-vah_head,
    body.geodir-page-cpt-gd_vendor .hpg-vah_head {
        font-size: 30px !important;
    }
}

@media (max-width: 575.98px) {

    body.post-type-archive-gd_vendor .hpg-vah01,
    body.geodir-page-cpt-gd_vendor .hpg-vah01 {
        padding-top: 28px !important;
        padding-bottom: 28px !important;
    }

    body.post-type-archive-gd_vendor .hpg-vah_head,
    body.geodir-page-cpt-gd_vendor .hpg-vah_head {
        font-size: 26px !important;
    }
}

/* ==========================================================================
   Single vendor profile
   ========================================================================== */

/* EMPTY-SECTION RULES — WHY THEY ARE WRITTEN `:not(:has(X:not(:empty)))`
   Bricks does not render a shortcode element that produces an empty string: it
   omits the wrapper from the DOM ENTIRELY rather than leaving `<div></div>`.
   Verified live on the current vendor, whose identity image, linked products
   and (in other states) description are all absent this way. The intuitive
   `:has(.thing:empty)` form therefore never matches, because there is no
   `.thing` to match — measured: the "Products from this vendor" heading
   survived on a vendor with no products. The negated form covers BOTH shapes,
   absent and present-but-empty, and still keeps the section when the element
   holds real content. */

/* ── Profile bottom spacing ───────────────────────────────────────────────
   Measured before this rule: the last visible section's box ended at exactly
   the footer's top edge — a 0px gap — at all 11 verification widths, because
   which section renders LAST depends on the vendor's data (products, then
   details+claim, then description, then the identity block alone for a vendor
   with nothing else). Padding the page-level content wrapper puts the space
   beneath whichever one that is. Matches the 36px the v0.1.179 results-region
   rule gives the archives, so both vendor surfaces close the same way.

   The `body >` qualifier is REQUIRED, not decoration, and for exactly the
   reason homepezzo-archive.css documents for `article#brx-content`: the linked
   products loop renders the page-20 card template once per product and wraps
   EACH render in its own `<main id="brx-content">`. A bare `#brx-content`
   would therefore also pad the inside of every product card. Only the
   page-level wrapper is a direct child of <body>. */

body.single-gd_vendor > main#brx-content {
    padding-bottom: 36px;
}

/* ── Identity block ───────────────────────────────────────────────────────
   Compact and information-first: no decorative hero, no full-bleed image.
   The media column is a fixed square so a portrait logo and a landscape one
   occupy the same footprint and the text column never shifts; it collapses
   entirely (`:empty` rule on the Bricks element) when the vendor has neither
   a logo nor a featured image, which is the current state of every vendor on
   this install. */

body.single-gd_vendor .hpg-vsp_id {
    width: 100%;
}

/* ROOT CAUSE, measured at 1440px before this rule: the identity row was
   correctly `display:flex; flex-direction:row; flex-wrap:wrap`, but Bricks
   gives every `.brxe-shortcode` element a computed `width: 100%`. The media
   wrapper therefore reported width 1152px — the full row — and the text column
   wrapped underneath it at EVERY viewport, so the profile opened with a
   stacked logo-over-name block instead of the intended compact identity row.
   Constraining the wrapper to its content is what makes the row work; the
   `.hp-vendor-logo` sizing below then decides the actual footprint. */
body.single-gd_vendor .hpg-vsp_media {
    flex: 0 0 auto;
    width: auto !important;
}

body.single-gd_vendor .hp-vendor-logo {
    width: 120px;
    height: 120px;
    flex: 0 0 120px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--hp-surface, #FFFFFF);
    border: 1px solid var(--hp-line, #E0DCD2);
    border-radius: 12px;
    overflow: hidden;
    padding: 8px;
    box-sizing: border-box;
}

/* `contain`, not `cover`: a logo must never be cropped. */
body.single-gd_vendor .hp-vendor-logo__img {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
    display: block;
}

/* The text column takes the remaining width and is allowed to shrink, so a
   long business name or URL wraps instead of forcing the row wider than the
   container (the flex default `min-width: auto` is what would otherwise
   overflow). */
body.single-gd_vendor .hpg-vsp_body {
    flex: 1 1 320px;
    min-width: 0;
    max-width: 100%;
}

body.single-gd_vendor .hpg-vsp_title,
body.single-gd_vendor .hpg-vsp_loc,
body.single-gd_vendor .hpg-vsp_body {
    overflow-wrap: anywhere;
}

/* Category eyebrow takes the listing's own section colour, using the approved
   TEXT-SAFE tokens — no new colour is introduced and no canonical value is
   redefined here.
   The section wrapper carries `{hp_section_class}` (same mechanism Template 45
   uses on its single-listing section), which resolves to hp-section-exterior /
   -interior / -green-power / -plumbing-fixtures via
   homepezzo_get_listing_section_class(). That tag returns '' for a vendor with
   no canonical section, so such a profile matches none of the four rules and
   keeps the neutral below.
   These are written as four explicit rules rather than `var(--hp-accent-text)`
   ON PURPOSE: --hp-accent-text is also declared at :root (defaulting to the
   Interior blue), so the var form would paint an UNCATEGORISED vendor's eyebrow
   Interior blue instead of neutral grey. */
body.single-gd_vendor .hpg-vsp_cat {
    color: var(--hp-ink-muted, #565D69);
}

body.single-gd_vendor .hp-section-exterior .hpg-vsp_cat {
    color: var(--hp-exterior-text, #8B5E3C);
}

body.single-gd_vendor .hp-section-interior .hpg-vsp_cat {
    color: var(--hp-interior-text, #315E9E);
}

body.single-gd_vendor .hp-section-green-power .hpg-vsp_cat {
    color: var(--hp-green-power-text, #126834);
}

body.single-gd_vendor .hp-section-plumbing-fixtures .hpg-vsp_cat {
    color: var(--hp-plumbing-fixtures-text, #7C610E);
}

/* ── Primary action ───────────────────────────────────────────────────── */

body.single-gd_vendor .hp-vendor-actions {
    margin-top: 8px;
}

body.single-gd_vendor .hp-vendor-actions__primary {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 44px;                /* practical touch target */
    padding: 10px 20px;
    border-radius: 8px;
    background: var(--hp-blue, #315E9E);
    color: #FFFFFF;
    font-size: 15px;
    font-weight: 600;
    text-decoration: none;
    transition: background-color 0.2s;
}

body.single-gd_vendor .hp-vendor-actions__primary:hover,
body.single-gd_vendor .hp-vendor-actions__primary:focus {
    background: var(--hp-blue-hover, #2A5086);
    color: #FFFFFF;
}

/* The outbound arrow marks an external destination without adding an icon
   font or an image request. */
body.single-gd_vendor .hp-vendor-external {
    font-size: 0.85em;
    line-height: 1;
}

/* ── Description ──────────────────────────────────────────────────────────
   Swiss editorial measure. The vendor's submitted content is printed by the
   Bricks {post_content} tag exactly as stored — nothing here rewrites it.
   When a vendor has no description the heading would stand alone over
   nothing, so the whole section is removed rather than left as an oversized
   blank region. */

body.single-gd_vendor .hpg-vsp_about {
    max-width: 68ch;
}

body.single-gd_vendor .hpg-vsp_about > *:first-child {
    margin-top: 0;
}

body.single-gd_vendor .hpg-vsp_about > *:last-child {
    margin-bottom: 0;
}

body.single-gd_vendor .hpg-vsp10:not(:has(.hpg-vsp_about:not(:empty))) {
    display: none !important;
}

/* ── Business details ─────────────────────────────────────────────────────
   A definition list, one row per populated field. The shortcode emits no row
   at all for an empty field, so there is never an empty label or a dangling
   separator; when EVERY field is empty it emits nothing and the section
   below removes itself. */

body.single-gd_vendor .hp-vendor-details {
    width: 100%;
    max-width: 68ch;
    margin: 0;
    border-top: 1px solid var(--hp-line, #E0DCD2);
}

body.single-gd_vendor .hp-vendor-details__row {
    display: grid;
    grid-template-columns: 160px minmax(0, 1fr);
    gap: 4px 20px;
    padding: 12px 0;
    border-bottom: 1px solid var(--hp-line, #E0DCD2);
}

body.single-gd_vendor .hp-vendor-details__label {
    margin: 0;
    font-size: 13px;
    font-weight: 600;
    color: var(--hp-ink-muted, #565D69);
}

body.single-gd_vendor .hp-vendor-details__value {
    margin: 0;
    font-size: 15px;
    line-height: 1.5;
    color: var(--hp-ink, #2B3038);
    overflow-wrap: anywhere;    /* long URLs and service areas wrap safely */
}

body.single-gd_vendor .hp-vendor-details__value a {
    color: var(--hp-blue, #315E9E);
    text-decoration: underline;
    text-underline-offset: 2px;
    /* Keeps a tapped phone/email/URL a comfortable target without turning the
       row into a block-level button. */
    display: inline-flex;
    align-items: center;
    gap: 4px;
    min-height: 24px;
    padding: 4px 0;
}

/* Remove the whole details section when no field produced a row. */
body.single-gd_vendor .hpg-vsp20:not(:has(.hpg-vsp_det:not(:empty))):not(:has(.hpg-vsp_claim:not(:empty))) {
    display: none !important;
}

/* Heading would otherwise stand alone above only a claim box. */
body.single-gd_vendor .hpg-vsp21:not(:has(.hpg-vsp_det:not(:empty))) .hpg-vsp_deth {
    display: none !important;
}

/* ── Claim action ─────────────────────────────────────────────────────────
   Deliberately SECONDARY: a quiet outlined control in a bordered box, placed
   after the business information an actual visitor came for, but before the
   product grid so an owner still finds it without hunting. Everything inside
   .hp-vendor-claim--action is Claim Listings' own widget output; only its
   colours, size and spacing are set here. */

body.single-gd_vendor .hp-vendor-claim {
    width: 100%;
    max-width: 68ch;
    margin: 20px 0 0;
}

body.single-gd_vendor .hp-vendor-claim--action {
    padding: 16px 18px;
    border: 1px solid var(--hp-line, #E0DCD2);
    border-radius: 10px;
    background: var(--hp-surface-warm, #FAF7F1);
}

body.single-gd_vendor .hp-vendor-claim__prompt {
    margin: 0 0 10px;
    font-size: 14px;
    color: var(--hp-ink-muted, #565D69);
}

/* GD renders the action as an AUI <button class="btn btn-primary">. Restyled
   to a restrained secondary control so it never competes with "Visit
   Website"; the element, its handler and its onclick target are untouched. */
body.single-gd_vendor .hp-vendor-claim--action .geodir-claim-post-form-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    padding: 9px 18px;
    border: 1px solid var(--hp-line-strong, #CFC9BC) !important;
    border-radius: 8px;
    background: #FFFFFF !important;
    color: var(--hp-ink, #2B3038) !important;
    font-size: 14px;
    font-weight: 600;
    box-shadow: none !important;
}

body.single-gd_vendor .hp-vendor-claim--action .geodir-claim-post-form-link:hover,
body.single-gd_vendor .hp-vendor-claim--action .geodir-claim-post-form-link:focus {
    border-color: var(--hp-blue, #315E9E) !important;
    color: var(--hp-blue, #315E9E) !important;
}

/* Claimed / pending are STATEMENTS OF FACT, not actions — no box, no button
   affordance, and no wording that implies a pending claim has been granted. */
body.single-gd_vendor .hp-vendor-claim--claimed,
body.single-gd_vendor .hp-vendor-claim--pending {
    font-size: 14px;
    color: var(--hp-ink-muted, #565D69);
}

body.single-gd_vendor .hp-vendor-claim__state {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    border: 1px solid var(--hp-line, #E0DCD2);
    border-radius: 999px;
    background: var(--hp-surface-warm, #FAF7F1);
}

/* ── Linked products ──────────────────────────────────────────────────────
   Cards come from the same page-20 template the archives use, via GD's own
   [gd_loop], so they are identical to directory cards. The grid rules in
   homepezzo-archive.css are NOT keyed to a body class, so the 20px gaps and
   the 3/4-column breakpoints already apply here. Section removes itself when
   the vendor has no linked products. */

body.single-gd_vendor .hpg-vsp30:not(:has(.hpg-vsp_prod:not(:empty))) {
    display: none !important;
}

body.single-gd_vendor .hp-vendor-products {
    width: 100%;
}

/* ── Mobile ───────────────────────────────────────────────────────────── */

@media (max-width: 767.98px) {

    body.single-gd_vendor .hpg-vsp_title {
        font-size: 28px !important;
    }

    body.single-gd_vendor .hp-vendor-logo {
        width: 88px;
        height: 88px;
        flex: 0 0 88px;
    }

    /* Label above value instead of a cramped two-column grid. */
    body.single-gd_vendor .hp-vendor-details__row {
        grid-template-columns: minmax(0, 1fr);
        gap: 2px;
    }

    /* Full-width primary action is the honest mobile affordance. */
    body.single-gd_vendor .hp-vendor-actions,
    body.single-gd_vendor .hp-vendor-actions__primary {
        width: 100%;
    }

    body.single-gd_vendor .hp-vendor-actions__primary {
        justify-content: center;
    }
}

@media (max-width: 575.98px) {

    body.single-gd_vendor .hpg-vsp_title {
        font-size: 24px !important;
    }

    body.single-gd_vendor .hp-vendor-claim--action .geodir-claim-post-form-link {
        width: 100%;
    }
}
