@klodd/ds 3.14.14 → 3.15.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.
- package/SKILL.md +94 -1
- package/css/base/typography.css +1 -0
- package/css/components/banner.css +1 -1
- package/css/components/chip.css +35 -4
- package/css/components/collapsible.css +1 -1
- package/css/components/dropdown.css +3 -1
- package/css/components/feedback.css +6 -3
- package/css/components/form.css +1 -1
- package/css/components/hero.css +3 -1
- package/css/components/hub-card.css +1 -1
- package/css/components/inline-edit.css +1 -1
- package/css/components/list-row.css +1 -1
- package/css/components/nav.css +8 -5
- package/css/components/offline.css +1 -1
- package/css/components/overlay.css +10 -5
- package/css/components/panel.css +1 -1
- package/css/components/setting-row.css +1 -1
- package/css/components/sheet-content.css +2 -2
- package/css/components/stat.css +1 -1
- package/css/components/swipe-stack.css +1 -1
- package/css/components/tab-bar.css +2 -2
- package/css/components/tooltip.css +1 -1
- package/package.json +9 -2
- package/references/02-components.md +137 -0
- package/references/03-quality-bar.md +26 -3
- package/references/04-locked-decisions/0011-strikt-bem-elementsyntax.md +133 -0
- package/references/04-locked-decisions/0012-stylelint-bem-enforcement.md +117 -0
- package/references/04-locked-decisions/0013-visual-coherence-doctrine.md +128 -0
- package/references/AUDIT-VISUAL-COHERENCE-2026-05-12.md +216 -0
- package/references/DESIGN-LANGUAGE.md +305 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# 0011 - Strikt BEM-elementsyntax för inre struktur av compound-blocks
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
Locked.
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
|
|
8
|
+
Regel 11 i `03-quality-bar.md` (compound blocks i samma fil) öppnade
|
|
9
|
+
för flat-hyphen-klasser via sibling-relation-undantaget. Den nuvarande
|
|
10
|
+
formuleringen säger:
|
|
11
|
+
|
|
12
|
+
> Ett block som logiskt kunde varit BEM-element av ett annat - i så
|
|
13
|
+
> fall ska det vara `.X__Y`, inte `.X-Y` som separat block.
|
|
14
|
+
|
|
15
|
+
Detta var stipulerat men inte konsekvent verkställt i app-domain-CSS.
|
|
16
|
+
Jubbs `jubb.css` och `pages/triage.css` ackumulerade ~28 flat-hyphen-
|
|
17
|
+
klasser som logiskt var inre struktur av compound-blocks men namngivna
|
|
18
|
+
utan `__`-syntax (`.score-dim-row` istället för `.score-breakdown__dim-row`,
|
|
19
|
+
`.triage-source` istället för `.triage-card__source` etc).
|
|
20
|
+
|
|
21
|
+
Ekonoms domain-CSS (`ekonom.css`) har också compound-block-undantag
|
|
22
|
+
men dessa är dokumenterade som Sprint G Tier D-undantag (2026-05-09)
|
|
23
|
+
med specifik rationale (visuell paritet, etablerade namn, lyft-värda
|
|
24
|
+
till paketet).
|
|
25
|
+
|
|
26
|
+
Skärpning behövdes för att:
|
|
27
|
+
1. Förtydliga vad "kunde varit BEM-element" betyder (test-baserat)
|
|
28
|
+
2. Stänga gapet där LLM-sessioner skapade flat-hyphen-inner-element
|
|
29
|
+
med felklassificering som "sibling"
|
|
30
|
+
3. Etablera dokumenterad Tier D-katalog som hindrar nya odokumenterade
|
|
31
|
+
undantag
|
|
32
|
+
|
|
33
|
+
## Decision
|
|
34
|
+
|
|
35
|
+
Compound-blocks i samma fil är OK ENDAST när alla följande gäller:
|
|
36
|
+
|
|
37
|
+
1. **JSDoc-header med `Blocks:`-sektion** (oförändrat krav från regel 11)
|
|
38
|
+
2. **Listade i `02-components.md`** (oförändrat krav)
|
|
39
|
+
3. **Inre struktur av compound-block MÅSTE använda BEM-element-syntax
|
|
40
|
+
(`__element`).** Bara root-level sibling-blocks (genuint fristående
|
|
41
|
+
koncept) får vara flat-hyphen.
|
|
42
|
+
|
|
43
|
+
### Test (compound-sibling vs BEM-element)
|
|
44
|
+
|
|
45
|
+
> "Skulle detta block fungera om jag tar bort dess parent-block?"
|
|
46
|
+
> - Ja, det är ett fristående koncept → sibling-block (flat-hyphen OK)
|
|
47
|
+
> - Nej, det är inre struktur av parent → BEM-element (`__`-syntax krav)
|
|
48
|
+
|
|
49
|
+
### Exempel
|
|
50
|
+
|
|
51
|
+
Rätt (siblings, kan användas separat):
|
|
52
|
+
- `.hub-card` + `.hub-list` + `.hub-category` (paketets hub-card.css)
|
|
53
|
+
- `.swipe-stack` + `.swipe-card` + `.swipe-actions` + ... (paketets swipe-stack.css)
|
|
54
|
+
- `.form-card` + `.form-section` + `.form-group` (paketets form.css)
|
|
55
|
+
|
|
56
|
+
Rätt (BEM-element, inre struktur):
|
|
57
|
+
- `.hub-card__icon` (inom .hub-card)
|
|
58
|
+
- `.swipe-card__title` (inom .swipe-card)
|
|
59
|
+
- `.score-breakdown__dim-row` (inom .score-breakdown)
|
|
60
|
+
- `.triage-card__source` (inom .triage-card)
|
|
61
|
+
|
|
62
|
+
Fel (flat-hyphen för inre struktur):
|
|
63
|
+
- `.score-dim-row` (skulle varit `.score-breakdown__dim-row`)
|
|
64
|
+
- `.triage-source` (skulle varit `.triage-card__source`)
|
|
65
|
+
- `.source-numbers` (skulle varit `.source-stats__numbers`)
|
|
66
|
+
|
|
67
|
+
## Migration genomförd 2026-05-12
|
|
68
|
+
|
|
69
|
+
Sprint BEM-2 + BEM-3 i Jubb migrerade 18 flat-hyphen-klasser till
|
|
70
|
+
strikt BEM via `scripts/migrate_bem.py`:
|
|
71
|
+
|
|
72
|
+
**BEM-2 (Jubb commit `21840ec`):**
|
|
73
|
+
- `.score-dim-row/-label/-value` → `.score-breakdown__dim-row/-label/-value`
|
|
74
|
+
- `.source-row/-numbers/-int/-dis` → `.source-stats__row/-numbers/-int/-dis`
|
|
75
|
+
|
|
76
|
+
**BEM-3 (Jubb commit `c371f56`):**
|
|
77
|
+
- `.triage-source/-title/-meta-row/-why/-detail-link` → `.triage-card__*`
|
|
78
|
+
- `.triage-dismiss/-save/-interest` → `.triage-btn--*`
|
|
79
|
+
- `.banner-triage*` → `.triage-banner` + `__text/__cta`
|
|
80
|
+
|
|
81
|
+
Verifiering via `migrate_bem.py verify` (0 träffar gamla namn).
|
|
82
|
+
Pytest 429 pass varje sprint. Class-maps committade som
|
|
83
|
+
`scripts/class_map_bem2.yaml` + `scripts/class_map_bem3.yaml` för
|
|
84
|
+
spårbarhet.
|
|
85
|
+
|
|
86
|
+
## Tier D-undantagskatalog (dokumenterade flat-hyphen-block-familjer)
|
|
87
|
+
|
|
88
|
+
Se `references/02-components.md` "Tier D-undantagskatalog"-sektionen
|
|
89
|
+
för komplett lista. Två kategorier:
|
|
90
|
+
|
|
91
|
+
### Paketets dokumenterade undantag
|
|
92
|
+
- `.tooltip-wrapper` (compound block parent till `.tooltip`)
|
|
93
|
+
- `.offline-wrap/-icon/-title/-text` (compound, alla 4 används tillsammans)
|
|
94
|
+
- `.kv-budget-header/-body` (compound, lyfta från Ekonom utan rename
|
|
95
|
+
för template-kompatibilitet)
|
|
96
|
+
|
|
97
|
+
### Ekonom Tier D (Sprint G 2026-05-09)
|
|
98
|
+
- `.cat-bar-*` (7 klasser)
|
|
99
|
+
- `.equity-bar-*` (6 klasser)
|
|
100
|
+
- `.budget-bar-*` (5 klasser)
|
|
101
|
+
- `.cat-tx-*` (6 klasser)
|
|
102
|
+
|
|
103
|
+
Total: 7 paket-undantag + 24 Ekonom Tier D = 31 dokumenterade undantag.
|
|
104
|
+
|
|
105
|
+
**Inga nya Tier D-poster utan ADR-beslut.**
|
|
106
|
+
|
|
107
|
+
## Consequences
|
|
108
|
+
|
|
109
|
+
**Bra:**
|
|
110
|
+
- LLM-sessioner kan applicera regel 11 entydigt via test:en
|
|
111
|
+
- Future flat-hyphen-inner-element fångas som regelbrott
|
|
112
|
+
- Tier D-katalog är frusen lista, inte växande
|
|
113
|
+
- Tooling (`scripts/migrate_bem.py`) kan användas igen för app-domain-
|
|
114
|
+
klasser som ackumuleras över tid
|
|
115
|
+
|
|
116
|
+
**Trade-off:**
|
|
117
|
+
- Existerande Ekonom Tier D-klasser förblir flat-hyphen. Migrera dem
|
|
118
|
+
retroaktivt skulle ge ingen visuell vinst men kostar template-byten
|
|
119
|
+
och risk för regression. Sprint G-rationale (2026-05-09) håller.
|
|
120
|
+
- Jubbs `jubb.css` har fortfarande sibling-block-familjer (hour-heatmap,
|
|
121
|
+
radar-indicator, mode-toggle, signal-badge, job-list/job-card) som
|
|
122
|
+
passerar testen som genuint fristående siblings. Dokumentation pass
|
|
123
|
+
i BEM-6 listar dessa explicit i `02-components.md`.
|
|
124
|
+
|
|
125
|
+
## References
|
|
126
|
+
|
|
127
|
+
- Jubb commit `21840ec` (BEM-2: score-breakdown + source-stats)
|
|
128
|
+
- Jubb commit `c371f56` (BEM-3: triage.css)
|
|
129
|
+
- klodd-ds commit (denna ADR)
|
|
130
|
+
- `references/03-quality-bar.md` regel 11
|
|
131
|
+
- `references/02-components.md` Tier D-undantagskatalog
|
|
132
|
+
- ADR `0009-no-flat-components-css.md` (besläktad, paket-vs-app-domain-separation)
|
|
133
|
+
- ADR `0010-collapsible-block-rename.md` (besläktad, BEM-konvertering i paketet)
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# 0012 - Stylelint BEM-enforcement via CI
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
Locked.
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
|
|
8
|
+
Regel 11 + ADR 0011 etablerade strikt BEM-element-syntax för inre
|
|
9
|
+
struktur av compound-blocks. Enforcement var dock enbart mänsklig
|
|
10
|
+
disciplin - inget automatiserat verktyg fångade regel-brott innan
|
|
11
|
+
commit. Future-CC kunde introducera flat-hyphen-inner-class utan
|
|
12
|
+
att CI flaggade det.
|
|
13
|
+
|
|
14
|
+
Sprint BEM-2/3/6 (2026-05-12) migrerade 23 klasser i Jubb manuellt.
|
|
15
|
+
Utan CI-enforcement skulle motsvarande drift kunna återinföras i
|
|
16
|
+
nästa sprint utan att fångas.
|
|
17
|
+
|
|
18
|
+
## Decision
|
|
19
|
+
|
|
20
|
+
Stylelint configurerad i alla repos (klodd-ds + Jubb + Ekonom) med
|
|
21
|
+
`selector-class-pattern`-regel som enforce BEM-syntax mekaniskt.
|
|
22
|
+
|
|
23
|
+
### Regex-pattern
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
^[a-z][a-z0-9]*(-[a-z0-9]+)*(__[a-z0-9]+(-[a-z0-9]+)*)?(--[a-z0-9]+(-[a-z0-9]+)*)?$
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Matchar:
|
|
30
|
+
- `.block` (lowercase, kebab-case)
|
|
31
|
+
- `.block-with-dashes` (compound block-namn)
|
|
32
|
+
- `.block__element`
|
|
33
|
+
- `.block--modifier`
|
|
34
|
+
- `.block__element--modifier`
|
|
35
|
+
- `.block-name__element-name--modifier-name` (compound på alla nivåer)
|
|
36
|
+
|
|
37
|
+
Fångar (block):
|
|
38
|
+
- PascalCase / camelCase (`.BadCapital`)
|
|
39
|
+
- snake_case (`.block_with_underscores`)
|
|
40
|
+
- Numerisk start (`.123-numeric`)
|
|
41
|
+
- Dubbel-`__` (`.block__elem__nested`)
|
|
42
|
+
- Dubbel-`--` (`.block--mod1--mod2`)
|
|
43
|
+
- Trailing dash / underscore
|
|
44
|
+
|
|
45
|
+
### CI-integration
|
|
46
|
+
|
|
47
|
+
GitHub Actions workflow (`.github/workflows/stylelint.yml`) i alla
|
|
48
|
+
tre repos kör `npm run lint:css` på push + PR mot main. Misslyckad
|
|
49
|
+
lint blockerar merge / deploy.
|
|
50
|
+
|
|
51
|
+
### Tier D-undantag
|
|
52
|
+
|
|
53
|
+
Eftersom regex tillåter compound-block-namn (`.cat-bar-row`,
|
|
54
|
+
`.tooltip-wrapper`) kräver dokumenterade Tier D-undantag inga
|
|
55
|
+
`/* stylelint-disable */`-kommentarer. Regex matchar dem som
|
|
56
|
+
"compound block". Begränsning: stylelint kan inte mekaniskt skilja
|
|
57
|
+
på "dokumenterat Tier D" vs "nytt brott av samma typ".
|
|
58
|
+
|
|
59
|
+
För strikt enforcement av Tier D-katalogen krävs custom plugin
|
|
60
|
+
(framtida arbete) som korsreferrerar 02-components.md. Sprint 10-1
|
|
61
|
+
levererar BEM-SYNTAX-enforcement, inte semantisk-Tier-D-enforcement.
|
|
62
|
+
|
|
63
|
+
## Konfigurations-detaljer
|
|
64
|
+
|
|
65
|
+
**Stäng av** (irrelevanta code-style-regler från stylelint-config-standard):
|
|
66
|
+
- `lightness-notation`, `color-function-notation`, `alpha-value-notation`
|
|
67
|
+
- `declaration-block-single-line-max-declarations`
|
|
68
|
+
- `declaration-block-no-shorthand-property-overrides` (override-intent
|
|
69
|
+
i overlay.css)
|
|
70
|
+
- Diverse `*-empty-line-before`-regler
|
|
71
|
+
|
|
72
|
+
**Behåll**:
|
|
73
|
+
- `selector-class-pattern` (BEM-regex) - huvudregel
|
|
74
|
+
- `color-no-invalid-hex`
|
|
75
|
+
- `no-duplicate-at-import-rules`
|
|
76
|
+
- `comment-no-empty`
|
|
77
|
+
- `no-invalid-double-slash-comments`
|
|
78
|
+
|
|
79
|
+
## Consequences
|
|
80
|
+
|
|
81
|
+
**Bra:**
|
|
82
|
+
- Future-CC får CI-error vid BEM-syntax-brott
|
|
83
|
+
- Regression-prevention för BEM-2/3/6-migrationen
|
|
84
|
+
- Mekanisk enforcement minskar dependence på mänsklig review
|
|
85
|
+
|
|
86
|
+
**Trade-off:**
|
|
87
|
+
- Tier D vs nytt-brott skillnaden är inte mekaniskt fångad. Kräver
|
|
88
|
+
fortfarande mänsklig kontroll mot 02-components.md Tier D-katalog.
|
|
89
|
+
- Stylelint-config replikeras i tre repos (klodd-ds + Jubb + Ekonom).
|
|
90
|
+
Migration till shared `@klodd/ds/stylelint-config` möjlig framöver
|
|
91
|
+
om underhåll blir issue.
|
|
92
|
+
- Code-style-regler från stylelint-config-standard avstängda för att
|
|
93
|
+
inte blockera på icke-BEM-violations.
|
|
94
|
+
|
|
95
|
+
## Setup-resultat 2026-05-12
|
|
96
|
+
|
|
97
|
+
Audit-resultat efter installation:
|
|
98
|
+
- **klodd-ds**: 0 BEM-violations (alla 37 komponentfiler + base/
|
|
99
|
+
+ utilities passerar)
|
|
100
|
+
- **Jubb**: 0 BEM-violations efter BEM-2/3/6-migrationen
|
|
101
|
+
- **Ekonom**: 0 BEM-violations (Tier D-klasser tillåtna som compound)
|
|
102
|
+
|
|
103
|
+
Test av regelns enforcement med medvetna brott:
|
|
104
|
+
- `.BadCapital` → fångad
|
|
105
|
+
- `.block_with_underscores` → fångad
|
|
106
|
+
- `.123-numeric` → fångad
|
|
107
|
+
- `.block__elem__nested` → fångad
|
|
108
|
+
- `.block--mod1--mod2` → fångad
|
|
109
|
+
|
|
110
|
+
## References
|
|
111
|
+
|
|
112
|
+
- ADR 0011 (strikt BEM-elementsyntax) - regel 11-skärpning
|
|
113
|
+
- `references/03-quality-bar.md` regel 11
|
|
114
|
+
- `references/02-components.md` Tier D-undantagskatalog
|
|
115
|
+
- `.stylelintrc.json` i alla tre repos
|
|
116
|
+
- `.github/workflows/stylelint.yml` i alla tre repos
|
|
117
|
+
- Jubb commits 21840ec, c371f56, 0bd1f97 (BEM-2/3/6-migration)
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# 0013 - Visual Coherence Doctrine
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
Locked.
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
|
|
8
|
+
Designsystemet hade efter Sprint 10 (BEM-mekanisk-konsekvens) en hög
|
|
9
|
+
nivå av token-disciplin och BEM-syntax-disciplin, men brist på
|
|
10
|
+
**komposition-disciplin**. Calle's observation 2026-05-12: "element
|
|
11
|
+
inte synkade i former och storlek, märklig ljus skugga på mörk
|
|
12
|
+
bakgrund, olika storlekar nära varandra som borde harmonisera."
|
|
13
|
+
|
|
14
|
+
Det var inte BEM-syntax-brott. Det var visuell koherens-brist.
|
|
15
|
+
Designsystem ger tokens + komponenter + regler, men hur komponenter
|
|
16
|
+
används TILLSAMMANS i layouter var inte kodifierat.
|
|
17
|
+
|
|
18
|
+
Full audit (Chrome MCP javascript_tool layout-extraction över 17
|
|
19
|
+
vyer i båda apparna) identifierade 5 kritiska brott:
|
|
20
|
+
|
|
21
|
+
1. **Border-radius-kaos**: 11+ distinkta BR-värden över systemet
|
|
22
|
+
2. **Shadow-användning bryter regel 10**: oklch-ljus-shadow på 4 vyer
|
|
23
|
+
3. **4px alignment-drift**: hero-content sittande på x=18, övriga på
|
|
24
|
+
x=14 (hero.css padding 20/4/24)
|
|
25
|
+
4. **Font-size-spread varierade dramatiskt**: 3-9 distinkta fs per vy
|
|
26
|
+
5. **Hero-pattern inkonsekvent mellan apparna**: Jubb siffer-hero,
|
|
27
|
+
Ekonom label-meta-hero, blandning page-header vs hero
|
|
28
|
+
|
|
29
|
+
Audit-rapport: `references/AUDIT-VISUAL-COHERENCE-2026-05-12.md`.
|
|
30
|
+
|
|
31
|
+
## Decision
|
|
32
|
+
|
|
33
|
+
`references/DESIGN-LANGUAGE.md` är **LOCKED** som visual coherence-
|
|
34
|
+
doktrin. 12 sektioner specificerar konkreta regler:
|
|
35
|
+
|
|
36
|
+
1. **Border-radius-skala**: 5 värden (4/10/14/50%/9999) - eliminerat
|
|
37
|
+
2/6/8/12/16/18/20/22/24 från komponent-CSS
|
|
38
|
+
2. **Shadow-policy**: restriktiv. Dialog/sheet/dropdown/bottom-nav/toast
|
|
39
|
+
har `box-shadow: none`. Bara iOS-style toggle-thumb och active-pill
|
|
40
|
+
får `--shadow-card`.
|
|
41
|
+
3. **Page-toppar**: TVÅ separata patterns (.hero med __amount för
|
|
42
|
+
metric-display, .page-header för titel+subtitle utility-pages)
|
|
43
|
+
4. **Padding-rytm**: 6 värden (4/8/12/16/20/24)
|
|
44
|
+
5. **Font-size-skala**: 8 token-bundna värden
|
|
45
|
+
6. **Container-klassifikation**: matrix för card/panel/hub-card/etc
|
|
46
|
+
7. **Spacing-rytm mellan block**: konsekvent margin-conventions
|
|
47
|
+
8. **Alignment-regler**: alla container-element på x=14
|
|
48
|
+
9. **PWA-konventioner**: 44x44 tap-targets, mobile-first, safe-areas
|
|
49
|
+
10. **Färg-konvention**: semantic-surface-tokens enbart
|
|
50
|
+
11. **Enforcement-status**: stylelint för BEM, mänsklig disciplin
|
|
51
|
+
för visual coherence (custom plugin candidate)
|
|
52
|
+
12. **När ändra regler**: ADR-process, inga ad-hoc-ändringar
|
|
53
|
+
|
|
54
|
+
## Migration genomförd 2026-05-12
|
|
55
|
+
|
|
56
|
+
### Sprint 3a: Quick-wins (klodd-ds 3.15.0)
|
|
57
|
+
- overlay.css: dialog + sheet shadow→none, bg surface-overlay
|
|
58
|
+
- dropdown.css: shadow→none
|
|
59
|
+
- hero.css: padding 20/4/24→20/0/24 (alignment-drift fixad)
|
|
60
|
+
- nav.css: bottom-nav shadow→none
|
|
61
|
+
- feedback.css: toast shadow→none
|
|
62
|
+
- typography.css: muted-footer-text margin-top: var(--space-16)
|
|
63
|
+
|
|
64
|
+
Commit: klodd-ds a3beab4
|
|
65
|
+
|
|
66
|
+
### Sprint 3b: BR-konsolidering (klodd-ds 3.15.0)
|
|
67
|
+
- 16 paket-komponenter migrerade till 5-värdes-BR-skala
|
|
68
|
+
- 6 → 10, 8 → 10, 12 → 14, 16 → 14, 20 → 14, 24 → 14
|
|
69
|
+
- App-domain BR-konsolidering: Ekonom ekonom.css, Jubb jubb.css +
|
|
70
|
+
pages/design.css + pages/triage.css
|
|
71
|
+
|
|
72
|
+
Commit: klodd-ds 96d1bf6 + Ekonom 955919a + Jubb f69bd14
|
|
73
|
+
|
|
74
|
+
### Sprint 3c: Template-migration
|
|
75
|
+
- Jubb: 24 .hero-label → .hero__label byten över 5 templates
|
|
76
|
+
- Jubb-template-migration: topbar__title → topbar+page-header-pattern
|
|
77
|
+
(jobs_list, insights, runs, install, job_detail)
|
|
78
|
+
- Konsekvens med Ekonom (som redan använder topbar+page-header)
|
|
79
|
+
|
|
80
|
+
Commit: Jubb dffb7eb
|
|
81
|
+
|
|
82
|
+
## Consequences
|
|
83
|
+
|
|
84
|
+
**Bra:**
|
|
85
|
+
- Cross-app visuell homogenitet (Jubb och Ekonom följer samma
|
|
86
|
+
patterns)
|
|
87
|
+
- 5 BR-värden istället för 11+ (eliminerar "olika former"-känsla)
|
|
88
|
+
- Inga shadow-anomalier på dark-mode (per regel 10-doktrin)
|
|
89
|
+
- Hero alignment fixad (4px-drift eliminerad)
|
|
90
|
+
- Klar pattern-distinktion (hero för metric, page-header för titel)
|
|
91
|
+
|
|
92
|
+
**Trade-offs:**
|
|
93
|
+
- Visuella ändringar på 17+ vyer kräver visuell verifiering per vy
|
|
94
|
+
(re-audit Sprint 4b)
|
|
95
|
+
- BR-konsolidering är breaking visual change (panel 20→14 är
|
|
96
|
+
tightare/mer angular)
|
|
97
|
+
- DESIGN-LANGUAGE.md är ytterligare doc att underhålla för
|
|
98
|
+
CC-sessioner
|
|
99
|
+
- Custom stylelint-plugin för design-rule-enforcement saknas (mänsklig
|
|
100
|
+
disciplin tills implementerad)
|
|
101
|
+
|
|
102
|
+
## Future work
|
|
103
|
+
|
|
104
|
+
1. **Custom stylelint-plugin** som validerar:
|
|
105
|
+
- border-radius är en av {4, 10, 14, 50%, 9999}
|
|
106
|
+
- font-size är token-bundet (--fs-N)
|
|
107
|
+
- padding-värden begränsade till de 6 listade
|
|
108
|
+
- box-shadow förbjudet utöver --shadow-card
|
|
109
|
+
|
|
110
|
+
2. **Visual regression testing** via Playwright (Sprint 10-5 deferred):
|
|
111
|
+
- snapshots av kärnvyer per viewport
|
|
112
|
+
- PR-comment med diff-images
|
|
113
|
+
- Baseline-update via `--update-snapshots`
|
|
114
|
+
|
|
115
|
+
3. **Component combination-katalog**: utvidga 02-components.md med
|
|
116
|
+
"när-använda-vilken-kombination"-tabeller (t.ex. card vs panel
|
|
117
|
+
för list-items, hub-card vs setting-row för settings).
|
|
118
|
+
|
|
119
|
+
## References
|
|
120
|
+
|
|
121
|
+
- `references/DESIGN-LANGUAGE.md` (locked doktrin)
|
|
122
|
+
- `references/AUDIT-VISUAL-COHERENCE-2026-05-12.md` (audit-rapport)
|
|
123
|
+
- `references/03-quality-bar.md` regel 10 (shadow), regel 11 (BEM)
|
|
124
|
+
- ADR `0011-strikt-bem-elementsyntax.md` (besläktad)
|
|
125
|
+
- ADR `0012-stylelint-bem-enforcement.md` (besläktad)
|
|
126
|
+
- Klodd-ds commits: a3beab4 + 96d1bf6 + 3.15.0-bump
|
|
127
|
+
- Jubb commits: f69bd14 + dffb7eb
|
|
128
|
+
- Ekonom commit: 955919a
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# Visual Coherence Audit - 2026-05-12
|
|
2
|
+
|
|
3
|
+
Full systemaudit av Jubb (jubb.klodd.io) och Ekonom (ekonom.klodd.io)
|
|
4
|
+
mot målet "homogent designuttryck, slaviskt följt". 17 vyer
|
|
5
|
+
auditerade via Chrome MCP javascript_tool layout-extraction.
|
|
6
|
+
|
|
7
|
+
iPhone 14 Pro Max viewport (430x932).
|
|
8
|
+
|
|
9
|
+
## Auditerade vyer (17)
|
|
10
|
+
|
|
11
|
+
**Jubb (7):** /, /jobb, /triage, /insikter, /installera, /korningar
|
|
12
|
+
**Ekonom (10):** /avstamning, /privat, /bolanet, /jag, /jag/abonnemang,
|
|
13
|
+
/import, /granskning, /kategorier, /installningar, /installningar/{vart-hushall,
|
|
14
|
+
var-bostad, auto-kategorisering, data}
|
|
15
|
+
|
|
16
|
+
## Sammanställning: 5 kritiska brott
|
|
17
|
+
|
|
18
|
+
### 1. Border-radius-kaos (11+ distinkta värden)
|
|
19
|
+
|
|
20
|
+
Systemet använder **11+ olika BR-värden**:
|
|
21
|
+
|
|
22
|
+
| Värde | Använt på |
|
|
23
|
+
|---|---|
|
|
24
|
+
| 2px | split-bar-segments |
|
|
25
|
+
| 4px | mini-progress-bars |
|
|
26
|
+
| 6px | small-badges |
|
|
27
|
+
| 8px | tab-bar__item |
|
|
28
|
+
| 10px | button (.btn) |
|
|
29
|
+
| 12px | stat-card, tab-bar, setting-row |
|
|
30
|
+
| 14px | job-card, hub-card |
|
|
31
|
+
| 16px | banner, swipe-card |
|
|
32
|
+
| 20px | panel, form-card |
|
|
33
|
+
| 50% | icon-circles, avatars |
|
|
34
|
+
| 9999px | pills (chip, badge--neutral) |
|
|
35
|
+
|
|
36
|
+
**Inkonsekvenser inom samma "card-typ"**:
|
|
37
|
+
- panel BR=20, form-card BR=20 ✓ matchar
|
|
38
|
+
- job-card BR=14, hub-card BR=14 ✓ matchar
|
|
39
|
+
- stat-card BR=12, swipe-card BR=16, banner BR=16 - varför olika?
|
|
40
|
+
- tab-bar BR=12, tab-bar__item BR=8 - inkonsekvent inom samma komponent!
|
|
41
|
+
|
|
42
|
+
**Ögat fångar detta som "olika former"** även när varje val är token-driven.
|
|
43
|
+
|
|
44
|
+
### 2. Shadow-användning bryter regel 10
|
|
45
|
+
|
|
46
|
+
Regel 10 (quality-bar): "ENDAST `var(--shadow-card)` i hela systemet.
|
|
47
|
+
Aldrig hierarkisk skugg-skala."
|
|
48
|
+
|
|
49
|
+
**Brott funna på 4 vyer**:
|
|
50
|
+
- Jubb /jobb (sheet/dialog rendered i DOM)
|
|
51
|
+
- Jubb /triage (sheet)
|
|
52
|
+
- Ekonom /jag (sheet)
|
|
53
|
+
- Ekonom /import (sheet)
|
|
54
|
+
|
|
55
|
+
Shadow-värde: `oklch(0.949679 0.0026593 none / 0.08) 0px 8px 16px 0px`
|
|
56
|
+
|
|
57
|
+
Detta är `--shadow-float` (overlay-shadow). På dark-mode ger ljus
|
|
58
|
+
shadow inverterad djupkänsla (ljust på mörkt = lyft, inte sänkt).
|
|
59
|
+
|
|
60
|
+
**Calle's observation "märklig ljus skugga på mörk bakgrund" är detta**.
|
|
61
|
+
|
|
62
|
+
### 3. Hero-padding ger 4px alignment-drift
|
|
63
|
+
|
|
64
|
+
Paketets `hero.css` har `padding: 20px 4px 24px`. Detta 4px horizontal
|
|
65
|
+
shift sätter hero-content på x=18 (i 430-viewport). Andra element
|
|
66
|
+
(setting-list, panels) sitter på x=14.
|
|
67
|
+
|
|
68
|
+
**Resultat**: hero-content och andra block är på olika vertikala
|
|
69
|
+
linjer. Calle's "alignment-problem" exakt fångat.
|
|
70
|
+
|
|
71
|
+
### 4. Font-size-spread varierar dramatiskt
|
|
72
|
+
|
|
73
|
+
Per-vy distinkta font-sizes:
|
|
74
|
+
|
|
75
|
+
| Vy | Antal sizes | Spread |
|
|
76
|
+
|---|---|---|
|
|
77
|
+
| Jubb /korningar | 3 | 13/14/17 (clean) |
|
|
78
|
+
| Ekonom /granskning | 4 | 12/14/15/22 (clean) |
|
|
79
|
+
| Jubb /jobb | 5 | 11/12/13/14/17 |
|
|
80
|
+
| Jubb /insikter | 7 | 10-22 |
|
|
81
|
+
| Ekonom /jag | 9 | 10-24 |
|
|
82
|
+
| Ekonom /bolanet | 9 | 10-51.6 (!) |
|
|
83
|
+
|
|
84
|
+
**Anomalier**:
|
|
85
|
+
- `51.6px` på Bolanet - INTE i token-skala (--fs-N är heltal-pixlar)
|
|
86
|
+
- `13.3333px` på 6 Ekonom-vyer - browser sub-pixel-rendering av %-baserad fs
|
|
87
|
+
|
|
88
|
+
### 5. Hero-pattern är inkonsekvent
|
|
89
|
+
|
|
90
|
+
- **Jubb /, /installera**: hero med siffer-display (fs-80 hero_amount)
|
|
91
|
+
- **Jubb /jobb, /insikter, /korningar**: ingen hero, börjar direkt med panel/list
|
|
92
|
+
- **Ekonom /avstamning, /privat, /bolanet, /kategorier**: hero med fs-22-32-headings
|
|
93
|
+
- **Ekonom /jag**: ingen hero, börjar med profil-panel
|
|
94
|
+
- **Ekonom /granskning**: minimal hero
|
|
95
|
+
|
|
96
|
+
Ingen kanonisk hero-pattern. Varje vy uppfinner sin egen.
|
|
97
|
+
|
|
98
|
+
## Sekundära observationer
|
|
99
|
+
|
|
100
|
+
### Padding-rytm är spridd
|
|
101
|
+
|
|
102
|
+
Distinkta padding-värden funna:
|
|
103
|
+
`0/2/4/6/8/10/12/14/16/18/20/24` plus combinations (20/4/24, 16/18, ...).
|
|
104
|
+
|
|
105
|
+
12 distinkta värden i en enda design-system. För många.
|
|
106
|
+
|
|
107
|
+
### Container-klasser används parallellt
|
|
108
|
+
|
|
109
|
+
Bag av "card-like" containers över systemet:
|
|
110
|
+
- .card (paketet)
|
|
111
|
+
- .panel (paketet)
|
|
112
|
+
- .job-card (Jubb)
|
|
113
|
+
- .swipe-card (paketet)
|
|
114
|
+
- .stat-card (paketet)
|
|
115
|
+
- .hub-card (paketet)
|
|
116
|
+
- .form-card (paketet)
|
|
117
|
+
- .banner (paketet)
|
|
118
|
+
|
|
119
|
+
8 olika container-typer. Varje har egen BR/bg/padding.
|
|
120
|
+
|
|
121
|
+
### Bolanet är värst för konsekvens
|
|
122
|
+
|
|
123
|
+
Ekonom /bolanet har:
|
|
124
|
+
- 9 distinkta font-sizes (inkl 51.6 som är off-token)
|
|
125
|
+
- 7 distinkta border-radius-värden
|
|
126
|
+
- 9 distinkta padding-värden
|
|
127
|
+
- Banner med OKLCH bg (positive-tint) som avviker från andra paneler
|
|
128
|
+
|
|
129
|
+
Värst-i-klass. Förmodligen hot-spot för Calle's "olika storlekar".
|
|
130
|
+
|
|
131
|
+
## Fix-strategi (Sprint 2-4)
|
|
132
|
+
|
|
133
|
+
Fyra fix-kategorier prioriterade efter ROI:
|
|
134
|
+
|
|
135
|
+
### Quick-wins (Sprint 2)
|
|
136
|
+
|
|
137
|
+
1. **Ta bort shadow på sheet/dialog**: paket-fix i overlay.css.
|
|
138
|
+
Använd surface-overlay-token istället för shadow för djup.
|
|
139
|
+
Estimat: 30 min + npm bump + 2 appar.
|
|
140
|
+
|
|
141
|
+
2. **Fixa hero-padding alignment**: paket-fix i hero.css. Byt
|
|
142
|
+
`padding: 20px 4px 24px` till `padding: 20px 0 24px`.
|
|
143
|
+
Estimat: 15 min + bump.
|
|
144
|
+
|
|
145
|
+
3. **Fixa Bolanet fs-51.6**: Ekonom-domain. Förmodligen
|
|
146
|
+
`font-size: clamp(...)` med fluid sizing som ger non-integer.
|
|
147
|
+
Estimat: 30 min audit + fix.
|
|
148
|
+
|
|
149
|
+
4. **Lägg till spacing-rule på setting-list/footer-text**: 16px gap.
|
|
150
|
+
Paket-fix på .muted-footer-text. Estimat: 15 min + bump.
|
|
151
|
+
|
|
152
|
+
### Medium-fixes (Sprint 3)
|
|
153
|
+
|
|
154
|
+
5. **Konsolidera BR-skala till 4 värden**: 10/14/20 + 9999.
|
|
155
|
+
- Button = 10
|
|
156
|
+
- Stat-card/tab-bar/setting-row = 14 (lyfta från 12)
|
|
157
|
+
- Job-card/hub-card/swipe-card/banner/panel/form-card = 14 (lyfta
|
|
158
|
+
från 14/16/20 till en värde)
|
|
159
|
+
- Pills/avatars = 9999/50%
|
|
160
|
+
|
|
161
|
+
Faktiskt sänka radikalt: 10 + 14 + 9999 = bara 3 värden.
|
|
162
|
+
|
|
163
|
+
Estimat: 2-3h paket-fix + 1h re-audit visuellt.
|
|
164
|
+
|
|
165
|
+
6. **Konsolidera padding-rytm till 5 värden**: 4/8/12/16/20.
|
|
166
|
+
Eliminera 6/10/14/18/24 från komponent-CSS.
|
|
167
|
+
Plus app-domain audit.
|
|
168
|
+
|
|
169
|
+
Estimat: 3-4h paket-fix + audit.
|
|
170
|
+
|
|
171
|
+
### Kanonisering (Sprint 4)
|
|
172
|
+
|
|
173
|
+
7. **Hero-doktrin**: en kanonisk hero-struktur med modifier-klasser
|
|
174
|
+
för varianter (.hero, .hero--amount, .hero--minimal).
|
|
175
|
+
Alla dashboards använder hero (eller medvetet skippa det).
|
|
176
|
+
|
|
177
|
+
Estimat: 2-3h doc + paket-update + app-migration.
|
|
178
|
+
|
|
179
|
+
8. **Container-klassifikation**: matrix för när använda card vs
|
|
180
|
+
panel vs *-card. Etablera doktrin "panel = sektion-container,
|
|
181
|
+
card = klickbar enhet, hub-card = navigation-target".
|
|
182
|
+
|
|
183
|
+
Estimat: 1-2h doc.
|
|
184
|
+
|
|
185
|
+
### Locked decisions (Sprint 5)
|
|
186
|
+
|
|
187
|
+
9. **ADR 0013-visual-coherence-doctrine.md** locked.
|
|
188
|
+
10. **DESIGN-LANGUAGE.md** i klodd-ds.
|
|
189
|
+
11. **SKILL.md update** med 10/10 visuell + mekanisk status.
|
|
190
|
+
|
|
191
|
+
## Datapunkter (för transparens)
|
|
192
|
+
|
|
193
|
+
Räknat över alla 17 vyer:
|
|
194
|
+
|
|
195
|
+
- **Unique BR-values**: 11
|
|
196
|
+
- **Unique font-sizes**: 13 (inkl rounding)
|
|
197
|
+
- **Unique padding-values**: 18 (kombinationer)
|
|
198
|
+
- **Unique container-classes**: 8
|
|
199
|
+
- **Vyer med shadow**: 4 av 17 (24%)
|
|
200
|
+
- **Vyer med hero**: 8 av 17 (47%)
|
|
201
|
+
|
|
202
|
+
Mätbar mål för 10/10 efter Sprint 2-4:
|
|
203
|
+
- BR-values: 11 → 4
|
|
204
|
+
- Font-sizes: 13 → 8 (matchande --fs-N-tokens)
|
|
205
|
+
- Padding-values: 18 → 6
|
|
206
|
+
- Vyer med shadow: 4 → 0 (regel 10 strikt)
|
|
207
|
+
- Vyer med hero: standardiserat per dashboard-doktrin
|
|
208
|
+
|
|
209
|
+
## Begränsningar
|
|
210
|
+
|
|
211
|
+
- Endast mobile-viewport (430x932)
|
|
212
|
+
- Endast dashboard-vyer, inte modal/sheet-interna views
|
|
213
|
+
- Sheets/dialogs auditerade i DOM-state, inte open-state
|
|
214
|
+
- Animation/transition inte auditerade
|
|
215
|
+
- Tap-target visuellt verifierat på job-card (44x44) men inte
|
|
216
|
+
systematiskt över hela systemet
|