/*
 * NG Armory, the wish list page.
 *
 * Design rules, from docs/registry-design.md section 5 and the brand file:
 *  1. Body text never goes below 18px. This is the single highest impact
 *     accessibility choice on the page and it costs nothing.
 *  2. Buttons are at least 48px tall and full width on mobile.
 *  3. Five palette colours only. bg #3c3c3c, card #b0aaaa, fg #eeeeee,
 *     primary #2d4ef4, accent #f97a35. White is the paper, not a sixth colour.
 *  4. Crillee is a display face and carries the page title and the group
 *     headings. Product names are set in the body face on purpose, because a
 *     grandparent has to read a product name accurately and an italic display
 *     face is the wrong tool for that job.
 */

@font-face {
	font-family: "NerfGunsDotNet";
	src: url("fonts/nerfgunsdotnet.woff2") format("woff2"),
	     url("fonts/nerfgunsdotnet.otf") format("opentype");
	font-weight: normal;
	font-style: normal;
	font-display: swap;
}

:root {
	--ng-ink: #3c3c3c;
	--ng-rule: #b0aaaa;
	--ng-light: #eeeeee;
	--ng-primary: #2d4ef4;
	--ng-accent: #f97a35;
}

/* The page owns its own width. It does not inherit the magazine grid. */
.ng-armory {
	max-width: 720px;
	margin: 0 auto;
	padding: 28px 18px 64px;
	color: var(--ng-ink);
	font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
	font-size: 18px;
	line-height: 1.6;
	-webkit-font-smoothing: antialiased;
}

/*
 * ⚠️ The !important flags here are load bearing, not laziness.
 *
 * The Extra theme zeroes margins with rules like `p:last-of-type`, and several
 * of the paragraphs on this page ARE the last of their type inside their
 * parent. Measured on the live page before this block existed: the gap between
 * the double-up line and the first group heading computed to 0px, and so did
 * the gap between a group note and its first card. Everything ran together.
 * Remove these and the page collapses back to that.
 */
.ng-armory p {
	font-size: 18px;
	line-height: 1.6;
	color: var(--ng-ink);
	margin: 0 0 16px !important;
}

.ng-armory a {
	color: var(--ng-primary);
}

/* ---------------------------------------------------------------- heading */

.ng-head {
	border-bottom: 3px solid var(--ng-rule);
	padding-bottom: 20px;
	margin-bottom: 24px;
}

.ng-armory .ng-title {
	font-family: "NerfGunsDotNet", Inter, Impact, sans-serif;
	font-size: 42px;
	line-height: 1.1;
	color: var(--ng-ink);
	margin: 0 0 14px;
	letter-spacing: 0.01em;
}

.ng-armory .ng-lede {
	font-size: 20px;
	line-height: 1.55;
	margin-bottom: 10px;
}

.ng-armory .ng-intro {
	font-size: 18px;
	font-style: italic;
	color: var(--ng-ink);
	margin-bottom: 0;
}

.ng-archived {
	background: var(--ng-light);
	border-left: 6px solid var(--ng-accent);
	padding: 16px 18px;
	margin-bottom: 24px;
	font-size: 18px;
}

/* ------------------------------------------------------------- disclosure */
/*
 * Clear and conspicuous, above the first button, in normal body text. It is
 * NOT small, NOT grey and NOT in a footer. Do not restyle it downward.
 */

.ng-disclosure {
	background: var(--ng-light);
	border: 2px solid var(--ng-rule);
	border-radius: 6px;
	padding: 18px 20px 4px;
	margin: 0 0 20px;
}

.ng-disclosure p {
	font-size: 18px;
	margin-bottom: 14px;
}

.ng-armory .ng-doubleup {
	font-weight: 600;
	border-left: 6px solid var(--ng-primary);
	padding: 4px 0 4px 14px;
	margin-bottom: 36px !important;
}

/* ----------------------------------------------------------------- groups */

