{
 "$schema": "../../schema.json",
 "schema": "fundus/1",
 "id": "gap-decorations-raster",
 "name": "Trennlinien im Raster (Gap Decorations)",
 "name_en": "Gap decorations: row-rule and column-rule in grid and flex",
 "kurz": "Haarlinien in Raster, Liste und umbrechender Leiste kommen aus row-rule und column-rule, mit Ersatz per Pseudo-Elementen, der gleich aussieht.",
 "kategorie": "Hero & Section-Layouts",
 "kategorie_slug": "hero-layouts",
 "kategorie_nr": 4,
 "bau_chat": "C2",
 "prioritaet": "F",
 "trendstatus": "aufsteigend",
 "belegstatus": "quellenbelegt",
 "website_belege": 0,
 "stimmung": [
  "ruhig",
  "editorial",
  "präzise"
 ],
 "stimmung_roh": [
  "präzise",
  "architektonisch",
  "ruhig",
  "editorial"
 ],
 "technik": [
  "css",
  "css-grid",
  "subgrid",
  "flexbox",
  "vanilla-js"
 ],
 "technik_gruppen": [
  "css",
  "js"
 ],
 "leistungskosten": "niedrig",
 "steckbrief": {
  "beschreibung": "Linien zwischen Rasterzellen, Listenzeilen und umbrechenden Flex-Elementen kommen direkt aus dem Layout: column-rule und row-rule zeichnen in die Lücke (gap), nicht an die Elemente. Die Linien passen sich an, wenn Spalten umbrechen oder Elemente ausgeblendet werden: keine doppelten Ränder, kein Strich am Zeilenende. rule-break legt fest, ob Linien an Kreuzungen durchlaufen oder abbrechen, rule-inset kürzt sie an Enden und Kreuzungen. Breite, Stil und Farbe nehmen Listen und repeat() an, etwa eine kräftigere Linie nach jeder fünften Zeile. Breite, Farbe und Inset lassen sich animieren.",
  "warum_es_wirkt": "Haarlinien geben einem ruhigen Raster Halt, ohne Flächen oder Kästen. Weil die Linien in der Lücke liegen, bleiben sie bei jedem Umbruch und jedem Filter richtig. Das wirkt präzise wie ein gedruckter Plan oder eine Tabelle im Jahresbericht. Der Code wird kürzer: keine Ränder an Kindern, keine :last-child-Ausnahmen, keine Rechnerei pro Spaltenzahl.",
  "wann_einsetzen": "Kenndaten einer Projektseite, Werkverzeichnisse und Programmlisten, Speise- und Preiskarten, Visitenkarten im Footer, Kennzahlen-Raster. Überall, wo Linien heute per border oder Pseudo-Element an Kinder gehängt werden und beim Umbrechen Ärger machen.",
  "wann_nicht": "Wenn die Linie zum Inhalt gehört und Bedeutung trägt, die ohne sie verloren geht (dann echte Tabelle mit Rahmen). Bei Layouts ohne gap. Wenn sehr alte Browser dieselbe Optik brauchen und kein Fallback gepflegt werden soll. Als reine Deko auf einer Seite, die sonst mit Weißraum gliedert.",
  "varianten": [
   "Kenndaten-Raster: Grid mit column-rule und row-rule, rule-break: intersection und Lücken an den Kreuzungen (rule-inset-junction)",
   "Werkliste oder Programm: nur row-rule, mit repeat() kräftigere Linie nach jeder fünften Zeile; Filter blenden Zeilen aus, die Linien zählen neu",
   "Visitenkarte oder Meta-Leiste: Flex mit flex-wrap und column-rule, Trennstriche nur zwischen Elementen derselben Zeile",
   "Mehrspaltiger Text mit column-rule (gab es schon für multi-column, jetzt mit denselben neuen Eigenschaften)",
   "Animiert: Linien wachsen beim Laden über rule-inset von der Mitte aus, Farbe und Kreuzungslücke wechseln beim Hover"
  ],
  "umsetzung": "Grid: .kenndaten { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 28px; rule: 1px solid #c5c7c7; rule-break: intersection; rule-inset-junction: -9px; rule-visibility-items: between }. Liste: ol als Grid mit row-gap 2px, row-rule-width: repeat(4, 1px), 2px und row-rule-color: repeat(4, #d9dbdb), #231f20 für eine kräftige Linie nach jeder fünften Zeile. Flex: flex-wrap: wrap mit column-rule. Weiche nur in CSS: Die Ersatzlinien (::before/::after an jedem Kind, Container mit overflow: clip) stehen immer im CSS, @supports (row-rule: 1px solid) schaltet die echten Linien ein und die Pseudo-Elemente aus. Ohne Unterstützung und ohne JS sieht die Seite damit gleich aus. Breite, Farbe und Insets sind animierbar; zum Aufziehen große Insets (größer als die halbe Segmentlänge) auf den Endwert animieren. Beobachtung in Chrome 153: eine @keyframes-Animation von column-rule-color: transparent ließ die Linien nach einem späteren Neuzeichnen verschwinden, daher nur Insets animieren (Farbübergänge per transition funktionieren).",
  "mobil": "Raster bricht auf zwei Spalten um, die Linien folgen ohne eigene Regeln. In umbrechenden Flex-Leisten stehen Trennstriche nur zwischen Elementen derselben Zeile, im Ersatz schneidet die Liste die Striche am Zeilenanfang ab. Kein Hover nötig; Tippen kann den Hover-Zustand umschalten.",
  "reduzierte_bewegung": "Linien stehen sofort. Kein Aufziehen, keine Übergänge bei Hover, Filter und Breitenwechsel.",
  "barrierefreiheit": "Linien sind reine Gestaltung und erscheinen nicht im Barrierefreiheitsbaum. Die Struktur kommt aus dem Markup: Kenndaten als dl, Werkliste als ol mit Zeilen als Links, Visitenkarte als address. Linien, die Gruppen trennen, mit mindestens 3 : 1 gegen den Grund (WCAG 1.4.11), etwa die kräftige Rhythmuslinie in #231f20; reine Zierlinien dürfen leiser sein. Filterknöpfe mit aria-pressed, Trefferzahl mit aria-live. Im Kontrastmodus (forced-colors) nehmen die Ersatzlinien CanvasText an."
 },
 "messwerte": {
  "easing": "cubic-bezier(0.1, 0.6, 0.4, 1) für Hover, cubic-bezier(0.1, 0.9, 0.3, 1) für das Aufziehen",
  "dauer_ms": "250 Hover (Farbe, Kreuzungslücke), 750 Aufziehen der Linien",
  "stagger_ms": "",
  "distanz": "Linienbreite 1px, kräftige Linie 2px; Kreuzungslücke 6px → 0",
  "sonstiges": "Chrome-Beispiel: transition column-rule-color 0.4s, rule-inset-junction 0.4s; repeat(2, 1px), 4px. Eigene Werte aus den Bewegungs-Tokens des Rezepts architektur-ruhiges-raster.",
  "herkunft": "eigene Festlegung",
  "quelle": "https://developer.chrome.com/blog/gap-decorations-stable"
 },
 "kurve": {
  "bezier": [
   0.1,
   0.6,
   0.4,
   1.0
  ],
  "css": "cubic-bezier(0.1, 0.6, 0.4, 1)",
  "name": "eigene Kurve",
  "dauer_ms": 125
 },
 "gesehen_bei": [
  {
   "seite": "Chrome for Developers: Gap decorations stable",
   "url": "https://developer.chrome.com/blog/gap-decorations-stable",
   "auszeichnung": "",
   "beobachtung": "Stabil in Chrome und Edge 149 (Beitrag vom 15.05.2026), Entwickler-Test seit Chrome 139. Eigenschaften column-rule, row-rule, rule, rule-break (normal | none | intersection), rule-inset mit -cap und -junction, rule-visibility-items (normal | all | around | between). repeat() für Breite, Stil, Farbe, z. B. row-rule-width: repeat(2, 1px), 4px. Breite, Farbe und Insets sind animierbar (transition: column-rule-color 0.4s, rule-inset-junction 0.4s). Ohne Unterstützung bleiben die Lücken einfach leer; ein Polyfill ist in Arbeit.",
   "art": "artikel"
  },
  {
   "seite": "ICS MEDIA: CSS Gap Decorations for adding lines to grid and flex gaps",
   "url": "https://ics.media/en/entry/260618/",
   "auszeichnung": "",
   "beobachtung": "Beitrag vom 18.06.2026: verfügbar in Chrome und Edge 149. Beispiele rule: 3px solid green für ein Raster und eine umbrechende Linkliste mit column-rule: 1px solid rgb(0 0 0 / 0.45); Hover und :focus-visible ändern column-rule-color und column-rule-inset.",
   "art": "artikel"
  },
  {
   "seite": "W3C: CSS Gap Decorations Module Level 1 (Working Draft 27.02.2026)",
   "url": "https://www.w3.org/TR/2026/WD-css-gaps-1-20260227/",
   "auszeichnung": "",
   "beobachtung": "Spezifikation der Eigenschaften für Grid, Flex, Multi-Column und Grid Lanes.",
   "art": "artikel"
  }
 ],
 "tutorials": [
  {
   "titel": "Chrome for Developers: Gap decorations stable",
   "url": "https://developer.chrome.com/blog/gap-decorations-stable"
  },
  {
   "titel": "ICS MEDIA: CSS Gap Decorations for adding lines to grid and flex gaps",
   "url": "https://ics.media/en/entry/260618/"
  },
  {
   "titel": "W3C: CSS Gap Decorations Module Level 1",
   "url": "https://www.w3.org/TR/css-gaps-1"
  }
 ],
 "kombinierbar_mit": [
  "case-study-geruest",
  "projektindex-hover-vorschau",
  "editorial-magazin-layout",
  "studio-visitenkarte-footer",
  "tabellenziffern",
  "meta-labels-hud-typografie",
  "eine-familie-wenig-gewichte"
 ],
 "urls": {
  "detail": "https://cecodesign.de/lab/fundus/hero-layouts/gap-decorations-raster/",
  "meta": "https://cecodesign.de/lab/fundus/hero-layouts/gap-decorations-raster/meta.json",
  "demo": "https://cecodesign.de/lab/fundus/hero-layouts/gap-decorations-raster/demo"
 },
 "herkunft": {
  "quelldateien": [
   "DEF-Recherche 01.11.2026"
  ],
  "pruefnotizen": [
   "Belegt durch Herstellerartikel, Fachartikel und Spezifikation; noch keine Produktionsseite mit Gap Decorations gefunden (Feature erst seit Chrome 149).",
   "Firefox und Safari: laut Web Features Explorer (02.11.2026) noch ohne Unterstützung, Status „Limited availability“; nur Chrome/Edge 149+ (stabil 02.06.2026). Fallback Pflicht."
  ]
 },
 "bau": {
  "status": "fertig",
  "kurz": "Haarlinien in Raster, Liste und umbrechender Leiste kommen aus row-rule und column-rule, mit Ersatz per Pseudo-Elementen, der gleich aussieht.",
  "demo": true,
  "abhaengigkeiten": [],
  "werte": {
   "easing": "cubic-bezier(0.1, 0.6, 0.4, 1) für Hover und Breite; cubic-bezier(0.1, 0.9, 0.3, 1) für das Aufziehen der Linien",
   "dauer_ms": "125 Linkfarbe, 250 Hover (Linienfarbe, Kreuzungslücke) und Filterknöpfe, 750 Aufziehen, 1200 Breitenwechsel der Visitenkarte",
   "stagger_ms": "120 (waagerechte Linien starten nach den senkrechten)",
   "weiche": "@supports (row-rule: 1px solid) { :root:not(.gd-ersatz) … } schaltet den nativen Weg ein und blendet die Pseudo-Elemente aus; JS liest CSS.supports('row-rule', '1px solid') && CSS.supports('rule-break', 'intersection') nur für die Statusanzeige",
   "ersatz": "Kind zeichnet Linie links (::before, left: calc(var(--spalt) / -2 - .5px)) und oben (::after); Container overflow: clip, overflow-clip-margin 0 schneidet Linien vor der ersten Spalte und über der ersten Zeile ab; Aufziehen per scaleX/scaleY 0 → 1",
   "farben": "Grund #ffffff, Text #231f20, Meta #76767a, Haarlinie #c5c7c7, Listenlinie #d9dbdb, dunkle Sektion #1f2323 mit Linie rgba(242, 242, 240, .26), Fokus #0022ff",
   "schrift": "Hanken Grotesk: Titel clamp(1.953rem, 1.2rem + 2.4vw, 3.052rem) wght 450, -0.02em; Text 1.0625rem/1.45, -0.012em; Meta 0.8rem #76767a; Betonung kursiv statt fett",
   "linienbreite": "1px, kräftige Rhythmuslinie 2px",
   "browser_geprueft": "HeadlessChrome 153 (pruef.sh, 01.11.2026): CSS.supports true für row-rule, rule, repeat() in Breite und Farbe, rule-break, rule-inset-cap/-junction, row-rule-inset-end, rule-visibility-items, rule-overlap; Ersatzweg im selben Browser erzwungen und verglichen"
  },
  "ausloeser": "laden",
  "touch": "Kein Hover: Kreuzungen bleiben offen, Tippen auf das Kenndaten-Raster schaltet den geschlossenen Zustand um. Unter 760 px zwei Spalten, die Linien folgen ohne eigene Regeln. Werkliste zweizeilig (Nr., Projekt, Jahr; darunter Ort, Typologie, Stand). Filterknöpfe 40 px, Listenzeilen mindestens 48 px hoch. Menü als Knopf mit aria-expanded.",
  "reduziert": "Linien stehen sofort, kein Aufziehen, keine Übergänge bei Hover, Filter (ohne View Transition) und Breite.",
  "korrekturen": {
   "umsetzung": "Grid: .kenndaten { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 28px; rule: 1px solid #c5c7c7; rule-break: intersection; rule-inset-junction: -9px; rule-visibility-items: between }. Liste: ol als Grid mit row-gap 2px, row-rule-width: repeat(4, 1px), 2px und row-rule-color: repeat(4, #d9dbdb), #231f20 für eine kräftige Linie nach jeder fünften Zeile. Flex: flex-wrap: wrap mit column-rule. Weiche nur in CSS: Die Ersatzlinien (::before/::after an jedem Kind, Container mit overflow: clip) stehen immer im CSS, @supports (row-rule: 1px solid) schaltet die echten Linien ein und die Pseudo-Elemente aus. Ohne Unterstützung und ohne JS sieht die Seite damit gleich aus. Breite, Farbe und Insets sind animierbar; zum Aufziehen große Insets (größer als die halbe Segmentlänge) auf den Endwert animieren. Beobachtung in Chrome 153: eine @keyframes-Animation von column-rule-color: transparent ließ die Linien nach einem späteren Neuzeichnen verschwinden, daher nur Insets animieren (Farbübergänge per transition funktionieren).",
   "mobil": "Raster bricht auf zwei Spalten um, die Linien folgen ohne eigene Regeln. In umbrechenden Flex-Leisten stehen Trennstriche nur zwischen Elementen derselben Zeile, im Ersatz schneidet die Liste die Striche am Zeilenanfang ab. Kein Hover nötig; Tippen kann den Hover-Zustand umschalten.",
   "reduzierte_bewegung": "Linien stehen sofort. Kein Aufziehen, keine Übergänge bei Hover, Filter und Breitenwechsel.",
   "barrierefreiheit": "Linien sind reine Gestaltung und erscheinen nicht im Barrierefreiheitsbaum. Die Struktur kommt aus dem Markup: Kenndaten als dl, Werkliste als ol mit Zeilen als Links, Visitenkarte als address. Linien, die Gruppen trennen, mit mindestens 3 : 1 gegen den Grund (WCAG 1.4.11), etwa die kräftige Rhythmuslinie in #231f20; reine Zierlinien dürfen leiser sein. Filterknöpfe mit aria-pressed, Trefferzahl mit aria-live. Im Kontrastmodus (forced-colors) nehmen die Ersatzlinien CanvasText an."
  },
  "geprueft": "02.11.2026",
  "notiz": "Welt: Rezept architektur-ruhiges-raster, erfundenes Büro Aaregg Architekten in Thun (Bälliz, Lerchenfeld, Gwatt, Oberhofen; Schweizer Schreibweise ohne ß). Drei Varianten über ?v=: Kenndaten eines Wohnhauses mit eigener Ansichtszeichnung (SVG), Werkverzeichnis mit 18 Projekten und Filter, dunkle Visitenkarte mit schematischem Lageplan (SVG) und Breitenregler. Das Pult schaltet zwischen nativ und Ersatz um (zusätzlich ?ersatz), damit man beide Wege im selben Browser vergleichen kann; beide wurden in Chrome 153 per Screenshot verglichen und sehen gleich aus, auch im eingefrorenen Zwischenstand des Aufziehens. Kategorie Hero & Section-Layouts, weil das Muster ganze Sektionen gliedert. Referenzen: developer.chrome.com, ics.media, w3.org; Prinzip Kenndaten-Raster nach forensic-architecture.org. AD-Review 02.11.2026: Note 4.",
  "varianten": [
   {
    "id": "kenndaten",
    "name": "Kenndaten-Raster",
    "wann": "Projekt- oder Objektseite (Architektur, Immobilien, Handwerk), Fakten als dl in drei Spalten.",
    "werte": {
     "raster": "grid-template-columns: repeat(3, minmax(0, 1fr)), gap 28px (Telefon 2 Spalten, 22px)",
     "linien": "rule: 1px solid #c5c7c7; rule-break: intersection; rule-inset-cap: 0; rule-inset-junction: calc(5px - 14px) = -9px, sichtbare Lücke an jeder Kreuzung 10px; rule-visibility-items: between",
     "hover": "Linienfarbe #231f20, Kreuzungslücke 0 (rule-inset-junction: -14px), 250 ms",
     "aufziehen": "@keyframes von column-rule-inset 160px und row-rule-inset 480px, 750 ms, Zeilen 120 ms später"
    }
   },
   {
    "id": "werkliste",
    "name": "Werkliste mit Filter",
    "wann": "Werkverzeichnis, Programm, Termine, Preisliste: lange Zeilen, die gefiltert werden; Linien zählen nach dem Filtern neu.",
    "werte": {
     "raster": "ol als Grid, row-gap 2px; Zeilen als Grid mit Spalten 3.2rem 1fr 11rem 8rem 11rem 3.4rem",
     "linien": "row-rule-width: repeat(4, 1px), 2px; row-rule-color: repeat(4, #d9dbdb), #231f20; row-rule-break: none",
     "ersatz": "li::before 1px #d9dbdb; li:nth-child(5n + 1 of :not([hidden]))::before 2px #231f20",
     "filter": "hidden an den Zeilen, document.startViewTransition wenn vorhanden; Trefferzahl aria-live",
     "aufziehen": "@keyframes von row-rule-inset-end: 100cqi (Container ist die Sektion), 750 ms"
    }
   },
   {
    "id": "karte",
    "name": "Visitenkarte im Footer",
    "wann": "Footer, Kontaktleiste, Meta-Zeilen und Linklisten, die umbrechen; für jede Branche.",
    "werte": {
     "raster": "address und ul als flex mit flex-wrap: wrap, gap 14px 34px (Links 26px)",
     "linien": "column-rule: 1px solid rgba(242, 242, 240, .26); column-rule-inset: .12em",
     "ersatz": "Element::before an left: calc(var(--spalt) / -2 - .5px), Liste overflow: clip mit overflow-clip-margin 6px (Fokusrahmen bleibt sichtbar)",
     "breite": "Regler 36 bis 100 %, transition inline-size 1200 ms cubic-bezier(0.1, 0.6, 0.4, 1)",
     "aufziehen": "@keyframes von column-rule-inset 1.2em, 750 ms"
    }
   }
  ]
 }
}
