/**
 * BuddyNext — Hub Shell Stylesheet
 *
 * The shell renders between the host theme's get_header() / get_footer().
 * The active theme owns DOCTYPE / <html> / <head> / <body> AND the top
 * navigation (the v2 wireframes always intended this — see chrome.js in
 * docs/v2 Plans/v2/*.html, which maps to the host theme header in
 * production). BuddyNext only owns the .bn-app subtree.
 *
 * To stay edge-to-edge regardless of whatever container the theme wraps
 * content in (.site-main, .container, max-width: 1200px, etc.), .bn-app
 * bursts out to 100vw using the classic left/right: 50% + margin: -50vw
 * technique, then re-establishes a centred two- or three-column grid for
 * content.
 *
 * Layout:
 *   .bn-app                       — 100vw burst-out wrapper (escapes theme containers)
 *   .bn-app__shell                — two-column grid (rail / main)
 *   .bn-app__shell--with-sidebar  — three-column grid (rail / main / right)
 *   .bn-app__rail                 — left navigation column
 *   .bn-app__main                 — primary content column
 *   .bn-app__right                — optional right sidebar column
 *
 * Tokens consumed: --bn-canvas, --bn-surface, --bn-railw,
 *   --bn-content-wide, --bn-ink, --bn-ink-2, --bn-line, --bn-accent.
 *
 * @package BuddyNext
 */

/* ── Component tokens ──────────────────────────────────────────────────────
 * Shell-local geometry that has no global design-system token. These alias or
 * derive from the global scale where one exists, and define a clearly-named
 * component token only for genuinely off-grid shell geometry (icon glyph size,
 * count-badge pill size, the right-sidebar width, the notification dropdown
 * panel, the mobile bottom-bar clearance). No raw colour/typography lives here
 * — those always reference the global --bn-* tokens. */
:root {
	--bn-shell-sidebar-w:       320px;
	--bn-rail-icon-size:        18px;
	--bn-rail-badge-size:       18px;
	--bn-rail-badge-dot-size:   9px;
	--bn-notif-dropdown-w:      360px;
	--bn-notif-dropdown-maxh:   440px;
	--bn-notif-avatar-size:     36px;
	--bn-rail-logo-maxh:        32px;
	--bn-rail-logo-maxh-sm:     28px;
	--bn-mobile-nav-clearance:  88px;
}

/* ── Full-width burst-out — .bn-app escapes the theme container ────────────
 *
 * The theme's header + footer always render around BN hubs. Themes typically
 * wrap content in a centred container (max-width: 1200px is common); the
 * burst-out below pulls .bn-app out to the full viewport width without
 * needing to know what wrapper the theme uses. left/right: 50% +
 * margin-(left|right): -50vw is the well-known technique for this and
 * works under any host theme because it relies on viewport units, not on
 * the parent's computed width.
 *
 * box-sizing keeps the 100vw width inclusive of borders/padding so themes
 * with body { overflow: auto } never show a horizontal scrollbar from this
 * pattern. Geometry is the only thing we touch — no body-level resets, the
 * theme owns <html> + <body>.
 * ────────────────────────────────────────────────────────────────────── */

.bn-app {
	position: relative;
	left: 50%;
	right: 50%;
	margin-left: -50vw;
	margin-right: -50vw;
	width: 100vw;
	max-width: 100vw;
	display: flex;
	flex-direction: column;
	min-height: 100vh;
	min-height: 100dvh;
	background: var(--bn-canvas);
	color: var(--bn-ink, inherit);
	box-sizing: border-box;
}

.bn-app *,
.bn-app *::before,
.bn-app *::after {
	box-sizing: border-box;
}

/* Host-theme top-gap reset — the burst-out above only fixes HORIZONTAL
 * containment. Many themes also add top padding/margin on their content
 * wrapper (e.g. Reign's #content carries padding: 40px 0), which leaves a dead
 * band between the site header and the full-bleed shell on hub pages. .bn-app
 * owns its own top rhythm (.bn-app__main), so zero the host wrapper's top
 * spacing — scoped to body.bn-page so non-hub pages keep the theme's spacing.
 * The #content id selector matches Reign's id-specificity rule; the class
 * selectors cover other host themes. */
body.bn-page #content,
body.bn-page .site-content,
body.bn-page .content-area,
body.bn-page .site-main {
	padding-top: 0;
	margin-top: 0;
}

