/* perennial — base
   Scoped resets and shared components. Everything lives under .pn
   (.pn-header, .pn-home, .pn-footer) so Blocksy keeps styling shop, cart and
   checkout until those pages are designed. Values come from the tokens. */

/* ── Scope ─────────────────────────────────────────────────────────────── */
.pn,
.pn *,
.pn *::before,
.pn *::after { box-sizing: border-box; }

.pn {
	--pn-gutter: var(--page-gutter);               /* 24px  < 768 */
	--pn-section-pad: calc(var(--space-8) / 2);    /* 32px each side → 64px between sections */
	--pn-text-h1: 36px;
	--pn-text-h2: 28px;
	--pn-text-h3: 22px;
	--pn-text-lead: 18px;

	background: var(--bg-page);
	color: var(--text-primary);
	font-family: var(--font-sans);
	font-size: var(--text-body);
	font-weight: var(--weight-regular);
	line-height: var(--lh-body);
	letter-spacing: var(--ls-body);
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	text-rendering: optimizeLegibility;
}

@media (min-width: 768px) {
	.pn {
		--pn-gutter: 40px;                            /* 32–48 on tablet */
		--pn-section-pad: calc(var(--space-9) / 2);   /* 48 → 96 between */
		--pn-text-h1: 42px;
		--pn-text-h2: 32px;
		--pn-text-h3: 24px;
		--pn-text-lead: var(--text-lead);
	}
}

@media (min-width: 1024px) {
	.pn {
		--pn-gutter: var(--page-gutter-lg);           /* 64 */
		--pn-section-pad: calc(var(--space-10) / 2);  /* 64 → 128 between beats */
	}
}

@media (min-width: 1280px) {
	.pn {
		--pn-text-h1: var(--text-h1);                 /* 52 */
		--pn-text-h2: var(--text-h2);                 /* 36 */
		--pn-text-h3: var(--text-h3);                 /* 26 */
	}
}

/* Inverse (forest) sections: the tokens swap the aliases, we paint them. */
.pn [data-theme="inverse"],
.pn[data-theme="inverse"] {
	background: var(--bg-page);
	color: var(--text-primary);
}

/* The two rules outside .pn.

   1. The sticky header must start at the very top of the page, or the fixed
      sheets no longer line up with it. Blocksy sets this too — stating it here
      means the alignment does not depend on the parent.

   2. The page's ground belongs on the document, not only on the .pn blocks
      that sit on it. The header is glass: 72% paper over 28% of whatever is
      behind it. Where nothing paints the document, that 28% is the browser's
      own canvas — dark in a dark-mode viewer — and the bar reads as a dark
      band. `color-scheme: light` stops the UA painting a dark canvas at all,
      and keeps form controls and scrollbars on paper.

      `html body` rather than `body`, because Blocksy paints the body too —
      `body { background-color: var(--theme-palette-color-7) }` from its inline
      styles, which is #FAFBFC, not paper. Both rules are 0-0-1 and its inline
      block prints after our stylesheet, so it was winning and a cool white sat
      behind the glass header. 0-0-2 settles it without caring about order. */
html {
	background: var(--bg-page);
	color-scheme: light;
}

html body {
	margin: 0;
	background: var(--bg-page);
}

/* ── Resets, inside .pn only ───────────────────────────────────────────── */
.pn :is(h1, h2, h3, h4, h5, h6, p, ul, ol, li, figure, blockquote) { margin: 0; padding: 0; }
/* Blocksy colours headings from its own palette with a bare `h1, h2, …` rule,
   and a direct rule on an element always beats an inherited colour — so every
   heading on our pages was rendering in its blue-grey, not our ink. 0-1-1 takes
   it back, and `inherit` keeps the inverse sections working. */
.pn :is(h1, h2, h3, h4, h5, h6) { color: inherit; }
.pn :is(ul, ol) { list-style: none; }
.pn :is(img, svg, video) { display: block; max-width: 100%; height: auto; border: 0; box-shadow: none; }
/* The hidden attribute must win over any component display rule (language toggle, sheet, backdrop). */
.pn [hidden],
.pn[hidden] { display: none !important; }
.pn a { color: inherit; text-decoration: none; }
.pn :is(button, input, select, textarea) { font: inherit; color: inherit; letter-spacing: inherit; margin: 0; }
.pn button {
	padding: 0;
	background: none;
	border: 0;
	border-radius: 0;
	cursor: pointer;
	-webkit-appearance: none;
	appearance: none;
	text-transform: none;
	box-shadow: none;
}
/* Blocksy styles every submit button on hover from its own palette — a #1559ed
   background, white text and a 3px lift — with `[type="submit"]:hover`, which is
   0-2-0. Every button this theme renders is a submit button, and we only ever
   declared *colour* on hover, so the blue background and the lift came through
   underneath it: the card's cart icon turned blue, and every filled button on
   the site rose 3px when you pointed at it.

   `:is()` takes the specificity of its most specific argument, so this lands at
   0-3-0 and settles it. The components below restate their own hover fills. */
