/*
Theme Name: Ethereal Bones
Theme URI: https://example.com/ethereal-bones
Author: JF & Claude
Author URI:
Description: A flexible, fully responsive theme for landing pages and full sites alike. Use a page bare for a distraction-free landing page, or opt into a "Regular Page" template with header/footer chrome, primary and corner menus, and footer widgets. Deep Customizer control over typography, colors, and spacing; an animated logo, image slider, and text-animation shortcodes; a native Tabs block; a top announcement bar; per-page SEO fields; and a maintenance mode with background/overlay options and an admin-bar on/off toggle.
Version: 1.116.0
Requires at least: 6.0
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: ethereal-bones
*/

/* -----------------------------------------------------------
   Reset / base
----------------------------------------------------------- */
*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	-webkit-text-size-adjust: 100%;
}

body {
	margin: 0;
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
	line-height: 1.6;
	color: #1a1a1a;
	background: #ffffff;
	/* Full-bleed (.alignfull) blocks use a 100vw trick below; this keeps
	   that from ever introducing a horizontal scrollbar. */
	overflow-x: hidden;
}

img {
	max-width: 100%;
	height: auto;
	display: block;
}

a {
	color: inherit;
}

/* -----------------------------------------------------------
   Layout: full-width background, constrained content width
   --ethereal-content-width is printed inline in wp_head from the
   theme options page (see inc/output.php)
----------------------------------------------------------- */
:root {
	--ethereal-content-width: 1140px;
	--ethereal-padding-top: 24px;
	--ethereal-padding-right: 20px;
	--ethereal-padding-bottom: 24px;
	--ethereal-padding-left: 20px;
}

.ethereal-site-background {
	width: 100%;
}

/* Maintenance Mode's stand-in page (body.ethereal-maintenance-page, added by
   ethereal_maintenance_body_class() in inc/output.php while that page is being
   viewed and Maintenance Mode is on -- see ethereal_is_maintenance_page() in
   inc/customizer.php). Its copyright line is suppressed
   (ethereal_output_footer_copyright()), so there's nothing else pinning content
   to the top of the page -- this centers it both ways instead, same
   min-height: 100vh + flex approach as any typical "coming soon" page.
   Assumes the page uses the default Landing page template (no header/
   footer chrome); picking the "Regular Page (Header & Footer)" template
   for it instead still centers the content area, just underneath that
   chrome rather than truly full-viewport. position: relative anchors the
   overlay pseudo-element below. */
.ethereal-maintenance-page .ethereal-site-background {
	min-height: 100vh;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	position: relative;
}

/* The optional overlay (Theme Options > Maintenance Mode > Overlay color/
   opacity) -- a flat color layered on top of this page's own background,
   mainly for keeping text readable over a busy background image.
   background-color and opacity are printed inline by
   ethereal_output_maintenance_bg_css() (inc/output.php) only once opacity is
   raised above 0; left unset here (no fallback), this pseudo-element stays
   fully transparent and invisible, same as if it didn't exist. Explicit
   z-index (rather than relying on default paint order) is what keeps it
   strictly behind .ethereal-content-wrap below regardless of source order,
   since position: absolute removes it from the normal in-flow painting
   order that would otherwise put it on top. */
.ethereal-maintenance-page .ethereal-site-background::before {
	content: "";
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	z-index: 0;
	pointer-events: none;
}

.ethereal-maintenance-page .ethereal-content-wrap {
	position: relative;
	z-index: 1;
}

/* Left/right content padding behaves like a MINIMUM edge margin, not a
   deduction from Content width: shrinking the box by the padding amount
   first, then capping it at Content width, means the max-width wins (the
   box is exactly Content width, full stop) whenever the viewport is wide
   enough for that -- the padding only actually shows up once the viewport
   gets narrower than Content width + the padding, at which point it keeps
   text off the screen edge exactly like the old padding-based version did.
   Top/bottom padding isn't affected by this (no equivalent "screen edge"
   concern vertically), so it stays as ordinary padding. */
.ethereal-content-wrap {
	width: calc(100% - (var(--ethereal-padding-left) + var(--ethereal-padding-right)));
	max-width: var(--ethereal-content-width);
	margin-left: auto;
	margin-right: auto;
	padding-top: var(--ethereal-padding-top);
	padding-bottom: var(--ethereal-padding-bottom);
}

.ethereal-entry-content {
	width: 100%;
}

.ethereal-entry-title {
	line-height: 1.25;
	/* font-size is set from Appearance > Customize > Typography (see
	   inc/output.php); this is just a sensible fallback if that hasn't
	   printed for some reason. Margin comes from the reset + margin-bottom
	   rules below (.ethereal-entry-title is itself an h1). */
	font-size: 2rem;
}

/* Default browser margin/padding removed from every typography element
   (headings, paragraphs, lists) — spacing is controlled entirely by the
   margin-bottom values in Appearance > Customize > Typography, printed
   inline in wp_head (see ethereal_output_typography_css() in inc/output.php,
   which targets these same elements at equal-or-higher specificity so it
   always wins the cascade). Covers page/post content, the footer widget
   area, and the footer copyright line. */
.ethereal-entry h1, .ethereal-entry h2, .ethereal-entry h3, .ethereal-entry h4, .ethereal-entry h5, .ethereal-entry h6,
.ethereal-entry p, .ethereal-entry ul, .ethereal-entry ol,
.ethereal-footer-widgets h1, .ethereal-footer-widgets h2, .ethereal-footer-widgets h3, .ethereal-footer-widgets h4, .ethereal-footer-widgets h5, .ethereal-footer-widgets h6,
.ethereal-footer-widgets p, .ethereal-footer-widgets ul, .ethereal-footer-widgets ol,
.ethereal-footer-copyright-inner,
.ethereal-footer-copyright-inner p {
	margin: 0;
	padding: 0;
}

