/* Comedy Pub Events — frontend stylesheet
   -------------------------------------------------------------
   Namespacing notes (read before editing):
   - All colors live as CSS custom properties on #cpe-app, using the
     --cpevn- prefix (Comedy Pub VieNna). This is deliberately NOT
     "--cpe-" because the theme/site may already define its own
     "--cpe-*" tokens — a generic prefix is exactly how plugin colors
     get silently overwritten by (or overwrite) unrelated theme
     variables that happen to share a name. --cpevn- is unique to
     this plugin.
   - Every rule is scoped under #cpe-app (the wrapper on both the
     archive and single templates) or, for the booking modal (which
     lives outside that wrapper in the DOM), under body #cpe-modal-overlay.
     An ID-anchored selector outweighs almost all theme selectors
     (classes, elements, attribute selectors) in the CSS cascade, so
     plugin styling wins without needing !important everywhere.
   - Fonts inherit the theme's font-stack by default (--cpevn-font:
     inherit) instead of forcing a plugin-chosen webfont. If a client
     ever wants the plugin to use its own font instead of the theme's,
     change --cpevn-font in this file (or add a Settings field) —
     never hunt through individual selectors.
   ------------------------------------------------------------- */

#cpe-app{
	--cpevn-bg:#0c0f0d;
	--cpevn-bg-alt:#10130f;
	--cpevn-card:#161a16;
	--cpevn-card-border:#252a24;
	--cpevn-orange:#ff6a3d;
	--cpevn-orange-dark:#e0501f;
	--cpevn-yellow:#f5c518;
	--cpevn-green:#2fd06b;
	--cpevn-teal:#17d6a3;
	--cpevn-text:#f4f4f2;
	--cpevn-text-dim:#a9ada7;
	--cpevn-text-faint:#767a73;
	--cpevn-radius:14px;
	--cpevn-radius-sm:8px;
	/* Brand CI colors (client style guide, Aug 2026 revision, corrected
	   after live review): Book Now buttons use --cpevn-brand-yellow as
	   their base/default color and the sitewide default Embed Brand
	   Color (item 11), with --cpevn-brand-green-hover (#009E57) as the
	   hover state -- the original written brief had green as the base
	   and a lighter green as hover; the client corrected this live to
	   yellow-base/green-hover instead. --cpevn-brand-green (#00492D) is
	   kept as a named color for anyone setting a custom Embed Brand
	   Color override who wants the original green back. */
	--cpevn-brand-green:#00492D;
	--cpevn-brand-green-hover:#009E57;
	--cpevn-brand-yellow:#fad53e;
	/* Inherit the theme's font by default. Fallback chain only kicks
	   in if the theme itself never set a font (rare), so the plugin
	   never fights the site's typography. */
	--cpevn-font: inherit;
	--cpevn-font-fallback: 'Poppins','Inter',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
}

#cpe-app{
	font-family:var(--cpevn-font), var(--cpevn-font-fallback);
	color:var(--cpevn-text);
	background:var(--cpevn-bg);
	line-height:1.5;
	/* overflow-x:hidden here (previously) breaks position:sticky on the
	   booking sidebar — ANY ancestor with a non-visible overflow value
	   stops position:sticky from working, even on a different axis
	   (setting overflow-x to anything other than visible forces the
	   browser to also treat overflow-y as a scroll container per the
	   CSS overflow spec, which is exactly what was silently killing the
	   sidebar's "stick to the top while scrolling" behavior). overflow-x:
	   clip gives the same 100vw full-bleed-hero horizontal-scrollbar
	   guard without creating a scroll container, so sticky keeps working. */
	overflow-x:clip;
}
#cpe-app *,
#cpe-app *::before,
#cpe-app *::after{box-sizing:border-box;}
/* Baseline reset for every icon in the plugin: inline SVGs default to
   display:inline, which leaves a few px of "line-height air" under them
   from the text baseline and can throw off centering inside flex icon
   boxes (this was the cause of icons looking off-center/clipped in the
   Schedule/Venue/Organizer summary cards). Each component still sets its
   own explicit width/height below — this just guarantees consistent,
   predictable box behavior underneath those. */
#cpe-app svg{display:block;flex-shrink:0;}
#cpe-app h1,#cpe-app h2,#cpe-app h3,#cpe-app h4,#cpe-app p,#cpe-app ul,#cpe-app li{margin:0;padding:0;list-style:none;}
/* Belt-and-braces: force every button/input/select/link inside the plugin
   onto the same font stack as the rest of #cpe-app, regardless of theme
   defaults (form controls in particular don't inherit font by default in
   most browsers). */
#cpe-app button,
#cpe-app input,
#cpe-app select,
#cpe-app textarea,
#cpe-app a{font-family:inherit !important;}
#cpe-app .cpe-container{max-width:1280px;margin:0 auto 80px;padding:80px 24px 0;}
/* Client request: the main events (archive/listing) page should also be
   1440px wide, same as the single event page — see the .cpe-single
   breakout rule further below for why plain max-width alone isn't
   enough (the theme's own boxed container still constrains us from the
   outside), so this uses the same full-bleed breakout technique. */
#cpe-app.cpe-wrap{
	width:100vw;
	position:relative;
	left:50%;
	right:50%;
	margin-left:-50vw;
	margin-right:-50vw;
}
#cpe-app.cpe-wrap .cpe-container,
#cpe-app.cpe-single .cpe-container{max-width:1440px;}

/* ---------- HERO / BANNER ---------- */
/* Full-bleed: the hero is pulled out to the true viewport edges (not
   just the container's own padding) so its background always reaches
   both sides with no gap, regardless of the theme's own wrapper width.
   .cpe-hero-inner still re-centers the actual copy/art — at 1440px,
   matching the rest of the page (see .cpe-container above). */
#cpe-app .cpe-hero{
	position:relative;
	width:100vw;
	margin-left:calc(50% - 50vw);
	margin-right:calc(50% - 50vw);
	padding:64px 0 88px;
	margin-bottom:40px;
	overflow:hidden;
	border-bottom:1px solid var(--cpevn-card-border);
}
/* Default (no image uploaded): dark panel with an orange glow bleeding
   in from the right edge, behind the CSS-built "Checkst Du" graphic. */
#cpe-app .cpe-hero--fallback{
	background:linear-gradient(to left, rgba(255,106,61,.5) 0%, rgba(255,106,61,.2) 32%, rgba(255,106,61,0) 62%) , var(--cpevn-bg);
}
/* Client-uploaded background: the image already carries its own
   gradient + artwork (e.g. a "Submit My Comedy" graphic baked in), so
   it simply covers the whole banner — no separate card/column needed.
   background-color is an orange fallback (not the dark theme bg) so
   that any sliver the image doesn't reach — a narrower upload, a very
   wide screen, the "cover" crop — blends with the image's own orange
   gradient instead of showing a bare dark gap. */
#cpe-app .cpe-hero--bg-image{
	background-color:var(--cpevn-orange-dark);
	background-size:cover;
	background-position:center right;
	background-repeat:no-repeat;
	min-height:420px;
	display:flex;
	align-items:center;
}
#cpe-app .cpe-hero--bg-image .cpe-hero-inner{width:100%;}
/* Safety scrim so the copy stays legible over the left side of
   whatever image gets uploaded, even if it doesn't have its own
   built-in dark-to-transparent fade. */
#cpe-app .cpe-hero--bg-image::before{content:"";position:absolute;inset:0;background:linear-gradient(to right, rgba(0,0,0,.4) 0%, rgba(0,0,0,.12) 45%, rgba(0,0,0,0) 65%);pointer-events:none;}
#cpe-app .cpe-hero--bg-image .cpe-hero-inner{position:relative;z-index:1;}
/* Shown only on small screens (see media query) as a plain, uncropped
   image block instead of forcing the wide banner image to `cover` a
   narrow, tall viewport. */
