Runs / transfer-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 4 counted, under 2 rules. “Not counted” marks a compiler error that restates a design-system violation, “Ignored” one the agent silenced with a comment.
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 get_guidelines, read_file, list_components, list_tokens 1,751 162 $0.0003 1 get_component, get_component, get_component, get_component, get_component 6,214 229 $0.0007 2 write_file, check_code 9,605 10,736 $0.0063
Output cap The provider's default 4 import {
5 Button,
6 Card,
7 CardBody,
8 CardDescription,
9 CardFooter,
10 CardHeader,
11 CardTitle,
12 FormField,
13 Input,
14 Select,
15 } from "@vektos/ds";
16 import { css } from "styled-system/css";
17 import data from "./fixture.json";
18
19 const money = new Intl.NumberFormat("en-IE", {
20 style: "currency",
21 currency: data.currency,
22 });
23
24 const IBAN_PATTERN = /^[A-Z]{2}\d{2}[A-Z0-9]{11,30}$/;
25
26 function normalizeIban(raw: string): string {
27 return raw.replace(/\s+/g, "").toUpperCase();
28 }
29
30 /** Accepts plain decimals such as "250", "250.5" or "250,00". Returns null otherwise. */
31 function parseAmount(raw: string): number | null {
32 const trimmed = raw.trim();
33 if (!/^\d+([.,]\d{1,2})?$/.test(trimmed)) {
34 return null;
35 }
36 return Number(trimmed.replace(",", "."));
37 }
38
39 const pageClass = css({
40 bg: "bg.canvas",
41 color: "fg.default",
42 p: "6",
43 });
44
45 const containerClass = css({
46 maxWidth: "lg",
47 mx: "auto",
48 });
49
50 const stackClass = css({
51 display: "flex",
52 flexDirection: "column",
53 gap: "4",
54 });
55
56 const confirmationClass = css({
57 bg: "success.subtle",
58 color: "success.text",
59 p: "4",
60 rounded: "md",
61 fontWeight: "medium",
62 });
63
64 export default function SepaTransferPage() {
65 const [accountId, setAccountId] = useState<string>(data.defaultAccountId);
66 const [beneficiaryName, setBeneficiaryName] = useState("");
67 const [beneficiaryIban, setBeneficiaryIban] = useState("");
68 const [amountText, setAmountText] = useState("");
69 const [reference, setReference] = useState("");
70 const [showErrors, setShowErrors] = useState(false);
71 const [sent, setSent] = useState<{ amount: number; beneficiary: string } | null>(
72 null,
73 );
74
75 const account =
76 data.accounts.find((item) => item.id === accountId) ?? data.accounts[0];
77 const amount = parseAmount(amountText);
78 const overBalance = amount !== null && amount > account.available;
79
80 const nameValid = beneficiaryName.trim() !== "";
81 const ibanValid = IBAN_PATTERN.test(normalizeIban(beneficiaryIban));
82 const amountValid = amount !== null && amount > 0;
83 const canSubmit = nameValid && ibanValid && amountValid && !overBalance;
84
85 const nameError =
86 showErrors && !nameValid ? "Enter the beneficiary name." : undefined;
87 const ibanError =
88 showErrors && !ibanValid
89 ? "Enter a valid IBAN, such as IT60 X054 2811 1010 0000 0123 456."
90 : undefined;
91 let amountError: string | undefined;
92 if (overBalance) {
93 amountError = `The amount is higher than the available balance of ${money.format(account.available)}.`;
94 } else if (showErrors && !amountValid) {
95 amountError = "Enter an amount greater than zero.";
96 }
97
98 function handleSubmit(event: FormEvent<HTMLFormElement>) {
99 event.preventDefault();
100 setShowErrors(true);
101 if (!canSubmit || amount === null) {
102 return;
103 }
104 setSent({ amount, beneficiary: beneficiaryName.trim() });
105 }
106
107 function resetForm() {
108 setSent(null);
109 setBeneficiaryName("");
110 setBeneficiaryIban("");
111 setAmountText("");
112 setReference("");
113 setShowErrors(false);
114 }
115
116 if (sent) {
117 return (
118 <div className={`vektos ${pageClass}`}>
119 <div className={containerClass}>
120 <Card>
121 <CardHeader>
122 <CardTitle>Transfer sent</CardTitle>
123 <CardDescription>Your SEPA transfer has been submitted.</CardDescription>
124 </CardHeader>
125 <CardBody>
126 <p role="status" className={confirmationClass}>
127 You sent {money.format(sent.amount)} to {sent.beneficiary}.
128 </p>
129 </CardBody>
130 <CardFooter>
131 <Button variant="outline" size="sm" onClick={resetForm}>
132 New transfer
133 </Button>
134 </CardFooter>
135 </Card>
136 </div>
137 </div>
138 );
139 }
140
141 return (
142 <div className={`vektos ${pageClass}`}>
143 <div className={containerClass}>
144 <form onSubmit={handleSubmit} noValidate>
145 <Card>
146 <CardHeader>
147 <CardTitle>SEPA transfer</CardTitle>
148 <CardDescription>
149 Send money in euros to a beneficiary in the SEPA area.
150 </CardDescription>
151 </CardHeader>
152 <CardBody>
153 <div className={stackClass}>
154 <FormField
155 label="From account"
156 helperText={`Available balance: ${money.format(account.available)}`}
157 >
158 <Select
159 options={data.accounts.map((item) => ({
160 label: `${item.name} (${item.iban})`,
161 value: item.id,
162 }))}
163 value={accountId}
164 onValueChange={setAccountId}
165 />
166 </FormField>
167
168 <FormField label="Beneficiary name" error={nameError}>
169 <Input
170 required
171 autoComplete="off"
172 value={beneficiaryName}
173 onChange={(event) => setBeneficiaryName(event.target.value)}
174 />
175 </FormField>
176
177 <FormField
178 label="Beneficiary IBAN"
179 error={ibanError}
180 helperText="Letters and digits, spaces are ignored."
181 >
182 <Input
183 required
184 autoComplete="off"
185 spellCheck={false}
186 value={beneficiaryIban}
187 onChange={(event) => setBeneficiaryIban(event.target.value)}
188 />
189 </FormField>
190
191 <FormField label={`Amount (${data.currency})`} error={amountError}>
192 <Input
193 required
194 inputMode="decimal"
195 placeholder="0.00"
196 value={amountText}
197 onChange={(event) => setAmountText(event.target.value)}
198 />
199 </FormField>
200
201 <FormField label="Reference (optional)">
202 <Input
203 autoComplete="off"
204 value={reference}
205 onChange={(event) => setReference(event.target.value)}
206 />
207 </FormField>
208 </div>
209 </CardBody>
210 <CardFooter>
211 <Button type="submit" disabled={overBalance}>
212 Send transfer
213 </Button>
214 </CardFooter>
215 </Card>
216 </form>
217 </div>
218 </div>
219 );
220 }
221