/* SINGLE SOURCE OF TRUTH for the vertical-rhythm spacing shared between the
   published tenant site's static-page body copy (Publisher's _base.css,
   "main .body" rules) and the Admin Quill editor (.ql-editor rules in app.css).
   Change values here, not in either consumer — see the drift-guard test in
   test/ChurchMatters.Tests/SiteStylesheetBuilderTests.cs.

   Spacing/line-height tokens ONLY — no font, color, or text-size tokens. Those
   stay theme-specific in Publisher and Admin-specific in the editor by design
   (the editor intentionally does not adopt tenant fonts/colors).

   --prose-line-height is consumed ONLY by the Admin editor, as a fixed
   theme-agnostic approximation. Publisher's published line-height remains
   driven by each theme's own --line-height-body (1.55-1.75) — untouched here. */
:root {
    --prose-line-height: 1.6;

    --prose-space-p: 1rem;

    --prose-space-h1: 2rem 0 1rem;
    --prose-space-h2: 1.75rem 0 0.85rem;
    --prose-space-h3: 1.5rem 0 0.75rem;
    --prose-space-h4: 1.25rem 0 0.6rem;
    --prose-space-h5: 1rem 0 0.5rem;
    --prose-space-h6: 1rem 0 0.5rem;

    --prose-space-list: 1rem;         /* margin-bottom on ul/ol */
    --prose-space-list-item: 0.35rem; /* margin-bottom on li */

    --prose-space-blockquote: 1rem;   /* margin-bottom on blockquote */
}


/* ChurchMatters tenant site — base structural CSS shared by all 9 public site
   templates and every theme. This file is assembled first (see
   SiteStylesheetBuilder), before the tenant's chosen theme.css and finally a
   generated :root block of --color-* custom properties from the tenant's chosen
   color scheme.

   HARD INVARIANT: this file must never contain a color literal (#hex, rgb()/
   rgba(), hsl(), or a bare color name like white/black) — every color reference
   here must be one of the --color-* tokens below, supplied at render time by
   SiteStylesheetBuilder from ColorSchemeCssTokens (Domain, the single source). Typography/spacing/shape tokens
   (--font-*, --text-*, --font-weight-*, --radius-*) are defined per-theme in
   theme-{key}.css, not here.

   Token names used throughout: --color-primary, --color-primary-strong,
   --color-on-primary, --color-accent, --color-bg, --color-surface, --color-text,
   --color-muted, --color-border, plus the band tokens --color-header-bg,
   --color-header-fg, --color-header-fg-muted, --color-footer-bg, --color-footer-fg,
   --color-footer-fg-muted and the title-card tokens --color-title-card-start,
   --color-title-card-end, --color-title-card-ink. */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

body {
    font-family: var(--font-body);
    font-weight: var(--font-weight-body);
    line-height: var(--line-height-body);
    color: var(--color-text);
    background: var(--color-bg);
}

/* Links default to the church's primary colour rather than the browser's blue (body copy,
   imported WordPress content, the contact page's Maps link). Element selectors, so every
   component rule below still wins; header/footer bands get their own band colours. */
a { color: var(--color-primary); }
a:hover { color: var(--color-primary-strong); }
header a { color: var(--color-header-fg); }
footer a { color: var(--color-footer-fg-muted); }

.container { max-width: 900px; margin: 0 auto; padding: 0 1.5rem; }

/* ── Header / nav (identical across every template) ──────────────────────── */
header {
    background: var(--color-header-bg);
    border-bottom: 1px solid var(--color-border);
    padding: 1rem 0;
}
header .inner { display: flex; align-items: center; justify-content: space-between; }
header .site-name {
    font-family: var(--font-heading);
    font-size: var(--text-lg);
    font-weight: var(--font-weight-heading);
    color: var(--color-header-fg);
}
/* Logo + org name group (only rendered when the org has an uploaded logo — see
   SiteChrome.Header/SiteViewModel.LogoUrl). Wrapped in .brand so header .inner's
   flex/space-between still sees two children (brand, nav) instead of the logo
   floating away from the heading it sits beside. */
/* The whole brand is the home link (.brand-link wraps .site-name or .brand): no link styling,
   a visible keyboard focus ring, and it must not break the logo-size or phone layouts below. */
header .brand-link {
    display: flex;
    align-items: center;
    min-width: 0;
    color: inherit;
    text-decoration: none;
    border-radius: 4px;
}
header .brand-link:hover { text-decoration: none; }
header .brand-link:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }
header.header--logo-stretched .brand-link { align-self: stretch; }
header.header--logo-own-row .brand-link { max-width: 100%; justify-content: center; }
header .brand { display: flex; align-items: center; gap: 0.75rem; }
.site-logo { height: 40px; width: auto; }

/* Logo sizes (Organization.LogoSize; SiteChrome.Header adds the modifier class only when a
   logo is uploaded and the size is not inline, so inline output is untouched). The heights
   here must match ChurchMatters.Domain.Theming.LogoSizes.DisplayHeightPx (40/80/96); a test
   keeps them in step.
   stretched: the logo fills the header height, 80px tall, with 3px breathing space above and below.
   own-row:   brand centred on its own row, nav centred underneath, logo up to 96px tall. */
header.header--logo-stretched { padding: 3px 0; }
header.header--logo-stretched .inner { min-height: 80px; }
header.header--logo-stretched .site-logo { height: 80px; max-width: 60vw; object-fit: contain; }
header.header--logo-stretched .brand { min-width: 0; align-self: stretch; }

header.header--logo-own-row .inner {
    flex-direction: column;
    justify-content: center;
    gap: 0.75rem;
}
header.header--logo-own-row .brand {
    flex-direction: column;
    justify-content: center;
    text-align: center;
    max-width: 100%;
    gap: 0.5rem;
}
header.header--logo-own-row .site-logo { height: 96px; max-width: min(100%, 480px); object-fit: contain; }
header.header--logo-own-row nav {
    align-self: stretch;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    column-gap: 1.5rem;
    row-gap: 0.25rem;
}
header.header--logo-own-row nav a,
header.header--logo-own-row nav details.nav-dropdown { margin-left: 0; }
nav a {
    margin-left: 1.5rem;
    color: var(--color-header-fg-muted);
    text-decoration: none;
    font-size: var(--text-base);
}
nav a:hover { color: var(--color-header-fg); }

/* Section dropdowns (About / Community / Resources; only rendered when a section
   has 2+ children — see SiteChrome.Header). */
nav details.nav-dropdown {
    position: relative;
    display: inline-block;
    margin-left: 1.5rem;
}
nav details.nav-dropdown > summary {
    cursor: pointer;
    color: var(--color-header-fg-muted);
    font-size: var(--text-base);
    list-style: none;
}
nav details.nav-dropdown > summary::-webkit-details-marker { display: none; }
nav details.nav-dropdown > summary:hover,
nav details.nav-dropdown[open] > summary { color: var(--color-header-fg); }
nav details.nav-dropdown .nav-dropdown-menu {
    position: absolute;
    top: 100%;
    left: 0;
    display: flex;
    flex-direction: column;
    min-width: 200px;
    margin-top: 0.5rem;
    padding: 0.5rem 0;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: 0 4px 12px var(--color-border);
    z-index: 20;
}
nav details.nav-dropdown .nav-dropdown-menu a {
    margin: 0;
    padding: 0.5rem 1rem;
    color: var(--color-text);
}
nav details.nav-dropdown .nav-dropdown-menu a:hover { color: var(--color-primary); }

