/* ProsGrade public design system (George, Sept 22 2026: "i want it to look clean and modern... not sure what it is that
   im doing to make it look a little sloppy").

   The diagnosis, measured rather than guessed: the public stylesheets carry 293 hex colours, 80 distinct shadows, 28
   radii and 50 gradients between them, and only 3 real custom properties. The single loudest symptom is the heading
   scale. `styles.css` is stock Bootstrap, whose headings are all `font-weight:500`, so every heading a ProsGrade
   stylesheet did NOT explicitly style fell back to 500 while the ones it did style are 700-800. The result on
   /plumbers/kelowna: the 40px H1 and the 28px section H3s render at weight 500 while the 34px H2s render at 800 with
   -1.02px tracking. The biggest type on the page is the thinnest, so nothing reads as being in charge. That is the
   "sloppy" - not crowding. Section spacing was already a consistent 40px rhythm and is deliberately left alone.

   This file loads AFTER the per-page @section Head stylesheets so it wins over Bootstrap without !important. To avoid
   trampling deliberate page styling, every scope selector is wrapped in :where(), which contributes ZERO specificity -
   so `:where(.core-directory) h1` scores (0,0,1), exactly matching Bootstrap's bare `h1`, beating it only on order, and
   losing to any class-based page rule such as `.tg-featured-title`. Intentional styling always wins; only the
   Bootstrap-default leftovers move.

   Scoped to an allow-list of public body classes on purpose: the Business Manager is a React SPA that shares this same
   layout with no body class, and it is on its own redesign track. It must not inherit any of this. */

/* The --pg-* tokens used below live in tokens.css, which every layout loads early. They are deliberately NOT defined
   here: this file loads last so its rules can beat Bootstrap, but a token must be present wherever a stylesheet that
   references it is served, and an undefined custom property fails silently. */

/* ---- Type scale -------------------------------------------------------------------------------------------------
   Weight now rises with size instead of falling. Tracking tightens as size grows, which is what the 800-weight
   headings were already doing alone and what made them look like a different typeface from the 500s. */

:where(.core-directory, .core-city, .core-profile, .core-comparison, .core-contact, .core-for-business,
       .core-get-matched, .core-home, .core-plan-pricing, .core-price-guide, .core-service-resource,
       .core-lead-unlock, .core-claim-owner-response) h1 {
    font-size: 36px;
    font-weight: 800;
    line-height: 1.15;
    letter-spacing: -0.02em;
}

:where(.core-directory, .core-city, .core-profile, .core-comparison, .core-contact, .core-for-business,
       .core-get-matched, .core-home, .core-plan-pricing, .core-price-guide, .core-service-resource,
       .core-lead-unlock, .core-claim-owner-response) h2 {
    font-size: 26px;
    font-weight: 750;
    line-height: 1.25;
    letter-spacing: -0.015em;
}

:where(.core-directory, .core-city, .core-profile, .core-comparison, .core-contact, .core-for-business,
       .core-get-matched, .core-home, .core-plan-pricing, .core-price-guide, .core-service-resource,
       .core-lead-unlock, .core-claim-owner-response) h3 {
    font-size: 19px;
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: -0.01em;
}

:where(.core-directory, .core-city, .core-profile, .core-comparison, .core-contact, .core-for-business,
       .core-get-matched, .core-home, .core-plan-pricing, .core-price-guide, .core-service-resource,
       .core-lead-unlock, .core-claim-owner-response) h4 {
    font-size: 16.5px;
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: -0.01em;
}

/* Bootstrap's .h1-.h4 utilities are meant to make an element look like that heading level, but they carry Bootstrap's
   own weight:500, so `<h3 class="h4">Customer Reviews</h3>` on a profile rendered 24px/500 next to 24px/700 siblings -
   the same size at two weights. Point the utilities at the same scale as the elements. These are (0,1,0), matching
   Bootstrap's, and this file loads later. */
:where(.core-directory, .core-city, .core-profile, .core-comparison, .core-contact, .core-for-business,
       .core-get-matched, .core-home, .core-plan-pricing, .core-price-guide, .core-service-resource) .h3 {
    font-size: 19px;
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: -0.01em;
}

:where(.core-directory, .core-city, .core-profile, .core-comparison, .core-contact, .core-for-business,
       .core-get-matched, .core-home, .core-plan-pricing, .core-price-guide, .core-service-resource) .h4 {
    font-size: 16.5px;
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: -0.01em;
}

