nk_jtb 0.29.0 → 0.30.0

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,66 @@
1
+ # Theme and Color System Review
2
+
3
+ ## Scope Reviewed
4
+
5
+ - Application audit of the JTB color/theme subsystem.
6
+ - Covered color maps, theme partials, utility generators, component defaults, and docs.
7
+ - Source-level review only; generated CSS and browser visuals were not tested.
8
+
9
+ ## Findings
10
+
11
+ ### Medium — Runtime brand overrides do not update all brand-dependent components
12
+
13
+ - **Impact:** A project that overrides `--primary` at runtime can get mixed old and new brand colors across components.
14
+ - **Evidence:** Brand defaults are defined from SCSS values in [src/maps_and_variables/_components.scss:79](src/maps_and_variables/_components.scss#L79), [src/maps_and_variables/_components.scss:86](src/maps_and_variables/_components.scss#L86), [src/maps_and_variables/_components.scss:87](src/maps_and_variables/_components.scss#L87), and [src/maps_and_variables/_components.scss:93](src/maps_and_variables/_components.scss#L93); `.navbar` emits the compiled `$navbar-bg` in [src/components/_navbar.scss:4](src/components/_navbar.scss#L4), menu hover/underline uses compiled fallbacks in [src/components/_menu.scss:28](src/components/_menu.scss#L28) and [src/components/_menu.scss:48](src/components/_menu.scss#L48), while tabs use runtime `var(--primary)` in [src/components/_tabs.scss:6](src/components/_tabs.scss#L6) and [src/components/_tabs.scss:25](src/components/_tabs.scss#L25). The docs say CSS custom properties let users swap a brand color without recompiling in [docs/variable-system.md:47](docs/variable-system.md#L47).
15
+ - **Fix:** Decide that brand colors are a runtime token family, then make brand-derived component defaults resolve through component CSS vars that default to `var(--primary)`, `var(--secondary)`, or `var(--accent)` instead of compiled `$primary` values.
16
+ - **Trade-off:** Components that rely on Sass color functions for derived values still need compile-time fallbacks or explicit runtime tokens.
17
+
18
+ ### Medium — Brand theme text contrast can go stale after runtime color changes
19
+
20
+ - **Impact:** Changing only `--primary`, `--secondary`, or `--accent` can leave stale text colors on theme classes and button states.
21
+ - **Evidence:** [src/themes/_brand.scss:21](src/themes/_brand.scss#L21) computes `--on-{name}` from the compile-time `$brand-colors`, but brand themes and outline hover states consume `var(--on-{name})` in [src/themes/_brand.scss:57](src/themes/_brand.scss#L57) and [src/themes/_brand.scss:68](src/themes/_brand.scss#L68); brand button hover/active states also consume the same token in [src/components/_button.scss:113](src/components/_button.scss#L113). [docs/variable-system.md:87](docs/variable-system.md#L87) documents this caveat, but [docs/colors-and-themes.md:386](docs/colors-and-themes.md#L386) and [docs/colors-and-themes.md:414](docs/colors-and-themes.md#L414) still describe brand themes as runtime-swappable without that qualification.
22
+ - **Fix:** Document and enforce runtime brand overrides as a full token set, or remove the implication that overriding only the base brand color is enough.
23
+ - **Trade-off:** CSS cannot reliably choose accessible `on-*` colors from arbitrary runtime colors without either explicit tokens or newer browser-dependent color logic.
24
+
25
+ ### Medium — Brand themes now bypass the normal theme builder pipeline
26
+
27
+ - **Impact:** `.primary`, `.secondary`, and `.accent` look like ordinary theme classes in the public API but are generated and maintained through different code paths.
28
+ - **Evidence:** Static hue and semantic themes use [src/themes/_color.scss:36](src/themes/_color.scss#L36), [src/themes/_color.scss:41](src/themes/_color.scss#L41), and the shared builders in [src/mixins/_themes.scss:28](src/mixins/_themes.scss#L28); brand themes are generated manually in [src/themes/_brand.scss:56](src/themes/_brand.scss#L56). Buttons repeat the same split with static themes in [src/components/_button.scss:106](src/components/_button.scss#L106) and brand themes in [src/components/_button.scss:113](src/components/_button.scss#L113). Before `81b753b`, `primary`, `secondary`, and `accent` lived in `$base-colors` and passed through the same loops as hue themes.
29
+ - **Fix:** Make one theme pipeline support both static Sass values and runtime CSS-var-backed values, then feed brand themes through that pipeline instead of hand-building them separately.
30
+ - **Trade-off:** The shared theme builders need a small extension so they can accept precomputed runtime tokens instead of only Sass color values.
31
+
32
+ ### Low — Brand colors are not first-class across all color-consuming APIs
33
+
34
+ - **Impact:** Users can reach for brand color classes in some places but not others, which makes the color system feel inconsistent.
35
+ - **Evidence:** Background, text, and border utilities are generated from static palette maps in [src/utilities/_backgrounds.scss:23](src/utilities/_backgrounds.scss#L23), [src/maps_and_variables/_typography.scss:34](src/maps_and_variables/_typography.scss#L34), and [src/utilities/_border.scss:28](src/utilities/_border.scss#L28), while brand utility generation lives separately in [src/themes/_brand.scss:78](src/themes/_brand.scss#L78). Gradient utilities generate only base and scale color stops in [src/utilities/_gradients.scss:57](src/utilities/_gradients.scss#L57), and the gradient resolver checks semantic/base colors but not brand colors in [src/mixins/_gradients.scss:12](src/mixins/_gradients.scss#L12).
36
+ - **Fix:** After the theme pipeline is unified, decide per utility domain whether brand tokens should be included.
37
+
38
+ ## Top Architectural Risks
39
+
40
+ - Brand has two meanings: compile-time SCSS defaults and runtime CSS tokens.
41
+ - Brand theme generation is separated from the normal theme builder pipeline.
42
+ - Component defaults mix `$primary` and `var(--primary)`, so runtime theming is uneven.
43
+ - Documentation promises runtime swapping more broadly than the implementation safely supports.
44
+
45
+ ## Top Refactor Priorities
46
+
47
+ - Treat brand as a runtime token family, not just three extra colors.
48
+ - Refactor theme builders so static and runtime-backed themes use the same public pipeline.
49
+ - Convert brand-derived component defaults to CSS custom properties with brand-token fallbacks.
50
+ - Tighten docs around what changes at runtime and what remains compile-time.
51
+
52
+ ## Next Sprint Action Plan
53
+
54
+ - **Action:** Define a clear brand token contract; **Why now:** removes the current compile/runtime ambiguity; **Effort:** S; **First step:** write the required token list for `primary`, `secondary`, and `accent`.
55
+ - **Action:** Unify theme generation; **Why now:** restores the pre-`81b753b` mental model where `.primary` and `.teal` are both normal themes; **Effort:** M; **First step:** extend [src/mixins/_themes.scss:28](src/mixins/_themes.scss#L28) to accept runtime-backed theme maps.
56
+ - **Action:** Convert component brand defaults to runtime component vars; **Why now:** makes brand overrides consistent across components; **Effort:** M; **First step:** start with navbar and menu because they currently compile `$primary`.
57
+ - **Action:** Update color/theme docs; **Why now:** prevents incorrect expectations about runtime swaps; **Effort:** S; **First step:** rewrite the runtime brand section in [docs/variable-system.md:75](docs/variable-system.md#L75).
58
+ - **Action:** Decide whether gradient stops should support brand; **Why now:** closes the most visible missing color API; **Effort:** S; **First step:** choose whether `from-primary` and `to-primary` should exist.
59
+
60
+ ## Maintainability Risk
61
+
62
+ Moderate. The current split is understandable, but the same brand concept is implemented through separate Sass maps, CSS vars, component variables, and docs language.
63
+
64
+ ## Cross-Boundary Coupling Risk
65
+
66
+ Moderate. Color decisions cross maps, themes, utilities, components, and documentation, so a change to brand behavior can easily miss one boundary.
@@ -0,0 +1,35 @@
1
+ # Commit Readiness Review
2
+
3
+ ## Scope Reviewed
4
+
5
+ - Review type: changed-file commit readiness review.
6
+ - Coverage: staged set, unstaged set, theme/color split, package metadata, and build validation.
7
+ - Exclusions: no full application audit; only current worktree changes were assessed.
8
+
9
+ ## Findings
10
+
11
+ ### Medium — The staged set is not safe to commit by itself
12
+
13
+ - **Impact:** A commit made from the current staged files would leave the repository internally inconsistent.
14
+ - **Evidence:** The staged `src/maps_and_variables/_colors.scss` change removes the old `$theme-colors` model, while the migration from `src/utilities/_themes.scss` to `src/themes/` is still unstaged/untracked.
15
+ - **Fix:** Either unstage the current files and regroup, or stage the full theme/color migration together.
16
+
17
+ ### Low — The package version bump should be kept out unless this is a release commit
18
+
19
+ - **Impact:** Committing `package.json` and `package-lock.json` now would mix release metadata with framework architecture changes.
20
+ - **Evidence:** Both files only change the project version from `0.28.3` to `0.29.1`.
21
+ - **Fix:** Commit the version bump separately when cutting the release.
22
+
23
+ ### Low — The staged homepage/demo change is unrelated to the theme/color migration
24
+
25
+ - **Impact:** Including `index.html` with SCSS architecture changes will make the commit harder to review and revert.
26
+ - **Evidence:** The staged diff replaces the Dusk homepage demo with a layout/sidebar test page.
27
+ - **Fix:** Commit `index.html` separately if the demo change is intentional.
28
+
29
+ ## Maintainability Risk
30
+
31
+ Moderate. The final working tree builds, but the current staging split separates dependent SCSS changes across staged, unstaged, deleted, and untracked files.
32
+
33
+ ## Cross-Boundary Coupling Risk
34
+
35
+ Moderate. Color maps, theme forwarding, utilities, docs, and generated examples are currently mixed; commit grouping needs to keep dependent SCSS files together.
@@ -383,8 +383,8 @@ All JTB theme classes are context-aware. Apply the same class to a button, box,
383
383
  ## Semantic & Brand Themes
384
384
 
385
385
  Beyond hue themes, JTB provides semantic themes for communicating intent and
386
- brand themes (`primary`, `secondary`, `accent`) that are runtime-swappable via
387
- CSS custom properties.
386
+ brand themes (`primary`, `secondary`, `accent`) for project identity. Brand
387
+ themes are generated from the same Sass color maps as hue and semantic themes.
388
388
 
389
389
  <div class="grid cols-8 gap-025">
390
390
  <div class="primary rounded-05 h-4 flex-centered font-mono">primary</div>
@@ -411,9 +411,8 @@ border and text, filling on hover.
411
411
 
412
412
  ## Customizing
413
413
 
414
- Brand themes (`primary`, `secondary`, `accent`) are overridable at runtime via
415
- CSS custom properties. See [Customizing Themes](/docs/jtb/customizing-themes)
416
- for the full reference.
414
+ Override brand colors with Sass variables before the build. See
415
+ [Variable System](/docs/jtb/variable-system) for the full reference.
417
416
 
418
417
  ## Examples
419
418
 
@@ -74,9 +74,9 @@ Apply theme modifiers for different colors:
74
74
  </div>
75
75
  ```
76
76
 
77
- `primary`, `secondary`, and `accent` follow the runtime semantic theme tokens
78
- documented in [/docs/jtb/variable-system](/docs/jtb/variable-system). Use that
79
- layer when you want to test brand variations without rebuilding the CSS.
77
+ `primary`, `secondary`, and `accent` are brand theme names generated from the
78
+ same Sass color maps as other button themes. See
79
+ [Variable System](/docs/jtb/variable-system).
80
80
 
81
81
  ## Button Sizes (review)
82
82
 
@@ -1,10 +1,12 @@
1
1
  # Menu (review)
2
2
 
3
- <p class="lead">The <code>.menu</code> class creates vertical navigation lists with automatic styling for links, buttons, icons, and states. No item classes required, just add links to the list.</p>
3
+ The `.menu` class creates vertical navigation lists with automatic styling for
4
+ links, buttons, icons, and states. No item classes required — just add links to
5
+ the list.
4
6
 
5
7
  ## Structure (review)
6
8
 
7
- Apply `.menu` to a `<ul>` element. The `<nav>` is just a container, the menu
9
+ Apply `.menu` to a `<ul>` element. The `<nav>` is just a container; the menu
8
10
  itself is the list.
9
11
 
10
12
  ```html +code
@@ -15,15 +17,10 @@ itself is the list.
15
17
  </nav>
16
18
  ```
17
19
 
18
- > **This structure is important:** Keeping the container (`<nav>`) separate from
19
- > the component (`<ul class="menu">`) gives you flexibility to switch between
20
- > vertical and horizontal layouts, nest menus, and use the menu component
21
- > anywhere—sidebars, dropdowns, or navbars.
22
-
23
20
  ## Basic Usage (review)
24
21
 
25
- ```html +demo-folded
26
- <nav class="bx">
22
+ ```html +demo-folded class="bx example-jtb"
23
+ <nav>
27
24
  <ul class="menu">
28
25
  <li>
29
26
  <a href="#"> <svg class="svg-icon-pink"></svg> Item </a>
@@ -54,11 +51,11 @@ itself is the list.
54
51
 
55
52
  ### Adding Icons (review)
56
53
 
57
- Icons work automatically, just add them inside links or buttons. Spacing and
54
+ Icons work automatically just add them inside links or buttons. Spacing and
58
55
  alignment are handled by the `.menu` class.
59
56
 
60
- ```html +demo-folded class="bx"
61
- <nav class="bg-white">
57
+ ```html +demo-folded class="bx example-jtb"
58
+ <nav>
62
59
  <ul class="menu">
63
60
  <li>
64
61
  <a href="#">
@@ -72,9 +69,10 @@ alignment are handled by the `.menu` class.
72
69
 
73
70
  ### Section titles (`.menu-title`) (review)
74
71
 
75
- Use `.menu-title` for non-clickable labels that group menu items (e.g. “Account”, “Settings”). Place it inside the same `<ul class="menu">` as a sibling to `<li>` elements.
72
+ Use `.menu-title` for non-clickable labels that group menu items. Place it
73
+ inside the same `<ul class="menu">` as a sibling to `<li>` elements.
76
74
 
77
- ```html
75
+ ```html +code
78
76
  <ul class="menu">
79
77
  <li class="menu-title">Section</li>
80
78
  <li><a href="#">Item</a></li>
@@ -83,19 +81,31 @@ Use `.menu-title` for non-clickable labels that group menu items (e.g. “Accoun
83
81
 
84
82
  ### Underline variant (`.link-underline`) (review)
85
83
 
86
- Add `.link-underline` to the menu element to replace the hover background with a sliding left-to-right underline on links and buttons. Use with `.menu`: e.g. `<ul class="menu link-underline">`.
84
+ Add `.link-underline` to the menu element to replace the hover background with
85
+ a sliding left-to-right underline on links and buttons.
86
+
87
+ ```html +code
88
+ <ul class="menu link-underline">
89
+ <li><a href="#">Item</a></li>
90
+ </ul>
91
+ ```
87
92
 
88
- ### Chevron rotation (`.chevron` / `.chevron.open`) (review)
93
+ ### Chevron rotation (`.chevron`) (review)
89
94
 
90
- For parent items that expand/collapse, add `.chevron` to the icon (e.g. the caret SVG). Toggle the `.open` class when the submenu is open so the chevron rotates 180°.
95
+ Add `.chevron` to a toggle icon. Toggle `.open` on it when the submenu is open
96
+ to rotate the icon 180°.
97
+
98
+ ```html +code
99
+ <svg class="chevron" :class="{ open: open }">...</svg>
100
+ ```
91
101
 
92
102
  ### Parent Items (review)
93
103
 
94
- Parent items use buttons to toggle child menus. Works for nested navigation or
95
- dropdowns. Uses Alpine.js for toggle behavior.
104
+ Parent items use buttons to toggle child menus. Uses Alpine.js for toggle
105
+ behaviour.
96
106
 
97
- ```html +demo-folded class="bx"
98
- <nav class="bg-white">
107
+ ```html +demo-folded class="bx example-jtb"
108
+ <nav>
99
109
  <ul class="menu">
100
110
  <li class="relative" x-data="{ open: false }" x-on:click.outside="open = false" x-on:keydown.escape="open = false">
101
111
  <button x-on:click="open = ! open">
@@ -123,10 +133,23 @@ dropdowns. Uses Alpine.js for toggle behavior.
123
133
  </nav>
124
134
  ```
125
135
 
136
+ ## SCSS Variables (review)
137
+
138
+ | Variable | Default | Description |
139
+ | ----------------------------- | ------------------------------------------ | ---------------------------- |
140
+ | `$menu-padding-x` | `0.75rem` | Horizontal item padding |
141
+ | `$menu-padding-y` | `0.5rem` | Vertical item padding |
142
+ | `$menu-icon-size` | `1.25rem` | Icon width and height |
143
+ | `$menu-hover-bg` | `gray-100` | Item hover background |
144
+ | `$menu-link-hover-color` | `$primary` | Item hover and active colour |
145
+ | `$menu-link-underline-color` | `$primary` | Underline variant colour |
146
+
147
+ See [Variable System](/docs/jtb/variable-system) for override instructions.
148
+
126
149
  ## Utility Examples (review)
127
150
 
128
- ```html +demo-folded
129
- <nav class="bx">
151
+ ```html +demo-folded class="bx example-utils"
152
+ <nav>
130
153
  <ul class="txt-sm">
131
154
  <li>
132
155
  <a href="#" class="flex items-center gap-075 px-075 py-05 rounded-lg txt-gray-600 hover:bg-gray-100">
@@ -162,4 +185,3 @@ dropdowns. Uses Alpine.js for toggle behavior.
162
185
  </ul>
163
186
  </nav>
164
187
  ```
165
-
@@ -1,10 +1,77 @@
1
1
  # JTB UI Showcase
2
2
 
3
+ ## Boxes
4
+
5
+ ```html +demo-folded
6
+ <div class="bx relative overflow-hidden max-w-384px" style="background-color: var(--brand-primary-surface); border-color: var(--brand-primary-surface-border);">
7
+ <svg class="absolute -top-1.5 -right-1.5 opacity-10" width="120" height="120" viewBox="0 0 120 120" style="color: var(--brand-primary)">
8
+ <circle cx="60" cy="60" r="50" fill="currentColor"/>
9
+ <circle cx="60" cy="60" r="35" fill="none" stroke="currentColor" stroke-width="2"/>
10
+ <circle cx="60" cy="60" r="20" fill="none" stroke="currentColor" stroke-width="2"/>
11
+ </svg>
12
+ <svg class="absolute -bottom-1 -left-1 opacity-10" width="80" height="80" viewBox="0 0 80 80" style="color: var(--brand-primary)">
13
+ <circle cx="40" cy="40" r="35" fill="currentColor"/>
14
+ </svg>
15
+ <p class="txt-xs font-medium uppercase tracking-widest opacity-70" style="color: var(--brand-primary)">Also available as</p>
16
+ <p class="font-serif txt-base font-medium" style="color: var(--brand-primary-on-surface)">Part of a program</p>
17
+ <p class="txt-sm" style="color: var(--brand-primary-on-surface)">Save with a bundle discount when you enrol in the full program.</p>
18
+ <a href="#" class="txt-sm font-medium inline-flex items-center gap-025" style="color: var(--brand-primary)">View program →</a>
19
+ </div>
20
+ ```
21
+
22
+ ## Brand colour + corner shapes
23
+
24
+ ```html +demo-folded
25
+ <div class="bx primary relative overflow-hidden max-w-384px">
26
+ <svg class="absolute -top-1.5 -right-1.5 opacity-10" width="100" height="100" viewBox="0 0 100 100">
27
+ <rect x="10" y="10" width="80" height="80" rx="8" fill="white"/>
28
+ <rect x="25" y="25" width="50" height="50" rx="4" fill="none" stroke="white" stroke-width="2"/>
29
+ </svg>
30
+ <svg class="absolute -bottom-1.5 -left-1.5 opacity-10" width="90" height="90" viewBox="0 0 90 90">
31
+ <circle cx="45" cy="45" r="40" fill="white"/>
32
+ <circle cx="45" cy="45" r="25" fill="none" stroke="white" stroke-width="2"/>
33
+ </svg>
34
+ <p class="txt-xs font-medium uppercase tracking-widest txt-rose-200 opacity-80">Also available as</p>
35
+ <p class="font-serif txt-base font-medium">Part of a program</p>
36
+ <p class="txt-sm txt-rose-200 opacity-90">Save with a bundle discount when you enrol in the full program.</p>
37
+ <a href="#" class="txt-sm font-medium inline-flex items-center gap-025">View program →</a>
38
+ </div>
39
+ ```
40
+
41
+ ## left border accent
42
+
43
+ ```html +demo-folded
44
+ <div class="bx relative overflow-hidden max-w-384px bdr-l-3 bdr-l-primary">
45
+ <p class="txt-xs font-medium uppercase tracking-widest opacity-70" style="color: var(--primary)">Also available as</p>
46
+ <p class="font-serif txt-base font-medium">Part of a program</p>
47
+ <p class="txt-sm txt-muted">Save with a bundle discount when you enrol in the full program.</p>
48
+ <a href="#" class="txt-sm font-medium inline-flex items-center gap-025" style="color: var(--primary)">View program →</a>
49
+ </div>
50
+ ```
51
+
52
+ ## diagonal shape bleed
53
+
54
+ ```html +demo-folded
55
+ <div class="bx relative overflow-hidden max-w-384px" style="background-color: var(--brand-primary-surface); border-color: var(--brand-primary-surface-border);">
56
+ <svg class="absolute top-0 right-0" width="120" height="120" viewBox="0 0 120 120" style="color: var(--brand-primary)">
57
+ <polygon points="120,0 120,120 0,0" fill="currentColor" opacity="0.08"/>
58
+ <polygon points="120,0 120,80 40,0" fill="currentColor" opacity="0.08"/>
59
+ </svg>
60
+ <svg class="absolute bottom-0 left-0" width="70" height="70" viewBox="0 0 70 70" style="color: var(--brand-primary)">
61
+ <polygon points="0,70 70,70 0,0" fill="currentColor" opacity="0.06"/>
62
+ </svg>
63
+ <p class="txt-xs font-medium uppercase tracking-widest opacity-70" style="color: var(--brand-primary)">Also available as</p>
64
+ <p class="font-serif txt-base font-medium" style="color: var(--brand-primary-on-surface)">Part of a program</p>
65
+ <p class="txt-sm" style="color: var(--brand-primary-on-surface)">Save with a bundle discount when you enrol in the full program.</p>
66
+ <a href="#" class="txt-sm font-medium inline-flex items-center gap-025" style="color: var(--brand-primary)">View program →</a>
67
+ </div>
68
+ ```
69
+
3
70
  ## Lists
4
71
 
5
72
  ### Checklist
6
73
 
7
- ```html +demo-folded class="bx" class="bx"
74
+ ```html +demo-folded class="bx"
8
75
  <ul class="checklist">
9
76
  <li>12 months access from enrolment</li>
10
77
  <li>Downloadable resources included</li>
@@ -82,7 +149,7 @@
82
149
 
83
150
  ### Checklist (utility)
84
151
 
85
- ```html +demo-folded class="bx" class="bx"
152
+ ```html +demo-folded class="bx"
86
153
  <ul class="space-y-05 txt-sm">
87
154
  <li class="flex gap-05">
88
155
  <svg class="wh-1.25 rounded-full bg-orange-100 txt-primary pxy-025" fill="none" viewBox="0 0 10 8" stroke="currentColor" stroke-width="1.5">
@@ -287,6 +287,12 @@ Files parked in `docs/review/` — purpose or audience unclear.
287
287
  | `api/make-themes.md` | audit | |
288
288
  | `api/variables.md` | ✅ | |
289
289
 
290
+ ### Layouts
291
+
292
+ | File | Status | Notes |
293
+ | ------------------------------------- | ------- | -------------------------------------------------- |
294
+ | `layouts/layout-sidebar-main.md` | partial | Base structure and independent scrolling confirmed |
295
+
290
296
  ### Components
291
297
 
292
298
  | File | Status | Notes |
@@ -0,0 +1,84 @@
1
+ # Sidebar + Main Layout (review)
2
+
3
+ A two-column layout with a persistent sidebar and a main content area. Start with the base structure and layer characteristics on top as needed.
4
+
5
+ ## Base Structure
6
+
7
+ A minimal shell: fixed-width sidebar, flex-fill main area.
8
+
9
+ - `fs-0` prevents the sidebar from shrinking
10
+ - `flex-1` on main fills the remaining space
11
+
12
+ ```html +demo-folded class="resizable-container with-docs-only-overrides"
13
+ <div class="flex min-h-screen">
14
+ <aside class="w-16 fs-0 flex-col bg-slate-900">
15
+ </aside>
16
+
17
+ <main class="flex-1 bg-gray-200">
18
+ </main>
19
+ </div>
20
+ ```
21
+
22
+ ## Characteristics (review)
23
+
24
+ ### Independent Scrolling
25
+
26
+ Each region scrolls independently within its own bounds. The outer container needs a fixed height — not a min-height — so both regions know where they end. The specific height depends on context (`h-screen` for a full app shell, `h-full` inside another container).
27
+
28
+ - Add `overflow-hidden` to the outer container and use a fixed height, not `min-h-screen`
29
+ - Add `overflow-y-auto` to the sidebar
30
+ - Add `overflow-y-auto` to main
31
+
32
+ ```html +demo-folded class="resizable-container with-docs-only-overrides"
33
+ <div class="flex h-20 overflow-hidden">
34
+ <aside class="w-16 fs-0 flex-col bg-slate-900 overflow-y-auto">
35
+ <div class="pxy-075 space-y">
36
+ <div class="h-6 bg-slate-700 rounded"></div>
37
+ <div class="h-12 bg-slate-700 rounded"></div>
38
+ </div>
39
+ </aside>
40
+
41
+ <main class="flex-1 bg-gray-200 overflow-y-auto">
42
+ <div class="container-md py space-y">
43
+ <div class="bx h-8"></div>
44
+ <div class="bx h-10"></div>
45
+ </div>
46
+ </main>
47
+ </div>
48
+ ```
49
+
50
+ ### Sticky Sidebar Header and Footer (review)
51
+
52
+ When the sidebar needs a persistent header or footer, `overflow-y-auto` moves from the `aside` to an inner content region. The aside itself becomes the fixed frame; only the content between the header and footer scrolls.
53
+
54
+ - Remove `overflow-y-auto` from the `aside`
55
+ - Add a `<header>` and `<footer>` as direct children of the `aside`
56
+ - Wrap the scrollable content in a `div` with `flex-1 overflow-y-auto`
57
+
58
+ ```html +demo-folded class="resizable-container with-docs-only-overrides"
59
+ <div class="flex h-20 overflow-hidden">
60
+ <aside class="w-16 fs-0 flex-col bg-slate-900">
61
+ <header class="pxy-075 bdr-b bdr-slate-700">
62
+ <div class="h-2 bg-slate-600 rounded"></div>
63
+ </header>
64
+
65
+ <div class="flex-1 overflow-y-auto pxy-075 space-y">
66
+ <div class="h-6 bg-slate-700 rounded"></div>
67
+ <div class="h-12 bg-slate-700 rounded"></div>
68
+ <div class="h-6 bg-slate-700 rounded"></div>
69
+ <div class="h-6 bg-slate-700 rounded"></div>
70
+ </div>
71
+
72
+ <footer class="pxy-075 bdr-t bdr-slate-700">
73
+ <div class="h-2 bg-slate-600 rounded"></div>
74
+ </footer>
75
+ </aside>
76
+
77
+ <main class="flex-1 bg-gray-200 overflow-y-auto">
78
+ <div class="container-md py space-y">
79
+ <div class="bx h-8"></div>
80
+ <div class="bx h-10"></div>
81
+ </div>
82
+ </main>
83
+ </div>
84
+ ```
@@ -1,92 +1,45 @@
1
- # JTB Layouts and Structures
2
-
3
- <p class="lead">Named layout patterns for page-level structure, with a clear distinction between layouts and reusable internal structures.</p>
4
-
5
- > Example previews may use docs-only wrapper overrides so they display cleanly
6
- > inside the documentation. The example code itself remains the correct
7
- > implementation to copy and use.
8
-
1
+ # Layouts and Structures
2
+
3
+ Named patterns for page-level structure. Layouts describe the overall shape of a page or major region. Structures are reusable internal arrangements that can appear inside any layout.
4
+
9
5
  ## Layouts
10
6
 
11
7
  Layouts describe the overall shape of a page or major page region.
12
8
 
13
9
  ### Defaults
14
10
 
15
- - use `container` for standard page sections
16
- - let the section or component own its internal padding
17
- - use `py-4-3-2` as a standard section rhythm
18
- - use `py-5-3-2` for more prominent sections
19
-
20
- ### Sidebar + Main
21
-
22
- A layout with a persistent sidebar for navigation and a main area for the
23
- primary workspace. The sidebar width is deliberate and usually stays consistent.
24
-
25
- Typical use cases:
26
-
27
- - admin dashboards
28
- - account areas
29
-
30
- #### Flexbox Example (preferred)
31
-
32
- Typical implementation:
33
-
34
- - `flex` container
35
- - fixed-width sidebar using width utilities
36
- - `flex-1` main area
37
-
38
- ```html +demo-folded class="resizable-container with-docs-only-overrides"
39
- <div class="flex min-h-screen">
40
- <!-- Sidebar -->
41
- <aside class="w-16 fs-0 to-md:hidden flex-col bg-slate-900 ">
42
- <header class="pxy-075 bdr-b bdr-gray-200">
43
- <div class="h-2 bg-slate-700 rounded"></div>
44
- </header>
45
-
46
- <div class="flex-1 pxy-075 space-y">
47
- <div class="h-full bg-slate-700 rounded"></div>
48
- </div>
49
-
50
- <footer class="pxy-075 bdr-t bdr-gray-200">
51
- <div class="h-2 bg-slate-700 rounded"></div>
52
- </footer>
53
- </aside>
54
-
55
- <!-- Main Content Area -->
56
- <main class="flex-1 bg-gray-200">
57
- <div class="container-md py">
58
- <div class="bx h-4"></div>
59
- <div class="bx h-14"></div>
60
- </div>
61
- </main>
62
- </div>
63
- ```
64
-
65
- ## Structures
66
-
67
- Structures are reusable internal arrangements that can appear inside different
68
- layouts.
69
-
70
- Common use cases:
71
-
72
- - layouts with a dominant content region and a smaller supporting panel
73
- - pages that pair primary content with summary, context, or actions
74
- - sections that need a proportional split without equal visual weight
75
-
76
- ### thirds-2-1
77
-
78
- A proportional structure with a larger primary region and a smaller supporting
79
- region in a two-thirds / one-third split.
80
-
81
- ```html +demo-folded class="resizable-container with-docs-only-overrides"
82
- <div class="grid gap lg:cols-3">
83
- <div class="lg:col-span-2 space-y">
84
- <div class="bx h-6"></div>
85
- <div class="bx h-10"></div>
86
- </div>
87
-
88
- <aside class="lg:col-span-1">
89
- <div class="bx h-12"></div>
90
- </aside>
91
- </div>
92
- ```
11
+ - Use `container` for standard page sections
12
+ - Let the section or component own its internal padding
13
+ - Use `py-4-3-2` as a standard section rhythm
14
+ - Use `py-5-3-2` for more prominent sections
15
+
16
+ ### Individual Layout Docs
17
+
18
+ - [Sidebar + Main](/docs/jtb/layouts/layout-sidebar-main)
19
+
20
+ ## Structures
21
+
22
+ Structures are reusable internal arrangements that can appear inside different layouts.
23
+
24
+ Common use cases:
25
+
26
+ - layouts with a dominant content region and a smaller supporting panel
27
+ - pages that pair primary content with summary, context, or actions
28
+ - sections that need a proportional split without equal visual weight
29
+
30
+ ### thirds-2-1
31
+
32
+ A proportional structure with a larger primary region and a smaller supporting region in a two-thirds / one-third split.
33
+
34
+ ```html +demo-folded class="resizable-container with-docs-only-overrides"
35
+ <div class="grid gap lg:cols-3">
36
+ <div class="lg:col-span-2 space-y">
37
+ <div class="bx h-6"></div>
38
+ <div class="bx h-10"></div>
39
+ </div>
40
+
41
+ <aside class="lg:col-span-1">
42
+ <div class="bx h-12"></div>
43
+ </aside>
44
+ </div>
45
+ ```