@ids-group-ltd/ids-design-system 0.1.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.
- package/README.md +114 -0
- package/fesm2022/ids-group-ltd-ids-design-system.mjs +3170 -0
- package/fesm2022/ids-group-ltd-ids-design-system.mjs.map +1 -0
- package/package.json +46 -0
- package/styles/_dropdown-overlay.scss +117 -0
- package/styles/_fonts.scss +59 -0
- package/styles/_icon-base.scss +9 -0
- package/styles/_layout-utils.scss +14 -0
- package/styles/_link.scss +77 -0
- package/styles/_page-grid.scss +68 -0
- package/styles/_reset.scss +17 -0
- package/styles/_scrollbar.scss +17 -0
- package/styles/_skeleton-shimmer.scss +32 -0
- package/styles/_toast-overlay.scss +6 -0
- package/styles/_tokens-charts.scss +71 -0
- package/styles/_tokens.scss +614 -0
- package/styles/_typography.scss +30 -0
- package/styles/ds.scss +27 -0
- package/styles/fonts/jetbrains-mono-latin-400-normal.woff2 +0 -0
- package/styles/fonts/jetbrains-mono-latin-500-normal.woff2 +0 -0
- package/styles/fonts/jetbrains-mono-latin-600-normal.woff2 +0 -0
- package/styles/fonts/mulish-latin-400-normal.woff2 +0 -0
- package/styles/fonts/mulish-latin-500-normal.woff2 +0 -0
- package/styles/fonts/mulish-latin-600-normal.woff2 +0 -0
- package/styles/fonts/mulish-latin-700-normal.woff2 +0 -0
- package/styles/fonts/mulish-latin-800-normal.woff2 +0 -0
- package/themes/README.md +96 -0
- package/themes/default/_palette.scss +159 -0
- package/themes/default/_theme.scss +274 -0
- package/types/ids-group-ltd-ids-design-system.d.ts +1398 -0
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ids-group-ltd/ids-design-system",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "IDS Group Angular design system: components, tokens, themes",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://bitbucket.org/itband/ids-design-system.git"
|
|
9
|
+
},
|
|
10
|
+
"keywords": [
|
|
11
|
+
"angular",
|
|
12
|
+
"design-system",
|
|
13
|
+
"components",
|
|
14
|
+
"ui",
|
|
15
|
+
"ids-group"
|
|
16
|
+
],
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public"
|
|
19
|
+
},
|
|
20
|
+
"exports": {
|
|
21
|
+
"./styles/*": "./styles/*",
|
|
22
|
+
"./themes/*": "./themes/*",
|
|
23
|
+
"./package.json": {
|
|
24
|
+
"default": "./package.json"
|
|
25
|
+
},
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./types/ids-group-ltd-ids-design-system.d.ts",
|
|
28
|
+
"default": "./fesm2022/ids-group-ltd-ids-design-system.mjs"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"@angular/cdk": "^21.2.0",
|
|
33
|
+
"@angular/common": "^21.2.0",
|
|
34
|
+
"@angular/core": "^21.2.0",
|
|
35
|
+
"@angular/forms": "^21.2.0",
|
|
36
|
+
"@angular/platform-browser": "^21.2.0",
|
|
37
|
+
"@angular/router": "^21.2.0"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"tslib": "^2.3.0"
|
|
41
|
+
},
|
|
42
|
+
"sideEffects": false,
|
|
43
|
+
"module": "fesm2022/ids-group-ltd-ids-design-system.mjs",
|
|
44
|
+
"typings": "types/ids-group-ltd-ids-design-system.d.ts",
|
|
45
|
+
"type": "module"
|
|
46
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// Dropdown panel styles — GLOBAL because the panel is portaled via CDK
|
|
2
|
+
// Overlay outside the host component's DOM tree, so emulated encapsulation
|
|
3
|
+
// (and any `:host ::ng-deep` selectors) cannot reach it. The component sets
|
|
4
|
+
// `panelClass: 'ds-dropdown-panel'` on the overlay config; this partial
|
|
5
|
+
// declares the matching rules so the portaled panel renders styled.
|
|
6
|
+
|
|
7
|
+
.ds-dropdown-panel {
|
|
8
|
+
.dropdown-panel {
|
|
9
|
+
// Fill the cdk-overlay-pane width (set from trigger.getBoundingClientRect()
|
|
10
|
+
// in dropdown.component.ts). Without `width: 100%` the panel is a flex
|
|
11
|
+
// child of the pane and shrinks to its own option content width.
|
|
12
|
+
width: 100%;
|
|
13
|
+
background: var(--surface-overlay);
|
|
14
|
+
border: var(--border-width-default) solid var(--border-default);
|
|
15
|
+
border-radius: var(--radius-md);
|
|
16
|
+
box-shadow: var(--shadow-popover);
|
|
17
|
+
padding: var(--space-1);
|
|
18
|
+
max-height: 320px;
|
|
19
|
+
overflow-y: auto;
|
|
20
|
+
z-index: var(--layer-popover);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.dropdown-list {
|
|
24
|
+
list-style: none;
|
|
25
|
+
margin: 0;
|
|
26
|
+
padding: 0;
|
|
27
|
+
display: flex;
|
|
28
|
+
flex-direction: column;
|
|
29
|
+
gap: 2px;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.optgroup {
|
|
33
|
+
list-style: none;
|
|
34
|
+
display: flex;
|
|
35
|
+
flex-direction: column;
|
|
36
|
+
gap: 2px;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.optgroup-label {
|
|
40
|
+
display: block;
|
|
41
|
+
padding: var(--space-2) var(--space-3) var(--space-1);
|
|
42
|
+
font: var(--font-weight-semibold) var(--font-size-xs)/var(--line-height-flat) var(--font-sans);
|
|
43
|
+
color: var(--text-tertiary);
|
|
44
|
+
text-transform: uppercase;
|
|
45
|
+
letter-spacing: var(--letter-spacing-wide);
|
|
46
|
+
|
|
47
|
+
// First group sits flush against the panel padding — no extra top space.
|
|
48
|
+
&.is-first {
|
|
49
|
+
padding-top: var(--space-1);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.optgroup-list {
|
|
54
|
+
list-style: none;
|
|
55
|
+
margin: 0;
|
|
56
|
+
padding: 0;
|
|
57
|
+
display: flex;
|
|
58
|
+
flex-direction: column;
|
|
59
|
+
gap: 2px;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.option {
|
|
63
|
+
display: flex;
|
|
64
|
+
align-items: center;
|
|
65
|
+
gap: var(--space-2);
|
|
66
|
+
width: 100%;
|
|
67
|
+
padding: var(--space-2) var(--space-2-5);
|
|
68
|
+
border: 0;
|
|
69
|
+
background: transparent;
|
|
70
|
+
font: var(--font-weight-medium) var(--font-size-s)/var(--line-height-flat) var(--font-sans);
|
|
71
|
+
color: var(--text-primary);
|
|
72
|
+
cursor: pointer;
|
|
73
|
+
border-radius: var(--radius-sm);
|
|
74
|
+
text-align: left;
|
|
75
|
+
|
|
76
|
+
.option-icon {
|
|
77
|
+
color: var(--icon-default);
|
|
78
|
+
flex: 0 0 auto;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.option-label {
|
|
82
|
+
flex: 1;
|
|
83
|
+
min-width: 0;
|
|
84
|
+
overflow: hidden;
|
|
85
|
+
text-overflow: ellipsis;
|
|
86
|
+
white-space: nowrap;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.option-check {
|
|
90
|
+
color: var(--primary);
|
|
91
|
+
flex: 0 0 auto;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
&:hover:not(.is-disabled),
|
|
95
|
+
&.is-active:not(.is-disabled) {
|
|
96
|
+
background: var(--surface-secondary);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
&:focus-visible {
|
|
100
|
+
outline: none;
|
|
101
|
+
box-shadow: var(--focus-ring);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
&.is-selected {
|
|
105
|
+
background: var(--primary-subtle);
|
|
106
|
+
color: var(--primary-strong);
|
|
107
|
+
|
|
108
|
+
.option-icon { color: var(--primary-strong); }
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
&.is-disabled {
|
|
112
|
+
color: var(--text-disabled);
|
|
113
|
+
cursor: not-allowed;
|
|
114
|
+
opacity: var(--opacity-muted);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// Self-hosted DS default fonts (latin subset). Consumers override --font-sans / --font-mono to swap.
|
|
2
|
+
|
|
3
|
+
@font-face {
|
|
4
|
+
font-family: 'Mulish';
|
|
5
|
+
font-style: normal;
|
|
6
|
+
font-weight: 400;
|
|
7
|
+
font-display: swap;
|
|
8
|
+
src: url('./fonts/mulish-latin-400-normal.woff2') format('woff2');
|
|
9
|
+
}
|
|
10
|
+
@font-face {
|
|
11
|
+
font-family: 'Mulish';
|
|
12
|
+
font-style: normal;
|
|
13
|
+
font-weight: 500;
|
|
14
|
+
font-display: swap;
|
|
15
|
+
src: url('./fonts/mulish-latin-500-normal.woff2') format('woff2');
|
|
16
|
+
}
|
|
17
|
+
@font-face {
|
|
18
|
+
font-family: 'Mulish';
|
|
19
|
+
font-style: normal;
|
|
20
|
+
font-weight: 600;
|
|
21
|
+
font-display: swap;
|
|
22
|
+
src: url('./fonts/mulish-latin-600-normal.woff2') format('woff2');
|
|
23
|
+
}
|
|
24
|
+
@font-face {
|
|
25
|
+
font-family: 'Mulish';
|
|
26
|
+
font-style: normal;
|
|
27
|
+
font-weight: 700;
|
|
28
|
+
font-display: swap;
|
|
29
|
+
src: url('./fonts/mulish-latin-700-normal.woff2') format('woff2');
|
|
30
|
+
}
|
|
31
|
+
@font-face {
|
|
32
|
+
font-family: 'Mulish';
|
|
33
|
+
font-style: normal;
|
|
34
|
+
font-weight: 800;
|
|
35
|
+
font-display: swap;
|
|
36
|
+
src: url('./fonts/mulish-latin-800-normal.woff2') format('woff2');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@font-face {
|
|
40
|
+
font-family: 'JetBrains Mono';
|
|
41
|
+
font-style: normal;
|
|
42
|
+
font-weight: 400;
|
|
43
|
+
font-display: swap;
|
|
44
|
+
src: url('./fonts/jetbrains-mono-latin-400-normal.woff2') format('woff2');
|
|
45
|
+
}
|
|
46
|
+
@font-face {
|
|
47
|
+
font-family: 'JetBrains Mono';
|
|
48
|
+
font-style: normal;
|
|
49
|
+
font-weight: 500;
|
|
50
|
+
font-display: swap;
|
|
51
|
+
src: url('./fonts/jetbrains-mono-latin-500-normal.woff2') format('woff2');
|
|
52
|
+
}
|
|
53
|
+
@font-face {
|
|
54
|
+
font-family: 'JetBrains Mono';
|
|
55
|
+
font-style: normal;
|
|
56
|
+
font-weight: 600;
|
|
57
|
+
font-display: swap;
|
|
58
|
+
src: url('./fonts/jetbrains-mono-latin-600-normal.woff2') format('woff2');
|
|
59
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Icon-base sizing — `.icon` class is used inside components to size <ds-icon> svg elements.
|
|
2
|
+
// The actual <svg> is rendered by IconComponent; this class sets default size.
|
|
3
|
+
.icon {
|
|
4
|
+
--_icon-size: var(--ds-icon-size, var(--icon-md));
|
|
5
|
+
|
|
6
|
+
width: var(--_icon-size);
|
|
7
|
+
height: var(--_icon-size);
|
|
8
|
+
flex-shrink: 0;
|
|
9
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Layout utility classes — grid helpers from patterns.css §Grid helpers.
|
|
2
|
+
// (Divider lives in _divider.scss — single canonical source.)
|
|
3
|
+
|
|
4
|
+
.grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-4); }
|
|
5
|
+
.grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-4); }
|
|
6
|
+
.grid-4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-4); }
|
|
7
|
+
|
|
8
|
+
@media (max-width: 1100px) {
|
|
9
|
+
.grid-4 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
@media (max-width: 820px) {
|
|
13
|
+
.grid-3, .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
14
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/* Global .link helper — pure CSS class (no Angular wrapper) so consumers
|
|
2
|
+
can apply it to inline anchors inside <p> text without disrupting line
|
|
3
|
+
flow. Modifiers: .quiet, .inline, .standalone, .xs, .sm, .lg. */
|
|
4
|
+
|
|
5
|
+
.link {
|
|
6
|
+
/* Public --ds-link-* are read with fallbacks, never declared — consumer
|
|
7
|
+
overrides inherit in. Hover/active derive from the resolved color. */
|
|
8
|
+
--_link-color: var(--ds-link-color, var(--text-link));
|
|
9
|
+
--_link-color-hover: var(--ds-link-color-hover, color-mix(in srgb, var(--_link-color) 80%, black));
|
|
10
|
+
--_link-color-active: var(--ds-link-color-active, color-mix(in srgb, var(--_link-color) 65%, black));
|
|
11
|
+
|
|
12
|
+
color: var(--_link-color);
|
|
13
|
+
text-decoration: underline;
|
|
14
|
+
text-decoration-color: var(--_link-color);
|
|
15
|
+
text-underline-offset: 2px;
|
|
16
|
+
text-decoration-thickness: 1px;
|
|
17
|
+
font-weight: var(--font-weight-medium);
|
|
18
|
+
cursor: pointer;
|
|
19
|
+
transition: color var(--duration-fast) var(--ease-standard), text-decoration-color var(--duration-fast) var(--ease-standard);
|
|
20
|
+
|
|
21
|
+
&:hover {
|
|
22
|
+
color: var(--_link-color-hover);
|
|
23
|
+
text-decoration-color: var(--_link-color-hover);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
&:active {
|
|
27
|
+
color: var(--_link-color-active);
|
|
28
|
+
text-decoration-color: var(--_link-color-active);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
&:focus-visible {
|
|
32
|
+
outline: none;
|
|
33
|
+
box-shadow: var(--focus-ring);
|
|
34
|
+
border-radius: var(--radius-sm);
|
|
35
|
+
text-decoration-color: var(--_link-color);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
&[aria-disabled="true"] {
|
|
39
|
+
color: var(--text-disabled);
|
|
40
|
+
text-decoration-color: var(--text-disabled);
|
|
41
|
+
pointer-events: none;
|
|
42
|
+
cursor: default;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.icon {
|
|
46
|
+
color: currentColor;
|
|
47
|
+
flex-shrink: 0;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
&.quiet {
|
|
51
|
+
color: var(--text-secondary);
|
|
52
|
+
/* Pull the underline down to match the muted text — the base rule sets
|
|
53
|
+
text-decoration-color to the link color, which would leave a bright
|
|
54
|
+
underline under grey text at rest. */
|
|
55
|
+
text-decoration-color: var(--text-secondary);
|
|
56
|
+
font-weight: var(--font-weight-medium);
|
|
57
|
+
|
|
58
|
+
&:hover {
|
|
59
|
+
color: var(--text-primary);
|
|
60
|
+
text-decoration-color: var(--text-primary);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
&.inline {
|
|
65
|
+
font-weight: inherit;
|
|
66
|
+
font-size: inherit;
|
|
67
|
+
line-height: inherit;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
&.standalone {
|
|
71
|
+
font-weight: var(--font-weight-bold);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
&.xs { font-size: var(--font-size-xs); }
|
|
75
|
+
&.sm { font-size: var(--font-size-s); }
|
|
76
|
+
&.lg { font-size: var(--font-size-l); }
|
|
77
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// Page grid — four-tier responsive layout grid.
|
|
2
|
+
//
|
|
3
|
+
// One column-count per breakpoint (4 / 8 / 12 / 12), gutters and margins
|
|
4
|
+
// scale with the viewport, content caps at --col-cap-content on the widest
|
|
5
|
+
// tier and stays fluid below. Sub-regions inherit the page grid — never
|
|
6
|
+
// invent a local grid. Sidenav lives OUTSIDE this grid (reserve its rail
|
|
7
|
+
// first, start `.page-grid` in the remaining width).
|
|
8
|
+
//
|
|
9
|
+
// Tier | Range | Cols | Gutter | Margin | Cap
|
|
10
|
+
// ------------ | -------------- | ---- | ------------- | ------------- | ----------------
|
|
11
|
+
// Mobile | <= 640px | 4 | --space-3 (12px) | --space-4 (16px) | fluid
|
|
12
|
+
// Tablet | 641-1024px | 8 | --space-4 (16px) | --space-6 (24px) | fluid
|
|
13
|
+
// Desktop | 1025-1440px | 12 | --space-5 (20px) | --space-8 (32px) | fluid
|
|
14
|
+
// Desktop wide | >= 1441px | 12 | --space-6 (24px) | --space-10 (40px) | --col-cap-content (1280px)
|
|
15
|
+
//
|
|
16
|
+
// Snap to columns, not pixels: 8+4 / 6+6 / 9+3 are canonical splits;
|
|
17
|
+
// 7+5 is forbidden. Prose blocks cap at --col-cap-text (720px) regardless
|
|
18
|
+
// of grid width.
|
|
19
|
+
|
|
20
|
+
.page-grid {
|
|
21
|
+
display: grid;
|
|
22
|
+
gap: var(--page-gutter);
|
|
23
|
+
padding: 0 var(--page-margin);
|
|
24
|
+
max-width: var(--col-cap-content);
|
|
25
|
+
margin: 0 auto;
|
|
26
|
+
|
|
27
|
+
// Mobile (default, <= 640px) — 4 columns
|
|
28
|
+
--page-gutter: var(--page-gutter-mobile);
|
|
29
|
+
--page-margin: var(--page-margin-mobile);
|
|
30
|
+
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
31
|
+
|
|
32
|
+
// Tablet (641-1024px) — 8 columns
|
|
33
|
+
@media (min-width: 641px) {
|
|
34
|
+
--page-gutter: var(--page-gutter-tablet);
|
|
35
|
+
--page-margin: var(--page-margin-tablet);
|
|
36
|
+
grid-template-columns: repeat(8, minmax(0, 1fr));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Desktop (1025-1440px) — 12 columns, fluid width
|
|
40
|
+
@media (min-width: 1025px) {
|
|
41
|
+
--page-gutter: var(--page-gutter-desktop);
|
|
42
|
+
--page-margin: var(--page-margin-desktop);
|
|
43
|
+
grid-template-columns: repeat(12, minmax(0, 1fr));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Desktop wide (>= 1441px) — 12 columns, container capped at --col-cap-content
|
|
47
|
+
@media (min-width: 1441px) {
|
|
48
|
+
--page-gutter: var(--page-gutter-wide);
|
|
49
|
+
--page-margin: var(--page-margin-wide);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Column-span helpers. The 12-col base covers every tier — at narrower tiers
|
|
54
|
+
// (8 / 4 cols) a span larger than the active column-count wraps to its own
|
|
55
|
+
// row, which is the intended fallback. Snap to canonical splits (8+4 / 6+6 /
|
|
56
|
+
// 9+3 / 4+4+4) rather than ad-hoc widths.
|
|
57
|
+
.col-span-1 { grid-column: span 1; }
|
|
58
|
+
.col-span-2 { grid-column: span 2; }
|
|
59
|
+
.col-span-3 { grid-column: span 3; }
|
|
60
|
+
.col-span-4 { grid-column: span 4; }
|
|
61
|
+
.col-span-5 { grid-column: span 5; }
|
|
62
|
+
.col-span-6 { grid-column: span 6; }
|
|
63
|
+
.col-span-7 { grid-column: span 7; }
|
|
64
|
+
.col-span-8 { grid-column: span 8; }
|
|
65
|
+
.col-span-9 { grid-column: span 9; }
|
|
66
|
+
.col-span-10 { grid-column: span 10; }
|
|
67
|
+
.col-span-11 { grid-column: span 11; }
|
|
68
|
+
.col-span-12 { grid-column: span 12; }
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Reset — ported from CLAUDE_DESIGN_DS/tokens.css §Base.
|
|
2
|
+
|
|
3
|
+
*, *::before, *::after { box-sizing: border-box; }
|
|
4
|
+
html, body {
|
|
5
|
+
margin: 0;
|
|
6
|
+
font-family: var(--font-sans);
|
|
7
|
+
color: var(--text-primary);
|
|
8
|
+
background: var(--surface-canvas);
|
|
9
|
+
-webkit-font-smoothing: antialiased;
|
|
10
|
+
text-rendering: optimizeLegibility;
|
|
11
|
+
}
|
|
12
|
+
button, input, select, textarea { font-family: inherit; }
|
|
13
|
+
|
|
14
|
+
/* Zero the browser's default heading margins (~0.83em) — they otherwise leak
|
|
15
|
+
into consumers and mangle spacing. Headings get their size from .t-* utils;
|
|
16
|
+
spacing is owned by the surrounding layout (gap / margin), not the element. */
|
|
17
|
+
h1, h2, h3, h4, h5, h6 { margin: 0; }
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Scrollbar — ported verbatim from CLAUDE_DESIGN_DS/components-extras.css §Global scrollbar.
|
|
2
|
+
// Brand-tinted neutral thumb applied globally.
|
|
3
|
+
|
|
4
|
+
html { scrollbar-width: thin; scrollbar-color: var(--scrollbar-thumb) transparent; }
|
|
5
|
+
*::-webkit-scrollbar { width: var(--scrollbar-w); height: var(--scrollbar-w); }
|
|
6
|
+
*::-webkit-scrollbar-track { background: transparent; }
|
|
7
|
+
*::-webkit-scrollbar-thumb {
|
|
8
|
+
background: var(--scrollbar-thumb);
|
|
9
|
+
border-radius: var(--radius-pill);
|
|
10
|
+
border: var(--space-0-5) solid transparent;
|
|
11
|
+
background-clip: padding-box;
|
|
12
|
+
}
|
|
13
|
+
*::-webkit-scrollbar-thumb:hover { background: var(--scrollbar-thumb-hover); background-clip: padding-box; }
|
|
14
|
+
*::-webkit-scrollbar-thumb:active { background: var(--scrollbar-thumb-active); background-clip: padding-box; }
|
|
15
|
+
|
|
16
|
+
// Global text-selection — sourced from components-extras.css line 910.
|
|
17
|
+
::selection { background: var(--select-bg, color-mix(in srgb, var(--primary) 22%, transparent)); color: var(--text-primary); }
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Global skeleton shimmer driver.
|
|
2
|
+
//
|
|
3
|
+
// All <ds-skeleton> instances on the page reveal the same moving slice by
|
|
4
|
+
// reading a shared, viewport-anchored offset (--skeleton-shimmer-x). The
|
|
5
|
+
// offset is animated ONCE on :root so every skeleton stays in lock-step with
|
|
6
|
+
// every other — no per-element animation timers drifting against each other.
|
|
7
|
+
//
|
|
8
|
+
// @property registration is required so the browser can interpolate the
|
|
9
|
+
// custom property continuously instead of treating it as a discrete switch
|
|
10
|
+
// at 0%/100%. Chrome 85+, Edge 85+, Firefox 128+, Safari 16.4+.
|
|
11
|
+
|
|
12
|
+
@property --skeleton-shimmer-x {
|
|
13
|
+
syntax: '<length>';
|
|
14
|
+
inherits: true;
|
|
15
|
+
initial-value: 100vw;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
:root {
|
|
19
|
+
animation: ds-skeleton-shimmer-loop var(--duration-loop-slow, 1400ms) linear infinite;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@keyframes ds-skeleton-shimmer-loop {
|
|
23
|
+
0% { --skeleton-shimmer-x: 100vw; }
|
|
24
|
+
100% { --skeleton-shimmer-x: -100vw; }
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Honour the user's reduced-motion preference — no shimmer travel.
|
|
28
|
+
@media (prefers-reduced-motion: reduce) {
|
|
29
|
+
:root {
|
|
30
|
+
animation: none;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Toast overlay panel — GLOBAL (portaled via CDK Overlay, outside component DOM).
|
|
2
|
+
// ToastService sets panelClass: 'ds-toast-panel'. CDK overlays stack by DOM
|
|
3
|
+
// insertion order, so lift the toast wrapper above modals/drawers explicitly.
|
|
4
|
+
.cdk-global-overlay-wrapper:has(> .ds-toast-panel) {
|
|
5
|
+
z-index: var(--layer-toast);
|
|
6
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/* ============================================================
|
|
2
|
+
Boilerplate — Chart / dataviz tokens
|
|
3
|
+
------------------------------------------------------------
|
|
4
|
+
Categorical: 8 hues, ordered by perceptual distance not
|
|
5
|
+
ramp position. First six are AA against both light and
|
|
6
|
+
dark surface-default; the last two are reserved for
|
|
7
|
+
"rest" / "other" buckets where contrast is less critical.
|
|
8
|
+
|
|
9
|
+
Sequential: single-hue ramp (blue) for ordinal data —
|
|
10
|
+
"low → high" magnitudes.
|
|
11
|
+
|
|
12
|
+
Divergent: red ↔ neutral ↔ green for signed data —
|
|
13
|
+
"bad ← zero → good". Used for Excess / Shortage matrix.
|
|
14
|
+
============================================================ */
|
|
15
|
+
|
|
16
|
+
:root {
|
|
17
|
+
/* CATEGORICAL (8) ----------------------------------------- */
|
|
18
|
+
--chart-cat-1: hsl(229, 100%, 59%); /* blue (primary) */
|
|
19
|
+
--chart-cat-2: hsl(165, 72%, 38%); /* teal */
|
|
20
|
+
--chart-cat-3: hsl( 24, 95%, 55%); /* orange */
|
|
21
|
+
--chart-cat-4: hsl(330, 82%, 55%); /* magenta */
|
|
22
|
+
--chart-cat-5: hsl(45, 95%, 50%); /* amber */
|
|
23
|
+
--chart-cat-6: hsl(190, 85%, 45%); /* cyan */
|
|
24
|
+
--chart-cat-7: hsl(280, 60%, 60%); /* lavender */
|
|
25
|
+
--chart-cat-8: hsl(130, 45%, 50%); /* moss */
|
|
26
|
+
|
|
27
|
+
/* SEQUENTIAL — single-hue, light → dark */
|
|
28
|
+
--chart-seq-1: var(--blue-100);
|
|
29
|
+
--chart-seq-2: var(--blue-200);
|
|
30
|
+
--chart-seq-3: var(--blue-300);
|
|
31
|
+
--chart-seq-4: var(--blue-500);
|
|
32
|
+
--chart-seq-5: var(--blue-700);
|
|
33
|
+
--chart-seq-6: var(--blue-900);
|
|
34
|
+
|
|
35
|
+
/* DIVERGENT — red ← neutral → green
|
|
36
|
+
Values taken verbatim from the source design prototype
|
|
37
|
+
(CLAUDE_DESIGN_DS/patterns.css) so the Excess/Shortage matrix
|
|
38
|
+
matches the reference one-for-one. Explicit HSL keeps the ramp
|
|
39
|
+
independent of palette retunes — re-skinning brand/red/green
|
|
40
|
+
should not shift the dataviz colour story. */
|
|
41
|
+
--chart-div--3: hsl(0 70% 40%); /* large negative (worst) */
|
|
42
|
+
--chart-div--2: hsl(0 60% 58%);
|
|
43
|
+
--chart-div--1: hsl(0 50% 80%);
|
|
44
|
+
--chart-div-0: hsl(225 8% 92%); /* zero */
|
|
45
|
+
--chart-div-1: hsl(140 35% 80%);
|
|
46
|
+
--chart-div-2: hsl(140 45% 55%);
|
|
47
|
+
--chart-div-3: hsl(140 55% 35%); /* large positive (best) */
|
|
48
|
+
|
|
49
|
+
/* AXIS / GRID / LEGEND */
|
|
50
|
+
--chart-axis-line: var(--neutral-300);
|
|
51
|
+
--chart-axis-label: var(--text-tertiary);
|
|
52
|
+
--chart-axis-title: var(--text-secondary);
|
|
53
|
+
--chart-grid-line: var(--neutral-150);
|
|
54
|
+
--chart-grid-line-strong: var(--neutral-200);
|
|
55
|
+
--chart-tick-size: 4px;
|
|
56
|
+
--chart-axis-fs: var(--font-size-2xs);
|
|
57
|
+
|
|
58
|
+
/* HIGHLIGHT / HOVER */
|
|
59
|
+
--chart-hover-bg: hsla(225, 39%, 7%, .04);
|
|
60
|
+
--chart-cursor-line: var(--neutral-400);
|
|
61
|
+
--chart-tooltip-bg: var(--neutral-900);
|
|
62
|
+
--chart-tooltip-fg: var(--neutral-0);
|
|
63
|
+
--chart-tooltip-border: var(--neutral-700);
|
|
64
|
+
|
|
65
|
+
/* DIMENSIONS */
|
|
66
|
+
--chart-bar-gap: 4px;
|
|
67
|
+
--chart-line-w: 2px;
|
|
68
|
+
--chart-line-w-bold: 3px;
|
|
69
|
+
--chart-dot-r: 4px;
|
|
70
|
+
--chart-dot-r-active: 6px;
|
|
71
|
+
}
|