/*
 * NutriScrolls base styles (front end + block editor).
 * Tokens come from theme.json (--wp--preset--*, --wp--custom--*). Dark mode lives in dark.css (front end only).
 * See TOKENS.md for the full list, the data-theme switch and the view-transition classes.
 */

/* ------------------------------------------------------------------ Base */
html {
	-webkit-text-size-adjust: 100%;
	text-size-adjust: 100%;
	scroll-padding-top: var(--wp--preset--spacing--80);
}

body {
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	text-rendering: optimizeLegibility;
	font-kerning: normal;
}

h1,
h2,
h3,
h4,
h5,
h6 {
	text-wrap: balance;
}

p,
li,
figcaption,
blockquote {
	text-wrap: pretty;
}

::selection {
	background: var(--wp--preset--color--highlight);
	color: var(--wp--preset--color--neutral-900);
}

mark {
	background: var(--wp--preset--color--highlight);
	color: var(--wp--preset--color--neutral-900);
	padding-inline: 0.15em;
	border-radius: var(--wp--custom--radius--sm);
}

img,
video {
	max-width: 100%;
	height: auto;
}

/* Uploads are served as <picture> (AVIF source, WebP image; Media\ModernImages): the wrapper adds no box, so the <img> lays out as before. */
picture {
	display: contents;
}

/* ------------------------------------------------------------ Accessibility */
.screen-reader-text {
	border: 0;
	clip-path: inset(50%);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	width: 1px;
	word-wrap: normal !important;
}

/* Skip link (added in functions.php on wp_body_open, targets <main id="main">). */
.skip-link.screen-reader-text:focus,
.skip-link.screen-reader-text:focus-visible {
	background: var(--wp--preset--color--action);
	border-radius: var(--wp--custom--radius--md);
	box-shadow: var(--wp--preset--shadow--md);
	clip-path: none;
	color: var(--wp--preset--color--on-action);
	font-size: var(--wp--preset--font-size--label);
	font-weight: 600;
	height: auto;
	left: var(--wp--preset--spacing--40);
	line-height: var(--wp--custom--line-height--label);
	padding: var(--wp--preset--spacing--30) var(--wp--preset--spacing--50);
	text-decoration: none;
	top: var(--wp--preset--spacing--40);
	width: auto;
	z-index: 100000;
}

/*
 * Focus ring (Figma effect style "focus/ring" + section 06): 2px outline in color/focus, 2px offset, on every
 * interactive element. Low specificity (:where) so components can override the offset, never remove the ring.
 */
:where(a, button, input, select, textarea, summary, [tabindex]:not([tabindex="-1"])):focus-visible {
	outline: var(--wp--custom--border--focus) solid var(--wp--preset--color--focus);
	outline-offset: 2px;
}

/* Long bare URLs in article text (source lists) wrap instead of widening the page on phones. */
.wp-block-post-content a,
.wp-block-post-content li,
.wp-block-post-content p {
	overflow-wrap: anywhere;
}

/* Variant for elements whose outline would be clipped (overflow:hidden parents, inputs inside a bordered wrapper). */
.ns-focus-ring:focus-visible {
	box-shadow: 0 0 0 2px var(--wp--preset--color--bg), 0 0 0 4px var(--wp--preset--color--focus);
	outline: 0;
}

/* Touch targets are at least 44 x 44 px (Figma grid notes). */
:where(button, input[type="submit"], input[type="button"], .wp-block-button__link) {
	min-height: 44px;
}

/* Buttons: the element styles come from theme.json; this adds the layout and the outline variant. */
.wp-block-button__link,
.wp-element-button {
	align-items: center;
	display: inline-flex;
	justify-content: center;
	text-align: center;
}

.wp-block-button.is-style-outline > .wp-block-button__link:not(.has-background),
.wp-block-button.is-style-outline > .wp-element-button:not(.has-background) {
	background: transparent;
	border: var(--wp--custom--border--hairline) solid var(--wp--preset--color--action);
	color: var(--wp--preset--color--action);
}

