/* Silver Memories Directory — Layout & Component Styles */

/* ── Public site wrapper ──────────────────────────────────── */
/* All brand typography and colour is scoped here. */

.sm-public-site {
    font-family: var(--font-body);
    color: var(--sm-ink);
    background-color: var(--sm-bg);
    font-size: var(--fs-base);
    line-height: 1.6;
    min-height: 100dvh;
}

.sm-public-site h1,
.sm-public-site h2,
.sm-public-site h3,
.sm-public-site h4,
.sm-public-site h5,
.sm-public-site h6 {
    font-family: var(--font-display);
    color: var(--sm-teal);
    line-height: 1.2;
}

/* Heading sizes come from the --fs-h* tiers in brand.css, not from Bootstrap's reboot, and not
   from a size inlined on the element. Admin is untouched: it keeps Bootstrap's scale.

   In :where() so each of these carries the weight of a bare element selector. Without it a tier
   would beat any single class — .sm-subhead, .sm-card-body h3, .sm-modal h2 — and a card's
   section heading would render at page-title size. */
:where(.sm-public-site) h1 { font-size: var(--fs-h1); }
:where(.sm-public-site) h2 { font-size: var(--fs-h2); }
:where(.sm-public-site) h3 { font-size: var(--fs-h3); }
:where(.sm-public-site) h4 { font-size: var(--fs-h4); }
:where(.sm-public-site) h5 { font-size: var(--fs-h5); }
:where(.sm-public-site) h6 { font-size: var(--fs-h6); }

/* The section heading inside a card or a run of prose. The register wizard was setting this at
   1.1rem and the confirm/self-service cards at 1rem, for the same job on adjacent screens. */
.sm-subhead {
    font-size: var(--fs-h4);
    margin: var(--sp-5) 0 var(--sp-3);
}

/* A card's heading opens the card, so it takes no leading gap; mid-prose headings keep theirs. */
.sm-subhead:first-child { margin-top: 0; }

.sm-subhead--danger { color: var(--sm-coral-ink); }

/* A second heading that continues the page title rather than starting a section beneath it. */
.sm-public-site .sm-heading-as-title { font-size: var(--fs-h1); }

/* Helper text that makes a promise rather than a hint — "we'll get back to you". A step up from
   .sm-form-help and in coral-ink, not brand coral, which fails AA as text. */
.sm-public-site .sm-form-help--callout {
    font-size: var(--fs-base);
    font-weight: 600;
    color: var(--sm-coral-ink);
}

/* Oversized decorative glyph above an empty state, a 404 or a success screen. */
.sm-glyph {
    font-size: clamp(2.5rem, 8vw, 3.5rem);
    line-height: 1;
    color: var(--sm-aqua);
    margin-bottom: var(--sp-4);
}

/* Base link colour for body copy. Wrapped in :where() so it carries the specificity of a bare
   `a` — every classed link below (nav, footer, pagination, social pills, card links) overrides it
   without needing to out-specify the wrapper. Before this existed the Blazor template's
   `a { color: #006bb7 }` won by default and prose links rendered blue, which is why several pages
   had started hand-painting `style="color:var(--sm-teal)"` onto individual links. */
:where(.sm-public-site) a {
    color: var(--sm-teal);
    text-underline-offset: 3px;
}

:where(.sm-public-site) a:hover {
    color: var(--sm-teal-dark);
}

/* ── Public shell ─────────────────────────────────────────── */

/* Teal surfaces: a teal focus ring would vanish into them, so flip the ring to paper for
   everything focusable inside. --sm-focus inherits, so one declaration covers the subtree. */
.sm-site-header,
.sm-site-footer,
.sm-home-hero {
    --sm-focus: var(--sm-paper);
}

.sm-site-header {
    background-color: var(--sm-teal);
    border-bottom: 1px solid rgba(255,255,255,0.12);
    padding: 1rem 0;
    position: sticky;
    top: 0;
    z-index: 100;
    box-shadow: var(--shadow-header);
}

.sm-nav-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 2.5rem;
    gap: 1rem;
}

.sm-logo { height: 48px; width: auto; }

.sm-site-header--dense { padding: 0.5rem 0; }

.sm-header-brand {
    display: flex;
    align-items: center;
    gap: 0.875rem;
    text-decoration: none;
}

.sm-logo-compact { height: 64px; width: auto; }

/* The script "Entertainment" beside the compact logo. An image, so it is sized by height; alt is
   empty because the link's aria-label already names it. */
.sm-header-title {
    display: block;
    height: 34px;
    width: auto;
}

.sm-nav-links {
    display: flex;
    gap: 0.5rem;
    list-style: none;
    margin: 0;
    padding: 0;
    align-items: center;
}

.sm-nav-links a {
    font-family: var(--font-body);
    font-weight: 600;
    color: var(--sm-paper);
    text-decoration: none;
    padding: 0.5rem 0.75rem;
    border-radius: var(--radius-sm);
    transition: background-color var(--t-fast);
    min-height: 44px;
    display: flex;
    align-items: center;
}

