/* ============================================================
   NiCok Puzzles — public (puzzle page) styles.
   Design language shared with nfc-membership and tournament-manager
   and taken from the platform mockup (mockups/index.html):
   indigo->magenta palette, Sora/Inter type, soft purple shadows,
   rounded cards.

   The tokens below are a per-plugin copy of the same values the
   other two carry, not a new palette. Each plugin has to stand
   alone — puzzles runs without membership installed — so it cannot
   inherit anyone else's :root.

   Sora/Inter are named first in the font stacks so the exact
   typography is used wherever the fonts load, falling back to
   system fonts otherwise. Everything is scoped under .nfcp-public
   to avoid colliding with the active theme.
   ============================================================ */
:root {

	/* Ink & surfaces */
	--nfcp-ink: #1a1130;
	--nfcp-ink-soft: #4a4360;
	--nfcp-muted: #8a83a3;
	--nfcp-line: #ece8f5;
	--nfcp-bg: #f6f3fc;
	--nfcp-card-bg: #fff;

	/* Brand */
	--nfcp-indigo: #6d28d9;
	--nfcp-violet: #8b5cf6;
	--nfcp-magenta: #ec4899;
	--nfcp-teal: #14b8a6;
	--nfcp-gold: #fbbf24;
	--nfcp-red: #ef4444;

	/* Gradients */
	--nfcp-grad: linear-gradient(120deg, #6d28d9 0%, #a21caf 55%, #ec4899 100%);
	--nfcp-grad-soft: linear-gradient(120deg, #f5f0ff 0%, #fdeef8 100%);
	--nfcp-grad-teal: linear-gradient(120deg, #0d9488 0%, #2dd4bf 100%);

	/* Shape & depth */
	--nfcp-radius: 18px;
	--nfcp-radius-sm: 12px;
	--nfcp-shadow: 0 10px 30px -12px rgba(80, 30, 120, 0.28);
	--nfcp-shadow-lg: 0 24px 60px -20px rgba(80, 30, 120, 0.45);

	/* Type */
	--nfcp-display: "Sora", -apple-system, blinkmacsystemfont, "Segoe UI", sans-serif;
	--nfcp-body: "Inter", -apple-system, blinkmacsystemfont, "Segoe UI", sans-serif;
}

.nfcp-public {
	margin: 1.5rem 0;
	max-width: 960px;
	font-family: var(--nfcp-body);
	color: var(--nfcp-ink);
	line-height: 1.5;
}

/* Themes reset every heading with an element-only selector — Divi ships
   `h1..h6 { color:#333; line-height:1em; padding-bottom:10px }`. An element
   selector beats an *inherited* value outright, because inheritance carries no
   specificity at all, so a heading on one of the gradient surfaces below would
   render near-black on purple however emphatic the `color:#fff` on its
   container was. The stray 10px is the same bug wearing a different hat.

   `color: inherit` rather than a literal, so a heading always takes the colour
   of the surface it sits on. `.nfcp-public :is(h1..h6)` is 0-1-1 against Divi's
   0-0-1, so this needs no !important — this file has none. */
.nfcp-public :is(h1, h2, h3, h4, h5, h6) {
	color: inherit;
	line-height: 1.25;
	padding-bottom: 0;
}

/* ---------- Buttons ---------- */

.nfcp-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	padding: 11px 20px;
	border: none;
	border-radius: var(--nfcp-radius-sm);
	background: var(--nfcp-grad);
	color: #fff;
	font-family: var(--nfcp-body);
	font-size: 14px;
	font-weight: 600;

	/* Pin the leading, or an <a class="nfcp-btn"> inherits the theme's
	   line-height while a <button> gets the UA's `normal` — under Divi that
	   makes a link-button 7px taller than the button beside it. */
	line-height: 1.2;
	text-decoration: none;
	cursor: pointer;
	box-shadow: 0 10px 24px -12px rgba(109, 40, 217, 0.7);
	transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.nfcp-btn:hover,
.nfcp-btn:focus {

	/* Restated: Divi colours all links #2ea3f2 globally, and would otherwise
	   repaint an <a> carrying this class on hover. */
	color: #fff;
	text-decoration: none;
	transform: translateY(-2px);
	box-shadow: var(--nfcp-shadow-lg);
}

.nfcp-btn[disabled],
.nfcp-btn[disabled]:hover {
	opacity: 0.55;
	transform: none;
	box-shadow: none;
	cursor: default;
}

.nfcp-btn--ghost {
	background: #fff;
	color: var(--nfcp-indigo);
	border: 1.5px solid #e3d8fb;
	box-shadow: none;
}

.nfcp-btn--ghost:hover,
.nfcp-btn--ghost:focus {
	color: var(--nfcp-indigo);
	border-color: var(--nfcp-indigo);
	background: var(--nfcp-grad-soft);
}

/* ---------- Badges ---------- */

.nfcp-badge {
	display: inline-block;
	padding: 0.2rem 0.6rem;
	margin: 0 0.35rem 0.35rem 0;
	border-radius: 999px;
	background: #ede9fe;
	color: #5b21b6;
	font-size: 0.7rem;
	font-weight: 700;
	letter-spacing: 0.03em;
	text-transform: uppercase;
	white-space: nowrap;
}

.nfcp-badge--points {
	background: linear-gradient(120deg, #ede9fe, #fce7f3);
	color: #a21caf;
}

.nfcp-badge--open {
	background: #e0f2fe;
	color: #0369a1;
}

.nfcp-badge--done {
	background: #dcfce7;
	color: #15803d;
}

.nfcp-badge--timer {
	background: #fef3c7;
	color: #b45309;
	font-variant-numeric: tabular-nums;
}

/* ---------- Card ---------- */

.nfcp-card {
	background: var(--nfcp-card-bg);
	border: 1px solid var(--nfcp-line);
	border-radius: var(--nfcp-radius);
	padding: 1.1rem 1.25rem;
	box-shadow: var(--nfcp-shadow);
}

/* ---------- Player ---------- */

.nfcp-puzzle__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	margin-bottom: 1rem;
}

.nfcp-q {
	margin: 0 0 1rem;
	padding: 1.1rem 1.25rem;
	border: 1px solid var(--nfcp-line);
	border-radius: var(--nfcp-radius);
	background: var(--nfcp-card-bg);
	box-shadow: var(--nfcp-shadow);
	transition: border-color 0.18s ease, box-shadow 0.18s ease;
}

/* A <legend> is positioned in a gap it cuts in its fieldset's top border, which
   on a bordered, shadowed card leaves the question sitting astride the edge.
   `float` is what puts it back into normal flow — `display: block` alone does
   not, because the placement is a legend-specific behaviour rather than a
   display one. The float is cleared on .nfcp-q below.

   Kept as fieldset/legend rather than swapped for a <p>: the options are
   a radio group, and the legend is what a screen reader announces as
   their question. */
.nfcp-q__prompt {
	float: left;
	width: 100%;
	padding: 0;
	margin: 0 0 0.75rem;
	font-family: var(--nfcp-display);
	font-size: 1rem;
	font-weight: 700;
	line-height: 1.35;
	color: var(--nfcp-ink);
}

.nfcp-q::after {
	content: "";
	display: table;
	clear: both;
}

.nfcp-q__option {
	display: flex;
	align-items: flex-start;
	gap: 0.6rem;
	padding: 0.45rem 0.6rem;
	border-radius: var(--nfcp-radius-sm);
	color: var(--nfcp-ink-soft);
	line-height: 1.5;
	cursor: pointer;
	transition: background 0.15s ease;
}

.nfcp-q__option:hover {
	background: var(--nfcp-bg);
}

.nfcp-q__option input {

	/* Nudged down so the control sits on the first line of a wrapped label
	   rather than centring itself against the whole block. */
	margin-top: 0.3rem;
	flex: 0 0 auto;
	accent-color: var(--nfcp-indigo);
}

.nfcp-q__text {
	width: 100%;
	max-width: 22rem;
	padding: 0.6rem 0.8rem;
	border: 1.5px solid var(--nfcp-line);
	border-radius: var(--nfcp-radius-sm);
	font-family: var(--nfcp-body);
	font-size: 0.95rem;
	color: var(--nfcp-ink);
}

.nfcp-q__text:focus {
	outline: none;
	border-color: var(--nfcp-violet);
	box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.18);
}

.nfcp-q.is-correct {
	border-color: var(--nfcp-teal);
	box-shadow: inset 3px 0 0 var(--nfcp-teal), var(--nfcp-shadow);
}

.nfcp-q.is-wrong {
	border-color: var(--nfcp-red);
	box-shadow: inset 3px 0 0 var(--nfcp-red), var(--nfcp-shadow);
}

.nfcp-puzzle__actions {
	margin-top: 1.25rem;
}

.nfcp-puzzle__status {
	margin-top: 0.9rem;
	min-height: 1.5em;
	font-family: var(--nfcp-display);
	font-weight: 700;
	color: var(--nfcp-ink-soft);
}

.nfcp-puzzle.is-solved .nfcp-puzzle__status {
	color: #0f766e;
}

/* ---------- Gate ---------- */

.nfcp-gate {
	padding: 1.6rem 1.4rem;
	border-radius: var(--nfcp-radius);
	background: var(--nfcp-grad-soft);
	border: 1px solid var(--nfcp-line);
	text-align: center;
}

.nfcp-gate__message {
	margin: 0 0 1rem;
	color: var(--nfcp-ink-soft);
}

/* ---------- List ---------- */

/*
 * Themes style lists inside their content areas, and they do it with selectors
 * this plugin cannot outrank. Divi ships:
 *
 *   #left-area ul, .entry-content ul, .et-l--body ul, .et-l--footer ul,
 *   .et-l--header ul { list-style-type: disc; padding: 0 0 23px 1em; ... }
 *
 * Every puzzle rendered in a Divi content area therefore came out with bullets
 * and a 1em indent, whatever the rules below said — the word-search word list
 * worst of all, since its words are laid out in a row and each marker landed
 * against the end of the previous word.
 *
 * `!important` rather than more specificity, because `#left-area` is an ID:
 * (1,0,1) cannot be beaten by any number of classes, and the alternative is
 * writing another theme's ID into this plugin's stylesheet. Only the three
 * properties Divi actually sets are forced, so a list here can still choose its
 * own layout — but it cannot choose padding-left or padding-bottom, which no
 * list in this plugin wants anyway.
 *
 * Verified against the local Divi site under all five of the ancestors above.
 */
.nfcp-public ul,
.nfcp-public ol {
	list-style: none !important;
	padding-left: 0 !important;
	padding-bottom: 0 !important;
}

.nfcp-list__items {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
	gap: 1rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.nfcp-card--puzzle {
	margin: 0;
	transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.nfcp-card--puzzle:hover {
	transform: translateY(-4px);
	box-shadow: var(--nfcp-shadow-lg);
}

.nfcp-card__title {
	margin: 0 0 0.6rem;
	font-family: var(--nfcp-display);
	font-size: 1.05rem;
	font-weight: 800;
	letter-spacing: -0.01em;
	line-height: 1.3;
}

.nfcp-card__title a {
	color: var(--nfcp-ink);
	text-decoration: none;
}

.nfcp-card__title a:hover,
.nfcp-card__title a:focus {
	color: var(--nfcp-indigo);
	text-decoration: none;
}

.nfcp-card__meta {
	display: flex;
	flex-wrap: wrap;
	margin: 0;
}

.nfcp-card--puzzle.is-played {
	border-color: #bbf7d0;
}

.nfcp-list__empty {
	color: var(--nfcp-muted);
	font-style: italic;
}

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

/* One grid, sized from a custom property the renderer sets, so the same CSS
   serves an 8x8 and a 20x20. `aspect-ratio: 1` on the cells keeps them square
   without knowing the container width — which matters under Divi, where the
   column width is whatever the page builder decided. */
.nfcp-ws__grid {
	display: grid;
	grid-template-columns: repeat(var(--nfcp-ws-size, 12), 1fr);
	gap: 2px;
	max-width: 34rem;
	margin: 0 0 1.25rem;
	padding: 0.6rem;
	border: 1px solid var(--nfcp-line);
	border-radius: var(--nfcp-radius);
	background: var(--nfcp-card-bg);
	box-shadow: var(--nfcp-shadow);
	touch-action: manipulation;
}

.nfcp-ws__cell {
	display: flex;
	align-items: center;
	justify-content: center;
	aspect-ratio: 1;
	padding: 0;
	border: none;
	border-radius: 4px;
	background: transparent;
	color: var(--nfcp-ink);
	font-family: var(--nfcp-body);

	/* Clamped rather than fixed: a 20x20 grid on a phone needs smaller type
	   than a 8x8 on a desktop, and no media query knows which it is. */
	font-size: clamp(0.6rem, 2.4vw, 0.95rem);
	font-weight: 600;
	line-height: 1;
	text-transform: uppercase;
	cursor: pointer;
	user-select: none;
}

.nfcp-ws__cell:hover {
	background: var(--nfcp-bg);
}

/* The first end of a selection, waiting for the second. */
.nfcp-ws__cell.is-anchor {
	background: var(--nfcp-violet);
	color: #fff;
}

.nfcp-ws__cell.is-found {
	background: #dcfce7;
	color: #15803d;
}

/* A found square that is also the current anchor stays the anchor colour —
   crossing words share squares, so this happens constantly. */
.nfcp-ws__cell.is-found.is-anchor {
	background: var(--nfcp-violet);
	color: #fff;
}

.nfcp-ws__words {
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem 0.75rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.nfcp-ws__word {
	font-weight: 600;
	letter-spacing: 0.02em;
	text-transform: uppercase;
}

.nfcp-ws__word.is-found {
	color: var(--nfcp-muted);
	text-decoration: line-through;
}

.nfcp-ws__word.is-wrong {
	color: var(--nfcp-red);
}

/* ---------- Sudoku ---------- */

.nfcp-sd__grid {
	display: grid;
	grid-template-columns: repeat(9, 1fr);
	max-width: 30rem;
	margin: 0 0 1.25rem;
	border: 2px solid var(--nfcp-ink);
	border-radius: var(--nfcp-radius-sm);
	background: var(--nfcp-card-bg);
	box-shadow: var(--nfcp-shadow);
	overflow: hidden;
}

.nfcp-sd__cell {
	display: flex;
	align-items: center;
	justify-content: center;
	aspect-ratio: 1;
	border-right: 1px solid var(--nfcp-line);
	border-bottom: 1px solid var(--nfcp-line);
}

/* The 3x3 boxes, drawn on the cells that sit on a box edge. A nested grid
   would look the same and break the keyboard order, which has to run straight
   across the board. */
.nfcp-sd__cell.is-box-right {
	border-right-width: 2px;
	border-right-color: var(--nfcp-ink);
}

.nfcp-sd__cell.is-box-bottom {
	border-bottom-width: 2px;
	border-bottom-color: var(--nfcp-ink);
}

.nfcp-sd__cell.is-clue {
	background: var(--nfcp-bg);
	color: var(--nfcp-ink);
	font-family: var(--nfcp-display);
	font-size: clamp(0.9rem, 3.5vw, 1.25rem);
	font-weight: 700;
}

.nfcp-sd__input {
	width: 100%;
	height: 100%;
	padding: 0;
	border: none;
	border-radius: 0;
	background: transparent;
	color: var(--nfcp-indigo);
	font-family: var(--nfcp-body);
	font-size: clamp(0.9rem, 3.5vw, 1.25rem);
	font-weight: 600;
	text-align: center;

	/* Divi styles inputs globally; without this the numbers sit off-centre and
	   the cell grows a shadow the grid did not ask for. */
	box-shadow: none;
	appearance: none;
}

.nfcp-sd__input:focus {
	outline: none;
	background: #ede9fe;
	box-shadow: inset 0 0 0 2px var(--nfcp-violet);
}

.nfcp-sd__cell.is-wrong {
	background: #fee2e2;
}

.nfcp-sd__cell.is-wrong .nfcp-sd__input {
	color: var(--nfcp-red);
}

/* ---------- Crossword ---------- */

.nfcp-cw__grid {
	display: grid;
	grid-template-columns: repeat(var(--nfcp-cw-cols, 5), 1fr);
	max-width: 32rem;
	margin: 0 0 1.25rem;
	border: 2px solid var(--nfcp-ink);
	border-radius: var(--nfcp-radius-sm);
	background: var(--nfcp-card-bg);
	box-shadow: var(--nfcp-shadow);
	overflow: hidden;
}

.nfcp-cw__cell {
	position: relative;
	aspect-ratio: 1;
	border-right: 1px solid var(--nfcp-line);
	border-bottom: 1px solid var(--nfcp-line);
}

.nfcp-cw__cell.is-block {
	background: var(--nfcp-ink);
}

/* The entry number sits in the corner of the square it starts, small enough
   not to compete with the letter the player types over it. */
.nfcp-cw__number {
	position: absolute;
	top: 1px;
	left: 3px;
	font-size: clamp(0.5rem, 1.6vw, 0.625rem);
	font-weight: 700;
	line-height: 1;
	color: var(--nfcp-muted);
	pointer-events: none;
}

.nfcp-cw__input {
	width: 100%;
	height: 100%;
	padding: 0;
	border: none;
	border-radius: 0;
	background: transparent;
	color: var(--nfcp-indigo);
	font-family: var(--nfcp-body);
	font-size: clamp(0.75rem, 3vw, 1.1rem);
	font-weight: 700;
	text-align: center;
	text-transform: uppercase;

	/* Divi styles inputs globally; without these the letters sit off-centre
	   and every square grows a shadow the grid did not ask for. */
	box-shadow: none;
	appearance: none;
}

.nfcp-cw__input:focus {
	outline: none;
	background: #ede9fe;
	box-shadow: inset 0 0 0 2px var(--nfcp-violet);
}

.nfcp-cw__cell.is-wrong {
	background: #fee2e2;
}

.nfcp-cw__cell.is-wrong .nfcp-cw__input {
	color: var(--nfcp-red);
}

.nfcp-cw__clues {
	display: flex;
	flex-wrap: wrap;
	gap: 1.5rem;
}

.nfcp-cw__cluelist {
	flex: 1 1 14rem;
}

.nfcp-cw__cluehead {
	margin: 0 0 0.5rem;
	font-family: var(--nfcp-display);
	font-size: 0.9rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--nfcp-muted);
}

.nfcp-cw__clueitems {
	margin: 0;
	padding: 0;
	list-style: none;
}

.nfcp-cw__clue {
	margin-bottom: 0.4rem;
	line-height: 1.45;
	color: var(--nfcp-ink-soft);
}

.nfcp-cw__cluenum {
	color: var(--nfcp-ink);
}

/* ---------- Jigsaw ---------- */

.nfcp-jg {
	margin: 0 0 1.25rem;
}

.nfcp-jg__tools {
	display: flex;
	justify-content: center;
	margin: 0 0 0.6rem;
}

/*
 * The finished picture, over the board while the player asks for it.
 *
 * At the size of the board rather than in a thumbnail beside it: the point is
 * to remember what you are making, and a stamp-sized version of a fifty-piece
 * photograph tells you nothing. The board is already drawn at the picture's own
 * proportions, so 100% each way fills it without cropping or stretching.
 */
.nfcp-jg__preview {
	position: absolute;
	inset: 0;
	z-index: 500;
	border-radius: var(--nfcp-radius);
	background-repeat: no-repeat;
	background-position: center;
	background-size: 100% 100%;
	box-shadow: 0 0 0 3px var(--nfcp-violet), var(--nfcp-shadow-lg);
	cursor: zoom-out;
}

/* Themes reset [hidden] often enough that it is worth restating. */
.nfcp-jg__preview[hidden] {
	display: none;
}

/*
 * The board is drawn at the picture's own shape, and the spaces divide it.
 *
 * It used to be a grid of square cells, which meant the picture was stretched
 * to whatever the grid's proportions happened to be — 3:2 or 4:3 — and anything
 * portrait came out visibly squashed. The server sends the shape, so the height
 * follows from the width and the spaces inherit the right proportions.
 *
 * The three width bounds are all doing something: 100% keeps it inside a narrow
 * phone, 34rem stops a landscape picture from filling a desktop, and the 70vh
 * term is what keeps a portrait one from running off the bottom of the screen —
 * with an aspect ratio set, height can only be limited through width.
 *
 * No padding, and the spaces are positioned rather than laid out in a grid:
 * a percentage on an absolutely positioned child resolves against the padding
 * box, so padding here would shift every piece off its space by a few pixels.
 */
.nfcp-jg__board {
	position: relative;
	aspect-ratio: var(--nfcp-jg-ratio, 1.3333);
	width: min(100%, 34rem, calc(70vh * var(--nfcp-jg-ratio, 1.3333)));
	margin: 0 auto 1rem;
	border-radius: var(--nfcp-radius);
	background: var(--nfcp-bg);
	box-shadow: var(--nfcp-shadow);
	touch-action: none;
}

/* Definitions only — the clip paths every piece is cut out with. */
.nfcp-jg__shapes {
	position: absolute;
	width: 0;
	height: 0;
}

/* One empty space on the board. */
.nfcp-jg__cell {
	position: absolute;
	padding: 0;
	border: 1px dashed rgb(0 0 0 / 12%);
	background: none;
	cursor: pointer;
}

.nfcp-jg__cell:disabled {
	border-color: transparent;
	cursor: default;
}

/*
 * A piece is its space grown by a tab on all four sides, so the tabs have
 * somewhere to be drawn — which is why they overlap their neighbours. The clip
 * path is what makes that safe: a browser will not deliver a pointer event to
 * the part of an element the clip has removed, so the overlap is invisible to
 * the hand as well as to the eye.
 *
 * The aspect ratio only matters in the tray. On the board every piece is given
 * an explicit width and height as percentages of the board.
 */
.nfcp-jg__piece {
	aspect-ratio: var(--nfcp-jg-piece-ratio, 1);
	width: var(--nfcp-jg-tray-size, 4.5rem);
	padding: 0;
	border: none;
	background-repeat: no-repeat;
	cursor: grab;
	transition: filter 0.12s ease;
}

.nfcp-jg__piece:hover {
	filter: brightness(1.06);
}

/*
 * The piece being held, by click or by keyboard.
 *
 * A ring cannot follow a jigsaw outline, so this is a pair of drop shadows
 * tracing the clip instead — box-shadow and outline both draw the rectangle
 * the piece is not. Two of them because one is too faint to read as a ring.
 */
.nfcp-jg__piece.is-picked,
.nfcp-jg__piece:focus-visible {
	outline: none;
	filter:
		drop-shadow(0 0 2px var(--nfcp-violet))
		drop-shadow(0 0 2px var(--nfcp-violet));
}

/* In the hand: out of the layout, above everything, following the pointer. */
.nfcp-jg__piece.is-dragging {
	position: fixed;
	z-index: 999;
	cursor: grabbing;
	filter: drop-shadow(0 6px 10px rgb(0 0 0 / 35%));
	transition: none;
}

/*
 * The pieces not yet on the board.
 *
 * A strip rather than the scattered field a desktop jigsaw uses: it stays
 * inside whatever column the shortcode was dropped into, and it is the only
 * version of this that works on a phone.
 */
.nfcp-jg__tray {
	display: flex;
	flex-wrap: wrap;
	gap: 0;
	align-content: flex-start;
	justify-content: center;
	min-height: 5rem;
	max-height: 16rem;
	padding: 0.5rem;
	overflow-y: auto;
	border-radius: var(--nfcp-radius);
	background: var(--nfcp-bg);
	touch-action: none;
}

/* ---------- Browse: categories, then the puzzles in one ---------- */

/*
 * Both views are in the DOM at once and the wrapper decides which is showing.
 *
 * That is deliberate rather than lazy: with no JavaScript the wrapper never
 * gets `is-open`, every group stays visible, and the page degrades into a
 * complete index of every category and its puzzles — which is also exactly
 * what a crawler should be served.
 */
.nfcp-browse__categories {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
	gap: 1rem;
	margin: 0 0 1.5rem;
}

.nfcp-browse.is-open .nfcp-browse__categories {
	display: none;
}

.nfcp-browse__group {
	margin: 0 0 2rem;
}

/*
 * Collapsing is what the script buys, so the script is what turns it on.
 * Without `is-enhanced` every group stays open under the tiles, which is the
 * whole index on one page — the right thing to serve a crawler, and the right
 * thing to leave someone whose JavaScript never arrived.
 */
.nfcp-browse.is-enhanced .nfcp-browse__group {
	display: none;
}

.nfcp-browse.is-enhanced .nfcp-browse__group.is-current {
	display: block;
}

/* Only meaningful once a category can be opened, so JS reveals it. */
.nfcp-browse__head {
	display: none;
	align-items: center;
	gap: 0.75rem;
	margin: 0 0 1rem;
}

.nfcp-browse.is-enhanced .nfcp-browse__head {
	display: flex;
}

.nfcp-browse__back {
	padding: 0.4rem 0.8rem;
	border: 1.5px solid var(--nfcp-line);
	border-radius: var(--nfcp-radius-sm);
	background: #fff;
	color: var(--nfcp-indigo);
	font-family: var(--nfcp-body);
	font-size: 0.85rem;
	font-weight: 600;
	cursor: pointer;
}

.nfcp-browse__back:hover {
	border-color: var(--nfcp-indigo);
	background: var(--nfcp-grad-soft);
}

.nfcp-browse__title {
	margin: 0;
	font-family: var(--nfcp-display);
	font-size: 1.25rem;
	font-weight: 700;
}

/* One category tile. The tint is set per engine below. */
.nfcp-cat {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 0.5rem;
	padding: 1.5rem 1rem 1.75rem;
	border: none;
	border-radius: var(--nfcp-radius);
	background: linear-gradient(180deg, var(--nfcp-cat-tint, #ede9fe) 0%, #fff 85%);
	color: var(--nfcp-ink);
	text-align: center;
	cursor: pointer;
	transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.nfcp-cat:hover,
.nfcp-cat:focus-visible {
	transform: translateY(-3px);
	box-shadow: var(--nfcp-shadow);
}

.nfcp-cat__icon {
	display: block;
	width: 3.5rem;
	height: 3.5rem;
	margin: 0 0 0.35rem;
}

.nfcp-cat__icon svg {
	width: 100%;
	height: 100%;
}

.nfcp-cat__name {
	font-family: var(--nfcp-display);
	font-size: 1.15rem;
	font-weight: 700;
	line-height: 1.2;
}

.nfcp-cat__blurb {
	color: var(--nfcp-ink-soft);
	font-size: 0.85rem;
	line-height: 1.35;
}

.nfcp-cat__count {
	color: var(--nfcp-muted);
	font-size: 0.75rem;
	font-weight: 600;
	letter-spacing: 0.02em;
	text-transform: uppercase;
}

/*
 * A hue per engine. Keyed by engine id, which is the same key
 * `.nfcp-card--<engine>` already uses, so a new engine picks up the fallback
 * tint above and looks deliberate rather than broken while someone chooses it
 * a colour.
 */
.nfcp-cat--crossword {
	--nfcp-cat-tint: #fdf0c8;
}

.nfcp-cat--quiz {
	--nfcp-cat-tint: #fbdde2;
}

.nfcp-cat--wordsearch {
	--nfcp-cat-tint: #cfe6fa;
}

.nfcp-cat--sudoku {
	--nfcp-cat-tint: #e3d9f8;
}

.nfcp-cat--jigsaw {
	--nfcp-cat-tint: #d5ecd9;
}

/* ---------- The category icons ---------- */

.nfcp-ico__frame {
	fill: #fff;
	stroke: var(--nfcp-ink);
	stroke-width: 2;
}

.nfcp-ico__dark {
	fill: var(--nfcp-ink);
}

.nfcp-ico__tint {
	fill: #f6e6cf;
}

.nfcp-ico__accent {
	fill: #f59e0b;
}

.nfcp-ico__blue {
	fill: #3b82f6;
}

.nfcp-ico__dot {
	fill: #9ca3af;
}

.nfcp-ico__blue-dot {
	fill: #3b82f6;
}

.nfcp-ico__stroke {
	stroke: #f59e0b;
	stroke-width: 7;
	stroke-linecap: round;
	opacity: 0.75;
}

.nfcp-ico__rule {
	stroke: var(--nfcp-ink);
	stroke-width: 1.5;
	fill: none;
}

.nfcp-ico__piece {
	fill: #fff;
	stroke: var(--nfcp-ink);
	stroke-width: 2;
	stroke-linejoin: round;
}

.nfcp-ico__num {
	fill: var(--nfcp-ink);
	font-family: var(--nfcp-body);
	font-size: 11px;
	font-weight: 700;
}

.nfcp-ico__glyph {
	fill: #fff;
	font-family: var(--nfcp-display);
	font-size: 20px;
	font-weight: 700;
}

/* ---------- A puzzle nobody signed up for yet ---------- */

.nfcp-card.is-locked {
	opacity: 0.92;
}

.nfcp-card__lock {
	padding: 0;
	border: none;
	background: none;
	color: inherit;
	font: inherit;
	text-align: left;
	cursor: pointer;
}

.nfcp-card__padlock {
	margin-left: 0.35rem;
	font-size: 0.85em;
}

.nfcp-card__notice {
	margin: 0.6rem 0 0;
	padding: 0.6rem 0.75rem;
	border-radius: var(--nfcp-radius-sm);
	background: var(--nfcp-grad-soft);
	color: var(--nfcp-ink-soft);
	font-size: 0.85rem;
}

.nfcp-card__signup {
	color: var(--nfcp-indigo);
	font-weight: 700;
	text-decoration: none;
	white-space: nowrap;
}

/* Divi paints every link #2ea3f2, so this has to say so itself. */
.nfcp-card__signup:hover,
.nfcp-card__signup:focus {
	color: var(--nfcp-magenta);
	text-decoration: underline;
}
