/*
 * Ferndale Intranet: plugin group "file-tools".
 *
 *   - HEIC to JPG (Client) 1.1.0     [heic_to_jpg]          page 949
 *   - PDF Scan Compressor 1.3.1      [pdf_compressor]       page 996
 *   - Masonry Collage Builder 1.2.5  [mcb_collage_builder]  page 962
 *
 * Loaded by inc/plugins/file-tools.php after the plugins' own stylesheets,
 * only where one of them is enqueued. Digest: theme-work/plugins/file-tools.md.
 *
 * Rules (DESIGN-BRIEF §3):
 * - Role tokens only (--fi-*). The plugins' own custom properties (--hj-*,
 *   --psc-*, --mcb-*) are remapped to role tokens, so their state rules
 *   (drag-over, done, error) pick up the theme colours unchanged.
 * - Specificity: HEIC has no fixed ID, so its rules start with
 *   "body .heic-to-jpg-client" (0,2,1 or more). PDF and MCB pin their roots
 *   with an ID, so their rules start with #pdf-compressor / #mcb-builder.
 * - Never set: the progress bars' width (written inline by JS); display on
 *   anything the plugins show or hide with classes or [hidden] (PDF compact
 *   bar, MCB compact drop zone, preset groups); the canvas size.
 * - No !important: the PDF [hidden] fix wins on specificity (it excludes the
 *   compact "Add more files" bar, which keeps [hidden] and is shown by the
 *   plugin's own !important rule).
 * - Shared look: drop zones (2px dashed --fi-control-border on --fi-surface),
 *   theme buttons (10px radius, weight 700, 2.75rem tall), segmented controls,
 *   trays (--fi-surface panels), cards, notices and progress tracks.
 * - Version A puts the content in a white article card, so the tools' own
 *   panels are nested there (12px, flat); Version B's page is open, so they
 *   are page-level panels (18px, soft shadow).
 */

/* ------------------------------------------------------------------
 * Group tokens (both designs; Version A overrides below).
 * ------------------------------------------------------------------ */
body .heic-to-jpg-client,
#pdf-compressor,
#mcb-builder {
	--fi-ft-radius: var(--fi-radius-lg);
	--fi-ft-shadow: var(--fi-shadow-sm);
	--fi-ft-icon-upload: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256' fill='black'%3E%3Cpath d='M224,144v64a8,8,0,0,1-8,8H40a8,8,0,0,1-8-8V144a8,8,0,0,1,16,0v56H208V144a8,8,0,0,1,16,0ZM93.66,77.66,120,51.31V144a8,8,0,0,0,16,0V51.31l26.34,26.35a8,8,0,0,0,11.32-11.32l-40-40a8,8,0,0,0-11.32,0l-40,40A8,8,0,0,0,93.66,77.66Z'/%3E%3C/svg%3E"); /* Phosphor upload-simple (MIT). */
	--fi-ft-icon-caret: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256' fill='black'%3E%3Cpath d='M184.49,136.49l-80,80a12,12,0,0,1-17-17L159,128,87.51,56.49a12,12,0,1,1,17-17l80,80A12,12,0,0,1,184.49,136.49Z'/%3E%3C/svg%3E"); /* Phosphor caret-right bold (MIT). */
}

.fi-design-classic .heic-to-jpg-client,
.fi-design-classic #pdf-compressor,
.fi-design-classic #mcb-builder {
	--fi-ft-radius: var(--fi-radius);
	--fi-ft-shadow: none;
}

/* ==================================================================
 * 1. HEIC to JPG (Client)
 * ================================================================== */
body .heic-to-jpg-client {
	--hj-bg: var(--fi-surface);
	--hj-card: var(--fi-card-bg);
	--hj-border: var(--fi-border);
	--hj-text: var(--fi-text);
	--hj-muted: var(--fi-muted);
	--hj-accent: var(--fi-primary);
	--hj-danger: var(--fi-danger);
	--hj-danger-bg: var(--fi-danger-tint);
	--hj-progress-bg: var(--fi-surface-2);
	--hj-radius: var(--fi-ft-radius);
	margin: 0;
	color: var(--fi-text);
	font-family: inherit;
	font-size: 1rem;
	line-height: 1.55;
}

/* The page (B) or the article card (A) is the card: no box in a box. */
body .heic-to-jpg-client .heic-to-jpg-card {
	padding: 0;
	border: 0;
	border-radius: 0;
	background: transparent;
	box-shadow: none;
}

/* Drop zone: the whole zone is the button (role="button" in the markup). */
body .heic-to-jpg-client .heic-to-jpg-dropzone {
	--fi-ft-dz-pad: clamp(1.75rem, 1.25rem + 2vw, 2.75rem);
	padding: var(--fi-ft-dz-pad) 1.25rem;
	border: 2px dashed var(--fi-control-border);
	border-radius: var(--fi-ft-radius);
	background: var(--fi-surface);
	color: var(--fi-text);
	transition: border-color var(--fi-duration) ease, background-color var(--fi-duration) ease;
}

/* Icon: a tinted circle (::before) with the upload glyph on it (::after). */
body .heic-to-jpg-client .heic-to-jpg-dropzone::before {
	content: "";
	display: block;
	width: 3.5rem;
	height: 3.5rem;
	margin: 0 auto 0.875rem;
	border-radius: 50%;
	background: var(--fi-tint);
	transition: background-color var(--fi-duration) ease;
}

body .heic-to-jpg-client .heic-to-jpg-dropzone::after {
	content: "";
	position: absolute;
	top: calc(var(--fi-ft-dz-pad) + 0.875rem);
	right: 0;
	left: 0;
	width: 1.75rem;
	height: 1.75rem;
	margin-inline: auto;
	background: var(--fi-primary);
	-webkit-mask: var(--fi-ft-icon-upload) center / contain no-repeat;
	mask: var(--fi-ft-icon-upload) center / contain no-repeat;
	pointer-events: none;
}

