@charset "UTF-8";
/* ==========================================================================
   John’s Burger – Design-System

   Alle Marken-Farben und -Maße stehen ausschließlich hier in :root.
   Im HTML steht kein einziger Hex-Wert.

   HERKUNFT DER FARBEN
   Ein Corporate-Design-Dokument gibt es zu dieser Marke nicht. Auf Ansage des
   Kunden gilt das Logo als CD.
   Stand: Logo vom 19.08.2026, Input/logo/johns-burger-logo.png, hier
   vektorisiert. Es löst das runde Emblem ab, das bis dahin galt.

       #B64238  Rot        Tomate, führende Fläche
       #CD9D53  Gold       Brötchen hell, Akzentfläche
       #B07844  Gold 2     Brötchen beschattet, zweite Akzentfläche
       #775844  Grillbraun Patty, zweite dunkle Fläche
       #719648  Grün       Salat, Kennzeichnung vegetarisch/vegan
       #333331  Schwarz    Schriftzug
       #E6DBD1  Creme      Fläche des Aufklebers

   ROLLENWECHSEL GEGENÜBER DEM ALTEN EMBLEM
   Die Rollen sind dieselben geblieben, die Werte nicht. Rot war #C11615 und
   ist jetzt das deutlich gedämpftere Tomatenrot; Gold war ein Senfton und ist
   jetzt Brötchengold; Creme war fast weißes Gelb (#FDFAE2) und ist jetzt ein
   warmes Beige. Ofenschwarz #100F10 gibt es nicht mehr: das neue Logo bringt
   nur #333331 mit, das als Text auf Salatgrün 3,71:1 erreicht und damit als
   Systemfarbe nicht trägt. Dafür steht Schwarz Tief unten in Schicht 1b.
   Nicht übernommen wurde die Verteilung der Flächenanteile im Logo: dort ist
   Brötchengold die größte bunte Fläche und Rot die kleinste. Die Seite führt
   weiter Rot, weil Gold als große Fläche weder Weiß (2,4:1) noch den
   Fließtexton mit AAA trägt, und ein goldener Hero die ganze Seite umbauen
   würde. Das ist eine Entscheidung, keine Nachlässigkeit.

   Alles Weitere ist daraus abgeleitet und trägt unten eine Begründung.
   Ändert sich das CD, ist DIESER Block die Vergleichsgrundlage – nicht die
   einzelnen Rollen weiter unten.

   GEMESSENE KONTRASTE (WCAG 2.1, sRGB-Relativluminanz)
     Weiß         auf Rot      5,49:1   AA für Fließtext
     Schwarz Tief auf Gold     7,00:1   AA
     Weiß         auf Gold     2,40:1   DURCHGEFALLEN -> Gold trägt nie Weiß
     Schwarz      auf Gold     5,15:1   AA, aber siehe Grün
     Schwarz Tief auf Grün     5,04:1   AA
     Schwarz      auf Grün     3,71:1   DURCHGEFALLEN -> darum Schwarz Tief
     Weiß         auf Braun    6,43:1   AA
     Schwarz Tief auf Creme   12,63:1   AAA
     Rot          auf Weiß     5,49:1   AA, Rot ist auch als Textfarbe nutzbar
     Rot          auf Creme    4,03:1   DURCHGEFALLEN -> Flächen führen Creme Hell
     Rot          auf Creme H  4,73:1   AA
     Rot          auf Dunkel   3,13:1   DURCHGEFALLEN -> im Dark Mode Rot Hell
     Rot Hell     auf Dunkel   5,99:1   AA
     Creme Hell   auf Rot      4,73:1   Fokusring auf roter Fläche
     Gold         auf Dunkel   7,31:1   AA

   REGELN, DIE HIER DURCHGESETZT WERDEN
   - Gold ist Fläche, nie Textfarbe auf Hell (2,40:1 auf Weiß).
   - Grün ist Kennzeichnungsfarbe und Fläche, nie Fließtext. Als Text auf Hell
     gilt Grün Tief, auf Dunkel Grün Hell.
   - Auf Flächen steht Schwarz Tief, nicht das Logo-Schwarz. Der Unterschied
     entscheidet auf Salatgrün zwischen 3,71:1 und 5,04:1.
   - Helle Flächen führen Creme Hell, nicht die Aufkleberfläche selbst: Rot als
     Text erreicht auf dieser nur 4,03:1. Die Aufkleberfläche bleibt als
     Trennlinie im Einsatz, dort gilt kein Sollwert.
   - Rot ist im Dark Mode als Textfarbe gesperrt, dort gilt Rot Hell. Als
     FLÄCHE bleibt Rot in beiden Modi gleich, Weiß darauf hält 5,49:1.
   - Kein Muster liegt je unter Text. Das Streifenband ist Kante, nicht Grund.
   - Status nie allein über Farbe: jeder Marker trägt Symbol und Wort.

   SCHRIFT
   Zwei Familien, beide unter SIL Open Font License 1.1:

     Anton    Überschriften, Aufkleber, Bannertitel. Die Schrift des Logos,
              vom Kunden benannt. Ein einziger Schnitt, keine Achsen, keine
              Kursive.
     Archivo  Fließtext, Navigation, Knöpfe, Rubriken und die vierte
              Überschriftebene. Variable Familie über Breite (62–100) und
              Stärke (400–900).

   Bis zum 19.08.2026 trug Archivo beides: der Logoschnitt war über die
   Achsenwerte nachgebildet (Breite 68–78, Stärke 800–900, kursiv), weil der
   Name der Logoschrift nicht bekannt war. Mit Anton ist das hinfällig. Die
   kursive Fassung von Archivo ist damit ebenfalls entfallen, sie trug allein
   die geneigten Überschriften.
   Die Schriften liegen lokal unter assets/fonts/ – kein Google-Fonts-CDN.
   ========================================================================== */

/* ------------------------------------------------------------ Schriften -- */

/* Archivo, die Textschrift. Variable Familie, eine Datei je Zeichenausschnitt.
   latin und latin-ext sind getrennt, damit latin-ext nur geladen wird, wenn eine
   Seite ein Zeichen daraus braucht. */
