/* Farm Meat Market — site styles
 *
 * Ported from the confirmed Round 1 artboards. Three things differ from the
 * mockups, all deliberate:
 *
 *   1. Type and gutters are fluid rather than fixed at the 1440px artboard size,
 *      so there is no dead zone between breakpoints.
 *   2. Colour pairings are encoded as ground classes instead of per-element
 *      inline styles. Put .on-wine on a section and everything inside it picks
 *      the pairing that passes contrast on wine. That is what stops the 158
 *      failures from creeping back the first time someone adds a heading.
 *   3. Every clamp() keeps its maximum under 2.5x its minimum, so the page still
 *      reflows properly for anyone who has raised their browser's text size.
 */

/* ---------------------------------------------------------------- fonts */
/* Headline Gothic is licensed from ATF — the webfont here is Farm Meat Market's
   own licensed copy. Familjen Grotesk is OFL. Both are subset to Latin. */
@font-face {
  font-family: 'Headline Gothic';
  src: url('/fonts/hg.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: 'Familjen Grotesk';
  src: url('/fonts/fg-400.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: 'Familjen Grotesk';
  src: url('/fonts/fg-600.woff2') format('woff2');
  font-weight: 600;
  font-display: swap;
}
@font-face {
  font-family: 'Familjen Grotesk';
  src: url('/fonts/fg-700.woff2') format('woff2');
  font-weight: 700;
  font-display: swap;
}

/* --------------------------------------------------------------- tokens */
:root {
  --wine: #4E1325;
  --crimson: #CC1517;
  --bone: #DED6AD;
  --tallow: #F5F3E2;
  --flesh: #D99695;
  --paper: #DBDDE2;          /* the studio ground the product shots sit on */

  /* frozen chip — the one sanctioned departure from the palette */
  --ice: #DCE9F0;
  --ice-line: #BCD6E4;
  --ice-ink: #24536B;

  --gut: clamp(1.25rem, 6vw, 6.25rem);
  --max: 77.5rem;

  /* Display sizes. The artboards were drawn at the maximum; the minimum is what
     a 360px phone gets. */
  --d1: clamp(2.75rem, 1.4rem + 6vw, 5.5rem);
  --d2: clamp(2rem, 1.1rem + 4vw, 3.875rem);
  --d3: clamp(1.625rem, 1.1rem + 2.2vw, 2.625rem);
  --d4: clamp(1.25rem, 1rem + 1vw, 1.6875rem);

  --band: clamp(3.5rem, 8vw, 6.875rem);
  --band-tight: clamp(2.75rem, 6vw, 4.75rem);
}

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

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

body {
  margin: 0;
  background: var(--tallow);
  color: var(--wine);
  font-family: 'Familjen Grotesk', system-ui, -apple-system, 'Segoe UI', Arial, sans-serif;
  font-size: 1.0625rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { display: block; max-width: 100%; height: auto; }

p { margin: 0; text-wrap: pretty; }

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

a { color: var(--crimson); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--wine); }

/* Visible focus everywhere. Keyboard users get a ring that clears the text. */
:focus-visible {
  outline: 3px solid currentColor;
  outline-offset: 3px;
}

/* Honour a reduced-motion preference for every transition on the site. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--wine);
  color: var(--tallow);
  padding: 0.75rem 1.25rem;
  z-index: 100;
}
.skip:focus { left: 0; }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ------------------------------------------------------------- typography */
.hg {
  font-family: 'Headline Gothic', 'Arial Narrow', Arial, sans-serif;
  text-transform: uppercase;
  font-weight: 400;
  letter-spacing: 0;
}

.d1 { font-size: var(--d1); line-height: 0.92; margin: 0; }
.d2 { font-size: var(--d2); line-height: 0.96; margin: 0; }
.d3 { font-size: var(--d3); line-height: 1; margin: 0; }
.d4 { font-size: var(--d4); line-height: 1.08; margin: 0; }

.lede { font-size: clamp(1.125rem, 1rem + 0.6vw, 1.3125rem); line-height: 1.55; margin: 0; }
.small { font-size: 0.90625rem; line-height: 1.58; }

/* Secondary text — dates, captions. Set here rather than inline because the
   value is a contrast threshold, not a taste decision: below about .7 the wine
   lifts off the tallow and small text drops under 4.5:1. */
.meta { opacity: 0.72; }

.tiny {
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.16em;
}

/* --------------------------------------------------------------- grounds */
/* Set the ground once on a section; text inside picks a pairing that passes.
   These values come from measuring the palette against itself:
     on wine     bone 9.9   crimson 2.6 (display only)
     on crimson  tallow 5.1  bone 3.9 (display only)
     on bone     wine 9.9   crimson 3.9 (display only)
     on tallow   wine 13.0  crimson 5.1
   Small text never gets a pairing below 4.5. */
/* Each ground sets its own colours as custom properties rather than as
   descendant rules. It matters when grounds nest — a bone card inside a tallow
   section, say: descendant selectors of equal specificity are settled by their
   order in this file, so the outer section would win and the card's small text
   would be styled for the wrong background. Custom properties inherit, so the
   nearest ground always wins, which is the behaviour you would expect. */
.on-wine    { background: var(--wine);    color: var(--bone);   --accent: var(--bone);    --link: var(--bone); }
.on-crimson { background: var(--crimson); color: var(--tallow); --accent: var(--tallow);  --link: var(--tallow); }
.on-bone    { background: var(--bone);    color: var(--wine);   --accent: var(--wine);    --link: var(--wine); }
.on-tallow  { background: var(--tallow);  color: var(--wine);   --accent: var(--crimson); --link: var(--crimson); }
.on-flesh   { background: var(--flesh);   color: var(--wine);   --accent: var(--wine);    --link: var(--wine); }

.eyebrow, .cue { color: var(--accent, var(--crimson)); }
a { color: var(--link, var(--crimson)); }

/* Display type takes the ground's own text colour. */
.d1, .d2, .d3, .d4 { color: inherit; }

.eyebrow {
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  margin: 0;
}

/* ---------------------------------------------------------------- layout */
.wrap { max-width: var(--max); margin-inline: auto; padding-inline: var(--gut); }

.band { padding-block: var(--band); }
.band-tight { padding-block: var(--band-tight); }

.stack { display: flex; flex-direction: column; }
.row { display: flex; align-items: center; flex-wrap: wrap; }

/* Grids collapse by available width rather than by device, so a two-column
   block inside a narrow container behaves the same as on a small screen. */
.grid { display: grid; gap: clamp(1.5rem, 4vw, 4rem); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr)); }
.grid-5 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr)); }