/* Nav can carry up to 8 top-level items (Home, Teachings, Events, About, Community,
   Resources, Give, Contact) plus the org logo/name — on a phone
   width that overflows a single no-wrap flex row. Let the header wrap to a
   second line and give nav its own wrapping flex layout (gap instead of
   margin-left, so wrapped rows don't inherit a lopsided leading margin), with
   extra vertical padding on each link so the tap target clears the 44px
   minimum touch-target guideline. */
/* Header tools (search icon + Menu button) exist for phones only; hidden on desktop. */
.header-tools { display: none; }
.nav-toggle { display: none; }

/* Phones: one header row (brand left, search + Menu right) with the nav as a stacked
   drop-down panel directly beneath it. Without JS the panel simply stays expanded in flow
   (.js-nav, set by the inline script in SiteChrome.Header, is what enables the collapse).
   Applies to all three logo sizes; desktop (>640px) is untouched. */
@media (max-width: 640px) {
    header { position: relative; padding: 0.25rem 0; }
    header .inner,
    header.header--logo-own-row .inner,
    header.header--logo-stretched .inner {
        flex-direction: row;
        flex-wrap: wrap;
        align-items: center;
        justify-content: space-between;
        gap: 0;
        min-height: 56px;
        padding-top: 0;
    }
    header .brand,
    header.header--logo-own-row .brand,
    header.header--logo-stretched .brand {
        flex-direction: row;
        text-align: left;
        align-self: center;
        height: auto;
        min-width: 0;
        flex: 1 1 auto;
        gap: 0.5rem;
    }
    header .brand-link,
    header.header--logo-own-row .brand-link,
    header.header--logo-stretched .brand-link { flex: 1 1 auto; align-self: center; justify-content: flex-start; }
    .site-logo,
    header.header--logo-stretched .site-logo,
    header.header--logo-own-row .site-logo { height: auto; max-height: 48px; max-width: 55vw; object-fit: contain; }
    header .site-name { font-size: var(--text-base); }

    .header-tools { display: flex; align-items: center; gap: 0.25rem; margin-left: auto; }
    .header-tools a.nav-search { display: none; }
    .js-nav .header-tools a.nav-search { display: inline-flex; }
    .js-nav nav a.nav-search { display: none; }
    .js-nav .nav-toggle {
        display: inline-flex;
        align-items: center;
        gap: 0.4rem;
        min-height: 44px;
        padding: 0 0.5rem;
        background: transparent;
        border: 0;
        color: var(--color-header-fg);
        font: inherit;
        font-size: var(--text-base);
        cursor: pointer;
    }
    .nav-toggle svg { display: block; }
    .nav-toggle:focus-visible,
    nav a:focus-visible,
    nav details.nav-dropdown > summary:focus-visible,
    .header-tools a:focus-visible { outline: 2px solid currentColor; outline-offset: -2px; }

    nav,
    header.header--logo-own-row nav {
        order: 3;
        flex: 0 0 100%;
        display: flex;
        flex-direction: column;
        flex-wrap: nowrap;
        align-self: stretch;
        justify-content: flex-start;
        padding: 0.25rem 0 0.5rem;
        border-top: 1px solid var(--color-border);
    }
    .js-nav nav,
    .js-nav header.header--logo-own-row nav {
        display: none;
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        z-index: 30;
        padding: 0.25rem 1rem 0.5rem;
        background: var(--color-header-bg);
        border-bottom: 1px solid var(--color-border);
    }
    .js-nav header.nav-open nav { display: flex; }

    nav a,
    header.header--logo-own-row nav a {
        display: flex;
        align-items: center;
        margin: 0;
        padding: 0 0.25rem;
        min-height: 48px;
        color: var(--color-header-fg-muted);
    }
    nav a:hover { color: var(--color-header-fg); }
    nav a.nav-search { min-width: 0; justify-content: flex-start; }

    nav details.nav-dropdown,
    header.header--logo-own-row nav details.nav-dropdown { display: block; position: static; margin: 0; }
    nav details.nav-dropdown > summary {
        display: flex;
        align-items: center;
        justify-content: space-between;
        min-height: 48px;
        padding: 0 0.25rem;
    }
    nav details.nav-dropdown > summary::after { content: "\25B8"; }
    nav details.nav-dropdown[open] > summary::after { content: "\25BE"; }
    nav details.nav-dropdown .nav-dropdown-menu {
        position: static;
        min-width: 0;
        margin: 0;
        padding: 0 0 0.25rem 1rem;
        background: transparent;
        border: 0;
        border-radius: 0;
        box-shadow: none;
    }
    nav details.nav-dropdown .nav-dropdown-menu a {
        padding: 0 0.25rem;
        min-height: 44px;
        color: var(--color-header-fg-muted);
    }
    nav details.nav-dropdown .nav-dropdown-menu a:hover { color: var(--color-header-fg); }
}

/* ── Hero (home page) ──────────────────────────────────────────────────── */
.hero { padding: 4rem 0 2rem; text-align: center; }
.hero h1 {
    font-family: var(--font-heading);
    font-size: var(--text-3xl);
    font-weight: var(--font-weight-display);
    margin-bottom: 0.75rem;
}
.hero p { color: var(--color-muted); font-size: 1.1rem; }

/* ── Home CTA slider (optional, above the .hero banner — Organization.HomeCtaSliderEnabled,
   gated by Feature.HomeCtaSlider). Degrades to a static single banner — no rotation, no
   dots — when only one slide is configured; see assets/home-cta-slider.js.

   Every color below MUST come from the 9 --color-* tokens (SiteStylesheetBuilderTests'
   ThemeCssFiles_ContainNoHardcodedColorLiterals forbids hex/rgb/hsl/named-color literals
   in this file) — the dark legibility scrim over the background image is therefore built
   from --color-text at reduced `opacity` on a separate ::before layer, not an rgba()
   literal, so the slide's own text (a sibling layer, not a child of the dimmed one) stays
   fully opaque. ─────────────────────────────────────────────────────────────────────── */
.cta-slider { position: relative; width: 100%; min-height: 420px; overflow: hidden; }

/* Only the .active slide and the outgoing .leaving one are ever visible, so the incoming
   slide always lands on top of the one it replaces. (Before this, every inactive slide stayed
   visible at z-index 0 and painted in DOM order, so the last slide flashed through during
   1→2.) The image sits on its own .cta-slide-bg layer so Ken Burns can scale it without
   scaling the text. The modifier is Model.HomeCtaSliderTransition (SliderTransitions). */
.cta-slide {
    position: absolute;
    inset: 0;
    overflow: hidden;
    background-color: var(--color-primary-strong);
    visibility: hidden;
    z-index: 0;
}
.cta-slide.leaving { visibility: visible; z-index: 1; }
.cta-slide.active { visibility: visible; z-index: 2; }
.cta-slide-bg {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
}

/* Durations must match TRANSITION_MS in assets/home-cta-slider.js. */
@keyframes cta-slide-enter {
    from { transform: translateX(100%); }
    to { transform: translateX(0); }
}
@keyframes cta-fade-enter {
    from { opacity: 0; }
    to { opacity: 1; }
}
.cta-slider--slide .cta-slide.entering { animation: cta-slide-enter 750ms ease-in-out; }
.cta-slider--fade .cta-slide.entering,
.cta-slider--ken-burns .cta-slide.entering { animation: cta-fade-enter 1000ms ease-in-out; }

/* Ken Burns: a slow zoom and pan, longer than the 6s rotate interval plus the 1s fade so the
   photo never comes to rest while it shows. The same animation applies to .active and .leaving,
   so the outgoing photo keeps its zoom while it fades out instead of snapping back. Each slide
   pans a different way. */
