@dialpad/dialtone-css 8.80.0-next.6 → 8.80.0-next.8

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.
Files changed (144) hide show
  1. package/lib/build/js/dialtone_migrate_border_radius/index.mjs +273 -0
  2. package/lib/build/js/dialtone_migrate_border_radius/test.mjs +422 -0
  3. package/lib/build/js/dialtone_migrate_typography/index.mjs +1628 -0
  4. package/lib/build/js/dialtone_migrate_typography/test.mjs +1020 -0
  5. package/lib/build/js/dialtone_migration_helper/configs/theme-to-mode.mjs +108 -0
  6. package/lib/build/js/dialtone_migration_helper/tests/theme-to-mode-test-examples.vue +24 -0
  7. package/lib/build/js/dialtone_migration_helper/tests/theme-to-mode.test.mjs +177 -0
  8. package/lib/build/less/components/box.less +11 -3
  9. package/lib/build/less/components/button.less +32 -25
  10. package/lib/build/less/components/card.less +1 -1
  11. package/lib/build/less/components/chip.less +32 -0
  12. package/lib/build/less/components/emoji-picker.less +10 -11
  13. package/lib/build/less/components/forms.less +22 -16
  14. package/lib/build/less/components/image-viewer.less +1 -0
  15. package/lib/build/less/components/modal.less +9 -3
  16. package/lib/build/less/components/notice.less +4 -0
  17. package/lib/build/less/components/popover.less +2 -2
  18. package/lib/build/less/components/presence.less +23 -3
  19. package/lib/build/less/components/toast.less +2 -2
  20. package/lib/build/less/recipes/leftbar_row.less +1 -0
  21. package/lib/build/less/recipes/unread_pill.less +1 -1
  22. package/lib/build/less/utilities/effects.less +11 -5
  23. package/lib/dist/dialtone-default-theme.css +608 -162
  24. package/lib/dist/dialtone-default-theme.min.css +1 -1
  25. package/lib/dist/dialtone-docs.json +1 -1
  26. package/lib/dist/dialtone.css +446 -118
  27. package/lib/dist/dialtone.min.css +1 -1
  28. package/lib/dist/js/dialtone_migrate_border_radius/index.mjs +273 -0
  29. package/lib/dist/js/dialtone_migrate_border_radius/test.mjs +422 -0
  30. package/lib/dist/js/dialtone_migrate_typography/index.mjs +1628 -0
  31. package/lib/dist/js/dialtone_migrate_typography/test.mjs +1020 -0
  32. package/lib/dist/js/dialtone_migration_helper/configs/theme-to-mode.mjs +108 -0
  33. package/lib/dist/js/dialtone_migration_helper/tests/theme-to-mode-test-examples.vue +24 -0
  34. package/lib/dist/js/dialtone_migration_helper/tests/theme-to-mode.test.mjs +177 -0
  35. package/lib/dist/tokens/tokens-101-dark.css +1 -0
  36. package/lib/dist/tokens/tokens-101-light.css +1 -0
  37. package/lib/dist/tokens/tokens-102-dark.css +1 -0
  38. package/lib/dist/tokens/tokens-102-light.css +1 -0
  39. package/lib/dist/tokens/tokens-103-dark.css +1 -0
  40. package/lib/dist/tokens/tokens-103-light.css +1 -0
  41. package/lib/dist/tokens/tokens-104-dark.css +1 -0
  42. package/lib/dist/tokens/tokens-104-light.css +1 -0
  43. package/lib/dist/tokens/tokens-105-dark.css +1 -0
  44. package/lib/dist/tokens/tokens-105-light.css +1 -0
  45. package/lib/dist/tokens/tokens-106-dark.css +1 -0
  46. package/lib/dist/tokens/tokens-106-light.css +1 -0
  47. package/lib/dist/tokens/tokens-107-dark.css +1 -0
  48. package/lib/dist/tokens/tokens-107-light.css +1 -0
  49. package/lib/dist/tokens/tokens-108-dark.css +1 -0
  50. package/lib/dist/tokens/tokens-108-light.css +1 -0
  51. package/lib/dist/tokens/tokens-109-dark.css +1 -0
  52. package/lib/dist/tokens/tokens-109-light.css +1 -0
  53. package/lib/dist/tokens/tokens-110-dark.css +1 -0
  54. package/lib/dist/tokens/tokens-110-light.css +1 -0
  55. package/lib/dist/tokens/tokens-111-dark.css +1 -0
  56. package/lib/dist/tokens/tokens-111-light.css +1 -0
  57. package/lib/dist/tokens/tokens-112-dark.css +1 -0
  58. package/lib/dist/tokens/tokens-112-light.css +1 -0
  59. package/lib/dist/tokens/tokens-113-dark.css +1 -0
  60. package/lib/dist/tokens/tokens-113-light.css +1 -0
  61. package/lib/dist/tokens/tokens-114-dark.css +1 -0
  62. package/lib/dist/tokens/tokens-114-light.css +1 -0
  63. package/lib/dist/tokens/tokens-115-dark.css +1 -0
  64. package/lib/dist/tokens/tokens-115-light.css +1 -0
  65. package/lib/dist/tokens/tokens-116-dark.css +1 -0
  66. package/lib/dist/tokens/tokens-116-light.css +1 -0
  67. package/lib/dist/tokens/tokens-117-dark.css +1 -0
  68. package/lib/dist/tokens/tokens-117-light.css +1 -0
  69. package/lib/dist/tokens/tokens-118-dark.css +1 -0
  70. package/lib/dist/tokens/tokens-118-light.css +1 -0
  71. package/lib/dist/tokens/tokens-119-dark.css +1 -0
  72. package/lib/dist/tokens/tokens-119-light.css +1 -0
  73. package/lib/dist/tokens/tokens-120-dark.css +1 -0
  74. package/lib/dist/tokens/tokens-120-light.css +1 -0
  75. package/lib/dist/tokens/tokens-121-dark.css +1 -0
  76. package/lib/dist/tokens/tokens-121-light.css +1 -0
  77. package/lib/dist/tokens/tokens-122-dark.css +1 -0
  78. package/lib/dist/tokens/tokens-122-light.css +1 -0
  79. package/lib/dist/tokens/tokens-123-dark.css +1 -0
  80. package/lib/dist/tokens/tokens-123-light.css +1 -0
  81. package/lib/dist/tokens/tokens-124-dark.css +1 -0
  82. package/lib/dist/tokens/tokens-124-light.css +1 -0
  83. package/lib/dist/tokens/tokens-125-dark.css +1 -0
  84. package/lib/dist/tokens/tokens-125-light.css +1 -0
  85. package/lib/dist/tokens/tokens-126-dark.css +1 -0
  86. package/lib/dist/tokens/tokens-126-light.css +1 -0
  87. package/lib/dist/tokens/tokens-127-dark.css +1 -0
  88. package/lib/dist/tokens/tokens-127-light.css +1 -0
  89. package/lib/dist/tokens/tokens-128-dark.css +1 -0
  90. package/lib/dist/tokens/tokens-128-light.css +1 -0
  91. package/lib/dist/tokens/tokens-129-dark.css +1 -0
  92. package/lib/dist/tokens/tokens-129-light.css +1 -0
  93. package/lib/dist/tokens/tokens-130-dark.css +1 -0
  94. package/lib/dist/tokens/tokens-130-light.css +1 -0
  95. package/lib/dist/tokens/tokens-131-dark.css +1 -0
  96. package/lib/dist/tokens/tokens-131-light.css +1 -0
  97. package/lib/dist/tokens/tokens-132-dark.css +1 -0
  98. package/lib/dist/tokens/tokens-132-light.css +1 -0
  99. package/lib/dist/tokens/tokens-133-dark.css +1 -0
  100. package/lib/dist/tokens/tokens-133-light.css +1 -0
  101. package/lib/dist/tokens/tokens-134-dark.css +1 -0
  102. package/lib/dist/tokens/tokens-134-light.css +1 -0
  103. package/lib/dist/tokens/tokens-135-dark.css +1 -0
  104. package/lib/dist/tokens/tokens-135-light.css +1 -0
  105. package/lib/dist/tokens/tokens-136-dark.css +1 -0
  106. package/lib/dist/tokens/tokens-136-light.css +1 -0
  107. package/lib/dist/tokens/tokens-137-dark.css +1 -0
  108. package/lib/dist/tokens/tokens-137-light.css +1 -0
  109. package/lib/dist/tokens/tokens-aegean-dark.css +1 -0
  110. package/lib/dist/tokens/tokens-aegean-light.css +1 -0
  111. package/lib/dist/tokens/tokens-base-dark.css +267 -126
  112. package/lib/dist/tokens/tokens-base-light.css +161 -44
  113. package/lib/dist/tokens/tokens-botany-dark.css +1 -0
  114. package/lib/dist/tokens/tokens-botany-light.css +1 -0
  115. package/lib/dist/tokens/tokens-buttercream-dark.css +1 -0
  116. package/lib/dist/tokens/tokens-buttercream-light.css +1 -0
  117. package/lib/dist/tokens/tokens-ceruleo-dark.css +1 -0
  118. package/lib/dist/tokens/tokens-ceruleo-light.css +1 -0
  119. package/lib/dist/tokens/tokens-debug-base.css +158 -41
  120. package/lib/dist/tokens/tokens-debug-dp.css +1 -0
  121. package/lib/dist/tokens/tokens-dp-dark.css +1 -0
  122. package/lib/dist/tokens/tokens-dp-light.css +1 -0
  123. package/lib/dist/tokens/tokens-expressive-dark.css +1 -0
  124. package/lib/dist/tokens/tokens-expressive-light.css +1 -0
  125. package/lib/dist/tokens/tokens-expressive-sm-dark.css +1 -0
  126. package/lib/dist/tokens/tokens-expressive-sm-light.css +1 -0
  127. package/lib/dist/tokens/tokens-high-desert-dark.css +1 -0
  128. package/lib/dist/tokens/tokens-high-desert-light.css +1 -0
  129. package/lib/dist/tokens/tokens-melon-dark.css +1 -0
  130. package/lib/dist/tokens/tokens-melon-light.css +1 -0
  131. package/lib/dist/tokens/tokens-plum-dark.css +1 -0
  132. package/lib/dist/tokens/tokens-plum-light.css +1 -0
  133. package/lib/dist/tokens/tokens-prota-deuter-dark.css +1 -0
  134. package/lib/dist/tokens/tokens-prota-deuter-light.css +1 -0
  135. package/lib/dist/tokens/tokens-sunflower-dark.css +1 -0
  136. package/lib/dist/tokens/tokens-sunflower-light.css +1 -0
  137. package/lib/dist/tokens/tokens-tmo-dark.css +1 -0
  138. package/lib/dist/tokens/tokens-tmo-light.css +1 -0
  139. package/lib/dist/tokens/tokens-trita-dark.css +1 -0
  140. package/lib/dist/tokens/tokens-trita-light.css +1 -0
  141. package/lib/dist/tokens/tokens-verdant-haze-dark.css +1 -0
  142. package/lib/dist/tokens/tokens-verdant-haze-light.css +1 -0
  143. package/lib/dist/tokens-docs.json +1 -1
  144. package/package.json +5 -3
