/*
 * Save Point Shop — the polish layer.
 *
 * theme.css holds the structure: bays, cards, slots, the form. This file
 * holds what makes it read as designed rather than assembled —
 *
 *   10. Depth: the night sky, panel lighting, edge highlights.
 *   11. Type craft: display treatment, numerals, pull quotes.
 *   12. Motion: reveals and hover feedback, all opt-in and reduced-motion safe.
 *   13. New section shapes: marquee, split feature, stat band, console browser.
 *
 * Loaded after theme.css on the front end and in the editor.
 */

/* ---------------------------------------------------------------
   10. Depth
   The old page was one flat navy. Three things fix that without a
   single image: a very slow radial wash, panels lit from above, and
   a one-pixel highlight along the top edge of anything raised.
   --------------------------------------------------------------- */

:root {
	--sps-lift: 0 1px 0 rgba(238, 232, 213, 0.06) inset;
	--sps-shadow: 0 18px 40px -24px rgba(0, 0, 0, 0.9);
	--sps-shadow-lg: 0 32px 70px -30px rgba(0, 0, 0, 0.95);
	--sps-glow-red: 0 0 0 1px rgba(224, 43, 43, 0.35), 0 12px 38px -14px rgba(224, 43, 43, 0.45);
	/* The moulded base a button sits on: the fill colour, driven down. */
	--sps-btn-edge: #7F1313;
	--sps-icon-external: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 17 17 7'/%3E%3Cpath d='M8.5 7H17v8.5'/%3E%3C/svg%3E");
	--sps-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

body {
	background-image:
		radial-gradient(1100px 620px at 78% -8%, rgba(224, 43, 43, 0.10), transparent 62%),
		radial-gradient(900px 560px at 6% 4%, rgba(245, 166, 35, 0.07), transparent 58%);
	background-repeat: no-repeat;
	background-attachment: fixed;
}
@media (max-width: 782px) {
	/* Fixed attachment repaints the whole wash on every scroll frame on
	   mobile Safari. Not worth it for a gradient nobody is looking at. */
	body { background-attachment: scroll; }
}

/* Panels are lit from above: a hair lighter at the top, a highlight on the
   top edge, and a shadow underneath to sit them off the page. */
.sps-card,
.sps-tile,
.sps-quote,
.sps-steps li,
.sps-storefront {
	background-image: linear-gradient(180deg, rgba(238, 232, 213, 0.045), transparent 42%);
	box-shadow: var(--sps-lift), var(--sps-shadow);
}

.sps-card--raised { box-shadow: var(--sps-lift), var(--sps-shadow-lg); }

/* Bay rules earn their keep by fading out at the edges rather than running
   the full width like a table border. */
.sps-bay {
	border-top: 0;
	position: relative;
}
.sps-bay::before {
	content: "";
	position: absolute;
	inset-inline: var(--sps-gutter);
	top: 0;
	height: 1px;
	background: linear-gradient(90deg, transparent, var(--wp--preset--color--rule) 12%, var(--wp--preset--color--rule) 88%, transparent);
}
.sps-bay--flush::before { display: none; }

/* ---------------------------------------------------------------
   11. Type craft
   --------------------------------------------------------------- */

/* The display headline gets optical tightening the fluid scale can't do on
   its own, and a shadow so it sits on the wash rather than floating. */
h1, h2 { text-wrap: balance; }
h1 { text-shadow: 0 2px 24px rgba(0, 0, 0, 0.35); }

/* The accent word inside a headline. Underscored with a soft bar rather
   than a hard rule, so it reads as emphasis and not as a link. */
.sps-accent { position: relative; }

/* Figures. Oversized, tabular, and sharing one optical baseline so the row
   reads as a set rather than four separate numbers. */
.sps-figure {
	font-variant-numeric: tabular-nums lining-nums;
	letter-spacing: -0.015em;
	background: linear-gradient(180deg, var(--wp--preset--color--cream), rgba(238, 232, 213, 0.72));
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
}
/* A gradient-filled figure has no colour to fall back on if background-clip
   is unsupported, so restore it where it is. */
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
	.sps-figure { color: var(--wp--preset--color--cream); background: none; }
}

/* The deck sits in a slightly cooler tone than body copy so the heading,
   deck and body read as three levels rather than two. */
.sps-deck { letter-spacing: -0.003em; }

/* Pull quote, for a line worth stopping on. */
.sps-pull {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	text-transform: uppercase;
	font-size: var(--wp--preset--font-size--x-large);
	line-height: 1.04;
	color: var(--wp--preset--color--cream);
	border-left: 3px solid var(--wp--preset--color--red-2);
	padding-left: clamp(1rem, 2.5vw, 1.75rem);
	/* margin-block, never the shorthand — see the bay rule in theme.css. */
	margin-block: 0;
	max-width: 24ch;
}

/* ---------------------------------------------------------------
   12. Motion
   Nothing here runs unless sps.js has added .sps-js to <html>, which it
   only does when IntersectionObserver exists and the visitor has not
   asked for reduced motion. No JS, old browser, or reduce → the page is
   simply already in its final state.
   --------------------------------------------------------------- */

.sps-js .sps-reveal {
	opacity: 0;
	transform: translateY(18px);
	transition: opacity 620ms var(--sps-ease), transform 620ms var(--sps-ease);
}
.sps-js .sps-reveal.is-revealed {
	opacity: 1;
	transform: none;
}
.sps-js .sps-reveal--stagger > * {
	opacity: 0;
	transform: translateY(14px);
	transition: opacity 520ms var(--sps-ease), transform 520ms var(--sps-ease);
}
.sps-js .sps-reveal--stagger.is-revealed > * {
	opacity: 1;
	transform: none;
}

@media (prefers-reduced-motion: reduce) {
	.sps-js .sps-reveal,
	.sps-js .sps-reveal > * {
		opacity: 1 !important;
		transform: none !important;
		transition: none !important;
	}
}

/* Hover feedback that reports something: the tile lifts, its edge lights up
   in the accent, and the arrow moves the way it is pointing. */
.sps-tile {
	transition: border-color 180ms var(--sps-ease), transform 180ms var(--sps-ease), box-shadow 180ms var(--sps-ease);
}
.sps-tile:hover,
.sps-tile:focus-within {
	transform: translateY(-4px);
	box-shadow: var(--sps-lift), var(--sps-glow-red);
}
.sps-tile .sps-label--red { transition: transform 180ms var(--sps-ease); transform-origin: left; }
.sps-tile:hover .sps-label--red { transform: translateX(4px); }
.sps-tile__icon { transition: transform 260ms var(--sps-ease); }
.sps-tile:hover .sps-tile__icon { transform: scale(1.05) rotate(-2deg); }

/* Buttons, as physical things.
 *
 * A flat rectangle tells you nothing about whether it can be pressed. These
 * sit on a hard darker edge — the moulded base of a console button — so they
 * stand proud of the page, and on :active the face travels down onto the base
 * and the edge collapses to nothing. The travel distance and the edge height
 * are the same number, which is what makes the press read as real rather than
 * as a wobble.
 *
 * The fill is not set here: theme.json owns the colour. What is layered on is
 * a vertical light gradient and a lit top rim, so the same rule works for any
 * button colour without restating it.
 */
.wp-block-button__link {
	--sps-btn-travel: 4px;
	position: relative;
	background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0.11), rgba(0, 0, 0, 0.07));
	box-shadow:
		inset 0 1px 0 rgba(255, 255, 255, 0.20),
		0 var(--sps-btn-travel) 0 var(--sps-btn-edge),
		0 7px 14px rgba(0, 0, 0, 0.38);
	transition:
		background-color 180ms var(--sps-ease),
		border-color 180ms var(--sps-ease),
		color 180ms var(--sps-ease),
		box-shadow 110ms var(--sps-ease),
		transform 110ms var(--sps-ease);
}
.wp-block-button__link:hover {
	transform: translateY(-1px);
	box-shadow:
		inset 0 1px 0 rgba(255, 255, 255, 0.26),
		0 5px 0 var(--sps-btn-edge),
		0 12px 22px rgba(0, 0, 0, 0.45);
}
.wp-block-button__link:active {
	transform: translateY(var(--sps-btn-travel));
	box-shadow:
		inset 0 1px 0 rgba(255, 255, 255, 0.10),
		0 0 0 var(--sps-btn-edge),
		0 1px 3px rgba(0, 0, 0, 0.40);
}

/* The outline button is the same object in a lighter material: no fill, no
   gradient, a shorter edge in the rule colour so it never competes with the
   primary next to it. */
.is-style-outline .wp-block-button__link {
	--sps-btn-travel: 3px;
	/* Not `rule` (#2E3152): that is 1.36:1 on night, and the outline button's
	   border plus this moulded edge are its ONLY boundary — a transparent fill
	   has nothing else to see. WCAG 1.4.11 wants 3:1 for a control's boundary.
	   #6E74AE measures 3.88:1. */
	--sps-btn-edge: #6E74AE;
	background-image: none;
	box-shadow: 0 var(--sps-btn-travel) 0 var(--sps-btn-edge);
}
.is-style-outline .wp-block-button__link:hover {
	box-shadow: 0 4px 0 var(--sps-btn-edge);
}
.is-style-outline .wp-block-button__link:active {
	box-shadow: 0 0 0 var(--sps-btn-edge);
}

