/*
Theme Name: Serzo
Theme URI: https://www.serzomusic.com
Author: Elemental Web
Author URI: https://www.eleweb.no
Description: Block theme for serzomusic.com: the site's tokens, logo, header/footer, templates and patterns. Shared functionality comes from the plugin elemental-core.
Requires at least: 6.6
Requires PHP: 8.1
Version: 0.2.13
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: serzo
*/

/* Design direction: decision 0004 "the cut" (docs/decisions/0004-design-direction.md). A light
   site on the paper of the 2025 shoot, in the logo's brown, and one signature: the logo's 45° cut
   on section edges, covers and buttons. Tokens live in theme.json; this file holds the layout
   classes and what theme.json can't express. Spacing comes from the layout classes, never per
   block. Vocabulary: the Elemental Web design system (font roles display/body, spacing 20–80,
   custom line-height/letter-spacing/gutter/box/control tokens), and only these breakpoints,
   always as max-width (width − 1px):
     xs  360px   small phones                            @media (max-width: 360px)
     sm  600px   phone / tablet                          @media (max-width: 599px)
     md  782px   WordPress stacks columns below this     @media (max-width: 781px)
     lg  1024px  tablet / desktop                        @media (max-width: 1023px)
     xl  1280px  fluid type and spacing stop growing (theme.json typography.fluid) */

/* Fallback face with Saira's metrics (Arial resized), so text keeps its size and line breaks
   while Saira loads. From the theme's own woff2 (fontTools): units per em 1000, ascent 1135,
   descent 439, line gap 0; average lowercase width about 5% wider than Arial's. Recompute if the
   font changes. */
@font-face {
	font-family: "Saira Fallback";
	src: local("Arial"), local("ArialMT");
	ascent-override: 108.1%;
	descent-override: 41.8%;
	line-gap-override: 0%;
	size-adjust: 105%;
}

/* Boxes inside columns and query loops are padded by the width of that column, not the screen:
   --wp--custom--box--padding uses cqi. Outside a container cqi measures the viewport. */
.wp-block-column,
.wp-block-post-template > li {
	container-type: inline-size;
}

/* Header, main and footer sit flush (also in the site editor): sections bring their own spacing. */
.wp-site-blocks > *,
.editor-styles-wrapper .is-root-container > *,
main.wp-block-group > .alignfull {
	margin-block-start: 0;
}

/* ---------------------------------------------------------------------------------------
   Type: Saira in two roles. Display is ExtraBold Italic, a little wide, sentence case: it
   slants like the logo. No all-caps labels, no tracked-out small text (decision 0004).
   --------------------------------------------------------------------------------------- */

h1,
h2,
h3,
h4,
.wp-block-post-title,
.serzo-display {
	font-stretch: var(--wp--custom--display--stretch);
	text-wrap: balance;
}

.serzo-display {
	font-family: var(--wp--preset--font-family--display);
	font-style: var(--wp--custom--display--style);
	font-weight: var(--wp--custom--display--weight);
	line-height: var(--wp--custom--line-height--tight);
	color: var(--wp--preset--color--heading);
}

::selection {
	background: var(--wp--preset--color--gel);
	color: var(--wp--preset--color--heading);
}

/* Buttons carry the cut: the bottom-right corner sliced at 45°. The outline style is a text link
   with an underline (one filled button per section). */
.wp-element-button,
.wp-block-button__link {
	clip-path: polygon(0 0, 100% 0, 100% calc(100% - var(--wp--custom--cut--button)), calc(100% - var(--wp--custom--cut--button)) 100%, 0 100%);
}

.wp-block-button.is-style-outline > .wp-block-button__link {
	clip-path: none;
	padding-inline: 0;
	border: 0;
	background: none;
	color: var(--wp--preset--color--heading);
	text-decoration: underline;
	text-underline-offset: 5px;
	text-decoration-thickness: 2px;
}

.wp-block-button.is-style-outline > .wp-block-button__link:hover {
	color: var(--wp--preset--color--accent);
}

p,
li {
	text-wrap: pretty;
}

/* Buttons are clipped (the cut), so their focus ring sits inside them. */
.wp-element-button:focus-visible,
.wp-block-button__link:focus-visible {
	outline: 2px solid var(--wp--preset--color--on-accent) !important;
	outline-offset: -5px !important;
}