.wp-block-button.is-style-outline > .wp-block-button__link:not(.has-background):hover {
	background: var(--wp--preset--color--action-subtle);
	color: var(--wp--preset--color--on-action-subtle);
}

/* ------------------------------------------------------- Numbers and data */
/*
 * Public Sans has tabular, lining figures (tnum, lnum), so amounts line up in tables and data cells.
 * Use .ns-data or .ns-num (both: tabular lining figures in Public Sans) for any value, unit or table of numbers.
 */
.ns-data,
.ns-num,
table,
code,
kbd,
samp,
pre {
	font-variant-numeric: tabular-nums lining-nums;
	font-feature-settings: "tnum" 1, "lnum" 1;
}

.ns-data,
code,
kbd,
samp,
pre {
	font-family: var(--wp--preset--font-family--body);
}

.ns-data {
	font-size: var(--wp--preset--font-size--data);
	line-height: var(--wp--custom--line-height--data);
}

.ns-data--large {
	font-size: var(--wp--preset--font-size--data-large);
	font-weight: 600;
	line-height: var(--wp--custom--line-height--data-large);
}

.ns-data--small {
	font-size: var(--wp--preset--font-size--data-small);
	line-height: var(--wp--custom--line-height--data-small);
}

.ns-data--strong {
	font-weight: 600;
}

/*
 * Units (cup | g) and region (us | eu), both chosen in the header settings menu (plugin block
 * nutriscrolls/settings-menu, preference store nutriscrolls_prefs). Every amount that depends on the basis is printed
 * once per variant: <span class="ns-u" data-u="cup">per ¼ cup (39 g)</span><span class="ns-u" data-u="g">per 100 g</span>,
 * and every word or number that depends on the region likewise: <span class="ns-r" data-r="us">% DV</span><span
 * class="ns-r" data-r="eu">% RI</span> (or the classes + data attributes on a whole row, list or tbody; an element can
 * carry both). An inline <head> script sets <html data-units> and <html data-region> before first paint; without it
 * (no script) the cup and us variants show.
 */
html:not([data-units="g"]) .ns-u[data-u="g"],
html[data-units="g"] .ns-u[data-u="cup"],
html:not([data-region="eu"]) .ns-r[data-r="eu"],
html[data-region="eu"] .ns-r[data-r="us"] {
	display: none !important;
}

/*
 * The same for authored content (templates, patterns, posts): give a block the additional CSS class ns-only-us or
 * ns-only-eu and it shows in that region only (no script: the US block shows). Use it for text that names the
 * reference value ("% DV" | "% RI"); the server-rendered data blocks do this themselves.
 */
html:not([data-region="eu"]) .ns-only-eu,
html[data-region="eu"] .ns-only-us {
	display: none !important;
}

/*
 * Settings menu in the header (plugin block nutriscrolls/settings-menu). The header is the containing block of the panel
 * in the mobile group, so it hangs full width under the header bar (a sheet); in the desktop group the block itself is
 * the containing block and the panel is a popover under the gear, left of the search field. The templates make the
 * header sticky (a positioned element already); :where() keeps this fallback from ever overriding that.
 */
:where(.site-header) {
	position: relative;
}
.ns-header-actions .wp-block-nutriscrolls-settings-menu {
	position: static;
}
.ns-header-actions .ns-settings__panel {
	border-left: 0;
	border-radius: 0 0 var(--wp--custom--radius--lg) var(--wp--custom--radius--lg);
	border-right: 0;
	left: 0;
	/* Content at most 480 px wide, centred, on wide tablets. */
	padding-inline: max(var(--wp--preset--spacing--40), calc((100% - 480px) / 2));
	right: 0;
	top: 100%;
	width: auto;
}

