Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 21 additions & 10 deletions src/components/callout-banner/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
<component
:is="clickable ? 'button' : 'div'"
:type="clickable ? 'button' : undefined"
data-slot="callout-banner"
:data-tone="tone"
:data-clickable="clickable ? '' : undefined"
class="flex flex-col gap-3 rounded-menu-shell border px-4 py-3 text-left sm:flex-row sm:items-center"
:class="[toneClass, clickable ? interactiveClass : '']"
>
Expand Down Expand Up @@ -68,19 +71,27 @@ const props = withDefaults(defineProps<{
})

// Full literal class strings per tone — Tailwind scans source text, so a runtime
// concat would never be generated. Both tones now use a soft-token triplet.
const toneClass = computed(() =>
props.tone === 'destructive'
? 'border-destructive-border bg-destructive-soft'
: 'border-warning-border bg-warning-soft',
)
// concat would never be generated. Clickable hover uses the *-soft-hover tokens
// (utilities layer) so the wash is visible and stays in the same tone family.
const toneClass = computed(() => {
if (props.tone === 'destructive') {
const rest = 'border-destructive-border bg-destructive-soft'
return props.clickable
? `${rest} transition-colors hover:bg-destructive-soft-hover hover:border-destructive-border-hover`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Move hover chrome back into style.css

For every clickable banner, these hover:* and transition-colors utilities put interaction chrome in the Vue utility layer, leaving the new data-slot/data-tone attributes unused and preventing this state from being maintained through the library's central chrome contract. Move the tone-specific hover and transition rules into style.css, keyed by the added data attributes, rather than resolving the cascade conflict by bypassing the required ownership boundary.

AGENTS.md reference: AGENTS.md:L112-L114

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep the border unchanged when deepening the hover fill

On every clickable-banner hover, this now deepens both the background and the border, stacking two simultaneous chrome changes where the design contract permits one layer to change in place. Preserve the tone by deepening only the soft fill and remove the hover:border-* treatment and its dedicated border-hover tokens.

AGENTS.md reference: AGENTS.md:L142-L151

Useful? React with 👍 / 👎.

: rest
}
const rest = 'border-warning-border bg-warning-soft'
return props.clickable
? `${rest} transition-colors hover:bg-warning-soft-hover hover:border-warning-border-hover`
: rest
})

const iconClass = computed(() =>
props.tone === 'destructive' ? 'text-destructive' : 'text-warning-foreground',
)

// When the whole banner is the affordance, it gets the neutral overlay hover the
// rest of the app's clickable surfaces use — the tile's own chrome, not a page
// injection.
const interactiveClass = 'w-full transition-colors hover:bg-accent' /* ui-allow-style */
// When the whole banner is the affordance, hover stays in the same tone family
// (see [data-slot="callout-banner"] rules in style.css) — not hover:bg-accent,
// which replaced destructive/warning fills with neutral gray.
const interactiveClass = 'w-full cursor-pointer'
</script>
8 changes: 8 additions & 0 deletions src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -1089,6 +1089,8 @@
call sites (see --muted-soft above for why color-mix, not a literal). */
--destructive-soft: color-mix(in oklab, var(--destructive) 5%, transparent);
--destructive-border: color-mix(in oklab, var(--destructive) 30%, transparent);
--destructive-soft-hover: color-mix(in oklab, var(--destructive) 14%, transparent);
--destructive-border-hover: color-mix(in oklab, var(--destructive) 45%, transparent);
--border: oklch(0.915 0.0045 72);
/* Alpha policy: the soft/faint divider and card-edge rung — same color-mix
reasoning as --muted-soft/--destructive-soft, reproducing `border-border/60`
Expand Down Expand Up @@ -1387,6 +1389,8 @@
--warning-solid-foreground: oklch(0.18 0.02 75);
--warning-soft: oklch(0.97 0.045 80);
--warning-border: oklch(0.86 0.10 80);
--warning-soft-hover: color-mix(in oklab, var(--warning-foreground) 16%, var(--warning-soft));
--warning-border-hover: color-mix(in oklab, var(--warning-foreground) 30%, var(--warning-border));
--info: oklch(0.62 0.15 235);
--info-foreground: oklch(0.36 0.12 235);
--info-soft: oklch(0.96 0.035 235);
Expand Down Expand Up @@ -1954,6 +1958,8 @@
--color-destructive-foreground: var(--destructive-foreground);
--color-destructive-soft: var(--destructive-soft);
--color-destructive-border: var(--destructive-border);
--color-destructive-soft-hover: var(--destructive-soft-hover);
--color-destructive-border-hover: var(--destructive-border-hover);
--color-border: var(--border);
--color-border-soft: var(--border-soft);
--color-input: var(--input);
Expand Down Expand Up @@ -2036,6 +2042,8 @@
--color-warning-solid-foreground: var(--warning-solid-foreground);
--color-warning-soft: var(--warning-soft);
--color-warning-border: var(--warning-border);
--color-warning-soft-hover: var(--warning-soft-hover);
--color-warning-border-hover: var(--warning-border-hover);
--color-info: var(--info);
--color-info-foreground: var(--info-foreground);
--color-info-soft: var(--info-soft);
Expand Down
Loading