/**
 * Nahnu Link Bio — frontend stylesheet
 *
 * Architecture
 * ============
 * Every visual surface on the bio page is driven by a CSS custom property
 * declared in the :root block at the top of this file. The PHP `NLB_Theme`
 * class emits an inline <style id="nlb-theme-vars"> block that overrides
 * any subset of these variables on `body.nlb-page`, so themes can change
 * colors, radii, shadows, hover behavior, and even fonts without touching
 * a single component selector.
 *
 * If a theme leaves a variable unset, the :root default below applies. This
 * lets themes ship as small as a single property override, while keeping the
 * rendered page coherent.
 *
 * Variable groups
 * ---------------
 *   Page            --nlb-page-*
 *   Card            --nlb-card-*
 *   Avatar          --nlb-avatar-*
 *   Typography      --nlb-title-*  --nlb-subtitle-*  --nlb-bio-*  --nlb-font-*
 *   Social row      --nlb-social-*
 *   Link buttons    --nlb-link-*
 *   Photo cards     --nlb-card-link-*  (the photo-overlay link variant)
 *   Lang switcher   --nlb-lang-*
 *   Misc            --nlb-accent  --nlb-selection-*  --nlb-text  --nlb-text-muted
 *
 * Anti-theme defenses
 * -------------------
 * Sections at the bottom neutralise margins, classes, and CSS that an active
 * WordPress theme might inject into <body> when wp_head() / wp_footer() run.
 * The bio page is meant to fully replace the host theme's chrome.
 */

/* =========================================================================
   1. THEMEABLE TOKENS (defaults — themes override on body.nlb-page)
   ========================================================================= */
