/* =====================================================================
   VULGAR — design system
   Avant-garde streetwear: black/white sections behind torn brush edges,
   serif display + condensed UI type + typewriter body, venom accent.
   ===================================================================== */

/* 1. Tokens ----------------------------------------------------------- */

:root {
	/* Palette. Original archetype accent was #fc0 yellow / sale #db0249 —
	   Vulgar swaps the accent to venom green and keeps the sale crimson. */
	--c-black: #000;
	--c-surface: #0a0a0a;
	--c-white: #fff;
	--c-accent: #3eff6b;        /* venom — on dark */
	--c-accent-ink: #0a8a34;    /* venom — on light */
	--c-sale: #db0249;
	--c-grey: #dedede;
	--c-grey-soft: #efefef;
	--c-line-dark: #1c1c1c;
	--c-ink-soft: rgba(0, 0, 0, 0.6);
	--c-paper-soft: rgba(255, 255, 255, 0.55);

	/* Page base under the static grain. Keep in sync with BASE_HEX in
	   tools/make_noise_bg.py -- the tile has this colour baked into it. */
	--c-bg: #121212;

	/* Chips that must stay black whatever section they land in. .sec-light flips
	   --c-black to the ink colour, which would turn the sale badge into a pale
	   rectangle with low-contrast venom text. Deliberately NOT re-pointed there. */
	--c-chip: #000;

	--font-display: "Playfair Display", "Saol Display", Georgia, serif;
	--font-cond: "Barlow Condensed", "Arial Narrow", Arial, sans-serif;
	--font-mono: "Courier New", Courier, monospace;

	--ls: 0.05em;
	--header-h: 150px;
	--gap: 25px;
	--torn-h: clamp(26px, 4.5vw, 54px);
}

/* 2. Base ------------------------------------------------------------- */

*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	-webkit-text-size-adjust: 100%;
	scroll-behavior: smooth;
}

body {
	margin: 0;
	padding-top: var(--header-h);
	background: var(--c-bg) url("../img/bg-noise.gif?v=4") repeat;
	color: var(--c-white);
	font-family: var(--font-mono);
	font-size: 16px;
	line-height: 1.6;
	letter-spacing: var(--ls);
	overflow-x: hidden;
}

@media (min-width: 1200px) {
	body {
		font-size: 18px;
	}
}

img {
	max-width: 100%;
	height: auto;
	display: block;
}

a {
	color: inherit;
	text-decoration: none;
}

p a,
.article-body a {
	text-decoration: underline;
	text-underline-offset: 3px;
}

h1,
h2,
h3,
h4,
h5,
h6 {
	margin: 0;
	padding: 0;
	font-family: var(--font-display);
	font-weight: 400;
	line-height: 1.1;
	letter-spacing: 0.01em;
}

::selection {
	background: var(--c-accent);
	color: var(--c-black);
}

:focus-visible {
	outline: 2px solid var(--c-accent);
	outline-offset: 2px;
}

.sec-light :focus-visible {
	outline-color: var(--c-accent-ink);
}

/* 3. Utilities -------------------------------------------------------- */

.container {
	width: min(92%, 1330px);
	margin-inline: auto;
}

.container.narrow {
	max-width: 880px;
}

.center {
	text-align: center;
}

.padding-ver-70 {
	padding-block: 70px;
}

.padding-ver-100 {
	padding-block: clamp(70px, 9vw, 110px);
}

.margin-top-50 {
	margin-top: 50px;
}

.margin-bot-25 {
	margin-bottom: 25px;
}

.margin-bot-50 {
	margin-bottom: 50px;
}

/* Sections ------------------------------------------------------------
   The site is dark throughout. The static grain lives on <body> once, so it runs
   continuously behind every section and behind the torn dividers -- nothing
   re-tiles it and nothing has to line up.

   Sections are therefore translucent rather than opaque: .sec-light lets the
   grain through at full strength, .sec-dark lays a near-black band over it that
   still reads as textured. That keeps the black/light rhythm the torn dividers
   exist to express, without breaking the grain into per-section patches.

   The ?v= on the tile is load-bearing: theme images are served with a 7-day
   cache and the filename never changes, so re-rendering the tile without
   bumping it would keep serving the old one. Bump on every make_noise_bg.py run. */

.sec-dark {
	background: rgba(0, 0, 0, 0.78);
	color: var(--c-white);
}

/* .sec-light keeps its name -- eight templates and the whole WooCommerce skin
   key off it -- but it is no longer light. Rather than restate several hundred
   rules, it re-points the colour tokens: custom properties inherit, so every
   button, border, input, product card and Woo component inside inverts from
   this one block. --c-black is the ink, --c-white is the raised surface. */
.sec-light {
	--c-black: #ededed;
	--c-white: #17171b;
	--c-grey: #2c2c2c;
	--c-grey-soft: #1b1b1b;
	--c-ink-soft: rgba(255, 255, 255, 0.62);
	--c-accent-ink: var(--c-accent);

	background: transparent;
	color: #ededed;
}

/* The grain animates, so it is motion. Anyone asking for less gets the flat base. */
@media (prefers-reduced-motion: reduce) {
	body {
		background-image: none;
	}
}

.sec-bleed {
	position: relative;
}

.mono-note {
	font-family: var(--font-mono);
	color: var(--c-ink-soft);
}

.sec-dark .mono-note {
	color: var(--c-paper-soft);
}

.screen-reader-text {
	position: absolute !important;
	width: 1px;
	height: 1px;
	margin: -1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
	border: 0;
	padding: 0;
}

.skip-link {
	left: 8px;
	top: 8px;
	z-index: 300;
	background: var(--c-black);
	color: var(--c-white);
	padding: 10px 16px;
	font-family: var(--font-cond);
	text-transform: uppercase;
}

.skip-link:focus {
	position: fixed !important;
	width: auto;
	height: auto;
	clip: auto;
}

/* 4. Buttons ---------------------------------------------------------- */

