
/* ── Faux-condensed Montserrat ────────────────────────────────────────────
   IMPORTANT — this is a *simulated* condensed look, not a real condensed
   cut: Montserrat has no wdth axis on Google Fonts (confirmed against the
   variable font — filename is literally Montserrat-VariableFont_wght.ttf,
   weight only) and no separate condensed family exists either. There's a
   genuinely condensed typeface already available in this theme —
   'Helvetica Neue LT Std' Heavy Condensed (style.css, HelveticaNeueLTStd-
   HvCn) — that's the option if a real condensed cut matters more than
   staying on-brand-font. This class instead narrows Montserrat itself via
   scaleX + tightened letter-spacing, which is a reasonable approximation
   for a short line of display/heading text but will visibly distort glyph
   shapes (thinner strokes than a real condensed cut would have) — best
   used sparingly, not for body copy or long headlines.

   transform-origin must match the text's alignment, because scaleX()
   shrinks toward its origin rather than shrinking in place — flexbox
   centers/right-aligns the (untransformed) layout box correctly, but a
   left-origin scaleX on a centered box still visually squashes the
   content toward that box's left edge, which looks like the text is
   off-center even though the box itself isn't (this exact bug shipped on
   the "Control the flow" hero slide: hero-text--center's box was
   correctly centered, but .text-condensed defaulted to a left origin).
   Rather than rely on remembering to add a matching --center/--right
   modifier class every time .text-condensed is used, the .hero-text--*
   ancestor selectors below set the correct origin automatically. The
   standalone --center/--right modifiers still exist for the rare case
   .text-condensed is used somewhere outside a .hero-text container. ──── */
.text-condensed {
    display: inline-block;
    transform: scaleX(0.8);
    transform-origin: left center;
    letter-spacing: -0.01em;
}
.text-condensed.text-condensed--center,
.hero-text--center .text-condensed {
    transform-origin: center center;
}
.text-condensed.text-condensed--right,
.hero-text--right .text-condensed {
    transform-origin: right center;
}


/* ── Sticky header ─────────────────────────────────────────────────────── */
#header-wrap {
    position: sticky;
    top: 0;
    z-index: 1000;
}

/* ── Product sidebar menu: sticky + column-fluid ──────────────────────────
   _ProductMenu.cshtml. The nav previously carried inline
   `width:280px; position:fixed;`. position:fixed is viewport-anchored, so it
   can't inherit the .sidebar (col-lg-3) width — hence the hard 280px, which
   overflowed the maroon column on any viewport narrower than ~1680px
   (280 / (2/12)); the overspill was clipped/over-painted by the adjacent
   .prod-BAK main column. Most visible on tablet landscape (~1024px), where
   labels like "SHOPPING BASKETS" / "ANTI-SLIP COATINGS" were cut mid-word.

   Fix: position:fixed → position:sticky. Sticky keeps the intended
   "follows the scroll" behaviour while staying IN normal flow, so width:100%
   fills the column at every breakpoint and bg-dark contains it — no hand-
   computed pixel width to keep re-deriving against the grid.

   Two requirements sticky imposes here:

   (a) No ancestor may establish a non-scrolling scroll container, or sticky
       resolves against that box (which never scrolls) and never engages.
       .content-wrap (style.css) sets overflow:hidden — needed on the HOMEPAGE
       (_PublicLayout) for the hero slider's 100vw breakout sliver, but the
       product layout has no such element, so we neutralise it there only,
       scoped via the .product-layout body class (_ProductLayout.cshtml).

   (b) Sticky travels only within its nearest block ancestor's box. The wrapper
       chain (.sidebar-widgets-wrap > .d-flex) is content-height (≈ nav
       height), which would unstick the menu almost immediately. .sidebar is a
       flex-row child and already stretches to row height (= the tall .prod-BAK
       column); h-100 on the wrappers passes that height down so the nav can
       travel the full length of the product list.

   Scoped to lg+ (≥992px) — the only band where the sidebar is a rail. Below
   that the column stacks to col-12 and the menu is a normal static block
   above the product grid, where sticky is neither needed nor wanted.
   top offset tracks the Canvas header-height variable (96px) + 1rem gap. ─── */