.ng-group {
	margin: 0 0 44px;
}

.ng-armory .ng-group-heading {
	font-family: "NerfGunsDotNet", Inter, Impact, sans-serif;
	font-size: 30px;
	line-height: 1.2;
	color: var(--ng-ink);
	margin: 0 0 14px !important;
	padding-bottom: 8px;
	border-bottom: 3px solid var(--ng-accent);
}

.ng-armory .ng-group-note {
	font-size: 18px;
	font-weight: 600;
	margin: 0 0 24px !important;
}

/* ------------------------------------------------------------------ cards */

.ng-cards {
	display: block;
}

.ng-card {
	border: 2px solid var(--ng-rule);
	border-radius: 8px;
	padding: 20px 20px 22px;
	margin: 0 0 18px;
	background: #ffffff;
}

.ng-armory .ng-card-name {
	font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
	font-size: 23px;
	line-height: 1.3;
	font-weight: 700;
	color: var(--ng-ink);
	margin: 0 0 10px !important;
}

.ng-armory .ng-card-why {
	margin-bottom: 18px !important;
}

.ng-card-must {
	font-weight: 700;
	color: var(--ng-ink);
	background: var(--ng-light);
	border-left: 6px solid var(--ng-accent);
	padding: 8px 12px;
	margin-bottom: 16px;
}

.ng-card-claimed {
	font-weight: 600;
	margin-bottom: 16px;
}

.ng-card.ng-claimed {
	opacity: 0.62;
}

/* ---------------------------------------------------------------- buttons */
/*
 * 48px minimum height, full width on mobile. A 68 year old on a tablet has to
 * hit this without thinking about it.
 */

.ng-armory a.ng-btn {
	display: block;
	width: 100%;
	box-sizing: border-box;
	min-height: 56px;
	line-height: 1.2;
	padding: 17px 22px;
	background: var(--ng-primary);
	color: var(--ng-light);
	font-size: 20px;
	font-weight: 700;
	text-align: center;
	text-decoration: none;
	border: 0;
	border-radius: 6px;
	transition: background 0.15s ease;
}

.ng-armory a.ng-btn:hover,
.ng-armory a.ng-btn:focus {
	background: var(--ng-ink);
	color: var(--ng-light);
	text-decoration: none;
}

.ng-armory a.ng-btn:focus {
	outline: 3px solid var(--ng-accent);
	outline-offset: 2px;
}

/* ------------------------------------------------------------ what is this */

.ng-what {
	border-top: 3px solid var(--ng-rule);
	padding-top: 24px;
	margin-top: 8px;
}

.ng-armory .ng-what-heading {
	font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
	font-size: 22px;
	font-weight: 700;
	color: var(--ng-ink);
	margin: 0 0 12px;
}

.ng-empty {
	font-size: 19px;
	font-weight: 600;
}

/* The print block never shows on screen. armory-print.css reveals it. */
.ng-print-only {
	display: none;
}

/* ----------------------------------------------------------------- mobile */

@media (max-width: 640px) {
	.ng-armory {
		padding: 20px 14px 48px;
	}

	.ng-armory .ng-title {
		font-size: 32px;
	}

	.ng-armory .ng-lede {
		font-size: 19px;
	}

	.ng-armory .ng-group-heading {
		font-size: 25px;
	}

	.ng-armory .ng-card-name {
		font-size: 21px;
	}

	.ng-card {
		padding: 16px 16px 18px;
	}
}

/* --------------------------------------------------------------- pass it on */
/*
 * The share row. It is for a VISITOR forwarding the list to another relative,
 * not for the owner, who has copy buttons on their own editor screen.
 *
 * Positioned after the items on purpose. A share prompt above the buy buttons
 * competes with the thing the page exists to do.
 */

.ng-share-row {
	border-top: 3px solid var(--ng-rule);
	padding-top: 24px;
	margin: 8px 0 32px;
}

