/* ==========================================================================
   Landing page - styles/landing.css

   Loaded only on the landing route (index.php links it when is_landing()), and
   kept out of mobbia.css on purpose: the home page is the one surface that can be
   rolled back by deleting a single <link>, with nothing else in the theme touched.

   The artwork is the client's own start-screen background. It is the page, so the
   rules here are mostly about not covering it: surfaces are translucent, the
   header floats over the image instead of sitting above it, and the status band
   the shell prints on every other route is suppressed rather than restated.

   Palette is lifted from the art and the client panels (teal-black, warm gold),
   not from mobbia.css's neutral ink, so the landing and the in-game client read as
   one product. The site behind keeps its own tokens.
   ========================================================================== */

:root {
	--landing-bg: url('../images/landing-bg.jpg');

	/* Sampled from the panels in the client and the bronze in the logo. */
	--landing-ink: #0a1a24;
	--landing-ink-2: #10242f;
	--landing-edge: #2c4a5c;
	--landing-gold: #e0b64d;
	--landing-gold-2: #f2d184;
	--landing-text: #eaf2f7;
	--landing-muted: #a8bccb;
	--landing-live: #4ec98a;
	--landing-down: #ef8f8f;
}

/* --- The page ground --------------------------------------------------- */

body.is-landing { background: var(--landing-ink); }

/* The illustration lives on the hero, not on the page. Painting it on .ledger-page
   scales it to cover the WHOLE document, so once the page grows past the fold the
   bottom of the artwork reappears below the panel band. Giving it a solid ground
   and letting only the hero carry the image makes "ends at the fold" structural
   instead of something the gradient has to cover up. */
.is-landing .ledger-page {
	background: var(--landing-ink);
	min-height: 100dvh;
}

.is-landing .ledger-main {
	position: relative;
	z-index: 1;
	max-width: none;
	padding: 0;
	display: block;
}

.is-landing .ledger-rule,
.is-landing .ledger-aside,
.is-landing .ledger-band { display: none; }

.is-landing .ledger-content { max-width: none; }

/* --- Header: floats over the artwork ------------------------------------ */

/* The shell's header is sticky and opaque; on the landing it would cut the image
   in half. Absolute + translucent keeps the artwork whole and still gives a
   readable bar, because the art behind it at that height is sky and castle. */
.is-landing .ledger-header {
	position: absolute;
	left: 0;
	right: 0;
	background: linear-gradient(to bottom, rgba(6, 14, 20, 0.88), rgba(6, 14, 20, 0.35));
	backdrop-filter: blur(4px);
	border-bottom: 1px solid var(--landing-edge);
}

.is-landing .ledger-brand img { height: 30px; }

/* The placeholder SVG mark is a 132x32 waypoint. On the landing the mark is the
   real one, so it is swapped in markup; this keeps the box from collapsing while
   that image decodes. */
.is-landing .ledger-nav a,
.is-landing .ledger-header a { color: var(--landing-muted); }
.is-landing .ledger-nav a:hover,
.is-landing .ledger-header a:hover { color: var(--landing-text); }

/* --- Hero -------------------------------------------------------------- */

.landing-hero {
	position: relative;
	z-index: 1;
	min-height: 100dvh;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 1.25rem;
	padding: 6rem var(--pad) 3rem;
	text-align: center;

	background-image: var(--landing-bg);
	background-size: cover;
	/* Biased right on purpose: the rider, the mage and the deer head are the
	   identity of the picture, and a centred crop cuts them off while keeping
	   more empty sky on the left. */
	background-position: 68% 42%;
	background-repeat: no-repeat;
}

/* Two scrims, because the art is bright at the top (sky and lightning), bright in
   the middle (the ship and the lit water) and dark at the bottom (rock). The
   tagline and the buttons land on the bright middle, so the lower scrim has to
   carry real weight or the copy sits unreadable over the water. */
.landing-hero::before,
.landing-hero::after {
	content: '';
	position: absolute;
	left: 0;
	right: 0;
	pointer-events: none;
	/* Explicit, because the particle canvas is also absolutely positioned and a
	   z-index:auto pseudo-element would otherwise win or lose on paint order rather
	   than on intent. The order is: artwork (the element's own background), balls,
	   scrims, copy. */
	z-index: 1;
}
.landing-hero::before {
	top: 0;
	height: 170px;
	background: linear-gradient(to bottom, rgba(6, 14, 20, 0.8), rgba(6, 14, 20, 0));
}
/* rgba(10,26,36) is --landing-ink spelled out. The scrim has to LAND on the same
   value the ground below the hero uses, or the hero's bottom edge shows as a seam
   across the page where the artwork stops. */
