/*
Theme Name: 1ity
Theme URI: https://1ity.com
Description: Storefront theme for 1ity.com digital downloads. Child of Twenty Twenty-Five so the block editor and WooCommerce block templates stay available; all 1ity styling lives here, never in the parent.
Author: 1ity
Template: twentytwentyfive
Version: 0.14.0
Requires at least: 6.7
Tested up to: 7.1
Requires PHP: 8.1
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: 1ity
Tags: e-commerce
*/

/* -----------------------------------------------------------------------------
 * Design tokens (spec v2 §5.3)
 *
 * The values live in `theme.json`, once: ten palette entries and the radius
 * scale (`settings.color.palette`, `settings.custom.radius`), plus the container
 * width (`settings.layout.wideSize`). WordPress publishes them as
 * `--wp--preset--color--*` and `--wp--custom--radius--*`, so the Site Editor and
 * the CSS read the same numbers.
 *
 * The names below are the contract's own (`--1ity-*`), mapped onto those presets
 * so a stylesheet can be written against §5.3 without repeating a hex value. Add
 * a token in theme.json first, map it here second, use it third. A literal colour
 * in this file is a bug — `scripts/verify-tokens.php` fails the build for one.
 *
 * Note the prefixes: `--1ity-*` (digit one) are design tokens and come from the
 * contract; `--iity-*` (double i) are this theme's internal shorthands, used only
 * in this file. They were renamed from `--iity-border`/`--iity-focus` so that a
 * border *colour* and a border *shorthand* cannot be confused at a glance.
 * -------------------------------------------------------------------------- */

:root {
	/* Colour */
	--1ity-primary: var(--wp--preset--color--primary);
	--1ity-secondary: var(--wp--preset--color--secondary);
	--1ity-background: var(--wp--preset--color--base);
	--1ity-surface: var(--wp--preset--color--surface);
	--1ity-text: var(--wp--preset--color--contrast);
	--1ity-muted: var(--wp--preset--color--muted);
	--1ity-border: var(--wp--preset--color--border);
	--1ity-success: var(--wp--preset--color--success);
	--1ity-warning: var(--wp--preset--color--warning);
	--1ity-danger: var(--wp--preset--color--danger);

	/* Radii */
	--1ity-radius-sm: var(--wp--custom--radius--sm);
	--1ity-radius-md: var(--wp--custom--radius--md);
	--1ity-radius-lg: var(--wp--custom--radius--lg);

	/* Layout */
	--1ity-container: var(--wp--style--global--wide-size);

	/* Theme-internal shorthands — not tokens, never referenced outside this file. */
	--iity-header-height: 4.5rem;
	--iity-rule: 1px solid var(--1ity-border);
	--iity-outline: 2px solid var(--1ity-text);
}

/* -----------------------------------------------------------------------------
 * Header
 * -------------------------------------------------------------------------- */

.site-header {
	position: sticky;
	top: 0;
	z-index: 100;
	border-bottom: var(--iity-rule);
	background-color: var(--wp--preset--color--base);
}

.site-header__inner {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--30);
	align-items: center;
	justify-content: space-between;
	min-height: var(--iity-header-height);
}

.site-header__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--40);
	align-items: center;
}

.site-header .wp-block-site-title {
	font-size: var(--wp--preset--font-size--large);
	font-weight: 700;
	letter-spacing: -0.01em;
	margin: 0;
}

.site-header .wp-block-site-title a {
	text-decoration: none;
}

/*
 * The header's second row (`spec v2` §6.1).
 *
 * The contract asks the header to name the six families, and a shop's families are
 * a bar of their own rather than five more words in the primary menu: the menu is
 * editorial (Shop, About, FAQ, Contact) and the bar is the catalogue, read from
 * `product_cat`. Search shares the row, right-aligned on a wide screen.
 */
.site-header__bar {
	gap: var(--wp--preset--spacing--30);
	padding-block: var(--wp--preset--spacing--20);
	border-top: var(--iity-rule);
}

.site-category-nav__list {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--30);
	margin: 0;
	padding: 0;
	list-style: none;
}

.site-category-nav__link {
	display: inline-block;
	padding-block: 0.2rem;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	color: var(--1ity-text);
	text-decoration: none;
	border-bottom: 2px solid transparent;
}

.site-category-nav__link:hover,
.site-category-nav__link:focus-visible {
	border-bottom-color: currentColor;
}

