feat(web): marketing Home page and the product component library (ADR 0023)

Product UI components are built once at design size from the Figma file and reused by the marketing mockups and, later, the app. Text contrast tokens now meet WCAG AA in both themes, with a test. Pricing stays hidden until decided.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014SdXCbrN5PtGExkpvMaMHx
This commit is contained in:
Claude
2026-10-12 15:25:50 +00:00
parent 913d7a8832
commit 6947113027
110 changed files with 3135 additions and 37 deletions
+4 -5
View File
@@ -3,9 +3,8 @@ Do not redraw or edit them. Re-export from Figma if the design changes.
| File | Figma node |
|---|---|
| brand-mark-light.svg | Brand/Mark (28:30), light |
| brand-mark-dark.svg | Brand/Mark in Nav Bar, dark (136:72493) |
| icons/menu.svg | Icon in Menu · Mobile (143:77164) |
| icons/chevron-right.svg | Icon/chevron-right in Hero Announcement (64:1451) |
| brand-mark-light.svg / brand-mark-dark.svg | Brand/Mark (28:30), Nav Bar light (64:1426) and dark (136:72493) |
| avatar-mark.svg / avatar-mark-dark.svg | Mark inside the Wursor Avatar (28:98), light and dark |
| backdrop.svg | Backdrop "Size=Wide" (63:1707); the same warm backdrop is used in light and dark |
Single-colour icons are drawn with CSS masks so they take the token colour for the current theme.
Icons are in ../icons. They are drawn with CSS masks so they take the token colour for the current theme.
@@ -0,0 +1,6 @@
<svg preserveAspectRatio="none" overflow="visible" style="display: block;" width="10.6944" height="10.6944" viewBox="0 0 10.6944 10.6944" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Mark">
<path id="Vector" d="M2.00521 6.90683C2.00521 5.06115 3.50154 3.56481 5.34722 3.56481C7.19291 3.56481 8.68924 5.06115 8.68924 6.90683" stroke="#14120B" stroke-width="2.48264" stroke-linecap="round" stroke-linejoin="round"/>
<circle id="ember" cx="5.34722" cy="6.90683" r="0.891204" fill="#FF7A33"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 511 B

+6
View File
@@ -0,0 +1,6 @@
<svg preserveAspectRatio="none" overflow="visible" style="display: block;" width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Mark">
<path id="Vector" d="M2.625 9.04167C2.625 6.6255 4.58383 4.66667 7 4.66667C9.41617 4.66667 11.375 6.6255 11.375 9.04167" stroke="#F2F1EC" stroke-width="3.25" stroke-linecap="round" stroke-linejoin="round"/>
<circle id="ember" cx="7" cy="9.04167" r="1.16667" fill="#E8590C"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 467 B

+48
View File
@@ -0,0 +1,48 @@
<svg preserveAspectRatio="none" overflow="visible" style="display: block;" width="1344" height="720" viewBox="0 0 1344 720" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Backdrop">
<g clip-path="url(#clip0_0_834)">
<rect id="Base" width="1344" height="720" fill="url(#paint0_linear_0_834)"/>
<g id="Blob 1" filter="url(#filter0_f_0_834)">
<ellipse cx="201.6" cy="540" rx="369.6" ry="324" fill="#F28C54" fill-opacity="0.5"/>
</g>
<g id="Blob 2" filter="url(#filter1_f_0_834)">
<ellipse cx="1048.32" cy="144" rx="336" ry="288" fill="#FFEDCC" fill-opacity="0.9"/>
</g>
<g id="Blob 3" filter="url(#filter2_f_0_834)">
<ellipse cx="739.2" cy="684" rx="302.4" ry="216" fill="#FCCCA8" fill-opacity="0.9"/>
</g>
<g id="Blob 4" filter="url(#filter3_f_0_834)">
<ellipse cx="67.2" cy="72" rx="235.2" ry="180" fill="#FFE0C2" fill-opacity="0.9"/>
</g>
</g>
</g>
<defs>
<filter id="filter0_f_0_834" x="-337" y="47" width="1077.2" height="986" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="84.5" result="effect1_foregroundBlur_0_834"/>
</filter>
<filter id="filter1_f_0_834" x="543.32" y="-313" width="1010" height="914" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="84.5" result="effect1_foregroundBlur_0_834"/>
</filter>
<filter id="filter2_f_0_834" x="267.8" y="299" width="942.8" height="770" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="84.5" result="effect1_foregroundBlur_0_834"/>
</filter>
<filter id="filter3_f_0_834" x="-337" y="-277" width="808.4" height="698" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="84.5" result="effect1_foregroundBlur_0_834"/>
</filter>
<linearGradient id="paint0_linear_0_834" x1="672" y1="0" x2="672" y2="720" gradientUnits="userSpaceOnUse">
<stop stop-color="#FAEDE0"/>
<stop offset="1" stop-color="#F5D6BD"/>
</linearGradient>
<clipPath id="clip0_0_834">
<path d="M0 24C0 10.7452 10.7452 0 24 0H1320C1333.25 0 1344 10.7452 1344 24V696C1344 709.255 1333.25 720 1320 720H24C10.7452 720 0 709.255 0 696V24Z" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

@@ -1,5 +0,0 @@
<svg preserveAspectRatio="none" overflow="visible" style="display: block;" width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Icon/chevron-right">
<path id="Vector" d="M7.5 15L12.5 10L7.5 5" stroke="#6B675E" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 335 B

-5
View File
@@ -1,5 +0,0 @@
<svg preserveAspectRatio="none" overflow="visible" style="display: block;" width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Icon">
<path id="Vector" d="M5.33333 4H14M5.33333 8H14M5.33333 12H14M2 4H2.00667M2 8H2.00667M2 12H2.00667" stroke="#14120B" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 377 B