.btn,
input[type="submit"] {
	display: inline-block;
	box-sizing: border-box;
	border: 2px solid transparent;
	border-radius: 0;
	background: var(--c-black);
	color: var(--c-white);
	font-family: var(--font-cond);
	font-weight: 400;
	font-size: 18px;
	letter-spacing: var(--ls);
	text-transform: uppercase;
	line-height: 1;
	padding: 0.72em 1.5em;
	cursor: pointer;
	transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.btn:hover,
input[type="submit"]:hover {
	background: var(--c-white);
	color: var(--c-black);
	border-color: var(--c-black);
}

.btn-outline-black {
	background: transparent;
	border-color: var(--c-black);
	color: var(--c-black);
}

.btn-outline-black:hover {
	background: var(--c-black);
	color: var(--c-white);
	border-color: var(--c-black);
}

.btn-outline-white {
	background: transparent;
	border-color: var(--c-white);
	color: var(--c-white);
}

.btn-outline-white:hover {
	background: var(--c-white);
	color: var(--c-black);
	border-color: var(--c-white);
}

.btn-black-outline-white {
	background: var(--c-black);
	border-color: var(--c-white);
	color: var(--c-white);
}

.btn-black-outline-white:hover {
	background: var(--c-white);
	color: var(--c-black);
}

.btn-solid-inverse {
	background: var(--c-white);
	color: var(--c-black);
	border-color: var(--c-white);
}

.btn-solid-inverse:hover {
	background: transparent;
	color: var(--c-white);
}

.btn-accent {
	background: var(--c-accent);
	border-color: var(--c-accent);
	color: var(--c-black);
}

.btn-accent:hover {
	background: transparent;
	color: var(--c-accent);
}

/* 5. Header ----------------------------------------------------------- */

.site-header {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 100;
	height: var(--header-h);
	background: var(--c-black);
	color: var(--c-white);
}

.header-inner {
	width: min(96%, 1560px);
	margin-inline: auto;
	height: 100%;
	display: flex;
	align-items: center;
	gap: 20px;
}

.site-brand {
	margin-right: auto;
	display: flex;
	align-items: center;
}

.site-brand img {
	max-height: 138px;
	width: auto;
}

/* Brand lockup: sits dark by default, lights up while the top bar is hovered.
   Both frames are stacked and cross-fade, so the swap never flashes or reflows. */

.brand-swap {
	position: relative;
	display: inline-block;
	line-height: 0;
	transition: filter 0.35s ease;
}

.brand-swap img {
	display: block;
	transition: opacity 0.35s ease;
}

.brand-swap .swap-on {
	position: absolute;
	left: 0;
	top: 0;
	height: 100%;
	width: auto;
	opacity: 0;
}

.site-header:hover .brand-swap .swap-on {
	opacity: 1;
}

.site-header:hover .brand-swap .swap-off {
	opacity: 0;
}

.site-header:hover .brand-swap--logo {
	filter: drop-shadow(0 0 12px rgba(62, 255, 107, 0.38)) drop-shadow(0 0 32px rgba(62, 255, 107, 0.19));
}

.site-brand .brand-swap--logo {
	top: 2mm;
}

.site-brand .brand-swap--monster {
	margin-left: -6px;
	align-self: center;
	top: 5mm;
}

.site-brand .brand-swap--monster img {
	max-height: 58px;
	width: auto;
}

.site-header:hover .brand-swap--monster {
	filter: drop-shadow(0 0 8px rgba(62, 255, 107, 0.6)) drop-shadow(0 0 24px rgba(62, 255, 107, 0.34));
}

/* Comments ------------------------------------------------------------ */

.comments {
	margin-top: 10px;
}

.comments-title {
	font-family: var(--font-cond);
	text-transform: uppercase;
	letter-spacing: var(--ls);
	font-size: 19px;
	font-weight: 400;
	margin: 0 0 22px;
}

.comment-list {
	list-style: none;
	margin: 0 0 34px;
	padding: 0;
}

.comment-list ol.children {
	list-style: none;
	margin: 0;
	padding-left: 26px;
}

.comment-list li article,
.comment-list li .comment-body {
	padding: 18px 0;
	border-top: 1px solid var(--c-grey);
}

.comment-list .comment-author {
	font-family: var(--font-cond);
	text-transform: uppercase;
	letter-spacing: var(--ls);
	font-size: 14px;
}

.comment-list .comment-metadata,
.comment-list .comment-metadata a {
	font-size: 12.5px;
	color: var(--c-ink-soft);
}

.comment-form label {
	display: block;
	font-family: var(--font-cond);
	text-transform: uppercase;
	letter-spacing: var(--ls);
	font-size: 13px;
	margin-bottom: 6px;
}

.comment-form input[type="text"],
.comment-form input[type="email"],
.comment-form input[type="url"],
.comment-form textarea {
	width: 100%;
	padding: 12px 14px;
	border: 1px solid var(--c-grey);
	background: var(--c-white);
	font-family: var(--font-mono);
	font-size: 15px;
}

.comment-form textarea {
	resize: vertical;
}

/* Media hub — articles + video ---------------------------------------- */

.media-filters {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 8px 10px;
	margin: 0 0 44px;
}

.media-filter {
	font-family: var(--font-cond);
	text-transform: uppercase;
	letter-spacing: var(--ls);
	font-size: 14px;
	line-height: 1;
	padding: 11px 18px;
	border: 1px solid var(--c-grey);
	color: inherit;
	transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.media-filter:hover {
	border-color: var(--c-black);
	background: var(--c-black);
	color: var(--c-white);
}

.media-filter.is-active {
	background: var(--c-black);
	border-color: var(--c-black);
	color: var(--c-accent);
}

.media-lead {
	margin-bottom: 34px;
}

.media-grid {
	display: grid;
	gap: 34px 28px;
	grid-template-columns: repeat(3, 1fr);
}

.media-card-link {
	display: block;
	color: inherit;
}

.media-card-media {
	position: relative;
	display: block;
	overflow: hidden;
	aspect-ratio: 3 / 2;
	background: var(--c-black);
}

.media-card-media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.6s ease;
}

.media-card-link:hover .media-card-media img {
	transform: scale(1.045);
}

/* Play badge marks video without needing a label to be read. */
.media-play {
	position: absolute;
	inset: 0;
	display: grid;
	place-items: center;
	color: var(--c-white);
	transition: color 0.25s ease, transform 0.25s ease;
}

.media-play svg {
	width: 58px;
	height: 58px;
	filter: drop-shadow(0 2px 10px rgba(0, 0, 0, 0.55));
}

.media-card-link:hover .media-play {
	color: var(--c-accent);
	transform: scale(1.06);
}

.media-card-body {
	display: block;
	padding-top: 16px;
}

.media-card-kicker {
	display: block;
	font-family: var(--font-cond);
	text-transform: uppercase;
	letter-spacing: 0.12em;
	font-size: 12.5px;
	color: var(--c-accent-ink);
	margin-bottom: 7px;
}

.media-card-title {
	font-family: var(--font-display);
	font-size: 21px;
	line-height: 1.25;
	margin: 0 0 8px;
}

.media-card-link:hover .media-card-title {
	text-decoration: underline;
	text-underline-offset: 3px;
}

.media-card-meta {
	display: block;
	font-size: 13px;
	color: var(--c-ink-soft);
}

/* Lead card: image beside the text on wide screens. */
.media-card--lead .media-card-link {
	display: grid;
	grid-template-columns: 1.35fr 1fr;
	gap: 32px;
	align-items: center;
}

.media-card--lead .media-card-media {
	aspect-ratio: 16 / 9;
}

.media-card--lead .media-card-body {
	padding-top: 0;
}

.media-card--lead .media-card-title {
	font-size: clamp(26px, 3vw, 38px);
}

.media-card--lead .media-play svg {
	width: 74px;
	height: 74px;
}

.media-empty {
	padding: 40px 0 20px;
}

/* Video embeds in article bodies: keep 16:9 and never overflow the column.
   Targets WordPress' own embed wrappers plus any raw iframe/video. */
.article-body .wp-block-embed__wrapper,
.article-body figure.wp-block-embed,
.article-body .wp-block-embed {
	margin-inline: 0;
}

.article-body .wp-block-embed__wrapper {
	position: relative;
}

.article-body iframe,
.article-body video,
.article-body .wp-block-embed__wrapper > iframe {
	display: block;
	width: 100%;
	aspect-ratio: 16 / 9;
	height: auto;
	border: 0;
	background: var(--c-black);
}

.article-kicker {
	font-family: var(--font-cond);
	text-transform: uppercase;
	letter-spacing: 0.12em;
	font-size: 13px;
	color: var(--c-accent-ink);
	margin: 0 0 10px;
}

.padding-ver-40 {
	padding-block: 40px;
}

@media (max-width: 1020px) {
	.media-grid {
		grid-template-columns: repeat(2, 1fr);
	}

	.media-card--lead .media-card-link {
		grid-template-columns: 1fr;
		gap: 18px;
	}

	.media-card--lead .media-card-body {
		padding-top: 4px;
	}
}

@media (max-width: 640px) {
	.media-grid {
		grid-template-columns: 1fr;
		gap: 30px;
	}

	.media-play svg {
		width: 48px;
		height: 48px;
	}
}

/* Arcade cabinet ------------------------------------------------------ */

/* The screen box is measured off the artwork (screen occupies x 96-310,
   y 186-400 of a 408x612 image), expressed as percentages so it stays locked
   to the cabinet at any render size. Re-measure if the art is ever replaced. */

/* Full-bleed stage: lets the cabinet use the whole viewport width on phones
   instead of being boxed in by .container's 92%. Flex keeps it centred at
   whatever size it lands on, so no negative-margin maths is needed. */
.arcade-stage {
	display: flex;
	justify-content: center;
	width: 100vw;
	margin-inline: calc(50% - 50vw);
}

/* 100vw counts the scrollbar, which can push a stray horizontal scrollbar onto
   the page. Clip it at the section rather than the container, so the bleed
   still works. */
.arcade-main {
	overflow-x: clip;
}

.arcade-cabinet {
	position: relative;
	width: auto;
	height: min(97.5vh, 950px);
	aspect-ratio: 408 / 612;
	margin: 40px auto 0;
	line-height: 0;
}

.arcade-cabinet-art {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: contain;
}

.arcade-screen {
	position: absolute;
	left: 23.529%;
	top: 30.392%;
	width: 52.451%;
	height: 34.967%;
	overflow: hidden;
	background: #000;
}

/* Whatever gets mounted in the screen fills it edge to edge. */
.arcade-screen > iframe,
.arcade-screen > canvas,
.arcade-screen > video,
.arcade-screen > img {
	display: block;
	width: 100%;
	height: 100%;
	border: 0;
}

.arcade-intro {
	max-width: 680px;
	margin-inline: auto;
}

@media (max-width: 760px) {
	/* As large as it can be while still fitting: take the full viewport width,
	   unless the remaining height below the header is the tighter limit — then
	   derive width from that instead, so the cabinet is never cut off.
	   Aspect ratio is held exactly either way, which keeps .arcade-screen
	   aligned to the artwork. svh is used so mobile browser chrome
	   appearing/disappearing can't crop it; the vh line is the fallback. */
	.arcade-cabinet {
		height: auto;
		margin-top: 12px;
		width: min(100vw, calc((100vh - var(--header-h) - 24px) * 408 / 612));
		width: min(100vw, calc((100svh - var(--header-h) - 24px) * 408 / 612));
	}

	.arcade-stage + *,
	.site-main .arcade-stage {
		margin-bottom: 0;
	}
}

.site-nav > ul {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	align-items: center;
}

.site-nav > ul > li {
	margin-left: 20px;
	position: relative;
}

.site-nav > ul > li:first-child {
	margin-left: 0;
}

.site-nav a {
	display: block;
	padding: 20px 0;
	font-family: var(--font-cond);
	font-weight: 300;
	font-size: 16.5px;
	letter-spacing: var(--ls);
	text-transform: uppercase;
	color: var(--c-white);
	transition: color 0.2s ease;
}

.site-nav a:hover {
	color: var(--c-accent);
}

/* Script-artwork nav labels: dark at rest, neon on hover — same light as the
   monster mark. Both frames stack so the swap never reflows the menu. */

.site-nav .nav-swap {
	position: relative;
	display: inline-block;
	line-height: 0;
	transition: filter 0.3s ease;
}

.site-nav .nav-swap img {
	display: block;
	height: 33px;
	width: auto;
	transition: opacity 0.3s ease;
}

/* Per-label optical tuning: the source artwork isn't drawn to a common
   baseline, so a couple of labels need nudging to read at the same size. */
.site-nav .nav-swap--main img {
	height: 34.65px;
}

.site-nav .nav-swap .swap-on {
	position: absolute;
	left: 0;
	top: 0;
	opacity: 0;
}

.site-nav a:hover .nav-swap .swap-on,
.site-nav a:focus-visible .nav-swap .swap-on {
	opacity: 1;
}

.site-nav a:hover .nav-swap .swap-off,
.site-nav a:focus-visible .nav-swap .swap-off {
	opacity: 0;
}

.site-nav a:hover .nav-swap,
.site-nav a:focus-visible .nav-swap {
	filter: drop-shadow(0 0 8px rgba(62, 255, 107, 0.6)) drop-shadow(0 0 24px rgba(62, 255, 107, 0.34));
}

.site-nav li.highlight > a,
.site-nav li.sale > a {
	color: var(--c-accent);
}

/* Dropdowns */
.site-nav ul ul {
	list-style: none;
	margin: 0;
	padding: 8px 0;
	position: absolute;
	top: 100%;
	left: -18px;
	min-width: 220px;
	background: var(--c-black);
	border: 1px solid var(--c-line-dark);
	opacity: 0;
	visibility: hidden;
	transform: translateY(8px);
	transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
	z-index: 90;
}

/* Frosted glass -- but ONLY where the browser can actually blur what is behind
   it. The solid --c-black above stays as the fallback on purpose: with no
   backdrop-filter support a 45%-black panel leaves the hero flash art showing
   straight through the menu text, which is unreadable rather than merely
   unstyled. Firefox shipped this late and some builds still gate it, so the
   guard is not theoretical. */
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
	.site-nav ul ul {
		/* brightness() is doing the real work here, and the first attempt
		   without it was invisible. The hero art behind this menu averages a
		   luminance of about 26/255 -- blurring near-black just gives you
		   near-black, so a 45% tint over it landed at ~17/255, roughly 7% off
		   the solid black panel it replaced. Nobody could see the difference.
		   Lifting the backdrop is what makes glass read as glass: the panel has
		   to end up LIGHTER than what surrounds it, not merely blurrier. Tint
		   is correspondingly light so the lift is not immediately cancelled. */
		background: rgba(14, 22, 16, 0.22);
		-webkit-backdrop-filter: blur(18px) saturate(180%) brightness(2.6);
		backdrop-filter: blur(18px) saturate(180%) brightness(2.6);
		/* A hairline of light along the edge is what separates "glass" from
		   "translucent black box". */
		border-color: rgba(255, 255, 255, 0.2);
		box-shadow: 0 16px 34px rgba(0, 0, 0, 0.45);
	}
}