#cpe-app .cpe-hero-mobile-img{display:none;}
#cpe-app .cpe-hero-inner{
	display:flex;
	align-items:center;
	justify-content:space-between;
	gap:48px;
	max-width:1440px;
	margin:0 auto;
	padding:0 24px;
	flex-wrap:wrap;
}
#cpe-app .cpe-hero-copy{flex:1 1 460px;max-width:640px;text-align:left;}
#cpe-app .cpe-eyebrow{color:var(--cpevn-green);text-transform:uppercase;font-weight:700;letter-spacing:.12em;font-size:12px;margin:0 0 16px;}
#cpe-app .cpe-hero-title{font-size:56px;line-height:.92;font-weight:900;margin:0;text-transform:uppercase;letter-spacing:-.02em;}
#cpe-app .cpe-hero-subtitle{font-size:20px;line-height:1.3;font-weight:800;color:var(--cpevn-text);margin:8px 0 28px;text-transform:uppercase;letter-spacing:.08em;}
#cpe-app .cpe-hero-desc{color:var(--cpevn-text-dim);font-size:15px;line-height:1.65;max-width:460px;margin:0 0 32px;}
#cpe-app .cpe-badges{display:flex;flex-wrap:wrap;gap:22px;}
#cpe-app .cpe-badge{display:inline-flex;align-items:center;gap:8px;font-size:10px;font-weight:700;color:var(--cpevn-text-dim);text-transform:uppercase;letter-spacing:.08em;}
#cpe-app .cpe-badge svg{width:16px;height:16px;flex-shrink:0;color:var(--cpevn-green);}

/* Right-hand hero graphic: rotated orange panel with a decorative
   pun graphic by default, or the client's own image (still framed
   the same way) when one is set via the Customizer. */
#cpe-app .cpe-hero-art{
	flex:0 0 460px;
	max-width:100%;
	width:100%;
}
#cpe-app .cpe-hero-art img{
	display:block;
	width:100%;
	border-radius:var(--cpevn-radius);
	transform:rotate(3deg);
	box-shadow:0 0 80px rgba(255,106,61,.35);
}
#cpe-app .cpe-hero-art-graphic{
	position:relative;
	width:100%;
	min-height:320px;
	background:linear-gradient(135deg,var(--cpevn-orange) 0%,var(--cpevn-orange-dark) 100%);
	border-radius:var(--cpevn-radius);
	transform:rotate(3deg);
	box-shadow:0 0 80px rgba(255,106,61,.35);
	overflow:hidden;
	display:flex;
	align-items:center;
	justify-content:center;
	padding:40px;
}
#cpe-app .cpe-hero-qmark{position:absolute;color:var(--cpevn-yellow);font-weight:900;opacity:.45;line-height:1;}
#cpe-app .cpe-hero-qmark-1{top:16px;left:16px;font-size:64px;transform:rotate(-12deg);}
#cpe-app .cpe-hero-qmark-2{bottom:16px;right:28px;font-size:76px;transform:rotate(12deg);}
#cpe-app .cpe-hero-qmark-3{bottom:44px;left:28px;font-size:54px;opacity:.3;transform:rotate(6deg);}
#cpe-app .cpe-hero-art-copy{position:relative;z-index:2;text-align:center;transform:rotate(-2deg);}
#cpe-app .cpe-hero-art-kicker{display:inline-block;background:var(--cpevn-bg);color:var(--cpevn-yellow);font-size:22px;font-weight:900;font-style:italic;padding:6px 16px;border-radius:8px;border:2px solid var(--cpevn-yellow);margin:0 0 10px;}
#cpe-app .cpe-hero-art-title-wrap{position:relative;display:inline-block;}
#cpe-app .cpe-hero-art-title{font-size:40px;font-weight:900;font-style:italic;color:var(--cpevn-teal);text-shadow:0 2px 10px rgba(0,0,0,.35);margin:0;}
#cpe-app .cpe-hero-art-check{position:absolute;top:-18px;right:-32px;width:42px;height:42px;background:var(--cpevn-green);border:4px solid #fff;border-radius:50%;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 10px rgba(0,0,0,.25);}
#cpe-app .cpe-hero-art-check svg{width:22px;height:22px;color:#fff;}
#cpe-app .cpe-hero-art-tag{margin:18px 0 0;display:inline-block;background:var(--cpevn-bg);color:#fff;font-size:13px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;padding:6px 14px;border-radius:999px;}
#cpe-app .cpe-hero-art-sub{margin:6px 0 0;color:var(--cpevn-bg);font-size:13px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;}

/* ---------- FILTER BAR ---------- */
#cpe-app .cpe-filters{background:var(--cpevn-bg-alt);border:1px solid var(--cpevn-card-border);border-radius:var(--cpevn-radius);padding:18px 20px;margin:28px 0 32px;}
#cpe-app .cpe-filter-tabs{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:16px;}
#cpe-app .cpe-filter-tab{background:transparent;border:1px solid var(--cpevn-card-border);color:var(--cpevn-text-dim);padding:9px 16px;border-radius:999px;font-size:13px;font-weight:600;cursor:pointer;transition:.15s ease;white-space:nowrap;}
#cpe-app .cpe-filter-tab:hover{border-color:var(--cpevn-yellow);color:var(--cpevn-text);}
#cpe-app .cpe-filter-tab.is-active{background:var(--cpevn-yellow);border-color:var(--cpevn-yellow);color:#1a1a1a;}
#cpe-app .cpe-search-row{display:flex;gap:12px;flex-wrap:wrap;}
#cpe-app .cpe-search{flex:1 1 320px;position:relative;}
#cpe-app .cpe-search input[type="search"]{width:100%;background:var(--cpevn-bg);border:1px solid var(--cpevn-card-border);border-radius:var(--cpevn-radius-sm);padding:11px 14px 11px 38px;color:var(--cpevn-text);font-size:14px;font-family:inherit;}
#cpe-app .cpe-search svg{position:absolute;left:12px;top:50%;transform:translateY(-50%);opacity:.5;width:16px;height:16px;}
#cpe-app .cpe-sort select{
	appearance:none;
	-webkit-appearance:none;
	-moz-appearance:none;
	background-color:var(--cpevn-bg);
	background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23a9ada7' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
	background-repeat:no-repeat;
	background-position:right 14px center;
	background-size:14px;
	border:1px solid var(--cpevn-card-border);
	border-radius:var(--cpevn-radius-sm);
	padding:11px 38px 11px 14px;
	color:var(--cpevn-text);
	font-size:14px;
	font-family:inherit;
	cursor:pointer;
}
#cpe-app .cpe-sort select:focus{outline:none;border-color:var(--cpevn-teal);}
#cpe-app .cpe-sort select::-ms-expand{display:none;}

/* ---------- FEATURED CARD ----------
   The border wraps the whole card with breathing room (padding) around
   its contents, rather than sitting flush against the image edge — the
   image/media block gets its own radius + overflow clip so it reads as
   a distinct element inside the framed card, not the card's own edge. */