@font-face {
  font-family: 'Archivo';
  src: url('../fonts/archivo-latin.woff2') format('woff2');
  font-weight: 400 900;
  font-stretch: 62% 100%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Archivo';
  src: url('../fonts/archivo-latin-ext.woff2') format('woff2');
  font-weight: 400 900;
  font-stretch: 62% 100%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Die kursive Fassung von Archivo ist mit dem Schriftwechsel entfallen. Sie trug
   allein die geneigten Überschriften; die stehen jetzt in Anton und aufrecht.
   Kursiv gesetzt wird auf der Seite sonst nichts: das einzige Element mit
   kursivem Vorgabewert, <address>, steht per Regel aufrecht. Kommt später ein
   <em> dazu, synthetisiert der Browser die Neigung – dann gehören die beiden
   Dateien zurück, statt die Synthese hinzunehmen. */

/* Anton, die Schrift des Logos. Auf Ansage des Kunden. Ein einziger Schnitt,
   keine Breiten- und keine Stärkeachse, keine echte Kursive: die Neigung der
   Überschriften ist deshalb synthetisch. Das ist hier richtig, denn im Logo ist
   die Neigung ebenfalls nachträglich aufgebracht und keine Schrifteigenschaft.

   Die Dateien liegen lokal unter assets/fonts/ – kein Google-Fonts-CDN.
   Lizenz: SIL Open Font License 1.1. */
@font-face {
  font-family: 'Anton';
  src: url('../fonts/anton-latin.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Anton';
  src: url('../fonts/anton-latin-ext.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* --------------------------------------------------------------- Tokens -- */

:root {
  /* Schicht 1 · Markenfarben, direkt aus dem Logo. Namen nach dem Bauteil, aus
     dem sie stammen, damit der Weg zurück zur Zeichnung erkennbar bleibt. */
  --jb-rot:         #B64238;   /* Tomatenscheibe */
  --jb-gold:        #CD9D53;   /* Brötchen, helle Hälfte */
  --jb-gold-2:      #B07844;   /* Brötchen, beschattete Hälfte */
  --jb-braun:       #775844;   /* Patty */
  --jb-gruen:       #719648;   /* Salat */
  --jb-schwarz:     #333331;   /* Schriftzug */
  --jb-creme:       #E6DBD1;   /* Fläche des Aufklebers */

  /* Schicht 1b · Abgeleitete Werte. Jeder existiert wegen einer Messung, und
     die Messung steht daneben. Hover ist Kanal ×0,80, Klickkante ×0,62. */
  --jb-schwarz-tief: #1C1B1A;  /* Logo-Schwarz trägt auf Salatgrün nur 3,71:1, dieser Ton 5,04:1 */
  --jb-creme-hell:   #F4EDE6;  /* Rot als Text auf der Aufkleberfläche nur 4,03:1, hier 4,73:1 */
  --jb-rot-hell:     #E07767;  /* Rot auf Dunkel nur 3,13:1, dieser Ton 5,99:1 */
  --jb-rot-dunkel:   #92352D;  /* Hover-Stufe der roten Fläche, Weiß darauf 7,61:1 */
  --jb-rot-tief:     #712923;  /* Klickkante unter der roten Fläche, Weiß darauf 10,29:1 */
  --jb-gruen-tief:   #55702F;  /* Grün als Text auf Hell: 3,41:1 -> 5,61:1 */
  --jb-gruen-hell:   #8FBC55;  /* Grün als Text auf Dunkel, 8,12:1 */
  --jb-gold-dunkel:  #A47E42;  /* Hover-Stufe der Goldfläche */
  --jb-gold-tief:    #7F6133;  /* Klickkante unter der Goldfläche */

  /* Schicht 2 · Semantische Rollen · Light Mode */
  --jb-bg:          #FFFFFF;
  --jb-surface:     #F4EDE6;   /* Creme Hell */
  --jb-line:        #E6DBD1;   /* die Aufkleberfläche selbst, als Trennlinie */
  --jb-border:      #847C71;   /* 3,55:1 auf der Fläche, reicht für Ränder */
  --jb-text:        #1C1B1A;
  --jb-text-muted:  #5F574F;   /* 7,09:1 auf Weiß, 6,11:1 auf der Fläche */
  --jb-brand:       #B64238;   /* Fläche */
  --jb-brand-text:  #B64238;   /* Textfarbe, 5,49:1 auf Weiß */
  --jb-on-brand:    #FFFFFF;
  --jb-accent:      #CD9D53;   /* Fläche */
  --jb-on-accent:   #1C1B1A;
  --jb-veggie:      #719648;   /* Fläche des Markers */
  --jb-veggie-text: #55702F;   /* Schrift/Icon davon */
  --jb-on-veggie:   #1C1B1A;
  --jb-dunkel:      #1C1B1A;   /* Fußzeile, Hero-Sockel */
  --jb-on-dunkel:   #F4EDE6;
  --jb-focus:       #1C1B1A;

  /* Feste Werte für Flächen, die in BEIDEN Modi gleich bleiben.
     Der rote Hero und die schwarze Fußzeile kippen nicht mit dem Modus. Stünde
     dort --jb-surface, würde die Fläche im Dark Mode dunkel und der Text darauf
     verlöre seinen gemessenen Kontrast. Gleiche Begründung wie bei der Scheibe
     unter den Produktfotos: sie ist immer Creme, weil die Fotos auf Weiß
     freigestellt sind und auf dunklem Grund einen harten Kasten zeigen würden. */
  --jb-creme-fest:  #F4EDE6;
  --jb-weiss-fest:  #FFFFFF;
  --jb-schwarz-fest:#1C1B1A;

  /* Schrift. Zwei Familien: Anton für die Überschriften, weil das Logo sie
     trägt, Archivo für alles andere. Der Rückfall ist eine schmale Grotesk,
     damit die Zeilenlänge beim Nachladen nicht springt. */
  --jb-font:         'Archivo', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --jb-font-display: 'Anton', 'Arial Narrow', 'Archivo', system-ui, sans-serif;

  /* Fließende Überschriftgrößen */
  /* Die H1 soll auf JEDER Breite zwei Zeilen haben, nie drei. Eine einzelne
     clamp schafft das nicht: ab 940 px wird der Hero zweispaltig, die Spalte
     ist dann schmaler als das Fenster, und die Schrift erreicht ihr Maximum,
     bevor die Spalte dafür breit genug ist. Bei 1024 px lief die Zeile
     deshalb auf drei um, bei 1280 px nicht. Darum drei Stufen, jede an der
     tatsächlichen Spaltenbreite gemessen (siehe Zeilenzählung). */
  --jb-h1:     clamp(2.85rem, 1.2rem + 6.4vw, 5rem);
  --jb-h2:     clamp(2rem, 1.25rem + 3.3vw, 3.2rem);
  --jb-h3:     clamp(1.5rem, 1.1rem + 1.8vw, 2.3rem);
  --jb-h4:     clamp(1.1rem, 1rem + .5vw, 1.32rem);
  --jb-rubrik: clamp(.95rem, .9rem + .3vw, 1.06rem);

  /* Textgrößen */
  --jb-text-xs: 13px;  --jb-lh-xs: 1.5;
  --jb-text-sm: 16px;  --jb-lh-sm: 1.62;
  --jb-text-md: 19px;  --jb-lh-md: 1.45;
  --jb-text-lg: 23px;  --jb-lh-lg: 1.35;

  /* Abstände · 4-px-Raster */
  --jb-space-1: 4px;   --jb-space-2: 8px;   --jb-space-3: 12px;
  --jb-space-4: 16px;  --jb-space-5: 24px;  --jb-space-6: 32px;
  --jb-space-7: 48px;  --jb-space-8: 64px;  --jb-space-9: 96px;

  /* Radien */
  --jb-radius-sm: 6px;
  --jb-radius-md: 14px;
  --jb-radius-lg: 26px;
  --jb-radius-pill: 999px;

  /* Maße */
  --jb-wrap: 1200px;
  --jb-wrap-schmal: 68ch;
  --jb-nav-hoehe: 88px;

  /* Schatten */
  --jb-schatten-sm: 0 1px 2px rgba(28, 27, 26, .07), 0 2px 8px rgba(28, 27, 26, .06);
  --jb-schatten-md: 0 2px 4px rgba(28, 27, 26, .07), 0 14px 30px rgba(28, 27, 26, .12);
  /* Zwei Schatten, die nicht in die Staffelung oben passen: einer folgt der
     freigestellten Form statt dem Bildkasten, einer sitzt unter einem Aufkleber.
     Sie standen bisher als Rohwert in ihrer Regel.

     Der Schatten der Speisen ist bewusst zurückgenommen: er soll die Motive vom
     Rot abheben, nicht selbst auffallen. Vorher lag er bei 45 Prozent Deckkraft
     und 16 px Versatz und bildete einen dunklen Sockel unter jedem Burger, der
     mit dem hellen Rest der Freistellung um Aufmerksamkeit stritt. */
  --jb-schatten-speise:  0 10px 18px rgba(28, 27, 26, .26);
  --jb-schatten-sticker: 0 4px 12px rgba(28, 27, 26, .3);
  /* Trennlinie auf der dunklen Fußzeile. Aus Creme Hell, damit sie in beiden
     Modi gleich bleibt: die Fußzeile ist immer dunkel. */
  --jb-auf-dunkel-linie: rgba(244, 237, 230, .22);

  /* Diagonalband. Ein Diner-Markisenstreifen als Kante zwischen zwei Flächen.
     Er liegt NIE unter Text – deshalb genügt hier ein Verlauf, es braucht
     keine deckende Platte darüber.

     Die Streifenbreite steht in ganzen Pixeln. Eine Bruchzahl ließe den
     Browser jede Kachel anders runden und der Takt des Musters bräche. */
  --jb-streifen:      26px;
  --jb-streifen-a:    var(--jb-rot);
  --jb-streifen-b:    var(--jb-creme-fest);
  /* Eigenes Token, weil der Hero diese Höhe von seiner eigenen abzieht: das
     Band soll im ersten Bildschirm mit erscheinen und die Kante zur nächsten
     Sektion sofort zeigen. Wird der Wert hier geändert, zieht die Hero-Höhe
     von allein nach. */
  --jb-band-hoehe:    16px;
  /* Die Kopfzeile ist --jb-nav-hoehe HOCH PLUS diese Trennlinie. Wer nur die
     Navhöhe abzieht, verschenkt genau diesen Pixel, und das Band unter dem
     Hero ragte um 1 px aus dem Bildschirm. Gemessen auf allen Auflösungen. */
  --jb-kopf-rand:     1px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --jb-bg:          #1A1614;
    --jb-surface:     #241E1B;
    --jb-line:        #3A322D;
    --jb-border:      #857C73;   /* 4,39:1 auf --jb-bg, 4,02:1 auf --jb-surface */
    --jb-text:        #F4EDE6;   /* 15,49:1 auf --jb-bg */
    --jb-text-muted:  #A9A29A;   /* 7,12:1 auf --jb-bg */
    --jb-brand:       #B64238;   /* Fläche bleibt Markenrot: Weiß darauf 5,49:1 */
    --jb-brand-text:  #E07767;   /* Rot als Text erreicht hier nur 3,13:1 */
    --jb-on-brand:    #FFFFFF;
    --jb-accent:      #CD9D53;
    --jb-on-accent:   #1C1B1A;
    --jb-veggie:      #719648;
    --jb-veggie-text: #8FBC55;   /* Grün Tief wäre auf Dunkel zu dunkel, dieser Ton 8,12:1 */
    --jb-on-veggie:   #1C1B1A;
    --jb-dunkel:      #1C1B1A;
    --jb-on-dunkel:   #F4EDE6;
    --jb-focus:       #CD9D53;   /* Logo-Schwarz wäre auf dunklem Grund unsichtbar, Gold 7,31:1 */

    --jb-schatten-sm: 0 1px 2px rgba(0, 0, 0, .55), 0 2px 8px rgba(0, 0, 0, .4);
    --jb-schatten-md: 0 2px 4px rgba(0, 0, 0, .55), 0 14px 30px rgba(0, 0, 0, .5);
  }
}

@media (min-width: 900px)  { :root { --jb-streifen: 32px; } }

/* Zweite und dritte Stufe der H1, siehe Begründung an --jb-h1. Ab 940 px teilt
   sich der Hero in zwei Spalten, ab 1200 px steht die Spaltenbreite fest, weil
   der Inhaltsrahmen dort deckelt. */
@media (min-width: 940px)  { :root { --jb-h1: clamp(3.9rem, 0.5rem + 6.2vw, 4.9rem); } }
@media (min-width: 1200px) { :root { --jb-h1: 5.5rem; } }
/* Auf hohen Fenstern darf die Überschrift größer werden, dort ist die Luft
   vorhanden: bei 1920x1080 bleiben unter der Knopfleiste knapp hundert Pixel,
   bei 1440x900 nur vierzig. Die Stufe hängt deshalb an der HÖHE, nicht an der
   Breite. Ohne sie müsste die größte Fassung sich an das engste Fenster halten
   und bliebe überall zu klein. */
@media (min-width: 1200px) and (min-height: 950px) { :root { --jb-h1: 6.6rem; } }

/* ----------------------------------------------------------------- Basis -- */

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--jb-nav-hoehe) + var(--jb-space-4));
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family: var(--jb-font);
  font-size: var(--jb-text-sm);
  line-height: var(--jb-lh-sm);
  color: var(--jb-text);
  background: var(--jb-bg);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

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

h1, h2, h3, h4, p, ul, ol, figure, table { margin: 0; }
ul, ol { padding: 0; list-style: none; }

a { color: var(--jb-brand-text); text-decoration-thickness: .08em; text-underline-offset: .18em; }
a:hover { text-decoration-thickness: .14em; }

/* Die Überschriften stehen in Anton, der Schrift des Logos: kondensiert, sehr
   fett, in Versalien. Anton hat genau einen Schnitt, deshalb steht hier weder
   font-weight noch font-stretch – beides wäre wirkungslos oder, schlimmer,
   würde den Browser zu einer synthetisch gefetteten Fassung verleiten.

   AUFRECHT, nicht geneigt. Bis zum Schriftwechsel war die H1 kursiv, das war
   ein echter Schnitt der variablen Familie. Anton hat keine Kursive; der
   Browser synthetisiert sie mit rund 14 Grad, und daneben gelegt steht der
   Schriftzug im Logo senkrecht. Zwischenwerte helfen nicht: Chrome
   synthetisiert bei `oblique 5deg` bis `11deg` gar nicht und setzt aufrecht.
   Der Kontrast zum Subhead kommt jetzt aus der Schriftfamilie selbst und
   braucht die Neigung nicht mehr. */
h1, h2, h3 {
  font-family: var(--jb-font-display);
  font-weight: 400;
  font-style: normal;
  text-transform: uppercase;
  letter-spacing: .005em;
  text-wrap: balance;
  /* Sicherheitsnetz gegen Überlauf. Die Größen wachsen mit der eingestellten
     Standardschriftgröße; bei 200 % misst „GEDRÜCKT." mehr als die Spalte auf
     einem 390-px-Gerät breit ist, und ein einzelnes Wort bricht von allein
     nicht um. Gemessen entstand dort horizontales Scrollen (519 statt 375 px).

     `anywhere` und NICHT `break-word`: beide brechen ein zu langes Wort um,
     aber nur `anywhere` senkt auch die intrinsische Mindestbreite des
     Elements. Mit `break-word` behielt das Grid-Item die volle Wortbreite als
     min-content und blähte die Seite unverändert auf. hyphens trennt vorher
     sauber nach Silben, damit `anywhere` möglichst nie greifen muss. */
  hyphens: auto;
  overflow-wrap: anywhere;
}
h1 { font-size: var(--jb-h1); line-height: 1; }
h2 { font-size: var(--jb-h2); line-height: 1.04; }
h3 { font-size: var(--jb-h3); line-height: 1.1; }
/* Die vierte Ebene bleibt bewusst im Textschnitt. Sie trägt die Gerichtsnamen
   in den Karten der Speisekarte, und ein Versalsatz in Anton macht daraus über
   siebzig schreiende Zeilen. */
h4 {
  font-family: var(--jb-font);
  font-weight: 700;
  font-stretch: 100%;
  font-style: normal;
  font-size: var(--jb-h4);
  line-height: 1.28;
  letter-spacing: -.005em;
}

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 3px solid var(--jb-focus);
  outline-offset: 2px;
  border-radius: var(--jb-radius-sm);
}