@keyframes cta-ken-burns-1 {
    from { transform: scale(1) translate(0, 0); }
    to { transform: scale(1.12) translate(-2%, -1%); }
}
@keyframes cta-ken-burns-2 {
    from { transform: scale(1.12) translate(2%, 1%); }
    to { transform: scale(1) translate(0, 0); }
}
@keyframes cta-ken-burns-3 {
    from { transform: scale(1) translate(0, 0); }
    to { transform: scale(1.12) translate(1%, -2%); }
}
.cta-slider--ken-burns .cta-slide-bg { will-change: transform; }
.cta-slider--ken-burns .cta-slide:is(.active, .leaving) .cta-slide-bg { animation: cta-ken-burns-1 8s ease-out forwards; }
.cta-slider--ken-burns .cta-slide:nth-child(2):is(.active, .leaving) .cta-slide-bg { animation-name: cta-ken-burns-2; }
.cta-slider--ken-burns .cta-slide:nth-child(3):is(.active, .leaving) .cta-slide-bg { animation-name: cta-ken-burns-3; }

/* Reduced motion: no sliding and no zoom; every mode becomes a short crossfade. */
@media (prefers-reduced-motion: reduce) {
    .cta-slider .cta-slide.entering { animation: cta-fade-enter 400ms ease-in-out; }
    .cta-slider--ken-burns .cta-slide:is(.active, .leaving) .cta-slide-bg { animation: none; }
}
.cta-slide-overlay {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem 1rem;
}
.cta-slide-overlay::before {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--color-text);
    opacity: 0.45;
}
.cta-slide-content { position: relative; max-width: 640px; text-align: center; color: var(--color-on-primary); }
.cta-slide-content h2 {
    font-family: var(--font-heading);
    font-size: var(--text-3xl);
    font-weight: var(--font-weight-display);
    margin-bottom: 0.75rem;
}
.cta-slide-content p { font-size: 1.1rem; margin-bottom: 1.25rem; }
.cta-slide-button {
    position: relative;
    display: inline-block;
    background: var(--color-primary);
    color: var(--color-on-primary);
    padding: 0.75rem 1.75rem;
    border-radius: var(--radius-md);
    text-decoration: none;
    font-weight: 600;
}
.cta-dots {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 1rem;
    display: flex;
    justify-content: center;
    gap: 0.5rem;
    z-index: 3;
}
.cta-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    border: none;
    padding: 0;
    background: var(--color-on-primary);
    opacity: 0.5;
    cursor: pointer;
}
.cta-dot.active { opacity: 1; }

/* ── Home page intro (the Home system page's BodyHtml) ─────────────────── */
.page-intro {
    max-width: 700px;
    margin: 0 auto;
    padding-bottom: 2rem;
    text-align: center;
    color: var(--color-text);
}
.page-intro p { margin-bottom: 1rem; }

/* ── Livestream banner (home page, Model.Livestream.IsLive) ─────────────── */
.live-banner {
    background: var(--color-primary-strong);
    color: var(--color-on-primary);
    border-radius: var(--radius-md);
    padding: 1.5rem;
    text-align: center;
    margin-bottom: 1rem;
}
.live-banner p { margin-top: 0.5rem; }
.live-banner a { color: var(--color-on-primary); text-decoration: underline; }
.live-embed { position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; border-radius: var(--radius-md); }
.live-embed iframe { position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0; }

/* ── Section / card grid (home page) ───────────────────────────────────── */
section { padding: 2.5rem 0; }
section h3 {
    font-family: var(--font-heading);
    font-size: 1.3rem;
    font-weight: var(--font-weight-heading);
    margin-bottom: 1.25rem;
    border-bottom: 2px solid var(--color-primary);
    padding-bottom: 0.5rem;
}
.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 1rem; }
.card {
    background: var(--color-surface);
    border-radius: var(--radius-md);
    padding: 1.25rem;
    box-shadow: 0 1px 3px var(--color-border);
}
/* A card carrying a feature image (home.cshtml's latest-sermon/upcoming-events cards) —
   the image sits flush against the card's rounded top corners, unpadded; the rest of the
   card's content moves into .card-body so it keeps the padding .card itself no longer
   supplies. Cards with no image (Announcements/Giving/Small Groups on home.cshtml) are
   untouched — plain .card, no .has-media, no .card-body wrapper needed. */
.card.has-media { padding: 0; overflow: hidden; }
.card.has-media .card-body { padding: 1.25rem; }
/* Squared image corners get clipped to the card's own rounded corners by the card's
   overflow:hidden + border-radius above — no radius needed on .card-image itself. Covers
   both .event-card's and .card.has-media's .card-media wrapper. */
.card h4 { font-size: var(--text-md); font-weight: 600; margin-bottom: 0.4rem; }
.card p { font-size: 0.875rem; color: var(--color-muted); }
/* Scannable fact within a card — e.g. an event's date/time — gets the same
   primary-colored, bold treatment as .event-card .time on the dedicated events
   page, instead of reading identically to the rest of the card's muted text. */
.card p.highlight { color: var(--color-primary); font-weight: 600; }
.card a {
    display: inline-block;
    margin-top: 0.75rem;
    font-size: var(--text-sm);
    color: var(--color-primary);
    text-decoration: none;
    font-weight: 600;
}

/* ── Page headings, list pages (sermons/events/giving/groups/series —
   every template whose top-level content wrapper is <main class="container">).
   Higher specificity than the bare "main h2" rule below, so it wins wherever
   both apply. NOTE: series_detail.cshtml originally used a slightly tighter
   bottom padding (2rem 0 0.5rem vs 2rem 0 1rem elsewhere) — consolidated to the
   majority value here; see publisher-dev's report for this documented, purely
   cosmetic (non-color) deviation. ────────────────────────────────────────── */
main.container h1,
main.container h2 {
    font-family: var(--font-heading);
    font-size: var(--text-xl);
    font-weight: var(--font-weight-display);
    padding: 2rem 0 1rem;
}

/* ── Detail-page shell (sermon/page detail — narrower column, own background,
   not nested in .container) and its heading. ─────────────────────────────── */
main {
    padding: 3rem 1.5rem;
    max-width: 800px;
    margin: 0 auto;
    background: var(--color-surface);
    min-height: 70vh;
}
main h1,
main h2 {
    font-family: var(--font-heading);
    font-size: var(--text-2xl);
    font-weight: var(--font-weight-display);
    margin-bottom: 0.5rem;
}

/* ── Feature images (implementation-05-site-artwork-nav.md Phase 1) ──────
   SiteChrome.ImageCard/ItemThumb/FeatureBanner emit one of these 3 boxes — a real <img>,
   or (no feature image set) a .title-card <div> with the same box class, so a real photo
   and the gradient fallback line up identically in a grid/row/banner. object-fit: cover
   crops to the box; aspect-ratio (not width/height attrs — see FeatureImage's doc comment
   on why) is what reserves layout space before the image loads. */
.card-image, .item-thumb, .detail-banner { display: block; width: 100%; object-fit: cover; }
/* The <img> width/height attributes (real rendition sizes, set so the browser reserves space)
   map to a presentational height that beats aspect-ratio — height: auto lets the ratio below
   govern the box, with object-fit cropping the image into it. */
.card-image, .detail-banner { height: auto; }
/* Images inside admin-authored body HTML carry the editor's resize width (e.g. width="421")
   and would overflow a phone screen. Cap them to the column and keep their proportions;
   classed images (cards, thumbs, banners) size themselves above. */