#cpe-app .cpe-featured{position:relative;display:flex;gap:24px;background:var(--cpevn-card);border:1px solid var(--cpevn-yellow);border-radius:var(--cpevn-radius);padding:16px;margin-bottom:36px;}
#cpe-app .cpe-featured-badge-corner{position:absolute;top:12px;left:12px;background:var(--cpevn-yellow);color:#1a1500;font-size:11px;font-weight:800;letter-spacing:.04em;padding:5px 10px;border-radius:6px;text-transform:uppercase;z-index:3;}
#cpe-app .cpe-featured-media{flex:0 0 320px;position:relative;background:linear-gradient(135deg,var(--cpevn-orange),var(--cpevn-orange-dark));min-height:220px;border-radius:var(--cpevn-radius-sm);overflow:hidden;display:block;}
#cpe-app .cpe-featured-media img{width:100%;height:100%;object-fit:cover;position:absolute;inset:0;}
#cpe-app .cpe-featured-tag{position:absolute;top:12px;right:12px;background:var(--cpevn-orange);color:#fff;font-size:11px;font-weight:700;letter-spacing:.04em;padding:5px 10px;border-radius:6px;z-index:2;text-transform:uppercase;}
#cpe-app .cpe-featured-body{flex:1;padding:12px 16px 12px 0;display:flex;flex-direction:column;justify-content:center;gap:14px;min-width:0;}
#cpe-app .cpe-featured-badge{display:inline-block;color:var(--cpevn-orange);font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;margin-bottom:8px;}
#cpe-app .cpe-featured-title{font-size:24px;font-weight:800;margin:0 0 8px;text-transform:uppercase;color:var(--cpevn-brand-yellow);font-family:var(--cpevn-font-fallback);}
#cpe-app .cpe-featured-desc{color:var(--cpevn-text-dim);font-size:14px;line-height:1.6;margin:0;}
#cpe-app .cpe-featured-meta{display:flex;gap:18px;flex-wrap:wrap;color:var(--cpevn-text-faint);font-size:13px;}
#cpe-app .cpe-featured-meta span{display:inline-flex;align-items:center;gap:6px;}
#cpe-app .cpe-featured-meta svg{width:14px;height:14px;flex-shrink:0;color:var(--cpevn-brand-yellow);}
#cpe-app .cpe-featured-foot{display:flex;align-items:center;justify-content:space-between;margin-top:6px;flex-wrap:wrap;gap:12px;}
#cpe-app .cpe-price{font-weight:700;color:var(--cpevn-text);font-size:17px;}
#cpe-app .cpe-price.is-free{color:var(--cpevn-green);}

/* ---------- DATE BLOCK (shared: featured + grid cards) ----------
   The stacked "FRI / 18 / JUL" block, set beside the title with a
   divider — used identically in the featured event and every card. */
#cpe-app .cpe-card-row{display:flex;gap:16px;align-items:flex-start;}
#cpe-app .cpe-date-block{display:flex;flex-direction:column;align-items:center;justify-content:center;border-right:1px solid var(--cpevn-card-border);padding-right:16px;min-width:44px;flex-shrink:0;}
#cpe-app .cpe-date-block .dow{color:var(--cpevn-text-faint);font-size:12px;font-weight:700;text-transform:uppercase;}
#cpe-app .cpe-date-block .dom{color:var(--cpevn-text);font-size:28px;font-weight:800;line-height:1;margin:2px 0;}
#cpe-app .cpe-date-block .mon{color:var(--cpevn-text-faint);font-size:12px;font-weight:700;text-transform:uppercase;}
#cpe-app .cpe-card-info{min-width:0;flex:1;}

/* ---------- BUTTONS ----------
   font-family is forced with !important here (and mirrored on every other
   interactive control below) because theme/page-builder button styles
   (e.g. Elementor's own button/link typography rules) are frequently more
   specific than a plain class selector and were winning the cascade,
   making "Book Now" / "Reserve Tickets" render in the theme's default
   button font instead of the site's body font that #cpe-app inherits. */
#cpe-app .cpe-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:12px 24px;border-radius:8px;font-weight:700;font-size:14px;text-transform:uppercase;letter-spacing:.03em;cursor:pointer;border:none;text-decoration:none;font-family:"Asap Condensed", sans-serif !important;}
/* Client request (item 20): base #00492D, hover #009E57, smooth
   transition rather than an instant color snap (client correction: base
   is brand YELLOW, hover is brand GREEN -- reversed from the original
   written spec after live review). --cpevn-btn-bg / --cpevn-btn-bg-hover /
   --cpevn-btn-font / --cpevn-btn-font-hover are set inline per-button by
   cpe_render_ticket_cta() (see class-templates.php) from each event's
   resolved Embed Brand Color (item 11) — falling back to the brand
   green/its exact hover here whenever no override is set. */
#cpe-app .cpe-btn-primary{background:var(--cpevn-btn-bg, var(--cpevn-brand-yellow));color:var(--cpevn-btn-font, #1a1500);transition:background-color .2s ease, color .2s ease;}
#cpe-app .cpe-btn-primary:hover{background:var(--cpevn-btn-bg-hover, var(--cpevn-brand-green-hover));color:var(--cpevn-btn-font-hover, #fff);}
#cpe-app .cpe-btn-outline{background:transparent;border:1px solid var(--cpevn-card-border);color:var(--cpevn-text);transition:border-color .2s ease,color .2s ease;}
#cpe-app .cpe-btn-outline:hover{border-color:var(--cpevn-brand-yellow);color:var(--cpevn-brand-yellow);}
#cpe-app .cpe-btn-block{width:100%;}
#cpe-app .cpe-btn-sm{padding:9px 16px;font-size:12px;}
/* Client request: "View Event" is a plain text link now, separate from
   the "Book Now" button — sits beside it in .cpe-card-ctas. */
#cpe-app .cpe-view-link{color:var(--cpevn-brand-yellow);font-size:13px;font-weight:700;text-decoration:none;white-space:nowrap;}
#cpe-app .cpe-view-link:hover{text-decoration:underline;}
#cpe-app .cpe-card-ctas{display:flex;align-items:center;gap:14px;flex-wrap:wrap;justify-content:flex-end;}
/* Every other button-like control in the plugin (tab pills, filter pills,
   the modal close button, and Universe's own ticket-embed button) gets the
   same treatment so ALL buttons share one font, not just .cpe-btn. */
#cpe-app .cpe-tab-btn,
#cpe-app .cpe-filter-tab,
#cpe-app .cpe-modal-close,
#cpe-app .unii-listing-button{font-family:"Asap Condensed", sans-serif !important;}
/* Universe's official button embed (unii-listing-button) sets its own
   background/color inline per the vendor's documented markup, but now
   via the same --cpevn-btn-bg CSS custom properties as every other Book
   Now button (see cpe_render_ticket_cta()), so it gets the identical
   smooth base->hover transition instead of an instant color snap. */
#cpe-app .unii-listing-button{background-color:var(--cpevn-btn-bg, var(--cpevn-brand-yellow)) !important;color:var(--cpevn-btn-font, #1a1500) !important;transition:background-color .2s ease, color .2s ease;}
#cpe-app .unii-listing-button:hover{background-color:var(--cpevn-btn-bg-hover, var(--cpevn-brand-green-hover)) !important;color:var(--cpevn-btn-font-hover, #fff) !important;}

/* ---------- GRID / CARDS ----------
   Client request: 4 columns on desktop (was 3), and square artwork on
   the listing cards (was a short 150px-tall crop) — aspect-ratio keeps
   it perfectly square at any card width instead of a fixed pixel height. */
#cpe-app .cpe-section-title{font-size:22px;font-weight:800;margin:0 0 18px;}
#cpe-app .cpe-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:20px;}
/* [events_grid] shortcode (item 28) reuses the same grid/card styling as
   the main archive — .cpe-grid--small is a denser layout for embedding
   elsewhere on the site (e.g. the client's existing Courses page)
   without dominating the surrounding page content. Related Events (the
   single event page) uses its own horizontally-scrolling carousel
   instead — see .cpe-related-carousel further down. */
#cpe-app .cpe-grid--small{grid-template-columns:repeat(3,1fr);gap:14px;}
#cpe-app .cpe-card{background:var(--cpevn-card);border:1px solid var(--cpevn-card-border);border-radius:var(--cpevn-radius);overflow:hidden;display:flex;flex-direction:column;transition:.2s ease;}
#cpe-app .cpe-card:hover{border-color:var(--cpevn-teal);transform:translateY(-2px);}
#cpe-app .cpe-card-media{position:relative;aspect-ratio:16/10;height:auto;background:linear-gradient(135deg,#2a1810,#1a1210);display:block;}
#cpe-app .cpe-card-media img{width:100%;height:100%;object-fit:cover;position:absolute;inset:0;}
#cpe-app .cpe-card-tag{position:absolute;top:10px;left:10px;background:rgba(0,0,0,.55);color:#fff;font-size:11px;font-weight:700;text-transform:uppercase;padding:5px 10px;border-radius:5px;z-index:2;}
/* Solid per-type tag colors, matching the reference design (each show
   type reads at a glance from its card color, not just its label). */
