/* Chefs Only, the site's own design.

   Source: getComputedStyle measurements taken off the LIVE
   www.chefsonly.be/home1 at 1280px, via
   test/e2e/scripts/live-design-tokens.mjs. NOT from
   ~/dev/mdx-sites/chefsonly.be/, which is a hand-rebuilt proposal
   rather than a mirror; where the two disagree the live measurements win.

   This site and lekker-belgisch.be run the SAME Squarespace template and measure
   identically: Lato throughout, 14px body at rgba(28,28,28,.9) on #fcfcfc,
   hairline uppercase headings. The only measured difference is the link
   colour, gold #c59b26 here against grey #666 on lekker-belgisch. The two
   stylesheets are therefore near-copies on purpose, one file per site, since
   each site owns its own directory (ADR 0018) and Rob may take them apart
   independently.

   LAYERING RULE: priv/cms_assets/site.css is linked first and stays
   unchanged. It owns the section-settings vocabulary (.width-*, .spacing-*,
   .bg-* and the per-kind variants). This file only overrides tokens and
   restyles components; it never blanks a baseline rule.

   NO CAROUSEL RULE HERE, deliberately. The live /products gallery is a grid
   (sqs-gallery-block-grid, verified 10 August 2026), so applying the
   site-wide `.section:not(.hero) + .gallery` carousel heuristic would deviate
   from live rather than match it. */

/* --- Webfonts -----------------------------------------------------------
   Self-hosted: no request to fonts.gstatic.com from a Belgian site.
   See fonts/README.md. */

@font-face {
  font-family: "Lato";
  font-style: normal;
  font-weight: 100;
  font-display: swap;
  src: url("fonts/lato-100-latin.woff2") format("woff2");
}

@font-face {
  font-family: "Lato";
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url("fonts/lato-300-latin.woff2") format("woff2");
}

@font-face {
  font-family: "Lato";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/lato-400-latin.woff2") format("woff2");
}

@font-face {
  font-family: "Lato";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/lato-700-latin.woff2") format("woff2");
}

/* --- Tokens -------------------------------------------------------------
   Measured live: Lato everywhere, 14px/24.5px body in rgba(28,28,28,.9) on
   a near-white #fcfcfc. The palette is deliberately near-monochrome; the
   live site has no coloured brand accent outside its own logo. */

:root {
  --font-body: "Lato", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-heading: var(--font-body);

  --color-text: rgba(28, 28, 28, 0.9);
  --color-text-muted: #666666;
  --color-bg: #fcfcfc;
  --color-bg-subtle: #f5f5f3;
  --color-bg-contrast: #1c1c1c;
  --color-text-on-contrast: #ffffff;
  --color-link: #c59b26;
  --color-border: #e6e6e6;
}

body {
  font-size: 14px;
  line-height: 1.75;
}

/* --- Headings -----------------------------------------------------------
   The signature of this template: Lato 100, a genuine hairline weight,
   uppercase with 1px tracking. That thin elegant look is a very light font
   weight, not a display typeface. */

.hero__heading {
  font-weight: 100;
  font-size: clamp(2rem, 1.2rem + 2.6vw, 3.0625rem);
  line-height: 1.1;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: rgba(28, 28, 28, 0.8);
}

/* The hairline uppercase treatment belongs to the page heading on the
   photograph, not to headings inside the white panel: live sets those in
   bold sentence case, so they read as body copy leading a paragraph. */
.cta__heading,
.location__heading {
  font-weight: 300;
  font-size: 1.15rem;
  line-height: 1.4;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(28, 28, 28, 0.85);
}

.richtext__inner h2 {
  font-weight: 700;
  font-size: 0.95rem;
  line-height: 1.4;
  letter-spacing: 0;
  text-transform: none;
  color: #1c1c1c;
  text-wrap: balance;
}

.hero__eyebrow {
  order: 2;
  font-weight: 400;
  font-size: 0.875rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(28, 28, 28, 0.75);
}

/* --- Links and buttons --------------------------------------------------
   Live links are unstyled-looking, no underline, muted colour. Buttons are
   flat near-black rectangles with wide tracking and no radius. */