.pn :is(button, [type="submit"], [type="button"], [type="reset"]):hover {
	background-color: transparent;
	border-color: transparent;
	transform: none;
}

.pn :focus { outline: none; }
.pn :focus-visible { outline: none; box-shadow: var(--focus-ring); }

/* ── Layout ────────────────────────────────────────────────────────────── */
.pn-container {
	width: 100%;
	max-width: calc(var(--page-max) + 2 * var(--pn-gutter));
	margin-inline: auto;
	padding-inline: var(--pn-gutter);
}

.pn-grid {
	display: grid;
	grid-template-columns: repeat(var(--grid-columns), minmax(0, 1fr));
	column-gap: var(--grid-gap);
	row-gap: var(--space-6);
}

.pn-section { padding-block: var(--pn-section-pad); }

/* Vertical rhythm inside a text block. The `.pn ` prefix takes these past the
   element reset above, which is 0-1-1 and would otherwise win. */
.pn .pn-text > * + * { margin-top: var(--space-5); }

/* ── Type ──────────────────────────────────────────────────────────────── */
.pn-h1,
.pn-h2,
.pn-h3,
.pn-quote {
	font-family: var(--font-serif);
	font-weight: var(--weight-regular);
	text-wrap: balance;
	line-break: strict;
	hanging-punctuation: allow-end;
}

.pn-h1 { font-size: var(--pn-text-h1); line-height: var(--lh-h1); letter-spacing: var(--ls-h1); }
.pn-h2 { font-size: var(--pn-text-h2); line-height: var(--lh-h2); letter-spacing: var(--ls-h2); }
.pn-h3 { font-size: var(--pn-text-h3); line-height: var(--lh-h3); letter-spacing: var(--ls-h3); font-weight: var(--weight-medium); }
.pn-quote { font-size: var(--text-quote); line-height: var(--lh-quote); letter-spacing: var(--ls-quote); font-style: italic; }

.pn-lead {
	font-size: var(--pn-text-lead);
	line-height: var(--lh-lead);
	letter-spacing: var(--ls-lead);
	font-weight: var(--weight-light);
	max-width: var(--measure-lead);
}

.pn-body { font-size: var(--text-body); line-height: var(--lh-body); max-width: var(--measure-body); }
.pn-small { font-size: var(--text-small); line-height: var(--lh-small); letter-spacing: var(--ls-small); }
.pn-caption { font-size: var(--text-caption); line-height: var(--lh-caption); letter-spacing: var(--ls-caption); color: var(--text-secondary); }

/* Chinese measures: 62ch / 44ch are Latin measures; ≈34 and 22 characters per line instead. */
:lang(zh) .pn-body { max-width: 34em; }
:lang(zh) .pn-lead { max-width: 22em; }

/* ── Eyebrow: 12px tracked label. No rule before it — a line here would be
      decoration; lines are kept for things that mean something (the active
      nav dot, the hairline under a category row). Hover is a colour change,
      never a line. ──────────────────────────────────────────────────────── */
.pn-eyebrow {
	display: block;
	font-family: var(--font-sans);
	font-size: var(--text-label);
	line-height: var(--lh-label);
	font-weight: var(--weight-medium);
	letter-spacing: var(--ls-label);
	text-transform: uppercase;
	color: var(--text-secondary);
	max-width: none;
}
/* Chinese never uppercases; the tokens already widen the tracking to 0.2em. */
:lang(zh) .pn-eyebrow { text-transform: none; }

/* ── Dots ──────────────────────────────────────────────────────────────── */
.pn-dot {
	display: inline-block;
	width: var(--dot-size);
	height: var(--dot-size);
	border-radius: var(--radius-full);
	background: var(--dot-brand);
	vertical-align: middle;
	flex: none;
}
.pn-dot--accent { width: var(--dot-size-lg); height: var(--dot-size-lg); background: var(--dot-accent); }
.pn-dot--inactive { background: transparent; box-shadow: inset 0 0 0 var(--line-weight) var(--line-strong); }

