/* ==========================================================================
   runevents-base.v2.css — GENERATED-PAGE VOCABULARY LAYER
   runevents vocabulary v2
   --------------------------------------------------------------------------
   THIS IS NOT ADMIN UI CSS. Do not import it into main.css. Do not move it into
   the numbered atomic-design tree (00-design-tokens … 08-vendor) — everything in
   those folders is bundled into the Blazor admin app, and this file must never
   load there.

   WHAT IT IS
   The structural implementation of the `runevents__` component vocabulary used by
   AI-generated organizer pages. It defines HOW every component is laid out and
   NEVER what it looks like: every visual value is a var() supplied by the site's
   Design Guideline (DesignGuidelines.GlobalCss), which loads AFTER this file and
   may override any rule here. Machinery, never opinions.

   CASCADE:  runevents-base.v2.css  →  guideline GlobalCss  →  (freestyle only) page <style>

   WHAT CHANGED IN v2 (2026-08-04) — the modern-composition expansion (plan 209, Step A1).
   v2 is a strict SUPERSET of the v1.4 vocabulary: every v1.4 class exists here under the
   same name. Two deliberate BEHAVIOR changes (why this is v2, not v1.5):
     R30 DECOUPLING — no coupled pairs a brief would sensibly override separately.
       · `.runevents__stat-panel` now defaults to a LIGHT surface via
         --stat-panel-bg / --stat-panel-color; the dark treatment is the explicit
         modifier `.runevents__stat-panel--dark` (which uses --color-surface-dark /
         --color-text-on-surface-dark). Recipes emit the modifier when a dark panel
         is wanted.
       · `.runevents__section--dark` ground and ink are independently overridable
         (--section-dark-bg / --section-dark-color), and so are the footer's
         (--footer-bg / --footer-color). All fallbacks reproduce v1.4's rendering.
   NEW MACHINERY GROUPS — all namespaced `runevents__`, all token-driven, all opt-in:
     motion/reveal (scroll-driven entrances, @supports-gated), bento grid, overlap
     composition, sticky pair, image treatments (tint / thick frame / masks / offset /
     drift), section bands + shaped dividers, big numerals, logo strip (static + flow
     marquee), type extras (XL display, outline display, gradient text, ruled eyebrow,
     gradient hero), depth (panel, glass, lift).
   Full v1.x change history (v1.1 :where() wrap, v1.3 button-on-dark fix, v1.4
   text-center margin-auto group) lives in runevents-base.v1.4.css.

   v1.2 DOES NOT EXIST — the number was burned by a CDN caching mishap during rollout and skipped
   deliberately. Never publish anything as v1.2; a stale object may be cached under that URL.
   NEVER EDIT A PUBLISHED VERSION IN PLACE. v1 / v1.1 / v1.3 / v1.4 are frozen and still
   served; any change to a published file ships as a NEW version, restored from the published
   bytes before branching. Until v2 itself is published to the CDN (plan 209, Step G3) it is a
   working-tree file and may be edited freely.

   HARD RULES FOR THIS FILE — enforced by review, checked by the Step A1 greps
     1. Every visual property is a `var(--…, fallback)`. No literal colour, font-family
        or font-size outside a var() fallback.
     2. No bare element selectors. Not body, html, h1-h6, p, a, img, ul, input.
        Element-level rules live ONLY inside `:where(.runevents__section …)` at (0,0,0);
        component classes are (0,1,0). (This page is embedded in a run.events Smart Hub
        column — a bare `body` rule would repaint the HOST page, not just our column.)
     3. No `.gjs-*` and no leading `.span-*` selectors. GrapesJS binds to those names
        and legacy pages already use them; styling them here would silently re-lay-out
        every existing page. Markup carries BOTH classes — `class="gjs-row runevents__row"` —
        and only the namespaced one is styled.
     4. No viewport units and no fixed positioning ANYWHERE in this file, in ANY mode.
        Fluid sizing uses cqi against `.runevents__section`. Full-bleed is token-driven —
        the guideline supplies --bleed per layout mode — so the base stays viewport-unit-free.
     5. No coupled pairs a brief would sensibly override separately (the R30 lesson).
     6. `prefers-reduced-motion: reduce` disables ALL motion this file defines.
     7. `.runevents__page` is the page canvas, emitted on <body> by ToolsController and on
        the GrapesJS canvas body. It carries the whole-page background. No RECIPE emits it —
        it is a host wrapper — but it is always present in a rendered page. The
        `runevents__header` / `runevents__footer` chrome renders as SIBLINGS of <main> and
        never depends on a page-level ancestor (R13).
     8. Reveal/entrance machinery must NEVER hide content by default: every element is fully
        visible with zero JavaScript and zero feature support. Animations that start at
        opacity 0 exist ONLY inside `@supports (animation-timeline: view())` blocks.

   THREE LAYOUT MODES — token-driven; the base implements, the guideline selects.
   The full contract is runevents.EIC.BL/AI/Prompts/LayoutModes.md (plan 209, Step A2).
     EMBEDDED (1)    the page lives in a ~700-1120px run.events Smart Hub column.
                     --page-max is a column value; --bleed is 0 — always, never anything
                     else. Sizing is container-relative (cqi against .runevents__section).
     CONTAINED (2)   standalone page, classic centered container. --page-max ~75rem; the
                     guideline may set a negative --bleed so `.runevents__section--band`
                     becomes a true full-bleed band (legal there: a standalone page owns
                     its own edges — that calc never appears in THIS file).
     FULL-WIDTH (3)  standalone page, edge-to-edge. --page-max: none; --bleed stays 0
                     (sections already span, bands need no bleed).
     No mode stated → EMBEDDED (the safe default: an embedded page renders fine
     standalone; the reverse breaks). Either way layout is driven by container queries,
     so it is responsive on mobile without any mode needing a special case.

   TOKENS CONSUMED (all optional — every one has a neutral fallback below)
     colour     --color-primary --color-primary-hover --color-secondary --color-accent
                --color-bg --color-surface --color-surface-alt --color-surface-dark
                --color-border --color-text --color-text-muted --color-text-inverse
                --color-text-on-primary --color-text-on-secondary --color-text-on-surface-dark
                --color-error
     type       --font-heading --font-body --font-mono
                --text-mega --text-display --text-h1 --text-h2 --text-h3 --text-h4
                --text-lead --text-body --text-small --text-overline
                --font-weight-heading --line-height-body --tracking-display
                --measure-display --measure-heading --measure-lead --measure-body --measure-form
     spacing    --space-xs --space-sm --space-md --space-lg --space-xl --space-2xl
     shape      --radius-sm --radius-md --radius-lg --radius-full
     depth      --shadow-sm --shadow-md --shadow-lg
     motion     --transition-fast --transition-base
     a11y       --color-focus-ring
     frame      --page-max --gutter --gutter-sm
     buttons    --btn-primary-bg-on-dark --btn-primary-text-on-dark
     embed      --embed-ratio
     NEW IN v2 (all with neutral fallbacks — a token-less guideline still renders coherently)
     mode/band  --bleed --band-bg --section-pad --section-gradient
     dividers   --divider-height --divider-bg
     decoupled  --stat-panel-bg --stat-panel-color --section-dark-bg --section-dark-color
                --footer-bg --footer-color --panel-bg --panel-color
     motion v2  --motion-duration --motion-ease --flow-duration
     bento      --bento-cols --bento-cols-md --bento-row-min
     overlap    --overlap-amount
     sticky     --sticky-offset
     media      --media-tint --media-blend --mask-shape --frame-width --frame-color
                --frame-offset --frame-offset-color --logo-filter
     numerals   --text-numeral
     type v2    --text-gradient --text-display-xl --stroke-width --hero-gradient
     depth v2   --glass-blur --lift-y --lift-shadow

   SPECIFICITY CONTRACT — carried over from v1.1, still load-bearing. The full statement
   sits above section 2: every element-level rule is wrapped in :where() at (0,0,0);
   component classes are (0,1,0); a guideline overrides by SOURCE ORDER, never by
   out-specifying. Deliberately NOT wrapped (they must outrank component colours to keep
   contrast and focus visible): the inverted-section colour rules and :focus-visible.

   ⚠️ WHEN YOU ADD OR RENAME A CLASS HERE, update the vocabulary inventory in
      runevents.EIC.BL/AI/Prompts/DesignSpecsAgent-CSS-1200.md (section "THE VOCABULARY").
      That inventory is how the CSS-generating agent learns which class names exist. If it drifts,
      the agent invents plausible names instead and emits a stylesheet that renders nothing.
      Regenerate it with:
        grep -o '\.runevents__[a-z0-9-]*' runevents-base.v2.css | sort -u

   Breaking changes ship as runevents-base.v3.css. Once v2 is published (G3) its shape
   freezes: vocabulary-compatible fixes then ship as v2.x and may be swapped in without
   regenerating pages.
   Plan: store/PAGES-DESIGNS-REVAMP/209-AI-POWERED-DESIGN-SITE-CREATION.md (Step A1)
   ========================================================================== */


/* ==========================================================================
   1. PAGE FRAME
   ========================================================================== */

/* THE PAGE CANVAS.
   Emitted by ToolsController on <body> and set on the GrapesJS canvas body, so it is
   always present in a rendered page. It is the ONLY hook for a whole-page background —
   the base cannot style `body` directly, because in an embedded page that would repaint
   the Smart Hub host around us. A body background propagates to the viewport canvas, so
   this fills the screen even when the content is short. */
