/* Hero eyebrow — small caps positioning for the contextual line above the
   rotator. Uses the brand indigo so it ties to the AppBar/CTA family.
   `width: fit-content` + `margin: 0 auto` keeps the pill centred regardless
   of the parent container's text-align. */
.hero-eyebrow {
    display: block;
    width: fit-content;
    max-width: 100%;
    margin: 0 auto 30px;
    color: #3B3F7A;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    text-align: center;
    padding: 8px 16px;
    border-radius: 999px;
    background: rgba(59, 63, 122, 0.08);
}

/* Risk-section paragraphs — left-aligned, capped line length and dialled-down
   body size so two long paragraphs don't read as a wall of text. */
.risk-paragraph {
    text-align: justify;
    text-justify: inter-word;
    font-size: 1.25rem;
    line-height: 1.65;
    max-width: 64ch;
    hyphens: auto;
}

.risk-lead {
    color: #3B3F7A;
    font-weight: 700;
}

/* Stat strip — four quick stats above the 'see how GP Clarity can help' line.
   Four equal cells that span the same column width as the heading and
   logo+text rows above, so the section reads as one aligned grid.
   Numbers are read live from PsrCaseOutcomes so the values always match
   the /psr-case-insights detail page. */
.stat-strip {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 16px;
    margin: 88px 0 8px;
    width: 100%;
}

.stat-strip__item {
    padding: 18px 20px;
    background: rgba(59, 63, 122, 0.05);
    border: 1px solid rgba(59, 63, 122, 0.12);
    border-radius: 10px;
    text-align: center;
}

@media (max-width: 960px) {
    .stat-strip {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 600px) {
    .stat-strip {
        grid-template-columns: 1fr;
    }
}

.stat-strip__number {
    display: block;
    color: #3B3F7A;
    font-size: 1.6rem;
    font-weight: 700;
    line-height: 1.1;
    margin-bottom: 4px;
}

.stat-strip__label {
    display: block;
    color: #4A4E6A;
    font-size: 0.82rem;
    line-height: 1.35;
}

/* Section 4 — vertical Module tiles. Each tile is a single MudPaper that
   stacks: gradient header (module name + tagline) -> white description body
   -> price block -> add-link footer. Replaces the previous 4x3 grid. */
.module-tile {
    display: flex;
    flex-direction: column;
    /* Each tile lives inside a MudItem with Class="d-flex". Without an
       explicit width:100% the .module-tile is just a flex item with the
       default `flex: 0 1 auto`, so it can sit slightly narrower than
       the grid column. width:100% pins the tile to the column edge so
       all four right rails render at the same exact pixel column. */
    width: 100%;
    height: 100%;
    background: #ffffff;
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 4px 14px rgba(15, 22, 50, 0.06);
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}

/* The site loads a global `html, body *` rule that sets
   `scrollbar-width: thin` + `scrollbar-color: ... transparent` on
   every element. On the .module-tile chain that combines badly with
   .module-tile's `overflow: hidden` — Chromium reserves a thin
   inline-end gutter even though no scrollbar is ever drawn, and the
   right rail of .module-tile__body-back ends up painted underneath
   that reserved gutter (i.e. invisible). The inner cards in the row
   appear unaffected only because their reserved gutter sits opposite
   the next card's reserved gutter across the MudGrid column gap, so
   the visible asymmetry only shows on the first / last cards.
   We restore the spec default (`auto` for both) on every element that
   participates in the tile's layout, with !important so it wins
   regardless of stylesheet order or specificity. Scoped to .module-tile
   so the rest of the app keeps the global thin scrollbar styling. */
.module-tile,
.module-tile * {
    scrollbar-width: auto !important;
    scrollbar-color: auto !important;
}

.module-tile:hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 22px rgba(15, 22, 50, 0.10);
}

.module-tile__header {
    padding: 18px 18px 16px;
    color: #ffffff;
    text-align: center;
}

.module-tile__title {
    font-weight: 600;
    font-size: 1.375rem;
    line-height: 1.2;
    margin-bottom: 4px;
}

/* `min-height: 2.7em` (≈ 2 line-heights at line-height: 1.35) reserves
   space for a two-line tagline on every card even if the actual tagline
   only takes one line. Without this the four headers render at slightly
   different heights — Clarity Enhance's "Quality-checked consult
   evidence" wraps to one line on most viewports while the other three
   wrap to two — and the price blocks underneath sit at four different
   y-positions across the row. The reserved 2-line slot keeps every
   header the same vertical footprint so the price blocks (and any
   subsequent footer slots) line up across the strip. */
.module-tile__tagline {
    font-size: 0.9rem;
    opacity: 0.95;
    line-height: 1.35;
    min-height: 2.7em;
}

/* Body section is now a 3D-flip shell. The front face stays in normal
   flow so it gives body-inner its natural height (long descriptions
   make tall cards; short descriptions make short cards); the back face
   overlays the front absolutely so it always matches the front's box
   exactly, regardless of content length or viewport width. overflow:hidden
   on the body clips any in-flight render artefacts during the rotation. */
.module-tile__body {
    perspective: 1200px;
    cursor: pointer;
    outline: none;
    flex: 1 1 auto;
    position: relative;
    overflow: hidden;
    /* Side rails live on this OUTER container — not on the back face.
       The back face is absolutely positioned with `inset: 0` inside
       .module-tile__body, and the global `html, body *` rule that sets
       `scrollbar-width: thin` causes Chromium to reserve a thin
       inline-end gutter on the body even though no scrollbar ever
       renders. That gutter pushes the back face's contents inward and
       hid the right-most rail on the row's outer cards (cards 2 and 3
       got visual cover from their neighbour's left rail across the
       MudGrid gap, masking the same problem there). Painting the rails
       on .module-tile__body's own box puts them at the body's true
       outer left/right edges, where no scrollbar gutter can move them.
       box-sizing: border-box keeps the rails inside the column width.
       No border-radius — see note in .module-tile about why this inner
       body stays square while the outer card keeps its 10px radius. */
    box-sizing: border-box;
    border-left: 1px solid #d8dbe4;
    border-right: 1px solid #d8dbe4;
    /* Ensure the body is tall enough that the back face's
       justify-content: center has a comfortable gutter above and below
       the kicker + marker list block on every card. The prose body face
       still drives natural height if the description is taller than
       this minimum, so longer descriptions are not clipped — this
       only kicks in when the description happens to be short. */
    min-height: 240px;
}

