/*
	najib • info — gothic layer
	Loaded last, on top of main.css (Aerial) and share_style.css.
	Palette and glitch language borrowed from ./w174rd.
*/

/* Tokens */

	:root {
		--void:   #000000;
		--pitch:  #0b0b0e;
		--crypt:  #131317;
		--ink:    #cfc7ba;
		--ash:    #7a736a;
		--dim:    #45403a;
		--blood:  #8f1616;
		--ember:  #c2143a;
		--ghost:  #1f7f96;
		/* the cursor mint, borrowed from ./w174rd's caret */
		--glow:   #7de3c3;
		/* the string value leads the line by brightness, not by hue */
		--parchment: #e8e1d5;

		/* Hard black-and-white static, shared by the sigil and the wards.
		   feTurbulence alone is mid-grey mush with random alpha, so it is
		   desaturated, pushed through a steep transfer to force the pixels to
		   the extremes, and has its alpha flattened to 1 — otherwise the tile
		   fades out from under itself and `screen` blending eats what is left. */
		--noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='wn'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.7' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncR type='linear' slope='3.5' intercept='-0.9'/%3E%3CfeFuncG type='linear' slope='3.5' intercept='-0.9'/%3E%3CfeFuncB type='linear' slope='3.5' intercept='-0.9'/%3E%3CfeFuncA type='linear' slope='0' intercept='1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23wn)'/%3E%3C/svg%3E");

		--mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
		--gothic: 'UnifrakturMaguntia', 'Lombardina Initial Two', serif;
		--drop-cap: 'Lombardina Initial One', 'Lombardina Initial Two', 'UnifrakturMaguntia', serif;
	}

/* Basic */

	html, body {
		background: var(--void);
	}

	/* beats share_style.css's blanket `* { font-family: Poppins }`,
	   loses to every icon font's own class rule — which is the point */
	body *, input, select, textarea, button {
		font-family: var(--mono);
	}

	body, input, select, textarea {
		background-color: var(--void);
		color: var(--ink);
		font-family: var(--mono);
		letter-spacing: 0.02em;
		-webkit-font-smoothing: antialiased;
	}

	::selection {
		background: var(--blood);
		color: #fff;
	}

	::-moz-selection {
		background: var(--blood);
		color: #fff;
	}

/* Wrapper */

	#wrapper {
		-moz-animation: wrapper 4s forwards;
		-webkit-animation: wrapper 4s forwards;
		animation: wrapper 4s forwards;
	}

/* BG — flat void, no gradient, no fog */

	#bg {
		width: 100%;
		height: 100%;
		background: var(--void);
	}

/* Glitch — the sigil, never quite holding still */

	.glitch {
		position: relative;
		display: inline-block;
	}

		.glitch:before,
		.glitch:after {
			content: attr(data-text);
			position: absolute;
			top: 0;
			left: 0;
			right: 0;
			bottom: 0;
			pointer-events: none;
			text-shadow: none;
			mix-blend-mode: screen;
		}

		.glitch:before {
			color: var(--ember);
			-webkit-transform: translateX(-0.035em);
			transform: translateX(-0.035em);
			-webkit-animation: slice-a 6.5s steps(1, end) infinite;
			animation: slice-a 6.5s steps(1, end) infinite;
		}

		.glitch:after {
			color: var(--ghost);
			-webkit-transform: translateX(0.035em);
			transform: translateX(0.035em);
			-webkit-animation: slice-b 6.5s steps(1, end) infinite;
			animation: slice-b 6.5s steps(1, end) infinite;
		}

	@keyframes slice-a {
		0%, 74%, 100% { clip-path: inset(100% 0 0 0); }
		75% { clip-path: inset(10% 0 66% 0); }
		77% { clip-path: inset(64% 0 18% 0); }
		79% { clip-path: inset(100% 0 0 0); }
		81% { clip-path: inset(34% 0 48% 0); }
		83% { clip-path: inset(4% 0 82% 0); }
		85% { clip-path: inset(72% 0 12% 0); }
		87% { clip-path: inset(100% 0 0 0); }
		89% { clip-path: inset(22% 0 60% 0); }
		91% { clip-path: inset(52% 0 30% 0); }
		93% { clip-path: inset(12% 0 74% 0); }
		95% { clip-path: inset(100% 0 0 0); }
		97% { clip-path: inset(60% 0 24% 0); }
		99% { clip-path: inset(30% 0 52% 0); }
	}

	@keyframes slice-b {
		0%, 74%, 100% { clip-path: inset(0 0 100% 0); }
		76% { clip-path: inset(56% 0 28% 0); }
		78% { clip-path: inset(18% 0 70% 0); }
		80% { clip-path: inset(74% 0 10% 0); }
		82% { clip-path: inset(0 0 100% 0); }
		84% { clip-path: inset(42% 0 42% 0); }
		86% { clip-path: inset(8% 0 76% 0); }
		88% { clip-path: inset(66% 0 20% 0); }
		90% { clip-path: inset(0 0 100% 0); }
		92% { clip-path: inset(36% 0 50% 0); }
		94% { clip-path: inset(78% 0 8% 0); }
		96% { clip-path: inset(16% 0 68% 0); }
		98% { clip-path: inset(48% 0 36% 0); }
		99% { clip-path: inset(0 0 100% 0); }
	}

/* Header — the sigil */

	#header {
		top: -1.5em;
	}

	.title_content {
		display: inline-flex;
		align-items: center;
		gap: 0.1em;
	}

		#header .title_content h1 {
			position: relative;
			font-family: var(--drop-cap) !important;
			font-size: clamp(4.5rem, 19vw, 8.5rem) !important;
			font-weight: normal;
			line-height: 0.9;
			letter-spacing: 0;
			color: var(--blood);
			text-shadow:
				0 0 0.08em rgba(143, 22, 22, 0.55),
				0 0 0.4em rgba(143, 22, 22, 0.32),
				0 0 1.1em rgba(143, 22, 22, 0.16);
			-webkit-animation: candle 7s ease-in-out infinite;
			animation: candle 7s ease-in-out infinite;
		}

		#header .title_content span {
			font-family: var(--gothic);
			font-size: clamp(1.1rem, 5vw, 2rem);
			line-height: 0.95;
			margin-left: 0.15em;
			text-align: left;
			color: var(--ink);
			opacity: 0.9;
			text-shadow: 0 0 0.6em rgba(207, 199, 186, 0.16);
		}

		/* UnifrakturMaguntia does cover ~, but draws it as a rounded rectangle
		   — no wave, 148 of 2048 units tall, flatter than its own hyphen — so at
		   this size it reads as a dash. Mono keeps the wave and echoes the ~ in
		   the prompt below; the name either side stays blackletter. */
		#header .title_content span .tilde {
			font-family: var(--mono);
			font-size: 0.78em;
			vertical-align: 0.12em;
			letter-spacing: 0;
		}

		/* the sigil's own :before/:after are the chromatic ghosts, so the static
		   needs a third layer — an empty child inside the h1 */
		#header .title_content h1 .noise {
			position: absolute;
			top: 0;
			left: 0;
			right: 0;
			bottom: 0;
			pointer-events: none;
		}

		/* A plain noise rectangle reads as a grey card, and mix-blend-mode cannot
		   fix it: the h1 animates opacity, so it isolates its own blend group and
		   the backdrop inside it is transparent, not the black page. So the static
		   is painted into a third copy of the letter and clipped to the glyph with
		   background-clip: text — the noise can then only land on the ink. */
		#header .title_content h1 .noise:before {
			content: attr(data-text);
			position: absolute;
			top: 0;
			left: 0;
			font-family: var(--drop-cap);
			font-style: normal;
			font-weight: normal;
			letter-spacing: 0;
			white-space: pre;
			background-image: var(--noise);
			-webkit-background-clip: text;
			background-clip: text;
			color: transparent;
			-webkit-text-fill-color: transparent;
			text-shadow: none;
			opacity: 0;
			-webkit-animation: sigil-noise 6.5s steps(1, end) infinite;
			animation: sigil-noise 6.5s steps(1, end) infinite;
		}

		/* banded, not a solid fill, and timed to the 74–100% window where
		   slice-a / slice-b fire so the static lands with the tearing */
		@keyframes sigil-noise {
			0%, 73%, 100% { opacity: 0; clip-path: inset(100% 0 0 0); }
			74% { opacity: 0.6;  clip-path: inset(12% 0 62% 0); background-position: 0 0; }
			76% { opacity: 0.35; clip-path: inset(58% 0 20% 0); background-position: -37px 21px; }
			78% { opacity: 0;    clip-path: inset(100% 0 0 0); }
			80% { opacity: 0.55; clip-path: inset(30% 0 44% 0); background-position: 43px -19px; }
			82% { opacity: 0.3;  clip-path: inset(6% 0 76% 0);  background-position: 25px 37px; }
			84% { opacity: 0;    clip-path: inset(100% 0 0 0); }
			86% { opacity: 0.5;  clip-path: inset(66% 0 12% 0); background-position: -51px -12px; }
			88% { opacity: 0.28; clip-path: inset(20% 0 54% 0); background-position: 17px 45px; }
			90% { opacity: 0;    clip-path: inset(100% 0 0 0); }
			93% { opacity: 0.45; clip-path: inset(44% 0 34% 0); background-position: -29px 11px; }
			95% { opacity: 0.25; clip-path: inset(10% 0 68% 0); background-position: 39px -41px; }
			97% { opacity: 0;    clip-path: inset(100% 0 0 0); }
			99% { opacity: 0.35; clip-path: inset(72% 0 8% 0);  background-position: -13px 27px; }
		}

	@keyframes candle {
		0%, 100% { opacity: 1; }
		41% { opacity: 0.95; }
		43% { opacity: 0.68; }
		46% { opacity: 0.97; }
		61% { opacity: 0.83; }
		64% { opacity: 1; }
	}

/* Header — the incantation */

	#header .typed {
		display: block;
		font-family: var(--mono);
		font-size: clamp(0.85rem, 3.4vw, 1.25rem);
		/* no editor or terminal tracks its type out — this is the single thing
		   that made the line read as decoration instead of as code */
		letter-spacing: 0.05em;
		line-height: 1.6;
		margin: 1.8em 0 0.4em 0;
		color: var(--ash);
		opacity: 1;
	}

		/* the braced group is centred; #typed-text gets a per-label slot in JS
		   so the group holds still while a label types and only re-centres
		   between labels, the closing brace landing hugging each one. */
		#header .typed {
			text-align: center;
		}

		/* share_style.css sets a blanket `header span { font-size: 25px }` that
		   hijacks every span in this line and breaks the em-based sizing below.
		   Reset the typed spans to inherit so the prompt, quotes and label size
		   from .typed again (the brace and valbox rules below are more specific
		   and still win). */
		#header .typed span {
			font-size: inherit;
		}

		/* the gothic braces, borrowed from the very first typed line */
		#header .typed .brace {
			color: var(--blood);
			font-size: 2.6em;
			line-height: 0;
			vertical-align: middle;
			margin: 0 0.12em;
			text-shadow: 0 0 0.6em rgba(143, 22, 22, 0.45);
			-webkit-user-select: none;
			user-select: none;
		}

		/* shrink-to-fit box holding prompt + label, so the brace after it hugs */
		#header .typed .cmdbox {
			display: inline-block;
			vertical-align: middle;
			white-space: nowrap;
		}

		/* najib@server1 prompt: the two names carry light, the separators recede
		   to --dim so it reads as najib then server1, and the $ keeps the blood. */
		#header .typed .prompt {
			-webkit-user-select: none;
			user-select: none;
			/* the gap to the quoted label is a margin, not a literal space: a mono
			   space plus this line's 0.05em tracking ran near 0.65em, and the
			   opening quote carries side bearing of its own on top of that. */
			margin-right: 0.25em;
		}

			#header .typed .user {
				color: #3e0712;
				text-shadow: 0 0 0.6em rgba(62, 7, 18, 0.4);
			}

			#header .typed .host {
				color: #10333e;
				text-shadow: 0 0 0.6em rgba(16, 51, 62, 0.4);
			}

			/* the @, the path and the $/# sigil all recede to --dim */
			#header .typed .at,
			#header .typed .path,
			#header .typed .sh {
				color: var(--dim);
			}

		/* quotes wrap the label in a dark tone, the way the first typed line
		   had them — punctuation that frames the value without competing. */
		#header .typed .quote {
			color: var(--dim);
		}

		/* The fixed box is .valbox, not the label: it wraps the quotes and the
		   label and gets a per-label width in JS, holding the prompt and brace
		   still. Its width only changes between labels, so easing it glides the
		   brace to the next length and re-centres the group instead of snapping. */
		#header .typed .valbox {
			display: inline-block;
			text-align: left;
			white-space: nowrap;
			/* the quoted label sits smaller than the prompt that frames it */
			font-size: 0.92em;
			transition: width 0.32s cubic-bezier(0.33, 1, 0.68, 1);
		}

		/* the label is the bright thing; inline, so the closing quote right
		   after it follows the caret across the box as it types. */
		#header .typed #typed-text {
			color: var(--parchment);
			text-shadow: 0 0 0.7em rgba(232, 225, 213, 0.2);
		}

		/* typed.js parks its cursor at the slot's right edge; hide it and draw
		   the caret as ::after so it sits right after the text and snaps like a
		   terminal cursor rather than fading. */
		#header .typed .typed-cursor {
			display: none;
		}

		#header .typed #typed-text:after {
			content: '';
			display: inline-block;
			width: 0.55ch;
			height: 1em;
			margin-left: 0.15ch;
			vertical-align: -0.12em;
			background: var(--glow);
			box-shadow: 0 0 0.7em rgba(125, 227, 195, 0.55);
			-webkit-animation: term-blink 1.06s steps(1, end) infinite;
			animation: term-blink 1.06s steps(1, end) infinite;
		}

		@keyframes term-blink {
			0%, 50%      { opacity: 1; }
			50.01%, 100% { opacity: 0; }
		}

/* Header — the wards */

	/* The gap to the typed line above is this margin alone: #header is an
	   inline-block, so the two are block siblings and their margins collapse
	   — .typed's own 0.4em bottom is absorbed and never adds to it. */
	#header nav {
		margin: 3.2em 0 0 0;
	}

		/* flex instead of inline-block so the row never spills past #header */
		#header nav ul {
			display: flex;
			flex-wrap: wrap;
			align-items: flex-start;
			justify-content: center;
		}

		/* labels are wider than the 2.5em circle and overflow it, so the
		   gutter has to clear the widest one ("GOOGLE PLAY"), not the circle */
		#header nav li {
			height: 6em;
			margin-left: 22px;
			margin-right: 22px;
		}

		#header nav a {
			-moz-transition: all 0.35s ease-in-out;
			-webkit-transition: all 0.35s ease-in-out;
			transition: all 0.35s ease-in-out;
			border: solid 1px rgba(207, 199, 186, 0.16);
			background-color: rgba(207, 199, 186, 0.015);
			box-shadow: inset 0 0 1.6em rgba(0, 0, 0, 0.65);
			color: var(--ash);
			font-size: 1.6em;
			margin-left: auto;
			margin-right: auto;
		}

			#header nav a:hover,
			#header nav a:focus-visible {
				background-color: rgba(143, 22, 22, 0.14);
				border-color: var(--blood);
				color: var(--ink);
				box-shadow:
					0 0 1.5em rgba(143, 22, 22, 0.4),
					inset 0 0 1.2em rgba(143, 22, 22, 0.28);
				-webkit-transform: translateY(-2px);
				transform: translateY(-2px);
				outline: none;
				-webkit-animation: ward-tear 0.4s steps(1, end) 1;
				animation: ward-tear 0.4s steps(1, end) 1;
			}

			/* Ambient tear, dealt out at random by assets/js/glitch.js.
			   Reuses the hover keyframes verbatim — same 0.4s, same offsets — so
			   an unattended ward tears exactly the way a hovered one does. The
			   :not(:hover) means a ward caught mid-burst hands over to the real
			   hover the instant the pointer arrives. */
			#header nav a.is-glitching:not(:hover) {
				-webkit-animation: ward-tear 0.4s steps(1, end) 1;
				animation: ward-tear 0.4s steps(1, end) 1;
			}

			#header nav a.is-glitching:not(:hover):after {
				-webkit-animation: ward-noise 0.4s steps(1, end) 1;
				animation: ward-noise 0.4s steps(1, end) 1;
			}

			#header nav a.is-glitching:not(:hover) .title:before {
				-webkit-animation: label-tear-a 0.4s steps(1, end) 1;
				animation: label-tear-a 0.4s steps(1, end) 1;
			}

			#header nav a.is-glitching:not(:hover) .title:after {
				-webkit-animation: label-tear-b 0.4s steps(1, end) 1;
				animation: label-tear-b 0.4s steps(1, end) 1;
			}

			/* harder hit on press — later rule, so it wins over :hover */
			#header nav a:active {
				-webkit-animation: ward-hit 0.28s steps(1, end) 1;
				animation: ward-hit 0.28s steps(1, end) 1;
			}

			/* drop-shadow splits the whole subtree, so the two <img> marks tear
			   along with the icon-font glyphs — one effect covers all seven.
			   No transform here on purpose: the ward holds still and only the
			   colour separates, so the hover rule's own lift stays undisturbed. */
			/* offsets stay under the 22px gutter so a torn ward never bleeds
			   into its neighbour */
			@keyframes ward-tear {
				0%   { filter: drop-shadow(6px 0 var(--ember)) drop-shadow(-6px 0 var(--ghost)); }
				15%  { filter: drop-shadow(-9px 1px var(--ember)) drop-shadow(9px -1px var(--ghost)); }
				30%  { filter: none; }
				45%  { filter: drop-shadow(8px -1px var(--ghost)) drop-shadow(-8px 1px var(--ember)); }
				60%  { filter: drop-shadow(-4px 0 var(--ember)) drop-shadow(4px 0 var(--ghost)); }
				75%  { filter: drop-shadow(2px 0 var(--ghost)); }
				100% { filter: none; }
			}

			@keyframes ward-hit {
				0%   { filter: drop-shadow(12px 0 var(--ember)) drop-shadow(-12px 0 var(--ghost)); }
				20%  { filter: drop-shadow(-15px 2px var(--ember)) drop-shadow(15px -2px var(--ghost)); }
				40%  { filter: none; }
				60%  { filter: drop-shadow(11px -2px var(--ghost)) drop-shadow(-11px 2px var(--ember)); }
				80%  { filter: drop-shadow(-6px 0 var(--ember)) drop-shadow(6px 0 var(--ghost)); }
				100% { filter: none; }
			}

			/* static burst inside the ring — FontAwesome owns :before, :after is free */
			#header nav a:after {
				content: '';
				position: absolute;
				top: 0;
				left: 0;
				right: 0;
				bottom: 0;
				border-radius: 100%;
				opacity: 0;
				pointer-events: none;
				mix-blend-mode: screen;
				background-image: var(--noise);
			}

			#header nav a:hover:after,
			#header nav a:focus-visible:after {
				-webkit-animation: ward-noise 0.4s steps(1, end) 1;
				animation: ward-noise 0.4s steps(1, end) 1;
			}

			#header nav a:active:after {
				-webkit-animation: ward-noise-hard 0.28s steps(1, end) 1;
				animation: ward-noise-hard 0.28s steps(1, end) 1;
			}

			/* the tile is only shifted, never scaled — resampling would blur it
			   and static has to stay pixel-hard to read as interference */
			@keyframes ward-noise {
				0%   { opacity: 0.85; background-position: 0 0; }
				15%  { opacity: 0.5;  background-position: -37px 21px; }
				30%  { opacity: 0.12; background-position: 43px 9px; }
				45%  { opacity: 0.78; background-position: 19px -43px; }
				60%  { opacity: 0.4;  background-position: -51px -12px; }
				75%  { opacity: 0.15; background-position: -23px 47px; }
				100% { opacity: 0; }
			}

			@keyframes ward-noise-hard {
				0%   { opacity: 1;    background-position: 11px -29px; }
				20%  { opacity: 0.7;  background-position: -44px 33px; }
				40%  { opacity: 0.28; background-position: 39px 41px; }
				60%  { opacity: 0.92; background-position: 27px 17px; }
				80%  { opacity: 0.5;  background-position: -18px -55px; }
				100% { opacity: 0; }
			}

			/* The label is wider than the 2.5em ring, and an in-flow block can only
			   overflow to the right — so every label longer than the circle drifted
			   off its axis, worst on GOOGLE PLAY. Out of flow it shrinks to the text
			   and centres on its own width; top: 100% plus the inherited .5em margin
			   reproduces where it sat before. */
			#header nav a .title {
				position: absolute;
				/* +2px: box-sizing is border-box, so 100% stops at the padding box,
				   2px inside where the icon's full-em line box used to end */
				top: calc(100% + 2px);
				left: 50%;
				transform: translateX(-50%);
				font-family: var(--mono);
				font-size: 0.68rem !important;
				letter-spacing: 0.14em;
				text-transform: uppercase;
				color: var(--ash);
				-moz-transition: color 0.35s ease-in-out;
				-webkit-transition: color 0.35s ease-in-out;
				transition: color 0.35s ease-in-out;
			}

			/* label ghosts — invisible until a burst drives their own opacity */
			#header nav a .title:before,
			#header nav a .title:after {
				content: attr(data-text);
				position: absolute;
				top: 0;
				left: 0;
				right: 0;
				opacity: 0;
				pointer-events: none;
				mix-blend-mode: screen;
			}

			#header nav a .title:before {
				color: var(--ember);
			}

			#header nav a .title:after {
				color: var(--ghost);
			}

			#header nav a:hover .title:before,
			#header nav a:focus-visible .title:before,
			#header nav a:active .title:before {
				color: var(--ember);
				-webkit-animation: label-tear-a 0.4s steps(1, end) 1;
				animation: label-tear-a 0.4s steps(1, end) 1;
			}

			#header nav a:hover .title:after,
			#header nav a:focus-visible .title:after,
			#header nav a:active .title:after {
				color: var(--ghost);
				-webkit-animation: label-tear-b 0.4s steps(1, end) 1;
				animation: label-tear-b 0.4s steps(1, end) 1;
			}

			/* ghosts only — the real label never moves. Capped at 5px so a slice
			   stays inside the li rather than running under the next label. */
			@keyframes label-tear-a {
				0%   { opacity: 1; transform: translateX(-5px); clip-path: inset(14% 0 52% 0); }
				25%  { opacity: 1; transform: translateX(4px);  clip-path: inset(58% 0 10% 0); }
				50%  { opacity: 1; transform: translateX(-5px); clip-path: inset(4% 0 66% 0); }
				75%  { opacity: 1; transform: translateX(3px);  clip-path: inset(40% 0 26% 0); }
				100% { opacity: 0; transform: translateX(0);    clip-path: inset(0 0 100% 0); }
			}

			@keyframes label-tear-b {
				0%   { opacity: 1; transform: translateX(5px);  clip-path: inset(50% 0 18% 0); }
				25%  { opacity: 1; transform: translateX(-5px); clip-path: inset(8% 0 62% 0); }
				50%  { opacity: 1; transform: translateX(4px);  clip-path: inset(66% 0 4% 0); }
				75%  { opacity: 1; transform: translateX(-3px); clip-path: inset(26% 0 42% 0); }
				100% { opacity: 0; transform: translateX(0);    clip-path: inset(0 0 100% 0); }
			}

			#header nav a:hover .title,
			#header nav a:focus-visible .title {
				color: var(--ink);
			}

			/* the two <img> marks can't inherit currentColor — dim them instead */
			.fa-wattpad,
			.fa-w174rd {
				opacity: 0.5;
				-moz-transition: all 0.35s ease-in-out;
				-webkit-transition: all 0.35s ease-in-out;
				transition: all 0.35s ease-in-out;
			}

			#header nav a:hover .fa-wattpad,
			#header nav a:hover .fa-w174rd,
			#header nav a:focus-visible .fa-wattpad,
			#header nav a:focus-visible .fa-w174rd {
				opacity: 1;
				-webkit-filter: drop-shadow(0 0 0.35em rgba(194, 20, 58, 0.65));
				filter: drop-shadow(0 0 0.35em rgba(194, 20, 58, 0.65));
			}

/* Footer */

	#footer {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: flex-end;
		gap: 0.9em;
		height: auto;
		line-height: 1.6;
		padding: 4em 1em 1.5em 1em;
		background-image: linear-gradient(to top, rgba(0, 0, 0, 0.8), rgba(0, 0, 0, 0));
	}

		#footer .copyright {
			font-family: var(--mono);
			font-size: 0.72rem;
			letter-spacing: 0.24em;
			text-transform: uppercase;
			color: var(--dim);
		}

			#footer .copyright a {
				border-bottom: 0;
				color: var(--ash);
				-moz-transition: all 0.4s ease-in-out;
				-webkit-transition: all 0.4s ease-in-out;
				transition: all 0.4s ease-in-out;
			}

				#footer .copyright a:hover {
					color: var(--ember);
					text-shadow: 0 0 0.8em rgba(194, 20, 58, 0.5);
				}

			.copyright .icon-footer {
				font-family: var(--gothic);
				font-size: 1.75em;
				line-height: 0;
				color: var(--blood);
				vertical-align: -0.22em;
				margin-right: 0.1em;
			}

/* Share + QR — dragged out of the light */

	.share-button-container {
		position: relative;
		z-index: 20;
	}

		/* no frame — the 38px box is kept only as a hit area */
		.view-modal,
		.view-modal-qrcode {
			display: inline-flex;
			align-items: center;
			justify-content: center;
			width: 38px;
			height: 38px;
			padding: 0;
			margin-left: 0;
			font-size: 21px;
			color: var(--ash);
			border: 0;
			border-radius: 0;
			background-color: transparent;
			box-shadow: none;
			-moz-transition: color 0.35s ease-in-out, text-shadow 0.35s ease-in-out;
			-webkit-transition: color 0.35s ease-in-out, text-shadow 0.35s ease-in-out;
			transition: color 0.35s ease-in-out, text-shadow 0.35s ease-in-out;
		}

			.view-modal:hover,
			.view-modal-qrcode:hover,
			.view-modal:focus-visible,
			.view-modal-qrcode:focus-visible {
				color: var(--ink);
				text-shadow: 0 0 0.7em rgba(143, 22, 22, 0.6);
				outline: none;
			}

			.view-modal:hover,
			.view-modal-qrcode:hover,
			.view-modal:focus-visible,
			.view-modal-qrcode:focus-visible,
			.view-modal.is-glitching:not(:hover),
			.view-modal-qrcode.is-glitching:not(:hover) {
				-webkit-animation: tool-tear 0.4s steps(1, end) 1;
				animation: tool-tear 0.4s steps(1, end) 1;
			}

			.view-modal:active,
			.view-modal-qrcode:active {
				-webkit-animation: tool-hit 0.28s steps(1, end) 1;
				animation: tool-hit 0.28s steps(1, end) 1;
			}

			/* One red ghost, never a red-and-cyan pair. Opposing warm and cool
			   fringes on a dark ground is the TikTok mark, and it stays the
			   TikTok mark however small the offset gets — the cool half has to
			   go, not shrink. A single displaced channel still reads as a signal
			   fault, and red-on-black is the palette the rest of the page is in.
			   Offsets are the tools' own: the wards' 6-9px is scaled to a 69px
			   circle and would swamp a 21px glyph. */
			@keyframes tool-tear {
				0%   { filter: drop-shadow(-2px 0 var(--ember)); }
				20%  { filter: drop-shadow(3px 1px var(--ember)); }
				32%  { filter: none; }
				46%  { filter: drop-shadow(-2px -1px var(--ember)); }
				64%  { filter: drop-shadow(1px 0 var(--ember)); }
				80%, 100% { filter: none; }
			}

			@keyframes tool-hit {
				0%   { filter: drop-shadow(-4px 0 var(--ember)); }
				22%  { filter: drop-shadow(4px 2px var(--ember)); }
				40%  { filter: none; }
				60%  { filter: drop-shadow(-3px -2px var(--ember)); }
				80%  { filter: drop-shadow(2px 0 var(--ember)); }
				100% { filter: none; }
			}

			/* With the frame gone there is nothing to hold a square of static, so
			   the noise goes into the glyph itself. Painting it as the background
			   of unicons' own :before and clipping to text needs no codepoint —
			   which matters, because the icon font is served from a CDN and its
			   private-use values are not ours to hardcode. */
			.view-modal:hover i:before,
			.view-modal-qrcode:hover i:before,
			.view-modal:focus-visible i:before,
			.view-modal-qrcode:focus-visible i:before,
			.view-modal:active i:before,
			.view-modal-qrcode:active i:before,
			.view-modal.is-glitching:not(:hover) i:before,
			.view-modal-qrcode.is-glitching:not(:hover) i:before {
				background-image: var(--noise);
				-webkit-background-clip: text;
				background-clip: text;
				-webkit-animation: tool-noise 0.4s steps(1, end) 1;
				animation: tool-noise 0.4s steps(1, end) 1;
			}

			/* The glyph flickers between its own colour and static rather than
			   being overlaid — there is no second copy of it to overlay with, so
			   "more noise" has to mean more of the burst spent as static. It sits
			   in static ~80% of the time now, the clean frames only punctuating
			   it, and the tile is reseated on every one so the grain keeps moving
			   instead of freezing into a texture. */
			@keyframes tool-noise {
				0%        { -webkit-text-fill-color: transparent; background-position: 0 0; }
				14%       { -webkit-text-fill-color: transparent; background-position: -37px 21px; }
				28%       { -webkit-text-fill-color: currentColor; }
				34%       { -webkit-text-fill-color: transparent; background-position: 43px 9px; }
				48%       { -webkit-text-fill-color: transparent; background-position: 19px -43px; }
				60%       { -webkit-text-fill-color: currentColor; }
				66%       { -webkit-text-fill-color: transparent; background-position: -51px -12px; }
				80%       { -webkit-text-fill-color: transparent; background-position: 27px 35px; }
				92%, 100% { -webkit-text-fill-color: currentColor; }
			}

	/* Only the page behind is blurred — the panels sit above this layer and
	   keep their own opaque --pitch ground */
	.modal-backdrop {
		position: fixed;
		inset: 0;
		z-index: 25;
		background: rgba(0, 0, 0, 0.55);
		-webkit-backdrop-filter: blur(3px) saturate(0.85);
		backdrop-filter: blur(3px) saturate(0.85);
		opacity: 0;
		pointer-events: none;
		transition: opacity 0.2s ease-in-out;
	}

		.modal-backdrop.show {
			opacity: 1;
			pointer-events: auto;
		}

	.popup,
	.popup-qrcode {
		z-index: 30;
		background: var(--pitch);
		color: var(--ink);
		border: 1px solid rgba(143, 22, 22, 0.3);
		border-radius: 2px;
		box-shadow:
			0 0 0 1px rgba(0, 0, 0, 0.6),
			0 24px 60px rgba(0, 0, 0, 0.85),
			0 0 90px rgba(143, 22, 22, 0.1);
	}

		.popup header,
		.popup-qrcode header {
			border-bottom: 1px solid rgba(207, 199, 186, 0.1);
		}

		.popup header span,
		.popup-qrcode header span {
			font-family: var(--gothic);
			font-size: 1.5rem;
			font-weight: normal;
			letter-spacing: 0.02em;
			color: var(--ink);
		}

		.popup header .close,
		.popup-qrcode header .close {
			background: transparent;
			border: 1px solid rgba(207, 199, 186, 0.14);
			border-radius: 0;
			color: var(--dim);
		}

			.popup header .close:hover,
			.popup-qrcode header .close:hover {
				background: rgba(143, 22, 22, 0.16);
				border-color: var(--blood);
				color: var(--ink);
			}

		.content_share p,
		.content-qrcode p {
			font-family: var(--mono);
			font-size: 0.62rem;
			font-weight: normal;
			letter-spacing: 0.26em;
			text-transform: uppercase;
			color: var(--ash);
		}

		/* seven 50px tiles never fit a 380px modal — shrink and wrap them */
		.popup .icons {
			flex-wrap: wrap;
			justify-content: center;
			gap: 5px;
			overflow: visible;
		}

		/* one voice, not seven brand colours */
		.popup .icons a,
		.popup .icons a:nth-child(1),
		.popup .icons a:nth-child(2),
		.popup .icons a:nth-child(3),
		.popup .icons a:nth-child(4),
		.popup .icons a:nth-child(5),
		.popup .icons a:nth-child(6),
		.popup .icons a:nth-child(7) {
			color: var(--ash);
			border-radius: 0;
			border: 1px solid rgba(207, 199, 186, 0.14);
			background: transparent;
			margin-right: 0;
		}

			.popup .icons a i {
				width: 38px;
				height: 38px;
				padding: 10px;
				font-size: 17px;
			}

			.popup .icons a:hover,
			.popup .icons a:nth-child(1):hover,
			.popup .icons a:nth-child(2):hover,
			.popup .icons a:nth-child(3):hover,
			.popup .icons a:nth-child(4):hover,
			.popup .icons a:nth-child(5):hover,
			.popup .icons a:nth-child(6):hover,
			.popup .icons a:nth-child(7):hover {
				color: var(--ink);
				border-color: var(--blood);
				background: rgba(143, 22, 22, 0.16);
			}

		.content_share .field {
			border: 1px solid rgba(207, 199, 186, 0.14);
			border-radius: 0;
			background: rgba(0, 0, 0, 0.35);
		}

			.field.active {
				border-color: var(--blood);
			}

			.field i {
				color: var(--dim);
			}

			.field.active i {
				color: var(--ember);
			}

			.field input {
				font-family: var(--mono);
				font-size: 0.8rem;
				letter-spacing: 0.04em;
				color: var(--ink);
				background-color: transparent;
			}

			.field button {
				font-family: var(--mono);
				font-size: 0.62rem;
				letter-spacing: 0.2em;
				text-transform: uppercase;
				border-radius: 0;
				color: var(--ink);
				background: var(--blood);
				-moz-transition: all 0.3s ease-in-out;
				-webkit-transition: all 0.3s ease-in-out;
				transition: all 0.3s ease-in-out;
			}

			.field button:hover {
				background: var(--ember);
				box-shadow: 0 0 1em rgba(194, 20, 58, 0.45);
			}

		/* The QR ships its own ground at #0b0b0e — the same value as --pitch — so
		   the mount only has to extend it outwards into a quiet zone. Anything
		   lighter here rings the code like a frame. No blend mode: multiply would
		   crush the light modules against a ground this dark. */
		.content-qrcode {
			padding: 10px;
			background: var(--pitch);
		}

			.content-qrcode img {
				display: block;
			}

/* Tablet — seven wards stop fitting one row well before the phone breakpoint,
   so drop to a 4 + 3 grid early; the max-width keeps it from spreading thin */

	@media screen and (max-width: 900px) {

		#header nav ul {
			max-width: 30em;
			margin-left: auto;
			margin-right: auto;
		}

		#header nav li {
			flex: 0 0 25%;
			margin-left: 0;
			margin-right: 0;
		}

	}

/* Mobile */

	@media screen and (max-width: 736px) {

		#header {
			top: -1em;
			width: 96%;
		}

		/* These were cut back to stop the wordmark running off the right edge,
		   but that overflow was a measuring error — headless Chrome floors the
		   viewport at 500px, so the "390px" shots were 500px pages cropped, not
		   scaled. Measured properly the block was using 46% of the header. */
		#header .title_content h1 {
			font-size: clamp(6rem, 31vw, 8.5rem) !important;
		}

		#header .title_content span {
			font-size: clamp(1.5rem, 8vw, 2rem);
		}

		/* three per row on phones — seven then reads as 3 + 3 + 1. The narrower
		   cap keeps them clustered instead of drifting apart at the wide end of
		   this breakpoint, where a third of 700px would be all gutter. */
		#header nav ul {
			max-width: 24em;
		}

		#header nav li {
			flex: 0 0 33.333%;
			height: 6.8em;
		}

		/* 50px circles sat in 93-117px cells — the row was never short of width.
		   What it was short of is height, so the margins below give some back. */
		#header nav a {
			font-size: 1.85em;
		}

		#header nav a .title {
			font-size: 0.68rem !important;
			letter-spacing: 0.08em;
		}

		#header nav {
			margin: 2.2em 0 0 0;
		}

		#header .typed {
			letter-spacing: 0.04em;
			margin: 1.3em 0 0.3em 0;
		}

		#footer {
			padding: 2em 1em 1.1em 1em;
		}

	}

