Culture Exchange Standard v2.0

MADE CX Design System

Consolidated design language for institutional credibility and professional trust. Sharp edges. Functional color. Text over icons. 2px borders. No compromises.

Core Design Principles

Every element reinforces the platform's role as the authoritative ledger for cultural property rights. These five rules are non-negotiable.

Sharp, Not Soft

No rounded corners, no blur effects. All edges are crisp and defined. border-radius: 0 everywhere.

Green is Functional

Color reserved for arrows, logo stroke, success states, chart lines, and verified badges only. Never decorative.

Text Over Icons

Clear labels, not emoji decorations. Every element is labeled with text. No emoji in production UI.

Contrast Over Gradients

Pure black/white with strategic accent color. No gradients anywhere. Solid colors only.

Structure Over Decoration

2px borders define space, not shadows. Consistent border treatment. No drop shadows.

Anti-Patterns
Don'tDo Instead
Use rounded corners (border-radius)Keep all edges sharp (0px radius)
Fill backgrounds with greenUse green only for arrows and accents
Add drop shadowsUse 2px borders consistently
Use emoji in production UIUse text labels or simple SVG icons
Use gradients anywhereUse solid colors only
Use 1px bordersUse 2px borders for all structural elements
Add blur or glassmorphism effectsKeep contrast high and crisp

Brand & Logo

The MADE CX wordmark: solid "MADE" represents established culture, outlined "CX" in green represents exchange and future potential.

Primary Logo
MADECX
MADECX
Logo Construction
PropertyValueCSS
FontInter, 900font-weight: 900
"MADE" Color (Light)#000000color: var(--text)
"MADE" Color (Dark)#FFFFFFcolor: var(--text)
"CX" FillTransparentcolor: transparent
"CX" Stroke#00C805, 2.5px-webkit-text-stroke: 2.5px var(--green)
Letter Spacing-0.01emletter-spacing: -0.01em
Gap8pxmargin-left: 8px
Downloadable Logo Files
MADECX
SVG — Light
MADECX
SVG — Dark
MADECX
PNG — Light (2x)
MADECX
PNG — Dark (2x)
HTML + CSS
.logo-text {
    display: flex;
    align-items: baseline;
    font-family: var(--font-primary); /* Inter */
    font-size: 22px;
    font-weight: 900;
    letter-spacing: -0.01em;
}
.logo-made { color: var(--text); }
.logo-cx {
    color: transparent;
    -webkit-text-stroke: 2.5px var(--green);
    margin-left: 8px;
}

Color System

Pure black and white with strategic green accent. Green is functional, never decorative. Red for negative/error states only.

Primary Palette
Black
#000000
Primary text, borders, backgrounds
White
#FFFFFF
Backgrounds, text on dark
Green (Accent)
#00C805
Arrows, logo, success, charts
Red (Error)
#EF4444
Negative charts, errors, declines
Gray Scale
50
100
200
300
400
500
600
700
800
900
Green Usage Rules
Correct UsageIncorrect Usage
Logo "CX" outline strokeButton fills or backgrounds
Arrow symbols in buttonsBadge or card backgrounds
Success/verified checkmarksText highlights or section fills
Chart lines (positive growth)Icon fills
Price change indicators (+2.5%)Navigation elements
Section labels (mono, 11px)Large filled areas of any kind
Stat values ($15T, 4%)Form inputs or borders
Theme Variables
TokenLightDarkUsage
--bg#FFFFFF#000000Page background
--bg-alt#F5F5F5#171717Section/card backgrounds
--bg-tertiary#FAFAFA#262626Nested backgrounds
--text#000000#FFFFFFPrimary text, buttons
--text-secondary#525252#A3A3A3Body text
--text-muted#737373#525252Captions, labels
--border#E5E5E5#262626All borders (always 2px)

Typography

Three font families with strict roles: Space Grotesk for display/headlines, Inter for body/UI, IBM Plex Mono for technical/labels.

