From b3e5177397b28efcebcadcbbe49e85f8d011b753 Mon Sep 17 00:00:00 2001 From: Maxi Date: Fri, 4 Sep 2026 09:43:11 +0100 Subject: [PATCH] feat(alert): add themeable subtle variant --- AGENTS.md | 5 +- CHANGELOG.md | 2 + README.md | 17 +++-- .../issue-22-alert-emphasis-ember.jpg | Bin 0 -> 18812 bytes .../issue-22-alert-emphasis-ocean.jpg | Bin 0 -> 19540 bytes docs/evidence/issue-22-alert-narrow-ember.jpg | Bin 0 -> 7770 bytes .../issue-22-alert-theme-override-ember.jpg | Bin 0 -> 12062 bytes src/components/Alert.stories.tsx | 66 +++++++++++++++++- src/components/Alert.tsx | 44 ++++++++---- src/components/components.test.tsx | 17 +++++ src/entries/alert.ts | 2 +- src/index.ts | 2 +- src/stories/Theme.mdx | 25 +++++++ src/styles.css | 4 +- 14 files changed, 159 insertions(+), 25 deletions(-) create mode 100644 docs/evidence/issue-22-alert-emphasis-ember.jpg create mode 100644 docs/evidence/issue-22-alert-emphasis-ocean.jpg create mode 100644 docs/evidence/issue-22-alert-narrow-ember.jpg create mode 100644 docs/evidence/issue-22-alert-theme-override-ember.jpg diff --git a/AGENTS.md b/AGENTS.md index 0043680..c5ddf45 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -256,10 +256,13 @@ Use `Avatar` with a required `name`; sizes are `sm`, `md`, and `lg`. Supply `src ### Alert -Use `Alert` for persistent inline feedback. Tones are `info`, `warning`, `success`, and `danger`. +Use `Alert` for persistent inline feedback. Tones are `info`, `warning`, `success`, and `danger`; variants are `default` and `subtle`. - Use `danger` for failures that need immediate attention; it uses `role="alert"`. +- Use `subtle` for persistent advisory regions such as danger zones that should communicate meaning without competing with current content. Subtle alerts use `role="status"` unless `role` is set explicitly. - Use quieter tones for advisory state; they use `role="status"`. +- Theme alert fills and borders with `--bits-alert-surface` and `--bits-alert-border`; do not target private `.bits-alert-*` selectors. +- Pass `icon={null}` when the alert should have no marker. Subtle alerts otherwise use a compact, glyph-free marker by default. - Provide a concrete recovery control through `action` when the user can resolve the condition. - Do not use Alert for transient confirmation that is better handled by Toast. - Do not use Toast as the only record of a blocking error. diff --git a/CHANGELOG.md b/CHANGELOG.md index 39eb981..59f91f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,11 +10,13 @@ this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ### Added - Dialog block content, compact and medium sizes, and disabled/loading confirmation states for short form workflows. +- A subtle Alert variant with derived low-emphasis surfaces, borders, and compact markers. ### Changed - Dialog focus trapping now includes native select, textarea, editable, and explicitly tabbable controls. - An open Select consumes Escape before a containing dialog closes. +- Alert surfaces and borders can be themed through `--bits-alert-surface` and `--bits-alert-border`. ## 0.2.0 - 2026-09-02 diff --git a/README.md b/README.md index d56e0f7..6e443f7 100644 --- a/README.md +++ b/README.md @@ -177,21 +177,30 @@ import { Segmented } from '@16-bits-design/ui/segmented'; ### Alert -Use `Alert` for persistent inline feedback that must remain available in the page. Danger alerts use `role="alert"`; info, warning, and success alerts use the quieter `role="status"`. Actions remain explicit composable controls. +Use `Alert` for persistent inline feedback that must remain available in the page. +The default variant uses a strong tone border for events that need attention now; +use `variant="subtle"` for persistent advisory regions such as a danger zone. +Subtle alerts use a compact marker and the quieter `role="status"`, including for +the danger tone. Actions remain explicit composable controls. ```tsx import { Alert } from '@16-bits-design/ui/alert'; import { Button } from '@16-bits-design/ui/button'; Retry} + title="Delete this organization" + action={} > - The service returned an unexpected response. + Permanently removes the organization and all of its projects. ``` +The derived subtle colors follow the active tone and theme. A theme can provide +exact authored values through `--bits-alert-surface` and `--bits-alert-border` +without targeting component classes. Pass `icon={null}` to omit the marker. + ### Table Use the composable table primitives for genuinely tabular data. `Table` keeps wide content inside a keyboard-focusable horizontal scroll region; give that region a context-specific `scrollLabel`. End-aligned cells use tabular numerals automatically. diff --git a/docs/evidence/issue-22-alert-emphasis-ember.jpg b/docs/evidence/issue-22-alert-emphasis-ember.jpg new file mode 100644 index 0000000000000000000000000000000000000000..18603b6d1d9ed13bafe0837b592bf8d5a6df75dd GIT binary patch literal 18812 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 literal 0 HcmV?d00001 diff --git a/docs/evidence/issue-22-alert-emphasis-ocean.jpg b/docs/evidence/issue-22-alert-emphasis-ocean.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bed4eaf26cbad5f6e103642d09db271c0bacc3ec GIT binary patch literal 19540 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 C+L@<-#(}_F%AFv zySqP#4bJ^J+1CB~?RuA#G_yZmrazk812KP%{#t$uum`eVf8T+FduwM5-vl_Yf8Rd+ zU)S~a8NRO%-4Fcww%F+0pT7I(%Rkp0F#h|uyE4EZ_FVQE>Kg+506PhKickI%?|*LT zHT66d;A~h4Y;-)98uY;WNSjLcVc!yKd;E`m_=UXT8=mjwOGGzDy{71E`*3!uEp8{7pHGRi^S?6n-S`O%8yV0OI6BXzbj&WKua zZMIY+yXI`tE@c8OJQ9YDlZ~bD)1^D(jcqnl{n{A(X5Qk!_%2}1dKX}}S+ol%`KT7{ zcLB}QW;^$A6^owyMpEhWkrj} zZq~U}M?LKjlCh*>PT=w|xIeAy!De8HL84_uIEfZ>!u>`-1{cInzQLt9%R4yv^hEWk zVnSIaft8g;*7_Znq&`aP-TI)(j9pg}*Tj*^Kr<{5!=k#-WAaKtl681njdHm1866`N zdU%P!YZAlJ2F;MS=6l_iP|^Ug01vJ+Kkei)la7aeKaIY)QIbGcZ<*P2E`p;ONZM?< zH(qV@F6vO;v4(=E>sRKQIrT3hBJN!h7nmTp0mcwkTn-vthF&Af+ZQw?7M2mULGNvY z%p0T8TbK!GY*C{ev)wq$OLZvonj~I%DPu;7NSRVtOaL%uWCdmc^GoYZqcx6Lh4U(2 z-P#2lJs)d(u&)XiKInWYl9$!mUo5yQMLVc-bhky`f^-=wt&Qk?pyE~WemFyAbdMbG z^3x;W0)h(*^}Yj7G#0zK1}*}7;4wc=0oU(Dbp3L6ra0Y_m`0VRj&vv&?eK(goX17N zntg3@jG+Dav-Qm(_B}GPU4tcYHHIKe%O(m-?OQrZT0g}|$m%*V@m2Cs9~~7>Z{ng0 z1YRtn16l2%Y7|RwzI{c1UB_Q{6CGS>MMMs{hYJYb67IlEnRXOTB+E0YY=$Qq%1{kh z-%aFiL?W-<8uhbLx+92m0UjgehV?T}a=WLFe%Re}zq$Z!qx4rqiYUtXT-m61qiR9J z@cP7yYVJ-W>3pW5GT6cxCPQ(No69bCf;3m~SVZJ#s1d?w056Nry)9jfeNkY2>@QBL z$QUFNds%RNErmfUMvf9Wz5Zf^a8fN~WDpx!4&{Mc4af7^kDht*Q|%G6=pHU9dKeZy zTPi~~GgwSPzZ-b#8F}RE_77xM=I+Rvd)Z(*#hzpW8%Shs#GzW_yf8)s?gp)ZU!0OX zOeSVCJr*w3rBHd!(Yz41WQZU=x|DIM9~dm&9&P`|;9V&06ih&^4knoU2qUFUjFC(2 zuq=$oBoDlXGm^9|s5bsauDm=OvFg$=LTY-R;h^MYNTa!-erb(aC1y#RG@bnUCI_}f zE>7%fbCb6DG@~e|x9F!h;+F<9Iwzg$1O~g^(oPxbd{UBIo`6|K4q#P0v(@m^U#%JQ-%iEnjCRb{MK_n7?-6OKP!OQe^lwxRcl)4$ENi z`%!HPg@{IW?)Eqh+7%56yy@j;-WQgbicHp7T%Dd*x>K?RjdyGd*DGvld~quB@Tm~i znNG?A?zz;k0k+mR>Op&1d9F!ybGhbB@Gt2;`lsAi4^|=7(BR9i9o=YN3P!3Ex|0hg zEw7(F^JQ<(<0tJuKjkRhE#b#k=N5P-Fj4sU81i!d>Ak7adh8xlv+?0ubu#+lTv3|a z_g*glW#D{v_RZY+%u~{BerD~neJyN45&o>hkgt#T8b@jj4PLb9T}!{0nx?z&pqAtk z^V*pdV$Cq58(pwE3v&VbbkBH(zv8x7vbR>laZp55ptd1+Nj@|3si|i4RayUuvL}z~ z+$&iWOuvs?$PySfoTxII(H>IL$))6ca=wN}V8nTpmKM#=JX$9z&JR~U7P>;_dr89y zjKat>^yUPH2QzaSCdqtWFK91~FpL`un5R_B1!y7Nuh_nHVZ<`_Wb{Z2H#N(BZlj?W ztOf;Ta|X{B4xf}Qp2K!VPjuu9abZ02(h7=^lk`A|qZ-x`9OxJj66>Elq=h{-7Mrv+KGH@u;I$@v(xt5;)1o4P)f% zK2ks0mWruVX|s5)$pg1iv6`3qMen=6(? z7T?`Y%3etoh3x_eCTbV|jwpQB=UW2uYE!wnQ!Jg$vuCK~T5QcGV#Q zS6aL{QBNu?e(dB&!;QeAr<|&?FX)xyoduIQVx@ttp^FjFr~%*qeLk5+_b7p*qC42u zF#7gpWrdAebyr@GWv7NogT+2)N@b{43Oz#`0(U~Hd(09Aaf*zEP>=*+0tSbSetgD8 z2y!No!{Bk1wPrgF;LhcBaY$QdY2hsdBMy})1C0jfy@#W*74hf~VDNjmE16^#rCO6k z;oIP64Z$J!K**TQW2!mL)b6xeGaXGt^P)Rs*igfe&sersRXQ;U-vzb&YTxTJ`QMaK z5i}qa?ilJlRzQw)hE)5+9gO5UI zR!~k|EuH1M4CVAUUcDa7MFrEHM_IRWZY9-0!iHV^q2P{d+MaPgiD6rL$}HZxpeQCV zz%-GP$g1_}rc>fI_ddEp(N5 zY}81waresxMnZ$Pvr>A&D{Cj&sxaj2aGfBED>-rG88lqikP=D3VrIrrV@IQks zTE*a<+QFgG(L6)kRqeWb7w}a|!&D60R0)Rq6f{>cSiA)aZ|~#YUBII-iCgesd++8) z11j@Q-|(B~SC?>bx2qm@K4HC~sCu5Ov_Zp*plyEKg!1YhS7>}K1LeiE7$t> z>F$`|gZ8p@aQ}<(O}{4@^yH06LMb0Cg@m?>T{SJZ9-l>}%a6DhqS`}5cR`Sk2{eUz zI}8VGUGDA50cTThjp!_UniWg4v{?f;!xpvGeAQ2Fp0Fu7gUYj~CzbV8vfPQ8%<8mRi#_%(a#N;d>_%3X6V#^$ zqzQ^ym)8bCQX}h=^5;ZdgXgl(tZUKgGzrWt08#Wum`|1(Ua+uy{horIxQJrr1;6YH zVa}~OB{u)fJtkcxtbwBmj5EXqNSMEWuNDJzv5KptwTv!&^)Gw(>l|x`it(jCy;WcE zFGx?!Bz=;Gdff^R_Pn`}{afr?mCC&93SaoQ1DQ4+vOQ=(iGikEL0uZ{x%E!htttYenMGZUk!#w%z!$Wq$b%)IVDVVZ z#T5w&vR7E-+VAX@g;@2PybUK5Pb?m2{_$)dV(ac0ripglw{lSo=y{Q39jn-InZf&f}kyc)V zQUW`^v!VohcAPZClEs&K=O$1RX;n%k110*!a=yLYzZdMk7V>aWjFvHcV~@qhXRPgA zm*(jd8%hbxy2=#*IPJCdXJSrSjtD%4zcKFhk3OLSNJUA9CPT z4y!2d=U9}1C<#i8Yt2RDOUKc6@zv>?{7cvDA6%ntr}sa5;iru`wpqS7_=_jR6AlCg^{yl_ zzf4=Ur^KCg@t!<2Nt?vucJBVt+PBmEa{jk%&u_;2_q08Pm1D1nDv2+@OUmcO74R9h z{f450!3EjYe^2D>xQ;y~g+eG;Ty#Kp919tbrP=w7JT7?Ivf*jIB}Z%J_4gYV{h3RFt<_8Uo05q;%ZwYV_?2P5_*ux2d5wyb+iO9A^<-Uck(Vr1 z@lqV9X^>o>WRsNMcFZgx?#1M2pQw&h5aPDABEb^z@+?M1VQajEnW^y&-7fe{7wOxu zj`jWB(;uH0sd~y88E+@0O?AR?9(hlwsnO7ukZlQXt2O8tDj=d^bl!28l)`ok%}~2) z;b5@HbrY3Pe)HkS6?@q5p`q<~RmhFs^UA5c&|MM4tCIR(J&9+u2XALKjtj&CS=*AC z%X875GzL;aqCI=gVXwq%VX-8WP>2awGb2;@>JtAY8_*slY%V>xB5wJPh# zT))Ng-;?WIa6(bwVd36#|8wqb5ESC!!Oo>>EHZfoQo)mr@DZ%7DZC4^DuI=LHj!E0}Am&Q*~W6qHmq;; zS#0SKzlQp}tOQh6WRw)|bGLJN5$M(<``Zb-^fDQ#Vc3vr7!Ao@p*Qg?1-O~w{ph+t z?1Nm&*^yfUm~3o&VW3GV?__Zc{Z#U_p=*Dr^zx08D5?tnd9IaAL}|!NuxEG8yiIU zphS^YW}QzabmkqIS_HpP1c+Qr*E5xX**99zAb zDQvf@J=S^WMe$^ZdnJRo(UQP7b6_Qr<(x%CGLM?Ob4!>ccw>{vTzvPu7fkItX5#it=pp!=BUF`T*-+eR%_+UOwe7B7 z2?}BH$K*$}#^hP-UOG4XkEA}hP-?_O? zY2SxEXos6pP>o9KjkC~Qz|Xv;1gn_f10t8d);mrk>R>%&(>aFI2(dY6HHGvL=n2N& zhq(kBOZ&!GKe3AV1OWK&47BXwI_wBV**u97buWrYYUfiul%g8#LwrJbcpIwsfcK&3R+y p$2zzvXNW3tk%vRbNro8c@!PMu*InwL@=pf-$-w_R1`Kwe|2scd$xQ$N literal 0 HcmV?d00001 diff --git a/docs/evidence/issue-22-alert-theme-override-ember.jpg b/docs/evidence/issue-22-alert-theme-override-ember.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1dfd39954085183224902336579396e80e5a3328 GIT binary patch literal 12062 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 J0wmMezX6I<5)%Lb literal 0 HcmV?d00001 diff --git a/src/components/Alert.stories.tsx b/src/components/Alert.stories.tsx index aca75a5..69822a9 100644 --- a/src/components/Alert.stories.tsx +++ b/src/components/Alert.stories.tsx @@ -1,6 +1,12 @@ import type { Meta, StoryObj } from '@storybook/react-vite'; import { Alert } from './Alert'; import { Button } from './Button'; +import type { ThemeCSSProperties } from '../theme'; + +const authoredDangerZoneTheme: ThemeCSSProperties = { + '--bits-alert-surface': '#170d0b', + '--bits-alert-border': '#4a231c', +}; const meta = { title: 'Components/Alert', @@ -8,11 +14,13 @@ const meta = { tags: ['autodocs'], args: { tone: 'info', + variant: 'default', title: 'Maintenance window scheduled', children: 'Requests may be delayed for up to two minutes while the edge nodes restart.', }, argTypes: { tone: { control: 'inline-radio', options: ['info', 'warning', 'success', 'danger'] }, + variant: { control: 'inline-radio', options: ['default', 'subtle'] }, action: { control: false }, icon: { control: false }, }, @@ -42,6 +50,60 @@ export const Tones: Story = { ), }; +export const SubtleTones: Story = { + args: { variant: 'subtle' }, + render: () => ( +
+ + Version 4.8 can be enabled from workspace settings. + + + 86% of this month's execution allowance has been used. + + + The key remains available until you leave this page. + + + Destructive organization controls are grouped below. + +
+ ), +}; + +export const EmphasisComparison: Story = { + render: () => ( +
+ + No changes were made. Check your connection and try again. + + Delete organization} + > + Permanently removes the organization and all of its projects. + +
+ ), +}; + +export const ThemeOverride: Story = { + args: { variant: 'subtle', tone: 'danger' }, + render: () => ( +
+ Delete organization} + > + Permanently removes the organization and all of its projects. + +
+ ), +}; + export const WithRecoveryAction: Story = { render: () => ( (
- View usage}> - Some new executions may be held if the remaining allowance is consumed. + Delete organization}> + Permanently removes the organization and all of its projects.
), diff --git a/src/components/Alert.tsx b/src/components/Alert.tsx index 365466b..a591b45 100644 --- a/src/components/Alert.tsx +++ b/src/components/Alert.tsx @@ -3,6 +3,7 @@ import type { HTMLAttributes, ReactNode } from 'react'; import { cn } from '../lib/cn'; export type AlertTone = 'info' | 'warning' | 'success' | 'danger'; +export type AlertVariant = 'default' | 'subtle'; const alertIcons: Record = { info: 'i', @@ -13,6 +14,7 @@ const alertIcons: Record = { export type AlertProps = Omit, 'title'> & { tone?: AlertTone; + variant?: AlertVariant; title: ReactNode; icon?: ReactNode; action?: ReactNode; @@ -22,6 +24,7 @@ export const Alert = forwardRef( ( { tone = 'info', + variant = 'default', title, icon, action, @@ -31,22 +34,33 @@ export const Alert = forwardRef( ...props }, ref, - ) => ( -
- -
-
-
{title}
- {children === undefined ? null :
{children}
} + ) => { + const defaultMarker = variant === 'subtle' ? null : alertIcons[tone]; + + return ( +
+ {icon === null ? null : ( + + )} +
+
+
{title}
+ {children === undefined ? null :
{children}
} +
+ {action === undefined ? null :
{action}
}
- {action === undefined ? null :
{action}
}
-
- ), + ); + }, ); Alert.displayName = 'Alert'; diff --git a/src/components/components.test.tsx b/src/components/components.test.tsx index c08698f..14902a7 100644 --- a/src/components/components.test.tsx +++ b/src/components/components.test.tsx @@ -162,6 +162,23 @@ describe('display components', () => { expect(screen.getByRole('button', { name: 'Retry request' })).toBeEnabled(); }); + it('renders subtle alerts with a compact marker and advisory semantics', () => { + render(Destructive controls follow.); + + const alert = screen.getByRole('status'); + expect(alert).toHaveClass('bits-alert--subtle', 'bits-alert--danger'); + expect(alert.querySelector('.bits-alert__icon--marker')).toBeEmptyDOMElement(); + expect(stylesheet).toContain('var(--bits-alert-border, var(--bits-alert-tone))'); + expect(stylesheet).toContain('var(--bits-alert-surface, var(--bits-raised))'); + expect(stylesheet).toContain('var(--bits-alert-border, color-mix'); + expect(stylesheet).toContain('var(--bits-alert-surface, color-mix'); + }); + + it('allows an alert marker to be omitted explicitly', () => { + render(Message.); + expect(screen.getByRole('status').querySelector('.bits-alert__icon')).not.toBeInTheDocument(); + }); + it('exposes only live Ember and Ocean theme tokens', () => { expect(builtInThemes).toEqual(['ember', 'ocean']); expect(colors.primary).toBe('var(--bits-primary)'); diff --git a/src/entries/alert.ts b/src/entries/alert.ts index 91c7943..8b90e7a 100644 --- a/src/entries/alert.ts +++ b/src/entries/alert.ts @@ -1,2 +1,2 @@ export { Alert } from '../components/Alert'; -export type { AlertProps, AlertTone } from '../components/Alert'; +export type { AlertProps, AlertTone, AlertVariant } from '../components/Alert'; diff --git a/src/index.ts b/src/index.ts index db20e86..3ffdc3e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ export { Alert } from '@16-bits-design/ui/alert'; -export type { AlertProps, AlertTone } from '@16-bits-design/ui/alert'; +export type { AlertProps, AlertTone, AlertVariant } from '@16-bits-design/ui/alert'; export { Avatar } from '@16-bits-design/ui/avatar'; export type { AvatarProps, AvatarSize } from '@16-bits-design/ui/avatar'; diff --git a/src/stories/Theme.mdx b/src/stories/Theme.mdx index a2f4b6c..982b815 100644 --- a/src/stories/Theme.mdx +++ b/src/stories/Theme.mdx @@ -130,6 +130,31 @@ a stable selector or application state value: +## Component color overrides + +Component-level variables are optional. They inherit through a theme container and +let a design tune a component without depending on its private class names. + + + + + + + + + +
VariablePurposeFallback
--bits-alert-surfaceAlert background fill--bits-raised, or a tone-derived wash for subtle alerts
--bits-alert-borderAlert border colorThe alert tone, or a weakened tone mix for subtle alerts
+ +For example, a theme with authored danger-zone values can set both variables on a +container. The same Alert API and markup remain unchanged: + +```css +.brand-danger-zone { + --bits-alert-surface: #170d0b; + --bits-alert-border: #4a231c; +} +``` + Keep text/background and interactive-state combinations accessible. In particular, check `--bits-ink` on `--bits-primary`, all text levels on surfaces, and focus rings. diff --git a/src/styles.css b/src/styles.css index 57b8661..52b8028 100644 --- a/src/styles.css +++ b/src/styles.css @@ -362,8 +362,9 @@ .bits-badge--danger { background: var(--bits-danger); } .bits-badge--outline { border: var(--bits-border-width) solid currentColor; background: transparent; color: var(--bits-text-muted); } -.bits-alert { --bits-alert-tone: var(--bits-primary); display: flex; align-items: flex-start; gap: var(--bits-space-3); width: 100%; padding: var(--bits-space-3); border: var(--bits-border-width) solid var(--bits-alert-tone); background: var(--bits-raised); color: var(--bits-text); font-family: var(--bits-font-body); } +.bits-alert { --bits-alert-tone: var(--bits-primary); display: flex; align-items: flex-start; gap: var(--bits-space-3); width: 100%; padding: var(--bits-space-3); border: var(--bits-border-width) solid var(--bits-alert-border, var(--bits-alert-tone)); background: var(--bits-alert-surface, var(--bits-raised)); color: var(--bits-text); font-family: var(--bits-font-body); } .bits-alert__icon { display: flex; align-items: center; justify-content: center; flex: none; width: 24px; height: 24px; background: var(--bits-alert-tone); color: var(--bits-ink); font: 400 10px/1 var(--bits-font-display); } +.bits-alert__icon--marker { width: 12px; height: 12px; margin-top: 2px; } .bits-alert__content { display: flex; align-items: center; justify-content: space-between; gap: var(--bits-space-4); flex: 1; min-width: 0; } .bits-alert__copy { display: flex; flex-direction: column; gap: var(--bits-space-1); min-width: 0; } .bits-alert__title { color: var(--bits-text); font-size: var(--bits-font-size-small); font-weight: 700; line-height: 1.45; } @@ -373,6 +374,7 @@ .bits-alert--warning { --bits-alert-tone: var(--bits-amber); } .bits-alert--success { --bits-alert-tone: var(--bits-success); } .bits-alert--danger { --bits-alert-tone: var(--bits-danger); } +.bits-alert--subtle { border-color: var(--bits-alert-border, color-mix(in srgb, var(--bits-alert-tone) 30%, var(--bits-surface))); background: var(--bits-alert-surface, color-mix(in srgb, var(--bits-alert-tone) 8%, var(--bits-surface))); } @media (max-width: 480px) { .bits-alert__content { align-items: flex-start; flex-direction: column; } .bits-alert__action { width: 100%; }