diff --git a/apps/web/app/components/ui/Button/Button.css b/apps/web/app/components/ui/Button/Button.css index 5caa2ad..0a1f4a1 100644 --- a/apps/web/app/components/ui/Button/Button.css +++ b/apps/web/app/components/ui/Button/Button.css @@ -26,6 +26,9 @@ * "Ghost / Large / Default" is the one cell in the matrix with no padding while its own Hover and Disabled cells have it - an authoring slip that would make the button jump on hover. Padding is kept on all ghost states. + * Ghost is repainted to the Claude Design drafts rather than to the Figma + frame: text-only throughout, no hover fill, no lift, widening gap. See + the block below and the ghost tokens in semantic.css. * Disabled uses the opaque `-bg-disabled` / `-fg-disabled` tokens rather than Figma's 40% opacity, so the page never shows through a disabled control. `--control-opacity-disabled` still holds the 0.4 if that is ever wanted. @@ -190,11 +193,28 @@ --sh-btn-border-disabled: var(--interactive-ghost-border-disabled); } - /* Figma gives the ghost md/lg cells radius.md while every other cell uses - radius.sm - reproduced rather than normalised. */ - .sh-btn[data-variant="ghost"][data-size="md"], - .sh-btn[data-variant="ghost"][data-size="lg"] { - border-radius: var(--radius-control-lg); + /* GHOST IS A TEXT LINK, NOT A BUTTON. + The drafts draw "All updates ->" and "What we do ->" as plain text that + turns accent green while the label-to-arrow gap opens from 8px to 12px. + So the ghost variant opts out of the 3px lift the filled controls take - + nothing that has no box should appear to rise off the page - and animates + its gap instead. (The old Figma-quirk override that gave ghost md/lg + radius.md is gone with --radius-control-lg; every control is 4px.) */ + .sh-btn[data-variant="ghost"] .sh-btn__content { + transition: + opacity var(--motion-duration-fast) var(--motion-ease-standard), + gap var(--motion-duration-base) var(--motion-ease-standard); + } + + @media (hover: hover) { + .sh-btn[data-variant="ghost"]:hover:not(:disabled):not([aria-disabled="true"]):not([data-loading]) { + transform: none; + } + + .sh-btn[data-variant="ghost"]:hover:not(:disabled):not([aria-disabled="true"]):not([data-loading]) + .sh-btn__content { + gap: var(--spacing-sm); + } } /* --------------------------------------------------------------------- diff --git a/apps/web/app/components/ui/Card/CardCTA.tsx b/apps/web/app/components/ui/Card/CardCTA.tsx index 07305fd..0ff8ded 100644 --- a/apps/web/app/components/ui/Card/CardCTA.tsx +++ b/apps/web/app/components/ui/Card/CardCTA.tsx @@ -65,7 +65,10 @@ export function CardCTA({ data-surface="dark" className={cx( "sh-card relative flex flex-col gap-lg rounded-surface p-10", - "bg-surface-accent text-text-on-accent shadow-[var(--elevation-popover)]", + /* The drafts rest nothing on a shadow - a panel is a fill and an edge, + and the black is spent on what floats. --elevation-card is that + resting step: none on the dark surface, soft on the light one. */ + "bg-surface-accent text-text-on-accent shadow-[var(--elevation-card)]", "sm:flex-row sm:items-center", className, )} diff --git a/apps/web/app/components/ui/Card/CardContent.tsx b/apps/web/app/components/ui/Card/CardContent.tsx index 2aa88f9..cf12927 100644 --- a/apps/web/app/components/ui/Card/CardContent.tsx +++ b/apps/web/app/components/ui/Card/CardContent.tsx @@ -85,7 +85,7 @@ export function CardContent({ light on both surfaces - text-on-accent is the only always-white role, text-primary would go dark on the light surface. */} {badge ? ( - + {badge} ) : null} diff --git a/apps/web/app/components/ui/Card/CardShell.tsx b/apps/web/app/components/ui/Card/CardShell.tsx index 8b27dd9..1d2b9ab 100644 --- a/apps/web/app/components/ui/Card/CardShell.tsx +++ b/apps/web/app/components/ui/Card/CardShell.tsx @@ -7,7 +7,7 @@ STYLING RULE for this whole directory: * colour and radius come from the tier-2 Tailwind bridge (bg-surface-raised, text-text-accent, border-border-subtle, - rounded-surface, ...) - never a hex, never a tier-1 primitive; + rounded-card, ...) - never a hex, never a tier-1 primitive; * tokens without a bridge utility are spent as arbitrary values, e.g. shadow-[var(--elevation-card)]; * spacing uses the named scale (p-lg = 24, gap-md = 16) so the Figma @@ -143,8 +143,10 @@ export interface CardShellProps { } /** - * The surface every card shares: raised fill, hairline border, 12px corner - * (Figma radius/lg) and the card elevation. + * The surface every card shares: raised fill, hairline border and the 4px + * corner the design drafts draw. `--elevation-card` is the drafts' resting + * shadow, which on the dark surface is none at all - the hairline does the + * separating, and the black is kept for the hover state in card.css. */ export function CardShell({ as = "article", @@ -160,7 +162,7 @@ export function CardShell({ "sh-card", linked && "sh-card--linked", "relative flex bg-[var(--surface-card)] text-text-primary", - "rounded-surface border border-border-subtle shadow-[var(--elevation-card)]", + "rounded-card border border-border-subtle shadow-[var(--elevation-card)]", className, )} > diff --git a/apps/web/app/components/ui/Card/CardStat.tsx b/apps/web/app/components/ui/Card/CardStat.tsx index ee2b6fd..255a6a9 100644 --- a/apps/web/app/components/ui/Card/CardStat.tsx +++ b/apps/web/app/components/ui/Card/CardStat.tsx @@ -72,7 +72,7 @@ export function CardStat({ is falling. */