/* Honour the WP admin bar when present (logged-in user). */
body.admin-bar .bn-app {
	min-height: calc(100vh - 32px);
	min-height: calc(100dvh - 32px);
}
@media screen and (max-width: 782px) {
	body.admin-bar .bn-app {
		min-height: calc(100vh - 46px);
		min-height: calc(100dvh - 46px);
	}
}

/* Embedded shortcode context — a [buddynext_*] shortcode dropped onto an
 * arbitrary page (ShortcodeService::wrap_embedded). The `.bn-app` canvas above
 * bursts out to 100vw / 100vh for the routed hub; embedded, that would overflow
 * the host page and force a fragment to fill the viewport. Neutralize the
 * full-bleed geometry so the widget flows inside the host content column, while
 * keeping the token scope + `.bn-app *` reset intact. */
.bn-app.bn-app--embedded {
	left: auto;
	right: auto;
	margin-left: 0;
	margin-right: 0;
	width: auto;
	max-width: 100%;
	min-height: 0;
	background: transparent;
}
body.admin-bar .bn-app.bn-app--embedded {
	min-height: 0;
}
/* The host page already supplies the horizontal gutter; drop the column's own
 * inline padding so embedded content stays flush with surrounding page content. */
.bn-app--embedded .bn-app__main {
	padding-inline: 0;
}

/* Register the rail width as an animatable <length> so the grid track that
   consumes it can transition smoothly instead of snapping — plain CSS custom
   properties are not interpolable, but an @property-registered one is. */
@property --bn-railw {
	syntax: '<length>';
	inherits: true;
	initial-value: 260px;
}

/* ── Two/three-column shell — full-viewport, rail anchored to viewport edge ── */
.bn-app__shell {
	display: grid;
	grid-template-columns: var(--bn-railw) minmax(0, 1fr);
	gap: 0;
	width: 100%;
	max-width: none;
	margin: 0;
	padding: 0;
	flex: 1 1 auto;
	min-height: 0;
	/* Animate the rail track on collapse/expand: --bn-railw is @property-
	   registered above, so interpolating it re-runs grid-template-columns each
	   frame for a smooth slide instead of an instant snap. */
	transition: --bn-railw 0.2s ease;
}

@media (prefers-reduced-motion: reduce) {
	.bn-app__shell {
		transition: none;
	}
}

/* The client-nav router region (.bn-app__region) wraps main + the optional right
   sidebar. display:contents removes it from layout so main and the sidebar remain
   direct grid tracks of .bn-app__shell — the wrapper exists only so a client
   navigation swaps both together. */
.bn-app__region {
	display: contents;
}

/* Sidebar track is presence-driven via :has(.bn-app__right) rather than a
   --with-sidebar class: the sidebar lives inside the swapped region, so the grid
   must react to it appearing/disappearing on a client navigation (a class on
   .bn-app__shell would be outside the region and go stale). */
.bn-app__shell:has( .bn-app__right ) {
	grid-template-columns: var(--bn-railw) minmax(0, 1fr) var(--bn-shell-sidebar-w);
}

/* Community navigation disabled (buddynext_community_nav_enabled() === false):
   the rail markup is not rendered, so drop its grid track and let the content
   reflow to full width instead of reserving the empty --bn-railw column. */
.bn-app__shell--no-nav {
	grid-template-columns: minmax(0, 1fr);
}

.bn-app__shell--no-nav:has( .bn-app__right ) {
	grid-template-columns: minmax(0, 1fr) var(--bn-shell-sidebar-w);
}

.bn-app__main {
	min-width: 0;
	padding-block: var(--bn-s5);
	padding-inline: var(--bn-s6);
}

/* Main column flows at full available width. Hub templates own their
 * own internal layout (the feed template has its own feed+sidebar
 * 2-column grid, the profile template has its hero+tabs, etc.) — the
 * shell does not constrain them. */
.bn-app__main > * {
	width: 100%;
	max-width: none;
	margin-inline: 0;
}

.bn-app__right {
	padding: var(--bn-s5);
	border-inline-start: 1px solid var(--bn-line);
	background: var(--bn-canvas);
	display: flex;
	flex-direction: column;
	gap: var(--bn-s4);
}

/* ── Left rail ───────────────────────────────────────────────────────────── */
.bn-app__rail {
	border-right: 1px solid var(--bn-line);
	padding: var(--bn-s5) var(--bn-s2);
	position: sticky;
	top: 0;
	align-self: start;
	height: 100vh;
	height: 100dvh;
	overflow-y: auto;
	scrollbar-width: thin;
}

