NES Retro / Pixel
Chunky pixel fonts, limited 4-color palettes, and scanline overlays — interface design inspired by 8-bit Nintendo consoles.
MCP
Code
/* ============================================================
NES RETRO / PIXEL — Style Showcase
Font: Press Start 2P (Google Fonts)
Palette: #00FF7F | #FF4500 | #4169E1 | #FFD700 | #FFFFFF
============================================================ */
@import url("https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap");
/* --- Root variables --- */
:root {
--green: #00ff7f;
--red: #ff4500;
--blue: #4169e1;
--gold: #ffd700;
--white: #ffffff;
--bg: #0b0b0b;
--panel: #1a1a2e;
--text: #e8e8e8;
--muted: #888888;
--font: "Press Start 2P", monospace;
}
/* --- Reset & base --- */
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
image-rendering: pixelated;
image-rendering: crisp-edges;
}
html {
font-size: 16px;
}
body {
background-color: var(--bg);
color: var(--text);
font-family: var(--font);
font-size: 8px;
line-height: 1.8;
min-height: 100vh;
position: relative;
overflow-x: hidden;
}
/* CRT Scanlines overlay */
body::after {
content: "";
position: fixed;
inset: 0;
pointer-events: none;
z-index: 9999;
background: repeating-linear-gradient(
to bottom,
transparent 0px,
transparent 2px,
rgba(0, 0, 0, 0.15) 3px,
rgba(0, 0, 0, 0.15) 4px
);
}
/* --- Scrollbar --- */
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: var(--panel);
}
::-webkit-scrollbar-thumb {
background: var(--green);
}
/* --- Header --- */
.site-header {
border-bottom: 4px solid var(--green);
background: var(--panel);
box-shadow: 0 4px 0 var(--green);
position: sticky;
top: 0;
z-index: 100;
}
.header-inner {
max-width: 900px;
margin: 0 auto;
padding: 12px 20px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
}
.header-logo {
font-size: 10px;
color: var(--green);
display: flex;
align-items: center;
gap: 8px;
text-shadow: 2px 2px 0 #004d30;
}
.pixel-icon {
color: var(--gold);
font-size: 12px;
}
.header-nav {
display: flex;
gap: 16px;
}
.nav-link {
color: var(--muted);
text-decoration: none;
font-size: 8px;
padding: 4px 8px;
border: 2px solid transparent;
transition: color 0.1s, border-color 0.1s;
}
.nav-link:hover,
.nav-active {
color: var(--green);
border: 2px solid var(--green);
box-shadow: 2px 2px 0 var(--green);
}
.lives-display {
display: flex;
gap: 4px;
}
.heart {
color: var(--red);
font-size: 14px;
text-shadow: 2px 2px 0 #7a1500;
animation: pulse-heart 1.5s ease-in-out infinite;
}
.heart:nth-child(2) {
animation-delay: 0.3s;
}
.heart:nth-child(3) {
animation-delay: 0.6s;
}
@keyframes pulse-heart {
0%,
100% {
transform: scale(1);
}
50% {
transform: scale(1.2);
}
}
/* --- Hero --- */
.hero {
text-align: center;
padding: 48px 20px 40px;
position: relative;
background: linear-gradient(180deg, #0b0b0b 0%, #1a1a2e 100%);
border-bottom: 4px solid var(--green);
}
.hero-tagline {
color: var(--gold);
font-size: 8px;
letter-spacing: 0.1em;
margin-bottom: 20px;
animation: blink 1.2s step-end infinite;
}
.hero-title {
font-size: clamp(18px, 4vw, 36px);
color: var(--green);
line-height: 1.4;
text-shadow: 4px 4px 0 #004d30, 8px 8px 0 rgba(0, 255, 127, 0.15);
margin-bottom: 16px;
}
.hero-sub {
color: var(--blue);
font-size: 8px;
margin-bottom: 20px;
text-shadow: 2px 2px 0 #1a2e7a;
}
.blink-cursor {
color: var(--green);
font-size: 20px;
animation: blink 0.8s step-end infinite;
}
@keyframes blink {
0%,
49% {
opacity: 1;
}
50%,
100% {
opacity: 0;
}
}
/* --- Main content --- */
.main-content {
max-width: 900px;
margin: 0 auto;
padding: 32px 20px 80px;
display: flex;
flex-direction: column;
gap: 28px;
}
/* --- Card --- */
.card {
background: var(--panel);
border: 4px solid var(--green);
box-shadow: 4px 4px 0 var(--green);
padding: 0;
}
.card-title-bar {
background: var(--green);
color: var(--bg);
font-size: 8px;
padding: 8px 12px;
display: flex;
align-items: center;
gap: 8px;
letter-spacing: 0.05em;
}
.title-bar-icon {
font-size: 8px;
flex-shrink: 0;
}
/* --- Profile card --- */
.profile-body {
padding: 20px;
display: flex;
gap: 20px;
align-items: flex-start;
flex-wrap: wrap;
}
/* Pixel avatar */
.avatar-wrap {
flex-shrink: 0;
}
.avatar {
display: grid;
gap: 0;
border: 4px solid var(--green);
box-shadow: 4px 4px 0 var(--gold);
}
.px-row {
display: flex;
}
.px {
width: 12px;
height: 12px;
display: block;
}
.px.dark {
background: #0b0b0b;
}
.px.skin {
background: #f4a460;
}
.px.blue {
background: var(--blue);
}
.profile-info {
flex: 1;
min-width: 200px;
}
.profile-name {
font-size: 12px;
color: var(--green);
text-shadow: 2px 2px 0 #004d30;
margin-bottom: 8px;
}
.profile-role {
font-size: 8px;
color: var(--gold);
margin-bottom: 16px;
}
/* HP bar */
.hp-bar-wrap {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 16px;
}
.hp-label {
font-size: 8px;
color: var(--red);
flex-shrink: 0;
text-shadow: 1px 1px 0 #7a1500;
}
.hp-track {
flex: 1;
height: 12px;
background: #0b0b0b;
border: 2px solid var(--red);
position: relative;
overflow: hidden;
}
.hp-fill {
height: 100%;
background: repeating-linear-gradient(
90deg,
var(--red) 0px,
var(--red) 8px,
#7a1500 8px,
#7a1500 10px
);
transition: width 0.3s steps(10);
}
.hp-val {
font-size: 7px;
color: var(--muted);
flex-shrink: 0;
}
/* Profile stats */
.profile-stats {
display: flex;
gap: 12px;
flex-wrap: wrap;
}
.stat-box {
background: #0b0b0b;
border: 2px solid var(--gold);
padding: 8px 12px;
text-align: center;
box-shadow: 2px 2px 0 var(--gold);
display: flex;
flex-direction: column;
gap: 4px;
}
.stat-num {
font-size: 10px;
color: var(--gold);
display: block;
}
.stat-lbl {
font-size: 7px;
color: var(--muted);
display: block;
}
/* --- Buttons --- */
.button-row {
padding: 20px;
display: flex;
flex-wrap: wrap;
gap: 16px;
align-items: center;
}
.btn {
font-family: var(--font);
font-size: 8px;
cursor: pointer;
border: none;
padding: 12px 20px;
letter-spacing: 0.04em;
transition: transform 0.05s, box-shadow 0.05s;
user-select: none;
position: relative;
outline: none;
}
.btn:focus-visible {
outline: 2px dashed var(--gold);
outline-offset: 4px;
}
/* Primary */
.btn-primary {
background: var(--green);
color: #0b0b0b;
box-shadow: 4px 4px 0 #004d30;
}
.btn-primary:hover {
background: #00e873;
transform: translate(-2px, -2px);
box-shadow: 6px 6px 0 #004d30;
}
.btn-primary:active,
.btn-primary.pressed {
transform: translate(4px, 4px);
box-shadow: 0 0 0 #004d30;
}
/* Secondary */
.btn-secondary {
background: var(--blue);
color: var(--white);
box-shadow: 4px 4px 0 #1a2e7a;
}
.btn-secondary:hover {
background: #5a7de8;
transform: translate(-2px, -2px);
box-shadow: 6px 6px 0 #1a2e7a;
}
.btn-secondary:active,
.btn-secondary.pressed {
transform: translate(4px, 4px);
box-shadow: 0 0 0 #1a2e7a;
}
/* Ghost */
.btn-ghost {
background: transparent;
color: var(--gold);
border: 4px solid var(--gold);
box-shadow: 4px 4px 0 #7a5c00;
}
.btn-ghost:hover {
background: rgba(255, 215, 0, 0.1);
transform: translate(-2px, -2px);
box-shadow: 6px 6px 0 #7a5c00;
}
.btn-ghost:active,
.btn-ghost.pressed {
transform: translate(4px, 4px);
box-shadow: 0 0 0 #7a5c00;
}
/* --- Input --- */
.input-group {
padding: 20px;
}
.input-label {
display: block;
font-size: 8px;
color: var(--green);
margin-bottom: 10px;
letter-spacing: 0.08em;
}
.input-wrap {
position: relative;
display: inline-block;
width: 100%;
}
.pixel-input {
font-family: var(--font);
font-size: 9px;
background: #0b0b0b;
color: var(--green);
border: 4px solid var(--green);
padding: 10px 14px 10px 14px;
width: 100%;
max-width: 360px;
box-shadow: inset 2px 2px 0 rgba(0, 0, 0, 0.5);
caret-color: var(--green);
outline: none;
}
.pixel-input::placeholder {
color: var(--muted);
opacity: 0.6;
}
.pixel-input:focus {
border-color: var(--gold);
box-shadow: 0 0 0 2px var(--gold), inset 2px 2px 0 rgba(0, 0, 0, 0.5);
color: var(--white);
}
.input-hint {
margin-top: 8px;
font-size: 7px;
color: var(--muted);
}
/* --- Badges --- */
.badge-row {
padding: 20px;
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.badge {
font-family: var(--font);
font-size: 7px;
padding: 6px 10px;
display: inline-flex;
align-items: center;
gap: 6px;
}
.badge-green {
background: #004d30;
color: var(--green);
border: 2px solid var(--green);
box-shadow: 2px 2px 0 var(--green);
}
.badge-gold {
background: #3d2e00;
color: var(--gold);
border: 2px solid var(--gold);
box-shadow: 2px 2px 0 var(--gold);
}
.badge-blue {
background: #0d1a4a;
color: #7a9fff;
border: 2px solid var(--blue);
box-shadow: 2px 2px 0 var(--blue);
}
.badge-red {
background: #3d0a00;
color: #ff7a5a;
border: 2px solid var(--red);
box-shadow: 2px 2px 0 var(--red);
}
/* --- Score ticker --- */
.score-ticker {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background: var(--green);
color: #0b0b0b;
overflow: hidden;
white-space: nowrap;
height: 28px;
display: flex;
align-items: center;
border-top: 4px solid #004d30;
z-index: 50;
}
.ticker-inner {
display: inline-block;
font-size: 8px;
padding-left: 100%;
animation: ticker 18s linear infinite;
}
@keyframes ticker {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-100%);
}
}
/* --- Responsive --- */
@media (max-width: 600px) {
.header-inner {
flex-wrap: wrap;
gap: 10px;
}
.profile-body {
flex-direction: column;
}
.hero-title {
font-size: 18px;
}
.button-row {
flex-direction: column;
align-items: flex-start;
}
.btn {
width: 100%;
text-align: center;
}
}/* ============================================================
NES RETRO / PIXEL — Interactive Script
- Pixel press effect on button click
- Hover scale flash
- Simulated HP bar damage animation
- Scanline flicker on page load
- Score counter easter egg
============================================================ */
(function () {
"use strict";
/* ----------------------------------------------------------
1. Pixel button press effect
---------------------------------------------------------- */
const buttons = document.querySelectorAll(".btn[data-pixel-sound]");
buttons.forEach(function (btn) {
btn.addEventListener("click", function () {
btn.classList.add("pressed");
// Flash the button color briefly
const originalBg = btn.style.background;
if (btn.classList.contains("btn-primary")) {
btn.style.background = "#FFFFFF";
btn.style.color = "#0B0B0B";
} else if (btn.classList.contains("btn-secondary")) {
btn.style.background = "#FFFFFF";
btn.style.color = "#4169E1";
} else if (btn.classList.contains("btn-ghost")) {
btn.style.background = "rgba(255,215,0,0.3)";
}
setTimeout(function () {
btn.classList.remove("pressed");
btn.style.background = "";
btn.style.color = "";
}, 120);
});
// Hover scale pop
btn.addEventListener("mouseenter", function () {
btn.style.transform = "translate(-2px, -2px)";
});
btn.addEventListener("mouseleave", function () {
btn.style.transform = "";
});
});
/* ----------------------------------------------------------
2. HP bar animation on load
---------------------------------------------------------- */
const hpFill = document.querySelector(".hp-fill");
if (hpFill) {
const targetWidth = hpFill.style.width || "74%";
hpFill.style.width = "0%";
// Drain from full to target, simulating damage received
let current = 100;
const target = parseInt(targetWidth, 10);
const decrement = (100 - target) / 20;
const hpInterval = setInterval(function () {
if (current <= target) {
hpFill.style.width = target + "%";
clearInterval(hpInterval);
return;
}
current -= decrement;
hpFill.style.width = Math.max(current, target) + "%";
}, 40);
}
/* ----------------------------------------------------------
3. Score counter easter egg — click the logo to increment
---------------------------------------------------------- */
const logo = document.querySelector(".header-logo");
const ticker = document.querySelector(".ticker-inner");
let score = 0;
if (logo && ticker) {
logo.style.cursor = "pointer";
logo.title = "Click for points!";
logo.addEventListener("click", function () {
score += 100;
// Flash logo
logo.style.color = "#FFD700";
setTimeout(function () {
logo.style.color = "";
}, 200);
// Spawn floating +100 label
const float = document.createElement("span");
float.textContent = "+100";
float.style.cssText = [
"position: fixed",
'font-family: "Press Start 2P", monospace',
"font-size: 10px",
"color: #FFD700",
"pointer-events: none",
"z-index: 10000",
"text-shadow: 2px 2px 0 #0B0B0B",
"animation: floatUp 0.8s ease-out forwards",
"left: " + (logo.getBoundingClientRect().left + 20) + "px",
"top: " + (logo.getBoundingClientRect().top + 10) + "px",
].join(";");
document.body.appendChild(float);
setTimeout(function () {
float.remove();
}, 800);
// Update ticker text
ticker.textContent = ticker.textContent.replace(
/HIGH SCORE: [\d,]+/,
"HIGH SCORE: " + score.toLocaleString()
);
});
}
// Float-up keyframe injection
const styleEl = document.createElement("style");
styleEl.textContent = `
@keyframes floatUp {
0% { opacity: 1; transform: translateY(0); }
100% { opacity: 0; transform: translateY(-40px); }
}
`;
document.head.appendChild(styleEl);
/* ----------------------------------------------------------
4. Scanline flicker on page load (CRT power-on effect)
---------------------------------------------------------- */
document.body.style.opacity = "0";
let flickerCount = 0;
const maxFlickers = 5;
const flicker = setInterval(function () {
flickerCount++;
document.body.style.opacity = flickerCount % 2 === 0 ? "0" : "0.85";
if (flickerCount >= maxFlickers) {
clearInterval(flicker);
document.body.style.opacity = "1";
document.body.style.transition = "opacity 0.1s";
}
}, 60);
/* ----------------------------------------------------------
5. Pixel input: play with characters counter
---------------------------------------------------------- */
const playerInput = document.getElementById("player-name");
const hintEl = document.querySelector(".input-hint");
if (playerInput && hintEl) {
playerInput.addEventListener("input", function () {
const remaining = 10 - playerInput.value.length;
if (remaining <= 0) {
hintEl.textContent = "MAX REACHED!";
hintEl.style.color = "#FF4500";
} else {
hintEl.textContent = remaining + " CHARS REMAINING";
hintEl.style.color = "";
}
});
}
/* ----------------------------------------------------------
6. Stat boxes — wobble on hover
---------------------------------------------------------- */
const statBoxes = document.querySelectorAll(".stat-box");
statBoxes.forEach(function (box) {
box.style.cursor = "pointer";
box.addEventListener("mouseenter", function () {
box.style.transform = "translate(-2px, -2px)";
box.style.boxShadow = "4px 4px 0 #FFD700";
});
box.addEventListener("mouseleave", function () {
box.style.transform = "";
box.style.boxShadow = "";
});
});
})();<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<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=Press+Start+2P&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
<title>NES Retro / Pixel</title>
</head>
<body>
<!-- Header -->
<header class="site-header">
<div class="header-inner">
<div class="header-logo">
<span class="pixel-icon">■</span>
PIXEL UI
</div>
<nav class="header-nav">
<a href="#" class="nav-link">START</a>
<a href="#" class="nav-link">SELECT</a>
<a href="#" class="nav-link nav-active">PLAY</a>
</nav>
<div class="lives-display">
<span class="heart">♥</span>
<span class="heart">♥</span>
<span class="heart">♥</span>
</div>
</div>
</header>
<!-- Hero -->
<section class="hero">
<p class="hero-tagline">INSERT COIN TO CONTINUE</p>
<h1 class="hero-title">NES RETRO<br />DESIGN</h1>
<p class="hero-sub">8-BIT AESTHETICS FOR THE MODERN WEB</p>
<div class="blink-cursor" aria-hidden="true">▮</div>
</section>
<!-- Main content -->
<main class="main-content">
<!-- Profile Card -->
<section class="card profile-card">
<div class="card-title-bar">
<span class="title-bar-icon">■</span>
PLAYER PROFILE
<span class="title-bar-icon">■</span>
</div>
<div class="profile-body">
<div class="avatar-wrap">
<div class="avatar">
<!-- pixel face -->
<div class="px-row">
<span class="px dark"></span><span class="px dark"></span><span class="px skin"></span><span class="px skin"></span><span class="px skin"></span><span class="px skin"></span><span class="px dark"></span><span class="px dark"></span>
</div>
<div class="px-row">
<span class="px dark"></span><span class="px skin"></span><span class="px dark"></span><span class="px skin"></span><span class="px skin"></span><span class="px dark"></span><span class="px skin"></span><span class="px dark"></span>
</div>
<div class="px-row">
<span class="px dark"></span><span class="px skin"></span><span class="px skin"></span><span class="px skin"></span><span class="px skin"></span><span class="px skin"></span><span class="px skin"></span><span class="px dark"></span>
</div>
<div class="px-row">
<span class="px dark"></span><span class="px skin"></span><span class="px skin"></span><span class="px skin"></span><span class="px skin"></span><span class="px skin"></span><span class="px skin"></span><span class="px dark"></span>
</div>
<div class="px-row">
<span class="px dark"></span><span class="px dark"></span><span class="px skin"></span><span class="px skin"></span><span class="px skin"></span><span class="px skin"></span><span class="px dark"></span><span class="px dark"></span>
</div>
<div class="px-row">
<span class="px blue"></span><span class="px blue"></span><span class="px blue"></span><span class="px blue"></span><span class="px blue"></span><span class="px blue"></span><span class="px blue"></span><span class="px blue"></span>
</div>
<div class="px-row">
<span class="px blue"></span><span class="px dark"></span><span class="px blue"></span><span class="px blue"></span><span class="px blue"></span><span class="px blue"></span><span class="px dark"></span><span class="px blue"></span>
</div>
<div class="px-row">
<span class="px dark"></span><span class="px dark"></span><span class="px dark"></span><span class="px dark"></span><span class="px dark"></span><span class="px dark"></span><span class="px dark"></span><span class="px dark"></span>
</div>
</div>
</div>
<div class="profile-info">
<div class="profile-name">PIXEL HERO</div>
<div class="profile-role">LEVEL 42 WARRIOR</div>
<div class="hp-bar-wrap">
<span class="hp-label">HP</span>
<div class="hp-track">
<div class="hp-fill" style="width: 74%"></div>
</div>
<span class="hp-val">74/100</span>
</div>
<div class="profile-stats">
<div class="stat-box">
<span class="stat-num">1,240</span>
<span class="stat-lbl">SCORE</span>
</div>
<div class="stat-box">
<span class="stat-num">42</span>
<span class="stat-lbl">LEVEL</span>
</div>
<div class="stat-box">
<span class="stat-num">99</span>
<span class="stat-lbl">WINS</span>
</div>
</div>
</div>
</div>
</section>
<!-- Buttons -->
<section class="card">
<div class="card-title-bar">
<span class="title-bar-icon">■</span>
ACTIONS
<span class="title-bar-icon">■</span>
</div>
<div class="button-row">
<button class="btn btn-primary" data-pixel-sound>► START GAME</button>
<button class="btn btn-secondary" data-pixel-sound>▶ CONTINUE</button>
<button class="btn btn-ghost" data-pixel-sound>◆ HIGH SCORE</button>
</div>
</section>
<!-- Input -->
<section class="card">
<div class="card-title-bar">
<span class="title-bar-icon">■</span>
ENTER NAME
<span class="title-bar-icon">■</span>
</div>
<div class="input-group">
<label class="input-label" for="player-name">PLAYER NAME</label>
<div class="input-wrap">
<input
id="player-name"
class="pixel-input"
type="text"
placeholder="HERO_01"
maxlength="10"
autocomplete="off"
/>
</div>
<div class="input-hint">MAX 10 CHARACTERS</div>
</div>
</section>
<!-- Badges -->
<section class="card">
<div class="card-title-bar">
<span class="title-bar-icon">■</span>
ACHIEVEMENTS
<span class="title-bar-icon">■</span>
</div>
<div class="badge-row">
<span class="badge badge-green">★ FIRST BLOOD</span>
<span class="badge badge-gold">◆ COMBO x10</span>
<span class="badge badge-blue">⇧ LEVEL UP</span>
<span class="badge badge-red">♥ NO DAMAGE</span>
<span class="badge badge-green">◆ SPEED RUN</span>
</div>
</section>
</main>
<!-- Score ticker -->
<div class="score-ticker" aria-hidden="true">
<span class="ticker-inner">
■ PRESS START ■ HIGH SCORE: 99,999 ■ PLAYER 1 ■ INSERT COIN ■ LEVEL SELECT ■ GAME OVER ■ CONTINUE? 9 8 7 6 5 4 3 2 1 ■
</span>
</div>
<script src="script.js"></script>
</body>
</html>NES Retro / Pixel
A full-page component showcase built on the visual language of 8-bit Nintendo consoles. Every pixel is intentional: square corners, chunky borders, phosphor-green accents, and the iconic Press Start 2P bitmap font that makes every headline feel like a title screen.
The scanline overlay — a repeating semi-transparent gradient applied via a body ::after pseudo-element — adds the CRT television warmth that makes the illusion complete. The HP bar, pixel-art box-shadow technique, and limited 4-color palette all reinforce the constraint-driven beauty of early home gaming hardware.
Key characteristics
Press Start 2PGoogle Font — a true pixel/bitmap typeface at 8–12 px- Hard 4-color palette:
#00FF7Fgreen,#FF4500red,#4169E1blue,#FFD700gold - Zero border-radius — every element is perfectly square
- Pixel drop-shadow via
box-shadow: 4px 4px 0 <color>(no blur) - CRT scanline overlay using
repeating-linear-gradienton a fixed pseudo-element - HP bar progress indicator styled as a game health meter
- Blinking cursor animation using
@keyframes blink
When to use it
Use this style for gaming dashboards, retro-themed landing pages, indie game project sites, portfolio pieces targeting game developers, or any product where nostalgia and personality are more important than polish. It pairs especially well with chiptune audio or pixel-art illustrations.