/* ════════════════════════════════════════════════════════════════
   <bruna-nav> — checker navigation component
   Single source of truth for the nav tile shared across pages.
   Pages declare <bruna-nav attrs></bruna-nav>; this file + bruna-nav.js
   render everything. Classes are scoped under the host element so no
   leakage into page-level styles.
   ══════════════════════════════════════════════════════════════════ */

/* TEMP — Euclid Circular B as the nav-tile typeface. CDN-hosted via
   onlinewebfonts.com (NOT licensed for production — replace with
   self-hosted files once the license is acquired). Declared here
   (not in tokens.css) because it's a nav-component-only font; the
   rest of the site runs on the system stack from tokens.css. Only
   the Regular weight is provided; the labels declare font-weight:600
   so the browser synthesizes the bolder weight (acceptable for
   testing, not ideal long-term).

   The earlier "editorial trio" Google Fonts import (Barlow Condensed
   + Libre Caslon Display) was removed once the site consolidated on
   the system stack — those families weren't actually applied via
   `font-family` anywhere in production, just imported. */
@font-face {
	font-family: 'Euclid Circular B';
	src: url('https://db.onlinewebfonts.com/t/f29cfc3fa5ade3421e1a2c66f9e01a34.eot');
	src: url('https://db.onlinewebfonts.com/t/f29cfc3fa5ade3421e1a2c66f9e01a34.eot?#iefix') format('embedded-opentype'),
	     url('https://db.onlinewebfonts.com/t/f29cfc3fa5ade3421e1a2c66f9e01a34.woff2') format('woff2'),
	     url('https://db.onlinewebfonts.com/t/f29cfc3fa5ade3421e1a2c66f9e01a34.woff') format('woff'),
	     url('https://db.onlinewebfonts.com/t/f29cfc3fa5ade3421e1a2c66f9e01a34.ttf') format('truetype'),
	     url('https://db.onlinewebfonts.com/t/f29cfc3fa5ade3421e1a2c66f9e01a34.svg#EuclidCircularB-Regular') format('svg');
	font-weight: normal;
	font-style: normal;
	font-display: swap;
}

/* ── Host ──────────────────────────────────────────────────────── */
/* Position is snapped to the 25px grid by JS (_snap) so tiles line up
   with the Shader Cascade on index.html and the footer's checker
   frame across all pages regardless of viewport. */
bruna-nav {
	position: fixed;
	top: 50px;
	left: 0;
	z-index: 100;
	display: block;
	width: 175px;
}
/* Hidden state — pages use GSAP to animate opacity smoothly; this is
   just the default at-rest value controlled by the data attribute. */
bruna-nav[data-hidden="true"] {
	opacity: 0;
	pointer-events: none;
}

/* ════════════════════════════════════════════════════════════════════
   HOME LINK — wordmark at top-left of every sub-page (NOT index.html).

   Injected as a body-level sibling of <bruna-nav> by the component's
   _injectHomeLink() method. Body placement matters: mix-blend-mode
   only blends against the element's stacking context, and bruna-nav
   creates an isolated context (z-index + fixed). Keeping the link
   outside the nav lets the blend compute against the actual page bg.

   Height 47px is tuned so the logo's circles don't visually exceed
   the nav grid height — the wordmark sits flush with the nav top
   without towering over it.

   Stroke uses `vector-effect: non-scaling-stroke` (in the inline SVG),
   so the value in CSS is the LITERAL px width on screen regardless
   of the SVG's viewBox scale. Base 2px → hover 2.6px makes the
   weight change visible.

   `mix-blend-mode: difference` + a white stroke keeps the logo
   legible against any backdrop: dark bg → white stroke; light bg →
   dark stroke. No per-page theming needed.

   Entrance: blur 14px + opacity 0 → blur 0 + opacity 1, same recipe
   as `.c-word-stack` items. Lives on the inner .bruna-home-svg so
   the link's mix-blend-mode isn't compromised by `filter:` creating
   an isolating stacking context on the link itself.
   ════════════════════════════════════════════════════════════════════ */