/* Default state shows the BACK face (the markers list with ticks) so a
   visitor immediately sees what each module covers. Hover / keyboard
   focus rotates back to 0deg, exposing the FRONT face (prose body).
   The front face still owns the natural height because it stays in
   normal flow, so card heights across the row stay consistent with
   the longer descriptive copy and don't snap shorter when ticks are
   the visible default. */
.module-tile__body-inner {
    position: relative;
    transform-style: preserve-3d;
    transition: transform 0.6s cubic-bezier(0.22, 0.61, 0.36, 1);
    height: 100%;
    transform: rotateY(180deg);
    /* Vertical-centre the FRONT face (prose description). The front
       face is a normal-flow block whose height equals its text, so by
       itself it sits at the top of body-inner with empty space below.
       Putting body-inner into grid + align-content:center centres the
       single normal-flow row (the front face) inside body-inner's full
       100% height. The back face is position:absolute so it is removed
       from grid flow and continues to centre its own content via its
       own align-content:center — both faces are now centred. */
    display: grid;
    align-content: center;
}

@media (hover: hover) {
    .module-tile__body:hover .module-tile__body-inner,
    .module-tile__body:focus-visible .module-tile__body-inner {
        transform: rotateY(0deg);
    }
}

.module-tile__body:focus-visible {
    box-shadow: 0 0 0 3px rgba(59, 63, 122, 0.35);
}

.module-tile__body-face {
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
    padding: 9px 20px;
}

/* Front face in normal flow drives body-inner's natural height. */
.module-tile__body-front {
    color: #333;
    font-size: 0.82rem;
    line-height: 1.65;
    text-align: justify;
    text-justify: inter-word;
    hyphens: auto;
}

/* Back face overlays the front exactly, matching its box for a clean
   3D flip without size mismatch on either face. justify-content: center
   pushes the kicker + marker list as a vertical block to the middle of
   the card body so cards with short marker lists don't look top-heavy.
   Thin neutral border + soft inner shadow give the marker-list face a
   subtle "card" outline so it reads as a distinct surface from the
   gradient header above and the price block below. */
.module-tile__body-back {
    position: absolute;
    inset: 0;
    transform: rotateY(180deg);
    background: rgba(15, 22, 50, 0.03);
    /* Grid with `align-content: center` reliably vertical-centres the
       kicker + marker-list block as a whole inside the back face.
       Flexbox + justify-content:center was being short-circuited here
       because the back face is absolutely positioned (inset:0) and
       flex was using the content's natural height instead of the
       inset:0 height for the centring math, leaving the block top-
       aligned. Grid uses the explicit box size every time. The default
       grid auto-flow puts kicker on row 1 and the <ul> on row 2; the
       gap controls the visual paragraph break between them; justify
       defaults to stretch so the marker list still fills the width. */
    display: grid;
    align-content: center;
    gap: 20px;
    /* No borders here any more — the side rails live on the parent
       .module-tile__body so they survive the global scrollbar-width
       gutter quirk. See the note in .module-tile__body for the full
       story. The back face still owns just the tinted background that
       distinguishes the marker-list face from the prose body face. */
    border-radius: 0;
}

.module-tile__back-kicker {
    font-weight: 600;
    color: #2A2E55;
    font-size: 0.85rem;
    line-height: 1.35;
    text-align: center;
    /* No margin here — the parent's grid `gap: 20px` is the only
       spacing between the kicker and the marker list, so the
       align-content: center math stays symmetrical and the block
       reads as a true vertical centre on the back face. */
}

.module-tile__marker-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.module-tile__marker-list li {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    color: #2A2E55;
    font-size: 0.85rem;
    line-height: 1.35;
}

