konpeki 0.1.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.
Files changed (121) hide show
  1. package/.agents/skills/authoring-visuals/SKILL.md +82 -0
  2. package/AGENTS.md +33 -0
  3. package/AUTHORING.md +233 -0
  4. package/LICENSE +201 -0
  5. package/README.md +70 -0
  6. package/SETUP.md +86 -0
  7. package/composition/README.md +166 -0
  8. package/composition/compile.ts +227 -0
  9. package/composition/document.ts +709 -0
  10. package/composition/schema.json +2992 -0
  11. package/composition/schema.ts +435 -0
  12. package/composition/theme-tokens.ts +16 -0
  13. package/composition/types.ts +286 -0
  14. package/composition/validate.ts +684 -0
  15. package/composition/vector.ts +143 -0
  16. package/composition/visualizations.ts +335 -0
  17. package/design/README.md +17 -0
  18. package/design/palettes/README.md +14 -0
  19. package/design/palettes/base.ts +14 -0
  20. package/design/palettes/candidates.ts +19 -0
  21. package/design/palettes/index.ts +78 -0
  22. package/design/review/color-theme.md +44 -0
  23. package/design/review/layout.md +16 -0
  24. package/design/review/text.md +18 -0
  25. package/design/review/typography.md +15 -0
  26. package/design/review/visuals.md +31 -0
  27. package/design/semantic-patterns.md +43 -0
  28. package/design/themes/README.md +22 -0
  29. package/design/themes/index.ts +13 -0
  30. package/design/visual-languages/technical-product.md +17 -0
  31. package/design/visual-review.md +88 -0
  32. package/docs/development.md +140 -0
  33. package/docs/workflow.md +61 -0
  34. package/index.html +17 -0
  35. package/lib/assets.d.ts +8 -0
  36. package/lib/charts.ts +18 -0
  37. package/lib/contrast.ts +16 -0
  38. package/lib/layouts.ts +50 -0
  39. package/lib/slide.tsx +42 -0
  40. package/lib/taste.ts +17 -0
  41. package/lib/text.tsx +89 -0
  42. package/lib/typeface.ts +44 -0
  43. package/package.json +85 -0
  44. package/runtime/konpeki.mjs +1685 -0
  45. package/scripts/migrate-react-page.ts +120 -0
  46. package/slides/README.md +153 -0
  47. package/slides/architecture/PROMPT.md +31 -0
  48. package/slides/architecture/index.tsx +102 -0
  49. package/slides/article-brief/PROMPT.md +35 -0
  50. package/slides/article-brief/index.tsx +71 -0
  51. package/slides/bar-chart/PROMPT.md +39 -0
  52. package/slides/bar-chart/index.tsx +97 -0
  53. package/slides/comparison/PROMPT.md +29 -0
  54. package/slides/comparison/index.tsx +95 -0
  55. package/slides/decision-memo/PROMPT.md +34 -0
  56. package/slides/decision-memo/index.tsx +85 -0
  57. package/slides/delivery-plan/PROMPT.md +45 -0
  58. package/slides/delivery-plan/index.tsx +105 -0
  59. package/slides/experiment/PROMPT.md +44 -0
  60. package/slides/experiment/index.tsx +127 -0
  61. package/slides/incident-workflow/PROMPT.md +57 -0
  62. package/slides/incident-workflow/index.tsx +78 -0
  63. package/slides/introducing-konpeki/PROMPT.md +19 -0
  64. package/slides/introducing-konpeki/README.md +54 -0
  65. package/slides/introducing-konpeki/SOURCE.md +20 -0
  66. package/slides/introducing-konpeki/author.ts +163 -0
  67. package/slides/introducing-konpeki/composition.json +3265 -0
  68. package/slides/line-chart/PROMPT.md +40 -0
  69. package/slides/line-chart/index.tsx +72 -0
  70. package/slides/migration/PROMPT.md +38 -0
  71. package/slides/migration/index.tsx +89 -0
  72. package/slides/og-images/PROMPT.md +21 -0
  73. package/slides/og-images/index.tsx +76 -0
  74. package/slides/product-introduction/PROMPT.md +24 -0
  75. package/slides/product-introduction/index.tsx +105 -0
  76. package/slides/research-brief/PROMPT.md +40 -0
  77. package/slides/research-brief/index.tsx +104 -0
  78. package/slides/results-explanation/PROMPT.md +32 -0
  79. package/slides/results-explanation/index.tsx +96 -0
  80. package/slides/retrospective/PROMPT.md +43 -0
  81. package/slides/retrospective/index.tsx +105 -0
  82. package/slides/sankey/PROMPT.md +11 -0
  83. package/slides/sankey/index.tsx +93 -0
  84. package/slides/teaching/PROMPT.md +45 -0
  85. package/slides/teaching/index.tsx +124 -0
  86. package/slides/vertical-bar-charts/PROMPT.md +13 -0
  87. package/slides/vertical-bar-charts/index.tsx +97 -0
  88. package/src/app/App.tsx +694 -0
  89. package/src/assets/konpeki-mark.png +0 -0
  90. package/src/components/Canvas.tsx +1168 -0
  91. package/src/components/DiagramTypeIcon.tsx +78 -0
  92. package/src/components/InspectorPanel.tsx +687 -0
  93. package/src/components/LeftPanel.tsx +107 -0
  94. package/src/components/PageSizePicker.tsx +30 -0
  95. package/src/components/Presentation.tsx +105 -0
  96. package/src/components/RightPanel.tsx +201 -0
  97. package/src/components/VectorOverflowWarning.tsx +46 -0
  98. package/src/components/WorkspaceChrome.tsx +199 -0
  99. package/src/components/ui.tsx +53 -0
  100. package/src/lib/examples/react-page-migration.json +1295 -0
  101. package/src/lib/examples.ts +42 -0
  102. package/src/lib/export-png.ts +101 -0
  103. package/src/lib/file-session.ts +74 -0
  104. package/src/lib/history.ts +53 -0
  105. package/src/lib/model.ts +188 -0
  106. package/src/lib/page-size.ts +24 -0
  107. package/src/lib/presentation.ts +17 -0
  108. package/src/lib/storage.ts +43 -0
  109. package/src/lib/theme.ts +25 -0
  110. package/src/lib/use-file-session.ts +162 -0
  111. package/src/main.tsx +26 -0
  112. package/src/styles/base.css +105 -0
  113. package/src/styles/canvas.css +268 -0
  114. package/src/styles/chrome.css +214 -0
  115. package/src/styles/component-previews.css +386 -0
  116. package/src/styles/feedback.css +71 -0
  117. package/src/styles/left-panel.css +125 -0
  118. package/src/styles/presentation.css +72 -0
  119. package/src/styles/right-panel.css +1172 -0
  120. package/src/styles/shell.css +247 -0
  121. package/vite.config.ts +6 -0
