@klodd/ds 3.5.7 → 3.6.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.
@@ -1,15 +1,26 @@
1
1
  /* ================================================================
2
2
  components/chip.css
3
- Sma status-pills. .chip ar bas. Modifiers: --accent, --positive,
4
- --negative, --warning, --faint.
5
-
6
- Plus relaterade pill-mont:
7
- - .brand-pill: liten pill med projekt-namn
8
- - .month-pill: navigations-pill for manads-byte
9
- - .install-chip: PWA install-prompt floating-pill
10
- - .score-pill: ratings-pill (variants --strong/--medium/--low)
11
-
12
- .chip-list ar wrapper for flera chips i rad (form-edit-flode).
3
+ Pills- och chips-familjen: sex fristående blocks som delar
4
+ form-språket (rounded-full, kompakt padding, inline-flex).
5
+
6
+ Blocks:
7
+ .chip - generisk status-pill med dot-prefix (har modifiers)
8
+ .chip-list - sibling-wrapper för chips i rad (har __item/__delete/__add)
9
+ .brand-pill - projekt-namn-pill i topbar
10
+ .month-pill - navigations-pill för månadsbyte (Ekonom)
11
+ .score-pill - ratings-pill (NB: definieras även i badge.css - identiska regler)
12
+ .install-chip - PWA install-prompt som flyter ovan bottom-nav
13
+
14
+ HTML-relationer:
15
+ .chip-list innehåller .chip-list__item (egna BEM-element, ej .chip)
16
+ Övriga blocks är fristående och placeras där de behövs
17
+
18
+ Modifiers:
19
+ .chip --accent/-positive/-negative/-warning/-faint
20
+ .score-pill --strong/-medium/-low
21
+
22
+ .install-chip har egna BEM-element (__text/__install/__dismiss) plus
23
+ keyframe-animation install-chip-up (respekterar prefers-reduced-motion).
13
24
  ================================================================ */