body .heic-to-jpg-client .heic-to-jpg-dropzone:hover,
body .heic-to-jpg-client .heic-to-jpg-dropzone.is-dragover {
	border-color: var(--fi-primary);
	background: var(--fi-tint);
}

body .heic-to-jpg-client .heic-to-jpg-dropzone:hover::before,
body .heic-to-jpg-client .heic-to-jpg-dropzone.is-dragover::before {
	background: var(--fi-card-bg);
}

/* The plugin removes the outline on :focus; keyboard focus gets the ring back. */
body .heic-to-jpg-client .heic-to-jpg-dropzone:focus-visible {
	border-color: var(--fi-primary);
	outline: 3px solid var(--fi-focus);
	outline-offset: 2px;
}

/* The file input sat inside the drop zone as an invisible second Tab stop
 * (a focusable control nested in a button). The drop zone opens it with
 * input.click(), which works on an undisplayed input (as the PDF tool's
 * own hidden input does). */
body .heic-to-jpg-client .heic-to-jpg-file-input {
	display: none;
}

body .heic-to-jpg-client .heic-to-jpg-title {
	margin: 0 0 0.25rem;
	color: var(--fi-heading);
	font-size: 1.125rem;
	font-weight: 750;
	line-height: 1.3;
}

body .heic-to-jpg-client .heic-to-jpg-subtitle {
	margin: 0;
	color: var(--fi-muted);
	font-size: 0.9375rem;
}

/* Buttons (markup: wp-admin's "button button-secondary"). */
body .heic-to-jpg-client .heic-to-jpg-actions {
	flex-wrap: wrap;
	gap: 0.75rem;
	margin: 1.25rem 0 1rem;
}

body .heic-to-jpg-client .heic-to-jpg-actions .button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 2.75rem;
	margin: 0;
	padding: 0.55rem 1.15rem;
	border: 2px solid var(--fi-primary);
	border-radius: var(--fi-radius-control);
	background: var(--fi-card-bg);
	color: var(--fi-primary);
	font-family: inherit;
	font-size: 0.9375rem;
	font-weight: 700;
	line-height: 1.2;
	text-decoration: none;
	text-shadow: none;
	box-shadow: none;
	cursor: pointer;
	transition: background-color var(--fi-duration) ease, border-color var(--fi-duration) ease, color var(--fi-duration) ease;
}

body .heic-to-jpg-client .heic-to-jpg-actions .button:hover {
	border-color: var(--fi-primary);
	background: var(--fi-primary);
	color: var(--fi-on-primary);
}

body .heic-to-jpg-client .heic-to-jpg-actions .button.heic-to-jpg-cancel {
	border-color: var(--fi-danger);
	color: var(--fi-danger);
}

body .heic-to-jpg-client .heic-to-jpg-actions .button.heic-to-jpg-cancel:hover {
	border-color: var(--fi-danger);
	background: var(--fi-danger);
	color: var(--fi-on-primary);
}

body .heic-to-jpg-client .heic-to-jpg-actions .button:focus-visible {
	outline: 3px solid var(--fi-focus);
	outline-offset: 2px;
}

/* File list (a div grid with a header row). */
body .heic-to-jpg-client .heic-to-jpg-list {
	border: 1px solid var(--fi-border);
	border-radius: var(--fi-radius);
	background: var(--fi-card-bg);
	box-shadow: var(--fi-ft-shadow);
}

body .heic-to-jpg-client .heic-to-jpg-list-head {
	padding: 0.7rem 1rem;
	background: var(--fi-surface-2);
	color: var(--fi-muted);
	font-size: 0.8125rem;
	font-weight: 750;
	letter-spacing: 0.05em;
	text-transform: uppercase;
}

/* Phones: the plugin hides the header row (max-width: 700px), so an empty
 * list would show as a stray line. It stays in place (a live region). */
@media (max-width: 700px) {
	body .heic-to-jpg-client .heic-to-jpg-list:has(> .heic-to-jpg-list-body:empty) {
		border-color: transparent;
		box-shadow: none;
	}
}

body .heic-to-jpg-client .heic-to-jpg-row {
	padding: 0.8rem 1rem;
	border-top: 1px solid var(--fi-border);
	font-size: 0.9375rem;
}

body .heic-to-jpg-client .heic-to-jpg-file {
	color: var(--fi-heading);
	font-weight: 650;
}

body .heic-to-jpg-client .heic-to-jpg-size {
	color: var(--fi-muted);
	font-variant-numeric: tabular-nums;
}

body .heic-to-jpg-client .heic-to-jpg-status {
	color: var(--fi-text);
}

body .heic-to-jpg-client .heic-to-jpg-progress-wrap {
	height: 0.5rem;
	border-radius: var(--fi-radius-pill);
	background: var(--fi-surface-2);
}

/* Width stays with JS (inline style). */
body .heic-to-jpg-client .heic-to-jpg-progress-bar {
	border-radius: var(--fi-radius-pill);
	background: var(--fi-primary);
}

/* Error banner = theme danger notice. */
body .heic-to-jpg-client .heic-to-jpg-banner {
	margin: 0 0 1.25rem;
	padding: 0.9rem 1.1rem;
	border: 1px solid var(--fi-border);
	border-inline-start: 4px solid var(--fi-danger);
	border-radius: var(--fi-radius);
	background: var(--fi-danger-tint);
	color: var(--fi-text);
	font-size: 0.9375rem;
	line-height: 1.6;
}

body .heic-to-jpg-client .heic-to-jpg-banner strong {
	color: var(--fi-danger);
	font-weight: 750;
}

