/* ==========================================================================
   THE NEXUS — Homepage
   Implements design-system/10-homepage-strategy.md. Every value here reads
   from tokens.css custom properties — no hardcoded colors/type/spacing.
   ========================================================================== */

/* ---------- base / reset (nx- pages only, scoped by body.home/.nx-page) ----------
   Any page built from this widget library needs to opt in here — currently
   the homepage (body.home, WP's native front-page class) and the About page
   (body.nx-page, added via the body_class filter in nexus-homepage.php,
   since WordPress does not add a page-{slug} class by default). Extend the
   nexus_home_body_class() condition, not this file, for future pages. */
/* overflow-x lives on <html>, not <body> — setting it on body pairs with the
   default overflow-y:visible and gets silently promoted to overflow-y:auto,
   which turns body into its own scroll container and breaks window.scrollTo
   (expects documentElement to be the scrolling element). */
html:has(body.home),
html:has(body.nx-page) {
	/* `overflow-x: hidden` unconditionally promotes the other axis's used
	   value to `auto` per spec — "one axis non-visible forces the other
	   off visible too" — and there is no way to override that by also
	   setting overflow-y: visible; the browser still computes auto for
	   it regardless of author intent, since the promotion runs on used
	   values, not on which declarations were authored. That auto turns
	   <html> into its own scroll container, which breaks
	   position:sticky for every descendant (the sticky containing block
	   stops being the viewport). `overflow-x: clip` gets the same
	   "no horizontal scrollbar" result without ever forming a scroll
	   container, so it doesn't trigger the promotion at all — the fix
	   here is the value, not an extra override rule. */
	overflow-x: clip;
	/* <body> gets --color-bg below, but <html> itself was left at the
	   browser default (white/transparent) — invisible on desktop since
	   body always fully covers the viewport there, but mobile Safari/Chrome
	   rubber-band overscroll (top and bottom bounce) briefly exposes <html>
	   beneath <body>, flashing white on every dark nx- page. nexus-events.css
	   already carries this exact fix for single-etn event pages
	   (html:has(body.single-etn)); this mirrors it for the rest. */
	background: var(--color-bg);
}
/* Astra's own theme CSS independently sets `body { overflow-x: hidden; }`
   site-wide (main.min.css) — same bug, but on <body> this time, which (per
   the note above) makes body itself a scroll container even with the
   <html> fix in place. Same fix, scoped to these pages only. */
body.home,
body.nx-page {
	overflow-x: clip;
}
body.home,
body.nx-page {
	background: var(--color-bg);
	color: var(--color-text-primary);
	font-family: var(--font-body);
}
body.home *, body.nx-page * { box-sizing: border-box; }
body.home img, body.nx-page img { max-width: 100%; display: block; }
body.home a, body.nx-page a { color: inherit; }
/* The active header/footer plugin needs a real (non-canvas) page template to
   inject into, and that template brings Astra's own boxed .ast-container
   wrapper along with it — neutralize it on these pages only, so it doesn't
   fight this file's own full-width sections. Every other page keeps
   Astra's boxed layout untouched. */
body.home .ast-container,
body.nx-page .ast-container {
	max-width: none;
	padding-inline: 0;
	margin-inline: 0;
	width: 100%;
}
body.home :focus-visible,
body.nx-page :focus-visible {
	outline: 2px solid var(--color-gold-500);
	outline-offset: 3px;
	box-shadow: var(--glow-focus);
	border-radius: var(--radius-xs);
}

.nx-container {
	max-width: var(--container-max);
	margin-inline: auto;
	padding-inline: var(--container-margin);
}

.nx-eyebrow {
	font-family: var(--font-heading);
	font-weight: 500;
	font-size: var(--text-h6-overline);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-text-muted);
	margin: 0 0 var(--space-4);
}

.nx-h2 {
	font-family: var(--font-heading);
	font-weight: 600;
	font-size: var(--text-h2);
	line-height: 1.1;
	letter-spacing: -0.01em;
	margin: 0;
	max-width: 20ch;
	text-wrap: balance;
	/* Astra's theme CSS sets an explicit (dark, near-illegible-on-void)
	   color on bare h1-h6 elements. An explicit rule always wins over an
	   inherited one regardless of specificity, so every heading in this
	   system must set its own color rather than rely on inheriting it
	   from body.home/.nx-page — this is the fix for that whole class of
	   bug, not just this one heading. */
	color: var(--color-text-primary);
}

.nx-section-head { margin-bottom: var(--space-9); }

.screen-reader-text {
	position: absolute !important;
	width: 1px; height: 1px;
	overflow: hidden;
	clip: rect(1px,1px,1px,1px);
	white-space: nowrap;
}

/* ---------- buttons ---------- */
.nx-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-2);
	font-family: var(--font-heading);
	font-weight: 600;
	font-size: var(--text-body-s);
	letter-spacing: 0.01em;
	padding: var(--space-4) var(--space-7);
	border-radius: var(--radius-sm);
	text-decoration: none;
	cursor: pointer;
	transition: background-color var(--duration-fast) var(--ease-standard),
		color var(--duration-fast) var(--ease-standard),
		border-color var(--duration-fast) var(--ease-standard),
		box-shadow var(--duration-fast) var(--ease-standard),
		transform var(--duration-instant) var(--ease-standard);
	min-height: 44px;
}
/* `display: inline-flex` above is an author-stylesheet rule, which beats
   the browser's own `[hidden] { display: none }` UA rule regardless of
   specificity — so JS toggling the `hidden` attribute (event grid's "Load
   More", set via `p.hidden = true` in nexus-homepage.js) silently stopped
   working the moment a button carried this class, leaving a "Load More"
   button visible over an empty state with nothing left to load. Same fix
   already applied to the voices carousel's `.nx-voices__slide[hidden]` —
   applying it here too rather than leaving this one class of button exempt. */
.nx-btn[hidden] { display: none; }
.nx-btn:active { transform: scale(0.98); }
.nx-btn--primary {
	background: var(--color-gold-500);
	color: var(--color-void);
	box-shadow: var(--glow-gold-md);
}
.nx-btn--primary:hover { background: var(--color-gold-300); }
.nx-btn--primary:active { background: var(--color-gold-700); }
.nx-btn--ghost {
	background: transparent;
	color: var(--color-text-primary);
	border: var(--stroke-default) solid var(--color-border-default);
}
.nx-btn--ghost:hover { border-color: var(--color-gold-500); color: var(--color-gold-300); }
.nx-btn--sm { padding: var(--space-3) var(--space-5); font-size: var(--text-caption); min-height: 40px; }
/* "Outline (on photo/glass)" — §04.2. For buttons sitting directly on
   photography/canvas (e.g. the hero), where a solid gold fill would compete
   with the starfield rather than sit on it. */
.nx-btn--outline {
	background: transparent;
	color: var(--color-text-primary);
	border: var(--stroke-default) solid rgba(255,255,255,0.4);
}
.nx-btn--outline:hover { border-color: var(--color-text-primary); }

/* NAV: intentionally not styled here. This plugin's own bespoke nav
   (templates/nav.php) was retired in favor of the site-wide Ultimate
   Addons for Elementor header/footer templates (see class-nexus-about.php
   history / project notes) — its markup independently uses a `.nx-nav`
   class of its own for the mega-menu's link list. A same-named `.nx-nav`
   rule block used to live here too, a leftover from the retired system;
   since nexus-homepage.css loads site-wide, its `position: fixed` (with no
   height constraint) collided with the UAE header's unrelated `.nx-nav`
   element and stretched it to cover the full page on every page site-wide.
   Removed rather than renamed, since nothing in this plugin renders that
   markup anymore — grep widgets/ for `nx-nav` before reintroducing it. */

/* ============================================================
   HERO
   ============================================================ */
