@klodd/ds 3.21.5 → 3.21.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@klodd/ds",
3
- "version": "3.21.5",
3
+ "version": "3.21.6",
4
4
  "description": "Klodd shared design system - tokens, components, JS",
5
5
  "main": "css/index.css",
6
6
  "bin": {
@@ -0,0 +1,122 @@
1
+ # 0018 - Outline-offset: list-rows får använda -2px (anti-clipping)
2
+
3
+ ## Status
4
+ Locked.
5
+
6
+ ## Context
7
+
8
+ DESIGN-LANGUAGE.md sektion 9 (etablerad 2026-05-12 via ADR 0013)
9
+ specificerade `outline: 2px solid var(--border-focus); outline-offset: 2px`
10
+ som regel för alla interaktiva element.
11
+
12
+ Audit 2026-05-14 (Ekonom UI/UX/CSS-cykel) visade att paketet självt
13
+ använder `outline-offset: -2px` på 5 komponenter:
14
+
15
+ | Fil | Selector | Värde |
16
+ |---|---|---|
17
+ | `collapsible.css:50` | `.collapsible__header:focus-visible` | `-2px` |
18
+ | `setting-row.css:63` | `.setting-row:focus-visible` | `-2px` |
19
+ | `sheet-content.css:101` | `.sheet__item:focus-visible` | `-1px` |
20
+ | `sheet-content.css:150` | `.sheet__btn--save:focus-visible` | `-1px` |
21
+ | `dropdown.css:72` | `.dropdown__item:focus-visible` | `-2px` |
22
+
23
+ Plus i Ekonom-domain:
24
+ - `ekonom.css:162` `.cat-row__header:focus-visible` `-2px`
25
+ - `ekonom.css:229` `.cat-list-row[data-tx-id]:focus-visible` `-2px`
26
+ - `ekonom.css:319` `.sub-row:focus-visible` `-2px`
27
+
28
+ Detta är **inte** slarv. Negative offset placerar outline _innanför_
29
+ elementets borders, vilket är nödvändigt för:
30
+
31
+ 1. **List-rows utan visible border**: outline +2px hänger utanför
32
+ elementet och clip:as av parent-list-row's border eller scroll-
33
+ container's `overflow: hidden`. Result: outline syns delvis eller
34
+ inte alls vid keyboard-fokus.
35
+ 2. **Dropdown-items inom radius-14-clippad menu**: outline +2px på
36
+ sista item:t clip:as av menu-borderns BR.
37
+ 3. **Items inom collapsible/sheet/card med BR-clipping**: samma
38
+ problem.
39
+
40
+ Standalone-element (knappar, inputs, links i text) har visible borders
41
+ eller tillräcklig spacing för outline +2px.
42
+
43
+ ## Decision
44
+
45
+ **Outline-offset är context-sensitive:**
46
+
47
+ ### -2px (inom-element, "inset")
48
+
49
+ Använd för items inom radius-clippade containers eller list-rader
50
+ utan visible border:
51
+ - `.list-row:focus-visible`
52
+ - `.setting-row:focus-visible`
53
+ - `.collapsible__header:focus-visible`
54
+ - `.sheet__item:focus-visible` (`-1px` pga tightare BR)
55
+ - `.sheet__btn--save:focus-visible` (`-1px`)
56
+ - `.dropdown__item:focus-visible`
57
+ - App-domain list-rows (Ekonom: `.cat-row__header`, `.cat-list-row[data-tx-id]`,
58
+ `.sub-row`; Jubb: motsvarande list-row-typer)
59
+
60
+ ### +2px (utanför-element, "outset")
61
+
62
+ Använd för standalone-element med visible border eller tillräcklig
63
+ spacing:
64
+ - `.btn:focus-visible`
65
+ - `.input:focus-visible` (text-input-undantag - använder `:focus`
66
+ istället per ADR-konvention, men om outline används är det +2px)
67
+ - `.skip-link:focus`
68
+ - `.chip:focus-visible`
69
+ - `.month-pill a:focus-visible`
70
+ - Topbar-actions (`.btn--icon`, `.pwa-avatar`, `.avatar` med focus)
71
+ - Generic `:focus-visible`-default i app/base.css
72
+
73
+ ### Komposita BR (för list-row med inset)
74
+
75
+ `border-radius: var(--radius-4)` på outline:n så den följer en mjuk
76
+ form, inte fyrkantig 0px. Per app/base.css default `:focus-visible`-rule.
77
+
78
+ ### Outline-bredd
79
+
80
+ `2px solid var(--accent-9)` (paket) eller `var(--border-focus)` (ADR
81
+ 0013-spec). Båda är acceptabla token-konsumenter.
82
+
83
+ ## Konsekvenser
84
+
85
+ **Bra:**
86
+ - Doktrinen matchar paketets faktiska implementation
87
+ - Future-CC har klar regel för var att applicera vilken offset
88
+ - Inset-värdet är _korrekt_ för list-rows (anti-clipping är funktionell
89
+ design, inte slarv)
90
+ - Stylelint-plugin (Sprint 5) kan validera per-komponent-typ
91
+
92
+ **Trade-offs:**
93
+ - Två varianter av outline-offset i systemet (-2/-1 vs +2). Komplexitet
94
+ ökar marginellt.
95
+ - Visuell skillnad mellan inset och outset är märkbar för
96
+ keyboard-användare. Outset är mer prominent, inset är mer subtil.
97
+ Trade-off: subtilitet vs synlighet. Anti-clipping vinner.
98
+
99
+ ## Migration
100
+
101
+ **Ingen migration krävs.** Paketet och appar är redan i låst state.
102
+ ADR dokumenterar bara regeln post-hoc.
103
+
104
+ Sprint F i Ekonom-auditen 2026-05-14 skippades baserat på denna analys -
105
+ fyndet var inte ett brott utan en medveten design-pattern som doktrinen
106
+ inte hade dokumenterat.
107
+
108
+ ## Stylelint-plugin (Sprint 5, framtida)
109
+
110
+ Validera:
111
+ - `outline-offset: -1px` eller `-2px` är endast tillåtet på selectors
112
+ som matchar list-row-/dropdown-item-/sheet-item-pattern
113
+ - `outline-offset: 2px` på alla andra :focus-visible-regler
114
+ - Varning vid avvikelse från ADR-tabellen ovan
115
+
116
+ ## References
117
+
118
+ - DESIGN-LANGUAGE.md sektion 9 (uppdaterad 2026-05-14)
119
+ - ADR 0013 (visual-coherence-doctrine) - tidigare regel
120
+ - Ekonom DECISIONS 2026-05-14 (audit-cykel skip-rationale för Sprint F)
121
+ - Audit-not: paketets faktiska outline-offset-värden inventoradde
122
+ 2026-05-14 via `grep -rEn "outline-offset:\s*-" app/static/css/ds/`
@@ -289,6 +289,24 @@ egna `margin-bottom`. Välj en mekanism per kontext.
289
289
  - List-rows: `padding: 14px 0` minimum (= 50px height med text-line).
290
290
  - Icon-buttons: `width: 44px; height: 44px`.
291
291
 
292
+ ### Focus-ring (outline-offset context-sensitive)
293
+
294
+ Outline-offset är **inte** alltid `+2px`. Inom radius-clippade
295
+ containers eller list-rader utan visible border klipps `+2px` outline
296
+ av parent. Använd inset (`-2px` eller `-1px`) i dessa fall för
297
+ synlig fokus-ring.
298
+
299
+ | Kontext | offset | Komponenter |
300
+ |---|---|---|
301
+ | Standalone-element med border eller spacing | `+2px` | `.btn`, `.chip`, `.skip-link`, `.month-pill a`, topbar-actions, generic `:focus-visible` |
302
+ | List-rader utan visible border | `-2px` | `.list-row`, `.setting-row`, `.collapsible__header`, `.dropdown__item` |
303
+ | Items inom radius-clippad menu/sheet | `-1px` | `.sheet__item`, `.sheet__btn--save` (tightare BR kräver -1) |
304
+ | App-domain list-rows | `-2px` | Ekonom `.cat-row__header`/`.cat-list-row[data-tx-id]`/`.sub-row`; Jubb motsvarande |
305
+
306
+ `outline: 2px solid var(--accent-9)` (eller `var(--border-focus)`) +
307
+ `border-radius: var(--radius-4)` på outline:n så den följer en mjuk
308
+ form. Se ADR 0018 för full rationale.
309
+
292
310
  ### Mobile-first
293
311
 
294
312
  - Default-styles är mobile (375-430 viewport).