body .heic-to-jpg-client .heic-to-jpg-banner a {
	color: var(--fi-link);
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

body .heic-to-jpg-client .heic-to-jpg-banner a:hover {
	color: var(--fi-link-hover);
}

/* ==================================================================
 * 2. PDF Scan Compressor
 * ================================================================== */
#pdf-compressor {
	--psc-primary: var(--fi-primary);
	--psc-primary-hover: var(--fi-primary-hover);
	--psc-success: var(--fi-success);
	--psc-success-hover: var(--fi-success-hover);
	--psc-warning: var(--fi-warning-text);
	--psc-error: var(--fi-danger);
	--psc-border: var(--fi-control-border);
	--psc-bg: var(--fi-card-bg);
	--psc-bg-light: var(--fi-surface);
	--psc-text: var(--fi-text);
	--psc-text-muted: var(--fi-muted);
	--psc-radius: var(--fi-radius-control);
	/* --psc-gap is left to the plugin (it changes per breakpoint). */
	color: var(--fi-text);
	font-family: inherit;
	font-size: 1rem;
	line-height: 1.55;
}

/* Hidden buttons stay hidden: the plugin's display:inline-flex on
 * .pdf-compressor__btn beat [hidden], so Cancel and an empty Download link
 * showed on queued files. The compact "Add more files" bar keeps [hidden]
 * all the time and is shown by the plugin's own !important rule: leave it. */
#pdf-compressor [hidden]:not(.pdf-compressor__dropzone-compact) {
	display: none;
}

#pdf-compressor .pdf-compressor__top {
	gap: clamp(1rem, 0.75rem + 1vw, 1.5rem);
	margin-bottom: clamp(1rem, 0.75rem + 1vw, 1.5rem);
}

/* No trailing margins until something is queued: the empty queue is the
 * last block, so they only added space under the tool (80px in A's card
 * against 40px above it). (1,2,0) beats the (1,1,0) rules. */
#pdf-compressor:not(:has(.pdf-compressor__item)) :is(.pdf-compressor__top, .pdf-compressor__queue) {
	margin-bottom: 0;
}

/* Settings: a tray. */
#pdf-compressor .pdf-compressor__options {
	padding: clamp(1rem, 0.75rem + 1vw, 1.5rem);
	border: 1px solid var(--fi-border);
	border-radius: var(--fi-ft-radius);
	background: var(--fi-surface);
}

/* Presets: a segmented control (the radios stay visually hidden and focusable). */
#pdf-compressor .pdf-compressor__presets {
	gap: 3px;
	margin-bottom: 0.75rem;
	padding: 3px;
	overflow: visible;
	border: 1px solid var(--fi-control-border);
	border-radius: var(--fi-radius-control);
	background: var(--fi-control-bg);
}

#pdf-compressor .pdf-compressor__preset {
	position: relative;
	justify-content: center;
	min-height: 3.5rem;
	padding: 0.5rem 0.4rem;
	border: 0;
	border-radius: calc(var(--fi-radius-control) - 3px);
	background: transparent;
	color: var(--fi-text);
	transition: background-color var(--fi-duration) ease, color var(--fi-duration) ease;
}

#pdf-compressor .pdf-compressor__preset:hover {
	background: var(--fi-tint);
}

#pdf-compressor .pdf-compressor__preset:has(input:checked) {
	background: var(--fi-primary);
	color: var(--fi-on-primary);
}

#pdf-compressor .pdf-compressor__preset-label {
	color: inherit;
	font-size: 0.9375rem;
	font-weight: 700;
	line-height: 1.3;
}

#pdf-compressor .pdf-compressor__preset-detail {
	margin-top: 0.1rem;
	color: var(--fi-muted);
	font-size: 0.8125rem;
	font-variant-numeric: tabular-nums;
}

#pdf-compressor .pdf-compressor__preset:has(input:checked) .pdf-compressor__preset-label,
#pdf-compressor .pdf-compressor__preset:has(input:checked) .pdf-compressor__preset-detail {
	color: var(--fi-on-primary);
}

/* Ring for keyboard focus only (the plugin's :focus-within also fired on click). */
#pdf-compressor .pdf-compressor__preset:focus-within {
	outline: none;
}

#pdf-compressor .pdf-compressor__preset:has(input:focus-visible) {
	z-index: 1;
	outline: 3px solid var(--fi-focus);
	outline-offset: 2px;
}

/* Advanced settings: a disclosure link with a turning caret. */
#pdf-compressor .pdf-compressor__advanced summary {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	min-height: 2.75rem;
	padding: 0.25rem 0.1rem;
	border-radius: 4px;
	color: var(--fi-link);
	font-size: 0.9375rem;
	font-weight: 700;
	list-style: none;
}

#pdf-compressor .pdf-compressor__advanced summary::-webkit-details-marker {
	display: none;
}

#pdf-compressor .pdf-compressor__advanced summary::before {
	content: "";
	flex: none;
	width: 0.875rem;
	height: 0.875rem;
	background: currentColor;
	-webkit-mask: var(--fi-ft-icon-caret) center / contain no-repeat;
	mask: var(--fi-ft-icon-caret) center / contain no-repeat;
	transition: transform var(--fi-duration) var(--fi-ease);
}

#pdf-compressor .pdf-compressor__advanced[open] summary::before {
	transform: rotate(90deg);
}

#pdf-compressor .pdf-compressor__advanced summary:hover {
	color: var(--fi-link-hover);
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

#pdf-compressor .pdf-compressor__advanced summary:focus-visible {
	outline: 3px solid var(--fi-focus);
	outline-offset: 2px;
}

#pdf-compressor .pdf-compressor__advanced-inner {
	gap: 1.1rem;
	padding: 0.5rem 0 0;
}

#pdf-compressor .pdf-compressor__slider-group label {
	margin-bottom: 0.25rem;
	color: var(--fi-heading);
	font-size: 0.9375rem;
	font-weight: 650;
}

#pdf-compressor .pdf-compressor__slider-group output {
	color: var(--fi-primary);
	font-weight: 800;
	font-variant-numeric: tabular-nums;
}

#pdf-compressor .pdf-compressor__slider-group input[type="range"] {
	height: 1.5rem;
	margin: 0;
}