.nx-hero {
	position: relative;
	min-height: 100vh;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	overflow: hidden;
	background: var(--color-void);
}
.nx-hero__canvas-root { position: absolute; inset: 0; width: 100%; height: 100%; overflow: hidden; background: #000; z-index: 0; pointer-events: none; }
.nx-hero__canvas-root canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

/* Full-bleed photo hero (Communities) — swaps in for the starfield canvas
   when a background image is set. Same centered-content layout, same
   overlay-scrim token already used for image/text legibility elsewhere in
   the design system, so it reads as a variant of the one hero, not a
   second component. */
.nx-hero__bg { position: absolute; inset: 0; z-index: 0; margin: 0; overflow: hidden; }
/* height:100% !important is load-bearing: Elementor's own frontend.min.css
   ships `.elementor img { height: auto; }` at the exact same specificity
   (one class + type selector) and wins the source-order tie, silently
   turning this into "auto height at the image's intrinsic ratio" instead
   of a full-bleed cover. Invisible on wide/short viewports where the
   intrinsic-ratio height happens to exceed the container by coincidence,
   but a hard gap of bare background below the photo on tall/narrow ones
   (confirmed on mobile: a 4:3 photo at 100% width stopped ~1/3 of the way
   down a 100vh hero, leaving the rest of the hero plain black). */
.nx-hero__bg img { width: 100%; height: 100% !important; object-fit: cover; display: block; }
.nx-hero__bg-scrim { position: absolute; inset: 0; background: var(--overlay-scrim); }
.nx-hero--bg .nx-hero__headline,
.nx-hero--bg .nx-hero__intro { text-shadow: 0 2px 24px rgba(0,0,0,0.4); }

/* width: 100% is load-bearing here, not decorative — .nx-hero uses
   align-items: center (not the flex default of stretch) on its column axis,
   so without an explicit width this flex item shrinks to fit its widest
   child (the logo) instead of taking the intended 900px column. That was
   quietly forcing "WHERE STORIES BEGIN" to wrap one word per line, since
   the headline's wrap width was the logo's width, not 900px. */
.nx-hero__content { position: relative; z-index: 2; width: 100%; max-width: 900px; text-align: center; padding-inline: var(--container-margin); display: flex; flex-direction: column; align-items: center; }
/* Wide variant: the About hero's letter-split headline is sized to fill
   most of the viewport width (see .nx-hero__headline--letters below), so
   it needs a much roomier column than the default 900px hero cap. */
.nx-hero__content--wide { max-width: 1800px; }
.nx-hero .nx-hero__logo {
	height: clamp(150px, 26vw, 360px);
	width: auto;
	margin: 0 0 var(--space-8);
	filter: drop-shadow(0 0 44px rgba(201, 162, 75, 0.3));
}
/* Default hero identity mark: an eyebrow label, not a second logo — the
   nav already carries the wordmark top-left, so repeating it full-size in
   the hero was pure duplication rather than hierarchy. */
.nx-hero__eyebrow { text-align: center; margin: 0 0 var(--space-6); }
/* Subheading scale, not the full hero-display treatment — the logo is the
   primary mark now, this just names the moment underneath it. Sized well
   below the logo's own scale on purpose, so it reads as a caption rather
   than competing with it. */
.nx-hero__headline {
	font-family: var(--font-display);
	font-weight: 700;
	font-size: var(--text-h4);
	line-height: 1.2;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	margin: 0;
	color: var(--color-text-secondary);
}
/* Per-letter headline — same mechanic as the footer's "Get In Touch" CTA
   (span-per-letter, scaleY stretch + gold on hover), reused here rather than
   invented fresh so the two "big letters" moments on the site (footer CTA,
   About hero) share one animation language. */
.nx-hero__headline--letters {
	/* Extreme scale, matching the "OUR STUDIO"-style reference: letters
	   run near edge-to-edge on desktop rather than sitting at the
	   restrained size the default line-mask hero headline uses. */
	font-size: clamp(4.5rem, 1.5rem + 15vw, 15rem);
	line-height: 0.85;
	letter-spacing: -0.01em;
	/* Every page that uses this letter-split treatment (About, Contact,
	   Communities, Events, Corporate) also sets hide_logo=yes — it's
	   never paired with the logo mark, so unlike the default line-mask
	   headline (a caption sitting under the logo, correctly muted) this
	   one IS the hero's primary visual. The inherited --color-text-secondary
	   from .nx-hero__headline was sized for the caption role and left
	   these full-width, edge-to-edge headlines looking washed out at 72%
	   opacity instead of carrying the page. */
	color: var(--color-text-primary);
}
/* Compact variant — same mechanic, smaller clamp for 3+ word headlines
   (e.g. "DISCOVER WHAT'S NEXT" on Events) so they don't hit the full-size
   clamp's extreme scale, which overflowed the hero's height and collided
   with the photo cluster. Words are forced one-per-line (rather than left
   to wrap naturally) because natural wrapping is viewport-width dependent:
   at wide desktop widths all three words fit on one line, which is wide
   enough to run straight into the photo cluster on either side. */
.nx-hero__headline--letters-compact {
	font-size: clamp(2.5rem, 1rem + 6vw, 7rem);
	line-height: 1.05;
}
.nx-hero__headline--letters .nx-word { display: inline-block; white-space: nowrap; }
.nx-hero__headline--letters-compact .nx-word { display: block; }
.nx-hero__headline--letters .nx-letter {
	display: inline-block;
	transform-origin: 50% 100%;
	opacity: 0;
	transform: translateY(40px) scaleY(1);
	transition: transform 200ms ease, color 200ms ease;
}
.nx-hero__headline--letters .nx-letter.is-visible {
	opacity: 1;
	transform: translateY(0) scaleY(1);
	transition: opacity var(--duration-slow) var(--ease-out-expo), transform var(--duration-slow) var(--ease-out-expo);
}
@media (hover: hover) and (pointer: fine) {
	.nx-hero__headline--letters .nx-letter:hover {
		color: var(--color-gold-500);
		transform: scaleY(1.3);
		transition: transform 200ms ease, color 200ms ease;
	}
}
@media (prefers-reduced-motion: reduce) {
	.nx-hero__headline--letters .nx-letter { opacity: 1; transform: none; }
}

.nx-hero__intro {
	font-family: var(--font-body);
	font-size: var(--text-body-l);
	line-height: 1.6;
	color: var(--color-text-secondary);
	max-width: 46ch;
	margin: var(--space-7) 0 0;
}

.nx-hero__actions { margin-top: var(--space-8); }

.nx-hero__cluster { position: absolute; inset: 0; z-index: 1; pointer-events: none; display: none; }
@media (min-width: 1024px) { .nx-hero__cluster { display: block; } }
.nx-hero__photo {
	position: absolute; margin: 0;
	width: 220px; aspect-ratio: 340/430;
	border-radius: var(--radius-md);
	overflow: hidden;
	box-shadow: var(--shadow-4);
	transition: transform var(--duration-fast) var(--ease-standard);
}
.nx-hero .nx-hero__photo img { width: 100%; height: 100%; object-fit: cover; }
/* Photos must never intrude on the centered .nx-hero__content column
   (max-width: 900px), and must never fly off-canvas either. max() picks
   whichever inset is LARGER — the flat 8-9% edge offset on most desktop
   widths, or the calc()'d headline-clearance distance on ultra-wide screens
   where that pushes the photo out even further for extra breathing room.
   (This was min() before, which — since the calc() term goes deeply
   negative at ordinary laptop widths like 1440px — picked that negative
   value and dragged the photo off the left edge of the viewport.) */
.nx-hero__photo--1 { top: 30%; left: max(8%, calc(50% - 450px - 220px - 32px)); transform: rotate(-6deg); }
.nx-hero__photo--2 { bottom: 14%; right: max(9%, calc(50% - 450px - 240px - 32px)); transform: rotate(5deg); width: 240px; }
@media (min-width: 1440px) {
	.nx-hero__photo { width: 280px; }
	.nx-hero__photo--1 { left: max(8%, calc(50% - 450px - 280px - 32px)); }
	.nx-hero__photo--2 { width: 300px; right: max(9%, calc(50% - 450px - 300px - 32px)); }
}

.nx-hero__scroll-cue { position: absolute; bottom: var(--space-9); left: 50%; transform: translateX(-50%); z-index: 2; }
.nx-hero__scroll-line { display: block; width: 1px; height: 48px; background: linear-gradient(to bottom, var(--color-text-muted), transparent); animation: nx-scroll-cue 2.4s var(--ease-in-out-soft) infinite; }
@keyframes nx-scroll-cue { 0%,100% { opacity: 0.3; transform: scaleY(0.6); transform-origin: top; } 50% { opacity: 1; transform: scaleY(1); transform-origin: top; } }
@media (prefers-reduced-motion: reduce) { .nx-hero__scroll-line { animation: none; opacity: 0.6; } }

/* Cursor image trail — opt-in hero enhancement (Communities page). As the
   visitor moves the pointer across the hero, nexus-homepage.js cycles
   through these hidden frames, positioning whichever one is "up" at the
   cursor and fading it in/out. Desktop pointer-driven only: mobile/touch
   never gets a mousemove trail, so the section just renders without it —
   no separate mobile treatment needed. */
.nx-hero__trail { position: absolute; inset: 0; z-index: 1; overflow: hidden; pointer-events: none; }
@media (hover: none) or (pointer: coarse) { .nx-hero__trail { display: none; } }
.nx-hero__trail-item {
	position: absolute; top: 0; left: 0;
	width: 220px; aspect-ratio: 4/3;
	margin: -110px 0 0 -110px;
	border-radius: var(--radius-md);
	overflow: hidden;
	box-shadow: var(--shadow-4);
	opacity: 0;
	transform: translate3d(-9999px, -9999px, 0) scale(0.85);
	transition: opacity var(--duration-moderate) var(--ease-out-expo), transform var(--duration-moderate) var(--ease-out-expo);
	will-change: transform, opacity;
}
.nx-hero__trail-item img { width: 100%; height: 100% !important; object-fit: cover; display: block; }
.nx-hero__trail-item.is-active { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .nx-hero__trail { display: none; } }

/* ============================================================
   THE SIGNAL
   ============================================================ */
.nx-signal {
	position: relative; z-index: 2;
	background: var(--color-bg);
	padding-block: var(--space-9);
	padding-inline: var(--container-margin);
	text-align: center;
}
/* A small anchor mark so the statement doesn't read as text floating
   unframed in empty space — restrained (a single hairline, no icon/badge),
   in keeping with this section's deliberately quiet "one confident line"
   role rather than turning it into a denser block. */
.nx-signal__mark {
	display: block;
	width: var(--stroke-bold);
	height: 28px;
	margin: 0 auto var(--space-6);
	background: var(--color-gold-500);
	border-radius: var(--radius-full);
}
.nx-signal__text {
	font-family: var(--font-serif);
	font-style: italic;
	font-weight: 400;
	font-size: var(--text-display-l);
	line-height: 1.25;
	max-width: 16ch;
	margin: 0 auto;
	color: var(--color-text-primary);
	text-wrap: balance;
}

/* ============================================================
   COMMUNITIES
   ============================================================ */
.nx-communities { position: relative; z-index: 2; background: var(--color-bg); padding-block: var(--space-13); }
.nx-community-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-6);
}
@media (min-width: 768px) {
	.nx-community-grid { grid-template-columns: repeat(2, 1fr); gap: var(--space-7); }
	.nx-community-tile--lead { grid-column: span 2; }
}
@media (min-width: 1024px) {
	.nx-community-grid { grid-template-columns: repeat(6, 1fr); grid-auto-rows: 180px; }
	.nx-community-tile--lead { grid-column: span 4; grid-row: span 3; }
	.nx-community-tile:not(.nx-community-tile--lead) { grid-column: span 2; grid-row: span 3; }
	.nx-community-tile:nth-of-type(2) { grid-row: span 3; }
}

/* --trio: exactly 3 tiles (Events page "Explore our communities") — the
   6-tile bento math above leaves a third card orphaned on its own row, so
   this swaps in a plain, even grid: stacked on mobile/tablet, three equal
   columns on desktop. */
.nx-community-grid--trio.nx-community-grid { grid-template-columns: 1fr; }
@media (min-width: 1024px) {
	.nx-community-grid--trio.nx-community-grid { grid-template-columns: repeat(3, 1fr); grid-auto-rows: auto; }
	.nx-community-grid--trio .nx-community-tile--lead,
	.nx-community-grid--trio .nx-community-tile:not(.nx-community-tile--lead) { grid-column: span 1; grid-row: span 1; }
	.nx-community-grid--trio .nx-community-tile { aspect-ratio: 4 / 5; height: auto; }
}