/* The account entry (`iity/account-link`) sits with the menu and the cart. */
.site-account {
	margin: 0;
}

.site-account__link {
	display: inline-block;
	padding-block: 0.35rem;
	color: inherit;
	text-decoration: none;
	border-bottom: 2px solid transparent;
}

.site-account__link:hover,
.site-account__link:focus-visible {
	border-bottom-color: currentColor;
}

/*
 * The catalogue search (`iity/search-form`). A real `<form>` with a real button:
 * `flex: 1 1 16rem` lets it take the row's spare width on a desktop and drop to
 * its own line under the families on a phone, which is the whole of the mobile
 * behaviour it needs.
 */
.iity-search {
	display: flex;
	flex-wrap: nowrap;
	justify-content: flex-end;
	gap: 0.4rem;
	flex: 1 1 16rem;
	max-width: 26rem;
	margin: 0;
}

.iity-search__field,
.iity-search__submit {
	min-height: 2.5rem;
	padding: 0.35rem 0.7rem;
	border-radius: var(--1ity-radius-sm);
	font: inherit;
	font-size: var(--wp--preset--font-size--small);
}

.iity-search__field {
	flex: 1 1 auto;
	min-width: 0;
	border: var(--iity-rule);
	background: var(--wp--preset--color--base);
	color: inherit;
}

.iity-search__submit {
	border: 1px solid var(--wp--preset--color--primary);
	background: var(--wp--preset--color--primary);
	color: var(--wp--preset--color--base);
	cursor: pointer;
}

.iity-search__submit:hover,
.iity-search__submit:focus {
	background: transparent;
	color: var(--wp--preset--color--primary);
}

/* -----------------------------------------------------------------------------
 * Navigation (rendered by the iity/nav block)
 * -------------------------------------------------------------------------- */

.site-nav__list {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--40);
	margin: 0;
	padding: 0;
	list-style: none;
}

.site-nav__list a,
.site-footer .site-nav__list a {
	display: inline-block;
	padding-block: 0.35rem;
	color: inherit;
	text-decoration: none;
	border-bottom: 2px solid transparent;
}

.site-nav__list a:hover,
.site-nav__list a:focus-visible {
	border-bottom-color: currentColor;
}

.site-nav__list .current-menu-item > a,
.site-nav__list .current_page_item > a {
	border-bottom-color: currentColor;
	font-weight: 600;
}

/* Keyboard focus stays visible everywhere, including block buttons. */
:where(a, button, summary, .wp-element-button):focus-visible {
	outline: var(--iity-outline);
	outline-offset: 2px;
}

/* -----------------------------------------------------------------------------
 * Search results (`templates/product-search-results.html`, spec v2 §6.1)
 *
 * The row above the grid holds the field (so a phrase can be changed without
 * going back) and WooCommerce's sorting control. Below it, one block says what
 * happened — the count, or that nothing matched and where else to look.
 * -------------------------------------------------------------------------- */

.iity-search__bar {
	gap: var(--wp--preset--spacing--30);
	margin-block: 0 var(--wp--preset--spacing--40);
}

.iity-search__bar .iity-search {
	max-width: 30rem;
}

.iity-search-summary {
	max-width: 65ch;
	margin-block: 0 var(--wp--preset--spacing--40);
}

.iity-search-summary__line {
	margin-block: 0;
	font-weight: 600;
}

.iity-search-summary--empty .iity-search-summary__line {
	margin-block-end: var(--wp--preset--spacing--20);
}

.iity-search-summary__next {
	margin: 0;
	color: color-mix(in srgb, var(--1ity-text) 80%, transparent);
}

/* -----------------------------------------------------------------------------
 * Content scaffolding
 * -------------------------------------------------------------------------- */

.iity-hero {
	padding: var(--wp--preset--spacing--60) var(--wp--preset--spacing--50);
	border-radius: var(--1ity-radius-md);
}

.iity-callout {
	padding: var(--wp--preset--spacing--50);
	border-radius: var(--1ity-radius-md);
}

.iity-hero__title {
	font-size: clamp(1.9rem, 4vw, 2.75rem);
	line-height: 1.15;
	max-width: 20ch;
}

.iity-hero__lede {
	font-size: var(--wp--preset--font-size--medium);
	max-width: 60ch;
}

.iity-flow > * + * {
	margin-block-start: var(--wp--preset--spacing--40);
}

.iity-steps {
	padding-inline-start: 1.25rem;
}