#cpe-app .cpe-card-tag--showcase{background:#7a2020;}
#cpe-app .cpe-card-tag--open-mic{background:var(--cpevn-orange);}
#cpe-app .cpe-card-tag--solo-show{background:#2b3a67;}
#cpe-app .cpe-card-tag--german-show{background:#7a4a1f;}
#cpe-app .cpe-card-tag--status-sold-out,
#cpe-app .cpe-card-tag--status-cancelled{left:auto;right:10px;background:#c0392b;}
#cpe-app .cpe-card-tag--status-postponed{left:auto;right:10px;background:#8a6d1f;}
#cpe-app .cpe-card-body{padding:18px 18px 20px;display:flex;flex-direction:column;gap:14px;flex:1;}
#cpe-app .cpe-card-title{font-size:18px;font-weight:800 !important;margin:0 0 8px;line-height:1.3;text-transform:uppercase;color:var(--cpevn-brand-yellow);font-family:var(--cpevn-font-fallback);}
#cpe-app .cpe-card-title a{font-weight:inherit !important;color:inherit;}
#cpe-app .cpe-card-desc{color:var(--cpevn-text-faint);font-size:13.5px;line-height:1.5;margin:2px 0 8px;}
#cpe-app .cpe-card--small .cpe-card-desc{font-size:12px;margin:1px 0 6px;}
#cpe-app .cpe-card-meta{color:var(--cpevn-text-faint);font-size:14px;display:flex;flex-wrap:wrap;gap:6px 14px;}
#cpe-app .cpe-card-meta .meta-item{display:inline-flex;align-items:center;gap:6px;}
#cpe-app .cpe-card-meta .meta-item svg{width:15px;height:15px;flex-shrink:0;color:var(--cpevn-brand-yellow);}
#cpe-app .cpe-card-meta .meta-item--full{width:100%;margin-top:4px;}
#cpe-app .cpe-card-foot{margin-top:auto;display:flex;align-items:center;justify-content:space-between;padding-top:8px;}

/* ---------- PAGINATION ---------- */
#cpe-app .cpe-pagination{display:flex;align-items:center;justify-content:center;gap:8px;margin:32px 0 8px;}
#cpe-app .cpe-page-num{width:36px;height:36px;display:inline-flex;align-items:center;justify-content:center;border-radius:8px;background:var(--cpevn-card);border:1px solid var(--cpevn-card-border);color:var(--cpevn-text-dim);font-weight:600;font-size:13px;cursor:pointer;}
#cpe-app .cpe-page-num.is-active{background:var(--cpevn-yellow);border-color:var(--cpevn-yellow);color:#1a1500;}
#cpe-app .cpe-load-more{text-align:center;margin:20px 0 8px;}

/* ---------- INFO STRIP ---------- */
#cpe-app .cpe-info-strip{display:grid;grid-template-columns:repeat(3,1fr);gap:24px;margin:56px 0;padding:28px 0;border-top:1px solid var(--cpevn-card-border);border-bottom:1px solid var(--cpevn-card-border);}
#cpe-app .cpe-info-item{display:flex;gap:12px;align-items:flex-start;}
#cpe-app .cpe-info-item strong{display:block;font-size:14px;margin-bottom:2px;}
#cpe-app .cpe-info-item span{color:var(--cpevn-text-faint);font-size:13px;}

/* ---------- SINGLE EVENT PAGE ----------
   Three grid children — .cpe-single-top (hero/title/meta), .cpe-sidebar
   (booking box) and .cpe-single-body (tabs + panels) — placed with named
   grid areas instead of a simple 2-column split. On desktop the sidebar
   spans both rows next to the content; on mobile (see the 960px query
   below) the areas collapse into a single column in this exact order:
   top, sidebar, body — which is what puts the booking box right under
   the date/time meta strip on a phone instead of at the very bottom of
   the page. */
/* Client request: widen the event page to ~1440px. The .cpe-container
   max-width alone wasn't enough because the THEME's own page wrapper
   (Elementor's boxed content width) was still constraining us from the
   outside — same "theme fights our CSS" pattern as the icon/card-layout
   fixes above. This is the standard "full-bleed breakout" trick: make
   #cpe-app itself span the full viewport width regardless of its
   parent, then .cpe-container (below) re-centers the real content at
   1440px inside that. Guarantees the width regardless of what wrapper
   the theme puts around it. */
#cpe-app.cpe-single{
	padding:24px 0 60px;
	width:100vw;
	position:relative;
	left:50%;
	right:50%;
	margin-left:-50vw;
	margin-right:-50vw;
}
#cpe-app .cpe-breadcrumb{color:var(--cpevn-text-faint);font-size:13px;margin-bottom:16px;display:inline-flex;align-items:center;gap:6px;text-decoration:none;}
#cpe-app .cpe-single-grid{
	display:grid;
	grid-template-columns:1fr 340px;
	grid-template-areas:"top sidebar" "body sidebar";
	gap:32px;
	align-items:start;
}
#cpe-app .cpe-single-top{grid-area:top;min-width:0;}
#cpe-app .cpe-single-body{grid-area:body;min-width:0;}

#cpe-app .cpe-hero-banner{position:relative;border-radius:var(--cpevn-radius);overflow:hidden;aspect-ratio:2/1;background:linear-gradient(135deg,var(--cpevn-orange),var(--cpevn-orange-dark));margin-bottom:24px;}
#cpe-app .cpe-hero-banner img{width:100%;height:100%;object-fit:cover;position:absolute;inset:0;}
#cpe-app .cpe-hero-banner .cpe-card-tag{top:auto;bottom:16px;left:16px;font-size:11px;padding:6px 12px;background:var(--cpevn-orange);}

#cpe-app .cpe-single-title{font-size:36px;font-weight:800;line-height:1.2;margin:0 0 6px;text-transform:uppercase;color:var(--cpevn-brand-yellow);font-family:var(--cpevn-font-fallback);}
#cpe-app .cpe-hosted-by{color:var(--cpevn-text-faint);font-size:14px;margin-bottom:18px;}
#cpe-app .cpe-hosted-by a{color:var(--cpevn-teal);text-decoration:none;}

#cpe-app .cpe-meta-strip{display:flex;flex-wrap:wrap;gap:28px;padding:16px 0;border-top:1px solid var(--cpevn-card-border);border-bottom:1px solid var(--cpevn-card-border);margin-bottom:32px;}
#cpe-app .cpe-meta-strip .item{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:600;color:var(--cpevn-text-dim);}
#cpe-app .cpe-meta-strip svg{width:16px;height:16px;flex-shrink:0;color:var(--cpevn-brand-yellow);}

/* ---------- INFO ROW (Schedule / Venue / Organizer summary) ----------
   Client request: these three summaries sit in one row on desktop and
   stack to a single column on mobile — see the 960px query below.
   Rendered twice (see cpe_render_single_info_row() in class-templates.php)
   because its two placements live in different CSS Grid areas
   (.cpe-single-top vs .cpe-single-body) that can't be reordered into each
   other with plain CSS `order`. Only one copy is ever visible at a time:
   --desktop-only is the default/only one shown until the 960px query
   below flips it off and switches on --mobile-only instead. */
#cpe-app .cpe-info-row--mobile-only{display:none;}
#cpe-app .cpe-info-row{display:grid !important;grid-template-columns:repeat(3,1fr) !important;gap:16px;margin-bottom:0;align-items:stretch;}
#cpe-app .cpe-info-card{display:flex;flex-direction:column;gap:10px;background:var(--cpevn-card);border:1px solid var(--cpevn-card-border);border-radius:var(--cpevn-radius-sm);padding:16px;transition:.15s ease;height:100%;}
#cpe-app .cpe-info-card:hover{border-color:var(--cpevn-teal);}
#cpe-app .cpe-info-card-head{display:flex;align-items:center;gap:10px;}
/* Client request (item 21): explicit "Schedule / Venue / Organizer"
   kicker label above each card's name/link, so the three cards read as
   distinctly labeled even though Schedule and Venue/Organizer used to
   share near-identical layouts. */
