/*
 * Advertisers — the grid on the front end.
 *
 * The file loads on a page that holds the block, and in the editor
 * canvas. It is written in the language of the network theme: the card
 * of a coupon, which is a white box with a dashed line in the accent of
 * the site and a small corner radius. A card of the grid and the card
 * of the block netsite/single-advertiser draw the same box, from the
 * same variables, so the two blocks agree on one page. The grid card
 * holds the logo on top, a short line under it, and a pill button.
 *
 * The theme supplies --brand-accent, --surface, --line, --radius and
 * the rest. Every rule below carries a fallback, so the grid still
 * looks correct under another theme, or before the theme's stylesheets
 * have loaded.
 *
 * NAMING RULE — do not break it. Every class here must stay free of the
 * words "affiliate", "ad", "advert", "sponsor" and "banner". An ad
 * blocker hides an element whose class contains one of them, and this
 * grid is how the network earns.
 */

/*
 * THE BOX MODEL OF THE BLOCK — do not take it away.
 *
 * A size below is the size of the border box: a padding and a border
 * stay inside it. The page gets this box model from the theme, and the
 * theme sets it in main.css. That file loads on the front end only.
 *
 * The card of the grid has "height: 100%" and a padding. Without the
 * rule below, the browser adds the padding to that height in the editor
 * canvas: the card becomes 2rem taller than its cell, it goes out of
 * the block, and the next block writes over it. The logo box grows in
 * the same way.
 *
 * The block therefore sets its own box model. The grid is then the same
 * height on the page, in the editor canvas and under another theme.
 */
.netsite-advertisers,
.netsite-advertisers *,
.netsite-advertisers *::before,
.netsite-advertisers *::after {
	box-sizing: border-box;
}