a {
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

.hero__action a,
.cta__action a {
  display: inline-block;
  background: #1c1c1c;
  color: #ffffff;
  font-weight: 700;
  font-size: 0.8125rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 0.95rem 1.9rem;
  border-radius: 0;
}

.hero__action a:hover {
  background: #000000;
  text-decoration: none;
}

.cta__action a:hover {
  background: #000000;
  text-decoration: none;
}

/* --- Gallery ------------------------------------------------------------
   Live is a frameless four-up grid, no card borders and no rounded corners,
   generous gaps. Products are shot on white, so tiles get a white plate
   rather than the page's off-white. */

.gallery--grid .gallery__inner {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1.25rem;
}

/* margin: 0 and background: #ffffff for .gallery__item now live in the
   baseline (priv/cms_assets/site.css) - three of the four sites agreed on
   both, so this sheet no longer needs to restate them. */
.gallery__item img {
  display: block;
  width: 100%;
  height: auto;
}

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

@media (max-width: 600px) {
  .gallery--grid .gallery__inner {
    grid-template-columns: repeat(2, 1fr);
    gap: 0.75rem;
  }
}

/* --- Location -----------------------------------------------------------
   The map is one of our own assets (ADR 0017), never a Maps iframe. */

img.location__map {
  display: block;
  max-width: 100%;
  height: auto;
  border: 1px solid var(--color-border);
}

/* The opening hours are one multi-line string on SiteIdentity, so without
   pre-line every day collapses onto a single run-on line. Same treatment as
   site 6. Bullets are deliberately NOT faked with characters in the data. */

.location__hours {
  display: block;
  margin-top: 0.8rem;
  white-space: pre-line;
}

.location__address span {
  display: block;
}

/* --- Poster layout ------------------------------------------------------
   Live is a poster: one photograph fixed behind the whole site, a centred
   gold menu across the top, and the page copy on a white panel floating
   over the photo. Measured off www.chefsonly.be at 1280px.

   The background is a theme file, not a CMS asset: it is chrome, it never
   appears in a section, and the exporter copies the whole theme directory
   (Export.copy_theme!), so `background.jpg` ships with style.css. The gold
   Meynendonckx logo in the top right is baked into that photograph on live,
   so there is no separate logo element to place. */

body {
  background-image: url("background.jpg");
  background-size: cover;
  background-position: center top;
  background-attachment: fixed;
  background-repeat: no-repeat;
}

/* The header is the menu and nothing else: live shows no wordmark up here,
   because the brand is in the photograph. The site name stays in the DOM
   for screen readers and for the link back to the splash. */
.site-header {
  justify-content: center;
  background: transparent;
  padding-top: 1.5rem;
}

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

.site-header nav {
  justify-content: center;
  gap: 1.75rem;
}

.site-header nav a,
.site-nav__group-label {
  color: #c59b26;
  font-weight: 700;
  font-size: 0.875rem;
  letter-spacing: 2px;
  text-transform: uppercase;
}

/* Live never underlines the active nav item; the baseline sheet does. */
.site-header nav a[aria-current="page"] {
  text-decoration: none;
}

/* --- Mobile nav toggle ----------------------------------------------------
   Live collapses the nav into a plain "MENU" text toggle below 640px (the
   same breakpoint site.css already uses for the nav-group submenu). No
   hamburger icon on live, just the label, so the bars are hidden here. The
   button already carries aria-expanded, toggled by app.js; this sheet only
   maps that attribute to a display rule. */
@media (max-width: 40rem) {
  .site-nav-toggle {
    display: block;
    margin: 0 auto;
    background: none;
    border: none;
    cursor: pointer;
    color: #c59b26;
    font-weight: 700;
    font-size: 0.875rem;
    letter-spacing: 2px;
    text-transform: uppercase;
  }

  .site-nav-toggle__bars {
    display: none;
  }

  /* Fixed, not in-flow: the dropdown overlays the page rather than
     pushing it, so opening the menu never moves the hero image beneath it. */
  .site-header {
    position: relative;
  }

  .site-header nav {
    display: none;
    position: fixed;
    top: 4.25rem;
    left: 0;
    right: 0;
    z-index: 20;
    justify-content: center;
    flex-direction: column;
    align-items: center;
    gap: 1.25rem;
    padding: 1.5rem 0;
    background: var(--color-bg);
  }

  .site-nav-toggle[aria-expanded="true"] + nav {
    display: flex;
  }
}

/* The white panel. Every section except the splash hero sits on it, so the
   panel is drawn per section and the sections butt together seamlessly. */
main > .section:not(.hero--media_background) {
  background: #ffffff;
  max-width: 40rem;
  margin-left: auto;
  margin-right: auto;
  width: 100%;
}

main > .section:not(.hero--media_background) > * {
  padding-left: 3.25rem;
  padding-right: 3.25rem;
}

/* 3.25rem (52px) each side is fine on desktop, where the hero section is
   wide, but on a narrow phone viewport it eats a much bigger share of the
   width and forces the page heading to wrap far more than live does. */
@media (max-width: 40rem) {
  main > .section:not(.hero--media_background) > * {
    padding-left: 1.5rem;
    padding-right: 1.5rem;
  }
}

/* --- Sticky footer -------------------------------------------------------
   On a short page the footer used to sit right after the content, leaving
   bare page background below it. Push it to the bottom of the viewport
   instead, without pinning it there on tall pages - it stays in normal
   flow, just with the gap absorbed above it. */
body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* .site-content (masthead + main, footer stays outside per
   MdxWeb.Site.Pages.page/1) is the actual flex item now that the
   masthead sits beside main rather than main sitting directly under
   body; it's also its own flex column so main can still flex:1 within
   whatever the masthead (when present) leaves behind. */
.site-content {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

main {
  flex: 1;
  min-height: 0;
}

/* --- Footer ----------------------------------------------------------------
   Live's footer is a plain centred, uppercase, pipe-separated line on the
   page background - no card, no border, no narrow panel width. */
.site-footer {
  background: transparent;
  border-top: none;
  max-width: none;
  margin: 0;
  padding-top: 2rem;
  padding-bottom: 2rem;
  text-align: center;
}

.site-footer__address {
  display: block;
  font-weight: 700;
  font-size: 0.8125rem;
  letter-spacing: 1px;
  text-transform: uppercase;
}

.site-footer__address span {
  display: inline;
}

.site-footer__name::after {
  content: " | ";
}

.site-footer__street::after {
  content: ", ";
}

.site-footer__locality::after,
.site-footer__phone::after {
  content: " | ";
}

.site-footer__address span.site-footer__vat {
  display: none;
}

/* Below 40rem, stack each field on its own line instead of running them
   together with pipes; street and locality stay one line. */
@media (max-width: 40rem) {
  .site-footer__address span {
    display: block;
  }

  .site-footer__address span.site-footer__street,
  .site-footer__address span.site-footer__locality {
    display: inline;
  }

  .site-footer__name::after,
  .site-footer__locality::after,
  .site-footer__phone::after {
    content: "";
  }
}

/* The splash page (`/`) no longer renders a `hero--media_background`
   section at all - it moved to `page_type: :splash` (2026-08-12,
   plans/2026-08-12-cms-splash-page-type-design.md Task 5) and is now
   rendered by `MdxWeb.Site.Pages.splash/1` via `.splash`/`.splash__image`,
   styled elsewhere in this file. Beurs (`/beurs`) is the only page left
   using `hero--media_background`, and it always has a CTA section after
   the hero, so it always matches the `:not(:only-child)` overrides below.
   That means the three rules that used to exist here for the bare
   `.hero--media_background`/`main:has(> .hero--media_background)`
   selectors are now provably dead:
     - `main:has(> .hero--media_background) { min-height: 0; }` duplicated
       the unconditional `main { min-height: 0; }` rule above (line ~380) -
       removing it changes nothing on any page, splash-shaped or not.
     - `.hero--media_background { flex: 1; min-height: 0; }` was always
       shadowed on Beurs by the higher-specificity
       `main > .hero--media_background:not(:only-child)` rule below
       (`flex: none; min-height: 26rem; max-height: 60vh`), and no page
       renders the bare (only-child) shape anymore.
     - `.hero--media_background .hero__media img { object-position: top
       center; }` was always shadowed on Beurs by the higher-specificity
       `main > .hero--media_background:not(:only-child) .hero__media img`
       rule below (`object-fit: contain; object-position: center`).
   Confirmed via `getComputedStyle` against the live dev export before and
   after removing these three rules (Task 5 report has the values) - Beurs
   renders pixel-identical either way. The `.hero--media_background
   .hero__heading` clip-hiding rule below stays: Beurs still renders that
   heading and still wants it visually hidden. */
.hero--media_background .hero__heading {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --- Beurs: bespoke dark promo banner -------------------------------------
   Live's /beurs is a one-off design unlike every other page: a full-bleed
   dark photo with two gold pill buttons, no white panel at all. It reuses
   hero--media_background (the splash's own full-bleed-photo machinery)
   rather than inventing new CSS, but the splash's hero is the ONLY section
   on its page (flex:1, fills the whole remaining viewport - see above);
   this one has a CTA section after it and needs a bounded height instead
   of also fighting for 100% of the leftover space. :not(:only-child) is
   the distinguishing signal, since both share every class otherwise. */
main > .hero--media_background:not(:only-child) {
  flex: none;
  min-height: 26rem;
  max-height: 60vh;
}

/* The 26rem desktop minimum leaves a slab of empty dark space above a
   narrow-viewport contain-fit image, which is short relative to its
   width. Let the section size to the image itself on a phone instead. */
@media (max-width: 40rem) {
  main > .hero--media_background:not(:only-child) {
    min-height: 0;
  }
}

/* This banner image has "CHEFS ONLY @ TRADEMART BRUSSELS" baked into the
   photo itself (same asset family as lekker-belgisch's beurs-cover.jpg -
   see memory project_cms_sites_789_live_facts). object-fit:cover, inherited
   from the splash's own full-bleed treatment, was cropping that text off
   at the top instead of showing the whole banner. contain shows the whole
   image, unlike cover which fills the box by cropping. */
main > .hero--media_background:not(:only-child) .hero__media img {
  object-fit: contain;
  object-position: center;
  background: #1c1c1c;
}

/* The CTA section right after it carries on the same dark banner, since
   our content model has one button where live overlays two on the photo
   itself - the closest honest match without inventing a second link. */
main > .hero--media_background:not(:only-child) + .cta.bg-contrast {
  background: #1c1c1c;
  max-width: none;
}

main > .hero--media_background:not(:only-child) + .cta.bg-contrast .cta__heading {
  color: #f5efe0;
}

main > .hero--media_background:not(:only-child) + .cta.bg-contrast .cta__inner p {
  color: rgba(245, 239, 224, 0.75);
}

main > .hero--media_background:not(:only-child) + .cta.bg-contrast .cta__action a {
  background: #c59b26;
  color: #1c1c1c;
}

main > .hero--media_background:not(:only-child) + .cta.bg-contrast .cta__action a:hover {
  background: #b58e0d;
}

/* --- Panel rhythm -------------------------------------------------------
   Live sets the copy tight: paragraphs sit about half a line apart, not the
   full line the baseline gives every section. Measured against the live
   panel at 1280px, where the whole NL+FR block fits in roughly the height
   our looser spacing needed for the Dutch half alone. */

main > .section:not(.hero--media_background) {
  max-width: 37.75rem; /* 604px, measured live's richtext text column */
}

/* The products gallery panel is a different, WIDER box on live (720px)
   than the richtext text column above - matches lekker-belgisch exactly,
   same template, same measurement. */
main > .section.gallery:not(.hero--media_background) {
  max-width: 45rem; /* 720px, measured live */
}

main > .section.spacing-normal:not(.hero--media_background) > * {
  padding-top: 0.9rem;
  padding-bottom: 0.9rem;
}

.richtext__inner {
  gap: 0.55rem;
}

.richtext__inner h2 {
  margin-top: 0.9rem;
  margin-bottom: 0;
}

.richtext__inner p {
  margin: 0;
}

/* Live marks a menu group with a leading plus, which is the only cue that
   the item opens rather than navigates. */
.site-nav__group-label::before {
  content: "+ ";
}

/* Consecutive panel sections are one continuous sheet on live, so the seam
   between them carries a paragraph's worth of space, not two sections'
   worth. The NL and FR halves of a page are two sections purely because
   they are two languages; the reader should not see the join. */
main > .section.spacing-normal:not(.hero--media_background) > * {
  padding-top: 0.45rem;
  padding-bottom: 0.45rem;
}

/* The comment above only shrinks the child's own padding; the visible gap
   is the SECTION's padding-top/bottom (3rem each from the site-wide
   spacing-normal rule), which is still full-sized on both sides of the
   seam. Collapse it only at the seam between two stacked richtext
   sections, not at the top of the first section or the bottom of the
   last. */
main > .section.richtext.spacing-normal + .section.richtext.spacing-normal {
  padding-top: 0.9rem;
}

main > .section.richtext.spacing-normal:has(+ .section.richtext.spacing-normal) {
  padding-bottom: 0.9rem;
}

/* Same seam collapse where an image+heading hero (Verleye, Trzor, Creades,
   Service) is immediately followed by its richtext body copy - live shows
   no gap between the two white panels at all. */
main > .section.hero--centered:has(.hero__media).spacing-normal {
  padding-bottom: 0;
}

main > .section.hero--centered:has(.hero__media).spacing-normal + .section.richtext.spacing-normal {
  padding-top: 0;
}

/* Live's text column carries NO left/right inset of its own on desktop -
   it IS the 604px box main > .section.richtext is matched to above. The
   generic 3.25rem inset is still right for the page-heading hero section,
   but on the richtext panels it just narrows the text and forces extra
   line-wraps live doesn't have. On mobile live pads directly instead of
   relying on the desktop wide-box-centering trick, so a smaller 1.5rem
   inset is restored there. */
main > .section.richtext:not(.hero--media_background) {
  padding-inline: 3.25rem;
}

main > .section.richtext:not(.hero--media_background) > * {
  padding-left: 0;
  padding-right: 0;
}

@media (max-width: 40rem) {
  main > .section.richtext:not(.hero--media_background) {
    padding-left: 1.5rem;
    padding-right: 1.5rem;
  }
}

/* --- Site masthead --------------------------------------------------------
   A real element now (MdxWeb.Site.Pages.page/1 + Mdx.CMS.Theme.masthead/1),
   not CSS-generated content: "Chefs Only" plus its tagline, shown above
   every page's own content except the splash and Beurs, which already
   carry the same text baked into their own full-bleed photo. Site design,
   not CMS content - by explicit choice this REPLACES each page's own
   title (Products, Contact, ...) rather than sitting alongside it, so
   every hero section below renders its own heading small, inside the
   white panel, regardless of whether it also carries a photo. */
.site-masthead {
  padding: 1.75rem 1.25rem 0;
  text-align: center;
}

.site-masthead__title {
  margin: 0;
  margin-block: 2rem;
  font-weight: 100;
  font-size: clamp(2rem, 1.2rem + 2.6vw, 3.0625rem);
  line-height: 1.1;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: rgba(28, 28, 28, 0.8);
}

.site-masthead__subtitle {
  margin: 0;
  margin-bottom: 3.75rem;
  font-weight: 400;
  font-size: 0.875rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(28, 28, 28, 0.75);
}

/* Every hero section - whether it's a plain title (Products, Contact) or
   carries its own photo (Verleye, Trzor, Creades, Service) - renders its
   own heading small and inside the white panel now that the masthead
   above covers the big brand title. hero__media and hero__inner are
   SIBLINGS in the markup, not media nested inside inner, so both need the
   identical box treatment to read as one continuous panel with no visible
   seam, the same trick the richtext sections use for their own NL/FR
   seam.

   604.8px/37.75rem flat, zero padding, matching the richtext sections
   directly below: measured live, image/heading/paragraph all share the
   exact same x-coordinate (417.59px) - flush, not inset. An earlier pass
   tried a wider 720px outer box here, which misaligned this section's
   left edge against the richtext sections under it. */
main > .section.hero--centered .hero__media,
main > .section.hero--centered .hero__inner {
  background: #ffffff;
  max-width: 37.75rem;
  margin-left: auto;
  margin-right: auto;
  width: 100%;
  padding: 0;
}

main > .section.hero--centered .hero__media {
  margin-bottom: 0;
}

main > .section.hero--centered .hero__inner {
  align-items: flex-start;
  text-align: left;
}

@media (max-width: 40rem) {
  main > .section.hero--centered .hero__media,
  main > .section.hero--centered .hero__inner {
    padding: 0 1.5rem;
  }
}

/* Live shows no per-page title at all on these pages now that the
   masthead above covers that role sitewide - visibly repeating the
   page's own heading right underneath it just duplicated "Chefs Only" (or
   any other heading) a second time. Visually hidden, not removed: it
   stays in the DOM as the page's h1/h2 for a screen reader and for
   search, same treatment as the splash and Beurs headings above. */
main > .section.hero--centered .hero__heading {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Without a photo (Products, Contact), hiding the heading above leaves
   hero__inner empty - it collapses to 0 height on its own, but the
   SECTION's own 3rem top/bottom spacing-normal padding doesn't, leaving a
   96px blank gap between the masthead and this page's first real content
   (its gallery or location section). Collapse that too, only for the
   no-photo case - Verleye/Trzor/Creades/Service still need their normal
   spacing around the photo. */
main > .section.hero--centered:not(:has(.hero__media)) {
  padding-top: 0;
  padding-bottom: 0;
}

/* A page with no hero section at all (/home/ - just two richtext blocks,
   NL then FR) falls back to MdxWeb.Site.Pages' generic pagetitle block
   instead, and it duplicated "Chefs Only" a second time same as the hero
   heading did above - same fix, same reasoning: visually hidden, not
   removed, and its own section padding collapsed so it leaves no gap. */
main > .section.pagetitle {
  padding-top: 0;
  padding-bottom: 0;
}

main > .section.pagetitle .pagetitle__inner {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* exclusive product pages */

.trezor, .verleye, .creades, .service {
  h2 {
      font-family: Lato;
      font-style: normal;
      font-weight: 300;
      font-size: 18px;
      letter-spacing: 4px;
      text-transform: uppercase;
      text-decoration: none;
      line-height: 1.1em;
      color: #1c1c1c;
      margin: 2em 0 .75em;
  }

}

body.home {
    background-image: none;
    .hero--media_background .hero__media img {
        object-fit: contain;
        object-position: center;
    }
}