#cpe-app .cpe-info-card-headtext{display:flex;flex-direction:column;gap:1px;min-width:0;}
#cpe-app .cpe-info-card-kicker{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--cpevn-brand-yellow) !important;}
/* Bug fix: ".cpe-info-card-headtext span" below unintentionally also
   matched .cpe-info-card-kicker just above (it's a <span> too) with
   HIGHER specificity (class+element beats a single class) -- silently
   overriding the kicker back to white despite the rule above. :not()
   now excludes it explicitly so the two rules can never fight again
   regardless of source order. */
#cpe-app .cpe-info-card-head a,
#cpe-app .cpe-info-card-headtext span:not(.cpe-info-card-kicker){color:var(--cpevn-text);font-size:13px;font-weight:700;text-transform:uppercase;letter-spacing:.03em;text-decoration:none;}
/* Client correction: Schedule/Venue/Organizer TITLES (the date/venue-name/
   organizer-name line) are white; only the small action LINKS below each
   card (View Details / Get Directions / website) are yellow -- see
   .cpe-info-card-action below. */
#cpe-app .cpe-info-card-head a:hover{text-decoration:underline;}
/* !important below is deliberate: the icon box was rendering off-center
   on the live site (icon glyph stuck in the top-left corner of its box)
   despite plain flexbox centering — a strong sign a theme/page-builder
   global style (Elementor etc. commonly ship high-specificity `svg{...}`
   resets) was winning the cascade against ours. Locking every relevant
   property down here guarantees this specific icon box centers no
   matter what the theme does elsewhere. */
#cpe-app .cpe-info-card-icon{
	flex-shrink:0;width:32px;height:32px;border-radius:8px;
	background:var(--cpevn-bg-alt);
	display:flex !important;align-items:center !important;justify-content:center !important;
	position:relative;overflow:hidden;
}
#cpe-app .cpe-info-card-icon svg{
	display:block !important;position:static !important;
	margin:0 !important;padding:0 !important;
	width:16px !important;height:16px !important;
	min-width:16px !important;min-height:16px !important;
	max-width:16px !important;max-height:16px !important;
	flex-shrink:0 !important;
	color:var(--cpevn-brand-yellow);
	top:auto !important;left:auto !important;right:auto !important;bottom:auto !important;
	transform:none !important;
}
#cpe-app .cpe-info-card-list{display:flex;flex-direction:column;gap:5px;}
#cpe-app .cpe-info-card-list li{display:flex;align-items:baseline;justify-content:space-between;gap:10px;font-size:13px;}
#cpe-app .cpe-info-card-list li span{color:var(--cpevn-text-faint);}
#cpe-app .cpe-info-card-list li strong{color:var(--cpevn-text-dim);font-weight:600;text-align:right;}
#cpe-app .cpe-info-card-text{font-size:13px;line-height:1.5;color:var(--cpevn-text-dim);}
#cpe-app .cpe-info-card-action{display:inline-block;margin-top:auto;padding-top:2px;font-size:12px;font-weight:700;color:var(--cpevn-brand-yellow);text-decoration:none;text-transform:uppercase;letter-spacing:.03em;}
#cpe-app .cpe-info-card-action:hover{text-decoration:underline;}

#cpe-app .cpe-tabs{display:flex;flex-wrap:wrap;gap:4px;background:var(--cpevn-bg-alt);border:1px solid var(--cpevn-card-border);border-radius:var(--cpevn-radius-sm);padding:6px;margin-bottom:28px;}
#cpe-app .cpe-tab-btn{background:transparent;border:none;color:var(--cpevn-text-faint);padding:9px 16px;border-radius:6px;font-size:13px;font-weight:700;text-transform:uppercase;letter-spacing:.02em;cursor:pointer;}
#cpe-app .cpe-tab-btn.is-active{background:var(--cpevn-card);color:var(--cpevn-yellow);}
/* All sections render at once — clicking a tab smooth-scrolls to it
   (see frontend.js) rather than hiding/showing panels. scroll-margin-top
   keeps the jump target clear of the sticky tab bar. */
#cpe-app .cpe-tab-panel{display:block;scroll-margin-top:96px;margin-bottom:44px;}
#cpe-app .cpe-tab-panel:last-child{margin-bottom:0;}
#cpe-app .cpe-tabs{position:sticky;top:0;z-index:10;}

/* Tab section headings: gold/yellow label text with a short green
   underline rule directly beneath it — matches the reference design
   (About This Event / Schedule / Location / Organizer / Related). */
#cpe-app .cpe-tab-heading{font-size:20px;font-weight:800;color:var(--cpevn-yellow);margin:0 0 6px;padding-bottom:8px;display:inline-block;}
/* Client request (item 22): removed the decorative 3px underline/dash that used to sit under this heading (border-bottom:3px solid var(--cpevn-green)) -- purely a visual trim. */
#cpe-app .cpe-tab-panel > .cpe-tab-heading{display:block;width:fit-content;}
#cpe-app .cpe-tab-body{margin-top:18px;}
#cpe-app .cpe-tab-body p{color:var(--cpevn-text);line-height:1.7;font-size:15px;margin-bottom:16px;}
#cpe-app .cpe-calendar-embed{margin-top:4px;}

/* ---------- SHOW MORE (long description clamp) ----------
   Client request: clamp at exactly 4 lines — if the description doesn't
   reach 4 lines, it renders completely normal (no dim, no button); if it
   does, only then does it get the fade + "Show More". -webkit-line-clamp
   is used instead of a guessed pixel max-height because it's an exact,
   reliable "N lines" cut regardless of font size/line-height, and is
   well-supported in every modern browser now (not just WebKit). JS (see
   frontend.js) only ever toggles the .is-clamped / .is-expanded classes
   below — it doesn't compute the clamp itself. */
#cpe-app .cpe-longdesc{position:relative;}
#cpe-app .cpe-longdesc.is-clamped{display:-webkit-box;-webkit-line-clamp:4;line-clamp:4;-webkit-box-orient:vertical;overflow:hidden;}
#cpe-app .cpe-longdesc.is-clamped.is-expanded{display:block;-webkit-line-clamp:unset;line-clamp:unset;overflow:visible;}
/* Dim just the last line while clamped. */
#cpe-app .cpe-longdesc.is-clamped:not(.is-expanded)::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1.6em;background:linear-gradient(to bottom, transparent, var(--cpevn-bg));pointer-events:none;}
#cpe-app .cpe-show-more-btn{display:inline-flex;align-items:center;gap:6px;margin-top:10px;margin-bottom:16px;background:none;border:none;color:var(--cpevn-teal);font-weight:700;font-size:13px;text-transform:uppercase;letter-spacing:.03em;cursor:pointer;padding:0;font-family:inherit;}
#cpe-app .cpe-show-more-btn:hover{text-decoration:underline;}
#cpe-app .cpe-highlight-list{list-style:none;padding:0;margin:18px 0 0;display:grid;grid-template-columns:1fr 1fr;gap:12px 24px;}
#cpe-app .cpe-highlight-list li{display:flex;gap:10px;align-items:flex-start;color:var(--cpevn-text);font-size:14px;}
#cpe-app .cpe-highlight-list svg{color:var(--cpevn-green);flex-shrink:0;margin-top:2px;width:16px;height:16px;}

#cpe-app .cpe-schedule-table{width:100%;border-collapse:collapse;background:var(--cpevn-card);border:1px solid var(--cpevn-card-border);border-radius:var(--cpevn-radius-sm);overflow:hidden;}
#cpe-app .cpe-schedule-table tr:not(:last-child) td{border-bottom:1px solid var(--cpevn-card-border);}
#cpe-app .cpe-schedule-table td{padding:14px 20px;font-size:14px;}
#cpe-app .cpe-schedule-table td:first-child{color:var(--cpevn-yellow);font-weight:700;width:110px;}
#cpe-app .cpe-schedule-table td:last-child{color:var(--cpevn-text);}