@@ -0,0 +1,108 @@
1
+ // Migration: deprecated `setTheme()` and `data-dt-theme` attribute → layered API.
2
+ //
3
+ // - Startup call: setTheme(KnownTheme) → initDialtoneTheme(KnownTheme, 'mode')
4
+ // - Dynamic calls: setTheme(expr) → flagged with TODO comment
5
+ // - HTML attributes: data-dt-theme= → data-dt-mode=
6
+ // - JS attribute methods: setAttribute/getAttribute('data-dt-theme') → 'data-dt-mode'
7
+ // - CSS selectors: [data-dt-theme...] → [data-dt-mode...]
8
+ // - Invert regions (data-dt-theme="invert") are flagged with a TODO comment
9
+ // rather than auto-rewritten — the v-dt-mode directive uses a live
10
+ // MutationObserver that cannot be replicated with a static replacement.
11
+
12
+ // Identifiers and their mode extracted from the known legacy theme names.
13
+ const KNOWN_LIGHT = ['DpLight', 'TmoLight', 'ExpressiveLight', 'ExpressiveSmLight'];
14
+ const KNOWN_DARK = ['DpDark', 'TmoDark', 'ExpressiveDark', 'ExpressiveSmDark'];
15
+ const ALL_KNOWN = [...KNOWN_LIGHT, ...KNOWN_DARK];
16
+ const KNOWN_PATTERN = ALL_KNOWN.join('|');
17
+
18
+ export default {
19
+ description:
20
+ 'Migrates from the deprecated setTheme() / data-dt-theme API to the layered theming API.\n' +
21
+ '- setTheme(DpLight) → initDialtoneTheme(DpLight, \'light\')\n' +
22
+ '- setTheme(DpDark) → initDialtoneTheme(DpDark, \'dark\')\n' +
23
+ '- Same for TmoLight, TmoDark, ExpressiveLight, ExpressiveDark, ExpressiveSmLight, ExpressiveSmDark\n' +
24
+ '- setTheme(dynamicExpr) → preserved + TODO comment\n' +
25
+ '- data-dt-theme= → data-dt-mode= (HTML attributes, JS attr methods, CSS selectors)\n' +
26
+ '- data-dt-theme="invert" → preserved + TODO comment (review for v-dt-mode directive)\n',
27
+
28
+ patterns: ['**/*.{vue,html,js,ts,jsx,tsx,css,less,scss,mjs}'],
29
+
30
+ globbyConfig: {
31
+ ignore: [
32
+ '**/dialtone_migration_helper/tests/**',
33
+ '**/guides/migration/theme-to-mode/**',
34
+ '**/guides/theme-and-mode/index.md',
35
+ '**/whats-new/posts/2024-8-1.md',
36
+ ],
37
+ },
38
+
39
+ expressions: [
40
+ // 1. setTheme() call rewrites for known light identifiers.
41
+ // Must run BEFORE the unknown-call flag expression (3) so these are
42
+ // fully consumed before the fallthrough regex fires.
43
+ {
44
+ from: new RegExp(
45
+ `(?<!\\.)setTheme\\(\\s*(${KNOWN_LIGHT.join('|')})\\s*\\)`,
46
+ 'g',
47
+ ),
48
+ to: (_match, identifier) => `initDialtoneTheme(${identifier}, 'light')`,
49
+ },
50
+
51
+ // 2. setTheme() call rewrites for known dark identifiers.
52
+ {
53
+ from: new RegExp(
54
+ `(?<!\\.)setTheme\\(\\s*(${KNOWN_DARK.join('|')})\\s*\\)`,
55
+ 'g',
56
+ ),
57
+ to: (_match, identifier) => `initDialtoneTheme(${identifier}, 'dark')`,
58
+ },
59
+
60
+ // 3. setTheme() calls with unknown / dynamic arguments → TODO comment.
61
+ // Negative-lookahead skips the eight known identifiers already rewritten above.
62
+ // Negative-lookbehind on '.' prevents matching unrelated .setTheme() methods.
63
+ {
64
+ from: new RegExp(
65
+ `(?<!\\.)setTheme\\(\\s*(?!(${KNOWN_PATTERN})\\s*\\))([^)]*)\\)`,
66
+ 'g',
67
+ ),
68
+ to: (match) =>
69
+ `// TODO: review for layered API migration — see /guides/migration/theme-to-mode/\n${match}`,
70
+ },
71
+
72
+ // 4. Attribute rename: data-dt-theme → data-dt-mode
73
+ // Covers HTML/Vue/JSX attributes, JS string literals, and CSS selectors.
74
+ // Negative lookahead (?!-) prevents matching data-dt-theme-x (longer names).
75
+ // Works correctly with applyConfig's inner match.replace() since the inner
76
+ // call operates on just the matched text "data-dt-theme" where (?!-) passes
77
+ // at end-of-string (no "-" follows).
78
+ {
79
+ from: /\bdata-dt-theme(?!-)/g,
80
+ to: () => 'data-dt-mode',
81
+ },
82
+
83
+ // 5. CSS selector invert — add TODO comment before the renamed selector.
84
+ // Expression 5 already renamed [data-dt-theme=...] → [data-dt-mode=...],
85
+ // so we match on the result. HTML attribute invert is handled by
86
+ // expression 5 (just renamed, no comment — inserting HTML comments inside
87
+ // tags produces invalid markup; consumers grep for data-dt-mode="invert"
88
+ // to find regions needing v-dt-mode review).
89
+ {
90
+ from: /\[data-dt-mode="invert"\]|\[data-dt-mode=invert\]/g,
91
+ to: (match) =>
92
+ `/* TODO: review for v-dt-mode adoption — see /guides/migration/theme-to-mode/ */\n${match}`,
93
+ },
94
+
95
+ // 6. JS attribute methods: setAttribute/getAttribute/etc. on 'data-dt-theme'
96
+ {
97
+ from: /(\.(?:set|get|toggle|remove|has)Attribute\(\s*['"])data-dt-theme(['"])/g,
98
+ to: (_match, prefix, suffix) => `${prefix}data-dt-mode${suffix}`,
99
+ },
100
+
101
+ // 7. CSS attribute selectors: [data-dt-theme...] → [data-dt-mode...]
102
+ // Runs after the invert-flagging expressions to avoid double-processing.
103
+ {
104
+ from: /\[data-dt-theme(\]|=[^\]]*\])/g,
105
+ to: (_match, rest) => `[data-dt-mode${rest}`,
106
+ },
107
+ ],
108
+ };
@@ -0,0 +1,24 @@
1
+ <template>
2
+ <!-- Module path example (should be rewritten by codemod) -->
3
+ <section data-dt-theme="light">
4
+ Light mode section
5
+ </section>
6
+
7
+ <!-- CSS selector example (for stylesheet tests) -->
8
+ <div class="themed-container">
9
+ Theme-aware container
10
+ </div>
11
+ </template>
12
+
13
+ <script>
14
+ // Legacy imports — these paths and calls are transformed by the codemod
15
+ import DpLight from '@dialpad/dialtone/themes/dp-light';
16
+ import DpDark from '@dialpad/dialtone/themes/dp-dark';
17
+ import { setTheme } from '@dialpad/dialtone/themes/config';
18
+
19
+ // Startup initialization
20
+ setTheme(DpLight);
21
+
22
+ // Mode switching (runtime)
23
+ setTheme(DpDark);
24
+ </script>
@@ -0,0 +1,177 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import config from '../configs/theme-to-mode.mjs';
4
+ import { applyConfig } from './helpers.mjs';
5
+
6
+ const apply = (input) => applyConfig(config, input);
7
+
8
+ describe('theme-to-mode config', () => {
9
+ // ─── setTheme call rewrites ───────────────────────────────────────────────
10
+
11
+ describe('setTheme() → initDialtoneTheme() for known identifiers', () => {
12
+ it('rewrites setTheme(DpLight) → initDialtoneTheme(DpLight, \'light\')', () => {
13
+ const input = `setTheme(DpLight);`;
14
+ const expected = `initDialtoneTheme(DpLight, 'light');`;
15
+ assert.equal(apply(input), expected);
16
+ });
17
+
18
+ it('rewrites setTheme(DpDark) → initDialtoneTheme(DpDark, \'dark\')', () => {
19
+ const input = `setTheme(DpDark);`;
20
+ const expected = `initDialtoneTheme(DpDark, 'dark');`;
21
+ assert.equal(apply(input), expected);
22
+ });
23
+
24
+ it('rewrites setTheme(TmoLight) → initDialtoneTheme(TmoLight, \'light\')', () => {
25
+ const input = `setTheme(TmoLight);`;
26
+ const expected = `initDialtoneTheme(TmoLight, 'light');`;
27
+ assert.equal(apply(input), expected);
28
+ });
29
+
30
+ it('rewrites setTheme(TmoDark) → initDialtoneTheme(TmoDark, \'dark\')', () => {
31
+ const input = `setTheme(TmoDark);`;
32
+ const expected = `initDialtoneTheme(TmoDark, 'dark');`;
33
+ assert.equal(apply(input), expected);
34
+ });
35
+
36
+ it('rewrites setTheme(ExpressiveLight) → initDialtoneTheme(ExpressiveLight, \'light\')', () => {
37
+ const input = `setTheme(ExpressiveLight);`;
38
+ const expected = `initDialtoneTheme(ExpressiveLight, 'light');`;
39
+ assert.equal(apply(input), expected);
40
+ });
41
+
42
+ it('rewrites setTheme(ExpressiveDark) → initDialtoneTheme(ExpressiveDark, \'dark\')', () => {
43
+ const input = `setTheme(ExpressiveDark);`;
44
+ const expected = `initDialtoneTheme(ExpressiveDark, 'dark');`;
45
+ assert.equal(apply(input), expected);
46
+ });
47
+
48
+ it('handles whitespace inside setTheme call', () => {
49
+ const input = `setTheme( DpLight );`;
50
+ const expected = `initDialtoneTheme(DpLight, 'light');`;
51
+ assert.equal(apply(input), expected);
52
+ });
53
+
54
+ it('rewrites setTheme(DpLight) as part of onMounted setup', () => {
55
+ const input = `onMounted(() => { setTheme(DpLight); });`;
56
+ const expected = `onMounted(() => { initDialtoneTheme(DpLight, 'light'); });`;
57
+ assert.equal(apply(input), expected);
58
+ });
59
+
60
+ it('does NOT rewrite setTheme() with a dynamic variable — emits TODO comment', () => {
61
+ const input = `setTheme(myDynamicTheme);`;
62
+ const result = apply(input);
63
+ assert.ok(result.includes('setTheme(myDynamicTheme)'), 'original call preserved');
64
+ assert.ok(result.includes('TODO: review for layered API migration'), 'TODO comment inserted');
65
+ });
66
+
67
+ it('does NOT rewrite setTheme() with an expression — emits TODO comment', () => {
68
+ const input = `setTheme(isDark ? DpDark : DpLight);`;
69
+ const result = apply(input);
70
+ assert.ok(result.includes('setTheme(isDark ? DpDark : DpLight)'), 'original call preserved');
71
+ assert.ok(result.includes('TODO: review for layered API migration'), 'TODO comment inserted');
72
+ });
73
+
74
+ it('does NOT rewrite myObj.setTheme() — unrelated method', () => {
75
+ const input = `myThemeManager.setTheme(DpLight);`;
76
+ assert.equal(apply(input), input);
77
+ });
78
+ });
79
+
80
+ // ─── Attribute renames ────────────────────────────────────────────────────
81
+
82
+ describe('data-dt-theme → data-dt-mode in HTML attributes', () => {
83
+ it('rewrites data-dt-theme= in HTML attribute', () => {
84
+ const input = `<html data-dt-theme="dp-light">`;
85
+ const expected = `<html data-dt-mode="dp-light">`;
86
+ assert.equal(apply(input), expected);
87
+ });
88
+
89
+ it('rewrites data-dt-theme= with single quotes', () => {
90
+ const input = `<section data-dt-theme='dark'>content</section>`;
91
+ const expected = `<section data-dt-mode='dark'>content</section>`;
92
+ assert.equal(apply(input), expected);
93
+ });
94
+
95
+ it('does NOT rewrite data-dt-theme-x (longer attribute with same prefix)', () => {
96
+ const input = `<div data-dt-theme-custom="foo">`;
97
+ assert.equal(apply(input), input);
98
+ });
99
+
100
+ it('rewrites data-dt-theme= in Vue template binding (static)', () => {
101
+ const input = `<div data-dt-theme="light">`;
102
+ const expected = `<div data-dt-mode="light">`;
103
+ assert.equal(apply(input), expected);
104
+ });
105
+ });
106
+
107
+ describe('data-dt-theme in JS setAttribute/getAttribute', () => {
108
+ it('rewrites setAttribute first argument', () => {
109
+ const input = `el.setAttribute('data-dt-theme', 'dark');`;
110
+ const expected = `el.setAttribute('data-dt-mode', 'dark');`;
111
+ assert.equal(apply(input), expected);
112
+ });
113
+
114
+ it('rewrites getAttribute first argument', () => {
115
+ const input = `const mode = el.getAttribute('data-dt-theme');`;
116
+ const expected = `const mode = el.getAttribute('data-dt-mode');`;
117
+ assert.equal(apply(input), expected);
118
+ });
119
+
120
+ it('rewrites removeAttribute first argument', () => {
121
+ const input = `el.removeAttribute('data-dt-theme');`;
122
+ const expected = `el.removeAttribute('data-dt-mode');`;
123
+ assert.equal(apply(input), expected);
124
+ });
125
+
126
+ it('rewrites hasAttribute first argument', () => {
127
+ const input = `if (el.hasAttribute('data-dt-theme')) {`;
128
+ const expected = `if (el.hasAttribute('data-dt-mode')) {`;
129
+ assert.equal(apply(input), expected);
130
+ });
131
+ });
132
+
133
+ describe('data-dt-theme in CSS attribute selectors', () => {
134
+ it('rewrites [data-dt-theme] bare selector', () => {
135
+ const input = `[data-dt-theme] { color: red; }`;
136
+ const expected = `[data-dt-mode] { color: red; }`;
137
+ assert.equal(apply(input), expected);
138
+ });
139
+
140
+ it('rewrites [data-dt-theme="value"] selector', () => {
141
+ const input = `[data-dt-theme="dp-light"] { background: white; }`;
142
+ const expected = `[data-dt-mode="dp-light"] { background: white; }`;
143
+ assert.equal(apply(input), expected);
144
+ });
145
+
146
+ it('rewrites [data-dt-theme=value] selector (unquoted)', () => {
147
+ const input = `[data-dt-theme=light] .d-banner { border: 1px; }`;
148
+ const expected = `[data-dt-mode=light] .d-banner { border: 1px; }`;
149
+ assert.equal(apply(input), expected);
150
+ });
151
+ });
152
+
153
+ // ─── Invert handling ──────────────────────────────────────────────────────
154
+
155
+ describe('data-dt-theme="invert" handling', () => {
156
+ it('renames data-dt-theme="invert" to data-dt-mode="invert" (grep to find for v-dt-mode review)', () => {
157
+ const input = `<section data-dt-theme="invert">content</section>`;
158
+ const result = apply(input);
159
+ assert.ok(result.includes('data-dt-mode="invert"'), 'attribute renamed');
160
+ assert.ok(!result.includes('data-dt-theme="invert"'), 'old attribute removed');
161
+ });
162
+
163
+ it('adds TODO comment before [data-dt-theme="invert"] CSS selector', () => {
164
+ const input = `[data-dt-theme="invert"] .d-card { box-shadow: none; }`;
165
+ const result = apply(input);
166
+ assert.ok(result.includes('[data-dt-mode="invert"]'), 'selector renamed');
167
+ assert.ok(result.includes('TODO: review for v-dt-mode adoption'), 'TODO inserted');
168
+ });
169
+
170
+ it('adds TODO comment before [data-dt-theme=invert] unquoted CSS selector', () => {
171
+ const input = `[data-dt-theme=invert] { background: red; }`;
172
+ const result = apply(input);
173
+ assert.ok(result.includes('[data-dt-mode=invert]'), 'selector renamed');
174
+ assert.ok(result.includes('TODO: review for v-dt-mode adoption'), 'TODO inserted');
175
+ });
176
+ });
177
+ });
@@ -62,6 +62,8 @@
62
62
  }
