/* =====================================================================
   Grundlagen — Schriften, Variablen, Grundtypografie
   Apotheke am Bürgerhaus
   =====================================================================

   Kein Framework, kein Build-Schritt. Drei gewöhnliche CSS-Dateien, die
   in dieser Reihenfolge geladen werden:

       grundlagen.css     was überall gilt
       komponenten.css    die wiederkehrenden Bausteine
       startseite.css     was nur die Startseite braucht

   Das Projekt soll in drei Jahren ohne Werkzeugkette baubar sein. Wer
   eine Farbe ändern will, ändert sie hier und nirgendwo sonst.

   ===================================================================== */


/* ---------------------------------------------------------------------
   Schriften — selbst gehostet
   ---------------------------------------------------------------------

   Nicht per Link von Google eingebunden. Das dynamische Einbinden von
   Google Fonts überträgt die IP-Adresse jedes Besuchers an einen
   Drittanbieter und ist in Deutschland abgemahnt worden
   (LG München I, 20.01.2022, 3 O 17493/20).

   Beide Familien stehen unter der SIL Open Font License 1.1; die
   Lizenztexte liegen neben den Schriftdateien. Herkunft und Fassung
   stehen im README.

   font-display: swap ist Absicht. Der Text ist sofort lesbar, auch wenn
   die Schrift noch lädt — bei dieser Zielgruppe wichtiger als ein
   sauberer erster Umbruch.

   Zwei Schnitte pro Gewicht: "latin" deckt Deutsch ab, "latin-ext"
   kommt nur nach, wenn ein Zeichen daraus wirklich vorkommt. Im
   Stadtteil sind Namen mit ł, ğ, ş oder ő nicht die Ausnahme.
   --------------------------------------------------------------------- */

/* Atkinson Hyperlegible — Fließtext.
   Vom Braille Institute für schwaches Sehen gezeichnet: Zeichen, die
   sich sonst ähneln (I l 1, O 0, b d), sind bewusst verschieden. */

@font-face {
  font-family: "Atkinson Hyperlegible";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/atkinson-hyperlegible-400-latin.woff2") format("woff2");
  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: "Atkinson Hyperlegible";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/atkinson-hyperlegible-400-latin-ext.woff2") format("woff2");
  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;
}

@font-face {
  font-family: "Atkinson Hyperlegible";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/atkinson-hyperlegible-700-latin.woff2") format("woff2");
  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: "Atkinson Hyperlegible";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/atkinson-hyperlegible-700-latin-ext.woff2") format("woff2");
  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;
}

/* Zilla Slab — Überschriften und Auszeichnungen.
   Ein kantiger Slab: Plakat- statt Pharma-Charakter. */

@font-face {
  font-family: "Zilla Slab";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/zilla-slab-500-latin.woff2") format("woff2");
  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: "Zilla Slab";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/zilla-slab-500-latin-ext.woff2") format("woff2");
  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;
}

@font-face {
  font-family: "Zilla Slab";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/zilla-slab-600-latin.woff2") format("woff2");
  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: "Zilla Slab";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/zilla-slab-600-latin-ext.woff2") format("woff2");
  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;
}

@font-face {
  font-family: "Zilla Slab";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/zilla-slab-700-latin.woff2") format("woff2");
  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: "Zilla Slab";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/zilla-slab-700-latin-ext.woff2") format("woff2");
  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;
}


/* ---------------------------------------------------------------------
   Schriften fuer die Originalschriften — Ticket 25
   ---------------------------------------------------------------------
   Atkinson Hyperlegible und Zilla Slab decken Latin und Latin-Ext ab.
   Fuer Arabisch, Persisch, Urdu, Japanisch und Koreanisch fehlen die
   Zeichen; ohne eigene Schrift stuenden dort Kaestchen oder eine
   beliebige Systemschrift.

   Drei Teilschnitte aus der Noto-Familie, SIL Open Font License 1.1 —
   dieselbe Lizenz wie die beiden vorhandenen. Sie enthalten nur die
   Zeichen, die auf dieser Website vorkommen: zusammen rund 29 Kilobyte
   statt mehrerer Megabyte. Herkunft, Umfang und Rechteinhaber stehen in
   fonts/HERKUNFT-Noto.txt.

   Selbst gehostet wie alles andere. Zur Laufzeit geht keine Anfrage an
   Google; ein Prueflauf haelt das fest (B2.2 in ANNAHMEN.md).

   `unicode-range` ist hier keine Optimierung, sondern die eigentliche
   Mechanik: Der Browser laedt einen dieser Schnitte **nur**, wenn auf
   der Seite wirklich ein Zeichen daraus steht. Wer eine Seite ohne
   fremde Schrift aufruft, laedt kein einziges Byte davon.

   Die Schnitte sind variabel und decken 400 bis 700 aus einer Datei ab.
   --------------------------------------------------------------------- */

