/* Oben weniger Luft als unten: Das Formular soll auf dem Handy ohne Scrollen zu sehen sein. */
  .rbxff { --section-padding-top: 36px; --section-padding-bottom: 96px; }

  /* Der Hintergrund: drei weiche Farbwolken in den Haustoenen, die langsam gegeneinander
     wandern. Kein Selbstzweck — die Seite bittet um ein Foto aus der eigenen Wohnung, und
     das tut man eher auf einer Seite, die nach Sorgfalt aussieht als auf einer weissen.

     Gebaut als ::before hinter dem Inhalt, nicht als Hintergrund des Abschnitts: So kann
     die Flaeche ueber die Raender hinauslaufen und an den Kanten weich auslaufen, ohne dass
     der Inhalt mitwandert. isolation begrenzt den Stapelkontext auf diesen Abschnitt — der
     Rest der Seite bleibt unberuehrt.

     ZWEI KORREKTUREN NACH DEM ERSTEN BLICK DES KUNDEN:

     Erstens stand die Flaeche still — bewegen soll sie sich nicht. Die urspruengliche
     Ueberlegung war, dass 28 Sekunden je Zyklus unterhalb der Wahrnehmung liegen. Sie tun
     es nicht („die bewegt sich, das sieht komisch aus\"). Ein Hintergrund, den man beim
     Lesen bemerkt, ist ein schlechter Hintergrund, egal wie langsam er ist.

     Zweitens endete der Verlauf rechts an einer harten Linie. Ursache ist nicht diese
     Flaeche, sondern die Seite darunter: Etwas im Theme macht das Dokument breiter als das
     Fenster. Der Abschnitt bleibt dann fensterbreit, der scrollbare Bereich daneben bleibt
     weiss — und genau die Kante dazwischen sieht man. Deshalb steht unten am Dokument ein
     overflow-x: clip. Es beseitigt den Ueberlauf da, wo er entsteht; die Flaeche selbst
     braucht dann keine Tricks mehr. */
  /* DRITTE FASSUNG — und diesmal ohne Kunststuecke.
     Auf dem iPhone war die Seite LEER. Nicht falsch gesetzt, nicht verschoben: leer.

     Der Hintergrund stapelte vier Dinge uebereinander, die einzeln unauffaellig sind und
     zusammen iOS' Compositing ueberfordern: isolation: isolate erzeugt einen eigenen
     Stapelkontext, darin ein ::before mit z-index: -1, darauf filter: blur(28px), und
     obendrauf zwei Masken, die per mask-composite verrechnet werden. Safari verwirft in
     dieser Kombination den ganzen Stapelkontext — mitsamt dem Inhalt, der nichts dafuer
     kann.

     Ein Hintergrund ist Zierrat. Er darf die Seite nicht kosten. Also:
     - kein isolation, kein negativer z-index. Der Verlauf ist jetzt der Hintergrund des
       Abschnitts selbst, der Inhalt liegt ohnehin darueber.
     - kein blur. Die radialen Verlaeufe sind von sich aus weich; die Unschaerfe war Luxus,
       und teuer noch dazu.
     - keine mask-composite-Verrechnung. Ein einzelner vertikaler Verlauf im Hintergrund
       leistet dasselbe, ohne dass zwei Masken miteinander verrechnet werden muessen.
     - overflow-x nur noch am Abschnitt, nicht mehr am Dokument. Am html-Element ist das ein
       Eingriff in die ganze Seite, den eine Landingpage nicht rechtfertigt.

     Was bleibt, ist derselbe ruhige Glasverlauf — nur baut ihn jetzt jeder Browser. */
  .rbxff {
    position: relative; overflow-x: clip; max-width: 100%;
    background:
      linear-gradient(to bottom, #fff 0%, transparent 14%, transparent 88%, #fff 100%),
      radial-gradient(46% 42% at 16% 20%, rgb(var(--rbxff-warm, 247 184 148) / .26) 0%, transparent 70%),
      radial-gradient(54% 48% at 84% 28%, rgb(var(--rbxff-kuehl, 127 179 164) / .24) 0%, transparent 72%),
      radial-gradient(62% 56% at 52% 92%, rgb(var(--rbxff-tief, 60 100 120) / .13) 0%, transparent 74%);
  }
/* Flaechen, Raender und Radien kommen aus dem Theme, nicht aus eigenen Werten: sonst
     wandert die Seite beim naechsten Farbwechsel im Theme aus dem Bild. Der Weg dorthin
     ist rgb(var(--color-foreground) / …) — dasselbe Muster wie im Wunschfarben-Mischer.
     „--color-background-secondary" und „--rounded-input" standen hier vorher und existieren
     im Theme nicht. */
  .rbxff__kopf { margin-bottom: 18px; }
  .rbxff__lead { margin: 10px 0 0; font-size: 16px; line-height: 1.55; max-width: 56ch; opacity: .85; }
  /* Unter dem Formular: erst die Bildstrecke, ganz unten der Seitentext aus dem Shop. */
  .rbxff__ablauf { margin-top: 52px; }
  .rbxff__text { max-width: 68ch; }
  .rbxff__text h2 {
    font-size: clamp(19px, 2vw, 24px); line-height: 1.3; text-transform: none;
    letter-spacing: -.005em; margin: 30px 0 10px;
  }
  .rbxff__text h2:first-child { margin-top: 0; }
  .rbxff__text p, .rbxff__text li { line-height: 1.65; }
  .rbxff__text ul { padding-inline-start: 0; list-style: none; }
  .rbxff__text li { margin: 0 0 8px; }
  .rbxff__schritte { list-style: none; margin: 0; padding: 0; display: grid; gap: 20px; }
  /* Die Buehne haelt Raster, Funken und Farbkarten ueber dem Foto — deshalb relativ
     positioniert und beschnitten, sonst laegen die Auflagen ueber der Bildecke. */
  .rbxff__schrittbild {
    position: relative; display: block; overflow: hidden;
    border-radius: var(--rounded-block, 14px); margin-bottom: 10px;
    border: 1px solid rgb(var(--color-foreground) / .08);
  }
  .rbxff__schritt img { width: 100%; height: auto; display: block; }
  /* Raster und Funken liegen sonst still und blenden erst waehrend der Analyse auf. Hier
     sind sie Teil der Erklaerung und muessen dauerhaft zu sehen sein. */
  .rbxff__schrittbild .rbxff__raster--fest,
  .rbxff__schrittbild .rbxff__funken--fest { opacity: 1; }
  /* Vier Farbkarten, leicht gedreht an die Wand gehalten — nicht als Raster ausgelegt,
     sondern so, wie man Karten wirklich haelt. */
  /* Die Flaeche MUSS beide Raender setzen. Mit nur einem Rand ergibt sich die Breite aus
     dem Inhalt — und der Inhalt sind Karten mit „width: 21%", also 21 % von einer Breite,
     die es noch gar nicht gibt. Das Ergebnis war null: Kachel 3 sah aus wie Kachel 1, die
     Karten waren da und unsichtbar (Nutzer: „im letzten bild fehlen die farbtoene").
     Mit inset-inline-end steht die Breite fest, bevor die Karten sie brauchen. */
  /* Die Karten schwebten quer ueber dem halben Bild und schnitten das Fenster an — vier
     Rechtecke in der Luft statt vier Karten an einer Wand (Nutzer: „die farbmuster sitzen
     irgendwie komisch im bild"). Jetzt sitzen sie kleiner und tiefer auf der freien
     Wandflaeche rechts, ueberlappen einander leicht wie ein aufgefaechertes Kartenset und
     lassen Fenster, Bild und Sofa in Ruhe. */
  .rbxff__karten {
    position: absolute; inset-block-start: 24%;
    inset-inline-start: 46%; inset-inline-end: 9%;
    display: flex; align-items: flex-start; gap: 0; pointer-events: none;
  }
  .rbxff__karten i {
    flex: 1 1 0; aspect-ratio: 3 / 4; border-radius: 2px;
    box-shadow: 0 5px 14px rgb(0 0 0 / .22);
    outline: 1px solid rgb(255 255 255 / .45); outline-offset: -1px;
  }
  .rbxff__karten i + i { margin-inline-start: -6%; }
  .rbxff__karten i:nth-child(1) { transform: rotate(-3deg); }
  .rbxff__karten i:nth-child(2) { transform: rotate(1.5deg) translateY(4%); }
  .rbxff__karten i:nth-child(3) { transform: rotate(-1deg) translateY(-3%); }
  .rbxff__karten i:nth-child(4) { transform: rotate(2.5deg) translateY(2%); }
  .rbxff__schritt b { display: block; font-size: 15px; margin-bottom: 2px; }
  .rbxff__schritt p { font-size: 14px; line-height: 1.55; opacity: .8; margin: 0; }
  @media screen and (min-width: 760px) {
    .rbxff__schritte { grid-template-columns: repeat(3, 1fr); gap: 24px; }
  }

  /* Glas statt Flaeche: Der Verlauf soll durch die Karte hindurchscheinen, sonst waere er
     hinter ihr einfach weg. Wo backdrop-filter fehlt (aeltere Browser), traegt der
     Weissanteil die Karte allein — lesbar bleibt sie in beiden Faellen. */
  .rbxff__karte {
    padding: 26px 28px; border-radius: var(--rounded-block, 16px);
    background: rgb(255 255 255 / .58);
    border: 1px solid rgb(255 255 255 / .70);
    box-shadow: 0 10px 40px rgb(var(--color-foreground) / .07);
    -webkit-backdrop-filter: blur(14px) saturate(1.15);
    backdrop-filter: blur(14px) saturate(1.15);
  }
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .rbxff__karte { background: rgb(255 255 255 / .86); }
  }
  .rbxff__karte--eng { margin-top: 28px; }
  /* 13px war die Groesse einer Formularbeschriftung. „Foto deines Raums" ist aber keine
     Beschriftung neben zehn anderen, sondern die einzige Aufforderung der ganzen Karte —
     sie darf die Ueberschrift sein, die sie ist. */
  .rbxff__feldtitel { margin: 0 0 12px; font-size: 18px; font-weight: 700; line-height: 1.25; }
  @media screen and (min-width: 700px) { .rbxff__feldtitel { font-size: 20px; } }

  /* Der Dateiwaehler liegt IM Knopf und ist unsichtbar — sonst steht der Systemstil des
     Browsers („Datei auswaehlen | Keine ausgewaehlt") mitten in der Seite. */
  .rbxff__upload {
    margin-bottom: 18px;
    padding: 16px; border-radius: var(--rounded-block, 14px);
    border: 1.5px dashed rgb(var(--color-foreground) / .18);
    transition: border-color .15s ease, background-color .15s ease, padding .2s ease;
  }
  .rbxff__upload[data-ueber="true"] {
    border-color: rgb(var(--color-foreground) / .45);
    background: rgb(255 255 255 / .45);
  }
  /* Liegt ein Foto drin, ist die Flaeche das Foto — der gestrichelte Rahmen hat dann nichts
     mehr anzukuendigen. */
  .rbxff__upload[data-hatfoto="true"] { padding: 8px; border-style: solid; border-color: rgb(255 255 255 / .70); }
  .rbxff__leer { display: flex; flex-wrap: wrap; gap: 12px 16px; align-items: center; }
  .rbxff__ziehen { display: block; font-weight: 600; margin-top: 3px; }
  /* Auf Geräten ohne Zeiger gibt es kein Ziehen — dort waere der Hinweis nur eine
     Anweisung, die niemand befolgen kann. */
  @media (hover: none), (pointer: coarse) { .rbxff__ziehen { display: none; } }
  /* Der Theme-Knopf ist eine Pille. In einem Kasten mit weichem, aber eckigem Radius sieht
     das aus, als waeren zwei Entwuerfe uebereinandergelegt (Nutzer: „so sieht das
     unharmonisch aus\"). Also nimmt der Knopf hier den Radius des Kastens an — auch die
     Fuellung innen, sonst schaut sie an den Ecken darunter hervor. */
  /* Der zweite Knopf des Themes traegt Rahmen und Schrift im hellen Hausmintton. Auf der
     fast weissen Karte bleibt davon zu wenig uebrig, um als Knopf gelesen zu werden
     (Nutzer: „button hat zuwenig kontrast\"). Rahmen und Schrift nehmen deshalb hier die
     Textfarbe der Seite — die Form bleibt die des Themes, nur sichtbar wird sie. */
  .rbxff .button--secondary {
    color: rgb(var(--color-foreground));
    border-color: rgb(var(--color-foreground) / .45);
  }
  .rbxff .button--secondary:hover { border-color: rgb(var(--color-foreground) / .85); }
  .rbxff .button--secondary .btn-text { color: inherit; }

  .rbxff__uploadknopf,
  .rbxff__uploadknopf .btn-fill { border-radius: var(--rounded-block, 14px); }
  .rbxff__uploadknopf { cursor: pointer; }
  .rbxff__uploadknopf input[type="file"] {
    position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none;
  }
  .rbxff__uploadhinweis { font-size: 13px; line-height: 1.45; opacity: .7; flex: 1 1 14rem; min-width: 0; }

  .rbxff__field { margin-bottom: 16px; }

  /* Die Vorschau bleibt klein — sie soll bestaetigen, nicht die Seite fuellen. */
  .rbxff__buehne {
    position: relative; margin: 0; width: 100%; max-width: 420px;
    aspect-ratio: 4 / 3; overflow: hidden;
    border-radius: calc(var(--rounded-block, 14px) - 4px);
  }
  .rbxff__vorschau { width: 100%; height: 100%; object-fit: cover; display: block; }

  /* Raster und Punkte liegen still ueber dem Bild und erwachen erst mit der Analyse.
     Beides ist reines CSS: eine Animation, die auf einen Wert wartet, kostet nichts,
     solange sie nicht laeuft.

     RUHIG, NICHT HEKTISCH (Nutzer, 25.09.2026: „der ist zu hektisch, sanft und entspannt,
     ansonsten ist das unruhig"). Bis dahin blitzte alle 0,28 s ein Punkt auf (Zyklus 2,6 s,
     hoch in 0,3 s, dazu ein Ueberschwinger auf 115 %) — das Auge kam nicht zur Ruhe. Jetzt:
     - Raster und Punkte blenden ueber 1,2 s ein und aus, statt aufzuspringen.
     - Jeder Punkt atmet langsam: 2,2 s hell werden, 2,2 s verloeschen, dann Pause
       (Zyklus 7,2 s), ohne Ueberschwinger.
     - Die Punkte folgen einander im Abstand von 0,8 s — eine sanfte Welle ueber das Bild.
       Die Verzoegerungen sind negativ: Die Welle laeuft schon, wenn das Raster erscheint,
       statt erst Sekunden spaeter mit dem ersten Punkt anzufangen.
     Dieselben Werte stehen im Chat-Widget (anna/src/App.css, .rbx-scan) und in der
     Praesentation, aus der die Videoanzeigen aufgenommen werden (praesentation.css, .scan) —
     src/analyseanimation.test.mjs haelt sie gleich. */
  .rbxff__raster, .rbxff__funken { position: absolute; inset: 0; opacity: 0; pointer-events: none; transition: opacity 1.2s ease; }
  .rbxff__raster {
    background-image:
      repeating-linear-gradient(to right, rgb(255 255 255 / .55) 0 1px, transparent 1px 25%),
      repeating-linear-gradient(to bottom, rgb(255 255 255 / .55) 0 1px, transparent 1px 25%);
    mix-blend-mode: overlay;
  }
  /* Neun Punkte, die nacheinander sanft aufleuchten und wieder verloeschen — als tastete ein
     Blick ueber das Bild. Der weisse Balken davor sah aus wie ein Kopierer.

     Die Positionen sind bewusst ungleichmaessig: Ein sauberes 3x3-Gitter wirkt wie ein
     Messgeraet, ein leicht versetztes wie jemand, der schaut. */
  .rbxff__funken i {
    position: absolute; width: 7px; height: 7px; margin: -3.5px 0 0 -3.5px;
    border-radius: 50%; background: #fff;
    box-shadow: 0 0 0 2px rgb(255 255 255 / .3), 0 0 12px 3px rgb(255 255 255 / .55);
    opacity: 0; transform: scale(.7);
  }
  .rbxff__funken i:nth-child(1) { left: 18%; top: 24%; animation-delay: -7.2s; }
  .rbxff__funken i:nth-child(2) { left: 52%; top: 16%; animation-delay: -6.4s; }
  .rbxff__funken i:nth-child(3) { left: 81%; top: 31%; animation-delay: -5.6s; }
  .rbxff__funken i:nth-child(4) { left: 27%; top: 55%; animation-delay: -4.8s; }
  .rbxff__funken i:nth-child(5) { left: 63%; top: 48%; animation-delay: -4s; }
  .rbxff__funken i:nth-child(6) { left: 88%; top: 66%; animation-delay: -3.2s; }
  .rbxff__funken i:nth-child(7) { left: 14%; top: 79%; animation-delay: -2.4s; }
  .rbxff__funken i:nth-child(8) { left: 45%; top: 84%; animation-delay: -1.6s; }
  .rbxff__funken i:nth-child(9) { left: 72%; top: 72%; animation-delay: -.8s; }

  .rbxff__buehne[data-analyse="true"] .rbxff__raster { opacity: .85; }
  .rbxff__buehne[data-analyse="true"] .rbxff__funken { opacity: 1; }
  /* In Kachel 2 der Bildstrecke laufen die Punkte immer — dort sind sie die Erklaerung. */
  /* Einzelangaben statt der Kurzform „animation": Die Kurzform setzte die Verzoegerung der
     Punkte (oben, je Position) auf 0 zurueck — alle neun leuchteten dann gleichzeitig. */
  .rbxff__buehne[data-analyse="true"] .rbxff__funken i,
  .rbxff__funken--fest i {
    animation-name: rbxffFunke; animation-duration: 7.2s;
    animation-timing-function: ease-in-out; animation-iteration-count: infinite;
  }
  @keyframes rbxffFunke {
    0%, 100% { opacity: 0; transform: scale(.7); }
    30%      { opacity: .95; transform: scale(1); }
    60%      { opacity: 0; transform: scale(.7); }
  }
  /* Wer Bewegung abbestellt hat, bekommt Raster und Punkte ruhig — dass etwas laeuft, sagt
     dann der Text darunter. */
  @media (prefers-reduced-motion: reduce) {
    .rbxff__raster, .rbxff__funken { transition: none; }
    .rbxff__buehne[data-analyse="true"] .rbxff__funken i,
    .rbxff__funken--fest i { animation: none; opacity: .6; transform: none; }
  }

  /* Das X zum Austauschen. Es sitzt IM Bild, oben rechts — dort, wo man es sucht. */
  .rbxff__weg {
    position: absolute; inset-block-start: 8px; inset-inline-end: 8px;
    width: 30px; height: 30px; display: grid; place-items: center;
    border: 0; border-radius: 50%; cursor: pointer; padding: 0;
    color: #313131; background: rgb(255 255 255 / .88);
    box-shadow: 0 2px 10px rgb(0 0 0 / .18);
    transition: background-color .15s ease, transform .15s ease;
  }
  .rbxff__weg:hover { background: #fff; transform: scale(1.06); }
  /* Waehrend gerechnet wird, waere ein Austauschen nur verwirrend — das Ergebnis kaeme
     trotzdem zum alten Foto. */
  .rbxff__buehne[data-analyse="true"] .rbxff__weg { display: none; }
  .rbxff__haken { display: grid; grid-template-columns: auto 1fr; gap: 11px; align-items: start;
    font-size: 13px; line-height: 1.5; opacity: .8; margin-bottom: 20px; cursor: pointer; }
  /* Selbst gezeichnet statt dem Browser ueberlassen: Das Theme rundet Ankreuzfelder zu
     Kapseln, hier sollen sie quadratisch sein („und das ich bin einverstanden kaestchen
     bitte quadratisch\"). Mit appearance: none ist die Form sicher unsere, in jedem
     Browser — der Haken ist ein gedrehtes L aus zwei Raendern, kein Zeichen aus einer
     Schrift, die es vielleicht nicht gibt. */
  /* ZWEITER ANLAUF. Der erste setzte width und height auf 17px und wurde trotzdem
     laenglich: Das Theme gibt Ankreuzfeldern eigene Masse und einen Innenabstand, und in
     einem Flex-Kasten darf ein Feld ausserdem wachsen. Gegen all das reichen zwei
     Eigenschaften nicht.

     Jetzt wird jede Stellschraube festgezogen — Mindest- und Hoechstbreite, box-sizing,
     padding auf null, flex-basis fest — und die Regel steht unter .rbxff, damit sie in der
     Spezifitaet ueber der des Themes liegt. Ein Quadrat, das keines mehr werden kann,
     gibt es danach nicht. */
  .rbxff .rbxff__haken input[type="checkbox"] {
    appearance: none; -webkit-appearance: none;
    box-sizing: border-box; padding: 0; margin: 2px 0 0;
    width: 18px; min-width: 18px; max-width: 18px;
    height: 18px; min-height: 18px; max-height: 18px;
    aspect-ratio: 1 / 1; flex: 0 0 18px;
    display: block; cursor: pointer; box-shadow: none; outline: none;
    border: 1.5px solid rgb(var(--color-foreground) / .32);
    border-radius: 5px;
    background: rgb(255 255 255 / .72);
    transition: background-color .15s ease, border-color .15s ease;
  }
  /* Das Theme zeichnet Ankreuzfeldern eigene Pseudoelemente — daher der zweite Rahmen um
     unseren Kasten und ein zweiter Haken darin (Nutzer: „ein haekchen, nicht zwei").
     appearance: none nimmt nur die Darstellung des Browsers weg, nicht die des Themes.
     Also beide Pseudoelemente ausdruecklich abraeumen. Unser Haken ist ein
     Hintergrundbild und bleibt davon unberuehrt. */
  .rbxff .rbxff__haken input[type="checkbox"]::before,
  .rbxff .rbxff__haken input[type="checkbox"]::after { content: none; display: none; }
  .rbxff .rbxff__haken input[type="checkbox"]:hover { border-color: rgb(var(--color-foreground) / .55); }
  .rbxff .rbxff__haken input[type="checkbox"]:checked {
    background-color: rgb(var(--color-foreground) / .90);
    border-color: rgb(var(--color-foreground) / .90);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 8.5l3 3 6-6.5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 13px 13px;
  }
  /* Der Haken war ein gedrehtes L aus zwei Raendern. Das ist der uebliche Trick und sieht
     bei 18px auch entsprechend aus: zu dick, leicht schief, nie ganz mittig — die Drehung
     verschiebt den optischen Schwerpunkt, und man korrigiert ihn mit Pixelwerten nach
     Gefuehl. Ein Haken als SVG hat diese Probleme nicht: Er ist gezeichnet, nicht
     zusammengebogen, skaliert sauber und sitzt, wo er sitzen soll. */
  .rbxff .rbxff__haken input[type="checkbox"]:focus-visible {
    outline: 2px solid rgb(var(--color-foreground) / .55); outline-offset: 2px;
  }
  .rbxff__knopf { width: 100%; }
  .rbxff__klein { font-size: 12px; line-height: 1.5; opacity: .65; margin-top: 12px; }
  .rbxff__status { font-size: 14px; margin-top: 12px; min-height: 1.4em; }
  .rbxff__status[data-art="fehler"] { color: #b3261e; }

  .rbxff__befund { margin-top: 34px; }
  /* Der Satz ueber den Empfehlungen fasst die ganze Analyse zusammen — er hat die Groesse
     verdient (Nutzer: „das über die Farbempfehlungen, Text größer, das ist kaum lesbar"). */
  .rbxff__fazit { font-size: 20px; line-height: 1.5; font-weight: 500; margin-bottom: 26px; }
  @media screen and (min-width: 760px) { .rbxff__fazit { font-size: 22px; } }

  /* Foto und Lesart nebeneinander: Was wir sehen, steht neben dem, worin wir es sehen. */
  /* hidden ist ein Attribut, display: flex ist eine CSS-Regel — und die gewinnt. Der
     Knopf „Foto auswaehlen" blieb deshalb stehen, obwohl das Foto laengst da war
     (Nutzer: „der button Foto auswaehlen kann verschwinden"). Eine Zeile, die das
     Attribut wieder gelten laesst. */
  .rbxff__leer[hidden] { display: none; }

  .rbxff__lesart { min-width: 0; }

  /* ---------- Was gerade passiert ---------- */
  /* Ein Knopf mit drei pulsierenden Punkten sagt „es tut sich was" und sonst nichts. Bei
     vierzig Sekunden ist das zu wenig: Man weiss nicht, ob es haengt, wie lange es noch
     dauert, und ob das eigene Foto ueberhaupt angekommen ist. Balken, Prozentzahl und ein
     Satz, der den aktuellen Schritt benennt, beantworten alle drei Fragen — und die
     Schritte sind nicht erfunden, sie stehen so im Auftrag an das Bildmodell. */
  .rbxff__lauf { min-width: 0; }
  .rbxff__balken {
    height: 7px; border-radius: 99px; overflow: hidden;
    background: rgb(var(--color-foreground) / .10); margin: 2px 0 10px;
  }
  .rbxff__balken > i {
    display: block; height: 100%; width: 0%; border-radius: 99px;
    background: rgb(var(--color-foreground) / .55);
    transition: width .6s cubic-bezier(.4, 0, .2, 1);
  }
  .rbxff__proz { margin: 0 0 6px; font-size: 26px; line-height: 1; font-weight: 700; }
  .rbxff__schritt { margin: 0 0 10px; font-size: 14px; line-height: 1.5; min-height: 2.6em; }
  .rbxff__dauer { margin: 0; opacity: .6; }
  /* Waehrend die Analyse laeuft, ist der Balken die Auskunft — der Knopf mit den Punkten
     waere eine zweite, die dasselbe schlechter sagt. */
  form[data-ff-form][data-laeuft="true"] .rbxff__knopf,
  form[data-ff-form][data-laeuft="true"] .rbxff__haken { display: none; }
  @media (prefers-reduced-motion: reduce) { .rbxff__balken > i { transition: none; } }
  .rbxff__raum { font-size: 16px; line-height: 1.5; font-weight: 600; margin: 0 0 6px; }
  .rbxff__licht { font-size: 15px; line-height: 1.55; margin: 0; opacity: .75; }
  @media screen and (min-width: 700px) {
    .rbxff__upload[data-hatfoto="true"] {
      display: grid; grid-template-columns: minmax(0, 400px) minmax(0, 1fr);
      gap: 22px; align-items: center;
    }
  }
  /* Nach dem Ergebnis verschwindet das Formular — samt Ladeknopf. Foto und Lesart bleiben
     stehen, denn beides gehoert zur Antwort. */
  form[data-ff-form][data-fertig="true"] .rbxff__haken,
  form[data-ff-form][data-fertig="true"] .rbxff__knopf,
  form[data-ff-form][data-fertig="true"] .rbxff__status,
  form[data-ff-form][data-fertig="true"] .rbxff__feldtitel { display: none; }
  .rbxff__toene { display: grid; gap: 12px; }
  .rbxff__ton {
    display: grid; grid-template-columns: 78px 1fr; gap: 16px; align-items: center;
    text-decoration: none; color: inherit; padding: 10px; border-radius: var(--rounded-block, 14px);
    border: 1px solid rgb(255 255 255 / .70);
    background: rgb(255 255 255 / .52);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
  }
  .rbxff__ton:hover { border-color: rgb(var(--color-foreground) / .32); }
  .rbxff__klecks { width: 78px; height: 78px; border-radius: 12px; border: 1px solid rgb(var(--color-foreground) / .10); }
  /* Das Produktfoto sitzt an derselben Stelle wie vorher die Farbflaeche und in derselben
     Groesse — so bleibt die Zeile ruhig, egal ob ein Foto vorliegt oder nicht. */
  .rbxff__klecks--foto { object-fit: cover; display: block; background: rgb(255 255 255 / .6); }
  @media screen and (min-width: 700px) {
    .rbxff__ton { grid-template-columns: 96px 1fr; }
    .rbxff__ton .rbxff__klecks { width: 96px; height: 96px; }
  }

  /* Die Ideen tragen jetzt ebenfalls Fotos statt blosser Namen. */
  .rbxff__ideeton {
    display: flex; align-items: center; gap: 10px; text-decoration: none; color: inherit;
    font-size: 13px; font-weight: 600; padding: 6px 12px 6px 6px; border-radius: 99px;
    border: 1px solid rgb(var(--color-foreground) / .12); background: rgb(255 255 255 / .55);
  }
  .rbxff__ideeton:hover { border-color: rgb(var(--color-foreground) / .32); background: #fff; }
  .rbxff__ideeton .rbxff__klecks { width: 40px; height: 40px; border-radius: 50%; flex: none; }
  .rbxff__ton b { display: block; font-size: 16px; }
  .rbxff__ton small { display: block; font-size: 14px; line-height: 1.45; opacity: .8; margin-top: 3px; }
  .rbxff__ideen { display: grid; gap: 12px; margin-top: 22px; }
  .rbxff__idee {
    padding: 15px 17px; border-radius: var(--rounded-block, 14px);
    border: 1px solid rgb(255 255 255 / .70); background: rgb(255 255 255 / .52);
    -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  }
  .rbxff__idee b { font-size: 15px; }
  .rbxff__idee p { font-size: 14px; opacity: .8; margin-top: 3px; }
  .rbxff__streifen { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 10px; }
  .rbxff__streifen a { text-decoration: none; color: inherit; font-size: 12px; font-weight: 600;
    padding: 7px 12px; border-radius: 99px; border: 1px solid rgb(var(--color-foreground) / .14); }
  .rbxff__weiter { margin-top: 22px; }

  /* ---------- Die Abschnitte unter dem Formular ---------- */
  .rbxff__mehr { margin-top: 64px; display: grid; gap: 56px; }
  .rbxff__kicker {
    font-size: 12px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
    opacity: .55; margin: 0 0 8px;
  }
  .rbxff__block { display: grid; gap: 24px; align-items: center; }
  .rbxff__blockbild {
    width: 100%; height: auto; display: block; border-radius: var(--rounded-block, 16px);
    border: 1px solid rgb(255 255 255 / .70);
    box-shadow: 0 14px 44px rgb(var(--color-foreground) / .10);
  }
  /* Die Theme-Klassen title-lg/title-md sind fuer Schlagworte gemacht, nicht fuer ganze
     Saetze: in Versalien und Plakatgroesse laeuft eine Ueberschrift wie „Du siehst den
     Farbton an deiner eigenen Wand" ueber sechs Zeilen und erschlaegt den Text darunter
     (Nutzer: „die Ueberschriften sind zu gross"). Deshalb hier eine eigene Groesse und
     normale Schreibweise — die Schrift des Themes bleibt, nur der Ton wird leiser. */
  .rbxff h1.heading { font-size: clamp(27px, 3.6vw, 42px); line-height: 1.14; text-transform: none; }
  .rbxff h2.heading,
  .rbxff__blocktext h2,
  .rbxff__quiz h2 {
    font-size: clamp(21px, 2.4vw, 29px); line-height: 1.24; text-transform: none;
    letter-spacing: -.005em;
  }
  .rbxff__blocktext h2 { margin: 0 0 12px; }
  .rbxff__blocktext p { margin: 0 0 14px; line-height: 1.65; }
  .rbxff__blocktext .button { margin-top: 4px; }
  @media screen and (min-width: 820px) {
    .rbxff__block { grid-template-columns: 1fr 1fr; gap: 40px; }
    /* Bild und Text tauschen die Seiten, damit die Seite nicht zur Liste wird. */
    .rbxff__block--gedreht .rbxff__blockbild { order: 2; }
  }

  /* ---------- Alles fuer den Anstrich ---------- */
  /* Der Block laeuft ueber die volle Breite und nicht als Zweispalter wie die Abschnitte
     darueber: Drei Kacheln nebeneinander brauchen den Platz, und der Text steht als Zeile
     darueber besser als in einer Spalte daneben. */
  .rbxff__block--voll { display: block; }
  .rbxff__blocktext--mitte { max-width: 46ch; margin: 0 auto 26px; text-align: center; }
  .rbxff__blocktext--mitte p { margin: 0; }
  .rbxff__produkte { list-style: none; margin: 0; padding: 0; display: grid; gap: 16px; }
  .rbxff__produkt a {
    display: block; text-decoration: none; color: inherit; height: 100%;
    padding: 14px 14px 16px; border-radius: var(--rounded-block, 16px);
    background: rgb(255 255 255 / .58);
    border: 1px solid rgb(255 255 255 / .70);
    box-shadow: 0 8px 30px rgb(var(--color-foreground) / .06);
    transition: box-shadow .18s ease, border-color .18s ease, transform .18s ease;
  }
  .rbxff__produkt a:hover {
    border-color: rgb(var(--color-foreground) / .22);
    box-shadow: 0 14px 40px rgb(var(--color-foreground) / .12);
    transform: translateY(-2px);
  }
  .rbxff__produkt img {
    width: 100%; height: auto; aspect-ratio: 1 / 1; object-fit: cover; display: block;
    border-radius: calc(var(--rounded-block, 16px) - 6px); margin-bottom: 12px;
    background: rgb(255 255 255 / .6);
  }
  .rbxff__produkt b { display: block; font-size: 15px; line-height: 1.3; margin-bottom: 3px; }
  .rbxff__preis { display: block; font-size: 13px; opacity: .68; }
  /* Vier Vorschaubilder im Quadrat — zusammen so gross wie ein Produktbild, damit die
     Zubehoer-Kachel neben den Boxen nicht aus der Reihe faellt. */
  .rbxff__zubvorschau {
    display: grid; grid-template-columns: 1fr 1fr; gap: 4px;
    aspect-ratio: 1 / 1; margin-bottom: 12px;
    border-radius: calc(var(--rounded-block, 16px) - 6px); overflow: hidden;
  }
  .rbxff__zubvorschau img { margin: 0; border-radius: 0; height: 100%; }
  @media screen and (min-width: 700px) {
    .rbxff__produkte { grid-template-columns: repeat(3, 1fr); gap: 20px; }
  }

  /* ---------- Das Farborakel ---------- */
  .rbxff__quiz {
    padding: 30px 28px 32px; border-radius: var(--rounded-block, 16px);
    background: rgb(255 255 255 / .58);
    border: 1px solid rgb(255 255 255 / .70);
    box-shadow: 0 10px 40px rgb(var(--color-foreground) / .07);
    -webkit-backdrop-filter: blur(14px) saturate(1.15);
    backdrop-filter: blur(14px) saturate(1.15);
    text-align: center;
  }
  .rbxff__quiz h2 { margin: 0 0 10px; }
  .rbxff__quizunter { max-width: 46ch; margin: 0 auto 4px; opacity: .8; }
  .rbxff__quizkarte { margin-top: 22px; }

  .rbxff__punkte { display: flex; gap: 7px; justify-content: center; margin-bottom: 20px; }
  .rbxff__punkte span {
    width: 8px; height: 8px; border-radius: 50%;
    background: rgb(var(--color-foreground) / .14); transition: all .3s ease;
  }
  .rbxff__punkte span.war { background: rgb(var(--color-foreground) / .38); }
  .rbxff__punkte span.hier { background: rgb(var(--color-foreground) / .70); transform: scale(1.35); }

  .rbxff__frage { font-size: 19px; line-height: 1.35; font-weight: 700; margin: 0 0 20px; }
  .rbxff__wahlen { display: grid; gap: 10px; max-width: 34rem; margin: 0 auto; }
  .rbxff__wahl {
    font: inherit; text-align: left; cursor: pointer;
    padding: 14px 18px; border-radius: var(--rounded-block, 14px);
    border: 1px solid rgb(var(--color-foreground) / .12);
    background: rgb(255 255 255 / .60); color: inherit;
    transition: border-color .15s ease, background-color .15s ease, transform .1s ease;
  }
  .rbxff__wahl:hover { border-color: rgb(var(--color-foreground) / .38); background: #fff; }
  .rbxff__wahl:active { transform: scale(.995); }
  .rbxff__wahl--trio, .rbxff__wahl--fleck { display: flex; align-items: center; gap: 14px; }
  .rbxff__trio { display: flex; flex: none; }
  .rbxff__trio span {
    width: 26px; height: 26px; border-radius: 50%;
    box-shadow: 0 0 0 2px rgb(255 255 255 / .9);
  }
  .rbxff__trio span + span { margin-inline-start: -9px; }
  .rbxff__quizfleck {
    width: 34px; height: 34px; border-radius: 10px; flex: none;
    box-shadow: inset 0 0 0 1px rgb(var(--color-foreground) / .14);
  }
  /* Steht in der Wahlzeile ein Produktfoto statt einer Flaeche, gilt die Zeilengroesse —
     sonst zieht die 78px-Grundgroesse der Kachel die ganze Frage auseinander. */
  .rbxff__wahl--fleck .rbxff__klecks { width: 40px; height: 40px; border-radius: 10px; flex: none; }

  .rbxff__typname { font-size: 26px; line-height: 1.2; font-weight: 700; margin: 0 0 8px; }
  .rbxff__typsatz { max-width: 44ch; margin: 0 auto 22px; opacity: .82; }
  .rbxff__quiztoene { display: grid; gap: 10px; max-width: 30rem; margin: 0 auto; }
  .rbxff__quizton {
    display: flex; align-items: center; gap: 14px; text-decoration: none; color: inherit;
    padding: 10px 14px; border-radius: var(--rounded-block, 14px);
    border: 1px solid rgb(255 255 255 / .70); background: rgb(255 255 255 / .55);
  }
  .rbxff__quizton:hover { border-color: rgb(var(--color-foreground) / .30); }
  .rbxff__quizton .rbxff__klecks { width: 44px; height: 44px; border-radius: 10px; flex: none; }
  /* Der Wechsel zur naechsten Frage war ein harter Schnitt: Der Text stand einfach anders
     da. Jetzt sinkt die alte Frage kurz weg und die neue kommt von unten herein — 340 ms
     insgesamt, gerade genug, damit das Auge dem Wechsel folgt. */
  .rbxff__quizkarte { transition: opacity .16s ease, transform .16s ease; }
  .rbxff__quizkarte--raus { opacity: 0; transform: translateY(-6px); }
  @keyframes rbxffQuizEin {
    from { opacity: 0; transform: translateY(9px); }
    to   { opacity: 1; transform: none; }
  }
  .rbxff__quizkarte--ein { animation: rbxffQuizEin .26s ease both; }
  @media (prefers-reduced-motion: reduce) {
    .rbxff__quizkarte, .rbxff__quizkarte--raus, .rbxff__quizkarte--ein {
      transition: none; animation: none; opacity: 1; transform: none;
    }
  }
  .rbxff__nochmal {
    font: inherit; font-size: 14px; margin-top: 20px; cursor: pointer;
    background: none; border: 0; padding: 6px 4px; color: inherit;
    text-decoration: underline; text-underline-offset: 3px; opacity: .65;
  }
  .rbxff__nochmal:hover { opacity: 1; }
  @media screen and (min-width: 700px) {
    .rbxff__quiztoene { grid-template-columns: repeat(3, 1fr); }
    .rbxff__quizton { flex-direction: column; text-align: center; gap: 9px; padding: 16px 10px; }
    .rbxff__quizton .rbxff__klecks { width: 58px; height: 58px; }
  }
  @media screen and (min-width: 700px) { .rbxff__knopf { width: auto; } }
.rbxff__uploadknopf { border-radius: var(--buttons-radius, 999px); }
.rbxff__uploadknopf .btn-fill { border-radius: inherit; }
.rbxff__umstreichen-link { margin: 10px 0 0; font-size: 15px; }
.rbxff__umstreichen-link a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }
#raum-umstreichen { margin-top: 28px; scroll-margin-top: 90px; }