.sm-nav-links a:hover { background-color: rgba(255,255,255,0.10); }
.sm-nav-links a.active { color: #fff; font-weight: 700; background-color: rgba(255,255,255,0.15); }

/* ── Footer ───────────────────────────────────────────────── */

.sm-site-footer {
    background-color: var(--sm-teal);
    color: var(--sm-paper);
    padding: 3rem 0 1.5rem;
    margin-top: 4rem;
}

/* Home page background */
main:has(.sm-home-hero) {
    background-color: var(--sm-bg);
}

/* Footer sits flush against the last home section */
main:has(.sm-home-hero) + .sm-site-footer {
    margin-top: 0;
}

.sm-footer-inner {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 1.5rem;
}

/* Taller than the plain logo needed: the tagline is set small inside the artwork, and at 72px it
   came out under 7px. The PNG is 300px tall, enough for a 2.5x screen at this size. */
.sm-footer-logo { height: 120px; width: auto; }

.sm-footer-cols {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 2rem;
    margin-top: 2rem;
    margin-bottom: 2rem;
}

.sm-footer-cols h3 {
    font-family: var(--font-display);
    font-size: var(--fs-base);
    color: var(--sm-aqua-pale);
    margin-bottom: 0.75rem;
}

.sm-footer-cols a,
.sm-footer-cols p {
    color: rgba(255,255,255,0.92);
    font-size: var(--fs-sm);
    text-decoration: none;
    display: block;
    margin-bottom: 0.4rem;
}

.sm-footer-cols a:hover { color: var(--sm-paper); text-decoration: underline; }

/* Attribution line — sized to match the copyright strip */
.sm-footer-cols p.sm-footer-fineprint { font-size: var(--fs-xs); }

/* Inline footer link */
.sm-footer-cols .sm-footer-link-inline {
    display: inline;
    margin-bottom: 0;
    text-decoration: underline;
}

/* Funding acknowledgement: Queensland Government logo beside the statement, stacking when narrow. */
.sm-footer-funding {
    border-top: 1px solid rgba(255,255,255,0.15);
    padding: 1.5rem 0;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 1rem 1.5rem;
}
.sm-footer-funding-logo { height: 48px; width: auto; flex-shrink: 0; }
.sm-footer-funding p {
    color: rgba(255,255,255,0.92);
    font-size: var(--fs-sm);
    margin: 0;
}

.sm-footer-bottom {
    border-top: 1px solid rgba(255,255,255,0.15);
    padding-top: 1.25rem;
    font-size: var(--fs-xs);
    color: rgba(255,255,255,0.92);
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* ── Page wrapper ─────────────────────────────────────────── */

.sm-page {
    max-width: 1200px;
    margin: 0 auto;
    padding: 2rem 1.5rem;
}

.sm-page-narrow {
    max-width: 720px;
    margin: 0 auto;
    padding: 2rem 1.5rem;
}

/* ── Homepage: transparent header, fades to glass on scroll ── */

body:has(.sm-home-hero) .sm-site-header {
    position: fixed;
    width: 100%;
    background: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    border-bottom: 1px solid transparent;
    box-shadow: none;
    transition: background var(--t-slow) ease, border-color var(--t-slow) ease, backdrop-filter var(--t-slow) ease;
}

/* Floating over the hero photo, the nav links otherwise have no backing until hover — fine over a
   plain teal header, but "Find an Entertainer" / "Get Listed" wash out against a busy part of the
   image before the glass background above kicks in on scroll. Solid pill buttons instead of a
   translucent chip: one prominent (coral, matching the hero's own CTA), one subtler so the two
   don't compete for attention. */
/* Same shadow as the hero subtext, so the logo holds up over a light patch of the photo the way
   the hero text does. A filter rather than box-shadow, so it follows the logo's shape. */
body:has(.sm-home-hero) .sm-logo,
body:has(.sm-home-hero) .sm-logo-compact {
    filter: drop-shadow(0 1px 8px rgba(0,0,0,0.5)) drop-shadow(0 1px 6px rgba(0,0,0,0.25));
}

body:has(.sm-home-hero) .sm-nav-cta-primary,
body:has(.sm-home-hero) .sm-nav-cta-secondary {
    border-radius: var(--radius-pill);
    font-weight: 700;
}

body:has(.sm-home-hero) .sm-nav-cta-primary {
    background-color: var(--sm-coral);
    color: var(--sm-paper);
}

body:has(.sm-home-hero) .sm-nav-cta-primary:hover {
    background-color: var(--sm-orange);
}

/* The hero has its own Find button, so the nav's copy waits until the hero scrolls away. It keeps
   its space while hidden so Get Listed doesn't shift, and visibility takes it out of the tab order. */
body:has(.sm-home-hero) .sm-nav-cta-primary {
    opacity: 0;
    visibility: hidden;
    transition: background-color var(--t-fast), opacity var(--t-slow) ease, visibility var(--t-slow);
}

body:has(.sm-home-hero).header-scrolled .sm-nav-cta-primary {
    opacity: 1;
    visibility: visible;
}

body:has(.sm-home-hero) .sm-nav-cta-secondary {
    background-color: rgba(255,255,255,0.92);
    color: var(--sm-teal);
}

body:has(.sm-home-hero) .sm-nav-cta-secondary:hover {
    background-color: #fff;
}

/* The hero title's script "Entertainment" joins the logo once the header turns solid. Hidden
   everywhere else, and below 901px, where the nav buttons need the width. */
.sm-header-script {
    display: none;
}

@media (min-width: 901px) {
    body:has(.sm-home-hero) .sm-header-script {
        display: block;
        height: 34px;
        width: auto;
        opacity: 0;
        visibility: hidden;
        transform: translateY(4px);
        transition: opacity var(--t-slow) ease, transform var(--t-slow) ease, visibility var(--t-slow);
    }

    body:has(.sm-home-hero).header-scrolled .sm-header-script {
        opacity: 1;
        visibility: visible;
        transform: none;
    }
}

body:has(.sm-home-hero).header-scrolled .sm-site-header {
    background: color-mix(in srgb, var(--sm-teal) 72%, transparent);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    border-bottom: 1px solid rgba(255,255,255,0.10);
}

body:has(.sm-home-hero) .sm-home-hero {
    min-height: 100dvh;
}

body:has(.sm-home-hero) .sm-home-hero-content {
    padding-top: 10rem;
}

/* ── Home hero — full-viewport, solid image over teal ─────────── */

.sm-home-hero {
    position: relative;
    min-height: calc(100dvh - 72px);
    background-color: var(--sm-teal);
    background-image: url('/brand/hero_performer01.webp');
    background-position: center 30%;
    background-size: cover;
    background-repeat: no-repeat;
    display: flex;
    align-items: flex-start;
    justify-content: flex-start;
    overflow: hidden;
}

.sm-home-hero::before {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(
        to right,
        rgba(30, 65, 75, 0.72) 0%,
        rgba(30, 65, 75, 0.35) 40%,
        transparent 65%
    );
    z-index: 0;
}

.sm-home-hero-content {
    position: relative;
    z-index: 1;
    text-align: left;
    padding: 3rem 3rem 5rem 4rem;
    max-width: 720px;
    width: 100%;
}

.sm-home-hero-content .sm-home-title {
    color: var(--sm-paper);
    /* "Silver Memories" measures ~6.9em in Playfair Display, and this content box allows
       720px less 7rem of padding = 608px. At the old 5.5rem cap that came to ~605px — inside
       the box by 3px, so any fallback to Georgia would break the line and render the title as
       three rows ("Silver" / "Memories" / "Entertainment"). The old 3rem floor was just as tight
       at 375px. Both ends pulled in for headroom; pre-rebrand the longest line was one word. */
    font-size: clamp(2.25rem, 7.5vw, 5rem);
    line-height: 1.05;
    margin-bottom: 3rem;
    /* A tight, dark shadow for edge definition against the now-lighter overlay, layered under the
       original soft glow for depth — the glow alone blurs into a busy background instead of
       separating the letterforms from it. */
    text-shadow: 0 2px 10px rgba(0,0,0,0.55), 0 2px 24px rgba(0,0,0,0.3);
    outline: none;
}

/* "Silver Memories" steps down so the script "Entertainment" beneath it carries the title. */
.sm-home-hero-content .sm-home-title .heading-display {
    font-size: 0.6em;
}

/* The script "Entertainment" is an image, so it is sized in em to track the title's clamp() and
   takes a drop-shadow filter in place of the text-shadow an <img> ignores. */
.sm-home-hero-content .sm-home-title-script {
    display: inline-block;
    height: 1em;
    width: auto;
    max-width: 100%;
    margin-top: 0.15em;
    vertical-align: top;
    filter: drop-shadow(0 2px 10px rgba(0,0,0,0.55));
}

.sm-home-sub {
    color: rgba(255,255,255,0.88);
    font-size: clamp(1.5rem, 3.75vw, 1.8rem);
    max-width: 560px;
    margin: 0 0 2.5rem;
    line-height: 1.4;
    /* Splits the line evenly when it wraps rather than leaving a word or two on its own. */
    text-wrap: balance;
    text-shadow: 0 1px 8px rgba(0,0,0,0.5), 0 1px 6px rgba(0,0,0,0.25);
}

/* On desktop the line always wraps once, and plain wrapping fills the first line up to "with",
   which reads better than balance's even split that pushes "with" down. */
@media (min-width: 769px) {
    .sm-home-sub { text-wrap: wrap; }
}

.sm-hero-actions {
    display: flex;
    gap: 1rem;
    justify-content: flex-start;
    flex-wrap: wrap;
}

.btn-sm-primary-hero {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-body);
    font-weight: 700;
    font-size: 1rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--sm-paper);
    background-color: var(--sm-coral);
    border: 2px solid var(--sm-coral);
    border-radius: var(--radius-pill);
    padding: 0.85rem 2.25rem;
    min-height: 52px;
    text-decoration: none;
    cursor: pointer;
    transition: background-color var(--t-base), border-color var(--t-base);
    line-height: 1;
}