.landing-hero::after {
	bottom: 0;
	height: 68%;
	background: linear-gradient(
		to top,
		rgba(10, 26, 36, 1) 0%,
		rgba(10, 26, 36, 0.94) 26%,
		rgba(10, 26, 36, 0.62) 52%,
		rgba(10, 26, 36, 0.18) 78%,
		rgba(10, 26, 36, 0) 100%
	);
}

/* Layer order, all explicit because the three of them are absolutely positioned and
   z-index:auto would settle it on paint order rather than on intent:

     1  scrims      .landing-hero::before / ::after
     2  the balls   .landing-particles
     3  the copy    everything else in the hero

   The balls sit ABOVE the scrims and that is the whole design decision. Under them
   the effect is invisible: the lower scrim reaches full --landing-ink at the bottom
   and 68% of the hero's height, so most of the ~87 motes were hidden behind it and
   the field read as three or four stray specks. Above them they read as what they
   are in the client - atmosphere in the picture, which is the only place there is
   one, because the game has no scrim to compete with.

   They stay below the copy, so the wordmark, the tagline and the two tiles are never
   behind a mote. The hero's own lower scrim already puts the tagline on the darkest
   part of the ground, and the balls are 20px and sparse, so contrast is untouched;
   only the artwork between them changes. */
.landing-hero > :not(.landing-particles) { position: relative; z-index: 3; }

/* The client's UIParticles is `phantom: true` so the balls never swallow a click on
   the login fields. Same here: the canvas is decoration, so pointer-events:none is
   both the faithful port and the only way the tiles stay clickable. */
.landing-particles {
	position: absolute;
	inset: 0;
	z-index: 2;
	width: 100%;
	height: 100%;
	pointer-events: none;
}

.landing-hero__title {
	margin: 0;
	line-height: 0;
	/* The lockup and the plaque are stacked here rather than living in one flattened
	   PNG, so each is sized by its own rule (.landing-hero__mark / __banner). They used
	   to be a single image at width: min(560px, 84vw); both are half of that now - the
	   hero was carrying a 207px wordmark over a 350px row of plates, and the page read
	   as a poster rather than a way in. */
	gap: 0.5rem;
	display: flex;
	flex-direction: column;
	align-items: center;
}

/* A drop shadow, not a glow: the mark is already high-contrast stone, and the
   art behind it ranges from near-white sky to dark rock. */
.landing-hero__title img {
	height: auto;
	filter: drop-shadow(0 6px 24px rgba(0, 0, 0, 0.55));
}

/* The MOBBIA wordmark: was min(560px, 84vw), halved. */
.landing-hero__mark {
	width: min(280px, 42vw);
}

/* The ONLINE MMORPG plaque: same halving. It is 657px of artwork against the
   lockup's 720, so it keeps that 0.91 relationship rather than being given a size
   of its own - these two numbers are one number. */
.landing-hero__banner {
	width: min(256px, 38vw);
}

.landing-hero__tagline {
	max-width: 46ch;
	margin: 0;
	color: var(--landing-text);
	font-size: var(--step-1);
	text-shadow: 0 1px 10px rgba(0, 0, 0, 0.85);
}

.landing-hero__scroll {
	margin: 1.5rem 0 0;
	color: var(--landing-muted);
	font-family: var(--font-chrome);
	font-size: var(--step-0);
	letter-spacing: 0.22em;
	text-transform: uppercase;
	text-shadow: 0 1px 8px rgba(0, 0, 0, 0.9);
}