#pdf-compressor .pdf-compressor__hint {
	margin-top: 0.2rem;
	color: var(--fi-muted);
	font-size: 0.8125rem;
	line-height: 1.5;
}

#pdf-compressor .pdf-compressor__checkbox-group label {
	gap: 0.55rem;
	color: var(--fi-heading);
	font-size: 0.9375rem;
	font-weight: 650;
}

/* The theme draws the box; give it the theme's size. */
#pdf-compressor .pdf-compressor__checkbox-group input[type="checkbox"] {
	width: 1.125rem;
	height: 1.125rem;
	margin: 0;
}

/* Drop zone. In full mode only the Choose Files button acts on a click, so
 * the zone shows hover feedback in compact mode (where the zone is the
 * button) and while files are dragged over it. */
#pdf-compressor .pdf-compressor__dropzone {
	/* In the stacked (phone) layout the plugin's min-height: 120px replaced
	 * the flex item's content minimum, so the content spilled out. */
	min-height: auto;
	padding: clamp(1.5rem, 1rem + 2vw, 2.25rem) 1.25rem;
	border: 2px dashed var(--fi-control-border);
	border-radius: var(--fi-ft-radius);
	background: var(--fi-surface);
	color: var(--fi-text);
	cursor: default;
	transition: border-color var(--fi-duration) ease, background-color var(--fi-duration) ease;
}

#pdf-compressor .pdf-compressor__dropzone.pdf-compressor__dropzone--compact {
	padding: 1rem 1.25rem;
	cursor: pointer;
}

#pdf-compressor .pdf-compressor__dropzone.pdf-compressor__dropzone--compact:hover {
	border-color: var(--fi-primary);
	background: var(--fi-tint);
}

#pdf-compressor .pdf-compressor__dropzone.pdf-compressor__dropzone--active {
	border-color: var(--fi-primary);
	background: var(--fi-tint);
}

#pdf-compressor .pdf-compressor__dropzone:focus-visible {
	border-color: var(--fi-primary);
	outline: 3px solid var(--fi-focus);
	outline-offset: 2px;
}

#pdf-compressor .pdf-compressor__dropzone-icon {
	box-sizing: content-box;
	width: 1.75rem;
	height: 1.75rem;
	margin-bottom: 0.875rem;
	padding: 0.875rem;
	border-radius: 50%;
	background: var(--fi-tint);
	color: var(--fi-primary);
}

#pdf-compressor .pdf-compressor__dropzone--active .pdf-compressor__dropzone-icon {
	background: var(--fi-card-bg);
}

#pdf-compressor .pdf-compressor__dropzone-text {
	margin: 0 0 1rem;
	color: var(--fi-heading);
	font-size: 1.0625rem;
	font-weight: 700;
	line-height: 1.35;
}

/* Never set display here: the plugin shows this bar in compact mode. */
#pdf-compressor .pdf-compressor__dropzone-compact {
	gap: 0.75rem;
	color: var(--fi-primary);
	font-size: 1rem;
	font-weight: 700;
}

#pdf-compressor .pdf-compressor__dropzone-compact-icon {
	box-sizing: content-box;
	width: 1.25rem;
	height: 1.25rem;
	padding: 0.625rem;
	border-radius: 50%;
	background: var(--fi-tint);
}

#pdf-compressor .pdf-compressor__dropzone--compact:is(:hover, .pdf-compressor__dropzone--active) .pdf-compressor__dropzone-compact-icon {
	background: var(--fi-card-bg);
}

/* Buttons. Base = theme secondary (primary outline, fills on hover). */
#pdf-compressor .pdf-compressor__btn {
	gap: 0.4rem;
	min-height: 2.75rem;
	padding: 0.55rem 1.15rem;
	border: 2px solid var(--fi-primary);
	border-radius: var(--fi-radius-control);
	background: var(--fi-card-bg);
	color: var(--fi-primary);
	font-family: inherit;
	font-size: 0.9375rem;
	font-weight: 700;
	line-height: 1.2;
	text-decoration: none;
	transition: background-color var(--fi-duration) ease, border-color var(--fi-duration) ease, color var(--fi-duration) ease, transform 0.1s ease;
}

#pdf-compressor .pdf-compressor__btn:hover {
	border-color: var(--fi-primary);
	background: var(--fi-primary);
	color: var(--fi-on-primary);
}

#pdf-compressor .pdf-compressor__btn:focus-visible {
	outline: 3px solid var(--fi-focus);
	outline-offset: 2px;
}

/* Primary: Choose Files, Start / Retry. */
#pdf-compressor .pdf-compressor__btn:is(.pdf-compressor__btn--choose, .pdf-compressor__btn--start) {
	border-color: var(--fi-primary);
	background: var(--fi-primary);
	color: var(--fi-on-primary);
}

#pdf-compressor .pdf-compressor__btn:is(.pdf-compressor__btn--choose, .pdf-compressor__btn--start):hover {
	border-color: var(--fi-primary-hover);
	background: var(--fi-primary-hover);
	color: var(--fi-on-primary);
}

#pdf-compressor .pdf-compressor__btn.pdf-compressor__btn--choose {
	min-width: 10rem;
}

/* Danger outline: Cancel. */
#pdf-compressor .pdf-compressor__btn.pdf-compressor__btn--cancel {
	border-color: var(--fi-danger);
	background: var(--fi-card-bg);
	color: var(--fi-danger);
}

#pdf-compressor .pdf-compressor__btn.pdf-compressor__btn--cancel:hover {
	border-color: var(--fi-danger);
	background: var(--fi-danger);
	color: var(--fi-on-primary);
}

/* Success: Download (a link: restate every link state). */
#pdf-compressor a.pdf-compressor__btn.pdf-compressor__btn--download,
#pdf-compressor a.pdf-compressor__btn.pdf-compressor__btn--download:is(:link, :visited, :focus, :active) {
	border-color: var(--fi-success);
	background: var(--fi-success);
	color: var(--fi-on-primary);
	text-decoration: none;
}

