/**
 * Conference Public Frontend Styles
 *
 * Purpose-built for conference program types.
 * Complements the base styles injected by conference.js (conf-* classes).
 * Uses Fusebox brand palette with Space Grotesk headings, Inter body text.
 */

/* =============================================================================
   CSS Variables / Design Tokens
   ============================================================================= */

:root {
    /* Theme tokens (#2718) — per-org overrides set by conference.js
       _applyBranding() via document.documentElement.style.setProperty().
       When no override is set, fall back to the Fusebox brand palette so
       existing customers look identical. */
    --color-primary: var(--theme-primary, #ec0244);
    --color-dark: #262f35;
    --color-light: #dddfd8;
    --color-maroon: var(--theme-accent, #7b0035);

    /* Form-focus glow (#2765) — 12% alpha of --theme-primary. Default tracks the
       Fusebox red focus ring; per-org JS overrides set this alongside
       --theme-primary so cfp.html / sponsor-apply.html focus states match the
       active theme. Inline styles consume it via var(--theme-primary-glow). */
    --theme-primary-glow: rgba(236, 2, 68, 0.12);

    --color-bg: var(--theme-page-bg, #fafafa);
    --color-surface: var(--theme-surface, #ffffff);
    --color-surface-alt: #f5f5f5;

    --color-text: var(--theme-text, #1a1a1a);
    --color-text-muted: var(--theme-text-muted, #666666);
    --color-text-light: #999999;

    --color-border: #e5e5e5;
    --color-border-dark: #cccccc;

    /* Typography */
    --font-heading: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

    /* Spacing */
    --space-xs: 4px;
    --space-sm: 8px;
    --space-md: 16px;
    --space-lg: 24px;
    --space-xl: 32px;
    --space-xxl: 48px;
    --space-xxxl: 64px;

    /* Layout */
    --max-width: 1200px;
}

/* =============================================================================
   Reset & Base
   ============================================================================= */

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

body {
    font-family: var(--font-body);
    color: var(--color-text);
    background: var(--theme-bg, #262f35);
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}

a { color: var(--color-primary); text-decoration: none; }
a:hover { text-decoration: underline; }
img { max-width: 100%; height: auto; display: block; }

/* =============================================================================
   Per-org dark hero variant (#2718)
   Applied when body.hero-style-dark is present (set by conference.js when
   branding.theme.hero_style === "dark"). Uses theme tokens with fallback to
   the UMich navy palette ABG ships as the first preset.
   ============================================================================= */

body.hero-style-dark .conf-hero,
body.hero-style-dark .ch-hero-bg {
    background-image: linear-gradient(
        135deg,
        var(--theme-bg, #00274c) 0%,
        var(--theme-bg-gradient-to, #1a2c45) 100%
    );
}

body.hero-style-dark .conf-hero {
    color: #fff;
    text-shadow: none;
}

/* Dark-theme readable body copy (#2949). When the org ships
   hero_style=dark, paint section headings + paragraphs in light text by
   default — without these, body copy and section h2/h3 fall back to
   #1a1a1a / #262f35 (the values in `var(--theme-text, …)` references
   throughout this file) which is unreadable on the dark page bg set by
   #2921. Orgs that explicitly set theme.text_color via branding still
   win because schedule-builder.html:49 / sponsor-apply.html:48 set
   --theme-text on :root before this rule applies. */
body.hero-style-dark {
    --theme-text: #e5e7eb;
    --theme-text-muted: #b1bac4;
    color: var(--theme-text);
}

/* =============================================================================
   Legible text on a dark page background (#6099)

   conference.js sets body.page-bg-dark from the background the page actually
   paints (getComputedStyle on body), not from a branding flag.

   INVARIANT: this block sets `color` on an enumerated selector list and NOTHING
   else. It must never set --color-text/-muted/-light or any other token, at any
   level. --color-surface is #ffffff and nothing in the repo moves it, so a token
   flip turns white-card text light-on-white — the #3089 regression, re-proved on
   the abandoned first attempt at this issue.

   Every selector below was checked to sit directly on the body background on
   EVERY page where it renders:
     .section-header        cfp, passes, sponsor-apply, speakers, tracks,
                            sponsors — always a direct child of main.page-content
     .schedule-page-header  schedule, schedule-builder — inside .schedule-container,
                            which declares no background
     .sponsor-form          sponsor-apply only; its fieldsets have a border and no
                            background
     .speaker-info/-bio     speaker.html only; .speaker-detail and .speaker-hero
                            declare no background. cfp.html's `speaker-bio` is an
                            ID on a textarea, which .speaker-bio cannot match
     .session-detail-section session.html only; a sibling of the white
                            .session-detail-hero, and neither it nor
                            .session-detail-wrapper declares a background
     .session-detail-abstract session.html only; a direct child of
                            .session-detail-section, same background as its h2
     .session-detail-back-link session.html only; .session-detail-back-row and
                            .session-detail-wrapper declare no background (#6388)
     .day-tab               schedule, schedule-builder — inside .day-tabs, a
                            direct child of .schedule-container (#6388)
     .tier-name             sponsors.html only; inside .sponsor-tier, which
                            declares no background (#6388)
     .empty-state           every render site is a bare grid/list container:
                            .speakers-grid, .tracks-grid, #schedule-grid,
                            .schedule-list, #sponsors-container,
                            .conf-sponsor-pitch__tiers, #builder-list — none
                            declares a background (#6388)
     .loading-state         schedule-builder (#builder-list), session
                            (#session-detail), speaker (.speaker-detail),
                            tracks (.tracks-grid) — the same containers already
                            audited for .error-state, and the same CSS rule
                            (#6388 Gate #2)
     .sponsor-form .form-help sponsor-apply.html only; scoped to .sponsor-form
                            because cfp.html's .form-help sits in the white
                            .cfp-form card (#6388)
     .conf-sponsor-pitch__title      sponsors.html only; direct child of
                            .conf-sponsor-pitch__head, which declares no
                            background (#6581)
     .conf-sponsor-pitch__body       sponsors.html only; same ancestor as
                            .conf-sponsor-pitch__title (#6581)
     .conf-sponsor-pitch__body-html  sponsors.html only; direct child of
                            .conf-sponsor-pitch, which declares no
                            background (#6581)
   Bare `legend`/`label` are deliberately NOT used: cfp.html's .cfp-form and
   passes.html's .passes-extras are white cards that contain both.
   Colors match the values conference_static.py already emits server-side for
   the same elements, so first paint equals the post-JS state. That SSR list
   fires whenever conference_static.py's is_dark predicate resolves dark — by
   text_color_mode or by the hero background hex — which is the signal this
   issue exists to stop trusting alone, so these rules also cover a
   dark-background org that never set text_color_mode. */

body.page-bg-dark .section-header h1,
body.page-bg-dark .schedule-page-header h1,
body.page-bg-dark .sponsor-form legend,
body.page-bg-dark .sponsor-form label,
body.page-bg-dark .speaker-info h1,
body.page-bg-dark .ssr-detail-title,
body.page-bg-dark .speaker-bio,
body.page-bg-dark .session-detail-section h2,
body.page-bg-dark .session-detail-abstract,
body.page-bg-dark .conf-sponsor-pitch__title,
body.page-bg-dark .conf-sponsor-pitch__body-html {
    color: #e5e7eb;
}

body.page-bg-dark .section-subtitle,
body.page-bg-dark .day-tab,
body.page-bg-dark .tier-name,
body.page-bg-dark .empty-state,
body.page-bg-dark .loading-state,
body.page-bg-dark .session-detail-back-link,
body.page-bg-dark .sponsor-form .form-help,
body.page-bg-dark .conf-sponsor-pitch__body {
    color: #b1bac4;
}

/* #6388 root cause B — a brand color is a safe foreground only against a
   surface the theme controls. --color-primary IS the page background's own
   palette, so on the page background it can land on itself: ARA's #223660 on
   #0f172a measured 1.50:1. Both rules resolve to a fixed on-dark value. */
body.page-bg-dark .day-tab.active {
    color: #ffffff;
}

body.page-bg-dark .error-state {
    color: #fca5a5;
}

/* The ch- namespace (index.html) is scoped per SECTION, because most ch-
   sections paint their own surface via a modifier class:
     .ch-speakers-section  .ch-why-section    --color-bg          #fafafa
     .ch-whos-section                         --color-surface-alt #f5f5f5
     .ch-sponsor-pitch-section                .ch-section-dark    #262f35
                                              (+ .ch-title-onDark = #fff)
     .ch-getinvolved-section                  text is in .ch-cta-card, which
                                              sets its own background
     sales-banner                             .ch-sales-banner brand gradient
   Only .ch-cfp-section and .ch-advance-info-section declare no background, so
   only those two sit on the page background. Bare .ch-section-title would hit
   4 of its 6 render sites on a light surface; .ch-section-subtitle renders
   ONLY inside .ch-speakers-section and .ch-whos-section, so it is absent here
   on purpose. */

body.page-bg-dark .ch-cfp-section .ch-section-title,
body.page-bg-dark .ch-cfp-section .ch-cfp-body,
body.page-bg-dark .ch-cfp-section .ch-cfp-body strong,
body.page-bg-dark .ch-advance-info-section .ch-section-title,
body.page-bg-dark .ch-advance-info-section .ch-advance-info-body,
body.page-bg-dark .ch-advance-info-section .ch-advance-fact-value {
    color: #e5e7eb;
}

body.page-bg-dark .ch-cfp-section .ch-cfp-meta-item,
body.page-bg-dark .ch-advance-info-section .ch-advance-fact-label {
    color: #b1bac4;
}

/* Accent-word span — used by hero h1 when theme.hero_accent_word matches a
   token in hero_title. Gradient text effect that degrades to a solid accent
   color when background-clip: text isn't supported. */
.conf-hero-accent,
.ch-hero-accent {
    color: var(--theme-accent, var(--color-primary));
    background: linear-gradient(
        to right,
        var(--theme-accent, var(--color-primary)),
        var(--theme-accent-2, var(--color-primary))
    );
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}

/* Glass-card treatment for sponsor + speaker tiles on dark hero pages.
   Subtle backdrop blur, semi-transparent white surface, hairline border. */
body.hero-style-dark .sponsor-card,
body.hero-style-dark .ch-sponsor-card,
body.hero-style-dark .ch-speaker-card,
body.hero-style-dark .conf-speaker-card {
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.1);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    color: #fff;
}

/* =============================================================================
   Hero Section (Landing Page)
   ============================================================================= */

.conf-hero {
    background: linear-gradient(135deg, var(--color-dark) 0%, var(--color-maroon) 100%);
    color: #fff;
    padding: var(--space-xxxl) var(--space-lg);
    text-align: center;
}

.conf-hero-inner {
    max-width: 800px;
    margin: 0 auto;
}

.conf-hero h1 {
    font-family: var(--font-heading);
    font-size: 48px;
    font-weight: 700;
    line-height: 1.15;
    margin-bottom: var(--space-md);
}

.conf-hero-dates {
    font-size: 18px;
    font-weight: 500;
    opacity: 0.9;
    margin-bottom: var(--space-xs);
}

.conf-hero-venue {
    font-size: 16px;
    opacity: 0.75;
    margin-bottom: var(--space-lg);
}

.conf-hero-tagline {
    font-size: 20px;
    line-height: 1.5;
    opacity: 0.9;
    max-width: 600px;
    margin: 0 auto var(--space-xl);
}

.conf-hero-actions {
    display: flex;
    gap: var(--space-md);
    justify-content: center;
    flex-wrap: wrap;
}

.btn-primary {
    display: inline-block;
    background: var(--color-primary);
    color: #fff;
    padding: 14px 32px;
    border-radius: 8px;
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 16px;
    border: none;
    cursor: pointer;
    transition: background 0.2s;
    text-decoration: none;
}

.btn-primary:hover { background: #d0023b; text-decoration: none; }

.btn-outline {
    display: inline-block;
    background: transparent;
    color: #fff;
    padding: 14px 32px;
    border-radius: 8px;
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 16px;
    border: 2px solid rgba(255, 255, 255, 0.5);
    cursor: pointer;
    transition: border-color 0.2s, color 0.2s;
    text-decoration: none;
}

.btn-outline:hover { border-color: #fff; color: #fff; text-decoration: none; }

.btn-outline-dark {
    display: inline-block;
    background: transparent;
    color: var(--color-dark);
    padding: 12px 28px;
    border-radius: 8px;
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 15px;
    border: 2px solid var(--color-border-dark);
    cursor: pointer;
    transition: border-color 0.2s, background 0.2s;
    text-decoration: none;
}

.btn-outline-dark:hover { border-color: var(--color-dark); background: var(--color-surface-alt); text-decoration: none; }

/* =============================================================================
   Section Layout
   ============================================================================= */

.conf-section {
    padding: var(--space-xxxl) var(--space-lg);
}

.conf-section-inner {
    max-width: var(--max-width);
    margin: 0 auto;
}

.conf-section-alt { background: var(--color-surface-alt); }

.section-header {
    text-align: center;
    margin-bottom: var(--space-xl);
}

.section-header h2 {
    font-family: var(--font-heading);
    font-size: 32px;
    font-weight: 700;
    color: var(--color-dark);
    margin-bottom: var(--space-sm);
}

.section-subtitle {
    font-size: 16px;
    color: var(--color-text-muted);
}

/* =============================================================================
   Speaker Card Grid (landing page keynotes)
   ============================================================================= */

.speakers-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: var(--space-lg);
}

/* Speaker detail page overrides */
.speaker-detail { max-width: var(--max-width); margin: 0 auto; padding: var(--space-xl) var(--space-lg); }

.speaker-hero {
    display: flex;
    gap: var(--space-xl);
    align-items: flex-start;
    margin-bottom: var(--space-xl);
}

.speaker-photo img {
    width: 200px;
    height: 200px;
    object-fit: cover;
    border-radius: 12px;
}

.photo-placeholder {
    width: 200px;
    height: 200px;
    background: var(--color-surface-alt);
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--color-text-light);
    font-size: 64px;
}

.speaker-info h1 { font-family: var(--font-heading); font-size: 32px; margin-bottom: var(--space-xs); }
.speaker-title { font-size: 16px; color: var(--color-text-muted); }
.speaker-company { font-size: 14px; color: var(--color-text-light); }
.speaker-bio { font-size: 16px; line-height: 1.7; color: var(--color-text); }

.social-links { display: flex; gap: var(--space-md); margin-top: var(--space-md); }
.social-links a { color: var(--color-text-muted); font-size: 20px; transition: color 0.2s; }
.social-links a:hover { color: var(--color-primary); text-decoration: none; }

.tags { display: flex; flex-wrap: wrap; gap: var(--space-xs); margin-top: var(--space-sm); }
.tags .tag {
    display: inline-block;
    background: var(--color-surface-alt);
    color: var(--color-text-muted);
    font-size: 12px;
    padding: 3px 10px;
    border-radius: 4px;
}

.speaker-sessions { max-width: var(--max-width); margin: 0 auto; padding: 0 var(--space-lg) var(--space-xl); }
.speaker-sessions h2 { font-family: var(--font-heading); font-size: 24px; margin-bottom: var(--space-md); }

/* =============================================================================
   Track Cards
   ============================================================================= */

.tracks-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: var(--space-lg);
}

.track-card {
    background: var(--color-surface);
    border-radius: 12px;
    padding: var(--space-lg);
    border-left: 5px solid var(--color-primary);
    border-top: 1px solid var(--color-border);
    border-right: 1px solid var(--color-border);
    border-bottom: 1px solid var(--color-border);
    transition: transform 0.2s, box-shadow 0.2s;
}

.track-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
}

.track-card-name {
    font-family: var(--font-heading);
    font-size: 20px;
    font-weight: 600;
    margin-bottom: var(--space-sm);
}

.track-card-count {
    font-size: 14px;
    color: var(--color-text-muted);
}

.track-card-description {
    font-size: 14px;
    color: var(--color-text-muted);
    margin-top: var(--space-sm);
    line-height: 1.5;
}

/* =============================================================================
   Sponsors Section
   ============================================================================= */

.sponsors-tier {
    margin-bottom: var(--space-xl);
    text-align: center;
}

.sponsors-tier-name {
    font-family: var(--font-heading);
    font-size: 14px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 1.5px;
    color: var(--color-text-muted);
    margin-bottom: var(--space-md);
}

.sponsors-logos {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: var(--space-xl);
}

.sponsor-logo {
    display: block;
    transition: opacity 0.2s;
}

/* Public sponsors page layout — used by /conference/sponsors.html (#2613 follow-up).
   The JS there generates .sponsor-tier / .tier-name / .sponsors-grid /
   .sponsor-card / .sponsor-name-only which were previously unstyled,
   collapsing the page into overlapping inline text. */
.sponsor-tier {
    margin-bottom: var(--space-xl);
    text-align: center;
}

.tier-name {
    font-family: var(--font-heading);
    font-size: 18px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 1.5px;
    color: var(--color-text-muted);
    margin: 0 0 var(--space-lg);
}

.sponsors-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 280px));
    gap: var(--space-lg);
    justify-content: center;
    align-items: stretch;
}

.sponsor-card {
    background: var(--color-surface, #fff);
    border: 1px solid var(--color-border, #e5e7eb);
    border-radius: 12px;
    padding: var(--space-lg);
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-sm);
    min-height: 140px;
    transition: box-shadow 0.2s, transform 0.2s;
}

.sponsor-card:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
    transform: translateY(-2px);
}

.sponsor-name-only {
    font-family: var(--font-heading);
    font-size: 18px;
    font-weight: 600;
    color: var(--color-text);
}

.sponsor-description {
    font-size: 14px;
    color: var(--color-text-muted);
    margin: 0;
    line-height: 1.4;
}

.sponsor-logo:hover { opacity: 0.7; text-decoration: none; }

.sponsor-logo img {
    height: 48px;
    width: auto;
    object-fit: contain;
    filter: grayscale(30%);
    transition: filter 0.2s;
}

.sponsor-logo:hover img { filter: grayscale(0%); }

.sponsors-tier:first-child .sponsor-logo img { height: 64px; }

.sponsor-name-text {
    display: inline-block;
    font-size: 14px;
    font-weight: 500;
    color: var(--color-text-muted);
    padding: var(--space-sm) var(--space-md);
    background: var(--color-surface-alt);
    border-radius: 6px;
    text-decoration: none;
}

.sponsor-name-text:hover { color: var(--color-text); text-decoration: none; }

/* =============================================================================
   Schedule Page
   ============================================================================= */

.schedule-container {
    max-width: var(--max-width);
    margin: 0 auto;
    padding: var(--space-xl) var(--space-lg);
}

.schedule-page-header {
    text-align: center;
    margin-bottom: var(--space-xl);
}

.schedule-page-header h1 {
    font-family: var(--font-heading);
    font-size: 36px;
    font-weight: 700;
    color: var(--color-dark);
    margin-bottom: var(--space-xs);
}

/* Day tabs */
.day-tabs {
    display: flex;
    gap: var(--space-xs);
    margin-bottom: var(--space-lg);
    border-bottom: 2px solid var(--color-border);
    overflow-x: auto;
}

.day-tab {
    padding: var(--space-sm) var(--space-lg);
    background: none;
    border: none;
    font-family: var(--font-heading);
    font-size: 15px;
    font-weight: 500;
    color: var(--color-text-muted);
    cursor: pointer;
    border-bottom: 3px solid transparent;
    margin-bottom: -2px;
    white-space: nowrap;
    transition: color 0.2s, border-color 0.2s;
}

.day-tab:hover { color: var(--color-text); }
.day-tab.active { color: var(--color-primary); border-bottom-color: currentColor; font-weight: 600; }

/* Filter bar */
.filter-bar {
    display: flex;
    gap: var(--space-md);
    align-items: center;
    flex-wrap: wrap;
    margin-bottom: var(--space-lg);
    padding: var(--space-md);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 8px;
}

.filter-group {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

.filter-label {
    font-size: 13px;
    font-weight: 600;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.filter-select {
    padding: 8px 12px;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    font-family: var(--font-body);
    font-size: 14px;
    background: var(--color-surface);
    color: var(--color-text);
    cursor: pointer;
}

.filter-select:focus { outline: none; border-color: var(--color-primary); }

.filter-input {
    padding: 8px 12px;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    font-family: var(--font-body);
    font-size: 14px;
    background: var(--color-surface);
    color: var(--color-text);
}

.filter-input:focus { outline: none; border-color: var(--color-primary); }

.track-filter-chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs);
}

.track-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 12px;
    border-radius: 20px;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    border: 2px solid var(--color-border);
    background: var(--color-surface);
    color: var(--color-text);
    transition: background 0.15s, border-color 0.15s, color 0.15s;
}

/* Fallback only -- schedule.html sets this inline per track color (#6503). */
.track-chip.active { color: #fff; }

.track-chip-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex-shrink: 0;
}

/* Schedule grid (desktop) -- complements conf-day-grid from conference.js */
.schedule-grid-wrapper {
    border: 1px solid var(--color-border);
    border-radius: 8px;
    overflow: hidden;
}

/* Session block enhancements for schedule.html inline grid */
.session-block {
    padding: var(--space-sm) var(--space-md);
    height: 100%;
    border-left: 4px solid var(--color-primary);
    cursor: pointer;
    background: var(--color-surface);
    transition: background 0.15s;
}

.session-block:hover { background: var(--color-surface-alt); }

.session-block-name {
    font-family: var(--font-heading);
    font-size: 14px;
    font-weight: 600;
    margin-bottom: 2px;
    line-height: 1.3;
}

.session-block-meta {
    font-size: 12px;
    color: var(--color-text-muted);
}

.session-block-speakers {
    font-size: 12px;
    color: var(--color-text-light);
    margin-top: 2px;
}

.session-block-badge {
    display: inline-block;
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    padding: 1px 6px;
    border-radius: 3px;
    background: var(--color-surface-alt);
    color: var(--color-text-muted);
    margin-top: 4px;
}

/* #6570 — compact pill so the shared RSVP control fits inside the tile's
   minmax(60px, auto) row without growing it. */
.session-block .conf-rsvp-control { margin-top: 2px; gap: 0.3rem; }
.session-block .conf-btn { padding: 1px 8px; font-size: 10px; }
.session-block .conf-rsvp-seats, .session-block .conf-rsvp-note { font-size: 10px; }

/* Schedule list (mobile) */
.schedule-list { display: none; }

.schedule-list-item {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 8px;
    padding: var(--space-md);
    margin-bottom: var(--space-sm);
    cursor: pointer;
    transition: box-shadow 0.15s;
    border-left: 4px solid var(--color-primary);
}

.schedule-list-item:hover { box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); }

.schedule-list-time {
    font-family: var(--font-heading);
    font-size: 13px;
    font-weight: 600;
    color: var(--color-primary);
    margin-bottom: 4px;
}

.schedule-list-name {
    font-family: var(--font-heading);
    font-size: 16px;
    font-weight: 600;
    margin-bottom: 2px;
}

.schedule-list-meta {
    font-size: 13px;
    color: var(--color-text-muted);
}

/* #6570 — same shared control as the grid tile; the list card has more
   room, so no compact override needed here. */
.schedule-list-item .conf-rsvp-control { margin-top: 8px; }

/* =============================================================================
   Session Detail Modal
   ============================================================================= */

.modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-lg);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s;
}