::selection { background: var(--jb-accent); color: var(--jb-on-accent); }

/* ------------------------------------------------------------ Werkzeuge -- */

.wrap {
  width: 100%;
  max-width: var(--jb-wrap);
  margin-inline: auto;
  padding-inline: var(--jb-space-5);
}

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

.sprungmarke {
  position: absolute;
  left: var(--jb-space-4);
  top: -100px;
  z-index: 100;
  padding: var(--jb-space-3) var(--jb-space-5);
  background: var(--jb-accent);
  color: var(--jb-on-accent);
  font-weight: 700;
  border-radius: var(--jb-radius-pill);
  transition: top .15s ease;
}
.sprungmarke:focus { top: var(--jb-space-4); }

/* Diagonalband als Kante zwischen zwei Flächen. Es liegt nie unter Text und
   ist rein dekorativ; ohne CSS-Verläufe bleibt schlicht eine Farbfläche. */
.band {
  height: var(--jb-band-hoehe);
  background-image: repeating-linear-gradient(
    -45deg,
    var(--jb-streifen-a) 0 var(--jb-streifen),
    var(--jb-streifen-b) var(--jb-streifen) calc(var(--jb-streifen) * 2));
}

/* --------------------------------------------------------------- Knöpfe -- */

/* Sticker-Optik: harte Kante nach unten, die beim Klick eingedrückt wird.
   Dieselbe Mechanik tragen die Bestell-Buttons der Standortkacheln. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--jb-space-2);
  font-family: var(--jb-font);
  font-weight: 700;
  font-size: var(--jb-text-sm);
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  border: 0;
  border-radius: var(--jb-radius-pill);
  padding: var(--jb-space-3) var(--jb-space-5);
  min-height: 48px;
  cursor: pointer;
  transition: transform .14s ease, background-color .14s ease, box-shadow .14s ease;
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

/* `color` wird in jedem Zustand ausgeschrieben. Das globale a:hover weiter oben
   hat mit (0,1,1) die höhere Spezifität als ein Modifier mit (0,1,0) und
   färbte den Buttontext sonst beim Überfahren um. */
.btn--primaer {
  background: var(--jb-brand);
  color: var(--jb-on-brand);
  box-shadow: 0 4px 0 var(--jb-rot-dunkel), var(--jb-schatten-sm);
}
.btn--primaer:hover {
  background: var(--jb-rot-dunkel);
  color: var(--jb-on-brand);
  box-shadow: 0 6px 0 var(--jb-rot-tief), var(--jb-schatten-md);
}
.btn--primaer:active { transform: translateY(2px); box-shadow: 0 1px 0 var(--jb-rot-tief); }

.btn--gold {
  background: var(--jb-accent);
  color: var(--jb-on-accent);
  box-shadow: 0 4px 0 var(--jb-gold-tief), var(--jb-schatten-sm);
}
.btn--gold:hover {
  background: var(--jb-gold-dunkel);
  color: var(--jb-on-accent);
  box-shadow: 0 6px 0 var(--jb-gold-tief), var(--jb-schatten-md);
}
.btn--gold:active { transform: translateY(2px); box-shadow: 0 1px 0 var(--jb-gold-tief); }

.btn--kontur {
  background: transparent;
  color: var(--jb-brand-text);
  box-shadow: inset 0 0 0 2px currentColor;
}
.btn--kontur:hover {
  background: color-mix(in srgb, var(--jb-brand) 10%, transparent);
  color: var(--jb-brand-text);
}

/* Auf der roten Fläche kehren sich die Rollen um. Hier NICHT --jb-bg nehmen:
   die rote Fläche bleibt in beiden Modi rot, --jb-bg wird im Dark Mode dunkel
   und Rot auf Dunkel ist als Textfarbe gesperrt (3,13:1). --jb-weiss-fest ist
   in beiden Modi Weiß, Rot darauf liegt konstant bei 5,49:1. */
.auf-marke .btn--primaer {
  background: var(--jb-weiss-fest);
  color: var(--jb-rot);
  box-shadow: 0 4px 0 var(--jb-rot-tief), var(--jb-schatten-sm);
}
.auf-marke .btn--primaer:hover {
  background: var(--jb-creme-fest);
  color: var(--jb-rot);
  box-shadow: 0 6px 0 var(--jb-rot-tief), var(--jb-schatten-md);
}
/* Der Konturknopf behält auf Rot eine deckende rote Fläche statt transparent.
   Optisch ist das auf dem roten Hero nicht zu unterscheiden, sichert aber zu,
   dass unter dem Label immer Rot liegt – Weiß darauf 5,49:1. Ohne sie
   entschiede die Position des Knopfes über den Kontrast. */
.auf-marke .btn--kontur {
  background: var(--jb-rot);
  color: var(--jb-weiss-fest);
  box-shadow: inset 0 0 0 2px var(--jb-weiss-fest);
}
.auf-marke .btn--kontur:hover {
  background: var(--jb-rot-dunkel);
  color: var(--jb-weiss-fest);
}

/* Fokusring auf der roten Fläche. --jb-focus ist Schwarz Tief und erreicht auf
   Rot nur 3,13:1 – WCAG 1.4.11 verlangt 3:1 für Bedienelemente, das ist zu
   knapp, um sich darauf zu verlassen. Creme Hell kommt auf 4,73:1 und ist
   gemessen, nicht geschätzt. Gold wäre mit 2,23:1 durchgefallen; Fokusfarben
   gehören je Marke gegen ihre Fläche gemessen. */
.auf-marke :focus-visible { outline-color: var(--jb-creme-fest); }
/* Auf der dunklen Fußzeile trägt Gold mit 7,00:1. */
.fuss :focus-visible { outline-color: var(--jb-accent); }

.btn--klein { min-height: 40px; padding: var(--jb-space-2) var(--jb-space-4); font-size: var(--jb-text-xs); }
.btn--gross { min-height: 56px; padding: var(--jb-space-4) var(--jb-space-7); font-size: var(--jb-text-md); }
.btn__icon { width: 20px; height: 20px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* Ein Bestell-Shop ohne Ziel. Fläche, Schrift und Lift werden im :hover
   ausdrücklich festgeschrieben: .btn[disabled] und .btn--wolt:hover haben
   dieselbe Spezifität (0,2,0), sonst entschiede allein die Reihenfolge in der
   Datei. Ein Button, den man nicht drücken kann, reagiert nicht. */
.btn[disabled] {
  background: var(--jb-line);
  color: var(--jb-text-muted);
  box-shadow: none;
  cursor: not-allowed;
}
.btn[disabled]:hover {
  background: var(--jb-line);
  color: var(--jb-text-muted);
  transform: none;
  box-shadow: none;
}

/* Bestell-Buttons je Shop.
   Wolt und Lieferando sind fremde Marken und tragen bei JEDER Kettenmarke
   dieselben Werte; der eigene Shop ist die Marke selbst und kommt aus dem CD.
   Reihenfolge auf der Kachel setzt SHOPS in standorte.js, nicht diese Datei. */
:root {
  /* Wolt: aus Wolts eigenen Design-Tokens (--base-color-brand-wolt-40/50/60).
     Der in Kundentabellen kursierende Wert #009de0 ist NICHT Wolts Blau und
     kommt auf wolt.com nirgends vor – nicht zurückändern. */
  --jb-wolt:            #00c2e8;
  --jb-wolt-dunkel:     #00a9cc;
  --jb-wolt-tief:       #0091af;
  --jb-lieferando:      #ff8000;
  --jb-lieferando-dunkel: #cc6600;
  --jb-lieferando-tief: #9e4f00;
  /* Eigener Shop: die Marke selbst. Rot aus dem CD, die beiden dunkleren
     Stufen sind daraus gerechnet (×0,80 und ×0,62). */
  --jb-shop:            #B64238;
  --jb-shop-dunkel:     #92352D;
  --jb-shop-tief:       #712923;

  /* BEWUSSTE UNTERSCHREITUNG, gemessen mit voller Absicht übernommen:
     Weiß erreicht auf #00c2e8 nur 2,13:1 und auf #ff8000 nur 2,52:1 und
     verfehlt AA deutlich. Beide Plattformen treten auf ihren eigenen Seiten
     genauso auf; die Wiedererkennbarkeit der fremden Marke wiegt hier
     schwerer. Nur der eigene Shop trägt Weiß sauber (5,49:1). Das ist kein
     Versehen – nicht auf dunkle Schrift „reparieren". */
}

.btn--wolt { background: var(--jb-wolt); color: var(--jb-weiss-fest); box-shadow: 0 4px 0 var(--jb-wolt-dunkel), var(--jb-schatten-sm); }
.btn--wolt:hover { background: var(--jb-wolt-dunkel); color: var(--jb-weiss-fest); box-shadow: 0 6px 0 var(--jb-wolt-tief), var(--jb-schatten-md); }
.btn--wolt:active { transform: translateY(2px); box-shadow: 0 1px 0 var(--jb-wolt-tief); }

.btn--lieferando { background: var(--jb-lieferando); color: var(--jb-weiss-fest); box-shadow: 0 4px 0 var(--jb-lieferando-dunkel), var(--jb-schatten-sm); }
.btn--lieferando:hover { background: var(--jb-lieferando-dunkel); color: var(--jb-weiss-fest); box-shadow: 0 6px 0 var(--jb-lieferando-tief), var(--jb-schatten-md); }
.btn--lieferando:active { transform: translateY(2px); box-shadow: 0 1px 0 var(--jb-lieferando-tief); }

.btn--eigener-shop { background: var(--jb-shop); color: var(--jb-weiss-fest); box-shadow: 0 4px 0 var(--jb-shop-dunkel), var(--jb-schatten-sm); }
.btn--eigener-shop:hover { background: var(--jb-shop-dunkel); color: var(--jb-weiss-fest); box-shadow: 0 6px 0 var(--jb-shop-tief), var(--jb-schatten-md); }
.btn--eigener-shop:active { transform: translateY(2px); box-shadow: 0 1px 0 var(--jb-shop-tief); }

/* ----------------------------------------------------------- Navigation -- */

.kopf {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--jb-bg);
  border-bottom: 1px solid var(--jb-line);
  transition: box-shadow .18s ease;
}
.kopf--kompakt { box-shadow: var(--jb-schatten-sm); }

.kopf__inner {
  display: flex;
  align-items: center;
  gap: var(--jb-space-4);
  min-height: var(--jb-nav-hoehe);
}

