/* ═══════════════════════════════════════════════════════════
   VELARO — Ristorante · Bar, Berlin-Tegel
   Built on the v09-cinema treatment: near-black, letterboxed,
   sticky chapters, scroll-driven cross-dissolves — but the
   logistics (phone, hours, address, menu) never fade out.
   ═══════════════════════════════════════════════════════════ */

:root{
  --ink:#06080a;
  --paper:#f2ede4;
  --paper-ink:#14181b;
  --haze:#8d8f8a;
  --gold:#c9a15c;          /* brass accent on the dark side */
  --navy:#1b3a55;          /* the velvet banquettes */
  --line:#1c2124;
  --line-ink:#c9c0ae;      /* rules on the paper side */
  /* Letterbox off: black bands on a near-black page read as wasted height rather than as a
     cinema frame. Kept as a token at 0 instead of deleted — thirteen calc() expressions key
     off it (nav offset, scroll hint, chips, scroll-margin), and they all stay correct. */
  --bar:0px;
  --navh:3.4rem;            /* height of the fixed nav — sticky offsets key off this */
  --pad:clamp(20px, 7vw, 110px);
  --serif:"Cormorant Garamond", "Times New Roman", serif;
  --didone:"Bodoni Moda", "Playfair Display", Georgia, serif;
  --mono:"DM Mono", ui-monospace, "SF Mono", Menlo, monospace;
}

*,*::before,*::after{box-sizing:border-box}
html{
  -webkit-text-size-adjust:100%; scroll-behavior:smooth;
  /* clip, not hidden: `overflow-x:hidden` on <body> makes <body> the scroll
     container, which moves the snap points off the document scroller. */
  overflow-x:clip;

  /* One flick, one frame. `proximity`, not `mandatory`: with mandatory the
     scroller must always come to rest on a snap point, and the sections after
     the chapters (the menu is ~13 000 px tall) have no snap point inside them —
     measured at 1440 and 390, a flick inside the menu got yanked back to the
     last chapter and the foot of the menu, the gallery and the footer were
     unreachable. Then `proximity` turned out to be the whole problem, not a
     milder form of it — see the chapter block below. There is no snap container
     here now. Anchor offsets still live on the targets (scroll-margin-top)
     rather than scroll-padding, which would shrink the snapport it no longer
     has and is simply the wrong tool for an anchor offset. */
}
body{
  margin:0; background:var(--ink); color:var(--paper);
  font-family:var(--serif); font-weight:300;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%}
a{color:inherit}
h2,h3{font-weight:400}

/* ── bilingual switching: one class pair, no JS per string ── */
html[lang="de"] .en{display:none}
html[lang="en"] .de{display:none}

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

.skip{
  position:absolute; left:-9999px; top:0; z-index:99;
  background:var(--gold); color:var(--ink); padding:.8rem 1.2rem;
  font-family:var(--mono); font-size:.7rem; letter-spacing:.2em; text-transform:uppercase; text-decoration:none}
.skip:focus{left:0; top:0}

:focus-visible{outline:2px solid var(--gold); outline-offset:3px}

/* ── the notched double-rule frame from the printed menu ──── */
.rule{
  position:relative; border:1px solid var(--gold);
  --n:11px;
  clip-path:polygon(var(--n) 0, calc(100% - var(--n)) 0, 100% var(--n), 100% calc(100% - var(--n)),
                    calc(100% - var(--n)) 100%, var(--n) 100%, 0 calc(100% - var(--n)), 0 var(--n));
}
.rule::before{
  content:""; position:absolute; inset:5px; border:1px solid var(--gold); opacity:.55; pointer-events:none;
  --n:7px;
  clip-path:polygon(var(--n) 0, calc(100% - var(--n)) 0, 100% var(--n), 100% calc(100% - var(--n)),
                    calc(100% - var(--n)) 100%, var(--n) 100%, 0 calc(100% - var(--n)), 0 var(--n));
}

