/* Valor access gate — the unlock card + revealed downloads.
   Brand system: Sora (display), Public Sans (body), IBM Plex Mono (labels/code).
   Palette: navy #1C2C44, slate #233D6E, mint #7BC8AE, mint-deep #2E9B78, paper #F4F3EE,
   ember #C2563A. Light + dark aware. The button grammar matches the funnel lead form
   (slate pill that flips to a paper fill with a slate inset border + lift on hover) so the
   gate reads as a Valor control, not a default form button. */

.valor-gate {
	--vg-navy: #1C2C44;
	--vg-slate: #233D6E;
	--vg-mint: #7BC8AE;
	--vg-mint-deep: #2E9B78;
	--vg-paper: #F4F3EE;
	--vg-ember: #C2563A;
	--vg-ink: #232A33;
	--vg-gray: #5A6472;
	--vg-line: #E3E1D8;
	--vg-card: #FFFFFF;
	margin: 20px 0;
	font-family: "Public Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
	color: var(--vg-ink);
}

.valor-gate__lock {
	background: var(--vg-card);
	border: 1px solid var(--vg-line);
	border-radius: 16px;
	padding: 24px 26px;
	max-width: 560px;
	box-shadow: 0 1px 2px rgba(28, 44, 68, 0.06), 4px 4px 0 rgba(123, 200, 174, 0.14);
}

.valor-gate__title {
	margin: 0 0 6px;
	font-family: "Sora", "Public Sans", sans-serif;
	font-size: 20px;
	font-weight: 700;
	letter-spacing: -0.01em;
	color: var(--vg-navy);
}

.valor-gate__intro {
	margin: 0 0 16px;
	color: var(--vg-gray);
	font-size: 14.5px;
	line-height: 1.55;
}

.valor-gate__fields { border: 0; margin: 0; padding: 0; }

.valor-gate__row {
	display: flex;
	gap: 10px;
	margin-bottom: 10px;
	flex-wrap: wrap;
}

.valor-gate__row > input {
	flex: 1 1 200px;
	min-width: 0;
	padding: 11px 13px;
	border: 2px solid var(--vg-line);
	border-radius: 10px;
	font: inherit;
	font-size: 14.5px;
	color: var(--vg-navy);
	background: #fff;
	transition: border-color .15s cubic-bezier(.22, .61, .36, 1);
}

