@ibis-design/css 0.9.0 → 1.0.0-alpha.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.
package/README.md CHANGED
@@ -442,6 +442,30 @@ Dark-mode utilities respond to `[data-color-mode="dark"]`. Set `data-brand` and
442
442
 
443
443
  ---
444
444
 
445
+ ## Bootstrap 5.3 CSS variables
446
+
447
+ Map IBIS semantic tokens onto Bootstrap's `--bs-*` custom properties for apps that use [Bootstrap 5.3](https://getbootstrap.com/docs/5.3/customize/css-variables/):
448
+
449
+ ```html
450
+ <link href="bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" />
451
+ <link rel="stylesheet" href="/path/to/app.css" />
452
+ ```
453
+
454
+ ```css
455
+ @import "@ibis-design/css";
456
+ @import "@ibis-design/css/bootstrap-overrides.css";
457
+ ```
458
+
459
+ `bootstrap-overrides.css` sets `--bs-primary`, `--bs-body-bg`, `--bs-body-color`, and related vars from IBIS semantic tokens under each `[data-brand][data-color-mode]` selector.
460
+
461
+ For Bootstrap's native dark mode, pass `syncBootstrapTheme: true` to `setTheme()` so `data-bs-theme` stays in sync with `data-color-mode`:
462
+
463
+ ```ts
464
+ setTheme({ brand: "ib", colorMode: "dark", syncBootstrapTheme: true });
465
+ ```
466
+
467
+ ---
468
+
445
469
  ## Fonts
446
470
 
447
471
  Font stacks in tokens (Inter, Metrisch, Beyond Infinity, etc.) are **not** included. Load matching fonts in your app.
@@ -455,5 +479,6 @@ Font stacks in tokens (Inter, Metrisch, Beyond Infinity, etc.) are **not** inclu
455
479
  | `@ibis-design/css` | Full token stylesheet |
456
480
  | `@ibis-design/css/components/<name>.css` | Component presentation |
457
481
  | `@ibis-design/css/tailwind.preset` | Tailwind preset |
482
+ | `@ibis-design/css/bootstrap-overrides.css` | Bootstrap 5.3 `--bs-*` overrides |
458
483
 