.module-tile__tick {
    color: var(--tick-color, #3B3F7A) !important;
    font-size: 1.05rem !important;
    flex: 0 0 auto;
    margin-top: 1px;
}

/* Touch / no-hover fallback — drop the 3D flip and stack the front
   description above the marker list so readers without hover capability
   still see both bits of content. */
@media (hover: none) {
    .module-tile__body {
        cursor: default;
        perspective: none;
        overflow: visible;
    }
    .module-tile__body-inner {
        transform: none !important;
        transform-style: flat;
        transition: none;
        height: auto;
        /* On touch, both faces are stacked block-style; restore plain
           block layout instead of the desktop grid centring (which
           would treat both faces as grid rows and centre them as a
           pair, leaving odd whitespace above/below the stack). */
        display: block;
    }
    .module-tile__body-face {
        backface-visibility: visible;
        padding: 9px 20px;
    }
    .module-tile__body-back {
        position: relative;
        inset: auto;
        background: transparent;
        padding-top: 12px;
        transform: none;
        /* Drop the bordered card look on touch — both faces are stacked
           visible here, so the marker list reads as a continuation of
           the description above rather than a separate card. */
        border: none;
    }
}

/* min-height pegs the price block to its annual worst case (4 lines:
   headline + per-month equivalence caption + module label + savings).
   Inc/Ex GST is now toggle-driven from the controls row, so we no
   longer render two prices simultaneously and the block is one line
   shorter than the original spike. Sized from the longest numeric
   permutation (Foundations Personal Annual in Inc GST mode) so cards
   do not bounce vertically when the user toggles either Monthly <->
   Annual or Inc GST <-> Ex GST. Monthly cards have 3 lines (headline
   + label + savings slot reserves min-height) and centre inside the
   same 95px box. */
.module-tile__price-block {
    padding: 10px 18px 6px;
    text-align: center;
    border-top: 1px solid rgba(15, 22, 50, 0.06);
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-height: 95px;
}

.module-tile__price {
    font-weight: 700;
    font-size: 1.2rem;
    line-height: 1.1;
}

/* Per-month equivalence caption shown only on annual cards. Strict ACL
   only requires the annual figure to be at least as prominent as the
   per-month figure when there is an annual commitment; we satisfy that
   today by omission (the headline IS per-year). This caption is more
   transparent than required and intentionally muted so it does not
   challenge the headline's prominence. Same toggle-driven basis as
   the headline (Inc/Ex GST). */
.module-tile__price-permonth {
    margin-top: 4px;
    font-size: 0.75rem;
    line-height: 1.2;
    opacity: 0.8;
}

.module-tile__price-label {
    display: block;
    margin-top: 6px;
    font-size: 0.7rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    opacity: 0.85;
}

.module-tile__savings-slot {
    min-height: 16px;
    margin-top: 2px;
    text-align: center;
    font-size: 0.7rem;
    font-style: italic;
    opacity: 0.85;
}


/* Section-heading row holds the section H4 plus the Monthly/Annual
   pricing cadence toggle on the same line. The heading stays centered
   in normal flow; the toggle is absolute-positioned to the right so it
   doesn't push the heading off-axis. */
.section-heading-row {
    position: relative;
}

/* Wrapper holding the two pill toggles (Personal/Practice + Monthly/Annual)
   that sit below the price cards. Width is locked to the same 760px the
   five-chip bracket row uses, and each pill stretches via flex:1 to fill
   half of that span. Result: the two top pills + the five bottom chips
   form a single rectangular footprint, which keeps the eye anchored on
   one block of controls. flex-wrap lets the row collapse on very narrow
   viewports. */
.section-heading-toggles {
    display: flex;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
    gap: 16px;
    margin: 0 auto 24px;
    width: 760px;
    max-width: 100%;
}

.section-heading-toggles .micro-pricing-toggle {
    flex: 1 1 0;
}

.section-heading-toggles .micro-pricing-toggle__btn {
    flex: 1 1 0;
    min-width: 0;
}

/* Practice user-count brackets — sits below the two pill toggles. The row
   is ALWAYS rendered (so the layout doesn't jump when toggling between
   Personal and Practice); when Personal is active the chips are hidden
   via visibility:hidden, which keeps their layout footprint intact.
   Reuses the .micro-pricing-toggle__btn geometry so chip widths match
   the pills above, but laid out as a single un-grouped row (no enclosing
   pill shell) so the chips read as a half-step "below" the toggles. Each
   chip stretches via flex:1 to take an equal share of the 760px row, so
   all five always sit on a single line at the same width regardless of
   label content. Negative top margin pulls the row close to the toggles
   since they already carry their own 24px bottom margin.

   `flex-wrap: wrap` lets the five chips break onto a second row on
   narrow viewports (≤480px) where five chips × ~76px each + 4 × 8px
   gaps would otherwise force each chip to ~76px wide and clip the
   bracket labels (e.g. "21-50" gets cut off). On wider viewports the
   chips still sit on one line because the 760px width gives each chip
   ~144px, well above the wrap threshold. */
.section-heading-brackets {
    display: flex;
    justify-content: center;
    align-items: stretch;
    flex-wrap: wrap;
    gap: 8px;
    margin: -8px auto 24px;
    width: 760px;
    max-width: 100%;
}

.section-heading-brackets .micro-pricing-toggle__btn {
    flex: 1 1 0;
    min-width: 0;
}

/* Phone — at <=480px the 5-chip bracket row + the 2-pill toggle row
   are too tight to render legibly side-by-side at flex:1. Bump each
   chip's min-width so wrapping kicks in cleanly, and stack the
   Personal/Practice + Monthly/Annual pills vertically so the labels
   are not crushed. Both controls keep their `width: 760px; max-width:
   100%` outer envelope, so they expand to the column width and the
   inner items decide how they break. */
@media (max-width: 480px) {
    .section-heading-toggles {
        flex-direction: column;
        gap: 8px;
    }

    .section-heading-toggles .micro-pricing-toggle {
        width: 100%;
    }

    .section-heading-brackets .micro-pricing-toggle__btn {
        flex: 1 0 calc(50% - 8px);
        min-width: 0;
    }
}

/* ── Pricing tile compact mode for phones ────────────────────────────
   Below the sm breakpoint (600 px) the four module tiles render as a
   2×2 grid (xs="6" on the MudItem in Home.razor) instead of stacking
   1-up. At a typical 568 px phone viewport the inner div's 116 % /
   margin: -8% extension keeps the strip ~660 px wide and each card
   ends up around 320 px — still readable but the desktop padding /
   font sizes leave the body content cramped against the price block.
   The block below scales the chrome (header padding, title, tagline,
   body text, marker list, price headline) down by ~10–15 % so the
   2-up layout breathes properly.

   Boundary picked at 599.95 px so it exactly matches MudBlazor's
   xs / sm breakpoint and the override engages the moment the grid
   flips from 1-up (≥sm) to 2-up. */
@media (max-width: 599.95px) {
    /* Tighter padding and smaller title/tagline so the header strip
       doesn't dominate the card. */
    .module-tile__header {
        padding: 14px 12px 12px;
    }
    .module-tile__title {
        font-size: 1.05rem;
        line-height: 1.2;
    }
    .module-tile__tagline {
        font-size: 0.78rem;
        line-height: 1.3;
    }

    /* Body face padding tightened from 9/20 to 8/12 so the prose body
       and the marker list have room either side without wrapping
       awkwardly. The desktop min-height of 240 px is dropped to 180 px
       because the body face's natural height drives the card on a
       phone (long descriptions still grow it, short ones don't waste
       a fixed 240 px slot). */
    .module-tile__body {
        min-height: 180px;
    }
    .module-tile__body-face {
        padding: 8px 12px;
    }
    .module-tile__body-front {
        font-size: 0.74rem;
        line-height: 1.5;
        /* `text-align: justify` produces large word gaps in narrow
           columns (the body face is ~280 px wide here). Switch to
           left-aligned so the prose reads naturally without rivers of
           white. */
        text-align: left;
    }
    .module-tile__back-kicker {
        font-size: 0.78rem;
    }
    .module-tile__marker-list {
        gap: 6px;
    }
    .module-tile__marker-list li {
        font-size: 0.78rem;
    }

    /* Price block scales down with the rest of the card but keeps
       enough min-height for the worst-case 4-line annual layout
       (headline + per-month + label + savings) plus a touch of
       breathing room. */
    .module-tile__price-block {
        padding: 8px 12px 6px;
        min-height: 88px;
    }
    .module-tile__price {
        font-size: 1rem;
    }
    .module-tile__price-permonth {
        font-size: 0.7rem;
    }
    .module-tile__price-label {
        font-size: 0.62rem;
    }
    .module-tile__savings-slot {
        font-size: 0.65rem;
    }

    /* Toggle pill scaling. At 480-600 px the three toggles share one
       horizontal row at flex: 1 1 0, which forces each button down to
       ~85 px content area. Short two-word labels ("Ex GST", "Inc GST")
       were breaking at the space between the words and rendering on
       two lines under the desktop padding/font (10/22 + 0.95rem).
       Scaling padding to 7/12 and font to 0.78rem brings each label
       back inside one line while keeping the pill shape intact.
       white-space: nowrap on the base rule makes this a hard
       single-line guarantee even if a future label edges close to the
       width budget. */
    .micro-pricing-toggle {
        font-size: 0.78rem;
        padding: 2px;
    }
    .micro-pricing-toggle__btn {
        min-width: 0;
        padding: 7px 12px;
        font-size: 0.78rem;
        letter-spacing: 0;
    }
    .section-heading-toggles {
        gap: 8px;
    }

    /* ── Pricing section: toggles + brackets above cards ────────────
       Default DOM order in Home.razor (#section-5):
         1. .section-heading-row     (heading)
         2. .home-section-bleed      (4 module tiles strip)
         3. .section-heading-toggles (3 pill toggle pairs)
         4. .section-heading-brackets (5 user-count chips)
         5. .pricing-flow-cta        (Start free trial button)

       Below 600 px the user has to scroll past the 2×2 cards strip to
       reach the controls that drive each card's headline pricing,
       which inverts the natural "set the controls, see the result"
       reading order. The flex `order` overrides below relocate the
       toggle/bracket controls UP to between the heading and the cards
       on phones, while leaving the desktop column flow untouched
       (outside this @media block .pricing-flow is still display: flex
       column, but every child has the default order: 0 so DOM order
       wins).

       Heading is anchored at 1, controls run 2-3, cards at 4, CTA at
       5; numbers leave room for future controls (e.g. a sticky-top
       toggle band) without renumbering. */
    .pricing-flow > .section-heading-row { order: 1; }
    .pricing-flow > .section-heading-toggles { order: 2; }
    .pricing-flow > .section-heading-brackets { order: 3; }
    .pricing-flow > .home-section-bleed { order: 4; }
    .pricing-flow > .pricing-flow-cta { order: 5; }

    /* The toggles set carries large desktop margins (mt: 64 px on the
       toggle row, mb: 24 px from the default .section-heading-toggles
       rule, and another 24 px below the bracket row) that read well
       when the controls sit BELOW the cards but produce too much air
       between the controls and the cards once the controls are moved
       above. Override every margin in the chain explicitly so the
       phone pricing flow reads as one connected block:

         heading
           ↓ 16 px       (toggles top)
         toggles
           ↓  4 px       (toggles bottom + brackets top)
         brackets
           ↓  4 px       (brackets bottom)
         cards

       Total margin gap between toggles and cards = 8 px + the bracket
       row's own height. Tightened from 56 px of pure margin in the
       previous pass. */
    .pricing-flow > .section-heading-toggles {
        margin-top: 16px;
        margin-bottom: 4px;
    }
    .pricing-flow > .section-heading-brackets {
        margin-top: 0;
        margin-bottom: 4px;
    }
}

/* `home-cta-multiline` centres wrapped label text inside the three
   primary CTAs (Download Sample, Explore Case Studies, Start Free
   Trial). MudButton's inner `.mud-button-label` defaults to a flex /
   inline-flex container with `text-align: inherit` — when a long label
   like "Download Sample Compliance Overview Report" wraps to two or
   three lines, the lines render left-aligned inside the centred
   button box, which is what produced the user's "left-aligned text
   in a centred box" screenshot.

   Both `text-align: center` and `justify-content: center` are needed
   because the label is a flex container: text-align governs how the
   wrapped lines lay out within the label, justify-content governs how
   the (single-line) inline-flex children lay out across the label
   row. Setting both makes the label centre wrapped multi-line text
   correctly regardless of MudButton's internal label markup. */
.home-cta-multiline .mud-button-label {
    text-align: center;
    justify-content: center;
    /* `line-height: 1.3` is a touch tighter than MudButton's default
       (~ 1.75 from inheriting body line-height) so wrapped lines sit
       close enough together to read as one label rather than two
       separate phrases. */
    line-height: 1.3;
}

/* `pricing-flow` activates a column flexbox on the section-5 MudItem so
   its named children (heading, cards, toggles, brackets, CTA) become
   flex items addressable by `order`. Default order: 0 across all
   children means desktop renders in DOM order; the @media block above
   reorders only on phones. Lives outside the @media block so the
   container is a flex column at every viewport (avoids a layout-mode
   change at the breakpoint that could trigger a momentary reflow
   flicker on resize). */
.pricing-flow {
    display: flex;
    flex-direction: column;
}

/* ── Home section bleed-frame ────────────────────────────────────────
   Two sections on the home page (impact cards in #section-4, pricing
   tiles in #section-5) extend their inner content slightly past the
   parent MudContainer's box so the strip visually breaks out of the
   page rhythm and reads as wider than the surrounding text. The
   geometry is `width: 116 %; margin: 0 -8 %` — i.e. 8 % overrun on
   each side relative to the container's content width.

   Critical width math (the previous responsive pass got this wrong
   and produced visible horizontal-scrollbar / cropped-content issues
   between 600 px and full desktop):

     • MudContainer MaxWidth.Large caps at 1280 px and adds pa-4
       (16 px each side), so the inner content area is 1248 px once
       the viewport is wide enough to clear that cap.
     • A 116 % bleed needs 1.16 × 1248 = 1447.7 px of horizontal
       canvas to render without overflowing.
     • Below the cap, MudContainer fills the viewport, so the bleed's
       1.16 × content_width is ALWAYS wider than the viewport and
       overflows by 8 % of the content area on each side.
     • Consequence: the bleed only fits cleanly on viewports ≥ 1448 px
       (the 1500 px threshold below adds ~50 px of safety margin so
       the bleed never touches the viewport edge).

   Below the threshold the bleed flips OFF and the strip uses 100 %
   of the container — same width as the surrounding text columns,
   identical visual to a non-bleed section. The "break-out" effect
   was always cosmetic, never load-bearing for the layout, so losing
   it on intermediate viewports has no readability cost. */
.home-section-bleed {
    /* Default = no bleed. Strip width matches the container's content
       area at every viewport from 320 px up through 1499 px. */
    margin-left: 0;
    margin-right: 0;
    width: 100%;
}

@media (min-width: 1500px) {
    /* Wide-desktop only: re-engage the cosmetic bleed once the viewport
       is wide enough to host it without horizontal overflow. At 1500 px
       slack-each-side = (1500 − 1280) / 2 = 110 px versus required
       8 % × 1248 = ~ 100 px, leaving ~ 10 px of breathing room. */
    .home-section-bleed {
        margin-left: -8%;
        margin-right: -8%;
        width: 116%;
    }
}

/* NOTE: extra specificity (.section-heading-brackets ancestor) is intentional
   so these rules win against the base .micro-pricing-toggle__btn rule
   further down in this file, which sets `border: 0`. Without the extra
   class the border would be reset to none and the chips would look like
   floating text. */
.section-heading-brackets .micro-pricing-toggle__btn--bracket {
    background: rgba(255, 255, 255, 0.6);
    /* Thin light-grey outline so unselected chips have a clear edge against
       the page background instead of looking like floating text. */
    border: 1px solid #D1D5DB;
}

.section-heading-brackets .micro-pricing-toggle__btn--bracket:hover {
    background: rgba(255, 255, 255, 0.95);
    border-color: #9CA3AF;
}

/* Contact form card (last section). Cleaner than the original
   gradient-paper look: pure white background, soft shadow, rounded
   corners, and a brand-indigo accent strip on top to give the card
   visual identity without competing with the form fields inside. */
.contact-form-card {
    background: #F7F8FC;
    border: 1px solid rgba(15, 22, 50, 0.08);
    border-top: 4px solid #3B3F7A;
    border-radius: 16px;
    box-shadow: 0 8px 28px rgba(15, 22, 50, 0.06);
}

/* Pill-shaped Personal/Practice + Monthly/Annual toggles (and the
   Practice user-count bracket chips that share .micro-pricing-toggle__btn).
   Single source of truth: _pricingAudience / _pricingCadence /
   _practiceBracketId, so every card's headline price stays in sync. */
.micro-pricing-toggle {
    display: inline-flex;
    align-self: center;
    background: rgba(255, 255, 255, 0.6);
    border: 1px solid rgba(15, 22, 50, 0.10);
    border-radius: 999px;
    padding: 3px;
    font-size: 0.95rem;
    line-height: 1;
    overflow: hidden;
}

.micro-pricing-toggle__btn {
    appearance: none;
    border: 0;
    background: transparent;
    color: #4A4E6A;
    /* min-width keeps both toggles (Personal/Practice + Monthly/Annual) the
       same width regardless of label length, so the pair reads as a matched
       control row rather than two mismatched pills. */
    min-width: 120px;
    padding: 10px 22px;
    border-radius: 999px;
    text-align: center;
    font-weight: 600;
    letter-spacing: 0.02em;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
    /* nowrap stops short labels like "Ex GST" / "Inc GST" from being
       broken at the space between the two words once the button has
       been forced narrower than its natural content width — which
       happens whenever the three toggles are sharing one row at
       flex: 1 1 0 (see .section-heading-toggles below) on a viewport
       just above the 480 px stack-vertically threshold. The narrow
       viewport block further down also scales the font and padding so
       short labels still fit on a single line at any horizontal-row
       viewport down to 480 px. */
    white-space: nowrap;
}

.micro-pricing-toggle__btn:hover {
    color: #1E2240;
}


/* ─────────────────────────── Preview carousel ───────────────────────────
   Rolling-strip carousel. Architecture:

     .showcase-carousel  ← outer flex row (chevrons sit outside the
                            viewport so they never clip a peeking slide)
       ├─ .showcase-nav--prev
       ├─ .showcase-viewport  ← overflow:hidden window
       │     └─ .showcase-strip  ← horizontal flex strip containing ALL
       │                            slots; translateX-es so the active
       │                            slot lands in the viewport centre.
       │           └─ .showcase-slot * N
       └─ .showcase-nav--next

   Smoothness: the only thing that animates between slide changes is
   `.showcase-strip { transform }` plus each slot's
   `transform/opacity/filter` (active vs peek). Everything is driven by a
   single `--showcase-index` CSS custom property that Razor sets inline
   on the strip. Two CSS variables (`--slot-width-pct`, `--slot-gap`)
   make the rolling distance derive from the slot pitch, which means the
   responsive breakpoints only need to override those two values. */
.showcase-carousel {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    margin: 16px 0 18px;
    user-select: none;
}

.showcase-viewport {
    position: relative;
    width: 100%;
    max-width: 1200px;
    overflow: hidden;
    /* Vertical breathing room so the active slot's drop-shadow is not
       clipped by overflow:hidden. */
    padding: 18px 0;
}

.showcase-strip {
    /* CSS variables drive the slot pitch and the centring offset. The
       transform formula:
         translateX( (100% - slot-width-pct) / 2
                     − showcase-index * (slot-width-pct + slot-gap) )
       puts slot[0] in the centre at index 0, slides one full pitch left
       per index increment, and the single transition gives the rolling
       motion. */
    --slot-width-pct: 60%;
    --slot-gap: 18px;
    --showcase-index: 0;

    display: flex;
    align-items: center;
    gap: var(--slot-gap);
    transform: translateX(calc(
        (100% - var(--slot-width-pct)) / 2
        - var(--showcase-index) * (var(--slot-width-pct) + var(--slot-gap))
    ));
    transition: transform 0.7s cubic-bezier(0.22, 0.61, 0.36, 1);
    will-change: transform;
}

/* Toggled on for one render after a wrap-around lands on a phantom slot.
   Disables BOTH the strip translate transition and the slot enter/exit
   transitions so the snap from phantom to its real twin is invisible —
   the next render restores transitions for normal rolling. */
.showcase-strip--no-transition,
.showcase-strip--no-transition .showcase-slot {
    transition: none !important;
}

.showcase-slot {
    flex: 0 0 var(--slot-width-pct);
    max-width: var(--slot-width-pct);
    border-radius: 10px;
    overflow: hidden;
    background: #ffffff;
    cursor: pointer;
    transition: transform 0.55s cubic-bezier(0.22, 0.61, 0.36, 1),
                opacity 0.55s ease,
                filter 0.55s ease,
                box-shadow 0.55s ease;
}

.showcase-slot img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 10px;
    pointer-events: none;
}

