/* PCF Hub — front-end app styles.

   GENERATED FILE. Built from preview/pcf-preview.css by tools/build-app-css.mjs,
   with every rule scoped under .pcf-app so no theme rule leaks in and none of
   ours leaks out. Edit the preview sheet and re-run the tool; changes made here
   are lost on the next build. */

/* Perfect Circle Format — front-end preview
   Tokens shared with the PCF Hub plugin (simonemissaglia.com family). */

.pcf-app {
	--bg: #f6f6f3;
	--surface: #ffffff;
	--surface-2: #f0f0ec;
	--surface-3: #e8e8e3;
	--text: #111111;
	--muted: #575757;
	--faint: #8a8a86;
	--line: #d8d8d4;
	--accent: #111111;
	--on-accent: #ffffff;

	/* Categorical series, for the representation chart. Six fixed hues assigned
	   in order and never cycled — a seventh deck folds into "Other" in grey.
	   Both sets are checked (lightness band, chroma, colour-blind separation
	   and contrast against this theme's surface) rather than picked by eye. */
	--series-1: #2a78d6;
	--series-2: #eb6834;
	--series-3: #1baf7a;
	--series-4: #eda100;
	--series-5: #e87ba4;
	--series-6: #008300;
	--series-rest: #9a9a96;

	--forbidden: #b3261e;
	--limited: #b4690e;
	--semi: #2f6f3e;
	--monster: #a9762f;
	--spell: #1c7a6b;
	--trap: #9b2f6f;
	--perfect: #4b3fbf;
	--gold: #d9a520;

	--r: 12px;
	--r-sm: 8px;
	--r-lg: 20px;
	--ease: cubic-bezier(.22, 1, .36, 1);
	--fast: 180ms;
	--shadow: 0 20px 45px -34px rgba(0, 0, 0, .45);
	--shadow-lg: 0 32px 70px -40px rgba(0, 0, 0, .6);
	--head-h: 58px;

	/* One decklist strip is ten cards across at --ev-card plus nine 3px gaps;
	   a row card is that plus its own padding and border. Both live here
	   because the deck preview, the sheet image and the card width have to
	   agree — see .ev-mini / .ev-deck / .ev-row. */
	--ev-card: 46px;
	--ev-deck-w: 487px;
	--ev-row-w: 517px;
}

.pcf-app[data-theme="dark"] {
	--bg: #141618;
	--surface: #1d2023;
	--surface-2: #24282c;
	--surface-3: #2c3135;
	--text: #f3f3f2;
	--muted: #d0d0cc;
	--faint: #9a9a96;
	--line: #3a3e42;
	--accent: #f3f3f2;
	--on-accent: #141618;
	--forbidden: #e2695f;
	--series-1: #3987e5;
	--series-2: #d95926;
	--series-3: #199e70;
	--series-4: #c98500;
	--series-5: #d55181;
	--series-6: #008300;
	--series-rest: #7d8288;
	--limited: #dc9a3e;
	--semi: #6fbf85;
	--monster: #d8ab68;
	--spell: #56bfad;
	--trap: #dd7ab0;
	--perfect: #9b91f5;
	--gold: #e6bb45;
	--shadow: 0 20px 45px -30px rgba(0, 0, 0, .8);
	--shadow-lg: 0 32px 70px -36px rgba(0, 0, 0, .9);
}

.pcf-app, .pcf-app * { box-sizing: border-box; }

/* Smooth crossfade between pages instead of the browser's default flash of
   white while a full-page navigation loads: the View Transitions API keeps
   the old page's pixels on screen and fades straight into the new page's,
   with no blank gap between them. Same-origin navigations only, and only
   where the browser supports it — everywhere else this block is simply
   ignored and navigation looks exactly as it did before. */
@view-transition {
	navigation: auto;
}

/* the ::view-transition pseudo-tree sits outside .pcf-app's box, at the
   document root — it cannot see --ease (defined on .pcf-app so no theme rule
   leaks out of it), so the curve is spelled out here rather than referenced */
::view-transition-group(root) {
	animation-duration: 260ms;
	animation-timing-function: cubic-bezier(.22, 1, .36, 1);
}

/* the old page fades out, the new page fades in over the tail of that; any
   real gap between the two falls back to the live page's own <body>
   background (this stylesheet has nothing themed to offer at that scope —
   see above), which is never white to begin with */
::view-transition-old(root) {
	animation: pcf-fade-out 260ms cubic-bezier(.22, 1, .36, 1) both;
}

::view-transition-new(root) {
	animation: pcf-fade-in 260ms cubic-bezier(.22, 1, .36, 1) both;
}

@keyframes pcf-fade-out {
	to { opacity: 0; }
}

@keyframes pcf-fade-in {
	from { opacity: 0; }
}

.pcf-app,
.pcf-app { height: 100%; }
.pcf-app { overflow-x: hidden; }

.pcf-app {
	margin: 0;
	/* kills the double-tap zoom, which fired on every card tap; pinch to zoom
	   is left alone so the page can still be enlarged on purpose */
	touch-action: manipulation;
	background: var(--bg);
	color: var(--text);
	font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
	font-size: 14px;
	line-height: 1.5;
	-webkit-font-smoothing: antialiased;
	display: flex;
	flex-direction: column;
	overflow: hidden;
}

.pcf-app a { color: inherit; }

.pcf-app button,
.pcf-app input,
.pcf-app select,
.pcf-app textarea { font: inherit; color: inherit; }

.pcf-app ::-webkit-scrollbar { width: 10px; height: 10px; }
.pcf-app ::-webkit-scrollbar-track { background: transparent; }
.pcf-app ::-webkit-scrollbar-thumb { background: var(--line); border-radius: 99px; border: 3px solid var(--bg); }
.pcf-app ::-webkit-scrollbar-thumb:hover { background: var(--faint); }

/* ---------- header ---------- */

.pcf-app .site-head {
	height: var(--head-h);
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	gap: 22px;
	padding: 0 20px;
	background: var(--surface);
	border-bottom: 1px solid var(--line);
	position: relative;
	z-index: 40;
}

.pcf-app .brand {
	display: flex;
	align-items: center;
	gap: 10px;
	text-decoration: none;
	font-weight: 600;
	letter-spacing: -.01em;
	white-space: nowrap;
}

.pcf-app .brand {
	order: -1;
	margin-right: 0;
}

/* As tall as the 58px bar allows once its own padding is accounted for. The
   header keeps its height; only the mark grows into it. */
.pcf-app .brand .mark {
	position: relative;
	top: auto;
	right: auto;
	width: 44px;
	height: 44px;
	flex: 0 0 auto;
	border-radius: 0;
	box-shadow: none;
	background: url("../img/pc-icon.png") center / contain no-repeat;
}

/* the mark is black line art on a transparent ground: in the dark theme it
   would sink into the surface. Inverting it is no longer enough — the logo has
   a red triangle, which invert() turns cyan — so the white artwork is swapped
   in instead. */
.pcf-app[data-theme="dark"] .brand .mark {
	background-image: url("../img/pc-icon-light.png");
}

/* restored: without this the subtitle runs on after the title and the brand
   becomes one long line that shoves the rest of the bar sideways */
.pcf-app .brand small {
	display: block;
	font-weight: 400;
	font-size: 11px;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--faint);
	line-height: 1.1;
}

.pcf-app .nav { display: flex; gap: 4px; margin-left: 6px; }

.pcf-app .nav a {
	text-decoration: none;
	padding: 7px 13px;
	border-radius: 99px;
	color: var(--muted);
	transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
}

.pcf-app .nav a:hover { background: var(--surface-2); color: var(--text); }
.pcf-app .nav a[aria-current="page"] { background: var(--accent); color: var(--on-accent); }

.pcf-app .head-right { margin-left: auto; display: flex; align-items: center; gap: 10px; }

/* the phone-only hamburger and the panel it opens — on a wide screen the
   button never shows and the panel is display:contents, which erases it from
   layout entirely, so .nav and .head-right sit exactly where they already did */
.pcf-app .menu-toggle {
	display: none;
	width: 34px;
	height: 34px;
	flex: 0 0 auto;
	border-radius: 50%;
	border: 1px solid var(--line);
	background: var(--surface);
	cursor: pointer;
}

.pcf-app .menu-toggle span,
.pcf-app .menu-toggle span::before,
.pcf-app .menu-toggle span::after {
	display: block;
	width: 16px;
	height: 1.6px;
	border-radius: 2px;
	background: var(--text);
	transition: transform 220ms var(--ease), opacity 140ms var(--ease);
}

.pcf-app .menu-toggle span { position: relative; }
.pcf-app .menu-toggle span::before,
.pcf-app .menu-toggle span::after { content: ""; position: absolute; left: 0; }
.pcf-app .menu-toggle span::before { top: -5px; }
.pcf-app .menu-toggle span::after { top: 5px; }

/* open: the middle bar fades and the other two cross into an X, so the button
   always says what the next tap does */
.pcf-app .menu-toggle[aria-expanded="true"] { background: var(--accent); border-color: var(--accent); }
.pcf-app .menu-toggle[aria-expanded="true"] span { background: transparent; }
.pcf-app .menu-toggle[aria-expanded="true"] span::before,
.pcf-app .menu-toggle[aria-expanded="true"] span::after { background: var(--on-accent); }
.pcf-app .menu-toggle[aria-expanded="true"] span::before { transform: translateY(5px) rotate(45deg); }
.pcf-app .menu-toggle[aria-expanded="true"] span::after { transform: translateY(-5px) rotate(-45deg); }

.pcf-app .menu-panel { display: contents; }

.pcf-app .fmt-chip {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 6px 12px 6px 8px;
	border: 1px solid var(--line);
	border-radius: 99px;
	background: var(--surface-2);
	text-decoration: none;
	font-size: 12.5px;
	color: var(--muted);
	transition: border-color var(--fast) var(--ease);
}

.pcf-app .fmt-chip:hover { border-color: var(--faint); color: var(--text); }
.pcf-app .fmt-chip .fmt-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--faint); flex: 0 0 auto; margin-left: 4px; }

/* the Goat / Perfect Circle switch — a two-way segmented control next to the
   banlist chip, present on every app screen since it is rendered once, in the
   shared header (PCF_App::head()), not per-screen */
.pcf-app .fmt-toggle {
	display: inline-flex;
	flex: 0 0 auto;
	padding: 3px;
	border: 1px solid var(--line);
	border-radius: 99px;
	background: var(--surface-2);
	gap: 2px;
}
.pcf-app .fmt-toggle button {
	appearance: none;
	border: 0;
	background: transparent;
	color: var(--muted);
	font: inherit;
	font-size: 12.5px;
	font-weight: 600;
	padding: 5px 12px;
	border-radius: 99px;
	cursor: pointer;
	/* "Perfect Circle" is long enough that a tight flex row (the mobile menu
	   shelf, squeezed alongside the account avatar and theme toggle) would
	   otherwise shrink the button until the words wrapped — JS swaps in the
	   short label there (see initChrome()), but nothing should ever wrap or
	   collapse the pill into a circle while that happens or if it fails */
	white-space: nowrap;
	flex: 0 0 auto;
	transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
}
.pcf-app .fmt-toggle button:hover { color: var(--text); }
.pcf-app .fmt-toggle button.active { background: var(--accent); color: var(--on-accent); }

