/* =====================================================================
 * RAISE NEXT — SHARED DESIGN SYSTEM
 * =====================================================================
 * Single source of truth for the whole site. Loaded by all three
 * layouts (public, members, admin) so the admin panel and the public
 * site can never drift apart visually.
 *
 * Load order matters:  bootstrap.min.css  →  raise-next.css
 * The <html> element must carry  data-bs-theme="dark"  or  "light".
 * Every layout takes it from App\Libraries\Theme::current() (the
 * rn_theme cookie), with components/theme_auto applying the device's
 * setting until the visitor picks.
 *
 * ---------------------------------------------------------------------
 * HOW TO RE-THEME THE ENTIRE SITE
 * ---------------------------------------------------------------------
 * Everything below is driven by the custom properties in §1. Colour
 * tokens exist twice — once per theme — so a colour change usually needs
 * its light counterpart too. Never hardcode a colour in a rule: use a
 * token, or a  rgba(var(--rn-ink-rgb), α)  wash, so both themes follow.
 *
 *   --rn-bg / --rn-surface   backgrounds (page, cards)
 *   --rn-violet … --rn-teal  the brand colour ramp
 *   --rn-grad-cta            primary buttons + CTA banner gradient
 *   --rn-grad-warm           the accent word inside big headings
 *   --rn-tier-1/2/3          ticket tier accents
 *   --rn-font-heading/body   typefaces (also update the <link> in layouts)
 *   --rn-radius, --rn-section-py   shape and rhythm
 *
 * Colour values were sampled pixel-by-pixel from the client mockups in
 * req_docs/sceenshots/ — do not "tidy" them to round numbers.
 *
 * ACCESSIBILITY NOTES
 *   - .rn-grad-text is for 32px+ only. Violet on near-black is ~4.3:1,
 *     which passes for large text but NOT for body copy.
 *   - --rn-text-muted (#9AA6BF) on --rn-bg is 7.4:1 — safe anywhere.
 *   - --rn-text-dim is a deliberate deviation from the sampled mockup
 *     value #6B7690, which fails WCAG AA on the card surfaces (3.6–4.3:1).
 *     #8A96B2 holds 5.5:1+ everywhere up to --rn-surface-3. Keep any
 *     replacement at ≥4.5:1 against --rn-surface-3, the lightest surface
 *     dim text ever sits on.
 *   - --rn-border-control exists because --rn-border composites to ~1.2:1
 *     over the surfaces — fine as a decorative card edge, invisible as a
 *     form-control boundary (WCAG 1.4.11 wants ≥3:1). It holds ≥3:1 on
 *     every surface; inputs, selects, textareas and checkboxes use it.
 *   - Every animation here is inside a prefers-reduced-motion guard.
 * ===================================================================== */


/* =====================================================================
 * §1  TOKENS
 * ===================================================================== */

/* --- Colour: dark theme (the default brand look) ---
 * Colour tokens are declared on the theme attribute as well as :root so a
 * "dark island" (data-bs-theme="dark" on an element inside a light page)
 * recomputes every token locally — custom properties resolve where they are
 * declared, so the island must redeclare them all in one rule. §24 gives
 * islands their text colour. */