.iity-steps > li + li {
	margin-block-start: var(--wp--preset--spacing--20);
}

/* Links inserted by iity/page-link and iity/support-email. */
.iity-link,
.iity-support-email {
	margin-block: 0;
}

/* "Browse 3D models" links inside the front-page family cards (STR-02). */
.iity-card-link {
	margin-block: 0;
	font-weight: 600;
}

.iity-link--unavailable {
	text-decoration: underline dotted;
}

/* A page that is a draft must never look clickable to a visitor. */

/* Draft notices are only ever visible to logged-in editors (the pages they
   live on are drafts), so they are allowed to shout. */
.iity-draft-notice {
	padding: var(--wp--preset--spacing--30);
	border: 2px dashed currentColor;
	border-radius: var(--1ity-radius-sm);
	font-weight: 600;
}

/* -----------------------------------------------------------------------------
 * Front page sections (blocks/home-*, STR-16)
 *
 * One section wrapper, one card, one product card — the blocks carry the data,
 * this file carries the grid. Every row is `auto-fit`/`auto-fill`, so the same
 * markup answers a 320 px phone and a 1280 px container without a breakpoint,
 * and a row that renders nothing (an empty "Best sellers") leaves no gap.
 * -------------------------------------------------------------------------- */

.iity-section {
	margin-block-start: var(--wp--preset--spacing--70);
}

.iity-section__title {
	margin-block: 0 var(--wp--preset--spacing--40);
}

/* Said out loud instead of a broken grid: an empty catalogue, or a catalogue
 * with no categories in it yet. */
.iity-section__empty {
	max-width: 60ch;
	margin: 0;
	padding: var(--wp--preset--spacing--40);
	border: 1px dashed var(--1ity-border);
	border-radius: var(--1ity-radius-md);
	color: var(--1ity-muted);
}

/* Category cards */
.iity-cards,
.iity-products,
.iity-assurances {
	margin: 0;
	padding: 0;
	list-style: none;
}

.iity-cards {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
	gap: var(--wp--preset--spacing--30);
}

.iity-card {
	display: flex;
}

/* The whole card is the link: one target, and the heading inside it is still a
 * heading for anyone navigating by headings. */
.iity-card__link {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--20);
	width: 100%;
	padding: var(--wp--preset--spacing--40);
	border: var(--iity-rule);
	border-radius: var(--1ity-radius-md);
	background-color: var(--1ity-background);
	color: inherit;
	text-decoration: none;
}

.iity-card__link:hover,
.iity-card__link:focus-visible {
	border-color: var(--1ity-primary);
	outline: var(--iity-outline);
	outline-offset: 2px;
}

.iity-card__title {
	margin: 0;
	font-size: var(--wp--preset--font-size--medium);
	line-height: 1.3;
}

.iity-card__text {
	margin: 0;
	font-size: var(--wp--preset--font-size--small);
	color: color-mix(in srgb, var(--1ity-text) 78%, transparent);
}

.iity-card__meta {
	margin-block-start: auto;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	color: var(--1ity-muted);
}

.iity-card--empty .iity-card__meta {
	font-weight: 400;
}

/* Product cards */
.iity-products {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
	gap: var(--wp--preset--spacing--40);
}

.iity-product-card {
	display: flex;
	flex-direction: column;
	overflow: hidden;
	border: var(--iity-rule);
	border-radius: var(--1ity-radius-md);
	background-color: var(--1ity-background);
}

.iity-product-card__media img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	background-color: var(--1ity-surface);
}

.iity-product-card__body {
	display: flex;
	flex: 1;
	flex-direction: column;
	gap: var(--wp--preset--spacing--20);
	padding: var(--wp--preset--spacing--30);
}

.iity-product-card__type {
	font-size: var(--wp--preset--font-size--small);
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--1ity-muted);
}

.iity-product-card__title {
	margin: 0;
	font-size: var(--wp--preset--font-size--medium);
	line-height: 1.3;
}

.iity-product-card__title a {
	color: inherit;
	text-decoration: none;
}

.iity-product-card__title a:hover,
.iity-product-card__title a:focus-visible {
	text-decoration: underline;
}

.iity-product-card__text {
	margin: 0;
	font-size: var(--wp--preset--font-size--small);
	color: color-mix(in srgb, var(--1ity-text) 78%, transparent);
}

.iity-product-card__price {
	margin: 0;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
}

.iity-product-card__price del {
	font-weight: 400;
	color: var(--1ity-muted);
}