/* Die Kopfzeile trägt in JEDEM Scrollzustand dasselbe Logo. Kein Wechsel beim
   Scrollen: das drehte nur die Farben um und wirkte wie ein Fehler.

   Hier steht die Querfassung, nicht der ganze Aufkleber. Dessen Schriftzug
   steht zweizeilig unter dem Burger und misst bei 52 px Bauhöhe rund 9 px je
   Zeile – unlesbar. Die Querfassung stellt Burger und Wortmarke nebeneinander
   und hält den Namen dadurch auf lesbarer Größe. Der ganze Aufkleber steht
   dafür groß in der Sektion „Über uns".

   EINE Datei für beide Modi, keine helle Zweitfassung: Burger und Schriftzug
   sitzen je auf einem cremefarbenen Aufkleber, der sich auf hellem wie auf
   dunklem Grund selbst trägt. Ein heller Schriftzug stünde auf seinem eigenen
   Rand und verschwände darin. */
.kopf__logo { display: flex; align-items: center; flex: none; }
.kopf__logo img { display: block; height: 55px; width: auto; }

.kopf__nav { margin-left: auto; }
.kopf__nav ul { display: flex; align-items: center; gap: var(--jb-space-1); }
.kopf__nav a {
  display: block;
  padding: var(--jb-space-2) var(--jb-space-3);
  color: var(--jb-text);
  text-decoration: none;
  font-weight: 600;
  border-radius: var(--jb-radius-pill);
}
.kopf__nav a:hover { background: var(--jb-surface); color: var(--jb-brand-text); }
.kopf__nav a[aria-current='true'] { color: var(--jb-brand-text); }

.kopf__cta { flex: none; }

.kopf__schalter {
  display: none;
  margin-left: auto;
  align-items: center;
  gap: var(--jb-space-2);
  background: transparent;
  border: 2px solid var(--jb-line);
  border-radius: var(--jb-radius-pill);
  padding: var(--jb-space-2) var(--jb-space-3);
  min-height: 44px;
  font: inherit;
  font-weight: 700;
  color: var(--jb-text);
  cursor: pointer;
}
.kopf__schalter svg { width: 22px; height: 22px; stroke: currentColor; stroke-width: 2; fill: none; stroke-linecap: round; }

@media (max-width: 900px) {
  /* Auf dem Handy darf die Leiste nicht ein Viertel des Bildschirms fressen.
     Das Lockup geht auf 40 px Höhe herunter; darin misst die Wortmarke noch
     17 px, das trägt. Weiter schrumpfen ginge nur ohne Wortmarke. */
  :root { --jb-nav-hoehe: 68px; }
  .kopf__logo img { height: 42px; }

  .kopf__schalter { display: inline-flex; }
  .kopf__nav {
    display: none;
    position: absolute;
    left: 0; right: 0;
    top: 100%;
    background: var(--jb-bg);
    border-bottom: 1px solid var(--jb-line);
    box-shadow: var(--jb-schatten-md);
    padding: var(--jb-space-3) var(--jb-space-5) var(--jb-space-5);
  }
  .kopf__nav[data-offen='true'] { display: block; }
  .kopf__nav ul { flex-direction: column; align-items: stretch; gap: 0; }
  .kopf__nav a { padding: var(--jb-space-4) var(--jb-space-3); border-radius: var(--jb-radius-md); }
  .kopf__nav li + li { border-top: 1px solid var(--jb-line); }
  .kopf__cta { display: none; }
}

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

/* Der Hero ist eine einfarbige rote Fläche. Kein Muster darunter: jeder Text
   hier steht auf reinem Rot und hält damit durchgehend 5,49:1 – unabhängig
   davon, wo eine Zeile umbricht und wie groß der Besucher die Schrift stellt.
   Ein gemustertes Feld müsste je Feld gemessen werden und bräuchte eine
   deckende Platte unter dem Text. Die ist hier schlicht nicht nötig. */
/* Der Hero füllt genau einen Bildschirm abzüglich der Kopfzeile. Damit steht
   der CTA ohne Scrollen im Blick: das ist der Zweck der ganzen Sektion.

   svh statt vh: auf dem Handy zählt vh die Fläche OHNE eingeblendete
   Browserleiste, der Hero wäre beim Laden also höher als der sichtbare
   Bereich und die Knöpfe lägen darunter. svh nimmt den kleinen Zustand, also
   den mit Leiste, und passt in beiden Fällen. Die vh-Zeile davor ist der
   Rückfall für Browser ohne svh.

   Kein feste Höhe, sondern min-height: wächst der Inhalt (200 % Schriftgröße),
   darf die Sektion mitwachsen, statt den Text abzuschneiden. */
.hero {
  position: relative;
  background: var(--jb-rot);
  color: var(--jb-weiss-fest);
  /* Kopfzeile UND Streifenband abziehen: das Band ist die Kante zum nächsten
     Abschnitt und soll im ersten Bildschirm mitkommen. Nähme der Hero die
     volle Resthöhe, läge es exakt einen Pixel darunter und der Besucher sähe
     eine randlos abgeschnittene Fläche. */
  min-height: calc(100vh - var(--jb-nav-hoehe) - var(--jb-kopf-rand) - var(--jb-band-hoehe));
  min-height: calc(100svh - var(--jb-nav-hoehe) - var(--jb-kopf-rand) - var(--jb-band-hoehe));
  display: grid;
  align-content: center;
  padding-block: clamp(var(--jb-space-5), 3vh, var(--jb-space-7));
  overflow: hidden;
}

/* Der Text steht mittig ÜBER der Bildreihe, nicht daneben. Dadurch bekommen
   die Speisen die volle Breite und werden zum Blickfang, statt eine halbe
   Spalte zu füllen. */
.hero__text {
  /* Schmaler als der Lesetext-Rahmen sonst. Die H1 bricht nach „BURGER," um und
     fuellte in 46rem nur 73 Prozent der Zeile; sie wirkte dadurch kleiner, als
     sie ist. In 41rem sind es 87 Prozent, ohne dass die Schrift wachsen muss
     und Hoehe kostet. */
  max-width: 41rem;
  margin-inline: auto;
  text-align: center;
}

.hero__rubrik {
  font-weight: 700;
  font-stretch: 100%;
  font-size: var(--jb-rubrik);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--jb-creme-fest);
  margin-bottom: var(--jb-space-3);
}
/* Die Rubrik stand bis zum Logowechsel in Gold, mit der Begründung, sie sei nur
   Zier. Das trug nicht: „Smash & Classic" nennt die beiden Patty-Arten, um die
   sich die ganze Seite dreht, und ist damit Information. Gold auf dem neuen Rot
   liegt bei 2,23:1 (auf dem alten bei 2,42:1) und fällt in beiden Fällen durch.
   Creme Hell hält 4,73:1 und behält den warmen Ton. */

/* Die H1 braucht keinen eigenen Schnitt mehr: Anton hat nur einen, und der ist
   bereits der des Logos. Der Kontrast zum Subhead darunter kommt jetzt aus der
   Schriftfamilie selbst, nicht mehr aus Achsenwerten derselben Familie. */
.hero h1 {
  /* Mehr Luft als vorher: Anton hat eine sehr große Versalhöhe und praktisch
     keine Unterlängen, dadurch rückte der Subhead optisch an die Grundlinie
     heran. Vier Pixel reichten beim alten Schnitt, hier nicht mehr. Zwölf waren
     zu viel: bei 414x736 schob das den Hero um einen Pixel über seine Höhe und
     das Streifenband aus dem Bildschirm. Gemessen, nicht geschätzt. */
  margin-bottom: var(--jb-space-2);
}

/* Der Subhead steht bewusst am ANDEREN Ende derselben Familie: normale
   Laufweite, normales Gewicht, aufrecht, gemischte Schreibung. Vier Merkmale
   gegenläufig, damit die beiden Zeilen nicht wie zwei Größen derselben Sache
   wirken. Vorher stand hier ein zweiter Display-Satz, der sich von der H1 nur
   durch die Schriftgröße unterschied und dadurch mit ihr konkurrierte. */
.hero__lead {
  font-stretch: 100%;
  font-weight: 400;
  font-style: normal;
  text-transform: none;
  font-size: var(--jb-text-md);
  line-height: 1.55;
  max-width: 46ch;
  margin-inline: auto;
  color: var(--jb-weiss-fest);
}
/* Der hervorgehobene Begriff bleibt in der Textfarbe: Gold käme auf Rot nur
   auf 2,23:1. Das Gewicht allein trägt die Betonung. */
.hero__lead strong { font-weight: 700; color: inherit; }

.hero__aktionen {
  display: flex;
  flex-wrap: wrap;
  gap: var(--jb-space-4);
  justify-content: center;
  /* Abstand zur Bildreihe. Ohne ihn lagen die Knöpfe auf den äußeren Burgern:
     die Reihe richtet ihre Motive unten aus, die Knöpfe folgen unmittelbar.
     Der Wert steht in vh, nicht in vw: er zehrt von der Höhe des Hero, und die
     entscheidet darüber, ob die Knöpfe über der Falz bleiben. Über vw gerechnet
     war er auf breiten, mittelhohen Fenstern am größten – also genau dort, wo
     am wenigsten Platz ist. Die neun Pixel, die die Burger nach unten schweben,
     sind hier untergebracht. */
  margin-top: clamp(var(--jb-space-4), 3.4vh, var(--jb-space-6));
}

/* --------------------------------------------------- Bildbühne im Hero -- */

/* Drei freigestellte Burger nebeneinander, der mittlere größer und vorn. Die
   Reihe ist der Blickfang des Hero, nicht eine Beigabe neben dem Text.

   - Die Motive sind vom weißen Fotogrund freigestellt (Alphakanal im WebP),
     stehen also direkt auf dem Rot. Mit entfernt ist auch das weiße Geschirr,
     auf dem das Essen stand: sein Rand wäre sonst als heller Streifen unter
     jedem Burger stehengeblieben und hätte nach schlechter Freistellung
     ausgesehen.
   - Nichts bewegt sich von allein. Damit entfällt WCAG 2.2.2 samt
     Anhalteschalter: es gibt keinen Automatismus, der anzuhalten wäre.
   - Alle drei tragen echte Alt-Texte. Der Umweg über aria-hidden plus
     Namenszeile war nur nötig, solange alle vier Sekunden ein neues Bild
     vorgelesen worden wäre. */
.hero__reihe {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  /* Der Abstand muss den AUFKLEBER freistellen, nicht den Burger: der sitzt mit
     top: -.6em über der Bildkante und ragt je nach Schriftgröße 12 bis 20 px
     nach oben. Vom gemessenen Abstand blieb deshalb kaum die Hälfte übrig, und
     Text und Bild klebten aneinander. */
  margin-top: clamp(var(--jb-space-6), 5vh, var(--jb-space-9));
}

