/*
 * Content templates — articles, archives, search, 404, and the About/Contacts pages.
 *
 * Scope: everything the old theme rendered from `index.php`, `page-aboutus.php`,
 * `single-*.php`, `category-clients.php`, `category-photogallery.php`, `404.php` and
 * `maps.php`. The commerce, shell and homepage streams own their own files.
 *
 * Rules this file follows (DESIGN.md):
 *   - tokens only; a literal colour, font size or spacing value here is a bug
 *   - container queries, never viewport breakpoints — a card grid does not care how wide
 *     the WINDOW is, it cares how wide ITS COLUMN is
 *   - reading measure capped near 70 characters; long tables are the documented exception
 */

/* ---------------------------------------------------------------------------
 * Rhythm
 *
 * The old templates separated everything with `<hr>` — a horizontal rule used as a spacer,
 * which is a divider announced to a screen reader on every scroll. Space does that job here.
 * ------------------------------------------------------------------------ */

/*
 * Bottom padding is `md`, not `xl`. The footer already opens with its own top margin, and the
 * two stacked read as one gap: measured on /category/stati/ at 1440px, the last line of the
 * pagination sat ~230px above the footer band — `xl` (86px) plus the footer's `xxl` (144px) —
 * which reads as the page having ended early. `md` here plus `lg` there lands at ~78px: still
 * a clear break between content and footer, without the hole.
 */
.nv-main {
	padding-block: var(--wp--preset--spacing--lg) var(--wp--preset--spacing--md);
}

.nv-article > * + *,
.nv-listing > * + * {
	margin-block-start: var(--wp--preset--spacing--lg);
}

/* ---------------------------------------------------------------------------
 * Article / page body
 * ------------------------------------------------------------------------ */

.nv-article__title {
	font-size: var(--wp--preset--font-size--xxxl);
	max-inline-size: 20ch;
	margin-block-end: var(--wp--preset--spacing--sm);
	text-wrap: balance;
}

.nv-article__figure {
	margin-block: var(--wp--preset--spacing--md);
}

.nv-article__figure img {
	inline-size: 100%;
	block-size: auto;
	border-radius: var(--wp--custom--radius--lg);
}

/*
 * The client posts are LOGOS, not photographs. The old theme handled that with a Bootstrap
 * `col-md-4 col-md-offset-4` on a duplicate template; a max width on the figure does the same
 * thing for every template at once, and a logo blown to 1280px wide looks like a mistake.
 */
.nv-article__figure {
	max-inline-size: min(100%, 44rem);
	margin-inline: auto;
}

/*
 * Prose: the reading column. 70ch is the measure DESIGN.md asks for; tables and galleries
 * break out because a specification table squeezed into 70ch is unreadable.
 */
.nv-prose {
	max-inline-size: 70ch;
}

.nv-prose--wide {
	max-inline-size: none;
}

.nv-prose > * + * {
	margin-block-start: var(--wp--preset--spacing--sm);
}

.nv-prose h2,
.nv-prose h3,
.nv-prose h4 {
	margin-block-start: var(--wp--preset--spacing--lg);
	margin-block-end: var(--wp--preset--spacing--xs);
	text-wrap: balance;
}

.nv-prose ul,
.nv-prose ol {
	padding-inline-start: var(--wp--preset--spacing--md);
}

.nv-prose li + li {
	margin-block-start: var(--wp--preset--spacing--xxxs);
}

.nv-prose img {
	max-inline-size: 100%;
	block-size: auto;
	border-radius: var(--wp--custom--radius--md);
}

.nv-prose table {
	inline-size: 100%;
	border-collapse: collapse;
}

.nv-prose td,
.nv-prose th {
	padding: var(--wp--preset--spacing--xxs);
	border-block-end: 1px solid var(--wp--preset--color--border);
	text-align: start;
}