.ng-armory .ng-share-heading {
	font-family: "NerfGunsDotNet", Inter, Impact, sans-serif;
	font-size: 26px;
	line-height: 1.2;
	color: var(--ng-ink);
	margin: 0 0 10px !important;
}

.ng-share-tools {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin-top: 4px;
}

/*
 * Specificity note, same trap as the add-buttons in armory-guest.css: the child
 * theme's brand.css carries `#page-container button { background: ... }` at
 * (1,0,1), which beats a plain class selector. Anything here that styles a
 * <button> needs the prefix or it silently renders in the theme's colours.
 */
#page-container .ng-armory .ng-copy-btn,
.ng-armory .ng-copy-btn {
	display: inline-block;
	box-sizing: border-box;
	min-height: 48px;
	padding: 13px 20px;
	border: 2px solid var(--ng-primary);
	border-radius: 6px;
	background: #ffffff;
	color: var(--ng-primary);
	font-family: inherit;
	font-size: 17px;
	font-weight: 700;
	line-height: 1.3;
	text-align: center;
	text-decoration: none;
	text-transform: none;
	letter-spacing: 0;
	cursor: pointer;
	-webkit-appearance: none;
	appearance: none;
}

#page-container .ng-armory .ng-copy-btn:hover,
#page-container .ng-armory .ng-copy-btn:focus,
.ng-armory .ng-copy-btn:hover,
.ng-armory .ng-copy-btn:focus {
	background: var(--ng-primary);
	color: var(--ng-light);
	text-decoration: none;
}

.ng-armory .ng-copy-btn:focus-visible {
	outline: 3px solid var(--ng-accent);
	outline-offset: 2px;
}

/* Monarch, if it renders here at all, should not shout on this page. */
.ng-share-row .et_social_networks {
	margin: 0 0 14px !important;
}

@media (max-width: 640px) {
	.ng-share-tools {
		display: block;
	}

	#page-container .ng-armory .ng-copy-btn,
	.ng-armory .ng-copy-btn {
		display: block;
		width: 100%;
		margin-bottom: 10px;
	}
}

/* The text-message target only means anything on a phone. On a desktop an
 * sms: link either does nothing or opens something unexpected, which is worse
 * than not offering it. */
@media (min-width: 641px) {
	.ng-armory .ng-copy-btn-sms {
		display: none;
	}
}

/* ------------------------------------------------- priority, plain, flags */
/*
 * Priority tags, shown to the BUYER. Three values only, and the strings are a
 * shared contract with the Chrome extension, so do not invent a fourth here.
 */

.ng-armory .ng-prio {
	display: inline-block;
	margin: 0 0 10px !important;
	padding: 3px 12px;
	border-radius: 999px;
	font-size: 14px !important;
	font-weight: 700;
	letter-spacing: 0.02em;
	text-transform: uppercase;
}

.ng-prio-must-have {
	background: var(--ng-accent);
	color: #3c3c3c;
}

.ng-prio-nice-to-have {
	background: var(--ng-light);
	color: var(--ng-ink);
	border: 2px solid var(--ng-rule);
}

.ng-prio-dream-gift {
	background: var(--ng-primary);
	color: var(--ng-light);
}

/*
 * The plain English layer is HIDDEN until the toggle is pressed.
 *
 * Both versions ship in the HTML because this page is cached and cannot know
 * who is looking. Hiding one with CSS is what makes a per-visitor preference
 * possible on a page that is byte identical for everybody.
 */
.ng-armory .ng-plain {
	display: none;
}

.ng-armory.ng-plain-on .ng-plain {
	display: block;
	font-size: 17px !important;
	font-style: italic;
	margin: 0 0 12px !important;
	color: var(--ng-ink);
}

.ng-plain-toggle {
	margin-top: 14px;
}