#pdf-compressor a.pdf-compressor__btn.pdf-compressor__btn--download:hover {
	border-color: var(--fi-success-hover);
	background: var(--fi-success-hover);
	color: var(--fi-on-primary);
}

/* Ghost: Remove. */
#pdf-compressor .pdf-compressor__btn.pdf-compressor__btn--remove {
	padding-inline: 0.85rem;
	border-color: transparent;
	background: transparent;
	color: var(--fi-muted);
}

#pdf-compressor .pdf-compressor__btn.pdf-compressor__btn--remove:hover {
	border-color: transparent;
	background: var(--fi-danger-tint);
	color: var(--fi-danger);
}

/* Queue. */
#pdf-compressor .pdf-compressor__queue {
	gap: 0.75rem;
}

#pdf-compressor .pdf-compressor__item {
	padding: 1rem 1.25rem;
	border: 1px solid var(--fi-border);
	border-radius: var(--fi-radius);
	background: var(--fi-card-bg);
	box-shadow: var(--fi-shadow-sm);
	transition: box-shadow var(--fi-duration) ease;
}

/* State bar on the leading edge (an inset shadow: no layout shift). */
#pdf-compressor .pdf-compressor__item.pdf-compressor__item--processing {
	box-shadow: inset 4px 0 0 var(--fi-primary), var(--fi-shadow-sm);
}

#pdf-compressor .pdf-compressor__item.pdf-compressor__item--done {
	box-shadow: inset 4px 0 0 var(--fi-success), var(--fi-shadow-sm);
}

#pdf-compressor .pdf-compressor__item.pdf-compressor__item--error {
	box-shadow: inset 4px 0 0 var(--fi-danger), var(--fi-shadow-sm);
}

#pdf-compressor .pdf-compressor__item-header {
	gap: 0.25rem 0.75rem;
	margin-bottom: 0.6rem;
}

#pdf-compressor .pdf-compressor__item-name {
	color: var(--fi-heading);
	font-weight: 700;
	word-break: break-word;
}

#pdf-compressor .pdf-compressor__item-size,
#pdf-compressor .pdf-compressor__item-pages {
	color: var(--fi-muted);
	font-size: 0.875rem;
	font-variant-numeric: tabular-nums;
}

#pdf-compressor .pdf-compressor__item-progress-wrap {
	gap: 0.75rem;
	margin-bottom: 0.4rem;
}

#pdf-compressor .pdf-compressor__item-progress {
	height: 0.625rem;
	border-radius: var(--fi-radius-pill);
	background: var(--fi-surface-2);
}

/* Colour comes from --psc-primary / --psc-success; width stays with JS. */
#pdf-compressor .pdf-compressor__item-progress-bar {
	border-radius: var(--fi-radius-pill);
}

#pdf-compressor .pdf-compressor__item-percent {
	min-width: 2.75rem;
	color: var(--fi-muted);
	font-size: 0.875rem;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
}

/* Status colours come from the remapped tokens (info muted, success fern,
 * warning dark amber, error red); only the type is set here. */
#pdf-compressor .pdf-compressor__item-status {
	margin-bottom: 0.75rem;
	font-size: 0.9375rem;
}

#pdf-compressor .pdf-compressor__item-status.pdf-compressor__item-status--success {
	font-size: 0.9375rem;
	font-weight: 700;
}

#pdf-compressor .pdf-compressor__item-status:is(.pdf-compressor__item-status--warning, .pdf-compressor__item-status--error) {
	font-weight: 650;
}

#pdf-compressor .pdf-compressor__item-actions {
	gap: 0.5rem;
}

/* Sticky Clear All bar: fades in over the content surface. It is the last
 * block while files are queued, so no trailing margin. */
#pdf-compressor .pdf-compressor__actions {
	margin-bottom: 0;
	padding: 0.75rem 0;
	background: linear-gradient(transparent, var(--fi-card-bg) 35%);
}

/* Feature-detection error (replaces the drop zone's content). */
#pdf-compressor .pdf-compressor__error {
	margin: 0;
	padding: 0.9rem 1.1rem;
	border-inline-start: 4px solid var(--fi-danger);
	border-radius: var(--fi-radius);
	background: var(--fi-danger-tint);
	color: var(--fi-danger);
	font-size: 0.9375rem;
	font-weight: 650;
	text-align: start;
}

@media (max-width: 44rem) {
	#pdf-compressor .pdf-compressor__preset {
		min-height: 3.25rem;
		padding-inline: 0.25rem;
	}

	#pdf-compressor .pdf-compressor__preset-label {
		font-size: 0.875rem;
	}

	#pdf-compressor .pdf-compressor__preset-detail {
		font-size: 0.75rem;
	}

	#pdf-compressor .pdf-compressor__item {
		padding: 0.875rem 1rem;
	}
}

@media (max-width: 26rem) {
	#pdf-compressor .pdf-compressor__preset-label {
		font-size: 0.8125rem;
		text-wrap: balance;
	}
}

/* ==================================================================
 * 3. Masonry Collage Builder
 * ================================================================== */
#mcb-builder {
	--mcb-primary: var(--fi-primary);
	--mcb-primary-h: var(--fi-primary-hover);
	--mcb-success: var(--fi-success);
	--mcb-danger: var(--fi-danger);
	--mcb-gray-50: var(--fi-surface);
	--mcb-gray-100: var(--fi-surface-2);
	--mcb-gray-200: var(--fi-control-border);
	--mcb-gray-400: var(--fi-muted);
	--mcb-gray-600: var(--fi-muted);
	--mcb-gray-900: var(--fi-text);
	--mcb-radius: var(--fi-radius-control);
	max-width: none;
	color: var(--fi-text);
	font-family: inherit;
	font-size: 1rem;
	line-height: 1.5;
}

