@charset "UTF-8";
/* =====================================================================
   grundlage.css · was der Browser falsch macht, und was jeder Besucher
   braucht. Sonst nichts.

   Wird unveraendert ins Projekt kopiert und VOR dem Projekt-CSS
   geladen:

       grundlage.css   diese Datei
       style.css       der ganze Entwurf, frei gebaut

   WAS HIER ABSICHTLICH NICHT MEHR STEHT · umgestellt am 07.08.2026:

   Bis dahin standen hier .bahn, .raster, .abschnitt, .abschnitt--tief,
   .vorzeile, .satz und .taste. Also der Satzspiegel, der Rhythmus der
   Abschnitte, der Anriss ueber jeder Ueberschrift und die Tasten. Das
   klang nach Grundlage und war in Wahrheit das Skelett: Drei Projekte,
   die damit gebaut wurden, teilten sich 61 bis 70 Prozent ihrer
   Klassen, und 78 bis 86 Prozent von jedem einzelnen kamen aus dem
   Bausatz. Ein Autoservice und ein Hofbetrieb hatten dieselbe Seite.

   Ein Satzspiegel ist eine Gestaltungsentscheidung. Er gehoert ins
   Projekt, mitsamt der Frage, ob es ueberhaupt einen gibt.

   DIE REGEL FUER DIESE DATEI: Kein Selektor auf einen Klassennamen,
   ausser bei den vier Namen, an denen verhalten.js haengt. Alles
   andere zielt auf HTML-Elemente. Was sich nicht so schreiben laesst,
   ist Gestaltung und gehoert nicht hierher.

   NIRGENDS style="…" im HTML. Steht style-src 'self' in der .htaccess,
   verwirft der Browser jedes style-Attribut live und lautlos. Lokal
   faellt das nur mit router-lokal.php auf. Per JavaScript gesetzte
   Stile (element.style.setProperty) sind davon nicht betroffen.
   ===================================================================== */


/* ═══ 1 · Ruecksetzen ══════════════════════════════════════════════════
   Nur das, was der Browser wirklich falsch macht. Kein grosser Reset,
   der hinterher zurueckgebaut werden muss. Keine Farbe, keine Schrift,
   keine Groesse: Das alles setzt das Projekt. */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /*
   * Ein Anker darf nicht unter einer festen Kopfzeile landen.
   *
   * Der Fallback 0px ist noetig, weil diese Datei nicht wissen kann,
   * ob das Projekt ueberhaupt eine feste Kopfzeile hat. Hat es eine,
   * setzt es --kopfhoehe.
   *
   * GEMESSEN WIRD DER ERSTE SPRUNG, nicht der zweite. Beim ersten
   * Ankersprung einer frisch geladenen Seite fehlt oft noch ein Stueck
   * Hoehe, deshalb gehoeren rund 30 Punkte Reserve dazu. Wer nur den
   * zweiten Sprung prueft, sieht den Fehler nie.
   */
  scroll-padding-top: calc(var(--kopfhoehe, 0px) + 30px);
}

body {
  margin: 0;
  /* -webkit- zuerst, sonst ignoriert aelteres Safari die Zeile ganz. */
  -webkit-font-smoothing: antialiased;
}

/*
 * figure, blockquote, dl und dd bringen im Browser eigene Raender mit:
 * figure und blockquote stehen auf margin: 1em 40px. Vierzig Punkte
 * links und rechts, die niemand gesetzt hat und die in einer engen
 * Rasterspalte aussehen wie ein Fehler im Raster. dd hat 40 Punkte
 * links. Das gehoert weg, bevor irgendetwas gebaut wird.
 */
figure, blockquote, dl, dd, ul, ol, p, h1, h2, h3, h4, h5, h6 { margin: 0; }
ul, ol { padding: 0; }

/* Bilder. display: block gegen den Zeilenabstand darunter, height: auto
   gegen das Verzerren, sobald width und height im HTML stehen · und die
   stehen dort immer, siehe bild_tag() in werkzeug.php. */
img, svg, video { display: block; max-width: 100%; }
img { height: auto; }

table { border-collapse: collapse; }
th { text-align: left; }

button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }

/* Ueberschriften erben die Groesse NICHT vom Browser. Sie hier auf 1em
   zu setzen waere schon eine Entscheidung; sie beim Browser zu lassen
   auch. Deshalb steht hier nur der Umbruch, der sonst vergessen wird:
   text-wrap: balance bricht gleichmaessig um.

   ACHTUNG: Wer im HTML selbst ein <br> setzt, muss im Projekt
   text-wrap: wrap schreiben, sonst bricht der Browser ein zweites Mal
   um. Der Gegenwert heisst wrap, NICHT normal. "text-wrap: normal"
   gibt es nicht; gueltig sind wrap, nowrap, balance, stable, pretty. */
h1, h2, h3, h4 { text-wrap: balance; }


/* ═══ 2 · Zugaenglichkeit ══════════════════════════════════════════════
   Nicht nachgeruestet, sondern von vornherein da. Die Farben kommen
   aus den CSS-Systemfarben, damit diese Datei kein Projekt-Token
   voraussetzt und trotzdem in hell wie dunkel lesbar bleibt. Ein
   Projekt, das die Sprungmarke gestalten will, ueberschreibt sie. */