459
484
  Legacy aliases `@ibis-design/css/ibis-design.css` and `@ibis-design/css/alchemy-design.css` point at the same token bundle—use `data-brand` and `data-color-mode` instead.
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Do not edit directly. Generated by @ibis-design/css build.
3
+ * Load after Bootstrap CSS and @ibis-design/css design tokens.
4
+ * IBIS theme selectors set --bs-* vars from semantic --color-* / --font-* tokens.
5
+ */
6
+
7
+ :root, [data-brand="ib"][data-color-mode="light"] {
8
+ --bs-primary: var(--color-brand-primary);
9
+ --bs-secondary: var(--color-brand-secondary);
10
+ --bs-success: var(--color-status-success);
11
+ --bs-danger: var(--color-status-error);
12
+ --bs-warning: var(--color-status-warning);
13
+ --bs-body-color: var(--color-text-primary);
14
+ --bs-secondary-color: var(--color-text-secondary);
15
+ --bs-body-bg: var(--color-surface-page);
16
+ --bs-secondary-bg: var(--color-surface-muted);
17
+ --bs-tertiary-bg: var(--color-surface-subtle);
18
+ --bs-link-color: var(--color-interactive-primary-fg);
19
+ --bs-link-hover-color: var(--color-interactive-primary-bg-emphasized);
20
+ --bs-border-color: var(--border-color-default);
21
+ --bs-border-radius: var(--border-radius-md);
22
+ --bs-font-sans-serif: var(--font-family-sans);
23
+ --bs-body-font-size: var(--font-size-body-md);
24
+ }
25
+
26
+ [data-brand="ib"][data-color-mode="dark"] {
27
+ --bs-primary: var(--color-brand-primary);
28
+ --bs-secondary: var(--color-brand-secondary);
29
+ --bs-success: var(--color-status-success);
30
+ --bs-danger: var(--color-status-error);
31
+ --bs-warning: var(--color-status-warning);
32
+ --bs-body-color: var(--color-text-primary);
33
+ --bs-secondary-color: var(--color-text-secondary);
34
+ --bs-body-bg: var(--color-surface-page);
35
+ --bs-secondary-bg: var(--color-surface-muted);
36
+ --bs-tertiary-bg: var(--color-surface-subtle);
37
+ --bs-link-color: var(--color-interactive-primary-fg);
38
+ --bs-link-hover-color: var(--color-interactive-primary-bg-emphasized);
39
+ --bs-border-color: var(--border-color-default);
40
+ --bs-border-radius: var(--border-radius-md);
41
+ --bs-font-sans-serif: var(--font-family-sans);
42
+ --bs-body-font-size: var(--font-size-body-md);
43
+ }
44
+
45
+ [data-brand="alc"][data-color-mode="light"] {
46
+ --bs-primary: var(--color-brand-primary);
47
+ --bs-secondary: var(--color-brand-secondary);
48
+ --bs-success: var(--color-status-success);
49
+ --bs-danger: var(--color-status-error);
50
+ --bs-warning: var(--color-status-warning);
51
+ --bs-body-color: var(--color-text-primary);
52
+ --bs-secondary-color: var(--color-text-secondary);
53
+ --bs-body-bg: var(--color-surface-page);
54
+ --bs-secondary-bg: var(--color-surface-muted);
55
+ --bs-tertiary-bg: var(--color-surface-subtle);
56
+ --bs-link-color: var(--color-interactive-primary-fg);
57
+ --bs-link-hover-color: var(--color-interactive-primary-bg-emphasized);
58
+ --bs-border-color: var(--border-color-default);
59
+ --bs-border-radius: var(--border-radius-md);
60
+ --bs-font-sans-serif: var(--font-family-sans);
61
+ --bs-body-font-size: var(--font-size-body-md);
62
+ }
63
+
64
+ [data-brand="alc"][data-color-mode="dark"] {
65
+ --bs-primary: var(--color-brand-primary);
66
+ --bs-secondary: var(--color-brand-secondary);
67
+ --bs-success: var(--color-status-success);
68
+ --bs-danger: var(--color-status-error);
69
+ --bs-warning: var(--color-status-warning);
70
+ --bs-body-color: var(--color-text-primary);
71
+ --bs-secondary-color: var(--color-text-secondary);
72
+ --bs-body-bg: var(--color-surface-page);
73
+ --bs-secondary-bg: var(--color-surface-muted);
74
+ --bs-tertiary-bg: var(--color-surface-subtle);
75
+ --bs-link-color: var(--color-interactive-primary-fg);
76
+ --bs-link-hover-color: var(--color-interactive-primary-bg-emphasized);
77
+ --bs-border-color: var(--border-color-default);
78
+ --bs-border-radius: var(--border-radius-md);
79
+ --bs-font-sans-serif: var(--font-family-sans);
80
+ --bs-body-font-size: var(--font-size-body-md);
81
+ }
@@ -0,0 +1,124 @@
1
+ /* Auth Layout — import via @ibis-design/css/components/authLayout.css */
2
+
3
+ .ib-auth-layout {
4
+ display: flex;
5
+ flex-direction: row;
6
+ height: 100dvh;
7
+ width: 100%;
8
+ background-color: var(--color-surface-muted);
9
+ overflow: hidden;
10
+ }
11
+
12
+ /* Left panel */
13
+ .ib-auth-layout__left {
14
+ display: flex;
15
+ flex-direction: column;
16
+ flex: 0 0 50%;
17
+ padding: var(--spacing-6);
18
+ position: relative;
19
+ box-sizing: border-box;
20
+ }
21
+
22
+ .ib-auth-layout__logo {
23
+ display: flex;
24
+ align-items: flex-start;
25
+ justify-content: flex-start;
26
+ flex-shrink: 0;
27
+ }
28
+
29
+ .ib-auth-layout__logo-placeholder {
30
+ width: 48px;
31
+ height: 48px;
32
+ border-radius: var(--border-radius-full);
33
+ background: var(--gradient-brand-primary);
34
+ display: flex;
35
+ align-items: center;
36
+ justify-content: center;
37
+ color: var(--color-text-inverse);
38
+ font-family: var(--font-family-heading);
39
+ font-weight: var(--font-weight-bold);
40
+ font-size: var(--font-size-body-lg);
41
+ }
42
+
43
+ .ib-auth-layout-logo-image {
44
+ height: 48px;
45
+ width: auto;
46
+ object-fit: contain;
47
+ }
48
+
49
+ .ib-auth-layout__content {
50
+ display: flex;
51
+ flex-direction: column;
52
+ gap: var(--spacing-6);
53
+ flex: 1;
54
+ justify-content: center;
55
+ padding: 0 var(--spacing-12);
56
+ box-sizing: border-box;
57
+ }
58
+
59
+ .ib-auth-layout__heading {
60
+ display: flex;
61
+ flex-direction: column;
62
+ gap: var(--spacing-2);
63
+ }
64
+
65
+ .ib-auth-layout__title {
66
+ font-family: var(--font-family-heading);
67
+ font-size: var(--font-size-heading-h2);
68
+ font-weight: var(--font-weight-bold);
69
+ color: var(--color-text-primary);
70
+ margin: 0;
71
+ }
72
+
73
+ .ib-auth-layout__subtitle {
74
+ font-family: var(--font-family-sans);
75
+ font-size: var(--font-size-body-md);
76
+ color: var(--color-text-secondary);
77
+ margin: 0;
78
+ }
79
+
80
+ .ib-auth-layout__form {
81
+ display: flex;
82
+ flex-direction: column;
83
+ gap: var(--spacing-4);
84
+ align-items: center;
85
+ }
86
+
87
+ .ib-auth-layout__copyright {
88
+ font-family: var(--font-family-sans);
89
+ font-size: var(--font-size-body-sm);
90
+ color: var(--color-text-muted);
91
+ flex-shrink: 0;
92
+ }
93
+
94
+ /* Right panel */
95
+ .ib-auth-layout__right {
96
+ flex: 0 0 50%;
97
+ padding: var(--spacing-4);
98
+ box-sizing: border-box;
99
+ display: flex;
100
+ align-items: stretch;
101
+ }
102
+
103
+ .ib-auth-layout__image-placeholder {
104
+ width: 100%;
105
+ border-radius: var(--border-radius-2xl);
106
+ border: var(--border-width-thin) solid var(--border-color-default);
107
+ overflow: hidden;
108
+ display: flex;
109
+ align-items: stretch;
110
+ background-color: var(--color-surface-default);
111
+ }
112
+
113
+ .ib-auth-layout__image-placeholder svg {
114
+ width: 100%;
115
+ height: 100%;
116
+ }
117
+
118
+ .ib-auth-layout__image {
119
+ width: 100%;
120
+ height: 100%;
121
+ object-fit: cover;
122
+ border-radius: var(--border-radius-2xl);
123
+ display: block;
124
+ }
@@ -0,0 +1,86 @@
1
+ /* Card component — import via @ibis-design/css/components/card.css */
2
+
3
+ .ibis-card {
4
+ display: flex;
5
+ flex-direction: column;
6
+ background-color: var(--color-surface-default);
7
+ border: var(--border-width-thin) solid var(--border-color-subtle);
8
+ border-radius: var(--border-radius-lg);
9
+ box-shadow: var(--shadow-elevation-sm);
10
+ overflow: visible;
11
+ box-sizing: border-box;
12
+ min-height: 200px;
13
+ }
14
+
15
+ .ibis-card__header {
16
+ display: flex;
17
+ flex-direction: column;
18
+ gap: var(--spacing-1);
19
+ padding: var(--spacing-4) var(--spacing-4) 0;
20
+ }
21
+
22
+ .ibis-card__title {
23
+ font-family: var(--font-family-heading);
24
+ font-size: var(--font-size-heading-h5);
25
+ font-weight: var(--font-weight-semibold);
26
+ color: var(--color-text-primary);
27
+ margin: 0;
28
+ }
29
+
30
+ .ibis-card__subtitle {
31
+ font-family: var(--font-family-sans);
32
+ font-size: var(--font-size-body-sm);
33
+ color: var(--color-text-muted);
34
+ margin: 0;
35
+ }
36
+
37
+ .ibis-card__body {
38
+ flex: 1;
39
+ padding: var(--spacing-4);
40
+ font-family: var(--font-family-sans);
41
+ font-size: var(--font-size-body-md);
42
+ color: var(--color-text-primary);
43
+ line-height: var(--line-height-normal);
44
+ }
45
+
46
+ .ibis-card__footer {
47
+ display: flex;
48
+ flex-direction: row;
49
+ align-items: center;
50
+ justify-content: flex-end;
51
+ gap: var(--spacing-2);
52
+ padding: 0 var(--spacing-4) var(--spacing-4);
53
+ border-top: var(--border-width-thin) solid var(--border-color-subtle);
54
+ padding-top: var(--spacing-3);
55
+ margin-top: var(--spacing-2);
56
+ }
57
+
58
+ /* ===== SIZE VARIANTS ===== */
59
+
60
+ .ibis-card--sm {
61
+ min-height: 120px;
62
+ }
63
+
64
+ .ibis-card--md {
65
+ min-height: 200px;
66
+ }
67
+
68
+ .ibis-card--md-wide {
69
+ min-height: 200px;
70
+ }
71
+
72
+ .ibis-card--lg {
73
+ min-height: 320px;
74
+ }
75
+
76
+ .ibis-card--lg-wide {
77
+ min-height: 320px;
78
+ }
79
+
80
+ .ibis-card--ex-wide {
81
+ min-height: 200px;
82
+ }
83
+
84
+ .ibis-card--full {
85
+ min-height: 400px;
86
+ }
@@ -0,0 +1,93 @@
1
+ /* Card Layout — import via @ibis-design/css/components/cardLayout.css */
2
+
3
+ .ibis-card-layout {
4
+ display: flex;
5
+ flex-direction: column;
6
+ gap: var(--spacing-4);
7
+ width: 100%;
8
+ box-sizing: border-box;
9
+ }
10
+
11
+ .ibis-card-layout__header {
12
+ display: flex;
13
+ flex-direction: row;
14
+ align-items: flex-start;
15
+ justify-content: space-between;
16
+ gap: var(--spacing-4);
17
+ }
18
+
19
+ .ibis-card-layout__header-text {
20
+ display: flex;
21
+ flex-direction: column;
22
+ gap: var(--spacing-1);
23
+ }
24
+
25
+ .ibis-card-layout__title {
26
+ font-family: var(--font-family-heading);
27
+ font-size: var(--font-size-heading-h4);
28
+ font-weight: var(--font-weight-bold);
29
+ color: var(--color-text-primary);
30
+ margin: 0;
31
+ }
32
+
33
+ .ibis-card-layout__subtitle {
34
+ font-family: var(--font-family-sans);
35
+ font-size: var(--font-size-body-sm);
36
+ color: var(--color-text-muted);
37
+ margin: 0;
38
+ }
39
+
40
+ .ibis-card-layout__header-action {
41
+ display: flex;
42
+ align-items: center;
43
+ flex-shrink: 0;
44
+ }
45
+
46
+ /* Default — 1 column (mobile) */
47
+ .ibis-card-layout__grid {
48
+ display: grid;
49
+ gap: var(--spacing-4);
50
+ grid-template-columns: 1fr;
51
+ }
52
+
53
+ /* sm (640px) — 2 columns (tablet) */
54
+ @media (min-width: 640px) {
55
+ .ibis-card-layout__grid {
56
+ grid-template-columns: repeat(2, 1fr);
57
+ }
58
+ }
59
+
60
+ /* lg (1024px) — 4 columns (desktop), card size props apply */
61
+ @media (min-width: 1024px) {
62
+ .ibis-card-layout__grid {
63
+ grid-template-columns: repeat(4, 1fr);
64
+ }
65
+
66
+ .ibis-card-layout__grid .ibis-card--sm {
67
+ grid-column: span 1;
68
+ }
69
+
70
+ .ibis-card-layout__grid .ibis-card--md {
71
+ grid-column: span 2;
72
+ }
73
+
74
+ .ibis-card-layout__grid .ibis-card--md-wide {
75
+ grid-column: span 3;
76
+ }
77
+
78
+ .ibis-card-layout__grid .ibis-card--lg {
79
+ grid-column: span 2;
80
+ }
81
+
82
+ .ibis-card-layout__grid .ibis-card--lg-wide {
83
+ grid-column: span 3;
84
+ }
85
+
86
+ .ibis-card-layout__grid .ibis-card--ex-wide {
87
+ grid-column: span 4;
88
+ }
89
+
90
+ .ibis-card-layout__grid .ibis-card--full {
91
+ grid-column: span 4;
92
+ }
93
+ }
@@ -0,0 +1,92 @@
1
+ /* Dashboard Layout — import via @ibis-design/css/components/dashboardLayout.css */
2
+
3
+ .ib-dashboard-layout {
4
+ position: relative;
5
+ display: flex;
6
+ flex-direction: row;
7
+ height: 100dvh;
8
+ width: 100%;
9
+ overflow: hidden;
10
+ background-color: var(--color-surface-muted);
11
+ }
12
+
13
+ /* Rail wrapper */
14
+ .ib-dashboard-layout__rail-wrapper {
15
+ position: fixed;
16
+ top: 0;
17
+ left: 0;
18
+ height: 100dvh;
19
+ z-index: var(--z-index-sticky);
20
+ transition: transform var(--transition-duration-slow) var(--transition-timing-in-out);
21
+ }
22
+
23
+ .ib-dashboard-layout__rail-wrapper--hidden {
24
+ transform: translateX(-100%);
25
+ }
26
+
27
+ /* Drawer wrapper */
28
+ .ib-dashboard-layout__drawer-wrapper {
29
+ position: fixed;
30
+ top: 0;
31
+ left: 0;
32
+ height: 100dvh;
33
+ z-index: var(--z-index-sticky);
34
+ transform: translateX(-100%);
35
+ transition: transform var(--transition-duration-slow) var(--transition-timing-in-out);
36
+ }
37
+
38
+ .ib-dashboard-layout__drawer-wrapper--visible {
39
+ transform: translateX(0);
40
+ }
41
+
42
+ /* Content area */
43
+ .ib-dashboard-layout__content {
44
+ display: flex;
45
+ flex-direction: column;
46
+ flex: 1;
47
+ min-width: 0;
48
+ height: 100dvh;
49
+ overflow: hidden;
50
+ margin-left: 72px;
51
+ transition: margin-left var(--transition-duration-slow) var(--transition-timing-in-out);
52
+ }
53
+
54
+ .ib-dashboard-layout__content--expanded {
55
+ margin-left: 360px;
56
+ }
57
+
58
+ /* Main content */
59
+ .ib-dashboard-layout__main {
60
+ flex: 1;
61
+ overflow-y: auto;
62
+ padding: var(--spacing-6);
63
+ box-sizing: border-box;
64
+ }
65
+
66
+ /* Bottom nav — hidden by default */
67
+ .ib-dashboard-layout__bottom {
68
+ display: none;
69
+ }
70
+
71
+ /* Mobile */
72
+ @media (max-width: 768px) {
73
+ .ib-dashboard-layout__rail-wrapper {
74
+ display: none;
75
+ }
76
+
77
+ .ib-dashboard-layout__drawer-wrapper {
78
+ display: none;
79
+ }
80
+
81
+ .ib-dashboard-layout__content {
82
+ margin-left: 0;
83
+ }
84
+
85
+ .ib-dashboard-layout__bottom {
86
+ display: block;
87
+ }
88
+
89
+ .ib-dashboard-layout__main {
90
+ padding-bottom: calc(var(--spacing-6) + 56px);
91
+ }
92
+ }
@@ -11,10 +11,7 @@
11
11
  cursor: pointer;