/* The photogallery posts are a paragraph plus a core [gallery]. Give it room to breathe. */
.nv-prose .wp-block-gallery,
.nv-prose .gallery {
	max-inline-size: none;
	margin-block: var(--wp--preset--spacing--md);
}

.nv-prose .gallery img {
	border: 1px solid var(--wp--preset--color--border);
}

/* ---------------------------------------------------------------------------
 * Listings — archives and search
 * ------------------------------------------------------------------------ */

.nv-listing__title {
	font-size: var(--wp--preset--font-size--xxxl);
	margin-block-end: var(--wp--preset--spacing--xs);
	text-wrap: balance;
}

.nv-listing__intro {
	max-inline-size: 70ch;
	color: var(--wp--preset--color--text-muted);
	font-size: var(--wp--preset--font-size--md);
}

/*
 * Listings come in two shapes, and which one a category gets is a property of its CONTENT,
 * not of the viewport:
 *
 *   - `clients` and `photogallery` are LOGOS and gallery covers with no useful excerpt —
 *     an image-led card grid.
 *   - `novosti`, `stati` and every other archive are ARTICLES — a media list, where the
 *     excerpt is the point and a 17rem column would truncate it to nothing.
 *
 * One template serves both; the switch is the `category-<slug>` body class WordPress already
 * emits, so no second template and no markup fork. `container-type: inline-size` on the list
 * means each row/card queries the LIST's width — the old theme wrote `col-md-3 col-sm-4
 * col-xs-6` into the markup instead, which is the thing DESIGN.md non-negotiable 4 forbids.
 */

.nv-cards {
	container-type: inline-size;
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--md);
}

.nv-card {
	display: grid;
	grid-template-columns: minmax(0, 12rem) minmax(0, 1fr);
	gap: var(--wp--preset--spacing--sm);
	align-items: start;
	padding-block-end: var(--wp--preset--spacing--md);
	border-block-end: 1px solid var(--wp--preset--color--border);
}

.nv-cards > li:last-child .nv-card {
	border-block-end: 0;
	padding-block-end: 0;
}

.nv-card__media {
	margin: 0;
	border-radius: var(--wp--custom--radius--md);
	overflow: hidden;
	background-color: var(--wp--preset--color--surface);
}

.nv-card__media img {
	inline-size: 100%;
	block-size: 100%;
	/*
	 * `contain`, not `cover`. These listings carry client LOGOS and gallery covers; cropping
	 * a logo to fill a 4/3 box cuts the brand in half. Letterboxing on the surface tone is
	 * the honest presentation.
	 */
	object-fit: contain;
}

.nv-card__title {
	margin: 0 0 var(--wp--preset--spacing--xxxs);
	line-height: 1.25;
	text-wrap: balance;
}

.nv-card__title a {
	text-decoration: none;
	color: var(--wp--preset--color--contrast);
}

.nv-card__title a:hover,
.nv-card__title a:focus-visible {
	color: var(--wp--preset--color--brand);
	text-decoration: underline;
}

.nv-card__excerpt {
	margin: 0;
	max-inline-size: 70ch;
	color: var(--wp--preset--color--text-muted);
}

/* Narrow list: stack, and cap the thumbnail so it does not become the whole screen. */
@container (max-width: 34rem) {
	.nv-card {
		grid-template-columns: minmax(0, 1fr);
	}

	.nv-card__media {
		max-inline-size: 12rem;
	}
}

/* ---------------------------------------------------------------------------
 * Image-led card grid — the clients and photogallery archives.
 * ------------------------------------------------------------------------ */

.category-clients .nv-cards,
.category-photogallery .nv-cards {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
	align-items: stretch;
}

.category-clients .nv-card,
.category-photogallery .nv-card {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--xxs);
	block-size: 100%;
	padding: var(--wp--preset--spacing--xs);
	border: 1px solid var(--wp--preset--color--border);
	border-block-end: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--lg);
	background-color: var(--wp--preset--color--base);
	transition: border-color var(--wp--custom--transition--base);
}