#pb-452{
    container-type: inline-size;
    width: 100%;
    margin-inline: auto;
    background-color: var(--color-bg, #fcfcfd);
    color: var(--color-text, #1a181e);
}

/* The section IS the frame and the container context. Every fluid value inside a
   section resolves against the section, never against the viewport.

   `--page-max` decides the mode: 1120px (default) keeps the page in a column;
   `--page-max: none` makes every section span the full browser width. Nothing else
   needs to change between the two — `max-width: none` is valid CSS. */
#pb-452 .runevents__section{
    container-type: inline-size;
    position: relative;
    box-sizing: border-box;
    width: 100%;
    max-width: var(--page-max, 1120px);
    margin-inline: auto;
    padding-block: var(--section-pad, var(--space-2xl, 5rem));
    padding-inline: var(--gutter, 2rem);
    background-color: var(--color-bg, #fcfcfd);
    color: var(--color-text, #1a181e);
}

#pb-452 .runevents__section *,#pb-452 .runevents__section *::before,#pb-452 .runevents__section *::after{
    box-sizing: border-box;
}

#pb-452 .runevents__section--xl{ padding-block: calc(var(--section-pad, var(--space-2xl, 5rem)) * 1.4); }
#pb-452 .runevents__section--flush{ padding-block: 0; }
#pb-452 .runevents__section--flush-top{ padding-block-start: 0; }
#pb-452 .runevents__section--flush-bottom{ padding-block-end: 0; }

#pb-452 .runevents__section--light{
    background-color: var(--color-surface-alt, #f5f4f7);
    color: var(--color-text, #1a181e);
    border-radius: var(--radius-lg, 16px);
}

/* R30 decoupling (v2): ground and ink are INDEPENDENT tokens. A guideline can retint
   the dark ground without dragging the ink along, or vice versa. Fallbacks keep the
   v1.4 rendering for token-less guidelines. */
#pb-452 .runevents__section--dark{
    background-color: var(--section-dark-bg, var(--color-surface-dark, #23202a));
    color: var(--section-dark-color, var(--color-text-on-surface-dark, #ffffff));
    border-radius: var(--radius-lg, 16px);
    overflow: clip;
}

#pb-452 .runevents__section--primary{
    background-color: var(--color-primary, #4a4458);
    color: var(--color-text-on-primary, #ffffff);
    border-radius: var(--radius-lg, 16px);
}

#pb-452 .runevents__section--secondary{
    background-color: var(--color-secondary, #6b6478);
    color: var(--color-text-on-secondary, #ffffff);
    border-radius: var(--radius-lg, 16px);
}

/* Inverted sections hand their colour down rather than re-stating it per element. */
#pb-452 .runevents__section--dark h1,#pb-452 .runevents__section--dark h2,#pb-452 .runevents__section--dark h3,#pb-452 .runevents__section--dark h4,#pb-452 .runevents__section--dark p,#pb-452 .runevents__section--dark li,#pb-452 .runevents__section--dark span,#pb-452 .runevents__section--primary h1,#pb-452 .runevents__section--primary h2,#pb-452 .runevents__section--primary h3,#pb-452 .runevents__section--primary h4,#pb-452 .runevents__section--primary p,#pb-452 .runevents__section--primary li,#pb-452 .runevents__section--primary span,#pb-452 .runevents__section--secondary h1,#pb-452 .runevents__section--secondary h2,#pb-452 .runevents__section--secondary h3,#pb-452 .runevents__section--secondary h4,#pb-452 .runevents__section--secondary p,#pb-452 .runevents__section--secondary li,#pb-452 .runevents__section--secondary span{
    color: inherit;
}

#pb-452 .runevents__container{
    width: 100%;
    max-width: none;
    margin-inline: 0;
}

@media (max-width: 640px) {
    #pb-452 .runevents__section{ padding-inline: var(--gutter-sm, 1.25rem); }
}


/* SPECIFICITY CONTRACT (new in v1.1) — every element-level rule in this file is wrapped in
   :where() so it contributes ZERO specificity. This is load-bearing, not style.
     - An element-qualified selector like `.runevents__section p` is (0,1,1).
     - Every component class in this file — .runevents__lead, .runevents__stat-figure,
       .runevents__eyebrow, .runevents__display, .runevents__btn — is (0,1,0).
   Unwrapped, the generic rule beats ALL of them and flattens the type scale to --text-body
   regardless of source order. That was the v1 defect. Wrapped in :where(), these are true
   baselines: any component class wins, and a guideline's own (0,1,0) component rule wins over
   ours on source order — which is how a guideline is supposed to override the base.
   Deliberately NOT wrapped: the inverted-section colour rules and :focus-visible. Those must
   outrank component colours to keep contrast and focus visible.
   Never remove a :where() here to "make something apply". */

/* ==========================================================================
   2. TYPOGRAPHY — scoped under .runevents__section, never bare elements
   ========================================================================== */

#pb-452 :where(.runevents__section h1,
       .runevents__section h2,
       .runevents__section h3,
       .runevents__section h4){
    margin: 0;
    font-family: var(--font-heading, system-ui, sans-serif);
    line-height: 1.2;
    letter-spacing: -0.02em;
    text-wrap: balance;
    color: inherit;
}

#pb-452 :where(.runevents__section h1){ font-size: var(--text-h1, clamp(1.75rem, 4.2cqi, 2.75rem)); font-weight: var(--font-weight-heading, 700); }
#pb-452 :where(.runevents__section h2){ font-size: var(--text-h2, clamp(1.5rem, 3.4cqi, 2.25rem)); font-weight: var(--font-weight-heading, 700); max-width: var(--measure-heading, 20ch); }
#pb-452 :where(.runevents__section h3){ font-size: var(--text-h3, clamp(1.0625rem, 1.9cqi, 1.375rem)); font-weight: var(--font-weight-heading, 600); }
#pb-452 :where(.runevents__section h4){ font-size: var(--text-h4, 1rem); font-weight: var(--font-weight-heading, 600); }

#pb-452 :where(.runevents__section p,
       .runevents__section li){
    margin: 0;
    font-family: var(--font-body, system-ui, sans-serif);
    font-size: var(--text-body, 1rem);
    line-height: var(--line-height-body, 1.6);
    max-width: var(--measure-body, 70ch);
}

#pb-452 :where(.runevents__section p + p){ margin-top: var(--space-md, 1rem); }

#pb-452 :where(.runevents__section ul,
       .runevents__section ol){ margin: 0; padding-left: 1.25rem; }

#pb-452 :where(.runevents__section img,
       .runevents__section picture,
       .runevents__section svg){
    display: block;
    max-width: 100%;
    height: auto;
}

#pb-452 :where(.runevents__section a){
    color: var(--color-primary, #4a4458);
    text-decoration: none;
    transition: color var(--transition-fast, 160ms ease), opacity var(--transition-fast, 160ms ease);
}
#pb-452 :where(.runevents__section a:hover){ color: var(--color-primary-hover, #3a3546); }

#pb-452 .runevents__section--dark a:not(.runevents__btn),#pb-452 .runevents__section--primary a:not(.runevents__btn),#pb-452 .runevents__section--secondary a:not(.runevents__btn){
    color: inherit;
}
#pb-452 .runevents__section--dark a:not(.runevents__btn):hover,#pb-452 .runevents__section--primary a:not(.runevents__btn):hover,#pb-452 .runevents__section--secondary a:not(.runevents__btn):hover{ opacity: 0.85; }

#pb-452 .runevents__section :focus-visible,#pb-452 .runevents__header :focus-visible,#pb-452 .runevents__footer :focus-visible{
    outline: 2px solid var(--color-primary, #4a4458);
    outline-offset: 2px;
    box-shadow: 0 0 0 4px var(--color-focus-ring, rgba(74, 68, 88, 0.3));
}

#pb-452 .runevents__display{
    font-family: var(--font-heading, system-ui, sans-serif);
    font-size: var(--text-display, clamp(2rem, 5cqi, 3.25rem));
    font-weight: var(--font-weight-heading, 700);
    line-height: 1.1;
    letter-spacing: var(--tracking-display, -0.02em);
    max-width: none;
}

#pb-452 .runevents__display--breakout{
    font-size: var(--text-mega, clamp(2.25rem, 6.5cqi, 4.25rem));
    line-height: 0.94;
    letter-spacing: var(--tracking-display, -0.035em);
    max-width: var(--measure-display, 13ch);
}

#pb-452 .runevents__lead{
    font-family: var(--font-body, system-ui, sans-serif);
    font-size: var(--text-lead, clamp(1.0625rem, 1.5cqi, 1.1875rem));
    line-height: 1.5;
    max-width: var(--measure-lead, 52ch);
    color: var(--color-text-muted, #56525e);
}

#pb-452 .runevents__section--dark .runevents__lead,#pb-452 .runevents__section--primary .runevents__lead,#pb-452 .runevents__section--secondary .runevents__lead{
    color: inherit;
    opacity: 0.82;
}

#pb-452 .runevents__text-muted{ color: var(--color-text-muted, #56525e); }

/* The only alignment utility in the vocabulary. Reserved for the closing CTA —
   the brief-level rule "no centred layouts except the closing CTA" is a design
   decision the guideline owns, but the mechanism has to exist somewhere. */
#pb-452 .runevents__text-center{ text-align: center; }

/* text-align alone does NOT centre these. Headings, the display and the lead all carry a
   `max-width` measure cap, so each is a NARROW BLOCK that stays flush left inside a centred
   section — `text-align: center` then only centres the text within that narrow box, and the box
   itself hugs the left edge. A guideline's `h2::after` accent rule lands left too, because it is
   a block inside the same box. v1.3 centred `p`, `.runevents__lead` and `.runevents__eyebrow` but
   not the headings, so a centred closing CTA rendered with a left-aligned headline above a centred
   button — the single most visibly broken thing on a generated page.
   Anything measure-capped must be margin-auto'd here. */
#pb-452 .runevents__text-center :where(h1, h2, h3, h4, p,
    .runevents__display,
    .runevents__lead,
    .runevents__meta,
    .runevents__section-header,
    .runevents__stat-label,
    .runevents__fact-label,
    .runevents__numeral-label
){ margin-inline: auto; }

#pb-452 .runevents__text-center .runevents__eyebrow{ justify-content: center; }

#pb-452 .runevents__meta,#pb-452 .runevents__time{
    font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: var(--text-small, 0.8125rem);
    letter-spacing: 0.02em;
    color: var(--color-text-muted, #56525e);
}

#pb-452 .runevents__section--dark .runevents__meta,#pb-452 .runevents__section--dark .runevents__time{ color: inherit; opacity: 0.7; }