.btn-sm-primary-hero:hover {
    background-color: var(--sm-orange);
    border-color: var(--sm-orange);
    color: var(--sm-paper);
    text-decoration: none;
}

/* The hero's Find button is the page's one big call to action, so it steps out of the pill system:
   larger, squarer, sentence case. A solid fill in the orange of the script "Entertainment" above
   it carries against a dark photo where a dark fill disappeared; its text and border are the SVG's
   own deep teal, since white or brand teal on orange fails contrast. Hover inverts.
   The below-fold Get Listed button keeps the standard coral pill. */
.sm-hero-actions .btn-sm-primary-hero {
    min-height: 72px;
    padding: 0.9rem 1.75rem;
    font-size: 1.75rem;
    letter-spacing: 0;
    text-transform: none;
    color: var(--sm-teal-deep);
    background-color: var(--sm-orange);
    border: 3px solid var(--sm-teal-deep);
    border-radius: var(--radius-card);
    box-shadow: 0 8px 24px rgba(0,0,0,0.35);
    transition: background-color var(--t-base), color var(--t-base), transform var(--t-base), box-shadow var(--t-base);
}

.sm-hero-actions .btn-sm-primary-hero:hover {
    color: var(--sm-orange);
    background-color: var(--sm-teal-deep);
    border-color: var(--sm-orange);
    transform: translateY(-2px);
    box-shadow: 0 12px 32px rgba(0,0,0,0.4);
}