.category-clients .nv-cards > li:last-child .nv-card,
.category-photogallery .nv-cards > li:last-child .nv-card {
	border-block-end: 1px solid var(--wp--preset--color--border);
	padding-block-end: var(--wp--preset--spacing--xs);
}

.category-clients .nv-card:hover,
.category-clients .nv-card:focus-within,
.category-photogallery .nv-card:hover,
.category-photogallery .nv-card:focus-within {
	border-color: var(--wp--preset--color--brand);
}

.category-clients .nv-card__media,
.category-photogallery .nv-card__media {
	max-inline-size: none;
}

/* ---------------------------------------------------------------------------
 * Search results
 *
 * A LIST, not a grid. The old site had no `search.php`, so search fell through to
 * `index.php` and rendered its SINGULAR branch: `/?s=zerkalo` emitted NINE `<h1>` elements and
 * every result's full content. One `<h1>` (the query), then a scannable list.
 * ------------------------------------------------------------------------ */

.nv-search__form {
	max-inline-size: 30rem;
}

.nv-results {
	container-type: inline-size;
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--md);
}

.nv-result {
	display: grid;
	grid-template-columns: minmax(0, 10rem) minmax(0, 1fr);
	gap: var(--wp--preset--spacing--sm);
	align-items: start;
	padding-block-end: var(--wp--preset--spacing--md);
	border-block-end: 1px solid var(--wp--preset--color--border);
}

.nv-result:last-child {
	border-block-end: 0;
}

.nv-result__media {
	margin: 0;
	border-radius: var(--wp--custom--radius--md);
	overflow: hidden;
	background-color: var(--wp--preset--color--surface);
}

.nv-result__media img {
	inline-size: 100%;
	block-size: 100%;
	object-fit: contain;
}

.nv-result__title {
	margin: 0 0 var(--wp--preset--spacing--xxxs);
}

.nv-result__title a {
	text-decoration: none;
}

.nv-result__title a:hover,
.nv-result__title a:focus-visible {
	text-decoration: underline;
}

.nv-result__excerpt {
	margin: 0;
	max-inline-size: 70ch;
	color: var(--wp--preset--color--text-muted);
}

@container (max-width: 34rem) {
	.nv-result {
		grid-template-columns: minmax(0, 1fr);
	}

	.nv-result__media {
		max-inline-size: 12rem;
	}
}

/* ---------------------------------------------------------------------------
 * Pagination
 * ------------------------------------------------------------------------ */

.nv-pagination {
	gap: var(--wp--preset--spacing--xxs);
	margin-block-start: var(--wp--preset--spacing--lg);
}

.nv-pagination a,
.nv-pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	/* 44px minimum touch target — DESIGN.md non-negotiable 5. */
	min-inline-size: 44px;
	min-block-size: 44px;
	padding-inline: var(--wp--preset--spacing--xxs);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--md);
	text-decoration: none;
}

.nv-pagination .current {
	background-color: var(--wp--preset--color--brand);
	color: var(--wp--preset--color--base);
	border-color: var(--wp--preset--color--brand);
}

/* ---------------------------------------------------------------------------
 * Advantages grid (About page)
 * ------------------------------------------------------------------------ */

.nv-advantages {
	container-type: inline-size;
	padding-block: var(--wp--preset--spacing--lg);
	border-block: 1px solid var(--wp--preset--color--border);
}

.nv-advantages__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
	gap: var(--wp--preset--spacing--md);
}

.nv-advantage {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--wp--preset--spacing--xs);
	text-align: center;
}

.nv-advantage__image {
	max-inline-size: 100%;
	block-size: auto;
}

.nv-advantage__title {
	margin: 0;
	font-size: var(--wp--preset--font-size--md);
	line-height: 1.3;
}

/* ---------------------------------------------------------------------------
 * Client logo wall ("Нам доверяют")
 * ------------------------------------------------------------------------ */

.nv-clients {
	container-type: inline-size;
	margin-block-start: var(--wp--preset--spacing--lg);
}