/* The saving is a number and a word, not a red sticker: it stays legible in
 * greyscale and to a screen reader. */
.iity-product-card__discount {
	margin-inline-start: 0.5rem;
	padding: 0.1rem 0.4rem;
	border-radius: var(--1ity-radius-sm);
	background-color: var(--1ity-text);
	color: var(--1ity-background);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
}

.iity-product-card__rating {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.35rem;
	margin: 0;
	font-size: var(--wp--preset--font-size--small);
	color: var(--1ity-muted);
}

.iity-product-card__rating .star-rating {
	margin: 0;
}

/* Pushed to the bottom of every card so the buttons in a row line up, whatever
 * the length of the description above them. */
.iity-product-card__cta {
	margin-block-start: auto;
	padding-block-start: var(--wp--preset--spacing--20);
	border-top: var(--iity-rule);
	font-weight: 600;
}

/* "Why 1ity?" */
.iity-assurances {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
	gap: var(--wp--preset--spacing--40);
}

.iity-assurance {
	padding-block-start: var(--wp--preset--spacing--20);
	border-top: var(--iity-rule);
}

.iity-assurance__title {
	margin: 0 0 var(--wp--preset--spacing--20);
	font-size: var(--wp--preset--font-size--medium);
	line-height: 1.3;
}

.iity-assurance__text {
	max-width: 48ch;
	margin: 0;
	font-size: var(--wp--preset--font-size--small);
	color: color-mix(in srgb, var(--1ity-text) 78%, transparent);
}

/* -----------------------------------------------------------------------------
 * Product archive
 *
 * templates/archive-product.html puts the filter sidebar beside the product
 * grid. The filters themselves are ordinary links rendered by
 * iity/archive-filters, so everything works without JavaScript; this file only
 * says where the pieces sit.
 * -------------------------------------------------------------------------- */

.iity-archive {
	gap: var(--wp--preset--spacing--60);
}

.iity-archive__sidebar,
.iity-archive__results {
	min-width: 0;
}

/* An archive with nothing worth filtering renders the block with `hidden`; an
   empty column must not leave a 240px gutter beside the products. */
.iity-archive__sidebar:has(.iity-filters--empty) {
	display: none;
}

.iity-filters__head {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--20);
	align-items: baseline;
	justify-content: space-between;
	margin-block-end: var(--wp--preset--spacing--30);
}

.iity-filters__title {
	font-size: var(--wp--preset--font-size--medium);
	margin: 0;
}

.iity-filters__clear {
	font-size: var(--wp--preset--font-size--small);
}

.iity-filters__groups,
.iity-filters__values {
	margin: 0;
	padding: 0;
	list-style: none;
}

.iity-filters__group + .iity-filters__group {
	margin-block-start: var(--wp--preset--spacing--40);
	padding-block-start: var(--wp--preset--spacing--30);
	border-top: var(--iity-rule);
}

.iity-filters__group-title {
	font-size: var(--wp--preset--font-size--small);
	text-transform: uppercase;
	letter-spacing: 0.08em;
	margin-block: 0 var(--wp--preset--spacing--20);
}

/* The count sits at the right edge, so the values read as one column of text
   with their numbers lined up. */
.iity-filters__values a {
	display: flex;
	gap: 0.75ch;
	justify-content: space-between;
	padding-block: 0.2rem;
	color: inherit;
	text-decoration: none;
}

.iity-filters__values a:hover,
.iity-filters__values a:focus-visible {
	text-decoration: underline;
}

.iity-filters__value--active {
	font-weight: 600;
}

.iity-filters__count {
	color: color-mix(in srgb, currentColor 60%, transparent);
	font-variant-numeric: tabular-nums;
}

/* -----------------------------------------------------------------------------
 * Product page
 *
 * templates/single-product.html puts the buy box and the specification table
 * where a customer reads them before paying. Both are deliberately plain: rows
 * with one hairline border, and a small screen stacks label over value instead
 * of squeezing a two-column table.
 * -------------------------------------------------------------------------- */

.iity-product-top {
	gap: var(--wp--preset--spacing--50);
}

/*
 * The licence selector (STR-21). Every option states its tier's price, because
 * choosing a licence is choosing what to pay; the rules below only make that
 * readable. The field is a plain `select` and the money is in the labels, so
 * nothing here depends on JavaScript running — WooCommerce's variation script
 * adds the chosen tier's price and terms underneath, and when it does not run
 * the option labels and the licence table still state all three prices.
 */