/* ── Homepage: below-fold sections ───────────────────────── */

.sm-home-about {
    background-color: var(--sm-paper);
    padding: 5rem 0 4rem;
}

.sm-home-about .sm-home-section-heading {
    margin-bottom: 1.5rem;
}

.sm-home-about-text {
    max-width: 700px;
    margin: 0 auto;
    text-align: center;
    font-size: var(--fs-base);
    color: var(--sm-ink-soft);
    line-height: 1.75;
}

.sm-home-how-it-works {
    background-color: var(--sm-sand-light);
    padding: 5rem 0 4rem;
}

.sm-home-section-heading {
    text-align: center;
    font-size: clamp(1.6rem, 3.5vw, 2.2rem);
    color: var(--sm-teal);
    margin-bottom: 3rem;
}

.sm-home-steps {
    display: grid;
    /* card · arrow · card · arrow · card */
    grid-template-columns: 1fr auto 1fr auto 1fr;
    gap: 1rem;
}

.sm-home-step-arrow {
    align-self: center;
    color: var(--sm-teal);
    opacity: 0.45;
}

.sm-home-step-arrow svg {
    display: block;
    width: 34px;
    height: 26px;
}

.sm-home-step-card {
    background: var(--sm-paper);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);
    padding: 2.25rem 1.75rem;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.sm-home-step-icon {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background-color: var(--sm-aqua-tint);
    color: var(--sm-teal);
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 1.25rem;
}

.sm-home-step-icon svg {
    width: 26px;
    height: 26px;
}

.sm-home-step-card h3 {
    font-size: 1.1rem;
    color: var(--sm-teal);
    margin-bottom: 0.6rem;
}

.sm-home-step-card p {
    font-size: var(--fs-base);
    color: var(--sm-ink-soft);
    line-height: 1.6;
    max-width: 260px;
    margin: 0 auto;
}

.sm-home-entertainer-cta {
    background-color: var(--sm-paper);
    padding: 5rem 0 4rem;
}

.sm-home-entertainer-cta-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 2rem;
    flex-wrap: wrap;
}

/* Takes the whole row minus the button, so the heading gets the ~950px it needs
   to stay on one line. The reading measure lives on the paragraph below. */
.sm-home-entertainer-cta-copy {
    flex: 1 1 30rem;
}

.sm-home-entertainer-cta-inner h2 {
    color: var(--sm-teal);
    font-size: clamp(1.4rem, 3vw, 2rem);
    margin-bottom: 0.6rem;
    /* Only bites once the row is too narrow for one line — then it splits evenly
       instead of leaving a stub on the second line. */
    text-wrap: balance;
}

.sm-home-entertainer-cta-inner p {
    color: var(--sm-ink-soft);
    font-size: 1rem;
    /* Wide enough to hold this copy to two lines, narrow enough to stay readable. */
    max-width: 45rem;
    margin: 0;
    line-height: 1.6;
    /* Keeps the last line from ending on a single orphaned word. */
    text-wrap: pretty;
}