body.admin-bar .bn-app__rail {
	top: 32px;
	height: calc(100vh - 32px);
	height: calc(100dvh - 32px);
}
@media screen and (max-width: 782px) {
	body.admin-bar .bn-app__rail {
		top: 46px;
		height: calc(100vh - 46px);
		height: calc(100dvh - 46px);
	}
}

.bn-rail__group {
	display: flex;
	flex-direction: column;
	gap: calc(var(--bn-s1) / 2);
	margin-bottom: var(--bn-s4);
}

.bn-rail__heading {
	padding: var(--bn-s2) var(--bn-s3) var(--bn-s1);
	font-size: var(--bn-text-2xs);
	font-weight: var(--bn-fw-bold);
	letter-spacing: var(--bn-ls-wide);
	text-transform: uppercase;
	color: var(--bn-ink-3);
}

.bn-rail__item {
	display: flex;
	align-items: center;
	gap: var(--bn-s3);
	padding: var(--bn-s2) var(--bn-s3);
	min-height: var(--bn-s10);
	border-radius: var(--bn-r-sm);
	font-size: var(--bn-text-base);
	font-weight: var(--bn-fw-medium);
	color: var(--bn-ink-2);
	text-decoration: none;
	transition: background 0.12s, color 0.12s;
	position: relative;
}

.bn-rail__item:hover {
	background: var(--bn-canvas);
	color: var(--bn-ink);
}

.bn-rail__item:focus-visible {
	outline: 2px solid var(--bn-accent, var(--brand));
	outline-offset: -2px;
}

.bn-rail__item[aria-current="page"] {
	background: var(--bn-canvas);
	color: var(--bn-accent, var(--brand));
	font-weight: var(--bn-fw-semibold);
}

.bn-rail__icon {
	width: var(--bn-rail-icon-size);
	height: var(--bn-rail-icon-size);
	flex-shrink: 0;
	stroke: currentColor;
}

