/**
 * Codequelle Garbe – front end styles
 *
 * Contents
 *  1. Tokens & base
 *  2. Header (non blocking overlay)
 *  3. Main menu (hamburger, sliding sidebar, backdrop)
 *  4. Quick links
 *  5. Fullscreen covers
 *  6. Cover slideshow
 *  7. Content overlays
 *  8. Gallery lightbox
 *  9. Quick link panel (opening hours)
 * 10. Consent placeholder and privacy settings
 * 11. Footer (optional helper)
 * 12. Forms (Contact Form 7)
 * 13. Scroll slides (start page)
 * 14. Curtain (start page)
 */

/* -------------------------------------------------------------------------
 * 1. Tokens & base
 * ---------------------------------------------------------------------- */

:root {
  /* Sidebar menu (hamburger). */
  --garbe-menu-bg: #083b06;
  --garbe-menu-text: #c5a77a;
  /* Hamburger icon over the page (white on the photos). */
  --garbe-nav-toggle-default: #ffffff;
  /* Quick link bars and footer. Garbe → Settings overrides these six colours
     (inline style after this file). The hover shades mix a little of the
     text colour into the background, so they follow any chosen colour. */
  --garbe-quicklinks-bg: #e7e3d6;
  --garbe-quicklinks-text: #3a3a3a;
  --garbe-quicklinks-bg-hover: color-mix(
    in srgb,
    var(--garbe-quicklinks-bg),
    var(--garbe-quicklinks-text) 12%
  );
  --garbe-quicklinks-2-bg: #000;
  --garbe-quicklinks-2-text: #fff;
  --garbe-quicklinks-2-bg-hover: color-mix(
    in srgb,
    var(--garbe-quicklinks-2-bg),
    var(--garbe-quicklinks-2-text) 12%
  );
  --garbe-footer-bg: #e7e3d6;
  --garbe-footer-text: #3a3a3a;
  /* Phones get the full width, see the media query in 3.2. */
  --garbe-menu-width: clamp(320px, 24vw, 460px);
  --garbe-header-inset: clamp(0.75rem, 1.5vw, 1.25rem);
  --garbe-admin-bar: 0px;
  --garbe-overlay-bg: rgba(255, 255, 255, 0.88);
  --garbe-overlay-scrim: rgba(38, 38, 38, 0.35);
  --garbe-overlay-close-bg: rgba(255, 255, 255, 0.92);
  --garbe-transition: 0.45s cubic-bezier(0.4, 0, 0.2, 1);
  /* The header is fixed + z-indexed, so it forms its own stacking context:
	   everything inside it (sidebar, hamburger, quick links) is painted as one
	   layer at --garbe-z-header. It therefore has to sit ABOVE the backdrop,
	   otherwise the backdrop dims the sidebar along with the page. */
  --garbe-z-backdrop: 990;
  --garbe-z-header: 1000;
  --garbe-z-menu: 1000;
  /* Inside the header: the open sidebar covers the quick link bars, which
     come later in the markup and would otherwise paint on top. */
  --garbe-z-nav-panel: 1010;
  --garbe-z-overlay: 1100;
  --garbe-z-lightbox: 1200;
  --garbe-lightbox-bg: rgba(0, 0, 0, 0.85);
  /* The dropups hang off the bottom bar, so they share its colours. */
  --garbe-dropup-bg: var(--garbe-quicklinks-2-bg);
  --garbe-dropup-text: var(--garbe-quicklinks-2-text);
  --garbe-dropup-max-width: 420px;
  --garbe-cover-button-hover-bg: #fff;
  --garbe-cover-button-hover-text: #000;
  --garbe-cover-button-wipe: 0.55s cubic-bezier(0.65, 0, 0.35, 1);
  /* Fade-in of the cover texts (like restaurantfrantzen.com). */
  --garbe-reveal-duration: 900ms;
  --garbe-reveal-distance: 24px;
}

/* The theme fonts are set centrally in theme.json (settings.custom.font:
   heading + body). Lora and Nunito were the fonts before; blocks saved back
   then still carry their preset classes / variables (e.g.
   has-lora-font-family), which core no longer generates – map them to the
   current pair. !important like core's own preset classes. */
:root {
  --wp--preset--font-family--lora: var(--wp--custom--font--heading);
  --wp--preset--font-family--nunito: var(--wp--custom--font--body);
}

.has-lora-font-family {
  font-family: var(--wp--custom--font--heading) !important;
}

.has-nunito-font-family {
  font-family: var(--wp--custom--font--body) !important;
}

html {
  /* Keeps the gutter reserved so nothing shifts while scrolling is locked. */
  scrollbar-gutter: stable;
}

/* Scroll lock used by the sidebar and the content overlays. */
html.garbe-is-locked,
html.garbe-is-locked body {
  overflow: hidden;
}

/* Hide the source groups that are only used as overlay content:
   garbe-<name>-content, also with a number from the earlier scheme. The
   class has to END in "-content" (or "-content-N"), so groups that merely
   carry a layout class like is-content-justification-center stay visible. */
.wp-block-group[class*="garbe-"]:is(
    [class$="-content"],
    [class*="-content "],
    [class*="-content-0"],
    [class*="-content-1"],
    [class*="-content-2"],
    [class*="-content-3"],
    [class*="-content-4"],
    [class*="-content-5"],
    [class*="-content-6"],
    [class*="-content-7"],
    [class*="-content-8"],
    [class*="-content-9"]
  ),
.garbe-quicklink-source {
  display: none;
}

/* -------------------------------------------------------------------------
 * 2. Header – sits on top of the content, never pushes it down
 * ---------------------------------------------------------------------- */

.garbe-header {
  position: fixed;
  top: var(--garbe-admin-bar);
  right: 0;
  left: 0;
  z-index: var(--garbe-z-header);
  display: block;
  margin: 0;
  padding: 0;
  background: none !important;
  pointer-events: none;
}

.garbe-header > * {
  pointer-events: auto;
}

body.admin-bar {
  --garbe-admin-bar: 32px;
}

@media screen and (max-width: 782px) {
  body.admin-bar {
    --garbe-admin-bar: 46px;
  }
}

/* Gutenberg gives every direct child of .wp-site-blocks a block-gap margin.
   On a section site that shows up as a white strip between the last cover and
   the footer (and above the first cover). The sections carry their own
   spacing, so the root gap is removed. */
.wp-site-blocks > * {
  margin-block-start: 0;
  margin-block-end: 0;
}

/* The template part wrapper around the header group (a <header> or a plain
   <div class="wp-block-template-part">, depending on the tagName setting)
   must not reserve any space either. */
.wp-site-blocks > header,
.wp-site-blocks > .wp-block-template-part:first-child {
  margin-block: 0;
}

.wp-site-blocks > :has(> .garbe-header) {
  height: 0;
  margin-block: 0;
  overflow: visible;
}

/* -------------------------------------------------------------------------
 * 3. Main menu
 * ---------------------------------------------------------------------- */

/* 3.1 Hamburger */

.garbe-nav-toggle {
  position: fixed;
  top: calc(var(--garbe-admin-bar) + var(--garbe-header-inset));
  left: var(--garbe-header-inset);
  z-index: var(--garbe-z-menu);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  width: 52px;
  height: 52px;
  padding: 0 12px;
  border: 0;
  background: none;
  color: var(--garbe-nav-toggle-color, var(--garbe-nav-toggle-default));
  cursor: pointer;
  transition:
    opacity 0.25s ease,
    transform 0.25s ease;
}

/* The start page (default page template) has a light background, so the
   hamburger is black there. Body class set by WordPress. */
body.page-template-default {
  --garbe-nav-toggle-color: #000;
}

.garbe-nav-toggle__bar {
  display: block;
  width: 100%;
  height: 2px;
  background: currentColor;
  border-radius: 2px;
  transition:
    transform 0.25s ease,
    opacity 0.25s ease;
}

.garbe-nav-toggle:hover .garbe-nav-toggle__bar {
  opacity: 0.75;
}

.garbe-nav-toggle:focus-visible,
.garbe-nav-close:focus-visible,
.garbe-overlay__close:focus-visible,
.garbe-slideshow__button:focus-visible,
.garbe-slideshow__dot:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 4px;
}

/* The dot buttons are 24px around an 11px dot: ring on the button edge. */
.garbe-slideshow__dots .garbe-slideshow__dot:focus-visible {
  outline-offset: 0;
}

/* While the sidebar is open the hamburger is hidden behind it anyway – fade
   it out so it never shines through on narrow screens. */