.nx-community-tile {
	position: relative;
	display: block;
	aspect-ratio: 4/5;
	border-radius: var(--radius-lg);
	overflow: hidden;
	text-decoration: none;
	box-shadow: var(--shadow-1);
}
@media (min-width: 1024px) { .nx-community-tile { aspect-ratio: auto; height: 100%; } }
.nx-community-tile .nx-community-tile__img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--duration-base) var(--ease-out-expo); }
.nx-community-tile__scrim { position: absolute; inset: 0; background: var(--gradient-image-scrim); transition: opacity var(--duration-base); }
.nx-community-tile__text { position: absolute; left: var(--space-6); right: var(--space-6); bottom: var(--space-6); display: flex; flex-direction: column; gap: var(--space-2); }
.nx-community-tile__category { color: var(--color-gold-500); margin: 0; }
.nx-community-tile__title { font-family: var(--font-heading); font-weight: 600; font-size: var(--text-h3); color: var(--color-text-primary); }
.nx-community-tile:hover .nx-community-tile__img,
.nx-community-tile:focus-visible .nx-community-tile__img { transform: scale(1.04); }
.nx-community-tile:hover .nx-community-tile__category,
.nx-community-tile:focus-visible .nx-community-tile__category { color: var(--color-gold-300); }

/* ============================================================
   TEXTURE WALL
   ============================================================ */
.nx-texture { position: relative; z-index: 2; background: var(--color-surface-1); padding-block: var(--space-13) var(--space-11); overflow: hidden; }
.nx-texture__mosaic { display: flex; flex-direction: column; gap: var(--space-4); margin-bottom: var(--space-11); }
.nx-texture__row { display: flex; gap: var(--space-4); will-change: transform; justify-content: center; }
.nx-texture__cell { flex: 1 1 260px; max-width: 420px; border-radius: var(--radius-md); overflow: hidden; }
.nx-texture .nx-texture__cell img { width: 100%; height: 100%; object-fit: cover; aspect-ratio: 4/5; }
@media (max-width: 767px) {
	.nx-texture__row { overflow-x: auto; scroll-snap-type: x mandatory; padding-inline: var(--container-margin); }
	.nx-texture__cell { flex: 0 0 70vw; scroll-snap-align: start; }
}

.nx-marquee { overflow: hidden; border-block: var(--stroke-hairline) solid var(--color-border-subtle); padding-block: var(--space-4); margin-bottom: var(--space-11); }
.nx-marquee__track { display: flex; width: max-content; animation: nx-marquee 40s linear infinite; }
.nx-marquee__item { font-family: var(--font-mono); font-size: var(--text-body-s); color: var(--color-text-muted); letter-spacing: 0.04em; padding-inline: var(--space-6); white-space: nowrap; }
@keyframes nx-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .nx-marquee__track { animation: none; } }

.nx-texture__counters { display: flex; justify-content: center; max-width: 640px; margin-inline: auto; }
.nx-counter { flex: 1 1 0; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; gap: var(--space-2); padding-inline: var(--space-6); }
.nx-counter:not(:first-child) { border-left: var(--stroke-hairline) solid var(--color-border-subtle); }
.nx-counter__number { display: block; font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--text-h2); line-height: 1; color: var(--color-gold-500); }
.nx-counter__label { font-size: var(--text-caption); color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.1em; }
@media (max-width: 767px) {
	.nx-texture__counters { flex-direction: column; align-items: stretch; max-width: 320px; gap: var(--space-6); }
	.nx-counter { padding-inline: 0; }
	.nx-counter:not(:first-child) { border-left: none; border-top: var(--stroke-hairline) solid var(--color-border-subtle); padding-top: var(--space-5); }
}

/* ============================================================
   MEMBER VOICES
   ============================================================ */
.nx-voices { position: relative; z-index: 2; background: var(--color-bg); }
.nx-voices__carousel { display: grid; grid-template-columns: 1fr; min-height: 70vh; }
@media (min-width: 1024px) { .nx-voices__carousel { grid-template-columns: 1fr 1.2fr; min-height: 90vh; } }

.nx-voices__slide { display: contents; }
.nx-voices__slide[hidden] { display: none; }

.nx-voices__portrait { grid-column: 1; grid-row: 1; margin: 0; order: 2; }
@media (min-width: 1024px) { .nx-voices__portrait { order: 1; } }
.nx-voices .nx-voices__portrait img { width: 100%; height: 100%; object-fit: cover; aspect-ratio: 4/3; }
@media (min-width: 1024px) { .nx-voices .nx-voices__portrait img { aspect-ratio: auto; height: 90vh; } }

.nx-voices__text { grid-column: 1; grid-row: 1; order: 1; display: flex; flex-direction: column; justify-content: center; padding: var(--space-9) var(--container-margin); }
@media (min-width: 1024px) { .nx-voices__text { order: 2; padding: var(--space-9) var(--space-13); } }
.nx-voices__quote { font-family: var(--font-serif); font-style: italic; font-size: var(--text-display-l); line-height: 1.25; margin: 0 0 var(--space-6); max-width: 14ch; color: var(--color-text-primary); }
.nx-voices__attribution { font-family: var(--font-heading); font-size: var(--text-body-s); color: var(--color-text-secondary); margin: 0; }

.nx-voices__controls { position: absolute; left: var(--container-margin); bottom: var(--space-9); display: flex; align-items: center; gap: var(--space-4); z-index: 3; }
@media (min-width: 1024px) { .nx-voices__controls { left: var(--space-13); } }
.nx-voices__arrow { width: 44px; height: 44px; border-radius: var(--radius-full); border: var(--stroke-default) solid var(--color-border-default); background: transparent; color: var(--color-text-primary); cursor: pointer; font-size: 18px; }
.nx-voices__arrow:hover { border-color: var(--color-gold-500); color: var(--color-gold-300); }
.nx-voices__counter { font-family: var(--font-mono); font-size: var(--text-caption); color: var(--color-text-muted); font-variant-numeric: tabular-nums; }
.nx-voices { position: relative; }

/* ============================================================
   THIS WEEK (LIVE STRIP)
   ============================================================ */
.nx-live-strip { position: relative; z-index: 2; background: var(--color-bg); padding-block: var(--space-13); }
.nx-live-strip__head { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-3); margin-bottom: var(--space-9); }
.nx-live-strip__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--color-ion-500); box-shadow: 0 0 0 0 rgba(111,168,255,0.5); animation: nx-live-pulse 3.2s var(--ease-in-out-soft) infinite; }
@keyframes nx-live-pulse { 0% { box-shadow: 0 0 0 0 rgba(111,168,255,0.5); } 70% { box-shadow: 0 0 0 8px rgba(111,168,255,0); } 100% { box-shadow: 0 0 0 0 rgba(111,168,255,0); } }
@media (prefers-reduced-motion: reduce) { .nx-live-strip__dot { animation: none; } }
.nx-live-strip__label { margin: 0; color: var(--color-ion-500); flex-basis: 100%; }
.nx-live-strip__head .nx-h2 { flex-basis: 100%; }

.nx-live-strip__track {
	display: flex; gap: var(--space-6);
	overflow-x: auto; scroll-snap-type: x mandatory;
	margin-inline: calc(var(--container-margin) * -1);
	padding-inline: var(--container-margin);
	padding-bottom: var(--space-4);
	scrollbar-width: thin; scrollbar-color: var(--color-border-default) transparent;
}
.nx-event-card { flex: 0 0 260px; scroll-snap-align: start; text-decoration: none; border-radius: var(--radius-md); overflow: hidden; background: var(--color-surface-2); border: var(--stroke-hairline) solid var(--color-border-subtle); transition: transform var(--duration-base) var(--ease-out-expo), border-color var(--duration-base); }
.nx-event-card:hover { transform: translateY(-4px); border-color: var(--color-border-strong); }
.nx-event-card__thumb { height: 150px; background-size: cover; background-position: center; background-color: var(--color-surface-3); }
.nx-event-card__body { padding: var(--space-5); }
.nx-event-card__date { font-family: var(--font-mono); font-size: var(--text-caption); color: var(--color-ion-500); margin: 0 0 var(--space-2); text-transform: uppercase; letter-spacing: 0.04em; }
.nx-event-card__title { font-family: var(--font-heading); font-weight: 600; font-size: var(--text-h4); color: var(--color-text-primary); margin: 0 0 var(--space-2); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.nx-event-card__meta { font-size: var(--text-body-s); color: var(--color-text-muted); margin: 0; }
.nx-event-card--empty { flex: 0 0 100%; text-align: center; padding: var(--space-9); }

/* ============================================================
   SPACES — editorial alternating split (image + text), not a wall of
   full-bleed crops. Redesigned 2026-08-07: the previous version stacked
   three 78vh full-width images with zero gap between them, which (a) forced
   every photo — including wide group shots — through the same tall crop
   regardless of its actual composition, and (b) read as a monotonous photo
   dump rather than storytelling, the opposite of the brief's "never repeat
   the same layout" / negative-space principles. This version gives each
   photo a contained, aspect-locked frame with real breathing room and pairs
   it with an editorial text column, alternating sides per panel.
   ============================================================ */
.nx-spaces { position: relative; z-index: 2; background: var(--color-bg); padding-block: var(--space-13); overflow: hidden; }
.nx-spaces__list { display: flex; flex-direction: column; gap: var(--space-13); }
.nx-spaces__panel {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-7);
	align-items: center;
}
@media (min-width: 1024px) {
	.nx-spaces__panel { grid-template-columns: 1.3fr 1fr; gap: var(--space-13); }
	.nx-spaces__panel--right { grid-template-columns: 1fr 1.3fr; }
	.nx-spaces__panel--right .nx-spaces__media { order: 2; }
	.nx-spaces__panel--right .nx-spaces__text { order: 1; }
}
.nx-spaces__media {
	position: relative;
	margin: 0;
	aspect-ratio: 5/4;
	border-radius: var(--radius-lg);
	overflow: hidden;
	box-shadow: var(--shadow-3);
}
.nx-spaces .nx-spaces__media img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform var(--duration-cinematic) var(--ease-out-expo); }
.nx-spaces__panel:hover .nx-spaces__media img { transform: scale(1.04); }
.nx-spaces__text { display: flex; flex-direction: column; gap: var(--space-3); max-width: 46ch; }
@media (min-width: 1024px) { .nx-spaces__panel--right .nx-spaces__text { justify-self: end; text-align: right; align-items: flex-end; } }
.nx-spaces__index {
	font-family: var(--font-mono);
	font-size: var(--text-caption);
	letter-spacing: var(--tracking-overline);
	color: var(--color-gold-500);
}
.nx-spaces__index i { font-style: normal; color: var(--color-text-disabled); }
.nx-spaces__location { font-family: var(--font-heading); font-weight: 600; font-size: var(--text-h3); color: var(--color-text-primary); line-height: 1.2; }
.nx-spaces__caption { font-family: var(--font-serif); font-style: italic; font-weight: 400; font-size: var(--text-body-l); line-height: 1.6; color: var(--color-text-secondary); margin: 0; }

