feat(design): the NavRail primitive with optional short labels, the flat surfaces onto roles (E28 S3d3, B7/B5)

This commit is contained in:
2026-09-25 00:47:46 +02:00
parent 6354454cc9
commit 7fa8f4ebde
20 changed files with 342 additions and 101 deletions
+4 -3
View File
@@ -43,6 +43,7 @@ import { useNavigationActions } from "./navigationContext";
import { usePlexActions } from "./plexContext";
import { navItemAttrs } from "../lib/listNav";
import { Pressable } from "./ui/Pressable";
import { SURFACE } from "./ui/surfaces";
// The Home surface (E24) — "Mit nézzek most?".
//
@@ -257,7 +258,7 @@ function ShelfTile({
// Shift+F10, the only keyboard route to the menu. Inert to the click (the handler guards),
// alive to all three input paths.
aria-disabled={!card.next}
className="block w-full rounded-xl overflow-hidden border border-border bg-surface transition-colors aria-disabled:opacity-60 [&:not([aria-disabled='true'])]:hover:border-accent"
className={`${SURFACE.card} glass-hover block w-full overflow-hidden transition-colors aria-disabled:opacity-60 [&:not([aria-disabled='true'])]:hover:border-accent`}
>
<span className="block aspect-video bg-card overflow-hidden">
{card.thumb ? (
@@ -305,7 +306,7 @@ function Hero({
return (
<section
{...pinMenu.triggerProps(card)}
className="mb-6 rounded-xl border border-border bg-surface p-4 grid gap-4 sm:grid-cols-[minmax(0,18rem)_1fr]"
className={`${SURFACE.panel} mb-6 p-4 grid gap-4 sm:grid-cols-[minmax(0,18rem)_1fr]`}
>
<Pressable
onClick={() => onPlay(card)}
@@ -743,7 +744,7 @@ export default function Home() {
) : (
// Honest: nothing in the library fits what was asked. Offering something that does not fit
// would make the one control on this page meaningless.
<section className="mb-6 rounded-xl border border-border bg-surface p-4">
<section className={`${SURFACE.panel} mb-6 p-4`}>
{/* Not `StateMessage`'s `onRetry` slot: that button is labelled "Retry", which promises
a re-run of something that failed. Nothing failed — the library simply has no answer
this short, and the honest offer is to ask a different question. */}