/*
 * Base: reset, typography, layout primitives, and the interaction states the
 * mockups do not cover.
 *
 * Every value comes from tokens.css. No raw colours or sizes belong in here.
 */

/* ------------------------------------------------------------------- reset */

*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	-webkit-text-size-adjust: 100%;
}

/*
 * The `hidden` attribute only carries a user agent rule, so any author
 * `display` on the same element beats it and the element renders anyway. That
 * is how the search field's clear button sat over the placeholder on every
 * page while its own script was setting `hidden` correctly. This is the one
 * place in the theme `!important` earns its keep: the alternative is a
 * per-component rule every time something is toggled by attribute.
 */
[hidden] {
	display: none !important;
}

body {
	margin: 0;
	background: var(--fms-cream);
	color: var(--fms-ink);
	font-family: var(--fms-font-body);
	font-weight: var(--fms-weight-regular);
	font-size: var(--fms-size-body);
	line-height: var(--fms-leading-body);
	/* Kept on: the design has real curves and the fonts were drawn with them. */
	-webkit-font-smoothing: antialiased;
}

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

img {
	display: block;
}

button,
input,
select,
textarea {
	font: inherit;
	color: inherit;
}

/* --------------------------------------------------------------- typography
 * Headings are ink, not forest. Forest is chrome and buttons.
 */

h1,
h2,
h3,
h4,
h5,
h6 {
	margin: 0 0 0.5em;
	font-family: var(--fms-font-heading);
	font-weight: var(--fms-weight-semibold);
	line-height: var(--fms-leading-heading);
	color: var(--fms-ink);
}

h1 { font-size: var(--fms-size-h1); }
h2 { font-size: var(--fms-size-h2); }
h3 { font-size: var(--fms-size-h3); line-height: var(--fms-leading-tight); }
h4 { font-size: var(--fms-size-h4); }

p {
	margin: 0 0 1em;
}

a {
	color: var(--fms-forest);
	text-decoration: none;
	transition: color var(--fms-transition);
}

a:hover {
	color: var(--fms-brass);
}

/*
 * Links inside running text carry an underline as well as a colour, because
 * colour alone is not a distinguishable cue: WCAG 1.4.1, and Lighthouse reports
 * it as "links rely on color to be distinguishable". The mockups set
 * `a{text-decoration:none}` globally and draw no underline anywhere, so this is
 * ours rather than theirs, and it is confined to prose. A nav item, a product
 * card and a button all have their own shape and need no underline.
 *
 * Excludes .fms-button, and excludes a link that wraps a whole card or image,
 * because underlining those puts a rule under a picture.
 */
.fms-prose p a:not(.fms-button),
.fms-prose li a:not(.fms-button),
.fms-prose dd a:not(.fms-button),
.fms-prose td a:not(.fms-button),
.fms-prose h1 a:not(.fms-button),
.fms-prose h2 a:not(.fms-button),
.fms-prose h3 a:not(.fms-button),
.fms-prose h4 a:not(.fms-button) {
	text-decoration: underline;
	text-decoration-color: var(--fms-brass);
	text-underline-offset: 3px;
}

/* The lead paragraph. Acceptance criterion 5's 16.5px at 1.55 lives here,
 * which is where the mockups use it. Running text is 15px at 1.7. */
.fms-lead {
	font-size: var(--fms-size-lead);
	line-height: var(--fms-leading-lead);
}

/* Section eyebrow. Always brass, always uppercase, always above a heading. */
.fms-eyebrow {
	margin: 0 0 12px;
	font-family: var(--fms-font-body);
	font-weight: var(--fms-weight-bold);
	font-size: var(--fms-size-eyebrow);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--fms-brass);
}

.fms-measure {
	max-width: var(--fms-measure);
}

/*
 * Prose holds itself to the reading measure, while any band inside it runs the
 * full width of the viewport. This is the content-size and wide-size rule from
 * theme.json, written out for the classic templates, and it is what lets one page
 * mix paragraphs with designed bands.
 */
.fms-prose > * {
	max-width: var(--fms-measure);
	margin-inline: auto;
	padding-inline: var(--fms-gutter);
}

.fms-prose > .fms-band,
.fms-prose > .alignfull,
.fms-prose > .alignwide {
	max-width: none;
	padding-inline: 0;
}

.fms-page-content > .fms-band:first-child {
	margin-top: 0;
}

/* ------------------------------------------------------------------ layout */

/*
 * The container's *content* is 1320px wide, not its border box.
 *
 * `max-width: 1320px` with `padding-inline: 24px` made the content 1272, so
 * every grid on the site sat 48px narrower than the mockup: the hero's two
 * columns measured 636 each instead of 660, and the article hero came out 1272
 * against the drawn 1320. `width: min()` puts the gutter outside the 1320
 * instead, so the content is exactly 1320 wherever the viewport allows it and
 * still keeps its distance from the edge when it does not.
 */