.site-nav li:hover > ul,
.site-nav li:focus-within > ul {
	opacity: 1;
	visibility: visible;
	transform: translateY(0);
}

.site-nav ul ul a {
	padding: 8px 18px;
	font-size: 16px;
}

.header-actions {
	display: flex;
	align-items: center;
	gap: 4px;
}

.header-icon {
	position: relative;
	width: 40px;
	height: 40px;
	display: grid;
	place-items: center;
	background: none;
	border: 0;
	padding: 0;
	color: var(--c-white);
	cursor: pointer;
	transition: color 0.2s ease;
}

.header-icon svg {
	width: 20px;
	height: 20px;
}

.header-icon:hover {
	color: var(--c-accent);
}

.cart-count {
	position: absolute;
	top: 1px;
	right: 0;
	min-width: 16px;
	height: 16px;
	padding: 0 3px;
	background: var(--c-accent);
	color: var(--c-black);
	font-family: var(--font-mono);
	font-size: 11px;
	line-height: 16px;
	letter-spacing: 0;
	text-align: center;
}

.nav-toggle {
	display: none;
}

.nav-toggle .icon-close {
	display: none;
}

body.nav-open .nav-toggle .icon-burger {
	display: none;
}

body.nav-open .nav-toggle .icon-close {
	display: block;
}

@media (max-width: 1020px) {
	.nav-toggle {
		display: grid;
	}

	.site-nav {
		position: fixed;
		inset: var(--header-h) 0 0 0;
		background: var(--c-black);
		z-index: 95;
		display: grid;
		place-items: center;
		opacity: 0;
		pointer-events: none;
		transform: translateY(-10px);
		transition: opacity 0.25s ease, transform 0.25s ease;
		overflow-y: auto;
	}

	body.nav-open .site-nav {
		opacity: 1;
		pointer-events: auto;
		transform: none;
	}

	.site-nav > ul {
		flex-direction: column;
		gap: 6px;
		padding: 40px 0;
	}

	.site-nav > ul > li {
		margin: 0;
		text-align: center;
	}

	.site-nav a {
		padding: 10px 0;
		font-size: 30px;
	}

	.site-nav .nav-swap img {
		height: 55px;
	}

	.site-nav .nav-swap--main img {
		height: 57.75px;
	}

	.site-nav ul ul {
		position: static;
		opacity: 1;
		visibility: visible;
		transform: none;
		border: 0;
		padding: 0 0 8px;
		min-width: 0;
		/* No glass on mobile. Here the submenu is a static list sitting INSIDE
		   the opened nav panel, so there is nothing behind it worth blurring --
		   it would just be a translucent tile stacked on an opaque panel, plus
		   a real compositing cost on the weakest devices. */
		background: transparent;
		-webkit-backdrop-filter: none;
		backdrop-filter: none;
		box-shadow: none;
	}

	.site-nav ul ul a {
		font-size: 19px;
		color: var(--c-paper-soft);
	}
}

body.nav-open,
body.overlay-open {
	overflow: hidden;
}

/* 6. Torn dividers ----------------------------------------------------
   The divider is the ripped edge of the section it tears INTO, so it has to be
   made of the same stuff as that section -- including the static grain.

   Painting the SVG as a background-image cannot do that: the shape is a flat
   fill, so it reads as a smooth slab pasted over a textured page, which is
   exactly the "separate frame with its own base" problem. Instead the SVG is
   used as a MASK and the element is filled with the destination section's
   actual background, grain and all. The static then runs through the torn
   shape and the seam disappears.

   The grain tile starts at each element's own origin rather than the page's,
   but the source is random noise, so the phase difference is not visible.
   Same 7-day image cache applies here as to the tile, hence the ?v=. */

