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

TokenValueUsage
--propcore-redoklch(0.47 0.18 18)Primary actions, emphasis, danger
--propcore-blackoklch(0.15 0 0)Text, borders, backgrounds
--propcore-creamoklch(0.95 0.02 90)Backgrounds, contrast (warm paper tone)
--propcore-goldoklch(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

ClassSizeWeightUsage
text-display4rem+700Hero headlines
text-headline2rem700Section headers
text-title1.25rem600Card titles, labels
text-body1rem400Body text
text-caption0.875rem500Small labels, metadata

Typography Principles

  • Headlines can rotate. Use rotate-[-2deg] to rotate-[-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

ContextWidth
Buttons, inputsborder-3
Cards, containersborder-3 or border-4
Emphasis/selectedborder-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-8 or gap-12 between major sections
  • Negative margins (-mt-4, -ml-2) to create overlap
  • Generous padding inside containers (p-6 to p-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-boxShadowY

Focus

Bold, visible focus rings — accessibility is revolutionary:

focus:outline-none focus:ring-2 focus:ring-border focus:ring-offset-2

Disabled

Desaturated, no shadow:

disabled:opacity-50 disabled:shadow-none disabled:cursor-not-allowed

Animation

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-3 minimum)
  • 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