63
63
 
64
64
  ._box-layout(@prop) {
65
+ &-0 { @{prop}: 0; }
66
+
65
67
  &-1px { @{prop}: var(--dt-layout-1px); }
66
68
  &-2px { @{prop}: var(--dt-layout-2px); }
67
69
  &-8px { @{prop}: var(--dt-layout-8px); }
@@ -70,9 +72,15 @@
70
72
  &-24px { @{prop}: var(--dt-layout-24px); }
71
73
  &-50 { @{prop}: var(--dt-layout-50); }
72
74
  &-75 { @{prop}: var(--dt-layout-75); }
73
- each(range(0, 1600, 100), {
75
+
76
+ each(range(100, 200, 25), {
77
+ &-@{value} { @{prop}: ~"var(--dt-layout-@{value})"; }
78
+ });
79
+
80
+ each(range(250, 1600, 50), {
74
81
  &-@{value} { @{prop}: ~"var(--dt-layout-@{value})"; }
75
82
  });
83
+
76
84
  // Percentage tokens
77
85
  each(@box-layout-percent-values, {
78
86
  &-@{value}p { @{prop}: ~"var(--dt-layout-@{value}-percent)"; }
@@ -103,13 +111,13 @@
103
111
  // ============================================================================
104
112
  // $ VALUE LISTS
105
113
  // ----------------------------------------------------------------------------
106
- @box-surface-values: primary, secondary, moderate, bold, strong, contrast, backdrop, brand, info, warning, critical, positive, success, brand-subtle, brand-strong, info-subtle, info-strong, warning-subtle, warning-strong, critical-subtle, critical-strong, positive-subtle, positive-strong, success-subtle, success-strong, primary-opaque, secondary-opaque, moderate-opaque, bold-opaque, strong-opaque, contrast-opaque, brand-opaque, brand-subtle-opaque, info-opaque, info-subtle-opaque, warning-opaque, warning-subtle-opaque, critical-opaque, critical-subtle-opaque, positive-opaque, positive-subtle-opaque, success-opaque, success-subtle-opaque;
114
+ @box-surface-values: overlay, primary, secondary, moderate, bold, strong, contrast, backdrop, brand, info, warning, critical, positive, success, brand-subtle, brand-strong, info-subtle, info-strong, warning-subtle, warning-strong, critical-subtle, critical-strong, positive-subtle, positive-strong, success-subtle, success-strong, primary-opaque, secondary-opaque, moderate-opaque, bold-opaque, strong-opaque, contrast-opaque, brand-opaque, brand-subtle-opaque, info-opaque, info-subtle-opaque, warning-opaque, warning-subtle-opaque, critical-opaque, critical-subtle-opaque, positive-opaque, positive-subtle-opaque, success-opaque, success-subtle-opaque;
107
115
 
108
116
  @box-border-color-values: subtle, default, moderate, bold, accent, focus, brand, warning, critical, info, positive, success, brand-subtle, brand-strong, warning-subtle, warning-strong, critical-subtle, critical-strong, info-subtle, info-strong, positive-subtle, positive-strong, success-subtle, success-strong;
109
117
 
110
118
  @box-border-width-values: 0, 50, 100, 150, 200, 300, 400;
111
119
  @box-layout-percent-values: 10, 20, 25, 30, 33, 40, 50, 60, 66, 70, 75, 80, 90, 95, 100;
112
- @box-shadow-values: small, medium, large, extra-large, card;
120
+ @box-shadow-values: raised, overlay, modal;
113
121
  @box-overflow-values: hidden, scroll, auto, clip, visible;
114
122
 
115
123
  @layer dialtone.components {
@@ -113,31 +113,6 @@
113
113
  box-shadow: var(--dt-shadow-focus);
114
114
  }
115
115
 
116
- &--disabled,
117
- &:disabled {
118
- --chroma-adjust-text: .08;
119
- --chroma-adjust-background: .08;
120
- --chroma-adjust-border: .08;
121
- --opacity-adjust-text: 65%;
122
- --opacity-adjust-background: 65%;
123
- --opacity-adjust-border: 40%;
124
-
125
- color: color-mix(in oklch, oklch( from var(--button-color-text) l calc(c - var(--chroma-adjust-text)) h ) var(--opacity-adjust-text), transparent );
126
- background-color: color-mix(in oklch, oklch( from var(--button-color-background) l calc(c - var(--chroma-adjust-background)) h ) var(--opacity-adjust-background), transparent );
127
- border-color: color-mix(in oklch, oklch( from var(--button-color-border) l calc(c - var(--chroma-adjust-border)) h ) var(--opacity-adjust-border), transparent );
128
- cursor: not-allowed;
129
- transition: none;
130
- pointer-events: none;
131
-
132
- &.d-btn--primary {
133
- --opacity-adjust-text: 80%;
134
- }
135
-
136
- &.d-btn--muted {
137
- --opacity-adjust-text: 50%;
138
- --opacity-adjust-border: 50%;
139
- }
140
- }
141
116
  }
142
117
 
143
118
  ._btn-circle() {
@@ -207,6 +182,36 @@
207
182
  ._btn();
208
183
  }
209
184
 
185
+ .d-btn:where(.d-btn--disabled, :disabled),
186
+ .d-btn--md:where(.d-btn--disabled, :disabled) {
187
+ --chroma-adjust-text: .08;
188
+ --chroma-adjust-background: .08;
189
+ --chroma-adjust-border: .08;
190
+ --opacity-adjust-text: 65%;
191
+ --opacity-adjust-background: 65%;
192
+ --opacity-adjust-border: 40%;
193
+
194
+ color: color-mix(in oklch, oklch( from var(--button-color-text) l calc(c - var(--chroma-adjust-text)) h ) var(--opacity-adjust-text), transparent );
195
+ background-color: color-mix(in oklch, oklch( from var(--button-color-background) l calc(c - var(--chroma-adjust-background)) h ) var(--opacity-adjust-background), transparent );
196
+ border-color: color-mix(in oklch, oklch( from var(--button-color-border) l calc(c - var(--chroma-adjust-border)) h ) var(--opacity-adjust-border), transparent );
197
+ cursor: not-allowed;
198
+ transition: none;
199
+ pointer-events: none;
200
+
201
+ &:where(.d-btn--primary) {
202
+ --opacity-adjust-text: 80%;
203
+ }
204
+
205
+ &:where(.d-btn--muted) {
206
+ --opacity-adjust-text: 50%;
207
+ --opacity-adjust-border: 60%;
208
+ }
209
+
210
+ &:where(.d-btn--active):where(.d-btn--outlined, .d-btn--muted) {
211
+ --button-color-background: var(--dt-action-color-background-muted-active);
212
+ }
213
+ }
214
+
210
215
  .d-btn--unstyled {
211
216
  /* stylelint-disable */
212
217
  all: unset; // Must be first!
@@ -274,6 +279,7 @@
274
279
  // ----------------------------------------------------------------------------
275
280
  .d-btn__leading,
276
281
  .d-btn__trailing {
282
+ z-index: var(--zi-base1);
277
283
  display: inline-flex;
278
284
  align-items: center;
279
285
  align-self: stretch;
@@ -318,6 +324,7 @@
318
324
  }
319
325
 
320
326
  .d-btn__icon {
327
+ z-index: var(--zi-base1);
321
328
  display: flex;
322
329
 
323
330
  :where(.d-btn--disabled) & ,
@@ -25,7 +25,7 @@
25
25
  background: var(--dt-color-surface-primary);
26
26
  border: var(--dt-size-border-100) solid var(--dt-color-border-subtle);
27
27
  border-radius: var(--dt-size-radius-300);
28
- box-shadow: var(--dt-shadow-card);
28
+ box-shadow: var(--dt-shadow-raised);
29
29
  }
30
30
 
31
31
 
@@ -115,6 +115,38 @@
115
115
  }
116
116
  }
117
117
 
118
+ // Explicit disabled styling for chip close button.
119
+ // This duplicates the button disabled logic since the ._btn() mixin no longer includes disabled state handling.
120
+ // PLUS it may be simplified with upcoming Chip redesign/refactor
121
+ .d-chip__close:where(.d-chip__close--disabled, :disabled) {
122
+ --chroma-adjust-text: .08;
123
+ --chroma-adjust-background: .08;
124
+ --chroma-adjust-border: .08;
125
+ --opacity-adjust-text: 65%;
126
+ --opacity-adjust-background: 65%;
127
+ --opacity-adjust-border: 40%;
128
+
129
+ color: color-mix(in oklch, oklch( from var(--button-color-text) l calc(c - var(--chroma-adjust-text)) h ) var(--opacity-adjust-text), transparent );
130
+ background-color: color-mix(in oklch, oklch( from var(--button-color-background) l calc(c - var(--chroma-adjust-background)) h ) var(--opacity-adjust-background), transparent );
131
+ border-color: color-mix(in oklch, oklch( from var(--button-color-border) l calc(c - var(--chroma-adjust-border)) h ) var(--opacity-adjust-border), transparent );
132
+ cursor: not-allowed;
133
+ transition: none;
134
+ pointer-events: none;
135
+
136
+ &:where(.d-btn--primary) {
137
+ --opacity-adjust-text: 80%;
138
+ }
139
+
140
+ &:where(.d-btn--muted) {
141
+ --opacity-adjust-text: 50%;
142
+ --opacity-adjust-border: 60%;
143
+ }
144
+
145
+ &:where(.d-btn--active):where(.d-btn--outlined, .d-btn--muted) {
146
+ --button-color-background: var(--dt-action-color-background-muted-active);
147
+ }
148
+ }
149
+
118
150
  .d-chip__icon {
119
151
  --chip-icon-size: calc(var(--dt-layout-25) * 1.25);
120
152
 
@@ -17,7 +17,7 @@
17
17
  // with this width we have 9 emoji per row
18
18
  inline-size: var(--dt-layout-550);
19
19
  block-size: 100%;
20
- background-color: var(--dt-color-surface-primary);
20
+ background-color: var(--dt-color-surface-overlay);
21
21
  border-radius: var(--dt-size-radius-300);
22
22
 
23
23
  &--header {
@@ -28,8 +28,8 @@
28
28
  position: absolute;
29
29
  inset-inline: 0;
30
30
  inset-block-end: 0;
31
- block-size: var(--dt-size-border-200);
32
- background-color: var(--dt-color-surface-moderate) !important;
31
+ block-size: var(--dt-size-border-100);
32
+ background-color: var(--dt-color-border-subtle) !important;
33
33
  content: '';
34
34
  }
35
35
  }
@@ -49,7 +49,6 @@
49
49
  justify-content: space-between;
50
50
  block-size: calc(var(--dt-layout-100) - var(--dt-spacing-75));
51
51
  padding: 0 var(--dt-spacing-200);
52
- background: var(--dt-color-surface-secondary);
53
52
  border-block-start: var(--dt-size-border-100) solid var(--dt-color-border-subtle);
54
53
  }
55
54
 
@@ -62,7 +61,7 @@
62
61
  gap: var(--dt-spacing-0);
63
62
 
64
63
  &::after {
65
- background-color: var(--dt-color-surface-moderate) !important;
64
+ background-color: var(--dt-color-neutral-transparent) !important;
66
65
  }
67
66
 
68
67
  .d-tablist__item {
@@ -92,8 +91,8 @@
92
91
  margin: 0;
93
92
  padding: 0;
94
93
  background: none;
95
- border: var(--dt-size-border-100) solid transparent;
96
- border-radius: var(--dt-size-radius-350);
94
+ border: var(--dt-size-border-100) solid var(--dt-color-neutral-transparent);
95
+ border-radius: var(--dt-size-radius-circle);
97
96
  outline: none;
98
97
  cursor: pointer;
99
98
 
@@ -103,7 +102,7 @@
103
102
 
104
103
  &:active,
105
104
  &.selected {
106
- border-color: var(--dt-color-border-bold);
105
+ border-color: var(--dt-color-border-moderate);
107
106
  }
108
107
  }
109
108
  }
@@ -116,13 +115,13 @@
116
115
  margin: 0;
117
116
  padding: calc(var(--dt-spacing-75) + var(--dt-spacing-1));
118
117
  background: var(--dt-color-surface-moderate-opaque);
119
- border: none;
118
+ border: var(--dt-size-border-100) solid var(--dt-color-neutral-transparent);
120
119
  border-radius: var(--dt-size-radius-circle);
121
120
  outline: none;
122
121
  cursor: pointer;
123
122
 
124
123
  &:hover {
125
- background: var(--dt-color-surface-bold);
124
+ border-color: var(--dt-color-border-subtle);
126
125
  }
127
126
  }
