/* ==========================================================================
   shop.css — the product card, the shop archive and its filters.

   The card is the one component that appears on five screens (home grid, shop
   archive, category archive, tag archive, related strip). Everything about it
   is declared once here and varied only by an image height, so those screens
   cannot drift apart.

   Mobile-first. Single breakpoint at 900px, always min-width.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. The product card
   -------------------------------------------------------------------------- */

.cd-pcard {
	position: relative;
	display: flex;
	flex-direction: column;
	min-width: 0;

	/* Overridden per variant; every other measurement is shared. */
	--cd-pcard-img: 158px;
}

.cd-pcard__media {
	position: relative;
	border-radius: 9px;
	overflow: hidden;
	background: var(--cd-chip);
}

.cd-pcard__img {
	display: block;
	width: 100%;
	height: var(--cd-pcard-img);
	object-fit: cover;
	border-radius: inherit;
}

.cd-pcard__img--placeholder {
	object-fit: contain;
	padding: 18%;
	opacity: .35;
}

/* Title — the card's only tab stop, stretched over the whole card. */
.cd-pcard__title {
	margin: 8px 0 0;
	font: 700 12.5px/1.3 var(--cd-sans);
	letter-spacing: -.005em;
	color: var(--cd-ink);
	text-wrap: pretty;
	min-height: 2.6em;
}

.cd-pcard__title a {
	color: inherit;
	text-decoration: none;
}

.cd-pcard__title a:hover {
	text-decoration: underline;
	text-underline-offset: 2px;
	text-decoration-thickness: 1.5px;
}

/* The stretched hit area sits under the flag and stamp, never over them. */
.cd-pcard .cd-stretched::after {
	border-radius: 9px;
}

.cd-pcard__spec {
	margin: 4px 0 0;
	font: 400 10.5px/1.4 var(--cd-mono);
	font-variant-numeric: tabular-nums;
	color: var(--cd-ink-soft);
}

.cd-pcard .cd-price {
	margin: 5px 0 0;
}

.cd-pcard__meta {
	display: flex;
	align-items: center;
	gap: 6px;
	margin: 6px 0 0;
}

.cd-pcard__meta .cd-grade {
	font-size: 9.5px;
	flex: none;
}

.cd-pcard__listed {
	font: 500 10px var(--cd-sans);
	color: var(--cd-ink-faint);
	font-variant-numeric: tabular-nums;
}

/* The kit flag. Smaller and tighter to the corner on a small card. */
.cd-pcard .cd-flag {
	top: 8px;
	left: 8px;
	font-size: 8.5px;
	letter-spacing: .07em;
	padding: 3px 6px;
}

/* -- sold ------------------------------------------------------------------
   The item stays in the grid. Colour alone never carries the message: the
   stamp is the word SOLD, the price is struck through, the spec line says how
   fast it went and the link's accessible name ends in "— sold".
   -------------------------------------------------------------------------- */

.cd-pcard.is-sold .cd-pcard__title {
	color: var(--cd-ink-soft);
}

.cd-pcard.is-sold .cd-pcard__spec {
	color: var(--cd-ink-faint);
	text-transform: lowercase;
}

.cd-pcard .cd-sold-stamp > span {
	font-size: 10px;
	padding: 4px 8px;
}

.cd-price--sold .cd-price__amount {
	color: var(--cd-ink-faint);
}

.cd-price--sold s {
	text-decoration: line-through;
	text-decoration-thickness: 1.5px;
}

/* Not a link: the whole card already is one, and nesting a second control
   inside it would break the single-tab-stop contract. */
.cd-pcard__cta {
	align-self: flex-start;
	margin: 6px 0 0;
	padding-bottom: 2px;
	font: 600 11px var(--cd-sans);
	color: var(--cd-ink);
	border-bottom: 2px solid var(--cd-accent);
}

/* -- variants -------------------------------------------------------------- */

.cd-pcard--home {
	--cd-pcard-img: 172px;
}

.cd-pcard--home .cd-pcard__media,
.cd-pcard--home .cd-stretched::after {
	border-radius: var(--cd-r-image);
}

.cd-pcard--home .cd-pcard__title {
	margin-top: 9px;
	min-height: 2.65em;
}

.cd-pcard--home .cd-pcard__spec {
	min-height: 2.85em;
}

.cd-pcard--home .cd-price {
	margin-top: 7px;
}

.cd-pcard--home .cd-pcard__meta {
	margin-top: auto;
	padding-top: 6px;
}

/* The archive's 2-up phone card drops the spec line — at 171px wide the title,
   price and grade are what a thumb is scanning for. */