/* ── Buttons ───────────────────────────────────────────────────────────── */
.pn .pn-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-2);
	min-height: 44px;
	padding: var(--space-3) var(--space-5);
	background: var(--bg-brand);
	color: var(--text-on-brand);
	border: var(--line-weight) solid var(--bg-brand);
	border-radius: var(--radius-none);
	font-family: var(--font-sans);
	font-size: var(--text-small);
	font-weight: var(--weight-medium);
	line-height: 1.2;
	letter-spacing: 0;
	text-align: center;
	text-decoration: none;
	text-transform: none;
	cursor: pointer;
	box-shadow: none;
	-webkit-appearance: none;
	appearance: none;
	transition:
		opacity var(--dur-fast) var(--ease-out),
		transform var(--dur-fast) var(--ease-out);
}
.pn .pn-btn:hover,
.pn .pn-btn:focus-visible {
	background: var(--bg-brand);
	border-color: var(--bg-brand);
	color: var(--text-on-brand);
	opacity: var(--hover-opacity);
}
.pn .pn-btn:active { transform: scale(var(--press-scale)); }
.pn .pn-btn:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.pn .pn-btn--outline { background: transparent; color: var(--text-primary); border-color: var(--line-strong); }
.pn .pn-btn--outline:hover,
.pn .pn-btn--outline:focus-visible {
	background: transparent;
	border-color: var(--line-strong);
	color: var(--text-primary);
}

/* The label is a wrapper, not a signal: the hover belongs to the button. */
.pn .pn-btn__label { display: inline-block; }
.pn .pn-btn[disabled],
.pn .pn-btn[aria-disabled="true"] { opacity: 0.4; pointer-events: none; }

/* ── Text link ─────────────────────────────────────────────────────────
   The hover signal on this site is a colour change and nothing else — the
   same fade the header nav, the sheet links and the footer columns use. No
   underline grows anywhere: a line drawn on hover is decoration, and the
   lines here are kept for things that mean something. ─────────────────── */
.pn .pn-link {
	display: inline;
	color: var(--text-primary);
	/* No font-size: a link takes the size of the sentence it sits in. Hard-setting
	   16px here rendered links oversized inside 14px and 12px text — found on the
	   contact page's consent line in Round 6 and scoped-fixed there; fixed at the
	   source now. Every caller that wants a different size still states one. */
	text-decoration: none;
	transition: opacity var(--dur-fast) var(--ease-out);
}
.pn .pn-link:hover,
.pn .pn-link:focus-visible { opacity: var(--hover-opacity); }

/* ── Media: image bleeds to the edges of its box ───────────────────────── */
.pn-media {
	/* `display` is not decoration here: aspect-ratio does nothing on an inline
	   box, so a .pn-media on a <span> — which the product gallery needs, being
	   inside a <button> — silently fell back to the image's own proportions.
	   Every other caller is a <div> and already block, so stating it costs
	   nothing and stops the next <span> from doing the same. */
	display: block;
	position: relative;
	width: 100%;
	overflow: hidden;
	background: var(--bg-muted);
}
.pn-media--4x5 { aspect-ratio: 4 / 5; }
.pn-media--3x4 { aspect-ratio: 3 / 4; }
.pn-media--16x10 { aspect-ratio: 16 / 10; }
.pn-media--5x6 { aspect-ratio: 5 / 6; }   /* the ingredient photographs, at both scales */
.pn-media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* ── Inputs ────────────────────────────────────────────────────────────── */
.pn .pn-input {
	width: 100%;
	min-height: 44px;
	padding: 0 var(--space-4);
	background: var(--bg-page);
	color: var(--text-primary);
	border: var(--line-weight) solid var(--line-hair);
	border-radius: var(--radius-sm);
	font-family: var(--font-sans);
	font-size: var(--text-body);
	line-height: 1.4;
	box-shadow: none;
	-webkit-appearance: none;
	appearance: none;
}
.pn .pn-input::placeholder { color: var(--text-tertiary); opacity: 1; }
.pn .pn-input:focus-visible { border-color: var(--line-strong); box-shadow: var(--focus-ring); }
.pn .pn-input[aria-invalid="true"] { border-color: var(--error); }

/* ── Icons ─────────────────────────────────────────────────────────────── */
.pn-icon { width: 20px; height: 20px; flex: none; color: var(--text-secondary); }

/* ── Utilities ─────────────────────────────────────────────────────────── */
.pn-sr-only {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* Skip link sits outside .pn (before #main-container), styled from the raw tokens. */
.pn-skip {
	position: absolute;
	top: var(--space-4);
	left: var(--space-4);
	z-index: 1000;
	padding: var(--space-3) var(--space-4);
	background: var(--paper-000);
	color: var(--green-950);
	font: var(--weight-medium) var(--text-small) / 1.2 var(--font-sans);
	text-decoration: none;
	transform: translateY(-300%);
}
.pn-skip:focus { transform: none; outline: none; box-shadow: var(--focus-ring); }

@media (prefers-reduced-motion: reduce) {
	.pn .pn-btn:active { transform: none; }
	.pn .pn-btn,
	.pn .pn-link { transition: none; }
}