128
127
  }
@@ -144,7 +143,7 @@
144
143
  inline-size: 100%;
145
144
  margin: 0;
146
145
  padding: var(--dt-spacing-200) var(--dt-spacing-200) 0 var(--dt-spacing-200);
147
- background: var(--dt-color-surface-primary);
146
+ background: var(--dt-color-surface-overlay);
148
147
  }
149
148
 
150
149
  &__list {
@@ -118,6 +118,8 @@ fieldset {
118
118
  // ----------------------------------------------------------------------------
119
119
  .d-validation-message {
120
120
  --validation-color-text: var(--dt-color-foreground-tertiary);
121
+ --validation-size-icon: var(--dt-layout-25);
122
+ --validation-icon: initial;
121
123
 
122
124
  display: flex;
123
125
  gap: var(--dt-spacing-50);
@@ -129,14 +131,15 @@ fieldset {
129
131
  font-family: inherit;
130
132
  line-height: var(--dt-font-line-height-300);
131
133
 
132
- // Icon Slot
133
- &::before {
134
+ // Raw-HTML icon fallback — suppressed when a real .d-icon child is present
135
+ &:not(:has(.d-icon))::before {
134
136
  display: block;
135
137
  margin-block-start: var(--dt-spacing-25);
136
- inline-size: var(--dt-layout-25); // 16
137
- min-inline-size: var(--dt-layout-25); // 16
138
- block-size: var(--dt-layout-25); // 16
138
+ inline-size: var(--validation-size-icon);
139
+ min-inline-size: var(--validation-size-icon);
140
+ block-size: var(--validation-size-icon);
139
141
  background-color: var(--validation-color-text);
142
+ mask: var(--validation-icon);
140
143
  content: '';
141
144
  }
142
145
 
@@ -144,6 +147,13 @@ fieldset {
144
147
  display: flex;
145
148
  flex-direction: column;
146
149
  }
150
+
151
+ &__icon {
152
+ margin-block-start: calc(var(--dt-spacing-25) / 2);
153
+ color: var(--validation-color-text);
154
+ inline-size: var(--validation-size-icon);
155
+ block-size: var(--validation-size-icon);
156
+ }
147
157
  }
148
158
 
149
159
  // $$ VALIDATION STATES
@@ -151,27 +161,23 @@ fieldset {
151
161
 
152
162
  .d-validation-message--warning {
153
163
  --validation-color-text: var(--dt-color-foreground-warning);
154
-
155
- &::before {
156
- mask: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDEyIDEyIj4gPHBhdGggZmlsbD0iIzY4M2UwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNS4yNCAxLjE5N2ExLjUgMS41IDAgMCAxIDIuMDYuNTU2bDMuOTk4IDYuOTk3YTEuNTA0IDEuNTA0IDAgMCAxIDAgMS41IDEuNSAxLjUgMCAwIDEtMS4yOTcuNzVIMi4wMDJhMS41IDEuNSAwIDAgMS0xLjMxLTIuMjQ5VjguNzVMNC42OSAxLjc1M2ExLjUgMS41IDAgMCAxIC41NS0uNTU2Wm0uNzU1Ljc5NmEuNS41IDAgMCAwLS40MzUuMjU0di4wMDFMMS41NTcgOS4yNWEuNS41IDAgMCAwIC40MzguNzVIMTBhLjUuNSAwIDAgMCAuNDMyLS43NWwtLjAwMS0uMDAyLTQtNy0uMDAxLS4wMDFhLjUuNSAwIDAgMC0uNDM1LS4yNTRaIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz4gPHBhdGggZmlsbD0iIzY4M2UwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNiA0YS41LjUgMCAwIDEgLjUuNXYyYS41LjUgMCAwIDEtMSAwdi0yQS41LjUgMCAwIDEgNiA0Wm0tLjUgNC41QS41LjUgMCAwIDEgNiA4aC4wMDVhLjUuNSAwIDAgMSAwIDFINmEuNS41IDAgMCAxLS41LS41WiIgY2xpcC1ydWxlPSJldmVub2RkIi8+IDwvc3ZnPg==') repeat;
157
- }
164
+ --validation-icon: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDEyIDEyIj4gPHBhdGggZmlsbD0iIzY4M2UwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNS4yNCAxLjE5N2ExLjUgMS41IDAgMCAxIDIuMDYuNTU2bDMuOTk4IDYuOTk3YTEuNTA0IDEuNTA0IDAgMCAxIDAgMS41IDEuNSAxLjUgMCAwIDEtMS4yOTcuNzVIMi4wMDJhMS41IDEuNSAwIDAgMS0xLjMxLTIuMjQ5VjguNzVMNC42OSAxLjc1M2ExLjUgMS41IDAgMCAxIC41NS0uNTU2Wm0uNzU1Ljc5NmEuNS41IDAgMCAwLS40MzUuMjU0di4wMDFMMS41NTcgOS4yNWEuNS41IDAgMCAwIC40MzguNzVIMTBhLjUuNSAwIDAgMCAuNDMyLS43NWwtLjAwMS0uMDAyLTQtNy0uMDAxLS4wMDFhLjUuNSAwIDAgMC0uNDM1LS4yNTRaIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz4gPHBhdGggZmlsbD0iIzY4M2UwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNiA0YS41LjUgMCAwIDEgLjUuNXYyYS41LjUgMCAwIDEtMSAwdi0yQS41LjUgMCAwIDEgNiA0Wm0tLjUgNC41QS41LjUgMCAwIDEgNiA4aC4wMDVhLjUuNSAwIDAgMSAwIDFINmEuNS41IDAgMCAxLS41LS41WiIgY2xpcC1ydWxlPSJldmVub2RkIi8+IDwvc3ZnPg==') repeat;
158
165
  }
159
166
 
160
167
  .d-validation-message--critical,
161
168
  .d-validation-message--error {
162
169
  --validation-color-text: var(--dt-color-foreground-critical);
163
-
164
- &::before {
165
- mask: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDEyIDEyIj4gPGcgY2xpcC1wYXRoPSJ1cmwoI2EpIj4gPHBhdGggZmlsbD0iI2VjMGUwZSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNiAxLjVhNC41IDQuNSAwIDEgMCAwIDkgNC41IDQuNSAwIDAgMCAwLTlaTS41IDZhNS41IDUuNSAwIDEgMSAxMSAwIDUuNSA1LjUgMCAwIDEtMTEgMFpNNiAzLjVhLjUuNSAwIDAgMSAuNS41djJhLjUuNSAwIDAgMS0xIDBWNGEuNS41IDAgMCAxIC41LS41Wk01LjUgOGEuNS41IDAgMCAxIC41LS41aC4wMDVhLjUuNSAwIDAgMSAwIDFINmEuNS41IDAgMCAxLS41LS41WiIgY2xpcC1ydWxlPSJldmVub2RkIi8+IDwvZz4gPGRlZnM+IDxjbGlwUGF0aCBpZD0iYSI+IDxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0wIDBoMTJ2MTJIMHoiLz4gPC9jbGlwUGF0aD4gPC9kZWZzPiA8L3N2Zz4=') no-repeat;
166
- }
170
+ --validation-icon: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDEyIDEyIj4gPGcgY2xpcC1wYXRoPSJ1cmwoI2EpIj4gPHBhdGggZmlsbD0iI2VjMGUwZSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNiAxLjVhNC41IDQuNSAwIDEgMCAwIDkgNC41IDQuNSAwIDAgMCAwLTlaTS41IDZhNS41IDUuNSAwIDEgMSAxMSAwIDUuNSA1LjUgMCAwIDEtMTEgMFpNNiAzLjVhLjUuNSAwIDAgMSAuNS41djJhLjUuNSAwIDAgMS0xIDBWNGEuNS41IDAgMCAxIC41LS41Wk01LjUgOGEuNS41IDAgMCAxIC41LS41aC4wMDVhLjUuNSAwIDAgMSAwIDFINmEuNS41IDAgMCAxLS41LS41WiIgY2xpcC1ydWxlPSJldmVub2RkIi8+IDwvZz4gPGRlZnM+IDxjbGlwUGF0aCBpZD0iYSI+IDxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0wIDBoMTJ2MTJIMHoiLz4gPC9jbGlwUGF0aD4gPC9kZWZzPiA8L3N2Zz4=') no-repeat;
167
171
  }
168
172
 
169
173
  .d-validation-message--positive,
170
174
  .d-validation-message--success {
171
175
  --validation-color-text: var(--dt-color-foreground-positive);
176
+ --validation-icon: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDEyIDEyIj4gPGcgY2xpcC1wYXRoPSJ1cmwoI2EpIj4gPHBhdGggZmlsbD0iIzAwNjcxZCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNLjUgNmE1LjUgNS41IDAgMSAxIDExIDAgNS41IDUuNSAwIDAgMS0xMSAwWk02IDEuNWE0LjUgNC41IDAgMSAwIDAgOSA0LjUgNC41IDAgMCAwIDAtOVptMS44NTQgMy4xNDZhLjUuNSAwIDAgMSAwIC43MDhsLTIgMmEuNS41IDAgMCAxLS43MDggMGwtMS0xYS41LjUgMCAxIDEgLjcwOC0uNzA4bC42NDYuNjQ3IDEuNjQ2LTEuNjQ3YS41LjUgMCAwIDEgLjcwOCAwWiIgY2xpcC1ydWxlPSJldmVub2RkIi8+IDwvZz4gPGRlZnM+IDxjbGlwUGF0aCBpZD0iYSI+IDxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0wIDBoMTJ2MTJIMHoiLz4gPC9jbGlwUGF0aD4gPC9kZWZzPiA8L3N2Zz4=') no-repeat;
177
+ }
172
178
 
173
- &::before {
174
- mask: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDEyIDEyIj4gPGcgY2xpcC1wYXRoPSJ1cmwoI2EpIj4gPHBhdGggZmlsbD0iIzAwNjcxZCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNLjUgNmE1LjUgNS41IDAgMSAxIDExIDAgNS41IDUuNSAwIDAgMS0xMSAwWk02IDEuNWE0LjUgNC41IDAgMSAwIDAgOSA0LjUgNC41IDAgMCAwIDAtOVptMS44NTQgMy4xNDZhLjUuNSAwIDAgMSAwIC43MDhsLTIgMmEuNS41IDAgMCAxLS43MDggMGwtMS0xYS41LjUgMCAxIDEgLjcwOC0uNzA4bC42NDYuNjQ3IDEuNjQ2LTEuNjQ3YS41LjUgMCAwIDEgLjcwOCAwWiIgY2xpcC1ydWxlPSJldmVub2RkIi8+IDwvZz4gPGRlZnM+IDxjbGlwUGF0aCBpZD0iYSI+IDxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0wIDBoMTJ2MTJIMHoiLz4gPC9jbGlwUGF0aD4gPC9kZWZzPiA8L3N2Zz4=') no-repeat;
175
- }
179
+ .d-validation-message--info {
180
+ --validation-color-text: var(--dt-color-foreground-info);
181
+ --validation-icon: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDEyIDEyIj4gPGcgY2xpcC1wYXRoPSJ1cmwoI2EpIj4gPHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNiAxLjVhNC41IDQuNSAwIDEgMCAwIDkgNC41IDQuNSAwIDAgMCAwLTlaTS41IDZhNS41IDUuNSAwIDEgMSAxMSAwIDUuNSA1LjUgMCAwIDEtMTEgMFptNS0yYS41LjUgMCAwIDEgLjUtLjVoLjAwNWEuNS41IDAgMCAxIDAgMUg2YS41LjUgMCAwIDEtLjUtLjVaTTYgNS41YS41LjUgMCAwIDEgLjUuNXYyYS41LjUgMCAwIDEtMSAwVjZhLjUuNSAwIDAgMSAuNS0uNVoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPiA8L2c+IDxkZWZzPiA8Y2xpcFBhdGggaWQ9ImEiPiA8cGF0aCBmaWxsPSIjZmZmIiBkPSJNMCAwaDEydjEySDB6Ii8+IDwvY2xpcFBhdGg+IDwvZGVmcz4gPC9zdmc+') no-repeat;
176
182
  }
177
183
  }
@@ -22,6 +22,7 @@
22
22
  max-block-size: 80%;
23
23
  padding: var(--dt-spacing-0);
24
24
  border-radius: var(--dt-size-radius-0);
25
+ box-shadow: var(--dt-shadow-modal);
25
26
 
26
27
  &__image {
27
28
  max-inline-size: 100%;