.ng-armory .ng-plain-btn {
	min-height: 44px;
	padding: 10px 16px;
	border: 2px solid var(--ng-primary);
	border-radius: 6px;
	background: #ffffff;
	color: var(--ng-primary);
	font-family: inherit;
	font-size: 16px;
	font-weight: 700;
	text-transform: none;
	letter-spacing: 0;
	cursor: pointer;
}

#page-container .ng-armory .ng-plain-btn {
	background: #ffffff;
	color: var(--ng-primary);
}

.ng-armory.ng-plain-on .ng-plain-btn,
#page-container .ng-armory.ng-plain-on .ng-plain-btn {
	background: var(--ng-primary);
	color: var(--ng-light);
}

/*
 * Flags. Deliberately plain boxes rather than alarm colours: everything here is
 * true and useful, and a page of red warnings reads as broken rather than
 * helpful. Only the safety one gets the accent bar.
 */
.ng-armory .ng-flag {
	font-size: 17px !important;
	margin: 0 0 12px !important;
	padding: 10px 14px;
	background: var(--ng-light);
	border-left: 5px solid var(--ng-rule);
}

.ng-armory .ng-flag-safety,
.ng-armory .ng-flag-clash {
	border-left-color: var(--ng-accent);
	font-weight: 600;
}

@media print {
	.ng-plain-toggle {
		display: none !important;
	}

	/* On paper there is no toggle, so the plain English always prints. It is
	 * the version a reader with the page in their hand and nobody to ask will
	 * get the most out of. */
	.ng-armory .ng-plain {
		display: block !important;
		font-style: italic;
	}
}

/* ------------------------------------------------------- cover and claims */

.ng-cover {
	margin: 0 0 26px;
}

.ng-cover img {
	display: block;
	width: 100%;
	height: auto;
	border-radius: 8px;
}

.ng-armory .ng-claim {
	display: block;
	width: 100%;
	box-sizing: border-box;
	min-height: 44px;
	margin: 12px 0 0;
	padding: 11px 16px;
	border: 2px solid var(--ng-rule);
	border-radius: 6px;
	background: #ffffff;
	color: var(--ng-ink);
	font-family: inherit;
	font-size: 16px;
	font-weight: 600;
	text-transform: none;
	letter-spacing: 0;
	cursor: pointer;
}

#page-container .ng-armory .ng-claim {
	background: #ffffff;
	color: var(--ng-ink);
}

.ng-armory .ng-claim:hover,
.ng-armory .ng-claim:focus {
	border-color: var(--ng-primary);
	color: var(--ng-primary);
}

.ng-armory .ng-claim-on,
#page-container .ng-armory .ng-claim-on {
	background: var(--ng-light);
	color: var(--ng-ink);
	border-color: var(--ng-accent);
}

.ng-armory .ng-claim:disabled {
	opacity: 0.55;
	cursor: default;
}

/* The claim button is screen UI. On paper it would be an instruction nobody
 * can follow, and the cover is ink somebody else pays for. */
@media print {
	.ng-armory .ng-claim,
	.ng-cover {
		display: none !important;
	}
}

/* An unverified item that has not cleared review. It occupies the same space a
 * button would, so the card does not look broken or half-loaded, and it says
 * plainly why there is nothing to press. */
.ng-armory .ng-pending {
	display: block;
	box-sizing: border-box;
	min-height: 56px;
	padding: 15px 20px;
	margin: 0 !important;
	background: var(--ng-light);
	border: 2px dashed var(--ng-rule);
	border-radius: 6px;
	font-size: 17px !important;
	font-weight: 600;
	text-align: center;
}

/**
 * TODO 80 v2, the FTC disclosure badge for a 13-17 owner's list (Age Gate
 * Recomendations.docx section 2). Deliberately loud and directly above the
 * buy button it belongs to, not a small grey aside — "aggressively obvious"
 * was the brief, and this is the same visual weight as .ng-card-must
 * ("Please do not skip this one") for exactly that reason.
 */