/* The reset above zeroes ul/ol's padding-left along with everything else,
   but that padding is also what a browser uses to make room for the list
   marker itself (list-style-position: outside draws the bullet/number
   INSIDE that padding, to the left of the text) -- zeroing it left markers
   hanging off the list's left edge instead of sitting indented like normal
   list text, flush with or even left of the surrounding paragraphs. This
   restores just enough padding-left for a normal-looking indent without
   reintroducing the margin that the reset above was specifically removing
   (vertical spacing still comes entirely from the margin-bottom Typography
   setting). Same specificity and later in the cascade than the block above,
   so it wins for this one property without disturbing margin: 0. */
.ethereal-entry ul, .ethereal-entry ol,
.ethereal-footer-widgets ul, .ethereal-footer-widgets ol {
	padding-left: 1.2em;
}

/* -----------------------------------------------------------
   Wide / full-width block alignment (e.g. the Cover block).
   Requires add_theme_support('align-wide') in functions.php,
   which is what makes the "Wide width"/"Full width" buttons
   appear in the block toolbar in the first place.
----------------------------------------------------------- */
.ethereal-entry-content > .alignwide {
	--ethereal-wide-offset: 80px;
	width: calc(100% + (var(--ethereal-wide-offset) * 2));
	max-width: calc(var(--ethereal-content-width) + (var(--ethereal-wide-offset) * 2));
	margin-left: calc(var(--ethereal-wide-offset) * -1);
	margin-right: calc(var(--ethereal-wide-offset) * -1);
}

.ethereal-entry-content > .alignfull {
	/* --ethereal-vw is the real, scrollbar-excluded viewport width, set by a
	   tiny inline script in wp_head (see inc/output.php). Falls back to
	   100vw (which DOES include the scrollbar, causing a slight gap on
	   the side of the scrollbar) if JavaScript is disabled.

	   The margins are calculated from the known content-width and
	   padding values (not from "50% of this element's own container"),
	   because that container is .ethereal-entry-content — which is padded,
	   and padded asymmetrically whenever the left/right padding values
	   differ. Centering relative to an asymmetric box shifts the result
	   off the true page center by half the left/right difference. Using
	   the actual centered wrapper's geometry (.ethereal-content-wrap, via
	   --ethereal-content-width) instead sidesteps that entirely.

	   The needed negative margin is exactly how far .ethereal-content-wrap's
	   own edge sits from the true viewport edge -- which is the same
	   max(padding, (viewport - content-width) / 2) expression
	   .content-width uses below, just applied as a negative margin here
	   instead of as padding. It's the padding amount on a narrow screen
	   (where .ethereal-content-wrap has shrunk to less than content-width and
	   is inset only by that padding), or the true centering gutter on a
	   wide screen (where .ethereal-content-wrap sits at exactly content-width
	   and the gutter around it is bigger than the padding). max() picks
	   whichever of those two is actually the current gutter, so this
	   works at every window size without a fixed breakpoint. */
	width: var(--ethereal-vw, 100vw);
	max-width: var(--ethereal-vw, 100vw);
	margin-left: calc(-1 * max(var(--ethereal-padding-left), (var(--ethereal-vw, 100vw) - var(--ethereal-content-width)) / 2));
	margin-right: calc(-1 * max(var(--ethereal-padding-right), (var(--ethereal-vw, 100vw) - var(--ethereal-content-width)) / 2));
}

/* The background/media of a full-width block spans edge to edge (above),
   but its inner CONTENT is still inset by the site's left/right content
   padding, so text doesn't sit flush against the browser edge. This
   deliberately excludes background media elements (the Cover block's own
   background image/video/overlay, or a bare <img>/<video>) so the
   background itself always stays true edge-to-edge — only actual content
   wrappers (e.g. a Group block's direct children) get the inset. Also
   excludes .content-width: that class sets its own (larger, calc()-based)
   padding, and without this exclusion this rule's higher specificity would
   win the same property and silently override it. .wp-block-cover__inner-container
   is excluded too -- a full-width Cover's content gets its own dedicated
   rule below instead (see the comment there for why). Remove this rule if
   you want truly edge-to-edge content instead. */
.ethereal-entry-content > .alignfull > *:not(img):not(video):not(.wp-block-cover__image-background):not(.wp-block-cover__video-background):not(.wp-block-cover__background):not(.content-width):not(.full-bleed):not(.wp-block-cover__inner-container) {
	padding-left: var(--ethereal-padding-left);
	padding-right: var(--ethereal-padding-right);
	box-sizing: border-box;
}

/* A full-width Cover block's own content (text, an HTML block, whatever's
   inside it) is always capped at Content width and centered, the same way
   .content-width works below -- no class needed. This is a dedicated rule
   (not just "give .wp-block-cover__inner-container the .content-width
   class automatically") because .content-width's own padding is meant to
   be layered on top of a plain inset -- nesting it inside content that's
   already been inset once (which is what the general rule above would do
   to a Cover) double-counts the padding on narrow screens/short Content
   widths. This rule is the full-width Cover's ONLY source of inset, so
   that can't happen. A full-bleed background image/video on the Cover
   itself is untouched either way, since backgrounds are separate layers
   from .wp-block-cover__inner-container. */
.ethereal-entry-content > .alignfull > .wp-block-cover__inner-container {
	padding-left: max(var(--ethereal-padding-left), calc((100% - var(--ethereal-content-width)) / 2));
	padding-right: max(var(--ethereal-padding-right), calc((100% - var(--ethereal-content-width)) / 2));
	box-sizing: border-box;
}

/* Counterpart to .content-width: instead of a bigger inset, this removes
   the inset entirely. The auto-inset rule above only skips a bare
   img/video that's a DIRECT child of .alignfull -- a photo placed inside a
   Columns/Group block (the image's parent being a .wp-block-column or
   similar wrapper, not .alignfull itself) still gets the wrapper's inset,
   so an "edge to edge photo band" made with e.g. a single-column Columns
   block needs this class on that inner block (the Column, not the outer
   Columns block) to actually reach the edges. Add "full-bleed" in that
   block's "Additional CSS Class(es)" field. */