.torn {
	height: var(--torn-h);
	pointer-events: none;

	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-size: 100% 100%;
	mask-size: 100% 100%;

	background-color: var(--c-bg);
	background-repeat: repeat;
}

/* Tears into a .sec-dark band, which is rgba(0,0,0,.78) over the page base --
   replicated here as a flat overlay on top of the same grain. */
.torn--black {
	-webkit-mask-image: url("../img/divider-black.svg?v=2");
	mask-image: url("../img/divider-black.svg?v=2");
	background-image: linear-gradient(rgba(0, 0, 0, 0.78), rgba(0, 0, 0, 0.78)),
		url("../img/bg-noise.gif?v=4");
}

/* Tears into a .sec-light section, which is simply the page base showing. */
.torn--white {
	-webkit-mask-image: url("../img/divider-white.svg?v=2");
	mask-image: url("../img/divider-white.svg?v=2");
	background-image: url("../img/bg-noise.gif?v=4");
}

/* If masking is unavailable the element would be a hard-edged bar, which is
   worse than no divider at all -- hide it instead. */
@supports not ((-webkit-mask-image: url("")) or (mask-image: url(""))) {
	.torn {
		display: none;
	}
}

.torn--flip {
	transform: scaleY(-1);
}

.torn--abs-top,
.torn--abs-bottom {
	position: absolute;
	left: 0;
	right: 0;
	z-index: 3;
}

.torn--abs-top {
	top: -1px;
	transform: scaleY(-1);
}

.torn--abs-top.torn--flip {
	transform: none;
}

.torn--abs-bottom {
	bottom: -1px;
}

.torn--abs-bottom.torn--flip {
	transform: scaleY(-1);
}

/* In-flow dividers sit flush between sections */
.site-content > .torn,
.site-content .torn:not(.torn--abs-top):not(.torn--abs-bottom) {
	margin: 0;
	display: block;
}

/* 7. Section headings ------------------------------------------------- */

.sec-head {
	margin-bottom: 50px;
}

.sec-title {
	font-size: clamp(30px, 4.6vw, 46px);
	text-transform: none;
}

.sec-sub {
	margin: 8px 0 0;
	font-family: var(--font-cond);
	font-weight: 400;
	font-size: clamp(19px, 2.2vw, 24px);
	letter-spacing: 0.06em;
	text-transform: uppercase;
	line-height: 1.25;
}

/* 8. Hero ------------------------------------------------------------- */

/* Translucent, not solid: an opaque surface here would block the page grain and
   leave the hero as a smooth slab between textured sections. */
.hero {
	position: relative;
	height: min(92vh, 960px);
	min-height: 540px;
	background: rgba(10, 10, 10, 0.82);
	overflow: hidden;
}

.hero-slider,
.hero-slide {
	position: absolute;
	inset: 0;
}

.hero-slide {
	opacity: 0;
	transition: opacity 1s ease;
}

.hero-slide.is-active {
	opacity: 1;
}

.hero-slide img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.hero-scrim {
	position: absolute;
	inset: 0;
	/* Raised for the flash-sheet art (2026-07-31). The old placeholder was a
	   calm gradient, so a 12% midpoint was plenty; the real artwork is dense
	   green linework and the mono sub-line and CTA labels disappeared into it
	   entirely. Still light enough to read every motif through. */
	background: linear-gradient(180deg, rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.46) 45%, rgba(0, 0, 0, 0.66));
	z-index: 1;
}

.hero-content {
	position: relative;
	z-index: 2;
	height: 100%;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	text-align: center;
	padding: 0 6%;
	color: var(--c-white);
}

.hero-title {
	font-family: var(--font-cond);
	font-weight: 400;
	font-size: clamp(30px, 4.6vw, 54px);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	line-height: 1.15;
}

.hero-sub {
	margin: 14px 0 0;
	font-family: var(--font-mono);
	font-size: clamp(13px, 1.4vw, 16px);
	letter-spacing: 0.22em;
	text-transform: uppercase;
	color: var(--c-accent);
}

.hero-ctas {
	margin-top: 34px;
	display: flex;
	gap: 12px;
	flex-wrap: wrap;
	justify-content: center;
}

.hero-dots {
	position: absolute;
	bottom: calc(var(--torn-h) + 18px);
	left: 0;
	right: 0;
	z-index: 4;
	display: flex;
	justify-content: center;
	gap: 8px;
}

/* Square dots — shared with carousels */
.dot {
	width: 9px;
	height: 9px;
	padding: 0;
	border: 1px solid var(--c-white);
	background: transparent;
	cursor: pointer;
	transition: background 0.2s ease;
}

.dot.is-active {
	background: var(--c-white);
}

.sec-light .dot,
.carousel-dots .dot {
	border-color: var(--c-black);
}

.sec-light .dot.is-active,
.carousel-dots .dot.is-active {
	background: var(--c-black);
}

/* 9. Tiles ------------------------------------------------------------ */

.tile-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--gap);
}

.tile {
	position: relative;
	aspect-ratio: 3 / 2;
	overflow: hidden;
	background: var(--c-surface);
}

.tile-link {
	position: absolute;
	inset: 0;
	display: block;
}

.tile-media {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	filter: saturate(0.85) contrast(1.04);
	transition: transform 0.55s ease;
}

.tile:hover .tile-media {
	transform: scale(1.06);
}

.tile-scrim {
	position: absolute;
	inset: 0;
	background: linear-gradient(180deg, rgba(0, 0, 0, 0.28), rgba(0, 0, 0, 0.55));
	z-index: 1;
	transition: background 0.3s ease;
}

.tile-content {
	position: absolute;
	inset: 0;
	z-index: 2;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	text-align: center;
	padding: 18px;
}

.tile-title {
	font-family: var(--font-cond);
	font-weight: 400;
	font-size: 20px;
	letter-spacing: var(--ls);
	line-height: 1.3;
	text-transform: uppercase;
	color: var(--c-white);
}

.tile-tag {
	margin-top: 10px;
	font-family: var(--font-mono);
	font-size: 14px;
	letter-spacing: var(--ls);
	color: var(--c-accent);
}

.like-star {
	position: absolute;
	top: 10px;
	right: 10px;
	z-index: 3;
	width: 36px;
	height: 36px;
	display: grid;
	place-items: center;
	background: none;
	border: 0;
	padding: 0;
	color: var(--c-white);
	opacity: 0.9;
	cursor: pointer;
	transition: transform 0.2s ease, color 0.2s ease;
}

.like-star svg {
	width: 22px;
	height: 22px;
}

.like-star:hover {
	transform: scale(1.12);
}

.like-star.is-active {
	color: var(--c-accent);
}

.like-star.is-active svg path {
	fill: currentColor;
}

/* 10. Portrait feature tiles (fly-apart hover) ------------------------ */

.portrait-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--gap);
}

.portrait-tile {
	position: relative;
	aspect-ratio: 2 / 3;
	overflow: hidden;
	background: var(--c-surface);
}

.portrait-link {
	position: absolute;
	inset: 0;
	display: block;
}

.portrait-media {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	filter: saturate(0.85) contrast(1.04);
	transition: transform 0.6s ease;
}

.portrait-tile:hover .portrait-media {
	transform: scale(1.05);
}

.portrait-content {
	position: absolute;
	inset: 0;
	z-index: 2;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	text-align: center;
	padding: 20px;
}

.portrait-title {
	font-family: var(--font-cond);
	font-weight: 400;
	font-size: 21px;
	letter-spacing: var(--ls);
	text-transform: uppercase;
	color: var(--c-white);
	transition: all 0.2s ease-in-out;
}

.portrait-tag {
	margin-top: 10px;
	font-family: var(--font-mono);
	font-size: 14px;
	color: var(--c-accent);
	text-transform: uppercase;
	letter-spacing: var(--ls);
	transition: all 0.2s ease-in-out;
}

.portrait-tile:hover .portrait-title {
	transform: translateY(-100px) scale(1.5);
	opacity: 0;
}