/*
 * Header on phones: logo (~114 px), settings gear and menu button (44 px each), and the search icon from 430 px up, must
 * fit in one row with 16 px side padding. Below 430 px the search icon goes (the menu has search) and the gaps tighten
 * (header 24 -> 12 px, actions 4 -> 0 px): at 358 px 88 px of controls in 199.6 px (111.6 px to spare), at 390 px in 231 px;
 * at 430 px (search icon back, 4 px gaps) 140 px of controls in 259 px.
 */
@media (max-width: 429px) {
	.site-header .ns-header-search-mobile {
		display: none;
	}
	.site-header > .wp-block-group {
		gap: var(--wp--preset--spacing--30);
	}
	.site-header .ns-header-actions {
		gap: 0;
	}
}

/* Eyebrow / overline text style (also available as the "Eyebrow" paragraph block style). */
.ns-eyebrow {
	color: var(--wp--preset--color--accent);
	font-size: var(--wp--preset--font-size--eyebrow);
	font-weight: 600;
	letter-spacing: 0.08em;
	line-height: var(--wp--custom--line-height--eyebrow);
	text-transform: uppercase;
}

/* Skeleton pulse (Figma 05 Motion: 1.2 s opacity loop between surface-strong 100% and 60%). */
.ns-skeleton {
	animation: ns-skeleton-pulse 1.2s ease-in-out infinite;
	background: var(--wp--preset--color--surface-strong);
	border-radius: var(--wp--custom--radius--md);
}

@keyframes ns-skeleton-pulse {
	50% {
		opacity: 0.6;
	}
}

/* ------------------------------------------------------------------ Motion */
:root {
	--ns-ease: var(--wp--custom--motion--easing);
	--ns-duration-fast: var(--wp--custom--motion--duration--fast);
	--ns-duration-base: var(--wp--custom--motion--duration--base);
	--ns-duration-slow: var(--wp--custom--motion--duration--slow);
	/* Hover: 120 ms colour / shadow transition (cards, buttons, rows). */
	--ns-transition-hover: color var(--ns-duration-fast) var(--ns-ease), background-color var(--ns-duration-fast) var(--ns-ease),
		border-color var(--ns-duration-fast) var(--ns-ease), box-shadow var(--ns-duration-fast) var(--ns-ease);
}

:where(a, button, summary, .wp-block-button__link) {
	transition: var(--ns-transition-hover);
}

/* ---------------------------------------------- Cross-document view transitions */
/*
 * Figma "05 Motion". Progressive enhancement: Chromium 126+ and Safari 18.2+ animate, other browsers navigate normally.
 * Same-origin navigations only. Shared elements get a unique name per slug via a custom property set inline:
 *
 *   <a class="ns-vt-image" style="--vt-image: food-image-broccoli"> ... on the card image wrapper / img
 *   <h3 class="ns-vt-title" style="--vt-title: food-title-broccoli"> ... on the card title
 *   and the same two classes + the same custom properties on the hero image and the H1 of the target page.
 *
 * Names (Figma): food-image-{slug}, food-title-{slug}, post-image-{slug}, post-title-{slug}, nutrient-title-{slug}.
 * A name may be used only once per page: only set --vt-image / --vt-title on the first card for a given slug.
 * Without the custom property the name resolves to "none", so the classes are safe to leave on the markup.
 * The LCP hero image on the target page must not be lazy-loaded (fetchpriority="high").
 */
@view-transition {
	navigation: auto;
}

.ns-vt-image {
	view-transition-name: var(--vt-image);
}

.ns-vt-title {
	view-transition-name: var(--vt-title);
	width: fit-content;
}

/* The site header stays static on every page so navigation never flickers. */
.ns-vt-header,
.site-header,
.wp-site-blocks > header.wp-block-template-part {
	view-transition-name: site-header;
}

::view-transition-group(*) {
	animation-duration: var(--wp--custom--motion--duration--view-transition);
	animation-timing-function: var(--wp--custom--motion--easing);
}