12
12
  }
13
13
 
14
- .ibis-dropdown__trigger .ibis-input {
15
- gap: var(--spacing-0);
16
- }
17
-
14
+ /* Hide TextInput's label, help, and error inside the trigger */
18
15
  .ibis-dropdown__trigger .ibis-input__label-wrapper {
19
16
  display: none;
20
17
  }
@@ -24,35 +21,63 @@
24
21
  display: none;
25
22
  }
26
23
 
24
+ .ibis-dropdown__trigger .ibis-input {
25
+ gap: var(--spacing-0);
26
+ }
27
+
28
+ /* Prevent TextInput's field from capturing pointer/focus events */
29
+ .ibis-dropdown__trigger .ibis-input__field {
30
+ pointer-events: none;
31
+ }
32
+
33
+ /* Suppress TextInput's own hover/focus border changes inside the trigger */
34
+ .ibis-dropdown__trigger
35
+ .ibis-input:not(.ibis-input--disabled):not(.ibis-input--invalid)
36
+ .ibis-input__field-wrapper:not(:focus-within):hover {
37
+ border-color: var(--border-color-default);
38
+ }
39
+
40
+ .ibis-dropdown__trigger .ibis-input__field-wrapper:focus-within {
41
+ border-color: var(--border-color-default);
42
+ box-shadow: none;
43
+ }
44
+
45
+ /* Default field wrapper radius */
27
46
  .ibis-dropdown__trigger .ibis-input__field-wrapper {
28
47
  border-radius: var(--border-radius-lg);
29
- transition: border-radius var(--transition-duration-fast) var(--transition-timing-default);
48
+ transition:
49
+ border-radius var(--transition-duration-fast) var(--transition-timing-default),
50
+ border-color var(--transition-duration-fast) var(--transition-timing-default);
30
51
  }