.nv-clients__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
	gap: var(--wp--preset--spacing--sm);
}

.nv-client__link {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var(--wp--preset--spacing--xxs);
	/* 44px minimum touch target. */
	min-block-size: 44px;
	block-size: 100%;
	padding: var(--wp--preset--spacing--xs);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--lg);
	background-color: var(--wp--preset--color--base);
	text-decoration: none;
	color: var(--wp--preset--color--contrast);
	transition: border-color var(--wp--custom--transition--base);
}

.nv-client__link:hover,
.nv-client__link:focus-visible {
	border-color: var(--wp--preset--color--brand);
}

.nv-client__image {
	max-inline-size: 100%;
	block-size: auto;
	object-fit: contain;
}

.nv-client__name {
	font-size: var(--wp--preset--font-size--xs);
	color: var(--wp--preset--color--text-muted);
	text-align: center;
}

/* ---------------------------------------------------------------------------
 * Contacts map
 * ------------------------------------------------------------------------ */

.nv-map {
	margin-block-start: var(--wp--preset--spacing--lg);
}

.nv-map__heading {
	font-size: var(--wp--preset--font-size--xl);
	margin-block-end: var(--wp--preset--spacing--xs);
}

.nv-map__frame {
	inline-size: 100%;
	/* Deliberately not a fixed pixel height: aspect ratio keeps it sane on a phone. */
	aspect-ratio: 16 / 9;
	max-block-size: 30rem;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--lg);
	background-color: var(--wp--preset--color--surface);
}

.nv-map__link {
	margin-block-start: var(--wp--preset--spacing--xxs);
	font-size: var(--wp--preset--font-size--sm);
}

/* The escape hatch out of a non-interactive map embed, and the only control in this section.
   Measured 167x17 on /contacts/ at 390px. */
.nv-map__link a {
	display: inline-flex;
	align-items: center;
	min-block-size: 44px;
}

/* ---------------------------------------------------------------------------
 * Contact form (Contact Form 7)
 *
 * The form on /contacts/ had NO styling in this theme — grep for `wpcf7` across
 * assets/css returned nothing — so it rendered with the plugin's defaults: 22px-tall
 * controls at a fixed 280px width, measured at a real 390px viewport. That is the primary
 * conversion path on the page and it was the least usable thing on the site on a phone.
 *
 * Controls are matched to the ones commerce.css already uses for the coupon field and the
 * checkout button, so the site has one input style rather than two. No viewport media query:
 * the fields are full-width at every size and simply stop growing at a readable measure.
 * ------------------------------------------------------------------------ */

.wpcf7 .wpcf7-form-control-wrap {
	display: block;
}

.wpcf7 :is(input[type="text"], input[type="email"], input[type="tel"], input[type="url"], input[type="number"], textarea) {
	inline-size: 100%;
	max-inline-size: 34rem;
	min-block-size: 44px;
	padding: 0.5em 0.75em;
	color: inherit;
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--md);
	font: inherit;
}

.wpcf7 textarea {
	min-block-size: 8rem;
	resize: vertical;
}

.wpcf7 :is(input, textarea):focus-visible {
	outline: var(--wp--custom--focus--width) solid var(--wp--preset--color--accent);
	outline-offset: var(--wp--custom--focus--offset);
}

.wpcf7 p {
	margin-block: 0 var(--wp--preset--spacing--xs);
}

.wpcf7 input[type="submit"] {
	min-block-size: 44px;
	min-inline-size: 44px;
	padding: 0.75em 1.5em;
	color: var(--wp--preset--color--base);
	background: var(--wp--preset--color--brand);
	border: 0;
	border-radius: var(--wp--custom--radius--md);
	font: inherit;
	font-weight: 700;
	cursor: pointer;
	transition: background var(--wp--custom--transition--base);
}

.wpcf7 input[type="submit"]:hover {
	background: var(--wp--preset--color--brand-dark);
}