/* Default cross-fade of the rest of the page: old fades out in 120 ms, new fades in over 200 ms after an 80 ms delay. */
::view-transition-old(root) {
	animation-duration: var(--wp--custom--motion--duration--fast);
}

::view-transition-new(root) {
	animation-delay: 80ms;
	animation-duration: var(--wp--custom--motion--duration--base);
}

::view-transition-group(site-header) {
	animation: none;
}

/* ----------------------------------------------------------- Reduced motion */
@media (prefers-reduced-motion: reduce) {
	@view-transition {
		navigation: none;
	}

	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		scroll-behavior: auto !important;
		transition-duration: 0.01ms !important;
	}

	.ns-skeleton {
		animation: none;
	}
}

/* Wordmark (Figma "Logo"): "Nutri" bold in the brand blue, "Scrolls" regular. Markup: render_block filter in functions.php. */
.wp-block-site-title .ns-logo__nutri {
	color: var(--wp--preset--color--action);
	font-weight: 700;
}
.wp-block-site-title .ns-logo__scrolls {
	font-weight: 400;
}

/* ----------------------------------------------------------- Site footer (parts/footer.html) */
/* Semantic tokens only (surface, ink, line), so the footer follows light and dark mode like the rest of the page. */
.ns-footer > * + * {
	margin-block-start: var(--wp--preset--spacing--70);
}

.ns-footer__top {
	display: grid;
	gap: var(--wp--preset--spacing--70);
}

@media (min-width: 1024px) {
	.ns-footer__top {
		grid-template-columns: minmax(0, 24rem) minmax(0, 1fr);
		gap: var(--wp--preset--spacing--90);
	}
}

.ns-footer__brand p {
	margin: 0;
	max-width: 34rem;
}

.ns-footer__notes {
	display: grid;
	gap: var(--wp--preset--spacing--30);
	padding-block-start: var(--wp--preset--spacing--40);
	border-block-start: 1px solid var(--wp--preset--color--line);
	width: 100%;
	max-width: 34rem;
}

.ns-footer__note {
	color: var(--wp--preset--color--ink-muted);
}

.ns-footer__note strong {
	color: var(--wp--preset--color--ink);
	font-weight: 600;
}

.ns-footer__links {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 150px), 1fr));
	gap: var(--wp--preset--spacing--60) var(--wp--preset--spacing--50);
	align-content: start;
}

.ns-footer__links > * {
	margin: 0;
}

.ns-footer .ns-footer__heading {
	margin: 0 0 var(--wp--preset--spacing--20);
	color: var(--wp--preset--color--ink-muted);
	font-size: var(--wp--preset--font-size--eyebrow);
	font-weight: 600;
	letter-spacing: 0.08em;
	line-height: var(--wp--custom--line-height--eyebrow);
	text-transform: uppercase;
}

.ns-footer__list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.ns-footer__list a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	color: var(--wp--preset--color--ink);
	text-decoration: none;
}

@media (min-width: 1024px) {
	.ns-footer__list a {
		min-height: 32px;
	}
}

.ns-footer__list a:hover {
	color: var(--wp--preset--color--link-hover);
	text-decoration: underline;
}

.ns-footer__sources {
	padding-block-start: var(--wp--preset--spacing--50);
	border-block-start: 1px solid var(--wp--preset--color--line);
}

.ns-footer__sources p {
	margin: 0;
	max-width: 72rem;
}

.ns-footer__bottom {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--30) var(--wp--preset--spacing--50);
	padding-block-start: var(--wp--preset--spacing--50);
	border-block-start: 1px solid var(--wp--preset--color--line);
	font-weight: 500;
}

.ns-footer__bottom p {
	margin: 0;
}

.ns-footer__disclaimer {
	flex: 1 1 420px;
}

.ns-footer__legal a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	color: inherit;
}

.ns-footer__legal a:hover {
	color: var(--wp--preset--color--ink);
}