.modal-overlay.active { opacity: 1; pointer-events: auto; }

.modal-content {
    background: var(--color-surface);
    border-radius: 12px;
    max-width: 600px;
    width: 100%;
    max-height: 80vh;
    overflow-y: auto;
    padding: var(--space-xl);
    position: relative;
}

.modal-close {
    position: absolute;
    top: var(--space-md);
    right: var(--space-md);
    background: none;
    border: none;
    font-size: 24px;
    color: var(--color-text-muted);
    cursor: pointer;
    line-height: 1;
}

.modal-close:hover { color: var(--color-text); }

.modal-track-badge {
    display: inline-block;
    padding: 3px 10px;
    border-radius: 4px;
    font-size: 12px;
    font-weight: 600;
    /* Fallback only -- schedule.html sets this inline per track color (#6503). */
    color: #fff;
    margin-bottom: var(--space-sm);
}

.modal-title {
    font-family: var(--font-heading);
    font-size: 24px;
    font-weight: 700;
    margin-bottom: var(--space-sm);
}

.modal-meta {
    font-size: 14px;
    color: var(--color-text-muted);
    margin-bottom: var(--space-md);
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-md);
}

.modal-meta-item {
    display: flex;
    align-items: center;
    gap: 6px;
}

.modal-meta-item i { color: var(--color-primary); font-size: 14px; }

