/* Summer Storms — Playdate-inspired dark theme.
   Halo text + ambient rain. Block-content friendly + responsive.
   Foundation styling for the Summer Storms website. */

/* ---------- Stage ---------- */

.summer-storms-main {
	/* --ss-bg is injected per-page from the "Background color" setting
	   (see Summer_Storms_Plugin::enqueue_assets). Falls back to pure black. */
	background: var(--ss-bg, #000);
	color: #fff;
	position: relative;
	width: 100%;
	min-height: 70vh;
	min-height: 70dvh;
	overflow: hidden;
	font-family: 'Roobert', system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

/* Full-bleed override: this template owns the viewport. */
.summer-storms-main--full-bleed {
	min-height: 100vh;
	min-height: 100dvh;
}

body.summer-storms-body.summer-storms-body {
	background: var(--ss-bg, #000);
}

/* ---------- Rain layer ---------- */

/* The rain is a STATIC viewport backdrop. It's pinned with position:fixed and a
   STABLE height (100vh / 100lvh = the large, URL-bar-hidden viewport) so it
   never moves or resizes while scrolling -- 100dvh would jitter on every scroll
   and made the rain "jump" on mobile. Content scrolls over it; only the
   accelerometer moves the rain. (Same "rain on glass" idea as the iOS Weather
   app.) */
.summer-storms-rain-layer {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	height: 100vh;
	height: 100lvh;
	pointer-events: none;
	z-index: 0;
	overflow: hidden;
}

#summer-storms-rain {
	display: block;
	width: 100%;
	height: 100%;
}

/* ---------- Centered scroll column ---------- */

.summer-storms-stage {
	position: relative;
	z-index: 1;
	min-height: inherit;
	display: flex;
	justify-content: center;
	align-items: flex-start;
	/* --ss-top is the "Top offset" setting from the plugin's options page,
	   expressed in vh. Fallback (30vh) matches the option default so the
	   page still styles correctly if the custom property is somehow
	   unset. In full-bleed mode the stage starts at viewport top, so this
	   is also % from window top exactly. In non-full-bleed mode the
	   stage starts below the theme's chrome -- the offset is from the
	   stage top either way. */
	padding: var(--ss-top, 30vh) 1rem clamp(1.5rem, 4vw, 3rem);
	box-sizing: border-box;
}

.summer-storms-scroll {
	/* Match the logo's responsive widths via the same custom properties,
	   so the content column always shares the logo's edges. The fallback
	   values (70vw / 50vw) match the option defaults. */
	width: var(--ss-logo-w-mobile, 70vw);
	text-align: center;
}

@media (min-width: 768px) {
	.summer-storms-scroll {
		width: var(--ss-logo-w-desktop, 50vw);
	}
}

/* ---------- Halo border + default text colour (Playdate "drawTextWithBorder") ----------
 * The "border" (a text-shadow halo drawn in the background colour) is the ONE
 * thing we intentionally force onto every piece of content. Because
 * text-shadow is an inherited
 * property, declaring it once on the wrapper paints the halo on every
 * descendant automatically -- and, crucially, WITHOUT the extra specificity
 * that used to stomp on the block editor's own settings.
 *
 * Colour here is only a DEFAULT. It's inherited from the wrapper rather than
 * pinned onto each element, so any per-block colour you pick in the editor
 * (a `has-…-color` class or an inline style) overrides it the normal way.
 * Alignment behaves the same: body copy defaults to left (see
 * .summer-storms-blocks) and is overridden by the editor's `has-text-align-*`
 * classes. Net effect: the border is automatic, but colour + alignment stay
 * under your control.
 */
.summer-storms-content {
	color: #fff;
	/* The halo is drawn in the stage BACKGROUND colour (--ss-bg), not hard
	   black, so on an off-black stage the outline matches the backdrop -- it
	   knocks the white rain away from the glyph edges without ringing the text
	   in a mismatched colour. Falls back to #000 when --ss-bg is unset. */
	text-shadow:
		-1px -1px 0 var(--ss-bg, #000),
		 1px -1px 0 var(--ss-bg, #000),
		-1px  1px 0 var(--ss-bg, #000),
		 1px  1px 0 var(--ss-bg, #000),
		 0   -1px 0 var(--ss-bg, #000),
		 0    1px 0 var(--ss-bg, #000),
		-1px  0   0 var(--ss-bg, #000),
		 1px  0   0 var(--ss-bg, #000);
}

/* Per-block opt-out. The "Remove text border (halo)" toggle the plugin adds to
   every block's sidebar sets this class (render_block adds it server-side, so
   it works for static AND dynamic blocks). !important so it beats the inherited
   halo on the block itself and everything inside it. */
.ss-no-border,
.ss-no-border * {
	text-shadow: none !important;
}

/* ---------- Logo ---------- */

.summer-storms-logo {
	margin: 0 0 clamp(1rem, 3vw, 2rem);
}

.summer-storms-logo img {
	display: inline-block;
	height: auto;
	/* Logo width follows the same --ss-logo-w-* custom properties as the
	   scroll column above, so the two always share their left/right
	   edges. Fallbacks (70vw / 50vw) match the plugin's option defaults
	   if the inline style ever fails to set the property. */
	width: var(--ss-logo-w-mobile, 70vw);
	text-shadow: none;
	image-rendering: -webkit-optimize-contrast;
}

@media (min-width: 768px) {
	.summer-storms-logo img {
		width: var(--ss-logo-w-desktop, 50vw);
	}
}

/* ---------- Header button ----------
 * The reusable per-page header: one clickable <a> wrapping an image, returning
 * to the home page by default. With NO background it's a compact centred
 * button; with a "Header background" colour set (.is-badge) it becomes a
 * fully-rounded BAR the width of the page content (the per-page "Content
 * width"). The image inside is sized independently by "Header image width"
 * and centred in the bar. */
.summer-storms-page-header {
	display: inline-flex;          /* compact button; centred by the column's text-align */
	align-items: center;
	justify-content: center;
	box-sizing: border-box;
	margin-bottom: clamp(1.25rem, 3vw, 2rem);
	line-height: 0;
	text-decoration: none;
	transition: opacity 120ms ease;
}

.summer-storms-page-header img {
	display: block;
	width: var(--ss-header-w, 100px);
	height: auto;
	max-width: 100%;
}

/* The bar spans the page CONTENT width (the same per-page "Content width" the
   column already uses, via width:100%), so it lines up with the content below.
   The image inside is sized independently by the "Header image width" setting,
   centred in the bar (justify-content from the base rule). */
.summer-storms-page-header.is-badge {
	display: flex;
	width: 100%;
	background: var(--ss-header-bg, transparent);
	border-radius: 999px;
	padding-inline: clamp(0.9rem, 3.5vw, 1.75rem);
	padding-block: clamp(0.6rem, 2.5vw, 1.25rem);
	overflow: hidden;
}

a.summer-storms-page-header:hover {
	opacity: 0.85;
}

a.summer-storms-page-header:focus-visible {
	outline: 3px solid currentColor;
	outline-offset: 4px;
}

/* ---------- Tagline ----------
 * Rendered as inline SVG by the template with textLength on the <text>
 * element, so it always spans exactly the parent column's width. The SVG
 * scales as a single unit (width:100%; height:auto), so the visible font
 * height tracks the logo width automatically.
 *
 * The font-family is set via the --ss-tagline-font custom property the
 * template injects from the user's "Tagline font" setting; the var()
 * fallback chain re-uses the page's font stack when no override is set.
 */

.summer-storms-tagline {
	/* Pull the tagline up close to the logo's baseline, then add a
	   bigger gap below so the content blocks don't crowd it. */
	margin: 0 auto clamp(1.5rem, 4vw, 2.5rem);
}

.summer-storms-tagline svg {
	display: block;
	width: 100%;
	height: auto;
	overflow: visible;
}

.summer-storms-tagline text {
	fill: #fff;
	font-family: var(--ss-tagline-font, 'Roobert', system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);
	font-weight: 600;
	/* The page-wide text-shadow halo would clash with SVG fill rules at
	   small sizes; the tagline reads cleanly white-on-black without it. */
	text-shadow: none;
}

/* ---------- Block content styling ---------- */

.summer-storms-blocks {
	font-size: clamp(1rem, 0.95rem + 0.2vw, 1.125rem);
	line-height: 1.55;
	/* Body content defaults to LEFT, even though the column itself is centred
	   (which is what keeps the logo + tagline centred above). The block
	   editor's `has-text-align-*` classes sit on each child element, so a
	   per-block Center/Right choice still overrides this inherited default.
	   Switch this to `center` if you ever want centred copy as the default. */
	text-align: left;
}

.summer-storms-blocks > * {
	margin-block: 0.6em;
}

/* Heading rhythm is a DEFAULT only. Wrapping the selectors in :where() drops
   their specificity to zero, so anything you set on a heading in the editor
   -- alignment (`has-text-align-*`), size (`has-*-font-size` or a custom
   size), colour, weight -- overrides these. Note we no longer set
   text-align or font-weight here: alignment inherits from the block container
   (left by default; see .summer-storms-blocks) and your per-block choice
   wins, and headings are already bold by default, so a weight you pick in the
   editor is respected. */
:where(.summer-storms-blocks h1, .summer-storms-blocks h2, .summer-storms-blocks h3, .summer-storms-blocks h4, .summer-storms-blocks h5, .summer-storms-blocks h6) {
	line-height: 1.2;
	margin: 1.2em 0 0.35em;
}

:where(.summer-storms-blocks h1) { font-size: clamp(1.8rem, 1.4rem + 1.6vw, 2.5rem); }
:where(.summer-storms-blocks h2) { font-size: clamp(1.5rem, 1.2rem + 1.2vw, 2rem); }
:where(.summer-storms-blocks h3) { font-size: clamp(1.25rem, 1.05rem + 0.8vw, 1.5rem); }

.summer-storms-blocks p {
	margin: 0.5em 0;
}

/* White links are a DEFAULT (links don't inherit colour, so without this the
   theme's link colour could be invisible on black). :where() keeps it
   zero-specificity, so a theme/site link colour wins; an editor-set per-block
   link colour wins via the rule below. */
:where(.summer-storms-blocks a) {
	color: #fff;
	text-decoration: underline;
	text-underline-offset: 2px;
}

/* If the user picked a link colour on the block (signalled by .has-link-color
   on a parent, which Gutenberg/WP always stamps when you choose a link colour
   in the editor), step aside and let the link inherit the parent's colour. On
   WordPress.com Atomic the matching `.wp-elements-{hash} a { color: ... }`
   inline rule is sometimes dropped by CSS optimisation -- without this guard
   our white default would otherwise overpaint the intended colour. The slight
   specificity bump (class + descendant + element = 0,1,1) beats the :where()
   default above (0,0,0). */
.summer-storms-blocks :where(.has-link-color) a,
.summer-storms-blocks a:where(.has-link-color) {
	color: inherit;
}

.summer-storms-blocks a:hover,
.summer-storms-blocks a:focus-visible {
	text-decoration-thickness: 2px;
}

.summer-storms-blocks ul,
.summer-storms-blocks ol {
	list-style-position: inside;
	padding: 0;
	margin: 0.5em 0;
}

:where(.summer-storms-blocks .wp-block-image),
:where(.summer-storms-blocks figure) {
	margin-inline: auto;
}

.summer-storms-blocks img,
.summer-storms-blocks .wp-block-image img {
	max-width: 100%;
	height: auto;
}

:where(.summer-storms-blocks .wp-block-separator) {
	border: 0;
	border-top: 1px solid rgba(255, 255, 255, 0.4);
	margin: 1.5em auto;
	max-width: 30%;
}

:where(.summer-storms-blocks .wp-block-quote) {
	border-left: 2px solid rgba(255, 255, 255, 0.6);
	padding-left: 1em;
	text-align: left;
	margin: 1em auto;
	max-width: 90%;
}

/* Buttons keep their OWN editor/theme styling -- the plugin must not impose a
   colour, border, radius, or the text halo on them. We do exactly two things:
   (1) switch the halo OFF (it would otherwise be inherited onto the button
   label, including labels wrapped in <strong>/<span>, leaving a "border" on the
   text); and (2) centre the Buttons block by default. The centring is a
   zero-specificity :where() default, so the editor's Justify / Align controls
   (is-content-justification-*, has-text-align-*) always win. */
.summer-storms-blocks .wp-element-button,
.summer-storms-blocks .wp-element-button *,
.summer-storms-blocks .wp-block-button__link,
.summer-storms-blocks .wp-block-button__link * {
	text-shadow: none;
}

:where(.summer-storms-blocks .wp-block-buttons) {
	justify-content: center;
	text-align: center;
}

:where(.summer-storms-blocks code),
:where(.summer-storms-blocks pre) {
	background: rgba(255, 255, 255, 0.08);
	color: #fff;
	border-radius: 4px;
}

:where(.summer-storms-blocks pre) {
	padding: 1em;
	text-align: left;
	overflow-x: auto;
	text-shadow: none;
}

:where(.summer-storms-blocks code) {
	padding: 0 0.3em;
	text-shadow: none;
}

/* ---------- Full-bleed: hide common theme chrome ---------- */

body.summer-storms-body:has(.summer-storms-main--full-bleed) header.site-header,
body.summer-storms-body:has(.summer-storms-main--full-bleed) footer.site-footer,
body.summer-storms-body:has(.summer-storms-main--full-bleed) #masthead,
body.summer-storms-body:has(.summer-storms-main--full-bleed) #colophon,
body.summer-storms-body:has(.summer-storms-main--full-bleed) .wp-block-template-part[data-type="header"],
body.summer-storms-body:has(.summer-storms-main--full-bleed) .wp-block-template-part[data-type="footer"] {
	display: none;
}

/* ---------- Small screens ---------- */

@media (max-width: 480px) {
	/* Keep the 30vh padding-top from the base rule -- per the design,
	   the logo should sit 30% down on every screen size, not collapse
	   on small viewports. Only adjust the body font here. */
	.summer-storms-blocks {
		font-size: 1rem;
	}
}

/* ---------- iOS tilt-permission pill ---------- */

/* rain.js injects this button only on iOS 13+ where DeviceOrientationEvent
   requires a user-gesture-triggered permission grant. Styled to match the
   stage: dark fill, white border, white text, pill shape -- so it reads as
   part of the Summer Storms surface, not a foreign system UI element. */
.summer-storms-tilt-chip {
	position: fixed;
	right: 16px;
	bottom: 16px;
	z-index: 9999;
	padding: 0.55em 1.2em;
	font: 600 13px/1 'Roobert', system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
	color: var(--ss-rain, #fff);
	background: rgba(0, 0, 0, 0.7);
	border: 2px solid var(--ss-rain, #fff);
	border-radius: 999px;
	cursor: pointer;
	-webkit-tap-highlight-color: transparent;
	text-shadow: none;
	backdrop-filter: blur(4px);
}

.summer-storms-tilt-chip:hover,
.summer-storms-tilt-chip:focus-visible {
	background: var(--ss-rain, #fff);
	color: var(--ss-bg, #000);
	outline: none;
}

/* ---------- Pause / resume button ---------- */

/* rain.js appends this when the "Show pause button" option is on. Sits in
   the opposite corner from the iOS tilt pill so the two never overlap.
   Circular, icon-only -- the icon class comes from the plugin option, so
   any Font Awesome (or compatible) class list works. */
.summer-storms-pause-btn {
	position: fixed;
	left: 16px;
	bottom: 16px;
	z-index: 9999;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	padding: 0;
	color: var(--ss-rain, #fff);
	background: rgba(0, 0, 0, 0.7);
	border: 2px solid var(--ss-rain, #fff);
	border-radius: 50%;
	font-size: 16px;
	cursor: pointer;
	-webkit-tap-highlight-color: transparent;
	text-shadow: none;
	backdrop-filter: blur(4px);
	/* Rest at half opacity so the button is unobtrusive when ignored, and
	   ramps to full on hover/focus when the user actually intends to act.
	   Touch devices have no hover state, so we also bump opacity when the
	   button is actively pressed so a tap still gives feedback. */
	opacity: 0.5;
	transition: opacity 150ms ease, background-color 120ms ease, color 120ms ease;
}

.summer-storms-pause-btn:hover,
.summer-storms-pause-btn:focus-visible,
.summer-storms-pause-btn:active {
	background: var(--ss-rain, #fff);
	color: var(--ss-bg, #000);
	opacity: 1;
	outline: none;
}

/* No raw text-shadow halo on the icon -- the icon font handles its own
   weight, and the halo we apply elsewhere would muddy the glyph. */
.summer-storms-pause-btn i {
	text-shadow: none;
	line-height: 1;
}

/* ---------- Respect motion preferences ---------- */

@media (prefers-reduced-motion: reduce) {
	.summer-storms-rain-layer {
		display: none;
	}
	/* No rain = no use for the tilt chip or pause button either. */
	.summer-storms-tilt-chip,
	.summer-storms-pause-btn {
		display: none;
	}
}

/* ---------- Minimal persistent navigation ----------
 * The chosen FSE Navigation menu (Settings → Summer Storms → Navigation) is
 * rendered by the core Navigation block, which outputs:
 *   <nav class="wp-block-navigation summer-storms-nav summer-storms-nav--…">
 *     <ul class="wp-block-navigation__container"><li><a>…</a></li> … </ul>
 *   </nav>
 * We pin and flatten it into a fixed, minimal text-link row that sits above the
 * rain (z 0) and content (z 1) but below the rain control chips (z 9999). Links
 * carry the same background-colour halo as body copy so they stay readable
 * where the rain (or scrolling content) passes behind them.
 */
.summer-storms-nav {
	position: fixed;
	z-index: 50;
	margin: 0;
	padding: clamp(1rem, 3vw, 1.75rem) clamp(1.1rem, 4vw, 2.25rem);
	background: transparent;
	font-family: 'Roobert', system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
	font-size: clamp(0.85rem, 0.8rem + 0.2vw, 1rem);
	letter-spacing: 0.01em;
	max-width: 100%;
	box-sizing: border-box;
}

/* Flatten the block's container into a simple inline row with our spacing. */
.summer-storms-nav .wp-block-navigation__container,
.summer-storms-nav ul {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: clamp(0.9rem, 2.5vw, 1.75rem);
	margin: 0;
	padding: 0;
	list-style: none;
}

.summer-storms-nav li,
.summer-storms-nav .wp-block-navigation-item {
	margin: 0;
	padding: 0;
}

/* overlayMenu:"never" should keep the links inline, but hide any responsive
   toggle/overlay the block might still emit, just in case. */
.summer-storms-nav .wp-block-navigation__responsive-container-open,
.summer-storms-nav .wp-block-navigation__responsive-container-close {
	display: none !important;
}

.summer-storms-nav a,
.summer-storms-nav .wp-block-navigation-item__content {
	color: #fff;
	text-decoration: none;
	padding: 0;
	opacity: 0.82;
	transition: opacity 120ms ease;
	text-shadow:
		-1px -1px 0 var(--ss-bg, #000),
		 1px -1px 0 var(--ss-bg, #000),
		-1px  1px 0 var(--ss-bg, #000),
		 1px  1px 0 var(--ss-bg, #000),
		 0   -1px 0 var(--ss-bg, #000),
		 0    1px 0 var(--ss-bg, #000),
		-1px  0   0 var(--ss-bg, #000),
		 1px  0   0 var(--ss-bg, #000);
}

.summer-storms-nav a:hover,
.summer-storms-nav a:focus-visible,
.summer-storms-nav .wp-block-navigation-item__content:hover,
.summer-storms-nav .wp-block-navigation-item__content:focus-visible {
	opacity: 1;
	text-decoration: underline;
	text-underline-offset: 3px;
}

.summer-storms-nav--top-left      { top: 0; left: 0; }
.summer-storms-nav--top-right     { top: 0; right: 0; }
.summer-storms-nav--top-center    { top: 0; left: 50%; transform: translateX(-50%); }
.summer-storms-nav--bottom-center { bottom: 0; left: 50%; transform: translateX(-50%); }

/* ---------- Forms on the dark stage ----------
 * Inputs don't carry an inline colour/background, so normal specificity styles
 * them. We keep whatever corner radius the block ships (the Jetpack subscribe
 * form is square) and just make the field read as designed-for-dark.
 */
.summer-storms-blocks input[type="email"],
.summer-storms-blocks input[type="text"],
.summer-storms-blocks input[type="url"],
.summer-storms-blocks input[type="search"],
.summer-storms-blocks input[type="number"],
.summer-storms-blocks textarea {
	background: transparent;
	color: #fff;
	border: 1px solid rgba(255, 255, 255, 0.55);
}

.summer-storms-blocks input::placeholder,
.summer-storms-blocks textarea::placeholder {
	color: rgba(255, 255, 255, 0.55);
	opacity: 1;
}

.summer-storms-blocks input:focus,
.summer-storms-blocks textarea:focus {
	outline: none;
	border-color: #fff;
	box-shadow: 0 0 0 1px #fff;
}

/* The Jetpack subscribe button is a button too, so we deliberately do NOT style
   it here -- its colours/border come from the block editor, never the plugin's
   white outline. Its text halo is already removed by the .wp-element-button rule
   above. The dark-stage field styling above only targets the email input. */

/* ---------- "Secondary" colour remap for legibility ----------
 * Many themes' "secondary" preset is a mid-tone tuned for a LIGHT background
 * (e.g. #787670), which drops to ~3:1 on the dark stage -- under AA. Remap the
 * preset locally to a muted white so "secondary"-coloured copy (footers,
 * credits) reads as de-emphasised but stays legible. Scoped to the stage; the
 * rest of the site keeps the theme's value.
 */
.summer-storms-content {
	--wp--preset--color--secondary: rgba(255, 255, 255, 0.62);
}

/* ---------- Entrance + caret motion ----------
 * Only for visitors who haven't requested reduced motion. A single gentle
 * fade-up reveals the logo, then tagline, then content; the nav fades in
 * (opacity only, so centred positions keep their translateX); the caret bobs
 * to signal "scroll". scroll-behavior is smoothed so a caret linked to an
 * in-page anchor (href="#projects") glides instead of jumping.
 */
@media (prefers-reduced-motion: no-preference) {
	html {
		scroll-behavior: smooth;
	}

	@keyframes summer-storms-rise {
		from { opacity: 0; transform: translateY(14px); }
		to   { opacity: 1; transform: translateY(0); }
	}
	@keyframes summer-storms-fade {
		from { opacity: 0; }
		to   { opacity: 1; }
	}

	.summer-storms-logo,
	.summer-storms-tagline,
	.summer-storms-blocks {
		animation: summer-storms-rise 700ms cubic-bezier(0.16, 1, 0.3, 1) both;
	}
	.summer-storms-logo    { animation-delay: 80ms; }
	.summer-storms-tagline { animation-delay: 220ms; }
	.summer-storms-blocks  { animation-delay: 360ms; }

	/* Opacity-only so the centred nav variants keep their translateX(-50%). */
	.summer-storms-nav {
		animation: summer-storms-fade 700ms ease 500ms both;
	}

	@keyframes summer-storms-bob {
		0%, 100% { transform: translateY(0); }
		50%      { transform: translateY(6px); }
	}
	/* The caret-down icon (a Font Awesome glyph) bobs to invite scrolling.
	   Wrap it in a link to #your-section to make it click-to-scroll. */
	.summer-storms-blocks .fa-caret-down {
		animation: summer-storms-bob 1.8s ease-in-out infinite;
	}
}