.full-bleed {
	padding-left: 0;
	padding-right: 0;
}

/* Utility class for a full-width block whose own CONTENT should still be
   capped at the site's Content width (Theme Options) and centered, while
   the block itself (and any background color/image on it) keeps spanning
   edge to edge -- add it in the block's "Additional CSS Class(es)" field
   alongside "alignfull". Uses padding rather than max-width + margin:auto
   so the block's own box (and any background painted on it) is untouched;
   only the visible content area is inset. max() picks whichever is larger:
   the normal site padding, or the amount needed to center Content width
   within the current viewport -- so on narrow screens (where that amount
   goes negative) it falls back to the normal padding instead, matching
   .ethereal-content-wrap's own behavior at the same widths. */
.content-width {
	padding-left: max(var(--ethereal-padding-left), calc((100% - var(--ethereal-content-width)) / 2));
	padding-right: max(var(--ethereal-padding-right), calc((100% - var(--ethereal-content-width)) / 2));
	box-sizing: border-box;
}

/* The "wide" breakpoint (below which .alignwide collapses to normal
   content width, since there's no room to usefully extend it) is
   configurable from Appearance > Customize > Theme Options, so it's
   printed as an inline <style> in wp_head (see inc/output.php) rather
   than fixed here. .alignfull never needs a breakpoint override — its
   max(0px, …) clamp above already produces the correct result at every
   screen size. */

/* Make sure oversized media never breaks layout */
.ethereal-entry-content img,
.ethereal-entry-content iframe,
.ethereal-entry-content video,
.ethereal-entry-content embed {
	max-width: 100%;
	height: auto;
}

.ethereal-entry-content iframe {
	width: 100%;
}

/* -----------------------------------------------------------
   Note: content padding (all four sides) is fully controlled from
   Appearance > Customize > Theme Options and applies at every screen
   size — there's no automatic mobile reduction. Pick values that work
   on small screens too, or use Additional CSS for a breakpoint override.
----------------------------------------------------------- */

/* -----------------------------------------------------------
   Scroll to top button (base styles; position/size are
   applied inline via inc/output.php based on theme options)
----------------------------------------------------------- */
.ethereal-scroll-top {
	position: fixed;
	z-index: 9999;
	display: block;
	padding: 0;
	border: 0;
	background: transparent;
	cursor: pointer;
	opacity: 0;
	visibility: hidden;
	transform: translateY(10px);
	transition: opacity 0.25s ease, transform 0.25s ease, visibility 0.25s ease;
}

.ethereal-scroll-top.is-visible {
	opacity: 1;
	visibility: visible;
	transform: translateY(0);
}

.ethereal-scroll-top img {
	width: 100%;
	height: 100%;
	display: block;
}

/* -----------------------------------------------------------
   Header & footer chrome (only printed on pages using the
   "Regular Page (Header & Footer)" template — see ethereal_has_chrome()
   in functions.php). Colors, padding, and the desktop/tablet/mobile
   logo-width + min-height values are all configured from
   Appearance > Customize > Header / Footer and printed as inline
   <style> in inc/output.php; this is just the structural CSS that
   never changes.
----------------------------------------------------------- */
/* Same width/max-width technique as .ethereal-content-wrap above, so the
   header/footer inner width matches the main content's behavior: Content
   width on any screen wide enough for it, shrinking below that only once
   the viewport gets tight enough that the padding is actually needed to
   keep things off the screen edge. */
.ethereal-inner {
	width: calc(100% - (var(--ethereal-padding-left) + var(--ethereal-padding-right)));
	max-width: var(--ethereal-content-width);
	margin-left: auto;
	margin-right: auto;
}

.ethereal-header {
	width: 100%;
	position: relative;
}

.ethereal-header--sticky {
	position: sticky;
	top: 0;
	z-index: 500;
}

/* A small, separately-positioned spot in the header band for a compact row
   of icon links (its own nav menu, assigned at Appearance > Menus). top/
   right offsets come from Theme Options > Header > Corner menu and are
   printed inline (see ethereal_output_header_footer_css() in inc/output.php).
   Positioned relative to .ethereal-header itself (not .ethereal-header-inner), so it
   sits in the corner of the whole header band regardless of the header's
   own layout or Content-width constraint. */
.ethereal-header-corner {
	position: absolute;
	z-index: 10;
	/* Only visually matters when Fade out on scroll is on (see .is-faded
	   below); harmless to always have since nothing else on this element
	   animates opacity. */
	transition: opacity 0.3s ease;
}

/* "Sticky" corner menu (Theme Options > Header > Corner menu): pins it to
   the same spot in the VIEWPORT regardless of scroll, instead of scrolling
   away with whatever it's normally positioned relative to. top/right are
   already set inline (same values either way -- see
   ethereal_output_header_footer_css() in inc/output.php), so this only needs to
   override the position itself. */
.ethereal-header-corner.is-sticky {
	position: fixed;
	z-index: 1000;
}

/* Fade out on scroll (same section): toggled by a small script in
   inc/output.php based on scroll position -- see
   ethereal_output_corner_menu_fade_script(). Non-interactive while faded so it
   can't be clicked through. */
.ethereal-header-corner.is-faded {
	opacity: 0;
	pointer-events: none;
}

/* Positioning context for the corner menu when it's reused on the default
   landing-page template, which has no <header> (position: relative) to
   anchor .ethereal-header-corner's position: absolute to -- see
   ethereal_output_landing_corner_menu() in inc/output.php, and the "Also show on
   landing pages" checkbox under Theme Options > Header > Corner menu. Zero
   footprint otherwise: same corner menu, same offsets, same everything,
   just wrapped in enough to place it identically without an actual header. */
.ethereal-landing-corner-wrap {
	position: relative;
}