/* ============================================================
   HOW IT WORKS
   ============================================================ */
.nx-how { position: relative; z-index: 2; background: var(--color-surface-1); padding-block: var(--space-13); }
.nx-how__steps { list-style: none; margin: 0 0 var(--space-13); padding: 0; display: grid; grid-template-columns: 1fr; gap: var(--space-9); }
@media (min-width: 768px) { .nx-how__steps { grid-template-columns: repeat(3, 1fr); gap: var(--space-7); } }
.nx-how__number { display: block; font-family: var(--font-display); font-size: var(--text-display-l); color: var(--color-gold-500); line-height: 1; margin-bottom: var(--space-4); }
.nx-how__step-title { font-family: var(--font-heading); font-weight: 600; font-size: var(--text-h4); margin: 0 0 var(--space-2); color: var(--color-text-primary); }
.nx-how__step-desc { color: var(--color-text-secondary); margin: 0; max-width: 40ch; }

.nx-how__qa { display: grid; grid-template-columns: 1fr; gap: var(--space-6); padding-top: var(--space-9); border-top: var(--stroke-hairline) solid var(--color-border-subtle); }
@media (min-width: 768px) { .nx-how__qa { grid-template-columns: repeat(3, 1fr); } }
.nx-how__question { font-family: var(--font-heading); font-weight: 600; margin: 0 0 var(--space-2); }
.nx-how__answer { font-size: var(--text-body-s); color: var(--color-text-secondary); margin: 0; }

/* ============================================================
   THE ASK
   ============================================================ */
.nx-ask { position: relative; z-index: 2; background: var(--color-void); padding-block: var(--space-14); text-align: center; overflow: hidden; }
.nx-ask__aurora { position: absolute; inset: 0; background: var(--gradient-aurora); pointer-events: none; }
.nx-ask__content { position: relative; z-index: 1; max-width: 720px; margin-inline: auto; padding-inline: var(--container-margin); }
.nx-ask__headline { font-family: var(--font-display); font-size: var(--text-display-l); text-transform: uppercase; letter-spacing: -0.02em; line-height: 1; margin: 0 0 var(--space-9); color: var(--color-text-primary); }
.nx-ask__actions { display: flex; flex-direction: column; align-items: center; gap: var(--space-5); }
.nx-ask__secondary { font-size: var(--text-body-s); color: var(--color-text-muted); text-decoration: underline; text-underline-offset: 4px; }
.nx-ask__secondary:hover { color: var(--color-text-secondary); }

/* ============================================================
   FOOTER
   ============================================================ */
.nx-footer { position: relative; z-index: 2; background: var(--color-surface-1); padding-block: var(--space-11) var(--space-6); }
.nx-footer__grid { display: grid; grid-template-columns: 1fr; gap: var(--space-9); margin-bottom: var(--space-9); }
@media (min-width: 768px) { .nx-footer__grid { grid-template-columns: 1.6fr repeat(3, 1fr); } }
.nx-footer .nx-footer__brand img { height: 22px; width: auto; margin-bottom: var(--space-4); }
.nx-footer__tagline { color: var(--color-text-muted); font-size: var(--text-body-s); max-width: 32ch; margin: 0 0 var(--space-6); }
.nx-footer__newsletter label { display: block; font-size: var(--text-caption); color: var(--color-text-secondary); margin-bottom: var(--space-2); }
.nx-footer__newsletter-row { display: flex; gap: var(--space-2); max-width: 320px; }
.nx-footer__newsletter-row input { flex: 1; background: var(--color-surface-2); border: var(--stroke-default) solid var(--color-border-default); border-radius: var(--radius-sm); padding: var(--space-3) var(--space-4); color: var(--color-text-primary); font-size: var(--text-body-s); min-height: 44px; }
.nx-footer__newsletter-row input:focus-visible { border-color: var(--color-gold-500); }
.nx-footer__col { display: flex; flex-direction: column; gap: var(--space-3); }
.nx-footer__col-title { font-family: var(--font-heading); font-weight: 600; color: var(--color-text-primary); margin: 0 0 var(--space-2); }
.nx-footer__col a { font-size: var(--text-body-s); color: var(--color-text-muted); text-decoration: none; }
.nx-footer__col a:hover { color: var(--color-text-primary); }
.nx-footer__bottom { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-4); padding-top: var(--space-6); border-top: var(--stroke-hairline) solid var(--color-border-subtle); font-size: var(--text-caption); color: var(--color-text-muted); }
.nx-footer__bottom p { margin: 0; }
.nx-footer__social { display: flex; gap: var(--space-5); }
.nx-footer__social a { color: var(--color-text-muted); text-decoration: none; }
.nx-footer__social a:hover { color: var(--color-text-primary); }

/* ============================================================
   ABOUT — "Three rooms. One instinct."
   Two-zone asymmetric composition: a left narrative column (eyebrow,
   headline, kinetic lede, CTA/meta) paired with a right editorial index of
   the three rooms. The index deliberately stays small/typographic (a peek
   thumbnail, not a full photo panel) — the Verticals Tabs section further
   down the page already owns the full photographic "pick your room"
   experience, so this section's job is comprehension + intrigue, not a
   second gallery.
   ============================================================ */
.nx-about { position: relative; z-index: 2; background: var(--color-bg); padding-block: var(--space-13); }

.nx-about__frame { display: flex; flex-direction: column; gap: var(--space-11); align-items: flex-start; }
@media (min-width: 1024px) { .nx-about__frame { flex-direction: row; gap: var(--space-13); } }

.nx-about__intro { flex: 1 1 100%; min-width: 0; max-width: 620px; }
@media (min-width: 1024px) { .nx-about__intro { flex: 0 1 580px; } }

.nx-about__eyebrow { display: flex; align-items: baseline; gap: var(--space-3); }

.nx-about__headline {
	font-family: var(--font-heading);
	font-weight: 600;
	/* A dedicated (slightly smaller than --text-display-l) clamp: the
	   headline renders as two explicit clauses (see the <br> in render()),
	   each needs to fit the intro column on one line at the largest
	   breakpoint — text-display-l's 5.5rem ceiling was wide enough to force
	   "Three rooms." to wrap a second time inside its own column. */
	font-size: clamp(2.5rem, 1.8rem + 3vw, 4.75rem);
	line-height: 1.08;
	letter-spacing: -0.02em;
	color: var(--color-text-primary);
	margin: 0 0 var(--space-7);
}

.nx-about__lede {
	font-size: var(--text-body-l);
	line-height: 1.6;
	color: var(--color-text-muted);
	max-width: 42ch;
	margin: 0 0 var(--space-9);
}
/* agntix-style: unrevealed words sit dim, revealed words step to full opacity — reads as a kinetic paragraph, not a flat fade-in */
.nx-about__lede .word { color: var(--color-text-muted); transition: color var(--duration-slow) var(--ease-out-expo); }
.nx-about__lede .word.is-revealed { color: var(--color-text-primary); }

.nx-about__foot { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-7); }
.nx-about__link { display: inline-flex; align-items: center; gap: var(--space-2); font-family: var(--font-heading); font-weight: 600; font-size: var(--text-body-s); color: var(--color-gold-500); text-decoration: none; }
.nx-about__link svg { transition: transform var(--duration-fast) var(--ease-standard); }
.nx-about__link:hover { color: var(--color-gold-300); }
.nx-about__link:hover svg { transform: translateY(3px); }
.nx-about__meta { display: flex; align-items: baseline; gap: var(--space-2); margin: 0; font-family: var(--font-mono); font-size: var(--text-caption); color: var(--color-text-muted); }
.nx-about__meta-figure { color: var(--color-text-secondary); }
.nx-about__meta-label { text-transform: uppercase; letter-spacing: 0.04em; }

/* -- the index -- */
.nx-about__index-wrap { flex: 1 1 100%; min-width: 0; width: 100%; }
@media (min-width: 1024px) { .nx-about__index-wrap { flex: 1 1 auto; margin-top: var(--space-11); } }
.nx-about__index-label { margin-bottom: var(--space-5); }
.nx-about__index { list-style: none; margin: 0; padding: 0; border-top: var(--stroke-hairline) solid var(--color-border-subtle); }

.nx-about__index-item {
	display: flex;
	align-items: center;
	gap: var(--space-5);
	padding-block: var(--space-6);
	border-bottom: var(--stroke-hairline) solid var(--color-border-subtle);
	text-decoration: none;
	min-height: 44px;
}
@media (min-width: 640px) { .nx-about__index-item { gap: var(--space-7); padding-block: var(--space-7); } }