main img { max-width: 100%; }
main img:not([class]) { height: auto; }
.card-image { aspect-ratio: 16 / 10; }
.item-thumb { width: 64px; height: 64px; aspect-ratio: 1 / 1; border-radius: var(--radius-sm); }
.detail-banner { aspect-ratio: 21 / 9; border-radius: var(--radius-md); margin-bottom: 1.5rem; }

/* The CSS title-card fallback — a themed gradient built from the --color-title-card-* tokens
   (this file's no-color-literal invariant, see the header comment) with the row/page title
   centered over it. No generated PNGs — see the plan's "Fallback" decision. */
.title-card {
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, var(--color-title-card-start), var(--color-title-card-end));
    padding: 0.5rem;
    text-align: center;
}
.title-card .title-card-text {
    font-family: var(--font-heading);
    font-weight: var(--font-weight-display);
    color: var(--color-title-card-ink);
    line-height: 1.3;
    font-size: var(--text-md);
}
.item-thumb.title-card .title-card-text { font-size: 0.55rem; }
.detail-banner.title-card .title-card-text { font-size: var(--text-2xl); }

/* ── Call to Action tiles (implementation-05 Phase 4) ─────────────────
   1-3 whole-tile links under Latest Sermons. 1 column on phones, up to 3 from 720px; the
   tile is one <a> (no nested links), so children are spans made block-level here. Reuses
   .card-image/.title-card for the artwork so photo and fallback line up. */
.cta-tiles-grid { display: grid; grid-template-columns: 1fr; gap: 1rem; }
@media (min-width: 720px) { .cta-tiles-grid { grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); } }
.cta-tile {
    display: flex;
    flex-direction: column;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    overflow: hidden;
    color: var(--color-text);
    text-decoration: none;
    box-shadow: 0 1px 3px var(--color-border);
}
.cta-tile:hover, .cta-tile:focus-visible { border-color: var(--color-primary); }
.cta-tile-media { display: block; }
.cta-tile-body { display: flex; flex-direction: column; gap: 0.4rem; padding: 1.25rem; flex: 1; }
.cta-tile-heading { font-family: var(--font-heading); font-size: var(--text-md); font-weight: 600; }
.cta-tile-text { font-size: 0.875rem; color: var(--color-muted); }
.cta-tile-cta { margin-top: auto; padding-top: 0.5rem; font-size: var(--text-sm); font-weight: 600; color: var(--color-primary); }

.meta { color: var(--color-muted); margin-bottom: 2rem; }
.back-link {
    display: inline-block;
    margin-bottom: 2rem;
    color: var(--color-primary);
    text-decoration: none;
    font-weight: 600;
}
/* "Share on WhatsApp" pill — SiteChrome.WhatsAppShareButton. Sits under a detail page's title (h1).
   Deliberately ignores the theme palette: the --brand-whatsapp* values are fixed WhatsApp
   brand colours emitted for every scheme by SiteStylesheetBuilder (see WhatsAppBrand there
   for the contrast trade-off). The badge SVG fills with currentColor, so `color` sets it. */
.whatsapp-share {
    display: inline-flex;
    align-items: center;
    box-sizing: border-box;
    min-height: 48px;
    margin: 0.25rem 0 1.25rem;
    padding: 0.4rem 1.1rem;
    background: var(--brand-whatsapp-surface);
    color: var(--brand-whatsapp);
    border: 2px solid var(--brand-whatsapp);
    border-radius: 999px;
    line-height: 1;
    text-decoration: none;
    transition: background-color 150ms ease-in-out, border-color 150ms ease-in-out;
}
/* The colour here also beats the global a:hover (0,1,1), which would otherwise turn the badge the theme's primary. */
.whatsapp-share:hover { background: var(--brand-whatsapp-surface-hover); border-color: var(--brand-whatsapp-strong); color: var(--brand-whatsapp-strong); }
.whatsapp-share:focus-visible { outline: 2px solid var(--brand-whatsapp-strong); outline-offset: 2px; }
.whatsapp-share svg { flex: none; display: block; width: auto; }
.whatsapp-share-logo { height: 32px; margin-right: 0.5rem; }
/* "Share on" is HTML text stacked above the wordmark SVG (the brand pack's lockup has no
   "Share on"); a bold neo-grotesque stack to sit close to WhatsApp's own lettering. */
.whatsapp-share-label { display: flex; flex-direction: column; align-items: flex-start; gap: 3px; }
.whatsapp-share-lead {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 12px;
    font-weight: 700;
    line-height: 1;
    letter-spacing: 0.01em;
}
.whatsapp-share-wordmark { height: 16px; }
@media print { .whatsapp-share { display: none !important; } }
/* series_detail.cshtml is the one .container page with a back-link; it needs
   top spacing instead (nothing else pushes it down from the header). */
main.container .back-link { margin-top: 1.5rem; margin-bottom: 0; }
/* series_detail.cshtml's banner sits between the back-link and the h2 — give it the same
   top breathing room .back-link gets above, since .container has no top padding of its
   own (see this file's header comment on why bare `main` and `.container` split). */
main.container .detail-banner { margin-top: 1.5rem; }

/* Stock-photo credit (implementation-13 D6): FeatureBanner wraps the banner in a <figure> only
   when the image has a credit. The figure's default margins are zeroed and the banner's bottom
   margin moves below the caption, so the layout matches an uncredited banner. Muted text on
   the page background, the pairing the per-scheme contrast check already covers. */
.detail-figure { margin: 0; }
.detail-figure .detail-banner { margin-bottom: 0.5rem; }
.photo-credit { margin: 0 0 1.5rem; font-size: var(--text-sm); color: var(--color-muted); }
.photo-credit a { color: inherit; text-decoration: underline; }

/* ── Sermon audio/video player ─────────────────────────────────────────── */
.player-wrapper {
    background: var(--color-text);
    border-radius: var(--radius-md);
    overflow: hidden;
    margin-bottom: 2rem;
    aspect-ratio: 16 / 9;
    display: flex;
    align-items: center;
    justify-content: center;
}
/* Audio has no picture, so it drops the 16:9 dark stage and sits at its native
   control height (~54px) instead of floating in a ~420px empty box. */
.player-wrapper--audio {
    background: none;
    border-radius: 0;
    aspect-ratio: auto;
}
audio, video { width: 100%; }
audio { display: block; }

/* ── Sermon notes (rendered Quill HTML) and its print action (sermon detail
   page) ─────────────────────────────────────────────────────────────────── */
.sermon-notes {
    margin-top: 2rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--color-border);
    line-height: var(--line-height-body);
}
.sermon-notes h1, .sermon-notes h2, .sermon-notes h3, .sermon-notes h4 {
    font-family: var(--font-heading);
    font-weight: var(--font-weight-heading);
    margin: 1.5rem 0 0.5rem;
}
.sermon-notes p, .sermon-notes ul, .sermon-notes ol { margin-bottom: 1rem; }
.sermon-notes ul, .sermon-notes ol { padding-left: 1.5rem; }
.sermon-notes a { color: var(--color-primary); }
.sermon-notes img { max-width: 100%; border-radius: var(--radius-sm); }
.sermon-notes blockquote {
    border-left: 3px solid var(--color-primary);
    padding-left: 1rem;
    color: var(--color-muted);
    margin-bottom: 1rem;
}