31
52
 
53
+ /* Remove bottom radius and border when open so it connects to the menu */
32
54
  .ibis-dropdown--open .ibis-dropdown__trigger .ibis-input__field-wrapper {
33
55
  border-bottom-left-radius: 0;
34
56
  border-bottom-right-radius: 0;
35
57
  border-bottom-color: transparent;
36
58
  }
37
59
 
60
+ /* Menu */
38
61
  .ibis-dropdown__menu {
39
62
  position: absolute;
40
63
  width: 100%;
41
- background-color: var(--color-surface-default);
42
- border: 2px solid var(--border-color-emphasis);
64
+ background-color: var(--color-white);
65
+ border: 2px solid var(--color-interactive-primary-indicator);
43
66
  border-radius: 0 0 var(--border-radius-lg) var(--border-radius-lg);
44
67
  border-top: none;
45
68
  margin-top: 0;
46
- z-index: 10;
69
+ z-index: var(--z-index-dropdown);
47
70
  list-style: none;
48
71
  padding: var(--spacing-0);
49
72
  overflow: hidden;
50
73
  }
51
74
 
75
+ /* Dividers between items */
52
76
  .ibis-dropdown__menu li + li {
53
- border-top: 1px solid var(--border-color-default);
77
+ border-top: 1px solid var(--color-interactive-neutral-bg-hover);
54
78
  }