/* Short screens — three taller rows do not fit under 640px of height, and the
   header would run into the footer rather than scroll, since body is hidden */

	@media screen and (max-width: 736px) and (max-height: 640px) {

		#header .title_content h1 {
			font-size: clamp(4.5rem, 24vw, 8.5rem) !important;
		}

		#header .title_content span {
			font-size: clamp(1.2rem, 6.2vw, 2rem);
		}

		/* the roomier gap above is the first thing to give back here — under
		   640px of height the rows already only just clear the footer */
		#header nav {
			margin: 1.5em 0 0 0;
		}

		#header nav li {
			height: 5.6em;
		}

		#header nav a {
			font-size: 1.45em;
		}

		#header nav a .title {
			font-size: 0.6rem !important;
		}

	}

/* Reduced motion */

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

		.glitch:before,
		.glitch:after,
		#header .title_content h1 .noise,
		#header nav a:after,
		#header nav a .title:before,
		#header nav a .title:after {
			display: none;
		}

		#header nav a,
		#header nav a:hover,
		#header nav a:focus-visible,
		#header nav a:active,
		#header .title_content h1,
		#header .typed #typed-text:after {
			-webkit-animation: none !important;
			animation: none !important;
		}

		#header .typed .valbox {
			transition: none !important;
		}

	}