Font Families
Space Grotesk
ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789
var(--font-display) — Headlines, Titles, Display, Card Titles
Aa 400
Aa 500
Aa 600
Aa 700
Aa 800
IBM Plex Mono
ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789
var(--font-mono) — Labels, Code, Technical, Badges, Section Labels
Aa 400
Aa 700
Aa 800
Type Scale
Hero Title
The Manifesto
Space Groteskclamp(40px, 6vw, 72px)900-0.03em
Section Title
Why MADE CX Exists
Space Groteskclamp(32px, 5vw, 48px)900-0.02em
Card Title
David Drake Pottery 1
Space Grotesk20px900
Section Label
Community Impact
IBM Plex Mono11px8000.15em
Body Text
Black creativity has always built global markets — yet no system has ever existed to protect its origin.
Inter16px400-500line-height: 1.6
Button Text
Start Registration →
Inter14px8000.1em uppercase

Buttons

Buttons use var(--text) as background (black in light, white in dark). Green is ONLY for the arrow icon accent. All borders 2px. Font-weight 800.

Button Variants
Button Sizes
CTA Button (Header)
Button Specs
PropertyValue
Border width2px (all variants)
Font weight800
Text transformuppercase
Letter spacing0.1em
Arrow icon colorvar(--green) — only green on buttons
Arrow hovertranslateX(4px)
Primary bgvar(--text) — black/white per theme

Image Standards

Professional photography with clear subjects. No text overlays. High contrast for white backgrounds.

Image Dimensions
4:3
Grid View Cards
400 x 300px
1:1
List Thumbnails
80 x 80px
1:1
Detail Hero
600 x 600px
Requirements
PropertyValue
Max file size2MB
Object fitobject-fit: cover
Object positionobject-position: center
Border on imagesnone
Resolution2x for retina
High Contrast

Images must work on white backgrounds

Clear Subject

Main subject clearly identifiable

No Text Overlays

Text separate from image layer

Professional Quality

No phone snapshots, proper lighting

Product Cards

Grid view cards with 4:3 image ratio. Category badge top-left, asset icon bottom-right. 2px border, hover to black.

Product
Product

David Drake Pottery 1

David Drake Legacy Trust

Uncategorized
Service
Service

Beat Production Pack

ATL Sound Labs

Music
Card Specs
ElementStyle
Card border2px solid var(--border)
Hoverborder-color: var(--black)
Image ratioaspect-ratio: 4/3
Category badgeTop-left 16px, 2px solid #000, transparent bg
Asset iconBottom-right 16px, 40x40px, black bg
Asset typeGreen #00C805 (only green on card)
Content padding20px

List View & Financial Accordion

Table-style layout with expandable financial charts. Click chevron to reveal price history, projections, and stats.

NameCategoryChartPriceValuation
Product

David Drake Pottery 1

David Drake Legacy Trust

David Drake Pottery 1
David Drake Legacy Trust
Uncategorized
$1,000
+2.5%
$10K
Market Cap
$1,000 $1,200$1,000$800$400 1Y6MTODAY+3M
View Full Details
Price
$1,000
Projected
$1,150 (+15%)
Mkt Cap
$10,000
Service

Beat Production Pack

ATL Sound Labs

Beat Production Pack
ATL Sound Labs
Music
$8,750
-1.4%
$450K
Market Cap
$8,750 $12K$9K$6K 1YTODAY+3M
View Full Details
Price
$8,750
Projected
$8,200 (-6.3%)
Mkt Cap
$450K
Chart Specs
ElementStyle
Chart height180px, border: 2px solid var(--border)
SVG viewBox0 0 700 156
Price line (positive)stroke: #00C805, width: 2.5
Price line (negative)stroke: #EF4444
Projection linestroke: #737373, dasharray: 4,3
Volume barsopacity: 0.3, green/red fill
TODAY labelGreen for positive, red for negative

Product Detail Page

Two-column layout: 600x600 hero image left, product information right. Registration box and creator box below info.

CX
Product

David Drake Pottery 1

David Drake Legacy Trust

Pottery craft in the 19th century by David Drake, who was enslaved during the time of creation. A testament to enduring creativity.

Registration IDMADE-2026-FCE4E
Category
Statusverified
Created By
David Drake Legacy Trust
Greenbelt

UI Patterns

Common patterns: section headers, pull quotes, stats, layer diagrams, form elements, badges, and icons.

