/* Meynendonckx CMS, Phase 3 Task 1: the baseline public-site stylesheet.
   Per generic design section 10, a :root block of tokens (fonts, content
   widths, spacing scale, colour roles) plus just enough component CSS that
   the settings tokens (width, spacing, background, hero variant, rich-text
   alignment) actually do something visible. Per-site design is Phase 7 -
   this is a baseline, not a design. Keep it small and boring. */

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

  --width-narrow: 40rem;
  --width-normal: 60rem;
  --width-wide: 80rem;
  --width-full: 100%;

  --space-compact: 1.5rem;
  --space-normal: 3rem;
  --space-spacious: 6rem;

  --color-text: #1a1a1a;
  --color-text-muted: #555555;
  --color-bg: #ffffff;
  --color-bg-subtle: #f5f5f3;
  --color-bg-contrast: #1a1a1a;
  --color-text-on-contrast: #ffffff;
  --color-link: #1a4d8f;
  --color-border: #dddddd;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  font-family: var(--font-body);
  color: var(--color-text);
  background: var(--color-bg);
  line-height: 1.5;
}

main {
  display: flex;
  flex-direction: column;
}

h1,
h2,
h3,
h4 {
  font-family: var(--font-heading);
  line-height: 1.2;
}

a {
  color: var(--color-link);
}

/* --- Header / nav / footer (site chrome) -------------------------------- */

.site-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.5rem 1.25rem;
}

.site-wordmark {
  font-weight: bold;
  font-size: 1.125rem;
  color: var(--color-text);
  text-decoration: none;
}

/* The logo picker on the identity form is site-agnostic: every site can set
   a wordmark image, not just the ones with their own stylesheet. This is a
   floor, not a design - height: auto browser sizing is unbounded, so a
   sane default keeps an unstyled site's header from being crushed. A
   per-site sheet, loaded after this one, can still override it. */
.site-wordmark__image {
  height: 40px;
  width: auto;
}

/* The nav toggle button is markup-only plumbing for a later hamburger-menu
   task; it stays invisible here so a site with no theme of its own is
   unaffected by its presence. A site's own stylesheet, loaded after this
   one, opts it in by giving it a display value. */
.site-nav-toggle {
  display: none;
}

.site-header nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.25rem;
}

.site-header nav a[aria-current="page"] {
  text-decoration: underline;
}

/* --- Grouped menu items -------------------------------------------------
   A group heading is a label with a submenu, not a link. The submenu opens
   on hover AND on focus-within, so it is reachable by keyboard; there is no
   JavaScript involved, which matters because the exported sites ship only
   the small mobile-toggle script and nothing here may depend on it.

   Below the mobile breakpoint the submenu is simply always open: a hover
   dropdown on a touch screen is a trap, and the menu is already a vertical
   stack there. */

.site-nav__group {
  position: relative;
}

.site-nav__group-label {
  cursor: default;
}

/* Hidden with opacity, NOT display:none or visibility:hidden. Both of those
   make the children unfocusable, so tabbing can never move into the submenu,
   so :focus-within can never fire, so a keyboard user cannot open it at all.
   Opacity leaves them focusable: the first Tab into the group reveals it. */
.site-nav__children {
  position: absolute;
  left: 0;
  top: 100%;
  z-index: 10;
  opacity: 0;
  pointer-events: none;
  margin: 0;
  padding: 0.75rem 1rem;
  list-style: none;
  min-width: 10rem;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
}

.site-nav__group:hover .site-nav__children,
.site-nav__group:focus-within .site-nav__children {
  opacity: 1;
  pointer-events: auto;
}

.site-nav__children li + li {
  margin-top: 0.5rem;
}

/* On a narrow screen the menu is already a wrapped stack and there is no
   hover, so the submenu is shown open and in flow rather than as an
   absolutely positioned panel that can never be dismissed by touch. */
@media (max-width: 40rem) {
  .site-nav__children {
    position: static;
    opacity: 1;
    pointer-events: auto;
    padding: 0.25rem 0 0 0.75rem;
    min-width: 0;
    background: none;
    border: none;
    border-left: 1px solid var(--color-border);
  }
}

.site-footer {
  padding: 1.5rem 1.25rem;
  border-top: 1px solid var(--color-border);
  color: var(--color-text-muted);
}

.site-footer__address {
  font-style: normal;
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1rem;
}

.site-footer__address span {
  display: block;
}

/* --- Section-level tokens (shared by every section kind) --------------- */

.section {
  padding-left: 1rem;
  padding-right: 1rem;
}

