@ucptools/validator 1.0.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/CLAUDE.md +109 -0
  2. package/CONTRIBUTING.md +113 -0
  3. package/LICENSE +21 -0
  4. package/README.md +203 -0
  5. package/api/analyze-feed.js +140 -0
  6. package/api/badge.js +185 -0
  7. package/api/benchmark.js +177 -0
  8. package/api/directory-stats.ts +29 -0
  9. package/api/directory.ts +73 -0
  10. package/api/generate-compliance.js +143 -0
  11. package/api/generate-schema.js +457 -0
  12. package/api/generate.js +132 -0
  13. package/api/security-scan.js +133 -0
  14. package/api/simulate.js +187 -0
  15. package/api/tsconfig.json +10 -0
  16. package/api/validate.js +1351 -0
  17. package/apify-actor/.actor/actor.json +68 -0
  18. package/apify-actor/.actor/input_schema.json +32 -0
  19. package/apify-actor/APIFY-STORE-LISTING.md +412 -0
  20. package/apify-actor/Dockerfile +8 -0
  21. package/apify-actor/README.md +166 -0
  22. package/apify-actor/main.ts +111 -0
  23. package/apify-actor/package.json +17 -0
  24. package/apify-actor/src/main.js +199 -0
  25. package/docs/BRAND-IDENTITY.md +238 -0
  26. package/docs/BRAND-STYLE-GUIDE.md +356 -0
  27. package/drizzle/0000_black_king_cobra.sql +39 -0
  28. package/drizzle/meta/0000_snapshot.json +309 -0
  29. package/drizzle/meta/_journal.json +13 -0
  30. package/drizzle.config.ts +10 -0
  31. package/examples/full-profile.json +70 -0
  32. package/examples/minimal-profile.json +23 -0
  33. package/package.json +69 -0
  34. package/public/.well-known/ucp +25 -0
  35. package/public/android-chrome-192x192.png +0 -0
  36. package/public/android-chrome-512x512.png +0 -0
  37. package/public/apple-touch-icon.png +0 -0
  38. package/public/brand.css +321 -0
  39. package/public/directory.html +701 -0
  40. package/public/favicon-16x16.png +0 -0
  41. package/public/favicon-32x32.png +0 -0
  42. package/public/favicon.ico +0 -0
  43. package/public/guides/bigcommerce.html +743 -0
  44. package/public/guides/fastucp.html +838 -0
  45. package/public/guides/magento.html +779 -0
  46. package/public/guides/shopify.html +726 -0
  47. package/public/guides/squarespace.html +749 -0
  48. package/public/guides/wix.html +747 -0
  49. package/public/guides/woocommerce.html +733 -0
  50. package/public/index.html +3835 -0
  51. package/public/learn.html +396 -0
  52. package/public/logo.jpeg +0 -0
  53. package/public/og-image-icon.png +0 -0
  54. package/public/og-image.png +0 -0
  55. package/public/robots.txt +6 -0
  56. package/public/site.webmanifest +31 -0
  57. package/public/sitemap.xml +69 -0
  58. package/public/social/linkedin-banner-1128x191.png +0 -0
  59. package/public/social/temp.PNG +0 -0
  60. package/public/social/x-header-1500x500.png +0 -0
  61. package/public/verify.html +410 -0
  62. package/scripts/generate-favicons.js +44 -0
  63. package/scripts/generate-ico.js +23 -0
  64. package/scripts/generate-og-image.js +45 -0
  65. package/scripts/reset-db.ts +77 -0
  66. package/scripts/seed-db.ts +71 -0
  67. package/scripts/setup-benchmark-db.js +70 -0
  68. package/src/api/server.ts +266 -0
  69. package/src/cli/index.ts +302 -0
  70. package/src/compliance/compliance-generator.ts +452 -0
  71. package/src/compliance/index.ts +28 -0
  72. package/src/compliance/templates.ts +338 -0
  73. package/src/compliance/types.ts +170 -0
  74. package/src/db/index.ts +28 -0
  75. package/src/db/schema.ts +84 -0
  76. package/src/feed-analyzer/feed-analyzer.ts +726 -0
  77. package/src/feed-analyzer/index.ts +34 -0
  78. package/src/feed-analyzer/types.ts +354 -0
  79. package/src/generator/index.ts +7 -0
  80. package/src/generator/key-generator.ts +124 -0
  81. package/src/generator/profile-builder.ts +402 -0
  82. package/src/hosting/artifacts-generator.ts +679 -0
  83. package/src/hosting/index.ts +6 -0
  84. package/src/index.ts +105 -0
  85. package/src/security/index.ts +15 -0
  86. package/src/security/security-scanner.ts +604 -0
  87. package/src/security/types.ts +55 -0
  88. package/src/services/directory.ts +434 -0
  89. package/src/simulator/agent-simulator.ts +941 -0
  90. package/src/simulator/index.ts +7 -0
  91. package/src/simulator/types.ts +170 -0
  92. package/src/types/generator.ts +140 -0
  93. package/src/types/index.ts +7 -0
  94. package/src/types/ucp-profile.ts +140 -0
  95. package/src/types/validation.ts +89 -0
  96. package/src/validator/index.ts +194 -0
  97. package/src/validator/network-validator.ts +417 -0
  98. package/src/validator/rules-validator.ts +297 -0
  99. package/src/validator/sdk-validator.ts +330 -0
  100. package/src/validator/structural-validator.ts +476 -0
  101. package/tests/fixtures/non-compliant-profile.json +25 -0
  102. package/tests/fixtures/official-sample-profile.json +75 -0
  103. package/tests/integration/benchmark.test.ts +207 -0
  104. package/tests/integration/database.test.ts +163 -0
  105. package/tests/integration/directory-api.test.ts +268 -0
  106. package/tests/integration/simulate-api.test.ts +230 -0
  107. package/tests/integration/validate-api.test.ts +269 -0
  108. package/tests/setup.ts +15 -0
  109. package/tests/unit/agent-simulator.test.ts +575 -0
  110. package/tests/unit/compliance-generator.test.ts +374 -0
  111. package/tests/unit/directory-service.test.ts +272 -0
  112. package/tests/unit/feed-analyzer.test.ts +517 -0
  113. package/tests/unit/lint-suggestions.test.ts +423 -0
  114. package/tests/unit/official-samples.test.ts +211 -0
  115. package/tests/unit/pdf-report.test.ts +390 -0
  116. package/tests/unit/sdk-validator.test.ts +531 -0
  117. package/tests/unit/security-scanner.test.ts +410 -0
  118. package/tests/unit/validation.test.ts +390 -0
  119. package/tsconfig.json +20 -0
  120. package/vercel.json +34 -0
  121. package/vitest.config.ts +22 -0