Section Header

The MADE Foundation

Reclaiming $15 Trillion by 2050

Pull Quote

Culture is the world's most powerful operating system. MADE CX is the ledger that protects it.

Statistics
$15T
Target by 2050
4%
Community Reinvestment
100%
Transparency
Layer Diagram
Top
Creators

Broadcasting, licensing, owning value

Middle
MADE CX

Ledger / Compliance / Valuation

Bottom
Marketplace

Brands / Platforms / Institutions

Form Elements
Badges
Default BadgeOutline Badge
Filter Chips
AllMusicFashionArtDance
Icons
Arrow
External
Shield
Check
Menu
Close
Expand
Grid

Spacing System

4px base unit. Structure over decoration.

4px
8px
16px
24px
32px
40px
48px
64px
ContextValue
Card padding20px
Section spacing40px
Element gaps16px
Inline spacing8px
Container (mobile)16px
Container (tablet)24px
Container (desktop)40px

Email Templates

9 production-ready transactional emails triggered by database events. All follow the Culture Exchange Standard: table-based layout, 600px max-width, inline CSS, cross-client compatible.

Architecture
01
Platform Action

User signup, status change, agreement signed

02
Database Trigger

Supabase trigger detects change, queues email

03
Edge Function + Resend

Processes queue every 5 min, delivers via Resend API

Email Template Index
#TemplateTriggerAudience
01Brand WelcomeBrand completes onboardingBrands
02Registration ApprovedStatus → approvedCreators
03Needs More InfoStatus → needs_infoCreators
04Royalties Enabledroyalties_enabled = trueCreators
05CCA ConfirmedAgreement insertedCreators
06Under ReviewRegistration inserted (pending)Creators
07Cultural Lien FiledLien record insertedCreators
08Brand RegistrationBrand status → approvedBrands
09License ApprovedLicense status → approvedBrands
Email Design Standards
600px Max Width

Table-based layout, centered on #F5F5F5 background. All content within a single 600px container.

Inline CSS Only

No external stylesheets. Every style is inline for Gmail, Outlook, and Apple Mail compatibility.

No Emoji in Prod

Use text badges (REGISTRATION APPROVED, ACTION REQUIRED) instead of emoji. Checkmarks use "✓" character.

Green = Arrows Only

Logo CX stroke and arrow symbols (→) are the only green elements. Everything else is black/white/gray.