.hero__platz {
  flex: 0 1 auto;
  min-width: 0;
}
/* Die äußeren rücken unter den mittleren. Negative Ränder statt eines
   negativen gap, den es nicht gibt.

   Der Wert steht in vh, NICHT in Prozent: ein prozentualer Rand bezieht sich
   auf die Breite des Elternelements, die Motive werden aber über die Höhe
   bemessen. Sobald sie auf flachen Fenstern kleiner wurden, blieb der Versatz
   gleich groß und verschluckte den linken Burger fast vollständig hinter dem
   mittleren. In vh skaliert er mit den Bildern mit. */
.hero__platz--links  { margin-right: -4vh; z-index: 1; }
.hero__platz--rechts { margin-left: -4vh;  z-index: 1; }
.hero__platz--mitte  { z-index: 2; }

.hero__gericht {
  position: relative;
  display: block;
}

.hero__speise {
  display: block;
  width: auto;
  height: 100%;
  /* drop-shadow statt box-shadow: der Schatten folgt der freigestellten Form.
     Ein box-shadow läge am rechteckigen Bildkasten und schwebte sichtbar
     neben dem Motiv. */
  filter: drop-shadow(var(--jb-schatten-speise));
}

/* Die Motive werden über die HÖHE bemessen, nicht über die Breite: der Hero
   soll auf einen Bildschirm passen, und begrenzt wird er von der Höhe. Über
   die Breite gesteuert wuchsen die Burger auf breiten, flachen Fenstern so
   weit, dass die Knöpfe unter die Falz rutschten.

   Nebeneffekt, der hier erwünscht ist: die drei Fotos haben verschiedene
   Seitenverhältnisse, über eine gemeinsame Höhe stehen sie sauber auf einer
   Linie statt unterschiedlich hoch. */
.hero__platz--links  .hero__gericht { height: clamp(130px, 24vh, 275px); }
.hero__platz--rechts .hero__gericht { height: clamp(130px, 24vh, 275px); }
.hero__platz--mitte  .hero__gericht { height: clamp(175px, 33vh, 365px); }

/* Beschriftung als Aufkleber. Fläche Creme Hell, Schrift Schwarz Tief: 14,83:1.
   Die Goldvariante trägt dieselbe Schriftfarbe und kommt auf 7,00:1. Weiß
   wäre auf Gold mit 2,46:1 durchgefallen, deshalb steht hier nie Weiß.

   Die Drehung steht als eigene Variable, nicht direkt im transform: die
   Intro-Animation setzt transform ebenfalls und müsste die Drehung sonst in
   jedem Keyframe je Variante wiederholen. */
.hero__sticker {
  --dreh: -3deg;
  position: absolute;
  left: 50%;
  top: -.6em;
  z-index: 3;
  padding: .3em .85em .35em;
  background: var(--jb-creme-fest);
  color: var(--jb-schwarz-fest);
  font-family: var(--jb-font-display);
  font-weight: 400;
  font-style: normal;
  text-transform: uppercase;
  font-size: clamp(.82rem, .5rem + .9vw, 1.35rem);
  line-height: 1.1;
  white-space: nowrap;
  border-radius: var(--jb-radius-sm);
  box-shadow: var(--jb-schatten-sticker);
  transform: translateX(-50%) rotate(var(--dreh));
}
.hero__sticker--gold {
  --dreh: 2.5deg;
  background: var(--jb-gold);
}

/* ------------------------------------------------- Intro und Bewegung -- */

/* Grundsatz: OHNE Animation ist alles sichtbar. Die Startzustände stehen
   ausschließlich in den Keyframes, nie als Basisregel. Liefe die Animation
   nicht (abgeschaltete Bewegung, alter Browser, Fehler), bliebe der Hero
   sonst leer. Deshalb greift der ganze Block nur bei ausdrücklich erlaubter
   Bewegung. */
@media (prefers-reduced-motion: no-preference) {
  .hero__text > * {
    animation: jb-auf .55s ease-out backwards;
  }
  .hero__rubrik { animation-delay: .05s; }
  .hero h1      { animation-delay: .12s; }
  .hero__lead   { animation-delay: .22s; }

  /* Die Burger kommen von unten herein, der mittlere zuerst: er ist der
     Blickfang, die äußeren rahmen ihn danach. */
  .hero__platz {
    animation: jb-burger-rein .75s cubic-bezier(.22, .9, .28, 1.06) backwards;
  }
  .hero__platz--mitte  { animation-delay: .30s; }
  .hero__platz--links  { animation-delay: .46s; }
  .hero__platz--rechts { animation-delay: .58s; }

  /* Die Aufkleber erscheinen, wenn ihr Burger STEHT, nicht währenddessen.
     Der mittlere Burger ist bei 0,30 s + 0,75 s = 1,05 s fertig, die
     Verzögerungen liegen danach.

     NUR Deckkraft, keine Größen- oder Lageänderung. Zwei Anläufe mit Maßstab
     sind als Sprung wahrgenommen worden: gemessen ging die Deckkraft in einem
     einzigen Bildschritt von 0,14 auf 0,41 und die Breite gleichzeitig um
     4,4 px, weil die Kurve vorne steil ist. Ohne Transform kann nichts mehr
     springen, es bleibt ein ruhiges Aufblenden. Deshalb auch eine gleichmäßige
     Kurve statt einer beschleunigenden. */
  .hero__sticker {
    animation: jb-sticker-auf .6s cubic-bezier(.4, 0, .2, 1) backwards;
  }
  .hero__platz--mitte  .hero__sticker { animation-delay: .95s; }
  .hero__platz--links  .hero__sticker { animation-delay: 1.05s; }
  .hero__platz--rechts .hero__sticker { animation-delay: 1.15s; }

  .hero__aktionen {
    animation: jb-auf .55s ease-out .68s backwards;
  }

  /* Nach dem Intro schweben die Burger weiter, damit der Hero nicht erstarrt.
     Die Dauerbewegung sitzt auf .hero__gericht, das Intro auf .hero__platz:
     zwei Ebenen, weil beide `transform` setzen und sich auf demselben Element
     gegenseitig überschrieben.

     Verschiedene Dauern und Verzögerungen je Burger, sonst wippen alle drei im
     Gleichschritt und es sieht mechanisch aus. Der Versatz ist bewusst kein
     Vielfaches der Dauer, damit sie nicht wieder zusammenlaufen.

     Das Schweben setzt erst ein, wenn auch der letzte Aufkleber steht
     (1,15 s + 0,6 s = 1,75 s), sonst überlagern sich Einblenden und Bewegung
     und der Aufkleber wirkt unruhig. */
  .hero__gericht {
    animation: jb-schweben 5.5s ease-in-out 1.8s infinite alternate;
  }
  .hero__platz--links  .hero__gericht { animation-duration: 6.4s; animation-delay: 2.05s; }
  .hero__platz--rechts .hero__gericht { animation-duration: 7.1s; animation-delay: 2.25s; }
}