.fms-container {
	width: min(100% - (var(--fms-gutter) * 2), var(--fms-container));
	margin-inline: auto;
}

/*
 * A band is a full width horizontal section. Bands carry their own vertical
 * padding and NEVER a vertical margin: the 176px rhythm between content edges
 * is one band's 88px bottom plus the next band's 88px top.
 */
.fms-band {
	padding-block: var(--fms-band-y);
}

.fms-band--cream { background: var(--fms-cream); }
.fms-band--white { background: var(--fms-white); }
.fms-band--sage { background: var(--fms-sage); }

.fms-band--forest {
	background: var(--fms-forest);
	color: var(--fms-cream);
}

/* Cream, not white: every heading the mockups put on a forest ground is
 * #F7F4ED. The footer's own headings are white, and the footer is not a band. */
.fms-band--forest h1,
.fms-band--forest h2,
.fms-band--forest h3,
.fms-band--forest h4 {
	color: var(--fms-cream);
}

/*
 * `:not(.fms-button)` is load bearing. Without it this rule beats
 * `.fms-button--brass` on specificity, one class plus a type selector against
 * one class, and the brass button on the promotions band rendered brass text on
 * a brass ground: invisible, and measured that way in Chrome before it was
 * caught. A button is not a link for colouring purposes.
 */
.fms-band--forest a:not(.fms-button) {
	color: var(--fms-brass);
}

.fms-band--forest a:not(.fms-button):hover {
	color: var(--fms-white);
}

/* Cards are the only thing that uses white, so they lift off the cream. */
.fms-card {
	background: var(--fms-white);
	border: 1px solid var(--fms-border);
	border-radius: var(--fms-radius-card);
	box-shadow: var(--fms-shadow-card);
	transition: box-shadow var(--fms-transition), border-color var(--fms-transition);
}

.fms-card:hover {
	box-shadow: var(--fms-shadow-card-hover);
	border-color: var(--fms-brass);
}

.fms-grid {
	display: grid;
	gap: var(--fms-gap-card);
}

.fms-grid--4 { grid-template-columns: repeat(4, 1fr); }
.fms-grid--3 { grid-template-columns: repeat(3, 1fr); }
.fms-grid--2 { grid-template-columns: repeat(2, 1fr); }

/* A square artwork slot. The mockups never declare 312px or 163px: both are
 * arithmetic from the grid, so this reproduces them by the same arithmetic
 * rather than hard-coding a number that would drift. */
.fms-square {
	aspect-ratio: 1 / 1;
	background: var(--fms-sage);
	overflow: hidden;
}

.fms-square > img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* ----------------------------------------------------------------- buttons */

.fms-button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: var(--fms-tap-min);
	padding: 13px 32px 11px;
	border: 0;
	border-radius: var(--fms-radius-pill);
	background: var(--fms-forest);
	color: var(--fms-cream);
	font-family: var(--fms-font-body);
	font-weight: var(--fms-weight-medium);
	font-size: var(--fms-size-meta);
	text-transform: uppercase;
	letter-spacing: 0.04em;
	cursor: pointer;
	transition: background var(--fms-transition), color var(--fms-transition);
}

/*
 * Hover darkens with an overlay rather than a darker green, because a darker
 * green would be a ninth colour.
 *
 * The overlay was a palette alpha, `--fms-ink-14`, and that turned out to be
 * the wrong tool: ink is almost exactly as dark as forest, so the hover moved
 * the button from rgb(31,58,46) to rgb(32,55,44) and nobody could see it. A
 * neutral shade does the same job visibly, and the shadow gives the press a
 * second cue that does not depend on colour at all. Every solid button in the
 * theme uses this pair.
 */
.fms-button:hover {
	background: linear-gradient(var(--fms-shade-22), var(--fms-shade-22)), var(--fms-forest);
	color: var(--fms-white);
	box-shadow: var(--fms-shadow-card-hover);
}

/*
 * Ink on brass, which is what all six brass buttons and badges in the mockups
 * use. It is also the higher contrast of the two available choices: brass with
 * ink measures 4.34 to 1 against 3.55 to 1 with white. Neither reaches 4.5, and
 * DECISIONS.md section E records that as a conflict between criterion 1 and
 * criterion 16 that cannot be resolved inside the eight colour palette.
 */
.fms-button--brass {
	background: var(--fms-brass);
	color: var(--fms-ink);
}

.fms-button--brass:hover {
	background: linear-gradient(var(--fms-white-15), var(--fms-white-15)), var(--fms-brass);
	color: var(--fms-ink);
}

.fms-button--ghost {
	background: transparent;
	border: 1px solid var(--fms-forest);
	color: var(--fms-forest);
}

.fms-button--ghost:hover {
	background: var(--fms-forest);
	color: var(--fms-cream);
}

/* -------------------------------------------------------------------- forms */

