Harden UX & accessibility (ui-ux-pro-max pass)
deploy / deploy (push) Successful in 24s

Audited the site with the ui-ux-pro-max skill. It validated the brand blue
(#2563EB == its SaaS primary) but flagged real high-severity gaps:

- Contrast: muted grays were zinc-400 (~2.8:1, fails WCAG AA). Bumped the
  muted token + all text-zinc-400 to zinc-500 (#71717a, ~4.6:1).
- Touch targets: social buttons 38px -> 44x44 (meets 44pt minimum).
- Cursor + disabled: cursor-pointer on buttons; disabled state dims + blocks.
- Form a11y: required-field asterisks (name/service/budget/message),
  autocomplete on name/company, and role=status aria-live=polite on the
  submit status so screen readers announce success/error.

Kept Syne + system fonts and the blue accent (skill suggested Inter + an
AI-purple palette its own anti-patterns reject). Rebuilt Tailwind bundles.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-26 05:33:44 +03:30
parent 93f7873dd1
commit 8896740895
6 changed files with 21 additions and 17 deletions
+1 -1
View File
@@ -20,7 +20,7 @@
<a href="/blog/@post.Slug" class="group reveal grid grid-cols-1 gap-2 border-t border-zinc-200 py-6 sm:grid-cols-[8rem_1fr] sm:gap-8">
<div class="flex items-baseline justify-between sm:flex-col sm:gap-1">
<span class="kicker">@post.Category</span>
<span class="text-[.78rem] text-zinc-400">@post.ReadTime @(fa ? "دقیقه" : "min")</span>
<span class="text-[.78rem] text-zinc-500">@post.ReadTime @(fa ? "دقیقه" : "min")</span>
</div>
<div>
<h2 class="text-[1.1rem] font-semibold transition-colors group-hover:text-accent @(fa ? "font-fa" : "")">@post.Title</h2>
+1 -1
View File
@@ -21,7 +21,7 @@
<header class="mb-8">
<span class="kicker">@Model.Category</span>
<h1 class="mt-3 @(fa ? "font-fa" : "")" style="font-size:clamp(1.8rem,4vw,2.5rem)">@Model.Title</h1>
<p class="mt-3 text-sm text-zinc-400">@Model.ReadTime @(fa ? "دقیقه مطالعه" : "min read")</p>
<p class="mt-3 text-sm text-zinc-500">@Model.ReadTime @(fa ? "دقیقه مطالعه" : "min read")</p>
</header>
<article class="prose-custom">
+10 -10
View File
@@ -68,7 +68,7 @@
@foreach (var (id, title, desc, tags) in services)
{
<article class="svc reveal border-t border-zinc-200 pt-6" style="transition-delay:@(si * 60)ms">
<span class="svc-icon text-zinc-400" aria-hidden="true">@Html.Raw(ServiceIcon(id))</span>
<span class="svc-icon text-zinc-500" aria-hidden="true">@Html.Raw(ServiceIcon(id))</span>
<h3 class="mt-5 text-lg font-semibold @(fa ? "font-fa" : "")">@title</h3>
<p class="mt-2.5 text-[.95rem] leading-relaxed text-zinc-600">@desc</p>
<div class="mt-4 flex flex-wrap gap-1.5">
@@ -110,7 +110,7 @@
{
stepN++;
<li class="reveal border-t border-zinc-200 pt-4" style="transition-delay:@((stepN-1) * 40)ms">
<span class="font-display text-sm text-zinc-400">@stepN.ToString("D2")</span>
<span class="font-display text-sm text-zinc-500">@stepN.ToString("D2")</span>
<h3 class="mt-2 text-base font-semibold @(fa ? "font-fa" : "")">@nlabel</h3>
<p class="mt-1.5 text-[.85rem] leading-relaxed text-zinc-600">@ndesc</p>
</li>
@@ -268,7 +268,7 @@
<a href="/blog/@slug" class="group reveal grid grid-cols-1 gap-2 border-t border-zinc-200 py-6 sm:grid-cols-[8rem_1fr] sm:gap-8">
<div class="flex items-baseline justify-between sm:flex-col sm:gap-1">
<span class="kicker">@cat</span>
<span class="text-[.78rem] text-zinc-400">@readTime @(fa ? "دقیقه" : "min")</span>
<span class="text-[.78rem] text-zinc-500">@readTime @(fa ? "دقیقه" : "min")</span>
</div>
<div>
<h3 class="text-[1.1rem] font-semibold transition-colors group-hover:text-accent @(fa ? "font-fa" : "")">@btitle</h3>
@@ -299,18 +299,18 @@
<div class="grid grid-cols-1 gap-5 sm:grid-cols-2">
<div>
<label class="flabel" for="name">@(fa ? "نام" : "Name")</label>
<input id="name" name="name" type="text" required placeholder="@(fa ? "نام و نام خانوادگی" : "Full name")" class="field" />
<label class="flabel" for="name">@(fa ? "نام" : "Name")<span class="text-red-600" aria-hidden="true"> *</span></label>
<input id="name" name="name" type="text" required autocomplete="name" placeholder="@(fa ? "نام و نام خانوادگی" : "Full name")" class="field" />
</div>
<div>
<label class="flabel" for="company">@(fa ? "سازمان" : "Company")</label>
<input id="company" name="company" type="text" placeholder="@(fa ? "نام سازمان" : "Organization")" class="field" />
<input id="company" name="company" type="text" autocomplete="organization" placeholder="@(fa ? "نام سازمان" : "Organization")" class="field" />
</div>
</div>
<div class="grid grid-cols-1 gap-5 sm:grid-cols-2">
<div>
<label class="flabel" for="service">@(fa ? "خدمت" : "Service")</label>
<label class="flabel" for="service">@(fa ? "خدمت" : "Service")<span class="text-red-600" aria-hidden="true"> *</span></label>
<select id="service" name="service" required class="field">
<option value="" disabled selected>@(fa ? "انتخاب کنید" : "Select…")</option>
@if (fa)
@@ -334,7 +334,7 @@
</select>
</div>
<div>
<label class="flabel" for="budget">@(fa ? "بودجه (تقریبی)" : "Budget (rough)")</label>
<label class="flabel" for="budget">@(fa ? "بودجه (تقریبی)" : "Budget (rough)")<span class="text-red-600" aria-hidden="true"> *</span></label>
<select id="budget" name="budget" required class="field">
<option value="" disabled selected>@(fa ? "انتخاب کنید" : "Select…")</option>
<option>Under $10k</option>
@@ -346,12 +346,12 @@
</div>
<div>
<label class="flabel" for="message">@(fa ? "پیام" : "Message")</label>
<label class="flabel" for="message">@(fa ? "پیام" : "Message")<span class="text-red-600" aria-hidden="true"> *</span></label>
<textarea id="message" name="message" required rows="4" placeholder="@(fa ? "هدف، بازه‌ی زمانی، و چیزی که الان گیرتان انداخته…" : "Goal, timeline, current blockers…")" class="field resize-none"></textarea>
</div>
<button type="submit" class="btn w-full">@(fa ? "ارسال پیام" : "Send request")</button>
<p id="contact-status" class="mt-1 text-sm text-zinc-500">@(fa ? "معمولاً ظرف ۲۴ ساعت کاری جواب می‌دهم." : "Typical reply within 24 working hours.")</p>
<p id="contact-status" role="status" aria-live="polite" class="mt-1 text-sm text-zinc-500">@(fa ? "معمولاً ظرف ۲۴ ساعت کاری جواب می‌دهم." : "Typical reply within 24 working hours.")</p>
</form>
</div>
</section>
+2 -2
View File
@@ -150,8 +150,8 @@
</div>
<div class="mx-auto mt-12 flex max-w-6xl flex-col items-center gap-2 border-t border-zinc-200 pt-6 text-center sm:flex-row sm:justify-between sm:text-start">
<p class="text-[.78rem] text-zinc-400">© 2026 Soroush Asadi. @(fa ? "تمام حقوق محفوظ است." : "All rights reserved.")</p>
<p class="text-[.78rem] text-zinc-400">@(fa ? "ساخته‌شده با دقت در تهران." : "Built with care in Tehran.")</p>
<p class="text-[.78rem] text-zinc-500">© 2026 Soroush Asadi. @(fa ? "تمام حقوق محفوظ است." : "All rights reserved.")</p>
<p class="text-[.78rem] text-zinc-500">@(fa ? "ساخته‌شده با دقت در تهران." : "Built with care in Tehran.")</p>
</div>
</footer>