/* ── Directory grid ───────────────────────────────────────── */

/* Two shared rows — label, control — that every filter and the button subgrid into, so the boxes
   sit on one line even where a column has no label above it. Postcode is a 4-digit value, so it is capped rather than stretched; the type dropdown takes
   what is left. */
.sm-search-bar {
    background: var(--sm-paper);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);
    padding: 1.25rem 1.5rem;
    display: grid;
    grid-template-columns: minmax(9rem, 11rem) minmax(12rem, 1fr) auto auto;
    column-gap: 1.5rem;
    row-gap: 0;
    margin-bottom: 2rem;
}

.sm-search-bar > * {
    grid-row: span 2;
    display: grid;
    grid-template-rows: subgrid;
    min-width: 0;
}
/* Search field labels — same tier as .sm-form-label */
.sm-search-bar .sm-field label { font-weight: 600; font-size: var(--fs-base); margin-bottom: 0.3rem; display: block; color: var(--sm-ink-soft); }
.sm-search-bar .sm-form-select { height: var(--control-height); }
/* Spans the label row as well as the control row, so it centres on the whole bar rather than
   lining up with the inputs. */
.sm-search-bar .sm-search-action .btn-sm-primary { grid-row: 1 / span 2; align-self: center; justify-self: end; }

/* Voluntary-bookings checkbox filter. It has no heading label, so the first row stays empty and
   the placement is explicit: auto-placement would lift the checkbox into it. */
.sm-search-bar .sm-search-check label {
    grid-row: 2;
    display: flex;
    align-items: center;
    min-height: var(--control-height);
    box-sizing: border-box;
    gap: 0.5rem;
    margin-bottom: 0;
    cursor: pointer;
}
.sm-search-bar .sm-search-check input {
    flex-shrink: 0;
    width: 1.1rem;
    height: 1.1rem;
    accent-color: var(--sm-teal);
}

.sm-entertainer-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 1.5rem;
}

.sm-entertainer-card {
    background: var(--sm-paper);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);
    overflow: hidden;
    transition: box-shadow var(--t-base), transform var(--t-base);
    display: flex;
    flex-direction: column;
}

.sm-entertainer-card:hover {
    box-shadow: var(--shadow-card-hover);
    transform: translateY(-3px);
}

/* Square on purpose. Uploads skew portrait — phone photos of a performer, promo headshots —
   and a fixed pixel height against a fluid grid column made the crop drift from 1.4:1 to
   nearly 3:1 across breakpoints. A 1:1 window is constant and keeps ~75% of a 3:4 portrait
   in frame where the old 220px box kept 45%. */
.sm-card-img-wrap {
    aspect-ratio: 1 / 1;
    /* Safety valve for the narrow band (~640-672px) where auto-fill can fit neither two
       300px columns nor the 1fr rule below 640, and one card spans the full width. Never
       engages at normal column widths (368px at desktop, 342px on a phone). */
    max-height: 460px;
    overflow: hidden;
    background-color: var(--sm-aqua-tint);
}

/* The image is wrapped in a link — block it out so it fills the square box. */
.sm-card-img-wrap a {
    display: block;
    height: 100%;
}

.sm-card-img-wrap img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.sm-card-body {
    padding: 1.25rem;
    flex: 1;
    display: flex;
    flex-direction: column;
}

/* The square image gives the card enough visual mass to carry a bigger name; at 1.15rem it
   read as a caption under the photo rather than the heading of a listing. */
.sm-card-body h3 {
    font-size: 1.4rem;
    margin-bottom: 0.25rem;
    color: var(--sm-teal);
}

.sm-card-location {
    font-size: var(--fs-sm);
    color: var(--sm-ink-soft);
    margin-bottom: 0.6rem;
}

.sm-card-location svg { vertical-align: -2px; margin-right: 3px; }

.sm-card-types { margin-bottom: 1rem; flex: 1; }

.sm-card-footer {
    padding-top: 1rem;
    border-top: 1px solid var(--sm-sand-light);
}

/* Name/location on the left, "From $X" price on the right */
.sm-card-heading {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
}

.sm-card-heading-text { min-width: 0; }

.sm-card-fee {
    flex-shrink: 0;
    text-align: right;
    white-space: nowrap;
    font-size: var(--fs-sm);
    line-height: 1.2;
    color: var(--sm-ink-soft);
}

/* Deliberately a step below the name (1.4rem) rather than matching it. Results are ordered by
   fee, so the price has to stay prominent — but it shouldn't compete with the name for the
   first read. The teal Playfair name against this ink sans price separates them further. */
.sm-card-fee strong {
    display: block;
    font-size: 1.25rem;
    color: var(--sm-ink);
}

/* ── Directory pagination ─────────────────────────────────── */

.sm-pagination {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    margin-top: 2.5rem;
}