.iity-product-top form.cart table.variations {
	width: 100%;
	margin-block: 0 var(--wp--preset--spacing--30);
	border-collapse: collapse;
}

.iity-product-top form.cart table.variations th,
.iity-product-top form.cart table.variations td {
	padding-block: 0.4rem;
	text-align: start;
	vertical-align: middle;
	font-weight: inherit;
}

.iity-product-top form.cart table.variations .label {
	white-space: nowrap;
	padding-inline-end: var(--wp--preset--spacing--30);
	font-weight: 600;
}

.iity-product-top form.cart table.variations select {
	width: 100%;
	max-width: 28rem;
	padding-block: 0.55rem;
	padding-inline: 0.7rem;
	border: var(--iity-rule);
	border-radius: var(--1ity-radius-sm);
	background-color: var(--1ity-surface);
	color: inherit;
	font: inherit;
}

.iity-product-top .reset_variations {
	margin-inline-start: 0.75rem;
	font-size: var(--wp--preset--font-size--small, 0.875rem);
}

/*
 * The two lines WooCommerce's own script fills when a tier is chosen: the price
 * of that tier and its description, which the seeder writes as the tier's
 * permitted use. They sit inside the form, not over the price block above,
 * so the range and the chosen price are never mistaken for one another.
 */

.iity-product-top .single_variation_wrap .woocommerce-variation-price {
	margin-block: 0 var(--wp--preset--spacing--20);
	font-size: var(--wp--preset--font-size--large);
	font-variant-numeric: tabular-nums;
}

.iity-product-top .single_variation_wrap .woocommerce-variation-description {
	max-width: 60ch;
	margin-block: 0 var(--wp--preset--spacing--20);
}

@media (max-width: 480px) {
	.iity-product-top form.cart table.variations,
	.iity-product-top form.cart table.variations tbody,
	.iity-product-top form.cart table.variations tr,
	.iity-product-top form.cart table.variations th,
	.iity-product-top form.cart table.variations td {
		display: block;
	}

	.iity-product-top form.cart table.variations .label {
		padding-inline-end: 0;
	}
}

.iity-facts {
	margin-block-start: var(--wp--preset--spacing--50);
}

.iity-facts__title {
	font-size: var(--wp--preset--font-size--medium);
	letter-spacing: 0.02em;
	margin-block: 0 var(--wp--preset--spacing--30);
}

.iity-facts__list {
	margin: 0;
	border-top: var(--iity-rule);
}

.iity-facts__row {
	display: grid;
	grid-template-columns: minmax(8rem, 14rem) 1fr;
	gap: var(--wp--preset--spacing--30);
	padding-block: 0.65rem;
	border-bottom: var(--iity-rule);
}

.iity-facts__label {
	font-weight: 600;
}

.iity-facts__value {
	margin: 0;
	overflow-wrap: anywhere;
}

/*
 * Licence tiers (blocks/licence-terms): the same file at three prices. The
 * table is the whole block, so it carries the rules a table needs — a header
 * row on a wide screen, a stacked card per tier on a narrow one, where the
 * column names come back as the data-label of each cell.
 */

.iity-licence {
	margin-block-start: var(--wp--preset--spacing--50);
}

.iity-licence__title {
	font-size: var(--wp--preset--font-size--medium);
	letter-spacing: 0.02em;
	margin-block: 0 var(--wp--preset--spacing--30);
}

.iity-licence__warning {
	margin-block: 0 var(--wp--preset--spacing--30);
	padding: 0.6rem 0.8rem;
	border-inline-start: 3px solid currentColor;
	background: color-mix(in srgb, currentColor 6%, transparent);
}

.iity-licence__intro,
.iity-licence__note {
	margin-block: 0 var(--wp--preset--spacing--30);
	max-width: 60ch;
}

.iity-licence__note {
	color: color-mix(in srgb, currentColor 75%, transparent);
}

.iity-licence__table {
	width: 100%;
	border-collapse: collapse;
	border-top: var(--iity-rule);
	margin-block: var(--wp--preset--spacing--30);
}

.iity-licence__table th,
.iity-licence__table td {
	text-align: start;
	vertical-align: top;
	padding: 0.65rem 1rem 0.65rem 0;
	border-bottom: var(--iity-rule);
	font-weight: inherit;
}