Email Anatomy
MADECX
Template Badge
Email Headline Goes Here
Supporting description text for the email.
Hi [First Name], body content with dynamic variables replaced by the trigger function.
Content Section
Structured content: registration details, checklists, distribution breakdowns, etc.
Accent Section
Used for "What This Unlocks", "Why Verification Matters", etc.
Call to Action
MADECX
Verify the Culture. Reinvest the Future.
Email Component Specs
ElementStyle
Outer background#F5F5F5 with 20px padding
Container600px max-width, #FFFFFF background
Header#000000 bg, 32px 40px padding, border-bottom: 3px solid #00C805
Logo in header28px, weight 900. "MADE" white, "CX" stroke 3px green
Hero section56px 40px padding, border-bottom: 1px solid #E5E5E5
Status badgeborder: 2px solid #000, 11px mono, uppercase, 0.15em spacing
Headline36px, weight 900, -0.02em, line-height 1.1
Body text15px Inter, line-height 1.8, #171717
Info boxborder: 2px solid #000, bg #FAFAFA, 32px padding
Accent boxborder-left: 3px solid #00C805, bg #FAFAFA
Warning box (needs-info)border-left: 4px solid #FF6B00, bg #FFFAF5
CTA button#000 bg, 18px 40px padding, 13px uppercase, arrow #00C805
Footer#000000 bg, border-top: 3px solid #00C805, 40px padding
Footer logo18px, "CX" stroke 2.5px green
Template Variables
Dynamic Variables
[First Name]           — User's first name
[PROPERTY_NAME]        — Creative property title
[BCID_NUMBER]          — Blackchain Creative ID
[SUBMISSION_ID]        — Registration submission ID
[CCA_ID]               — Creator Creditor Agreement ID
[LIEN_ID]              — Cultural Lien reference number
[LICENSE_ID]           — Cultural Use License number
[BRAND_NAME]           — Brand/company name
[Brand Contact Name]   — Brand contact person
[DATE_TIME]            — Formatted timestamp
[REVIEWER_NOTES_HERE]  — Admin notes for rejections
[RESUBMIT_URL]         — Link to edit submission
[SUBMISSION_URL]       — New submission link
[LEDGER_URL]           — Public ledger entry
[PROPERTY_URL]         — Product detail page
[CERTIFICATE_PDF_URL]  — Certificate download
[DASHBOARD_URL]        — Dashboard link
[PORTAL_URL]           — Creator portal link
[SHARE_IG]             — Instagram share
[SHARE_TIKTOK]         — TikTok share
[SHARE_X]              — X/Twitter share
[SHARE_LINKEDIN]       — LinkedIn share
Royalty Distribution (Email 04)
80%
Creator
16%
Custodian / Enforcement
4%
Cultural Reinvestment
Trigger Functions (Supabase)
SQL — Email Queue Table
CREATE TABLE IF NOT EXISTS email_queue (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    to_email TEXT NOT NULL,
    to_name TEXT,
    subject TEXT NOT NULL,
    html_content TEXT NOT NULL,
    email_type TEXT NOT NULL,
    user_id UUID REFERENCES auth.users(id),
    created_at TIMESTAMPTZ DEFAULT NOW(),
    sent_at TIMESTAMPTZ,
    error_message TEXT
);
SQL — Example Trigger (Registration Approved)
CREATE OR REPLACE FUNCTION queue_registration_approved_email()
RETURNS TRIGGER AS $
BEGIN
    IF NEW.status IN ('approved', 'verified')
       AND (OLD.status IS NULL
            OR OLD.status NOT IN ('approved', 'verified'))
    THEN
        INSERT INTO email_queue (
            to_email, to_name, subject,
            html_content, email_type, user_id
        )
        SELECT
            NEW.email,
            NEW.business_name,
            'Your Creative Property Is Now Protected',
            replace(
              replace(
                replace(template_html,
                  '[First Name]', COALESCE(NEW.first_name, 'there')),
                '[PROPERTY_NAME]', NEW.item_name),
              '[BCID_NUMBER]', NEW.registration_id),
            'registration_approved',
            NEW.auth_user_id;
    END IF;
    RETURN NEW;
END;
$ LANGUAGE plpgsql;

-- Attach trigger
CREATE TRIGGER trigger_registration_approved_email
    AFTER UPDATE OF status ON registrations
    FOR EACH ROW
    EXECUTE FUNCTION queue_registration_approved_email();
SQL — All 9 Trigger Summary
-- TRIGGER MAP: Action → Function → Table
--
-- 01  Brand onboarding complete    → queue_brand_welcome_email()
--     ON users AFTER UPDATE OF onboarding_completed
--
-- 02  Registration approved        → queue_registration_approved_email()
--     ON registrations AFTER UPDATE OF status
--
-- 03  Registration needs info      → queue_registration_needs_info_email()
--     ON registrations AFTER UPDATE OF status
--
-- 04  Royalties enabled            → queue_royalties_enabled_email()
--     ON registrations AFTER UPDATE OF royalties_enabled
--
-- 05  CCA signed                   → queue_cca_confirmed_email()
--     ON creator_creditor_agreements AFTER INSERT
--
-- 06  Registration submitted       → queue_registration_under_review_email()
--     ON registrations AFTER INSERT
--
-- 07  Cultural lien filed          → queue_cultural_lien_filed_email()
--     ON cultural_liens AFTER INSERT
--
-- 08  Brand registration approved  → queue_brand_registration_confirmed_email()
--     ON registrations AFTER UPDATE OF status (user_type='brand')
--
-- 09  Brand license approved       → queue_brand_license_approved_email()
--     ON cultural_use_licenses AFTER UPDATE OF status
Queue Processing (Edge Function)
TypeScript — Supabase Edge Function
// supabase/functions/process-email-queue/index.ts
import { serve } from 'https://deno.land/std/http/server.ts';
import { createClient } from 'https://esm.sh/@supabase/supabase-js';