@@ -0,0 +1,10 @@
1
+ import { defineConfig } from 'drizzle-kit';
2
+
3
+ export default defineConfig({
4
+ schema: './src/db/schema.ts',
5
+ out: './drizzle',
6
+ dialect: 'postgresql',
7
+ dbCredentials: {
8
+ url: process.env.DATABASE_URL!,
9
+ },
10
+ });
@@ -0,0 +1,70 @@
1
+ {
2
+ "ucp": {
3
+ "version": "2026-01-11",
4
+ "services": {
5
+ "dev.ucp.shopping": {
6
+ "version": "2026-01-11",
7
+ "spec": "https://ucp.dev/specification/overview/",
8
+ "rest": {
9
+ "schema": "https://ucp.dev/services/shopping/rest.openapi.json",
10
+ "endpoint": "https://api.merchant.example.com/ucp/v1"
11
+ },
12
+ "mcp": {
13
+ "schema": "https://ucp.dev/services/shopping/mcp.openrpc.json",
14
+ "endpoint": "https://mcp.merchant.example.com/ucp"
15
+ }
16
+ }
17
+ },
18
+ "capabilities": [
19
+ {
20
+ "name": "dev.ucp.shopping.checkout",
21
+ "version": "2026-01-11",
22
+ "spec": "https://ucp.dev/specification/checkout/",
23
+ "schema": "https://ucp.dev/schemas/shopping/checkout.json"
24
+ },
25
+ {
26
+ "name": "dev.ucp.shopping.order",
27
+ "version": "2026-01-11",
28
+ "spec": "https://ucp.dev/specification/order/",
29
+ "schema": "https://ucp.dev/schemas/shopping/order.json"
30
+ },
31
+ {
32
+ "name": "dev.ucp.shopping.fulfillment",
33
+ "version": "2026-01-11",
34
+ "spec": "https://ucp.dev/specification/fulfillment/",
35
+ "schema": "https://ucp.dev/schemas/shopping/fulfillment.json",
36
+ "extends": "dev.ucp.shopping.order"
37
+ },
38
+ {
39
+ "name": "dev.ucp.shopping.discount",
40
+ "version": "2026-01-11",
41
+ "spec": "https://ucp.dev/specification/discount/",
42
+ "schema": "https://ucp.dev/schemas/shopping/discount.json"
43
+ }
44
+ ]
45
+ },
46
+ "payment": {
47
+ "handlers": [
48
+ {
49
+ "id": "stripe",
50
+ "name": "Stripe",
51
+ "version": "2026-01-11",
52
+ "spec": "https://ucp.dev/handlers/tokenization/stripe/",
53
+ "config": {
54
+ "publishable_key": "pk_live_..."
55
+ }
56
+ }
57
+ ]
58
+ },
59
+ "signing_keys": [
60
+ {
61
+ "kty": "EC",
62
+ "kid": "ucp-webhook-key-1",
63
+ "use": "sig",
64
+ "alg": "ES256",
65
+ "crv": "P-256",
66
+ "x": "example_x_coordinate_base64url",
67
+ "y": "example_y_coordinate_base64url"
68
+ }
69
+ ]
70
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "ucp": {
3
+ "version": "2026-01-11",
4
+ "services": {
5
+ "dev.ucp.shopping": {
6
+ "version": "2026-01-11",
7
+ "spec": "https://ucp.dev/specification/overview/",
8
+ "rest": {
9
+ "schema": "https://ucp.dev/services/shopping/rest.openapi.json",
10
+ "endpoint": "https://merchant.example.com/ucp/v1"
11
+ }
12
+ }
13
+ },
14
+ "capabilities": [
15
+ {
16
+ "name": "dev.ucp.shopping.checkout",
17
+ "version": "2026-01-11",
18
+ "spec": "https://ucp.dev/specification/checkout/",
19
+ "schema": "https://ucp.dev/schemas/shopping/checkout.json"
20
+ }
21
+ ]
22
+ }
23
+ }
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "@ucptools/validator",
3
+ "version": "1.0.0",
4
+ "description": "Validate and generate UCP (Universal Commerce Protocol) Business Profiles",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "ucp-validate": "./dist/cli/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "dev": "tsx watch src/api/server.ts",
13
+ "start": "node dist/api/server.js",
14
+ "test": "vitest",
15
+ "lint": "eslint src --ext .ts",
16
+ "validate": "tsx src/cli/index.ts",
17
+ "generate": "tsx src/cli/generate.ts",
18
+ "db:generate": "drizzle-kit generate",
19
+ "db:migrate": "drizzle-kit migrate",
20
+ "db:push": "drizzle-kit push",
21
+ "db:studio": "drizzle-kit studio"
22
+ },
23
+ "keywords": [
24
+ "ucp",
25
+ "universal-commerce-protocol",
26
+ "profile-generator",
27
+ "validator"
28
+ ],
29
+ "author": "UCP.tools",
30
+ "license": "MIT",
31
+ "dependencies": {
32
+ "@neondatabase/serverless": "^1.0.2",
33
+ "@ucp-js/sdk": "^0.1.0",
34
+ "ajv": "^8.17.1",
35
+ "ajv-formats": "^3.0.1",
36
+ "chalk": "^5.3.0",
37
+ "commander": "^12.1.0",
38
+ "drizzle-orm": "^0.45.1",
39
+ "express": "^4.21.0",
40
+ "jose": "^5.9.6",
41
+ "nanoid": "^5.0.7",
42
+ "pg": "^8.13.0",
43
+ "pino": "^9.5.0",
44
+ "pino-pretty": "^11.3.0",
45
+ "zod": "^3.23.8"
46
+ },
47
+ "devDependencies": {
48
+ "@types/express": "^5.0.0",
49
+ "@types/node": "^22.9.0",
50
+ "@types/pg": "^8.11.10",
51
+ "@vercel/node": "^5.5.20",
52
+ "dotenv": "^17.2.3",
53
+ "drizzle-kit": "^0.31.8",
54
+ "png-to-ico": "^3.0.1",
55
+ "sharp": "^0.34.5",
56
+ "tsx": "^4.19.2",
57
+ "typescript": "^5.6.3",
58
+ "vitest": "^4.0.17"
59
+ },
60
+ "overrides": {
61
+ "diff": "^8.0.3",
62
+ "undici": "^7.0.0",
63
+ "esbuild": "^0.25.0",
64
+ "path-to-regexp": "^8.0.0"
65
+ },
66
+ "engines": {
67
+ "node": ">=20.0.0"
68
+ }
69
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "ucp": {
3
+ "version": "2026-01-14",
4
+ "services": {
5
+ "shopping": {
6
+ "version": "1.0",
7
+ "spec": "https://ucp.dev/specs/shopping/1.0",
8
+ "rest": {
9
+ "endpoint": "https://ucptools.dev/api",
10
+ "auth": {
11
+ "type": "none"
12
+ }
13
+ }
14
+ }
15
+ },
16
+ "capabilities": [
17
+ {
18
+ "name": "dev.ucp.shopping.checkout",
19
+ "version": "1.0",
20
+ "spec": "https://ucp.dev/specs/shopping/checkout/1.0",
21
+ "schema": "https://ucp.dev/schemas/shopping/checkout/1.0.json"
22
+ }
23
+ ]
24
+ }
25
+ }
Binary file
@@ -0,0 +1,321 @@
1
+ /**
2
+ * UCP.tools Brand Design System
3
+ * CSS Design Tokens extracted from brand logo
4
+ *
5
+ * Usage: @import './brand.css' or <link rel="stylesheet" href="/brand.css">
6
+ */
7
+
8
+ :root {
9
+ /* ========================================
10
+ PRIMARY COLORS (from logo gradient)
11
+ ======================================== */
12
+ --brand-blue: #2E86AB;
13
+ --brand-teal: #36B5A2;
14
+ --brand-green: #47C97A;
15
+
16
+ /* Brand gradient - primary brand expression */
17
+ --brand-gradient: linear-gradient(135deg, #2E86AB 0%, #36B5A2 50%, #47C97A 100%);
18
+ --brand-gradient-hover: linear-gradient(135deg, #267593 0%, #2EA18F 50%, #3BB86B 100%);
19
+
20
+ /* ========================================
21
+ SECONDARY COLORS
22
+ ======================================== */
23
+ --color-dark: #1A2B3C;
24
+ --color-medium: #5A6978;
25
+ --color-light: #94A3B8;
26
+ --color-border: #E2E8F0;
27
+ --color-background: #F8FAFC;
28
+ --color-card: #FFFFFF;
29
+
30
+ /* ========================================
31
+ SEMANTIC COLORS
32
+ ======================================== */
33
+ --color-success: #47C97A;
34
+ --color-warning: #F59E0B;
35
+ --color-error: #EF4444;
36
+ --color-info: #2E86AB;
37
+
38
+ /* ========================================
39
+ GRADE COLORS
40
+ ======================================== */
41
+ --grade-a-bg: #DCFCE7;
42
+ --grade-a-text: #16A34A;
43
+ --grade-b-bg: #DBEAFE;
44
+ --grade-b-text: #2563EB;
45
+ --grade-c-bg: #FEF9C3;
46
+ --grade-c-text: #CA8A04;
47
+ --grade-d-bg: #FED7AA;
48
+ --grade-d-text: #EA580C;
49
+ --grade-f-bg: #FEE2E2;
50
+ --grade-f-text: #DC2626;
51
+
52
+ /* ========================================
53
+ TYPOGRAPHY
54
+ ======================================== */
55
+ --font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
56
+
57
+ /* Font Sizes */
58
+ --text-xs: 0.75rem; /* 12px */
59
+ --text-sm: 0.875rem; /* 14px */
60
+ --text-base: 1rem; /* 16px */
61
+ --text-lg: 1.25rem; /* 20px */
62
+ --text-xl: 1.5rem; /* 24px */
63
+ --text-2xl: 2.25rem; /* 36px */
64
+ --text-3xl: 3rem; /* 48px */
65
+
66
+ /* Font Weights */
67
+ --font-normal: 400;
68
+ --font-medium: 500;
69
+ --font-semibold: 600;
70
+ --font-bold: 700;
71
+
72
+ /* Line Heights */
73
+ --leading-tight: 1.2;
74
+ --leading-snug: 1.3;
75
+ --leading-normal: 1.5;
76
+ --leading-relaxed: 1.6;
77
+
78
+ /* ========================================
79
+ SPACING (8px grid)
80
+ ======================================== */
81
+ --space-1: 4px;
82
+ --space-2: 8px;
83
+ --space-3: 12px;
84
+ --space-4: 16px;
85
+ --space-5: 20px;
86
+ --space-6: 24px;
87
+ --space-8: 32px;
88
+ --space-10: 40px;
89
+ --space-12: 48px;
90
+ --space-16: 64px;
91
+
92
+ /* ========================================
93
+ BORDER RADIUS
94
+ ======================================== */
95
+ --radius-sm: 4px;
96
+ --radius-md: 8px;
97
+ --radius-lg: 12px;
98
+ --radius-xl: 16px;
99
+ --radius-full: 9999px;
100
+
101
+ /* ========================================
102
+ SHADOWS
103
+ ======================================== */
104
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
105
+ --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1);
106
+ --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
107
+ --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
108
+ --shadow-brand: 0 4px 12px rgba(46, 134, 171, 0.4);
109
+
110
+ /* ========================================
111
+ TRANSITIONS
112
+ ======================================== */
113
+ --transition-fast: 150ms ease;
114
+ --transition-base: 200ms ease;
115
+ --transition-slow: 300ms ease;
116
+ }
117
+
118
+ /* ========================================
119
+ UTILITY CLASSES
120
+ ======================================== */
121
+
122
+ /* Gradient Text */
123
+ .gradient-text {
124
+ background: var(--brand-gradient);
125
+ -webkit-background-clip: text;
126
+ -webkit-text-fill-color: transparent;
127
+ background-clip: text;
128
+ }
129
+
130
+ /* Logo */
131
+ .logo {
132
+ font-size: var(--text-xl);
133
+ font-weight: var(--font-bold);
134
+ background: var(--brand-gradient);
135
+ -webkit-background-clip: text;
136
+ -webkit-text-fill-color: transparent;
137
+ background-clip: text;
138
+ text-decoration: none;
139
+ }
140
+
141
+ .logo .suffix {
142
+ font-weight: var(--font-normal);
143
+ -webkit-text-fill-color: var(--color-medium);
144
+ }
145
+
146
+ /* Primary Button */
147
+ .btn-brand {
148
+ display: inline-block;
149
+ background: var(--brand-gradient);
150
+ color: white;
151
+ padding: var(--space-3) var(--space-6);
152
+ border-radius: var(--radius-md);
153
+ font-weight: var(--font-semibold);
154
+ font-size: var(--text-base);
155
+ border: none;
156
+ cursor: pointer;
157
+ transition: transform var(--transition-base), box-shadow var(--transition-base);
158
+ text-decoration: none;
159
+ }
160
+
161
+ .btn-brand:hover {
162
+ transform: translateY(-1px);
163
+ box-shadow: var(--shadow-brand);
164
+ }
165
+
166
+ .btn-brand:active {
167
+ transform: translateY(0);
168
+ }
169
+
170
+ .btn-brand:disabled {
171
+ opacity: 0.6;
172
+ cursor: not-allowed;
173
+ transform: none;
174
+ }
175
+
176
+ /* Secondary Button */
177
+ .btn-secondary {
178
+ display: inline-block;
179
+ background: var(--color-card);
180
+ color: var(--color-dark);
181
+ padding: var(--space-3) var(--space-6);
182
+ border-radius: var(--radius-md);
183
+ font-weight: var(--font-semibold);
184
+ font-size: var(--text-base);
185
+ border: 2px solid var(--color-border);
186
+ cursor: pointer;
187
+ transition: border-color var(--transition-base), color var(--transition-base);
188
+ text-decoration: none;
189
+ }
190
+
191
+ .btn-secondary:hover {
192
+ border-color: var(--brand-blue);
193
+ color: var(--brand-blue);
194
+ }
195
+
196
+ /* Card */
197
+ .card-brand {
198
+ background: var(--color-card);
199
+ border-radius: var(--radius-lg);
200
+ padding: var(--space-8);
201
+ box-shadow: var(--shadow-sm);
202
+ border: 1px solid var(--color-border);
203
+ }
204
+
205
+ .card-brand:hover {
206
+ transform: translateY(-2px);
207
+ box-shadow: var(--shadow-md);
208
+ transition: transform var(--transition-base), box-shadow var(--transition-base);
209
+ }
210
+
211
+ /* Input Fields */
212
+ .input-brand {
213
+ width: 100%;
214
+ padding: var(--space-3) var(--space-4);
215
+ border: 2px solid var(--color-border);
216
+ border-radius: var(--radius-md);
217
+ font-size: var(--text-base);
218
+ font-family: var(--font-family);
219
+ transition: border-color var(--transition-base), box-shadow var(--transition-base);
220
+ }
221
+
222
+ .input-brand:focus {
223
+ outline: none;
224
+ border-color: var(--brand-blue);
225
+ box-shadow: 0 0 0 3px rgba(46, 134, 171, 0.1);
226
+ }
227
+
228
+ /* Grade Badges */
229
+ .grade-badge {
230
+ display: inline-flex;
231
+ align-items: center;
232
+ gap: var(--space-2);
233
+ padding: var(--space-2) var(--space-4);
234
+ border-radius: var(--radius-full);
235
+ font-weight: var(--font-bold);
236
+ font-size: var(--text-lg);
237
+ }
238
+
239
+ .grade-badge.grade-a {
240
+ background: var(--grade-a-bg);
241
+ color: var(--grade-a-text);
242
+ }
243
+
244
+ .grade-badge.grade-b {
245
+ background: var(--grade-b-bg);
246
+ color: var(--grade-b-text);
247
+ }
248
+
249
+ .grade-badge.grade-c {
250
+ background: var(--grade-c-bg);
251
+ color: var(--grade-c-text);
252
+ }
253
+
254
+ .grade-badge.grade-d {
255
+ background: var(--grade-d-bg);
256
+ color: var(--grade-d-text);
257
+ }
258
+
259
+ .grade-badge.grade-f {
260
+ background: var(--grade-f-bg);
261
+ color: var(--grade-f-text);
262
+ }
263
+
264
+ /* Hero Section Background */
265
+ .hero-gradient {
266
+ background: linear-gradient(135deg, rgba(46, 134, 171, 0.1) 0%, rgba(54, 181, 162, 0.05) 50%, rgba(71, 201, 122, 0.1) 100%);
267
+ }
268
+
269
+ /* Focus Ring */
270
+ .focus-ring:focus {
271
+ outline: none;
272
+ box-shadow: 0 0 0 3px rgba(46, 134, 171, 0.3);
273
+ }
274
+
275
+ /* Link Styles */
276
+ .link-brand {
277
+ color: var(--brand-blue);
278
+ text-decoration: none;
279
+ transition: color var(--transition-fast);
280
+ }
281
+
282
+ .link-brand:hover {
283
+ color: var(--brand-teal);
284
+ }
285
+
286
+ /* Issue Styles */
287
+ .issue-error {
288
+ background: #fef2f2;
289
+ border-left: 3px solid var(--color-error);
290
+ padding: var(--space-3);
291
+ border-radius: var(--radius-sm);
292
+ }
293
+
294
+ .issue-warning {
295
+ background: #fefce8;
296
+ border-left: 3px solid var(--color-warning);
297
+ padding: var(--space-3);
298
+ border-radius: var(--radius-sm);
299
+ }
300
+
301
+ .issue-info {
302
+ background: rgba(46, 134, 171, 0.1);
303
+ border-left: 3px solid var(--color-info);
304
+ padding: var(--space-3);
305
+ border-radius: var(--radius-sm);
306
+ }
307
+
308
+ /* Success/Error Result Boxes */
309
+ .result-success {
310
+ background: #dcfce7;
311
+ border: 1px solid #86efac;
312
+ border-radius: var(--radius-md);
313
+ padding: var(--space-5);
314
+ }
315
+
316
+ .result-error {
317
+ background: #fee2e2;
318
+ border: 1px solid #fca5a5;
319
+ border-radius: var(--radius-md);
320
+ padding: var(--space-5);
321
+ }