/* ============================================================
 * Organization Website Theme - Base
 * ============================================================
 * Single customizable theme for standalone org websites.
 * All colors/fonts use CSS custom properties so they can be
 * overridden per-org via OrgWebsiteBrandingHelper.
 *
 * Future: expand to 3 themes (Clean/Bold/Elegant) by overriding
 * the layout/spacing variables below.
 * ============================================================ */

/* ----------------------------------------------------------
 * Website-specific tokens (extend the global design tokens)
 * ---------------------------------------------------------- */

:root {
    --website-nav-height: 72px;
    --website-nav-bg: var(--bg-primary);
    --website-nav-border: var(--border-default);
    --website-nav-link-color: var(--text-primary);
    --website-nav-link-hover: var(--color-primary-600);
    --website-nav-link-hover-bg: var(--color-primary-50);
    --website-nav-link-active: var(--color-primary-700);
    --website-nav-link-active-bg: transparent;
    --website-nav-brand-weight: var(--font-weight-bold);
    --website-nav-brand-size: var(--font-size-lg);

    --website-footer-bg: var(--color-neutral-900);
    --website-footer-text: var(--color-neutral-300);
    --website-footer-heading: var(--color-neutral-50);
    --website-footer-link: var(--color-neutral-400);
    --website-footer-link-hover: var(--color-primary-400);
    --website-footer-border: var(--color-neutral-800);
    --website-footer-padding-y: var(--space-16);
    --website-footer-padding-x: clamp(1.25rem, 4vw, 3rem);
    --website-footer-gutter: var(--space-8);

    --website-section-padding-y: var(--space-20);
    --website-section-gap: 0;

    /* Body-copy text alignment. `inherit` = keep whatever each section already
       sets, so the default is a visual no-op; the global Text Alignment control
       (OrgWebsiteBrandingHelper) overrides this on :root, and a per-section
       inline value on .website-section beats both. */
    --website-text-align: inherit;

    /* Design Theme structural tokens (overridden per-site by
       WebsiteDesignThemeRegistry via OrgWebsiteBrandingHelper). Defaults below
       reproduce the pre-theme look (classic). */
    --website-card-padding: 1.5rem;
    --website-section-divider: none;

    --website-page-max-width: 860px;
    --website-page-padding-y: var(--space-16);
}

[data-theme="dark"] {
    --website-nav-bg: var(--bg-primary);
    --website-nav-border: var(--border-default);
    --website-footer-bg: var(--color-neutral-950);
    --website-footer-border: var(--color-neutral-800);
}

/* ----------------------------------------------------------
 * Navigation
 * ---------------------------------------------------------- */

.website-navbar {
    background-color: var(--website-nav-bg);
    border-bottom: 1px solid var(--website-nav-border);
    min-height: var(--website-nav-height);
    transition: var(--transition-colors);
}

/* When the navbar lives inside a header strip (as a main_menu section),
 * the strip already provides its own background via .website-header-strip-bg-*.
 * Suppress the navbar's own background + border so the strip's bg
 * paints through; otherwise the menu area renders as a dark block on
 * top of an otherwise colored strip.
 *
 * `!important` is required to beat theme.css:20 which declares
 * `.navbar { background-color: var(--bg-secondary) !important; }`
 * for the main-app header. Theme.css loads via ThemeAsset (registered
 * by the theme-switcher in the strip), so it's present on the org
 * website too. Without !important here, the main-app rule wins
 * regardless of specificity. */
.website-header-strip .navbar,
.website-header-strip .website-navbar {
    background-color: transparent !important;
    border-bottom: 0 !important;
    min-height: 0;
}

.website-navbar .navbar-brand {
    font-weight: var(--website-nav-brand-weight);
    font-size: var(--website-nav-brand-size);
    font-family: var(--font-family-brand, var(--font-family-heading));
    color: var(--text-primary);
    text-decoration: none;
}

.website-navbar .navbar-brand:hover {
    color: var(--color-primary-600);
}

.website-nav-logo {
    max-height: var(--website-nav-logo-height, 40px);
    width: auto;
    object-fit: contain;
    flex: 0 0 auto;
}

/* ---------------------------------------------------------------------------
 * Logo set - light/dark theme swap
 *
 * When an org configures a dark-mode logo, the renderer emits two <img>s
 * (website-logo--light + website-logo--dark). We show the one that matches
 * the active theme. Sites with only a primary logo emit a single <img> with
 * neither class, so these rules never apply and markup is unchanged.
 *
 * theme.js always writes an explicit [data-theme] on <html> at load, so the
 * prefers-color-scheme block below only covers the brief pre-hydration / no-JS
 * window.
 * ------------------------------------------------------------------------- */
.website-logo--dark {
    display: none;
}
[data-theme="dark"] .website-logo--light {
    display: none;
}
[data-theme="dark"] .website-logo--dark {
    display: inline-block;
}
/* Footer logo is display:block - keep it block when swapped. */
[data-theme="dark"] .website-footer-logo.website-logo--dark {
    display: block;
}

@media (prefers-color-scheme: dark) {
    html:not([data-theme]) .website-logo--light {
        display: none;
    }
    html:not([data-theme]) .website-logo--dark {
        display: inline-block;
    }
    html:not([data-theme]) .website-footer-logo.website-logo--dark {
        display: block;
    }
}

