Web Pages Medium
Redline Portfolio
A minimal dark portfolio with high-contrast red and black design, smooth animations, and a focus on UI systems and capabilities.
Open in Lab
MCP
html css javascript gsap lenis threejs
Targets: JS HTML
Code
:root {
color-scheme: only dark;
--bg: #050506;
--panel: #0d0d10;
--red: #ff2b2b;
--red-soft: rgba(255, 43, 43, 0.2);
--fg: #f6f6f8;
--muted: rgba(246, 246, 248, 0.65);
}
* {
box-sizing: border-box;
}
body {
margin: 0;
min-height: 100vh;
font-family: "Lettering Gothic", "Oswald", "Segoe UI", sans-serif;
background: radial-gradient(circle at 20% 0%, rgba(255, 43, 43, 0.08), transparent 55%),
radial-gradient(circle at 80% 10%, rgba(255, 43, 43, 0.06), transparent 60%), var(--bg);
color: var(--fg);
}
body.dark-armed {
background: radial-gradient(circle at 50% 20%, rgba(255, 43, 43, 0.18), transparent 55%),
radial-gradient(circle at 20% 80%, rgba(255, 43, 43, 0.14), transparent 60%), var(--bg);
}
.page {
max-width: 1200px;
margin: 0 auto;
padding: 32px clamp(20px, 6vw, 80px) 80px;
}
.nav {
display: flex;
align-items: center;
justify-content: space-between;
gap: 24px;
margin-bottom: 32px;
padding-bottom: 20px;
border-bottom: 1px solid rgba(255, 43, 43, 0.2);
}
.logo {
font-family: "Lettering Gothic", "Oswald", sans-serif;
text-transform: uppercase;
letter-spacing: 0.2em;
color: var(--red);
}
.nav-links {
display: flex;
gap: 20px;
}
.nav a {
color: var(--muted);
text-decoration: none;
text-transform: uppercase;
letter-spacing: 0.12em;
font-size: 0.75rem;
position: relative;
}
.nav a::after {
content: "";
position: absolute;
left: 0;
bottom: -6px;
width: 100%;
height: 2px;
background: var(--red);
transform: scaleX(0);
transform-origin: left;
transition: transform 0.3s ease;
}
.nav a:hover::after {
transform: scaleX(1);
}
.hero {
display: grid;
grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
gap: 32px;
padding-bottom: 40px;
border-bottom: 1px solid rgba(255, 43, 43, 0.2);
}
.tag {
font-family: "Lettering Gothic", "Oswald", sans-serif;
text-transform: uppercase;
letter-spacing: 0.2em;
color: var(--red);
margin: 0 0 12px;
}
.hero h1 {
font-family: "Lettering Gothic", "Oswald", sans-serif;
font-size: clamp(2.5rem, 5vw, 4rem);
margin: 0 0 16px;
}
.lead {
color: var(--muted);
max-width: 55ch;
}
.actions {
display: flex;
gap: 16px;
margin-top: 24px;
}
.dark-toggle,
.outline {
padding: 0.85rem 1.6rem;
border-radius: 999px;
border: 1px solid var(--red);
background: transparent;
color: var(--fg);
text-transform: uppercase;
letter-spacing: 0.2em;
font-size: 0.7rem;
cursor: pointer;
position: relative;
overflow: hidden;
}
.dark-toggle::before {
content: "";
position: absolute;
inset: 0;
background: var(--red);
transform: translateX(-100%);
transition: transform 0.4s ease;
z-index: 0;
}
.dark-toggle span,
.dark-toggle {
position: relative;
z-index: 1;
}
.dark-toggle:hover::before {
transform: translateX(0);
}
.dark-toggle.active::before {
transform: translateX(0);
}
.dark-toggle.active {
color: #050506;
}
.outline {
border-color: rgba(255, 43, 43, 0.5);
}
.hero-panel {
background: var(--panel);
border: 1px solid rgba(255, 43, 43, 0.25);
border-radius: 18px;
padding: 24px;
display: grid;
gap: 16px;
}
.panel-row {
display: flex;
justify-content: space-between;
color: var(--muted);
}
.panel-row strong {
color: var(--red);
}
.section {
padding: 48px 0;
}
.section-header {
display: flex;
justify-content: space-between;
align-items: baseline;
gap: 16px;
}
.section-header p {
color: var(--muted);
}
.grid {
margin-top: 24px;
display: grid;
gap: 20px;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.card {
padding: 20px;
border-radius: 16px;
background: var(--panel);
border: 1px solid rgba(255, 43, 43, 0.2);
}
.card h3 {
margin: 12px 0 8px;
}
.card p {
color: var(--muted);
}
.card span {
font-size: 0.85rem;
color: var(--red);
text-transform: uppercase;
letter-spacing: 0.15em;
}
.split {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 24px;
}
.list {
list-style: none;
padding: 0;
margin: 16px 0 0;
display: grid;
gap: 12px;
}
.list li {
padding: 12px 16px;
border-radius: 12px;
border: 1px solid rgba(255, 43, 43, 0.2);
background: rgba(13, 13, 16, 0.7);
}
.pill-grid {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 16px;
}
.pill-grid span {
padding: 8px 14px;
border-radius: 999px;
border: 1px solid rgba(255, 43, 43, 0.4);
font-size: 0.75rem;
}
.stats {
display: grid;
gap: 20px;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}
.stats div {
background: var(--panel);
border: 1px solid rgba(255, 43, 43, 0.2);
border-radius: 16px;
padding: 20px;
text-align: center;
}
.stats h2 {
margin: 0 0 8px;
font-family: "Lettering Gothic", "Oswald", sans-serif;
font-size: 2rem;
color: var(--red);
}
.contact-cards {
display: grid;
gap: 16px;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
.contact-card {
padding: 18px;
border-radius: 14px;
background: var(--panel);
border: 1px solid rgba(255, 43, 43, 0.2);
}
.contact-card p {
margin: 6px 0 0;
color: var(--muted);
}
@media (max-width: 900px) {
.nav {
flex-direction: column;
align-items: flex-start;
}
.nav-links {
flex-wrap: wrap;
}
.hero {
grid-template-columns: 1fr;
}
}const data = {
projects: [
{
title: "Crimson Grid",
desc: "Minimal admin UI with redline accents and rapid navigation.",
tag: "UI",
},
{
title: "Shadow Runner",
desc: "Landing system for a stealth game brand rollout.",
tag: "Brand",
},
{
title: "Night Signal",
desc: "Realtime dashboard tuned for low-light control rooms.",
tag: "Data",
},
{
title: "Blacksite",
desc: "Secure onboarding flow with multi-step verification.",
tag: "Product",
},
],
capabilities: [
"High-contrast UI systems",
"Motion timing and easing",
"Brand systems for dark interfaces",
"Interactive dashboards",
],
stack: ["Figma", "GSAP", "Lenis", "Three.js", "TypeScript", "WebGL"],
stats: [
{ value: "18", label: "Launches completed" },
{ value: "7", label: "Active retainers" },
{ value: "96%", label: "On-time delivery" },
],
contacts: [
{ label: "Email", value: "redline@studio.com" },
{ label: "LinkedIn", value: "/redline" },
{ label: "GitHub", value: "@redline" },
],
};
const projectGrid = document.getElementById("project-grid");
const capabilityList = document.getElementById("capabilities");
const stackGrid = document.getElementById("stack");
const statsGrid = document.getElementById("stats");
const contactGrid = document.getElementById("contact-cards");
if (projectGrid) {
projectGrid.innerHTML = data.projects
.map(
(project) => `
<article class="card">
<span>${project.tag}</span>
<h3>${project.title}</h3>
<p>${project.desc}</p>
</article>
`
)
.join("");
}
if (capabilityList) {
capabilityList.innerHTML = data.capabilities.map((item) => `<li>${item}</li>`).join("");
}
if (stackGrid) {
stackGrid.innerHTML = data.stack.map((item) => `<span>${item}</span>`).join("");
}
if (statsGrid) {
statsGrid.innerHTML = data.stats
.map(
(stat) => `
<div>
<h2>${stat.value}</h2>
<p>${stat.label}</p>
</div>
`
)
.join("");
}
if (contactGrid) {
contactGrid.innerHTML = data.contacts
.map(
(contact) => `
<article class="contact-card">
<h4>${contact.label}</h4>
<p>${contact.value}</p>
</article>
`
)
.join("");
}
const lenis = window.Lenis
? new Lenis({
smoothWheel: true,
smoothTouch: false,
})
: null;
function raf(time) {
if (lenis) lenis.raf(time);
requestAnimationFrame(raf);
}
requestAnimationFrame(raf);
gsap.from(".hero", {
opacity: 0,
y: 40,
duration: 1,
ease: "power3.out",
});
gsap.utils.toArray(".card, .list li, .pill-grid span, .stats div").forEach((item, index) => {
gsap.from(item, {
opacity: 0,
y: 20,
duration: 0.8,
delay: index * 0.04,
ease: "power2.out",
});
});
const toggle = document.getElementById("dark-toggle");
if (toggle) {
toggle.addEventListener("click", () => {
const isActive = toggle.classList.toggle("active");
document.body.classList.toggle("dark-armed", isActive);
toggle.setAttribute("aria-pressed", String(isActive));
});
}<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Redline Portfolio</title>
<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=Oswald:wght@400;600;700&family=Manrope:wght@400;500;600&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<main class="page">
<nav class="nav">
<div class="logo">Redline</div>
<div class="nav-links">
<a href="#projects">Projects</a>
<a href="#skills">Skills</a>
<a href="#contact">Contact</a>
</div>
<button class="outline">Access</button>
</nav>
<header class="hero">
<div>
<p class="tag">Redline Interface</p>
<h1>Dark. Focused. Red.</h1>
<p class="lead">Sample portfolio data with a strict black and red palette.</p>
<div class="actions">
<button class="dark-toggle" id="dark-toggle">Dark Button</button>
<button class="outline">View Log</button>
</div>
</div>
<div class="hero-panel">
<div class="panel-row">
<span>Status</span>
<strong>Active</strong>
</div>
<div class="panel-row">
<span>Focus</span>
<strong>UI Systems</strong>
</div>
<div class="panel-row">
<span>Region</span>
<strong>Sector 13</strong>
</div>
</div>
</header>
<section class="section" id="projects">
<div class="section-header">
<h2>Projects</h2>
<p>High-contrast experiences with precise motion.</p>
</div>
<div class="grid" id="project-grid"></div>
</section>
<section class="section split" id="skills">
<div>
<h2>Capabilities</h2>
<ul class="list" id="capabilities"></ul>
</div>
<div>
<h2>Stack</h2>
<div class="pill-grid" id="stack"></div>
</div>
</section>
<section class="section stats" id="stats"></section>
<section class="section" id="contact">
<div class="section-header">
<h2>Contact</h2>
<p>Ready to build in the dark.</p>
</div>
<div class="contact-cards" id="contact-cards"></div>
</section>
</main>
<script src="https://cdn.jsdelivr.net/npm/@studio-freight/lenis@1.0.42/bundled/lenis.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.min.js"></script>
<script src="script.js"></script>
</body>
</html>Redline Portfolio
A minimal, high-contrast portfolio design featuring a strict black and red color palette. Built with focus on UI systems, capabilities, and clean data presentation.
How it works
The portfolio uses a data-driven approach with dynamic content generation:
- Data Structure — Projects, capabilities, stack, and stats defined in JavaScript
- GSAP Animations — Smooth fade-in animations for cards and content
- Lenis Smooth Scroll — Enhanced scrolling experience
- Dark Mode Toggle — Interactive button to switch between light and dark backgrounds
- Grid Layouts — Responsive grid systems for projects and contact cards
Key features
- High-contrast red and black design
- Data-driven content generation
- Smooth GSAP animations
- Dark mode toggle functionality
- Responsive grid layouts
- Minimal, focused UI
- Clean typography with Oswald and Manrope fonts
When to use it
- UI/UX designer portfolios
- Minimal portfolio designs
- High-contrast interfaces
- Data-focused presentations
- Creative agency showcases