/* FAQ questions are a row label inside an accordion, not a section heading. On a business profile they inherited the
   profile's forced 24px h2 size at weight 400 - the largest and lightest text in that whole panel. */
:where(.core-directory, .core-city, .core-profile, .core-price-guide, .core-service-resource) .core-faq-question,
/* On a profile these sit inside .core-profile-panel, whose own rule in profile-parity.css is (0,2,1) and forces 24px.
   Matching that shape here (class + class + element) ties on specificity, and this file loads after it. */
:where(.core-profile) .core-profile-panel h2.core-faq-question,
:where(.core-profile) .core-profile-panel h3.core-faq-question {
    font-size: 17px;
    font-weight: 700;
    line-height: 1.35;
    letter-spacing: normal;
}

/* Section headings sit in `.block-head` (City.cshtml and friends) and are marked up as either h2 or h3 depending on the
   page, which is why "Top Options for Plumbers in Kelowna" (h3, 28px) and "Questions about Plumbers" (h2) disagreed.
   One deliberate rule so a section heading reads the same everywhere, one clear step below the page title. This one is
   NOT in :where() - normalising section headings is the point, so it must beat the 28px Bootstrap default that the
   unstyled ones inherit. */
:where(.core-directory, .core-city, .core-profile, .core-comparison, .core-contact, .core-for-business,
       .core-get-matched, .core-home, .core-plan-pricing, .core-price-guide,
       .core-service-resource) .block-head > h2,
:where(.core-directory, .core-city, .core-profile, .core-comparison, .core-contact, .core-for-business,
       .core-get-matched, .core-home, .core-plan-pricing, .core-price-guide,
       .core-service-resource) .block-head > h3 {
    font-size: 26px;
    font-weight: 750;
    line-height: 1.25;
    letter-spacing: -0.015em;
    color: var(--pg-ink);
}

/* Feature-panel headings. These four were explicitly styled at 34px/800 (and the pricing one at a clamp up to 32px),
   which on /plumbers/kelowna put a sub-section heading within 2px of the page title - the loudest remaining break in
   the ladder once the Bootstrap defaults were fixed. They are section-level content, so they get the section level.
   Their own rules are single-class (0,1,0) and this matches at (0,1,0) while loading later, so it wins cleanly. */
:where(.core-directory, .core-city, .core-profile, .core-price-guide, .core-service-resource) .tg-city-match-title,
:where(.core-directory, .core-city, .core-profile, .core-price-guide, .core-service-resource) .tg-city-guide-title,
:where(.core-directory, .core-city, .core-profile, .core-price-guide, .core-service-resource) .tg-city-insights-title,
:where(.core-directory, .core-city, .core-profile, .core-price-guide, .core-service-resource) .tg-pricing-title {
    font-size: 26px;
    font-weight: 750;
    line-height: 1.25;
    letter-spacing: -0.015em;
}

/* ---- Radius scale ------------------------------------------------------------------------------------------------
   George (Sept 22 2026): "are there too many rounded edges everywhere... panels inside of panels... outer panel with
   straight edges, inside ones rounded? sharp edges give the idea of professionalism right?"

   The instinct is right, the remedy is the other way round. The rule for nested boxes is CONCENTRIC radii: the inner
   radius should be SMALLER than the outer, ideally outer minus the padding between them, so the two curves stay
   parallel. Square-outside-round-inside breaks that badly - the inner curve would read as floating loose inside a hard
   corner. Measured on /plumbers/kelowna: 72 rounded boxes, 57 nested pairs, and 30 of them with the inner radius equal
   to or LARGER than its parent's. That inversion, plus radii up to 22px, is what reads as soft and toy-like.

   So: no square corners, but a tighter, properly concentric three-step scale. Outer panels and cards 14px, anything
   nested inside them 8px, pills stay pills. Drops 16, 18, 20 and 22 from the public pages entirely. */

/* Outer panels: were 20-22px. */
:where(.core-directory, .core-city, .core-profile, .core-price-guide, .core-service-resource) .tg-pricing-card,
:where(.core-directory, .core-city, .core-profile, .core-price-guide, .core-service-resource) .tg-city-match-card,
:where(.core-directory, .core-city, .core-profile, .core-price-guide, .core-service-resource) .tg-city-guide-card,
:where(.core-directory, .core-city, .core-profile, .core-price-guide, .core-service-resource) .tg-city-insights-card,
:where(.core-directory, .core-city, .core-profile, .core-price-guide, .core-service-resource) .tg-city-faq-card,
:where(.core-directory, .core-city, .core-profile, .core-price-guide, .core-service-resource) .tg-city-snapshot-card {
    border-radius: var(--pg-r-md);
}