.website-nav-brand-text {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ----------------------------------------------------------
 * Navigation - Mobile (< 992px)
 * No header strip - the hero takes the full top of the page.
 * A floating hamburger in the top-right opens the off-canvas
 * menu (wired by web/js/mobile-menu.js via #mobileMenuBtn).
 * ---------------------------------------------------------- */

@media (max-width: 991.98px) {
    .website-navbar {
        display: none;
    }

    .website-nav-toggle {
        position: fixed;
        top: 12px;
        right: 16px;
        z-index: 1031;
        width: 44px;
        height: 44px;
        padding: 0;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        background: var(--bg-primary);
        color: var(--website-nav-link-color);
        border: 1px solid var(--border-default);
        border-radius: var(--radius-md);
        box-shadow: var(--shadow-md);
        font-size: 1.1rem;
        transition: var(--transition-colors);
    }

    .website-nav-toggle:hover,
    .website-nav-toggle:focus {
        background: var(--bg-secondary);
        color: var(--color-primary-600);
    }
}

.website-navbar .nav-link {
    color: var(--website-nav-link-color);
    font-weight: var(--font-weight-medium);
    font-family: var(--font-family-menu-left, inherit);
    padding: var(--space-2) var(--space-4);
    border-radius: var(--radius-md);
    transition: var(--transition-colors);
}

.website-navbar .nav-link:hover,
.website-navbar .nav-link:focus {
    color: var(--website-nav-link-hover);
    background-color: var(--website-nav-link-hover-bg);
}

.website-navbar .nav-link.active {
    color: var(--website-nav-link-active);
    background-color: var(--website-nav-link-active-bg);
    font-weight: var(--font-weight-semibold);
}

/* Dark-theme default for the hover pill. Declared as a variable (not a
   background override) so a custom org "Menu Hover Background" still wins in
   dark mode - an override rule here would out-specify the variable. */
[data-theme="dark"] {
    --website-nav-link-hover-bg: var(--color-neutral-800);
}

.website-navbar .dropdown-menu {
    border: 1px solid var(--border-default);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: var(--space-2);
}

.website-navbar .dropdown-item {
    border-radius: var(--radius-md);
    padding: var(--space-2) var(--space-4);
    font-weight: var(--font-weight-normal);
    transition: var(--transition-colors);
}

.website-navbar .dropdown-item:hover {
    background-color: var(--color-primary-50);
    color: var(--color-primary-700);
}

[data-theme="dark"] .website-navbar .dropdown-item:hover {
    background-color: var(--color-neutral-800);
}

/* Active dropdown item - use the variant's primary tint, not Bootstrap blue.
   One shade stronger than hover (-100 vs -50) so active reads as more prominent.
   Cover both .active and :active - Bootstrap colors both. */
.website-navbar .dropdown-item.active,
.website-navbar .dropdown-item:active {
    background-color: var(--color-primary-100);
    color: var(--color-primary-700);
    font-weight: var(--font-weight-medium);
}

[data-theme="dark"] .website-navbar .dropdown-item.active,
[data-theme="dark"] .website-navbar .dropdown-item:active {
    background-color: var(--color-primary-900);
    color: var(--color-primary-300);
}

.website-navbar .nav-divider {
    width: 1px;
    height: 24px;
    background-color: var(--border-default);
    margin: 0 var(--space-2);
    align-self: center;
}

/* Child dividers inside a dropdown menu. Bootstrap's .dropdown-divider
 * already handles the "line" variant; these add the "space" and "dot"
 * variants so all three top-level styles translate cleanly to the
 * vertical stack of a dropdown. */
.nav-dropdown-divider--space {
    height: var(--space-3);
    pointer-events: none;
}
.nav-dropdown-divider--dot {
    text-align: center;
    padding: var(--space-1) 0;
    color: var(--text-tertiary);
    font-size: 0.25rem;
    opacity: 0.6;
    pointer-events: none;
}

/* ----------------------------------------------------------
 * Navbar: Language & Theme widgets
 * ---------------------------------------------------------- */

.website-navbar .language-switcher {
    margin: 0;
}

.website-navbar .language-flags {
    display: flex;
    align-items: center;
    gap: var(--space-1);
}

.website-navbar .language-flag {
    opacity: 0.5;
    transition: var(--transition-all);
    font-size: 1.25rem;
    line-height: 1;
    text-decoration: none;
}

.website-navbar .language-flag:hover,
.website-navbar .language-flag.active {
    opacity: 1;
}

.website-navbar .theme-toggle-switch {
    margin-bottom: 0;
}

.website-navbar .theme-switcher {
    margin: 0;
}

/* ----------------------------------------------------------
 * Main Content Area
 * ---------------------------------------------------------- */

.website-body {
    min-height: 100vh;
}

.website-body main {
    flex: 1;
}

/* Headings inside an org website must follow the org's heading font knob.
 * site.css unconditionally overrides h1 to use --font-family-brand (an
 * Eventure.si design opinion), which leaks into org websites and makes
 * the per-org "Heading font" setting look broken: changing it only moves
 * h2-h6, while the hero h1 stays on the brand font. Re-binding h1-h6
 * here keeps every heading - including widget-emitted h1s like the hero
 * title - on --font-family-heading. The navbar brand keeps its own
 * font via .website-navbar .navbar-brand (higher specificity). */
/* Per-level typography defaults. Each named style (Display / Heading 1-3 /
 * Lead) falls back to the umbrella --font-family-heading (or -tagline/-body
 * for lead) until the org picks a font for that level in Appearance -> Fonts.
 * OrgWebsiteBrandingHelper::getCssOverrides() overrides these on :root when a
 * level is set, so the cascade lets an unset level inherit the heading font. */
.website-body {
    --font-family-h1: var(--font-family-heading);
    --font-family-h2: var(--font-family-heading);
    --font-family-h3: var(--font-family-heading);
    --font-family-display: var(--font-family-heading);
    --font-family-lead: var(--font-family-tagline, var(--font-family-body));
}

/* Bind each heading tag to its own level token so widget-emitted headings
 * (hero h1, cta h2, ...) automatically pick up the per-level font. h4-h6
 * share the Heading 3 font. */
.website-body h1 { font-family: var(--font-family-h1); }
.website-body h2 { font-family: var(--font-family-h2); }
.website-body h3,
.website-body h4,
.website-body h5,
.website-body h6 {
    font-family: var(--font-family-h3);
}

/* Brand display: any element that renders the organisation name as the
 * site's identity (navbar wordmark, auto-hero title, footer brand). Must
 * outrank `.website-body h1-h6` above so the brand h1 in the auto-hero
 * picks up --font-family-brand instead of the heading font. Specificity
 * 0,2,0 (.website-body .website-brand-display) > 0,1,1 (.website-body h1). */
.website-body .website-brand-display {
    font-family: var(--font-family-brand, var(--font-family-heading));
}

/* Tagline / "voice" copy: the lead paragraph under a hero, slider
 * subheadings, section kicker lines, and testimonial sub-titles. These
 * are semantically different from body copy (they're marketing voice,
 * not running text) and historically had no font binding - the
 * --font-family-tagline knob was registered in the helper but read by
 * nothing. The .website-body prefix keeps this rule org-scoped (the
 * main Eventure.si site has its own .brand-tagline / .navbar-brand-tagline
 * consumers in site.css). */
.website-body .lead,
.website-body .hero-slider-subheading,
.website-body .video-feature-kicker,
.website-body .testimonial-subtitle {
    font-family: var(--font-family-tagline, inherit);
}

/* Apply-a-style classes: a section title can opt into a named typography
 * level (Word-style "apply Heading 1") without changing its <h2> tag. Font
 * comes from the level token, size from the global scale token. Used by the
 * per-section "Title style" dropdown (views/website/_section.php). */
.website-body .wb-style-display { font-family: var(--font-family-display); font-size: var(--website-font-size-display, var(--font-size-5xl)); }
.website-body .wb-style-h1 { font-family: var(--font-family-h1); font-size: var(--website-font-size-h1, var(--font-size-4xl)); }
.website-body .wb-style-h2 { font-family: var(--font-family-h2); font-size: var(--website-font-size-h2, var(--font-size-3xl)); }
.website-body .wb-style-h3 { font-family: var(--font-family-h3); font-size: var(--website-font-size-h3, var(--font-size-2xl)); }
.website-body .wb-style-body { font-family: var(--font-family-body); font-size: var(--website-font-size-base, var(--font-size-base)); }
.website-body .wb-style-lead { font-family: var(--font-family-lead); }

/* Body-text wrappers: the per-section "Body text style" dropdown wraps a
 * section's widget output so its running text re-fonts to a chosen level
 * without touching each widget's markup. */
.website-body .wb-bodytext-display { font-family: var(--font-family-display); }
.website-body .wb-bodytext-h1 { font-family: var(--font-family-h1); }
.website-body .wb-bodytext-h2 { font-family: var(--font-family-h2); }
.website-body .wb-bodytext-h3 { font-family: var(--font-family-h3); }
.website-body .wb-bodytext-body { font-family: var(--font-family-body); }
.website-body .wb-bodytext-lead { font-family: var(--font-family-lead); }

/* Per-section font (role) classes: the per-section "Title font" / "Body font"
 * dropdowns re-font a section's title or running text to one of the 5 site
 * fonts (roles). Font-family only - the title keeps its section-title size.
 * See views/website/_section.php. The .wb-style-* / .wb-bodytext-* blocks above
 * are legacy (nothing emits them now that values normalize to roles). */
.website-body .wb-font-heading { font-family: var(--font-family-heading); }
.website-body .wb-font-body { font-family: var(--font-family-body); }
.website-body .wb-font-brand { font-family: var(--font-family-brand, var(--font-family-heading)); }
.website-body .wb-font-menu { font-family: var(--font-family-menu-left); }
.website-body .wb-font-tagline { font-family: var(--font-family-tagline, var(--font-family-body)); }

/* Body-copy text alignment. Scoped to running copy (paragraphs, lead/tagline
 * lines, and the Pell / block-editor rich-text render contexts) so headings and
 * buttons keep their own alignment and "Justify" only ever hits body text. The
 * value comes from --website-text-align, whose :root default is `inherit`, so
 * these rules stay a no-op until the global Text Alignment control or a
 * per-section override sets a real value. */
.website-body p,
.website-body .lead,
.website-body .split-bio-body,
.website-page-content .content-paragraph {
    text-align: var(--website-text-align);
}

/* Page content (for custom pages with block editor content) */
.website-page-content {
    max-width: var(--website-page-max-width);
    margin: 0 auto;
    padding: var(--website-page-padding-y) var(--space-4);
}

.website-page-content .content-heading {
    font-family: var(--font-family-heading);
}

.website-page-content .content-paragraph {
    font-size: var(--font-size-lg);
    line-height: 1.75;
    color: var(--text-secondary);
}

/* Per-paragraph typography presets in the website-page context. The base
 * .txt-* rules (web/css/site.css) lose to the (0,2,0) rule above, so these
 * context-scoped overrides restore the author's choice. The .split-bio-body
 * prefix covers the Pell rich-text render context for the same reason. */
.website-page-content .txt-size-s,  .split-bio-body .txt-size-s  { font-size: var(--font-size-sm); }
.website-page-content .txt-size-m,  .split-bio-body .txt-size-m  { font-size: var(--font-size-base); }
.website-page-content .txt-size-l,  .split-bio-body .txt-size-l  { font-size: var(--font-size-lg); }
.website-page-content .txt-size-xl, .split-bio-body .txt-size-xl { font-size: var(--font-size-xl); }

.website-page-content .txt-lh-tight,   .split-bio-body .txt-lh-tight   { line-height: var(--line-height-tight); }
.website-page-content .txt-lh-normal,  .split-bio-body .txt-lh-normal  { line-height: var(--line-height-normal); }
.website-page-content .txt-lh-relaxed, .split-bio-body .txt-lh-relaxed { line-height: var(--line-height-relaxed); }
.website-page-content .txt-lh-loose,   .split-bio-body .txt-lh-loose   { line-height: var(--line-height-loose); }

/* Full-width page layout (no max-width constraint) */
.website-page-full-width .website-page-content {
    max-width: none;
    padding-left: 0;
    padding-right: 0;
}

/* Sidebar layouts */
.website-page-sidebar-left,
.website-page-sidebar-right {
    max-width: 1200px;
    margin: 0 auto;
    padding: var(--website-page-padding-y) var(--space-4);
    display: grid;
    grid-template-columns: 280px 1fr;
    gap: var(--space-8);
}

.website-page-sidebar-right {
    grid-template-columns: 1fr 280px;
}

@media (max-width: 991.98px) {
    .website-page-sidebar-left,
    .website-page-sidebar-right {
        grid-template-columns: 1fr;
    }
}

/* ----------------------------------------------------------
 * Homepage Sections
 * ---------------------------------------------------------- */

.website-section {
    /* Per-side padding so a section can override top and bottom independently
       (config[section_spacing_top] / [_bottom]); each side falls back to the
       linked/global --website-section-padding-y when its override is unset. */
    padding-top: var(--website-section-padding-top, var(--website-section-padding-y));
    padding-bottom: var(--website-section-padding-bottom, var(--website-section-padding-y));
    padding-left: 0;
    padding-right: 0;
    position: relative;
    overflow: hidden;
    /* Anchor-nav jump offset: keep the section top clear of the sticky/overlay
       header. Reuses the header-height var (default matches overlay CSS). */
    scroll-margin-top: var(--website-header-height, 96px);
}

/* Smooth scrolling for in-page anchor nav links. */
html {
    scroll-behavior: smooth;
}

.website-section + .website-section {
    margin-top: var(--website-section-gap);
    /* Design Theme hairline divider between adjacent sections. Default 'none'
       (classic) draws nothing; the 'slab' theme sets a 1px border-default rule. */
    border-top: var(--website-section-divider);
}

/* Section backgrounds */
.website-section-light {
    background-color: var(--bg-secondary);
}

.website-section-dark {
    background-color: var(--color-neutral-900);
    color: var(--color-neutral-100);
}

.website-section-dark *,
.website-section-dark h1,
.website-section-dark h2,
.website-section-dark h3,
.website-section-dark h4,
.website-section-dark p,
.website-section-dark span,
.website-section-dark a:not(.btn) {
    color: inherit;
}

.website-section-primary {
    background-color: var(--color-primary-600);
    color: white;
}

.website-section-primary *,
.website-section-primary h1,
.website-section-primary h2,
.website-section-primary h3,
.website-section-primary h4,
.website-section-primary p,
.website-section-primary span {
    color: inherit;
}

/* Deep (the base / default gradient): primary-600 deepening to primary-800
 * along a 135deg diagonal. The slider controls WHERE primary-800 reaches
 * its full strength: at slider 0.5 (default) the stop sits at 100% which
 * reproduces the original smooth blend exactly; lower values pull primary-800
 * earlier (more dramatic deepening), higher push it past the viewport edge
 * (softer, more single-toned). */
.website-section-gradient {
    background: linear-gradient(
        135deg,
        var(--color-primary-600),
        var(--color-primary-800) calc(70% + var(--wb-bg-intensity, 0.5) * 60%)
    );
    color: white;
}

.website-section-gradient *,
.website-section-gradient h1,
.website-section-gradient h2,
.website-section-gradient h3,
.website-section-gradient h4,
.website-section-gradient p,
.website-section-gradient span {
    color: inherit;
}

/* Gradient recipe variants. Each overrides only `background` (the base rule
 * supplies color: white and the text-inheritance cascade). Doubled selector
 * `.website-section-gradient.website-section-gradient-{key}` beats the base
 * 1-class specificity. Default 'deep' uses the base rule (no extra class
 * needed) - existing rows keep their look. */

/* Duo: primary -> secondary diagonal. Slider controls the angle:
 *   0 -> 45deg (steep diagonal), 0.5 -> 135deg (current default), 1 -> 225deg. */
.website-section-gradient.website-section-gradient-duo {
    background: linear-gradient(
        calc(45deg + var(--wb-bg-intensity, 0.5) * 180deg),
        var(--color-primary-500),
        var(--color-secondary-500)
    );
}

/* Radial: center-out spotlight. Slider controls the focal point position
 * diagonally across the section: 0 -> top-left (20% 20%), 0.5 -> center
 * (50% 50%, current default), 1 -> bottom-right (80% 80%). */
.website-section-gradient.website-section-gradient-radial {
    background: radial-gradient(
        circle at
            calc(20% + var(--wb-bg-intensity, 0.5) * 60%)
            calc(20% + var(--wb-bg-intensity, 0.5) * 60%),
        var(--color-primary-500),
        var(--color-primary-800) 70%
    );
}

/* Sweep: 3-stop primary -> soft tint -> secondary. Slider controls where
 * the soft tint sits along the diagonal: 0 -> 30%, 0.5 -> 50% (current
 * default), 1 -> 70%. */
.website-section-gradient.website-section-gradient-sweep {
    background: linear-gradient(
        135deg,
        var(--color-primary-500) 0%,
        color-mix(in srgb, var(--bg-secondary, #f8f9fa) 80%, transparent) calc(30% + var(--wb-bg-intensity, 0.5) * 40%),
        var(--color-secondary-500) 100%
    );
}

/* Secondary section: mirror of Primary using the org's secondary brand token.
 * Closes the obvious gap in the matrix - orgs with a rich palette can now
 * lean on their full brand identity without dropping to custom CSS. */
.website-section-secondary {
    background-color: var(--color-secondary-600);
    color: white;
}

.website-section-secondary *,
.website-section-secondary h1,
.website-section-secondary h2,
.website-section-secondary h3,
.website-section-secondary h4,
.website-section-secondary p,
.website-section-secondary span {
    color: inherit;
}

/* Mesh: three overlapping radial-gradient blobs in the org's primary +
 * secondary, with a soft center tone that auto-flips per theme so the
 * page reads cohesively on both light and dark backgrounds. The Stripe /
 * Linear / Vercel "premium without motion" look.
 *
 * Default 'diagonal' composition. The slider controls how far the two
 * brand blobs fly toward their corners:
 *   0   -> blobs at 40% 40% / 60% 60% (soft, centered, almost merged)
 *   0.5 -> blobs at 20% 20% / 80% 80% (current default)
 *   1   -> blobs at 0%  0%  / 100% 100% (full corners, bold separation) */
.website-section-mesh {
    background-color: var(--bg-secondary, #f8f9fa);
    background-image:
        radial-gradient(at calc(40% - var(--wb-bg-intensity, 0.5) * 40%) calc(40% - var(--wb-bg-intensity, 0.5) * 40%), color-mix(in srgb, var(--color-primary-500) 55%, transparent), transparent 55%),
        radial-gradient(at calc(60% + var(--wb-bg-intensity, 0.5) * 40%) calc(60% + var(--wb-bg-intensity, 0.5) * 40%), color-mix(in srgb, var(--color-secondary-500) 55%, transparent), transparent 55%),
        radial-gradient(at 50% 50%, rgba(255, 255, 255, 0.55), transparent 60%);
    color: var(--text-primary);
}

[data-theme="dark"] .website-section-mesh {
    background-color: var(--color-neutral-900, #111);
    background-image:
        radial-gradient(at calc(40% - var(--wb-bg-intensity, 0.5) * 40%) calc(40% - var(--wb-bg-intensity, 0.5) * 40%), color-mix(in srgb, var(--color-primary-500) 45%, transparent), transparent 55%),
        radial-gradient(at calc(60% + var(--wb-bg-intensity, 0.5) * 40%) calc(60% + var(--wb-bg-intensity, 0.5) * 40%), color-mix(in srgb, var(--color-secondary-500) 45%, transparent), transparent 55%),
        radial-gradient(at 50% 50%, rgba(0, 0, 0, 0.45), transparent 60%);
    color: var(--text-primary, #fff);
}

/* Mesh composition variants. Each variant overrides only the background-image
 * (the base rule supplies background-color + text color, which differ per theme).
 * Selector doubles up `.website-section-mesh.website-section-mesh-{key}` so
 * specificity beats both the base mesh rule and any single-class neighbors.
 * Variants intentionally drop the soft white/dark center band so they work
 * uniformly across light and dark themes without per-theme overrides; the
 * theme-aware background-color underneath supplies the right "base canvas." */

/* Aurora: horizontal bands. Slider controls band thickness:
 *   0 -> 30% (thin / horizon-line whisper)
 *   0.5 -> 60% (current default)
 *   1 -> 90% (thick / fills most of the section). */
.website-section-mesh.website-section-mesh-aurora {
    background-image:
        radial-gradient(ellipse 100% calc(30% + var(--wb-bg-intensity, 0.5) * 60%) at 50% 0%, color-mix(in srgb, var(--color-primary-500) 55%, transparent), transparent 65%),
        radial-gradient(ellipse 100% calc(30% + var(--wb-bg-intensity, 0.5) * 60%) at 50% 100%, color-mix(in srgb, var(--color-secondary-500) 55%, transparent), transparent 65%);
}

/* Spotlight: single primary blob centered with secondary fades from the
 * opposite corners. Slider controls the spotlight RADIUS (where the
 * primary blob fades to transparent):
 *   0 -> 25% (tight, dramatic vignette)
 *   0.5 -> 45% (current default)
 *   1 -> 65% (wide, the primary blob bleeds across most of the section). */
.website-section-mesh.website-section-mesh-spotlight {
    background-image:
        radial-gradient(circle at 50% 50%, color-mix(in srgb, var(--color-primary-500) 65%, transparent) 0%, transparent calc(25% + var(--wb-bg-intensity, 0.5) * 40%)),
        radial-gradient(circle at 0% 100%, color-mix(in srgb, var(--color-secondary-500) 45%, transparent), transparent 50%),
        radial-gradient(circle at 100% 0%, color-mix(in srgb, var(--color-secondary-500) 45%, transparent), transparent 50%);
}

/* Twin: vertical left/right split. Slider controls how SHARPLY the two
 * sides meet (via each ellipse's x-radius - wider ellipses overlap more
 * and produce a blurred blend):
 *   0 -> 85% radius (heavy overlap, soft purple/blended middle)
 *   0.5 -> 65% radius (current default)
 *   1 -> 45% radius (no overlap, hard two-tone split). */
.website-section-mesh.website-section-mesh-twin {
    background-image:
        radial-gradient(ellipse calc(85% - var(--wb-bg-intensity, 0.5) * 40%) 100% at 0% 50%, color-mix(in srgb, var(--color-primary-500) 55%, transparent), transparent 70%),
        radial-gradient(ellipse calc(85% - var(--wb-bg-intensity, 0.5) * 40%) 100% at 100% 50%, color-mix(in srgb, var(--color-secondary-500) 55%, transparent), transparent 70%);
}

/* Solid surface treatments. Apply only to single-tone backgrounds
 * (light/dark/primary/secondary) via .website-section-solid-{soft|vignette|grain}.
 * Each variant uses ::after (animation overlays use ::before, so the two
 * layers compose without colliding - a Primary section can be both Soft
 * and Pulse-animated at the same time). Default 'flat' adds no class,
 * meaning no ::after is generated and existing rows render identically. */
.website-section-solid-soft,
.website-section-solid-vignette,
.website-section-solid-grain {
    position: relative;
    isolation: isolate;
    overflow: hidden;
}
.website-section-solid-soft::after,
.website-section-solid-vignette::after,
.website-section-solid-grain::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 0;
}

/* Soft: gentle radial highlight in upper-center, like ambient room light
 * spilling onto the section. Works on both light and dark themes because
 * white-at-low-alpha reads as "lift" against any base color. */
.website-section-solid-soft::after {
    background: radial-gradient(ellipse 80% 60% at 50% 30%, rgba(255, 255, 255, 0.12), transparent 60%);
}

/* Vignette: darken the corners so the eye is pulled toward whatever
 * content sits in the center. Good for hero / CTA sections. Black-at-
 * low-alpha works on light themes; on dark sections the corners just go
 * a touch deeper - subtle but visible. */
.website-section-solid-vignette::after {
    background: radial-gradient(ellipse at 50% 50%, transparent 50%, rgba(0, 0, 0, 0.22) 100%);
}

/* Grain: faint film-grain noise overlay. SVG fractalNoise inlined as a
 * data URL so no separate request fires. mix-blend-mode: overlay lets
 * the grain ride on top of any color without washing it out. */
.website-section-solid-grain::after {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E");
    background-size: 160px 160px;
    opacity: 0.08;
    mix-blend-mode: overlay;
}

/* Shape dividers. Decorative SVG silhouettes pinned to a section's top and/or
 * bottom edge, rendered as child <svg> elements (NOT ::before/::after, which are
 * already used by animation + solid-surface variants, and because the two edges
 * must be independent). Paths are authored top-filled; the bottom edge flips
 * vertically so one path map serves both. The renderer gates these off image and
 * mesh backgrounds. The path fills with `currentColor`, set by a role class
 * below or an inline `color:` for a Brand Palette hex. preserveAspectRatio="none"
 * lets the 1200x120 viewBox stretch to the element, so height is pure CSS. The
 * section's `overflow: hidden` keeps each divider clipped to its own box; the
 * section gap is 0 so neighbours butt together and the silhouette reads as a
 * transition. */
.website-section-divider {
    position: absolute;
    left: 0;
    width: 100%;
    height: var(--wb-divider-h, 80px);
    display: block;
    line-height: 0;
    pointer-events: none;
    /* Sit BELOW the background overlay (.wb-bg-overlay is z-index 1) so a
     * page/section overlay tints the divider exactly like it tints the section
     * background - otherwise the silhouette stays bright while its section
     * darkens in dark mode (or under any overlay), and the fill no longer
     * matches. Still above the section's own solid background (z-index 0 on a
     * positioned child paints over the wrapper's background-color) and below
     * content (.container is lifted to z-index 2). */
    z-index: 0;
}
.website-section-divider--top {
    top: 0;
}
.website-section-divider--bottom {
    bottom: 0;
    transform: scaleY(-1);
}
.website-section-divider--flip {
    transform: scaleX(-1);
}
.website-section-divider--bottom.website-section-divider--flip {
    transform: scaleY(-1) scaleX(-1);
}

/* Keep section content above the dividers, which sit in the section's vertical
 * padding band. Content is wrapped in .container (title, contained content,
 * empty states), so lifting it clears any tall divider. */
.website-section > .container {
    position: relative;
    z-index: 2;
}

/* Preset fill roles -> brand CSS vars. Values mirror the section background
 * colours defined above so a divider can match its neighbour exactly:
 * light = --bg-secondary, dark = --color-neutral-900,
 * primary = --color-primary-600, secondary = --color-secondary-600. */
.website-divider-fill-primary {
    color: var(--color-primary-600);
}
.website-divider-fill-secondary {
    color: var(--color-secondary-600);
}
.website-divider-fill-light {
    color: var(--bg-secondary, #f8f9fa);
}
.website-divider-fill-dark {
    color: var(--color-neutral-900, #111);
}
.website-divider-fill-white {
    color: #fff;
}

/* Shorter on small screens so a tall wave doesn't swallow the viewport while
 * keeping full width (preserveAspectRatio="none"). */
@media (max-width: 767.98px) {
    .website-section-divider {
        height: clamp(28px, calc(var(--wb-divider-h, 80px) * 0.6), var(--wb-divider-h, 80px));
    }
}

/* Buttons inside dark/primary/secondary/gradient/mesh sections keep their
 * own colors. `color: revert` here used to fall through to the UA link-blue
 * for <a class="btn">, which is what made CTAs render as ugly Bootstrap blue
 * on the public site. `inherit` keeps the section's text color for plain
 * link-style buttons; explicit .btn-* classes below override per variant.
 * Exclude .btn-light / .btn-white: their near-white background needs the
 * Bootstrap-default dark text, otherwise inheriting the section's white text
 * would render the label invisible. */
.website-section-dark .btn:not(.btn-light):not(.btn-white),
.website-section-primary .btn:not(.btn-light):not(.btn-white),
.website-section-secondary .btn:not(.btn-light):not(.btn-white),
.website-section-gradient .btn:not(.btn-light):not(.btn-white),
.website-section-mesh .btn:not(.btn-light):not(.btn-white) {
    color: inherit;
}

/* Brand-primary CTA buttons on primary / gradient / mesh sections would
 * otherwise fill with the section's own primary color (invisible button).
 * Swap to the org's secondary brand token so the CTA visibly pops against
 * the primary background, regardless of how pastel or saturated the org's
 * primary is. Secondary section keeps the default brand-primary button -
 * the colors don't collide so no swap needed there. */
.website-section-primary .btn-brand-primary,
.website-section-gradient .btn-brand-primary,
.website-section-mesh .btn-brand-primary {
    background-color: var(--color-secondary-500);
    border-color: var(--color-secondary-500);
    color: #fff;
}
.website-section-primary .btn-brand-primary:hover,
.website-section-primary .btn-brand-primary:focus,
.website-section-gradient .btn-brand-primary:hover,
.website-section-gradient .btn-brand-primary:focus,
.website-section-mesh .btn-brand-primary:hover,
.website-section-mesh .btn-brand-primary:focus {
    background-color: var(--color-secondary-600);
    border-color: var(--color-secondary-600);
    color: #fff;
}
.website-section-primary .btn-brand-primary:active,
.website-section-gradient .btn-brand-primary:active,
.website-section-mesh .btn-brand-primary:active {
    background-color: var(--color-secondary-700);
    border-color: var(--color-secondary-700);
    color: #fff;
}

/* Fix text visibility inside dark-variant widgets (HeroSectionWidget bg-dark, etc.) */
.website-section .bg-dark,
.website-section .bg-primary {
    color: white;
}

.website-section .bg-dark *,
.website-section .bg-dark h1,
.website-section .bg-dark h2,
.website-section .bg-dark h3,
.website-section .bg-dark p,
.website-section .bg-dark span,
.website-section .bg-primary *,
.website-section .bg-primary h1,
.website-section .bg-primary h2,
.website-section .bg-primary h3,
.website-section .bg-primary p,
.website-section .bg-primary span {
    color: white !important;
}

.website-section .bg-dark .text-muted,
.website-section .bg-primary .text-muted,
.website-section .bg-dark .lead.text-muted,
.website-section .bg-primary .lead.text-muted {
    color: rgba(255, 255, 255, 0.7) !important;
}

.website-section .bg-dark .btn,
.website-section .bg-primary .btn {
    color: revert !important;
}

/* Image background base. `position: relative` + `isolation: isolate`
 * provide a stacking context for the Ken Burns inner frame and overlay
 * pseudos. The auto-50%-black overlay that used to live here has been
 * replaced by the Phase 2 .website-section-image-overlay-* variants -
 * each section now explicitly opts into a darken/lighten/tint overlay
 * via the admin's Image sub-row. */
.website-section-image {
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    position: relative;
    isolation: isolate;
    overflow: hidden;
}

.website-section-image > * {
    position: relative;
    z-index: 1;
}

/* Section title */
.website-section-title {
    font-family: var(--font-family-heading);
    font-size: var(--font-size-3xl);
    font-weight: var(--font-weight-bold);
    text-align: center;
    margin-bottom: var(--space-12);
}

/* ----------------------------------------------------------
 * Footer
 * ---------------------------------------------------------- */

.website-footer {
    background-color: var(--website-footer-bg);
    color: var(--website-footer-text);
    padding: var(--website-footer-padding-y) 0;
    margin-top: auto;
}

/* Horizontal breathing room for footer content. The base rule pads the
 * footer vertically only, so left/right spacing came from the inner
 * Bootstrap container gutter (~0.75rem) alone - too tight, especially in
 * the "wide" (container-fluid) layout. Padding the inner content wrappers
 * (not the footer itself) keeps the full-bleed .wb-bg-layer background
 * edge-to-edge while insetting the columns/strips. */
.website-footer > .container,
.website-footer > .container-fluid,
.website-footer > [data-web="footer-pre-strip"],
.website-footer > [data-web="footer-post-strip"] {
    padding-inline: var(--website-footer-padding-x);
}

/* Loosen the column gutter natively (org info / sitemap / content /
 * newsletter) - g-4's 1.5rem reads tight for a footer. */
.website-footer .row {
    --bs-gutter-x: var(--website-footer-gutter);
    --bs-gutter-y: var(--website-footer-gutter);
}

/* Nudge the stacked below-column blocks (downloads / social / legal /
 * custom text) from mt-4 (1.5rem). The 0,2,0 selector beats the mt-4
 * utility (0,1,0) without !important. */
.website-footer [data-web="footer-downloads"],
.website-footer [data-web="footer-social-row"],
.website-footer [data-web="footer-legal"],
.website-footer [data-web="footer-text"] {
    margin-top: var(--website-footer-gutter);
}

/* Footer spacing density (org_website_footer_padding). Normal = the :root
 * defaults above, so no rule is needed for it. Compact/Spacious re-scale
 * both the horizontal padding and the inter-item gutter; the custom props
 * cascade to the inner container / row / blocks that reference them. */
.website-footer[data-footer-padding="compact"] {
    --website-footer-padding-x: clamp(0.75rem, 2vw, 1.25rem);
    --website-footer-gutter: var(--space-6);
}
.website-footer[data-footer-padding="spacious"] {
    --website-footer-padding-x: clamp(2rem, 6vw, 5rem);
    --website-footer-gutter: var(--space-12);
}

.website-footer-grid {
    display: grid;
    grid-template-columns: 2fr 1fr 1fr;
    gap: var(--space-10);
}

@media (max-width: 767.98px) {
    .website-footer-grid {
        grid-template-columns: 1fr;
        gap: var(--space-8);
    }
}

.website-footer h5 {
    color: var(--website-footer-heading);
    font-family: var(--font-family-heading);
    font-weight: var(--font-weight-semibold);
    font-size: var(--font-size-base);
    margin-bottom: var(--space-4);
}

.website-footer p {
    color: var(--website-footer-text);
    margin-bottom: var(--space-2);
    font-size: var(--font-size-sm);
}

.website-footer a {
    color: var(--website-footer-link);
    text-decoration: none;
    transition: var(--transition-colors);
}

.website-footer a:hover {
    color: var(--website-footer-link-hover);
}

/* `.website-body` prefix bumps specificity to 0,2,0 so this beats the
 * `.website-body h6` heading-font rule above; the footer brand is an
 * h6 element and would otherwise stay on --font-family-heading. */
.website-body .website-footer-brand {
    color: var(--website-footer-heading);
    font-family: var(--font-family-brand, var(--font-family-heading));
    font-weight: var(--font-weight-semibold);
}

.website-footer-logo {
    max-height: 56px;
    max-width: 100%;
    width: auto;
    display: block;
}

.website-footer-eventure-logo {
    height: 12px;
    width: auto;
    vertical-align: middle;
    opacity: 0.7;
}

.website-footer-powered-by {
    color: var(--website-footer-text, inherit);
    font-size: 0.7rem;
    font-weight: 400;
    letter-spacing: 0.02em;
    opacity: 0.45;
    text-decoration: none;
    transition: opacity 0.2s ease;
}

.website-footer-powered-by:hover,
.website-footer-powered-by:focus {
    opacity: 0.85;
    color: inherit;
    text-decoration: none;
}

.website-footer-text {
    color: var(--website-footer-text);
    font-size: var(--font-size-sm);
}

.website-footer-social {
    display: flex;
    gap: var(--space-3);
    margin-top: var(--space-4);
}

.website-footer-social a {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: var(--radius-full);
    background-color: var(--color-neutral-800);
    color: var(--website-footer-text);
    font-size: var(--font-size-base);
    transition: var(--transition-all);
}

.website-footer-social a:hover {
    background-color: var(--color-primary-600);
    color: white;
    transform: translateY(-2px);
}

.website-footer-bottom {
    border-top: 1px solid var(--website-footer-border);
    margin-top: var(--space-10);
    padding-top: var(--space-6);
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-4);
}

.website-footer-bottom p {
    margin: 0;
}

.website-footer-powered {
    font-size: var(--font-size-xs);
    opacity: 0.7;
}

.website-footer-powered:hover {
    opacity: 1;
}

/* ----------------------------------------------------------
 * Blog listing on website
 * ---------------------------------------------------------- */

.website-blog-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: var(--space-8);
}

.website-blog-card {
    border: 1px solid var(--border-default);
    border-radius: var(--radius-xl);
    overflow: hidden;
    transition: var(--transition-shadow);
    background-color: var(--bg-primary);
}

.website-blog-card:hover {
    box-shadow: var(--shadow-lg);
}

.website-blog-card img {
    width: 100%;
    height: 200px;
    object-fit: cover;
}

.website-blog-card-body {
    padding: var(--space-6);
}

.website-blog-card-body h3 {
    font-family: var(--font-family-heading);
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    margin-bottom: var(--space-2);
}

.website-blog-card-body h3 a {
    color: var(--text-primary);
    text-decoration: none;
}

.website-blog-card-body h3 a:hover {
    color: var(--color-primary-600);
}

.website-blog-card-meta {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
    margin-bottom: var(--space-3);
}

/* ----------------------------------------------------------
 * Events listing on website
 * ---------------------------------------------------------- */

.website-events-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

/* ----------------------------------------------------------
 * Contact page
 * ---------------------------------------------------------- */

.website-contact-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-10);
    max-width: 1000px;
    margin: 0 auto;
    padding: var(--space-12) var(--space-4);
}

@media (max-width: 767.98px) {
    .website-contact-grid {
        grid-template-columns: 1fr;
    }
}

/* Info column is a flex column so the map can be pushed to the bottom and
 * line up with the foot of the form card in the adjacent grid cell. */
.website-contact-info {
    display: flex;
    flex-direction: column;
}

.website-contact-info h2 {
    font-family: var(--font-family-heading);
    margin-bottom: var(--space-2);
}

.website-contact-intro {
    max-width: 42ch;
}

.website-contact-items {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

/* Contact detail as a tile: subtle surface, circular tinted icon, hover lift. */
.website-contact-item {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    padding: var(--space-4);
    border-radius: var(--radius-lg, 0.75rem);
    background: var(--bs-tertiary-bg, rgba(127, 127, 127, 0.08));
    border: 1px solid var(--bs-border-color, rgba(127, 127, 127, 0.15));
    transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}

.website-contact-item:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.12);
    border-color: var(--color-primary-600);
}

.website-contact-item i {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: color-mix(in srgb, var(--color-primary-600) 16%, transparent);
    color: var(--color-primary-600);
    font-size: 1.05rem;
    margin: 0;
}

.website-contact-item-label {
    display: block;
    font-weight: 600;
    margin-bottom: 2px;
}

.website-contact-item-value,
.website-contact-item-value a {
    color: var(--bs-body-color, inherit);
    line-height: 1.5;
    text-decoration: none;
}

.website-contact-item-value a:hover {
    color: var(--color-primary-600);
    text-decoration: underline;
}

/* ----------------------------------------------------------
 * Responsive adjustments
 * ---------------------------------------------------------- */

@media (max-width: 991.98px) {
    :root {
        --website-section-padding-y: var(--space-12);
        --website-page-padding-y: var(--space-8);
    }

    .website-section-title {
        font-size: var(--font-size-2xl);
    }
}

@media (max-width: 575.98px) {
    :root {
        --website-section-padding-y: var(--space-8);
    }

    .website-footer-bottom {
        flex-direction: column;
        text-align: center;
    }
}

/* =============================================================================
 * Header effects: sticky, glass, shrink-on-scroll.
 * Toggled by OrgWebsiteNavWidget via classes on the <nav> element.
 * =========================================================================== */

.website-navbar-sticky {
    position: sticky;
    top: 0;
    z-index: 1030;
}

.website-navbar-glass {
    background-color: rgba(255, 255, 255, 0.65);
    backdrop-filter: blur(12px) saturate(150%);
    -webkit-backdrop-filter: blur(12px) saturate(150%);
    border-bottom-color: rgba(255, 255, 255, 0.2);
}

[data-theme="dark"] .website-navbar-glass {
    background-color: rgba(17, 17, 17, 0.55);
    border-bottom-color: rgba(255, 255, 255, 0.08);
}

.website-navbar-shrinkable {
    transition: min-height 0.25s ease, padding 0.25s ease, box-shadow 0.25s ease;
}

.website-navbar-shrinkable .website-nav-logo {
    transition: max-height 0.25s ease;
}

.website-navbar-shrunk {
    min-height: 52px;
    box-shadow: var(--shadow-sm);
}

.website-navbar-shrunk .navbar-brand {
    font-size: var(--font-size-base);
}

.website-navbar-shrunk .website-nav-logo {
    max-height: calc(var(--website-nav-logo-height, 40px) * 0.7);
}

/* =============================================================================
 * Footer style variants. Default .website-footer is dark - variants re-map the
 * --website-footer-* custom properties so existing rules keep working.
 * =========================================================================== */

.website-footer-light {
    --website-footer-bg: var(--color-neutral-100);
    --website-footer-text: var(--color-neutral-700);
    --website-footer-heading: var(--color-neutral-900);
    --website-footer-link: var(--color-neutral-700);
    --website-footer-link-hover: var(--color-primary-600);
    --website-footer-border: var(--color-neutral-300);
}

[data-theme="dark"] .website-footer-light {
    --website-footer-bg: var(--color-neutral-100);
    --website-footer-text: var(--color-neutral-700);
    --website-footer-heading: var(--color-neutral-900);
    --website-footer-border: var(--color-neutral-300);
}

.website-footer-primary {
    --website-footer-bg: var(--color-primary-600);
    --website-footer-text: rgba(255, 255, 255, 0.85);
    --website-footer-heading: #ffffff;
    --website-footer-link: rgba(255, 255, 255, 0.85);
    --website-footer-link-hover: #ffffff;
    --website-footer-border: rgba(255, 255, 255, 0.2);
}

.website-footer-transparent {
    --website-footer-bg: transparent;
    --website-footer-border: var(--border-default);
}

.website-footer-legal {
    text-align: center;
}

.website-footer-legal a {
    text-decoration: none;
}

/* =============================================================================
 * Secondary color accents (opt-in)
 *
 * The --color-secondary-* palette is emitted by OrgWebsiteBrandingHelper using
 * the explicit secondary color, or an analogous +30° fallback derived from
 * primary. Rules below are opt-in: existing markup is untouched unless it
 * carries one of these variant classes. Keep the secondary color to 10-20%
 * of the visual field - it is an accent, not a co-primary.
 * =========================================================================== */

/* --- Buttons (outline only; solid .btn-secondary intentionally not styled) - */
.website-body .btn-outline-secondary,
.website-navbar .btn-outline-secondary {
    color: var(--color-secondary-600);
    border-color: var(--color-secondary-600);
    background-color: transparent;
    transition: background-color var(--duration-150, 150ms) var(--ease-in-out), color var(--duration-150, 150ms) var(--ease-in-out), border-color var(--duration-150, 150ms) var(--ease-in-out);
}

.website-body .btn-outline-secondary:hover,
.website-navbar .btn-outline-secondary:hover {
    color: var(--color-secondary-700);
    border-color: var(--color-secondary-700);
    background-color: color-mix(in srgb, var(--color-secondary-500) 12%, transparent);
}

.website-body .btn-outline-secondary:focus,
.website-navbar .btn-outline-secondary:focus {
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-secondary-500) 25%, transparent);
}

[data-bs-theme="dark"] .website-body .btn-outline-secondary,
[data-bs-theme="dark"] .website-navbar .btn-outline-secondary {
    color: var(--color-secondary-300);
    border-color: var(--color-secondary-400);
}

[data-bs-theme="dark"] .website-body .btn-outline-secondary:hover,
[data-bs-theme="dark"] .website-navbar .btn-outline-secondary:hover {
    color: var(--color-secondary-200, var(--color-secondary-300));
    border-color: var(--color-secondary-300);
    background-color: color-mix(in srgb, var(--color-secondary-500) 18%, transparent);
}

/* --- Badges / tags / chips ------------------------------------------------- */
.website-body .badge.bg-secondary,
.website-body .website-chip-secondary {
    background-color: var(--color-secondary-50) !important;
    color: var(--color-secondary-700);
    border: 1px solid var(--color-secondary-200, var(--color-secondary-300));
}

[data-bs-theme="dark"] .website-body .badge.bg-secondary,
[data-bs-theme="dark"] .website-body .website-chip-secondary {
    background-color: rgba(var(--color-secondary-500-rgb), 0.15) !important;
    color: var(--color-secondary-200, var(--color-secondary-300));
    border-color: rgba(var(--color-secondary-500-rgb), 0.25);
}

.website-chip-secondary {
    display: inline-flex;
    align-items: center;
    padding: 0.15rem 0.55rem;
    border-radius: var(--radius-full, 999px);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
    line-height: 1.4;
}

/* --- Links & decorative icons --------------------------------------------- */
.website-link-accent {
    color: var(--color-secondary-600);
    text-decoration: none;
    transition: color var(--duration-150, 150ms) var(--ease-in-out);
}

.website-link-accent:hover {
    color: var(--color-secondary-700);
    text-decoration: underline;
}

.website-icon-accent {
    color: var(--color-secondary-500);
}

[data-bs-theme="dark"] .website-link-accent {
    color: var(--color-secondary-300);
}

[data-bs-theme="dark"] .website-link-accent:hover {
    color: var(--color-secondary-200, var(--color-secondary-300));
}

[data-bs-theme="dark"] .website-icon-accent {
    color: var(--color-secondary-300);
}

/* --- Heading underline (48px bar below h2/h3) ----------------------------- */
.website-heading-accent {
    display: block;
    position: relative;
    padding-bottom: calc(var(--space-3, 0.75rem) + 4px);
}

.website-heading-accent::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: 0;
    /* Per-section delimiter knobs (views/website/_section.php). The vars are
       only ever set on a configured section title; every other accent heading
       leaves them unset and falls back to the historical 48px x 3px bar.
       --wb-delim-resolved is the single colour source every style reads: a
       custom picked colour, else the theme default (--wb-delim-default, swapped
       in dark mode below), else the light secondary. Routing all styles through
       one variable - and NEVER overriding background-color per-theme - keeps the
       textured styles (dashed/dotted/gradient/dots) transparent in their gaps. */
    --wb-delim-resolved: var(--wb-delim-color, var(--wb-delim-default, var(--color-secondary-500)));
    width: var(--wb-delim-w, 48px);
    height: var(--wb-delim-h, 3px);
    border-radius: 2px;
    background-color: var(--wb-delim-resolved);
}

