@klodd/ds 3.5.5 → 3.5.6

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/SKILL.md CHANGED
@@ -113,4 +113,11 @@ list-row, tab-bar, nav, swipe-stack, inline-edit) - 11 nya selectorer
113
113
  fick outline 2px solid var(--border-focus) med outline-offset 2px. Plus
114
114
  .tab outline-offset normaliserad 1px->2px. input.css och .inline-edit__input
115
115
  ar dokumenterade undantag som behaller :focus (text-input-konvention).
116
- Sprint C fas 2 template-migration pagaar.)
116
+ v3.5.6 (Sprint F) konsoliderar BEM over 5 komponenter (card, dropdown,
117
+ hero-roll, overlay, nav) - 23 flat-hyphen element-klasser konverterade
118
+ till .block__element-syntax. Inkluderar JS-koordinering pa hero-roll,
119
+ sheet-drag, turbo-nav, nav-optimistic dar querySelector/classList
120
+ adresserar de bytta klasserna. .bottom-nav-item.active konverterad till
121
+ BEM-modifier .bottom-nav__item--active. tooltip-wrapper bevarad som
122
+ compound block per references/03-quality-bar.md regel 1. Sprint C fas 2
123
+ template-migration pagaar.)
@@ -5,8 +5,8 @@
5
5
  pa klickbara kort. .card--flush tar bort padding (anvand for
6
6
  inbaddat innehall som hanterar egen padding).
7
7
 
8
- Slot-konvention: .card-header / .card-body / .card-footer for
9
- strukturerat innehall. .card-divider for horisontell separator.
8
+ Slot-konvention: .card__header / .card__body / .card__footer for
9
+ strukturerat innehall. .card__divider for horisontell separator.
10
10
  ================================================================ */
11
11
 
12
12
 
@@ -54,7 +54,7 @@
54
54
 
55
55
  /* --flush tar bort default padding sa innehallet kan ga edge-to-edge.
56
56
  Anvand nar barn-element har egen padding (ex. lista med list-rows). */
