/* Erzeugt aus shop/templates/page_css.html durch parser.php -- NICHT von Hand aendern. */
/* ══════════════════════════════════════════════════════════════════════════
       SCHRIFT: INSTRUMENT SANS
       ══════════════════════════════════════════════════════════════════════════

       Selbst gehostet, kein Aufruf an fonts.googleapis.com. Herkunft und Lizenz:
       shop/assets/fonts/instrument-sans/HERKUNFT.md

       Zwei Dinge, die hier schon einmal schiefgegangen sind:

       - format('woff2') und nicht format('ttf'). Die alte Regel fuer Riccione
         Serial hatte einen Format-Bezeichner, den es nicht gibt; Browser
         ueberspringen die Quelle dann laut Spezifikation, still und ohne
         Fehlermeldung. Sieben Monate lang lud deshalb keine Schrift.
       - font-weight: 400 700 als BEREICH, nicht als einzelner Wert. Die Dateien
         sind variabel (fvar-Tabelle vorhanden) und decken 400 bis 700 aus einer
         Datei ab. Stuende hier nur "400", wuerde der Browser jedes fettere Gewicht
         selbst faelschen, statt die vorhandenen Zwischenstufen zu nutzen.

       font-display: swap -- der Text steht sofort in der Systemschrift und wird
       ausgetauscht, sobald die Datei da ist. Nie ein unsichtbarer Bildschirm.
       Die unicode-range sorgt dafuer, dass fuer deutschen Text nur die beiden
       Grunddateien geladen werden (29 und 31 KB); die erweiterten Zeichen kommen
       nur, wenn ein Name sie braucht.
       ══════════════════════════════════════════════════════════════════════════ */

    @font-face {
      font-family: 'Instrument Sans';
      src: url('/shop/assets/fonts/instrument-sans/instrument-sans-latin.woff2') format('woff2');
      font-weight: 400 700;
      font-style: normal;
      font-display: swap;
      unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
    }
    @font-face {
      font-family: 'Instrument Sans';
      src: url('/shop/assets/fonts/instrument-sans/instrument-sans-italic-latin.woff2') format('woff2');
      font-weight: 400 700;
      font-style: italic;
      font-display: swap;
      unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
    }
    @font-face {
      font-family: 'Instrument Sans';
      src: url('/shop/assets/fonts/instrument-sans/instrument-sans-latin-ext.woff2') format('woff2');
      font-weight: 400 700;
      font-style: normal;
      font-display: swap;
      unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
    }
    @font-face {
      font-family: 'Instrument Sans';
      src: url('/shop/assets/fonts/instrument-sans/instrument-sans-italic-latin-ext.woff2') format('woff2');
      font-weight: 400 700;
      font-style: italic;
      font-display: swap;
      unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
    }

    /* ══════════════════════════════════════════════════════════════════════════
       DESIGN-TOKENS
       ══════════════════════════════════════════════════════════════════════════

       Vorher standen im Shop-Frontend 1.195 hart codierte Hex-Farben gegen sieben
       CSS-Variablen und 15 verschiedene Eckenradien. Die Folge war nicht nur ein
       uneinheitliches Bild, sondern auch, dass "einheitlich machen" jedes Mal eine
       Suchaktion war statt einer Einstellung.

       Ab hier gilt: Farben und Radien kommen aus diesem Block. Neue Regeln greifen
       auf die Variablen zu, nicht auf Hex-Werte.

       Belegte Entscheidungen:

       - Grau fuer Sekundaertext war fuenffach vorhanden (#64748b, #6b7280, #666,
         #999, #9ca3af). Davon fielen #999 (2,85:1) und #9ca3af (2,54:1) durch die
         WCAG-AA-Schwelle von 4,5:1 -- 82 Fundstellen mit zu schwachem Text. Jetzt
         genau ein Wert: #666 mit 5,74:1, zugleich der bisher haeufigste (76x).
       - Rahmengrau war dreifach vorhanden. #e5e5e5 (95x) gewinnt gegen das fast
         identische #e5e7eb (63x), weil es neutral ist und zur uebrigen Grauleiter passt.
       - Textfarbe: #1a1a1a (17,4:1) statt Reinschwarz fuer Fliesstext, das war ohnehin
         der haeufigste Wert (145x). Reinschwarz bleibt als --accent fuer Flaechen.
       - Fehlerrot war #e74c3c (3,82:1, faellt durch). Jetzt #c0392b (5,44:1).
       ══════════════════════════════════════════════════════════════════════════ */

    /* Riccione Serial, die Serifenschrift der ausgewaehlten Ueberschriften.
       Die Datei liegt seit dem urspruenglichen Entwurf im Repository; die alte
       @font-face-Regel dazu war kaputt (sie meldete format('ttf') statt
       format('truetype')) und hat nie eine Schrift geladen -- deshalb war sie
       entfernt worden. Sie ist jetzt richtig eingebunden.

       Welche Ueberschriften sie bekommen, steht weiter unten bei der Regel selbst;
       es sind fuenf Auswahlen, keine einzelne. 53 KB fuer diese Gruppe sind
       vertretbar, fuer Fliesstext waeren sie es nicht -- deshalb bleibt sie auf
       Ueberschriften beschraenkt. font-display: swap sorgt dafuer,
       dass die Ueberschrift sofort in Instrument Sans steht und nur nachtauscht --
       ueber einem Video ist ein unsichtbarer Text die schlechtere Wahl.

       ACHTUNG Lizenz: die Datei ist eine kommerzielle Schrift von 1996, es liegt
       keine Lizenzdatei dabei. Fuer die Auslieferung als Webfont braucht es eine
       Webfont-Lizenz. Das ist zu klaeren, bevor das auf main geht. */
    @font-face {
      font-family: "Riccione Serial";
      src: url("/shop/assets/fonts/riccione-serial-light-regular.ttf") format("truetype");
      font-weight: 300;
      font-style: normal;
      font-display: swap;
    }

    :root {
      /* Aufbau */
      /* Hoehe der fixierten Kopfzeile, siehe .bar weiter unten. Als Token, weil der
         Abstand darunter sonst an jeder Seite einzeln nachgepflegt werden muss --
         und genau das ist schiefgegangen (siehe die Regel bei "main"). */
      --kopf-hoehe: 78px;

      /* Flaechen */
      --bg: #ffffff;
      --surface: #ffffff;
      --surface-sunk: #f5f5f5;

      /* Text */
      --text: #1a1a1a;
      --text-muted: #666666;
      --text-invert: #ffffff;

      /* Linien */
      --border: #e5e5e5;
      --border-strong: #d0d0d0;
      /* Nur fuer Bedienelemente, an denen man etwas eingibt. WCAG 1.4.11 verlangt
         fuer die Umrandung eines Bedienelements 3:1 gegen die Flaeche daneben --
         --border liegt bei 1,26:1, --border-strong bei 1,54. Beide auf 3:1 zu
         ziehen wuerde jede Karte, jede Trennlinie und jede Kachel der Seite
         schwerer machen; das ist eine Gestaltungsfrage und keine Korrektur.
         Ein Feld, in das man tippt, ist etwas anderes: dort ist der Rahmen die
         einzige Auskunft darueber, wo das Feld anfaengt und aufhoert.
         Der Rahmen grenzt an ZWEI Flaechen: aussen die weisse Seite, innen die
         Feldfuellung --surface-sunk (#f5f5f5). Gegen beide muss er 3:1 schaffen,
         deshalb #8e8e8e und nicht #949494 -- letzteres schafft nur die weisse
         Seite (3,03:1) und scheitert an der Fuellung (2,78:1).
         #8e8e8e: 3,28:1 gegen Weiss, 3,01:1 gegen die Fuellung. */
      --border-feld: #8e8e8e;

      /* Aktionen */
      --accent: #000000;
      --accent-hover: #333333;
      --on-accent: #ffffff;
      --on-accent-muted: #cfcfcf;

      /* Uebergangsdauern. Es waren zehn verschiedene im Umlauf, mehrere davon
         derselbe Wert in zwei Schreibweisen (200ms und 0.2s, 150ms und 0.15s,
         300ms und 0.3s), dazu 220ms und 320ms als Nachbarn ohne erkennbaren
         Grund. Drei Stufen reichen: schnell fuer Zustaende am Zeiger, normal fuer
         alles Uebrige, lang fuer Flaechen, die sich oeffnen. --dauer-bild ist die
         Ausnahme fuer die langsame Bildbewegung auf den Kacheln. */
      --dauer-schnell: 150ms;
      --dauer: 200ms;
      --dauer-lang: 300ms;
      --dauer-bild: 700ms;

      /* Weicher Markenakzent. Bisher an vier Stellen hart als #c4ae94 gesetzt
         (Social-Icons auf der Creator-Seite, Filterleisten). Der Wert bleibt
         unveraendert -- Hinweis fuer spaeter: auf Weiss erreicht er 2,14:1 und liegt
         damit unter den 3:1, die WCAG fuer aussagekraeftige Grafiken vorsieht. Ein
         dunklerer Ton derselben Farbfamilie waere #917350 (4,40:1). Das ist eine
         Markenentscheidung, keine Aufraeumarbeit, deshalb hier nur notiert. */
      --accent-soft: #c4ae94;

      /* Zustaende. Jeweils ein vollstaendiger Satz aus Text-, Flaechen- und
         Rahmenfarbe -- vorher standen dieselben drei Tripel in vier Dateien
         nebeneinander (login, change-password, reset-password, widerruf). */
      --danger: #b91c1c;
      --danger-bg: #fef2f2;
      --danger-border: #fecaca;
      --success: #166534;
      --success-bg: #ecfdf3;
      --success-border: #bbf7d0;
      --warn: #8a6d1f;
      --warn-bg: #fff8e6;

      /* Formen -- vier Radien statt 15 gewachsener Werte. Die Regel dahinter, damit
         sich neue Elemente von selbst einordnen:

           pill   Alles, was man drueckt. Knoepfe, Filter-Chips, Etiketten.
                  Erkennbar als Bedienelement, bevor man den Text gelesen hat.
           round  Alles, was von Natur aus kreisrund ist. Avatare.
           md     Flaechen und Objekte, die fuer sich auf der Seite stehen:
                  Karten, Panels, Produktkacheln, Creator-Kacheln, Bildrahmen.
           sm     Was INNERHALB einer solchen Flaeche liegt. Eine Stufe kleiner,
                  damit die Rundungen konzentrisch wirken statt ausgebeult --
                  das Produktbild in der Produktkarte, Eingabefelder in der
                  Anmeldekarte.

         Verkuerzt: aussen md, innen sm, drueckbar pill, rund round. */
      --r-sm: 8px;
      --r-md: 12px;
      --r-pill: 999px;
      --r-round: 50%;

      /* Eine Schrift fuer die ganze Seite. Die Systemschriften dahinter sind der
         Ruecksfall, bis die Datei da ist (font-display: swap) -- und wenn sie nie
         kaeme, saehe die Seite exakt so aus wie vor dieser Umstellung.
         Zur Vorgeschichte: hier standen einmal vier verschiedene Schriften, von
         denen keine einzige geladen wurde. Siehe DESIGNSYSTEM.md. */
      --font: "Instrument Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

      /* Der Auszeichnungsstil fuer grosse Ueberschriften: Instrument Sans, 700,
         aufrecht (Entscheidung Jakob, 28.08.2026). Bewusst als drei eigene
         Variablen -- Gewicht, Schnitt und Laufweite lassen sich damit an genau
         dieser Stelle seitenweit aendern, ohne ein einziges Template anzufassen.
         Betrifft: Hero, Creator- und Rooms-Ueberschrift, Produkttitel auf der PDP,
         Kachelbeschriftungen, About-Ueberschriften und die 404-Seite. */
      --display-weight: 700;
      --display-style: normal;
      --display-track: -0.02em;

      /* Groessenskala */
      --fs-display: clamp(34px, 8vw, 72px);
      --fs-h1: clamp(28px, 4.2vw, 44px);
      --fs-h2: clamp(24px, 3.4vw, 34px);
      --fs-h3: 20px;
      --fs-body: 16px;
      --fs-sm: 14px;
      --fs-xs: 12px;

      /* Altnamen. Bestehende Regeln greifen an ueber 60 Stellen per var() darauf zu;
         sie zeigen jetzt auf die neuen Werte, statt eigene zu fuehren. */
      --muted: var(--text-muted);
      --menu-color: #ffffff;
      --menu-hover: #cccccc;
    }

    * { box-sizing: border-box; }
    /* overflow-x steht bewusst NUR am body, nicht am html-Element.
       Am html-Element schaltet es "position: sticky" ab -- fuer den Browser ist die
       Seite dann nicht mehr der Scrollbereich, an dem sich ein klebendes Element
       ausrichten koennte. Sichtbar an der Bereichsnavigation der About-Seiten: sie
       steht seit jeher auf "sticky", ist aber nie stehengeblieben, sondern bei
       2500px Scrollposition auf -2446 mitgewandert. Im Browser nachgemessen, mit
       html{overflow-x:visible} klebt sie sofort bei 54px.
       Der Zweck bleibt erhalten: der body klippt waagerechten Ueberlauf weiterhin.
       Auf allen Seiten und Breiten gegengeprueft, dass nichts seitlich scrollt. */
    html { margin: 0; padding: 0; width: 100%; }
    body { margin: 0; padding: 0; width: 100%; overflow-x: hidden; }
    /* Die Fusszeile sitzt immer unten -- auch auf kurzen Seiten.
       Ohne das endete das Dokument dort, wo der Inhalt endet, und darunter blieb
       die weisse Seitenflaeche stehen: auf der 404-Seite bei 900px Fensterhoehe
       ein weisser Streifen unter der schwarzen Fusszeile. Dieselbe Sorte Luecke
       gibt es auf Impressum, Widerruf, Login und jeder anderen kurzen Seite.
       flex-column mit "main" als dehnbarem Teil ist der ganze Trick. Die
       Kopfzeile steht fixiert und liegt ohnehin ausserhalb des Flusses; style-,
       script- und iframe-Kinder sind display:none und zaehlen nicht mit.
       Zweiter Fall, andere Ursache, gleiche Wirkung: beim Ueberscrollen auf dem
       Handy zieht iOS die Seite ueber ihr Ende hinaus. Dagegen steht der Schatten
       an .site-footer -- siehe dort. Beides zusammen deckt es ab. */
    body {
      min-height: 100vh;
      min-height: 100dvh;
      display: flex;
      flex-direction: column;
    }
    /* width: 100% ist hier PFLICHT, nicht Kosmetik -- und der Grund ist unauffaellig:
       .container hat "margin: 0 auto". Im normalen Blocklayout heisst das "nimm die
       volle Breite bis max-width und stelle dich mittig". In einem Flex-Container
       heisst es etwas voellig anderes: automatische Seitenraender schlucken den
       freien Platz, und das schaltet das Dehnen ab. main schrumpfte dadurch auf die
       Breite seines Inhalts -- auf der Startseite bei 1440px Fenster gemessen 664px
       statt 1280, das Creator-Raster war knapp halb so breit wie vorgesehen.
       Mit width: 100% ist die Basisbreite wieder das Fenster, max-width deckelt bei
       1280, und die automatischen Raender zentrieren nur noch den Rest -- also genau
       das Verhalten von vorher. */
    body > main { flex: 1 0 auto; width: 100%; }
    /* Zusaetzlich zum dehnbaren "main": auf einer Seite ohne <main> -- oder wenn
       eines Tages ein Block dazwischenkommt -- schiebt der automatische Aussenabstand
       die Fusszeile trotzdem nach unten. Auf langen Seiten ist kein Platz uebrig,
       dann bewirkt er nichts. */
    body > .site-footer { margin-top: auto; }
    body {
      font-family: var(--font);
      font-size: var(--fs-body);
      /* Ohne diese Zeile steht der Zeilenabstand auf "normal", also auf dem, was die
         Schrift selbst vorschlaegt -- bei Instrument Sans knapp unter 1,2. Gemessen
         hatte der Fliesstext dadurch drei verschiedene Zeilenabstaende: 1,65 auf der
         404, 1,5 auf Impressum und Datenschutz und "normal" auf der Creator-Seite.
         1,55 ist der Mittelwert, den die vorhandenen Absaetze ohnehin anpeilen;
         Stellen mit eigener Angabe (Vorspann, Fliesstext der Rechtstexte) behalten
         ihre. */
      line-height: 1.55;
      color: var(--text);
      background: var(--bg);
    }
    a { color: inherit; text-decoration: none; }

    /* Der graue Kasten, den iOS Safari beim Antippen ueber Links und Knoepfe legt.
       Er ist scharfkantig, ignoriert jede Rundung und sieht auf einer Pillenform
       wie ein Fehler aus -- auf dem Handy beim Tippen auf "Creators" im Menue
       gesehen. Sichtbares Feedback gibt es weiterhin: ueber :active weiter unten
       und ueber :focus-visible fuer die Tastatur. */
    a, button, [role="button"], input, select, textarea, label, summary {
      -webkit-tap-highlight-color: transparent;
    }

    /* Ersatz fuer den entfernten Antipp-Kasten: ein kurzes Nachgeben beim
       Druecken. Folgt der Form des Elements, statt sie zu ueberdecken. */
    @media (hover: none) {
      a:active, button:active, .btn-base:active, .hero-cta:active, .more-button:active {
        opacity: .62;
      }
    }

    /* Formularelemente erben die Schrift NICHT von selbst -- Browser setzen dort ihre
       eigene Oberflaechenschrift. Auf der PDP fiel dadurch "Mehr anzeigen" aus dem
       Bild: der Knopf rendert in Arial, alles daneben in der Systemschrift. Nur die
       Familie erben, nicht die Groesse, damit sich keine Layouts verschieben. */
    button, input, select, textarea { font-family: inherit; }

    /* Ueberschriften -- die Grundregel fuer ALLE, Sans und 600. Die Serifenschrift
       kommt weiter unten und nur fuer eine benannte Auswahl obendrauf.
       Frueher setzte die (damals kaputte) Riccione-Regel jede Ueberschrift pauschal
       auf font-weight: 300 und ueberschrieb damit die Gewichte der Einzelseiten,
       ohne je eine Schrift zu laden. Das Gewicht steht deshalb jetzt hier. */
    h1, h2, h3, h4, h5, h6 {
      font-family: var(--font);
      /* Bewusst KEINE Farbe: Ueberschriften erben sie vom Umfeld. Eine feste Farbe
         hier haette die weisse Hero-Ueberschrift ueber dem Video ueberschrieben --
         eine Element-Regel schlaegt die geerbte Farbe des Elternelements.

         Das Gewicht dagegen ist bewusst gesetzt. Vorher stand hier 300, aber nicht
         als Entscheidung: es gehoerte zur @font-face-Regel fuer Riccione Serial, die
         nie eine Schrift geladen hat. Weggelassen wuerden alle Ueberschriften auf
         den Browser-Standard (700) springen -- auch in den Dashboards, die keine
         eigenen Gewichte setzen. 600 ist derselbe Wert wie im Auszeichnungsstil und
         damit eine Entscheidung statt eines Ueberbleibsels. */
      font-weight: 600;
      text-wrap: balance;
    }
    h1 { font-size: var(--fs-h1); }
    h2 { font-size: var(--fs-h2); }
    h3 { font-size: var(--fs-h3); }

    /* Der eine Auszeichnungsstil der Marke. Er stammt aus dem Produkttitel der PDP --
       der einzigen Stelle, an der die Typografie bisher eine bewusste Entscheidung war.
       Jetzt gilt er ueberall, wo eine Ueberschrift gross auftreten soll. */
    .display,
    /* Jede h1 ist die Ueberschrift ihrer Seite -- also ueberall dasselbe Bauteil und
       ueberall derselbe Auftritt. Ohne diese Zeile bekam sie den Stil nur dort, wo
       jemand ".display" ins Markup geschrieben hatte: gemessen standen die
       Ueberschriften von Impressum, Datenschutz und Creator-Seite auf Gewicht 600
       ohne Laufweite, waehrend 404 und alle About-Seiten auf 700 mit -0,02em
       standen. Drei Fassungen desselben Bauteils. */
    h1,
    .creators-intro h2,
    .creators-intro .intro,
    .collections-intro h2,
    .collections-intro .intro,
    .rooms-intro h2,
    .rooms-intro .intro,
    .audience-col-title,
    .audience-modal-title,
    .pdp-title,
    .pdp-teaser-title {
      font-family: var(--font);
      font-weight: var(--display-weight);
      font-style: var(--display-style);
      letter-spacing: var(--display-track);
      line-height: 1.06;
    }

    /* ── Die Serifenschrift ───────────────────────────────────────────────────
       Sie markiert NAMEN und die grossen Ansagen der Marke -- nicht Bedienung,
       nicht Erklaerungen, nicht Fliesstext. Die Liste ist bewusst geschlossen:

         .hero-overlay h1        die Zeile ueber dem Video
         .schlagwort             das eine Substantiv einer Abschnittsueberschrift
                                 ("Shop by CREATOR"), die Zeile darueber bleibt Sans
         .creator-intro h1       der Name des Creators auf seiner Seite
         .pdp-title              der Produkttitel
         .about-h                die Ueberschriften der About-Seiten

       Marken- und Kategorieseiten bleiben ausdruecklich Sans (Entscheidung Jakob).

       Warum diese Gruppe NACH der Auszeichnungsgruppe steht: mehrere dieser
       Auswahlen stehen auch dort drin. Bei gleicher Spezifitaet gewinnt die
       spaetere Regel, und das soll hier die Serifenschrift sein.

       Die Datei hat nur einen Schnitt (Light 300) -- deshalb nie unter 40px und
       nie fuer Fliesstext. Bei den About-Ueberschriften faellt damit die
       Zweitonigkeit ueber <em> ersatzlos weg: <em> bleibt rein semantisch, ohne
       eigene Farbe und ohne eigenes Gewicht. Das ist Jakobs Entscheidung
       ("schwarz schon ueberall") -- keine farbige Auszeichnung in den
       Ueberschriften, auch nicht als Ersatz fuer den fehlenden zweiten Schnitt. */
    .hero-overlay h1,
    .schlagwort,
    .creator-intro h1,
    .pdp-title,
    .about-h {
      font-family: "Riccione Serial", Georgia, "Times New Roman", serif;
      font-weight: 300;
      font-style: normal;
      letter-spacing: 0;
    }

    /* ── Ein Knopf-System ──────────────────────────────────────────────────────
       Vorher hatten der erste und der letzte Knopf der Kaufstrecke ("Shop Now" im
       Hero, "Jetzt bei ... kaufen" auf der PDP) kein einziges gemeinsames Merkmal:
       nicht Farbe, nicht Rahmen, nicht Form, nicht Innenabstand.
       Jetzt teilen sich alle Knoepfe Form, Groesse und Verhalten; nur die Farbrolle
       unterscheidet sich. .btn-invert gibt es, weil der Hero-Knopf ueber bewegtem
       Video steht -- dort ist Weiss auf Dunkel lesbarer als Schwarz. Gleiche Form,
       andere Rolle. */
    /* Diese Aufzaehlung ist die Antwort auf die Frage "und die Knoepfe?".
       Jeder anklickbare Knopf im oeffentlichen Bereich steht hier drin und teilt
       sich damit Form, Rahmenstaerke, Zeiger und Uebergang:

         .hero-cta                 "Shop Now" ueber dem Video
         .more-button              "More", "All Creators", "Discover Virtual Room"
         .pdp-cta                  "Jetzt bei Sephora kaufen"
         .button-primary           "Weiter" auf der Weiterleitungsseite
         .audience-col-cta         die drei Spalten auf /register
         .audience-mobile-cta-btn  Register/Login auf schmalen Geraeten
         .btn-base                 alles Neue (About-Seiten, 404)

       Groesse und Schriftgrad duerfen sich unterscheiden, wo der Ort es verlangt
       -- der Kaufknopf auf der PDP ist breiter als ein "Mehr" unter einem Raster.
       Die Form nicht. */
    .btn-base,
    .hero-cta,
    .more-button,
    .pdp-cta,
    .button-primary,
    .audience-col-cta,
    .audience-mobile-cta-btn {
      display: inline-block;
      font-family: var(--font);
      font-size: var(--fs-sm);
      font-weight: 500;
      line-height: 1.2;
      padding: 12px 26px;
      border-radius: var(--r-pill);
      border: 1px solid transparent;
      cursor: pointer;
      text-align: center;
      transition: background-color var(--dauer) ease, color var(--dauer) ease, border-color var(--dauer) ease;
    }
    .btn-solid {
      background: var(--accent);
      color: var(--on-accent);
      border-color: var(--accent);
    }
    .btn-solid:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
    .btn-outline {
      background: transparent;
      color: var(--text);
      border-color: var(--border-strong);
    }
    .btn-outline:hover { border-color: var(--accent); color: var(--accent); }
    .btn-invert {
      background: var(--bg);
      color: var(--accent);
      border-color: var(--bg);
    }
    .btn-invert:hover { background: transparent; color: var(--text-invert); border-color: var(--text-invert); }

    /* Wortmarke mitten in einer Ueberschrift. Hoehe in em, damit sie mit der
       Schriftgroesse waechst; die Grundlinienkorrektur haelt sie auf der Zeile.
       Der Buchstabenabstand davor faellt weg -- sonst steht die Marke bei negativer
       Laufweite (--display-track) am Nachbarbuchstaben. */
    /* Haelt die Wortmarke mit dem Wort davor und dem Satzzeichen danach zusammen.
       Ohne das faellt sie auf schmalen Geraeten allein in die letzte Zeile und
       sieht aus wie ein Umbruchfehler. */
    .zusammen { white-space: nowrap; }

    .wortmarke {
      /* Grundlinie: im viewBox (0 0 447 168) sitzt die Schriftlinie bei y=123,35 --
         das ist die Unterkante der geraden Buchstaben, das 'y' laeuft bis 167,3
         darunter. Damit die Marke auf derselben Linie sitzt wie der Text daneben,
         muss ihre Unterkante um die Unterlaenge nach unten: (168-123,35)/168 =
         26,6 % ihrer Hoehe. Bei 0,84em Hoehe sind das 0,223em.
         Vorher stand hier -0,055em -- die Marke schwebte dadurch sichtbar ueber
         der Zeile. Im Browser gegengemessen.

         Groesse: die Hoehe gilt fuer den GANZEN viewBox, nicht fuer die
         Buchstaben. Sichtbar hoch ist nur der Teil bis zur Schriftlinie, also
         123,35/168 = 73,4 % davon. Bei den frueheren 0,84em waren die Buchstaben
         damit 0,617em hoch, waehrend Instrument Sans 700 daneben auf 0,720em
         Oberlaenge steht (im Browser ueber measureText nachgemessen) -- die Marke
         war 14 % zu klein und wirkte deshalb wie hineingelegt statt mitgeschrieben.
         0,98em bringt die Buchstaben auf 0,98 x 0,734 = 0,719em, also genau auf
         die Oberlaenge der Nachbarbuchstaben. Die Grundlinienkorrektur waechst
         entsprechend mit: 0,98 x 26,6 % = 0,261em.

         Rechts fast kein Abstand: dort folgt in allen Ueberschriften ein
         Satzzeichen, und "wyrld ." mit Luecke sieht nach Versehen aus. Links etwas
         weniger als vorher, weil der viewBox bei groesserer Marke schon 0,05em
         eigene Vorbreite mitbringt. */
      height: 0.98em;
      width: auto;
      vertical-align: -0.261em;
      margin-inline: 0.10em 0.02em;
      letter-spacing: normal;
    }

    /* ── Einblenden beim Hereinscrollen ──────────────────────────────────────
       Bewusst sparsam: 350ms, 14px Weg, einmal je Element, nichts Wanderndes.

       Der Aufbau ist absichtlich herum gedreht -- und das ist der wichtige Teil.
       Naheliegend waere: Element unsichtbar, Klasse setzen, per transition
       einblenden. Genau daran ist die alte About-Seite gescheitert: dort blieb die
       Ueberschrift auf dem Handy sekundenlang unsichtbar. Eine transition, die aus
       irgendeinem Grund nicht laeuft (gedrosselter Hintergrundtab, ausgebremstes
       Geraet, Browser mit abgeschalteten Uebergaengen), laesst das Element im
       Startzustand stehen -- also unsichtbar.

       Deshalb hier: der SICHTBARE Zustand ist der Normalzustand. Unsichtbar ist nur,
       was die Klage .sichtbar noch NICHT hat. Sobald sie gesetzt ist, greift gar
       keine Deckkraft-Regel mehr -- das Element ist sofort sichtbar, und die
       Animation spielt die Einblendung nur noch als Zugabe ab. Laeuft sie nicht,
       steht der Inhalt trotzdem da.

       Dazu haengt der Startzustand an "auftauchen-aktiv" am <html>-Element. Diese
       Kennzeichnung setzt das Einblend-Skript selbst als erste Anweisung -- der
       unsichtbare Zustand kann es also nicht geben, ohne dass auch der Code da ist,
       der ihn aufloest. Bei "prefers-reduced-motion" setzt das Skript sie gar nicht
       erst. */
    @media (prefers-reduced-motion: no-preference) {
      html.auftauchen-aktiv .auftauchen:not(.sichtbar) {
        opacity: 0;
        transform: translateY(14px);
      }
      html.auftauchen-aktiv .auftauchen.sichtbar {
        /* Fuellmodus bewusst "none" und nicht "both": bei "both" haelt der Browser
           den Anfangszustand der Animation fest, solange sie noch nicht gelaufen
           ist -- also opacity 0. Mit "none" gilt ausserhalb der Laufzeit der
           normale, sichtbare Zustand des Elements. Nachgemessen. */
        animation: auftauchen 350ms cubic-bezier(0.22, 1, 0.36, 1);
      }
    }
    @keyframes auftauchen {
      from { opacity: 0; transform: translateY(14px); }
      to   { opacity: 1; transform: none; }
    }
    /* Beim Drucken zaehlt kein Scrollen: was noch nicht eingeblendet war, stuende
       sonst unsichtbar auf dem Papier. */
    @media print {
      html.auftauchen-aktiv .auftauchen:not(.sichtbar) { opacity: 1 !important; transform: none !important; }
    }

    /* Sichtbarer Tastaturfokus. Vorher gab es keinen -- wer mit der Tastatur
       navigiert, sah nicht, wo er steht.

       Bewusst OHNE border-radius: die Eigenschaft wuerde nicht den Fokusrahmen
       runden, sondern das Element selbst -- ein Pillenknopf waere im Fokus
       ploetzlich eckig. Der Rahmen folgt der vorhandenen Rundung des Elements
       von allein. */
    a:focus-visible,
    button:focus-visible,
    input:focus-visible,
    select:focus-visible,
    textarea:focus-visible,
    [tabindex]:focus-visible {
      outline: 2px solid var(--accent);
      outline-offset: 2px;
    }

  .placeholder {
    display: none;
  }

    /* Social-Icons auf der Creator-Seite. Die Farbe stand vorher viermal als
       fill="#c4ae94" direkt im SVG -- ein Attribut, das kein var() annimmt und
       damit ausserhalb jedes Farbsystems lag. Jetzt faerbt der Link, das SVG erbt
       ueber currentColor. */
    /* Die Icons zu TikTok, Instagram und Pinterest standen auf --accent-soft: 2,14:1
       gegen Weiss. Fuer bedeutungstragende Grafik verlangt WCAG 1.4.11 mindestens
       3:1, und praktisch verschwinden sie auf einem Handy im Hellen. --text-muted
       sind 5,74:1 und bleiben trotzdem zurueckhaltend; beim Zeigen gehen sie wie
       vorher auf die volle Textfarbe.
       (--accent-soft selbst bleibt im Farbsatz und traegt weiter die grosse Ziffer
       auf der 404-Seite -- dort ist sie aria-hidden und rein dekorativ.) */
    /* Die Social-Symbole waren 35x20px gross -- die einzigen Ausgaenge vom
       Creator-Profil auf dessen Kanaele, und der kleinste Tippbereich der ganzen
       Seite. Im Browser bei 375px nachgemessen. Jetzt 44x44 wie in der Kopfzeile;
       das Symbol darin bleibt unveraendert gross. */
    .creator-intro > a {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      min-width: 44px;
      min-height: 44px;
    }
    .creator-intro a svg { color: var(--text-muted); transition: color var(--dauer) ease; }
    .creator-intro a:hover svg { color: var(--text); }


    /* HEADER */


    /* Sticky header */
    .header {
      /*
      position: absolute;
      */
      position: fixed; 
      top: 0; left: 0; right: 0; z-index: 100;
      background: var(--bg);
      /* KEIN backdrop-filter im Grundzustand.
         Hier stand "backdrop-filter: blur(0px)" -- ein Weichzeichner mit Radius 0,
         also ohne jede sichtbare Wirkung. Er zwingt die Kopfzeile aber dauerhaft auf
         eine eigene GPU-Ebene, und an deren Kante entstehen auf iOS 1px-Nahtstellen:
         genau der Spalt zwischen Kopfzeile und Bereichsnavigation, durch den man den
         Inhalt durchscrollen sieht. Im Desktop-Browser ist er nicht ausloesbar (an
         14 Breiten und acht Scrollpositionen gemessen, Luecke ueberall 0), auf dem
         Geraet schon.
         Gebraucht wird der Filter nur von ".header.blurred" -- und die Klasse wird
         ausschliesslich in affiliate-homepage.html gesetzt, einer Vorlage mit eigenem
         CSS, die page_css gar nicht einbindet. Auf allen normalen Seiten war er
         reiner Ballast. */
      transition: background var(--dauer) ease;
      /* border-bottom: 1px solid var(--border); */
    }
    .header.blurred {
      background: rgba(0,0,0,0.15);
      -webkit-backdrop-filter: blur(2px);
      backdrop-filter: blur(2px);
    }
    @media (prefers-reduced-motion: reduce) {
      .header { transition: none; }
      .tile { transition: none; }
    }
    .bar {
      display: flex; 
      align-items: center; 
      justify-content: space-between; 
      height: 78px;
      transition: height var(--dauer) ease, background var(--dauer) ease, padding var(--dauer);
    }
    body.homepage .header .bar { height: 108px; }
    body.homepage .header.intransparent .bar { height: 64px; }
    .header.intransparent .bar { height: 60px; }

    .left { display: flex; align-items: center; gap: 10px; }
    .logo { width: 100px; height: 32px; transition: height var(--dauer) ease;}
    .logo svg path { transition: fill var(--dauer); }
    .logo svg { max-height: 100%; transition: height var(--dauer);}
    .brand { letter-spacing: -0.01em; }

    .right { display: flex; align-items: center; gap: 18px; }
    /* 400 statt 200: Instrument Sans hat eine Gewichtsachse von 400 bis 700. Ein
       angefordertes 200 klemmt der Browser stillschweigend auf 400 -- die Angabe
       waere also eine Behauptung ohne Wirkung, genau die Sorte, die uns bei der
       Schrift schon einmal sieben Monate gekostet hat. Sichtbare Folge: die
       Kopfzeilen-Links sind etwas kraeftiger als mit der Systemschrift, wo 200
       tatsaechlich ein hauchduenner Schnitt war. */
    .menu { display: flex; gap: 14px; color: var(--menu-color); font-weight: 400; font-size: var(--fs-sm); transition: color var(--dauer); }
    .button { padding: 6px 8px; font-size: var(--fs-sm); transition: color var(--dauer); cursor: pointer; }
    .button.selected, .button.selected:hover { background-color: var(--text-muted); color: var(--text-invert); }
    .register { padding: 6px 12px; font-size: var(--fs-sm); transition: color var(--dauer); }
    .menu a {
        margin-right: 14px;
        transition: color var(--dauer);
    }
    /* Tippflaeche der Kopfzeilen-Links auf volle Kopfzeilenhoehe ziehen.
       Vorher war das anklickbare Feld nur so hoch wie der Text selbst -- 15px, bei einer
       Empfehlung von mindestens 44px. Direkt unterhalb der Kopfzeile beginnt auf der
       Startseite bereits das Creator-Raster: Wer auf dem Handy ein paar Pixel zu tief tippte,
       landete statt auf "Register" auf einem Creator-Profil. Genau so gemeldet und im Browser
       nachgestellt.
       Nur senkrechter Innenabstand, keine Randaenderung: der Text steht unveraendert an
       derselben Stelle, die Trefferflaeche waechst darum herum.

       ACHTUNG, die Zahlen hier waren veraltet: sie stammten aus der Zeit, als die
       Leiste 54px hoch war, und nannten 53px Trefferflaeche bei Text-Mitte y=27.
       Die Leiste ist inzwischen hoeher. Neu nachgemessen:

         375px:  Leiste 64px, Trefferflaeche 58px, Text-Mitte y=32
        1440px:  Leiste 78px, Trefferflaeche 60px, Text-Mitte y=39

       Die 44px sind damit in beiden Faellen deutlich ueberschritten -- was die Regel
       hier bezweckt, gilt weiter. Nur die konkreten Werte gehen mit der
       Kopfzeilenhoehe mit, also beim naechsten Mal wieder nachmessen statt
       fortzuschreiben. */
    .header .menu a {
        padding: 19px 0;
    }
    /* Der Abstand zwischen den Kopfzeilen-Links.
       Hier stand kurzzeitig gap: 28px, weil ich "gap: 14px" und "margin-right: 14px"
       an .menu a gesehen und daraus 28px Abstand plus 14px hinter dem letzten Link
       geschlossen habe. Beim Vergleich Element fuer Element gegen main gemessen: das
       margin greift dort gar nicht, es kommt auf 0px an. Der echte Abstand ist 14px,
       und hinter dem letzten Link steht nichts -- seine rechte Kante sitzt bei 359px
       in einer 375px breiten Leiste, also genau auf dem Seitenrand des Containers.
       Es gab nichts zu korrigieren. Das margin-right: 0 bleibt trotzdem stehen: es
       schreibt hin, was ohnehin gilt, statt es einer Ueberschreibung zu ueberlassen,
       die irgendwo weiter unten steht. */
    .header .menu { gap: 14px; }
    .header .menu a { margin-right: 0; }
    /* Auf schmalen Geraeten enger. Bei 320px Fensterbreite steht neben dem Logo
       184px Platz zur Verfuegung, die Liste braucht mit 14px Abstand aber 214 --
       "Register" wird abgeschnitten. Mit 10px passt sie bei 360 und 375 mit
       deutlichem Rand und bei 320 fast; im Browser nachgemessen. Weiter runter zu
       gehen hiesse, die Schrift zu verkleinern, und dafuer ist die Kopfzeile die
       falsche Stelle.

       Was "fast" genau heisst, nachgemessen bei 320px: der Streifen ist 178px
       breit und endet buendig bei 304, sein Inhalt ist 202px -- "Register" reicht
       bis 328 und steht damit 8px hinter dem rechten Fensterrand. Es ist nicht
       verloren, sondern erreichbar, weil ".header .menu" weiter unten waagerecht
       scrollt. Wer hier flex-shrink abschaltet, damit es ohne Wischen passt,
       bricht den angemeldeten Fall: dort sind es sechs Eintraege, und dann wandert
       das Logo aus dem Bild (siehe die Begruendung zu ".header .right"). */
    @media (max-width: 640px) {
      .header .menu { gap: 10px; }
    }
    /* Die Kopfzeile hat kein Klappmenue, alle Eintraege stehen immer nebeneinander.
       Angemeldet sind es bis zu sechs (About, Creators, Dein Profil, Deine
       Produkte, Abrechnung, Logout); bei 375px Fensterbreite braucht diese Liste
       364px und hat neben dem Logo 259px -- im Browser gemessen. Ohne diese Regel
       schiebt sie das Logo aus dem Bild. Mit ihr wandert nur die Liste. */
    .header .right { min-width: 0; }
    .header .menu { overflow-x: auto; overflow-y: hidden; scrollbar-width: none; }
    .header .menu::-webkit-scrollbar { display: none; }
    /* Angemeldet und schmal: die Leiste klappt zu einem Menue. Der Knopf steht
       nur im Markup, wenn topMenuVoll gesetzt ist (page_header), und wird nur
       unter 640px gezeigt -- auf dem Desktop bleiben die Links nebeneinander.
       Das Menue haengt als Ebene unter der fixierten Kopfzeile (top: 100%),
       geht also auch mit der niedrigeren .intransparent-Leiste mit. Eine Zeile
       je Eintrag, 52px hoch wie die Liste im Dashboard, eigener Hintergrund
       und eigene Textfarbe, damit es auch ueber dem Startseiten-Hero lesbar
       ist, wo die Leiste durchsichtig und die Linkfarbe weiss ist. */
    .menu-knopf { display: none; }
    /* ================================================================
       SEITEN HINTER DEM LOGIN: ein Kopf fuer alle.
       ================================================================
       Vorher hatte jede Seite ihren eigenen: 32px/600 auf dem Creator-
       Dashboard, 28px/600 als <div> im Admin-Dashboard, --fs-h2 in Georgia
       auf Shops, Produktpflege und Katalogen (Riccione Serial ist seit dem
       28.08. draussen, der Fallback war Georgia), --fs-h1 auf der
       Produktsuche. Elf Seiten, fuenf Ueberschriften (gemessen 08.09.2026).
       Jetzt: h1.app-titel, 28px (24 auf dem Handy), Gewicht und Laufweite
       wie jede Auszeichnung; darunter .app-untertitel in --fs-sm gedaempft.
       ".container h1.app-titel" zusaetzlich: weiter unten setzt ".container h1"
       die Groesse auf --fs-h1, gleiche Spezifitaet und spaeter im Text -- auf
       der Produktliste, deren h1 in einem .container steht, blieb die
       Ueberschrift dadurch bei 28px statt 24 (gemessen bei 375px). */
    h1.app-titel,
    .container h1.app-titel {
      font-size: 28px;
      font-weight: var(--display-weight);
      letter-spacing: var(--display-track);
      line-height: 1.2;
      margin: 0 0 4px;
      color: var(--text);
    }
    .app-untertitel {
      margin: 0;
      color: var(--text-muted);
      font-size: var(--fs-sm);
      line-height: 1.5;
      max-width: 68ch;
    }
    @media (max-width: 640px) {
      h1.app-titel,
      .container h1.app-titel { font-size: 24px; }
    }
    @media (max-width: 640px) {
      .header.menu-voll .menu-knopf {
        display: inline-flex; flex-direction: column; justify-content: center; gap: 5px;
        width: 44px; height: 44px; margin-right: -11px; padding: 0;
        /* inherit, nicht --menu-color: die Links bekommen ihre Farbe ueber
           "body .menu { color: var(--text) }", --menu-color ist weiss und nur
           fuer die durchsichtige Leiste ueber dem Startseiten-Hero gedacht.
           Mit --menu-color war der Knopf auf jeder normalen Seite weiss auf
           weiss -- in den Screenshots schlicht nicht da. */
        border: 0; background: none; color: inherit; cursor: pointer;
        border-radius: var(--r-sm);
      }
      body.homepage .header:not(.intransparent) .menu-knopf { color: var(--menu-color); }
      .header.menu-voll .menu-knopf span {
        display: block; width: 22px; height: 2px; margin: 0 auto;
        background: currentColor; border-radius: 2px;
        transition: transform var(--dauer) ease, opacity var(--dauer) ease;
      }
      .header.menu-voll.menu-offen .menu-knopf span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
      .header.menu-voll.menu-offen .menu-knopf span:nth-child(2) { opacity: 0; }
      .header.menu-voll.menu-offen .menu-knopf span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
      .header.menu-voll .menu {
        display: none; position: absolute; left: 0; right: 0; top: 100%;
        max-height: calc(100vh - var(--kopf-hoehe)); overflow-y: auto;
        flex-direction: column; gap: 0; padding: 4px 20px 12px;
        background: var(--bg); color: var(--text);
        border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
        box-shadow: 0 16px 32px rgba(0, 0, 0, 0.08);
      }
      .header.menu-voll.menu-offen .menu { display: flex; }
      .header.menu-voll .menu a {
        display: flex; align-items: center; min-height: 52px; padding: 0;
        font-size: var(--fs-body); border-bottom: 1px solid var(--border);
      }
      .header.menu-voll .menu a:last-child { border-bottom: 0; }
    }
    .menu a:hover,
    .header.intransparent .menu a:hover {
      color: var(--text-muted);
    }
    body.homepage .menu a:hover {
      color: var(--menu-hover);
    }
    .register:hover, .button:hover {
      color: var(--menu-hover);
    }
    a.register:hover, span.button:hover {
      color: var(--menu-hover) !important;
    }
    /* Mobile View */
    @media (max-width: 1296px) {
      body.homepage .container.bar { padding: 0 32px; }
    }
    @media (max-width: 640px) {
      /* Auf schmalen Geraeten ist die Leiste 64px hoch (siehe .header .bar unten),
         der Abstand darunter muss mitgehen. */
      :root { --kopf-hoehe: 64px; }
      /*.menu { display: none; }*/
      body.homepage .container.bar { padding: 0 16px 0 20px; }
      .header .bar { height: 64px; }
      .header.intransparent .bar { height: 54px; }
      .header.intransparent .logo { height: 28px; }
      body.homepage .header .bar { height: 64px; }
      body.homepage .header.intransparent .bar { height: 54px; }
    }
    @media (prefers-reduced-motion: reduce) {
      .tile::before { transition: none; }
    }



    /* Common Layout Elements */
    .hidden { display: none !important; }
    /* Sichtbar nur fuer Vorleseprogramme. Gebraucht dort, wo eine Seite eine
       Hauptueberschrift haben MUSS, aber keine zeigen soll -- /register besteht
       aus drei gleichrangigen Spalten und hatte deshalb gar keine h1. */
    .nur-vorlesen {
      position: absolute;
      width: 1px; height: 1px;
      margin: -1px; padding: 0; border: 0;
      overflow: hidden;
      clip-path: inset(50%);
      white-space: nowrap;
    }
    .opacity-25 { opacity: 0.25; }
    .opacity-50 { opacity: 0.5; }
    .opacity-75 { opacity: 0.75; }
    .opacity-100 { opacity: 1; }
    .container {
      max-width: 1280px; 
      margin: 0 auto; 
      padding: 0 16px; 
      transition: height var(--dauer) ease, background var(--dauer) ease, padding var(--dauer);
    }
    /* Die Kopfzeile ist fixiert und nimmt im Fluss keinen Platz ein. Jede Seite
       ausser der Startseite -- dort liegt sie absichtlich transparent ueber dem
       Hero -- braucht deshalb genau diesen Abstand darunter.
       Vorher stand er an jeder Seite einzeln und in vier Varianten: als
       .unter-header (404, About-Nav, Guide), als .mt-80 (Impressum, Datenschutz),
       ueber die About-Navigation (die restlichen About-Seiten) -- und auf
       /creators, /brands, /categories und /rooms ueberhaupt nicht. Dort lief der
       Inhalt unter der Kopfzeile durch: im Browser gemessen stand die erste
       Ueberschrift von /creators bei y=32 unter einer 78px hohen Leiste.
       Ein Ort, eine Regel, keine Klasse zum Vergessen. */
    main { padding: 24px 0 0; }
    body:not(.homepage) main { padding-top: calc(var(--kopf-hoehe) + 24px); }
    .placeholder { padding: 40px; border: 1px dashed var(--border); border-radius: var(--r-md); color: var(--text-muted); text-align: center; }
      /* Altbestand aus der Zeit vor dem Auszeichnungsstil -- und inzwischen ohne
         Wirkung. Hier stand frueher, die Regel greife noch auf den Marken- und
         Kategorieseiten ("Die Top Auswahl unserer Creator"). Das stimmt nicht mehr:
         dort liegt ".container h2" darueber (0,1,1 gegen 0,0,2), gemessen 34px statt
         der 4rem hier. Auf 19 oeffentlichen Seiten nachgesehen -- Startseite,
         Rasterseiten, Marke, Kategorie, Creator, alle About-Seiten, Rechtstexte,
         Login, Register, Produktseite -- ist KEINE einzige h2 in main 64px gross:
         jede wird von .container h2, .about-h, .about-kachel h2,
         .pdp-teaser-title oder .audience-col-title uebersteuert.

         Die Regel kann damit vermutlich ersatzlos weg. "Vermutlich", weil die
         Seiten hinter dem Login (Dashboards, Produktpflege) in dieser Durchsicht
         nicht dabei waren -- wer sie loescht, sollte dort einmal nachsehen. Bis
         dahin bleibt sie stehen; die Kursivstellung ist raus, damit diese
         Ueberschriften aufrecht stehen wie alle anderen. */
      /* "font-weight: 400" stand hier und war eine Auffangregel mit Fernwirkung:
         sie traf jede h2 in main, fuer die keine spezifischere Regel ein Gewicht
         setzt. Auf Impressum und Datenschutz setzt ".content h2" nur die Groesse --
         deren Ueberschriften standen dadurch auf 400, waehrend jede andere h2 der
         Seite auf 600 oder 700 steht. Ohne die Zeile greift die Basisregel fuer
         h1..h6 (600). Groesse und Abstand bleiben unveraendert. */
      main h2 {
        font-size: 4rem;
        margin-top: 4rem;
        margin-bottom: 4rem;
    }
    main h2 .intro {
        font-weight: 400;
        font-size: 1.5rem;
        display: block;
    }

    /* Form, Groesse und Uebergang kommen aus der Gruppe oben. Hier nur die Farbrolle.
       Vorher stand hier 6px/12px bei 12px Schrift und font-weight 200 -- fuer die
       Hauptaktion der Weiterleitungsseite ("Weiter") deutlich zu klein und zu duenn. */
    .button-primary {
      background-color: var(--accent);
      color: var(--on-accent);
      border-color: var(--accent);
    }
    .button-primary:hover {
      background: var(--accent-hover);
      border-color: var(--accent-hover);
      color: var(--on-accent);
    }
    .button-primary.big {
      padding: 14px 32px;
      font-size: var(--fs-body);
    }

    .button-secondary {
        border: 1px solid var(--border); 
        color: var(--menu-color); 
        /* 500 wie alle anderen Knoepfe -- 200 gab es in dieser Schrift ohnehin nicht. */
        font-weight: 500;
        transition: background var(--dauer) ease, backdrop-filter var(--dauer) ease, color var(--dauer) ease, border-color var(--dauer) ease, color var(--dauer) ease;
    }
    .button-secondary:hover {
        background: rgba(255,255,255, 0.2);
        backdrop-filter: blur(2px);
        color: var(--text-invert);
    }
    .muted {
        color: var(--muted);
    }
    .small {
      font-size: var(--fs-xs);
    }




    /* Homepage Elements */
    body .menu { color: var(--text); }
    /* Die Wortmarke nimmt dieselben Farben wie der Text daneben. Vorher standen
       hier "black" und "white" direkt -- die einzigen Stellen im oeffentlichen
       CSS, an denen die Kopfzeile am Farbsatz vorbei gefaerbt wurde. */
    body .logo svg path { fill: var(--text); }
    body .button-secondary { color: var(--text); border-color: var(--border-strong); }
    /* Special Header for Homepage */
    body.homepage .header { background: transparent; }
    body.homepage .menu { color: var(--text-invert); }
    body.homepage .logo svg path { fill: var(--text-invert); }
    body.homepage .button-secondary { color: var(--text-invert); border-color: var(--text-invert); }
    /* Header on homepage is scrolled down*/
    body.homepage .header.intransparent { background: var(--bg); }
    body.homepage .header.intransparent .menu { color: var(--text); }
    body.homepage .header.intransparent .logo svg path { fill: var(--text); }
    body.homepage .header.intransparent .button-secondary { color: var(--text); border-color: var(--border-strong); }

    /* Full-width top video */
    .hero-video { margin: 0; padding: 0; position: relative; }
    .hero-video video { display: block; width: 100%; height: 90vh; object-fit: cover; object-position: center; }
    /* Auf grossen Desktop-Screens hat 90vh praktisch den ganzen sichtbaren Bereich gefuellt --
       ohne jeden Hinweis darauf, dass unter dem Video noch etwas kommt (Jakob: "ich sehe
       nicht, dass da noch was auf der Seite folgt"). Etwas kuerzer, damit "Shop by Creator"
       schon leicht ins Bild ragt. Auf Mobile unveraendert, da laut Feedback schon ok. */
    @media (min-width: 1000px) {
      .hero-video video { height: 78vh; }
    }
    /* Standbild-Ebene ueber dem Video.
       iOS legt einen eigenen Abspielknopf mitten ins Video, sobald es das automatische
       Abspielen verweigert -- im Strom- wie im Datensparmodus. Diesen Knopf per CSS
       auszublenden funktioniert auf aktuellen iOS-Versionen nicht mehr, Apple hat den
       Zugriff auf die Steuerelemente dichtgemacht (auf staging ausprobiert, der Knopf
       blieb stehen).
       Deshalb der Weg drumherum statt dagegen: ein Standbild liegt als eigene Ebene UEBER
       dem Video und verdeckt es samt Knopf. Es verschwindet erst, wenn das Video
       tatsaechlich laeuft. Das Bild stammt aus Sekunde 0 des Videos, der Wechsel ist
       deshalb nicht zu sehen.
       Wichtig: das Video wird NICHT auf display:none gesetzt -- ein ausgeblendetes Video
       startet in manchen Browsern gar nicht erst. Es bleibt sichtbar und liegt nur unten. */
    .hero-video .hero-standbild { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center; }
    .hero-video.laeuft .hero-standbild { display: none; }

    .hero-overlay { position: absolute; inset: 0; z-index: 1; display: flex; align-items: center; justify-content: center; text-align: center; padding: 0 24px; color: var(--text-invert); flex-direction: column; gap: 14px; }
    /* Die Hero-Ueberschrift ist die eine Stelle mit der Serifenschrift. Sie steht
       deshalb NICHT im Auszeichnungsstil, sondern setzt Familie, Gewicht und
       Laufweite selbst -- die enge Laufweite von --display-track ist fuer eine
       leichte Serifenschrift zu eng, und Gewicht 700 gibt es in dieser Datei nicht
       (sie hat nur einen Schnitt, Light). */
    /* Schrift, Gewicht und Laufweite kommen aus der Serifen-Gruppe oben. */
    .hero-overlay h1 {
      margin: 0 0 14px;
      line-height: 1.08;
      font-size: var(--fs-display);
      text-shadow: 0 4px 24px rgba(0,0,0,0.45);
    }

    /* Form, Groesse und Uebergang kommen aus .btn-base weiter oben. Hier nur die
       Farbrolle: ueber dem Video ist Weiss auf Dunkel lesbarer als Schwarz. */
    .hero-cta {
      background: var(--bg);
      color: var(--accent);
      border-color: var(--bg);
      padding: 13px 34px;
    }
    .hero-cta:hover {
      background: transparent;
      color: var(--text-invert);
      border-color: var(--text-invert);
    }

    /* Responsive grid */
    /* Zwei Rasterarten, zwei Abstaende -- aber jeweils nur EINER.
       Bildkacheln (dieses Raster fuer Rooms/Marken/Kategorien und #creators-grid)
       stehen dicht beieinander, das ist die Collage-Wirkung: 6px. Produktkarten
       (.product.grid und .pdp-teaser-grid) brauchen mehr Luft: 10px.
       Vorher waren es vier Werte fuer vier Raster -- 4, 6, 10 und 16/24 -- und
       beim Scrollen ueber die Startseite aendert sich der Rhythmus von Abschnitt
       zu Abschnitt, ohne dass etwas anderes wechselt. */
    .grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
    /* Vorher eckig, waehrend Produktkacheln daneben gerundet waren -- derselbe
       Kachel-Typ auf derselben Seite, zwei verschiedene Formen. Jetzt --r-md wie
       jede andere Flaeche, die fuer sich auf der Seite steht. */
    .tile { position: relative; aspect-ratio: 4 / 5; border-radius: var(--r-md); overflow: hidden; background-size: cover; background-position: center; background-repeat: no-repeat; }
    .tile::before { content: ""; position: absolute; inset: 0; xxbackground-image: inherit; background-size: cover; background-position: center; background-repeat: no-repeat; transform: scale(1); transition: transform var(--dauer-lang) ease; }
    .tile:hover::before { transform: scale(1.06); }
    /* .tile .label stand hier mit 14px und wurde weiter unten von .grid .label mit
       32px wieder ueberschrieben -- zwei Regeln fuer dasselbe Element. Die
       Beschriftung ist jetzt einmal definiert, siehe "Name auf einer Bildkachel". */

    @media (max-width: 1000px) {
      .grid { grid-template-columns: repeat(2, 1fr); }
      .grid > .tile8 { display: none; }
    }

    @media (min-width: 1000px) {
      .grid { grid-auto-flow: dense; }
      .tile.primary { grid-column: span 2; grid-row: span 2; }
      /* Wie bei den Creator-Kacheln: ohne genug nachfolgende Kacheln bleibt die
         zweite Zeile leer, die grosse Kachel wird um den Zeilenabstand hoeher als
         ihre Nachbarinnen und die Unterkanten stehen versetzt. Vier Spalten,
         2x2-Kachel -> es muessen noch vier Kacheln folgen. */
      .grid .tile.primary:nth-last-child(-n+4) { grid-column: auto; grid-row: auto; }
      /* Float tiles 4 and 5 around the primary tile on the first row */
      .grid.creators > .tile:nth-child(4) { grid-column: 3; grid-row: 1; }
      .grid.creators > .tile:nth-child(5) { grid-column: 4; grid-row: 1; }
    }

    .grid.creators .tile { position: relative; }
    /* ── Name auf einer Bildkachel ──────────────────────────────────────────
       Gilt fuer beide Raster: Creator-Kacheln (#creators-grid .creator-tile-label
       in grid_creators.html) und das Raster fuer Rooms, Marken und Kategorien
       (.grid .label). Das waren vorher zwei Systeme -- Creator 18px, ab 640px
       22px, fuer die grossen Kacheln bis 28px; Rooms dagegen flach 32px ohne
       jede Anpassung. Auf derselben Seite, fuer dasselbe Element.
       Die Ausnahmen fuer die grossen Creator-Kacheln stehen weiterhin in
       grid_creators.html, weil sie an deren nth-child-Regeln haengen. */
    .grid .label,
    #creators-grid .creator-tile-label,
    #collections-grid .creator-tile-label {
      position: absolute;
      z-index: 1;
      font-size: 18px;
      line-height: 1.1;
      font-weight: var(--display-weight);
      font-style: var(--display-style);
      color: var(--text-invert);
      text-shadow: 0 2px 6px rgba(0,0,0,0.35);
      /* Lange Einzelwoerter (z.B. "Dannenberg") haben ohne diese beiden Regeln
         keine Umbruchstelle und laufen ueber den rechten Kachelrand hinaus. */
      overflow-wrap: break-word;
      word-break: break-word;
    }
    #creators-grid .creator-tile-label,
    #collections-grid .creator-tile-label { top: 14px; left: 14px; right: 14px; }
    .grid .label.top-left     { top: 14px; left: 14px; right: 14px; }
    .grid .label.top-right    { top: 14px; right: 14px; left: 14px; text-align: right; }
    .grid .label.bottom-left  { bottom: 14px; left: 14px; right: 14px; }
    .grid .label.bottom-right { bottom: 14px; right: 14px; left: 14px; text-align: right; }
    @media (min-width: 640px) {
      .grid .label,
      #creators-grid .creator-tile-label { font-size: 22px; }
      #creators-grid .creator-tile-label { top: 18px; left: 18px; right: 18px; }
      .grid .label.top-left     { top: 18px; left: 18px; right: 18px; }
      .grid .label.top-right    { top: 18px; right: 18px; left: 18px; }
      .grid .label.bottom-left  { bottom: 18px; left: 18px; right: 18px; }
      .grid .label.bottom-right { bottom: 18px; right: 18px; left: 18px; }
    }

    .brand.grid .tile::after {
      content: "";
      position: absolute;
      inset: 0;
      background: rgba(0, 0, 0, 0.4);
      z-index: 0;
    }

    /* Markenkacheln behalten die mittige Ausrichtung -- dort liegt ein dunkler
       Schleier ueber dem Bild, der Name steht bewusst in der Mitte. Groesse und
       Schriftschnitt kommen aus derselben Regel wie oben. */
    .brand.grid .label {
      position: absolute;
      top: 50%;
      bottom: auto;
      left: 0;
      right: 0;
      transform: translateY(-50%);
      width: 100%;
      padding: 0 20px;
      text-align: center;
      z-index: 2;
    }
    .center {
      text-align: center;
    }

    .mt-40 { margin-top: 40px; }
    .mt-80 { margin-top: 80px; }
    .mb-40 { margin-bottom: 40px; }
    .mb-80 { margin-bottom: 80px; }

    
    /* CONTENT PAGES */

    /* Impressum, Datenschutz, Widerruf. Der Block stand vorher wortgleich in
       page_impressum.html UND page_datenschutz.html -- zweimal dasselbe, auf
       beiden Seiten mit ausgeliefert.

       Wichtig war dabei "font-size: 3rem" an der Ueberschrift: eine feste Groesse
       quer zur Groessenstaffel. Bei 375px Fensterbreite ist
       "Datenschutzerklaerung" in 48px 495px breit und laeuft damit 152px aus
       seinem 343px breiten Kasten -- ein einzelnes langes Wort bricht nicht von
       allein um. Im Browser nachgemessen. Mit --fs-h1 sind es dort 28px und das
       Wort passt.

       hyphens zusaetzlich, weil das Dokument lang="de" traegt und deutsche
       Komposita sonst genau diese Sorte Ueberlauf erzeugen. */
    .content h1 {
        font-size: var(--fs-h1);
        margin: 2rem 0;
    }
    .content h2 {
        font-size: var(--fs-h3);
        margin: 2rem 0 1rem;
    }
    .content h1,
    .content h2,
    .content h3 {
        hyphens: auto;
        overflow-wrap: break-word;
    }
    /* Dieselbe Behandlung wie die Ueberschriften darueber, aus demselben Grund und
       einmal zu wenig gemacht: die Rechtstexte sind deutsch und stecken voller
       Komposita, dazu stehen im Datenschutz ausgeschriebene Adressen im Fliesstext
       (https://www.instagram.com/..., https://policies.google.com/...). Beides
       bricht ohne Hilfe nicht um. Bei 320px im Browser nachgemessen: fuenf Absaetze
       standen 3 bis 22px ueber der Textspalte. hyphens: auto trennt die Komposita
       (lang="de" steht am Dokument), overflow-wrap faengt die Adressen. */
    .para {
        margin: 0;
        padding: 0;
        line-height: 1.5;
        hyphens: auto;
        overflow-wrap: break-word;
    }
    .content li, .content td { hyphens: auto; overflow-wrap: break-word; }


    .product-page .brand {
        margin-top: 30px;
        color: var(--text-muted);
    }

    .more-button {
        background: transparent;
        color: var(--text);
        border-color: var(--border-strong);
    }
    .more-button:hover {
        background: var(--accent);
        color: var(--on-accent);
        border-color: var(--accent);
    }
    #brands-grid.all .brands.hidden,
    #rooms-grid.all .rooms.hidden,
    #categories-grid.all .categories.hidden,
    #creators-grid.all .creators.hidden {
        display: block !important;
    }

    section h2 {
      text-align: center;
    }
    section h2 .intro {
      margin-bottom: 10px;
    }

    
    /* Das graue Band hinter den Produktrastern. Der Abstand nach oben stand vorher
       nur auf der Creator-Seite, und zwar als Inline-Stil (margin-top: 60px);
       Marken- und Kategorieseite hatten gar keinen. Dreimal dasselbe Bauteil, zwei
       Abstaende. Jetzt hier, einmal. */
    .bg-grey {
      background-color: var(--surface-sunk);
      width: 100%;
      /* 60px waren auf dem Handy zu viel: zwischen dem Profilblock und dem grauen
         Band stand eine leere weisse Flaeche, waehrend darueber schon der Abstand
         zur Kopfleiste sass. Mitwachsend 24 bis 44 -- auf dem Desktop also 44 statt
         60, auf dem Handy 24.
         Achtung beim Nachmessen: was man zwischen den Social-Symbolen und dem Band
         sieht, ist NICHT dieser Wert. Creator mit hinterlegtem Raum haben darunter
         noch den Knopf "Discover Virtual Room" mit eigenem Abstand -- auf Kisus
         Seite sind es dadurch 99px, auf einer Seite ohne Raum 27. */
      margin: clamp(24px, 5vw, 44px) 0 0;
      padding: 0 10px;
    }

    /* Nur Groessen, keine Gewichte. Das "font-weight: 600" stand hier frueher und
       hat den Auszeichnungsstil ausgehebelt: .container h2 und die .display-Gruppe
       haben dieselbe Spezifitaet, und diese Regel steht spaeter -- "Shop by Creator"
       lief dadurch auf 600, waehrend --display-weight auf 700 stand. Im Browser
       nachgemessen. Gewichte kommen jetzt ausschliesslich aus der Basisregel fuer
       h1..h6 (600) und dem Auszeichnungsstil (--display-weight). */
    /* Diese vier Werte standen quer zur Groessenstaffel und haben die Rangfolge
       umgedreht: h1 auf 2rem (32px), h2 auf 3rem (48px). Auf der Marken- und der
       Kategorieseite war die Seitenueberschrift damit KLEINER als die
       Abschnittsueberschrift darunter -- "Massimo Dutti" 32px ueber "Die Top
       Auswahl unserer Creator" 48px. Im Browser nachgemessen.
       Jetzt dieselben Tokens wie ueberall sonst: h1 klar ueber h2. */
    .container h1 { font-size: var(--fs-h1); }
    /* Die Ueberschrift der Rasterseiten (Creators, Marken, Kategorien, Raeume) ist
       ein h1 -- jede Seite braucht genau eine Hauptueberschrift, sonst fehlt
       Screenreadern und Suchmaschinen der Einstieg. Sie war vorher ein h2, und die
       vier Seiten hatten damit gar kein h1.

       Diese Regel setzt die Groesse aber nur auf ZWEI der vier: auf /brands und
       /categories, wo sie ein h2 bleibt -- eine Ueberschrift ueber einem Raster,
       kein Seitentitel im Hero-Format. /creators und /rooms bringen mit
       ".creators-intro h1" bzw. ".rooms-intro h1" ihre eigene Anzeigestaffel mit
       (44 / 72 / 96px) und gewinnen dagegen: gleiche Spezifitaet (0,1,1), aber
       ihr <style> steht spaeter im Dokument. Im Browser bei 320px nachgemessen:
       /brands und /categories 24px (= --fs-h2), /creators und /rooms 44px. Wer
       --fs-h2 aendert, aendert also nur die Haelfte der Rasterseiten.

       Der Aufhaenger ist das .schlagwort darin, nicht der umgebende Abschnitt: zwei
       der vier Seiten haben ein <section> ganz ohne Klasse.

       Und die Regel steht bewusst HIER, direkt hinter ".container h1": beide haben
       dieselbe Spezifitaet (0,1,1), also entscheidet die Reihenfolge. Weiter oben
       platziert hat ".container h1" gewonnen und die Ueberschrift stand auf 44px. */
    h1:has(> .schlagwort) { font-size: var(--fs-h2); }
    .container h2 { font-size: var(--fs-h2); }
    .container h3 { font-size: var(--fs-h3); }
    .container h4 { font-size: 1rem; }
    
    /* Der Abstand ueber dem Profilbild stand fest auf 64px -- auf jedem Geraet
       derselbe Wert. Jetzt mitwachsend: 28px auf dem Handy, ab 1067px unveraendert
       64, der Desktop bleibt also wie er war.
       Was am Ende zwischen Kopfleiste und Profilbild steht, ist die Summe aus dem
       Abstand an "main" (Kopfhoehe plus 24) und diesem Wert hier. Bei 375px sind
       das 24 + 28 = 52px, im Browser nachgemessen; vorher waren es 24 + 64 = 88. */
    .container .intro {
        padding-top: clamp(28px, 6vw, 64px);
        text-align: center;
    }
    /* Die Beschreibung des Creators lief ueber die volle Spaltenbreite. Auf einem
       1920px breiten Schirm stand sie als EINE Zeile von 1800px -- das Auge findet
       am Zeilenende den Anfang der naechsten nicht mehr. 62 Zeichen ist die Breite,
       auf der auch der Rest der Seite laeuft. Trifft nur die Creator-Seite: die
       Marken- und Kategorieseiten haben in .intro kein <p>. */
    .container .intro > p {
        max-width: 62ch;
        margin-left: auto;
        margin-right: auto;
    }
    .container .intro .icon img {
        width: 120px;
        height: 120px;
        border-radius: var(--r-round);
        object-fit: cover;
    }

    .product.grid .labels {
        font-size: var(--fs-sm);
        font-weight: 400;
        line-height: 1.2;
    }

    .small.curators,
    .product.grid .curators {
      line-height: 20px;
      vertical-align: top;
      font-size: var(--fs-xs);
      margin-bottom: 10px;
      color: var(--text-muted);
    }
    /* Der Creatorname unter der Kachel steht in 12px Schrift auf einer 20px hohen
       Zeile -- und er fuehrt woandershin als die Kachel selbst (zum Creator statt
       zum Produkt), ist also ein eigener Weg und kein Zweitlink. Innenabstand
       vergroessert die Trefferflaeche auf 40px (20 Zeilenhoehe plus zweimal 10),
       der gleich grosse negative Aussenabstand nimmt sie aus dem Layout wieder
       heraus: die Zeile bleibt exakt 20px hoch, nichts verschiebt sich. Alle Werte
       auf der Creator-Seite bei 375px nachgemessen. Die 10px nach oben und unten
       landen in den Abstaenden, die ohnehin da sind (12px unter dem Bild, 10px
       unter dieser Zeile) -- es ueberlappt also keine andere Trefferflaeche. Auf
       44px zu gehen waere genau das gewesen: nach unten sind nur 10px frei. */
    .product.grid .curators a.hover-underline {
      display: inline-block;
      padding: 10px 0;
      margin: -10px 0;
    }
    .small.curators img,
    .product.grid .curators img {
      height: 20px;
      width: 20px;
      border-radius: var(--r-round);
      object-fit: cover;
      margin-right: 4px;
    }

    .product.container .brand,
    .product.grid .brand {
        margin-bottom: 4px;
        height: 17px;
        font-size: var(--fs-xs);
        xline-height: 20px;
        overflow: hidden;
        text-overflow: ellipsis;
        display: -webkit-box;
        -webkit-line-clamp: 1;
        -webkit-box-orient: vertical;
    }
    .product.grid .name {
        font-weight: 600;
        height: 40px;
        overflow: hidden;
        text-overflow: ellipsis;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        font-size: var(--fs-body);
    }
    a.hover-underline:hover,
    .product.grid .brand a:hover,
    .product.grid .name a:hover {
      text-decoration: underline;
    }
    .product.grid .price {
        color: var(--text-muted);
        margin-top: 4px;
    }
    /* Nicht kaufbare Produkte: das Bild zurueckgenommen, statt des Preises ein
       Hinweis. Die Kachel bleibt klickbar -- der Shop kann das Produkt
       zurueckbringen, und der Creator soll sehen, WELCHES Produkt es ist. */
    .product.grid .product-tile.nicht-kaufbar .image img {
        opacity: 0.45;
        filter: grayscale(0.6);
    }
    .product.grid .nicht-verfuegbar {
        margin-top: 4px;
        font-size: 0.86em;
        font-weight: 500;
        color: #8a6d1f;
    }

    /* Grundpreis auf der Kachel: eine Stufe leiser als der Preis, damit die
       Kachel ruhig bleibt. Eine Zeile, notfalls mit Auslassungspunkten -- die
       Kachelbreite darf davon nicht wachsen. */
    .product.grid .grundpreis {
        color: var(--text-muted);
        /* 0.86em ergibt bei 14px Grundschrift rund 12px. 0.78em waren 10,9px
           und damit unter der Grenze, ab der Text auf einem Handy muehsam
           wird -- im Browser nachgemessen. */
        font-size: 0.86em;
        margin-top: 2px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

  .product.grid { gap: 10px; }
  /* Der Abstand unter dem Raster stand als Inline-Stil im Template
     (padding-bottom: 64px) und liess sich damit von keiner Regel mehr korrigieren.
     Jetzt hier, damit die Regel darunter ihn zuruecknehmen kann. */
  .product.grid.container { padding: 20px 0 64px; }

  /* Der "Mehr"-Knopf unter einem Raster: 40px darueber, 40px darunter, ueberall
     gleich. Vorher standen ueber dem Knopf 104px und darunter 40 -- die 64px
     Bodenabstand des Rasters und die 40px des Knopfblocks kamen hintereinander,
     im Browser auf der Creator-Seite nachgemessen. Der Knopf sah dadurch aus, als
     gehoere er zur Fusszeile statt zum Raster.
     Ausserdem trugen die sieben Knopfbloecke drei verschiedene Inline-Abstaende
     (padding-top: 40px in den Rastern, padding: 40px bei den Produkten). Jetzt
     eine Klasse, ein Wert. */
  .raster-mehr { padding: 40px 0; }
  .product.grid.container:has(~ .raster-mehr) { padding-bottom: 0; }
  /* Ueber den Filterknoepfen standen 20px, darunter 30 -- 10 aus der Leiste selbst
     plus 20 aus dem Raster hier. Dasselbe Bauteil, zwei Abstaende; im Browser auf
     der Creator-Seite bei 375 und 1440px nachgemessen. Die Leiste bringt ihre 20px
     jetzt auf beiden Seiten selbst mit (Innenabstand im Template), das Raster
     steuert direkt darunter nichts mehr bei. Steht das Raster ohne Filterleiste --
     Markenseite, Startseite --, bleiben die 20px oben, wie gehabt.
     Nachbarwahl mit "~", nicht "+": product_grid bindet als erstes die Bildregel
     ein, und deren style- und script-Element stehen zwischen Leiste und Raster.
     Mit "+" greift die Regel nicht -- im Browser geprueft. */
  .filter-category ~ .product.grid.container,
  .filter-creators ~ .product.grid.container { padding-top: 0; }
  .product-tile {
    display: block;
    background: var(--surface);
    border-radius: var(--r-md);
    overflow: hidden;
    text-decoration: none;
    padding: 15px;
  }
  /* ── Die Bildregel ────────────────────────────────────────
     Die Kachel steht fest auf 4:5 und ist IMMER randlos gefuellt -- aber nie auf
     Kosten des Produkts. Welcher der beiden Wege gilt, entscheidet allein das
     Format des Bildes; die Herleitung mit allen Messwerten steht bei
     Content::kachelbild().

       Format nah an 4:5  ->  .fuellt, das Bild wird grossgezogen.
       Format weit weg    ->  das Bild bleibt ganz, der Hintergrund des Bildes
                              wird ueber die Kachel gezogen.

     Der Hintergrund ist dasselbe Bild, nur 60-fach vergroessert und auf die linke
     obere Ecke gesetzt. Sichtbar bleibt davon rund 1,7 % des Bildes -- bei einem
     freigestellten Produkt also reiner Hintergrund, als Flaeche ueber die ganze
     Kachel. Gleiche Adresse wie das Bild darueber, es entsteht also KEIN
     zusaetzlicher Abruf. Der leichte Weichzeichner glaettet die Verlaeufe, die
     viele Studioaufnahmen in der Ecke haben; ohne ihn bleiben graue Schlieren
     stehen (im Browser verglichen).

     Warum nicht mit fest eingebautem Weiss auffuellen: 84 % der Packshots stehen
     auf Weiss, aber 14 % auf hellem Grau oder Creme. Bei denen stand vorher ein
     sichtbares Rechteck in der Kachel -- genau der Fall, den Jakob am
     Kerastase-Bild gezeigt hat. */
  .product.grid .image {
    position: relative;
    aspect-ratio: 4 / 5;
    width: 100%;
    overflow: hidden;
    /* Innenliegendes Bild bewusst eine Stufe kleiner gerundet als die Karte selbst --
       gleiche Rundung wirkt bei verschachtelten Flaechen ausgebeult. */
    border-radius: var(--r-sm);
    margin-bottom: 12px;
    background: var(--kachelgrund, #ffffff);
  }
  /* Der Untergrund ist eine GEMESSENE, flache Farbe -- kein abgetasteter Pixel.

     Vorgeschichte, damit sie niemand ein viertes Mal durchlaeuft: hier stand erst
     eine fortgesetzte Bildkante, dann ein oberer linker Eckpixel, 200-fach
     vergroessert und mit blur(30px) verwischt. Beides hat den echten Hintergrund
     nur in 79 bzw. 83 % der Faelle getroffen, und die Fehltreffer waren die, die
     auffielen.

     Der Grund war nicht die Idee, sondern WO gemessen wurde: abgetastet wurde das
     BESCHNITTENE Bild (trim=border), und nach dem Zuschnitt ist die Ecke nicht mehr
     der Hintergrund, sondern der Schatten am Produktrand. An der Avene-Sonnencreme
     nachgemessen -- unbeschnitten #fefefe, beschnitten #e2e0e1 bis #f1eff0, also
     grau UND ungleichmaessig. Daher die grauen Balken statt einer Flaeche.

     Jetzt wird der ganze Randstreifen des unbeschnittenen Bildes ausgewertet und
     die Mehrheitsfarbe einmal gemessen (siehe app/www/src/kachelfarben.php). Ein
     einzelner Schattenpixel wird dabei ueberstimmt. Gibt es keine Mehrheit, ist es
     ein Foto ohne Hintergrund und die Kachel bleibt weiss.

     Damit entfallen die Abtast-Ebene, der 200-fach-Zoom, der Weichzeichner und die
     Klasse "weiss" samt Schwelle. Es bleibt eine Farbe. */
  .product.grid .image img {
    position: relative;
    z-index: 1;
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
    object-position: center;
  }
  /* Die Klasse setzt ein winziges Skript, sobald das Bild seine echten Masse kennt
     (siehe bildregel.html). Ohne JavaScript bleibt es beim vollstaendigen Bild mit
     Hintergrund -- das ist der sichere Weg, es wird nie etwas beschnitten. */
  .product.grid .image.fuellt img { object-fit: cover; }

  /* ── Gemessene Kacheln ────────────────────────────────────────────────────
     Die Regel in einem Satz: jedes Produkt nimmt in seiner Kachel denselben
     Anteil ein (88 % in der Richtung, die zuerst anstoesst) und sitzt mittig.

     Die Klasse "gemessen" steht nur an Kacheln, fuer die ein Produktrahmen
     gemessen wurde -- also nur dort, wo um das Produkt herum ein einheitlicher
     (oder durchsichtiger) Rand liegt. Nur dann ist Ziehen gefahrlos: beschnitten
     wird der Rand, nie das Produkt. Ohne Eintrag bleibt alles wie bisher.

     Warum das die Formatregel ersetzt und nicht ergaenzt: die alte Entscheidung
     kannte nur das Bildformat und war damit blind fuer die Sache selbst. Der
     Smeg-Wasserkocher fuellt sein Bild randlos aus, lag nah an 4:5, wurde
     formatfuellend gezogen -- und der Griff war ab. Die Tangle-Teezer-Buerste
     steht in ihrem Bild in einer grossen weissen Flaeche, liegt ebenfalls nah an
     4:5, und blieb winzig. Gemessen: Kocher 0,92 (wird kleiner), Buerste 1,22,
     Kylie-Flakon 1,55. Deshalb hier "object-fit: contain" auch dann, wenn die
     Bildregel "fuellt" gesetzt haben sollte -- die beiden duerfen sich nicht in
     die Quere kommen.

     Skaliert wird um die Kachelmitte, deshalb ist der Versatz schon mit dem Zoom
     verrechnet (siehe werkzeug/kachelzoom_bauen.py). Reihenfolge im transform:
     CSS wendet von rechts nach links an, also erst skalieren, dann verschieben. */
  .product.grid .image.gemessen img,
  .product.grid .image.gemessen.fuellt img {
    object-fit: contain;
    transform: translate(var(--zoom-x, 0), var(--zoom-y, 0)) scale(var(--zoom, 1));
  }
  /* Ohne Richtungsklasse haben beide Pseudoelemente keine Groesse und sind
     unsichtbar -- das ist auch der Zustand ohne JavaScript. */


  /* PDP */
  .product.container p {
    line-height: 1.3;
  }

  /* Product Images Container */
  .product-images-container {
    display: flex;
    flex-direction: column;
    gap: 5px;
    max-width: 620px;
  }
  
  .product-main-image {
    width: 100%;
    overflow: hidden;
    background: var(--surface);
  }

  .product-main-image img {
    width: 100%;
    height: auto;
    display: block;
    aspect-ratio: 0.9;
    object-fit: contain;
  }

  /* Thumbnails - Desktop (horizontal) */
  .product-thumbnails {
    width: 100%;
    overflow: hidden;
  }

  .thumbnails-slider {
    display: flex;
    gap: 5px;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-behavior: smooth;
    cursor: grab;
    user-select: none;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none; /* Firefox */
    -ms-overflow-style: none; /* IE/Edge */
  }

  .thumbnails-slider::-webkit-scrollbar {
    display: none; /* Chrome/Safari */
  }

  .thumbnail {
    flex-shrink: 0;
    width: 120px;
    height: 120px;
    overflow: hidden;
    cursor: pointer;
    transition: opacity var(--dauer);
    object-fit: cover;
    background: var(--surface);
  }

  .thumbnail:hover {
    opacity: 0.8;
  }

  .thumbnail.active {
    opacity: 1;
  }

  /* Mobile (vertical) */
  @media (max-width: 768px) {
    .product-images-container {
      flex-direction: row !important;
      gap: 5px !important;
      height: 500px !important;
      max-width: 100%;
    }

    .product-main-image {
      flex: 1 !important;
      min-width: 0 !important;
      height: 500px !important;
    }

    .product-main-image img {
      height: 100% !important;
      width: 100% !important;
      /*object-fit: cover !important;*/
    }

    .product-thumbnails {
      width: 90px !important;
      flex-shrink: 0 !important;
      height: 500px !important;
      overflow: hidden !important;
    }

    .thumbnails-slider {
      flex-direction: column !important;
      overflow-x: hidden !important;
      overflow-y: scroll !important;
      height: 500px !important;
    }

    .thumbnail {
      width: 96px !important;
      height: 96px !important;
    }
  }


    /* FOOTER */
    /* Der Schatten ist keine Deko, er schliesst ein Loch: auf dem Handy zieht iOS
       die Seite ueber ihr Ende hinaus und malt in dem freiwerdenden Streifen den
       Hintergrund der Seitenflaeche -- und der ist weiss, waehrend die Fusszeile
       schwarz ist. Im Dokument steht dort nichts (nachgemessen: Dokumenthoehe =
       Unterkante der Fusszeile), es ist also nichts zu entfernen.
       Versatz UND Ausbreitung je 50vh: der Schatten beginnt dadurch genau an der
       Oberkante der Fusszeile (also ohne Luecke darunter) und reicht 100vh nach
       unten. Ein reiner Versatz haette zwischen Fusszeile und Schatten eine Luecke
       gelassen, weil die Fusszeile keine 50vh hoch ist. Er kostet keinen Platz --
       ein Schatten liegt ausserhalb des Layouts -- und wird nur sichtbar, wenn
       genau dieser Bereich beim Ueberscrollen hochkommt. Im Browser gegengeprueft. */
    .site-footer { background: var(--accent); color: var(--on-accent-muted); padding: 8px 10px 20px; width: 100%; margin: 0; box-shadow: 0 50vh 0 50vh var(--accent); }
    /* ── Meldung unter einem Formular ────────────────────────────────────────
       Stand neunmal als identischer Inline-Stil in login, widerruf,
       change-password und reset-password -- jedes Mal dieselben sieben
       Deklarationen, jedes Mal von Hand. Darunter eine Schriftgroesse (13px), die
       es im Groessensatz gar nicht gibt: sie liegt zwischen --fs-xs (12) und
       --fs-sm (14). Genau so entstehen Seiten, auf denen dieselbe Meldung anders
       aussieht, je nachdem wo sie steht.

       Aufgeraeumt ist damit die MELDUNG, nicht die Groesse: 13px steht weiterhin
       an zehn Stellen im oeffentlichen Frontend (login, widerruf zweimal,
       register, creator_kpi_grid, admin-creators-order zweimal und dreimal hier
       in dieser Datei). Wer die Groessenstaffel wirklich schliessen will, faengt
       dort an -- aber jede dieser Stellen ist ein eigener Fall, keine
       Sammelaenderung.

       Das display:none bleibt bewusst am Element: die Skripte dieser Seiten
       schalten ueber element.style.display, und ein Inline-Wert gewinnt gegen
       diese Klasse. So aendert sich das Verhalten um kein Jota. */
    .hinweis {
      margin-top: 16px;
      font-size: var(--fs-sm);
      line-height: 1.45;
      border: 1px solid transparent;
      border-radius: var(--r-sm);
      padding: 10px 12px;
    }
    .hinweis.fehler { color: var(--danger);  background: var(--danger-bg);  border-color: var(--danger-border); }
    .hinweis.erfolg { color: var(--success); background: var(--success-bg); border-color: var(--success-border); }

    .site-footer a { color: var(--border); text-decoration: none; }
    .site-footer a:hover { color: var(--text-invert); }
    /* .footer-inner und .footer-links gehoeren jetzt nur noch der Affiliate-
       Startseite, die ihre eigene Fusszeile mitbringt. Die Fusszeile aller anderen
       Seiten steht darunter. */
    .footer-inner { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 20px 0; font-size: var(--fs-sm); }
    .footer-links { display: flex; flex-wrap: wrap; gap: 16px; }

    /* ── Fusszeile ────────────────────────────────────────────────────────────
       Vorher: eine Zeile Copyright links, sechs Links rechts hintereinander weg --
       zwei Wege in die Seite und vier Pflichtangaben, alle gleich aussehend, auf dem
       Handy in zwei ungleich lange Zeilen umgebrochen. Dazu 200px Mindesthoehe fuer
       62px Inhalt: 138px leere schwarze Flaeche, im Browser nachgemessen.
       Jetzt: Claim links, zwei benannte Gruppen rechts, darunter eine feine Linie
       und das Copyright. Die Hoehe kommt aus dem Inhalt, nicht aus min-height. */
    .footer-oben {
      display: flex;
      justify-content: space-between;
      gap: 40px 64px;
      flex-wrap: wrap;
      padding: 24px 0 32px;
    }
    .footer-claim {
      margin: 0;
      font-size: var(--fs-body);
      color: var(--text-invert);
      max-width: 22ch;
    }
    .footer-gruppen { display: flex; gap: 64px; }
    /* Der senkrechte Abstand kommt aus dem Innenabstand der Links, nicht aus
       einem gap: so ist die Trefferflaeche auf jeder Breite 44px hoch. Vorher
       galten die 11px nur unter 640px -- darueber waren die Links 22px hoch,
       auf jeder Seite der Website, im Browser bei 768px nachgemessen. */
    .footer-gruppe { display: flex; flex-direction: column; }
    .footer-gruppe a { padding: 11px 0; }
    .footer-gruppe-titel {
      margin: 0 0 2px;
      font-size: var(--fs-xs);
      font-weight: 600;
      letter-spacing: 0.08em;
      text-transform: uppercase;
      color: var(--on-accent-muted);
    }
    .footer-gruppe a { font-size: var(--fs-sm); }
    .footer-unten {
      border-top: 1px solid rgba(255,255,255,.14);
      padding: 20px 0 4px;
      font-size: var(--fs-xs);
      color: var(--on-accent-muted);
    }
    @media (max-width: 640px) {
      .footer-oben { flex-direction: column; gap: 28px; padding: 20px 0 28px; }
      .footer-claim { font-size: var(--fs-sm); max-width: none; }
      /* Zwei Spalten statt zweier ungleich langer Zeilen: die kuerzere Gruppe steht
         links, die laengere rechts, beide beginnen auf derselben Linie. */
      .footer-gruppen { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px 20px; }
      /* Trefferflaeche: 44px hoch, wie in der Kopfzeile. */
      .footer-gruppe-titel { margin-bottom: 6px; }
    }

    /* Fusszeile auf schmalen Geraeten.
       Die Regeln dafuer standen bis hierher in einem <style>-Block MITTEN IM <nav>
       der Fusszeile -- also auf jeder Seite mit ausgeliefert und weit weg von allem
       anderen, was die Fusszeile betrifft. Und sie waren kaputt:
         max-width: 100vw;  ... spaeter im selben Block ... max-width: 60vw;
       Zwei Deklarationen derselben Eigenschaft, die zweite gewinnt. Zusammen mit
       "width: 160px" und "min-width: max-content" an den Links ergab das im Browser
       bei 375px gemessen: die Leiste 225px breit, an den rechten Rand geschoben,
       jeder der sechs Links 225px breit, alle untereinander -- eine 271px hohe
       Spalte statt einer Fusszeile.
       Jetzt: Blockrichtung untereinander (Zeile darueber, Links darunter), Links
       umbrechen normal, volle Breite, Trefferflaeche bleibt 44px hoch. */
    @media (max-width: 640px) {
      .footer-inner {
        flex-direction: column;
        align-items: flex-start;
        gap: 4px;
        padding: 16px 0 8px;
      }
      .footer-links {
        gap: 4px 20px;
        font-size: 15px;
      }
      .footer-links a {
        /* Waagerecht kein Polster, damit die erste Spalte buendig unter der
           Copyright-Zeile steht; senkrecht genug fuer eine 44px-Trefferflaeche. */
        padding: 11px 0;
      }
    }



/* Special CSS for preview Phase */
.creators.blurred .tile {
    xfilter: blur(20px);
}

.creators.blurred .tile:hover::before { transform: none; }

.creators.blurred .tile .label {
    filter: blur(8px);
}

.creators.blurred .tile {
  position: relative;
}

.creators.blurred .tile::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(180, 180, 180, 0.5);
  backdrop-filter: blur(40px);
}





/*
.tile {
  transition: transform var(--dauer-lang) ease;
}
.tile:hover {
  transform: translateY(-3px);
}
*/
.tile::before {
  content: "";
  position: absolute;
  inset: 0;

  /* 👇 inherit the background from .tile */
  background-image: inherit;
  background-size: inherit;
  background-position: inherit;
  background-repeat: inherit;

  transform: scale(1);
  transition: transform var(--dauer-lang) ease;
  will-change: transform;
}

.tile:hover::before {
  transform: scale(1.05);
}






.section-teaser {
  max-width: 600px;
  text-align: center;
  margin-bottom: 3rem;
  margin-left: auto;
  margin-right: auto;
  line-height: 1.3rem;
}
/* Auf den vier Rasterseiten ist dieser Block LEER und damit nur noch ein
   Abstandshalter -- und als solcher war er ungleich: bei 390px gemessen standen
   zwischen Ueberschrift und Raster 24px auf /creators und /rooms, aber 48px auf
   /brands und /categories, obwohl dazwischen auf allen vieren nichts steht. Die
   48 kamen aus den 3rem hier oben, die 24 aus der engeren Regel in
   grid_creators/grid_rooms.
   Ein leerer Teaser bekommt deshalb einen eigenen, einheitlichen Wert. Auf der
   Startseite ist er gefuellt (204 bzw. 233 Zeichen) und behaelt seine 3rem --
   ":empty" trifft dort nachweislich nicht. */
.section-teaser:empty { margin-bottom: 24px; }

.creator-theresaadlee .label {
  color: var(--text);
}


/* Login */
  .login-page {
    min-height: calc(100vh - 200px);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 60px 16px;
  }

  .login-card {
    width: 100%;
    max-width: 420px;
    background: var(--surface);
    border-radius: var(--r-md);
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.06);
    padding: 32px 28px 28px;
    border: 1px solid var(--border);
  }

  .login-title {
    font-size: 24px;
    font-weight: 600;
    margin-bottom: 8px;
    color: var(--text);
  }

  .login-subtitle {
    font-size: var(--fs-sm);
    color: var(--text-muted);
    margin-bottom: 24px;
  }

  .login-form-group {
    margin-bottom: 16px;
  }

  .login-label {
    display: block;
    font-size: 13px;
    font-weight: 500;
    color: var(--text);
    margin-bottom: 6px;
  }

  .login-input {
    width: 100%;
    border-radius: var(--r-sm);
    border: 1px solid var(--border-feld);
    padding: 10px 12px;
    font-size: var(--fs-sm);
    font-family: inherit;
    color: var(--text);
    outline: none;
    transition: border-color var(--dauer-schnell) ease, box-shadow var(--dauer-schnell) ease, background-color var(--dauer-schnell) ease;
    background-color: var(--surface-sunk);
  }

  .login-input:focus {
    border-color: var(--accent);
    background-color: var(--surface);
    box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.04);
  }

  .login-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 8px;
    gap: 8px;
  }

  .login-remember {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: var(--fs-xs);
    color: var(--text-muted);
    cursor: pointer;
  }

  .login-remember input[type="checkbox"] {
    width: 14px;
    height: 14px;
    cursor: pointer;
  }

  .login-forgot {
    /* War 15px hoch. Ein Schalter, der ein Formular auf- und zuklappt, ist keine
       Beilaeufigkeit im Fliesstext -- er braucht dieselbe Trefferflaeche wie ein
       Knopf. */
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    font-size: var(--fs-xs);
    color: var(--text-muted);
    text-decoration: none;
  }

  .login-forgot:hover {
    color: var(--accent);
    text-decoration: underline;
  }

  .login-submit {
    margin-top: 20px;
    width: 100%;
    border: none;
    border-radius: var(--r-pill);
    padding: 12px 18px;
    font-size: var(--fs-sm);
    font-weight: 500;
    background-color: var(--accent);
    color: var(--on-accent);
    cursor: pointer;
    transition: background-color var(--dauer-schnell) ease, transform 50ms ease;
  }

  .login-submit:hover {
    background-color: var(--accent-hover);
  }

  .login-submit:active {
    transform: translateY(1px);
  }

  .login-footer-text {
    margin-top: 20px;
    font-size: var(--fs-xs);
    color: var(--text-muted);
    text-align: center;
  }

  .login-footer-text a {
    color: var(--accent);
    text-decoration: none;
    font-weight: 500;
  }

  .login-footer-text a:hover {
    text-decoration: underline;
  }

  @media (max-width: 640px) {
    .login-card {
      padding: 24px 18px 20px;
    }

    .login-title {
      font-size: var(--fs-h3);
    }
    header .container {
      gap: 10px;
    }
    header .menu a {
      margin-right: 0px;
      font-size: 13px;
    }
  }

      .form-actions {
      display: flex;
      gap: 12px;
      margin-top: 40px;
      padding-top: 30px;
      border-top: 1px solid var(--border);
    }

    /* Dieselbe Pillenform wie alle anderen Knoepfe der Seite. Vorher 8px eckig --
       das war der einzige Ort, an dem eine Hauptaktion nicht rund war. */
    .btn {
      padding: 13px 28px;
      font-size: var(--fs-sm);
      font-weight: 500;
      border: 1px solid transparent;
      border-radius: var(--r-pill);
      cursor: pointer;
      transition: background-color var(--dauer) ease, color var(--dauer) ease, border-color var(--dauer) ease;
      font-family: inherit;
    }

    .btn-primary {
      background: var(--accent);
      color: var(--on-accent);
      border-color: var(--accent);
      flex: 1;
    }

    .btn-primary:hover:not(:disabled) {
      background: var(--accent-hover);
      border-color: var(--accent-hover);
    }

    .btn-secondary {
      background: transparent;
      color: var(--text);
      border-color: var(--border-strong);
    }

    .btn-secondary:hover:not(:disabled) {
      background: var(--surface-sunk);
      border-color: var(--accent);
    }

    .btn:disabled {
      opacity: 0.5;
      cursor: not-allowed;
    }

    .form-error {
      color: var(--danger);
      font-size: 13px;
      margin-top: 6px;
      display: none;
    }

    .form-group.has-error .form-error {
      display: block;
    }

    .form-group.has-error .form-input,
    .form-group.has-error .form-textarea,
    .form-group.has-error .form-select {
      border-color: var(--danger);
    }

    .form-group.has-error .file-upload-button {
      border-color: var(--danger);
    }

    .validation-message {
      background: var(--warn-bg);
      border: 1px solid var(--warn);
      color: var(--warn);
      border-radius: var(--r-sm);
      padding: 16px;
      margin-bottom: 24px;
      display: none;
    }

    .validation-message.show {
      display: block;
      animation: slideDown 0.3s ease;
    }

    .small-container {
      max-width: 1480px;
      padding: 0 20px;
      margin: auto;
    }

    .clickable {
      cursor: pointer;
    }