/* --- The two actions ---------------------------------------------------
   Two image tiles: the frames are artwork, so the label is a real <span> above each
   button and the whole tile is the target. The frames arrived with their centre
   already cut out, which is why the label is not drawn into the glow.

   Sizing is on the width and the height is declared in the markup, so the browser
   reserves the box before the 82 KB PNG lands and the hero does not jump. The
   frames are 2.08:1 and 2.06:1, close enough that one width suits both.

   The motion models one physical plate in a socket, and it only ever goes IN:

     idle     raised on its shadow, a slow breathing halo behind it
     hover    it does NOT rise. It settles a hair toward the page and the halo
              tightens and brightens - tension, like a finger resting on a button
              before the travel
     press    it plunges down and in, the drop shadow collapses almost to nothing
              because the plate has entered its socket, and the halo flashes to
              full at the moment of contact
     release  it springs back out with a small overshoot

   Nothing here lifts on hover. That is the whole point of "the other way round":
   the usual web button rises to meet the pointer, which reads as floating. A plate
   that is pressed into a surface does the opposite - it winds up downward and then
   goes down. So the only positive translateY in the whole set is on :active, and
   the easing on release overshoots to sell the return.

   Everything is disabled under prefers-reduced-motion, halo included: a slow
   infinite animation is exactly what that setting is about, not just the transitions. */

.landing-tiles {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 1.5rem 2rem;
	margin: 2rem 0 0;
	padding: 0;
	list-style: none;
}

.landing-tile {
	display: flex;
	flex-direction: column;
	align-items: center;
}

/* The label sits ON the plate, centred in its glow - which is what the empty centre
   of these frames is for. It is absolutely positioned because the frame is artwork
   with a hole in the middle; flowing the text would push it out above the image.

   Each label takes the colour its own plate can carry, measured against the artwork:
   the green interior averages #73e509 and the blue #0550bd, and they need opposite
   treatments. White on the green is 1.62:1, unreadable. Dark ink on the blue is
   2.44:1, unreadable. So dark on green at 10.91:1 and white on blue at 7.27:1.

   Both also carry an outline in the opposite direction, and that is not decoration:
   each plate has a radial highlight and the brightest pixel inside the text band sits
   around 0.85 luminance on the green and 0.75 on the blue, which drags the contrast
   to 1.06:1 and 4.12:1 under a bare glyph. The outline is what guarantees the label
   stays readable wherever a highlight happens to fall under it. */
.landing-tile__label {
	position: absolute;
	left: 50%;
	top: 52%;
	transform: translate(-50%, -50%);
	z-index: 1;
	white-space: nowrap;
	pointer-events: none;
	font-family: var(--font-chrome);
	font-weight: 700;
	letter-spacing: 0.16em;
	text-indent: 0.16em; /* the trailing track, so the word sits optically centred */
	text-transform: uppercase;
	transition: text-shadow 0.18s var(--ease-out), transform 0.18s var(--ease-out);
}

/* PLAY, on the bright green plate: dark face, light rim. 40px -> 30px, tracking down
   from --step-4's 0.16em to 0.14em so four letters keep the same optical width. */
.landing-tile:first-child .landing-tile__label {
	font-size: 1.875rem;
	letter-spacing: 0.14em;
	color: #08210b;
	text-shadow:
		0 0 3px rgba(255, 255, 255, 0.85),
		0 0 12px rgba(255, 255, 255, 0.55),
		0 2px 4px rgba(255, 255, 255, 0.35);
}

/* CREATE ACCOUNT, on the deep blue plate: light face, dark rim. Smaller than PLAY
   on purpose - it is the longer word and the secondary action, and PLAY is the one
   the page is asking for. 22px -> 15.5px, which is what a 260px plate fits. */
.landing-tile:last-child .landing-tile__label {
	font-size: 0.96875rem;
	letter-spacing: 0.12em;
	color: #ffffff;
	text-shadow:
		0 0 4px rgba(2, 12, 30, 0.95),
		0 0 14px rgba(2, 12, 30, 0.85),
		0 2px 5px rgba(2, 12, 30, 0.9);
}

/* The label lives INSIDE the anchor, not beside it. Beside it, the link had no
   accessible name at all - axe reports link-name on both - because the <span> was a
   sibling and an empty alt is no name. Inside, the tile is one target: clicking the
   word works as well as clicking the frame, and the name comes from the text.

   block, not a flex column: the label is absolutely positioned now, so it is out of
   the flow and the frame is the only thing that sizes the anchor. */
.landing-tile a {
	position: relative;
	display: block;
	border-radius: 6px;
	text-decoration: none;
	transform: translateZ(0);
	transition: transform 0.14s var(--ease-out), filter 0.14s var(--ease-out);
}