57
- .card--flush > .card-body {
57
+ .card--flush > .card__body {
58
58
  padding: 0;
59
59
  }
60
60
 
@@ -62,24 +62,24 @@
62
62
  /* ================================================================
63
63
  ==== SLOTS
64
64
  Header och footer har samma padding som body men separator-linjer.
65
- Anvand .card-divider for visuell uppdelning inom samma slot.
65
+ Anvand .card__divider for visuell uppdelning inom samma slot.
66
66
  ================================================================ */
67
- .card-header {
67
+ .card__header {
68
68
  padding: var(--space-16) var(--space-16) var(--space-12);
69
69
  border-bottom: 1px solid var(--border-subtle);
70
70
  }
71
71
 
72
- .card-body {
72
+ .card__body {
73
73
  padding: var(--space-16);
74
74
  }
75
75
 
76
- .card-footer {
76
+ .card__footer {
77
77
  padding: var(--space-12) var(--space-16);
78
78
  border-top: 1px solid var(--border-subtle);
79
79
  background: var(--surface-default);
80
80
  }
81
81
 
82
- .card-divider {
82
+ .card__divider {
83
83
  height: 1px;
84
84
  background: var(--border-subtle);
85
85
  margin: 0 calc(-1 * var(--space-16));
@@ -1,15 +1,15 @@
1
1
  /* ================================================================
2
2
  components/dropdown.css
3
- Kontextuell meny. Wrapper med trigger + .dropdown-menu som
3
+ Kontextuell meny. Wrapper med trigger + .dropdown__menu som
4
4
  visas via .is-open-toggling fran JS.
5
5
 
6
6
  Markup-pattern:
7
7
  <div class="dropdown" data-dropdown>
8
8
  <button class="btn btn--icon" data-dropdown-trigger>...</button>
9
- <div class="dropdown-menu" role="menu">
10
- <button class="dropdown-item" role="menuitem">Item 1</button>
11
- <hr class="dropdown-divider">
12
- <button class="dropdown-item dropdown-item--danger">Ta bort</button>
9
+ <div class="dropdown__menu" role="menu">
10
+ <button class="dropdown__item" role="menuitem">Item 1</button>
11
+ <hr class="dropdown__divider">
12
+ <button class="dropdown__item dropdown__item--danger">Ta bort</button>
13
13
  </div>
14
14
  </div>
15
15
 
@@ -21,7 +21,7 @@
21
21
  display: inline-flex;
22
22
  }
23
23
 
24
- .dropdown-menu {
24
+ .dropdown__menu {
25
25
  position: absolute;
26
26
  top: calc(100% + var(--space-4));
27
27
  left: 0;
@@ -35,11 +35,11 @@
35
35
  display: none;
36
36
  }
37
37
 
38
- .dropdown.is-open .dropdown-menu {
38
+ .dropdown.is-open .dropdown__menu {
39
39
  display: block;
40
40
  }
41
41
 
42
- .dropdown-item {
42
+ .dropdown__item {
43
43
  display: flex;
44
44
  align-items: center;
45
45
  gap: var(--space-8);
@@ -56,32 +56,32 @@
56
56
  }
57
57
 
58
58
  @media (hover: hover) and (pointer: fine) {
59
- .dropdown-item:hover {
59
+ .dropdown__item:hover {
60
60
  background: var(--surface-hover);
61
61
  }
62
62
  }
63
63
 
64
- .dropdown-item:active {
64
+ .dropdown__item:active {
65
65
  background: var(--surface-active);
66
66
  }
67
67
 
68
- .dropdown-item:focus-visible {
68
+ .dropdown__item:focus-visible {
69
69
  outline: 2px solid var(--border-focus);
70
70
  outline-offset: -2px;
71
71
  }
72
72
 
73
- .dropdown-item[disabled],
74
- .dropdown-item:disabled {
73
+ .dropdown__item[disabled],
74
+ .dropdown__item:disabled {
75
75
  opacity: 0.5;
76
76
  cursor: not-allowed;
77
77
  pointer-events: none;
78
78
  }
79
79
 
80
- .dropdown-item--danger {
80
+ .dropdown__item--danger {
81
81
  color: var(--bg-danger);
82
82
  }
83
83
 
84
- .dropdown-divider {
84
+ .dropdown__divider {
85
85
  border: none;
86
86
  border-top: 1px solid var(--border-subtle);
87
87
  margin: var(--space-4) 0;
@@ -42,7 +42,7 @@
42
42
  En per siffra. Containrar en track av siffror som translateY:as
43
43
  till slutvardet. Overflow:hidden klipper allt utom synlig position.
44
44
  ================================================================ */
45
- .hero-digit-roller {
45
+ .hero-amount__digit-roller {
46
46
  display: inline-block;
47
47
  height: var(--hero-digit-height, 1em);
48
48
  line-height: var(--hero-digit-height, 1em);
@@ -54,8 +54,8 @@
54
54
  /* Vignett over och under sa siffrorna fadar ut nar de rullar in/ut.
55
55
  --hero-vignette-color satts av app-konsumenten om subtle fade
56
56
  onskas mot bg, default transparent. */
57
- .hero-digit-roller::before,
58
- .hero-digit-roller::after {
57
+ .hero-amount__digit-roller::before,
58
+ .hero-amount__digit-roller::after {
59
59
  content: '';
60
60
  position: absolute;
61
61
  left: 0;
@@ -66,7 +66,7 @@
66
66
  background: transparent;
67
67
  }
68
68
 
69
- .hero-digit-roller::before {
69
+ .hero-amount__digit-roller::before {
70
70
  top: 0;
71
71
  background: linear-gradient(
72
72
  to bottom,
@@ -75,7 +75,7 @@
75
75
  );
76
76
  }
77
77
 
78
- .hero-digit-roller::after {
78
+ .hero-amount__digit-roller::after {
79
79
  bottom: 0;
80
80
  background: linear-gradient(
81
81
  to top,
@@ -91,13 +91,13 @@
91
91
  transition + transform. tabular-nums upprepad pa span-niva som
92
92
  safety-net om hero-amount-arvet skulle brytas av nan parent.
93
93
  ================================================================ */
94
- .hero-digit-track {
94
+ .hero-amount__digit-track {
95
95
  display: flex;
96
96
  flex-direction: column;
97
97
  will-change: transform;
98
98
  }
99
99
 
100
- .hero-digit-track > span {
100
+ .hero-amount__digit-track > span {
101
101
  height: var(--hero-digit-height, 1em);
102
102
  line-height: var(--hero-digit-height, 1em);
103
103
  display: block;
@@ -110,7 +110,7 @@
110
110
  Mellanslag och "kr"-suffix runt rollers. white-space: pre bevarar
111
111
  exakta blanksteg.
112
112
  ================================================================ */
113
- .hero-static-char {
113
+ .hero-amount__static-char {
114
114
  display: inline-block;
115
115
  white-space: pre;
116
116
  }
@@ -123,7 +123,7 @@
123
123
  denna regel bara safety-net for befintliga inline-transitions.
124
124
  ================================================================ */
125
125
  @media (prefers-reduced-motion: reduce) {
126
- .hero-digit-track {
126
+ .hero-amount__digit-track {
127
127
  transition: none !important;
128
128
  }
129
129
  }
@@ -31,7 +31,7 @@
31
31
  border-radius: 0;
32
32
  }
33
33
 
34
- .bottom-nav-item {
34
+ .bottom-nav__item {
35
35
  display: flex;
36
36
  flex-direction: column;
37
37
  align-items: center;
@@ -51,22 +51,22 @@
51
51
  }
52
52
 
53
53
  @media (hover: hover) and (pointer: fine) {
54
- .bottom-nav-item:hover {
54
+ .bottom-nav__item:hover {
55
55
  color: var(--text-default);
56
56
  }
57
57
  }
58
58
 
59
- .bottom-nav-item:focus-visible {
59
+ .bottom-nav__item:focus-visible {
60
60
  outline: 2px solid var(--border-focus);
61
61
  outline-offset: 2px;
62
62
  }
63
63
 
64
- .bottom-nav-item.active {
64
+ .bottom-nav__item--active {
65
65
  color: var(--accent-text);
66
66
  }
67
67
 
68
- .bottom-nav-item .icon,
69
- .bottom-nav-item svg {
68
+ .bottom-nav__item .icon,
69
+ .bottom-nav__item svg {
70
70
  width: var(--space-20);
71
71
  height: var(--space-20);
72
72
  }
@@ -85,7 +85,7 @@
85
85
  margin-bottom: var(--space-16);
86
86
  }
87
87
 
88
- .topbar-back {
88
+ .topbar__back {
89
89
  display: inline-flex;
90
90
  align-items: center;
91
91
  justify-content: center;
@@ -102,17 +102,17 @@
102
102
  }
103
103
 
104
104
  @media (hover: hover) and (pointer: fine) {
105
- .topbar-back:hover {
105
+ .topbar__back:hover {
106
106
  background: var(--surface-hover);
107
107
  }
108
108
  }
109
109
 
110
- .topbar-back:focus-visible {
110
+ .topbar__back:focus-visible {
111
111
  outline: 2px solid var(--border-focus);
112
112
  outline-offset: 2px;
113
113
  }
114
114
 
115
- .topbar-title {
115
+ .topbar__title {
116
116
  flex: 1;
117
117
  min-width: 0;
118
118
  font-size: var(--fs-17);
@@ -125,7 +125,7 @@
125
125
  white-space: nowrap;
126
126
  }
127
127
 
128
- .topbar-action {
128
+ .topbar__action {
129
129
  display: inline-flex;
130
130
  align-items: center;
131
131
  justify-content: center;
@@ -141,12 +141,12 @@
141
141
  }
142
142
 
143
143
  @media (hover: hover) and (pointer: fine) {
144
- .topbar-action:hover {
144
+ .topbar__action:hover {
145
145
  color: var(--text-default);
146
146
  }
147
147
  }
148
148
 
149
- .topbar-action:focus-visible {
149
+ .topbar__action:focus-visible {
150
150
  outline: 2px solid var(--border-focus);
151
151
  outline-offset: 2px;
152
152
  }
@@ -13,9 +13,9 @@
13
13
  ==== DIALOG-BACKDROP
14
14
  Halvtransparent overlay med blur. Anvands av bade .dialog och
15
15
  .sheet. native ::backdrop pseudo-element (om <dialog>) eller en
16
- konkret <div class="dialog-backdrop"> for portal-baserade modaler.
16
+ konkret <div class="dialog__backdrop"> for portal-baserade modaler.
17
17
  ================================================================ */
18
- .dialog-backdrop,
18
+ .dialog__backdrop,
19
19
  dialog.dialog::backdrop,
20
20
  dialog.sheet::backdrop {
21
21
  background: color-mix(in oklch, var(--surface-page) 60%, transparent);
@@ -54,7 +54,7 @@ dialog.sheet::backdrop {
54
54
  inset: auto;
55
55
  }
56
56
 
57
- .dialog-header {
57
+ .dialog__header {
58
58
  display: flex;
59
59
  align-items: center;
60
60
  justify-content: space-between;
@@ -63,13 +63,13 @@ dialog.sheet::backdrop {
63
63
  border-bottom: 1px solid var(--border-subtle);
64
64
  }
65
65
 
66
- .dialog-body {
66
+ .dialog__body {
67
67
  padding: var(--space-20);
68
68
  overflow-y: auto;
69
69
  max-height: 60vh;
70
70
  }
71
71
 
72
- .dialog-footer {
72
+ .dialog__footer {
73
73
  display: flex;
74
74
  justify-content: flex-end;
75
75
  gap: var(--space-8);
@@ -111,7 +111,7 @@ dialog.sheet::backdrop {
111
111
  inset: auto 0 0 0;
112
112
  }
113
113
 
114
- .sheet-handle {
114
+ .sheet__handle {
115
115
  width: 32px;
116
116
  height: 4px;
117
117
  margin: 0 auto var(--space-16);
@@ -119,12 +119,12 @@ dialog.sheet::backdrop {
119
119
  border-radius: var(--radius-full);
120
120
  }
121
121
 
122
- .sheet-body {
122
+ .sheet__body {
123
123
  padding-top: var(--space-4);
124
124
  }
125
125
 
126
126
  /* Sheet-section divider for grupper inom samma sheet. */
127
- .sheet-divider {
127
+ .sheet__divider {
128
128
  height: 1px;
129
129
  background: var(--border-subtle);
130
130
  margin: var(--space-16) calc(-1 * var(--space-20));
@@ -13,7 +13,13 @@
13
13
  tooltip-elementet sa det inte snor klick fran wrappern.
14
14
 
15
15
  prefers-reduced-motion respekteras (opacity-fade tas bort).
16
- ================================================================ */
16
+
17
+ BEM-anteckning (Sprint F): .tooltip-wrapper ar ett COMPOUND BLOCK,
18
+ inte ett flat-element av .tooltip. Wrappern ar utanfor .tooltip i
19
+ DOM (parent, inte child). Compound-block-monstret foljer .hub-card-
20
+ konventionen per references/03-quality-bar.md regel 1 ("Block:
21
+ substantiv (.card, .banner, .hub-card)"). Ingen __wrapper-syntax
22
+ eftersom wrappern inte ar ett element AV tooltip. */
17
23
  .tooltip-wrapper {
18
24
  position: relative;
19
25
  display: inline-flex;
package/js/hero-roll.js CHANGED
@@ -77,10 +77,10 @@
77
77
 
78
78
  function buildRoller ( targetDigit ) {
79
79
  const roller = document.createElement( 'span' );
80
- roller.className = 'hero-digit-roller';
80
+ roller.className = 'hero-amount__digit-roller';
81
81
 
82
82
  const track = document.createElement( 'span' );
83
- track.className = 'hero-digit-track';
83
+ track.className = 'hero-amount__digit-track';
84
84
 
85
85
  const totalSteps = targetDigit + ( EXTRA_ROUNDS * 10 );
86
86
  for ( let i = 0; i <= totalSteps; i++ ) {
@@ -95,7 +95,7 @@
95
95
 
96
96
  function buildStaticChar ( text ) {
97
97
  const span = document.createElement( 'span' );
98
- span.className = 'hero-static-char';
98
+ span.className = 'hero-amount__static-char';
99
99
  span.textContent = text;
100
100
  return span;
101
101
  }
@@ -41,11 +41,11 @@
41
41
 
42
42
  const pod = e.target.closest( '.nav-pod' );
43
43
  if ( ! pod || ! nav.contains( pod ) ) return;
44
- if ( pod.classList.contains( 'active' ) ) return;
44
+ if ( pod.classList.contains( 'bottom-nav__item--active' ) ) return;
45
45
 
46
46
  const previousActive = nav.querySelector( '.nav-pod.active' );
47
- previousActive && previousActive.classList.remove( 'active' );
48
- pod.classList.add( 'active' );
47
+ previousActive && previousActive.classList.remove( 'bottom-nav__item--active' );
48
+ pod.classList.add( 'bottom-nav__item--active' );
49
49
 
50
50
  pendingNav = { from: previousActive, to: pod };
51
51
 
@@ -55,8 +55,8 @@
55
55
  clearTimeout( failsafeTimer );
56
56
  failsafeTimer = setTimeout( () => {
57
57
  if ( pendingNav ) {
58
- pendingNav.to.classList.remove( 'active' );
59
- pendingNav.from && pendingNav.from.classList.add( 'active' );
58
+ pendingNav.to.classList.remove( 'bottom-nav__item--active' );
59
+ pendingNav.from && pendingNav.from.classList.add( 'bottom-nav__item--active' );
60
60
  reset();
61
61
  }
62
62
  }, 3000 );
package/js/sheet-drag.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /*--------------------------------------------------------------
2
2
  Ekonom - Sheet drag-to-dismiss (Sprint C2).
3
3
 
4
- Pointer Events-baserad drag fran sheet-handle (eller sheet-toppen
4
+ Pointer Events-baserad drag fran sheet__handle (eller sheet-toppen
5
5
  nar sheet ar scrollad till topp). 1:1 tracking under drag.
6
6
  Threshold for dismiss: 40% av sheet-hojd ELLER velocity > 0.5 px/ms.
7
7
  Spring-back om under threshold (CSS bounce-easing).
@@ -22,7 +22,7 @@
22
22
  if (dialog.dataset.dragAttached) return;
23
23
  dialog.dataset.dragAttached = '1';
24
24
 
25
- const handle = dialog.querySelector('.sheet-handle');
25
+ const handle = dialog.querySelector('.sheet__handle');
26
26
  if (!handle) return;
27
27
 
28
28
  let dragging = false;
package/js/turbo-nav.js CHANGED
@@ -186,12 +186,12 @@
186
186
  if ( newNav && liveNav ) {
187
187
  const newActiveHref = newNav.querySelector( '.nav-pod.active' );
188
188
  const liveActive = liveNav.querySelector( '.nav-pod.active' );
189
- if ( liveActive ) liveActive.classList.remove( 'active' );
189
+ if ( liveActive ) liveActive.classList.remove( 'bottom-nav__item--active' );
190
190
  if ( newActiveHref ) {
191
191
  const target = liveNav.querySelector(
192
192
  'a[href="' + newActiveHref.getAttribute( 'href' ) + '"]'
193
193
  );
194
- if ( target ) target.classList.add( 'active' );
194
+ if ( target ) target.classList.add( 'bottom-nav__item--active' );
195
195
  }
196
196
  }
197
197
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@klodd/ds",
3
- "version": "3.5.5",
3
+ "version": "3.5.6",
4
4
  "description": "Klodd Design System - shared tokens, typography, components and JS for Jubb, Ekonom, and future apps. v3.5.3 (2026-05-09): tillagg .heading (17px medium tight) i base/typography.css for dialog-titlar och sheet-rubriker. Tackar luckan mellan .heading-2 (18px) och .heading-3 (15px) - matchar Ekonoms gamla .heading-class.",
5
5
  "main": "css/index.css",
6
6
  "bin": {
@@ -54,7 +54,7 @@ inga primitives. BEM-konvention (block__element--modifier).
54
54
  - **Tokens:** `currentColor` - parent-element styr fargen
55
55
 
56
56
  ### hero-roll (`hero-roll.css`)
57
- - **Klasser:** `.hero-amount[data-animate-roll]`, `.hero-digit-track`
57
+ - **Klasser:** `.hero-amount[data-animate-roll]`, `.hero-amount__digit-track`
58
58
  - **Anvand:** Display-siffer-animation pa hero-vyer (kodlas-rullning)
59
59
  - **INTE:** Vanliga numeriska varden (anvand `.hero__amount` utan data-animate-roll)
60
60
  - **Tokens:** `--text-default`, `--lh-tight`, `--ls-tightest`, `--fs-80`. **Undantag:** `font-weight: 600` (display-undantaget fran 400/500-policyn).