/* chummu — das ganze css der seite, eine datei.
   farben, schrift und bildmarke sind die der etikette. alles kantig, kein
   radius, keine schatten, keine verläufe. mobile first; breitere ansichten nur
   per @media.

   aufbau: schrift · tokens · grundlage · bausteine · kopf · hero · ort ·
   geschichte · jahrgang · zwischenbild · lehrjahr · weine · kontakt · fuss ·
   unterseiten · bewegung · druck.

   farbfolge der startseite: hero · ort (hell) · geschichte (dunkel) ·
   jahrgang (muscat) · zwischenbild · lehrjahr (dunkel) · weine (hell) ·
   kontakt (dunkel) · fuss.

   bewegung: alles hängt an .bewegt (setzt das inline-script im <head>, nicht
   mit ?edit / ?feedback) UND an prefers-reduced-motion: no-preference.
   scrollgebundenes zusätzlich an @supports (animation-timeline: view()).
   ohne js, im editor, bei «weniger bewegung» und in browsern ohne
   scroll-timelines steht alles fertig da. nur transform/translate/scale,
   opacity und clip-path — dazu die textfüllung des manifests (ein absatz). */

/* ————— schrift ————— */

@font-face {
  font-family: 'Archivo';
  src: url('/assets/fonts/archivo-latin-var.woff2') format('woff2');
  font-weight: 400 600;
  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;
}

/* ersatzschriften, auf archivo 400 vermessen (laufweite eines typischen absatzes,
   ascender 878, descender 210): der text springt beim schriftwechsel kaum.
   arial für macos, ios und windows; roboto für android. */
@font-face {
  font-family: 'Archivo Ersatz';
  src: local('Arial'), local('ArialMT');
  size-adjust: 98.33%;
  ascent-override: 89.29%;
  descent-override: 21.36%;
  line-gap-override: 0%;
}
@font-face {
  font-family: 'Archivo Ersatz Roboto';
  src: local('Roboto'), local('Roboto-Regular');
  size-adjust: 99.11%;
  ascent-override: 88.59%;
  descent-override: 21.19%;
  line-gap-override: 0%;
}

/* ————— registrierte properties (zählwerk, textfüllung) ————— */

@property --zahl {
  syntax: '<integer>';
  inherits: false;
  initial-value: 0;
}

@property --fuellung {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 120%;
}

/* ————— tokens ————— */

:root {
  --schiefer: #12150e;
  --kalk: #efede2;
  --kalk-70: rgba(239, 237, 226, 0.7);
  --muscat: #e6dea0;
  --chasselas: #e1e6c6;

  /* abgeleitet, keine neuen farben: deckkraft und die platzhalter-fläche */
  --schiefer-70: rgba(18, 21, 14, 0.7);
  --platzhalter: #1e221a;
  --linie: rgba(239, 237, 226, 0.16);
  --linie-hell: rgba(18, 21, 14, 0.2);

  --schrift: 'Archivo', 'Archivo Ersatz', 'Archivo Ersatz Roboto', system-ui, sans-serif;

  /* typo-skala */
  --t-wortmarke: clamp(3rem, min(24vw, (100vw - 2 * var(--rand)) / 3.8), 13.5rem);
  --t-ziffer: clamp(3.5rem, 2rem + 8vw, 10rem);
  --t-zahl: clamp(4rem, 2rem + 9vw, 10rem);
  --t-manifest: clamp(1.625rem, 1.1rem + 2.4vw, 3rem);
  --t-titel: clamp(2rem, 1.3rem + 3.2vw, 3.75rem);
  --t-zitat: clamp(1.375rem, 1rem + 1.6vw, 2.125rem);
  --t-h3: clamp(1.25rem, 1rem + 1vw, 1.625rem);
  --t-meta: 0.875rem;

  /* raster: 72rem, gedanklich 12 spalten */
  --rand: clamp(1rem, 4vw, 3rem);
  --abstand: clamp(4rem, 1.6rem + 7.5vw, 10rem); /* 64 px mobil … 160 px breit */
  --breite: 72rem;
  --gutter: clamp(1rem, 3vw, 2rem);
  --stufe: clamp(2rem, 0.5rem + 5vw, 6rem); /* terrassen-versatz, senkrecht */
  --mass: 44ch; /* ch misst die «0»; laufender text ist schmaler — 44ch ergeben rund 60 zeichen */
  --kopf-h: 3.5rem;

  /* bewegung */
  --ease-aus: cubic-bezier(0.19, 1, 0.22, 1);
  --ease-ruhig: cubic-bezier(0.22, 0.61, 0.36, 1);
  --dauer: 400ms;
  --dauer-auftritt: 600ms;
  --weg: 12px;
}

/* ————— grundlage ————— */

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