const RESEND_API_KEY = Deno.env.get('RESEND_API_KEY')!;
const SUPABASE_URL = Deno.env.get('SUPABASE_URL')!;
const SUPABASE_KEY = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!;

serve(async () => {
  const supabase = createClient(SUPABASE_URL, SUPABASE_KEY);

  // Fetch pending emails
  const { data: emails } = await supabase
    .from('email_queue')
    .select('*')
    .is('sent_at', null)
    .is('error_message', null)
    .order('created_at')
    .limit(10);

  if (!emails?.length) return new Response('No emails to send');

  for (const email of emails) {
    try {
      const res = await fetch('https://api.resend.com/emails', {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${RESEND_API_KEY}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          from: 'MADECX <[email protected]>',
          to: email.to_email,
          subject: email.subject,
          html: email.html_content,
        }),
      });

      if (res.ok) {
        await supabase.from('email_queue')
          .update({ sent_at: new Date().toISOString() })
          .eq('id', email.id);
      } else {
        const err = await res.text();
        await supabase.from('email_queue')
          .update({ error_message: err })
          .eq('id', email.id);
      }
    } catch (e) {
      await supabase.from('email_queue')
        .update({ error_message: e.message })
        .eq('id', email.id);
    }
  }

  return new Response(`Processed ${emails.length} emails`);
});
Deployment Checklist
Upload 9 HTML templates to Supabase Storage
Run all 9 trigger SQL scripts in Supabase SQL Editor
Deploy Edge Function: supabase functions deploy process-email-queue
Set RESEND_API_KEY in Edge Function secrets
Configure cron job (every 5 min) to process queue
Test each email type with manual SQL updates
Verify rendering in Gmail, Outlook, Apple Mail

React Component Library

Production-ready TSX components for the React platform team. Copy these files into your project or download the complete package below.

Quick Start
Terminal
# 1. Copy the design-system/ folder into your project
# 2. Import tokens in your root layout:
import '@/design-system/tokens.css'

# 3. Import components:
import { Button, Card, Badge, Logo } from '@/design-system/components'
tokens.css
design-system/tokens.css
/* MADE CX Design Tokens — v2.0 */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&family=Space+Grotesk:wght@400;500;600;700;800;900&family=IBM+Plex+Mono:wght@400;500;600;700;800&display=swap');

:root {
  --black: #000000;
  --white: #FFFFFF;
  --gray-50: #FAFAFA; --gray-100: #F5F5F5; --gray-200: #E5E5E5;
  --gray-300: #D4D4D4; --gray-400: #A3A3A3; --gray-500: #737373;
  --gray-600: #525252; --gray-700: #404040; --gray-800: #262626;
  --gray-900: #171717;
  --green: #00C805; --green-light: #00E806; --green-dark: #00A804;
  --red: #EF4444;
  --bg: var(--white); --bg-alt: var(--gray-100); --bg-tertiary: var(--gray-50);
  --text: var(--black); --text-secondary: var(--gray-600); --text-muted: var(--gray-500);
  --border: var(--gray-200); --card-bg: var(--white);
  --font-primary: 'Inter', -apple-system, sans-serif;
  --font-display: 'Space Grotesk', sans-serif;
  --font-mono: 'IBM Plex Mono', 'Monaco', monospace;
}
[data-theme="dark"] {
  --bg: var(--black); --bg-alt: var(--gray-900); --bg-tertiary: var(--gray-800);
  --text: var(--white); --text-secondary: var(--gray-400); --text-muted: var(--gray-600);
  --border: var(--gray-800); --card-bg: var(--gray-900);
}
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
::selection { background: var(--green); color: var(--black); }
Logo Component
design-system/components/Logo.tsx
import React from 'react';

interface LogoProps {
  size?: 'sm' | 'md' | 'lg';
  className?: string;
}

const sizes = { sm: '18px', md: '22px', lg: '40px' };
const strokes = { sm: '2px', md: '2.5px', lg: '3px' };