.modal-description {
    font-size: 15px;
    line-height: 1.7;
    color: var(--color-text);
    margin-bottom: var(--space-lg);
}

.modal-speakers-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
}

.modal-speaker {
    display: flex;
    align-items: center;
    gap: var(--space-md);
}

.modal-speaker img {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    object-fit: cover;
}

.modal-speaker-placeholder {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: var(--color-surface-alt);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--color-text-light);
    font-size: 20px;
}

.modal-speaker-name { font-weight: 600; font-size: 14px; }
.modal-speaker-title { font-size: 13px; color: var(--color-text-muted); }

/* =============================================================================
   Session Cards (speaker detail / sessions list)
   ============================================================================= */

.sessions-list {
    display: grid;
    gap: var(--space-md);
}

.session-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 8px;
    padding: var(--space-md);
    border-left: 4px solid var(--color-primary);
}

.session-card-name {
    font-family: var(--font-heading);
    font-size: 16px;
    font-weight: 600;
    margin-bottom: 4px;
}

.session-card-meta {
    font-size: 13px;
    color: var(--color-text-muted);
}

/* =============================================================================
   Footer
   ============================================================================= */

.conf-footer {
    background: var(--color-dark);
    color: rgba(255, 255, 255, 0.7);
    padding: var(--space-xl) var(--space-lg);
    text-align: center;
    font-size: 14px;
}

.conf-footer a { color: rgba(255, 255, 255, 0.85); text-decoration: none; }
.conf-footer a:hover { color: #fff; }

.conf-footer-inner {
    max-width: var(--max-width);
    margin: 0 auto;
}

.conf-footer-links {
    display: flex;
    justify-content: center;
    gap: var(--space-lg);
    margin-bottom: var(--space-md);
    flex-wrap: wrap;
}

/* =============================================================================
   Utility States
   ============================================================================= */

.loading-state, .empty-state, .error-state {
    text-align: center;
    padding: var(--space-xxxl) var(--space-lg);
    color: var(--color-text-muted);
    font-size: 16px;
}

.error-state { color: var(--color-primary); }

/* The server-rendered heading on session.html + speaker.html (#6487). It is
   the only heading a non-JS crawler sees; the client wipes it with the real
   title. Sized between the two headings that replace it (.session-detail-title
   36px, .speaker-info h1 32px) so hydration does not jump — the UA default is
   2em with 0.67em margins. Its on-dark color is in the page-bg-dark block. */
.ssr-detail-title {
    font-family: var(--font-heading);
    font-size: 32px;
    line-height: 1.2;
    font-weight: 700;
    color: var(--color-text);
    margin: 0 0 var(--space-md);
}

/* =============================================================================
   Skeleton screens (#2920) — placeholders sized to the final grid so the
   page doesn't grow downward when async data arrives. One shimmer keyframe,
   four card-shape utilities matched to the real grids in
   speakers.html / schedule.html / sponsors.html.
   ============================================================================= */

.skeleton {
    background: linear-gradient(
        90deg,
        var(--theme-skeleton-bg, rgba(255, 255, 255, 0.06)) 0%,
        var(--theme-skeleton-bg-hi, rgba(255, 255, 255, 0.12)) 50%,
        var(--theme-skeleton-bg, rgba(255, 255, 255, 0.06)) 100%
    );
    background-size: 200% 100%;
    animation: skeleton-shimmer 1.6s ease-in-out infinite;
    border-radius: 8px;
}

@keyframes skeleton-shimmer {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

.skeleton-speaker-card { height: 280px; }
.skeleton-schedule-row { height: 88px; margin-bottom: 12px; }
.skeleton-sponsor-card { height: 200px; }
.skeleton-tier-card { height: 220px; }

.page-content { min-height: calc(100vh - 56px - 120px); }

/* =============================================================================
   Tracks Page (tracks.html)
   ============================================================================= */

.tracks-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: var(--space-lg);
    max-width: var(--max-width);
    margin: 0 auto;
    padding: 0 var(--space-lg);
}

.conf-track-card {
    background: var(--color-surface, #fff);
    border: 1px solid var(--color-border, rgba(0, 0, 0, 0.08));
    border-top: 4px solid var(--conf-primary, #ec0244);
    border-radius: 10px;
    padding: var(--space-lg);
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    transition: box-shadow 0.15s, transform 0.15s;
}

.conf-track-card:hover {
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.08);
    transform: translateY(-1px);
}

.conf-track-card-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-sm);
}

.conf-track-name {
    font-family: var(--font-heading);
    font-size: 20px;
    font-weight: 700;
    color: var(--color-dark);
    margin: 0;
}

.conf-track-count {
    font-size: 13px;
    color: var(--color-text-muted);
    white-space: nowrap;
}

.conf-track-desc {
    font-size: 14px;
    line-height: 1.55;
    color: var(--color-text);
    margin: 0;
}

.conf-track-chair {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    margin-top: auto;
    padding-top: var(--space-sm);
    border-top: 1px solid var(--color-border, rgba(0, 0, 0, 0.06));
    color: inherit;
    text-decoration: none;
}