/* Nested panels: were 14-18px inside a 20-22px parent, i.e. almost the same curve as their container. */
:where(.core-directory, .core-city, .core-profile, .core-price-guide, .core-service-resource) .tg-city-guide-panel,
:where(.core-directory, .core-city, .core-profile, .core-price-guide, .core-service-resource) .tg-city-insight-panel,
:where(.core-directory, .core-city, .core-profile, .core-price-guide, .core-service-resource) .tg-pricing-table,
:where(.core-directory, .core-city, .core-profile, .core-price-guide, .core-service-resource) .tg-pricing-context,
:where(.core-directory, .core-city, .core-profile, .core-price-guide, .core-service-resource) .tg-city-snapshot-stat {
    border-radius: var(--pg-r-sm);
}

/* Business profile panels: an 18px callout sitting inside an 18px panel, same curve as its container. */
:where(.core-profile) .core-profile-panel,
:where(.core-profile) .tg-business-panel {
    border-radius: var(--pg-r-md);
}

:where(.core-profile) .tg-business-strength-callout,
:where(.core-profile) .core-profile-panel .card,
:where(.core-profile) .tg-business-panel .card {
    border-radius: var(--pg-r-sm);
}

/* Third rung: a small well inside an 8px panel needs to step down again, or it matches its parent. */
:where(.core-directory, .core-city, .core-profile, .core-price-guide, .core-service-resource) .tg-city-insight-icon {
    border-radius: 6px;
}

/* Badges rendered at 20px inside 14px cards - wider than the card holding them. They are tags, so make them tags:
   a pill reads as a different kind of object and steps out of the panel hierarchy altogether. */
:where(.core-directory, .core-city, .core-profile, .core-price-guide, .core-service-resource) .badge {
    border-radius: var(--pg-r-pill);
}

/* Logo wells sat at 14px inside a 14px card - the clearest case of a child matching its parent's curve. The doubled
   class matches the (0,2,0) of `.core-city .tg-pro-logo-box` in city-parity.css, which this file loads after. */
:where(.core-directory, .core-city, .core-profile) .tg-featured-logo-wrap.tg-featured-logo-wrap,
:where(.core-directory, .core-city, .core-profile) .tg-pro-logo-box.tg-pro-logo-box {
    border-radius: var(--pg-r-sm);
}

/* ---- Logo and photo wells -----------------------------------------------------------------------------------------
   George (Sept 22 2026): "when a photo/logo doesnt fit the square in dimensions.. can we scale to fit the square?"

   A listing with no logo falls back to one of its photos, and the markup already tags that case `.tg-logo-photo` with
   `object-fit:cover` waiting in page-city.css. It never applied: `.core-city img.tg-pro-logo` in core.css is (0,2,1)
   and beats the (0,1,0) of `.tg-logo-photo`, so photos were letterboxed inside the square with dead bands above and
   below. Matching that (0,2,1) here, later in the cascade, lets the intended rule through.

   Photos crop to fill - a cropped kitchen still reads as a kitchen. Real logos keep `contain`, because cropping a
   brand mark is worse than matting it; they get a white ground and a little padding so the mat looks deliberate. */
:where(.core-directory, .core-city, .core-profile) img.tg-pro-logo.tg-logo-photo,
:where(.core-directory, .core-city, .core-profile) img.tg-featured-logo.tg-logo-photo {
    object-fit: cover;
    object-position: center;
    /* core.css pins these to 72px via width + min-width + max-width + flex-basis, but the well is a 64px box with a
       1px border, so a 72px image overflowed its own container and got clipped off-centre. All four have to be
       released together or the widest one wins and the image still is not square. */
    width: 100%;
    height: 100%;
    min-width: 0;
    max-width: 100%;
    flex: 1 1 auto;
    padding: 0;
    background: var(--pg-surface-2);
}

