Initial commit
This commit is contained in:
@@ -0,0 +1,473 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Pinkudex — Status Filter Layouts</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg-0: #0e0a14;
|
||||
--bg-1: #18121f;
|
||||
--fg: #ece6f5;
|
||||
--fg-dim: #b9b1c6;
|
||||
--fg-muted: #7d7388;
|
||||
--cyan: #4dd9e6;
|
||||
--violet: #b87cf6;
|
||||
--coral: #ff7a8a;
|
||||
--mint: #79e6b2;
|
||||
--amber: #fbbf24;
|
||||
--glass-border: #2a2434;
|
||||
--glass-border-strong: #3d3548;
|
||||
--glass: rgba(40, 32, 56, 0.5);
|
||||
--glass-strong: rgba(56, 46, 76, 0.7);
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
html, body {
|
||||
margin: 0;
|
||||
background: radial-gradient(1200px 600px at 70% -10%, rgba(184,124,246,0.08), transparent),
|
||||
radial-gradient(800px 500px at 10% 110%, rgba(77,217,230,0.06), transparent),
|
||||
var(--bg-0);
|
||||
color: var(--fg);
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
}
|
||||
.page { max-width: 1600px; margin: 0 auto; padding: 32px 24px 96px; }
|
||||
h1 { font-size: 28px; margin: 0 0 8px; font-weight: 600; letter-spacing: -0.01em; }
|
||||
.lede { color: var(--fg-dim); margin: 0 0 32px; max-width: 820px; line-height: 1.5; }
|
||||
h2 {
|
||||
margin: 32px 0 4px;
|
||||
font-size: 13px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
color: var(--cyan);
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
||||
}
|
||||
.desc { color: var(--fg-dim); font-size: 13px; margin: 0 0 12px; max-width: 820px; line-height: 1.5; }
|
||||
.stage {
|
||||
background: var(--bg-1);
|
||||
border: 1px solid var(--glass-border);
|
||||
border-radius: 16px;
|
||||
padding: 20px;
|
||||
margin-bottom: 24px;
|
||||
position: relative;
|
||||
}
|
||||
.stage-label {
|
||||
font-size: 10px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
color: var(--fg-muted);
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding-bottom: 220px; }
|
||||
.chip {
|
||||
display: inline-flex; align-items: center; gap: 6px;
|
||||
padding: 6px 12px; border-radius: 9999px;
|
||||
border: 1px solid var(--glass-border); background: var(--glass);
|
||||
color: var(--fg-dim); font-size: 14px; cursor: default;
|
||||
font-family: inherit;
|
||||
}
|
||||
.chip.active-coral { background: rgba(255,122,138,0.12); border-color: rgba(255,122,138,0.4); color: var(--coral); }
|
||||
.chip.active-cyan { background: rgba(77,217,230,0.15); border-color: rgba(77,217,230,0.4); color: var(--cyan); }
|
||||
.badge {
|
||||
display: inline-flex; align-items: center; justify-content: center;
|
||||
width: 22px; height: 16px; border-radius: 9999px;
|
||||
color: #000; font-size: 10px; font-weight: 700;
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
||||
}
|
||||
.badge.coral { background: var(--coral); }
|
||||
.badge.cyan { background: var(--cyan); }
|
||||
|
||||
.popup {
|
||||
margin-top: 8px;
|
||||
background: var(--bg-0);
|
||||
border: 1px solid var(--glass-border-strong);
|
||||
border-radius: 14px;
|
||||
padding: 14px;
|
||||
box-shadow: 0 24px 60px rgba(0,0,0,0.7);
|
||||
position: absolute;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
/* Tabs */
|
||||
.tabs {
|
||||
display: flex; gap: 2px; border-bottom: 1px solid var(--glass-border);
|
||||
padding-bottom: 8px; margin-bottom: 10px; flex-wrap: wrap;
|
||||
}
|
||||
.tab {
|
||||
padding: 5px 10px; border-radius: 6px;
|
||||
font-size: 12px; color: var(--fg-muted);
|
||||
display: inline-flex; align-items: center; gap: 5px;
|
||||
}
|
||||
.tab.active { background: var(--glass-strong); color: var(--coral); }
|
||||
.tab .tab-badge {
|
||||
display: inline-flex; align-items: center; justify-content: center;
|
||||
width: 14px; height: 14px; border-radius: 9999px;
|
||||
background: var(--coral); color: #000;
|
||||
font-size: 9px; font-weight: 700;
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
||||
}
|
||||
|
||||
/* segmented tri-state */
|
||||
.seg {
|
||||
display: flex; gap: 0;
|
||||
border: 1px solid var(--glass-border);
|
||||
border-radius: 8px; overflow: hidden;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.seg .opt {
|
||||
flex: 1; text-align: center;
|
||||
padding: 6px 10px;
|
||||
font-size: 12px; color: var(--fg-muted);
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
||||
border-right: 1px solid var(--glass-border);
|
||||
cursor: default;
|
||||
}
|
||||
.seg .opt:last-child { border-right: none; }
|
||||
.seg .opt.on {
|
||||
background: var(--coral); color: #000; font-weight: 700;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
padding: 8px 4px;
|
||||
border-bottom: 1px solid var(--glass-border);
|
||||
}
|
||||
.row:last-child { border-bottom: none; }
|
||||
.row .label {
|
||||
color: var(--fg-dim); font-size: 13px;
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
}
|
||||
.row .label .ico { color: var(--fg-muted); }
|
||||
.axis-title {
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
||||
font-size: 10px; text-transform: uppercase; letter-spacing: 0.1em;
|
||||
color: var(--coral); margin-top: 8px; margin-bottom: 6px;
|
||||
}
|
||||
.axis-title:first-child { margin-top: 0; }
|
||||
|
||||
/* checkbox */
|
||||
.check {
|
||||
width: 14px; height: 14px; border-radius: 3px;
|
||||
border: 1.5px solid var(--glass-border-strong);
|
||||
display: inline-flex; align-items: center; justify-content: center;
|
||||
font-size: 9px; color: var(--coral);
|
||||
}
|
||||
.check.on { background: rgba(255,122,138,0.18); border-color: var(--coral); }
|
||||
|
||||
/* Master/detail */
|
||||
.md {
|
||||
display: flex; gap: 12px;
|
||||
}
|
||||
.md .left {
|
||||
width: 160px;
|
||||
border-right: 1px solid var(--glass-border);
|
||||
padding-right: 8px;
|
||||
}
|
||||
.md .left .ax {
|
||||
padding: 8px 10px; border-radius: 6px;
|
||||
color: var(--fg-muted); font-size: 13px;
|
||||
cursor: default; display: flex; align-items: center; justify-content: space-between;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.md .left .ax.on { background: var(--glass-strong); color: var(--coral); }
|
||||
.md .left .ax .pill {
|
||||
font-size: 9px; padding: 1px 6px; border-radius: 9999px;
|
||||
background: var(--coral); color: #000; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
||||
font-weight: 700;
|
||||
}
|
||||
.md .right { flex: 1; padding-left: 4px; }
|
||||
.md .right .opt {
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
padding: 8px 10px; border-radius: 6px;
|
||||
color: var(--fg-dim); font-size: 13px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.md .right .opt.on { background: rgba(255,122,138,0.12); color: var(--coral); }
|
||||
.md .right .radio {
|
||||
width: 14px; height: 14px; border-radius: 9999px;
|
||||
border: 1.5px solid var(--glass-border-strong);
|
||||
display: inline-flex; align-items: center; justify-content: center;
|
||||
}
|
||||
.md .right .radio .dot {
|
||||
width: 6px; height: 6px; border-radius: 9999px; background: var(--coral);
|
||||
display: none;
|
||||
}
|
||||
.md .right .opt.on .radio { border-color: var(--coral); }
|
||||
.md .right .opt.on .radio .dot { display: block; }
|
||||
|
||||
.pros-cons {
|
||||
display: flex; gap: 12px; margin-top: 14px; font-size: 12px;
|
||||
}
|
||||
.pros, .cons {
|
||||
flex: 1; padding: 8px 10px; border-radius: 8px;
|
||||
border: 1px solid var(--glass-border);
|
||||
}
|
||||
.pros { border-color: rgba(121,230,178,0.2); }
|
||||
.cons { border-color: rgba(255,122,138,0.2); }
|
||||
.pros strong { color: var(--mint); font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em; }
|
||||
.cons strong { color: var(--coral); font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em; }
|
||||
.pros ul, .cons ul { margin: 4px 0 0; padding-left: 16px; color: var(--fg-dim); }
|
||||
.pros li, .cons li { margin: 2px 0; }
|
||||
code { background: var(--glass); padding: 1px 5px; border-radius: 4px; font-size: 12px; color: var(--coral); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page">
|
||||
<h1>Status Filter — Layout Options</h1>
|
||||
<p class="lede">
|
||||
Five takes on solving the redundancy of paired Watched/Unwatched + Rated/No Rating filters,
|
||||
plus housing for No Collection / No Tags. Goal: zero contradictory states, easy to extend with new axes
|
||||
(Year, Resolution, etc.), keeps the filter bar slim.
|
||||
</p>
|
||||
|
||||
<!-- =================================================== -->
|
||||
<h2>Option A — Tabbed status popover (mirrors "Filter by")</h2>
|
||||
<p class="desc">
|
||||
Same shape as the entity filter. Each axis is a tab; inside the tab is a tri-state radio (All / X / not X).
|
||||
Future axes (Year, Resolution, Has Notes) drop in as new tabs at zero design cost.
|
||||
</p>
|
||||
<div class="stage">
|
||||
<div class="stage-label">Bar: All · Filter by ▾ · Status ▾ · search · sort</div>
|
||||
<div class="bar">
|
||||
<span class="chip active-cyan">All</span>
|
||||
<span class="chip">⛓ Filter by <span class="badge cyan" style="visibility:hidden">0</span> ▾</span>
|
||||
<span class="chip active-coral" style="position: relative">
|
||||
⊘ Status <span class="badge coral">2</span> ▾
|
||||
<div class="popup" style="left: 0; top: calc(100% + 6px); width: 380px;">
|
||||
<div class="tabs">
|
||||
<span class="tab active">👁 Watched <span class="tab-badge">1</span></span>
|
||||
<span class="tab">⭐ Rated <span class="tab-badge">1</span></span>
|
||||
<span class="tab">📁 Collection</span>
|
||||
<span class="tab">🏷 Tags</span>
|
||||
</div>
|
||||
<div style="font-family: ui-monospace; font-size: 10px; color: var(--fg-muted); text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 8px;">Watched</div>
|
||||
<div class="seg">
|
||||
<span class="opt">All</span>
|
||||
<span class="opt on">Watched</span>
|
||||
<span class="opt">Unwatched</span>
|
||||
</div>
|
||||
<div style="font-size: 11px; color: var(--fg-muted); font-family: ui-monospace;">tap to set · only one option per tab</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div class="pros-cons">
|
||||
<div class="pros"><strong>Pros</strong><ul>
|
||||
<li>Endlessly extensible — new axis = new tab</li>
|
||||
<li>Visually consistent with Filter by</li>
|
||||
<li>No contradictions possible</li>
|
||||
</ul></div>
|
||||
<div class="cons"><strong>Cons</strong><ul>
|
||||
<li>Two clicks to change a different axis</li>
|
||||
<li>Tabs hide other axes' state until clicked</li>
|
||||
</ul></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- =================================================== -->
|
||||
<h2>Option B — Single popover, all axes visible (sectioned tri-states)</h2>
|
||||
<p class="desc">
|
||||
Keep one popover, but show every axis at once with a tri-state segmented control per axis.
|
||||
No tabs — everything's a click away. Becomes taller as axes are added.
|
||||
</p>
|
||||
<div class="stage">
|
||||
<div class="stage-label">All status axes visible at once</div>
|
||||
<div class="bar">
|
||||
<span class="chip active-cyan">All</span>
|
||||
<span class="chip">⛓ Filter by <span class="badge cyan" style="visibility:hidden">0</span> ▾</span>
|
||||
<span class="chip active-coral" style="position: relative">
|
||||
⊘ Status <span class="badge coral">3</span> ▾
|
||||
<div class="popup" style="left: 0; top: calc(100% + 6px); width: 360px;">
|
||||
<div class="axis-title">Watched</div>
|
||||
<div class="seg">
|
||||
<span class="opt on">All</span>
|
||||
<span class="opt">Watched</span>
|
||||
<span class="opt">Unwatched</span>
|
||||
</div>
|
||||
<div class="axis-title">Rated</div>
|
||||
<div class="seg">
|
||||
<span class="opt">All</span>
|
||||
<span class="opt on">Rated</span>
|
||||
<span class="opt">No Rating</span>
|
||||
</div>
|
||||
<div class="axis-title">Collection</div>
|
||||
<div class="seg">
|
||||
<span class="opt">All</span>
|
||||
<span class="opt">Has</span>
|
||||
<span class="opt on">No Collection</span>
|
||||
</div>
|
||||
<div class="axis-title">Tags</div>
|
||||
<div class="seg">
|
||||
<span class="opt">All</span>
|
||||
<span class="opt">Has</span>
|
||||
<span class="opt on">No Tags</span>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div class="pros-cons">
|
||||
<div class="pros"><strong>Pros</strong><ul>
|
||||
<li>All state visible — no hidden tabs</li>
|
||||
<li>Tri-state radios prevent contradictions</li>
|
||||
<li>One click to toggle any axis</li>
|
||||
</ul></div>
|
||||
<div class="cons"><strong>Cons</strong><ul>
|
||||
<li>Grows tall when more axes are added (Year, Resolution, etc.)</li>
|
||||
<li>Less directly extensible than tabs</li>
|
||||
</ul></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- =================================================== -->
|
||||
<h2>Option C — One chip per axis in the bar</h2>
|
||||
<p class="desc">
|
||||
Each status dimension is its own chip in the filter bar with its own dropdown. Clicking shows just that axis's options.
|
||||
Most decluttered axis-by-axis, but the bar grows wide as axes are added.
|
||||
</p>
|
||||
<div class="stage">
|
||||
<div class="stage-label">Bar: All · Filter by ▾ · Watched ▾ · Rated ▾ · Collection ▾ · Tags ▾ · search · sort</div>
|
||||
<div class="bar">
|
||||
<span class="chip active-cyan">All</span>
|
||||
<span class="chip">⛓ Filter by ▾</span>
|
||||
<span class="chip active-coral" style="position: relative">
|
||||
👁 Watched <span style="font-family: ui-monospace; font-size: 11px; opacity: 0.8;">: Watched</span> ▾
|
||||
<div class="popup" style="left: 0; top: calc(100% + 6px); width: 200px;">
|
||||
<div class="row"><span class="label">All</span><span class="check"></span></div>
|
||||
<div class="row"><span class="label">Watched</span><span class="check on">✓</span></div>
|
||||
<div class="row"><span class="label">Unwatched</span><span class="check"></span></div>
|
||||
</div>
|
||||
</span>
|
||||
<span class="chip">⭐ Rated ▾</span>
|
||||
<span class="chip">📁 Collection ▾</span>
|
||||
<span class="chip">🏷 Tags ▾</span>
|
||||
</div>
|
||||
<div class="pros-cons">
|
||||
<div class="pros"><strong>Pros</strong><ul>
|
||||
<li>Each axis label visible without opening</li>
|
||||
<li>Active selection shows on the chip itself ("Watched: Watched")</li>
|
||||
<li>One click to a specific axis</li>
|
||||
</ul></div>
|
||||
<div class="cons"><strong>Cons</strong><ul>
|
||||
<li>Bar grows wide — each new axis adds a chip</li>
|
||||
<li>Less consolidation; reverts to the "many chips" problem</li>
|
||||
</ul></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- =================================================== -->
|
||||
<h2>Option D — Master/detail popover (axis list left, options right)</h2>
|
||||
<p class="desc">
|
||||
Opens to a two-column layout: axis list on the left (with active value), options for the selected axis on the right.
|
||||
Only one click to switch axes; current selection visible at all times in the left column. Scales to many axes.
|
||||
</p>
|
||||
<div class="stage">
|
||||
<div class="stage-label">Two-pane popover with permanent axis sidebar</div>
|
||||
<div class="bar">
|
||||
<span class="chip active-cyan">All</span>
|
||||
<span class="chip">⛓ Filter by ▾</span>
|
||||
<span class="chip active-coral" style="position: relative">
|
||||
⊘ Status <span class="badge coral">2</span> ▾
|
||||
<div class="popup" style="left: 0; top: calc(100% + 6px); width: 460px;">
|
||||
<div class="md">
|
||||
<div class="left">
|
||||
<div class="ax on">👁 Watched <span class="pill">Watched</span></div>
|
||||
<div class="ax">⭐ Rated <span class="pill">Rated</span></div>
|
||||
<div class="ax">📁 Collection</div>
|
||||
<div class="ax">🏷 Tags</div>
|
||||
<!-- Future axes drop in here:
|
||||
<div class="ax">📅 Year</div>
|
||||
<div class="ax">📐 Resolution</div>
|
||||
-->
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="opt">
|
||||
<span class="radio"><span class="dot"></span></span>
|
||||
All
|
||||
</div>
|
||||
<div class="opt on">
|
||||
<span class="radio"><span class="dot"></span></span>
|
||||
Watched
|
||||
</div>
|
||||
<div class="opt">
|
||||
<span class="radio"><span class="dot"></span></span>
|
||||
Unwatched
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div class="pros-cons">
|
||||
<div class="pros"><strong>Pros</strong><ul>
|
||||
<li>Active value visible per axis without opening anything</li>
|
||||
<li>Switch axes in one click — no tab clicks lost</li>
|
||||
<li>Cleanest scaling for many axes (just longer left column)</li>
|
||||
<li>Scans like a settings panel — predictable</li>
|
||||
</ul></div>
|
||||
<div class="cons"><strong>Cons</strong><ul>
|
||||
<li>Wider popover (~460px+)</li>
|
||||
<li>More implementation work than a flat tabbed layout</li>
|
||||
</ul></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- =================================================== -->
|
||||
<h2>Option E — Inline accordion (collapsed sections, click to expand)</h2>
|
||||
<p class="desc">
|
||||
All axes listed; current selection shown inline; click an axis to expand its options. Closed axes show only their value.
|
||||
Compact when most axes are on default, expands as needed.
|
||||
</p>
|
||||
<div class="stage">
|
||||
<div class="stage-label">Sections collapse when not active; current value always visible</div>
|
||||
<div class="bar">
|
||||
<span class="chip active-cyan">All</span>
|
||||
<span class="chip">⛓ Filter by ▾</span>
|
||||
<span class="chip active-coral" style="position: relative">
|
||||
⊘ Status <span class="badge coral">2</span> ▾
|
||||
<div class="popup" style="left: 0; top: calc(100% + 6px); width: 320px;">
|
||||
<div class="row">
|
||||
<span class="label">👁 Watched <span style="color: var(--coral); font-family: ui-monospace; font-size: 11px; margin-left: 4px;">: Watched</span></span>
|
||||
<span style="color: var(--fg-muted); font-size: 11px;">▾</span>
|
||||
</div>
|
||||
<div style="padding: 4px 8px 8px;">
|
||||
<div class="seg">
|
||||
<span class="opt">All</span>
|
||||
<span class="opt on">Watched</span>
|
||||
<span class="opt">Unwatched</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="label">⭐ Rated <span style="color: var(--coral); font-family: ui-monospace; font-size: 11px; margin-left: 4px;">: Rated</span></span>
|
||||
<span style="color: var(--fg-muted); font-size: 11px;">▸</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="label">📁 Collection <span style="color: var(--fg-muted); font-family: ui-monospace; font-size: 11px; margin-left: 4px;">: All</span></span>
|
||||
<span style="color: var(--fg-muted); font-size: 11px;">▸</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="label">🏷 Tags <span style="color: var(--fg-muted); font-family: ui-monospace; font-size: 11px; margin-left: 4px;">: All</span></span>
|
||||
<span style="color: var(--fg-muted); font-size: 11px;">▸</span>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div class="pros-cons">
|
||||
<div class="pros"><strong>Pros</strong><ul>
|
||||
<li>Compact when nothing's set; details on demand</li>
|
||||
<li>Active values visible inline without opening anything</li>
|
||||
<li>Stays narrow — easy to fit on tablets</li>
|
||||
</ul></div>
|
||||
<div class="cons"><strong>Cons</strong><ul>
|
||||
<li>Two clicks to change an axis (open + select)</li>
|
||||
<li>Animations / disclosure indicators add UI complexity</li>
|
||||
</ul></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p style="margin-top: 24px; font-size: 11px; color: var(--fg-muted); font-family: ui-monospace;">
|
||||
All five solve contradictions via tri-state radios and house Collection/Tags as proper axes.
|
||||
Pick based on your taste: A scales most cleanly; D shows the most info at once; B is simplest to implement;
|
||||
C wears state on the bar; E is the most space-efficient.
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user