.showcase-slot--active {
    transform: scale(1);
    opacity: 1;
    box-shadow: 0 14px 32px rgba(15, 22, 50, 0.22);
    z-index: 2;
}

.showcase-slot--peek {
    transform: scale(0.86);
    opacity: 0.5;
    filter: saturate(0.85);
    box-shadow: 0 6px 16px rgba(15, 22, 50, 0.10);
    z-index: 1;
}

.showcase-slot--peek:hover {
    opacity: 0.8;
    transform: scale(0.92);
    filter: saturate(1);
}

/* Chevron buttons sit OUTSIDE the viewport so they don't crop the
   peeking slides; brand-indigo on hover. */
.showcase-nav {
    flex-shrink: 0;
    width: 42px;
    height: 42px;
    border-radius: 50%;
    border: 1px solid rgba(59, 63, 122, 0.25);
    background: rgba(255, 255, 255, 0.95);
    color: #3B3F7A;
    font-size: 1.6rem;
    line-height: 1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    transition: background 0.2s ease, border-color 0.2s ease,
                transform 0.2s ease, color 0.2s ease;
    z-index: 3;
}

.showcase-nav:hover {
    background: #3B3F7A;
    color: #ffffff;
    border-color: #3B3F7A;
    transform: scale(1.06);
}

