@nextrap/ntl-2col 0.1.4 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,101 @@
1
+ ---
2
+ name: ntl-2col-theming
3
+ description: Theme- und Component-Style-Klassen für @nextrap/ntl-2col entwickeln; beschreibt Parts, responsive Slot-Aufteilung und vorhandene SCSS-Mixins.
4
+ ---
5
+
6
+ # NTL 2Col Theming
7
+
8
+ Nutze diesen Skill für Theme-SCSS und neue visuelle Varianten. Für Markup und Content-Zuordnung nutze `ntl-2col-usage`.
9
+
10
+ ## Verbindlicher Slot-Vertrag
11
+
12
+ Behalte beim Seaming standardmäßig die eingebaute Content-Zuordnung bei:
13
+
14
+ - `main` enthält den Hauptinhalt.
15
+ - `aside` enthält den Inhalt der zweiten Spalte.
16
+ - `top` und `bottom` gehen innerhalb des `wrapper` über dessen volle Breite.
17
+ - `header` und `footer` liegen außerhalb des `wrapper` und bleiben über die volle Containerbreite.
18
+ - Verschiebe `header`, `wrapper` oder `footer` nicht per Grid oder Flex in nebeneinanderliegende Spalten.
19
+
20
+ Soll nur eine Überschrift links beziehungsweise seitlich stehen, ordne sie `aside` zu und verwende die vorhandene `.reverse`- beziehungsweise `.reverse-desktop`-Funktion. Erstelle dafür keine eigene `style-header-left`-Variante. Weitere Inhalte derselben Seitenspalte werden ebenfalls `aside` zugeordnet; der Hauptinhalt bleibt dadurch unabhängig in `main` erweiterbar.
21
+
22
+ Weiche von der Standardzuordnung nur für eine ausdrücklich verlangte, wiederverwendbare Sonderkomposition ab. Prüfe dabei immer die mobile Lesereihenfolge.
23
+
24
+ Entwickler sagen teilweise `header` oder `footer`, meinen aber `top` oder `bottom`. Wenn Position oder Ebene nicht eindeutig ist, frage: „Meinst du `header`/`footer` außerhalb oder `top`/`bottom` innerhalb des Wrappers?“
25
+
26
+ ## Ausnahme: Content-Zuordnung im Theme überschreiben
27
+
28
+ Die automatischen Selektoren der benannten Slots können über CSS-Variablen ersetzt werden. Verwende diese Möglichkeit ausschließlich für eine ausdrücklich freigegebene, wiederverwendbare Sonderkomposition. Hole vor jeder Nutzung die Erlaubnis des Users ein. Normale Content-Zuordnung, `.reverse`, `.reverse-desktop`, Parts und CSS-Layout haben Vorrang.
29
+
30
+ | Zielbereich | Selektorvariable |
31
+ |---|---|
32
+ | `header` | `--ntl-2col-header-selector` |
33
+ | `top` | `--ntl-2col-top-selector` |
34
+ | `aside` | `--ntl-2col-aside-selector` |
35
+ | `bottom` | `--ntl-2col-bottom-selector` |
36
+ | `footer` | `--ntl-2col-footer-selector` |
37
+
38
+ Der unbenannte `main`-Slot besitzt absichtlich keine Selektorvariable. Ein Variablenwert ist ein CSS-Selektor oder eine kommaseparierte Selektorliste und wird ohne Anführungszeichen gesetzt:
39
+
40
+ ```scss
41
+ .page-special-composition ntl-2col {
42
+ --ntl-2col-top-selector: :scope > .header;
43
+ }
44
+ ```
45
+
46
+ Dieses Beispiel verschiebt direkte `.header`-Kinder in den inneren `top`-Bereich. Sobald der Variablenselektor Elemente findet, ersetzt er für den Zielbereich die eingebaute Zuordnung. Soll die eigene Auswahl die Standardauswahl ergänzen, muss der Standardselektor in einer kommaseparierten Liste enthalten sein, zum Beispiel `--ntl-2col-top-selector: :scope > .special-top, :scope > .top;`.
47
+
48
+ Beachte bei jeder Freigabe:
49
+
50
+ - Prüfe die semantische Rolle und die mobile Lesereihenfolge, nicht nur die Desktop-Position.
51
+ - Vermeide Überschneidungen, bei denen dasselbe Light-DOM-Kind mehrere Selektorvariablen erfüllt.
52
+ - Fehlerhafte Selektoren werden per `console.error` gemeldet. Nur die fehlerhafte Alternative wird übersprungen; weitere Alternativen, die Standardzuordnung und andere Slots werden weiterhin verarbeitet.
53
+ - Die Selektoren werden beim ersten Update ausgewertet. Ein späteres Ändern der Variablen sortiert vorhandene Inhalte nicht erneut.
54
+ - Die Funktion benötigt eine Version von `@trunkjs/content-pane`, die `@var(...)` in `data-query` unterstützt.
55
+
56
+ ## Theme-Regeln
57
+
58
+ - Binde die vollständige Baseline an genau eine `style-*` Klasse, normalerweise mit `default-style()`.
59
+ - Nutze vorhandene Mixins, bevor du eigenes `::part(...)`-Styling ergänzt.
60
+ - Erzwinge in der gemeinsamen Standard-Baseline keine vertikale Zentrierung oder sonstige `justify`-Ausrichtung. Standardmäßig bleiben `main` und `aside` ohne zusätzliches Justify-Override; wenn eine Ausrichtung gewünscht ist, muss sie im Theme bewusst ergänzt werden – entweder direkt in der jeweiligen `style-*`-Variante oder ausdrücklich über eine Modifier-Class.
61
+ - Wenn ein Theme eine eigene vertikale Ausrichtungslogik festlegt, wende sie innerhalb dieses Themes konsistent auf alle betroffenen `ntl-2col`-Varianten an statt nur auf einzelne Zufallsfälle.
62
+ - Feature-Klassen beginnen mit `with-*`; jede Style-Variante beginnt mit `style-*` und enthält ihre vollständige Baseline.
63
+ - Ändere Slot-Anordnung und Reihenfolge mit CSS, nicht mit TypeScript oder DOM-Umbauten.
64
+ - Scope Desktop-Regeln auf `[mode='desktop']` und stelle im Mobile-Modus die richtige Lesereihenfolge sicher.
65
+ - Definiere am `ntl-2col` keinen wiederkehrenden Abstand zu benachbarten Layouts und verlange dafür im Markup keine `py-*`, `my-*` oder `mt-*` Utilities. Dieser Content-Rhythmus gehört mit `--nt-spacing-section` in das umgebende Theme beziehungsweise den Content Container; die Komponente steuert nur interne Parts, Slots, Gaps und bewusst variant-spezifisches Padding.
66
+
67
+ Erstelle keine zusätzliche `style-*`-Variante nur für konfigurierbare Eigenschaften:
68
+
69
+ | Eigenschaft | Verwende stattdessen |
70
+ |---|---|
71
+ | Spaltenbreite | `--cols` pro Instanz, in Content Pane über `section-style` |
72
+ | Abstand zu anderen Layouts | Theme-Content-Flow mit `--nt-spacing-section` |
73
+ | Section-Fläche | `.surface-*` für Fläche und passende Textfarben; `.bg-*` für reinen Background |
74
+ | Reverse oder Breakout | vorhandene Modifier wie `.reverse`, `.reverse-desktop`, `.breakout-start`, `.breakout-end` |
75
+ | Vertikale Ausrichtung | nicht in die gemeinsame Standard-Baseline einbauen; nur bei Bedarf explizit im Theme setzen – bevorzugt direkt in der jeweiligen `style-*`-Variante über `::part(main)` und bei Bedarf `::part(aside)`, alternativ bewusst über eine Modifier-Class |
76
+ | Sticky Main | `.with-main-sticky-top`; Offset über `--main-sticky-top` |
77
+ | Wrapper-Background | `default-style($wrapper-bg-color: ...)` oder `with-wrapper-bg-color()` |
78
+ | Border oder Radius | `default-style()`, eine dokumentierte Variable oder ein kombinierbarer `with-*`-Modifier |
79
+
80
+ Eine weitere `style-*`-Variante ist nur gerechtfertigt, wenn sie eine vollständige, wiederverwendbare visuelle Baseline mit eigener Part-/Child-Darstellung und responsiver Komposition bildet, zum Beispiel ein echtes Hero-Layout. Eine einzelne Farbe, Breite oder Position genügt nicht.
81
+
82
+ ## Parts und Variablen
83
+
84
+ Verfügbare Parts: `container`, `header`, `top`, `wrapper`, `main`, `aside`, `bottom`, `footer`.
85
+
86
+ Wichtige Layoutvariablen: `--breakpoint`, `--cols`, `--container-width`, `--gap` und `--inner-padding`. Die Selektorvariablen sind keine normale Layoutkonfiguration; für sie gelten die Freigaberegeln im vorherigen Abschnitt.
87
+
88
+ ## Vorhandene Mixins
89
+
90
+ | Mixin | Zweck |
91
+ |---|---|
92
+ | `default-style()` | Vollständige visuelle Baseline |
93
+ | `with-reverse()` | `main` und `aside` umkehren |
94
+ | `with-alternating()` | Aufeinanderfolgende Layouts alternieren |
95
+ | `with-breakout-start()` / `with-breakout-end()` | Spalte zum Viewport-Rand erweitern |
96
+ | `with-image-auto-objectfit()` | Automatische Aside-Bilder einpassen |
97
+ | `with-justify($justify)` | vorhandenes Legacy-Mixin; nicht Teil der empfohlenen Standard-Baseline. Nur bewusst und explizit verwenden, wenn eine Modifier-Class oder eine projektweite Opt-in-Lösung gewünscht ist |
98
+ | `with-main-sticky-top($top)` | Kurzen Main-Content auf Desktop im Viewport halten |
99
+ | `with-background-and-divider()` | Hintergrund und Spaltentrenner |
100
+ | `with-wrapper-bg-color()` | Wrapper-Hintergrund setzen |
101
+ | `with-modifier-classes()` | Vorbereitete Modifier-Klassen registrieren |
@@ -0,0 +1,72 @@
1
+ # NTL 2Col Theme-Beispiele
2
+
3
+ Bereichsklassen wie `.aside` oder `.top` müssen am direkten Light-DOM-Kind von `ntl-2col` landen.
4
+
5
+ ## Standard
6
+
7
+ ```markdown
8
+ ## Behandlungsschwerpunkt
9
+ {: layout="ntl-2col.style-focus" section-style="--cols: 8;"}
10
+
11
+ Der Hauptinhalt bleibt in `main`.
12
+
13
+ ![Diagnostik](./diagnostik.jpg)
14
+ ```
15
+
16
+ ```scss
17
+ @use '../../../../../../../../node_modules/@nextrap/ntl-2col/index' as twoCol;
18
+
19
+ ntl-2col.style-focus {
20
+ @include twoCol.default-style();
21
+ }
22
+ ```
23
+
24
+ ## Überschrift als linke Spalte
25
+
26
+ Bevorzugt wird die Überschrift `aside` zugeordnet. `.reverse` setzt sie auf Desktop nach links und mobil vor `main`.
27
+
28
+ ```markdown
29
+ ## Behandlungsschwerpunkt
30
+ {: layout="ntl-2col.style-heading-column.reverse" .aside section-style="--cols: 8;"}
31
+
32
+ Der Hauptinhalt bleibt in `main`.
33
+ ```
34
+
35
+ ```scss
36
+ ntl-2col.style-heading-column {
37
+ @include twoCol.default-style();
38
+ }
39
+ ```
40
+
41
+ ## Ausnahme: `top` als linke Spalte
42
+
43
+ Ein leeres `aside` setzt `main` intern auf volle Breite. Die Theme-Klasse muss deshalb die betroffenen Parts für Desktop überschreiben und mobil zurücksetzen.
44
+
45
+ ```markdown
46
+ ## Behandlungsschwerpunkt
47
+ {: layout="ntl-2col.style-top-heading" .top section-style="--cols: 8;"}
48
+
49
+ Der Hauptinhalt bleibt in `main`.
50
+ ```
51
+
52
+ ```scss
53
+ ntl-2col.style-top-heading {
54
+ @include twoCol.default-style();
55
+
56
+ &[mode='desktop'] {
57
+ &::part(wrapper) { flex-direction: row; }
58
+ &::part(top) { order: 1; width: auto; flex: 1 1 0; }
59
+ &::part(main) {
60
+ order: 2;
61
+ width: calc(100% * var(--cols, 8) / 12);
62
+ flex: 0 0 calc(100% * var(--cols, 8) / 12);
63
+ }
64
+ }
65
+
66
+ &[mode='mobile'] {
67
+ &::part(wrapper) { flex-direction: column; }
68
+ &::part(top) { order: 1; width: 100%; flex: 0 0 auto; }
69
+ &::part(main) { order: 2; width: 100%; flex: 0 0 auto; }
70
+ }
71
+ }
72
+ ```
@@ -0,0 +1,108 @@
1
+ ---
2
+ name: ntl-2col-usage
3
+ description: "@nextrap/ntl-2col korrekt importieren und in HTML oder trunkjs/content-pane Markdown mit den passenden Content-Bereichen verwenden."
4
+ ---
5
+
6
+ # NTL 2Col Usage
7
+
8
+ Nutze diesen Skill für Markup, Content-Zuordnung und Beispiele. Für Theme-SCSS nutze `ntl-2col-theming`.
9
+
10
+ ## Import
11
+
12
+ ```ts
13
+ import '@nextrap/ntl-2col';
14
+ ```
15
+
16
+ ## Verbindliche Content-Zuordnung
17
+
18
+ Ordne Inhalte zuerst nach ihrer Rolle zu. Eine gewünschte Position allein ist kein Grund, einen anderen Slot zu verwenden oder eine neue Style-Variante anzulegen.
19
+
20
+ | Inhalt | Bereich |
21
+ |---|---|
22
+ | Haupttext und primärer Content | `main` |
23
+ | Zweite Spalte, Bild oder seitlicher Zusatzinhalt | `aside` |
24
+ | Volle Breite innerhalb des gerahmten Wrappers | `top` oder `bottom` |
25
+ | Volle Breite außerhalb des Wrappers | `header` oder `footer` |
26
+
27
+ - `main` und `aside` bilden im Desktop-Modus die beiden Spalten.
28
+ - `top` und `bottom` liegen im `wrapper` und gehen dort über die volle Breite.
29
+ - `header` und `footer` liegen außerhalb des `wrapper` und bleiben über die volle Containerbreite.
30
+ - Direkte Light-DOM-Kinder mit `.header`, `.top`, `.aside`, `.bottom` oder `.footer` werden automatisch zugeordnet.
31
+ - Direkte Bildabsätze können automatisch in `aside` verschoben werden.
32
+
33
+ ### Automatische Bildzuordnung
34
+
35
+ Die Komponente ordnet jedes direkte `p:has(img)`-Kind automatisch dem `aside`-Slot zu und ergänzt daran die Klasse `.auto`. Ein normales Markdown-Bild wird als direkter Bildabsatz gerendert und landet deshalb standardmäßig in `aside`:
36
+
37
+ ```markdown
38
+ ## Behandlungsschwerpunkt
39
+ {: layout="ntl-2col" section-style="--cols: 8;"}
40
+
41
+ Der Text bleibt in `main`.
42
+
43
+ ![Diagnostik](./diagnostik.jpg)
44
+ ```
45
+
46
+ Die Automatik greift nicht bei verschachtelten Bildabsätzen und nicht bei einem direkten `<img>` ohne umgebenden Absatz. Verwende dafür ein direktes Light-DOM-Kind mit `.aside` oder weise den `aside`-Slot ausdrücklich zu. Weitere direkte `.aside`-Kinder können Text, Bilder und andere Elemente derselben Seitenspalte aufnehmen.
47
+
48
+ Bereichsklassen müssen am direkten Light-DOM-Kind von `ntl-2col` stehen. Verwende `header` nicht, um eine normale Überschrift lediglich als linke oder rechte Spalte zu positionieren. Ordne eine solche Überschrift `aside` zu und ändere ihre visuelle Position mit `.reverse` oder `.reverse-desktop`.
49
+
50
+ Wenn ein Entwickler `header` oder `footer` sagt und die Ebene unklar ist, kläre, ob der äußere Bereich oder `top` beziehungsweise `bottom` im Wrapper gemeint ist.
51
+
52
+ ## Markdown-Beispiele
53
+
54
+ Für besondere Slot-Anordnungen, insbesondere `top` als Desktop-Spalte, lies [references/examples.md](references/examples.md).
55
+
56
+ Standard mit acht von zwölf Spalten für `main`:
57
+
58
+ ```markdown
59
+ ## Behandlungsschwerpunkt
60
+ {: layout="ntl-2col" section-style="--cols: 8;"}
61
+
62
+ Der Hauptinhalt bleibt in `main`.
63
+
64
+ ![Diagnostik](./diagnostik.jpg)
65
+ ```
66
+
67
+ Überschrift als linke Spalte:
68
+
69
+ ```markdown
70
+ ## Behandlungsschwerpunkt
71
+ {: layout="ntl-2col.reverse" .aside section-style="--cols: 8;"}
72
+
73
+ Der Hauptinhalt bleibt in `main`.
74
+ ```
75
+
76
+ `.reverse` stellt die Aside-Überschrift auf Desktop nach links und mobil vor den Hauptinhalt. Verwende `.reverse-desktop` nur, wenn der Aside-Inhalt mobil bewusst nach dem Hauptinhalt stehen soll.
77
+
78
+ Weitere direkte Children mit `.aside` können dieselbe Seitenspalte ergänzen. Lege dafür keine positionsspezifische `style-*`-Variante an.
79
+
80
+ ## Vertikale Ausrichtung wählen
81
+
82
+ `default-style()` zentriert auf Desktop die Inhalte von `main` und `aside`. Wähle Modifier nach dem tatsächlichen Höhenverhältnis:
83
+
84
+ | Situation | Empfehlung |
85
+ |---|---|
86
+ | Beide Spalten sind ungefähr gleich hoch | Keinen Modifier setzen; die Default-Zentrierung reicht aus. |
87
+ | Eine Spalte, häufig `aside`, ist deutlich länger | `.with-justify-top` setzt beide Inhalte an den oberen Rand und vermeidet eine große leere Fläche oberhalb des kürzeren Inhalts. |
88
+ | `aside` ist lang und der kürzere Main-Content soll beim Scrollen sichtbar bleiben | `.with-main-sticky-top` verwenden; den Viewport-Abstand über `--main-sticky-top` setzen. |
89
+ | Eine gemeinsame Unterkante ist Teil der bewussten Komposition | `.with-justify-bottom` verwenden. |
90
+
91
+ Top-Ausrichtung und Sticky können lange Zweispalten-Abschnitte optisch auflockern. Setze sie trotzdem nicht pauschal: Bei ausgeglichenen Inhalten bleibt das Layout ohne Modifier ruhiger.
92
+
93
+ Nutze immer die `trunkjs/content-pane`-Notation `{: layout="..."}`. Die Default-Style-Klasse wird automatisch ergänzt, wenn keine `style-*` Klasse gesetzt ist.
94
+
95
+ ## Relevante Konfiguration
96
+
97
+ - `--cols`: Breite von `main` im Desktop-Zwölfersystem, standardmäßig `6`; normalerweise pro Instanz über `section-style` setzen
98
+ - `--breakpoint`: Umschaltpunkt, standardmäßig `md`
99
+ - `--container-width`: Containerbreite
100
+ - `--gap`: Abstand zwischen den Spalten
101
+ - `--main-sticky-top`: Viewport-Abstand für `.with-main-sticky-top`, standardmäßig `var(--nt-spacing-layout)`
102
+ - `.surface-*`: Section-Fläche mit passenden semantischen Textfarben
103
+ - `.bg-*`: reiner Section-Background
104
+ - `.with-justify-top` / `.with-justify-center` / `.with-justify-bottom`: Inhalte beider Spalten auf Desktop oben, mittig oder unten ausrichten
105
+ - `.with-main-sticky-top`: kürzeren Main-Content auf Desktop sticky oben halten
106
+ - `.reverse`: tauscht `main` und `aside`
107
+ - `.reverse-desktop`: tauscht sie nur im Desktop-Modus
108
+ - `.breakout-start` / `.breakout-end`: aktiviert Desktop-Breakouts
@@ -0,0 +1,58 @@
1
+ # NTL 2Col Usage-Beispiele
2
+
3
+ Bereichsklassen wie `.aside` oder `.top` müssen am direkten Light-DOM-Kind von `ntl-2col` stehen.
4
+
5
+ ## Standard
6
+
7
+ ```markdown
8
+ ## Behandlungsschwerpunkt
9
+ {: layout="ntl-2col" section-style="--cols: 8;"}
10
+
11
+ Der Hauptinhalt bleibt in `main`.
12
+
13
+ ![Diagnostik](./diagnostik.jpg)
14
+ ```
15
+
16
+ ## Überschrift als linke Spalte
17
+
18
+ Bevorzugt wird die Überschrift `aside` zugeordnet. `.reverse` setzt sie im Desktop-Modus nach links und mobil vor `main`.
19
+
20
+ ```markdown
21
+ ## Behandlungsschwerpunkt
22
+ {: layout="ntl-2col.reverse" .aside section-style="--cols: 8;"}
23
+
24
+ Der Hauptinhalt bleibt in `main`.
25
+ ```
26
+
27
+ ## Ausnahme: `top` als linke Spalte
28
+
29
+ Ein leeres `aside` setzt `main` intern auf volle Breite. Die Theme-Klasse muss deshalb die betroffenen Parts im Desktop-Modus überschreiben und mobil zurücksetzen.
30
+
31
+ ```markdown
32
+ ## Behandlungsschwerpunkt
33
+ {: layout="ntl-2col.style-top-heading" .top section-style="--cols: 8;"}
34
+
35
+ Der Hauptinhalt bleibt in `main`.
36
+ ```
37
+
38
+ ```scss
39
+ ntl-2col.style-top-heading {
40
+ @include twoCol.default-style();
41
+
42
+ &[mode='desktop'] {
43
+ &::part(wrapper) { flex-direction: row; }
44
+ &::part(top) { order: 1; width: auto; flex: 1 1 0; }
45
+ &::part(main) {
46
+ order: 2;
47
+ width: calc(100% * var(--cols, 8) / 12);
48
+ flex: 0 0 calc(100% * var(--cols, 8) / 12);
49
+ }
50
+ }
51
+
52
+ &[mode='mobile'] {
53
+ &::part(wrapper) { flex-direction: column; }
54
+ &::part(top) { order: 1; width: 100%; flex: 0 0 auto; }
55
+ &::part(main) { order: 2; width: 100%; flex: 0 0 auto; }
56
+ }
57
+ }
58
+ ```
@@ -0,0 +1,132 @@
1
+ # @nextrap/ntl-2col
2
+
3
+ Responsive two-column layout web component for Nextrap content sections.
4
+
5
+ ## First reference
6
+
7
+ Before changing usage or styling, read the demo files:
8
+
9
+ - `demo/base.md` contains the declarative examples and explains what each example demonstrates.
10
+ - `demo/demo.scss` shows how semantic classes bind the exported SCSS mixins. The demo binds `default-style()` to `ntl-2col.style-default`; examples do not add a `.default` class. Demo classes starting with `style-` such as `style-testimonial` must include the complete visual baseline themselves.
11
+
12
+ Do not duplicate examples from the demo here. Keep this file focused on implementation rules and package API hints.
13
+
14
+ ## Import
15
+
16
+ ```ts
17
+ import '@nextrap/ntl-2col';
18
+ ```
19
+
20
+ For styling:
21
+
22
+ ```scss
23
+ @use '@nextrap/ntl-2col' as twoCol;
24
+ ```
25
+
26
+ ## Component behavior
27
+
28
+ - Renders `header`, `top`, `main`, `aside`, `bottom` and `footer` areas in Shadow DOM.
29
+ - `header` and `footer` are outside the `wrapper` frame; use them for headings or content that should not be inside the wrapper border.
30
+ - `top` and `bottom` are inside the `wrapper`, span 100% width when assigned, and are hidden when empty; use them for framed full-width content.
31
+ - Uses `BreakPointMixin`; the current mode is reflected as `mode="mobile"` or `mode="desktop"`.
32
+ - Uses `SubLayoutApplyMixin` queries to assign direct `.header`, `.top`, `.bottom`, `.footer`, `.aside` children and direct `p:has(img)` elements.
33
+ - Each named slot prepends an exceptional `@var(--ntl-2col-*-selector)` query. A successful variable selector overrides built-in assignments; missing, empty, or non-matching variables keep the defaults.
34
+ - Every direct `p:has(img)` child is moved into the `aside` slot and receives class `auto`; this matches the paragraph generated by a normal Markdown image.
35
+ - Nested image paragraphs and direct `<img>` children do not match the automatic query. Wrap them in a direct `.aside` child or assign the `aside` slot explicitly.
36
+ - When `default-style()` is used, a direct child with class `.aside` (not just `slot="aside"`) automatically adds inner padding to the `aside` part. Add `.p-0` to that same direct `.aside` element to suppress this padding.
37
+
38
+ Important CSS variables:
39
+
40
+ - `--breakpoint`: layout switch breakpoint, default `md`
41
+ - `--cols`: desktop main column width in a 12-column model, default `6`
42
+ - `--container-width`: container width, default `var(--nt-container-width, 100%)`
43
+ - `--gap`: gap between columns, default `var(--nt-spacing-layout)`
44
+ - `--main-sticky-top`: viewport offset for `.with-main-sticky-top`, default `var(--nt-spacing-layout)`
45
+
46
+ Exceptional selector variables: `--ntl-2col-header-selector`, `--ntl-2col-top-selector`, `--ntl-2col-aside-selector`, `--ntl-2col-bottom-selector`, and `--ntl-2col-footer-selector`. Do not use them without explicit prior approval. Prefer normal slots, modifiers, parts, and CSS layout. Values are unquoted CSS selectors, run only during the component's first update, and require `@trunkjs/content-pane` with `@var(...)` query support. Read `ntl-2col-theming` before using them.
47
+
48
+ ## CSS parts
49
+
50
+ Use these parts for external styling:
51
+
52
+ - `container`
53
+ - `header`
54
+ - `top`
55
+ - `wrapper`
56
+ - `main`
57
+ - `aside`
58
+ - `bottom`
59
+ - `footer`
60
+
61
+ ## Styling rules
62
+
63
+ - Use existing exported mixins whenever possible. Check `demo/demo.scss` before adding custom `::part(...)` styling.
64
+ - Add a new mixin only if the required visual behavior is not covered by the existing package mixins.
65
+ - Visual styling belongs in package SCSS mixins, not in Shadow DOM component CSS.
66
+ - Feature/variant mixins must not contain concrete modifier class names. The caller binds the mixin to a semantic selector.
67
+ - Feature/variant mixin names start with `with-<feature>`.
68
+ - Each public mixin lives in its own file under `src/scss/` and is exported via `index.scss`.
69
+ - Use `::part(...)` from Light DOM/demo/theme SCSS for Shadow DOM styling.
70
+ - Do not use `::part(...)` inside Shadow DOM stylesheets.
71
+ - Use `:has()` in Light DOM styling when parent state depends on assigned Light DOM children.
72
+ - `::slotted(...)` can only style the assigned node itself; do not use it to change sibling Shadow DOM layout.
73
+
74
+ ## Exported mixins
75
+
76
+ ```scss
77
+ @include twoCol.default-style(
78
+ $innerPadding: var(--nt-space-3),
79
+ $gap: var(--nt-spacing-layout),
80
+ $background: transparent,
81
+ $border: 1px solid var(--nt-dark),
82
+ $border-radius: var(--nt-border-radius),
83
+ $objectFit: cover,
84
+ $aspectRatio: none,
85
+ $modifierClasses: true,
86
+ $wrapper-bg-color: transparent,
87
+ $justify: center
88
+ );
89
+
90
+ @include twoCol.with-reverse();
91
+ @include twoCol.with-alternating();
92
+ @include twoCol.with-breakout-end();
93
+ @include twoCol.with-breakout-start();
94
+ @include twoCol.with-image-auto-objectfit($objectFit: cover);
95
+ @include twoCol.with-justify($justify: center);
96
+ @include twoCol.with-main-sticky-top($top: var(--nt-spacing-layout));
97
+ @include twoCol.with-modifier-classes();
98
+ @include twoCol.with-wrapper-bg-color($background: transparent);
99
+ @include twoCol.with-background-and-divider(
100
+ $gap: 2rem,
101
+ $background: var(--nt-primary),
102
+ $divider-color: var(--nt-light)
103
+ );
104
+ ```
105
+
106
+ `default-style()` is the default visual baseline and vertically centers the content of both columns on desktop through `$justify: center`. By default it includes `with-image-auto-objectfit()` and `with-modifier-classes()`.
107
+ Set `$objectFit: none` or `$modifierClasses: false` to disable these bundled helpers.
108
+
109
+ `default-style()` also adds `padding: var(--inner-padding)` to the `main` part. For the `aside` part, the same inner padding is only applied when the direct assigned Light DOM node uses class `.aside`. A plain `slot="aside"` alone does not trigger this automatic aside padding. Add `.p-0` to the direct `.aside` node to opt out.
110
+
111
+ ## Modifier classes
112
+
113
+ `default-style()` loads the predefined modifier classes automatically. Only include `with-modifier-classes()` manually when not using `default-style()` or when `$modifierClasses: false` is set intentionally.
114
+
115
+ Available classes:
116
+
117
+ - `.reverse` reverses only `main` and `aside`; `header`/`top` stay above and `bottom`/`footer` stay below.
118
+ - `.reverse-desktop` reverses columns only in desktop mode.
119
+ - `.breakout-start` / `.breakout-end` enable desktop breakout layouts.
120
+ - `.with-justify-top` / `.with-justify-center` / `.with-justify-bottom` align the content of both columns at the top, center or bottom on desktop.
121
+ - `.with-main-sticky-top` keeps a shorter main column sticky at the top on desktop; configure its viewport offset with `--main-sticky-top`.
122
+
123
+ For similarly tall columns, keep the default and do not add an alignment modifier. When one column—commonly `aside`—is substantially longer, use `.with-justify-top` for a shared top edge or `.with-main-sticky-top` when the shorter `main` content should remain visible while the long `aside` scrolls. Use `.with-justify-bottom` only for an intentional shared bottom edge.
124
+
125
+ Use `@nextrap/style-utils` background utilities such as `.bg-primary` or `.bg-primary-subtle` for section background colors. Use `default-style($wrapper-bg-color: ...)` or `with-wrapper-bg-color($background)` if the Shadow DOM `wrapper` part needs its own background; `default-style()` sets it to transparent by default via this mixin.
126
+
127
+ ## Shadow DOM implementation hints
128
+
129
+ - Keep Shadow DOM CSS minimal and functional only.
130
+ - Use `@nextrap/style-reset` in the component styles array.
131
+ - Do not import `@nextrap/style-base` into Shadow DOM styles; use global `--nt-*` variables from outside.
132
+ - Reuse the existing `data-query` / `SubLayoutApplyMixin` pattern for slot/content processing.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ ## 2.0.1 (2026-09-10)
2
+
3
+ ### 🚀 Features
4
+
5
+ - **ntl-2col:** allow theme-controlled slot selectors ([f585712](https://github.com/nextrap/nextrap-monorepo/commit/f585712))
6
+ - **ntl-2col:** add main positioning modifiers ([b6f35f9](https://github.com/nextrap/nextrap-monorepo/commit/b6f35f9))
7
+ - add component theme and usage skills ([617cfde](https://github.com/nextrap/nextrap-monorepo/commit/617cfde))
8
+
9
+ ### 🩹 Fixes
10
+
11
+ - declare external libraries as peers and retain test dependencies ([67c6ffa](https://github.com/nextrap/nextrap-monorepo/commit/67c6ffa))
12
+ - **ntl:** migrate ntl-2col to nt-core ([568f8b2](https://github.com/nextrap/nextrap-monorepo/commit/568f8b2))
13
+ - **layout:** keep layout packages separate ([c82b05a](https://github.com/nextrap/nextrap-monorepo/commit/c82b05a))
14
+ - use aliasesExclude to avoid internal relative paths ([6b8123e](https://github.com/nextrap/nextrap-monorepo/commit/6b8123e))
15
+
16
+ ### ❤️ Thank You
17
+
18
+ - Enzo Volkmann @evolkmann
19
+ - Matthias Leuffen
20
+
1
21
  ## 0.1.4 (2025-07-25)
2
22
 
3
23
  This was a version bump only for ntl-2col to align it with other projects, there were no code changes.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  This library was generated with [Nx](https://nx.dev).
4
4
 
5
- ## Building
5
+ ## Visual testing
6
6
 
7
7
  Run `nx build ntl-2col` to build the library.
8
8
 
package/default.scss ADDED
@@ -0,0 +1,13 @@
1
+ @use './index' as mixin;
2
+
3
+ .default {
4
+ @include mixin.default-style(var(--nt-spacing-text), var(--nt-spacing-text));
5
+ }
6
+
7
+ .reverse {
8
+ @include mixin.with-reverse;
9
+ }
10
+
11
+ .alternating {
12
+ @include mixin.with-alternating;
13
+ }
package/index.d.ts CHANGED
@@ -1 +1 @@
1
- export * from './lib/ntl-2col';
1
+ export * from './src/components/ntl-2col/ntl-2col';