/* Sprungmarke. Erstes Element im body, sichtbar erst beim Tabben. */
.sprungmarke {
  position: absolute;
  left: 1rem;
  top: 1rem;
  z-index: 999;
  transform: translateY(-200%);
  background: Canvas;
  color: CanvasText;
  border: 2px solid CanvasText;
  padding: .6rem 1.2rem;
  text-decoration: none;
  transition: transform .2s;
}
.sprungmarke:focus { transform: translateY(0); }

/*
 * Ein sichtbarer Fokusring, ueberall.
 *
 * currentColor statt einer Akzentfarbe: Der Ring passt sich damit von
 * selbst jedem Abschnitt an, auch einem dunklen Band, ohne dass diese
 * Datei die Farben des Projekts kennen muss.
 *
 * :focus-visible statt :focus, damit der Ring nicht bei jedem
 * Mausklick aufblitzt. outline-offset, damit er nicht am Zeichen
 * klebt. NIE outline: none ohne Ersatz.
 */
:focus-visible {
  outline: 3px solid currentColor;
  outline-offset: 3px;
}

/* Nur fuer Vorleseprogramme. Nicht display: none, das waere auch dort
   weg. */
.nur-vorlesen {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}


/* ═══ 3 · Einblenden ═══════════════════════════════════════════════════
   Gehoert zu verhalten.js, nicht zur Gestaltung: Ohne diese zwei
   Regeln steht das Skript vor einem Element, das es zeigen soll, das
   aber nie versteckt war.

   Der Ausgangszustand steht in @media (prefers-reduced-motion:
   no-preference). Ohne diese Klammer waere ein Besucher mit
   abgeschalteter Bewegung auf einer Seite unterwegs, deren Abschnitte
   auf opacity: 0 stehen und deren Skript sie nicht einschaltet.

   Und: Die Regel, die aufhebt, muss DIESELBEN Selektoren nennen wie
   die Regel, die setzt. Wer unten .einblenden schreibt und oben
   .abschnitt .einblenden, hebt nichts auf.

   Der Weg und die Dauer sind bewusst zurueckhaltend. Ein Projekt, das
   eine andere Bewegung will, ueberschreibt sie · aber es muss dann
   BEIDE Regeln ueberschreiben. */

@media (prefers-reduced-motion: no-preference) {
  .einblenden {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity .6s ease, transform .6s ease;
  }
  .einblenden[data-da="ja"] { opacity: 1; transform: none; }
}


/* ═══ 4 · Mit dem Finger ═══════════════════════════════════════════════
   Abgefragt wird die ZEIGERART, nicht die Fensterbreite. Ein Tablet im
   Querformat ist breit UND wird mit dem Finger bedient; ein schmales
   Browserfenster am Schreibtisch ist es nicht.

   Gezielt wird auf HTML-Elemente, nicht auf Klassen: ein Verweis im
   Fliesstext, in einer Liste, in einer Anschrift oder im Fuss ist
   sonst 18 Punkte hoch und nicht sicher zu treffen. Verweise, die
   ohnehin schon gross sind (Tasten, Kacheln), gestaltet das Projekt
   und bringt die 44 Punkte selbst mit.

   NACHMESSEN, nicht glauben: Gestapelte Verweise stehlen einander die
   Flaeche. Mit document.elementFromPoint abtasten. */

@media (pointer: coarse) {
  p > a, li > a, address a, footer a, dd > a {
    display: inline-block;
    min-height: 44px;
    padding-block: .5rem;
  }
}


/* ═══ 5 · Sonderwuensche des Systems ═══════════════════════════════════ */

/* Weniger Bewegung. Dieselben Selektoren wie oben, plus die Bremse
   fuer alles, was sonst noch laeuft. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}


/* ═══ 6 · Druckfassung ═════════════════════════════════════════════════
   Eine Speisekarte oder Preisliste wird ausgedruckt, und zwar
   regelmaessig. Sie darf dabei nicht zerfallen.

   Hier steht nur, was ohne Kenntnis des Entwurfs gilt. Was das Projekt
   beim Drucken ausblenden will · seine Kopfzeile, seine Rufleiste,
   seine Tastenreihen · blendet es in seinem eigenen @media print aus.
   Diese Datei kennt seine Klassennamen nicht und soll sie nicht raten. */

@media print {
  .sprungmarke { display: none !important; }

  body { background: #fff; color: #000; font-size: 11pt; }

  /* Der Ausgangszustand des Einblendens darf hier nicht gelten, sonst
     druckt die Seite leere Flaechen. */
  .einblenden { opacity: 1 !important; transform: none !important; }

  h1, h2, h3 { break-after: avoid; }
  figure, tr, dl { break-inside: avoid; }

  /* Adressen hinter Verweisen ausschreiben, sonst steht auf dem Papier
     "hier klicken". tel: und mailto: stehen schon im Text, die
     Wiederholung waere nur Ballast. */
  a { color: #000; text-decoration: underline; }
  p > a::after, address a::after { content: " (" attr(href) ")"; font-size: 9pt; }
  a[href^="tel:"]::after,
  a[href^="mailto:"]::after,
  a[href^="#"]::after { content: ""; }

  img { max-height: 8cm; }
}