.cd-pcard--archive .cd-pcard__spec {
	display: none;
}

.cd-pcard--related {
	--cd-pcard-img: 140px;
}

.cd-pcard--related .cd-pcard__title {
	min-height: 0;
}

.cd-pcard--related .cd-price {
	margin-top: 6px;
}

.cd-pcard--related .cd-price__amount {
	font-size: 15px;
}

@media (min-width: 900px) {
	.cd-pcard {
		--cd-pcard-img: 228px;
	}

	.cd-pcard__media,
	.cd-pcard .cd-stretched::after {
		border-radius: var(--cd-r-image);
	}

	.cd-pcard__title {
		margin-top: 11px;
		font-size: 14.5px;
		min-height: 0;
	}

	.cd-pcard__spec {
		margin-top: 5px;
		font-size: 11.5px;
	}

	.cd-pcard--archive .cd-pcard__spec {
		display: block;
	}

	.cd-pcard .cd-price {
		margin-top: 9px;
	}

	.cd-pcard__meta {
		gap: 8px;
		margin-top: 9px;
	}

	.cd-pcard__meta .cd-grade {
		font-size: 10px;
	}

	.cd-pcard__listed {
		font-size: 11px;
	}

	.cd-pcard .cd-flag {
		top: 10px;
		left: 10px;
		font-size: 9.5px;
		letter-spacing: .08em;
		padding: 4px 7px;
	}

	.cd-pcard .cd-sold-stamp > span {
		font-size: 12.5px;
		padding: 6px 12px;
		letter-spacing: .1em;
	}

	.cd-pcard__cta {
		margin-top: 9px;
		font-size: 12px;
	}

	.cd-pcard--home {
		--cd-pcard-img: 212px;
	}

	.cd-pcard--home .cd-pcard__title,
	.cd-pcard--home .cd-pcard__spec {
		min-height: 0;
	}

	.cd-pcard--home .cd-pcard__meta {
		margin-top: 9px;
		padding-top: 0;
	}

	.cd-pcard--related {
		--cd-pcard-img: 180px;
	}

	.cd-pcard--related .cd-pcard__title {
		margin-top: 9px;
		font-size: 13.5px;
	}

	.cd-pcard--related .cd-price {
		margin-top: 6px;
	}

	.cd-pcard--related .cd-price__amount {
		font-size: 15px;
	}
}

/* --------------------------------------------------------------------------
   2. Card grids
   -------------------------------------------------------------------------- */

.cd-pgrid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 20px 12px;
}

/* The home row is a swipeable strip of fixed-width cards on a phone. */
.cd-pgrid--scroll {
	display: flex;
	align-items: stretch;
	gap: 12px;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
	-webkit-overflow-scrolling: touch;
	margin-inline: calc(var(--cd-gutter) * -1);
	padding-inline: var(--cd-gutter);
}

.cd-pgrid--scroll::-webkit-scrollbar {
	display: none;
}

/* 158px, not 172px: at 172 two cards plus the gap came to within a pixel of the
   row's width, so the scroller looked like a finished two-card grid and nothing
   said it moved. At 158 the third card shows a ~17px sliver, which is the only
   affordance a hidden-scrollbar row has. */
.cd-pgrid--scroll > .cd-pcard {
	flex: none;
	width: 158px;
	scroll-snap-align: start;
}

@media (min-width: 900px) {
	.cd-pgrid--three {
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: 26px 22px;
	}

	.cd-pgrid--four {
		grid-template-columns: repeat(4, minmax(0, 1fr));
		gap: 22px;
	}

	.cd-pgrid--scroll {
		display: grid;
		overflow: visible;
		margin-inline: 0;
		padding-inline: 0;
	}

	.cd-pgrid--scroll > .cd-pcard {
		width: auto;
	}
}

.cd-pgrid-section {
	padding-block: 26px 8px;
}

.cd-pgrid-section .cd-pgrid {
	margin-top: 18px;
}

@media (min-width: 900px) {
	.cd-pgrid-section {
		padding-block: 44px 12px;
	}

	.cd-pgrid-section .cd-pgrid {
		margin-top: 24px;
	}
}

/* --------------------------------------------------------------------------
   3. The archive — header band
   -------------------------------------------------------------------------- */

.cd-main--shop {
	padding-inline: 0;

	/* The root layout puts a block-gap between the header part and main; the
	   archive's header band sits flush under the header rule instead. */
	margin-block-start: 0;
}

/* The kit's "· OR FROM $150" rides in the currency slot and is uppercase mono
   like every other fact on the card. */
.cd-pcard .cd-price__currency {
	text-transform: uppercase;
}