html.garbe-nav-open .garbe-nav-toggle {
  opacity: 0;
  pointer-events: none;
}

/* 3.2 Sidebar */

.garbe-nav-panel {
  position: fixed;
  top: var(--garbe-admin-bar);
  bottom: 0;
  left: 0;
  z-index: var(--garbe-z-nav-panel);
  display: flex;
  flex-direction: column;
  gap: clamp(1.5rem, 3vh, 2.75rem);
  width: var(--garbe-menu-width);
  max-width: 100%;
  margin: 0;
  padding: clamp(4rem, 8vh, 6rem) clamp(1rem, 2vw, 2rem) clamp(2rem, 6vh, 4rem);
  /* Vertical scrolling is fine, horizontal never: long words break with
     hyphenation (language from <html lang>) instead of sticking out. */
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  overflow-wrap: break-word;
  hyphens: auto;
  /* The headlines size themselves to the panel width (cqi units). */
  container-type: inline-size;
  background: var(--garbe-menu-bg);
  color: var(--garbe-menu-text);
  transform: translateX(-100%);
  transition:
    transform var(--garbe-transition),
    visibility 0s linear 0.45s;
  visibility: hidden;
}

@media (max-width: 600px) {
  :root {
    --garbe-menu-width: 100%;
  }
}

html.garbe-nav-open .garbe-nav-panel {
  transform: translateX(0);
  visibility: visible;
  transition:
    transform var(--garbe-transition),
    visibility 0s;
}

.garbe-nav-panel,
.garbe-nav-panel a,
.garbe-nav-panel h1,
.garbe-nav-panel h2,
.garbe-nav-panel h3,
.garbe-nav-panel p {
  color: var(--garbe-menu-text);
}

/* Category headlines inside the sidebar. */
.garbe-nav-panel :where(h1, h2, h3, h4, h5, h6) {
  margin: 0 0 0.75rem;
  font-size: clamp(1.35rem, 1.1rem + 0.6vw, 1.75rem);
  /* Relative to the panel, so the longest headline always fits. Measured
     width of KASTANIENGARTEN incl. letter spacing (regular weight; ~5% more
     at 600): Playfair Display 10.5em, Mulish and Cormorant Garamond 10.6em,
     Newsreader 10.9em – at 7.5cqi about 83–86% of the panel. Fraunces is 12.3em: with
     it as heading font, lower the 7.5cqi to about 6.5cqi. */
  font-size: clamp(1.1rem, 7.5cqi, 1.75rem);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-align: center;
  text-transform: uppercase;
}

/* A linked headline keeps the plain headline look – no underline from the
   global link style, and the sidebar text colour instead of the link colour. */
.garbe-nav-panel :where(h1, h2, h3, h4, h5, h6) a,
.garbe-nav-panel :where(h1, h2, h3, h4, h5, h6) a:hover,
.garbe-nav-panel :where(h1, h2, h3, h4, h5, h6) a:focus {
  color: inherit;
  text-decoration: none;
  transition: opacity 0.2s ease;
}

.garbe-nav-panel :where(h1, h2, h3, h4, h5, h6) a:hover,
.garbe-nav-panel :where(h1, h2, h3, h4, h5, h6) a:focus {
  opacity: 0.8;
}

/* Navigation blocks: always a centred vertical list, never a burger. */
.garbe-nav-panel .wp-block-navigation,
.garbe-nav-panel .wp-block-navigation__container {
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
}

.garbe-nav-panel .wp-block-navigation__responsive-container-open,
.garbe-nav-panel .wp-block-navigation__responsive-container-close {
  display: none !important;
}

/* The navigation block's own responsive/overlay container is neutralised in
   every state, so the full list is always rendered inside the sidebar. */
.garbe-nav-panel .wp-block-navigation__responsive-container,
.garbe-nav-panel .wp-block-navigation__responsive-container:not(.is-menu-open) {
  display: block !important;
  position: static !important;
  width: auto !important;
  max-width: none !important;
  height: auto !important;
  padding: 0 !important;
  overflow: visible !important;
  background: none !important;
  opacity: 1 !important;
  visibility: visible !important;
}

.garbe-nav-panel .wp-block-navigation__responsive-dialog,
.garbe-nav-panel .wp-block-navigation__responsive-container-content {
  display: block !important;
  width: 100%;
}

.garbe-nav-panel .wp-block-navigation__container > li,
.garbe-nav-panel .wp-block-navigation-item {
  display: block;
  width: 100%;
}

.garbe-nav-panel .wp-block-navigation-item__content,
.garbe-nav-panel .wp-block-navigation a {
  display: block;
  padding: 0.3rem 0.25rem;
  font-size: 0.95rem;
  letter-spacing: 0.05em;
  text-align: center;
  text-decoration: none;
  text-transform: uppercase;
  opacity: 0.92;
  transition: opacity 0.2s ease;
}

.garbe-nav-panel .wp-block-navigation a:hover,
.garbe-nav-panel .wp-block-navigation a:focus,
.garbe-nav-panel .current-menu-item > a {
  opacity: 1;
  text-decoration: underline;
  text-underline-offset: 0.3em;
}

/* Plain list markup works as well (if no navigation block is used). */
.garbe-nav-panel ul {
  margin: 0;
  padding: 0;
  list-style: none;
  text-align: center;
}

/* 3.3 Close icon – top right inside the sidebar */

.garbe-nav-close {
  position: absolute;
  top: clamp(1rem, 2vh, 1.75rem);
  right: clamp(1rem, 1.5vw, 1.5rem);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--garbe-menu-text);
  cursor: pointer;
  transition:
    transform 0.25s ease,
    opacity 0.25s ease;
}

.garbe-nav-close:hover {
  opacity: 0.75;
  transform: rotate(90deg);
}

.garbe-nav-close svg {
  width: 26px;
  height: 26px;
  display: block;
}

/* 3.4 Backdrop */

.garbe-nav-backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--garbe-z-backdrop);
  background: rgba(38, 38, 38, 0.4);
  opacity: 0;
  visibility: hidden;
  transition:
    opacity var(--garbe-transition),
    visibility 0s linear 0.45s;
}

html.garbe-nav-open .garbe-nav-backdrop {
  opacity: 1;
  visibility: visible;
  transition:
    opacity var(--garbe-transition),
    visibility 0s;
}

/* -------------------------------------------------------------------------
 * 4. Quick links
 *
 * garbe-quicklinks    – pinned to the top right
 * garbe-quicklinks-2  – pinned to the bottom right, black buttons
 *
 * The shared base matches both, so a second bar works whether it carries
 * only garbe-quicklinks-2 or both classes.
 * ---------------------------------------------------------------------- */

[class*="garbe-quicklinks"] {
  position: fixed;
  top: var(--garbe-admin-bar);
  right: var(--garbe-quicklinks-inset, 30px);
  /* Stays above the menu backdrop, as in the design draft. */
  z-index: var(--garbe-z-menu);
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  /* !important beats the layout gap Gutenberg prints for the buttons block. */
  gap: var(--garbe-quicklinks-gap, 30px) !important;
  margin: 0;
  padding: 0;
  /* Works even when the bar is nested deeper inside the header, which is
     pointer-events: none. */
  pointer-events: auto;
}

[class*="garbe-quicklinks"] .wp-block-buttons {
  gap: var(--garbe-quicklinks-gap, 30px) !important;
}

[class*="garbe-quicklinks"] .wp-block-button {
  margin: 0;
}

[class*="garbe-quicklinks"] .wp-block-button__link,
[class*="garbe-quicklinks"] > a {
  display: inline-block;
  padding: 1.05rem 1.6rem;
  border: 0;
  border-radius: 0;
  background: var(--garbe-quicklinks-bg);
  color: var(--garbe-quicklinks-text);
  font-family: var(
    --wp--custom--font--heading,
    Georgia,
    "Times New Roman",
    serif
  );
  font-size: var(--garbe-quicklinks-font-size, 1rem);
  font-weight: 600;
  letter-spacing: 0.1em;
  line-height: 1;
  text-decoration: none;
  text-transform: uppercase;
  transition: background-color 0.25s ease;
}

[class*="garbe-quicklinks"] .wp-block-button__link:hover,
[class*="garbe-quicklinks"] .wp-block-button__link:focus,
[class*="garbe-quicklinks"] > a:hover,
[class*="garbe-quicklinks"] > a:focus {
  background: var(--garbe-quicklinks-bg-hover);
  color: var(--garbe-quicklinks-text);
}

/* Keyboard focus: a ring inside the button in its text colour, so it reads
   on any background behind the bar. */