/* The permission notice renders outside #mcb-builder (its tokens are
 * undefined there): the theme's info notice. */
body .entry-content .mcb-notice {
	padding: 0.9rem 1.1rem;
	border: 1px solid var(--fi-border);
	border-inline-start: 4px solid var(--fi-info);
	border-radius: var(--fi-radius);
	background: var(--fi-info-tint);
	color: var(--fi-text);
	font-size: 1rem;
	text-align: start;
}

/* Drop zone (not a button: Select Files is the control). */
#mcb-builder .mcb-dropzone {
	margin-bottom: 1.25rem;
	padding: clamp(1.75rem, 1.25rem + 2vw, 2.75rem) 1.25rem;
	border: 2px dashed var(--fi-control-border);
	border-radius: var(--fi-ft-radius);
	background: var(--fi-surface);
	color: var(--fi-text);
	transition: border-color var(--fi-duration) ease, background-color var(--fi-duration) ease, padding 0.3s ease;
}

#mcb-builder .mcb-dropzone.mcb-dropzone--compact {
	padding: 0.875rem 1.25rem;
}

/* The full drop zone is the last visible block (thumbnails and workspace
 * are [hidden]; the status has its own margin-top). */
#mcb-builder .mcb-dropzone:not(.mcb-dropzone--compact) {
	margin-bottom: 0;
}

#mcb-builder .mcb-dropzone.mcb-dropzone--hover {
	border-color: var(--fi-primary);
	background: var(--fi-tint);
}

#mcb-builder .mcb-dropzone__inner {
	gap: 0.5rem;
}

#mcb-builder .mcb-dropzone__icon {
	box-sizing: content-box;
	width: 1.75rem;
	height: 1.75rem;
	margin-bottom: 0.375rem;
	padding: 0.875rem;
	border-radius: 50%;
	background: var(--fi-tint);
	color: var(--fi-primary);
}

#mcb-builder .mcb-dropzone--hover .mcb-dropzone__icon {
	background: var(--fi-card-bg);
}

#mcb-builder .mcb-dropzone__title {
	color: var(--fi-heading);
	font-size: 1.0625rem;
	font-weight: 700;
	line-height: 1.35;
}

#mcb-builder .mcb-dropzone__or {
	color: var(--fi-muted);
	font-size: 0.875rem;
}

#mcb-builder .mcb-dropzone__hint {
	margin-top: 0.25rem;
	color: var(--fi-muted);
	font-size: 0.875rem;
}

/* Buttons. Base = theme secondary; the plugin restates :focus like :hover
 * at (0,3,0), so the ID keeps focus on the base look plus the ring. */
#mcb-builder .mcb-btn {
	gap: 0.4rem;
	min-height: 2.75rem;
	padding: 0.55rem 1.15rem;
	border: 2px solid var(--fi-primary);
	border-radius: var(--fi-radius-control);
	background: var(--fi-card-bg);
	color: var(--fi-primary);
	font-family: inherit;
	font-size: 0.9375rem;
	font-weight: 700;
	line-height: 1.2;
	transition: background-color var(--fi-duration) ease, border-color var(--fi-duration) ease, color var(--fi-duration) ease;
}

#mcb-builder .mcb-btn:hover {
	border-color: var(--fi-primary);
	background: var(--fi-primary);
	color: var(--fi-on-primary);
}

#mcb-builder .mcb-btn:focus-visible {
	outline: 3px solid var(--fi-focus);
	outline-offset: 2px;
}

#mcb-builder .mcb-btn:disabled {
	opacity: 0.55;
	cursor: not-allowed;
}

#mcb-builder .mcb-btn.mcb-btn--primary {
	border-color: var(--fi-primary);
	background: var(--fi-primary);
	color: var(--fi-on-primary);
}

#mcb-builder .mcb-btn.mcb-btn--primary:hover {
	border-color: var(--fi-primary-hover);
	background: var(--fi-primary-hover);
	color: var(--fi-on-primary);
}

#mcb-builder .mcb-btn.mcb-btn--danger {
	border-color: var(--fi-danger);
	background: var(--fi-card-bg);
	color: var(--fi-danger);
}

#mcb-builder .mcb-btn.mcb-btn--danger:hover {
	border-color: var(--fi-danger);
	background: var(--fi-danger);
	color: var(--fi-on-primary);
}

#mcb-builder .mcb-dropzone .mcb-btn.mcb-btn--primary {
	min-width: 10rem;
}

/* Thumbnails. */
#mcb-builder .mcb-thumbnails {
	margin-bottom: 1.25rem;
}

#mcb-builder .mcb-thumbnails__count {
	color: var(--fi-muted);
	font-size: 0.875rem;
	font-weight: 700;
}

#mcb-builder .mcb-thumbnails__list {
	gap: 0.625rem;
	padding: 0.25rem 0.125rem 0.625rem;
}

/* Visible overflow, so the remove button's focus ring isn't clipped; the
 * image keeps the rounded corners itself. */
#mcb-builder .mcb-thumb {
	overflow: visible;
	border-radius: var(--fi-radius-sm);
}

#mcb-builder .mcb-thumb img {
	border-radius: calc(var(--fi-radius-sm) - 2px);
}

#mcb-builder .mcb-thumb__remove {
	top: 5px;
	right: 5px;
	display: grid;
	place-items: center;
	width: 1.75rem;
	height: 1.75rem;
	padding: 0;
	border: 2px solid var(--fi-card-bg);
	border-radius: 50%;
	background: var(--fi-primary);
	color: var(--fi-on-primary);
	font-family: inherit;
	font-size: 1.125rem;
	font-weight: 700;
	line-height: 1;
	transition: opacity var(--fi-duration) ease, background-color var(--fi-duration) ease;
}

/* The plugin shows it on hover only: keyboard focus and touch screens too. */
#mcb-builder .mcb-thumb:focus-within .mcb-thumb__remove,
#mcb-builder .mcb-thumb .mcb-thumb__remove:focus-visible {
	opacity: 1;
}