.cd-shop-head {
	border-bottom: 1px solid var(--cd-rule-soft);
}

.cd-shop-head > .cd-wrap {
	padding-block: 18px 14px;
}

.cd-shop-head__title {
	font: 800 26px/1.05 var(--cd-sans);
	letter-spacing: -.03em;
	color: var(--cd-ink);
	text-wrap: balance;
}

.cd-shop-head__lede {
	margin: 8px 0 0;
	max-width: 560px;
	font: 400 13px/1.5 var(--cd-sans);
	color: var(--cd-ink-muted);
}

.cd-shop-head__search {
	margin-top: 14px;
}

@media (min-width: 900px) {
	.cd-shop-head > .cd-wrap {
		padding-block: 30px 22px;
	}

	.cd-shop-head__title {
		font-size: 36px;
	}

	.cd-shop-head__lede {
		margin-top: 9px;
		font-size: 14.5px;
		line-height: 1.55;
	}

	/* From 900px the site header carries the search field. */
	.cd-shop-head__search {
		display: none;
	}
}

/* --------------------------------------------------------------------------
   4. The archive — two-column body

   Below 900px the sidebar is a disclosure sheet sitting beside the sort
   control; the results flow underneath it. From 900px the disclosure is always
   open and becomes the fixed 212px sidebar.
   -------------------------------------------------------------------------- */

.cd-shop-body__inner {
	display: grid;
	grid-template-columns: 1fr 1fr;
	column-gap: 8px;
	padding-block: 14px 24px;
}

.cd-shop-results,
.cd-shop-toolbar {
	display: contents;
}

.cd-shop-toolbar__count {
	grid-column: 1 / -1;
	grid-row: 2;
	margin: 12px 0 0;
	padding-top: 12px;
	border-top: 1px solid var(--cd-rule-soft);
	font: 500 11px var(--cd-mono);
	font-variant-numeric: tabular-nums;
	letter-spacing: .05em;
	text-transform: uppercase;
	color: var(--cd-ink-soft);
}

.cd-shop-results > .cd-pgrid,
.cd-shop-empty {
	grid-column: 1 / -1;
	grid-row: 3;
}

.cd-pagination {
	grid-column: 1 / -1;
	grid-row: 4;
}

.cd-shop-results > .cd-pgrid {
	margin-top: 8px;
}

@media (min-width: 900px) {
	.cd-shop-body__inner {
		display: flex;
		align-items: flex-start;
		gap: 34px;
		padding-block: 24px 40px;
	}

	.cd-shop-results {
		display: block;
		flex: 1;
		min-width: 0;
	}

	/* One continuous hairline under the whole toolbar — drawn on the row, not
	   on its two children, or the flex gap cuts a notch out of it. */
	.cd-shop-toolbar {
		display: flex;
		justify-content: space-between;
		align-items: center;
		gap: 16px;
		padding-bottom: 16px;
		border-bottom: 1px solid var(--cd-rule);
	}

	.cd-shop-toolbar__count {
		margin: 0;
		padding-top: 0;
		border-top: 0;
		font-size: 12.5px;
		letter-spacing: .04em;
		flex: 1;
	}

	.cd-shop-results > .cd-pgrid {
		margin-top: 24px;
	}
}

/* --------------------------------------------------------------------------
   5. Filters
   -------------------------------------------------------------------------- */

.cd-filters {
	grid-column: 1;
	grid-row: 1;
	position: relative;
}

.cd-filters__summary {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
	min-height: 44px;
	padding: 10px 12px;
	border: 2px solid var(--cd-ink);
	border-radius: 9px;
	font: 600 12px var(--cd-sans);
	color: var(--cd-ink);
	cursor: pointer;
	list-style: none;
}

.cd-filters__summary::-webkit-details-marker {
	display: none;
}

.cd-filters__count {
	font: 700 10px var(--cd-mono);
	background: var(--cd-accent);
	color: var(--cd-on-accent);
	border-radius: var(--cd-r-badge);
	padding: 2px 5px;
}

/* On a phone the filters are a sheet that drops over the results, not a long
   list stacked above them — the grid stays where the thumb left it. The width
   spans both toolbar columns: two columns plus the 8px gap between them. */
.cd-filters__body {
	position: absolute;
	z-index: 7;
	top: calc(100% + 8px);
	left: 0;
	width: calc(200% + 8px);
	max-height: 68vh;
	overflow-y: auto;
	overscroll-behavior: contain;
	display: flex;
	flex-direction: column;
	gap: 22px;
	padding: 16px 16px 20px;
	background: var(--cd-card);
	border: 1.5px solid var(--cd-ink);
	border-radius: var(--cd-r-input);
}