.ng-armory .ng-ftc-badge {
	display: block;
	box-sizing: border-box;
	padding: 10px 14px;
	margin: 0 0 8px !important;
	background: #fff4e5;
	border: 2px solid #f97a35;
	border-radius: 6px;
	font-size: 15px !important;
	font-weight: 700;
	text-align: center;
	color: #7a3d10;
}

/*
 * 🔴 .ng-card-shot IS GONE ON PURPOSE. It styled a hotlinked retailer product
 * photo on the public list page, removed 2026-08-16 by Wayne's ruling. The rules
 * are deleted with the markup rather than left behind, because a stylesheet that
 * still dresses a banned element is an invitation to put the element back. The
 * reasoning lives in templates/single-wishlist.php, where the markup used to be.
 */

/* ------------------------------------------------------- the trending board */
/*
 * The board reuses .ng-card, .ng-btn, .ng-disclosure and .ng-flag exactly as the
 * list page renders them, so a change to a card is a change to both surfaces and
 * the two cannot drift apart. Only what is unique to this page lives here.
 */

/*
 * ⚠️ .ng-plain-always, NOT .ng-plain, and the reason is a trap rather than a
 * preference. On a list page .ng-plain is display:none until the reader presses
 * "Explain this in plain English", which flips a class on the wrapper. There is
 * no toggle on this page, so reusing that class would have rendered the sentence
 * into the markup and then hidden it from everybody, silently and forever.
 */
.ng-armory .ng-plain-always {
	font-size: 17px !important;
	font-style: italic;
	margin: 0 0 12px !important;
	color: var(--ng-ink);
}

.ng-trending-rank {
	font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.06em;
	color: var(--ng-accent);
	margin: 0 0 4px !important;
}

.ng-trending-count {
	font-weight: 700;
	color: var(--ng-ink);
	margin: 0 0 12px !important;
}

.ng-trending-basis {
	font-size: 16px;
	color: #555555;
	margin: 0 0 22px !important;
}

/*
 * The empty state is styled as CONTENT, not as an error. It is the honest
 * answer to a real question, and a grey warning box would read as something
 * being broken rather than as the page working correctly on a young feature.
 */
.ng-empty-state {
	border: 2px solid var(--ng-rule);
	border-radius: 8px;
	padding: 22px 22px 24px;
	margin: 0 0 26px;
	background: #ffffff;
}

.ng-empty-links {
	margin: 0;
	padding-left: 22px;
}

.ng-empty-links li {
	margin-bottom: 8px;
}