.product-layout .content-wrap {
    overflow: visible;
}

@media (min-width: 992px) {
    .product-layout .sidebar .sidebar-widgets-wrap,
    .product-layout .sidebar .sidebar-widgets-wrap > .d-flex {
        height: 100%;
    }
    .product-layout #sideMenu {
        position: sticky;
        top: calc(var(--cnvs-header-height, 96px) + 1rem);
        width: 100%;
    }
}

/* Long category labels wrap instead of clipping/overflowing the column. */
.product-layout #sideMenu a,
.product-layout #sideMenu .pmenu-toggle {
    overflow-wrap: break-word;
}

/* ── Product page background: mobile full-bleed ───────────────────────────
   Pages/Shared/_ProductLayout.cshtml, .prod-BAK (<main>). Two compounding
   causes kept the hexagon background from reaching the screen edges on
   mobile (≤576px):

   1. background-size (style.css, .prod-BAK mobile media query) switches
      from `cover` to `auto` below 576px — auto renders
      HexagonBackground-MOB.webp at native pixel size instead of scaling to
      fill the element, so unless the image's native size happens to match
      the viewport exactly, uncovered space is left. Restored to `cover`
      here so it scales to fill regardless of viewport width.

   2. .prod-BAK doesn't reach the viewport edges at mobile: it sits inside
      .container-fluid (px-4, resets to px-md-0 at ≥768px) — content-wrap's
      own px-4/px-lg-0 was removed at the source (changed to px-0 directly
      in _ProductLayout.cshtml), so .container-fluid's px-4 is now the only
      remaining inset, ~24px (1.5rem) per side below the md breakpoint. A
      correctly-scaled background still can't look full-bleed inside a
      padded box. Same breakout technique as the homepage hero slider
      (100vw + negative margins, see .hero-slider-viewport above): pulls
      the element to the true viewport edges regardless of the remaining
      ancestor padding. Scoped to .product-layout (body class,
      _ProductLayout.cshtml) so the homepage/public pages, which don't
      share this structure, are untouched. --scrollbar-width isn't
      available on product pages (the measurement script is homepage-only
      — see hero slider comment), so this uses 100vw directly; on mobile
      the vertical scrollbar is typically zero-width/overlay, so the
      sub-pixel sliver 100vw can introduce next to a desktop scrollbar
      isn't a practical concern at this breakpoint. ─────────────────────── */
@media (max-width: 576px) {
    .product-layout .prod-BAK {
        background-size: cover !important;
        width: 100vw;
        margin-left: calc(50% - 50vw);
        margin-right: calc(50% - 50vw);
        padding-left: 1.5rem;
        padding-right: 1.5rem;
        box-sizing: border-box;
    }
}
   _ProductLayout.cshtml sets data-menu-breakpoint="1320" (same value as
   _PublicLayout.cshtml, which switches correctly at 1320). On product pages
   only, Canvas's own JS (functions.js: Core.viewport().width, i.e.
   window.innerWidth) reads consistently ~26px short of the true window
   width at this breakpoint, so the body loses `is-expanded-menu` (and the
   header swaps to the hamburger trigger) at 1294px instead of 1320px.
   window.innerWidth includes the scrollbar gutter, and product pages are
   the only pages with a sticky, height-reflowing sidebar column — evidently
   enough to produce a stable, page-specific offset here that the homepage
   doesn't exhibit. This isn't resize "jitter": the boundary is a fixed,
   repeatable pixel value (confirmed 1294 = burger, 1295 = desktop nav).

   Rather than patch vendor JS (functions.js) or duplicate the homepage's
   --scrollbar-width measurement script onto the product layout, this closes
   the gap in CSS: for the 1295–1319px band specifically, force the same
   visual state Canvas would apply if is-expanded-menu were correctly set —
   show the desktop menu container, hide the mobile trigger — scoped to
   .product-layout only so public/homepage pages (which already switch
   correctly at 1320) are untouched. If the underlying ~26px offset ever
   changes (different scrollbar width, DPI/zoom, browser), this band may
   need re-measuring. ─────────────────────────────────────────────────── */
@media (min-width: 1295px) and (max-width: 1319px) {
    .product-layout .menu-container:not(.mobile-primary-menu) {
        display: flex !important;
        flex-wrap: wrap;
        align-items: center;
    }
    .product-layout .primary-menu-trigger,
    .product-layout #page-menu-trigger {
        display: none !important;
        opacity: 0;
        pointer-events: none;
    }
}

/* ── Bootstrap modal z-index safety net ────────────────────────────────────
   ROOT CAUSE (found): .prod-BAK (the product page <main> wrapper, in
   style.css) sets background-attachment: fixed + z-index: 1, which creates
   its own stacking context. Any modal markup nested inside it — like the
   trolley schematic/configurator modals were — gets trapped inside that
   context, so .modal-backdrop (appended to <body>, outside the trap) paints
   over the modal regardless of the modal's own z-index. FIXED at the source
   by moving modal markup out of <main>/.prod-BAK entirely, into a "Modals"
   Razor section rendered at <body> level in _ProductLayout.cshtml — see
   Pages/Trolleys/Detail.cshtml and Pages/Shared/_ProductLayout.cshtml.
   This rule is kept only as a defensive safety net in case a future modal
   is accidentally placed back inside a stacking-context ancestor. ───────── */
.modal {
    z-index: 1056 !important;
}

/* ── Search icon button ────────────────────────────────────────────────── */
.header-search-btn {
    background: transparent;
    border: none;
    cursor: pointer;
    color: rgb(148, 28, 74);
    font-size: 1.2rem;
    padding: 0 0.5rem;
    vertical-align: middle;
    line-height: 1;
}
.header-search-btn:hover {
    opacity: 0.75;
}

/* ── Search overlay ────────────────────────────────────────────────────── */
.search-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(87, 4, 48, 0.82);
    z-index: 2000;
    align-items: center;
    justify-content: center;
}
.search-overlay.is-open {
    display: flex;
}
.search-overlay-inner {
    position: relative;
    width: 100%;
    max-width: 680px;
    padding: 0 1.5rem;
}
.search-overlay-form {
    display: flex;
    align-items: center;
    border-bottom: 2px solid #ffffff;
    padding-bottom: 0.5rem;
}
.search-overlay-input {
    flex: 1;
    background: transparent;
    border: none;
    outline: none;
    color: #ffffff;
    font-size: 1.8rem;
    padding: 0.25rem 0.5rem 0.25rem 0;
}
.search-overlay-input::placeholder {
    color: rgba(255, 255, 255, 0.5);
}
.search-overlay-submit {
    background: transparent;
    border: none;
    color: #ffffff;
    font-size: 1.6rem;
    cursor: pointer;
    padding: 0 0.25rem;
    line-height: 1;
}
.search-overlay-submit:hover {
    opacity: 0.75;
}
.search-overlay-close {
    position: absolute;
    top: -3rem;
    right: 1.5rem;
    background: transparent;
    border: none;
    color: #ffffff;
    font-size: 1.8rem;
    cursor: pointer;
    line-height: 1;
}
.search-overlay-close:hover {
    opacity: 0.75;
}

/* ── Colour swatch hexagon sizing fix ───────────────────────────────────────
   .dot (style.css) is fixed at 50x50px with a hexagon clip-path. As a flex
   child of .d-flex.flex-wrap (_ColourSwatches.cshtml), it's shrinkable by
   default — when several swatches share a wrapping row, flexbox can compress
   .dot's width below 50px while height stays fixed, distorting the hexagon
   clip-path out of shape. flex-shrink: 0 pins it to its declared 50x50px
   regardless of how many swatches share the row.
   Applies sitewide to every colour swatch row (trolleys and baskets). ────── */