[class*="garbe-quicklinks"] .wp-block-button__link:focus-visible,
[class*="garbe-quicklinks"] > a:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: -5px;
}

.garbe-quicklinks {
  --garbe-quicklinks-font-size: 1.2rem;
}

/* 4.1 Second bar: bottom right, black buttons, smaller type.
   Declared after .garbe-quicklinks so it wins on an element that carries
   both classes. */

.garbe-quicklinks-2 {
  --garbe-quicklinks-font-size: 0.9rem;
  top: auto;
  /* Flush with the bottom edge, mirroring the top bar. */
  bottom: var(--garbe-quicklinks-2-bottom, 0px);
  right: var(--garbe-quicklinks-inset, 30px);
}

.garbe-quicklinks-2 .wp-block-button__link,
.garbe-quicklinks-2 > a {
  background: var(--garbe-quicklinks-2-bg);
  color: var(--garbe-quicklinks-2-text);
}

.garbe-quicklinks-2 .wp-block-button__link:hover,
.garbe-quicklinks-2 .wp-block-button__link:focus,
.garbe-quicklinks-2 > a:hover,
.garbe-quicklinks-2 > a:focus {
  background: var(--garbe-quicklinks-2-bg-hover);
  color: var(--garbe-quicklinks-2-text);
}

@media (max-width: 781px) {
  /* Scaled down proportionally instead of one flat size, so the two bars keep
     their size relationship on phones. */
  .garbe-quicklinks {
    --garbe-quicklinks-font-size: 0.82rem;
  }

  .garbe-quicklinks-2 {
    --garbe-quicklinks-font-size: 0.68rem;
  }

  [class*="garbe-quicklinks"] .wp-block-button__link,
  [class*="garbe-quicklinks"] > a {
    padding: 0.85rem 0.9rem;
    letter-spacing: 0.06em;
  }
}

/* 4.2 Phones: both bars become narrow stacks on the right edge – top bar top
   right, bottom bar bottom right – so they never spread over the page or the
   hamburger. Each button is as wide as its text, aligned right. */
@media (max-width: 600px) {
  /* .wp-block-buttons raises the specificity above core's .is-layout-flex
     (flex-wrap: wrap; align-items: center). */
  .wp-block-buttons[class*="garbe-quicklinks"] {
    --garbe-quicklinks-inset: 0px;
    --garbe-quicklinks-gap: 4px;
    /* Same distance from the bottom edge as between the buttons. */
    --garbe-quicklinks-2-bottom: var(--garbe-quicklinks-gap);
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: flex-end;
    max-width: calc(100% - 52px - 2 * var(--garbe-header-inset));
  }

  /* Same distance from the top edge as between the buttons. */
  .wp-block-buttons.garbe-quicklinks {
    top: calc(var(--garbe-admin-bar) + var(--garbe-quicklinks-gap));
  }

  .garbe-quicklinks {
    --garbe-quicklinks-font-size: 0.72rem;
  }

  .garbe-quicklinks-2 {
    --garbe-quicklinks-font-size: 0.62rem;
  }

  [class*="garbe-quicklinks"] .wp-block-button__link,
  [class*="garbe-quicklinks"] > a {
    padding: 0.6rem 0.75rem;
  }

  /* Partnerbetrieb goes to the bottom of its stack. */
  .garbe-quicklinks-2 .garbe-partnerbetrieb {
    order: 1;
  }
}

/* -------------------------------------------------------------------------
 * 5. Fullscreen covers
 * ---------------------------------------------------------------------- */

/* The section wrapper spans the full width. */
[class*="garbe-"][class*="-overview"] {
  width: 100%;
  max-width: none !important;
  margin-left: 0;
  margin-right: 0;
}

[class*="garbe-"][class*="-overview"] > * {
  max-width: none;
}

.wp-block-cover[class*="garbe-"][class*="-cover"] {
  position: relative;
  width: 100%;
  max-width: none !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
  /* Beats the inline min-height Gutenberg writes onto the cover block. */
  min-height: 100vh !important;
  min-height: 100svh !important;
  height: auto;
  overflow: hidden;
}

/* The admin bar shifts the document down via html{margin-top}, so for logged
   in users a full viewport cover would overshoot by its height. */
body.admin-bar .wp-block-cover[class*="garbe-"][class*="-cover"] {
  min-height: calc(100vh - var(--garbe-admin-bar)) !important;
  min-height: calc(100svh - var(--garbe-admin-bar)) !important;
}

/* Keep the cover content clear of the fixed header on small screens. */
.wp-block-cover[class*="garbe-"][class*="-cover"]
  > .wp-block-cover__inner-container {
  width: 100%;
  max-width: var(--wp--style--global--content-size, 1240px);
  padding-inline: clamp(1.25rem, 5vw, 4rem);
  padding-block: clamp(5rem, 12vh, 8rem);
}

.wp-block-cover[class*="garbe-"][class*="-cover"] .wp-block-buttons {
  margin-top: 1.75rem;
}

/* Parallax: theme.js shifts the cover text while scrolling (section 8). */
.garbe-parallax {
  will-change: transform;
}

/* Reveal: the cover texts fade in once, one by one (theme.js, section 9).
   Until theme.js has marked the elements, html.garbe-reveal-pending (set in
   <head>) keeps them hidden. Without motion preference nothing is hidden. */
@media (prefers-reduced-motion: no-preference) {
  .garbe-reveal-pending
    .wp-block-cover[class*="garbe-"][class*="-cover"]
    > .wp-block-cover__inner-container
    > * {
    opacity: 0;
  }

  .garbe-reveal {
    opacity: 0;
    transform: translate3d(0, var(--garbe-reveal-distance), 0);
    transition:
      opacity var(--garbe-reveal-duration) ease,
      transform var(--garbe-reveal-duration) ease;
    transition-delay: var(--garbe-reveal-delay, 0ms);
  }

  /* Other directions, as a class on the block in the editor. */
  .garbe-reveal.garbe-reveal--fade {
    transform: none;
  }

  .garbe-reveal.garbe-reveal--left {
    transform: translate3d(calc(-1 * var(--garbe-reveal-distance)), 0, 0);
  }

  .garbe-reveal.garbe-reveal--right {
    transform: translate3d(var(--garbe-reveal-distance), 0, 0);
  }

  .garbe-reveal.is-visible {
    opacity: 1;
    transform: none;
  }
}

/* Outline buttons on the covers ("Jetzt entdecken"): on hover and keyboard
   focus a white fill wipes in from the left, the text turns black in step.
   The fill is a background image whose width animates; background-color
   stays transparent so the global button hover colour never shows through.
   !important beats the preset text colour class (has-base-color), which
   carries !important itself. The border is set explicitly, as the outline
   style draws it in the text colour. */
.wp-block-cover[class*="garbe-"][class*="-cover"]
  .wp-block-button.is-style-outline
  > .wp-block-button__link {
  border-color: var(--garbe-cover-button-hover-bg);
  background-color: transparent;
  background-image: linear-gradient(
    var(--garbe-cover-button-hover-bg),
    var(--garbe-cover-button-hover-bg)
  );
  background-position: left center;
  background-repeat: no-repeat;
  background-size: 0% 100%;
  transition:
    background-size var(--garbe-cover-button-wipe),
    color var(--garbe-cover-button-wipe);
}

.wp-block-cover[class*="garbe-"][class*="-cover"]
  .wp-block-button.is-style-outline
  > .wp-block-button__link:is(:hover, :focus-visible) {
  background-color: transparent;
  background-size: 100% 100%;
  color: var(--garbe-cover-button-hover-text) !important;
}

@media (prefers-reduced-motion: reduce) {
  .wp-block-cover[class*="garbe-"][class*="-cover"]
    .wp-block-button.is-style-outline
    > .wp-block-button__link {
    transition-duration: 0.01ms;
  }
}

/* 5.1 Link tiles
 *
 * A cover with a link in its text becomes clickable as a whole: the link's
 * ::after is stretched over the cover. One real link per tile, so
 * middle-click, keyboard and the status bar URL work as usual.
 *
 *   garbe-link-tiles  on a wrapper (e.g. the columns) – every cover inside
 *   garbe-link-tile   on a single cover
 *
 * Core positions the cover's inner container, which would trap the stretched
 * area inside it. So the container goes static, and image + dim move below
 * the text into the tile's own stacking context (isolation + z-index -1). */

:is(.garbe-link-tile, .garbe-link-tiles .wp-block-cover) {
  isolation: isolate;
  overflow: hidden;
}