html {
  color-scheme: dark;
  background: var(--schiefer);
  color: var(--kalk);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: var(--kopf-h);
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

body {
  margin: 0;
  overflow-x: hidden;
  overflow-x: clip;
  background: var(--schiefer);
  font-family: var(--schrift);
  font-weight: 400;
  font-size: clamp(1.0625rem, 1rem + 0.25vw, 1.1875rem); /* 17 … 19 px */
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

h1,
h2,
h3,
p,
ol,
ul,
figure,
blockquote {
  margin: 0;
}

h1,
h2,
h3 {
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.05;
  text-wrap: balance;
}

p {
  text-wrap: pretty;
}

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

img {
  height: auto;
}

picture {
  display: block;
}

a {
  color: var(--muscat);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
}

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

button {
  font: inherit;
  color: inherit;
}

/* fokus: muscat aussen, schiefer innen — sichtbar auf dem dunklen und dem hellen grund */
:focus-visible {
  outline: 2px solid var(--muscat);
  outline-offset: 2px;
  box-shadow: 0 0 0 4px var(--schiefer);
}

/* auf muscat-grund umgekehrt: umriss schiefer, ring muscat */
.jahrgang :focus-visible {
  outline-color: var(--schiefer);
  box-shadow: 0 0 0 4px var(--muscat);
}

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

/* metadaten: hero-zeile, jahreszeiten, fakten, bildtexte */
.meta {
  font-weight: 500;
  font-size: var(--t-meta);
  line-height: 1.5;
  color: var(--kalk-70);
  font-variant-numeric: tabular-nums;
}

/* leere felder aus den listen blenden sich aus. :not(img) ist pflicht —
   ein <img> ist immer :empty, sonst verschwänden die bilder der weine. */
[data-field]:not(img):empty {
  display: none;
}

/* ein leer gelassener bildtext (zwischenbild, kapitel, chummudorf) lässt
   keine lücke — ausser im editor: dort bleibt er als anklickbares feld
   stehen, sonst liesse er sich auf der seite nicht wieder füllen */
html:not([data-modus='bearbeiten']) figcaption:empty {
  display: none;
}

[data-modus='bearbeiten'] figcaption:empty {
  min-width: 8ch;
  min-height: 1.5em;
  min-height: 1lh;
}

/* data-split: cms.js schreibt <span class="line"> ohne leerraum dazwischen —
   ohne display:block kleben die zeilen aneinander («generationen,ein»).
   darum immer, nicht nur mit bewegung. */
[data-split] .line {
  display: block;
}

/* ————— skip-link ————— */

.skip {
  position: absolute;
  z-index: 20;
  left: var(--rand);
  top: 0;
  transform: translateY(-120%);
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  padding: 0.5rem 1rem;
  background: var(--schiefer);
  color: var(--muscat);
  font-weight: 500;
}

.skip:focus-visible {
  transform: translateY(0.5rem);
}

/* ————— bausteine ————— */

.sektion {
  padding: var(--abstand) var(--rand);
}

/* zwei dunkle sektionen hintereinander (heute keine — die farbfolge wechselt
   überall): ohne farbwechsel zählt der abstand nur einmal. scroll-margin hält
   den anker frei vom kopf. */
.sektion.dunkel + .sektion.dunkel {
  padding-top: 0;
  scroll-margin-top: var(--abstand);
}

.sektion__innen {
  max-width: var(--breite);
  margin-inline: auto;
}

.hell {
  background: var(--kalk);
  color: var(--schiefer);
  color-scheme: light;
}

.hell a {
  color: var(--schiefer);
}

.hell .meta,
.hell .kicker {
  color: var(--schiefer-70);
}

/* kicker: kein versal-label, sondern eine 2rem-haarlinie davor */
.kicker {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: clamp(1rem, 2.5vw, 1.5rem);
  color: var(--kalk-70);
  font-weight: 500;
  font-size: var(--t-meta);
  line-height: 1.5;
}

.kicker::before {
  content: '';
  flex: none;
  width: 2rem;
  height: 1px;
  background: currentColor;
}

.titel {
  margin-bottom: clamp(1.75rem, 4vw, 3rem);
  font-size: var(--t-titel);
}

.fliesstext {
  max-width: var(--mass);
}

.fliesstext p + p {
  margin-top: 1em;
}

.bild {
  background: var(--platzhalter);
}

/* 4:5 fest: die mediathek schneidet nicht zu, ein getauschtes foto mit anderem
   verhältnis würde sonst das raster sprengen */
.bild img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
}

/* bildtext unter einem bild (chummudorf, kapitel): «Symbolbild» */
.bildtext {
  margin-top: 0.625rem;
}

/* ————— bildmarke «hang» ————— */

.bildmarke {
  color: var(--muscat);
  height: auto;
  pointer-events: none;
}

/* ————— kopf ————— */

.kopf {
  position: fixed;
  z-index: 10;
  inset: 0 0 auto;
  height: var(--kopf-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-inline: var(--rand);
  background: var(--schiefer);
  border-bottom: 1px solid var(--linie);
}

/* fortschritt: die haarlinie füllt sich in muscat (nur mit scroll-timelines) */
.kopf::after {
  content: '';
  position: absolute;
  inset: auto 0 -1px;
  display: none;
  height: 1px;
  background: var(--muscat);
  transform-origin: 0 50%;
}

/* auf der startseite blendet der kopf erst nach dem hero ein (site.js).
   ohne javascript, im editor und mit tastaturfokus ist er immer da. */
.js .kopf[data-kopf='einblenden']:not(.kopf--sichtbar):not(:focus-within) {
  opacity: 0;
  pointer-events: none;
}

/* offenes menü: der kopf bleibt da, und die links bekommen die pointer-events
   zurück (das popover erbt sie vom kopf, obwohl es im top-layer liegt).
   eigene regel — ohne :has() fiele sonst die ganze regel darüber weg */
.js .kopf[data-kopf='einblenden']:has(.menue:popover-open) {
  opacity: 1;
  pointer-events: auto;
}

.kopf__marke {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  color: var(--muscat);
  font-weight: 600;
  font-size: 1.5rem;
  letter-spacing: -0.05em;
  line-height: 0.85;
  text-decoration: none;
  view-transition-name: marke;
}

.kopf__nav ul,
.menue ul {
  display: flex;
  gap: clamp(0.5rem, 2.5vw, 2rem);
  padding: 0;
  list-style: none;
}

.kopf__nav a,
.kopf__menue {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  padding-inline: 0.25rem;
  color: var(--kalk);
  font-weight: 500;
  font-size: 0.9375rem;
  text-decoration: none;
}

.kopf__menue {
  display: none;
  margin: 0 -0.25rem 0 0;
  padding-inline: 0.25rem;
  border: 0;
  background: none;
  cursor: pointer;
}

.kopf__nav a:hover,
.kopf__menue:hover,
.menue a:hover {
  color: var(--muscat);
}

/* unterstrich wächst von links (hover und tastatur) — rückmeldung, keine deko */
.kopf__nav a > span,
.kopf__menue > span,
.menue a > span,
.fuss a > span {
  padding-bottom: 2px;
  background: linear-gradient(currentColor 0 0) 0 100% / 0 1px no-repeat;
}

.kopf__nav a:is(:hover, :focus-visible) > span,
.kopf__menue:is(:hover, :focus-visible) > span,
.menue a:is(:hover, :focus-visible) > span,
.fuss a:is(:hover, :focus-visible) > span {
  background-size: 100% 1px;
}

/* menü: unter 48em ein knopf mit nativem popover. ohne popover-unterstützung
   bleibt es beim link «kontakt» wie bisher. */
.menue {
  display: none;
  position: fixed;
  inset: var(--kopf-h) var(--rand) auto auto;
  width: auto;
  min-width: 12rem;
  margin: 0;
  padding: 0.5rem 1.25rem;
  /* bei wenig höhe (400 % zoom) scrollt das menü, statt unten abzuschneiden */
  max-height: calc(100vh - var(--kopf-h));
  max-height: calc(100dvh - var(--kopf-h));
  overflow-y: auto;
  border: 1px solid var(--linie);
  background: var(--schiefer);
  color: var(--kalk);
}

.menue:popover-open {
  display: block;
}

.menue ul {
  flex-direction: column;
  gap: 0;
}

.menue a {
  display: flex;
  align-items: center;
  min-height: 2.75rem;
  color: var(--kalk);
  font-weight: 500;
  font-size: 1.25rem;
  text-decoration: none;
}

@media (max-width: 47.99em) {
  .kopf__weit {
    display: none;
  }

  @supports selector(:popover-open) {
    .kopf__nav {
      display: none;
    }

    .kopf__menue {
      display: inline-flex;
    }
  }
}

/* ————— hero ————— */

.hero {
  --marke-b: min(72vw, 46rem);
  --marke-unten: clamp(1.25rem, 4svh, 3rem);
  position: relative;
  isolation: isolate;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: calc(var(--kopf-h) + 2rem) var(--rand)
    calc(var(--marke-unten) + var(--marke-b) * 0.27 + clamp(1.5rem, 4svh, 3rem));
  overflow: hidden;
  overflow: clip;
  background: var(--platzhalter);
}

.hero__bg {
  position: absolute;
  z-index: -2;
  inset: 0;
}

.hero__bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* flächig abgedunkelt, kein verlauf. α .65 hält aa auch über einem weissen
   bildpixel: kalk 4.87:1, muscat 4.17:1 (grosse schrift). wer α senkt, misst
   am hellsten bereich unter dem text nach (BILDER.md). */
.hero::after {
  content: '';
  position: absolute;
  z-index: -1;
  inset: 0;
  background: rgb(18 21 14 / 0.65);
  pointer-events: none;
}

/* die meta-zeile steht auf dem foto: kalk statt kalk-70, sonst reicht der kontrast nicht */
.hero__zeile {
  margin-bottom: clamp(0.75rem, 2vw, 1.25rem);
  color: var(--kalk);
}

.wortmarke {
  color: var(--muscat);
  font-weight: 600;
  /* «chummu» ist 3.72 em breit. /3.8 lässt auch unter 320 px luft: einzeilig im
     normalfall, umbrechen nur unter einem textabstands-override (wcag 1.4.12) */
  font-size: var(--t-wortmarke);
  letter-spacing: -0.05em;
  line-height: 0.85;
  overflow-wrap: anywhere;
}

.hero__satz {
  margin-top: clamp(1rem, 3vw, 1.75rem);
  max-width: 28ch;
  color: var(--kalk);
  font-size: clamp(1.1875rem, 1rem + 1vw, 1.625rem);
  line-height: 1.35;
  text-wrap: balance;
}

.bildmarke--hero {
  position: absolute;
  right: -2px; /* läuft sicher aus dem bild, ohne antialiasing-spalt */
  bottom: var(--marke-unten);
  width: var(--marke-b);
}

/* ————— ort (hell) ————— */

.ort__raster {
  display: grid;
  gap: clamp(2rem, 6vw, 3rem) var(--gutter);
}

/* schmal: die trockenmauer rückt rechts ein, das chummudorf darunter geht
   über die ganze breite — zwei stufen statt eines bildblocks. auf dem
   telefon ist die mauer ohnehin voll breit, dort trennt der abstand */
.ort__bild {
  width: min(100%, 26rem);
  justify-self: end;
}

.ort__dorf {
  margin-top: clamp(1rem, 4vw, 2rem);
}

@media (min-width: 56em) {
  /* terrassen-versatz: kicker und titel ab spalte 1, text ab spalte 2,
     das bild rechts noch eine stufe tiefer */
  .ort__raster {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    row-gap: 0;
  }

  .ort__kopf {
    grid-column: 1 / 8;
  }

  .ort__text {
    grid-column: 2 / 7;
    grid-row: 2;
  }

  .ort__bild {
    grid-column: 8 / 13;
    grid-row: 2;
    align-self: start;
    justify-self: stretch;
    width: auto;
    margin-top: var(--stufe);
  }

  .ort__dorf {
    grid-column: 1 / -1;
    grid-row: 3;
    margin-top: clamp(4rem, 8vw, 7rem);
  }
}

/* chummudorf: ein foto über die ganze breite, 3:2 fest — ein getauschtes
   foto mit anderem verhältnis wird zugeschnitten, das raster bleibt */
.ort__dorf .bild img {
  aspect-ratio: 3 / 2;
}

/* ————— geschichte (dunkel) ————— */

.manifest {
  max-width: 24ch;
  font-weight: 500;
  font-size: var(--t-manifest);
  letter-spacing: -0.02em;
  line-height: 1.2;
}

.manifest p {
  text-wrap: balance;
}

.geschichte__titel {
  margin-top: var(--stufe);
}

.kapitel {
  position: relative;
  margin-top: clamp(1rem, 4vw, 3rem);
  padding: 0;
  list-style: none;
  counter-reset: kapitel;
}

.kapitel__eintrag {
  counter-increment: kapitel;
  display: grid;
  gap: clamp(1.5rem, 4vw, 2.5rem);
  padding-block: clamp(2.5rem, 7vw, 6rem);
  border-top: 1px solid var(--linie);
}

/* nach dem letzten kapitel zählt nur der abstand der sektion (flächenwechsel) */
.kapitel__eintrag:last-child {
  padding-bottom: 0;
}

/* mobil: ziffer und titel nebeneinander, darunter die marke */
.kapitel__kopf {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: end;
  gap: 1rem 1rem;
}

/* die ziffer ist kein text im html: css-counter, für screenreader stumm */
.kapitel__kopf::before {
  content: counter(kapitel, upper-roman);
  content: counter(kapitel, upper-roman) / '';
  color: var(--muscat);
  font-weight: 600;
  font-size: 3.5rem;
  letter-spacing: -0.05em;
  line-height: 0.85;
  font-variant-numeric: tabular-nums;
}

.kapitel__titel {
  font-size: var(--t-h3);
}

.kapitel__marke {
  grid-column: 1 / -1;
  width: 4.5rem;
  color: var(--linie);
}

.kapitel__marke .dran {
  color: var(--muscat);
}

.kapitel__inhalt {
  display: grid;
  gap: clamp(1.5rem, 4vw, 2.5rem);
}

.kapitel__zitat {
  max-width: 28ch;
  font-weight: 500;
  font-size: var(--t-zitat);
  line-height: 1.25;
  letter-spacing: -0.01em;
}

@media (min-width: 56em) {
  .kapitel__eintrag {
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
    gap: clamp(2.5rem, 6vw, 6rem);
  }

  /* sticky: jeder kopf klebt nur innerhalb seines kapitels — der nächste
     schiebt ihn weg. reines css. */
  .kapitel__kopf {
    position: sticky;
    top: calc(var(--kopf-h) + 2rem);
    align-self: start;
    grid-template-columns: minmax(0, 1fr);
    gap: 1.25rem;
  }

  .kapitel__kopf::before {
    font-size: var(--t-ziffer);
  }

  /* zeitstrahl: 1 px muscat links aussen durch alle drei kapitel */
  .kapitel::before {
    content: '';
    position: absolute;
    inset: 0 auto 0 calc(-1 * clamp(0.75rem, 2vw, 1.5rem));
    width: 1px;
    background: var(--muscat);
    transform-origin: 50% 0;
  }
}

/* ————— jahrgang (muscat-band) ————— */

.jahrgang {
  background: var(--muscat);
  color: var(--schiefer);
  color-scheme: light;
}

.jahrgang .meta {
  color: var(--schiefer-70);
}

.zahlen {
  display: grid;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--linie-hell);
}

.zahl {
  padding-block: clamp(1.5rem, 4vw, 2rem);
  border-bottom: 1px solid var(--linie-hell);
}

.zahl__zeile {
  font-weight: 600;
  font-size: var(--t-zahl);
  letter-spacing: -0.05em;
  line-height: 0.85;
  font-variant-numeric: tabular-nums;
  /* flex statt nowrap: wird es eng (textabstand nach wcag 1.4.12), rutscht die
     einheit unter die zahl, statt am rand abgeschnitten zu werden. der &nbsp;
     bleibt ein eigenes flex-item */
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  /* der &nbsp; vor der einheit: immer 0.5rem, nicht 0.25em der riesenzahl.
     0.25em leerschlag − 2 × 0.05em laufweite (ziffer und leerschlag) − 0.15em = 0 */
  word-spacing: calc(0.5rem - 0.15em);
}

.zahl__wert {
  position: relative;
  display: inline-block;
}

.zahl__einheit {
  font-weight: 500;
  font-size: 1.25rem;
  letter-spacing: 0;
}

.zahl__text {
  margin-top: 0.75rem;
}

@media (min-width: 48em) {
  .zahlen {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    border-top: 0;
  }

  .zahl {
    padding: 0 var(--gutter);
    border-bottom: 0;
    border-left: 1px solid var(--linie-hell);
  }

  .zahl:first-child {
    padding-left: 0;
    border-left: 0;
  }
}

/* ————— zwischenbild ————— */

.zwischenbild__bild {
  overflow: hidden;
  overflow: clip;
  background: var(--platzhalter);
}

.zwischenbild__bild img {
  width: 100%;
  aspect-ratio: 21 / 9;
  object-fit: cover;
}

@media (orientation: portrait) {
  .zwischenbild__bild img {
    aspect-ratio: 4 / 5;
  }
}

.zwischenbild__text {
  max-width: calc(var(--breite) + 2 * var(--rand));
  margin-inline: auto;
  padding: 0.75rem var(--rand) 0;
}

/* ————— lehrjahr (dunkel, #handwerk) ————— */

.lehrjahr__intro {
  max-width: var(--mass);
}

.jahreszeiten {
  display: grid;
  gap: clamp(2.5rem, 7vw, 3.5rem) var(--gutter);
  margin-top: clamp(2.5rem, 6vw, 4.5rem);
  padding: 0;
  list-style: none;
}

.jahreszeit__text {
  margin-top: 1.25rem;
}

.jahreszeit__titel {
  margin-top: 0.25rem;
  font-size: var(--t-h3);
}

.jahreszeit__beschreibung {
  margin-top: 0.75rem;
  max-width: var(--mass);
}

@media (min-width: 30em) {
  .jahreszeiten {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 72em) {
  /* vier spalten, getrennt durch haarlinien, keine kästen. erst ab 72em:
     darunter kämen die zeilen auf gut 20 zeichen, dort bleiben es zwei */
  .jahreszeiten {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .jahreszeit {
    position: relative;
  }

  /* die haarlinie steht mitten in der lücke — alle spalten bleiben gleich breit */
  .jahreszeit + .jahreszeit::before {
    content: '';
    position: absolute;
    inset: 0 auto 0 calc(var(--gutter) / -2);
    width: 1px;
    background: var(--linie);
  }
}

/* ————— weine (hell) ————— */

.weine {
  display: grid;
  gap: clamp(3rem, 7vw, 4.5rem) clamp(1.5rem, 4vw, 3rem);
  padding: 0;
  list-style: none;
}

@media (min-width: 48em) {
  .weine {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.wein {
  --akzent: var(--muscat);
}

.wein[data-akzent='chasselas'] {
  --akzent: var(--chasselas);
}

/* akzentlinie über der karte (site.js lässt sie einmal von rechts aufziehen).
   die akzentfarbe steht nur als linie und als bildfläche, nie als schrift:
   muscat und chasselas auf kalk hätten kaum kontrast. darum sitzt die linie
   direkt auf der oberkante des bildes — frei auf kalk wäre sie unsichtbar */
.wein::before {
  content: '';
  display: block;
  height: 2px;
  margin-bottom: 0;
  background: var(--akzent);
  transform-origin: 100% 50%;
}

/* die einzige fläche: 4:5 in der etikettenfarbe. heute füllt ein traubenfoto
   sie ganz, später steht die freigestellte flasche darauf */
.wein__bild {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: contain;
  background: var(--akzent);
}

.wein__name {
  margin-top: 1.25rem;
  font-size: clamp(1.5rem, 1.1rem + 1.6vw, 2.25rem);
}

.wein__meta,
.wein__notiz {
  padding-block: 0.75rem;
  border-bottom: 1px solid var(--linie-hell);
}

.wein__meta {
  margin-top: 1rem;
  border-top: 1px solid var(--linie-hell);
}

.weine__hinweis {
  margin-top: clamp(2.5rem, 6vw, 4rem);
  max-width: var(--mass);
  color: var(--schiefer-70);
}

/* ————— kontakt (dunkel) ————— */

.kontakt {
  padding-bottom: 0;
  overflow-x: hidden;
  overflow-x: clip; /* die bildmarke läuft rechts hinaus */
}

.kontakt__raster {
  display: grid;
  gap: clamp(2.5rem, 6vw, 4rem);
}

.kontakt__text {
  max-width: 100%;
}

.kontakt__satz {
  max-width: var(--mass);
  margin-bottom: clamp(1.5rem, 4vw, 2.5rem);
}

.kontakt__mail {
  display: inline-block;
  max-width: 100%;
  min-height: 44px;
  padding-block: 0.15em;
  font-weight: 600;
  font-size: clamp(1.75rem, 1rem + 4.5vw, 4.5rem);
  letter-spacing: -0.02em;
  line-height: 1.1;
  overflow-wrap: anywhere;
  text-decoration-thickness: 0.05em;
  text-underline-offset: 0.14em;
}

.kontakt__mail:is(:hover, :focus-visible) {
  text-decoration-thickness: 0.1em;
}

.kontakt__ort {
  margin-top: 1.25rem;
}

/* grosse bildmarke: dieselbe wie im hero (gleiches svg, vier balken). läuft
   rechts aus dem bild und sitzt unten auf — die viewBox hat unter dem
   untersten balken 1.6 von 27 einheiten luft, der negative rand nimmt sie weg */
.bildmarke--kontakt {
  --marke-b: min(80vw, 32rem);
  justify-self: end;
  align-self: end;
  width: var(--marke-b);
  max-width: none;
  margin-right: calc(-1 * var(--rand) - 2px);
  margin-bottom: calc(var(--marke-b) * -0.016);
}

@media (min-width: 56em) {
  .bildmarke--kontakt {
    --marke-b: min(60vw, 32rem);
  }
}

/* breit genug für mail und marke nebeneinander: die marke rechts, bündig mit
   dem rechten bildrand — aus dem container hinaus bis an den rand */
@media (min-width: 80em) {
  .kontakt__raster {
    --aussen: calc(var(--rand) + max(0px, (100vw - 2 * var(--rand) - var(--breite)) / 2) + 2px);
    grid-template-columns: minmax(0, 1fr) calc(min(60vw, 32rem) - var(--aussen));
    column-gap: var(--gutter);
  }

  .kontakt__text {
    padding-bottom: var(--abstand);
  }

  .bildmarke--kontakt {
    margin-right: calc(-1 * var(--aussen));
  }
}

/* ————— fuss ————— */

.fuss {
  padding: clamp(3rem, 6vw, 5rem) var(--rand) clamp(1.5rem, 3vw, 2.5rem);
  border-top: 1px solid var(--linie);
}

.fuss__innen {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.5rem 2rem;
  max-width: var(--breite);
  margin-inline: auto;
}

.bildmarke--fuss {
  width: 3rem; /* unter 60 px: die kräftige variante */
  margin-bottom: 1rem;
}

.fuss__text {
  flex: 1 1 auto;
}

.fuss__zeile {
  line-height: 2.75rem;
}

.fuss ul {
  display: flex;
  gap: 1.5rem;
  padding: 0;
  list-style: none;
}

.fuss a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  color: var(--kalk-70);
  font-weight: 500;
  font-size: var(--t-meta);
  text-decoration: none;
}

.fuss a:hover {
  color: var(--muscat);
}

/* ————— unterseiten ————— */

.unterseite {
  padding-top: calc(var(--kopf-h) + var(--abstand) * 0.75);
  min-height: 70vh;
}

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

.fehler__link {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
}

.rechtstext h2 {
  margin-top: 2.5rem;
  margin-bottom: 0.75rem;
  font-size: 1.25rem;
}

.rechtstext p + p {
  margin-top: 1em;
}

.rechtstext .meta {
  margin-top: 3rem;
}

.bildnachweis {
  font-variant-numeric: tabular-nums;
}

/* jeder nachweis ein absatz: umbricht einer, rückt die zweite zeile ein und
   liest sich nicht wie ein eigener eintrag ohne bildnamen */
.bildnachweis p + p {
  padding-left: 1em;
  text-indent: -1em;
}

.bildnachweis p + p + p {
  margin-top: 0.25em;
}

/* ————— bewegung ————— */

/* hover und fokus: der zustand wechselt immer, weich nur ohne «weniger bewegung» */
@media (prefers-reduced-motion: no-preference) {
  .kopf {
    transition: opacity var(--dauer) ease;
  }

  .kopf__nav a > span,
  .kopf__menue > span,
  .menue a > span,
  .fuss a > span {
    transition: background-size var(--dauer) var(--ease-aus);
  }

  .kontakt__mail {
    transition: text-decoration-thickness var(--dauer) var(--ease-aus);
  }

  /* menü: 12 px / 400 ms beim öffnen und schliessen */
  .bewegt .menue {
    transition: opacity var(--dauer) var(--ease-aus), translate var(--dauer) var(--ease-aus),
      display var(--dauer) allow-discrete, overlay var(--dauer) allow-discrete;
  }

  .bewegt .menue:not(:popover-open) {
    opacity: 0;
    translate: 0 calc(-1 * var(--weg));
  }

  @starting-style {
    .bewegt .menue:popover-open {
      opacity: 0;
      translate: 0 calc(-1 * var(--weg));
    }
  }

  /* — auftritte beim laden: hero — */

  /* wortmarke steigt aus der grundlinie: maske öffnet von unten, 12 px weg.
     der gebundene span bleibt unangetastet, der text ist nie unsichtbar gesetzt */
  .bewegt .wortmarke {
    animation: aufsteigen var(--dauer-auftritt) var(--ease-aus) 60ms both;
  }

  .bewegt .hero__zeile {
    animation: auftauchen var(--dauer) var(--ease-aus) 300ms both;
  }

  .bewegt .hero__satz {
    animation: auftauchen var(--dauer) var(--ease-aus) 380ms both;
  }

  /* hang: terrasse um terrasse vom hang (rechts) aus, die unterste zuerst.
     im hero beim laden. im kontakt dieselbe marke, dort erst, wenn sie zur
     hälfte im bild ist (site.js setzt .ist-sichtbar) — bis dahin wartet die
     animation pausiert im ersten bild (fill both: balken bei scale 0) */
  .bewegt :is(.bildmarke--hero, .bildmarke--kontakt) rect {
    transform-box: fill-box;
    transform-origin: 100% 50%;
    animation: terrasse var(--dauer-auftritt) var(--ease-aus) both;
  }

  .bewegt :is(.bildmarke--hero, .bildmarke--kontakt) rect:nth-child(4) { animation-delay: 200ms; }
  .bewegt :is(.bildmarke--hero, .bildmarke--kontakt) rect:nth-child(3) { animation-delay: 290ms; }
  .bewegt :is(.bildmarke--hero, .bildmarke--kontakt) rect:nth-child(2) { animation-delay: 380ms; }
  .bewegt :is(.bildmarke--hero, .bildmarke--kontakt) rect:nth-child(1) { animation-delay: 470ms; }

  .bewegt .bildmarke--kontakt:not(.ist-sichtbar) rect {
    animation-play-state: paused;
  }

  /* — auftritte beim scrollen (site.js setzt .ist-sichtbar) — */

  .bewegt [data-einblenden] {
    transition: opacity var(--dauer) var(--ease-aus), translate var(--dauer) var(--ease-aus);
  }

  .bewegt [data-einblenden]:not(.ist-sichtbar) {
    opacity: 0;
    translate: 0 var(--weg);
  }

  /* bilder und die kontakt-marke haben einen eigenen auftritt (vorhang,
     terrassen) — kein einblenden über opacity und weg */
  .bewegt :is([data-einblenden='bild'], [data-einblenden='marke']) {
    transition: none;
  }

  .bewegt :is([data-einblenden='bild'], [data-einblenden='marke']):not(.ist-sichtbar) {
    opacity: 1;
    translate: none;
  }

  /* bilder: vorhang von rechts nach links, wie die terrassen. der vorhang sitzt
     auf dem <img>, nicht auf dem beobachteten <picture> — chrome rechnet den
     eigenen clip-path in die intersection ein, ein ganz zugezogenes element
     meldete ratio 0 und würde nie sichtbar. */

  .bewegt [data-einblenden='bild'] img {
    transition: clip-path var(--dauer-auftritt) var(--ease-aus);
  }

  .bewegt [data-einblenden='bild']:not(.ist-sichtbar) img {
    clip-path: inset(0 0 0 100%);
  }

  /* der sichtbare zustand braucht ein inset(): zwischen inset() und none
     gibt es keinen übergang, das bild stünde schlagartig da */
  .bewegt [data-einblenden='bild'].ist-sichtbar img {
    clip-path: inset(0);
  }

  /* gestaffelt, wo bilder in einer reihe stehen */
  @media (min-width: 72em) {
    .bewegt .jahreszeit:nth-child(2) .bild img { transition-delay: 90ms; }
    .bewegt .jahreszeit:nth-child(3) .bild img { transition-delay: 180ms; }
    .bewegt .jahreszeit:nth-child(4) .bild img { transition-delay: 270ms; }
  }

  /* zählwerk: ein ::after mit counter(zahl) überdeckt den transparent gemachten
     echten text und zählt --zahl hoch. der gebundene text wird nie beschrieben.
     .zaehlt-bereit: steht auf 0, bis die zahl zu 60 % sichtbar ist (site.js) */
  .bewegt .zahl__wert:is(.zaehlt-bereit, .zaehlt) {
    color: transparent;
  }

  .bewegt .zahl__wert:is(.zaehlt-bereit, .zaehlt)::after {
    content: counter(zahl);
    content: counter(zahl) / '';
    counter-reset: zahl var(--zahl);
    position: absolute;
    inset: 0 0 auto auto;
    color: var(--schiefer);
  }

  .bewegt .zahl__wert.zaehlt::after {
    animation: zaehlen 900ms var(--ease-ruhig) both;
  }

  /* akzentlinie der weine: einmal von rechts, nach partials:loaded (site.js) */
  .bewegt .wein::before {
    transition: scale var(--dauer-auftritt) var(--ease-aus);
  }

  .bewegt .wein.linie-wartet::before {
    scale: 0 1;
  }

  /* seitenwechsel startseite ↔ impressum/datenschutz: die wortmarke bleibt stehen */
  @view-transition {
    navigation: auto;
  }

  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation-duration: 300ms;
  }
}

/* — an den scroll gekoppelt: nur wo animation-timeline geht, sonst endzustand — */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* fortschritt in der kopf-linie */
    .bewegt .kopf::after {
      display: block;
      scale: 0 1; /* seite ohne scrollweg: timeline inaktiv, linie leer */
      animation: fortschritt linear both;
      animation-timeline: scroll(root block);
    }

    /* hero-bild wandert langsamer als die seite. nie über opacity (lcp) */
    .bewegt .hero__bg img {
      animation: hero-weg linear both;
      animation-timeline: scroll(root block);
      animation-range: 0 100svh;
    }

    /* parallax im bildrahmen: nur der ausschnitt wandert, der rahmen steht */
    .bewegt .bild--parallax,
    .bewegt .zwischenbild__bild {
      overflow: clip;
    }

    .bewegt .bild--parallax img,
    .bewegt .zwischenbild__bild img {
      scale: 1.12;
      animation: bild-weg linear both;
      animation-timeline: view();
    }

    /* zwischenbild öffnet sich wie ein vorhang, nur horizontal (höhe bleibt) */
    .bewegt .zwischenbild__bild {
      animation: vorhang-auf linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 40%;
    }

    /* titelzeilen aus data-split öffnen sich, jede mit eigener timeline */
    .bewegt [data-split] .line {
      animation: zeile linear both;
      animation-timeline: view();
      animation-range: entry 10% entry 90%;
    }

    /* manifest: die grenze hell/gedämpft wandert in leserichtung durch den text.
       das <p> ist inline, damit der verlauf über alle zeilen läuft — harte kante,
       kein weicher übergang. nur bei genau einem absatz */
    .bewegt .fuellen {
      view-timeline: --manifest block;
    }

    .bewegt .fuellen p:only-child {
      display: inline;
      color: transparent;
      background: linear-gradient(to right, var(--kalk) var(--fuellung), var(--kalk-70) var(--fuellung));
      -webkit-background-clip: text;
      background-clip: text;
      -webkit-box-decoration-break: slice;
      box-decoration-break: slice;
      animation: textfuellung linear both;
      animation-timeline: --manifest;
      animation-range: entry 60% cover 55%;
    }

    /* kapitel: aktives kapitel voll, die anderen gedämpft (nie unter 0.5).
       nur mit dem sticky-kopf ab 56em — mobil stünde der titel beim lesen gedimmt */
    @media (min-width: 56em) {
      .bewegt .kapitel__eintrag {
        view-timeline: --kapitel block;
      }

      .bewegt .kapitel__kopf {
        animation: kapitel-licht linear both;
        animation-timeline: --kapitel;
      }

      .bewegt .kapitel::before {
        animation: strahl linear both;
        animation-timeline: view();
        animation-range: entry 50% exit 50%;
      }
    }
  }
}

@keyframes aufsteigen {
  from {
    clip-path: inset(100% -5% -5% -5%);
    translate: 0 var(--weg);
  }
  to {
    clip-path: inset(-5%);
    translate: 0 0;
  }
}

@keyframes auftauchen {
  from {
    opacity: 0;
    translate: 0 var(--weg);
  }
}

@keyframes terrasse {
  from {
    scale: 0 1;
  }
}

@keyframes zaehlen {
  from {
    --zahl: 0;
  }
  to {
    --zahl: var(--ziel);
  }
}

@keyframes fortschritt {
  from {
    scale: 0 1;
  }
  to {
    scale: 1 1;
  }
}

@keyframes hero-weg {
  to {
    translate: 0 14%;
  }
}

@keyframes bild-weg {
  from {
    translate: 0 -5%;
  }
  to {
    translate: 0 5%;
  }
}

@keyframes vorhang-auf {
  from {
    clip-path: inset(0 8%);
  }
  to {
    clip-path: inset(0);
  }
}

@keyframes zeile {
  from {
    clip-path: inset(100% 0 -0.25em 0);
    translate: 0 var(--weg);
  }
  to {
    clip-path: inset(-0.25em 0 -0.25em 0);
    translate: 0 0;
  }
}

@keyframes textfuellung {
  from {
    --fuellung: -20%;
  }
  to {
    --fuellung: 120%;
  }
}

@keyframes kapitel-licht {
  0%,
  100% {
    opacity: 0.5;
  }
  25%,
  75% {
    opacity: 1;
  }
}

@keyframes strahl {
  from {
    scale: 1 0;
  }
  to {
    scale: 1 1;
  }
}

/* ————— sicherheitsnetze ————— */

@media (prefers-reduced-motion: reduce) {
  [data-einblenden='bild'] img {
    clip-path: none !important;
  }
}

@media (forced-colors: active) {
  .fuellen p {
    background: none !important;
    color: CanvasText !important;
  }
}

/* ————— druck ————— */

/* nicht angescrollte sektionen wären sonst leer, der fixe kopf stünde auf jeder seite */
@media print {
  .bewegt *,
  .bewegt *::before,
  .bewegt *::after {
    animation: none !important;
    transition: none !important;
  }

  .bewegt [data-einblenden] {
    opacity: 1 !important;
    translate: none !important;
  }

  [data-einblenden='bild'] img {
    clip-path: none !important;
  }

  .zahl__wert {
    color: inherit !important;
  }

  .zahl__wert::after {
    content: none !important;
  }

  .fuellen p {
    background: none !important;
    color: inherit !important;
  }

  .kopf {
    position: absolute;
  }

  .menue {
    display: none !important;
  }
}
