feat(design): C5 recorded, every E28 decision taken
The owner's lean Plex control set with both refinements (Back by position, a touch double-tap for the 10 s skip) goes into DESIGN.md's Players chapter and the log. The lab is now the reference only.
This commit is contained in:
@@ -1,84 +1,13 @@
|
||||
import { useSyncExternalStore, type ReactNode } from "react";
|
||||
import clsx from "clsx";
|
||||
|
||||
// Building blocks of the design lab. A lab page asks the owner ONE question per <Decision>: two or
|
||||
// three <Variant>s rendered side by side with the app's real CSS, the recommended one marked and its
|
||||
// one-line reason (the rule it rests on) printed under it. Everything is static markup on purpose —
|
||||
// what is being decided is the look, and a variant that only exists here must not need app state.
|
||||
|
||||
export function Decision({
|
||||
id,
|
||||
code,
|
||||
title,
|
||||
question,
|
||||
now,
|
||||
children,
|
||||
}: {
|
||||
id: string;
|
||||
code: string;
|
||||
title: string;
|
||||
question: string;
|
||||
/** What the app does today, measured (the E28 S1 inventory). */
|
||||
now: ReactNode;
|
||||
children: ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<section id={id} className="glass rounded-2xl p-5 scroll-mt-20">
|
||||
<header className="mb-4">
|
||||
<div className="flex items-baseline gap-3">
|
||||
<span className="text-xs font-bold tracking-widest text-accent">{code}</span>
|
||||
<h2 className="text-lg font-bold">{title}</h2>
|
||||
</div>
|
||||
<p className="mt-1 text-sm">{question}</p>
|
||||
<p className="mt-1 text-xs text-muted">
|
||||
<span className="font-semibold">Today: </span>
|
||||
{now}
|
||||
</p>
|
||||
</header>
|
||||
<div className="grid gap-4 grid-cols-[repeat(auto-fit,minmax(18rem,1fr))]">{children}</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
export function Variant({
|
||||
letter,
|
||||
name,
|
||||
recommended = false,
|
||||
why,
|
||||
children,
|
||||
}: {
|
||||
letter: string;
|
||||
name: string;
|
||||
recommended?: boolean;
|
||||
why: string;
|
||||
children: ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<article
|
||||
className={clsx(
|
||||
"glass-card rounded-xl p-4 flex flex-col gap-3 border",
|
||||
recommended ? "border-accent" : "border-transparent",
|
||||
)}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="grid h-6 w-6 place-items-center rounded-full bg-card text-xs font-bold">
|
||||
{letter}
|
||||
</span>
|
||||
<h3 className="text-sm font-semibold flex-1">{name}</h3>
|
||||
{recommended && (
|
||||
<span className="rounded-full bg-accent px-2 py-0.5 text-2xs font-bold text-accent-fg">
|
||||
Recommended
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-col gap-3">{children}</div>
|
||||
<p className="mt-auto border-t border-border/60 pt-2 text-xs text-muted">{why}</p>
|
||||
</article>
|
||||
);
|
||||
}
|
||||
// Building blocks of the design lab. Every E28 decision is taken, so the lab is the reference half
|
||||
// only: each <Reference> is the chosen rendering with the rule it became. A new design round brings
|
||||
// back the side-by-side <Decision>/<Variant> pair (E28 S2 history) for its open questions. Everything
|
||||
// is static markup on purpose: a rendering that only exists here must not need app state.
|
||||
|
||||
/** A decision already taken: the chosen rendering only, with the rule it became. The lab's
|
||||
* reference half — the living style guide the open decisions sit on top of. */
|
||||
* reference half — the living style guide. */
|
||||
export function Reference({
|
||||
id,
|
||||
code,
|
||||
|
||||
Reference in New Issue
Block a user