.pcf-app .icon-btn {
	width: 34px;
	height: 34px;
	display: grid;
	place-items: center;
	border-radius: 50%;
	border: 1px solid var(--line);
	background: var(--surface);
	cursor: pointer;
	transition: background var(--fast) var(--ease), border-color var(--fast) var(--ease);
}

.pcf-app .icon-btn:hover { background: var(--surface-2); }

/* Safari does not honour grid/flex centring on a <button>'s anonymous content
   box, which is what left the hamburger, the close cross and the header icons
   sitting a couple of pixels off centre inside their circles. Placing the
   child explicitly is not subject to that quirk anywhere. */
.pcf-app .icon-btn,
.pcf-app .menu-toggle { position: relative; }

.pcf-app .icon-btn > *,
.pcf-app .menu-toggle > span {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
}

/* Every control in the app that holds an icon, sized in one place.

   An inline <svg> carries no intrinsic size, so wherever one of these is left
   out the icon renders at 0x0 and the control collapses around it — silently,
   with nothing on screen to suggest a button was ever meant to be there. The
   `display: block` matters too: an inline SVG sits on the text baseline and
   leaves a few pixels of descender space under it, which is what makes an
   icon look a touch high inside its own circle. */
.pcf-app .icon-btn svg,
.pcf-app .btn svg,
.pcf-app .saved .x svg,
.pcf-app[data-icon] svg { width: 16px; height: 16px; display: block; flex: 0 0 auto; }

.pcf-app .btn svg { width: 14px; height: 14px; }

/* ---------- layout ---------- */

.pcf-app main { flex: 1 1 auto; min-height: 0; display: flex; }

.pcf-app .site-foot {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 9px;
	padding: 11px 20px;
	border-top: 1px solid var(--line);
	background: var(--surface);
	font-size: 11.5px;
	letter-spacing: .02em;
	color: var(--faint);
}

.pcf-app .site-foot-logo { height: 18px; width: auto; display: none; }
.pcf-app .site-foot .is-light { display: block; }

.pcf-app[data-theme="dark"] .site-foot .is-light { display: none; }
.pcf-app[data-theme="dark"] .site-foot .is-dark { display: block; }

.pcf-app .pane { min-height: 0; min-width: 0; display: flex; flex-direction: column; }
.pcf-app .scroll { overflow-y: auto; overflow-x: hidden; min-height: 0; overscroll-behavior: contain; }

.pcf-app .pane-head {
	flex: 0 0 auto;
	padding: 14px 18px;
	border-bottom: 1px solid var(--line);
	background: var(--surface);
}

.pcf-app .rail { border-left: 1px solid var(--line); background: var(--surface); }
.pcf-app .rail-l { border-right: 1px solid var(--line); border-left: 0; background: var(--surface); }

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

.pcf-app .search-row { display: flex; gap: 8px; align-items: center; }

.pcf-app .search-field { position: relative; flex: 1 1 auto; }

.pcf-app .search-field svg {
	position: absolute;
	left: 12px;
	top: 50%;
	transform: translateY(-50%);
	width: 15px;
	height: 15px;
	color: var(--faint);
	pointer-events: none;
}

.pcf-app input[type="text"],
.pcf-app input[type="number"],
.pcf-app select {
	width: 100%;
	padding: 9px 12px;
	border: 1px solid var(--line);
	border-radius: var(--r-sm);
	background: var(--bg);
	outline: none;
	/* iOS Safari bug: with the body's line-height (1.5) inherited into a
	   single-line input, the text caret renders near the TOP of that inflated
	   line box instead of centered on the glyphs — most visible in the advanced
	   search's Level/ATK number fields, where the box is narrow and short. A
	   near-1 line-height keeps the line box close to the actual text height,
	   so there is nowhere above the glyphs left for the caret to drift to. */
	line-height: normal;
	transition: border-color var(--fast) var(--ease), background var(--fast) var(--ease);
}

.pcf-app .search-field input { padding-left: 34px; border-radius: 99px; }

.pcf-app input:focus,
.pcf-app select:focus { border-color: var(--accent); background: var(--surface); }

.pcf-app select { appearance: none; padding-right: 28px; background-image: linear-gradient(45deg, transparent 50%, var(--faint) 50%), linear-gradient(135deg, var(--faint) 50%, transparent 50%); background-position: calc(100% - 15px) 52%, calc(100% - 10px) 52%; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; }

.pcf-app .btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
	padding: 9px 14px;
	border: 1px solid var(--line);
	border-radius: 99px;
	background: var(--surface);
	cursor: pointer;
	white-space: nowrap;
	transition: background var(--fast) var(--ease), border-color var(--fast) var(--ease), transform var(--fast) var(--ease);
}

.pcf-app .btn:hover { background: var(--surface-2); }
.pcf-app .btn:active { transform: translateY(1px); }
.pcf-app .btn[aria-pressed="true"] { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
.pcf-app .btn.primary { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
.pcf-app .btn.sm { padding: 6px 11px; font-size: 12.5px; }
.pcf-app .btn.block { width: 100%; }

/* the one destructive action in the panel, and the one in a modal that
   confirms it: outlined rather than filled, so it is unmistakable without
   shouting over everything else in a small column */
.pcf-app .btn.danger {
	color: var(--forbidden);
	/* declared twice: the plain value is what a browser without color-mix()
	   keeps, and it is already a usable outline rather than a broken one */
	border-color: var(--line);
	border-color: color-mix(in srgb, var(--forbidden) 40%, var(--line));
}

.pcf-app .btn.danger:hover {
	border-color: var(--forbidden);
	background: var(--surface-2);
	background: color-mix(in srgb, var(--forbidden) 12%, var(--surface));
}
.pcf-app .adv {
	display: none;
	grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
	gap: 10px;
	margin-top: 12px;
	padding-top: 12px;
	border-top: 1px solid var(--line);
}

.pcf-app .adv.open { display: grid; }

.pcf-app .adv-reset { grid-column: 1 / -1; align-self: end; }

.pcf-app .field label {
	display: block;
	font-size: 11px;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--faint);
	margin-bottom: 5px;
}

.pcf-app .range { display: flex; gap: 6px; align-items: center; }
.pcf-app .range input { padding: 8px 9px; text-align: center; }

.pcf-app .result-meta {
	display: flex;
	align-items: center;
	gap: 10px;
	margin-top: 10px;
	font-size: 12.5px;
	color: var(--muted);
}

.pcf-app .result-meta .spacer { flex: 1 1 auto; }

/* ---------- card grid ---------- */

.pcf-app .card-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(var(--tile, 118px), 1fr));
	gap: 14px 12px;
	padding: 16px 18px 28px;
	align-content: start;
}