.cd-filter-group__head {
	margin: 0;
	padding-bottom: 10px;
	border-bottom: 1px solid var(--cd-rule);
	font: 700 10.5px var(--cd-mono);
	letter-spacing: .09em;
	text-transform: uppercase;
	color: var(--cd-ink-soft);
}

/* Category and price lists */
.cd-filter-list {
	list-style: none;
	margin: 4px 0 0;
	padding: 0;
}

.cd-filter-list--plain {
	margin-top: 12px;
}

.cd-filter-list__row {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: 12px;
	padding: 8px 0;
	font: 500 13px var(--cd-sans);
	color: var(--cd-ink-body);
	text-decoration: none;
}

.cd-filter-list--plain .cd-filter-list__row {
	padding: 4.5px 0;
}

.cd-filter-list__row:hover {
	color: var(--cd-ink);
	text-decoration: none;
}

.cd-filter-list__row.is-active {
	font-weight: 700;
	color: var(--cd-ink);
}

.cd-filter-list__count {
	font: 500 11px var(--cd-mono);
	font-variant-numeric: tabular-nums;
	color: var(--cd-ink-faint);
}

/* Brand and grade chip sets */
.cd-filter-chips {
	display: flex;
	flex-wrap: wrap;
	gap: 7px;
	margin-top: 12px;
}

.cd-filters .cd-chip--outline {
	font: 600 11.5px var(--cd-sans);
	padding: 5px 11px;
	color: var(--cd-ink-muted);
	background: var(--cd-paper);
	border: 1.5px solid var(--cd-rule);
}

.cd-filters .cd-chip--outline:hover {
	border-color: var(--cd-ink);
	color: var(--cd-ink);
}

/* Active brand reads as chosen, not merely outlined. */
.cd-filters .cd-chip--outline.is-active {
	background: var(--cd-ink);
	border-color: var(--cd-ink);
	color: var(--cd-card);
	padding: 6px 11px;
	border-width: 0;
}

.cd-filter-group .cd-filter-chips:has(.cd-grade--filter) {
	gap: 6px;
}

/* Grade chips: the accent fill is the "chosen" state, not decoration. */
.cd-grade--filter {
	font: 700 10.5px var(--cd-mono);
	background: var(--cd-paper);
	border: 1.5px solid var(--cd-rule);
	color: var(--cd-ink-muted);
	padding: 3px 7px;
	border-radius: var(--cd-r-badge);
	text-decoration: none;
}

.cd-grade--filter:hover {
	border-color: var(--cd-ink);
	color: var(--cd-ink);
	text-decoration: none;
}

.cd-grade--filter.is-active {
	background: var(--cd-accent);
	border-color: var(--cd-accent);
	color: var(--cd-on-accent);
	padding: 4px 7px;
	border-width: 0;
}

.cd-filter-grades-link {
	margin-top: 12px;
	font: 500 11.5px var(--cd-sans);
	border-bottom-width: 1.5px;
}

.cd-filter-clear {
	align-self: flex-start;
	font: 600 11.5px var(--cd-sans);
	color: var(--cd-ink-muted);
	border-bottom: 1.5px solid var(--cd-rule);
	padding-bottom: 2px;
}

.cd-filter-clear:hover {
	color: var(--cd-ink);
	border-bottom-color: var(--cd-ink);
	text-decoration: none;
}

@media (min-width: 900px) {
	.cd-filters {
		flex: none;
		width: 212px;
	}

	.cd-filters__body {
		position: static;
		width: auto;
		max-height: none;
		overflow: visible;
		gap: 26px;
		padding: 0;
		background: none;
		border: 0;
		border-radius: 0;
	}

	/* The sidebar and the results column start at the same y, but the toolbar row
	   is taller than a filter heading (it carries the Sort control), so their two
	   hairlines landed 21px apart and read as a misalignment. Dropping the first
	   group by the difference puts CATEGORY's rule on the same line as the
	   "showing N of M" rule. Applies to the first group only — the rest of the
	   sidebar keeps its own 26px rhythm. */
	.cd-filters__body > .cd-filter-group:first-child {
		padding-top: 21px;
	}

	/* From here the sidebar is not a disclosure at all — it is simply there.
	   Browsers without ::details-content keep the summary as a real toggle
	   rather than losing the filters altogether. */
	@supports selector(::details-content) {
		.cd-filters__summary {
			display: none;
		}

		.cd-filters::details-content {
			content-visibility: visible;
			block-size: auto;
		}
	}
}

/* --------------------------------------------------------------------------
   6. Sort — a disclosure of links, so it works with JavaScript off
   -------------------------------------------------------------------------- */