/* ---------------------------------------------------------------------------
 * 404
 * ------------------------------------------------------------------------ */

.nv-notfound {
	max-inline-size: 60ch;
	margin-inline: auto;
	padding-block: var(--wp--preset--spacing--lg);
	text-align: center;
}

.nv-notfound__title {
	font-size: var(--wp--preset--font-size--xxxl);
	margin-block-end: var(--wp--preset--spacing--sm);
	text-wrap: balance;
}

.nv-notfound__lead {
	color: var(--wp--preset--color--text-muted);
	font-size: var(--wp--preset--font-size--md);
	margin-block-end: var(--wp--preset--spacing--md);
}

.nv-notfound__actions {
	list-style: none;
	margin: 0 0 var(--wp--preset--spacing--md);
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--xs);
	justify-content: center;
	align-items: center;
}

.nv-notfound__button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-block-size: 44px;
	padding-inline: var(--wp--preset--spacing--sm);
	border-radius: var(--wp--custom--radius--md);
	background-color: var(--wp--preset--color--brand);
	color: var(--wp--preset--color--base);
	font-weight: 700;
	text-decoration: none;
}

.nv-notfound__button:hover,
.nv-notfound__button:focus-visible {
	background-color: var(--wp--preset--color--brand-dark);
	color: var(--wp--preset--color--base);
}

.nv-notfound__actions a:not(.nv-notfound__button) {
	display: inline-flex;
	align-items: center;
	min-block-size: 44px;
}

.nv-notfound__search {
	display: flex;
	justify-content: center;
}

.nv-notfound__search form {
	inline-size: min(100%, 26rem);
}

/* ---------------------------------------------------------------------------
 * 404 — the eyebrow
 *
 * The old 404 said "Николь ВИВА → 404. Страница не найдена" in a Breadcrumb NavXT trail
 * above the heading. The trail itself is worthless on a 404 (there is no page to be a
 * breadcrumb OF), but the words are not: "Страница не найдена" is the plain statement of
 * what happened, and the exclamation-marked heading below it is the tone. Keeping it as an
 * eyebrow keeps the information and drops the fake hierarchy — and it restores the exact
 * sentence the content-parity gate samples from the reference page.
 * ------------------------------------------------------------------------ */

.nv-notfound__eyebrow {
	max-inline-size: 60ch;
	margin-inline: auto;
	margin-block-end: 0;
	padding-block-start: var(--wp--preset--spacing--lg);
	color: var(--wp--preset--color--text-muted);
	text-align: center;
	text-transform: uppercase;
	letter-spacing: 0.08em;
}

/* The eyebrow now owns the top space, so the block below it must not add its own again. */
.nv-notfound__eyebrow + .nv-notfound {
	padding-block-start: var(--wp--preset--spacing--xxs);
}

/* ---------------------------------------------------------------------------
 * Search — form and the empty state
 *
 * `button-outside` rather than `button-inside`: the inside variant nests the control in a
 * bordered shell whose height is driven by the input, and the button inherits it. Outside,
 * the button is a real box that can be given the 44px minimum on its own — DESIGN.md
 * non-negotiable 5 — without fighting the wrapper.
 * ------------------------------------------------------------------------ */

.nv-search__form {
	max-inline-size: 34rem;
	margin-block-start: var(--wp--preset--spacing--sm);
}

.nv-search__form .wp-block-search__input {
	min-block-size: 44px;
	padding: 0.5em 0.75em;
	color: inherit;
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--wp--custom--radius--md);
	font: inherit;
}

.nv-search__form .wp-block-search__input:focus-visible {
	outline: var(--wp--custom--focus--width) solid var(--wp--preset--color--accent);
	outline-offset: var(--wp--custom--focus--offset);
}

