/*
 * Coming-soon page, design 3B ("bordoo, ühtne font").
 * Mobile first (artboard 390×844); desktop layout (artboard 1440×900) from 1100px wide on
 * landscape screens. The media query must match the <source media> in templates/landing.php.
 */

:root {
	--cs-text: #f3efe7;
	--cs-accent: #e6b7bf;
	--cs-muted: #d3dbd8;
	--cs-label: #b3c0bb;
	--cs-small: #93a39e;
	--cs-placeholder: #7f8f8a;
	--cs-button: #8a1c32;
	--cs-button-hover: #a0223c;
	--cs-error: #f7c8cf;
	--cs-bg: #031210;
	--cs-serif: "garamond-premier-pro-display", Garamond, Georgia, serif; /* Adobe Fonts, see coming-soon.php */
	--cs-sans: "Gilroy", system-ui, -apple-system, "Segoe UI", sans-serif;
}

*,
*::before,
*::after {
	box-sizing: border-box;
}

html,
body {
	margin: 0;
}

body {
	background: var(--cs-bg);
	color: var(--cs-text);
	font-family: var(--cs-sans);
	font-weight: 300;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	text-rendering: optimizeLegibility;
}

a {
	color: var(--cs-text);
}

a:hover {
	color: var(--cs-accent);
}

:focus-visible {
	outline: 2px solid var(--cs-accent);
	outline-offset: 3px;
}

/* ---------- Mobile (default) ---------- */

.cs-page {
	position: relative;
	display: flex;
	flex-direction: column;
	min-height: 100vh;
	min-height: 100svh;
	overflow: hidden;
	background: var(--cs-bg);
}