.portrait-tile:hover .portrait-tag {
	transform: translateY(100px) scale(1.5);
	opacity: 0;
}

/* 11. Product cards --------------------------------------------------- */

.product-card {
	text-align: center;
}

.product-card-link {
	display: block;
}

.product-card-media {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	aspect-ratio: 3 / 4;
	background: var(--c-white);
	overflow: hidden;
	margin-bottom: 14px;
}

.product-card-media img {
	max-width: 100%;
	max-height: 100%;
	width: auto;
	height: auto;
	object-fit: contain;
	transition: transform 0.4s ease;
}

.product-card:hover .product-card-media img {
	transform: scale(1.045);
}

.product-card-title {
	font-family: var(--font-mono);
	font-weight: 400;
	font-size: 14.5px;
	letter-spacing: var(--ls);
	color: var(--c-black);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	padding: 0 6px;
}

.price {
	display: block;
	margin-top: 8px;
	font-family: var(--font-cond);
	font-size: 1.2em;
	letter-spacing: var(--ls);
	color: var(--c-black);
}

.price del {
	text-decoration: line-through;
	margin-right: 8px;
}

.price ins,
.price .sale-price {
	text-decoration: none;
	color: var(--c-sale);
}

/* 12. Carousel -------------------------------------------------------- */

.carousel {
	position: relative;
}

.carousel-track {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: calc((100% - 3 * var(--gap)) / 4);
	gap: var(--gap);
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
	-ms-overflow-style: none;
	padding-bottom: 4px;
}

.carousel-track::-webkit-scrollbar {
	display: none;
}

.carousel-item {
	scroll-snap-align: start;
}

.carousel-dots {
	margin-top: 28px;
	display: flex;
	justify-content: center;
	gap: 8px;
}

/* 13. Banners (featured drop / stockist) ------------------------------ */

.banner {
	position: relative;
	min-height: clamp(420px, 62vh, 660px);
	display: flex;
	align-items: center;
	justify-content: center;
	text-align: center;
	overflow: hidden;
	background: rgba(10, 10, 10, 0.82);
}

.banner-media {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.banner .tile-scrim {
	background: linear-gradient(180deg, rgba(0, 0, 0, 0.58), rgba(0, 0, 0, 0.52));
}

.banner-content {
	position: relative;
	z-index: 2;
	color: var(--c-white);
	padding: clamp(80px, 12vh, 140px) 6%;
	display: flex;
	flex-direction: column;
	align-items: center;
}

.banner-title {
	display: block;
	font-family: var(--font-display);
	font-size: clamp(32px, 4.4vw, 48px);
	line-height: 1.1;
}

.banner-sub {
	display: block;
	margin: 8px 0 0;
	font-family: var(--font-cond);
	font-weight: 400;
	font-size: clamp(19px, 2.2vw, 25px);
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.banner-sub--mono {
	font-family: var(--font-mono);
	font-size: 15px;
	letter-spacing: var(--ls);
	text-transform: none;
	color: var(--c-accent);
}

.banner-content .btn {
	margin-top: 26px;
}

/* 14. Selection split rows -------------------------------------------- */

.selection-row {
	display: grid;
	grid-template-columns: 37% 1fr;
	gap: 0 45px;
	width: min(96%, 1560px);
	margin: 70px auto 0;
	align-items: stretch;
}

.selection-banner {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	text-align: center;
	overflow: hidden;
	min-height: 560px;
	background: var(--c-surface);
}

.selection-row.is-flipped .selection-banner {
	order: 2;
}

.selection-banner .banner-content {
	padding: 60px 8%;
}

.selection-banner .banner-title {
	font-size: clamp(28px, 3vw, 38px);
}

.selection-products {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 45px var(--gap);
	align-content: start;
	padding: 10px 0;
}

.selection-more {
	grid-column: 1 / -1;
	text-align: center;
	margin: 10px 0 0;
}

/* 15. Mission / about ------------------------------------------------- */

.mission-text {
	font-family: var(--font-cond);
	font-weight: 400;
	font-size: clamp(19px, 2.1vw, 23px);
	line-height: 2.05;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	text-align: justify;
	color: var(--c-paper-soft);
	margin: 0 0 28px;
}

.mission-text strong {
	font-weight: 400;
	color: var(--c-white);
}

.mission-text em {
	font-style: normal;
	color: var(--c-accent);
}

.read-more-link {
	font-family: var(--font-mono);
	font-size: 15px;
	letter-spacing: 0.08em;
	color: var(--c-accent);
}

.read-more-link:hover {
	text-decoration: underline;
	text-underline-offset: 4px;
}

/* 16. Newsletter ------------------------------------------------------ */

.newsletter-note {
	font-family: var(--font-mono);
	font-size: 15px;
	color: var(--c-ink-soft);
	margin: 0 0 28px;
}

.sec-dark .newsletter-note,
.site-footer .newsletter-note {
	color: var(--c-paper-soft);
	margin: 12px 0 0;
	font-size: 13px;
}

.newsletter-form {
	display: flex;
	gap: 0;
}

.newsletter-form--inline {
	justify-content: center;
}

.newsletter-input {
	width: min(420px, 100%);
	padding: 13px 16px;
	border: 1px solid var(--c-black);
	border-radius: 0;
	background: var(--c-white);
	font-family: var(--font-mono);
	font-size: 15px;
	letter-spacing: var(--ls);
	color: var(--c-black);
}

.newsletter-input::placeholder {
	color: rgba(0, 0, 0, 0.45);
}

.newsletter-form .btn {
	border-width: 1px;
	font-size: 17px;
	padding: 0 1.6em;
}

.site-footer .newsletter-input {
	background: transparent;
	border-color: rgba(255, 255, 255, 0.85);
	color: var(--c-white);
	width: 100%;
}

.site-footer .newsletter-input::placeholder {
	color: rgba(255, 255, 255, 0.5);
}

.js-newsletter.is-done .newsletter-input,
.js-newsletter.is-done .btn {
	opacity: 0.45;
	pointer-events: none;
}

/* 17. Footer ---------------------------------------------------------- */

.site-footer {
	padding: 64px 0 28px;
}

.footer-grid {
	display: grid;
	grid-template-columns: 1fr 1.7fr 1fr 1fr;
	gap: 44px;
}

.footer-head {
	font-family: var(--font-cond);
	font-weight: 400;
	font-size: 17px;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	margin-bottom: 18px;
}

.footer-links,
.legal-links {
	list-style: none;
	margin: 0;
	padding: 0;
}

.footer-links li {
	margin-bottom: 10px;
	font-family: var(--font-mono);
	font-size: 14px;
}

.footer-links a {
	color: rgba(255, 255, 255, 0.85);
	transition: color 0.2s ease;
}

.footer-links a::before {
	content: "> ";
	opacity: 0.6;
}

.footer-links a:hover {
	color: var(--c-accent);
}

.social-row {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
}

.social-box {
	width: 40px;
	height: 40px;
	display: grid;
	place-items: center;
	border: 1px solid rgba(255, 255, 255, 0.85);
	color: var(--c-white);
	transition: all 0.2s ease;
}

.social-box svg {
	width: 18px;
	height: 18px;
}

.social-box:hover {
	background: var(--c-accent);
	border-color: var(--c-accent);
	color: var(--c-black);
}

.social-box.is-placeholder {
	opacity: 0.4;
}

.footer-legal {
	margin-top: 54px;
	padding-top: 22px;
	border-top: 1px solid rgba(255, 255, 255, 0.14);
	display: flex;
	flex-wrap: wrap;
	gap: 12px 24px;
	justify-content: space-between;
	font-family: var(--font-mono);
	font-size: 12.5px;
	color: rgba(255, 255, 255, 0.6);
}

.legal-links {
	display: flex;
	gap: 20px;
}

.legal-links a:hover {
	color: var(--c-accent);
}

/* 18. Search overlay -------------------------------------------------- */

.search-overlay {
	position: fixed;
	inset: 0;
	z-index: 200;
	background: rgba(0, 0, 0, 0.96);
	display: grid;
	place-items: center;
	opacity: 0;
	transition: opacity 0.25s ease;
}

.search-overlay.is-open {
	opacity: 1;
}

.search-overlay[hidden] {
	display: none;
}

.search-overlay-inner {
	width: min(640px, 88vw);
	text-align: center;
}

.search-kicker {
	font-family: var(--font-mono);
	font-size: 14px;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--c-accent);
	margin: 0 0 24px;
}

.search-overlay .search-form {
	display: flex;
	gap: 12px;
}

.search-overlay .search-field {
	flex: 1;
	background: transparent;
	border: 0;
	border-bottom: 2px solid var(--c-white);
	border-radius: 0;
	color: var(--c-white);
	font-family: var(--font-mono);
	font-size: clamp(18px, 3vw, 26px);
	letter-spacing: var(--ls);
	padding: 10px 4px;
}

.search-overlay .search-field:focus {
	outline: none;
	border-bottom-color: var(--c-accent);
}

.search-overlay .btn {
	background: var(--c-white);
	color: var(--c-black);
}

.overlay-close {
	position: absolute;
	top: 14px;
	right: 16px;
	width: 44px;
	height: 44px;
	display: grid;
	place-items: center;
	background: none;
	border: 0;
	color: var(--c-white);
	cursor: pointer;
}

.overlay-close svg {
	width: 24px;
	height: 24px;
}

.overlay-close:hover {
	color: var(--c-accent);
}

/* Inline search form (search page) */
.search-form {
	display: inline-flex;
	gap: 10px;
}

.search-form .search-field {
	padding: 12px 15px;
	border: 1px solid var(--c-black);
	border-radius: 0;
	font-family: var(--font-mono);
	font-size: 15px;
	min-width: min(360px, 70vw);
}

/* 19. Cart drawer ----------------------------------------------------- */

.drawer-scrim {
	position: fixed;
	inset: 0;
	z-index: 205;
	background: rgba(0, 0, 0, 0.55);
	opacity: 0;
	transition: opacity 0.3s ease;
	border: 0;
}

.drawer-scrim.is-open {
	opacity: 1;
}

.drawer-scrim[hidden] {
	display: none;
}

.cart-drawer {
	position: fixed;
	top: 0;
	right: 0;
	bottom: 0;
	z-index: 210;
	width: min(420px, 92vw);
	background: var(--c-surface);
	color: var(--c-white);
	border-left: 1px solid var(--c-line-dark);
	transform: translateX(102%);
	transition: transform 0.35s ease;
	display: flex;
	flex-direction: column;
}

.cart-drawer.is-open {
	transform: none;
}

.cart-drawer[hidden] {
	display: none;
}

.drawer-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 16px 20px;
	border-bottom: 1px solid var(--c-line-dark);
}