.bn-rail__label {
	flex: 1;
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.bn-rail__badge {
	background: var(--bn-danger);
	color: var(--bn-accent-fg);
	font-size: var(--bn-text-2xs);
	font-weight: var(--bn-fw-bold);
	min-width: var(--bn-rail-badge-size);
	height: var(--bn-rail-badge-size);
	padding: 0 var(--bn-s1);
	border-radius: var(--bn-r-full);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	line-height: 1;
}

/* ── Rail collapse toggle ────────────────────────────────────────────────── */
/* Rail header — logo (left) + compact collapse toggle (right) on one row. */
.bn-rail__head {
	display: flex;
	align-items: center;
	gap: var(--bn-s2);
	padding: var(--bn-s2) var(--bn-s3);
	margin-bottom: var(--bn-s2);
	min-height: var(--bn-s10);
}
/* Collapsed rail: stack logo over the toggle, both centred in the icon column. */
[data-bn-rail="collapsed"] .bn-rail__head {
	flex-direction: column;
	gap: var(--bn-s1);
	padding-inline: var(--bn-s1);
}

.bn-rail__logo {
	display: flex;
	align-items: center;
	min-width: 0;
}
.bn-rail__logo img {
	max-width: 100%;
	max-height: var(--bn-rail-logo-maxh);
	width: auto;
	height: auto;
	object-fit: contain;
}
/* Collapsed rail: keep the logo within the icon-only column. */
[data-bn-rail="collapsed"] .bn-rail__logo {
	justify-content: center;
}
[data-bn-rail="collapsed"] .bn-rail__logo img {
	max-height: var(--bn-rail-logo-maxh-sm);
}

/* Compact, square icon button — not a full-width bar (which read as an input). */
.bn-rail__toggle {
	flex: 0 0 auto;
	margin-inline-start: auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	padding: 0;
	background: transparent;
	border: 0;
	border-radius: var(--bn-r-sm);
	color: var(--bn-ink-3);
	cursor: pointer;
	transition: background 0.12s, color 0.12s;
}
.bn-rail__toggle:hover {
	background: var(--bn-canvas);
	color: var(--bn-ink);
}
.bn-rail__toggle:focus-visible {
	outline: 2px solid var(--bn-accent, var(--brand));
	outline-offset: -2px;
}
.bn-rail__toggle .bn-rail__icon {
	transition: transform 0.18s ease;
}

/* ── Collapsed → icon-only panel ─────────────────────────────────────────────
 * Stamped on <html data-bn-rail="collapsed"> (font-scale.js bootstrap). The
 * rail column shrinks, labels/headings hide, icons centre, and the count badge
 * becomes a corner dot. Item `title` attributes provide hover tooltips. */
/* Labels fade + collapse rather than display:none (which cannot animate), so
   they disappear in step with the rail slide. */
.bn-rail__label,
.bn-rail__heading,
.bn-rail__brand-name {
	transition: opacity 0.15s ease;
}
[data-bn-rail="collapsed"] {
	--bn-railw: 72px;
}
[data-bn-rail="collapsed"] .bn-rail__label,
[data-bn-rail="collapsed"] .bn-rail__heading,
[data-bn-rail="collapsed"] .bn-rail__brand-name {
	opacity: 0;
	width: 0;
	min-width: 0;
	flex: 0 0 0;
	margin: 0;
	overflow: hidden;
	pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
	.bn-rail__label,
	.bn-rail__heading,
	.bn-rail__brand-name {
		transition: none;
	}
}
[data-bn-rail="collapsed"] .bn-rail__item {
	justify-content: center;
	padding-inline: 0;
}
[data-bn-rail="collapsed"] .bn-rail__toggle {
	justify-content: center;
	margin-inline-start: 0;
}
[data-bn-rail="collapsed"] .bn-rail__toggle .bn-rail__icon {
	transform: rotate(180deg);
}
[data-bn-rail="collapsed"] .bn-rail__badge {
	position: absolute;
	top: var(--bn-s1);
	right: var(--bn-s4);
	min-width: var(--bn-rail-badge-dot-size);
	width: var(--bn-rail-badge-dot-size);
	height: var(--bn-rail-badge-dot-size);
	padding: 0;
	font-size: 0;
	line-height: 0;
	border-radius: var(--bn-r-full);
}

/* ── Responsive ──────────────────────────────────────────────────────────── */
@media (max-width: 1024px) {
	/* Right sidebar is hidden at this width; collapse its grid track. Uses :has()
	   at matching specificity so it overrides the presence-driven rule above (the
	   sidebar element still exists in the DOM, just display:none). */
	.bn-app__shell:has( .bn-app__right ) {
		grid-template-columns: var(--bn-railw) minmax(0, 1fr);
	}
	/* No rail + right sidebar hidden at this width → single content column. */
	.bn-app__shell--no-nav:has( .bn-app__right ) {
		grid-template-columns: minmax(0, 1fr);
	}
	.bn-app__right {
		display: none;
	}
}

/* Tablet range (between the mobile bottom-bar breakpoint and full desktop):
 * force the rail to its icon-only panel so it never crowds the content. The
 * manual toggle is hidden here since the width is driving the state. */
@media (min-width: 769px) and (max-width: 1024px) {
	.bn-app__shell {
		--bn-railw: 72px;
	}
	.bn-rail__label,
	.bn-rail__heading {
		display: none;
	}
	.bn-rail__item {
		justify-content: center;
		padding-inline: 0;
	}
	.bn-rail__toggle {
		display: none;
	}
	.bn-rail__badge {
		position: absolute;
		top: var(--bn-s1);
		right: var(--bn-s4);
		min-width: var(--bn-rail-badge-dot-size);
		width: var(--bn-rail-badge-dot-size);
		height: var(--bn-rail-badge-dot-size);
		padding: 0;
		font-size: 0;
		line-height: 0;
		border-radius: var(--bn-r-full);
	}
}

@media (max-width: 768px) {
	/* Single content column; include the :has() variants at matching specificity
	   so they override the presence-driven sidebar grid above. */
	.bn-app__shell,
	.bn-app__shell:has( .bn-app__right ),
	.bn-app__shell--no-nav:has( .bn-app__right ) {
		grid-template-columns: minmax(0, 1fr);
	}
	.bn-app__rail {
		display: none;
	}
	.bn-app__main {
		padding-bottom: var(--bn-mobile-nav-clearance); /* clear .bn-mobile-nav bottom bar */
	}
}

/* ── Notification dropdown (shell-extras) ────────────────────────────────── */
.bn-nav-notif-wrap { position: relative; }
.bn-notif-dropdown {
	position: absolute;
	top: calc(100% + var(--bn-s2));
	right: 0;
	width: var(--bn-notif-dropdown-w);
	max-height: var(--bn-notif-dropdown-maxh);
	background: var(--bn-surface);
	border: 1px solid var(--bn-line);
	border-radius: var(--bn-r-md);
	box-shadow: var(--bn-shadow-lg);
	z-index: 220;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	animation: bn-dropdown-in 0.15s ease;
}
@keyframes bn-dropdown-in {
	from { opacity: 0; transform: translateY(-4px); }
	to { opacity: 1; transform: translateY(0); }
}
.bn-notif-dropdown__header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: var(--bn-s3) var(--bn-s4);
	border-bottom: 1px solid var(--bn-line-faint);
}
.bn-notif-dropdown__title {
	font-weight: var(--bn-fw-bold);
	font-size: var(--bn-text-base);
	color: var(--bn-ink);
}
.bn-notif-dropdown__mark-read {
	background: none;
	border: none;
	color: var(--bn-accent, var(--brand));
	font-size: var(--bn-text-xs);
	font-weight: var(--bn-fw-semibold);
	cursor: pointer;
	font-family: inherit;
}
.bn-notif-dropdown__mark-read:hover { text-decoration: underline; }
.bn-notif-dropdown__list { flex: 1; overflow-y: auto; }
.bn-notif-dropdown__loading {
	padding: var(--bn-s6);
	text-align: center;
	color: var(--bn-ink-3);
	font-size: var(--bn-text-sm);
}
.bn-notif-dropdown__item {
	display: flex;
	gap: var(--bn-s2);
	padding: var(--bn-s2) var(--bn-s4);
	cursor: pointer;
	transition: background 0.1s;
}
.bn-notif-dropdown__item:hover { background: var(--bn-canvas); }
.bn-notif-dropdown__item--unread { background: var(--bn-accent-100); }
.bn-notif-dropdown__avatar {
	width: var(--bn-notif-avatar-size);
	height: var(--bn-notif-avatar-size);
	border-radius: var(--bn-r-full);
	flex-shrink: 0;
	background: var(--bn-accent-100);
	color: var(--bn-accent, var(--brand));
	font-size: var(--bn-text-sm);
	font-weight: var(--bn-fw-bold);
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
}
.bn-notif-dropdown__avatar img { width: 100%; height: 100%; object-fit: cover; }
.bn-notif-dropdown__body { flex: 1; min-width: 0; }
.bn-notif-dropdown__text {
	font-size: var(--bn-text-sm);
	color: var(--bn-ink);
	line-height: var(--bn-leading-snug);
}
.bn-notif-dropdown__text strong { font-weight: var(--bn-fw-semibold); }
.bn-notif-dropdown__time {
	font-size: var(--bn-text-2xs);
	color: var(--bn-ink-3);
	margin-top: calc(var(--bn-s1) / 2);
}
.bn-notif-dropdown__see-all {
	display: block;
	text-align: center;
	padding: var(--bn-s2);
	font-size: var(--bn-text-sm);
	font-weight: var(--bn-fw-semibold);
	color: var(--bn-accent, var(--brand));
	text-decoration: none;
	border-top: 1px solid var(--bn-line-faint);
}
.bn-notif-dropdown__see-all:hover { background: var(--bn-canvas); }
@media (max-width: 640px) {
	.bn-notif-dropdown { width: calc(100vw - var(--bn-s4)); right: -60px; }
}


/* ── Community Nav menu (Appearance → Menus → BuddyNext Community Nav) ──────
 * Rendered atop the hub main column by templates/shell/hub-shell.php when a
 * menu is assigned to the buddynext-community location. Horizontal, wraps on
 * small screens, tokens follow the host theme (light/dark). */
.bn-community-menu {
	margin-bottom: var(--bn-s4);
}
.bn-community-menu__list {
	display: flex;
	flex-wrap: wrap;
	gap: var(--bn-s2);
	align-items: center;
	margin: 0;
	padding: 0;
	list-style: none;
}
.bn-community-menu__list > li > a {
	display: inline-flex;
	align-items: center;
	padding: var(--bn-s1) var(--bn-s3);
	border-radius: var(--bn-r-sm);
	color: var(--bn-ink-2, inherit);
	text-decoration: none;
	font-weight: var(--bn-fw-medium, 500);
	transition: background 0.12s, color 0.12s;
}
.bn-community-menu__list > li > a:hover {
	background: var(--bn-canvas);
	color: var(--bn-ink);
}
.bn-community-menu__list > li.current-menu-item > a {
	background: var(--bn-canvas);
	color: var(--bn-accent, var(--brand));
}