@font-face {
  font-family: "Noto Sans Arabic";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/noto-sans-arabic-apotheke.woff2") format("woff2");
  unicode-range: U+0627-0629, U+062E-062F, U+0631, U+0633, U+0635, U+0639,
    U+0641, U+0644-0648, U+064A, U+06CC;
}

@font-face {
  font-family: "Noto Sans JP";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/noto-sans-jp-apotheke.woff2") format("woff2");
  unicode-range: U+5C40, U+65E5, U+672C, U+85AC, U+8A9E;
}

@font-face {
  font-family: "Noto Sans KR";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("../fonts/noto-sans-kr-apotheke.woff2") format("woff2");
  unicode-range: U+1100, U+110B, U+1163, U+116E, U+11A8, U+AC38-AC39,
    U+AD6C-AD6D, U+C57C-C57D, U+C6B0-C6B1;
}


/* ---------------------------------------------------------------------
   Variablen
   ---------------------------------------------------------------------

   Gemessene Kontraste auf hellem Grund (papier / grund2):

       tinte  auf papier   14,3 : 1     Fließtext
       tinte  auf grund2   13,0 : 1     Fließtext
       petrol auf papier    9,0 : 1     Links, Auszeichnungen
       petrol auf grund2    8,2 : 1     Links, Auszeichnungen
       papier auf petrol    9,0 : 1     Fuß, Knöpfe
       ocker  auf papier    3,6 : 1     nur Fokusring und Grafik
       ocker  auf grund2    3,2 : 1     nur Fokusring und Grafik

   Für Fließtext ist 7 : 1 das Ziel — bewusst über dem Mindeststandard,
   weil der Altersschwerpunkt bei 60+ liegt. Beide Textfarben liegen
   deutlich darüber.

   Ocker trägt nirgends Text. Er ist zu hell dafür (3,6 : 1) und steht
   ausschließlich als Fläche, Marke und Fokusring — dort gilt 3 : 1, und
   das ist erfüllt. Auf petrolfarbenem Grund erreicht Ocker nur 2,5 : 1;
   deshalb ist der Fokusring im Fuß papierfarben (9,0 : 1).
   --------------------------------------------------------------------- */

:root {
  /* Farben */
  --papier: #f6f2e9;
  --grund2: #ede7d9;
  --tinte: #1c2321;
  --petrol: #17494b;
  --ocker: #bb6c15;
  --linie: #cfc6ae;

  /* Maße */
  --spalte: 36rem;   /* Lesebreite eines Absatzes */
  --rand: 1.25rem;   /* seitlicher Rand, wächst ab 768px */
  --breite: 64rem;   /* Breite des Satzspiegels */
  --ziel: 48px;      /* kleinste Klickfläche */

  /* Schriftrollen
     Die drei Noto-Schnitte stehen seit Ticket 25 in beiden Rollen. Sie
     aendern am lateinischen Satz nichts: ihr `unicode-range` deckt nur
     Arabisch, Japanisch und Koreanisch ab, und der Browser zieht sie
     ausschliesslich fuer diese Zeichen heran.

     Sie stehen global und nicht nur an den Sprachlisten. Sonst haette
     jede andere Stelle, an der einmal ein fremdes Zeichen steht — ein
     Produktname, eine Leistung —, eine beliebige Systemschrift oder ein
     Kaestchen. */
  --display: "Zilla Slab", "Noto Sans Arabic", "Noto Sans JP",
    "Noto Sans KR", Georgia, "Times New Roman", serif;
  --text: "Atkinson Hyperlegible", "Noto Sans Arabic", "Noto Sans JP",
    "Noto Sans KR", "Segoe UI", Tahoma, Arial, sans-serif;

  /* Radien: keine. Steht hier, damit die Entscheidung sichtbar ist. */
  --radius: 0;
}


/* ---------------------------------------------------------------------
   Zurücksetzen — nur das Nötige
   --------------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  /* Ziel für die Sprungmarke; ohne den Abstand klebt die Überschrift
     nach dem Sprung am oberen Rand. */
  scroll-padding-top: 1rem;
}

body {
  margin: 0;
  background: var(--papier);
  color: var(--tinte);
  font-family: var(--text);
  font-size: 1.125rem; /* 18px Fließtext, Untergrenze aus dem Ticket */
  line-height: 1.6;

  /* Hier stand bis Ticket 19 `overflow-wrap: break-word`. Das war der
     Notnagel für lange deutsche Zusammensetzungen — und er hat den
     schlechtestmöglichen Umbruch erzeugt: einen ohne Trennstrich.
     Auf der Leistungsseite stand "Kompressionsstrümpf" / "e anmessen".
     Begründung unter "Silbentrennung". */

  /* Keine automatische Silbentrennung als Vorgabe. Welche Stellen sie
     bekommen, steht weiter unten unter "Silbentrennung". */
  hyphens: manual;
}

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