.drawer-head .overlay-close {
	position: static;
}

.drawer-title {
	font-family: var(--font-cond);
	font-size: 21px;
	letter-spacing: 0.07em;
	text-transform: uppercase;
}

.drawer-body {
	padding: 20px;
	overflow-y: auto;
	flex: 1;
	font-family: var(--font-mono);
	font-size: 14px;
}

/* 20. Journal article ------------------------------------------------- */

.article-hero {
	position: relative;
	height: min(62vh, 640px);
	min-height: 360px;
	overflow: hidden;
	background: var(--c-surface);
}

.article-head {
	margin-bottom: 40px;
}

.article-title {
	font-size: clamp(30px, 4.4vw, 46px);
}

.article-meta {
	margin: 14px 0 0;
	font-family: var(--font-mono);
	font-size: 13px;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--c-accent-ink);
}

.article-body {
	max-width: 74ch;
	margin-inline: auto;
}

.article-body h2,
.article-body h3 {
	margin: 1.6em 0 0.6em;
}

.article-body blockquote {
	margin: 1.6em 0;
	padding: 4px 0 4px 22px;
	border-left: 3px solid var(--c-accent-ink);
	font-family: var(--font-cond);
	font-size: 1.25em;
	text-transform: uppercase;
	letter-spacing: 0.05em;
}

.article-foot {
	margin-top: 54px;
}

/* Pagination */
.pagination .nav-links,
.woocommerce-pagination ul.page-numbers {
	display: flex;
	justify-content: center;
	gap: 10px;
	margin-top: 54px;
	list-style: none;
	padding: 0;
}

.page-numbers {
	min-width: 40px;
	height: 40px;
	display: inline-grid;
	place-items: center;
	border: 1px solid var(--c-black);
	font-family: var(--font-mono);
	font-size: 14px;
	color: var(--c-black);
	padding: 0 8px;
}

.page-numbers.current {
	background: var(--c-black);
	color: var(--c-white);
}

.page-numbers:hover:not(.current) {
	background: var(--c-grey-soft);
}

/* 21. Reveal animation ------------------------------------------------ */

.reveal {
	opacity: 0;
	transform: translateY(18px);
	transition: opacity 0.7s ease, transform 0.7s ease;
	transition-delay: var(--reveal-delay, 0s);
}

.reveal.in-view {
	opacity: 1;
	transform: none;
}

/* 22. Responsive ------------------------------------------------------ */

@media (max-width: 1100px) {
	.tile-grid {
		grid-template-columns: repeat(2, 1fr);
	}

	.portrait-grid {
		grid-template-columns: repeat(3, 1fr);
	}

	.carousel-track {
		grid-auto-columns: calc((100% - var(--gap)) / 2);
	}

	.selection-row {
		grid-template-columns: 1fr;
		gap: 40px;
	}

	.selection-banner {
		min-height: 380px;
	}

	.footer-grid {
		grid-template-columns: 1fr 1fr;
	}
}

@media (max-width: 760px) {
	:root {
		--header-h: 126px;
	}

	/* The hero had no mobile rule at all, so phones inherited the desktop
	   min(92vh, 960px). With a 126px header on top, that pushes the hero past
	   the bottom of the screen — its content is centred in a box taller than
	   the viewport, so the headline sits low and the buttons land on the fold.
	   Size it to the space actually below the header instead, less a margin so
	   the next section peeks and there is something to scroll toward. svh
	   keeps the browser chrome from changing the answer mid-scroll. */
	.hero {
		height: min(calc(100vh - var(--header-h) - 56px), 620px);
		height: min(calc(100svh - var(--header-h) - 56px), 620px);
		min-height: 380px;
	}

	.site-brand img {
		max-height: 114px;
	}

	.site-brand .brand-swap--monster img {
		max-height: 46px;
	}

	.portrait-grid {
		grid-template-columns: 1fr;
		max-width: 420px;
		margin-inline: auto;
	}

	.selection-products {
		gap: 36px 16px;
	}

	.newsletter-form--inline {
		flex-direction: column;
		gap: 12px;
		align-items: center;
	}

	.newsletter-form--inline .newsletter-input {
		width: 100%;
	}
}

@media (max-width: 560px) {
	.tile-grid {
		grid-template-columns: 1fr;
	}

	.carousel-track {
		grid-auto-columns: 78%;
	}

	.selection-products {
		grid-template-columns: 1fr 1fr;
	}

	.footer-grid {
		grid-template-columns: 1fr;
		gap: 36px;
	}

	.footer-legal {
		flex-direction: column;
	}
}

/* 23. Reduced motion --------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}

	*,
	*::before,
	*::after {
		transition-duration: 0.01ms !important;
		animation-duration: 0.01ms !important;
	}

	.reveal {
		opacity: 1;
		transform: none;
	}
}

/* 20. Contact — ouija board frame -------------------------------------
   The board art is a frame and the form is mounted in its dark centre. The
   panel offsets are percentages measured off the artwork by
   tools/prep_ouija.py, so the form stays locked to the board at any width.
   Re-run that script if the art is ever replaced and paste the four numbers. */

.ouija-stage {
	margin-top: 34px;
}

/* The panel is a fixed percentage of the art, so panel height scales with board
   width. A 10-row message box needs the board at full container width to fit. */
.ouija-board {
	position: relative;
	width: 100%;
	margin-inline: auto;
}

.ouija-board-art {
	display: block;
	width: 100%;
	height: auto;
}

.ouija-panel {
	position: absolute;
	left: 29.00%;
	top: 20.70%;
	width: 42.00%;
	height: 58.59%;
	display: flex;
	align-items: center;
	justify-content: center;
	text-align: left;
}

.ouija-panel > * {
	width: 100%;
}