/* ── letterbox + chrome ─────────────────────────────────── */
.bar{display:none; position:fixed; left:0; right:0; height:var(--bar); background:#000; z-index:70; pointer-events:none}
.bar-top{top:0}
.bar-bot{bottom:0}

.progress{position:fixed; top:var(--bar); left:0; right:0; height:1px; z-index:71; background:rgba(255,255,255,.07); pointer-events:none}
.progress i{display:block; height:100%; background:var(--gold); transform-origin:0 50%; scale:0 1;
  animation:prog linear both; animation-timeline:scroll(root block)}
@keyframes prog{from{scale:0 1}to{scale:1 1}}

/* the nav does NOT fade in — the phone number is reachable from the first pixel */
.nav{
  position:fixed; top:var(--bar); left:0; right:0; z-index:72;
  display:flex; align-items:center; gap:1rem;
  padding:.7rem var(--pad);
  font-family:var(--mono); font-size:.66rem; letter-spacing:.2em; text-transform:uppercase;
  color:var(--haze);
  min-height:var(--navh);
  background:linear-gradient(180deg, rgba(6,8,10,.97) 0%, rgba(6,8,10,.93) 74%, rgba(6,8,10,0) 100%);
}
.nav-mark{font-family:var(--didone); font-size:1.05rem; letter-spacing:.36em; color:var(--paper); text-decoration:none; flex:0 0 auto}
.nav-links{display:flex; gap:clamp(.8rem,2.2vw,1.9rem); flex:1 1 auto; justify-content:center; flex-wrap:nowrap; overflow:hidden}
.nav-links a{text-decoration:none; white-space:nowrap; transition:color .3s}
.nav-links a:hover,.nav-links a:focus-visible{color:var(--gold)}
.nav-act{display:flex; align-items:center; gap:.5rem; flex:0 0 auto}
.lang-btn{
  font-family:var(--mono); font-size:.64rem; letter-spacing:.18em;
  background:transparent; color:var(--haze); border:1px solid var(--line);
  padding:.45rem .6rem; cursor:pointer; min-width:2.9em}
.lang-btn:hover{color:var(--paper); border-color:var(--gold)}
.tel-btn{
  display:inline-flex; align-items:center; gap:.45em; text-decoration:none;
  background:var(--gold); color:var(--ink); padding:.5rem .85rem; letter-spacing:.14em; white-space:nowrap}
.tel-btn:hover{background:#dcb676}
.tel-short{display:none}
@media (max-width:900px){
  .nav-links{display:none}
  .nav{justify-content:space-between}
}
@media (max-width:560px){
  .tel-full{display:none}
  .tel-short{display:inline}
  .nav-mark{font-size:.9rem; letter-spacing:.24em}
  /* thumb-sized targets: this is the button that books the table */
  .tel-btn,.lang-btn{min-height:44px; padding-inline:.9rem; display:inline-flex; align-items:center; justify-content:center}
  :root{--navh:4.6rem}
  .cta .cta-tel{display:none}
}

/* ── chapters: one screen each ──────────────────────────────
   Each chapter is exactly one viewport. The chapter-at-a-time feeling comes from
   the wheel handler in app.js, NOT from CSS snapping, and that is a correction
   rather than a preference: snapping and the handler were pulling in opposite
   directions and the visitor felt the fight.

   Measured at 1440, leaving the last chapter downwards — the handler scrolls to
   the foot of the run while `proximity` drags back to the frame's own snap point,
   which is nearer. Six wheel gestures moved the page 831px and three of them
   moved it nothing at all. Coming back up out of Willkommen was worse: its snap
   point sat 831px below the last chapter's, so every gesture short of that fell
   back into it — six gestures, 4431 every time, the page never moved once.

   Giving the sections below snap points of their own was the previous attempt at
   this and it is what built that trap. With no snap container at all the same
   six gestures travel 900px and 1801px, and the handler still delivers one frame
   per gesture on a wheel or a trackpad. On touch there is no wheel event, so a
   phone now scrolls natively — which is the right place to land anyway: a chapter
   is not one viewport on a phone once the frame and the text stack, and iOS
   resizes the viewport under your thumb as the address bar collapses.
   To bring it back: `scroll-snap-type:y proximity` on html and
   `scroll-snap-align:start` here. */
.chapter{
  position:relative; height:100svh; overflow:clip;
}
.stage{
  position:relative; height:100%; background:transparent;
  /* height of one letterbox band, so the type can be placed inside the
     photograph instead of drifting onto the black at short viewports */
  --lb:max(0px, calc((100svh - 100vw / 2.39) / 2));
}

.frame{
  position:absolute; left:0; right:0; top:50%; translate:0 -50%;
  aspect-ratio:2.39; max-height:100%; overflow:clip;
}
.frame picture{display:contents}
.frame img{
  width:100%; height:100%; object-fit:cover; display:block;
  filter:contrast(1.16) saturate(.82) brightness(.84);
  transform-origin:52% 48%; transform:scale(1.07);
  transition:transform 1.7s cubic-bezier(.22,.61,.36,1);
}
.chapter.in .frame img{transform:scale(1)}

.grade{position:absolute; inset:0; pointer-events:none; mix-blend-mode:soft-light;
  background:linear-gradient(197deg, rgba(255,196,128,.34) 0%, rgba(255,196,128,0) 46%, rgba(12,42,64,.58) 100%)}
.grade::after{content:""; position:absolute; inset:0; background:#0d2436; mix-blend-mode:lighten; opacity:.13}
.vignette{position:absolute; inset:0; pointer-events:none;
  background:radial-gradient(ellipse 80% 88% at 50% 44%, rgba(0,0,0,0) 30%, rgba(0,0,0,.8) 100%)}

/* ── one thought per screen ─────────────────────────────────
   Placement is per photograph, not per rule: bottom-left is the default, but
   each frame's quiet quarter was measured (mean luminance and standard
   deviation of every quadrant) and the type put there, so it never lands on a
   plate, a face or the horizon. A soft radial scrim carries the contrast the
   photograph cannot. */
.say{position:absolute; z-index:2; max-width:min(44rem,calc(100% - 2 * var(--pad)))}
/* A wash across the full width of the frame, fading out towards the middle —
   the same device as the logistics slab on the title card. Two of the allowed
   photographs (v090 and v106) are white linen edge to edge and have no dark
   quarter at all, so display type on them needs carried contrast, not luck. */
.say::before{
  content:""; position:absolute; z-index:-1; pointer-events:none;
  inset:-3.4rem calc(-100vw) -10svh calc(-1 * var(--pad));
  background:linear-gradient(to top, rgba(6,8,10,.9) 0%, rgba(6,8,10,.86) 55%,
    rgba(6,8,10,.55) 79%, rgba(6,8,10,0) 100%);
}
.say-br::before{inset:-3.4rem calc(-1 * var(--pad)) -10svh -100vw}
.say-tr::before{inset:-10svh calc(-1 * var(--pad)) -3.4rem -100vw;
  background:linear-gradient(to bottom, rgba(6,8,10,.9) 0%, rgba(6,8,10,.86) 55%,
    rgba(6,8,10,.55) 79%, rgba(6,8,10,0) 100%)}
.say>*{opacity:0; translate:0 20px; filter:blur(6px);
  transition:opacity .85s ease, translate .85s cubic-bezier(.22,.61,.36,1), filter .85s ease}
.chapter.in .say>*{opacity:1; translate:0 0; filter:blur(0)}
.chapter.in .say>*+*{transition-delay:.16s}

.say-bl{left:var(--pad); bottom:calc(var(--lb) + 4svh); --sx:0%; --sy:100%}
.say-br{right:var(--pad); bottom:calc(var(--lb) + 4svh); text-align:right; --sx:100%; --sy:100%}
.say-tr{right:var(--pad); text-align:right; --sx:100%; --sy:0%;
  top:max(calc(var(--lb) + 4svh), calc(var(--bar) + var(--navh) + 1.2rem))}
.say-br .line,.say-tr .line{margin-left:auto}

.line{margin:0; font-family:var(--didone); font-weight:400;
  font-size:clamp(1.7rem,4.2vw,3.4rem); line-height:1.08; letter-spacing:-.005em; text-wrap:balance; max-width:22ch}
.line.small{margin-top:.9rem; font-family:var(--serif); font-size:clamp(1rem,1.7vw,1.45rem);
  line-height:1.45; color:#cfc8ba; max-width:44ch; letter-spacing:0}
.line.small a{text-decoration:none; border-bottom:1px solid rgba(201,161,92,.6); white-space:nowrap}

/* ── title card ─────────────────────────────────────────── */
.say-mid{left:var(--pad); right:var(--pad); top:50%; translate:0 -50%; max-width:none;
  display:grid; place-items:center; text-align:center; text-shadow:0 2px 22px rgba(0,0,0,.72)}
.say-mid::before{inset:-3rem -2rem;
  background:radial-gradient(70% 80% at 50% 50%, rgba(6,8,10,.58) 0%, rgba(6,8,10,0) 76%)}
.wordmark{display:inline-block; background:rgba(6,8,10,.35);
  padding:clamp(.9rem,2.4vw,1.7rem) clamp(1.1rem,4vw,2.8rem) clamp(1.2rem,3vw,2.1rem)}
h1{margin:0; font-family:var(--didone); font-weight:400;
  font-size:clamp(2.4rem,9vw,6.4rem); line-height:1; letter-spacing:.14em; text-indent:.14em}
.wm-sub{margin:.5em 0 0; font-family:var(--mono); font-size:clamp(.56rem,1.2vw,.78rem);
  letter-spacing:.42em; text-indent:.42em; color:var(--gold)}
.sub{margin:1.1rem 0 0; font-size:clamp(.98rem,1.7vw,1.3rem); color:#d5cec1; font-style:italic; text-wrap:balance}
/* logistics slab — never animated, never hidden */
.hero-facts{
  position:absolute; left:0; right:0; bottom:calc(var(--bar) + 4svh);
  padding:2.6rem var(--pad) 1.4rem; text-align:center; z-index:3;
  background:linear-gradient(180deg, rgba(6,8,10,0) 0%, rgba(6,8,10,.78) 46%, rgba(6,8,10,.9) 100%)}
.hf-line{margin:0 0 1rem; font-family:var(--mono); font-size:clamp(.6rem,1.3vw,.72rem);
  letter-spacing:.2em; text-transform:uppercase; color:#ded7c9;
  display:flex; gap:.4rem .8em; justify-content:center; align-items:baseline; flex-wrap:wrap}
@media (max-width:620px){ .hf-line{flex-direction:column; gap:.5rem} .hf-line .sep{display:none} }
.hf-line a{text-decoration:none; border-bottom:1px solid rgba(201,161,92,.5)}
.hf-line .sep{margin:0 .8em; color:var(--gold)}
.hf-cta{margin:0; display:flex; gap:.6rem; justify-content:center; flex-wrap:wrap}
.cta{
  display:inline-block; text-decoration:none; background:var(--gold); color:var(--ink);
  font-family:var(--mono); font-size:.66rem; letter-spacing:.2em; text-transform:uppercase;
  padding:.85rem 1.5rem; transition:background .25s}
.cta:hover{background:#dcb676}
.cta-ghost{background:transparent; color:var(--paper); border:1px solid var(--gold)}
.cta-ghost:hover{background:rgba(201,161,92,.14)}

.label,.scroll-hint{font-family:var(--mono); font-weight:300; font-size:.64rem;
  letter-spacing:.3em; text-transform:uppercase; color:var(--haze); margin:0}
.scroll-hint{position:absolute; left:var(--pad); bottom:calc(var(--bar) + 2.2svh); z-index:2;
  opacity:0; transition:opacity .6s ease}
#title.in .scroll-hint{opacity:1}

/* ── phone / portrait window: portrait frame, type underneath ──
   On a phone the photograph is portrait (see the <picture> media source) and the
   line sits below it on black instead of over it: on a 3/4 frame there is no
   quiet quarter big enough for display type without covering the food. */
@media (orientation:portrait){
  .chapter:not(#title) .stage{
    display:flex; flex-direction:column; justify-content:center;
    padding-block:calc(var(--bar) + var(--navh) + .4rem) calc(var(--bar) + 2rem)}
  .chapter:not(#title) .frame{
    position:relative; top:auto; translate:none; flex:0 1 auto; min-height:0;
    aspect-ratio:3/2; max-height:none; width:100%}
  .chapter:not(#title) .say{
    position:relative; left:auto; right:auto; top:auto; bottom:auto; translate:none;
    max-width:none; text-align:left; padding:1.3rem var(--pad) 0}
  .chapter:not(#title) .say::before{display:none}
  .chapter:not(#title) .say-br .line,.chapter:not(#title) .say-tr .line{margin-left:0}
  /* the title card keeps the photograph full-bleed behind the wordmark */
  #title .frame{aspect-ratio:auto; inset:0; top:0; translate:none; max-height:none}
  #title .say-mid{top:44%}
  .hero-facts{bottom:calc(var(--bar) + 4svh)}
}

/* ═══ the practical half ══════════════════════════════════ */
.credits{position:relative; z-index:2; background:var(--ink); border-top:1px solid var(--line)}
/* the nav is fixed, and the snapport must stay the full viewport (see html{}),
   so the anchor offset sits on the jump targets instead of on the scroller */
main,.block,.menu-sec,.foot,.grid{scroll-margin-top:calc(var(--bar) + var(--navh) + 1rem)}
/* Capped and centred, same measure as the printed-menu section. Without this the
   blocks ran the full width of a wide monitor: a heading at the far left, prose
   smeared across 1900px and the portrait marooned on the right edge. */
.block,.foot{padding:clamp(3rem,7svh,5.5rem) var(--pad); max-width:82rem; margin-inline:auto}
.label{color:var(--gold); margin-bottom:1.2rem}
.block h2,.menu-head h2{margin:0 0 .9rem; font-family:var(--didone); font-weight:400;
  font-size:clamp(1.7rem,4vw,3rem); line-height:1.1}
.note{margin:0; max-width:60ch; color:var(--haze); font-size:clamp(.98rem,1.4vw,1.1rem); line-height:1.6}
.note-inline{color:var(--haze); font-size:.9em}

/* ── Willkommen ─────────────────────────────────────────────
   An uncropped 2:3 portrait 24rem wide is 36rem tall; three short paragraphs are
   ~27rem. No amount of tuning makes those two match, so the band was never a
   row of two equal-height items — it is one text column running the FULL height
   of the section, with the portrait beside it top to bottom. Label and heading
   therefore live inside the text column (they used to cap the band from above,
   which is exactly the height the portrait had nothing to align with), and the
   credit rule is pushed to the foot of the column so it lands level with the
   foot of the frame. Three edges line up: cap-line, foot, and section padding. */
.welcome-wrap{
  display:grid; gap:clamp(1.6rem,3.4vw,3rem);
  /* the host's column is the only portrait in the section and the client wants it read, not
     glanced at — wide enough that the full 2:3 frame stands taller than the prose beside it */
  /* 21rem floor, not 19: below ~1000px the 34% track collapsed to its minimum and the
     frame ended up SHORTER than the text — the same imbalance mirrored. */
  grid-template-columns:minmax(0,1fr) clamp(21rem,34%,30rem);
  align-items:stretch}
@media (max-width:900px){ .welcome-wrap{grid-template-columns:1fr; gap:2rem; align-items:start} }
.welcome-text{display:flex; flex-direction:column}
.welcome-text h2{margin-bottom:1.7rem}
/* two text columns, not one narrow one: the paragraphs are short, and at this
   width a single 60ch measure left a third of the section empty */
.prose{columns:2; column-gap:clamp(1.6rem,3vw,2.8rem)}
/* the second column exists only while the portrait is beside the text; once the
   band stacks, one measure. Switching earlier than 900px made the text tower
   over the frame instead. */
@media (max-width:900px){ .prose{columns:1} }
.prose p{margin:0 0 1rem; font-size:clamp(1rem,1.35vw,1.12rem); line-height:1.62; color:#ded7c9}
/* first paragraph as the lede, spanning both columns: hierarchy inside the
   block, so three equal grey paragraphs stop reading as a slab */
.prose p:first-child{column-span:all; margin-bottom:1.5rem;
  font-size:clamp(1.15rem,1.9vw,1.55rem); line-height:1.45; color:#f0e9dc; max-width:44ch}
.prose p:last-child{margin-bottom:0}
.attrib{margin:1.6rem 0 0; padding-top:1rem; border-top:1px solid var(--line);
  font-family:var(--mono); font-size:.62rem; letter-spacing:.22em; text-transform:uppercase; color:var(--haze)}
/* margin-top:auto pins the credit rule to the foot of the column, i.e. level with
   the foot of the frame — the residual slack (~2-3rem now that the column runs the
   whole section height, not ~10rem as when the heading sat above the band) reads as
   air above the rule instead of a void beside the portrait. */
.welcome-text .attrib{margin-top:auto; padding-top:1.4rem}
@media (max-width:900px){ .welcome-text .attrib{margin-top:1.6rem} }
.welcome-fig,.anf-fig{margin:0; padding:6px; background:#0a0d10;
  display:grid; grid-template-rows:auto auto; align-self:start}
/* The portrait is shown WHOLE — no crop. Cropping it to the text's height cut the
   host's head off, which is worse than any alignment gain. It is the frame that
   sets the height of the band now; the text column stretches to meet it. */
.welcome-fig img,.anf-fig img{display:block; width:100%; height:auto;
  aspect-ratio:2/3; object-fit:contain; filter:contrast(1.06) saturate(.9) brightness(.94)}
.welcome-fig figcaption,.anf-fig figcaption{
  padding:.9rem .6rem .5rem; font-family:var(--mono); font-size:.6rem;
  letter-spacing:.18em; text-transform:uppercase; color:var(--haze); text-align:center}

/* ── DIE SPEISEKARTE — printed-menu treatment on paper ───── */
.menu-sec{background:var(--paper); color:var(--paper-ink); padding:clamp(3rem,7svh,5.5rem) var(--pad)}
.menu-inner{max-width:78rem; margin:0 auto}
.menu-sec a{color:#7a5a1e}
.label-ink{color:#8a6a24}
.menu-head h2{color:var(--paper-ink)}
.menu-intro{margin:0 0 .8rem; max-width:62ch; font-size:clamp(1.02rem,1.6vw,1.22rem); line-height:1.6; color:#3d454a}
.menu-count{margin:0; font-family:var(--mono); font-size:.62rem; letter-spacing:.2em; text-transform:uppercase; color:#7b8288}
.menu-sec :focus-visible{outline:2px solid #8a6a24; outline-offset:3px}

/* signature block */
.sig{--n:12px; border-color:#8a6a24; margin:2.2rem 0 0; padding:clamp(1.1rem,2.6vw,1.8rem)}
.sig::before{border-color:#8a6a24; opacity:.4}
.sig-list{list-style:none; margin:.4rem 0 0; padding:0;
  display:grid; gap:.9rem 2rem; grid-template-columns:repeat(auto-fit,minmax(min(100%,15rem),1fr))}
.sig-list li{border-top:1px solid var(--line-ink); padding-top:.7rem}
.sig-name{display:block; font-family:var(--didone); font-size:clamp(1.05rem,1.9vw,1.35rem)}
.sig-meta{display:block; margin-top:.25rem; font-family:var(--mono); font-size:.6rem; letter-spacing:.18em; text-transform:uppercase; color:#7b8288}

/* section chips */
.chips{
  display:flex; flex-wrap:wrap; gap:.4rem;
  padding:.9rem 0; margin:2.2rem 0 1.4rem;
  background:var(--paper)}
/* on a phone the chip row becomes a sticky horizontal scroller: 22 wrapped chips
   would eat half the screen, and this is the jump-to-course control */
@media (max-width:900px){
  .chips{position:sticky; top:calc(var(--bar) + var(--navh)); z-index:20;
    flex-wrap:nowrap; overflow-x:auto; overscroll-behavior-x:contain; scrollbar-width:thin}
}
.chips a{
  flex:0 0 auto; display:inline-flex; align-items:center; min-height:42px;
  text-decoration:none; color:#3d454a; border:1px solid var(--line-ink);
  font-family:var(--mono); font-size:.6rem; letter-spacing:.16em; text-transform:uppercase;
  padding:.5rem .8rem; white-space:nowrap; transition:background .2s,color .2s}
.chips a:hover{background:var(--paper-ink); color:var(--paper); border-color:var(--paper-ink)}
.chips .chip-head{flex:0 0 100%; padding:.6rem 0 .1rem; border:0; color:#8a6a24; pointer-events:none;
  font-family:var(--mono); font-size:.58rem; letter-spacing:.24em; text-transform:uppercase}
@media (max-width:900px){ .chips .chip-head{flex:0 0 auto; align-self:center; padding:.5rem .4rem .5rem 0} }

.menu-group{margin:0 0 2.6rem}
.menu-group>h3{
  margin:2.4rem 0 1.2rem; font-family:var(--didone); font-weight:400;
  font-size:clamp(1.4rem,3vw,2.1rem); letter-spacing:.06em; text-transform:uppercase;
  border-bottom:1px solid var(--line-ink); padding-bottom:.75rem}
/* multicolumn, not grid: a grid row is as tall as its tallest section and leaves
   craters next to Suppen. Columns just flow. */
.menu-cols{columns:2; column-gap:clamp(1.6rem,4vw,3.4rem)}
@media (max-width:820px){ .menu-cols{columns:1} }

.msec{break-inside:avoid; margin:0 0 2rem;
  scroll-margin-top:calc(var(--bar) + var(--navh) + 5rem)}
.msec h4{margin:0 0 .2rem; font-family:var(--didone); font-weight:500;
  font-size:clamp(1.15rem,2.1vw,1.5rem); letter-spacing:.03em}
.msec-unit{margin:0 0 .7rem; font-family:var(--mono); font-size:.58rem; letter-spacing:.18em; text-transform:uppercase; color:#7b8288}
.msec-note{margin:0 0 .8rem; font-style:italic; color:#4c5459; font-size:1rem; line-height:1.5}
.callout{margin:0 0 .9rem; padding:.7rem .9rem; border-left:2px solid #8a6a24; background:rgba(138,106,36,.07);
  font-size:1rem; line-height:1.5; color:#3d454a}

.items{list-style:none; margin:0; padding:0; display:grid; gap:.85rem}
.items li{display:grid; grid-template-columns:minmax(0,1fr) auto; gap:.3rem .8rem; align-items:baseline}
.iname{font-size:clamp(1.02rem,1.6vw,1.14rem); line-height:1.3}
.iprice{font-family:var(--mono); font-size:.92rem; white-space:nowrap; font-variant-numeric:tabular-nums}
.idesc{grid-column:1/-1; margin:0; font-size:.98rem; line-height:1.45; color:#5a6267; max-width:56ch}
.codes{font-family:var(--mono); font-size:.58em; letter-spacing:.06em; color:#8a6a24; vertical-align:.35em; margin-left:.35em}
.sig-mark{display:inline-block; margin-left:.45em; font-family:var(--mono); font-size:.52em;
  letter-spacing:.14em; text-transform:uppercase; color:#8a6a24; border:1px solid #c3a86a; padding:.14em .38em; vertical-align:.2em}
.isize{font-family:var(--mono); font-size:.58rem; letter-spacing:.12em; color:#7b8288; margin-right:.5em}

/* two-size drink tables — real columns */
.tbl-wrap{overflow-x:auto; max-width:100%}
table.sizes{width:100%; border-collapse:collapse; font-size:1rem}
table.sizes caption{text-align:left; font-family:var(--mono); font-size:.58rem; letter-spacing:.18em;
  text-transform:uppercase; color:#7b8288; padding-bottom:.5rem}
table.sizes th,table.sizes td{text-align:left; padding:.5rem .5rem; border-bottom:1px solid var(--line-ink); vertical-align:baseline}
table.sizes thead th{font-family:var(--mono); font-weight:400; font-size:.58rem; letter-spacing:.16em;
  text-transform:uppercase; color:#7b8288; border-bottom:1px solid var(--paper-ink)}
table.sizes td.p,table.sizes th.p{text-align:right; white-space:nowrap; font-variant-numeric:tabular-nums; min-width:6.5rem}
table.sizes td.p .isize{display:block; margin:0 0 .1rem}
table.sizes th[scope="row"]{font-weight:400; padding-left:0}
table.sizes .tdesc{display:block; color:#5a6267; font-size:.94rem; margin-top:.15rem}

/* legend */
.legend{--n:12px; border-color:#8a6a24; margin:2.6rem 0 0; padding:clamp(1.2rem,3vw,2rem)}
.legend::before{border-color:#8a6a24; opacity:.4}
.legend h3{margin:0 0 .6rem; font-family:var(--didone); font-weight:400; font-size:clamp(1.2rem,2.3vw,1.6rem)}
.legend-note{margin:0 0 1.2rem; max-width:62ch; color:#5a6267; font-size:.98rem; line-height:1.55}
.legend-cols{display:grid; gap:1.4rem 2.4rem; grid-template-columns:repeat(auto-fit,minmax(min(100%,18rem),1fr))}
.legend-cols h4{margin:0 0 .6rem; font-family:var(--mono); font-size:.6rem; letter-spacing:.2em; text-transform:uppercase; color:#8a6a24}
.legend-cols dl{margin:0; display:grid; grid-template-columns:2.6em 1fr; gap:.3rem .7rem; font-size:.95rem}
.legend-cols dt{font-family:var(--mono); font-size:.8rem; color:#8a6a24}
.legend-cols dd{margin:0; color:#4c5459}
.menu-fine{margin:1.8rem 0 0; color:#7b8288; font-size:.9rem; line-height:1.5; max-width:70ch}

/* ── Galerie ────────────────────────────────────────────── */
.filters{display:flex; flex-wrap:wrap; gap:.5rem; margin-top:1.6rem}
.filt{font-family:var(--mono); font-size:.62rem; letter-spacing:.2em; text-transform:uppercase;
  display:inline-flex; align-items:center; min-height:42px;
  background:transparent; color:var(--haze); border:1px solid var(--line);
  padding:.6rem 1rem; cursor:pointer; transition:color .25s,border-color .25s}
.filt b{font-weight:300; opacity:.55; margin-left:.5em}
.filt:hover{color:var(--paper); border-color:#3a4145}
.filt.is-on{color:var(--ink); background:var(--gold); border-color:var(--gold)}

/* 31 photographs at 112px read as contact-sheet thumbnails, not as a gallery — the client's word
   was "бедно". Six columns on a desktop gives roughly 240px a frame, which is big enough to see
   the food; two on a phone. Portraits get a taller span so the wall staggers instead of forcing
   every frame into a square. */
.grid{display:grid; grid-template-columns:repeat(6,minmax(0,1fr)); gap:4px; padding:0 4px 4px}
/* Only 6 / 4 / 2 columns — no 3-column step. The spread in app.js guarantees no two frames of
   the same subject touch left-right or up-down, and it can only do that for a known set of
   column counts; a 3-column breakpoint would reintroduce the pairs the client spotted. */
@media (max-width:1100px){.grid{grid-template-columns:repeat(4,minmax(0,1fr))}}
@media (max-width:620px){.grid{grid-template-columns:repeat(2,minmax(0,1fr)); gap:3px}}
/* One aspect for every tile: mixing 3:2 and 2:3 spans against auto-sized rows never lines up
   (a 2-row span of a 160px row is 324px, a real portrait is 360px). Uniform 4:3 reads as a
   deliberate wall, and the lightbox still shows each frame uncropped. */
.grid figure{margin:0; position:relative; aspect-ratio:4/3}
.grid button{display:block; width:100%; height:100%; padding:0; border:0; background:#0d1113; cursor:pointer; overflow:hidden}
.grid img{width:100%; height:100%; object-fit:cover; display:block;
  filter:contrast(1.1) saturate(.72) brightness(.8); transition:filter .45s ease, transform .6s ease}
.grid button:hover img,.grid button:focus-visible img{filter:none; transform:scale(1.05)}
.grid button:focus-visible{outline:2px solid var(--gold); outline-offset:-2px}
.grid[data-filter="Restaurant"] figure:not([data-g="Restaurant"]),
.grid[data-filter="Armin"] figure:not([data-g="Armin"]){display:none}

/* ── Reservierung ───────────────────────────────────────────
   One grid instead of three stacked half-width blocks: the two ways to reach
   the house on the left (the phone loudest, because that is what closes a
   reservation), the written request as one bordered panel on the right. Both
   columns are stretched, so the section has no empty half and both edges land
   on the same line. */
/* Both ways to book span the full measure: the two contact cards as one ruled
   row of equal height, the written request as one full-width panel under them.
   Nothing is half a section wide any more, and the phone stays the loudest
   thing on the page. */
.res-layout{display:grid; gap:clamp(1rem,2vw,1.5rem); margin:1.8rem 0 0}
.res-side{display:grid; gap:clamp(1rem,2vw,1.5rem); grid-auto-rows:1fr;
  grid-template-columns:repeat(2,minmax(0,1fr))}
@media (max-width:760px){ .res-side{grid-template-columns:1fr; grid-auto-rows:auto} }
.res-card{padding:clamp(1.2rem,3vw,1.9rem); display:flex; flex-direction:column}
.res-k{margin:0 0 .5rem; font-family:var(--mono); font-size:.6rem; letter-spacing:.2em; text-transform:uppercase; color:var(--gold)}
.res-k-2{margin-top:1.6rem}
.res-big{display:inline-block; font-family:var(--didone); font-size:clamp(1.5rem,3.6vw,2.4rem);
  line-height:1.15; text-decoration:none; margin:0 0 .8rem; border-bottom:1px solid rgba(201,161,92,.45); word-break:break-word}
/* the phone number is the loudest thing in the section, by a clear step */
.res-phone .res-big{font-size:clamp(1.9rem,4.4vw,3.1rem); align-self:start}
.res-big.res-mail{font-size:clamp(1.05rem,2.2vw,1.5rem)}
.res-big:hover{color:var(--gold)}
.form-note{margin:0 0 .4rem; max-width:60ch; color:#b6b0a4; font-size:.98rem}

.form{display:grid; gap:1rem; grid-template-columns:repeat(3,minmax(0,1fr)); margin-top:1.4rem}
@media (max-width:960px){ .form{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (max-width:560px){ .form{grid-template-columns:1fr} }
.form label{display:grid; gap:.45rem; font-family:var(--mono); font-size:.6rem; letter-spacing:.2em; text-transform:uppercase; color:var(--haze)}
.form .wide{grid-column:1/-1}
.form input,.form select,.form textarea{
  font-family:var(--serif); font-size:1.05rem; color:var(--paper);
  background:#0c1114; border:1px solid var(--line); padding:.7rem .8rem; width:100%; max-width:100%; border-radius:0}
.form textarea{resize:vertical}
.form input:focus,.form select:focus,.form textarea:focus{outline:1px solid var(--gold); border-color:var(--gold)}
.form button{
  grid-column:1/-1; justify-self:start; font-family:var(--mono); font-size:.66rem; letter-spacing:.22em; text-transform:uppercase;
  background:var(--gold); color:var(--ink); border:0; padding:.9rem 2rem; cursor:pointer}
.form button:hover{background:#dcb676}

/* ── Anfahrt ────────────────────────────────────────────────
   Two columns now — the facts and the way here. The host's portrait is gone from this
   section, so a third column would only reopen the empty right-hand side. */
.anf-grid{display:grid; gap:clamp(1.2rem,3vw,2.5rem); align-items:start; margin-top:1.8rem;
  grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
@media (max-width:760px){ .anf-grid{grid-template-columns:1fr} }
.anf-col{display:flex; flex-direction:column}
.anf-card{padding:clamp(1.2rem,3vw,1.8rem); display:flex; flex-direction:column}
.anf-card .note{margin-top:auto; padding-top:1.2rem; font-size:.95rem}
.anf-note{padding-top:1.1rem; font-size:.95rem}
.cta-block{display:block; text-align:center; padding-block:1.05rem}
/* the button that opens the card — a button, not a link, so it needs the .cta box
   explicitly (font-family and cursor do not inherit into form controls) */
/* heading and the button share a row; the button drops under the heading when the row
   runs out of width, which is what happens on a phone */
/* Heading and button share the top row on a wide screen; on a phone the button belongs
   AFTER the sentence that explains what it opens, not wedged between the two. A grid gets
   both from one source order — the button is the header's last child either way, and only
   its placement changes. Flexbox could not: the button and the prose would have to sit in
   different containers, and `order` does not reach across one. */
.menu-head{display:grid; grid-template-columns:1fr auto; column-gap:2rem; align-items:start}
.menu-head h2{grid-column:1; grid-row:1}
.menu-head .menu-intro{grid-column:1; grid-row:2}
.menu-head .menu-count{grid-column:1; grid-row:3}
.menu-head #menuToggle{grid-column:2; grid-row:1; justify-self:end; align-self:center}
@media (max-width:760px){
  .menu-head{grid-template-columns:1fr}
  /* and the button carries a thumb here, not a cursor — 40px was under the 44px minimum */
  .menu-head #menuToggle{grid-column:1; grid-row:4; justify-self:start;
    margin-top:1.1rem; min-height:44px}
}
button.cta{border:0; cursor:pointer; font-family:var(--mono)}
.modes{list-style:none; margin:1rem 0 0; padding:0; display:grid; gap:.5rem}
.modes a{display:flex; justify-content:space-between; align-items:center; gap:1rem;
  text-decoration:none; color:#ded7c9; border-bottom:1px solid var(--line);
  padding:.55rem 0; font-family:var(--mono); font-size:.62rem; letter-spacing:.16em; text-transform:uppercase}
.modes a::after{content:"→"; color:var(--gold)}
.modes a:hover{color:var(--gold); border-color:var(--gold)}
/* the fact rows carry a hairline each and spread over the full column height:
   four evenly ruled rows read as a printed information panel, where the same
   four rows bunched at the top read as a hole in the layout */
/* no column gap, so the hairline over each row runs unbroken across both cells */
/* Rows sit one under another. `flex:1 1 auto` + `align-content:space-between` spread
   four rows over the height of the tallest neighbouring column, which is what left
   several hundred pixels of black between "Opening hours" and "Phone". */
.facts{margin:0; display:grid; grid-template-columns:minmax(0,7.5rem) 1fr;
  gap:1rem 0; align-content:start}
.facts dt,.facts dd{padding-top:.9rem; border-top:1px solid var(--line)}
.facts dd{padding-left:1.2rem}
.facts dt{font-family:var(--mono); font-size:.6rem; letter-spacing:.2em; text-transform:uppercase; color:var(--haze)}
.facts dd{margin:0; font-size:1.08rem; line-height:1.5; color:#ded7c9}
.facts a{text-decoration:none; border-bottom:1px solid rgba(201,161,92,.45)}
@media (max-width:560px){
  .facts{grid-template-columns:1fr; gap:.15rem}
  .facts dd{margin-bottom:.9rem; padding-top:.2rem; border-top:0}
}
.map-links{display:flex; gap:.6rem; flex-wrap:wrap; margin:.8rem 0 0}
.map-links .cta{flex:1 1 8rem; text-align:center}

/* ── Footer ─────────────────────────────────────────────── */
.foot{border-top:1px solid var(--line); padding-bottom:calc(var(--bar) + 3rem)}
/* two columns on the same grid as Anfahrt above it: the contact rows no longer
   sit in the left half with the legal notice stranded underneath */
/* Impressum is its own block now, and the footer is a single line — the contact rows that used
   to sit here duplicated the Anfahrt list one screen above. */
/* ── Impressum & Datenschutz ─────────────────────────────
   A definition list, because that is what this is: a fixed set of legally named fields
   and their values. Fields the owner still has to supply are marked rather than faked —
   an Impressum with an invented company name is worse than one with a visible gap. */
.imp-list{margin:1.1rem 0 0; display:grid; grid-template-columns:minmax(12rem,18rem) 1fr;
  gap:.55rem 2rem; align-items:baseline}
.imp-list dt{font-family:var(--mono); font-size:.62rem; letter-spacing:.16em;
  text-transform:uppercase; color:var(--gold); padding-top:.2em}
.imp-list dd{margin:0; font-size:.94rem; line-height:1.62}
.imp-list dd a{color:inherit}
.imp-todo{display:inline-block; padding:.1em .5em; border:1px dashed currentColor;
  border-radius:2px; opacity:.55; font-style:italic}
.imp-warn{margin-top:1.8rem}
/* the second heading follows a list whose last row can wrap to two lines, so it needs its
   own air rather than inheriting the tight rhythm of the rows above it */
.impressum h3 + .imp-list{margin-top:1.1rem}
.impressum .imp-list + h3{margin-top:2.4rem}   /* .impressum h3 below sets margin:0, and wins on specificity */
@media (max-width:760px){
  .imp-list{grid-template-columns:1fr; gap:.15rem 0}
  .imp-list dt{padding-top:.9rem}
  .imp-list dt:first-of-type{padding-top:0}
}

.impressum-sec{padding-block:clamp(2.5rem,6svh,4rem)}
.impressum{padding:clamp(1.2rem,3vw,1.9rem); margin:0}
.impressum .note{font-size:.95rem}
.impressum strong{font-weight:500; color:#ded7c9}
.impressum h3{margin:0 0 .7rem; font-family:var(--didone); font-weight:400; font-size:clamp(1.1rem,2.2vw,1.45rem); color:var(--gold)}
.impressum .note{max-width:80ch}
.foot-fine{margin:0; color:#585d60; font-size:.9rem; line-height:1.5}

/* ── lightbox ───────────────────────────────────────────── */
.lb{position:fixed; inset:0; z-index:90; background:rgba(3,4,5,.97); display:grid; place-items:center;
  padding:calc(var(--bar) + 3.4rem) clamp(1rem,6vw,5rem)}
.lb[hidden]{display:none}
.lb-fig{margin:0; max-width:100%; max-height:100%; display:grid; place-items:center}
.lb-fig img{max-width:100%; max-height:76svh; object-fit:contain; display:block}
.lb-cap{position:absolute; left:0; right:0; bottom:calc(var(--bar) + 1rem); text-align:center; margin:0;
  font-family:var(--mono); font-size:.62rem; letter-spacing:.22em; text-transform:uppercase; color:var(--haze)}
.lb-x,.lb-nav{position:absolute; background:rgba(6,8,10,.6); border:1px solid var(--line); color:var(--paper); cursor:pointer;
  font-family:var(--mono); font-size:.7rem; letter-spacing:.18em; padding:.6rem .9rem}
.lb-x:hover,.lb-nav:hover{border-color:var(--gold); color:var(--gold)}
.lb-x{top:calc(var(--bar) + 1rem); right:clamp(1rem,4vw,3rem); text-transform:uppercase}
.lb-nav{top:50%; translate:0 -50%; font-size:1rem; padding:.7rem 1rem}
.lb-prev{left:clamp(.4rem,2vw,2rem)}
.lb-next{right:clamp(.4rem,2vw,2rem)}
body.lb-open{overflow:hidden}

/* the progress hairline is the only scroll-driven animation left */
.no-sdt .progress{display:none}

/* ── reduced motion: no snapping, no reveal, nothing that moves ──
   Snapping is animated scrolling the visitor did not ask for, so it is switched
   off entirely here and the chapters become plain stacked blocks. */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation:none !important; transition:none !important}
  .progress{display:none}
  .chapter{height:auto; overflow:visible; border-bottom:1px solid var(--line);
    scroll-margin-top:calc(var(--bar) + var(--navh) + 1rem)}
  .stage{position:static; height:auto; padding:calc(var(--bar) + 4.5rem) var(--pad) 4rem;
    display:block !important}
  .frame{position:relative; inset:auto; top:auto; translate:none; max-height:none;
    margin-bottom:2.2rem; aspect-ratio:2.39; flex:none !important}
  .frame img{transform:none !important}
  .say,.say-mid{position:static; left:auto; right:auto; top:auto; bottom:auto; translate:none;
    max-width:min(46rem,100%); text-align:left; padding:0; display:block}
  .say::before{display:none}
  .say>*{opacity:1 !important; translate:none !important; filter:none !important}
  .say-br .line,.say-tr .line{margin-left:0}
  .line{font-size:clamp(1.4rem,2.8vw,2.3rem)}
  .hero-facts{position:static; left:auto; right:auto; bottom:auto; text-align:left; margin-top:2rem;
    padding-inline:0; background:none}
  .hf-cta{justify-content:flex-start}
  .scroll-hint{display:none}
  .grid img{filter:contrast(1.04) saturate(.9) brightness(.94)}
  /* same specificity as the portrait rules above, which would otherwise keep
     their max-height and their inner padding here */
  @media (orientation:portrait){
    .frame,.chapter:not(#title) .frame{aspect-ratio:3/2; max-height:none}
    .chapter:not(#title) .say{padding:0}
  }
}