55
79
 
80
+ /* Menu items */
56
81
  .ibis-dropdown__item {
57
82
  all: unset;
58
83
  display: flex;
@@ -65,25 +90,25 @@
65
90
  font-family: var(--font-family-sans);
66
91
  font-size: var(--font-size-body-md);
67
92
  font-weight: var(--font-weight-medium);
68
- color: var(--color-text-primary);
93
+ color: var(--color-surface-inverse);
69
94
  text-align: center;
70
95
  transition: background-color var(--transition-duration-fast) var(--transition-timing-default);
71
96
  }
72
97
 
73
98
  .ibis-dropdown__item:hover {
74
99
  background-color: var(--color-interactive-primary-bg-menu-hover);
75
- color: var(--color-text-on-primary);
100
+ color: var(--color-white);
76
101
  }
77
102
 
78
103
  li[aria-selected="true"] .ibis-dropdown__item {
79
104
  background-color: var(--color-interactive-primary-bg-menu-selected);
80
- color: var(--color-text-on-primary);
105
+ color: var(--color-white);
81
106
  font-weight: var(--font-weight-bold);
82
107
  }
83
108
 
84
109
  li[aria-selected="true"] .ibis-dropdown__item:hover {
85
110
  background-color: var(--color-interactive-primary-bg-menu-selected-hover);
86
- color: var(--color-text-on-primary);
111
+ color: var(--color-white);
87
112
  }
88
113
 
89
114
  .ibis-dropdown__item:focus {
@@ -91,6 +116,7 @@ li[aria-selected="true"] .ibis-dropdown__item:hover {
91
116
  background-color: var(--color-interactive-neutral-bg-hover);
92
117
  }
93
118
 
119
+ /* Disabled */
94
120
  .ibis-dropdown__trigger:disabled {
95
121
  cursor: not-allowed;
96
122
  opacity: var(--opacity-5);