#cpe-app .cpe-location-box{display:flex;gap:0;background:var(--cpevn-card);border:1px solid var(--cpevn-card-border);border-radius:var(--cpevn-radius-sm);overflow:hidden;flex-wrap:wrap;}
#cpe-app .cpe-location-info{flex:1 1 260px;padding:24px;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;}
#cpe-app .cpe-location-info h4{margin:0 0 6px;font-size:16px;}
#cpe-app .cpe-location-info p{color:var(--cpevn-text);font-size:14px;margin:0 0 16px;}
#cpe-app .cpe-location-map{flex:1 1 320px;min-height:200px;background:#1a1c19;}
#cpe-app .cpe-location-map iframe{width:100%;height:100%;min-height:200px;border:0;display:block;}


/* Client request (item 25): related events grid grew from 3 to 6 cards,
   using a smaller card layout so 6 still fits comfortably — a denser
   grid (up to 3 cols but tighter card internals) rather than just
   shrinking the same card design proportionally. */
#cpe-app .cpe-card--small{border-radius:10px;}
#cpe-app .cpe-card--small .cpe-card-media{aspect-ratio:1/1;}
#cpe-app .cpe-card--small .cpe-card-body{padding:10px 10px 12px;gap:8px;}
#cpe-app .cpe-card--small .cpe-card-title{font-size:12.5px;margin-bottom:2px;-webkit-line-clamp:2;display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;line-height:1.25;}
#cpe-app .cpe-card--small .cpe-card-meta{font-size:10.5px;gap:3px 6px;}
#cpe-app .cpe-card--small .cpe-card-meta .meta-item svg{width:11px;height:11px;}
#cpe-app .cpe-card--small .cpe-date-block{padding-right:8px;min-width:30px;}
#cpe-app .cpe-card--small .cpe-date-block .dow{font-size:9px;}
#cpe-app .cpe-card--small .cpe-date-block .dom{font-size:16px;}
#cpe-app .cpe-card--small .cpe-date-block .mon{font-size:9px;}
#cpe-app .cpe-card--small .cpe-price{font-size:12px;}
#cpe-app .cpe-card--small .cpe-card-ctas{gap:6px;}
#cpe-app .cpe-card--small .cpe-view-link{display:none;}
#cpe-app .cpe-card--small .cpe-btn-sm{padding:6px 10px;font-size:10px;width:100%;}

/* Client request (live review): Related Events redesigned as a
   horizontally-scrolling carousel with left/right arrow controls,
   roughly 5 cards visible at once on desktop, instead of a wrapping
   grid. Cards inside reuse .cpe-card--small (same look as before) —
   only the container/scrolling mechanism changed. */
#cpe-app .cpe-related-carousel{position:relative;display:flex;align-items:center;gap:8px;}
#cpe-app .cpe-related-track{
	display:flex;gap:12px;overflow-x:auto;scroll-behavior:smooth;
	scroll-snap-type:x mandatory;padding:2px;flex:1;
	/* Hide the native scrollbar -- the arrow buttons are the primary
	   control; dragging/swiping still works, it's just not visually
	   cluttered with a scrollbar track under the cards. */
	scrollbar-width:none;-ms-overflow-style:none;
}
#cpe-app .cpe-related-track::-webkit-scrollbar{display:none;}
#cpe-app .cpe-related-track .cpe-card{
	flex:0 0 calc((100% - 4 * 12px) / 5); /* 5 cards visible, 4 gaps between them */
	scroll-snap-align:start;
}
#cpe-app .cpe-carousel-arrow{
	flex-shrink:0;display:flex;align-items:center;justify-content:center;
	width:36px;height:36px;border-radius:50%;border:1px solid var(--cpevn-card-border);
	background:var(--cpevn-card);color:var(--cpevn-text);cursor:pointer;
	transition:background-color .2s ease,border-color .2s ease;
}
#cpe-app .cpe-carousel-arrow:hover{border-color:var(--cpevn-brand-yellow);color:var(--cpevn-brand-yellow);}
#cpe-app .cpe-carousel-arrow svg{width:18px;height:18px;}
#cpe-app .cpe-carousel-arrow:disabled{opacity:.3;cursor:default;}
#cpe-app .cpe-carousel-arrow:disabled:hover{border-color:var(--cpevn-card-border);color:var(--cpevn-text);}

/* ---------- SIDEBAR ---------- */
#cpe-app .cpe-sidebar{grid-area:sidebar;position:sticky;top:120px;background:var(--cpevn-card);border:1px solid var(--cpevn-card-border);border-radius:var(--cpevn-radius);padding:24px;}
#cpe-app .cpe-sidebar-date{display:flex;gap:12px;align-items:center;margin-bottom:16px;}
#cpe-app .cpe-sidebar-date .icon{width:44px;height:44px;border-radius:10px;background:var(--cpevn-orange);display:flex;align-items:center;justify-content:center;flex-shrink:0;}
#cpe-app .cpe-sidebar-date .icon svg{width:22px;height:22px;color:#fff;}
#cpe-app .cpe-sidebar-date .label{color:var(--cpevn-text-faint);font-size:11px;text-transform:uppercase;letter-spacing:.05em;}
#cpe-app .cpe-sidebar-date .value{font-size:17px;font-weight:800;}
#cpe-app .cpe-sidebar-time{color:var(--cpevn-text-dim);font-size:13px;margin-bottom:4px;}
#cpe-app .cpe-sidebar-venue{font-weight:700;font-size:14px;margin-bottom:2px;}
#cpe-app .cpe-sidebar-address{color:var(--cpevn-text-faint);font-size:13px;margin-bottom:16px;}
#cpe-app .cpe-sidebar hr{border:none;border-top:1px solid var(--cpevn-card-border);margin:16px 0;}
#cpe-app .cpe-sidebar-price-label{color:var(--cpevn-green);font-size:13px;font-weight:700;text-transform:uppercase;margin-bottom:2px;}
#cpe-app .cpe-sidebar-price{font-size:26px;font-weight:800;margin-bottom:4px;}
#cpe-app .cpe-sidebar-price small{color:var(--cpevn-text-faint);font-size:12px;font-weight:400;}
#cpe-app .cpe-sidebar .cpe-btn{margin-bottom:10px;}
#cpe-app .cpe-secure-note{display:flex;align-items:center;gap:8px;color:var(--cpevn-text-faint);font-size:12px;margin-bottom:16px;}
#cpe-app .cpe-share-row{display:flex;gap:10px;margin-top:8px;}
#cpe-app .cpe-share-row a{width:34px;height:34px;border-radius:50%;background:var(--cpevn-bg-alt);border:1px solid var(--cpevn-card-border);display:flex;align-items:center;justify-content:center;color:var(--cpevn-text-dim);text-decoration:none;}
#cpe-app .cpe-share-row a:hover{border-color:var(--cpevn-teal);color:var(--cpevn-teal);}
#cpe-app .cpe-sidebar-label{color:var(--cpevn-text-faint);font-size:12px;text-transform:uppercase;letter-spacing:.05em;margin:0 0 10px;}

/* ---------- CHOOSE ANOTHER SHOW ----------
   Client request: renamed from "Choose Another Date", picking an option
   jumps straight to that occurrence's own booking flow (see frontend.js
   for the #cpe-book auto-trigger). */
#cpe-app .cpe-choose-another{margin-top:16px;}
#cpe-app .cpe-choose-another-select{width:100%;background:var(--cpevn-bg);border:1px solid var(--cpevn-card-border);border-radius:var(--cpevn-radius-sm);padding:10px 14px;color:var(--cpevn-text);font-size:13px;font-family:inherit;cursor:pointer;}