/* Visible keyboard focus everywhere. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: 3px;
}

/* For a heading that's there for screen readers and search engines, not for the eye. */
.serzo-sr-only {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* ---------------------------------------------------------------------------------------
   Layout system. Templates and patterns use these classes instead of per-block padding.
   `.wp-block-group.` / `.wp-block-cover.` raise specificity above WordPress's layout rules.
   --------------------------------------------------------------------------------------- */

/* Full-width content section: spacing-80 top and bottom (fluid), gutter at the sides. */
.wp-block-group.serzo-section {
	padding: var(--wp--preset--spacing--80) var(--wp--custom--gutter);
}

/* Two sections in a row read as one rhythm: the second doesn't add its own top spacing, unless
   it has its own background. */
.wp-block-group.serzo-section + .wp-block-group.serzo-section:not(.has-background) {
	padding-top: 0;
}

/* Hero (a Cover block): the image full bleed under a gradient, the text bottom left in the
   inner container, lined up with the wide size. `__inner` does the same for a hero built from a
   Group. */
.wp-block-cover.serzo-hero {
	min-height: min(70vh, 680px);
	padding: var(--wp--preset--spacing--80) var(--wp--custom--gutter) var(--wp--preset--spacing--60);
	align-items: flex-end;
}

.wp-block-cover.serzo-hero .wp-block-cover__inner-container,
.serzo-hero__inner {
	width: 100%;
	max-width: var(--wp--style--global--wide-size);
	margin-inline: auto;
}

.wp-block-cover.serzo-hero .wp-block-cover__inner-container > *,
.serzo-hero__inner > * {
	max-width: 720px;
}

/* Phones: a hero is as tall as its text plus some image. */
@media (max-width: 599px) {
	.wp-block-cover.serzo-hero {
		min-height: 0;
		padding-top: 160px;
		padding-bottom: var(--wp--preset--spacing--50);
	}
}

.wp-block-cover.serzo-hero + .wp-block-group.serzo-section {
	padding-top: var(--wp--preset--spacing--70);
}

/* Plain pages (page.html, index, 404, the policies). */
.wp-block-group.serzo-page {
	padding: var(--wp--preset--spacing--70) var(--wp--custom--gutter) var(--wp--preset--spacing--80);
}

/* Running text on plain pages (the policies): headings at reading size, not section size. */
.serzo-page .wp-block-post-content h2 {
	font-size: var(--wp--preset--font-size--x-large);
	margin-block-start: var(--wp--preset--spacing--60);
}

.serzo-page .wp-block-post-content h3 {
	font-size: var(--wp--preset--font-size--large);
}

/* A section's heading row sits above its content. */
.serzo-section__head {
	margin-bottom: var(--wp--preset--spacing--50);
}

/* Image edges: no image sits on the page as a bare rectangle. Every image uses one of
   - the sleeve cut (covers: `.serzo-sleeve`, the corner sliced at 45° inside a 1px line),
   - the edge line (cards and tiles: `.serzo-edge`),
   - the fade into the page (photos on the page ground: `.serzo-fade`),
   - full bleed under a gradient (the dark band: `.serzo-band`, a Cover block under the
     `band` gradient), or
   - the white paper of the 2025 shoot fading into the hero's white (`.serzo-hero__photo`).
   Logos and icons are cut-outs and need none. Keep this list in step with the site's own edges. */

/* Edge line, drawn as a layer over the image (an inset shadow on the image itself is hidden by
   the image). The shadow is the theme.json preset `edge`. */
.serzo-edge {
	position: relative;
}

.serzo-edge::after {
	content: "";
	position: absolute;
	inset: 0;
	box-shadow: var(--wp--preset--shadow--edge);
	pointer-events: none;
}

/* A photo on the page ground fades into it at every edge (two linear fades, intersected). */
.serzo-fade img {
	-webkit-mask-image: linear-gradient(to right, transparent, #000 12%, #000 88%, transparent), linear-gradient(to bottom, transparent, #000 10%, #000 80%, transparent);
	-webkit-mask-composite: source-in;
	mask-image: linear-gradient(to right, transparent, #000 12%, #000 88%, transparent), linear-gradient(to bottom, transparent, #000 10%, #000 80%, transparent);
	mask-composite: intersect;
}

/* Sleeve cut: a cover's bottom-right corner sliced at 45°, inside a 1px line drawn by the
   figure behind it (decision 0004: the edge for covers). */
.serzo-sleeve {
	--serzo-sleeve: polygon(0 0, 100% 0, 100% calc(100% - var(--wp--custom--cut--cover)), calc(100% - var(--wp--custom--cut--cover)) 100%, 0 100%);
	padding: 1px;
	background: var(--wp--preset--color--line);
	clip-path: var(--serzo-sleeve);
}

.serzo-sleeve img {
	display: block;
	clip-path: var(--serzo-sleeve);
}

/* ---------------------------------------------------------------------------------------
   The cut: sections end in a 45° slice at the angle of the logo's gaps (decision 0004).
   --------------------------------------------------------------------------------------- */

/* Bottom-right corner cut off. */
.serzo-cut-end {
	clip-path: polygon(0 0, 100% 0, 100% calc(100% - var(--wp--custom--cut--size)), calc(100% - var(--wp--custom--cut--size)) 100%, 0 100%);
}

/* Top-left and bottom-right corners cut off (the dark band). */
.serzo-cut-both {
	clip-path: polygon(0 var(--wp--custom--cut--size), var(--wp--custom--cut--size) 0, 100% 0, 100% calc(100% - var(--wp--custom--cut--size)), calc(100% - var(--wp--custom--cut--size)) 100%, 0 100%);
}

/* ---------------------------------------------------------------------------------------
   Home hero: the portrait on its white paper, gel light behind the text, the cut at the
   bottom. The site's one motion: the cut slices in once on load (600ms); still under
   reduced motion.
   --------------------------------------------------------------------------------------- */

.wp-block-group.serzo-hero--home {
	position: relative;
	display: grid;
	min-height: min(86vh, 820px);
	padding: var(--wp--preset--spacing--70) var(--wp--custom--gutter) calc(var(--wp--custom--cut--size) + var(--wp--preset--spacing--60));
	overflow: hidden;
	background: var(--wp--preset--gradient--gel-light), var(--wp--preset--color--surface);
	animation: serzo-slice 600ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}

@keyframes serzo-slice {
	from {
		clip-path: polygon(0 0, 100% 0, 100% 100%, 100% 100%, 0 100%);
	}
}

/* The portrait: right side, fading from its white paper into the hero's white (its edge). */
.serzo-hero--home .serzo-hero__photo {
	position: absolute;
	inset: 0 0 0 auto;
	width: min(62%, 900px);
	height: 100%;
	margin: 0;
}

.serzo-hero--home .serzo-hero__photo img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: 30% 20%;
	-webkit-mask-image: linear-gradient(to right, transparent, #000 38%), linear-gradient(to top, transparent, #000 30%);
	-webkit-mask-composite: source-in;
	mask-image: linear-gradient(to right, transparent, #000 38%), linear-gradient(to top, transparent, #000 30%);
	mask-composite: intersect;
	mix-blend-mode: multiply;
}

.serzo-hero--home .serzo-hero__inner {
	position: relative;
	z-index: 1;
	align-self: center;
	width: 100%;
	max-width: var(--wp--style--global--wide-size);
	margin-inline: auto;
}

.serzo-hero--home .serzo-hero__inner > * {
	max-width: 620px;
}

.serzo-hero--home .wp-block-post-title {
	margin: 0;
	font-size: var(--wp--preset--font-size--display);
}

@media (max-width: 781px) {
	.wp-block-group.serzo-hero--home {
		min-height: 600px;
		align-content: end;
	}

	.serzo-hero--home .serzo-hero__photo {
		width: 100%;
		height: 62%;
	}

	.serzo-hero--home .serzo-hero__photo img {
		object-position: 60% 15%;
		-webkit-mask-image: linear-gradient(to bottom, #000 55%, transparent);
		mask-image: linear-gradient(to bottom, #000 55%, transparent);
	}

	.serzo-hero--home .serzo-hero__inner {
		align-self: end;
	}
}

@media (prefers-reduced-motion: reduce) {
	.wp-block-group.serzo-hero--home {
		animation: none;
	}
}

/* Page hero (Tour dates, Booking): title and a line on the white paper, cut at the bottom. */
.wp-block-group.serzo-hero--page {
	padding: var(--wp--preset--spacing--80) var(--wp--custom--gutter) calc(var(--wp--custom--cut--size) + var(--wp--preset--spacing--50));
	background: var(--wp--preset--gradient--gel-light), var(--wp--preset--color--surface);
}

.serzo-hero--page h1 {
	font-size: var(--wp--preset--font-size--display);
}

/* ---------------------------------------------------------------------------------------
   Releases: covers on the paper, newest first. 6 per row (4 on /music/), 3 on tablets,
   2 on phones.
   --------------------------------------------------------------------------------------- */

.serzo-releases .wp-block-post-template {
	display: grid;
	grid-template-columns: repeat(6, minmax(0, 1fr));
	gap: var(--wp--preset--spacing--50) clamp(16px, 2vw, 28px);
	margin: 0;
	padding: 0;
	list-style: none;
}

.serzo-releases--archive .wp-block-post-template {
	grid-template-columns: repeat(4, minmax(0, 1fr));
}

/* The grid's gap does the spacing: the flow layout's margin between items would push every card
   after the first down in its row. */
.serzo-releases .wp-block-post-template > li {
	margin-block: 0;
}

.serzo-release {
	display: flex;
	flex-direction: column;
	gap: 4px;
}

.serzo-release .wp-block-post-featured-image {
	margin: 0 0 var(--wp--preset--spacing--20);
	transition: transform 160ms ease;
}

/* The only hover effect on the site: a cover lifts 4px. */
.serzo-release:hover .wp-block-post-featured-image,
.serzo-release:focus-within .wp-block-post-featured-image {
	transform: translateY(-4px);
}

.serzo-release .wp-block-post-title {
	margin: 0;
	font-size: var(--wp--preset--font-size--large);
	line-height: var(--wp--custom--line-height--snug);
}

.serzo-release__meta {
	display: flex;
	flex-wrap: wrap;
	gap: 0 0.5em;
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.4;
}

.serzo-release__meta > * {
	margin: 0;
}

@media (max-width: 1023px) {
	.serzo-releases .wp-block-post-template,
	.serzo-releases--archive .wp-block-post-template {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

@media (max-width: 599px) {
	.serzo-releases .wp-block-post-template,
	.serzo-releases--archive .wp-block-post-template {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (prefers-reduced-motion: reduce) {
	.serzo-release .wp-block-post-featured-image {
		transition: none;
	}
}

/* Release page: cover left, title and details right. */
.serzo-release-page .wp-block-post-title {
	margin: 0;
	font-size: var(--wp--preset--font-size--display);
}

/* ---------------------------------------------------------------------------------------
   The dark band (tour dates, booking): logo brown over the live photo, cut top-left and
   bottom-right. The page reads light, dark, light.
   --------------------------------------------------------------------------------------- */

.wp-block-cover.serzo-band {
	min-height: 0;
	padding: calc(var(--wp--custom--cut--size) + var(--wp--preset--spacing--60)) var(--wp--custom--gutter);
	color: var(--wp--preset--color--background);
}

.serzo-band .wp-block-cover__inner-container {
	width: 100%;
	max-width: var(--wp--style--global--wide-size);
	margin-inline: auto;
}

.serzo-band .wp-block-cover__inner-container > * {
	max-width: 900px;
}

.serzo-band :is(h1, h2, h3) {
	color: var(--wp--preset--color--background);
}

.serzo-band a:not(.wp-element-button) {
	color: var(--wp--preset--color--background);
}

/* Straight after a page hero, the band keeps a gap of paper between the two cuts. */
.serzo-hero + .wp-block-cover.serzo-band {
	margin-top: var(--wp--preset--spacing--60);
}

/* Bandsintown inside the band: dates in gel orange display type, rows on hairlines, the
   tickets button like the site's button. The widget's stylesheet uses `.bit-widget .bit-…`
   with !important and loads later, so these selectors carry one class more. */
.serzo-schedule {
	min-height: 200px;
}

/* Before consent the widget's script waits, and its link to Bandsintown shows instead. */
.serzo-schedule > .bit-widget-initializer {
	color: var(--wp--preset--color--background);
	font-size: var(--wp--preset--font-size--lead);
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

.serzo-schedule .bit-widget {
	font-family: var(--wp--preset--font-family--body) !important;
}

/* The widget centres everything; the band is left aligned. */
.serzo-schedule .bit-widget,
.serzo-schedule .bit-widget * {
	text-align: left !important;
}

/* No dates: just the sentence, in the band's lead size. Bandsintown's own "Play my city" button
   is hidden, so "Book Serzo" stays the band's one action. */
.serzo-schedule .bit-widget .bit-play-my-city-wrapper {
	align-items: flex-start !important;
	padding: 0 !important;
}

.serzo-schedule .bit-widget .bit-play-my-city-heading-text {
	font-size: var(--wp--preset--font-size--lead) !important;
	color: var(--wp--preset--color--background) !important;
}

.serzo-schedule .bit-widget .bit-play-my-city-wrapper .bit-play-my-city-cta {
	display: none !important;
}

.serzo-schedule .bit-widget .bit-date {
	color: var(--wp--preset--color--gel) !important;
	font-family: var(--wp--preset--font-family--display) !important;
	font-style: var(--wp--custom--display--style) !important;
	font-weight: 800 !important;
	font-stretch: var(--wp--custom--display--stretch);
	font-size: var(--wp--preset--font-size--x-large) !important;
}

.serzo-schedule .bit-widget .bit-button {
	display: inline-block !important;
	padding: var(--wp--custom--control--padding-block) var(--wp--custom--control--padding-inline) !important;
	border: 0 !important;
	border-radius: 0 !important;
	background: var(--wp--preset--color--accent) !important;
	color: var(--wp--preset--color--on-accent) !important;
	font-family: var(--wp--preset--font-family--body) !important;
	font-size: var(--wp--preset--font-size--caption) !important;
	font-weight: 600 !important;
	text-transform: lowercase !important;
	text-decoration: none !important;
	clip-path: polygon(0 0, 100% 0, 100% calc(100% - var(--wp--custom--cut--button)), calc(100% - var(--wp--custom--cut--button)) 100%, 0 100%);
}

.serzo-schedule .bit-widget .bit-button::first-letter {
	text-transform: uppercase;
}

.serzo-schedule .bit-widget .bit-button:hover {
	background: var(--wp--preset--color--accent-hover) !important;
}

/* On stage (Booking, decision 0005): three live photos with the sleeve cut, event and year
   under each. 3 in a row, 1 on phones. */
.serzo-on-stage__grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: var(--wp--preset--spacing--50) clamp(16px, 2vw, 28px);
}

.serzo-on-stage__grid > * {
	margin-block: 0;
}

.serzo-on-stage__show {
	display: flex;
	flex-direction: column;
	gap: 4px;
}

.serzo-on-stage__show .wp-block-image {
	margin: 0 0 var(--wp--preset--spacing--20);
}

.serzo-on-stage__show .wp-block-image img {
	width: 100%;
}

.serzo-on-stage__show h3 {
	margin: 0;
	font-size: var(--wp--preset--font-size--large);
	line-height: var(--wp--custom--line-height--snug);
}

.serzo-on-stage__show p {
	margin: 0;
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--small);
}

@media (max-width: 599px) {
	.serzo-on-stage__grid {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* About: a photo beside a few lines (front page, booking). The photo stands on the page's
   paper and fades into it at the bottom and sides (its edge). */
.serzo-about .serzo-fade img {
	width: 100%;
	height: auto;
}

/* ---------------------------------------------------------------------------------------
   Header and navigation
   --------------------------------------------------------------------------------------- */

.serzo-header {
	position: relative;
	z-index: 10;
}

.serzo-logo img {
	display: block;
	width: 120px;
	height: auto;
}

.serzo-header .wp-block-navigation-item__content {
	padding-block: 12px;
}

/* The phone menu buttons get a 44px tap target. */
.wp-block-navigation__responsive-container-open,
.wp-block-navigation__responsive-container-close {
	box-sizing: content-box;
	padding: 10px;
}

.wp-block-navigation__responsive-container.is-menu-open {
	padding: 24px var(--wp--custom--gutter);
}

/* ---------------------------------------------------------------------------------------
   Footer: a brand column and two link columns; two columns on tablets, one on phones.
   --------------------------------------------------------------------------------------- */

.wp-block-group.serzo-footer {
	padding: var(--wp--preset--spacing--70) var(--wp--custom--gutter) var(--wp--preset--spacing--50);
	border-top: 1px solid var(--wp--preset--color--line);
}

.serzo-footer-grid {
	display: grid;
	grid-template-columns: minmax(0, 1.4fr) repeat(2, minmax(0, 1fr));
	gap: var(--wp--preset--spacing--50);
}

.serzo-footer-grid > * {
	margin-block: 0;
}

.serzo-footer__heading {
	margin: 0;
	font-size: var(--wp--preset--font-size--caption);
	font-weight: 600;
	color: var(--wp--preset--color--heading);
}

.serzo-footer a {
	display: inline-block;
	padding-block: 4px;
	text-decoration: none;
}

.serzo-footer a:hover,
.serzo-footer a:focus-visible {
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* Privacy and cookie policy: side by side, small and muted. */
.serzo-footer__legal {
	display: flex;
	flex-wrap: wrap;
	gap: 0 var(--wp--preset--spacing--30);
}

.serzo-footer .serzo-footer__legal a {
	color: var(--wp--preset--color--muted);
}

@media (max-width: 1023px) {
	.serzo-footer-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.serzo-footer-grid > .serzo-footer__brand {
		grid-column: 1 / -1;
	}
}

@media (max-width: 599px) {
	.serzo-footer-grid {
		grid-template-columns: minmax(0, 1fr);
	}
}
