/*
 * Polish Route — main stylesheet.
 *
 * Colour is never hard-coded below. Everything derives from four custom
 * properties (--pr-accent, --pr-accent-soft, --pr-ink, --pr-paper) that
 * inc/games.php sets per project, so one palette swap re-skins the whole page.
 * Surfaces are mixed from ink and paper rather than declared, which is what
 * lets a light game (Narcissu) and a dark one (Juniper's Knot) share
 * a stylesheet without a second set of rules.
 */

/* ---------------------------------------------------------------- fonts -- */

/*
 * The site's display face since 2013. The file ships as playtime.ttf, but its
 * real family name is "Playtime With Hot Toddies" — the old theme registered
 * it under the alias "katawa". Named properly here.
 *
 * It carries the full Polish set (ą ć ę ł ń ó ś ź ż), so it can be used for
 * real copy and not just decoration.
 */
@font-face {
	font-family: 'Playtime With Hot Toddies';
	src: url('../fonts/playtime.ttf') format('truetype');
	font-weight: normal;
	font-style: normal;
	font-display: swap;
}

/* --------------------------------------------------------------- tokens -- */

:root {
	/*
	 * The house palette, unchanged since 2013: beige paper, warm brown, sand.
	 * inc/games.php overrides accent and accent-soft per project but keeps
	 * paper and ink, so every game stays recognisably Polish Route.
	 */
	--pr-accent: #7a6563;
	--pr-accent-soft: #d7c9aa;
	--pr-ink: #232323;
	--pr-paper: #f5f5dc;

	/* Amber, used by the original theme for the active and hovered nav item. */
	--pr-highlight: #f7b32b;

	--pr-font-display: 'Playtime With Hot Toddies', 'Trebuchet MS', ui-rounded, system-ui, sans-serif;
	--pr-font-ui: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
	--pr-font-prose: Georgia, 'Iowan Old Style', 'Times New Roman', serif;

	--pr-measure: 68ch;
	--pr-gutter: clamp(1rem, 4vw, 2.5rem);
	--pr-radius: 10px;
	--pr-radius-lg: 18px;

	--pr-shadow: 0 1px 2px rgb(0 0 0 / 6%), 0 8px 24px rgb(0 0 0 / 8%);
	--pr-shadow-lg: 0 2px 6px rgb(0 0 0 / 8%), 0 18px 50px rgb(0 0 0 / 14%);

	--pr-ease: cubic-bezier(0.22, 0.61, 0.36, 1);

	/* Logo (60px) plus the masthead's vertical padding. The banner is pulled
	   up by this much so the bar sits on the artwork. */
	--pr-masthead-h: 84px;
}

/* Derived surfaces. These follow the mood automatically. */
:root {
	--pr-surface: color-mix(in srgb, var(--pr-ink) 4%, var(--pr-paper));
	--pr-surface-2: color-mix(in srgb, var(--pr-ink) 8%, var(--pr-paper));
	--pr-line: color-mix(in srgb, var(--pr-ink) 14%, var(--pr-paper));
	--pr-muted: color-mix(in srgb, var(--pr-ink) 58%, var(--pr-paper));
	--pr-on-accent: #fff;

	/* X's mark is near-black, which is its brand. Lightened by PHP wherever
	   the surface it sits on is dark. */
	--pr-x-mark: #0f1419;

	/* How far the banner is held back from the page behind it. */
	--pr-art-opacity: 0.85;

	/* Brightness applied to a solid accent fill on hover. Reversed by PHP on
	   a dark surface, where "brighter" means "glaring". */
	--pr-hover-lift: 1.08;
}

/*
 * --pr-on-accent is computed per project in inc/games.php from the accent's
 * luminance and emitted on :root. Do not set it on a body class here: body is
 * a closer ancestor than :root, so it would win and defeat the calculation.
 *
 * The same goes for the tokens above that vary with the scheme. There is no
 * .pr-mood-dark rule here for the deeper shadows a dark page needs, because a
 * page can now be dark for two unrelated reasons — the project chose it, or
 * the reader did — and a body class only knows about the first. They are
 * emitted from polish_route_theme_vars() instead, keyed off the paper that
 * actually ends up on the page. The .pr-mood-dark class is still set, for
 * anything that genuinely means "this project is dark" rather than "this page
 * is dark".
 */

/* ----------------------------------------------------------------- base -- */

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

html {
	scroll-behavior: smooth;
	-webkit-text-size-adjust: 100%;
}

body {
	margin: 0;
	background: var(--pr-paper);
	color: var(--pr-ink);
	font-family: var(--pr-font-ui);
	font-size: 1rem;
	line-height: 1.65;
	overflow-x: hidden;
}

img,
video {
	max-width: 100%;
	height: auto;
}

/*
 * Iframes are deliberately left out of the rule above.
 *
 * An <img> carries an intrinsic aspect ratio, so height:auto scales it
 * proportionally. An iframe has none — height:auto overrides its height
 * attribute and falls back to the CSS default for replaced elements, 150px,
 * squashing a video embed into a strip. Embeds get their ratio restored
 * explicitly further down.
 */
iframe {
	max-width: 100%;
}

a {
	color: var(--pr-accent);
	text-decoration-thickness: 1px;
	text-underline-offset: 0.18em;
}

/*
 * Visited links get an explicit colour. Without this rule they fall through to
 * the browser's own idea of "visited", which came out washed out and barely
 * readable. Mixing the accent toward the ink keeps the link recognisably part
 * of the palette while staying legible — and because it is mixed with ink
 * rather than a fixed value, it darkens on light themes and lightens on dark
 * ones by itself.
 *
 * Declared early and with low specificity on purpose: links that already have
 * a colour of their own (nav, card titles, tags, widgets) are defined later
 * and keep it.
 */
a:visited {
	color: color-mix(in srgb, var(--pr-accent) 55%, var(--pr-ink));
}

a:hover,
a:visited:hover {
	color: color-mix(in srgb, var(--pr-accent) 70%, var(--pr-ink));
}

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

h1, h2, h3, h4, h5, h6 {
	line-height: 1.2;
	text-wrap: balance;
	margin: 0 0 0.5em;
}

/* ------------------------------------------------------------ a11y bits -- */

.screen-reader-text {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

.pr-skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 200;
	padding: 0.75rem 1.25rem;
	background: var(--pr-accent);
	color: var(--pr-on-accent);
	border-radius: 0 0 var(--pr-radius) 0;
}

.pr-skip-link:focus {
	left: 0;
}

/* --------------------------------------------------------------- layout -- */

.pr-content {
	padding: 0 var(--pr-gutter);
}

.pr-layout {
	max-width: 1180px;
	margin: 0 auto;
	padding: clamp(2rem, 5vw, 3.5rem) 0;
	display: grid;
	gap: clamp(2rem, 5vw, 3.5rem);
	grid-template-columns: minmax(0, 1fr) 300px;
	align-items: start;
}

.pr-layout--wide,
.pr-layout:not(:has(.pr-sidebar)) {
	grid-template-columns: minmax(0, 1fr);
}

.pr-main {
	min-width: 0;
}

/* ------------------------------------------------------------- masthead -- */

/*
 * The masthead rides on the banner rather than sitting in a strip above it, so
 * logo and menu share the artwork's line. It stays sticky: transparent while
 * the banner is behind it, then picking up a background once it would
 * otherwise overlap the content. theme.js toggles .is-stuck.
 */
.pr-masthead {
	position: sticky;
	top: 0;
	z-index: 60;
	background: transparent;
	border-bottom: 1px solid transparent;
	transition: background 0.25s var(--pr-ease), border-color 0.25s var(--pr-ease);
}

/*
 * A soft wash under the bar so dark menu text stays legible over whatever
 * artwork happens to be behind it.
 */
.pr-masthead::before {
	content: '';
	position: absolute;
	inset: 0;
	z-index: -1;
	pointer-events: none;
	/*
	 * A light veil over the artwork, not a solid bar — the banner is meant to
	 * show through. --pr-bar-veil is chosen per banner in inc/games.php from
	 * the measured brightness of its top band: dark over a light image, light
	 * over a dark one, so it always pushes the artwork away from the text
	 * colour rather than towards it.
	 *
	 * It fades out over the lower third, so the bar has no hard edge.
	 */
	background: linear-gradient(
		to bottom,
		var(--pr-bar-veil, transparent) 0%,
		var(--pr-bar-veil, transparent) 62%,
		transparent 100%
	);
	transition: opacity 0.25s var(--pr-ease);
}

.pr-masthead.is-stuck {
	background: color-mix(in srgb, var(--pr-paper) 92%, transparent);
	backdrop-filter: blur(12px);
	border-bottom-color: var(--pr-line);

	/*
	 * Scrolled clear of the banner, the bar has its own paper background, so
	 * the banner-derived colours no longer apply — back to the page's ink,
	 * no shadow, and no veil to lay over artwork that is no longer behind it.
	 */
	--pr-bar-ink: var(--pr-ink);
	--pr-bar-shadow: none;
	--pr-bar-veil: transparent;
}

.pr-masthead.is-stuck::before {
	opacity: 0;
}

/*
 * The admin bar is fixed at the top of the viewport for logged-in users, so a
 * masthead stuck at top:0 slides underneath it. WordPress's bar is 32px wide
 * screens, 46px below 782px, and stops being fixed below 600px.
 */
.admin-bar .pr-masthead {
	top: 32px;
}

@media screen and (max-width: 782px) {
	.admin-bar .pr-masthead {
		top: 46px;
	}
}

@media screen and (max-width: 600px) {
	.admin-bar .pr-masthead {
		top: 0;
	}
}

.pr-masthead__inner {
	max-width: 1180px;
	margin: 0 auto;
	padding: 0.7rem var(--pr-gutter);
	display: flex;
	align-items: center;
	gap: 1rem;
}

.pr-brand {
	display: flex;
	align-items: center;
	gap: 0.7rem;
	margin-right: auto;
	text-decoration: none;
	/* Kills the descender gap under an inline image. */
	line-height: 0;
}

.pr-brand__logo {
	display: block;
	height: 60px;
	width: auto;
	transition: transform 0.2s var(--pr-ease);
}

.pr-brand:hover .pr-brand__logo {
	transform: scale(1.04);
}

/*
 * Name and tagline beside the logo. Both are sized to stack well inside the
 * logo's 60px, so the bar's height still comes from the logo alone and adding
 * the text does not make it taller.
 */
.pr-brand__text {
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: 0.1rem;
	line-height: 1.15;
	min-width: 0;
}

/*
 * Over the banner these follow --pr-bar-ink, set per banner from its measured
 * brightness. Once the bar has scrolled clear and gained its own background,
 * .is-stuck below puts them back to the page's ink.
 */
.pr-brand__name {
	font-family: var(--pr-font-display);
	font-size: 1.3rem;
	color: var(--pr-bar-ink, var(--pr-ink));
	text-shadow: var(--pr-bar-shadow, none);
}

/*
 * Not --pr-muted: at 58% ink that measures 3.87:1 against the beige, under
 * the 4.5:1 needed for text this size, and it sits over banner artwork where
 * it is worse still. Mixed at 78% instead, which reads clearly at 7.2:1 while
 * staying quieter than the name above it.
 */
.pr-brand__tagline {
	font-size: 0.76rem;
	line-height: 1.2;
	letter-spacing: 0.02em;
	color: var(--pr-bar-ink, var(--pr-ink));
	/* Slightly held back from the name, without losing contrast. */
	opacity: 0.85;
	text-shadow: var(--pr-bar-shadow, none);
}

.pr-brand:hover .pr-brand__name {
	color: var(--pr-accent);
}

/* ------------------------------------------------------------------ nav -- */

.pr-nav__list {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.25rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.pr-nav__list li {
	position: relative;
}

.pr-nav__list a {
	display: block;
	padding: 0.45rem 0.75rem;
	border-radius: var(--pr-radius);
	color: var(--pr-bar-ink, var(--pr-ink));
	text-shadow: var(--pr-bar-shadow, none);
	text-decoration: none;
	/* The old theme set the menu in Playtime; slightly up-sized because the
	   face runs small next to a UI sans. */
	font-family: var(--pr-font-display);
	font-size: 1.06rem;
	transition: background 0.15s var(--pr-ease), color 0.15s var(--pr-ease);
}

/*
 * Amber on hover and for the current page, as the site has always done.
 *
 * Two things had to change for it to survive a photographic banner.
 *
 * The pill is tinted onto --pr-bar-veil rather than onto nothing. The veil is
 * already picked per banner from its measured brightness, so the highlight
 * comes out dark-amber over dark art and pale-amber over light art, and either
 * way it is a ground rather than a transparent wash the picture reads through.
 *
 * The label mixes toward --pr-bar-ink, not --pr-ink. It was mixing with the
 * page's ink while sitting on the banner, which is the wrong reference
 * entirely: over a bright banner in light mode that produced mid-amber text on
 * a pale amber pill.
 *
 * Most of the amber then had to come out of the text. At the old 72% the text
 * and the pill are the same hue, and no amount of veil rescues it — measured
 * over dark, mid and bright banners it lands at 2.08–2.49:1 whatever else is
 * changed. At 30% the worst case across all of them is 5.99:1, and the amber
 * still reads, because it is the pill that carries it.
 */
.pr-nav__list a:hover,
.pr-nav__list .current-menu-item > a,
.pr-nav__list .current_page_item > a,
.pr-nav__list .current-menu-ancestor > a {
	background: color-mix(in srgb, var(--pr-highlight) 26%, var(--pr-bar-veil, transparent));
	color: color-mix(in srgb, var(--pr-highlight) 30%, var(--pr-bar-ink, var(--pr-ink)));
}

/* Submenus: the Tłumaczenia menu has one level of children. */
.pr-nav__list .sub-menu {
	position: absolute;
	top: 100%;
	left: 0;
	min-width: 230px;
	margin: 0;
	padding: 0.35rem;
	list-style: none;
	background: var(--pr-paper);

	/*
	 * The dropdown has its own paper panel, so it is no longer over the
	 * banner — reset the banner-derived colours or its links inherit white
	 * text from a dark banner and vanish against the beige. The veil goes too,
	 * or the highlight below lays a scrim meant for artwork onto the panel.
	 */
	--pr-bar-ink: var(--pr-ink);
	--pr-bar-shadow: none;
	--pr-bar-veil: transparent;
	border: 1px solid var(--pr-line);
	border-radius: var(--pr-radius);
	box-shadow: var(--pr-shadow);
	opacity: 0;
	visibility: hidden;
	transform: translateY(-6px);
	transition: all 0.18s var(--pr-ease);
	z-index: 70;
}

.pr-nav__list li:hover > .sub-menu,
.pr-nav__list li:focus-within > .sub-menu {
	opacity: 1;
	visibility: visible;
	transform: translateY(0);
}

.pr-nav-toggle {
	display: none;
	width: 44px;
	height: 44px;
	padding: 0;
	border: 1px solid var(--pr-line);
	border-radius: var(--pr-radius);
	background: transparent;
	cursor: pointer;
}

.pr-nav-toggle__bars,
.pr-nav-toggle__bars::before,
.pr-nav-toggle__bars::after {
	display: block;
	width: 20px;
	height: 2px;
	margin: 0 auto;
	background: var(--pr-bar-ink, var(--pr-ink));
	transition: transform 0.2s var(--pr-ease), opacity 0.2s var(--pr-ease);
}

.pr-nav-toggle__bars::before,
.pr-nav-toggle__bars::after {
	content: '';
	position: relative;
}

.pr-nav-toggle__bars::before { top: -6px; }
.pr-nav-toggle__bars::after  { top: 4px; }

.pr-nav-toggle[aria-expanded='true'] .pr-nav-toggle__bars {
	background: transparent;
}

.pr-nav-toggle[aria-expanded='true'] .pr-nav-toggle__bars::before {
	transform: translateY(6px) rotate(45deg);
}

.pr-nav-toggle[aria-expanded='true'] .pr-nav-toggle__bars::after {
	transform: translateY(-4px) rotate(-45deg);
}

/* --------------------------------------------------------- scheme switch -- */

/*
 * Cycles system → light → dark. The icon shown is the state the site is in,
 * not the state pressing it would produce, so the control reports rather than
 * promises — and "system" is a state you can get back to, which a two-way
 * switch would not give you.
 *
 * Hidden until the inline script in inc/games.php puts pr-js on <html>. The
 * button does nothing without JavaScript, and a dead control is worse than no
 * control at all.
 */
.pr-theme-toggle {
	display: none;
	/* Sits after the menu on a wide screen; the mobile query below moves it
	   back beside the logo, where the hamburger takes over the right end. */
	order: 1;
	flex: 0 0 auto;
	width: 40px;
	height: 40px;
	padding: 0;
	border-radius: 50%;
	cursor: pointer;
	color: var(--pr-bar-ink, var(--pr-ink));
	transition: background 0.15s var(--pr-ease), color 0.15s var(--pr-ease);
}

.pr-js .pr-theme-toggle {
	display: grid;
	place-items: center;
	/*
	 * The same veil the masthead text uses, so a thin-stroked icon stays
	 * legible over whichever banner is up — measured per banner, so this
	 * lightens on dark art and darkens on bright.
	 */
	background: var(--pr-bar-veil, transparent);
	border: 1px solid color-mix(in srgb, var(--pr-bar-ink, var(--pr-ink)) 35%, transparent);
}

/* The same highlight as a menu item, and on the banner for the same reason. */
.pr-theme-toggle:hover {
	background: color-mix(in srgb, var(--pr-highlight) 26%, var(--pr-bar-veil, transparent));
	color: color-mix(in srgb, var(--pr-highlight) 30%, var(--pr-bar-ink, var(--pr-ink)));
}

.pr-theme-toggle svg {
	width: 20px;
	height: 20px;
}

/*
 * Which of the three icons is showing is decided by the attribute on <html>,
 * so the button is correct on the first paint — before any script has run to
 * bind the click handler.
 */
.pr-theme-toggle__icon {
	display: none;
}

.pr-theme-toggle__icon--auto {
	display: block;
}

[data-theme='light'] .pr-theme-toggle__icon--auto,
[data-theme='dark'] .pr-theme-toggle__icon--auto {
	display: none;
}

[data-theme='light'] .pr-theme-toggle__icon--light {
	display: block;
}

[data-theme='dark'] .pr-theme-toggle__icon--dark {
	display: block;
}

/* ----------------------------------------------------------------- hero -- */

/*
 * The banner is artwork and nothing else. With no title laid over it there is
 * no scrim and no contrast compromise, so it can run tall and show the picture
 * whole. Headings are printed in the content column instead.
 */
.pr-hero {
	position: relative;
	isolation: isolate;
	overflow: hidden;
	/*
	 * Pulled up under the masthead so the artwork runs behind the logo and
	 * menu; the padding gives that space back, leaving the same amount of
	 * visible art below the bar.
	 */
	margin-top: calc(var(--pr-masthead-h) * -1);
	padding-top: var(--pr-masthead-h);
	min-height: calc(clamp(200px, 22vw, 320px) + var(--pr-masthead-h));
	background: color-mix(in srgb, var(--pr-accent-soft) 30%, var(--pr-paper));
	border-bottom: 1px solid var(--pr-line);
}

/* Art sits on ::before at -2 so the motif layer at -1 can sit over it. */
.pr-hero::before {
	content: '';
	position: absolute;
	inset: 0;
	background-image: var(--pr-hero-art);
	/* Both set per banner from its filename — see polish_route_banner_options(). */
	background-size: var(--pr-hero-fit, cover);
	background-position: var(--pr-hero-pos, center 35%);
	background-repeat: no-repeat;
	/*
	 * Held back so the artwork settles into the beige behind it rather than
	 * sitting hard on top of the page. The scrim that used to keep the title
	 * readable is gone — there is no title now — but this wash stays, because
	 * it is what ties the banner to the rest of the palette.
	 *
	 * Held back further on a dark page, where key art at full strength is a
	 * lit rectangle floating on near-black. See --pr-art-opacity.
	 */
	opacity: var(--pr-art-opacity, 0.85);
	z-index: -2;
}

/*
 * A taller banner for images worth showing more of. Named with --tall, this
 * roughly doubles the visible slice rather than cropping a 16:9 picture down
 * to a strip.
 */
.pr-hero--tall {
	min-height: calc(clamp(320px, 34vw, 520px) + var(--pr-masthead-h));
}

/* Letterboxed images sit on the project's accent rather than on nothing. */
.pr-hero::before {
	background-color: color-mix(in srgb, var(--pr-accent) 18%, var(--pr-paper));
}

/* Softens the join into the page below. */
.pr-hero__fade {
	position: absolute;
	inset: auto 0 0 0;
	height: 90px;
	background: linear-gradient(to bottom, transparent, var(--pr-paper));
	pointer-events: none;
}

/* ------------------------------------------------------------ character -- */

/*
 * A cut-out figure standing at the bottom edge of the banner. Until the art
 * exists, an outline marks the slot — see polish_route_character().
 */
.pr-character {
	position: absolute;
	right: clamp(1rem, 6vw, 5rem);
	bottom: 0;
	z-index: 2;
	width: clamp(130px, 17vw, 230px);
	pointer-events: none;
}

.pr-character img {
	display: block;
	width: 100%;
	height: auto;
	filter: drop-shadow(0 6px 18px rgb(0 0 0 / 28%));
}

.pr-character--empty {
	height: clamp(150px, 20vw, 260px);
	display: grid;
	place-items: center;
	text-align: center;
	border: 2px dashed color-mix(in srgb, var(--pr-accent) 60%, transparent);
	border-bottom: 0;
	border-radius: var(--pr-radius-lg) var(--pr-radius-lg) 0 0;
	background: color-mix(in srgb, var(--pr-paper) 62%, transparent);
}

.pr-character__label {
	display: grid;
	gap: 0.2rem;
	padding: 0.75rem;
	font-family: var(--pr-font-display);
	font-size: 0.95rem;
	line-height: 1.25;
	color: var(--pr-muted);
}

.pr-character__label small {
	font-family: var(--pr-font-ui);
	font-size: 0.68rem;
	opacity: 0.75;
}

/* Too cramped beside the banner on a phone. */
@media (max-width: 782px) {
	.pr-character {
		display: none;
	}
}

/* ---------------------------------------------------------- page header -- */

.pr-page-header {
	margin-bottom: clamp(1.25rem, 3vw, 2rem);
}

.pr-page-header__title {
	font-family: var(--pr-font-display);
	font-size: clamp(1.9rem, 5vw, 3rem);
	margin: 0;
	color: var(--pr-ink);
}

.pr-page-header__tagline {
	margin: 0.35rem 0 0;
	font-size: clamp(1rem, 2vw, 1.15rem);
	color: var(--pr-muted);
	max-width: 52ch;
}

/* A project's progress panel, now that it sits in the content column. */
.pr-main > .pr-progress-panel {
	margin-bottom: clamp(1.25rem, 3vw, 2rem);
}

/* ---------------------------------------------------------- hero motifs -- */

.pr-motif-dango::after,
.pr-motif-petals::after,
.pr-motif-mist::after,
.pr-motif-grain::after,
.pr-motif-embers::after,
.pr-motif-sparkles::after,
.pr-motif-scanlines::after,
.pr-motif-hazard::after {
	content: '';
	position: absolute;
	inset: 0;
	z-index: -1;
	pointer-events: none;
}

/* Clannad: the dango family, as a field of soft circles. */
.pr-motif-dango::after {
	background-image:
		radial-gradient(circle at 20% 30%, color-mix(in srgb, var(--pr-accent-soft) 55%, transparent) 0 9px, transparent 10px),
		radial-gradient(circle at 27% 34%, color-mix(in srgb, var(--pr-accent) 35%, transparent) 0 9px, transparent 10px),
		radial-gradient(circle at 34% 30%, color-mix(in srgb, var(--pr-accent-soft) 45%, transparent) 0 9px, transparent 10px);
	background-size: 260px 260px;
	opacity: 0.5;
}

/* Katawa Shoujo: drifting petals. */
.pr-motif-petals::after {
	background-image:
		radial-gradient(ellipse 7px 4px at 15% 20%, color-mix(in srgb, var(--pr-accent-soft) 70%, transparent) 0 100%, transparent 101%),
		radial-gradient(ellipse 5px 3px at 65% 55%, color-mix(in srgb, var(--pr-accent) 45%, transparent) 0 100%, transparent 101%),
		radial-gradient(ellipse 6px 4px at 88% 28%, color-mix(in srgb, var(--pr-accent-soft) 60%, transparent) 0 100%, transparent 101%);
	background-size: 320px 300px;
	opacity: 0.65;
}

/* Narcissu: a low sea haze. */
.pr-motif-mist::after {
	background-image:
		linear-gradient(0deg, color-mix(in srgb, var(--pr-accent-soft) 45%, transparent) 0%, transparent 45%),
		linear-gradient(100deg, transparent 40%, color-mix(in srgb, var(--pr-accent-soft) 30%, transparent) 70%, transparent 100%);
	opacity: 0.7;
}

/* Sepia Tears: film grain. */
.pr-motif-grain::after {
	background-image:
		repeating-conic-gradient(color-mix(in srgb, var(--pr-accent) 12%, transparent) 0% 25%, transparent 0% 50%);
	background-size: 4px 4px;
	opacity: 0.35;
}

/* Juniper's Knot: embers rising off the ruins. */
.pr-motif-embers::after {
	background-image:
		radial-gradient(circle at 12% 70%, color-mix(in srgb, var(--pr-accent) 80%, transparent) 0 2px, transparent 3px),
		radial-gradient(circle at 47% 40%, color-mix(in srgb, var(--pr-accent-soft) 70%, transparent) 0 1.5px, transparent 3px),
		radial-gradient(circle at 78% 62%, color-mix(in srgb, var(--pr-accent) 65%, transparent) 0 2px, transparent 3px);
	background-size: 180px 200px;
	opacity: 0.8;
}

/* Mhakna Gramura: fairy sparkle. */
.pr-motif-sparkles::after {
	background-image:
		radial-gradient(circle at 25% 25%, color-mix(in srgb, var(--pr-accent-soft) 90%, transparent) 0 1.5px, transparent 2.5px),
		radial-gradient(circle at 70% 60%, color-mix(in srgb, var(--pr-accent) 70%, transparent) 0 1px, transparent 2px);
	background-size: 140px 140px;
	opacity: 0.75;
}

/* FLODT: broadcast scanlines. */
.pr-motif-scanlines::after {
	background-image: repeating-linear-gradient(
		0deg,
		color-mix(in srgb, var(--pr-accent) 16%, transparent) 0 1px,
		transparent 1px 4px
	);
	opacity: 0.5;
}

/* Czarnobyl: hazard stripes. */
.pr-motif-hazard::after {
	background-image: repeating-linear-gradient(
		45deg,
		color-mix(in srgb, var(--pr-accent) 22%, transparent) 0 14px,
		transparent 14px 28px
	);
	opacity: 0.35;
}

/* ------------------------------------------------------- progress panel -- */

.pr-progress-panel {
	background: color-mix(in srgb, var(--pr-paper) 82%, transparent);
	backdrop-filter: blur(8px);
	border: 1px solid var(--pr-line);
	border-left: 4px solid var(--pr-accent);
	border-radius: var(--pr-radius-lg);
	padding: clamp(1.1rem, 3vw, 1.6rem);
	box-shadow: var(--pr-shadow);
}

.pr-progress-panel__title {
	font-family: var(--pr-font-display);
	font-size: 1.15rem;
	margin: 0 0 1rem;
	color: var(--pr-ink);
}

.pr-progress-panel__source {
	margin: 1rem 0 0;
	font-size: 0.85rem;
	color: var(--pr-muted);
}

/* --------------------------------------------------------- progress bar -- */

.pr-bar + .pr-bar {
	margin-top: 0.85rem;
}

.pr-bar__head {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: 1rem;
	margin-bottom: 0.3rem;
}

.pr-bar__label {
	font-weight: 600;
	font-size: 0.92rem;
}

.pr-bar__value {
	font-variant-numeric: tabular-nums;
	font-size: 0.85rem;
	color: var(--pr-muted);
}

.pr-bar__track {
	position: relative;
	height: 10px;
	border-radius: 999px;
	background: var(--pr-surface-2);
	overflow: hidden;
}

.pr-bar__fill {
	height: 100%;
	width: 0;
	border-radius: inherit;
	background: linear-gradient(90deg, var(--pr-accent), var(--pr-accent-soft));
	transition: width 1.1s var(--pr-ease);
}

.is-visible .pr-bar__fill,
.pr-bar__track.is-visible .pr-bar__fill {
	width: var(--pr-fill, 0%);
}

/* ------------------------------------- [skillbar] from the post archive -- */

/*
 * Two rows: the label and its figure share the first, the track spans the
 * second. The shortcode emits them in source order (title, track, percent),
 * so grid areas do the rearranging rather than changing markup that 4800
 * existing shortcodes depend on.
 */
.pr-skillbar {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	grid-template-areas:
		"title percent"
		"track track";
	align-items: baseline;
	column-gap: 1rem;
	row-gap: 0.3rem;
	margin: 0 0 0.9rem;
	font-family: var(--pr-font-ui);
}

.pr-skillbar .skillbar-title {
	grid-area: title;
	margin: 0;
	min-width: 0;
}

.pr-skillbar .skillbar-title h6 {
	font-family: var(--pr-font-display);
	font-size: 1.02rem;
	font-weight: normal;
	letter-spacing: 0.02em;
	margin: 0;
	color: var(--pr-ink);
}

.pr-skillbar .skillbar-track {
	grid-area: track;
	position: relative;
	height: 14px;
	border-radius: 999px;
	background: var(--pr-surface-2);
	overflow: hidden;
}

.pr-skillbar .skillbar-bar {
	height: 100%;
	width: 0;
	border-radius: inherit;
	background: var(--pr-accent);
	transition: width 1.2s var(--pr-ease);
}

.pr-skillbar.is-visible .skillbar-bar {
	width: var(--pr-fill, 0%);
}

.pr-skillbar .skillbar-percent {
	grid-area: percent;
	margin: 0;
	font-size: 0.85rem;
	font-variant-numeric: tabular-nums;
	color: var(--pr-muted);
	text-align: right;
	white-space: nowrap;
}

.pr-skillbar.no-percent .skillbar-percent {
	display: none;
}

/* -------------------------------------------------------- project index -- */

.pr-projects {
	max-width: 1180px;
	margin: 0 auto;
	padding: clamp(2.5rem, 6vw, 4rem) 0 0;
}

.pr-projects__title {
	font-family: var(--pr-font-display);
	font-size: clamp(1.5rem, 3vw, 2rem);
	margin-bottom: 1.25rem;
}

.pr-projects__grid {
	display: grid;
	gap: 1rem;
	grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}

.pr-project {
	position: relative;
	isolation: isolate;
	overflow: hidden;
	display: block;
	padding: 1.25rem;
	border: 1px solid var(--pr-line);
	border-radius: var(--pr-radius-lg);
	background:
		linear-gradient(150deg, color-mix(in srgb, var(--pr-accent) 14%, var(--pr-paper)), var(--pr-paper) 75%);
	color: var(--pr-ink);
	text-decoration: none;
	transition: transform 0.2s var(--pr-ease), box-shadow 0.2s var(--pr-ease);
}

.pr-project:hover {
	transform: translateY(-3px);
	box-shadow: var(--pr-shadow-lg);
	color: var(--pr-ink);
}

.pr-project::before {
	content: '';
	position: absolute;
	inset: 0 auto 0 0;
	width: 4px;
	background: var(--pr-accent);
}

/* Icon and title share a row; the meter and figure sit below. */
.pr-project__head {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	min-width: 0;
}

.pr-project__icon {
	flex: 0 0 auto;
	width: 38px;
	height: 38px;
	border-radius: 8px;
	object-fit: cover;
	/* A thin ring in the project's accent ties the artwork to its palette. */
	box-shadow: 0 0 0 1px color-mix(in srgb, var(--pr-accent) 45%, transparent);
}

.pr-project__name {
	font-family: var(--pr-font-display);
	font-size: 1.2rem;
	margin: 0;
	min-width: 0;
}

.pr-project__tagline {
	margin: 0 0 1rem;
	font-size: 0.88rem;
	color: var(--pr-muted);
	min-height: 2.6em;
}

.pr-project__meter {
	height: 8px;
	border-radius: 999px;
	background: color-mix(in srgb, var(--pr-ink) 10%, var(--pr-paper));
	overflow: hidden;
}

.pr-project__fill {
	height: 100%;
	width: 0;
	border-radius: inherit;
	background: linear-gradient(90deg, var(--pr-accent), var(--pr-accent-soft));
	transition: width 1.1s var(--pr-ease);
}

.pr-project.is-visible .pr-project__fill {
	width: var(--pr-fill, 0%);
}

.pr-project__value {
	display: inline-block;
	margin-top: 0.45rem;
	font-size: 0.82rem;
	font-variant-numeric: tabular-nums;
	color: var(--pr-muted);
}

.pr-project__value--done {
	color: var(--pr-accent);
	font-weight: 600;
}

/* A released project reads as a full, calmer bar. */
.pr-project__fill--done {
	opacity: 0.5;
}

/*
 * Card backgrounds.
 *
 * The motifs are shapes — dango, petals, embers — and shapes need room. In a
 * 250x70 card a tiled pattern reduces to a few stray dots however it is
 * scaled, which reads as noise rather than as the project's character. So on
 * cards every motif is replaced by the treatment that did work at this size:
 * fine horizontal lines over a wash of the project's accent, fading out to the
 * right. It fills any area, stays legible behind text, and the colour alone
 * carries which project it is.
 *
 * Scoped to .pr-project, so the full-width banner keeps its real motif.
 */
.pr-project.pr-motif-dango::after,
.pr-project.pr-motif-petals::after,
.pr-project.pr-motif-embers::after,
.pr-project.pr-motif-sparkles::after,
.pr-project.pr-motif-grain::after,
.pr-project.pr-motif-scanlines::after,
.pr-project.pr-motif-mist::after,
.pr-project.pr-motif-hazard::after,
.pr-project.pr-motif-none::after {
	content: '';
	background-image: linear-gradient(
		100deg,
		color-mix(in srgb, var(--pr-accent) 26%, transparent) 0%,
		color-mix(in srgb, var(--pr-accent) 9%, transparent) 55%,
		transparent 100%
	);
	background-size: auto;
	background-repeat: no-repeat;
	opacity: 1;
}

/* ------------------------------------------------------- game subpages -- */

.pr-gamedesc {
	margin-bottom: clamp(1.25rem, 3vw, 2rem);
}

.pr-section-title {
	font-family: var(--pr-font-display);
	font-size: clamp(1.2rem, 2.6vw, 1.5rem);
	margin: 0 0 1rem;
	padding-bottom: 0.4rem;
	border-bottom: 2px solid color-mix(in srgb, var(--pr-accent) 35%, transparent);
}

/* Separates the news run from the description above it. */
.pr-section-title--news {
	margin-top: clamp(1.75rem, 4vw, 2.5rem);
}


/* ---------------------------------------------------------------- cards -- */

.pr-cards {
	display: grid;
	gap: 1.25rem;
}

.pr-card {
	position: relative;
	display: grid;
	grid-template-columns: 240px minmax(0, 1fr);
	/*
	 * Start-aligned, so the media column is only as tall as the image plus its
	 * credit line. Stretching it to the row height pushed the caption past the
	 * card's bottom edge.
	 */
	align-items: start;
	gap: 1.25rem;
	padding: 1.25rem;
	background: var(--pr-surface);
	border: 1px solid var(--pr-line);
	border-radius: var(--pr-radius-lg);
	transition: box-shadow 0.2s var(--pr-ease), border-color 0.2s var(--pr-ease);
}

/*
 * Lifts with a shadow and a firmer edge, but stays where it is. Nudging the
 * card up on hover moved everything inside it — a long title reflowing under a
 * cursor that had not moved — for an effect the shadow already gives.
 */
.pr-card:hover {
	box-shadow: var(--pr-shadow);
	border-color: color-mix(in srgb, var(--pr-accent) 35%, var(--pr-line));
}

.pr-card:not(:has(.pr-card__media)) {
	grid-template-columns: minmax(0, 1fr);
}

.pr-card__media {
	margin: 0;
	min-width: 0;
}

/*
 * No aspect-ratio and no object-fit: the artwork keeps its own proportions.
 * Much of it is portrait, and cropping every thumbnail to a landscape band cut
 * the characters' heads off.
 */
.pr-card__media img {
	display: block;
	width: 100%;
	height: auto;
	border-radius: var(--pr-radius);
}

.pr-card__body {
	min-width: 0;
}

.pr-card__title {
	font-family: var(--pr-font-display);
	font-size: clamp(1.25rem, 2.4vw, 1.6rem);
	margin: 0.4rem 0 0.35rem;
}

.pr-card__title a {
	color: var(--pr-ink);
	text-decoration: none;
	transition: color 0.2s var(--pr-ease);
}

/*
 * A warm shift toward the project's colour, not a jump to it. Going all the
 * way to the accent moved a large heading from near-black to a saturated hue
 * in one step, which read as the title changing rather than responding.
 *
 * It also read worse: at full strength the hover measured 2.91:1 on Mhakna and
 * 2.98:1 on Narcissu against the card, below AA and well under the resting
 * state it replaced. Mixed at 45% the worst case across every project and both
 * schemes is 5.62:1.
 */
.pr-card__title a:hover {
	color: color-mix(in srgb, var(--pr-accent) 45%, var(--pr-ink));
}

.pr-card__excerpt {
	margin: 0.6rem 0 0;
	color: var(--pr-muted);
	font-size: 0.95rem;
}

.pr-card__progress {
	margin-top: 0.9rem;
	display: flex;
	align-items: center;
	gap: 0.75rem;
}

.pr-card__progress .pr-bar__track {
	flex: 1;
	height: 8px;
}

.pr-card__progress-value {
	font-size: 0.8rem;
	color: var(--pr-muted);
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

/*
 * The artist credit lifted out of the post body along with the thumbnail.
 * The box grows to fit however long the credit is — long artist names and
 * multi-clause credits both wrap rather than spilling out of the card.
 */
.pr-card__caption {
	margin-top: 0.45rem;
	font-size: 0.75rem;
	line-height: 1.4;
	color: var(--pr-muted);
	overflow-wrap: anywhere;
	hyphens: auto;
}

/* The artist link is the point of the credit; keep it visible. */
.pr-card__caption a {
	color: var(--pr-accent);
	text-decoration: underline;
	text-underline-offset: 0.15em;
}

.pr-card__caption a:hover {
	color: color-mix(in srgb, var(--pr-accent) 70%, var(--pr-ink));
}

.pr-card__more {
	display: inline-block;
	margin-top: 0.9rem;
	font-size: 0.88rem;
	font-weight: 600;
	text-decoration: none;
}

/* ---------------------------------------------------------------- badge -- */

/* A post covering two projects shows a badge for each. */
.pr-badges {
	display: inline-flex;
	flex-wrap: wrap;
	gap: 0.35rem;
}

.pr-badge {
	display: inline-block;
	padding: 0.18rem 0.6rem;
	border-radius: 999px;
	background: color-mix(in srgb, var(--pr-accent) 15%, transparent);
	color: var(--pr-accent);
	font-family: var(--pr-font-display);
	font-size: 0.9rem;
	letter-spacing: 0.02em;
	text-decoration: none;
	border: 1px solid color-mix(in srgb, var(--pr-accent) 35%, transparent);
	transition: background 0.15s var(--pr-ease), border-color 0.15s var(--pr-ease),
		color 0.15s var(--pr-ease);
}

/*
 * Hover deepens the tint rather than filling with the accent.
 *
 * A solid fill is a slab of saturated colour, and in dark mode the accent has
 * been lifted so it reads on near-black — which makes the slab bright enough
 * to flare when you run down a list of news items.
 *
 * The label goes to --pr-ink instead of staying accent-coloured. Text and
 * background would otherwise be the same hue, and deepening one while reading
 * the other costs contrast every time: measured across every accent on every
 * page in both schemes, accent-on-tint lands between 1.69:1 and 4.05:1, all of
 * it below AA. Against ink the same chip measures 6.93:1 at worst — better, as
 * it happens, than the resting state it replaces.
 */
.pr-badge:hover,
.pr-badge:focus-visible {
	background: color-mix(in srgb, var(--pr-accent) 28%, transparent);
	border-color: color-mix(in srgb, var(--pr-accent) 55%, transparent);
	color: var(--pr-ink);
}

/* ----------------------------------------------------------------- meta -- */

.pr-meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.4rem 0.9rem;
	font-family: var(--pr-font-display);
	font-size: 0.95rem;
	letter-spacing: 0.01em;
	color: var(--pr-muted);
}

/* The icons separate the items, so the old middot separators are gone. */
.pr-meta__date,
.pr-meta__author,
.pr-meta__comments {
	display: inline-flex;
	align-items: center;
	gap: 0.35rem;
}

.pr-icon {
	flex: 0 0 auto;
	opacity: 0.8;
	/* Nudged to sit on the text's optical centre rather than its baseline. */
	margin-top: -0.05em;
}

.pr-meta__comments {
	color: var(--pr-muted);
	text-decoration: none;
}

.pr-meta__comments:hover {
	color: var(--pr-accent);
}

/* Nameplate: the visual-novel speaker tag. */
.pr-nameplate {
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	padding: 0.35rem 0.9rem 0.35rem 0.35rem;
	border-radius: 999px;
	background: var(--pr-surface-2);
	border: 1px solid var(--pr-line);
}

.pr-nameplate__avatar img {
	display: block;
	width: 32px;
	height: 32px;
	border-radius: 50%;
}

.pr-nameplate__name {
	font-family: var(--pr-font-display);
	font-size: 1rem;
	color: var(--pr-ink);
}

/* -------------------------------------------------------------- article -- */

/*
 * Content panels.
 *
 * Posts, pages, comments and empty states all sit on the same raised surface
 * as the preview cards, rather than directly on the page background — so a
 * post reads as the same object opened up, not as loose text on the beige.
 */
.pr-article,
.pr-comments,
.pr-empty,
.pr-gamedesc {
	background: var(--pr-surface);
	border: 1px solid var(--pr-line);
	border-radius: var(--pr-radius-lg);
	padding: clamp(1.25rem, 4vw, 2.25rem);
}

.pr-article__head {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.85rem;
	padding-bottom: 1.25rem;
	margin-bottom: 1.5rem;
	border-bottom: 1px solid var(--pr-line);
}

.pr-article__title {
	flex-basis: 100%;
	font-family: var(--pr-font-display);
	font-size: clamp(1.9rem, 4.2vw, 2.8rem);
	margin: 0.3rem 0 0.2rem;
}

/* ---------------------------------------------------------- edit link -- */

/*
 * Only rendered for users who can edit the post — see
 * polish_route_edit_link(). Styled as a quiet outline button so it reads as a
 * tool rather than as part of the article.
 */
.pr-edit a {
	display: inline-flex;
	align-items: center;
	gap: 0.35rem;
	padding: 0.25rem 0.7rem;
	border: 1px dashed color-mix(in srgb, var(--pr-accent) 55%, transparent);
	border-radius: 999px;
	font-family: var(--pr-font-ui);
	font-size: 0.8rem;
	font-weight: 600;
	color: var(--pr-accent);
	text-decoration: none;
	transition: background 0.15s var(--pr-ease), border-color 0.15s var(--pr-ease);
}

.pr-edit a:hover,
.pr-edit a:focus-visible {
	background: color-mix(in srgb, var(--pr-accent) 22%, transparent);
	border-color: color-mix(in srgb, var(--pr-accent) 70%, transparent);
	border-style: solid;
	color: var(--pr-ink);
}


/* On a page the link sits under the title rather than on a meta row. */
.pr-article__title + .pr-edit {
	display: block;
	margin-bottom: 1.25rem;
}

/* Author plate and post meta share a row under the title. */
.pr-article__byline {
	flex-basis: 100%;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.85rem;
}

.pr-article__thumb {
	margin: 0 0 2rem;
}

.pr-article__thumb img {
	width: 100%;
	border-radius: var(--pr-radius-lg);
}

/* ------------------------------------------------------------ team page -- */

/*
 * Each person is a paragraph with a floated avatar and their name flowing
 * beside it. The float has to stay — the names are typed around the image, so
 * turning the row into a flex container would split them.
 */
.pr-page-zespol .pr-prose > p {
	/* Contains the float, so an avatar cannot spill into the next person. */
	display: flow-root;
	min-height: 48px;
	margin-top: 0.35rem;
}

.pr-page-zespol .pr-prose img {
	width: 48px;
	height: 48px;
	border-radius: 50%;
	/* One avatar is 64x59; cover keeps it circular rather than an oval. */
	object-fit: cover;
	margin: 0 0.7rem 0.3rem 0;
	box-shadow: 0 0 0 1px var(--pr-line);
}

.pr-page-zespol .pr-prose h5 {
	font-family: var(--pr-font-ui);
	font-size: 1.05rem;
	margin: 1.6rem 0 0.5rem;
	padding-bottom: 0.3rem;
	border-bottom: 2px solid color-mix(in srgb, var(--pr-accent) 30%, transparent);
}

.pr-page-zespol .pr-prose h5:first-child {
	margin-top: 0;
}

/* ---------------------------------------------------------------- prose -- */

.pr-prose {
	font-family: var(--pr-font-prose);
	font-size: 1.06rem;
	line-height: 1.75;
	max-width: var(--pr-measure);
	/*
	 * Posts and comments are full of bare URLs, and a long one is a single
	 * unbreakable word. On a phone that word sets the minimum width of the
	 * page, pushing everything else sideways — the symptom is unrelated text
	 * further down appearing clipped at the left edge.
	 */
	overflow-wrap: break-word;
	word-break: break-word;
}

/*
 * Links get the stronger rule: they may be broken at any character, since a
 * URL has no sensible break points and must never be the widest thing on the
 * page. Ordinary prose keeps break-word, which only breaks a word that would
 * otherwise overflow.
 */
.pr-prose a,
.pr-comments a,
.pr-xfeed__text a {
	overflow-wrap: anywhere;
}

.pr-prose > * + * {
	margin-top: 1.15em;
}

.pr-prose h2,
.pr-prose h3,
.pr-prose h4 {
	font-family: var(--pr-font-ui);
	margin-top: 2em;
	margin-bottom: 0.6em;
}

.pr-prose h2 {
	font-size: 1.6rem;
	padding-bottom: 0.3em;
	border-bottom: 2px solid color-mix(in srgb, var(--pr-accent) 30%, transparent);
}

.pr-prose img {
	border-radius: var(--pr-radius);
}

/*
 * Video embeds fill the column and keep their shape. aspect-ratio gives the
 * iframe the intrinsic proportion it lacks, so height:auto behaves the way it
 * does for an image. Covers both classic-editor iframes and block embeds.
 */
.pr-prose iframe[src*="youtube"],
.pr-prose iframe[src*="youtu.be"],
.pr-prose iframe[src*="vimeo"],
.pr-prose iframe[src*="dailymotion"],
.pr-prose iframe[src*="player.twitch"],
.pr-prose .wp-block-embed__wrapper iframe {
	width: 100%;
	height: auto;
	aspect-ratio: 16 / 9;
}

.pr-prose figure,
.pr-prose .wp-caption {
	margin-left: 0;
	margin-right: 0;
	max-width: 100%;
}

.pr-prose figcaption,
.pr-prose .wp-caption-text {
	font-family: var(--pr-font-ui);
	font-size: 0.85rem;
	color: var(--pr-muted);
	text-align: center;
	margin-top: 0.5rem;
}

.pr-prose blockquote {
	margin-left: 0;
	margin-right: 0;
	padding: 0.5rem 0 0.5rem 1.25rem;
	border-left: 4px solid var(--pr-accent);
	color: var(--pr-muted);
	font-style: italic;
}

.pr-prose code,
.pr-prose pre {
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	font-size: 0.9em;
}

.pr-prose code {
	padding: 0.15em 0.4em;
	border-radius: 4px;
	background: var(--pr-surface-2);
}

.pr-prose pre {
	padding: 1rem;
	overflow-x: auto;
	background: var(--pr-surface-2);
	border-radius: var(--pr-radius);
}

.pr-prose hr {
	border: 0;
	border-top: 1px solid var(--pr-line);
	margin: 2.5em 0;
}

.pr-prose table {
	width: 100%;
	border-collapse: collapse;
	font-family: var(--pr-font-ui);
	font-size: 0.92rem;
}

.pr-prose th,
.pr-prose td {
	padding: 0.5rem 0.7rem;
	border: 1px solid var(--pr-line);
	text-align: left;
}

.pr-prose th {
	background: var(--pr-surface-2);
}

/* Full-width media inside the reading column. */
.pr-prose .alignwide,
.pr-prose .alignfull {
	max-width: none;
	width: 100%;
}

.pr-prose .aligncenter {
	display: block;
	margin-left: auto;
	margin-right: auto;
}

.pr-prose .alignleft {
	float: left;
	margin: 0.3rem 1.4rem 1rem 0;
}

.pr-prose .alignright {
	float: right;
	margin: 0.3rem 0 1rem 1.4rem;
}

/* Progress bars sit outside the prose measure so they use the full width. */
.pr-prose .pr-skillbar {
	max-width: none;
	font-family: var(--pr-font-ui);
}

/* --------------------------------------------------------------- tags/nav */

.pr-tags {
	margin-top: 2rem;
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem;
}

.pr-tags a {
	display: inline-block;
	padding: 0.2rem 0.65rem;
	border-radius: 999px;
	background: var(--pr-surface-2);
	color: var(--pr-muted);
	font-family: var(--pr-font-display);
	font-size: 0.92rem;
	/* Uppercased for display only — the tag names themselves are untouched,
	   so archive pages and the admin still show them as written. */
	text-transform: uppercase;
	letter-spacing: 0.03em;
	text-decoration: none;
	transition: background 0.15s var(--pr-ease), color 0.15s var(--pr-ease);
}

/* Neutral at rest, tinted on hover — the same calmer treatment as the badge. */
.pr-tags a:hover,
.pr-tags a:focus-visible {
	background: color-mix(in srgb, var(--pr-accent) 22%, var(--pr-surface-2));
	color: var(--pr-ink);
}

.pr-post-nav {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 1rem;
	margin: 2.5rem 0;
}

/*
 * The grid stretches these wrappers to equal height already, but the link
 * inside only grew to fit its own text — so a two-line title next to a
 * one-line one left the boxes visibly uneven. Making each wrapper a flex
 * container and letting the link fill it keeps both the same height whatever
 * the titles are.
 */
.pr-post-nav__prev,
.pr-post-nav__next {
	display: flex;
}

.pr-post-nav a {
	display: flex;
	align-items: center;
	flex: 1;
	padding: 1rem;
	background: var(--pr-surface);
	border: 1px solid var(--pr-line);
	border-radius: var(--pr-radius);
	text-decoration: none;
	color: var(--pr-ink);
	font-size: 0.92rem;
	/* A long title should wrap, not widen the row. */
	overflow-wrap: break-word;
	min-width: 0;
}

.pr-post-nav a:hover {
	border-color: var(--pr-accent);
	color: var(--pr-accent);
}

.pr-post-nav__next {
	text-align: right;
	grid-column: 2;
}

.pr-post-nav__next a {
	justify-content: flex-end;
}

/* ----------------------------------------------------------- pagination -- */

.pagination {
	margin-top: 2.5rem;
}

.pagination .nav-links {
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem;
	justify-content: center;
}

.pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 42px;
	height: 42px;
	padding: 0 0.75rem;
	border: 1px solid var(--pr-line);
	border-radius: var(--pr-radius);
	text-decoration: none;
	color: var(--pr-ink);
}

.pagination .page-numbers:hover {
	border-color: var(--pr-accent);
	color: var(--pr-accent);
}

.pagination .page-numbers.current {
	background: var(--pr-accent);
	border-color: var(--pr-accent);
	color: var(--pr-on-accent);
}

/* -------------------------------------------------------------- gallery -- */

.pr-gallery,
.pr-prose .gallery {
	display: grid;
	gap: 0.75rem;
	grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
	margin: 2rem 0;
}

.pr-gallery__item,
.pr-prose .gallery-item {
	margin: 0;
	width: auto !important;
}

.pr-gallery__item img,
.pr-prose .gallery-item img {
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	border-radius: var(--pr-radius);
	border: 1px solid var(--pr-line);
	transition: transform 0.2s var(--pr-ease);
}

.pr-gallery__item a:hover img,
.pr-prose .gallery-item a:hover img {
	transform: scale(1.02);
}

/* ------------------------------------------------------------- lightbox -- */

.pr-lightbox {
	position: fixed;
	inset: 0;
	z-index: 200;

	/*
	 * Must be display:none while closed.
	 *
	 * The browser hides a closed dialog with `dialog:not([open]){display:none}`
	 * in its own stylesheet, but any author rule beats that regardless of
	 * specificity. Setting `display:grid` here unconditionally therefore left
	 * the dialog laid out even when shut: a fixed, full-viewport, z-index 200
	 * sheet at opacity 0, invisible but still catching every click on the page.
	 * The display switch belongs on [open], below.
	 */
	display: none;
	place-items: center;

	/* Undo the dialog defaults: it is a full-screen overlay, not a panel. */
	width: 100%;
	max-width: 100%;
	height: 100%;
	max-height: 100%;
	margin: 0;
	border: 0;

	padding: clamp(1rem, 4vw, 3rem);
	background: rgb(0 0 0 / 88%);
	opacity: 0;
	transition: opacity 0.2s var(--pr-ease);
}

.pr-lightbox[open] {
	display: grid;
	opacity: 1;
}

/* Fades in on open; harmlessly ignored where unsupported. */
@starting-style {
	.pr-lightbox[open] {
		opacity: 0;
	}
}

.pr-lightbox::backdrop {
	background: transparent;
}

.pr-lightbox__img {
	max-width: 100%;
	max-height: 82vh;
	border-radius: var(--pr-radius);
	box-shadow: 0 20px 60px rgb(0 0 0 / 60%);
}

.pr-lightbox__caption {
	margin-top: 0.9rem;
	color: #eee;
	font-size: 0.9rem;
	text-align: center;
	max-width: 60ch;
}

.pr-lightbox__close,
.pr-lightbox__nav {
	position: absolute;
	display: grid;
	place-items: center;
	width: 48px;
	height: 48px;
	border: 1px solid rgb(255 255 255 / 25%);
	border-radius: 50%;
	background: rgb(0 0 0 / 40%);
	color: #fff;
	font-size: 1.2rem;
	cursor: pointer;
}

.pr-lightbox__close:hover,
.pr-lightbox__nav:hover {
	background: rgb(255 255 255 / 15%);
}

.pr-lightbox__close { top: 1rem; right: 1rem; }
.pr-lightbox__nav--prev { left: 1rem; top: 50%; transform: translateY(-50%); }
.pr-lightbox__nav--next { right: 1rem; top: 50%; transform: translateY(-50%); }

/* ------------------------------------------------------------- comments -- */

.pr-comments {
	margin-top: 2rem;
}

.pr-comments__title {
	font-family: var(--pr-font-display);
	font-size: 1.4rem;
	margin-bottom: 1.5rem;
}

.pr-comments__list,
.pr-comments__list .children {
	list-style: none;
	padding: 0;
	margin: 0;
}

.pr-comments__list .children {
	margin-left: clamp(0.75rem, 3vw, 2rem);
	padding-left: clamp(0.75rem, 3vw, 1.25rem);
	border-left: 2px solid var(--pr-line);
}

.pr-comments__list li.comment {
	margin-bottom: 1.25rem;
}

.pr-comments__list article.comment-body {
	padding: 1rem 1.15rem;
	background: var(--pr-surface);
	border: 1px solid var(--pr-line);
	border-radius: var(--pr-radius);
	/* Same reasoning as .pr-prose: comments are where the bare URLs live. */
	overflow-wrap: break-word;
	word-break: break-word;
	min-width: 0;
}

.pr-comments__list .comment-content {
	min-width: 0;
}

.pr-comments__list .comment-author {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	font-weight: 600;
}

.pr-comments__list .comment-author img {
	border-radius: 50%;
}

.pr-comments__list .comment-metadata {
	font-size: 0.8rem;
	color: var(--pr-muted);
	margin-bottom: 0.6rem;
}

.pr-comments__list .comment-metadata a {
	color: inherit;
	text-decoration: none;
}

.pr-comments__list .reply {
	font-size: 0.85rem;
}

/* ----------------------------------------------------------------- forms -- */

input[type='text'],
input[type='email'],
input[type='url'],
input[type='search'],
input[type='password'],
textarea,
select {
	width: 100%;
	padding: 0.6rem 0.8rem;
	font: inherit;
	font-size: 0.95rem;
	color: var(--pr-ink);
	background: var(--pr-paper);
	border: 1px solid var(--pr-line);
	border-radius: var(--pr-radius);
}

input:focus,
textarea:focus,
select:focus {
	border-color: var(--pr-accent);
	outline: none;
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--pr-accent) 22%, transparent);
}

.pr-button,
button[type='submit'],
input[type='submit'],
.comment-form .submit {
	display: inline-block;
	padding: 0.6rem 1.4rem;
	font: inherit;
	font-weight: 600;
	color: var(--pr-on-accent);
	background: var(--pr-accent);
	border: 0;
	border-radius: var(--pr-radius);
	cursor: pointer;
	text-decoration: none;
	transition: filter 0.15s var(--pr-ease);
}

/*
 * A solid accent button is the one place a fill is still right — it is the
 * primary action. But "brighter on hover" is a light-page assumption: on a
 * dark page the accent has already been lifted, so brightening it further
 * glares. --pr-hover-lift flips to a slight darkening there instead.
 */
.pr-button:hover,
button[type='submit']:hover,
input[type='submit']:hover {
	filter: brightness(var(--pr-hover-lift, 1.08));
	color: var(--pr-on-accent);
}

.comment-form label {
	display: block;
	font-size: 0.88rem;
	font-weight: 600;
	margin-bottom: 0.3rem;
}

.comment-form p {
	margin-bottom: 1rem;
}

/* --------------------------------------------------------------- search -- */

.pr-search {
	display: flex;
	gap: 0.5rem;
	max-width: 420px;
}

.pr-search__submit {
	flex: 0 0 auto;
	width: 44px;
	padding: 0;
}

/* -------------------------------------------------------------- sidebar -- */

.pr-sidebar {
	position: sticky;
	top: 90px;
	display: grid;
	gap: 1.5rem;
}

/* The project index, condensed into a sidebar panel. */
.pr-sidebar .pr-projects {
	max-width: none;
	margin: 0;
	padding: 1.15rem;
	background: var(--pr-surface);
	border: 1px solid var(--pr-line);
	border-radius: var(--pr-radius-lg);
}

.pr-sidebar .pr-projects__title {
	font-size: 1.05rem;
	margin-bottom: 0.75rem;
	padding-bottom: 0.5rem;
	border-bottom: 2px solid color-mix(in srgb, var(--pr-accent) 35%, transparent);
}

.pr-sidebar .pr-projects__grid {
	grid-template-columns: minmax(0, 1fr);
	gap: 0.45rem;
}

.pr-sidebar .pr-project {
	padding: 0.6rem 0.75rem;
	border-radius: var(--pr-radius);
	background: var(--pr-paper);
}

.pr-sidebar .pr-project:hover {
	transform: none;
	box-shadow: none;
	border-color: var(--pr-accent);
}

/* The tagline is for the wide layout; it would crowd a 300px column. */
.pr-sidebar .pr-project__tagline {
	display: none;
}

.pr-sidebar .pr-project__name {
	font-size: 0.95rem;
	margin: 0;
}

/* Tighter in a 300px column. */
.pr-sidebar .pr-project__icon {
	width: 32px;
	height: 32px;
}

.pr-sidebar .pr-project__head {
	margin-bottom: 0.45rem;
}

.pr-sidebar .pr-project__value {
	margin-top: 0.3rem;
	font-size: 0.76rem;
}

.pr-sidebar .widget,
.pr-footer .widget {
	background: var(--pr-surface);
	border: 1px solid var(--pr-line);
	border-radius: var(--pr-radius-lg);
	padding: 1.15rem;
}

.widget-title {
	font-family: var(--pr-font-display);
	font-size: 1.05rem;
	margin-bottom: 0.75rem;
	padding-bottom: 0.5rem;
	border-bottom: 2px solid color-mix(in srgb, var(--pr-accent) 35%, transparent);
}

.widget ul {
	list-style: none;
	margin: 0;
	padding: 0;
}

.widget li {
	padding: 0.3rem 0;
	border-bottom: 1px solid var(--pr-line);
	font-size: 0.92rem;
}

.widget li:last-child {
	border-bottom: 0;
}

.widget a {
	text-decoration: none;
	color: var(--pr-ink);
}

.widget a:hover {
	color: var(--pr-accent);
}

/* --------------------------------------------------------------- social -- */

.pr-social {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	padding: 0.7rem 0.9rem;
	border: 1px solid var(--pr-line);
	border-radius: var(--pr-radius);
	background: var(--pr-paper);
	color: var(--pr-ink);
	text-decoration: none;
	transition: border-color 0.2s var(--pr-ease), transform 0.2s var(--pr-ease);
}

.pr-social:hover {
	border-color: var(--pr-brand, var(--pr-accent));
	transform: translateY(-1px);
	color: var(--pr-ink);
}

/*
 * The platform's own colour, so the banner is recognisable at a glance. Its
 * mark is near-black and would vanish on a dark page, so the value comes from
 * --pr-x-mark, which PHP lightens whenever the surface is dark — whether that
 * is because the project is dark or because the reader is in dark mode.
 */
.pr-social--x {
	--pr-brand: var(--pr-x-mark, #0f1419);
}

.pr-social--facebook {
	--pr-brand: #1877f2;
}

.pr-social__icon {
	flex: 0 0 auto;
	color: var(--pr-brand, var(--pr-accent));
}

.pr-social__text {
	display: flex;
	flex-direction: column;
	line-height: 1.25;
	min-width: 0;
}

.pr-social__label {
	font-size: 0.78rem;
	color: var(--pr-muted);
}

.pr-social__handle {
	font-family: var(--pr-font-display);
	font-size: 1.02rem;
	overflow-wrap: anywhere;
}

/* ------------------------------------------------------------- X feed -- */

/*
 * Rebuilt from the posts the old plugin cached in the database, so it needs
 * no third-party script and cannot be blocked the way an embedded timeline is.
 */
.pr-xfeed {
	border: 1px solid var(--pr-line);
	border-radius: var(--pr-radius);
	background: var(--pr-paper);
	padding: 0.9rem;
}

.pr-xfeed__head {
	display: flex;
	align-items: center;
	gap: 0.6rem;
}

.pr-xfeed__avatar {
	width: 44px;
	height: 44px;
	border-radius: 50%;
	flex: 0 0 auto;
}

.pr-xfeed__id {
	display: flex;
	flex-direction: column;
	line-height: 1.2;
	min-width: 0;
	margin-right: auto;
}

.pr-xfeed__name {
	font-family: var(--pr-font-display);
	font-size: 1.02rem;
	color: var(--pr-ink);
	text-decoration: none;
}

.pr-xfeed__name:hover {
	color: var(--pr-accent);
}

.pr-xfeed__handle,
.pr-xfeed__stat {
	font-size: 0.76rem;
	color: var(--pr-muted);
}

.pr-xfeed .pr-social__icon {
	flex: 0 0 auto;
	color: var(--pr-ink);
}

.pr-xfeed__bio {
	margin: 0.7rem 0 0.35rem;
	font-size: 0.82rem;
	line-height: 1.45;
	color: var(--pr-muted);
}

.pr-xfeed__stat {
	margin: 0 0 0.5rem;
}

.pr-xfeed__list {
	list-style: none;
	margin: 0;
	padding: 0;
	border-top: 1px solid var(--pr-line);
}

.pr-xfeed__post {
	padding: 0.7rem 0;
	border-bottom: 1px solid var(--pr-line);
}

.pr-xfeed__text {
	font-size: 0.85rem;
	line-height: 1.5;
	overflow-wrap: anywhere;
}

.pr-xfeed__text a {
	text-decoration: none;
}

.pr-xfeed__text a:hover {
	text-decoration: underline;
}

.pr-xfeed__date {
	display: inline-block;
	margin-top: 0.3rem;
	font-size: 0.72rem;
	color: var(--pr-muted);
	text-decoration: none;
}

.pr-xfeed__date:hover {
	color: var(--pr-accent);
}

.pr-xfeed__more {
	display: inline-block;
	margin-top: 0.7rem;
	font-family: var(--pr-font-display);
	font-size: 0.95rem;
	text-decoration: none;
}

/*
 * Third-party embeds (the Facebook page plugin) are fixed-width by default and
 * overflow a 300px column. Scale them down to fit instead.
 */
.pr-sidebar .fb-page,
.pr-sidebar .fb_iframe_widget,
.pr-sidebar .fb_iframe_widget span,
.pr-sidebar .fb_iframe_widget iframe {
	max-width: 100% !important;
}

.pr-sidebar iframe {
	max-width: 100%;
	border: 0;
}

/* Facebook's iframe is fixed-width; keep it inside a narrower column. */
.pr-fbpage {
	max-width: 100%;
	overflow: hidden;
	border-radius: var(--pr-radius);
}

.pr-fbpage iframe {
	display: block;
	max-width: 100%;
}

/* ---------------------------------------------------- facebook card -- */

.pr-fbcard {
	overflow: hidden;
	border: 1px solid var(--pr-line);
	border-radius: var(--pr-radius);
	background: var(--pr-paper);
}

/*
 * Stands in for the cover photo. The accent gradient is the fallback; set
 * 'polish_route_facebook_banner' to lay artwork over it.
 */
.pr-fbcard__banner {
	height: 62px;
	background-color: var(--pr-accent);
	background-image:
		var(--pr-fb-art, none),
		linear-gradient(120deg, var(--pr-accent), var(--pr-accent-soft));
	background-size: cover;
	background-position: center;
}

.pr-fbcard__body {
	display: flex;
	align-items: flex-end;
	gap: 0.6rem;
	padding: 0 0.85rem;
	/* Lifts the logo so it straddles the banner edge. */
	margin-top: -26px;
}

.pr-fbcard__logo {
	width: 52px;
	height: 52px;
	flex: 0 0 auto;
	border-radius: 12px;
	border: 3px solid var(--pr-paper);
	background: var(--pr-paper);
}

.pr-fbcard__id {
	display: flex;
	flex-direction: column;
	line-height: 1.2;
	min-width: 0;
	padding-bottom: 0.2rem;
}

.pr-fbcard__name {
	font-family: var(--pr-font-display);
	font-size: 1.02rem;
	color: var(--pr-ink);
	overflow-wrap: anywhere;
}

.pr-fbcard__meta {
	font-size: 0.74rem;
	color: var(--pr-muted);
}

.pr-fbcard__button {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.45rem;
	margin: 0.7rem 0.85rem 0.85rem;
	padding: 0.5rem 0.75rem;
	border-radius: var(--pr-radius);
	background: #1877f2;
	color: #fff;
	font-size: 0.88rem;
	font-weight: 600;
	text-decoration: none;
	transition: filter 0.15s var(--pr-ease);
}

.pr-fbcard__button:hover {
	filter: brightness(1.08);
	color: #fff;
}

.pr-fbcard__button .pr-social__icon {
	width: 18px;
	height: 18px;
	color: currentColor;
}

/* --------------------------------------------------------------- footer -- */

.pr-footer {
	margin-top: 4rem;
	background: var(--pr-surface);
	border-top: 1px solid var(--pr-line);
}

.pr-footer__widgets {
	max-width: 1180px;
	margin: 0 auto;
	padding: 2.5rem var(--pr-gutter);
	display: grid;
	gap: 1.5rem;
	grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

.pr-footer__bar {
	border-top: 1px solid var(--pr-line);
}

.pr-footer__bar {
	max-width: 1180px;
	margin: 0 auto;
	padding: 1.25rem var(--pr-gutter);
	display: flex;
	flex-wrap: wrap;
	gap: 1rem;
	align-items: center;
	justify-content: space-between;
	font-size: 0.88rem;
	color: var(--pr-muted);
}

.pr-footer__copy {
	margin: 0;
}

.pr-footer__list {
	display: flex;
	flex-wrap: wrap;
	gap: 1rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.pr-footer__list a {
	color: var(--pr-muted);
	text-decoration: none;
}

.pr-footer__list a:hover {
	color: var(--pr-accent);
}

/* ---------------------------------------------------------------- empty -- */

.pr-empty {
	text-align: center;
	padding-block: clamp(2rem, 8vw, 4rem);
}

.pr-empty__code {
	font-family: var(--pr-font-display);
	font-size: clamp(4rem, 18vw, 9rem);
	line-height: 1;
	margin: 0;
	color: color-mix(in srgb, var(--pr-accent) 35%, transparent);
}

.pr-empty__title {
	font-size: clamp(1.4rem, 4vw, 2rem);
}

.pr-empty .pr-search {
	margin: 1.5rem auto;
}

/* --------------------------------------------------------------- to top -- */

.pr-to-top {
	position: fixed;
	right: 1.25rem;
	bottom: 1.25rem;
	z-index: 80;
	width: 44px;
	height: 44px;
	border: 1px solid var(--pr-line);
	border-radius: 50%;
	background: var(--pr-paper);
	color: var(--pr-ink);
	cursor: pointer;
	box-shadow: var(--pr-shadow);
	transition: opacity 0.2s var(--pr-ease), transform 0.2s var(--pr-ease);
}

.pr-to-top:hover {
	color: var(--pr-accent);
	transform: translateY(-2px);
}

.pr-to-top[hidden] {
	display: none;
}

/* ----------------------------------------------------------- responsive -- */

@media (max-width: 1024px) {
	.pr-layout {
		grid-template-columns: minmax(0, 1fr);
	}

	.pr-sidebar {
		position: static;
	}
}

@media (max-width: 782px) {
	.pr-nav-toggle {
		display: block;
	}

	/* The hamburger owns the right end of the bar here, so the scheme switch
	   goes back to source order, beside the logo. */
	.pr-theme-toggle {
		order: 0;
	}

	/* Logo, name and the menu button all have to fit one line. */
	.pr-brand__name {
		font-size: 1.1rem;
	}

	.pr-brand__tagline {
		display: none;
	}

	.pr-nav {
		position: absolute;
		top: 100%;
		left: 0;
		right: 0;
		display: none;
		padding: 0.75rem var(--pr-gutter) 1.25rem;
		background: var(--pr-paper);
		border-bottom: 1px solid var(--pr-line);
		box-shadow: var(--pr-shadow);

		/* Its own panel, so it is off the banner — same reset as the
		   desktop dropdown, or a dark banner leaves white links on beige. */
		--pr-bar-ink: var(--pr-ink);
		--pr-bar-shadow: none;
		--pr-bar-veil: transparent;
	}

	.pr-nav.is-open {
		display: block;
	}

	.pr-nav__list {
		flex-direction: column;
		align-items: stretch;
		gap: 0;
	}

	.pr-nav__list a {
		padding: 0.7rem 0.5rem;
		border-bottom: 1px solid var(--pr-line);
		border-radius: 0;
	}

	.pr-nav__list .sub-menu {
		position: static;
		opacity: 1;
		visibility: visible;
		transform: none;
		border: 0;
		box-shadow: none;
		padding-left: 1rem;
	}

	.pr-card {
		grid-template-columns: minmax(0, 1fr);
	}

	.pr-post-nav {
		grid-template-columns: minmax(0, 1fr);
	}

	.pr-post-nav__next {
		grid-column: 1;
		text-align: left;
	}

	/* Stacked, so it aligns left like the previous link. */
	.pr-post-nav__next a {
		justify-content: flex-start;
	}

	.pr-prose .alignleft,
	.pr-prose .alignright {
		float: none;
		margin: 1rem auto;
		display: block;
	}

	/* A wide table widens the page exactly as a long URL does; let it scroll
	   inside its own box instead. */
	.pr-prose table {
		display: block;
		max-width: 100%;
		overflow-x: auto;
	}
}

/* ------------------------------------------------------- reduced motion -- */

@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}

	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
	}

	/* Bars still need to reach their value; they just get there instantly. */
	.pr-bar__fill,
	.pr-project__fill,
	.pr-skillbar .skillbar-bar {
		transition: none !important;
	}
}

/* -------------------------------------------------------------- printing -- */

@media print {
	.pr-masthead,
	.pr-nav,
	.pr-sidebar,
	.pr-footer,
	.pr-to-top,
	.pr-post-nav,
	.pr-comments {
		display: none !important;
	}

	body {
		background: #fff;
		color: #000;
	}

	.pr-hero {
		background: none;
		border: 0;
	}
}