:is(.garbe-link-tile, .garbe-link-tiles .wp-block-cover)
  :is(
    .wp-block-cover__image-background,
    .wp-block-cover__video-background,
    .wp-block-cover__background
  ) {
  z-index: -1;
}

:is(.garbe-link-tile, .garbe-link-tiles .wp-block-cover)
  .wp-block-cover__inner-container {
  position: static;
}

:is(.garbe-link-tile, .garbe-link-tiles .wp-block-cover)
  .wp-block-cover__inner-container
  a {
  text-decoration: none;
}

:is(.garbe-link-tile, .garbe-link-tiles .wp-block-cover)
  .wp-block-cover__inner-container
  a::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}

:is(.garbe-link-tile, .garbe-link-tiles .wp-block-cover)
  .wp-block-cover__inner-container
  a:focus-visible {
  outline: none;
}

:is(.garbe-link-tile, .garbe-link-tiles .wp-block-cover)
  .wp-block-cover__inner-container
  a:focus-visible::after {
  outline: 2px solid #fff;
  outline-offset: -8px;
}

/* Hover: the image zooms in slowly. */
:is(.garbe-link-tile, .garbe-link-tiles .wp-block-cover)
  .wp-block-cover__image-background {
  transition: transform 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

:is(.garbe-link-tile, .garbe-link-tiles .wp-block-cover):is(
    :hover,
    :focus-within
  )
  .wp-block-cover__image-background {
  transform: scale(1.06);
}

@media (prefers-reduced-motion: reduce) {
  :is(.garbe-link-tile, .garbe-link-tiles .wp-block-cover)
    .wp-block-cover__image-background {
    transition: none;
  }
}

/* -------------------------------------------------------------------------
 * 6. Cover slideshow
 * ---------------------------------------------------------------------- */

.garbe-slideshow {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
}

.garbe-slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 0.9s ease-in-out;
  will-change: opacity;
}

.garbe-slide.is-active {
  opacity: 1;
}

.garbe-slide img,
.garbe-slide .garbe-slide__bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  margin: 0;
  object-fit: cover;
  object-position: center;
  background-position: center;
  background-size: cover;
}

.garbe-slideshow__button {
  position: absolute;
  top: 50%;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  padding: 0;
  border: 0;
  background: none;
  color: #fff;
  cursor: pointer;
  transform: translateY(-50%);
  opacity: 0.85;
  transition:
    opacity 0.2s ease,
    transform 0.2s ease;
}

.garbe-slideshow__button:hover {
  opacity: 1;
}

.garbe-slideshow__button svg {
  width: 26px;
  height: 26px;
  display: block;
}

.garbe-slideshow__button--prev {
  left: clamp(0.5rem, 1.5vw, 1.5rem);
}

.garbe-slideshow__button--next {
  right: clamp(0.5rem, 1.5vw, 1.5rem);
}

.garbe-slideshow__dots {
  position: absolute;
  bottom: clamp(1.25rem, 4vh, 2.5rem);
  left: 50%;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 0;
  transform: translateX(-50%);
}

/* 24px targets (WCAG 2.5.8), the visible dot stays 11px. */
.garbe-slideshow__dot {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  cursor: pointer;
}

.garbe-slideshow__dot::before {
  content: "";
  box-sizing: border-box;
  width: 11px;
  height: 11px;
  border: 1px solid rgba(255, 255, 255, 0.85);
  border-radius: 50%;
  transition: background-color 0.25s ease;
}

.garbe-slideshow__dot.is-active::before,
.garbe-slideshow__dot:hover::before {
  background: #fff;
}

/* Pause / play, after the dots. */
.garbe-slideshow__toggle {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  margin-left: 6px;
  padding: 0;
  border: 0;
  background: none;
  color: #fff;
  cursor: pointer;
  opacity: 0.85;
}

.garbe-slideshow__toggle:hover {
  opacity: 1;
}

.garbe-slideshow__toggle svg {
  width: 14px;
  height: 14px;
}

.garbe-slideshow__toggle:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .garbe-slide {
    transition: none;
  }
}

/* -------------------------------------------------------------------------
 * 7. Content overlays
 * ---------------------------------------------------------------------- */

/* The container must not animate its own opacity. An ancestor with
   opacity < 1 forms a backdrop root, so while the container was fading the
   scrim's backdrop-filter had nothing to sample – the blur only appeared once
   the fade had finished. Scrim and dialog now animate their own properties,
   so blur and overlay come up together. */
.garbe-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--garbe-z-overlay);
  display: flex;
  align-items: center;
  justify-content: center;
}

.garbe-overlay[hidden] {
  display: none;
}

.garbe-overlay__scrim {
  position: absolute;
  inset: 0;
  background-color: rgba(38, 38, 38, 0);
  -webkit-backdrop-filter: blur(0);
  backdrop-filter: blur(0);
  transition:
    background-color 0.3s ease,
    -webkit-backdrop-filter 0.3s ease,
    backdrop-filter 0.3s ease;
}

.garbe-overlay.is-open .garbe-overlay__scrim {
  background-color: var(--garbe-overlay-scrim);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}

/* Browsers without backdrop-filter get a stronger scrim instead. */
@supports not (
  (backdrop-filter: blur(4px)) or (-webkit-backdrop-filter: blur(4px))
) {
  .garbe-overlay.is-open .garbe-overlay__scrim {
    background-color: rgba(38, 38, 38, 0.65);
  }
}

/* Quick link overlays carry garbe-overlay--<slug> and can set their own
   --garbe-overlay-max-width (see below).

   The dialog is a fixed frame; only .garbe-overlay__body scrolls. So the
   close button, which sits in the frame, stays in the corner while a long
   overlay is scrolled. */
.garbe-overlay__dialog {
  position: relative;
  display: flex;
  flex-direction: column;
  width: min(var(--garbe-overlay-max-width, 1400px), 86vw);
  /* svh = the height with the browser bars shown. On phones plain vh is
     taller than the visible screen, which pushed the dialog's top edge –
     and its close button – behind the address bar. vh stays as fallback. */
  max-height: 84vh;
  max-height: 84svh;
  overflow: hidden;
  background: var(--garbe-overlay-bg);
  color: var(--wp--preset--color--contrast, #262626);
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.25);
  opacity: 0;
  transform: translateY(16px);
  transition:
    opacity 0.3s ease,
    transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
}

.garbe-overlay.is-open .garbe-overlay__dialog {
  opacity: 1;
  transform: translateY(0);
}

/* The scrolling part of the dialog. min-height: 0 lets it shrink below its
   content inside the flex column, which is what makes it scroll. */
.garbe-overlay__body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: clamp(2rem, 4vw, 4.5rem);
}

/* The moved group has to become visible again inside the dialog, and its own
   block padding is replaced by the body padding. */
.garbe-overlay__body > * {
  display: block !important;
  margin: 0;
  padding: 0 !important;
}

.garbe-overlay__body :where(h1, h2, h3) {
  margin-top: 0;
  padding-bottom: 0.65rem;
  border-bottom: 1px solid rgba(38, 38, 38, 0.35);
}

.garbe-overlay__body .wp-block-columns {
  gap: clamp(1.5rem, 3vw, 3rem);
  margin-top: clamp(1.5rem, 3vw, 2.75rem);
  margin-bottom: 0;
}

/* Pinned in the dialog frame (see above). The soft round background is
   invisible against the dialog, but keeps the X readable when text scrolls
   underneath. --garbe-overlay-scrollbar (set by theme.js) keeps it clear of
   a classic desktop scrollbar; overlay scrollbars on phones measure 0. */
.garbe-overlay__close {
  position: absolute;
  top: clamp(0.75rem, 1.5vw, 1.5rem);
  right: calc(
    clamp(0.75rem, 1.5vw, 1.75rem) + var(--garbe-overlay-scrollbar, 0px)
  );
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--garbe-overlay-close-bg);
  color: #262626;
  cursor: pointer;
  transition:
    transform 0.25s ease,
    opacity 0.25s ease;
}

.garbe-overlay__close:hover {
  opacity: 0.75;
  transform: rotate(90deg);
}

.garbe-overlay__close svg {
  display: block;
  width: 26px;
  height: 26px;
}

/* Table reservation: the Teburio form needs no more than this. */
.garbe-overlay--tisch-reservieren {
  --garbe-overlay-max-width: 700px;
}