/* --- Accessibility utilities ----------------------------------------------
   The guideline stylesheet is told the base owns these, so the base must own them. */
#pb-452 .runevents__sr-only{
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}

#pb-452 .runevents__skip-link{
    position: absolute;
    left: 50%;
    top: -100%;
    transform: translateX(-50%);
    z-index: 9999;
    padding: var(--space-sm, 0.5rem) var(--space-md, 1rem);
    background: var(--color-primary, #4a4458);
    color: var(--color-text-on-primary, #ffffff);
    border-radius: var(--radius-sm, 4px);
    font-family: var(--font-body, system-ui, sans-serif);
    font-weight: 600;
    text-decoration: none;
}
#pb-452 .runevents__skip-link:focus{ top: var(--space-sm, 0.5rem); }


/* ==========================================================================
   3. GRID — paired with gjs-row / gjs-cell, never styled through them
   ========================================================================== */

#pb-452 .runevents__row{
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    gap: var(--space-lg, 1.5rem);
}

/* Cells wrap rather than crush: below ~19rem the row breaks instead of squeezing. */
#pb-452 .runevents__cell{
    flex: 1 1 19rem;
    min-width: 0;
}

/* Span classes only bias free space, and only when qualified by the namespaced
   class — so these rules can never match a legacy page. */
#pb-452 .runevents__cell.span-3{ flex-grow: 3; }
#pb-452 .runevents__cell.span-4{ flex-grow: 4; }
#pb-452 .runevents__cell.span-5{ flex-grow: 5; }
#pb-452 .runevents__cell.span-7{ flex-grow: 7; }
#pb-452 .runevents__cell.span-8{ flex-grow: 8; }

#pb-452 .runevents__cell > .runevents__media-frame,#pb-452 .runevents__cell > .runevents__card{ height: 100%; }


/* ==========================================================================
   4. SECTION HEADER + EYEBROW
   ========================================================================== */

#pb-452 .runevents__eyebrow{
    display: flex;
    align-items: center;
    gap: 0.75rem;
    max-width: none;
    margin: 0 0 var(--space-md, 1rem);
    font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: var(--text-overline, 0.75rem);
    font-weight: 500;
    letter-spacing: 0.18em;
    line-height: 1.2;
    text-transform: uppercase;
    color: var(--color-text-muted, #56525e);
}

#pb-452 .runevents__eyebrow::before{
    content: "";
    flex: none;
    width: 24px;
    height: 2px;
    background: var(--color-primary, #4a4458);
}

#pb-452 .runevents__section--dark .runevents__eyebrow,#pb-452 .runevents__section--primary .runevents__eyebrow,#pb-452 .runevents__section--secondary .runevents__eyebrow{
    color: inherit;
    opacity: 0.72;
}
#pb-452 .runevents__section--dark .runevents__eyebrow::before{ background: var(--color-accent, #8a7f96); }
#pb-452 .runevents__section--primary .runevents__eyebrow::before,#pb-452 .runevents__section--secondary .runevents__eyebrow::before{ background: currentColor; }

#pb-452 .runevents__section-header{ margin-bottom: var(--space-xl, 3rem); }
#pb-452 .runevents__section-header .runevents__lead{ margin-top: var(--space-md, 1rem); }

#pb-452 .runevents__section-header--split{
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--space-lg, 1.5rem);
    flex-wrap: wrap;
}
#pb-452 .runevents__section-header--split > *{ flex: 1 1 18rem; }


/* ==========================================================================
   5. HERO — one column, text over the image. Never a two-cell split.
   ========================================================================== */

#pb-452 .runevents__hero{
    display: block;
    position: relative;
    isolation: isolate;
    overflow: clip;
    padding-block: clamp(3rem, 9cqi, 6rem);
    border-radius: var(--radius-lg, 16px);
}

#pb-452 .runevents__hero--compact{ padding-block: clamp(2.5rem, 7cqi, 4.5rem); }

#pb-452 .runevents__hero-media{
    position: absolute;
    inset: 0;
    z-index: -2;
    width: 100%;
    height: 100%;
    max-width: none;
    object-fit: cover;
    object-position: center 40%;
}