#mcb-builder .mcb-thumb .mcb-thumb__remove:hover {
	background: var(--fi-danger);
	color: var(--fi-on-primary);
}

#mcb-builder .mcb-thumb .mcb-thumb__remove:focus-visible {
	outline: 3px solid var(--fi-focus);
	outline-offset: 1px;
}

@media (hover: none) {
	#mcb-builder .mcb-thumb .mcb-thumb__remove {
		opacity: 1;
	}
}

/* Workspace and controls. The workspace is the last block unless the
 * status shows (its margin-top keeps the space), so no trailing margin. */
#mcb-builder .mcb-workspace {
	gap: 1.25rem;
	margin-bottom: 0;
}

#mcb-builder .mcb-controls {
	gap: 1rem;
}

/* Sections: trays. Each tray is a size container, so the narrow-tray rules
 * below follow its own width (narrow on phones, and in A's card at some
 * tablet and small-laptop widths, where the trays sit two or three to a row).
 * Side padding: 1.25rem from a 300px tray down to 0.875rem at 270px and
 * below (a percentage here resolves against the tray's grid column). */
#mcb-builder .mcb-controls__section {
	min-width: 0;
	padding: 1.15rem clamp(0.875rem, 20% - 2.5rem, 1.25rem) 1.25rem;
	container: fi-ft-tray / inline-size;
	border: 1px solid var(--fi-border);
	border-radius: var(--fi-ft-radius);
	background: var(--fi-surface);
}

/* The legend sits inside the tray (not on its border). */
#mcb-builder .mcb-controls__heading {
	float: left;
	width: 100%;
	margin: 0 0 0.875rem;
	padding: 0;
	color: var(--fi-h2);
	font-family: inherit;
	font-size: 0.8125rem;
	font-weight: 800;
	letter-spacing: 0.06em;
	line-height: 1.3;
}

#mcb-builder .mcb-controls__heading + * {
	clear: both;
}

/* Orientation: a segmented control. */
#mcb-builder .mcb-tabs {
	gap: 3px;
	margin-bottom: 0.75rem;
	padding: 3px;
	overflow: visible;
	border: 1px solid var(--fi-control-border);
	border-radius: var(--fi-radius-control);
	background: var(--fi-control-bg);
}

#mcb-builder .mcb-tab {
	min-height: 2.5rem;
	padding: 0.4rem 0.5rem;
	border: 0;
	border-radius: calc(var(--fi-radius-control) - 3px);
	background: transparent;
	color: var(--fi-text);
	font-family: inherit;
	font-size: 0.875rem;
	font-weight: 700;
	line-height: 1.2;
}

#mcb-builder .mcb-tab:hover {
	background: var(--fi-tint);
	color: var(--fi-text);
}

#mcb-builder .mcb-tab.mcb-tab--active,
#mcb-builder .mcb-tab.mcb-tab--active:hover {
	background: var(--fi-primary);
	color: var(--fi-on-primary);
}

#mcb-builder .mcb-tab:focus-visible {
	position: relative;
	z-index: 1;
	outline: 3px solid var(--fi-focus);
	outline-offset: 2px;
}

/* Size presets: chips. */
#mcb-builder .mcb-presets__group {
	gap: 0.4rem;
	margin-bottom: 1rem;
}

#mcb-builder .mcb-preset {
	min-height: 2.25rem;
	padding: 0.3rem 0.35rem;
	border: 1px solid var(--fi-control-border);
	border-radius: var(--fi-radius-pill);
	background: var(--fi-control-bg);
	color: var(--fi-text);
	font-family: inherit;
	font-size: 0.8125rem;
	font-weight: 650;
	line-height: 1.2;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

#mcb-builder .mcb-preset:hover {
	border-color: var(--fi-primary);
	background: var(--fi-tint);
	color: var(--fi-text);
}

#mcb-builder .mcb-preset.mcb-preset--active,
#mcb-builder .mcb-preset.mcb-preset--active:hover {
	border-color: var(--fi-primary);
	background: var(--fi-primary);
	color: var(--fi-on-primary);
}

#mcb-builder .mcb-preset:focus-visible {
	outline: 3px solid var(--fi-focus);
	outline-offset: 2px;
}

/* Labels and the form-control spec. */
#mcb-builder .mcb-controls__row {
	gap: 0.75rem;
}

#mcb-builder .mcb-label {
	gap: 0.35rem;
	margin-bottom: 0.875rem;
	color: var(--fi-heading);
	font-size: 0.9375rem;
}

#mcb-builder .mcb-label > span {
	font-weight: 650;
}

#mcb-builder .mcb-label--range {
	gap: 0.35rem 0.75rem;
}

#mcb-builder .mcb-label--range > span {
	flex-basis: 5.5rem;
}

/* margin-inline-start: if a row ever wraps, the value stays on the right. */
#mcb-builder .mcb-label--range output {
	flex-basis: 3.5rem;
	margin-inline-start: auto;
	color: var(--fi-primary);
	font-size: 0.875rem;
	font-weight: 800;
}

/* Narrow trays (content 264px or less). Above that the chips fit three to
 * a row (3 x 82px + gaps), the tabs fit (about 240px) and the slider rows
 * fit on one line (248px). Below it:
 * - the chips reflow (two to a row, one in a very narrow tray);
 * - the tabs share the width by content, slightly smaller (about 202px);
 * - each slider row stays on one line: label, slider, value (208px),
 *   with the labels kept equal ("Emphasize" is 78px) so the sliders align.
 *   The slider is still as wide as the space left (about 75px or more). */