@media (max-width: 781px) {
  .garbe-overlay__dialog {
    width: min(var(--garbe-overlay-max-width, 1400px), 92vw);
    max-height: 88vh;
    max-height: 88svh;
  }

  .garbe-overlay__body {
    padding: 3rem 1.5rem 2rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .garbe-overlay__scrim,
  .garbe-overlay__dialog,
  .garbe-nav-panel,
  .garbe-nav-backdrop,
  .garbe-dropup__inner {
    transition-duration: 0.01ms;
  }
}

/* -------------------------------------------------------------------------
 * 8. Gallery lightbox
 * ---------------------------------------------------------------------- */

.garbe-lightbox-trigger {
  cursor: zoom-in;
}

.garbe-lightbox-trigger:focus-visible {
  outline: 2px solid var(--garbe-menu-bg);
  outline-offset: 3px;
}

/* Sits above the content overlay, which stays open underneath. */
.garbe-lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--garbe-z-lightbox);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--garbe-lightbox-bg);
  color: #fff;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.garbe-lightbox[hidden] {
  display: none;
}

.garbe-lightbox.is-open {
  opacity: 1;
}

.garbe-lightbox__stage {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Room for the arrows left/right and the close icon/counter above. */
  padding: clamp(3.5rem, 8vh, 5rem) clamp(1rem, 7vw, 6rem);
}

.garbe-lightbox__figure {
  display: flex;
  flex-direction: column;
  align-items: center;
  max-width: 100%;
  max-height: 100%;
  margin: 0;
}

.garbe-lightbox__image {
  display: block;
  max-width: 100%;
  max-height: calc(100vh - 2 * clamp(3.5rem, 8vh, 5rem));
  max-height: calc(100svh - 2 * clamp(3.5rem, 8vh, 5rem));
  width: auto;
  height: auto;
  object-fit: contain;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
  transition: opacity 0.25s ease;
}

.garbe-lightbox.is-loading .garbe-lightbox__image {
  opacity: 0.35;
}

.garbe-lightbox__caption {
  margin-top: 0.75rem;
  font-size: 0.95rem;
  text-align: center;
  color: rgba(255, 255, 255, 0.9);
}

.garbe-lightbox__counter {
  position: absolute;
  top: clamp(1.25rem, 2.5vh, 2rem);
  left: 50%;
  font-size: 0.9rem;
  letter-spacing: 0.1em;
  color: rgba(255, 255, 255, 0.85);
  transform: translateX(-50%);
}

.garbe-lightbox__button {
  position: absolute;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  padding: 0;
  border: 0;
  background: none;
  color: #fff;
  cursor: pointer;
  opacity: 0.85;
  transition:
    opacity 0.2s ease,
    transform 0.25s ease;
}

.garbe-lightbox__button[hidden] {
  display: none;
}

.garbe-lightbox__button:hover {
  opacity: 1;
}

.garbe-lightbox__button:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 4px;
}

.garbe-lightbox__button svg {
  display: block;
  width: 26px;
  height: 26px;
}

.garbe-lightbox__close {
  top: clamp(0.75rem, 1.5vw, 1.5rem);
  right: clamp(0.75rem, 1.5vw, 1.75rem);
}

.garbe-lightbox__close:hover {
  transform: rotate(90deg);
}

.garbe-lightbox__nav {
  top: 50%;
  transform: translateY(-50%);
}

.garbe-lightbox__nav--prev {
  left: clamp(0.25rem, 1.5vw, 1.5rem);
}

.garbe-lightbox__nav--next {
  right: clamp(0.25rem, 1.5vw, 1.5rem);
}

@media (prefers-reduced-motion: reduce) {
  .garbe-lightbox,
  .garbe-lightbox__image,
  .garbe-lightbox__button {
    transition-duration: 0.01ms;
  }
}

/* -------------------------------------------------------------------------
 * 9. Quick link panel ("dropup", e.g. the opening hours)
 *
 * The panel sits on top of its button and slides up out of it: the outer
 * element clips, the inner one moves from behind the button into place.
 * ---------------------------------------------------------------------- */

.garbe-has-dropup {
  position: relative;
}

/* Right edge flush with the button; extra width extends to the left. */
.garbe-dropup {
  position: absolute;
  right: 0;
  bottom: 100%;
  min-width: 100%;
  width: max-content;
  max-width: min(var(--garbe-dropup-max-width), calc(100vw - 2rem));
  overflow: hidden;
  visibility: hidden;
  transition: visibility 0s linear 0.45s;
}

.garbe-dropup[hidden] {
  display: none;
}

/* Not enough room on the left (narrow screens): flush left instead. */
.garbe-dropup--align-left .garbe-dropup {
  right: auto;
  left: 0;
}

.garbe-has-dropup.is-open .garbe-dropup {
  visibility: visible;
  transition: visibility 0s;
}

.garbe-dropup__inner {
  position: relative;
  padding: 1.25rem 3.25rem 1.25rem 1.6rem;
  background: var(--garbe-dropup-bg);
  color: var(--garbe-dropup-text);
  font-size: 0.95rem;
  line-height: 1.6;
  text-align: left;
  transform: translateY(100%);
  transition: transform var(--garbe-transition);
}

.garbe-has-dropup.is-open .garbe-dropup__inner {
  transform: translateY(0);
}

.garbe-dropup__body > .garbe-quicklink-source {
  display: block;
}

.garbe-dropup__body :where(p, ul, ol) {
  margin: 0 0 0.6em;
}

.garbe-dropup__body :where(p, ul, ol):last-child {
  margin-bottom: 0;
}

.garbe-dropup__body :where(h1, h2, h3, h4, h5, h6) {
  margin: 0 0 0.5em;
  color: inherit;
  font-size: 1.4rem;
}

.garbe-dropup__body,
.garbe-dropup__body a {
  color: var(--garbe-dropup-text);
}

.garbe-dropup__close {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--garbe-dropup-text);
  cursor: pointer;
  transition:
    transform 0.25s ease,
    opacity 0.25s ease;
}

.garbe-dropup__close:hover {
  opacity: 0.75;
  transform: rotate(90deg);
}

.garbe-dropup__close:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

.garbe-dropup__close svg {
  display: block;
  width: 20px;
  height: 20px;
}

@media (max-width: 781px) {
  .garbe-dropup__inner {
    padding: 1rem 2.75rem 1rem 0.9rem;
    font-size: 0.85rem;
  }
}

/* -------------------------------------------------------------------------
 * 10. Consent placeholder and privacy settings
 * ---------------------------------------------------------------------- */