.nx-about__index-num {
	flex: 0 0 auto;
	font-family: var(--font-mono);
	font-size: var(--text-h4);
	color: var(--color-gold-500);
	font-variant-numeric: tabular-nums;
	transition: color var(--duration-base) var(--ease-standard);
}
.nx-about__index-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.nx-about__index-title {
	font-family: var(--font-heading);
	font-weight: 600;
	font-size: var(--text-h4);
	text-transform: uppercase;
	letter-spacing: 0.02em;
	color: var(--color-text-primary);
	transition: color var(--duration-base) var(--ease-standard);
}
.nx-about__index-desc { font-size: var(--text-body-s); color: var(--color-text-secondary); max-width: 42ch; }
.nx-about__index-thumb {
	flex: 0 0 auto;
	width: 64px; height: 84px;
	border-radius: var(--radius-sm);
	overflow: hidden;
	box-shadow: var(--shadow-1);
}
@media (min-width: 640px) { .nx-about__index-thumb { width: 84px; height: 108px; } }
.nx-about__index-thumb img { width: 100%; height: 100% !important; object-fit: cover; display: block; transition: transform var(--duration-base) var(--ease-out-expo); }
.nx-about__index-arrow { flex: 0 0 auto; display: none; color: var(--color-text-muted); transition: transform var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard); }
@media (min-width: 640px) { .nx-about__index-arrow { display: block; } }

.nx-about__index-item:hover .nx-about__index-num,
.nx-about__index-item:focus-visible .nx-about__index-num { color: var(--color-gold-300); }
.nx-about__index-item:hover .nx-about__index-title,
.nx-about__index-item:focus-visible .nx-about__index-title { color: var(--color-gold-300); }
.nx-about__index-item:hover .nx-about__index-thumb img,
.nx-about__index-item:focus-visible .nx-about__index-thumb img { transform: scale(1.06); }
.nx-about__index-item:hover .nx-about__index-arrow,
.nx-about__index-item:focus-visible .nx-about__index-arrow { transform: translateX(3px); color: var(--color-gold-500); }

/* ============================================================
   EVENTS TEASER
   ============================================================ */
.nx-events-teaser { position: relative; z-index: 2; background: var(--color-surface-1); padding-block: var(--space-13); }
.nx-events-teaser__head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-end; gap: var(--space-5); }
/* auto-fill/minmax instead of fixed breakpoint column counts — cards always
   stretch to fill the row edge-to-edge at whatever width they land on,
   rather than 3 fixed narrow columns stranding empty space beside them. */
.nx-events-teaser__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: var(--space-7); }
.nx-events-teaser__card {
	display: flex;
	flex-direction: column;
	text-decoration: none;
	border-radius: var(--radius-lg);
	overflow: hidden;
	background: var(--color-surface-2);
	border: var(--stroke-hairline) solid var(--color-border-subtle);
	transition: transform var(--duration-base) var(--ease-out-expo), border-color var(--duration-base), box-shadow var(--duration-base);
}
.nx-events-teaser__card:hover { transform: translateY(-4px); border-color: var(--color-border-strong); box-shadow: var(--shadow-3); }
.nx-events-teaser__thumb {
	position: relative;
	aspect-ratio: 4 / 3;
	background-size: contain;
	background-repeat: no-repeat;
	background-position: center;
	background-color: var(--color-surface-3);
	display: flex;
	align-items: center;
	justify-content: center;
}
/* No banner uploaded yet — the day number stands in as a deliberate
   editorial mark instead of a blank/broken-looking box. */
.nx-events-teaser__thumb-day { display: flex; flex-direction: column; align-items: center; color: var(--color-text-disabled); }
.nx-events-teaser__thumb-day strong { font-family: var(--font-display); font-size: 4rem; line-height: 0.9; color: var(--color-text-muted); }
.nx-events-teaser__thumb-day span { font-family: var(--font-mono); font-size: var(--text-caption); letter-spacing: 0.08em; text-transform: uppercase; margin-top: var(--space-2); }
.nx-events-teaser__badge { position: absolute; top: var(--space-5); left: var(--space-5); font-family: var(--font-mono); font-size: var(--text-caption); letter-spacing: 0.06em; text-transform: uppercase; color: var(--color-void); background: var(--color-gold-500); padding: var(--space-1) var(--space-3); border-radius: var(--radius-full); }
.nx-events-teaser__body { padding: var(--space-6); flex: 1; display: flex; flex-direction: column; }
.nx-events-teaser__date { font-family: var(--font-mono); font-size: var(--text-caption); color: var(--color-ion-500); text-transform: uppercase; letter-spacing: 0.04em; margin: 0 0 var(--space-2); }
.nx-events-teaser__card .nx-events-teaser__title { font-family: var(--font-heading); font-weight: 600; font-size: var(--text-h3); color: var(--color-text-primary); margin: 0 0 var(--space-2); }
.nx-events-teaser__card .nx-events-teaser__meta { font-size: var(--text-body-s); color: var(--color-text-muted); margin: 0 0 0 0; margin-top: auto; padding-top: var(--space-3); }

/* ============================================================
   EVENTS TABS — live Eventin data, filterable by room
   ============================================================ */
.nx-events-tabs { position: relative; z-index: 2; background: var(--color-surface-1); padding-block: var(--space-13); }
.nx-events-tabs__head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-end; gap: var(--space-5); margin-bottom: var(--space-9); }
.nx-events-tabs__head > div { position: relative; padding-left: var(--space-5); }
.nx-events-tabs__head .nx-live-strip__dot { position: absolute; left: 0; top: 6px; }
.nx-events-tabs__label { color: var(--color-ion-500); margin-bottom: var(--space-2); }
.nx-events-tabs__tabbar { margin-bottom: var(--space-9); }
.nx-events-tabs__empty { color: var(--color-text-muted); font-size: var(--text-body); padding: var(--space-9) 0; text-align: center; border: var(--stroke-hairline) dashed var(--color-border-subtle); border-radius: var(--radius-md); }

/* "Load More" tile — takes the place of the (limit+1)th event in the grid
   when a tab has more upcoming events than the home page teaser shows.
   Dashed border and transparent fill (vs. the solid surface-2 cards)
   deliberately read as "not an event" at a glance, and it goes to the full
   archive rather than expanding the grid in place — the home page teaser
   stays a fixed, predictable size no matter how many events are live. */
.nx-events-teaser__card--more {
	align-items: center;
	justify-content: center;
	background: transparent;
	border: var(--stroke-default) dashed var(--color-border-default);
	min-height: 220px;
}
.nx-events-teaser__card--more:hover {
	border-color: var(--color-gold-500);
	background: var(--color-surface-2);
	transform: translateY(-4px);
}
.nx-events-teaser__more-inner {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-3);
	padding: var(--space-8);
	text-align: center;
}
.nx-events-teaser__more-arrow {
	width: 40px;
	height: 40px;
	border-radius: 50%;
	border: var(--stroke-default) solid var(--color-border-default);
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--color-gold-300);
	transition: transform var(--duration-base) var(--ease-out-expo), border-color var(--duration-base) var(--ease-standard);
}
.nx-events-teaser__card--more:hover .nx-events-teaser__more-arrow {
	transform: translateX(3px);
	border-color: var(--color-gold-500);
}
.nx-events-teaser__more-label {
	font-family: var(--font-heading);
	font-weight: 600;
	font-size: var(--text-body);
	color: var(--color-text-primary);
}

/* ============================================================
   GALLERY — scattered tilted grid, agntix-inspired
   ============================================================ */
.nx-gallery { position: relative; z-index: 2; background: var(--color-bg); padding-block: var(--space-13); overflow: hidden; }
.nx-gallery__grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-7) var(--space-6); }
@media (min-width: 768px) { .nx-gallery__grid { grid-template-columns: repeat(4, 1fr); } }
.nx-gallery__cell { margin: 0; border-radius: var(--radius-md); overflow: hidden; box-shadow: var(--shadow-2); transform: rotate(var(--nx-tilt, 0deg)); transition: transform var(--duration-base) var(--ease-out-expo), box-shadow var(--duration-base); }
.nx-gallery__cell:nth-child(3n) { margin-top: var(--space-9); }
.nx-gallery__cell img { width: 100%; aspect-ratio: 4/5; object-fit: cover; display: block; }
.nx-gallery__cell figcaption { padding: var(--space-2) 0 0; font-size: var(--text-caption); color: var(--color-text-muted); }
.nx-gallery__cell:hover { transform: rotate(0deg) scale(1.03); box-shadow: var(--shadow-4); z-index: var(--z-raised); position: relative; }

/* ============================================================
   VERTICALS TABS — Chess / Art / Social Nexus
   ============================================================ */
.nx-verticals { position: relative; z-index: 2; background: var(--color-surface-1); padding-block: var(--space-13); }
/* Horizontal scroll on mobile — 4 large display-type tab labels wrapping to
   multiple cramped lines reads as broken, not responsive. A single scrollable
   row (the standard mobile tab pattern) keeps the tab bar's height constant
   and gives each label its full type scale regardless of viewport width. */
.nx-verticals__tabbar {
	display: flex;
	flex-wrap: nowrap;
	gap: var(--space-7);
	border-bottom: var(--stroke-hairline) solid var(--color-border-subtle);
	margin-bottom: var(--space-9);
	overflow-x: auto;
	overflow-y: hidden;
	scrollbar-width: none;
	-webkit-overflow-scrolling: touch;
	margin-inline: calc(var(--container-margin) * -1);
	padding-inline: var(--container-margin);
}
.nx-verticals__tabbar::-webkit-scrollbar { display: none; }
/* Scroll affordance: confirmed live at 375px that this bar's content
   (748px — 4 tabs on the shared "What's On" instance) silently overflows
   past the viewport with a hard cut at the edge and no fade, arrow, or
   next-label peek — nothing tells a visitor there's more to swipe to, so
   "The Art Nexus" / "The Social Nexus" go undiscovered. A static edge mask
   (not scroll-position-aware, but zero extra markup or JS) fades both ends
   of the bar's own box — independent of how far the inner content has
   scrolled — so it always reads as "this scrolls" rather than "this ends
   here." Only needed while this is a single scrolling row (< 768px); the
   md+ breakpoint below switches to a wrapped, non-scrolling layout where
   nothing needs fading. */