.ethereal-corner-menu {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	list-style: none;
	margin: 0;
	padding: 0;
	/* gap is set inline from Theme Options > Header > Corner menu; see
	   ethereal_output_header_footer_css() in inc/output.php. */
}

.ethereal-corner-menu a {
	display: inline-flex;
	align-items: center;
	color: inherit;
	text-decoration: none;
}

/* .ethereal-header-inner is the single flex container for the logo, the menu
   toggle, and the nav — no extra wrapper row. align-items:center is set
   unconditionally so the content is always vertically centered regardless
   of layout: in the default "centered" (column) layout that's the CROSS
   axis (horizontal centering), and justify-content:center is the MAIN
   axis (vertical centering); in "inline" (row) layout those roles swap,
   so align-items:center becomes the vertical centering instead. Either
   way, vertical centering never has to be turned off. */
.ethereal-header-inner {
	display: flex;
	flex-wrap: wrap;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	position: relative;
	box-sizing: border-box;
}

.ethereal-header--inline .ethereal-header-inner {
	flex-direction: row;
	justify-content: space-between;
}

.ethereal-header-logo a {
	display: inline-block;
	/* Without this, the inline-block box sits on the surrounding text
	   baseline, leaving room below it for a descender that's never
	   there — the "space at the bottom of the logo" this fixes. */
	vertical-align: bottom;
}

.ethereal-header-logo img {
	display: block;
	height: auto;
}

/* -----------------------------------------------------------
   Animated logo ("ESSENCE TAROT", letter-by-letter, moon/sun
   icons that blend through 3 colors each). Colors, speed, loop,
   font and the *default* width are all configurable from Theme
   Options > Header > Animated logo -- see
   ethereal_output_animated_logo_css() in inc/output.php for the
   keyframes/width those settings drive. This block is the fixed
   structural part: the layout, the width-to-font-size scaling,
   and the one-time letter-by-letter fade-in itself.

   .ethereal-animated-logo-wrap is a CSS container (container-type:
   inline-size) with a WIDTH -- either the responsive one printed
   in inc/output.php, or a fixed inline style="width:..." from the
   shortcode's own width="" attribute (which wins either way, since
   an inline style beats an external stylesheet regardless of
   specificity). .ethereal-animated-logo's font-size is a percentage of
   that container's width (cqw units) rather than a fixed size, so
   the whole thing scales to fill the wrapper -- no separate
   font-size setting needed, and no JavaScript measuring anything.
   12.94cqw was measured against the actual "ESSENCE TAROT" text
   (icons, side margins and kerning included) set in Fonseca: at that
   value, the rendered content's width lands within a fraction of a
   pixel of the wrapper's width, confirmed live at several sizes.
   Re-measure this if the icon sizing/margins/kerning above ever
   change again, or if "Font family" is switched to something with
   very different letter widths than Fonseca -- it won't fill the
   wrapper quite as precisely either way.

   max-width: 100% is what makes the whole thing responsive the way
   an <img> is: the wrap's own "width" (either the responsive default
   from inc/output.php, or a shortcode's fixed override) is a ceiling,
   not a fixed size -- if that width would be wider than the space
   actually available (a narrow phone screen, a narrow column/sidebar
   the shortcode is dropped into), it shrinks to fit instead of
   overflowing. Because the font-size above is a container-query
   percentage of the wrap's own (now-shrunk) width, the letters and
   icons scale down right along with it -- nothing needs its own
   separate "mobile size" for this. */
.ethereal-animated-logo-wrap {
	display: inline-block;
	container-type: inline-size;
	max-width: 100%;
}

.ethereal-animated-logo {
	display: inline-flex;
	align-items: center;
	line-height: 1;
	white-space: nowrap;
	text-transform: uppercase;
	font-size: 12.94cqw;
}

.ethereal-header-logo--animated a {
	display: inline-flex;
	align-items: center;
}

.ethereal-al-letter,
.ethereal-al-icon,
.ethereal-al-space {
	display: inline-block;
	opacity: 0;
	animation-name: ethereal-al-fade-in;
	animation-duration: 0.5s;
	animation-timing-function: ease;
	animation-fill-mode: forwards;
}