.section > * {
  margin-left: auto;
  margin-right: auto;
}

.width-narrow > * {
  max-width: var(--width-narrow);
}

.width-normal > * {
  max-width: var(--width-normal);
}

.width-wide > * {
  max-width: var(--width-wide);
}

.width-full > * {
  max-width: var(--width-full);
}

.spacing-compact {
  padding-top: var(--space-compact);
  padding-bottom: var(--space-compact);
}

.spacing-normal {
  padding-top: var(--space-normal);
  padding-bottom: var(--space-normal);
}

.spacing-spacious {
  padding-top: var(--space-spacious);
  padding-bottom: var(--space-spacious);
}

.bg-default {
  background: var(--color-bg);
}

.bg-subtle {
  background: var(--color-bg-subtle);
}

.bg-contrast {
  background: var(--color-bg-contrast);
  color: var(--color-text-on-contrast);
}

.bg-image {
  background: var(--color-bg-contrast);
  color: var(--color-text-on-contrast);
  background-size: cover;
  background-position: center;
}

/* The chosen Achtergrond image (set inline as --section-bg). Declared
   !important because the per-site stylesheets restyle sections with the
   `background:` shorthand (e.g. `main > .section:not(...)`), which would
   otherwise reset the image, size and position. */
.bg-image.has-bg-image {
  background-image: linear-gradient(rgba(0, 0, 0, 0.45), rgba(0, 0, 0, 0.45)), var(--section-bg) !important;
  background-size: cover !important;
  background-position: center !important;
}

/* --- Fallback page title ----------------------------------------------- */
/* The page h1 for a page whose first section did not claim it (see
   MdxWeb.Site.Pages). It wears the ordinary settings classes so it lines
   up with every other block; .pagetitle is the per-site hook. */

.pagetitle__inner h1 {
  margin: 0;
}

/* --- Hero ---------------------------------------------------------------- */

.hero__inner {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.hero__eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.875rem;
  color: var(--color-text-muted);
}

.hero--centered .hero__inner {
  align-items: center;
  text-align: center;
}

.hero--split_left .hero__inner {
  align-items: flex-start;
  text-align: left;
}

.hero--split_right .hero__inner {
  align-items: flex-end;
  text-align: right;
}

.hero--media_background {
  background-size: cover;
  background-position: center;
}

.hero--media_background .hero__inner {
  align-items: center;
  text-align: center;
}

/* --- Shared responsive image (every media-bearing section kind) -------- */

picture {
  display: block;
}

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

/* --- Hero media ----------------------------------------------------------- */

.hero__media {
  margin-bottom: 1rem;
}

/* `isolation: isolate` is load-bearing, not decoration. The media below sits
   at z-index -1 so the hero text paints over it. Without an explicit
   stacking context here, -1 escapes this element and the image is painted
   behind the nearest ancestor that has a background of its own, which makes
   it vanish entirely on any site with a page background. */