@media (max-width: 767px) {
	.nx-verticals__tabbar {
		-webkit-mask-image: linear-gradient(to right, transparent 0, black 20px, black calc(100% - 36px), transparent 100%);
		mask-image: linear-gradient(to right, transparent 0, black 20px, black calc(100% - 36px), transparent 100%);
	}
}
@media (min-width: 768px) {
	.nx-verticals__tabbar { flex-wrap: wrap; overflow-x: visible; margin-inline: 0; padding-inline: 0; }
}
.nx-verticals__tab {
	background: none; border: none; cursor: pointer;
	font-family: var(--font-display);
	text-transform: uppercase;
	font-size: clamp(1.125rem, 0.95rem + 1vw, 2rem);
	white-space: nowrap;
	flex: 0 0 auto;
	letter-spacing: -0.01em;
	color: var(--color-text-muted);
	padding-bottom: var(--space-5);
	position: relative;
	transition: color var(--duration-base) var(--ease-standard);
}
.nx-verticals__tab::after { content: ''; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; background: var(--color-gold-500); transform: scaleX(0); transform-origin: left; transition: transform var(--duration-base) var(--ease-out-expo); }
.nx-verticals__tab:hover { color: var(--color-text-secondary); }
.nx-verticals__tab.is-active { color: var(--color-text-primary); }
.nx-verticals__tab.is-active::after { transform: scaleX(1); }
/* Astra's theme-wide `button:focus, button:hover { background: var(--ast-global-color-1) }`
   (main inline theme CSS, loaded after this stylesheet) beats the plain
   `background: none` above on tap/focus — confirmed live as a solid Astra-blue
   box painting over these tabs on mobile tap. Same root cause as the
   Astra-button-focus issue fixed elsewhere on this site; !important is the
   only thing that reliably wins here since Astra's rule isn't scoped to a
   class we can out-specificity normally. */
.nx-verticals__tab:hover,
.nx-verticals__tab:focus,
.nx-verticals__tab:active {
	background: none !important;
}

.nx-verticals__panel[hidden] { display: none; }
.nx-verticals__panel { display: grid; grid-template-columns: 1fr; gap: var(--space-9); align-items: center; }
@media (min-width: 1024px) { .nx-verticals__panel { grid-template-columns: 1.1fr 1fr; } }

.nx-verticals__glimpses { position: relative; display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-4); }
.nx-verticals__glimpse { border-radius: var(--radius-md); overflow: hidden; box-shadow: var(--shadow-2); }
.nx-verticals__glimpse img { width: 100%; aspect-ratio: 3/4; object-fit: cover; display: block; }
.nx-verticals__glimpse--1 { transform: rotate(-3deg) translateY(10px); }
.nx-verticals__glimpse--2 { transform: rotate(2deg); z-index: 1; }
.nx-verticals__glimpse--3 { transform: rotate(-2deg) translateY(14px); }

.nx-verticals__desc { font-size: var(--text-body-l); color: var(--color-text-secondary); max-width: 42ch; margin: 0 0 var(--space-6); }
.nx-verticals__soon { font-family: var(--font-mono); font-size: var(--text-caption); color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.05em; }

/* ============================================================
   ORIGIN — Who We Are / Values / Vision (About + Communities)
   Three acts (01 Who We Are, 02 What We Stand For, 03 The Vision), each
   opened with a numbered eyebrow — the same "index" grammar as the
   homepage About section's room list, so the site's editorial voice reads
   as one system rather than three unrelated text treatments. Values moved
   from a plain feature-card grid to numbered rows (a grid of cards read as
   a generic SaaS feature list); the vision line keeps its own centered,
   quieter register as the section's one deliberate "close."
   ============================================================ */
.nx-origin { position: relative; z-index: 2; background: var(--color-surface-1); padding-block: var(--space-13); }

.nx-origin__act + .nx-origin__act { margin-top: var(--space-13); }

.nx-origin__eyebrow { display: flex; align-items: baseline; gap: var(--space-3); }
.nx-origin__eyebrow-index { font-family: var(--font-mono); color: var(--color-gold-500); font-variant-numeric: tabular-nums; }

/* -- 01 Who We Are: heading and copy as two asymmetric columns rather than
   one stacked block -- */
.nx-origin__intro { display: flex; flex-direction: column; gap: var(--space-7); margin-top: var(--space-6); }
.nx-origin__heading { max-width: 480px; margin: 0; }
.nx-origin__body { max-width: 560px; display: flex; flex-direction: column; gap: var(--space-5); }
/* flex-basis is a row-axis sizing hint for the desktop side-by-side
   layout — applying it unscoped also affects the mobile column axis,
   forcing each item to a minimum ~360px *height* and opening a large dead
   gap between heading and body. Scope the basis to the same breakpoint
   that switches the axis to row. */
@media (min-width: 900px) {
	.nx-origin__intro { flex-direction: row; gap: var(--space-13); align-items: flex-start; }
	.nx-origin__heading { flex: 1 1 360px; }
	.nx-origin__body { flex: 1 1 360px; }
}
.nx-origin__body p { font-size: var(--text-body-l); line-height: 1.65; color: var(--color-text-secondary); margin: 0; }

/* -- 02 What We Stand For: numbered index rows, not feature cards -- */
.nx-origin__values-list {
	list-style: none; margin: var(--space-6) 0 0; padding: 0;
	display: grid; grid-template-columns: 1fr; gap: 0;
	border-top: var(--stroke-hairline) solid var(--color-border-subtle);
}
@media (min-width: 768px) { .nx-origin__values-list { grid-template-columns: repeat(2, 1fr); } }
.nx-origin__value {
	display: flex; align-items: baseline; gap: var(--space-5);
	padding-block: var(--space-6);
	border-bottom: var(--stroke-hairline) solid var(--color-border-subtle);
}
@media (min-width: 768px) {
	.nx-origin__value { padding: var(--space-7) var(--space-8) var(--space-7) 0; }
	.nx-origin__value:nth-child(odd) { border-right: var(--stroke-hairline) solid var(--color-border-subtle); padding-right: var(--space-8); }
	.nx-origin__value:nth-child(even) { padding-left: var(--space-8); }
}
.nx-origin__value-num { flex: 0 0 auto; font-family: var(--font-mono); font-size: var(--text-h4); color: var(--color-gold-500); font-variant-numeric: tabular-nums; }
.nx-origin__value-body { display: flex; flex-direction: column; gap: var(--space-2); }
.nx-origin__value-title { font-family: var(--font-heading); font-weight: 600; font-size: var(--text-h4); color: var(--color-text-primary); margin: 0; }
.nx-origin__value-desc { font-size: var(--text-body-s); color: var(--color-text-secondary); margin: 0; max-width: 38ch; }

/* -- 03 The Vision: kept centered and quiet — the section's one deliberate
   close, distinct in rhythm from the two left-aligned acts before it -- */
.nx-origin__vision-wrap {
	max-width: 640px;
	margin-inline: auto;
	padding-top: var(--space-9);
	border-top: var(--stroke-hairline) solid var(--color-border-subtle);
	text-align: center;
}
.nx-origin__vision-eyebrow { justify-content: center; }
.nx-origin__vision {
	font-family: var(--font-serif); font-style: italic; font-weight: 400;
	font-size: var(--text-display-l); line-height: 1.3;
	max-width: 18ch; margin: var(--space-6) auto 0; text-align: center;
	color: var(--color-text-primary); text-wrap: balance;
}
.nx-origin__vision-mark {
	display: block;
	width: var(--stroke-bold);
	height: 28px;
	margin: var(--space-7) auto 0;
	background: var(--color-gold-500);
	border-radius: var(--radius-full);
}

/* ============================================================
   FOUNDERS
   ============================================================ */
.nx-founders { position: relative; z-index: 2; background: var(--color-bg); padding-block: var(--space-13); }
.nx-founders__grid { display: grid; grid-template-columns: 1fr; gap: var(--space-11); }
@media (min-width: 768px) { .nx-founders__grid { grid-template-columns: repeat(2, 1fr); gap: var(--space-9); } }
.nx-founders__card { display: flex; flex-direction: column; }
/* Portrait sources here are mixed — some flat studio shots on a plain
   background, some background-removed cutouts on transparent PNG — rather
   than one consistent photo shoot. A shared base fill + edge vignette
   brings both into the same dark, "lifted blacks" grading the rest of the
   site's photography uses (§7 photography direction), so a stark white
   studio backdrop or a transparent cutout's empty canvas both read as
   "the same brand" instead of visibly different sources. Swap for real
   consistently-shot portraits when available and this can simplify back
   down to a plain object-fit: cover. */
.nx-founders__photo, .nx-people__photo {
	position: relative;
	background: var(--color-surface-2);
}
.nx-founders__photo::after, .nx-people__photo::after {
	content: '';
	position: absolute;
	inset: 0;
	z-index: 0;
	background: radial-gradient(ellipse at 50% 42%, transparent 52%, var(--color-surface-1) 108%);
	pointer-events: none;
}
.nx-founders__photo { margin: 0 0 var(--space-6); border-radius: var(--radius-lg); overflow: hidden; aspect-ratio: 4/5; box-shadow: var(--shadow-2); }
/* Cap the photo size only once the grid goes 2-column (768px+, matching
   .nx-founders__grid's own breakpoint) — on the single-column mobile
   layout the photo should span the full card width like the text below
   it does, or it dangles with an unmatched right edge. */
@media (min-width: 768px) { .nx-founders__photo { max-width: 280px; } }
.nx-founders .nx-founders__photo img {
	width: 100%; height: 100%; object-fit: contain; object-position: center;
	filter: grayscale(1) saturate(0.92) contrast(1.04);
	transition: filter var(--duration-moderate) var(--ease-out-expo);
}
.nx-founders__photo:hover img,
.nx-founders__photo:focus-within img { filter: grayscale(0) saturate(0.92) contrast(1.04); }
.nx-founders__name { font-family: var(--font-heading); font-weight: 600; font-size: var(--text-h3); color: var(--color-text-primary); margin: 0 0 var(--space-2); }
.nx-founders__role { font-family: var(--font-heading); font-weight: 500; font-size: var(--text-body-s); color: var(--color-gold-500); text-transform: uppercase; letter-spacing: 0.04em; margin: 0 0 var(--space-5); }
.nx-founders__bio { font-size: var(--text-body); color: var(--color-text-secondary); line-height: 1.6; margin: 0; max-width: 48ch; }