/* ---------- MOBILE STICKY BOOKING BAR ----------
   Client request: price + Book Now pinned to the bottom of the screen on
   mobile so it's always reachable while scrolling. Hidden by default —
   frontend.js shows it only once the visitor has scrolled the main
   sidebar CTA out of view, and only below the 960px breakpoint (see that
   query further down), so desktop keeps the existing sticky-to-top
   sidebar instead of also getting a redundant bottom bar. */
#cpe-app .cpe-sticky-bookbar{display:none;}
#cpe-app .cpe-sticky-bookbar-price{display:flex;flex-direction:column;line-height:1.2;}
#cpe-app .cpe-sticky-bookbar-label{font-size:11px;text-transform:uppercase;letter-spacing:.04em;color:var(--cpevn-text-faint);}
#cpe-app .cpe-sticky-bookbar-amount{font-size:18px;font-weight:800;}
#cpe-app .cpe-sticky-bookbar-cta{flex-shrink:0;}
#cpe-app .cpe-sticky-bookbar-cta .cpe-btn{padding:12px 22px;}

#cpe-app .cpe-status-flag{display:inline-block;padding:6px 14px;border-radius:6px;font-size:12px;font-weight:700;text-transform:uppercase;margin-bottom:12px;}
#cpe-app .cpe-status-flag.sold-out{background:#3a1414;color:#ff7676;}
#cpe-app .cpe-status-flag.cancelled{background:#3a1414;color:#ff7676;}
#cpe-app .cpe-status-flag.postponed{background:#3a2f14;color:#f0c05a;}

/* ---------- MODAL (booking popup) ----------
   Lives outside #cpe-app in the DOM (appended at the end of the
   template so it can sit above everything with position:fixed), so
   it carries its own scope. It re-declares the small palette it
   needs as body-level custom properties so a theme's :root vars can
   never leak in, and every rule is anchored to the unique
   #cpe-modal-overlay id — nothing in a theme normally targets that
   id, so nothing overwrites it. */
body{
	--cpevn-modal-bg-alt:#10130f;
	--cpevn-modal-card:#161a16;
	--cpevn-modal-border:#252a24;
	--cpevn-modal-text:#f4f4f2;
	--cpevn-modal-text-dim:#a9ada7;
}
body #cpe-modal-overlay{position:fixed;inset:0;background:rgba(0,0,0,.75);z-index:99998;display:none;align-items:center;justify-content:center;padding:24px;font-family:inherit;}
body #cpe-modal-overlay.is-open{display:flex;}
body #cpe-modal-overlay .cpe-modal{background:var(--cpevn-modal-bg-alt);border:1px solid var(--cpevn-modal-border);border-radius:14px;width:100%;max-width:640px;max-height:88vh;overflow:auto;position:relative;padding:20px;}
body #cpe-modal-overlay .cpe-modal-close{position:absolute;top:12px;right:12px;width:34px;height:34px;border-radius:50%;background:var(--cpevn-modal-card);border:1px solid var(--cpevn-modal-border);color:var(--cpevn-modal-text);font-size:18px;cursor:pointer;z-index:2;font-family:inherit !important;}
body #cpe-modal-overlay .cpe-modal-body iframe{width:100%;min-height:520px;border:0;}
body #cpe-modal-overlay .cpe-modal-fallback{padding:32px 8px;text-align:center;color:var(--cpevn-modal-text-dim);}
/* Spinner shown over the legacy popup modal until its iframe loads. */
body #cpe-modal-overlay .cpe-modal-loading{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:var(--cpevn-modal-bg-alt);border-radius:14px;z-index:3;}

/* ---------- LOADING ---------- */
#cpe-app .cpe-grid.is-loading{opacity:.4;pointer-events:none;transition:opacity .2s;}
#cpe-app .cpe-no-results{grid-column:1/-1;text-align:center;color:var(--cpevn-text-faint);padding:40px 0;}

@keyframes cpe-spin{to{transform:rotate(360deg);}}

