@klodd/ds 5.14.0 → 5.15.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.
@@ -470,3 +470,130 @@
470
470
  );
471
471
  }
472
472
  }
473
+
474
+
475
+ /* ================================================================
476
+ ==== LIGHT MODE PRIMITIVES
477
+ Radix Light-skalor. Konsumeras BARA av [data-theme="light"]-blocket
478
+ i 10-semantic.css och app-filer. Aldrig direkt i komponenter.
479
+
480
+ Hex-värden hämtade från @radix-ui/colors v3.0.0 via unpkg
481
+ (2026-05-26). P3-varianter finns i Radix-paketet men ingår inte
482
+ här - klodd-ds håller sRGB-hex för portabilitet, matchande
483
+ dark-rampernas format ovan.
484
+
485
+ Naming: <ramp>-light-<step> för solid, <ramp>-light-a<step> för
486
+ alpha. Dark-skalorna ovan saknar suffix (de är default).
487
+ ================================================================ */
488
+
489
+
490
+ /* ================================================================
491
+ ==== MAUVE LIGHT (neutral, --gray-N i light mode)
492
+ ================================================================ */
493
+ :root {
494
+ --gray-light-1: #fdfcfd;
495
+ --gray-light-2: #faf9fb;
496
+ --gray-light-3: #f2eff3;
497
+ --gray-light-4: #eae7ec;
498
+ --gray-light-5: #e3dfe6;
499
+ --gray-light-6: #dbd8e0;
500
+ --gray-light-7: #d0cdd7;
501
+ --gray-light-8: #bcbac7;
502
+ --gray-light-9: #8e8c99;
503
+ --gray-light-10: #84828e;
504
+ --gray-light-11: #65636d;
505
+ --gray-light-12: #211f26;
506
+
507
+ --gray-light-a1: #55005503;
508
+ --gray-light-a2: #2b005506;
509
+ --gray-light-a3: #30004010;
510
+ --gray-light-a4: #20003618;
511
+ --gray-light-a5: #20003820;
512
+ --gray-light-a6: #14003527;
513
+ --gray-light-a7: #10003332;
514
+ --gray-light-a8: #08003145;
515
+ --gray-light-a9: #05001d73;
516
+ --gray-light-a10: #0500197d;
517
+ --gray-light-a11: #0400119c;
518
+ --gray-light-a12: #020008e0;
519
+ }
520
+
521
+
522
+ /* ================================================================
523
+ ==== BLUE LIGHT (Jubb accent)
524
+ ================================================================ */
525
+ :root {
526
+ --blue-light-1: #fbfdff;
527
+ --blue-light-2: #f4faff;
528
+ --blue-light-3: #e6f4fe;
529
+ --blue-light-4: #d5efff;
530
+ --blue-light-5: #c2e5ff;
531
+ --blue-light-6: #acd8fc;
532
+ --blue-light-7: #8ec8f6;
533
+ --blue-light-8: #5eb1ef;
534
+ --blue-light-9: #0090ff;
535
+ --blue-light-10: #0588f0;
536
+ --blue-light-11: #0d74ce;
537
+ --blue-light-12: #113264;
538
+
539
+ --blue-light-a1: #0080ff04;
540
+ --blue-light-a2: #008cff0b;
541
+ --blue-light-a3: #008ff519;
542
+ --blue-light-a4: #009eff2a;
543
+ --blue-light-a5: #0093ff3d;
544
+ --blue-light-a6: #0088f653;
545
+ --blue-light-a7: #0083eb71;
546
+ --blue-light-a8: #0084e6a1;
547
+ --blue-light-a9: #0090ff;
548
+ --blue-light-a10: #0086f0fa;
549
+ --blue-light-a11: #006dcbf2;
550
+ --blue-light-a12: #002359ee;
551
+ }
552
+
553
+
554
+ /* ================================================================
555
+ ==== PLUM LIGHT (Ekonom accent)
556
+ ================================================================ */
557
+ :root {
558
+ --plum-light-1: #fefcff;
559
+ --plum-light-2: #fdf7fd;
560
+ --plum-light-3: #fbebfb;
561
+ --plum-light-4: #f7def8;
562
+ --plum-light-5: #f2d1f3;
563
+ --plum-light-6: #e9c2ec;
564
+ --plum-light-7: #deade3;
565
+ --plum-light-8: #cf91d8;
566
+ --plum-light-9: #ab4aba;
567
+ --plum-light-10: #a144af;
568
+ --plum-light-11: #953ea3;
569
+ --plum-light-12: #53195d;
570
+
571
+ --plum-light-a1: #aa00ff03;
572
+ --plum-light-a2: #c000c008;
573
+ --plum-light-a3: #cc00cc14;
574
+ --plum-light-a4: #c200c921;
575
+ --plum-light-a5: #b700bd2e;
576
+ --plum-light-a6: #a400b03d;
577
+ --plum-light-a7: #9900a852;
578
+ --plum-light-a8: #9000a56e;
579
+ --plum-light-a9: #89009eb5;
580
+ --plum-light-a10: #7f0092bb;
581
+ --plum-light-a11: #730086c1;
582
+ --plum-light-a12: #40004be6;
583
+ }
584
+
585
+
586
+ /* ================================================================
587
+ ==== STATUS LIGHT
588
+ Bara step 9 (solid bg) och 11 (text-on-light) - det är de steg
589
+ som konsumeras av --bg-success/warning/danger respektive
590
+ --positive/-negative/-warning i 10-semantic.css.
591
+ ================================================================ */
592
+ :root {
593
+ --green-light-9: #30a46c;
594
+ --green-light-11: #218358;
595
+ --amber-light-9: #ffc53d;
596
+ --amber-light-11: #ab6400;
597
+ --red-light-9: #e5484d;
598
+ --red-light-11: #ce2c31;
599
+ }
@@ -321,6 +321,101 @@
321
321
  }