.rule { height: 3px; background: var(--crimson); border: 0; margin: 0; }
.hair { height: 1px; background: currentColor; opacity: 0.3; border: 0; margin: 0; }

/* --------------------------------------------------------------- header */
.topstrip {
  background: var(--wine);
  color: var(--bone);
  padding: 0.5625rem var(--gut);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.16em;
}
.topstrip .second { display: none; }
@media (min-width: 60rem) { .topstrip .second { display: inline-flex; align-items: center; } }

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2.5rem;
  padding: 1.25rem var(--gut);
  background: var(--crimson);
}
.nav__logo { width: clamp(7.5rem, 14vw, 10.25rem); }

.nav__links { display: flex; gap: 0.5rem; align-items: center; list-style: none; margin: 0; padding: 0; }
.nav__links a {
  font-size: 0.8125rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--tallow);              /* 5.1 on crimson; bone would be 3.9 */
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  min-height: 44px;                   /* a real tap target */
  padding-inline: 0.75rem;
}
.nav__links a:hover { color: var(--bone); }
/* The current page is marked by an underline as well as colour, so it doesn't
   depend on colour vision to read. */
.nav__links a[aria-current="page"] {
  color: var(--tallow);
  box-shadow: inset 0 -3px 0 0 var(--wine);
}

/* Below the nav breakpoint the links become a disclosure, driven by <details>
   so it works with JavaScript switched off. */