.print-action { margin-top: 1.5rem; }
.print-action button {
    background: var(--color-primary);
    color: var(--color-on-primary);
    border: none;
    padding: 0.5rem 1.25rem;
    border-radius: var(--radius-sm);
    font-size: var(--text-sm);
    font-weight: 600;
    cursor: pointer;
}

/* ── Series navigation / metadata (sermon detail page) ─────────────────── */
.series-line { margin-bottom: 1rem; }
.series-line a { color: var(--color-primary); text-decoration: none; font-weight: 600; }
.series-nav {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    margin-top: 2rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--color-border);
}
.series-nav a { color: var(--color-primary); text-decoration: none; font-weight: 600; }
.series-nav .next { margin-left: auto; text-align: right; }

/* ── Series landing page ────────────────────────────────────────────────── */
.series-description { color: var(--color-muted); margin-bottom: 1.5rem; }

/* ── Static ("page"-type) content body ─────────────────────────────────── */
main .body p { margin-bottom: var(--prose-space-p); }
/* Page titles are the single h1; a stray body h1 (legacy content) is styled exactly like an h2. */
main .body h1 { font-family: var(--font-heading); font-weight: var(--font-weight-heading); margin: var(--prose-space-h1); }
main .body h2 { font-family: var(--font-heading); font-weight: var(--font-weight-heading); margin: var(--prose-space-h2); }
main .body h3 { font-family: var(--font-heading); font-weight: var(--font-weight-heading); margin: var(--prose-space-h3); }
main .body h4 { font-family: var(--font-heading); font-weight: var(--font-weight-heading); margin: var(--prose-space-h4); }
main .body h5 { font-family: var(--font-heading); font-weight: var(--font-weight-heading); margin: var(--prose-space-h5); }
main .body h6 { font-family: var(--font-heading); font-weight: var(--font-weight-heading); margin: var(--prose-space-h6); }
main .body > *:first-child { margin-top: 0; }
main .body ul, main .body ol { margin-bottom: var(--prose-space-list); padding-left: 1.5rem; }
main .body li { margin-bottom: var(--prose-space-list-item); }
main .body li:last-child { margin-bottom: 0; }
main .body li > ul, main .body li > ol { margin-top: var(--prose-space-list-item); margin-bottom: 0; }
main .body blockquote {
    margin-bottom: var(--prose-space-blockquote);
    padding-left: 1rem;
    border-left: 3px solid var(--color-border);
    color: var(--color-muted);
}

/* ── Contact page (contact.cshtml) ──────────────────────────────────────── */
.contact-info { margin: 1.5rem 0; }
.contact-info p { margin-bottom: 0.5rem; }
.contact-info a { color: var(--color-primary); text-decoration: none; font-weight: 600; }
.contact-address { color: var(--color-muted); }

.contact-map { margin: 1.5rem 0; border-radius: var(--radius-md); overflow: hidden; }
.contact-map iframe { width: 100%; height: 300px; border: 0; display: block; }

/* main h2 has no top margin; on Contact Us each section follows a map or card grid, so it needs room. */
main h2.contact-section-heading { margin-top: 2.5rem; }
/* Multi-campus Contact Us: the main location spans the grid with its map beside the details,
   stacking below them on narrow screens so the map never drifts away from its address. */
.campus-card-main { grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); gap: 1.5rem; align-items: start; }
.campus-card-main .contact-map { margin: 0; }
.campus-card-main .contact-map iframe { height: 260px; }
@media (max-width: 640px) {
    .campus-card-main { grid-template-columns: minmax(0, 1fr); }
}
.campus-tag { font-size: var(--text-sm); text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-muted); margin: -0.25rem 0 0.5rem; }

.contact-form { display: flex; flex-direction: column; gap: 0.75rem; max-width: 500px; margin-top: 1.5rem; }
.contact-form label { font-size: var(--text-sm); font-weight: 600; margin-bottom: -0.5rem; }
.contact-form input, .contact-form textarea {
    padding: 0.6rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    font: inherit;
}
.contact-form button {
    background: var(--color-primary);
    color: var(--color-on-primary);
    border: none;
    padding: 0.6rem;
    border-radius: var(--radius-sm);
    font-weight: 600;
    cursor: pointer;
}
/* Screen-reader-only text (e.g. the org-name h1 when the logo already spells the name).
   Stays in the DOM for accessibility and SEO. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}
/* Honeypot spam trap — visually hidden from real visitors but still present in the
   DOM/tab order for bots that blindly fill every field. Not display:none, which some
   scrapers skip. */
.contact-honeypot { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; opacity: 0; }

/* ── Sermon list / series list (sermons.cshtml, series_detail.cshtml) ───── */
.sermon-list, .series-list { display: flex; flex-direction: column; gap: 1rem; padding-bottom: 3rem; }
.series-list { gap: 0.75rem; padding-bottom: 1rem; }

/* Sermon archive pager (sermons.cshtml, pages 2+ at /sermons/page/N/). */
.pager { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; padding: 0 0 3rem; }
.pager a { font-weight: 600; }
.pager-status { color: var(--color-muted); margin: 0 auto; }

.sermon-item, .series-item {
    background: var(--color-surface);
    border-radius: var(--radius-md);
    padding: 1.25rem;
    box-shadow: 0 1px 3px var(--color-border);
    display: flex;
    align-items: center;
    gap: 1rem;
}
/* Row thumbnail (SiteChrome.ItemThumb) — sermons.cshtml's sermon/series rows and
   series_detail.cshtml's sermon rows keep their existing row layout (implementation-05
   plan's "no Mars Hill Teachings-page redesign" decision); this just adds a small square
   of art, real or the .title-card gradient fallback, before each row's text. ItemThumb
   always renders something (image or fallback), so every row now has exactly 3 flex
   children (thumb, text, link) — text grows to fill the middle, link stays pinned right,
   replacing the old 2-child justify-content:space-between layout. */
.sermon-item .item-thumb, .series-item .item-thumb { flex-shrink: 0; }
/* :not(.item-thumb) matters here — the title-card fallback (SiteChrome.TitleCard) is ALSO
   a bare <div>, so without this exclusion the flex:1 rule below would match it too and
   blow its 64x64 box up to fill the row (caught by a real browser render during Phase 1
   QA — see PublishAsync_SermonWithFeatureImage_LogoStillWinsOnPagesWithNoOwnOrSeriesArt-
   style tests for the fallback path this covers). */
.sermon-item > div:not(.item-thumb), .series-item > div:not(.item-thumb) { flex: 1; min-width: 0; }
.sermon-item > a, .series-item > a { flex-shrink: 0; }
.series-item { padding: 1rem 1.25rem; }
.sermon-item h3, .series-item h3 { font-size: var(--text-md); font-weight: 600; }
.sermon-item .meta, .series-item .meta { font-size: var(--text-sm); color: var(--color-muted); margin-top: 0.25rem; }
.series-item .meta { margin-top: 0.15rem; }
.sermon-item a, .series-item a {
    font-size: var(--text-sm);
    color: var(--color-primary);
    text-decoration: none;
    font-weight: 600;
    white-space: nowrap;
    margin-left: 1rem;
}
.sermon-item .series-badge { display: block; font-size: 0.8rem; margin-top: 0.35rem; }
.sermon-item .series-badge a { color: var(--color-primary); text-decoration: none; font-weight: 600; margin-left: 0; white-space: normal; }

/* ── Event / campus / campaign / group cards (list pages) ──────────────── */
.event-grid, .campus-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 1.5rem; padding-bottom: 3rem; }
.group-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1.5rem; padding-bottom: 3rem; }