/* ==========================================================================
   THE LABEL GUARD. Read this before changing any button colour above.
   ==========================================================================

   🔴 EVERY BUTTON ON A WISH LIST RENDERED WITH AN INVISIBLE LABEL. Found on the
   live site by Wayne on 2026-08-16, on his own list, minutes after approving it.
   Measured before fixing: a blue label on a blue background, contrast ratio
   1.00, on all four buy buttons, the copy button and the plain English toggle,
   and 1.84 on the claim buttons.

   ⚠️ IT WAS NOT THE CLIPPED ITEMS. The first theory was that the unverified
   branch emitted different markup from the catalog branch. It does not: both
   emit exactly `<a class="ng-btn">`. Reading the computed colour on
   /wishlist/demo/ as a control settled it in one run: the demo list, approved
   back in Phase 1, was equally broken and had been all along. Ten buttons at
   ratio 1.00 on the page everybody had been using to prove nothing regressed.

   🔑 THE ACTUAL CAUSE, from CDP's matched-rules dump rather than from reading
   our own stylesheet: the Extra theme ships `color:#2d4ef4 !important` and
   `background-color:#2d4ef4 !important` inside very large selector lists that
   happen to match our controls. EVERY ng-armory button rule was non-important,
   and an !important declaration beats any non-important one no matter what its
   specificity is. So the theme won everywhere.

   🔴 SO THE GUARD NEEDS BOTH HALVES, AND THAT IS THE WHOLE FIX. Phase 2 raised
   specificity but stayed non-important, which loses to any !important. My own
   first attempt used !important but dropped the `#page-container` prefix, which
   loses on specificity: the theme's winning rule is

       #page-container button { background-color: #2d4ef4 !important }   (1,0,1)

   and `.ng-armory .ng-copy-btn !important` is only (0,2,0). Two !important
   declarations are settled by specificity, and 020 loses to 101. Each half
   alone fixed nothing. Together, (1,2,0) important beats (1,0,1) important.

   The unprefixed selector is kept beside the prefixed one so the guard still
   works if this feature is ever rendered outside the Extra theme's
   #page-container wrapper.

   ⚠️ AND EVERY CHECK MISSED IT, which is the reusable part. Every verification
   in this tranche COUNTED buttons: "10 buttons", "3/3 tagged", "byte identical".
   A button with an invisible label counts as a button, tags as a button and
   serves identical bytes. Counting is not inspecting, and colour in particular
   is only knowable after the cascade resolves.

   ⚠️ ONE MORE TRAP, paid for twice in one hour. Appending a <style> and reading
   getComputedStyle in the SAME synchronous block returns the value from before
   the recalc. A candidate fix that actually worked was measured as failing, and
   nearly abandoned, because of that alone. Let a frame pass before believing a
   contrast reading.

   SO THESE DECLARATIONS ARE !important ON PURPOSE. It is normally a smell, and
   here it is the only thing in CSS that beats the theme's !important. Scoped to
   `.ng-armory` so nothing outside this feature is affected, and kept in ONE
   block so both the list page and the trending board inherit the same guard
   rather than being patched separately.

   Anything added later that renders a control inside `.ng-armory` belongs in
   this block too, or it will be blue on blue and nobody will notice.
   ========================================================================== */

/* Solid buttons: the buy button on a list card and on the trending board. */
#page-container .ng-armory a.ng-btn,
.ng-armory a.ng-btn {
	background: var(--ng-primary) !important;
	color: var(--ng-light) !important;
}

#page-container .ng-armory a.ng-btn:hover,
#page-container .ng-armory a.ng-btn:focus,
.ng-armory a.ng-btn:hover,
.ng-armory a.ng-btn:focus {
	background: var(--ng-ink) !important;
	color: var(--ng-light) !important;
}

/* Outline buttons: share, the plain English toggle, and mark-as-bought. */
#page-container .ng-armory .ng-copy-btn,
#page-container .ng-armory .ng-plain-btn,
.ng-armory .ng-copy-btn,
.ng-armory .ng-plain-btn {
	background: #ffffff !important;
	color: var(--ng-primary) !important;
}

#page-container .ng-armory .ng-claim,
.ng-armory .ng-claim {
	background: #ffffff !important;
	color: var(--ng-ink) !important;
}

#page-container .ng-armory .ng-copy-btn:hover,
#page-container .ng-armory .ng-copy-btn:focus,
#page-container .ng-armory .ng-plain-btn:hover,
#page-container .ng-armory .ng-plain-btn:focus,
.ng-armory .ng-copy-btn:hover,
.ng-armory .ng-copy-btn:focus,
.ng-armory .ng-plain-btn:hover,
.ng-armory .ng-plain-btn:focus {
	background: var(--ng-primary) !important;
	color: var(--ng-light) !important;
}

/* The two "on" states, which must also survive the theme. */
#page-container .ng-armory.ng-plain-on .ng-plain-btn,
.ng-armory.ng-plain-on .ng-plain-btn {
	background: var(--ng-primary) !important;
	color: var(--ng-light) !important;
}

#page-container .ng-armory .ng-claim-on,
#page-container .ng-armory .ng-claim:hover,
#page-container .ng-armory .ng-claim:focus,
.ng-armory .ng-claim-on,
.ng-armory .ng-claim:hover,
.ng-armory .ng-claim:focus {
	background: var(--ng-light) !important;
	color: var(--ng-ink) !important;
}