/* Fluent Forms ships a light skin; restate it small, dark and on-brand so it
   sits on the board instead of on top of it. */
.ouija-panel .fluentform .ff-el-group {
	margin-bottom: 8px;
}

/* The panel is a fixed share of the artwork, so vertical space is the scarce
   resource. Labels are hidden visually (kept for screen readers) and the
   placeholders carry the meaning -- otherwise the form outgrows the board. */
.ouija-panel .fluentform .ff-el-input--label {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
}

.ouija-panel .fluentform input[type="text"],
.ouija-panel .fluentform input[type="email"],
.ouija-panel .fluentform textarea {
	background: rgba(0, 0, 0, 0.45);
	border: 1px solid rgba(255, 255, 255, 0.22);
	border-radius: 0;
	color: #f2f2f2;
	font-family: var(--font-mono);
	font-size: 13px;
	padding: 6px 9px;
	min-height: 0;
	height: auto;
	box-shadow: none;
}

/* Height comes from the field's rows="10", not from CSS -- a min-height here
   would silently override it and the box would stop matching the form config.
   line-height must be set explicitly though: left to the browser default a
   textarea collapses to about 1.0, so ten rows render unreadably tight. */
.ouija-panel .fluentform textarea {
	line-height: 1.45;
	resize: vertical;
}

.ouija-panel .fluentform input::placeholder,
.ouija-panel .fluentform textarea::placeholder {
	color: rgba(255, 255, 255, 0.35);
}

/* Fluent Forms' default skin repaints focused fields white
   (`.ff-default .ff-el-form-control:focus`). Restating only the border here was
   not enough -- the background has to be held explicitly or the field flashes
   white against the board the moment it is clicked. */
.ouija-panel .fluentform input:focus,
.ouija-panel .fluentform textarea:focus {
	background: rgba(0, 0, 0, 0.45);
	color: #f2f2f2;
	border-color: var(--c-accent);
	outline: none;
	box-shadow: none;
}

/* Fluent Forms prints a per-form <style> in the head reading
   `form.fluent_form_3 .ff-btn-submit:not(.ff_btn_no_style)` -- an element plus
   three classes, which outranks a plain class chain and lands after the theme
   sheet. Rather than escalate a specificity war that the next plugin update
   would win anyway, set the custom property that rule actually reads. */
.ouija-panel {
	--fluentform-primary: var(--c-accent);
}

/* Park the submit button over the GOODBYE text.

   The button lives inside .ouija-panel, and an absolutely positioned element
   resolves against its nearest positioned ancestor -- the panel, not the board.
   So these are PANEL-relative coordinates, which is why top is over 100%:
   the GOODBYE band sits below the panel. Both numbers come straight out of
   tools/prep_ouija.py, which measures the text and does the conversion. */
.ouija-panel .fluentform .ff_submit_btn_wrapper {
	position: absolute;
	left: 52.00%;
	top: 117.27%;
	transform: translate(-50%, -50%);
	margin: 0;
	/* 64.6% of the panel is 76% scaled down 15% at Brad's call (~27% of the
	   board). The width lives on the wrapper because the button sizes off it. */
	width: 64.6%;
	text-align: center;
	z-index: 4;
}

/* The button IS the carved plaque. The artwork carries the wording, so the text
   is collapsed visually but left in the DOM -- it is what gives the button its
   accessible name. `background` shorthand (not background-image) because Fluent
   Forms also sets background-color, and the shorthand resets it; otherwise the
   colour would show through the plaque's transparent edges. */
.ouija-panel .fluentform form.frm-fluent-form .ff-btn-submit {
	width: 100%;
	aspect-ratio: 370 / 115;
	height: auto;
	min-width: 0;
	min-height: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	background: url("../img/send-message.webp") no-repeat center / contain;
	font-size: 0;
	line-height: 0;
	color: transparent;
	cursor: pointer;
	transition: filter 0.2s ease, transform 0.2s ease;
}

.ouija-panel .fluentform form.frm-fluent-form .ff-btn-submit:hover {
	filter: brightness(1.18) drop-shadow(0 0 10px rgba(62, 255, 107, 0.35));
	transform: translateY(-1px);
}

.ouija-panel .fluentform form.frm-fluent-form .ff-btn-submit:focus-visible {
	outline: 2px solid var(--c-accent);
	outline-offset: 4px;
}

.ouija-panel .ff-message-success,
.ouija-panel .ff-el-is-error .error {
	font-family: var(--font-mono);
	font-size: 13px;
	color: var(--c-accent);
}

/* The panel is a fixed share of the artwork, so below roughly this width there
   is not enough room inside the board for a usable form. Drop the framing and
   let the form stand on its own rather than shrink it into illegibility. */
@media (max-width: 1100px) {
	.ouija-panel {
		position: static;
		width: 100%;
		height: auto;
		overflow: visible;
		margin-top: 26px;
	}

	/* No board to sit on once the framing is dropped -- back into the flow. */
	.ouija-panel .fluentform .ff_submit_btn_wrapper {
		position: static;
		transform: none;
		text-align: left;
	}

	.ouija-panel .fluentform input[type="text"],
	.ouija-panel .fluentform input[type="email"],
	.ouija-panel .fluentform textarea {
		font-size: 16px; /* stops iOS zooming the field on focus */
		padding: 10px 12px;
	}

	.ouija-panel .fluentform textarea {
		min-height: 120px;
	}
}

/* Shop landing: category tiles + curated rows ------------------------- */

/* The shop runs inside .sec-light, which inverts the palette (--c-black is
   the text colour there, --c-white the surface). Everything below uses those
   tokens rather than literal colours so it stays correct if that flips. */

.shop-cats {
	margin: 0 0 60px;
}

.shop-cats-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
	gap: 14px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.shop-cat a {
	position: relative;
	display: block;
	overflow: hidden;
	aspect-ratio: 4 / 3;
	text-decoration: none;
	background: #101013;
	border: 1px solid rgba(255, 255, 255, 0.14);
}

.shop-cat .shop-cat-img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* Muted so the label stays readable and the row does not compete with the
	   products underneath — but only slightly. These are black garments shot
	   on near-black, so they carry almost no headroom: dimming them the way
	   you would a normal photo crushes them to flat rectangles. */
	filter: grayscale(0.25) brightness(0.78);
	transition: transform 0.45s ease, filter 0.45s ease;
}

.shop-cat--all .shop-cat-img {
	background:
		repeating-linear-gradient(
			45deg,
			rgba(62, 255, 107, 0.09) 0 10px,
			transparent 10px 20px
		),
		#141418;
}

.shop-cat a:hover .shop-cat-img,
.shop-cat a:focus-visible .shop-cat-img {
	transform: scale(1.06);
	filter: grayscale(0) brightness(0.8);
}

.shop-cat-name {
	position: absolute;
	inset: auto 0 0 0;
	padding: 26px 12px 11px;
	font-family: var(--font-cond);
	font-size: 16px;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: #fff;
	background: linear-gradient(to top, rgba(0, 0, 0, 0.9), transparent);
}

.shop-cat-count {
	position: absolute;
	top: 8px;
	right: 9px;
	min-width: 22px;
	padding: 1px 6px;
	font-family: var(--font-mono);
	font-size: 11px;
	text-align: center;
	color: #fff;
	background: rgba(0, 0, 0, 0.6);
	border: 1px solid rgba(255, 255, 255, 0.18);
}

.shop-cat.is-current a {
	border-color: var(--c-accent);
}

.shop-cat.is-current .shop-cat-img {
	filter: grayscale(0) brightness(0.82);
}

.shop-cat.is-current .shop-cat-name {
	color: var(--c-accent);
}

/* Curated rows sit between the tiles and the full grid. Their headings are
   smaller than the page heading so the hierarchy reads top-down. */
.shop-row {
	margin: 0 0 64px;
}

.shop-row .sec-head,
.shop-all .sec-head {
	margin-bottom: 30px;
}

.shop-row .sec-title,
.shop-all .sec-title {
	font-size: clamp(24px, 3.2vw, 34px);
}

.shop-row .sec-sub,
.shop-all .sec-sub {
	font-size: clamp(15px, 1.6vw, 18px);
}

.shop-all {
	margin-top: 10px;
}

