Our Wedding Link Design System
Overview
Our Wedding Link presents itself as Indonesia's leading digital wedding platform — a toolchain spanning invitation creation, guestbook management, and wedding planning coordination. The visual system strikes a careful balance between contemporary SaaS polish and the emotional warmth expected of wedding industry branding. The dominant mood is optimistic romance: soft coral-pink CTAs pop against cream-washed hero backgrounds, while Montserrat's geometric humanism carries both utility-laden navigation labels and large-scale display headlines without sacrificing readability or personality.
Brand voltage concentrates in two specific surfaces: the coral-pink primary action buttons ({colors.accent} / #ffa0ae) that drive conversions throughout the funnel, and the warm rose-tinted background washes ({colors.signature-rose} / #fbeced) that distinguish the hero and statistics bands from neutral page real estate. The gold/yellow accent ({colors.primary} / #ffc107) operates as a tertiary highlight color — applied sparingly to badge-style text ("No #1 Platform") and icon treatments rather than serving as the main conversion driver.
The single typographic move defining this system is its generous size scale paired with modest-to-strong weights. Body copy sits at an unusually large {typography.body-md} (20px), ensuring accessibility and approachability for a demographic spanning tech-savvy couples to their parents. Display headlines ({typography.display-lg} at 36px, weight 700) command attention without resorting to compressed or ultra-black treatments. The shape language favors friendly roundness over sharp precision: buttons use {rounded.md} (12px), cards hover around {rounded.DEFAULT} (10px), and fully circular elements (social icons, avatar placeholders) hit {rounded.circle} (50%). Pill-shaped treatments appear reserved for special cases rather than being the default.
Sub-systems observed include: the main landing page dialect (coral CTAs, cream backgrounds, large type), the navigation dialect (clean white bar, link-based actions, dropdown indicators), and the device mockup presentation layer (realistic phone/tablet frames with subtle shadows showcasing invitation template previews). The chat widget operates as an independent floating component using the info-blue palette ({colors.info}) to differentiate it from brand CTAs.
Key Characteristics:
- Canvas is pure white (
{colors.canvas}— #ffffff) with warm off-white alternatives ({colors.surface-soft},{colors.signature-rose}) - Primary conversion color is coral-pink (
{colors.accent}— #ffa0ae) with dark ink text ({colors.on-accent}) - Gold highlight (
{colors.primary}— #ffc107) serves badges and accent moments, not primary buttons - Headlines use slate-navy (
{colors.heading}— #49516f) for sophisticated contrast against warm backgrounds - Body text at 20px (
{typography.body-md}) prioritizes readability across age demographics - Button radius consistently
{rounded.md}(12px) — friendly but not overly playful - Shadow system is intentionally soft (
{extensions.shadows.sm}) with warm undertones - Decorative floral imagery provides organic counterpoint to geometric UI surfaces
- Stats band uses oversized numerals (
{typography.stat-number}— 56px) in coral for impact
Colors
Brand & Accent
- Primary (
{colors.primary}— #ffc107): Golden-yellow accent used for badge-style callouts ("No #1 Platform"), icon highlights, and tertiary emphasis. Not used as primary button fill. - Primary Hover (
{colors.primary-hover}— #ffb300): Darker gold state for interactive elements using the primary token. - Primary Active (
{colors.primary-active}— #ff8f00): Pressed/deepest gold state. - Accent (
{colors.accent}— #ffa0ae): The true workhorse brand color — coral-pink filling all primary buttons, CTAs, stat numbers, and key conversion surfaces. Carries the emotional warmth of the wedding category. - Accent Hover (
{colors.accent-hover}— #ff8a9c): Deepened coral for hover states on primary buttons and interactive elements. - Accent Active (
{colors.accent-active}— #f06e85): Deepest coral for active/pressed states, maintaining sufficient contrast against{colors.on-accent}. - Secondary (
{colors.secondary}— #f63854): Red-pink used for link text (nav dropdowns, inline links) and alert-type communications. - Signature Coral (
{colors.signature-coral}— #ffa0ae): Alias for{colors.accent}, reinforcing the brand's primary identity color in documentation contexts. - Signature Rose (
{colors.signature-rose}— #fbeced): Very light pink wash used as section backgrounds (hero band, CTA areas) to create warmth without competing with content. - Signature Red (
{colors.signature-red}— #d6001c): Deep red reserved for error states and high-urgency semantic communication.
Surface
- Canvas (
{colors.canvas}— #ffffff): Pure white baseline for the majority of page real estate — nav bar, card backgrounds, content areas. - Surface Soft (
{colors.surface-soft}— #f8f8f8): Near-white with slight warmth, used for subtle sectional differentiation and alternate row backgrounds. - Surface Warm (
{colors.surface-warm}— #fbeced): Rose-tinted off-white creating the distinctive hero and CTA band atmosphere. This is the system's most recognizable non-white surface. - Surface Neutral (
{colors.surface-neutral}— #f4f4f4): Cool gray-white for device mockup frames, card containers needing neutral grounding. - Surface Elevated (
{colors.surface-elevated}— #ffffff): White surfaces sitting above baseline via shadow elevation — modals, dropdowns, floating panels. - Surface Dark (
{colors.surface-dark}— #26282b): Near-black used for inverted text scenarios, dark mode accents within the light theme, and high-contrast label backgrounds.
Text & Ink
- Ink (
{colors.ink}— #ffc107): Yellow-toned text token (per pre-assigned value) used for special highlight text applications where gold visibility is required. - Body (
{colors.body}— #212529): Near-black, the workhorse text color for body paragraphs, descriptions, and general readable content. Provides maximum contrast against white and light surfaces. - Heading (
{colors.heading}— #49516f): Slate-blue navy carrying headlines and subheadlines — sophisticated alternative to pure black that harmonizes with warm brand colors while remaining highly legible. - Muted (
{colors.muted}— #495057): Medium-gray for secondary text, captions, placeholder content, and supporting information that shouldn't compete with primary content. - Muted Medium (
{colors.muted-medium}— #5d5d5d): Slightly lighter mid-tone gray for tertiary text, timestamps, metadata. - Muted Dark (
{colors.muted-dark}— #2d2d2d): Dark gray approaching black — used for small-button text where{colors.body}feels too heavy at small sizes. - On-Accent (
{colors.on-accent}— #26282b): Very dark text color placed atop{colors.accent}(coral) surfaces — ensures WCAG-compliant contrast on pink backgrounds. - On-Primary (
{colors.on-primary}— #ffffff): White text for placement atop{colors.primary}(gold) and any dark-surface scenarios. - On-Dark (
{colors.on-dark}— #ffffff): White text for dark backgrounds, inverted UI regions. - On-Surface (
{colors.on-surface}— #212529): Alias for body text when referencing surface-specific text treatment conventions.
Hairlines & Borders
- Hairline (
{colors.hairline}— #f4f4f4): Barely-visible divider for subtle separation between content blocks, table rows, list items. - Border Soft (
{colors.border-soft}— #e9ecef): Visible but gentle border color for input fields, card outlines, and contained elements. - Border Accent (
{colors.border-accent}— #ffa0ee): Coral-tinted border for outlined button variants, focus rings on primary-adjacent components, and highlighted containment. - Border Strong (
{colors.border-strong}— #dee2e6): Medium-gray border for defined edges — card borders when elevation isn't sufficient, form field defaults.
Semantic
- Link (
{colors.link}— #f63854): Red-pink matching{colors.secondary}— standard hyperlink color for inline navigation and external references. - Link Hover (
{colors.link-hover}— #d6001c): Deepened red on hover/active link states. - Info (
{colors.info}— #007bff): Standard blue for informational UI — the chat widget uses this as its background color to stand apart from brand CTAs. - Success (
{colors.success}— #008489): Teal-green for confirmation states, success messages, completed actions. - Error (
{colors.error}— #d6001c): Deep red for validation errors, warning states, destructive action feedback.
Typography
Font Family
The system is built primarily on Montserrat, a geometric sans-serif with excellent readability across Latin and extended character sets — critical for an Indonesian-market platform supporting both Bahasa Indonesia and English content. Montserrat carries every role from navigation links ({typography.nav-link} at 18px) through massive display headlines ({typography.display-xl} at 48px). Poppins appears as a closely-matched secondary fallback, sharing Montserrat's geometric humanist skeleton while providing subtle distinction in edge cases. The font stack resolves as "montserrat, 'Poppins', sans-serif" across all tokens.
Beyond the core system fonts, Our Wedding Link deploys a rich library of custom decorative typefaces loaded via @font-face for invitation template rendering and signature-branding moments: amanise (elegant script), honey-carrot (display serif), brittney-signature (handwritten style), julietta-messie (editorial serif), malatan, monarda, and maxcellent. These are not part of the UI system type scale — they exist strictly within the invitation preview/mockup subsystem. Roboto variants (Black, Light, Regular) serve as functional fallbacks for weight coverage outside Montserrat's native range.
Hierarchy
| Token | Size | Weight | Line Height | Letter Spacing | Use |
|---|---|---|---|---|---|
| {typography.display-xl} | 48px | 700 | 1.2 | -0.02em | Hero-level statements, campaign headlines |
| {typography.display-lg} | 36px | 700 | 1.2 | -0.01em | Main hero headline ("Pernikahan Digital") |
| {typography.display-md} | 28px | 700 | 1.25 | 0 | Section titles, major subheadlines |
| {typography.title-lg} | 24px | 600 | 1.3 | 0 | Card titles, feature names |
| {typography.title-md} | 20px | 600 | 1.35 | 0 | Subsection headers, testimonial names |
| {typography.body-md} | 20px | 400 | 1.5 | 0 | Primary body copy, hero descriptions |
| {typography.body-sm} | 16px | 400 | 1.5 | 0 | Secondary body text, legal, captions |
| {typography.caption} | 14px | 400 | 1.4 | 0 | Metadata, timestamps, helper text |
| {typography.button} | 15px | 600 | 1.3 | 0 | Button labels, CTA text |
| {typography.label-sm} | 11px | 600 | 1.2 | 0.02em | Small button text, tags, badges |
| {typography.nav-link} | 18px | 600 | 1.3 | 0 | Navigation items, dropdown triggers |
| {typography.stat-number} | 56px | 700 | 1.1 | -0.03em | Statistics numerals, big counters |
Principles
The typography system's most distinctive characteristic is its refusal to compress line height or letter-spacing for dramatic effect. Even at 48px display size, lines sit at a comfortable 1.2 ratio with only -0.02em tracking — this keeps text feeling open, breathable, and welcoming rather than aggressive or fashion-editorial. The weight distribution tells a clear story: body text stays at 400 (regular) while anything demanding attention jumps to 600 or 700. There's no 500 middleweight in the system — the hierarchy relies on size deltas (48→36→28→24→20) combined with binary regular/bold switching.
Color plays an equal role in typographic hierarchy. The hero headline splits into two tones: the superheading ("No #1 Platform") renders in {colors.accent} (coral-pink) at display size, while the primary headline ("Pernikahan Digital") drops to {colors.heading} (slate navy). This mixed-color technique allows the system to create visual interest without inflating the type scale further. Stat numbers invert the expectation — they're enormous (56px) and rendered in coral ({colors.accent}), making them function as graphic elements as much as data readouts.
The system trusts size over weight transformation for creating emphasis. Uppercase is absent entirely; italic is unobserved in UI text. Letter-spacing adjustments are minimal and reserved for the smallest text ({typography.label-sm} gets +0.02em to aid legibility at 11px). The overall voice is conversational confidence — bold enough to be authoritative, open enough to feel like a helpful friend guiding you through wedding planning.
Note on Font Substitutes
Montserrat maps directly to Google Fonts' Montserrat (weights 400, 500, 600, 700 available). Poppins also exists on Google Fonts as a drop-in substitute if the secondary fallback needs explicit loading. For environments where Google CDN access is restricted (certain enterprise or Indonesian network configurations), the system should self-host Montserrat woff2 files. The custom decorative fonts (amanise, honey-carrot, etc.) are proprietary to the platform and cannot be publicly substituted — they must be bundled with the application or served from the project's /fonts directory. If these fail to load, the system degrades gracefully to Montserrat with appropriate weight matching.
CSS variable definitions for implementation:
:root {
--font-sans: 'montserrat', 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
--font-display: 'montserrat', 'Poppins', sans-serif;
}
Layout
Spacing System
- Base unit: 3px (the finest increment observed, used for micro-adjustments).
- Tokens:
{spacing.xxs}(3px — atomic offsets),{spacing.xs}(5px — tight internal gaps),{spacing.sm}(8px — icon-text gaps),{spacing.md}(10px — compact padding),{spacing.base}(12px — standard small padding),{spacing.lg}(15px — comfortable padding),{spacing.xl}(16px — card internal spacing),{spacing.xx l}(20px — section-internal spacing),{spacing.section-sm}(22px — minor vertical rhythm),{spacing.section-md}(24px — component stacking),{spacing.section-lg}(25px — major section breaks),{spacing.hero}(110px — hero bottom breathing room),{spacing.container-offset}(125px — left offset for fixed containers). - Section padding (vertical):
{spacing.hero}(110px) below the header/navigation zone;{spacing.section-lg}(25px) between content bands in the lower page. - Card internal padding: Varies by component —
{component.card-elevated}uses{spacing.xx l}(20px);{component.chat-bubble}uses{spacing.lg}(15px). - Gutters: The main content area maintains approximately 125px left offset (
{spacing.container-offset}) for the hero section's asymmetric layout; standard centered sections use responsive auto margins with implicit ~20px gutters on mobile.
Grid & Container
The layout employs a fluid-asymmetric hero grid where text content occupies roughly the left 45-50% of viewport width, while the device mockup illustration claims the right portion with overlapping positioning. Below the fold, the system shifts to a centered columnar layout with max-width constraints around 1200-1440px (matching the extracted container width of 1440px). The statistics band spans full-viewport width with internally-centered content. Portfolio grids appear to use a multi-column masonry or flex-wrap arrangement for invitation template thumbnails.
Editorial density is low-to-moderate — the 20px body size and generous leading (1.5) prevent cramped reading experiences. This is a storytelling landing page, not a dashboard marketplace, so whitespace is used liberally between rhetorical units. The hero specifically leverages negative space via the {colors.signature-rose} background wash to create a "breathing room" effect before dense mockup detail enters from the right.
Whitespace Philosophy
Our Wedding Link practices asymmetric generosity with whitespace — the left-side text column in the hero has substantial right-margin clearance, while the right-side device cluster crowds toward the viewport edge. This creates dynamic tension rather than static centering. Vertical whitespace follows a "big-small-big" rhythm: massive hero padding (110px), tighter inter-component spacing (20-25px), then another large stats band. The philosophy treats whitespace as active compositional element rather than mere separator — the rose-tinted empty space in the hero signals "wedding day warmth" as strongly as any photograph could.
Header Architecture
┌─────────────────────────────────────────────────────────────────┐
│ [♥ Logo] Preset/Desain Portofolio Lainnya ▼ Daftar [Masuk] │
│ ──────────── ────────── ──────── ───── │
└─────────────────────────────────────────────────────────────────┘
↑ ↑
flush-left logo flush-right auth
centered navigation links (with dropdown indicator)
Navigation uses a standard top-bar architecture: logo lock-left, navigation links centered (with the "Lainnya" item carrying a dropdown caret and {colors.secondary} coloring), and authentication actions (text link "Daftar" + solid button "Masuk") flush-right. The bar sits on {colors.canvas} with no bottom border or shadow — it relies on background continuity with the page body. Height is auto-determined by content (roughly 60-72px including padding).
Hero Section
┌──────────────────────────────────────────────────────────────────┐
│ ┌─────────────────────┐ ┌────────────────────────────────┐ │
│ │ No #1 Platform │ │ [Social Icons Stack] │ │
│ │ Pernikahan Digital │ │ ┌──────────┐ │ │
│ │ Wedding Planner │ │ │ Tablet │ │ │
│ │ ...description... │ │ │ Mockup │ │ │
│ │ │ │ └──────────┘ │ │
│ │ Solusi pernikahan.. │ │ ┌──────┐ │ │
│ │ │ │ │Phone │ │ │
│ │ [Buat Sekarang!] │ │ │Mockup│ │ │
│ └─────────────────────┘ │ └──────┘ │ │
│ │ [Floral Decoration] │ │
│ └────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
← Text Column (45%) → ← Illustration Column (55%) →
Background: {signature-rose} Overlapping devices + flora
The hero is a two-column asymmetric composition on a {colors.signature-rose} (cream-pink) background wash. Left column holds the message hierarchy: coral accent superheadline, navy primary headline, subtitle, descriptive paragraph emphasizing modernity/efficiency, and the primary CTA button. Right column contains a layered arrangement: vertical social media icon stack (Facebook, Instagram, WhatsApp, Phone) in circular containers, a tablet device frame showing an invitation template preview, a smaller mobile phone frame overlaid in front, and decorative floral photography (white peonies/flowers) bleeding from the right edge. Devices cast soft shadows ({extensions.shadows.sm}).
Statistics Band
┌──────────────────────────────────────────────────────────────────┐
│ │
│ [Photo: Bride back-of-head] 50.611 Pasangan berbahagia │
│ Dari luar dan dalam negeri... │
│ │
│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │card 1│ │card 2│ │card 3│ │card 4│ ← Portfolio grid │
│ └──────┘ └──────┘ └──────┘ └──────┘ │
│ │
└──────────────────────────────────────────────────────────────────┘
The stats section introduces a split-image-and-data layout. Left side features atmospheric photography (bride from behind, soft focus). Right side presents the key metric: "50.611" in enormous coral {typography.stat-number} (56px), followed by "Pasangan berbahagia" (Happy couples) in navy {typography.display-lg}, and a supportive sentence about geographic reach. Below this, a horizontal portfolio grid displays invitation template thumbnails as clickable cards.
Elevation & Depth
| Level | Treatment | Use |
|---|---|---|
| 0 (Flat) | No shadow, solid background {colors.canvas} | Base page surfaces, nav bar, flat buttons |
| 1 (Hairline) | 1px border {colors.border-soft} or {colors.border-accent} | Outlined buttons, input fields, card boundaries |
| 2 (Soft Drop) | {extensions.shadows.sm} — warm rgba(184,180,184,0.2) blur | Device mockup frames, elevated cards, floating panels |
| 3 (Modal) | {extensions.shadows.md} — deeper rgba(34,34,34,0.25) | Dropdown menus, modal dialogs, tooltip containers |
| 4 (Strong) | {extensions.shadows.lg} — sharp rgba(0,0,0,0.4) | Chat widget, persistent floating actions |
| Focus Ring | Border-color transition + subtle shadow shift | Input focus, keyboard-navigated elements |
The elevation philosophy is warmly layered rather than cool-flat. Shadows carry distinct warm/gray undertones (the primary {extensions.shadows.sm} has brownish-gray rgba values) rather than neutral-black drops, which helps the depth system harmonize with the overall warm palette. The system avoids hard-edged drop shadows entirely — every elevation uses significant blur radius (13px+ at level 2) to create diffuse, ambient depth. Buttons at rest are flat (no shadow, relying on background color differentiation); they don't lift on hover in the current implementation (shadow presence is minimal across interactive surfaces).
Color-block elevation (using {colors.surface-soft} or {colors.signature-rose} to raise a section) competes equally with shadow-based elevation. The hero band "rises" via background color change, not shadow. The stats band returns to {colors.canvas} to "settle" back to baseline. This alternation of warm-toned color bands and white space creates rhythmic depth without shadow fatigue.
Decorative Depth
Beyond UI elevation, the system employs photographic and illustrative depth layers: the floral decoration (white peonies) overlaps the device mockup edge, creating a foreground/midground/background relationship within the hero. The bride photograph in the stats section uses shallow depth-of-field (bokeh background) to create natural focal hierarchy. Device screens show rendered invitation interfaces with their own internal UI depth (cards within cards within frames) — a "Russian doll" layering that demonstrates product capability while adding visual richness.
Shapes
Border Radius Scale
| Token | Value | Use |
|---|---|---|
| {rounded.sm} | 6.4px | Small buttons, tag elements, subtle rounding |
| {rounded.DEFAULT} | 10px | Default card radius, standard containers |
| {rounded.md} | 12px | Primary buttons, chat widget, prominent CTAs |
| {rounded.lg} | 15px | Larger cards, mobile device frames |
| {rounded.xl} | 25px | Tablet device frames, hero image containers |
| {rounded.pill} | 9999px | Reserved for special pill-shaped elements |
| {rounded.circle} | 50% | Social icon containers, avatars, perfectly round elements |
The shape vocabulary is intentionally constrained — seven tokens cover every observed rounded corner, with clear semantic separation by size class. The system avoids sub-pixel radii (the smallest is 6.4px, a deliberate non-integer suggesting Bootstrap-derived origin) and extreme rounding (nothing exceeds 25px except circles/pills). This restraint prevents the "everything is rounded" aesthetic trap while maintaining approachability. Buttons consistently use {rounded.md} (12px) — round enough to feel friendly, square enough to feel purposeful. Device frames use progressively larger radii (mobile at 15px, tablet at 25px) to mirror real-world hardware proportions.
Photography Geometry
Images in this system follow natural aspect ratios with controlled rounding. The hero floral decoration bleeds edge-to-edge without container rounding (it's a positional overlay, not a contained image). The bride photograph in the stats section appears as a rectangular crop (roughly 3:4 or 4:5 portrait) with no corner rounding — it integrates as a raw photographic element. Portfolio thumbnail cards likely use 4:3 or 3:2 landscape ratios with {rounded.md} (12px) corners to match the card container. Device mockup screenshots maintain the aspect ratios of the frames they inhabit (tablet ~4:3, mobile ~9:19.5). Avatar or user-photo placeholders (if present in authenticated views) would adopt {rounded.circle} per the social icon convention.
Components
No hover states documented. Hover behavior is unreliable to extract from a single screenshot. State variants live as separate entries in the
components:frontmatter (e.g.{component.button-primary-hover},{component.text-input-focus}); add hover styling at implementation time per your stack's conventions.
Buttons
{component.button-primary} — The system's primary conversion button. Background {colors.accent} (coral #ffa0ae), text {colors.on-accent} (near-black #26282b), type {typography.button} (15px/600), rounded {rounded.md} (12px), padding 16px 26px. Used for "Masuk" (Sign In) in the navigation and "Buat Sekarang Gratis!" (Create Free Now!) in the hero. Has no box shadow at rest, relying on color mass for visibility. Border matches background color (1px solid {colors.accent}). State variants: {component.button-primary-hover} darkens to {colors.accent-hover}, {component.button-primary-active} reaches deepest coral {colors.accent-active}.
{component.button-outline} — Secondary/tertiary button with transparent background, 1px border in {colors.border-accent} (coral), text {colors.muted-dark} at {typography.label-sm} (11px/600). Significantly smaller than primary (padding 4.8px 8px) — used for lightweight actions like "Log in" text-link-styled buttons. Rounded {rounded.md} (12px) maintains consistency despite reduced size. State variant: {component.button-outline-focus} shifts text to {colors.heading} on interaction.
{component.button-link} — Text-only button behaving as a link. Transparent background, no border, text {colors.secondary} (red-pink #f63854) at {typography.nav-link} (18px/600). Used for the "Lainnya" (More) dropdown trigger. Minimal padding (0), rounded {rounded.sm} (6.4px) for hit-area definition. State: {component.button-link-hover} deepens to {colors.link-hover}.
Cards & Containers
{component.card-basic} — Standard content card. Background {colors.canvas}, text {colors.body}, type {typography.body-sm}, rounded {rounded.DEFAULT} (10px), padding {spacing.xl} (16px). Used for portfolio grid items, informational tiles. Flat (no shadow), relying on optional border or background differentiation.
{component.card-elevated} — Raised content card with presence. Background {colors.surface-elevated} (white), text {colors.body}, type {typography.body-sm}, rounded {rounded.lg} (15px), padding {spacing.xx l} (20px). Would carry {extensions.shadows.sm} for elevation (described in prose, not YAML). Used for featured content, testimonials, or surfaces needing to detach from the page plane.
{component.device-mockup-container} — Wrapping container for the hero's device presentation stack. Transparent background (allows {colors.signature-rose} to show through), rounded {rounded.xl} (25px) to match the largest frame inside. Contains nested {component.device-frame-tablet} and {component.device-frame-mobile} plus floral overlays.
{component.device-frame-tablet} — Tablet-sized device frame in the hero. Background {colors.surface-neutral} (#f4f4f4) simulating device bezel, rounded {rounded.xl} (25px) for realistic tablet corner proportion. Contains a screenshot of the invitation builder interface.
{component.device-frame-mobile} — Mobile phone frame overlaid on the tablet. Background {colors.canvas} (white screen), rounded {rounded.lg} (15px) matching phone proportions. Shows a narrower view of the same invitation interface, demonstrating responsiveness.
{component.floral-decoration} — Decorative image overlay (peonies/flowers). No background or text color (purely presentational), rounded 0 (natural photo edges). Positioned absolute/relative to break out of the device container, creating organic framing.
{component.portfolio-grid-item} — Thumbnail card in the portfolio section. Background {colors.surface-neutral}, text {colors.body}, rounded {rounded.md} (12px). Likely contains an image preview with hover-reveal details.
{component.chat-bubble} — Speech bubble appearing near the chat widget. Background {colors.canvas}, text {colors.body} at {typography.body-sm}, rounded {rounded.lg} (15px) for conversational bubble shape, padding {spacing.lg} (15px). Contains the prompt text "Ada yang ingin ditanyakan?" (Anything to ask?).
Navigation
{component.top-nav} — The global navigation bar. Background {colors.canvas} (white), text defaults to {colors.body}, type {typography.nav-link} (18px/600), auto height determined by padding 16px vertical. Spans full viewport width, content constrained to 1440px max-width. No border-bottom, no shadow — seamless with page body.
{component.nav-logo} — Brand mark in the navigation left slot. Transparent background, text {colors.heading} (slate navy), type {typography.display-md} (28px/700) for "Our Wedding" wordmark. Preceded by a heart icon (♥) in coral. No rounded corners (inline text element).
{component.nav-link} — Standard navigation menu item. Transparent background, text {colors.body}, type {typography.nav-link}, padding 8px 16px. Horizontal layout within the centered nav group.
{component.nav-link-active} — Currently-active or emphasized nav link. Same structure as {component.nav-link} but text color shifts to {colors.secondary} (red-pink), indicating selection or hover proximity.
{component.nav-dropdown} — Dropdown-trigger nav item ("Lainnya ▸"). Transparent background, text {colors.secondary} (already styled as actionable/differentiated), type {typography.nav-link}, zero padding (compact). Includes a downward-caret indicator (CSS border-triangle or SVG).
{component.nav-auth-link} — Text-based authentication link ("Daftar" / Register). Transparent background, text {colors.body}, type {typography.body-sm} (smaller than nav links to de-emphasize), padding 8px 16px. Sits adjacent to the primary auth button.
Signature Components
{component.hero-band} — The full-width hero section container. Background {colors.signature-rose} (cream-pink #fbeced), text defaults to {colors.heading}, type {typography.display-lg} for child headlines, padding 0 bottom with 110px clearance. Establishes the distinctive warm opening atmosphere.
{component.hero-headline-accent} — The "No #1 Platform" superheadline. Transparent background, text {colors.accent} (coral), type {typography.display-lg} (36px/700). Renders above the main headline in coral to create dual-tone headline effect.
{component.hero-headline-primary} — The "Pernikahan Digital" main headline. Transparent background, text {colors.heading} (slate navy), type {typography.display-lg} (36px/700). The primary message carrier in the hero text column.
{component.hero-subheadline} — "Wedding Planner(soon) - Invitation - Digital Guestbook". Transparent background, text {colors.heading}, type {typography.body-md} (20px/400) — note body size used at subheadline weight for this role. Provides scannable capability summary.
{component.hero-description} — "One stop solution your wedding buddy! Solusi pernikahanmu jadi lebih modern..." Transparent background, text {colors.body} (near-black), type {typography.body-md} (20px/400). The persuasive body copy in the hero. Contains bold-weight emphasis on key phrases.
{component.hero-cta} — The "Buat Sekarang Gratis!" call-to-action button within the hero context. Structurally identical to {component.button-primary} (same colors, type, rounding, padding) but semantically distinguished as the hero's conversion target. Position: below description text, left-aligned with headline column.
{component.social-icon-circle} — Circular icon button for social platforms (Facebook, Instagram, WhatsApp, Phone). Transparent background, text/icon color {colors.muted} (gray), rounded {rounded.circle} (50%), size 44px (WCAG touch-target compliant). Arranged vertically along the left edge of the device mockup area. State: {component.social-icon-circle-hover} adds {colors.surface-soft} background and shifts icon to {colors.secondary} (coral/red-pink).
{component.stats-band} — Full-width statistics section. Background {colors.canvas} (returning to white after hero warmth), text {colors.heading}, type {typography.stat-number} (56px/700) for numerals, padding {spacing.section-lg} (25px) vertical. Contains the "50.611" metric and supporting text. Photo element occupies left portion.
{component.stat-number} — The large numerical display "50.611". Transparent background, text {colors.accent} (coral — making the number the most vivid element in the band), type {typography.stat-number} (56px/700, -0.03em tracking for tight numeral display). Functions as both data and graphic element.
{component.stat-label} — "Pasangan berbahagia" (Happy Couples) label beside the number. Transparent background, text {colors.heading} (navy), type {typography.display-lg} (36px/700) — headline-scale text acting as unit label for the stat number.
{component.stat-caption} — Supporting sentence "Dari luar dan dalam negeri sudah membuat undangannya..." Transparent background, text {colors.muted}, type {typography.body-sm} (16px/400). Provides context without competing for attention.
{component.chat-widget} — Floating action button in viewport bottom-right. Background {colors.info} (blue #007bff — deliberately differentiating from brand coral to avoid confusion with primary CTAs), text {colors.on-primary} (white), type {typography.button} (15px/600), rounded {rounded.md} (12px), padding 12px 20px. Contains a chat icon + "Chat" label. Uses {extensions.shadows.lg} for strong elevation (must float above all page content). Fixed/fixed-position.
{component.cta-section} — Call-to-action band (inferred pattern for lower-page conversion zones). Background {colors.signature-rose} (returning to warm tone for closing conversion), text {colors.heading}, type {typography.display-md} (28px/700), padding {spacing.section-lg}. Would contain a final {component.button-primary} instance.
Do's and Don'ts
Do
- Do use
{colors.accent}(#ffa0ae) for all primary conversion buttons — the coral-pink is the recognized CTA color across the brand, not{colors.primary}(gold). - Do set body text at
{typography.body-md}(20px/400) minimum for readability across the platform's multi-generational audience of couples and families. - Do apply
{colors.signature-rose}(#fbeced) as the hero and CTA section background to create the distinctive warm atmosphere — don't substitute plain white. - Do use
{colors.heading}(slate navy #49516f) for headlines against warm backgrounds — the cool-warm contrast is intentional and sophisticated. - Do round primary buttons to
{rounded.md}(12px) consistently — this is the established friendly-but-purposeful radius for CTAs. - Do leverage the dual-tone headline technique (coral superheadline + navy main headline) in hero contexts for visual rhythm without inflating type size.
- Do give social icon containers
{rounded.circle}(50%) and 44px minimum dimension for touch compliance and visual consistency. - Do reserve
{colors.info}(blue) exclusively for the chat/widget system — never use it for primary brand actions. - Do apply
{extensions.shadows.sm}(warm blur) to device mockups and elevated cards — avoid hard-edged black shadows. - Do keep stat numbers at
{typography.stat-number}(56px) in{colors.accent}when displaying metrics — the oversized coral numeral is a signature pattern. - Do use Montserrat as the sole UI typeface for all interface text; reserve custom script fonts (amanise, honey-carrot) exclusively for invitation template rendering.
Don't
- Don't use
{colors.primary}(#ffc107 gold) as a primary button background — this color is reserved for badge highlights and accent moments, not conversion drivers. - Don't drop headline weight below 600 for any display or title role — the system relies on boldness for hierarchy, not compression or decoration.
- Don't add gradient overlays or dramatic shadows to the hero band — the
{colors.signature-rose}flat wash is the intended treatment. - Don't exceed
{rounded.xl}(25px) for any rectangular container — larger radii are reserved for{rounded.pill}and{rounded.circle}only. - Don't introduce new typefaces into the UI layer beyond Montserrat/Poppins — the custom fonts are template-system artifacts, not interface chrome.
- Don't place
{colors.muted}text on{colors.accent}(coral) backgrounds — always use{colors.on-accent}(#26282b) for sufficient contrast. - Don't collapse the hero's 110px bottom padding (
{spacing.hero}) — this breathing room between nav and content is structurally important. - Don't make the chat widget coral-colored — its blue (
{colors.info}) differentiation prevents confusion with primary CTAs. - Don't use letter-spacing beyond -0.03em (stat numbers) or +0.02em (labels) — the system avoids wide-tracking aesthetics.
- Don't promote the stats-band photo+number layout to a generic repeating pattern — it's a signature one-time moment, not a grid system.
Motion & Animation
Transition Tokens
--transition-default: all 0.15s ease-in-out;
--transition-color: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
--transition-focus: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
--transition-linear: 0.2s linear;
--transition-shadow: box-shadow 0.5s;
The system's motion vocabulary is deliberately conservative — the longest explicit transition is 500ms (shadow changes only), with most interactions resolving in 150ms. The ease-in-out easing dominates, producing gentle acceleration-deceleration curves that feel "soft" rather than snappy or mechanical. Color transitions bundle background, border, and text color into a single coordinated 150ms sweep, preventing jarring intermediate states during hover/focus interactions.
Keyframe Animations
Several keyframe animations were detected in the extracted CSS, though many originate from framework utilities (Bootstrap spinner/skeleton animations) rather than brand-specific motion design:
progress-bar-stripes— Striped progress bar animation (Bootstrap utility, likely unused in visible landing page).spinner-border/spinner-grow— Loading spinners (framework-provided for async states).b-skeleton-animate-wave/b-skeleton-animate-fade/b-skeleton-animate-throb— Content placeholder skeleton animations (loading states).shine— Highlight shimmer effect, potentially used on CTA buttons or premium badges.shimmer-data-v-1d573b8e— Component-scoped shimmer animation (Vue/Nuxt scoped style artifact).blink— Simple opacity blink, possibly for notification dots or live indicators.target-highlight— Brief flash animation for drawing attention to updated elements.- Icon animation variants (
b-icon-animation-cylon,-spin,-throb,-fade) — Decorative motion for icon elements.
Interaction Patterns
Based on the extracted transition data and observable UI patterns:
- Button color shifts: All buttons transition background, text, border, and shadow simultaneously over 150ms
ease-in-out— no transform (scale/translate) was detected on button hover. - Focus ring emergence: Form inputs and focusable elements grow border-color definition and optional shadow over 150ms, using the
{extensions.transitions.focus}token. - Shadow depth change: Elevated surfaces (cards, modals, chat widget) can transition shadow intensity over 500ms (
{extensions.transitions.shadow}) — significantly slower than color changes, creating a "settling" feel. - Chat widget: Likely uses fixed positioning with potential slide-up entrance animation (not explicitly captured in CSS transitions — may be JS-driven).
- Skeleton loading: Content placeholders use wave/fade/throb animations during async data fetch, indicating the platform handles template loading states with motion feedback.
- Scroll-triggered reveals: While no explicit scroll libraries were detected, the stats band and portfolio grid are candidates for fade-up-on-scroll behavior common in landing pages (recommend implementing via Intersection Observer).
No parallax, marquee, or complex gesture-driven animations were detected in the extracted styles. The motion level is firmly subtle per the extensions classification.
Imagery Style
- Photography: Romantic lifestyle photography featuring couples (embrace pose visible in tablet mockup), bridal details (back-of-head shot with updo in stats section), and floral still-life (white peonies/flowers as decorative overlay).
- Color treatment: Images lean warm and slightly desaturated — skin tones are natural, whites are creamy rather than clinical, and overall saturation sits below "vibrant" to let UI elements command attention.
- Depth of field: Shallow focus (bokeh) used strategically — the bride photo blurs the background to isolate the subject; floral decorations are crisply focused to create foreground layering against softer device mockups.
- Subject matter: Exclusively wedding-adjacent — couples in affectionate poses, invitation physical artifacts (envelopes, paper textures implied in templates), flowers (peonies suggest luxury/elegance), and device screens showing the product in use.
- Composition role: Imagery supports rather than dominates — the hero's device mockups occupy roughly 55% of visual weight but serve as product demonstration, not abstract art. The stats photo is a narrow vertical slice balancing the large numeral.
- Integration method: Photos are treated as layered elements (absolute positioning, overlap with UI containers) rather than self-contained image cards — the floral decoration breaks out of the device frame boundary, creating collage-like depth.
- Aspect ratios: Portrait orientation for human subjects (2:3 or 3:4), landscape for device screenshots matching hardware proportions, square or slight rectangle for portfolio thumbnails.
- Cropping style: Natural, unforced compositions — no extreme close-ups or abstract crops. Images feel like authentic wedding documentation rather than stock photography.
- Illustration: None detected — the system relies entirely on photography and UI rendering (device mockups showing actual interface screens).
- Treatment consistency: No filters, duotones, or heavy post-processing observed on images — the warmth comes from color grading, not artificial tinting.
Icon System
- Library: Custom SVG icons (no Lucide, Heroicons, Material, or Font Awesome classes detected in the extraction). Icons appear to be inline SVGs or custom font glyphs.
- Specific icons observed:
- ♥ Heart (logo mark, coral-filled)
- Facebook "f" (circle-contained)
- Instagram camera (circle-contained)
- WhatsApp phone-in-bubble (circle-contained)
- Phone handset (circle-contained)
- Dropdown caret/triangle (▾ next to "Lainnya")
- Chat bubble (in floating widget)
- Close/dismiss X (implied on chat or modals)
- Treatment: Stroke-style icons for social platforms (outlined, not filled), fill-style for the heart logo mark. Social icons render in
{colors.muted}(gray) at rest, shifting to{colors.secondary}(red-pink) on hover per{component.social-icon-circle-hover}. - Size: Social icon containers are 44×44px (
{component.social-icon-circle}.size), with the icon glyph itself occupying approximately 20-24px within the circle. Navigation icons (caret) are smaller (~10-12px). The chat icon matches{typography.button}proportions relative to its label. - Alignment: Social icons are center-aligned within their circular containers. Nav icons (caret) align baseline with adjacent text. Chat icon precedes its label with inline-flex alignment.
- Stroke weight: Appears consistent at 1.5px–2px for outline icons — substantial enough for visibility at small sizes without feeling clumsy.
Recommended Frontend Stack
- Framework: Nuxt.js 3 (Vue meta detected in source; SSR-capable for SEO-heavy landing pages)
- Styling: Tailwind CSS v3 (utility-first matches the atomic token structure; custom config for brand palette)
- Fonts: Google Fonts CDN for Montserrat (weights 400,600,700); self-host custom fonts (/fonts directory)
- Animation: Vue Transition wrapper + CSS custom properties (no heavy GSAP/Framer needed at this subtlety level)
- Icons: Custom SVG component (inline Vue SFC icons matching the detected set)
- Component lib: Headless UI (Nuxt variant) for accessible dropdowns, dialogs, disclosure widgets; or pure custom
- Build: Vite (Nuxt default) with PostCSS for custom font-face declarations
Rationale: The extracted HTML contains window.__NUXT__ initialization, confirming a Nuxt/Vue codebase. Tailwind CSS maps naturally to the atomic spacing/radius/color tokens extracted. The custom font collection requires @font-face declarations in a global CSS layer or Nuxt plugin. Animation complexity is low enough that Vue's built-in <Transition> component + CSS custom properties handle all documented motion without external libraries.
Responsive Behavior
Breakpoints
| Name | Width | Key Changes | |---|---|---| | Mobile | < 640px | Single-column hero (text stacks above mockup); nav collapses to hamburger; stats band stacks vertically (photo above number); chat widget becomes bottom-fixed bar; portfolio grid becomes 1-2 columns | | Tablet | 640px – 1023px | Two-column hero maintained but with reduced mockup size; nav links may truncate or wrap; stats photo narrows; portfolio grid 2-3 columns | | Desktop | 1024px – 1439px | Full asymmetric hero layout restored; all nav items visible; device mockups at designed proportions; stats side-by-side layout active | | Wide | ≥ 1440px | Container max-width engaged (1440px); hero left-offset of 125px active; generous whitespace margins |
Touch Targets
{component.button-primary}: 16px × 26px padding + 15px text ≈ 56px height — exceeds WCAG AAA 44×44 minimum ✓{component.button-outline}: 4.8px × 8px padding + 11px text ≈ 21px height — below 44px minimum, recommend increasing to 36px+ for mobile or wrapping in a larger tap area{component.social-icon-circle}: 44 × 44px (explicit size) — meets WCAG AAA exactly ✓{component.chat-widget}: 12px × 20px padding + 15px text ≈ 44px height — meets minimum ✓- Nav links: 8px × 16px padding + 18px text ≈ 44px height — meets minimum ✓
Collapsing Strategy
- Navigation: At mobile breakpoint, the horizontal nav links (Preset/Desain, Portofolio, Lainnya, Daftar) collapse into a hamburger-menu drawer or bottom sheet. The "Masuk" button remains visible as a persistent header action or moves into the drawer. Logo stays flush-left.
- Hero columns: The asymmetric two-column layout (45% text / 55% mockup) stacks vertically — text column moves above the device mockup, which scales down to roughly 70-80% width and centers. The floral decoration may hide on small screens or reduce opacity to avoid clutter.
- Stats band: The side-by-side photo + number layout stacks with the photograph above (or hidden on very small screens), and the "50.611 Pasangan berbahagia" block centering horizontally. Font size for
{typography.stat-number}may reduce to 36-42px on mobile. - Portfolio grid: Multi-column grid reduces to 2 columns on tablet, 1 column on mobile, with cards expanding to full available width.
- Chat widget: On mobile, the floating button may anchor to bottom-center or bottom-right with a larger tap target (min 56px). The speech bubble ("Ada yang ingin ditanyakan?") may appear as a persistent bottom bar above the button.
- Spacing compression: Vertical rhythm compresses moderately —
{spacing.hero}(110px) likely reduces to 48-64px on mobile;{spacing.section-lg}(25px) reduces to 16-20px.
Image Behavior
- Hero device mockups: Scale down proportionally on tablet; on mobile, the tablet frame may hide (showing only mobile frame) or both frames stack vertically with reduced dimensions. Shadow intensity may decrease on small screens.
- Floral decoration: May become semi-transparent or position-static (flowing in document order rather than absolutely overlaid) to prevent layout disruption on narrow viewports.
- Stats photo: Maintains aspect ratio with
width: 100%; object-fit: coverbehavior, height capped at 300-400px on mobile to prevent the photo from pushing content too far down. - Portfolio thumbnails: Maintain 4:3 or 3:2 aspect ratio with
{rounded.md}corners, scaling to grid column width viaobject-fit: cover.
Iteration Guide
-
Initialize with Nuxt 3 + Tailwind CSS — Set up a Nuxt project with
@nuxtjs/tailwindcssmodule. Define all color, spacing, radius, and typography tokens as Tailwind theme extensions mapping to the YAML frontmatter values exactly. Never hard-code a hex or px value that has a corresponding{token}reference. -
Build the token foundation first — Before writing any component markup, ensure
tailwind.config.ts(or equivalent) declares every token from the frontmatter:colors.primary,colors.accent,colors.signature-rose,typography.display-lg,rounded.md,spacing.hero, etc. Run the dev server and verify token output matches this spec using browser dev tools. -
Implement the navigation bar (
{component.top-nav}) as the first component — It establishes the font family (Montserrat), the canvas baseline ({colors.canvas}), and the nav-link typographic role ({typography.nav-link}at 18px/600). Get the logo lock-left, links center, auth-right layout working before proceeding. -
Construct the hero band (
{component.hero-band}) with its{colors.signature-rose}background and 110px bottom padding — This is the most visually distinctive section. Implement the two-column grid (text left, mockup right) with the left-offset container pattern (125px). Build the dual-tone headline (coral superheadline + navy main headline) using{component.hero-headline-accent}and{component.hero-headline-primary}respectively. -
Wire the primary CTA system — Every
{component.button-primary}instance shares identical styling:{colors.accent}background,{colors.on-accent}text, 12px radius, 16px 26px padding, 15px/600 type. Create a singleBaseButtoncomponent (or Tailwind@applyvariant) and reuse it for "Masuk", "Buat Sekarang Gratis!", and all future conversion points. Add hover/active state classes mapping to{component.button-primary-hover}and{component.button-primary-active}. -
Implement the device mockup layer — Build the overlapping tablet (
{component.device-frame-tablet}, 25px radius,{colors.surface-neutral}bg) and mobile ({component.device-frame-mobile}, 15px radius, white bg) frames. Apply{extensions.shadows.sm}for elevation. Layer the social icon stack ({component.social-icon-circle}, 44px circles, 50% radius) vertically along the left edge. Overlay the floral image as a positioned decorative element ({component.floral-decoration}). -
Build the statistics band (
{component.stats-band}) with the signature large-numeral treatment — The "50.611" number uses{typography.stat-number}(56px/700) in{colors.accent}(coral). Pair it with{component.stat-label}in navy{colors.display-lg}. Place the bride photograph as a left-column element (natural aspect ratio, no rounding). Ensure the band returns to{colors.canvas}white background to create rhythm after the rose hero. -
Add the chat widget (
{component.chat-widget}) as a fixed-position element — Use{colors.info}(blue, NOT coral) for the background to differentiate from primary CTAs. Apply{extensions.shadows.lg}for strong elevation. Include the chat bubble ({component.chat-bubble}) as an adjacent positioned element with the prompt text. -
Implement state variants per-stack convention — For each component with
-hover,-active,-focus, or-disabledvariants in the frontmatter, add the appropriate CSS/Tailwind pseudo-class or data-state styling. Example:.btn-primary:hover { background-color: {colors.accent-hover}; }. Document these additions in your component files. -
Run lint validation — After completing implementation, run
npx @google/design.md lint DESIGN.md(or manual equivalence check) to catch broken token references ({colors.nonexistent}), orphaned tokens (defined but never referenced in components), and contrast-ratio warnings (especially{colors.accent}+{colors.on-accent}pairing). Fix all errors before shipping.
Font Setup: Import Montserrat from Google Fonts in your nuxt.config.ts or layout <head>:
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600;700&family=Poppins:wght@400;600;700&display=swap" rel="stylesheet">
Define CSS variables for the custom decorative fonts (these must be self-hosted from /fonts):
@font-face { font-family: 'amanise'; src: url('/fonts/Amanise.f73e260.ttf') format('truetype'); }
@font-face { font-family: 'honey-carrot'; src: url('/fonts/Honey-Carrot.5d786cf.ttf') format('truetype'); }
@font-face { font-family: 'brittney-signature'; src: url('/fonts/Brittney Signature.80881c0.ttf') format('truetype'); }
/* ... repeat for julietta-messie, malatan, monarda, maxcellent, Roboto variants ... */
Known Gaps
- Hover state specifics: Per the no-hover policy, exact hover color transitions (interpolation stops, timing function nuances) for buttons, links, and cards are inferred from the transition tokens but not visually verified from the static screenshot.
- Loading skeletons: While skeleton animation keyframes were detected in CSS (
b-skeleton-animate-*), the exact visual appearance (gradient direction, pulse timing, bone shapes) of loading placeholder states for invitation templates, portfolio images, or async data is not depicted in the screenshot. - Form validation states: Beyond the generic focus-border transition, error-message styling (icon + text color + placement), success checkmarks, and disabled-input appearance for the email/name fields implied by the "Daftar" flow are not extractable.
- Authenticated/dashboard surfaces: The screenshot shows only the public landing page. Internal dashboards (invitation editor analytics, guestbook management, template customization UI) likely have additional component patterns, density variations, and potentially sidebar navigation not represented here.
- Dropdown menu rendering: The "Lainnya ▾" dropdown trigger implies a menu panel, but its contents, dimensions, shadow elevation, and item styling are not visible in the static capture.
- Mobile navigation drawer: The collapsed mobile nav (hamburger state) structure, animation (slide-from-right vs. bottom-sheet), and item layout are inferred from breakpoint strategy but not observed.
- Dark mode: The entire system is documented in light mode (
{extensions.mode}: "light"). No dark-mode token equivalents, inversion rules, or toggle mechanism were detectable. A dark theme would require new surface/text pairings and possibly adjusted accent saturations. - Internationalization (i18n) layout: The site serves Bahasa Indonesia content but the design system doesn't document how longer translated strings affect nav width, button sizing, or headline wrapping (Indonesian words can be significantly longer than English equivalents).
- Accessibility (a11y) testing: While touch targets and contrast ratios are annotated where calculable, formal screen-reader testing, keyboard-navigation flow, and focus-visible indicator styling are not verified from static extraction alone.
- Pixel-exact surface colors: The
{colors.signature-rose}(#fbeced) and{colors.accent}(#ffa0ae) values are derived from CSS rgb() conversions; subtle monitor calibration differences or CSS filter operations not visible in the DOM snapshot could shift perceived hue slightly.