298 lines
16 KiB
HTML
298 lines
16 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<title>Detail Page — Spacing Pass (Same Design, Symmetric Rhythm)</title>
|
||
<script src="https://cdn.tailwindcss.com"></script>
|
||
<style>
|
||
:root {
|
||
--color-bg-0: oklch(0.16 0.02 280);
|
||
--color-bg-1: oklch(0.20 0.03 280);
|
||
--color-fg: oklch(0.96 0.01 280);
|
||
--color-fg-dim: oklch(0.78 0.02 280);
|
||
--color-fg-muted: oklch(0.55 0.02 280);
|
||
--color-glass: oklch(0.27 0.04 280 / 0.45);
|
||
--color-glass-strong: oklch(0.30 0.05 280 / 0.65);
|
||
--color-glass-border: oklch(0.40 0.05 280 / 0.30);
|
||
--color-glass-border-strong: oklch(0.50 0.06 280 / 0.45);
|
||
--color-cyan: oklch(0.82 0.16 200);
|
||
--color-violet: oklch(0.72 0.18 305);
|
||
--color-coral: oklch(0.74 0.18 25);
|
||
--color-mint: oklch(0.82 0.14 165);
|
||
}
|
||
body {
|
||
background: var(--color-bg-0);
|
||
color: var(--color-fg);
|
||
font-family: ui-sans-serif, system-ui, -apple-system, sans-serif;
|
||
}
|
||
.glass {
|
||
background: var(--color-glass);
|
||
border: 1px solid var(--color-glass-border);
|
||
}
|
||
.glass-strong {
|
||
background: var(--color-glass-strong);
|
||
border: 1px solid var(--color-glass-border-strong);
|
||
}
|
||
.label-mono {
|
||
font-family: ui-monospace, "JetBrains Mono", monospace;
|
||
font-size: 10px;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.1em;
|
||
color: var(--color-fg-muted);
|
||
}
|
||
.pill {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 0.4rem;
|
||
padding: 0 0.78rem;
|
||
height: 31px;
|
||
border-radius: 999px;
|
||
font-size: 11px;
|
||
font-family: ui-monospace, monospace;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.06em;
|
||
border: 1px solid var(--color-glass-border);
|
||
background: transparent;
|
||
color: var(--color-fg-muted);
|
||
justify-content: center;
|
||
}
|
||
.pill.on-mint { color: var(--color-mint); border-color: oklch(0.82 0.14 165 / 0.4); background: oklch(0.82 0.14 165 / 0.10); }
|
||
.pill.on-cyan { color: var(--color-cyan); border-color: oklch(0.82 0.16 200 / 0.4); background: oklch(0.82 0.16 200 / 0.10); }
|
||
.pill.on-violet { color: var(--color-violet); border-color: oklch(0.72 0.18 305 / 0.4); background: oklch(0.72 0.18 305 / 0.10); }
|
||
.chip {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 0.4rem;
|
||
padding: 0 0.78rem;
|
||
height: 29px;
|
||
border-radius: 999px;
|
||
font-size: 12px;
|
||
border: 1px solid var(--color-glass-border);
|
||
color: var(--color-fg-muted);
|
||
}
|
||
.chip-violet { color: var(--color-violet); border-color: oklch(0.72 0.18 305 / 0.4); background: oklch(0.72 0.18 305 / 0.14); }
|
||
.chip-cyan { color: var(--color-cyan); border-color: oklch(0.82 0.16 200 / 0.4); background: oklch(0.82 0.16 200 / 0.14); }
|
||
.frame-label {
|
||
font-family: ui-monospace, monospace;
|
||
font-size: 11px;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.08em;
|
||
color: var(--color-cyan);
|
||
}
|
||
.why { font-size: 12px; color: var(--color-fg-muted); }
|
||
.btn {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 0.4rem;
|
||
height: 33px;
|
||
padding: 0 0.83rem;
|
||
border-radius: 0.5rem;
|
||
font-size: 12px;
|
||
border: 1px solid var(--color-glass-border);
|
||
background: var(--color-glass);
|
||
color: var(--color-fg);
|
||
}
|
||
.btn-coral {
|
||
color: var(--color-coral);
|
||
background: oklch(0.74 0.18 25 / 0.10);
|
||
border-color: oklch(0.74 0.18 25 / 0.30);
|
||
}
|
||
/* Visual spacing-guide: a faint dotted box around every gap-bearing element. */
|
||
.show-rhythm > * { outline: 1px dotted oklch(0.55 0.16 200 / 0.30); }
|
||
</style>
|
||
</head>
|
||
<body class="p-6 space-y-8 max-w-[1400px] mx-auto">
|
||
|
||
<header class="space-y-1">
|
||
<h1 class="text-2xl font-semibold tracking-tight">Detail Page · Spacing Pass</h1>
|
||
<p class="why max-w-[820px]">
|
||
Same design, same components, same colors, same chip/pill/button styles — only margins, paddings, and gaps changed for strict symmetry. One set of spacing tokens applied everywhere.
|
||
</p>
|
||
</header>
|
||
|
||
<!-- ====================================================================
|
||
Spacing tokens
|
||
==================================================================== -->
|
||
<section class="glass rounded-2xl p-5">
|
||
<div class="frame-label mb-3">Tokens applied throughout (snug + 1)</div>
|
||
<div class="grid grid-cols-2 sm:grid-cols-4 gap-x-6 gap-y-2 text-[12px] font-mono text-[var(--color-fg-dim)]">
|
||
<div><span class="text-[var(--color-fg-muted)]">card padding</span> <code class="text-[var(--color-cyan)]">p-[15px]</code> · 15 px</div>
|
||
<div><span class="text-[var(--color-fg-muted)]">card gap</span> <code class="text-[var(--color-cyan)]">gap-[9px]</code> · 9 px</div>
|
||
<div><span class="text-[var(--color-fg-muted)]">section gap</span> <code class="text-[var(--color-cyan)]">space-y-[15px]</code> · 15 px</div>
|
||
<div><span class="text-[var(--color-fg-muted)]">label → content</span> <code class="text-[var(--color-cyan)]">mb-[7px]</code> · 7 px</div>
|
||
<div><span class="text-[var(--color-fg-muted)]">chip gap</span> <code class="text-[var(--color-cyan)]">gap-[7px]</code> · 7 px</div>
|
||
<div><span class="text-[var(--color-fg-muted)]">chip height</span> 29 px</div>
|
||
<div><span class="text-[var(--color-fg-muted)]">pill height</span> 31 px</div>
|
||
<div><span class="text-[var(--color-fg-muted)]">button height</span> 33 px</div>
|
||
<div><span class="text-[var(--color-fg-muted)]">card radius</span> <code class="text-[var(--color-cyan)]">rounded-2xl</code> · 16 px</div>
|
||
<div><span class="text-[var(--color-fg-muted)]">stat label → value</span> <code class="text-[var(--color-cyan)]">mb-[5px]</code> · 5 px</div>
|
||
<div><span class="text-[var(--color-fg-muted)]">flag pill grid</span> <code class="text-[var(--color-cyan)]">gap-[7px]</code> · 7 px</div>
|
||
<div><span class="text-[var(--color-fg-muted)]">action btn grid</span> <code class="text-[var(--color-cyan)]">gap-[7px]</code> · 7 px</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ====================================================================
|
||
Side-by-side: current vs symmetric
|
||
==================================================================== -->
|
||
<section class="grid grid-cols-1 xl:grid-cols-2 gap-8">
|
||
|
||
<!-- BEFORE (current) ............................................. -->
|
||
<div class="space-y-2">
|
||
<div class="frame-label !text-[var(--color-fg-muted)]">BEFORE · current</div>
|
||
<div class="space-y-2">
|
||
<!-- Top card: mixed paddings and dividers -->
|
||
<div class="glass rounded-2xl p-4 space-y-3">
|
||
<div class="flex items-start justify-between">
|
||
<div>
|
||
<div class="font-mono text-[var(--color-cyan)] text-xl font-semibold">YUJ-001</div>
|
||
<div class="text-sm italic text-[var(--color-fg-muted)] mt-1">Untitled</div>
|
||
</div>
|
||
<div class="flex gap-1 text-[var(--color-cyan)]"><span>★</span><span>★</span><span>★</span><span>★</span><span>★</span></div>
|
||
</div>
|
||
<div class="grid grid-cols-4 gap-1.5">
|
||
<button class="pill on-cyan">⬢ VIP</button>
|
||
<button class="pill">☆ Favorite</button>
|
||
<button class="pill on-mint">◉ Watched</button>
|
||
<button class="pill on-violet">▣ Owned</button>
|
||
</div>
|
||
<div class="text-[12px] font-mono text-[var(--color-fg-muted)]">
|
||
<span class="opacity-70 text-[10px] uppercase tracking-wider">RESOLUTION</span> <span class="text-[var(--color-fg)] font-bold">800×538</span>
|
||
<span class="mx-2 opacity-40">·</span>
|
||
<span class="opacity-70 text-[10px] uppercase tracking-wider">SIZE</span> <span class="text-[var(--color-fg)] font-bold">170 KB</span>
|
||
<span class="mx-2 opacity-40">·</span>
|
||
<span class="opacity-70 text-[10px] uppercase tracking-wider">IMPORTED</span> <span class="text-[var(--color-fg)] font-bold">4/29/2026</span>
|
||
</div>
|
||
<div class="flex flex-wrap items-end justify-center gap-x-10 gap-y-3 pt-2 border-t border-[var(--color-glass-border)]">
|
||
<div><div class="label-mono mb-1">Resolution</div><div class="font-mono text-2xl font-semibold text-[var(--color-fg-dim)]">1920×1080</div></div>
|
||
<div><div class="label-mono mb-1">Bitrate</div><div class="font-mono text-2xl font-semibold text-[var(--color-fg-dim)]">5.7 Mbps</div></div>
|
||
<div><div class="label-mono mb-1">File Size</div><div class="font-mono text-3xl font-semibold">8.65 GB</div></div>
|
||
<div><div class="label-mono mb-1">Length</div><div class="font-mono text-3xl font-semibold text-[var(--color-cyan)]">3:53:50</div></div>
|
||
</div>
|
||
</div>
|
||
<!-- Actresses card alone -->
|
||
<div class="glass rounded-2xl p-4 space-y-2">
|
||
<div class="label-mono">Actresses</div>
|
||
<div class="flex flex-wrap gap-1.5">
|
||
<span class="chip chip-violet">Ichika Matsumoto</span>
|
||
<button class="chip">+ Add</button>
|
||
</div>
|
||
</div>
|
||
<!-- Tags+Collections fused (inconsistent) -->
|
||
<div class="glass rounded-2xl p-4 space-y-3">
|
||
<div>
|
||
<div class="label-mono mb-1">Tags</div>
|
||
<button class="chip">+ Add tag</button>
|
||
</div>
|
||
<div>
|
||
<div class="label-mono mb-1">Collections</div>
|
||
<div class="flex flex-wrap gap-1.5">
|
||
<span class="chip chip-cyan">Sugar & Spice ✕</span>
|
||
<button class="chip">+ Add to collection</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- Action row, orphaned -->
|
||
<div class="grid grid-cols-3 gap-2 px-1">
|
||
<button class="btn">✎ Edit Metadata</button>
|
||
<button class="btn">⤓ Import .nfo / JSON</button>
|
||
<button class="btn btn-coral">🗑 Delete</button>
|
||
</div>
|
||
</div>
|
||
<ul class="text-[11px] font-mono text-[var(--color-fg-muted)] mt-2 space-y-0.5 list-disc list-inside">
|
||
<li>card padding alternates p-4 / mixed</li>
|
||
<li>card vertical gap is 8px (space-y-2) but identity card uses space-y-3 internally</li>
|
||
<li>flag pill grid gap differs from action button grid gap</li>
|
||
<li>cover dotted strip uses a different label style than the hero stats</li>
|
||
<li>Tags + Collections share a card; Actresses doesn't (inconsistent grouping)</li>
|
||
<li>Action buttons sit OUTSIDE every card → break the rhythm</li>
|
||
<li>chip + pill + button heights all different and arbitrary</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<!-- AFTER (symmetric, balanced) .................................. -->
|
||
<div class="space-y-2">
|
||
<div class="frame-label">AFTER · symmetric · snug+1 · same design</div>
|
||
<div style="display: flex; flex-direction: column; gap: 9px;">
|
||
<!-- Top card: 15 px padding, 15 px section gap -->
|
||
<div class="glass rounded-2xl" style="padding: 15px; display: flex; flex-direction: column; gap: 15px;">
|
||
<div class="flex items-start justify-between gap-3">
|
||
<div class="space-y-1">
|
||
<div class="font-mono text-[var(--color-cyan)] text-xl font-semibold leading-none">YUJ-001</div>
|
||
<div class="text-sm italic text-[var(--color-fg-muted)] leading-none">Untitled</div>
|
||
</div>
|
||
<div class="flex gap-1 text-[var(--color-cyan)]"><span>★</span><span>★</span><span>★</span><span>★</span><span>★</span></div>
|
||
</div>
|
||
<div class="grid grid-cols-4" style="gap: 7px;">
|
||
<button class="pill on-cyan">⬢ VIP</button>
|
||
<button class="pill">☆ Favorite</button>
|
||
<button class="pill on-mint">◉ Watched</button>
|
||
<button class="pill on-violet">▣ Owned</button>
|
||
</div>
|
||
<div class="flex flex-wrap items-baseline justify-center gap-x-5 gap-y-1 border-t border-[var(--color-glass-border)] text-[12px] font-mono" style="padding-top: 15px;">
|
||
<span><span class="label-mono">Resolution</span> <span class="text-[var(--color-fg)] ml-1.5">800×538</span></span>
|
||
<span class="opacity-30">·</span>
|
||
<span><span class="label-mono">Size</span> <span class="text-[var(--color-fg)] ml-1.5">170 KB</span></span>
|
||
<span class="opacity-30">·</span>
|
||
<span><span class="label-mono">Imported</span> <span class="text-[var(--color-fg)] ml-1.5">4/29/2026</span></span>
|
||
</div>
|
||
<div class="grid grid-cols-4 text-center" style="gap: 13px;">
|
||
<div><div class="label-mono" style="margin-bottom: 5px;">Resolution</div><div class="font-mono text-2xl font-semibold text-[var(--color-fg-dim)] leading-none">1920×1080</div></div>
|
||
<div><div class="label-mono" style="margin-bottom: 5px;">Bitrate</div><div class="font-mono text-2xl font-semibold text-[var(--color-fg-dim)] leading-none">5.7 Mbps</div></div>
|
||
<div><div class="label-mono" style="margin-bottom: 5px;">File Size</div><div class="font-mono text-3xl font-semibold leading-none">8.65 GB</div></div>
|
||
<div><div class="label-mono" style="margin-bottom: 5px;">Length</div><div class="font-mono text-3xl font-semibold text-[var(--color-cyan)] leading-none">3:53:50</div></div>
|
||
</div>
|
||
</div>
|
||
<!-- Actresses -->
|
||
<div class="glass rounded-2xl" style="padding: 15px; display: flex; flex-direction: column; gap: 7px;">
|
||
<div class="label-mono">Actresses</div>
|
||
<div class="flex flex-wrap" style="gap: 7px;">
|
||
<span class="chip chip-violet">Ichika Matsumoto</span>
|
||
<button class="chip">+ Add</button>
|
||
</div>
|
||
</div>
|
||
<!-- Tags -->
|
||
<div class="glass rounded-2xl" style="padding: 15px; display: flex; flex-direction: column; gap: 7px;">
|
||
<div class="label-mono">Tags</div>
|
||
<div class="flex flex-wrap" style="gap: 7px;">
|
||
<button class="chip">+ Add tag</button>
|
||
</div>
|
||
</div>
|
||
<!-- Collections -->
|
||
<div class="glass rounded-2xl" style="padding: 15px; display: flex; flex-direction: column; gap: 7px;">
|
||
<div class="label-mono">Collections</div>
|
||
<div class="flex flex-wrap" style="gap: 7px;">
|
||
<span class="chip chip-cyan">Sugar & Spice ✕</span>
|
||
<button class="chip">+ Add to collection</button>
|
||
</div>
|
||
</div>
|
||
<!-- Action buttons — separate from any card. Same 9 px card-gap
|
||
above and 7 px horizontal gap matching chip clusters. -->
|
||
<div class="grid grid-cols-3" style="gap: 7px;">
|
||
<button class="btn">✎ Edit Metadata</button>
|
||
<button class="btn">⤓ Import .nfo / JSON</button>
|
||
<button class="btn btn-coral">🗑 Delete</button>
|
||
</div>
|
||
</div>
|
||
<ul class="text-[11px] font-mono text-[var(--color-fg-muted)] mt-2 space-y-0.5 list-disc list-inside">
|
||
<li>every card: same <code class="text-[var(--color-cyan)]">p-[15px]</code>, <code class="text-[var(--color-cyan)]">rounded-2xl</code> (16 px)</li>
|
||
<li>card-to-card gap: <code class="text-[var(--color-cyan)]">gap-[9px]</code></li>
|
||
<li>internal section gap: <code class="text-[var(--color-cyan)]">space-y-[15px]</code> for blocks, <code class="text-[var(--color-cyan)]">gap-[7px]</code> for label→chips</li>
|
||
<li>flag pill grid · chip clusters · action btn grid: all <code class="text-[var(--color-cyan)]">gap-[7px]</code></li>
|
||
<li>chip 29 · pill 31 · button 33 — even 2 px ladder, all bumped +1</li>
|
||
<li>cover row + hero stats: SAME label-mono treatment, no bold-caps strip</li>
|
||
<li>Actresses · Tags · Collections each get their own card</li>
|
||
<li>action buttons sit OUTSIDE any card, on the same <code class="text-[var(--color-cyan)]">gap-[9px]</code> rhythm</li>
|
||
<li>stat values get <code class="text-[var(--color-cyan)]">leading-none</code> so label-to-value gap is exact across all four</li>
|
||
</ul>
|
||
</div>
|
||
|
||
</section>
|
||
|
||
<footer class="text-[11px] text-[var(--color-fg-muted)]">
|
||
Same design — only spacing tokens unified. Approve and I'll apply these exact values to <code class="text-[var(--color-cyan)]">components/image/ImageDetailView.tsx</code>.
|
||
</footer>
|
||
|
||
</body>
|
||
</html>
|