@keyframes jb-auf {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

@keyframes jb-burger-rein {
  from { opacity: 0; transform: translateY(46px) scale(.92); }
  to   { opacity: 1; transform: none; }
}

/* Kein transform in diesen Keyframes: der Aufkleber trägt seine Drehung aus
   der Basisregel, und die soll die Animation nicht anfassen. Würde hier ein
   transform stehen, müsste es die Drehung wiederholen (dafür gäbe es die
   Variable --dreh) und jede Größenänderung wäre wieder als Ruck sichtbar. */
@keyframes jb-sticker-auf {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Sehr kleine Auslenkung: die Burger sollen atmen, nicht wackeln. Bei mehr als
   rund zehn Pixeln zieht die Bewegung den Blick vom Text und vom CTA ab.

   Die Bewegung geht nach UNTEN, weg vom Text. Vorher lief sie nach oben: der
   Abstand zum Subhead war damit im Ruhezustand am größten und schrumpfte
   während der halben Laufzeit um neun Pixel, und weil der Aufkleber ohnehin
   über den Burger hinausragt, klebten Text und Bild am oberen Umkehrpunkt
   zusammen. Nach unten hin ist der Ruheabstand der kleinste, den es je gibt,
   und der lässt sich einmal messen. Unten ist Platz: dort folgt die Knopfleiste
   mit ihrem eigenen Abstand. */
@keyframes jb-schweben {
  from { transform: translateY(0); }
  to   { transform: translateY(9px); }
}

/* KEIN Hover-Effekt auf den Burgern. Ein Element, das auf den Zeiger
   reagiert, verspricht eine Aktion; die Bilder im Hero führen aber nirgendwo
   hin. Die Belebung übernimmt das Schweben oben, das ohne Zutun läuft. */

/* Unter 700 px stünden drei Burger so eng, dass von den äußeren nur noch
   Ränder zu sehen wären und die Aufkleber sich überlagerten. Dort bleibt der
   mittlere allein und füllt die Breite. */
@media (max-width: 700px) {
  .hero__platz--links,
  .hero__platz--rechts { display: none; }
  /* Auf dem Handy können BEIDE Richtungen begrenzen: ein schmales hohes Fenster
     über die Breite, ein schmales flaches über die Höhe. Deshalb hier weder
     height noch width fest, sondern zwei Obergrenzen auf dem Bild selbst. Es
     skaliert proportional und stößt an die zuerst erreichte Grenze.

     Vorher standen height auf der figure und width:100% auf dem Bild; zusammen
     mit den Höhenstufen weiter unten stauchte das die Motive, statt sie zu
     verkleinern. */
  .hero__platz--mitte .hero__gericht { height: auto; width: auto; }
  .hero__platz--mitte .hero__speise {
    width: auto;
    height: auto;
    max-width: min(400px, 82vw);
    /* 30 statt 34 vh: auf dem Handy steht nur dieses eine Motiv, und die vier
       Prozentpunkte gehen an den Abstand zum Text darüber. Der war die
       Beanstandung, nicht die Bildgröße. */
    max-height: 30vh;
  }
  .hero__sticker { font-size: clamp(1rem, .6rem + 2.2vw, 1.35rem); }
}

/* FLACHE FENSTER, erste Stufe. Bei 1366x768 und 1440x810 passte der Inhalt
   nicht mehr in die vorgesehene Höhe: der Hero wuchs über seine min-height
   hinaus und schob das Streifenband aus dem Bildschirm. Betroffen sind gerade
   die breiten Fenster, weil dort die größte H1-Stufe greift.

   Hier reicht es, Überschrift und Bildhöhe etwas zurückzunehmen. */
@media (max-height: 820px) {
  /* Die flache Stufe nahm die Überschrift auf 56 px zurück; sie füllte damit
     nur die halbe Zeile und wirkte klein, obwohl unter der Knopfleiste noch
     hundert Pixel frei waren. Größer, und die Spalte enger, damit die zwei
     Zeilen ihre Breite auch ausnutzen. */
  .hero h1 { font-size: clamp(2.6rem, 1rem + 4.6vw, 4.6rem); }
  .hero__text { max-width: 32rem; }
  .hero__reihe { margin-top: clamp(var(--jb-space-5), 5vh, var(--jb-space-8)); }
  .hero__aktionen { margin-top: clamp(var(--jb-space-3), 2.4vh, var(--jb-space-5)); }
  .hero__platz--mitte  .hero__gericht { height: clamp(150px, 27vh, 290px); }
  .hero__platz--links  .hero__gericht,
  .hero__platz--rechts .hero__gericht { height: clamp(115px, 20vh, 225px); }
}
@media (max-height: 820px) and (max-width: 700px) {
  /* Die Höhenstufe darüber setzt eine feste height auf die Hülle, das Bild
     behält aber seine eigene max-height von 34vh aus der Breitenregel und wird
     damit HÖHER als seine Hülle. Der Überstand fließt nicht mit, er legt sich
     über die Knopfleiste: gemessen bei 390x760, 390x815, 360x780 und 414x736
     bis zu 38 px, während die Falzprüfung grün meldete – sie maß die Hülle,
     nicht das Bild. Auf schmalen Fenstern begrenzt deshalb allein das Bild. */
  .hero__platz--mitte .hero__gericht { height: auto; }
  .hero__platz--mitte .hero__speise { max-height: 26vh; }
}

/* FLACHE FENSTER, zweite Stufe. Gemessen: bei 1280x720, 390x667 und 360x640
   rutschten die Knöpfe unter die Falz, weil Text, Bildreihe und Knöpfe
   zusammen mehr Höhe brauchten als der Bildschirm hergibt. Hier wird jeder
   Baustein kleiner, statt einen davon zu streichen: der Subhead trägt Inhalt
   und bleibt. */
@media (max-height: 745px) {
  .hero { padding-block: var(--jb-space-4); }
  .hero h1 { font-size: clamp(2.3rem, 1rem + 3.8vw, 3.8rem); margin-bottom: var(--jb-space-2); }
  .hero__text { max-width: 30rem; }
  .hero__rubrik { margin-bottom: var(--jb-space-2); }
  .hero__lead { font-size: var(--jb-text-sm); line-height: 1.5; }
  .hero__reihe { margin-top: var(--jb-space-4); }
  .hero__aktionen { margin-top: var(--jb-space-4); gap: var(--jb-space-3); }
  .btn--gross {
    min-height: 48px;
    padding: var(--jb-space-3) var(--jb-space-5);
    font-size: var(--jb-text-sm);
  }
  .hero__platz--mitte  .hero__gericht { height: clamp(130px, 26vh, 260px); }
  .hero__platz--links  .hero__gericht,
  .hero__platz--rechts .hero__gericht { height: clamp(100px, 19vh, 200px); }
}
@media (max-height: 745px) and (max-width: 700px) {
  /* Gleiche Begründung wie eine Stufe darüber: die Hülle bleibt auf auto, sonst
     wird das Bild höher als sie und legt sich über die Knöpfe. */
  .hero__platz--mitte .hero__gericht { height: auto; }
  .hero__platz--mitte .hero__speise { max-height: 27vh; }
}

/* Noch flachere Geräte (360x640 und ähnlich). Dort blieb der CTA mit 2 px
   unter der Falz stehen, nachdem der Subhead um eine Zeile länger geworden
   war. Gespart wird am Bild, nicht am Text. */
@media (max-height: 665px) {
  .hero__platz--mitte  .hero__gericht { height: clamp(115px, 22vh, 210px); }
  .hero__platz--links  .hero__gericht,
  .hero__platz--rechts .hero__gericht { height: clamp(90px, 16vh, 170px); }
  /* Zwölf Pixel reichten nicht: der Aufkleber ragt darüber hinaus, gemessen
     blieb ein Pixel Überlappung. Auch vierundzwanzig ließen nur elf Pixel Luft. */
  .hero__reihe { margin-top: var(--jb-space-6); }
  .hero__aktionen { margin-top: var(--jb-space-3); }
}
@media (max-height: 665px) and (max-width: 700px) {
  /* Auf dem Handy bleibt die figure auf auto, sonst staucht die Höhe das Bild.
     Begrenzt wird allein über das Bild. */
  .hero__platz--mitte .hero__gericht { height: auto; }
  .hero__platz--mitte .hero__speise { max-height: 23vh; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* --------------------------------------------------------- Sektionen ---- */

.sektion { padding-block: clamp(var(--jb-space-7), 6vw, var(--jb-space-9)); }
.sektion--flaeche { background: var(--jb-surface); }
.sektion--dunkel { background: var(--jb-dunkel); color: var(--jb-on-dunkel); }

.sektion__kopf {
  max-width: var(--jb-wrap-schmal);
  margin-bottom: clamp(var(--jb-space-6), 4vw, var(--jb-space-8));
}
.sektion__kopf h2 { margin-bottom: var(--jb-space-4); }
.sektion__kopf p { font-size: var(--jb-text-md); line-height: var(--jb-lh-md); color: var(--jb-text-muted); }

.rubrik {
  font-weight: 700;
  font-stretch: 100%;
  font-size: var(--jb-rubrik);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--jb-brand-text);
  margin-bottom: var(--jb-space-3);
}

/* ---------------------------------------------------------- Über uns ---- */

.ueber {
  display: grid;
  gap: clamp(var(--jb-space-6), 5vw, var(--jb-space-8));
  align-items: center;
}
@media (min-width: 860px) {
  .ueber { grid-template-columns: 320px 1fr; }
}

/* Das Primärlogo, an seiner zweiten prominenten Stelle. Es steht hier groß
   genug, dass der Schriftzug lesbar bleibt. Spalte statt bloßem Block, weil
   der Jahresaufkleber darunter hängt und seinen eigenen Abstand braucht. */
.ueber__logo {
  justify-self: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--jb-space-4);
}
.ueber__logo img { width: min(300px, 72vw); height: auto; }

/* Der Jahresaufkleber. Gleiche Mechanik wie die Aufkleber im Hero: gedrehte
   Fläche, harter Schatten, Text im Logoschnitt.

   ROT, nicht Gold. Gold trägt zwar Schwarz Tief mit 7,00:1, hebt sich von der
   cremefarbenen Sektionsfläche (--jb-surface, hell #F4EDE6) aber nur mit
   2,12:1 ab und verschwimmt dort. Rot kommt gegen dieselbe Fläche auf 4,73:1
   und trägt Weiß mit 5,49:1. Im Dark Mode liegt die Fläche bei #241E1B, dort
   sind es 3,00:1 Randabstand; --jb-brand und --jb-on-brand sind in beiden Modi
   gleich, der Aufkleber sieht also überall identisch aus.

   Kein font-weight und kein font-stretch: Anton hat genau einen Schnitt. */
.ueber__jahr {
  padding: .3em .9em .35em;
  background: var(--jb-brand);
  color: var(--jb-on-brand);
  font-family: var(--jb-font-display);
  text-transform: uppercase;
  font-size: clamp(1rem, .8rem + .7vw, 1.4rem);
  line-height: 1.1;
  letter-spacing: .02em;
  border-radius: var(--jb-radius-sm);
  box-shadow: var(--jb-schatten-sticker);
  transform: rotate(-3deg);
}

/* Diese Sektion nutzt kein .sektion__kopf, deshalb greift dessen Abstand hier
   nicht: ohne diese Regel klebte der Absatz direkt an der Überschrift.

   Die Regeln hängen an .ueber__text, nicht an .ueber: sonst fasst `.ueber p`
   auch den Jahresaufkleber und überschreibt dessen Farbe und Größe, weil ein
   Elementselektor darin höher wiegt als dessen Klasse allein. */
.ueber__text h2 { margin-bottom: var(--jb-space-4); }

/* Der Fließtext steht auf derselben Stufe wie überall sonst auf der Seite
   (16 px). Vorher trug er --jb-text-md, das ist die Größe der EINLEITUNGEN in
   .sektion__kopf: dort sind es zwei Zeilen, hier ein ganzer Block, und der
   wirkte damit größer als alles um ihn herum.

   Eine gemeinsame Kante für alle Absätze, in Pixeln. Mit einer `ch`-Grenze je
   Absatz misst dieselbe Zahl bei jeder Schriftgröße anders: zwei Absätze
   endeten so 130 px versetzt, und das sieht nach Versehen aus. 600 px sind hier
   rund 67 Zeichen.

   Die Grenze steht an den Absätzen und NICHT an .ueber__text: am Container
   erfasst sie auch die h2, und die brach damit auf zwei Zeilen um, obwohl sie
   in einer stand.

   :not(.rubrik), sonst überschreibt dieser Selektor mit seinem Elementanteil
   die Farbe der Rubrik und macht sie aus Rot zu Grau. Genau das war passiert:
   „ÜBER UNS" stand grau, während die Rubriken der Abschnitte darunter rot
   waren, und im Bild fiel es nicht auf. */
.ueber__text p:not(.rubrik) {
  font-size: var(--jb-text-sm);
  line-height: var(--jb-lh-sm);
  color: var(--jb-text-muted);
  max-width: 600px;
}

/* Der erste Absatz führt die Sektion an. Er unterscheidet sich allein über die
   FARBE, nicht über die Größe.

   Vorher stand er auf --jb-text-md, also 19 px neben 16 px. Drei Pixel sind zu
   wenig, um als Rangfolge gelesen zu werden, und zu viel, um wie Absicht
   auszusehen: der Unterschied wirkte wie ein vergessener Wert. In der ganzen
   Sektion gilt jetzt EIN Textmaß; gestaffelt wird über die drei
   Überschriftebenen, nicht über den Fließtext. */
.ueber__text .ueber__lead {
  color: var(--jb-text);
  margin-bottom: var(--jb-space-4);
  /* Nicht `balance`: das gilt nur bis vier Zeilen und gleicht alle Zeilen an,
     hier soll allein die letzte nicht als einzelnes Wort stehenbleiben. Genau
     das macht `pretty`. Browser ohne Unterstützung setzen normal um. */
  text-wrap: pretty;
}

/* Die Herkunft auf einer Markenfläche, mit freigestelltem Burger. Das Bild
   trägt den Abschnitt, der Text bleibt kurz.

   Sechs Fassungen zuvor suchten den Unterschied in Bauteilen (gedrehter
   Aufkleber, Rahmen mit farbiger Kante, riesige Jahreszahl, gezeichnetes
   Diner-Schild) oder in der Achse (mittig statt linksbündig). Alle blieben
   Typografie auf derselben cremefarbenen Fläche und wirkten entweder
   aufgesetzt oder wie eine Wiederholung. Den Bruch trägt die FLÄCHE plus ein
   Foto, das über ihre Kante läuft.

   Gemessene Kontraste auf der roten Fläche: Weiß 5,49:1, Creme Hell für die
   Rubrik 4,73:1. Gold wäre mit 2,23:1 durchgefallen, deshalb steht es hier
   nicht. Die Fläche selbst hebt sich mit 4,73:1 von der Sektionsfläche ab, im
   Dark Mode mit 3,00:1. --jb-brand und --jb-on-brand sind in beiden Modi
   gleich, der Block sieht überall identisch aus. */
.ueber__story {
  position: relative;
  margin-block: clamp(var(--jb-space-8), 7vw, var(--jb-space-9));
  padding: clamp(var(--jb-space-6), 4vw, var(--jb-space-8));
  background: var(--jb-brand);
  color: var(--jb-on-brand);
  border-radius: var(--jb-radius-lg);
  display: grid;
  gap: clamp(var(--jb-space-5), 4vw, var(--jb-space-7));
  align-items: center;
}
@media (min-width: 860px) {
  /* Die zweite Spalte bleibt leer und hält nur den Platz für das Bild frei,
     das darüber liegt und nicht mitfließt. */
  .ueber__story { grid-template-columns: 1fr minmax(0, 46%); }
}

/* Die Rubrik steht hier in Creme Hell, nicht in Markenrot: rot auf rot wäre
   unsichtbar. Denselben Wert trägt die Rubrik im Hero, aus demselben Grund. */
.ueber__story .rubrik { color: var(--jb-creme-fest); }
.ueber__story h3 { margin-bottom: var(--jb-space-4); }
.ueber__story__text p:not(.rubrik) {
  max-width: 46ch;
  font-size: var(--jb-text-sm);
  line-height: var(--jb-lh-sm);
  color: var(--jb-on-brand);
  text-wrap: pretty;
}

/* drop-shadow statt box-shadow: der Schatten soll der freigestellten Form
   folgen, nicht dem Bildkasten. Derselbe Wert wie unter den Speisen im Hero.

   Gestapelt bleibt das Bild im Fluss und gedeckelt: über die volle Spalte lief
   es auf 768 px auf 538 px Höhe und blähte die Sektion auf 2493 px auf. */
.ueber__story__bild {
  width: 100%;
  max-width: min(100%, 420px);
  height: auto;
  margin-inline: auto;
  filter: drop-shadow(var(--jb-schatten-speise));
}

/* Nebeneinander ragt der Burger über die Fläche, wie in der Vorlage. Dafür ist
   er aus dem Fluss genommen, statt über negative Ränder geschoben zu werden:
   trägt er zur Zeilenhöhe bei, wächst die Fläche mit ihm, und der Überstand
   frisst sich am Innenabstand auf. Gemessen kam er so auf minus 10 px, lag also
   vollständig innerhalb der Fläche.

   Jetzt bestimmt der Text die Höhe des Blocks, das Bild liegt darüber und ragt
   um die halbe Differenz oben und unten hinaus. Bei sehr großer
   Standardschriftgröße wird der Text höher als das Bild, dann sitzt es innen.
   Das ist gewollt: der Text hat Vorrang.

   Der Rand um den Block ist mindestens 64 px, der Überstand rund 50: der
   Burger läuft also nie in einen Nachbarabschnitt. Beides wird gemessen. */
@media (min-width: 860px) {
  .ueber__story__bild {
    position: absolute;
    right: clamp(8px, 2vw, 40px);
    top: 50%;
    translate: 0 -50%;
    width: min(44%, 520px);
    max-width: none;
    margin-inline: 0;
  }
}
/* Der Abschnitt zur Machart, linksbündig und über die volle Inhaltsbreite.
   Trennlinie oben; die drei Karten darunter gehören zu ihm und belegen ihn,
   deshalb steht sie über ihm und nicht zwischen ihm und den Karten. */
.ueber__block {
  padding-top: clamp(var(--jb-space-6), 4vw, var(--jb-space-7));
  border-top: 2px solid var(--jb-line);
}
.ueber__block > .rubrik { margin-bottom: var(--jb-space-2); }
/* Die Trennlinie läuft über die volle Inhaltsbreite, die Überschrift nicht:
   eine Linie, die mitten im Satzspiegel endet, liest sich als abgeschnitten,
   eine Überschrift über die ganze Breite dagegen als Fließtext. */
.ueber__block h3 {
  max-width: 600px;
  margin-bottom: var(--jb-space-5);
}
.ueber__block__text p {
  max-width: 480px;
  font-size: var(--jb-text-sm);
  line-height: var(--jb-lh-sm);
  color: var(--jb-text-muted);
  text-wrap: pretty;
}
.karten-reihe {
  display: grid;
  gap: var(--jb-space-5);
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  /* Näher an den Block darüber als dieser an den Text über ihm: die Karten
     gehören zum Abschnitt „So macht John das", nicht zur Sektion allgemein.
     Der Wert stand vorher als inline style im HTML. */
  margin-top: clamp(var(--jb-space-6), 4vw, var(--jb-space-7));
}

.info-karte {
  background: var(--jb-bg);
  border: 2px solid var(--jb-line);
  border-radius: var(--jb-radius-md);
}
/* Der Innenabstand sitzt auf Überschrift und Text, nicht auf der Karte: das
   Bild soll bündig an den Rändern kleben, der Text nicht. Eine zusätzliche
   Hülle im Markup wäre der einzige andere Weg und spart nichts.

   h4, nicht h3: der Block „So macht John das" darüber trägt die h3 dieses
   Abschnitts, sonst übersprünge die Gliederung eine Ebene. Der Schnitt bleibt
   trotzdem Anton. Das ist die Ausnahme von der Regel, dass h4 im Textschnitt
   steht – die gilt der Speisekarte, wo h4 über siebzig Gerichtsnamen trägt und
   ein Versalsatz daraus siebzig schreiende Zeilen machen würde. Hier sind es
   drei Karten mit je einem Wort, und sie sollen wie Überschriften aussehen,
   nicht wie fett gesetzter Fließtext. Die Größe ist unverändert. */
.info-karte h4 {
  font-family: var(--jb-font-display);
  /* Die globale h4-Regel setzt 700 und würde Chrome auf die synthetisch
     gefettete Fassung von Anton schicken. Nur deshalb steht hier ein Gewicht;
     400 ist der einzige Schnitt, den Anton hat. `font-stretch` bleibt weg, der
     Vorgabewert trifft es und Anton hat ohnehin keine Breitenachse. */
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: .005em;
  /* Eigene Größe statt --jb-h4. Jenes clamp fängt bei 1,1rem an, und damit
     stand die Überschrift auf 360 px bei 17,8 px, während der Lead-Absatz
     derselben Sektion 19 px misst: eine Überschrift, die kleiner ist als der
     Fließtext über ihr. Hier liegt die Untergrenze deshalb bei 20 px, gemessen
     über alle Breiten und über 100, 150 und 200 % Standardschriftgröße.
     --jb-h4 selbst bleibt unangetastet: dort hängen über siebzig Gerichtsnamen
     der Speisekarte dran, die neben keinem 19-px-Absatz stehen. */
  font-size: clamp(1.25rem, 1.05rem + .55vw, 1.5rem);
  line-height: 1.1;
  hyphens: auto;
  overflow-wrap: anywhere;
  margin: var(--jb-space-5) var(--jb-space-5) var(--jb-space-2);
}
.info-karte p {
  color: var(--jb-text-muted);
  margin: 0 var(--jb-space-5) var(--jb-space-5);
}

/* Zeichen im Kreis. Weiß auf Markenrot misst 5,49:1 und ist damit deutlich
   sauberer als die frühere Fassung mit Schwarz auf Gold: die kam zwar
   rechnerisch auf 7,00:1, wirkte als dunkles Grau auf Senfgelb aber stumpf.
   Der Kontrastwert allein entscheidet eben nicht über den Eindruck.

   --jb-brand und --jb-on-brand sind in beiden Modi gleich, der Kreis sieht im
   Dark Mode also genauso aus. currentColor trägt die Farbe ins Zeichen, damit
   steht kein Hex-Wert im HTML. */
.info-karte__icon {
  display: grid;
  place-items: center;
  width: 72px;
  height: 72px;
  border-radius: var(--jb-radius-pill);
  background: var(--jb-brand);
  color: var(--jb-on-brand);
  margin: var(--jb-space-5) var(--jb-space-5) var(--jb-space-4);
}
/* 40 px, nicht 30: bei kleinerem Zeichen fiel der Druckpfeil des Smash-Zeichens
   zu einem Strich zusammen und die drei Lagen des Classic-Zeichens lasen sich
   als Gleichheitszeichen. Die Form muss bei der ausgelieferten Größe tragen,
   nicht bei der im Entwurf. */
.info-karte__icon svg {
  width: 40px;
  height: 40px;
  fill: currentColor;
}

/* -------------------------------------------------------- Speisekarte -- */

.karte-nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--jb-space-2);
  margin-bottom: clamp(var(--jb-space-6), 4vw, var(--jb-space-7));
}
.karte-nav a {
  display: inline-block;
  padding: var(--jb-space-2) var(--jb-space-4);
  border-radius: var(--jb-radius-pill);
  background: var(--jb-surface);
  border: 2px solid var(--jb-line);
  color: var(--jb-text);
  text-decoration: none;
  font-weight: 700;
  font-size: var(--jb-text-xs);
}
.karte-nav a:hover { background: var(--jb-brand); color: var(--jb-on-brand); border-color: var(--jb-brand); }