export const Logo: React.FC<LogoProps> = ({ size = 'md', className }) => (
  <span
    className={className}
    style={{
      display: 'flex',
      alignItems: 'baseline',
      fontSize: sizes[size],
      fontWeight: 900,
      letterSpacing: '-0.01em',
      lineHeight: 1,
      fontFamily: 'var(--font-primary)',
    }}
  >
    <span style={{ color: 'var(--text)' }}>MADE</span>
    <span
      style={{
        color: 'transparent',
        WebkitTextStroke: `${strokes[size]} var(--green)`,
        marginLeft: '8px',
      }}
    >
      CX
    </span>
  </span>
);
Button Component
design-system/components/Button.tsx
import React from 'react';

interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: 'primary' | 'secondary' | 'ghost';
  size?: 'sm' | 'default' | 'lg';
  showArrow?: boolean;
  children: React.ReactNode;
}

const Arrow = () => (
  <svg width="16" height="16" viewBox="0 0 24 24"
    fill="none" stroke="currentColor" strokeWidth="2"
    style={{ color: 'var(--green)', transition: 'transform 0.2s' }}>
    <path d="M5 12h14M12 5l7 7-7 7" />
  </svg>
);

const sizeStyles = {
  sm:      { padding: '8px 16px',  fontSize: '12px' },
  default: { padding: '16px 32px', fontSize: '14px' },
  lg:      { padding: '20px 40px', fontSize: '16px' },
};

const variantStyles = {
  primary:   { background: 'var(--text)', color: 'var(--bg)', borderColor: 'var(--text)' },
  secondary: { background: 'transparent', color: 'var(--text)', borderColor: 'var(--text)' },
  ghost:     { background: 'transparent', color: 'var(--text)', borderColor: 'transparent' },
};

export const Button: React.FC<ButtonProps> = ({
  variant = 'primary', size = 'default', showArrow = true,
  children, style, ...props
}) => (
  <button
    {...props}
    style={{
      display: 'inline-flex', alignItems: 'center', gap: '12px',
      fontFamily: 'var(--font-primary)', fontWeight: 800,
      textTransform: 'uppercase', letterSpacing: '0.1em',
      border: '2px solid', cursor: 'pointer', transition: 'all 0.2s',
      textDecoration: 'none',
      ...sizeStyles[size], ...variantStyles[variant], ...style,
    }}
  >
    {children}
    {showArrow && <Arrow />}
  </button>
);
ProductCard Component
design-system/components/ProductCard.tsx
import React from 'react';

interface ProductCardProps {
  image?: string;
  category: string;
  assetType: string;
  name: string;
  creator: string;
  tag?: string;
  verifiedDate?: string;
  onClick?: () => void;
}

export const ProductCard: React.FC<ProductCardProps> = ({
  image, category, assetType, name, creator, tag, verifiedDate, onClick,
}) => (
  <div onClick={onClick} style={{
    background: 'var(--card-bg)', border: '2px solid var(--border)',
    cursor: 'pointer', transition: 'border-color 0.2s',
    display: 'flex', flexDirection: 'column',
  }}>
    {/* Image */}
    <div style={{ position: 'relative', width: '100%', aspectRatio: '4/3',
      overflow: 'hidden', background: 'var(--bg-alt)' }}>
      {image
        ? <img src={image} alt={name}
            style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
        : <div style={{ width: '100%', height: '100%', display: 'flex',
            alignItems: 'center', justifyContent: 'center' }}>
            <PlaceholderIcon />
          </div>
      }
      <span style={{
        position: 'absolute', top: 16, left: 16, padding: '6px 12px',
        border: '2px solid var(--black)', fontFamily: 'var(--font-mono)',
        fontSize: '11px', fontWeight: 800, textTransform: 'uppercase',
        letterSpacing: '0.15em',
      }}>{category}</span>
    </div>

    {/* Content */}
    <div style={{ padding: 20 }}>
      <div style={{ fontFamily: 'var(--font-mono)', fontSize: '11px',
        fontWeight: 800, textTransform: 'uppercase', letterSpacing: '0.15em',
        color: 'var(--green)', marginBottom: 8 }}>{assetType}</div>
      <h3 style={{ fontFamily: 'var(--font-display)', fontSize: '20px',
        fontWeight: 900, margin: '0 0 8px', lineHeight: 1.2 }}>{name}</h3>
      <p style={{ fontSize: '14px', color: 'var(--text-muted)',
        margin: '0 0 16px' }}>{creator}</p>
      {tag && <span style={{ display: 'inline-block', padding: '6px 12px',
        border: '1px solid var(--border)', fontFamily: 'var(--font-mono)',
        fontSize: '10px', fontWeight: 700, textTransform: 'uppercase',
        letterSpacing: '0.1em', color: 'var(--text-secondary)' }}>{tag}</span>}
      {verifiedDate && (
        <div style={{ display: 'flex', justifyContent: 'space-between',
          marginTop: 20, paddingTop: 16,
          borderTop: '1px solid var(--border)' }}>
          <span style={{ fontFamily: 'var(--font-mono)', fontSize: '11px',
            fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.1em',
            color: 'var(--text-muted)' }}>{verifiedDate}</span>
          <span style={{ fontFamily: 'var(--font-mono)', fontSize: '11px',
            fontWeight: 800, textTransform: 'uppercase', letterSpacing: '0.1em',
            display: 'flex', alignItems: 'center', gap: 6 }}>
            <CheckIcon /> Asset
          </span>
        </div>
      )}
    </div>
  </div>
);