/* ---------------------------------------------------------------------
   Verborgen ist verborgen
   ---------------------------------------------------------------------
   Das hidden-Attribut wirkt nicht von selbst. Der Browser setzt es mit
   einer eigenen Regel `[hidden] { display: none }` um — und die kommt
   aus der Herkunft "Browser". Jede Regel aus diesem Stylesheet schlägt
   sie, unabhängig von der Spezifität, weil die Herkunft vor der
   Spezifität entscheidet.

   `.knopf` setzt `display: inline-flex`. Damit blieb der Startknopf des
   Rundgangs sichtbar, obwohl er hidden trug: ohne JavaScript stand er
   über der Vorschau und führte ins Leere. Vorher war dasselbe schon
   beim Live-Status der Öffnungszeiten aufgefallen. Beide Male wurde eine
   einzelne Ausnahmeregel nachgereicht — und beim dritten Mal wäre es
   wieder passiert.

   Deshalb steht die Regel jetzt einmal und für alles. `!important` ist
   hier kein Notnagel, sondern die Bedingung: ohne sie gewinnt jede
   spätere Komponentenregel, und genau das war der Fehler.

   Wer hidden verwendet, prüft die Darstellung und nicht das Attribut.
   Im Markup stand es beide Male richtig da.
   --------------------------------------------------------------------- */

[hidden] {
  display: none !important;
}


/* ---------------------------------------------------------------------
   Grundtypografie
   --------------------------------------------------------------------- */

h1,
h2,
h3 {
  font-family: var(--display);
  line-height: 1.15;
  margin: 0 0 0.6rem;

  /* Bis Ticket 19 stand hier `hyphens: manual` — Überschriften sollten
     gar nicht getrennt werden. Die Regel hatte einen blinden Fleck:
     Bei einem Wort, das allein schon zu lang für die Zeile ist, gibt es
     keine Leerstelle zum Ausweichen. Sie hat damit die einzig gute
     Möglichkeit verboten und die schlechteste übrig gelassen.

     Getrennt wird deshalb wieder — aber nur, wo es gebraucht wird.
     hyphenate-limit-chars sagt: erst ab 14 Zeichen, und nie weniger als
     vier Zeichen vor oder nach dem Strich. "Bürgerhaus" (10) und
     "beraten" (7) bleiben damit unangetastet; genau die waren in
     Ticket 14 der Anlass. "Kompressionsstrümpfe" (20) wird getrennt.

     Ältere Browser kennen hyphenate-limit-chars nicht und trennen dann
     großzügiger. Das ist die schlechtere, aber immer noch eine
     brauchbare Darstellung — ein Trennstrich an ungewohnter Stelle ist
     besser als ein Wort, das mittendrin ohne Strich abbricht. */
  hyphens: auto;
  hyphenate-limit-chars: 14 4 4;
}

h1 {
  font-size: 2.3rem;
  font-weight: 700;
  letter-spacing: -0.005em;
}

h2 {
  font-size: 1.75rem;
  font-weight: 700;
}

h3 {
  font-size: 1.2rem;
  font-weight: 600;
}

p {
  margin: 0 0 1rem;
  max-width: var(--spalte);
}

p:last-child {
  margin-bottom: 0;
}

.lead {
  font-size: 1.25rem;
  line-height: 1.55;
}

/* ---------------------------------------------------------------------
   Silbentrennung
   ---------------------------------------------------------------------
   Bis Ticket 14 stand `hyphens: auto` auf dem <body> und galt damit für
   alles. Das Ergebnis war an den falschen Stellen zu sehen: "in Ruhe
   be-raten" in der Einleitung der Startseite, "wieder ge-öffnet" in der
   Statuszeile der Öffnungszeiten.

   Für eine Zielgruppe mit schwachem Sehen hebt das genau den Vorteil
   auf, für den Atkinson Hyperlegible gewählt wurde: ein getrenntes Wort
   muss über den Umbruch hinweg zusammengesetzt werden, und das kostet
   Aufmerksamkeit, die für den Inhalt gebraucht wird.

   Automatische Trennung deshalb nur dort, wo wirklich längerer
   Fließtext steht — Absätze, Listenpunkte, Angaben im Zeilenwerk. Diese
   Stellen laufen bei 320px sonst tatsächlich aus der Spalte.

   **Korrektur in Ticket 19.** Der „Notnagel für überlange Wörter“ war
   `overflow-wrap: break-word` auf dem <body>. Er hat getan, was
   dasteht: bei Bedarf mitten im Wort umgebrochen — ohne Trennstrich.
   Auf der Leistungsseite stand „Kompressionsstrümpf / e anmessen“.

   Die Regel gilt jetzt:

     Ein Wort, das nicht in die Zeile passt, bricht **mit Trennstrich**.
     Niemals ohne.

   Deshalb ist `overflow-wrap: break-word` vom <body> entfernt, und
   Überschriften trennen wieder — begrenzt auf lange Einzelwörter, siehe
   oben bei h1/h2/h3.

   `word-break: break-all` und `overflow-wrap: anywhere` sind damit für
   Fließtext und Überschriften ausgeschlossen. Es bleibt genau eine
   Ausnahme, in komponenten.css: die E-Mail-Adresse. Ein
   „apotheke.buergerhaus@gmail.com“ hat keine Silbengrenze, an der ein
   Trennstrich sinnvoll wäre.

   Voraussetzung für all das ist `lang="de"` am Wurzelelement. Ohne
   Sprachauszeichnung trennt der Browser nach englischen Regeln und setzt
   den Strich an falsche Stellen. Es steht in site/snippets/kopf.php und
   wird geprüft.
   --------------------------------------------------------------------- */