/* WhatsApp / LinkedIn / Instagram surface over the portrait itself rather
   than as a text row under the bio — keeps the copy block clean and puts
   the contact action where the eye already is. Permanently visible (not
   gated behind :hover/:focus-within) so the icons read as part of the
   card, not a secret only a mouse can find; the photo's own ::after (base
   vignette, above) stays put, ::before layers a second, always-on scrim
   on top of it purely for icon contrast against whatever the photo looks
   like underneath. Only the photo's own grayscale-to-color filter
   (further below) is still hover-only. */
.nx-founders__photo::before {
	content: '';
	position: absolute;
	inset: 0;
	z-index: 1;
	background: linear-gradient(to top, rgba(0,0,0,0.82) 0%, rgba(0,0,0,0.4) 40%, transparent 65%);
	pointer-events: none;
}

.nx-founders__social {
	position: absolute;
	z-index: 2;
	inset: auto 0 0 0;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-3);
	padding: 0 var(--space-4) var(--space-6);
}
.nx-founders__social-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	flex: 0 0 auto;
	border-radius: var(--radius-full);
	background: var(--color-glass);
	border: var(--stroke-default) solid var(--color-border-default);
	backdrop-filter: blur(var(--blur-sm));
	-webkit-backdrop-filter: blur(var(--blur-sm));
	color: var(--color-text-primary);
	transition: background-color var(--duration-fast) var(--ease-standard),
		border-color var(--duration-fast) var(--ease-standard),
		color var(--duration-fast) var(--ease-standard),
		box-shadow var(--duration-fast) var(--ease-standard),
		transform var(--duration-fast) var(--ease-standard);
}
.nx-founders__social-btn svg { width: var(--icon-md); height: var(--icon-md); }

.nx-founders__social-btn:hover,
.nx-founders__social-btn:focus-visible {
	background: var(--color-gold-500);
	border-color: var(--color-gold-500);
	color: var(--color-bg);
	box-shadow: var(--glow-gold-sm);
	transform: translateY(0) scale(1.06);
}
.nx-founders__social-btn:focus-visible { outline: 2px solid var(--color-gold-300); outline-offset: 3px; }

/* Touch devices have no hover state to trigger the reveal — keep the
   icons permanently visible (at rest opacity) so the action stays
   reachable without relying on a gesture the device doesn't support.
   `pointer: coarse` is included alongside `hover: none` (matching
   .nx-hero__trail's own touch query above) to also catch hybrid
   touchscreen laptops that report a precision pointer is available but
   whose primary input is still a tap. */
@media (hover: none), (pointer: coarse) {
	.nx-founders__photo::before { opacity: 1; background: linear-gradient(to top, rgba(0,0,0,0.72) 0%, transparent 55%); }
	.nx-founders__social-btn { opacity: 1; transform: none; }
	.nx-founders .nx-founders__photo img { filter: grayscale(0) saturate(0.92) contrast(1.04); }
}

/* Narrowest phones (≤360px): the 44px icon row can crowd the photo's
   bottom padding — trim the button size and gap slightly rather than
   let them press against the card's rounded corners. */
@media (max-width: 360px) {
	.nx-founders__social { gap: var(--space-2); padding: 0 var(--space-3) var(--space-4); }
	.nx-founders__social-btn { width: 40px; height: 40px; }
	.nx-founders__social-btn svg { width: var(--icon-sm); height: var(--icon-sm); }
}

/* ============================================================
   PEOPLE — Community Leads by city
   ============================================================ */
.nx-people { position: relative; z-index: 2; background: var(--color-surface-1); padding-block: var(--space-13); }
.nx-people__intro { font-size: var(--text-body-l); color: var(--color-text-secondary); max-width: 60ch; margin: var(--space-5) 0 0; }
.nx-people__city { margin-top: var(--space-11); }
.nx-people__city-name {
	font-family: var(--font-heading); font-weight: 600; font-size: var(--text-h3); color: var(--color-text-primary);
	margin: 0 0 var(--space-7); padding-bottom: var(--space-4);
	border-bottom: var(--stroke-hairline) solid var(--color-border-subtle);
}
.nx-people__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--space-7); }
.nx-people__card { text-align: left; }
.nx-people__photo { margin: 0 0 var(--space-4); border-radius: var(--radius-md); overflow: hidden; aspect-ratio: 4/5; box-shadow: var(--shadow-1); }
.nx-people .nx-people__photo img { width: 100%; height: 100%; object-fit: cover; object-position: center; filter: saturate(0.92) contrast(1.04); }
/* "Photo coming soon" state — a handful of community leads don't have a
   portrait yet. Previously these fell back to an ambient bokeh texture
   image never meant to stand in for a face; at card size it just read as
   a broken/blank image next to a name. A quiet monogram in the brand's
   own numeral treatment reads as "intentionally awaiting a photo" instead. */
.nx-people__photo--pending {
	display: flex;
	align-items: center;
	justify-content: center;
	background: var(--color-surface-2);
}
.nx-people__photo--pending::after { background: none; }
.nx-people__monogram {
	position: relative;
	z-index: 1;
	font-family: var(--font-mono);
	font-size: var(--text-display-l);
	color: var(--color-text-muted);
}
.nx-people__name { font-family: var(--font-heading); font-weight: 600; font-size: var(--text-h4); color: var(--color-text-primary); margin: 0 0 var(--space-1); }
.nx-people__role { font-family: var(--font-heading); font-weight: 500; font-size: var(--text-caption); color: var(--color-gold-500); text-transform: uppercase; letter-spacing: 0.05em; margin: 0 0 var(--space-2); }
.nx-people__bio { font-size: var(--text-body-s); color: var(--color-text-muted); line-height: 1.5; margin: 0; }

/* ============================================================
   Custom cursor (desktop only, opt-in class on <html>)
   ============================================================ */
.nx-has-cursor { cursor: none; }
.nx-cursor { position: fixed; top: 0; left: 0; width: 10px; height: 10px; border-radius: 50%; background: var(--color-gold-500); pointer-events: none; z-index: var(--z-max); transform: translate(-50%, -50%); transition: width var(--duration-fast) var(--ease-standard), height var(--duration-fast) var(--ease-standard), background var(--duration-fast) var(--ease-standard), border var(--duration-fast) var(--ease-standard); }
.nx-cursor.is-active { width: 32px; height: 32px; background: transparent; border: 1.5px solid var(--color-gold-500); }
@media (max-width: 1023px), (prefers-reduced-motion: reduce), (hover: none) { .nx-has-cursor { cursor: auto; } .nx-cursor { display: none; } }

/* ============================================================
   Reveal-on-scroll base states (JS adds .is-visible)
   ============================================================ */
[data-nx-reveal] { opacity: 0; transform: translateY(24px); }
[data-nx-reveal].is-visible { opacity: 1; transform: translateY(0); transition: opacity var(--duration-slow) var(--ease-out-expo), transform var(--duration-slow) var(--ease-out-expo); }
[data-nx-reveal="cinematic"].is-visible { transition-duration: var(--duration-cinematic); }
[data-nx-stagger-item] { opacity: 0; transform: translateY(24px); }
[data-nx-stagger-item].is-visible { opacity: 1; transform: translateY(0); transition: opacity var(--duration-slow) var(--ease-out-expo), transform var(--duration-slow) var(--ease-out-expo); }
@media (prefers-reduced-motion: reduce) {
	[data-nx-reveal], [data-nx-stagger-item] { opacity: 1 !important; transform: none !important; }
}

.nx-split-line, .nx-split-word { overflow: hidden; display: block; }
.nx-split-line > div, .nx-split-word > div { will-change: transform; }

/* ============================================================
   COMMUNITY FEATURE — full-bleed alternating split section, one per
   community on the Communities page. Same grammar as .nx-verticals__panel
   (image/text split) and .nx-origin (eyebrow + cinematic heading), scaled
   up so each community reads as its own immersive world rather than a tab.
   ============================================================ */
.nx-community-feature { position: relative; z-index: 2; background: var(--color-bg); padding-block: var(--space-13); overflow: hidden; }
.nx-community-feature + .nx-community-feature { border-top: var(--stroke-hairline) solid var(--color-border-subtle); }
.nx-community-feature__grid { display: grid; grid-template-columns: 1fr; gap: var(--space-9); align-items: start; }
@media (min-width: 1024px) { .nx-community-feature__grid { grid-template-columns: 1fr 1fr; gap: var(--space-13); } }
.nx-community-feature__media { position: relative; margin: 0; border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-3); aspect-ratio: 4/5; }
.nx-community-feature__media img { width: 100%; height: 100% !important; object-fit: cover; display: block; }
/* Index badge — same "gold mono numeral" language as .nx-origin__eyebrow-index
   and .nx-about__index-num, just pinned to the photo instead of the text
   column so the number reads as a plate caption, not a duplicate of the
   inline eyebrow index below. */
.nx-community-feature__index {
	position: absolute; top: var(--space-5); left: var(--space-5); z-index: 2;
	display: flex; align-items: center; justify-content: center;
	width: 44px; height: 44px; border-radius: var(--radius-full);
	font-family: var(--font-mono); font-size: var(--text-body-s); color: var(--color-text-primary);
	font-variant-numeric: tabular-nums;
	background: rgba(10, 10, 10, 0.55);
	backdrop-filter: blur(6px);
	border: var(--stroke-hairline) solid var(--color-border-default);
}
@media (min-width: 1024px) {
	.nx-community-feature--reverse .nx-community-feature__media { order: 2; }
	.nx-community-feature--reverse .nx-community-feature__content { order: 1; }
}
.nx-community-feature__content { max-width: 560px; }
.nx-community-feature__logo { height: 40px; width: auto; margin: 0 0 var(--space-6); opacity: 0.92; }
.nx-community-feature__eyebrow-row { display: flex; align-items: baseline; gap: var(--space-3); margin: 0; }
.nx-community-feature__eyebrow-index { font-family: var(--font-mono); color: var(--color-gold-500); font-variant-numeric: tabular-nums; }
.nx-community-feature__heading {
	font-family: var(--font-heading);
	font-weight: 600;
	font-size: var(--text-h1);
	line-height: 1.08;
	letter-spacing: -0.01em;
	color: var(--color-text-primary);
	margin: var(--space-4) 0 var(--space-6);
	max-width: 16ch;
	text-wrap: balance;
}
.nx-community-feature__body { font-size: var(--text-body-l); line-height: 1.65; color: var(--color-text-secondary); margin: 0 0 var(--space-7); max-width: 52ch; }
/* Highlights render as a single quiet meta line (mono caps, gold dot
   separators) rather than a wall of pill buttons — so a community with
   nine tags and one with three both read as the same-weight component,
   instead of the tag count visibly changing how "big" the section feels. */