.iity-licence__table thead th {
	font-size: var(--wp--preset--font-size--small, 0.875rem);
	font-weight: 600;
	letter-spacing: 0.04em;
	text-transform: uppercase;
}

.iity-licence__table tbody th {
	font-weight: 600;
}

.iity-licence__price {
	white-space: nowrap;
	font-variant-numeric: tabular-nums;
}

@media (max-width: 640px) {
	.iity-licence__table,
	.iity-licence__table tbody,
	.iity-licence__table tr,
	.iity-licence__table th,
	.iity-licence__table td {
		display: block;
	}

	.iity-licence__table thead {
		display: none;
	}

	.iity-licence__table tr {
		padding-block: 0.75rem;
		border-bottom: var(--iity-rule);
	}

	.iity-licence__table th,
	.iity-licence__table td {
		padding: 0;
		border-bottom: 0;
	}

	.iity-licence__table tbody th {
		margin-block-end: 0.35rem;
	}

	.iity-licence__table tbody td + td {
		margin-block-start: 0.35rem;
	}

	.iity-licence__table tbody td::before {
		content: attr(data-label) ": ";
		font-weight: 600;
	}
}

.iity-product-description {
	margin-block-start: var(--wp--preset--spacing--60);
}

/* The specification table spans the wide area; the description reads at
 * content width. WordPress centres a constrained group's children inside it —
 * with `!important` — which indents the description under a wider table.
 * Align it to the same left edge so the page reads as one column. */
.iity-product-description.is-layout-constrained
	> :where(:not(.alignleft):not(.alignright):not(.alignfull)) {
	margin-inline-start: 0 !important;
	margin-left: 0 !important;
}

/* -----------------------------------------------------------------------------
 * Asset turntable (blocks/asset-turntable, STR-09)
 *
 * One PNG holds every frame of one rotation; the animation walks a window
 * across it in `steps()`, so there is no JavaScript and no request per frame.
 * The frame size and frame count arrive as custom properties from the block,
 * which is why a strip redrawn with a different number of frames plays at the
 * right speed without a CSS edit.
 * -------------------------------------------------------------------------- */

.iity-turntable {
	margin-block-start: var(--wp--preset--spacing--50);
}

.iity-turntable__title {
	font-size: var(--wp--preset--font-size--medium);
	letter-spacing: 0.02em;
	margin-block: 0 var(--wp--preset--spacing--30);
}

.iity-turntable__stage {
	width: var(--iity-turntable-frame, 300px);
	height: var(--iity-turntable-frame, 300px);
	max-width: 100%;
	background-color: transparent;
	background-image: var(--iity-turntable-image);
	background-repeat: no-repeat;
	background-position: 0 0;
	background-size: calc(var(--iity-turntable-frame, 300px) * var(--iity-turntable-frames, 24))
		var(--iity-turntable-frame, 300px);
	animation: iity-turntable-turn var(--iity-turntable-duration, 3s)
		steps(var(--iity-turntable-frames, 24)) infinite;
}

/* A preview should never be impossible to stop looking at: hovering holds the
 * frame the reader is on. */
.iity-turntable__stage:hover {
	animation-play-state: paused;
}

@keyframes iity-turntable-turn {
	from {
		background-position-x: 0;
	}

	to {
		background-position-x: calc(
			var(--iity-turntable-frame, 300px) * var(--iity-turntable-frames, 24) * -1
		);
	}
}

.iity-turntable__caption {
	margin-block: var(--wp--preset--spacing--30) 0;
	max-width: 60ch;
	color: color-mix(in srgb, currentColor 75%, transparent);
}

/* -----------------------------------------------------------------------------
 * Footer
 * -------------------------------------------------------------------------- */

.site-footer {
	margin-block-start: var(--wp--preset--spacing--70);
	padding-block: var(--wp--preset--spacing--60);
	border-top: var(--iity-rule);
	background-color: var(--1ity-surface);
	font-size: var(--wp--preset--font-size--small);
}

.site-footer__columns .wp-block-column {
	min-width: 0;
}

.site-footer .wp-block-site-title {
	font-size: var(--wp--preset--font-size--medium);
	margin-block: 0 var(--wp--preset--spacing--20);
}

.site-footer__blurb {
	max-width: 34ch;
}

/* Column headings are printed by iity/nav, so they disappear together with a
 * menu that has nothing in it (the legal pages stay drafts until LAU-14). */
