Model Management Design System
Overview
Model Management presents a bold, photography-first marketplace experience built on high-contrast dark-mode foundations. The design language trusts full-bleed model portraiture to carry emotional weight while keeping UI chrome minimal and intentionally recessed. Near-black surfaces ({colors.surface} / #1d1d1f) dominate the viewport, allowing crisp white typography ({colors.ink} / #ffffff) to pop with editorial clarity. The system deploys electric blue ({colors.primary} / #75c1fb) sparingly—as link accents and subtle interactive hints—while reserving a vivid magenta ({colors.signature-magenta}) exclusively for conversion-carrying CTAs.
Typography hinges on Montserrat across every role, with a decisive binary weight strategy: 700 for anything demanding attention (headlines, labels, buttons, navigation items) and 400 for reading copy (body text, descriptions, legal prose). There is no intermediate weight—the system chooses impact or neutrality. Size carries hierarchical signal more than weight does: display text scales to 36–48px while body settles at a generous 18px, ensuring readability even against complex photographic backgrounds.
Shape language splits cleanly along functional lines: pill-shaped containers (160px radius) for all interactive elements—buttons, nav pills, filter tags—signaling tappability through extreme roundness. Card containers use 24px radius, soft enough to feel contemporary without dissolving into ambiguity. Avatars and icon circles go fully round (50%). This dual-radius vocabulary lets users instantly distinguish actionable chrome from content containers.
The layout breathes with 64–96px vertical rhythm between major sections, while cards maintain tight internal spacing (24–32px) that keeps overlaid text feeling anchored to imagery. A subtle shadow stack ({extensions.shadows.md}) lifts the privacy modal and elevated surfaces just enough to separate them from the background plane without breaking the dark-atmosphere immersion.
Key Characteristics:
- Dark-first canvas with
{colors.surface}(#1d1d1f) as the dominant container background and{colors.canvas}(#f2f2f2) reserved for outer page shells - Magenta CTAs (
{colors.signature-magenta}) as the sole conversion color, never used for non-actionable elements - Electric blue links (
{colors.link}/ #75c1fb) providing the only non-white/non-black text color in the system - Pill-radius ({rounded.pill} / 160px) on every button and nav item; {rounded.lg} / 24px on content cards
- Montserrat 700 for all headings, labels, and buttons; Montserrat 400 exclusively for body copy
- 18px minimum body size ensuring legibility over photographic backgrounds
- Shadow elevation limited to two tiers: subtle ({extensions.shadows.sm}) for hover states, moderate ({extensions.shadows.md}) for modals
- 300ms ease-in-out transitions governing all state changes
Colors
Brand & Accent
- Primary (
{colors.primary}— #75c1fb): Electric blue reserved for text links, focus indicators, and accent highlights. Never used as a solid background fill on this page. - Primary Hover (
{colors.primary-hover}— #5bb3f9): Slightly deepened blue for link hover states. - Primary Active (
{colors.primary-active}— #419ef7): Pressed-state blue for interactive text elements. - Signature Magenta (
{colors.signature-magenta}— #e83a7b): High-voltage magenta-pink used exclusively on primary CTA buttons (Sign up, Accept All, For models and talents, For professionals). This is the conversion color—it appears nowhere else in the interface. - Signature Magenta Hover (
{colors.signature-magenta-hover}— #d62a6a): Darkened magenta for button hover states. - Signature Magenta Active (
{colors.signature-magenta-active}— #c41d5a): Deepest magenta for pressed/active button states.
Surface
- Canvas (
{colors.canvas}— #f2f2f2): Light gray serving as the outermost page background behind the main content area. Visible at viewport edges. - Surface (
{colors.surface}— #1d1d1f): Near-black default surface for navigation bars, card containers, and the primary content layer. - Surface Soft (
{colors.surface-soft}— #1d1d1f): Identical to Surface in current implementation; reserved for future lighter-dark variants. - Surface Strong (
{colors.surface-strong}— #2c2c2e): Slightly lifted dark gray for hero card backgrounds, providing subtle differentiation from the deepest black. - Surface Elevated (
{colors.surface-elevated}— #ffffff): Pure white reserved for the Privacy Settings modal and any overlay dialogs requiring maximum contrast. - Surface Dark (
{colors.surface-dark}— #141416): Deepest black available for potential deepest-layer backgrounds or extreme contrast needs.
Text
- Ink (
{colors.ink}— #ffffff): Primary text color on all dark surfaces. Used for headings, body copy, and UI labels against{colors.surface}and darker. - Body (
{colors.body}— #1d1d1f): Near-black text for content appearing on light surfaces (modal body, canvas-level text). - Body Inverse (
{colors.body-inverse}— #ffffff): Alias for white text on dark backgrounds; semantically distinct for light/dark context switching. - Muted (
{colors.muted}— rgba(255, 255, 255, 0.7)): Secondary text at 70% white opacity—supporting descriptions, timestamps, metadata. - Muted Soft (
{colors.muted-soft}— rgba(255, 255, 255, 0.5)): Tertiary text at 50% opacity—legal lines, attribution, "Powered by" footers. - On Primary (
{colors.on-primary}— #ffffff): Text color for any element rendered atop{colors.primary}or{colors.signature-magenta}backgrounds. Always white for AA contrast. - On Dark (
{colors.on-dark}— #ffffff): White text guaranteed readable on any dark surface variant. - On Surface (
{colors.on-surface}— #1d1d1f): Dark text for elevated/whtie surfaces like{component.modal}. - On Canvas (
{colors.on-canvas}— #1d1d1f): Dark text for{colors.canvas}-background areas.
Hairlines & Borders
- Hairline (
{colors.hairline}— rgba(255, 255, 255, 0.12)): Default divider and border color on dark surfaces—subtle white at 12% opacity. - Hairline Soft (
{colors.hairline-soft}— rgba(255, 255, 255, 0.08)): Barely-visible borders for extremely subdued separation (8% opacity). - Border Strong (
{colors.border-strong}— rgba(255, 255, 255, 0.2)): Emphasized borders at 20% opacity for input focus rings or highlighted containers.
Semantic
- Link (
{colors.link}— #75c1bf): Interactive text color matching Primary; used for "change my consent" and navigational anchors. - Link Active (
{colors.link-active}— #5bb3f9): Link hover/active state, slightly deepened. - Error (
{colors.error}— #ff4757): Red for validation errors and destructive actions (inferred from standard semantic palette). - Success (
{colors.success}— #2ed573): Green for confirmations and positive status (inferred).
Typography
Font Family
The entire system runs on Montserrat, a geometric sans-serif with strong humanist influences and excellent readability at both display and body sizes. The font-face declarations load WOFF2 and WOFF formats with font-display: swap, covering Latin Extended, Latin, Cyrillic Extended, and Cyrillic character sets—essential for a global modeling platform. The fallback stack degrades gracefully through Lucida Grande → Lucida Sans Unicode → DejaVu Sans → Verdana → system sans-serif. Montserrat is proprietary (Google Fonts hosted via self-hosted WOFF2 in this Nuxt deployment) and carries a distinctive personality: circular bowls, tall x-height, and a slightly condensed proportion that packs density into headlines without sacrificing clarity.
A single typeface serves every role—there is no serif pairing, no monospace exception, no display face swap. The system achieves hierarchy purely through size (36–48px vs 18px vs 14px), weight (700 vs 400), and color (white vs muted vs accent blue). This mono-family approach creates strong visual cohesion across a page that already battles complexity through layered photography.
Hierarchy
| Token | Size | Weight | Line Height | Letter Spacing | Use |
|---|---|---|---|---|---|
| {typography.display-xl} | 48px | 700 | 1.15 (-0.02em) | -0.02em | Hero-level headlines (future use); largest display |
| {typography.display-lg} | 36px | 700 | 1.11 | 0 | Hero card titles ("Find work as a model"), section headings |
| {typography.title-md} | 36px | 700 | 1.11 | 0 | Alternate title role at same spec as display-lg |
| {typography.title-sm} | 18px | 700 | 1.17 | 0 | Modal headers ("Privacy Settings"), card subtitles |
| {typography.body-lg} | 18px | 400 | 1.33 | 0 | Hero card descriptive text, body copy on dark |
| {typography.body-md} | 18px | 400 | 1.33 | 0 | Modal body text, paragraph content |
| {typography.body-sm} | 14px | 400 | 1.43 | 0 | Secondary supporting text, metadata |
| {typography.caption} | 13px | 400 | 1.38 | 0 | Legal fine print, "Powered by" attribution |
| {typography.button} | 14px | 700 | 1.25 | 0 | All button labels, nav items, CTAs |
| {typography.label-md} | 14px | 700 | 1.4 | 0 | Form labels, small UI badges |
Principles
The typography system enforces a binary weight discipline: 700 for anything that competes for attention (headlines, buttons, navigation labels, form labels) and 400 for everything meant to be consumed passively (paragraphs, descriptions, disclaimers). There are no 500, 600, or intermediate weights in the loaded font faces, and the design deliberately avoids them. When emphasis is needed within body copy, the system relies on color shifts (white → {colors.muted} → {colors.link}) rather than weight changes.
Size provides the primary hierarchical signal. The jump from 18px body to 36px headline is exactly 2×—a confident ratio that ensures headlines command the photographic backgrounds they overlay. Letter spacing remains at normal (0) for almost all roles, except {typography.display-xl} which applies -0.02em to tighten large display text slightly. Line heights are relatively tight (1.11–1.33 range), reflecting Montserrat's natural proportions and the design's density-over-airs preference.
Uppercase is absent from the extracted styles—all text renders in sentence case. Italics are available in the loaded font faces (Montserrat Italic 400 and 700 are declared) but don't appear in the above-fold UI; they're reserved for potential editorial or legal contexts.
Note on Font Substitutes
Montserrat is freely available on Google Fonts. For implementations unable to self-host, substitute via:
:root {
--font-family-base: 'Montserrat', 'Lucida Grande', 'Lucida Sans Unicode', 'DejaVu Sans', Verdana, sans-serif;
}
Google Fonts CDN link: <link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&display=swap" rel="stylesheet">
If Montserrat cannot be loaded, the fallback stack degrades gracefully through system fonts that share geometric-sans characteristics. Avoid substituting with humanist faces (Open Sans, Lato) or grotesques (Inter, Roboto) as they alter the brand's circular, slightly-condensed voice significantly.
Layout
Spacing System
-
Base unit: 4px (with 6px appearing frequently for compact UI elements).
-
Tokens:
{spacing.xxs}(4px): Micro-adjustments, internal icon padding.{spacing.xs}(6px): Button vertical padding, compact gaps, nav item internal spacing.{spacing.sm}(8px): Tight inline gaps between related elements.{spacing.md}(16px): Most common spacing—grid gutters, card internal margins, text-to-edge padding.{spacing.lg}(24px): Card internal padding, section sub-spacing, modal padding supplement.{spacing.xl}(32px): Modal total padding, larger card internals.{spacing.xxl}(40px): Section-internal breathing room.{spacing.section}(64px): Vertical rhythm between major page sections (hero → "More than models").{spacing.section-xl}(96px): Major sectional breaks (observed twice in layout).{spacing.component-lg}(216px): Fixed dimension for hero card heights or sidebar widths.{spacing.max-content}(672px): Max-width constraint for text-heavy content columns.{spacing.sidebar}(272px): Potential rail or aside width.
-
Section padding (vertical):
{spacing.section}(64px) — used between the hero card grid and the "More than models" heading band. -
Card internal padding: Hero cards (
{component.hero-card}) use 0 explicit padding (content overlays sit absolutely), while{component.modal}uses{spacing.xl}(32px) on all sides. -
Gutters: Grid gutters appear to be
{spacing.md}(16px) to{spacing.lg}(24px) based on spacing frequency data.
Grid & Container
- Max content width: 1440px (extracted from section container).
- Density choice: Editorial-marketplace hybrid—the hero presents two large feature cards side-by-side (roughly 50/50 split within the container), while the underlying page structure accommodates denser grid content below.
- Desktop grid behavior: The hero section uses a 2-column equal-width layout for the paired model showcase cards. Content below likely transitions to a 3–4 column grid for model cards or casting listings (inferred from marketplace patterns).
- Hero column split: Two equal columns, each containing one
{component.hero-card}with full-bleed imagery, gradient overlay, and bottom-aligned text + CTA.
Whitespace Philosophy
The system employs generous vertical rhythm (64–96px between sections) combined with tight internal card spacing. This creates a "poster-frame" effect where each content block feels like a curated composition with breathing room around it, but dense information within. The dark background amplifies perceived space—whitespace reads as void rather than empty paper, giving the layout a cinematic, gallery-like quality.
Header Architecture
┌─────────────────────────────────────────────────────────────────┐
│ [model logo] Home Castings Models Pro dir Marketplace [Log in] [Sign up] ≡ │
│ ───── active pill ──────────────────────────── │
└─────────────────────────────────────────────────────────────────┘
↑ 1440px max-width container centered
Flush-left logo mark ("model management.com"), center-weighted navigation with {component.nav-link-active} pill on "Home", flush-right utility cluster: {component.button-secondary} (Log in), {component.button-primary} (Sign up), {component.hamburger-icon}. Total nav height: 64px. Background: {colors.surface} (#1d1d1f). The active nav item receives a subtle white-at-10% background highlight.
Hero Section
┌────────────────────────────────┬────────────────────────────────┐
│ │ │
│ ┌──────────────────────────┐ │ ┌──────────────────────────┐ │
│ │ │ │ │ │ │
│ │ MODEL PHOTOGRAPH │ │ │ MODEL PHOTOGRAPH │ │
│ │ (full-bleed) │ │ │ (full-bleed) │ │
│ │ │ │ │ │ │
│ │ ┌──────────────────┐ │ │ │ ┌──────────────────┐ │ │
│ │ │ Find work as a │ │ │ │ │ Find models and │ │ │
│ │ │ model │ │ │ │ │ talents │ │ │
│ │ │ Modeling jobs.. │ │ │ │ │ Source models... │ │ │
│ │ │ │ │ │ │ │ │ │ │
│ │ │ [For models..] │ │ │ │ │ [For profess..] │ │ │
│ │ └──────────────────┘ │ │ │ └──────────────────┘ │ │
│ └──────────────────────────┘ │ └──────────────────────────┘ │
│ │ │
└────────────────────────────────┴────────────────────────────────┘
↑ Hero Card 1 (left) ↑ Hero Card 2 (right)
↑ {component.hero-card} × 2 ↑ 24px border radius
Gradient overlay bottom 60%
Two {component.hero-card} instances sit side-by-side with {spacing.md} to {spacing.lg} gap. Each card contains:
- Full-bleed model photography (aspect ratio ~4:3 or 3:2 portrait)
{component.hero-card-overlay}— gradient from opaque black (bottom) to transparent (top, 60% up)- Bottom-aligned text block:
{typography.display-lg}headline,{typography.body-lg}subheadline {component.hero-card-cta}— pill button with{colors.signature-magenta}background
Privacy Modal (Overlay)
┌──────────────────────────────────────────────────┐
│ │
│ Privacy Settings 🌐 │
│ │
│ This site uses third-party website tracking │
│ technologies to provide and continually │
│ improve our services, and to display │
│ advertisements according to users' interests. │
│ I agree and may revoke or change my consent │
│ at any time with effect for the future. │
│ │
│ ┌──────────────────────────────────────────┐ │
│ │ Accept All │ │
│ └──────────────────────────────────────────┘ │
│ │
│ Powered by Usercentrics Consent Mgmt │
│ │
└──────────────────────────────────────────────────┘
↑ {component.modal}
↑ White surface, 24px radius, 32px pad
↑ Shadow: {extensions.shadows.md}
Centered overlay with {component.modal-overlay} (60% black) backdrop. Modal uses {colors.surface-elevated} (white) background with {colors.on-surface} (#1d1d1f) text—a rare inversion of the dark theme for legibility and attention-capture. The {component.button-accept-all} spans full width with {colors.signature-magenta} fill. A globe icon ({component.globe-icon}) sits top-right for language selection.
Elevation & Depth
| Level | Treatment | Use |
|---|---|---|
| 0 – Flat | No shadow, {colors.surface} background | Base page shell, nav bar, hero cards |
| 1 – Subtle | {extensions.shadows.sm} — 6% black dual-shadow | Button hover lifts, subtle card elevation |
| 2 – Modal | {extensions.shadows.md} — 12% black dual-shadow | Privacy dialog, dropdown panels |
| 3 – Focus ring | {colors.border-strong} (20% white) outline | Input focus states, keyboard navigation |
Philosophy: The system favors color-block layering over shadow depth for most elevation needs. Dark surfaces naturally recede; white or lighter surfaces advance. Shadows appear only when an element must physically "lift" off the plane—primarily the modal and hover states. The shadow stacks use dual-offset construction (a close blur + a farther drop shadow) creating a soft, diffuse edge rather than a hard cast. Both shadow tiers are neutral-cooled (pure black at reduced opacity), avoiding the warm-toned shadows that would clash with the cool-dark atmosphere.
Decorative Depth
Beyond mechanical elevation, the system employs gradient overlays as decorative depth on {component.hero-card} instances. A linear gradient runs from rgba(29, 29, 31, 0.95) at the bottom edge to rgba(29, 29, 31, 0.4) at 60% height to transparent at the top. This ensures text legibility over arbitrary photography while maintaining the illusion that imagery extends behind the content. The gradient is part of the {component.hero-card-overlay} component definition.
Shapes
Border Radius Scale
| Token | Value | Use |
|---|---|---|
| {rounded.xs} | 6px | Small internal elements, badge corners |
| {rounded.DEFAULT} | 12px | Default container rounding (unused in current view, available) |
| {rounded.md} | 16px | Medium containers, input fields |
| {rounded.lg} | 24px | Hero cards, modal container, content panels |
| {rounded.xl} | 32px | Large feature panels (potential) |
| {rounded.pill} | 160px | All buttons, navigation pills, CTAs—fully capsule-shaped |
| {rounded.full} | 50% | Avatar circles, icon containers |
Photography Geometry
Images in the hero cards render full-bleed within their {rounded.lg} (24px) containers, with overflow hidden to clip to the rounded rectangle. Aspect ratio appears to be approximately 3:4 (portrait) or 4:5, optimized for model headshots and full-body fashion photography. No border, no inset shadow, no frame—imagery touches the container edge directly. On mobile, these cards likely stack vertically and may shift to 1:1 or 16:9 aspect ratios to fit narrower viewports.
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.top-nav} — The persistent header bar anchoring the entire page. Background {colors.surface} (#1d1d1f), height 64px, spanning full viewport width with content constrained to 1440px. Contains {component.logo-mark}, {component.nav-link} items, {component.button-secondary}, {component.button-primary}, and {component.hamburger-icon}. No visible border-bottom; separation from content comes from background-color change alone.
{component.nav-link} — Navigation menu items (Home, Castings, Models, Pro directory, Marketplace). Transparent background, white text ({typography.button} — 14px/700), pill shape ({rounded.pill} / 160px), padding 6px horizontal 17.5px vertical. These are subtly interactive with hover darkening. The "Home" item renders as {component.nav-link-active} with a 10% white background tint indicating current page.
{component.nav-link-active} — Current-page indicator variant of {component.nav-link}. Adds backgroundColor: "rgba(255, 255, 255, 0.1)" to create a subtle filled-pill appearance without full inversion. Same typography and dimensions as default state.
{component.button-primary} — The principal conversion button (Sign up in nav, Accept All in modal). Background {colors.signature-magenta} (#e83a7b), white text ({typography.button} — 14px/700), pill radius ({rounded.pill}), padding 6px 17.5px. Carries {extensions.shadows.sm} on the nav Sign up variant for slight lift. This is the single most important interactive element in the system—its magenta color is reserved exclusively for action-taking.
{component.button-primary-hover} — Hover state deepening to {colors.signature-magenta-hover} (#d62a6a). Same dimensions and radius.
{component.button-primary-active} — Pressed/active state at {colors.signature-magenta-active} (#c41d5a), darkest magenta in the scale.
{component.button-secondary} — Secondary action button (Log in). Background {colors.canvas} (#f2f2f2)—a light gray island in the dark nav—text {colors.body} (#1d1d1f), pill shape, same padding as primary. No shadow (is-shadowless class). Provides visual hierarchy below primary without competing for attention.
{component.button-secondary-hover} — Hover state lightens background slightly to #e6e6e6.
{component.button-secondary-active} — Active state at #d9d9d9 background.
{component.button-ghost} — Transparent-background button variant with white text. Used for tertiary actions where neither primary nor secondary weight is appropriate. Same pill geometry as other buttons.
{component.button-accept-all} — Full-width modal CTA. Background {colors.signature-magenta}, white text, {typography.button}, {rounded.DEFAULT} (24px—slightly less rounded than nav buttons to fill width gracefully), padding 14px 24px. Dominates the modal footer visually.
{component.button-accept-all-hover} — Hover at {colors.signature-magenta-hover}.
{component.button-accept-all-active} — Active/pressed at {colors.signature-magenta-active}.
{component.hero-card-cta} — Inline card action button ("For models and talents", "For professionals"). Background {colors.signature-magenta}, white text, {typography.button}, {rounded.pill}, padding 10px 20px. Sits at the bottom of each hero card's text overlay, acting as the card's conversion point. Appears to have no shadow, blending into the card's gradient overlay.
{component.hero-card-cta-hover} — Hover variant at {colors.signature-magenta-hover}.
Cards & Containers
{component.hero-card} — The dominant visual component of the above-fold experience. Background {colors.surface-strong} (#2c2c2e), {rounded.lg} (24px), no internal padding (children position absolute). Contains full-bleed <img>, {component.hero-card-overlay} gradient, and bottom-aligned text+CTA cluster. Dimensions roughly 50% of container width minus gap; height appears fixed around 400–500px. These cards are the system's "signature moment"—where photography, typography, and color converge.
{component.hero-card-overlay} — Linear gradient layer positioned absolute over the bottom 60% of {component.hero-card}. Transitions from 95% opaque #1d1d1f at bottom edge → 40% at midpoint → 0% (transparent) at 60% height. Ensures white headline and body text remain legible regardless of photograph brightness. Rounded to match parent card (24px clip).
{component.hero-card-title} — Headline text within the card overlay ("Find work as a model", "Find models and talents"). Uses {typography.display-lg} (36px/700), white color, positioned bottom-left area of card with margin from edge.
{component.hero-card-body} — Supporting description under the title ("Modeling jobs for newcomers and professional models"). Uses {typography.body-lg} (18px/400), {colors.muted} (70% white), providing context without competing with headline.
{component.modal} — Centered dialog box for Privacy Settings. Background {colors.surface-elevated} (white)—the only white surface in the dark-theme page—text color {colors.on-surface} (#1d1d1f), {rounded.lg} (24px), padding {spacing.xl} (32px) all sides, max-width ~560px. Elevated with {extensions.shadows.md} (12% black dual-shadow). Contains header, body, footer stacked vertically.
{component.modal-header} — "Privacy Settings" title row. {typography.title-sm} (18px/700), dark text, with {component.globe-icon} aligned right for language toggle.
{component.modal-body} — Legal consent prose paragraph. {typography.body-md} (18px/400), {colors.body} (#1d1d1f), comfortable line length (~70 chars). Contains one inline {component.consent-link} ("change my consent").
{component.modal-footer} — Bottom area holding {component.button-accept-all} and {component.powered-by-text}. Vertical stacking with gap ~16px.
{component.modal-overlay} — Full-viewport backdrop behind {component.modal}. Background rgba(0, 0, 0, 0.6) — 60% black—creating dimming effect that focuses attention on the modal.
Inputs & Forms
No text inputs or form fields were visible in the above-fold screenshot. The login/signup flows (which presumably contain email/password inputs) are likely accessed after clicking {component.button-secondary} or {component.button-primary} in the nav.
Navigation
{component.logo-mark} — "model management.com" wordmark in the nav's left slot. White text, likely custom SVG or styled text. Sits at the visual start of the {component.top-nav} flex row.
{component.hamburger-icon} — Three-line menu icon at the far right of the nav (outside the Log in / Sign up cluster). Color {colors.body} (#1d1d1f)—note this renders as dark on dark surface, suggesting it may invert on scroll or the nav background is actually lighter than expected in this region, or the icon uses an explicit lighter color not captured. Size 24px × 24px.
{component.icon-button} — Generic icon-only button template. Transparent background, inherit text color, 24px × 24px hit area. Used for hamburger, globe, and potential close/back icons.
{component.globe-icon} — Language selector icon in modal header-top-right. 20px size, {colors.body} color (dark on white modal). Opens a language picker (not shown).
Text & Link Components
{component.section-heading} — Large section title below the hero ("More than models"). {typography.display-lg} (36px/700), {colors.body} (#1d1d1f)—notably dark text suggesting this heading sits on the {colors.canvas} (light gray) background area below the dark hero section.
{component.section-subheading} — Supporting paragraph under section headings. {typography.body-md}, {colors.muted} tone.
{component.link-accent} — Standard inline link using {colors.link} (#75c1fb) electric blue. Underlined on hover (implied). Used for "change my consent" and potentially other contextual links.
{component.link-accent-hover} — Link hover state at {colors.link-active} (#5bb3f9).
{component.consent-link} — Specifically the "change my consent" underline link inside the modal body text. Inherits {typography.body-md}, colored {colors.link}, with explicit text-decoration: underline.
{component.powered-by-text} — "Powered by Usercentrics Consent Management" attribution line. {typography.caption} (13px/400), {colors.muted-soft} (50% white—or dark gray in modal context). Small, unobtrusive legal attribution.
Do's and Don'ts
Do
- Do reserve
{colors.signature-magenta}exclusively for primary conversion actions. Every magenta element on the page should be tappable and should advance the user toward signup, acceptance, or another business-critical goal. Using it for decoration or non-interactive labels dilutes its power. - Do apply
{rounded.pill}(160px) to every button and nav item. The capsule shape is the universal signifier of interactivity in this system. Non-interactive elements (cards, panels) use{rounded.lg}(24px) or smaller—never pill. - Do maintain the 700/400 binary weight split across all typography. If text competes for attention (headings, buttons, labels), use
{typography.button}or{typography.title-sm}weight 700. If text is meant to be read continuously (body paragraphs, descriptions), use{typography.body-md}weight 400. No intermediate weights exist in the font loading. - Do place white text (
{colors.ink}) on{colors.surface}or darker, and dark text ({colors.body}or{colors.on-surface}) on{colors.surface-elevated}or lighter. The modal correctly inverts to dark-on-white; follow this pattern for any future elevated surfaces. - Do use
{colors.link}(#75c1fb) for inline navigation links, and always provide a hover state at{colors.link-active}. Blue links are the only non-white, non-black text color outside of CTAs—they signal "this goes elsewhere" without demanding action. - Do apply the gradient overlay pattern (
{component.hero-card-overlay}) whenever text sits on top of photography. The three-stop gradient (opaque → semi-transparent → transparent) ensures legibility across any image brightness while maintaining visual continuity. - Do keep section vertical spacing at
{spacing.section}(64px) or{spacing.section-xl}(96px) between major content blocks. The dark theme needs this rhythmic breathing room to avoid feeling cramped or oppressive. - Do limit shadow usage to the two defined tiers:
{extensions.shadows.sm}for hover lifts and{extensions.shadows.md}for modals. Over-shadowing in a dark theme creates muddy, indistinct edges—let color contrast carry most of the elevation work. - Do set
min-height: 44pxon all button variants to meet WCAG AAA touch target guidelines. Current button padding (6px vertical + 14px font + borders) yields ~32px height—consider increasing to 44px for accessibility compliance. - Do use Montserrat's native letter-spacing (normal/0) for all roles except
{typography.display-xl}which applies -0.02em. Artificially expanding or compressing letter-spacing fights the typeface's designed proportions.
Don't
- Don't use
{colors.signature-magenta}as a background for non-button elements. Cards, panels, tags, or dividers should never be magenta—it's exclusively a CTA fill color. Use{colors.primary}blue for accent backgrounds if needed, or stick to surface grays. - Don't apply
{rounded.pill}to content containers like cards or modals. Pill shapes signal "tap me"; rounded rectangles (24px) signal "read me." Confusing the two harms usability. - Don't introduce a new font family for any purpose. Montserrat handles every role from 48px display to 13px caption. Adding a serif or monospace face breaks the cohesive geometric-sans voice.
- Don't place white text directly on mid-tone photography without an overlay. The gradient system exists for a reason—unprotected text becomes illegible on bright or busy images.
- Don't exceed two levels of nested shadow or combine shadows with heavy border treatments. The defined shadow stacks are sufficient; adding more creates a "floating too high" effect that disconnects elements from the surface plane.
- Don't use
{colors.muted-soft}(50% opacity) for body copy or any text longer than 10 words. That opacity level fails WCAG AA contrast requirements against dark backgrounds—reserve it for truly optional/attribution text like "Powered by...". - Don't make the nav shorter than 64px or the logo smaller than its natural size. The header establishes the vertical rhythm for the entire page; shrinking it makes the content below feel cramped.
- Don't apply transitions faster than 150ms or slower than 400ms for standard interactions. The extracted timing centers on 300ms (
ease-in-out)—deviating significantly makes the interface feel either sluggish or twitchy. - Don't forget to implement
{component.modal-overlay}backdrop when rendering any modal or drawer. Without the 60% black dimming, modals fail to create proper focal isolation and feel disconnected from the layer beneath. - Don't use
{colors.canvas}(#f2f2f2) as a card or panel background within the dark-themed content area. The light gray is reserved for the outer page shell—inner surfaces stay in the #1d1d1f–#2c2c2e range unless elevating to white for a modal.
Motion & Animation
Transition Tokens
--transition-base: all 0.3s ease-in-out;
--transition-color: color 0.3s ease-in-out, background-color 0.3s ease-in-out;
--transition-filter: filter 0.3s ease-in-out;
--transition-opacity: opacity 0.3s ease-in;
--transform: transform 0.3s ease-in-out;
--transition-quick: 0.15s ease-in-out;
The dominant transition duration across the extracted stylesheet is 300ms with ease-in-out timing. This applies to color changes (button background shifts, link hovers), opacity fades (modal appearance, tooltip reveals), and transforms (card hover lifts, dropdown slides). A secondary 150ms tier exists for micro-interactions that need snappiness (focus ring expansion, icon state changes). Filter transitions (likely for grayscale-to-color image effects or blur backdrop adjustments) also use 300ms.
Keyframe Animations
- spinAround — Continuous 360° rotation, likely used for loading spinners or the swiper-preloader.
- fadeOut / fadeOutDown / fadeOutUp — Exit animations with directional translation (downward or upward fade). Used for dismissing toasts, closing modals, or transitioning slides out of view.
- fadeIn / fadeInDown / fadeInUp — Entrance animations mirroring the fadeOut suite. New content fades in while sliding from above or below, creating a smooth "curtain" reveal effect.
- swiper-preloader-spin — Specialized spinner animation for the Swiper carousel's loading state, probably a variation of spinAround tailored to the carousel's preload indicator.
Interaction Patterns
- Modal entrance: The Privacy Settings modal likely uses
fadeIncombined with a subtletranslateY(-10px) → translateY(0)to drop in from slightly above while fading from 0% to 100% opacity over 300ms. - Button hover lift: Primary and secondary buttons probably gain
{extensions.shadows.sm}on hover with a 300ms transition, creating a subtle "press and release" physicality. - Image hover: Hero cards may apply a slight scale (1.0 → 1.02) or brightness shift on hover via the
filtertransition, making photography feel responsive without jarring movement. - Nav active pill: The
{component.nav-link-active}background tint likely fades in/out over 300ms as the user navigates between sections or the active state updates. - Carousel slide: The presence of
swiper-preloader-spinand fade keyframes strongly suggests a Swiper.js-powered image carousel in the hero or lower sections, usingfadeInUp/fadeOutDownfor slide transitions. - Focus rings: Input and button focus states probably expand a
{colors.border-strong}outline with the--transition-quick(150ms) timing for immediate keyboard-navigation feedback. - Hamburger animation: The
{component.hamburger-icon}likely morphs to an X shape on click using a transform transition, common in mobile-nav patterns. - Backdrop blur: The modal overlay may incorporate a
backdrop-filter: blur()that animates in alongside opacity for a frosted-glass effect (though this wasn't explicitly in the extracted shadows, it's a common companion to the observed transition patterns).
Imagery Style
- Photography-forward design: Model portraiture dominates the hero section—these are professional fashion/modeling shots with studio lighting, not stock lifestyle imagery. Subjects are diverse in ethnicity and presentation style.
- Full-bleed treatment: Images extend edge-to-edge within their card containers, clipped only by the 24px border radius. No frames, no insets, no padding between photo and card edge.
- Portrait orientation: Hero card photographs appear to be shot in 3:4 or 2:3 portrait aspect ratio, optimized for showcasing full-body or 3/4-length model poses.
- High-contrast tonality: The photography leans toward dramatic lighting with deep shadows and bright highlights, complementing (rather than fighting) the dark UI chrome.
- Human-centric subject matter: Faces and figures are the compositional focus—no abstract textures, product shots, or scenery. This reinforces the platform's talent-marketplace identity.
- Gradient protection: A CSS gradient overlay (
{component.hero-card-overlay}) is systematically applied to ensure text readability, meaning imagery is always treated as a "background layer" with UI superimposed, never placed side-by-side as equal partners. - Color neutrality: Despite the magenta/blue UI palette, the photography itself appears color-neutral or desaturated, preventing clashing between UI chrome and image content.
- Professional quality: Images suggest agency-grade or portfolio-quality work, setting a premium tone for the platform. No casual snapshots or user-generated aesthetic in the hero placement.
- Emotive expression: Visible models show expressive poses and facial expressions (eyes closed, water spray, camera-holding stance)—the imagery sells aspiration and artistic vision, not just literal "here is a person."
- Consistent crop philosophy: Both hero cards use the same overlay treatment and text-positioning strategy, suggesting a template-based approach where any model photograph can be swapped into the card system with predictable results.
Icon System
- Library: Custom SVG icons (no detected dependency on Lucide, Heroicons, Material Icons, or Font Awesome). The font-face declaration includes
swiper-iconsfor carousel controls, and the globe/hamburger marks appear to be inline SVGs or custom icon-font glyphs. - Specific icons observed:
- Hamburger menu (three horizontal lines) — top-right nav, triggers mobile/off-canvas menu
- Globe/world — modal header, language/region selector
- Swiper navigation arrows (implied by swiper-icons font-face) — prev/next carousel controls
- Swiper loader/spinner (implied by swiper-preloader-spin keyframe) — carousel loading state
- Treatment: Stroke-based or simple fill icons (exact vector style unclear from screenshot resolution). Color is typically
currentColorinheriting from parent text color—white on dark surfaces, dark on the white modal. Size ranges from 20px (globe) to 24px (hamburger), aligning with{typography.body-sm}cap height for visual harmony. - Alignment: Icons center vertically with adjacent text (e.g., globe icon aligns with "Privacy Settings" baseline/midline). Touch targets expand to at least 24px × 24px (or 44px × 44px for accessibility) even if the glyph itself is smaller.
- Weight consistency: Icons match the 400 or 700 weight of nearby typography—no ultra-light or hand-drawn styles that would clash with Montserrat's geometric precision.
Recommended Frontend Stack
- Framework: Nuxt 3 (Vue meta-framework detected via __NUXT__ hydration payload)
- Styling: Custom CSS / SCSS modules (non-Tailwind; extracted classes use BEM-like naming: .button.primary.is-rounded)
- Fonts: Self-hosted Montserrat WOFF2/WOFF (currently served from /_nuxt/fonts/)
Fallback: Google Fonts CDN <link> for Montserrat wght@400;700
- Animation: Vanilla CSS transitions (300ms ease-in-out baseline) + JS-triggered keyframe classes
Optional: Swiper.js for carousel behavior (font-face present)
- Icons: Custom SVG inline + swiper-icons font for carousel controls
- Component lib: Custom components (no Radix/shadcn detected; likely hand-rolled Vue SFCs)
- State: Vue 3 Composition API / Pinia (standard Nuxt 3 stack)
Responsive Behavior
Breakpoints
| Name | Width | Key Changes |
|---|---|---|
| Mobile | < 768px | Single-column layout; hero cards stack vertically; nav collapses to hamburger-only; modal width 90vw; CTA buttons full-width |
| Tablet | 768px – 1024px | Two-column hero cards with reduced padding; nav shows abbreviated menu; sidebar rails collapse |
| Desktop | 1025px – 1440px | Full layout as screenshot: 2-col hero, full nav, centered 1440px container |
| Wide | > 1440px | Container stops expanding at 1440px; extra horizontal space distributes as background {colors.canvas} visible at edges |
Touch Targets
{component.button-primary}/{component.button-secondary}: Currently ~32px height (6px pad × 2 + 14px font). Should increase to 44px minimum for WCAG AAA. Recommend padding adjustment to10px 17.5px.{component.button-accept-all}: ~46px height (14px pad × 2 + 18px implicit line-height). Meets 44px guideline—acceptable as-is.{component.hero-card-cta}: ~40px height (10px pad × 2 + 20px implied). Slightly under 44px—increase padding to12px 20px.{component.nav-link}: ~32px height. Needs expansion to 44px for mobile touch; considerpadding: 14px 17.5pxon small screens.{component.hamburger-icon}: 24px × 24px. Must wrap in 44px × 44px invisible tap area (padding or min-width/height).{component.globe-icon}: 20px × 20px. Same requirement—expand touch target to 44px minimum.
Collapsing Strategy
- Navigation: The full horizontal nav (Home, Castings, Models, Pro directory, Marketplace) hides behind
{component.hamburger-icon}on mobile, revealing an off-canvas or dropdown menu. "Log in" and "Sign up" buttons may remain visible or move into the menu. - Hero cards: The two-column hero card grid collapses to single-column stack on mobile. Card order preserved (left card on top, right card below). Each card takes full viewport width minus
{spacing.md}(16px) horizontal gutter. - Modal:
{component.modal}switches from fixed ~560px width to 90vw max-width on mobile, maintaining{spacing.xl}(32px) internal padding but allowing horizontal scroll if content overflows. - Section headings:
{component.section-heading}(36px) may downscale to 28–30px on mobile to prevent orphaned words, or remain 36px with tighter line-height. - CTA buttons:
{component.hero-card-cta}buttons become full-width within their card on mobile, maximizing tap area. - Typography scaling: Body text may reduce from 18px to 16px on narrow viewports (< 375px) to prevent 10–12 character line lengths.
Image Behavior
- Hero card images: Maintain portrait aspect ratio (3:4) on mobile but scale width to 100% of card container. Height becomes fluid (auto) rather than fixed, preventing excessive scrolling.
- Object-fit: Images likely use
object-fit: coverto fill their containers without distortion, withobject-position: centerortopto keep faces visible. - Lazy loading: Below-fold images (cards below the hero, model thumbnails) should use
loading="lazy"or intersectionObserver-based lazy loading—critical for a photography-heavy page. - Art direction: Consider serving cropped/square versions of hero images on mobile (via
<picture>+srcset) to prevent excessively tall cards that push content too far down. - Avatar images (profile pictures in model listings, not visible in screenshot but inferred): Circle-clipped (
border-radius: 50%), 48–80px size,object-fit: cover.
Iteration Guide
- Initialize a Nuxt 3 project with Vue 3 and configure the Montserrat font-face declarations to match the extracted
@font-faceblocks (WOFF2 primary, WOFF fallback, swap display strategy). - Define CSS custom properties for every token in the YAML frontmatter following the
{section.token}path convention:--colors-primary: #75c1fb;,--rounded-pill: 160px;,--spacing-section: 64px;, etc. Reference these variables in all component styles—never hard-code hex values or pixel measurements that have a token equivalent. - Build the layout shell first:
{component.top-nav}(64px height,{colors.surface}background, 1440px centered container), then the hero section with two-column grid, then the modal overlay structure. Validate spacing tokens ({spacing.md}gutters,{spacing.section}breaks) before adding inner components. - Implement components in dependency order: Start with atomic buttons (
{component.button-primary},{component.button-secondary},{component.button-ghost}), then composite containers ({component.hero-card}wrapping{component.hero-card-overlay}+ text +{component.hero-card-cta}), finally page-level assemblies (hero section, modal). - Add state variants as separate CSS classes or Vue prop states:
.button-primary-hover,.button-primary-active,.nav-link-active. Do not nest these in the default component definition—keep them as siblings that can be toggled via JS or:hover/:activepseudo-classes. - Apply motion last: Once static layouts are pixel-match accurate, add the 300ms
ease-in-outtransitions tobackground-color,color,opacity,transform, andfilterproperties. ImplementfadeIn/fadeOutkeyframe classes for modal and carousel animations. - Test the dark-theme inversion carefully: Any component using
{colors.surface-elevated}(white) like{component.modal}must switch text color to{colors.on-surface}(#1d1d1f). Verify contrast ratios meet WCAG AA (4.5:1 for body text, 3:1 for large text). - Responsive pass: After desktop layout is complete, add media queries at 768px and 1024px breakpoints. Collapse nav to hamburger, stack hero cards, adjust modal width to 90vw, expand button touch targets to 44px minimum.
- Accessibility audit: Verify all interactive elements have focus-visible styles (outline using
{colors.border-strong}or 2px solid{colors.primary}), all images have meaningfulalttext, and color contrast passes for{colors.muted-soft}(currently at risk at 50% opacity on dark backgrounds). - Run the linter: Execute
npx @google/design.md lint DESIGN.mdafter any token additions or component changes. Watch forbroken-ref(typos in{token.path}references),orphaned-tokens(defined but never referenced), andcontrast-ratiowarnings (especially for{colors.muted-soft}usages).
Font Setup for Development:
/* Add to your global CSS or nuxt.config.css */
@font-face {
font-display: swap;
font-family: 'Montserrat';
font-style: normal;
font-weight: 400;
src: local(''), url('/fonts/montserrat-v15-latin-ext_latin_cyrillic-ext_cyrillic-regular.woff2') format('woff2');
}
@font-face {
font-display: swap;
font-family: 'Montserrat';
font-style: normal;
font-weight: 700;
src: local(''), url('/fonts/montserrat-v15-latin-ext_latin_cyrillic-ext_cyrillic-700.woff2') format('woff2');
}
:root {
--font-family-base: 'Montserrat', 'Lucida Grande', 'Lucida Sans Unicode', 'DejaVu Sans', Verdana, sans-serif;
}
Known Gaps
- Hover state styling: Per the no-hover policy, all
-hovercomponent variants are named but lack exact property values. Implement hover darkening (~8–12% luminance shift for backgrounds, color lighten for text) based on the documented active states as reference. - Primary button background color discrepancy: The pre-assigned
{colors.primary}is #75c1fb (electric blue), but the dominant CTA button color observed in the screenshot is a vivid magenta/pink (documented here as{colors.signature-magenta}/ #e83a7b). The extracted CSS showsbackgroundColor: rgba(0, 0, 0, 0)(transparent) for the Sign up button, suggesting the magenta may be applied via CSS gradient, pseudo-element (::before), or a class not fully captured. Verify the exact hex value of the magenta CTA color from the live site's computed styles before final implementation. - Loading skeletons / pending states: No skeleton loaders, spinners (beyond the swiper-preloader), or shimmer effects were visible. Design and implement loading states for model card grids, search results, and image uploads using
{colors.hairline-soft}backgrounds with pulse animation. - Form validation states: No input fields appeared in the above-fold view. Error (
{colors.error}/ #ff4757) and success ({colors.success}/ #2ed573) colors are defined in the palette but unvalidated against actual form designs. Design error outlines, helper text, and icon treatments for login/signup forms. - Authenticated-only surfaces: Dashboard, profile editing, messaging, and booking flow screens are entirely unknown. These may introduce new sub-systems (tables, calendars, chat bubbles) beyond the landing-page scope documented here.
- Sub-brand palettes: Model Management may offer tiered accounts (Free, Premium, Agency) with distinct accent colors or surface treatments for each tier. No evidence of this in the current screenshot.
- Exact modal shadow spread: The
{extensions.shadows.md}value is extracted accurately but may interact differently with the white-on-dark backdrop. Test modal elevation against various background complexities (solid color vs. photographic vs. patterned). - Carousel/Swiper configuration: The presence of
swiper-iconsfont-face andswiper-preloader-spinkeyframe confirms Swiper.js usage, but slide count, autoplay settings, pagination style (dots/arrows/none), and touch-behavior parameters are unknown. Configure based on standard marketplace carousel patterns. {colors.muted-soft}contrast risk: Atrgba(255, 255, 255, 0.5)on{colors.surface}(#1d1d1f), contrast ratio is approximately 4.5:1—barely passing AA for 18px+ text. For 14px or smaller text (like{typography.caption}), this fails WCAG AA. Consider bumping to 60% opacity or restricting{colors.muted-soft}to text ≥ 18px.- Mobile nav interaction detail: Whether the hamburger triggers a full-screen overlay, a slide-out drawer, or a dropdown panel is unknown. Design the mobile navigation pattern consistent with the dark theme and pill-shaped link treatment.