@media (max-width: 760px) {
	.shop-cats {
		margin-bottom: 40px;
	}

	.shop-cats-grid {
		/* Two up on a phone: five 140px tiles would otherwise stack into a
		   very tall column before any product is visible. */
		grid-template-columns: repeat(2, 1fr);
		gap: 10px;
	}

	/* Five tiles over two columns leaves the last category stranded alone on
	   its own row. Letting "All" span the full width turns the remaining four
	   into a clean 2x2 — and it reads better anyway, since "All" is a reset
	   rather than a peer of the categories. */
	.shop-cat--all {
		grid-column: 1 / -1;
	}

	.shop-cat--all a {
		aspect-ratio: 5 / 2;
	}

	.shop-cat-name {
		font-size: 14px;
		letter-spacing: 0.12em;
		padding: 20px 10px 9px;
	}

	.shop-row {
		margin-bottom: 44px;
	}
}

/* Showcase ring: Top Picks & Best Sellers ------------------------------
   A 3D card ring (after the lunaproject.online hero carousel): cards sit on
   a circle via rotateY(--a) translateZ(--vring-r) inside a perspective
   stage, and JS rotates the stage to bring one card to the front. Behind it,
   the whole catalogue drifts past as a slow, dimmed, non-interactive strip —
   a distant echo of the shop, not a control. */

.vring-section {
	overflow-x: clip;   /* ring edges + full-bleed strip must not scroll the page */
}

.vring {
	--vring-r: 300px;        /* ring radius; fixed, tuned for up to 8 cards */
	--vring-card-w: 210px;
	--vring-card-h: 348px;

	position: relative;
	height: 520px;
	margin-top: 10px;
}

/* --- the distant ring --------------------------------------------------
   The backdrop is a GIANT rotating cylinder seen from the INSIDE: items sit
   on the circle via rotateY(--ba) translateZ(-R) — the negative radius turns
   the wheel inside-out, so instead of a convex drum bulging toward the
   viewer, the catalogue lines a concave wall that wraps around behind the
   showcase, amphitheatre-style, and spans the full width. The centre of the
   wall is the far point; cards grow and angle inward as they sweep to the
   edges. One linear animation spins the whole cylinder forever.

   Two rules keep the 3D real: no filter/opacity/overflow on the TRACK
   (any of them force transform-style back to flat and the ring collapses
   into a plane — dimming lives on the wrapper, per-item effects on the
   items), and backface-visibility hides the near half of the cylinder,
   which faces away and would otherwise show through mirrored. */

.vring-bg {
	--vbg-w: 450px;          /* item size — big enough to fill the wall */
	--vbg-h: 600px;
	/* Radius sized so the VISIBLE arc spans past both viewport edges with the
	   cards still mostly face-on. On a small cylinder the edge cards turn
	   nearly edge-on and the wall dies out before the screen does — the cure
	   is a bigger circle lined with more items, not a wider mask. */
	--vbg-r: 1800px;
	--vbg-push: -500px;      /* how far the cylinder's axis sits behind the glass */
	--vbg-lap: 180s;         /* one full revolution */

	position: absolute;
	left: 50%;
	top: 0;
	transform: translateX(-50%);
	width: 100vw;
	height: 100%;
	overflow: hidden;
	z-index: 0;
	opacity: 0.28;
	pointer-events: none;
	perspective: 2400px;
}

.vring-bg-track {
	position: absolute;
	left: 50%;
	top: 50%;
	transform-style: preserve-3d;
	transform: translateZ(var(--vbg-push)) rotateY(0deg);
	animation: vring-bg-spin var(--vbg-lap) linear infinite;
}

.vring-bg-item {
	position: absolute;
	width: var(--vbg-w);
	height: var(--vbg-h);
	margin: calc(var(--vbg-h) / -2) 0 0 calc(var(--vbg-w) / -2);
	transform: rotateY(calc(var(--ba) * 1deg)) translateZ(calc(var(--vbg-r) * -1));
	backface-visibility: hidden;
	-webkit-backface-visibility: hidden;
}

.vring-bg-item img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	border-radius: 14px;
	border: 1px solid rgba(255, 255, 255, 0.08);
	filter: brightness(0.5) grayscale(0.35) blur(1.2px);
}

@keyframes vring-bg-spin {
	to { transform: translateZ(var(--vbg-push)) rotateY(-360deg); }
}

/* --- the ring ---------------------------------------------------------- */

.vring-stage-wrap {
	position: absolute;
	inset: 0;
	z-index: 1;
	perspective: 1100px;
}

.vring-stage {
	position: absolute;
	left: 50%;
	top: 50%;
	transform-style: preserve-3d;
	transition: transform 0.75s ease-in-out;
}

.vring-card {
	position: absolute;
	width: var(--vring-card-w);
	height: var(--vring-card-h);
	margin: calc(var(--vring-card-h) / -2) 0 0 calc(var(--vring-card-w) / -2);
	transform: rotateY(calc(var(--a) * 1deg)) translateZ(var(--vring-r));
	/* Hidden once a card turns away — product names mirror-image otherwise
	   and read as a rendering bug rather than depth. */
	backface-visibility: hidden;
	-webkit-backface-visibility: hidden;

	display: flex;
	flex-direction: column;
	align-items: center;
	padding: 14px 14px 16px;
	border-radius: 16px;
	border: 1px solid rgba(255, 255, 255, 0.18);
	background: rgba(10, 10, 12, 0.55);
	box-shadow: inset 0 0 30px rgba(255, 255, 255, 0.05);
	text-decoration: none;
	text-align: center;
	color: var(--c-black);
}

.vring-card:hover,
.vring-card:focus-visible {
	border-color: var(--c-accent);
}

.vring-chip {
	align-self: flex-start;
	font-family: var(--font-mono);
	font-size: 10px;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--c-accent);
	border: 1px solid rgba(62, 255, 107, 0.4);
	padding: 2px 8px;
	border-radius: 999px;
	margin-bottom: 10px;
}

.vring-media {
	display: block;
	width: 100%;
	flex: 1;
	min-height: 0;
	overflow: hidden;
	border-radius: 10px;
	/* Brightness floor: the current mockups are near-black garments on a
	   near-black ground, and on a glass card they read as an empty slot.
	   A faint backing keeps them legible until real photography lands. */
	background: rgba(255, 255, 255, 0.05);
}

.vring-media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.vring-card-title {
	font-family: var(--font-mono);
	font-size: 13px;
	letter-spacing: 0.05em;
	margin: 12px 0 4px;
	line-height: 1.35;
}

.vring-card .price {
	font-family: var(--font-cond);
	font-size: 17px;
	letter-spacing: 0.04em;
}

/* --- controls ----------------------------------------------------------- */

.vring-nav {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	z-index: 2;
	width: 44px;
	height: 44px;
	border-radius: 50%;
	border: 1px solid rgba(255, 255, 255, 0.25);
	background: rgba(0, 0, 0, 0.45);
	color: var(--c-black);
	font-size: 26px;
	line-height: 1;
	cursor: pointer;
	display: grid;
	place-items: center;
	padding: 0 0 4px;
	transition: border-color 0.2s ease, color 0.2s ease;
}

.vring-nav:hover,
.vring-nav:focus-visible {
	border-color: var(--c-accent);
	color: var(--c-accent);
}

.vring-nav.is-prev { left: 4%; }
.vring-nav.is-next { right: 4%; }

/* --- responsive --------------------------------------------------------- */

@media (max-width: 760px) {
	.vring {
		--vring-r: 205px;
		--vring-card-w: 150px;
		--vring-card-h: 260px;
		height: 400px;
	}

	.vring-stage-wrap { perspective: 850px; }

	.vring-bg {
		--vbg-w: 260px;
		--vbg-h: 347px;
		--vbg-r: 1070px;
		--vbg-push: -260px;
		perspective: 1400px;
	}

	.vring-card-title { font-size: 11.5px; margin-top: 9px; }
	.vring-card .price { font-size: 15px; }
	.vring-chip { font-size: 9px; }

	.vring-nav.is-prev { left: 2%; }
	.vring-nav.is-next { right: 2%; }
}

@media (prefers-reduced-motion: reduce) {
	.vring-bg-track { animation: none; }
	.vring-stage { transition: none; }
}