.nav .nav__toggle { display: none; }   /* beats .btn's inline-flex on specificity */
@media (max-width: 63.99rem) {
  .nav { flex-wrap: wrap; }
  .nav__links { display: none; }
  .nav .nav__toggle { display: inline-flex; }
  .nav[data-open] .nav__links {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    width: 100%;
    gap: 0;
    border-top: 1px solid rgba(245, 243, 226, 0.25);
    margin-top: 0.75rem;
    padding-top: 0.5rem;
  }
  /* The enquiry button would otherwise wrap onto a row of its own and push the
     photograph down the screen, so below the breakpoint it lives inside the
     menu rather than in the bar. */
  .nav .nav__cta { display: none; }
  .nav[data-open] .nav__cta {
    display: inline-flex;
    justify-content: center;
    width: 100%;
    margin-top: 0.875rem;
  }
}

/* -------------------------------------------------------------- controls */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  padding: 1.0625rem 1.875rem;
  font-size: 0.8125rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  min-height: 48px;
  text-decoration: none;
  border: 0;
  cursor: pointer;
}
.btn--crimson { background: var(--crimson); color: var(--tallow); }
.btn--bone { background: var(--bone); color: var(--wine); }
.btn--wine { background: var(--wine); color: var(--bone); }
.btn--outline { border: 2px solid currentColor; background: transparent; color: inherit; }
.btn:hover { filter: brightness(1.08); }

.cue {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 44px;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  text-decoration: none;
}
.cue:hover { text-decoration: underline; }

.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4375rem;
  padding: 0.4375rem 0.8125rem;
  font-size: 0.71875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
}
.chip--fresh { background: var(--crimson); color: var(--tallow); }
.chip--frozen { background: var(--ice); color: var(--ice-ink); border: 1px solid var(--ice-line); }

/* A value the business hasn't supplied yet. Loud on purpose — it should be
   impossible to ship a page with one of these still on it. */
/* Solid rather than tinted. A translucent fill takes its contrast from whatever
   happens to be behind it, and these markers sit on all five grounds. */
.tbc {
  background: var(--crimson);
  color: var(--tallow);
  padding: 1px 6px;
  font-weight: 700;
}
.on-wine .tbc, .on-crimson .tbc, .footer .tbc {
  background: var(--bone);
  color: var(--wine);
}

/* ----------------------------------------------------------- range cards */
.rcard {
  display: flex;
  flex-direction: column;
  background: #fff;
  outline: 1px solid rgba(78, 19, 37, 0.1);
  container-type: inline-size;        /* the card scales by its own width */
}
.rcard__img { position: relative; aspect-ratio: 1; overflow: hidden; background: var(--paper); }
.rcard__img img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.rcard__swatch { height: 9px; outline: 1px solid rgba(78, 19, 37, 0.45); outline-offset: -1px; }
.rcard__body { padding: 1.25rem 1.25rem 1.5rem; display: flex; flex-direction: column; gap: 0.5rem; }
.rcard__title { font-size: clamp(1.125rem, 7cqi, 1.5rem); line-height: 1.05; color: var(--wine); margin: 0; }

/* ---------------------------------------------------------- deck nine-up */
.nineup { position: relative; width: 100%; max-width: 56.25rem; }
.nineup__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.625rem; }
.nineup__badge {
  position: absolute;
  transform: translate(-50%, -50%);
  pointer-events: none;
}

/* ---------------------------------------------------------------- footer */
.footer { background: var(--wine); color: var(--bone); }
.footer a { color: var(--bone); text-decoration: none; }
.footer a:hover { text-decoration: underline; }
.foot-col .eyebrow { color: var(--bone); margin-bottom: 1rem; display: block; }
.foot-col p { margin: 0 0 0.5625rem; font-size: 0.9375rem; opacity: 0.9; }
.foot-col ul { list-style: none; margin: 0; padding: 0; }
.foot-col li { margin: 0 0 0.5625rem; font-size: 0.9375rem; }

/* ------------------------------------------------------------- utilities */
.media { background: var(--paper); }
.ratio-32 { aspect-ratio: 3 / 2; object-fit: cover; width: 100%; }
.ratio-11 { aspect-ratio: 1; object-fit: cover; width: 100%; }
.ratio-45 { aspect-ratio: 4 / 5; object-fit: cover; width: 100%; }