.showcase-nav:focus-visible {
    outline: 2px solid #3B3F7A;
    outline-offset: 2px;
}

/* Indicator dots — same colour family as the section navigator and hero
   rotator dots so the page reads as one consistent control style. */
.showcase-dots {
    display: flex;
    justify-content: center;
    gap: 10px;
    margin-bottom: 4px;
}

.showcase-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background-color: rgba(59, 63, 122, 0.25);
    cursor: pointer;
    transition: background-color 0.2s ease, transform 0.2s ease;
}

.showcase-dot:hover {
    background-color: rgba(59, 63, 122, 0.55);
}

.showcase-dot.active {
    background-color: #3B3F7A;
    transform: scale(1.25);
}

/* Caption pill above the carousel — reuses .hero-eyebrow's pill styling
   but tightens the spacing so it sits snugly between the section heading
   and the carousel images. */
.showcase-eyebrow {
    margin-top: 0;
    margin-bottom: 12px;
}

/* ───────────────────── Feature flip-tile grid ─────────────────────
   Sits directly under the carousel. Each tile is a 3D flip card —
   icon + title on the front, longer detail on the back. The tiles
   are driven by _featureTiles in Home.razor so adding/removing
   capabilities is a one-line change in C#.

   Touch / no-hover devices get a flat fallback (see @media block at
   the bottom) where the front and back are stacked vertically and the
   3D transform is disabled — flipping on tap feels gimmicky on mobile
   and trades discoverability for novelty. */