.campus-card, .campaign-card, .group-card {
    background: var(--color-surface);
    border-radius: var(--radius-md);
    padding: 1.5rem;
    box-shadow: 0 1px 3px var(--color-border);
}
/* .event-card carries a feature image (see events.cshtml/home.cshtml) — same
   flush-image-then-padded-body split as .card.has-media above. */
.event-card {
    background: var(--color-surface);
    border-radius: var(--radius-md);
    box-shadow: 0 1px 3px var(--color-border);
    overflow: hidden;
    display: flex;
    flex-direction: column;
}
.event-card .card-media { display: block; }
/* Body grows so every card's "Event details →" link sits on the same baseline across a row. */
.event-card .event-card-body { padding: 1.5rem; display: flex; flex-direction: column; flex: 1; }
.event-card h3 a { color: inherit; text-decoration: none; }
.event-card h3 a:hover, .event-card h3 a:focus-visible { text-decoration: underline; }
/* Listing cards are a teaser — the full, paragraph-formatted description lives on
   /events/{slug}/ (event_detail.cshtml), so clamp it here to keep the grid even. */
.event-card .excerpt {
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
    color: var(--color-muted);
}
.event-card a.more {
    margin-top: auto;
    padding-top: 1rem;
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-primary);
    text-decoration: none;
}
.event-card a.more:hover, .event-card a.more:focus-visible { text-decoration: underline; }
.event-card h3, .campus-card h3, .group-card h3 { font-size: 1.1rem; font-weight: 600; margin-bottom: 0.5rem; }
.campaign-card h3 { font-size: 1.2rem; font-weight: 700; margin-bottom: 0.5rem; }

.event-card .time, .campus-card .times { color: var(--color-primary); font-weight: 600; font-size: var(--text-base); margin-bottom: 0.5rem; }
.event-card .location, .campus-card .address { color: var(--color-muted); font-size: var(--text-base); margin-bottom: 0.5rem; }
.event-card .location { margin-bottom: 1rem; }
.event-card p, .group-card p { font-size: 0.95rem; }
.group-card p { margin-bottom: 1rem; }
.group-description { margin-bottom: 1rem; }
.group-description p { margin-bottom: 0; }
.campus-card a:not(.give) { color: var(--color-primary); }
.campus-card .address a.directions { margin-left: 0.35rem; font-size: var(--text-sm); white-space: nowrap; }
.campus-card .contact { font-size: var(--text-sm); color: var(--color-muted); }
.campus-card a.give {
    display: inline-block;
    margin-top: 0.75rem;
    font-size: var(--text-sm);
    color: var(--color-primary);
    text-decoration: none;
    font-weight: 600;
}

.campaign-list { display: flex; flex-direction: column; gap: 1.5rem; padding-bottom: 3rem; }
.campaign-card .desc { color: var(--color-muted); margin-bottom: 1rem; }
.campaign-card .desc p + p, .group-description p + p, .series-description p + p { margin-top: 0.6rem; }
.bar-track { background: var(--color-border); border-radius: var(--radius-pill); height: 12px; overflow: hidden; margin-bottom: 0.5rem; }
.bar-fill { background: var(--color-primary); height: 100%; }
.campaign-card .stats { display: flex; justify-content: space-between; font-size: var(--text-base); color: var(--color-muted); }
/* Campaign cards carry a feature image (giving.cshtml) - flush image, padded body, like .event-card. */
.campaign-card.has-media { padding: 0; overflow: hidden; display: flex; flex-direction: column; }
.campaign-card .card-media { display: block; }
.campaign-card .campaign-card-body { padding: 1.5rem; display: flex; flex-direction: column; flex: 1; }
.campaign-card h3 a { color: inherit; text-decoration: none; }
.campaign-card h3 a:hover, .campaign-card h3 a:focus-visible { text-decoration: underline; }
.campaign-card a.more { margin-top: 1rem; font-size: var(--text-sm); font-weight: 600; color: var(--color-primary); text-decoration: none; }
.campaign-card a.more:hover, .campaign-card a.more:focus-visible { text-decoration: underline; }
.campaign-teaser p + p { margin-top: 0.4rem; }

/* Campaign page (campaign_detail.cshtml): progress under the body, then the Donate form. */
.campaign-progress { margin: 2rem 0 1.5rem; }
.campaign-progress .stats { display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; color: var(--color-muted); }
.campaign-dates { margin-top: 0.5rem; font-size: 0.85rem; color: var(--color-muted); }
.donate { margin: 1.5rem 0 3rem; }
.donate h3 { margin-bottom: 1rem; }
.donate-notice { padding: 1rem 1.25rem; border-radius: var(--radius-md); background: var(--color-surface); box-shadow: 0 1px 3px var(--color-border); font-weight: 600; }
.donate-form { display: flex; flex-direction: column; gap: 1.25rem; max-width: 36rem; }
.donate-form fieldset { border: 0; padding: 0; margin: 0; }
.donate-form legend { font-weight: 600; margin-bottom: 0.5rem; }
.donate-presets { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.donate-preset {
    min-width: 5rem;
    padding: 0.6rem 1rem;
    border: 2px solid var(--color-primary);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    color: var(--color-primary);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}
.donate-preset[aria-pressed="true"] { background: var(--color-primary); color: var(--color-on-primary); }
.donate-other { display: flex; flex-direction: column; gap: 0.25rem; margin-top: 0.75rem; }
.donate-other[hidden] { display: none; }
.donate-fields { display: grid; grid-template-columns: 1fr; gap: 0.75rem; }
.donate-fields label, .donate-other { display: flex; flex-direction: column; gap: 0.25rem; font-weight: 600; font-size: var(--text-sm); }
.donate-fields input, .donate-other input {
    padding: 0.6rem 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    font: inherit;
    font-weight: 400;
    background: var(--color-surface);
    color: var(--color-text);
}
@media (min-width: 560px) {
    .donate-fields { grid-template-columns: 1fr 1fr; }
    .donate-fields .donate-email { grid-column: 1 / -1; }
}
.donate-captcha { min-height: 65px; }
.donate-error { margin: 0; padding: 0.6rem 0.75rem; border-left: 3px solid var(--color-text); background: var(--color-bg); color: var(--color-text); font-weight: 600; }
.donate-submit {
    align-self: flex-start;
    padding: 0.75rem 1.5rem;
    border: none;
    border-radius: var(--radius-sm);
    background: var(--color-primary);
    color: var(--color-on-primary);
    font: inherit;
    font-weight: 700;
    cursor: pointer;
}
.donate-submit[disabled] { opacity: 0.6; cursor: not-allowed; }
.donate-note { font-size: var(--text-sm); color: var(--color-muted); }
.donate [hidden] { display: none; }

.group-card .meta { color: var(--color-muted); font-size: var(--text-base); margin-bottom: 0.5rem; }
.group-card button.join {
    background: var(--color-primary);
    color: var(--color-on-primary);
    border: none;
    padding: 0.5rem 1rem;
    border-radius: var(--radius-sm);
    font-size: var(--text-sm);
    font-weight: 600;
    cursor: pointer;
}
.signup-form { display: none; margin-top: 1rem; flex-direction: column; gap: 0.5rem; }
.signup-form.open { display: flex; }
.signup-captcha:not(:empty) { min-height: 65px; }
.contact-captcha { min-height: 65px; }
.signup-form input, .signup-form textarea {
    padding: 0.5rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    font: inherit;
}
.signup-form button {
    background: var(--color-primary);
    color: var(--color-on-primary);
    border: none;
    padding: 0.5rem;
    border-radius: var(--radius-sm);
    font-weight: 600;
    cursor: pointer;
}
.signup-status { font-size: var(--text-sm); margin-top: 0.5rem; }

/* ── Footer (identical across every template, via SiteChrome.Footer) ───── */
footer {
    text-align: center;
    padding: 2rem 0;
    background: var(--color-footer-bg);
    color: var(--color-footer-fg-muted);
    font-size: var(--text-sm);
    border-top: 1px solid var(--color-border);
}

.footer-contact { margin-bottom: 1rem; }
.footer-contact p { margin-bottom: 0.25rem; }
.footer-contact a { color: var(--color-footer-fg-muted); text-decoration: none; }
.footer-contact a:hover { color: var(--color-footer-fg); }

.footer-social { display: flex; justify-content: center; gap: 1rem; margin-bottom: 1rem; }
.footer-social a { color: var(--color-footer-fg-muted); display: inline-flex; }
.footer-social a:hover { color: var(--color-footer-fg); }

.footer-cta { margin-bottom: 0.75rem; font-size: var(--text-sm); }
.footer-cta a { color: var(--color-footer-fg-muted); text-decoration: underline; }
.footer-cta a:hover { color: var(--color-footer-fg); }

/* Hidden on screen; sermon_detail.cshtml's own print media query (theme-independent
   by design, so it lives in that template rather than per-theme CSS) reveals
   elements with this class when printing. */
.print-only { display: none; }

/* ── Photo gallery grid + lightbox (see GalleryEmbedRenderer, assets/gallery.js) ──
   Fixed 3-then-2 column grid, not auto-fill — a gallery is capped at 6 photos, so
   there's no "how many columns fit" question to answer responsively beyond the one
   mobile breakpoint below. */
.gallery-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.75rem;
    margin: 1.5rem 0;
}
@media (max-width: 640px) {
    .gallery-grid { grid-template-columns: repeat(2, 1fr); }
}
.gallery-thumb {
    display: block;
    padding: 0;
    border: none;
    background: none;
    cursor: pointer;
}
.gallery-thumb img {
    aspect-ratio: 4 / 3;
    object-fit: cover;
    width: 100%;
    border-radius: var(--radius-md);
    display: block;
}

