@klodd/ds 1.2.0 → 3.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,100 @@
1
+ /* ================================================================
2
+ components/hub-card.css
3
+ Stora settings-hub-kort. Anvands i settings-hub-vyer dar varje
4
+ kort lankar till en sub-sida. Layout: ikon + titel + subtitle +
5
+ chev. Hela kortet ar klickbart.
6
+
7
+ .hub-list samlar flera hub-cards i en kolumn.
8
+ .hub-category ar group-rubrik over flera kort.
9
+ ================================================================ */
10
+ .hub-list {
11
+ display: flex;
12
+ flex-direction: column;
13
+ gap: var(--space-8);
14
+ margin: 0;
15
+ padding: 0;
16
+ list-style: none;
17
+ }
18
+
19
+ .hub-card {
20
+ display: flex;
21
+ align-items: center;
22
+ gap: var(--space-14);
23
+ padding: var(--space-16) var(--space-18);
24
+ background: var(--surface-raised);
25
+ border: 1px solid var(--border-subtle);
26
+ border-radius: var(--radius-16);
27
+ color: var(--text-default);
28
+ text-decoration: none;
29
+ cursor: pointer;
30
+ -webkit-tap-highlight-color: transparent;
31
+ touch-action: manipulation;
32
+ transition:
33
+ background var(--dur-base) var(--ease-spring-snappy),
34
+ transform var(--press-out-duration) var(--press-out-easing);
35
+ }
36
+
37
+ @media (hover: hover) and (pointer: fine) {
38
+ .hub-card:hover {
39
+ background: var(--surface-overlay);
40
+ }
41
+ }
42
+
43
+ .hub-card:active {
44
+ transform: scale(0.99);
45
+ transition: transform var(--press-in-duration) var(--press-in-easing);
46
+ }
47
+
48
+ .hub-card:focus-visible {
49
+ outline: 2px solid var(--border-focus);
50
+ outline-offset: 2px;
51
+ }
52
+
53
+ .hub-card__icon {
54
+ display: inline-flex;
55
+ align-items: center;
56
+ justify-content: center;
57
+ width: 36px;
58
+ height: 36px;
59
+ background: var(--surface-default);
60
+ color: var(--accent-text);
61
+ border-radius: var(--radius-12);
62
+ flex-shrink: 0;
63
+ }
64
+
65
+ .hub-card__text {
66
+ flex: 1;
67
+ min-width: 0;
68
+ display: flex;
69
+ flex-direction: column;
70
+ gap: var(--space-2);
71
+ }
72
+
73
+ .hub-card__title {
74
+ font-size: var(--fs-15);
75
+ font-weight: var(--fw-medium);
76
+ color: var(--text-default);
77
+ line-height: var(--lh-snug);
78
+ }
79
+
80
+ .hub-card__subtitle {
81
+ font-size: var(--fs-12);
82
+ color: var(--text-muted);
83
+ line-height: var(--lh-snug);
84
+ }
85
+
86
+ .hub-card__chev {
87
+ flex-shrink: 0;
88
+ color: var(--text-disabled);
89
+ }
90
+
91
+ .hub-category {
92
+ font-size: var(--fs-11);
93
+ font-weight: var(--fw-medium);
94
+ color: var(--text-muted);
95
+ letter-spacing: 0.08em;
96
+ text-transform: uppercase;
97
+ margin: var(--space-20) 0 var(--space-8);
98
+ padding: 0 var(--space-4);
99
+ }
100
+ .hub-category:first-child { margin-top: 0; }
@@ -0,0 +1,74 @@
1
+ /* ================================================================
2
+ components/inline-edit.css
3
+ Inline-edit-monstret for klickbart text-falt som expanderas till
4
+ input vid pencil-click. Anvands for profil-namn, etiketter, taggar.
5
+
6
+ Tidigare hette komponenten .profile-name-edit (Ekonom-domain).
7
+ Nu generaliserad till .inline-edit.
8
+ ================================================================ */
9
+ .inline-edit {
10
+ display: inline-flex;
11
+ align-items: center;
12
+ gap: var(--space-6);
13
+ }
14
+
15
+ .inline-edit__text {
16
+ font-size: var(--fs-17);
17
+ font-weight: var(--fw-medium);
18
+ color: var(--text-default);
19
+ letter-spacing: var(--ls-tight);
20
+ }
21
+
22
+ .inline-edit__btn {
23
+ display: inline-flex;
24
+ align-items: center;
25
+ justify-content: center;
26
+ width: 28px;
27
+ height: 28px;
28
+ padding: 0;
29
+ background: transparent;
30
+ border: 0;
31
+ color: var(--text-muted);
32
+ cursor: pointer;
33
+ border-radius: 50%;
34
+ transition: background var(--dur-fast) var(--ease-default);
35
+ }
36
+
37
+ @media (hover: hover) and (pointer: fine) {
38
+ .inline-edit__btn:hover {
39
+ background: var(--surface-hover);
40
+ color: var(--text-default);
41
+ }
42
+ }
43
+
44
+ .inline-edit__form {
45
+ display: inline-flex;
46
+ align-items: center;
47
+ gap: var(--space-6);
48
+ margin: 0;
49
+ }
50
+
51
+ /* HTML5 hidden-attribut ska respekteras - default UA-stylesheet ger
52
+ display:none men paketets display:inline-flex kan over-rida det.
53
+ Explicit regel saker att hidden alltid vinner. */
54
+ .inline-edit__form[hidden] {
55
+ display: none;
56
+ }
57
+
58
+ .inline-edit__input {
59
+ display: inline-block;
60
+ height: 32px;
61
+ padding: 0 var(--space-10);
62
+ background: var(--surface-sunken);
63
+ border: 1px solid var(--border-default);
64
+ border-radius: var(--radius-8);
65
+ color: var(--text-default);
66
+ font-family: inherit;
67
+ font-size: 16px;
68
+ outline: none;
69
+ }
70
+
71
+ .inline-edit__input:focus {
72
+ border-color: var(--accent-9);
73
+ box-shadow: 0 0 0 3px var(--accent-a3);
74
+ }
@@ -0,0 +1,115 @@
1
+ /* ================================================================
2
+ components/list-row.css
3
+ Generisk list-rad med ikon + body + amount. Anvands for transaktioner,
4
+ subscriptions, audit-logs, jobblistor.
5
+
6
+ Tidigare hette komponenten .tx-row (transaction) - nu generaliserad
7
+ till .list-row sa inte affarsdomanen sipprar in i namnet.
8
+
9
+ Element: .list-row__icon, .list-row__body, .list-row__desc,
10
+ .list-row__amount, .list-row__date, .list-row__meta.
11
+
12
+ Modifiers: --excluded (greyed out), --pending (with dashed border).
13
+
14
+ App-specifika domain-overrides (kategori-fargade ikoner) lever i
15
+ app-repots egna CSS - inte i paketet.
16
+ ================================================================ */
17
+ .list {
18
+ list-style: none;
19
+ margin: 0;
20
+ padding: 0;
21
+ }
22
+
23
+ .list-row {
24
+ display: flex;
25
+ align-items: center;
26
+ gap: var(--space-12);
27
+ padding: var(--space-10) 0;
28
+ border-bottom: 1px solid var(--border-subtle);
29
+ min-height: 56px;
30
+ }
31
+
32
+ .list-row:last-child { border-bottom: none; }
33
+
34
+ .list-row__icon {
35
+ width: 36px;
36
+ height: 36px;
37
+ border-radius: var(--radius-12);
38
+ display: flex;
39
+ align-items: center;
40
+ justify-content: center;
41
+ flex-shrink: 0;
42
+ background: var(--surface-default);
43
+ color: var(--text-subtle);
44
+ }
45
+
46
+ .list-row__icon svg {
47
+ width: 18px;
48
+ height: 18px;
49
+ stroke: currentColor;
50
+ fill: none;
51
+ stroke-width: 2;
52
+ }
53
+
54
+ .list-row__body {
55
+ flex: 1;
56
+ min-width: 0;
57
+ display: flex;
58
+ flex-direction: column;
59
+ gap: var(--space-2);
60
+ }
61
+
62
+ .list-row__desc {
63
+ font-size: var(--fs-14);
64
+ color: var(--text-default);
65
+ white-space: nowrap;
66
+ overflow: hidden;
67
+ text-overflow: ellipsis;
68
+ }
69
+
70
+ .list-row__desc a { color: inherit; }
71
+
72
+ .list-row__meta {
73
+ font-size: var(--fs-12);
74
+ color: var(--text-muted);
75
+ }
76
+
77
+ .list-row__date {
78
+ font-size: var(--fs-12);
79
+ color: var(--text-muted);
80
+ white-space: nowrap;
81
+ min-width: 3.5rem;
82
+ font-variant-numeric: tabular-nums;
83
+ }
84
+
85
+ .list-row__amount {
86
+ font-size: var(--fs-14);
87
+ font-weight: var(--fw-medium);
88
+ color: var(--text-default);
89
+ text-align: right;
90
+ white-space: nowrap;
91
+ min-width: 5rem;
92
+ font-variant-numeric: tabular-nums;
93
+ }
94
+
95
+ .list-row__amount--positive { color: var(--positive); }
96
+ .list-row__amount--negative { color: var(--negative); }
97
+
98
+ .list-row--excluded {
99
+ opacity: 0.5;
100
+ }
101
+
102
+ .list-row--pending .list-row__icon {
103
+ border: 1px dashed var(--border-default);
104
+ background: transparent;
105
+ }
106
+
107
+ .list-row--clickable {
108
+ cursor: pointer;
109
+ -webkit-tap-highlight-color: transparent;
110
+ touch-action: manipulation;
111
+ }
112
+
113
+ @media (hover: hover) and (pointer: fine) {
114
+ .list-row--clickable:hover { background: var(--surface-hover); }
115
+ }
@@ -0,0 +1,95 @@
1
+ /* ================================================================
2
+ components/panel.css
3
+ Allmanna paneler. .panel ar bas. Modifiers: --info, --danger,
4
+ --attention. Slot-element: .panel__title, .panel__title-row,
5
+ .panel__step-row.
6
+
7
+ Skiljer sig fran .card sa: panel ar mer noga med padding och
8
+ margin-bottom (flode i lista). Card ar mer flexibel med slots
9
+ (.card-header, .card-body, .card-footer).
10
+ ================================================================ */
11
+ .panel {
12
+ background: var(--surface-raised);
13
+ border: 1px solid var(--border-subtle);
14
+ border-radius: var(--radius-20);
15
+ padding: var(--space-16) var(--space-18);
16
+ margin-bottom: var(--space-14);
17
+ }
18
+
19
+ .panel__title {
20
+ font-size: var(--fs-10);
21
+ font-weight: var(--fw-medium);
22
+ letter-spacing: var(--ls-tracker-xl, 0.12em);
23
+ text-transform: uppercase;
24
+ color: var(--text-muted);
25
+ margin: 0 0 var(--space-12);
26
+ }
27
+
28
+ .panel__title-row {
29
+ display: flex;
30
+ justify-content: space-between;
31
+ align-items: center;
32
+ gap: var(--space-10);
33
+ margin-bottom: var(--space-12);
34
+ }
35
+ .panel__title-row .panel__title { margin-bottom: 0; }
36
+
37
+ .panel__title-meta {
38
+ font-size: var(--fs-12);
39
+ color: var(--text-muted);
40
+ font-weight: var(--fw-medium);
41
+ font-variant-numeric: tabular-nums;
42
+ }
43
+
44
+ .panel__title-link {
45
+ font-size: var(--fs-12);
46
+ color: var(--accent-text);
47
+ font-weight: var(--fw-medium);
48
+ text-decoration: none;
49
+ }
50
+ @media (hover: hover) and (pointer: fine) {
51
+ .panel__title-link:hover { text-decoration: underline; }
52
+ }
53
+
54
+ .panel--info {
55
+ border-left: 3px solid var(--positive-border);
56
+ }
57
+
58
+ .panel--info-warning {
59
+ border-left: 3px solid var(--warning-border);
60
+ }
61
+
62
+ .panel--danger {
63
+ border: 1px solid var(--accent-danger-border);
64
+ background: var(--accent-danger-dim);
65
+ }
66
+
67
+ .panel--attention {
68
+ background: var(--warning-dim);
69
+ border: 1px solid var(--warning-border);
70
+ }
71
+ .panel--attention .panel__title {
72
+ color: var(--warning);
73
+ }
74
+
75
+ .panel__step-row {
76
+ display: flex;
77
+ align-items: center;
78
+ gap: var(--space-8);
79
+ margin-bottom: var(--space-8);
80
+ }
81
+
82
+ .panel__step-badge {
83
+ display: inline-flex;
84
+ align-items: center;
85
+ height: 20px;
86
+ padding: 0 var(--space-8);
87
+ background: var(--surface-active);
88
+ color: var(--accent-text);
89
+ font-size: var(--fs-11);
90
+ font-weight: var(--fw-medium);
91
+ letter-spacing: 0.04em;
92
+ text-transform: uppercase;
93
+ border-radius: var(--radius-full);
94
+ flex-shrink: 0;
95
+ }
@@ -0,0 +1,186 @@
1
+ /* ================================================================
2
+ components/setting-row.css
3
+ Tap-to-edit-rad som triggar bottom-sheet. Vanster: label + sub.
4
+ Hoger: varde + chevron. Anvands i settings-vyer.
5
+
6
+ Plus iOS-stil .setting-toggle med native checkbox dolt.
7
+
8
+ .setting-list samlar flera setting-rows med subtle dividers.
9
+ ================================================================ */
10
+ .setting-list {
11
+ list-style: none;
12
+ margin: 0;
13
+ padding: 0;
14
+ display: flex;
15
+ flex-direction: column;
16
+ }
17
+ .setting-list > li { display: block; }
18
+ .setting-list > li + li {
19
+ border-top: 1px solid var(--border-subtle);
20
+ }
21
+
22
+ .setting-row {
23
+ display: flex;
24
+ align-items: center;
25
+ justify-content: space-between;
26
+ gap: var(--space-12);
27
+ width: 100%;
28
+ padding: var(--space-14) var(--space-16);
29
+ background: transparent;
30
+ border: 0;
31
+ border-radius: var(--radius-12);
32
+ color: inherit;
33
+ text-align: left;
34
+ cursor: pointer;
35
+ font-family: inherit;
36
+ -webkit-tap-highlight-color: transparent;
37
+ touch-action: manipulation;
38
+ transition: background var(--dur-fast) var(--ease-spring-snappy);
39
+ }
40
+
41
+ .setting-row + .setting-row {
42
+ border-top: 1px solid var(--border-subtle);
43
+ }
44
+
45
+ @media (hover: hover) and (pointer: fine) {
46
+ .setting-row:hover { background: var(--surface-hover); }
47
+ }
48
+
49
+ .setting-row:active {
50
+ background: var(--surface-active);
51
+ transform: scale(0.985);
52
+ transition:
53
+ transform 80ms var(--ease-spring-snappy),
54
+ background var(--dur-fast) var(--ease-spring-snappy);
55
+ }
56
+
57
+ .setting-row:focus-visible {
58
+ outline: 2px solid var(--border-focus);
59
+ outline-offset: -2px;
60
+ }
61
+
62
+ .setting-row__text {
63
+ display: flex;
64
+ flex-direction: column;
65
+ gap: 2px;
66
+ min-width: 0;
67
+ flex: 1;
68
+ }
69
+
70
+ .setting-row__label {
71
+ font-size: var(--fs-15);
72
+ font-weight: var(--fw-medium);
73
+ color: var(--text-default);
74
+ line-height: var(--lh-snug);
75
+ }
76
+
77
+ .setting-row__sub {
78
+ font-size: var(--fs-12);
79
+ color: var(--text-muted);
80
+ line-height: var(--lh-snug);
81
+ }
82
+
83
+ .setting-row__value {
84
+ display: flex;
85
+ align-items: center;
86
+ gap: var(--space-6);
87
+ flex-shrink: 0;
88
+ }
89
+
90
+ .setting-row__amount {
91
+ font-size: var(--fs-15);
92
+ font-weight: var(--fw-medium);
93
+ color: var(--text-subtle);
94
+ font-variant-numeric: tabular-nums;
95
+ }
96
+
97
+ .setting-row__chevron {
98
+ color: var(--text-disabled);
99
+ flex-shrink: 0;
100
+ }
101
+
102
+ .setting-row__avatar {
103
+ margin-right: var(--space-12);
104
+ flex-shrink: 0;
105
+ }
106
+
107
+ .setting-row--static {
108
+ cursor: default;
109
+ }
110
+ .setting-row--static:active {
111
+ background: transparent;
112
+ transform: none;
113
+ }
114
+ @media (hover: hover) and (pointer: fine) {
115
+ .setting-row--static:hover { background: transparent; }
116
+ }
117
+
118
+ .setting-row--danger .setting-row__label {
119
+ color: var(--accent-danger);
120
+ }
121
+
122
+ .setting-row__pill {
123
+ display: inline-flex;
124
+ align-items: center;
125
+ height: 28px;
126
+ padding: 0 var(--space-12);
127
+ background: var(--accent-9);
128
+ color: var(--text-on-accent);
129
+ font-size: var(--fs-12);
130
+ font-weight: var(--fw-medium);
131
+ border-radius: var(--radius-full);
132
+ white-space: nowrap;
133
+ }
134
+
135
+
136
+ /* ================================================================
137
+ ==== TOGGLE (iOS-stil)
138
+ Native checkbox dolt visuellt men a11y-tillganglig.
139
+ ================================================================ */
140
+ .setting-toggle {
141
+ position: relative;
142
+ display: inline-block;
143
+ width: 44px;
144
+ height: 26px;
145
+ flex-shrink: 0;
146
+ }
147
+ .setting-toggle input {
148
+ position: absolute;
149
+ inset: 0;
150
+ width: 100%;
151
+ height: 100%;
152
+ margin: 0;
153
+ opacity: 0;
154
+ cursor: pointer;
155
+ z-index: 1;
156
+ }
157
+ .setting-toggle__track {
158
+ display: block;
159
+ width: 100%;
160
+ height: 100%;
161
+ background: var(--border-strong);
162
+ border-radius: var(--radius-full);
163
+ transition: background var(--dur-medium) var(--ease-spring-snappy);
164
+ position: relative;
165
+ }
166
+ .setting-toggle__thumb {
167
+ position: absolute;
168
+ top: 2px;
169
+ left: 2px;
170
+ width: 22px;
171
+ height: 22px;
172
+ background: var(--surface-page);
173
+ border-radius: 50%;
174
+ transition: transform var(--dur-medium) var(--ease-spring-snappy);
175
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
176
+ }
177
+ .setting-toggle input:checked + .setting-toggle__track {
178
+ background: var(--accent-9);
179
+ }
180
+ .setting-toggle input:checked + .setting-toggle__track .setting-toggle__thumb {
181
+ transform: translateX(18px);
182
+ }
183
+ .setting-toggle input:focus-visible + .setting-toggle__track {
184
+ outline: 2px solid var(--border-focus);
185
+ outline-offset: 2px;
186
+ }
@@ -0,0 +1,53 @@
1
+ /* ================================================================
2
+ components/split-bar.css
3
+ Visuell proportionsbar dar tva eller flera segment delar baren.
4
+ Anvands for cost-split (vem betalar), debt-vs-equity, time-allocation.
5
+
6
+ Modell: .split-bar har N stycken .split-bar__segment som tillsammans
7
+ fyller 100%. Brett valbart segment satts genom data-bar-width-pattern
8
+ eller manuella width-classes.
9
+ ================================================================ */
10
+ .split-bar {
11
+ display: flex;
12
+ height: 8px;
13
+ border-radius: var(--radius-full);
14
+ overflow: hidden;
15
+ background: var(--surface-active);
16
+ margin: var(--space-8) 0 var(--space-12);
17
+ }
18
+
19
+ .split-bar__segment {
20
+ height: 100%;
21
+ transition: width var(--dur-medium) var(--ease-spring-snappy);
22
+ }
23
+
24
+ .split-bar__segment--primary { background: var(--accent-9); }
25
+ .split-bar__segment--secondary { background: var(--text-disabled); flex: 1; }
26
+ .split-bar__segment--positive { background: var(--positive); }
27
+ .split-bar__segment--negative { background: var(--negative); }
28
+ .split-bar__segment--warning { background: var(--warning); }
29
+
30
+ .split-bar__label {
31
+ font-size: var(--fs-13);
32
+ color: var(--text-subtle);
33
+ margin: 0 0 var(--space-6);
34
+ line-height: var(--lh-snug);
35
+ }
36
+
37
+ .split-bar__label strong {
38
+ color: var(--text-default);
39
+ font-weight: var(--fw-medium);
40
+ }
41
+
42
+ .split-bar__labels {
43
+ display: flex;
44
+ justify-content: space-between;
45
+ gap: var(--space-10);
46
+ margin-top: var(--space-6);
47
+ font-size: var(--fs-12);
48
+ color: var(--text-subtle);
49
+ }
50
+
51
+ @media (prefers-reduced-motion: reduce) {
52
+ .split-bar__segment { transition: none; }
53
+ }
@@ -0,0 +1,55 @@
1
+ /* ================================================================
2
+ components/stat.css
3
+ Stat-card och metric-card - sma kort med stor siffra + label.
4
+ .stat-grid lagger ut flera kort i grid (2 kol mobil, 4 desktop).
5
+
6
+ .stat-card ar nyare BEM-versionen. .metric-card behalls for
7
+ bakatkompat med befintliga vyer som anvander metric-grid.
8
+ ================================================================ */
9
+ .stat-grid {
10
+ display: grid;
11
+ grid-template-columns: repeat(2, 1fr);
12
+ gap: var(--space-12);
13
+ margin-bottom: var(--space-14);
14
+ }
15
+ .stat-grid--single { grid-template-columns: 1fr; }
16
+
17
+ .stat-card {
18
+ display: flex;
19
+ flex-direction: column;
20
+ align-items: flex-start;
21
+ gap: var(--space-4);
22
+ padding: var(--space-16);
23
+ background: var(--surface-default);
24
+ border-radius: var(--radius-12);
25
+ }
26
+
27
+ .stat-card__value {
28
+ font-size: var(--fs-22);
29
+ font-weight: var(--fw-medium);
30
+ color: var(--text-default);
31
+ font-variant-numeric: tabular-nums;
32
+ line-height: 1;
33
+ }
34
+
35
+ .stat-card__label {
36
+ font-size: var(--fs-12);
37
+ color: var(--text-muted);
38
+ }
39
+
40
+ .stat-card__value--positive { color: var(--positive); }
41
+ .stat-card__value--negative { color: var(--negative); }
42
+ .stat-card__value--accent { color: var(--accent-text); }
43
+ .stat-card__value--warning { color: var(--warning); }
44
+
45
+ .stat-card__unit {
46
+ font-size: var(--fs-11);
47
+ color: var(--text-muted);
48
+ margin-top: var(--space-2);
49
+ }
50
+
51
+ .stat-card__sub {
52
+ font-size: var(--fs-11);
53
+ color: var(--text-subtle);
54
+ margin-top: var(--space-4);
55
+ }