chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,516 @@
|
||||
<!-- Copyright 2026 Anthropic PBC · SPDX-License-Identifier: Apache-2.0 -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Empty state — four visual directions</title>
|
||||
<style>
|
||||
:root {
|
||||
--ivory: #FAF9F5;
|
||||
--slate: #141413;
|
||||
--clay: #D97757;
|
||||
--oat: #E3DACC;
|
||||
--olive: #788C5D;
|
||||
--gray-150: #F0EEE6;
|
||||
--gray-300: #D1CFC5;
|
||||
--gray-500: #87867F;
|
||||
--gray-700: #3D3D3A;
|
||||
--white: #FFFFFF;
|
||||
|
||||
--serif: ui-serif, Georgia, 'Times New Roman', serif;
|
||||
--sans: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
|
||||
--mono: ui-monospace, 'SF Mono', Menlo, Monaco, monospace;
|
||||
}
|
||||
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
|
||||
body {
|
||||
font-family: var(--sans);
|
||||
background: var(--ivory);
|
||||
color: var(--gray-700);
|
||||
line-height: 1.55;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
padding-bottom: 96px;
|
||||
}
|
||||
|
||||
/* ---------- sticky toolbar ---------- */
|
||||
|
||||
.toolbar {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
background: var(--ivory);
|
||||
border-bottom: 1.5px solid var(--gray-300);
|
||||
padding: 14px 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 18px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.toolbar .title {
|
||||
font-family: var(--mono);
|
||||
font-size: 12px;
|
||||
letter-spacing: 0.04em;
|
||||
color: var(--gray-500);
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.toolbar .field {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.toolbar .field > span {
|
||||
color: var(--gray-700);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.seg {
|
||||
display: inline-flex;
|
||||
border: 1.5px solid var(--gray-300);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
background: var(--white);
|
||||
}
|
||||
|
||||
.seg label {
|
||||
padding: 6px 14px;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
color: var(--gray-700);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.seg label + label {
|
||||
border-left: 1.5px solid var(--gray-300);
|
||||
}
|
||||
|
||||
.seg input { display: none; }
|
||||
|
||||
.seg input:checked + span {
|
||||
color: var(--slate);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.seg label:has(input:checked) {
|
||||
background: var(--oat);
|
||||
}
|
||||
|
||||
/* ---------- page header ---------- */
|
||||
|
||||
.page {
|
||||
max-width: 1240px;
|
||||
margin: 0 auto;
|
||||
padding: 48px 32px 0;
|
||||
}
|
||||
|
||||
header.page-head {
|
||||
max-width: 720px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.eyebrow {
|
||||
font-size: 12px;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
color: var(--gray-500);
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: var(--serif);
|
||||
font-weight: 500;
|
||||
font-size: 38px;
|
||||
line-height: 1.15;
|
||||
color: var(--slate);
|
||||
margin-bottom: 18px;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
.prompt-box {
|
||||
background: var(--gray-150);
|
||||
border: 1.5px solid var(--gray-300);
|
||||
border-radius: 12px;
|
||||
padding: 16px 20px;
|
||||
font-size: 14.5px;
|
||||
}
|
||||
|
||||
.prompt-box .label {
|
||||
font-family: var(--mono);
|
||||
font-size: 11px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
color: var(--gray-500);
|
||||
display: block;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
/* ---------- artboard grid ---------- */
|
||||
|
||||
.board {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
@media (max-width: 960px) {
|
||||
.board { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
.artboard {
|
||||
background: var(--white);
|
||||
border: 1.5px solid var(--gray-300);
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tag {
|
||||
position: absolute;
|
||||
top: 14px;
|
||||
left: 14px;
|
||||
font-family: var(--mono);
|
||||
font-size: 11px;
|
||||
letter-spacing: 0.02em;
|
||||
background: var(--oat);
|
||||
color: var(--slate);
|
||||
padding: 4px 10px;
|
||||
border-radius: 8px;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.stage {
|
||||
height: 280px;
|
||||
border-radius: 8px;
|
||||
border: 1.5px solid var(--gray-300);
|
||||
background: var(--ivory);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 24px;
|
||||
transition: background 0.15s, border-color 0.15s;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.stage.dark {
|
||||
background: var(--slate);
|
||||
border-color: var(--slate);
|
||||
}
|
||||
|
||||
.rationale {
|
||||
margin-top: 16px;
|
||||
font-size: 13px;
|
||||
color: var(--gray-500);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* =========================================================
|
||||
Empty-state variants — each scoped under .es-*
|
||||
Theme tokens flip when .stage.dark is present.
|
||||
========================================================= */
|
||||
|
||||
.stage { --fg: var(--slate); --muted: var(--gray-500); --line: var(--gray-300); --panel: var(--white); }
|
||||
.stage.dark { --fg: #F0EEE6; --muted: #9C9A93; --line: #3D3D3A; --panel: #1F1E1B; }
|
||||
|
||||
/* ---- A · Minimal ---- */
|
||||
|
||||
.es-a {
|
||||
text-align: center;
|
||||
max-width: 300px;
|
||||
}
|
||||
.es-a h3 {
|
||||
font-family: var(--serif);
|
||||
font-weight: 500;
|
||||
font-size: 19px;
|
||||
color: var(--fg);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.es-a p {
|
||||
font-size: 13px;
|
||||
color: var(--muted);
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
.es-a .btn {
|
||||
display: inline-block;
|
||||
font-size: 13px;
|
||||
color: var(--fg);
|
||||
border: 1.5px solid var(--line);
|
||||
border-radius: 8px;
|
||||
padding: 8px 16px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* ---- B · Illustrated ---- */
|
||||
|
||||
.es-b {
|
||||
text-align: center;
|
||||
max-width: 320px;
|
||||
}
|
||||
.es-b svg {
|
||||
display: block;
|
||||
margin: 0 auto 18px;
|
||||
}
|
||||
.es-b h3 {
|
||||
font-family: var(--serif);
|
||||
font-weight: 500;
|
||||
font-size: 19px;
|
||||
color: var(--fg);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.es-b p {
|
||||
font-size: 13px;
|
||||
color: var(--muted);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.es-b .btn {
|
||||
display: inline-block;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: var(--white);
|
||||
background: var(--clay);
|
||||
border-radius: 8px;
|
||||
padding: 8px 16px;
|
||||
}
|
||||
.stage.dark .es-b .btn { color: var(--slate); background: var(--oat); }
|
||||
|
||||
/* ---- C · Playful ---- */
|
||||
|
||||
.es-c {
|
||||
text-align: center;
|
||||
max-width: 300px;
|
||||
}
|
||||
.es-c .float {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
margin: 0 auto 20px;
|
||||
position: relative;
|
||||
animation: bob 3.2s ease-in-out infinite;
|
||||
}
|
||||
.es-c .float .card {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 10px;
|
||||
background: var(--panel);
|
||||
border: 1.5px solid var(--line);
|
||||
}
|
||||
.es-c .float .card:nth-child(1) { transform: rotate(-8deg) translate(-6px, 4px); opacity: 0.5; }
|
||||
.es-c .float .card:nth-child(2) { transform: rotate( 6deg) translate( 6px, 2px); opacity: 0.75; }
|
||||
.es-c .float .card:nth-child(3) { background: var(--oat); border-color: var(--oat); }
|
||||
.stage.dark .es-c .float .card:nth-child(3) { background: var(--clay); border-color: var(--clay); }
|
||||
.es-c .shadow {
|
||||
width: 44px;
|
||||
height: 8px;
|
||||
margin: -8px auto 22px;
|
||||
border-radius: 50%;
|
||||
background: rgba(0,0,0,0.12);
|
||||
filter: blur(2px);
|
||||
animation: shadow 3.2s ease-in-out infinite;
|
||||
}
|
||||
.stage.dark .es-c .shadow { background: rgba(0,0,0,0.5); }
|
||||
.es-c h3 {
|
||||
font-family: var(--serif);
|
||||
font-weight: 500;
|
||||
font-size: 19px;
|
||||
color: var(--fg);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.es-c p {
|
||||
font-size: 13px;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
@keyframes bob {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-10px); }
|
||||
}
|
||||
@keyframes shadow {
|
||||
0%, 100% { transform: scaleX(1); opacity: 0.9; }
|
||||
50% { transform: scaleX(0.8); opacity: 0.5; }
|
||||
}
|
||||
|
||||
/* ---- D · Instructional ---- */
|
||||
|
||||
.es-d {
|
||||
width: 100%;
|
||||
max-width: 360px;
|
||||
}
|
||||
.es-d h3 {
|
||||
font-family: var(--serif);
|
||||
font-weight: 500;
|
||||
font-size: 18px;
|
||||
color: var(--fg);
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.es-d ol {
|
||||
list-style: none;
|
||||
counter-reset: step;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
.es-d li {
|
||||
counter-increment: step;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
background: var(--panel);
|
||||
border: 1.5px solid var(--line);
|
||||
border-radius: 8px;
|
||||
padding: 10px 14px;
|
||||
font-size: 13px;
|
||||
color: var(--fg);
|
||||
}
|
||||
.es-d li::before {
|
||||
content: counter(step);
|
||||
font-family: var(--mono);
|
||||
font-size: 11px;
|
||||
flex: 0 0 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
background: var(--oat);
|
||||
color: var(--slate);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: 1px;
|
||||
}
|
||||
.es-d li span { color: var(--muted); display: block; font-size: 12px; margin-top: 2px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="toolbar">
|
||||
<div class="title">Acme · design exploration</div>
|
||||
<div class="field">
|
||||
<span>Background:</span>
|
||||
<div class="seg" id="bg-seg">
|
||||
<label><input type="radio" name="bg" value="light" checked><span>Light</span></label>
|
||||
<label><input type="radio" name="bg" value="dark"><span>Dark</span></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page">
|
||||
|
||||
<header class="page-head">
|
||||
<div class="eyebrow">Exploration · Empty states</div>
|
||||
<h1>Four visual directions for the “no tasks yet” state</h1>
|
||||
<div class="prompt-box">
|
||||
<span class="label">Prompt</span>
|
||||
Explore four visual directions for our empty-state component. Render each
|
||||
live so we can compare tone, density, and how well they hold up on light
|
||||
and dark surfaces.
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<section class="board">
|
||||
|
||||
<!-- ================= A — Minimal ================= -->
|
||||
<article class="artboard">
|
||||
<span class="tag">A — Minimal</span>
|
||||
<div class="stage">
|
||||
<div class="es-a">
|
||||
<h3>No tasks yet</h3>
|
||||
<p>When you create a task it will show up here.</p>
|
||||
<span class="btn">New task</span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="rationale">
|
||||
Pure typography, single quiet action. Reads as calm and confident;
|
||||
assumes the surrounding UI already carries enough personality.
|
||||
</p>
|
||||
</article>
|
||||
|
||||
<!-- ================= B — Illustrated ================= -->
|
||||
<article class="artboard">
|
||||
<span class="tag">B — Illustrated</span>
|
||||
<div class="stage">
|
||||
<div class="es-b">
|
||||
<svg width="120" height="90" viewBox="0 0 120 90" aria-hidden="true">
|
||||
<rect x="14" y="20" width="72" height="54" rx="8"
|
||||
fill="var(--panel)" stroke="var(--line)" stroke-width="1.5"/>
|
||||
<rect x="34" y="10" width="72" height="54" rx="8"
|
||||
fill="var(--oat)"/>
|
||||
<line x1="46" y1="26" x2="92" y2="26"
|
||||
stroke="var(--slate)" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="46" y1="38" x2="80" y2="38"
|
||||
stroke="var(--slate)" stroke-width="2" stroke-linecap="round" opacity="0.5"/>
|
||||
<circle cx="98" cy="60" r="12" fill="var(--clay)"/>
|
||||
<path d="M98 55 v10 M93 60 h10"
|
||||
stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
<h3>Start your first list</h3>
|
||||
<p>Group related work and watch progress roll up automatically.</p>
|
||||
<span class="btn">Create a task</span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="rationale">
|
||||
A small geometric spot illustration anchors the eye and explains the
|
||||
object model (lists contain tasks) without a wall of copy.
|
||||
</p>
|
||||
</article>
|
||||
|
||||
<!-- ================= C — Playful ================= -->
|
||||
<article class="artboard">
|
||||
<span class="tag">C — Playful</span>
|
||||
<div class="stage">
|
||||
<div class="es-c">
|
||||
<div class="float">
|
||||
<div class="card"></div>
|
||||
<div class="card"></div>
|
||||
<div class="card"></div>
|
||||
</div>
|
||||
<div class="shadow"></div>
|
||||
<h3>Nothing on your plate</h3>
|
||||
<p>Enjoy the quiet, or add something to get moving.</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="rationale">
|
||||
A gently bobbing stack adds life to an otherwise static screen. Motion
|
||||
is subtle enough to loop indefinitely without drawing complaints.
|
||||
</p>
|
||||
</article>
|
||||
|
||||
<!-- ================= D — Instructional ================= -->
|
||||
<article class="artboard">
|
||||
<span class="tag">D — Instructional</span>
|
||||
<div class="stage">
|
||||
<div class="es-d">
|
||||
<h3>Set up this project</h3>
|
||||
<ol>
|
||||
<li>
|
||||
Create your first task
|
||||
<span>Give it a name and an owner.</span>
|
||||
</li>
|
||||
<li>
|
||||
Add a due date
|
||||
<span>Acme will surface it on the timeline.</span>
|
||||
</li>
|
||||
<li>
|
||||
Invite a teammate
|
||||
<span>Shared projects stay in sync automatically.</span>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<p class="rationale">
|
||||
Treats the empty state as onboarding. Higher density, but every line is
|
||||
actionable — best when the user is new to the product, not just the view.
|
||||
</p>
|
||||
</article>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const stages = document.querySelectorAll('.stage');
|
||||
document.getElementById('bg-seg').addEventListener('change', (e) => {
|
||||
const dark = e.target.value === 'dark';
|
||||
stages.forEach((s) => s.classList.toggle('dark', dark));
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user