#pb-452 .runevents__hero-overlay{
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background:
        linear-gradient(100deg,
            color-mix(in srgb, var(--color-surface-dark, #23202a) 94%, transparent) 0%,
            color-mix(in srgb, var(--color-surface-dark, #23202a) 78%, transparent) 42%,
            color-mix(in srgb, var(--color-surface-dark, #23202a) 30%, transparent) 100%),
        linear-gradient(to top,
            color-mix(in srgb, var(--color-surface-dark, #23202a) 88%, transparent) 0%,
            transparent 48%);
}

#pb-452 .runevents__hero-inner{
    position: relative;
    max-width: 42ch;
    min-width: 0;
}

#pb-452 .runevents__hero-inner > * + *{ margin-top: var(--space-md, 1rem); }
#pb-452 .runevents__hero-inner > .runevents__display,#pb-452 .runevents__hero-inner > .runevents__display--breakout{ max-width: 13ch; }
#pb-452 .runevents__hero .runevents__lead{ max-width: 40ch; }

/* --- Hero variant: text beside an image, rather than over it -----------------
   Some sites want a split hero. It is a legitimate choice, not a mistake, so the
   vocabulary supports it explicitly instead of the base silently forcing one form.
   The two sides stack at narrow container widths so the headline never gets
   squeezed into a gutter. */
#pb-452 .runevents__hero--split{
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-xl, 3rem);
}
#pb-452 .runevents__hero--split > .runevents__hero-inner{
    flex: 1 1 22rem;
    max-width: none;
}
#pb-452 .runevents__hero--split > .runevents__hero-figure{
    flex: 1 1 18rem;
    min-width: 0;
    align-self: stretch;
}
#pb-452 .runevents__hero-figure{
    overflow: hidden;
    border-radius: var(--radius-lg, 16px);
    background: var(--color-surface-alt, #f5f4f7);
    min-height: clamp(12rem, 24cqi, 22rem);
}
#pb-452 :where(.runevents__hero-figure img){
    width: 100%;
    height: 100%;
    object-fit: cover;
}
/* A split hero has no background photo, so it needs no overlay and no motion offset. */
#pb-452 .runevents__hero--split > .runevents__hero-media,#pb-452 .runevents__hero--split > .runevents__hero-overlay{ display: none; }

/* Safety net: outside the split variant, a hero that receives a row collapses to
   one column — a two-cell hero at 780px squeezes the headline into a gutter. */
#pb-452 .runevents__hero:not(.runevents__hero--split) .runevents__row{ display: block; }
#pb-452 .runevents__hero:not(.runevents__hero--split) .runevents__row > .runevents__cell + .runevents__cell{ margin-top: var(--space-lg, 1.5rem); }


/* ==========================================================================
   6. STAT PANEL
   ========================================================================== */

/* R30 decoupling (v2 BEHAVIOR CHANGE): the panel defaults to a LIGHT surface driven by
   its own tokens. v1.x hard-coupled it to the dark-section pair, so a brief asking for
   "stats on a light card" had to fight the base. The dark treatment is now the explicit
   modifier `runevents__stat-panel--dark` below — recipes emit it when a dark panel is
   wanted. Internal hairlines follow currentColor so they survive either ground. */
#pb-452 .runevents__stat-panel{
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: var(--space-lg, 1.5rem);
    padding: var(--space-xl, 3rem);
    background: var(--stat-panel-bg, var(--color-surface, #ffffff));
    color: var(--stat-panel-color, var(--color-text, #1a181e));
    border: 1px solid var(--color-border, #e0dde5);
    border-radius: var(--radius-lg, 16px);
    box-shadow: var(--shadow-lg, 0 20px 50px rgba(20, 18, 24, 0.18));
}

/* The v1.x dark treatment, now opt-in. */
#pb-452 .runevents__stat-panel--dark{
    background: color-mix(in srgb, var(--color-text-on-surface-dark, #ffffff) 6%, var(--color-surface-dark, #23202a));
    color: var(--color-text-on-surface-dark, #ffffff);
    border-color: color-mix(in srgb, var(--color-text-on-surface-dark, #ffffff) 14%, transparent);
}

/* Lifts over the boundary of the section above it. */
#pb-452 .runevents__stat-panel--lift{
    position: relative;
    z-index: 2;
    margin-top: clamp(-3.5rem, -5cqi, -2rem);
}

#pb-452 .runevents__stat + .runevents__stat{
    border-left: 1px solid color-mix(in srgb, currentColor 16%, transparent);
    padding-left: var(--space-lg, 1.5rem);
}

#pb-452 .runevents__stat-figure{
    max-width: none;
    margin: 0;
    font-family: var(--font-heading, system-ui, sans-serif);
    font-size: var(--text-display, clamp(2rem, 5cqi, 3.25rem));
    font-weight: var(--font-weight-heading, 700);
    line-height: 1;
    letter-spacing: var(--tracking-display, -0.03em);
}

#pb-452 .runevents__stat-label{
    max-width: none;
    margin-top: var(--space-sm, 0.5rem);
    font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: var(--text-overline, 0.75rem);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    opacity: 0.7;
}

@container (max-width: 620px) {
    #pb-452 .runevents__stat-panel{ padding: var(--space-lg, 1.5rem); }
    #pb-452 .runevents__stat + .runevents__stat{ border-left: 0; padding-left: 0; }
}


/* ==========================================================================
   7. FACT — image + figure + line. The default content unit.
   ========================================================================== */

#pb-452 .runevents__fact-row{
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-lg, 1.5rem);
}

#pb-452 .runevents__fact{
    display: flex;
    flex-direction: column;
    flex: 1 1 16rem;
    min-width: 0;
    overflow: hidden;
    background: var(--color-surface, #ffffff);
    border: 1px solid var(--color-border, #e0dde5);
    border-radius: var(--radius-md, 8px);
    transition:
        transform var(--transition-base, 240ms ease),
        box-shadow var(--transition-base, 240ms ease),
        border-color var(--transition-fast, 160ms ease);
}

#pb-452 .runevents__fact:hover{
    transform: translateY(-4px);
    box-shadow: var(--shadow-md, 0 10px 30px rgba(20, 18, 24, 0.12));
    border-color: color-mix(in srgb, var(--color-primary, #4a4458) 45%, var(--color-border, #e0dde5));
}

#pb-452 .runevents__fact-media{
    aspect-ratio: 3 / 2;
    overflow: hidden;
    background: var(--color-surface-alt, #f5f4f7);
}

#pb-452 :where(.runevents__fact-media img){
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform var(--transition-base, 240ms ease);
}
#pb-452 .runevents__fact:hover .runevents__fact-media img{ transform: scale(1.04); }

#pb-452 .runevents__fact-body{ padding: var(--space-lg, 1.5rem); }
#pb-452 :where(.runevents__fact-body p){ margin-top: var(--space-sm, 0.5rem); max-width: none; }

#pb-452 .runevents__fact-figure{
    max-width: none;
    margin: 0;
    font-family: var(--font-heading, system-ui, sans-serif);
    font-size: var(--text-h1, clamp(1.75rem, 4.2cqi, 2.75rem));
    font-weight: var(--font-weight-heading, 700);
    line-height: 1;
    letter-spacing: var(--tracking-display, -0.03em);
    color: var(--color-primary, #4a4458);
}

#pb-452 .runevents__fact-label{
    max-width: none;
    margin-top: var(--space-xs, 0.25rem);
    font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: var(--text-overline, 0.75rem);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--color-text-muted, #56525e);
}

#pb-452 .runevents__section--dark .runevents__fact{
    background: color-mix(in srgb, var(--color-text-on-surface-dark, #ffffff) 6%, var(--color-surface-dark, #23202a));
    border-color: color-mix(in srgb, var(--color-text-on-surface-dark, #ffffff) 14%, transparent);
    color: inherit;
}
#pb-452 .runevents__section--dark .runevents__fact-figure{ color: var(--color-text-on-surface-dark, #ffffff); }
#pb-452 .runevents__section--dark .runevents__fact-label{ color: inherit; opacity: 0.7; }


/* ==========================================================================
   8. CARDS
   ========================================================================== */

#pb-452 .runevents__card-grid{
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-lg, 1.5rem);
}
#pb-452 .runevents__card-grid > *{ flex: 1 1 16rem; min-width: 0; }

#pb-452 .runevents__card{
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--color-surface, #ffffff);
    color: var(--color-text, #1a181e);
    border: 1px solid var(--color-border, #e0dde5);
    border-radius: var(--radius-md, 8px);
    box-shadow: var(--shadow-sm, 0 4px 16px rgba(20, 18, 24, 0.06));
    padding: var(--space-lg, 1.5rem);
    transition:
        transform var(--transition-base, 240ms ease),
        box-shadow var(--transition-base, 240ms ease),
        border-color var(--transition-fast, 160ms ease);
}

#pb-452 .runevents__card:hover{
    transform: translateY(-4px);
    box-shadow: var(--shadow-md, 0 10px 30px rgba(20, 18, 24, 0.12));
    border-color: color-mix(in srgb, var(--color-primary, #4a4458) 45%, var(--color-border, #e0dde5));
}

#pb-452 .runevents__card--flush{ padding: 0; }
#pb-452 .runevents__card--flush .runevents__card-body{ padding: var(--space-lg, 1.5rem); }

#pb-452 .runevents__card-media{
    overflow: hidden;
    aspect-ratio: 1 / 1;
    background: var(--color-surface-alt, #f5f4f7);
}
#pb-452 .runevents__card-media--wide{ aspect-ratio: 4 / 3; }

#pb-452 :where(.runevents__card-media img){
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform var(--transition-base, 240ms ease);
}
#pb-452 .runevents__card:hover .runevents__card-media img{ transform: scale(1.04); }

#pb-452 .runevents__card-body > * + *{ margin-top: var(--space-sm, 0.5rem); }
#pb-452 :where(.runevents__card p){ max-width: none; }

#pb-452 .runevents__card-more{
    display: flex;
    flex: 1 1 16rem;
    align-items: center;
    justify-content: center;
    min-height: 100%;
    padding: var(--space-lg, 1.5rem);
    border-radius: var(--radius-md, 8px);
    background: var(--color-primary, #4a4458);
    color: var(--color-text-on-primary, #ffffff);
    font-family: var(--font-heading, system-ui, sans-serif);
    font-size: clamp(1.0625rem, 1.9cqi, 1.375rem);
    font-weight: 700;
    text-align: center;
}

#pb-452 .runevents__section--dark .runevents__card{
    background: color-mix(in srgb, var(--color-text-on-surface-dark, #ffffff) 6%, var(--color-surface-dark, #23202a));
    border-color: color-mix(in srgb, var(--color-text-on-surface-dark, #ffffff) 14%, transparent);
    color: inherit;
}


/* ==========================================================================
   9. SPLIT — text beside a media panel that actually fills
   ========================================================================== */

#pb-452 .runevents__split{
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xl, 3rem);
    align-items: stretch;
}

#pb-452 .runevents__split-text{ flex: 1 1 22rem; min-width: 0; }
#pb-452 .runevents__split-media{ flex: 1 1 18rem; min-width: 0; }
#pb-452 .runevents__split-text > * + *{ margin-top: var(--space-md, 1rem); }
#pb-452 :where(.runevents__split-text p){ max-width: 58ch; }


/* ==========================================================================
   10. MEDIA FRAME — always fills its cell, never a floating rectangle
   ========================================================================== */

#pb-452 .runevents__media-frame{
    height: 100%;
    min-height: clamp(12rem, 24cqi, 20rem);
    overflow: hidden;
    border-radius: var(--radius-lg, 16px);
    background: var(--color-surface-alt, #f5f4f7);
}

#pb-452 :where(.runevents__media-frame img){
    width: 100%;
    height: 100%;
    object-fit: cover;
}

#pb-452 .runevents__media-frame--wide{ height: auto; min-height: 0; }
#pb-452 :where(.runevents__media-frame--wide img){ aspect-ratio: 16 / 9; height: auto; }
#pb-452 .runevents__media-frame--tall{ height: auto; min-height: 0; }
#pb-452 :where(.runevents__media-frame--tall img){ aspect-ratio: 4 / 5; height: auto; }


/* ==========================================================================
   11. AGENDA ROW — rows, not cards
   ========================================================================== */

#pb-452 .runevents__agenda-row{
    display: grid;
    grid-template-columns: 6rem 1fr auto;
    gap: var(--space-lg, 1.5rem);
    align-items: baseline;
    padding: var(--space-lg, 1.5rem) var(--space-md, 1rem);
    border-top: 1px solid color-mix(in srgb, var(--color-text, #1a181e) 12%, transparent);
    transition: background-color var(--transition-fast, 160ms ease);
}

#pb-452 .runevents__agenda-row:last-of-type{
    border-bottom: 1px solid color-mix(in srgb, var(--color-text, #1a181e) 12%, transparent);
}
#pb-452 .runevents__agenda-row:hover{ background: var(--color-surface-alt, #f5f4f7); }
#pb-452 .runevents__agenda-row .runevents__time{ font-weight: 500; color: var(--color-text, #1a181e); }
#pb-452 :where(.runevents__agenda-row p){ max-width: 60ch; }

@container (max-width: 720px) {
    #pb-452 .runevents__agenda-row{ grid-template-columns: 1fr; gap: var(--space-sm, 0.5rem); }
}

#pb-452 .runevents__badge{
    display: inline-flex;
    align-items: center;
    padding: 0.25rem 0.5rem;
    border: 1px solid var(--color-border, #e0dde5);
    border-left: 2px solid var(--color-primary, #4a4458);
    border-radius: var(--radius-sm, 4px);
    font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: var(--text-overline, 0.75rem);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--color-text-muted, #56525e);
}

#pb-452 .runevents__section--dark .runevents__badge{
    border-color: color-mix(in srgb, var(--color-text-on-surface-dark, #ffffff) 14%, transparent);
    border-left-color: var(--color-accent, #8a7f96);
    color: inherit;
}


/* ==========================================================================
   12. QUOTE
   ========================================================================== */

#pb-452 .runevents__quote{
    max-width: 24ch;
    margin: 0;
    font-family: var(--font-heading, system-ui, sans-serif);
    font-size: var(--text-h2, clamp(1.5rem, 3.4cqi, 2.25rem));
    font-weight: var(--font-weight-heading, 600);
    line-height: 1.25;
    letter-spacing: -0.015em;
    text-wrap: balance;
}

#pb-452 .runevents__quote--wide{ max-width: 34ch; }

#pb-452 .runevents__quote-cite{
    display: block;
    margin-top: var(--space-lg, 1.5rem);
    padding-top: var(--space-md, 1rem);
    border-top: 1px solid color-mix(in srgb, currentColor 25%, transparent);
    font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: 0.8125rem;
    font-style: normal;
    letter-spacing: 0.04em;
    opacity: 0.75;
}


/* ==========================================================================
   13. LOGOS
   ========================================================================== */

#pb-452 .runevents__logo-row{
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-lg, 1.5rem);
}

#pb-452 .runevents__logo-frame{
    display: grid;
    place-items: center;
    flex: 1 1 12rem;
    height: 6rem;
    padding: var(--space-lg, 1.5rem);
    background: var(--color-surface, #ffffff);
    border: 1px solid var(--color-border, #e0dde5);
    border-radius: var(--radius-md, 8px);
}

#pb-452 :where(.runevents__logo-frame img){
    max-height: 100%;
    width: auto;
    object-fit: contain;
}


/* ==========================================================================
   14. TIERS — pricing / ticket types
   ========================================================================== */

#pb-452 .runevents__tier-row{
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-lg, 1.5rem);
    align-items: stretch;
}

#pb-452 .runevents__tier{
    display: flex;
    flex-direction: column;
    flex: 1 1 16rem;
    min-width: 0;
    padding: var(--space-xl, 3rem) var(--space-lg, 1.5rem);
    background: var(--color-surface, #ffffff);
    border: 1px solid var(--color-border, #e0dde5);
    border-radius: var(--radius-md, 8px);
    transition:
        transform var(--transition-base, 240ms ease),
        box-shadow var(--transition-base, 240ms ease),
        border-color var(--transition-fast, 160ms ease);
}

#pb-452 .runevents__tier:hover{
    transform: translateY(-4px);
    box-shadow: var(--shadow-md, 0 10px 30px rgba(20, 18, 24, 0.12));
}

#pb-452 .runevents__tier--featured{
    border-color: var(--color-primary, #4a4458);
    border-width: 2px;
    box-shadow: var(--shadow-md, 0 10px 30px rgba(20, 18, 24, 0.12));
}

#pb-452 .runevents__tier-name{
    margin: 0;
    font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: var(--text-overline, 0.75rem);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--color-text-muted, #56525e);
}

#pb-452 .runevents__tier-price{
    max-width: none;
    margin-top: var(--space-sm, 0.5rem);
    font-family: var(--font-heading, system-ui, sans-serif);
    font-size: var(--text-display, clamp(2rem, 5cqi, 3.25rem));
    font-weight: var(--font-weight-heading, 700);
    line-height: 1;
    letter-spacing: var(--tracking-display, -0.03em);
    color: var(--color-primary, #4a4458);
}

#pb-452 .runevents__tier-features{
    margin-top: var(--space-lg, 1.5rem);
    padding-left: 1.25rem;
}
#pb-452 :where(.runevents__tier-features li + li){ margin-top: var(--space-sm, 0.5rem); }

#pb-452 .runevents__tier .runevents__btn-row{ margin-top: auto; padding-top: var(--space-lg, 1.5rem); }

#pb-452 .runevents__section--dark .runevents__tier{
    background: color-mix(in srgb, var(--color-text-on-surface-dark, #ffffff) 6%, var(--color-surface-dark, #23202a));
    border-color: color-mix(in srgb, var(--color-text-on-surface-dark, #ffffff) 14%, transparent);
    color: inherit;
}
#pb-452 .runevents__section--dark .runevents__tier-price{ color: var(--color-text-on-surface-dark, #ffffff); }


/* ==========================================================================
   15. FAQ — built on <details>/<summary>. No JavaScript.
   ========================================================================== */

#pb-452 .runevents__faq-list{
    display: flex;
    flex-direction: column;
    border-top: 1px solid color-mix(in srgb, var(--color-text, #1a181e) 12%, transparent);
}

#pb-452 .runevents__faq-item{
    border-bottom: 1px solid color-mix(in srgb, var(--color-text, #1a181e) 12%, transparent);
}

#pb-452 .runevents__faq-question{
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md, 1rem);
    padding: var(--space-lg, 1.5rem) var(--space-md, 1rem);
    cursor: pointer;
    list-style: none;
    font-family: var(--font-heading, system-ui, sans-serif);
    font-size: clamp(1.0625rem, 1.9cqi, 1.375rem);
    font-weight: 600;
    line-height: 1.3;
    transition: background-color var(--transition-fast, 160ms ease);
}

#pb-452 .runevents__faq-question::-webkit-details-marker{ display: none; }
#pb-452 .runevents__faq-question:hover{ background: var(--color-surface-alt, #f5f4f7); }

/* Chevron built from a border — no icon font dependency. */
#pb-452 .runevents__faq-question::after{
    content: "";
    flex: none;
    width: 0.6em;
    height: 0.6em;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(45deg) translate(-0.15em, -0.15em);
    transition: transform var(--transition-fast, 160ms ease);
    opacity: 0.55;
}

#pb-452 .runevents__faq-item[open] > .runevents__faq-question::after{
    transform: rotate(-135deg) translate(-0.15em, -0.15em);
}

#pb-452 .runevents__faq-answer{
    padding: 0 var(--space-md, 1rem) var(--space-lg, 1.5rem);
    max-width: 68ch;
}

#pb-452 .runevents__section--dark .runevents__faq-list,#pb-452 .runevents__section--dark .runevents__faq-item{
    border-color: color-mix(in srgb, var(--color-text-on-surface-dark, #ffffff) 14%, transparent);
}
#pb-452 .runevents__section--dark .runevents__faq-question:hover{
    background: color-mix(in srgb, var(--color-text-on-surface-dark, #ffffff) 6%, transparent);
}


/* ==========================================================================
   16. CHROME — header / footer.
   These render as SIBLINGS of <main>, not inside a section, so they carry
   their own frame and must never depend on a page-level ancestor.
   ========================================================================== */

#pb-452 .runevents__header,#pb-452 .runevents__footer{
    container-type: inline-size;
    box-sizing: border-box;
    width: 100%;
    max-width: var(--page-max, 1120px);
    margin-inline: auto;
    padding-inline: var(--gutter, 2rem);
    font-family: var(--font-body, system-ui, sans-serif);
}

#pb-452 .runevents__header *,#pb-452 .runevents__footer *{ box-sizing: border-box; }

#pb-452 .runevents__header{
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md, 1rem);
    padding-block: var(--space-md, 1rem);
    background-color: var(--color-bg, #fcfcfd);
    color: var(--color-text, #1a181e);
    border-bottom: 1px solid var(--color-border, #e0dde5);
}

#pb-452 .runevents__header-brand{ display: flex; align-items: center; gap: var(--space-sm, 0.5rem); }
#pb-452 :where(.runevents__header-brand img){ max-height: 2.5rem; width: auto; }

#pb-452 .runevents__header-nav{
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-lg, 1.5rem);
}

#pb-452 :where(.runevents__header-nav a){
    color: inherit;
    text-decoration: none;
    font-weight: 500;
    transition: opacity var(--transition-fast, 160ms ease);
}
#pb-452 :where(.runevents__header-nav a:hover){ opacity: 0.7; }

/* R30 decoupling (v2): the footer's ground and ink no longer ride the section-dark
   tokens as a coupled pair — --footer-bg / --footer-color override independently.
   Fallbacks keep the v1.4 rendering. */
#pb-452 .runevents__footer{
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xl, 3rem);
    padding-block: var(--space-2xl, 5rem);
    background-color: var(--footer-bg, var(--color-surface-dark, #23202a));
    color: var(--footer-color, var(--color-text-on-surface-dark, #ffffff));
    border-radius: var(--radius-lg, 16px);
}

#pb-452 .runevents__footer-col{ flex: 1 1 14rem; min-width: 0; }
#pb-452 .runevents__footer-col > * + *{ margin-top: var(--space-sm, 0.5rem); }

#pb-452 .runevents__footer-links{ list-style: none; margin: 0; padding: 0; }
#pb-452 :where(.runevents__footer-links li + li){ margin-top: var(--space-sm, 0.5rem); }
#pb-452 :where(.runevents__footer-links a){
    color: inherit;
    text-decoration: none;
    opacity: 0.8;
    transition: opacity var(--transition-fast, 160ms ease);
}
#pb-452 :where(.runevents__footer-links a:hover){ opacity: 1; }

#pb-452 .runevents__footer-legal{
    flex: 1 1 100%;
    padding-top: var(--space-lg, 1.5rem);
    border-top: 1px solid color-mix(in srgb, var(--color-text-on-surface-dark, #ffffff) 14%, transparent);
    font-size: 0.8125rem;
    opacity: 0.7;
}


/* ==========================================================================
   17. BUTTONS
   ========================================================================== */

#pb-452 .runevents__btn{
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    padding: 0 var(--space-lg, 1.5rem);
    border: 1px solid transparent;
    border-radius: var(--radius-md, 8px);
    font-family: var(--font-body, system-ui, sans-serif);
    font-weight: 600;
    line-height: 1;
    text-decoration: none;
    cursor: pointer;
    transition:
        background-color var(--transition-fast, 160ms ease),
        border-color var(--transition-fast, 160ms ease),
        color var(--transition-fast, 160ms ease),
        transform var(--transition-fast, 160ms ease);
}

#pb-452 .runevents__btn:hover{ transform: translateY(-1px); }

#pb-452 .runevents__btn--primary{
    background-color: var(--color-primary, #4a4458);
    color: var(--color-text-on-primary, #ffffff);
}
#pb-452 .runevents__btn--primary:hover{
    background-color: var(--color-primary-hover, #3a3546);
    color: var(--color-text-on-primary, #ffffff);
}

#pb-452 .runevents__btn--outline{
    background-color: transparent;
    border-color: var(--color-border, #e0dde5);
    color: var(--color-primary, #4a4458);
}
#pb-452 .runevents__btn--outline:hover{
    background-color: var(--color-primary-hover, #3a3546);
    border-color: var(--color-primary-hover, #3a3546);
    color: var(--color-text-inverse, #ffffff);
}

#pb-452 .runevents__btn--lg{ min-height: 52px; padding: 0 var(--space-xl, 3rem); font-size: 1.0625rem; }
#pb-452 .runevents__btn--small{ min-height: 36px; padding: 0 var(--space-md, 1rem); font-size: 0.875rem; }

/* A primary button KEEPS its brand colour on a dark ground.
   v1 inverted it to white here at (0,2,0), which outranks a guideline's own
   `.runevents__btn--primary { background: var(--color-primary) }` at (0,1,0) whatever the source
   order — so on any page whose only primary buttons sit in the hero and the closing CTA (the
   common shape), the brand colour vanished from the page entirely. That is the base making a
   design decision the guideline cannot reverse, which is exactly what this layer must not do.
   A guideline that WANTS the inverted treatment sets --btn-primary-bg-on-dark. */
#pb-452 .runevents__section--dark .runevents__btn--primary{
    background-color: var(--btn-primary-bg-on-dark, var(--color-primary, #4a4458));
    color: var(--btn-primary-text-on-dark, var(--color-text-on-primary, #ffffff));
}
#pb-452 .runevents__section--dark .runevents__btn--outline{
    border-color: var(--color-text-on-surface-dark, #ffffff);
    color: var(--color-text-on-surface-dark, #ffffff);
}
#pb-452 .runevents__section--dark .runevents__btn--outline:hover{
    background-color: var(--color-text-on-surface-dark, #ffffff);
    color: var(--color-surface-dark, #23202a);
}

#pb-452 .runevents__btn-row{
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-md, 1rem);
    margin-top: var(--space-lg, 1.5rem);
}
#pb-452 .runevents__btn-row .runevents__btn{ flex: 0 1 auto; }

/* Centred variant — used by the closing CTA. Exists so no recipe ever needs an
   inline style="justify-content:center", which the vocabulary contract forbids. */
#pb-452 .runevents__btn-row--center{ justify-content: center; }

@container (max-width: 420px) {
    #pb-452 .runevents__btn-row{ flex-direction: column; }
    #pb-452 .runevents__btn-row .runevents__btn{ width: 100%; }
}


/* ==========================================================================
   17b. DIVIDER — the editor's Divider block. Rule colour follows the guideline.
   ========================================================================== */

#pb-452 .runevents__divider{
    border: 0;
    border-top: 1px solid color-mix(in srgb, currentColor 18%, transparent);
    margin-block: var(--space-lg, 1.5rem);
}


/* ==========================================================================
   18. WIDGET — sealed third-party run.events web components.
   We own the box it sits in, never its internals.
   ========================================================================== */

#pb-452 .runevents__widget{
    display: block;
    width: 100%;
    min-width: 0;
}

#pb-452 .runevents__widget > *{ max-width: 100%; }


/* ==========================================================================
   18b. FORM — contact, enquiry, RSVP, newsletter.
   PART 1 of the page contract states form accessibility rules, so the vocabulary
   must be able to emit a form. Every value is a token, like everything else.
   ========================================================================== */

#pb-452 .runevents__form{
    display: flex;
    flex-direction: column;
    gap: var(--space-lg, 1.5rem);
    max-width: var(--measure-form, 40rem);
}

#pb-452 .runevents__field{
    display: flex;
    flex-direction: column;
    gap: var(--space-xs, 0.25rem);
}

#pb-452 .runevents__field--inline{ flex-direction: row; align-items: center; gap: var(--space-sm, 0.5rem); }

#pb-452 .runevents__label{
    font-family: var(--font-body, system-ui, sans-serif);
    font-size: var(--text-small, 0.875rem);
    font-weight: 600;
    color: var(--color-text, #1a181e);
}

#pb-452 .runevents__input,#pb-452 .runevents__textarea,#pb-452 .runevents__select{
    width: 100%;
    min-height: 44px;
    padding: 0.75rem 0.875rem;
    font-family: var(--font-body, system-ui, sans-serif);
    font-size: var(--text-body, 1rem);
    background-color: var(--color-surface, #ffffff);
    color: var(--color-text, #1a181e);
    border: 1px solid var(--color-border, #e0dde5);
    border-radius: var(--radius-md, 8px);
    transition:
        border-color var(--transition-fast, 160ms ease),
        box-shadow var(--transition-fast, 160ms ease);
}

#pb-452 .runevents__textarea{ min-height: 8rem; resize: vertical; }

#pb-452 .runevents__field-hint{
    font-size: var(--text-small, 0.875rem);
    color: var(--color-text-muted, #56525e);
}

#pb-452 .runevents__field-error{
    font-size: var(--text-small, 0.875rem);
    color: var(--color-error, #d92d20);
}

#pb-452 .runevents__section--dark .runevents__label{ color: inherit; }
#pb-452 .runevents__section--dark .runevents__input,#pb-452 .runevents__section--dark .runevents__textarea,#pb-452 .runevents__section--dark .runevents__select{
    background-color: color-mix(in srgb, var(--color-text-on-surface-dark, #ffffff) 8%, transparent);
    border-color: color-mix(in srgb, var(--color-text-on-surface-dark, #ffffff) 20%, transparent);
    color: inherit;
}


/* ==========================================================================
   18c. EMBED — video, map, or any third-party iframe.
   Responsive by aspect-ratio; needs no JavaScript.
   ========================================================================== */

#pb-452 .runevents__embed{
    position: relative;
    width: 100%;
    aspect-ratio: var(--embed-ratio, 16 / 9);
    overflow: hidden;
    border-radius: var(--radius-lg, 16px);
    background: var(--color-surface-alt, #f5f4f7);
}

#pb-452 .runevents__embed iframe,#pb-452 .runevents__embed video{
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

#pb-452 .runevents__embed--square{ --embed-ratio: 1 / 1; }
#pb-452 .runevents__embed--tall{ --embed-ratio: 4 / 5; }


/* ==========================================================================
   19. BENTO GRID — dense mixed-size mosaic (v2)
   Opt-in machinery for mixing media, stats and copy in one composition.
   Column count is token-driven and clamps with container width; cells opt into
   spans. `grid-auto-flow: dense` backfills the gaps the spans leave.
   ========================================================================== */

#pb-452 .runevents__bento{
    display: grid;
    grid-template-columns: repeat(var(--bento-cols, 3), minmax(0, 1fr));
    grid-auto-rows: minmax(var(--bento-row-min, 10rem), auto);
    grid-auto-flow: dense;
    gap: var(--space-lg, 1.5rem);
}

#pb-452 .runevents__bento-cell{
    display: flex;
    flex-direction: column;
    gap: var(--space-sm, 0.5rem);
    min-width: 0;
    overflow: clip;
    padding: var(--space-lg, 1.5rem);
    background: var(--color-surface, #ffffff);
    border: 1px solid var(--color-border, #e0dde5);
    border-radius: var(--radius-lg, 16px);
}

#pb-452 .runevents__bento-cell--wide{ grid-column: span 2; }
#pb-452 .runevents__bento-cell--tall{ grid-row: span 2; }
#pb-452 .runevents__bento-cell--2x{ grid-column: span 2; grid-row: span 2; }

/* A media cell: the image (or media frame) fills it edge to edge. */
#pb-452 .runevents__bento-cell--media{ padding: 0; }
#pb-452 .runevents__bento-cell--media > *{ flex: 1 1 auto; height: 100%; min-height: 0; border-radius: 0; }
#pb-452 :where(.runevents__bento-cell--media img){ width: 100%; height: 100%; object-fit: cover; }

/* Centres a numeral, a logo or a short statement inside its cell. */
#pb-452 .runevents__bento-cell--center{
    align-items: center;
    justify-content: center;
    text-align: center;
}

/* Token-driven dark cell — modern bentos mix grounds. Same decoupled pair as
   the dark section, so a brief can retint cells without touching sections. */
#pb-452 .runevents__bento-cell--dark{
    background: var(--section-dark-bg, var(--color-surface-dark, #23202a));
    color: var(--section-dark-color, var(--color-text-on-surface-dark, #ffffff));
    border-color: color-mix(in srgb, var(--color-text-on-surface-dark, #ffffff) 14%, transparent);
}

#pb-452 .runevents__section--dark .runevents__bento-cell{
    background: color-mix(in srgb, var(--color-text-on-surface-dark, #ffffff) 6%, var(--color-surface-dark, #23202a));
    border-color: color-mix(in srgb, var(--color-text-on-surface-dark, #ffffff) 14%, transparent);
    color: inherit;
}

@container (max-width: 900px) {
    #pb-452 .runevents__bento{ grid-template-columns: repeat(var(--bento-cols-md, 2), minmax(0, 1fr)); }
}

@container (max-width: 620px) {
    #pb-452 .runevents__bento{ grid-template-columns: minmax(0, 1fr); grid-auto-rows: auto; }
    #pb-452 .runevents__bento-cell--wide,#pb-452 .runevents__bento-cell--2x{ grid-column: auto; }
    #pb-452 .runevents__bento-cell--tall,#pb-452 .runevents__bento-cell--2x{ grid-row: auto; }
}


/* ==========================================================================
   20. OVERLAP — media with a content panel riding its edge (v2)
   Grid-layered: the media block extends UNDER the panel by --overlap-amount.
   Collapses to a stacked composition below a container threshold.
   ========================================================================== */

#pb-452 .runevents__overlap{
    display: grid;
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    align-items: center;
}

#pb-452 .runevents__overlap-media{
    grid-column: 1;
    grid-row: 1;
    align-self: stretch;
    min-height: clamp(16rem, 42cqi, 30rem);
    margin-inline-end: calc(-1 * var(--overlap-amount, 4rem));
    overflow: hidden;
    border-radius: var(--radius-lg, 16px);
    background: var(--color-surface-alt, #f5f4f7);
}

#pb-452 :where(.runevents__overlap-media img){
    width: 100%;
    height: 100%;
    object-fit: cover;
}

#pb-452 .runevents__overlap-panel{
    position: relative;
    z-index: 2;
    grid-column: 2;
    grid-row: 1;
    padding: var(--space-xl, 3rem);
    background: var(--panel-bg, var(--color-surface, #ffffff));
    color: var(--panel-color, var(--color-text, #1a181e));
    border-radius: var(--radius-lg, 16px);
    box-shadow: var(--shadow-lg, 0 20px 50px rgba(20, 18, 24, 0.18));
}

#pb-452 .runevents__overlap-panel > * + *{ margin-top: var(--space-md, 1rem); }

/* Panel on the left, media on the right. */
#pb-452 .runevents__overlap--reverse{ grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
#pb-452 .runevents__overlap--reverse .runevents__overlap-media{
    grid-column: 2;
    margin-inline-end: 0;
    margin-inline-start: calc(-1 * var(--overlap-amount, 4rem));
}
#pb-452 .runevents__overlap--reverse .runevents__overlap-panel{ grid-column: 1; }

@container (max-width: 700px) {
    #pb-452 .runevents__overlap,#pb-452 .runevents__overlap--reverse{ grid-template-columns: minmax(0, 1fr); }
    #pb-452 .runevents__overlap-media,#pb-452 .runevents__overlap--reverse .runevents__overlap-media{
        grid-column: 1;
        grid-row: 1;
        margin-inline: 0;
        min-height: clamp(12rem, 40cqi, 18rem);
    }
    #pb-452 .runevents__overlap-panel,#pb-452 .runevents__overlap--reverse .runevents__overlap-panel{
        grid-column: 1;
        grid-row: 2;
        margin-inline: var(--space-md, 1rem);
        margin-top: calc(-1 * var(--space-xl, 3rem));
    }
}


/* ==========================================================================
   21. STICKY PAIR — pinned media beside scrolling copy (v2)
   position: sticky only — NEVER fixed. Auto-disabled in narrow containers,
   which includes every EMBEDDED page: inside a Smart Hub column the HOST page
   owns the scroll, and a sticky child there is broken UX (see LayoutModes.md).
   ========================================================================== */

#pb-452 .runevents__sticky-pair{
    display: flex;
    flex-direction: column;
    gap: var(--space-xl, 3rem);
}

#pb-452 .runevents__sticky-media{ min-width: 0; }
#pb-452 .runevents__sticky-copy{ min-width: 0; }
#pb-452 .runevents__sticky-copy > * + *{ margin-top: var(--space-md, 1rem); }

/* 72rem is wider than any Smart Hub column (~700-1120px), so only CONTAINED and
   FULL-WIDTH pages ever activate the sticky column. */
@container (min-width: 72rem) {
    #pb-452 .runevents__sticky-pair{
        display: grid;
        grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
        align-items: start;
    }
    #pb-452 .runevents__sticky-pair--reverse{ grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
    #pb-452 .runevents__sticky-pair--reverse > .runevents__sticky-media{ order: 2; }
    #pb-452 .runevents__sticky-media{
        position: sticky;
        top: var(--sticky-offset, 2rem);
    }
}


/* ==========================================================================
   22. IMAGE TREATMENTS — opt-in modifiers for treated imagery (v2)
   Every modifier is self-sufficient: it composes with .runevents__media-frame
   but also works on .runevents__card-media / .runevents__fact-media, so a
   recipe can treat any media block without restructuring it.
   ========================================================================== */

/* Tint: an overlay layer, fully token-driven. The default renders NOTHING —
   the guideline supplies --media-tint (and optionally --media-blend) for the
   duotone-like look. */
#pb-452 .runevents__media-frame--tint{ position: relative; }
#pb-452 .runevents__media-frame--tint::after{
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    border-radius: inherit;
    background: var(--media-tint, transparent);
    mix-blend-mode: var(--media-blend, multiply);
}

/* Thick frame: a deliberate border; width and colour come from the guideline. */
#pb-452 .runevents__media-frame--frame-thick{
    border: var(--frame-width, 0.5rem) solid var(--frame-color, var(--color-text, #1a181e));
}

/* Masks: clip-path from the --mask-shape token. The generic modifier consumes
   whatever shape the guideline supplies; the presets seed --mask-shape and the
   guideline can still override the token on the same element. */
#pb-452 .runevents__media-frame--mask,#pb-452 .runevents__media-frame--mask-arch,#pb-452 .runevents__media-frame--mask-blob{
    clip-path: var(--mask-shape, none);
}
#pb-452 .runevents__media-frame--mask-arch{ --mask-shape: inset(0 round 50% 50% var(--radius-lg, 16px) var(--radius-lg, 16px)); }
#pb-452 .runevents__media-frame--mask-blob{ --mask-shape: inset(0 round 62% 38% 54% 46% / 48% 58% 42% 52%); }

/* Offset: the frame sits over a solid offset block. The margins reserve the
   room so the block never collides with a neighbour. */
#pb-452 .runevents__media-frame--offset{
    position: relative;
    margin-inline-end: var(--frame-offset, 0.75rem);
    margin-block-end: var(--frame-offset, 0.75rem);
    box-shadow: var(--frame-offset, 0.75rem) var(--frame-offset, 0.75rem) 0 0 var(--frame-offset-color, var(--color-accent, #8a7f96));
}


/* ==========================================================================
   23. SECTION BANDS + SHAPED DIVIDERS (v2)
   --band is an edge-to-edge tinted ground. The base stays viewport-unit-free:
   the ONLY bleed it applies is the --bleed token, which the guideline sets per
   layout mode (EMBEDDED: always 0; CONTAINED: may go negative; FULL-WIDTH: 0 —
   see LayoutModes.md). The padding-inline max() keeps the content at the
   gutter even when the ground bleeds past it. Combining --band with --dark:
   set --band-bg to the dark ground (the band's ground wins by source order).
   ========================================================================== */

#pb-452 .runevents__section--band{
    max-width: none;
    border-radius: 0;
    margin-inline: var(--bleed, 0);
    padding-inline: max(var(--gutter, 2rem), calc(0px - var(--bleed, 0px)));
    background-color: var(--band-bg, var(--color-surface-alt, #f5f4f7));
}

/* Token-driven gradient ground for any section — pairs well with --band and
   the closing CTA. The neutral fallback is a whisper, not an opinion. */
#pb-452 .runevents__section--gradient{
    background: var(--section-gradient, linear-gradient(120deg, var(--color-surface-alt, #f5f4f7), var(--color-bg, #fcfcfd)));
}

/* Shaped dividers: a standalone <hr class="runevents__divider runevents__divider--slant">
   between sections. The shape is a clip-path on ::after; height and fill are tokens. */
#pb-452 .runevents__divider--slant,#pb-452 .runevents__divider--curve,#pb-452 .runevents__divider--fade{
    border: 0;
    width: 100%;
    height: var(--divider-height, 4rem);
    margin-block: 0;
    overflow: hidden;
}

#pb-452 .runevents__divider--slant::after,#pb-452 .runevents__divider--curve::after,#pb-452 .runevents__divider--fade::after{
    content: "";
    display: block;
    width: 100%;
    height: 100%;
    background: var(--divider-bg, var(--color-surface-alt, #f5f4f7));
}

#pb-452 .runevents__divider--slant::after{ clip-path: polygon(0 100%, 100% 0, 100% 100%); }
#pb-452 .runevents__divider--curve::after{ clip-path: ellipse(75% 100% at 50% 100%); }
#pb-452 .runevents__divider--fade::after{ background: linear-gradient(to bottom, transparent, var(--divider-bg, var(--color-surface-alt, #f5f4f7))); }

/* Mirrors any shaped divider for the opposite transition. */
#pb-452 .runevents__divider--flip::after{ transform: scale(-1); }

@media (max-width: 640px) {
    #pb-452 .runevents__section--band{ padding-inline: max(var(--gutter-sm, 1.25rem), calc(0px - var(--bleed, 0px))); }
}


/* ==========================================================================
   24. BIG NUMERALS — display-scale figures for stats that deserve drama (v2)
   Content rule (PART 1 of the page contract): a numeral is NEVER invented —
   no real figure, no numeral component.
   ========================================================================== */

#pb-452 .runevents__numeral-row{
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-xl, 3rem) var(--space-2xl, 5rem);
}

#pb-452 .runevents__numeral-row > *{ min-width: 0; }

#pb-452 .runevents__numeral{
    max-width: none;
    margin: 0;
    font-family: var(--font-heading, system-ui, sans-serif);
    font-size: var(--text-numeral, clamp(3rem, 9cqi, 6rem));
    font-weight: var(--font-weight-heading, 700);
    line-height: 0.95;
    letter-spacing: var(--tracking-display, -0.03em);
    font-variant-numeric: tabular-nums;
}

#pb-452 .runevents__numeral--accent{ color: var(--color-primary, #4a4458); }

#pb-452 .runevents__numeral-label{
    max-width: none;
    margin-top: var(--space-sm, 0.5rem);
    font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: var(--text-overline, 0.75rem);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--color-text-muted, #56525e);
}

/* Hairlines between figures — currentColor, so they survive any ground. */
#pb-452 .runevents__numeral-row--divided > * + *{
    border-left: 1px solid color-mix(in srgb, currentColor 18%, transparent);
    padding-left: var(--space-xl, 3rem);
}

#pb-452 .runevents__section--dark .runevents__numeral--accent{ color: var(--color-text-on-surface-dark, #ffffff); }
#pb-452 .runevents__section--dark .runevents__numeral-label{ color: inherit; opacity: 0.7; }

@container (max-width: 620px) {
    #pb-452 .runevents__numeral-row{ gap: var(--space-lg, 1.5rem); }
    #pb-452 .runevents__numeral-row--divided > * + *{ border-left: 0; padding-left: 0; }
}


/* ==========================================================================
   25. LOGO STRIP — a quieter, frameless alternative to the logo row (v2)
   Static by default. --flow turns it into a CSS-only marquee: the recipe emits
   the SAME track twice (the copy aria-hidden="true") so the loop is seamless.
   The animation itself lives in the MOTION section — one place, one kill
   switch. PAGE-CONTENT logos only — run.events widgets stay untouched (L10).
   ========================================================================== */

#pb-452 .runevents__logo-strip{
    display: flex;
    align-items: center;
    gap: var(--space-xl, 3rem);
}

#pb-452 .runevents__logo-strip-track{
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-xl, 3rem);
    min-width: 0;
}

#pb-452 :where(.runevents__logo-strip img){
    max-height: 3rem;
    width: auto;
    object-fit: contain;
}

/* Muted treatment: logos rest quiet, wake on hover. Token-driven filter. */
#pb-452 .runevents__logo-strip--muted :where(img){
    filter: var(--logo-filter, grayscale(1));
    opacity: 0.72;
    transition: filter var(--transition-fast, 160ms ease), opacity var(--transition-fast, 160ms ease);
}
#pb-452 .runevents__logo-strip--muted :where(img:hover){
    filter: none;
    opacity: 1;
}

#pb-452 .runevents__logo-strip--flow{
    overflow: hidden;
    flex-wrap: nowrap;
}
#pb-452 .runevents__logo-strip--flow .runevents__logo-strip-track{
    flex: none;
    flex-wrap: nowrap;
    justify-content: space-around;
    min-width: 100%;
    width: max-content;
}


/* ==========================================================================
   26. TYPE + HERO EXTRAS (v2)
   ========================================================================== */

/* One display step above --text-display, for statement openers. */
#pb-452 .runevents__display--xl{
    font-size: var(--text-display-xl, clamp(2.75rem, 8.5cqi, 5.75rem));
    line-height: 0.92;
    letter-spacing: var(--tracking-display, -0.04em);
    max-width: var(--measure-display, 13ch);
}

/* Outline display text. @supports-gated: without text-stroke support the text
   simply renders solid — never invisible. */
@supports (-webkit-text-stroke: 1px) {
    #pb-452 .runevents__display--outline{
        -webkit-text-stroke: var(--stroke-width, 0.045em) currentColor;
        color: transparent;
    }
}

/* Gradient text. The solid colour is the fallback for engines without
   background-clip: text — the content is always legible. The inverted-section
   re-assertions below must sit AFTER the (0,2,0) colour-inherit rules in
   section 1, or a dark hero would flatten the gradient back to solid ink. */
#pb-452 .runevents__text-gradient{ color: var(--color-primary, #4a4458); }
@supports ((background-clip: text) or (-webkit-background-clip: text)) {
    #pb-452 .runevents__text-gradient{
        background: var(--text-gradient, linear-gradient(94deg, var(--color-primary, #4a4458), var(--color-accent, #8a7f96)));
        -webkit-background-clip: text;
        background-clip: text;
        color: transparent;
    }
    #pb-452 .runevents__section--dark .runevents__text-gradient,#pb-452 .runevents__section--primary .runevents__text-gradient,#pb-452 .runevents__section--secondary .runevents__text-gradient{ color: transparent; }
}

/* Eyebrow with a rule extending to the content edge. */
#pb-452 .runevents__eyebrow--rule::after{
    content: "";
    flex: 1 1 2rem;
    height: 2px;
    background: color-mix(in srgb, currentColor 25%, transparent);
}

/* Hero on a token-driven gradient ground — no photo required. Combine with
   --dark for inverted ink; media/overlay slots are ignored if present. */
#pb-452 .runevents__hero--gradient{
    background: var(--hero-gradient, linear-gradient(120deg, var(--color-surface-dark, #23202a), color-mix(in srgb, var(--color-primary, #4a4458) 55%, var(--color-surface-dark, #23202a))));
}
#pb-452 .runevents__hero--gradient > .runevents__hero-media,#pb-452 .runevents__hero--gradient > .runevents__hero-overlay{ display: none; }

/* A taller opener for splashy pages; parallel to --compact. */
#pb-452 .runevents__hero--tall{ padding-block: clamp(4rem, 14cqi, 9rem); }


/* ==========================================================================
   27. DEPTH — panel, glass, lift (v2)
   ========================================================================== */

/* A plain padded surface block — the generic ground for copy that needs a card
   without card semantics. Ground and ink decoupled (R30). */
#pb-452 .runevents__panel{
    padding: var(--space-xl, 3rem);
    background: var(--panel-bg, var(--color-surface, #ffffff));
    color: var(--panel-color, var(--color-text, #1a181e));
    border: 1px solid var(--color-border, #e0dde5);
    border-radius: var(--radius-lg, 16px);
}

#pb-452 .runevents__panel--dark{
    background: var(--panel-bg, var(--color-surface-dark, #23202a));
    color: var(--panel-color, var(--color-text-on-surface-dark, #ffffff));
    border-color: color-mix(in srgb, var(--color-text-on-surface-dark, #ffffff) 14%, transparent);
}

/* Glass: translucent blur where supported, the opaque panel ground where not —
   never a legibility gamble. Composes with .runevents__panel (which supplies
   padding and radius) or with .runevents__card via --glass below. */
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    #pb-452 .runevents__panel--glass{
        background: color-mix(in srgb, var(--panel-bg, var(--color-surface, #ffffff)) 55%, transparent);
        -webkit-backdrop-filter: blur(var(--glass-blur, 10px));
        backdrop-filter: blur(var(--glass-blur, 10px));
    }
    #pb-452 .runevents__card--glass{
        background: color-mix(in srgb, var(--color-surface, #ffffff) 55%, transparent);
        -webkit-backdrop-filter: blur(var(--glass-blur, 10px));
        backdrop-filter: blur(var(--glass-blur, 10px));
    }
}

/* A stronger, token-driven hover lift for feature cards. */
#pb-452 .runevents__card--lift:hover{
    transform: translateY(var(--lift-y, -6px));
    box-shadow: var(--lift-shadow, var(--shadow-lg, 0 20px 50px rgba(20, 18, 24, 0.18)));
}


/* ==========================================================================
   28. MOTION — CSS only; all content is visible without JavaScript (v2)
   Two layers:
     · time-based entrances (hero, marquee) — durations/easings ride
       --motion-duration / --motion-ease / --flow-duration, with the v1.4
       rendering as the fallback;
     · scroll-driven reveals — ONLY inside @supports (animation-timeline: view()),
       so an engine without support shows everything, immediately (hard rule 8).
   prefers-reduced-motion kills every one of them — `animation: none`, because
   scroll-driven animations ignore duration overrides.
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {
    #pb-452 .runevents__hero-inner > *{
        animation: runevents-rise var(--motion-duration, 700ms) var(--motion-ease, cubic-bezier(0.16, 1, 0.3, 1)) both;
    }
    #pb-452 .runevents__hero-inner > *:nth-child(1){ animation-delay: 120ms; }
    #pb-452 .runevents__hero-inner > *:nth-child(2){ animation-delay: 220ms; }
    #pb-452 .runevents__hero-inner > *:nth-child(3){ animation-delay: 380ms; }
    #pb-452 .runevents__hero-inner > *:nth-child(4){ animation-delay: 500ms; }

    #pb-452 .runevents__hero-media{
        animation: runevents-zoom calc(var(--motion-duration, 700ms) * 2) var(--motion-ease, cubic-bezier(0.16, 1, 0.3, 1)) both;
    }

    /* The logo-strip marquee. Pauses under pointer or keyboard focus. */
    #pb-452 .runevents__logo-strip--flow .runevents__logo-strip-track{
        animation: runevents-flow var(--flow-duration, 40s) linear infinite;
    }
    #pb-452 .runevents__logo-strip--flow:hover .runevents__logo-strip-track,#pb-452 .runevents__logo-strip--flow:focus-within .runevents__logo-strip-track{
        animation-play-state: paused;
    }

    /* SCROLL-DRIVEN REVEALS. Without view() support these rules do not exist
       and every .runevents__reveal element is simply visible — reveal must
       never hide content (hard rule 8). Modifiers pick the keyframes. */
    @supports (animation-timeline: view()) {
        #pb-452 .runevents__reveal{
            animation: runevents-rise var(--motion-duration, 700ms) var(--motion-ease, linear) both;
            animation-timeline: view();
            animation-range: entry 5% cover 22%;
        }
        #pb-452 .runevents__reveal--rise{ animation-name: runevents-rise; }
        #pb-452 .runevents__reveal--fade{ animation-name: runevents-fade; }
        #pb-452 .runevents__reveal--scale{ animation-name: runevents-scale; }
        #pb-452 .runevents__reveal--left{ animation-name: runevents-slide-left; }
        #pb-452 .runevents__reveal--right{ animation-name: runevents-slide-right; }
        #pb-452 .runevents__reveal--blur{ animation-name: runevents-blur; }

        /* Stagger: the PARENT carries --stagger; its direct children reveal in
           sequence through offset ranges (scroll timelines have no delay). */
        #pb-452 .runevents__reveal--stagger > *{
            animation: runevents-rise var(--motion-duration, 700ms) var(--motion-ease, linear) both;
            animation-timeline: view();
            animation-range: entry 5% cover 22%;
        }
        #pb-452 .runevents__reveal--stagger > *:nth-child(2){ animation-range: entry 10% cover 28%; }
        #pb-452 .runevents__reveal--stagger > *:nth-child(3){ animation-range: entry 15% cover 34%; }
        #pb-452 .runevents__reveal--stagger > *:nth-child(4){ animation-range: entry 20% cover 40%; }
        #pb-452 .runevents__reveal--stagger > *:nth-child(n+5){ animation-range: entry 25% cover 46%; }

        /* Slow media drift inside a frame while it crosses the viewport. */
        #pb-452 .runevents__media-frame--drift{ overflow: hidden; }
        #pb-452 :where(.runevents__media-frame--drift img){
            scale: 1.12;
            animation: runevents-drift linear both;
            animation-timeline: view();
            animation-range: cover 0% cover 100%;
        }
    }
}

@media (prefers-reduced-motion: reduce) {
    #pb-452 .runevents__section *,#pb-452 .runevents__section *::before,#pb-452 .runevents__section *::after,#pb-452 .runevents__header *,#pb-452 .runevents__footer *{
        animation: none !important;
        transition-duration: 0.01ms !important;
    }
    #pb-452 .runevents__card--lift:hover,#pb-452 .runevents__card:hover,#pb-452 .runevents__fact:hover,#pb-452 .runevents__tier:hover,#pb-452 .runevents__btn:hover{ transform: none !important; }
    #pb-452 .runevents__card:hover .runevents__card-media img,#pb-452 .runevents__fact:hover .runevents__fact-media img{ transform: none !important; }
    #pb-452 :where(.runevents__media-frame--drift img){ scale: none !important; }
}

@keyframes runevents-rise {
    from { opacity: 0; transform: translateY(18px); }
    to   { opacity: 1; transform: none; }
}

@keyframes runevents-fade {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@keyframes runevents-scale {
    from { opacity: 0; transform: scale(0.94); }
    to   { opacity: 1; transform: none; }
}

@keyframes runevents-slide-left {
    from { opacity: 0; transform: translateX(-24px); }
    to   { opacity: 1; transform: none; }
}

@keyframes runevents-slide-right {
    from { opacity: 0; transform: translateX(24px); }
    to   { opacity: 1; transform: none; }
}

@keyframes runevents-blur {
    from { opacity: 0; filter: blur(8px); }
    to   { opacity: 1; filter: none; }
}

@keyframes runevents-zoom {
    from { transform: scale(1.06); }
    to   { transform: none; }
}

@keyframes runevents-flow {
    to { transform: translateX(calc(-100% - var(--space-xl, 3rem))); }
}

@keyframes runevents-drift {
    from { translate: 0 -3%; }
    to   { translate: 0 3%; }
}