a.conf-track-chair:hover { background: transparent; }
a.conf-track-chair:hover .conf-track-chair-name { color: var(--conf-primary, #ec0244); }

.conf-track-chair-photo {
    width: 36px;
    height: 36px;
    object-fit: cover;
    border-radius: 50%;
    flex-shrink: 0;
}

.conf-track-chair-placeholder {
    background: var(--color-surface-alt, #f4f4f4);
    color: var(--color-text-light, #888);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 14px;
}

.conf-track-chair-meta {
    display: flex;
    flex-direction: column;
    line-height: 1.2;
    min-width: 0;
}

.conf-track-chair-label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-text-muted);
}

.conf-track-chair-name {
    font-size: 14px;
    font-weight: 600;
    color: var(--color-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* =============================================================================
   Responsive
   ============================================================================= */

@media (max-width: 768px) {
    .conf-hero h1 { font-size: 32px; }
    .conf-hero-tagline { font-size: 16px; }

    .speakers-grid { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }
    .tracks-grid { grid-template-columns: 1fr; }

    .speaker-hero { flex-direction: column; align-items: center; text-align: center; }
    .speaker-photo img, .photo-placeholder { width: 140px; height: 140px; }
    .speaker-info h1 { font-size: 24px; }

    /* Switch schedule to list view on mobile. #6352 — .schedule-grid-wrapper
       (conference.css:765) already declares the same border + 8px
       border-radius that renderGrid's own inline wrapper puts on
       #schedule-grid (schedule.html:541), so reusing it here would double
       the border and put the loading skeletons and the empty state in a
       box they don't have today. Dedicated marker class instead. */
    .schedule-grid-view,
    #schedule-grid .conf-day-grid { display: none !important; }
    .schedule-list { display: block; }

    .filter-bar { flex-direction: column; align-items: stretch; }
    .filter-group { flex-wrap: wrap; }

    .section-header h2 { font-size: 24px; }
    .schedule-page-header h1 { font-size: 28px; }
}

@media (max-width: 480px) {
    .conf-hero { padding: var(--space-xl) var(--space-md); }
    .conf-hero h1 { font-size: 26px; }
    .conf-hero-actions { flex-direction: column; align-items: center; }
    .btn-primary, .btn-outline { width: 100%; text-align: center; }
    .speakers-grid { grid-template-columns: 1fr 1fr; gap: var(--space-md); }
}


/* =============================================================================
   Conference Homepage Template (ch-* classes)
   Landing page: hero, credibility, notify, speakers, why, who, sponsor, venue
   ============================================================================= */

/* Toggle utility */
.conf-section--hidden { display: none !important; }

/* =============================================================================
   Phase-gated visibility (#2721)
   Body class <body class="phase-<value>"> is applied by conference.js.
   - .conf-section--announcement-only renders only in announcement.
   - .conf-section--sales-only renders only when sales are open or live.

   #2807: removed `.conf-section--placeholder` fade-to-grayscale treatment.
   In announcement phase the past-speakers/past-sponsors/past-artists
   sections ARE the social proof — they must render full color. When
   there is no content to surface (zero past entries), the populating JS
   hides the section outright via `.conf-section--hidden` rather than
   rendering a faded placeholder treatment.
   ============================================================================= */

.conf-section--announcement-only { display: none; }
body.phase-announcement .conf-section--announcement-only { display: block; }

.conf-section--sales-only { display: block; }
body.phase-announcement .conf-section--sales-only,
body.phase-live .conf-section--sales-only { display: none; }

body.phase-announcement .conf-section--hide-in-announcement { display: none !important; }

/* Design principle: in announcement phase, pass-tier cards must be
   HIDDEN. "If you can see a tier, you should be able to buy it" — so
   we never show tiers behind a paywall. Tiers appear when phase flips
   to sales_open. */
body.phase-announcement .pass-tier-card { display: none !important; }

/* -----------------------------------------------------------------------------
   phase=sales_open (#2889) — tickets on sale
   The lineup has been revealed AND tickets are now actively on sale. All
   `lineup_announced` content stays visible; the difference is in the
   action surfaces (hero CTAs + pass-tier buy buttons) and the appearance
   of sales-only sections (e.g. an index-page "Tickets are live" banner).

   What's shown:
   - Pass-tier checkout buttons (.pass-buy-btn): default state, no
     suppression rule needed. The Stripe Checkout path is wired to the
     existing single-tier checkout shim (#2546).
   - Hero "Sales open" indicator pill (.ch-hero-sales-open-pill) — a
     small high-contrast badge surfaced under the hero badge to signal
     that registration is live.
   - Hero "Buy Passes / View Schedule" CTA row (.ch-cta-sales-open) —
     replaces the prelaunch CTA row. Default-hidden; phase-sales_open
     reveals it.
   - Sales-only sections (.conf-section--sales-only) — sections that
     only make sense once tickets are on sale (e.g. an index-page
     "Tickets are live, save your seat" banner). Default-visible via
     the rule above (line ~959); phase-announcement / live hide it,
     leaving sales_open as the active reveal phase.
   - Speakers / Schedule / Sponsors render normally.

   What's suppressed:
   - "Sales closed" pill (sales-closed-note) — wrong copy before
     the event itself.
   - Hero prelaunch CTAs (.ch-cta-prelaunch) — sign-up-for-notify is the
     wrong primary action once sales are open. The dedicated #section-notify
     section stays in the DOM but no longer carries the hero CTA load.
   - Announcement-only sections (.conf-section--announcement-only) —
     inherit the default-hidden rule; only phase-announcement reveals them.

   Out of scope: the admin transition handler that mass-flips
   `ticket_sales_open=True` on event rows when an admin advances phase to
   sales_open — tracked in sibling issue #2890.
   ----------------------------------------------------------------------------- */

/* Sales-only sections reveal in phase-sales_open. The default rule (line
   ~959) sets `display: block` and the three other phases hide it; the
   selector below makes the intent explicit for code-search / grep and
   guards against a future refactor of the default-visible rule. */
body.phase-sales_open .conf-section--sales-only { display: block; }

/* Suppress lingering post-sale pill in sales_open. The pass-buy-btn
   default state (visible) is the right CTA here. */
body.phase-sales_open .pass-tier-sales-closed-note { display: none !important; }

/* Hide the hero prelaunch CTA row in phase-sales_open — sign-up-for-notify
   isn't the right primary CTA once tickets are on sale. */
body.phase-sales_open .ch-cta-prelaunch { display: none !important; }

/* Reveal the sales-open hero CTA row. The .ch-cta-sales-open block is
   hidden by default (rule below in the hero block); flip it on for
   phase-sales_open so the "Buy Passes / View Schedule" buttons show. */
.ch-cta-sales-open { display: none; }
body.phase-sales_open .ch-cta-sales-open { display: flex !important; gap: 16px; flex-wrap: wrap; justify-content: center; }

/* "Sales open" hero indicator pill — small high-contrast badge surfaced
   under the hero badge in sales_open phase only. Default-hidden so the
   markup can ship in every render without polluting other phases. */
.ch-hero-sales-open-pill { display: none; }
body.phase-sales_open .ch-hero-sales-open-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 12px;
    margin-top: 8px;
    margin-bottom: 16px;
    background: var(--conf-primary, #ec0244);
    color: #fff;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 1.2px;
    text-transform: uppercase;
}
.ch-hero-sales-open-pill::before {
    content: "";
    display: inline-block;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: #fff;
    animation: schedule-live-pulse 1.6s ease-in-out infinite;
}

/* "Tickets are live" sales-only banner (index page). A compact card-style
   strip that surfaces in phase-sales_open as the primary post-lineup CTA. */
.ch-sales-banner {
    margin: 0 auto;
    max-width: 1140px;
    padding: 24px 32px;
    background: linear-gradient(135deg, var(--conf-primary, #ec0244) 0%, var(--conf-accent, #7b0035) 100%);
    color: #fff;
    border-radius: 12px;
    box-shadow: 0 4px 16px rgba(0,0,0,0.12);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
}
.ch-sales-banner__text {
    flex: 1 1 60%;
    min-width: 240px;
}
.ch-sales-banner__title {
    font-size: 22px;
    font-weight: 700;
    line-height: 1.25;
    margin: 0 0 4px;
}
.ch-sales-banner__body {
    font-size: 14px;
    opacity: 0.92;
    margin: 0;
}
.ch-sales-banner__btn {
    background: #fff;
    color: var(--conf-primary, #ec0244);
    padding: 10px 22px;
    border-radius: 8px;
    font-weight: 700;
    text-decoration: none;
    font-size: 14px;
    letter-spacing: 0.3px;
    transition: transform 0.15s, box-shadow 0.15s;
}
.ch-sales-banner__btn:hover { transform: translateY(-1px); box-shadow: 0 6px 16px rgba(0,0,0,0.18); }

/* -----------------------------------------------------------------------------
   phase=live (#2802) — event day-of
   The conference is happening right now. Schedule is the centerpiece:
   surface a live status strip (countdown to next session / "Happening now"
   / "Just ended") and highlight the currently-running session in the grid
   and list views.

   What's suppressed:
   - Pass-tier checkout buttons (.pass-buy-btn): tickets sales closed.
   - "Sales-only" sections (already handled in the rule above with
     .conf-section--sales-only): registration sections collapsed.
   - "Get involved" announcement-only sections: inherit hidden default
     since only phase-announcement reveals them.
   - Hero "Get on the List / Apply to Speak" prelaunch CTAs: the event
     is mid-flight; these CTAs don't belong on the day-of page.

   What's shown:
   - Hero "Register Now / View Agenda" .ch-cta-live block — but JS in
     index.html overrides label/href during phase=live to point at the
     schedule page (no longer a register CTA — see issue #2802 follow-up
     to refine the live-phase hero CTA copy).
   - Schedule live-status strip + .session-live-now highlight on the
     currently-running session card.
   - Speakers, sponsors, schedule sections all render normally.

   Out of scope: phase=archived (filed as follow-up to #2802).
   ----------------------------------------------------------------------------- */

/* Suppress the checkout button on every pass-tier card. JS still
   renders the button so the DOM stays stable; CSS just hides it. */
body.phase-live .pass-buy-btn { display: none !important; }

/* Sales-closed pill — hidden by default, revealed in phase-live. */
.pass-tier-sales-closed-note { display: none; }
body.phase-live .pass-tier-sales-closed-note {
    display: block;
    width: 100%;
    padding: 12px 20px;
    background: var(--conf-dark, #262f35);
    color: #fff;
    border-radius: 8px;
    font-size: 14px;
    font-weight: 600;
    text-align: center;
    letter-spacing: 0.2px;
}

/* Hide the hero prelaunch CTA row in phase-live. The mailing-list /
   "Apply to Speak" prompts don't belong on the day-of page. */
body.phase-live .ch-cta-prelaunch { display: none !important; }

/* Reveal the hero live-action CTA row. The .ch-cta-live block is hidden
   by default (rule at line ~1190); flip it on for phase-live so the
   "Register Now / View Agenda" buttons show. JS in index.html may
   re-label the buttons for the day-of context. */
body.phase-live .ch-cta-live { display: flex !important; gap: 16px; flex-wrap: wrap; justify-content: center; }

/* -----------------------------------------------------------------------------
   Schedule live status strip (#2802)
   Rendered into schedule.html above the grid; only visible in phase-live.
   Three states (JS-populated): "Happening now: <session>", "Up next: <session>
   in <T>", "Just ended: <session>".
   ----------------------------------------------------------------------------- */
.conf-live-only { display: none; }
body.phase-live .conf-live-only { display: block; }

.schedule-live-status {
    margin: 0 0 24px;
    padding: 18px 24px;
    background: linear-gradient(135deg, var(--conf-primary, #ec0244) 0%, var(--conf-accent, #7b0035) 100%);
    color: #fff;
    border-radius: 12px;
    box-shadow: 0 4px 16px rgba(0,0,0,0.12);
}
.schedule-live-status__label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 2px;
    text-transform: uppercase;
    opacity: 0.85;
    margin-bottom: 6px;
}
.schedule-live-status__title {
    font-size: 22px;
    font-weight: 700;
    line-height: 1.25;
    margin-bottom: 4px;
}
.schedule-live-status__meta {
    font-size: 14px;
    opacity: 0.9;
}
.schedule-live-status__pulse {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: #fff;
    margin-right: 8px;
    vertical-align: middle;
    animation: schedule-live-pulse 1.6s ease-in-out infinite;
}
@keyframes schedule-live-pulse {
    0%, 100% { opacity: 0.4; transform: scale(0.9); }
    50% { opacity: 1; transform: scale(1.1); }
}

/* "Happening now" highlight on the live session card in the grid + list. */
body.phase-live .session-block.session-live-now,
body.phase-live .schedule-list-item.session-live-now {
    outline: 2px solid var(--conf-primary, #ec0244);
    outline-offset: -2px;
    box-shadow: 0 0 0 4px rgba(236, 2, 68, 0.18);
}
.session-live-now-badge {
    display: none;
    background: var(--conf-primary, #ec0244);
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 1px;
    text-transform: uppercase;
    padding: 3px 8px;
    border-radius: 4px;
    margin-left: 8px;
    vertical-align: middle;
}
body.phase-live .session-live-now .session-live-now-badge { display: inline-block; }

/* ---- Shared section scaffolding ---- */
.ch-section {
    padding: 80px 24px;
    opacity: 0;
    transform: translateY(20px);
    transition: opacity 0.6s ease, transform 0.6s ease;
}
.ch-section.ch-revealed,
.ch-credibility.ch-revealed,
.ch-notify.ch-revealed { opacity: 1; transform: none; }

.ch-section-inner {
    max-width: 1140px;
    margin: 0 auto;
}

.ch-section-alt  { background: var(--color-surface-alt); }
.ch-section-dark { background: var(--color-dark); }
.ch-section-ruled {
    border-top: 1px solid var(--color-border);
    border-bottom: 1px solid var(--color-border);
}

.ch-section-header {
    text-align: center;
    margin-bottom: 56px;
}

.ch-section-label {
    display: inline-block;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 2.5px;
    text-transform: uppercase;
    color: var(--color-primary);
    margin-bottom: 12px;
}

.ch-label-onDark { color: var(--color-light); opacity: 0.7; }

.ch-section-title {
    font-family: var(--font-heading);
    font-size: 40px;
    font-weight: 700;
    color: var(--color-dark);
    line-height: 1.15;
    margin: 0 0 16px;
}

.ch-title-onDark { color: #fff; }

.ch-section-subtitle {
    font-size: 17px;
    color: var(--color-text-muted);
    max-width: 580px;
    margin: 0 auto;
    line-height: 1.6;
}

.ch-section-footer { text-align: center; margin-top: 40px; }

.ch-link-more {
    font-size: 15px;
    font-weight: 600;
    color: var(--color-primary);
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    transition: gap 0.2s;
}
.ch-link-more:hover { gap: 10px; text-decoration: none; }

/* ---- Buttons ---- */
.ch-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 14px 32px;
    border-radius: 8px;
    font-family: var(--font-heading);
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    text-decoration: none;
    border: 2px solid transparent;
    transition: background 0.18s, border-color 0.18s, color 0.18s, transform 0.15s;
    white-space: nowrap;
}
.ch-btn:hover { text-decoration: none; transform: translateY(-1px); }

.ch-btn-primary {
    background: var(--color-primary);
    color: #fff;
    border-color: var(--color-primary);
}
/* The fill stays the brand color, which has no contrast guarantee against this
   always-dark section, so the edge carries 1.4.11 instead (#6143). */
.ch-section-dark .ch-btn-primary { border-color: rgba(255,255,255,0.45); }
.ch-btn-primary:hover { background: #d0023b; border-color: #d0023b; color: #fff; }

.ch-btn-ghost {
    background: transparent;
    color: #fff;
    border-color: rgba(255,255,255,0.45);
}
.ch-btn-ghost:hover { border-color: #fff; color: #fff; background: rgba(255,255,255,0.08); }

.ch-btn-lg { padding: 16px 40px; font-size: 16px; }


/* ---- Hero ---- */
.ch-hero {
    position: relative;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-align: center;
    overflow: hidden;
    color: #fff;
    padding: 120px 24px 80px;
}

.ch-hero-bg {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
    background-image: linear-gradient(135deg, var(--color-dark) 0%, var(--color-maroon) 100%);
    transform: scale(1.03);
    transition: transform 8s ease-out;
}
.ch-hero-bg.loaded { transform: scale(1); }

.ch-hero-overlay {
    position: absolute;
    inset: 0;
    background: linear-gradient(
        to bottom,
        rgba(38,47,53,0.72) 0%,
        rgba(38,47,53,0.58) 50%,
        rgba(38,47,53,0.82) 100%
    );
}

.ch-hero-inner {
    position: relative;
    z-index: 1;
    max-width: 860px;
    animation: ch-fade-up 0.9s ease both;
}

.ch-hero-eyebrow {
    display: inline-block;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: rgba(255,255,255,0.75);
    margin-bottom: 24px;
    padding: 6px 16px;
    border: 1px solid rgba(255,255,255,0.22);
    border-radius: 20px;
    backdrop-filter: blur(4px);
}

.ch-hero-title {
    font-family: var(--font-heading);
    font-size: clamp(42px, 6vw, 80px);
    font-weight: 800;
    line-height: 1.07;
    letter-spacing: -1px;
    margin: 0 0 28px;
    color: #fff;
}

.ch-hero-tagline {
    font-size: clamp(16px, 2.2vw, 20px);
    line-height: 1.6;
    color: rgba(255,255,255,0.82);
    max-width: 640px;
    margin: 0 auto 44px;
}

.ch-hero-actions {
    display: flex;
    gap: 16px;
    justify-content: center;
    flex-wrap: wrap;
}
.ch-cta-live { display: none; }

.ch-hero-scroll {
    position: absolute;
    bottom: 32px;
    left: 50%;
    transform: translateX(-50%);
    background: none;
    border: 1px solid rgba(255,255,255,0.3);
    border-radius: 50%;
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: rgba(255,255,255,0.7);
    cursor: pointer;
    transition: opacity 0.3s, border-color 0.2s;
    animation: ch-bounce 2.4s ease infinite 2s;
    z-index: 1;
}
.ch-hero-scroll:hover { border-color: rgba(255,255,255,0.7); color: #fff; }


/* ---- Credibility bar ---- */
.ch-credibility {
    background: var(--color-dark);
    padding: 28px 24px;
    opacity: 0;
    transform: translateY(12px);
    transition: opacity 0.5s ease 0.1s, transform 0.5s ease 0.1s;
}

.ch-credibility-inner {
    max-width: 1140px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0;
    flex-wrap: wrap;
}

.ch-cred-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 8px 36px;
    text-align: center;
}

.ch-cred-number {
    font-family: var(--font-heading);
    font-size: 26px;
    font-weight: 700;
    color: #fff;
    line-height: 1;
    margin-bottom: 4px;
}

.ch-cred-label {
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: rgba(255,255,255,0.5);
}

.ch-cred-divider {
    width: 1px;
    height: 40px;
    background: rgba(255,255,255,0.15);
    flex-shrink: 0;
}


/* ---- Email capture ---- */
.ch-notify {
    background: var(--color-dark);
    border-top: 1px solid rgba(255,255,255,0.08);
    padding: 72px 24px;
    opacity: 0;
    transform: translateY(20px);
    transition: opacity 0.6s ease, transform 0.6s ease;
}

.ch-notify-inner {
    max-width: 760px;
    margin: 0 auto;
    display: flex;
    gap: 48px;
    align-items: center;
}

.ch-notify-text { flex: 1; }

.ch-notify-heading {
    font-family: var(--font-heading);
    font-size: 32px;
    font-weight: 700;
    color: #fff;
    margin: 0 0 10px;
}

.ch-notify-sub {
    font-size: 15px;
    color: rgba(255,255,255,0.65);
    line-height: 1.6;
    margin: 0;
}

.ch-notify-form { flex: 1; }

.ch-notify-input-row {
    display: flex;
    gap: 10px;
}

.ch-notify-input {
    flex: 1;
    padding: 13px 16px;
    border-radius: 8px;
    border: 1.5px solid rgba(255,255,255,0.2);
    background: rgba(255,255,255,0.07);
    color: #fff;
    font-size: 15px;
    font-family: var(--font-body);
    outline: none;
    transition: border-color 0.18s;
    min-width: 0;
}
.ch-notify-input::placeholder { color: rgba(255,255,255,0.55); }
.ch-notify-input:focus { border-color: var(--color-primary); }

.ch-notify-legal {
    margin: 10px 0 0;
    font-size: 12px;
    color: rgba(255,255,255,0.7);
}

.ch-notify-success {
    display: none;
    align-items: center;
    gap: 10px;
    color: #6ee7b7;
    font-size: 15px;
    font-weight: 500;
    padding: 14px 0;
}
.ch-notify-success i { font-size: 20px; }


/* ---- Speakers grid ---- */
.ch-speakers-section { background: var(--color-bg); }

.ch-speakers-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 24px;
}

.ch-spk-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 12px;
    padding: 28px 20px 24px;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    transition: border-color 0.2s, box-shadow 0.2s, transform 0.2s;
    position: relative;
}
.ch-spk-card:hover {
    border-color: var(--color-border-dark);
    box-shadow: 0 8px 28px rgba(0,0,0,0.08);
    transform: translateY(-2px);
}

.ch-spk-card--featured {
    grid-column: span 3;
    flex-direction: row;
    text-align: left;
    gap: 32px;
    padding: 36px;
    border-left: 4px solid var(--color-primary);
    align-items: flex-start;
}

/* The 0.55 dim is deliberate: it is what makes a TBA placeholder read as
   secondary to a real speaker card. `pointer-events: none` is invisible and
   the dashed border alone is not enough. It composites the card's own text
   toward the #fafafa section, so the two text colors below are near-black to
   clear AA THROUGH it — #000000 lands at 4.87:1, and anything above #080808
   fails. Change this opacity and those two colors together (#6388). */
.ch-spk-card--tba {
    border-style: dashed;
    border-color: var(--color-border);
    opacity: 0.55;
    pointer-events: none;
}
.ch-spk-card--tba:hover { transform: none; box-shadow: none; }

.ch-spk-photo-wrap { margin-bottom: 16px; flex-shrink: 0; }
.ch-spk-card--featured .ch-spk-photo-wrap { margin-bottom: 0; }

.ch-spk-photo {
    width: 96px;
    height: 96px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--color-surface-alt);
    display: block;
}

.ch-spk-photo--lg { width: 128px; height: 128px; }

.ch-spk-initial {
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-heading);
    font-size: 32px;
    font-weight: 700;
    color: var(--color-dark);
    background: var(--color-light);
}

.ch-spk-badge {
    display: inline-block;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: var(--color-primary);
    background: rgba(236,2,68,0.09);
    padding: 3px 10px;
    border-radius: 4px;
    margin-bottom: 8px;
}

.ch-spk-name {
    font-family: var(--font-heading);
    font-size: 17px;
    font-weight: 700;
    color: var(--color-dark);
    margin: 0 0 5px;
    line-height: 1.2;
}
.ch-spk-name--lg { font-size: 26px; margin-bottom: 8px; }

.ch-spk-role {
    font-size: 13px;
    color: var(--color-text-muted);
    margin: 0 0 2px;
}

.ch-spk-company {
    font-size: 13px;
    font-weight: 600;
    color: var(--color-dark);
    margin: 0;
}

.ch-spk-bio {
    font-size: 14px;
    line-height: 1.65;
    color: var(--color-text-muted);
    margin: 14px 0 0;
}

.ch-spk-card--featured .ch-spk-body { flex: 1; }

.ch-spk-tba-circle {
    width: 96px;
    height: 96px;
    border-radius: 50%;
    background: var(--color-surface-alt);
}

.ch-spk-tba-label {
    font-size: 14px;
    font-weight: 600;
    /* #6388: #666666 rendered at 2.31:1 through the card's 0.55 opacity. */
    color: #000000;
    margin: 0 0 4px;
}

.ch-spk-tba-sub {
    font-size: 12px;
    /* #6388: #999999 rendered at 1.70:1 through the same dim. */
    color: #000000;
    margin: 0;
}


/* ---- Why Attend ---- */
.ch-why-section { background: var(--color-bg); }

.ch-why-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 28px;
}

.ch-why-card {
    padding: 32px 28px;
    border-left: 3px solid var(--color-primary);
    background: var(--color-surface);
    border-radius: 0 10px 10px 0;
    border-top: 1px solid var(--color-border);
    border-right: 1px solid var(--color-border);
    border-bottom: 1px solid var(--color-border);
}

.ch-why-icon {
    width: 44px;
    height: 44px;
    background: rgba(236,2,68,0.07);
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--color-primary);
    font-size: 18px;
    margin-bottom: 20px;
}

.ch-why-heading {
    font-family: var(--font-heading);
    font-size: 18px;
    font-weight: 700;
    color: var(--color-dark);
    margin: 0 0 10px;
}

.ch-why-body {
    font-size: 14px;
    line-height: 1.7;
    color: var(--color-text-muted);
    margin: 0;
}


/* ---- Who's in the Room ---- */
.ch-whos-section { background: var(--color-surface-alt); }

/* Logo scroll strip */
.ch-logo-strip {
    width: 100%;
    overflow: hidden;
    margin-bottom: 48px;
    mask-image: linear-gradient(to right, transparent 0%, black 12%, black 88%, transparent 100%);
    -webkit-mask-image: linear-gradient(to right, transparent 0%, black 12%, black 88%, transparent 100%);
}

.ch-logo-track {
    display: flex;
    gap: 0;
    animation: ch-scroll-logos 28s linear infinite;
    width: max-content;
}
.ch-logo-track:hover { animation-play-state: paused; }

@keyframes ch-scroll-logos {
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
}

.ch-logo-item {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 40px;
    height: 60px;
    flex-shrink: 0;
}

.ch-logo-item img {
    height: 32px;
    width: auto;
    object-fit: contain;
    filter: grayscale(100%);
    opacity: 0.5;
    transition: opacity 0.2s, filter 0.2s;
}
.ch-logo-item img:hover { filter: grayscale(0%); opacity: 0.9; }

.ch-logo-wordmark {
    font-family: var(--font-heading);
    font-size: 14px;
    font-weight: 600;
    color: var(--color-text-muted);
    white-space: nowrap;
    letter-spacing: 0.3px;
}

/* Attendee profile tiles */
.ch-profile-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 12px;
    margin-bottom: 48px;
}

.ch-profile-tile {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 8px;
    padding: 16px 18px;
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.ch-profile-title {
    font-size: 13px;
    font-weight: 600;
    color: var(--color-dark);
    line-height: 1.3;
}

.ch-profile-company {
    font-size: 12px;
    color: var(--color-text-muted);
}

/* Testimonial quotes */
.ch-quotes-row {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 24px;
}

.ch-quote {
    background: var(--color-surface);
    border-radius: 10px;
    padding: 28px 24px;
    border: 1px solid var(--color-border);
    margin: 0;
    position: relative;
}
.ch-quote::before {
    content: '\201C';
    position: absolute;
    top: 16px;
    left: 20px;
    font-size: 48px;
    font-family: Georgia, serif;
    color: var(--color-primary);
    line-height: 1;
    opacity: 0.35;
}

.ch-quote-text {
    font-size: 14px;
    line-height: 1.7;
    color: var(--color-text);
    margin: 0 0 16px;
    padding-top: 16px;
}

.ch-quote-cite {
    font-size: 12px;
    font-style: normal;
    font-weight: 600;
    color: var(--color-text-muted);
}


/* ---- Sponsor pitch ---- */
.ch-sponsor-pitch-section { padding: 80px 24px; }

.ch-sponsor-split {
    display: grid;
    grid-template-columns: 1.1fr 0.9fr;
    gap: 64px;
    align-items: start;
}

.ch-sponsor-body {
    font-size: 16px;
    line-height: 1.7;
    color: rgba(255,255,255,0.72);
    margin: 0 0 32px;
}

.ch-tier-list {
    border-top: 1px solid rgba(255,255,255,0.12);
    margin-bottom: 36px;
}

.ch-tier-row {
    display: flex;
    align-items: baseline;
    gap: 16px;
    padding: 14px 0;
    border-bottom: 1px solid rgba(255,255,255,0.08);
}

.ch-tier-name {
    font-family: var(--font-heading);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 1px;
    text-transform: uppercase;
    /* fixed light: this section is always dark (#6122) */
    color: rgba(255,255,255,0.92);
    flex-shrink: 0;
    width: 80px;
}

.ch-tier-benefit {
    font-size: 14px;
    color: rgba(255,255,255,0.65);
}

.ch-sponsor-incoming {
    background: rgba(255,255,255,0.05);
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 12px;
    padding: 36px 32px;
    text-align: center;
}

.ch-sponsor-incoming-headline {
    font-family: var(--font-heading);
    font-size: 20px;
    font-weight: 700;
    color: #fff;
    margin: 0 0 8px;
}

.ch-sponsor-incoming-sub {
    font-size: 14px;
    color: rgba(255,255,255,0.55);
    margin: 0 0 24px;
}

.ch-sponsor-inquire {
    font-size: 14px;
    font-weight: 600;
    color: #fff;
    text-decoration: underline;
    text-underline-offset: 3px;
}
.ch-sponsor-inquire:hover { opacity: 0.8; }

/* Confirmed sponsors (shown when data loads) */
.ch-confirmed-logos { display: flex; flex-direction: column; gap: 24px; }

.ch-sponsor-tier-group {}
.ch-sponsor-tier-label {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: rgba(255,255,255,0.4);
    margin-bottom: 12px;
}

.ch-sponsor-logo-row {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    align-items: center;
}

/* #6474 — light plate, not a knockout filter; renders every logo at
   its own colors regardless of alpha. */
.ch-sponsor-logo {
    height: 50px; /* 36px logo + 2x6px padding + 2x1px border (box-sizing:border-box, line 61) */
    width: auto;
    background: #ffffff;
    border: 1px solid rgba(0,0,0,0.08);
    border-radius: 6px;
    padding: 6px 10px;
}
.ch-sponsor-name { font-size: 13px; font-weight: 600; color: rgba(255,255,255,0.7); }


/* ---- Venue ---- */
.ch-venue-section { background: var(--color-bg); }

.ch-venue-split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 64px;
    align-items: center;
}

.ch-venue-name {
    font-family: var(--font-heading);
    font-size: 36px;
    font-weight: 700;
    color: var(--color-dark);
    margin: 12px 0 4px;
    line-height: 1.2;
}

.ch-venue-institution {
    font-size: 15px;
    color: var(--color-primary);
    font-weight: 600;
    margin: 0 0 16px;
    letter-spacing: 0.3px;
}

.ch-venue-address {
    font-size: 14px;
    color: var(--color-text-muted);
    margin: 0 0 20px;
}

.ch-venue-desc {
    font-size: 15px;
    line-height: 1.75;
    color: var(--color-text);
    margin: 0 0 28px;
}

.ch-venue-links {
    display: flex;
    gap: 24px;
    flex-wrap: wrap;
}

.ch-venue-link {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: 14px;
    font-weight: 600;
    color: var(--color-dark);
    text-decoration: none;
    transition: color 0.18s;
}
.ch-venue-link:hover { color: var(--color-primary); text-decoration: none; }
.ch-venue-link i { font-size: 13px; color: var(--color-primary); }

.ch-venue-visual {
    border-radius: 14px;
    overflow: hidden;
    aspect-ratio: 4/3;
    /* #4409: white card + subtle border so a white-background venue logo
       blends into the card instead of sitting on gray with letterbox bands,
       and the card still reads against the #fafafa section background. */
    background: var(--color-surface);
    border: 1px solid var(--color-border);
}

.ch-venue-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 14px;
    color: var(--color-text-light);
    background: linear-gradient(135deg, var(--color-dark) 0%, #3a4a55 100%);
}
.ch-venue-placeholder i { font-size: 48px; color: rgba(255,255,255,0.25); }
/* #6388: rgba(255,255,255,0.5) composited to 3.65:1 against the light end of
   this element's own #262f35 -> #3a4a55 gradient. Opaque light grey instead. */
.ch-venue-placeholder span { font-size: 14px; font-weight: 500; color: #cbd5e1; text-align: center; line-height: 1.5; }

/* #4406: `contain` (not `cover`) so wide venue logos fit in full inside the
   4:3 box rather than being scaled up and cropped. Works for photos and logos.
   #4409: padding centers the logo with even breathing room (a padded logo
   card) instead of hugging the edges; box-sizing keeps it inside the box. */
.ch-venue-photo {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
    padding: 32px;
    box-sizing: border-box;
}


/* ---- CFP / Apply to Speak ---- */
.ch-cfp-inner {
    max-width: 680px;
    margin: 0 auto;
    text-align: center;
}

.ch-cfp-body {
    font-size: 17px;
    line-height: 1.75;
    color: var(--color-text);
    margin: 0 0 32px;
}
.ch-cfp-body strong { color: var(--color-dark); }

.ch-cfp-meta {
    display: flex;
    gap: 28px;
    justify-content: center;
    flex-wrap: wrap;
    margin-bottom: 36px;
}

.ch-cfp-meta-item {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 14px;
    color: var(--color-text-muted);
    font-weight: 500;
}
.ch-cfp-meta-item i { color: var(--color-primary); }


/* ---- Footer ---- */
.ch-footer {
    background: var(--color-dark);
    padding: 40px 24px;
    border-top: 1px solid rgba(255,255,255,0.08);
}

.ch-footer-inner {
    max-width: 1140px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    gap: 40px;
    flex-wrap: wrap;
}

.ch-footer-brand {
    display: flex;
    flex-direction: column;
    gap: 4px;
    flex: 1;
}

/* Org social links (#5743). Own row under brand/nav/powered: flex-basis 100%
   forces the wrap in .ch-footer-inner's existing flex-wrap layout, so the
   three-part row above is untouched.

   :empty keeps it invisible for an org with no socials — the container is
   always emitted, and applySocialLinks writes nothing when every value is
   blank. Without this an org with no socials would get 24px of dead space,
   border included. The emitted container must therefore stay byte-empty; a
   single space would defeat :empty. Pinned in
   tests/js/conference_social_links_5743.js. */
.ch-footer-social {
    flex-basis: 100%;
    display: flex;
    justify-content: center;
    gap: 20px;
    padding-top: 24px;
    border-top: 1px solid rgba(255,255,255,0.08);
}

.ch-footer-social:empty {
    display: none;
}

.ch-footer-social a {
    color: rgba(255,255,255,0.6);
    font-size: 18px;
    line-height: 1;
    transition: color 0.15s ease;
}

.ch-footer-social a:hover,
.ch-footer-social a:focus-visible {
    color: #fff;
}

.ch-footer-name {
    font-family: var(--font-heading);
    font-size: 16px;
    font-weight: 700;
    color: #fff;
}

.ch-footer-date {
    font-size: 12px;
    color: rgba(255,255,255,0.45);
}

.ch-footer-nav {
    display: flex;
    gap: 28px;
    flex-wrap: wrap;
}

.ch-footer-nav a {
    font-size: 13px;
    font-weight: 500;
    color: rgba(255,255,255,0.6);
    text-decoration: none;
    transition: color 0.18s;
}
.ch-footer-nav a:hover { color: #fff; text-decoration: none; }

.ch-footer-powered {
    font-size: 12px;
    color: rgba(255,255,255,0.3);
    margin: 0;
}

.ch-footer-powered a { color: rgba(255,255,255,0.5); text-decoration: none; }
.ch-footer-powered a:hover { color: #fff; text-decoration: none; }


/* ---- Animations ---- */
@keyframes ch-fade-up {
    from { opacity: 0; transform: translateY(28px); }
    to   { opacity: 1; transform: none; }
}

@keyframes ch-bounce {
    0%, 100% { transform: translateX(-50%) translateY(0); }
    50%       { transform: translateX(-50%) translateY(6px); }
}


/* ---- Responsive ---- */
@media (max-width: 1024px) {
    .ch-speakers-grid { grid-template-columns: repeat(2, 1fr); }
    .ch-spk-card--featured { grid-column: span 2; }
    .ch-profile-grid { grid-template-columns: repeat(3, 1fr); }
    .ch-why-grid { grid-template-columns: repeat(3, 1fr); }
    .ch-sponsor-split { gap: 40px; }
    .ch-venue-split { gap: 40px; }
}

@media (max-width: 768px) {
    .ch-section { padding: 56px 20px; }
    .ch-section-title { font-size: 30px; }
    .ch-section-header { margin-bottom: 36px; }

    .ch-speakers-grid { grid-template-columns: repeat(2, 1fr); gap: 16px; }
    .ch-spk-card--featured { grid-column: span 2; flex-direction: column; text-align: center; }
    .ch-spk-card--featured .ch-spk-photo-wrap { margin-bottom: 16px; }

    .ch-why-grid { grid-template-columns: 1fr; gap: 16px; }
    .ch-profile-grid { grid-template-columns: repeat(2, 1fr); }
    .ch-quotes-row { grid-template-columns: 1fr; }
    .ch-sponsor-split { grid-template-columns: 1fr; gap: 40px; }
    .ch-venue-split { grid-template-columns: 1fr; gap: 32px; }
    .ch-notify-inner { flex-direction: column; gap: 28px; }
    .ch-credibility-inner { gap: 0; }
    .ch-cred-item { padding: 8px 20px; }
    .ch-cred-divider { height: 28px; }
    .ch-footer-inner { flex-direction: column; align-items: flex-start; gap: 20px; }
}

@media (max-width: 480px) {
    .ch-hero { padding: 100px 20px 60px; }
    .ch-hero-title { font-size: 36px; letter-spacing: -0.5px; }
    .ch-hero-actions { flex-direction: column; }
    .ch-btn { width: 100%; justify-content: center; }
    .ch-speakers-grid { grid-template-columns: 1fr; }
    .ch-spk-card--featured { grid-column: span 1; }
    .ch-profile-grid { grid-template-columns: 1fr 1fr; }
    .ch-notify-input-row { flex-direction: column; }
    .ch-credibility-inner { flex-direction: column; gap: 4px; }
    .ch-cred-divider { width: 40px; height: 1px; }
}


/* =============================================================================
   Session Detail Page (session.html)
   Public session page — hero, speakers, abstract, calendar button.
   ============================================================================= */

.session-detail-wrapper {
    max-width: 860px;
    margin: 0 auto;
    padding: var(--space-xl) var(--space-lg) var(--space-xxxl);
}

.session-detail-back-row { margin-bottom: var(--space-lg); }

.session-detail-back-link {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--color-text-muted);
    font-size: 14px;
    font-weight: 500;
    text-decoration: none;
    transition: color 0.15s;
}
.session-detail-back-link:hover { color: var(--color-primary); text-decoration: none; }
.session-detail-back-link i { font-size: 12px; }

/* ---- Hero ---- */
.session-detail-hero {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 12px;
    padding: var(--space-xl) var(--space-lg);
    margin-bottom: var(--space-xl);
}

.session-detail-badges {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: var(--space-md);
}

.session-detail-badge {
    display: inline-block;
    padding: 4px 12px;
    border-radius: 12px;
    font-size: 12px;
    font-weight: 600;
    text-transform: capitalize;
    letter-spacing: 0.02em;
}
.session-detail-badge--format {
    background: var(--color-light);
    color: var(--color-dark);
}
.session-detail-badge--level {
    background: var(--color-surface-alt);
    color: var(--color-text-muted);
}

.session-detail-title {
    font-family: var(--font-heading);
    font-size: 36px;
    line-height: 1.2;
    font-weight: 700;
    color: var(--color-dark);
    margin-bottom: var(--space-md);
}

.session-detail-time,
.session-detail-venue {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 16px;
    color: var(--color-text);
    margin-bottom: var(--space-xs);
}
.session-detail-time i,
.session-detail-venue i {
    color: var(--color-text-muted);
    font-size: 14px;
    width: 16px;
    text-align: center;
}
.session-detail-venue { color: var(--color-text-muted); }

.session-detail-actions {
    display: flex;
    gap: var(--space-md);
    flex-wrap: wrap;
    margin-top: var(--space-lg);
}

.session-detail-cta-join,
.session-detail-cta-ics {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 15px;
    padding: 12px 24px;
}

/* ---- Sections ---- */
.session-detail-section {
    margin-bottom: var(--space-xl);
}

.session-detail-section h2 {
    font-family: var(--font-heading);
    font-size: 22px;
    font-weight: 700;
    color: var(--color-dark);
    margin-bottom: var(--space-md);
    padding-bottom: var(--space-sm);
    border-bottom: 1px solid var(--color-border);
}

/* ---- Abstract ---- */
.session-detail-abstract {
    font-size: 16px;
    line-height: 1.7;
    color: var(--color-text);
}
.session-detail-abstract p { margin-bottom: var(--space-md); }
.session-detail-abstract p:last-child { margin-bottom: 0; }

/* ---- Speakers ---- */
.session-detail-speakers-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
}

.session-detail-speaker-card {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 10px;
    padding: var(--space-md);
}

.session-detail-speaker-photo {
    width: 80px;
    height: 80px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--color-light);
    flex-shrink: 0;
}
.session-detail-speaker-photo--placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-heading);
    font-size: 28px;
    font-weight: 700;
    color: var(--color-dark);
}

.session-detail-speaker-info {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
    flex: 1;
}
.session-detail-speaker-name {
    font-family: var(--font-heading);
    font-size: 18px;
    font-weight: 700;
    color: var(--color-dark);
    margin: 0;
}
.session-detail-speaker-subtitle {
    font-size: 14px;
    color: var(--color-text-muted);
    margin: 0;
    line-height: 1.4;
}
.session-detail-speaker-role {
    display: inline-block;
    align-self: flex-start;
    margin-top: 4px;
    padding: 2px 10px;
    border-radius: 10px;
    background: var(--color-surface-alt);
    color: var(--color-text-muted);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

/* ---- Mobile ---- */
@media (max-width: 600px) {
    .session-detail-wrapper {
        padding: var(--space-lg) var(--space-md) var(--space-xxl);
    }
    .session-detail-hero {
        padding: var(--space-lg) var(--space-md);
    }
    .session-detail-title { font-size: 26px; }
    .session-detail-time,
    .session-detail-venue { font-size: 14px; }
    .session-detail-actions { flex-direction: column; align-items: stretch; }
    .session-detail-cta-join,
    .session-detail-cta-ics { width: 100%; justify-content: center; }
    .session-detail-section h2 { font-size: 18px; }
    .session-detail-abstract { font-size: 15px; }
    .session-detail-speaker-card { padding: var(--space-sm) var(--space-md); }
    .session-detail-speaker-photo { width: 64px; height: 64px; }
    .session-detail-speaker-photo--placeholder { font-size: 22px; }
    .session-detail-speaker-name { font-size: 16px; }
}

/* =============================================================================
   Announcement Phase Components (#2721)
   Hero subhead, inline hero mailing-list form, two-card CTA row,
   advance information section, footer mailing-list.
   ============================================================================= */

/* Hero subhead */
.ch-hero-subhead {
    margin-top: 18px;
    font-size: 18px;
    line-height: 1.55;
    color: rgba(255, 255, 255, 0.85);
    max-width: 720px;
    margin-left: auto;
    margin-right: auto;
}

/* Inline hero mailing-list form (announcement phase) */
.ch-hero-notify {
    margin-top: 28px;
    max-width: 520px;
    margin-left: auto;
    margin-right: auto;
    text-align: center;
    position: relative;
}
.ch-hero-notify-row {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    justify-content: center;
}
.ch-hero-notify-input {
    flex: 1 1 240px;
    min-width: 0;
    padding: 14px 18px;
    border-radius: 8px;
    border: 1px solid rgba(255, 255, 255, 0.25);
    background: rgba(255, 255, 255, 0.08);
    color: #fff;
    font-size: 15px;
    font-family: inherit;
}
.ch-hero-notify-input::placeholder { color: rgba(255, 255, 255, 0.55); }
.ch-hero-notify-input:focus {
    outline: none;
    border-color: var(--theme-accent, var(--color-primary, #ec0244));
    background: rgba(255, 255, 255, 0.12);
}
.ch-hero-notify-legal {
    margin-top: 10px;
    font-size: 12px;
    color: rgba(255, 255, 255, 0.55);
}
.ch-hero-notify-success {
    margin-top: 12px;
    color: #b8e3c1;
    font-size: 14px;
    display: flex;
    gap: 8px;
    align-items: center;
    justify-content: center;
}

/* Two-card CTA row */
.ch-getinvolved-section { padding: 56px 24px 32px; }
.ch-cta-row {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 24px;
    max-width: 980px;
    margin: 0 auto;
}
.ch-cta-card {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 32px 28px;
    border: 1px solid var(--color-border, rgba(38, 47, 53, 0.12));
    border-radius: 14px;
    background: var(--theme-bg, #fff);
    color: var(--theme-text, #262f35);
    text-decoration: none;
    transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}
.ch-cta-card:hover {
    transform: translateY(-3px);
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.08);
    border-color: var(--theme-accent, var(--color-primary, #ec0244));
}
.ch-cta-card-icon {
    width: 48px;
    height: 48px;
    border-radius: 12px;
    background: linear-gradient(
        135deg,
        var(--theme-accent, var(--color-primary, #ec0244)),
        var(--theme-accent-2, var(--color-maroon, #7b0035))
    );
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
}
.ch-cta-card-title {
    margin: 0;
    font-size: 22px;
    font-weight: 600;
    font-family: var(--conf-font-display, inherit);
}
.ch-cta-card-body {
    margin: 0;
    color: var(--theme-text-muted, #5a6770);
    font-size: 15px;
    line-height: 1.55;
}
.ch-cta-card-link {
    margin-top: auto;
    padding-top: 8px;
    font-weight: 600;
    color: var(--theme-accent, var(--color-primary, #ec0244));
}
.ch-cta-card-link i { margin-left: 6px; transition: transform 0.18s ease; }
.ch-cta-card:hover .ch-cta-card-link i { transform: translateX(3px); }
@media (max-width: 700px) {
    .ch-cta-row { grid-template-columns: 1fr; gap: 16px; }
    .ch-cta-card { padding: 24px 20px; }
}

/* Advance Information section */
.ch-advance-info-section { padding: 64px 24px; }
.ch-advance-info-grid {
    display: grid;
    grid-template-columns: minmax(220px, 320px) 1fr;
    gap: 48px;
    max-width: 1100px;
    margin: 0 auto;
}
.ch-advance-info-facts {
    display: flex;
    flex-direction: column;
    gap: 18px;
}
.ch-advance-fact {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--color-border, rgba(38, 47, 53, 0.12));
}
.ch-advance-fact:last-child { border-bottom: none; }
.ch-advance-fact-label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 1.2px;
    color: var(--theme-text-muted, #5a6770);
    font-weight: 600;
}
.ch-advance-fact-value {
    font-size: 18px;
    color: var(--theme-text, #262f35);
    font-weight: 500;
}
.ch-advance-info-body {
    color: var(--theme-text, #262f35);
    font-size: 16px;
    line-height: 1.65;
}
.ch-advance-info-body p { margin: 0 0 14px; }
.ch-advance-info-body p:last-child { margin-bottom: 0; }
.ch-advance-info-body ul { padding-left: 1.25em; margin: 0 0 14px; }
.ch-advance-info-body li { margin-bottom: 6px; }
@media (max-width: 760px) {
    .ch-advance-info-grid { grid-template-columns: 1fr; gap: 32px; }
}

/* Footer mailing-list — visual parity with .ch-notify but variant class */
.ch-notify--footer {
    padding: 56px 24px;
}

/* =============================================================================
   Announcement UX Pass #1 (#2728)
   - Hide the duplicate "Advance Information" section in announcement phase
     (the hero now carries title + tagline + dates + venue).
   - Hide the "Apply to Speak" / "Become a Sponsor" nav items in announcement
     (their CTAs live inside the section pages now).
   - When a hero background image is set, swap the gradient overlay to a
     darker treatment so the title + tagline + date badge stay legible.
   - Section-page CTA strip styles (announcement phase only).
   - Sponsors-page announcement-phase pitch block above the existing grid.
   ============================================================================= */

/* Hide the duplicate Advance Information section in announcement phase.
   The hero already shows title + tagline + date badge + venue, so the bottom
   section is redundant (and was showing stale "Oct 23-24, Austin" data). */
body.phase-announcement .ch-advance-info-section,
body.phase-announcement section[data-section="advance-info"],
body.phase-announcement #section-advance-info {
    display: none !important;
}

/* Announcement-phase nav: hide "Apply to Speak". conference.js renderNav()
   emits data-nav-page attributes (#2728) so the CSS can target by destination. */
body.phase-announcement .conf-nav-link[data-nav-page="cfp.html"] {
    display: none;
}

/* Register nav link: hidden by default, revealed only when ticket sales are
   open. renderNav() always emits the link; the body.phase-sales_open class
   (set by conference.js on branding load AND by the per-page pre-paint
   script from sessionStorage cache) is what makes it visible. */
.conf-nav-link[data-nav-page="passes.html"] {
    display: none;
}
body.phase-sales_open .conf-nav-link[data-nav-page="passes.html"] {
    display: revert;
}

/* Hero with background image — when hero_image_url is set, conference.js adds
   body.has-hero-image. The stock .ch-hero-overlay gradient is too light for
   most photos; this swaps to a dark navy → near-black gradient so the title
   and tagline always read. Opacity tuned for real photographs (#2741) — keep
   it transparent enough that the hero image is still visibly the hero, dark
   enough that the title + tagline always read. */
body.has-hero-image .ch-hero-overlay {
    background: linear-gradient(
        180deg,
        rgba(0, 39, 76, 0.55) 0%,
        rgba(0, 39, 76, 0.65) 55%,
        rgba(38, 47, 53, 0.78) 100%
    );
}

/* When a hero image is loaded, paint it cover/center and remove the default
   linear-gradient that #2731 used as a placeholder so the photo isn't
   double-painted. */
body.has-hero-image .ch-hero-bg {
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    opacity: 1;
}

/* Section-page CTA strip (#2728) — used at the bottom of schedule.html,
   speakers.html and at the bottom of the sponsors pitch block. */
.conf-section-cta {
    margin: 56px auto 24px;
    padding: 28px 28px;
    max-width: 760px;
    background: var(--color-surface-alt, #f5f6f3);
    border: 1px solid var(--color-border, rgba(38, 47, 53, 0.1));
    border-radius: 12px;
    text-align: center;
}
.conf-section-cta__title {
    margin: 0 0 6px;
    font-family: var(--font-heading);
    font-size: 20px;
    font-weight: 700;
    color: var(--theme-text, #262f35);
}
.conf-section-cta__body {
    margin: 0 0 16px;
    font-size: 15px;
    line-height: 1.5;
    color: var(--theme-text-muted, #5a6770);
}
.conf-section-cta__btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 12px 24px;
    background: var(--color-primary, #ec0244);
    color: #fff;
    font-weight: 600;
    font-size: 15px;
    text-decoration: none;
    border-radius: 8px;
    transition: background 0.15s ease, transform 0.15s ease;
}
.conf-section-cta__btn:hover {
    background: var(--color-maroon, #7b0035);
    transform: translateY(-1px);
}

/* Sponsors-page pitch block (#2728) — announcement-phase only.
   Hidden by default; conference.js + sponsors.html template makes it visible
   when phase=announcement. */
.conf-sponsor-pitch {
    max-width: 1100px;
    margin: 0 auto 48px;
    padding: 56px 24px 32px;
}
.conf-sponsor-pitch__head {
    text-align: center;
    max-width: 720px;
    margin: 0 auto 36px;
}
.conf-sponsor-pitch__title {
    font-family: var(--font-heading);
    font-size: clamp(28px, 4vw, 40px);
    font-weight: 800;
    color: var(--theme-text, #262f35);
    margin: 0 0 12px;
    letter-spacing: -0.5px;
}
.conf-sponsor-pitch__body {
    font-size: 17px;
    line-height: 1.6;
    color: var(--theme-text-muted, #5a6770);
    margin: 0;
}
.conf-sponsor-pitch__tiers {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 16px;
    margin: 0 0 28px;
}
@media (max-width: 900px) {
    .conf-sponsor-pitch__tiers { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 520px) {
    .conf-sponsor-pitch__tiers { grid-template-columns: 1fr; }
}
.conf-sponsor-tier-card {
    background: #fff;
    border: 1px solid var(--color-border, rgba(38, 47, 53, 0.12));
    border-radius: 10px;
    padding: 20px 18px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    box-shadow: 0 1px 3px rgba(38, 47, 53, 0.04);
}
.conf-sponsor-tier-card__name {
    font-family: var(--font-heading);
    font-size: 16px;
    font-weight: 700;
    color: var(--color-primary, #ec0244);
    text-transform: uppercase;
    letter-spacing: 0.8px;
    margin: 0;
}
.conf-sponsor-tier-card__price {
    font-size: 13px;
    font-weight: 600;
    color: var(--theme-text, #262f35);
    margin: 0;
}
.conf-sponsor-tier-card__benefit {
    font-size: 13px;
    line-height: 1.5;
    color: var(--theme-text-muted, #5a6770);
    margin: 0;
}
.conf-sponsor-pitch__body-html {
    max-width: 720px;
    margin: 8px auto 0;
    font-size: 15px;
    line-height: 1.65;
    color: var(--theme-text, #262f35);
}
.conf-sponsor-pitch__body-html p { margin: 0 0 12px; }
.conf-sponsor-pitch__body-html p:last-child { margin: 0; }

/* =============================================================================
   Event RSVP panel (#5292) — event-level RSVP, distinct from the #6570
   session-level control above.
   ============================================================================= */
.conf-event-rsvp-heading {
    font-family: var(--font-heading);
    font-size: 20px;
    font-weight: 700;
    color: var(--theme-text, #262f35);
    margin: 0 0 12px;
}
.conf-event-rsvp-card {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    background: var(--color-surface, #fff);
    border: 1px solid var(--color-border, #e2e5e8);
    border-radius: 8px;
    padding: 12px 16px;
    margin-bottom: 8px;
}
.conf-event-rsvp-name { font-size: 15px; font-weight: 600; margin: 0; color: var(--theme-text, #262f35); }
.conf-event-rsvp-time, .conf-event-rsvp-venue, .conf-event-rsvp-seats {
    display: block;
    font-size: 13px;
    color: var(--theme-text-muted, #5a6770);
}
.conf-event-rsvp-action { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.conf-event-rsvp-status { font-size: 13px; font-weight: 600; }
.conf-event-rsvp-confirmed { color: #1a7a3d; }
.conf-event-rsvp-waitlisted { color: var(--color-primary, #ec0244); }

