/*
    Public website overrides.

    Last stylesheet in the public website load order, so use this file only for
    narrow corrections that must win over the template vendor CSS and
    public-website.css.

    Keep general public site branding in public-website.css.
    Keep component-specific styling in .razor.css isolation files.
    Always use var(--rc-...) tokens rather than literal colour values.
*/

/*
    Brand logo sizing on the public site (2026-08-02).

    ⚠️ THE TEMPLATE SIZED ITS LOGO BY WIDTH; BrandLogo SIZES BY HEIGHT. `style.css` sets
    `.navbar-brand img { width: 170px }` and `.footer-logo img { width: 200px }`, but BrandLogo's scoped
    rule `.brand-logo__image[b-...]` is more specific and sets `width: auto` with a height meant for the
    admin top bar — so swapping the artwork in silently shrank the mark from about 65px tall to 44px.
    Nothing looked broken, it just looked wrong, which is the kind of change that ships.

    These heights are the template's own intended sizes converted through the horizontal lockup's 2.61:1
    ratio, so the logo occupies the space the design allowed for it:
        header  170px wide / 2.61 = 65px = 4.0rem
        footer  200px wide / 2.61 = 77px = 4.8rem
        mobile  130px wide / 2.61 = 50px = 3.1rem

    ⚠️ Set through --rc-brand-logo-height rather than by overriding height directly. That custom property
    is the documented way a shell asks BrandLogo for a size; fighting its scoped rule with a more
    specific selector would work until the component's CSS changed.
*/
.navbar-brand {
    --rc-brand-logo-height: 4rem;
}

.offcanvas-brand {
    --rc-brand-logo-height: 3.1rem;
}

.footer-logo {
    --rc-brand-logo-height: 4.8rem;
}

@media (max-width: 991px) {
    .navbar-brand {
        --rc-brand-logo-height: 3.1rem;
    }
}

/* ⚠️ The office-hours item in the top contact strip is NOT an anchor — office hours are a fact, not
   somewhere to go, so the buttons-not-links rule leaves it as plain text. The SenoCare template only
   ever colours `.header-top-list a`, so without this the hours and their clock icon render in the
   strip's dim inherited grey while the email and phone beside them are white with a teal icon. It
   looked like a disabled control sitting between two live ones. (2026-08-05.) */
.header-top-list ul li[data-public-header-hours] {
    color: var(--color-white);
}

.header-top-list ul li[data-public-header-hours] i {
    color: var(--theme-color);
    margin-right: 5px;
}

/* ── The two public enquiry forms (Notifications stage 3c) ─────────────────────────────────────────
   ⚠️ These live HERE, not in `syncfusion-brand.css`: the public shell links the theme, the SenoCare
   template CSS and this file, and nothing else. A rule written into the admin sheet would be DEAD on
   this page — silently, with the form rendering unstyled, which reads as markup nobody finished
   rather than as a broken import. (The P-D21 lesson, from the portal side.)
   ────────────────────────────────────────────────────────────────────────────────────────────── */

/* ⚠️⚠️ THE HONEYPOT (NT18). It must be unreachable to a person and PRESENT to something filling every
   input it finds. `display: none` is what the crudest bots skip, so this is hidden by position rather
   than by display — the field is really in the layout, just nowhere anybody can see or tab to it.
   ⚠️ The markup also carries aria-hidden and tabindex="-1", so a screen reader and the keyboard skip
   it. A visitor who filled this in would be silently discarded, so making it unreachable to assistive
   technology is a correctness requirement, not a nicety. */