/* Buttons that go to eBay carry the eBay mark, matched on href so every eBay
   call to action gets it wherever it lives — patterns, page content, or a menu
   item added later — with no markup to keep in sync.

   It is painted as a mask in currentColor rather than as a colour image, for
   one reason: eBay's own red is a near neighbour of this theme's red, so the
   four-colour mark on a red button loses its "a" entirely and muddies its "B".
   Knocked out in a single colour it reads instantly, and it inherits whatever
   the button's text is — white on the red button, cream on the outline one —
   so it stays correct if a button is ever recoloured.

   The mark itself is eBay's, unmodified in shape: assets/img/ebay-mark.svg is
   their wordmark, and assets/img/ebay-mark-white.svg is the same paths in
   white for anywhere a plain <img> is wanted instead.

   It does not animate on hover: a sliding arrow reads as motion toward
   somewhere, a sliding logo just looks loose. The mark holds still and the
   button does the moving. */
.wp-block-button__link[href*="ebay."]::after,
.sps-nav-cta .wp-block-navigation-item__content[href*="ebay."]::after {
	content: "";
	display: inline-block;
	width: 2.5em;
	height: 1em;
	margin-left: 0.6em;
	vertical-align: -0.12em;
	background-color: currentColor;
	-webkit-mask: url("../img/ebay-mark.svg") center / contain no-repeat;
	mask: url("../img/ebay-mark.svg") center / contain no-repeat;
}

/* The service-area map. It is a light image on a dark page, so it needs a
   frame rather than being allowed to glow at the edges: the same panel, rule
   and lift the cards use, so it reads as part of the page instead of a
   screenshot dropped onto it. */
.sps-map {
	/* margin-block, never the shorthand — see the bay rule in theme.css. */
	margin-block: 0;
	/* Centred, deliberately overriding the bay's `margin-inline: var(--sps-inset) auto`.
	   That rule exists so a narrow child does not drift out of the column by
	   accident; this one is narrow on purpose and reads as an object on the
	   page rather than as a column of text, so it is centred on purpose.
	   Centring within the bay and centring within the measure are the same
	   place, because the measure is itself centred in the bay. */
	margin-inline: auto;
	/* Narrower than the measure on purpose. At the full 1320 the map is 742px
	   tall and swallows the page; the labels stop gaining legibility well
	   before that. */
	max-width: 62rem;
	border: 1px solid var(--wp--preset--color--rule);
	border-radius: var(--sps-radius);
	background: var(--wp--preset--color--panel);
	padding: 0.5rem;
	box-shadow: var(--sps-lift), var(--sps-shadow);
	overflow: hidden;
}
.sps-map img {
	display: block;
	width: 100%;
	height: auto;
	border-radius: calc(var(--sps-radius) - 2px);
}
/* The home-page copy of the map sits in the narrow half of a split, where the
   Find Us page's 62rem cap is irrelevant and the caption should not shout.
 *
 * Two things this has to undo that the Find Us copy gets for free:
 *
 * `margin-inline: 0` — a <figure> carries a UA margin of `1em 40px`, and the
 * 40px is INLINE. On Find Us the figure is a direct bay child, so the bay's
 * own `margin-inline` overrides it. Here nothing does, and the map rendered
 * 288px wide inside a 355px column with 40px of dead space either side.
 * `margin-block: 0` alone does not touch it — that is the whole point of the
 * block/inline split, and the reason this looked fine on one page and wrong
 * on the other.
 *
 * `align-self: start` — the split is a flex row, so the figure was stretching
 * to the text column's height and leaving ~270px of empty panel below the
 * map at desktop widths. */
.sps-map--inline {
	max-width: none;
	margin-inline: 0;
	align-self: start;
}
.sps-map--inline figcaption { font-size: 0.9375rem; padding-block: 0.75rem 0.25rem; }

.sps-map figcaption {
	padding: 0.9rem 0.75rem 0.4rem;
	color: var(--wp--preset--color--cream-2);
	font-size: 1rem;
	line-height: 1.5;
}

/* Card icons. A mark sized to the heading it sits above, in amber like the
   other accents, with enough space under it that it reads as a label for the
   card rather than as part of the heading. Deliberately NOT given a tinted
   plate: these appear four to a row and a row of four plates is a row of four
   boxes competing with the cards they are inside. */
.sps-card__icon {
	display: block;
	margin-bottom: 0.9rem;
	color: var(--wp--preset--color--amber);
	line-height: 0;
}
.sps-card__icon .sps-ico { font-size: 1.75rem; }

/* Carousel chrome. The controls are injected by the script, so the markup
   never ships a button that does nothing. */
.sps-carousel { position: relative; }
.sps-carousel__bar {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	margin-top: 0.75rem;
}
.sps-carousel__btn {
	flex: none;
	width: 44px;
	height: 44px;
	display: grid;
	place-items: center;
	border: 1px solid var(--wp--preset--color--rule);
	border-radius: var(--sps-radius);
	background: var(--wp--preset--color--panel);
	color: var(--wp--preset--color--cream);
	cursor: pointer;
	transition: border-color 180ms var(--sps-ease), color 180ms var(--sps-ease), background 180ms var(--sps-ease);
}
.sps-carousel__btn:hover:not([aria-disabled="true"]) {
	border-color: var(--wp--preset--color--amber);
	color: var(--wp--preset--color--amber);
}
.sps-carousel__btn:focus-visible {
	outline: 2px solid var(--wp--preset--color--amber);
	outline-offset: 2px;
}
/* Disabled rather than hidden: a control that vanishes at the ends makes the
   row jump and leaves the user wondering what moved. */
/* aria-disabled rather than :disabled — see the carousel in assets/js/sps.js.
   The button stays focusable so a keyboard user is never dropped back to
   <body> mid-row; it just stops doing anything. */
.sps-carousel__btn[aria-disabled="true"] { opacity: 0.35; cursor: default; }
.sps-carousel__btn svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }

/* The track's own progress, as a rule that fills rather than a row of dots:
   six dots for six reviews is six more things to look at, and dots stop
   scaling the moment another review is added. */
.sps-carousel__rail {
	flex: 1;
	height: 2px;
	background: var(--wp--preset--color--rule);
	border-radius: 999px;
	overflow: hidden;
}
.sps-carousel__rail span {
	display: block;
	height: 100%;
	width: 33%;
	background: var(--wp--preset--color--amber);
	border-radius: inherit;
	transform-origin: left;
	transition: transform 180ms var(--sps-ease), width 180ms var(--sps-ease);
}
.sps-carousel__count {
	flex: none;
	font-family: var(--wp--preset--font-family--display);
	text-transform: uppercase;
	letter-spacing: 0.04em;
	font-size: 1rem;
	color: var(--wp--preset--color--cream-2);
	font-variant-numeric: tabular-nums;
}

@media (prefers-reduced-motion: reduce) {
	.sps-carousel__btn, .sps-carousel__rail span { transition: none; }
}

.sps-quote { transition: border-color 180ms var(--sps-ease), transform 180ms var(--sps-ease); }
.sps-quote:hover { transform: translateY(-3px); border-left-color: var(--wp--preset--color--red-2); }

@media (prefers-reduced-motion: reduce) {
	.sps-tile, .sps-tile__icon, .wp-block-button__link, .sps-quote,
	.sps-tile .sps-label--red { transition: none; }
	.sps-tile:hover, .wp-block-button__link:hover, .sps-quote:hover,
	.sps-tile:hover .sps-tile__icon, .sps-tile:hover .sps-label--red { transform: none; }
	/* The press still has to land. Motion goes; the edge collapsing under the
	   button does not, because it is the only feedback left that the click
	   registered. */
	.wp-block-button__link:active { transform: none; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.10), 0 0 0 var(--sps-btn-edge), 0 1px 3px rgba(0, 0, 0, 0.40); }
}

/* ---------------------------------------------------------------
   13. New section shapes
   --------------------------------------------------------------- */

/* Console icons, from the sprite. currentColor, so they take whatever the
   surrounding text is set to. */
.sps-ico { width: 1em; height: 1em; fill: none; stroke: currentColor; flex: none; }

/* The marquee: a continuous run of console icons under the hero. Pure CSS,
   two identical tracks, duplicated so the loop has no seam. Paused on hover
   and switched off entirely for reduced motion, where it becomes a plain
   centred row. */
.sps-marquee {
	position: relative;
	padding: 1.1rem 0;
	border-block: 1px solid var(--wp--preset--color--rule);
	background: linear-gradient(180deg, rgba(238, 232, 213, 0.03), transparent);
}
/* The mask lives on this inner box and not on .sps-marquee, because a mask
   applies to the whole subtree — including the absolutely-positioned pause
   button, which is anchored to the right edge of the content column and so
   sits right in the fade ramp. Measured: the stop control rendered at 29%
   opacity at 1280px wide and 8% at 1440, i.e. invisible at the two most
   common desktop widths, on the one control WCAG 2.2.2 actually requires.
   Above 1920 the measure caps and the button clears the ramp, which is why
   it looked fine every time it was checked on a big screen. Keeping the
   button a sibling of the masked box fixes it without touching the fade. */