14
25
  .chip {
15
26
  display: inline-flex;
@@ -1,14 +1,25 @@
1
1
  /* ================================================================
2
2
  components/collapsible.css
3
- Panel som expanderar pa klick. Anvands for budget-sektioner,
3
+ Panel som expanderar klick. Används för budget-sektioner,
4
4
  kategori-grupper, FAQ-rader.
5
5
 
6
- Element: .collapsible-card (root) som ar bas.
7
- - .collapsible__header klickbar header (button-element)
8
- - .collapsible__body expanderat innehall (hidden default)
9
- - .collapsible__chev chevron som roterar 180deg
6
+ Block:
7
+ .collapsible-card - root-block (huvud-container)
10
8
 
11
- State drivs via [data-expanded] attribut pa root - JS togglar.
9
+ BEM-element av blocket:
10
+ .collapsible__header - klickbar header (button-element)
11
+ .collapsible__header-text - text-wrapper i header
12
+ .collapsible__body - expanderat innehåll (hidden default)
13
+ .collapsible__chev - chevron som roterar 180deg
14
+
15
+ ANTECKNING (BEM-stam-mismatch, öppen punkt):
16
+ Blocket heter .collapsible-card men elementen heter .collapsible__X
17
+ (utan -card-suffix). Två lösningar finns: rename block till
18
+ .collapsible eller rename element till .collapsible-card__X.
19
+ Underlag finns i sprint-rapport 2026-05-09. Ingen rename i fas 1.
20
+
21
+ States:
22
+ [data-expanded] på .collapsible-card - JS togglar, roterar __chev 180deg
12
23
  ================================================================ */
13
24
  .collapsible-card {
14
25
  background: var(--surface-raised);
@@ -1,7 +1,26 @@
1
1
  /* ================================================================
2
2
  components/feedback.css
3
- Toast, empty-state, skeleton-loader, spinner.
4
- Komponenter for transient feedback och loading-states.
3
+ Transient feedback och loading-states: fyra fristående blocks som
4
+ tematiskt hör ihop (status- eller loading-feedback) men används
5
+ oberoende i HTML.
6
+
7
+ Blocks:
8
+ .toast - transient meddelande (ankrat top-center via toast-region)
9
+ .empty-state - centrerad ikon + rubrik + text för tomma listor
10
+ .skeleton - loading-placeholder med pulse-animation
11
+ .spinner - roterande loader (inline-block)
12
+
13
+ Inga inbördes HTML-relationer - alla fyra placeras självständigt.
14
+ .toast och .empty-state har egna BEM-element (__title/__text/__icon).
15
+ .skeleton och .spinner har bara modifiers.
16
+
17
+ Modifiers:
18
+ .toast --success/-error/-warning
19
+ .skeleton --text/-circle/-card
20
+ .spinner --sm/-lg
21
+
22
+ Alla fyra respekterar prefers-reduced-motion (animation tas bort
23
+ eller saktas ned).
5
24
  ================================================================ */
6
25
 
7
26
 
@@ -1,9 +1,23 @@
1
1
  /* ================================================================
2
2
  components/form.css
3
- Form-skelett. .form-section, .form-group, .form-row.
3
+ Form-skelett: wrapper-strukturen som gör formuläret komplett.
4
+ Skiljer sig från input.css (input-elementen själva).
4
5
 
5
- Skiljer sig fran input.css (input-elementen). form.css ar
6
- wrapper-strukturen som gor formularet komplett.
6
+ Blocks:
7
+ .form-card - kort-style wrapper för forms (max-width 480px)
8
+ .form-section - sektion-grupp inom form (har __title)
9
+ .form-group - field-grupp: label + input (har __label)
10
+ .form-hint - help-text under field (atomisk)
11
+ .form-row - horisontell field-rad (grid-baserad, har --inline)
12
+
13
+ Alla fem är fristående blocks. .form-section och .form-group har
14
+ egna BEM-element (__title, __label). De kombineras fritt - ingen
15
+ tvingad hierarki i CSS:en.
16
+
17
+ HTML-relationer (vanligt mönster, ej tvingande):
18
+ .form-card > .form-section > .form-group > .form-row > <inputs>
19
+
20
+ Modifiers: .form-row har --inline (flex-wrap-variant).
7
21
  ================================================================ */
8
22
  .form-card {
9
23
  background: var(--surface-raised);
@@ -1,14 +1,23 @@
1
1
  /* ================================================================
2
2
  components/hero.css
3
- Stora display-rubriker med amount + meta. Anvands pa dashboard,
3
+ Stora display-rubriker med amount + meta. Används dashboard,
4
4
  detaljvyer, primary-page-toppar.
5
5
 
6
- Element: .hero (wrapper), .hero__heading, .hero__amount (default 80px),
7
- .hero__amount--card (40px sekundar), .hero__amount-row, .hero__label,
8
- .hero__label--muted, .hero__meta, .hero__actions.
6
+ Blocks:
7
+ .hero - wrapper med padding och text-alignment (huvud-block)
8
+ .hero-amount - sibling-block: hero-roll-animations-target
9
9
 
10
- .hero-amount och .hero__amount-roll anvands av hero-roll-animation
11
- - se components/hero-roll.css for animation-styling.
10
+ .hero har BEM-element (__heading/__amount/__amount-row/__label/__meta/__actions).
11
+ .hero-amount är ett separat root-block av historiska skäl - hero-roll-
12
+ animationen adresserar just klassen .hero-amount[data-animate-roll],
13
+ inte .hero__amount. Definieras även i hero-roll.css (animation-styling).
14
+
15
+ Modifiers:
16
+ .hero__amount --card (40px sekundär), --fluid (clamp 40-80px)
17
+ .hero__label --muted
18
+
19
+ Se components/hero-roll.css för digit-roller-styling när
20
+ data-animate-roll triggar animationen.
12
21
  ================================================================ */
13
22
  .hero {
14
23
  padding: var(--space-20) var(--space-4) var(--space-24);
@@ -1,11 +1,20 @@
1
1
  /* ================================================================
2
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.
3
+ Settings-hub-navigation: kort-listor som länkar till sub-sidor.
4
+ Layout per kort: ikon + titel + subtitle + chevron. Hela kortet
5
+ är klickbart.
6
6
 
7
- .hub-list samlar flera hub-cards i en kolumn.
8
- .hub-category ar group-rubrik over flera kort.
7
+ Blocks:
8
+ .hub-card - klickbart kort (huvud-block med BEM-element)
9
+ .hub-list - sibling-wrapper: <ul> som samlar flera hub-cards
10
+ .hub-category - sibling-block: <h6>-rubrik över en hub-list-grupp
11
+
12
+ HTML-relationer:
13
+ .hub-list innehåller flera <li> med .hub-card
14
+ .hub-category placeras som sibling FÖRE .hub-list (inte inuti)
15
+
16
+ Bara .hub-card har egna BEM-element (__icon/__text/__title/__subtitle/__chev).
17
+ .hub-list och .hub-category är fristående blocks utan egna element.
9
18
  ================================================================ */
10
19
  .hub-list {
11
20
  display: flex;
@@ -1,12 +1,27 @@
1
1
  /* ================================================================
2
2
  components/input.css
3
- .input + .textarea + .select med konsekvent styling.
4
- States: :focus, :disabled, [aria-invalid="true"] (error).
5
- Tillagg: .input-group (label + input + error), .input-icon (input
6
- med leading ikon).
3
+ Form-fält med iOS-zoom-skydd (17px font-size).
7
4
 
8
- Regel: font-size 17px sa iOS Safari inte auto-zoomar in vid focus.
9
- Aldrig under 16px pa input-element.
5
+ Blocks:
6
+ .input - text-input-element (single-line)
7
+ .textarea - textarea-element (multi-line)
8
+ .select - select-element med custom chevron-bg
9
+ .input-group - sibling-wrapper: label + input + hint/error
10
+ .input-icon - sibling-wrapper: leading-ikon + input
11
+
12
+ .input/.textarea/.select delar bas-styling via comma-selector.
13
+ .input-group och .input-icon är fristående blocks, inte BEM-element
14
+ av .input. I HTML ligger ett .input-element som child inuti
15
+ wrapper-blocken (DOM-konvention, inte BEM-relation).
16
+
17
+ Modifiers: inga klassiska BEM-modifiers - tillstånd via [aria-invalid].
18
+
19
+ States på .input/.textarea/.select: :focus, :disabled, [aria-invalid="true"].
20
+ Text-inputs använder :focus istället för :focus-visible som dokumenterat
21
+ undantag (Radix UI/MUI/shadcn-konvention).
22
+
23
+ Regel: font-size 17px så iOS Safari inte auto-zoomar vid focus.
24
+ Aldrig under 16px på input-element.
10
25
  ================================================================ */
11
26
 
12
27
 
@@ -1,17 +1,27 @@
1
1
  /* ================================================================
2
2
  components/list-row.css
3
- Generisk list-rad med ikon + body + amount. Anvands for transaktioner,
3
+ Generisk list-rad med ikon + body + amount. Används för transaktioner,
4
4
  subscriptions, audit-logs, jobblistor.
5
5
 
6
6
  Tidigare hette komponenten .tx-row (transaction) - nu generaliserad
7
- till .list-row sa inte affarsdomanen sipprar in i namnet.
7
+ till .list-row inte affärsdomänen sipprar in i namnet.
8
8
 
9
- Element: .list-row__icon, .list-row__body, .list-row__desc,
10
- .list-row__amount, .list-row__date, .list-row__meta.
9
+ Blocks:
10
+ .list - sibling-wrapper: <ul>-reset (list-style none, no padding)
11
+ .list-row - själva raden (huvud-block med BEM-element)
11
12
 
12
- Modifiers: --excluded (greyed out), --pending (with dashed border).
13
+ HTML-relationer:
14
+ .list innehåller flera <li> med .list-row (vanligt men ej tvingande)
15
+ .list-row kan också användas fristående utanför .list
13
16
 
14
- App-specifika domain-overrides (kategori-fargade ikoner) lever i
17
+ .list-row har element __icon/__body/__desc/__date/__amount/__meta.
18
+ .list är atomisk (ingen __element).
19
+
20
+ Modifiers:
21
+ .list-row --excluded (greyed out), --pending (dashed border), --clickable
22
+ .list-row__amount --positive/-negative
23
+
24
+ App-specifika domain-overrides (kategori-färgade ikoner) lever i
15
25
  app-repots egna CSS - inte i paketet.
16
26
  ================================================================ */
17
27
  .list {
@@ -1,9 +1,22 @@
1
1
  /* ================================================================
2
2
  components/nav.css
3
- Bottom-nav, topbar och tab-bar - tre standardnavigations-monster.
3
+ Tva navigations-blocks: fixed bottom-nav och in-flow topbar.
4
+ Tab-bar och .tab-bar__item lever i components/tab-bar.css.
4
5
 
5
- Bottom-nav ar position:fixed och ALLTID synlig pa mobil. Topbar
6
- ar in-flow under safe-area. Tab-bar ar inline (inom en panel).
6
+ Blocks:
7
+ .bottom-nav - position:fixed pa mobil-botten (har __item)
8
+ .topbar - in-flow header under safe-area (har __back/__title/__action)
9
+
10
+ HTML-relationer:
11
+ .bottom-nav > .bottom-nav__item (BEM-element)
12
+ .topbar > .topbar__back/__title/__action (BEM-element)
13
+
14
+ Modifiers/States:
15
+ .bottom-nav__item--active - aktiv pod (Sprint F BEM-konvertering)
16
+
17
+ Sprint 1 (3.6.0): den gamla flat-form-varianten .tab + .tab-bar i
18
+ denna fil togs bort. Den hade min-height: 36px under WCAG-kravet
19
+ 44px. Kanonisk tab-komponent: .tab-bar__item i tab-bar.css.
7
20
  ================================================================ */
8
21
 
9
22
 
@@ -150,53 +163,3 @@
150
163
  outline: 2px solid var(--border-focus);
151
164
  outline-offset: 2px;
152
165
  }
153
-
154
-
155
- /* ================================================================
156
- ==== TAB-BAR (inline tabs i panel)
157
- Segmented control monster. Active-tab har highlighted bg.
158
- ================================================================ */
159
- .tab-bar {
160
- display: flex;
161
- gap: var(--space-4);
162
- padding: var(--space-4);
163
- background: var(--surface-default);
164
- border-radius: var(--radius-12);
165
- }
166
-
167
- .tab {
168
- flex: 1;
169
- display: inline-flex;
170
- align-items: center;
171
- justify-content: center;
172
- min-height: 36px;
173
- padding: 0 var(--space-12);
174
- font-family: inherit;
175
- font-size: var(--fs-13);
176
- font-weight: var(--fw-medium);
177
- color: var(--text-subtle);
178
- background: transparent;
179
- border: 0;
180
- border-radius: var(--radius-8);
181
- cursor: pointer;
182
- text-decoration: none;
183
- transition:
184
- background var(--dur-fast) var(--ease-spring-snappy),
185
- color var(--dur-fast) var(--ease-spring-snappy);
186
- }
187
-
188
- @media (hover: hover) and (pointer: fine) {
189
- .tab:not(.active):hover {
190
- color: var(--text-default);
191
- }
192
- }
193
-
194
- .tab.active {
195
- background: var(--surface-raised);
196
- color: var(--text-default);
197
- }
198
-
199
- .tab:focus-visible {
200
- outline: 2px solid var(--border-focus);
201
- outline-offset: 2px;
202
- }
@@ -1,17 +1,29 @@
1
1
  /* ================================================================
2
2
  components/progress.css
3
- Linjar progress-indikator. Anvands for budget-burndown, upload-
4
- status, multi-step-flows. Modifiers for status-fargning.
3
+ Linjär progress-indikator. Används för budget-burndown, upload-
4
+ status, multi-step-flows.
5
5
 
6
- .progress ar wrappern (track), .progress-bar ar fyllnaden.
7
- Sätt width via inline style eller data-attribut + JS (CSP-safe).
6
+ Blocks:
7
+ .progress - track (wrapper, surface-raised bg)
8
+ .progress-bar - fyllning (eget block, alltid DOM-child av .progress)
8
9
 
9
- Brief-pattern fran Ekonom:
10
+ HTML-relationer:
11
+ .progress-bar placeras alltid som child inuti .progress i HTML.
12
+ CSS-mässigt fristående block - flat-namnet behålls av historiska
13
+ skäl (inte .progress__bar). Se references/03-quality-bar.md
14
+ regel 11 om fil med flera root-blocks.
15
+
16
+ Modifiers:
17
+ .progress-bar --success/-warning/-danger
18
+
19
+ Bredd via CSP-safe pattern (bar-styles.js applicerar style.width
20
+ från data-bar-width vid runtime):
10
21
  <div class="progress">
11
22
  <div class="progress-bar progress-bar--warning"
12
23
  data-bar-width="73%"></div>
13
24
  </div>
14
- bar-styles.js applicerar style.width fran data-bar-width.
25
+
26
+ Respekterar prefers-reduced-motion (transition tas bort).
15
27
  ================================================================ */
16
28
  .progress {
17
29
  width: 100%;
@@ -1,10 +1,19 @@
1
1
  /* ================================================================
2
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).
3
+ Små kort med stor siffra + label. Används för read-only metric-display.
5
4
 
6
- .stat-card ar nyare BEM-versionen. .metric-card behalls for
7
- bakatkompat med befintliga vyer som anvander metric-grid.
5
+ Blocks:
6
+ .stat-grid - grid-container (2 kol mobil, 4 desktop)
7
+ .stat-card - kort med siffra + label (huvud-block med BEM-element)
8
+
9
+ HTML-relationer:
10
+ .stat-grid > .stat-card (multipel, layout-grid)
11
+
12
+ .stat-card har element __value/__label/__unit/__sub.
13
+
14
+ Modifiers:
15
+ .stat-grid --single (1-kol-grid)
16
+ .stat-card__value --positive/-negative/-accent/-warning
8
17
  ================================================================ */
9
18
  .stat-grid {
10
19
  display: grid;
@@ -1,23 +1,42 @@
1
1
  /* ================================================================
2
2
  components/swipe-stack.css
3
- Tinder-stil swipe-card-stack med drag-physics. Anvands for
3
+ Tinder-stil swipe-card-stack med drag-physics. Används för
4
4
  triage-flow, decision-cards, tutorial-stacks.
5
5
 
6
- Klassnamn ar generiska (.swipe-*) - inte vy-specifika (.triage-*).
7
- App-repots vyer applicerar dessa pa sina specifika data-cards.
8
-
9
- Element:
10
- - .swipe-stack: container med relative position
11
- - .swipe-card: individuellt kort (absolute positionerat)
12
- - .swipe-card__header: ovre header-omrade
13
- - .swipe-card__body: huvud-innehall
14
- - .swipe-card__footer: nedre actions-rad
15
- - .swipe-card__back: nasta kort i stacken (visuellt bakom)
16
- - .swipe-decision-overlay: overlay med "spara"/"avfard" indikator
17
- - .swipe-actions: knapp-rad under stacken
18
- - .swipe-meta: kort-meta-info
19
- - .swipe-progress: progress-indikator
20
- - .swipe-empty: tomt-state
6
+ Klassnamn är generiska (.swipe-*) - inte vy-specifika (.triage-*).
7
+ App-repots vyer applicerar dessa sina specifika data-cards.
8
+
9
+ Blocks (10 fristående blocks i swipe-familjen):
10
+
11
+ Stack och kort:
12
+ .swipe-stack - container med relative position
13
+ .swipe-card - individuellt kort (absolute positionerat, har BEM-element)
14
+
15
+ Decision-overlays och actions:
16
+ .swipe-decision-overlay - overlay med "spara"/"avfärd"-indikator
17
+ .swipe-actions - knapp-rad under stacken
18
+ .swipe-action-btn - rund knapp i swipe-actions
19
+
20
+ Meta och feedback:
21
+ .swipe-meta - kort-meta-info (inline-flex)
22
+ .swipe-meta-sep - dot-separator mellan meta-items
23
+ .swipe-progress - text "X av Y"
24
+ .swipe-empty - tomt-state när stacken är klar
25
+ .swipe-hint - hint-text (t.ex. "Svep åt sidan")
26
+
27
+ HTML-relationer:
28
+ .swipe-stack > .swipe-card (multipel, absolute positionerade)
29
+ .swipe-card > .swipe-decision-overlay (overlay i kortet)
30
+ .swipe-actions > .swipe-action-btn (multipel)
31
+ Övriga är fristående.
32
+
33
+ Bara .swipe-card har egna BEM-element (__header/__title/__body/__footer).
34
+ Övriga blocks är atomiska eller har bara modifiers.
35
+
36
+ Modifiers:
37
+ .swipe-card --back/-gone
38
+ .swipe-decision-overlay --save/-dismiss/-visible
39
+ .swipe-action-btn --save/-dismiss
21
40
  ================================================================ */
22
41
  .swipe-stack {
23
42
  position: relative;
@@ -61,3 +61,10 @@
61
61
  outline: 2px solid var(--border-focus);
62
62
  outline-offset: 2px;
63
63
  }
64
+
65
+ .tab-bar__item:disabled,
66
+ .tab-bar__item[aria-disabled="true"] {
67
+ opacity: 0.5;
68
+ cursor: not-allowed;
69
+ pointer-events: none;
70
+ }
@@ -1,10 +1,24 @@
1
1
  /* ================================================================
2
2
  components/upload-spinner.css
3
- Stor loading-overlay som tacker viewport. Anvands for OCR-uploads,
4
- AI-anrop och andra langa async-operations dar appen ar blockerad.
3
+ Viewport-overlay för långa async-operations (OCR, AI-anrop, andra
4
+ där appen är visuellt blockerad).
5
5
 
6
- .upload-spinner-overlay ar fixed-positionerat overlay som visas
7
- nar .is-visible-klassen togglas via JS.
6
+ Blocks:
7
+ .upload-spinner-overlay - fixed-positionerat overlay (huvud-block)
8
+ .upload-spinner - själva spinner-cirkeln (atomisk)
9
+
10
+ HTML-relationer:
11
+ .upload-spinner-overlay > .upload-spinner + label + hint
12
+ (spinner ligger inuti overlay, men är ett separat CSS-block)
13
+
14
+ .upload-spinner-overlay har BEM-element __label/__hint plus
15
+ .is-visible state-class (JS togglar för display: flex).
16
+ .upload-spinner är atomisk - används bara som child av overlay.
17
+
18
+ States:
19
+ .upload-spinner-overlay.is-visible - visa overlay (display: flex)
20
+
21
+ Animation upload-spinner-rotate respekterar prefers-reduced-motion.
8
22
  ================================================================ */
9
23
  .upload-spinner-overlay {
10
24
  position: fixed;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@klodd/ds",
3
- "version": "3.5.7",
3
+ "version": "3.6.0",
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": {
@@ -1,84 +1,116 @@
1
1
  # Komponentkatalog
2
2
 
3
- 33 komponenter i `@klodd/ds@3.x`. Alla refererar bara semantic tokens -
3
+ 35 komponent-filer i `@klodd/ds@3.x`. Alla refererar bara semantic tokens -
4
4
  inga primitives. BEM-konvention (block__element--modifier).
5
5
 
6
+ ## Klassificeringsformat
7
+
8
+ För varje entry gäller:
9
+
10
+ - **Blocks:** root-blocks i filen. Flera blocks kan dela en fil när de är
11
+ semantiskt relaterade (se `references/03-quality-bar.md` regel 11).
12
+ Sibling-relation eller wrapper-roll noteras i parentes.
13
+ - **Element:** BEM-element (`block__element`). Listas bara om de finns.
14
+ - **Modifiers:** BEM-modifiers (`block--modifier`). Listas bara om de finns.
15
+ - **States:** state-classes (`.is-X`) eller attribut-states (`[data-X]`).
16
+ Listas bara om de finns.
17
+
6
18
  ## Grundkomponenter
7
19
 
8
20
  ### button (`button.css`)
9
- - **Klasser:** `.btn`, `.btn--primary/-secondary/-ghost/-danger`, `.btn--sm/-lg/-icon/-circle`, `.btn--loading`
21
+ - **Blocks:** `.btn`
22
+ - **Modifiers:** `.btn--primary/-secondary/-ghost/-danger`, `.btn--sm/-lg/-icon/-circle`, `.btn--block/-add`, `.btn--loading`
10
23
  - **Anvand:** alla aktioner med tap-target >=44px
11
24
  - **INTE:** Cirkel-link i topbar (anvand `.btn--icon.btn--circle`)
12
25
  - **Tokens:** `--surface-default/-hover/-active`, `--text-default/-on-accent`, `--border-default/-focus`, `--accent-9/-10`, `--bg-danger`, `--touch-min`
13
26
 
14
27
  ### input (`input.css`)
15
- - **Klasser:** `.input`, `.textarea`, `.select`, `.input-group__label/__hint/__error`, `.input-icon`
28
+ - **Blocks:** `.input`, `.textarea`, `.select`, `.input-group` (sibling-wrapper for label + input + hint/error), `.input-icon` (sibling-wrapper for input med leading ikon)
29
+ - **Element:** `.input-group__label`, `.input-group__hint`, `.input-group__error`
30
+ - **States:** `:focus`, `:disabled`, `[aria-invalid="true"]` (text-inputs anvander `:focus` istallet for `:focus-visible` per dokumenterat undantag)
16
31
  - **Anvand:** form-falt med 17px font-size (anti iOS auto-zoom)
17
32
  - **INTE:** Inline-edit-pattern (anvand `.inline-edit__input`)
18
33
  - **Tokens:** `--surface-sunken/-default`, `--accent-9`, `--accent-a3` (focus-ring), `--bg-danger` (error-state)
19
34
 
20
35
  ### badge (`badge.css`)
21
- - **Klasser:** `.badge`, `.badge--success/-warning/-danger/-accent`, `.score-pill`, `.score-pill--strong/-medium/-low`
36
+ - **Blocks:** `.badge`, `.score-pill` (sibling, definieras aven i `chip.css` med identiska regler)
37
+ - **Modifiers:** `.badge--neutral/-success/-warning/-danger/-accent`, `.score-pill--strong/-medium/-low`
22
38
  - **Anvand:** Status-pills (statiska)
23
39
  - **INTE:** Klickbara chips (anvand `.chip`)
24
40
  - **Tokens:** `--positive/-dim/-border`, `--warning/-dim/-border`, `--bg-danger`, `--accent-text/-a2/-a6`
25
41
 
26
42
  ### card (`card.css`)
27
- - **Klasser:** `.card`, `.card--interactive/-flush`, `.card-header/-body/-footer/-divider`
43
+ - **Blocks:** `.card`
44
+ - **Element:** `.card__header`, `.card__body`, `.card__footer`, `.card__divider`
45
+ - **Modifiers:** `.card--interactive`, `.card--flush`
28
46
  - **Anvand:** Standardcontainer for paneler. `--interactive` ger hover/press-feedback
29
47
  - **INTE:** Settings-hub-kort (anvand `.hub-card`)
30
48
  - **Tokens:** `--surface-raised/-overlay/-hover`, `--border-subtle/-default/-focus`
31
49
 
32
50
  ### nav (`nav.css`)
33
- - **Klasser:** `.bottom-nav`, `.bottom-nav-item.active`, `.topbar`, `.topbar-back/-title/-action`, `.tab-bar`, `.tab.active`
51
+ - **Blocks:** `.bottom-nav`, `.topbar`, `.tab-bar`, `.tab` (child av tab-bar)
52
+ - **Element:** `.bottom-nav__item`, `.topbar__back`, `.topbar__title`, `.topbar__action`
53
+ - **Modifiers:** `.bottom-nav__item--active` (Sprint F BEM-konvertering)
54
+ - **States:** `.tab.active`
34
55
  - **Anvand:** Mobile bottom-nav (fixed), in-flow topbar, segmented tabs
35
- - **INTE:** Generisk navigations-meny (anvand `.dropdown`)
56
+ - **INTE:** Generisk navigations-meny (anvand `.dropdown`). For utokad tab-bar med 44px touch-target, anvand `.tab-bar__item` fran `tab-bar.css`
36
57
  - **Tokens:** `--surface-default`, `--text-muted/-default`, `--accent-text` (active), `--border-subtle/-focus`, `--touch-min`, `--safe-bottom`
37
58
 
38
59
  ### feedback (`feedback.css`)
39
- - **Klasser:** `.toast`, `.toast--success/-error/-warning`, `.empty-state`, `.skeleton`, `.skeleton--text/-circle/-card`, `.spinner`
60
+ - **Blocks:** `.toast`, `.empty-state`, `.skeleton`, `.spinner` (fyra fristaende blocks i samma fil - feedback-familjen)
61
+ - **Element:** `.empty-state__icon`, `.empty-state__title`, `.empty-state__text`
62
+ - **Modifiers:** `.toast--success/-error/-warning`, `.skeleton--text/-circle/-card`, `.spinner--sm/-lg`
40
63
  - **Anvand:** Transient feedback + loading-states
41
64
  - **INTE:** Inline error-meddelanden (anvand `.input-group__error`)
42
65
  - **Tokens:** `--surface-overlay`, `--bg-success/-warning/-danger`, `--text-on-status`, `--shadow-float`. Respekterar `prefers-reduced-motion`.
43
66
 
44
67
  ### overlay (`overlay.css`)
45
- - **Klasser:** `.dialog`, `.sheet`, `.dialog-backdrop` (med cursor: pointer), `.dialog-header/-body/-footer`, `.sheet-handle/-body/-divider`
68
+ - **Blocks:** `.dialog`, `.sheet` (sibling - tva olika overlay-monster i samma fil)
69
+ - **Element:** `.dialog__backdrop`, `.dialog__header`, `.dialog__body`, `.dialog__footer`, `.sheet__handle`, `.sheet__body`, `.sheet__divider`
46
70
  - **Anvand:** Native `<dialog>` (centrerad modal) eller `<dialog class="sheet">` (bottom-attached)
47
71
  - **INTE:** Tooltip eller dropdown (egna komponenter)
48
72
  - **Tokens:** `--surface-raised/-overlay`, `--border-subtle`, `--shadow-float`, `--z-overlay`, `--safe-bottom`
49
73
 
50
74
  ### icon (`icon.css`)
51
- - **Klasser:** `.icon`, `.icon--xs/-sm/-md/-lg/-xl`, `.icon-custom`
75
+ - **Blocks:** `.icon`, `.icon-custom` (sibling - wrapper for handritade SVG som Lucide saknar)
76
+ - **Modifiers:** `.icon--xs/-sm/-md/-lg/-xl`
52
77
  - **Anvand:** Lucide via CDN (cdn.jsdelivr.net) ELLER inline-SVG via `.icon-custom`
53
78
  - **INTE:** Inline `style="width:Xpx"` pa ikoner (anvand size-modifier)
54
79
  - **Tokens:** `currentColor` - parent-element styr fargen
55
80
 
56
81
  ### hero-roll (`hero-roll.css`)
57
- - **Klasser:** `.hero-amount[data-animate-roll]`, `.hero-amount__digit-track`
82
+ - **Blocks:** `.hero-amount` (definieras aven i `hero.css`)
83
+ - **Element:** `.hero-amount__digit-track`
84
+ - **States:** `[data-animate-roll]` pa `.hero-amount` (JS triggar animation)
58
85
  - **Anvand:** Display-siffer-animation pa hero-vyer (kodlas-rullning)
59
86
  - **INTE:** Vanliga numeriska varden (anvand `.hero__amount` utan data-animate-roll)
60
87
  - **Tokens:** `--text-default`, `--lh-tight`, `--ls-tightest`, `--fs-80`. **Undantag:** `font-weight: 600` (display-undantaget fran 400/500-policyn).
61
88
 
62
89
  ### divider (`divider.css`)
63
- - **Klasser:** `.divider`, `.divider--vertical/-strong`
90
+ - **Blocks:** `.divider`
91
+ - **Modifiers:** `.divider--vertical`, `.divider--strong`
64
92
  - **Anvand:** Horisontell eller vertikal separator
65
- - **INTE:** Visuell separator inom card (anvand `.card-divider`)
93
+ - **INTE:** Visuell separator inom card (anvand `.card__divider`)
66
94
  - **Tokens:** `--border-subtle/-default`
67
95
 
68
96
  ### progress (`progress.css`)
69
- - **Klasser:** `.progress`, `.progress-bar`, `.progress-bar--success/-warning/-danger`
97
+ - **Blocks:** `.progress` (track), `.progress-bar` (fyllning, alltid DOM-child av `.progress`)
98
+ - **Modifiers:** `.progress-bar--success/-warning/-danger`
70
99
  - **Anvand:** Linjar progress med data-bar-width-pattern (CSP-safe via bar-styles.js)
71
100
  - **INTE:** Progress med text-overlay (eget komposit-pattern)
72
101
  - **Tokens:** `--surface-raised`, `--accent-9`, `--bg-success/-warning/-danger`. Respekterar `prefers-reduced-motion`.
73
102
 
74
103
  ### tooltip (`tooltip.css`)
75
- - **Klasser:** `.tooltip-wrapper`, `.tooltip`
104
+ - **Blocks:** `.tooltip-wrapper` (compound block, parent i DOM), `.tooltip` (child i DOM, eget CSS-block)
76
105
  - **Anvand:** Pure-CSS tooltip via `:hover/:focus-within` pa wrappern
77
106
  - **INTE:** Long-content tooltips (anvand `.dialog`)
78
107
  - **Tokens:** `--surface-overlay`, `--text-default`, `--border-default`, `--z-tooltip`
108
+ - **Special:** `.tooltip-wrapper` ar compound block, INTE flat-element av `.tooltip`. Wrappern ar utanfor `.tooltip` i DOM (parent, inte child).
79
109
 
80
110
  ### dropdown (`dropdown.css`)
81
- - **Klasser:** `.dropdown.is-open`, `.dropdown-menu`, `.dropdown-item`, `.dropdown-item--danger`, `.dropdown-divider`
111
+ - **Blocks:** `.dropdown`, `.dropdown-menu`, `.dropdown-item`, `.dropdown-divider` (siblings i dropdown-familjen)
112
+ - **Modifiers:** `.dropdown-item--danger`
113
+ - **States:** `.dropdown.is-open`, `.dropdown.is-open-toggling`
82
114
  - **Anvand:** Kontextuell meny (kebab/more-actions). JS togglar `.is-open`
83
115
  - **INTE:** Permanent visible navigation (anvand `.nav` eller `.tab-bar`)
84
116
  - **Tokens:** `--surface-overlay/-hover/-active`, `--text-default`, `--border-default/-subtle/-focus`, `--bg-danger` (item--danger), `--z-dropdown`
@@ -87,103 +119,140 @@ inga primitives. BEM-konvention (block__element--modifier).
87
119
  ## Layout-komponenter (v3.0.0+)
88
120
 
89
121
  ### banner (`banner.css`)
90
- - **Klasser:** `.banner`, `.banner--hero/-accent/-positive/-negative/-warning`, `.banner__title/__sub/__content`
122
+ - **Blocks:** `.banner`
123
+ - **Element:** `.banner__title`, `.banner__sub`, `.banner__content`
124
+ - **Modifiers:** `.banner--hero/-accent/-positive/-negative/-warning`
91
125
  - **Anvand:** Bred informations-rad i flode (top-of-page eller mellan sektioner)
92
126
  - **INTE:** Toast-notifikation (anvand `.toast`)
93
127
 
94
128
  ### panel (`panel.css`)
95
- - **Klasser:** `.panel`, `.panel--info/-info-warning/-danger/-attention`, `.panel__title/__title-row/__title-meta/__title-link/__step-row/__step-badge`
129
+ - **Blocks:** `.panel`
130
+ - **Element:** `.panel__title`, `.panel__title-row`, `.panel__title-meta`, `.panel__title-link`, `.panel__header-row`, `.panel__step-row`, `.panel__step-badge`, `.panel__pill`
131
+ - **Modifiers:** `.panel--info`, `.panel--info-warning`, `.panel--danger`, `.panel--attention`
96
132
  - **Anvand:** Sektion med ramad styling och titel
97
133
  - **INTE:** Klickbart kort (anvand `.card--interactive`)
98
134
 
99
135
  ### hub-card (`hub-card.css`)
100
- - **Klasser:** `.hub-card`, `.hub-card__icon/__text/__title/__subtitle/__chev`, `.hub-list`, `.hub-category`
136
+ - **Blocks:** `.hub-card`, `.hub-list` (sibling-wrapper for kort-lista), `.hub-category` (sibling-rubrik over hub-list)
137
+ - **Element:** `.hub-card__icon`, `.hub-card__text`, `.hub-card__title`, `.hub-card__subtitle`, `.hub-card__chev`
101
138
  - **Anvand:** Settings-hub navigation (kort-listor som lankar till sub-sidor)
102
139
  - **INTE:** Generic listrader (anvand `.list-row`)
103
140
 
104
141
  ### stat (`stat.css`)
105
- - **Klasser:** `.stat-grid`, `.stat-grid--single`, `.stat-card`, `.stat-card__value/__label/__unit/__sub`, `.stat-card__value--positive/-negative/-accent/-warning`
142
+ - **Blocks:** `.stat-grid` (grid-container), `.stat-card` (kort med BEM-element)
143
+ - **Element:** `.stat-card__value`, `.stat-card__label`, `.stat-card__unit`, `.stat-card__sub`
144
+ - **Modifiers:** `.stat-grid--single`, `.stat-card__value--positive/-negative/-accent/-warning`
106
145
  - **Anvand:** Sma kort med stor siffra + label (read-only metric-display)
107
146
  - **INTE:** Editerbart varde (anvand `.setting-row`)
108
147
 
109
148
  ### form (`form.css`)
110
- - **Klasser:** `.form-card`, `.form-section`, `.form-section__title`, `.form-group`, `.form-group__label`, `.form-hint`, `.form-row`, `.form-row--inline`
149
+ - **Blocks:** `.form-card`, `.form-section`, `.form-group`, `.form-hint`, `.form-row` (fem fristaende blocks i form-familjen)
150
+ - **Element:** `.form-section__title`, `.form-group__label`
151
+ - **Modifiers:** `.form-row--inline`
152
+ - **States:** `.form-group.is-fixed` (anvands inom `.form-row--inline`)
111
153
  - **Anvand:** Wrapper-strukturen for formularet
112
154
  - **INTE:** Inputs sjalva (egen `.input`)
113
155
 
114
156
  ### setting-row (`setting-row.css`)
115
- - **Klasser:** `.setting-list`, `.setting-row`, `.setting-row--static/-danger`, `.setting-row__text/__label/__sub/__value/__amount/__chevron/__avatar/__pill`, `.setting-toggle/__track/__thumb`
157
+ - **Blocks:** `.setting-list` (sibling-wrapper for setting-rows), `.setting-row` (huvud-block med BEM-element), `.setting-toggle` (iOS-stil toggle, sibling-block)
158
+ - **Element:** `.setting-row__text`, `.setting-row__label`, `.setting-row__sub`, `.setting-row__value`, `.setting-row__amount`, `.setting-row__chevron`, `.setting-row__avatar`, `.setting-row__pill`, `.setting-row__form`, `.setting-toggle__track`, `.setting-toggle__thumb`
159
+ - **Modifiers:** `.setting-row--static`, `.setting-row--danger`
116
160
  - **Anvand:** Tap-to-edit-rad som triggar bottom-sheet
117
161
  - **INTE:** Klickbart kort med rich content (anvand `.hub-card`)
118
162
 
119
163
  ### collapsible (`collapsible.css`)
120
- - **Klasser:** `.collapsible-card`, `.collapsible__header/__header-text/__chev/__body`, `[data-expanded]`
164
+ - **Blocks:** `.collapsible-card`
165
+ - **Element:** `.collapsible__header`, `.collapsible__header-text`, `.collapsible__chev`, `.collapsible__body`
166
+ - **States:** `[data-expanded]` pa `.collapsible-card`
121
167
  - **Anvand:** Panel som expanderar pa klick. JS togglar `data-expanded`
122
168
  - **INTE:** Modal-content (anvand `.dialog` eller `.sheet`)
169
+ - **Special:** BEM-stam-mismatch - block heter `.collapsible-card` men element heter `.collapsible__X` (utan `-card`-suffix). Oppen punkt for rename, se sprint-rapport 2026-05-09.
123
170
 
124
171
  ### hbar (`hbar.css`)
125
- - **Klasser:** `.hbar`, `.hbar__item/__track/__fill/__label/__value`, `.hbar__fill--positive/-warning/-negative`
172
+ - **Blocks:** `.hbar`
173
+ - **Element:** `.hbar__item`, `.hbar__track`, `.hbar__fill`, `.hbar__label`, `.hbar__value`
174
+ - **Modifiers:** `.hbar__fill--positive/-warning/-negative`
126
175
  - **Anvand:** Generisk horisontell bar med label + value + track + fill
127
176
  - **INTE:** Status-progress (anvand `.progress`)
128
177
 
129
178
  ### split-bar (`split-bar.css`)
130
- - **Klasser:** `.split-bar`, `.split-bar__segment`, `.split-bar__segment--primary/-secondary/-positive/-negative/-warning`, `.split-bar__label/__labels`
179
+ - **Blocks:** `.split-bar`
180
+ - **Element:** `.split-bar__segment`, `.split-bar__label`, `.split-bar__labels`
181
+ - **Modifiers:** `.split-bar__segment--primary/-secondary/-positive/-negative/-warning`
131
182
  - **Anvand:** Flersegment-bar for cost-split, debt-vs-equity m.fl.
132
183
  - **INTE:** Single-bar-progress (anvand `.hbar`)
133
184
 
134
185
  ### hero (`hero.css`)
135
- - **Klasser:** `.hero`, `.hero__heading/__amount/__amount--card/__amount--fluid/__amount-row/__label/__label--muted/__meta/__actions`
186
+ - **Blocks:** `.hero`, `.hero-amount` (sibling, animation-target - definieras aven i `hero-roll.css`)
187
+ - **Element:** `.hero__heading`, `.hero__amount`, `.hero__amount-row`, `.hero__label`, `.hero__meta`, `.hero__actions`
188
+ - **Modifiers:** `.hero__amount--card`, `.hero__amount--fluid`, `.hero__label--muted`
136
189
  - **Anvand:** Stora display-rubriker (80px-skala default, 40px card)
137
190
  - **INTE:** Vanlig `<h1>` (anvand `.heading-1`)
138
191
 
139
192
  ### chip (`chip.css`)
140
- - **Klasser:** `.chip`, `.chip--accent/-positive/-negative/-warning/-faint`, `.chip-list`, `.chip-list__item/__delete/__add`, `.brand-pill`, `.month-pill`, `.score-pill`, `.install-chip`
193
+ - **Blocks:** `.chip`, `.chip-list` (sibling-wrapper for chips i rad), `.brand-pill`, `.month-pill`, `.score-pill` (definieras aven i `badge.css`), `.install-chip` (PWA install-prompt)
194
+ - **Element:** `.chip-list__item`, `.chip-list__text`, `.chip-list__form`, `.chip-list__delete`, `.chip-list__add`, `.install-chip__text`, `.install-chip__install`, `.install-chip__dismiss`
195
+ - **Modifiers:** `.chip--accent/-positive/-negative/-warning/-faint`, `.score-pill--strong/-medium/-low`
141
196
  - **Anvand:** Kort-format pills med dot-prefix (status, kategori, count)
142
197
  - **INTE:** Form-inputs (anvand `.input`)
143
198
 
144
199
  ### avatar (`avatar.css`)
145
- - **Klasser:** `.avatar`, `.avatar--sm/-lg`
200
+ - **Blocks:** `.avatar`
201
+ - **Modifiers:** `.avatar--sm`, `.avatar--lg`
146
202
  - **Anvand:** Cirkular initial-avatar med accent-gradient
147
203
  - **INTE:** Foto-avatar (overlapp via custom regel)
148
204
 
149
205
  ### list-row (`list-row.css`)
150
- - **Klasser:** `.list`, `.list-row`, `.list-row--excluded/-pending/-clickable`, `.list-row__icon/__body/__desc/__meta/__date/__amount`, `.list-row__amount--positive/-negative`
206
+ - **Blocks:** `.list` (sibling-wrapper, `<ul>`-reset), `.list-row` (huvud-block med BEM-element)
207
+ - **Element:** `.list-row__icon`, `.list-row__body`, `.list-row__desc`, `.list-row__meta`, `.list-row__date`, `.list-row__amount`
208
+ - **Modifiers:** `.list-row--excluded`, `.list-row--pending`, `.list-row--clickable`, `.list-row__amount--positive/-negative`
151
209
  - **Anvand:** Generisk listrad med ikon + body + amount (transaktioner, audit-log, jobs)
152
210
  - **INTE:** Settings-rad (anvand `.setting-row`)
153
211
 
154
212
  ### table (`table.css`)
155
- - **Klasser:** `.table`, `.table .num`
213
+ - **Blocks:** `.table`
214
+ - **Element:** `.table .num` (descendant-selector)
156
215
  - **Anvand:** Tabell med tabular-nums-stod
157
216
  - **INTE:** Layout-grid (anvand CSS Grid utility)
158
217
 
159
218
  ### auth (`auth.css`)
160
- - **Klasser:** `.auth-container`, `.auth-container__title/__subtitle`
219
+ - **Blocks:** `.auth-container`
220
+ - **Element:** `.auth-container__title`, `.auth-container__subtitle`
161
221
  - **Anvand:** Centrerad layout for inloggning + onboarding
162
222
  - **INTE:** Settings-vyer
163
223
 
164
224
  ### swipe-stack (`swipe-stack.css`)
165
- - **Klasser:** `.swipe-stack`, `.swipe-card`, `.swipe-card--back/-gone`, `.swipe-card__header/__title/__body/__footer`, `.swipe-decision-overlay`, `.swipe-decision-overlay--save/-dismiss/-visible`, `.swipe-actions`, `.swipe-action-btn`, `.swipe-action-btn--save/-dismiss`, `.swipe-meta`, `.swipe-meta-sep`, `.swipe-progress`, `.swipe-empty`, `.swipe-hint`
225
+ - **Blocks:** `.swipe-stack`, `.swipe-card`, `.swipe-decision-overlay`, `.swipe-actions`, `.swipe-action-btn`, `.swipe-meta`, `.swipe-meta-sep`, `.swipe-progress`, `.swipe-empty`, `.swipe-hint` (10 fristaende blocks i swipe-familjen)
226
+ - **Element:** `.swipe-card__header`, `.swipe-card__title`, `.swipe-card__body`, `.swipe-card__footer`
227
+ - **Modifiers:** `.swipe-card--back`, `.swipe-card--gone`, `.swipe-decision-overlay--save/-dismiss/-visible`, `.swipe-action-btn--save/-dismiss`
166
228
  - **Anvand:** Tinder-stil swipe-stack med drag-physics
167
- - **INTE:** Card-galleri (anvand `.card-grid`)
229
+ - **INTE:** Card-galleri (anvand multipla `.card`)
168
230
 
169
231
  ### inline-edit (`inline-edit.css`)
170
- - **Klasser:** `.inline-edit`, `.inline-edit__text/__btn/__form/__input`
232
+ - **Blocks:** `.inline-edit`
233
+ - **Element:** `.inline-edit__text`, `.inline-edit__btn`, `.inline-edit__form`, `.inline-edit__input`
171
234
  - **Anvand:** Inline-edit av profil-namn, etiketter (pencil-knapp togglar form)
172
235
  - **INTE:** Form-fields (anvand `.form-group`)
173
- - **Special:** `.inline-edit__form[hidden]` har explicit `display: none` (paritet med globalt `[hidden]`-stod i base/pwa.css)
236
+ - **Special:** `.inline-edit__form[hidden]` har explicit `display: none` (paritet med globalt `[hidden]`-stod i base/pwa.css). `.inline-edit__input` anvander `:focus` istallet for `:focus-visible` per text-input-konvention.
174
237
 
175
238
  ### upload-spinner (`upload-spinner.css`)
176
- - **Klasser:** `.upload-spinner-overlay`, `.upload-spinner-overlay.is-visible`, `.upload-spinner`, `.upload-spinner-overlay__label/__hint`
239
+ - **Blocks:** `.upload-spinner-overlay` (huvud-block), `.upload-spinner` (atomisk, anvands inuti overlay)
240
+ - **Element:** `.upload-spinner-overlay__label`, `.upload-spinner-overlay__hint`
241
+ - **States:** `.upload-spinner-overlay.is-visible`
177
242
  - **Anvand:** Viewport-overlay for langa async-operationer (OCR, AI-anrop)
178
- - **INTE:** Inline-spinner (anvand `.spinner`)
243
+ - **INTE:** Inline-spinner (anvand `.spinner` fran `feedback.css`)
179
244
 
180
245
  ### tab-bar (`tab-bar.css`)
181
- - **Klasser:** `.tab-bar`, `.tab-bar__item.is-active`
182
- - **Anvand:** Inline tab-grupp for format-val (CSV/Avi etc.)
246
+ - **Blocks:** `.tab-bar` (definieras aven i `nav.css` med 5 identiska properties + skillnad i margin)
247
+ - **Element:** `.tab-bar__item`
248
+ - **States:** `.tab-bar__item.is-active`
249
+ - **Anvand:** Inline tab-grupp for format-val (CSV/Avi etc.) - 44px touch-target
183
250
  - **INTE:** Bottom-nav (anvand `.bottom-nav`)
251
+ - **Special:** Importordning i `index.css`: `nav.css` fore `tab-bar.css`. `.tab-bar`-block-styling fran tab-bar.css vinner via cascade.
184
252
 
185
253
  ### colored-row (`colored-row.css`) - v3.1.0
186
- - **Klasser:** `.colored-row`, `.colored-row--sm/-lg`
254
+ - **Blocks:** `.colored-row`
255
+ - **Modifiers:** `.colored-row--sm`, `.colored-row--lg`
187
256
  - **Anvand:** Kategoriserade rader, fargkodade listor, statusrader -
188
257
  med vansterkant fran `--row-accent`-token (default: `--border-subtle`)
189
258
  - **INTE:** Rader utan fargkodning (anvand `.list-row` eller plain `.tx-row`)
@@ -191,13 +260,22 @@ inga primitives. BEM-konvention (block__element--modifier).
191
260
  - **Pattern:** Se "Kategori-monstret" nedan
192
261
 
193
262
  ### colored-bar (`colored-bar.css`) - v3.1.0
194
- - **Klasser:** `.colored-bar`, `.colored-bar--sm/-md/-lg`, `.colored-bar--vertical`
263
+ - **Blocks:** `.colored-bar`
264
+ - **Modifiers:** `.colored-bar--sm`, `.colored-bar--md`, `.colored-bar--lg`, `.colored-bar--vertical`
195
265
  - **Anvand:** Budget-staplar, kategori-staplar, progress med semantisk
196
266
  farg fran `--bar-accent`-token (default: `--accent-9`)
197
267
  - **INTE:** Generisk progress utan kategori (anvand `.progress`)
198
268
  - **Tokens:** `--bar-accent` (sattes av app-bindning), `--accent-9` (default)
199
269
  - **Pattern:** Se "Kategori-monstret" nedan
200
270
 
271
+ ### sheet-content (`sheet-content.css`) - v3.5.1
272
+ - **Blocks:** `.sheet` (kompletterar `.sheet` fran `overlay.css` med innehall-typografi och form-monster)
273
+ - **Element:** `.sheet__title`, `.sheet__description`, `.sheet__form`, `.sheet__field`, `.sheet__field-label`, `.sheet__hint`, `.sheet__items`, `.sheet__item`, `.sheet__actions`, `.sheet__toggle`, `.sheet__subform`, `.sheet__save`, `.sheet__delete`, `.sheet__handle`, `.sheet__body`, `.sheet__divider` (kompletterande element)
274
+ - **Modifiers:** `.sheet__form--inline`, `.sheet__field-label--upper`, `.sheet__hint--compact`
275
+ - **States:** `.sheet__hint.is-error`, `.sheet__hint--compact.is-error`
276
+ - **Anvand:** Sprint-65 sheet-form-monster (Title + description + Form + Field + Items + Actions + Toggle + Subform)
277
+ - **INTE:** Sheet-overlay sjalv (definieras i `overlay.css`)
278
+
201
279
 
202
280
  ## Kategori-monstret
203
281
 
@@ -258,3 +336,4 @@ Jubb, Ekonom, framtida appar foljer samma monster med sina egna tokens.
258
336
  - **`var(--gray-9)` i komponent-CSS.** Komponenter laser bara semantic.
259
337
  - **Egen .button-style.** Anvand `.btn` med modifier istallet.
260
338
  - **`font-weight: 700`.** Anvand `--fw-medium` (500). Display-siffror ar dokumenterat undantag.
339
+ - **Anta att alla komponent-filer har ett root-block.** 17 av 35 komponent-filer har flera root-blocks - se regel 11 i `references/03-quality-bar.md`.
@@ -210,7 +210,83 @@ Varje interaktiv komponent SKA ha:
210
210
  annan 0.7, snart finns alla varianter och visuellt sprak ar splittrat
211
211
 
212
212
 
213
- ## 11. Inter font + Linear-stack
213
+ ## 11. En fil kan innehalla flera root-blocks
214
+
215
+ I 17 av 35 komponent-filer i paketet definieras flera root-blocks i
216
+ samma fil (`form.css`, `nav.css`, `chip.css`, `swipe-stack.css`,
217
+ `feedback.css`, `hub-card.css` m.fl.). Det ar en medveten konvention,
218
+ inte ett undantag eller teknisk skuld.
219
+
220
+ **Nar det ar korrekt att samla flera blocks i en fil:**
221
+ - **Semantiskt relaterade:** blocks som tillhor samma tema (form-skelett,
222
+ feedback-states, navigation-monster, swipe-card-familjen)
223
+ - **Anvands i kombination:** wrapper + child-block som alltid renderas
224
+ tillsammans (`.hub-list` + `.hub-card`, `.list` + `.list-row`,
225
+ `.progress` + `.progress-bar`)
226
+ - **Sibling-relation:** blocks som placeras parallellt i HTML men aldrig
227
+ ar BEM-element av varandra (`.hub-category` + `.hub-list`,
228
+ `.input-group` + `.input-icon` som siblings till `.input`)
229
+
230
+ **Nar det INTE ar korrekt:**
231
+ - Tva orelaterade komponenter staplade i samma fil av bekvamlighet
232
+ - Ett block som logiskt kunde varit BEM-element av ett annat - i sa
233
+ fall ska det vara `.X__Y`, inte `.X-Y` som separat block
234
+
235
+ **Hur de ska dokumenteras:**
236
+
237
+ JSDoc-header i CSS-filen ska ha en `Blocks:`-sektion som listar varje
238
+ root-block med en kort beskrivning + relation:
239
+
240
+ ```css
241
+ /* ================================================================
242
+ components/example.css
243
+ [Kort beskrivning av filens syfte]
244
+
245
+ Blocks:
246
+ .block-a - [vad den gor]
247
+ .block-b - sibling-wrapper for [...]
248
+ .block-c - atomisk, anvands inuti .block-a
249
+
250
+ HTML-relationer (om ej uppenbara):
251
+ .block-c placeras alltid som child av .block-a i HTML
252
+ ================================================================ */
253
+ ```
254
+
255
+ I `references/02-components.md` listas root-blocks under
256
+ `**Blocks:**`-raden, BEM-element under `**Element:**`, modifiers under
257
+ `**Modifiers:**`, state-classes under `**States:**`. Sibling- och
258
+ wrapper-relationer noteras i parentes.
259
+
260
+ **Konkret exempel:** `hub-card.css` har tre fristaende blocks:
261
+
262
+ ```
263
+ .hub-card - klickbart kort (huvud-block med BEM-element)
264
+ .hub-list - <ul>-wrapper for flera hub-cards (sibling)
265
+ .hub-category - <h6>-rubrik over hub-list (sibling, placeras FORE)
266
+ ```
267
+
268
+ I HTML ligger `.hub-category` som syskon till `.hub-list`, inte inuti
269
+ det. Bara `.hub-card` har egna BEM-element (`__icon/__text/__title`).
270
+
271
+ **Varfor:**
272
+ - Semantisk gruppering > arbitrar fil-uppdelning. Att splittra
273
+ `.form-card/.form-section/.form-group` i tre filer ger inget varde -
274
+ de hor ihop som "form-skelett".
275
+ - Auditer ska kunna lasa filens kommentar och forsta strukturen utan
276
+ att behova rekonstruera den fran selektor-mosaik.
277
+ - BEM-falska-positiv minimeras. En extern reviewer som ser `.hub-list`
278
+ ska kunna avgora om det ar ett brott (compound block i fel fil) eller
279
+ konvention (sibling i samma fil).
280
+
281
+ **Trade-off:**
282
+ - Kraver disciplinerad JSDoc + 02-components.md-underhall vid varje ny
283
+ komponent. Utan det blir flera-blocks-i-samma-fil ett mysterium.
284
+ - Risk for junk-drawer-filer dar olika blocks staplas av lathet.
285
+ Mitigation: granska om varje nytt block hor ihop tematiskt eller
286
+ borde fa egen fil.
287
+
288
+
289
+ ## 12. Inter font + Linear-stack
214
290
 
215
291
  **Hur man foljer:**
216
292
  - Anvand `var(--font-sans)` overallt - ALDRIG specifika font-family-
@@ -230,7 +306,7 @@ Varje interaktiv komponent SKA ha:
230
306
  - Linear, Vercel och liknande modern SaaS anvander samma stack
231
307
 
232
308
 
233
- ## 12. Bara nya semantic token-namn
309
+ ## 13. Bara nya semantic token-namn
234
310
 
235
311
  **Hur man foljer:**
236
312
  - Anvand bara nya semantic-namn: `--text-default/-subtle/-muted/-disabled`,
@@ -0,0 +1,48 @@
1
+ # 0009 - collapsible block-rename: .collapsible-card → .collapsible
2
+
3
+ ## Status
4
+ Locked. Beslutat 2026-05-09.
5
+
6
+ ## Context
7
+ collapsible.css definierade root-blocket som `.collapsible-card` men
8
+ BEM-elementen som `.collapsible__header`, `.collapsible__body`,
9
+ `.collapsible__chev`, `.collapsible__header-text`. BEM-stammen var
10
+ inkonsekvent: elementen antydde att parent-blocket borde heta
11
+ `.collapsible`, inte `.collapsible-card`.
12
+
13
+ Fyndet identifierades i paritetsaudit 2026-05-09 (undersökning 4).
14
+ Underlaget visade:
15
+
16
+ - 3 produktion-templates i Ekonom (avstamning.html)
17
+ - 3 showcase-templates i Ekonom (design.html)
18
+ - 3 showcase-templates i Jubb (design.html)
19
+ - 0 produktion-templates i Jubb
20
+ - 0 lokala CSS-overrides i någon app
21
+ - JS-koppling via [data-collapsible]-attribut, inte via klasnamn
22
+ (en querySelector på .collapsible__body i Ekonom app.js rad 202)
23
+
24
+ ## Considered options
25
+
26
+ ### Alternativ A: rename block .collapsible-card → .collapsible
27
+ Elementen (.collapsible__header etc.) oförändrade.
28
+ ~12 ändringar: 1 CSS-fil + 2 template-filer per app.
29
+ JS opåverkat (data-attribut-koppling).
30
+
31
+ ### Alternativ B: rename element .collapsible__X → .collapsible-card__X
32
+ Blocket (.collapsible-card) oförändrat.
33
+ ~15 ändringar + 1 JS-ändring (app.js rad 202).
34
+
35
+ ## Decision
36
+ **Alternativ A.** Elementen är rätt — `.collapsible__` speglar det
37
+ semantiska begreppet. Blocket är det som avviker. "-card"-suffixet är
38
+ en implementationsdetalj från ursprunglig skapelse, inte en semantisk
39
+ egenskap. JS-kopplingen via data-attribut gör att rename är renare än
40
+ Alternativ B.
41
+
42
+ ## Consequences
43
+ - + BEM-stammen är konsekvent: .collapsible → .collapsible__header etc.
44
+ - + JS opåverkat
45
+ - + Färre ändringar än Alternativ B
46
+ - − Template-ändringar krävs i Ekonom produktion (3 rader) och
47
+ showcase i båda appar (6 rader)
48
+ - − npm minor version-bump krävs (publik klass-rename är breaking change)