.bruna-home-link {
	position: fixed;
	top: 50px;
	left: 50px;
	height: 47px;
	display: inline-block;
	line-height: 0;
	mix-blend-mode: difference;
	z-index: 99;
	/* `overflow: visible` so the thicker hover stroke (2 → 2.6) and
	   the entrance blur halo don't get clipped at the wrapper edge. */
	overflow: visible;
	/* Pointer events follow visibility — disabled when collapsed so
	   the invisible logo isn't a hidden click target. */
	pointer-events: none;
}
body.bruna-nav-expanded .bruna-home-link {
	pointer-events: auto;
}

.bruna-home-svg {
	height: 100%;
	width: auto;
	display: block;
	overflow: visible;
	/* Default (nav collapsed) = invisible + blurred. Transition timing
	   here controls the OUTRO (expand → collapse): symmetric blur fade,
	   same 0.6s reveal/conceal curve as the intro for matching feel. */
	opacity: 0;
	filter: blur(14px);
	transition:
		opacity 0.6s var(--ease-in-out-cubic),
		filter  0.6s var(--ease-in-out-cubic),
		stroke-width 0.2s ease;
}
/* Expanded state — overrides transition timing for the INTRO (collapse
   → expand). Same duration + curve as the outro so both directions
   feel like the same animation in mirror. */
body.bruna-nav-expanded .bruna-home-svg {
	opacity: 1;
	filter: blur(0);
	transition:
		opacity 0.6s var(--ease-in-out-cubic),
		filter  0.6s var(--ease-in-out-cubic),
		stroke-width 0.2s ease;
}
.bruna-home-link:hover .bruna-home-svg {
	stroke-width: 2.6px;
}

/* Auto-hide on index.html — that page declares `.hero-main-logo`
   at bottom-left, so the top-left version would be redundant. The
   :has() selector is well-supported in modern browsers. */
body:has(.hero-main-logo) .bruna-home-link {
	display: none;
}

/* ── Grid structure ────────────────────────────────────────────── */
bruna-nav .nav-grid { width: 175px; }

bruna-nav .nav-row {
	position: relative;
	height: 25px;
	width: 175px;
}

bruna-nav .row-left {
	position: absolute;
	top: 0;
	right: calc(100% - 75px);
	display: flex;
	flex-direction: row-reverse;
	height: 25px;
}

bruna-nav .row-pivot {
	position: absolute;
	left: 75px;
	top: 0;
	width: 25px;
	height: 25px;
	z-index: 2;
}