.cd-sort {
	position: relative;
	grid-column: 2;
}

.cd-sort__summary {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 7px;
	min-height: 44px;
	padding: 10px 12px;
	border: 1.5px solid var(--cd-rule);
	border-radius: 9px;
	font: 600 12px var(--cd-sans);
	color: var(--cd-ink-muted);
	cursor: pointer;
	list-style: none;
	white-space: nowrap;
}

.cd-sort__summary::-webkit-details-marker {
	display: none;
}

.cd-sort__label {
	display: none;
}

.cd-sort__value {
	overflow: hidden;
	text-overflow: ellipsis;
}

.cd-sort__menu {
	position: absolute;
	z-index: 6;
	top: calc(100% + 6px);
	right: 0;
	min-width: 184px;
	display: flex;
	flex-direction: column;
	background: var(--cd-card);
	border: 1.5px solid var(--cd-ink);
	border-radius: var(--cd-r-input);
	padding: 5px;
}

.cd-sort__option {
	padding: 8px 10px;
	border-radius: 5px;
	font: 500 12.5px var(--cd-sans);
	color: var(--cd-ink-body);
	white-space: nowrap;
}

.cd-sort__option:hover {
	background: var(--cd-chip);
	color: var(--cd-ink);
	text-decoration: none;
}

.cd-sort__option.is-active {
	font-weight: 700;
	color: var(--cd-ink);
}

@media (min-width: 900px) {
	.cd-sort {
		flex: none;
		display: flex;
		align-items: center;
		gap: 9px;
	}

	.cd-sort__label {
		display: inline;
		font: 500 12.5px var(--cd-sans);
		color: var(--cd-ink-soft);
	}

	.cd-sort__summary {
		min-height: 0;
		padding: 6px 11px;
		border: 1.5px solid var(--cd-ink);
		border-radius: 6px;
		font-size: 12.5px;
		color: var(--cd-ink);
	}

	.cd-sort__menu {
		top: calc(100% + 8px);
	}
}

/* --------------------------------------------------------------------------
   7. Pagination
   -------------------------------------------------------------------------- */

.cd-pagination {
	display: flex;
	justify-content: center;
	flex-wrap: wrap;
	gap: 8px;
	margin-top: 26px;
}

.cd-pagination .page-numbers {
	display: flex;
	align-items: center;
	justify-content: center;
	min-width: 34px;
	height: 34px;
	padding: 0 6px;
	border: 1.5px solid var(--cd-rule);
	border-radius: 6px;
	font: 600 12.5px var(--cd-sans);
	font-variant-numeric: tabular-nums;
	color: var(--cd-ink-muted);
}

.cd-pagination .page-numbers:hover {
	border-color: var(--cd-ink);
	color: var(--cd-ink);
	text-decoration: none;
}

.cd-pagination .page-numbers.prev,
.cd-pagination .page-numbers.next {
	padding: 0 13px;
}

.cd-pagination .page-numbers.current {
	background: var(--cd-ink);
	border-color: var(--cd-ink);
	color: var(--cd-card);
	font-weight: 700;
}

.cd-pagination .page-numbers.dots {
	border-color: transparent;
}

@media (min-width: 900px) {
	.cd-pagination {
		gap: 9px;
		margin-top: 34px;
	}

	.cd-pagination .page-numbers {
		min-width: 36px;
		height: 36px;
		font-size: 13px;
	}

	.cd-pagination .page-numbers.prev,
	.cd-pagination .page-numbers.next {
		padding: 0 14px;
	}
}

/* --------------------------------------------------------------------------
   8. Empty state — never a dead page
   -------------------------------------------------------------------------- */

.cd-shop-empty {
	margin-top: 20px;
	padding: 26px 20px 28px;
	border: 1px solid var(--cd-rule);
	border-radius: var(--cd-r-card);
	background: var(--cd-card);
}

.cd-shop-empty__title {
	font: 800 22px/1.15 var(--cd-sans);
	letter-spacing: -.025em;
	color: var(--cd-ink);
}

.cd-shop-empty__body {
	margin: 9px 0 0;
	max-width: 460px;
	font: 400 13.5px/1.55 var(--cd-sans);
	color: var(--cd-ink-muted);
}

.cd-shop-empty__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin: 18px 0 0;
}

@media (min-width: 900px) {
	.cd-shop-empty {
		margin-top: 26px;
		padding: 34px 32px 36px;
	}

	.cd-shop-empty__title {
		font-size: 26px;
	}

	.cd-shop-empty__body {
		font-size: 14.5px;
	}
}