.netsite-advertisers {
	/*
	 * The button reads the three colours that a site sets in the
	 * Customizer, under "Colours". The theme writes each filled-in field
	 * on the <html> element (--brand-button and the two beside it), on
	 * the page and in the editor canvas, and EVERY button of the network
	 * reads the same three: the button of a core block, the CTA of a
	 * banner, the sticker of an affiliate link and the button of the
	 * newsletter signup block. A site therefore picks a button colour
	 * one time.
	 *
	 * An empty "Button background colour" gives the second colour of
	 * the site (--brand-accent). An empty "Button background hover
	 * colour" gives a dark version of THE COLOUR OF THE BUTTON, never
	 * the dark version of the accent: a site that picks a button colour
	 * of its own must not get a hover colour out of another colour. The
	 * 18% is the same amount of black that the theme mixes into its own
	 * deep colours (theme.json, custom.accentDeep). The last value of
	 * each line is for a page that carries neither the variable nor the
	 * theme.
	 */
	--adv-button: var(--brand-button, var(--brand-accent, #e8590c));
	--adv-button-hover: var(--brand-button-hover, color-mix(in srgb, #000 18%, var(--adv-button)));
	--adv-button-ink: var(--brand-button-text, #fff);
	--adv-button-hover-ink: var(--brand-button-hover-text, var(--adv-button-ink));

	/*
	 * The box of a card. The values are the values of the "Deal box
	 * (coupon)" style of the theme (is-style-deal-box in blocks.css),
	 * so a change of the deal box reaches every advertiser card.
	 *
	 * The line takes the second colour of the site, never the colour of
	 * the button: a site that gives its buttons a colour of its own
	 * keeps the line of its coupons. A site with no second colour falls
	 * back to the colour of the button, and then to the last value.
	 */
	--adv-surface: var(--surface, var(--paper-white, #fff));
	--adv-rule: 2px;
	--adv-rule-ink: var(--brand-accent, var(--adv-button));
	--adv-line: color-mix(in srgb, var(--adv-rule-ink) 65%, var(--line, #e7e4de));
	--adv-corner: var(--radius, 10px);
	--adv-corner-button: var(--corner-pill, 9999px);
	--adv-shadow-lift: var(--shadow-lg, rgba(0, 0, 0, 0.12) 0 4px 24px 0);
	--adv-ink: var(--text, #000);
	--adv-ink-soft: var(--text-soft, #787574);
	--adv-gap: var(--gap, 0.75rem);
	--adv-ease: var(--ease, cubic-bezier(0.2, 0.8, 0.2, 1));
}

.netsite-advertisers__heading {
	margin: 0 0 var(--s5, 1.5rem);
	font-family: var(--font-display, inherit);
	font-weight: var(--display-weight, 600);
	font-size: var(--wp--preset--font-size--large, 1.5rem);
	letter-spacing: var(--track-display, -0.05em);
	line-height: 1.1;
	text-align: center;
	overflow-wrap: break-word;
}

.netsite-advertisers__more {
	margin: var(--s5, 1.5rem) 0 0;
	text-align: center;
}

/*
 * THE ROW IS CENTRED, NEVER FILLED FROM THE LEFT.
 *
 * The block is wide, and an advertiser list can hold one, two or three cards.
 * A grid with fixed columns puts them in the left cells of the row and
 * leaves the rest empty, so the block looks off the text column. A
 * flex row with "justify-content: center" keeps each card the width of
 * a cell, and puts a short row, and the last short line of a long one,
 * in the middle.
 *
 * Each item takes the width of one column: --adv-cols columns share the
 * width, and the gaps come out first.
 */
.netsite-advertisers__grid {
	--adv-cols: 2;
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--adv-gap);
	margin: 0;
	padding: 0;
	list-style: none;
}

@media (min-width: 40em) {

	.netsite-advertisers__grid {
		--adv-cols: 3;
	}
}

@media (min-width: 60em) {

	.netsite-advertisers__grid {
		--adv-cols: 4;
	}
}

.netsite-advertisers__item {
	flex: 0 0 calc((100% - (var(--adv-cols) - 1) * var(--adv-gap)) / var(--adv-cols));
	min-width: 0;
	margin: 0;
	padding: 0;
	list-style: none;
}

/*
 * The whole card is the link, so a click on any part of it opens the
 * advertiser. The card is the box of a coupon: white, with a dashed line in
 * the accent of the site. It has no shadow at rest, and it lifts under
 * the pointer. It draws no punch hole: a hole belongs to the one
 * advertiser that a page features, and a grid of holes reads as noise.
 */
.netsite-advertisers__card {
	display: flex;
	flex-direction: column;
	gap: var(--s3, 0.75rem);
	height: 100%;
	padding: var(--s4, 1rem);
	border: var(--adv-rule) dashed var(--adv-line);
	border-radius: var(--adv-corner);
	background: var(--adv-surface);
	color: var(--adv-ink);
	font-family: inherit;
	font-weight: inherit;
	text-decoration: none;
	transition: transform 420ms var(--adv-ease), box-shadow 420ms var(--adv-ease);
}

.netsite-advertisers__card:hover,
.netsite-advertisers__card:focus {
	color: var(--adv-ink);
	text-decoration: none;
	transform: translateY(-3px);
	box-shadow: var(--adv-shadow-lift);
}

.netsite-advertisers__card:focus-visible {
	outline: 2px solid var(--adv-ink);
	outline-offset: 3px;
}

.netsite-advertisers__logo {
	display: flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	/*
	 * THE BOX KEEPS ITS PLACE — a definite height, and never `auto`.
	 * A box that grows when the file arrives moves everything below
	 * the grid down. PageSpeed named this picture as a cause of the
	 * layout shift of the page. The box holds its place from the
	 * first moment, whatever the picture inside it does.
	 */
	height: clamp(3.5rem, 10vw, 5rem);
	/*
	 * No space under the box. The card already holds a gap there, and
	 * the line under the logo belongs to the logo.
	 */
	padding: var(--s2, 0.5rem) var(--s2, 0.5rem) 0;
}

/*
 * A card with no description has the logo and the button only. Its row
 * can be taller, because a card beside it holds a description. The
 * logo box then takes the spare height, so the logo stays in the
 * middle and no blank band stands above the button.
 */
.netsite-advertisers__logo:has(+ .netsite-advertisers__button) {
	flex-grow: 1;
}

/*
 * THE PICTURE FILLS THE BOX, in the direction that limits it. A tall
 * logo takes the height, and a wide one takes the width.
 *
 * Do not put a height on the picture. A height of its own makes the
 * box of the SHAPE of the file: a square logo of 200 pixels then
 * stands 56 pixels tall in a box of 80, and a wordmark of the same
 * file size fills the card. The offers list holds the same two rules.
 */
.netsite-advertisers__logo img {
	width: auto;
	height: auto;
	max-width: 100%;
	max-height: 100%;
	object-fit: contain;
}

/* The short description of the advertiser, below the logo. */
.netsite-advertisers__description {
	margin: 0;
	font-size: var(--text-sm, 0.875rem);
	line-height: 1.4;
	letter-spacing: var(--track-sm, -0.014em);
	text-align: center;
	overflow-wrap: break-word;
	/*
	 * The text of a card is the text of the page, and not a grey one.
	 * A soft grey on a white card was hard to read, and the line says
	 * what the advertiser sells.
	 */
	color: var(--adv-ink);
}

/*
 * An advertiser without a logo shows its name.
 *
 * The name is a flex item, and a long name of one word makes that item
 * larger than the card: the text then goes out of the card and, on a
 * telephone, out of the screen. "overflow-wrap: anywhere" breaks such a
 * word and also makes the smallest width of the item small, so the card
 * keeps its width at each screen size.
 */
.netsite-advertisers__name {
	min-width: 0;
	font-family: var(--font-display, inherit);
	font-size: 1.125rem;
	font-weight: var(--display-weight, 600);
	line-height: 1.2;
	letter-spacing: var(--track-sub, -0.03em);
	text-align: center;
	overflow-wrap: break-word;
	hyphens: auto;
	color: var(--adv-ink);
}

/*
 * The button is a box inside the card link, never a link itself: a link
 * inside a link is not valid HTML. The card always shows the button.
 * It is a pill in the accent of the site: the one colour on the card.
 */
.netsite-advertisers__button {
	display: block;
	margin-top: auto;
	padding: 0.65em 1em;
	background: var(--adv-button);
	border-radius: var(--adv-corner-button);
	color: var(--adv-button-ink);
	font-family: var(--font-display, inherit);
	font-size: var(--text-sm, 0.875rem);
	/* The word on a button is the one thing a visitor presses. */
	font-weight: 700;
	line-height: 1.2;
	letter-spacing: var(--track-sm, -0.014em);
	text-align: center;
	overflow-wrap: break-word;
	transition: background-color 160ms var(--adv-ease);
}

.netsite-advertisers__card:hover .netsite-advertisers__button,
.netsite-advertisers__card:focus .netsite-advertisers__button,
.netsite-advertisers__card:focus-visible .netsite-advertisers__button {
	color: var(--adv-button-hover-ink);
	background: var(--adv-button-hover);
}

/* The message that the editor sees while the block holds no advertiser. */
.netsite-advertisers__empty {
	margin: 0;
	padding: var(--s4, 1rem);
	border: 1.5px dashed var(--stone, #ccc);
	border-radius: var(--adv-corner);
	text-align: center;
	color: var(--adv-ink-soft);
}

/* ------------------------------------------------------------------ */
/* One advertiser, featured                                            */
/* ------------------------------------------------------------------ */

/*
 * The block netsite/single-advertiser draws ONE advertiser as a coupon,
 * so it reads as an offer and not as one tile of a list.
 *
 * The box is the box of a grid card, from the same variables: the same
 * dashed line, the same corner and the same surface. Two things only
 * belong to the featured advertiser — a punch hole at each side, and
 * more room inside — and they are what makes the card read as an offer.
 *
 * The button keeps the pill of the grid card, because the button is the
 * one thing that a visitor presses and it must look the same everywhere
 * on the site.
 */
.netsite-advertisers--feature {
	--adv-hole: var(--paper, #fbfaf7);
	--adv-feature-pad: clamp(1.25rem, 3vw, 1.75rem);
}

.netsite-advertisers__feature-card {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--adv-gap);
	padding: var(--adv-feature-pad) clamp(1.25rem, 3vw, 2rem);
	background: var(--adv-surface);
	border: var(--adv-rule) dashed var(--adv-line);
	border-radius: var(--adv-corner);
	color: var(--adv-ink);
	font-family: inherit;
	font-weight: inherit;
	text-align: center;
	text-decoration: none;
	transition: transform 420ms var(--adv-ease), box-shadow 420ms var(--adv-ease);
}

.netsite-advertisers__feature-card:hover,
.netsite-advertisers__feature-card:focus {
	color: var(--adv-ink);
	text-decoration: none;
	transform: translateY(-3px);
	box-shadow: var(--adv-shadow-lift);
}

.netsite-advertisers__feature-card:focus-visible {
	outline: 2px solid var(--adv-ink);
	outline-offset: 3px;
}

/*
 * The two punch holes of the coupon. They carry the colour of the paper
 * behind the card, and the clip keeps each one a half circle, so the
 * dashed line of the card runs into them.
 */
.netsite-advertisers__feature-card::before,
.netsite-advertisers__feature-card::after {
	content: "";
	position: absolute;
	top: 50%;
	width: 1.15rem;
	height: 1.15rem;
	background: var(--adv-hole);
	border: var(--adv-rule) dashed var(--adv-line);
	border-radius: 50%;
	transform: translateY(-50%);
}

.netsite-advertisers__feature-card::before {
	left: -0.7rem;
	clip-path: inset(-4px -4px -4px 45%);
}

.netsite-advertisers__feature-card::after {
	right: -0.7rem;
	clip-path: inset(-4px 45% -4px -4px);
}

.netsite-advertisers__feature-logo {
	display: flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
}

/* A definite height here too. See the note above the grid logo. */
.netsite-advertisers__feature-logo img {
	width: auto;
	max-width: 100%;
	height: clamp(3rem, 9vw, 4.5rem);
	object-fit: contain;
}

.netsite-advertisers__feature-body {
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
	gap: var(--s2, 0.5rem);
	min-width: 0;
}

/*
 * The name of the advertiser is the head of the coupon. It is not a heading
 * element: the card is one link, and a heading inside a link would put
 * a false step in the outline of the page. The editor writes the real
 * headings of the page.
 */
.netsite-advertisers__title {
	min-width: 0;
	font-family: var(--font-display, inherit);
	font-size: var(--text-h-sm, 1.25rem);
	font-weight: var(--display-weight, 600);
	line-height: 1.2;
	letter-spacing: var(--track-sub, -0.03em);
	overflow-wrap: break-word;
	hyphens: auto;
	color: var(--adv-ink);
}

.netsite-advertisers__feature-card .netsite-advertisers__description {
	font-size: var(--text-base, 1rem);
	text-align: inherit;
}

.netsite-advertisers__feature-card .netsite-advertisers__button {
	flex: 0 0 auto;
	margin-top: 0;
	padding: 0.7em 1.4em;
	font-size: var(--text-base, 1rem);
}

.netsite-advertisers__feature-card:hover .netsite-advertisers__button,
.netsite-advertisers__feature-card:focus .netsite-advertisers__button,
.netsite-advertisers__feature-card:focus-visible .netsite-advertisers__button {
	color: var(--adv-button-hover-ink);
	background: var(--adv-button-hover);
}

/*
 * On a screen that is wide enough, the coupon reads as one line: the
 * logo, the text, and the button that a visitor presses at the end.
 */
@media (min-width: 40em) {

	.netsite-advertisers__feature-card {
		flex-direction: row;
		gap: clamp(1rem, 3vw, 1.75rem);
		text-align: left;
	}

	.netsite-advertisers__feature-logo {
		width: clamp(6rem, 14vw, 9rem);
	}
}

/* ------------------------------------------------------------------ */
/* A short grid                                                        */
/* ------------------------------------------------------------------ */

/*
 * A grid of one advertiser draws the coupon of the single block. The
 * grid is wide by default, so the coupon keeps the width of the text
 * column, the same as the single block.
 */
.wp-block-netsite-advertisers > .netsite-advertisers__feature-card {
	max-width: var(--wp--style--global--content-size, 680px);
	margin-inline: auto;
}

.netsite-advertisers__feature-card :is(.netsite-advertisers__reason, .netsite-advertisers__offer, .netsite-advertisers__why) {
	text-align: inherit;
}

/*
 * Two or three advertisers get larger cards in the middle of the row,
 * so they take more focus than a full grid. On a telephone, the cards
 * keep their size, because two columns leave no room for more.
 */
@media (min-width: 40em) {

	.netsite-advertisers--few .netsite-advertisers__card {
		padding: var(--s5, 1.5rem);
	}

	.netsite-advertisers--few .netsite-advertisers__logo {
		height: clamp(4rem, 12vw, 6rem);
	}

	.netsite-advertisers--few .netsite-advertisers__description,
	.netsite-advertisers--few .netsite-advertisers__button {
		font-size: var(--text-base, 1rem);
	}

	.netsite-advertisers--few-2 .netsite-advertisers__grid {
		--adv-cols: 2;
		max-width: var(--wp--style--global--content-size, 680px);
		margin-inline: auto;
	}
}

@media (min-width: 60em) {

	.netsite-advertisers--few-3 .netsite-advertisers__grid {
		--adv-cols: 3;
	}
}

/*
 * ---------------------------------------------------------------------
 * The offers block — netsite/advertiser-offers.
 *
 * One offer is one row: the logo of the advertiser on the left, the name of
 * the advertiser and the text of the offer in the middle, the coupon code
 * beside it, and the button at the end. The row is ONE link, the same
 * as a card of the grid, so the code is text inside that link and
 * never a second link.
 *
 * The row reads the same variables as the card: the surface, the line,
 * the corner and the three button colours. A site therefore picks its
 * colours one time, and the offers follow.
 *
 * NAMING RULE — the class names hold none of the words "affiliate",
 * "ad", "advert", "sponsor" and "banner". An ad blocker hides an
 * element that carries one of them.
 * ---------------------------------------------------------------------
 */
/*
 * EVERY ROW IS AS WIDE AS THE BLOCK. A row that was as wide as the
 * words it held made a ragged edge: three offers gave three widths,
 * and no line of the column started in the same place.
 *
 * The block itself is as wide as a paragraph, so the words of an offer
 * begin where the words of the text above them begin. An editor that
 * wants it wider sets Wide or Full in the block panel.
 */
.netsite-offers__list {
	display: flex;
	flex-direction: column;
	gap: var(--s3, 0.75rem);
	margin: 0;
	padding: 0;
	list-style: none;
}

.netsite-offers__item {
	width: 100%;
	max-width: 100%;
	margin: 0;
	padding: 0;
}

.netsite-offers__row {
	display: flex;
	align-items: center;
	width: 100%;
	max-width: 100%;
	gap: var(--s4, 1rem);
	padding: var(--s4, 1rem);
	background: var(--adv-surface);
	border: var(--adv-rule) dashed var(--adv-line);
	border-radius: var(--adv-corner);
	color: var(--adv-ink);
	text-decoration: none;
	transition: transform 420ms var(--adv-ease), box-shadow 420ms var(--adv-ease);
}

.netsite-offers__row:hover,
.netsite-offers__row:focus {
	color: var(--adv-ink);
	text-decoration: none;
	transform: translateY(-3px);
	box-shadow: var(--adv-shadow-lift);
}

.netsite-offers__row:focus-visible {
	outline: 2px solid var(--adv-ink);
	outline-offset: 3px;
}

/*
 * The logo box keeps its width, so every row of the list starts at the
 * same place and the list reads as a column and not as a stack of
 * different boxes.
 */
.netsite-offers__logo {
	display: flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	width: 5.5rem;
	height: 3rem;
	overflow: hidden;
}

.netsite-offers__logo img {
	max-width: 100%;
	max-height: 100%;
	width: auto;
	height: auto;
	object-fit: contain;
}

.netsite-offers__body {
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
	gap: var(--s1, 0.25rem);
	min-width: 0;
}

/*
 * The row of the offers block holds its own name element, because the
 * grid already gives ".netsite-advertisers__title" the size of a head
 * of a coupon box. The two must not fight over one class.
 */

/*
 * The text of the offer is not a heading element: the row is one link,
 * and a heading inside a link would put a false step in the outline of
 * the page.
 */
.netsite-offers__title {
	font-family: var(--font-display, inherit);
	font-size: var(--text-base, 1rem);
	font-weight: var(--display-weight, 600);
	line-height: 1.25;
	letter-spacing: var(--track-sub, -0.02em);
	overflow-wrap: break-word;
	hyphens: auto;
}

.netsite-offers__ends,
.netsite-offers__terms {
	font-size: var(--text-xs, 0.75rem);
	line-height: 1.4;
	color: var(--adv-ink-soft, var(--adv-ink));
}

/*
 * The coupon code. A visitor copies it by eye, so it stands in a box
 * with a monospaced face and enough space around it.
 */
.netsite-offers__code {
	display: flex;
	flex: 0 0 auto;
	flex-direction: column;
	gap: 0;
	padding: 0.4em 0.8em;
	border: var(--adv-rule) dashed var(--adv-line);
	border-radius: var(--adv-corner);
	text-align: center;
}

/*
 * The two lines of the box stand against each other, and the code is
 * as big as the text of the page. A visitor copies it by eye.
 */
.netsite-offers__code-label {
	font-size: var(--text-xs, 0.8125rem);
	line-height: 1.1;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--adv-ink-soft, var(--adv-ink));
}

.netsite-offers__code-value {
	font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
	font-size: var(--text-h-xs, 1.125rem);
	line-height: 1.2;
	font-weight: 600;
	letter-spacing: 0.04em;
	overflow-wrap: break-word;
	hyphens: auto;
}

.netsite-offers .netsite-advertisers__button {
	flex: 0 0 auto;
	margin-top: 0;
	padding: 0.7em 1.2em;
}

.netsite-offers__row:hover .netsite-advertisers__button,
.netsite-offers__row:focus .netsite-advertisers__button,
.netsite-offers__row:focus-visible .netsite-advertisers__button {
	color: var(--adv-button-hover-ink);
	background: var(--adv-button-hover);
}

/*
 * On a narrow screen the row becomes a column: the logo, the advertiser, the
 * offer, the day it ends, the code and the button, each under the one
 * before it and each on the middle line. A telephone reads one column
 * top to bottom, and the eye then follows one line and not four.
 *
 * Nothing is hidden, because every part of a row says something that a
 * visitor needs. The order is the order of the source, so no rule here
 * names a place.
 */
/*
 * A ROW CARRIES MORE ON A WIDE SCREEN. The row holds a logo, a name, a
 * day, a code and a button on one line. At the space of a telephone
 * the five stand shoulder to shoulder, and the row reads as a strip.
 *
 * A desktop has the room, so the space inside the row grows and the
 * logo with it. Only the space changes: no part is added, and no part
 * is hidden.
 */
@media (min-width: 40.0625rem) {
	.netsite-offers__list {
		gap: var(--s4, 1rem);
	}

	.netsite-offers__row {
		gap: var(--s5, 1.5rem);
		padding: var(--s5, 1.5rem);
	}

	.netsite-offers__logo {
		width: 7rem;
		height: 4rem;
	}

	.netsite-offers__title {
		font-size: var(--text-lg, 1.125rem);
	}

	.netsite-offers__ends,
	.netsite-offers__terms {
		font-size: var(--text-sm, 0.875rem);
	}

	.netsite-offers .netsite-advertisers__button {
		padding: 0.85em 1.5em;
	}
}

@media (max-width: 40rem) {
	/*
	 * The card fills the column of the page. A card that shrank to its
	 * text stood as an island with paper on both sides.
	 */
	.netsite-offers__item,
	.netsite-offers__row {
		width: 100%;
	}

	.netsite-offers__row {
		flex-direction: column;
		align-items: center;
		gap: var(--s3, 0.75rem);
		text-align: center;
	}

	.netsite-offers__body {
		align-items: center;
		flex-basis: auto;
		width: 100%;
	}

	.netsite-offers__logo {
		width: 7rem;
		height: 2.5rem;
	}

	/*
	 * The button is as wide as the card. It is what a visitor presses,
	 * and a thumb finds a wide target.
	 */
	.netsite-offers .netsite-advertisers__button {
		width: 100%;
	}
}

/*
 * The block Shop categories. It answers one question of a visitor:
 * where do I find the advertisers for what I want?
 *
 * - The chips jump to a group, so a long list reads on a telephone.
 * - The popular categories are coupons, in the language of the deal
 *   box of the theme: a dashed edge, a perforation with two punch
 *   holes, and a stub that says where the coupon leads.
 * - A card of a group is text: the name, the first advertisers as links, and
 *   a button to the category page.
 *
 * Every colour comes from the two colours of the site, and every space
 * from the spacing sizes of theme.json.
 */
.netsite-category-index {
	--cat-paper: var(--wp--custom--paper, #fbfaf7);
	--cat-surface: var(--wp--custom--surface, #fff);
	--cat-line: var(--wp--custom--line, #e7e4de);
	--cat-ink: var(--wp--custom--ink, #1e2126);
	--cat-muted: var(--wp--custom--muted, #5a5f68);
	--cat-primary: var(--brand-primary, #0f4c81);
	--cat-primary-ink: var(--brand-primary-ink, #fff);
	--cat-accent: var(--brand-accent, #e8590c);
	--cat-accent-deep: var(--wp--custom--accent-deep, #bf490a);
	--cat-accent-tint: var(--wp--custom--accent-tint, #fdf1e9);
	--cat-tint: var(--wp--custom--tint, #f2f4f7);
	--cat-dash: color-mix(in srgb, var(--cat-accent) 65%, var(--cat-line));
	--cat-corner: var(--wp--custom--radius, 10px);
	--cat-shadow: var(--wp--custom--shadow-card, 0 8px 24px -12px rgb(20 22 26 / 0.18));
	--cat-gap: var(--wp--preset--spacing--sm, 0.75rem);
	--cat-ease: cubic-bezier(0.2, 0.8, 0.2, 1);
	display: grid;
	/* minmax(0, 1fr) lets the row of chips scroll, and keeps it from making the page wider. */
	grid-template-columns: minmax(0, 1fr);
	gap: var(--wp--preset--spacing--lg, 2rem);
}

.netsite-category-index,
.netsite-category-index * {
	box-sizing: border-box;
}

.netsite-category-index ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

.netsite-category-index li {
	margin: 0;
	padding: 0;
}

.netsite-category-index a {
	color: inherit;
	text-decoration: none;
}

.netsite-category-index a:focus-visible {
	outline: 2px solid var(--cat-accent);
	outline-offset: 3px;
}

.netsite-category-index__heading {
	margin: 0 0 var(--wp--preset--spacing--sm, 0.75rem);
	font-family: var(--font-display, inherit);
	font-weight: var(--display-weight, 700);
	font-size: var(--wp--preset--font-size--large, 1.5rem);
	letter-spacing: var(--track-display, -0.02em);
	line-height: 1.15;
}

/* The chips: one line that scrolls on a telephone, and wraps on a wide screen. */
.netsite-category-index__jump ul {
	display: flex;
	gap: var(--wp--preset--spacing--xs, 0.5rem);
	overflow-x: auto;
	padding-bottom: 0.25rem;
	scroll-snap-type: x proximity;
	scrollbar-width: none;
}

.netsite-category-index__jump ul::-webkit-scrollbar {
	display: none;
}

.netsite-category-index__jump li {
	flex: 0 0 auto;
	scroll-snap-align: start;
}

.netsite-category-index__chip {
	display: inline-block;
	padding: 0.45rem 0.95rem;
	background: var(--cat-surface);
	border: 1px solid var(--cat-line);
	border-radius: 9999px;
	font-size: 0.9375rem;
	font-weight: 600;
	white-space: nowrap;
	transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.netsite-category-index__chip:hover {
	background: var(--cat-primary);
	border-color: var(--cat-primary);
	color: var(--cat-primary-ink);
}

@media (min-width: 48em) {

	.netsite-category-index__jump ul {
		flex-wrap: wrap;
		overflow: visible;
	}
}

/*
 * The coupons of the popular categories. On a telephone they stand in
 * one row that the thumb swipes, and the edge of the next coupon says
 * that there is more.
 */
.netsite-category-index__tickets {
	display: grid;
	grid-auto-columns: 82%;
	grid-auto-flow: column;
	gap: var(--wp--preset--spacing--sm, 0.75rem);
	overflow-x: auto;
	padding: 0.5rem 0.75rem 0.75rem;
	margin: -0.5rem -0.75rem 0;
	scroll-snap-type: x mandatory;
	scroll-padding-inline: 0.75rem;
	scrollbar-width: none;
}

.netsite-category-index__tickets::-webkit-scrollbar {
	display: none;
}

.netsite-category-index__tickets > li {
	scroll-snap-align: start;
}

@media (min-width: 48em) {

	.netsite-category-index__tickets {
		grid-auto-flow: row;
		grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
		gap: var(--wp--preset--spacing--md, 1.25rem);
		overflow: visible;
		padding: 0;
		margin: 0;
	}
}

.netsite-category-ticket {
	display: flex;
	flex-direction: column;
	height: 100%;
	background: var(--cat-surface);
	border: 2px dashed var(--cat-dash);
	border-radius: var(--cat-corner);
	transition: transform 0.2s var(--cat-ease), box-shadow 0.2s var(--cat-ease), border-color 0.2s ease;
}

.netsite-category-ticket:hover {
	border-color: var(--cat-accent);
	box-shadow: var(--cat-shadow);
	transform: translateY(-3px);
}

.netsite-category-ticket__body {
	display: grid;
	flex: 1 1 auto;
	gap: var(--wp--preset--spacing--sm, 0.75rem);
	align-content: start;
	padding: var(--wp--preset--spacing--md, 1.25rem);
}

.netsite-category-ticket__name {
	font-family: var(--font-display, inherit);
	font-weight: var(--display-weight, 700);
	font-size: clamp(1.35rem, 2.5vw, 1.6rem);
	line-height: 1.1;
	letter-spacing: var(--track-display, -0.02em);
	color: var(--cat-primary);
}

.netsite-category-ticket__logos {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 0.5rem;
}

.netsite-category-ticket__logos .netsite-category-index__logo {
	height: 2.75rem;
}

/* The perforation, with a punch hole at each end, as the deal box of the theme. */
.netsite-category-ticket__stub {
	position: relative;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 0.25rem var(--cat-gap);
	padding: var(--wp--preset--spacing--sm, 0.75rem) var(--wp--preset--spacing--md, 1.25rem);
	background: var(--cat-accent-tint);
	border-top: 2px dashed var(--cat-dash);
	border-radius: 0 0 calc(var(--cat-corner) - 2px) calc(var(--cat-corner) - 2px);
}

.netsite-category-ticket__stub::before,
.netsite-category-ticket__stub::after {
	content: "";
	position: absolute;
	top: 0;
	width: 1.1rem;
	height: 1.1rem;
	background: var(--cat-paper);
	border: 2px dashed var(--cat-dash);
	border-radius: 50%;
	transform: translateY(-50%);
}

.netsite-category-ticket__stub::before {
	left: -0.68rem;
	clip-path: inset(-4px -4px -4px 50%);
}

.netsite-category-ticket__stub::after {
	right: -0.68rem;
	clip-path: inset(-4px 50% -4px -4px);
}

.netsite-category-ticket__count {
	font-size: 0.875rem;
	color: var(--cat-muted);
}

.netsite-category-ticket__cta {
	font-weight: 700;
	color: var(--cat-accent-deep);
	white-space: nowrap;
}

.netsite-category-ticket__cta::after {
	content: "\2192";
	display: inline-block;
	margin-left: 0.4em;
	transition: transform 0.2s var(--cat-ease);
}

.netsite-category-ticket:hover .netsite-category-ticket__cta::after {
	transform: translateX(4px);
}

/* A logo box: a white plate that keeps its place before the file arrives. */
.netsite-category-index__logo {
	display: flex;
	align-items: center;
	justify-content: center;
	height: 2rem;
	padding: 0.3rem 0.5rem;
	background: var(--cat-surface);
	border: 1px solid var(--cat-line);
	border-radius: var(--wp--custom--radius-small, 6px);
	overflow: hidden;
}

.netsite-category-index__logo img {
	width: auto;
	height: auto;
	max-width: 100%;
	max-height: 100%;
	object-fit: contain;
}

/* The cards of a group: one on a telephone, as many as fit on a wide screen. */
.netsite-category-index__list {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(min(100%, 16rem), 1fr));
	gap: var(--cat-gap);
}

/*
 * A card reads top down: the name, the first advertisers, the button. The
 * button sits at the foot, so the buttons of one row stand in a line.
 * The selector names the block, so the reset of its list items above
 * does not take the padding away.
 */
.netsite-category-index .netsite-category-card {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--xs, 0.5rem);
	height: 100%;
	padding: var(--wp--preset--spacing--md, 1.25rem);
	background: var(--cat-surface);
	border: 1px solid var(--cat-line);
	border-radius: var(--cat-corner);
}

.netsite-category-card__title {
	margin: 0;
	font-family: var(--font-display, inherit);
	font-weight: var(--display-weight, 700);
	font-size: 1.25rem;
	line-height: 1.2;
	letter-spacing: var(--track-display, -0.02em);
	overflow-wrap: break-word;
	hyphens: auto;
}

.netsite-category-index .netsite-category-card__title a:hover {
	color: var(--cat-primary);
}

/* The first advertisers of a card: small logo plates, three in a row. */
.netsite-category-index .netsite-category-card__shops {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 0.5rem;
	margin: 0 0 var(--wp--preset--spacing--xs, 0.5rem);
}

.netsite-category-index .netsite-category-card__shop {
	height: 2.5rem;
	transition: border-color 0.15s ease;
}

.netsite-category-index .netsite-category-card__shop:hover {
	border-color: var(--cat-primary);
}

/* An advertiser with no logo: its name on the same plate, in two lines at most. */
.netsite-category-card__shop--name {
	color: var(--cat-ink);
	font-size: 0.75rem;
	font-weight: 600;
	line-height: 1.1;
	text-align: center;
	overflow-wrap: break-word;
	hyphens: auto;
}

.netsite-category-card__shop--name:hover {
	color: var(--cat-primary);
}

/* The button: the outline of the first colour of the site, filled on hover. */
.netsite-category-index .netsite-category-card__button {
	display: inline-flex;
	align-self: flex-start;
	align-items: center;
	gap: 0.4em;
	margin-top: auto;
	padding: 0.55rem 1rem;
	border: 2px solid var(--cat-primary);
	border-radius: 9999px;
	color: var(--cat-primary);
	font-weight: 700;
	font-size: 0.9375rem;
	line-height: 1.2;
	transition: background-color 0.15s ease, color 0.15s ease;
}

.netsite-category-index .netsite-category-card__button::after {
	content: "\203A";
	font-size: 1.2em;
	line-height: 1;
	transition: transform 0.2s var(--cat-ease);
}

.netsite-category-index .netsite-category-card__button:hover {
	background: var(--cat-primary);
	color: var(--cat-primary-ink);
}

.netsite-category-index .netsite-category-card__button:hover::after {
	transform: translateX(3px);
}

@media (prefers-reduced-motion: reduce) {

	.netsite-category-ticket,
	.netsite-category-ticket__cta::after,
	.netsite-category-index .netsite-category-card__button::after {
		transition: none;
	}

	.netsite-category-ticket:hover,
	.netsite-category-ticket:hover .netsite-category-ticket__cta::after,
	.netsite-category-index .netsite-category-card__button:hover::after {
		transform: none;
	}
}

/*
 * THE TEST KNOBS (manual 6.1).
 *
 * Each rule below belongs to a knob of a block. A card or a block that
 * holds the default of every knob draws none of these classes.
 */
.netsite-advertisers__card {
	position: relative;
}

/*
 * A card that a campaign paid for says so. The label sits on the end
 * corner, away from the badge. The block draws it, so no author can
 * leave it out. The class holds no "sponsor" or "ad": an ad blocker
 * hides such a class.
 */
.netsite-advertisers__paid {
	position: absolute;
	top: var(--s2, 0.5rem);
	inset-inline-end: var(--s2, 0.5rem);
	z-index: 1;
	padding: 0.2em 0.65em;
	border: 1px solid currentcolor;
	border-radius: 999px;
	background: var(--adv-surface, #fff);
	color: var(--adv-ink, #1f2937);
	font-size: var(--text-xs, 0.75rem);
	font-weight: 700;
	letter-spacing: 0.03em;
	line-height: 1.3;
	text-transform: uppercase;
}

/* One advertiser alone keeps the width of one card. */
.netsite-advertisers--promoted .netsite-advertisers__grid {
	--adv-cols: 3;
}

/* A badge sits on the corner of the card. It claims what the data of the advertiser backs. */
.netsite-advertisers__badge {
	position: absolute;
	top: var(--s2, 0.5rem);
	inset-inline-start: var(--s2, 0.5rem);
	z-index: 1;
	padding: 0.2em 0.65em;
	border-radius: 999px;
	background: var(--adv-button);
	color: var(--adv-button-ink);
	font-size: var(--text-xs, 0.75rem);
	font-weight: 700;
	line-height: 1.3;
}

/* The card layout "offer first": the offer leads, and the logo follows. */
.netsite-advertisers__offer {
	color: var(--adv-ink);
	font-size: var(--text-sm, 0.875rem);
	font-weight: 700;
	line-height: 1.3;
	text-align: center;
	overflow-wrap: break-word;
}

.netsite-advertisers__item--offer-first .netsite-advertisers__offer {
	font-size: var(--text-base, 1rem);
}

/* The "why we recommend" line. */
.netsite-advertisers__why {
	margin: 0;
	color: var(--adv-ink);
	font-size: var(--text-sm, 0.875rem);
	line-height: 1.4;
	text-align: center;
	overflow-wrap: break-word;
}

/* The reason that an editor typed for an advertiser: one line at the foot of the card. */
.netsite-advertisers__reason {
	margin: 0;
	color: var(--adv-ink);
	font-size: var(--text-sm, 0.875rem);
	line-height: 1.4;
	text-align: center;
	overflow-wrap: break-word;
}

/* The code that a press of the button reveals. */
.netsite-advertisers__button.is-revealed {
	font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
	letter-spacing: 0.08em;
}

/* The single block, sticky: it stays at the foot of the screen while the page scrolls. */
.netsite-advertisers--feature.is-sticky {
	position: sticky;
	bottom: var(--s3, 0.75rem);
	z-index: 5;
}

/* The price anchor of the single block: the offer, above the button. */
.netsite-advertisers__anchor {
	display: block;
	margin-top: 0.25rem;
	color: var(--adv-ink);
	font-weight: 700;
}

/*
 * THE SHOP FACTS BLOCK.
 *
 * A definition list: label over text on a phone, and label beside
 * text from 40em. The colours and the corner read the tokens of the
 * theme, with the same fallbacks as the cards above.
 */
.netsite-shop-facts,
.netsite-shop-facts * {
	box-sizing: border-box;
}

.netsite-shop-facts {
	padding: var(--s4, 1rem);
	border: 1px solid var(--line, #e7e4de);
	border-radius: var(--radius, 10px);
	background: var(--surface, var(--paper-white, #fff));
	color: var(--text, #000);
}

.netsite-shop-facts__title {
	margin: 0 0 var(--s3, 0.75rem);
	font-family: var(--font-display, inherit);
	font-weight: var(--display-weight, 600);
	font-size: var(--wp--preset--font-size--medium, 1.125rem);
	line-height: 1.2;
	overflow-wrap: break-word;
}

.netsite-shop-facts__list {
	margin: 0;
}

.netsite-shop-facts__row {
	padding: var(--s2, 0.5rem) 0;
	border-top: 1px solid var(--line, #e7e4de);
}

.netsite-shop-facts__row dt {
	margin: 0;
	color: var(--text-soft, #787574);
	font-size: var(--text-sm, 0.875rem);
	font-weight: 600;
}

.netsite-shop-facts__row dd {
	margin: 0.125rem 0 0;
	overflow-wrap: break-word;
}

.netsite-shop-facts__row--checked dt,
.netsite-shop-facts__row--checked dd {
	color: var(--text-soft, #787574);
	font-size: var(--text-sm, 0.875rem);
}

@media (min-width: 40em) {
	.netsite-shop-facts__row {
		display: grid;
		grid-template-columns: 10rem 1fr;
		gap: var(--s4, 1rem);
	}

	.netsite-shop-facts__row dd {
		margin: 0;
	}

	.netsite-shop-facts__row dd + dd {
		grid-column: 2;
	}
}