.dot {
    flex-shrink: 0;
    flex-basis: 50px;
}

/* ── Colour swatch group layout ─────────────────────────────────────────────
   Each swatch group (label / hexagon row / hint text) always stacks, at
   every breakpoint, for consistency between mobile and desktop. ─────────── */
.swatch-group:last-child {
    margin-bottom: 0 !important;
}
.swatch-hint {
    font-size: 0.95rem;
    color: var(--cnvs-contrast-600, #666);
}

/* ── Available Options grid ──────────────────────────────────────────────
   .option-title is absolutely positioned above .option-image at
   top: -35px, so margin-top reserves that space instead of letting the
   banner overlap the row above. width is relative (not a fixed 126px) so
   longer labels like "Advertising Holder" scale with the card instead of
   overflowing into the neighbouring column. See Trolleys/Detail.cshtml
   "Available Options" grid. ──────────────────────────────────────────── */
.option-image {
    position: relative;
    display: inline-block;
    width: 100%;
    margin-top: 40px;
}
.option-image img {
    display: block;
    width: 100%;
    height: auto;
    border: 1px solid rgb(239 239 239);
}
.option-title {
    position: absolute;
    top: -35px;
    left: 0;
    box-sizing: border-box;
    display: block;
    white-space: nowrap;
    padding: 8px 6px;
    /*background: #941c4a; FB Burgundy*/
    background: #696d6e; /*FB Dark Grey*/ 
    color: #fff;
    width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    text-align: center;
    border-radius: 4px 4px 0 0;
    font-size: 14px;
    font-weight: 500;
}

.FooterButton {
	background: #f08300;
	background-color:#f08300;
	border-radius:35px;
	display:inline-block;
	cursor:pointer;
	color:#FFFFFF !important;
	font-size:16px;
    font-weight: 600;
	padding:14px 45px;
	text-decoration:none;
    border: 2px #f08300 solid;
}

.SubscribeButton {
	background: #f08300;
	background-color:#f08300;
	border-radius:35px;
	display:inline-block;
	cursor:pointer;
	color:#FFFFFF !important;
	font-size:23px;
    font-weight: 600;
	padding:14px 45px;
	text-decoration:none;
    border: 2px #f08300 solid;
}
.SubscribeButton:hover, .FooterButton:hover {
	background-color:#FFFFFF;
    color:#f08300 !important;
    border: 2px #f08300 solid;
}
.SubscribeButton:active, .FooterButton:active {
	position:relative;
	top:1px;
}



.roundedbox {
    width: 90px;
    height: 90px;
    border-radius: 50%;
    border: none !important;
    background: #FFFFFF;
    display: block;
    margin: 0 auto;
}
.roundedbox2 {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: #FFFFFF;
    display: block;
    margin: 0 auto;
}

.roundedboxGRN
{
    width: 90px;
    height: 90px;
    border-radius: 50%;
    border: 6px;
    background: #50a39c;
    display: block;
    margin: 0 auto;
    
  filter: drop-shadow(2px 0px 0px #50a39c)    /* Right */
          drop-shadow(-2px 0px 0px #50a39c)   /* Left */
          drop-shadow(0px 2px 0px #50a39c)    /* Bottom */
          drop-shadow(0px -2px 0px #50a39c);  /* Top */
}

/* ── Homepage "Explore our Retail Solutions" category grid ──────────────
   Pages/Index.cshtml. Bootstrap grid (row-cols-2 / row-cols-md-3) handles
   the responsive column count; these rules style the tile itself.
   FB Burgundy (#941c4a) is the resting state for every tile, FB Orange
   (#f08300) is the shared hover state — confirmed by Anton, this is not a
   permanently "active" first tile. Real Prod-Menu-*.webp images (see
   Pages/Index.cshtml) replaced the earlier Bootstrap Icon placeholders. ─── */
.home-cat-heading {
    color: #941c4a;
    font-weight: 700;
    text-align: center;
    margin-bottom: 2rem;
}
.home-cat-tile {
    display: flex;
    flex-direction: column;
    background-color: #941c4a;
    text-decoration: none;
    height: 100%;
    padding: 20px 20px 0 20px;
    transition: background-color 0.2s ease;
}
.home-cat-tile:hover,
.home-cat-tile:focus {
    background-color: #f08300;
    text-decoration: none;
}
.home-cat-image {
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: #ffffff;
    aspect-ratio: 1.40 / 1;
    overflow: hidden;
}
.home-cat-image img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}
.home-cat-label {
    display: block;
    color: #ffffff;
    font-weight: 700;
    text-transform: uppercase;
    font-size: 1.65rem;
    line-height: 1.3;
    padding: 14px 4px 18px;
}

/* ── Homepage "Supporting Better Retail Journeys" intro section ─────────
   Pages/Index.cshtml, directly under the category grid. CONTACT US reuses
   the existing .SubscribeButton pill (already orange/FB brand) rather than
   introducing a second button style. It scroll-links to #quick-contact,
   an id added to the footer's quick-contact-widget (Pages/Shared/
   _Footer.cshtml) — there is no standalone /contact-us page yet. Smooth
   scrolling is already global via style.css's prefers-reduced-motion-aware
   `scroll-behavior: smooth`, so no extra JS is needed here. ────────────── */
.home-intro {
    margin-top: 3rem;
    text-align: center;
}
.home-intro-inner {
    margin: 0 auto;
}
.home-intro-heading {
    color: #941c4a;
    font-weight: 700;
    margin-bottom: 1rem;
}
.home-intro-subhead {
    font-weight: 700;
    color: #1a1a1a;
    max-width: 940px;
    margin: 0 auto 1.5rem;
    font-size: 1.55rem;
    line-height: 1.2 !important;
}
.home-intro-inner p:not(.home-intro-subhead) {
    text-align: left;
    color: #000000;
    margin-bottom: 1rem;
}
.home-intro-cta {
    margin-top: 1.5rem;
}

/* ── Homepage testimonials carousel ──────────────────────────────────────
   Pages/Index.cshtml, below the intro section. Card background is a light
   tint of FB Burgundy (rgba, not a hardcoded hex) so it stays tied to the
   brand colour if that ever changes. Quote glyphs reuse the bi-quote
   Bootstrap Icon already loaded sitewide (bi-quote-close doesn't exist in
   this icon set, so the closing mark is bi-quote mirrored via CSS). ────── */
.home-testimonials {
    margin-top: 3rem;
}
.home-testimonials-carousel {
    display: flex;
    align-items: center;
    gap: 1rem;
}
.home-testimonials-card {
    position: relative;
    flex: 1;
    background-color: rgba(148, 28, 74, 0.08);
    padding: 3rem 3.5rem;
    overflow: hidden;
}
.home-testimonials-quote {
    position: absolute;
    font-size: 3.5rem;
    color: rgba(148, 28, 74, 0.35);
    line-height: 1;
}
.home-testimonials-quote-open {
    top: 1.25rem;
    left: 1.5rem;
}
.home-testimonials-quote-close {
    bottom: 1.25rem;
    right: 1.5rem;
    transform: scaleX(-1) scaleY(-1);
}
.home-testimonials-heading {
    position: relative;
    color: #941c4a;
    font-weight: 700;
    text-align: center;
    margin-bottom: 1.5rem;
}
.home-testimonials-slide {
    display: none;
    text-align: center;
    color: #000000;
}
.home-testimonials-slide.is-active {
    display: block;
}
.home-testimonials-slide p {
    margin-bottom: 1rem;
    max-width: 760px;
    margin-left: auto;
    margin-right: auto;
}
.home-testimonials-attribution {
    color: #941c4a;
    font-weight: 700;
    text-transform: uppercase;
    font-size: 0.95rem;
    margin-bottom: 0 !important;
}
.home-testimonials-arrow {
    flex-shrink: 0;
    background: transparent;
    border: 0px;
    color: #941c4a;
    font-size: 3rem;
    line-height: 1;
    cursor: pointer;
    padding: 0.5rem;
}
.home-testimonials-arrow:hover,
.home-testimonials-arrow:focus {
    color: #f08300;
}
@media (max-width: 767.98px) {
    .home-testimonials-card {
        padding: 2.5rem 1.25rem;
    }
    .home-testimonials-quote {
        font-size: 2.25rem;
    }
    .home-testimonials-arrow {
    flex-shrink: 0;
    background: transparent;
    border: 0px;
    color: #941c4a;
    font-size: 1rem;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
    padding: 0.5rem;
}
    
}
/* ── TABLET FIX */
@media (max-width: 770px) {
    .home-cat-label {
    font-size: 1.25rem;
}
}

/* ── Homepage "Why Formbar" feature grid ─────────────────────────────────
   Pages/Index.cshtml, final homepage section. Card title gradients are
   built from colours already established elsewhere in this file (FB
   Burgundy #941c4a, FB Orange #f08300, the existing green/teal #50a39c
   from .roundedboxGRN, and the near-black #1a1a1a from .home-intro-subhead)
   rather than new hex values, so the whole page shares one palette. ──── */
.why-formbar {
    margin-top: 3rem;
}
.why-fb-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    background-color: #ffffff;
    border: 1px solid #e2e2e2;
}
.why-fb-title {
    color: #ffffff;
    font-weight: 800;
    text-transform: uppercase;
    text-align: center;
    line-height: 1.3;
    font-size: 1.25rem;
    padding: 1.5rem 0.75rem;
}
.why-fb-title--1 {
    background: linear-gradient(90deg, #1a1a1a, #941c4a);
}
.why-fb-title--2 {
    background: linear-gradient(90deg, #941c4a, #359954);
}
.why-fb-title--3 {
    background: linear-gradient(90deg, #359954, #f08300, #359954);
}
.why-fb-title--4 {
    background: linear-gradient(90deg, #359954, #941c4a);
}
.why-fb-title--5 {
    background: linear-gradient(90deg, #941c4a, #1a1a1a);
}
.why-fb-body {
    flex: 1;
    text-align: center;
    color: #000000;
    padding: 0rem .4rem 1rem;
}
.why-fb-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 219px;
    margin-bottom: 0rem;
}
.why-fb-icon img {
    max-width: 246px;
    max-height: 219px;
    object-fit: contain;
}

/* ── TABLET FIX */
@media (max-width: 1024px) {
.why-fb-icon img {
    max-width: 200px;
    max-height: 170px;
    object-fit: contain;
}
}


.why-fb-body p {
    font-size: 1rem;
        line-height: 1.2;
    margin-bottom: 1rem;
}
.why-fb-body p:last-child {
    margin-bottom: 0;
}

/* ── Homepage hero slider ─────────────────────────────────────────────────
   Pages/Index.cshtml, first element on the page. Three deliberate CSS
   tricks:

   1. Touches the header with no gap: .content-wrap (style.css) applies
      padding: var(--cnvs-content-padding) 0 (3rem) around @RenderBody().
      The theme's own .header-stick utility negates --cnvs-margin-lg (5rem)
      instead, which doesn't match --cnvs-content-padding and would over-
      shoot into the header. margin-top here negates the exact variable
      .content-wrap actually uses, so the gap closes precisely to zero.

   2. Full-bleed width: .container (Bootstrap, inside .content-wrap) is
      centred and padded, so a full-viewport-width banner can't just be
      dropped in as normal body content. The negative side margins + 100vw
      "breakout" pull it out to the viewport edges regardless of where it
      sits in the DOM. .content-wrap already has overflow: hidden
      (style.css), which safely clips the sub-pixel sliver 100vw can
      produce next to a scrollbar — but clipping the sliver isn't enough
      on its own; see point 3.

   3. Scrollbar-width compensation: 100vw includes the vertical scrollbar's
      width, unlike %-based layout. That made .hero-slider-viewport a few
      pixels wider than the true visible viewport — invisible (clipped by
      point 2's overflow: hidden), but it meant anything centred inside
      the box, like .hero-text--center, was centring against a box that
      was wider than what's actually on screen, so it landed slightly left
      of true-center. --scrollbar-width is measured in JS as early as
      possible (see _PublicLayout.cshtml, right after <body> opens) and
      defaults to 0px in CSS so nothing breaks before that script runs or
      on platforms with zero-width/overlay scrollbars (Mac, mobile).

   Every slide currently points at the same placeholder banner image — see
   the comment in Index.cshtml. Arrow/dot colours were read off that
   supplied banner: white arrows, dark-burgundy active dot, dusty-pink
   inactive dots. ─────────────────────────────────────────────────────── */
.hero-slider {
    margin-top: calc(-1 * var(--cnvs-content-padding));
}
.hero-slider-viewport {
    position: relative;
    width: calc(100vw - var(--scrollbar-width, 0px));
    margin-left: calc(50% - 50vw + (var(--scrollbar-width, 0px) / 2));
    margin-right: calc(50% - 50vw + (var(--scrollbar-width, 0px) / 2));
    overflow: hidden;
}
.hero-slide {
    display: none;
}
.hero-slide.is-active {
    display: block;
}
.hero-slide img {
    display: block;
    width: 100%;
    height: auto;
}
.hero-slider-arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    background: transparent;
    border: 0;
    color: #ffffff;
    font-weight: 800;
    line-height: 1;
    cursor: pointer;
    padding: 0.5rem 1rem;
    z-index: 2;
        /* font-weight has no effect on icon-font glyphs (bi-chevron-left/
       -right) — Bootstrap Icons only ships one weight per glyph, so
       there's no bold cut for the browser to substitute. -webkit-text-
       stroke draws a stroke centered on the glyph outline instead, which
       actually thickens it. Despite the prefix this has been supported in
       every major browser since ~2016; the unprefixed text-stroke still
       hasn't shipped anywhere, so the prefixed form is the correct one to
       ship, not a legacy fallback. Tune the width to taste — much above
       ~3px on a glyph this simple (open V-shape) starts looking chunky
       rather than just bolder. */
    -webkit-text-stroke: 2px currentColor;
}
.hero-slider-arrow:hover,
.hero-slider-arrow:focus {
    opacity: 0.75;
}
.hero-slider-arrow-prev {
    left: 0.5rem;
}
.hero-slider-arrow-next {
    right: 0.5rem;
}
.hero-slider-dots {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    padding: 1.25rem 0;
}
.hero-slider-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    border: 0;
    padding: 0;
    background-color: rgba(128, 128, 128, 0.5); /* dusty pink, inactive */
    cursor: pointer;
    transition: background-color 0.2s ease, transform 0.2s ease;
}
.hero-slider-dot.is-active {
    background-color: #941c4a; /* FB Burgundy, active */
    transform: scale(1.3);
}

/* ── Hero slider live text overlay ────────────────────────────────────────
   Pages/Index.cshtml. Three independently composable modifier axes rather
   than fixed named templates — hero-text--{left|center|right} for
   alignment, hero-text--{sm|md|lg} for size, optional hero-text--scrim
   for a gradient legibility panel — so new combinations never need new
   CSS. Bounding box is padding: 7% 14% on a container covering the full
   slide, content vertically centred within it. text-shadow is always on
   as the lightweight legibility fallback even without --scrim.
   pointer-events: none keeps the whole slide clickable through the
   overlay (the <a> is the slide itself). ─────────────────────────────── */
.hero-text {
    position: absolute;
    inset: 0;
    z-index: 2;
    padding: 7% 7%;
    display: flex;
    align-items: center;
    color: #ffffff;
    text-shadow: 0 2px 10px rgba(0, 0, 0, 0.2), 0 1px 3px rgba(0, 0, 0, 0.1);
    pointer-events: none;
}
.hero-text-inner {
    max-width: 100%;
    font-weight: 700;
    line-height: 1.25;
    /* Per-slide vertical nudge within the text block, set inline as
       --text-offset-y (see Index.cshtml TextOffsetY). margin-top rather
       than a transform: translateY() specifically because .text-condensed
       already uses transform: scaleX() — a second transform declaration
       here would silently replace, not combine with, that one. margin-top
       is a fully independent property, so it composes safely with
       text-condensed (or anything else applied to this element later)
       regardless of which classes are also present. Positive values push
       the text down, negative values pull it up, within the fixed 7%/14%
       padded box — the box itself and any --scrim panel don't move,
       only the text glyphs do. */
    margin-top: var(--text-offset-y, 0px);
}
/* TextOffsetY is a fixed px/rem value, tuned by eye against the desktop
   banner height. Mobile images are proportionally much shorter (same
   aspect ratio, narrower width), so the same offset that reads as a small
   nudge on desktop can push the text out of the padded box and into the
   area .hero-slider-viewport's overflow: hidden clips away — it looks
   like the text vanishes, but it's actually just been pushed off-canvas.
   Resetting to 0 here overrides that per-slide offset below 768px so text
   always stays vertically centered on mobile, regardless of what
   TextOffsetY is set to for that slide at tablet/desktop. */
@media (max-width: 767.98px) {
    .hero-text-inner {
        margin-top: 0;
    }
}
.hero-text--left {
    justify-content: flex-start;
    text-align: left;
}
.hero-text--center {
    justify-content: center;
    text-align: center;
}
.hero-text--right {
    justify-content: flex-end;
    text-align: right;
}

/* Size tiers — mobile default, then tablet (md) / desktop (xl), matching
   the same breakpoints used by the <picture> art-direction above. */
.hero-text--sm .hero-text-inner {
    font-size: 1.1rem;
}
.hero-text--md .hero-text-inner {
    font-size: 1.5rem;
}
.hero-text--lg .hero-text-inner {
    font-size: 2rem;
}
.hero-slider-arrow {
    font-size: 2rem;
}
@media (min-width: 768px) {
    .hero-text--sm .hero-text-inner {
        font-size: 1.4rem;
    }
    .hero-text--md .hero-text-inner {
        font-size: 2.25rem;
    }
    .hero-text--lg .hero-text-inner {
        font-size: 3rem;
    }
    .hero-slider-arrow {
    font-size: 3rem;
}
}
@media (min-width: 1200px) {
    .hero-text--sm .hero-text-inner {
        font-size: 1.75rem;
    }
    .hero-text--md .hero-text-inner {
        font-size: 3.75rem;
    }
    .hero-text--lg .hero-text-inner {
        font-size: 5.75rem;
    }
    .hero-slider-arrow {
    font-size: 4.5rem;
}
}

/* Optional scrim: gradient anchored to the same edge the text is aligned
   to, so it reads as a natural falloff rather than a hard-edged box. This
   covers exactly the padded bounding box (not beyond it) — a reasonable
   first pass, worth revisiting once real photos (rather than the current
   placeholders) are in place, since the ideal falloff distance depends on
   the actual image content. */
.hero-text--scrim::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
}
.hero-text--scrim.hero-text--left::before {
    background: linear-gradient(90deg, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0.55) 55%, rgba(0, 0, 0, 0) 100%);
}
.hero-text--scrim.hero-text--right::before {
    background: linear-gradient(270deg, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0.55) 55%, rgba(0, 0, 0, 0) 100%);
}
.hero-text--scrim.hero-text--center::before {
    background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.3) 55%, rgba(0, 0, 0, 0) 100%);
}