.rc-hp {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* The confirmation and the failure. ⚠️ The public site raises NO TOAST — it is static SSR, so there is
   no circuit and no host — which makes these the only thing that tells somebody what happened. */
.rc-public-note {
    padding: 1rem 1.25rem;
    margin-bottom: 1.5rem;
    border-left: 4px solid;
    border-radius: 4px;
    font-weight: 500;
}

.rc-public-note--ok {
    color: #14532d;
    border-color: var(--theme-color);
    background-color: #e8f7f8;
}

/* ⚠️ Colour is not the only signal — the border weight and the text weight carry it too, because a
   red-only cue is invisible to a good many readers. */
.rc-public-note--error {
    color: #7f1d1d;
    border-color: #dc2626;
    background-color: #fef2f2;
}

/* The template styles `.form-group` for its own contact block; these two are ours. */
.contact-section .form-group {
    margin-bottom: 1.25rem;
}

.contact-section .validation-message {
    display: block;
    margin-top: 0.35rem;
    color: #dc2626;
    font-size: 0.9rem;
}

/* ═══ HOME PAGE CARD ROWS AND SERVICE DIVIDERS (RP80/RP84, product owner, 2026-08-20) ═══════════════

   ⚠️⚠️ THE SOLUTION-WIDE RULE IS THAT CARDS IN A ROW ALL TAKE THE HEIGHT OF THE TALLEST, and the
   public home page was breaking it in three places — measured before the fix: feature cards at
   307.4 / 336.2 / 336.2 / 273.8, service cards at 272.2 / 238.6 / 209.8 x4, testimonials at
   369.8 / 369.8 / 337.4. Several different bottom edges in one band read as a broken layout.

   ⚠️ THE BOOTSTRAP COLUMNS WERE ALREADY EQUAL — `.row` is a flex container and stretches its children
   by default. What was ragged is the CARD INSIDE the column, which sized to its own content. So the
   fix is `height: 100%` on the item, not `align-items` on the row: nothing here is opting out of
   stretch, so there is nothing to switch back on. */

.feature-area .feature-item,
.service-area .service-item {
    height: 100%;
}

/* ⚠️ The service card is `display: flex` in the template (icon beside content), so it needs its own
   stretch restated once it fills a taller box — without this the icon and the text stay top-aligned
   in a card that is now taller than they are, which is correct but reads as unfinished. */
.service-area .service-item {
    align-items: flex-start;
}

/*  ── The dividers between service cards ────────────────────────────────────────────────────────────
    The services row is `g-0` (no gutters), so the cards already touch: a rule between them is a
    DIVIDER rather than a gap, which is what was asked for.

    ⚠️ This block first shipped as BORDERS on the cards (RP84) and was replaced by the pseudo-elements
    below within the hour (RP85), because a border cannot be inset. The border version's own note has
    been REMOVED rather than left standing above the rules that superseded it — a comment describing a
    mechanism the code no longer uses is the hazard this repository keeps recording. */
/*  ⚠️⚠️ THEY ARE PSEUDO-ELEMENTS, NOT BORDERS, AND THAT IS FORCED (RP85, product owner, 2026-08-20:
    the dividers "must have padding in both ends so border doesn't run edge to edge").

    A `border` ALWAYS spans its whole edge — there is no way to inset one — so a bordered grid draws
    every rule corner to corner and the vertical and horizontal ones MEET, closing each junction into a
    continuous table rule. Inset rules need a box of their own, which is what these are.

    ⚠️ `.service-item` is already `position: relative` in the template, so there is a containing block
    to position against and nothing here has to create one.

    ⚠️⚠️ ABSOLUTE POSITIONING IS ALSO WHAT KEEPS THEM OUT OF THE FLEX LAYOUT. `.service-item` is
    `display: flex` (icon beside content), and a pseudo-element on a flex container is otherwise a FLEX
    ITEM — the trap that put a separator dot inside a value's own box when that value became a flex
    container. An absolutely-positioned child does not participate in flex layout at all.

    ⚠️ The 20px inset is the CARD'S OWN PADDING, not a number chosen by eye: the rule then spans exactly
    the card's content box, so it starts and stops where the text does. Both ends, so two rules meeting
    at a junction are 20px clear of each other in both directions. */
.service-area .service-wrap .service-item::before,
.service-area .service-wrap .service-item::after {
    content: "";
    position: absolute;
    /*  ⚠️⚠️ LIGHTER THAN `--rc-color-border` ITSELF, AND DERIVED FROM IT RATHER THAN RE-POINTING IT
        (RP87, product owner, 2026-08-20: "the line colour is too prominent, make it a bit lighter").
        The token is `rgba(0, 0, 0, 0.08)` and is the hairline under every table and panel in the admin
        portal — changing the token would repaint all of them to fix six dividers on one public page,
        which is the mistake RP57b recorded and refused.

        ⚠️ `color-mix` rather than a second literal, so this stays TIED to the token: if the hairline is
        ever re-toned the dividers follow it instead of drifting into a grey of their own. */
    background-color: color-mix(in srgb, var(--rc-color-border) 55%, transparent);
    /* ⚠️ Hidden by default and switched ON per breakpoint below. Drawing them all and removing the outer
       ones would need the removal repeated in every media query; this way each width states only what it
       draws. */
    display: none;
}

/* The VERTICAL divider — between two cards side by side. */
.service-area .service-wrap .service-item::after {
    inset-block: 20px;
    inset-inline-end: 0;
    width: 1px;
}

/* The HORIZONTAL divider — between two rows. */
.service-area .service-wrap .service-item::before {
    inset-inline: 20px;
    inset-block-end: 0;
    height: 1px;
}

/*  ⚠️⚠️ WHICH CARD IS LAST IN A ROW CHANGES WITH THE VIEWPORT — three across at lg, two at md, one
    below — so each width states its own rule rather than inheriting one written for the desktop grid,
    which would leave a stray divider hanging off the right edge on a tablet.

    One column (default): no vertical divider at all, and a horizontal one under every card but the last. */
.service-area .service-wrap [class*="col-"]:not(:last-child) .service-item::before {
    display: block;
}

/* Two across (md): a vertical rule on every odd card, and a horizontal one on every row but the last. */
@media (min-width: 768px) {
    .service-area .service-wrap [class*="col-"]:nth-child(2n + 1) .service-item::after {
        display: block;
    }

    .service-area .service-wrap [class*="col-"] .service-item::before {
        display: block;
    }

    .service-area .service-wrap [class*="col-"]:nth-last-child(-n + 2) .service-item::before {
        display: none;
    }
}

/* Three across (lg): the vertical rule belongs on the first two of each triple, and the bottom row is
   the last three. ⚠️ The md rule above must be UNDONE for every third card, or the middle column keeps
   a divider it should not have at this width. */
@media (min-width: 992px) {
    .service-area .service-wrap [class*="col-"] .service-item::after {
        display: block;
    }

    .service-area .service-wrap [class*="col-"]:nth-child(3n) .service-item::after {
        display: none;
    }

    .service-area .service-wrap [class*="col-"] .service-item::before {
        display: block;
    }

    .service-area .service-wrap [class*="col-"]:nth-last-child(-n + 3) .service-item::before {
        display: none;
    }
}

/*  ── Testimonials: equal-height slides ─────────────────────────────────────────────────────────────
    ⚠️⚠️ AN OWL CAROUSEL NEEDS THE STAGE MADE FLEX, NOT JUST THE CARD. The plugin lays its slides out as
    inline-block cells inside `.owl-stage`, so each one sizes to its own content and `height: 100%` on
    the card resolves against nothing. Measured before: 369.8 / 369.8 / 337.4.

    ⚠️ `.owl-stage` keeps its transform-based positioning — only its display changes — so the slider's
    own dragging and dot navigation are untouched. */
.testimonial-slider.owl-carousel .owl-stage {
    display: flex;
    align-items: stretch;
}

.testimonial-slider.owl-carousel .owl-item {
    display: flex;
}

.testimonial-slider.owl-carousel .testimonial-item {
    display: flex;
    flex-direction: column;
    width: 100%;
}

/* ⚠️ The quote block takes the slack, so the author line sits on the same baseline across all three
   slides. Without this the cards are equal and their FOOTERS are not, which is the defect wearing a
   different hat. */
.testimonial-slider.owl-carousel .testimonial-quote {
    flex: 1 1 auto;
}

/* ═══ THE TAGLINE BADGES (RP88, product owner, 2026-08-20) ═══════════════════════════════════════════
   "Get in touch" and "Considering a move" — the two badges with NO icon — sat off-centre in their pill
   and rendered with odd capitals. Both come from one template rule, and each half is a different fault.

   ⚠️⚠️ THE PADDING IS ASYMMETRIC ON PURPOSE, AND IT IS RIGHT FOR THE ICONED BADGE. `style.css` sets
   `padding: 2px 15px 2px 3px` — 3px on the left against 15px on the right — because the iconed variant
   opens with a 30px white circle that is meant to sit almost flush inside the pill's left edge. Eight of
   the ten badges have that icon and look correct.

   ⚠️ The two WITHOUT an icon inherit the same 3px, so their TEXT starts 3px from the edge and ends 15px
   from the other. Only those two are corrected, and they are selected by the thing that actually differs
   — whether the badge contains an icon — rather than by naming the two call sites, which would leave the
   next iconless badge with the same defect and no clue why. */
.site-title-tagline:not(:has(i)) {
    padding-inline: 15px;
}

/*  ⚠️⚠️ `text-transform: capitalize` UPPERCASES EVERY WORD, so "Get in touch" rendered as "Get In Touch"
    and "Considering a move" as "Considering A Move" — capitals mid-phrase, which is what was reported as
    the odd casing.

    ⚠️ IT IS REMOVED RATHER THAN OVERRIDDEN ON THE TWO CALL SITES. All ten taglines were read first: every
    one is already written in the casing it should display ("Our Services", "Testimonials", "FAQs"), so
    the transform was changing nothing that needed changing and mangling the only two written as
    sentences. Rendering the source as authored is both the fix and the simpler rule — and it puts the
    wording back under the control of whoever writes it. */
.site-title-tagline {
    text-transform: none;
}

/* ═══ HEADINGS AND BUTTONS RENDER AS AUTHORED (RP90, product owner, 2026-08-20) ══════════════════════
   "Review the whole home page and fix heading casing" — the same fault RP88 found on two badges, and it
   reaches every heading and every button on the site.

   ⚠️⚠️ THE SOURCE TEXT WAS ALREADY RIGHT IN ALMOST EVERY CASE. `.site-title` and `.hero-title` carry
   `text-transform: capitalize`, so markup reading "Every resident deserves quality care" rendered as
   "Every Resident Deserves Quality Care", and buttons written "Send enquiry" and "Send message"
   rendered "Send Enquiry" and "Send Message". Every heading source on this site was read before this
   rule was written: all of them are sentence case already.

   ⚠️ SO THE TRANSFORM IS REMOVED RATHER THAN THE STRINGS BEING RE-CASED TO FIGHT IT. Whoever writes the
   copy decides how it reads; a stylesheet that overrules them is why a correction to the markup appeared
   to do nothing. The handful of strings genuinely written in title case are corrected at source.

   ⛔ SUPERSEDED 2026-09-24 (PC65) — the paragraph below is kept because the REASONING was sound and its
   PREMISE was overtaken, which is the only way the next reader can tell this apart from an oversight.
   As written: "⚠️ `.nav-link` KEEPS ITS CAPITALIZE, deliberately. Those four labels are single words
   already capitalised in the markup, so the transform changes nothing there, and title case is the
   ordinary convention for a navigation bar."

   ⚠️⚠️ THAT WAS TRUE OF FOUR HARD-CODED WORDS AND IS FALSE OF CONTENT. CFG-015 slice 5 moved the menu
   into the database, so a System Admin types the label at /admin/website/menu — and the first one they
   wrote as a phrase, "About us", rendered "About Us". See the rule below. */
.site-title,
.hero-single .hero-content .hero-title,
.theme-btn,
.theme-btn2,
.pricing-header h5,
.blog-title,
.counter-box .title {
    text-transform: none;
}

/* ═══ THE MENU RENDERS AS AN ADMINISTRATOR TYPED IT (PC65, product owner, 2026-09-24) ═════════════════
   "I renamed one of the menu items, but when it renders in the public website each word gets
   capitalised." Reported against the published build after CFG-015: "About us" rendered "About Us".

   ⚠️⚠️ THIS IS RP90's OWN FINDING REACHING THE ONE SELECTOR RP90 DELIBERATELY SPARED, because the thing
   that made sparing it safe has gone. The menu was four words in markup when that call was made; it is
   a table now. A stylesheet that overrules the person writing the copy is exactly what RP90 removed
   everywhere else, and the argument does not change because the copy moved into the database — it gets
   stronger, since an administrator editing a label cannot read this file to find out why their
   correction did nothing.

   ⚠️ IT WAS A DESKTOP-ONLY DEFECT AND THE INCONSISTENCY IS THE PART WORTH KNOWING: both template rules
   sit inside `@media all and (min-width: 992px)`, so the SAME label already rendered "About us" on a
   phone and "About Us" on a laptop. The override is stated unconditionally rather than inside a
   matching media query — there is no width at which this transform is wanted, and a copied media query
   is one more place for the two to drift apart.

   ⚠️ `.dropdown-item` CARRIES THE IDENTICAL TRANSFORM AND IS DELIBERATELY NOT TOUCHED HERE. The menu
   renders no submenu today (`PublicNavigationMenu` emits a flat list), so a rule for it would style
   nothing and read as though sub-menus existed. `PublicWebsiteCasingGuardTests` is keyed on whether the
   class reaches public markup, so the day a submenu is built the guard asks for it. */
.navbar .nav-item .nav-link {
    text-transform: none;
}

/* ======================================================================
   THE PRICING BAND'S HEADLINE RANGE (2026-09-21, PC37b)

   "From 75,000 – 175,000", under the band's heading. It states a span over
   EVERY published package, including the ones withholding their own figure,
   which is what lets an operator hide the specifics and still tell a family
   what to expect.

   ⚠️⚠️ THE CLASS IS OURS AND IS DEFINED HERE BECAUSE THE PURCHASED TEMPLATE HAS
   NO SUCH ELEMENT. It was written into the markup first and `grep` found it in
   no stylesheet at all — P-D52's invented-class trap, caught before publishing
   rather than by somebody looking at an unstyled line on the live site.

   ⚠️ It goes in THIS file, not in the vendor's `style.css`: that sheet is the
   purchased template and is replaced wholesale on an upgrade.

   ⚠️ Sized between the title and the body text on purpose — it is a
   qualification of the heading, not a second heading. Tabular figures so the
   two numbers line up on their digits rather than drifting.
   ====================================================================== */
.pricing-area .site-heading .pricing-range {
    margin-block: 10px 0;
    font-size: 18px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    /* ⚠️ The TEMPLATE's own token, not one of ours — this sheet sits on top of `style.css` and a
       rebrand there must carry the range with it. `--color-primary` was written here first and exists
       in no public stylesheet at all; the fallback would have hidden that. */
    color: var(--theme-color2, #0197a1);
}

/* ======================================================================
   Care packages band — the name tag, and pricing switched off (CFG-015, PC57, 2026-09-22)

   The tag is CENTRED on the card's top edge with every corner rounded (product owner, from the
   approved mock): the template placed it top-right with one square corner, which read as broken.
   `white-space: nowrap` keeps a long name on one line now that it no longer hangs off an edge.

   With public pricing OFF the cards carry no figure (`.pricing-note`) and the operator's typed range
   sits in a centred footer band with the section's button beneath it. Every colour is the TEMPLATE's
   variable, so the branding sheet (PC52) carries it.
   ====================================================================== */
.pricing-item .pricing-header {
    left: 50%;
    right: auto;
    transform: translateX(-50%);
    border-radius: 50px;
    white-space: nowrap;

    /* ⚠️⚠️ THE NAME SAT HIGH IN THE TAG: more space beneath it than above (product owner, 2026-09-23,
       from the published band). The template gives this tag `padding: 0 15px` — NO vertical padding at
       all — so its height came entirely from the heading's line box, and the heading is an INLINE-BLOCK
       inside a block, which reserves room under the baseline for descenders whether or not the name has
       any. That gap is what put the extra space at the bottom.
       ✅ A flex box removes the baseline gap (there is no line box to sit on), and the padding is then
       stated on BOTH axes so the tag's space above and below the name is the same number. */
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 8px 18px;
}

/* ⚠️⚠️ AND THE NAME'S OWN BOTTOM MARGIN, WHICH IS THE OTHER HALF AND WAS MEASURED, NOT GUESSED: with the
   flex box and 8px padding in place the live tag still read 8px above the name and 16px below. Our markup
   is `<h3 class="h5">`, and Bootstrap gives the `.h5` CLASS `margin-bottom: 0.5rem` — 8px, exactly the
   difference. The template's own reset zeroes h1–h6 as ELEMENTS, so it never touched this one.
   ✅ Re-measured after this: 8px above, 8px below. */
.pricing-item .pricing-header h3,
.pricing-item .pricing-header h5 {
    margin: 0;
}

.pricing-item .pricing-note {
    margin: 0;
    font-size: 16px;
    color: var(--body-text-color);
}

.pricing-footer {
    margin-block-start: 50px;
    padding: 32px 36px;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    background: var(--color-white);
    border: 2px solid var(--theme-color2);
    border-radius: 40px;
}

.pricing-footer-label {
    font-size: 14px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--body-text-color);
}

.pricing-footer-range {
    margin: 4px 0 0;
    font-family: var(--heading-font);
    font-size: 26px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--theme-color2);
}

