/**
 * M2 Unified Login — "Simpler" skin (design 6.2, the LAGOON hero)
 *
 * Clean-room rebuild of design 6.0, regenerated from DESIGN.md — change that
 * document and regenerate rather than patching selectors here. The stage is
 * the landing's first hero: a full-bleed WebGL aurora ([data-m2ul-aurora],
 * faded in over per-side static washes the moment its first frame paints via
 * html.m2ul-aurora-live; the washes stand in for good when it never does)
 * with the form floating at its center the way the hero's content column
 * does. Rising star-dust, an ink-pool veil for legibility, the gate-status
 * pill and the fact cards furnish the room; the aurora answers the
 * mechanics (typing charges it, jams wash it crimson, the unlock floods it
 * sea-glass).
 *
 * Theming is driven by attributes on .m2ul-simpler:
 *   data-side  = os | game                     which world is armed
 *   data-view  = login | lost | rp | verify    which seam view is visible
 *   data-phase = idle | error | align | retract | open
 * The sheet is self-contained; every mechanics hook (classes, ids,
 * data-m2ul-*) matches the markup byte-for-byte.
 */

/* =========================================================================
   Root, palette & side accents
   ========================================================================= */

.m2ul-simpler {
	/* Tell the engine this room IS dark: without it Safari treats the page
	   as light and paints its autofill ink black over the dark slabs */
	color-scheme: dark;
	--sim-bg: #070E10;
	--sim-ink: #E9F6F2;
	--sim-ink-soft: #DFF4EE;
	--sim-title: #F2FAF7;
	--sim-sub: rgba(202, 222, 217, 0.62);
	--sim-label: rgba(178, 212, 205, 0.92);
	--sim-faint: #7A948E; /* 6.0:1 on --sim-bg — the 12px helper text must clear AA */
	--sim-warn: #d9b36c;
	--sim-line: rgba(146, 192, 186, 0.14);
	--sim-line-soft: rgba(146, 192, 186, 0.1);
	/* Resting fields carry their own boundary a step above the shared
	   hairline — quiet, but findable without hunting for the label */
	--sim-field-line: rgba(146, 192, 186, 0.38);
	--sim-field-line-hover: rgba(146, 192, 186, 0.55);
	--sim-field-grad: linear-gradient(180deg, rgba(15, 29, 28, 0.75), rgba(8, 16, 16, 0.75));
	--sim-field-grad-focus: linear-gradient(180deg, rgba(19, 42, 40, 0.9), rgba(10, 19, 19, 0.9));
	--sim-autofill: #0C1414;
	--sim-ok: #8FC6BB;
	--sim-bad: #e08585;
	--sim-ac: #5CD6CC;
	--sim-ac-strong: #D2F7F1;
	--sim-ac-dim: rgba(92, 214, 204, 0.68);
	--sim-ring: rgba(92, 214, 204, 0.13);
	--sim-glow: rgba(92, 214, 204, 0.5);
	--sim-key-ink: #071C18;
	--sim-key-grad: linear-gradient(180deg, #CFF5EE 0%, #9EE2D6 52%, #7FCDBF 100%);
	--sim-key-grad-open: linear-gradient(180deg, #DFFFF8 0%, #AEEDE0 52%, #83D9C9 100%);
	--sim-key-border: rgba(178, 240, 229, 0.42);
	--sim-key-shadow: 0 14px 34px rgba(61, 206, 197, 0.14), 0 2px 8px rgba(0, 0, 0, 0.66);
	--sim-key-shadow-hover: 0 18px 40px rgba(61, 206, 197, 0.18), 0 3px 10px rgba(0, 0, 0, 0.68);
	--sim-font: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
	--sim-mono: 'IBM Plex Mono', monospace;
	--sim-serif: 'Source Serif 4', Georgia, serif;
	/* Vertical rhythm of the form column, as one retunable scale — the
	   compaction tiers further down wind these in so "or go the usual way"
	   can open inside the same screen instead of pushing past the fold. */
	--sim-gap-title: clamp(28px, 7vh, 78px);
	--sim-gap-tabs: 38px;
	--sim-gap-form: 34px;
	--sim-gap-field: 20px;
	--sim-gap-key: 26px;
	--sim-gap-remember: 18px;
	--sim-gap-classic: 30px;
	--sim-gap-foot: 28px;
	width: 100%;
	background: var(--sim-bg);
	font-family: var(--sim-font);
	color: var(--sim-ink);
}

.m2ul-simpler[data-side="game"] {
	--sim-ac: #C7A87A;
	--sim-ac-strong: #EAD4AD;
	--sim-ac-dim: rgba(199, 168, 122, 0.68);
	--sim-ring: rgba(199, 168, 122, 0.14);
	--sim-glow: rgba(199, 168, 122, 0.5);
	--sim-label: rgba(216, 199, 172, 0.88);
	--sim-field-grad: linear-gradient(180deg, rgba(21, 32, 31, 0.75), rgba(10, 16, 16, 0.75));
	--sim-field-grad-focus: linear-gradient(180deg, rgba(28, 44, 42, 0.9), rgba(13, 20, 20, 0.9));
	--sim-autofill: #0D1414;
	--sim-key-ink: #101A1A;
	--sim-key-grad: linear-gradient(180deg, #F4E3C4 0%, #DDBB86 52%, #C39C60 100%);
	--sim-key-border: rgba(240, 214, 165, 0.42);
	--sim-key-shadow: 0 14px 34px rgba(205, 156, 88, 0.1), 0 2px 8px rgba(0, 0, 0, 0.66);
	--sim-key-shadow-hover: 0 18px 40px rgba(205, 156, 88, 0.14), 0 3px 10px rgba(0, 0, 0, 0.68);
}

.m2ul-simpler,
.m2ul-simpler * {
	box-sizing: border-box;
}

.m2ul-simpler a {
	color: var(--sim-ac);
	text-decoration: none;
	transition: color 0.2s ease;
}

.m2ul-simpler a:hover {
	color: var(--sim-ac-strong);
}

.m2ul-simpler input {
	outline: none;
}

.m2ul-simpler button {
	font-family: var(--sim-font);
}

.m2ul-simpler :focus-visible {
	outline: 2px solid var(--sim-ac);
	outline-offset: 2px;
}

.m2ul-simpler a:focus-visible {
	border-radius: 4px;
}

/* The accent border + side-tinted ring carry field focus; the generic
   outline would double up inside the passwrap */
.m2ul-sim-input:focus-visible {
	outline: none;
}

.m2ul-simpler ::selection {
	background: var(--sim-ac-dim);
	color: #070E10;
}

/* While the key turns, the whole stage reads busy */
.m2ul-simpler[data-phase="align"],
.m2ul-simpler[data-phase="retract"],
.m2ul-simpler[data-phase="open"] {
	cursor: progress;
}

/* =========================================================================
   Entrance — the column settles in like an instrument warming up. The rise
   rides on children (never the shaking form element itself) so a jam's
   transform animation can't restart it.
   ========================================================================= */

@keyframes m2ulSimRise {
	from { opacity: 0; transform: translateY(10px); }
	to { opacity: 1; transform: none; }
}

.m2ul-sim-brand,
.m2ul-sim-title,
.m2ul-sim-sub,
.m2ul-sim-tabs,
.m2ul-sim-view > *,
.m2ul-sim-foot {
	animation: m2ulSimRise 0.5s cubic-bezier(0.2, 0.7, 0.3, 1) backwards;
}

.m2ul-sim-title { animation-delay: 0.07s; }
.m2ul-sim-sub { animation-delay: 0.1s; }
.m2ul-sim-tabs { animation-delay: 0.14s; }
.m2ul-sim-view > * { animation-delay: 0.16s; }
.m2ul-sim-view > .m2ul-sim-field { animation-delay: 0.2s; }
.m2ul-sim-view > .m2ul-sim-field ~ .m2ul-sim-field { animation-delay: 0.25s; }
.m2ul-sim-view > .m2ul-sim-key { animation-delay: 0.3s; }
.m2ul-sim-view > .m2ul-sim-key ~ * { animation-delay: 0.34s; }
.m2ul-sim-foot { animation-delay: 0.42s; }

/* =========================================================================
   Stage layout
   ========================================================================= */

/* The stage is the hero: full-bleed, the aurora underfoot, the form column
   centered over it the way .hero-content floats on the landing. */
.m2ul-sim-stage {
	position: relative;
	display: flex;
	justify-content: center;
	min-height: 100vh;
	min-height: 100dvh;
	width: 100%;
	overflow: hidden;
}

/* The premium edge vignette: the whole stage darkens toward its frame.
   The shader carries its own vignette and the ink-pool veil owns the
   column's legibility — this one just seats the room in its frame. */
.m2ul-sim-stage::after {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	z-index: 2;
	box-shadow: inset 0 0 200px 36px rgba(0, 0, 0, 0.66);
}

.m2ul-sim-col {
	position: relative;
	z-index: 3;
	width: 480px;
	max-width: 100%;
	flex-shrink: 0;
	min-height: 100vh;
	min-height: 100dvh;
	padding: 40px 28px 120px;
	display: flex;
	flex-direction: column;
	/* An invisible safety valve only: the fluid rhythm below is what makes
	   the column fit one viewport — a scrollbar thumb down the middle of
	   the stage breaks the room, so none ever paints. */
	overflow-y: auto;
	scrollbar-width: none;
}

.m2ul-sim-col::-webkit-scrollbar {
	display: none;
}

/* =========================================================================
   Brand & headline
   ========================================================================= */

.m2ul-sim-brand {
	display: flex;
	align-items: center;
	justify-content: center;
}

/* The serif M2 monogram is the brand's own mark and the column's one
   standing champagne moment — it holds brand gold on BOTH sides, never
   re-accenting with the world switch. */
.m2ul-sim-brand-mark {
	font-family: var(--sim-serif);
	font-weight: 600;
	font-size: 25px;
	line-height: 1;
	letter-spacing: 0.01em;
	color: #D9B36C;
}

.m2ul-sim-title {
	/* the rhythm scale's breathing gap under the brand */
	margin: var(--sim-gap-title) auto 0;
	font-family: var(--sim-serif);
	font-weight: 600;
	font-size: clamp(46px, 6vw, 70px);
	line-height: 1.02;
	letter-spacing: -0.03em;
	text-align: center;
	color: var(--sim-title);
	/* Stack the headline ("Welcome" / "back") the way the hero sets its
	   two lines — wide enough for any one word, never two */
	max-width: 3.6em;
	text-wrap: balance;
}

/* The hero's "Made easy." pour: the stacked headline's last word sets
   italic under the violet→champagne gradient. Engines without
   background-clip:text read the word in plain champagne; forced-colors
   reads it as the headline. */
.m2ul-sim-pour {
	font-style: italic;
	color: #d9b36c;
}

@supports ((-webkit-background-clip: text) or (background-clip: text)) {
	.m2ul-sim-pour {
		/* keeps the serif swash inside the text clip */
		padding-right: 0.06em;
		/* Routed through light: a straight violet→gold ramp dies in grey at
		   its midpoint, so the hue travels while luminance never drops —
		   the same shape the hero's own pour renders with */
		background: linear-gradient(100deg, #B79BFF 0%, #E7CFEA 26%, #F2DCB4 56%, #F5C83C 92%);
		-webkit-background-clip: text;
		background-clip: text;
		-webkit-text-fill-color: transparent;
		color: transparent;
	}
}

@media (forced-colors: active) {
	.m2ul-sim-pour {
		background: none;
		-webkit-text-fill-color: currentColor;
		color: currentColor;
	}
}

/* The signed-in card's lead line */
.m2ul-sim-sub {
	margin: 18px auto 0;
	font-size: 15.5px;
	line-height: 1.55;
	text-align: center;
	color: var(--sim-sub);
	max-width: 330px;
	text-wrap: pretty;
}

/* On the sub-panels the display headline yields the stage to the panel's
   own serif voice — still present, no longer competing with it */
.m2ul-simpler[data-view="lost"] .m2ul-sim-title,
.m2ul-simpler[data-view="rp"] .m2ul-sim-title,
.m2ul-simpler[data-view="verify"] .m2ul-sim-title,
.m2ul-simpler[data-view="held"] .m2ul-sim-title {
	font-size: clamp(32px, 3.6vw, 42px);
}

/* =========================================================================
   World switch — a hairline, not a chunky segmented control. The armed
   world's underline carries the accent; the rail is the shared baseline.
   ========================================================================= */

.m2ul-sim-tabs {
	position: relative;
	margin-top: var(--sim-gap-tabs);
	display: flex;
	justify-content: center;
	gap: 34px;
	border-bottom: 1px solid var(--sim-line-soft);
}

.m2ul-sim-tab {
	flex: 0 0 auto;
	padding: 6px 0 13px;
	margin-bottom: -1px;
	background: transparent;
	border: none;
	border-bottom: 1px solid transparent;
	border-radius: 0;
	font-family: var(--sim-mono);
	font-size: 11px;
	font-weight: 500;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: rgba(168, 204, 198, 0.82);
	cursor: pointer;
	transition: color 0.2s ease, border-color 0.2s ease;
}

/* The warm ink is dimmer than the OS teal-grey at equal alpha — match the
   rendered contrast, not the declared alpha */
.m2ul-simpler[data-side="game"] .m2ul-sim-tab {
	color: rgba(234, 212, 173, 0.85);
}

.m2ul-sim-tab:hover {
	color: var(--sim-ink-soft);
}

.m2ul-simpler[data-side="os"] .m2ul-sim-tab--os,
.m2ul-simpler[data-side="game"] .m2ul-sim-tab--game {
	color: var(--sim-title);
	border-bottom-color: var(--sim-ac);
}

.m2ul-sim-tab[disabled] {
	cursor: default;
}

/* Mid-verification the world is already chosen — the switch goes inert.
   Same on the dormancy hold: there is no journey to redirect. */
.m2ul-simpler[data-view="verify"] .m2ul-sim-tabs,
.m2ul-simpler[data-view="held"] .m2ul-sim-tabs {
	opacity: 0.45;
	pointer-events: none;
}

/* =========================================================================
   Views (login | lost | rp | verify | held)
   ========================================================================= */

.m2ul-sim-view {
	display: none;
}

.m2ul-simpler[data-view="login"] .m2ul-sim-view--login,
.m2ul-simpler[data-view="lost"] .m2ul-sim-view--lost,
.m2ul-simpler[data-view="rp"] .m2ul-sim-view--rp,
.m2ul-simpler[data-view="verify"] .m2ul-sim-view--verify,
.m2ul-simpler[data-view="held"] .m2ul-sim-view--held {
	display: flex;
}

.m2ul-sim-form {
	margin-top: var(--sim-gap-form);
	flex-direction: column;
}

.m2ul-sim-panel-title {
	margin: 0;
	font-family: var(--sim-serif);
	font-weight: 600;
	font-size: 30px;
	line-height: 1.05;
	letter-spacing: -0.02em;
	text-align: center;
	color: var(--sim-title);
}

.m2ul-sim-panel-hint {
	margin: 10px auto 0;
	font-size: 14.5px;
	line-height: 1.5;
	text-align: center;
	max-width: 360px;
	color: var(--sim-sub);
}

.m2ul-sim-sent {
	margin: 14px 0 0;
	font-size: 13px;
	text-align: center;
	color: var(--sim-sub);
}

.m2ul-sim-sent b {
	color: var(--sim-label);
	font-weight: 500;
}

/* =========================================================================
   Fields — machined 3px-radius slabs with an engraved mono label
   ========================================================================= */

.m2ul-sim-field {
	display: flex;
	flex-direction: column;
	gap: 9px;
	margin-top: var(--sim-gap-field);
}

.m2ul-sim-form > .m2ul-sim-field:first-of-type {
	margin-top: 0;
}

/* On the panels the first field seats under the hint, not flush to it */
.m2ul-sim-panel .m2ul-sim-field:first-of-type {
	margin-top: 22px;
}

.m2ul-sim-labelrow {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
}

.m2ul-sim-label {
	font-family: var(--sim-mono);
	font-size: 9.5px;
	font-weight: 400;
	letter-spacing: 0.28em;
	text-transform: uppercase;
	color: var(--sim-label);
	transition: color 0.6s ease;
}

/* A quiet seat in the label row — carries the .m2ul-simpler weight so the
   muted ink actually out-ranks the global link teal */
.m2ul-simpler .m2ul-sim-forgot {
	font-size: 12.5px;
	color: rgba(168, 204, 198, 0.62);
}

.m2ul-simpler .m2ul-sim-forgot:hover {
	color: var(--sim-ink-soft);
}

/* 16px base keeps iOS/iPadOS Safari from zoom-jumping the viewport on
   focus at ANY width; mouse-driven machines get the tighter 15px below */
.m2ul-sim-input {
	width: 100%;
	background: var(--sim-field-grad);
	border: 1px solid var(--sim-field-line);
	border-radius: 3px;
	padding: 14px 16px;
	font-family: var(--sim-font);
	font-size: 16px;
	color: var(--sim-ink-soft);
	/* mirrors color — WebKit paints text-fill over color, and Safari can
	   hold a stale black fill while typing over just-autofilled text */
	-webkit-text-fill-color: var(--sim-ink-soft);
	box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
	transition: border-color 0.22s ease, background 0.22s ease, box-shadow 0.22s ease;
}

@media (hover: hover) and (pointer: fine) {
	.m2ul-sim-input {
		font-size: 15px;
		padding: 15px 16px;
	}
}

.m2ul-sim-input::placeholder {
	color: rgba(223, 244, 238, 0.5);
}

.m2ul-sim-input:hover {
	border-color: var(--sim-field-line-hover);
}

.m2ul-sim-input:focus {
	border-color: var(--sim-ac-dim);
	background: var(--sim-field-grad-focus);
	box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 0 0 3px var(--sim-ring);
}

/* Dark-theme autofill: kill the yellow/white flash the UA paints. The
   ink must be PINNED: Safari's autofill sheet forces black text at
   UA-important weight, so the box-shadow trick alone leaves black ink
   standing on the dark slab (measured Safari pass 2026-08-03) */
.m2ul-sim-input:-webkit-autofill,
.m2ul-sim-input:-webkit-autofill:hover,
.m2ul-sim-input:-webkit-autofill:focus {
	-webkit-text-fill-color: var(--sim-ink-soft) !important;
	-webkit-box-shadow: 0 0 0 1000px var(--sim-autofill) inset;
	caret-color: var(--sim-ink-soft) !important;
	transition: background-color 999999s ease-out;
}

/* Field-level jam: the offending input carries the red until the next
   keystroke. A hot border + standing ring — the hairline alone measured
   under the 3:1 component floor on the veiled aurora. */
.m2ul-sim-input.is-err,
.m2ul-sim-passwrap.is-err {
	border-color: #E5484D;
	box-shadow: 0 0 0 3px rgba(229, 72, 77, 0.22);
}

.m2ul-sim-input.is-err:focus,
.m2ul-sim-passwrap.is-err:focus-within {
	box-shadow: 0 0 0 3px rgba(229, 72, 77, 0.3);
}

/* The password slab: the wrapper owns ALL the chrome, the input inside
   goes bare, and the show-toggle sits as the input's sibling */
.m2ul-sim-passwrap {
	display: flex;
	align-items: center;
	background: var(--sim-field-grad);
	border: 1px solid var(--sim-field-line);
	border-radius: 3px;
	padding: 0 8px 0 16px;
	box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
	transition: border-color 0.22s ease, background 0.22s ease, box-shadow 0.22s ease;
}

.m2ul-sim-passwrap:hover {
	border-color: var(--sim-field-line-hover);
}

.m2ul-sim-passwrap:focus-within {
	border-color: var(--sim-ac-dim);
	background: var(--sim-field-grad-focus);
	box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 0 0 3px var(--sim-ring);
}

.m2ul-sim-input--bare {
	background: transparent;
	border: none;
	border-radius: 0;
	padding: 14px 0;
	flex: 1;
	min-width: 0;
	box-shadow: none;
	letter-spacing: 0.08em;
}

@media (hover: hover) and (pointer: fine) {
	.m2ul-sim-input--bare {
		padding: 15px 0;
	}
}

.m2ul-sim-input--bare:hover {
	border-color: transparent;
}

.m2ul-sim-input--bare:focus {
	border: none;
	background: transparent;
	box-shadow: none;
}

/* Inside the passwrap the wrapper owns the autofill paint */
.m2ul-sim-input--bare:-webkit-autofill,
.m2ul-sim-input--bare:-webkit-autofill:hover,
.m2ul-sim-input--bare:-webkit-autofill:focus {
	-webkit-box-shadow: 0 0 0 1000px var(--sim-autofill) inset;
	border-radius: 3px;
}

.m2ul-sim-showtoggle {
	background: none;
	border: none;
	cursor: pointer;
	font-family: var(--sim-mono);
	font-size: 9.5px;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: rgba(168, 204, 198, 0.62);
	padding: 8px 10px;
	transition: color 0.15s ease, transform 0.1s ease;
}

.m2ul-sim-showtoggle:hover {
	color: var(--sim-ink-soft);
}

.m2ul-sim-showtoggle:active {
	transform: scale(0.92);
}

.m2ul-sim-showtoggle[aria-pressed="true"] {
	color: var(--sim-ac);
}

/* Caps-lock telltale under the passphrase field (script-toggled) */
.m2ul-sim-caps {
	display: none;
	margin-top: 6px;
	font-family: var(--sim-mono);
	font-size: 11px;
	letter-spacing: 0.08em;
	color: var(--sim-warn);
}

.m2ul-sim-caps.is-on {
	display: block;
}

/* =========================================================================
   The key button — pale glass, dark engraving, real weight
   ========================================================================= */

.m2ul-sim-key {
	position: relative;
	overflow: hidden;
	margin-top: var(--sim-gap-key);
	width: 100%;
	padding: 17px 20px;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 11px;
	background: var(--sim-key-grad);
	border: 1px solid var(--sim-key-border);
	/* the hero CTA's pill silhouette — the one shape change the key makes */
	border-radius: 999px;
	box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5), var(--sim-key-shadow);
	font-size: 15px;
	font-weight: 600;
	letter-spacing: 0.01em;
	color: var(--sim-key-ink);
	cursor: pointer;
	transition: transform 0.2s ease, box-shadow 0.2s ease, opacity 0.2s ease,
		border-color 0.2s ease, margin-top 0.34s cubic-bezier(0.2, 0.7, 0.3, 1);
}

/* Glass sheen across the top face */
.m2ul-sim-key::before {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(180deg, rgba(255, 255, 255, 0.22), rgba(255, 255, 255, 0) 46%);
	pointer-events: none;
}

/* the engraving rides above the sheen */
.m2ul-sim-key-icon,
.m2ul-sim-key-label {
	position: relative;
}

.m2ul-sim-key:hover {
	transform: translateY(-1px);
	box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55), var(--sim-key-shadow-hover);
}

.m2ul-sim-key:active {
	transform: translateY(0);
	box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 4px 12px rgba(0, 0, 0, 0.4);
}

.m2ul-sim-key-icon {
	flex-shrink: 0;
	transition: transform 0.7s cubic-bezier(0.6, 0, 0.2, 1);
}

/* The key teases its quarter-turn under the pointer… */
.m2ul-simpler[data-phase="idle"] .m2ul-sim-view--login .m2ul-sim-key:hover .m2ul-sim-key-icon {
	transform: rotate(18deg);
}

/* …and turns it for real through the ceremony */
.m2ul-simpler[data-phase="align"] .m2ul-sim-key-icon,
.m2ul-simpler[data-phase="retract"] .m2ul-sim-key-icon,
.m2ul-simpler[data-phase="open"] .m2ul-sim-key-icon {
	transform: rotate(90deg);
}

.m2ul-simpler[data-phase="align"] .m2ul-sim-view--login .m2ul-sim-key,
.m2ul-simpler[data-phase="retract"] .m2ul-sim-view--login .m2ul-sim-key,
.m2ul-simpler[data-phase="open"] .m2ul-sim-view--login .m2ul-sim-key {
	pointer-events: none;
}

.m2ul-simpler[data-phase="align"] .m2ul-sim-view--login .m2ul-sim-key,
.m2ul-simpler[data-phase="retract"] .m2ul-sim-view--login .m2ul-sim-key {
	opacity: 0.85;
}

.m2ul-simpler[data-phase="open"] .m2ul-sim-view--login .m2ul-sim-key {
	background: var(--sim-key-grad-open);
	border-color: rgba(174, 237, 224, 0.45);
}

.m2ul-sim-key--panel {
	margin-top: 24px;
}

.m2ul-sim-key--panel[disabled] {
	opacity: 0.6;
	pointer-events: none;
}

/* The signed-in card's key is an anchor — the engraved ink must out-rank
   the global .m2ul-simpler a teal */
.m2ul-sim-key--link {
	width: 100%;
	max-width: 320px;
	align-self: center;
	text-decoration: none;
}

.m2ul-simpler .m2ul-sim-key--link,
.m2ul-simpler .m2ul-sim-key--link:hover {
	color: var(--sim-key-ink);
}

.m2ul-sim-signedin-dest {
	margin-top: 12px;
	font-size: 13.5px;
	text-align: center;
	color: var(--sim-sub);
}

/* =========================================================================
   Error / status lines — the instrument's lamp language
   ========================================================================= */

.m2ul-sim-err,
.m2ul-sim-status {
	min-height: 18px;
	margin-top: 12px;
	font-size: 13px;
	line-height: 1.4;
	color: var(--sim-bad);
}

.m2ul-sim-err.is-ok,
.m2ul-sim-status.is-ok {
	color: var(--sim-ok);
}

/* A lit indicator dot precedes every reading */
.m2ul-sim-err:not(:empty)::before,
.m2ul-sim-status:not(:empty)::before {
	content: "";
	display: inline-block;
	width: 7px;
	height: 7px;
	border-radius: 50%;
	margin-right: 7px;
	vertical-align: 1px;
	background: currentColor;
	box-shadow: 0 0 6px currentColor;
}

/* …and each new reading settles in instead of teleporting */
@keyframes m2ulSimMsgReveal {
	from { opacity: 0; transform: translateY(-2px); }
	to { opacity: 1; transform: translateY(0); }
}

.m2ul-sim-err:not(:empty),
.m2ul-sim-status:not(:empty) {
	animation: m2ulSimMsgReveal 0.2s ease;
}

@keyframes m2ulSimShake {
	0%, 100% { transform: translateX(0); }
	20% { transform: translateX(-7px); }
	45% { transform: translateX(6px); }
	70% { transform: translateX(-3px); }
	88% { transform: translateX(2px); }
}

.m2ul-sim-form.is-shake {
	animation: m2ulSimShake 0.45s ease;
}

/* =========================================================================
   Remember row / cipher signal / rows / resend / back
   ========================================================================= */

.m2ul-sim-rememberrow {
	margin-top: var(--sim-gap-remember);
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	transition: margin-top 0.34s cubic-bezier(0.2, 0.7, 0.3, 1);
}

.m2ul-sim-remember {
	display: flex;
	align-items: center;
	gap: 10px;
	cursor: pointer;
	font-size: 13.5px;
	color: var(--sim-sub);
	transition: color 0.2s ease;
}

.m2ul-sim-remember:hover {
	color: var(--sim-ink-soft);
}

/* Hand-machined checkbox — stock browser chrome has no place on this panel */
.m2ul-sim-remember input {
	appearance: none;
	-webkit-appearance: none;
	width: 16px;
	height: 16px;
	margin: 0;
	flex-shrink: 0;
	border: 1px solid rgba(146, 192, 186, 0.28);
	border-radius: 3px;
	background: rgba(255, 255, 255, 0.03);
	cursor: pointer;
	transition: border-color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
}

.m2ul-sim-remember input:checked {
	border-color: transparent;
	background-color: var(--sim-ac);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23070E10' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round' d='M3.5 8.5l3 3 6-7'/%3E%3C/svg%3E");
	background-size: 12px 12px;
	background-position: center;
	background-repeat: no-repeat;
}

.m2ul-sim-remember input:focus-visible {
	outline: none;
	box-shadow: 0 0 0 3px var(--sim-ring);
	border-color: var(--sim-ac);
}

/* The breathing cipher lamp: quiet proof the line is live */
.m2ul-sim-signal {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	font-family: var(--sim-mono);
	font-size: 9.5px;
	letter-spacing: 0.22em;
	/* 9.5px tracked mono never renders its declared color — the alpha is
	   set for the stroke that actually reaches the screen */
	color: rgba(168, 204, 198, 0.82);
	white-space: nowrap;
}

.m2ul-simpler[data-side="game"] .m2ul-sim-signal {
	color: rgba(216, 199, 172, 0.85);
}

@keyframes m2ulSimBreathe {
	0%, 100% { opacity: 0.55; }
	50% { opacity: 0.9; }
}

/* The hero badge's live dot, ported: a ring pings out and dies behind the
   breathing core — the same 2s gesture the first hero opens with. */
@keyframes m2ulSimPing {
	0%, 100% { opacity: 0.75; transform: scale(1); }
	50% { opacity: 0; transform: scale(2.4); }
}

.m2ul-sim-signal-dot {
	position: relative;
	width: 5px;
	height: 5px;
	border-radius: 50%;
	background: var(--sim-ac);
	box-shadow: 0 0 8px 1px var(--sim-glow);
	animation: m2ulSimBreathe 3.6s ease-in-out infinite;
}

.m2ul-sim-signal-dot::before {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: 50%;
	background: var(--sim-ac);
	animation: m2ulSimPing 2s ease-in-out infinite;
}

.m2ul-sim-row {
	margin-top: 16px;
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: 12px;
}

.m2ul-sim-row .m2ul-sim-remember {
	margin-top: 0;
}

/* Where a stage offers no device-trust box, a plain note takes the seat on
   the left of this row. It wears .m2ul-sim-remember for the row's baseline
   and colour — but it is a sentence, not a control, so no pointer cursor. */
.m2ul-sim-verify-note {
	font-size: 13.5px;
	color: var(--sim-sub);
	cursor: default;
}

/* The dormancy hold's reviewer note — the stage's one multi-line field.
   Rides the machined slab; only the height behavior is its own. */
.m2ul-sim-note {
	min-height: 96px;
	resize: vertical;
	line-height: 1.5;
}

.m2ul-sim-resend {
	background: none;
	border: none;
	cursor: pointer;
	font-size: 13px;
	color: var(--sim-ac);
	padding: 4px 0;
	transition: color 0.2s ease;
}

.m2ul-sim-resend:hover {
	color: var(--sim-ac-strong);
}

.m2ul-sim-resend[disabled] {
	color: var(--sim-faint);
	cursor: default;
}

/* "Why am I being asked for this?" — closed by default; same quiet register
   as the back link so the code panel gains no visual weight. The body text
   explains that a code can be routine, not only a brand-new device. */
.m2ul-sim-verify-why {
	margin-top: 18px;
	font-size: 13px;
	line-height: 1.55;
	color: var(--sim-sub);
	align-self: center;
	max-width: 360px;
}

.m2ul-sim-verify-why summary {
	list-style: none;
	text-align: center;
	cursor: pointer;
	text-decoration: underline;
	text-underline-offset: 2px;
}

.m2ul-sim-verify-why summary::-webkit-details-marker { display: none; }

.m2ul-sim-verify-why summary:hover,
.m2ul-sim-verify-why[open] summary { color: var(--sim-ink-soft); }

.m2ul-sim-verify-why p {
	margin: 10px 0 0;
	text-align: left;
}

/* A quiet way back — the muted ink must out-rank the global link teal */
.m2ul-simpler .m2ul-sim-back {
	margin-top: 22px;
	font-size: 13px;
	color: var(--sim-sub);
	align-self: center;
}

.m2ul-simpler .m2ul-sim-back:hover {
	color: var(--sim-ink-soft);
}

/* =========================================================================
   "or go the usual way" — quiet destination chips under a hairline
   ========================================================================= */

.m2ul-sim-classic {
	margin-top: var(--sim-gap-classic);
	padding-top: 20px;
	border-top: 1px solid var(--sim-line-soft);
	transition: margin-top 0.34s cubic-bezier(0.2, 0.7, 0.3, 1);
}

.m2ul-sim-usual {
	list-style: none;
	cursor: pointer;
	text-align: center;
	font-family: var(--sim-serif);
	font-style: italic;
	font-size: 15.5px;
	/* thin italic serif strokes render well under their declared color —
	   the alpha is set for the stroke that reaches the screen */
	color: rgba(202, 222, 217, 0.72);
	transition: color 0.2s ease;
}

.m2ul-sim-usual::-webkit-details-marker {
	display: none;
}

.m2ul-sim-usual:hover {
	color: var(--sim-ink-soft);
}

.m2ul-sim-usual > span {
	border-bottom: 1px solid rgba(255, 255, 255, 0.12);
	padding-bottom: 2px;
}

/* The whole disclosure rides the column's centered axis, like the
   summary line above it — a left-clustered chip row reads as debris */
.m2ul-sim-dests {
	margin-top: 16px;
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	justify-content: center;
	gap: 6px;
}

/* The disclosure eases open instead of snapping */
.m2ul-sim-classic[open] .m2ul-sim-dests,
.m2ul-sim-classic[open] .m2ul-sim-dest-hint {
	animation: m2ulSimRise 0.3s cubic-bezier(0.2, 0.7, 0.3, 1) backwards;
}

.m2ul-sim-classic[open] .m2ul-sim-dest-hint {
	animation-delay: 0.08s;
}

.m2ul-sim-dest {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 8px 14px;
	background: transparent;
	border: 1px solid var(--sim-line);
	border-radius: 999px;
	cursor: pointer;
	transition: border-color 0.2s ease, background 0.2s ease, transform 0.12s ease;
}

.m2ul-sim-dest:hover {
	border-color: rgba(146, 192, 186, 0.3);
}

.m2ul-sim-dest:active {
	transform: translateY(1px);
}

.m2ul-sim-dest.is-on {
	border-color: var(--sim-ac-dim);
	background: var(--sim-ring);
}

/* The chip is the detent: the radio keeps the tab order, the keyboard
   arrows and every state it always drove, and hands its lamp to the
   chip around it. */
.m2ul-sim-dest input {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	border: 0;
	clip-path: inset(50%);
	overflow: hidden;
}

.m2ul-sim-dest:focus-within {
	border-color: var(--sim-ac);
	box-shadow: 0 0 0 3px var(--sim-ring);
}

/* Pointer picks shouldn't leave the ring lit behind them */
@supports selector(:has(*)) {
	.m2ul-sim-dest:focus-within:not(:has(input:focus-visible)) {
		box-shadow: none;
	}

	.m2ul-sim-dest:focus-within:not(:has(input:focus-visible)):not(.is-on) {
		border-color: var(--sim-line);
	}
}

.m2ul-sim-dest-text {
	display: flex;
	flex-direction: column;
	min-width: 0;
}

.m2ul-sim-dest-name {
	font-size: 12.5px;
	font-weight: 500;
	line-height: 1.25;
	color: rgba(202, 222, 217, 0.62);
	transition: color 0.2s ease;
}

.m2ul-sim-dest.is-on .m2ul-sim-dest-name {
	color: var(--sim-ink);
}

/* Descriptors read out beneath the strip — one line for the armed pick
   instead of three permanent ones. Clipped rather than display:none so
   each radio keeps its full accessible name. */
.m2ul-sim-dest-desc {
	position: absolute;
	width: 1px;
	height: 1px;
	clip-path: inset(50%);
	overflow: hidden;
}

.m2ul-sim-dest-hint {
	margin-top: 12px;
	font-size: 12px;
	color: var(--sim-faint);
	min-height: 15px;
	line-height: 1.4;
	text-align: center;
}

.m2ul-sim-dest-hint i {
	font-family: var(--sim-serif);
	font-style: italic;
	font-size: 13px;
	color: var(--sim-sub);
}

/* =========================================================================
   Verify — segmented code cells over the real input
   ========================================================================= */

.m2ul-sim-code {
	position: relative;
}

.m2ul-sim-code-input {
	font-family: var(--sim-mono);
	letter-spacing: 0.35em;
}

/* Once the cells take over, the input surrenders ALL its chrome — the six
   cells are the field (the armed cell's pulse carries focus) */
.m2ul-sim-code.is-jscode .m2ul-sim-code-input,
.m2ul-sim-code.is-jscode .m2ul-sim-code-input:hover,
.m2ul-sim-code.is-jscode .m2ul-sim-code-input:focus {
	color: transparent;
	/* WebKit paints text-fill OVER color — the base .m2ul-sim-input ink
	   pin would otherwise print the raw value across the cells */
	-webkit-text-fill-color: transparent;
	caret-color: transparent;
	text-shadow: none;
	border-color: transparent;
	background: transparent;
	box-shadow: none;
}

/* Safari's one-time-code fill trips the autofill ink pin (!important) —
   the veiled input must out-pin it or the pasted code prints over the cells */
.m2ul-sim-code.is-jscode .m2ul-sim-code-input:-webkit-autofill,
.m2ul-sim-code.is-jscode .m2ul-sim-code-input:-webkit-autofill:hover,
.m2ul-sim-code.is-jscode .m2ul-sim-code-input:-webkit-autofill:focus {
	-webkit-text-fill-color: transparent !important;
	caret-color: transparent !important;
	-webkit-box-shadow: none;
}

.m2ul-sim-code.is-jscode .m2ul-sim-code-input::placeholder {
	color: transparent;
}

.m2ul-sim-code-cells {
	position: absolute;
	inset: 0;
	display: grid;
	grid-template-columns: repeat(6, 1fr);
	gap: 8px;
	pointer-events: none;
}

.m2ul-sim-code-cell {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	/* six small slabs over the veiled aurora: a light glass fill and an
	   0.18-white edge clear the 3:1 component floor where the machined
	   field gradient sank into the ink pool */
	background: rgba(255, 255, 255, 0.06);
	border: 1px solid rgba(255, 255, 255, 0.18);
	border-radius: 3px;
	box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
	font-family: var(--sim-mono);
	font-size: 17px;
	color: var(--sim-ink-soft);
	transition: border-color 0.15s ease;
}

/* Each digit lands with a stamp */
@keyframes m2ulSimStamp {
	0% { transform: scale(1.14); }
	100% { transform: scale(1); }
}

.m2ul-sim-code-cell.is-filled {
	border-color: rgba(146, 192, 186, 0.34);
	background: var(--sim-field-grad-focus);
	animation: m2ulSimStamp 0.18s cubic-bezier(0.3, 1.6, 0.4, 1);
}

@keyframes m2ulSimArmed {
	0%, 100% { border-color: var(--sim-ac); }
	50% { border-color: var(--sim-ac-dim); }
}

.m2ul-sim-code-cell.is-armed {
	border-color: var(--sim-ac);
	box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 0 0 3px var(--sim-ring);
	animation: m2ulSimArmed 1.2s ease-in-out infinite;
}

/* the armed cell carries a caret bar — "type here" without a cursor */
.m2ul-sim-code-cell.is-armed::after {
	content: "";
	position: absolute;
	left: 50%;
	bottom: 7px;
	width: 38%;
	height: 2px;
	transform: translateX(-50%);
	border-radius: 1px;
	background: var(--sim-ac);
}

.m2ul-sim-code.is-bad .m2ul-sim-code-cell {
	border-color: var(--sim-bad);
}

/* success sweeps green cell-by-cell */
.m2ul-sim-code.is-ok .m2ul-sim-code-cell {
	border-color: var(--sim-ok);
	transition: border-color 0.2s ease;
	transition-delay: calc(var(--i, 0) * 45ms);
}

/* =========================================================================
   Footer
   ========================================================================= */

.m2ul-sim-foot {
	margin-top: auto;
	padding-top: var(--sim-gap-foot);
	display: flex;
	flex-direction: column;
	gap: 10px;
}

.m2ul-sim-terms {
	font-size: 12.5px;
	color: var(--sim-faint);
}

.m2ul-sim-terms a {
	color: rgba(200, 236, 229, 0.8);
	border-bottom: 1px solid rgba(200, 236, 229, 0.25);
}

.m2ul-sim-terms a:hover {
	color: var(--sim-ac-strong);
	border-bottom-color: var(--sim-ac-dim);
}

.m2ul-sim-recaptcha {
	font-family: var(--sim-mono);
	font-size: 9.5px;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--sim-faint);
}

.m2ul-sim-recaptcha a {
	color: var(--sim-faint);
	text-decoration: underline;
	text-decoration-color: rgba(146, 192, 186, 0.3);
	text-underline-offset: 2px;
}

.m2ul-sim-recaptcha a:hover {
	color: var(--sim-label);
}

/* Google's own badge is redundant with the printed notice */
.grecaptcha-badge {
	visibility: hidden;
}

/* =========================================================================
   The hero — the aurora floor: static washes, flow canvas, star-dust,
   the ink-pool veil, the gate-status pill and facts
   ========================================================================= */

.m2ul-sim-hero {
	position: absolute;
	inset: 0;
	z-index: 0;
	overflow: hidden;
	background: var(--sim-bg);
}

/* The landing hero's overhead glow puck, centered over the stage */
.m2ul-sim-hero::before {
	content: "";
	position: absolute;
	z-index: 2;
	pointer-events: none;
	left: 50%;
	top: 0;
	width: 520px;
	height: 520px;
	transform: translateX(-50%);
	background: radial-gradient(circle, rgba(87, 217, 209, 0.07) 0%, transparent 70%);
	filter: blur(60px);
}

.m2ul-simpler[data-side="game"] .m2ul-sim-hero::before {
	background: radial-gradient(circle, rgba(157, 123, 255, 0.07) 0%, transparent 70%);
}

.m2ul-sim-hero-bg {
	position: absolute;
	inset: 0;
	opacity: 0;
	overflow: hidden;
	transition: opacity 0.7s ease;
}

.m2ul-simpler[data-side="os"] .m2ul-sim-hero-bg--os,
.m2ul-simpler[data-side="game"] .m2ul-sim-hero-bg--game {
	opacity: 1;
}

/* The first hero's own static aurora — the landing's skeleton fallback,
   byte-for-byte, standing in until (or forever if) the shader's first
   frame lands. Teal-led while M2//OS is armed. */
.m2ul-sim-hero-bg--os {
	background:
		radial-gradient(120% 80% at 70% 18%, rgba(23, 77, 87, 0.46), transparent 60%),
		radial-gradient(90% 70% at 25% 78%, rgba(87, 217, 209, 0.14), transparent 65%),
		radial-gradient(70% 55% at 82% 82%, rgba(161, 128, 250, 0.09), transparent 70%),
		var(--sim-bg);
}

/* WORLD: the same composition re-led — violet takes the deep blob's seat
   and teal steps back to the corner accent, so the two families never
   average into slate. The stops are pinned HOT (R−G ≥ +15 at the pocket
   cores) because a polite violet dies into slate over the sea-black. */
.m2ul-sim-hero-bg--game {
	background:
		radial-gradient(120% 80% at 70% 18%, rgba(84, 58, 158, 0.46), transparent 60%),
		radial-gradient(90% 70% at 25% 78%, rgba(157, 123, 255, 0.2), transparent 65%),
		radial-gradient(70% 55% at 82% 82%, rgba(87, 217, 209, 0.08), transparent 70%),
		var(--sim-bg);
}

/* The static aurora breathes: two blobs on counter-phased drifts. The
   blanket reduced-motion rule stills them into the composition. */
@keyframes m2ulSimAuroraA {
	0%, 100% { transform: translate3d(-2.5%, 1.5%, 0) scale(1); }
	50% { transform: translate3d(2.5%, -2%, 0) scale(1.07); }
}

@keyframes m2ulSimAuroraB {
	0%, 100% { transform: translate3d(2%, -1.5%, 0) scale(1.05); }
	50% { transform: translate3d(-2%, 2%, 0) scale(1); }
}

.m2ul-sim-hero-bg::before,
.m2ul-sim-hero-bg::after {
	content: "";
	position: absolute;
	inset: -12%;
	pointer-events: none;
}

.m2ul-sim-hero-bg::before {
	animation: m2ulSimAuroraA 26s ease-in-out infinite;
}

.m2ul-sim-hero-bg::after {
	animation: m2ulSimAuroraB 34s ease-in-out infinite;
}

.m2ul-sim-hero-bg--os::before {
	background: radial-gradient(70% 55% at 30% 72%, rgba(87, 217, 209, 0.12), transparent 65%);
}

.m2ul-sim-hero-bg--os::after {
	background: radial-gradient(55% 45% at 72% 78%, rgba(161, 128, 250, 0.17), transparent 70%);
}

.m2ul-sim-hero-bg--game::before {
	background: radial-gradient(70% 55% at 30% 72%, rgba(157, 123, 255, 0.24), transparent 65%);
}

.m2ul-sim-hero-bg--game::after {
	background: radial-gradient(55% 45% at 72% 78%, rgba(87, 217, 209, 0.08), transparent 70%);
}

/* The flow canvas — hidden until its first painted frame lands, then it
   glows in over the static washes on its own signal. A dead controller
   (html.m2ul-aurora-dead, or no class at all) leaves the washes standing
   in permanently — the same dead-man the landing hero runs. */
.m2ul-sim-hero-canvas {
	position: absolute;
	inset: 0;
	z-index: 1;
	width: 100%;
	height: 100%;
	opacity: 0;
}

@keyframes m2ulSimCanvasIn {
	from { opacity: 0; }
	to { opacity: 1; }
}

html.m2ul-aurora-live .m2ul-sim-hero-canvas {
	animation: m2ulSimCanvasIn 1.4s cubic-bezier(0.33, 0, 0.3, 1) both;
}

/* Star-dust: two planes of rising motes (far plane small and slow, near
   plane larger and faster), each drifting exactly one background tile per
   loop so the wrap is seamless — the landing's ambient-cinema recipe. */
.m2ul-sim-hero-dust {
	position: absolute;
	inset: 0;
	z-index: 2;
	pointer-events: none;
	overflow: hidden;
}

@keyframes m2ulSimDustFar { to { transform: translateY(-380px); } }
@keyframes m2ulSimDustNear { to { transform: translateY(-463px); } }

.m2ul-sim-hero-dust::before,
.m2ul-sim-hero-dust::after {
	content: "";
	position: absolute;
	left: -20px;
	right: -20px;
	top: -460px;
	bottom: -460px;
	background-repeat: repeat;
}

.m2ul-sim-hero-dust::before {
	opacity: 0.4;
	background-image:
		radial-gradient(1px 1px at 11% 19%, rgba(247, 250, 249, 0.5), transparent 55%),
		radial-gradient(1px 1px at 74% 8%, rgba(247, 250, 249, 0.34), transparent 55%),
		radial-gradient(1.4px 1.4px at 38% 63%, rgba(212, 168, 83, 0.36), transparent 55%),
		radial-gradient(1px 1px at 91% 47%, rgba(247, 250, 249, 0.3), transparent 55%),
		radial-gradient(1.2px 1.2px at 55% 88%, rgba(61, 206, 197, 0.38), transparent 55%);
	background-size: 460px 380px;
	animation: m2ulSimDustFar 92s linear infinite;
}

.m2ul-sim-hero-dust::after {
	opacity: 0.3;
	background-image:
		radial-gradient(1.7px 1.7px at 23% 34%, rgba(247, 250, 249, 0.42), transparent 55%),
		radial-gradient(1.4px 1.4px at 67% 76%, rgba(232, 196, 122, 0.4), transparent 55%),
		radial-gradient(1.9px 1.9px at 86% 16%, rgba(247, 250, 249, 0.26), transparent 55%),
		radial-gradient(1.4px 1.4px at 8% 81%, rgba(61, 206, 197, 0.32), transparent 55%);
	/* prime-ish tile + phase offset so the two planes' motes never land on
	   a shared grid the eye can lock onto */
	background-size: 547px 463px;
	background-position: 137px 89px;
	animation: m2ulSimDustNear 118s linear infinite;
}

/* The ink pool: a quiet darkening under the centered column so engraved
   labels and 12px helper text keep their contrast over the brightest
   streaks. It reads as depth, not as a card — and it lifts with the
   unlock, the room brightening as the door opens. */
.m2ul-sim-hero-veil {
	position: absolute;
	inset: 0;
	z-index: 3;
	pointer-events: none;
	background: radial-gradient(46% 62% at 50% 46%, rgba(4, 10, 11, 0.68), rgba(4, 10, 11, 0.3) 60%, transparent 82%);
	transition: opacity 1.2s ease;
}

.m2ul-simpler[data-phase="open"] .m2ul-sim-hero-veil {
	opacity: 0;
}

/* The jam's crimson breath: the shader's wash is real but decays fast —
   this layer makes the refusal legible at a glance, snapping in with the
   jam and draining out slowly with it. */
.m2ul-sim-hero-veil::before {
	content: "";
	position: absolute;
	inset: 0;
	opacity: 0;
	background: radial-gradient(62% 52% at 50% 44%, rgba(220, 60, 60, 0.13), transparent 72%);
	transition: opacity 0.9s ease;
}

.m2ul-simpler[data-phase="error"] .m2ul-sim-hero-veil::before {
	opacity: 1;
	transition-duration: 0.12s;
}

/* The departure: with the door open the room lets you through. A beat after
   the flood lands (ACCESS GRANTED gets its moment first) the column lifts
   away and the stage's own vignette closes to sea-black — the last frame
   before navigation is the dark of the doorway, which is exactly the frame
   the /os boot opens on (it reads the handoff stamp and lets this same
   lagoon wash recede off its hull). Both animations ride the open phase and
   run THROUGH the network wait — the page keeps painting until the far side
   answers, so a slow response reads as a held dip, not a stall. */
@keyframes m2ulSimEgress {
	to { opacity: 0; transform: translateY(-12px) scale(1.015); }
}

@keyframes m2ulSimDepartDip {
	to { background-color: rgba(4, 9, 11, 0.97); }
}

.m2ul-simpler[data-phase="open"] .m2ul-sim-col {
	animation: m2ulSimEgress 0.55s cubic-bezier(0.55, 0.06, 0.68, 0.19) 0.4s forwards;
}

.m2ul-simpler[data-phase="open"] .m2ul-sim-stage::after {
	background-color: rgba(4, 9, 11, 0);
	animation: m2ulSimDepartDip 0.6s cubic-bezier(0.5, 0.1, 0.7, 0.5) 0.5s forwards;
}

/* Gate-status pill: the design's state narrator, a quiet instrument plate
   in the stage's top corner. The script keeps engraving through the
   [data-m2ul-status] hooks; the phases recolor it from the root. */
.m2ul-sim-gate {
	position: absolute;
	top: 26px;
	right: 30px;
	z-index: 4;
	display: inline-flex;
	align-items: center;
	gap: 11px;
	padding: 9px 17px;
	border-radius: 999px;
	border: 1px solid rgba(255, 255, 255, 0.1);
	background: rgba(240, 251, 248, 0.05);
	backdrop-filter: blur(13px);
	-webkit-backdrop-filter: blur(13px);
}

.m2ul-sim-gate-ping {
	position: relative;
	width: 7px;
	height: 7px;
	flex-shrink: 0;
	border-radius: 50%;
	background: var(--sim-ac);
	transition: background 0.6s ease;
}

.m2ul-sim-gate-ping::before {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: 50%;
	background: inherit;
	animation: m2ulSimPing 2s ease-in-out infinite;
}

.m2ul-simpler[data-phase="error"] .m2ul-sim-gate-ping {
	background: var(--sim-bad);
}

.m2ul-sim-gateword {
	display: none;
	align-items: baseline;
	gap: 10px;
	font-family: var(--sim-mono);
}

.m2ul-simpler[data-side="os"] .m2ul-sim-gateword--os,
.m2ul-simpler[data-side="game"] .m2ul-sim-gateword--game {
	display: inline-flex;
}

.m2ul-sim-gatename {
	font-size: 9.5px;
	letter-spacing: 0.3em;
	text-transform: uppercase;
	/* thin letter-spaced caps at 9.5px need the near-white read — a
	   side-accented alpha lands sub-AA on the glass pill */
	color: rgba(240, 251, 248, 0.62);
}

.m2ul-sim-gatestatus {
	font-size: 10.5px;
	letter-spacing: 0.24em;
	text-transform: uppercase;
	color: var(--sim-ac-strong);
	transition: color 0.3s ease;
}

.m2ul-simpler[data-phase="error"] .m2ul-sim-gatestatus {
	/* brighter than --sim-bad: the 10.5px engraving must clear AA mid-jam */
	color: #F2A9A9;
}

/* Engraved words settle in with a flicker instead of teleporting */
@keyframes m2ulSimFlip {
	0% { opacity: 0.15; filter: blur(2px); }
	55% { opacity: 0.7; filter: blur(0.4px); }
	100% { opacity: 1; filter: none; }
}

.m2ul-sim-gatestatus.is-flip {
	animation: m2ulSimFlip 0.32s ease;
}

/* Fact cards keep the sea-glass corner; they yield the floor entirely
   when the viewport can't seat them beside the centered column */
.m2ul-sim-facts {
	position: absolute;
	left: 30px;
	bottom: 26px;
	z-index: 4;
	width: min(320px, 23vw);
	display: flex;
	flex-direction: column;
	gap: 10px;
}

@media (max-width: 1239px) {
	.m2ul-sim-facts {
		display: none;
	}
}

.m2ul-sim-fact {
	/* The hero's glass vocabulary, cooled to sea-glass: the aurora reads
	   THROUGH the card instead of dying behind a smoked slab */
	background: rgba(240, 251, 248, 0.05);
	backdrop-filter: blur(13px);
	-webkit-backdrop-filter: blur(13px);
	border: 1px solid var(--sim-line-soft);
	border-radius: 3px;
	padding: 13px 16px;
	animation: m2ulSimRise 0.5s cubic-bezier(0.2, 0.7, 0.3, 1) 0.5s backwards;
	transition: border-color 0.25s ease;
}

.m2ul-sim-fact:hover {
	border-color: var(--sim-line);
}

.m2ul-sim-fact .m2ul-fact-label {
	display: block;
	font-family: var(--sim-mono);
	font-size: 10px;
	letter-spacing: 0.25em;
	text-transform: uppercase;
	color: var(--sim-ac);
	transition: color 0.7s ease;
}

/* The sea-glass card lifts the floor under this ink, so the ink floats
   brighter than the shared --sim-sub to hold AA on the lit panel */
.m2ul-sim-fact .m2ul-fact-text {
	margin: 7px 0 0;
	font-size: 13px;
	line-height: 1.5;
	color: rgba(226, 242, 238, 0.88);
}

.m2ul-sim-fact .m2ul-fact-text a {
	color: var(--sim-ac);
}

/* =========================================================================
   Wide stage — the room breathes a little wider on big monitors
   ========================================================================= */

@media (min-width: 1600px) {
	.m2ul-sim-col {
		width: 500px;
	}
}

/* =========================================================================
   Desktop — one viewport, always

   The column floats over the aurora, so growing past the fold doesn't
   just add a scrollbar: the whole page scrolls and the room slides out
   of frame. The column is capped at the viewport and its rhythm goes
   CONTINUOUSLY fluid — every gap carries a vh term and the headline
   yields to short rooms — so the whole console compresses to fit any
   window instead of jumping between fixed tiers (which left 850–1000px
   windows uncompressed and overflowing into a mid-stage scrollbar).
   Internal scroll survives only as the invisible safety valve.
   ========================================================================= */

@media (min-width: 980px) {
	.m2ul-sim-col {
		max-height: 100vh;
		max-height: 100dvh;
		padding: clamp(24px, 4vh, 40px) 28px clamp(22px, 3.4vh, 30px);
	}

	.m2ul-simpler {
		--sim-gap-title: clamp(14px, 6.5vh, 78px);
		--sim-gap-tabs: clamp(16px, 3.6vh, 38px);
		--sim-gap-form: clamp(16px, 3.2vh, 34px);
		--sim-gap-field: clamp(10px, 2vh, 20px);
		--sim-gap-key: clamp(14px, 2.6vh, 26px);
		--sim-gap-remember: clamp(10px, 1.9vh, 18px);
		--sim-gap-classic: clamp(14px, 2.9vh, 30px);
		--sim-gap-foot: clamp(12px, 2.6vh, 28px);
	}

	/* 6vw rules wide rooms, 8vh rules short ones — the display headline is
	   the one element with real slack to give */
	.m2ul-sim-title {
		font-size: clamp(40px, min(6vw, 8vh), 70px);
	}

	.m2ul-sim-title,
	.m2ul-sim-tabs,
	.m2ul-sim-form,
	.m2ul-sim-field,
	.m2ul-sim-classic {
		transition: margin-top 0.34s cubic-bezier(0.2, 0.7, 0.3, 1);
	}

	.m2ul-sim-foot {
		flex-direction: row;
		justify-content: space-between;
		align-items: baseline;
		gap: 24px;
		transition: padding-top 0.34s cubic-bezier(0.2, 0.7, 0.3, 1);
	}

	.m2ul-sim-dests {
		margin-top: 12px;
	}
}

/* Tablet strait — the centered column just narrows a touch */
@media (max-width: 1099px) and (min-width: 980px) {
	.m2ul-sim-col {
		width: 460px;
	}
}

/* The chips block costs ~140px, so an OPEN disclosure squeezes the whole
   scale a step tighter on anything but a truly tall room — this is what
   keeps "or go the usual way" inside the same screen. The script arms
   data-classic; the :has() twin covers the no-JS round-trip and the
   server-rendered open state (a remembered destination boots the stage
   with the panel already open), wrapped in :is() so engines without
   :has() drop that branch alone instead of invalidating the rule. */
@media (min-width: 980px) and (max-height: 999px) {
	.m2ul-simpler[data-classic="on"],
	.m2ul-simpler:is(:has(.m2ul-sim-classic[open])) {
		--sim-gap-title: clamp(12px, 3vh, 34px);
		--sim-gap-tabs: clamp(12px, 1.9vh, 20px);
		--sim-gap-form: clamp(12px, 1.9vh, 20px);
		--sim-gap-field: clamp(8px, 1.4vh, 14px);
		--sim-gap-key: clamp(10px, 1.7vh, 16px);
		--sim-gap-remember: clamp(8px, 1.2vh, 12px);
		--sim-gap-classic: clamp(10px, 1.6vh, 14px);
		--sim-gap-foot: clamp(10px, 1.4vh, 12px);
	}
}

/* Very short desktop viewports: the headline and key give up their last
   slack */
@media (min-width: 980px) and (max-height: 660px) {
	.m2ul-sim-title {
		font-size: 40px;
	}

	.m2ul-sim-key {
		padding: 14px 20px;
	}
}

/* =========================================================================
   Mobile port — the same room, held in one hand: the aurora stays
   full-bleed under the centered column; the desktop furniture yields.

   One viewport, always — like the desktop rule above, but against svh:
   the closed login view must fit the SMALL viewport (browser bars still
   up, the state every visit starts in), so every gap carries an svh term
   and compresses continuously on short phones instead of stepping through
   fixed tiers. Opening "or go the usual way" is the one sanctioned way
   past the fold — the column keeps its natural height and the page
   scrolls. The fixed declarations are the no-svh fallback; the @supports
   block is the real scale.
   ========================================================================= */

@media (max-width: 979px) {
	.m2ul-simpler {
		--sim-gap-title: 24px;
		--sim-gap-tabs: 24px;
		--sim-gap-form: 22px;
		--sim-gap-field: 14px;
		--sim-gap-key: 16px;
		--sim-gap-remember: 12px;
		--sim-gap-classic: 16px;
		--sim-gap-foot: 16px;
	}

	@supports (height: 1svh) {
		.m2ul-simpler {
			--sim-gap-title: clamp(10px, 2.6svh, 44px);
			--sim-gap-tabs: clamp(14px, 2.8svh, 34px);
			--sim-gap-form: clamp(12px, 2.8svh, 30px);
			--sim-gap-field: clamp(9px, 2svh, 20px);
			--sim-gap-key: clamp(10px, 2.2svh, 24px);
			--sim-gap-remember: clamp(8px, 1.8svh, 18px);
			--sim-gap-classic: clamp(10px, 2.2svh, 26px);
			--sim-gap-foot: clamp(10px, 2.2svh, 24px);
		}
	}

	/* M2 WORLD is not offered here. It has no mobile port yet, so this one
	   does not advertise it: the world switch goes entirely (one world left
	   means no switch — exactly what a single-world install renders), and the
	   gate pill and static wash drop their game half with it. The margin
	   leaves with the row, so the rhythm closes on its own.

	   The server has usually withheld the whole world already — get_worlds()
	   reads the User-Agent — and then none of this markup exists to hide. This
	   arm is for every narrow viewport the User-Agent does not name: tablets,
	   split-screen, a resized desktop window. Being CSS, it holds with
	   JavaScript off; the script's matching guard re-points the posted context
	   at M2//OS so the landing follows the offer.

	   Settings → Unified Login → Portal Doors → "M2 WORLD's mobile port is
	   ready" flips the attribute to "ready" and retires every rule here. */
	.m2ul-simpler[data-game-mobile="hold"] .m2ul-sim-tabs {
		display: none;
	}

	/* The gate word and its wash belong to the armed side, not to the offer,
	   and mid-verification the armed side is a record of a journey already
	   committed to — one that started in a window wide enough to offer M2
	   WORLD and was narrowed since. Taking the WORLD half away there would
	   leave the pill with a ping and no word at all (only the armed side's
	   gateword is ever displayed), so the state narrator would go silent
	   exactly where a member is waiting on a code. The switch above is gone
	   either way; nothing new can be entered from here. */
	.m2ul-simpler[data-game-mobile="hold"]:not([data-view="verify"]) .m2ul-sim-gateword--game,
	.m2ul-simpler[data-game-mobile="hold"]:not([data-view="verify"]) .m2ul-sim-hero-bg--game {
		display: none;
	}

	/* Softer frame on a small screen — the big vignette would swallow it */
	.m2ul-sim-stage::after {
		box-shadow: inset 0 0 110px 18px rgba(0, 0, 0, 0.6);
	}

	/* The drift blobs are a desktop gesture; the canvas (or the still
	   washes) carries the whole mood here */
	.m2ul-sim-hero-bg::before,
	.m2ul-sim-hero-bg::after {
		display: none;
	}

	/* The ink pool widens — the column owns most of the screen */
	.m2ul-sim-hero-veil {
		background: radial-gradient(90% 70% at 50% 46%, rgba(4, 10, 11, 0.62), rgba(4, 10, 11, 0.3) 64%, transparent 88%);
	}

	/* Fact cards yield; the gate pill compacts to ping + status (it is the
	   design's state narrator — JAMMED / AWAITING CODE need a home here
	   too) */
	.m2ul-sim-hero .m2ul-sim-facts {
		display: none;
	}

	.m2ul-sim-gate {
		top: 14px;
		right: 14px;
		padding: 7px 13px;
		gap: 9px;
	}

	.m2ul-sim-gatename {
		display: none;
	}

	/* the pill holds the top-right corner, so the brand takes the left —
	   an app-header read instead of a centered collision */
	.m2ul-sim-brand {
		justify-content: flex-start;
	}

	.m2ul-sim-col {
		width: 100%;
		/* Phones fill it edge to edge; the tablet range centers a column
		   instead of stretching fields across the whole slab */
		max-width: 560px;
		max-height: none;
		min-height: 100vh;
		min-height: 100dvh;
		overflow: visible;
		padding: 20px max(26px, env(safe-area-inset-right)) calc(20px + env(safe-area-inset-bottom)) max(26px, env(safe-area-inset-left));
	}

	@supports (height: 1svh) {
		.m2ul-sim-col {
			padding-top: clamp(10px, 2.4svh, 24px);
			padding-bottom: calc(clamp(10px, 2.4svh, 24px) + env(safe-area-inset-bottom));
		}
	}

	/* The display headline is the block with real slack: 13vw rules roomy
	   phones, the svh term folds it in on short ones */
	.m2ul-sim-title {
		font-size: clamp(38px, 13vw, 58px);
	}

	@supports (height: 1svh) {
		.m2ul-sim-title {
			font-size: clamp(32px, min(13vw, 6.5svh), 58px);
		}
	}

	/* An idle status line spends no height here — the viewport budget is
	   too tight to reserve a blank row; a jam re-opens it as it prints */
	.m2ul-sim-err:empty {
		min-height: 0;
		margin-top: 0;
	}

	.m2ul-sim-sub {
		font-size: 15px;
	}

	.m2ul-sim-tabs {
		gap: 26px;
	}

	.m2ul-sim-tab {
		padding: 12px 0 14px;
		font-size: 11.5px;
	}

	.m2ul-sim-key {
		padding: 18px 20px;
		font-size: 15.5px;
	}

	/* Every small control clears the 44px touch minimum */
	.m2ul-sim-showtoggle,
	.m2ul-sim-forgot,
	.m2ul-sim-resend,
	.m2ul-sim-back {
		min-height: 44px;
		display: inline-flex;
		align-items: center;
	}

	/* …but "Forgot?" must not bill its 44px to the label row's LAYOUT —
	   that row reads as one 10px engraving and the viewport budget is
	   spoken for. The negative margins hand the height back; the relative
	   seat keeps the overhanging halves of the hit area on top of the
	   neighboring fields so the full 44px still answers the thumb. */
	.m2ul-simpler .m2ul-sim-forgot {
		margin: -14px 0;
		position: relative;
		z-index: 1;
	}

	.m2ul-sim-back {
		margin-top: 10px;
	}

	.m2ul-sim-dest {
		min-height: 44px;
		padding: 11px 18px;
	}

	.m2ul-sim-dest-name {
		font-size: 13px;
	}

	.m2ul-sim-remember {
		min-height: 44px;
	}

	.m2ul-sim-remember input {
		width: 19px;
		height: 19px;
	}

	.m2ul-sim-code-cell {
		font-size: 19px;
	}

	/* Whatever slack a tall phone has left settles here, not at the fold:
	   the foot (terms + reCAPTCHA lines) anchors to the bottom of the room
	   and the auto margin absorbs the difference. On a short phone it
	   collapses to zero and the gap-foot padding is the separation. */
	.m2ul-sim-foot {
		gap: 8px;
		margin-top: auto;
	}
}

/* =========================================================================
   Reduced motion / raised contrast
   ========================================================================= */

@media (prefers-reduced-motion: reduce) {
	.m2ul-simpler *,
	.m2ul-simpler *::before,
	.m2ul-simpler *::after {
		transition-duration: 0.01ms !important;
		transition-delay: 0ms !important;
		animation-duration: 0.01ms !important;
		/* delays must die with the durations: a surviving entrance delay
		   plus the `backwards` fill would blank content for its length */
		animation-delay: 0ms !important;
		animation-iteration-count: 1 !important;
	}

	/* The departure must not survive as a snapped end-frame: a zeroed
	   duration plus its `forwards` fill would black the stage the instant
	   the open phase lands, while the reduced-motion script path is still
	   waiting on the network. No dip at all — the page just leaves. */
	.m2ul-simpler[data-phase="open"] .m2ul-sim-col,
	.m2ul-simpler[data-phase="open"] .m2ul-sim-stage::after {
		animation: none !important;
	}
}

@media (prefers-contrast: more) {
	.m2ul-simpler {
		--sim-line: rgba(255, 255, 255, 0.36);
		--sim-line-soft: rgba(255, 255, 255, 0.26);
		--sim-field-line: rgba(255, 255, 255, 0.42);
		--sim-field-line-hover: rgba(255, 255, 255, 0.6);
		--sim-faint: #8FA6A0;
		--sim-sub: #96ACA6;
		--sim-label: #A9BEB8;
	}
}

/* Konami-revealed staff link (passwordless mode): the label-row link ships
   [hidden]; the script un-hides it and stamps this class for one soft rise.
   The reduced-motion block above already flattens the animation.

   The display rule is load-bearing, not belt-and-braces: the phone tier's
   44px touch-minimum rule sets .m2ul-sim-forgot to inline-flex, and any
   author display beats the UA's [hidden] { display: none } — without this,
   "hidden" would render visible on every phone. */
.m2ul-simpler [data-m2ul-staff][hidden] {
	display: none;
}
@keyframes m2ulSimStaffReveal {
	from { opacity: 0; transform: translateY(4px); }
	to { opacity: 1; transform: none; }
}

.m2ul-simpler .m2ul-staff-revealed {
	animation: m2ulSimStaffReveal 0.4s ease both;
}
