@klodd/ds 1.2.0 → 3.0.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,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,67 @@
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
+ .inline-edit__input {
52
+ display: inline-block;
53
+ height: 32px;
54
+ padding: 0 var(--space-10);
55
+ background: var(--surface-sunken);
56
+ border: 1px solid var(--border-default);
57
+ border-radius: var(--radius-8);
58
+ color: var(--text-default);
59
+ font-family: inherit;
60
+ font-size: 16px;
61
+ outline: none;
62
+ }
63
+
64
+ .inline-edit__input:focus {
65
+ border-color: var(--accent-9);
66
+ box-shadow: 0 0 0 3px var(--accent-a3);
67
+ }
@@ -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
+ }