:root {

	/* --- Page (the area outside the card) --- */
	--nlb-page-bg:              #0a0a0f;

	/* --- Card (the contained content area) --- */
	--nlb-card-bg:              linear-gradient(180deg, #1a1a2e 0%, #0f0f1a 100%);
	--nlb-card-bg-fallback:     #14141f;
	--nlb-card-border-color:    rgba(255, 255, 255, 0.08);
	--nlb-card-border-width:    1px;
	--nlb-card-radius:          24px;
	--nlb-card-shadow:          0 24px 60px rgba(0, 0, 0, 0.40);
	--nlb-card-max:             580px;
	--nlb-card-padding-x:       32px;
	--nlb-card-padding-y:       48px;

	/* --- Avatar --- */
	--nlb-avatar-size:          96px;
	--nlb-avatar-ring-color:    rgba(255, 255, 255, 0.20);
	--nlb-avatar-ring-width:    2px;
	--nlb-avatar-shadow:        0 8px 24px rgba(0, 0, 0, 0.30);

	/* --- Typography --- */
	--nlb-font-family:          -apple-system, BlinkMacSystemFont, "Inter", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
	--nlb-heading-font-family:  var(--nlb-font-family);
	--nlb-text:                 #ffffff;
	--nlb-text-muted:           rgba(255, 255, 255, 0.65);

	--nlb-title-color:          var(--nlb-text);
	--nlb-title-weight:         700;
	--nlb-title-size:           22px;
	--nlb-title-spacing:        -0.01em;

	--nlb-subtitle-color:       rgba(255, 255, 255, 0.55);
	--nlb-subtitle-weight:      500;
	--nlb-subtitle-size:        14px;

	--nlb-bio-color:            var(--nlb-text-muted);
	--nlb-bio-size:             15px;

	/* --- Social icons row --- */
	--nlb-social-color:         rgba(255, 255, 255, 0.85);
	--nlb-social-color-hover:   #ffffff;
	--nlb-social-bg:            transparent;
	--nlb-social-bg-hover:      rgba(255, 255, 255, 0.10);
	--nlb-social-border-color:  transparent;
	--nlb-social-border-width:  0;
	--nlb-social-radius:        50%;
	--nlb-social-size:          40px;
	--nlb-social-icon-size:     22px;
	--nlb-social-transform-hover: translateY(-2px);

	/* --- Link buttons --- */
	--nlb-link-bg:              rgba(255, 255, 255, 0.06);
	--nlb-link-bg-hover:        rgba(255, 255, 255, 0.10);
	--nlb-link-text:            var(--nlb-text);
	--nlb-link-text-hover:      var(--nlb-text);
	--nlb-link-border-color:    rgba(255, 255, 255, 0.10);
	--nlb-link-border-color-hover: rgba(255, 255, 255, 0.20);
	--nlb-link-border-width:    1.5px;
	--nlb-link-border-style:    solid;
	--nlb-link-radius:          14px;
	--nlb-link-shadow:          none;
	--nlb-link-shadow-hover:    0 12px 32px rgba(0, 0, 0, 0.35);
	--nlb-link-transform-hover: translateY(-2px);
	--nlb-link-padding-y:       16px;
	--nlb-link-padding-x:       20px;
	--nlb-link-font-weight:     600;
	--nlb-link-font-size:       15px;
	--nlb-link-transition:      background 0.18s ease, color 0.18s ease, border-color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;

	/* --- Photo card link variant --- */
	--nlb-card-link-radius:     var(--nlb-link-radius);
	/* Photo-card overlay. The four-stop gradient with three stops at the
	   same 15% position creates a sharp transition: the bottom 15% of the
	   card is a solid dark band (1.0 → 0.8 alpha), then everything above
	   is fully transparent. This keeps the photo unobscured and lets the
	   title sit on a clean readable base — much more legible than a soft
	   bottom-fade on busy photos. */
	--nlb-card-link-overlay:    #000000;
	--nlb-card-link-title-color:#ffffff;
	--nlb-card-link-badge-bg:   rgba(255, 255, 255, 0.95);
	--nlb-card-link-badge-color:#111111;

	/* --- Language switcher --- */
	--nlb-lang-bg:              transparent;
	--nlb-lang-bg-active:       rgba(255, 255, 255, 0.10);
	--nlb-lang-text:            rgba(255, 255, 255, 0.55);
	--nlb-lang-text-active:     #ffffff;
	--nlb-lang-border:          rgba(255, 255, 255, 0.12);
	--nlb-lang-radius:          999px;

	/* --- Accent + selection --- */
	--nlb-accent:               #FF6A00;
	--nlb-selection-bg:         var(--nlb-accent);
	--nlb-selection-color:      #ffffff;

	/* --- Footer --- */
	--nlb-footer-color:         rgba(255, 255, 255, 0.40);
}

/* =========================================================================
   2. RESET — body-level + low-specificity element resets
   =========================================================================
   Element-level resets are wrapped in :where() so they have specificity 0,
   guaranteeing component classes (.nlb-card, .nlb-bio p, .nlb-link, etc.)
   always win the cascade. The previous approach used `body.nlb-page <tag>`
   which carried specificity (0,1,2) and silently overrode component CSS:

     body.nlb-page main { padding: 0 } (0,1,2) >  .nlb-card     { padding } (0,1,0)
     body.nlb-page p    { margin: 0  } (0,1,2) >  .nlb-bio p    { margin  } (0,1,1)

   Only resets that won't conflict with component layout live here. Heading
   and section margin/padding resets have been removed entirely — components
   set their own spacing explicitly, and host-theme CSS doesn't reach into
   `.nlb-card` because we dequeue theme stylesheets on the bio page.
   ========================================================================= */
html, body.nlb-page {
	margin: 0;
	padding: 0;
	min-height: 100%;
	min-height: 100dvh;
	width: 100%;
}

body.nlb-page #wpadminbar { display: none !important; }
html[lang] { margin-top: 0 !important; }
body.nlb-page { margin-top: 0 !important; }

body.nlb-page *,
body.nlb-page *::before,
body.nlb-page *::after {
	box-sizing: border-box;
}

/* Low-specificity (0,0,1) fallbacks for user-content elements. Component
   classes (.nlb-link, .nlb-social, .nlb-lang, .nlb-avatar img, etc.) all
   beat these because any class selector outranks (0,0,1). */
:where(body.nlb-page) a {
	color: inherit;
	text-decoration: none;
}

:where(body.nlb-page) img {
	display: block;
}

body.nlb-page ::selection {
	background: var(--nlb-selection-bg);
	color: var(--nlb-selection-color);
}

/* =========================================================================
   2.5. EXPLICIT OVERRIDES
   =========================================================================
   These intentionally use specificity (0,1,2) to win over component classes
   like `.nlb-card { padding: ... }`. Keep them grouped here so the override
   surface is obvious.
   ========================================================================= */
body.nlb-page nav,
body.nlb-page main,
body.nlb-page footer,
body.nlb-page section {
	margin: 0;
	padding: 15px;
}

p.nlb-subtitle {
	padding-bottom: 10px !important;
}

nav.nlb-socials {
	padding: 0 0 10px 0 !important;
}

.nlb-lang-switcher {
	padding-top: 15px;
}

/* =========================================================================
   3. PAGE LAYOUT
   ========================================================================= */
body.nlb-page {
	background: var(--nlb-page-bg);
	color: var(--nlb-text);
	font-family: var(--nlb-font-family);
	font-size: 16px;
	line-height: 1.5;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	display: flex;
	align-items: flex-start;
	justify-content: center;
	padding: 32px 16px;
	overflow-x: hidden;
}

/* Mobile: card takes full viewport, page chrome disappears. */
@media (max-width: 600px) {
	body.nlb-page {
		padding: 0;
	}
}

/* =========================================================================
   4. CARD
   ========================================================================= */
.nlb-card {
	width: 100%;
	max-width: var(--nlb-card-max);
	margin: 0 auto;
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	background: var(--nlb-card-bg-fallback);
	background: var(--nlb-card-bg);
	border: var(--nlb-card-border-width) solid var(--nlb-card-border-color);
	border-radius: var(--nlb-card-radius);
	padding: var(--nlb-card-padding-y) var(--nlb-card-padding-x);
	box-shadow: var(--nlb-card-shadow);
}

@media (max-width: 600px) {
	.nlb-card {
		max-width: 100%;
		min-height: 100vh;
		min-height: 100dvh;
		border-radius: 0;
		border-left: 0;
		border-right: 0;
		padding: 40px 20px 56px;
		box-shadow: none;
	}
}

/* =========================================================================
   5. AVATAR
   ========================================================================= */
.nlb-avatar {
	width: var(--nlb-avatar-size);
	height: var(--nlb-avatar-size);
	border-radius: 50%;
	overflow: hidden;
	margin: 0 0 20px;
	background: rgba(255, 255, 255, 0.05);
	border: var(--nlb-avatar-ring-width) solid var(--nlb-avatar-ring-color);
	box-shadow: var(--nlb-avatar-shadow);
	flex-shrink: 0;
}

.nlb-avatar img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

/* =========================================================================
   6. TYPOGRAPHY
   ========================================================================= */
.nlb-title {
	font-family: var(--nlb-heading-font-family);
	font-size: var(--nlb-title-size);
	font-weight: var(--nlb-title-weight);
	letter-spacing: var(--nlb-title-spacing);
	color: var(--nlb-title-color);
	margin: 0 0 4px;
	line-height: 1.25;
}

.nlb-subtitle {
	font-size: var(--nlb-subtitle-size);
	font-weight: var(--nlb-subtitle-weight);
	color: var(--nlb-subtitle-color);
	margin: 0 0 16px;
	line-height: 1.4;
}

.nlb-bio {
	font-size: var(--nlb-bio-size);
	color: var(--nlb-bio-color);
	margin: 0 0 24px;
	max-width: 420px;
	line-height: 1.5;
}

.nlb-bio p { margin: 0 0 8px; }
.nlb-bio p:last-child { margin-bottom: 0; }

/* =========================================================================
   7. SOCIAL ICONS ROW (between bio and links — Linktree placement)
   ========================================================================= */
.nlb-socials {
	margin: 0 0 24px;
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 8px;
	width: 100%;
	/* Force LTR icon order even on RTL pages — icon glyphs read better unmirrored. */
	direction: ltr;
}

.nlb-social {
	width: var(--nlb-social-size);
	height: var(--nlb-social-size);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	color: var(--nlb-social-color);
	background: var(--nlb-social-bg);
	border: var(--nlb-social-border-width) solid var(--nlb-social-border-color);
	border-radius: var(--nlb-social-radius);
	text-decoration: none;
	transition: var(--nlb-link-transition);
	-webkit-tap-highlight-color: transparent;
}

.nlb-social:hover,
.nlb-social:focus-visible {
	color: var(--nlb-social-color-hover);
	background: var(--nlb-social-bg-hover);
	transform: var(--nlb-social-transform-hover);
	outline: none;
}

.nlb-social .nlb-link__icon,
.nlb-social .nlb-link__icon-img,
.nlb-social > i {
	width: var(--nlb-social-icon-size);
	height: var(--nlb-social-icon-size);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
}

.nlb-social .nlb-link__icon svg {
	width: 100%;
	height: 100%;
	display: block;
}

.nlb-social > i {
	font-size: var(--nlb-social-icon-size);
	line-height: 1;
}

.nlb-social .nlb-link__icon-img {
	object-fit: contain;
	border-radius: 4px;
}

/* =========================================================================
   8. LINK BUTTONS (the main stack)
   ========================================================================= */
.nlb-links {
	width: 100%;
	display: flex;
	flex-direction: column;
	gap: 12px;
	margin: 0 0 28px;
}

.nlb-link {
	position: relative;
	display: flex;
	align-items: center;
	gap: 14px;
	width: 100%;
	padding: var(--nlb-link-padding-y) var(--nlb-link-padding-x);
	background: var(--nlb-link-bg);
	color: var(--nlb-link-text);
	border: var(--nlb-link-border-width) var(--nlb-link-border-style) var(--nlb-link-border-color);
	border-radius: var(--nlb-link-radius);
	text-decoration: none;
	font-size: var(--nlb-link-font-size);
	font-weight: var(--nlb-link-font-weight);
	box-shadow: var(--nlb-link-shadow);
	transition: var(--nlb-link-transition);
	-webkit-tap-highlight-color: transparent;
}

.nlb-link:hover,
.nlb-link:focus-visible {
	background: var(--nlb-link-bg-hover);
	color: var(--nlb-link-text-hover);
	border-color: var(--nlb-link-border-color-hover);
	box-shadow: var(--nlb-link-shadow-hover);
	transform: var(--nlb-link-transform-hover);
	outline: none;
}

.nlb-link:active {
	transform: scale(0.99);
}

.nlb-link[hidden] { display: none !important; }

.nlb-link__icon {
	width: 22px;
	height: 22px;
	flex-shrink: 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	color: currentColor;
}

.nlb-link__icon svg { width: 100%; height: 100%; display: block; }
.nlb-link__icon i   { font-size: 20px; line-height: 1; }

.nlb-link__icon-img {
	width: 32px;
	height: 32px;
	flex-shrink: 0;
	border-radius: 8px;
	object-fit: cover;
}

.nlb-link__text {
	flex: 1 1 auto;
	min-width: 0;
	text-align: center;
}

/* When a link has no leading icon, the text still centers in the button. */
.nlb-link:not(:has(.nlb-link__icon)):not(:has(.nlb-link__icon-img)) .nlb-link__text {
	text-align: center;
}

/* =========================================================================
   9. PHOTO CARD LINK VARIANT (16:9 hero image with title overlay)
   ========================================================================= */
.nlb-link--card {
	aspect-ratio: 16 / 9;
	position: relative;
	padding: 0;
	overflow: hidden;
	background: var(--nlb-link-bg);
	border-radius: var(--nlb-card-link-radius);
	display: block;
}

.nlb-link--card .nlb-link__image {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	transition: transform 0.4s ease;
}

.nlb-link--card:hover .nlb-link__image {
	transform: scale(1.04);
}

.nlb-link--card .nlb-link__text {
	position: absolute;
	bottom: 0;
	left: 0;
	right: 0;
	padding: clamp(10px, 2vw, 8px) clamp(12px, 2vw, 24px) clamp(12px, 1.5vw, 10px);
	background: var(--nlb-lang-text-active);
	color: var(--nlb-card-link-title-color);
	font-size: clamp(13px, 2.8vw, 18px);
	font-weight: 700;
	text-align: center;
	text-shadow: 0 1px 6px rgba(0, 0, 0, 0.55);
	z-index: 1;
}

.nlb-link--card .nlb-link__badge {
	position: absolute;
	top: 12px;
	right: 12px;
	width: 32px;
	height: 32px;
	background: var(--nlb-card-link-badge-bg);
	color: var(--nlb-card-link-badge-color);
	border-radius: 50%;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	z-index: 2;
}

.nlb-link--card .nlb-link__badge svg,
.nlb-link--card .nlb-link__badge i { width: 16px; height: 16px; font-size: 16px; }
.nlb-link--card .nlb-link__badge .nlb-link__icon { width: 16px; height: 16px; }

/* =========================================================================
   9.5. MEDIA STYLE — square thumbnail + title + provider subtitle
        Used for music/podcast embeds (Spotify, Apple Music, Bandcamp,
        SoundCloud, Apple Podcasts). Renders as a horizontal row matching
        the layout most music platforms use in their official widgets.
   ========================================================================= */
.nlb-link--media {
	display: grid;
	grid-template-columns: var(--nlb-media-thumb-size, 64px) 1fr auto;
	align-items: center;
	gap: 14px;
	padding: 10px 14px;
	min-height: calc(var(--nlb-media-thumb-size, 64px) + 20px);
	overflow: hidden;
	text-align: start;
	text-decoration: none;
}

.nlb-link--media .nlb-link__media-thumb {
	width: var(--nlb-media-thumb-size, 64px);
	height: var(--nlb-media-thumb-size, 64px);
	object-fit: cover;
	border-radius: 6px;
	display: block;
	flex-shrink: 0;
}

.nlb-link--media .nlb-link__media-body {
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: 2px;
	min-width: 0; /* allow text truncation inside the grid cell */
}

.nlb-link--media .nlb-link__media-title {
	font-weight: 600;
	font-size: 15px;
	line-height: 1.3;
	color: var(--nlb-link-text);
	overflow: hidden;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	line-clamp: 2;
	-webkit-box-orient: vertical;
}

.nlb-link--media .nlb-link__media-subtitle {
	font-size: 12px;
	font-weight: 400;
	color: var(--nlb-link-text);
	opacity: 0.65;
	line-height: 1.3;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.nlb-link--media .nlb-link__media-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 22px;
	height: 22px;
	color: var(--nlb-link-text);
	opacity: 0.5;
	flex-shrink: 0;
}

.nlb-link--media .nlb-link__media-icon svg,
.nlb-link--media .nlb-link__media-icon i { width: 18px; height: 18px; font-size: 18px; }

.nlb-link--media:hover .nlb-link__media-icon { opacity: 0.85; }

/* =========================================================================
   9.6. EMBED STYLE — playable iframe (YouTube, Spotify, Bunny Stream, etc.)
        The wrapper is a <div> instead of an <a> so iframe clicks reach the
        embed itself. Optional caption link below the iframe handles the
        case where the user wants a "Watch on platform" affordance.
   ========================================================================= */
.nlb-link--embed {
	display: block;
	overflow: hidden;
	padding: 0;
	background: var(--nlb-link-bg);
	border-radius: var(--nlb-link-radius);
	border: var(--nlb-link-border-width, 1px) solid var(--nlb-link-border-color, transparent);
	/* Override the generic .nlb-link box-shadow inherited from --nlb-link-shadow.
	   Embeds are visual surfaces of their own (video player chrome, audio
	   player UI, form fields) — a wrapper shadow competes with the iframe's
	   own visual treatment. Hover shadow on the wrapper is also disabled
	   below since iframes capture pointer events anyway. */
	box-shadow: none;
	/* Default video aspect-ratio. Gives the wrapper a defined size even
	   when the iframe inside has no inline dimensions (common with
	   pasted Bunny Stream / Wistia / Loom embeds, where wp_kses strips
	   the position/width/height styles those embeds rely on). Without
	   this, the wrapper collapses to 0px tall and the embed appears
	   not to render. Audio players, shortcodes, and form/calendar
	   providers override this to aspect-ratio:auto below. */
	aspect-ratio: 16 / 9;
	min-height: 220px;
}

/* Audio / music players have their own fixed heights baked into the
   iframe's inline style (Spotify 152/352px, Deezer 92/420px, etc.) —
   16:9 would leave empty space below the player. Match by class
   substring so this catches every provider variant (spotify_track,
   spotify_playlist, etc.) without enumerating each one. */
.nlb-link--embed[class*="--embed-spotify"],
.nlb-link--embed[class*="--embed-apple_music"],
.nlb-link--embed[class*="--embed-apple_podcasts"],
.nlb-link--embed[class*="--embed-soundcloud"],
.nlb-link--embed[class*="--embed-bandcamp"],
.nlb-link--embed[class*="--embed-mixcloud"],
.nlb-link--embed[class*="--embed-tidal"],
.nlb-link--embed[class*="--embed-deezer"],
.nlb-link--embed[class*="--embed-audiomack"],
.nlb-link--embed[class*="--embed-youtube_music"],
/* Forms, schedulers, ticketing — free-sizing so the embedded surface
   fills naturally based on its own content. */
.nlb-link--embed[class*="--embed-calendly"],
.nlb-link--embed[class*="--embed-cal_com"],
.nlb-link--embed[class*="--embed-typeform"],
.nlb-link--embed[class*="--embed-tally"],
.nlb-link--embed[class*="--embed-google_forms"],
.nlb-link--embed[class*="--embed-substack"],
.nlb-link--embed[class*="--embed-eventbrite"],
.nlb-link--embed[class*="--embed-luma"],
.nlb-link--embed[class*="--embed-patreon"],
.nlb-link--embed[class*="--embed-gumroad"] {
	aspect-ratio: auto;
	min-height: 0;
}

.nlb-link--embed iframe {
	display: block;
	width: 100%;
	max-width: 100%;
	/* Fill the wrapper. For 16:9 video wrappers this stretches the
	   iframe to fill its 16:9 container (overriding the browser's
	   default 300x150 when the iframe has no inline dimensions). For
	   audio/forms the wrapper is aspect-ratio:auto, so this computes
	   to auto and inline iframe heights take over (Spotify's 152px,
	   Deezer's 92px, etc.). */
	height: 100%;
	border: 0;
}

/* Caption link below the embed is now hidden by default. Embeds are
   self-contained interactive surfaces — the iframe IS the click target.
   A caption duplicates the destination unnecessarily and adds visual
   weight below the player. Users who want a "Watch on YouTube" style
   attribution can re-enable it via Custom CSS:
       body.nlb-page .nlb-link--embed .nlb-link__embed-caption {
           display: block;
       } */
.nlb-link--embed .nlb-link__embed-caption {
	display: none;
}

/* ----------------------------------------------------------------------
   Shortcode style
   ----------------------------------------------------------------------
   A first-class style separate from the embed (iframe) style. Used to
   render WordPress shortcodes — Contact Form 7, Gravity Forms, Fluent
   Forms, WPForms, Ninja Forms, custom plugins.

   The wrapper is intentionally chrome-free (transparent background,
   no border, no border-radius, no shadow, no hover effects). The
   embedded form/widget supplies its own visual treatment via the
   underlying plugin's styles, so we get out of the way and don't
   double-frame it.

   The link's `text` field becomes an optional heading rendered above
   the shortcode — letting users add context like "Join my newsletter"
   or "Get in touch" to introduce the form below. */
.nlb-link--shortcode {
	display: block;
	background: transparent;
	border: 0;
	border-radius: 0;
	box-shadow: none;
	padding: 0;
	color: var(--nlb-text);
}
/* Disable hover/focus visual changes — there's nothing clickable at the
   wrapper level (the form fields and submit button handle their own
   states), so a wrapper hover would be visual noise. */
.nlb-link--shortcode:hover,
.nlb-link--shortcode:focus,
.nlb-link--shortcode:focus-visible {
	background: transparent;
	border: 0;
	box-shadow: none;
	transform: none;
	outline: none;
}
.nlb-link--shortcode:active {
	transform: none;
}
.nlb-link__shortcode-heading {
	margin: 8px 0 12px;
	font-size: 17px;
	font-weight: 600;
	line-height: 1.35;
	color: var(--md-sys-color-on-surface, var(--nlb-text));
	text-align: center;
}
.nlb-link__shortcode-body :where(input, textarea, select, button) {
	max-width: 100%;
	box-sizing: border-box;
}
.nlb-link__shortcode-body :where(p, label, h1, h2, h3, h4, h5, h6) {
	color: var(--nlb-text);
}

/* =========================================================================
   9b. VIDSTACK PLAYER  (only used when a vidstack-style link is on the page)
   =========================================================================
   The bridge below maps our --nlb-player-* tokens onto Vidstack's --media-*
   variables. Vidstack reads these to color the play button, scrubber,
   buttons, time text, etc. Tokens are emitted by every preset and by the
   Custom theme builder; users who don't customize them get sensible
   auto-derived defaults (accent inherits the page accent, chrome is dark,
   icons are white).

   The wrapper itself gets minimal chrome — no background, no border, no
   shadow — because the player chrome is itself the visual treatment. The
   border-radius wraps the whole player so the rounded corners apply to
   the layout container and the video element clips correctly. */

.nlb-link--vidstack {
	background: transparent;
	border: 0;
	box-shadow: none;
	padding: 0;
	overflow: hidden;
	border-radius: var(--nlb-player-radius, var(--nlb-card-radius, 24px));
	width: 100%;
}
.nlb-link--vidstack:hover,
.nlb-link--vidstack:focus,
.nlb-link--vidstack:focus-visible {
	background: transparent;
	border: 0;
	box-shadow: none;
	transform: none;
}

/* Vidstack <media-player> custom element. Fill the wrapper width; let
   Vidstack handle the aspect ratio internally (16:9 for video; ~80px tall
   for audio). The crossorigin attribute on the element is what enables
   subtitle tracks for HLS streams. */
.nlb-link__vidstack {
	display: block;
	width: 100%;
	border-radius: inherit;
	overflow: hidden;
}

/* Aspect-ratio enforcement on the wrapper. Vidstack's own video.css sets
   aspect-ratio on <media-player>, but if Vidstack's JS hasn't yet upgraded
   the custom element (slow network, blocked CDN, etc.) the wrapper would
   collapse to its content height — and any poster image would render at
   its native dimensions, looking like a giant cropped fragment. Pinning
   16:9 on the video wrapper means the poster always fits cleanly even
   pre-hydration. Audio uses auto height (no poster, just controls). */
.nlb-link--vidstack-video {
	aspect-ratio: 16 / 9;
}
.nlb-link--vidstack-video .nlb-link__vidstack {
	height: 100%;
}
/* Force any direct poster <img> to fill the wrapper dimensions pre-hydration.
   Do NOT set object-fit here — Vidstack's own poster.css already sets
   object-fit:contain on .vds-poster :where(img). Overriding it with cover
   causes the zoom/crop problem on non-16:9 thumbnails. */
.nlb-link--vidstack-video img,
.nlb-link--vidstack-video media-poster img,
.nlb-link--vidstack-video [data-part="poster"] img {
	width: 100%;
	height: 100%;
}

/* The CSS-variable bridge from --nlb-player-* to Vidstack's --media-*
   variables is NOT in this file. It's emitted inline in templates/bio-page.php
   AFTER the Vidstack stylesheet <link> tags, because Vidstack's own theme.css
   declares the same --media-* variables on `media-player` with the same
   specificity (0,0,1) and source order would otherwise cause Vidstack's
   defaults to win over anything we put here. See NLB_Theme::vidstack_bridge_css(). */

/* Audio layout is short by default; give it a touch of breathing room
   so it visually sits between two button-style links cleanly. */
.nlb-link--vidstack-audio .nlb-link__vidstack {
	min-height: 80px;
}

/* =========================================================================
   10. LANGUAGE SWITCHER
   ========================================================================= */
.nlb-lang-switcher {
	display: flex;
	gap: 6px;
	margin-top: 8px;
	flex-wrap: wrap;
	justify-content: center;
}

.nlb-lang {
	padding: 6px 14px;
	background: var(--nlb-lang-bg);
	color: var(--nlb-lang-text);
	border: 1px solid var(--nlb-lang-border);
	border-radius: var(--nlb-lang-radius);
	text-decoration: none;
	font-size: 13px;
	font-weight: 500;
	transition: var(--nlb-link-transition);
}

.nlb-lang:hover,
.nlb-lang:focus-visible {
	color: var(--nlb-lang-text-active);
	outline: none;
}

.nlb-lang.is-current {
	background: var(--nlb-lang-bg-active);
	color: var(--nlb-lang-text-active);
}

/* =========================================================================
   11. RESPONSIVE TUNING
   ========================================================================= */
@media (max-width: 480px) {
	:root {
		--nlb-title-size:    20px;
		--nlb-link-font-size: 14px;
		--nlb-card-padding-x: 20px;
	}
}

/* =========================================================================
   12. PRINT
   ========================================================================= */
@media print {
	body.nlb-page {
		background: #fff;
		color: #000;
	}
	.nlb-card {
		box-shadow: none;
		border: 1px solid #ccc;
	}
	.nlb-link {
		page-break-inside: avoid;
		background: #fff;
		color: #000;
		border-color: #ccc;
		box-shadow: none;
	}
}

/* =========================================================================
   9.6. EMBED STYLE — actual playable iframe (YouTube, Vimeo, Spotify,
        Apple Music, Apple Podcasts, SoundCloud)
        Renders an iframe instead of a clickable link card. The optional
        caption below the iframe links out to the source page in case the
        visitor wants to open the original (e.g., to comment on YouTube).
   ========================================================================= */
.nlb-link--embed {
	display: block;
	width: 100%;
	margin: 0;
	padding: 0;
	overflow: hidden;
	border-radius: var(--nlb-link-radius, 12px);
	background: var(--nlb-card-bg-2, #1a1a2e);
	line-height: 0; /* eliminate iframe inline-block whitespace */
	box-shadow: var(--nlb-card-shadow, 0 1px 3px rgba(0, 0, 0, 0.06));
}

.nlb-link--embed iframe {
	display: block;
	width: 100%;
	border: 0;
	min-height: 0;
}

.nlb-link__embed-caption {
	display: block;
	padding: 8px 14px;
	font-size: 12px;
	line-height: 1.4;
	color: var(--nlb-link-text);
	opacity: 0.7;
	text-decoration: none;
	background: var(--nlb-card-bg-fallback, transparent);
	border-top: 1px solid var(--nlb-card-border-color, rgba(255, 255, 255, 0.06));
	transition: opacity 0.15s ease;
}

.nlb-link__embed-caption:hover {
	opacity: 1;
}

.nlb-link__embed-caption::after {
	content: ' ↗';
	opacity: 0.5;
	font-size: 10px;
}

/* Music embeds (Spotify, Apple Music, Apple Podcasts, SoundCloud) have a
   pre-set pixel height baked into the iframe style attribute. Video embeds
   (YouTube, Vimeo) use aspect-ratio:16/9. Both work without extra CSS. */

/* ----------------------------------------------------------------------
   Featured link highlight (per-link "stand out" toggle)
   ---------------------------------------------------------------------- */

.nlb-link--featured {
	position: relative;
	overflow: hidden;
}

/* Subtle animated gradient sweep across the surface — draws the eye but
   doesn't shake or jolt (which can trigger motion sickness). */
.nlb-link--featured::before {
	content: '';
	position: absolute;
	top: 0;
	left: -75%;
	width: 50%;
	height: 100%;
	background: linear-gradient(
		110deg,
		transparent 0%,
		rgba(255, 255, 255, 0.18) 50%,
		transparent 100%
	);
	transform: skewX(-20deg);
	animation: nlb-featured-sweep 3.5s ease-in-out infinite;
	pointer-events: none;
}

@keyframes nlb-featured-sweep {
	0%   { left: -75%; }
	60%  { left: 125%; }
	100% { left: 125%; }
}

/* Card-style featured links also get a soft pulsing glow. */
.nlb-link--featured.nlb-link--card,
.nlb-link--featured.nlb-link--media {
	animation: nlb-featured-pulse 2.4s ease-in-out infinite;
}

@keyframes nlb-featured-pulse {
	0%, 100% { box-shadow: 0 0 0 0 rgba(255, 106, 0, 0.0); }
	50%      { box-shadow: 0 0 0 6px rgba(255, 106, 0, 0.25); }
}

/* Respect reduced-motion preference — disable both effects. The featured
   class still applies any other styling (a slightly bolder border) so
   highlighted links are visible without animation. */
@media (prefers-reduced-motion: reduce) {
	.nlb-link--featured::before { animation: none; left: -75%; }
	.nlb-link--featured.nlb-link--card,
	.nlb-link--featured.nlb-link--media { animation: none; }
	.nlb-link--featured {
		outline: 2px solid var(--nlb-accent, #FF6A00);
		outline-offset: 2px;
	}
}

/* ----------------------------------------------------------------------
   Showcase rail (horizontal-scroll product/content cards)
   ---------------------------------------------------------------------- */

.nlb-showcase {
	margin: 16px 0;
	width: 100%;
}
.nlb-showcase__heading {
	font-size: 14px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--nlb-text-muted, #6b7280);
	margin: 0 0 10px;
	padding-inline: 4px;
}

.nlb-showcase__viewport {
	position: relative;
}

.nlb-showcase__track {
	display: flex;
	gap: 12px;
	overflow-x: auto;
	overflow-y: hidden;
	scroll-snap-type: x mandatory;
	-webkit-overflow-scrolling: touch;
	scroll-padding-inline: 4px;
	/* Hide scrollbars but keep scrolling — users swipe on mobile, click
	   the arrow buttons on desktop. */
	scrollbar-width: none;
	padding: 4px 4px 12px;
	margin: 0 -4px;
}
.nlb-showcase__track::-webkit-scrollbar { display: none; }

.nlb-showcase__card {
	flex: 0 0 200px;
	min-width: 200px;
	max-width: 200px;
	scroll-snap-align: start;
	display: flex;
	flex-direction: column;
	background: var(--nlb-link-bg, rgba(255,255,255,0.05));
	border: var(--nlb-link-border-width, 1px) solid var(--nlb-link-border-color, rgba(255,255,255,0.12));
	border-radius: var(--nlb-link-radius, 14px);
	overflow: hidden;
	text-decoration: none;
	color: inherit;
	transition: var(--nlb-link-transition, transform 0.2s ease, box-shadow 0.2s ease, background 0.2s ease);
}
/* M3-style hover: subtle 1px lift + level-1 elevation shadow + a faint
   state-layer tint via the link-bg-hover token. No big drop shadow,
   no dramatic translate — Material Design 3 prefers calm motion. */
.nlb-showcase__card:hover,
.nlb-showcase__card:focus-visible {
	transform: translateY(-1px);
	box-shadow: var(--md-sys-elevation-1, 0 1px 2px rgba(0,0,0,0.30), 0 1px 3px 1px rgba(0,0,0,0.15));
	background: var(--nlb-link-bg-hover, rgba(255,255,255,0.10));
	border-color: var(--nlb-link-border-color-hover, var(--nlb-accent, #FF6A00));
	outline: none;
}

.nlb-showcase__image {
	width: 100%;
	aspect-ratio: 1 / 1;
	background: var(--nlb-card-bg-2, rgba(0,0,0,0.1));
	overflow: hidden;
}
.nlb-showcase__image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
.nlb-showcase__image--placeholder {
	background: linear-gradient(135deg,
		var(--nlb-card-bg-2, rgba(255,255,255,0.04)),
		var(--nlb-card-bg, rgba(255,255,255,0.08))
	);
}

.nlb-showcase__body {
	padding: 12px 14px 14px;
	display: flex;
	flex-direction: column;
	gap: 4px;
	flex: 1;
}
.nlb-showcase__title {
	font-size: 14px;
	font-weight: 600;
	line-height: 1.35;
	color: var(--nlb-link-text, var(--nlb-text, #fff));
	display: -webkit-box;
	-webkit-line-clamp: 2;
	line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
.nlb-showcase__price {
	font-size: 13px;
	font-weight: 700;
	color: var(--nlb-accent, #FF6A00);
	margin-top: 2px;
}
.nlb-showcase__cta {
	margin-top: auto;
	padding-top: 8px;
	display: block;
	font-size: 12px;
	font-weight: 600;
	color: var(--nlb-accent, #FF6A00);
	text-transform: uppercase;
	letter-spacing: 0.04em;
}

/* Scroll-arrow buttons (desktop). Hidden by default; frontend.js shows
   them on devices with hover capability AND when there's overflow. */
.nlb-showcase__nav {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	width: 36px;
	height: 36px;
	border-radius: 50%;
	border: 1px solid var(--nlb-link-border-color, rgba(0,0,0,0.1));
	background: var(--nlb-card-bg, #fff);
	color: var(--nlb-text, #111);
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
	box-shadow: 0 4px 12px rgba(0,0,0,0.1);
	z-index: 2;
	transition: opacity 0.2s ease, transform 0.2s ease;
}
.nlb-showcase__nav:hover {
	transform: translateY(-50%) scale(1.05);
}
.nlb-showcase__nav--prev { left: -8px; }
.nlb-showcase__nav--next { right: -8px; }
.nlb-showcase__nav[disabled] {
	opacity: 0.3;
	cursor: not-allowed;
}

@media (hover: none) {
	/* Touch-only devices: swipe is the interaction model, hide arrows. */
	.nlb-showcase__nav { display: none !important; }
}

/* ----------------------------------------------------------------------
   Sensitive content gate (modal overlay)
   ---------------------------------------------------------------------- */

.nlb-gate {
	position: fixed;
	inset: 0;
	background: rgba(0, 0, 0, 0.92);
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 24px;
	z-index: 9999;
	backdrop-filter: blur(8px);
}
.nlb-gate__panel {
	max-width: 420px;
	background: var(--nlb-card-bg, #1a1a1f);
	color: var(--nlb-text, #fff);
	border-radius: 16px;
	padding: 32px 28px;
	border: 1px solid var(--nlb-card-border-color, rgba(255,255,255,0.1));
	box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
}
.nlb-gate__title {
	font-size: 22px;
	font-weight: 700;
	margin: 0 0 12px;
	color: var(--nlb-title-color, var(--nlb-text, #fff));
}
.nlb-gate__message {
	font-size: 15px;
	line-height: 1.6;
	margin: 0 0 24px;
	color: var(--nlb-text, #fff);
	opacity: 0.85;
}
.nlb-gate__actions {
	display: flex;
	flex-direction: column;
	gap: 8px;
}
.nlb-gate__btn {
	display: block;
	padding: 14px 20px;
	border-radius: var(--nlb-link-radius, 12px);
	border: 0;
	font-size: 15px;
	font-weight: 600;
	cursor: pointer;
	text-align: center;
	text-decoration: none;
	transition: filter 0.15s ease, transform 0.15s ease;
}
.nlb-gate__btn--primary {
	background: var(--nlb-accent, #FF6A00);
	color: #fff;
}
.nlb-gate__btn--primary:hover {
	filter: brightness(1.1);
	transform: translateY(-1px);
}
.nlb-gate__btn--secondary {
	background: transparent;
	color: var(--nlb-text-muted, #9ca3af);
	border: 1px solid var(--nlb-card-border-color, rgba(255,255,255,0.15));
}

/* When the gate is active, hide the bio content underneath so it doesn't
   render before consent. JS removes the data attribute on accept. */
body.nlb-page[data-nlb-gated="1"] .nlb-card {
	visibility: hidden;
}

/* ----------------------------------------------------------------------
   Per-link sensitive content indicator
   ---------------------------------------------------------------------- */

/* Small lock badge appears on links flagged sensitive. Doesn't change
   the link's clickability — JS intercepts the click and shows the
   confirmation modal. The badge is just a hint to the visitor. */
.nlb-link[data-nlb-sensitive="1"]::after {
	content: '';
	position: absolute;
	top: 8px;
	right: 8px;
	width: 18px;
	height: 18px;
	background: rgba(0, 0, 0, 0.5);
	border-radius: 50%;
	background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='11' width='18' height='11' rx='2'/><path d='M7 11V7a5 5 0 0 1 10 0v4'/></svg>");
	background-size: 11px;
	background-repeat: no-repeat;
	background-position: center;
	pointer-events: none;
}
.nlb-link[data-nlb-sensitive="1"] {
	position: relative;
}
/* Once the user has accepted (cleared the gate for this slot in this
   browser), JS adds .is-revealed and we hide the lock badge. */
.nlb-link[data-nlb-sensitive="1"].is-revealed::after {
	display: none;
}

/* Per-link confirmation modal — separate from the page-level gate so
   the page stays interactive and only the targeted link is gated. */
.nlb-link-gate {
	position: fixed;
	inset: 0;
	background: rgba(0, 0, 0, 0.85);
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 24px;
	z-index: 9998;
	backdrop-filter: blur(6px);
	animation: nlb-link-gate-in 0.18s ease-out;
}
.nlb-link-gate[hidden] {
	display: none;
}
@keyframes nlb-link-gate-in {
	from { opacity: 0; }
	to   { opacity: 1; }
}
.nlb-link-gate__panel {
	max-width: 380px;
	background: var(--nlb-card-bg, #1a1a1f);
	color: var(--nlb-text, #fff);
	border-radius: 14px;
	padding: 28px 24px;
	border: 1px solid var(--nlb-card-border-color, rgba(255,255,255,0.1));
	box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5);
}
.nlb-link-gate__title {
	font-size: 18px;
	font-weight: 700;
	margin: 0 0 10px;
	color: var(--nlb-title-color, var(--nlb-text, #fff));
}
.nlb-link-gate__message {
	font-size: 14px;
	line-height: 1.55;
	margin: 0 0 12px;
	color: var(--nlb-text, #fff);
	opacity: 0.85;
}
.nlb-link-gate__target {
	font-size: 12px;
	color: var(--nlb-text-muted, #9ca3af);
	margin: 0 0 18px;
	padding: 8px 10px;
	background: rgba(0, 0, 0, 0.25);
	border-radius: 6px;
	word-break: break-all;
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.nlb-link-gate__target:empty {
	display: none;
}
.nlb-link-gate__actions {
	display: flex;
	flex-direction: column;
	gap: 8px;
}
.nlb-link-gate__btn {
	display: block;
	padding: 12px 18px;
	border-radius: var(--nlb-link-radius, 10px);
	border: 0;
	font-size: 14px;
	font-weight: 600;
	cursor: pointer;
	text-align: center;
	transition: filter 0.15s ease;
}
.nlb-link-gate__btn--primary {
	background: var(--nlb-accent, #FF6A00);
	color: #fff;
}
.nlb-link-gate__btn--primary:hover {
	filter: brightness(1.1);
}
.nlb-link-gate__btn--secondary {
	background: transparent;
	color: var(--nlb-text-muted, #9ca3af);
	border: 1px solid var(--nlb-card-border-color, rgba(255,255,255,0.15));
}