.nx-community-feature__meta {
	display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3);
	margin: 0 0 var(--space-8);
	font-family: var(--font-mono); font-size: var(--text-caption); letter-spacing: 0.03em; text-transform: uppercase;
	color: var(--color-text-muted);
}
.nx-community-feature__meta-dot { width: 3px; height: 3px; border-radius: 50%; background: var(--color-gold-500); flex-shrink: 0; }
.nx-community-feature__actions { display: flex; }

/* Text link with a sliding gold arrow — the "quiet CTA" used wherever a
   boxed button would out-weigh the content around it (currently Community
   Feature's explore link, generic on purpose). Mirrors the arrow-on-hover
   language of .nx-about__index-arrow for a consistent feel site-wide. */
.nx-link-arrow {
	display: inline-flex;
	align-items: center;
	gap: var(--space-3);
	font-family: var(--font-heading);
	font-weight: 600;
	font-size: var(--text-body);
	color: var(--color-text-primary);
	text-decoration: none;
	padding-bottom: var(--space-2);
	border-bottom: var(--stroke-hairline) solid var(--color-border-default);
	transition: color var(--duration-fast) var(--ease-standard), border-color var(--duration-fast) var(--ease-standard);
}
.nx-link-arrow svg { color: var(--color-gold-500); flex-shrink: 0; transition: transform var(--duration-fast) var(--ease-standard); }
.nx-link-arrow:hover { color: var(--color-gold-300); border-color: var(--color-gold-500); }
.nx-link-arrow:hover svg { transform: translateX(4px); }

/* ============================================================
   FEATURE CARDS — icon + title + description grid, reused twice per
   venture detail page ("What Makes It Different" / "What You'll
   Experience"). §04.3 Feature card spec: no image, idea over photo.
   ============================================================ */
.nx-feature-cards { position: relative; z-index: 2; background: var(--color-bg); padding-block: var(--space-13); }
.nx-feature-cards__intro { margin: var(--space-4) 0 0; font-size: var(--text-body-l); color: var(--color-text-secondary); max-width: var(--measure-reading); }
.nx-feature-cards__grid { display: grid; grid-template-columns: 1fr; gap: var(--space-6); }
@media (min-width: 640px) { .nx-feature-cards__grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .nx-feature-cards__grid { grid-template-columns: repeat(3, 1fr); gap: var(--space-7); } }
.nx-feature-cards__card {
	background: var(--color-surface-2);
	border: var(--stroke-hairline) solid var(--color-border-subtle);
	border-radius: var(--radius-md);
	padding: var(--space-6);
	box-shadow: var(--shadow-1);
	transition: transform var(--duration-base) var(--ease-out-expo), box-shadow var(--duration-base) var(--ease-out-expo), border-color var(--duration-base);
}
@media (min-width: 1024px) { .nx-feature-cards__card { padding: var(--space-7); } }
.nx-feature-cards__card:hover { transform: translateY(-4px); box-shadow: var(--shadow-2); border-color: var(--color-border-default); }
.nx-feature-cards__icon { display: inline-flex; color: var(--color-gold-500); margin-bottom: var(--space-5); }
.nx-feature-cards__icon svg { width: var(--icon-xl); height: var(--icon-xl); }
.nx-feature-cards__title { font-family: var(--font-heading); font-weight: 600; font-size: var(--text-h4); margin: 0 0 var(--space-2); color: var(--color-text-primary); }
.nx-feature-cards__desc { margin: 0; font-size: var(--text-body-s); line-height: 1.6; color: var(--color-text-secondary); }

/* ============================================================
   VENUE — single-venue deep dive: hero image, description, amenities,
   embedded map, photo strip.
   ============================================================ */
.nx-venue { position: relative; z-index: 2; background: var(--color-bg); padding-bottom: var(--space-13); overflow: hidden; }
.nx-venue__hero { margin: 0 0 var(--space-11); aspect-ratio: 21/9; min-height: 320px; }
.nx-venue__hero img { width: 100%; height: 100% !important; object-fit: cover; display: block; }
.nx-venue__body { margin: var(--space-4) 0 0; font-size: var(--text-body-l); line-height: 1.65; color: var(--color-text-secondary); max-width: var(--measure-reading); }
.nx-venue__grid { display: grid; grid-template-columns: 1fr; gap: var(--space-7); margin-top: var(--space-9); }
@media (min-width: 1024px) { .nx-venue__grid { grid-template-columns: 1fr 1.2fr; gap: var(--space-13); align-items: start; } }
.nx-venue__amenities { list-style: none; margin: 0 0 var(--space-7); padding: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.nx-venue__amenity { display: flex; align-items: center; gap: var(--space-3); font-size: var(--text-body); color: var(--color-text-secondary); }
.nx-venue__amenity-icon { display: inline-flex; color: var(--color-gold-500); flex-shrink: 0; }
.nx-venue__amenity-icon svg { width: var(--icon-md); height: var(--icon-md); }
.nx-venue__address { margin: 0; font-family: var(--font-mono); font-size: var(--text-body-s); color: var(--color-text-primary); line-height: 1.6; }
.nx-venue__landmark { margin: var(--space-2) 0 0; font-size: var(--text-body-s); color: var(--color-text-muted); }
.nx-venue__map { border-radius: var(--radius-md); overflow: hidden; border: var(--stroke-hairline) solid var(--color-border-subtle); box-shadow: var(--shadow-2); min-height: 320px; }
.nx-venue__map iframe {
	width: 100%; height: 100%; min-height: 320px; border: 0; display: block;
	/* Dark-mode treatment for the default light Google Maps embed, so it
	   doesn't read as a bright rectangle punched into a void-black page. */
	filter: invert(90%) hue-rotate(180deg) contrast(90%) brightness(95%);
}
.nx-venue__strip { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-4); margin-top: var(--space-9); }
@media (min-width: 768px) { .nx-venue__strip { grid-template-columns: repeat(4, 1fr); } }
.nx-venue__strip-cell { margin: 0; border-radius: var(--radius-sm); overflow: hidden; }
.nx-venue__strip-cell img { width: 100%; aspect-ratio: 1/1; object-fit: cover; display: block; }

/* ============================================================
   FAQ — <details>/<summary> accordion, motion layered on in JS
   (initFaqAccordion) via measured-height, native fallback without JS.
   ============================================================ */
.nx-faq { position: relative; z-index: 2; background: var(--color-bg); padding-block: var(--space-13); }
.nx-faq__container { max-width: 800px; }
.nx-faq__list { border-top: var(--stroke-hairline) solid var(--color-border-subtle); }
.nx-faq__item { border-bottom: var(--stroke-hairline) solid var(--color-border-subtle); }
.nx-faq__question {
	display: flex; align-items: center; justify-content: space-between; gap: var(--space-6);
	padding: var(--space-5) 0;
	font-family: var(--font-heading); font-weight: 500; font-size: var(--text-h5);
	color: var(--color-text-primary);
	cursor: pointer; list-style: none;
	transition: color var(--duration-fast) var(--ease-standard);
}
.nx-faq__question::-webkit-details-marker { display: none; }
.nx-faq__item:hover .nx-faq__question { color: var(--color-gold-300); }
.nx-faq__chevron { position: relative; flex-shrink: 0; width: 16px; height: 16px; transition: transform var(--duration-fast) var(--ease-standard); }
.nx-faq__chevron::before, .nx-faq__chevron::after {
	content: ""; position: absolute; top: 50%; width: 8px; height: var(--stroke-bold);
	background: currentColor; border-radius: var(--radius-full);
}
.nx-faq__chevron::before { left: 0; transform: rotate(45deg); }
.nx-faq__chevron::after { right: 0; transform: rotate(-45deg); }
.nx-faq__item[open] .nx-faq__chevron { transform: rotate(180deg); color: var(--color-gold-500); }
.nx-faq__answer { overflow: hidden; }
.nx-faq__answer p { margin: 0 0 var(--space-5); font-size: var(--text-body); line-height: 1.6; color: var(--color-text-secondary); max-width: var(--measure-narrow); }

/* ============================================================
   Third-party / theme overrides — site-wide, so a chrome element
   never reads as "not designed" against the void-black/gold palette.
   ============================================================ */
/* Astra's native "Scroll to Top" button ships with the pre-brand default
   blue (#046bd2) since the earlier global-color pass only covered
   Elementor's Kit, not Astra's own Customizer options. #ast-scroll-top is
   a single-class-selector target in Astra's CSS, so an ID selector here
   outranks it without needing !important. */
#ast-scroll-top.ast-scroll-top-icon {
	background-color: var(--color-surface-2);
	border: var(--stroke-hairline) solid var(--color-border-default);
	border-radius: var(--radius-full);
	box-shadow: var(--shadow-2);
	transition: background-color var(--duration-fast) var(--ease-standard), border-color var(--duration-fast) var(--ease-standard);
}
#ast-scroll-top.ast-scroll-top-icon:hover {
	background-color: var(--color-gold-500);
	border-color: var(--color-gold-500);
}
#ast-scroll-top .ast-arrow-svg path { fill: var(--color-text-primary); transition: fill var(--duration-fast) var(--ease-standard); }
#ast-scroll-top:hover .ast-arrow-svg path { fill: var(--color-void); }

/* WooCommerce's default My Account template (login form, dashboard, etc.)
   isn't an nx-page, so it never picked up the top clearance every nx-
   widget-built page adds for `.nx-header` — same fixed 112px header every
   other template already accounts for (see nexus-events.css). Without it,
   the page's own "Login"/"My account" heading rendered directly under the
   fixed header, overlapping the logo. 112px is hardcoded here rather than
   a --space-* token since those are a fluid spacing *scale* (they shrink
   on mobile), not a header-height value — the header itself is a fixed
   112px at every breakpoint. */
body.woocommerce-account .site-content { padding-top: 112px; }