.cs-photo {
	display: block;
	position: relative;
	width: 100%;
	max-width: 600px;
	max-height: 78vh;
	max-height: 78svh;
	margin: 0 auto;
	aspect-ratio: 390 / 600;
	-webkit-mask-image: linear-gradient(180deg, #000 0%, #000 68%, transparent 100%);
	mask-image: linear-gradient(180deg, #000 0%, #000 68%, transparent 100%);
}

.cs-photo img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: 50% 0;
}

.cs-header {
	position: absolute;
	z-index: 2;
	top: 14px;
	right: 10px;
	left: 20px;
	display: flex;
	align-items: center;
	justify-content: space-between;
}

.cs-logo {
	display: block;
}

.cs-logo img {
	display: block;
	width: 104px;
	height: auto;
}

/* Baseline-aligned: Light and ExtraBold have different line metrics (ascent 913 vs 955), so
   box-aligned links put the bold one lower on some systems (macOS). Same cap height, so on a
   shared baseline the letters line up exactly. */
.cs-lang {
	display: flex;
	align-items: baseline;
	font-size: 12px;
	letter-spacing: 0.14em;
}

.cs-lang a {
	min-width: 44px;
	padding: 14px 10px;
	color: var(--cs-muted);
	text-align: center;
	text-decoration: none;
}

.cs-lang a[aria-current] {
	color: var(--cs-text);
	font-weight: 800;
}

.cs-lang a:hover {
	color: var(--cs-accent);
}

.cs-content {
	position: relative;
	z-index: 1;
	display: flex;
	flex: 1 0 auto; /* Fill down to the bottom of the screen ... */
	align-items: flex-end; /* ... and sit the card there, as in the mobile artboard. */
	justify-content: center;
	/* How far the card may reach up over the photo on short screens. */
	margin: calc(-1 * min(64vw, 300px)) 12px 12px;
}

.cs-card {
	--cs-card-gap: 20px; /* Between the text and the form. */
	--cs-consent-gap: 14px; /* Above the consent text. */
	display: flex;
	flex-direction: column;
	gap: var(--cs-card-gap);
	width: 100%;
	max-width: 520px;
	padding: 28px 24px 24px;
	background: rgba(3, 18, 16, 0.78);
	-webkit-backdrop-filter: blur(18px);
	backdrop-filter: blur(18px);
	border: 1px solid rgba(243, 239, 231, 0.14);
	border-radius: 18px;
}

.cs-text {
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.cs-heading {
	margin: 0;
	font-family: var(--cs-serif);
	font-size: 31px;
	font-weight: 400;
	line-height: 1.12;
	color: var(--cs-text);
}

/* Adobe's Garamond Premier Pro Display has taller vertical metrics (ascent 848, descent 306 per
   1000, measured in Chrome) than the self-hosted file the design was tuned with (1485/563 per
   2048), which puts its baseline 0.046em lower in the same line box. Move serif text back up so
   it sits exactly where it did. Visual only: the layout does not change. */
.cs-heading,
.cs-doc-title,
.cs-doc-content h2,
.cs-doc-content h3 {
	position: relative;
	top: -0.046em;
}

.cs-accent {
	color: var(--cs-accent);
}

.cs-intro {
	margin: 0;
	font-size: 15px;
	line-height: 1.5;
	color: var(--cs-muted);
}

/* Ticket link at the end of the intro: same size and weight as the intro text, in the heading's
   pink. nowrap keeps the text and arrow together; when it does not fit, the whole link moves to
   the next line. */
.cs-intro-link,
.cs-intro-link:hover {
	color: var(--cs-accent);
}

.cs-intro-link {
	white-space: nowrap;
	text-decoration-line: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.2em;
	transition: text-decoration-thickness 0.15s ease;
}

.cs-intro-link:hover,
.cs-intro-link:focus-visible {
	text-decoration-thickness: 2px;
}

/* The gap before the arrow is a margin, not a space, so the underline ends with the text. */
.cs-intro-arrow {
	display: inline-block; /* So it can move; not underlined. */
	margin-left: 0.3em;
	transition: transform 0.15s ease;
}

.cs-intro-link:hover .cs-intro-arrow,
.cs-intro-link:focus-visible .cs-intro-arrow {
	transform: translateX(3px);
}

/* Read by screen readers, not shown. */
.cs-sr-only {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/*
 * The form is a grid with a fixed slot for messages right under the field (on phones between the
 * field and the button), so an error never moves anything. The success message takes the place
 * of the label, field and button, which stay in the layout, just invisible: the card keeps its
 * height. Rows on phones: label, field, message slot, button, consent.
 */
.cs-form {
	--cs-msg-slot: 26px; /* 6px space + one 20px line. */
	display: grid;
	grid-template-rows: auto auto var(--cs-msg-slot) auto auto;
	grid-template-columns: minmax(0, 1fr);
}

/* One column for everything (on phones the field and button are grid items too): without this
   the success message, which shares the other rows, would get a column of its own. */
.cs-form > *,
.cs-row > * {
	grid-column: 1;
}

.cs-label {
	grid-row: 1;
	margin-bottom: 10px;
	font-size: 13px;
	letter-spacing: 0.03em;
	color: var(--cs-label);
}

/* On phones the field and button are rows of the form grid themselves (message between them). */
.cs-row {
	display: contents;
}


.cs-input {
	grid-row: 2;
	width: 100%;
	min-width: 0;
	height: 52px;
	padding: 0 16px;
	font: inherit;
	font-size: 16px; /* 16px stops iOS from zooming in on focus. */
	color: var(--cs-text);
	background: rgba(2, 14, 12, 0.6);
	border: 1px solid rgba(243, 239, 231, 0.28);
	border-radius: 10px;
	-webkit-appearance: none;
	appearance: none;
}

.cs-input::placeholder {
	color: var(--cs-placeholder);
	opacity: 1;
}

/* No outline ring on the field: focus shows as a brighter border instead (still visible for
   keyboard users). */
.cs-input:focus,
.cs-input:focus-visible {
	border-color: rgba(243, 239, 231, 0.7);
	outline: none;
}

.cs-button {
	grid-row: 4;
	height: 52px;
	margin-top: 6px;
	padding: 0 28px;
	font: inherit;
	font-size: 13px;
	font-weight: 800;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--cs-text);
	background: var(--cs-button);
	border: 0;
	border-radius: 10px;
	cursor: pointer;
	transition: background-color 0.15s ease;
}

.cs-button:hover {
	background: var(--cs-button-hover);
}

.cs-button:disabled {
	cursor: progress;
	opacity: 0.7;
}

.cs-status {
	grid-row: 3;
	align-self: end;
	margin: 0;
	font-size: 13px;
	line-height: 20px;
}

.cs-status:empty {
	display: none;
}

.cs-status.is-ok {
	font-size: 15px;
	line-height: 1.5;
	color: var(--cs-accent);
}

.cs-status.is-error {
	color: var(--cs-error);
}

.cs-input[aria-invalid="true"],
.cs-input[aria-invalid="true"]:focus {
	border-color: var(--cs-error);
}

.cs-form.is-done .cs-label,
.cs-form.is-done .cs-row {
	visibility: hidden; /* Keeps their space; also hides them from keyboard and screen readers. */
}

/* In the space the label and field leave, with equal space above (to the intro) and below (to
   the consent text): centred, then raised by half the difference between the two gaps. */
.cs-form.is-done .cs-status {
	grid-row: 1 / 5;
	align-self: center;
	margin: 0 0 calc(var(--cs-card-gap) - var(--cs-consent-gap));
}

.cs-consent {
	grid-row: 5;
	margin: var(--cs-consent-gap) 0 0;
	font-size: 12px;
	line-height: 1.5;
	color: var(--cs-small);
}

/* Honeypot: invisible to people, filled in by bots. */
.cs-hp {
	position: absolute !important;
	left: -10000px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

/* Only used by the desktop layout. */
.cs-backdrop-left {
	display: none;
}

/*
 * Tablets (wider than a phone, not the desktop layout): a wider crop (silvia-tablet-*.jpg, same
 * height band as the phone crop, centred on her) fills the screen width with the photo's real
 * backdrop, so there are no side fades. Same height as the phone photo at its 600px maximum, so
 * she is the same size and the card sits where it did. The desktop rules override all of this.
 */
@media (min-width: 601px) {
	.cs-photo {
		max-width: none;
		height: min(calc(600px * 600 / 390), 78vh);
		height: min(calc(600px * 600 / 390), 78svh);
		aspect-ratio: auto;
	}
}

/* ---------- Desktop ---------- */

@media (min-width: 1100px) and (min-aspect-ratio: 7/5) {

	.cs-page {
		--cs-text-left: max(57.64vw, calc(10.42vw + 66.67vh + 40px));
		display: block;
		isolation: isolate;
		/*
		 * Right of the photo: continue the photo's own backdrop instead of switching to the design
		 * gradient. The top follows the colours sampled from the photo's right edge; the
		 * wall-to-floor change runs over 72-100% height (softer than in the photo, and starting about
		 * where the photo's dark area beside her ends). It darkens steadily from the photo's edge
		 * towards the right of the screen, so there is no darker trough between photo and text.
		 * These colours start under the photo already (from 16% of its width, where it is fully
		 * visible), so the space behind it matches the photo while it loads; the darkening
		 * starts at the photo's edge.
		 *
		 * The photo's last 20% already fades into exactly these colours in the image files (built by
		 * tools/coming-soon-images.py, which reads --cs-cont-backdrop from this file), so the photo
		 * needs no right-side mask: a CSS mask made Chrome round the faded pixels down and left a
		 * faint vertical line where the photo's box ends. Change these colours -> rebuild the images.
		 */
		--cs-cont-backdrop: linear-gradient(180deg, #030c09 0%, #05100c 10%, #05110e 20%, #05110f 30%, #05120f 45%, #041311 67%, #031311 72%, #031513 75.5%, #031c19 79%, #022521 82.5%, #02302a 86%, #023b33 89.5%, #01443b 93%, #014b41 96.5%, #014d43 100%);
		background:
			linear-gradient(90deg, rgba(4, 13, 11, 0), rgba(4, 13, 11, 0.6)) right top / calc(100% - 10.42vw - 66.67vh) 100% no-repeat,
			var(--cs-cont-backdrop) right top / calc(100% - 10.42vw - 66.67vh * 0.16) 100% no-repeat,
			linear-gradient(180deg, rgba(1, 77, 67, 0) 74%, rgba(1, 77, 67, 0.85) 100%),
			linear-gradient(90deg, #00231d 0%, #002b24 14%, #0a1b17 52%, #040d0b 100%);
	}

	/*
	 * Left of the photo: the same idea. Starts under the photo's fade-in zone (its first 16%) in
	 * the photo's colours where it becomes fully visible (16% in, sampled top to bottom;
	 * 65-70% interpolated, the sample there caught the cello's edge) and fades
	 * into the design gradient towards the left of the screen, so there is no kink at the edge.
	 */
	.cs-backdrop-left {
		display: block;
		position: absolute;
		z-index: 0;
		top: 0;
		bottom: 0;
		left: 0;
		width: calc(10.42vw + 66.67vh * 0.8);
		background: linear-gradient(180deg, #011513 0%, #001f1a 10%, #002520 20%, #002b24 30%, #002d27 40%, #012e28 50%, #012f29 60%, #01312b 65%, #01332d 70%, #01352e 75%, #01362f 80%, #021b17 85%, #02312a 90%, #015347 95%, #015246 100%);
		/* Under the photo (hidden once it has loaded) it fades into the right-hand colours, so
		   the space behind the photo has no edges while the photo loads. */
		-webkit-mask-image: linear-gradient(90deg, transparent 0, #000 10.42vw, #000 calc(10.42vw + 66.67vh * 0.16), transparent 100%);
		mask-image: linear-gradient(90deg, transparent 0, #000 10.42vw, #000 calc(10.42vw + 66.67vh * 0.16), transparent 100%);
		pointer-events: none;
	}

	/* Fine grain over the background and the photo (not the text), matched to the photo's own
	   grain on screen (~0.8 levels, same in dark and light areas): dithers the gradients so they
	   cannot band. It lifts what it covers by about one level, by a different amount per device
	   (0.5 in headless Chrome, 1.2 on a Retina Mac), so it covers the photo too: with the grain
	   only on the background, the photo's edge showed as a faint vertical line on some screens.
	   On the photo it adds a little to the photo's own grain, which is invisible. */
	.cs-page::after {
		content: "";
		position: absolute;
		z-index: 1; /* Same level as the photo but later in the page, so above it; below the text. */
		inset: 0;
		/* 256px tile shown at 128px: one grain dot per screen pixel on Retina, like the photo's. */
		background: url("../img/grain.png") 0 0 / 128px 128px;
		opacity: 0.0118; /* 3/255, the smallest step browsers render; x grain std 38 = the photo's grain on screen (~0.8 levels). */
		pointer-events: none;
	}

	.cs-photo {
		position: absolute;
		z-index: 1;
		top: 0;
		left: 10.42vw;
		width: auto;
		max-width: none;
		height: 100%;
		max-height: none;
		margin: 0;
		aspect-ratio: 2 / 3;
		-webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 16%);
		-webkit-mask-composite: source-over;
		mask-image: linear-gradient(90deg, transparent 0%, #000 16%);
		mask-composite: add;
	}

	.cs-header {
		z-index: 3; /* Above .cs-content, which fills the screen at z-index 2. */
		top: 28px;
		right: 56px;
		left: 56px;
		align-items: flex-start;
	}

	.cs-logo {
		margin-top: 12px;
	}

	.cs-logo img {
		width: 140px;
	}

	.cs-lang {
		gap: 4px;
		font-size: 13px;
	}

	.cs-lang a {
		min-width: 0;
		padding: 12px 10px;
		color: #a3b2ad;
	}

	.cs-content {
		z-index: 2; /* Above the grain layer (.cs-page::after). */
		align-items: center;
		justify-content: flex-start;
		min-height: 100vh;
		min-height: 100svh;
		margin: 0;
		padding: 100px 56px 100px var(--cs-text-left); /* Symmetric: centred like the artboard. */
	}

	.cs-card {
		--cs-card-gap: 36px;
		--cs-consent-gap: 8px; /* After the 28px message slot. */
		width: min(clamp(420px, 33.34vw, 560px), calc(100vw - var(--cs-text-left) - 56px));
		max-width: none;
		padding: 0;
		background: none;
		-webkit-backdrop-filter: none;
		backdrop-filter: none;
		border: 0;
		border-radius: 0;
	}

	.cs-text {
		gap: 18px;
	}

	.cs-heading {
		font-size: clamp(40px, 3.334vw, 56px);
		line-height: 1.1;
	}

	.cs-intro {
		max-width: 440px;
		font-size: 17px;
		line-height: 1.6;
	}

	/* Field and button side by side; the message slot is the row below them. */
	.cs-form {
		--cs-msg-slot: 28px; /* 8px space + one 20px line. */
		grid-template-rows: auto auto var(--cs-msg-slot) auto;
	}

	.cs-row {
		display: flex;
		grid-row: 2;
		flex-direction: row;
		gap: 10px;
	}

	.cs-form.is-done .cs-status {
		grid-row: 1 / 4;
	}

	.cs-input {
		flex: 1 1 auto;
		height: 54px;
		padding: 0 18px;
	}

	.cs-button {
		flex: none;
		height: 54px;
		margin-top: 0;
	}

	.cs-consent {
		grid-row: 4;
		font-size: 13px;
		line-height: 1.55;
	}
}

/* ---------- Policy pages (templates/document.php) ---------- */
/* They use the same .cs-header as the landing page, so the logo does not move. */

.cs-doc-body {
	position: relative;
	min-height: 100vh;
	background: linear-gradient(90deg, #00231d 0%, #0a1b17 52%, #040d0b 100%);
}

.cs-doc {
	max-width: 720px;
	margin: 0 auto;
	padding: 96px 20px 80px;
}

.cs-doc-title {
	margin: 0 0 24px;
	font-family: var(--cs-serif);
	font-size: clamp(32px, 5vw, 48px);
	font-weight: 400;
	line-height: 1.1;
}

.cs-doc-content {
	font-size: 17px;
	line-height: 1.6;
	color: var(--cs-muted);
}

.cs-doc-content h2,
.cs-doc-content h3 {
	font-family: var(--cs-serif);
	font-weight: 400;
	color: var(--cs-text);
}

.cs-doc-content h2 {
	margin: 40px 0 12px;
	font-size: 26px;
	line-height: 1.2;
}

.cs-doc-content ul,
.cs-doc-content ol {
	padding-left: 1.2em;
}

.cs-doc-content li + li {
	margin-top: 6px;
}

.cs-doc-content strong,
.cs-doc-content th {
	color: var(--cs-text);
}

.cs-doc-content a {
	color: var(--cs-text);
	text-underline-offset: 3px;
}

.cs-doc-content a:hover {
	color: var(--cs-accent);
}

/* Tables (the privacy policy has three): scroll sideways on narrow screens instead of squeezing. */
.cs-doc-content .wp-block-table {
	margin: 24px 0;
	overflow-x: auto;
}

.cs-doc-content table {
	width: 100%;
	min-width: 560px;
	font-size: 15px;
	line-height: 1.5;
	border-collapse: collapse;
}

.cs-doc-content th,
.cs-doc-content td {
	padding: 10px 16px 10px 0;
	text-align: left;
	vertical-align: top;
	border-bottom: 1px solid rgba(243, 239, 231, 0.14);
}

.cs-doc-content th {
	font-weight: 800;
	font-size: 13px;
	letter-spacing: 0.04em;
}

.cs-doc-back {
	margin-top: 48px;
	font-size: 15px;
}

@media (min-width: 1100px) and (min-aspect-ratio: 7/5) {

	.cs-doc {
		padding-top: 140px;
	}
}

/*
 * Page load: the photo fades in once it is loaded and decoded (not drawn in stages), the logo
 * and text once the fonts are ready (no flash of a fallback font). Only the card's contents
 * fade, not the card: a frosted-glass (backdrop-filter) box cannot blur while it is partly
 * transparent, so a fading card showed no glass and then snapped to frosted at the end.
 * The cs-* classes on <html> come from the small script in the page's <head>; without
 * JavaScript nothing is hidden. The cs-show animation is a safety net: it shows everything
 * after a few seconds whatever happens.
 */
.cs-js .cs-photo img {
	opacity: 0;
	transition: opacity 0.9s ease;
	animation: cs-show 0.3s ease 3s forwards;
}

.cs-js .cs-header,
.cs-js .cs-card > * {
	opacity: 0;
	transition: opacity 0.6s ease;
	animation: cs-show 0.3s ease 2s forwards;
}

/* animation: none once ready: a finished animation keeps the element on its own GPU layer,
   which draws the photo less sharply (measured) and text with coarser smoothing. */
.cs-photo-ready .cs-photo img,
.cs-fonts-ready .cs-header,
.cs-fonts-ready .cs-card > * {
	opacity: 1;
	animation: none;
}

@keyframes cs-show {

	to {
		opacity: 1;
	}
}

/* Arriving from our own site (e.g. the language switch, see the head script): the logo, and
   the photo when it is the same one, stay put; only the card's text fades in. An animation
   (not a transition) so it plays even when the fonts are ready at once; "backwards" so it does
   not stay applied when finished (see animation: none above). */
.cs-internal .cs-header,
.cs-photo-instant .cs-photo img {
	opacity: 1;
	transition: none;
	animation: none;
}

.cs-internal.cs-fonts-ready .cs-card > * {
	transition: none;
	animation: cs-in 0.5s ease backwards;
}

@keyframes cs-in {

	from {
		opacity: 0;
	}
}

@media (prefers-reduced-motion: reduce) {

	.cs-internal.cs-fonts-ready .cs-card > * {
		animation: none;
	}

	.cs-button,
	.cs-intro-link,
	.cs-intro-arrow,
	.cs-js .cs-photo img,
	.cs-js .cs-header,
	.cs-js .cs-card > * {
		transition: none;
	}

	.cs-intro-link:hover .cs-intro-arrow,
	.cs-intro-link:focus-visible .cs-intro-arrow {
		transform: none;
	}
}