@@ -0,0 +1,214 @@
1
+ .document-island,
2
+ .action-island,
3
+ .component-dock {
4
+ position: fixed;
5
+ z-index: 40;
6
+ display: flex;
7
+ align-items: center;
8
+ background: var(--ui-surface);
9
+ border: 1px solid var(--ui-border);
10
+ box-shadow: var(--ui-shadow);
11
+ }
12
+
13
+ .document-island {
14
+ top: 20px;
15
+ left: 20px;
16
+ width: 252px;
17
+ height: 56px;
18
+ gap: 10px;
19
+ padding: 8px 10px;
20
+ border-radius: 14px;
21
+ }
22
+
23
+ .workspace:has(.left-panel:not(.collapsed)) .document-island {
24
+ border-radius: 12px 12px 0 0;
25
+ box-shadow: none;
26
+ }
27
+
28
+ .document-island img {
29
+ flex: none;
30
+ width: 25px;
31
+ height: 27px;
32
+ object-fit: contain;
33
+ }
34
+
35
+ .document-island .panel-collapse-icon {
36
+ transform: rotate(-90deg);
37
+ }
38
+
39
+ .document-title {
40
+ min-width: 0;
41
+ flex: 1;
42
+ }
43
+
44
+ .document-title input {
45
+ height: 36px;
46
+ border-color: transparent;
47
+ background: transparent;
48
+ font-size: 13px;
49
+ font-weight: 500;
50
+ text-overflow: ellipsis;
51
+ }
52
+
53
+ .document-title input:hover {
54
+ border-color: transparent;
55
+ background: var(--ui-hover);
56
+ }
57
+
58
+ .document-title input:focus {
59
+ border-color: var(--ui-control);
60
+ background: var(--ui-surface);
61
+ }
62
+
63
+ .document-title-error {
64
+ position: absolute;
65
+ top: calc(100% + 6px);
66
+ right: 12px;
67
+ padding: 5px 8px;
68
+ border-radius: 4px;
69
+ background: #fff1f1;
70
+ color: #8d1717;
71
+ font-size: 11px;
72
+ box-shadow: 0 2px 8px #00000012;
73
+ }
74
+
75
+ .file-status {
76
+ flex: none;
77
+ display: inline-flex;
78
+ align-items: center;
79
+ gap: 5px;
80
+ color: var(--ui-muted);
81
+ font-size: 10px;
82
+ }
83
+
84
+ .file-status::before {
85
+ width: 6px;
86
+ height: 6px;
87
+ border-radius: 50%;
88
+ background: #3f875b;
89
+ content: "";
90
+ }
91
+
92
+ .file-status.loading::before,
93
+ .file-status.saving::before {
94
+ background: #a27616;
95
+ }
96
+
97
+ .file-status.conflict,
98
+ .file-status.error {
99
+ color: #8d1717;
100
+ }
101
+
102
+ .file-status.conflict::before,
103
+ .file-status.error::before {
104
+ background: #b13d3d;
105
+ }
106
+
107
+ .action-island {
108
+ bottom: 92px;
109
+ left: 20px;
110
+ width: 252px;
111
+ min-width: 252px;
112
+ height: 56px;
113
+ gap: 4px;
114
+ padding: 7px;
115
+ border-top: 1px solid var(--ui-border);
116
+ border-radius: 0 0 12px 12px;
117
+ box-shadow: none;
118
+ }
119
+
120
+ .left-collapsed .action-island {
121
+ visibility: hidden;
122
+ }
123
+
124
+ .action-island button {
125
+ display: inline-flex;
126
+ align-items: center;
127
+ gap: 6px;
128
+ height: 34px;
129
+ padding: 0 12px;
130
+ border-radius: 7px;
131
+ border-color: transparent;
132
+ background: transparent;
133
+ font-size: 13px;
134
+ font-weight: 500;
135
+ }
136
+
137
+ .action-island button:hover:not(:disabled) {
138
+ border-color: transparent;
139
+ background: var(--ui-hover);
140
+ }
141
+
142
+ .action-island button.icon-only {
143
+ flex: none;
144
+ width: 34px;
145
+ padding: 0 8px;
146
+ }
147
+
148
+ .action-island button.primary {
149
+ background: #202020;
150
+ color: white;
151
+ }
152
+
153
+ .action-island button.primary:hover:not(:disabled) {
154
+ background: #383838;
155
+ }
156
+
157
+ .action-island button.primary:disabled {
158
+ background: var(--ui-hover);
159
+ color: var(--ui-muted);
160
+ }
161
+
162
+ .action-island button svg {
163
+ flex: none;
164
+ width: 18px;
165
+ height: 18px;
166
+ fill: none;
167
+ stroke: currentColor;
168
+ stroke-linecap: round;
169
+ stroke-linejoin: round;
170
+ stroke-width: 1.7;
171
+ }
172
+
173
+ .component-dock {
174
+ bottom: 20px;
175
+ left: 50%;
176
+ min-height: 68px;
177
+ gap: 2px;
178
+ padding: 6px;
179
+ border-radius: 16px;
180
+ transform: translateX(-50%);
181
+ }
182
+
183
+ .component-dock button {
184
+ display: grid;
185
+ place-items: center;
186
+ min-width: 62px;
187
+ height: 54px;
188
+ gap: 1px;
189
+ padding: 4px 7px;
190
+ border-color: transparent;
191
+ color: var(--ui-text);
192
+ font-size: 11px;
193
+ }
194
+
195
+ .component-dock button.active {
196
+ background: var(--ui-selected);
197
+ color: #006aa1;
198
+ }
199
+
200
+ .dock-glyph {
201
+ width: 22px;
202
+ height: 22px;
203
+ fill: none;
204
+ stroke: currentColor;
205
+ stroke-linecap: round;
206
+ stroke-linejoin: round;
207
+ stroke-width: 1.6;
208
+ }
209
+
210
+ @media (max-width: 1120px) {
211
+ .component-dock button {
212
+ min-width: 55px;
213
+ }
214
+ }
@@ -0,0 +1,386 @@
1
+ .illustration {
2
+ width: 100%;
3
+ flex: 1;
4
+ min-height: 0;
5
+ }
6
+
7
+ .chart-preview {
8
+ display: flex;
9
+ flex: 1;
10
+ min-height: 0;
11
+ gap: 1cqw;
12
+ margin-top: 1cqw;
13
+ }
14
+
15
+ .chart-preview.legend-top,
16
+ .chart-preview.legend-bottom {
17
+ flex-direction: column;
18
+ }
19
+
20
+ .chart-preview.legend-top .chart-legend {
21
+ order: -1;
22
+ }
23
+
24
+ .chart-preview.legend-right {
25
+ flex-direction: row;
26
+ }
27
+
28
+ .chart-preview.legend-right .chart-legend {
29
+ flex-direction: column;
30
+ justify-content: center;
31
+ }
32
+
33
+ .chart-legend {
34
+ display: flex;
35
+ flex: none;
36
+ gap: 0.7cqw;
37
+ min-height: 0.7cqw;
38
+ color: var(--slide-muted);
39
+ font-size: 0.9cqw;
40
+ }
41
+
42
+ .chart-legend span {
43
+ display: flex;
44
+ align-items: center;
45
+ gap: 0.35cqw;
46
+ }
47
+
48
+ .chart-legend i {
49
+ display: block;
50
+ width: 1.8cqw;
51
+ height: 0.45cqw;
52
+ }
53
+
54
+ .legend-accent {
55
+ background: var(--component-accent);
56
+ }
57
+
58
+ .legend-context {
59
+ background: var(--component-context);
60
+ }
61
+
62
+ .chart-axis {
63
+ stroke: var(--slide-muted);
64
+ fill: none;
65
+ stroke-width: 2;
66
+ }
67
+
68
+ .chart-accent {
69
+ fill: var(--component-accent);
70
+ }
71
+
72
+ .chart-context {
73
+ fill: var(--component-context);
74
+ }
75
+
76
+ .chart-tertiary {
77
+ fill: color-mix(in srgb, var(--component-accent) 45%, var(--component-context));
78
+ }
79
+
80
+ .chart-line {
81
+ stroke: var(--component-accent);
82
+ fill: none;
83
+ stroke-width: 5;
84
+ }
85
+
86
+ .node-primary {
87
+ fill: var(--slide-bg);
88
+ font-size: 20px;
89
+ }
90
+
91
+ .diagram-canvas-icon {
92
+ width: 100%;
93
+ height: 100%;
94
+ flex: 1;
95
+ min-height: 0;
96
+ margin-top: 1cqw;
97
+ color: var(--component-context);
98
+ stroke-width: 0.7;
99
+ }
100
+
101
+ .diagram-canvas-icon .filled {
102
+ fill: var(--component-context);
103
+ }
104
+
105
+ .topology-preview .chart-axis {
106
+ stroke: var(--component-accent);
107
+ stroke-width: 0.8%;
108
+ }
109
+
110
+ .topology-arrowhead {
111
+ fill: var(--component-accent);
112
+ }
113
+
114
+ .topology-node {
115
+ fill: var(--slide-bg);
116
+ stroke: var(--component-accent);
117
+ stroke-width: 0.55%;
118
+ }
119
+
120
+ .topology-line {
121
+ fill: none;
122
+ }
123
+
124
+ .topology-icon {
125
+ fill: none;
126
+ stroke: var(--component-accent);
127
+ stroke-linejoin: round;
128
+ stroke-width: 0.8%;
129
+ }
130
+
131
+ .topology-node-label {
132
+ fill: var(--slide-ink);
133
+ font-size: 28px;
134
+ font-weight: 600;
135
+ }
136
+
137
+ .topology-edge-label {
138
+ fill: var(--slide-muted);
139
+ font-size: 22px;
140
+ paint-order: stroke;
141
+ stroke: var(--slide-bg);
142
+ stroke-width: 3px;
143
+ stroke-linejoin: round;
144
+ }
145
+
146
+ .topology-preview .color-ink {
147
+ stroke: var(--slide-ink);
148
+ }
149
+
150
+ .topology-preview .color-muted {
151
+ stroke: var(--slide-muted);
152
+ }
153
+
154
+ .topology-preview .fill-solid.color-accent,
155
+ .topology-preview .style-filled.color-accent {
156
+ fill: var(--component-accent);
157
+ }
158
+
159
+ .topology-preview .fill-solid.color-ink,
160
+ .topology-preview .style-filled.color-ink {
161
+ fill: var(--slide-ink);
162
+ }
163
+
164
+ .topology-preview .fill-solid.color-muted,
165
+ .topology-preview .style-filled.color-muted {
166
+ fill: var(--slide-muted);
167
+ }
168
+
169
+ .topology-preview .fill-wash {
170
+ fill: color-mix(in srgb, var(--component-accent) 14%, var(--slide-bg));
171
+ }
172
+
173
+ .node-text {
174
+ fill: var(--slide-ink);
175
+ font-size: 20px;
176
+ }
177
+
178
+ .text-layout-preview {
179
+ display: grid;
180
+ flex: 1;
181
+ min-height: 0;
182
+ gap: 1.1cqw;
183
+ margin-top: 1.4cqw;
184
+ }
185
+
186
+ .text-layout-preview i {
187
+ display: grid;
188
+ align-content: start;
189
+ gap: 0.7cqw;
190
+ min-width: 0;
191
+ min-height: 0;
192
+ padding: 1cqw;
193
+ border: 0;
194
+ background: transparent;
195
+ }
196
+
197
+ .text-layout-preview b {
198
+ display: block;
199
+ width: 88%;
200
+ height: 0.5cqw;
201
+ background: var(--component-context);
202
+ }
203
+
204
+ .text-layout-preview b:nth-child(2) {
205
+ width: 72%;
206
+ }
207
+
208
+ .text-layout-preview b:nth-child(3) {
209
+ width: 54%;
210
+ }
211
+
212
+ .text-layout-preview:not(.logic-none) i {
213
+ border: 1px solid var(--component-context);
214
+ }
215
+
216
+ .text-layout-preview.logic-parallel {
217
+ grid-template-columns: repeat(3, 1fr);
218
+ }
219
+
220
+ .text-layout-preview.logic-progressive {
221
+ grid-template-columns: repeat(4, 1fr);
222
+ align-items: end;
223
+ }
224
+
225
+ .text-layout-preview.logic-progressive i:nth-child(1) { height: 38%; }
226
+ .text-layout-preview.logic-progressive i:nth-child(2) { height: 58%; }
227
+ .text-layout-preview.logic-progressive i:nth-child(3) { height: 78%; }
228
+ .text-layout-preview.logic-progressive i:nth-child(4) { height: 100%; }
229
+
230
+ .text-layout-preview.logic-cyclical {
231
+ position: relative;
232
+ display: block;
233
+ }
234
+
235
+ .text-layout-preview.logic-cyclical::after {
236
+ position: absolute;
237
+ inset: 27% 34%;
238
+ border: 0.45cqw solid var(--component-accent);
239
+ border-radius: 50%;
240
+ content: "";
241
+ }
242
+
243
+ .text-layout-preview.logic-cyclical i {
244
+ position: absolute;
245
+ width: 34%;
246
+ height: 38%;
247
+ }
248
+
249
+ .text-layout-preview.logic-cyclical i:nth-child(1) { top: 0; left: 0; }
250
+ .text-layout-preview.logic-cyclical i:nth-child(2) { top: 0; right: 0; }
251
+ .text-layout-preview.logic-cyclical i:nth-child(3) { right: 0; bottom: 0; }
252
+ .text-layout-preview.logic-cyclical i:nth-child(4) { bottom: 0; left: 0; }
253
+
254
+ .text-layout-preview.logic-general-to-specific,
255
+ .text-layout-preview.logic-hierarchical {
256
+ grid-template: repeat(2, 1fr) / repeat(3, 1fr);
257
+ }
258
+
259
+ .text-layout-preview.logic-general-to-specific i:first-child {
260
+ grid-column: 1 / -1;
261
+ }
262
+
263
+ .text-layout-preview.logic-hierarchical i:first-child {
264
+ grid-column: 2;
265
+ }
266
+
267
+ .text-layout-preview.logic-hierarchical i:nth-child(n + 2) {
268
+ grid-row: 2;
269
+ }
270
+
271
+ .image-preview {
272
+ margin-top: 1cqw;
273
+ }
274
+
275
+ .image-mountain {
276
+ fill: var(--slide-bg);
277
+ opacity: 0.72;
278
+ }
279
+
280
+ .fit-contain .image-preview {
281
+ padding: 1.4cqw;
282
+ }
283
+
284
+ .table-preview {
285
+ display: grid;
286
+ grid-template-columns: repeat(3, minmax(0, 1fr));
287
+ flex: 1;
288
+ min-height: 0;
289
+ margin-top: 1.2cqw;
290
+ }
291
+
292
+ .table-preview i {
293
+ min-width: 0;
294
+ min-height: 0;
295
+ }
296
+
297
+ .table-preview i::after {
298
+ display: block;
299
+ width: 62%;
300
+ height: 0.45cqw;
301
+ margin: 1.1cqw;
302
+ background: var(--component-context);
303
+ content: "";
304
+ }
305
+
306
+ .table-preview .table-header {
307
+ border-bottom: 2px solid var(--component-context);
308
+ }
309
+
310
+ .table-preview .table-header::after {
311
+ width: 72%;
312
+ background: var(--component-context);
313
+ }
314
+
315
+ .table-style-top-header-bottom {
316
+ border-block: 1px solid var(--component-context);
317
+ }
318
+
319
+ .table-style-row-rules i {
320
+ border-bottom: 1px solid var(--component-context);
321
+ }
322
+
323
+ .table-style-full-grid {
324
+ border-top: 1px solid var(--component-context);
325
+ border-left: 1px solid var(--component-context);
326
+ }
327
+
328
+ .table-style-full-grid i {
329
+ border-right: 1px solid var(--component-context);
330
+ border-bottom: 1px solid var(--component-context);
331
+ }
332
+
333
+ .table-density-standard i::after {
334
+ height: 0.65cqw;
335
+ margin-block: 0.7cqw;
336
+ }
337
+
338
+ .topology-indicator {
339
+ align-self: flex-start;
340
+ margin-top: 0.65cqw;
341
+ padding: 0.3cqw 0.55cqw;
342
+ background: var(--slide-wash);
343
+ color: var(--slide-muted);
344
+ font-size: 1.15cqw;
345
+ line-height: 1.2;
346
+ }
347
+
348
+ .layout-two-column,
349
+ .layout-three-column,
350
+ .layout-four-column {
351
+ grid-auto-flow: column;
352
+ grid-auto-columns: 1fr;
353
+ }
354
+
355
+ .layout-two-plus-two {
356
+ grid-template-columns: repeat(2, 1fr);
357
+ grid-template-rows: repeat(2, 1fr);
358
+ }
359
+
360
+ .layout-one-plus-three.orientation-horizontal,
361
+ .layout-three-plus-one.orientation-horizontal {
362
+ grid-template: repeat(3, 1fr) / repeat(2, 1fr);
363
+ }
364
+
365
+ .layout-one-plus-three.orientation-horizontal i:first-child,
366
+ .layout-three-plus-one.orientation-horizontal i:last-child {
367
+ grid-row: 1 / -1;
368
+ }
369
+
370
+ .layout-three-plus-one.orientation-horizontal i:last-child {
371
+ grid-column: 2;
372
+ }
373
+
374
+ .layout-one-plus-three.orientation-vertical,
375
+ .layout-three-plus-one.orientation-vertical {
376
+ grid-template: repeat(2, 1fr) / repeat(3, 1fr);
377
+ }
378
+
379
+ .layout-one-plus-three.orientation-vertical i:first-child,
380
+ .layout-three-plus-one.orientation-vertical i:last-child {
381
+ grid-column: 1 / -1;
382
+ }
383
+
384
+ .layout-three-plus-one.orientation-vertical i:last-child {
385
+ grid-row: 2;
386
+ }
@@ -0,0 +1,71 @@
1
+ .toast {
2
+ position: fixed;
3
+ top: 20px;
4
+ bottom: auto;
5
+ left: 50%;
6
+ transform: translateX(-50%);
7
+ transform-origin: center top;
8
+ display: none;
9
+ align-items: center;
10
+ gap: 14px;
11
+ background: #252525;
12
+ color: white;
13
+ padding: 10px 12px 10px 18px;
14
+ border-radius: 6px;
15
+ font-size: 13px;
16
+ max-width: 80vw;
17
+ z-index: 50;
18
+ }
19
+ .toast.visible {
20
+ display: flex;
21
+ animation: toast-expand 360ms cubic-bezier(0.16, 1, 0.3, 1) both;
22
+ }
23
+ .toast.visible.closing {
24
+ pointer-events: none;
25
+ animation: toast-expand 280ms cubic-bezier(0.4, 0, 0.8, 0.2) reverse both;
26
+ }
27
+ .toast button {
28
+ background: transparent;
29
+ border-color: #707070;
30
+ color: white;
31
+ padding: 5px 10px;
32
+ }
33
+ .toast button:hover:not(:disabled) {
34
+ background: #444;
35
+ }
36
+ @keyframes toast-expand {
37
+ 0% {
38
+ opacity: 0;
39
+ transform: translate(-50%, -22px) scale(0.72, 0.4);
40
+ }
41
+ 62% {
42
+ opacity: 1;
43
+ transform: translate(-50%, 5px) scale(1.04, 1.08);
44
+ }
45
+ 80% {
46
+ transform: translate(-50%, -1px) scale(0.99, 0.97);
47
+ }
48
+ 100% {
49
+ opacity: 1;
50
+ transform: translate(-50%, 0) scale(1);
51
+ }
52
+ }
53
+ .recovery {
54
+ display: flex;
55
+ justify-content: center;
56
+ align-items: center;
57
+ gap: 20px;
58
+ background: #fff;
59
+ border-bottom: 1px solid #ccc;
60
+ padding: 12px;
61
+ font-size: 13px;
62
+ }
63
+ @media (prefers-reduced-motion: reduce) {
64
+ *,
65
+ *::before,
66
+ *::after {
67
+ scroll-behavior: auto !important;
68
+ animation: none !important;
69
+ transition: none !important;
70
+ }
71
+ }