/* The halo. A pseudo-element rather than a box-shadow on the anchor, because the
   anchor is a column (label + frame) and a shadow on it would sit under the word
   instead of behind the plate. */
.landing-tile a::after {
	content: '';
	position: absolute;
	left: 4%;
	right: 4%;
	top: 18%;
	bottom: -6%;
	z-index: -1;
	border-radius: 14px;
	pointer-events: none;
	background: radial-gradient(
		ellipse at 50% 70%,
		rgba(120, 220, 255, 0.35) 0%,
		rgba(80, 180, 240, 0.16) 45%,
		rgba(80, 180, 240, 0) 72%
	);
	opacity: 0.55;
	transform: scale(0.96);
	transition: opacity 0.18s var(--ease-out), transform 0.18s var(--ease-out);
	animation: landing-halo 3.4s ease-in-out infinite;
}

/* Green and blue plates carry their own colour, so the halo takes it from the
   frame by tinting through the artwork rather than from a hardcoded pair. */
.landing-tile:first-child a::after {
	background: radial-gradient(
		ellipse at 50% 70%,
		rgba(150, 255, 150, 0.4) 0%,
		rgba(90, 220, 90, 0.18) 45%,
		rgba(90, 220, 90, 0) 72%
	);
}
.landing-tile:last-child a::after {
	background: radial-gradient(
		ellipse at 50% 70%,
		rgba(150, 190, 255, 0.4) 0%,
		rgba(80, 140, 255, 0.18) 45%,
		rgba(80, 140, 255, 0) 72%
	);
}

@keyframes landing-halo {
	0%, 100% { opacity: 0.45; transform: scale(0.94); }
	50%      { opacity: 0.8;  transform: scale(1.04); }
}

.landing-tile img {
	/* 350px -> 260px. Not halved, and the reason is measured rather than taste: the
	   label sits in the frame's cut-out, which is 68% of the plate's width, so
	   "CREATE ACCOUNT" at 260px has 159px of room and fits at up to 16.2px of type.
	   At the 175px a literal halving would give, it fits at 10.9px - unreadable.
	   For reference the old 350px plate only fitted 21.8px, and it was set at 22px, so
	   the word was already sitting exactly on the edge of its hole. */
	width: clamp(150px, 20vw, 260px);
	height: auto;
	line-height: 0;
	border-radius: 4px;
	filter: drop-shadow(0 6px 16px rgba(0, 0, 0, 0.6));
	transition: filter 0.14s var(--ease-out), transform 0.08s var(--ease-out);
}

/* --- Hover: lift and light -------------------------------------------- */

.landing-tile a:hover,
.landing-tile a:focus-visible {
	/* Down, not up. This is the load before the press. */
	transform: translateY(1px);
	filter: brightness(1.16) saturate(1.08);
}

.landing-tile a:hover img,
.landing-tile a:focus-visible img {
	/* The shadow tightens as the plate sinks: less gap, less spread. */
	filter: drop-shadow(0 3px 9px rgba(0, 0, 0, 0.72))
		drop-shadow(0 0 20px rgba(140, 210, 255, 0.4));
}

/* The label lifts a hair with the plate and its rim widens, in the plate's own
   colour rather than a shared gold: the rim on the green already IS light, and the
   one on the blue already IS dark. */
.landing-tile a:hover .landing-tile__label,
.landing-tile a:focus-visible .landing-tile__label {
	transform: translate(-50%, calc(-50% - 1px));
}

.landing-tile:first-child a:hover .landing-tile__label,
.landing-tile:first-child a:focus-visible .landing-tile__label {
	text-shadow:
		0 0 5px rgba(255, 255, 255, 1),
		0 0 20px rgba(255, 255, 255, 0.8),
		0 2px 6px rgba(255, 255, 255, 0.5);
}

.landing-tile:last-child a:hover .landing-tile__label,
.landing-tile:last-child a:focus-visible .landing-tile__label {
	text-shadow:
		0 0 6px rgba(2, 12, 30, 1),
		0 0 22px rgba(2, 12, 30, 0.95),
		0 2px 7px rgba(2, 12, 30, 1);
}

.landing-tile a:hover::after,
.landing-tile a:focus-visible::after {
	/* Tightens and holds still: the breathing stops the moment a finger lands. */
	opacity: 0.85;
	transform: scale(0.93);
	animation-play-state: paused;
}