.gallery-lightbox[hidden] { display: none; }
.gallery-lightbox {
    position: fixed;
    inset: 0;
    /* Deliberately theme-independent scrim, same reasoning as sermon_detail.cshtml's
       print styles: a photo lightbox needs a consistently dark backdrop regardless of
       the tenant's color scheme. Built from --color-text (dark in 19 of 20 schemes,
       light only in the one dark scheme, Graphite — whose --color-on-primary is
       correspondingly dark, so the pairing below still contrasts) rather than a hex/
       rgba literal, honoring this file's no-color-literal invariant. The solid
       fallback line covers browsers without color-mix() support. */
    background: var(--color-text);
    background: color-mix(in srgb, var(--color-text) 90%, transparent);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: 1rem;
    z-index: 1000;
    padding: 2rem;
}
.gallery-lightbox .lightbox-image {
    max-width: 100%;
    max-height: 70vh;
    border-radius: var(--radius-md);
}
.gallery-lightbox .lightbox-caption {
    color: var(--color-on-primary);
    text-align: center;
    max-width: 700px;
}
.gallery-lightbox button {
    background: none;
    border: none;
    color: var(--color-on-primary);
    cursor: pointer;
}
.gallery-lightbox .lightbox-close {
    position: absolute;
    top: 1.5rem;
    right: 1.5rem;
    font-size: 2rem;
    line-height: 1;
}
.gallery-lightbox .lightbox-prev,
.gallery-lightbox .lightbox-next {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    font-size: 2.5rem;
    line-height: 1;
    padding: 0.5rem 1rem;
}
.gallery-lightbox .lightbox-prev { left: 0.5rem; }
.gallery-lightbox .lightbox-next { right: 0.5rem; }

/* ── People / staff page / sermon byline (implementation-05 Phase 3) ─────────── */
.sermon-byline { font-size: var(--text-sm); color: var(--color-muted); margin: 0.25rem 0 0.5rem; }
.sermon-byline a { color: var(--color-primary); text-decoration: none; font-weight: 600; }
.sermon-byline .scripture { font-style: italic; }
.person-role { color: var(--color-muted); margin: 0 0 0.75rem; }
.person-bio { margin-bottom: 2rem; }
.staff-grid .card-body p { color: var(--color-muted); font-size: var(--text-sm); }

/* ── Site search (/search/ and the header icon) ──────────────────────────── */
nav a.nav-search { display: inline-flex; align-items: center; vertical-align: middle; }
nav a.nav-search svg { display: block; }
@media (max-width: 640px) { .header-tools a.nav-search { min-width: 44px; min-height: 44px; justify-content: center; padding: 0; } }
.site-search label { display: block; margin-bottom: 0.25rem; color: var(--color-muted); font-size: var(--text-sm); }
.site-search-row { display: flex; gap: 0.5rem; }
.site-search-row input {
    flex: 1 1 auto;
    min-width: 0;
    padding: 0.6rem 0.75rem;
    font: inherit;
    color: var(--color-text);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
}
.site-search-row button {
    flex: 0 0 auto;
    padding: 0.6rem 1rem;
    font: inherit;
    color: var(--color-on-primary);
    background: var(--color-primary);
    border: 0;
    border-radius: var(--radius-md);
    cursor: pointer;
}
.site-search-row button:hover { background: var(--color-primary-strong); }
.site-search-status { margin: 1rem 0 0.5rem; color: var(--color-muted); }
.site-search-results { list-style: none; margin: 0; padding: 0; }
.site-search-results li { padding: 0.9rem 0; border-bottom: 1px solid var(--color-border); overflow-wrap: anywhere; }
.site-search-results a { font-family: var(--font-heading); font-size: var(--text-lg); color: var(--color-primary); }
.site-search-meta { margin-top: 0.2rem; color: var(--color-muted); font-size: var(--text-sm); }
.site-search-results p { margin: 0.35rem 0 0; }

/* ── Event bookings (event_detail.cshtml's #booking form, booking_manage.cshtml; driven by
   Assets/bookings.js) ─────────────────────────────────────────────────────────────────────
   A calm, form-first card: quantities first (the decision), contact details second, the
   running total right above the one primary button. Steppers are 44px so they work under a
   thumb on a phone in a church foyer. Themes define no error colour (and theme CSS may only
   use scheme tokens), so errors and the destructive Cancel button lean on weight, a strong
   text-coloured rule and the inline confirm step rather than red. */
.booking-jump {
    display: inline-block;
    margin: 0.75rem 0 0.25rem;
    font-weight: 600;
    font-size: var(--text-sm);
    color: var(--color-primary);
    text-decoration: none;
}
.booking-jump:hover, .booking-jump:focus-visible { text-decoration: underline; }

.booking {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 1.5rem;
    margin: 2.5rem 0 3rem;
    max-width: 640px;
    scroll-margin-top: 1.5rem;
}
/* The hidden attribute must win over the display values below (bookings.js toggles it). */
.booking [hidden] { display: none !important; }
/* Override the theme's underlined section heading — inside a card the border is noise. */
.booking h3 { font-family: var(--font-heading); font-size: var(--text-xl); margin: 0 0 0.75rem; padding: 0; border: 0; }
.booking h4 { font-family: var(--font-heading); font-size: var(--text-lg); margin: 0 0 0.5rem; }
.booking-manage { margin-top: 1.5rem; }