@keyframes ethereal-al-fade-in {
	from {
		opacity: 0;
		transform: translateY(6px);
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

/* Height is 110% of Fonseca's own cap-height (measured via canvas
   actualBoundingBoxAscent at a known font-size: ~0.733 of font-size, times
   1.1), so the icons read as slightly taller than the surrounding capital
   letters -- sized in em so it scales automatically across the
   mobile/tablet/desktop tiers along with the text, with no separate
   icon-size setting needed. Width isn't a fixed square: each icon has its
   own aspect ratio (the moon's tight viewBox in inc/output.php is 48 wide x
   72 tall; the sun's is 80x80), and matching that ratio here is what keeps
   them from looking squashed or leaving dead space in a boxy square. The
   small side margin (not present on letters/spaces) gives both icons a bit
   of breathing room from the letters on either side, rather than sitting
   flush against them. */
.ethereal-al-icon {
	margin: 0 0.08em;
}

/* Slightly tighter than the general 0.08em on this one side only -- the
   default read as a bit too roomy specifically after the sun. */
.ethereal-al-sun {
	margin-right: 0.05em;
}

.ethereal-al-moon {
	width: 0.5375em;
	height: 0.8063em;
}

.ethereal-al-sun {
	width: 0.8063em;
	height: 0.8063em;
}

.ethereal-al-icon-svg {
	display: block;
	width: 100%;
	height: 100%;
}

/* Text size/color are set from Appearance > Customize > Header > Tagline
   (see inc/output.php); this just resets the browser default <p> margin
   and centers it under the logo. */
.ethereal-header-tagline {
	margin: 4px 0 0;
	text-align: center;
}

.ethereal-header-nav {
	margin-top: 8px;
}

.ethereal-header--inline .ethereal-header-nav {
	margin-top: 0;
	margin-left: 16px;
}

/* When the mobile menu is opened in "inline" layout, it can't stay in the
   same row as the logo/toggle — drop it to its own full-width line below. */
.ethereal-header--inline .ethereal-header-nav.is-open {
	flex-basis: 100%;
	margin-left: 0;
	margin-top: 8px;
}

.ethereal-menu {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 8px 24px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.ethereal-header--inline .ethereal-menu {
	justify-content: flex-end;
}

/* A trailing run of icon-only items (e.g. social icons), grouped by
   assets/js/header-nav.js into one flex item so they share a single line
   even when the mobile menu opens and .ethereal-menu switches to one item per
   line (see the mobile breakpoint in inc/output.php). The original <li>
   elements are moved in whole (see the JS), so this is a real nested
   <ul> — reset like .ethereal-menu itself, just laid out as a row. */
.ethereal-menu-icon-row {
	display: flex;
	align-items: center;
	gap: 16px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.ethereal-menu a {
	color: inherit;
	text-decoration: none;
}

.ethereal-header-toggle {
	display: none;
	position: relative;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 5px;
	width: 32px;
	height: 32px;
	padding: 0;
	background: transparent;
	border: 0;
	cursor: pointer;
}

/* In "centered" layout the toggle is pulled out of flow so it doesn't
   throw off the logo's horizontal centering; it's pinned to the right
   edge, vertically centered on the header row itself. */
.ethereal-header--centered .ethereal-header-toggle {
	position: absolute;
	top: 50%;
	right: 0;
	transform: translateY(-50%);
}

.ethereal-header--inline .ethereal-header-toggle {
	margin-left: auto;
}

.ethereal-header-toggle span {
	display: block;
	width: 100%;
	height: 2px;
	background: currentColor;
	flex-shrink: 0;
}

/* Mobile menu toggle icon variants (Appearance > Customize > Header >
   Mobile menu toggle). Default (no modifier class) is the 3-line
   hamburger above; these override just enough to produce the alternates
   from the same three <span> elements, no extra markup needed. */
.ethereal-header-toggle--lines-2 span:nth-child(2) {
	display: none;
}

.ethereal-header-toggle--dots {
	gap: 4px;
}

.ethereal-header-toggle--dots span {
	width: 5px;
	height: 5px;
	border-radius: 50%;
}

/* Open state: always an X made from the first/third bars, the same size
   (20px) regardless of which icon variant is selected above -- this is
   deliberately placed after the variant rules so it wins any specificity
   tie with e.g. .ethereal-header-toggle--dots span (both 2 classes + type). */
.ethereal-header-toggle span {
	transition: transform 0.2s ease, opacity 0.2s ease, width 0.2s ease, height 0.2s ease;
}

.ethereal-header-toggle.is-open span {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 26px;
	height: 2px;
	border-radius: 0;
	margin: 0;
}

.ethereal-header-toggle.is-open span:nth-child(1) {
	transform: translate(-50%, -50%) rotate(45deg);
}

.ethereal-header-toggle.is-open span:nth-child(2) {
	opacity: 0;
}

.ethereal-header-toggle.is-open span:nth-child(3) {
	transform: translate(-50%, -50%) rotate(-45deg);
}

.ethereal-footer-widgets {
	display: flex;
	flex-direction: column;
	gap: 24px;
}

.ethereal-footer-widgets .widget {
	width: 100%;
}

.ethereal-footer-copyright {
	width: 100%;
}

.ethereal-footer-copyright-inner {
	text-align: center;
}

/* -----------------------------------------------------------
   Theme color utility classes: apply a swatch (Appearance > Customize >
   Theme Colors) as text color (.theme-color-N) or background color
   (.theme-bg-color-N) anywhere -- e.g. via the block editor's
   "Additional CSS Class(es)" field, or in a Custom HTML block. Each one
   just references the matching --ethereal-theme-color-N custom property (see
   inc/output.php), so if you rename or repick a swatch later, anything
   using these classes updates automatically -- no need to revisit them.
   !important on all of them: these are meant to be dropped onto any
   element as an override, e.g. an "Additional CSS Class" on a block whose
   own theme/plugin styles already set a color/background-color with equal
   or higher specificity -- without !important a single utility class would
   routinely lose that fight and silently do nothing.
----------------------------------------------------------- */
.theme-color-1 { color: var(--ethereal-theme-color-1) !important; }
.theme-color-2 { color: var(--ethereal-theme-color-2) !important; }
.theme-color-3 { color: var(--ethereal-theme-color-3) !important; }
.theme-color-4 { color: var(--ethereal-theme-color-4) !important; }
.theme-color-5 { color: var(--ethereal-theme-color-5) !important; }

.theme-bg-color-1 { background-color: var(--ethereal-theme-color-1) !important; }
.theme-bg-color-2 { background-color: var(--ethereal-theme-color-2) !important; }
.theme-bg-color-3 { background-color: var(--ethereal-theme-color-3) !important; }
.theme-bg-color-4 { background-color: var(--ethereal-theme-color-4) !important; }
.theme-bg-color-5 { background-color: var(--ethereal-theme-color-5) !important; }

/* -----------------------------------------------------------
   Top Bar (Appearance > Customize > Top Bar): a site-wide announcement bar,
   independent of the header -- can appear on every template, landing pages
   included. Background/min-height/padding/close-color are printed as
   dynamic CSS by ethereal_output_topbar_css() (inc/output.php); everything here
   is fixed structural layout. z-index 1200 sits above the corner menu's
   1000/1100 (see .ethereal-header-corner) so the bar always wins if both are
   sticky and happen to overlap on a very short screen.
----------------------------------------------------------- */
.ethereal-topbar {
	position: relative;
	width: 100%;
	box-sizing: border-box;
	z-index: 1200;
}

/* Sticky (Top Bar > Position & behavior): pins it to the viewport instead
   of scrolling away with the page. top/bottom match whichever position was
   picked -- see .ethereal-topbar-top / .ethereal-topbar-bottom below. Body padding
   that reserves matching space is handled in JS (updateOffset(), in
   ethereal_output_topbar_script()), since the bar's real height depends on its
   content and isn't known from CSS alone. */
.ethereal-topbar.is-sticky {
	position: fixed;
	left: 0;
}

.ethereal-topbar.is-sticky.ethereal-topbar-top {
	top: 0;
}

.ethereal-topbar.is-sticky.ethereal-topbar-bottom {
	bottom: 0;
}

.ethereal-topbar-inner {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-wrap: wrap;
	gap: 8px 16px;
	box-sizing: border-box;
	/* Room on the right for the close button, which is positioned
	   independently of this padding (see .ethereal-topbar-close) so it can't get
	   clipped by a narrow right-padding value. */
	padding-right: 40px;
}

/* flex: 0 1 auto (NOT 1 1 auto) is what actually makes "centered together"
   work: with flex-grow, this item would expand to fill every bit of extra
   row width, pushing the CTA button out to the row's far edge with no
   space left for justify-content: center (above) to have any visible
   effect. Without grow, the row's used width is just content + gap +
   button -- exactly the "centered together" unit that's wanted -- and it
   can still shrink (and, via flex-wrap on the parent, drop to its own
   line) on a narrow screen. */
.ethereal-topbar-content {
	flex: 0 1 auto;
	min-width: 0;
	text-align: center;
}

/* Raw HTML pasted into the Content field (Top Bar > Content) may well be
   plain text wrapped in a <p> by the site owner, or by a shortcode -- reset
   its default browser margin so it doesn't add unwanted height inside the
   bar. Deliberately narrow (only directly-nested <p>, not every descendant)
   so anything more elaborate pasted in there keeps its own natural spacing. */
.ethereal-topbar-content > p {
	margin: 0;
}

.ethereal-topbar-cta {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	/* Only creates visible space when an icon span is actually present
	   (see .ethereal-topbar-cta-icon below) -- harmless with just text. */
	gap: 6px;
	/* No border by design -- background-color (see .ethereal-topbar-cta above,
	   printed by ethereal_output_topbar_css() when set) is what distinguishes
	   the button, not an outline. font-size, font-weight, border-radius and
	   padding are also printed dynamically there (Top Bar > Call-to-action
	   button); nothing here hard-codes them. */
	color: inherit;
	text-decoration: none;
	white-space: nowrap;
	/* background-color itself (both normal and :hover) is only ever printed
	   by ethereal_output_topbar_css() when the corresponding Customizer field is
	   actually set -- this transition is harmless either way (nothing to
	   animate if there's no background), so it's always safe to include. */
	transition: background-color 0.2s ease;
}

/* Icon size/color are printed dynamically by ethereal_output_topbar_css() (Top
   Bar > Call-to-action button > Icon...); this just keeps a Font-Awesome-
   style icon vertically tidy inside the flex row above. */
.ethereal-topbar-cta-icon {
	display: inline-flex;
	align-items: center;
	line-height: 1;
}

.ethereal-topbar-close {
	position: absolute;
	top: 50%;
	right: 12px;
	transform: translateY(-50%);
	background: none;
	border: none;
	margin: 0;
	padding: 4px;
	font-size: 22px;
	line-height: 1;
	cursor: pointer;
	color: inherit;
}

/* -----------------------------------------------------------
   [ethereal_slider] -- see ethereal_shortcode_slider() in inc/output.php for the
   full attribute list and behavior. Track width/each slide's width are set
   inline per-instance (they depend on the slide count), so only the parts
   that don't vary by instance live here.
----------------------------------------------------------- */
.ethereal-slider {
	position: relative;
	width: 100%;
	overflow: hidden;
}

.ethereal-slider-track {
	display: flex;
	/* flex-start, not the stretch default -- each slide needs to keep its
	   own natural height so JS can read it accurately (see resize() in
	   ethereal_shortcode_slider()); stretch would make every slide match
	   whatever height the track last animated to, defeating the point. */
	align-items: flex-start;
	transition: transform 0.5s ease, height 0.3s ease;
}

.ethereal-slider-slide {
	flex-shrink: 0;
	box-sizing: border-box;
}

/* testimonials="true" -- see ethereal_shortcode_slider() in inc/output.php.
   Floated dropcap-style so the slide's own content wraps around it, same
   as a classic drop cap wraps around a paragraph's first letter -- floats
   align at the top of the current line box by default, which is what gets
   its top edge level with the slide's own text with no extra CSS needed
   here. font-size is in em, so it scales off the slide's own (inherited)
   font size along with everything else in it. Both color and font-family
   are set inline per-instance (via the quote_color attribute, and
   ethereal_font_family_css( 'body' ), respectively) since neither is a fixed
   Customizer setting; the font-family below is only a fallback for the
   rare case that comes back empty (Typography's Body font left on
   "Default", i.e. the browser's own default rather than a specific
   Google/custom font). A flex item (which .ethereal-slider-slide is, being
   a child of the flex .ethereal-slider-track) establishes its own block
   formatting context, so this float is contained correctly without any
   extra clearfix.

   The negative margin-bottom is deliberate, not a mistake: at this
   font-size, a "natural" (0-margin) float box is tall enough that the
   surrounding paragraph text wraps around it for 3 lines before returning
   to full width, which reads as too much empty space to the right of a
   mark that's visually much shorter than that. Pulling the float's own
   *footprint* up with a negative margin (rather than shrinking line-height
   further, which was tried first and visibly distorted the glyph at that
   extreme) tightens that to 2 wrapped lines while leaving the glyph itself
   rendered at full size and undistorted -- margin, unlike line-height,
   doesn't affect how the glyph itself is drawn, only how much space other
   content avoids around it. -0.25em is relative to THIS element's own
   font-size (not the paragraph's), so it scales along with font-size
   rather than needing its own separate tuning if font-size ever changes. */
.ethereal-slider-quote {
	float: left;
	font-family: Georgia, 'Times New Roman', serif;
	font-size: 8em;
	line-height: 0.7;
	margin: 0 0.15em -0.25em 0;
	font-style: normal;
}

.ethereal-slider-arrow {
	position: absolute;
	top: 50%;
	z-index: 2;
	transform: translateY(-50%);
	display: flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	margin: 0;
	padding: 0;
	border: none;
	border-radius: 50%;
	background: rgba(0, 0, 0, 0.4);
	color: #fff;
	font-size: 22px;
	line-height: 1;
	cursor: pointer;
	transition: background-color 0.2s ease, opacity 0.2s ease;
}

.ethereal-slider-arrow:hover {
	background: rgba(0, 0, 0, 0.6);
}

.ethereal-slider-arrow:disabled {
	opacity: 0.3;
	cursor: default;
}

.ethereal-slider-arrow-prev {
	left: 12px;
}

.ethereal-slider-arrow-next {
	right: 12px;
}

/* Sits below the slider in normal flow (not overlaid, unlike the arrows
   above), so it adds to the wrapper's own height rather than clipping
   inside its overflow: hidden. */
.ethereal-slider-dots {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	margin-top: 12px;
}

.ethereal-slider-dot {
	width: 8px;
	height: 8px;
	margin: 0;
	padding: 0;
	border: none;
	border-radius: 50%;
	background: rgba(0, 0, 0, 0.25);
	cursor: pointer;
	transition: background-color 0.2s ease;
}

.ethereal-slider-dot:hover {
	background: rgba(0, 0, 0, 0.45);
}

.ethereal-slider-dot.is-active {
	background: rgba(0, 0, 0, 0.75);
}

/* The horizontal slide + height animation is genuine motion, unlike, say,
   [ethereal_random_text]'s typing effect -- so unlike that one, this
   respects prefers-reduced-motion: slides still change on click/swipe/
   autorun, they just snap instantly instead of sliding/animating height. */
@media (prefers-reduced-motion: reduce) {
	.ethereal-slider-track {
		transition: none;
	}
}

/* -----------------------------------------------------------
   Ethereal Tabs block (lpb/tabs + lpb/tab-item -- see inc/blocks.php).
   A physical "file folder tab" look: each button has its own border (grey
   when inactive, its own set color when active, rounded on its top corners
   only) and sits with zero gap directly on top of the content box below,
   whose own border matches that same color -- so the active button's sides
   + the box's top edge read as one continuous outline, with no separate
   underline needed to show which tab is open.

   Colors are a PER-TAB setting (each lpb/tab-item has its own Colors panel
   in tabs-editor.js, covering both active AND inactive state, including
   each state's own hover colors), not a group-level one -- so the
   --ethereal-tabs-active-bg / -active-text / -active-border / -active-hover-bg /
   -active-hover-text / -active-hover-border / -inactive-bg / -inactive-text /
   -border / -hover-bg / -hover-text / -hover-border custom properties are
   printed directly onto that one tab's own elements: onto its <button> by
   ethereal_render_tabs_block() (inc/blocks.php, reading the child block's raw
   attrs), and onto its own .ethereal-tab-item panel by lpb/tab-item's own
   save()/edit() (tabs-editor.js) -- a button and its panel are sibling DOM
   nodes, not ancestor/descendant, so each needs the value printed on it
   directly rather than inheriting it via cascade. -active-border is the one
   dual-purpose property: it's "Button & content border" in the editor, so
   setting it colors both the button's border and its content box's border
   at once, from a single field.

   -border-width / -content-radius / -content-padding-{top,right,bottom,left}
   remain GROUP-level (every tab shares one border width/radius/padding),
   printed on the Tabs block's own wrapper by ethereal_render_tabs_block() and
   inherited by every .ethereal-tab-item inside it via normal cascade.

   The fallbacks here (the site's Primary theme color, white text, grey
   border, transparent inactive background, 1px border width, square
   corners, 20px padding) are what a Tab left on defaults gets.
   assets/js/blocks/tabs-view.js does the actual show/hide + is-active
   toggling on click; this is purely visual.
----------------------------------------------------------- */
.ethereal-tabs-nav {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: 4px;
}

.ethereal-tabs-nav-button {
	margin: 0;
	padding: 0.6em 1.1em;
	border-width: var(--ethereal-tabs-border-width, 1px);
	border-style: solid;
	border-color: var(--ethereal-tabs-border, rgba(0, 0, 0, 0.25));
	/* Open at the bottom -- it sits flush against .ethereal-tab-item below, whose
	   own top border (same color, when this tab is active) continues the
	   shape, so a separate bottom edge here would just be a seam. */
	border-bottom: 0;
	border-top-left-radius: var(--ethereal-tabs-content-radius, 0px);
	border-top-right-radius: var(--ethereal-tabs-content-radius, 0px);
	background-color: var(--ethereal-tabs-inactive-bg, transparent);
	color: var(--ethereal-tabs-inactive-text, inherit);
	font: inherit;
	/* The theme's own Body typography font (Appearance > Customize >
	   Typography), read fresh on every render by ethereal_render_tabs_block() --
	   same "follow whatever Typography is currently set to" reasoning as
	   $quote_font in ethereal_shortcode_slider() (inc/output.php). Buttons don't
	   inherit this from the page the way a <p> would (browsers give form
	   controls their own UA font stack that `font: inherit` above resets to
	   this element's actual parent, not to whatever font-family a sibling
	   <p> happens to use), so it has to be set explicitly here. Falls back
	   to `inherit` -- i.e. behaves like before -- when Body is left on
	   "Default" in Typography.  */
	font-family: var(--ethereal-tabs-button-font-family, inherit);
	/* Fallback (bold) matches this button's look from before this setting
	   existed, so a Tabs block left on default still renders the same. */
	font-weight: var(--ethereal-tabs-button-font-weight, bold);
	/* Desktop tier only -- the tablet/mobile tiers can't be driven by a
	   plain var() fallback here the way the other properties on this rule
	   are, because they also depend on the site's own (Customizer-
	   configurable, not a fixed pixel value) responsive breakpoints. See
	   the matching .ethereal-tabs-nav-button rules inside the @media blocks in
	   ethereal_output_breakpoint_css() / ethereal_output_mobile_breakpoint_css()
	   (inc/output.php) for those two tiers. */
	font-size: var(--ethereal-tabs-button-font-size-desktop, inherit);
	cursor: pointer;
	opacity: 0.7;
	transition: opacity 0.2s ease, background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

/* Hover falls back to the inactive tab's own base colors (not straight to
   `transparent`/`inherit`), so setting only the base inactive color still
   gives hover something sensible to lean on instead of jumping to an
   unrelated default the instant the mouse arrives. */
.ethereal-tabs-nav-button:hover,
.ethereal-tabs-nav-button:focus-visible {
	opacity: 1;
	background-color: var(--ethereal-tabs-hover-bg, var(--ethereal-tabs-inactive-bg, transparent));
	color: var(--ethereal-tabs-hover-text, var(--ethereal-tabs-inactive-text, inherit));
	border-color: var(--ethereal-tabs-hover-border, var(--ethereal-tabs-border, rgba(0, 0, 0, 0.25)));
}

.ethereal-tabs-nav-button.is-active {
	opacity: 1;
	background-color: var(--ethereal-tabs-active-bg, var(--ethereal-theme-color-1, #1a1a1a));
	/* Independent field now (no longer mirrors the active background by
	   default) -- falls straight to the site's theme color, same as
	   background does, so an unset border still looks reasonable on its
	   own. See .ethereal-tab-item below for the other half of that. */
	border-color: var(--ethereal-tabs-active-border, var(--ethereal-theme-color-1, #1a1a1a));
	color: var(--ethereal-tabs-active-text, #ffffff);
}

/* Same "hover falls back to this state's own base colors" reasoning as the
   plain :hover rule above, just for the active tab's own colors instead of
   the inactive ones -- and needs the extra .is-active class to win over
   that plain :hover rule regardless of source order (3 classes beat 2). */
.ethereal-tabs-nav-button.is-active:hover,
.ethereal-tabs-nav-button.is-active:focus-visible {
	background-color: var(--ethereal-tabs-active-hover-bg, var(--ethereal-tabs-active-bg, var(--ethereal-theme-color-1, #1a1a1a)));
	border-color: var(--ethereal-tabs-active-hover-border, var(--ethereal-tabs-active-border, var(--ethereal-theme-color-1, #1a1a1a)));
	color: var(--ethereal-tabs-active-hover-text, var(--ethereal-tabs-active-text, #ffffff));
}

/* Also matches the legacy ".lpb-tab-item" class -- see the doc comment atop
   tabs-view.js for why: a Tab block's saved markup is frozen HTML, so pages
   last saved before the lpb_ -> ethereal_ rename still carry the old class,
   and this alias keeps their panels styled without requiring a re-save. */
.ethereal-tab-item,
.lpb-tab-item {
	border-width: var(--ethereal-tabs-border-width, 1px);
	border-style: solid;
	/* Same fallback chain as .ethereal-tabs-nav-button.is-active's own
	   border-color -- keeps this box visually connected to whichever tab
	   is open, whether that tab's border color is explicitly set or just
	   following the plain theme-color fallback. */
	border-color: var(--ethereal-tabs-active-border, var(--ethereal-theme-color-1, #1a1a1a));
	border-radius: var(--ethereal-tabs-content-radius, 0px);
	/* Square, not var()-driven like the other 3 corners: the first tab
	   button always starts flush at the box's left edge, so rounding this
	   one corner would put a curve where that button's straight left side
	   meets the box -- squaring it keeps that seam a single continuous
	   line regardless of the radius setting. */
	border-top-left-radius: 0;
	padding: var(--ethereal-tabs-content-padding-top, 20px) var(--ethereal-tabs-content-padding-right, 20px)
		var(--ethereal-tabs-content-padding-bottom, 20px) var(--ethereal-tabs-content-padding-left, 20px);
}

/* Editor-only: every tab stays open at once while editing (see
   ethereal-tabs--editing in tabs-editor.js), so authoring doesn't require
   clicking through tabs one at a time. Border width/radius/padding are
   inherited from the .ethereal-tabs--editing wrapper (group-level, cascades
   down); border color is per-tab and set directly on each .ethereal-tab-item--
   editing element by lpb/tab-item's own edit() -- together this box
   previews the real front-end box above accurately while editing. */
.ethereal-tabs--editing .ethereal-tabs-editing-hint {
	margin: 0 0 1em;
	font-size: 0.85em;
	font-style: italic;
	opacity: 0.7;
}

.ethereal-tab-item--editing {
	margin-bottom: 1.5em;
	border-width: var(--ethereal-tabs-border-width, 1px);
	border-style: solid;
	border-color: var(--ethereal-tabs-active-border, var(--ethereal-theme-color-1, #1a1a1a));
	border-radius: var(--ethereal-tabs-content-radius, 0px);
	border-top-left-radius: 0;
	padding: var(--ethereal-tabs-content-padding-top, 20px) var(--ethereal-tabs-content-padding-right, 20px)
		var(--ethereal-tabs-content-padding-bottom, 20px) var(--ethereal-tabs-content-padding-left, 20px);
}

.ethereal-tab-item-title-field {
	max-width: 320px;
}

.ethereal-tabs-panel-note {
	margin: 0 0 1em;
	font-size: 12px;
	font-style: italic;
	color: #757575;
}

/* Custom CSS from the theme options page is injected after
   this stylesheet in wp_head, so it can override anything above. */
