feat(design): glass surfaces by role, the static Badge, LinkButton, user pickers on the Combobox (E28 S3d1)

This commit is contained in:
2026-09-25 00:34:35 +02:00
parent db10bfbbca
commit c47c193ad1
89 changed files with 818 additions and 478 deletions
+8 -5
View File
@@ -24,6 +24,7 @@ import { Btn } from "./batchA";
import { C1 } from "./batchCActions";
import { Reference, Sample } from "./labKit";
import { FADE_ABOVE_PANEL, FADE_BELOW_PANEL, H, LAYER, STRONG } from "./labTokens";
import { SURFACE } from "../components/ui/surfaces";
// E28 S2 · Batch C — behaviour on touch and on a narrow window, DECIDED (owner, 2026-09-24): C1–C4 as
// proposed; C5 is the owner's reworked Plex control set (found by the live player pass, E28 S2d: the
@@ -45,7 +46,7 @@ function Content() {
return (
<div className="grid grid-cols-3 gap-2 p-3">
{Array.from({ length: 9 }, (_, i) => (
<div key={i} className="glass-card flex flex-col gap-1 rounded-xl p-1.5">
<div key={i} className={`${SURFACE.card} flex flex-col gap-1 p-1.5`}>
<div className="aspect-video rounded-lg bg-linear-to-br from-accent/40 to-card" />
<span className="truncate text-2xs">Video {i + 1}</span>
</div>
@@ -56,7 +57,7 @@ function Content() {
function FilterPanel() {
return (
<div className="glass flex h-full w-44 flex-col gap-2 rounded-r-2xl p-3 text-xs">
<div className={`${SURFACE.panel} flex h-full w-44 flex-col gap-2 p-3 text-xs`}>
<div className="flex items-center justify-between">
<span className="font-semibold">Filters</span>
<span className="flex gap-0.5">
@@ -163,7 +164,7 @@ function C4() {
title="Dialog conventions"
rule="Modal takes an initialFocus by purpose (APG): a form focuses its first field, a confirm its least destructive button, anything else Close. The header and the footer are fixed, only the body scrolls, with the B9 fade at both edges, so Save stays one tap away with the keyboard up. Shown at a keyboard-up height."
>
<div className="glass relative flex h-52 flex-col overflow-hidden rounded-2xl">
<div className={`${SURFACE.panel} relative flex h-52 flex-col overflow-hidden`}>
<div
className={clsx(
"relative z-base flex items-center justify-between px-3 py-2 text-sm font-semibold",
@@ -270,7 +271,9 @@ function PlayerRow() {
<Maximize className="h-5 w-5" />
</span>
</div>
<div className="glass-menu absolute bottom-16 right-2 flex w-52 flex-col rounded-xl p-1 text-xs text-fg">
<div
className={`${SURFACE.menu} absolute bottom-16 right-2 flex w-52 flex-col text-xs text-fg`}
>
{MORE.map((c) => (
<span key={c.label} className="flex min-h-11 items-center gap-2.5 rounded-lg px-2.5">
<c.icon className={ico} />
@@ -286,7 +289,7 @@ function PlayerRow() {
function MediaCard({ state }: { state: "new" | "started" | "touch" }) {
const pill = "inline-flex h-8 items-center gap-1.5 rounded-full px-3 text-xs font-medium";
return (
<div className="glass-card flex w-44 flex-col gap-1.5 rounded-xl p-1.5">
<div className={`${SURFACE.card} flex w-44 flex-col gap-1.5 p-1.5`}>
<div className="relative aspect-2/3 overflow-hidden rounded-lg bg-linear-to-br from-accent/50 to-card">
{state !== "new" && (
<span className="absolute inset-x-0 bottom-0 h-1 bg-white/25">