.sps-marquee__viewport {
	overflow: hidden;
	padding-right: clamp(5rem, 9vw, 8rem);
	-webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 84%, transparent 96%);
	mask-image: linear-gradient(90deg, transparent, #000 7%, #000 84%, transparent 96%);
}
.sps-marquee__track {
	display: flex;
	width: max-content;
	animation: sps-marquee 46s linear infinite;
}
/* Each row is itself a flex line. Without this the rows are block boxes and
   the items stack into two vertical columns — which is exactly what it does
   look like when you forget. */
.sps-marquee__row {
	display: flex;
	align-items: center;
	gap: clamp(2rem, 5vw, 4rem);
	padding-inline: var(--sps-gutter);
	flex: none;
}
/* Scoped to the viewport, not to .sps-marquee: with the toggle inside the
   latter, tabbing onto the Pause button paused the strip by itself and left
   the button offering to do the thing it had already done. */
.sps-marquee:hover .sps-marquee__track,
.sps-marquee__viewport:focus-within .sps-marquee__track,
.sps-marquee.is-paused .sps-marquee__track { animation-play-state: paused; }

/* WCAG 2.2.2: anything that moves by itself for more than five seconds needs
   a stop control available to everyone, not just to a mouse. Hidden until
   the script wires it up, so it is never a dead button. */