.karte-gruppe { margin-bottom: clamp(var(--jb-space-8), 6vw, var(--jb-space-9)); }
.karte-gruppe:last-child { margin-bottom: 0; }
.karte-gruppe__kopf { margin-bottom: var(--jb-space-5); }
.karte-gruppe__kopf h3 { margin-bottom: var(--jb-space-2); }
.karte-gruppe__hinweis { color: var(--jb-text-muted); font-size: var(--jb-text-sm); }

/* Gerichte mit Foto */
.karte-raster {
  display: grid;
  gap: var(--jb-space-5);
  grid-template-columns: repeat(auto-fill, minmax(268px, 1fr));
}

.gericht {
  display: flex;
  flex-direction: column;
  background: var(--jb-bg);
  border: 2px solid var(--jb-line);
  border-radius: var(--jb-radius-md);
  overflow: hidden;
}
.gericht__bild {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  /* Feste Creme-Fläche hinter dem freigestellten Foto: im Dark Mode säße sonst
     ein weißer Kasten auf dunklem Grund. */
  background: var(--jb-creme-fest);
}
.gericht__ohne-bild {
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: 1;
  background: var(--jb-surface);
  color: var(--jb-text-muted);
  font-size: var(--jb-text-xs);
  text-align: center;
  padding: var(--jb-space-5);
}
.gericht__inhalt { padding: var(--jb-space-4) var(--jb-space-5) var(--jb-space-5); display: flex; flex-direction: column; gap: var(--jb-space-2); flex: 1; }
.gericht__nr {
  font-weight: 700;
  font-size: var(--jb-text-xs);
  color: var(--jb-text-muted);
  letter-spacing: .08em;
}
.gericht__name { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--jb-space-2); }
.gericht__zutaten { color: var(--jb-text-muted); font-size: var(--jb-text-sm); }
.gericht__text { font-size: var(--jb-text-sm); }