bruna-nav .row-pivot.expandable {
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
	cursor: pointer;
	/* Asymmetric tile timing — bg flips fast, text trails. */
	transition: background-color 0.15s ease;
}
bruna-nav .row-pivot.expandable .pivot-link { transition: color 0.5s ease; }
bruna-nav .row-pivot.expandable:hover { background-color: #0a0a0a !important; }
bruna-nav .row-pivot.expandable:hover .pivot-link { color: #ffffff; }

bruna-nav .row-right {
	position: absolute;
	top: 0;
	left: 100px;
	display: flex;
	flex-direction: row;
	height: 25px;
}

bruna-nav .nav-item {
	height: 25px;
	width: 25px;
	min-width: 25px;
	display: flex;
	align-items: center;
	justify-content: center;
	position: relative;
	cursor: default;
	flex-shrink: 0;
	overflow: hidden;
}

/* ── Checker colors ────────────────────────────────────────────── */
bruna-nav .row-top .row-left .nav-item:nth-child(odd)  { background-color: #ffffff; }
bruna-nav .row-top .row-left .nav-item:nth-child(even) { background-color: #0a0a0a; }
bruna-nav .row-top .row-pivot { background-color: #0a0a0a; }
bruna-nav .row-top .row-right .nav-item:nth-child(odd)  { background-color: #ffffff; }
bruna-nav .row-top .row-right .nav-item:nth-child(even) { background-color: #0a0a0a; }

bruna-nav .row-btm .row-left .nav-item:nth-child(odd)  { background-color: #0a0a0a; }
bruna-nav .row-btm .row-left .nav-item:nth-child(even) { background-color: #ffffff; }
bruna-nav .row-btm .row-pivot { background-color: #ffffff; }
bruna-nav .row-btm .row-right .nav-item:nth-child(odd)  { background-color: #0a0a0a; }
bruna-nav .row-btm .row-right .nav-item:nth-child(even) { background-color: #ffffff; }

/* ── Interactive states ────────────────────────────────────────── */
bruna-nav .nav-item.has-link { cursor: pointer; }

/* Asymmetric tile timing — bg flips fast, text color trails so the
   label appears to "catch up" to the new tile color. Tuned snappy
   (~0.5s total) — felt without dragging. Same timing used on
   filter-tab, density-btn, res-cta and the rest of the tile-language
   hovers across the site. */
bruna-nav .nav-item.has-link { transition: background-color 0.15s ease; }
bruna-nav .nav-item.has-link .nav-link { transition: color 0.5s ease; }

/* Hover scoped to :not(.is-locked) so adding .is-locked class instantly
   kills hover styles without waiting for mousemove. */
bruna-nav:not(.is-locked) .nav-item.has-link:hover { background-color: #0a0a0a !important; }
bruna-nav:not(.is-locked) .nav-item.has-link:hover .nav-link { color: #ffffff; }

/* Locked = inert (no clicks, no hover). Page uses .lock()/.unlock(). */
bruna-nav.is-locked,
bruna-nav.is-locked * { pointer-events: none !important; }

/* ── Labels ────────────────────────────────────────────────────── */
bruna-nav .nav-link,
bruna-nav .pivot-link {
	position: absolute;
	top: 0; left: 0; right: 0; bottom: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	white-space: nowrap;
	font-family: 'Euclid Circular B', 'Inter', sans-serif;
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: #000000;
	opacity: 0;
	pointer-events: none;
}

/* ════════════════════════════════════════════════════════════════
   Ambient glow (opt-in via ambient-glow="on")
   A soft café radial wash that descends from the top when the nav
   is expanded. Part of the nav's emerging atmosphere — appears with
   expand, fades with collapse.
   ══════════════════════════════════════════════════════════════════ */
.bruna-nav-glow {
	position: fixed;
	top: 0;
	left: 50%;
	transform: translateX(-50%) translateY(-8%) scale(0.96);
	width: 140vw;
	height: 70vh;
	pointer-events: none;
	z-index: 30;
	opacity: 0;
	/* Tenue first-pass color — no forcing, just a faint warmth that
	   says "the space breathes" without announcing itself. */
	background: radial-gradient(
		ellipse 70% 100% at 50% 0%,
		rgba(168, 120, 78, 0.22) 0%,
		rgba(140, 95, 60, 0.12) 35%,
		rgba(90, 60, 40, 0.04) 65%,
		rgba(0, 0, 0, 0) 100%
	);
	/* Exit transition (when body.bruna-nav-expanded is REMOVED) — longer
	   and softer so the glow doesn't snap away. CSS reads the transition
	   from the state the element is leaving FROM, so this applies to the
	   collapse direction. */
	transition:
		opacity 0.95s ease-out,
		transform 1.05s ease-out;
}
body.bruna-nav-expanded .bruna-nav-glow {
	opacity: 1;
	transform: translateX(-50%) translateY(0) scale(1);
	/* Entry transition (when body.bruna-nav-expanded is ADDED) — short
	   and precise, synced with the nav's expand tween. */
	transition:
		opacity 0.5s cubic-bezier(0.45, 0, 0.25, 1),
		transform 0.6s cubic-bezier(0.45, 0, 0.25, 1);
}
