/*
Theme Name: JouleWave
Theme URI: https://joulewave.com/
Description: Minimal Kadence child theme for JouleWave. Design tokens live in the Kadence Global Palette and theme.json; this stylesheet carries the waveform signature, a small set of reusable block styles, and the overrides Kadence's own CSS makes unavoidable.
Author: JouleWave
Template: kadence
Version: 1.1.5
Update URI: https://github.com/tclekovic/joule-wave
Requires at least: 6.6
Tested up to: 6.8
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: joulewave
*/

/* `Update URI:` is hijack protection, not plumbing — it stops wordpress.org
   answering for the slug `joulewave`. Feed and rationale: setup/updates.php. */

/* ---------------------------------------------------------------------------
   1. Token bridge
   Core presets resolve to the Kadence Global Palette, so the palette stays the
   single source of truth. The hex fallbacks only apply if Kadence is inactive.
   `html:root` beats the `:root` that global styles emits, whatever the order.
   --------------------------------------------------------------------------- */
html:root {
	--wp--preset--color--jw-accent: var(--global-palette1, #b4530a);
	--wp--preset--color--jw-accent-2: var(--global-palette2, #f5a623);
	--wp--preset--color--jw-ink: var(--global-palette3, #171b20);
	--wp--preset--color--jw-ink-soft: var(--global-palette4, #3d444d);
	--wp--preset--color--jw-hairline: var(--global-palette5, #e4e6e3);
	--wp--preset--color--jw-band: var(--global-palette6, #f6f7f5);
	--wp--preset--color--jw-paper: var(--global-palette7, #fff);
	--wp--preset--color--jw-paper-dark-text: var(--global-palette8, #f1f2f0);
	--wp--preset--color--jw-muted: var(--global-palette9, #8b9088);
}

/* ---------------------------------------------------------------------------
   2. Type polish
   Only the sizes used on paragraphs are here. The heading scale's line-height
   and tracking come from the Kadence typography settings that provision.php
   writes, so repeating them per preset class would be a second source of truth.
   --------------------------------------------------------------------------- */
.has-heading-s-font-size,
.has-heading-xs-font-size { line-height: 1.3; }
.has-body-l-font-size { line-height: 1.6; }
.has-body-s-font-size { line-height: 1.55; }
.has-mono-label-font-size { line-height: 1.5; }

/* About-teaser pull quote: display face at a heading weight, not body weight. */
.jw-pullquote { font-weight: 500; line-height: 1.35; letter-spacing: -0.01em; }

/* ---------------------------------------------------------------------------
   3. Section shell
   The design is a 1200px box with 24px side padding, i.e. a 1152px column.
   Growing the padding past the gutter on wide screens makes the group's content
   box *be* that column, so full-width children and left-aligned ones share the
   same left edge. Sections stack flush — the band backgrounds are the seam.

   The extra selectors only exist to outrank Kadence, which paints every
   `.entry-content .wp-block-group.has-background` with `padding: 20px 30px` and
   gives `.single-content` children a `--global-md-spacing` bottom margin.
   --------------------------------------------------------------------------- */
.jw-section,
.wp-block-group.jw-section,
.entry-content .wp-block-group.jw-section {
	padding-inline: max(var(--wp--preset--spacing--gutter), calc((100% - 1152px) / 2));
	margin-block: 0;
}

/* Sections and the stacks inside them are vertical flex (see jw_section() in
   tools/render.php), so every gap is a real `gap` that Kadence's element margin
   rules cannot reach. Core defaults vertical flex to `align-items: flex-start`,
   which shrink-wraps each child; the design wants them to fill the column. */
.jw-section.is-layout-flex.is-vertical,
.jw-section .is-layout-flex.is-vertical { align-items: stretch; }

/* With `gap` doing the spacing, Kadence's element margins are pure noise. */
.jw-section :is(p, ul, ol, figure, h1, h2, h3, h4, h5, h6),
.jw-section :is(.wp-block-columns, .wp-block-buttons) { margin-block: 0; }

/* Nothing in a section outgrows the column; the waveform re-opens this below. */
.jw-section > * { max-width: 100%; }

/* Text measures. Flex items honour max-width and stay at the start edge, so
   these need no margin juggling. `min(…, 100%)` is what stops a ch-based
   measure outgrowing a narrow viewport — 60ch of 19px text is wider than a
   phone. Core zeroes flex-child margins, so centring needs a heavier selector. */
.jw-measure { max-width: min(68ch, 100%); }
.jw-measure-sub { max-width: min(60ch, 100%); }
.jw-measure-h1 { max-width: min(14ch, 100%); }
.jw-measure-title { max-width: min(21ch, 100%); }
.jw-measure-center { max-width: min(56ch, 100%); }
.jw-measure-blurb { max-width: min(40ch, 100%); }
.jw-section > .jw-measure-center { margin-inline: auto; }

/* ---------------------------------------------------------------------------
   4. Reusable block styles (registered in functions.php, pickable in the editor)
   --------------------------------------------------------------------------- */
.is-style-jw-eyebrow {
	font-family: var(--wp--preset--font-family--jw-mono);
	font-size: var(--wp--preset--font-size--mono-label);
	font-weight: 500;
	letter-spacing: 0.08em;
	line-height: 1.4;
	text-transform: uppercase;
}

.is-style-jw-card {
	display: flex;
	flex-direction: column;
	border: 1px solid var(--wp--preset--color--jw-hairline);
	transition: border-color 0.2s ease, transform 0.2s ease;
}
.is-style-jw-card:hover { border-color: var(--wp--preset--color--jw-ink); transform: translateY(-2px); }

/* Keeps the pillar sub-item lists on a common baseline across the three cards
   however long the intros run. Heavier than core's flex-child margin reset. */
.is-style-jw-card > .jw-card-foot { margin-block-start: auto; }

.is-style-jw-rule-top { border-top: 2px solid var(--wp--preset--color--jw-ink); }
.is-style-jw-hairline-top { border-top: 1px solid var(--wp--preset--color--jw-hairline); }

.is-style-jw-pill {
	display: inline-block;
	padding: 5px 12px;
	border-radius: 999px;
	background: var(--wp--preset--color--jw-accent-2);
	color: var(--wp--preset--color--jw-ink);
	font-family: var(--wp--preset--font-family--jw-mono);
	font-size: 0.6875rem;
	font-weight: 500;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.wp-block-button.is-style-jw-secondary .wp-block-button__link {
	background: transparent;
	color: var(--wp--preset--color--jw-ink);
	border: 1px solid var(--wp--preset--color--jw-ink);
}
.wp-block-button.is-style-jw-secondary .wp-block-button__link:hover { background: var(--wp--preset--color--jw-band); }

/* Industries cards share 1px rules — a 1px block gap over a hairline ground.
   The grid is two rows, so the wrapper's own 1px gap draws the horizontal rule
   and each row's 1px gap draws the vertical ones; only the cards paint paper. */
.jw-grid-hairline {
	background: var(--wp--preset--color--jw-hairline);
	border: 1px solid var(--wp--preset--color--jw-hairline);
}
.jw-grid-hairline .wp-block-column { background: var(--wp--preset--color--jw-paper); }

/* ---------------------------------------------------------------------------
   5. Waveform signature — the only custom element in the design
   --------------------------------------------------------------------------- */
.jw-wave { display: block; width: 100%; height: auto; }
.jw-wave--divider { height: 40px; opacity: 0.9; }

.jw-wave .jw-draw {
	stroke-dasharray: 2600;
	stroke-dashoffset: 2600;
	animation: jw-draw 2.6s cubic-bezier(0.65, 0, 0.35, 1) 0.3s forwards;
}
.jw-wave .jw-blip { opacity: 0; animation: jw-blip 0.4s ease 2.9s forwards; }

@keyframes jw-draw { to { stroke-dashoffset: 0; } }
@keyframes jw-blip { to { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
	.jw-wave .jw-draw { animation: none; stroke-dashoffset: 0; }
	.jw-wave .jw-blip { animation: none; opacity: 1; }
}

/* The hero trace bleeds past the measure by exactly the gutter, lining up with
   the edges of the design's 1200px section box rather than the viewport. */
.jw-section > .jw-wave--hero {
	margin-block-start: 28px;
	margin-inline: calc(-1 * var(--wp--preset--spacing--gutter));
	width: calc(100% + 2 * var(--wp--preset--spacing--gutter));
	max-width: none;
}

/* About-teaser panel: waveform in place of photography until real images exist. */
.jw-panel {
	display: flex;
	align-items: center;
	justify-content: center;
	aspect-ratio: 4 / 3;
	overflow: hidden;
	border: 1px solid var(--wp--preset--color--jw-hairline);
	background: var(--wp--preset--color--jw-paper);
}
.jw-panel .jw-wave { flex: 0 0 100%; max-width: none; }

/* ---------------------------------------------------------------------------
   6. Dark surfaces (CTA band, footer)
   `:not()` rather than `:where()` on purpose — Kadence underlines links with
   `.inner-link-style-normal a:not(.button)`, which outranks a zero-weight
   `:where()`. Amber is reserved for the contact links; the navigate column
   inherits the footer's own text colour.
   --------------------------------------------------------------------------- */
.jw-dark a:not(.wp-element-button):not(.wp-block-button__link) {
	color: var(--wp--preset--color--jw-accent-2);
	text-decoration: none;
}
.jw-dark a:not(.wp-element-button):not(.wp-block-button__link):hover { text-decoration: underline; }
.jw-dark .jw-plain-link a:not(.wp-element-button):not(.wp-block-button__link) { color: inherit; }
.jw-dark .wp-block-button.is-style-jw-secondary .wp-block-button__link {
	color: var(--wp--preset--color--jw-paper-dark-text);
	border-color: var(--wp--preset--color--jw-paper-dark-text);
}
.jw-dark .wp-block-button.is-style-jw-secondary .wp-block-button__link:hover { background: rgba(241, 242, 240, 0.1); }
.jw-dark .is-style-jw-hairline-top { border-top-color: rgba(241, 242, 240, 0.15); }

/* ---------------------------------------------------------------------------
   7. Kadence chrome
   Kadence paints `.content-bg` / `body.content-style-unboxed .site` with
   palette9 ("Muted"), a role this repo repurposes for muted text and borders
   rather than a near-white site background — without this it surfaces as a
   visible strip wherever a full-width block does not cover its own background.
   --------------------------------------------------------------------------- */
.content-bg,
body.content-style-unboxed .site { background: var(--wp--preset--color--jw-paper); }

/* Enabling blockGap also gives the top-level site blocks a 24px gap, which
   shows up as a pale band between the last section and the footer. */
.wp-site-blocks > * { margin-block: 0; }

/* Sticky header: blur and hairline live here rather than in the Customizer
   because Kadence has no built-in backdrop-filter control. */
.site-main-header-wrap .site-header-row-container-inner {
	backdrop-filter: blur(8px);
	-webkit-backdrop-filter: blur(8px);
	border-bottom: 1px solid var(--wp--preset--color--jw-hairline);
}

/* Wordmark: the amber squiggle sits under "Wave", i.e. the last 44px of the
   title. Kadence renders the site title as one string, so it is painted as a
   background anchored to the end edge rather than wrapped around a span. */
.site-title {
	font-size: 1.375rem;
	font-weight: 600;
	letter-spacing: -0.01em;
	padding-block-end: 11px;
	background: url("assets/svg/logo-squiggle.svg") no-repeat right bottom 1px / 44px 8px;
}

/* The footer pattern renders inside Kadence's footer HTML element, which
   centres its content and adds a row inset; the pattern brings its own. */
.site-footer .footer-html .jw-section { text-align: start; }
.site-footer .site-footer-row,
.site-footer .footer-widget-area.site-info { padding: 0; }

/* Language switcher: the design's two-button EN/HR group, rendered by
   [joulewave_lang_switcher] into the header HTML element. Polylang marks the
   language being viewed with `current-lang`. */
.jw-lang-switcher {
	display: flex;
	margin: 0;
	padding: 0;
	list-style: none;
	border: 1px solid var(--wp--preset--color--jw-hairline);
	border-radius: 2px;
	overflow: hidden;
	font-family: var(--wp--preset--font-family--jw-mono);
	font-size: 0.75rem;
	font-weight: 500;
	line-height: 1;
	text-transform: uppercase;
}
.jw-lang-switcher a:not(.button) {
	display: block;
	padding: 6px 11px;
	color: var(--wp--preset--color--jw-ink-soft);
	background: var(--wp--preset--color--jw-paper);
	text-decoration: none;
}
.jw-lang-switcher .current-lang a {
	background: var(--wp--preset--color--jw-ink);
	color: var(--wp--preset--color--jw-paper);
}

/* Under 1024px Kadence replaces the desktop row — and with it the header HTML
   element — so provision.php renders the same shortcode in the drawer. Its
   ground is near-black, which would leave the *un*selected language the one
   painted paper: the fills swap, the group stops spanning the drawer, and the
   targets grow now that there is room. */
.mobile-html .jw-lang-switcher { width: fit-content; border-color: rgba(241, 242, 240, 0.25); }
.mobile-html .jw-lang-switcher a:not(.button) { padding: 10px 15px; background: none; color: var(--wp--preset--color--jw-paper-dark-text); }
.mobile-html .jw-lang-switcher .current-lang a { background: var(--wp--preset--color--jw-paper); color: var(--wp--preset--color--jw-ink); }

/* ---------------------------------------------------------------------------
   8. Focus & selection
   --------------------------------------------------------------------------- */
:focus-visible { outline: 2px solid var(--wp--preset--color--jw-accent); outline-offset: 2px; }
.jw-dark :focus-visible { outline-color: var(--wp--preset--color--jw-accent-2); }
::selection { background: var(--wp--preset--color--jw-accent-2); color: var(--wp--preset--color--jw-ink); }