.text-center > .website-heading-accent::after,
.website-heading-accent.text-center::after,
.website-heading-accent--center::after {
    left: 50%;
    transform: translateX(-50%);
}

/* Dark mode: only swap the DEFAULT colour (a CSS variable on the heading, which
   inherits into ::after). We do NOT touch background-color here - doing so would
   win on specificity over the textured styles below and paint a solid fill
   behind their transparent gaps. A custom --wb-delim-color still wins. */
[data-bs-theme="dark"] .website-heading-accent {
    --wb-delim-default: var(--color-secondary-300);
}

/* ---- Per-section title delimiter styles --------------------------------- */
/* These classes only ever land on a configured section <h2>, so retexturing
   the ::after bar here never touches the other .website-heading-accent
   headings. 'bar' is the base ::after above and needs no rule. Each style
   reads --wb-delim-resolved (custom colour -> theme default -> secondary) so the
   colour picker and dark mode both compose with every style. */
.website-delim-none::after {
    display: none;
}

/* Square-ended hairline that spans the full content width. */
.website-delim-line::after {
    width: 100%;
    border-radius: 0;
}

/* Two stacked thin lines (top + bottom band, transparent gap between). */
.website-delim-double::after {
    border-radius: 0;
    background-color: transparent;
    background-image: linear-gradient(
        to bottom,
        var(--wb-delim-resolved) 0 35%,
        transparent 35% 65%,
        var(--wb-delim-resolved) 65% 100%
    );
    min-height: 5px;
}

/* Repeating dashes. */
.website-delim-dashed::after {
    border-radius: 0;
    background-color: transparent;
    background-image: repeating-linear-gradient(
        to right,
        var(--wb-delim-resolved) 0 8px,
        transparent 8px 14px
    );
}

/* Repeating dots (tight square stops). */
.website-delim-dotted::after {
    background-color: transparent;
    background-image: repeating-linear-gradient(
        to right,
        var(--wb-delim-resolved) 0 3px,
        transparent 3px 9px
    );
}

/* Solid bar fading out to transparent on the right. */
.website-delim-gradient::after {
    background-color: transparent;
    background-image: linear-gradient(
        to right,
        var(--wb-delim-resolved),
        transparent
    );
}

/* Three evenly spaced dots. Each cell holds one centered disc. */
.website-delim-dots::after {
    background-color: transparent;
    background-image: radial-gradient(
        circle,
        var(--wb-delim-resolved) 40%,
        transparent 45%
    );
    background-size: 33.33% 100%;
    background-repeat: repeat-x;
}

/* --- Hero / section corner accent shape ----------------------------------- */
.website-section-accent-corner {
    position: relative;
    overflow: hidden;
}

.website-section-accent-corner::before {
    content: "";
    position: absolute;
    top: -80px;
    right: -80px;
    width: 240px;
    height: 240px;
    border-radius: 50%;
    background-color: var(--color-secondary-500);
    opacity: 0.12;
    filter: blur(40px);
    pointer-events: none;
    z-index: 0;
}

.website-section-accent-corner.website-section-accent-corner-left::before {
    right: auto;
    left: -80px;
}

.website-section-accent-corner > * {
    position: relative;
    z-index: 1;
}

[data-bs-theme="dark"] .website-section-accent-corner::before {
    opacity: 0.18;
    background-color: var(--color-secondary-400);
}

/* --- Card left-border accent (opt-in on .website-blog-card or .card) ----- */
.website-card-accent-secondary {
    border-left: 3px solid var(--color-secondary-500);
}

[data-bs-theme="dark"] .website-card-accent-secondary {
    border-left-color: var(--color-secondary-300);
}

/* --- Card hover: lifted shadow with secondary tint ----------------------- */
.website-card-hover-accent {
    transition: box-shadow 200ms var(--ease-in-out, ease), transform 200ms var(--ease-in-out, ease);
}

.website-card-hover-accent:hover {
    box-shadow: 0 8px 24px color-mix(in srgb, var(--color-secondary-500) 22%, transparent);
    transform: translateY(-2px);
}

[data-bs-theme="dark"] .website-card-hover-accent:hover {
    box-shadow: 0 8px 24px color-mix(in srgb, var(--color-secondary-500) 32%, transparent);
}

/* --- Site-wide text selection + form focus ring (subtle) ----------------- */
.website-body ::selection {
    background-color: var(--color-secondary-100, var(--color-secondary-200));
    color: var(--color-secondary-900, var(--color-secondary-800));
}

[data-bs-theme="dark"] .website-body ::selection {
    background-color: var(--color-secondary-800, var(--color-secondary-700));
    color: var(--color-secondary-50);
}

.website-body .form-control:focus,
.website-body .form-select:focus,
.website-body .form-check-input:focus {
    border-color: var(--color-secondary-500);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-secondary-500) 15%, transparent);
}

/* --- Footer accents ------------------------------------------------------ */
.website-footer {
    border-top: 1px solid color-mix(in srgb, var(--color-secondary-500) 25%, transparent);
}

.website-footer-social-link {
    transition: color var(--duration-150, 150ms) var(--ease-in-out, ease);
}

.website-footer-social-link:hover {
    color: var(--color-secondary-500);
}

.website-footer-legal a {
    transition: color var(--duration-150, 150ms) var(--ease-in-out, ease);
}

.website-footer-legal a:hover {
    color: var(--color-secondary-500);
}

[data-bs-theme="dark"] .website-footer-social-link:hover,
[data-bs-theme="dark"] .website-footer-legal a:hover {
    color: var(--color-secondary-300);
}

/* --- Breadcrumbs (utility; markup opt-in) -------------------------------- */
.website-breadcrumbs {
    color: var(--text-muted);
    font-size: var(--font-size-sm);
}