.valor-gate__row > input::placeholder { color: #A8ACB5; }

.valor-gate__row > input:focus {
	outline: none;
	border-color: var(--vg-slate);
}

/* #75: the post-attempt indicator — ember, cleared the moment the field is typed in. */
.valor-gate__row > input.is-missing,
.valor-gate__row > input.is-missing:focus {
	border-color: var(--vg-ember);
}

/* #74: the access code with its in-place copy control (the standard two-rectangles glyph). */
.valor-gate__codewrap {
	display: inline-flex;
	align-items: center;
	gap: 6px;
}

.valor-gate__copy {
	border: 0;
	background: none;
	padding: 3px;
	border-radius: 6px;
	color: var(--vg-gray);
	cursor: pointer;
	line-height: 0;
}

.valor-gate__copy:hover,
.valor-gate__copy:focus-visible {
	color: var(--vg-mint-deep);
	background: rgba(123, 200, 174, 0.14);
}

.valor-gate__copy.is-done { color: var(--vg-mint-deep); }

.valor-gate__copy svg {
	width: 15px;
	height: 15px;
	display: block;
}

/* Honeypot — the wrapper is visually gone but stays in the DOM for bots. */
.valor-gate__hp {
	position: absolute !important;
	left: -9999px !important;
	top: auto;
	width: 1px;
	height: 1px;
	overflow: hidden;
	opacity: 0;
}

.valor-gate__btn {
	display: inline-block;
	background: var(--vg-slate);
	color: #fff;
	text-decoration: none;
	padding: 14px 24px;
	border: 0;
	border-radius: 999px;
	font: inherit;
	font-size: 15.5px;
	font-weight: 700;
	cursor: pointer;
	transition: all .15s cubic-bezier(.22, .61, .36, 1);
}

.valor-gate__btn:hover:not(:disabled) {
	background: #EDEAE2;
	box-shadow: inset 0 0 0 2px var(--vg-slate);
	color: var(--vg-slate);
	transform: translateY(-2px);
}

.valor-gate__btn:active { transform: translateY(0); }
.valor-gate__btn:disabled { opacity: .55; cursor: not-allowed; }
.valor-gate__btn:focus-visible { outline: 3px solid var(--vg-mint); outline-offset: 3px; }

.valor-gate__submit {
	width: 100%;
	margin-top: 4px;
}

.valor-gate__msg,
.valor-gate__codemsg {
	margin: 10px 0 0;
	font-size: 13px;
	line-height: 1.45;
	min-height: 1em;
	color: var(--vg-gray);
}

.valor-gate__msg.is-error,
.valor-gate__codemsg.is-error { color: var(--vg-ember); font-weight: 600; }
.valor-gate__msg.is-ok,
.valor-gate__codemsg.is-ok { color: var(--vg-mint-deep); font-weight: 600; }

.valor-gate__alt {
	margin: 14px 0 0;
	font-size: 14px;
}

.valor-gate__alt a {
	color: var(--vg-mint-deep);
	font-weight: 600;
	text-decoration: none;
	border-bottom: 2px solid var(--vg-mint);
}

.valor-gate__alt a:hover { border-bottom-color: var(--vg-mint-deep); }

.valor-gate__code {
	margin-top: 18px;
	border-top: 1px solid var(--vg-line);
	padding-top: 14px;
}

.valor-gate__code > summary {
	cursor: pointer;
	color: var(--vg-gray);
	font-family: "IBM Plex Mono", ui-monospace, monospace;
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 0.02em;
	list-style: none;
}

.valor-gate__code > summary::-webkit-details-marker { display: none; }
.valor-gate__code[open] > summary { margin-bottom: 12px; }

.valor-gate__code input[name="code"] {
	font-family: "IBM Plex Mono", ui-monospace, monospace;
	text-transform: uppercase;
	letter-spacing: 1px;
}

/* Revealed downloads. */
.valor-gate__downloads[hidden] { display: none; }

.valor-gate__unlocked-note {
	margin: 0 0 8px;
	font-size: 13.5px;
	color: var(--vg-mint-deep);
	font-weight: 700;
}

.valor-gate__buttons {
	display: flex;
	gap: 12px;
	flex-wrap: wrap;
	margin: 0;
}

.valor-gate__code-shown {
	margin: 12px 0 0;
	font-size: 13px;
	color: var(--vg-gray);
}

.valor-gate__code-shown code {
	font-family: "IBM Plex Mono", ui-monospace, monospace;
	background: var(--vg-paper);
	padding: 2px 8px;
	border-radius: 6px;
	font-weight: 700;
	letter-spacing: 1px;
	color: var(--vg-navy);
}

@media (prefers-color-scheme: dark) {
	.valor-gate {
		--vg-line: #2C3340;
		--vg-card: #1B2028;
		--vg-ink: #E7EAEF;
		--vg-gray: #9AA3B0;
		--vg-paper: #232A33;
		/* On the dark card the reading navy would be invisible; remap the tokens that colour TEXT
		   to legible mint tints. --vg-slate is deliberately NOT remapped: it is the button fill, and
		   remapping it here turned every gate download button dark green in dark mode while the
		   comment above still claimed the button "keeps the slate fill". Slate is the brand's button
		   colour in both schemes. */
		--vg-navy: #CDE7DC;
	}
	.valor-gate__row > input { background: #232A33; color: #E7EAEF; border-color: #2C3340; }
	.valor-gate__row > input::placeholder { color: #7E8896; }
	.valor-gate__row > input:focus { border-color: var(--vg-mint); }
	.valor-gate__title { color: #CDE7DC; }
	.valor-gate__alt a { color: #9FE0C6; }
	.valor-gate__alt a:hover { border-bottom-color: #9FE0C6; }
	.valor-gate__code-shown code { background: #232A33; color: #CDE7DC; }
}

@media (prefers-reduced-motion: reduce) {
	.valor-gate__btn { transition: none; }
	.valor-gate__btn:hover:not(:disabled) { transform: none; }
}

/* ─────────────────────────── locked page body ───────────────────────────
   The scrambled body a visitor sees before unlocking. The blur is cosmetic only — the words
   underneath are already scrambled server-side, so nothing is being hidden by CSS alone. Kept
   light (3px) on purpose: the page must still read as a real document with real structure, which
   is what makes unlocking feel worth doing. */
.valor-locked { position: relative; }

.valor-locked__note {
	margin: 0 0 14px;
	font-weight: 700;
	color: #2E9B78;
}

/* Blur the TEXT elements rather than the container. A filter on a parent blurs its whole subtree,
   which is fine visually — but per-element is what lets the blur SCALE WITH TYPE SIZE, and that is
   the whole point here: blur illegibility is proportional to glyph size, so a 3px blur that makes
   16px body text unreadable leaves a 34px heading perfectly readable. Headings therefore get
   proportionally more, not an exemption. Nothing in the locked body is legible. */
.valor-locked__body {
	user-select: none;
	-webkit-user-select: none;
	pointer-events: none;
}

.valor-locked__body p,
.valor-locked__body li,
.valor-locked__body td,
.valor-locked__body th,
.valor-locked__body dd,
.valor-locked__body dt,
.valor-locked__body blockquote {
	filter: blur(3.4px);
	opacity: .55;
	transition: filter .5s cubic-bezier(.22,.61,.36,1), opacity .5s cubic-bezier(.22,.61,.36,1);
}

/* Roughly 0.2x the rendered font size, which is where a glyph stops resolving. */
.valor-locked__body h1 { filter: blur(9px);   opacity: .5; }
.valor-locked__body h2 { filter: blur(7px);   opacity: .5; }
.valor-locked__body h3 { filter: blur(5.5px); opacity: .5; }
.valor-locked__body h4 { filter: blur(4.5px); opacity: .52; }
.valor-locked__body h5,
.valor-locked__body h6 { filter: blur(4px);   opacity: .52; }
.valor-locked__body h1,
.valor-locked__body h2,
.valor-locked__body h3,
.valor-locked__body h4,
.valor-locked__body h5,
.valor-locked__body h6 {
	transition: filter .5s cubic-bezier(.22,.61,.36,1), opacity .5s cubic-bezier(.22,.61,.36,1);
}

/* The transmute: the swapped-in real text lands sharp, from slightly blurred, so the change reads
   as "this resolved" rather than as a flash of replaced content. */
.valor-locked__body.is-transmuting p,
.valor-locked__body.is-transmuting li,
.valor-locked__body.is-transmuting td,
.valor-locked__body.is-transmuting th,
.valor-locked__body.is-transmuting dd,
.valor-locked__body.is-transmuting dt,
.valor-locked__body.is-transmuting blockquote,
.valor-locked__body.is-transmuting h1,
.valor-locked__body.is-transmuting h2,
.valor-locked__body.is-transmuting h3,
.valor-locked__body.is-transmuting h4,
.valor-locked__body.is-transmuting h5,
.valor-locked__body.is-transmuting h6 {
	filter: blur(0);
	opacity: 1;
}
.valor-locked__body.is-transmuting,
.valor-locked.is-open .valor-locked__body {
	user-select: auto;
	-webkit-user-select: auto;
	pointer-events: auto;
}
.valor-locked.is-open .valor-locked__body * {
	filter: none;
	opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
	.valor-gate__btn { transition: none; }
	.valor-gate__btn:hover:not(:disabled) { transform: none; }
}

/* ─────────────────────────── locked page body ───────────────────────────
   The scrambled body a visitor sees before unlocking. The blur is cosmetic only — the words
   underneath are already scrambled server-side, so nothing is being hidden by CSS alone. Kept
   light (3px) on purpose: the page must still read as a real document with real structure, which
   is what makes unlocking feel worth doing. */
.valor-locked { position: relative; }

.valor-locked__note {
	margin: 0 0 14px;
	font-weight: 700;
	color: #2E9B78;
}

/* Blur the TEXT elements, not the container: a filter on a parent blurs its whole subtree, so a
   container blur would take the headings with it and there would be no way to exempt them. */
.valor-locked__body {
	user-select: none;
	-webkit-user-select: none;
	pointer-events: none;
}

.valor-locked__body p,
.valor-locked__body li,
.valor-locked__body td,
.valor-locked__body th,
.valor-locked__body dd,
.valor-locked__body dt,
.valor-locked__body blockquote {
	filter: blur(3.4px);
	opacity: .55;
	transition: filter .5s cubic-bezier(.22,.61,.36,1), opacity .5s cubic-bezier(.22,.61,.36,1);
}

/* Headings stay sharp and real. They are generic section names that give nothing away, and showing
   them is what makes the lock read as a deliberate preview rather than a broken page — scrambled
   text at heading size is simply large enough to be recognised as gibberish. */
.valor-locked__body h1,
.valor-locked__body h2,
.valor-locked__body h3,
.valor-locked__body h4,
.valor-locked__body h5,
.valor-locked__body h6 {
	opacity: .9;
}

/* The transmute: the swapped-in real text lands sharp, from slightly blurred, so the change reads
   as "this resolved" rather than as a flash of replaced content. */
.valor-locked__body.is-transmuting p,
.valor-locked__body.is-transmuting li,
.valor-locked__body.is-transmuting td,
.valor-locked__body.is-transmuting th,
.valor-locked__body.is-transmuting dd,
.valor-locked__body.is-transmuting dt,
.valor-locked__body.is-transmuting blockquote {
	filter: blur(0);
	opacity: 1;
}
.valor-locked__body.is-transmuting,
.valor-locked.is-open .valor-locked__body {
	user-select: auto;
	-webkit-user-select: auto;
	pointer-events: auto;
}
.valor-locked.is-open .valor-locked__body p,
.valor-locked.is-open .valor-locked__body li,
.valor-locked.is-open .valor-locked__body td,
.valor-locked.is-open .valor-locked__body th,
.valor-locked.is-open .valor-locked__body blockquote {
	filter: none;
	opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
	.valor-locked__body * { transition: none; }
}

/* ── Required marks, the copyable code, and error states (v1.115.0) ──────────────
   The required marks appear only AFTER a failed attempt. Marking a form up front
   decorates something nobody has failed yet; marking it after a mistake answers the
   question the person is actually asking, which is "what did I miss". */
.valor-gate__field { display: flex; flex-direction: column; gap: 4px; flex: 1 1 200px; }
.valor-gate__lab { font-size: 12.5px; color: #5a6675; font-weight: 600; }
.valor-gate__lab em { font-style: normal; color: #c2563a; opacity: 0; transition: opacity .18s ease; }
.valor-gate.is-tried .valor-gate__lab em { opacity: 1; }
.valor-gate__opt { font-weight: 400; color: #8b8577; }

.valor-gate.is-tried input:invalid { border-color: #c2563a; background: #fdf7f4; }
.valor-gate__msg.is-error { color: #8a2c1c; }
.valor-gate__msg.is-ok { color: #1f6b52; }

.valor-gate__codeline { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 10px 0 2px; }
.valor-gate__codelabel { font-size: 12.5px; color: #5a6675; font-weight: 600; }
.valor-gate__codevalue { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 15px;
	letter-spacing: .04em; background: #fff; border: 1px solid #d9d6cd; border-radius: 8px; padding: 6px 12px; }
.valor-gate__copy { border: 1.5px solid #233D6E; background: #fff; color: #233D6E; border-radius: 999px;
	padding: 6px 14px; font-weight: 700; font-size: 13px; cursor: pointer; }
.valor-gate__copy:hover { background: #f3f6fb; }
.valor-gate__copy.is-done { border-color: #43C6A0; color: #1f6b52; }
.valor-gate__codehint { font-size: 12.5px; color: #5a6675; margin: 0; }
