/* jeroensannen.be — Heavy Rotation.
   A record on an oak desk. The sleeve is my photo printed in the colours of a Bloc Party album, a
   different one on every visit, the record is whatever's on repeat, and the back of the sleeve is the tracklist. */

@property --tint {
	syntax: '<color>';
	inherits: true;
	initial-value: #4a689c;
}
@property --sticker {
	syntax: '<color>';
	inherits: true;
	initial-value: #f2c94c;
}
@property --paper-accent {
	syntax: '<color>';
	inherits: true;
	initial-value: #9a3b25;
}

:root {
	/* An oak desk, and dark ink for everything printed on it */
	--desk: #b98a58;
	--desk-photo: url(../images/oak-honey.webp);
	--ink: #2b1d10;
	--ink-2: rgb(43 29 16 / .78);
	--ink-3: rgb(43 29 16 / .45);
	--line: rgb(43 29 16 / .26);
	--on-ink: #f7efe3;
	--shadow: 50 26 8;
	--accent: color-mix(in oklab, var(--tint) 70%, #000);

	--paper: #ece6d9;
	--paper-ink: #1d1a16;

	--font: "Archivo", "Helvetica Neue", Arial, sans-serif;
	/* Every Bloc Party sleeve is set in Gill Sans; Cabin stands in where it isn't installed. */
	--sleeve-font: "Gill Sans", "Gill Sans MT", "Cabin", "Helvetica Neue", Arial, sans-serif;
	--ease: cubic-bezier(.2, .7, .2, 1);

	/* Noise, drawn by the browser: fine grain, scuffing, rubbed-off speckles and age spots */
	--grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n' x='0' y='0' width='1' height='1'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
	--scuff: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n' x='0' y='0' width='1' height='1'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.05 .4' numOctaves='3' seed='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4.5 0 0 0 -2.05'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
	--speckle: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n' x='0' y='0' width='1' height='1'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.2' numOctaves='3' seed='8' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 13 0 0 0 -8.9'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
	--blotch: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='520' height='520'%3E%3Cfilter id='n' x='0' y='0' width='1' height='1'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.007' numOctaves='3' seed='12' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .5 0 0 0 0 .41 0 0 0 0 .26 1.5 0 0 0 -.72'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
	/* Pebbled leather for the tags on the desk */
	--leather-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n' x='0' y='0' width='1' height='1'%3E%3CfeTurbulence type='turbulence' baseFrequency='.42' numOctaves='2' seed='4' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .5 0 0 0 0 .5 0 0 0 0 .5 0 0 0 -1.6 1.2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
	/* Where the spindle missed the hole, over and over */
	--spindle: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cg fill='none' stroke='%23302c28' stroke-linecap='round' stroke-width='.7'%3E%3Cpath stroke-opacity='.55' d='M43 41 A 10 10 0 0 1 57 41.5'/%3E%3Cpath stroke-opacity='.45' d='M58.5 46 A 9 9 0 0 1 57 58'/%3E%3Cpath stroke-opacity='.5' d='M40 55 A 11 11 0 0 0 49 61.5'/%3E%3Cpath stroke-opacity='.35' d='M41.5 46.5 A 8 8 0 0 1 45 42.5'/%3E%3Cpath stroke-opacity='.3' d='M53 61 A 12 12 0 0 0 61.5 52'/%3E%3Cpath stroke-opacity='.25' d='M46 37.5 A 13 13 0 0 1 62 44'/%3E%3C/g%3E%3C/svg%3E");

	color-scheme: light;
	transition: --tint 2s ease, --sticker 2s ease, --paper-accent 2s ease;
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
[hidden] { display: none !important; }

html, body { background: var(--desk); }
/* Nothing should ever make the page scroll sideways, and a quick double tap on the sleeve shouldn't zoom. */
html { overflow-x: hidden; overflow-x: clip; touch-action: manipulation; }

body {
	min-height: 100svh;
	color: var(--ink);
	font: 400 13px/1.4 var(--font);
	-webkit-font-smoothing: antialiased;
	-webkit-text-size-adjust: 100%;
	text-size-adjust: 100%;
	-webkit-tap-highlight-color: transparent;
}

a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

.sr {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

/* With JavaScript, the page waits for its fonts (the inline script in the head caps that at 4s). */
.js .page { opacity: 0; transition: opacity .7s ease; }
.js.is-shown .page { opacity: 1; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* ---------- The room ---------- */

.room {
	position: fixed;
	inset: 0;
	z-index: 0;
	overflow: hidden;
	/* Oak veneer, photographed: a seamless CC0 texture from Poly Haven (polyhaven.com) */
	background: var(--desk-photo) 0 0 / 1400px repeat, var(--desk);
}
.room::before,
.room::after { content: ""; position: absolute; inset: 0; }
/* The album's colour, cast onto the wood */
.room::before {
	background: radial-gradient(48% 55% at 60% 46%, color-mix(in srgb, var(--tint) 75%, transparent), transparent 75%);
	mix-blend-mode: soft-light;
	opacity: .5;
	transition: opacity 1.5s ease;
}
/* A desk lamp, and the edges of the desk falling into shadow */
.room::after {
	background:
		radial-gradient(ellipse 65% 60% at 42% 42%, rgb(255 246 228 / .3), transparent 70%),
		radial-gradient(ellipse 130% 110% at 50% 45%, transparent 50%, rgb(var(--shadow) / .45));
}
:root.is-live .room::before { opacity: 1; animation: breathe 6s ease-in-out infinite; }

@keyframes breathe { 50% { opacity: .75; scale: 1.06; } }

/* Disco lights: a short burst when someone finds the bonus disc */
.room__lights {
	position: absolute;
	inset: -50%;
	opacity: 0;
	background: conic-gradient(from 0deg,
		transparent 0deg 15deg, color-mix(in srgb, var(--sticker) 55%, transparent) 25deg, transparent 38deg 95deg,
		color-mix(in srgb, var(--tint) 60%, transparent) 108deg, transparent 122deg 190deg,
		rgb(246 207 69 / .5) 202deg, transparent 216deg 275deg,
		color-mix(in srgb, var(--accent) 50%, transparent) 290deg, transparent 305deg);
	filter: blur(40px);
	mix-blend-mode: overlay;
	transition: opacity 1.4s ease;
}
/* Only spin the lights while they're on: a huge blurred layer is not something to animate for nothing. */
:root.is-party .room__lights { opacity: .9; transition-duration: .3s; animation: sweep 9s linear infinite; }

@keyframes sweep { to { rotate: 360deg; } }

/* ---------- Layout ---------- */

.page {
	--pad: clamp(16px, 4vw, 56px);
	--s: min(68svh, calc((100vw - 2 * var(--pad)) / 1.78), 680px);
	--stage-w: calc(var(--s) * 1.78);
	--stage-h: var(--s);

	position: relative;
	z-index: 1;
	min-height: 100svh;
	display: grid;
	place-content: center;
	justify-items: start;
	gap: clamp(22px, 4.5svh, 44px);
	padding: var(--pad);
	overflow-x: clip;
}

/* ---------- Stage: sleeve + record ---------- */

.stage {
	/* The record slides out along (--ax, --ay): sideways on landscape screens, upwards on portrait.
	   Idle it sits close to the sleeve; while you're listening it comes all the way out. */
	--ax: 1;
	--ay: 0;
	--out: calc(var(--s) * .66);

	position: relative;
	width: var(--stage-w);
	height: var(--stage-h);
	transform: perspective(1800px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
	transition: transform .9s var(--ease);
}
:root.is-live .stage { --out: calc(var(--s) * .8); }
.stage.is-secret { --pull: calc(var(--s) * .14); }

/* The record */

.record {
	--travel: calc(var(--out) + var(--nudge, 0px) + var(--pull, 0px));
	position: absolute;
	z-index: 1;
	left: calc(var(--s) * .025);
	top: calc(var(--s) * .025);
	width: calc(var(--s) * .95);
	height: calc(var(--s) * .95);
	border-radius: 50%;
	cursor: grab;
	touch-action: pan-y;
	user-select: none;
	-webkit-user-select: none;
	-webkit-touch-callout: none;
	transform: translate(calc(var(--ax) * var(--travel)), calc(var(--ay) * var(--travel)));
	transition:
		transform 1.2s var(--ease) var(--record-delay, 0s),
		visibility 0s linear var(--record-delay, 0s);
}
.js:not(.is-ready) .record { transform: none; }
.stage[data-side="front"]:not(.is-pulling) .record:hover { --nudge: calc(var(--s) * .05); }
.stage.is-pulling .record { cursor: grabbing; transition: none; }
/* Let go past the stop and it springs out a little further. */
.stage.is-secret .record { transition-timing-function: cubic-bezier(.34, 1.56, .64, 1); }

/* On the back the record is inside the sleeve: slide it in, then it's gone before the sleeve turns. */
.stage[data-side="back"] .record {
	transform: none;
	visibility: hidden;
	transition: transform .5s var(--ease), visibility 0s linear .5s;
}

.record__disc {
	position: absolute;
	inset: 0;
	border-radius: 50%;
	background:
		radial-gradient(circle closest-side, transparent 0 35%, rgb(255 255 255 / .06) 35.6% 36.2%, transparent 36.8%),
		#0d0d0f;
	box-shadow:
		0 0 0 1px rgb(0 0 0 / .35),
		0 calc(var(--s) * .03) calc(var(--s) * .06) calc(var(--s) * -.02) rgb(var(--shadow) / .7),
		0 0 0 0 transparent;
	filter: brightness(.82);
	transition: box-shadow 1.5s ease, filter 1.5s ease;
	animation: spin 1.8s linear infinite paused; /* 33⅓ rpm */
}
:root.is-live .record__disc {
	animation-play-state: running;
	filter: none;
	box-shadow:
		0 0 0 1px rgb(0 0 0 / .35),
		0 calc(var(--s) * .03) calc(var(--s) * .06) calc(var(--s) * -.02) rgb(var(--shadow) / .7),
		0 0 calc(var(--s) * .1) 0 color-mix(in srgb, var(--tint) 35%, transparent);
}

@keyframes spin { to { rotate: 360deg; } }

.record__grooves {
	position: absolute;
	inset: 0;
	border-radius: 50%;
	background:
		/* a played copy: hairline scratches, a greasy thumbprint and a bit of dust */
		url(../images/vinyl-scratches.svg) center / 100% 100% no-repeat,
		radial-gradient(ellipse 13% 8% at 71% 73%, rgb(255 255 255 / .07), transparent 70%),
		radial-gradient(ellipse 9% 6% at 26% 30%, rgb(255 255 255 / .045), transparent 70%),
		radial-gradient(circle at 28% 24%, rgb(255 255 255 / .35) 0 .12%, transparent .3%),
		radial-gradient(circle at 71% 18%, rgb(255 255 255 / .25) 0 .1%, transparent .25%),
		radial-gradient(circle at 82% 63%, rgb(255 255 255 / .3) 0 .12%, transparent .3%),
		radial-gradient(circle at 22% 72%, rgb(255 255 255 / .22) 0 .1%, transparent .25%),
		radial-gradient(circle at 57% 88%, rgb(255 255 255 / .28) 0 .1%, transparent .28%),
		radial-gradient(circle at 43% 67%, rgb(255 255 255 / .2) 0 .08%, transparent .2%),
		radial-gradient(circle at 88% 41%, rgb(255 255 255 / .24) 0 .09%, transparent .22%),
		radial-gradient(circle closest-side, transparent 0 51.4%, rgb(255 255 255 / .07) 51.8% 52.4%, transparent 52.8%),
		radial-gradient(circle closest-side, transparent 0 64.4%, rgb(255 255 255 / .07) 64.8% 65.4%, transparent 65.8%),
		radial-gradient(circle closest-side, transparent 0 78.4%, rgb(255 255 255 / .07) 78.8% 79.4%, transparent 79.8%),
		repeating-radial-gradient(circle closest-side, rgb(255 255 255 / .05) 0 1px, transparent 1px 3px);
	-webkit-mask: radial-gradient(circle closest-side, transparent 0 39%, #000 39.5% 96%, transparent 96.6%);
	mask: radial-gradient(circle closest-side, transparent 0 39%, #000 39.5% 96%, transparent 96.6%);
}

.record__label {
	position: absolute;
	left: 33%;
	top: 33%;
	width: 34%;
	height: 34%;
	display: grid;
	place-items: center;
	overflow: hidden;
	border-radius: 50%;
	background: radial-gradient(circle, #f4f4f1 0 55%, #e8e8e4 100%);
	box-shadow: 0 0 0 1px rgb(0 0 0 / .6), inset 0 0 0 1px rgb(0 0 0 / .08);
}
.record__art {
	position: absolute;
	inset: 0;
	background: center / cover no-repeat;
	opacity: 0;
	transition: opacity .6s ease;
}
.record__art.is-loaded { opacity: .94; }
/* Printed on paper, not on glass */
.record__art::after {
	content: "";
	position: absolute;
	inset: 0;
	background-image: var(--grain);
	background-size: 120px;
	opacity: .3;
	mix-blend-mode: overlay;
}
/* Spindle marks, and a label that has gone a little grubby at the edge */
.record__label::before {
	content: "";
	position: absolute;
	z-index: 1;
	inset: 0;
	border-radius: 50%;
	background:
		var(--spindle) center / 100% 100% no-repeat,
		radial-gradient(circle closest-side, transparent 78%, rgb(60 48 30 / .16) 97%, rgb(30 24 16 / .3));
	mix-blend-mode: multiply;
	pointer-events: none;
}
.record__label::after {
	content: "";
	position: absolute;
	z-index: 2;
	left: 50%;
	top: 50%;
	width: 7%;
	height: 7%;
	translate: -50% -50%;
	border-radius: 50%;
	background: #141519;
	box-shadow: inset 0 1px 2px rgb(0 0 0 / .9), 0 0 0 1px rgb(255 255 255 / .12);
}
.record__label-text {
	display: grid;
	gap: calc(var(--s) * .07);
	text-align: center;
	text-transform: uppercase;
	color: #8d9298;
}
.record__label-text b { font: 400 calc(var(--s) * .024)/1 var(--sleeve-font); }
.record__label-text i { font: 400 calc(var(--s) * .011)/1 var(--sleeve-font); letter-spacing: .12em; }

/* The bonus disc label, only for people who pull the record all the way out */
.record__secret { display: none; position: absolute; inset: 0; width: 100%; height: 100%; }
.record__secret-rim { fill: none; stroke: var(--paper-accent); stroke-width: 1.4; }
.record__secret text {
	fill: var(--paper-ink);
	font: 700 6.4px var(--font);
	font-stretch: 85%;
	letter-spacing: .04em;
}
.record__secret .record__secret-mid {
	fill: var(--paper-accent);
	font-size: 8px;
	font-weight: 800;
	font-stretch: 125%;
	letter-spacing: .12em;
	text-anchor: middle;
}
.record__secret:not([data-kind="album"]) image,
.record__secret[data-kind="album"] .record__secret-mid { display: none; }
.stage.is-secret .record__label { background: var(--paper); }
.stage.is-secret .record__label-text,
.stage.is-secret .record__art { visibility: hidden; }
.stage.is-secret .record__secret { display: block; }
.stage.is-secret .sticker { --sticker: #f6cf45; }

.confetti { position: fixed; inset: 0; z-index: 10; width: 100%; height: 100%; pointer-events: none; }

.record__sheen {
	position: absolute;
	inset: 0;
	border-radius: 50%;
	pointer-events: none;
	background: conic-gradient(from 210deg, transparent 0deg, rgb(255 255 255 / .1) 22deg, transparent 48deg 180deg, rgb(255 255 255 / .08) 202deg, transparent 228deg);
	mix-blend-mode: screen;
}

/* The sleeve */

.sleeve {
	position: absolute;
	z-index: 2;
	left: 0;
	top: 0;
	width: var(--s);
	height: var(--s);
	perspective: 2400px;
	container-type: size;
}

.sleeve__inner {
	position: absolute;
	inset: 0;
	transform-style: preserve-3d;
	transition: transform 1s var(--ease) var(--sleeve-delay, 0s);
}
.stage[data-side="back"] .sleeve__inner { transform: rotateY(-180deg); }
/* Hovering the label that turns it over starts to turn it, so you can see what it's going to do. */
.stage.is-peek .sleeve__inner { transform: rotateY(-15deg); transition-duration: .6s; }
.stage[data-side="back"].is-peek .sleeve__inner { transform: rotateY(-165deg); }
.front,
.back { transition: visibility 0s linear calc(var(--sleeve-delay, 0s) + .25s); }
.back,
.stage[data-side="back"] .front { visibility: hidden; }
.stage[data-side="back"] .back { visibility: visible; }

.face {
	position: absolute;
	inset: 0;
	overflow: hidden;
	border-radius: 2px;
	backface-visibility: hidden;
	-webkit-backface-visibility: hidden;
	box-shadow: 0 3cqi 7cqi -2cqi rgb(var(--shadow) / .6), 0 .4cqi 1cqi rgb(var(--shadow) / .35);
}

/* ---------- Both sides: cardboard that has been around ---------- */

/* Each sleeve says whether it's printed light or dark; wear shows up as grime on the one and as
   rubbed-off ink on the other. */
.face {
	--wear-ink: rgb(98 88 72);
	--wear-blend: multiply;
	--wear: .35;
	--age: .35;
}

.wear,
.wrap { position: absolute; inset: 0; pointer-events: none; }

/* Age spots and a dented corner */
.wear {
	background:
		linear-gradient(-48deg, transparent 49%, rgb(255 255 255 / .5) 49.7%, rgb(0 0 0 / .2) 50.3%, transparent 51.2%) 100% 0 / 9cqi 9cqi no-repeat,
		linear-gradient(-48deg, transparent 47%, rgb(0 0 0 / .05) 50%, transparent 50.1%) 100% 0 / 9cqi 9cqi no-repeat,
		var(--blotch) 0 0 / 520px;
	opacity: var(--age);
}
.wear::before,
.wear::after {
	content: "";
	position: absolute;
	inset: 0;
	opacity: var(--wear);
	mix-blend-mode: var(--wear-blend);
}
/* Ring wear: the record inside, pressed through the cardboard, rubbed in over the years */
.wear::before {
	--o: 50.6% 50.4%;
	background:
		repeating-radial-gradient(circle at var(--o), rgb(from var(--wear-ink) r g b / .32) 0 .3px, transparent .4px 1.7px),
		radial-gradient(circle at var(--o), transparent 45cqi, rgb(from var(--wear-ink) r g b / .7) 46.6cqi 47.4cqi, transparent 48.6cqi);
	-webkit-mask:
		radial-gradient(circle at var(--o), transparent 44.6cqi, #000 46.2cqi 47.8cqi, transparent 48.8cqi),
		conic-gradient(from 20deg at var(--o), #000, rgb(0 0 0 / .2) 70deg, rgb(0 0 0 / .65) 130deg, transparent 175deg, rgb(0 0 0 / .45) 225deg, #000 290deg, #000),
		var(--scuff) 0 0 / 160px;
	-webkit-mask-composite: source-in, source-in;
	mask:
		radial-gradient(circle at var(--o), transparent 44.6cqi, #000 46.2cqi 47.8cqi, transparent 48.8cqi),
		conic-gradient(from 20deg at var(--o), #000, rgb(0 0 0 / .2) 70deg, rgb(0 0 0 / .65) 130deg, transparent 175deg, rgb(0 0 0 / .45) 225deg, #000 290deg, #000),
		var(--scuff) 0 0 / 160px;
	mask-composite: intersect;
}
/* Frayed edges and soft, bumped corners */
.wear::after {
	background:
		radial-gradient(circle at 0 0, var(--wear-ink) 0 .6cqi, transparent 3.2cqi),
		radial-gradient(circle at 100% 0, var(--wear-ink) 0 .5cqi, transparent 2.4cqi),
		radial-gradient(circle at 0 100%, var(--wear-ink) 0 .7cqi, transparent 3.6cqi),
		radial-gradient(circle at 100% 100%, var(--wear-ink) 0 .6cqi, transparent 2.8cqi),
		linear-gradient(to right, var(--wear-ink), transparent .9cqi),
		linear-gradient(to left, var(--wear-ink), transparent .7cqi),
		linear-gradient(to bottom, var(--wear-ink), transparent .8cqi),
		linear-gradient(to top, var(--wear-ink), transparent 1cqi);
	-webkit-mask: var(--scuff) 40px 20px / 130px;
	mask: var(--scuff) 40px 20px / 130px;
}

/* The shrink-wrap: a sheen that follows the light. Its scratches only show where the light catches
   them, so they come and go as the sleeve tilts. */
.wrap {
	--band: linear-gradient(115deg, transparent 30%, rgb(0 0 0 / .4) 39%, #000 41.5%, rgb(0 0 0 / .25) 45%, transparent 52% 72%, rgb(0 0 0 / .4) 79%, transparent 84%);
	background: linear-gradient(115deg, transparent 30%, rgb(255 255 255 / .022) 39%, rgb(255 255 255 / .06) 41.5%, rgb(255 255 255 / .014) 45%, transparent 52% 72%, rgb(255 255 255 / .022) 79%, transparent 84%) var(--sheen, 50%) 50% / 230% 230%;
	mix-blend-mode: screen;
	transition: background-position .9s var(--ease);
}
.wrap::before {
	content: "";
	position: absolute;
	inset: 0;
	background: url(../images/wrap-scratches.svg) 0 0 / 100% 100% no-repeat;
	opacity: .55;
	-webkit-mask: var(--band) var(--sheen, 50%) 50% / 230% 230%;
	mask: var(--band) var(--sheen, 50%) 50% / 230% 230%;
	transition: -webkit-mask-position .9s var(--ease), mask-position .9s var(--ease);
}
.back .wrap { transform: scaleX(-1); }

/* ---------- Front cover ---------- */

.front { background: var(--cover, #f5f6f7); color: #1a1a1a; }
.front__photo,
.front__art { position: absolute; inset: 0; pointer-events: none; }
.front__photo { overflow: hidden; isolation: isolate; }
.front__img {
	position: absolute;
	inset: var(--photo-bleed, 0);
	background: url(../images/bg.jpg) var(--photo-pos, 50% 64%) / var(--photo-size, cover) no-repeat;
	filter: var(--photo-filter, none);
	transform: var(--photo-turn, none);
}
/* Some sleeves colour the light by where it falls rather than how bright it is */
.front__photo::before { content: ""; position: absolute; z-index: 1; inset: 0; background: var(--tone-light, transparent); mix-blend-mode: multiply; }
/* Whatever the sleeve adds on top of the photo, and the grain of the print */
.front__art::before,
.front__art::after { content: ""; position: absolute; inset: 0; }
.front__art::before {
	background-image: var(--art, none);
	background-position: center;
	background-size: cover;
	background-repeat: no-repeat;
	mix-blend-mode: var(--art-blend, normal);
}
.front__art::after {
	background-image: var(--grain);
	opacity: var(--grain-o, .16);
	mix-blend-mode: overlay;
}

.front__type {
	position: absolute;
	left: 6.5cqi;
	right: 6cqi;
	top: 17cqi;
	color: #fff;
	font-family: var(--sleeve-font);
	text-transform: uppercase;
	white-space: nowrap;
}
.front__type h1 {
	font: 400 var(--title, 7cqi)/1 var(--sleeve-font);
	letter-spacing: -.005em;
}
.front__type h1::after { content: var(--stop, "."); }
.front__type p {
	margin-top: var(--sub-gap, .5cqi);
	font: 400 var(--sub, 2.4cqi)/1 var(--sleeve-font);
	letter-spacing: var(--sub-track, .01em);
}

.front__cat {
	display: none;
	position: absolute;
	left: 6.5cqi;
	bottom: 5.2cqi;
	font: 400 1.9cqi/1 var(--sleeve-font);
	letter-spacing: .2em;
	color: rgb(136 141 148 / .8);
}

/* The hype sticker */

.sticker {
	position: absolute;
	right: 6cqi;
	bottom: 6.5cqi;
	width: 30cqi;
	height: 30cqi;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 1cqi;
	padding: 3.6cqi;
	border-radius: 50%;
	background:
		/* the lower edge has started to come away and catches the lamp */
		linear-gradient(140deg, transparent 72%, rgb(255 255 255 / .16) 84%, rgb(255 255 255 / .3) 94%),
		linear-gradient(160deg, rgb(255 255 255 / .14), transparent 45%, rgb(0 0 0 / .05)),
		var(--sticker);
	color: #16130f;
	text-align: center;
	rotate: 8deg;
	/* a die-cut edge catching the light, grime along the rim, and a contact shadow that is a little
	   deeper where the sticker no longer lies flat */
	box-shadow:
		inset 0 0 0 .22cqi rgb(255 255 255 / .28),
		inset 0 0 1.2cqi rgb(70 50 20 / .22),
		0 .06cqi .1cqi rgb(0 0 0 / .32),
		0 .2cqi .5cqi -.1cqi rgb(0 0 0 / .12),
		.5cqi .7cqi .9cqi -.5cqi rgb(0 0 0 / .2);
}
.sticker::before,
.sticker::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: inherit;
	pointer-events: none;
}
/* ink rubbed off by thumbs and other records, mostly around the rim */
.sticker::before {
	background: rgb(255 253 246 / .6);
	-webkit-mask:
		radial-gradient(circle closest-side, transparent 70%, rgb(0 0 0 / .6) 88%, #000 97%),
		var(--speckle) 0 0 / 110px;
	-webkit-mask-composite: source-in;
	mask:
		radial-gradient(circle closest-side, transparent 70%, rgb(0 0 0 / .6) 88%, #000 97%),
		var(--speckle) 0 0 / 110px;
	mask-composite: intersect;
}
/* paper grain, printed over the ink */
.sticker::after {
	background-image: var(--grain);
	opacity: .22;
	mix-blend-mode: multiply;
}
.sticker.is-new { animation: slap .45s var(--ease); }

@keyframes slap {
	0%   { scale: 1.06; opacity: 0; rotate: 5deg; }
	100% { scale: 1; opacity: 1; rotate: 8deg; }
}

.sticker__top,
.sticker__foot {
	font: 700 max(7px, 1.75cqi)/1.15 var(--font);
	font-stretch: 85%;
	letter-spacing: .09em;
	text-transform: uppercase;
}
.sticker__foot { font-weight: 500; letter-spacing: .06em; }
.sticker__title {
	display: -webkit-box;
	-webkit-line-clamp: 4;
	-webkit-box-orient: vertical;
	overflow: hidden;
	font: 900 4.1cqi/.96 var(--font);
	font-stretch: 62%;
	text-transform: uppercase;
	overflow-wrap: anywhere;
}
.sticker__title[data-size="m"] { font-size: 3.4cqi; }
.sticker__title[data-size="s"] { font-size: 2.8cqi; }

.front__flip { position: absolute; inset: 0; cursor: pointer; }
.front__flip:disabled { cursor: default; }
.front__flip:focus-visible { outline-offset: -6px; }

/* ---------- Back cover: laid out like Silent Alarm's, whichever album it is ---------- */

.back {
	/* type sizes follow the sleeve, with a floor so a phone can still read them */
	--name: max(11px, 3.1cqi);
	--artist: max(8.5px, 1.55cqi);
	--head: max(8px, 1.6cqi);
	--fine: max(7px, 1.25cqi);

	transform: rotateY(180deg);
	display: grid;
	grid-template-rows: minmax(0, 1fr) auto;
	gap: 4cqi;
	padding: 6.5cqi 6.5cqi 5.5cqi;
	background: #f4f4f1;
	color: #1a1a1a;
	font-family: var(--sleeve-font);
}
.js .back { cursor: pointer; }
/* print grain over everything on the back, type included */
.back::after {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	background: radial-gradient(ellipse at 50% 40%, transparent 60%, rgb(60 60 50 / .12)), var(--grain);
	opacity: var(--grain-o, .35);
	mix-blend-mode: var(--grain-blend, multiply);
}

/* The same photo as the front, blurred until only its colours are left */
.back__art { position: absolute; inset: 0; overflow: hidden; isolation: isolate; pointer-events: none; }
.back__img {
	position: absolute;
	inset: -12cqi;
	background: var(--back-photo, none) var(--back-pos, 50% 50%) / var(--back-size, cover) no-repeat;
	filter: var(--back-filter, none);
}
.back__art::before,
.back__art::after { content: ""; position: absolute; z-index: 1; inset: 0; }
.back__art::before { background: var(--back-tone, transparent); mix-blend-mode: multiply; }
.back__art::after { background: var(--back-scrim, transparent); }

.sides,
.back__foot { position: relative; }

.sides {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 5cqi;
	min-height: 0;
	overflow: hidden;
}
.side { display: flex; flex-direction: column; min-width: 0; min-height: 0; }

.side h2 {
	margin-bottom: 2.6cqi;
	font: 400 var(--head)/1.2 var(--sleeve-font);
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--head-ink, #8f8f8b);
}

/* The list is spread over all the height the sleeve has */
.side ol {
	flex: 1;
	min-height: 0;
	list-style: none;
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	gap: 1.2cqi;
	counter-reset: track;
}
.side li {
	min-width: 0;
	counter-increment: track;
	/* --k runs from 0 (first) to 1 (last): mid grey at the top, black at the bottom */
	color: var(--row-ink, color-mix(in srgb, #141414 calc(42% + var(--k, 1) * 58%), #b4b4b0));
}
/* Long titles wrap onto a second line rather than being cut off */
.side li b {
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
	overflow: hidden;
	font: var(--name-style, normal) var(--name-weight, 400) var(--name)/1.08 var(--name-font, var(--sleeve-font));
	letter-spacing: .01em;
	text-transform: var(--case, uppercase);
	text-wrap: balance;
}
.side li i {
	display: block;
	margin-top: .35cqi;
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
	font: var(--name-style, normal) 400 var(--artist)/1.3 var(--name-font, var(--sleeve-font));
	letter-spacing: var(--artist-track, .07em);
	text-transform: var(--case, uppercase);
	color: var(--dim, #8d8d89);
}
.side .empty { color: var(--dim, #8d8d89); }

.back__foot {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	align-items: end;
	gap: 5cqi;
}
.fine {
	max-width: 54cqi;
	font: 400 var(--fine)/1.45 var(--sleeve-font);
	color: var(--fine-ink, #8a8a86);
}
.fine p + p { margin-top: .6em; }

.back__marks { display: flex; align-items: flex-end; gap: 3cqi; }
.back__logo {
	font: 400 max(8px, 2.1cqi)/1 var(--sleeve-font);
	letter-spacing: .04em;
	color: var(--fine-ink, #6f6f6b);
}
.barcode { width: 19cqi; text-align: center; color: #1a1a1a; }
.barcode svg { display: block; width: 100%; height: 7cqi; fill: currentColor; }
.barcode span {
	display: block;
	margin-top: .6cqi;
	font: 500 max(6.5px, 1.25cqi)/1 var(--font);
	letter-spacing: .1em;
	font-variant-numeric: tabular-nums;
	white-space: pre;
}

/* The dark sleeves: light type, and the barcode on its own white patch, as it would be at the printer */
:root:not([data-sleeve="silent-alarm"]) .back {
	--row-ink: currentColor;
	--dim: rgb(255 255 255 / .62);
	--head-ink: rgb(255 255 255 / .7);
	--fine-ink: rgb(255 255 255 / .6);
	--grain-o: .3;
	--grain-blend: overlay;
	--back-photo: url(../images/bg.jpg);
	color: #f7f4ee;
	text-shadow: 0 0 .8cqi rgb(0 0 0 / .25);
}
:root:not([data-sleeve="silent-alarm"]) .barcode {
	width: max(17cqi, 86px);
	padding: 1cqi 1.2cqi .8cqi;
	background: #f6f5f0;
	color: #111;
	text-shadow: none;
}

/* Rows and fine print follow the size of the sleeve, not the window */
@container (max-width: 440px) {
	.side li:nth-child(n + 7) { display: none; }
	.fine__legal, .fine__urls { display: none; }
}

/* ==========================================================================
   The sleeves: my photo printed in the colours of a Bloc Party album, with the
   type where that album has it
   ========================================================================== */

.tones { position: absolute; width: 0; height: 0; overflow: hidden; }

/* Every sleeve but Silent Alarm crops in on the photo, far enough that the edges stay out of sight */
:root:not([data-sleeve="silent-alarm"]) .front { --photo-bleed: -9.5cqi; }

/* ---------- Silent Alarm (2005): snow, haze and pale grey caps, top left ---------- */

[data-sleeve="silent-alarm"] .front {
	--cover: #f5f6f7;
	--photo-filter: grayscale(.8) brightness(2.35) contrast(.62);
	--art: radial-gradient(ellipse at 50% 42%, transparent 55%, rgb(80 86 94 / .14)),
		/* white sky above, snow below: the haze that makes it Silent Alarm */
		linear-gradient(#f5f6f7 0 25%, rgb(245 246 247 / .88) 29%, rgb(245 246 247 / .6) 33%, rgb(245 246 247 / .3) 38%, rgb(245 246 247 / .08) 44%, transparent 48% 56%, rgb(245 246 247 / .6) 72%, #f5f6f7 90%);
}
[data-sleeve="silent-alarm"] .front__art { box-shadow: inset 0 0 0 1px rgb(0 0 0 / .06), inset 0 0 2cqi rgb(0 0 0 / .05); }
[data-sleeve="silent-alarm"] .front__type {
	--title: 8.3cqi;
	--sub: 2.9cqi;
	--sub-gap: .9cqi;
	--sub-track: .02em;
	color: rgb(146 150 150 / .95);
}
[data-sleeve="silent-alarm"] .front__type p { padding-left: .3cqi; color: #9ea2a2; }
[data-sleeve="silent-alarm"] .front__cat { display: block; }
[data-sleeve="silent-alarm"] .face { --wear: .4; --age: .4; }
[data-sleeve="silent-alarm"] .back { --age: .22; }

/* ---------- A Weekend in the City (2007): sodium lamps, smeared sideways like a long exposure; type top left ---------- */

[data-sleeve="weekend"] .face { --wear-ink: rgb(236 228 208); --wear-blend: screen; --wear: .3; --age: .3; }
[data-sleeve="weekend"] .front {
	--cover: #0a0905;
	--grain-o: .3;
	--photo-filter: grayscale(1) brightness(2.9) contrast(1.6) url(#tone-weekend);
	--photo-size: auto 200%;
	--photo-pos: 22% 60%;
}
[data-sleeve="weekend"] .front__type { --title: 5.6cqi; --sub: 2.25cqi; left: 3.4cqi; top: 3.6cqi; text-shadow: 0 0 .6cqi rgb(0 0 0 / .4); }
[data-sleeve="weekend"] .back {
	--back-filter: grayscale(1) blur(6cqi) brightness(2.6) contrast(1.4) url(#tone-weekend);
	--back-size: auto 200%;
	--back-pos: 22% 60%;
	--back-scrim: linear-gradient(rgb(10 9 5 / .5), rgb(10 9 5 / .2) 70%, rgb(10 9 5 / .45));
	background: #0a0905;
}

/* ---------- Intimacy (2008): soft, pale pink, far too close to focus on; type dead centre ---------- */

[data-sleeve="intimacy"] .face { --wear-ink: rgb(96 76 78); --wear: .35; --age: .4; }
[data-sleeve="intimacy"] .front {
	--cover: #2a0f15;
	--grain-o: .22;
	--photo-filter: grayscale(1) blur(1.9cqi) brightness(2.9) contrast(1.6) url(#tone-intimacy);
	--photo-size: auto 380%;
	--photo-pos: 18% 46%;
	--photo-turn: rotate(90deg);
	/* a little shade behind the type, like the gap between the faces on the real cover */
	--art: radial-gradient(ellipse 58% 20% at 50% 46%, rgb(70 26 38 / .38), transparent);
}
[data-sleeve="intimacy"] .front__type { --title: 7.4cqi; --sub: 5.1cqi; --sub-gap: .4cqi; left: 0; right: 0; top: 40cqi; text-align: center; text-shadow: 0 0 2cqi rgb(60 20 30 / .35); }
[data-sleeve="intimacy"] .back {
	--back-filter: grayscale(1) blur(7cqi) brightness(2.6) contrast(1.3) url(#tone-intimacy-back);
	--back-size: auto 300%;
	--back-pos: 20% 50%;
	background: #3c464c;
}
[data-sleeve="intimacy"] .side li b::before { content: counter(track) ". "; }

/* ---------- Four (2012): black, and the light in the colours of the four rings; no title on the real one, so a small one here ---------- */

[data-sleeve="four"] .face { --wear-ink: rgb(240 236 228); --wear-blend: screen; --wear: .32; --age: .2; }
[data-sleeve="four"] .front {
	--cover: #070707;
	--grain-o: .3;
	--photo-filter: grayscale(1) blur(1.2cqi) brightness(3) contrast(1.4) url(#tone-four);
	--photo-size: auto 220%;
	--photo-pos: 20% 62%;
	--tone-light: radial-gradient(circle at 50% 50%, #6bb646 0 14%, #f1e33a 24% 30%, #34529f 40% 47%, #d2232a 58% 100%);
}
[data-sleeve="four"] .front__type { --title: 2.5cqi; --sub: 1.7cqi; --sub-gap: .7cqi; --sub-track: .06em; left: 4cqi; top: 4cqi; }
[data-sleeve="four"] .front__type p { opacity: .65; }
[data-sleeve="four"] .back {
	/* Four sets its tracklist in a bold italic serif, in title case */
	--name-font: Baskerville, "Baskerville Old Face", "Libre Baskerville", Georgia, serif;
	--name-style: italic;
	--name-weight: 700;
	--case: none;
	--artist-track: .02em;
	--name: max(12px, 3.3cqi);
	--artist: max(9px, 1.8cqi);
	--back-filter: grayscale(1) blur(6cqi) brightness(2.2) contrast(1.3) url(#tone-four);
	--back-size: auto 220%;
	--back-pos: 20% 62%;
	--back-tone: radial-gradient(circle at 50% 55%, #6bb646 0 14%, #f1e33a 24% 30%, #34529f 40% 47%, #d2232a 58% 100%);
	--back-scrim: rgb(7 7 7 / .5);
	background: #070707;
}

/* ---------- Hymns (2016): a band of light split into a spectrum, in a dark room; two words in the top corners ---------- */

[data-sleeve="hymns"] .face { --wear-ink: rgb(236 230 220); --wear-blend: screen; --wear: .28; --age: .2; }
[data-sleeve="hymns"] .front {
	--cover: #0d0b0a;
	--grain-o: .3;
	--photo-filter: grayscale(1) brightness(3.4) contrast(1.6) url(#tone-hymns);
	--photo-size: auto 260%;
	--photo-pos: 50% 66%;
	--tone-light: linear-gradient(100deg, #cfc8c2 0 25%, #9b8cff 34%, #6fd0ff 41%, #5bdc78 48%, #f7ef4f 55%, #ffad3a 62%, #ff5a3c 70%, #cfc8c2 80%);
}
[data-sleeve="hymns"] .front__type { --title: 2.75cqi; --sub: 2.75cqi; --stop: ""; left: 4.4cqi; right: 4.4cqi; top: 4.4cqi; display: flex; justify-content: space-between; align-items: baseline; }
[data-sleeve="hymns"] .front__type :is(h1, p) { margin: 0; letter-spacing: .03em; }
[data-sleeve="hymns"] .back {
	--back-filter: grayscale(1) blur(5cqi) brightness(2.8) contrast(1.4) url(#tone-hymns);
	--back-size: auto 260%;
	--back-pos: 50% 66%;
	--back-tone: linear-gradient(100deg, #cfc8c2 0 25%, #9b8cff 34%, #6fd0ff 41%, #5bdc78 48%, #f7ef4f 55%, #ffad3a 62%, #ff5a3c 70%, #cfc8c2 80%);
	--back-scrim: linear-gradient(rgb(13 11 10 / .55), rgb(13 11 10 / .35));
	background: #0d0b0a;
}

/* ---------- Alpha Games (2022): hot pink, blurred and sprayed on to near black; small caps bottom left ---------- */

[data-sleeve="alpha-games"] .face { --wear-ink: rgb(238 232 230); --wear-blend: screen; --wear: .3; --age: .2; }
[data-sleeve="alpha-games"] .front {
	--cover: #121318;
	--grain-o: .45;
	--photo-filter: grayscale(1) blur(2.1cqi) brightness(2.4) contrast(1.8) url(#tone-alpha);
	--photo-size: auto 220%;
	--photo-pos: 20% 62%;
}
[data-sleeve="alpha-games"] .front__type { --title: 2.45cqi; --sub: 2.45cqi; --sub-gap: .35cqi; --stop: ""; left: 4.4cqi; top: auto; bottom: 4.4cqi; }
[data-sleeve="alpha-games"] .back {
	/* numbered 01, 02… in title case */
	--case: none;
	--artist-track: .02em;
	--back-filter: grayscale(1) blur(6cqi) brightness(2.2) contrast(1.6) url(#tone-alpha);
	--back-size: auto 220%;
	--back-pos: 20% 62%;
	--back-scrim: linear-gradient(rgb(18 19 24 / .45), rgb(18 19 24 / .15) 60%, rgb(18 19 24 / .4));
	background: #121318;
}
[data-sleeve="alpha-games"] .side li b::before { content: counter(track, decimal-leading-zero) ".\2002"; }

/* ---------- Anatomy of a Brief Romance (2026): signal red and cream, grainy, upside down; type left of centre ---------- */

[data-sleeve="anatomy"] .face { --wear-ink: rgb(240 230 220); --wear-blend: screen; --wear: .3; --age: .25; }
[data-sleeve="anatomy"] .front {
	--cover: #140202;
	--grain-o: .5;
	--photo-filter: grayscale(1) blur(1.4cqi) brightness(2.8) contrast(1.6) url(#tone-anatomy);
	--photo-size: auto 420%;
	--photo-pos: 28% 58%;
	--photo-turn: rotate(180deg);
}
[data-sleeve="anatomy"] .front__type { --title: 5.4cqi; --sub: 1.6cqi; --sub-gap: 1.7cqi; --sub-track: .05em; left: 3.6cqi; top: 44cqi; text-shadow: 0 0 1cqi rgb(40 0 0 / .4); }
[data-sleeve="anatomy"] .back {
	--back-filter: grayscale(1) blur(6.5cqi) brightness(2.5) contrast(1.3) url(#tone-anatomy-back);
	--back-size: auto 260%;
	--back-pos: 60% 40%;
	--back-scrim: rgb(28 26 22 / .2);
	background: #3d3830;
	color: #fff8e8;
}

/* ---------- Deck: stitched leather tags, laser-engraved, lying on the desk ---------- */

.deck {
	width: var(--stage-w);
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 14px;
}

.tag {
	--leather: #3d2617;
	--stamp: #dcb98e;
	--thread: rgb(232 204 160 / .85);
	--tilt: -.6deg;
	--lift: 0px;
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: 8px;
	min-width: 0;
	max-width: 100%;
	height: 34px;
	padding: 1px 16px 0;
	border-radius: 3px;
	/* the engraving burns through the dye: lighter letters, sunk a little into the leather */
	color: var(--stamp);
	font: 600 12px/1 var(--sleeve-font);
	letter-spacing: .15em;
	text-transform: uppercase;
	white-space: nowrap;
	text-shadow: 0 -1px 0 rgb(0 0 0 / .6), 0 1px 0 rgb(255 228 196 / .14);
	/* full-grain leather: a soft sheen from the lamp over a pebbled surface */
	background:
		radial-gradient(120% 160% at 22% 0%, rgb(255 226 190 / .16), transparent 55%),
		var(--leather-grain) 0 0 / 120px,
		var(--leather);
	background-blend-mode: normal, overlay, normal;
	box-shadow:
		inset 0 0 0 1px rgb(18 9 3 / .6),
		inset 0 1px 0 1px rgb(255 222 184 / .08),
		inset 0 0 6px 1px rgb(15 8 3 / .5),
		0 1px 1px rgb(var(--shadow) / .6),
		0 calc(2px + var(--lift)) calc(4px + var(--lift) * 2) calc(-1px - var(--lift) * .2) rgb(var(--shadow) / .5);
	rotate: var(--tilt);
	translate: 0 calc(var(--lift) * -1);
	transition: translate .25s var(--ease), rotate .35s var(--ease), box-shadow .25s var(--ease), background-color .8s;
}
/* stitched all the way round, a few millimetres in from the edge */
.tag::before {
	content: "";
	position: absolute;
	inset: 4px 5px;
	pointer-events: none;
	background:
		repeating-linear-gradient(90deg, var(--thread) 0 4px, transparent 4px 7px) 0 0 / 100% 1.5px no-repeat,
		repeating-linear-gradient(90deg, var(--thread) 0 4px, transparent 4px 7px) 0 100% / 100% 1.5px no-repeat,
		repeating-linear-gradient(var(--thread) 0 4px, transparent 4px 7px) 0 0 / 1.5px 100% no-repeat,
		repeating-linear-gradient(var(--thread) 0 4px, transparent 4px 7px) 100% 0 / 1.5px 100% no-repeat;
	filter: drop-shadow(0 1px 0 rgb(0 0 0 / .55));
	opacity: .9;
}
.tag__text { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.tag__icon { display: inline-block; font: 400 16px/1 var(--font); letter-spacing: 0; transition: rotate .8s var(--ease); }

/* Tags you can use lift a little when you go near them, and press flat when you do */
:is(a, button).tag { cursor: pointer; }
:is(a, button).tag:hover,
:is(a, button).tag:focus-visible { --lift: 2px; rotate: calc(var(--tilt) * .4); }
:is(a, button).tag:active { --lift: -.5px; transition-duration: .06s; }
.tag:focus-visible { outline: 2px solid var(--ink); outline-offset: 4px; }

.tag--flip { --tilt: -1.4deg; }
.tag--flip:hover .tag__icon,
.stage:has(.front__flip:hover) + .deck .tag__icon { rotate: -40deg; }
.stage[data-side="back"] + .deck .tag--flip .tag__icon { rotate: -180deg; }
.stage[data-side="back"] + .deck .tag--flip:hover .tag__icon { rotate: -220deg; }
/* Hovering the sleeve points at the tag that does the same thing */
.stage:has(.front__flip:not(:disabled):hover) + .deck .tag--flip,
.stage:has(.back:hover) + .deck .tag--flip { --lift: 2px; rotate: calc(var(--tilt) * .4); }

.tag--status { --tilt: .5deg; flex: 0 1 auto; max-width: min(100%, 380px); }
/* While I'm listening it's an oxblood tag */
.tag--status.is-live { --leather: #4a1511; --stamp: #ecc2a4; }
.status__eq { display: none; flex: none; align-items: flex-end; gap: 2px; height: 10px; }
.tag--status.is-live .status__eq { display: inline-flex; }
.status__eq i {
	width: 3px;
	height: 100%;
	border-radius: 1px;
	background: var(--stamp);
	box-shadow: 0 -1px 0 rgb(0 0 0 / .5);
	transform-origin: bottom;
	animation: eq .9s ease-in-out infinite alternate;
}
.status__eq i:nth-child(2) { animation-duration: .7s; animation-delay: -.3s; }
.status__eq i:nth-child(3) { animation-duration: 1.1s; animation-delay: -.6s; }

@keyframes eq {
	from { scale: 1 .25; }
	to   { scale: 1 1; }
}

.links { display: flex; flex-wrap: wrap; gap: 10px; margin-left: auto; }
.links .tag { height: 32px; padding-inline: 14px; }
.links .tag:nth-child(1) { --tilt: -.9deg; }
.links .tag:nth-child(2) { --tilt: .6deg; }
.links .tag:nth-child(3) { --tilt: -.3deg; }
.links .tag:nth-child(4) { --tilt: 1deg; }
.links .tag:nth-child(5) { --tilt: -.6deg; }

/* ---------- Tea: brought over while you read the back ---------- */

.tea {
	/* in the record's spot: right of the sleeve here, above it on a phone. A 12 cm cup next to a
	   31 cm sleeve. */
	--size: calc(var(--s) * .58);
	--cup: url(../images/tea-matcha.svg);
	position: absolute;
	z-index: 0;
	left: calc(var(--s) * 1.39 - var(--size) / 2);
	top: calc(var(--s) * .5 - var(--size) / 2);
	width: var(--size);
	height: var(--size);
	pointer-events: none;
	visibility: hidden;
	opacity: 0;
	/* held a little above the desk and off to the side, then set down */
	translate: calc(var(--s) * .2) calc(var(--s) * -.06);
	rotate: 42deg;
	scale: 1.1;
	transition: translate .5s cubic-bezier(.5, 0, .75, .3), rotate .5s ease-in, scale .5s ease-in, opacity .3s linear .2s, visibility 0s linear .5s;
}
.tea[data-tea="chai"] { --cup: url(../images/tea-chai.svg); }
.stage.has-tea .tea {
	visibility: visible;
	opacity: 1;
	translate: 0 0;
	rotate: 14deg;
	scale: 1;
	transition: translate 1.1s cubic-bezier(.16, .84, .3, 1), rotate 1.3s cubic-bezier(.16, .84, .3, 1), scale 1.1s cubic-bezier(.3, .6, .3, 1), opacity .35s linear, visibility 0s;
}
.tea__cup {
	position: absolute;
	inset: 0;
	background: var(--cup) center / contain no-repeat;
	/* resting on the desk: a tight contact shadow and a soft one from the lamp */
	filter:
		drop-shadow(0 calc(var(--s) * .004) calc(var(--s) * .005) rgb(var(--shadow) / .6))
		drop-shadow(calc(var(--s) * .008) calc(var(--s) * .03) calc(var(--s) * .03) rgb(var(--shadow) / .5));
}

/* Steam, seen from above: a warm haze that drifts over the cup */
.tea__steam { position: absolute; inset: 24%; border-radius: 50%; pointer-events: none; mix-blend-mode: screen; }
.tea__steam i {
	position: absolute;
	inset: 0;
	border-radius: 50%;
	background:
		radial-gradient(closest-side at 38% 44%, rgb(255 255 255 / .5), transparent),
		radial-gradient(closest-side at 66% 62%, rgb(255 255 255 / .35), transparent);
	filter: blur(calc(var(--s) * .025));
	opacity: 0;
}
.stage.has-tea .tea__steam i { animation: steam 7s ease-in-out 1s infinite; }
.stage.has-tea .tea__steam i:nth-child(2) { animation-duration: 8.5s; animation-delay: 4.5s; }

@keyframes steam {
	0%   { opacity: 0; scale: .7; rotate: 0deg; translate: 0 0; }
	40%  { opacity: .5; }
	100% { opacity: 0; scale: 1.3; rotate: 80deg; translate: -8% -12%; }
}

/* ---------- Portrait: the record slides out of the top ---------- */

@media (max-aspect-ratio: 1/1) {
	.page {
		--s: min(calc(100vw - 2 * var(--pad)), calc((100svh - 150px) / 1.66), 560px);
		--stage-w: var(--s);
		--stage-h: calc(var(--s) * 1.66);
		place-content: start center;
		padding-top: max(var(--pad), 4svh);
	}
	.stage { --ax: 0; --ay: -1; }
	:root.is-live .stage { --out: calc(var(--s) * .74); }
	.stage.is-secret { --pull: calc(var(--s) * .05); }
	.sleeve { top: calc(var(--s) * .66); }
	.record { top: calc(var(--s) * .685); touch-action: pan-x; }
	.tea { --size: calc(var(--s) * .62); left: calc(var(--s) * .5 - var(--size) / 2); top: calc(var(--s) * .33 - var(--size) / 2); translate: calc(var(--s) * .14) calc(var(--s) * -.08); }
	.links { margin-left: 0; }
}

@media (prefers-reduced-motion: reduce) {
	:root { transition: none; }
	*, *::before, *::after { animation: none !important; transition: none !important; }
}