.slot {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.625rem;
  border: 2px dashed rgba(204, 21, 23, 0.55);
  background: rgba(204, 21, 23, 0.05);
  color: var(--crimson);
  text-align: center;
  padding: 1.5rem;
}

/* ------------------------------------------------------------------ hero */
.hero {
  position: relative;
  min-height: clamp(30rem, 62vw, 51.25rem);
  display: grid;
  align-items: end;
  overflow: hidden;
  background: var(--paper);
}
.hero__slides { position: absolute; inset: 0; }
.hero__slide {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.85s ease-in-out;
}
.hero__slide.is-on { opacity: 1; }

.hero__copy {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 1.375rem;
  padding-block: clamp(2.5rem, 6vw, 4.625rem);
  max-width: var(--max);
  width: 100%;
}

.hero__dots {
  position: absolute;
  right: var(--gut);
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: 0.6875rem;
}
.hero__dots button {
  width: 44px;                     /* a real tap target, with a small visible mark */
  height: 44px;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  display: grid;
  place-items: center;
}
.hero__dots button::before {
  content: "";
  width: 9px;
  height: 9px;
  border: 1.5px solid var(--wine);
  background: transparent;
  transition: background 0.3s;
}
.hero__dots button[aria-selected="true"]::before { background: var(--wine); }

/* On a phone the frame is portrait while the photograph is landscape. Overlaying
   the copy means either the words sit on the meat or a scrim washes the meat
   out, and neither is worth having — so the hero unstacks: the photograph keeps
   close to its own proportions in a band of its own, and the copy sits below it
   on solid paper. The crossfade and the alt text are unchanged. */
@media (max-width: 47.99rem) {
  .hero { display: block; min-height: 0; }
  .hero__slides { position: relative; inset: auto; aspect-ratio: 16 / 10; }
  .hero__slide { object-position: 62% 50%; }
  .hero__copy { padding-top: clamp(1.75rem, 7vw, 2.5rem); }
  .hero__dots { display: none; }
}

/* -------------------------------------------------------------- masthead */
.masthead { padding-block: clamp(3.25rem, 7vw, 5.5rem); }
.masthead__eyebrow { display: block; margin-bottom: 1.375rem; }
.masthead .d2 { max-width: 52rem; }
.masthead__lede { max-width: 41rem; margin-top: 1.5rem; opacity: 0.86; }

/* ----------------------------------------------------- range page blocks */
/* Two columns where there is room for both, one where there isn't. The photo
   grid keeps its own maximum so it never outgrows the words beside it. */
.rangehead {
  display: grid;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
}
@media (min-width: 60rem) {
  .rangehead { grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); }
}

/* Cut and specification. A description list because that is what it is: each
   cut is a term and each spec defines it, which is also how a screen reader
   will read it out. */
.cuts { margin: 0; }
.cuts__row {
  display: grid;
  gap: 0.25rem 1.5rem;
  padding: 0.875rem 0;
  border-top: 1px solid rgba(78, 19, 37, 0.18);
}
.cuts__row:last-child { border-bottom: 1px solid rgba(78, 19, 37, 0.18); }
@media (min-width: 40rem) {
  .cuts { columns: 2; column-gap: clamp(2rem, 5vw, 3.5rem); }
  .cuts__row { grid-template-columns: minmax(0, 11rem) minmax(0, 1fr); break-inside: avoid; }
  /* A column break can leave the first row of the second column without its
     rule, so the rule is restated at the top of each column. */
  .cuts__row:nth-child(1) { break-before: auto; }
}
.cuts__cut { font-size: 1.1875rem; line-height: 1.25; color: var(--wine); margin: 0; }
.cuts__spec { margin: 0; opacity: 0.82; }

.chip--quiet { background: rgba(78, 19, 37, 0.1); color: var(--wine); }
.on-wine .chip--quiet { background: rgba(222, 214, 173, 0.18); color: var(--bone); }

/* Three photographs edge to edge, or a single strip of one on a phone. */
.photostrip { display: grid; grid-template-columns: repeat(3, 1fr); }
.photostrip img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; background: var(--paper); }
@media (max-width: 40rem) {
  .photostrip { grid-template-columns: 1fr; }
  .photostrip img { aspect-ratio: 16 / 9; }
}