.site-nav__heading {
	margin-block: 0 var(--wp--preset--spacing--30);
	font-size: var(--wp--preset--font-size--small);
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

/* A footer column whose only child printed nothing is not an empty column, it is
 * a column that does not exist yet: take it out of the grid rather than leaving
 * a gap where "Legal" will be. */
.site-footer__columns .wp-block-column:empty {
	display: none;
}

.site-footer .site-nav__list {
	flex-direction: column;
	gap: var(--wp--preset--spacing--20);
}

.site-footer__bottom {
	margin-block-start: var(--wp--preset--spacing--50);
	padding-block-start: var(--wp--preset--spacing--30);
	border-top: var(--iity-rule);
}

.site-footer__bottom p {
	margin: 0;
}

/* -----------------------------------------------------------------------------
 * Small screens
 * -------------------------------------------------------------------------- */

@media (max-width: 781px) {
	.site-header {
		position: static;
	}

	.site-header__inner,
	.site-header__actions {
		justify-content: space-between;
	}

	.site-header__actions {
		width: 100%;
	}

	/*
	 * The families bar and the search field share a row on a desktop; on a phone
	 * they stack, and the field takes the full width so the button is reachable
	 * with a thumb. This is the header's whole responsive behaviour: nothing is
	 * hidden behind a menu that has to be opened, so nothing can be missed.
	 */
	.site-header__bar {
		padding-block-end: var(--wp--preset--spacing--30);
	}

	.site-header__bar .iity-search {
		flex: 1 1 100%;
		max-width: none;
	}

	/*
	 * The specification table is a two-column grid; on a phone the value column
	 * is squeezed to a few characters per line, so the label sits above its
	 * value instead. (The licence table stacks the same way, in its own block.)
	 */
	.iity-facts__row {
		grid-template-columns: 1fr;
		gap: 0.15rem;
	}
}

@media (prefers-reduced-motion: reduce) {
	* {
		scroll-behavior: auto !important;
		transition-duration: 0.01ms !important;
		animation-duration: 0.01ms !important;
	}

	/*
	 * A stepped turntable at 0.01ms per revolution is not "reduced motion", it is
	 * a strobe. The preview simply holds its first frame instead.
	 */
	.iity-turntable__stage {
		animation: none !important;
	}
}

/* -----------------------------------------------------------------------------
 * My Account download library (includes/account-downloads.php, DLV-08)
 *
 * The table WooCommerce prints for a download answers two questions; this one
 * answers four. Attempts left and the date access ends are the numbers the
 * licence is actually enforced by (iity_download_policy()), and a buyer who
 * cannot download needs the reason in the last column instead of a button that
 * refuses. It stacks on a phone the way the licence table does — `data-label`
 * becomes the row's labels, so nothing is lost when the header row is hidden.
 * -------------------------------------------------------------------------- */

.iity-downloads__title {
	font-size: var(--wp--preset--font-size--medium);
	letter-spacing: 0.02em;
	margin-block: 0 var(--wp--preset--spacing--30);
}

.iity-downloads__lede {
	margin-block: 0 var(--wp--preset--spacing--30);
	max-width: 60ch;
	color: color-mix(in srgb, currentColor 80%, transparent);
}

.iity-downloads__table {
	width: 100%;
	border-collapse: collapse;
	border-top: var(--iity-rule);
}

.iity-downloads__table th,
.iity-downloads__table td {
	text-align: start;
	vertical-align: top;
	padding: 0.75rem 1rem 0.75rem 0;
	border-bottom: var(--iity-rule);
	font-weight: inherit;
}

.iity-downloads__table thead th {
	font-size: var(--wp--preset--font-size--small, 0.875rem);
	font-weight: 600;
	letter-spacing: 0.04em;
	text-transform: uppercase;
}

/* The row is linked from WooCommerce's own surfaces, and the header is sticky. */
.iity-downloads__row {
	scroll-margin-block-start: calc(var(--iity-header-height) + 1rem);
}

.iity-downloads__name {
	display: block;
	font-weight: 600;
}

.iity-downloads__meta,
.iity-downloads__reason {
	display: block;
	font-size: var(--wp--preset--font-size--small, 0.875rem);
	color: color-mix(in srgb, currentColor 75%, transparent);
}

.iity-downloads__count,
.iity-downloads__expires {
	white-space: nowrap;
	font-variant-numeric: tabular-nums;
}

.iity-downloads__state {
	display: block;
	font-weight: 600;
}

.iity-downloads__button {
	display: inline-block;
	padding: 0.45rem 1.1rem;
	border: 1px solid var(--wp--preset--color--contrast);
	border-radius: 999px;
	background: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
	font-size: var(--wp--preset--font-size--small, 0.875rem);
	text-decoration: none;
	white-space: nowrap;
}

.iity-downloads__button:hover,
.iity-downloads__button:focus {
	background: transparent;
	color: var(--wp--preset--color--contrast);
}

.iity-downloads__button:focus-visible {
	outline: var(--iity-outline);
	outline-offset: 2px;
}

@media (max-width: 640px) {
	.iity-downloads__table,
	.iity-downloads__table tbody,
	.iity-downloads__table tr,
	.iity-downloads__table th,
	.iity-downloads__table td {
		display: block;
	}

	.iity-downloads__table thead {
		display: none;
	}

	.iity-downloads__table tr {
		padding-block: 0.9rem;
	}

	.iity-downloads__table th,
	.iity-downloads__table td {
		padding: 0;
		border-bottom: 0;
	}

	.iity-downloads__table tbody td + td {
		margin-block-start: 0.4rem;
	}

	.iity-downloads__table tbody td::before {
		content: attr(data-label) ": ";
		font-weight: 600;
	}

	.iity-downloads__button {
		margin-block-start: 0.2rem;
	}
}

/* -----------------------------------------------------------------------------
 * Download recovery (1ity-core includes/download-recovery.php, DLV-09)
 *
 * The form a buyer uses when the email never arrived. It is deliberately plain:
 * two fields, a button, and — once it has answered — either one sentence or the
 * same row table as the library (`blocks/download-recovery/render.php` renders
 * it, the plugin decides what is in it). Fields stack below 640px, which is also
 * where the table above them stops being a table.
 * -------------------------------------------------------------------------- */

.iity-recovery {
	margin-block: var(--wp--preset--spacing--50, 2rem) 0;
	padding-block-start: var(--wp--preset--spacing--30, 1rem);
	border-top: var(--iity-rule);
	max-width: 46rem;
}

.iity-recovery__title {
	font-size: var(--wp--preset--font-size--medium);
	letter-spacing: 0.02em;
	margin-block: 0 var(--wp--preset--spacing--30);
}

.iity-recovery__lede,
.iity-recovery__write {
	margin-block: 0 var(--wp--preset--spacing--30);
	max-width: 60ch;
	color: color-mix(in srgb, currentColor 80%, transparent);
}

.iity-recovery__form {
	display: flex;
	flex-wrap: wrap;
	align-items: end;
	gap: var(--wp--preset--spacing--30, 1rem);
	margin-block-end: var(--wp--preset--spacing--40, 1.5rem);
}

.iity-recovery__field {
	display: flex;
	flex-direction: column;
	gap: 0.35rem;
	flex: 1 1 14rem;
	margin: 0;
}

.iity-recovery__field label {
	font-size: var(--wp--preset--font-size--small, 0.875rem);
	font-weight: 600;
	letter-spacing: 0.02em;
}

.iity-recovery__field input {
	padding: 0.5rem 0.7rem;
	border: var(--iity-rule);
	border-radius: var(--1ity-radius-sm);
	background: var(--wp--preset--color--base);
	color: inherit;
	font: inherit;
	min-height: 2.75rem;
}

.iity-recovery__field input:focus-visible,
.iity-recovery__submit button:focus-visible {
	outline: var(--iity-outline);
	outline-offset: 2px;
}

.iity-recovery__submit {
	margin: 0;
}

.iity-recovery__submit button {
	padding: 0.45rem 1.1rem;
	min-height: 2.75rem;
	border: 1px solid var(--wp--preset--color--contrast);
	border-radius: 999px;
	background: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
	font: inherit;
	font-size: var(--wp--preset--font-size--small, 0.875rem);
	cursor: pointer;
}

.iity-recovery__submit button:hover,
.iity-recovery__submit button:focus {
	background: transparent;
	color: var(--wp--preset--color--contrast);
}

.iity-recovery__result {
	margin-block: 0 var(--wp--preset--spacing--30);
	font-weight: 600;
	max-width: 60ch;
}

.iity-recovery__result--throttled {
	color: color-mix(in srgb, var(--1ity-text) 70%, var(--1ity-danger));
}

@media (max-width: 640px) {
	.iity-recovery__form {
		align-items: stretch;
	}

	.iity-recovery__submit button {
		width: 100%;
	}
}