.fms-input,
input[type='text'],
input[type='search'],
input[type='email'],
input[type='tel'],
input[type='number'],
input[type='password'],
textarea,
select {
	width: 100%;
	min-height: var(--fms-tap-min);
	padding: 14px 26px 12px;
	border: 1px solid var(--fms-border);
	border-radius: var(--fms-radius-input);
	background: var(--fms-white);
	color: var(--fms-ink);
	font-size: var(--fms-size-nav);
}

textarea {
	border-radius: var(--fms-radius-card);
	min-height: 140px;
}

::placeholder {
	color: var(--fms-muted);
	opacity: 1;
}

/* ----------------------------------------------------------- states
 * None of the following is specified in the mockups. See DECISIONS.md D21.
 */

/*
 * Focus. The mockups declare `input:focus { outline: none }` and supply no
 * replacement, which would fail the accessibility target on its own. Keyboard
 * users get a brass ring; mouse users see nothing, via :focus-visible.
 */
:focus-visible {
	outline: var(--fms-focus-ring);
	outline-offset: var(--fms-focus-offset);
}

:focus:not(:focus-visible) {
	outline: none;
}

/* Disabled. Muted ground with cream text keeps the contrast legible without
 * reaching for opacity, which would wash the text below the contrast floor. */
[disabled],
.fms-is-disabled,
[aria-disabled='true'] {
	background: var(--fms-muted);
	border-color: var(--fms-muted);
	color: var(--fms-cream);
	cursor: not-allowed;
	pointer-events: none;
}

/*
 * Errors. The palette contains no red, and adding one would break acceptance
 * criterion 3. Brass carries the colour, but the message never depends on it:
 * every error also gets an icon and the word "Error", so it reads correctly in
 * greyscale and to a screen reader.
 */
.fms-error {
	color: var(--fms-brass);
	font-size: var(--fms-size-meta);
}

.fms-error::before {
	content: '⚠ ';
}

.fms-field--error .fms-input,
.fms-field--error input,
.fms-field--error textarea,
.fms-field--error select {
	border-color: var(--fms-brass);
	border-width: 2px;
}

/* Loading. Used while filters or search run. No spinner asset, no library. */
.fms-is-loading {
	opacity: 0.5;
	transition: opacity var(--fms-transition);
	pointer-events: none;
}

.fms-progress {
	height: 2px;
	background: var(--fms-border);
	overflow: hidden;
}

.fms-progress::after {
	content: '';
	display: block;
	height: 100%;
	width: 40%;
	background: var(--fms-brass);
	animation: fms-progress 1.1s ease-in-out infinite;
}

@keyframes fms-progress {
	0% { transform: translateX(-100%); }
	100% { transform: translateX(350%); }
}

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
	}
}

/* Out of stock, and other neutral status chips. */
.fms-chip {
	display: inline-block;
	padding: 5px 14px;
	border-radius: var(--fms-radius-chip);
	background: var(--fms-sage);
	color: var(--fms-muted);
	font-size: var(--fms-size-eyebrow);
	font-weight: var(--fms-weight-bold);
	text-transform: uppercase;
	letter-spacing: 0.06em;
}

.fms-chip--brass {
	background: var(--fms-brass);
	color: var(--fms-white);
}

/* Screen reader only, and the skip link that becomes visible on focus. */
.fms-visually-hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
	border: 0;
}

.fms-skip-link {
	position: absolute;
	top: -100px;
	left: var(--fms-gutter);
	z-index: 100;
	padding: 12px 24px;
	background: var(--fms-forest);
	color: var(--fms-cream);
	border-radius: 0 0 var(--fms-radius-card) var(--fms-radius-card);
}

.fms-skip-link:focus {
	top: 0;
	color: var(--fms-cream);
}

/* ------------------------------------------------------------- breakpoints
 * One fluid system rather than three artboards. Card grids step down at 900px,
 * and the 390px artboard rules apply from 600px down.
 */

@media (max-width: 900px) {
	.fms-grid--4 { grid-template-columns: repeat(2, 1fr); }
	.fms-grid--3 { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 600px) {
	body {
		font-size: var(--fms-size-body-m);
		line-height: var(--fms-leading-lead);
	}

	h1 { font-size: var(--fms-size-h1-m); }
	h2 { font-size: var(--fms-size-h2-m); }
	h3 { font-size: var(--fms-size-h3-m); }
	h4 { font-size: var(--fms-size-h4-m); }

	.fms-lead { font-size: var(--fms-size-lead-m); }
	.fms-eyebrow { font-size: var(--fms-size-eyebrow-m); }

	.fms-band {
		padding-block: var(--fms-band-y-m);
	}

	.fms-container {
		width: min(100% - (var(--fms-band-x-m) * 2), var(--fms-container));
	}

	.fms-grid {
		gap: var(--fms-gap-card-m);
	}

	.fms-grid--4,
	.fms-grid--3,
	.fms-grid--2 {
		grid-template-columns: repeat(2, 1fr);
	}
}