.sm-page-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 44px square is the WCAG 2.1 AA target size — these sit close together on a phone. */
    min-width: 44px;
    min-height: 44px;
    padding: 0 0.85rem;
    border: 1px solid var(--sm-sand);
    border-radius: var(--radius-pill);
    background: var(--sm-paper);
    color: var(--sm-teal);
    font-size: var(--fs-sm);
    font-weight: 600;
    text-decoration: none;
    transition: background-color var(--t-base), border-color var(--t-base);
}

.sm-page-link:hover {
    background: var(--sm-sand-light);
    color: var(--sm-teal);
    text-decoration: none;
}

.sm-page-link--current,
.sm-page-link--current:hover {
    background: var(--sm-teal);
    border-color: var(--sm-teal);
    color: var(--sm-paper);
}

/* Rendered as a span, not a disabled link — there is no previous page to point at. */
.sm-page-link--disabled {
    color: var(--sm-ink-soft);
    opacity: 0.45;
    background: transparent;
}

.sm-page-gap {
    padding: 0 0.25rem;
    color: var(--sm-ink-soft);
}

/* ── Profile page ─────────────────────────────────────────── */

.sm-profile-layout {
    display: grid;
    grid-template-columns: 1fr 360px;
    gap: 2rem;
    align-items: start;
}

/* Entertainer name on the left, "From $X" price across from it on the right */
.sm-profile-name-row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
}

.sm-profile-fee {
    flex-shrink: 0;
    text-align: right;
    white-space: nowrap;
    font-size: var(--fs-sm);
    line-height: 1.2;
    color: var(--sm-ink-soft);
    padding-top: 0.35rem;
}

.sm-profile-fee strong {
    display: block;
    font-size: 1.75rem;
    color: var(--sm-teal); /* matches the name colour */
}

.sm-profile-gallery {
    border-radius: var(--radius-card);
    overflow: hidden;
    background-color: var(--sm-aqua-tint);
    margin-bottom: 1.5rem;
}

/* The profile is the one page where the photo is the point, so it is contained rather than
   cropped — whatever doesn't fill the box letterboxes onto the gallery's aqua tint. The box
   keeps a fixed ratio so swapping thumbnails doesn't jump the page; because nothing is ever
   cropped, changing that ratio at a breakpoint only moves the surround, not the subject.
   Deliberately no object-position here: under `contain` it would shove a pillarboxed portrait
   against one edge instead of centring it (see Profile.razor). */
.sm-profile-gallery-primary {
    width: 100%;
    aspect-ratio: 3 / 2;
    object-fit: contain;
    display: block;
}

.sm-profile-gallery-thumbs {
    display: flex;
    gap: 8px;
    padding: 8px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
}

.sm-profile-gallery-thumbs img {
    height: 80px;
    width: 80px;
    object-fit: cover;
    border-radius: var(--radius-sm);
    cursor: pointer;
    scroll-snap-align: start;
    opacity: 0.75;
    transition: opacity var(--t-fast);
}

.sm-profile-gallery-thumbs img:hover,
.sm-profile-gallery-thumbs img.active { opacity: 1; }

.sm-profile-sidebar {
    background: var(--sm-paper);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);
    padding: 1.5rem;
    position: sticky;
    top: 80px;
}

.sm-profile-actions {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin-bottom: 1.5rem;
}

.sm-profile-represented {
    margin: 0;
    text-align: center;
    color: var(--sm-ink-soft);
    font-size: var(--fs-sm);
}

.sm-social-links { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: var(--sp-3); }

/* These are .btn-sm-outline pills, one step down in size to suit a sidebar. Everything about
   their shape — the border, the radius, the hover fill — comes from the button base in
   brand.css; this block used to restate all of it and had drifted to a 40px height and its own
   letter-spacing. */
.sm-social-link {
    font-size: var(--fs-xs);
    letter-spacing: 0.04em;
    padding: var(--sp-2) 1.1rem;
    min-height: 40px;
}

.sm-social-link svg { width: 1rem; height: 1rem; flex-shrink: 0; }

/* ── Register flow ────────────────────────────────────────── */

/* Two fields on one line (first/last name); single column on phones. */
.sm-form-row-2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
    align-items: start;
}

@media (max-width: 480px) {
    .sm-form-row-2 { grid-template-columns: 1fr; }
}

/* ── Registration progress ────────────────────────────────── */

.sm-reg-progress-bar {
    height: 5px;
    background: var(--sm-sand-light);
    border-radius: var(--radius-pill);
    overflow: hidden;
    margin-bottom: 1.5rem;
}

.sm-reg-progress-fill {
    height: 100%;
    background: var(--sm-teal);
    border-radius: var(--radius-pill);
    transition: width var(--t-slow) ease;
}

/* ── Service range slider ─────────────────────────────────── */