.nv-search__form .wp-block-search__button {
	min-block-size: 44px;
	min-inline-size: 44px;
	margin-inline-start: var(--wp--preset--spacing--xxs);
	padding-inline: var(--wp--preset--spacing--sm);
	color: var(--wp--preset--color--base);
	background: var(--wp--preset--color--brand);
	border: 0;
	border-radius: var(--wp--custom--radius--md);
	font: inherit;
	font-weight: 700;
	cursor: pointer;
	transition: background var(--wp--custom--transition--base);
}

.nv-search__form .wp-block-search__button:hover {
	background: var(--wp--preset--color--brand-dark);
}

/*
 * The empty state was a single sentence and nothing else — a dead end at the exact moment
 * the visitor has already told us what they wanted. Two links out, to pages that exist.
 */
.nv-noresults {
	max-inline-size: 70ch;
	padding-block: var(--wp--preset--spacing--md);
}

.nv-noresults__lead {
	color: var(--wp--preset--color--text-muted);
	font-size: var(--wp--preset--font-size--md);
}

/* ---------------------------------------------------------------------------
 * Informational pages — the "what next" band
 *
 * Delivery, payment, warranty and returns pages are read by someone deciding whether to
 * trust a term before they order. Whatever the answer, the next move is the same two moves:
 * ask, or go look at the products. Without this the page simply ends, and the only route on
 * is the footer.
 *
 * Both link labels ("Контакты", "Каталог продукции") are strings TranslatePress already
 * carries with status 2, so this band is Ukrainian on /ua/ with no new dictionary row —
 * verified by rendering /ua/dostavka-i-oplata/, which shows "Контакти" / "Каталог продукції".
 * ------------------------------------------------------------------------ */

.nv-page__next {
	margin-block-start: var(--wp--preset--spacing--xl);
	padding-block: var(--wp--preset--spacing--md);
	border-block-start: 1px solid var(--wp--preset--color--border);
}

.nv-page__next-lead {
	margin-block-end: var(--wp--preset--spacing--xs);
	font-size: var(--wp--preset--font-size--lg);
	font-weight: 700;
}

.nv-page__next-actions {
	gap: var(--wp--preset--spacing--xs);
	align-items: center;
}

.nv-page__next-actions p {
	margin: 0;
}

.nv-page__next-primary a,
.nv-noresults__primary a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-block-size: 44px;
	padding-inline: var(--wp--preset--spacing--sm);
	border-radius: var(--wp--custom--radius--md);
	background-color: var(--wp--preset--color--brand);
	color: var(--wp--preset--color--base);
	font-weight: 700;
	text-decoration: none;
}

.nv-page__next-primary a:hover,
.nv-page__next-primary a:focus-visible,
.nv-noresults__primary a:hover,
.nv-noresults__primary a:focus-visible {
	background-color: var(--wp--preset--color--brand-dark);
	color: var(--wp--preset--color--base);
}

.nv-page__next-secondary a,
.nv-noresults__secondary a {
	display: inline-flex;
	align-items: center;
	min-block-size: 44px;
	padding-inline: var(--wp--preset--spacing--xxs);
}

.nv-noresults__actions {
	gap: var(--wp--preset--spacing--xs);
	align-items: center;
	margin-block-start: var(--wp--preset--spacing--sm);
}

.nv-noresults__actions p {
	margin: 0;
}

/*
 * Placeholder markers.
 *
 * Informational pages ship with `[DATA NEEDED: …]` / `[TEXT NEEDED: …]` paragraphs where the
 * business has not supplied a fact. They must be impossible to mistake for copy — both for
 * whoever reviews the design and for anyone who deploys the page before the content lands.
 * The class is set on the paragraph in the page content, so a placeholder that is replaced
 * by real text loses the styling with it.
 */
.nv-placeholder {
	padding: var(--wp--preset--spacing--xs);
	border: 1px dashed var(--wp--preset--color--brand);
	border-radius: var(--wp--custom--radius--md);
	background-color: var(--wp--preset--color--surface);
	color: var(--wp--preset--color--text-muted);
	font-size: var(--wp--preset--font-size--sm);
}