/* --- Press: plunge into the socket --------------------------------------

   The travel is short and the easing is asymmetric on purpose. Going in is fast
   and nearly linear, because a finger does not ease into a button. Coming out
   overshoots, because a plate released by a spring does. Same two states, opposite
   physics, which is what makes it read as a press and not a hover.

   The shadow collapses toward zero rather than merely darkening: a plate in its
   socket is no longer above the surface, so there is no gap left to cast one. That
   single change does more for the illusion than any amount of blur. */

/* Contact. Nearly linear, and quick: the finger travels a few millimetres. */
.landing-tile a:active {
	transform: translateY(4px) scale(0.965);
	transition: transform 0.05s linear, filter 0.05s linear;
	filter: brightness(1.32) saturate(1.16);
}

.landing-tile a:active img {
	filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.9))
		drop-shadow(0 0 30px rgba(210, 245, 255, 0.7))
		brightness(1.25);
}

/* The flash: the halo flares out at the moment of contact, then the release
   animation pulls it back and overshoots with the plate. */
.landing-tile a:active::after {
	opacity: 1;
	transform: scale(1.18);
	animation-play-state: paused;
}

/* Release. The plate springs back out past its resting height and settles, which is
   the detail that reads as "pressed" rather than "hovered". Declared after :active
   so it wins on the way out, where the pseudo-class has already been dropped. */
.landing-tile a:not(:active) {
	transition:
		transform 0.42s cubic-bezier(0.34, 1.56, 0.64, 1),
		filter 0.42s var(--ease-out);
}

.landing-tile a:not(:active):hover,
.landing-tile a:not(:active):focus-visible {
	transform: translateY(1px) scale(1.01);
}

/* The ring, not the artwork: the frames carry their own glow already. */
.landing-tile a:focus-visible {
	outline: 2px solid var(--landing-gold-2);
	outline-offset: 6px;
}

.is-landing .ledger-btn--waypoint { display: none; }

/* --- Panel band, under the fold ---------------------------------------- */

.landing-panels {
	position: relative;
	z-index: 1;
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--gap);
	width: 100%;
	max-width: 1200px;
	margin: 0 auto;
	padding: 0 var(--pad) 4rem;
}

.landing-panel {
	background: rgba(16, 36, 47, 0.86);
	border: 1px solid var(--landing-edge);
	border-radius: 3px;
	padding: 1.1rem 1.2rem;
	color: var(--landing-text);
}

.landing-panel__head {
	margin: 0 0 0.9rem;
	padding-bottom: 0.5rem;
	border-bottom: 1px solid var(--landing-edge);
	font-size: var(--step-0);
	font-weight: 700;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--landing-gold);
	text-shadow: none;
}

.landing-panel__note {
	color: var(--landing-muted);
	font-size: var(--step-0);
}

.landing-panel > p:last-child { margin: 0.9rem 0 0; }

.landing-panel a {
	color: var(--landing-gold);
	text-decoration: underline;
	text-underline-offset: 0.18em;
}
.landing-panel a:hover { color: var(--landing-gold-2); }