/* Gerichte ohne Foto, als Liste */
.karte-liste {
  display: grid;
  gap: var(--jb-space-3);
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}
.posten {
  display: flex;
  flex-direction: column;
  gap: var(--jb-space-1);
  padding: var(--jb-space-4);
  background: var(--jb-bg);
  border: 2px solid var(--jb-line);
  border-radius: var(--jb-radius-md);
}
.posten__kopf { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--jb-space-2); }
.posten__nr { font-weight: 700; font-size: var(--jb-text-xs); color: var(--jb-text-muted); letter-spacing: .08em; }
.posten__name { font-weight: 700; font-size: var(--jb-text-sm); }
.posten__text { color: var(--jb-text-muted); font-size: var(--jb-text-xs); }

/* Marker. Nie Farbe allein: jeder trägt Symbol UND Wort. */
.marker {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px var(--jb-space-2);
  border-radius: var(--jb-radius-pill);
  font-size: var(--jb-text-xs);
  font-weight: 700;
  line-height: 1.4;
  white-space: nowrap;
}
.marker--veggie { background: var(--jb-veggie); color: var(--jb-on-veggie); }
.marker--vegan  { background: var(--jb-veggie); color: var(--jb-on-veggie); }
.marker--scharf { background: var(--jb-brand); color: var(--jb-on-brand); }
.marker svg { width: 14px; height: 14px; fill: currentColor; }

/* Allergene am Gericht */
.allergene { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin-top: auto; padding-top: var(--jb-space-2); }
.allergene__label { font-size: var(--jb-text-xs); color: var(--jb-text-muted); margin-right: var(--jb-space-1); }
.allergen {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  padding-inline: 4px;
  border: 2px solid var(--jb-border);
  border-radius: var(--jb-radius-sm);
  font-size: var(--jb-text-xs);
  font-weight: 700;
  color: var(--jb-text);
}
.allergen--keine { border: 0; font-weight: 500; color: var(--jb-text-muted); }

/* Legende */
.legende {
  display: grid;
  gap: var(--jb-space-3);
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
}
.legende li { display: flex; align-items: center; gap: var(--jb-space-3); font-size: var(--jb-text-sm); }

.karte-fussnote {
  margin-top: var(--jb-space-6);
  padding: var(--jb-space-4) var(--jb-space-5);
  background: var(--jb-surface);
  border-left: 6px solid var(--jb-brand);
  border-radius: var(--jb-radius-sm);
  color: var(--jb-text-muted);
  font-size: var(--jb-text-sm);
}

/* ---------------------------------------------------------- Standorte -- */

.finder {
  background: var(--jb-bg);
  border: 2px solid var(--jb-line);
  border-radius: var(--jb-radius-md);
  padding: clamp(var(--jb-space-5), 3vw, var(--jb-space-6));
  margin-bottom: clamp(var(--jb-space-6), 4vw, var(--jb-space-7));
}
.finder h3 { margin-bottom: var(--jb-space-2); }
.finder > p { color: var(--jb-text-muted); margin-bottom: var(--jb-space-4); }
.finder__form { display: flex; flex-wrap: wrap; gap: var(--jb-space-3); }
.finder__feld { flex: 1 1 240px; min-width: 0; }
.finder__feld input {
  width: 100%;
  min-height: 48px;
  padding: var(--jb-space-3) var(--jb-space-4);
  font: inherit;
  color: var(--jb-text);
  background: var(--jb-bg);
  border: 2px solid var(--jb-border);
  border-radius: var(--jb-radius-pill);
}
.finder__feld input::placeholder { color: var(--jb-text-muted); }
.finder__status { margin-top: var(--jb-space-4); font-size: var(--jb-text-sm); color: var(--jb-text-muted); }
.finder__status:empty { margin-top: 0; }

.loc-gruppe + .loc-gruppe { margin-top: clamp(var(--jb-space-6), 4vw, var(--jb-space-7)); }
.loc-gruppe[hidden] { display: none; }
.loc-gruppe__titel { margin-bottom: var(--jb-space-4); }

.locations { display: grid; grid-template-columns: repeat(auto-fill, minmax(310px, 1fr)); gap: var(--jb-space-5); }

.loc {
  display: flex;
  flex-direction: column;
  gap: var(--jb-space-3);
  padding: var(--jb-space-5);
  background: var(--jb-bg);
  border: 2px solid var(--jb-line);
  border-radius: var(--jb-radius-md);
}
.loc--nearest { border-color: var(--jb-brand); box-shadow: var(--jb-schatten-sm); }
.loc__top { display: flex; align-items: flex-start; flex-wrap: wrap; gap: var(--jb-space-2); }
.loc__name { flex: 1 1 auto; }
.loc__badge {
  padding: 2px var(--jb-space-2);
  border-radius: var(--jb-radius-pill);
  background: var(--jb-accent);
  color: var(--jb-on-accent);
  font-size: var(--jb-text-xs);
  font-weight: 700;
}
.loc__dist { font-size: var(--jb-text-xs); color: var(--jb-text-muted); font-weight: 700; }
.loc__addr { font-style: normal; color: var(--jb-text-muted); font-size: var(--jb-text-sm); }
.loc__addr .plz { font-weight: 700; color: var(--jb-text); }
.loc__hinweis { font-size: var(--jb-text-xs); color: var(--jb-text-muted); }
.loc__actions { margin-top: auto; display: flex; flex-direction: column; gap: var(--jb-space-2); }
.loc__actions .btn { width: 100%; }

.leerzustand {
  padding: var(--jb-space-6);
  background: var(--jb-bg);
  border: 2px dashed var(--jb-border);
  border-radius: var(--jb-radius-md);
  color: var(--jb-text-muted);
}
.leerzustand strong { color: var(--jb-text); display: block; margin-bottom: var(--jb-space-2); }

.ohne-js {
  margin-top: var(--jb-space-4);
  font-size: var(--jb-text-sm);
  color: var(--jb-text-muted);
}

/* ---------------------------------------------------------------- FAQ -- */

.faq { display: grid; gap: var(--jb-space-3); max-width: 90ch; }
.faq__eintrag {
  background: var(--jb-bg);
  border: 2px solid var(--jb-line);
  border-radius: var(--jb-radius-md);
  overflow: hidden;
}
.faq__frage {
  padding: var(--jb-space-4) var(--jb-space-5);
  font-weight: 700;
  font-size: var(--jb-text-md);
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--jb-space-4);
}
.faq__frage::-webkit-details-marker { display: none; }
.faq__frage::after {
  content: '+';
  font-weight: 800;
  font-size: var(--jb-text-lg);
  color: var(--jb-brand-text);
  flex: none;
}
.faq__eintrag[open] .faq__frage::after { content: '\2013'; }
.faq__antwort { padding: 0 var(--jb-space-5) var(--jb-space-5); color: var(--jb-text-muted); }

/* ------------------------------------------------------------- Fußzeile -- */

.fuss { background: var(--jb-dunkel); color: var(--jb-on-dunkel); }
.fuss .wrap { padding-block: clamp(var(--jb-space-7), 5vw, var(--jb-space-8)); }
.fuss__grid {
  display: grid;
  gap: var(--jb-space-6);
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
}
.fuss__logo { width: 220px; height: auto; margin-bottom: var(--jb-space-4); }
.fuss p { color: var(--jb-on-dunkel); opacity: .82; font-size: var(--jb-text-sm); }
.fuss h2 {
  font-size: var(--jb-text-md);
  margin-bottom: var(--jb-space-3);
  color: var(--jb-accent);
}
.fuss ul { display: grid; gap: var(--jb-space-2); }
.fuss a { color: var(--jb-on-dunkel); }
.fuss a:hover { color: var(--jb-accent); }
.fuss__unten {
  margin-top: var(--jb-space-7);
  padding-top: var(--jb-space-5);
  border-top: 1px solid var(--jb-auf-dunkel-linie);
  display: flex;
  flex-wrap: wrap;
  gap: var(--jb-space-3) var(--jb-space-6);
  justify-content: space-between;
  font-size: var(--jb-text-xs);
  color: var(--jb-on-dunkel);
  opacity: .8;
}

/* ----------------------------------------------------- Cookie-Hinweis -- */

.consent {
  position: fixed;
  left: var(--jb-space-4);
  right: var(--jb-space-4);
  bottom: var(--jb-space-4);
  z-index: 90;
  max-width: 520px;
  margin-inline: auto;
  padding: var(--jb-space-5);
  background: var(--jb-bg);
  border: 2px solid var(--jb-border);
  border-radius: var(--jb-radius-md);
  box-shadow: var(--jb-schatten-md);
}
.consent[hidden] { display: none; }
.consent__titel {
  font-family: var(--jb-font-display);
  font-weight: 400;
  font-style: normal;
  text-transform: uppercase;
  font-size: var(--jb-text-lg);
  margin-bottom: var(--jb-space-2);
}
.consent p { font-size: var(--jb-text-sm); }
.consent__aktionen { display: flex; flex-wrap: wrap; gap: var(--jb-space-3); margin-top: var(--jb-space-4); }
.consent__links { margin-top: var(--jb-space-4); font-size: var(--jb-text-xs); display: flex; gap: var(--jb-space-2); flex-wrap: wrap; }

/* -------------------------------------------------------- Rechtsseiten -- */

.recht { padding-block: clamp(var(--jb-space-7), 6vw, var(--jb-space-9)); }
.recht__inner { max-width: var(--jb-wrap-schmal); }
.recht__zurueck { display: inline-block; margin-bottom: var(--jb-space-5); font-weight: 700; }
.recht h1 { margin-bottom: var(--jb-space-5); }
.recht h2 {
  font-size: var(--jb-h3);
  margin-top: var(--jb-space-7);
  margin-bottom: var(--jb-space-3);
}
/* Auf den Rechtsseiten trägt die dritte Ebene Absatzüberschriften im Fließtext.
   Sie fällt deshalb aus dem Display-Schnitt heraus und steht im Textschnitt. */
.recht h3 {
  font-family: var(--jb-font);
  font-weight: 700;
  font-size: var(--jb-h4);
  font-stretch: 100%;
  font-style: normal;
  text-transform: none;
  margin-top: var(--jb-space-5);
  margin-bottom: var(--jb-space-2);
}
.recht p, .recht address, .recht li { margin-bottom: var(--jb-space-3); }
.recht address { font-style: normal; }
.recht ul { list-style: disc; padding-left: var(--jb-space-5); }
.recht mark { background: var(--jb-accent); color: var(--jb-on-accent); padding: 0 4px; border-radius: 3px; }
.recht code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .92em;
  background: var(--jb-surface);
  padding: 1px 5px;
  border-radius: 4px;
}
/* Der Widerrufsschalter im Fließtext ist ein echter Button, kein Link ohne
   Ziel: er löst eine Aktion aus und führt nirgendwohin. Er sieht aus wie ein
   Link, damit er im Satz nicht als Fremdkörper steht. */
.recht__link {
  font: inherit;
  color: var(--jb-brand-text);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-thickness: .08em;
  text-underline-offset: .18em;
}
.recht__link:hover { text-decoration-thickness: .14em; }
.recht__stand { margin-top: var(--jb-space-7); color: var(--jb-text-muted); font-size: var(--jb-text-sm); }