322
322
 
323
323
 
324
+ /* ================================================================
325
+ ==== LIGHT MODE OVERRIDES
326
+ Aktiveras via [data-theme="light"] på <html>-elementet.
327
+ Overridar bara tokens som faktiskt skiljer sig från dark default -
328
+ strukturella tokens (--touch-min, --z-*, --fw-*, spacing, radius)
329
+ delas mellan lägen.
330
+
331
+ App-specifika accenter overridas i
332
+ [data-app="X"][data-theme="light"] i respektive apps/X.css.
333
+
334
+ Shadow-doktrin: dark mode "ingen shadow, luminans skapar djup" -
335
+ light mode återställer shadow eftersom luminans-kontrast är svag.
336
+ Se ADR 0013 light mode-tillägg + ADR 0028 light mode-arkitektur.
337
+ ================================================================ */
338
+ [data-theme="light"] {
339
+ color-scheme: light;
340
+
341
+ /* SURFACES - Mauve Light, spegelvänt från dark-stegen */
342
+ --surface-page: var(--gray-light-1);
343
+ --surface-default: var(--gray-light-2);
344
+ --surface-raised: var(--gray-light-3);
345
+ --surface-elevated: var(--gray-light-4);
346
+ --surface-overlay: var(--gray-light-5);
347
+ --surface-hover: var(--gray-light-4);
348
+ --surface-active: var(--gray-light-5);
349
+ --surface-sunken: var(--gray-light-2);
350
+
351
+ /* Surface tints - svart istället för vit (white-tint osynlig på ljus bg) */
352
+ --surface-faint: color-mix(in oklch, black 2%, transparent);
353
+ --surface-subtle: color-mix(in oklch, black 4%, transparent);
354
+ --surface-medium: color-mix(in oklch, black 8%, transparent);
355
+ --surface-strong: color-mix(in oklch, black 12%, transparent);
356
+
357
+ /* TEXT - Mauve Light, höga steg = mörk text mot ljus bakgrund */
358
+ --text-default: var(--gray-light-12);
359
+ --text-subtle: var(--gray-light-11);
360
+ --text-muted: var(--gray-light-10);
361
+ --text-disabled: var(--gray-light-8);
362
+
363
+ /* BORDERS */
364
+ --border-subtle: var(--gray-light-5);
365
+ --border-default: var(--gray-light-7);
366
+ --border-strong: var(--gray-light-8);
367
+ --border-focus: var(--gray-light-9);
368
+ --border-hairline-faint: var(--bw-hairline) solid color-mix(in oklch, black 4%, transparent);
369
+
370
+ /* SHADOW-DOKTRIN LIGHT (ADR 0013 light-tillägg) */
371
+ --shadow-card: 0 1px 3px color-mix(in oklch, var(--gray-12) 12%, transparent),
372
+ 0 1px 2px color-mix(in oklch, var(--gray-12) 8%, transparent);
373
+ --shadow-float: 0 4px 12px color-mix(in oklch, var(--gray-12) 16%, transparent),
374
+ 0 2px 4px color-mix(in oklch, var(--gray-12) 10%, transparent);
375
+
376
+ /* GLASS - --gray-light-6 vid 55% (inte --surface-raised) - följer
377
+ iOS UIBlurEffect-konventionen att ge en svagt mörkare tint över
378
+ ljus page-bakgrund. Se ADR 0028. */
379
+ --glass-bg: color-mix(in oklch, var(--gray-light-6) 55%, transparent);
380
+ --glass-bg-fallback: color-mix(in oklch, var(--gray-light-6) 90%, transparent);
381
+
382
+ /* STATUS - Light step 11 för text, step 9 för bg */
383
+ --positive: var(--green-light-11);
384
+ --positive-dim: color-mix(in oklch, var(--green-light-9) 12%, transparent);
385
+ --positive-border: color-mix(in oklch, var(--green-light-9) 30%, transparent);
386
+ --negative: var(--red-light-11);
387
+ --negative-dim: color-mix(in oklch, var(--red-light-9) 12%, transparent);
388
+ --negative-border: color-mix(in oklch, var(--red-light-9) 30%, transparent);
389
+ --warning: var(--amber-light-11);
390
+ --warning-dim: color-mix(in oklch, var(--amber-light-9) 12%, transparent);
391
+ --warning-hover: color-mix(in oklch, var(--amber-light-9) 18%, transparent);
392
+ --warning-border: color-mix(in oklch, var(--amber-light-9) 30%, transparent);
393
+
394
+ /* Solid status-bakgrunder */
395
+ --bg-success: var(--green-light-9);
396
+ --bg-warning: var(--amber-light-9);
397
+ --bg-danger: var(--red-light-9);
398
+
399
+ /* Text-on-status: mörk i light mode. Vit oklch(0.98 0 0) ger
400
+ 1.58:1 mot amber-light-9 (WCAG-fail) - gray-light-12 ger 10.3:1
401
+ mot amber, 5.76:1 mot green-light-9, 5.52:1 mot red-light-9. */
402
+ --text-on-status: var(--gray-light-12);
403
+
404
+ /* --text-on-accent: mörk i light mode.
405
+ Vit oklch(0.98 0 0) ger ~3.29:1 mot blue-light-9 och ~2.8:1 mot
406
+ plum-light-9 - båda under WCAG AA 4.5:1.
407
+ gray-light-12 ger godkänd kontrast mot alla app-accenter. */
408
+ --text-on-accent: var(--gray-light-12);
409
+
410
+ /* Danger-action - dim/border följer via accent-danger-recursion */
411
+ --accent-danger: var(--red-light-9);
412
+
413
+ /* Chart-palette - re-pointe status step 9 till light-version */
414
+ --chart-2: var(--green-light-9);
415
+ --chart-3: var(--amber-light-9);
416
+ }
417
+
418
+
324
419
  /* ================================================================
325
420
  ==== COMPONENT TOKENS
326
421
  Atervaning av samma kombination i 3+ komponenter blir token.
@@ -63,3 +63,51 @@
63
63
  [data-app="ekonom"] {
64
64
  --glass-bg: color-mix(in oklch, var(--surface-raised) 65%, transparent);
65
65
  }
66
+
67
+
68
+ /* Light mode-override per app - Plum Light-rampen + Plum-tonad page.
69
+ Konsumeras när <html data-app="ekonom" data-theme="light">. Se ADR 0028.
70
+
71
+ (0,2,0) specificity - vinner garanterat över både [data-app]-block
72
+ och [data-theme]-block var för sig. Alla tokens som [data-app="ekonom"]
73
+ sätter måste även sättas här för light mode - annars vinner app-base
74
+ över semantic [data-theme="light"]-overriden via load-order. */
75
+ [data-app="ekonom"][data-theme="light"] {
76
+ /* Accent: Plum Light-rampen */
77
+ --accent-soft: var(--plum-light-3);
78
+ --accent-moderate: var(--plum-light-4);
79
+ --accent-9: var(--plum-light-9);
80
+ --accent-10: var(--plum-light-10);
81
+ --accent-text: var(--plum-light-11);
82
+ --accent-a1: var(--plum-light-a1);
83
+ --accent-a2: var(--plum-light-a2);
84
+ --accent-a3: var(--plum-light-a3);
85
+ --accent-a6: var(--plum-light-a6);
86
+ --accent-a8: var(--plum-light-a8);
87
+ --accent-a10: var(--plum-light-a10);
88
+ --accent-a12: var(--plum-light-a12);
89
+
90
+ /* Surface: Plum Light-toningar för alla 8 nivåer. Måste sättas här -
91
+ app-base sätter plum-N (dark-rampen) och vinner annars över
92
+ [data-theme="light"]-overriden i 10-semantic.css. */
93
+ --surface-page: var(--plum-light-1);
94
+ --surface-default: var(--plum-light-2);
95
+ --surface-raised: var(--plum-light-3);
96
+ --surface-elevated: var(--plum-light-4);
97
+ --surface-overlay: var(--plum-light-5);
98
+ --surface-hover: var(--plum-light-4);
99
+ --surface-active: var(--plum-light-5);
100
+ --surface-sunken: var(--plum-light-1);
101
+
102
+ /* Text-default: mörk i light. App-base sätter Ekonoms varma plum-vit
103
+ #F4F2FA som vinner annars över [data-theme="light"]. */
104
+ --text-default: var(--gray-light-12);
105
+
106
+ /* Glass-bg: neutral grå-tint mot ljus page (iOS UIBlurEffect-konvention).
107
+ App-base sätter surface-raised 65% som vinner annars över
108
+ [data-theme="light"]. */
109
+ --glass-bg: color-mix(in oklch, var(--gray-light-6) 55%, transparent);
110
+
111
+ /* Border-focus: Plum accent */
112
+ --border-focus: var(--plum-light-8);
113
+ }
package/css/apps/jubb.css CHANGED
@@ -51,3 +51,51 @@
51
51
  [data-app="jubb"] {
52
52
  --glass-bg: color-mix(in oklch, var(--surface-raised) 65%, transparent);
53
53
  }
