diff --git a/css/tailwind.source.css b/css/tailwind.source.css index 151a738f..f0a202a4 100644 --- a/css/tailwind.source.css +++ b/css/tailwind.source.css @@ -3773,11 +3773,11 @@ .notification-banner, .torrent-toast { - --notify-accent: var(--color-accent-strong); - --notify-accent-strong: var(--color-accent); - --notify-border: var(--surface-overlay-panel-tint); - --notify-background: var(--surface-overlay-panel); - --notify-foreground: var(--color-text); + --notify-accent: var(--notification-banner-accent); + --notify-accent-strong: var(--notification-banner-accent-strong); + --notify-border: var(--notification-banner-border); + --notify-background: var(--notification-banner-background); + --notify-foreground: var(--notification-banner-text); position: relative; display: flex; @@ -3845,37 +3845,38 @@ .notification-banner--critical, .torrent-toast--error { - --notify-accent: var(--color-critical-strong); - --notify-accent-strong: var(--color-critical); - --notify-border: var(--color-ring-critical-soft); - --notify-background: var(--color-card-critical); - --notify-foreground: var(--color-critical-strong); + --notify-accent: var(--notification-banner-critical-accent); + --notify-accent-strong: var(--notification-banner-critical-accent-strong); + --notify-border: var(--notification-banner-critical-border); + --notify-background: var(--notification-banner-critical-background); + --notify-foreground: var(--notification-banner-critical-text); } .notification-banner--success, .torrent-toast--success { - --notify-accent: var(--status-success-strong); - --notify-accent-strong: var(--status-success); - --notify-border: var(--status-success-border); - --notify-background: var(--status-success-surface); - --notify-foreground: var(--status-success-on); + --notify-accent: var(--notification-banner-success-accent); + --notify-accent-strong: var(--notification-banner-success-accent-strong); + --notify-border: var(--notification-banner-success-border); + --notify-background: var(--notification-banner-success-background); + --notify-foreground: var(--notification-banner-success-text); } .notification-banner--info, .torrent-toast--info { - --notify-accent: var(--color-info-strong); - --notify-accent-strong: var(--color-info); - --notify-border: var(--color-info-border); - --notify-background: var(--status-info-surface); + --notify-accent: var(--notification-banner-info-accent); + --notify-accent-strong: var(--notification-banner-info-accent-strong); + --notify-border: var(--notification-banner-info-border); + --notify-background: var(--notification-banner-info-background); + --notify-foreground: var(--notification-banner-info-text); } .notification-banner--warning, .torrent-toast--warn { - --notify-accent: var(--color-warning-strong); - --notify-accent-strong: var(--color-warning); - --notify-border: var(--status-warning-border); - --notify-background: var(--status-warning-surface); - --notify-foreground: var(--status-warning-on); + --notify-accent: var(--notification-banner-warning-accent); + --notify-accent-strong: var(--notification-banner-warning-accent-strong); + --notify-border: var(--notification-banner-warning-border); + --notify-background: var(--notification-banner-warning-background); + --notify-foreground: var(--notification-banner-warning-text); } .status-banner .status-spinner { @@ -5112,8 +5113,8 @@ align-self: flex-start; padding: var(--space-3xs) var(--space-xs); border-radius: var(--radius-full); - background: var(--surface-overlay); - color: var(--text-inverse); + background: var(--unread-badge-background); + color: var(--unread-badge-text); font-size: var(--font-size-3xs); } @@ -5196,8 +5197,9 @@ gap: var(--space-2xs); padding: var(--space-sm) var(--space-md); border-radius: var(--radius-lg); - border: var(--border-width-hairline) solid var(--border-subtle); - background: var(--surface-sunken); + border: var(--border-width-hairline) solid var(--message-bubble-border); + background: var(--message-bubble-background); + color: var(--message-bubble-text); } .dm-message-bubble--incoming { @@ -5206,7 +5208,8 @@ .dm-message-bubble--outgoing { align-self: flex-end; - background: var(--surface-overlay-panel); + background: var(--message-bubble-outgoing-background); + border-color: var(--message-bubble-outgoing-border); } .dm-message-bubble__content { @@ -5217,7 +5220,7 @@ display: flex; gap: var(--space-xs); font-size: var(--font-size-2xs); - color: var(--text-muted); + color: var(--message-bubble-meta); } .dm-message-bubble__status { @@ -5281,6 +5284,18 @@ color: var(--status-danger-on); } + .reply-highlight { + padding: var(--space-xs) var(--space-sm); + border-radius: var(--radius-md); + border: var(--border-width-hairline) solid var(--reply-highlight-border); + background: var(--reply-highlight-background); + color: var(--reply-highlight-text); + } + + .reply-highlight svg { + color: var(--reply-highlight-icon); + } + .dm-composer { display: flex; flex-direction: column; diff --git a/css/tokens.css b/css/tokens.css index 566d0be0..3003107b 100644 --- a/css/tokens.css +++ b/css/tokens.css @@ -141,6 +141,53 @@ --status-neutral-border: var(--color-neutral-border); --status-neutral-on: var(--color-neutral-on); + /* Messaging & notifications */ + --message-bubble-background: var(--surface-sunken); + --message-bubble-border: var(--border-subtle); + --message-bubble-text: var(--text-primary); + --message-bubble-meta: var(--text-muted); + --message-bubble-outgoing-background: var(--surface-overlay-panel); + --message-bubble-outgoing-border: var(--border-overlay); + + --unread-badge-background: var(--status-info-strong); + --unread-badge-text: var(--text-inverse); + + --reply-highlight-background: var(--status-info-surface); + --reply-highlight-border: var(--status-info-border); + --reply-highlight-text: var(--status-info-on); + --reply-highlight-icon: var(--status-info-on); + + --notification-banner-accent: var(--color-accent-strong); + --notification-banner-accent-strong: var(--color-accent); + --notification-banner-border: var(--surface-overlay-panel-tint); + --notification-banner-background: var(--surface-overlay-panel); + --notification-banner-text: var(--text-primary); + --notification-banner-icon: var(--text-primary); + + --notification-banner-critical-accent: var(--status-danger-strong); + --notification-banner-critical-accent-strong: var(--status-danger); + --notification-banner-critical-border: var(--color-ring-critical-soft); + --notification-banner-critical-background: var(--surface-raised-critical); + --notification-banner-critical-text: var(--status-danger-on); + + --notification-banner-success-accent: var(--status-success-strong); + --notification-banner-success-accent-strong: var(--status-success); + --notification-banner-success-border: var(--status-success-border); + --notification-banner-success-background: var(--status-success-surface); + --notification-banner-success-text: var(--status-success-on); + + --notification-banner-info-accent: var(--status-info-strong); + --notification-banner-info-accent-strong: var(--status-info); + --notification-banner-info-border: var(--status-info-border); + --notification-banner-info-background: var(--status-info-surface); + --notification-banner-info-text: var(--status-info-on); + + --notification-banner-warning-accent: var(--status-warning-strong); + --notification-banner-warning-accent-strong: var(--status-warning); + --notification-banner-warning-border: var(--status-warning-border); + --notification-banner-warning-background: var(--status-warning-surface); + --notification-banner-warning-text: var(--status-warning-on); + /* Layout & stacking */ --scrollbar-width: 0.5rem; --scrollbar-track: var(--color-white-soft); diff --git a/docs/design-system.md b/docs/design-system.md index e4ac598b..7761c42e 100644 --- a/docs/design-system.md +++ b/docs/design-system.md @@ -181,6 +181,15 @@ Mix in Tailwind utilities for icon spacing (`gap-3`), sizing (`px-lg`, `py-sm`), `.badge` renders an inline pill (`bg-panel`, uppercase text). Opt into semantic variants with `data-variant="info"`, `data-variant="critical"`, or `data-variant="neutral"`. Layer on utilities for icon alignment or truncation. +### Messaging & Notification Tokens + +Use the dedicated messaging tokens when styling chat surfaces and banners so they inherit theme-safe contrast and icon colors: + +- **Message bubbles:** `--message-bubble-background`, `--message-bubble-border`, `--message-bubble-text`, and `--message-bubble-meta` drive the base bubble surface, while `--message-bubble-outgoing-background`/`--message-bubble-outgoing-border` cover the current-user variant. These map back to surface, border, and text semantic tokens so bubbles maintain AA contrast. 【F:css/tokens.css†L102-L115】 +- **Unread badges:** `--unread-badge-background` and `--unread-badge-text` keep badge text legible at WCAG AA while ensuring iconography stays ≥3:1 against the fill. 【F:css/tokens.css†L117-L118】 +- **Reply highlights:** `--reply-highlight-background`, `--reply-highlight-border`, `--reply-highlight-text`, and `--reply-highlight-icon` align reply callouts with the info status palette. 【F:css/tokens.css†L120-L123】 +- **Notification banners:** Base banner colors map through `--notification-banner-*` tokens, with per-variant slots (`critical`, `success`, `info`, `warning`) pulling from the status palettes for AA-compliant text and 3:1 icon contrast. 【F:css/tokens.css†L125-L154】 + ### Cards `.card` is the base surface for grid items and panels: