HTML
<section class="ba-icn" aria-label="Icon-aligned alert banner demo">
<span class="section-label">// alert-banner--icon-aligned</span>
<div class="alert alert--success" role="alert" data-ba-icn-alert>
<div class="alert-icon-wrap" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 11-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg></div>
<div class="alert-content"><div class="alert-header"><span class="alert-title">Changes saved!</span><span class="alert-badge">success</span></div><span class="alert-desc">Your profile has been updated successfully.</span></div>
<button class="alert-dismiss" type="button" aria-label="Dismiss"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>
</div>
<div class="alert alert--error" role="alert" data-ba-icn-alert>
<div class="alert-icon-wrap" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg></div>
<div class="alert-content"><div class="alert-header"><span class="alert-title">Upload failed</span><span class="alert-badge">error</span></div><span class="alert-desc">The file exceeds the 10 MB limit. Please compress or choose a smaller file and try again.</span><div class="alert-actions"><button class="alert-link" type="button">Retry</button><button class="alert-link" type="button">Help</button></div></div>
<button class="alert-dismiss" type="button" aria-label="Dismiss"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>
</div>
<div class="alert alert--warning" role="alert" data-ba-icn-alert>
<div class="alert-icon-wrap" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg></div>
<div class="alert-content"><div class="alert-header"><span class="alert-title">Approaching rate limit</span><span class="alert-badge">warning</span></div><span class="alert-desc long">You have used 4,820 of your 5,000 monthly API requests. Once the limit is reached, all API calls will return a 429 error until the next billing cycle on July 1st. Consider upgrading your plan to avoid service interruption.</span><div class="alert-actions"><button class="alert-link" type="button">Upgrade Plan</button><button class="alert-link" type="button">View Usage</button></div></div>
<button class="alert-dismiss" type="button" aria-label="Dismiss"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>
</div>
<div class="alert alert--info" role="alert" data-ba-icn-alert>
<div class="alert-icon-wrap" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg></div>
<div class="alert-content"><div class="alert-header"><span class="alert-title">Scheduled downtime</span><span class="alert-badge">info</span></div><span class="alert-desc">Maintenance is scheduled for Friday 02:00–04:00 UTC. The dashboard will be read-only during this window.</span><div class="alert-actions"><button class="alert-link" type="button">View Schedule</button></div></div>
<button class="alert-dismiss" type="button" aria-label="Dismiss"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>
</div>
<div class="alert alert--tip" role="alert" data-ba-icn-alert>
<div class="alert-icon-wrap" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg></div>
<div class="alert-content"><div class="alert-header"><span class="alert-title">Pro tip</span><span class="alert-badge">tip</span></div><span class="alert-desc">Press <kbd>⌘ K</kbd> to open the command palette from anywhere.</span></div>
<button class="alert-dismiss" type="button" aria-label="Dismiss"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>
</div>
<div class="alert alert--update" role="alert" data-ba-icn-alert>
<div class="alert-icon-wrap" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 4 23 10 17 10"/><path d="M20.49 15a9 9 0 11-2.12-9.36L23 10"/></svg></div>
<div class="alert-content"><div class="alert-header"><span class="alert-title">Update available — v5.1.0</span><span class="alert-badge">update</span></div><span class="alert-desc long">A new version is ready with bug fixes for the export pipeline, improved dark mode contrast ratios, and a new drag-to-reorder feature in the sidebar. This update is non-breaking and backward compatible.</span><div class="alert-actions"><button class="alert-link" type="button">Update Now</button><button class="alert-link" type="button">Release Notes</button><button class="alert-link" type="button">Later</button></div></div>
<button class="alert-dismiss" type="button" aria-label="Dismiss"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>
</div>
</section> CSS
/* ─── 06 Icon-Aligned Alert Banner — pastel maximalist ────────── */
@import url('https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,600;0,700;0,800;0,900;1,700&family=Fira+Code:wght@400;500&display=swap');
.ba-icn {
--ba-icn-page-bg: #f8f5ff;
--ba-icn-success-bg: #ecfdf4; --ba-icn-success-border: #22c55e; --ba-icn-success-icon-bg: #dcfce7; --ba-icn-success-icon: #16a34a; --ba-icn-success-text: #14532d; --ba-icn-success-title: #15803d;
--ba-icn-error-bg: #fef2f2; --ba-icn-error-border: #f87171; --ba-icn-error-icon-bg: #fee2e2; --ba-icn-error-icon: #dc2626; --ba-icn-error-text: #7f1d1d; --ba-icn-error-title: #b91c1c;
--ba-icn-warning-bg: #fffbeb; --ba-icn-warning-border: #fbbf24; --ba-icn-warning-icon-bg: #fef3c7; --ba-icn-warning-icon: #d97706; --ba-icn-warning-text: #78350f; --ba-icn-warning-title: #b45309;
--ba-icn-info-bg: #eff6ff; --ba-icn-info-border: #60a5fa; --ba-icn-info-icon-bg: #dbeafe; --ba-icn-info-icon: #2563eb; --ba-icn-info-text: #1e3a8a; --ba-icn-info-title: #1d4ed8;
--ba-icn-tip-bg: #fdf4ff; --ba-icn-tip-border: #c084fc; --ba-icn-tip-icon-bg: #fae8ff; --ba-icn-tip-icon: #9333ea; --ba-icn-tip-text: #4a1d96; --ba-icn-tip-title: #7e22ce;
--ba-icn-update-bg: #fff7ed; --ba-icn-update-border: #fb923c; --ba-icn-update-icon-bg: #ffedd5; --ba-icn-update-icon: #ea580c; --ba-icn-update-text: #7c2d12; --ba-icn-update-title: #c2410c;
position: relative;
width: 100%;
min-height: 1000px;
background: var(--ba-icn-page-bg);
background-image: radial-gradient(circle at 20% 20%, rgba(168,85,247,0.08) 0%, transparent 45%), radial-gradient(circle at 80% 80%, rgba(34,197,94,0.08) 0%, transparent 40%), radial-gradient(circle at 60% 10%, rgba(59,130,246,0.07) 0%, transparent 35%);
display: flex; flex-direction: column; align-items: center; justify-content: center;
padding: 48px 20px; gap: 14px;
font-family: 'Nunito', sans-serif;
box-sizing: border-box;
}
.ba-icn *, .ba-icn *::before, .ba-icn *::after { box-sizing: border-box; margin: 0; padding: 0; }
.ba-icn .section-label { font-family: 'Fira Code', monospace; font-size: 10px; letter-spacing: 0.25em; text-transform: uppercase; color: #bbb; }
.ba-icn .alert { width: 100%; max-width: 620px; border-radius: 16px; border: 2px solid; padding: 16px 18px; display: flex; align-items: flex-start; gap: 14px; position: relative; overflow: hidden; transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.25s ease; animation: ba-icn-alertIn 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) both; }
.ba-icn .alert:hover { transform: translateY(-3px) scale(1.005); }
.ba-icn .alert:nth-child(2) { animation-delay: 0.07s; } .ba-icn .alert:nth-child(3) { animation-delay: 0.14s; } .ba-icn .alert:nth-child(4) { animation-delay: 0.21s; } .ba-icn .alert:nth-child(5) { animation-delay: 0.28s; } .ba-icn .alert:nth-child(6) { animation-delay: 0.35s; } .ba-icn .alert:nth-child(7) { animation-delay: 0.42s; }
@keyframes ba-icn-alertIn { from { opacity: 0; transform: translateX(-16px) scale(0.97); } to { opacity: 1; transform: translateX(0) scale(1); } }
.ba-icn .alert::before { content: ''; position: absolute; top: -30px; right: -30px; width: 100px; height: 100px; border-radius: 50%; background: currentColor; opacity: 0.05; pointer-events: none; }
.ba-icn .alert-icon-wrap { flex-shrink: 0; width: 42px; height: 42px; border-radius: 12px; display: flex; align-items: center; justify-content: center; position: relative; }
.ba-icn .alert-icon-wrap svg { width: 22px; height: 22px; }
.ba-icn .alert-icon-wrap::after { content: ''; position: absolute; inset: -3px; border-radius: 14px; border: 2px solid currentColor; opacity: 0; animation: ba-icn-pulse 2.5s ease-in-out infinite; }
@keyframes ba-icn-pulse { 0%, 100% { opacity: 0; transform: scale(1); } 50% { opacity: 0.3; transform: scale(1.08); } }
.ba-icn .alert-content { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.ba-icn .alert-header { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.ba-icn .alert-title { font-size: 15px; font-weight: 800; line-height: 1.25; }
.ba-icn .alert-badge { font-family: 'Fira Code', monospace; font-size: 9px; font-weight: 500; letter-spacing: 0.1em; padding: 2px 7px; border-radius: 4px; flex-shrink: 0; text-transform: uppercase; border: 1.5px solid currentColor; opacity: 0.7; }
.ba-icn .alert-desc { font-size: 13px; font-weight: 600; line-height: 1.6; opacity: 0.75; }
.ba-icn .alert-desc kbd { font-family: 'Fira Code', monospace; font-size: 11px; background: rgba(0,0,0,0.08); padding: 1px 5px; border-radius: 4px; }
.ba-icn .alert-actions { display: flex; gap: 10px; margin-top: 8px; flex-wrap: wrap; }
.ba-icn .alert-link { font-size: 12px; font-weight: 800; letter-spacing: 0.04em; text-decoration: none; padding: 5px 12px; border-radius: 8px; border: 2px solid currentColor; transition: all 0.18s; cursor: pointer; background: transparent; font-family: 'Nunito', sans-serif; }
.ba-icn .alert-link:hover { background: currentColor; color: white !important; }
.ba-icn .alert-dismiss { flex-shrink: 0; width: 28px; height: 28px; border-radius: 8px; display: flex; align-items: center; justify-content: center; border: none; background: transparent; cursor: pointer; opacity: 0.4; transition: opacity 0.2s, background 0.2s; margin-top: 6px; }
.ba-icn .alert-dismiss:hover { opacity: 0.8; background: rgba(0,0,0,0.06); }
.ba-icn .alert-dismiss svg { width: 14px; height: 14px; }
.ba-icn .alert--success { background: var(--ba-icn-success-bg); border-color: var(--ba-icn-success-border); color: var(--ba-icn-success-text); box-shadow: 0 4px 20px rgba(34,197,94,0.15); }
.ba-icn .alert--success .alert-icon-wrap { background: var(--ba-icn-success-icon-bg); color: var(--ba-icn-success-icon); }
.ba-icn .alert--success .alert-title { color: var(--ba-icn-success-title); }
.ba-icn .alert--success .alert-badge { color: var(--ba-icn-success-icon); border-color: var(--ba-icn-success-border); }
.ba-icn .alert--error { background: var(--ba-icn-error-bg); border-color: var(--ba-icn-error-border); color: var(--ba-icn-error-text); box-shadow: 0 4px 20px rgba(248,113,113,0.15); }
.ba-icn .alert--error .alert-icon-wrap { background: var(--ba-icn-error-icon-bg); color: var(--ba-icn-error-icon); }
.ba-icn .alert--error .alert-title { color: var(--ba-icn-error-title); }
.ba-icn .alert--error .alert-badge { color: var(--ba-icn-error-icon); border-color: var(--ba-icn-error-border); }
.ba-icn .alert--warning { background: var(--ba-icn-warning-bg); border-color: var(--ba-icn-warning-border); color: var(--ba-icn-warning-text); box-shadow: 0 4px 20px rgba(251,191,36,0.15); }
.ba-icn .alert--warning .alert-icon-wrap { background: var(--ba-icn-warning-icon-bg); color: var(--ba-icn-warning-icon); }
.ba-icn .alert--warning .alert-title { color: var(--ba-icn-warning-title); }
.ba-icn .alert--warning .alert-badge { color: var(--ba-icn-warning-icon); border-color: var(--ba-icn-warning-border); }
.ba-icn .alert--info { background: var(--ba-icn-info-bg); border-color: var(--ba-icn-info-border); color: var(--ba-icn-info-text); box-shadow: 0 4px 20px rgba(96,165,250,0.15); }
.ba-icn .alert--info .alert-icon-wrap { background: var(--ba-icn-info-icon-bg); color: var(--ba-icn-info-icon); }
.ba-icn .alert--info .alert-title { color: var(--ba-icn-info-title); }
.ba-icn .alert--info .alert-badge { color: var(--ba-icn-info-icon); border-color: var(--ba-icn-info-border); }
.ba-icn .alert--tip { background: var(--ba-icn-tip-bg); border-color: var(--ba-icn-tip-border); color: var(--ba-icn-tip-text); box-shadow: 0 4px 20px rgba(192,132,252,0.15); }
.ba-icn .alert--tip .alert-icon-wrap { background: var(--ba-icn-tip-icon-bg); color: var(--ba-icn-tip-icon); }
.ba-icn .alert--tip .alert-title { color: var(--ba-icn-tip-title); }
.ba-icn .alert--tip .alert-badge { color: var(--ba-icn-tip-icon); border-color: var(--ba-icn-tip-border); }
.ba-icn .alert--update { background: var(--ba-icn-update-bg); border-color: var(--ba-icn-update-border); color: var(--ba-icn-update-text); box-shadow: 0 4px 20px rgba(251,146,60,0.15); }
.ba-icn .alert--update .alert-icon-wrap { background: var(--ba-icn-update-icon-bg); color: var(--ba-icn-update-icon); }
.ba-icn .alert--update .alert-title { color: var(--ba-icn-update-title); }
.ba-icn .alert--update .alert-badge { color: var(--ba-icn-update-icon); border-color: var(--ba-icn-update-border); }
@media (prefers-reduced-motion: reduce) { .ba-icn .alert, .ba-icn .alert-icon-wrap::after { animation: none !important; } } JS
(() => {
const root = document.querySelector('.ba-icn');
if (!root) return;
root.addEventListener('click', (e) => {
const btn = e.target.closest('.alert-dismiss');
if (!btn) return;
const alert = btn.closest('[data-ba-icn-alert]');
if (!alert) return;
alert.style.transition = 'all 0.35s cubic-bezier(0.4,0,0.2,1)';
alert.style.opacity = '0';
alert.style.transform = 'translateX(20px) scale(0.97)';
alert.style.maxHeight = alert.offsetHeight + 'px';
setTimeout(() => {
alert.style.maxHeight = '0';
alert.style.padding = '0';
alert.style.margin = '0';
alert.style.borderWidth = '0';
alert.style.overflow = 'hidden';
}, 150);
});
})();