Loading...
Loading...
Generate UI in Nothing's design language — monochrome, typographic, industrial with Swiss hierarchy and OLED blacks
npx skill4agent add aradotso/design-skills nothing-design-system-skillSkill by ara.so — Design Skills collection.
# Clone the repository
git clone https://github.com/dominikmartn/nothing-design-skill.git
# Copy to Claude Code skills directory
cp -r nothing-design-skill/nothing-design ~/.claude/skills/
# Or create skills directory if it doesn't exist
mkdir -p ~/.claude/skills
cp -r nothing-design-skill/nothing-design ~/.claude/skills/--nothing-bg-primary: #000000; /* True OLED black */
--nothing-bg-secondary: #0A0A0A; /* Elevated surfaces */
--nothing-bg-tertiary: #141414; /* Cards, panels */
--nothing-text-primary: #FFFFFF; /* Headlines, body */
--nothing-text-secondary: #A0A0A0; /* Supporting text */
--nothing-text-tertiary: #606060; /* Metadata, disabled */
--nothing-border: #1F1F1F; /* Dividers, outlines */
--nothing-accent: #FF0000; /* Rare accent color */--nothing-bg-primary: #FFFFFF;
--nothing-bg-secondary: #F5F5F5;
--nothing-bg-tertiary: #EBEBEB;
--nothing-text-primary: #000000;
--nothing-text-secondary: #606060;
--nothing-text-tertiary: #A0A0A0;
--nothing-border: #E0E0E0;
--nothing-accent: #FF0000;--nothing-space-xs: 4px; /* Tight inline gaps */
--nothing-space-s: 8px; /* Component padding */
--nothing-space-m: 16px; /* Standard spacing */
--nothing-space-l: 24px; /* Section gaps */
--nothing-space-xl: 40px; /* Major sections */<div class="nothing-progress">
<div class="nothing-progress-track">
<div class="nothing-progress-segment"></div>
<div class="nothing-progress-segment"></div>
<div class="nothing-progress-segment"></div>
<div class="nothing-progress-segment active"></div>
<div class="nothing-progress-segment active"></div>
<div class="nothing-progress-segment active"></div>
</div>
<span class="nothing-progress-label">60%</span>
</div>
<style>
.nothing-progress {
display: flex;
align-items: center;
gap: var(--nothing-space-s);
}
.nothing-progress-track {
flex: 1;
display: grid;
grid-auto-flow: column;
gap: 2px;
height: 4px;
}
.nothing-progress-segment {
background: var(--nothing-bg-tertiary);
border-radius: 0; /* Hard edges */
}
.nothing-progress-segment.active {
background: var(--nothing-text-primary);
}
.nothing-progress-label {
font-family: 'Space Mono', monospace;
font-size: 11px;
color: var(--nothing-text-tertiary);
letter-spacing: 0.05em;
}
</style>// NothingButton.jsx
export default function NothingButton({
children,
variant = 'primary',
size = 'md',
onClick
}) {
const baseClasses = "uppercase tracking-wider font-medium transition-all duration-150";
const variants = {
primary: "bg-white text-black hover:bg-gray-200 active:bg-gray-300",
secondary: "bg-transparent border border-white/20 text-white hover:bg-white/5",
ghost: "bg-transparent text-white hover:bg-white/10"
};
const sizes = {
sm: "px-4 py-2 text-xs",
md: "px-6 py-3 text-sm",
lg: "px-8 py-4 text-base"
};
return (
<button
className={`${baseClasses} ${variants[variant]} ${sizes[size]}`}
onClick={onClick}
>
<span className="font-['Space_Grotesk']">{children}</span>
</button>
);
}
// Usage
<NothingButton variant="primary" size="md">
Start Now
</NothingButton>struct NothingToggle: View {
@Binding var isOn: Bool
var body: some View {
HStack(spacing: 2) {
Rectangle()
.fill(isOn ? Color.white : Color(hex: "141414"))
.frame(width: 24, height: 24)
.overlay(
Text(isOn ? "I" : "")
.font(.custom("Space Mono", size: 11))
.foregroundColor(.black)
)
Rectangle()
.fill(isOn ? Color(hex: "141414") : Color.white)
.frame(width: 24, height: 24)
.overlay(
Text(!isOn ? "O" : "")
.font(.custom("Space Mono", size: 11))
.foregroundColor(.black)
)
}
.onTapGesture {
withAnimation(.linear(duration: 0.15)) {
isOn.toggle()
}
}
}
}
// Usage
@State private var enabled = false
NothingToggle(isOn: $enabled)<article class="nothing-card">
<div class="nothing-card-header">
<h3 class="nothing-display">Battery Status</h3>
<span class="nothing-metadata">SYSTEM</span>
</div>
<div class="nothing-card-body">
<div class="nothing-dotmatrix">
<span class="nothing-dotmatrix-value">87%</span>
</div>
<p class="nothing-body">Estimated 4h 23m remaining</p>
</div>
</article>
<style>
@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;700&family=Space+Mono:wght@400&display=swap');
.nothing-card {
background: var(--nothing-bg-secondary);
border: 1px solid var(--nothing-border);
padding: var(--nothing-space-l);
}
.nothing-card-header {
display: flex;
justify-content: space-between;
align-items: baseline;
margin-bottom: var(--nothing-space-m);
}
.nothing-display {
font-family: 'Space Grotesk', sans-serif;
font-size: 24px;
font-weight: 700;
color: var(--nothing-text-primary);
margin: 0;
}
.nothing-metadata {
font-family: 'Space Mono', monospace;
font-size: 11px;
color: var(--nothing-text-tertiary);
letter-spacing: 0.1em;
text-transform: uppercase;
}
.nothing-body {
font-family: 'Space Grotesk', sans-serif;
font-size: 14px;
color: var(--nothing-text-secondary);
margin: var(--nothing-space-s) 0 0;
}
.nothing-dotmatrix {
background: repeating-linear-gradient(
0deg,
transparent,
transparent 2px,
var(--nothing-border) 2px,
var(--nothing-border) 3px
);
padding: var(--nothing-space-s);
margin-bottom: var(--nothing-space-s);
}
.nothing-dotmatrix-value {
font-family: 'Space Mono', monospace;
font-size: 32px;
font-weight: 700;
color: var(--nothing-text-primary);
display: block;
text-align: center;
}
</style><!-- In <head> -->
<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=Space+Grotesk:wght@400;500;700&family=Space+Mono:wght@400;700&display=swap" rel="stylesheet">// theme-switcher.js
const toggleTheme = () => {
const root = document.documentElement;
const currentTheme = root.getAttribute('data-theme');
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
root.setAttribute('data-theme', newTheme);
localStorage.setItem('nothing-theme', newTheme);
};
// Apply saved theme on load
const savedTheme = localStorage.getItem('nothing-theme') || 'dark';
document.documentElement.setAttribute('data-theme', savedTheme);:root {
--nothing-bg-primary: #000000;
--nothing-text-primary: #FFFFFF;
/* ... dark mode tokens ... */
}
[data-theme="light"] {
--nothing-bg-primary: #FFFFFF;
--nothing-text-primary: #000000;
/* ... light mode tokens ... */
}// NothingTheme.swift
struct NothingTheme: EnvironmentKey {
static let defaultValue = NothingColorScheme.dark
}
extension EnvironmentValues {
var nothingTheme: NothingColorScheme {
get { self[NothingTheme.self] }
set { self[NothingTheme.self] = newValue }
}
}
struct NothingColorScheme {
let bgPrimary: Color
let textPrimary: Color
// ... other tokens ...
static let dark = NothingColorScheme(
bgPrimary: Color(hex: "000000"),
textPrimary: Color.white
)
static let light = NothingColorScheme(
bgPrimary: Color.white,
textPrimary: Color(hex: "000000")
)
}font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;body {
background: #000000; /* Not #000 or rgb(0,0,0) if using color profiles */
color: #FFFFFF;
}.nothing-progress-track {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
gap: 2px; /* Fixed gap, not margin */
}[data-theme="light"] {
--nothing-text-primary: #000000; /* Not gray */
--nothing-text-secondary: #606060; /* Minimum WCAG AA */
}@keyframes nothing-fill {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
.nothing-progress-segment.active {
animation: nothing-fill 0.3s cubic-bezier(0.4, 0, 0.2, 1);
transform-origin: left;
}.nothing-dotmatrix-bg {
background-image:
radial-gradient(circle, var(--nothing-text-tertiary) 1px, transparent 1px);
background-size: 4px 4px;
background-position: 0 0;
}function NothingCounter({ value, digits = 4 }) {
const formatted = String(value).padStart(digits, '0');
return (
<div className="flex gap-0.5">
{formatted.split('').map((digit, i) => (
<div
key={i}
className="bg-[#141414] border border-[#1F1F1F] w-8 h-12 flex items-center justify-center"
>
<span className="font-['Space_Mono'] text-xl text-white">
{digit}
</span>
</div>
))}
</div>
);
}