Runs / kyc-form Batch Runs from different design-system versions should not be compared.
The page A screenshot in each theme, as the benchmark took it.
page.tsx As the agent left it; marked lines broke a rule.
Violations 121 counted, under 7 rules. “Not counted” marks a compiler error that restates a design-system violation, “Ignored” one the agent silenced with a comment. The first 200 are listed.
Steps One row per model call, with the tools it asked for. An agent that reads the guidelines before writing shows it here; what a checker or submit_view answered is under its call.
Step Tools Tokens in Tokens out Cost 0 docs-list 3 50 $0.0004 1 get-storybook-story-instructions 3 35 $0.0001 2 docs-show, docs-show, docs-show, docs-show, docs-show 3 122 $0.0003
Output cap The provider's default 3 import { useState, type FormEvent } from "react";
4 import {
5 Button,
6 Card,
7 CardBody,
8 CardDescription,
9 CardHeader,
10 CardTitle,
11 FormField,
12 Input,
13 Select,
14 } from "@vektos/ds";
15 import { css } from "styled-system/css";
16 import data from "./fixture.json";
17
18 type IdentityDetails = {
19 dateOfBirth: string;
20 nationality: string;
21 residence: string;
22 taxId: string;
23 documentType: string;
24 documentNumber: string;
25 politicallyExposed: string;
26 };
27
28 const emptyDetails: IdentityDetails = {
29 dateOfBirth: "",
30 nationality: "",
31 residence: "",
32 taxId: "",
33 documentType: "",
34 documentNumber: "",
35 politicallyExposed: "",
36 };
37
38 const countryOptions = data.countries.map((country) => ({
39 label: country.name,
40 value: country.code,
41 }));
42
43 const pageStyle = css({
44 minHeight: "100vh",
45 background: "#f5f7fa",
46 color: "#182230",
47 fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif",
48 });
49
50 const topbarStyle = css({
51 height: "72px",
52 background: "white",
53 borderBottom: "1px solid #e7ebf0",
54 display: "flex",
55 alignItems: "center",
56 justifyContent: "space-between",
57 paddingInline: "clamp(20px, 5vw, 72px)",
58 });
59
60 const brandStyle = css({ display: "flex", alignItems: "center", gap: "10px" });
61 const brandMarkStyle = css({
62 width: "32px",
63 height: "32px",
64 borderRadius: "10px",
65 background: "#1849a9",
66 display: "grid",
67 placeItems: "center",
68 color: "white",
69 fontSize: "16px",
70 fontWeight: "700",
71 });
72 const brandNameStyle = css({ fontSize: "16px", fontWeight: "700", letterSpacing: "-0.02em" });
73 const secureStyle = css({ display: "flex", gap: "8px", alignItems: "center", color: "#667085", fontSize: "13px" });
74 const mainStyle = css({
75 width: "min(100% - 40px, 760px)",
76 marginInline: "auto",
77 paddingBlock: "42px 72px",
78 });
79 const stepperStyle = css({ display: "flex", alignItems: "center", gap: "12px", marginBottom: "30px" });
80 const stepCircleStyle = css({
81 width: "32px",
82 height: "32px",
83 borderRadius: "50%",
84 background: "#1849a9",
85 color: "white",
86 display: "grid",
87 placeItems: "center",
88 fontSize: "13px",
89 fontWeight: "700",
90 flexShrink: "0",
91 });
92 const stepLabelStyle = css({ fontSize: "13px", fontWeight: "600", color: "#344054" });
93 const stepLineStyle = css({ height: "1px", flex: "1", background: "#d0d5dd", maxWidth: "72px" });
94 const eyebrowStyle = css({
95 textTransform: "uppercase",
96 color: "#475467",
97 fontSize: "11px",
98 fontWeight: "700",
99 letterSpacing: "0.1em",
100 marginBottom: "8px",
101 });
102 const titleStyle = css({ fontSize: "30px", lineHeight: "1.2", fontWeight: "700", letterSpacing: "-0.04em", margin: "0" });
103 const introStyle = css({ color: "#667085", fontSize: "15px", lineHeight: "1.6", marginTop: "10px", marginBottom: "24px" });
104 const customerStyle = css({
105 display: "grid",
106 gridTemplateColumns: "1fr 1fr",
107 gap: "12px",
108 border: "1px solid #e4e7ec",
109 borderRadius: "10px",
110 padding: "16px 18px",
111 background: "#fbfcfe",
112 marginBottom: "22px",
113 });
114 const detailLabelStyle = css({ display: "block", color: "#667085", fontSize: "12px", marginBottom: "4px" });
115 const detailValueStyle = css({ color: "#1d2939", fontSize: "14px", fontWeight: "600", overflowWrap: "anywhere" });
116 const formGridStyle = css({ display: "grid", gridTemplateColumns: "repeat(2, minmax(0, 1fr))", columnGap: "20px", rowGap: "18px" });
117 const spanStyle = css({ gridColumn: "1 / -1" });
118 const noticeStyle = css({
119 display: "flex",
120 alignItems: "flex-start",
121 gap: "10px",
122 color: "#475467",
123 background: "#f8fafc",
124 border: "1px solid #eaecf0",
125 borderRadius: "8px",
126 padding: "12px 14px",
127 fontSize: "13px",
128 lineHeight: "1.5",
129 marginTop: "22px",
130 });
131 const footerStyle = css({
132 display: "flex",
133 justifyContent: "space-between",
134 alignItems: "center",
135 gap: "16px",
136 borderTop: "1px solid #eaecf0",
137 marginTop: "24px",
138 paddingTop: "20px",
139 });
140 const requiredStyle = css({ color: "#667085", fontSize: "12px" });
141 const radioGroupStyle = css({ display: "flex", gap: "10px", marginTop: "8px" });
142 const radioOptionStyle = css({
143 display: "flex",
144 alignItems: "center",
145 gap: "8px",
146 border: "1px solid #d0d5dd",
147 borderRadius: "8px",
148 padding: "10px 14px",
149 minWidth: "92px",
150 color: "#344054",
151 fontSize: "14px",
152 cursor: "pointer",
153 background: "white",
154 _has: { "input:checked": { accentColor: "#1849a9" } },
155 });
156 const radioErrorStyle = css({ color: "#b42318", fontSize: "12px", marginTop: "7px" });
157 const successStyle = css({ textAlign: "center", padding: "50px 28px 56px" });
158 const successIconStyle = css({
159 display: "grid",
160 placeItems: "center",
161 width: "56px",
162 height: "56px",
163 borderRadius: "50%",
164 color: "#067647",
165 background: "#ecfdf3",
166 fontSize: "26px",
167 marginInline: "auto",
168 marginBottom: "18px",
169 });
170
171 export default function IdentityVerificationPage() {
172 const [details, setDetails] = useState<IdentityDetails>(emptyDetails);
173 const [hasSubmitted, setHasSubmitted] = useState(false);
174 const [isReviewing, setIsReviewing] = useState(false);
175
176 const update = (field: keyof IdentityDetails, value: string) => {
177 setDetails((current) => ({ ...current, [field]: value }));
178 };
179
180 const onSubmit = (event: FormEvent<HTMLFormElement>) => {
181 event.preventDefault();
182 setHasSubmitted(true);
183 const allComplete = Object.values(details).every((value) => value.trim() !== "");
184 if (allComplete) setIsReviewing(true);
185 };
186
187 const errorFor = (field: keyof IdentityDetails) =>
188 hasSubmitted && !details[field].trim() ? "This field is required." : undefined;
189
190 return (
191 <div className={pageStyle}>
192 <header className={topbarStyle}>
193 <div className={brandStyle}>
194 <div className={brandMarkStyle} aria-hidden="true">V</div>
195 <span className={brandNameStyle}>Vektos</span>
196 </div>
197 <div className={secureStyle}>
198 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" aria-hidden="true">
199 <path d="M6 10V7a6 6 0 0 1 12 0v3m-13 0h14v11H5V10Z" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" />
200 <circle cx="12" cy="15" r="1" fill="currentColor" />
201 </svg>
202 Secure account opening
203 </div>
204 </header>
205
206 <main className={mainStyle}>
207 <div className={stepperStyle} aria-label="Account opening progress">
208 <span className={stepCircleStyle}>1</span><span className={stepLabelStyle}>Your details</span>
209 <span className={stepLineStyle} />
210 <span className={stepCircleStyle}>2</span><span className={stepLabelStyle}>Identity check</span>
211 <span className={stepLineStyle} />
212 <span className={css({ ...stepCircleStyle.split ? {} : {}, background: "#e4e7ec", color: "#667085" })}>3</span>
213 <span className={css({ ...stepLabelStyle.split ? {} : {}, color: "#98a2b3" })}>Review</span>
214 </div>
215
216 {isReviewing ? (
217 <Card>
218 <CardBody>
219 <div className={successStyle}>
220 <div className={successIconStyle} aria-hidden="true">✓</div>
221 <p className={eyebrowStyle}>Identity verification</p>
222 <h1 className={titleStyle}>Your details are being reviewed</h1>
223 <p className={introStyle}>
224 Thanks, {data.customer.firstName}. We’ve received your information and will let you know when the review is complete.
225 </p>
226 </div>
227 </CardBody>
228 </Card>
229 ) : (
230 <>
231 <p className={eyebrowStyle}>Step 2 of 3 · Identity check</p>
232 <h1 className={titleStyle}>Verify your identity</h1>
233 <p className={introStyle}>We need a few details to meet our regulatory requirements. Your information is encrypted and kept secure.</p>
234
235 <Card>
236 <CardHeader>
237 <CardTitle>Personal information</CardTitle>
238 <CardDescription>Confirm who’s opening this account.</CardDescription>
239 </CardHeader>
240 <CardBody>
241 <div className={customerStyle}>
242 <div>
243 <span className={detailLabelStyle}>Full name</span>
244 <span className={detailValueStyle}>{data.customer.firstName} {data.customer.lastName}</span>
245 </div>
246 <div>
247 <span className={detailLabelStyle}>Email address</span>
248 <span className={detailValueStyle}>{data.customer.email}</span>
249 </div>
250 </div>
251
252 <form onSubmit={onSubmit} noValidate>
253 <div className={formGridStyle}>
254 <FormField label="Date of birth" required error={errorFor("dateOfBirth")}>
255 <Input type="date" value={details.dateOfBirth} onChange={(event) => update("dateOfBirth", event.target.value)} />
256 </FormField>
257
258 <FormField label="Nationality" required error={errorFor("nationality")}>
259 <Select
260 value={details.nationality}
261 onValueChange={(value) => update("nationality", value)}
262 placeholder="Select nationality"
263 options={countryOptions}
264 />
265 </FormField>
266
267 <FormField label="Country of residence" required error={errorFor("residence")}>
268 <Select
269 value={details.residence}
270 onValueChange={(value) => update("residence", value)}
271 placeholder="Select country"
272 options={countryOptions}
273 />
274 </FormField>
275
276 <FormField label="Tax identification number" required error={errorFor("taxId")}>
277 <Input value={details.taxId} onChange={(event) => update("taxId", event.target.value)} placeholder="Enter your tax ID" autoComplete="off" />
278 </FormField>
279
280 <FormField label="Type of identity document" required error={errorFor("documentType")}>
281 <Select
282 value={details.documentType}
283 onValueChange={(value) => update("documentType", value)}
284 placeholder="Select document type"
285 options={data.documentTypes}
286 />
287 </FormField>
288
289 <FormField label="Document number" required error={errorFor("documentNumber")}>
290 <Input value={details.documentNumber} onChange={(event) => update("documentNumber", event.target.value)} placeholder="Enter document number" autoComplete="off" />
291 </FormField>
292
293 <fieldset className={css({ border: "0", padding: "0", margin: "0", gridColumn: "1 / -1" })}>
294 <legend className={css({ color: "#344054", fontSize: "14px", fontWeight: "500" })}>Are you a politically exposed person (PEP)? <span aria-hidden="true" className={css({ color: "#b42318" })}>*</span></legend>
295 <div className={radioGroupStyle}>
296 {[{ value: "yes", label: "Yes" }, { value: "no", label: "No" }].map((option) => (
297 <label key={option.value} className={radioOptionStyle}>
298 <input
299 type="radio"
300 name="politicallyExposed"
301 value={option.value}
302 checked={details.politicallyExposed === option.value}
303 onChange={(event) => update("politicallyExposed", event.target.value)}
304 aria-invalid={Boolean(errorFor("politicallyExposed"))}
305 />
306 {option.label}
307 </label>
308 ))}
309 </div>
310 {errorFor("politicallyExposed") && <p className={radioErrorStyle} role="alert">{errorFor("politicallyExposed")}</p>}
311 </fieldset>
312 </div>
313
314 <div className={noticeStyle}>
315 <svg width="17" height="17" viewBox="0 0 24 24" fill="none" aria-hidden="true" className={css({ flexShrink: "0", marginTop: "1px" })}>
316 <circle cx="12" cy="12" r="9" stroke="currentColor" strokeWidth="1.7" />
317 <path d="M12 11v5m0-8h.01" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" />
318 </svg>
319 We use this information only to verify your identity and help protect your account.
320 </div>
321 <div className={footerStyle}>
322 <span className={requiredStyle}>* Required fields</span>
323 <Button type="submit" variant="solid" size="md">Submit details <span aria-hidden="true">→</span></Button>
324 </div>
325 </form>
326 </CardBody>
327 </Card>
328 </>
329 )}
330 </main>
331 </div>
332 );
333 }
334
page.tsx:75:10 · min(100% - 40px, 760px) `min(100% - 40px, 760px)` is a raw length. Use a token. page.tsx:157:58 · 50px 28px 56px `50px 28px 56px` is a raw length. Use a token. raw-values/raw-color 29 design-system page.tsx:45:15 · #f5f7fa `#f5f7fa` is a raw color. Use a semantic color token. page.tsx:46:10 · #182230 `#182230` is a raw color. Use a semantic color token. page.tsx:52:15 · white `white` is a raw color. Use a semantic color token. page.tsx:53:17 · 1px solid #e7ebf0 `1px solid #e7ebf0` is a raw color. Use a semantic color token. page.tsx:65:15 · #1849a9 `#1849a9` is a raw color. Use a semantic color token. page.tsx:68:10 · white `white` is a raw color. Use a semantic color token. page.tsx:73:85 · #667085 `#667085` is a raw color. Use a semantic color token. page.tsx:84:15 · #1849a9 `#1849a9` is a raw color. Use a semantic color token. page.tsx:85:10 · white `white` is a raw color. Use a semantic color token. page.tsx:92:74 · #344054 `#344054` is a raw color. Use a semantic color token. page.tsx:93:67 · #d0d5dd `#d0d5dd` is a raw color. Use a semantic color token. page.tsx:96:10 · #475467 `#475467` is a raw color. Use a semantic color token. page.tsx:103:33 · #667085 `#667085` is a raw color. Use a semantic color token. page.tsx:108:11 · 1px solid #e4e7ec `1px solid #e4e7ec` is a raw color. Use a semantic color token. page.tsx:111:15 · #fbfcfe `#fbfcfe` is a raw color. Use a semantic color token. page.tsx:114:57 · #667085 `#667085` is a raw color. Use a semantic color token. page.tsx:115:39 · #1d2939 `#1d2939` is a raw color. Use a semantic color token. page.tsx:122:10 · #475467 `#475467` is a raw color. Use a semantic color token. page.tsx:123:15 · #f8fafc `#f8fafc` is a raw color. Use a semantic color token. page.tsx:124:11 · 1px solid #eaecf0 `1px solid #eaecf0` is a raw color. Use a semantic color token. page.tsx:136:14 · 1px solid #eaecf0 `1px solid #eaecf0` is a raw color. Use a semantic color token. page.tsx:140:36 · #667085 `#667085` is a raw color. Use a semantic color token. page.tsx:146:11 · 1px solid #d0d5dd `1px solid #d0d5dd` is a raw color. Use a semantic color token. page.tsx:150:10 · #344054 `#344054` is a raw color. Use a semantic color token. page.tsx:153:15 · white `white` is a raw color. Use a semantic color token. page.tsx:154:43 · #1849a9 `#1849a9` is a raw color. Use a semantic color token. page.tsx:156:38 · #b42318 `#b42318` is a raw color. Use a semantic color token. page.tsx:164:10 · #067647 `#067647` is a raw color. Use a semantic color token. page.tsx:165:15 · #ecfdf3 `#ecfdf3` is a raw color. Use a semantic color token. Every run that broke raw-values/raw-color lint/@pandacss(no-physical-properties) 13 quality page.tsx:53:3 Use the logical property "borderBlockEnd" instead of the physical "borderBottom". page.tsx:79:80 Use the logical property "marginBlockEnd" instead of the physical "marginBottom". page.tsx:100:3 Use the logical property "marginBlockEnd" instead of the physical "marginBottom". page.tsx:103:81 Use the logical property "marginBlockStart" instead of the physical "marginTop". page.tsx:103:100 Use the logical property "marginBlockEnd" instead of the physical "marginBottom". page.tsx:112:3 Use the logical property "marginBlockEnd" instead of the physical "marginBottom". page.tsx:114:86 Use the logical property "marginBlockEnd" instead of the physical "marginBottom". page.tsx:129:3 Use the logical property "marginBlockStart" instead of the physical "marginTop". page.tsx:136:3 Use the logical property "borderBlockStart" instead of the physical "borderTop". page.tsx:137:3 Use the logical property "marginBlockStart" instead of the physical "marginTop". page.tsx:138:3 Use the logical property "paddingBlockStart" instead of the physical "paddingTop". page.tsx:141:61 Use the logical property "marginBlockStart" instead of the physical "marginTop". page.tsx:156:67 Use the logical property "marginBlockStart" instead of the physical "marginTop". Every run that broke lint/@pandacss(no-physical-properties) a11y/color-contrast 2 quality page.tsx:1:1 · <span class="c_#98a2b3">Review</span> Elements must meet minimum color contrast ratio thresholds (3 elements, dark theme) page.tsx:1:1 · <span class="c_#98a2b3">Review</span> Elements must meet minimum color contrast ratio thresholds (1 element, light theme) Every run that broke a11y/color-contrast lint/@pandacss(extraction-diagnostics) 1 quality typecheck/TS2769 0 quality 5 stories-changed 3 242 $0.0007
6 stories-find-by-component 3 55 $0.0002
7 stories-find-by-component 3 76 $0.0002