54
+
55
+
56
+ /* Light mode-override per app - Blue Light-rampen + Blue-tonad page.
57
+ Konsumeras när <html data-app="jubb" data-theme="light">. Se ADR 0028.
58
+
59
+ (0,2,0) specificity - vinner garanterat över både [data-app]-block
60
+ och [data-theme]-block var för sig. Alla tokens som [data-app="jubb"]
61
+ sätter måste även sättas här för light mode - annars vinner app-base
62
+ över semantic [data-theme="light"]-overriden via load-order. */
63
+ [data-app="jubb"][data-theme="light"] {
64
+ /* Accent: Blue Light-rampen */
65
+ --accent-soft: var(--blue-light-3);
66
+ --accent-moderate: var(--blue-light-4);
67
+ --accent-9: var(--blue-light-9);
68
+ --accent-10: var(--blue-light-10);
69
+ --accent-text: var(--blue-light-11);
70
+ --accent-a1: var(--blue-light-a1);
71
+ --accent-a2: var(--blue-light-a2);
72
+ --accent-a3: var(--blue-light-a3);
73
+ --accent-a6: var(--blue-light-a6);
74
+ --accent-a8: var(--blue-light-a8);
75
+ --accent-a10: var(--blue-light-a10);
76
+ --accent-a12: var(--blue-light-a12);
77
+
78
+ /* Surface: Blue Light-toningar för alla 8 nivåer. Måste sättas här -
79
+ app-base sätter blue-N (dark-rampen) och vinner annars över
80
+ [data-theme="light"]-overriden i 10-semantic.css. */
81
+ --surface-page: var(--blue-light-1);
82
+ --surface-default: var(--blue-light-2);
83
+ --surface-raised: var(--blue-light-3);
84
+ --surface-elevated: var(--blue-light-4);
85
+ --surface-overlay: var(--blue-light-5);
86
+ --surface-hover: var(--blue-light-4);
87
+ --surface-active: var(--blue-light-5);
88
+ --surface-sunken: var(--blue-light-1);
89
+
90
+ /* Text-default: mörk i light. App-base sätter Jubbs varma vit
91
+ #EEF4FF som vinner annars över [data-theme="light"]. */
92
+ --text-default: var(--gray-light-12);
93
+
94
+ /* Glass-bg: neutral grå-tint mot ljus page (iOS UIBlurEffect-konvention).
95
+ App-base sätter surface-raised 65% som vinner annars över
96
+ [data-theme="light"]. */
97
+ --glass-bg: color-mix(in oklch, var(--gray-light-6) 55%, transparent);
98
+
99
+ /* Border-focus: Blue accent */
100
+ --border-focus: var(--blue-light-8);
101
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@klodd/ds",
3
- "version": "5.14.0",
3
+ "version": "5.15.0",
4
4
  "description": "Klodd shared design system - tokens, components, JS",
5
5
  "main": "css/index.css",
6
6
  "bin": {
@@ -116,6 +116,36 @@ Commit: Jubb dffb7eb
116
116
  "när-använda-vilken-kombination"-tabeller (t.ex. card vs panel
117
117
  för list-items, hub-card vs setting-row för settings).
118
118
 
119
+ ## Light mode-tillägg (2026-05-26)
120
+
121
+ Dark mode-doktrinen (ingen box-shadow, luminans skapar djup) gäller
122
+ bara dark mode. I light mode gäller spegellogiken:
123
+
124
+ - box-shadow är förväntad och nödvändig på raised-ytor
125
+ - --shadow-card och --shadow-float definieras om i
126
+ [data-theme="light"]-blocket med synliga värden
127
+ - Luminans-hierarkin finns kvar men är svagare i light
128
+ (ljusa ytor mot vit bakgrund ger liten kontrast utan skugga)
129
+
130
+ Konkreta värden för light mode:
131
+
132
+ ```css
133
+ --shadow-card: 0 1px 3px color-mix(in oklch, var(--gray-12) 12%, transparent),
134
+ 0 1px 2px color-mix(in oklch, var(--gray-12) 8%, transparent);
135
+ --shadow-float: 0 4px 12px color-mix(in oklch, var(--gray-12) 16%, transparent),
136
+ 0 2px 4px color-mix(in oklch, var(--gray-12) 10%, transparent);
137
+ ```
138
+
139
+ I light mode är --gray-12 mörk (Mauve Light steg 12, #211f26 ≈ mörk
140
+ text), så color-mix ger synlig skugga. Token-systemet löser
141
+ korrekthet automatiskt när --gray-N mappas till light-rampen via
142
+ `[data-theme="light"]`-overriden.
143
+
144
+ Light-primitives (Mauve/Blue/Plum/Status Light) lagda i
145
+ 00-primitives.css 2026-05-26 som förberedelse - 78 nya variabler
146
+ med `-light-`-suffix. Konsumeras i nästa fas när
147
+ [data-theme="light"]-blocket adderas till 10-semantic.css.
148
+
119
149
  ## References
120
150
 
121
151
  - `references/DESIGN-LANGUAGE.md` (locked doktrin)
@@ -0,0 +1,37 @@
1
+ # 0028 - Light mode-arkitektur
2
+
3
+ ## Status
4
+ Locked. Implementerat 2026-05-26.
5
+
6
+ ## Decision
7
+
8
+ Light mode aktiveras via `data-theme="light"` på `<html>`-elementet.
9
+ System-default från `prefers-color-scheme`, manuell override via
10
+ LocalStorage (implementeras per app i Fas 3).
11
+
12
+ Token-override-strategi: `[data-theme="light"]`-block i
13
+ 10-semantic.css overridar surface/text/border/shadow/glass.
14
+ App-specifika accenter overridas i
15
+ `[data-app="X"][data-theme="light"]` i respektive apps/X.css.
16
+
17
+ Komponentskiktet rörs inte - det är 100% token-baserat och följer
18
+ automatiskt.
19
+
20
+ Shadow-doktrin light mode: se ADR 0013 light mode-tillägg.
21
+
22
+ Glass light mode: `--gray-light-6` 55% transparent (istället för
23
+ surface-raised 65%). Motiverat av iOS UIBlurEffect-konventionen
24
+ för light backgrounds där en svagt mörkare tint över ljus bakgrund
25
+ ger glaseffekten - omvänt mot dark mode.
26
+
27
+ Primitives-grund: 78 Radix Light-variabler i 00-primitives.css
28
+ (Mauve/Blue/Plum/Status Light, hex-värden hämtade från
29
+ `@radix-ui/colors` v3.0.0 via unpkg 2026-05-26).
30
+
31
+ ## Consequences
32
+
33
+ - Persistens är per enhet (LocalStorage), inte server-side - avsiktligt
34
+ för att stödja olika teman på olika enheter från samma konto
35
+ - Fas 3 (toggle-JS + visuell QA per app) genomförs separat per app
36
+ - Token-systemet löser komponent-korrekthet automatiskt - inga
37
+ komponent-CSS-edits krävs i light mode