.website-breadcrumbs a {
    color: var(--text-muted);
    text-decoration: none;
    transition: color var(--duration-150, 150ms) var(--ease-in-out, ease);
}

.website-breadcrumbs a:hover {
    color: var(--color-secondary-600);
}

.website-breadcrumbs .active {
    color: var(--color-secondary-600);
    font-weight: var(--font-weight-medium);
}

[data-bs-theme="dark"] .website-breadcrumbs a:hover,
[data-bs-theme="dark"] .website-breadcrumbs .active {
    color: var(--color-secondary-300);
}

/* --- Pagination ---------------------------------------------------------- */
.website-body .pagination .page-link {
    color: var(--color-secondary-700);
    transition: background-color var(--duration-150, 150ms) var(--ease-in-out, ease), color var(--duration-150, 150ms) var(--ease-in-out, ease);
}

.website-body .pagination .page-link:hover {
    background-color: var(--color-secondary-50);
    color: var(--color-secondary-800);
}

.website-body .pagination .page-item.active .page-link {
    background-color: var(--color-secondary-500);
    border-color: var(--color-secondary-500);
    color: #fff;
}

[data-bs-theme="dark"] .website-body .pagination .page-link {
    color: var(--color-secondary-300);
}

[data-bs-theme="dark"] .website-body .pagination .page-link:hover {
    background-color: rgba(var(--color-secondary-500-rgb), 0.15);
    color: var(--color-secondary-200, var(--color-secondary-300));
}

[data-bs-theme="dark"] .website-body .pagination .page-item.active .page-link {
    background-color: var(--color-secondary-400);
    border-color: var(--color-secondary-400);
    color: var(--color-neutral-950);
}

/* --- Prose links (inside .website-page-content) -------------------------- */
.website-page-content a:not(.btn):not(.website-chip-secondary):not(.website-link-accent) {
    color: var(--color-secondary-600);
    text-decoration-line: underline;
    text-decoration-color: color-mix(in srgb, var(--color-secondary-500) 40%, transparent);
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
    transition: color var(--duration-150, 150ms) var(--ease-in-out, ease), text-decoration-color var(--duration-150, 150ms) var(--ease-in-out, ease);
}

.website-page-content a:not(.btn):not(.website-chip-secondary):not(.website-link-accent):hover {
    color: var(--color-secondary-700);
    text-decoration-color: var(--color-secondary-500);
}

[data-bs-theme="dark"] .website-page-content a:not(.btn):not(.website-chip-secondary):not(.website-link-accent) {
    color: var(--color-secondary-300);
}

[data-bs-theme="dark"] .website-page-content a:not(.btn):not(.website-chip-secondary):not(.website-link-accent):hover {
    color: var(--color-secondary-200, var(--color-secondary-300));
}

/* =============================================================================
 * Layout & Type presets
 *
 * Admins choose presets in the Appearance tab (Corner Radius, Card Elevation,
 * Button Weight/Uppercase, Base Font Size, Heading Scale). Each preset emits
 * scoped --website-* custom properties from OrgWebsiteBrandingHelper, which
 * the rules below consume with fallbacks to the global design tokens.
 * =========================================================================== */

/* Buttons: weight / text-transform / tracking / shape */
.website-body .btn,
.website-navbar .btn,
.website-footer .btn {
    font-weight: var(--website-button-weight, var(--font-weight-medium));
    text-transform: var(--website-button-transform, none);
    letter-spacing: var(--website-button-tracking, 0);
    border-radius: var(--website-button-radius, var(--radius-md));
}


/* Card elevation + radius (listings across blog / events / shop, plus
 * the standalone .website-blog-card). Hover accent from
 * .website-card-hover-accent still layers on top. */
.website-body .card,
.website-body .website-blog-card {
    box-shadow: var(--website-card-shadow, var(--shadow-sm));
    border: var(--website-card-border, none);
    border-radius: var(--website-radius-lg, var(--radius-lg));
}

/* Inputs inherit the global radius too */
.website-body .form-control,
.website-body .form-select {
    border-radius: var(--website-radius-md, var(--radius-md));
}

/* Typography scale */
.website-body {
    font-size: var(--website-font-size-base, var(--font-size-base));
}

.website-body h1 {
    font-size: var(--website-font-size-h1, var(--font-size-4xl));
}

.website-body h2 {
    font-size: var(--website-font-size-h2, var(--font-size-3xl));
}

.website-body h3 {
    font-size: var(--website-font-size-h3, var(--font-size-2xl));
}

.website-body .display-1,
.website-body .display-2,
.website-body .display-3,
.website-body .display-4,
.website-body .display-5,
.website-body .display-6 {
    font-size: var(--website-font-size-display, var(--font-size-5xl));
}

/* =============================================================================
 * Announcement bar
 *
 * Thin strip rendered above the navbar. Four style variants (primary / secondary
 * / dark / light). Dismissible by default; close state persists via cookie.
 * =========================================================================== */

.website-announcement {
    padding: 0.5rem 2.5rem 0.5rem 1rem;
    text-align: center;
    font-size: var(--font-size-sm);
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-3);
    position: relative;
    line-height: 1.4;
}

.website-announcement-primary {
    background-color: var(--color-primary-600);
    color: #fff;
}

.website-announcement-secondary {
    background-color: var(--color-secondary-600);
    color: #fff;
}

.website-announcement-dark {
    background-color: var(--color-neutral-900);
    color: var(--color-neutral-100);
}

.website-announcement-light {
    background-color: var(--color-neutral-100);
    color: var(--color-neutral-900);
    border-bottom: 1px solid var(--border-default);
}

.website-announcement a {
    color: inherit;
    text-decoration: underline;
}

.website-announcement .website-announcement-cta {
    color: inherit;
    border-color: currentColor;
    padding: 0.15rem 0.75rem;
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
    text-decoration: none;
    border-radius: var(--website-button-radius, var(--radius-md));
    border: 1px solid currentColor;
    transition: background-color var(--duration-150, 150ms) var(--ease-in-out, ease);
}

.website-announcement .website-announcement-cta:hover {
    background-color: color-mix(in srgb, currentColor 12%, transparent);
}

.website-announcement-dismiss {
    position: absolute;
    right: 0.5rem;
    top: 50%;
    transform: translateY(-50%);
    background: transparent;
    border: 0;
    color: inherit;
    opacity: 0.7;
    cursor: pointer;
    padding: 0.25rem 0.5rem;
    line-height: 1;
    font-size: 1rem;
}

.website-announcement-dismiss:hover {
    opacity: 1;
}

/* =======================================================================
 * New widget styles - inspired by tahliastanton.com
 * ======================================================================= */

/* ----------------------------------------------------------------------
 * Header: double-layer mode (utility row above main navbar)
 * Activated by .header-double-layer on the <header> element.
 * ---------------------------------------------------------------------- */
.header-double-layer .header-top-bar {
    width: 100%;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--color-neutral-200, rgba(0, 0, 0, 0.06));
    background-color: inherit;
    font-size: var(--font-size-sm, 14px);
}
.header-double-layer .header-top-bar-inner {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 1rem;
    min-height: 36px;
}
.header-double-layer.header-top-bar-logo-left .header-top-bar-inner {
    grid-template-columns: auto 1fr 1fr;
}
.header-top-bar-left { justify-self: start; display: flex; align-items: center; gap: 0.75rem; }
.header-top-bar-logo { justify-self: center; display: flex; align-items: center; justify-content: center; }
.header-double-layer.header-top-bar-logo-left .header-top-bar-logo { justify-self: start; }
.header-top-bar-right { justify-self: end; display: flex; align-items: center; gap: 0.75rem; }
.header-top-bar-item { display: inline-flex; align-items: center; }
.header-top-bar-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    color: inherit;
    text-decoration: none;
    transition: background-color 0.2s var(--ease-out, ease);
}
.header-top-bar-icon:hover { background-color: rgba(0, 0, 0, 0.05); }
.header-top-bar-logo-img { max-height: 32px; width: auto; }
.header-top-bar-logo-link { text-decoration: none; color: inherit; display: inline-flex; align-items: center; }
/* Hide the navbar brand when the top bar already shows the logo */
.header-double-layer .navbar-brand { display: none; }
@media (max-width: 767.98px) {
    .header-double-layer .header-top-bar-inner { grid-template-columns: auto 1fr auto; gap: 0.5rem; }
    .header-top-bar-right { gap: 0.25rem; }
}

/* ----------------------------------------------------------------------
 * Marquee (infinite horizontal scroll)
 * ---------------------------------------------------------------------- */
.marquee-widget {
    width: 100%;
    overflow: hidden;
    position: relative;
}
.marquee-track {
    display: flex;
    flex-wrap: nowrap;
    width: max-content;
    gap: var(--space-8, 32px);
    align-items: center;
    animation: marquee-scroll-left var(--marquee-duration, 40s) linear infinite;
    will-change: transform;
}
.marquee-track[data-direction="right"] { animation-name: marquee-scroll-right; }
.marquee-widget[data-pause-on-hover="1"]:hover .marquee-track { animation-play-state: paused; }
@keyframes marquee-scroll-left {
    from { transform: translateX(0); }
    to { transform: translateX(-50%); }
}
@keyframes marquee-scroll-right {
    from { transform: translateX(-50%); }
    to { transform: translateX(0); }
}
.marquee-item { flex: 0 0 auto; display: flex; align-items: center; justify-content: center; }
.marquee-mode-image-strip .marquee-item { min-width: 120px; }
.marquee-mode-image-strip .marquee-item-img {
    max-height: 60px;
    width: auto;
    object-fit: contain;
    filter: grayscale(30%);
    opacity: 0.8;
    transition: filter 0.3s, opacity 0.3s;
}
.marquee-mode-image-strip .marquee-item:hover .marquee-item-img { filter: none; opacity: 1; }
.marquee-mode-card-strip .marquee-item { min-width: 280px; max-width: 280px; }
.marquee-mode-card-strip .marquee-card-item > * { width: 100%; }
@media (prefers-reduced-motion: reduce) {
    .marquee-track { animation: none; }
    .marquee-widget { overflow-x: auto; scroll-snap-type: x mandatory; }
}

/* ----------------------------------------------------------------------
 * Media Grid (preset layouts for image / video / text tiles)
 * ---------------------------------------------------------------------- */
