Design Principles
The visual language of Propcore, translated into code.
Color Palette
Neo-constructivism operates on restriction. The limited palette forces every color choice to be intentional.
Core Colors
| Token | Value | Usage |
|---|---|---|
--propcore-red | oklch(0.47 0.18 18) | Primary actions, emphasis, danger |
--propcore-black | oklch(0.15 0 0) | Text, borders, backgrounds |
--propcore-cream | oklch(0.95 0.02 90) | Backgrounds, contrast (warm paper tone) |
--propcore-gold | oklch(0.75 0.14 85) | Sparse accent only — warnings, highlights |
Usage Rules
- Red is active. Use it for CTAs, selected states, and elements that demand action.
- Black borders are non-negotiable. Every component has a hard edge.
- Cream is never pure white — the warm off-white evokes aged paper and printing.
- Gold appears sparingly. If everything is loud, nothing is.
:root {
--propcore-red: oklch(0.47 0.18 18);
--propcore-black: oklch(0.15 0 0);
--propcore-cream: oklch(0.95 0.02 90);
--propcore-gold: oklch(0.75 0.14 85);
}Typography
Constructivist typography is engineered, not decorated. Text is a visual element with weight and direction.
Font Stack
--font-display: "Oswald", "Bebas Neue", sans-serif; /* headlines */
--font-body: "Space Grotesk", "Inter", sans-serif; /* text */
--font-mono: "JetBrains Mono", monospace; /* code */Scale
| Class | Size | Weight | Usage |
|---|---|---|---|
text-display | 4rem+ | 700 | Hero headlines |
text-headline | 2rem | 700 | Section headers |
text-title | 1.25rem | 600 | Card titles, labels |
text-body | 1rem | 400 | Body text |
text-caption | 0.875rem | 500 | Small labels, metadata |
Typography Principles
- Headlines can rotate. Use
rotate-[-2deg]torotate-[-6deg]for tension. - ALL CAPS for display text — Constructivists used uppercase for impact.
- Tight tracking on headlines (
tracking-tight), generous on body text. - No decorative fonts. Geometric sans-serifs only.
<h1 className="font-heading text-4xl uppercase tracking-wider rotate-[-3deg]">
Build Something
</h1>Borders & Shadows
The signature Propcore look: hard black borders with offset shadows. No blur, no subtlety.
Border Weight
| Context | Width |
|---|---|
| Buttons, inputs | border-3 |
| Cards, containers | border-3 or border-4 |
| Emphasis/selected | border-4 |
Shadow System
Shadows are solid black offsets, never blurred. They create a stacked-paper or letterpress effect.
--shadow-sm: 2px 2px 0px 0px var(--border);
--shadow: 4px 4px 0px 0px var(--border);
--shadow-lg: 8px 8px 0px 0px var(--border);Usage
<button className="border-3 border-border bg-main text-main-foreground shadow-shadow">
Take Action
</button>Geometric Elements
Constructivism is built on triangles, circles, and rectangles in dynamic composition.
Diagonal Lines
Use pseudo-elements or SVG for decorative diagonals:
<div className="relative">
<div className="absolute w-full h-1 bg-border rotate-[-15deg] origin-left" />
{/* content */}
</div>Wedge Shapes
The iconic "red wedge" can be built with CSS triangles:
.wedge {
width: 0;
height: 0;
border-left: 60px solid transparent;
border-right: 60px solid transparent;
border-bottom: 100px solid var(--propcore-red);
transform: rotate(-30deg);
}Circle Accents
<div className="w-16 h-16 rounded-full border-4 border-border bg-accent" />Composition Rules
- Diagonals run 15–45 degrees
- Shapes overlap and intersect
- Asymmetry creates tension — avoid centering everything
Layout & Spacing
Constructivist layouts reject symmetry. Use CSS Grid with intentional misalignment.
Grid System
<div className="grid grid-cols-12 gap-4">
<div className="col-span-7 col-start-1">Main content</div>
<div className="col-span-4 col-start-9 -mt-8">Offset element</div>
</div>Spacing Scale
Use Tailwind's default scale, but don't be afraid of large gaps and negative margins:
gap-8orgap-12between major sections- Negative margins (
-mt-4,-ml-2) to create overlap - Generous padding inside containers (
p-6top-10)
Rotation & Transform
// Subtle rotation for cards
<div className="rotate-[-1deg] hover:rotate-0 transition-transform">
// More aggressive for decorative elements
<span className="inline-block rotate-[-6deg]">NEW</span>Interactive States
Interactions should feel mechanical and immediate — like pressing a button on industrial machinery.
Hover
Shadow shifts inward, element appears to press down:
<button className="
border-3 border-border bg-main text-main-foreground
shadow-shadow
hover:translate-x-boxShadowX hover:translate-y-boxShadowY
hover:shadow-none
transition-all duration-100
">
Press Me
</button>Active/Pressed
Shadow disappears entirely:
active:shadow-none active:translate-x-boxShadowX active:translate-y-boxShadowYFocus
Bold, visible focus rings — accessibility is revolutionary:
focus:outline-none focus:ring-2 focus:ring-border focus:ring-offset-2Disabled
Desaturated, no shadow:
disabled:opacity-50 disabled:shadow-none disabled:cursor-not-allowedAnimation
Movement should be purposeful and quick. No floating, no bouncing — this is industrial design.
Allowed Animations
- Transform translations (slide in/out)
- Rotation snaps
- Opacity fades
- Scale on interaction
Timing
--duration-fast: 100ms;
--duration-normal: 200ms;
--easing: cubic-bezier(0.25, 0.46, 0.45, 0.94); /* ease-out */What to Avoid
- Bounce easing
- Slow fades (>300ms)
- Continuous animations (unless loading states)
- Anything "playful" — this aesthetic is serious
Component Checklist
Before shipping a Propcore component, verify:
- Black border present (
border-3minimum) - Hard shadow (no blur)
- Colors from the restricted palette only
- Interactive states feel mechanical (translate + shadow shift)
- Typography is geometric sans-serif
- Focus states are visible and bold
- No rounded corners beyond
rounded-base(2px)
"The artist is not a special kind of person, but every person is a special kind of artist." — El Lissitzky