p,
dd,
li {
  hyphens: auto;
}

/* Und dort nicht, wo der Text kurz und die Trennung eine Zumutung ist:
   Einleitungen, Kennzeichnungen, Navigation, Knöpfe, Statusmeldungen,
   Tabellenköpfe und kurze Hinweise. Überschriften stehen schon weiter
   oben auf `manual`. */
.lead,
.kicker,
.nav a,
.knopf,
.knopf__klein,
.tel-still,
.weiter,
.kopf__tel,
.marke__name,
.marke__ort,
.banner p,
.streifen p,
.streifen__label,
.zeile dt,
.hinweis,
.tafel__kicker,
[data-oeffnungszeiten-status],
.oeffnungszeiten th,
.oeffnungszeiten td,
figcaption {
  hyphens: manual;
}


a {
  color: var(--petrol);
  text-decoration-thickness: 2px;
  text-underline-offset: 0.2em;
}

a:hover {
  color: var(--tinte);
}

strong {
  font-weight: 700;
}


/* ---------------------------------------------------------------------
   Tastaturbedienung
   ---------------------------------------------------------------------

   Der Fokusring ist überall gleich und überall sichtbar. Er wird
   nirgends abgeschaltet: wer mit der Tastatur unterwegs ist, muss
   jederzeit sehen, wo er steht.
   --------------------------------------------------------------------- */

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

/* Sprungmarke zum Inhalt. Liegt außerhalb des Bildes, bis sie den
   Fokus bekommt — dann steht sie ganz oben und ist nicht zu übersehen. */
.skip {
  position: absolute;
  left: -9999px;
}

.skip:focus {
  position: static;
  display: block;
  padding: 1rem var(--rand);
  background: var(--petrol);
  color: var(--papier);
  font-weight: 700;
}


/* ---------------------------------------------------------------------
   Raster
   --------------------------------------------------------------------- */

.wrap {
  max-width: var(--breite);
  margin: 0 auto;
}

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

/* Abschnitte werden nur durch den Grundwechsel getrennt — keine Karten,
   keine Schatten, keine Rundungen. */
.grund-alt {
  background: var(--grund2);
}

/* Sektionsmarke: kleines Ockerquadrat plus gesperrte Auszeichnung.
   Das Quadrat ist Schmuck; die Bedeutung trägt immer der Text daneben. */
.kicker {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  max-width: none;
  margin: 0 0 0.9rem;
  color: var(--petrol);
  font-family: var(--display);
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.kicker::before {
  content: "";
  flex: none;
  width: 0.7rem;
  height: 0.7rem;
  background: var(--ocker);
}

/* Nur für Screenreader — etwa eine Überschrift, die den Abschnitt
   benennt, ohne im Bild zu erscheinen. */
.nur-vorlesen {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}


/* ---------------------------------------------------------------------
   Ab 768px
   ---------------------------------------------------------------------
   Ein einziger Umbruchpunkt. Mehr braucht eine Seite mit einer
   Lesespalte nicht, und jeder weitere wäre eine Stelle mehr, an der
   später etwas auseinanderfällt.
   --------------------------------------------------------------------- */

@media (min-width: 768px) {
  :root {
    --rand: 2.5rem;
  }

  h1 {
    font-size: 3.25rem;
  }

  h2 {
    font-size: 2.25rem;
  }

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


/* ---------------------------------------------------------------------
   Bewegung
   ---------------------------------------------------------------------
   Die Seite animiert von sich aus nichts. Die Regel steht trotzdem
   hier, damit sie auch für alles gilt, was später dazukommt.
   --------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