.sps-marquee__toggle {
	position: absolute;
	/* Anchored to the content column, not to the window. The strip runs full
	   bleed, so `right: 0.5rem` parked this control against the edge of the
	   screen: measured 38px outside the column at 1024px wide, 56px at 1440,
	   and 545px at 2560, where it reads as a stray button adrift in the
	   margin while every other thing on the page lines up. The max() keeps
	   the same 0.5rem breathing room on narrow screens, where the gutter
	   rather than the measure sets the column edge. */
	right: calc(max(var(--sps-gutter), (100% - var(--sps-measure)) / 2) + 0.5rem);
	top: 50%;
	transform: translateY(-50%);
	z-index: 2;
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	min-height: 32px;
	padding: 0.35rem 0.7rem;
	font-family: var(--wp--preset--font-family--display);
	text-transform: uppercase;
	font-size: 0.9rem;
	letter-spacing: 0.04em;
	color: var(--wp--preset--color--cream-2);
	background: var(--wp--preset--color--night);
	border: 1px solid var(--wp--preset--color--rule);
	border-radius: var(--sps-radius);
	cursor: pointer;
}
.sps-marquee__toggle:hover { color: var(--wp--preset--color--cream); border-color: var(--wp--preset--color--amber); }
.sps-marquee__toggle:focus-visible { outline: 2px solid var(--wp--preset--color--amber); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { .sps-marquee__toggle { display: none; } }
.sps-marquee__item {
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	color: var(--wp--preset--color--cream-2);
	font-family: var(--wp--preset--font-family--display);
	text-transform: uppercase;
	font-size: 1.25rem;
	letter-spacing: 0.04em;
	white-space: nowrap;
}
.sps-marquee__item .sps-ico { font-size: 1.6rem; color: var(--wp--preset--color--amber); }
@keyframes sps-marquee {
	from { transform: translateX(0); }
	to   { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
	.sps-marquee__track { animation: none; width: auto; }
	.sps-marquee__row { flex-wrap: wrap; justify-content: center; row-gap: 0.75rem; }
	.sps-marquee { -webkit-mask-image: none; mask-image: none; }
	/* Hide the SECOND row only. This used to select [aria-hidden="true"],
	   which both rows carried, so asking for reduced motion emptied the
	   strip completely — an empty 37px band where seventeen systems should
	   be, for exactly the people the rule exists to protect. The duplicate
	   row is now the only one marked aria-hidden, and this selects it by
	   position so the two can never drift apart again. */
	.sps-marquee__row + .sps-marquee__row { display: none; }
}

/* Without JavaScript the Pause button never comes out of `hidden`, so the
   strip would move by itself for the length of the visit with no way to
   stop it — which is the situation WCAG 2.2.2 is about. If the script has
   not announced itself, the strip is a static centred row instead, the
   same shape reduced motion gets. */
html:not(.sps-js) .sps-marquee__track { animation: none; width: auto; }
html:not(.sps-js) .sps-marquee__row { flex-wrap: wrap; justify-content: center; row-gap: 0.75rem; }
html:not(.sps-js) .sps-marquee__viewport { -webkit-mask-image: none; mask-image: none; padding-right: 0; }
html:not(.sps-js) .sps-marquee__row + .sps-marquee__row { display: none; }

/* The Get in touch column was four links separated by <br> inside one
   paragraph: 21px-tall targets 4.9px apart at phone width, the only pair on
   the site under the 8px proximity guideline. A list with real spacing
   gives each one a 24px box and 10px of clear air. */
.sps-footer__links { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.625rem; }
.sps-footer__links li { margin: 0; }
.sps-footer__links a { display: inline-block; min-height: 24px; }

/* The console browser: every system we carry, as a grid of icon chips that
   link into that search on eBay. Replaces the plain text tag list. */
.sps-consoles {
	display: grid;
	/* 9.5rem, not the 8.5rem this started at, because the track has to hold
	   the longest label and not merely most of them.

	   A chip spends a fixed 62.8px on border, padding, its icon and the gap
	   beside it, so an 8.5rem (136px) track left 76px for type while
	   "PlayStation" in the display face wants 87px. The chips have been
	   overflowing their own boxes at almost every width since this was
	   written; it just never showed, because the spill landed in the page
	   gutter. At 320px there is no gutter to land in — the right-hand
	   column spilled past the viewport and put 9px of horizontal scroll on
	   the whole document.

	   The cost is a column: eight across at 1440 rather than nine, and a
	   single column at 320px. The single column is the honest answer at
	   that width rather than a concession — two chips wide enough for a
	   console name need 2 x 149.9px, the container is 288px, and no amount
	   of tightening the padding closes a 12px gap. */
	grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
	gap: 0.6rem;
}
.sps-console {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	min-height: 44px;
	padding: 0.7rem 0.85rem;
	border: 1px solid var(--wp--preset--color--rule);
	border-radius: var(--sps-radius);
	background: var(--wp--preset--color--panel);
	background-image: linear-gradient(180deg, rgba(238, 232, 213, 0.04), transparent 60%);
	color: var(--wp--preset--color--cream);
	text-decoration: none;
	font-family: var(--wp--preset--font-family--display);
	text-transform: uppercase;
	font-size: 1.125rem;
	letter-spacing: 0.02em;
	line-height: 1;
	/* The backstop behind the track width above, for the states that width
	   cannot anticipate.

	   `anywhere` rather than `break-word`, and the difference is the whole
	   point: only `anywhere` lowers the min-content size, and min-content is
	   the floor the label is actually held at inside a flex row. With
	   `break-word` the unbreakable word still sets that floor and the chip
	   still spills — measured at 320px with the webfont absent, `break-word`
	   left the page 329px wide and `anywhere` brought it to 320px.

	   With the display face loaded this never fires: the track is wide
	   enough now, at every width, with 6px to spare. It fires during the
	   `font-display: swap` window, when the far wider fallback face is on
	   screen, and permanently for anyone whose font request never lands.
	   There it will break PLAYSTATION across two lines mid-word, which is
	   genuinely ugly — but a broken word inside the chip is a better failure
	   than a console name crossing the chip border and dragging the page
	   sideways. */
	overflow-wrap: anywhere;
	transition: border-color 160ms var(--sps-ease), transform 160ms var(--sps-ease), color 160ms var(--sps-ease);
}
.sps-console .sps-ico { font-size: 1.5rem; color: var(--wp--preset--color--amber); transition: color 160ms var(--sps-ease); }
.sps-console:hover {
	border-color: var(--wp--preset--color--red-2);
	color: var(--wp--preset--color--cream);
	transform: translateY(-2px);
}
.sps-console:hover .sps-ico { color: var(--wp--preset--color--red-2); }
@media (prefers-reduced-motion: reduce) {
	.sps-console { transition: none; }
	.sps-console:hover { transform: none; }
}

/* The split feature: an oversized number or icon beside a claim. Used for
   the "how it works" steps on a wide screen and anywhere a section needs a
   change of rhythm. */
.sps-feature {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: clamp(1.5rem, 4vw, 3.5rem);
	align-items: center;
}
@media (min-width: 860px) {
	.sps-feature { grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); }
	.sps-feature--flip > :first-child { order: 2; }
}

/* The stat band: a full-width strip of figures on the deep ground, used to
   break up a long page. */
.sps-band {
	background: var(--wp--preset--color--night-deep);
	background-image:
		linear-gradient(180deg, rgba(238, 232, 213, 0.04), transparent 30%),
		radial-gradient(60% 120% at 50% 0%, rgba(224, 43, 43, 0.12), transparent 70%);
	border-block: 1px solid var(--wp--preset--color--rule);
}

/* A section eyebrow with a rule running off it — the small detail that
   makes a heading look placed rather than typed. */
.sps-label--rule {
	display: flex;
	align-items: center;
	gap: 0.9rem;
}
.sps-label--rule::after {
	content: "";
	height: 1px;
	flex: 1;
	max-width: 8rem;
	background: linear-gradient(90deg, var(--wp--preset--color--rule), transparent);
}


/* ---------------------------------------------------------------
   14. Print
   The reveal system hides what has not been scrolled to, and the
   figures are painted with background-clip, which browsers drop when
   background graphics are off. Printing the sell page from the top
   would otherwise lose the four steps, both buy lists, all four
   reassurance cards and the consignment terms.
   --------------------------------------------------------------- */

@media print {
	.sps-js .sps-reveal,
	.sps-js .sps-reveal > * {
		opacity: 1 !important;
		transform: none !important;
		transition: none !important;
	}
	.sps-figure {
		color: #000 !important;
		background: none !important;
		-webkit-text-fill-color: currentColor;
	}
	.sps-marquee, .sps-marquee__toggle { display: none !important; }
	body { background-image: none; }
}

/* ---------------------------------------------------------------
   15. Channels and the signup band
   --------------------------------------------------------------- */

/* Where else the shop sells, and where to follow it.

   The three social marks are WordPress core's own social-link icons
   (@wordpress/block-library, GPL-2.0-or-later, same licence as this theme),
   copied unmodified to assets/img/{instagram,facebook,tiktok}-mark.svg and
   painted as a CSS mask in currentColor — the same treatment as the eBay
   mark above, for the same reasons plus two more. Five full-colour brand
   logos in a footer row read as a fruit salad; TikTok's own brand colour is
   black, which is invisible on this ground; and Whatnot and Poshmark ship no
   openly-licensed mark, so two of the five are wordmark-only. Monochrome
   cream at rest with a single amber hover keeps all five equals in the row
   rather than making the two icon-less ones look like gaps.

   Every mark is square on a 24 grid, so one square box keeps them optically
   level with the label text without per-brand nudging — the thing the eBay
   wordmark, at 2.5:1, needs its own sizing for.

   The brand name stays as visible text in every chip: it is the accessible
   name, it is what a 44px target needs to be wide enough to hit, and it is
   what makes the icon-less two read as intentional. */
.sps-channels {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-start;
	gap: 1.5rem 3rem;
	margin-top: 2.5rem;
}
/* Label over its list, the same shape as the three footer columns above it.
   Side by side an inline label pushes each row to a different left edge —
   "Also selling on" is wider than "Follow us", so the chips came out ragged
   the moment the groups stacked. Stacked, every row starts flush. */
.sps-channels__group {
	display: grid;
	justify-items: start;
	gap: 0.6rem;
	min-width: 0;
}
.sps-channels ul {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	list-style: none;
	margin: 0;
	padding: 0;
}
.sps-channels .sps-label { flex: none; margin: 0; }
.sps-channels .sps-label--rule::after { display: none; }

.sps-channel {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	/* 44px is the tap target, not the visual height: the padding below draws
	   a 40px-looking chip and the min-height pads it out to the target. */
	min-height: 44px;
	padding: 0.5rem 0.9rem;
	border: 1px solid var(--wp--preset--color--rule);
	border-radius: var(--sps-radius);
	background-color: rgba(22, 33, 62, 0.6);
	background-image: linear-gradient(180deg, rgba(238, 232, 213, 0.05), transparent 55%);
	box-shadow: var(--sps-lift);
	font-family: var(--wp--preset--font-family--display);
	text-transform: uppercase;
	font-size: 1.0625rem;
	letter-spacing: 0.02em;
	line-height: 1;
	text-decoration: none;
	color: var(--wp--preset--color--cream);
	transition:
		border-color 160ms var(--sps-ease),
		color 160ms var(--sps-ease),
		background-color 160ms var(--sps-ease),
		transform 160ms var(--sps-ease),
		box-shadow 160ms var(--sps-ease);
}

/* 1.25em against a 17px chip is ~21px: a touch larger than the cap height so
   the mark reads as a sibling of the word, not a superscript. The -0.05em
   nudge sits it on the optical centre — these glyphs fill their 24 box top to
   bottom, so a flexbox centre leaves them looking a hair low. */
.sps-channel__mark {
	flex: none;
	width: 1.25em;
	height: 1.25em;
	margin-top: -0.05em;
	background-color: currentColor;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center;
	mask-position: center;
	-webkit-mask-size: contain;
	mask-size: contain;
}
.sps-channel__mark--instagram { -webkit-mask-image: url("../img/instagram-mark.svg"); mask-image: url("../img/instagram-mark.svg"); }
.sps-channel__mark--facebook  { -webkit-mask-image: url("../img/facebook-mark.svg");  mask-image: url("../img/facebook-mark.svg"); }
.sps-channel__mark--tiktok    { -webkit-mask-image: url("../img/tiktok-mark.svg");    mask-image: url("../img/tiktok-mark.svg"); }
/* A plain map pin, not the Google "G": the link is to the map listing. */
.sps-channel__mark--google    { -webkit-mask-image: url("../img/google-mark.svg");    mask-image: url("../img/google-mark.svg"); }

/* Whatnot and Poshmark are supplied as finished, full-colour marks — a yellow
   disc and a red rounded square, each with its own background baked in. They
   cannot be masked to currentColor the way the three single-path social
   glyphs can: a mask uses the file's alpha, and both of these are opaque
   edge to edge, so masking would paint a solid block. They are painted as
   background images instead, which means this row deliberately mixes a
   tinted mark with three monochrome ones. The tile below is what reconciles
   them — same box, same radius, same optical weight, so the row reads as one
   set of marks rather than as five different logos dropped in a line. */
.sps-channel__mark--whatnot,
.sps-channel__mark--poshmark {
	background-color: transparent;
	background-repeat: no-repeat;
	background-position: center;
	background-size: contain;
	-webkit-mask-image: none;
	mask-image: none;
	border-radius: 4px;
	/* Slightly larger than the glyphs: a filled mark reads smaller than an
	   outline one at the same box size. */
	width: 1.4em;
	height: 1.4em;
	margin-top: -0.12em;
}
.sps-channel__mark--whatnot  { background-image: url("../img/whatnot-mark.svg"); }
.sps-channel__mark--poshmark { background-image: url("../img/poshmark-mark.webp"); }

/* The chips' hover state recolours `currentColor`, which the two tinted marks
   do not follow. Lift them instead so the row still answers the pointer. */
.sps-channel:hover .sps-channel__mark--whatnot,
.sps-channel:hover .sps-channel__mark--poshmark,
.sps-channel:focus-visible .sps-channel__mark--whatnot,
.sps-channel:focus-visible .sps-channel__mark--poshmark {
	transform: scale(1.08);
}
.sps-channel__mark--whatnot,
.sps-channel__mark--poshmark { transition: transform 180ms var(--sps-ease); }

@media (prefers-reduced-motion: reduce) {
	.sps-channel__mark--whatnot,
	.sps-channel__mark--poshmark,
	.sps-channel:hover .sps-channel__mark--whatnot,
	.sps-channel:hover .sps-channel__mark--poshmark { transition: none; transform: none; }
}

/* The word and the mark move together because the mark is currentColor. */
.sps-channel:hover,
.sps-channel:focus-visible {
	border-color: var(--wp--preset--color--amber);
	color: var(--wp--preset--color--amber);
	background-color: rgba(22, 33, 62, 0.95);
	transform: translateY(-2px);
	box-shadow: var(--sps-lift), var(--sps-shadow);
}
.sps-channel:focus-visible {
	outline: 2px solid var(--wp--preset--color--amber);
	outline-offset: 2px;
}
.sps-channel:active { transform: translateY(0); box-shadow: var(--sps-lift); }

@media (prefers-reduced-motion: reduce) {
	.sps-channel { transition: none; }
	.sps-channel:hover, .sps-channel:focus-visible, .sps-channel:active { transform: none; }
}

/* The signup band. Sits on the deep ground at the foot of the homepage. */
.sps-subscribe {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: clamp(1.5rem, 4vw, 3rem);
}
.sps-subscribe > div { flex: 1 1 22rem; display: grid; gap: 0.5rem; }
.sps-subscribe h2 {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	text-transform: uppercase;
	font-size: var(--wp--preset--font-size--x-large);
	line-height: 1;
	margin: 0;
}
.sps-subscribe p { margin: 0; }
.sps-subscribe__form { flex: 1 1 20rem; display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: flex-start; }
.sps-subscribe__form .sps-field { flex: 1 1 14rem; }
.sps-subscribe__form .wp-block-buttons { flex: none; }
.sps-subscribe__form .wp-block-button__link { min-height: 48px; }

/* The spam question. See inc/captcha.php — it is a text question with a real
   label rather than an image or a puzzle, so it needs no special treatment
   beyond sitting where the eye already is: directly above the button, the
   last thing read before the submit. */
.sps-field--captcha {
	border-top: 1px solid var(--wp--preset--color--rule);
	padding-top: 1.1rem;
	margin-top: 0.4rem;
}
.sps-field--captcha input {
	max-width: 10rem;
}
/* In the newsletter band the form is a single flex row, so the question sits
   in that row beside the email box rather than below it, and the separating
   rule goes — there is nothing above it to separate from. Bottom-aligned,
   because the question needs a label and the email box does not, so without
   it the button floats halfway up the row. */
/* The newsletter box asks the question quietly — the script answers it, so
   nobody signing up for an email list is made to do arithmetic first. Hidden
   only once .sps-js is on the document, which is the same gate the rest of
   the theme uses and the same one that fails open: if the script throws,
   .sps-js comes back off, the field is visible, and the form still works.
   See sps_captcha_html() in inc/captcha.php. */
.sps-js .sps-field--quiet { display: none; }
.sps-subscribe__form .sps-field--captcha {
	flex: 1 1 100%;
	border-top: 0;
	padding-top: 0;
	margin-top: 0;
}
.sps-subscribe__form .sps-field--captcha .sps-field__hint { display: none; }

/* ---------------------------------------------------------------
   16. The header
   Three pieces: a promises strip, the bar itself, and the shrink.
   The Shopify header carried an announcement bar, a logo, a nav and
   a row of shop icons. Without a cart or a search there is room to
   give the logo and the one outbound CTA the space instead.
   --------------------------------------------------------------- */

.sps-topbar {
	background: var(--wp--preset--color--night-deep);
	border-bottom: 1px solid var(--wp--preset--color--rule);
	padding: 0.5rem var(--sps-gutter);
	overflow: hidden;
}
.sps-topbar ul {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 0.4rem 2rem;
	list-style: none;
	margin: 0 auto;
	padding: 0;
	max-width: var(--sps-measure);
}
.sps-topbar li {
	display: inline-flex;
	align-items: center;
	gap: 0.45rem;
	font-family: var(--wp--preset--font-family--display);
	text-transform: uppercase;
	font-size: 0.9375rem;
	letter-spacing: 0.04em;
	line-height: 1.4;
	color: var(--wp--preset--color--cream-2);
	white-space: nowrap;
}
.sps-topbar .sps-ico { font-size: 1.15rem; color: var(--wp--preset--color--amber); }
/* Below the fold of a phone the four promises become a wall of text. Keep the
   two that are actually differentiators. */
@media (max-width: 860px) {
	.sps-topbar li:nth-child(2), .sps-topbar li:nth-child(4) { display: none; }
}
@media (max-width: 520px) {
	.sps-topbar li { font-size: 0.875rem; }
	.sps-topbar li:nth-child(3) { display: none; }
}

/* No transition on either of these, deliberately.
   They change the header's HEIGHT, and the header is in the flow, so the
   browser's scroll anchoring moves the scroll position to match. Animated
   over 220ms that becomes a fifth of a second of the page sliding under the
   cursor — and it fights any momentum scroll still in progress. Instant, the
   same compensation happens in one step and the content simply does not
   move. The strip above disappears instantly anyway (display:none cannot be
   transitioned), so animating the rest only made one change look like two. */
.sps-header__bar { padding-block: 0.9rem; }
.sps-header__brand .wp-block-site-logo { margin: 0; line-height: 0; }
.sps-header__right { gap: clamp(1rem, 2.5vw, 2rem); }

/* Condensed state: once the visitor is past the hero the header gives the
   page its height back, and the promises strip has done its job. */
.sps-header.is-condensed .sps-topbar { display: none; }
.sps-header.is-condensed .sps-header__bar { padding-block: 0.5rem; }
.sps-header.is-condensed .sps-header__brand img { width: 92px !important; }

/* The nav's own submenu, for the category dropdown. */
.wp-block-navigation .wp-block-navigation-submenu__toggle { font: inherit; }
.wp-block-navigation .wp-block-navigation__submenu-container {
	background: var(--wp--preset--color--panel);
	border: 1px solid var(--wp--preset--color--rule);
	border-radius: var(--sps-radius);
	box-shadow: var(--sps-shadow-lg);
	padding: 0.4rem;
	min-width: 15rem;
}
.wp-block-navigation .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
	padding: 0.55rem 0.7rem;
	border-radius: 4px;
	font-size: 1.0625rem;
}
.wp-block-navigation .wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover {
	background: var(--wp--preset--color--night);
	color: var(--wp--preset--color--amber);
}