/* Generic spinner, reused by the full-page loader and the modal loader. */
.cpe-spinner{width:40px;height:40px;border:4px solid rgba(255,255,255,.25);border-top-color:#fff;border-radius:50%;animation:cpe-spin .7s linear infinite;}

/* Full-page loading overlay shown while navigating to an event / single
   event page (see frontend.js). Hidden by default; the browser's own
   page load (or a safety timeout) removes .is-visible again. */
body .cpe-loading-overlay{position:fixed;inset:0;background:rgba(10,10,14,.55);display:flex;align-items:center;justify-content:center;z-index:999999;opacity:0;visibility:hidden;pointer-events:none;transition:opacity .15s ease;}
body .cpe-loading-overlay.is-visible{opacity:1;visibility:visible;pointer-events:all;}

/* "Book Now" button loading state: swap the label for a small spinner
   instead of leaving the tap looking like it did nothing while
   Universe's embed script fetches the ticket popup. */
#cpe-app .unii-listing-button.is-loading{position:relative;color:transparent !important;pointer-events:none;}
#cpe-app .unii-listing-button.is-loading::after{content:"";position:absolute;top:50%;left:50%;width:18px;height:18px;margin:-9px 0 0 -9px;border:2px solid rgba(255,255,255,.45);border-top-color:#fff;border-radius:50%;animation:cpe-spin .6s linear infinite;}

/* ---------- RESPONSIVE ---------- */
@media (max-width: 1024px){
	/* Hero stacks image under copy, both centered as a block, matching
	   the reference's flex-col -> lg:flex-row breakpoint. */
	#cpe-app .cpe-hero-inner{flex-direction:column;align-items:stretch;gap:36px;}
	#cpe-app .cpe-hero-art{flex:0 0 auto;max-width:480px;margin:0 auto;}
	#cpe-app .cpe-hero-title{font-size:46px;}
	/* .cpe-hero-copy's flex-basis (460px) is a WIDTH hint for the
	   row layout above 1024px. Once flex-direction switches to
	   column here, "basis" maps to the main axis = height instead,
	   forcing a 460px-tall box regardless of how short the actual
	   text is — that's what was showing up as a big empty gap under
	   the badges. Reset it to a plain auto-height block down here. */
	#cpe-app .cpe-hero-copy{flex:0 0 auto;max-width:none;}
	/* 4-column grid needs a mid breakpoint before it collapses to 2 —
	   otherwise cards get uncomfortably narrow on tablet-width screens. */
	#cpe-app .cpe-grid{grid-template-columns:repeat(3,1fr);}
	/* 3 related cards visible at this width instead of 5. */
	#cpe-app .cpe-related-track .cpe-card{flex-basis:calc((100% - 2 * 12px) / 3);}
}
@media (max-width: 960px){
	/* Single column, source order top -> sidebar -> body (see the
	   .cpe-single-grid comment above), so the booking box sits right
	   under the meta strip instead of below all the tab content. */
	#cpe-app .cpe-single-grid{grid-template-columns:1fr;grid-template-areas:"top" "sidebar" "body";gap:24px;}
	#cpe-app .cpe-sidebar{position:static;margin-bottom:24px;}
	/* 2.2 visible (a peek of the 3rd card hints there's more to scroll to). */
	#cpe-app .cpe-related-track .cpe-card{flex-basis:calc((100% - 12px) / 2.2);}
	#cpe-app .cpe-grid{grid-template-columns:repeat(2,1fr);}
	#cpe-app .cpe-info-strip{grid-template-columns:1fr;}
	#cpe-app .cpe-highlight-list{grid-template-columns:1fr;}
	/* Client request: Schedule/Venue info row stacks on mobile. */
	#cpe-app .cpe-info-row{grid-template-columns:1fr !important;}
	/* Client request: on mobile, the Schedule/Location/Organizer info row
	   moves to sit right after Date & Time and before Location (it's up
	   near the top, right under the meta strip, on desktop) — swap which
	   rendered copy is visible (see cpe_render_single_info_row() /
	   .cpe-info-row--desktop-only vs --mobile-only in the single event
	   template) and give the now-visible one an `order` between the
	   Date & Time and Schedule tab panels. The duplicate lower Organizer
	   tab was already removed, so the full mobile order is now:
	   About -> Date & Time -> [this info row] -> Schedule -> Location ->
	   Related. Desktop keeps its own layout entirely — this only takes
	   effect once .cpe-single-body switches to a flex column at this
	   breakpoint, since CSS `order` has no effect on plain block-flow
	   children. */
	#cpe-app .cpe-info-row--desktop-only{display:none;}
	/* Fix (client-reported): keep this new mobile-only block's spacing
	   consistent with every other section's rhythm — same 44px
	   margin-bottom every .cpe-tab-panel already uses on mobile (see the
	   base .cpe-tab-panel rule), rather than a one-off smaller value. */
	#cpe-app .cpe-info-row--mobile-only{display:block;order:3;margin-bottom:44px;}
	#cpe-app .cpe-single-body{display:flex;flex-direction:column;}
	#cpe-app .cpe-tab-panel[data-panel="about"]{order:1;}
	#cpe-app .cpe-tab-panel[data-panel="datetime"]{order:2;}
	#cpe-app .cpe-tab-panel[data-panel="schedule"]{order:4;}
	#cpe-app .cpe-tab-panel[data-panel="location"]{order:5;}
	#cpe-app .cpe-tab-panel[data-panel="related"]{order:6;}
	#cpe-app .cpe-tabs{order:0;}
	#cpe-app .cpe-tab-btn[data-tab="about"]{order:1;}
	#cpe-app .cpe-tab-btn[data-tab="datetime"]{order:2;}
	#cpe-app .cpe-tab-btn[data-tab="schedule"]{order:3;}
	#cpe-app .cpe-tab-btn[data-tab="location"]{order:4;}
	#cpe-app .cpe-tab-btn[data-tab="related"]{order:5;}
	/* Mobile-only sticky booking bar (client request: "especially on
	   mobile only" — desktop keeps the existing sticky-to-top sidebar
	   instead, no bottom bar needed there). Sidebar's own CTA stays in
	   place too — this bar is an always-reachable shortcut to it while
	   scrolling, not a replacement, so the extra room at the very bottom
	   of the page (single.cpe-single padding) needs to clear it. */
	#cpe-app .cpe-sticky-bookbar{
		display:flex;position:fixed;left:0;right:0;bottom:0;z-index:9999;
		align-items:center;justify-content:space-between;gap:16px;
		background:var(--cpevn-card);border-top:1px solid var(--cpevn-card-border);
		padding:12px 16px;padding-bottom:calc(12px + env(safe-area-inset-bottom));
		box-shadow:0 -8px 24px rgba(0,0,0,.35);
	}
	#cpe-app.cpe-single{padding-bottom:88px;}
}
@media (max-width: 640px){
	#cpe-app .cpe-container{padding:40px 16px 0; margin:0 auto 40px;}
	/* 1.6 visible on phones -- still peeks the next card without feeling cramped. */
	#cpe-app .cpe-related-track .cpe-card{flex-basis:calc((100% - 12px) / 1.6);}
	#cpe-app .cpe-hero{margin-bottom:32px;padding:44px 0 56px;}
	#cpe-app .cpe-hero--bg-image{background-image:none !important;background-color:transparent;min-height:0;display:block;padding-top:0;}
	#cpe-app .cpe-hero--bg-image::before{display:none;}
	/* Full-bleed banner image at the very top of the hero on mobile —
	   no orange fill behind it, just the uploaded image itself at a
	   fixed 400px height, edge-to-edge with the viewport. order:-1
	   pulls it above the copy even though it's after it in the markup.
	   object-fit:contain (not cover) so the whole image is always
	   visible instead of cropping off text/logos baked into it; the
	   dark background fills any letterboxing that leaves. */
	#cpe-app .cpe-hero-mobile-img{
		display:block;
		order:-1;
		width:100vw;
		height:auto;
		margin-left:calc(50% - 50vw);
		margin-right:calc(50% - 50vw);
		margin-top:0;
		margin-bottom:24px;
		border-radius:0;
		overflow:hidden;
		background:var(--cpevn-bg);
	}
	#cpe-app .cpe-hero-mobile-img img{width:100%;height:100%;object-fit:contain;display:block;}
	#cpe-app .cpe-hero-inner{padding:0 16px;gap:28px;}
	#cpe-app .cpe-hero-title{font-size:32px;}
	#cpe-app .cpe-hero-subtitle{font-size:16px;margin:6px 0 20px;}
	#cpe-app .cpe-hero-desc{margin:0 0 24px;}
	#cpe-app .cpe-badges{gap:14px 18px;}
	#cpe-app .cpe-hero-art img,
	#cpe-app .cpe-hero-art-graphic{transform:rotate(1.5deg);}
	#cpe-app .cpe-hero-art-graphic{min-height:240px;padding:24px 16px;}
	#cpe-app .cpe-hero-art-title{font-size:26px;}
	#cpe-app .cpe-hero-art-kicker{font-size:16px;padding:5px 12px;}
	#cpe-app .cpe-hero-art-check{width:32px;height:32px;top:-12px;right:-16px;border-width:3px;}
	#cpe-app .cpe-hero-art-check svg{width:16px;height:16px;}
	#cpe-app .cpe-hero-art-tag,
	#cpe-app .cpe-hero-art-sub{font-size:11px;}
	#cpe-app .cpe-featured{flex-direction:column;gap:16px;}
	#cpe-app .cpe-featured-media{min-height:180px;flex-basis:auto;}
	#cpe-app .cpe-featured-body{padding:0 4px 4px;}
	/* Small cards (Related Events / [events_grid]) stay 2-across even on
	   phones — collapsing all the way to 1 wastes the point of them
	   being "small" cards in the first place. */
	#cpe-app .cpe-filter-tabs{overflow-x:auto;flex-wrap:nowrap;padding-bottom:4px;}

	/* Meta strip (date / time / venue / language on the single event
	   page) stacks one item per line on a phone instead of wrapping
	   inline, matching the reference mobile layout. */
	#cpe-app .cpe-meta-strip{flex-direction:column;align-items:flex-start;gap:12px;margin-bottom:24px;}
	#cpe-app .cpe-single-title{font-size:26px;}
	/* Banner now keeps its strict 2:1 aspect-ratio (see the base
	   .cpe-hero-banner rule) at every width, mobile included — no
	   fixed-height override needed here anymore. */

	/* Event cards (listing grid + "Related Events") on mobile: square
	   image on top (full card width), body below. !important guards
	   below are deliberate — the theme was overriding our plain
	   flex-direction rule and keeping the image/body side-by-side
	   despite this exact rule already being here (same root cause as
	   the icon-centering fix above: a higher-specificity theme style
	   winning the cascade). */
	#cpe-app .cpe-grid{grid-template-columns:1fr !important;gap:12px;}
	#cpe-app .cpe-card{display:flex !important;flex-direction:column !important;align-items:stretch !important;}
	#cpe-app .cpe-card-media{width:100% !important;flex-basis:auto !important;aspect-ratio:16/9 !important;height:auto !important;}
	#cpe-app .cpe-card-tag{font-size:10px;padding:4px 7px;top:6px;left:6px;}
	#cpe-app .cpe-card-body{padding:12px 14px;gap:8px;}
	#cpe-app .cpe-card-row{gap:10px;}
	#cpe-app .cpe-date-block{min-width:32px;padding-right:10px;}
	#cpe-app .cpe-date-block .dom{font-size:20px;}
	#cpe-app .cpe-card-title{font-size:15px;margin-bottom:4px;-webkit-line-clamp:2;display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;}
	#cpe-app .cpe-card-meta{gap:4px 10px;font-size:13px;}
	#cpe-app .cpe-card-foot{padding-top:6px;flex-wrap:wrap;gap:8px;}
	#cpe-app .cpe-card-foot .cpe-btn{padding:8px 14px;font-size:12px;}
	#cpe-app .cpe-card-ctas{justify-content:flex-start;width:100%;}
}