@container fi-ft-tray (max-width: 16.5rem) {
	#mcb-builder .mcb-presets__group {
		grid-template-columns: repeat(auto-fill, minmax(5.25rem, 1fr));
	}

	#mcb-builder .mcb-tab {
		flex: 1 1 auto;
		padding-inline: 0.25rem;
		font-size: 0.8125rem;
	}

	#mcb-builder .mcb-label--range {
		column-gap: 0.5rem;
	}

	#mcb-builder .mcb-label--range > span {
		flex-basis: 5rem;
	}

	#mcb-builder .mcb-label--range input[type="range"] {
		min-width: 4rem;
		margin-inline: 0;
	}

	#mcb-builder .mcb-label--range output {
		flex-basis: 2.75rem;
	}
}

#mcb-builder .mcb-input {
	min-height: 2.75rem;
	padding: 0.55rem 0.75rem;
	border: 1px solid var(--fi-control-border);
	border-radius: var(--fi-radius-control);
	background-color: var(--fi-control-bg);
	color: var(--fi-text);
	font-family: inherit;
	font-size: 0.9375rem;
	line-height: 1.4;
}

#mcb-builder .mcb-input:focus {
	border-color: var(--fi-primary);
	box-shadow: none;
}

#mcb-builder .mcb-input:focus-visible {
	border-color: var(--fi-primary);
	outline: 3px solid var(--fi-focus);
	outline-offset: 1px;
}

#mcb-builder input[type="color"] {
	height: 2.75rem;
	padding: 4px;
	border: 1px solid var(--fi-control-border);
	border-radius: var(--fi-radius-control);
	background-color: var(--fi-control-bg);
}

/* A hairline round the swatch, so a white background colour doesn't read
 * as an empty field. */
#mcb-builder input[type="color"]::-webkit-color-swatch {
	border: 1px solid var(--fi-border);
	border-radius: calc(var(--fi-radius-control) - 4px);
}

#mcb-builder input[type="color"]::-moz-color-swatch {
	border: 1px solid var(--fi-border);
	border-radius: calc(var(--fi-radius-control) - 4px);
}

#mcb-builder .mcb-controls__actions {
	gap: 0.5rem;
	margin-top: 0.25rem;
	padding-top: 1rem;
	border-top: 1px solid var(--fi-border);
}

/* Preview: keep the checkerboard (it shows the collage's edge and colour). */
#mcb-builder .mcb-preview {
	padding: clamp(0.75rem, 0.5rem + 1.5vw, 1.5rem);
	border: 1px solid var(--fi-border);
	border-radius: var(--fi-ft-radius);
}

#mcb-builder .mcb-preview canvas {
	box-shadow: var(--fi-shadow);
}

/* Status = theme notice (JS rewrites the class name; colours per state). */
#mcb-builder .mcb-status {
	margin-top: 1rem;
	padding: 0.9rem 1.1rem;
	border: 1px solid var(--fi-border);
	border-inline-start: 4px solid var(--fi-info);
	border-radius: var(--fi-radius);
	background: var(--fi-info-tint);
	color: var(--fi-text);
	font-size: 0.9375rem;
}

#mcb-builder .mcb-status.mcb-status--success {
	border-color: var(--fi-border);
	border-inline-start-color: var(--fi-success);
	background: var(--fi-success-tint);
	color: var(--fi-text);
}

#mcb-builder .mcb-status.mcb-status--error {
	border-color: var(--fi-border);
	border-inline-start-color: var(--fi-danger);
	background: var(--fi-danger-tint);
	color: var(--fi-danger);
	font-weight: 650;
}

#mcb-builder .mcb-status a {
	color: var(--fi-link);
}

/* ==================================================================
 * 4. Reduced motion (each group stills its own plugins; brief §5).
 *    Busy indicators keep showing work without movement.
 * ================================================================== */
@keyframes fi-ft-busy {
	0%,
	100% {
		opacity: 1;
	}

	50% {
		opacity: 0.45;
	}
}

@media (prefers-reduced-motion: reduce) {
	/* Same specificity as the rules that set the transitions, and later.
	 * Progress-bar width transitions stay (they show the work). */
	body .heic-to-jpg-client .heic-to-jpg-dropzone,
	body .heic-to-jpg-client .heic-to-jpg-dropzone::before,
	body .heic-to-jpg-client .heic-to-jpg-actions .button,
	#pdf-compressor .pdf-compressor__preset,
	#pdf-compressor .pdf-compressor__advanced summary::before,
	#pdf-compressor .pdf-compressor__dropzone,
	#pdf-compressor .pdf-compressor__btn,
	#pdf-compressor .pdf-compressor__item,
	#mcb-builder .mcb-dropzone,
	#mcb-builder .mcb-btn,
	#mcb-builder .mcb-thumb,
	#mcb-builder .mcb-thumb__remove,
	#mcb-builder .mcb-tab,
	#mcb-builder .mcb-preset {
		transition: none;
	}

	/* HEIC "loading decoder": no sliding bar; the whole track pulses slowly. */
	body .heic-to-jpg-client .heic-to-jpg-progress-wrap.is-indeterminate {
		background: var(--fi-primary);
		animation: fi-ft-busy 2.4s ease-in-out infinite;
	}

	body .heic-to-jpg-client .heic-to-jpg-progress-wrap.is-indeterminate .heic-to-jpg-progress-bar {
		animation: none;
		opacity: 0;
	}

	/* PDF: the processing pulse is a fade (kept, slower); no button squash. */
	#pdf-compressor .pdf-compressor__item--processing .pdf-compressor__item-progress-bar {
		animation-duration: 2.4s;
	}

	#pdf-compressor .pdf-compressor__btn:active {
		transform: none;
	}

	/* MCB: no zoom on the drag target. */
	#mcb-builder .mcb-thumb.mcb-thumb--over {
		transform: none;
	}
}

/* Forced colours: the dashed drop zones and segmented controls keep edges. */
@media (forced-colors: active) {
	#pdf-compressor .pdf-compressor__preset:has(input:checked),
	#mcb-builder :is(.mcb-tab--active, .mcb-preset--active) {
		outline: 2px solid Highlight;
		outline-offset: -2px;
	}
}