.pcf-app .card-cell {
	border: 0;
	background: none;
	padding: 0;
	cursor: pointer;
	text-align: left;
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.pcf-app .thumb {
	position: relative;
	aspect-ratio: 59 / 86;
	border-radius: 6px;
	overflow: hidden;
	background: var(--surface-3);
	box-shadow: var(--shadow);
	transition: transform var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}

.pcf-app .thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

.pcf-app .card-cell:hover .thumb,
.pcf-app .card-cell:focus-visible .thumb { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
.pcf-app .card-cell.active .thumb { outline: 2px solid var(--accent); outline-offset: 2px; }

.pcf-app .card-cell .nm {
	font-size: 11.5px;
	line-height: 1.25;
	color: var(--muted);
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.pcf-app .card-cell.active .nm { color: var(--text); }

.pcf-app .dot {
	position: absolute;
	top: 5px;
	left: 5px;
	width: 17px;
	height: 17px;
	border-radius: 50%;
	display: grid;
	place-items: center;
	font-size: 10px;
	font-weight: 700;
	color: #fff;
	box-shadow: 0 1px 4px rgba(0, 0, 0, .5);
}

/* Scoped on purpose: the brand in the header is also a <span class="mark">, and
   an unscoped rule pinned it to the top-right corner of the header with
   position:absolute — on top of the theme switch. The deck slot is listed too
   because the deckbuilder lifts the thumbnail's children out into the slot. */
.pcf-app .thumb .mark,
.pcf-app .slot .mark {
	position: absolute;
	top: 4px;
	right: 4px;
	width: 26px;
	height: 26px;
	border-radius: 50%;
	display: grid;
	place-items: center;
	background: var(--gold);
	box-shadow: 0 1px 5px rgba(0, 0, 0, .55);
	overflow: hidden;
}

/* the badge carries its own red, so it is never inverted or recoloured; the
   white disc behind it is what makes it readable over any card art */
/* the badge carries its own red, so it is never inverted or recoloured; the
   gold disc behind it is what makes it readable over any card art */
.pcf-app .thumb .mark .mk,
.pcf-app .slot .mark .mk { width: 26px; height: 26px; display: block; }
.pcf-app .legend .chip-mark { background: var(--gold); }
.pcf-app img.fmt-icon { width: 17px; height: 17px; display: inline-block; vertical-align: -4px; border-radius: 50%; background: var(--gold); }

.pcf-app .dot.l0 { background: var(--forbidden); }
.pcf-app .dot.l1 { background: var(--limited); }
.pcf-app .dot.l2 { background: var(--semi); }

.pcf-app .empty-note { padding: 40px 18px; color: var(--faint); text-align: center; }

/* ---------- card detail ---------- */

.pcf-app .detail { padding: 18px; display: flex; flex-direction: column; gap: 14px; }

.pcf-app .detail .art {
	flex: 0 0 auto;
	width: 100%;
	max-width: 236px;
	aspect-ratio: 59 / 86;
	border-radius: 8px;
	overflow: hidden;
	background: var(--surface-3);
	box-shadow: var(--shadow);
	align-self: center;
}

.pcf-app .detail .art img { width: 100%; height: 100%; object-fit: cover; display: block; }

.pcf-app .detail h2 { margin: 0; font-size: 18px; line-height: 1.25; letter-spacing: -.01em; }

.pcf-app .badges { display: flex; flex-wrap: wrap; gap: 6px; }

.pcf-app .badge {
	font-size: 11px;
	letter-spacing: .04em;
	text-transform: uppercase;
	padding: 3px 9px;
	border-radius: 99px;
	border: 1px solid var(--line);
	color: var(--muted);
}

.pcf-app .badge.cat-monster { border-color: color-mix(in srgb, var(--monster) 45%, transparent); color: var(--monster); }
.pcf-app .badge.cat-spell { border-color: color-mix(in srgb, var(--spell) 45%, transparent); color: var(--spell); }
.pcf-app .badge.cat-trap { border-color: color-mix(in srgb, var(--trap) 45%, transparent); color: var(--trap); }
.pcf-app .badge.perfect { display: inline-flex; align-items: center; gap: 6px; background: var(--perfect); border-color: var(--perfect); color: #fff; }
.pcf-app .badge.perfect .fmt-icon { width: 13px; height: 13px; }

.pcf-app .badge.l0 { background: var(--forbidden); border-color: var(--forbidden); color: #fff; }
.pcf-app .badge.l1 { background: var(--limited); border-color: var(--limited); color: #fff; }
.pcf-app .badge.l2 { background: var(--semi); border-color: var(--semi); color: #fff; }

.pcf-app .stat-line { font-size: 12.5px; color: var(--muted); }

.pcf-app .stats {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 1px;
	background: var(--line);
	border: 1px solid var(--line);
	border-radius: var(--r-sm);
	overflow: hidden;
}

.pcf-app .stats div { background: var(--surface); padding: 7px 10px; }
.pcf-app .stats dt { font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--faint); }
.pcf-app .stats dd { margin: 2px 0 0; font-variant-numeric: tabular-nums; }

.pcf-app .cardtext {
	font-size: 13px;
	line-height: 1.55;
	white-space: pre-wrap;
	color: var(--text);
	background: var(--surface-2);
	border-radius: var(--r-sm);
	padding: 12px 13px;
}

.pcf-app .cardtext.flavour { font-style: italic; color: var(--muted); }

.pcf-app .rulings h3 {
	margin: 0 0 8px;
	font-size: 12px;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--faint);
	display: flex;
	align-items: center;
	gap: 8px;
}

.pcf-app .rulings h3 .count {
	font-size: 11px;
	background: var(--surface-3);
	color: var(--muted);
	border-radius: 99px;
	padding: 1px 8px;
	letter-spacing: 0;
}

.pcf-app .rulings ul { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 8px; }

.pcf-app .rulings li {
	font-size: 12.5px;
	line-height: 1.5;
	color: var(--muted);
	padding-left: 14px;
	position: relative;
}

.pcf-app .rulings li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 8px;
	width: 5px;
	height: 5px;
	border-radius: 50%;
	background: var(--line);
}

.pcf-app .rulings .none { font-size: 12.5px; color: var(--faint); }

/* ---------- deckbuilder ---------- */

/* the card and the deck panel, the deck itself, the card pool */
/* the search rail's own column is what actually sizes its four-across cards
   (they are 1fr each, no fixed tile size) — narrower column, smaller cards,
   same four-column structure */
.pcf-app .db { display: grid; grid-template-columns: 330px minmax(0, 1fr) 380px; width: 100%; }

/* Belt and braces so the search rail (and its neighbours) always scroll on
   their own, however tall a sibling's content gets — the row's own height
   already bounds each grid item via .pane's min-height: 0 and the default
   grid stretch, but pinning it explicitly too costs nothing and rules out a
   browser getting that implicit sizing wrong. */
.pcf-app .db > .pane { height: 100%; }

.pcf-app .deck-pane { background: var(--bg); }

.pcf-app .counters {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	gap: 8px;
	padding: 12px 18px;
	border-bottom: 1px solid var(--line);
	background: var(--surface);
	flex-wrap: wrap;
}

.pcf-app .count-pill {
	display: inline-flex;
	align-items: baseline;
	gap: 6px;
	padding: 5px 12px;
	border-radius: 99px;
	background: var(--surface-2);
	border: 1px solid transparent;
	cursor: pointer;
	transition: border-color var(--fast) var(--ease);
}

.pcf-app .count-pill:hover { border-color: var(--line); }
.pcf-app .count-pill[aria-pressed="true"] { border-color: var(--accent); }
.pcf-app .count-pill .k { font-size: 10.5px; letter-spacing: .07em; text-transform: uppercase; color: var(--faint); }
.pcf-app .count-pill .v { font-variant-numeric: tabular-nums; font-weight: 600; }
.pcf-app .count-pill.m .v { color: var(--monster); }
.pcf-app .count-pill.s .v { color: var(--spell); }
.pcf-app .count-pill.t .v { color: var(--trap); }
.pcf-app .count-pill.over .v { color: var(--forbidden); }

.pcf-app .ratio { flex: 1 1 120px; height: 5px; border-radius: 99px; overflow: hidden; display: flex; background: var(--surface-3); min-width: 90px; }
.pcf-app .ratio i { display: block; height: 100%; }
.pcf-app .ratio .m { background: var(--monster); }
.pcf-app .ratio .s { background: var(--spell); }
.pcf-app .ratio .t { background: var(--trap); }

.pcf-app .zones { padding: 16px 18px 24px; display: flex; flex-direction: column; gap: 18px; margin-inline: auto; width: 100%; }

.pcf-app .zone-head {
	display: flex;
	align-items: baseline;
	gap: 10px;
	margin-bottom: 8px;
}

.pcf-app .zone-head h2 {
	margin: 0;
	font-size: 12px;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--faint);
}

.pcf-app .zone-head .n { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.pcf-app .zone-head .hint { margin-left: auto; font-size: 11.5px; color: var(--faint); }

.pcf-app .slots { display: grid; gap: 6px; }
.pcf-app .slots.main,
.pcf-app .slots.side,
.pcf-app .slots.extra { grid-template-columns: repeat(8, 1fr); }

/* one zone is on show at a time */
.pcf-app .zones[data-show] > .zone { display: none; }
.pcf-app .zones[data-show="main"] > .zone[data-zone="main"],
.pcf-app .zones[data-show="extra"] > .zone[data-zone="extra"],
.pcf-app .zones[data-show="side"] > .zone[data-zone="side"] { display: block; }

.pcf-app .zone-switch {
	flex: 0 0 auto;
	display: flex;
	gap: 6px;
	padding: 10px 18px 0;
	background: var(--bg);
}

.pcf-app .zone-switch button {
	flex: 1 1 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
	padding: 8px 10px;
	border: 1px solid var(--line);
	border-radius: 99px;
	background: var(--surface);
	color: var(--muted);
	font: inherit;
	font-size: 13px;
	cursor: pointer;
}

.pcf-app .zone-switch button .n { font-variant-numeric: tabular-nums; color: var(--faint); }
.pcf-app .zone-switch button[aria-pressed="true"] { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
.pcf-app .zone-switch button[aria-pressed="true"] .n { color: var(--on-accent); opacity: .75; }

/* the switch decides where a tapped card goes, so the old duplicate is gone */
.pcf-app .target { display: none; }

/* how many copies of this card the whole deck already holds */
.pcf-app .have-badge {
	position: absolute;
	top: 4px;
	right: 4px;
	min-width: 20px;
	height: 20px;
	padding: 0 5px;
	border-radius: 99px;
	display: grid;
	place-items: center;
	background: var(--accent);
	color: var(--on-accent);
	font-size: 11px;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	box-shadow: var(--shadow);
	pointer-events: none;
}

.pcf-app .slot {
	position: relative;
	aspect-ratio: 59 / 86;
	border-radius: 5px;
	background: var(--surface-2);
	border: 1px dashed var(--line);
	overflow: hidden;
}

.pcf-app .slot.filled { border: 0; background: none; cursor: pointer; }
.pcf-app .slot.filled img { width: 100%; height: 100%; object-fit: cover; border-radius: 5px; display: block; box-shadow: var(--shadow); transition: transform var(--fast) var(--ease); }
.pcf-app .slot.filled:hover img { transform: translateY(-2px); }
.pcf-app .slot.optional { border-style: dotted; opacity: .55; }
.pcf-app .slot.next { border-color: var(--accent); border-style: solid; display: grid; place-items: center; color: var(--faint); }
.pcf-app .slot.next::after { content: "+"; font-size: 18px; line-height: 1; }
.pcf-app .slot.drop { border-color: var(--accent); background: var(--surface-3); }

/* the card being read, outlined wherever it sits */
.pcf-app .slot.filled.active img { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Reordering: a bar down the edge the card would land on. The slot has
   overflow:hidden for its rounded corners, so the marker is drawn inside it
   rather than straddling the gap between two cards. */
.pcf-app .slot.filled.drop-before::after,
.pcf-app .slot.filled.drop-after::after {
	content: "";
	position: absolute;
	top: 0;
	bottom: 0;
	width: 3px;
	background: var(--accent);
	border-radius: 3px;
	z-index: 3;
	pointer-events: none;
}
.pcf-app .slot.filled.drop-before::after { left: 0; }
.pcf-app .slot.filled.drop-after::after { right: 0; }

/* the card being dragged fades, so the marker is what your eye follows */
.pcf-app .slot.filled.dragging { opacity: .4; }

/* The magnifier in the bottom-right corner of every card: the way to open a
   card in full now that the right button adds and removes.

   Dim until the card is hovered, so a grid of four hundred cards is still a
   grid of cards rather than a grid of buttons — but never invisible, because
   a control nobody can see is a control nobody uses. */
.pcf-app .info-badge {
	position: absolute;
	right: 3px;
	bottom: 3px;
	width: 20px;
	height: 20px;
	display: grid;
	place-items: center;
	border-radius: 99px;
	background: rgba(12, 12, 14, .74);
	color: #fff;
	cursor: pointer;
	opacity: .45;
	transition: opacity var(--fast) var(--ease), background var(--fast) var(--ease);
	z-index: 4;
}
.pcf-app .info-badge svg { width: 12px; height: 12px; display: block; }
.pcf-app .card-cell:hover .info-badge,
.pcf-app .slot.filled:hover .info-badge { opacity: 1; }
.pcf-app .info-badge:hover { background: var(--accent); color: var(--on-accent); opacity: 1; }

/* A phone keeps the scheme it had: a tap opens the card, the +/- badges add
   and remove, and there is no second mouse button to need a third affordance. */
@media (max-width: 760px) {
	.pcf-app .info-badge { display: none; }
}
.pcf-app .slot .dot { top: 3px; left: 3px; width: 15px; height: 15px; font-size: 9px; }
.pcf-app .slot .mark { top: 3px; right: 3px; width: 17px; height: 17px; }
.pcf-app .slot .mark .mk { width: 17px; height: 17px; }

.pcf-app .zones { max-width: 760px; }

.pcf-app .zone-sep { display: none; }

/* ---------- deck zones on a wide screen ----------
   Main and Side sit abreast, Fusion runs under both. The zones grid is thirteen
   columns wide (8 for Main + 5 for Side) with the same gap the slots use, so a
   card in Main and a card in Side come out exactly the same size, while the
   fifteen of the Fusion row spread over the full width and read smaller. */
@media (min-width: 761px) {
	.pcf-app .zones {
		display: grid;
		/* eight card columns, the separator, then three: every track is one card
		   wide, so a card in Main and one in Side come out the same size */
		grid-template-columns: repeat(8, 1fr) 26px repeat(3, 1fr);
		column-gap: 6px;
		row-gap: 18px;
		max-width: 1040px;
	}

	.pcf-app .zones[data-show] > .zone { display: block; }

	/* placed by hand: in the markup the Fusion deck comes before the Side, and
	   because it spans the full width auto-placement pushed the Side below it */
	.pcf-app .zone[data-zone="main"] { grid-column: 1 / span 8; grid-row: 1; }
	.pcf-app .zone[data-zone="side"] { grid-column: 10 / span 3; grid-row: 1; }
	.pcf-app .zone[data-zone="extra"] { grid-column: 1 / -1; grid-row: 2; }

	/* not a .zone, so it is left out of the placements above and would
	   otherwise auto-place into a single, narrow grid track */
	.pcf-app .deck-hint { grid-column: 1 / -1; grid-row: 3; }

	.pcf-app .zone-sep {
		display: block;
		grid-column: 9;
		grid-row: 1;
		justify-self: center;
		width: 1px;
		height: 100%;
		background: var(--line);
	}

	.pcf-app .slots.side { grid-template-columns: repeat(3, 1fr); }
	.pcf-app .slots.extra { grid-template-columns: repeat(15, 1fr); }

	/* THE CARD PANEL IS A FIXED FRAME.

	   Every card that lands here has a different name length, a different
	   amount of effect text, and monsters carry two rows that spells and traps
	   do not. Left to size themselves, each new card under the cursor moved
	   everything below it — the whole deck panel walking up and down the rail
	   as you swept across a search result.

	   So the frame is a fixed height, and the effect box inside it is a fixed
	   height pinned to the bottom of that frame: same size and same place for
	   every card in the game, with its own scrollbar when the text is long.
	   Whatever the card does not need becomes quiet space above the box, and
	   nothing below the frame ever moves. */
	/* `clip`, not `hidden`: an overflow:hidden box is still a scroll container,
	   so the wheel landed on it and went nowhere — which is why scrolling with
	   the pointer beside the card (rather than inside the effect box) could not
	   reach the deck panel underneath. `clip` is not a scroll container, so the
	   wheel passes straight through to .rail-l, which is. */
	.pcf-app .rail-l > .rail-read { flex: 0 0 auto; height: 468px; overflow: hidden; overflow: clip; }
	.pcf-app .rail-l .detail { height: 100%; padding: 13px 14px; gap: 8px; }
	.pcf-app .rail-l .detail .art { max-width: 108px; }

	/* two lines, always — a long name is clipped rather than allowed to push */
	.pcf-app .rail-l .detail h2 {
		flex: 0 0 auto;
		height: 2.5em;
		font-size: 15px;
		line-height: 1.25;
		overflow: hidden;
		display: -webkit-box;
		-webkit-line-clamp: 2;
		-webkit-box-orient: vertical;
	}

	.pcf-app .rail-l .detail .badges { flex: 0 0 auto; height: 22px; overflow: hidden; }
	.pcf-app .rail-l .detail .stat-line { flex: 0 0 auto; height: 17px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }

	/* ATK and DEF are printed on the card image right above, in the place
	   every player already looks for them */
	.pcf-app .rail-l .detail .stats { display: none; }

	/* the fixed section: same height and same place for every card, with its
	   own scrollbar when the effect text or the rulings run long */
	.pcf-app .rail-l .detail .detail-body {
		flex: 0 0 auto;
		margin-top: auto;
		height: 148px;
		overflow-y: auto;
		overscroll-behavior: contain;
		display: flex;
		flex-direction: column;
		gap: 8px;
		padding: 9px 10px;
		border: 1px solid var(--line);
		border-radius: var(--r-sm);
		background: var(--surface-2);
	}
	.pcf-app .rail-l .detail .detail-body > * { flex: 0 0 auto; }

	/* the deck panel underneath, sized by its own contents; the rail scrolls
	   as a last resort on a window too short for both */
	.pcf-app .rail-l { overflow-y: auto; }
	.pcf-app .rail-l > .tools { flex: 0 0 auto; padding: 12px 14px 16px; border-top: 1px solid var(--line); }
	.pcf-app #pcf-savedGroup .saved-list { max-height: clamp(76px, 16vh, 200px); }

	/* Four to a row in the deckbuilder's search, and small with it: at this
	   size a card is its artwork and little else, which is all it has to be —
	   the name, the text and the rest are one click away in the panel on the
	   left. Four small cards beat two big ones for finding anything. */
	.pcf-app .db .rail .card-grid {
		grid-template-columns: repeat(4, minmax(0, 1fr));
		gap: 10px 8px;
		padding: 14px 14px 24px;
	}
	.pcf-app .db .rail .card-cell .nm { font-size: 11px; }
}

.pcf-app .zone.over .zone-head .n { color: var(--forbidden); }

.pcf-app .deck-id {
	flex: 0 0 auto;
	padding: 12px 18px 0;
	background: var(--surface);
}

/* The + on a pool card and the - on a card already in the deck.

   Both are drawn rather than typed: a "+" or a "-" set in the page font sits
   wherever that font's metrics put it, which is never quite the middle of a
   circle, and it grows and shrinks with the font rather than with the card.
   Two bars built out of the box's own borders sit exactly in the centre at any
   size, so the badge can be scaled to the deck slot it covers — and it needed
   scaling: on a phone the old one ate a third of the card. */
.pcf-app .add-badge,
.pcf-app .remove-badge {
	position: absolute;
	display: none;
	place-items: center;
	border-radius: 99px;
	line-height: 0;
	font-size: 0;
}

.pcf-app .add-badge::before,
.pcf-app .remove-badge::before,
.pcf-app .add-badge::after {
	content: "";
	position: absolute;
	background: currentColor;
	border-radius: 1px;
}

/* the horizontal bar of both signs */
.pcf-app .add-badge::before,
.pcf-app .remove-badge::before {
	width: 46%;
	height: 1.6px;
}

/* and the upright that turns a minus into a plus */
.pcf-app .add-badge::after {
	width: 1.6px;
	height: 46%;
}

.pcf-app .add-badge {
	right: 5px;
	bottom: 26px;
	width: 22px;
	height: 22px;
	background: var(--accent);
	color: var(--on-accent);
	box-shadow: var(--shadow);
	pointer-events: none;
}

.pcf-app .card-cell { position: relative; }

/* the twin of .add-badge, on the cards already in the deck */
.pcf-app .remove-badge {
	right: 2px;
	bottom: 2px;
	width: 16px;
	height: 16px;
	padding: 0;
	border: 0;
	background: var(--forbidden);
	color: #fff;
	cursor: pointer;
	box-shadow: 0 1px 4px rgba(0, 0, 0, .5);
}

.pcf-app .remove-badge:active { transform: scale(.9); }

/* deck tools */

.pcf-app .tools { padding: 16px 16px 24px; display: flex; flex-direction: column; min-height: 0; }

/* One panel, not three stacks.

   Deck, My decks and Share are three steps of the same job — name it, keep it,
   pass it on — so they read as one card with three labelled sections and a
   hairline between them, rather than as three unrelated widgets floating in the
   rail. The box is what makes the grouping visible; the hairlines are what keep
   it from becoming a wall. */
.pcf-app .deck-box {
	display: flex;
	flex-direction: column;
	min-height: 0;
	border: 1px solid var(--line);
	/* between --r-sm and --r-lg on purpose: the pill radius is for controls and
	   the large one is for full-width surfaces, and this is neither */
	border-radius: 14px;
	background: var(--surface-2);
	overflow: hidden;
}

.pcf-app .deck-box > .tool-group,
.pcf-app .deck-box > .tools-fold > .tool-group { padding: 13px 14px; }

/* Every section but the first is separated from the one above it. Written as a
   top border on the follower rather than a bottom border on the leader, so the
   last section never leaves a hairline hanging above the panel's own edge. */
.pcf-app .deck-box > .tool-group + .tool-group,
.pcf-app .deck-box > .tools-fold,
.pcf-app .deck-box > .tools-fold > .tool-group + .tool-group { border-top: 1px solid var(--line); }

.pcf-app .deck-box .tools-fold { min-height: 0; }

.pcf-app .tool-group { display: flex; flex-direction: column; gap: 8px; }

.pcf-app .tool-group h3 {
	margin: 0;
	font-size: 10.5px;
	font-weight: 700;
	letter-spacing: .11em;
	text-transform: uppercase;
	color: var(--faint);
}

.pcf-app .tool-row { display: flex; gap: 8px; }
.pcf-app .tools-fold { display: flex; flex-direction: column; flex: 0 0 auto; }
.pcf-app .tools-fold > summary { display: none; }

.pcf-app .deck-bar { display: flex; gap: 8px; }
.pcf-app .deck-bar .btn { flex: 1 1 0; }
.pcf-app .tool-row .btn { flex: 1 1 0; min-width: 0; }

.pcf-app .deck-name {
	width: 100%;
	padding: 9px 12px;
	border: 1px solid var(--line);
	border-radius: var(--r-sm);
	background: var(--bg);
	font-weight: 600;
}

.pcf-app .saved-list { display: flex; flex-direction: column; gap: 5px; min-height: 0; max-height: 232px; overflow-y: auto; }

/* the empty state, and the "log in to keep these" line that replaces it */
.pcf-app .saved-list .none { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--faint); }
.pcf-app .saved-list .none a { color: var(--text); }

/* Name over count, with the delete button beside both, rather than all three
   on one line. In a column this narrow a single row left the name about five
   characters of room before the ellipsis — and the name is the whole point of
   the row, while the count is a detail you glance at second. */
.pcf-app .saved {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	align-items: center;
	column-gap: 8px;
	padding: 6px 9px;
	border-radius: var(--r-sm);
	border: 1px solid var(--line);
	background: var(--surface);
	cursor: pointer;
	transition: border-color var(--fast) var(--ease);
}

.pcf-app .saved:hover { border-color: var(--faint); }
.pcf-app .saved.current { border-color: var(--accent); }
/* One line, always: name and star together, the delete button beside them.
   The card counts used to sit on a second line under the name and made every
   row twice as tall for something nobody was reading. */
.pcf-app .saved .t { grid-column: 1; min-width: 0; display: flex; align-items: center; gap: 6px; font-size: 13px; }
.pcf-app .saved .t-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pcf-app .saved .x { grid-column: 2; }

/* pin ("open this deck automatically next time") — a small star on the name
   line: a mark on the deck rather than one of the row's actions. Off it is a
   readable outline rather than the near-invisible hairline it was, so it can
   be found before it has ever been used. */
.pcf-app .saved .star {
	flex: 0 0 auto;
	display: inline-grid;
	place-items: center;
	width: 18px;
	height: 18px;
	padding: 0;
	border: 0;
	background: none;
	font-size: 12px;
	line-height: 1;
	color: var(--faint);
	opacity: .6;
	cursor: pointer;
	transition: color var(--fast) var(--ease), opacity var(--fast) var(--ease);
}
.pcf-app .saved .star:hover { color: var(--text); opacity: 1; }
.pcf-app .saved .star.on,
.pcf-app .saved .star.on:hover { color: var(--gold); opacity: 1; }
/* An inline <svg> with no width/height of its own collapses to nothing inside
   a flex row — which is what this button was: a 4x9px sliver with an invisible
   icon in it, so the way to delete a saved deck was there and could not be
   seen or hit. Both the button and its icon are sized explicitly now, and the
   target is a proper 26px. */
.pcf-app .saved .x {
	flex: 0 0 auto;
	display: grid;
	place-items: center;
	width: 26px;
	height: 26px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: none;
	color: var(--faint);
	cursor: pointer;
	transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
}

.pcf-app .saved .x svg { width: 13px; height: 13px; display: block; }
.pcf-app .saved .x:hover { color: var(--forbidden); background: var(--surface-2); }

.pcf-app .mini-preview { display: flex; flex-direction: column; gap: 10px; }

.pcf-app .toast {
	position: fixed;
	left: 50%;
	bottom: 26px;
	transform: translate(-50%, 14px);
	background: var(--accent);
	color: var(--on-accent);
	padding: 10px 18px;
	border-radius: 99px;
	font-size: 13px;
	box-shadow: var(--shadow-lg);
	opacity: 0;
	pointer-events: none;
	transition: opacity var(--fast) var(--ease), transform var(--fast) var(--ease);
	z-index: 90;
}

.pcf-app .toast.show { opacity: 1; transform: translate(-50%, 0); }

/* ---------- banlist ---------- */

.pcf-app .bl-wrap { flex: 1 1 auto; min-height: 0; overflow-y: auto; }

.pcf-app .bl-inner { max-width: 1440px; margin: 0 auto; padding: 22px 24px 40px; }

.pcf-app .bl-top { display: flex; align-items: flex-end; gap: 20px; flex-wrap: wrap; margin-bottom: 18px; }

.pcf-app .bl-top h1 { margin: 0; font-size: 26px; letter-spacing: -.02em; }
.pcf-app .bl-top p { margin: 4px 0 0; color: var(--muted); font-size: 13px; }

.pcf-app .seg { display: flex; gap: 4px; padding: 4px; border-radius: 99px; background: var(--surface-2); border: 1px solid var(--line); margin-left: auto; }

.pcf-app .seg button {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 7px 14px;
	border: 0;
	border-radius: 99px;
	background: none;
	cursor: pointer;
	color: var(--muted);
	transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
}

.pcf-app .seg button:hover { color: var(--text); }
.pcf-app .seg button[aria-pressed="true"] { background: var(--accent); color: var(--on-accent); }
.pcf-app .seg .fmt-icon { width: 18px; height: 18px; }

.pcf-app .bl-section { margin-bottom: 18px; }

.pcf-app .bl-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }

.pcf-app .bl-head .swatch { width: 10px; height: 10px; border-radius: 50%; }
.pcf-app .bl-head.f .swatch { background: var(--forbidden); }
.pcf-app .bl-head.p .swatch { background: var(--perfect); }
.pcf-app .bl-head.l .swatch { background: var(--limited); }
.pcf-app .bl-head.s .swatch { background: var(--semi); }

.pcf-app .bl-head h2 { margin: 0; font-size: 13px; letter-spacing: .1em; text-transform: uppercase; }
.pcf-app .bl-head .n { font-size: 12px; color: var(--faint); font-variant-numeric: tabular-nums; }
.pcf-app .bl-head .rule { flex: 1 1 auto; height: 1px; background: var(--line); }

.pcf-app .bl-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(60px, 1fr)); gap: 10px 7px; }

/* ten to a row on a wide screen: bigger cards read more easily than the
   auto-fill count a 1440px-wide grid would otherwise pack in */
@media (min-width: 761px) {
	.pcf-app .bl-grid { grid-template-columns: repeat(10, 1fr); gap: 14px 10px; }
}

.pcf-app .bl-card {
	display: flex;
	flex-direction: column;
	gap: 5px;
	text-decoration: none;
	padding: 0;
	border: 0;
	background: none;
	font: inherit;
	text-align: left;
	cursor: pointer;
}
.pcf-app .bl-card .thumb { box-shadow: none; border: 1px solid var(--line); }
.pcf-app .bl-card:hover .thumb { transform: translateY(-3px); box-shadow: var(--shadow); }
.pcf-app .bl-card .nm { font-size: 9.5px; line-height: 1.25; color: var(--muted); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

/* ---------- tournaments ---------- */

.pcf-app .ev-wrap { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
/* Three row cards at full size need 3 x --ev-row-w plus two gaps (1579px)
   before padding. Narrower than that the columns shrink together — they stay
   matched, the cards just get smaller. */
.pcf-app .ev-inner { max-width: 1640px; margin: 0 auto; padding: 22px 24px 44px; }

.pcf-app .ev-crumb { display: inline-block; margin-bottom: 10px; font-size: 12.5px; color: var(--muted); text-decoration: none; }
.pcf-app .ev-crumb:hover { color: var(--text); }

.pcf-app .ev-section { margin-top: 26px; }
.pcf-app .ev-section:first-of-type { margin-top: 18px; }

/* one row per decklist played */

.pcf-app .ev-rows { display: flex; flex-direction: column; gap: 8px; }

/* Three decklists per row from desktop width up — each .ev-row is a self
   contained card, so laying them out as grid items just needs a column count.
   `align-items: start` keeps a 40-card list from being stretched to the height
   of the 60-card list beside it. */
@media (min-width: 900px) {
	.pcf-app .ev-rows {
		display: grid;
		/* the columns are the card's own width, not a third of the screen
		   each: packed to the left, they sit side by side instead of drifting
		   apart on a wide monitor — and they still shrink together when the
		   space is tighter, so the three never stop matching.

		   P.alignDeckRows counts these tracks at runtime rather than assuming
		   a number, so changing the count here is the only edit needed. */
		grid-template-columns: repeat(3, minmax(0, var(--ev-row-w)));
		justify-content: start;
		gap: 14px;
		/* stretch, not start: the cards on one line end at the same line even
		   when one holds 41 main cards and the others 40 — the odd card that
		   opens a fifth row used to make the line look broken. The slack goes
		   between the main grid and the side strip (see .ev-deck), so the side
		   decks line up across the whole line. */
		align-items: stretch;
	}
}

/* Every card is exactly as wide as the deck grid inside it needs to be, and no
   wider — so two cards side by side always match, whatever they hold: forty
   cards or sixty, a grid or a photographed sheet. Left as a free-flowing 1fr
   they were as wide as the screen allowed and the ten-across grid stretched
   with them, which is what made two neighbours read as different sizes. */
.pcf-app .ev-row { max-width: var(--ev-row-w); }

.pcf-app .ev-row {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr) auto;
	/* the deck row takes whatever height the card was stretched to */
	grid-template-rows: auto minmax(0, 1fr);
	grid-template-areas:
		"place main acts"
		"deck  deck deck";
	align-items: center;
	gap: 12px 14px;
	padding: 12px 14px;
	border: 1px solid var(--line);
	border-radius: var(--r);
	background: var(--surface);
}

.pcf-app .ev-place { grid-area: place; }
.pcf-app .ev-row-main { grid-area: main; }
.pcf-app .ev-row-acts { grid-area: acts; }

/* a decklist that reached the archive as a photograph of the sheet: shown at
   the width of the row it belongs to, and linking to itself at full size */
.pcf-app .ev-sheet {
	display: block;
	width: 100%;
	border: 1px solid var(--line);
	border-radius: var(--r-sm);
	overflow: hidden;
	background: var(--surface-2);
}

.pcf-app .ev-sheet img { display: block; width: 100%; height: auto; }

.pcf-app .ev-deck { grid-area: deck; }

.pcf-app .ev-place {
	flex: 0 0 auto;
	min-width: 44px;
	padding: 5px 9px;
	border-radius: 99px;
	background: var(--surface-2);
	border: 1px solid var(--line);
	text-align: center;
	font-size: 12px;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	color: var(--muted);
}

.pcf-app .ev-place.top { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }

.pcf-app .ev-row-main { min-width: 0; }
.pcf-app .ev-row-main h3 { margin: 0; font-size: 15px; letter-spacing: -.01em; }
.pcf-app .ev-who { margin: 2px 0 0; font-size: 13px; color: var(--muted); }
.pcf-app .ev-sub { margin: 2px 0 0; font-size: 12px; color: var(--faint); }

.pcf-app .ev-row-acts { display: flex; gap: 6px; }

/* the deck itself: main deck grid, then the full side deck as one row of 15
   underneath it — never side-by-side, so the side deck's smaller cards read
   as a distinct strip rather than a second column fighting main for space */
.pcf-app .ev-deck {
	display: grid;
	grid-template-columns: 1fr;
	grid-auto-rows: max-content;
	/* main at the top, side pinned to the bottom: whatever height this card was
	   stretched to lands in the gap between them rather than under the last row
	   of cards, which is what keeps the two side decks on one line */
	align-content: space-between;
	gap: 10px;
	padding-top: 11px;
	border-top: 1px solid var(--line);
	width: min(100%, var(--ev-deck-w));
}

.pcf-app .ev-deck-zone { min-width: 0; }

.pcf-app .ev-deck-label {
	display: block;
	margin-bottom: 5px;
	font-size: 10px;
	letter-spacing: .09em;
	text-transform: uppercase;
	color: var(--faint);
}

/* Fixed columns, the way a decklist is actually laid out: ten across for the
   main deck, which lands on four rows at forty cards and six at sixty, and the
   side deck in one row of fifteen underneath.

   The card size is capped rather than fractional: at `1fr` a card grew with
   whatever width the row happened to get, so the same deck looked different
   next to different neighbours. Capped, the strip has one true width
   (--ev-deck-w) everywhere, and still shrinks on a narrow screen. */
/* align-content: start is what makes row 4 of a 40-card deck sit level with
   row 4 of the 41-card deck beside it.

   P.alignDeckRows gives the shorter .ev-mini.main the min-height of the
   tallest on its line. A grid's align-content defaults to `stretch`, so that
   extra height was being shared out between the auto-sized rows: the shorter
   deck's four rows spread apart to fill five rows' worth of space, and the
   two lists drifted further out of step with every row down. Pinned to the
   start, the rows keep their true height and the slack collects at the bottom
   as empty space — which is what a decklist should look like. */
.pcf-app .ev-mini { display: grid; gap: 3px; align-content: start; }
.pcf-app .ev-mini.main { grid-template-columns: repeat(10, minmax(0, var(--ev-card))); }
.pcf-app .ev-mini.side { grid-template-columns: repeat(15, minmax(0, 1fr)); max-width: none; }

.pcf-app .ev-mini img {
	display: block;
	width: 100%;
	height: auto;
	/* the real proportions of a card: the row has its final height before the
	   image has loaded, which is what lets the two cards be measured against
	   each other as soon as they are drawn */
	aspect-ratio: 421 / 614;
	border-radius: 3px;
	box-shadow: 0 1px 2px rgba(0, 0, 0, .18);
}

.pcf-app .btn.ghost { background: transparent; }

/* the tournament cards */

.pcf-app .ev-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 12px; }

.pcf-app .ev-card {
	display: flex;
	flex-direction: column;
	gap: 12px;
	padding: 16px;
	border: 1px solid var(--line);
	border-radius: var(--r);
	background: var(--surface);
}

.pcf-app .ev-card-head { display: flex; align-items: flex-start; gap: 10px; }
.pcf-app .ev-card-head h3 { margin: 0; font-size: 16px; letter-spacing: -.01em; }
.pcf-app .ev-count { margin-left: auto; flex: 0 0 auto; font-size: 12px; color: var(--faint); font-variant-numeric: tabular-nums; }
.pcf-app .ev-card-foot { display: flex; align-items: center; gap: 10px; margin-top: auto; }
.pcf-app .ev-card-foot .btn { margin-left: auto; }

/* how much of the room each deck was */

.pcf-app .ev-bars { display: flex; flex-direction: column; gap: 7px; }

.pcf-app .ev-bar {
	display: grid;
	grid-template-columns: minmax(90px, 150px) 1fr auto;
	align-items: center;
	gap: 10px;
	text-decoration: none;
	color: inherit;
}

.pcf-app .ev-bar-name { font-size: 12.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.pcf-app .ev-bar-track {
	height: 8px;
	border-radius: 99px;
	background: var(--surface-2);
	overflow: hidden;
}

.pcf-app .ev-bar-track i { display: block; height: 100%; background: var(--accent); border-radius: 99px; }
.pcf-app .ev-bar-n { font-size: 12px; color: var(--faint); font-variant-numeric: tabular-nums; white-space: nowrap; }

.pcf-app .ev-bars.wide .ev-bar { grid-template-columns: minmax(120px, 220px) 1fr auto; }
.pcf-app a.ev-bar:hover .ev-bar-name { color: var(--text); }

/* representation as a ring: the chart carries the shape of the field at a
   glance, the legend beside it carries the reading (four of the six hues sit
   under 3:1 on the light surface, so the names and numbers are not optional) */

.pcf-app .ev-pie-wrap {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 18px 28px;
}

.pcf-app .ev-pie { width: 180px; height: 180px; flex: 0 0 auto; }

.pcf-app .ev-pie-slice {
	stroke-linecap: butt;
	transition: opacity var(--fast) var(--ease);
}

/* hovering either the ring or a legend row dims everything else — with six
   slices, matching a name to an arc by colour alone is a puzzle */
.pcf-app .ev-pie-wrap.is-hovering .ev-pie-slice { opacity: .3; }
.pcf-app .ev-pie-wrap.is-hovering .ev-pie-slice.is-on { opacity: 1; }

.pcf-app .ev-pie-total {
	fill: var(--text);
	font-size: 26px;
	font-weight: 650;
	font-variant-numeric: tabular-nums;
}

.pcf-app .ev-pie-cap {
	fill: var(--faint);
	font-size: 10px;
	letter-spacing: .09em;
	text-transform: uppercase;
}

.pcf-app .ev-legend {
	flex: 1 1 240px;
	min-width: 0;
	margin: 0;
	padding: 0;
	list-style: none;
	display: grid;
	gap: 2px;
}

.pcf-app .ev-legend-row {
	display: grid;
	grid-template-columns: 10px minmax(0, 1fr) auto;
	align-items: center;
	gap: 10px;
	padding: 4px 8px;
	border-radius: var(--r-sm);
	font-size: 13px;
	transition: background var(--fast) var(--ease);
}

.pcf-app .ev-pie-wrap.is-hovering .ev-legend-row { opacity: .5; }
.pcf-app .ev-pie-wrap.is-hovering .ev-legend-row.is-on { opacity: 1; background: var(--surface-2); }

.pcf-app .ev-legend-dot { width: 10px; height: 10px; border-radius: 3px; }

.pcf-app .ev-legend-name {
	color: var(--muted);
	text-decoration: none;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.pcf-app a.ev-legend-name:hover { color: var(--text); text-decoration: underline; }
.pcf-app .ev-legend-n { color: var(--faint); font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* the banner over a list opened from the archive */

.pcf-app .review-bar {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	gap: 10px;
	flex-wrap: wrap;
	padding: 10px 18px;
	background: var(--surface-2);
	border-bottom: 1px solid var(--line);
	font-size: 13px;
}

.pcf-app .review-bar span { color: var(--muted); }
.pcf-app .review-bar .btn { margin-left: auto; }
.pcf-app .review-bar .btn + .btn { margin-left: 0; }

/* ---------- legend, target switch, view tabs ---------- */

.pcf-app .legend {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	padding: 5px 11px 5px 8px;
	border: 1px solid var(--line);
	border-radius: 99px;
	font-size: 12px;
	color: var(--muted);
	background: var(--surface);
}

.pcf-app .legend .chip-mark {
	width: 18px;
	height: 18px;
	border-radius: 50%;
	display: grid;
	place-items: center;
	background: var(--perfect);
	color: #fff;
	flex: 0 0 auto;
}

.pcf-app .legend .chip-mark .mk { width: 22px; height: 22px; }

.pcf-app .target {
	display: flex;
	gap: 3px;
	padding: 3px;
	border-radius: 99px;
	background: var(--surface-2);
	border: 1px solid var(--line);
	flex: 0 0 auto;
}

.pcf-app .target button {
	border: 0;
	background: none;
	border-radius: 99px;
	padding: 6px 13px;
	cursor: pointer;
	color: var(--muted);
	font-size: 12.5px;
	transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
}

.pcf-app .target button[aria-pressed="true"] { background: var(--accent); color: var(--on-accent); }

.pcf-app .zone.target-zone .zone-head h2 { color: var(--text); }
.pcf-app .zone.target-zone .slots { outline: 1px dashed var(--line); outline-offset: 7px; border-radius: 4px; }

.pcf-app .deck-hint {
	margin: 4px 0 0;
	padding-top: 12px;
	border-top: 1px solid var(--line);
	font-size: 11.5px;
	color: var(--faint);
	text-align: center;
}
.pcf-app .deck-hint b { font-weight: 600; color: var(--muted); }
.pcf-app .deck-hint span { opacity: .5; margin: 0 2px; }

.pcf-app .tabs { display: none; }

/* ---------- modal (the player asked for before an image export) ---------- */

.pcf-app .modal-backdrop {
	position: fixed;
	inset: 0;
	background: rgba(0, 0, 0, .42);
	z-index: 80;
}

.pcf-app .modal {
	position: fixed;
	z-index: 81;
	left: 50%;
	top: 50%;
	transform: translate(-50%, -50%);
	width: min(400px, calc(100vw - 32px));
	max-height: calc(100vh - 32px);
	overflow-y: auto;
	display: flex;
	flex-direction: column;
	gap: 14px;
	padding: 20px;
	background: var(--surface);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	box-shadow: var(--shadow-lg);
}

.pcf-app .modal h2 { margin: 0; font-size: 17px; letter-spacing: -.01em; }

.pcf-app .modal-body { display: flex; flex-direction: column; gap: 14px; }

.pcf-app .modal-img {
	display: block;
	width: 100%;
	height: auto;
	border-radius: var(--r-sm);
	border: 1px solid var(--line);
}

.pcf-app .modal-note { margin: 0; font-size: 13px; line-height: 1.45; color: var(--muted); }

.pcf-app .modal-field { display: flex; flex-direction: column; gap: 6px; }

.pcf-app .modal-field span {
	font-size: 11px;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--faint);
}

.pcf-app .modal-field input { font-size: 16px; }

.pcf-app .modal-error {
	margin: 0;
	padding: 9px 12px;
	border-radius: var(--r-sm);
	background: var(--surface-2);
	border: 1px solid var(--forbidden);
	color: var(--forbidden);
	font-size: 13px;
	line-height: 1.4;
}

.pcf-app .modal-switch { margin: 0; font-size: 12.5px; color: var(--muted); }
.pcf-app .modal-switch a { color: var(--text); }

.pcf-app .modal-actions { display: flex; gap: 8px; margin-top: 2px; }
.pcf-app .modal-actions .btn { flex: 1 1 0; }
.pcf-app .modal-actions .btn.primary { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }

/* ---------- bottom sheet ---------- */

.pcf-app .sheet-backdrop {
	position: fixed;
	inset: 0;
	background: rgba(0, 0, 0, .42);
	opacity: 0;
	pointer-events: none;
	transition: opacity var(--fast) var(--ease);
	z-index: 60;
}

.pcf-app .sheet-backdrop.open { opacity: 1; pointer-events: auto; }

.pcf-app .sheet {
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	max-height: 88vh;
	display: flex;
	flex-direction: column;
	background: var(--surface);
	border-radius: var(--r-lg) var(--r-lg) 0 0;
	box-shadow: var(--shadow-lg);
	transform: translateY(101%);
	transition: transform 280ms var(--ease);
	z-index: 70;
}

.pcf-app .sheet.open { transform: translateY(0); }

.pcf-app .sheet-bar {
	position: relative;
	flex: 0 0 auto;
	height: 40px;
	display: grid;
	place-items: center;
	touch-action: none;
}

.pcf-app .sheet-bar .grip { width: 44px; height: 4px; border-radius: 99px; background: var(--line); }
.pcf-app .sheet-close { position: absolute; right: 10px; top: 4px; }

.pcf-app .sheet-actions {
	flex: 0 0 auto;
	display: flex;
	gap: 8px;
	padding: 0 16px 12px;
}

.pcf-app .sheet-actions .btn { flex: 1 1 0; }

.pcf-app .sheet-body {
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;
	padding-top: 4px;
	padding-bottom: calc(20px + env(safe-area-inset-bottom));
}

.pcf-app .sheet-body .art { max-width: 190px; }

.pcf-app.sheet-open { overflow: hidden; }

/* ---------- tablet ---------- */

/* The search column holds four cards to a row and will not give that up, so
   on a laptop the give has to come from somewhere: both flanking columns step
   down a size, and the deck keeps its grid readable. */
@media (max-width: 1440px) {
	.db { grid-template-columns: 292px minmax(0, 1fr) 330px; }
	.rail-l > .rail-read { height: 444px; }
	.rail-l .detail .art { max-width: 98px; }
	.rail-l .detail .detail-body { height: 138px; }
	.db .rail .card-grid { gap: 9px 7px; padding: 12px 12px 22px; }
}

@media (max-width: 1100px) {
	.pcf-app { overflow: auto; }
	.pcf-app main { display: block; }
	.pcf-app .db { display: block; }
	.pcf-app .pane,
.pcf-app .scroll { overflow: visible; height: auto; }
	.pcf-app .rail,
.pcf-app .rail-l { border: 0; border-top: 1px solid var(--line); }
	.pcf-app .pane-head { position: sticky; top: 0; z-index: 20; }
	.pcf-app .counters { position: sticky; top: 0; z-index: 20; }
	.pcf-app .zones { width: auto !important; }
	.pcf-app .slots.side,
.pcf-app .slots.extra { grid-template-columns: repeat(10, 1fr); }
	.pcf-app .detail .art { max-width: 210px; }
	.pcf-app .nav a { padding: 7px 11px; }
	.pcf-app .card-grid { --tile: 104px; }
}

/* ---------- phone ---------- */

@media (max-width: 760px) {
	.pcf-app { --head-h: 54px; }

	/* the desktop layout pins the page to the viewport and lets the panes share
	   what is left. On a phone the panes are stacked, so the page has to grow
	   instead: without this they get shrunk to nothing and overlap. */
	.pcf-app,
.pcf-app { height: auto; }
	.pcf-app { overflow: auto; display: block; }
	.pcf-app main { height: auto; min-height: 0; }

	.pcf-app .site-head { gap: 6px; padding: 0 10px; flex-wrap: nowrap; position: relative; }
	.pcf-app .brand small,
.pcf-app .brand span:not(.mark) { display: none; }
	.pcf-app .brand { flex: 0 0 auto; }
	.pcf-app .brand .mark { width: 40px; height: 40px; }

	/* .nav and .head-right stop sitting in the bar and move into the dropdown
	   .menu-panel opens below it instead — see the ".menu-panel" rules for the
	   panel itself; here they only need the column layout a dropdown wants
	   instead of the horizontal one the desktop bar wants. */
	/* last in the bar now, with .head-right carrying the auto margin before it */
	.pcf-app .menu-toggle { display: block; width: 36px; height: 36px; flex: 0 0 auto; }

	/* Tapping anywhere off the menu closes it, and the page behind dims while
	   it is open. Both come from one pseudo-element on the button itself:
	   a click on it is a click on the button, which is already the toggle, so
	   the sheet needs no extra element and no extra script to feel like a real
	   dropdown rather than a box that appeared. */
	.pcf-app .menu-toggle[aria-expanded="true"]::after {
		content: "";
		position: fixed;
		inset: 0;
		z-index: -1;
		background: rgba(0, 0, 0, .34);
		backdrop-filter: blur(1.5px);
		-webkit-backdrop-filter: blur(1.5px);
	}

	.pcf-app .menu-panel {
		display: flex;
		flex-direction: column;
		position: absolute;
		top: 100%;
		left: 8px;
		right: 8px;
		z-index: 5;
		margin-top: 10px;
		padding: 8px;
		border-radius: 18px;
		border: 1px solid var(--line);
		/* a solid surface everywhere, glassy where the browser can do it —
		   color-mix()+backdrop-filter are simply ignored where they cannot */
		background: var(--surface);
		background: color-mix(in srgb, var(--surface) 90%, transparent);
		backdrop-filter: blur(16px) saturate(1.5);
		-webkit-backdrop-filter: blur(16px) saturate(1.5);
		box-shadow: 0 18px 44px -12px rgba(0, 0, 0, .45), 0 2px 8px rgba(0, 0, 0, .12);
		opacity: 0;
		visibility: hidden;
		transform: translateY(-6px) scale(.97);
		transform-origin: top right;
		pointer-events: none;
		/* light and quick: under 200ms door to door, matching how fast a tap
		   already feels rather than making the panel the slow part of it */
		transition: opacity 120ms ease, transform 160ms cubic-bezier(.22, 1, .36, 1), visibility 160ms;
	}

	.pcf-app .menu-panel.open {
		opacity: 1;
		visibility: visible;
		transform: translateY(0) scale(1);
		pointer-events: auto;
	}

	/* the rows cascade in rather than arriving all at once — still done inside
	   the panel's own 160ms, just staggered a few milliseconds apart, which is
	   what actually reads as "the menu opened" rather than "a box appeared" */
	.pcf-app .menu-panel .nav a {
		opacity: 0;
		transform: translateY(-4px);
	}
	.pcf-app .menu-panel.open .nav a {
		animation: pcf-menu-item-in 150ms ease forwards;
	}
	.pcf-app .menu-panel.open .nav a:nth-child(1) { animation-delay: 15ms; }
	.pcf-app .menu-panel.open .nav a:nth-child(2) { animation-delay: 35ms; }
	.pcf-app .menu-panel.open .nav a:nth-child(3) { animation-delay: 55ms; }
	.pcf-app .menu-panel.open .nav a:nth-child(4) { animation-delay: 75ms; }

	@keyframes pcf-menu-item-in {
		to { opacity: 1; transform: translateY(0); }
	}

	/* a reader who asked the OS for fewer motion effects gets the fade only —
	   still light and quick, no cascade or movement */
	@media (prefers-reduced-motion: reduce) {
		.pcf-app .menu-panel { transition-duration: 90ms; transform: none !important; }
		.pcf-app .menu-panel .nav a { animation: none; opacity: 1; transform: none; }
	}

	/* Full-width rows with a real 46px target, the current page filled in
	   rather than merely tinted, and a chevron so a row reads as somewhere to
	   go instead of as a label. */
	.pcf-app .menu-panel .nav { flex-direction: column; align-items: stretch; gap: 2px; margin-left: 0; }

	.pcf-app .menu-panel .nav a {
		display: flex;
		align-items: center;
		min-height: 46px;
		padding: 0 14px;
		border-radius: 12px;
		font-size: 15px;
		font-weight: 500;
		white-space: normal;
	}

	.pcf-app .menu-panel .nav a::after {
		content: "";
		width: 7px;
		height: 7px;
		margin-left: auto;
		border-right: 1.6px solid currentColor;
		border-bottom: 1.6px solid currentColor;
		transform: rotate(-45deg);
		opacity: .35;
	}

	.pcf-app .menu-panel .nav a[aria-current="page"] { font-weight: 600; }
	.pcf-app .menu-panel .nav a[aria-current="page"]::after { opacity: .6; }

	/* The format toggle, the bell, the account and the theme switch stay in the
	   bar rather than folding into the dropdown: they are what you reach for
	   while reading a page, and a tap to open a menu before every one of them
	   was the whole reason the phone header felt awkward. Only the four page
	   links live behind the hamburger now. */
	.pcf-app .head-right { margin-left: auto; gap: 5px; flex: 0 1 auto; min-width: 0; }

	/* the one thing in there that is only ever a label. The toggle beside it
	   already says which format is on, and the date is on the banlist page
	   itself — dropping it is what buys the rest the room to breathe. */
	.pcf-app .head-right .fmt-chip { display: none; }

	.pcf-app .head-right .fmt-toggle { padding: 2px; }
	.pcf-app .head-right .fmt-toggle button { padding: 5px 9px; font-size: 12px; }
	.pcf-app .head-right .icon-btn { width: 32px; height: 32px; }
	.pcf-app .head-right .account-btn { padding: 2px; }

	.pcf-app main { display: block; }

	/* iOS zooms the page when a focused field is under 16px: keep them at 16 */
	.pcf-app input[type="text"],
.pcf-app input[type="number"],
.pcf-app select,
.pcf-app .deck-name { font-size: 16px; }

	/* search stays put, results scroll with the page.
	   The head is capped and scrolls on its own so the advanced panel can never
	   grow past the viewport and push its own close button out of reach. */
	.pcf-app .pane-head {
		position: sticky;
		top: 0;
		z-index: 25;
		padding: 10px 12px;
		max-height: 78vh;
		overflow-y: auto;
		overscroll-behavior: contain;
	}
	.pcf-app .search-row {
		gap: 6px;
		position: sticky;
		top: 0;
		z-index: 3;
		background: var(--surface);
	}
	.pcf-app .search-field input { padding: 10px 12px 10px 34px; }
	.pcf-app .btn { padding: 10px 13px; }
	.pcf-app .adv { grid-template-columns: 1fr 1fr !important; gap: 9px; }
	.pcf-app .result-meta { margin-top: 8px; }

	.pcf-app .card-grid { --tile: 98px; gap: 12px 8px; padding: 12px; }
	.pcf-app .card-cell .nm { font-size: 11px; }

	/* the reading panel becomes the bottom sheet */
	.pcf-app main:not(.db) > .rail:last-child { display: none; }

	/* ---- deckbuilder: everything on one screen ---- */

	.pcf-app .tabs { display: none; }

	.pcf-app .db { display: flex; flex-direction: column; padding-bottom: 74px; }
	.pcf-app .db > .pane { display: flex; flex: 0 0 auto; min-height: 0; }
	.pcf-app .db > .deck-pane { order: 1; }
	.pcf-app .db > .rail-l { order: 2; }
	.pcf-app .db > .rail { order: 3; }
	.pcf-app .db .rail,
.pcf-app .db .rail-l { border-top: 1px solid var(--line); }

	/* the card being read has its own bottom sheet on a phone (tap a card,
	   P.openSheet() opens it), so the rail keeps only the deck panel here */
	.pcf-app .db .rail-l > .rail-read { display: none; }

	/* name first, then the counters, then the deck itself: building a deck
	   stays inside the first screen */
	.pcf-app .deck-id { position: sticky; top: 0; z-index: 27; padding: 8px 12px 0; }
	.pcf-app .deck-name { font-size: 16px; }

	.pcf-app .db .deck-pane .scroll { overflow: visible; }
	.pcf-app .counters { position: sticky; top: 46px; z-index: 26; padding: 8px 12px; gap: 6px; }
	.pcf-app .count-pill { padding: 5px 10px; }
	.pcf-app .ratio { flex-basis: 100%; order: 9; }

	/* no right button and no hover to explain */
	.pcf-app .deck-hint { display: none; }

	/* one zone at a time, eight to a row: the whole grid fits the screen */
	.pcf-app .zone-switch { padding: 10px 12px 0; }
	.pcf-app .zone-switch button { padding: 8px 6px; font-size: 12.5px; }

	.pcf-app .zones { padding: 10px 12px 12px; gap: 12px; max-width: none; }
	.pcf-app .zone-head { margin-bottom: 6px; }
	.pcf-app .slots { gap: 4px; }

	/* the side is fifteen cards: five across reads as the three rows it is,
	   and since only one zone shows at a time the cards can afford the room */
	.pcf-app .slots.side { grid-template-columns: repeat(5, 1fr); }
	.pcf-app .slot .dot { top: 2px; left: 2px; width: 13px; height: 13px; font-size: 8px; }

	.pcf-app .db .rail .scroll { overflow: visible; }

	/* tapping a pool card adds it, tapping the minus takes it back out: iOS has
	   no drag and drop, and the tap on the card itself opens the card to read */
	.pcf-app .add-badge { display: grid; }
	.pcf-app .remove-badge { display: grid; }

	/* the side deck has fewer columns, so its cards can carry a bigger target */
	.pcf-app .slots.side .remove-badge { width: 21px; height: 21px; right: 3px; bottom: 3px; }

	.pcf-app #pcf-deckActions h3 { display: none; }
	.pcf-app #pcf-deckActions { gap: 0; }

	.pcf-app .tools-fold > summary {
		display: block;
		list-style: none;
		padding: 10px 13px;
		border: 1px solid var(--line);
		border-radius: 99px;
		background: var(--surface);
		color: var(--muted);
		font-size: 13px;
		text-align: center;
		cursor: pointer;
	}
	.pcf-app .tools-fold > summary::-webkit-details-marker { display: none; }

	/* On a phone the panel is not a panel: the deck's own buttons have left it
	   for the fixed bar at the bottom of the screen, and what remains is a
	   fold that is shut most of the time. A box drawn around a shut fold is a
	   box drawn around nothing, so it comes off and the summary pill carries
	   the grouping on its own. */
	.pcf-app .deck-box {
		border: 0;
		border-radius: 0;
		background: none;
		overflow: visible;
	}

	.pcf-app .deck-box > .tool-group,
.pcf-app .deck-box > .tools-fold,
.pcf-app .deck-box > .tools-fold > .tool-group { padding: 0; border-top: 0; }

	.pcf-app .deck-box > .tools-fold > .tool-group { margin-top: 16px; }

	/* Deck's own buttons have left for the fixed bar at the bottom of the
	   screen, so all this section still holds is Delete — which has no business
	   being the first thing in the panel. It goes under the fold instead. */
	.pcf-app .deck-box > .tools-fold { order: 1; }
	.pcf-app .deck-box > #pcf-deckActions { order: 2; margin-top: 14px; }

	.pcf-app .tools { padding: 14px 12px 20px; }
	.pcf-app .saved-list { max-height: none; }

	/* save / save as / new stay on screen while the deck is being built */
	.pcf-app .deck-bar {
		position: fixed;
		left: 0;
		right: 0;
		bottom: 0;
		z-index: 45;
		padding: 9px 12px calc(9px + env(safe-area-inset-bottom));
		background: var(--surface);
		border-top: 1px solid var(--line);
	}

	/* ---- tournaments ---- */

	.pcf-app .ev-wrap { overflow: visible; }
	.pcf-app .ev-inner { padding: 16px 12px 32px; }

	/* the row becomes two lines: placing and deck up top, the buttons on their
	   own line at full width, where a thumb can actually reach them */
	.pcf-app .ev-row {
		grid-template-columns: auto minmax(0, 1fr);
		grid-template-areas:
			"place main"
			"deck  deck"
			"acts  acts";
		gap: 10px 12px;
		padding: 12px;
	}
	.pcf-app .ev-row-main h3 { font-size: 14.5px; }
	.pcf-app .ev-row-acts .btn { flex: 1 1 0; }

	.pcf-app .ev-mini { gap: 2px; }

	.pcf-app .ev-grid { grid-template-columns: 1fr; gap: 10px; }
	.pcf-app .ev-card { padding: 14px; }
	.pcf-app .ev-card-head h3 { font-size: 15px; }

	/* the deck name sits above its own bar rather than being squeezed beside it */
	.pcf-app .ev-bar,
.pcf-app .ev-bars.wide .ev-bar {
		grid-template-columns: 1fr auto;
		grid-template-areas: "name n" "track track";
		gap: 4px 8px;
	}
	.pcf-app .ev-bar-name { grid-area: name; white-space: normal; }
	.pcf-app .ev-bar-n { grid-area: n; }
	.pcf-app .ev-bar-track { grid-area: track; }

	.pcf-app .ev-section { margin-top: 20px; }
	.pcf-app .ev-crumb { margin-bottom: 8px; }

	.pcf-app .review-bar { padding: 10px 12px; }
	.pcf-app .review-bar .btn,
.pcf-app .review-bar .btn + .btn { margin-left: 0; flex: 1 1 0; }

	/* ---- banlist ---- */

	.pcf-app .bl-inner { padding: 16px 12px 36px; }
	.pcf-app .bl-top { gap: 12px; margin-bottom: 14px; }
	.pcf-app .bl-top h1 { font-size: 22px; }
	.pcf-app .bl-grid { grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); gap: 12px 8px; }
	.pcf-app .bl-card .nm { font-size: 10px; }
	.pcf-app .legend { margin-left: 0; }

	/* ---- detail, when it is shown inline ---- */
	.pcf-app .detail { padding: 14px 12px 20px; }
	.pcf-app .detail .art { max-width: 168px; }

	.pcf-app .toast { bottom: 18px; font-size: 12.5px; }
}

@media (max-width: 380px) {
	.pcf-app .card-grid { --tile: 84px; }
	.pcf-app .nav a { padding: 8px 9px; font-size: 13px; }
}

/* pointer-coarse: no hover states that stick */
@media (hover: none) {
	.pcf-app .card-cell:hover .thumb { transform: none; box-shadow: var(--shadow); }
	.pcf-app .slot.filled:hover img { transform: none; }
}

/* ---------- print sheet (fallback for image export) ---------- */

.pcf-app .print-sheet { display: none; }

@media print {
	.pcf-app > *:not(.print-sheet) { display: none !important; }
	.pcf-app .print-sheet { display: block; padding: 16px; }
}

/* ---------- fitting the app into a themed page ----------
   The preview owns a whole browser tab. Here the app is a block on a page, so
   on a wide screen it fills what is left of the viewport below whatever the
   theme puts above it (--pcf-top is measured at runtime), and on a phone it
   grows with its content exactly as the preview does. */

.pcf-app {
	height: calc(100vh - var(--pcf-top, 0px));
	min-height: 520px;
	overflow: hidden;
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	color-scheme: light;
}

.pcf-app[data-theme="dark"] { color-scheme: dark; }

@media (max-width: 760px) {
	.pcf-app {
		height: auto;
		min-height: 0;
		overflow: visible;
		border: 0;
		border-radius: 0;
	}
}

/* ---------- the chromeless shell (templates/app-shell.php) ----------
   Here .pcf-app is not a block inside somebody else's page — it IS the page,
   the way the preview always looked. No theme header sits above it, so the
   box, its border and its rounded corners (all sized for sitting inside a
   themed page) are dropped; it runs edge to edge instead. */

body.pcf-app-shell { margin: 0; }

body.pcf-app-shell .pcf-app {
	border: 0;
	border-radius: 0;
}

/* The ground behind the app: the app is exactly one viewport tall and the
   credit footer sits below it, so anything visible past either of them should
   read as the app's own background rather than a stray white strip. */
html[data-theme="dark"] body.pcf-app-shell { background: #141618; }
html:not([data-theme="dark"]) body.pcf-app-shell,
body.pcf-app-shell { background: #f6f6f3; }

/* The credit footer sits below .pcf-app, not inside it (see app-shell.php),
   and below the fold with it: the app owns the viewport, this is reached by
   scrolling the page. It is a credit line, not a toolbar — pinning it across
   the bottom of every screen cost a band of every screen.

   Because it is a sibling it cannot reach the --tokens .pcf-app defines on
   itself — they are custom properties, and those only inherit downward, never
   sideways to a sibling. The values below are the same light/dark palette,
   spelled out. */
.site-foot {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 7px 18px;
	padding: 11px 20px;
	border-top: 1px solid #d8d8d4;
	background: #ffffff;
	font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
	font-size: 11.5px;
	letter-spacing: .02em;
	color: #8a8a86;
}

html[data-theme="dark"] .site-foot {
	border-top-color: #3a3e42;
	background: #1d2023;
	color: #9a9a96;
}

.site-foot-credit,
.site-foot-links { display: inline-flex; align-items: center; gap: 9px; }

.site-foot-credit { color: inherit; text-decoration: none; transition: color 150ms ease; }
.site-foot-credit:hover { color: #111111; }
html[data-theme="dark"] .site-foot-credit:hover { color: #f3f3f2; }

.site-foot-logo { height: 18px; width: auto; display: none; }
.site-foot .is-light { display: block; }
html[data-theme="dark"] .site-foot .is-light { display: none; }
html[data-theme="dark"] .site-foot .is-dark { display: block; }

/* The legal links: same weight as the credit line, never louder than it. */
.site-foot-links { gap: 7px; }
.site-foot-links a { color: inherit; text-decoration: none; }
.site-foot-links a:hover { color: #111111; text-decoration: underline; }
html[data-theme="dark"] .site-foot-links a:hover { color: #f3f3f2; }
.site-foot-sep { opacity: .45; }

/* ---------- "hidden" has to win ----------
   Several rules in this sheet give an explicit display to classes the app also
   toggles with el.hidden — .btn (inline-flex) and .modal-step (flex) among
   them — and an explicit display in an author stylesheet beats the user
   agent's own [hidden] { display: none }. The result is an element that has
   been hidden in script and is still on the screen: the Publish button showing
   to an account that cannot publish, the recovery sheet's code field showing
   before a code has been sent. One rule settles it for every such case. */
.pcf-app [hidden] { display: none !important; }

/* ---------- the account corner of the header ----------
   Plugin-only: the standalone preview has no server behind it and therefore no
   accounts, so none of this belongs in preview/pcf-preview.css. */

.account-slot { display: flex; align-items: center; }

/* signed out: a plain link, the quietest thing in the bar */
.account {
	font-size: 12.5px;
	color: var(--muted);
	text-decoration: none;
	white-space: nowrap;
	padding: 6px 4px;
}

.account:hover { color: var(--text); }

/* signed in: the profile icon, and the nickname beside it as its label.
   The circle is the target on a phone, where the name steps aside. */
.account-btn {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 3px 9px 3px 3px;
	border-radius: 99px;
	color: var(--muted);
	text-decoration: none;
	white-space: nowrap;
	transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
}

.account-btn:hover { background: var(--surface-2); color: var(--text); }

.avatar {
	display: inline-grid;
	place-items: center;
	flex: 0 0 auto;
	width: 26px;
	height: 26px;
	border-radius: 50%;
	background: var(--accent);
	color: var(--on-accent);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: .02em;
	line-height: 1;
	text-transform: uppercase;
	/* only an <img> avatar has anything to fit; a plain initials <span> ignores this */
	object-fit: cover;
}

.avatar.lg { width: 44px; height: 44px; font-size: 16px; }
.avatar.sm { width: 20px; height: 20px; font-size: 9px; }

/* .avatar is sometimes a plain <img>, which cannot contain a child element —
   so anything that has to sit on top of it hangs off this wrapper instead */
.avatar-wrap { position: relative; display: inline-grid; flex: 0 0 auto; }

/* the bell — quiet outline normally, the whole button filled while something
   is waiting in it, back to the outline the moment the list has been opened */
.notif-btn { position: relative; }
.notif-icon { display: grid; place-items: center; }
.notif-icon svg { width: 17px; height: 17px; display: block; }

.notif-btn.has-unseen {
	background: var(--forbidden);
	border-color: var(--forbidden);
	color: #fff;
}
.notif-btn.has-unseen:hover { background: var(--forbidden); border-color: var(--forbidden); }

.notif-dot { display: none; }

.account-name {
	font-size: 12.5px;
	max-width: 12ch;
	overflow: hidden;
	text-overflow: ellipsis;
}

@media (max-width: 900px) {
	.account-name { display: none; }
	.account-btn { padding: 3px; }
}

/* ---------- the account sheets ----------
   openModal() already styles the box, the title and the buttons; these are the
   few extra pieces the login, recovery and profile sheets bring with them. */

/* the notice line doubles as a confirmation — "a code is on its way" is not an
   error, and colouring it like one is how a form tells someone it failed when
   it did not */
.modal-error.ok {
	color: var(--muted);
	border-color: var(--line);
	background: var(--surface-2);
}

/* the second half of the recovery sheet, revealed once a code has been sent */
.modal-step { display: flex; flex-direction: column; gap: 14px; }

.modal-sep { height: 1px; background: var(--line); margin: 2px 0; }

.profile-head { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.profile-who { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.profile-who strong { font-size: 15px; }

/* the avatar upload's own error line wraps onto a row of its own rather than
   squeezing into the avatar/name row it is appended after */
.profile-head .modal-error { flex: 1 0 100%; margin: 4px 0 0; }

.profile-head .avatar { width: 56px; height: 56px; font-size: 19px; flex: 0 0 auto; }

/* Change / Remove, a plain row of its own under the avatar and name rather
   than an icon sitting on top of the photo — the badge read as far more
   urgent/clickable than "you can change this if you want to" should. */
.profile-avatar-actions { flex: 1 0 100%; display: flex; gap: 8px; }
.profile-avatar-actions .btn { flex: 0 0 auto; }

.profile-mail {
	font-size: 12.5px;
	color: var(--faint);
	overflow: hidden;
	text-overflow: ellipsis;
}

.profile-access { display: flex; flex-direction: column; gap: 6px; }

.profile-access h4 {
	margin: 0;
	font-size: 10.5px;
	font-weight: 700;
	letter-spacing: .11em;
	text-transform: uppercase;
	color: var(--faint);
}

/* label and value on one line on a desktop, stacked when there is no room —
   an IP and a browser name together are longer than they look */
.profile-row {
	display: flex;
	flex-wrap: wrap;
	gap: 2px 10px;
	font-size: 12.5px;
	line-height: 1.45;
}

.profile-row .k { color: var(--faint); flex: 0 0 auto; }
.profile-row .v { color: var(--muted); min-width: 0; }

.profile-actions { display: flex; flex-direction: column; gap: 8px; }

.profile-shared:empty { display: none; }
.profile-shared { display: flex; flex-direction: column; gap: 6px; margin-top: 4px; }
.profile-shared h4 {
	margin: 0;
	font-size: 10.5px;
	font-weight: 700;
	letter-spacing: .11em;
	text-transform: uppercase;
	color: var(--faint);
}

/* a link, not a button: it leaves the profile sheet for the deckbuilder */
.shared-row {
	display: flex;
	flex-wrap: wrap;
	gap: 2px 10px;
	padding: 7px 9px;
	border-radius: var(--r-sm);
	border: 1px solid var(--line);
	font-size: 12.5px;
	line-height: 1.4;
	text-decoration: none;
	color: inherit;
	transition: border-color var(--fast) var(--ease);
}
.shared-row:hover { border-color: var(--faint); }
.shared-row .k { color: var(--text); flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.shared-row .v { color: var(--faint); flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px; }
.shared-row.unseen { border-color: var(--perfect); }