.media-grid { display: grid; width: 100%; }
.media-grid-gap-none { gap: 0; }
.media-grid-gap-sm { gap: var(--space-2, 8px); }
.media-grid-gap-md { gap: var(--space-4, 16px); }
.media-grid-gap-lg { gap: var(--space-6, 24px); }
.media-grid-2x2-mosaic { grid-template-columns: 1fr 1fr; grid-template-rows: auto auto; }
.media-grid-3-col-strip { grid-template-columns: 1fr 1fr 1fr; }
.media-grid-hero-plus-4 { grid-template-columns: 2fr 1fr 1fr; grid-template-rows: 1fr 1fr; }
.media-grid-hero-plus-4 > .media-grid-tile:first-child { grid-row: span 2; }
.media-grid-tile {
    position: relative;
    overflow: hidden;
    display: block;
    background: var(--color-neutral-100, #f5f5f5);
    min-height: 200px;
    text-decoration: none;
    color: inherit;
}
.media-grid-rounded .media-grid-tile { border-radius: var(--radius-lg, 12px); }
.media-grid-tile-img,
.media-grid-tile-video {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.4s var(--ease-out, ease);
}
.media-grid-tile:hover .media-grid-tile-img,
.media-grid-tile:hover .media-grid-tile-video { transform: scale(1.03); }
.media-grid-tile-caption {
    position: absolute;
    bottom: 0; left: 0; right: 0;
    padding: 1rem;
    background: linear-gradient(to top, rgba(0,0,0,0.6), transparent);
    color: #fff;
    font-size: var(--font-size-sm, 14px);
}
.media-grid-tile-text {
    padding: 2rem;
    display: flex;
    flex-direction: column;
    justify-content: center;
    height: 100%;
    background: var(--color-neutral-50, #fafafa);
}
.media-grid-tile-heading { margin: 0 0 0.5rem; font-size: var(--font-size-xl, 20px); }
.media-grid-tile-body { margin: 0; color: var(--color-neutral-600, #666); }
.media-grid-tile-empty { background: transparent; min-height: 0; }
@media (max-width: 767.98px) {
    .media-grid-2x2-mosaic,
    .media-grid-3-col-strip,
    .media-grid-hero-plus-4 {
        grid-template-columns: 1fr;
        grid-template-rows: none;
    }
    .media-grid-hero-plus-4 > .media-grid-tile:first-child { grid-row: auto; }
}

/* ----------------------------------------------------------------------
 * Image & Text (2-col image + text; internal name "split-bio")
 * ---------------------------------------------------------------------- */
.split-bio { width: 100%; }
.split-bio-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-10, 40px);
    align-items: center;
}
/* Vertical alignment of the image against the text column (columns layout).
   Base rule above keeps center as the fallback for sections saved before the
   knob existed; these modifiers override it. */
.split-bio-valign-top .split-bio-grid { align-items: start; }
.split-bio-valign-center .split-bio-grid { align-items: center; }
.split-bio-valign-bottom .split-bio-grid { align-items: end; }
.split-bio-image-right .split-bio-grid {
    grid-template-columns: 1fr 1fr;
    direction: rtl;
}
/* No image uploaded: one full-width column instead of a half-empty 2-col grid. */
.split-bio-no-image .split-bio-grid {
    grid-template-columns: 1fr;
    direction: ltr;
}
.split-bio-no-image .split-bio-text { max-width: none; }
.split-bio-image-right .split-bio-grid > * { direction: ltr; }
.split-bio-image { display: flex; justify-content: center; }
.split-bio-image-img { display: block; width: 100%; height: auto; object-fit: cover; }
.split-bio-shape-rectangle .split-bio-image-img { border-radius: 0; }
.split-bio-shape-rounded .split-bio-image-img { border-radius: var(--radius-xl, 16px); }
.split-bio-shape-circle .split-bio-image-img {
    border-radius: 50%;
    aspect-ratio: 1 / 1;
    max-width: 440px;
    margin: 0 auto;
}
.split-bio-shape-full-bleed .split-bio-image-img {
    border-radius: 0;
    aspect-ratio: 4 / 5;
    width: 100%;
}
.split-bio-text { max-width: 560px; }
.split-bio-heading { font-size: var(--font-size-4xl, 36px); margin: 0 0 1rem; line-height: 1.15; }
.split-bio-body { color: var(--color-neutral-700, #4a4a4a); line-height: 1.65; margin-bottom: 1.5rem; }
.split-bio-button { display: inline-block; }
/* Wrap layout: the image floats and the body text flows around it (Word-style).
   Drops the grid to a block flow so the text is a normal sibling of the float. */
.split-bio-wrap .split-bio-grid {
    display: block;
    direction: ltr;
}
.split-bio-wrap .split-bio-image {
    float: left;
    width: 42%;
    max-width: 420px;
    margin: 0 var(--space-10, 40px) var(--space-6, 24px) 0;
}
.split-bio-wrap.split-bio-image-right .split-bio-image {
    float: right;
    margin: 0 0 var(--space-6, 24px) var(--space-10, 40px);
}
.split-bio-wrap .split-bio-text { max-width: none; }
.split-bio-wrap .split-bio-grid::after { content: ""; display: block; clear: both; }
@media (max-width: 767.98px) {
    .split-bio-grid,
    .split-bio-image-right .split-bio-grid {
        grid-template-columns: 1fr;
        direction: ltr;
        gap: var(--space-6, 24px);
    }
    /* Un-float on mobile so the image stacks above the text instead of
       squeezing a narrow column beside a few cramped words. */
    .split-bio-wrap .split-bio-image {
        float: none;
        width: 100%;
        max-width: none;
        margin: 0 0 var(--space-6, 24px) 0;
    }
}

/* ----------------------------------------------------------------------
 * Promo Trio (2-4 tall tiles with image + overlay text + CTA)
 * ---------------------------------------------------------------------- */
.promo-trio { display: grid; width: 100%; gap: var(--space-4, 16px); }
.promo-trio-count-2 { grid-template-columns: repeat(2, 1fr); }
.promo-trio-count-3 { grid-template-columns: repeat(3, 1fr); }
.promo-trio-count-4 { grid-template-columns: repeat(4, 1fr); }
.promo-trio-tile {
    position: relative;
    display: block;
    overflow: hidden;
    background-color: var(--color-neutral-200, #e5e5e5);
    background-size: cover;
    background-position: center;
    text-decoration: none;
    color: #fff;
    border-radius: var(--radius-lg, 12px);
    transition: transform 0.3s var(--ease-out, ease);
}
.promo-trio-tile:hover { transform: translateY(-4px); }
.promo-trio-height-short .promo-trio-tile { aspect-ratio: 4 / 3; }
.promo-trio-height-medium .promo-trio-tile { aspect-ratio: 3 / 4; }
.promo-trio-height-tall .promo-trio-tile { aspect-ratio: 2 / 3; }
.promo-trio-tile-overlay {
    position: absolute;
    inset: 0;
    display: flex;
    padding: 2rem;
    color: inherit;
}
.promo-trio-tile-overlay::before {
    content: "";
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, var(--promo-trio-overlay-opacity, 0.4));
    z-index: 0;
}
.promo-trio-pos-top .promo-trio-tile-overlay { align-items: flex-start; }
.promo-trio-pos-center .promo-trio-tile-overlay { align-items: center; }
.promo-trio-pos-bottom .promo-trio-tile-overlay { align-items: flex-end; }
.promo-trio-tile-content { position: relative; z-index: 1; width: 100%; }
.promo-trio-tile-heading { margin: 0 0 0.5rem; font-size: var(--font-size-2xl, 24px); line-height: 1.2; color: inherit; }
.promo-trio-tile-subheading { margin: 0 0 1rem; opacity: 0.9; line-height: 1.5; color: inherit; }
.promo-trio-tile-cta {
    display: inline-block;
    padding: 0.5rem 1rem;
    border: 1px solid currentColor;
    border-radius: var(--radius-md, 8px);
    font-size: var(--font-size-sm, 14px);
    font-weight: var(--font-weight-medium, 500);
    transition: background-color 0.2s var(--ease-out, ease);
}
.promo-trio-tile:hover .promo-trio-tile-cta { background-color: rgba(255, 255, 255, 0.15); }
@media (max-width: 767.98px) {
    .promo-trio-count-2,
    .promo-trio-count-3,
    .promo-trio-count-4 { grid-template-columns: 1fr; }
    .promo-trio-height-short .promo-trio-tile,
    .promo-trio-height-medium .promo-trio-tile,
    .promo-trio-height-tall .promo-trio-tile { aspect-ratio: 16 / 9; }
}

/* ----------------------------------------------------------------------
 * Hero compositional variants (split-media / minimal-left / overlay-center)
 * ---------------------------------------------------------------------- */
/* Split media - copy beside a tall image panel. */
.hero-variant-split-media .hero-split-image {
    width: 100%;
    min-height: 320px;
    border-radius: var(--website-radius-lg, 0.875rem);
    box-shadow: var(--website-card-shadow, var(--shadow-md));
}
.hero-variant-split-media .hero-split-copy p {
    margin-left: 0;
    margin-right: 0;
}
@media (max-width: 991.98px) {
    .hero-variant-split-media .hero-split-media {
        margin-top: 1.5rem;
    }
    .hero-variant-split-media .hero-split-image {
        min-height: 220px;
    }
}

/* Minimal left - a single left-aligned headline column with whitespace. */
.hero-variant-minimal-left .container {
    max-width: 760px;
    margin-left: 0;
}
.hero-variant-minimal-left h1 {
    margin-left: 0;
}
.hero-variant-minimal-left p {
    margin-left: 0 !important;
    margin-right: 0;
}

/* Overlay center - text over a full-bleed image with a dark scrim (scrim and
   light text are emitted by the widget; nothing extra needed here, but keep a
   hook for future tuning). */
.hero-variant-overlay-center {
    position: relative;
}

/* ----------------------------------------------------------------------
 * Hero Slider (Bootstrap fade-carousel mode on HeroSectionWidget)
 * ---------------------------------------------------------------------- */
.hero-slider { position: relative; overflow: hidden; }
.hero-slider-item {
    min-height: 60vh;
    background-size: cover;
    background-position: center;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
}
.hero-slider-overlay {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.35);
    z-index: 1;
}
.hero-slider-content {
    position: relative;
    z-index: 2;
    text-align: center;
    max-width: 800px;
}
.hero-slider-heading {
    font-size: var(--font-size-5xl, 48px);
    margin: 0 0 1rem;
    color: inherit;
    line-height: 1.1;
}
.hero-slider-subheading {
    font-size: var(--font-size-xl, 20px);
    margin: 0 0 1.5rem;
    color: inherit;
    opacity: 0.95;
}
.hero-slider .carousel-indicators button { background-color: rgba(255, 255, 255, 0.6); }
.hero-slider .carousel-indicators button.active { background-color: #fff; }

/* Dual-image hover overlay (.card-img-hover) now lives in site.css so it
 * applies on every layout, not just org-website pages. */

/* ----------------------------------------------------------------------
 * Org website navbar - brand alignment + double-layer mode
 * ---------------------------------------------------------------------- */

/* Brand alignment in single-row mode */
.website-navbar.website-navbar-brand-center:not(.website-navbar-double) > .container {
    position: relative;
}
.website-navbar.website-navbar-brand-center:not(.website-navbar-double) > .container > .navbar-brand {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
}
/* Keep nav items right-aligned; brand absolutely centered overlays visually */

/* Two-row mode */
.website-navbar.website-navbar-double {
    flex-direction: column;
    padding: 0;
}
.website-navbar-double .website-navbar-row {
    width: 100%;
    padding: 0.5rem 0;
}
.website-navbar-double .website-navbar-row-brand {
    border-bottom: 1px solid var(--color-neutral-200, rgba(0, 0, 0, 0.08));
}
.website-navbar-double .website-navbar-row-brand > .container {
    display: flex;
    align-items: center;
}
.website-navbar-double .website-navbar-row-nav > .container {
    display: flex;
    align-items: center;
}
/* Brand alignment inside the top row */
.website-navbar-double.website-navbar-brand-left  .website-navbar-row-brand > .container { justify-content: flex-start; }
.website-navbar-double.website-navbar-brand-center .website-navbar-row-brand > .container { justify-content: center; }
/* Menu in the second row: center the nav list when brand is centered,
   otherwise keep the existing right alignment via ms-auto on the <ul>. */
.website-navbar-double.website-navbar-brand-center .website-navbar-row-nav .navbar-nav { margin: 0 auto !important; }
.website-navbar-double .website-navbar-row-nav .navbar-brand { display: none; }

/* Mobile: always collapse to single row regardless of mode */
@media (max-width: 991.98px) {
    .website-navbar.website-navbar-double {
        flex-direction: row;
        padding: 0.5rem 0;
    }
    .website-navbar-double .website-navbar-row {
        padding: 0;
        border: 0;
    }
    .website-navbar-double .website-navbar-row-brand > .container,
    .website-navbar-double .website-navbar-row-nav > .container {
        display: contents;
    }
}

/* Row 1 in double-layer mode: three equal columns.
   Left slot stays empty (reserved for future search icon), center holds the
   brand when Brand Alignment = Center, right always holds the extras row.
   When Brand Alignment = Left the brand snaps to the left slot instead. */
.website-navbar-double .website-navbar-row-brand > .container {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    align-items: center;
    gap: 1rem;
}
.website-navbar-double .website-navbar-row-brand .navbar-brand {
    margin: 0;
}
.website-navbar-double.website-navbar-brand-left .website-navbar-row-brand .navbar-brand {
    grid-column: 1;
    justify-self: start;
}
.website-navbar-double.website-navbar-brand-center .website-navbar-row-brand .navbar-brand {
    grid-column: 2;
    justify-self: center;
}
.website-navbar-double .website-navbar-row-brand .website-navbar-extras {
    grid-column: 3;
    justify-self: end;
    margin: 0 !important;
}
.website-navbar-double .website-navbar-extras {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}
.website-navbar-double .website-navbar-extras-item {
    display: inline-flex;
    align-items: center;
}
@media (max-width: 991.98px) {
    .website-navbar-double .website-navbar-row-brand > .container {
        display: flex;
        justify-content: space-between;
    }
    .website-navbar-double .website-navbar-extras { display: none !important; }
}

/* ============================================================================
 * Section background animations
 *
 * Opt-in per section via the renderer-only `bg_animation` config key, which
 * adds a `.website-section-anim-{key}` class to the section wrapper. All
 * three animations target a ::before pseudo so the section's base background
 * stays untouched and motion composes with any solid color. Glow's highlight
 * opacity caps at 0.12 so saturated brand colors (electric blue, neon pink)
 * still feel like a gentle highlight rather than a flashlight orbiting the
 * section. `prefers-reduced-motion: reduce` disables all three visually
 * while the selected value stays in DB - flipping the OS preference back
 * restores the animation without any user action.
 * ============================================================================ */

.website-section-anim-pulse,
.website-section-anim-glow,
.website-section-anim-shimmer {
    position: relative;
    isolation: isolate;
    overflow: hidden;
}

.website-section-anim-pulse::before,
.website-section-anim-glow::before,
.website-section-anim-shimmer::before {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    mix-blend-mode: overlay;
    z-index: 0;
}

/* Pulse: slow radial breath from the section center. 6s ease-in-out infinite,
 * 0% to 8% opacity peak. The most "alive but unobtrusive" of the three. */
@keyframes wb-section-pulse {
    0%, 100% { opacity: 0; }
    50%      { opacity: 0.08; }
}
/* Speed controlled by --wb-bg-intensity. 0 -> 9s (slow), 1 -> 3s (fast),
 * default 0.5 -> 6s (matches pre-slider behavior exactly). */
.website-section-anim-pulse::before {
    background: radial-gradient(circle at 50% 50%, #fff, transparent 65%);
    animation: wb-section-pulse calc(9s - var(--wb-bg-intensity, 0.5) * 6s) ease-in-out infinite;
}

/* Glow: subtle highlight orbiting the section over 30s. Opacity capped at
 * 0.12 (peak) - any higher and saturated brand colors read as a flashlight. */
@keyframes wb-section-glow {
    0%   { transform: translate(-20%, -20%); opacity: 0.06; }
    25%  { transform: translate( 30%, -10%); opacity: 0.12; }
    50%  { transform: translate( 25%,  25%); opacity: 0.10; }
    75%  { transform: translate(-15%,  20%); opacity: 0.12; }
    100% { transform: translate(-20%, -20%); opacity: 0.06; }
}
/* Speed controlled by --wb-bg-intensity. 0 -> 50s (slow), 1 -> 10s (fast),
 * default 0.5 -> 30s (matches pre-slider behavior exactly). */
.website-section-anim-glow::before {
    background: radial-gradient(circle at 50% 50%, #fff, transparent 45%);
    width: 60%;
    height: 60%;
    left: 20%;
    top: 20%;
    inset: auto;
    animation: wb-section-glow calc(50s - var(--wb-bg-intensity, 0.5) * 40s) ease-in-out infinite;
}

/* Shimmer: 30deg gloss sheen sweeping across the section every 8s. A 25%
 * keyframe (sweep complete) plus a long dwell at 100% gives a ~6s pause
 * between sweeps so the eye gets a rest instead of a constant gloss. */
@keyframes wb-section-shimmer {
    0%   { transform: translateX(-120%) skewX(-30deg); opacity: 0; }
    10%  { opacity: 0.18; }
    25%  { transform: translateX( 220%) skewX(-30deg); opacity: 0; }
    100% { transform: translateX( 220%) skewX(-30deg); opacity: 0; }
}
/* Speed controlled by --wb-bg-intensity. 0 -> 12s (slow), 1 -> 4s (fast),
 * default 0.5 -> 8s (matches pre-slider behavior exactly). */
.website-section-anim-shimmer::before {
    background: linear-gradient(
        90deg,
        transparent 0%,
        rgba(255, 255, 255, 0.0) 30%,
        rgba(255, 255, 255, 0.55) 50%,
        rgba(255, 255, 255, 0.0) 70%,
        transparent 100%
    );
    width: 50%;
    animation: wb-section-shimmer calc(12s - var(--wb-bg-intensity, 0.5) * 8s) ease-out infinite;
}

@media (prefers-reduced-motion: reduce) {
    .website-section-anim-pulse::before,
    .website-section-anim-glow::before,
    .website-section-anim-shimmer::before {
        animation: none;
        display: none;
    }
}

/* ============================================================================
 * Phase 2 - Image overlay + Ken Burns, Gradient pan + rotate, Mesh drift
 *
 * Picks up where Phase 1 left off: solids already have pulse/glow/shimmer
 * via ::before pseudos; here we extend motion to Gradient, Mesh and Image,
 * plus add Image overlay variants that compose with Ken Burns / parallax.
 * Each animation has a `prefers-reduced-motion: reduce` disable at the end.
 * ============================================================================ */

/* ---- Image overlay variants ----
 * `::before` pseudo sits above the background image and below content.
 * Opacity reads `--wb-bg-intensity` (the per-bg slider) so admins dial in
 * exactly how heavy the overlay should be. */
.website-section-image-overlay-darken::before,
.website-section-image-overlay-lighten::before,
.website-section-image-overlay-tint_primary::before,
.website-section-image-overlay-tint_secondary::before {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 0;
    opacity: var(--wb-bg-intensity, 0.3);
}
.website-section-image-overlay-darken::before          { background: #000; }
.website-section-image-overlay-lighten::before         { background: #fff; }
.website-section-image-overlay-tint_primary::before    { background: var(--color-primary-500); }
.website-section-image-overlay-tint_secondary::before  { background: var(--color-secondary-500); }

/* Dark theme inverts the lighten/darken wash so contrast intent is preserved:
 * a white wash chosen for dark text becomes a black wash for the now-light text
 * (and vice-versa). Opacity (--wb-bg-intensity) is unchanged. Tints are
 * theme-independent and stay as-is. */
[data-theme="dark"] .website-section-image-overlay-lighten::before { background: #000; }
[data-theme="dark"] .website-section-image-overlay-darken::before  { background: #fff; }

/* Children of image-bg sections need to sit above the overlay. The base
 * `.website-section-image > *` rule already handles `position: relative; z-index: 1`,
 * which keeps content above any ::before. */

/* A darken / tint overlay implies light content sitting on a darkened image, so
 * the text must read white - mirroring how .website-section-dark forces white
 * text. Scoped to HERO image sections only (the wrapper carries both the overlay
 * class and data-web-section-type, see views/website/_section.php), so the
 * one-click cover hero stays legible while existing non-hero image sections are
 * left untouched. The 'lighten' and 'none' overlays keep the default dark text. */
.website-section-image-overlay-darken[data-web-section-type="hero"],
.website-section-image-overlay-tint_primary[data-web-section-type="hero"],
.website-section-image-overlay-tint_secondary[data-web-section-type="hero"] {
    color: #fff;
}
.website-section-image-overlay-darken[data-web-section-type="hero"] *,
.website-section-image-overlay-darken[data-web-section-type="hero"] h1,
.website-section-image-overlay-darken[data-web-section-type="hero"] h2,
.website-section-image-overlay-darken[data-web-section-type="hero"] h3,
.website-section-image-overlay-darken[data-web-section-type="hero"] h4,
.website-section-image-overlay-darken[data-web-section-type="hero"] p,
.website-section-image-overlay-darken[data-web-section-type="hero"] span,
.website-section-image-overlay-darken[data-web-section-type="hero"] a:not(.btn),
.website-section-image-overlay-tint_primary[data-web-section-type="hero"] *,
.website-section-image-overlay-tint_primary[data-web-section-type="hero"] h1,
.website-section-image-overlay-tint_primary[data-web-section-type="hero"] h2,
.website-section-image-overlay-tint_primary[data-web-section-type="hero"] h3,
.website-section-image-overlay-tint_primary[data-web-section-type="hero"] h4,
.website-section-image-overlay-tint_primary[data-web-section-type="hero"] p,
.website-section-image-overlay-tint_primary[data-web-section-type="hero"] span,
.website-section-image-overlay-tint_primary[data-web-section-type="hero"] a:not(.btn),
.website-section-image-overlay-tint_secondary[data-web-section-type="hero"] *,
.website-section-image-overlay-tint_secondary[data-web-section-type="hero"] h1,
.website-section-image-overlay-tint_secondary[data-web-section-type="hero"] h2,
.website-section-image-overlay-tint_secondary[data-web-section-type="hero"] h3,
.website-section-image-overlay-tint_secondary[data-web-section-type="hero"] h4,
.website-section-image-overlay-tint_secondary[data-web-section-type="hero"] p,
.website-section-image-overlay-tint_secondary[data-web-section-type="hero"] span,
.website-section-image-overlay-tint_secondary[data-web-section-type="hero"] a:not(.btn) {
    color: inherit;
}

/* ---- Image Ken Burns ----
 * The image-frame is an absolutely-positioned inner div the renderer emits
 * when image_animation === 'ken_burns'. Slight over-scale at rest (1.05)
 * hides edges that would otherwise peek out during the pan, and a 30s
 * ease-in-out cycle keeps the motion calm. */
.website-section-image-frame {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    pointer-events: none;
    z-index: -1;
    transform: scale(1.05);
    will-change: transform;
}
@keyframes wb-ken-burns {
    0%   { transform: scale(1.05) translate(0%, 0%); }
    50%  { transform: scale(1.14) translate(-2%, 1%); }
    100% { transform: scale(1.05) translate(0%, 0%); }
}
.website-section-image-anim-ken_burns .website-section-image-frame {
    animation: wb-ken-burns 30s ease-in-out infinite;
}

/* ---- Image parallax ----
 * Pin the section image while the page scrolls over it. The renderer paints
 * the image directly on the .website-section-image wrapper (the static path),
 * so background-attachment:fixed is all that's needed. It's janky/unsupported
 * on touch, so fall back to normal scroll there. Mirrors the Image Divider
 * .image-divider--parallax rule. */
.website-section-image.website-section-image-anim-parallax {
    background-attachment: fixed;
}
@media (hover: none), (max-width: 768px) {
    .website-section-image.website-section-image-anim-parallax { background-attachment: scroll; }
}

/* ---- Gradient pan ----
 * `background-size: 200% 200%` makes the gradient twice as wide as the
 * section; animating `background-position` slides the visible window
 * across, producing a smooth pan. Slider controls speed: 0 -> 30s,
 * 0.5 -> 20s (default), 1 -> 10s. */
.website-section-gradient-anim-pan {
    background-size: 200% 200%;
    animation: wb-gradient-pan calc(30s - var(--wb-bg-intensity, 0.5) * 20s) linear infinite;
    will-change: background-position;
}
@keyframes wb-gradient-pan {
    0%   { background-position: 0% 50%; }
    50%  { background-position: 100% 50%; }
    100% { background-position: 0% 50%; }
}

/* ---- Gradient rotate ----
 * Uses `@property --wb-grad-angle` so the angle interpolates smoothly.
 * Safari 16.4+ (March 2023), all modern Chrome/Firefox - older Safari
 * silently keeps the gradient at its initial angle (no error, no flicker).
 * Rotate overrides each variant's `background` so the angle is taken from
 * the animatable variable. Radial gradient has no angle so it's not in
 * the override list - selecting Rotate with the Radial variant is a no-op. */
@property --wb-grad-angle {
    syntax: '<angle>';
    initial-value: 135deg;
    inherits: false;
}
.website-section-gradient-anim-rotate {
    --wb-grad-angle: 135deg;
    animation: wb-grad-rotate calc(40s - var(--wb-bg-intensity, 0.5) * 30s) linear infinite;
}
@keyframes wb-grad-rotate {
    to { --wb-grad-angle: 495deg; }
}
/* Deep (base gradient): swap the fixed 135deg for the animatable angle. */
.website-section-gradient-anim-rotate.website-section-gradient {
    background: linear-gradient(
        var(--wb-grad-angle),
        var(--color-primary-600),
        var(--color-primary-800) calc(70% + var(--wb-bg-intensity, 0.5) * 60%)
    );
}
/* Duo */
.website-section-gradient-anim-rotate.website-section-gradient-duo {
    background: linear-gradient(
        var(--wb-grad-angle),
        var(--color-primary-500),
        var(--color-secondary-500)
    );
}
/* Sweep */
.website-section-gradient-anim-rotate.website-section-gradient-sweep {
    background: linear-gradient(
        var(--wb-grad-angle),
        var(--color-primary-500) 0%,
        color-mix(in srgb, var(--bg-secondary, #f8f9fa) 80%, transparent) calc(30% + var(--wb-bg-intensity, 0.5) * 40%),
        var(--color-secondary-500) 100%
    );
}

/* ---- Mesh drift ----
 * Each mesh variant has its own per-variant keyframes so Diagonal feels
 * different from Aurora etc. The technique is the same across all four:
 * `background-size: 110%` extends the gradient slightly beyond the section,
 * and `background-position` keyframes shift the visible window subtly.
 * Variant identity comes through via the SHAPE of the keyframe path
 * (diagonal, vertical-only, circular, horizontal-only). */
.website-section-mesh-anim-drift {
    background-size: 110% 110%;
    will-change: background-position;
}

/* Diagonal is the default mesh - the wrapper has .website-section-mesh
 * but no .website-section-mesh-* variant class. Use :not() to scope. */
.website-section-mesh-anim-drift.website-section-mesh:not(.website-section-mesh-aurora):not(.website-section-mesh-spotlight):not(.website-section-mesh-twin) {
    animation: wb-mesh-drift-diagonal calc(60s - var(--wb-bg-intensity, 0.5) * 40s) ease-in-out infinite;
}
.website-section-mesh-anim-drift.website-section-mesh-aurora {
    animation: wb-mesh-drift-aurora calc(50s - var(--wb-bg-intensity, 0.5) * 30s) ease-in-out infinite;
}
.website-section-mesh-anim-drift.website-section-mesh-spotlight {
    animation: wb-mesh-drift-spotlight calc(70s - var(--wb-bg-intensity, 0.5) * 40s) ease-in-out infinite;
}
.website-section-mesh-anim-drift.website-section-mesh-twin {
    animation: wb-mesh-drift-twin calc(55s - var(--wb-bg-intensity, 0.5) * 35s) ease-in-out infinite;
}

/* Diagonal: drift along the primary diagonal. */
@keyframes wb-mesh-drift-diagonal {
    0%, 100% { background-position: 0% 0%; }
    50%      { background-position: 5% 5%; }
}
/* Aurora: bands sway vertically (horizontal stays put). */
@keyframes wb-mesh-drift-aurora {
    0%, 100% { background-position: 50% 0%; }
    50%      { background-position: 50% 5%; }
}
/* Spotlight: small circular wander around center, four-stop path. */
@keyframes wb-mesh-drift-spotlight {
    0%, 100% { background-position: 50% 50%; }
    25%      { background-position: 52% 48%; }
    50%      { background-position: 50% 52%; }
    75%      { background-position: 48% 50%; }
}
/* Twin: breathe horizontally between the two halves. */
@keyframes wb-mesh-drift-twin {
    0%, 100% { background-position: 0% 50%; }
    50%      { background-position: 5% 50%; }
}

/* ---- Phase 2 reduced-motion guard ---- */
@media (prefers-reduced-motion: reduce) {
    .website-section-image-anim-ken_burns .website-section-image-frame,
    .website-section-gradient-anim-pan,
    .website-section-gradient-anim-rotate,
    .website-section-mesh-anim-drift {
        animation: none;
    }
}

/* ====================================================================
 * CtaBannerWidget - compact end-of-page call-to-action strip.
 * Visually distinct from HeroSectionWidget: tighter vertical rhythm,
 * smaller heading, supports both split and centered layouts.
 * ==================================================================== */
.cta-banner-widget {
    padding: 1.5rem 0;
}
.cta-banner-inner {
    padding: 1.25rem 1.5rem;
    border-radius: 0.75rem;
    background: var(--bs-tertiary-bg, rgba(0, 0, 0, 0.03));
}
.website-section-primary .cta-banner-inner,
.website-section-secondary .cta-banner-inner,
.website-section-dark .cta-banner-inner {
    background: rgba(255, 255, 255, 0.08);
}
.cta-banner-heading {
    font-size: 1.5rem;
    font-weight: 600;
    line-height: 1.25;
}
.cta-banner-body {
    font-size: 0.95rem;
    line-height: 1.45;
}
.cta-banner-centered .cta-banner-copy {
    max-width: 36rem;
}
.cta-banner-actions .btn {
    white-space: nowrap;
}
@media (min-width: 768px) {
    .cta-banner-split .cta-banner-inner {
        padding: 1.5rem 2rem;
    }
    .cta-banner-split .cta-banner-heading {
        font-size: 1.75rem;
    }
}
/* On colored section backgrounds, mute the body text contrast so the
 * heading + CTA stay the visual centerpiece. */
.website-section-primary .cta-banner-body,
.website-section-secondary .cta-banner-body,
.website-section-dark .cta-banner-body {
    color: rgba(255, 255, 255, 0.85) !important;
}

/* Stacked - left-aligned copy with full-width stacked buttons on the tinted card. */
.cta-banner-stacked .cta-banner-inner {
    padding: 1.75rem 2rem;
}
.cta-banner-actions-stacked {
    flex-direction: column;
    align-items: stretch;
}
.cta-banner-actions-stacked .btn {
    width: 100%;
}
@media (min-width: 768px) {
    .cta-banner-actions-stacked {
        flex-direction: row;
    }
    .cta-banner-actions-stacked .btn {
        width: auto;
    }
}

/* Banner - thin full-bleed strip: drop the inner card so it reads as a rule. */
.cta-banner-banner {
    padding: 0.75rem 0;
}
.cta-banner-banner .cta-banner-inner {
    background: transparent;
    border-radius: 0;
    padding: 0.5rem 0;
    border-top: 1px solid var(--border-default);
    border-bottom: 1px solid var(--border-default);
}
.cta-banner-banner .cta-banner-heading {
    font-size: 1.25rem;
}

/* Boxed - a prominent floating card, centered and shadowed. */
.cta-banner-boxed .cta-banner-inner {
    max-width: 48rem;
    margin: 0 auto;
    padding: 2.5rem 2rem;
    border-radius: 1.25rem;
    box-shadow: var(--shadow-lg);
    background: var(--bg-primary);
}
.website-section-primary .cta-banner-boxed .cta-banner-inner,
.website-section-secondary .cta-banner-boxed .cta-banner-inner,
.website-section-dark .cta-banner-boxed .cta-banner-inner {
    background: rgba(255, 255, 255, 0.1);
}

/* ====================================================================
 * LogoCloudWidget - static grid of partner / press / client logos.
 * ==================================================================== */
.logo-cloud-widget .logo-cloud-img {
    width: auto;
    object-fit: contain;
    transition: filter 0.2s ease, opacity 0.2s ease, transform 0.2s ease;
    opacity: 0.85;
}
.logo-cloud-grayscale .logo-cloud-img {
    filter: grayscale(100%);
    opacity: 0.6;
}
.logo-cloud-widget .logo-cloud-link:hover .logo-cloud-img,
.logo-cloud-widget .logo-cloud-img:hover {
    filter: grayscale(0);
    opacity: 1;
    transform: scale(1.04);
}
/* On dark / primary section backgrounds, invert grayscale logos so the
 * dark marks become readable on the dark surface. Brand colors win on
 * hover regardless. */
.website-section-dark .logo-cloud-grayscale .logo-cloud-img,
.website-section-primary .logo-cloud-grayscale .logo-cloud-img,
.website-section-secondary .logo-cloud-grayscale .logo-cloud-img {
    filter: grayscale(100%) brightness(0) invert(1);
    opacity: 0.75;
}
.website-section-dark .logo-cloud-grayscale .logo-cloud-link:hover .logo-cloud-img,
.website-section-primary .logo-cloud-grayscale .logo-cloud-link:hover .logo-cloud-img,
.website-section-secondary .logo-cloud-grayscale .logo-cloud-link:hover .logo-cloud-img {
    filter: none;
    opacity: 1;
}

/* ====================================================================
 * SponsorTiersWidget - partner / sponsor logos grouped into ranked tiers.
 * ==================================================================== */
.sponsor-tiers-widget .sponsor-tier {
    margin-bottom: 2.5rem;
}
.sponsor-tiers-widget .sponsor-tier:last-child {
    margin-bottom: 0;
}
.sponsor-tiers-widget .sponsor-tier-label {
    font-size: 0.875rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    opacity: 0.7;
    margin-bottom: 1.25rem;
}
.sponsor-tiers-widget .sponsor-tier-logos {
    gap: 2.5rem;
}
.sponsor-tiers-widget .sponsor-logo {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
    color: inherit;
}
.sponsor-tiers-widget .sponsor-logo-img {
    width: auto;
    object-fit: contain;
    transition: filter 0.2s ease, opacity 0.2s ease, transform 0.2s ease;
    opacity: 0.9;
}
.sponsor-tiers-widget .sponsor-logo-text {
    font-size: 1.25rem;
    font-weight: 600;
    opacity: 0.85;
}
.sponsor-tiers-grayscale .sponsor-logo-img {
    filter: grayscale(100%);
    opacity: 0.6;
}
.sponsor-tiers-widget .sponsor-logo:hover .sponsor-logo-img {
    filter: grayscale(0);
    opacity: 1;
    transform: scale(1.04);
}
/* Smaller tiers get progressively tighter spacing. */
.sponsor-tiers-widget .sponsor-tier-silver .sponsor-tier-logos,
.sponsor-tiers-widget .sponsor-tier-bronze .sponsor-tier-logos,
.sponsor-tiers-widget .sponsor-tier-partner .sponsor-tier-logos {
    gap: 2rem;
}
/* Invert grayscale marks on dark / primary section surfaces so dark logos
 * stay visible; full brand color returns on hover. */
.website-section-dark .sponsor-tiers-grayscale .sponsor-logo-img,
.website-section-primary .sponsor-tiers-grayscale .sponsor-logo-img,
.website-section-secondary .sponsor-tiers-grayscale .sponsor-logo-img {
    filter: grayscale(100%) brightness(0) invert(1);
    opacity: 0.75;
}
.website-section-dark .sponsor-tiers-grayscale .sponsor-logo:hover .sponsor-logo-img,
.website-section-primary .sponsor-tiers-grayscale .sponsor-logo:hover .sponsor-logo-img,
.website-section-secondary .sponsor-tiers-grayscale .sponsor-logo:hover .sponsor-logo-img {
    filter: none;
    opacity: 1;
}

/* ====================================================================
 * EventAgendaWidget - single-event session timetable (vertical timeline).
 * ==================================================================== */
.event-agenda-timeline {
    max-width: 760px;
}
.event-agenda-event-link {
    display: inline-flex;
    align-items: center;
    font-weight: 600;
    text-decoration: none;
    color: var(--website-primary, #0d6efd);
}
.event-agenda-event-link:hover {
    text-decoration: underline;
}
.event-agenda-track {
    margin-bottom: 2.5rem;
}
.event-agenda-track:last-child {
    margin-bottom: 0;
}
.event-agenda-track-label {
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    opacity: 0.8;
    margin-bottom: 1rem;
}
.event-agenda-row {
    gap: 1.25rem;
    padding: 1.1rem 0;
    border-bottom: 1px solid var(--border-default, rgba(0, 0, 0, 0.08));
}
.event-agenda-row:last-child {
    border-bottom: 0;
}
.event-agenda-time {
    flex: 0 0 6.5rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--website-primary, #0d6efd);
    padding-top: 0.1rem;
}
.event-agenda-title {
    font-size: 1.0625rem;
    font-weight: 600;
}
.event-agenda-badge {
    display: inline-block;
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    background: var(--bg-secondary, rgba(0, 0, 0, 0.06));
    opacity: 0.85;
}
.event-agenda-speaker {
    font-size: 0.9rem;
    opacity: 0.85;
    margin-top: 0.25rem;
}
.event-agenda-desc {
    font-size: 0.9rem;
    opacity: 0.75;
    margin-top: 0.35rem;
}
@media (max-width: 575.98px) {
    .event-agenda-row {
        flex-direction: column;
        gap: 0.25rem;
    }
    .event-agenda-time {
        flex-basis: auto;
    }
}

/* ====================================================================
 * DonationThermometerWidget - progress-to-goal fundraising bar.
 * ==================================================================== */
.donation-thermometer {
    max-width: 640px;
}
.donation-thermo-heading {
    font-weight: 700;
    margin-bottom: 0.5rem;
}
.donation-thermo-desc {
    opacity: 0.8;
    margin-bottom: 1.5rem;
}
.donation-thermo-track {
    position: relative;
    height: 2.25rem;
    border-radius: 999px;
    background: var(--bg-secondary, rgba(0, 0, 0, 0.08));
    overflow: hidden;
}
.donation-thermo-fill {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    height: 100%;
    width: var(--thermo-fill, 0%);
    min-width: 2.5rem;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--website-primary, #0d6efd), var(--website-secondary, var(--website-primary, #0d6efd)));
    animation: donation-thermo-grow 1.1s cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes donation-thermo-grow {
    from { width: 0; }
    to   { width: var(--thermo-fill, 0%); }
}
.donation-thermo-pct {
    color: #fff;
    font-size: 0.8125rem;
    font-weight: 700;
    padding: 0 0.75rem;
    white-space: nowrap;
}
.donation-thermo-amounts {
    margin-top: 0.75rem;
    font-size: 0.95rem;
    opacity: 0.9;
}
.donation-thermo-goal {
    opacity: 0.75;
}
/* Respect reduced-motion: snap to the final fill instead of animating. */
@media (prefers-reduced-motion: reduce) {
    .donation-thermo-fill {
        animation: none;
    }
}

/* Donate CTA - fully self-contained so it renders as a real button even
 * where Bootstrap's .btn base and theme.css's .btn-brand-* fills are not
 * loaded (the website layout omits theme.css). Variants key off the
 * buttonStyleClass() classes already on the <a>. Author's inline text
 * color (buttonColor) still wins via the element's style attribute. */
.donation-thermo-cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.7rem 1.75rem;
    border: 1px solid transparent;
    border-radius: var(--website-button-radius, var(--radius-md, 0.5rem));
    font-weight: 600;
    line-height: 1.2;
    text-decoration: none;
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
}
.donation-thermo-cta:hover {
    transform: translateY(-1px);
    text-decoration: none;
}
.donation-thermo-cta.btn-brand-primary {
    background-color: var(--color-primary-600);
    border-color: var(--color-primary-600);
    color: #fff;
}
.donation-thermo-cta.btn-brand-primary:hover {
    background-color: var(--color-primary-700, var(--color-primary-600));
    border-color: var(--color-primary-700, var(--color-primary-600));
}
.donation-thermo-cta.btn-brand-secondary {
    background-color: var(--color-secondary-600);
    border-color: var(--color-secondary-600);
    color: #fff;
}
.donation-thermo-cta.btn-brand-secondary:hover {
    background-color: var(--color-secondary-700, var(--color-secondary-600));
    border-color: var(--color-secondary-700, var(--color-secondary-600));
}
.donation-thermo-cta.btn-outline-brand-primary {
    background-color: transparent;
    border-color: var(--color-primary-600);
    color: var(--color-primary-600);
}
.donation-thermo-cta.btn-outline-brand-primary:hover {
    background-color: var(--color-primary-600);
    color: #fff;
}
.donation-thermo-cta.btn-outline-brand-secondary {
    background-color: transparent;
    border-color: var(--color-secondary-600);
    color: var(--color-secondary-600);
}
.donation-thermo-cta.btn-outline-brand-secondary:hover {
    background-color: var(--color-secondary-600);
    color: #fff;
}

/* Logo Cloud layouts (grid is the default markup above; these add the
 * cards / strip / row / carousel variants chosen via the Layout picker). */

/* Cards - each logo boxed in a bordered tile that lifts on hover. */
.logo-cloud-cards .logo-cloud-cell {
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.25rem 1rem;
    background: var(--bg-primary, #fff);
    border: 1px solid var(--border-default, #dee2e6);
    border-radius: var(--radius-lg, 0.75rem);
    transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}
.logo-cloud-cards .logo-cloud-cell:hover {
    transform: translateY(-4px);
    box-shadow: var(--shadow-md, 0 6px 18px rgba(0, 0, 0, 0.08));
    border-color: var(--color-primary-300, #b9c6ff);
}
[data-theme="dark"] .logo-cloud-cards .logo-cloud-cell {
    background: var(--bg-secondary);
}

/* Strip - seamless auto-scroll. Reuses the global @keyframes marquee-scroll-*. */
.logo-cloud-strip {
    width: 100%;
    overflow: hidden;
    position: relative;
}
.logo-cloud-strip-track {
    display: flex;
    flex-wrap: nowrap;
    width: max-content;
    align-items: center;
    gap: var(--space-8, 2.5rem);
    animation: marquee-scroll-left var(--lc-duration, 40s) linear infinite;
    will-change: transform;
}
.logo-cloud-strip-dup {
    display: contents;
}
.logo-cloud-strip-item {
    flex: 0 0 auto;
}
.logo-cloud-strip[data-pause-on-hover="1"]:hover .logo-cloud-strip-track {
    animation-play-state: paused;
}
@media (prefers-reduced-motion: reduce) {
    .logo-cloud-strip-track {
        animation: none;
    }
    .logo-cloud-strip {
        overflow-x: auto;
        scroll-snap-type: x proximity;
    }
}

/* Row - one centered line of logos with hairline dividers. */
.logo-cloud-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
}
.logo-cloud-row .logo-cloud-row-item {
    display: flex;
    align-items: center;
    padding: 0.5rem 1.75rem;
}
.logo-cloud-row .logo-cloud-row-item:not(:last-child) {
    border-right: 1px solid var(--border-default, #dee2e6);
}
@media (max-width: 575.98px) {
    .logo-cloud-row .logo-cloud-row-item:not(:last-child) {
        border-right: none;
    }
}

/* Carousel - horizontal scroll with arrow nav + optional autoplay (JS). */
.logo-cloud-carousel-wrap {
    position: relative;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}
.logo-cloud-carousel-track {
    flex: 1 1 auto;
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    gap: var(--space-8, 2.5rem);
    padding: 0.5rem 0;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    scroll-behavior: smooth;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}
.logo-cloud-carousel-track::-webkit-scrollbar {
    display: none;
}
.logo-cloud-carousel-item {
    flex: 0 0 auto;
    scroll-snap-align: start;
}
.logo-cloud-carousel-nav {
    flex: 0 0 auto;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    border: 1px solid var(--border-default, #dee2e6);
    background: var(--bg-primary, #fff);
    color: var(--text-primary, #212529);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.logo-cloud-carousel-nav:hover {
    background: var(--color-primary-600, #0d6efd);
    border-color: var(--color-primary-600, #0d6efd);
    color: #fff;
}
[data-theme="dark"] .logo-cloud-carousel-nav {
    background: var(--bg-secondary);
}

/* ====================================================================
 * VideoFeatureWidget - featured video with click-to-play facade.
 * The facade keeps third-party YouTube/Vimeo iframes off the page
 * until the visitor clicks play; only then is the real iframe injected.
 * ==================================================================== */
.video-feature-widget {
    padding: 1.5rem 0;
}
.video-feature-embed {
    border-radius: 0.75rem;
    overflow: hidden;
    box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
    background: #000;
}
.video-feature-facade {
    position: relative;
    cursor: pointer;
    background-size: cover;
    background-position: center;
    background-color: #111;
}
/* Gradient overlay lives on ::after so Bootstrap's `.ratio::before`
 * (which provides aspect-ratio height via padding-top) is not clobbered
 * when both classes sit on the same element. ::before with position:absolute
 * removes the pseudo from flow and the parent collapses to zero height,
 * making the facade invisible. */
.video-feature-facade::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(0,0,0,0.10) 0%, rgba(0,0,0,0.45) 100%);
    transition: background 0.2s ease;
    z-index: 1;
    pointer-events: none;
}
.video-feature-facade:hover::after,
.video-feature-facade:focus-visible::after {
    background: linear-gradient(180deg, rgba(0,0,0,0.05) 0%, rgba(0,0,0,0.55) 100%);
}
.video-feature-facade:focus-visible {
    outline: 3px solid var(--bs-primary, #0d6efd);
    outline-offset: 2px;
}
.video-feature-play {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 72px;
    height: 72px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.95);
    color: var(--bs-primary, #0d6efd);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.75rem;
    z-index: 2;
    transition: transform 0.2s ease, box-shadow 0.2s ease;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
}
.video-feature-facade:hover .video-feature-play {
    transform: translate(-50%, -50%) scale(1.08);
    box-shadow: 0 6px 28px rgba(0, 0, 0, 0.4);
}
.video-feature-play i {
    margin-left: 4px; /* Optical centering for the play triangle */
}
.video-feature-kicker {
    letter-spacing: 0.05em;
}
.video-feature-heading {
    font-size: 1.75rem;
    font-weight: 600;
    line-height: 1.25;
}
@media (min-width: 768px) {
    .video-feature-heading {
        font-size: 2.25rem;
    }
}

/* ====================================================================
 * FaqSectionWidget - minimal accordion override so it sits well inside
 * a website section without fighting other Bootstrap accordions.
 * ==================================================================== */
.faq-section-widget .accordion-button {
    font-weight: 600;
    background: var(--bg-primary, #fff);
}
.faq-section-widget .accordion-button:not(.collapsed) {
    background: var(--bg-secondary, #f8f9fa);
    color: inherit;
    box-shadow: none;
}
.faq-section-widget .accordion-item {
    border-color: var(--bs-border-color, #dee2e6);
    background: transparent;
}
.faq-section-widget .accordion-body {
    line-height: 1.6;
}
.website-section-dark .faq-section-widget .accordion-button,
.website-section-primary .faq-section-widget .accordion-button,
.website-section-secondary .faq-section-widget .accordion-button {
    background: rgba(255, 255, 255, 0.08);
    color: inherit;
}
.website-section-dark .faq-section-widget .accordion-button:not(.collapsed),
.website-section-primary .faq-section-widget .accordion-button:not(.collapsed),
.website-section-secondary .faq-section-widget .accordion-button:not(.collapsed) {
    background: rgba(255, 255, 255, 0.14);
}

/* --------------------------------------------------------------------
 * Open-header style presets (shared vocabulary with Tabs buttons).
 * Applied via a `.wb-btnstyle-*` class on `.faq-section-widget`; all
 * read `--wb-accent` (set inline from the Brand Palette accent picker).
 *
 * `soft` is the DEFAULT: it intentionally references `var(--wb-accent)`
 * WITHOUT a fallback inside color-mix, so when no accent is chosen the
 * whole declaration is invalid and the cascade falls back to the
 * existing neutral open-header rules above - preserving the historic
 * look on every background. The other presets are explicit user picks,
 * so they fall back to the brand primary when no accent is set.
 * ------------------------------------------------------------------ */
.faq-section-widget.wb-btnstyle-soft .accordion-button:not(.collapsed) {
    background: color-mix(in srgb, var(--wb-accent) 16%, var(--bg-secondary, #f8f9fa));
    color: var(--wb-accent, inherit);
}
.faq-section-widget.wb-btnstyle-solid .accordion-button:not(.collapsed) {
    background: var(--wb-accent, var(--bs-primary, #0d6efd));
    color: #fff;
}
.faq-section-widget.wb-btnstyle-outline .accordion-button:not(.collapsed) {
    background: transparent;
    box-shadow: inset 0 0 0 1px var(--wb-accent, var(--bs-primary, #0d6efd));
    color: var(--wb-accent, var(--bs-primary, #0d6efd));
}
.faq-section-widget.wb-btnstyle-bar .accordion-button:not(.collapsed) {
    background: transparent;
    box-shadow: inset 3px 0 0 0 var(--wb-accent, var(--bs-primary, #0d6efd));
    color: var(--wb-accent, var(--bs-primary, #0d6efd));
}
.faq-section-widget.wb-btnstyle-minimal .accordion-button:not(.collapsed) {
    background: transparent;
    color: var(--wb-accent, var(--bs-primary, #0d6efd));
}

/* ====================================================================
 * Accordion section - expand/collapse indicator styles.
 * Non-chevron indicators repurpose Bootstrap's .accordion-button::after
 * pseudo-element, swapping the glyph on the .collapsed state. FontAwesome 6
 * Free (weight 900) is loaded site-wide.
 * ==================================================================== */
.faq-section-widget.acc-icon-plusminus .accordion-button::after,
.faq-section-widget.acc-icon-caret .accordion-button::after,
.faq-section-widget.acc-icon-arrow .accordion-button::after,
.faq-section-widget.acc-icon-angle .accordion-button::after,
.faq-section-widget.acc-icon-toggle .accordion-button::after,
.faq-section-widget.acc-icon-pluscircle .accordion-button::after {
    font-family: "Font Awesome 6 Free";
    font-weight: 900;
    background-image: none;
    width: auto;
    height: auto;
    transition: transform 0.2s ease-in-out;
}

/* Plus / Minus */
.faq-section-widget.acc-icon-plusminus .accordion-button::after { content: "\f068"; }
.faq-section-widget.acc-icon-plusminus .accordion-button.collapsed::after { content: "\f067"; }
.faq-section-widget.acc-icon-plusminus .accordion-button:not(.collapsed)::after { transform: none; }

/* Caret */
.faq-section-widget.acc-icon-caret .accordion-button::after { content: "\f0d7"; }
.faq-section-widget.acc-icon-caret .accordion-button.collapsed::after { content: "\f0da"; }
.faq-section-widget.acc-icon-caret .accordion-button:not(.collapsed)::after { transform: none; }

/* Arrow - single glyph that rotates from right (closed) to down (open) */
.faq-section-widget.acc-icon-arrow .accordion-button::after { content: "\f063"; }
.faq-section-widget.acc-icon-arrow .accordion-button.collapsed::after { transform: rotate(-90deg); }
.faq-section-widget.acc-icon-arrow .accordion-button:not(.collapsed)::after { transform: none; }

/* Eye - Tabler eye (open) / eye-closed (collapsed); no strikeout */
.faq-section-widget.acc-icon-eye .accordion-button::after {
    font-family: "tabler-icons";
    font-weight: 400;
    background-image: none;
    width: auto;
    height: auto;
    transition: transform 0.2s ease-in-out;
    content: "\ea9a"; /* ti-eye (open) */
}
.faq-section-widget.acc-icon-eye .accordion-button.collapsed::after { content: "\f7ec"; } /* ti-eye-closed */
.faq-section-widget.acc-icon-eye .accordion-button:not(.collapsed)::after { transform: none; }

/* Angle - thin single-line chevron that rotates from right (closed) to down (open) */
.faq-section-widget.acc-icon-angle .accordion-button::after { content: "\f107"; } /* fa-angle-down */
.faq-section-widget.acc-icon-angle .accordion-button.collapsed::after { transform: rotate(-90deg); }
.faq-section-widget.acc-icon-angle .accordion-button:not(.collapsed)::after { transform: none; }

/* Toggle - switch off (closed) / on (open) */
.faq-section-widget.acc-icon-toggle .accordion-button::after { content: "\f205"; } /* fa-toggle-on */
.faq-section-widget.acc-icon-toggle .accordion-button.collapsed::after { content: "\f204"; } /* fa-toggle-off */
.faq-section-widget.acc-icon-toggle .accordion-button:not(.collapsed)::after { transform: none; }

/* Plus circle - circle-plus (closed) / circle-minus (open) */
.faq-section-widget.acc-icon-pluscircle .accordion-button::after { content: "\f056"; } /* fa-circle-minus */
.faq-section-widget.acc-icon-pluscircle .accordion-button.collapsed::after { content: "\f055"; } /* fa-circle-plus */
.faq-section-widget.acc-icon-pluscircle .accordion-button:not(.collapsed)::after { transform: none; }

/* Custom - two real <i> icons emitted by the widget, toggled by .collapsed.
 * Suppress the default chevron and push the visible icon to the far end. */
.faq-section-widget.acc-icon-custom .accordion-button::after { display: none; }
.faq-section-widget.acc-icon-custom .accordion-button .acc-label { margin-right: auto; }
.faq-section-widget.acc-icon-custom .accordion-button .acc-ci { transition: transform 0.2s ease-in-out; }
.faq-section-widget.acc-icon-custom .accordion-button.collapsed .acc-ci-open { display: none; }
.faq-section-widget.acc-icon-custom .accordion-button.collapsed .acc-ci-closed { display: inline-block; }
.faq-section-widget.acc-icon-custom .accordion-button:not(.collapsed) .acc-ci-open { display: inline-block; }
.faq-section-widget.acc-icon-custom .accordion-button:not(.collapsed) .acc-ci-closed { display: none; }

/* None */
.faq-section-widget.acc-icon-none .accordion-button::after { display: none; }

/* ====================================================================
 * Accordion section - container visual variants.
 * "bordered" is the default look (rules at the top of this block).
 * ==================================================================== */
/* Separated - each item a gapped, rounded, shadowed card */
.faq-section-widget.acc-variant-separated .accordion-item {
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: var(--bs-border-radius, 0.5rem);
    margin-bottom: 0.75rem;
    overflow: hidden;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
}
.faq-section-widget.acc-variant-separated .accordion-item:last-child {
    margin-bottom: 0;
}

/* Flush - borderless except divider lines between items */
.faq-section-widget.acc-variant-flush .accordion-item {
    border-left: 0;
    border-right: 0;
    border-radius: 0;
}
.faq-section-widget.acc-variant-flush .accordion-item:first-child {
    border-top: 0;
}
.faq-section-widget.acc-variant-flush .accordion-button,
.faq-section-widget.acc-variant-flush .accordion-button:not(.collapsed) {
    background: transparent;
}

/* Minimal - no box; header underline + generous spacing */
.faq-section-widget.acc-variant-minimal .accordion-item {
    border: 0;
    border-bottom: 1px solid var(--bs-border-color, #dee2e6);
    background: transparent;
}
.faq-section-widget.acc-variant-minimal .accordion-button,
.faq-section-widget.acc-variant-minimal .accordion-button:not(.collapsed) {
    background: transparent;
    padding-left: 0;
    padding-right: 0;
    padding-top: 1.1rem;
    padding-bottom: 1.1rem;
}
.faq-section-widget.acc-variant-minimal .accordion-body {
    padding-left: 0;
    padding-right: 0;
}

/* ====================================================================
 * TeamSectionWidget - card grid for people.
 * ==================================================================== */
.team-section-widget .team-card {
    padding: 0.5rem 0.25rem;
}
.team-photo {
    display: inline-block;
    width: 100%;
    max-width: 160px;
    aspect-ratio: 1 / 1;
    object-fit: cover;
}
.team-photo-circle {
    border-radius: 50%;
}
.team-photo-square {
    border-radius: 0.75rem;
}
.team-photo-placeholder {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--bs-tertiary-bg, #e9ecef);
    color: var(--bs-secondary-color, #6c757d);
    font-size: 3rem;
    font-weight: 600;
}
.team-name {
    font-size: 1.1rem;
    font-weight: 600;
}
.team-role {
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.team-bio {
    color: var(--bs-secondary-color, #6c757d);
    line-height: 1.55;
}
.team-social {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-secondary, #f8f9fa);
    color: var(--bs-body-color, #212529);
    transition: background-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
    text-decoration: none;
    font-size: 0.85rem;
}
.team-social:hover {
    background: var(--bs-primary, #0d6efd);
    color: #fff;
    transform: translateY(-2px);
}
.team-compact .team-photo {
    max-width: 96px;
}
.team-compact .team-name {
    font-size: 0.9rem;
    margin-top: 0.5rem !important;
}

/* Circles - larger centered round avatars, name + role only. */
.team-circles .team-photo {
    max-width: 120px;
}
.team-circles .team-card {
    padding: 0.75rem 0.25rem;
}

/* List - editorial photo-left rows. */
.team-list .team-card-list {
    border-bottom: 1px solid var(--border-default);
}
.team-list .team-card-list:last-child {
    border-bottom: none;
}
.team-photo-list {
    width: 88px;
    max-width: 88px;
    height: 88px;
}

/* Spotlight - oversized lead portrait. */
.team-photo-spotlight {
    max-width: 200px;
}
.team-spotlight .team-card-spotlight .team-name {
    font-size: 1.5rem;
}
.team-spotlight .team-card-spotlight .team-role {
    font-size: 0.95rem;
}

/* ====================================================================
 * ContactMapWidget - address + hours + Leaflet OSM map.
 * ==================================================================== */
.contact-map-widget {
    padding: 1rem 0;
}
.contact-map-canvas {
    width: 100%;
    min-height: 360px;
    height: 100%;
    border-radius: 0.75rem;
    overflow: hidden;
    border: 1px solid var(--bs-border-color, #dee2e6);
    background: var(--bs-tertiary-bg, #f8f9fa);
}
.contact-info-label {
    letter-spacing: 0.05em;
}
.contact-info-value {
    line-height: 1.5;
}
a.contact-info-value:hover {
    color: var(--bs-primary, #0d6efd) !important;
}
.contact-hours td {
    padding: 0.25rem 0.5rem;
    border-color: transparent;
}
.contact-hours tr:nth-child(odd) td {
    background: var(--bs-tertiary-bg, #f8f9fa);
}
.website-section-dark .contact-hours tr:nth-child(odd) td,
.website-section-primary .contact-hours tr:nth-child(odd) td,
.website-section-secondary .contact-hours tr:nth-child(odd) td {
    background: rgba(255, 255, 255, 0.05);
}
/* Leaflet's default control colors don't match our theme - reduce its weight. */
.contact-map-canvas .leaflet-control-attribution {
    font-size: 0.7rem;
}

/* Footer map: the base canvas min-height (360px) is too tall for a footer, so
 * override to a compact fixed height. The full-width band variant is a touch
 * taller for legibility across the page width. */
.website-footer-map {
    margin-top: 1rem;
}
.website-footer-map .contact-map-canvas {
    min-height: 0;
    height: 160px;
    border-radius: 0.5rem;
}
.website-footer-map--band .contact-map-canvas {
    height: 200px;
}

/* Contact page map: lives at the foot of the info column. margin-top:auto
 * pushes it down so it aligns with the bottom of the form card; a fixed
 * compact height keeps the column balanced rather than dominating it. */
.website-contact-map {
    margin-top: auto;
    padding-top: var(--space-6);
}
.website-contact-map .contact-map-canvas {
    min-height: 0;
    height: 260px;
}
@media (max-width: 767.98px) {
    /* Stacked layout: no column to align to, so just give it normal spacing. */
    .website-contact-map {
        margin-top: var(--space-6);
    }
}

/* Equal-height columns: the grid stretches both cells to the taller one (the
 * info column with its map). Make the form card fill that height and let the
 * message textarea grow to absorb the slack, so the form bottom lines up with
 * the map bottom instead of leaving dead space. */
.website-contact-form .card {
    height: 100%;
}
.website-contact-form .card-body {
    display: flex;
    flex-direction: column;
}
.website-contact-form form {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
}
.website-contact-msg {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
}
.website-contact-msg textarea {
    flex: 1 1 auto;
    min-height: 140px;
    resize: vertical;
}
@media (max-width: 767.98px) {
    /* Stacked: nothing to match, keep the textarea at its natural size. */
    .website-contact-msg textarea {
        flex: 0 1 auto;
    }
}

/* ====================================================================
 * ChartSectionWidget - Chart.js canvas wrapper.
 * ==================================================================== */
.chart-section-widget {
    padding: 1rem 0;
}
.chart-section-title {
    font-size: 1.5rem;
    font-weight: 600;
}
.chart-section-subtitle {
    font-size: 0.95rem;
}
.chart-section-canvas-wrap {
    position: relative;
    width: 100%;
}
.chart-section-canvas {
    width: 100% !important;
    height: 100% !important;
}

/* ====================================================================
 * ComparisonTableWidget - feature comparison grid.
 * ==================================================================== */
.comparison-table-widget .comparison-table {
    margin-bottom: 0;
    border-collapse: separate;
    border-spacing: 0;
}
.comparison-table .comparison-col-header {
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    font-size: 0.85rem;
    padding: 1rem 0.75rem;
    border-bottom: 2px solid var(--bs-border-color, #dee2e6);
}
.comparison-table .comparison-row-header {
    border-bottom: 2px solid var(--bs-border-color, #dee2e6);
    background: transparent;
}
.comparison-table .comparison-row-label {
    font-weight: 500;
    color: var(--bs-body-color, #212529);
    background: transparent;
}
.comparison-table .comparison-cell {
    padding: 0.85rem 0.75rem;
    vertical-align: middle;
}
.comparison-table .comparison-col-highlight {
    background: rgba(13, 110, 253, 0.08);
    border-top: 3px solid var(--bs-primary, #0d6efd);
    color: var(--bs-primary, #0d6efd);
}
.comparison-table .comparison-cell-highlight {
    background: rgba(13, 110, 253, 0.05);
    border-left: 1px solid rgba(13, 110, 253, 0.15);
    border-right: 1px solid rgba(13, 110, 253, 0.15);
}
.comparison-table tbody tr:last-child .comparison-cell-highlight {
    border-bottom: 1px solid rgba(13, 110, 253, 0.15);
}
.website-section-dark .comparison-col-highlight,
.website-section-primary .comparison-col-highlight,
.website-section-secondary .comparison-col-highlight {
    background: rgba(255, 255, 255, 0.10);
    color: inherit;
    border-top-color: rgba(255, 255, 255, 0.6);
}

/* ====================================================================
 * BeforeAfterSliderWidget - drag-divider image comparison.
 * ==================================================================== */
.ba-slider-widget {
    padding: 1rem 0;
}
.ba-slider-heading {
    font-size: 1.5rem;
    font-weight: 600;
}
.ba-slider {
    position: relative;
    width: 100%;
    overflow: hidden;
    border-radius: 0.75rem;
    box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
    user-select: none;
    touch-action: none;
}
.ba-slider-img {
    display: block;
    width: 100%;
    height: auto;
    pointer-events: none;
}
.ba-slider-img-after {
    width: 100%;
}
.ba-slider-clip {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    overflow: hidden;
    will-change: width;
}
.ba-slider-clip .ba-slider-img-before {
    width: 100vw; /* clipped by the parent */
    max-width: none;
    height: 100%;
    object-fit: cover;
}
.ba-slider-dragging {
    cursor: grabbing;
}
.ba-slider-dragging .ba-slider-clip {
    transition: none;
}
.ba-slider-handle {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 4px;
    background: transparent;
    transform: translateX(-50%);
    cursor: ew-resize;
    will-change: left;
    z-index: 2;
}
.ba-slider-handle:focus-visible {
    outline: none;
}
.ba-slider-handle-line {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    width: 3px;
    background: #fff;
    transform: translateX(-50%);
    box-shadow: 0 0 12px rgba(0, 0, 0, 0.5);
}
.ba-slider-handle-knob {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: #fff;
    color: var(--bs-primary, #0d6efd);
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
    transition: transform 0.15s ease;
    font-size: 0.85rem;
}
.ba-slider-handle:hover .ba-slider-handle-knob,
.ba-slider-handle:focus-visible .ba-slider-handle-knob {
    transform: translate(-50%, -50%) scale(1.1);
}
.ba-slider-label {
    position: absolute;
    top: 1rem;
    padding: 0.25rem 0.75rem;
    background: rgba(0, 0, 0, 0.6);
    color: #fff;
    border-radius: 2rem;
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    z-index: 3;
    pointer-events: none;
}
.ba-slider-label-before { left: 1rem; }
.ba-slider-label-after  { right: 1rem; }

/* ====================================================================
 * TabsSectionWidget - polished nav-pills overrides.
 * ==================================================================== */
.tabs-section-widget .nav-pills .nav-link {
    color: var(--bs-body-color, #212529);
    background: transparent;
    border-radius: 2rem;
    padding: 0.5rem 1.1rem;
    font-weight: 500;
}
.tabs-section-widget .nav-pills .nav-link:hover {
    background: var(--bg-secondary, #f8f9fa);
}
.tabs-section-widget .nav-pills .nav-link.active {
    background: var(--wb-accent, var(--bs-primary, #0d6efd));
    color: #fff;
}
.tabs-section-widget .tabs-section-content {
    line-height: 1.65;
}

/* --------------------------------------------------------------------
 * Active-tab button style presets. Applied via a `.wb-btnstyle-*`
 * modifier class on `.tabs-section-widget`; all read `--wb-accent`
 * (set inline from the Brand Palette accent picker) and fall back to
 * the brand primary. `solid` reproduces the historic filled pill.
 * Rules target `.nav-link` generally so they apply to pills AND tabs.
 * ------------------------------------------------------------------ */
.tabs-section-widget.wb-btnstyle-soft .nav-link.active {
    background: color-mix(in srgb, var(--wb-accent, var(--bs-primary, #0d6efd)) 16%, transparent);
    color: var(--wb-accent, var(--bs-primary, #0d6efd));
}
.tabs-section-widget.wb-btnstyle-outline .nav-link {
    border: 1px solid transparent;
}
.tabs-section-widget.wb-btnstyle-outline .nav-link.active {
    background: transparent;
    border-color: var(--wb-accent, var(--bs-primary, #0d6efd));
    color: var(--wb-accent, var(--bs-primary, #0d6efd));
}
.tabs-section-widget.wb-btnstyle-bar .nav-link {
    border-radius: 0;
    border-bottom: 2px solid transparent;
    background: transparent;
}
.tabs-section-widget.wb-btnstyle-bar .nav-link.active {
    background: transparent;
    color: var(--wb-accent, var(--bs-primary, #0d6efd));
    border-bottom-color: var(--wb-accent, var(--bs-primary, #0d6efd));
}
.tabs-section-widget.wb-btnstyle-minimal .nav-link.active {
    background: transparent;
    color: var(--wb-accent, var(--bs-primary, #0d6efd));
    font-weight: 700;
}

/* ====================================================================
 * EmbeddedSurveyGameWidget - call-out card for surveys / games.
 * ==================================================================== */
.embed-survey-game-widget {
    padding: 1rem 0;
}
.embed-sg-card {
    background: var(--bg-primary, #fff);
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 1rem;
    overflow: hidden;
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.08);
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.embed-sg-card:hover {
    transform: translateY(-3px);
    box-shadow: 0 10px 32px rgba(0, 0, 0, 0.12);
}
.embed-sg-image {
    width: 100%;
    height: 240px;
    object-fit: cover;
    display: block;
}
.embed-sg-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: rgba(13, 110, 253, 0.1);
    color: var(--bs-primary, #0d6efd);
    font-size: 1.1rem;
}
.embed-sg-icon-lg {
    width: 64px;
    height: 64px;
    font-size: 1.5rem;
}
.embed-sg-title {
    font-size: 1.35rem;
    font-weight: 600;
}
.embed-sg-compact {
    background: var(--bg-secondary, #f8f9fa);
    border-radius: 0.75rem;
    padding: 0.9rem 1.25rem;
    border-left: 4px solid var(--bs-primary, #0d6efd);
}
.website-section-dark .embed-sg-compact,
.website-section-primary .embed-sg-compact,
.website-section-secondary .embed-sg-compact {
    background: rgba(255, 255, 255, 0.08);
}

/* ====================================================================
 * CalendarGridWidget - month grid of org events.
 * ==================================================================== */
.calendar-grid-widget {
    padding: 1rem 0;
}
/* Suppress focus ring/glow on prev/next month buttons. Covers both the
 * mouse-click focus ring AND the post-reload focus flash caused by the
 * #fragment navigation re-applying focus to the targeted element. */
.calendar-grid-header .btn,
.calendar-grid-header .btn:focus,
.calendar-grid-header .btn:focus-visible,
.calendar-grid-header .btn:active {
    outline: none !important;
    box-shadow: none !important;
}
.calendar-grid-month-label {
    font-size: 1.5rem;
    font-weight: 600;
}
.calendar-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 1px;
    background: var(--bs-border-color, #dee2e6);
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 0.5rem;
    overflow: hidden;
}
.calendar-grid-dow {
    background: var(--bg-secondary, #f8f9fa);
    padding: 0.5rem;
    text-align: center;
    font-weight: 600;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--bs-secondary-color, #6c757d);
}
.calendar-grid-cell {
    background: var(--bg-primary, #fff);
    min-height: 92px;
    padding: 0.4rem;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    overflow: hidden;
}
.calendar-grid-cell-muted .calendar-grid-daynum {
    opacity: 0.35;
}
.calendar-grid-cell-muted {
    background: var(--bg-secondary, #f8f9fa);
}
.calendar-grid-cell-today .calendar-grid-daynum {
    background: var(--bs-primary, #0d6efd);
    color: #fff;
    border-radius: 50%;
    width: 24px;
    height: 24px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
}
.calendar-grid-daynum {
    font-size: 0.85rem;
    font-weight: 500;
    margin-bottom: 0.15rem;
}
.calendar-grid-chip {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    background: rgba(13, 110, 253, 0.12);
    color: var(--bs-primary, #0d6efd);
    text-decoration: none;
    padding: 0.15rem 0.4rem;
    border-radius: 0.25rem;
    font-size: 0.75rem;
    line-height: 1.25;
    transition: background-color 0.15s ease;
}
.calendar-grid-chip:hover {
    background: var(--bs-primary, #0d6efd);
    color: #fff;
}
.calendar-chip-label {
    flex: 1 1 auto;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* Facebook-style registration-count badge (org staff only). */
.calendar-chip-badge {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.2rem;
    height: 1.2rem;
    padding: 0 0.35rem;
    border-radius: 999px;
    background: var(--bs-danger, #dc3545);
    color: #fff;
    font-size: 0.65rem;
    font-weight: 700;
    line-height: 1;
}
.calendar-grid-chip:hover .calendar-chip-badge {
    background: #fff;
    color: var(--bs-danger, #dc3545);
}
.calendar-agenda-event .calendar-chip-badge {
    margin-left: auto;
}
.calendar-grid-more {
    font-size: 0.7rem;
    color: var(--bs-secondary-color, #6c757d);
    font-style: italic;
}
@media (max-width: 575.98px) {
    .calendar-grid-cell {
        min-height: 64px;
        padding: 0.25rem;
    }
    .calendar-grid-chip {
        font-size: 0.65rem;
    }
}
.website-section-dark .calendar-grid,
.website-section-primary .calendar-grid,
.website-section-secondary .calendar-grid {
    background: rgba(255, 255, 255, 0.15);
    border-color: rgba(255, 255, 255, 0.2);
}
.website-section-dark .calendar-grid-cell,
.website-section-primary .calendar-grid-cell,
.website-section-secondary .calendar-grid-cell {
    background: rgba(255, 255, 255, 0.05);
    color: inherit;
}
.website-section-dark .calendar-grid-cell-muted,
.website-section-primary .calendar-grid-cell-muted,
.website-section-secondary .calendar-grid-cell-muted {
    background: rgba(0, 0, 0, 0.15);
}
.website-section-dark .calendar-grid-dow,
.website-section-primary .calendar-grid-dow,
.website-section-secondary .calendar-grid-dow {
    background: rgba(0, 0, 0, 0.2);
    color: inherit;
}

/* Size variants (grid layout only). cozy = current defaults, no rules. */
.calendar-grid-size-compact .calendar-grid-cell {
    min-height: 64px;
    padding: 0.25rem;
}
.calendar-grid-size-compact .calendar-grid-chip {
    font-size: 0.7rem;
    padding: 0.1rem 0.3rem;
}
.calendar-grid-size-compact .calendar-grid-daynum {
    font-size: 0.7rem;
}
.calendar-grid-size-spacious .calendar-grid-cell {
    min-height: 128px;
    padding: 0.7rem;
}
.calendar-grid-size-spacious .calendar-grid-chip {
    font-size: 0.875rem;
    padding: 0.3rem 0.55rem;
}
.calendar-grid-size-spacious .calendar-grid-daynum {
    font-size: 1rem;
}

/* Agenda layout - vertical list of days-with-events. */
.calendar-agenda {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}
.calendar-agenda-day {
    background: var(--bg-primary, #fff);
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 0.5rem;
    padding: 0.75rem 1rem;
}
.calendar-agenda-day-today {
    border-color: var(--bs-primary, #0d6efd);
    border-width: 2px;
}
.calendar-agenda-day-header {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}
.calendar-agenda-day-num {
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--bs-primary, #0d6efd);
}
.calendar-agenda-day-name {
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--bs-secondary-color, #6c757d);
}
.calendar-agenda-events {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}
.calendar-agenda-event {
    display: flex;
    gap: 1rem;
    padding: 0.4rem 0.5rem;
    border-radius: 0.25rem;
    text-decoration: none;
    color: inherit;
    transition: background 0.15s;
}
.calendar-agenda-event:hover {
    background: var(--bg-secondary, #f8f9fa);
}
.calendar-agenda-event-time {
    min-width: 4em;
    font-weight: 600;
    color: var(--bs-secondary-color, #6c757d);
}
.calendar-agenda-empty {
    text-align: center;
    padding: 2rem;
    color: var(--bs-secondary-color, #6c757d);
}

/* Week layout - 7-column horizontal strip. */
.calendar-week {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 0.5rem;
}
.calendar-week-day {
    background: var(--bg-primary, #fff);
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 0.5rem;
    padding: 0.5rem;
    min-height: 140px;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}
.calendar-week-day-today {
    border-color: var(--bs-primary, #0d6efd);
    border-width: 2px;
}
.calendar-week-day-name {
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--bs-secondary-color, #6c757d);
}
.calendar-week-day-num {
    font-size: 1.25rem;
    font-weight: 700;
    line-height: 1;
    margin-bottom: 0.25rem;
}
@media (max-width: 575.98px) {
    .calendar-week {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* Dark / primary / secondary section overrides for agenda + week. */
.website-section-dark .calendar-agenda-day,
.website-section-primary .calendar-agenda-day,
.website-section-secondary .calendar-agenda-day,
.website-section-dark .calendar-week-day,
.website-section-primary .calendar-week-day,
.website-section-secondary .calendar-week-day {
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.2);
    color: inherit;
}
.website-section-dark .calendar-agenda-day-num,
.website-section-primary .calendar-agenda-day-num,
.website-section-secondary .calendar-agenda-day-num {
    color: inherit;
}
.website-section-dark .calendar-agenda-event:hover,
.website-section-primary .calendar-agenda-event:hover,
.website-section-secondary .calendar-agenda-event:hover {
    background: rgba(255, 255, 255, 0.1);
}
.website-section-dark .calendar-agenda-event-time,
.website-section-primary .calendar-agenda-event-time,
.website-section-secondary .calendar-agenda-event-time,
.website-section-dark .calendar-week-day-name,
.website-section-primary .calendar-week-day-name,
.website-section-secondary .calendar-week-day-name,
.website-section-dark .calendar-agenda-day-name,
.website-section-primary .calendar-agenda-day-name,
.website-section-secondary .calendar-agenda-day-name {
    color: inherit;
    opacity: 0.85;
}

/* ============================================================
 * Image Divider section (ImageDividerWidget)
 * Full-bleed image band used as a visual break between sections.
 * ============================================================ */

/* Drop the section's vertical padding so the band sits flush with its
 * neighbours (opt-in via _section.php for section_type=image_divider). */
.website-section-flush {
    padding-top: 0;
    padding-bottom: 0;
}

.image-divider {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    overflow: hidden;
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    text-decoration: none; /* when rendered as <a> */
}

/* Height presets - desktop min-heights, scaled down on small screens. */
.image-divider--slim   { min-height: 180px; }
.image-divider--medium { min-height: 340px; }
.image-divider--tall   { min-height: 520px; }
@media (max-width: 768px) {
    .image-divider--slim   { min-height: 120px; }
    .image-divider--medium { min-height: 220px; }
    .image-divider--tall   { min-height: 320px; }
}

/* Parallax: pin the image while the page scrolls. background-attachment:fixed
 * is janky/unsupported on touch, so fall back to a normal scroll there. */
.image-divider--parallax {
    background-attachment: fixed;
}
@media (hover: none), (max-width: 768px) {
    .image-divider--parallax { background-attachment: scroll; }
}

/* Ken Burns: animate an inner frame so the band's layout box stays put.
 * Reuses the @keyframes wb-ken-burns defined for image backgrounds above. */
.image-divider-frame {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    z-index: 0;
    transform: scale(1.05);
    will-change: transform;
}
.image-divider--ken-burns .image-divider-frame {
    animation: wb-ken-burns 30s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
    .image-divider--ken-burns .image-divider-frame { animation: none; }
}

/* Auto scrim - only present when the widget rendered overlay text/button.
 * A vertical gradient keeps text legible without flattening the image. */
.image-divider-scrim {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background: linear-gradient(180deg, rgba(0, 0, 0, 0.15) 0%, rgba(0, 0, 0, 0.45) 100%);
}

/* Overlay content sits above the image + scrim. */
.image-divider-content {
    position: relative;
    z-index: 2;
    max-width: 720px;
    padding: 1.5rem;
    text-align: center;
    color: #fff;
}
.image-divider-heading {
    margin: 0 0 0.5rem;
    color: #fff;
    font-weight: 700;
    text-shadow: 0 1px 12px rgba(0, 0, 0, 0.35);
}
.image-divider-subtext {
    margin: 0 0 1rem;
    color: rgba(255, 255, 255, 0.92);
    text-shadow: 0 1px 8px rgba(0, 0, 0, 0.35);
}
.image-divider-button {
    margin-top: 0.25rem;
}

/* Whole-band link: subtle hover feedback. */
.image-divider--linked {
    cursor: pointer;
    transition: filter 0.2s ease;
}
.image-divider--linked:hover {
    filter: brightness(1.06);
}

/* ============================================================
   Downloads section (FilesSectionWidget)
   ============================================================ */
.downloads-list .downloads-item + .downloads-item {
    margin-top: 0.5rem;
}
.downloads-link {
    padding: 0.7rem 0.9rem;
    border: 1px solid var(--border-default);
    border-radius: var(--radius-md, 0.5rem);
    background: var(--bg-primary);
    color: var(--text-primary);
    transition: border-color 0.18s ease, box-shadow 0.18s ease, transform 0.18s ease;
}
.downloads-link:hover {
    border-color: var(--color-primary-400);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.07);
    color: var(--text-primary);
    transform: translateY(-1px);
}
.downloads-icon {
    font-size: 1.4rem;
    color: var(--color-primary-600);
    width: 1.6rem;
    text-align: center;
    flex: 0 0 auto;
}
.downloads-cue {
    color: var(--text-muted);
    flex: 0 0 auto;
}
.downloads-compact .downloads-link {
    padding: 0.45rem 0.65rem;
}
.downloads-compact .downloads-icon {
    font-size: 1.1rem;
}

/* Cards variant */
.downloads-card {
    border: 1px solid var(--border-default);
    border-radius: var(--radius-md, 0.5rem);
    background: var(--bg-primary);
    color: var(--text-primary);
    transition: border-color 0.18s ease, box-shadow 0.18s ease, transform 0.18s ease;
}
.downloads-card:hover {
    border-color: var(--color-primary-400);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.08);
    color: var(--text-primary);
    transform: translateY(-2px);
}
.downloads-card-icon {
    font-size: 1.9rem;
    color: var(--color-primary-600);
}
.downloads-card-foot {
    border-top: 1px solid var(--border-default);
}

/* Footer downloads column */
.website-footer-downloads {
    list-style: none;
    padding: 0;
    margin: 0;
}
.website-footer-downloads li + li {
    margin-top: 0.35rem;
}
.website-footer-downloads a {
    color: var(--website-footer-link);
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}
.website-footer-downloads a:hover {
    color: var(--website-footer-link-hover);
}

/* ---------- Toastr notifications (cart add/remove, etc.) ----------------- *
 * Re-skin the toastr library to the org's brand so the "Item added to cart"
 * popup matches the site instead of toastr's default green. Scoped to
 * body[data-web="body"] (unique to the website layout) so platform pages keep
 * their normal toasts. Success uses the brand colour; error/warning stay
 * semantic so failures are still obvious. !important + the id-selector
 * specificity beat toastr.min.css / toastr-theme.css regardless of load order. */
body[data-web="body"] #toast-container > div {
    border-radius: var(--radius-xl, 0.75rem) !important;
    box-shadow: var(--shadow-lg, 0 10px 25px rgba(0, 0, 0, 0.15)) !important;
    opacity: 1 !important;
    font-family: inherit !important;
    color: #fff !important;
    padding: 0.95rem 1.25rem 0.95rem 3.1rem !important;
}
body[data-web="body"] #toast-container > div:hover {
    box-shadow: var(--shadow-xl, 0 16px 32px rgba(0, 0, 0, 0.22)) !important;
}
body[data-web="body"] #toast-container > .toast-success {
    background-color: var(--bs-primary, var(--color-primary-600, #2490c8)) !important;
}
body[data-web="body"] #toast-container > .toast-info {
    background-color: var(--color-primary-500, #3aa8e0) !important;
}
body[data-web="body"] #toast-container > .toast-error {
    background-color: var(--color-error-600, #dc2626) !important;
}
body[data-web="body"] #toast-container > .toast-warning {
    background-color: var(--color-warning-600, #d97706) !important;
}
/* Toast title/message + the close "x" all read as white on the brand fill. */
body[data-web="body"] #toast-container > div .toast-title,
body[data-web="body"] #toast-container > div .toast-message {
    color: #fff !important;
}
body[data-web="body"] #toast-container > div .toast-close-button {
    color: #fff !important;
    opacity: 0.9 !important;
    text-shadow: none !important;
}
body[data-web="body"] #toast-container > div .toast-close-button:hover {
    opacity: 1 !important;
}
/* Progress bar tinted to a translucent white so it reads on any brand fill. */
body[data-web="body"] #toast-container > div .toast-progress {
    background-color: rgba(255, 255, 255, 0.5) !important;
    opacity: 1 !important;
}

/* ============================================================
   Lottie animation section (LottieSectionWidget)
   A single lightweight vector animation. The stage is sized by
   the `--sm|md|lg|full` modifier; lottie-web's SVG fills it and
   preserves the animation's aspect ratio (letterboxing portrait
   animations cleanly). Horizontal placement comes from text-align
   on the wrapper, so the inline-block stage shifts left/center/right.
   ============================================================ */
.website-body .website-lottie { width: 100%; }
.website-body .website-lottie--left { text-align: left; }
.website-body .website-lottie--center { text-align: center; }
.website-body .website-lottie--right { text-align: right; }
.website-body .website-lottie-stage {
    display: inline-block;
    width: 240px;
    max-width: 100%;
    aspect-ratio: 1 / 1;
    line-height: 0;
}
.website-body .website-lottie--sm .website-lottie-stage { width: 120px; }
.website-body .website-lottie--md .website-lottie-stage { width: 240px; }
.website-body .website-lottie--lg .website-lottie-stage { width: 400px; }
.website-body .website-lottie--full .website-lottie-stage { width: 100%; max-width: 640px; }
.website-body .website-lottie-stage svg {
    display: block;
    width: 100% !important;
    height: 100% !important;
}
.website-body .website-lottie-caption { text-align: inherit; }