:root,
[data-bs-theme="dark"] {
    /* --- Base surfaces --- */
    --rn-bg: #05070F;
    --rn-bg-alt: #090C18;
    --rn-surface: #0F1322;
    --rn-surface-2: #141824;
    --rn-surface-3: #1A1F30;
    --rn-sidebar-bg: #0B0E1A;    /* members/admin sidebar (§16) */
    --rn-bg-rgb: 5, 7, 15;       /* --rn-bg as a triplet, for translucent bars */
    --rn-ink-rgb: 255, 255, 255; /* hover washes: light on dark, dark on light */
    --rn-violet-rgb: 139, 49, 232; /* --rn-violet as a triplet, for tinted washes */

    /* --- Borders --- */
    --rn-border: rgba(139, 124, 246, .14);
    --rn-border-strong: rgba(160, 140, 255, .30);
    --rn-border-plain: rgba(255, 255, 255, .08);
    /* Form-control boundaries only — ≥3:1 on every surface (see header) */
    --rn-border-control: rgba(160, 140, 255, .60);

    /* --- Text --- */
    --rn-text: #F5F6FA;
    --rn-text-muted: #9AA6BF;
    --rn-text-dim: #8A96B2; /* raised from sampled #6B7690 for AA — see header */

    /* --- Brand ramp --- */
    --rn-violet: #8B31E8;
    --rn-indigo: #4B3AE0;
    --rn-blue: #1E86DE;
    --rn-cyan: #06C4E4;
    --rn-pink: #EC3F87;
    --rn-coral: #F04E23;
    --rn-teal: #12A3B4;

    /* --- Status & small-text accents ---
     * Text-weight versions of the ramp. On dark they are lighter than the
     * fills; on light they are darker. Each holds ≥4.5:1 on every surface. */
    --rn-success: #34D399;
    --rn-warning: #F5B54A;
    --rn-danger: #FF8A6B;
    --rn-violet-text: #A78BFA;
    --rn-alert-success: #7FE3BC;
    --rn-alert-success-edge: #22C58A;
    --rn-alert-error: #FF9E82;
    --rn-alert-info: #7DE4F7;
    --rn-save: #2DD4BF;
    --rn-save-rgb: 45, 212, 191;
    --rn-selected-text: #fff; /* active segment of a segmented control */
    --rn-selection-bg: rgba(139, 49, 232, .45);
    --rn-selection-text: #fff;

    /* --- Gradients (the "fading / merging" colours) --- */
    --rn-grad-cta: linear-gradient(90deg, #8B31E8 0%, #4B3AE0 38%, #1E86DE 72%, #06C4E4 100%);
    --rn-grad-cta-hover: linear-gradient(90deg, #9B41F8 0%, #5B4AF0 38%, #2E96EE 72%, #16D4F4 100%);
    --rn-grad-warm: linear-gradient(90deg, #F04E23 0%, #EC3F87 55%, #8B31E8 100%);
    --rn-grad-cool: linear-gradient(90deg, #8B31E8 0%, #4B3AE0 45%, #06C4E4 100%);
    --rn-grad-surface: linear-gradient(160deg, rgba(139, 49, 232, .10), rgba(6, 196, 228, .04) 60%, transparent);
    --rn-grad-border: linear-gradient(135deg, rgba(139, 49, 232, .55), rgba(6, 196, 228, .35));

    /* --- Glows --- */
    --rn-glow: 0 0 60px rgba(139, 49, 232, .35);
    --rn-glow-sm: 0 0 24px rgba(139, 49, 232, .28);
    --rn-shadow-card: 0 18px 50px rgba(0, 0, 0, .55);
    /* Cast upward, for a bar floating at the foot of the screen (§10) */
    --rn-shadow-bar: 0 -12px 40px rgba(0, 0, 0, .6);

    /* --- Ticket tier accents --- */
    --rn-tier-1: #7C3AED;
    --rn-tier-2: #F04E23;
    --rn-tier-3: #0EA5B7;
    /* Tier colour as used for text (name, price, list ticks) */
    --rn-tier-1-text: #A78BFA;
    --rn-tier-2-text: #FB7A4A;
    --rn-tier-3-text: #22D3EE;
}

/* --- Colour: light theme ---
 * Same token names, re-derived for a light page rather than inverted. The
 * accents are darkened until small text holds ≥4.5:1 on --rn-surface-3 (the
 * darkest light surface); the CTA and warm gradients are unchanged because
 * white text sits on the first and the second is display-size only (≥3:1). */
[data-bs-theme="light"] {
    --rn-bg: #F5F6FB;
    --rn-bg-alt: #EDEFF7;
    --rn-surface: #FFFFFF;
    --rn-surface-2: #F3F4F9;
    --rn-surface-3: #E8EAF3;
    --rn-sidebar-bg: #FFFFFF;
    --rn-bg-rgb: 245, 246, 251;
    --rn-ink-rgb: 14, 18, 34;
    --rn-violet-rgb: 124, 43, 217;

    --rn-border: rgba(76, 58, 180, .14);
    --rn-border-strong: rgba(76, 58, 180, .30);
    --rn-border-plain: rgba(14, 18, 34, .09);
    --rn-border-control: rgba(76, 58, 180, .64);

    --rn-text: #0E1222;
    --rn-text-muted: #465068;
    --rn-text-dim: #535D76;

    --rn-violet: #7C2BD9;
    --rn-indigo: #4B3AE0;
    --rn-blue: #1663AD;
    --rn-cyan: #086F88;
    --rn-pink: #BE1858;
    --rn-coral: #B8350F;
    --rn-teal: #0B6D7A;

    --rn-success: #046C4E;
    --rn-warning: #9A4706;
    --rn-danger: #B33412;
    --rn-violet-text: #6D28D9;
    --rn-alert-success: #046C4E;
    --rn-alert-success-edge: #0F9F6E;
    --rn-alert-error: #B33412;
    --rn-alert-info: #086F88;
    --rn-save: #0C6A62;
    --rn-save-rgb: 12, 106, 98;
    --rn-selected-text: #5B1FB0;
    --rn-selection-bg: rgba(124, 43, 217, .20);
    --rn-selection-text: #0E1222;

    --rn-grad-cool: linear-gradient(90deg, #7C2BD9 0%, #4B3AE0 45%, #0891B2 100%);
    --rn-grad-surface: linear-gradient(160deg, rgba(139, 49, 232, .06), rgba(6, 196, 228, .03) 60%, transparent);

    --rn-glow: 0 0 60px rgba(139, 49, 232, .18);
    --rn-glow-sm: 0 0 24px rgba(139, 49, 232, .14);
    --rn-shadow-card: 0 18px 50px rgba(30, 27, 75, .12);
    --rn-shadow-bar: 0 -10px 36px rgba(30, 27, 75, .16);

    --rn-tier-1: #6D28D9;
    --rn-tier-2: #B03A0A;
    --rn-tier-3: #0B6A83;
    --rn-tier-1-text: #6D28D9;
    --rn-tier-2-text: #B03A0A;
    --rn-tier-3-text: #0B6A83;
}

/* --- Type, shape, motion (theme-independent) --- */
:root {
    --rn-font-heading: 'Space Grotesk', system-ui, -apple-system, sans-serif;
    --rn-font-body: 'Inter', system-ui, -apple-system, sans-serif;

    --rn-fs-display: clamp(2.5rem, 6.5vw, 4.5rem);
    --rn-fs-h1: clamp(2rem, 5vw, 3.5rem);
    --rn-fs-h2: clamp(1.75rem, 3.5vw, 2.5rem);
    --rn-fs-h3: clamp(1.25rem, 2vw, 1.5rem);
    --rn-fs-body: clamp(1rem, 1.15vw, 1.125rem);
    --rn-fs-sm: .875rem;
    --rn-fs-eyebrow: .75rem;

    /* --- Shape & rhythm --- */
    --rn-radius-sm: 8px;
    --rn-radius: 14px;
    --rn-radius-lg: 20px;
    --rn-radius-pill: 999px;
    --rn-section-py: clamp(3.5rem, 8vw, 7rem);
    --rn-header-h: 68px;

    --rn-ease: cubic-bezier(.22, .61, .36, 1);
    --rn-dur: 220ms;
}

/* Bootstrap 5.3 theme variable mapping — makes native Bootstrap components
 * (offcanvas, accordion, dropdown, form controls, tables) inherit the Raise
 * Next palette without per-component overrides. Same specificity as
 * Bootstrap's own theme rules; this file loads later, so it wins. */
[data-bs-theme="dark"],
[data-bs-theme="light"] {
    --bs-body-bg: var(--rn-bg);
    --bs-body-color: var(--rn-text);
    --bs-body-font-family: var(--rn-font-body);
    --bs-secondary-color: var(--rn-text-muted);
    --bs-tertiary-color: var(--rn-text-dim);
    --bs-border-color: var(--rn-border);
    --bs-border-color-translucent: var(--rn-border);
    --bs-primary: var(--rn-violet);
    --bs-link-color: var(--rn-cyan);
    --bs-code-color: var(--rn-pink);
    --bs-heading-color: var(--rn-text);
}

[data-bs-theme="dark"] {
    --bs-emphasis-color: #fff;
    --bs-primary-rgb: 139, 49, 232;
    --bs-link-color-rgb: 6, 196, 228;
    --bs-link-hover-color: #58DEF5;
}

[data-bs-theme="light"] {
    --bs-emphasis-color: var(--rn-text);
    --bs-primary-rgb: 124, 43, 217;
    --bs-link-color-rgb: 8, 111, 136;
    --bs-link-hover-color: #065A6F;
    --bs-link-hover-color-rgb: 6, 90, 111;
}


/* =====================================================================
 * §2  BASE
 * ===================================================================== */
html {
    scroll-behavior: smooth;
    /* Fixed header offset for anchor links */
    scroll-padding-top: calc(var(--rn-header-h) + 16px);
}

body {
    background: var(--rn-bg);
    color: var(--rn-text);
    font-family: var(--rn-font-body);
    font-size: var(--rn-fs-body);
    line-height: 1.65;
    -webkit-font-smoothing: antialiased;
    /* Never allow a stray wide element to scroll the page sideways */
    overflow-x: hidden;
}

h1, h2, h3, h4, h5, h6, .rn-display {
    font-family: var(--rn-font-heading);
    font-weight: 700;
    line-height: 1.08;
    letter-spacing: -.03em;
    color: var(--rn-text);
}

.rn-display { font-size: var(--rn-fs-display); }
h1, .rn-h1 { font-size: var(--rn-fs-h1); }
h2, .rn-h2 { font-size: var(--rn-fs-h2); }
h3, .rn-h3 { font-size: var(--rn-fs-h3); letter-spacing: -.02em; }

p { color: var(--rn-text-muted); }
.rn-lead { font-size: clamp(1.0625rem, 1.6vw, 1.25rem); color: var(--rn-text-muted); max-width: 56ch; }
.rn-muted { color: var(--rn-text-muted); }
.rn-dim { color: var(--rn-text-dim); }

a { text-decoration: none; transition: color var(--rn-dur) var(--rn-ease); }

/* Visible focus for keyboard users on every interactive element */
:focus-visible {
    outline: 2px solid var(--rn-cyan);
    outline-offset: 3px;
    border-radius: 4px;
}

::selection { background: var(--rn-selection-bg); color: var(--rn-selection-text); }

/* Skip link — first focusable element in every layout */
.rn-skip-link {
    position: absolute;
    top: 0; left: 50%;
    transform: translate(-50%, -120%);
    z-index: 2000;
    padding: .75rem 1.25rem;
    background: var(--rn-violet);
    color: #fff;
    border-radius: 0 0 var(--rn-radius-sm) var(--rn-radius-sm);
    transition: transform var(--rn-dur) var(--rn-ease);
}
.rn-skip-link:focus { transform: translate(-50%, 0); color: #fff; }


/* =====================================================================
 * §3  GRADIENT TEXT & EYEBROWS
 * ===================================================================== */

/* Large headings only — see accessibility note at the top of this file.
 *
 * ALWAYS set the gradient with background-image here, NEVER the `background`
 * shorthand. The shorthand resets background-clip to border-box, so the
 * gradient paints as a solid rectangle over transparent text instead of
 * filling the glyphs. Same applies to every modifier below. */
.rn-grad-text {
    color: var(--rn-violet);              /* solid fallback */
    background-image: var(--rn-grad-warm);
    -webkit-background-clip: text;
    background-clip: text;
}
@supports (-webkit-background-clip: text) or (background-clip: text) {
    .rn-grad-text { color: transparent; }
}
.rn-grad-text--cool { background-image: var(--rn-grad-cool); }
.rn-grad-text--cta { background-image: var(--rn-grad-cta); }

.rn-eyebrow {
    display: inline-block;
    font-family: var(--rn-font-body);
    font-size: var(--rn-fs-eyebrow);
    font-weight: 600;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--rn-violet);
    margin-bottom: .875rem;
}
.rn-eyebrow--cyan { color: var(--rn-cyan); }
.rn-eyebrow--muted { color: var(--rn-text-dim); }

/* Pill badge, e.g. "CANADA'S PREMIER STARTUP CAPITAL SUMMIT" */
.rn-pill {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    padding: .4375rem .875rem;
    font-size: var(--rn-fs-eyebrow);
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--rn-text);
    background: rgba(139, 49, 232, .10);
    border: 1px solid var(--rn-border-strong);
    border-radius: var(--rn-radius-pill);
}
.rn-pill .rn-pill-dot {
    width: 7px; height: 7px;
    border-radius: 50%;
    background: var(--rn-cyan);
    box-shadow: 0 0 10px var(--rn-cyan);
    flex: 0 0 auto;
}


/* =====================================================================
 * §4  SECTIONS & LAYOUT
 * ===================================================================== */
.rn-section { padding: var(--rn-section-py) 0; position: relative; }
.rn-section--alt { background: var(--rn-bg-alt); }
.rn-section--tight { padding: clamp(2rem, 5vw, 4rem) 0; }

/* Full-width page layout.
 * The client's mockup runs content to ~85% of the canvas, so a fixed centred
 * column left large margins on anything wider than ~1440px. This drops the
 * cap entirely: content spans the viewport minus a gutter that grows with it.
 *
 * Written as .container.rn-container (specificity 0,2,0) so it beats
 * Bootstrap's per-breakpoint .container max-widths without !important.
 *
 * To go back to a centred column, set a max-width here — that single
 * declaration is the whole switch. */
.container.rn-container {
    max-width: none;
    width: 100%;
    padding-inline: clamp(1.25rem, 3.5vw, 4.5rem);
}

/* Edge-to-edge means prose columns can get extremely wide on large monitors
 * — a paragraph at 2560px would run ~200 characters against a readable range
 * of 65–75. Anything carrying flowing body copy gets .rn-measure, which caps
 * the line length without narrowing the layout around it. */
.rn-measure { max-width: 68ch; }

.rn-section-head { max-width: 42rem; margin-bottom: clamp(2rem, 4vw, 3.5rem); }
.rn-section-head--center { margin-inline: auto; text-align: center; }

/* Thin gradient rule used under headings in the mockups */
.rn-rule {
    width: 56px; height: 3px;
    background: var(--rn-grad-cta);
    border-radius: 2px;
    margin: 1rem 0 1.5rem;
}
.rn-section-head--center .rn-rule { margin-inline: auto; }

/* Decorative background motifs (generated PNGs) */
.rn-motif {
    position: absolute;
    pointer-events: none;
    user-select: none;
    z-index: 0;
}
.rn-motif--blocks { top: 0; left: 0; width: min(320px, 30vw); opacity: .35; }
.rn-motif--mesh { right: 0; bottom: 0; width: min(460px, 45vw); opacity: .5; }
.rn-motif--waves { left: 0; bottom: 0; width: 100%; opacity: .5; }
@media (max-width: 767.98px) {
    /* Motifs are decoration — drop them on phones to save bandwidth
     * and keep text areas clean */
    .rn-motif { display: none; }
}


/* =====================================================================
 * §5  BUTTONS
 * ===================================================================== */
.rn-btn {
    --rn-btn-bg: transparent;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .625rem;
    min-height: 48px;                     /* touch target */
    padding: .75rem 1.5rem;
    font-family: var(--rn-font-body);
    font-size: .9375rem;
    font-weight: 600;
    letter-spacing: .01em;
    line-height: 1.2;
    color: var(--rn-text);
    background: var(--rn-btn-bg);
    border: 1px solid transparent;
    border-radius: var(--rn-radius-sm);
    cursor: pointer;
    text-align: center;
    transition: transform var(--rn-dur) var(--rn-ease),
                box-shadow var(--rn-dur) var(--rn-ease),
                background-color var(--rn-dur) var(--rn-ease),
                border-color var(--rn-dur) var(--rn-ease),
                opacity var(--rn-dur) var(--rn-ease);
}
.rn-btn:hover { color: var(--rn-text); }
.rn-btn:active { transform: translateY(1px); }
.rn-btn:disabled,
.rn-btn.disabled { opacity: .45; pointer-events: none; }

/* Primary — the brand gradient. Two stacked layers so the hover ramp
 * cross-fades instead of snapping (gradients aren't interpolatable). */
.rn-btn--primary {
    position: relative;
    background: var(--rn-grad-cta);
    color: #fff;
    box-shadow: 0 6px 24px rgba(75, 58, 224, .35);
    overflow: hidden;
    isolation: isolate;
}
.rn-btn--primary::before {
    content: '';
    position: absolute;
    inset: 0;
    background: var(--rn-grad-cta-hover);
    opacity: 0;
    transition: opacity var(--rn-dur) var(--rn-ease);
    z-index: -1;
}
.rn-btn--primary:hover { color: #fff; box-shadow: 0 10px 34px rgba(75, 58, 224, .5); }
.rn-btn--primary:hover::before { opacity: 1; }

/* Outline — the "BUY TICKETS" style from the mockups */
.rn-btn--outline {
    background: transparent;
    border-color: var(--rn-border-strong);
    color: var(--rn-text);
}
.rn-btn--outline:hover {
    border-color: var(--rn-cyan);
    background: rgba(6, 196, 228, .08);
}

.rn-btn--ghost { background: transparent; color: var(--rn-text-muted); }
.rn-btn--ghost:hover { color: var(--rn-text); background: rgba(var(--rn-ink-rgb), .05); }

.rn-btn--sm { min-height: 40px; padding: .5rem 1rem; font-size: .8125rem; }
.rn-btn--lg { min-height: 56px; padding: 1rem 2rem; font-size: 1rem; }
.rn-btn--block { width: 100%; }

/* Gradient hairline around a transparent pill — "BECOME A PARTNER" in the
 * partners mockup. The ring is a masked layer, so whatever sits behind the
 * button (glows included) shows through it. Declared after the size
 * modifiers so its own type and padding win over .rn-btn--lg. */
.rn-btn--grad-outline {
    position: relative;
    padding-inline: 2.25rem;
    border-radius: var(--rn-radius-pill);
    font-size: .8125rem;
    letter-spacing: .2em;
    text-transform: uppercase;
}
.rn-btn--grad-outline::before {
    content: '';
    position: absolute;
    inset: 0;
    padding: 1.5px;
    border-radius: inherit;
    background: var(--rn-grad-cta);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    pointer-events: none;
}
.rn-btn--grad-outline:hover { background: rgba(var(--rn-ink-rgb), .05); box-shadow: var(--rn-glow-sm); }
@media (max-width: 575.98px) {
    .rn-btn--grad-outline { padding-inline: 1.5rem; letter-spacing: .12em; }
}

/* Tier-accented buttons on the tickets page */
.rn-btn--tier { color: #fff; }
.rn-btn--tier-1 { background: linear-gradient(90deg, #6D28D9, #8B5CF6); }
.rn-btn--tier-2 { background: linear-gradient(90deg, #DC3B18, #F4703E); }
.rn-btn--tier-3 { background: linear-gradient(90deg, #087E93, #14B8CC); }
.rn-btn--tier:hover { color: #fff; filter: brightness(1.12); }

/* Trailing arrow that nudges on hover */
.rn-btn .rn-btn-arrow { transition: transform var(--rn-dur) var(--rn-ease); }
.rn-btn:hover .rn-btn-arrow { transform: translateX(3px); }


/* =====================================================================
 * §6  CARDS
 * ===================================================================== */
.rn-card {
    position: relative;
    background: var(--rn-surface);
    background-image: var(--rn-grad-surface);
    border: 1px solid var(--rn-border);
    border-radius: var(--rn-radius-lg);
    padding: clamp(1.5rem, 3vw, 2.25rem);
    /* NO height: 100% here. It used to be the default, which broke any column
     * holding more than one card: the first card claimed the full column
     * height and pushed its siblings out of the row and over the footer.
     * Cards that want to match a neighbour's height say so with Bootstrap's
     * .h-100 utility — see the ticket tiers below, which set it themselves. */
    transition: transform var(--rn-dur) var(--rn-ease),
                border-color var(--rn-dur) var(--rn-ease),
                box-shadow var(--rn-dur) var(--rn-ease);
}
.rn-card--hover:hover {
    transform: translateY(-4px);
    border-color: var(--rn-border-strong);
    box-shadow: var(--rn-shadow-card);
}
.rn-card--flat { background-image: none; }
.rn-card--plain { background: var(--rn-surface-2); border-color: var(--rn-border-plain); }

/* Photo sitting beside copy inside a card (About section).
 * Stretches to the height of the text column on wide screens; falls back to
 * a fixed 4:3 block once the card stacks. */
/* <picture> wrapper needs to fill the flex column so the image inside can */
.rn-about-figure { display: block; width: 100%; }
.rn-about-media {
    width: 100%;
    height: 100%;
    min-height: 260px;
    object-fit: cover;
    border-radius: var(--rn-radius);
    /* Visible while the photo loads, and if it is missing entirely */
    background: linear-gradient(135deg, #1A0B2E, #05070F 55%, #052538);
}
@media (max-width: 991.98px) {
    .rn-about-media { height: auto; aspect-ratio: 4 / 3; }
}

/* Pillar row — centred, separated by hairlines, as in the mockup */
.rn-pillars {
    margin-top: clamp(1.75rem, 4vw, 2.75rem);
    padding-top: clamp(1.75rem, 4vw, 2.75rem);
    border-top: 1px solid var(--rn-border);
}
.rn-pillar { position: relative; text-align: center; }
/* Divider sits on the column's padding edge, i.e. the middle of the gutter.
 * Only between items, and only once they are side by side. */
@media (min-width: 768px) {
    .rn-pillar + .rn-pillar::before {
        content: '';
        position: absolute;
        left: 0;
        top: 8%;
        bottom: 8%;
        width: 1px;
        background: var(--rn-border);
    }
}
.rn-pillar-icon {
    display: block;
    font-size: 1.875rem;
    line-height: 1;
    margin-bottom: .875rem;
}
.rn-pillar-title {
    font-family: var(--rn-font-body);
    font-size: .8125rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    margin-bottom: .375rem;
}
.rn-pillar-desc {
    font-size: .8125rem;
    line-height: 1.5;
    color: var(--rn-text-dim);
    margin: 0;
    /* Keeps the four descriptions from running edge to edge on wide cards */
    max-width: 22ch;
    margin-inline: auto;
}

/* =====================================================================
 * Feature row — a set of icon/title/description items separated by
 * hairlines, as in the accelerator's "What you get" band.
 *
 * A CSS grid rather than Bootstrap columns so the dividers can be handled
 * with nth-child: the border sits on every item's left edge and is removed
 * for whichever item starts a row at each breakpoint. Set --rn-cols to the
 * wide-screen column count.
 * ===================================================================== */
.rn-featurerow {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.75rem 0;
}
.rn-feature { text-align: center; padding: 0 1rem; border-left: 1px solid var(--rn-border); }
.rn-feature:nth-child(2n + 1) { border-left: 0; }

@media (min-width: 768px) {
    .rn-featurerow { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .rn-feature:nth-child(2n + 1) { border-left: 1px solid var(--rn-border); }
    .rn-feature:nth-child(3n + 1) { border-left: 0; }
}
/* nth-child() cannot take a custom property, so the wide layout is a fixed
 * 6 columns — the count the design uses. A different count needs its own
 * modifier with matching nth-child rules. */
@media (min-width: 1200px) {
    .rn-featurerow { grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 0; }
    .rn-feature:nth-child(3n + 1) { border-left: 1px solid var(--rn-border); }
    .rn-feature:nth-child(6n + 1) { border-left: 0; }
}
.rn-feature-icon { display: block; font-size: 1.75rem; line-height: 1; margin-bottom: .875rem; }
.rn-feature-title {
    font-family: var(--rn-font-body);
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    margin-bottom: .5rem;
}
.rn-feature-desc { font-size: .8125rem; line-height: 1.55; color: var(--rn-text-dim); margin: 0; }

/* Icon-left list — "Who should apply" */
.rn-icon-list { list-style: none; padding: 0; margin: 0; }
.rn-icon-list > li { display: flex; gap: 1rem; }
.rn-icon-list > li + li { margin-top: 1.5rem; }
.rn-icon-list i { flex: 0 0 auto; font-size: 1.375rem; line-height: 1.4; }
.rn-icon-list-title {
    font-size: .8125rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    margin-bottom: .25rem;
}
.rn-icon-list-desc { font-size: .875rem; color: var(--rn-text-muted); margin: 0; }

/* Vertical KPI stack — the accelerator's numbers column */
.rn-kpi { list-style: none; padding: 0; margin: 0; }
.rn-kpi > li + li { margin-top: 1.25rem; padding-top: 1.25rem; border-top: 1px solid var(--rn-border); }
.rn-kpi-value {
    font-family: var(--rn-font-heading);
    font-size: clamp(1.75rem, 3vw, 2.25rem);
    font-weight: 700;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}
.rn-kpi-label {
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--rn-text-dim);
    margin: .375rem 0 0;
}

/* Program journey — numbered steps, horizontal from md, stacked below */
.rn-journey { display: grid; grid-template-columns: 1fr; gap: 1.75rem; }
@media (min-width: 768px) {
    .rn-journey { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 1rem; }
}
.rn-journey-step { position: relative; text-align: center; }
/* Connector arrow, centred in the 1rem grid gap */
@media (min-width: 768px) {
    .rn-journey-step + .rn-journey-step::before {
        content: '→';
        position: absolute;
        left: -.5rem;
        top: 1.5rem;
        transform: translateX(-50%);
        color: var(--rn-text-dim);
        font-size: 1rem;
        line-height: 1;
    }
}
.rn-journey-icon {
    width: 56px; height: 56px;
    margin: 0 auto 1rem;
    display: flex; align-items: center; justify-content: center;
    font-size: 1.25rem;
    border: 1px solid var(--rn-border-strong);
    border-radius: 50%;
}
.rn-journey-title {
    font-size: .8125rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    margin-bottom: .375rem;
}
.rn-journey-desc { font-size: .8125rem; line-height: 1.5; color: var(--rn-text-dim); margin: 0; }

/* Speaker card — photo, name, role, opens a bio modal */
.rn-speaker {
    display: block;
    width: 100%;
    text-align: left;
    padding: 0;
    background: none;
    border: 0;
    color: inherit;
    cursor: pointer;
}
.rn-speaker-photo {
    position: relative;
    width: 100%;
    aspect-ratio: 4 / 5;
    overflow: hidden;
    border-radius: var(--rn-radius);
    background: var(--rn-surface-2);
    margin-bottom: .875rem;
}
.rn-speaker-photo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 400ms var(--rn-ease);
}
.rn-speaker:hover .rn-speaker-photo img,
.rn-speaker:focus-visible .rn-speaker-photo img { transform: scale(1.04); }
/* Gradient veil so white type stays readable over any portrait */
.rn-speaker-photo::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, transparent 55%, rgba(5, 7, 15, .75) 100%);
}
.rn-speaker-name { font-family: var(--rn-font-heading); font-size: 1.0625rem; margin-bottom: .1875rem; }
.rn-speaker-role { font-size: .8125rem; color: var(--rn-text-dim); margin: 0; }

/* News card — cover, date, title, excerpt */
.rn-post { display: flex; flex-direction: column; height: 100%; color: inherit; }
.rn-post-cover {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    border-radius: var(--rn-radius);
    background: var(--rn-surface-2);
    margin-bottom: 1rem;
    transition: transform 400ms var(--rn-ease);
}
.rn-post:hover .rn-post-cover,
.rn-post:focus-visible .rn-post-cover { transform: translateY(-3px); }
.rn-post-date {
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--rn-text-dim);
    margin-bottom: .5rem;
}
.rn-post-title { font-size: 1.125rem; line-height: 1.3; margin-bottom: .5rem; }
.rn-post:hover .rn-post-title { color: var(--rn-cyan); }
.rn-post-excerpt { font-size: .9375rem; color: var(--rn-text-muted); margin: 0; }

/* Article body — plain text rendered as paragraphs */
.rn-article-body > p {
    font-size: clamp(1rem, 1.2vw, 1.0625rem);
    line-height: 1.75;
    color: var(--rn-text-muted);
    max-width: 68ch;
}
.rn-article-body > p + p { margin-top: 1.25rem; }
.rn-article-body a { color: var(--rn-cyan); text-decoration: underline; text-underline-offset: 2px; }

/* Inline "change attendee" form inside the tickets table */
.rn-holder-row > td { border-top: 0 !important; }
.rn-holder-form {
    padding: 1rem 1rem 1.25rem;
    background: color-mix(in srgb, var(--rn-surface) 70%, transparent);
    border-radius: var(--rn-radius-sm, .5rem);
}

/* Notify-the-applicant block, set apart because ticking it emails a founder */
.rn-notify-block {
    margin-top: 1rem;
    padding: 1rem;
    border: 1px solid var(--rn-border);
    border-radius: var(--rn-radius-sm);
    background: color-mix(in srgb, var(--rn-surface) 60%, transparent);
}

/* Admission code with its QR */
.rn-ticket-code { display: flex; align-items: center; gap: .75rem; }
.rn-qr {
    display: block;
    width: 72px;
    height: 72px;
    border-radius: 6px;
    /* The PNG is black-on-white; keep it that way so scanners cope, even
       though the surrounding panel is dark. */
    background: #fff;
    padding: 2px;
    flex: none;
}

/* --- Tap-to-enlarge QR (components/qr_modal) ---
 * The thumbnail (.rn-qr here, .rn-mcard-qr on the card) is the button;
 * its white tile stays on the button and the PNG fills it. The badge is
 * the only cue a phone gets — there is no hover on a touch screen. */
.rn-qr-zoom {
    position: relative;
    border: 0;
    color: inherit;
    cursor: zoom-in;
}
.rn-qr-zoom img { display: block; width: 100%; height: auto; }
.rn-qr-zoom-badge {
    position: absolute;
    right: -6px;
    bottom: -6px;
    display: grid;
    place-items: center;
    width: 22px;
    height: 22px;
    font-size: .6875rem;
    color: #fff;
    background: var(--rn-violet);
    border-radius: 50%;
    box-shadow: 0 0 0 2px var(--rn-surface);
}

.modal.rn-qr-modal {
    --bs-modal-bg: var(--rn-surface);
    --bs-modal-border-color: var(--rn-border);
    --bs-modal-border-radius: var(--rn-radius-lg);
}
/* Full-screen on a phone: keep the QR mid-screen rather than under the title */
.rn-qr-modal .modal-body { display: flex; flex-direction: column; justify-content: center; }
.rn-qr-large {
    /* 60vh caps it on a phone turned sideways; 440px on a desktop */
    width: min(100%, 60vh, 440px);
    margin: 0 auto 1.25rem;
    padding: .75rem;
    line-height: 0;
    /* Scanners want dark-on-light; the white tile is extra quiet zone */
    background: #fff;
    border-radius: var(--rn-radius);
}
.rn-qr-large img {
    width: 100%;
    height: auto;
    /* The PNG is 320px and shown larger: hard module edges, not a blur */
    image-rendering: pixelated;
}
.rn-qr-large-code {
    margin-bottom: .25rem;
    font-family: var(--rn-font-heading);
    font-size: clamp(1.25rem, 6vw, 1.625rem);
    font-weight: 600;
    letter-spacing: .12em;
    font-variant-numeric: tabular-nums;
    color: var(--rn-text);
}

/* Door check-in verdict card — colour carries the answer at arm's length,
   but the wording says it too (never colour alone). */
.rn-checkin-result { border-left: 4px solid var(--rn-border); }
.rn-checkin-result--ok   { border-left-color: var(--rn-success); }
.rn-checkin-result--warn { border-left-color: var(--rn-warning); }
.rn-checkin-result--bad  { border-left-color: var(--rn-danger); }
.rn-checkin-verdict { font-size: 1.0625rem; margin-bottom: 1rem; }
.rn-checkin-result--warn .rn-checkin-verdict { color: var(--rn-warning); }
.rn-checkin-result--bad .rn-checkin-verdict  { color: var(--rn-danger); }

/* Off-site link marker */
.rn-link-out { font-size: .75em; margin-left: .3em; opacity: .7; vertical-align: baseline; }

/* Policy document (a GetTerms export, rendered in place) — plain h2/h3/h4,
   p, ul/ol and strong, with no classes of its own, so everything is styled
   from the wrapper. */
.rn-legal-doc { max-width: 72ch; color: var(--rn-text-muted); line-height: 1.75; }
.rn-legal-doc h2 {
    font-size: clamp(1.375rem, 2.2vw, 1.75rem);
    color: var(--rn-text);
    margin: 2.75rem 0 1rem;
}
.rn-legal-doc h3 { font-size: 1.1875rem; color: var(--rn-text); margin: 2rem 0 .75rem; }
.rn-legal-doc h4 { font-size: 1rem; color: var(--rn-text); margin: 1.5rem 0 .5rem; }
.rn-legal-doc > :first-child { margin-top: 0; }
.rn-legal-doc p, .rn-legal-doc ul, .rn-legal-doc ol { margin-bottom: 1rem; }
.rn-legal-doc li + li { margin-top: .375rem; }
.rn-legal-doc strong { color: var(--rn-text); }
.rn-legal-doc a { color: var(--rn-cyan); text-decoration: underline; text-underline-offset: 2px; overflow-wrap: anywhere; }
.rn-legal-questions { margin-top: clamp(2.5rem, 5vw, 4rem); }

/* Its table of contents: sticky beside the text, scrolling on its own when
   a long policy has more sections than the viewport holds. */
.rn-legal-toc {
    position: sticky;
    top: calc(var(--rn-header-h) + 1.5rem);
    max-height: calc(100vh - var(--rn-header-h) - 3rem);
    overflow-y: auto;
    padding-left: 1.25rem;
    border-left: 1px solid var(--rn-border);
}
.rn-legal-toc ol { list-style: none; padding: 0; margin: 0; font-size: var(--rn-fs-sm); }
.rn-legal-toc li + li { margin-top: .5rem; }
.rn-legal-toc a { color: var(--rn-text-muted); text-decoration: none; }
.rn-legal-toc a:hover { color: var(--rn-cyan); }

/* Simple prev/next pager */
.rn-pager { display: flex; align-items: center; justify-content: center; gap: 1rem; }
.rn-pager-status { font-size: .875rem; color: var(--rn-text-dim); font-variant-numeric: tabular-nums; }

/* Partner wall (About page), after the client's partners mockup: one tier
 * per row, bare logos split by hairlines, under corner glows.
 *
 * The view marks it data-bs-theme="dark" in both themes. Partners send
 * logos made for a dark background (white type on transparency) that would
 * vanish on the light page; §24 gives it a softer lift there. */
.rn-partners {
    position: relative;
    overflow: hidden;
    isolation: isolate;
    padding: clamp(2.5rem, 5vw, 4.5rem) clamp(1.25rem, 4vw, 4rem);
    background:
        radial-gradient(ellipse 45% 60% at 0% 0%, color-mix(in srgb, var(--rn-violet) 24%, transparent), transparent 70%),
        radial-gradient(ellipse 45% 60% at 100% 100%, color-mix(in srgb, var(--rn-indigo) 22%, transparent), transparent 70%),
        var(--rn-bg);
    border: 1px solid var(--rn-border);
    border-radius: var(--rn-radius-lg);
}
/* Fine concentric arcs fading out of two corners, standing in for the
 * mockup's wave lines */
.rn-partners::before,
.rn-partners::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
}
.rn-partners::before {
    background: repeating-radial-gradient(circle at 105% -40%,
        transparent 0 17px, color-mix(in srgb, var(--rn-violet) 30%, transparent) 17px 18px);
    -webkit-mask-image: radial-gradient(ellipse 38% 55% at 100% 0%, #000 10%, transparent 75%);
    mask-image: radial-gradient(ellipse 38% 55% at 100% 0%, #000 10%, transparent 75%);
}
.rn-partners::after {
    background: repeating-radial-gradient(circle at -5% 140%,
        transparent 0 17px, color-mix(in srgb, var(--rn-blue) 26%, transparent) 17px 18px);
    -webkit-mask-image: radial-gradient(ellipse 34% 45% at 0% 100%, #000 10%, transparent 75%);
    mask-image: radial-gradient(ellipse 34% 45% at 0% 100%, #000 10%, transparent 75%);
}

.rn-partners-head {
    max-width: 60rem;
    margin: 0 auto clamp(2.5rem, 5vw, 4rem);
    text-align: center;
}
/* Wide tracking, with the trailing letter-space offset so it stays centred */
.rn-partners-eyebrow { letter-spacing: .4em; padding-left: .4em; margin-bottom: 0; }
.rn-partners-head .rn-rule { width: 64px; height: 2px; margin: .75rem auto 1.5rem; }
.rn-partners-head .rn-lead { max-width: 64ch; }

.rn-partner-tier + .rn-partner-tier { margin-top: clamp(1.75rem, 3vw, 2.5rem); }
.rn-partner-tier-label {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    margin: 0 0 .75rem;
    font-family: var(--rn-font-body);
    font-size: var(--rn-fs-eyebrow);
    font-weight: 600;
    line-height: 1.4;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--rn-violet-text);
}
.rn-partner-tier-label::after {
    content: '';
    flex: 1 1 0;
    min-width: 2rem;
    height: 1px;
    background: linear-gradient(90deg,
        color-mix(in srgb, var(--rn-violet) 70%, transparent),
        color-mix(in srgb, var(--rn-blue) 50%, transparent) 60%,
        color-mix(in srgb, var(--rn-cyan) 15%, transparent));
}

/* Logos share each line equally. Every item carries a hairline on its left
 * and is pulled 1px left, so the overflow clip hides the hairline of
 * whichever logo starts a line — at any wrap point, with no JS. */
.rn-partner-row {
    --rn-partner-basis: 9rem;
    --rn-partner-h: 96px;
    --rn-partner-logo-h: 52px;
    display: flex;
    flex-wrap: wrap;
    row-gap: .5rem;
    margin: 0;
    padding: 0;
    list-style: none;
    overflow: hidden;
}
.rn-partner-row--headline {
    --rn-partner-basis: 12rem;
    --rn-partner-h: 140px;
    --rn-partner-logo-h: clamp(64px, 6vw, 96px);
}
.rn-partner-row > li {
    position: relative;
    display: flex;
    flex: 1 1 var(--rn-partner-basis);
    min-width: 0;
    margin-left: -1px;
}
.rn-partner-row > li::before {
    content: '';
    position: absolute;
    top: 20%;
    bottom: 20%;
    left: 0;
    width: 1px;
    background: rgba(var(--rn-ink-rgb), .14);
}
@media (max-width: 575.98px) {
    /* Two logos a line on phones, headline tier included */
    .rn-partner-row { --rn-partner-basis: 7.5rem; --rn-partner-h: 84px; --rn-partner-logo-h: 44px; }
    .rn-partner-row--headline { --rn-partner-h: 112px; --rn-partner-logo-h: 64px; }
}

/* One logo — or the organisation's name when none is uploaded */
.rn-partner {
    display: flex;
    flex: 1;
    align-items: center;
    justify-content: center;
    min-width: 0;
    min-height: var(--rn-partner-h);
    padding: .75rem clamp(.75rem, 2vw, 1.75rem);
    border-radius: var(--rn-radius);
    color: var(--rn-text-muted);
    font-family: var(--rn-font-heading);
    font-size: 1.0625rem;
    font-weight: 700;
    line-height: 1.25;
    text-align: center;
    overflow-wrap: anywhere;
    transition: color var(--rn-dur) var(--rn-ease), background-color var(--rn-dur) var(--rn-ease);
}
.rn-partner img {
    max-width: 100%;
    max-height: var(--rn-partner-logo-h);
    object-fit: contain;
    border-radius: 6px; /* softens logos supplied as boxed JPEGs */
    transition: transform var(--rn-dur) var(--rn-ease);
}
a.rn-partner:hover { color: var(--rn-text); background: rgba(var(--rn-ink-rgb), .04); }
a.rn-partner:focus-visible { outline-offset: -3px; } /* the row clips anything outside */
@media (prefers-reduced-motion: no-preference) {
    a.rn-partner:hover img { transform: scale(1.04); }
}

.rn-partners-foot {
    display: flex;
    justify-content: flex-end;
    margin-top: clamp(2rem, 4vw, 3rem);
}
@media (max-width: 767.98px) {
    .rn-partners-foot { justify-content: center; }
}

/* Agenda row — time on the left, session on the right */
.rn-agenda { list-style: none; padding: 0; margin: 0; }
.rn-agenda > li { padding: 1.25rem 0; border-top: 1px solid var(--rn-border); }
.rn-agenda > li:first-child { border-top: 0; padding-top: 0; }
.rn-agenda-time {
    font-family: var(--rn-font-heading);
    font-size: .875rem;
    font-variant-numeric: tabular-nums;
    color: var(--rn-cyan);
    white-space: nowrap;
}
.rn-agenda-title { font-size: 1.0625rem; margin-bottom: .375rem; }
.rn-agenda-desc { font-size: .875rem; color: var(--rn-text-muted); margin: 0 0 .5rem; }
.rn-agenda-meta { display: flex; flex-wrap: wrap; gap: .5rem 1rem; font-size: .75rem; color: var(--rn-text-dim); }
/* Breaks are structural, not programming — visually quieter */
.rn-agenda > li.is-break .rn-agenda-title { font-size: .9375rem; color: var(--rn-text-muted); font-weight: 500; }
.rn-agenda > li.is-break .rn-agenda-time { color: var(--rn-text-dim); }
/* The members toggle redirects to #session-{id}; keep the anchor clear of the
   fixed panel top bar (fallback covers the public page, outside that scope). */
.rn-agenda > li { scroll-margin-top: calc(var(--rn-topnav-h, 60px) + 1rem); }

/* Favorite star on the members schedule (amber matches .rn-chip--pending) */
.rn-fav {
    padding: .375rem;
    font-size: 1.125rem;
    line-height: 1;
    color: var(--rn-text-dim);
    background: transparent;
    border: 0;
    border-radius: 50%;
    transition: color var(--rn-dur) var(--rn-ease);
}
.rn-fav:hover { color: var(--rn-cyan); }
.rn-fav.is-active { color: var(--rn-warning); }

/* Day switcher on the event page */
.rn-daytabs { display: inline-flex; gap: .25rem; padding: .25rem; background: var(--rn-surface-2); border: 1px solid var(--rn-border); border-radius: var(--rn-radius-pill); }
.rn-daytabs button {
    min-height: 40px;
    padding: .5rem 1.25rem;
    font-size: .875rem;
    font-weight: 600;
    color: var(--rn-text-muted);
    background: transparent;
    border: 0;
    border-radius: var(--rn-radius-pill);
    transition: all var(--rn-dur) var(--rn-ease);
}
.rn-daytabs button.active { color: #fff; background: var(--rn-grad-cta); }

/* "Powered by" badge floating over a hero photo */
.rn-badge-card {
    position: absolute;
    right: clamp(.75rem, 2vw, 1.5rem);
    bottom: clamp(.75rem, 2vw, 1.5rem);
    z-index: 2;
    padding: .875rem 1.25rem;
    text-align: center;
    background: rgba(5, 7, 15, .82);
    border: 1px solid var(--rn-border);
    border-radius: var(--rn-radius);
}
@supports (backdrop-filter: blur(8px)) {
    .rn-badge-card { backdrop-filter: blur(10px); }
}
.rn-badge-card-label {
    font-size: .625rem;
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--rn-text-dim);
    margin: 0 0 .25rem;
}
.rn-badge-card-name {
    font-family: var(--rn-font-heading);
    font-size: 1rem;
    letter-spacing: .06em;
    margin: 0;
}
@media (max-width: 575.98px) {
    /* Too cramped over a small photo — the footer states it anyway */
    .rn-badge-card { display: none; }
}

/* Icon chip inside feature cards */
.rn-icon-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 52px; height: 52px;
    font-size: 1.375rem;
    color: var(--rn-violet);
    background: rgba(139, 49, 232, .12);
    border: 1px solid var(--rn-border);
    border-radius: var(--rn-radius);
    margin-bottom: 1.125rem;
}
.rn-icon-chip--cyan { color: var(--rn-cyan); background: rgba(6, 196, 228, .12); }
.rn-icon-chip--coral { color: var(--rn-coral); background: rgba(240, 78, 35, .12); }
.rn-icon-chip--pink { color: var(--rn-pink); background: rgba(236, 63, 135, .12); }
.rn-icon-chip--round { border-radius: 50%; }


/* =====================================================================
 * §7  STAT STRIP
 * ===================================================================== */
.rn-stats {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));   /* 2×2 on phones */
    gap: 1.25rem 1rem;
    padding-top: clamp(1.5rem, 4vw, 2.5rem);
    border-top: 1px solid var(--rn-border);
}
@media (min-width: 768px) {
    .rn-stats { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1.5rem; }
}
.rn-stat { display: flex; align-items: center; gap: .75rem; }
.rn-stat + .rn-stat { position: relative; }
@media (min-width: 768px) {
    .rn-stat + .rn-stat::before {
        content: '';
        position: absolute;
        left: -.75rem; top: 15%;
        height: 70%; width: 1px;
        background: var(--rn-border);
    }
}
.rn-stat-icon { font-size: 1.5rem; color: var(--rn-violet); flex: 0 0 auto; }
.rn-stat-value {
    font-family: var(--rn-font-heading);
    font-size: clamp(1.25rem, 3vw, 1.75rem);
    font-weight: 700;
    line-height: 1.1;
    /* Keeps counting animations from reflowing the layout */
    font-variant-numeric: tabular-nums;
}
.rn-stat-label {
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--rn-text-dim);
}


/* =====================================================================
 * §8  HEADER / NAVIGATION
 * ===================================================================== */
.rn-header {
    position: sticky;
    top: 0;
    z-index: 1030;
    min-height: var(--rn-header-h);
    background: rgba(var(--rn-bg-rgb), .78);
    border-bottom: 1px solid transparent;
    transition: background-color var(--rn-dur) var(--rn-ease),
                border-color var(--rn-dur) var(--rn-ease);
}
@supports (backdrop-filter: blur(12px)) {
    .rn-header { backdrop-filter: blur(14px) saturate(140%); }
}
/* .is-scrolled is toggled by raise-next.js past 24px */
.rn-header.is-scrolled {
    background: rgba(var(--rn-bg-rgb), .94);
    border-bottom-color: var(--rn-border);
}

.rn-brand { display: inline-flex; align-items: center; gap: .625rem; }
/* The mark is a <picture>; its size comes from the width/height attributes
 * the component renders, so no fixed dimensions here. */
.rn-brand picture { display: inline-flex; flex: 0 0 auto; }
.rn-brand-mark { display: block; height: auto; flex: 0 0 auto; }
.rn-brand-text {
    font-family: var(--rn-font-heading);
    font-size: 1.1875rem;
    font-weight: 700;
    letter-spacing: .01em;
    color: var(--rn-text);
    white-space: nowrap;
}
/* "RAISE" solid + "NEXT" gradient — live text, not an image.
 * Deliberately NOT scoped to .rn-brand-text: the hero lockup renders the
 * wordmark without that wrapper, and used to lose the gradient entirely.
 * background-image, not the shorthand — see the note in §3. */
.rn-brand-next {
    background-image: var(--rn-grad-cool);
    -webkit-background-clip: text;
    background-clip: text;
    color: var(--rn-cyan);                /* solid fallback */
}
@supports (-webkit-background-clip: text) or (background-clip: text) {
    .rn-brand-next { color: transparent; }
}
.rn-brand-tagline {
    display: block;
    font-family: var(--rn-font-body);
    font-size: .5rem;
    font-weight: 500;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--rn-text-dim);
}

.rn-nav-link {
    display: block;
    padding: .625rem .875rem;
    font-size: .8125rem;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--rn-text-muted);
    position: relative;
}
.rn-nav-link:hover { color: var(--rn-text); }
.rn-nav-link.is-active { color: var(--rn-text); }
.rn-nav-link.is-active::after {
    content: '';
    position: absolute;
    left: .875rem; right: .875rem; bottom: 2px;
    height: 2px;
    background: var(--rn-grad-cta);
    border-radius: 2px;
}

/* Priority nav (raise-next.js §17). The wrap takes the free space between
 * brand and actions (flex-basis 0, so its width never depends on its own
 * content and the resize observer cannot loop). Links never wrap or shrink;
 * whatever does not fit is hidden here and listed under "More". Until the
 * script runs, the overflow is clipped rather than pushed over the CTA. */
.rn-nav-wrap { flex: 1 1 0; min-width: 0; justify-content: center; align-items: center; }
.rn-nav { display: flex; align-items: center; min-width: 0; overflow-x: clip; }
.rn-nav .rn-nav-link { flex: 0 0 auto; white-space: nowrap; }
.rn-nav-more { flex: 0 0 auto; }
.rn-nav-more > .rn-nav-link {
    display: inline-flex; align-items: center; gap: .375rem;
    white-space: nowrap; background: none; border: 0;
}
.rn-nav-more > .rn-nav-link .bi { font-size: .625rem; }
.rn-nav-more .dropdown-menu {
    --bs-dropdown-bg: var(--rn-surface);
    --bs-dropdown-border-color: var(--rn-border);
    --bs-dropdown-link-color: var(--rn-text-muted);
    --bs-dropdown-link-hover-color: var(--rn-text);
    --bs-dropdown-link-hover-bg: rgba(var(--rn-ink-rgb), .05);
    --bs-dropdown-link-active-color: var(--rn-text);
    --bs-dropdown-link-active-bg: rgba(139, 49, 232, .25);
    --bs-dropdown-item-padding-y: .625rem;
    --bs-dropdown-item-padding-x: 1.125rem;
    font-size: .8125rem;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
}

/* Language switcher */
.rn-lang { display: inline-flex; border: 1px solid var(--rn-border); border-radius: var(--rn-radius-sm); overflow: hidden; }
.rn-lang a {
    min-width: 44px;                       /* touch target */
    padding: .5rem .625rem;
    font-size: .75rem;
    font-weight: 600;
    text-align: center;
    color: var(--rn-text-muted);
}
.rn-lang a:hover { color: var(--rn-text); background: rgba(var(--rn-ink-rgb), .05); }
.rn-lang a.is-active { color: var(--rn-selected-text); background: rgba(139, 49, 232, .35); }

/* Theme toggle — a link to /theme/{other}, upgraded in place by
 * raise-next.js §20. Both icons are rendered; the theme attribute decides
 * which one shows, so the button is right even before the script runs. */
.rn-theme-toggle {
    display: inline-flex;
    align-items: center; justify-content: center;
    flex: 0 0 auto;
    width: 44px; height: 44px;                /* touch target */
    font-size: 1.0625rem;
    color: var(--rn-text-muted);
    background: transparent;
    border: 1px solid var(--rn-border);
    border-radius: var(--rn-radius-sm);
}
.rn-theme-toggle:hover { color: var(--rn-text); background: rgba(var(--rn-ink-rgb), .05); }
/* From lg it sits beside the 40px .rn-btn--sm pair rather than the 44px
 * hamburger, so it takes their height. */
@media (min-width: 992px) {
    .rn-theme-toggle { width: 40px; height: 40px; }
}
[data-bs-theme="dark"] .rn-theme-toggle .rn-theme-to-dark,
[data-bs-theme="light"] .rn-theme-toggle .rn-theme-to-light { display: none; }

/* Mobile menu trigger */
.rn-nav-toggle {
    display: inline-flex;
    align-items: center; justify-content: center;
    width: 44px; height: 44px;
    background: transparent;
    border: 1px solid var(--rn-border);
    border-radius: var(--rn-radius-sm);
    color: var(--rn-text);
    font-size: 1.25rem;
}

/* Offcanvas mobile menu */
.rn-offcanvas {
    background: var(--rn-bg);
    border-left: 1px solid var(--rn-border);
    width: min(88vw, 360px);
}
.rn-offcanvas .rn-nav-link {
    padding: .875rem 0;
    font-size: 1rem;
    letter-spacing: .06em;
    border-bottom: 1px solid var(--rn-border);
}
.rn-offcanvas .rn-nav-link.is-active::after { display: none; }
.rn-offcanvas .rn-nav-link.is-active { color: var(--rn-cyan); }
/* CTA pinned to the bottom of the sheet */
.rn-offcanvas-footer { margin-top: auto; padding-top: 1.5rem; }


/* =====================================================================
 * §9  HERO
 * ===================================================================== */
.rn-hero {
    position: relative;
    padding: clamp(3rem, 8vw, 6rem) 0 clamp(2.5rem, 6vw, 4rem);
    overflow: hidden;
}
.rn-hero-media {
    position: relative;
    border-radius: var(--rn-radius-lg);
    overflow: hidden;

    /* Container queries let the logo lockup below scale with the photo
     * rather than the viewport, so it stays locked to the LED screen at
     * every breakpoint. */
    container-type: inline-size;

    /* --- Tuning knobs for the hero photo ---------------------------------
     * Aspect ratio must match the source image or object-fit: cover crops
     * the sides and the lockup drifts off the screen.
     * The screen coordinates were measured from hero-stage.jpg: the LED wall
     * spans 51.5–86.5% horizontally and 25–69% vertically.
     * Re-measure and update these three values if the photo is regenerated. */
    --rn-hero-ratio: 1584 / 672;
    --rn-screen-x: 69%;
    --rn-screen-y: 45%;
    --rn-screen-w: 19cqw;
}
/* Generated photos are not all the same shape. Give each hero the modifier
 * matching its asset, or object-fit: cover silently crops it. */
.rn-hero-media--43 { --rn-hero-ratio: 1408 / 768; }
/* Direct-child selectors on purpose: the brand lockup below nests its own
 * <picture>, and a descendant selector here would force the square logo into
 * this 2.36:1 box with object-fit: cover — cropping it to a horizontal slice. */
.rn-hero-media > picture,
.rn-hero-media > img { display: block; aspect-ratio: var(--rn-hero-ratio); }
.rn-hero-media > picture > img,
.rn-hero-media > img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Fades the photo into the page background on its left edge (desktop)
 * or bottom edge (mobile), as in the mockups */
.rn-hero-media::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, transparent 55%, var(--rn-bg) 100%);
}
@media (min-width: 992px) {
    .rn-hero-media::after {
        background: linear-gradient(90deg, var(--rn-bg) 0%, rgba(var(--rn-bg-rgb), .55) 22%, transparent 60%);
    }
}

/* --- Logo lockup composited onto the LED screen ------------------------
 * The hero photo is generated with a deliberately blank screen (see
 * req_docs/IMAGE_PROMPTS.md) and the brand lockup is laid over it here, so
 * it stays crisp at any density, translatable, and re-themeable — instead
 * of being baked into a JPEG that would have to be regenerated to change.
 * Sizes are in cqw (% of the photo's width), so the lockup scales with the
 * image and never drifts. */
.rn-hero-screen {
    position: absolute;
    left: var(--rn-screen-x);
    top: var(--rn-screen-y);
    transform: translate(-50%, -50%);
    width: var(--rn-screen-w);
    z-index: 1;
    text-align: center;
    line-height: 1.05;
    pointer-events: none;
    /* The screen behind is mid-violet; a soft shadow keeps the white type
     * readable wherever the beams fall. */
    text-shadow: 0 2px 12px rgba(5, 7, 15, .45);
}

/* Dark scrim behind the lockup.
 * Not decoration — the logo's R runs violet → blue → cyan and the lit screen
 * behind it is #6C51F1, which puts the violet end at 1.1:1. Without this the
 * R is genuinely invisible and only the coral arrow survives. Real event
 * screens show a logo on a dark backdrop for the same reason. */
.rn-hero-screen::before {
    content: '';
    position: absolute;
    left: 46%;
    top: 50%;
    width: 172%;
    height: 168%;
    transform: translate(-50%, -50%);
    background: radial-gradient(ellipse at center,
        rgba(5, 7, 15, .92) 0%,
        rgba(5, 7, 15, .86) 38%,
        rgba(5, 7, 15, .55) 68%,
        transparent 100%);
    z-index: -1;
    pointer-events: none;
}

.rn-hero-screen picture { display: block; width: 30%; margin: 0 auto .8cqw; }
.rn-hero-screen-mark { display: block; width: 100%; height: auto; }
.rn-hero-screen-word {
    font-family: var(--rn-font-heading);
    font-weight: 700;
    font-size: 2.6cqw;
    letter-spacing: .05em;
    color: #fff;
    margin: 0;
}
.rn-hero-screen-tag {
    font-size: .8cqw;
    font-weight: 600;
    letter-spacing: .11em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, .88);
    margin: .7cqw 0 0;
}
.rn-hero-screen-sub {
    font-size: .9cqw;
    font-weight: 500;
    letter-spacing: .4em;
    text-transform: uppercase;
    /* letter-spacing pads the right edge; pull it back to stay centred */
    text-indent: .4em;
    color: rgba(255, 255, 255, .7);
    margin: .9cqw 0 0;
}
/* On a narrow photo the two small lines stop being legible; the mark and
 * wordmark stay, scaled up a little, still locked to the screen. */
@container (max-width: 520px) {
    .rn-hero-screen { width: 24cqw; }
    .rn-hero-screen-word { font-size: 3.2cqw; }
    .rn-hero-screen-tag,
    .rn-hero-screen-sub { display: none; }
}
/* No container query support → the photo simply keeps its blank screen */
@supports not (container-type: inline-size) {
    .rn-hero-screen { display: none; }
}


/* =====================================================================
 * §10  TICKET CARDS & INCLUSION MATRIX
 * ===================================================================== */
.rn-ticket {
    display: flex;
    flex-direction: column;
    /* Tier cards always sit in a grid, so they fill their column to keep the
     * three of them level regardless of how many inclusions each lists. */
    height: 100%;
    text-align: center;
    border-width: 1px;
    border-color: var(--rn-border);
}
.rn-ticket-badge {
    position: absolute;
    top: -.75rem; left: 50%;
    transform: translateX(-50%);
    padding: .3125rem .875rem;
    font-size: .6875rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: #fff;
    border-radius: var(--rn-radius-pill);
    white-space: nowrap;
}
.rn-ticket-icon {
    width: 58px; height: 58px;
    margin: 0 auto 1.25rem;
    display: flex; align-items: center; justify-content: center;
    font-size: 1.5rem;
    color: #fff;
    border-radius: 50%;
}
.rn-ticket-name {
    font-size: .9375rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    margin-bottom: .25rem;
}
.rn-ticket-price {
    font-family: var(--rn-font-heading);
    font-size: clamp(2.5rem, 6vw, 3.25rem);
    font-weight: 700;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    margin: .5rem 0 .25rem;
}
.rn-ticket-currency { font-size: .8125rem; font-weight: 500; color: var(--rn-text-dim); letter-spacing: .04em; }
.rn-ticket-desc { font-size: .9375rem; color: var(--rn-text-muted); min-height: 3rem; }
.rn-ticket-list { list-style: none; padding: 0; margin: 1.5rem 0; text-align: left; }
.rn-ticket-list li {
    display: flex; align-items: flex-start; gap: .625rem;
    padding: .4375rem 0;
    font-size: .9375rem;
    color: var(--rn-text-muted);
}
.rn-ticket-list li i { flex: 0 0 auto; margin-top: .2rem; }
.rn-ticket-cta { margin-top: auto; }

/* Tier accents */
.rn-ticket--1 .rn-ticket-icon { background: linear-gradient(135deg, #6D28D9, #A78BFA); }
.rn-ticket--2 .rn-ticket-icon { background: linear-gradient(135deg, #DC3B18, #FB923C); }
.rn-ticket--3 .rn-ticket-icon { background: linear-gradient(135deg, #087E93, #22D3EE); }
.rn-ticket--1 .rn-ticket-name, .rn-ticket--1 .rn-ticket-price, .rn-ticket--1 .rn-ticket-list i { color: var(--rn-tier-1-text); }
.rn-ticket--2 .rn-ticket-name, .rn-ticket--2 .rn-ticket-price, .rn-ticket--2 .rn-ticket-list i { color: var(--rn-tier-2-text); }
.rn-ticket--3 .rn-ticket-name, .rn-ticket--3 .rn-ticket-price, .rn-ticket--3 .rn-ticket-list i { color: var(--rn-tier-3-text); }
.rn-ticket--1 .rn-ticket-badge { background: var(--rn-tier-1); }
.rn-ticket--2 .rn-ticket-badge { background: var(--rn-tier-2); }
.rn-ticket--3 .rn-ticket-badge { background: var(--rn-tier-3); }

/* Featured tier keeps its coloured border on every screen size but only
 * scales up on desktop, where there's room for it */
.rn-ticket.is-featured { border-color: var(--rn-tier-2); box-shadow: 0 0 40px rgba(240, 78, 35, .18); }
@media (min-width: 992px) {
    .rn-ticket.is-featured { transform: scale(1.03); }
    .rn-ticket.is-featured.rn-card--hover:hover { transform: scale(1.03) translateY(-4px); }
}

/* Quantity stepper */
.rn-qty { display: inline-flex; align-items: center; gap: .5rem; }
.rn-qty button {
    width: 44px; height: 44px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--rn-surface-2);
    border: 1px solid var(--rn-border);
    border-radius: var(--rn-radius-sm);
    color: var(--rn-text);
    font-size: 1.125rem;
}
.rn-qty button:hover:not(:disabled) { border-color: var(--rn-border-strong); background: var(--rn-surface-3); }
.rn-qty button:disabled { opacity: .4; cursor: not-allowed; }
.rn-qty input {
    width: 56px; height: 44px;
    text-align: center;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    background: var(--rn-bg);
    border: 1px solid var(--rn-border);
    border-radius: var(--rn-radius-sm);
    color: var(--rn-text);
    /* Hide native spinners — we provide our own 44px buttons */
    -moz-appearance: textfield;
}
.rn-qty input::-webkit-outer-spin-button,
.rn-qty input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* A tier in the order (raise-next.js §3): a ring outside the card's own
 * border, so it reads over the featured tier's coral edge too, and a
 * "✓ N" chip on the top edge, clear of the centred badge. */
.rn-ticket.is-picked { outline: 2px solid var(--rn-violet); outline-offset: 3px; }
.rn-ticket-picked {
    position: absolute;
    top: -.75rem; right: 1rem;
    display: inline-flex; align-items: center; gap: .125rem;
    padding: .25rem .625rem .25rem .5rem;
    font-size: .75rem;
    font-weight: 700;
    line-height: 1.2;
    color: #fff;
    background: var(--rn-violet);
    border-radius: var(--rn-radius-pill);
}

/* Order bar under the tier grid (tickets.php). Sticky to the foot of the
 * screen, and the form is its containing block: it floats only while the
 * grid is in view and comes to rest below it, never over the comparison
 * table or the footer. z-index 1020 keeps it under the header (1030), the
 * mobile menu and modals; the consent banner stays above it. .is-stuck is
 * set by the cart script while it floats. Phones show one combined savings
 * line (.rn-order-bar-save-total), wider screens the itemised ones. */
.rn-order-bar {
    position: sticky;
    bottom: calc(.75rem + env(safe-area-inset-bottom, 0px));
    z-index: 1020;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .75rem 1.5rem;
    margin-top: clamp(1.5rem, 3vw, 2.5rem);
    padding: .75rem .75rem .75rem 1.25rem;
    background-color: var(--rn-surface);
    background-image: var(--rn-grad-surface);
    border: 1px solid var(--rn-border-strong);
    border-radius: var(--rn-radius-lg);
    transition: box-shadow var(--rn-dur) var(--rn-ease);
}
.rn-order-bar.is-stuck { box-shadow: var(--rn-shadow-bar); }
.rn-order-bar-summary {
    flex: 1 1 20rem;
    min-width: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .125rem 1.5rem;
}
.rn-order-bar-total { font-weight: 500; color: var(--rn-text); }
.rn-order-bar-total strong { font-family: var(--rn-font-heading); font-size: 1.1875rem; }
.rn-order-bar-total .rn-dim { font-size: .875rem; }
.rn-order-bar-note { flex-basis: 100%; font-size: .8125rem; }
.rn-order-bar-cta { flex: 0 0 auto; }
@media (max-width: 767.98px) {
    .rn-order-bar { gap: .5rem; padding: .75rem; }
    .rn-order-bar-summary { flex-basis: 100%; flex-direction: column; align-items: flex-start; gap: 0; }
    /* The region keeps its name: aria-labelledby reads a hidden title */
    .rn-order-bar-title,
    .rn-order-bar-save-item { display: none; }
    .rn-order-bar-cta { width: 100%; }
}
@media (min-width: 768px) {
    .rn-order-bar-save-total { display: none; }
}
/* Keyboard focus never lands behind the floating bar (WCAG 2.4.11) */
html:has(.rn-order-bar:not([hidden])) { scroll-padding-bottom: 9.5rem; }
@media (min-width: 768px) {
    html:has(.rn-order-bar:not([hidden])) { scroll-padding-bottom: 7rem; }
}
@media (prefers-reduced-motion: no-preference) {
    .rn-order-bar:not([hidden]) { animation: rn-order-bar-in 260ms var(--rn-ease); }
    @keyframes rn-order-bar-in {
        from { opacity: 0; transform: translateY(12px); }
    }
}

/* Comparison matrix — a real table on desktop, stacked cards on mobile.
 * Never a horizontally scrolling table. */
.rn-matrix { width: 100%; border-collapse: collapse; }
.rn-matrix th, .rn-matrix td {
    padding: .875rem 1rem;
    font-size: .875rem;
    text-align: center;
    border-bottom: 1px solid var(--rn-border);
}
.rn-matrix thead th { background: var(--rn-bg-alt); font-size: .75rem; letter-spacing: .08em; text-transform: uppercase; }
.rn-matrix tbody th {
    text-align: left;
    font-weight: 500;
    color: var(--rn-text-muted);
    display: flex; align-items: center; gap: .625rem;
}
.rn-matrix .rn-matrix-yes { color: var(--rn-cyan); }
.rn-matrix .rn-matrix-no { color: var(--rn-text-dim); }
@media (max-width: 991.98px) { .rn-matrix-wrap { display: none; } }
@media (min-width: 992px) { .rn-matrix-stack { display: none; } }


/* =====================================================================
 * §11  FORMS
 * ===================================================================== */
.rn-label {
    display: block;
    margin-bottom: .4375rem;
    font-size: .75rem;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--rn-text-muted);
}
.rn-label .rn-required { color: var(--rn-coral); margin-left: .125rem; }

.rn-input,
.rn-select,
.rn-textarea {
    display: block;
    width: 100%;
    min-height: 48px;
    padding: .75rem 1rem;
    /* 16px minimum stops iOS Safari zooming on focus */
    font-size: 1rem;
    font-family: var(--rn-font-body);
    color: var(--rn-text);
    background: var(--rn-bg);
    border: 1px solid var(--rn-border-control);
    border-radius: var(--rn-radius-sm);
    transition: border-color var(--rn-dur) var(--rn-ease), box-shadow var(--rn-dur) var(--rn-ease);
}
.rn-textarea { min-height: 132px; resize: vertical; line-height: 1.6; }
.rn-input::placeholder, .rn-textarea::placeholder { color: var(--rn-text-dim); }
.rn-input:focus, .rn-select:focus, .rn-textarea:focus {
    outline: none;
    border-color: var(--rn-violet);
    box-shadow: 0 0 0 3px rgba(139, 49, 232, .22);
}
.rn-input.is-invalid, .rn-select.is-invalid, .rn-textarea.is-invalid { border-color: var(--rn-coral); }
.rn-select {
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%239AA6BF'%3E%3Cpath d='M8 11L3 6h10z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 1rem center;
    background-size: 14px;
    padding-right: 2.5rem;
}
.rn-help { margin-top: .375rem; font-size: .8125rem; color: var(--rn-text-dim); }
.rn-error { margin-top: .375rem; font-size: .8125rem; color: var(--rn-danger); }

/* Drag-and-drop file field */
.rn-dropzone {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .75rem;
    padding: 2rem 1rem;
    text-align: center;
    background: var(--rn-bg);
    border: 1.5px dashed var(--rn-border-control);
    border-radius: var(--rn-radius);
    color: var(--rn-text-muted);
    cursor: pointer;
    transition: border-color var(--rn-dur) var(--rn-ease), background-color var(--rn-dur) var(--rn-ease);
}
.rn-dropzone:hover, .rn-dropzone.is-dragover { border-color: var(--rn-cyan); background: rgba(6, 196, 228, .05); }
.rn-dropzone i { font-size: 1.75rem; color: var(--rn-violet); }

.rn-counter { font-size: .75rem; color: var(--rn-text-dim); font-variant-numeric: tabular-nums; }

/* Bootstrap checkboxes (bulk selection, etc.). The compiled defaults are
 * invisible on this palette: the fill matches the page background and the
 * border maps to --rn-border (~1.2:1 composited); checked/indeterminate are
 * hardcoded Bootstrap blue, off-palette. The violet fill is 3.1:1+ against
 * every surface and Bootstrap's white glyph on it is 5.7:1. */
.form-check-input {
    width: 1.125rem;
    height: 1.125rem;
    margin-top: 0;
    flex-shrink: 0;
    background-color: var(--rn-surface-3);
    border: 1px solid var(--rn-border-control);
}
.form-check-input:focus {
    border-color: var(--rn-violet);
    box-shadow: 0 0 0 3px rgba(139, 49, 232, .22);
}
.form-check-input:checked,
.form-check-input:indeterminate {
    background-color: var(--rn-violet);
    border-color: var(--rn-violet);
}

/* Bare checkboxes/radios (the edit forms' Active / Featured ticks) keep the
 * native control but tick in palette violet. */
input[type="checkbox"]:not(.form-check-input),
input[type="radio"]:not(.form-check-input) { accent-color: var(--rn-violet); }

/* Newsletter inline form */
.rn-newsletter { display: flex; flex-direction: column; gap: .625rem; }
@media (min-width: 576px) and (max-width: 991.98px) {
    .rn-newsletter { flex-direction: row; }
    .rn-newsletter .rn-input { flex: 1 1 auto; }
}


/* =====================================================================
 * §12  STEPS, FAQ, CTA BANNER
 * ===================================================================== */
.rn-steps { list-style: none; padding: 0; margin: 0; }
.rn-step { display: flex; gap: 1rem; padding-bottom: 1.5rem; position: relative; }
.rn-step:last-child { padding-bottom: 0; }
.rn-step-num {
    flex: 0 0 auto;
    width: 34px; height: 34px;
    display: flex; align-items: center; justify-content: center;
    font-family: var(--rn-font-heading);
    font-size: .875rem; font-weight: 700;
    color: #fff;
    background: var(--rn-grad-cta);
    border-radius: 50%;
}
/* Connector line between steps */
.rn-step:not(:last-child)::before {
    content: '';
    position: absolute;
    left: 17px; top: 40px; bottom: 8px;
    width: 1px;
    background: var(--rn-border);
}
.rn-step-title { font-size: .9375rem; font-weight: 600; margin-bottom: .1875rem; }
.rn-step-desc { font-size: .875rem; color: var(--rn-text-muted); margin: 0; }

/* FAQ accordion (Bootstrap accordion, restyled) */
.rn-faq .accordion-item { background: transparent; border: 0; border-bottom: 1px solid var(--rn-border); }
.rn-faq .accordion-button {
    padding: 1.125rem 0;
    font-size: .9375rem;
    font-weight: 500;
    color: var(--rn-text);
    background: transparent;
    box-shadow: none;
}
.rn-faq .accordion-button:not(.collapsed) { color: var(--rn-cyan); background: transparent; }
.rn-faq .accordion-button::after {
    /* Plus/minus rather than a chevron, matching the mockup */
    content: '+';
    background-image: none;
    display: flex; align-items: center; justify-content: center;
    width: 24px; height: 24px;
    font-size: 1.25rem;
    color: var(--rn-text-muted);
    transform: none;
    transition: transform var(--rn-dur) var(--rn-ease);
}
.rn-faq .accordion-button:not(.collapsed)::after { content: '−'; color: var(--rn-cyan); }
.rn-faq .accordion-body { padding: 0 0 1.125rem; font-size: .9375rem; color: var(--rn-text-muted); }

/* Wide gradient call-to-action banner */
.rn-cta-banner {
    position: relative;
    background: var(--rn-grad-cta);
    border-radius: var(--rn-radius-lg);
    padding: clamp(1.75rem, 4vw, 3rem);
    overflow: hidden;
}
.rn-cta-banner h2, .rn-cta-banner p { color: #fff; }
.rn-cta-banner p { opacity: .88; }
.rn-cta-banner .rn-btn--dark { background: #05070F; color: #fff; }
.rn-cta-banner .rn-btn--dark:hover { background: #12162A; }


/* =====================================================================
 * §13  FOOTER
 * ===================================================================== */
.rn-footer { background: var(--rn-bg-alt); border-top: 1px solid var(--rn-border); padding: clamp(2.5rem, 6vw, 4.5rem) 0 1.5rem; }
.rn-footer-title {
    font-family: var(--rn-font-body);
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--rn-text);
    margin-bottom: 1.125rem;
}
.rn-footer-links { list-style: none; padding: 0; margin: 0; }
.rn-footer-links li { margin-bottom: .625rem; }
.rn-footer-links a { font-size: .875rem; color: var(--rn-text-muted); }
.rn-footer-links a:hover { color: var(--rn-cyan); }
.rn-social { display: flex; gap: .625rem; flex-wrap: wrap; }
.rn-social a {
    width: 40px; height: 40px;
    display: inline-flex; align-items: center; justify-content: center;
    color: var(--rn-text-muted);
    border: 1px solid var(--rn-border);
    border-radius: 50%;
    transition: all var(--rn-dur) var(--rn-ease);
}
.rn-social a:hover { color: #fff; border-color: var(--rn-violet); background: rgba(139, 49, 232, .18); }
.rn-footer-bottom {
    margin-top: clamp(2rem, 4vw, 3rem);
    padding-top: 1.5rem;
    border-top: 1px solid var(--rn-border);
    font-size: .8125rem;
    color: var(--rn-text-dim);
}


/* =====================================================================
 * §14  ALERTS / FLASH MESSAGES
 * ===================================================================== */
.rn-alert {
    display: flex; align-items: flex-start; gap: .75rem;
    padding: 1rem 1.125rem;
    border: 1px solid var(--rn-border);
    border-left-width: 3px;
    border-radius: var(--rn-radius-sm);
    background: var(--rn-surface);
    font-size: .9375rem;
}
.rn-alert--success { border-left-color: var(--rn-alert-success-edge); color: var(--rn-alert-success); }
.rn-alert--error { border-left-color: var(--rn-coral); color: var(--rn-alert-error); }
.rn-alert--info { border-left-color: var(--rn-cyan); color: var(--rn-alert-info); }
.rn-alert ul { margin: 0; padding-left: 1.125rem; }


/* =====================================================================
 * §15  MOTION
 * ===================================================================== */
@media (prefers-reduced-motion: no-preference) {
    .rn-reveal {
        opacity: 0;
        transform: translateY(18px);
        transition: opacity 500ms var(--rn-ease), transform 500ms var(--rn-ease);
    }
    .rn-reveal.is-visible { opacity: 1; transform: none; }
    /* Stagger children by index — set --i in the markup */
    .rn-reveal[style*="--i"] { transition-delay: calc(var(--i) * 60ms); }
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
    }
}


/* =====================================================================
 * §16  MEMBERS / ADMIN PANEL
 * ---------------------------------------------------------------------
 * The panel shares the public palette. Layout-specific dimensions stay
 * overridable per layout via --rn-sidebar-w / --rn-topnav-h.
 * ===================================================================== */
:root {
    --rn-sidebar-w: 250px;
    --rn-topnav-h: 60px;
}

.rn-panel-topnav {
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 1030;
    height: var(--rn-topnav-h);
    display: flex;
    align-items: center;
    background: rgba(var(--rn-bg-rgb), .92);
    border-bottom: 1px solid var(--rn-border);
}
@supports (backdrop-filter: blur(12px)) {
    .rn-panel-topnav { backdrop-filter: blur(14px) saturate(140%); }
}

.rn-panel-sidebar {
    position: fixed;
    top: 0; left: 0; bottom: 0;
    z-index: 1020;
    width: var(--rn-sidebar-w);
    padding-top: var(--rn-topnav-h);
    background: var(--rn-sidebar-bg);
    border-right: 1px solid var(--rn-border);
    overflow-y: auto;
}
.rn-panel-sidebar .nav-link {
    position: relative;
    display: flex;
    align-items: center;
    gap: .625rem;
    padding: .75rem 1.25rem;
    font-size: .875rem;
    font-weight: 500;
    color: var(--rn-text-muted);
    border-radius: 0;
}
.rn-panel-sidebar .nav-link:hover { color: var(--rn-text); background: rgba(var(--rn-ink-rgb), .04); }
.rn-panel-sidebar .nav-link.active { color: var(--rn-selected-text); background: rgba(139, 49, 232, .14); }
/* Gradient indicator bar on the active item */
.rn-panel-sidebar .nav-link.active::before {
    content: '';
    position: absolute;
    left: 0; top: 0; bottom: 0;
    width: 3px;
    background: var(--rn-grad-cta);
}
.rn-panel-heading {
    padding: 1.25rem 1.25rem .5rem;
    font-size: .6875rem;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--rn-text-dim);
}

.rn-panel-main { padding-top: var(--rn-topnav-h); }
@media (min-width: 992px) {
    .rn-panel-main { margin-left: var(--rn-sidebar-w); }
}
/* Below lg the sidebar becomes an offcanvas, so no content offset */
@media (max-width: 991.98px) {
    .rn-panel-sidebar { transform: translateX(-100%); transition: transform var(--rn-dur) var(--rn-ease); }
    .rn-panel-sidebar.is-open { transform: none; box-shadow: 0 0 60px rgba(0, 0, 0, .7); }
}

/* Panel data tables */
.rn-table { width: 100%; font-size: .875rem; }
.rn-table th {
    padding: .75rem 1rem;
    font-size: .6875rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    /* muted, not dim: 11px uppercase needs the headroom (7.9:1 on bg-alt) */
    color: var(--rn-text-muted);
    background: var(--rn-bg-alt);
    white-space: nowrap;
}
.rn-table td { padding: .875rem 1rem; border-top: 1px solid var(--rn-border); vertical-align: middle; }
.rn-table tbody tr:hover td { background: rgba(var(--rn-ink-rgb), .02); }
/* Tables are the one place a horizontal scroll is acceptable — wrap
 * them in .rn-table-wrap so the page body itself never scrolls */
.rn-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* Drag-to-reorder rows (raise-next.js §12) */
.rn-drag-handle {
    display: inline-flex; align-items: center; justify-content: center;
    width: 28px; height: 28px; padding: 0;
    border: 0; border-radius: 6px; background: transparent;
    color: var(--rn-text-dim); cursor: grab;
}
.rn-drag-handle:hover,
.rn-drag-handle:focus-visible { color: var(--rn-text); background: rgba(var(--rn-ink-rgb), .06); }
.rn-drag-handle:active { cursor: grabbing; }
.rn-table tbody[data-rn-sort-row] tr { cursor: grab; }
.rn-table tbody[data-rn-sort-row] tr:active { cursor: grabbing; }
.rn-table tr.is-dragging { opacity: .45; }
.rn-table tr.is-dragging td { background: rgba(var(--rn-ink-rgb), .04); }

/* Status chips */
.rn-chip {
    display: inline-flex; align-items: center; gap: .375rem;
    padding: .25rem .625rem;
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    border-radius: var(--rn-radius-pill);
    border: 1px solid currentColor;
    white-space: nowrap;
}
.rn-chip--draft { color: var(--rn-text-dim); }
.rn-chip--pending { color: var(--rn-warning); }
.rn-chip--success { color: var(--rn-success); }
.rn-chip--danger { color: var(--rn-danger); }
.rn-chip--info { color: var(--rn-cyan); }
.rn-chip--violet { color: var(--rn-violet-text); }

/* EN | FR tab pair used on every translatable admin field.
 * Below lg the two languages are tabbed (JS toggles [hidden]); from lg both
 * panes show side by side, so the hidden attribute is overridden. */
@media (min-width: 992px) {
    [data-rn-lang-pane][hidden] { display: block !important; }
}
.rn-lang-tabs { display: inline-flex; gap: .25rem; margin-bottom: .5rem; }
.rn-lang-tabs button {
    padding: .25rem .625rem;
    font-size: .6875rem;
    font-weight: 700;
    letter-spacing: .06em;
    color: var(--rn-text-dim);
    background: transparent;
    border: 1px solid var(--rn-border);
    border-radius: var(--rn-radius-sm);
}
.rn-lang-tabs button.is-active { color: var(--rn-selected-text); background: rgba(139, 49, 232, .30); border-color: var(--rn-border-strong); }


/* =====================================================================
 * §17  UTILITIES
 * ===================================================================== */
.rn-stack-sm > * + * { margin-top: .5rem; }
.rn-stack > * + * { margin-top: 1rem; }
.rn-stack-lg > * + * { margin-top: 1.75rem; }
.rn-tabular { font-variant-numeric: tabular-nums; }
.rn-nowrap { white-space: nowrap; }
.rn-z1 { position: relative; z-index: 1; }
.rn-divider { height: 1px; background: var(--rn-border); border: 0; margin: 0; }
.rn-visually-hidden {
    position: absolute !important;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}
/* Honeypot trap container (Config\Honeypot::$containerId) on /apply and
   /contact. Hidden here rather than by the framework's <style nonce="…">
   injection: a nonce in style-src-elem switches 'unsafe-inline' off, which
   blocked the GetTerms banner's own <style> elements. See App\Honeypot\Honeypot. */
#hpc { display: none !important; }


/* =====================================================================
 * §18  AUTH SHELL
 * ---------------------------------------------------------------------
 * Split-screen chrome for the auth pages (login, register, 2FA, password
 * reset), rendered by layouts/auth.php only: branding panel on the left
 * (hidden under 992px, replaced by .rn-auth-mobile-brand above the card),
 * form panel on the right with the language switcher pinned top-right.
 * The tab switcher (.rn-auth-tabs) and the social sign-in placeholders
 * (.rn-social) appear on login/register only.
 * ===================================================================== */
.rn-auth {
    display: flex;
    min-height: 100dvh;
}

/* --- Left branding panel --------------------------------------------- */
.rn-auth-brand {
    position: relative;
    flex: 0 0 44%;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 3rem;
    overflow: hidden;
    background: linear-gradient(160deg, var(--rn-bg-alt) 0%, var(--rn-bg) 100%);
}
/* Decorative glow blobs, clipped by the panel */
.rn-auth-brand::before,
.rn-auth-brand::after {
    content: '';
    position: absolute;
    border-radius: 50%;
    pointer-events: none;
}
.rn-auth-brand::before {
    top: -30%; right: -20%;
    width: 500px; height: 500px;
    background: radial-gradient(circle, rgba(139, 49, 232, .16), transparent 70%);
}
.rn-auth-brand::after {
    bottom: -20%; left: -15%;
    width: 400px; height: 400px;
    background: radial-gradient(circle, rgba(6, 196, 228, .10), transparent 70%);
}
.rn-auth-brand-content {
    position: relative;
    z-index: 1;
    max-width: 24rem;
    text-align: center;
}
.rn-auth-brand-content .rn-brand { margin-bottom: 2.25rem; }
.rn-auth-brand-content .rn-brand-text { font-size: 1.5rem; }
.rn-auth-tagline {
    font-family: var(--rn-font-heading);
    font-size: 2rem;               /* keeps the .rn-grad-text span at 32px+ */
    font-weight: 700;
    line-height: 1.25;
    color: var(--rn-text);
    margin-bottom: .875rem;
}
.rn-auth-brand-sub {
    margin-bottom: 0;
    font-size: .9375rem;
    line-height: 1.6;
    color: var(--rn-text-muted);
}
/* Static decoration (dot 1 "active") — nothing rotates these */
.rn-auth-dots {
    display: flex;
    justify-content: center;
    gap: .5rem;
    margin-top: 2.5rem;
}
.rn-auth-dots span {
    width: 8px; height: 8px;
    border-radius: 50%;
    background: rgba(var(--rn-ink-rgb), .2);
}
.rn-auth-dots span.is-active {
    width: 24px;
    border-radius: 4px;
    background: var(--rn-violet);
}

/* --- Right form panel ------------------------------------------------ */
.rn-auth-panel {
    position: relative;
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 4.5rem 1.25rem 3rem;   /* top clears the absolute topbar */
}
.rn-auth-topbar {
    position: absolute;
    top: 1.25rem; right: 1.5rem;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: .5rem;
}

/* Single column the card, alerts and footer microcopy all share */
.rn-auth-card { width: min(100%, 28.5rem); }
.rn-auth-card .rn-card { box-shadow: var(--rn-shadow-card), var(--rn-glow-sm); }

/* Compact lockup shown above the card once the panel is hidden */
.rn-auth-mobile-brand {
    display: none;
    margin-bottom: 1.5rem;
    text-align: center;
}

.rn-auth-home { margin: 1.75rem 0 0; text-align: center; }
.rn-auth-home a {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    font-size: .8125rem;
    color: var(--rn-text-dim);
}
.rn-auth-home a:hover { color: var(--rn-text); }

/* --- Login | Register switcher (links; active set server-side) ------- */
.rn-auth-tabs {
    display: flex;
    padding: 4px;
    margin-bottom: 1.5rem;
    background: var(--rn-surface-2);
    border: 1px solid var(--rn-border);
    border-radius: var(--rn-radius-pill);
}
.rn-auth-tabs a {
    flex: 1;
    padding: .55rem 1rem;
    border-radius: var(--rn-radius-pill);
    font-size: .875rem;
    font-weight: 600;
    text-align: center;
    color: var(--rn-text-muted);
    transition: color var(--rn-dur) var(--rn-ease),
                background-color var(--rn-dur) var(--rn-ease);
}
.rn-auth-tabs a:hover { color: var(--rn-text); }
/* Same fill as .rn-lang-tabs — the contrast-checked combo */
.rn-auth-tabs a.is-active { color: var(--rn-selected-text); background: rgba(139, 49, 232, .30); }

/* --- Social sign-in placeholders — raise-next.js §13 ------------------ */
.rn-social { display: flex; gap: .75rem; margin-bottom: 1.25rem; }
.rn-social-btn {
    flex: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    min-height: 44px;                      /* touch target */
    padding: .55rem .75rem;
    border: 1px solid var(--rn-border-control);
    border-radius: var(--rn-radius);
    background: var(--rn-surface-2);
    font-size: .8125rem;
    font-weight: 600;
    color: var(--rn-text);
    transition: border-color var(--rn-dur) var(--rn-ease),
                box-shadow var(--rn-dur) var(--rn-ease);
}
.rn-social-btn:hover,
.rn-social-btn:focus-visible {
    border-color: var(--rn-border-strong);
    box-shadow: var(--rn-glow-sm);
}
.rn-social-btn svg { width: 18px; height: 18px; flex: 0 0 auto; }

.rn-auth-divider {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 1.25rem;
    font-size: .78rem;
    color: var(--rn-text-dim);
}
.rn-auth-divider::before,
.rn-auth-divider::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--rn-border-plain);
}

/* --- Live password checklist — raise-next.js §14 ---------------------- */
.rn-pw-checklist {
    list-style: none;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: .25rem .75rem;
    margin: .5rem 0 0;
    padding: 0;
    font-size: .8125rem;
    color: var(--rn-text-dim);
}
.rn-pw-checklist li {
    display: flex;
    align-items: center;
    gap: .4rem;
    transition: color var(--rn-dur) var(--rn-ease);
}
.rn-pw-checklist li.ok { color: var(--rn-cyan); }

.rn-auth-footer {
    margin: 1.25rem 0 0;
    font-size: .875rem;
    text-align: center;
    color: var(--rn-text-dim);
}

/* Label + inline action ("Forgot password?") on one line */
.rn-label-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: .75rem;
    margin-bottom: .4375rem;
}
.rn-label-row .rn-label { margin-bottom: 0; }
.rn-label-row a { font-size: .8125rem; }

/* One-time-code entry */
.rn-input--otp {
    text-align: center;
    letter-spacing: .5em;
    font-weight: 700;
    font-size: 1.25rem;
}

/* Password field with a visibility toggle — raise-next.js §10 */
.rn-input-group { position: relative; }
.rn-input-group .rn-input { padding-right: 3rem; }
.rn-input-toggle {
    position: absolute;
    top: 50%; right: .375rem;
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem; height: 2.5rem;
    border: 0;
    border-radius: var(--rn-radius-sm);
    background: transparent;
    color: var(--rn-text-dim);
    font-size: 1.05rem;
}
.rn-input-toggle:hover,
.rn-input-toggle:focus-visible { color: var(--rn-text); }

/* --- Auth shell responsive ------------------------------------------- */
@media (max-width: 991.98px) {
    .rn-auth-brand { display: none; }
    .rn-auth-mobile-brand { display: block; }
    .rn-auth-panel { padding: 4.5rem 1.25rem 2.5rem; }
}
@media (max-width: 575.98px) {
    .rn-social { flex-direction: column; }
    .rn-auth-topbar { top: .875rem; right: 1rem; }
    .rn-pw-checklist { grid-template-columns: 1fr; }
}


/* =====================================================================
 * §19  SALES COUNTDOWN BANNER
 * ---------------------------------------------------------------------
 * Full-width strip under the sticky header on home, tickets and
 * speakers while ticket sales are upcoming. Digits are ticked by
 * initCountdown() (raise-next.js §15); at zero the JS unhides the
 * pre-rendered .rn-cd-open state. Digit cells ride .rn-tabular so the
 * once-a-second updates never reflow the row.
 * ===================================================================== */
.rn-countdown {
    position: relative;
    background:
        linear-gradient(90deg, rgba(139, 49, 232, .12), rgba(30, 134, 222, .06) 55%, rgba(6, 196, 228, .10)),
        var(--rn-bg-alt);
    border-bottom: 1px solid var(--rn-border-strong);
    padding: 1rem 0;
    overflow: hidden;
}
/* Gradient hairline along the top edge, echoing the CTA ramp */
.rn-countdown::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 2px;
    background: var(--rn-grad-cta);
}

.rn-cd-live {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem 1.5rem;
}
.rn-cd-info { min-width: 0; }
.rn-cd-opens {
    font-size: var(--rn-fs-sm);
    color: var(--rn-text-muted);
}

.rn-cd-timer {
    display: flex;
    gap: .5rem;
}
.rn-cd-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    min-width: 3.375rem;
    padding: .5rem .375rem .4375rem;
    background: rgba(255, 255, 255, .04);
    border: 1px solid var(--rn-border-strong);
    border-radius: var(--rn-radius);
    box-shadow: var(--rn-glow-sm);
}
.rn-cd-num {
    display: block;
    font-family: var(--rn-font-heading);
    font-size: clamp(1.25rem, 3vw, 1.625rem);
    font-weight: 700;
    line-height: 1.1;
    color: var(--rn-text);
}
.rn-cd-lbl {
    margin-top: .125rem;
    font-size: .625rem;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--rn-text-dim);
}

.rn-cd-form {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem .75rem;
    flex: 1 1 100%;
}
.rn-cd-blurb {
    flex-basis: 100%;
    font-size: var(--rn-fs-sm);
    color: var(--rn-text-muted);
}
.rn-cd-form .rn-input { flex: 1 1 220px; min-width: 0; }

.rn-cd-open {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: .75rem 1.25rem;
    padding: .25rem 0;
}
.rn-cd-open-msg {
    font-family: var(--rn-font-heading);
    font-size: 1.0625rem;
    font-weight: 600;
}

/* From lg the three blocks share one row; the form stops full-bleeding */
@media (min-width: 992px) {
    .rn-cd-form { flex: 0 1 420px; }
}
/* On phones the four tiles spread evenly across the row */
@media (max-width: 575.98px) {
    .rn-cd-timer { width: 100%; }
    .rn-cd-tile { flex: 1 1 0; }
}

@media (prefers-reduced-motion: no-preference) {
    /* Live pulse on the pill dot — modifier only: the plain .rn-pill-dot
       is shared with the home hero pill and must stay still there. */
    @keyframes rn-cd-pulse {
        0%, 100% { transform: scale(1); opacity: 1; }
        50%      { transform: scale(1.35); opacity: .55; }
    }
    .rn-pill-dot--pulse { animation: rn-cd-pulse 2s var(--rn-ease) infinite; }

    /* Digit change — retriggered by JS via .is-tick */
    @keyframes rn-cd-tick {
        from { transform: translateY(-5px); opacity: 0; }
        to   { transform: none; opacity: 1; }
    }
    .rn-cd-num.is-tick { animation: rn-cd-tick 260ms var(--rn-ease); }
}

/* =====================================================================
 * §20  EARLY BIRD
 * ---------------------------------------------------------------------
 * The banner reuses the §19 strip (.rn-countdown, .rn-cd-live) — it takes
 * the countdown's place once sales open, so it keeps the same footprint.
 * Ticket cards gain a struck-through regular price above the price
 * actually charged. Teal reads as "saving" without competing with the
 * tier accents; --rn-save (#2DD4BF dark, #0C6A62 light) holds well above
 * 4.5:1 on the card surfaces in both themes.
 * ===================================================================== */
.rn-earlybird-title {
    font-family: var(--rn-font-heading);
    font-size: clamp(1.125rem, 2.4vw, 1.375rem);
    font-weight: 700;
    line-height: 1.25;
    color: var(--rn-text);
}

.rn-ticket-was {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: .25rem .5rem;
    margin-top: .5rem;
    font-size: 1rem;
    font-variant-numeric: tabular-nums;
    color: var(--rn-text-dim);
}
.rn-ticket-was s { text-decoration-thickness: 2px; }
.rn-ticket-save {
    padding: .125rem .5rem;
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .04em;
    color: var(--rn-save);
    background: rgba(var(--rn-save-rgb), .12);
    border: 1px solid rgba(var(--rn-save-rgb), .35);
    border-radius: var(--rn-radius-pill);
}
/* The price line already carries .5rem of top margin for the no-promo
 * layout; with the "was" line above it the gap closes up. */
.rn-ticket-was + .rn-ticket-price { margin-top: .25rem; }

.rn-ticket-savings { font-size: .875rem; color: var(--rn-save); }
.rn-ticket-savings i { margin-right: .25rem; }


/* =====================================================================
 * §21  MEMBERSHIP (Raise Next Card)
 * ---------------------------------------------------------------------
 * The card is drawn here rather than photographed (components/
 * membership_card.php): it stays sharp at any size and carries live
 * member data. Black brushed metal with silver lettering, after the
 * client mockups. Credit-card proportions (85.6 × 54 mm = 1.586).
 *
 * The card is its own size container, so everything inside it is sized
 * in cqw and scales with the card — one rule set serves the hero, the
 * compact stage and the phone-sized digital card alike.
 * ===================================================================== */
.rn-mcard {
    position: relative;
    container-type: inline-size;
    display: flex;
    flex-direction: column;
    width: 100%;
    aspect-ratio: 1.586;
    overflow: hidden;
    color: #E6E8EC;
    /* Percentages of the card's own box: credit-card corners (3.18 of
     * 85.6 mm), kept circular at this aspect ratio */
    border-radius: 3.7% / 5.87%;
    background:
        /* brushed grain: fine horizontal streaks, light and dark */
        repeating-linear-gradient(0deg, rgba(255, 255, 255, .028) 0 1px, transparent 1px 3px),
        repeating-linear-gradient(0deg, rgba(0, 0, 0, .22) 0 1px, transparent 1px 5px),
        linear-gradient(135deg, #1D1E23 0%, #0B0B0E 48%, #18191E 100%);
    /* A black card casts no visible shadow on a near-black page, so the
     * lift comes from a violet underglow instead */
    box-shadow:
        0 18px 36px -10px rgba(0, 0, 0, .7),
        0 24px 70px -18px rgba(139, 49, 232, .55);
}
/* Bevelled edge catching the light, brightest top-left as on the metal
 * card in the client mockup. It outlines the card on any background. */
.rn-mcard::before {
    content: '';
    position: absolute;
    inset: 0;
    padding: max(1px, .35cqw);
    border-radius: inherit;
    background: linear-gradient(135deg,
        rgba(255, 255, 255, .7) 0%, rgba(255, 255, 255, .16) 22%,
        rgba(255, 255, 255, .06) 55%, rgba(255, 255, 255, .38) 100%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    pointer-events: none;
}
/* Diagonal sheen across the metal */
.rn-mcard::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(115deg, transparent 30%, rgba(255, 255, 255, .07) 45%, transparent 60%);
    pointer-events: none;
}

/* The face, not the card, carries the padding. A size container can't
 * query itself, so cqw in .rn-mcard's own padding resolved against the
 * viewport: 129px a side on a 432px card at 1840px wide, which squeezed
 * everything inside to a third of the card and varied with the screen. */
.rn-mcard-face {
    display: flex;
    flex: 1;
    flex-direction: column;
    justify-content: center;
    min-height: 0;
    padding: 7cqw;
}

.rn-mcard-brand { display: flex; flex-direction: column; align-items: center; text-align: center; }
.rn-mcard-brand picture { display: block; line-height: 0; }
.rn-mcard .rn-mcard-mark {
    width: 20cqw;
    height: auto;
    margin-bottom: 3cqw;
    /* The colour logo, rendered as engraved silver */
    filter: grayscale(1) brightness(1.6) contrast(.9);
}
.rn-mcard-word,
.rn-mcard-sub { margin: 0; line-height: 1.1; font-family: var(--rn-font-heading); }
.rn-mcard-word {
    font-size: 7.6cqw;
    font-weight: 600;
    letter-spacing: .16em;
    white-space: nowrap;
    /* Silver on near-black — high contrast at any size, unlike violet */
    background: linear-gradient(180deg, #F4F5F7 0%, #A6AAB3 55%, #E4E6EA 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}
.rn-mcard-sub {
    margin-top: 1.5cqw;
    font-size: 5.2cqw;
    font-weight: 500;
    letter-spacing: .55em;
    /* letter-spacing trails the last glyph; this re-centres the word */
    margin-right: -.55em;
    color: #B4B8C0;
}

/* With member data the brand moves to the top-left — mark beside a
 * stacked wordmark — and the identity block fills the bottom. */
.rn-mcard--member .rn-mcard-face { justify-content: space-between; padding: 6cqw 6.5cqw; }
.rn-mcard--member .rn-mcard-brand {
    display: grid;
    grid-template-columns: auto 1fr;
    column-gap: 2.5cqw;
    align-items: center;
    text-align: left;
}
.rn-mcard--member .rn-mcard-brand picture { grid-row: span 2; }
.rn-mcard--member .rn-mcard-mark { width: 8cqw; margin-bottom: 0; }
.rn-mcard--member .rn-mcard-word { align-self: end; font-size: 4.6cqw; }
.rn-mcard--member .rn-mcard-sub { align-self: start; margin-top: .8cqw; margin-right: 0; font-size: 2cqw; letter-spacing: .45em; }

.rn-mcard-foot {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 4cqw;
}
.rn-mcard-id { min-width: 0; }
.rn-mcard-id p { margin: 0; }
.rn-mcard-name {
    font-size: 4.6cqw;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: .03em;
    overflow-wrap: anywhere;
}
.rn-mcard-id .rn-mcard-code {
    margin-top: 1cqw;
    font-family: var(--rn-font-heading);
    font-size: 4cqw;
    letter-spacing: .14em;
    font-variant-numeric: tabular-nums;
    color: #C8CBD2;
}
.rn-mcard-id .rn-mcard-valid { margin-top: 1cqw; font-size: 2.8cqw; color: #A3A8B2; }
/* QR on white with a quiet zone, so it scans off a dark card and a dim phone */
.rn-mcard-qr {
    flex: 0 0 auto;
    width: 25cqw;
    height: auto;
    padding: 1.2cqw;
    background: #fff;
    border-radius: 1.6cqw;
}
/* As the enlarge button (§6 .rn-qr-zoom): badge in card units, pulled in
 * less than on the ticket thumbnail so the card's rounded corner can't clip it */
.rn-mcard-qr .rn-qr-zoom-badge {
    right: -1.6cqw;
    bottom: -1.6cqw;
    width: 6cqw;
    height: 6cqw;
    font-size: 2.8cqw;
    box-shadow: 0 0 0 .5cqw #111216;
}

.rn-mcard--expired { filter: grayscale(1) brightness(.6); }
/* A lapsed card shouldn't stand in the brand light (§21 stage) */
.rn-mcard-stage:has(.rn-mcard--expired)::before { filter: blur(36px) grayscale(1); opacity: .3; }

/* --- Stage: the hero's two overlapping cards, backlit ---
 * Black on the near-black page barely registers, so the cards stand in
 * front of a light source: the violet-to-cyan streak of the client's
 * product shot, bright enough that the card silhouettes cut out of it. */
.rn-mcard-stage {
    position: relative;
    width: 100%;
    max-width: 600px;
    margin-inline: auto;
    aspect-ratio: 1.45;
}
.rn-mcard-stage::before {
    content: '';
    position: absolute;
    inset: -16% -14%;
    background:
        radial-gradient(closest-side at 50% 50%, rgba(236, 228, 255, .35), transparent 70%),
        linear-gradient(118deg, transparent 10%, #8B31E8 30%, #4B3AE0 45%, #1E86DE 58%, #06C4E4 72%, transparent 90%);
    -webkit-mask: radial-gradient(closest-side, #000 62%, transparent);
    mask: radial-gradient(closest-side, #000 62%, transparent);
    filter: blur(36px);
    pointer-events: none;
}
.rn-mcard-stage .rn-mcard--back,
.rn-mcard-stage .rn-mcard--front { position: absolute; }
.rn-mcard-stage .rn-mcard--back  { top: 4%; right: 1%; width: 66%; transform: rotate(7deg); }
.rn-mcard-stage .rn-mcard--front { bottom: 5%; left: 1%; width: 72%; transform: rotate(-5deg); }

/* Compact: one flat card in normal flow (join page, members area,
 * success page, digital card). */
.rn-mcard-stage--compact { max-width: 440px; margin-inline: 0; aspect-ratio: auto; }
.rn-mcard-stage--compact::before { inset: -22% -12%; opacity: .8; }
/* On a phone the card fills the column, and 12% of it outruns the gutter
 * into a horizontal scroll: 1rem is the narrower of the public container
 * (1.25rem) and the members panel's p-3 */
@media (max-width: 575.98px) {
    .rn-mcard-stage--compact::before { inset: -22% -1rem; }
}
.rn-mcard-stage--compact .rn-mcard--front { position: relative; inset: auto; width: 100%; transform: none; }

@media (prefers-reduced-motion: no-preference) {
    .rn-mcard-stage .rn-mcard { transition: transform 400ms var(--rn-ease); }
    .rn-mcard-stage:not(.rn-mcard-stage--compact):hover .rn-mcard--front { transform: rotate(-3deg) translateY(-6px); }
    .rn-mcard-stage:not(.rn-mcard-stage--compact):hover .rn-mcard--back  { transform: rotate(9deg) translateY(4px); }
}

/* --- Price line --- */
.rn-mprice { display: flex; flex-wrap: wrap; align-items: baseline; gap: .25rem .625rem; }
.rn-mprice-amount {
    font-family: var(--rn-font-heading);
    font-size: clamp(2rem, 4vw, 2.75rem);
    font-weight: 700;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    color: var(--rn-text);
}
.rn-mprice-unit { font-size: .875rem; color: var(--rn-text-muted); }

/* --- Three-up stat strip (the default .rn-stats is four-up) --- */
.rn-stats--3 { grid-template-columns: minmax(0, 1fr); }
@media (min-width: 768px) {
    .rn-stats--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 767.98px) {
    .rn-stats--3 .rn-stat + .rn-stat { padding-top: 1.25rem; border-top: 1px solid var(--rn-border); }
}

/* --- Benefit grid: hairline-ruled cells, like the mockup --- */
.rn-mbenefits {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1px;
    padding: 0;
    overflow: hidden;
    background: var(--rn-border);
    border: 1px solid var(--rn-border);
    border-radius: var(--rn-radius-lg);
}
@media (min-width: 768px)  { .rn-mbenefits { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* Eight benefits (terms art. 5): two rows of four, never a ragged last row. */
@media (min-width: 1200px) { .rn-mbenefits { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.rn-mbenefit { padding: clamp(1.5rem, 3vw, 2.25rem); background: var(--rn-surface); }
.rn-mbenefit-num {
    display: inline-grid;
    place-items: center;
    width: 2.25rem;
    height: 2.25rem;
    font-size: .8125rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: #C4A4FF;
    background: rgba(139, 49, 232, .16);
    border-radius: 50%;
}
.rn-mbenefit-icon { font-size: 1.375rem; }
.rn-mbenefit-title {
    margin-bottom: .5rem;
    font-family: var(--rn-font-heading);
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--rn-text);
}
.rn-mbenefit-desc { margin: 0; font-size: .9375rem; color: var(--rn-text-muted); }

.rn-fineprint { font-size: .8125rem; color: var(--rn-text-dim); }
.rn-fineprint li + li { margin-top: .375rem; }

/* --- Sign-up form --- */
/* Gradient top rule from the mockup. A pseudo-element clipped by the
 * card's own radius — border-image would drop the radius and side borders. */
.rn-mform { overflow: hidden; }
.rn-mform::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 3px;
    background: var(--rn-grad-cta);
}
.rn-mform-section {
    min-width: 0;
    margin: 0 0 1.75rem;
    padding: 0;
    border: 0;
}
.rn-mform-section + .rn-mform-section { padding-top: 1.75rem; border-top: 1px solid var(--rn-border); }
.rn-mform-legend {
    float: none;
    width: auto;
    margin-bottom: 1rem;
    font-family: var(--rn-font-heading);
    font-size: 1.0625rem;
    font-weight: 600;
    color: var(--rn-text);
}
.rn-mform-shipping {
    min-width: 0;
    margin: 1.25rem 0 0;
    padding: 1.25rem;
    background: var(--rn-bg-alt);
    border: 1px solid var(--rn-border);
    border-radius: var(--rn-radius);
}
.rn-optional {
    margin-left: .25rem;
    font-weight: 400;
    letter-spacing: 0;
    text-transform: none;
    color: var(--rn-text-dim);
}

/* Large tappable checkbox row (≥44px target) */
.rn-mcheck {
    display: flex;
    align-items: flex-start;
    gap: .75rem;
    min-height: 44px;
    padding: .875rem 1rem;
    cursor: pointer;
    background: var(--rn-bg);
    border: 1px solid var(--rn-border-control);
    border-radius: var(--rn-radius-sm);
    transition: border-color var(--rn-dur) var(--rn-ease), background-color var(--rn-dur) var(--rn-ease);
}
.rn-mcheck input { flex: 0 0 auto; width: 1.25rem; height: 1.25rem; margin-top: .125rem; }
.rn-mcheck:has(input:checked) { border-color: var(--rn-violet); background: rgba(139, 49, 232, .08); }
.rn-mcheck:has(input:disabled) { cursor: not-allowed; opacity: .55; }
.rn-mcheck:has(input:focus-visible) { box-shadow: 0 0 0 3px rgba(139, 49, 232, .22); }

.rn-msummary {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: flex-start;
    gap: .5rem 1rem;
    padding: 1rem 1.25rem;
    font-size: .875rem;
    background: var(--rn-surface-2);
    border: 1px solid var(--rn-border-plain);
    border-radius: var(--rn-radius);
}
.rn-msummary-name { font-weight: 600; color: var(--rn-text); }
.rn-msummary-price { font-weight: 700; font-variant-numeric: tabular-nums; color: var(--rn-text); }

/* --- Member note on /tickets --- */
/* Tells a logged-in member where their one member-rate ticket stands, since
 * it never combines with the Early Bird. Centred under the section head;
 * the compact variant is the per-card "member rate, one ticket" line. */
.rn-member-note {
    display: flex;
    align-items: flex-start;
    gap: .625rem;
    padding: .75rem 1rem;
    font-size: .875rem;
    color: var(--rn-text);
    background: rgba(139, 49, 232, .08);
    border: 1px solid rgba(139, 49, 232, .35);
    border-radius: var(--rn-radius-sm);
}
.rn-member-note .bi { flex: 0 0 auto; margin-top: .125rem; color: var(--rn-violet); }
.rn-member-note--compact { padding: .5rem .75rem; font-size: .8125rem; text-align: left; }


/* =====================================================================
 * §22  SIGN-IN SECURITY (two-step sign-in)
 * ---------------------------------------------------------------------
 * The banner offering an authenticator app (components/security_prompt)
 * is the §19 strip at panel scale: it sits at the top of .rn-panel-main,
 * above the page padding, so it spans the content column edge to edge.
 * Recovery codes are a two-column monospace grid, sized so a code never
 * wraps mid-way. Copy buttons are wired by raise-next.js §18.
 * ===================================================================== */
.rn-2fa-prompt {
    position: relative;
    background:
        linear-gradient(90deg, rgba(139, 49, 232, .14), rgba(30, 134, 222, .06) 55%, rgba(6, 196, 228, .10)),
        var(--rn-bg-alt);
    border-bottom: 1px solid var(--rn-border-strong);
    padding: .875rem 0;
}
.rn-2fa-prompt::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 2px;
    background: var(--rn-grad-cta);
}
.rn-2fa-prompt-inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .75rem 1.5rem;
}
.rn-2fa-prompt-text {
    display: flex;
    align-items: center;
    gap: .875rem;
    min-width: 0;
    flex: 1 1 22rem;
}
.rn-2fa-prompt-text .rn-icon-chip { flex: 0 0 auto; width: 42px; height: 42px; font-size: 1.125rem; }
.rn-2fa-prompt-title {
    font-family: var(--rn-font-heading);
    font-weight: 700;
    color: var(--rn-text);
}
.rn-2fa-prompt-lead { font-size: var(--rn-fs-sm); color: var(--rn-text-muted); }
.rn-2fa-prompt-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
}
.rn-2fa-prompt-actions form { margin: 0; }
@media (max-width: 575.98px) {
    /* Three full-width taps beat three cramped ones on a phone */
    .rn-2fa-prompt-actions { flex-direction: column; align-items: stretch; width: 100%; }
    .rn-2fa-prompt-actions .rn-btn { width: 100%; }
}

/* Password + button on one line, wrapping on narrow cards */
.rn-confirm-row {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}
.rn-confirm-row .rn-input { flex: 1 1 14rem; width: auto; min-width: 0; }

/* --- Recovery codes --- */
.rn-codes-card { border-color: rgba(139, 49, 232, .45); }
.rn-codes {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
    gap: .5rem;
    margin: 0;
    padding: 1rem;
    list-style: none;
    background: var(--rn-surface-2);
    border: 1px solid var(--rn-border-plain);
    border-radius: var(--rn-radius-sm);
}
.rn-codes li {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 1rem;
    letter-spacing: .06em;
    color: var(--rn-text);
    white-space: nowrap;
}
.rn-codes-low { color: var(--rn-alert-error); }

/* --- Authenticator setup --- */
.rn-qr-frame {
    display: inline-block;
    padding: .75rem;
    line-height: 0;
    /* Scanners want dark-on-light with a quiet zone; the PNG already has
     * one, the white frame keeps it from bleeding into a dark card */
    background: #fff;
    border-radius: var(--rn-radius-sm);
}
.rn-qr-frame img { width: min(240px, 100%); height: auto; }

.rn-secret-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
}
.rn-secret {
    padding: .5rem .75rem;
    font-size: .9375rem;
    letter-spacing: .08em;
    color: var(--rn-text);
    word-break: break-all;
    background: var(--rn-surface-2);
    border: 1px solid var(--rn-border-plain);
    border-radius: var(--rn-radius-sm);
}

/* --- <details> fold (recovery code on the sign-in challenge) --- */
.rn-disclosure {
    border-top: 1px solid var(--rn-border);
    padding-top: 1rem;
}
.rn-disclosure > summary {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    min-height: 44px;
    font-size: var(--rn-fs-sm);
    font-weight: 600;
    color: var(--rn-text-muted);
    cursor: pointer;
    list-style: none;
}
.rn-disclosure > summary::-webkit-details-marker { display: none; }
.rn-disclosure > summary::before {
    content: "\F285"; /* bi-chevron-right */
    font-family: "bootstrap-icons";
    font-size: .75rem;
    transition: transform var(--rn-dur) var(--rn-ease);
}
.rn-disclosure[open] > summary::before { transform: rotate(90deg); }
.rn-disclosure > summary:hover { color: var(--rn-text); }
@media (prefers-reduced-motion: reduce) {
    .rn-disclosure > summary::before { transition: none; }
}


/* =====================================================================
 * §23  ADMIN NOTIFICATION BELL
 * ---------------------------------------------------------------------
 * components/admin_bell, in the admin top bar. The count is the page
 * colour on --rn-warning: the same "needs a person" amber as the sidebar
 * badges (.rn-chip--pending), where white on the warm brand colours would
 * fail AA at 11px. Dark on amber, or light on deep amber, both ≥6:1. Unread entries carry a violet tint, a bolder title and a
 * dot; the dot is decoration, the visually hidden "Unread" is what a
 * screen reader hears. The menu narrows to the viewport on a phone, and
 * Popper keeps it on screen.
 * ===================================================================== */
.rn-bell {
    position: relative;
    display: inline-flex;
    align-items: center; justify-content: center;
    width: 44px; height: 44px;              /* touch target */
    padding: 0;
    background: transparent;
    border: 1px solid var(--rn-border);
    border-radius: var(--rn-radius-sm);
    color: var(--rn-text-muted);
    font-size: 1.125rem;
}
.rn-bell:hover,
.rn-bell[aria-expanded="true"] { color: var(--rn-text); background: rgba(var(--rn-ink-rgb), .05); }
.rn-bell.has-unread { color: var(--rn-text); }
.rn-bell-count {
    position: absolute;
    top: 3px; right: 3px;
    min-width: 18px; height: 18px;
    padding: 0 5px;
    font-size: .6875rem;
    font-weight: 700;
    line-height: 18px;
    text-align: center;
    color: var(--rn-bg);
    background: var(--rn-warning);
    border-radius: var(--rn-radius-pill);
    box-shadow: 0 0 0 2px var(--rn-bg);
}

.rn-bell-menu {
    --bs-dropdown-bg: var(--rn-surface);
    --bs-dropdown-border-color: var(--rn-border);
    width: min(22rem, calc(100vw - 2rem));
    padding: 0;
    overflow: hidden;
}
.rn-bell-head {
    display: flex;
    align-items: center; justify-content: space-between;
    gap: .75rem;
    padding: .5rem 1rem;
    min-height: 48px;
    border-bottom: 1px solid var(--rn-border);
}
.rn-bell-title {
    font-size: .6875rem;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--rn-text-muted);
}
.rn-bell-readall {
    min-height: 32px;
    padding: 0 .25rem;
    font-size: .8125rem;
    font-weight: 600;
    color: var(--rn-cyan);
    background: none;
    border: 0;
}
.rn-bell-readall:hover { text-decoration: underline; }

.rn-bell-list {
    list-style: none;
    margin: 0; padding: 0;
    max-height: min(26rem, 70vh);
    overflow-y: auto;
}
.rn-bell-list li + li { border-top: 1px solid var(--rn-border-plain); }
.rn-bell-item {
    display: flex;
    align-items: flex-start;
    gap: .75rem;
    padding: .75rem 1rem;
    color: var(--rn-text-muted);
    text-decoration: none;
}
.rn-bell-item:hover,
.rn-bell-item:focus-visible { color: var(--rn-text); background: rgba(var(--rn-ink-rgb), .04); }
.rn-bell-item.is-unread { background: rgba(139, 49, 232, .10); }
.rn-bell-item.is-unread:hover,
.rn-bell-item.is-unread:focus-visible { background: rgba(139, 49, 232, .16); }
.rn-bell-icon {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center; justify-content: center;
    width: 32px; height: 32px;
    border-radius: 50%;
    color: var(--rn-violet-text);
    background: rgba(139, 49, 232, .16);
}
.rn-bell-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: .125rem; }
.rn-bell-item-title { font-size: .875rem; font-weight: 500; }
.rn-bell-item.is-unread .rn-bell-item-title { font-weight: 700; color: var(--rn-text); }
.rn-bell-detail { font-size: .8125rem; overflow-wrap: anywhere; }
.rn-bell-time { font-size: .75rem; color: var(--rn-text-dim); }
.rn-bell-dot {
    flex: 0 0 auto;
    width: 8px; height: 8px;
    margin-top: .5rem;
    border-radius: 50%;
    background: var(--rn-violet-text);
}
.rn-bell-empty {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin: 0;
    padding: 1.25rem 1rem;
    font-size: .875rem;
    color: var(--rn-text-muted);
}
.rn-bell-empty .bi { color: var(--rn-success); }


/* =====================================================================
 * §24  LIGHT THEME
 * ---------------------------------------------------------------------
 * The palette itself is in §1; this section holds the few rules a token
 * swap can't express. Measured with a WCAG checker on the light tokens:
 *   - --rn-text-muted 7.5:1 and --rn-text-dim 6.1:1 on --rn-bg, both
 *     ≥5:1 on --rn-surface-3; every accent and status token ≥4.5:1 there.
 *   - --rn-border-control ≥3:1 on every light surface (WCAG 1.4.11).
 *   - .rn-grad-text (warm gradient) bottoms out at ~3.3:1 — fine for its
 *     32px+ rule, as on dark.
 *
 * Dark islands: an element marked data-bs-theme="dark" inside a light page
 * (the LED-screen lockup, the badge over the accelerator photo) gets every
 * dark token back from §1. It still needs its own text colour, because
 * `color` inherits as a computed value from the light body.
 *
 * Scope: every layout — public, auth, members and admin.
 * ===================================================================== */
[data-bs-theme="light"] [data-bs-theme="dark"] { color: var(--rn-text); }

/* Suppresses every transition for the one frame the theme flips, so the
 * page swaps at once instead of fading each card separately (§20 JS). */
.rn-theme-switching *,
.rn-theme-switching *::before,
.rn-theme-switching *::after { transition: none !important; }

/* Segmented controls: a solid violet wash would sit at ~1.3:1 behind dark
 * text on light; a pale tint with deep-violet text reads as "selected". */
[data-bs-theme="light"] .rn-lang a.is-active,
[data-bs-theme="light"] .rn-auth-tabs a.is-active,
[data-bs-theme="light"] .rn-lang-tabs button.is-active { background: rgba(124, 43, 217, .12); }

/* Select arrow drawn in --rn-text-muted (a data URI can't read a token) */
[data-bs-theme="light"] .rn-select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23465068'%3E%3Cpath d='M8 11L3 6h10z'/%3E%3C/svg%3E");
}

/* Motif PNGs were drawn for a near-black page: their shadow pixels vanish
 * into it, leaving only the glow. On light those same pixels become a grey
 * dot screen over body copy. Inverting luminance while rotating the hue back
 * keeps each motif's colour and turns its dark parts pale, which is the same
 * picture the dark theme shows. */
[data-bs-theme="light"] .rn-motif { filter: invert(1) hue-rotate(180deg); }
[data-bs-theme="light"] .rn-motif--mesh,
[data-bs-theme="light"] .rn-motif--waves { opacity: .35; }

/* The hero photos are dark stage shots. Fading one into a light page turns
 * the blend zone grey, so on light the photo stands framed instead. */
[data-bs-theme="light"] .rn-hero-media { box-shadow: var(--rn-shadow-card); }
[data-bs-theme="light"] .rn-hero-media::after { display: none; }
/* Same for speaker portraits: their veil sinks the foot of the photo into
 * the near-black page, and would only leave a dark band on light. */
[data-bs-theme="light"] .rn-speaker-photo::after { display: none; }

/* The partner wall stays a dark island on light (§6). Its own shadow token
 * resolves to the dark theme's black halo, a smudge on a light page; a soft
 * indigo lift frames it instead. */
[data-bs-theme="light"] .rn-partners { box-shadow: 0 18px 50px rgba(30, 27, 75, .18); }

[data-bs-theme="light"] .rn-social a:hover { color: var(--rn-violet); background: rgba(124, 43, 217, .10); }
[data-bs-theme="light"] .rn-cd-tile { background: var(--rn-surface); }
[data-bs-theme="light"] .rn-mbenefit-num { color: var(--rn-violet-text); background: rgba(124, 43, 217, .10); }

/* Panel drawer (sidebar below lg): the dark theme's black halo would read
 * as a smudge over a light page; a soft indigo shadow still lifts it. */
[data-bs-theme="light"] .rn-panel-sidebar.is-open { box-shadow: 0 0 60px rgba(30, 27, 75, .18); }


/* =====================================================================
 * §25  FEATURED SPEAKER (home)
 * ---------------------------------------------------------------------
 * components/featured_speaker: the home page's opening section when
 * Config\Home::$displaySpeaker is on, in place of the §19/§20 strip.
 * The portrait is a transparent cut-out standing on the section's bottom
 * edge, in front of three diagonal violet bands.
 *
 * From lg it has its own column. Below lg it sits behind the right side
 * of the copy, as in the mobile mockup, and its left edge fades out so
 * text running onto the shirt stays readable — in dark the type is white
 * and the shirt is pale.
 *
 * .rn-hero-facts is the date / attendance pair that takes the stage
 * photo's place in the hero below while the speaker shows.
 * ===================================================================== */
.rn-speaker-hero {
    position: relative;
    overflow: hidden;
    padding-top: clamp(2rem, 5vw, 3.5rem);
    background:
        linear-gradient(118deg,
            transparent 60%,
            rgba(var(--rn-violet-rgb), .10) 60.1% 71%,
            rgba(var(--rn-violet-rgb), .18) 71.1% 82%,
            rgba(var(--rn-violet-rgb), .30) 82.1%),
        linear-gradient(90deg, transparent 25%, rgba(var(--rn-violet-rgb), .08)),
        var(--rn-bg-alt);
    border-bottom: 1px solid var(--rn-border);
}

.rn-speaker-hero-copy {
    position: relative;
    z-index: 1;
    padding-bottom: clamp(2rem, 6vw, 3.5rem);
}
.rn-speaker-hero-eyebrow {
    font-size: clamp(.6875rem, .9vw, .9375rem);
    letter-spacing: .2em;
    margin-bottom: .75rem;
}
.rn-speaker-hero-rule {
    display: block;
    width: 3.25rem;
    height: 3px;
    border-radius: 2px;
    background: var(--rn-violet);
    margin-bottom: clamp(1rem, 2vw, 1.5rem);
}
.rn-speaker-hero-name {
    font-family: var(--rn-font-heading);
    font-size: clamp(2.75rem, 5.2vw + 1rem, 6.5rem);
    font-weight: 700;
    line-height: .95;
    letter-spacing: -.03em;
    margin-bottom: clamp(.75rem, 1.5vw, 1.25rem);
}
.rn-speaker-hero-name span { display: block; }
.rn-speaker-hero-role {
    font-family: var(--rn-font-heading);
    font-size: clamp(1.0625rem, 1.6vw, 1.75rem);
    font-weight: 600;
    line-height: 1.25;
    margin-bottom: .375rem;
}
.rn-speaker-hero-tagline {
    font-size: clamp(1rem, 1.3vw, 1.375rem);
    color: var(--rn-text-muted);
    margin-bottom: clamp(1.25rem, 2.5vw, 2rem);
}
/* Below lg the eyebrow and name run above the portrait's head, full width;
 * the lines level with it stop short of his face. */
.rn-speaker-hero-role,
.rn-speaker-hero-tagline { max-width: 68%; }

/* Stacked on phones and tablets, over the portrait's faded edge. */
.rn-speaker-hero-ctas {
    display: flex;
    flex-direction: column;
    gap: .75rem;
    width: min(100%, 15.5rem);
}
.rn-speaker-hero-ctas .rn-btn { padding-inline: 1.25rem; }
.rn-speaker-hero-explore { color: var(--rn-violet-text); border-color: var(--rn-violet); }

.rn-speaker-hero-when {
    display: flex;
    align-items: center;
    gap: .875rem;
    margin: clamp(1.25rem, 2.5vw, 2rem) 0 0;
    font-size: clamp(.75rem, .9vw, .875rem);
    font-weight: 600;
    letter-spacing: .14em;
    line-height: 1.6;
    text-transform: uppercase;
    color: var(--rn-text-muted);
}
.rn-speaker-hero-when i { font-size: 1.5rem; flex: 0 0 auto; }

.rn-speaker-hero-photo {
    position: absolute;
    right: calc(-1 * min(18vw, 6rem));
    bottom: 0;
    width: min(88vw, 34rem);
    /* Mask, not colour: only the alpha channel of these stops is used */
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 38%);
    mask-image: linear-gradient(90deg, transparent, #000 38%);
}
.rn-speaker-hero-photo img { display: block; width: 100%; height: auto; }

@media (min-width: 992px) {
    .rn-speaker-hero-grid {
        display: grid;
        grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
        gap: 2rem;
    }
    .rn-speaker-hero-copy { align-self: center; }
    .rn-speaker-hero-role,
    .rn-speaker-hero-tagline { max-width: none; }
    .rn-speaker-hero-ctas { flex-direction: row; flex-wrap: wrap; width: auto; }
    .rn-speaker-hero-ctas .rn-btn { padding-inline: 2rem; }
    .rn-speaker-hero-photo {
        position: relative;
        right: 17%;
        align-self: end;
        justify-self: center;
        width: min(100%, 42rem);
        -webkit-mask-image: none;
        mask-image: none;
    }
}

/* --- Accomplishments strip under the portrait --- */
.rn-speaker-facts {
    background: var(--rn-bg);
    border-bottom: 1px solid var(--rn-border);
    padding: clamp(1.25rem, 3vw, 1.75rem) 0;
}
.rn-speaker-facts-list {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));   /* 2×2 on phones */
    gap: 1.25rem 0;
}
.rn-speaker-fact {
    display: grid;
    justify-content: center;
    align-content: start;
    padding-inline: clamp(.75rem, 2.5vw, 2rem);
}
.rn-speaker-fact:nth-child(even) { border-left: 1px solid var(--rn-border-strong); }
@media (min-width: 576px) {
    .rn-speaker-facts-list { grid-template-columns: repeat(4, minmax(0, 1fr)); }
    .rn-speaker-fact + .rn-speaker-fact { border-left: 1px solid var(--rn-border-strong); }
}
.rn-speaker-fact-value {
    font-family: var(--rn-font-heading);
    font-size: clamp(1.125rem, 1.8vw, 1.625rem);
    font-weight: 700;
    line-height: 1.15;
    text-transform: uppercase;
}
.rn-speaker-fact-label {
    margin-top: .25rem;
    font-size: clamp(.8125rem, 1vw, 1rem);
    line-height: 1.35;
    color: var(--rn-text-muted);
}

/* --- Hero: date and attendance in place of the stage photo --- */
.rn-hero-facts {
    display: grid;
    grid-auto-flow: column;
    justify-content: start;
    gap: 1rem;
}
.rn-hero-fact { display: flex; align-items: flex-start; gap: .625rem; }
.rn-hero-fact + .rn-hero-fact {
    border-left: 1px solid var(--rn-border-strong);
    padding-left: 1rem;
}
.rn-hero-fact-icon { font-size: 1.5rem; line-height: 1; color: var(--rn-violet); }
.rn-hero-fact-value { display: block; font-size: .9375rem; font-weight: 600; color: var(--rn-text); }
.rn-hero-fact-label { display: block; font-size: .8125rem; color: var(--rn-text-muted); }
@media (min-width: 992px) {
    .rn-hero-facts {
        grid-auto-columns: minmax(0, 1fr);
        justify-content: stretch;
        gap: 1.5rem;
        border-left: 1px solid var(--rn-border-strong);
        padding-left: clamp(1.5rem, 3vw, 3rem);
    }
    .rn-hero-fact { flex-direction: column; gap: 1rem; }
    .rn-hero-fact + .rn-hero-fact { padding-left: 1.5rem; }
    .rn-hero-fact-icon { font-size: 2.25rem; }
    .rn-hero-fact-value { font-size: 1rem; }
    .rn-hero-fact-label { font-size: var(--rn-fs-sm); }
}