/* Live figures: the client's own numbers, on a panel rather than a band. */
.landing-figures {
	display: grid;
	grid-template-columns: 1fr;
	gap: 0.55rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.landing-figure {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
	padding-bottom: 0.45rem;
	border-bottom: 1px solid rgba(44, 74, 92, 0.5);
}

.landing-figure__label { color: var(--landing-muted); font-size: var(--step-0); }

/* Tabular so a value changing does not shift the row. */
.landing-figure__value {
	font-family: var(--font-chrome);
	font-weight: 700;
	font-size: var(--step-2);
	font-variant-numeric: tabular-nums;
	color: var(--landing-live);
}
.landing-figure[data-state='down'] .landing-figure__value { color: var(--landing-down); }

.landing-events,
.landing-news {
	margin: 0;
	padding: 0;
	list-style: none;
	display: grid;
	gap: 0.6rem;
}

.landing-events li {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
	padding-bottom: 0.45rem;
	border-bottom: 1px solid rgba(44, 74, 92, 0.5);
}
.landing-events__name { font-weight: 600; }
.landing-events__when,
.landing-news__date {
	color: var(--landing-muted);
	font-size: var(--step-0);
	white-space: nowrap;
}

.landing-news a { font-weight: 600; }

/* --- Width ------------------------------------------------------------- */

@media (min-width: 768px) {
	.landing-panels { grid-template-columns: repeat(3, 1fr); }
}

@media (min-width: 1280px) {
	/* Wide enough that the whole illustration fits, so the focal point stops
	   mattering here; only the marks grow. */
	.landing-hero__mark { width: 310px; }
	.landing-hero__banner { width: 283px; }
}

/* Portrait phones: 1376x768 cropped to a 375x667 viewport keeps only a narrow
   vertical strip of the illustration. Biasing the focal point right keeps the
   knight and the mage rather than a column of empty sky. */
@media (max-width: 767px) {
	.landing-hero {
		background-position: 62% 45%;
		padding-top: 7.5rem;
		min-height: 94dvh;
	}
	.landing-hero__mark { width: min(150px, 39vw); }
	.landing-hero__banner { width: min(137px, 35vw); }
	/* One tile per row on a phone: the frames are wide enough that two side by side
	   would drop under 150px and the artwork turns to mush. */
	.landing-tiles { flex-direction: column; align-items: center; gap: 1.25rem; }
	/* 250px, not 235px: at 235 the cut-out is 144px and CREATE ACCOUNT at 15.5px
	   measures 152px, so the word spills off the plate. 250 gives 153px of hole for
	   147px of word, once the label steps down to 15px on a phone. */
	.landing-tile img { width: min(250px, 68vw); }
	.landing-tile:last-child .landing-tile__label { font-size: 0.9375rem; }

	/* The label stays ABOVE its frame on a phone, as on desktop. What changes is the
	   spacing: a label above works stacked as long as it sits clearly closer to its
	   own plate than to the plate above it. So the gap inside the tile tightens and
	   the gap between tiles opens, and "CREATE ACCOUNT" ends up nearer the blue frame
	   than the green one - which is the whole of the ambiguity, solved with distance
	   rather than by moving the text somewhere it was not asked to go. */
	.landing-tiles { gap: 1.25rem; }
	.landing-hero__scroll { display: none; }

	/* 46ch is wider than a 375px viewport's text column, so the tagline would wrap
	   hard against both padding edges and read as a wall. Step it down a size and
	   shorten the measure so it keeps a margin on a small phone. */
	.landing-hero__tagline {
		max-width: 30ch;
		font-size: var(--step-0);
	}

	/* The shell header is one row taller than it looks: the account actions wrap
	   under the toggle. Both actions are already the hero's two tiles, so on a
	   phone the bar keeps the toggle and the login and drops the rest. */
	.is-landing .ledger-header__account .ledger-btn--quiet { display: none; }
	.is-landing .ledger-header__account { margin-left: auto; }
}

@media (prefers-reduced-motion: reduce) {
	/* The halo is an infinite animation, not a transition, so it is stopped here
	   rather than only neutralised: a slow pulse forever is the thing this setting
	   exists to prevent. The states stay, they just arrive without travel. */
	.landing-tile a,
	.landing-tile img,
	.landing-tile a::after,
	.landing-tile__label { transition: none; animation: none; }

	.landing-tile a::after { opacity: 0.6; }

	.landing-tile a:hover,
	.landing-tile a:focus-visible,
	.landing-tile a:active { transform: none; }

	/* The particle field is a continuous stream of things moving across the whole
	   hero, which is exactly what this setting is about, so it is not drawn at all
	   rather than drawn static. landing.js also refuses to start under this query,
	   and listens for it changing, so turning the OS setting on stops a field that
	   is already running. */
	.landing-particles { display: none; }
}

/* --- Print ------------------------------------------------------------- */

@media print {
	.is-landing .ledger-page { background: none; }
	.is-landing .ledger-header { position: static; }
	.landing-hero { min-height: 0; padding: 1rem 0; background-image: none; }
	.landing-hero::before, .landing-hero::after { display: none; }
	.landing-hero__scroll { display: none; }
	/* Same reason as under prefers-reduced-motion: nothing paints. */
	.landing-particles { display: none; }
	/* Artwork does not print: the tile keeps its label and loses the frame, which is
	   the one thing a reader on paper needs. */
	.landing-tile img { display: none; }
}