/* ---------------------------------------------------------------
   17. The hero
   Full-bleed image with a scrim, rather than a picture in a box.
   The scrim is two gradients: one along the reading edge so the type
   always has contrast, one from the foot so the section joins the
   page instead of stopping dead.
   --------------------------------------------------------------- */

.sps-hero {
	position: relative;
	isolation: isolate;
	display: grid;
	align-items: center;
	min-height: clamp(28rem, 66vh, 40rem);
	padding-block: clamp(3rem, 8vw, 6rem);
	overflow: hidden;
}
.sps-hero__media { position: absolute; inset: 0; z-index: -2; }
.sps-hero__media img { width: 100%; height: 100%; object-fit: cover; object-position: 58% 52%; display: block; }
.sps-hero::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background:
		linear-gradient(93deg, var(--wp--preset--color--night) 2%, rgba(26,26,46,0.97) 38%, rgba(26,26,46,0.88) 52%, rgba(26,26,46,0.45) 76%, rgba(26,26,46,0.66) 100%),
		linear-gradient(0deg, var(--wp--preset--color--night) 1%, transparent 34%),
		linear-gradient(180deg, rgba(19,19,42,0.85) 0%, transparent 22%);
}
/* Owns its own measure: relying on a constrained group meant WordPress
   centred the copy block inside it, which is not what a hero does. */
.sps-hero__inner {
	width: 100%;
	max-width: calc(var(--sps-measure) + 2 * var(--sps-gutter));
	margin-inline: auto;
	padding-inline: var(--sps-gutter);
}
/* Saveo in the hero.
 *
 * The inner becomes a two-column grid only when there is room for one: below
 * 68rem the mascot would either crush the headline or shrink to a sticker, so
 * it moves above the copy at a size that still reads as a character rather
 * than an icon, via `order` rather than by being moved in the markup. `min-width: 0` on the copy column is the usual grid guard —
 * without it a long unbroken word in the headline can push the column wider
 * than its track and squeeze the mascot out.
 *
 * It is aria-hidden and alt="": the mascot holds the shop's wordmark, which
 * the site title in the header already announces. Two announcements of the
 * same name is worse than none. */
.sps-hero__copy { max-width: 42rem; min-width: 0; }

.sps-hero__mascot { display: none; }
.sps-hero__mascot img {
	display: block;
	width: 100%;
	height: auto;
	/* A soft drop to lift him off the photograph, matched to the page's own
	   shadow rather than a generic black blur. */
	filter: drop-shadow(0 18px 28px rgba(0, 0, 0, 0.55));
}

@media (min-width: 68rem) {
	.sps-hero__inner {
		display: grid;
		grid-template-columns: minmax(0, 1fr) clamp(17rem, 27vw, 25rem);
		align-items: center;
		gap: clamp(1.5rem, 4vw, 4rem);
	}
	.sps-hero__mascot { display: block; }
}

@media (max-width: 67.99rem) {
	/* The mobile hero has one job the desktop one does not: get the headline
	   and the buttons onto the first screen.
	 *
	 * Measured before this block existed, on a 390x844 phone: the photo ran
	 * to 472, the mascot sat in a band of its own from 528 to 660, the
	 * headline started at 722 and the buttons at 1071 — 227px below the fold,
	 * and on a 360x780 Android the headline itself was cut in half. Two
	 * stacked images were eating the screen before a single word.
	 *
	 * So the mascot loses its band and overlaps the photo instead, pulled up
	 * by a negative margin and lifted a layer so he sits on top of it. He is
	 * in the markup after the copy — reading order stays headline-first for
	 * anything ignoring CSS — and `order` moves him visually, which is only
	 * safe because he is decorative and aria-hidden.
	 */
	.sps-hero__inner {
		display: flex;
		flex-direction: column;
		align-items: flex-start;
	}
	.sps-hero__copy { width: 100%; }
	.sps-hero__mascot {
		display: block;
		order: -1;
		width: clamp(8rem, 26vw, 12rem);
		margin: 0 0 1rem;
	}
}
.sps-hero__copy h1 {
	/* Two steps down from the display size. Over a photograph the headline
	   is competing with the picture rather than sitting on empty ground, and
	   the full display scale simply swamps it. */
	font-size: clamp(2.6rem, 5.4vw, 5.1rem);
	line-height: 0.94;
}
.sps-hero__copy .sps-deck { max-width: 42ch; font-size: 1.1875rem; }

/* The two-line proof under the buttons. Small, quiet, checkable. */
.sps-hero__proof {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem 1.75rem;
	list-style: none;
	margin: 1.75rem 0 0;
	padding: 1.25rem 0 0;
	border-top: 1px solid var(--wp--preset--color--rule);
	max-width: 34rem;
}
.sps-hero__proof li {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	font-size: 0.9375rem;
	color: var(--wp--preset--color--cream-2);
}
.sps-hero__proof .sps-ico { font-size: 1.25rem; color: var(--wp--preset--color--amber); }

