Document the contract and the traps
CONTRACT.md states the twelve rules and, for each, the failure it prevents. AGENTS.md lists the three directories a demo agent may touch and the seven traps that have already cost time here — pnpm 11's settings move, the non-portable RNG, the two-pass rule, the two reward-denominator subtleties, the silent CSP worker block, and Caddy's silent bind. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019mt6sHQHEnEYrJZvoMCJSB
This commit is contained in:
@@ -111,20 +111,36 @@ function useLineup() {
|
||||
const primary = live[0] ?? demos[0];
|
||||
const ctaHref = primary ? `/demos/${primary.slug}` : '/demos';
|
||||
|
||||
return { demos, live, spec, verticals, ctaHref };
|
||||
return { live, spec, verticals, ctaHref };
|
||||
}, []);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ panels */
|
||||
|
||||
function DemoRow({ demo, muted = false }: { demo: DemoMeta; muted?: boolean }) {
|
||||
/**
|
||||
* Spreads `...rest` onto the Link, and that is not tidiness.
|
||||
*
|
||||
* Both `NavigationMenuLink asChild` and `SheetClose asChild` work by cloning
|
||||
* this element and merging their own `onClick` into it. A component that takes
|
||||
* `demo` and ignores everything else silently drops those handlers: the row
|
||||
* still navigates, and the mega panel or the mobile sheet stays open on top of
|
||||
* the page you just arrived at.
|
||||
*/
|
||||
function DemoRow({
|
||||
demo,
|
||||
muted = false,
|
||||
className,
|
||||
...rest
|
||||
}: { demo: DemoMeta; muted?: boolean } & Omit<React.ComponentProps<typeof Link>, 'to'>) {
|
||||
return (
|
||||
<Link
|
||||
to={`/demos/${demo.slug}`}
|
||||
className={cn(
|
||||
'group/row flex gap-3 rounded-lg p-2.5 transition-colors duration-1 ease-enter hover:bg-surface-2',
|
||||
'flex gap-3 rounded-lg p-2.5 transition-colors duration-1 ease-enter hover:bg-surface-2',
|
||||
muted && 'opacity-70 hover:opacity-100',
|
||||
className,
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
<DemoIcon name={demo.icon} className="mt-0.5 size-4 text-accent-fg" />
|
||||
<span className="flex min-w-0 flex-col gap-0.5">
|
||||
@@ -272,10 +288,12 @@ function TasksetSource({ className }: { className?: string }) {
|
||||
|
||||
function HowItWorksPanel({ ctaHref }: { ctaHref: string }) {
|
||||
return (
|
||||
// 820px, not more: the panel hangs off the LEFT edge of the nav, which
|
||||
// starts about 100px in, so anything wider than this pushes past the right
|
||||
// edge of a 1024px laptop and gives the whole page a horizontal scrollbar.
|
||||
<div className="w-[min(90vw,820px)] p-4">
|
||||
<div
|
||||
// 820px, not more: the panel hangs off the LEFT edge of the nav, which
|
||||
// starts about 100px in, so anything wider pushes past the right edge of
|
||||
// a 1024px laptop and gives the whole page a horizontal scrollbar.
|
||||
className="w-[min(90vw,820px)] p-4"
|
||||
>
|
||||
<div className="grid grid-cols-[minmax(0,0.85fr)_minmax(0,1fr)] gap-4">
|
||||
<dl className="flex flex-col gap-3">
|
||||
{CONCEPTS.map((concept) => (
|
||||
|
||||
Reference in New Issue
Block a user