.garbe-consent__placeholder {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.75rem;
  padding: clamp(1.25rem, 3vw, 2rem);
  border: 1px solid var(--wp--preset--color--border, #d8d4cc);
  background: var(--wp--preset--color--muted, #f4f2ed);
  color: var(--wp--preset--color--contrast, #262626);
  text-align: left;
}

.garbe-consent__placeholder > * {
  margin: 0;
}

.garbe-consent__title {
  font-family: var(--wp--custom--font--heading, Georgia, serif);
  font-size: 1.2rem;
  font-weight: 600;
}

.garbe-consent__text {
  font-size: 0.95rem;
}

.garbe-consent__remember {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.9rem;
  cursor: pointer;
}

.garbe-consent__remember input,
.garbe-consent-settings__label input {
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--wp--preset--color--primary, #477071);
}

.garbe-consent-settings__list {
  margin: 1.5rem 0;
  padding: 0;
  list-style: none;
}

.garbe-consent-settings__item {
  padding: 1rem 0;
  border-top: 1px solid var(--wp--preset--color--border, #d8d4cc);
}

.garbe-consent-settings__item:last-child {
  border-bottom: 1px solid var(--wp--preset--color--border, #d8d4cc);
}

.garbe-consent-settings__label {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  cursor: pointer;
}

.garbe-consent-settings__description {
  margin: 0.4rem 0 0 calc(18px + 0.75rem);
  font-size: 0.95rem;
}

/* -------------------------------------------------------------------------
 * 11. Footer helper
 * ---------------------------------------------------------------------- */

.garbe-footer {
  background: var(--garbe-footer-bg);
  color: var(--garbe-footer-text);
  /* Preset font-size classes carry !important, so the footer scales its text
     by redefining the preset itself rather than fighting the utility class. */
  --wp--preset--font-size--small: 1.0625rem;
  font-size: 1.0625rem;
  line-height: 1.75;
}

.garbe-footer :where(a, h1, h2, h3, h4, h5, h6, p, li) {
  color: var(--garbe-footer-text);
}

/* Three centred columns. */
.garbe-footer .wp-block-columns {
  justify-content: center;
  gap: clamp(2rem, 5vw, 5rem);
  margin-inline: auto;
}

.garbe-footer .wp-block-column {
  flex-grow: 0;
  flex-basis: auto;
  text-align: center;
}

.garbe-footer :where(h1, h2, h3, h4, h5, h6) {
  font-size: 1.35rem;
}

@media (max-width: 781px) {
  .garbe-footer .wp-block-columns {
    gap: 2.5rem;
  }
}

.garbe-footer a {
  text-decoration: none;
}

.garbe-footer a:hover {
  text-decoration: underline;
}

/* -------------------------------------------------------------------------
 * 12. Forms (Contact Form 7)
 * 13. Scroll slides (start page)
 * 14. Curtain (start page)
 *
 * Calm, consistent layout for every CF7 form: labels above full-width
 * fields, short fields (dates, numbers) in pairs, one column in narrow
 * containers. Works with plain CF7 templates; optional <fieldset
 * class="garbe-form-group"> groups get a legend and their own grid.
 *
 * WCAG 2.2 AA: field borders 4:1 or more (#767676; 1.4.11 needs 3:1), grey
 * text 6:1, body text 13:1, error red 5.8:1 (all measured on the overlay
 * background #f3f1ee), visible focus outline, 48px high fields, errors as text
 * (not colour alone), 16px font so iOS does not zoom.
 * ---------------------------------------------------------------------- */

.wpcf7 {
  --garbe-form-text: #262626;
  --garbe-form-muted: #595959;
  --garbe-form-border: #767676;
  --garbe-form-border-hover: #262626;
  --garbe-form-bg: #fff;
  --garbe-form-focus: #000;
  --garbe-form-error: #b3261e;
  --garbe-form-gap: 1.25rem;
  container-type: inline-size;
  color: var(--garbe-form-text);
}

.wpcf7 .wpcf7-form {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--garbe-form-gap) 1.25rem;
  margin: 0;
}

/* Everything spans the full width; short fields (dates, numbers) take one
   column each and pair up in template order.

   The labels themselves are the grid items: CF7's auto-paragraphs wrap
   each label in its own <p> when the template has blank lines between
   them, and several labels in one <p> (separated by <br>) when it has not.
   Those paragraphs are dissolved with display: contents. */
.wpcf7 .wpcf7-form > *,
.wpcf7 .garbe-form-group > * {
  grid-column: 1 / -1;
  margin: 0;
}

.wpcf7 :is(.wpcf7-form, .garbe-form-group) > p:has(> label) {
  display: contents;
}

.wpcf7 :is(.wpcf7-form, .garbe-form-group) > p > br {
  display: none;
}

.wpcf7 :is(.wpcf7-form, .garbe-form-group) > p > label {
  grid-column: 1 / -1;
}

.wpcf7
  :is(.wpcf7-form, .garbe-form-group)
  > p
  > label:has(.wpcf7-date, .wpcf7-number) {
  grid-column: auto;
}

/* Optional groups: <fieldset class="garbe-form-group"><legend>…</legend> */
.wpcf7 .garbe-form-group {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--garbe-form-gap) 1.25rem;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

/* One column in narrow containers (phones, narrow layout columns). After
   the group rule, which would otherwise win. */
@container (max-width: 20rem) {
  .wpcf7 .wpcf7-form,
  .wpcf7 .garbe-form-group {
    grid-template-columns: minmax(0, 1fr);
  }
}

.wpcf7 .garbe-form-group > legend {
  width: 100%;
  margin: 0 0 var(--garbe-form-gap);
  padding: 0 0 0.5rem;
  border-bottom: 1px solid var(--garbe-form-border);
  color: var(--garbe-form-muted);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.wpcf7 .garbe-form-note {
  color: var(--garbe-form-muted);
  font-size: 0.875rem;
}

/* Labels above their field. CF7 puts a <br> between text and field. */
.wpcf7 .wpcf7-form label {
  display: block;
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1.4;
}

.wpcf7 .wpcf7-form label br {
  display: none;
}

.wpcf7 .wpcf7-form-control-wrap {
  display: block;
}

.wpcf7 .wpcf7-form label > .wpcf7-form-control-wrap {
  margin-top: 0.4rem;
}

/* Fields */
.wpcf7
  :is(
    input[type="text"],
    input[type="email"],
    input[type="tel"],
    input[type="url"],
    input[type="number"],
    input[type="date"],
    select,
    textarea
  ) {
  display: block;
  box-sizing: border-box;
  width: 100%;
  max-width: none;
  height: 3rem;
  margin: 0;
  padding: 0.65rem 0.9rem;
  border: 1px solid var(--garbe-form-border);
  border-radius: 0;
  background: var(--garbe-form-bg);
  color: var(--garbe-form-text);
  font: inherit;
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.5;
  transition:
    border-color 0.2s ease,
    box-shadow 0.2s ease;
}

.wpcf7 textarea {
  height: auto;
  min-height: 9rem;
  resize: vertical;
}

.wpcf7
  :is(
    input[type="text"],
    input[type="email"],
    input[type="tel"],
    input[type="url"],
    input[type="number"],
    input[type="date"],
    select,
    textarea
  ):hover {
  border-color: var(--garbe-form-border-hover);
}

.wpcf7
  :is(
    input[type="text"],
    input[type="email"],
    input[type="tel"],
    input[type="url"],
    input[type="number"],
    input[type="date"],
    select,
    textarea
  ):focus {
  border-color: var(--garbe-form-focus);
  outline: 2px solid var(--garbe-form-focus);
  outline-offset: 2px;
}

/* Empty date fields collapse in iOS Safari; keep their height and align
   the value left like the other fields. */
@supports (-webkit-touch-callout: none) {
  .wpcf7 input[type="date"] {
    -webkit-appearance: none;
    appearance: none;
  }
}

.wpcf7 input[type="date"]::-webkit-date-and-time-value {
  text-align: left;
}

/* Required marker: <span class="garbe-required" aria-hidden="true">*</span>
   (screen readers get aria-required from CF7 instead). */
.wpcf7 .garbe-required {
  margin-left: 0.15em;
  color: var(--garbe-form-muted);
}

/* Checkboxes and acceptance */
.wpcf7 .wpcf7-list-item {
  display: block;
  margin: 0;
}

.wpcf7 .wpcf7-list-item + .wpcf7-list-item {
  margin-top: 0.5rem;
}

.wpcf7 .wpcf7-list-item label {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  font-weight: 400;
  cursor: pointer;
}

.wpcf7 .wpcf7-list-item input[type="checkbox"],
.wpcf7 .wpcf7-list-item input[type="radio"] {
  flex: 0 0 auto;
  width: 1.25rem;
  height: 1.25rem;
  margin: 0.1rem 0 0;
  accent-color: var(--garbe-form-text);
  cursor: pointer;
}

.wpcf7 .wpcf7-list-item input:focus-visible {
  outline: 2px solid var(--garbe-form-focus);
  outline-offset: 2px;
}

.wpcf7 .wpcf7-form a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

.wpcf7 .wpcf7-form a:hover {
  text-decoration-thickness: 2px;
}

/* Arithmetic captcha (All In One WP Security) */
.wpcf7 .aiowps-captcha-equation p,
.wpcf7 .aiowps-captcha-equation strong {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 0;
  font-weight: 600;
}

.wpcf7 .aiowps-captcha-equation input.aiowps-captcha-answer {
  flex: 0 1 8rem;
  width: 8rem;
}

/* Submit */
.wpcf7 .wpcf7-form > p:has(.wpcf7-submit) {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
  margin-top: 0.5rem;
}

/* CF7 puts the captcha's wrapper into the submit row: hidden while empty,
   its error message on a line of its own above the button. */
.wpcf7 .wpcf7-form > p:has(.wpcf7-submit) > .wpcf7-form-control-wrap {
  flex-basis: 100%;
}

.wpcf7 .wpcf7-form > p:has(.wpcf7-submit) > .wpcf7-form-control-wrap:empty {
  display: none;
}

.wpcf7
  .wpcf7-form
  > p:has(.wpcf7-submit)
  > .wpcf7-form-control-wrap
  .wpcf7-not-valid-tip {
  margin-top: 0;
}

.wpcf7 .wpcf7-submit {
  min-width: 14rem;
  min-height: 3rem;
  margin: 0;
  padding: 0.85rem 2rem;
  border: 2px solid var(--garbe-form-text);
  border-radius: 0;
  background: var(--garbe-form-text);
  color: #fff;
  font: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  transition:
    background-color 0.2s ease,
    color 0.2s ease;
}

.wpcf7 .wpcf7-submit:hover {
  background: var(--garbe-form-bg);
  color: var(--garbe-form-text);
}

.wpcf7 .wpcf7-submit:focus-visible {
  outline: 2px solid var(--garbe-form-focus);
  outline-offset: 3px;
}

.wpcf7 .wpcf7-submit:disabled {
  border-color: var(--garbe-form-border);
  background: var(--garbe-form-border);
  color: #fff;
  cursor: not-allowed;
}

.wpcf7 .wpcf7-spinner {
  margin: 0;
}

@container (max-width: 20rem) {
  .wpcf7 .wpcf7-submit {
    width: 100%;
  }
}

/* Validation: message as text below the field, border as a second cue. */
.wpcf7 :is(input, select, textarea).wpcf7-not-valid {
  border-color: var(--garbe-form-error);
  box-shadow: inset 0 0 0 1px var(--garbe-form-error);
}

/* Checkbox / acceptance not ticked: outline as the visual cue. */
.wpcf7 .wpcf7-not-valid .wpcf7-list-item input {
  outline: 2px solid var(--garbe-form-error);
  outline-offset: 2px;
}

.wpcf7 .wpcf7-not-valid-tip {
  display: block;
  margin-top: 0.35rem;
  color: var(--garbe-form-error);
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.4;
}

/* Status message after sending (CF7 colours replaced, specificity above
   CF7's own ".wpcf7 form.sent .wpcf7-response-output"). */
.wpcf7 form.wpcf7-form .wpcf7-response-output {
  margin: 0;
  padding: 1rem 1.25rem;
  border: 2px solid var(--garbe-form-text);
  background: var(--garbe-form-bg);
  color: var(--garbe-form-text);
  font-weight: 600;
}

.wpcf7
  form.wpcf7-form:is(
    .invalid,
    .unaccepted,
    .payment-required,
    .failed,
    .aborted,
    .spam
  )
  .wpcf7-response-output {
  border-color: var(--garbe-form-error);
  color: var(--garbe-form-error);
}

/* -------------------------------------------------------------------------
 * 13. Scroll slides (start page)
 * 14. Curtain (start page)
 *
 * <Group class="garbe-scroll-slides"> with one Cover per slide. theme.js
 * (section 10) moves the covers into a sticky viewport and makes the group
 * as tall as all steps together; the scroll position picks the active
 * slide, which fades in over the previous one. Without JavaScript (and in
 * the editor) the covers are ordinary sections below each other.
 * ---------------------------------------------------------------------- */

.garbe-scroll-slides {
  --garbe-slide-h: calc(100vh - var(--garbe-admin-bar));
  --garbe-bar-gap: 0px;
  --garbe-slide-fade: 0.9s;
}

/* lvh = the height with the phone's address bar hidden. The slides are
   always that tall, so they never change size when the bar slides away or
   comes back (no gap, no jump). While the bar is shown it covers their
   bottom edge; --garbe-bar-gap (the bar's height, 0 on desktops) lifts the
   content and dots so they stay centred in what is visible. */
@supports (height: 100lvh) {
  .garbe-scroll-slides {
    --garbe-slide-h: calc(100lvh - var(--garbe-admin-bar));
    --garbe-bar-gap: calc(100lvh - 100svh);
  }
}

.garbe-scroll-slides.is-scroll-slides {
  position: relative;
  max-width: none !important;
  margin-block: 0 !important;
  padding: 0 !important;
  /* One step per slide, plus half a step so the last one stays a moment
     before the footer comes up. */
  height: calc((var(--garbe-slide-count) + 0.5) * var(--garbe-slide-h));
}

.garbe-scroll-slides__viewport {
  position: sticky;
  top: var(--garbe-admin-bar);
  height: var(--garbe-slide-h);
  overflow: hidden;
  isolation: isolate;
}

.garbe-scroll-slides.is-scroll-slides
  .garbe-scroll-slides__viewport
  > .wp-block-cover {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* Beats the cover's inline min-height (e.g. 1300px from the editor). */
  min-height: 100% !important;
  margin: 0 !important;
  /* Centres the content in the visible part (see --garbe-bar-gap);
     beats inline padding from the editor. */
  padding-bottom: var(--garbe-bar-gap) !important;
  opacity: 0;
  /* Not visibility:hidden – links in other slides stay reachable by
     keyboard; focusing one scrolls its slide into place (theme.js). */
  pointer-events: none;
  transition: opacity var(--garbe-slide-fade) ease;
}

.garbe-scroll-slides.is-scroll-slides
  .garbe-scroll-slides__viewport
  > .wp-block-cover.is-active {
  z-index: 1;
  opacity: 1;
  pointer-events: auto;
}

/* Leaving content fades with its slide, without the entrance delay. */
.garbe-scroll-slide:not(.is-active) .garbe-reveal {
  transition-delay: 0ms;
}

/* Snap points: every scroll gesture (wheel notch, swipe, arrow key) moves
   on by exactly one slide and comes to rest on it; the footer is the last
   stop. Opt out with the class garbe-no-snap on the group. */
html.garbe-scroll-snap {
  scroll-snap-type: y mandatory;
}

/* The footer stops at its top edge: on phones it is taller than the screen,
   and an end-aligned stop would jump straight past its first half. Inside
   a tall footer scrolling is free again. */
html.garbe-scroll-snap footer.wp-block-template-part {
  scroll-snap-align: start;
  scroll-margin-top: var(--garbe-admin-bar);
}

.garbe-scroll-slides__snap {
  position: absolute;
  top: calc(var(--garbe-slide-index) * var(--garbe-slide-h));
  left: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
  scroll-snap-align: start;
  /* No skipping slides with a fast flick. */
  scroll-snap-stop: always;
  scroll-margin-top: var(--garbe-admin-bar);
}

/* Section dots, right edge, vertically centred. 24px targets (WCAG 2.5.8),
   10px dots with a contrasting ring so they read on photos and white. */
.garbe-scroll-slides__nav {
  position: absolute;
  z-index: 2;
  top: calc(50% - var(--garbe-bar-gap) / 2);
  right: clamp(0.5rem, 2vw, 1.5rem);
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  color: #fff;
  transform: translateY(-50%);
  transition: color 0.4s ease;
}

.garbe-scroll-slides__dot {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: inherit;
  cursor: pointer;
}

.garbe-scroll-slides__dot::before {
  content: "";
  box-sizing: border-box;
  width: 10px;
  height: 10px;
  border: 1.5px solid currentColor;
  border-radius: 50%;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3);
  transition:
    background-color 0.3s ease,
    transform 0.3s ease;
}

.garbe-scroll-slides__dot:hover::before,
.garbe-scroll-slides__dot.is-active::before {
  background: currentColor;
}

.garbe-scroll-slides__dot.is-active::before {
  transform: scale(1.25);
}

.garbe-scroll-slides__dot:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 1px;
}

/* "More below" on the first slide. */
.garbe-scroll-slides__hint {
  position: absolute;
  z-index: 2;
  bottom: clamp(1rem, 4vh, 2.5rem);
  left: 50%;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  padding: 0;
  border: 0;
  background: none;
  color: #fff;
  cursor: pointer;
  transform: translateX(-50%);
  transition:
    opacity 0.4s ease,
    visibility 0.4s ease,
    color 0.4s ease;
}

.garbe-scroll-slides__hint svg {
  width: 32px;
  height: 32px;
}

.garbe-scroll-slides__hint.is-hidden {
  opacity: 0;
  visibility: hidden;
}

.garbe-scroll-slides__hint:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

/* Light slide (cover marked is-light): dark dots, hint and hamburger. */
html.garbe-slide-is-light {
  --garbe-nav-toggle-color: #262626;
}

html.garbe-slide-is-light .garbe-scroll-slides__nav,
html.garbe-slide-is-light .garbe-scroll-slides__hint {
  color: #262626;
}

html.garbe-slide-is-light .garbe-scroll-slides__dot::before {
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.6);
}

@media (prefers-reduced-motion: no-preference) {
  .garbe-scroll-slides__hint svg {
    animation: garbe-hint-bob 2.2s ease-in-out infinite;
  }
}

@keyframes garbe-hint-bob {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(6px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .garbe-scroll-slides {
    --garbe-slide-fade: 0s;
  }
}

/* Phones: the bottom quick links sit where the hint would be, and the
   text keeps clear of the dots on both sides (symmetric, so it stays
   centred). */
@media (max-width: 600px) {
  .garbe-scroll-slides__hint {
    display: none;
  }

  .garbe-scroll-slides__nav {
    right: 0.25rem;
  }

  .garbe-scroll-slides.is-scroll-slides
    .garbe-scroll-slide
    > .wp-block-cover__inner-container {
    padding-inline: 2.5rem;
  }
}

/* Intro box on the first start page slide (group with a background colour
   behind logo and welcome text): narrower than the 1240px content width.
   Two classes, so it beats the max-width WordPress gives children of
   constrained layouts. */
.wp-block-group.garbe-intro {
  box-sizing: border-box;
  width: 100%;
  max-width: var(--garbe-intro-max-width, 900px);
  margin-inline: auto !important;
  position: relative;
  top: -60px;
}

/* Sublines of the start page slides (the paragraph under "Restaurant",
   "Hotel" …): two balanced lines from tablet width on, instead of one long
   line. In em, so the width follows the fluid font size. Phones keep their
   natural wrapping. */
@media (min-width: 601px) {
  .garbe-scroll-slides .wp-block-cover__inner-container > p {
    max-width: var(--garbe-subline-max-width, 28em);
    margin-inline: auto !important;
    text-wrap: balance;
  }
}

/* -------------------------------------------------------------------------
 * 14. Curtain (start page)
 *
 * <Group class="garbe-curtain"> with two blocks: a Cover (the curtain) and
 * the stage behind it (e.g. Columns with three Covers). theme.js (section
 * 11) pins both in a sticky viewport; while the page scrolls, the curtain
 * splits in the middle and its halves slide out to the sides, following
 * --garbe-curtain-progress (0 closed … 1 open). Native scrolling, no snap.
 * ---------------------------------------------------------------------- */

.garbe-curtain {
  --garbe-slide-h: calc(100vh - var(--garbe-admin-bar));
  --garbe-bar-gap: 0px;
  /* Scroll distance for opening: about five wheel ticks. */
  --garbe-curtain-distance: 500px;
  /* The open stage stays this long before the footer comes up. */
  --garbe-curtain-hold: calc(0.2 * var(--garbe-slide-h));
}

/* Same viewport logic as the scroll slides (section 13): full height with
   the phone's address bar hidden, content lifted while it is shown. */
@supports (height: 100lvh) {
  .garbe-curtain {
    --garbe-slide-h: calc(100lvh - var(--garbe-admin-bar));
    --garbe-bar-gap: calc(100lvh - 100svh);
  }
}

.garbe-curtain.is-curtain {
  position: relative;
  max-width: none !important;
  margin-block: 0 !important;
  padding: 0 !important;
  height: calc(var(--garbe-slide-h) + var(--garbe-curtain-distance) + var(--garbe-curtain-hold));
}

.garbe-curtain__track {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: var(--garbe-curtain-distance);
  visibility: hidden;
  pointer-events: none;
}

.garbe-curtain__viewport {
  --garbe-curtain-progress: 0;
  --garbe-curtain-text: 1;
  position: sticky;
  top: var(--garbe-admin-bar);
  height: var(--garbe-slide-h);
  overflow: hidden;
  isolation: isolate;
}

/* Curtain halves: the same cover twice, each showing one half. */
.garbe-curtain.is-curtain .garbe-curtain__half {
  position: absolute;
  z-index: 2;
  inset: 0;
  width: 100%;
  height: 100%;
  min-height: 100% !important;
  margin: 0 !important;
  padding-top: 0 !important;
  padding-bottom: var(--garbe-bar-gap) !important;
  /* Smooths the steps of a mouse wheel. */
  transition: transform 0.25s ease-out;
  will-change: transform;
}

.garbe-curtain__half--left {
  clip-path: inset(0 50% 0 0);
  transform: translate3d(calc(var(--garbe-curtain-progress) * -50%), 0, 0);
}

.garbe-curtain__half--right {
  clip-path: inset(0 0 0 50%);
  transform: translate3d(calc(var(--garbe-curtain-progress) * 50%), 0, 0);
}

/* The curtain's text and logo fade out first, before the halves move
   (theme.js), so the text is never seen torn in two. */
.garbe-curtain__half > .wp-block-cover__inner-container {
  opacity: var(--garbe-curtain-text);
  transition: opacity 0.25s ease-out;
}

/* Once the halves move, clicks go to the stage; fully open, they are gone. */
.garbe-curtain__viewport.is-opening .garbe-curtain__half {
  pointer-events: none;
}

.garbe-curtain__viewport.is-open .garbe-curtain__half {
  visibility: hidden;
}

/* Stage: full viewport behind the curtain, settling from 106 % to 100 %. */
.garbe-curtain.is-curtain .garbe-curtain__stage {
  position: absolute;
  z-index: 1;
  inset: 0;
  display: flex;
  /* Core wraps columns with !important. */
  flex-wrap: nowrap !important;
  gap: 0 !important;
  width: 100%;
  max-width: none !important;
  height: 100%;
  margin: 0 !important;
  padding: 0 !important;
  transform: scale(calc(1.06 - 0.06 * var(--garbe-curtain-progress)));
  transition: transform 0.25s ease-out;
}

/* Three columns of equal width, full height. Two classes more than core's
   stacking rule for columns on small screens. */
.garbe-curtain.is-curtain .garbe-curtain__stage > .wp-block-column {
  display: flex;
  flex: 1 1 0 !important;
  min-width: 0;
  margin: 0 !important;
  padding: 0 !important;
}

/* html body: beats the full-screen min-height of section covers (also the
   admin bar variant). */
html body .garbe-curtain.is-curtain .garbe-curtain__stage .wp-block-cover {
  width: 100%;
  height: 100%;
  min-height: 0 !important;
  margin: 0 !important;
  /* Even padding, so content sits in the centre; the bottom part only
     compensates the phone's address bar. */
  padding-top: 0 !important;
  padding-bottom: var(--garbe-bar-gap) !important;
}

.garbe-curtain.is-curtain .garbe-curtain__stage .wp-block-cover__inner-container {
  padding-inline: clamp(1.25rem, 3vw, 3rem) !important;
}

.garbe-curtain .garbe-scroll-slides__hint {
  z-index: 3;
}

/* Phones and small tablets: three rows instead of three narrow columns,
   each a third of the screen, showing only the headline – centred on its
   image. Sublines are hidden; the button stays as an invisible link over
   the whole row (tap anywhere, screen readers still hear "Zum …"). */
@media (max-width: 781px) {
  .garbe-curtain.is-curtain .garbe-curtain__stage {
    flex-direction: column;
  }

  /* Static, so the button link can stretch over the whole cover; the
     headline keeps its own layer above the image. */
  .garbe-curtain.is-curtain .garbe-curtain__stage .wp-block-cover__inner-container {
    position: static;
    padding-block: 0 !important;
  }

  .garbe-curtain.is-curtain .garbe-curtain__stage h2 {
    position: relative;
    z-index: 2;
    margin: 0 !important;
    font-size: 2rem !important;
  }

  .garbe-curtain.is-curtain .garbe-curtain__stage p {
    display: none;
  }

  /* Only the bottom row sits behind the address bar. */
  html body .garbe-curtain.is-curtain .garbe-curtain__stage > .wp-block-column:not(:last-child) .wp-block-cover {
    padding-bottom: 0 !important;
  }

  .garbe-curtain.is-curtain .garbe-curtain__stage .wp-block-buttons {
    margin: 0 !important;
  }

  /* html body: beats the cover button style (outline, wipe, hover colour). */
  html body .garbe-curtain.is-curtain .garbe-curtain__stage .wp-block-cover .wp-block-button > .wp-block-button__link,
  html body .garbe-curtain.is-curtain .garbe-curtain__stage .wp-block-cover .wp-block-button > .wp-block-button__link:is(:hover, :focus-visible) {
    position: absolute;
    z-index: 3;
    inset: 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none !important;
    color: transparent !important;
    font-size: 0;
  }

  html body .garbe-curtain.is-curtain .garbe-curtain__stage .wp-block-cover .wp-block-button > .wp-block-button__link:focus-visible {
    outline: 3px solid #fff;
    outline-offset: -8px;
  }
}
/* Reduced motion: no sliding or zooming – the curtain fades instead. */
@media (prefers-reduced-motion: reduce) {
  .garbe-curtain__half--left,
  .garbe-curtain__half--right {
    clip-path: none;
    transform: none;
    opacity: calc(1 - var(--garbe-curtain-progress));
  }

  .garbe-curtain__half--right {
    display: none;
  }

  .garbe-curtain.is-curtain .garbe-curtain__stage {
    transform: none;
  }
}