.booking-availability {
    display: inline-block;
    margin: 0 0 1rem;
    padding: 0.25rem 0.75rem;
    border-radius: var(--radius-pill);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-muted);
}
.booking-availability.is-low { color: var(--color-primary); border-color: var(--color-primary); }
.booking-availability.is-full { display: block; border-radius: var(--radius-sm); color: var(--color-text); font-weight: 400; }
.booking-availability.is-closed, .booking-closed { color: var(--color-muted); }

.booking-form { display: flex; flex-direction: column; gap: 1.25rem; }
.booking-options { border: 0; margin: 0; padding: 0; min-width: 0; }
.booking-options legend { font-weight: 600; margin-bottom: 0.5rem; padding: 0; }
.booking-option {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.6rem 0;
    border-bottom: 1px solid var(--color-border);
}
.booking-option:last-child { border-bottom: 0; }
.booking-option label { display: flex; flex-direction: column; min-width: 0; }
.booking-option-label { font-weight: 600; overflow-wrap: anywhere; }
.booking-option-price { font-size: var(--text-sm); color: var(--color-muted); }

.stepper { display: flex; align-items: center; flex-shrink: 0; }
.stepper button {
    width: 44px;
    height: 44px;
    border: 1px solid var(--color-border);
    background: var(--color-bg);
    color: var(--color-text);
    font-size: 1.25rem;
    line-height: 1;
    cursor: pointer;
}
.stepper button:first-child { border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
.stepper button:last-child { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.stepper button:hover { background: var(--color-surface); color: var(--color-primary); }
.stepper input {
    width: 3.25rem;
    height: 44px;
    border: 1px solid var(--color-border);
    border-left: 0;
    border-right: 0;
    text-align: center;
    font: inherit;
    font-weight: 600;
    background: var(--color-surface);
    color: var(--color-text);
    -moz-appearance: textfield;
}
.stepper input::-webkit-outer-spin-button, .stepper input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.booking-fields { display: grid; gap: 0.9rem; }
.booking-fields label { display: flex; flex-direction: column; gap: 0.3rem; font-size: var(--text-sm); font-weight: 600; }
.booking-fields .optional { font-weight: 400; color: var(--color-muted); }
.booking-fields input {
    padding: 0.65rem 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    font: inherit;
    font-weight: 400;
    background: var(--color-surface);
    color: var(--color-text);
}
@media (min-width: 560px) {
    .booking-fields { grid-template-columns: 1fr 1fr; }
    .booking-fields label:first-child { grid-column: 1 / -1; }
}
/* Honeypot: off-screen rather than display:none, which some bots skip (same as .contact-honeypot). */
.booking-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; opacity: 0; }

.booking-captcha { min-height: 65px; }
.booking-summary {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--color-border);
    color: var(--color-muted);
}
.booking-summary strong { color: var(--color-text); text-align: right; }

.booking-submit {
    width: 100%;
    min-height: 48px;
    background: var(--color-primary);
    color: var(--color-on-primary);
    border: none;
    border-radius: var(--radius-sm);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
    transition: background-color 150ms ease-in-out;
}
.booking-submit:hover { background: var(--color-primary-strong); }
.booking-submit:disabled { opacity: 0.6; cursor: wait; }
.booking-secondary, .booking-danger {
    min-height: 44px;
    padding: 0 1rem;
    margin: 0.5rem 0.5rem 0 0;
    border-radius: var(--radius-sm);
    background: transparent;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}
.booking-secondary { border: 1px solid var(--color-primary); color: var(--color-primary); }
.booking-danger { border: 1px solid var(--color-border); color: var(--color-muted); }
.booking-danger:hover { border-color: var(--color-text); background: var(--color-text); color: var(--color-surface); }
.booking-submit:focus-visible, .booking-secondary:focus-visible, .booking-danger:focus-visible, .stepper button:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

.booking-error { margin: 0; padding: 0.6rem 0.75rem; border-left: 3px solid var(--color-text); background: var(--color-bg); color: var(--color-text); font-weight: 600; }
.booking-choice { padding: 0.75rem; border-radius: var(--radius-sm); background: var(--color-bg); }
.booking-choice p { margin: 0; }
.booking-pay-choice { display: flex; gap: 0.5rem; align-items: flex-start; padding: 0.5rem 0; cursor: pointer; }
.booking-pay-choice input { margin-top: 0.3rem; }
.booking-note { margin: 0; font-size: var(--text-sm); color: var(--color-muted); }
.booking-flash { margin: 0 0 1rem; padding: 0.6rem 0.75rem; border-left: 3px solid var(--color-primary); background: var(--color-bg); }
.booking-done:focus { outline: none; }
.booking-done p { margin: 0 0 0.6rem; }
.booking-reference strong { font-size: var(--text-lg); letter-spacing: 0.05em; }

.booking-manage-header { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; flex-wrap: wrap; margin-bottom: 0.75rem; }
.booking-manage-header h3 { margin: 0; }
.booking-manage-header a { color: inherit; text-decoration: none; }
.booking-manage-header a:hover { text-decoration: underline; }
.booking-status {
    padding: 0.2rem 0.65rem;
    border-radius: var(--radius-pill);
    font-size: var(--text-sm);
    font-weight: 600;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
}
.booking-status.is-confirmed { color: var(--color-primary); border-color: var(--color-primary); }
.booking-status.is-cancelled { color: var(--color-muted); }
.booking-details { display: grid; grid-template-columns: auto 1fr; gap: 0.4rem 1.25rem; margin: 0 0 1.5rem; }
.booking-details dt { color: var(--color-muted); font-size: var(--text-sm); padding-top: 0.1rem; }
.booking-details dd { margin: 0; overflow-wrap: anywhere; }
.booking-cancel p { margin: 0 0 0.25rem; }


/* Theme: Modern — clean, high-contrast sans-serif with generous whitespace.
   This is the platform's original look, kept as the default baseline: bold
   display headings, a relaxed line-height, and moderate rounding throughout.
   Every color reference elsewhere comes from the tenant's chosen color
   scheme; this file only ever touches typography, spacing and shape (see
   _base.css's header comment for the token contract). */
:root {
    --font-heading: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
    --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
    --font-weight-heading: 700;
    --font-weight-display: 800;
    --font-weight-body: 400;
    --line-height-body: 1.6;

    --text-sm: 0.85rem;
    --text-base: 0.9rem;
    --text-md: 1rem;
    --text-lg: 1.4rem;
    --text-xl: 1.8rem;
    --text-2xl: 2rem;
    --text-3xl: 2.2rem;

    --radius-sm: 6px;
    --radius-md: 8px;
    --radius-pill: 99px;
}


:root {
    --color-primary: #1d5c63;
    --color-primary-strong: #00464c;
    --color-on-primary: #ffffff;
    --color-accent: #956a00;
    --color-bg: #f7f7f7;
    --color-surface: #ffffff;
    --color-text: #0e2629;
    --color-muted: #4f686c;
    --color-border: #d0e2e4;
    --color-header-bg: #ffffff;
    --color-header-fg: #1d5c63;
    --color-header-fg-muted: #4f686c;
    --color-footer-bg: #e0a83c;
    --color-footer-fg: #000000;
    --color-footer-fg-muted: #271a04;
    --color-title-card-start: #1d5c63;
    --color-title-card-end: #044b52;
    --color-title-card-ink: #ffffff;
    --brand-whatsapp: #25D366;
    --brand-whatsapp-strong: #1DA851;
    --brand-whatsapp-surface: #FFFFFF;
    --brand-whatsapp-surface-hover: #EAFBF1;
}