@media (max-width: 700px) {
	/* On a phone the photograph is mostly hidden behind the scrim anyway;
	   let it sit above the copy where it can actually be seen. */
	.sps-hero { min-height: 0; padding-top: 0; }
	/* 16/9 rather than 16/10, and no bottom margin: the photo gives back
	   ~24px of a screen that had none to spare, and loses only empty floor. */
	.sps-hero__media { position: relative; inset: auto; z-index: 0; aspect-ratio: 16/9; margin-bottom: 0; }

	/* Saveo overlaps the photo rather than sitting in a band below it. That
	   band cost ~150px on a screen where the buttons were already 227px below
	   the fold. He needs the layer as well as the pull: the media block is
	   z-index 0 here, so a statically positioned mascot would slide behind
	   the photograph instead of onto it. */
	.sps-hero__mascot {
		align-self: flex-end;
		position: relative;
		z-index: 1;
		width: clamp(8rem, 32vw, 12rem);
		margin: calc(-1 * clamp(3rem, 11vw, 4.5rem)) 0 0.5rem 0;
	}
	.sps-hero::after { background: linear-gradient(0deg, var(--wp--preset--color--night) 60%, transparent 100%); }

	/* Everything below buys back vertical space so the buttons land on the
	   first screen. Measured on a 390x844 phone, they started 227px under the
	   fold; a hero whose call to action needs a scroll is decoration.
	 *
	 * The top bar goes first, and not reluctantly: its one surviving line on
	 * a phone is a trust claim that the hero's own proof list repeats a few
	 * hundred pixels later. Paying 37px to say the same thing twice is the
	 * easiest cut on the page. It returns the moment there is room for it. */
	.sps-topbar { display: none; }

	/* The deck is six lines at 19px on a 355px column. Supporting copy set
	   at nearly body-plus size, six lines deep, between the headline and the
	   button is the other thing standing in the way. */
	.sps-hero__copy .sps-deck {
		font-size: 1.0625rem;
		line-height: 1.5;
	}
	.sps-hero__copy .wp-block-buttons { margin-top: 1.5rem !important; }

	/* Cap the photo by height, not by width: on a wide phone a 16/9 block
	   keeps growing with the viewport and takes the space back again.
	 *
	 * `width: 100%` is not redundant here, it is the fix for the bug the
	 * first version of this rule shipped. `aspect-ratio` plus `max-height`
	 * and nothing else makes the box solve for WIDTH to keep the ratio: the
	 * height gets capped, the width shrinks to match, and the photo stops
	 * short of the right edge of the phone with a strip of background beside
	 * it. Pinning the width makes the ratio give way instead, and object-fit
	 * on the image crops rather than letterboxes. */
	.sps-hero__media { width: 100%; max-height: 26vh; }
	.sps-hero__media img { width: 100%; height: 100%; object-fit: cover; }
}

/* ---------------------------------------------------------------
   18. The four marks
   --------------------------------------------------------------- */

.sps-marks {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
	gap: 1rem;
}
.sps-mark {
	display: grid;
	gap: 0.7rem;
	align-content: start;
	padding: clamp(1.4rem, 2.5vw, 2rem);
	background: var(--wp--preset--color--panel);
	background-image: linear-gradient(180deg, rgba(238,232,213,0.045), transparent 45%);
	border: 1px solid var(--wp--preset--color--rule);
	border-radius: var(--sps-radius);
	box-shadow: var(--sps-lift), var(--sps-shadow);
}
.sps-mark__icon {
	display: grid;
	place-items: center;
	width: 3rem;
	height: 3rem;
	border-radius: 50%;
	border: 1px solid var(--wp--preset--color--red);
	background: rgba(224, 43, 43, 0.12);
	color: var(--wp--preset--color--red-text);
}
.sps-mark__icon .sps-ico { font-size: 1.6rem; }
.sps-mark h3 {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	text-transform: uppercase;
	font-size: 1.5rem;
	line-height: 1.05;
	margin: 0;
	color: var(--wp--preset--color--cream);
}
.sps-mark p { margin: 0; font-size: 1rem; line-height: 1.55; color: var(--wp--preset--color--cream-2); }

/* ---------------------------------------------------------------
   19. Category tiles, image-led
   The first version put a small illustration in a mostly empty card
   and the section read as five grey boxes. Give the artwork its own
   plate at the top of the tile, with the number and label sitting on
   it and the words underneath — which is why the Shopify category
   tiles worked and these did not.

   To swap an illustration for a photograph: replace the <img> and add
   class="sps-tile__photo" to it. Nothing else changes.
   --------------------------------------------------------------- */

.sps-tile { padding: 0; overflow: hidden; gap: 0; }

.sps-tile__media {
	position: relative;
	display: grid;
	place-items: center;
	aspect-ratio: 16 / 11;
	padding: 1rem;
	background:
		radial-gradient(120% 90% at 50% 18%, rgba(245,166,35,0.12), transparent 64%),
		linear-gradient(180deg, var(--wp--preset--color--night-deep), var(--wp--preset--color--panel));
	border-bottom: 1px solid var(--wp--preset--color--rule);
}
.sps-tile__media .sps-tile__icon {
	max-width: 60%;
	width: auto;
	max-height: 82%;
	margin: 0;
}
/* A real photograph fills the plate instead of floating on it. */
.sps-tile__media .sps-tile__photo {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	max-width: none;
	max-height: none;
	object-fit: cover;
	filter: none;
}
.sps-tile__media .sps-tile__num { position: absolute; top: 0.85rem; left: 1rem; }
.sps-tile__media .sps-label--muted { position: absolute; top: 0.85rem; right: 1rem; text-align: right; }

.sps-tile__body {
	display: grid;
	gap: 0.5rem;
	align-content: start;
	padding: 1.25rem 1.25rem 1.4rem;
}
.sps-tile__body .sps-label--red { margin-top: 0.35rem; }

/* Three across at full width; two reads better than three-plus-an-orphan on
   a tablet, and five tiles always leave one over somewhere. */
.sps-tiles { grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr)); }

/* Five tiles into an auto-fit grid gives four across and a lonely fifth.
   Three across with the last one spanning two fills both rows exactly, and
   reads as a decision rather than a leftover. The wide tile gets a letterbox
   plate so it does not tower over its neighbour. */
@media (min-width: 62rem) {
	.sps-tiles { grid-template-columns: repeat(3, minmax(0, 1fr)); }
	.sps-tiles > :last-child { grid-column: span 2; }
	/* The wide plate has to end at the same height as its neighbour's, or the
	   two headings on that row sit at different levels. A narrow plate is
	   16/11 of one column; the wide tile is two columns plus the gap, which
	   works out at very close to 2.97 across every desktop width. */
	.sps-tiles > :last-child .sps-tile__media { aspect-ratio: 2.97; }
	.sps-tiles > :last-child .sps-tile__media .sps-tile__icon { max-width: 26%; }
	.sps-tiles > :last-child .sps-tile__body p { max-width: 54ch; }
}

/* ---------------------------------------------------------------
   20. The news section
   A block theme sizes an h2 inside post content from the same token
   the homepage bays use — clamp(2.4rem, 5.2vw, 5.25rem). That is
   right for a section heading and absurd four paragraphs into an
   article, where it lands mid-sentence and reads as a mistake. So
   .sps-prose re-scales headings for reading rather than for
   scanning. Nothing outside an article body is touched, which is
   why the reset is scoped to the class and not to the template.
   --------------------------------------------------------------- */

/* Breadcrumbs. A real <nav> with an aria-label, because the trail is
   the only way back up from a post that was landed on from search. */
.sps-crumbs {
	font-family: var(--wp--preset--font-family--display);
	text-transform: uppercase;
	letter-spacing: 0.03em;
	font-size: 0.9375rem;
	line-height: 1.4;
	color: var(--wp--preset--color--cream-2);
}
.sps-crumbs ol {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.15rem 0.55rem;
}
.sps-crumbs a { color: var(--wp--preset--color--cream-2); text-decoration: none; }
.sps-crumbs a:hover { color: var(--wp--preset--color--amber); }
.sps-crumbs li + li::before {
	content: "/";
	margin-right: 0.55rem;
	color: var(--wp--preset--color--rule);
}
.sps-crumbs [aria-current="page"] { color: var(--wp--preset--color--cream); }
/* The last crumb is the whole post title, which on a phone is three lines of
   uppercase under a trail that is already two. Give it the row to itself and
   clip it — the title is directly below in 2rem type, so nothing is lost. */
@media (max-width: 600px) {
	.sps-crumbs li:last-child { flex: 1 1 100%; min-width: 0; }
	.sps-crumbs [aria-current="page"] {
		display: block;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}
}

/* The inline meta line: date, reading time, category. Separated by a
   middle dot rather than put in a table, and wrapping cleanly on a
   phone instead of pushing the column wider. */
.sps-postmeta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.25rem 0.85rem;
	font-family: var(--wp--preset--font-family--display);
	text-transform: uppercase;
	letter-spacing: 0.04em;
	font-size: 0.9375rem;
	line-height: 1.5;
	color: var(--wp--preset--color--cream-2);
	margin-block: 0;
}
/* The dot belongs to the item BEFORE it, not the one after. As a ::before on
   the following item it leads the next line whenever the row wraps — which a
   three-item meta row does on every phone — and a line that opens with a
   floating interpunct reads as a typo. */
.sps-postmeta > :not(:last-child)::after {
	content: "·";
	margin-left: 0.85rem;
	color: var(--wp--preset--color--rule);
}
.sps-postmeta a { color: var(--wp--preset--color--amber); text-decoration: none; }
.sps-postmeta a:hover { text-decoration: underline; }
.sps-postmeta time { font-variant-numeric: tabular-nums; }

/* The article head. The h1 comes down off the display token — a
   nine-word headline at 9.5rem is four lines of shouting — and the
   deck under it is the excerpt, which is also the meta description,
   so the page and the search result say the same thing. */
.sps-article__head { max-width: 52rem; }
.sps-article__head h1 {
	font-size: clamp(2.2rem, 5.4vw, 4rem);
	line-height: 0.98;
	margin-top: 1.1rem;
}
.sps-article__head .sps-deck { max-width: 54ch; margin-top: 1.1rem; }
.sps-article__head .sps-postmeta { margin-top: 1.4rem; }

/* The lead image runs to the wide measure while the prose keeps its
   44rem, so the article opens wide and then narrows to read. */
.sps-article__media { margin-block: clamp(2rem, 4vw, 3rem); }

/* The head and the lead image run to the bay's 1320px; the prose narrows to
   a reading measure inside the same bay, so the article opens wide and then
   settles. `margin-block` rather than `margin`, because the shorthand would
   cancel the inline inset every bay child depends on. */
.sps-bay > .sps-article__body { max-width: 44rem; }

/* A page of continuous prose, not a marketing bay. Without this the policy
   ran the full 1320px measure — 104 characters a line at 1280px wide, where
   comfortable is 45 to 75 — and it did so whichever of page.html and
   page-wide.html the page happened to be assigned, because the constraint
   was on the template rather than on the content. */
.sps-bay--prose > * { max-width: 44rem; }
.sps-bay--prose > .sps-bay__head { max-width: none; }
.sps-bay--prose > .sps-bay__head > * { max-width: 44rem; }
.sps-article__media img {
	width: 100%;
	height: auto;
	border-radius: var(--sps-radius);
	border: 1px solid var(--wp--preset--color--rule);
}

/* ---- The article body ---------------------------------------- */

.sps-prose { font-size: 1.125rem; line-height: 1.72; }
.sps-prose > * + * { margin-top: 1.35rem; }

.sps-prose h2 {
	font-size: clamp(1.75rem, 3.4vw, 2.5rem);
	line-height: 1.02;
	margin-top: 3.2rem;
	padding-top: 2.1rem;
	border-top: 1px solid var(--wp--preset--color--rule);
}
.sps-prose h3 {
	font-size: clamp(1.35rem, 2.4vw, 1.75rem);
	line-height: 1.1;
	margin-top: 2.4rem;
}
.sps-prose h4 {
	font-size: 1.1875rem;
	line-height: 1.2;
	margin-top: 1.9rem;
	color: var(--wp--preset--color--amber);
}
/* The first heading follows the lead image, not a wall of text, so the
   rule above it is a divider with nothing to divide. */
.sps-prose > :first-child { margin-top: 0; }
.sps-prose > h2:first-child { border-top: 0; padding-top: 0; }

/* A link in running text has to look like one. Cream on navy with no
   underline is invisible mid-paragraph — amber underline at an offset
   reads as a link without breaking the line rhythm. */
.sps-prose p a,
.sps-prose li a {
	color: var(--wp--preset--color--cream);
	text-decoration: underline;
	text-decoration-color: var(--wp--preset--color--amber);
	text-underline-offset: 0.18em;
	text-decoration-thickness: 1px;
}
.sps-prose p a:hover,
.sps-prose li a:hover {
	color: var(--wp--preset--color--amber);
	text-decoration-thickness: 2px;
}

.sps-prose ul,
.sps-prose ol { padding-left: 1.3rem; }
.sps-prose li + li { margin-top: 0.5rem; }
.sps-prose ul { list-style: none; padding-left: 0; }
.sps-prose ul li {
	position: relative;
	padding-left: 1.6rem;
}
/* The same amber tick the sell page uses for its promises — one mark
   across the site rather than a disc here and a check there. */
.sps-prose ul li::before {
	content: "";
	position: absolute;
	left: 0.1rem;
	top: 0.56em;
	width: 0.6rem;
	height: 0.32rem;
	border-left: 2px solid var(--wp--preset--color--amber);
	border-bottom: 2px solid var(--wp--preset--color--amber);
	transform: rotate(-45deg);
}
.sps-prose ol { list-style: decimal; }
.sps-prose ol li::marker {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	color: var(--wp--preset--color--amber);
}

.sps-prose blockquote {
	margin-left: 0;
	margin-right: 0;
	padding-left: 1.3rem;
	border-left: 2px solid var(--wp--preset--color--red-2);
	color: var(--wp--preset--color--cream);
	font-size: 1.1875rem;
}
.sps-prose blockquote p { margin: 0; }
.sps-prose blockquote cite {
	display: block;
	margin-top: 0.7rem;
	font-style: normal;
	font-size: 0.875rem;
	color: var(--wp--preset--color--cream-2);
}

.sps-prose img { border-radius: var(--sps-radius); height: auto; }
.sps-prose figcaption {
	font-size: 0.875rem;
	color: var(--wp--preset--color--cream-2);
	margin-top: 0.6rem;
}
.sps-prose hr {
	border: 0;
	border-top: 1px solid var(--wp--preset--color--rule);
	margin: 2.6rem 0;
}
.sps-prose strong { color: var(--wp--preset--color--cream); font-weight: 700; }

/* A definition panel — "CIB", "loose", "boxed". Not a blockquote,
   because it is not a quotation, and the editor would style it as one
   for anyone who came along later. */
.sps-callout {
	background: var(--wp--preset--color--panel);
	border: 1px solid var(--wp--preset--color--rule);
	border-left: 3px solid var(--wp--preset--color--amber);
	border-radius: var(--sps-radius);
	padding: 1.15rem 1.3rem;
	box-shadow: var(--sps-lift);
}
.sps-callout p { margin: 0; font-size: 1.0625rem; }
.sps-callout p + p { margin-top: 0.7rem; }
.sps-callout .sps-label { display: block; margin-bottom: 0.4rem; }

/* An in-article CTA. Quieter than the sell band at the foot — this one
   sits mid-read and must not look like an advertisement dropped into
   the page. */
.sps-inline-cta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 1rem 1.5rem;
	background: var(--wp--preset--color--panel-2);
	border: 1px solid var(--wp--preset--color--rule);
	border-radius: var(--sps-radius);
	padding: 1.3rem 1.5rem;
	box-shadow: var(--sps-lift), var(--sps-shadow);
}
.sps-inline-cta__text { flex: 1 1 18rem; }
.sps-inline-cta__text p { margin: 0; }
.sps-inline-cta__text p + p { margin-top: 0.35rem; font-size: 1rem; color: var(--wp--preset--color--cream-2); }
.sps-inline-cta .wp-block-button__link { white-space: nowrap; }

/* ---- Foot of the article -------------------------------------- */

.sps-article__foot {
	margin-top: clamp(2.5rem, 5vw, 4rem);
	padding-top: 2rem;
	border-top: 1px solid var(--wp--preset--color--rule);
	display: grid;
	gap: 1.75rem;
}

.sps-share {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.6rem;
}
.sps-share__label { margin: 0 0.35rem 0 0; }
.sps-share a,
.sps-share button {
	display: inline-flex;
	align-items: center;
	gap: 0.45rem;
	font-family: var(--wp--preset--font-family--display);
	text-transform: uppercase;
	letter-spacing: 0.02em;
	font-size: 1rem;
	line-height: 1;
	padding: 0.55rem 0.85rem;
	border: 1px solid var(--wp--preset--color--rule);
	border-radius: var(--sps-radius);
	background: var(--wp--preset--color--night);
	color: var(--wp--preset--color--cream);
	text-decoration: none;
	cursor: pointer;
	transition: border-color 0.2s var(--sps-ease), color 0.2s var(--sps-ease);
}
.sps-share a:hover,
.sps-share button:hover {
	border-color: var(--wp--preset--color--amber);
	color: var(--wp--preset--color--amber);
}
.sps-share svg { width: 1rem; height: 1rem; fill: currentColor; }
.sps-share button[data-copied="1"] { border-color: var(--wp--preset--color--amber); color: var(--wp--preset--color--amber); }

/* ---- Related, and the archive grid ---------------------------- */

/* The post template renders a <ul> of <li>, so the grid goes on the list and
   the card fills the item. Keeping the card and the list item as separate
   objects is what lets the related grid — which is built in PHP, not by a
   query loop — use exactly the same markup and the same rules. */