.sm-service-range {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    height: 2.2rem;
    background: transparent;
    outline: none;
    padding: 0;
    margin: 0;
    display: block;
    cursor: pointer;
}

.sm-service-range::-webkit-slider-runnable-track {
    height: 4px;
    background: transparent;
    border: none;
}

.sm-service-range::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 1.8rem;
    height: 1.8rem;
    border-radius: 50%;
    background: var(--sm-teal);
    border: 3px solid #fff;
    box-shadow: 0 2px 8px rgba(0,0,0,0.18);
    margin-top: calc((4px - 1.8rem) / 2);
    cursor: pointer;
    transition: box-shadow var(--t-fast);
}

.sm-service-range:hover::-webkit-slider-thumb,
.sm-service-range:focus::-webkit-slider-thumb {
    box-shadow: 0 3px 12px color-mix(in srgb, var(--sm-teal) 40%, transparent);
}

.sm-service-range::-moz-range-track {
    height: 4px;
    background: transparent;
    border: none;
}

.sm-service-range::-moz-range-thumb {
    width: 1.8rem;
    height: 1.8rem;
    border-radius: 50%;
    background: var(--sm-teal);
    border: 3px solid #fff;
    box-shadow: 0 2px 8px rgba(0,0,0,0.18);
    box-sizing: border-box;
    cursor: pointer;
    transition: box-shadow var(--t-fast);
}

.sm-service-range:hover::-moz-range-thumb,
.sm-service-range:focus::-moz-range-thumb {
    box-shadow: 0 3px 12px color-mix(in srgb, var(--sm-teal) 40%, transparent);
}

/* ── Modal ────────────────────────────────────────────────── */

.sm-modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.45);
    z-index: 500;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}

.sm-modal {
    background: var(--sm-paper);
    border-radius: var(--radius-card);
    box-shadow: 0 12px 48px rgba(0,0,0,0.2);
    max-width: 560px;
    width: 100%;
    padding: 2rem;
}

.sm-modal h2 {
    font-size: var(--fs-h3);
    margin: 0 0 var(--sp-5);
}

/* Title on the left, close button on the right. The title's own margin is dropped: the row
   carries the spacing, so the two sit on one baseline however long the title runs. */
.sm-modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--sp-3);
    margin-bottom: var(--sp-3);
}

.sm-modal-header h2 { margin: 0; }

/* One-time code entry (the SMS verification modal). Tracking and centring only — the size stays the
   base input size, like every other field, so nothing here sets a font-size on an input. */
.sm-code-input {
    max-width: 180px;
    letter-spacing: 0.3em;
    text-align: center;
    font-weight: 600;
}

/* ── Demo Turnstile widget ────────────────────────────────── */

.cf-widget {
    display: flex;
    align-items: center;
    justify-content: space-between;
    border: 1px solid #d9d9d9;
    border-radius: 4px;
    background: #fafafa;
    padding: 10px 14px;
    max-width: 300px;
    min-height: 64px;
    margin-bottom: 1rem;
}

.cf-widget-left {
    display: flex;
    align-items: center;
    gap: 10px;
}

.cf-widget-clickable { cursor: pointer; }

.cf-check-box {
    width: 28px;
    height: 28px;
    border: 1.5px solid #9b9b9b;
    border-radius: 2px;
    background: #fff;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: border-color var(--t-fast);
}