const PlaceholderIcon = () => (
  <svg width="48" height="48" viewBox="0 0 24 24" fill="none"
    stroke="currentColor" strokeWidth="1.5" style={{ opacity: 0.4 }}>
    <rect x="3" y="3" width="18" height="18" />
    <circle cx="8.5" cy="8.5" r="1.5" />
    <path d="M21 15l-5-5L5 21" />
  </svg>
);

const CheckIcon = () => (
  <svg width="12" height="12" viewBox="0 0 24 24"
    fill="var(--green)" stroke="none">
    <path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" />
  </svg>
);
Badge Component
design-system/components/Badge.tsx
import React from 'react';

interface BadgeProps {
  variant?: 'default' | 'outline';
  children: React.ReactNode;
}

export const Badge: React.FC<BadgeProps> = ({ variant = 'default', children }) => (
  <span style={{
    display: 'inline-flex', alignItems: 'center', gap: '8px',
    padding: '8px 16px', fontFamily: 'var(--font-mono)',
    fontSize: '11px', fontWeight: 800, textTransform: 'uppercase',
    letterSpacing: '0.15em',
    background: variant === 'outline' ? 'transparent' : 'var(--bg-alt)',
    border: `2px solid ${variant === 'outline' ? 'var(--text)' : 'var(--border)'}`,
  }}>
    {children}
  </span>
);
SectionLabel Component
design-system/components/SectionLabel.tsx
import React from 'react';

interface SectionLabelProps {
  children: React.ReactNode;
  centered?: boolean;
}

export const SectionLabel: React.FC<SectionLabelProps> = ({
  children, centered = false,
}) => (
  <div style={{
    fontFamily: 'var(--font-mono)', fontSize: '11px', fontWeight: 800,
    textTransform: 'uppercase', letterSpacing: '0.15em', color: 'var(--green)',
    display: 'flex', alignItems: 'center', gap: '12px',
    justifyContent: centered ? 'center' : 'flex-start',
    marginBottom: '12px',
  }}>
    <span style={{ width: 40, height: 2, background: 'var(--green)' }} />
    {children}
    {centered &&
      <span style={{ width: 40, height: 2, background: 'var(--green)' }} />}
  </div>
);
Barrel Export
design-system/components/index.ts
export { Logo } from './Logo';
export { Button } from './Button';
export { ProductCard } from './ProductCard';
export { Badge } from './Badge';
export { SectionLabel } from './SectionLabel';
File Structure
Directory
design-system/
├── tokens.css                  # CSS custom properties + fonts
├── components/
│   ├── index.ts                # Barrel export
│   ├── Logo.tsx                # Logo wordmark
│   ├── Button.tsx              # Primary / Secondary / Ghost
│   ├── ProductCard.tsx         # Grid view product card
│   ├── Badge.tsx               # Default / Outline badges
│   └── SectionLabel.tsx        # Green accent label
└── assets/
    ├── madecx-logo-light.svg   # Logo on white
    ├── madecx-logo-dark.svg    # Logo on black
    ├── [email protected]
    └── [email protected]