.hero--media_background {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

.hero--media_background .hero__media {
  position: absolute;
  inset: 0;
  margin: 0;
  z-index: -1;
}

.hero--media_background .hero__media picture,
.hero--media_background .hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* --- Splash page (page_type :splash) ------------------------------------
   One image, optionally a whole-page link. body is now the 100dvh flex
   column (see body{} above), so .splash (flex: 1, min-height: 0) only
   claims whatever the header/footer leave behind instead of stacking its
   own fixed 100dvh below them - that stacking is what pushed the header's
   logo below the fold on tall splash pages.

   The image/link is position: absolute so it's out of normal flow -
   same trick .hero--media_background uses (see above): an in-flow image
   sized by percentage would inflate .splash's own height right back to
   its intrinsic size before the percentage could ever cap it. Being
   absolute means .splash's flex-computed height is untouched by the
   image, so height: 100% on it is a real, non-circular cap; width: auto
   preserves aspect ratio and can run past the viewport - no cropping. */
.splash {
  position: relative;
  flex: 1;
  min-height: 0;
}

/* Visually hidden, not display:none - a screen reader and search engine
   still see the page's one heading, only sighted users don't (the image
   already carries the same message). No reusable .sr-only class exists in
   this stylesheet yet; standard clip-path technique, scoped to this one
   use rather than generalized speculatively. */
.splash__heading {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Whichever element is the direct child of .splash - the link when the
   image is linked, otherwise the image itself - is the one taken out of
   flow and centered. */
.splash__link,
.splash > .splash__image {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  height: 100%;
}

.splash__image {
  display: block;
  height: 100%;
  width: auto;
}

/* --- Rich text ------------------------------------------------------------ */

.richtext__inner {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.align-left .richtext__inner {
  text-align: left;
}

.align-center .richtext__inner {
  text-align: center;
}

blockquote {
  margin: 0;
  padding-left: 1rem;
  border-left: 3px solid var(--color-border);
  color: var(--color-text-muted);
}

/* --- Media + Text ----------------------------------------------------------- */

.mediatext__inner {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.mediatext__media,
.mediatext__content {
  flex: 1 1 0;
  min-width: 0;
}

.mediatext__eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.875rem;
  color: var(--color-text-muted);
}

@media (min-width: 48rem) {
  .mediatext--media_left .mediatext__inner,
  .mediatext--media_right .mediatext__inner {
    flex-direction: row;
    align-items: center;
    gap: 2rem;
  }

  .mediatext--media_right .mediatext__inner {
    flex-direction: row-reverse;
  }
}

/* --- Gallery ----------------------------------------------------------------- */

.gallery__inner {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: 1rem;
}

.gallery__item {
  margin: 0;
  /* White, which three of the four sites' own galleries agree on
     (chefsonly, lekker-belgisch, chocoladeverkoop): the products are
     photographed on white, so the tile gets a white plate rather than the
     page background. meynendonckx overrides this back to `none` in its own
     stylesheet. */
  background: #ffffff;
}

.gallery__item figcaption {
  margin-top: 0.5rem;
  font-size: 0.875rem;
  color: var(--color-text-muted);
}

.gallery__lightbox-opener {
  display: block;
}

/* --- Lightbox -------------------------------------------------------------------
   JS-driven only (see app.js), built on <dialog>/showModal(): native focus
   trap, native Escape-to-close, and the browser's top layer, so this can't
   repeat the site-6 stacking-context bug fixed in 3d1662ab. */

#lightbox {
  border: none;
  padding: 0;
  background: transparent;
  opacity: 0;
  transition:
    opacity 200ms ease,
    display 200ms allow-discrete,
    overlay 200ms allow-discrete;
}

#lightbox[open] {
  opacity: 1;
}

@starting-style {
  #lightbox[open] {
    opacity: 0;
  }
}

#lightbox::backdrop {
  background: rgba(0, 0, 0, 0);
  transition:
    background-color 200ms ease,
    display 200ms allow-discrete,
    overlay 200ms allow-discrete;
}

#lightbox[open]::backdrop {
  background: rgba(0, 0, 0, 0.9);
}

@starting-style {
  #lightbox[open]::backdrop {
    background: rgba(0, 0, 0, 0);
  }
}

#lightbox img {
  display: block;
  max-width: 90vw;
  max-height: 90vh;
  object-fit: contain;
  transition: opacity 150ms ease;
}

@media (prefers-reduced-motion: reduce) {
  #lightbox,
  #lightbox::backdrop,
  #lightbox img {
    transition-duration: 0.01ms;
  }
}

/* A solid dark circle, not translucent white: product photos are commonly
   shot on white backgrounds that reach the image edges, and a translucent
   white button all but disappears against them. Dark stays visible against
   both white-background product shots and the backdrop's own near-black. */
.lightbox__close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  width: 2.5rem;
  height: 2.5rem;
  border: none;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
}

.lightbox__close:hover,
.lightbox__close:focus-visible {
  background: rgba(0, 0, 0, 0.75);
}

/* --- Cards --------------------------------------------------------------------- */

.cards__intro {
  margin-bottom: 1.5rem;
}

.cards__grid {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: 1fr;
}

@media (min-width: 40rem) {
  .cards--columns_2 .cards__grid,
  .cards--columns_3 .cards__grid,
  .cards--columns_4 .cards__grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 64rem) {
  .cards--columns_3 .cards__grid {
    grid-template-columns: repeat(3, 1fr);
  }

  .cards--columns_4 .cards__grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

.card {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.card__title {
  margin: 0;
}

/* --- CTA ----------------------------------------------------------------------- */

.cta__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  text-align: center;
}

.cta--full_width {
  padding-left: 0;
  padding-right: 0;
}

.cta--media_accent {
  border-top: 3px solid var(--color-link);
  border-bottom: 3px solid var(--color-link);
}

/* --- Location ------------------------------------------------------------------ */

.location__inner {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.location__address {
  font-style: normal;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.location__address span {
  display: block;
}

.location--full_width {
  padding-left: 0;
  padding-right: 0;
}