.sps-postgrid {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(19rem, 1fr));
	gap: 1.25rem;
}
.sps-postgrid > li { display: flex; margin: 0; }
.sps-postgrid > li::before { content: none; }
@media (min-width: 62rem) {
	.sps-postgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.sps-post {
	flex: 1 1 auto;
	min-width: 0;
	display: flex;
	flex-direction: column;
	background: var(--wp--preset--color--panel);
	border: 1px solid var(--wp--preset--color--rule);
	border-radius: var(--sps-radius);
	overflow: hidden;
	box-shadow: var(--sps-lift);
	transition: transform 0.28s var(--sps-ease), border-color 0.28s var(--sps-ease), box-shadow 0.28s var(--sps-ease);
}
.sps-post:hover {
	transform: translateY(-3px);
	border-color: var(--wp--preset--color--rule);
	box-shadow: var(--sps-lift), var(--sps-shadow);
}
.sps-post__media { margin: 0; }
.sps-post__media img,
.sps-post__media .wp-block-post-featured-image img {
	display: block;
	width: 100%;
	aspect-ratio: 16 / 10;
	object-fit: cover;
	border-radius: 0;
}
/* No image yet is a labelled plate, not a collapsed card — the grid has
   to hold its shape from the first post, before there is artwork. */
.sps-post__media:empty,
.sps-post__media .wp-block-post-featured-image:empty {
	aspect-ratio: 16 / 10;
	background:
		linear-gradient(135deg, transparent 47%, var(--wp--preset--color--rule) 47%, var(--wp--preset--color--rule) 53%, transparent 53%),
		var(--wp--preset--color--night-deep);
	background-size: 14px 14px, auto;
	display: block;
}
.sps-post__body {
	display: flex;
	flex-direction: column;
	gap: 0.55rem;
	padding: 1.15rem 1.25rem 1.4rem;
	flex: 1 1 auto;
}
.sps-post__body h3,
.sps-post__body .wp-block-post-title {
	font-size: 1.4rem;
	line-height: 1.08;
	margin: 0;
}
.sps-post__body .wp-block-post-title a { text-decoration: none; }
.sps-post__body .wp-block-post-excerpt {
	font-size: 1rem;
	line-height: 1.55;
	color: var(--wp--preset--color--cream-2);
	margin: 0;
}
.sps-post__body .wp-block-post-excerpt__more-text { display: none; }

/* The newest post earns the width, but only on the first page — page two
   of an archive has no "lead" — and only when there are enough behind it
   to fill the row it leaves. Two posts spanning is just a wide gap. */
@media (min-width: 62rem) {
	body:not(.paged) .sps-postgrid > li:first-child:nth-last-child(n+4) { grid-column: span 2; }
	body:not(.paged) .sps-postgrid > li:first-child:nth-last-child(n+4) .sps-post { flex-direction: row; }
	body:not(.paged) .sps-postgrid > li:first-child:nth-last-child(n+4) .sps-post > * { flex: 1 1 0; min-width: 0; }
	body:not(.paged) .sps-postgrid > li:first-child:nth-last-child(n+4) .sps-post__media img { height: 100%; aspect-ratio: auto; }
	body:not(.paged) .sps-postgrid > li:first-child:nth-last-child(n+4) .sps-post__body { justify-content: center; padding: 1.8rem; }
	body:not(.paged) .sps-postgrid > li:first-child:nth-last-child(n+4) .sps-post__body h3,
	body:not(.paged) .sps-postgrid > li:first-child:nth-last-child(n+4) .sps-post__body .wp-block-post-title { font-size: 1.9rem; }
}

/* Category chips above the grid. The current one is filled, so the page
   says what it is filtering by without a sentence explaining it. */
.sps-chips {
	list-style: none;
	/* margin-block, not the shorthand: the chip row IS a direct child of the
	   bay on every archive, and `margin: 0 0 x` cancels the inline inset that
	   lines bay children up with the heading above them. */
	margin-block: 0 clamp(1.75rem, 3vw, 2.5rem);
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
}
.sps-chips a {
	display: inline-block;
	font-family: var(--wp--preset--font-family--display);
	text-transform: uppercase;
	letter-spacing: 0.02em;
	font-size: 1rem;
	line-height: 1;
	padding: 0.55rem 0.9rem;
	border: 1px solid var(--wp--preset--color--rule);
	border-radius: var(--sps-radius);
	color: var(--wp--preset--color--cream);
	background: var(--wp--preset--color--night);
	text-decoration: none;
	transition: border-color 0.2s var(--sps-ease), color 0.2s var(--sps-ease);
}
.sps-chips a:hover { border-color: var(--wp--preset--color--amber); color: var(--wp--preset--color--amber); }
.sps-chips [aria-current="page"] {
	background: var(--wp--preset--color--panel-2);
	border-color: var(--wp--preset--color--amber);
	color: var(--wp--preset--color--amber);
}
.sps-chips .sps-chips__count { color: var(--wp--preset--color--cream-2); font-size: 0.875rem; }

/* Tags at the foot. Not .sps-postmeta: that row puts a dot between its
   children, and post-terms renders every tag as a child — which would
   produce a dot between each tag and another before the "Tagged:" prefix. */
.sps-posttags {
	font-family: var(--wp--preset--font-family--display);
	text-transform: uppercase;
	letter-spacing: 0.03em;
	font-size: 0.9375rem;
	line-height: 1.7;
	color: var(--wp--preset--color--cream-2);
}
.sps-posttags a {
	color: var(--wp--preset--color--cream);
	text-decoration: none;
	border-bottom: 1px solid var(--wp--preset--color--rule);
}
.sps-posttags a:hover { color: var(--wp--preset--color--amber); border-bottom-color: var(--wp--preset--color--amber); }

/* The related section is emitted whole by PHP, including its own bay, so
   that a blog with one post in it drops the section rather than showing a
   ruled band with a heading and nothing under it. */
.sps-related { padding-block: var(--wp--preset--spacing--60); }
.sps-related__head { margin-bottom: 1.5rem; }
.sps-related .sps-postgrid { grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); }
@media (min-width: 62rem) {
	.sps-related .sps-postgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* Pagination, restyled off core's centred text links. */
.wp-block-query-pagination {
	font-family: var(--wp--preset--font-family--display);
	text-transform: uppercase;
	letter-spacing: 0.02em;
	font-size: 1.0625rem;
}
.wp-block-query-pagination a { text-decoration: none; }
.wp-block-query-pagination .page-numbers {
	display: inline-block;
	min-width: 2.35rem;
	text-align: center;
	padding: 0.45rem 0.6rem;
	border: 1px solid transparent;
	border-radius: var(--sps-radius);
	line-height: 1;
}
.wp-block-query-pagination .page-numbers:hover { border-color: var(--wp--preset--color--rule); color: var(--wp--preset--color--amber); }
.wp-block-query-pagination .page-numbers.current {
	border-color: var(--wp--preset--color--amber);
	color: var(--wp--preset--color--amber);
	background: var(--wp--preset--color--panel);
}

/* ---- Print ---------------------------------------------------- */

@media print {
	.sps-share,
	.sps-related,
	.sps-inline-cta,
	.sps-crumbs { display: none; }
	.sps-prose h2 { border-top: 0; padding-top: 0; }
}

/* ---------------------------------------------------------------
   Saveo with the cash bag
   ---------------------------------------------------------------
   The mascot from the Shopify "We buy collections" page. He reads as
   "we hand you money for this", so he belongs on the sell-to-us side
   only — on the buy-from-us sections the same picture argues the
   wrong way round.
   Decorative in both places: the heading and the list carry the
   message, so he is aria-hidden and never the only thing saying it. */

/* Under the Get a quote button, not beside the headline: the heading
   column is the tall one, so putting him there left a hole under the
   button and made the card lopsided. Here he balances it and lands
   where the offer is being made. */
.sps-band__mascot { margin-top: clamp(1.5rem, 3vw, 2.25rem); }
.sps-band__mascot img {
	display: block;
	width: clamp(8rem, 18vw, 13rem);
	height: auto;
	filter: drop-shadow(0 18px 28px rgba(0, 0, 0, 0.55));
}

/* On the sell page he sits beside the headline, but only once there is
   room for a real column. Below that the page has one job — get the
   offer and the Get a quote button onto the first screen — and a
   300px dragon above the headline is the same mistake the home hero
   already had to be rescued from. */
.sps-sellhero__mascot { display: none; }
.sps-sellhero__mascot img {
	display: block;
	width: 100%;
	height: auto;
	filter: drop-shadow(0 18px 28px rgba(0, 0, 0, 0.55));
}

@media (min-width: 60rem) {
	.sps-sellhero {
		display: grid;
		grid-template-columns: minmax(0, 1fr) clamp(13rem, 21vw, 19rem);
		align-items: center;
		gap: clamp(2rem, 5vw, 4rem);
	}
	.sps-sellhero__mascot { display: block; }
}

/* The footer brand is the logo, not the words. The site title stays in the
   markup as screen-reader text so the footer still announces whose site this
   is — the same pairing the header uses, because an <img> alone leaves a
   landmark with no accessible name. */
.sps-footer__logo { margin-bottom: 1.25rem; }
.sps-footer__logo img { display: block; height: auto; }