Usage Example
App.tsx — Example
import '@/design-system/tokens.css';
import { Logo, Button, ProductCard, Badge, SectionLabel } from '@/design-system/components';

export default function RegistryPage() {
  return (
    <main>
      <header style={{ display: 'flex', justifyContent: 'space-between',
        padding: '0 40px', height: 72, alignItems: 'center',
        borderBottom: '2px solid var(--border)' }}>
        <Logo size="md" />
        <Button variant="primary" size="default">Register Asset</Button>
      </header>

      <section style={{ padding: '80px 40px', maxWidth: 1200, margin: '0 auto' }}>
        <SectionLabel>Cultural Registry</SectionLabel>
        <h2 style={{ fontFamily: 'var(--font-display)', fontSize: 48,
          fontWeight: 900, letterSpacing: '-0.02em' }}>
          Browse Assets
        </h2>

        <div style={{ display: 'flex', gap: 12, margin: '32px 0' }}>
          <Badge>All</Badge>
          <Badge variant="outline">Music</Badge>
          <Badge variant="outline">Fashion</Badge>
        </div>

        <div style={{ display: 'grid',
          gridTemplateColumns: 'repeat(auto-fill, minmax(340px, 1fr))',
          gap: 24 }}>
          <ProductCard
            category="Product"
            assetType="Product"
            name="David Drake Pottery 1"
            creator="David Drake Legacy Trust"
            tag="Uncategorized"
            verifiedDate="Verified Jan 2026"
          />
          <ProductCard
            category="Service"
            assetType="Service"
            name="Beat Production Pack"
            creator="ATL Sound Labs"
            tag="Music"
            verifiedDate="Verified Dec 2025"
          />
        </div>
      </section>
    </main>
  );
}

Design Tokens

Complete CSS custom properties. Copy into any project to implement the MADE CX design system.

CSS Variables — Consolidated v2.0
:root {
    /* ── Primary Colors ── */
    --black: #000000;
    --white: #FFFFFF;

    /* ── Gray Scale ── */
    --gray-50:  #FAFAFA;
    --gray-100: #F5F5F5;
    --gray-200: #E5E5E5;
    --gray-300: #D4D4D4;
    --gray-400: #A3A3A3;
    --gray-500: #737373;
    --gray-600: #525252;
    --gray-700: #404040;
    --gray-800: #262626;
    --gray-900: #171717;

    /* ── Accent — FUNCTIONAL ONLY ── */
    --green: #00C805;
    --green-light: #00E806;
    --green-dark: #00A804;
    --red: #EF4444;

    /* ── Theme (Light) ── */
    --bg: var(--white);
    --bg-alt: var(--gray-100);
    --bg-tertiary: var(--gray-50);
    --text: var(--black);
    --text-secondary: var(--gray-600);
    --text-muted: var(--gray-500);
    --border: var(--gray-200);
    --card-bg: var(--white);

    /* ── Typography ── */
    --font-primary: 'Inter', -apple-system, sans-serif;
    --font-display: 'Space Grotesk', sans-serif;
    --font-mono: 'IBM Plex Mono', 'Monaco', monospace;

    /* ── Spacing (4px base) ── */
    --space-1: 4px;   --space-2: 8px;
    --space-3: 12px;  --space-4: 16px;
    --space-6: 24px;  --space-8: 32px;
    --space-10: 40px; --space-12: 48px;
    --space-16: 64px; --space-20: 80px;

    /* ── Borders — Always 2px, sharp ── */
    --border-width: 2px;
    --border-color: var(--gray-200);
}

/* ── Dark Mode ── */
[data-theme="dark"] {
    --bg: var(--black);
    --bg-alt: var(--gray-900);
    --bg-tertiary: var(--gray-800);
    --text: var(--white);
    --text-secondary: var(--gray-400);
    --text-muted: var(--gray-600);
    --border: var(--gray-800);
    --card-bg: var(--gray-900);
    --border-color: var(--gray-800);
}