/* A placeholder slot on a dark ground. Same loudness, legible colours. */
.slot--dark {
  border-color: rgba(222, 214, 173, 0.55);
  background: rgba(222, 214, 173, 0.08);
  color: var(--bone);
}

/* ------------------------------------------------------------------ form */
.form-card { padding: clamp(1.75rem, 4vw, 2.75rem); }

.form { display: flex; flex-direction: column; gap: 1.125rem; }

.field { display: flex; flex-direction: column; gap: 0.4375rem; border: 0; padding: 0; margin: 0; }
.field-row { display: grid; gap: 1.125rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr)); }

.field label, .field legend {
  font-size: 0.78125rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--wine);
  padding: 0;
}

.field input[type="text"],
.field input[type="email"],
.field input[type="tel"],
.field textarea {
  font: inherit;
  color: var(--wine);
  background: var(--tallow);
  border: 1px solid rgba(78, 19, 37, 0.35);
  border-radius: 0;
  padding: 0.75rem 0.875rem;
  min-height: 3rem;
  width: 100%;
}
.field textarea { resize: vertical; min-height: 6.5rem; }
.field input:focus-visible, .field textarea:focus-visible { outline-offset: 1px; }

/* :user-invalid marks a field only once the person has actually engaged with it,
   so an untouched required field is never shown as an error. */
.field input:user-invalid, .field textarea:user-invalid { border-color: var(--crimson); border-width: 2px; }

.checks__row { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.check {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  background: var(--tallow);
  border: 1px solid rgba(78, 19, 37, 0.35);
  padding: 0.5625rem 0.875rem;
  min-height: 44px;
  cursor: pointer;
  font-size: 0.875rem;
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
  color: var(--wine);
}
.check input { accent-color: var(--crimson); width: 1.0625rem; height: 1.0625rem; }
.check:has(input:checked) { border-color: var(--crimson); border-width: 2px; padding: calc(0.5625rem - 1px) calc(0.875rem - 1px); }

/* Off-screen rather than display:none — a hidden field some bots still fill in,
   and one a real person never sees or tabs to. */
.form__trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form__submit { align-self: flex-start; margin-top: 0.5rem; }

.form__status { margin: 0; font-weight: 600; }
.form__status:empty { display: none; }
.form__status[data-kind="ok"] { color: var(--wine); }
.form__status[data-kind="bad"] { color: var(--crimson); }

/* --------------------------------------------------------- detail blocks */
.deets { margin: 0; display: flex; flex-direction: column; gap: 1.125rem; }
.deets > div { display: grid; gap: 0.25rem 1.5rem; }
@media (min-width: 30rem) { .deets > div { grid-template-columns: minmax(0, 8.5rem) minmax(0, 1fr); } }
.deets dt {
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--crimson);
  padding-top: 0.1875rem;
}
.deets dd { margin: 0; }
.deets__line { display: block; }

/* ----------------------------------------------------------------- prose */
/* Long-form text — legal notices, journal bodies. One measure, set in ch so it
   stays around 70 characters whatever the reader's text size. */
.prose { max-width: 68ch; }
.prose h2 {
  font-family: 'Headline Gothic', 'Arial Narrow', Arial, sans-serif;
  text-transform: uppercase;
  font-weight: 400;
  font-size: var(--d4);
  line-height: 1.1;
  margin: 2.5rem 0 0.875rem;
}
.prose h2:first-child { margin-top: 0; }
.prose h3 { font-size: 1.125rem; margin: 2rem 0 0.625rem; }
.prose p { margin: 0 0 1.125rem; }
.prose ul, .prose ol { margin: 0 0 1.125rem; padding-left: 1.25rem; }
.prose li { margin-bottom: 0.4375rem; }
.prose > :last-child { margin-bottom: 0; }

/* Footer navigation is a list of links, not links inside a sentence, so each one
   needs a target of at least 24px in its own right (WCAG 2.2, 2.5.8). */
.foot-col li a, .foot-col p a {
  display: inline-block;
  padding-block: 0.1875rem;
  min-height: 24px;
}