.cf-widget-clickable:hover .cf-check-box { border-color: #444; }

.cf-check-box--done {
    background: #31b447;
    border-color: #31b447;
    color: #fff;
    font-size: 1rem;
}

.cf-widget-label {
    font-size: 0.875rem;
    color: var(--sm-ink);
    font-family: var(--font-body);
}

.cf-spin-box {
    width: 28px;
    height: 28px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

.cf-spin-ring {
    width: 24px;
    height: 24px;
    border: 2px solid #e0e0e0;
    border-top-color: #f38020;
    border-radius: 50%;
    animation: cf-spin 0.8s linear infinite;
}

@keyframes cf-spin { to { transform: rotate(360deg); } }

.cf-widget-brand {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 2px;
    margin-left: 12px;
    flex-shrink: 0;
}

.cf-widget-brand-logo {
    font-size: 0.7rem;
    font-weight: 700;
    color: #f38020;
    letter-spacing: 0.02em;
    font-family: var(--font-body);
}

.cf-widget-brand-sub {
    font-size: 0.6rem;
    color: #aaa;
    font-family: var(--font-body);
}

/* ── Misc ─────────────────────────────────────────────────── */

.sm-section-title { margin-bottom: 1.5rem; }
.sm-divider { border: none; border-top: 1px solid var(--sm-sand); margin: 2rem 0; }

.sm-empty-state {
    text-align: center;
    padding: 4rem 2rem;
    color: var(--sm-ink-soft);
}

.sm-empty-state svg { color: var(--sm-aqua); margin-bottom: var(--sp-4); }
.sm-empty-state h2 { font-size: var(--fs-h3); color: var(--sm-ink-soft); }

/* ── Responsive ───────────────────────────────────────────── */

@media (max-width: 768px) {
    /* Postcode and type on one line, the checkbox and button on the next. */
    .sm-search-bar { grid-template-columns: 1fr 1fr; }
    .sm-search-bar > :nth-child(n+3) { margin-top: 1rem; }
    .sm-profile-layout { grid-template-columns: 1fr; }
    .sm-profile-sidebar { position: static; padding: 0; background: none; box-shadow: none; }
    /* Contact buttons float as a fixed bottom bar, side by side */
    .sm-profile-actions {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 50;
        flex-direction: row;
        gap: 0.6rem;
        margin: 0;
        padding: 0.75rem 1rem calc(0.75rem + env(safe-area-inset-bottom));
        background: var(--sm-paper);
        box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.12);
    }
    .sm-profile-actions .btn-sm-primary,
    .sm-profile-actions .btn-sm-outline { flex: 1; width: auto; padding-left: 0.75rem; padding-right: 0.75rem; }
    .sm-profile-actions .sm-profile-represented { flex: 1; align-self: center; }
    /* Clearance for the fixed contact bar */
    .sm-page:has(.sm-profile-layout) { padding-bottom: 0; }
    body:has(.sm-profile-actions) .sm-site-footer { padding-bottom: 5.5rem; }
    .sm-footer-cols { grid-template-columns: 1fr 1fr; }
    /* Hero shrinks to its content on mobile */
    body:has(.sm-home-hero) .sm-home-hero { min-height: auto; }
    body:has(.sm-home-hero) .sm-home-hero-content { padding-top: 5.5rem; }
    .sm-home-hero-content { padding: 3rem 1.5rem 4rem; }
    /* Stacked: arrows rotate to point down the column */
    .sm-home-steps { grid-template-columns: 1fr; gap: 0.75rem; }
    .sm-home-step-arrow { justify-self: center; }
    .sm-home-step-arrow svg { transform: rotate(90deg); width: 30px; height: 23px; }
    .sm-home-entertainer-cta-inner { flex-direction: column; text-align: center; }
    /* Stacked, the flex-basis would apply to height — drop it back to content size. */
    .sm-home-entertainer-cta-copy { flex: 0 1 auto; }
    .sm-home-entertainer-cta-inner p { margin: 0 auto; }
}

/* Dense header: shrink the brand title and logo */
@media (max-width: 900px) {
    .sm-site-header--dense .sm-header-title { height: 30px; }
    .sm-site-header--dense .sm-logo-compact { height: 48px; }
    .sm-site-header--dense .sm-nav-links a { padding: 0.5rem 0.55rem; }
}

@media (max-width: 640px) {
    .sm-entertainer-grid { grid-template-columns: 1fr; }
    /* Squarer box on a phone: at ~342px wide a 3:2 frame would pillarbox a portrait photo
       down to a sliver. Nothing is cropped either way — this only tightens the surround. */
    .sm-profile-gallery-primary { aspect-ratio: 1 / 1; }
    .sm-footer-cols { grid-template-columns: 1fr; }
    /* Mobile header is brand only — no nav links */
    .sm-nav-links { display: none; }
    .sm-nav-inner { padding: 0 1rem; }
    .sm-logo { height: 40px; }
    .sm-logo-compact { height: 48px; }
    .sm-header-brand { gap: 0.6rem; }
    .sm-header-title,
    .sm-site-header--dense .sm-header-title { height: 26px; }
    /* One column: nothing sits beside anything, so the shared rows buy nothing — plain stacking. */
    .sm-search-bar { display: flex; flex-direction: column; gap: 1rem; }
    .sm-search-bar > * { display: block; }
    /* Nothing beside it to match the height of. */
    .sm-search-bar .sm-search-check label { min-height: 0; }
    .sm-search-bar .sm-search-action .btn-sm-primary { width: 100%; }
    .sm-home-hero-content { padding: 2.5rem 1.25rem 4rem; text-align: center; }
    .sm-home-sub { margin-left: auto; margin-right: auto; }
    .sm-hero-actions { justify-content: center; }
}

/* Override Bootstrap defaults to use brand styles */
.form-control:focus { border-color: var(--sm-teal); box-shadow: var(--glow-input); }
.form-select:focus { border-color: var(--sm-teal); box-shadow: var(--glow-input); }

/* Blazor validation — keep in step with .sm-validation-msg in brand.css */
.validation-message { color: var(--sm-coral-ink); font-size: var(--fs-sm); font-weight: 600; line-height: 1.5; margin-top: 0.25rem; }
.field-validation-error { color: var(--sm-coral-ink); font-size: var(--fs-sm); font-weight: 600; }
input.invalid, select.invalid, textarea.invalid,
input.modified.invalid, select.modified.invalid, textarea.modified.invalid { border-color: var(--sm-coral) !important; }