.pricing-footer .pricing-footer-btn {
    margin-block-start: 24px;
    background: var(--color-dark);
}

/* PC57 — the package's website description, and a cross-branch price RANGE, which at the template's 50px
   figure would overflow the card ("from 75,000.00 - 90,000.00"). */
.pricing-item .pricing-description {
    margin: 0 0 12px;
    font-size: 16px;
    color: var(--body-text-color);
}

.pricing-amount strong.pricing-amount-range {
    font-size: 28px;
    line-height: 1.25;
}

/* ======================================================================
   Care packages band — every card bordered, a readable tag, one height (CFG-015, PC59, 2026-09-22)

   Product owner, from the published band: "why only one gets a border … border on each card but very
   light (#f3cfd3)", "heading colour … hard to read", "all the cards should maintain the same height and
   the button of all cards should align at the same level".

   ⚠️ EVERY card takes the same light border and the template's 3px "featured" outline on the middle card
   is withdrawn — one card outlined read as one card selected. The markup still carries `.active` (the
   template's hover lift is unaffected); only the outline goes.
   ⚠️ The name measured GREY (rgb 117,127,149) on the coral tag. It is white now — the template's own
   intent for the tag (`.pricing-header h5`, which our `<h3 class="h5">` never matched) — at weight 700 so
   the 20px name is WCAG "large text" and the tag's ~3.4:1 passes the 3:1 floor.
   ⚠️ Equal height (RP35): Bootstrap's row already stretches the COLUMNS; the card fills its column and is
   a flex column, and the button's `margin-top: auto` pins every button to the card's bottom edge.
   ====================================================================== */
.pricing-area .pricing-item {
    height: 100%;
    display: flex;
    flex-direction: column;
    border: 1px solid #f3cfd3;
}

.pricing-area .pricing-item.active {
    outline: none;
}

.pricing-area .pricing-item .pricing-header h3 {
    color: var(--color-white);
    font-weight: 700;
}

.pricing-area .pricing-item .pricing-btn {
    margin-top: auto;
}