:where(.core-directory, .core-city, .core-profile) img.tg-pro-logo:not(.tg-logo-photo),
:where(.core-directory, .core-city, .core-profile) img.tg-featured-logo:not(.tg-logo-photo) {
    object-fit: contain;
    object-position: center;
    width: 100%;
    height: 100%;
    min-width: 0;
    max-width: 100%;
    flex: 1 1 auto;
    padding: 4px;
    background: var(--pg-surface);
}

/* The well itself has to clip, or a cover-fitted photo squares off the rounded corner it sits in. */
:where(.core-directory, .core-city, .core-profile) .tg-pro-logo-box,
:where(.core-directory, .core-city, .core-profile) .tg-featured-logo-wrap {
    overflow: hidden;
}

/* ---- Muted text -------------------------------------------------------------------------------------------------
   Bootstrap's .text-muted is #6c757d, a warm grey that clashes with the cool slate greys the ProsGrade stylesheets
   use. Same specificity as Bootstrap's utility (0,1,0), later in the cascade, so it wins without !important. */
:where(.core-directory, .core-city, .core-profile, .core-comparison, .core-contact, .core-for-business,
       .core-get-matched, .core-home, .core-plan-pricing, .core-price-guide, .core-service-resource,
       .core-lead-unlock, .core-claim-owner-response) .text-muted {
    color: var(--pg-muted);
}

/* ---- Business profile hero --------------------------------------------------------------------------------------
   George (Sept 22 2026): "let's test a reformatting of the business hero.. to shrink the height a bit and maybe
   re-organize all the information to look amazing". It measured 608px, 74% of an 820px laptop viewport, because
   162/100 padding wrapped six stacked blocks. The markup now emits three rows (eyebrow / name / meta) and these rules
   size them. Everything here is a single class at (0,1,0) matching page-businesses.css and loading after it. */

/* Not wrapped in :where(): profile-parity.css sets `.core-profile .tg-business-hero{padding:180px 0 120px}` at (0,2,0)
   and this rule is deliberately overriding it, so it has to match that shape rather than duck under it. */
.core-profile .tg-business-hero {
    /* 132/56 was too far the other way - George: "maybe a little more vertical space? that looks pretty crunched on
       desktop". The row count is right, the breathing room was not. Still well short of the original 162/100. */
    padding: 148px 0 92px;
}

:where(.core-profile) .tg-business-hero-main {
    align-items: center;
    gap: 22px;
}

/* Row 1: tier pill and trade/city on one line, replacing a pill stacked under the logo plus a separate subtitle. */
:where(.core-profile) .tg-business-hero-eyebrow {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 18px;
}

:where(.core-profile) .tg-business-hero-eyebrow-text {
    color: rgba(255, 255, 255, 0.86);
    font-size: 15px;
    font-weight: 600;
    letter-spacing: 0.01em;
}

:where(.core-profile) .tg-business-hero-tier-pill {
    min-height: 26px;
    padding: 5px 11px;
    font-size: 11.5px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    box-shadow: none;
}

/* 62px forced most business names onto two lines, which alone cost 60px of hero. 40px still leads the page - nothing
   else on a profile comes close - and usually sits on one line. */
:where(.core-profile) .tg-business-hero-title {
    font-size: 40px;
    font-weight: 800;
    line-height: 1.08;
    letter-spacing: -0.025em;
    margin-bottom: 22px;
    /* page-businesses.css caps this at 18ch, which was sized for 62px type. At 40px that wraps ordinary names like
       "Bree-link plumbing and Heating" onto a second line and gives back the height we just saved. Let the 760px
       right column do the constraining instead; genuinely long names still wrap. */
    max-width: none;
}

/* Row 3: rank, rating and phone share one row. The 2px rule that used to separate them is gone - with the blocks side
   by side there is nothing left to divide. */
:where(.core-profile) .tg-business-hero-meta-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px 14px;
    margin: 0;
}

/* George: "if the pills are all horizontally aligned.. they shouldn't be different sizes". They were 32 / 42 / 49px,
   because each came from a different component with its own padding and min-height. One row, one height. The phone
   stays the obvious primary action through colour and weight rather than by being physically taller. */
:where(.core-profile) .tg-business-hero-meta-row > * {
    height: 44px;
    min-height: 44px;
    padding: 0 18px;
    border-radius: var(--pg-r-pill);
    line-height: 1;
}

:where(.core-profile) .tg-business-hero-meta-row .core-profile-rank {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin: 0;
    border: 1px solid rgba(255, 255, 255, 0.26);
    background: rgba(255, 255, 255, 0.10);
    color: #fff;
    font-size: 14px;
    font-weight: 700;
}