/* Section eyebrow above the feature grid — reuses the .hero-eyebrow pill
   look but with section-spacing margins (more breathing room above to
   separate from the carousel, less below to hug the grid). */
.feature-flip-grid {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 18px;
    margin-top: 20px;
    margin-bottom: 8px;
}

.feature-tile {
    perspective: 1200px;
    height: 225px;
    cursor: pointer;
    outline: none;
}

.feature-tile-inner {
    position: relative;
    width: 100%;
    height: 100%;
    transform-style: preserve-3d;
    transition: transform 0.6s cubic-bezier(0.22, 0.61, 0.36, 1);
    border-radius: 12px;
}

@media (hover: hover) {
    .feature-tile:hover .feature-tile-inner,
    .feature-tile:focus-visible .feature-tile-inner {
        transform: rotateY(180deg);
    }
}

.feature-tile:focus-visible {
    box-shadow: 0 0 0 3px rgba(59, 63, 122, 0.35);
    border-radius: 12px;
}

.feature-tile-face {
    position: absolute;
    inset: 0;
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
    border-radius: 12px;
    padding: 10px 14px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
}

.feature-tile-front {
    background: rgba(59, 63, 122, 0.05);
    border: 1px solid rgba(59, 63, 122, 0.15);
}

.feature-tile-front .feature-tile-icon {
    color: #3B3F7A;
    margin-bottom: 8px;
}

.feature-tile-front .feature-tile-title {
    font-weight: 600;
    color: #1E2240;
    font-size: 0.9rem;
    line-height: 1.25;
}

.feature-tile-back {
    background: linear-gradient(135deg, #3B3F7A, #1E2240);
    color: #ffffff;
    transform: rotateY(180deg);
}

.feature-tile-back .feature-tile-title {
    font-weight: 600;
    font-size: 0.85rem;
    margin-bottom: 4px;
    line-height: 1.25;
}

.feature-tile-back .feature-tile-detail {
    font-size: 0.72rem;
    line-height: 1.4;
    opacity: 0.92;
}

/* Responsive grid columns — keep tiles readable at every breakpoint.
   Tile HEIGHT also scales down with column count so the 2-up and 1-up
   layouts don't leave a sea of empty space around the icon + title.
   The desktop 225 px is right for ~180 px-wide tiles where the
   detail text on the back face wraps to 5-6 lines; at 2-up phone
   widths the tiles are wider (~280 px) so the back text wraps to
   3-4 lines and the front face's icon + 1-2 line title only
   needs ~80 px of content area. Trimming the tile to 150 px (and
   130 px at 1-up) brings the empty space back into proportion
   without clipping any of the back-face copy.

   The (hover: none) override further down already sets height: auto
   on touch devices, but Chrome DevTools mobile emulation typically
   reports hover: hover so the fixed-height rule still applies and
   produces the screenshots the user flagged. These responsive heights
   apply regardless of hover capability so the visual is consistent
   across real phones and emulated phones. */
@media (max-width: 1280px) { .feature-flip-grid { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 960px)  { .feature-flip-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 720px)  {
    .feature-flip-grid { grid-template-columns: repeat(2, 1fr); gap: 12px; }
    .feature-tile { height: 150px; }
    /* Tighter icon -> title gap so the 150 px tile centres nicely. */
    .feature-tile-front .feature-tile-icon { margin-bottom: 4px; }
    .feature-tile-face { padding: 8px 12px; }
}
@media (max-width: 480px)  {
    .feature-flip-grid { grid-template-columns: 1fr; gap: 10px; }
    .feature-tile { height: 130px; }
}

/* Touch / no-hover fallback — stack front + back, drop the 3D flip,
   and tone the back panel down so it reads as a paragraph rather than
   a CTA panel. */
@media (hover: none) {
    .feature-tile {
        height: auto;
        cursor: default;
        perspective: none;
    }
    .feature-tile-inner {
        transform: none !important;
        transform-style: flat;
        transition: none;
    }
    .feature-tile-face {
        position: relative;
        inset: auto;
        backface-visibility: visible;
        padding: 18px 16px;
    }
    .feature-tile-back {
        transform: none;
        background: transparent;
        color: #5B6275;
        padding-top: 0;
    }
    .feature-tile-back .feature-tile-title { display: none; }
    .feature-tile-back .feature-tile-detail { opacity: 1; }
}

/* Tablet — let the active slot occupy more of the viewport so the
   chart-heavy screens stay legible. The strip's translateX formula
   recalculates automatically via the CSS variable. */
@media (max-width: 960px) {
    .showcase-strip {
        --slot-width-pct: 78%;
        --slot-gap: 14px;
    }
}

/* Mobile — single image at a time; the rolling motion still works,
   it just rolls a full slide-width per step with no peek visible. */
@media (max-width: 600px) {
    .showcase-strip {
        --slot-width-pct: 100%;
        --slot-gap: 12px;
    }
    .showcase-slot--peek {
        opacity: 0;
    }
    .showcase-nav {
        width: 36px;
        height: 36px;
        font-size: 1.3rem;
    }
}

/* Vertical text rotator */
.vertical-text-rotator {
    position: relative;
    height: 180px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

.rotator-content {
    position: relative;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 1;
}

/* Base rule deliberately has NO transition. When the external stylesheet
   first applies, the four <MudText> headings snap straight into their
   absolute-positioned, opacity-0 state (active one snaps to opacity 1)
   instead of animating from their unstyled in-flow positions — that's
   the "everything appears stacked then drops away" FOUC the user reported.
   The transition is added ONLY once Home.razor's OnAfterRenderAsync flips
   _rotatorMounted = true, which adds .rotator-content--mounted below. */
.rotator-text {
    position: absolute;
    width: 100%;
    opacity: 0;
    transform: translateY(100%);
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
}

.rotator-content--mounted .rotator-text {
    transition: opacity 0.8s cubic-bezier(0.4, 0, 0.2, 1),
                transform 0.8s cubic-bezier(0.4, 0, 0.2, 1);
}

.rotator-text.active {
    opacity: 1;
    transform: translateY(0);
}

.rotator-text.exiting {
    opacity: 0;
    transform: translateY(-100%);
}

.rotator-indicators {
    display: flex;
    gap: 8px;
    margin-top: auto;
    position: absolute;
    bottom: -40px;
    left: 50%;
    transform: translateX(-50%);
}

.rotator-indicators .indicator {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background-color: rgba(59, 63, 122, 0.3);
    cursor: pointer;
    transition: all 0.3s ease;
}

.rotator-indicators .indicator.active {
    background-color: #3B3F7A;
    transform: scale(1.2);
}

.rotator-indicators .indicator:hover {
    background-color: rgba(59, 63, 122, 0.6);
}

/* Offset anchor scrolling for fixed header */
[id^="section-"] {
    scroll-margin-top: 100px;
}

/* Section Navigator */
.section-navigator {
    position: fixed;
    right: 32px;
    top: 50%;
    transform: translateY(-50%);
    z-index: 1000;
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.nav-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background-color: rgba(59, 63, 122, 0.3);
    cursor: pointer;
    transition: all 0.3s ease;
    position: relative;
}

.nav-dot:hover {
    background-color: rgba(59, 63, 122, 0.6);
    transform: scale(1.2);
}

.nav-dot.active {
    background-color: #3B3F7A;
    transform: scale(1.3);
    box-shadow: 0 0 6px rgba(59, 63, 122, 0.4);
}

.nav-dot::before {
    content: attr(title);
    position: absolute;
    right: 18px;
    top: 50%;
    transform: translateY(-50%);
    background-color: #3B3F7A;
    color: white;
    padding: 4px 8px;
    border-radius: 3px;
    font-size: 0.7rem;
    white-space: nowrap;
    min-width: 80px;
    text-align: center;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s ease;
}

.nav-dot:hover::before {
    opacity: 1;
}

/* Hide on mobile */
@media (max-width: 960px) {
    .section-navigator {
        display: none;
    }

    /* The Section 3 centre image absolutely-positions across both impact
       cards. Below the md breakpoint the cards stack vertically and the
       overlay is meaningless / clipping, so drop it entirely. */
    .impact-center-image {
        display: none !important;
    }

    /* Also force the impact cards out of their indented padding so they
       use their full column width when stacked. The 28 px on each side
       gives the content a comfortable gutter inside the impact strip's
       12 px outer rounding without crowding the numbered chips against
       the strip's outer wall. */
    .impact-card-left,
    .impact-card-right {
        padding-left: 28px !important;
        padding-right: 28px !important;
    }

    /* Right-aligned For Practices items have their numbered chip on the
       trailing edge; tighten the body's right inset so the chip+text
       block sits comfortably inside the gutter rather than stretched
       all the way to the panel edge. */
    .impact-card-right .mud-typography {
        padding-right: 0 !important;
    }
}

/* Desktop-only asymmetric inset that pushes both impact cards away
   from the strip's vertical centreline so they read as a left-half /
   right-half pair with the watermark figure visible between them.
   Used to live as an inline `padding-{left,right}: 16% !important`
   on each MudPaper, which overrode every responsive rule below the
   md breakpoint and produced the "content hugging the edges" feel on
   phones. Moved here so the inset only applies once we're at desktop
   width — under 960 px the 28 px symmetric padding above takes over. */
@media (min-width: 960px) {
    .impact-card-left {
        padding-right: 16% !important;
    }
    .impact-card-right {
        padding-left: 16% !important;
    }
}

/* Unified translucent "strip" that wraps both impact cards. The photo
   underneath is a watermark (Home.razor sets opacity: 0.40) — it
   contributes recognisable figure rather than just texture. The strip's
   semi-opaque white background gives every word inside it a clean
   surface to sit on while still letting the photo show through, which
   is what the previous gradient-fade-card approach was trying and
   failing to deliver.

   z-index: 4 matches what the individual card classes used to claim
   (the cards still have it for back-compat, but the strip is now what
   actually lifts the content over the photo).

   background colour: rgb(238, 241, 246) is a very pale cool grey rather
   than pure white — it picks up the page's existing cool-blue accent
   tones (#7AB8E0 borders, #4A4E6A headings) rather than reading as a
   separate clinical-white element pasted on top. Composited over the
   page background at alpha 0.68 the rendered colour is ~(244, 245, 249),
   which is the "a tad darker" target without slipping into "grey panel".

   background opacity: 0.68 leaves a 32% bleed of the photo through the
   strip. At 0.50 photo opacity that compounds to ~16% visible photo
   through the strip body — figures clearly visible as a watermark
   behind the text, with the image's brightness(0.80) filter keeping
   their tones deep enough that they don't wash out against the panel.
   Note: the image's top mask feather was widened from 6% to 10% to
   accommodate this lower strip opacity — at <0.75 the photo's hard
   top edge would otherwise start bleeding through as a thin line. The photo's mask-image in Home.razor now
   feathers both top and bottom, so there's no hard horizontal edge
   bleeding through the strip near its top — important once the strip
   gets translucent enough for sub-edges to show.

   Dial range for the colour: rgb(245, 247, 250) (almost-white, very
   subtle tint) through rgb(225, 230, 238) (clearly grey-blue, panel
   reads as a section in its own right). For the opacity: 0.72 (more
   photo bleed through the strip body, more atmospheric, text contrast
   drops on light photo regions — also widen the top mask feather in
   Home.razor) through 0.90 (near-opaque, photo visible only as a faint
   wash). Pair with the photo opacity in Home.razor — both knobs
   compose multiplicatively in the strip's footprint.

   border-radius: 12px reads as "panel" rather than "page section"; the
   subtle drop shadow gives it the same lift the earlier cards had via
   their (now removed) gradient. */
.impact-strip {
    position: relative;
    z-index: 4;
    background: rgba(238, 241, 246, 0.68);
    border-radius: 12px;
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.06);
}

/* Make the impact cards reach the strip's outer edges, eliminating the
   "moat" of strip background that would otherwise show around them.

   Why this is needed: MudGrid Spacing="6" applies (effectively)
   margin: -12px to the grid container and padding: 12px to each item.
   Visually those cancel out so the items' content edges align with the
   grid's apparent boundary — but the .impact-strip then wraps the
   grid's *outer* box, leaving a 12px gap on every edge between the
   strip border and the actual card content. That gap is the green
   area the user sees in DevTools.

   The fix is two-part:

   1. Zero the grid's negative margin so the grid sits flush inside the
      strip rather than overflowing it by 12px on every side. Otherwise
      step 2 would push the items 12px past the strip's borders.
   2. Zero only the *outer* item paddings. The inner paddings (first
      card's right side / second card's left side at ≥md, or first
      card's bottom / second card's top when stacked) stay at 12px,
      preserving the breathing room between the two cards. The 24px
      total gap between cards (12px + 12px) becomes our centre gutter.

   Responsive split — !important throughout because MudGrid's own
   styles already use sufficient specificity:

   - ≥md  : side-by-side. first-child = left card, last-child = right
            card. Kill first's left + both's top/bottom; kill last's
            right.
   - <md  : stacked. first-child = top card, last-child = bottom card.
            Kill both's left/right; kill first's top + last's bottom.

   If you ever change MudGrid Spacing here, the inner gap moves with
   it automatically (we don't touch the inner paddings). */
.impact-strip > .mud-grid {
    margin: 0 !important;
    width: 100% !important;
}

@media (min-width: 960px) {
    .impact-strip > .mud-grid > .mud-grid-item:first-child {
        padding-left: 0 !important;
        padding-top: 0 !important;
        padding-bottom: 0 !important;
    }
    .impact-strip > .mud-grid > .mud-grid-item:last-child {
        padding-right: 0 !important;
        padding-top: 0 !important;
        padding-bottom: 0 !important;
    }
}

@media (max-width: 959.95px) {
    .impact-strip > .mud-grid > .mud-grid-item {
        padding-left: 0 !important;
        padding-right: 0 !important;
    }
    .impact-strip > .mud-grid > .mud-grid-item:first-child {
        padding-top: 0 !important;
    }
    .impact-strip > .mud-grid > .mud-grid-item:last-child {
        padding-bottom: 0 !important;
    }
}

/* Impact cards — fading top/bottom borders via pseudo-elements.
   z-index: 4 lifts the cards ABOVE the centre figure image (which sits
   at z-index: 3 in Home.razor). We deliberately let the figure widen
   into the text columns rather than constantly shrinking it / widening
   the side gutter every time a new consideration item is added — the
   text-shadow rule below keeps any text that overlaps the figure
   legible, and the card's existing `linear-gradient(rgba(255,255,255,
   0.5) → rgba(255,255,255,0))` background gives the inner edge a soft
   white veil that fades into the figure naturally. */
.impact-card-left,
.impact-card-right {
    position: relative;
    z-index: 4;
}

/* White text-halo for everything inside the impact cards. Multi-layer
   shadow (3px / 6px / 12px blur radii at decreasing opacity) gives a
   thicker, more solid halo than a single 6–8px blur — important
   because the underlying figure isn't a flat colour (dark suit, hair,
   skin tones all create high-contrast points the text would otherwise
   read poorly against). Scoped to .mud-typography so it covers every
   MudText inside the cards (titles, item subtitles, body copy)
   without bleeding into the numbered chips, which already have their
   own solid background colour. */
.impact-card-left .mud-typography,
.impact-card-right .mud-typography {
    text-shadow:
        0 0 3px rgba(255, 255, 255, 0.95),
        0 0 6px rgba(255, 255, 255, 0.85),
        0 0 12px rgba(255, 255, 255, 0.6);
}
.impact-card-left::before,
.impact-card-left::after {
    content: '';
    position: absolute;
    left: 0;
    height: 1px;
    width: 100%;
    background: linear-gradient(to right, rgba(200, 200, 210, 0.4) 0%, rgba(200, 200, 210, 0.4) 65%, transparent 100%);
    pointer-events: none;
}
.impact-card-left::before { top: 0; }
.impact-card-left::after { bottom: 0; }

.impact-card-right::before,
.impact-card-right::after {
    content: '';
    position: absolute;
    right: 0;
    height: 1px;
    width: 100%;
    background: linear-gradient(to left, rgba(200, 200, 210, 0.4) 0%, rgba(200, 200, 210, 0.4) 65%, transparent 100%);
    pointer-events: none;
}
.impact-card-right::before { top: 0; }
.impact-card-right::after { bottom: 0; }

/* Impact section numbered items */
.impact-item {
    display: flex;
    gap: 14px;
    align-items: flex-start;
    margin-bottom: 20px;
}
.impact-item:last-child {
    margin-bottom: 0;
}
.impact-item-right {
    flex-direction: row;
    justify-content: flex-end;
}
.impact-number {
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    color: white;
    font-size: 0.8rem;
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-top: 2px;
}

/* Scroll Indicator Chevron */
.scroll-indicator-wrapper {
    width: 80%;
    margin: 48px 10% 48px 10%;
    position: relative;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.chevron-down {
    width: 100%;
    height: 100%;
    position: relative;
}

.chevron-line {
    position: absolute;
    width: 50%;
    height: 2px;
    background-color: #E8EAF0;
}

.chevron-line-left {
    left: 0;
    top: 0;
    transform-origin: right center;
    transform: rotate(4deg);
}

.chevron-line-right {
    right: 0;
    top: 0;
    transform-origin: left center;
    transform: rotate(-4deg);
}

/* Upward Chevron */
.chevron-up {
    width: 100%;
    height: 100%;
    position: relative;
}

.chevron-line-up {
    position: absolute;
    width: 50%;
    height: 2px;
    background-color: #E8EAF0;
}

.chevron-line-up-left {
    left: 0;
    bottom: 0;
    transform-origin: right center;
    transform: rotate(-4deg);
}

.chevron-line-up-right {
    right: 0;
    bottom: 0;
    transform-origin: left center;
    transform: rotate(4deg);
}