/* 20px inside a 44px pill left almost no optical padding next to the 14px chips beside it. */
:where(.core-profile) .tg-business-hero-meta-row .tg-hero-phone-cta {
    font-size: 17px;
}

/* On a Basic listing this stands where the phone sits on a Pro one. Unstyled it was a bare label beside a bordered
   chip, which made the row look half-finished; it now matches the rank chip while staying visibly the muted state. */
:where(.core-profile) .tg-business-hero-meta-row .tg-locked-contact-hero {
    gap: 8px;
    border: 1px dashed rgba(255, 255, 255, 0.34);
    background: rgba(255, 255, 255, 0.06);
    color: rgba(255, 255, 255, 0.88);
    font-size: 14px;
    font-weight: 700;
}

:where(.core-profile) .tg-business-hero-meta-row .tg-locked-contact-hero:hover {
    border-color: rgba(255, 255, 255, 0.6);
    background: rgba(255, 255, 255, 0.14);
    color: #fff;
}

:where(.core-profile) .tg-business-hero-meta-dot {
    opacity: 0.55;
}

:where(.core-profile) .tg-business-hero-meta-row .tg-business-market-position-line2 {
    margin-left: 6px;
    font-size: 11.5px;
    font-weight: 600;
    opacity: 0.8;
}

:where(.core-profile) .tg-business-hero-meta-row .tg-business-hero-rating,
:where(.core-profile) .tg-business-hero-meta-row .tg-hero-phone-cta,
:where(.core-profile) .tg-business-hero-meta-row .tg-locked-contact-hero {
    display: inline-flex;
    align-items: center;
    margin: 0;
}

:where(.core-profile) .tg-business-hero-logo-wrap {
    width: 88px;
    height: 88px;
    border-radius: var(--pg-r-md);
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.20);
}

:where(.core-profile) .tg-business-hero-leftcol {
    width: 88px;
    min-width: 88px;
}

@media (max-width: 991.98px) {
    .core-profile .tg-business-hero {
        padding: 112px 0 40px;
    }

    :where(.core-profile) .tg-business-hero-title {
        font-size: 30px;
    }

    :where(.core-profile) .tg-business-hero-main {
        align-items: flex-start;
        gap: 16px;
    }
}

/* profile-parity.css also carries a 767.98 override at (0,2,0); match it or the phone hero keeps the old padding. */
@media (max-width: 767.98px) {
    .core-profile .tg-business-hero {
        padding: 104px 0 36px;
    }

    /* George (Sept 22 2026): "on mobile.. the one ranked #4 in kelowna isn't linking up as nice". page-businesses.css
       stacks this row at this breakpoint with `align-items:stretch` and gives the rating and phone `width:100%` - but
       not the rank, which never used to live in this row. The `align-items:center` set above for the desktop row then
       won anyway, because a media query adds no specificity and this file loads last, so the two sized chips filled
       the width while the rank floated centred at its natural size. Restore the stack and size all three alike. */
    :where(.core-profile) .tg-business-hero-meta-row {
        align-items: stretch;
    }

    :where(.core-profile) .tg-business-hero-meta-row > * {
        width: 100%;
        justify-content: flex-start;
    }
}

/* ---- Hero -------------------------------------------------------------------------------------------------------
   The title bar was padding-top:180px / padding-bottom:120px around 116px of actual content - 300px of padding, and
   asymmetric enough to look unbalanced. On a 820px laptop viewport that pushed the first listing 69% down the page, so
   the whole first screen was hero. The overlaid header is 88px, so 140px of top padding still leaves it 52px of
   clearance. Result: 416px -> ~346px, without taking air away from anything the eye actually reads. */
:where(.core-directory, .core-city, .core-profile, .core-comparison, .core-contact, .core-for-business,
       .core-get-matched, .core-plan-pricing, .core-price-guide, .core-service-resource) #prosgrade_titlebar {
    padding-top: 140px;
    padding-bottom: 90px;
}

@media (max-width: 991.98px) {
    :where(.core-directory, .core-city, .core-profile, .core-comparison, .core-contact, .core-for-business,
           .core-get-matched, .core-plan-pricing, .core-price-guide, .core-service-resource) #prosgrade_titlebar {
        padding-top: 120px;
        padding-bottom: 70px;
    }
}
