Open demo

CSS code

HTML
<div class="g-scene" aria-hidden="true"><i></i><i></i><i></i><i></i></div>
<div class="wrap">
<div class="two">
<div><span class="lbl lbl--chip">Modal dialog</span>
  <button type="button" class="g-btn g-btn--strong" data-dialog-open="archive-dialog">Open the dialog</button>
  <dialog class="g-strong g-modal" id="archive-dialog" aria-labelledby="archive-title" aria-describedby="archive-desc" open>
    <form method="dialog">
      <div class="g-modal-body">
        <span class="g-modal-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="5" rx="1.5"/><path d="M5 9v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V9M10 13h4"/></svg></span>
        <h2 id="archive-title">Archive “Q3 brand refresh”?</h2>
        <p id="archive-desc">The project and its 214 files move to the archive. Nobody can edit them until you restore it, and the share links stop working.</p>
      </div>
      <div class="g-modal-actions">
        <button class="g-btn" value="cancel">Cancel</button>
        <button class="g-btn g-btn--accent" value="archive">Archive project</button>
      </div>
    </form>
  </dialog>
</div>
<div><span class="lbl lbl--chip">Toasts and alert</span>
  <div class="g-toasts" role="status">
    <div class="g-strong g-toast" data-toast><span class="g-toast-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.5l4.5 4.5L19 7.5"/></svg></span>
      <p class="g-toast-text"><b>Invoice sent</b>INV-2048 is on its way to Halden & Co.</p>
      <button type="button" class="g-x" aria-label="Dismiss: Invoice sent" data-toast-dismiss><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" aria-hidden="true"><path d="M6 6l12 12M18 6 6 18"/></svg></button></div>
    <div class="g-strong g-toast g-toast--bad" data-toast><span class="g-toast-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"><path d="M12 7v6M12 17v.5"/><circle cx="12" cy="12" r="9"/></svg></span>
      <p class="g-toast-text"><b>Upload failed</b>brief-final.pdf is over the 25 MB limit.</p>
      <button type="button" class="g-x" aria-label="Dismiss: Upload failed" data-toast-dismiss><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" aria-hidden="true"><path d="M6 6l12 12M18 6 6 18"/></svg></button></div>
    <div class="g-strong g-toast g-toast--info" data-toast><span class="g-toast-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 14.5a2 2 0 0 1-2 2H8l-4 3.5V6.5a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2z"/></svg></span>
      <p class="g-toast-text"><b>New comment from Theo</b>“Can we try the headline in sentence case?”</p>
      <button type="button" class="g-x" aria-label="Dismiss: New comment from Theo" data-toast-dismiss><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" aria-hidden="true"><path d="M6 6l12 12M18 6 6 18"/></svg></button></div>
  </div>
  <div class="g-alert"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 3.5 2.5 20h19z"/><path d="M12 10v4.5M12 17.2v.3"/></svg>
    <div><b>Your trial ends in 3 days</b>Add a payment method to keep your 4 projects and 12 collaborators. <a href="#billing">Add payment method</a></div></div>
</div>
</div>
<section class="g-glass g-panel" aria-labelledby="c3"><span class="lbl" id="c3">Tooltips and dropdown menu</span>
  <div class="tools">
    <div class="g-row">
      <span class="g-tip-wrap" data-tip data-open><button type="button" class="g-icon-btn" aria-label="Copy link" aria-describedby="tip-copy"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1"/></svg></button><span class="g-tip" role="tooltip" id="tip-copy">Copy share link</span></span>
      <span class="g-tip-wrap" data-tip><button type="button" class="g-icon-btn" aria-label="Download" aria-describedby="tip-dl"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 4v11M7 10l5 5 5-5M5 20h14"/></svg></button><span class="g-tip" role="tooltip" id="tip-dl">Download as ZIP, 48 MB</span></span>
      <span class="g-tip-wrap" data-tip><button type="button" class="g-icon-btn" aria-label="Invite people" aria-describedby="tip-inv"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="9" cy="8" r="3.5"/><path d="M2.5 20a6.5 6.5 0 0 1 13 0M19 8v6M16 11h6"/></svg></button><span class="g-tip" role="tooltip" id="tip-inv">Invite people to this project</span></span>
    </div>
    <details class="g-dd" data-menu open>
      <summary class="g-btn">Project actions<svg class="g-chev" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg></summary>
      <ul class="g-strong g-menu">
        <li><button type="button"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 20h4L19 9l-4-4L4 16z"/></svg>Rename<kbd>R</kbd></button></li>
        <li><button type="button"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2"/><path d="M16 8V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h2"/></svg>Duplicate<kbd>D</kbd></button></li>
        <li><button type="button"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 12h12M12 6l6 6-6 6M20 4v16"/></svg>Move to team…</button></li>
        <li class="g-sep"><button type="button" class="g-danger"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M10 11v6M14 11v6M6 7l1 12a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2l1-12M9 7V4h6v3"/></svg>Delete project</button></li>
      </ul>
    </details>
  </div>
</section>
</div>
CSS
/* ===== uiCookies Glassmorphism kit: design tokens (identical in every set) =====
   Retheme the whole kit here. Light scene on :root, dark scene on [data-scene="dark"]
   (or any [data-scene] holding a checked [data-scene-switch]). Selectors use :where()
   so the fallbacks below always win. */
:where(:root,[data-scene="light"]){
  color-scheme:light;
  /* background scene: the colour the glass frosts */
  --scene-base:linear-gradient(155deg,#eceffe 0%,#fbeef7 52%,#e6f6fb 100%);
  --scene-1:linear-gradient(140deg,#7c3aed,#c026d3);
  --scene-2:linear-gradient(140deg,#fb7185,#f97316);
  --scene-3:linear-gradient(140deg,#22d3ee,#3b82f6);
  --scene-4:linear-gradient(140deg,#fde047,#fb923c);
  /* glass */
  --glass-tint:255 255 255;
  --glass-border:rgb(255 255 255 / .8);
  --glass-edge:rgb(36 32 88 / .9);
  --glass-highlight:inset 0 1px 0 rgb(255 255 255 / .85);
  --glass-shadow:0 18px 40px -18px rgb(37 30 102 / .45);
  --glass-ink:#16133a;
  --glass-ink-soft:#3b3862;
  --glass-accent:#4338ca;
  --glass-accent-bg:rgb(67 56 202 / .92);
  --glass-on-accent:#fff;
  --glass-check-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --glass-focus:#1e1b4b;
  --glass-good:#14532d;--glass-good-bg:rgb(220 252 231 / .9);
  --glass-bad:#991b1b;--glass-bad-bg:rgb(254 226 226 / .9);
  --glass-warn:#7c2d12;--glass-warn-bg:rgb(254 243 199 / .9);
  --glass-scrim:rgb(22 19 58 / .3);
}
:where([data-scene="dark"]),:where([data-scene]:has([data-scene-switch]:checked)){
  color-scheme:dark;
  --scene-base:linear-gradient(155deg,#0a0c22 0%,#170c2c 52%,#06171f 100%);
  --scene-1:linear-gradient(140deg,#6d28d9,#a21caf);
  --scene-2:linear-gradient(140deg,#e11d48,#ea580c);
  --scene-3:linear-gradient(140deg,#0891b2,#2563eb);
  --scene-4:linear-gradient(140deg,#ca8a04,#c2410c);
  --glass-tint:16 18 44;
  --glass-border:rgb(255 255 255 / .2);
  --glass-edge:rgb(214 220 255 / .72);
  --glass-highlight:inset 0 1px 0 rgb(255 255 255 / .16);
  --glass-shadow:0 18px 40px -18px rgb(0 0 0 / .75);
  --glass-ink:#f5f6ff;
  --glass-ink-soft:#d0d3ee;
  --glass-accent:#a5b4fc;
  --glass-accent-bg:rgb(165 180 252 / .96);
  --glass-on-accent:#14123a;
  --glass-check-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%2314123a' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --glass-focus:#c7d2fe;
  --glass-good:#bbf7d0;--glass-good-bg:rgb(20 83 45 / .7);
  --glass-bad:#fecaca;--glass-bad-bg:rgb(127 29 29 / .7);
  --glass-warn:#fde68a;--glass-warn-bg:rgb(120 53 15 / .7);
  --glass-scrim:rgb(0 0 0 / .5);
}
:where(:root){
  --glass-alpha:.6;          /* panels and cards */
  --glass-alpha-strong:.82;  /* menus, dialogs, toasts: they cover unknown content */
  --glass-alpha-control:.5;  /* buttons and fields sitting on a panel */
  --glass-blur:18px;
  --glass-saturate:150%;
  --glass-radius:20px;
}
/* derived: recomputed inside every scene so a dark scene gets dark glass */
:where(:root,[data-scene]){
  --glass-bg:rgb(var(--glass-tint) / var(--glass-alpha));
  --glass-bg-strong:rgb(var(--glass-tint) / var(--glass-alpha-strong));
  --glass-bg-control:rgb(var(--glass-tint) / var(--glass-alpha-control));
}
/* no backdrop-filter: frosting can't happen, so the glass turns nearly solid */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  :where(:root){--glass-alpha:.94;--glass-alpha-strong:.97;--glass-alpha-control:.9}
}
@media (prefers-reduced-transparency:reduce){
  :where(:root){--glass-alpha:.93;--glass-alpha-strong:.97;--glass-alpha-control:.9;--glass-blur:8px}
}
@media (prefers-contrast:more){
  :where(:root){--glass-alpha:.96;--glass-alpha-strong:.98;--glass-alpha-control:.96}
  :where(:root,[data-scene]){--glass-border:var(--glass-ink);--glass-edge:var(--glass-ink)}
}
/* ===== end of tokens ===== */
/* scene: fixed page background of four gradient orbs (decorative, aria-hidden) */
:where([data-scene]){color:var(--glass-ink)}
.g-scene{position:fixed;inset:0;z-index:-1;overflow:hidden;pointer-events:none;background:var(--scene-base)}
.g-scene i{position:absolute;aspect-ratio:1;border-radius:50%;animation:g-drift 32s ease-in-out infinite alternate}
.g-scene i:nth-child(1){width:clamp(240px,40vw,520px);left:-7%;top:-9%;background:var(--scene-1)}
.g-scene i:nth-child(2){width:clamp(170px,26vw,360px);right:-5%;top:18%;background:var(--scene-2);animation-delay:-9s}
.g-scene i:nth-child(3){width:clamp(220px,34vw,460px);left:28%;bottom:-16%;background:var(--scene-3);animation-delay:-17s}
.g-scene i:nth-child(4){width:clamp(90px,13vw,180px);left:54%;top:7%;background:var(--scene-4);animation-delay:-4s}
@keyframes g-drift{to{transform:translate3d(3vw,4vh,0) scale(1.06)}}
/* glass surface */
.g-glass{background:var(--glass-bg);-webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));
  backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));border:1px solid var(--glass-border);
  border-radius:var(--glass-radius);box-shadow:var(--glass-highlight),var(--glass-shadow);color:var(--glass-ink)}
.g-glass--strong{background:var(--glass-bg-strong)}
.g-panel{padding:24px}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.g-muted{color:var(--glass-ink-soft)}
@media (prefers-reduced-motion:reduce){.g-scene i{animation:none}}
/* buttons: glass control, tinted accent glass, quiet text button, round icon button */
.g-row{display:flex;flex-wrap:wrap;align-items:center;gap:12px}
.g-row+.g-row{margin-top:14px}
.g-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:44px;padding:0 20px;
  border:1px solid var(--glass-edge);border-radius:999px;background:var(--glass-bg-control);
  -webkit-backdrop-filter:blur(var(--glass-blur));backdrop-filter:blur(var(--glass-blur));box-shadow:var(--glass-highlight);
  color:var(--glass-ink);font:inherit;font-size:.95rem;font-weight:600;line-height:1;text-decoration:none;cursor:pointer;
  transition:background-color .2s,transform .2s}
.g-btn:hover{background:var(--glass-bg-strong)}
.g-btn:active{transform:translateY(1px)}
.g-btn:focus-visible,.g-icon-btn:focus-visible{outline:3px solid var(--glass-focus);outline-offset:3px}
.g-btn svg,.g-icon-btn svg{width:18px;height:18px;flex:none}
.g-btn--accent{border-color:transparent;background:var(--glass-accent-bg);color:var(--glass-on-accent);
  box-shadow:var(--glass-highlight)}
.g-btn--accent:hover{background:var(--glass-accent-bg);filter:brightness(1.08)}
.g-btn--quiet{border-color:transparent;background:transparent;-webkit-backdrop-filter:none;backdrop-filter:none;box-shadow:none;
  text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:1px}
.g-btn--quiet:hover{background:var(--glass-bg-control)}
.g-btn--strong{background:var(--glass-bg-strong)} /* for buttons placed straight on the scene */
.g-btn--sm{min-height:36px;padding:0 14px;font-size:.85rem}
.g-btn--lg{min-height:54px;padding:0 28px;font-size:1.05rem}
.g-btn:disabled{opacity:.5;cursor:not-allowed;transform:none}
.g-icon-btn{display:inline-grid;place-items:center;width:44px;height:44px;padding:0;border:1px solid var(--glass-edge);border-radius:50%;
  background:var(--glass-bg-control);-webkit-backdrop-filter:blur(var(--glass-blur));backdrop-filter:blur(var(--glass-blur));
  box-shadow:var(--glass-highlight);color:var(--glass-ink);cursor:pointer;transition:background-color .2s,transform .2s}
.g-icon-btn:hover{background:var(--glass-bg-strong)}
.g-icon-btn:active{transform:scale(.96)}
.g-icon-btn--accent{border-color:transparent;background:var(--glass-accent-bg);color:var(--glass-on-accent)}
.g-icon-btn--accent:hover{background:var(--glass-accent-bg);filter:brightness(1.08)}
.g-icon-btn--lg{width:56px;height:56px}
.g-icon-btn--lg svg{width:22px;height:22px}
@media (prefers-reduced-motion:reduce){.g-btn,.g-icon-btn{transition:none}.g-btn:active,.g-icon-btn:active{transform:none}}
/* overlays sit on unknown content, so they use the more opaque --glass-bg-strong */
.g-strong{background:var(--glass-bg-strong);-webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));
  backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));border:1px solid var(--glass-border);box-shadow:var(--glass-highlight),var(--glass-shadow);color:var(--glass-ink)}
/* dialog: native <dialog>, opened with showModal() so focus is trapped and Escape closes it */
.g-modal{width:min(440px,calc(100vw - 32px));max-width:none;padding:0;border-radius:var(--glass-radius)}
.g-modal::backdrop{background:var(--glass-scrim);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}
.g-modal[open]{animation:g-pop .22s ease-out}
@keyframes g-pop{from{opacity:0;transform:translateY(10px) scale(.98)}}
.g-modal-body{display:grid;gap:10px;padding:26px 26px 22px}
.g-modal h2{font-size:1.2rem;line-height:1.3}
.g-modal p{color:var(--glass-ink-soft);font-size:.95rem}
.g-modal-icon{display:grid;place-items:center;width:44px;height:44px;margin-bottom:4px;border-radius:14px;background:var(--glass-warn-bg);color:var(--glass-warn)}
.g-modal-icon svg{width:22px;height:22px}
.g-modal-actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:10px;margin:0;padding:16px 26px 22px;border-top:1px solid var(--glass-border)}
/* toasts */
.g-toasts{display:grid;gap:10px}
.g-toast{display:flex;align-items:flex-start;gap:12px;padding:14px;border-radius:16px}
.g-toast-icon{display:grid;place-items:center;flex:none;width:34px;height:34px;border-radius:11px;background:var(--glass-good-bg);color:var(--glass-good)}
.g-toast-icon svg{width:18px;height:18px}
.g-toast--bad .g-toast-icon{background:var(--glass-bad-bg);color:var(--glass-bad)}
.g-toast--info .g-toast-icon{background:var(--glass-accent-bg);color:var(--glass-on-accent)}
.g-toast-text{flex:1;min-width:0;font-size:.85rem;color:var(--glass-ink-soft)}
.g-toast-text b{display:block;font-size:.92rem;color:var(--glass-ink)}
.g-x{display:grid;place-items:center;flex:none;width:32px;height:32px;margin:-4px -4px 0 0;padding:0;border:0;border-radius:10px;background:transparent;color:var(--glass-ink);cursor:pointer}
.g-x:hover{background:var(--glass-bg-control)}
.g-x svg{width:16px;height:16px}
/* alert */
.g-alert{display:flex;align-items:flex-start;gap:12px;padding:16px;border:1px solid var(--glass-border);border-radius:16px;background:var(--glass-warn-bg);
  -webkit-backdrop-filter:blur(var(--glass-blur));backdrop-filter:blur(var(--glass-blur));color:var(--glass-ink);font-size:.9rem}
.g-alert svg{flex:none;width:22px;height:22px;color:var(--glass-warn)}
.g-alert b{display:block;color:var(--glass-warn)}
.g-alert a{color:inherit;font-weight:700;text-underline-offset:3px;border-radius:4px}
/* tooltip: shown on hover and keyboard focus, hidden again with Escape (data-dismissed) */
.g-tip-wrap{position:relative;display:inline-flex}
.g-tip{position:absolute;bottom:calc(100% + 10px);left:50%;z-index:5;width:max-content;max-width:220px;padding:7px 11px;border-radius:10px;
  background:color-mix(in srgb,var(--glass-ink) 90%,transparent);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  color:rgb(var(--glass-tint));font-size:.82rem;font-weight:600;line-height:1.35;
  opacity:0;visibility:hidden;transform:translate(-50%,4px);transition:opacity .15s,transform .15s,visibility .15s}
.g-tip::after{content:"";position:absolute;top:100%;left:50%;margin-left:-6px;border:6px solid transparent;border-top-color:color-mix(in srgb,var(--glass-ink) 90%,transparent)}
.g-tip::before{content:"";position:absolute;left:0;right:0;top:100%;height:12px}
.g-tip-wrap:hover .g-tip,.g-tip-wrap:focus-within .g-tip,.g-tip-wrap[data-open] .g-tip{opacity:1;visibility:visible;transform:translate(-50%,0)}
.g-tip-wrap[data-dismissed] .g-tip{opacity:0;visibility:hidden}
/* dropdown menu: <details> keeps it working without JavaScript */
.g-dd{position:relative;display:inline-block}
.g-dd>summary{list-style:none}
.g-dd>summary::-webkit-details-marker{display:none}
.g-dd>summary .g-chev{width:16px;height:16px;transition:transform .2s}
.g-dd[open]>summary .g-chev{transform:rotate(180deg)}
.g-menu{position:absolute;top:calc(100% + 8px);left:0;z-index:10;min-width:230px;margin:0;padding:6px;list-style:none;border-radius:16px}
.g-menu button{display:flex;align-items:center;gap:10px;width:100%;padding:9px 12px;border:0;border-radius:10px;background:transparent;
  color:var(--glass-ink);font:inherit;font-size:.92rem;text-align:left;cursor:pointer}
.g-menu button:hover{background:var(--glass-bg-control)}
.g-menu svg{flex:none;width:18px;height:18px}
.g-menu kbd{margin-left:auto;font:inherit;font-size:.78rem;color:var(--glass-ink-soft)}
.g-menu .g-sep{margin-top:6px;padding-top:6px;border-top:1px solid var(--glass-border)}
.g-menu .g-danger{color:var(--glass-bad);font-weight:600}
:is(.g-x,.g-alert a,.g-menu button):focus-visible{outline:3px solid var(--glass-focus);outline-offset:-1px}
.g-alert a:focus-visible{outline-offset:2px}
@media (prefers-reduced-motion:reduce){.g-modal[open]{animation:none}.g-tip,.g-dd>summary .g-chev{transition:none}}
JavaScript
// Dialog: open as a real modal (focus trap, Escape, ::backdrop). Toasts: dismiss. Tooltips and menus: Escape closes.
document.querySelectorAll('[data-dialog-open]').forEach(btn => btn.addEventListener('click', () => {
  const d = document.getElementById(btn.dataset.dialogOpen); if (!d) return;
  if (d.open) d.close(); d.showModal();
}));
document.querySelectorAll('[data-toast-dismiss]').forEach(btn => btn.addEventListener('click', () => btn.closest('[data-toast]')?.remove()));
document.addEventListener('keydown', e => {
  if (e.key !== 'Escape') return;
  document.querySelectorAll('[data-tip]').forEach(w => { w.dataset.dismissed = ''; });
  document.querySelectorAll('details[data-menu][open]').forEach(d => { d.open = false; d.querySelector('summary').focus(); });
});
document.querySelectorAll('[data-tip]').forEach(w => ['mouseleave', 'focusout'].forEach(ev => w.addEventListener(ev, () => delete w.dataset.dismissed)));
document.addEventListener('click', e => document.querySelectorAll('details[data-menu][open]').forEach(d => { if (!d.contains(e.target)) d.open = false; }));

Bootstrap 5 code

Requires: Bootstrap 5.3.8 CSS

HTML
<div class="g-scene" aria-hidden="true"><i></i><i></i><i></i><i></i></div>
<div class="wrap">
<div class="two">
<div><span class="lbl lbl--chip">Modal dialog</span>
  <button type="button" class="btn btn-glass btn-glass-strong" data-dialog-open="archive-dialog">Open the dialog</button>
  <dialog class="g-strong g-modal" id="archive-dialog" aria-labelledby="archive-title" aria-describedby="archive-desc" open>
    <form method="dialog" class="modal-content">
      <div class="modal-body">
        <span class="g-modal-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="5" rx="1.5"/><path d="M5 9v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V9M10 13h4"/></svg></span>
        <h2 class="modal-title" id="archive-title">Archive “Q3 brand refresh”?</h2>
        <p class="g-muted" id="archive-desc">The project and its 214 files move to the archive. Nobody can edit them until you restore it, and the share links stop working.</p>
      </div>
      <div class="modal-footer">
        <button class="btn btn-glass" value="cancel">Cancel</button>
        <button class="btn btn-glass btn-glass-accent" value="archive">Archive project</button>
      </div>
    </form>
  </dialog>
</div>
<div><span class="lbl lbl--chip">Toasts and alert</span>
  <div class="g-toasts" role="status">
    <div class="toast show g-toast" data-toast><span class="g-toast-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.5l4.5 4.5L19 7.5"/></svg></span>
      <div class="toast-body"><b>Invoice sent</b>INV-2048 is on its way to Halden & Co.</div>
      <button type="button" class="btn-close" aria-label="Dismiss: Invoice sent" data-toast-dismiss></button></div>
    <div class="toast show g-toast g-toast--bad" data-toast><span class="g-toast-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"><path d="M12 7v6M12 17v.5"/><circle cx="12" cy="12" r="9"/></svg></span>
      <div class="toast-body"><b>Upload failed</b>brief-final.pdf is over the 25 MB limit.</div>
      <button type="button" class="btn-close" aria-label="Dismiss: Upload failed" data-toast-dismiss></button></div>
    <div class="toast show g-toast g-toast--info" data-toast><span class="g-toast-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 14.5a2 2 0 0 1-2 2H8l-4 3.5V6.5a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2z"/></svg></span>
      <div class="toast-body"><b>New comment from Theo</b>“Can we try the headline in sentence case?”</div>
      <button type="button" class="btn-close" aria-label="Dismiss: New comment from Theo" data-toast-dismiss></button></div>
  </div>
  <div class="alert g-alert d-flex"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 3.5 2.5 20h19z"/><path d="M12 10v4.5M12 17.2v.3"/></svg>
    <div><b>Your trial ends in 3 days</b>Add a payment method to keep your 4 projects and 12 collaborators. <a class="alert-link" href="#billing">Add payment method</a></div></div>
</div>
</div>
<section class="card g-glass" aria-labelledby="c3"><div class="card-body"><span class="lbl" id="c3">Tooltips and dropdown menu</span>
  <div class="tools">
    <div class="g-row">
      <span class="g-tip-wrap" data-tip data-open><button type="button" class="btn btn-glass btn-icon rounded-circle" aria-label="Copy link" aria-describedby="tip-copy"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1"/></svg></button><span class="tooltip bs-tooltip-top" role="tooltip" id="tip-copy"><span class="tooltip-arrow"></span><span class="tooltip-inner">Copy share link</span></span></span>
      <span class="g-tip-wrap" data-tip><button type="button" class="btn btn-glass btn-icon rounded-circle" aria-label="Download" aria-describedby="tip-dl"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 4v11M7 10l5 5 5-5M5 20h14"/></svg></button><span class="tooltip bs-tooltip-top" role="tooltip" id="tip-dl"><span class="tooltip-arrow"></span><span class="tooltip-inner">Download as ZIP, 48 MB</span></span></span>
      <span class="g-tip-wrap" data-tip><button type="button" class="btn btn-glass btn-icon rounded-circle" aria-label="Invite people" aria-describedby="tip-inv"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="9" cy="8" r="3.5"/><path d="M2.5 20a6.5 6.5 0 0 1 13 0M19 8v6M16 11h6"/></svg></button><span class="tooltip bs-tooltip-top" role="tooltip" id="tip-inv"><span class="tooltip-arrow"></span><span class="tooltip-inner">Invite people to this project</span></span></span>
    </div>
    <details class="dropdown g-dd" data-menu open>
      <summary class="btn btn-glass">Project actions<svg class="g-chev" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg></summary>
      <ul class="dropdown-menu show g-menu">
        <li><button type="button" class="dropdown-item"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 20h4L19 9l-4-4L4 16z"/></svg>Rename<kbd>R</kbd></button></li>
        <li><button type="button" class="dropdown-item"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2"/><path d="M16 8V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h2"/></svg>Duplicate<kbd>D</kbd></button></li>
        <li><button type="button" class="dropdown-item"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 12h12M12 6l6 6-6 6M20 4v16"/></svg>Move to team…</button></li>
        <li class="g-sep"><button type="button" class="dropdown-item g-danger"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M10 11v6M14 11v6M6 7l1 12a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2l1-12M9 7V4h6v3"/></svg>Delete project</button></li>
      </ul>
    </details>
  </div>
</div></section>
</div>
CSS
/* ===== uiCookies Glassmorphism kit: design tokens (identical in every set) =====
   Retheme the whole kit here. Light scene on :root, dark scene on [data-scene="dark"]
   (or any [data-scene] holding a checked [data-scene-switch]). Selectors use :where()
   so the fallbacks below always win. */
:where(:root,[data-scene="light"]){
  color-scheme:light;
  /* background scene: the colour the glass frosts */
  --scene-base:linear-gradient(155deg,#eceffe 0%,#fbeef7 52%,#e6f6fb 100%);
  --scene-1:linear-gradient(140deg,#7c3aed,#c026d3);
  --scene-2:linear-gradient(140deg,#fb7185,#f97316);
  --scene-3:linear-gradient(140deg,#22d3ee,#3b82f6);
  --scene-4:linear-gradient(140deg,#fde047,#fb923c);
  /* glass */
  --glass-tint:255 255 255;
  --glass-border:rgb(255 255 255 / .8);
  --glass-edge:rgb(36 32 88 / .9);
  --glass-highlight:inset 0 1px 0 rgb(255 255 255 / .85);
  --glass-shadow:0 18px 40px -18px rgb(37 30 102 / .45);
  --glass-ink:#16133a;
  --glass-ink-soft:#3b3862;
  --glass-accent:#4338ca;
  --glass-accent-bg:rgb(67 56 202 / .92);
  --glass-on-accent:#fff;
  --glass-check-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --glass-focus:#1e1b4b;
  --glass-good:#14532d;--glass-good-bg:rgb(220 252 231 / .9);
  --glass-bad:#991b1b;--glass-bad-bg:rgb(254 226 226 / .9);
  --glass-warn:#7c2d12;--glass-warn-bg:rgb(254 243 199 / .9);
  --glass-scrim:rgb(22 19 58 / .3);
}
:where([data-scene="dark"]),:where([data-scene]:has([data-scene-switch]:checked)){
  color-scheme:dark;
  --scene-base:linear-gradient(155deg,#0a0c22 0%,#170c2c 52%,#06171f 100%);
  --scene-1:linear-gradient(140deg,#6d28d9,#a21caf);
  --scene-2:linear-gradient(140deg,#e11d48,#ea580c);
  --scene-3:linear-gradient(140deg,#0891b2,#2563eb);
  --scene-4:linear-gradient(140deg,#ca8a04,#c2410c);
  --glass-tint:16 18 44;
  --glass-border:rgb(255 255 255 / .2);
  --glass-edge:rgb(214 220 255 / .72);
  --glass-highlight:inset 0 1px 0 rgb(255 255 255 / .16);
  --glass-shadow:0 18px 40px -18px rgb(0 0 0 / .75);
  --glass-ink:#f5f6ff;
  --glass-ink-soft:#d0d3ee;
  --glass-accent:#a5b4fc;
  --glass-accent-bg:rgb(165 180 252 / .96);
  --glass-on-accent:#14123a;
  --glass-check-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%2314123a' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --glass-focus:#c7d2fe;
  --glass-good:#bbf7d0;--glass-good-bg:rgb(20 83 45 / .7);
  --glass-bad:#fecaca;--glass-bad-bg:rgb(127 29 29 / .7);
  --glass-warn:#fde68a;--glass-warn-bg:rgb(120 53 15 / .7);
  --glass-scrim:rgb(0 0 0 / .5);
}
:where(:root){
  --glass-alpha:.6;          /* panels and cards */
  --glass-alpha-strong:.82;  /* menus, dialogs, toasts: they cover unknown content */
  --glass-alpha-control:.5;  /* buttons and fields sitting on a panel */
  --glass-blur:18px;
  --glass-saturate:150%;
  --glass-radius:20px;
}
/* derived: recomputed inside every scene so a dark scene gets dark glass */
:where(:root,[data-scene]){
  --glass-bg:rgb(var(--glass-tint) / var(--glass-alpha));
  --glass-bg-strong:rgb(var(--glass-tint) / var(--glass-alpha-strong));
  --glass-bg-control:rgb(var(--glass-tint) / var(--glass-alpha-control));
}
/* no backdrop-filter: frosting can't happen, so the glass turns nearly solid */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  :where(:root){--glass-alpha:.94;--glass-alpha-strong:.97;--glass-alpha-control:.9}
}
@media (prefers-reduced-transparency:reduce){
  :where(:root){--glass-alpha:.93;--glass-alpha-strong:.97;--glass-alpha-control:.9;--glass-blur:8px}
}
@media (prefers-contrast:more){
  :where(:root){--glass-alpha:.96;--glass-alpha-strong:.98;--glass-alpha-control:.96}
  :where(:root,[data-scene]){--glass-border:var(--glass-ink);--glass-edge:var(--glass-ink)}
}
/* ===== end of tokens ===== */
/* scene: fixed page background of four gradient orbs (decorative, aria-hidden) */
:where([data-scene]){color:var(--glass-ink)}
.g-scene{position:fixed;inset:0;z-index:-1;overflow:hidden;pointer-events:none;background:var(--scene-base)}
.g-scene i{position:absolute;aspect-ratio:1;border-radius:50%;animation:g-drift 32s ease-in-out infinite alternate}
.g-scene i:nth-child(1){width:clamp(240px,40vw,520px);left:-7%;top:-9%;background:var(--scene-1)}
.g-scene i:nth-child(2){width:clamp(170px,26vw,360px);right:-5%;top:18%;background:var(--scene-2);animation-delay:-9s}
.g-scene i:nth-child(3){width:clamp(220px,34vw,460px);left:28%;bottom:-16%;background:var(--scene-3);animation-delay:-17s}
.g-scene i:nth-child(4){width:clamp(90px,13vw,180px);left:54%;top:7%;background:var(--scene-4);animation-delay:-4s}
@keyframes g-drift{to{transform:translate3d(3vw,4vh,0) scale(1.06)}}
/* glass surface */
.g-glass{background:var(--glass-bg);-webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));
  backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));border:1px solid var(--glass-border);
  border-radius:var(--glass-radius);box-shadow:var(--glass-highlight),var(--glass-shadow);color:var(--glass-ink)}
.g-glass--strong{background:var(--glass-bg-strong)}
.g-panel{padding:24px}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.g-muted{color:var(--glass-ink-soft)}
@media (prefers-reduced-motion:reduce){.g-scene i{animation:none}}
/* Bootstrap: the glass tokens feed Bootstrap's own component variables */
.card.g-glass{--bs-card-bg:var(--glass-bg);--bs-card-border-color:var(--glass-border);--bs-card-border-radius:var(--glass-radius);
  --bs-card-inner-border-radius:calc(var(--glass-radius) - 1px);--bs-card-color:var(--glass-ink);--bs-card-spacer-x:24px;--bs-card-spacer-y:24px;
  --bs-card-title-color:var(--glass-ink);--bs-card-subtitle-color:var(--glass-ink-soft)}
:where([data-scene]){--bs-body-color:var(--glass-ink);--bs-secondary-color:var(--glass-ink-soft);--bs-border-color:var(--glass-edge);;--bs-emphasis-color:var(--glass-ink)}
.g-row{display:flex;flex-wrap:wrap;align-items:center;gap:12px}
.btn-glass{--bs-btn-padding-x:20px;--bs-btn-padding-y:0;--bs-btn-font-size:.95rem;--bs-btn-font-weight:600;--bs-btn-line-height:1;--bs-btn-border-radius:999px;
  --bs-btn-color:var(--glass-ink);--bs-btn-bg:var(--glass-bg-control);--bs-btn-border-color:var(--glass-edge);
  --bs-btn-hover-color:var(--glass-ink);--bs-btn-hover-bg:var(--glass-bg-strong);--bs-btn-hover-border-color:var(--glass-edge);
  --bs-btn-active-color:var(--glass-ink);--bs-btn-active-bg:var(--glass-bg-strong);--bs-btn-active-border-color:var(--glass-edge);
  --bs-btn-disabled-color:var(--glass-ink);--bs-btn-disabled-bg:var(--glass-bg-control);--bs-btn-disabled-border-color:var(--glass-edge);--bs-btn-disabled-opacity:.5;
  --bs-btn-focus-box-shadow:var(--glass-highlight);
  display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:44px;
  -webkit-backdrop-filter:blur(var(--glass-blur));backdrop-filter:blur(var(--glass-blur));box-shadow:var(--glass-highlight);
  transition:background-color .2s,transform .2s}
.btn-glass:active{transform:translateY(1px)}
.btn-glass:focus-visible,.btn-check:focus-visible+.btn-glass{outline:3px solid var(--glass-focus);outline-offset:3px}
.btn-glass svg{width:18px;height:18px;flex:none}
.btn-glass-accent{--bs-btn-color:var(--glass-on-accent);--bs-btn-bg:var(--glass-accent-bg);--bs-btn-border-color:transparent;
  --bs-btn-hover-color:var(--glass-on-accent);--bs-btn-hover-bg:var(--glass-accent-bg);--bs-btn-hover-border-color:transparent;
  --bs-btn-active-color:var(--glass-on-accent);--bs-btn-active-bg:var(--glass-accent-bg);--bs-btn-active-border-color:transparent}
.btn-glass-accent:hover{filter:brightness(1.08)}
.btn-glass-quiet{--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-border-color:transparent;--bs-btn-hover-bg:var(--glass-bg-control);
  -webkit-backdrop-filter:none;backdrop-filter:none;box-shadow:none;text-decoration:underline;text-underline-offset:4px}
.btn-glass-strong{--bs-btn-bg:var(--glass-bg-strong)} /* for buttons placed straight on the scene */
.btn-glass.btn-sm{--bs-btn-padding-x:14px;--bs-btn-font-size:.85rem;min-height:36px}
.btn-glass.btn-lg{--bs-btn-padding-x:28px;--bs-btn-font-size:1.05rem;min-height:54px}
.btn-glass.btn-icon{width:44px;height:44px;min-height:0;padding:0}
.btn-glass.btn-icon.btn-sm{width:36px;height:36px}
.btn-glass.btn-icon.btn-sm svg{width:16px;height:16px}
.btn-glass.btn-icon.btn-lg{width:56px;height:56px}
.btn-glass.btn-icon.btn-lg svg{width:22px;height:22px}
@media (prefers-reduced-motion:reduce){.btn-glass{transition:none}.btn-glass:active{transform:none}}
/* overlays sit on unknown content, so they use the more opaque --glass-bg-strong */
.g-strong{background:var(--glass-bg-strong);-webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));
  backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-saturate));border:1px solid var(--glass-border);box-shadow:var(--glass-highlight),var(--glass-shadow);color:var(--glass-ink)}
/* dialog: native <dialog>, opened with showModal() so focus is trapped and Escape closes it */
.g-modal{width:min(440px,calc(100vw - 32px));max-width:none;padding:0;border-radius:var(--glass-radius)}
.g-modal::backdrop{background:var(--glass-scrim);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}
.g-modal[open]{animation:g-pop .22s ease-out}
@keyframes g-pop{from{opacity:0;transform:translateY(10px) scale(.98)}}
.g-modal-icon{display:grid;place-items:center;width:44px;height:44px;margin-bottom:4px;border-radius:14px;background:var(--glass-warn-bg);color:var(--glass-warn)}
.g-modal-icon svg{width:22px;height:22px}
/* toasts */
.g-toasts{display:grid;gap:10px}
.g-toast{display:flex;align-items:flex-start;gap:12px;padding:14px;border-radius:16px}
.g-toast-icon{display:grid;place-items:center;flex:none;width:34px;height:34px;border-radius:11px;background:var(--glass-good-bg);color:var(--glass-good)}
.g-toast-icon svg{width:18px;height:18px}
.g-toast--bad .g-toast-icon{background:var(--glass-bad-bg);color:var(--glass-bad)}
.g-toast--info .g-toast-icon{background:var(--glass-accent-bg);color:var(--glass-on-accent)}
/* alert */
.g-alert{align-items:flex-start;gap:12px;-webkit-backdrop-filter:blur(var(--glass-blur));backdrop-filter:blur(var(--glass-blur));font-size:.9rem}
.g-alert svg{flex:none;width:22px;height:22px;color:var(--glass-warn)}
.g-alert b{display:block;color:var(--glass-warn)}
/* tooltip: shown on hover and keyboard focus, hidden again with Escape (data-dismissed) */
.g-tip-wrap{position:relative;display:inline-flex}
/* dropdown menu: <details> keeps it working without JavaScript */
.g-dd{position:relative;display:inline-block}
.g-dd>summary{list-style:none}
.g-dd>summary::-webkit-details-marker{display:none}
.g-dd>summary .g-chev{width:16px;height:16px;transition:transform .2s}
.g-dd[open]>summary .g-chev{transform:rotate(180deg)}
.g-menu svg{flex:none;width:18px;height:18px}
.g-menu kbd{margin-left:auto;font:inherit;font-size:.78rem;color:var(--glass-ink-soft)}
.g-menu .g-sep{margin-top:6px;padding-top:6px;border-top:1px solid var(--glass-border)}

/* Bootstrap mapping: .modal-content/.modal-body/.modal-footer, .toast, .alert, .tooltip, .dropdown-menu */
.g-modal{--bs-modal-bg:transparent;--bs-modal-color:var(--glass-ink);--bs-modal-border-width:0;--bs-modal-border-radius:var(--glass-radius);
  --bs-modal-inner-border-radius:var(--glass-radius);--bs-modal-padding:26px;--bs-modal-footer-gap:10px;--bs-modal-footer-bg:transparent;
  --bs-modal-footer-border-color:var(--glass-border);--bs-modal-footer-border-width:1px}
.g-modal .modal-body{display:grid;gap:10px;padding:26px 26px 22px}
.g-modal .modal-title{margin:0;font-size:1.2rem;font-weight:700;line-height:1.3}
.g-modal .modal-body p{margin:0}
.g-modal .modal-footer{padding:11px 21px 17px}
.g-toast.toast{--bs-toast-max-width:none;--bs-toast-bg:var(--glass-bg-strong);--bs-toast-border-color:var(--glass-border);--bs-toast-border-radius:16px;
  --bs-toast-color:var(--glass-ink);--bs-toast-font-size:.85rem;--bs-toast-box-shadow:var(--glass-highlight),var(--glass-shadow);width:auto}
.g-toast .toast-body{flex:1;min-width:0;padding:0;color:var(--glass-ink-soft)}
.g-toast .toast-body b{display:block;font-size:.92rem;color:var(--glass-ink)}
.g-toast .btn-close{--bs-btn-close-opacity:1;--bs-btn-close-hover-opacity:1;--bs-btn-close-focus-shadow:none;
  --bs-btn-close-bg:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 6l12 12M18 6 6 18' fill='none' stroke='%2316133a' stroke-width='2.4' stroke-linecap='round'/%3E%3C/svg%3E");
  flex:none;width:32px;height:32px;margin:-4px -4px 0 0;padding:0;border-radius:10px;background-size:16px}
.g-toast .btn-close:hover{background-color:var(--glass-bg-control)}
.g-toast .btn-close:focus-visible{outline:3px solid var(--glass-focus);outline-offset:-1px}
.g-alert.alert{--bs-alert-bg:var(--glass-warn-bg);--bs-alert-color:var(--glass-ink);--bs-alert-border-color:var(--glass-border);--bs-alert-link-color:var(--glass-ink);
  --bs-alert-padding-x:16px;--bs-alert-padding-y:16px;--bs-alert-margin-bottom:0;--bs-alert-border-radius:16px}
.g-alert .alert-link{text-decoration:underline;text-underline-offset:3px}
.g-tip-wrap .tooltip{--bs-tooltip-bg:color-mix(in srgb,var(--glass-ink) 90%,transparent);--bs-tooltip-color:rgb(var(--glass-tint));--bs-tooltip-opacity:1;
  --bs-tooltip-font-size:.82rem;--bs-tooltip-border-radius:10px;--bs-tooltip-padding-x:11px;--bs-tooltip-padding-y:7px;--bs-tooltip-max-width:220px;--bs-tooltip-margin:0;
  position:absolute;bottom:calc(100% + 10px);left:50%;width:max-content;font-weight:600;line-height:1.35;visibility:hidden;transform:translate(-50%,4px);transition:opacity .15s,transform .15s,visibility .15s}
.g-tip-wrap .tooltip-arrow{position:absolute;left:50%;margin-left:-.4rem}
.g-tip-wrap .tooltip-inner{display:block;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}
.g-tip-wrap:hover .tooltip,.g-tip-wrap:focus-within .tooltip,.g-tip-wrap[data-open] .tooltip{opacity:1;visibility:visible;transform:translate(-50%,0)}
.g-tip-wrap[data-dismissed] .tooltip{opacity:0;visibility:hidden}
.g-menu.dropdown-menu{--bs-dropdown-bg:var(--glass-bg-strong);--bs-dropdown-border-color:var(--glass-border);--bs-dropdown-border-radius:16px;
  --bs-dropdown-padding-x:6px;--bs-dropdown-padding-y:6px;--bs-dropdown-link-color:var(--glass-ink);--bs-dropdown-link-hover-color:var(--glass-ink);
  --bs-dropdown-link-hover-bg:var(--glass-bg-control);--bs-dropdown-link-active-color:var(--glass-ink);--bs-dropdown-link-active-bg:var(--glass-bg-control);
  --bs-dropdown-item-padding-x:12px;--bs-dropdown-item-padding-y:9px;--bs-dropdown-item-border-radius:10px;--bs-dropdown-font-size:.92rem;--bs-dropdown-min-width:230px;
  top:calc(100% + 8px);left:0}
.g-menu .dropdown-item{display:flex;align-items:center;gap:10px}
.g-menu .dropdown-item.g-danger{color:var(--glass-bad)}
.g-menu .dropdown-item:focus-visible{outline:3px solid var(--glass-focus);outline-offset:-1px}
@media (prefers-reduced-motion:reduce){.g-modal[open]{animation:none}.g-tip-wrap .tooltip,.g-dd>summary .g-chev{transition:none}}
.g-menu kbd{padding:0;background:none;border-radius:0}
JavaScript
// Dialog: open as a real modal (focus trap, Escape, ::backdrop). Toasts: dismiss. Tooltips and menus: Escape closes.
document.querySelectorAll('[data-dialog-open]').forEach(btn => btn.addEventListener('click', () => {
  const d = document.getElementById(btn.dataset.dialogOpen); if (!d) return;
  if (d.open) d.close(); d.showModal();
}));
document.querySelectorAll('[data-toast-dismiss]').forEach(btn => btn.addEventListener('click', () => btn.closest('[data-toast]')?.remove()));
document.addEventListener('keydown', e => {
  if (e.key !== 'Escape') return;
  document.querySelectorAll('[data-tip]').forEach(w => { w.dataset.dismissed = ''; });
  document.querySelectorAll('details[data-menu][open]').forEach(d => { d.open = false; d.querySelector('summary').focus(); });
});
document.querySelectorAll('[data-tip]').forEach(w => ['mouseleave', 'focusout'].forEach(ev => w.addEventListener(ev, () => delete w.dataset.dismissed)));
document.addEventListener('click', e => document.querySelectorAll('details[data-menu][open]').forEach(d => { if (!d.contains(e.target)) d.open = false; }));

Tailwind 4 code

Requires: Tailwind CSS 4

HTML
<div aria-hidden="true" class="pointer-events-none fixed inset-0 -z-10 overflow-hidden bg-(image:--scene-base)">
  <i class="absolute -top-[9%] -left-[7%] aspect-square w-[clamp(240px,40vw,520px)] rounded-full bg-(image:--scene-1) motion-safe:animate-drift"></i>
  <i class="absolute top-[18%] -right-[5%] aspect-square w-[clamp(170px,26vw,360px)] rounded-full bg-(image:--scene-2) [animation-delay:-9s] motion-safe:animate-drift"></i>
  <i class="absolute -bottom-[16%] left-[28%] aspect-square w-[clamp(220px,34vw,460px)] rounded-full bg-(image:--scene-3) [animation-delay:-17s] motion-safe:animate-drift"></i>
  <i class="absolute top-[7%] left-[54%] aspect-square w-[clamp(90px,13vw,180px)] rounded-full bg-(image:--scene-4) [animation-delay:-4s] motion-safe:animate-drift"></i>
</div>
<div class="mx-auto flex max-w-[980px] flex-col gap-[26px]">
<div class="grid grid-cols-[repeat(auto-fit,minmax(min(100%,400px),1fr))] items-start gap-[26px]">
<div class="flex flex-col items-start gap-3.5"><span class="self-start inline-block rounded-full border border-glass-border bg-glass-strong px-[11px] py-[5px] text-[.72rem] font-bold tracking-[.12em] text-ink-soft uppercase backdrop-blur-glass">Modal dialog</span>
  <button type="button" class="inline-flex cursor-pointer items-center justify-center gap-2 rounded-full border border-glass-edge bg-glass-strong leading-none font-semibold text-ink no-underline inset-shadow-glass backdrop-blur-glass transition-[background-color,translate] duration-200 hover:bg-glass-strong active:translate-y-px disabled:cursor-not-allowed disabled:opacity-50 focus-visible:outline-3 focus-visible:outline-offset-3 focus-visible:outline-focus motion-reduce:transition-none motion-reduce:active:translate-y-0 min-h-11 px-5 text-[.95rem]" data-dialog-open="archive-dialog">Open the dialog</button>
  <dialog class="border border-glass-border bg-glass-strong text-ink shadow-glass inset-shadow-glass backdrop-blur-glass backdrop-saturate-150 w-[min(440px,calc(100vw-32px))] max-w-none self-stretch rounded-glass p-0 backdrop:bg-scrim backdrop:backdrop-blur-[6px] open:motion-safe:animate-pop" id="archive-dialog" aria-labelledby="archive-title" aria-describedby="archive-desc" open>
    <form method="dialog">
      <div class="grid gap-2.5 px-[26px] pt-[26px] pb-[22px]">
        <span class="mb-1 grid size-11 place-items-center rounded-[14px] bg-warn-glass text-warn" aria-hidden="true"><svg class="size-[22px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="5" rx="1.5"/><path d="M5 9v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V9M10 13h4"/></svg></span>
        <h2 class="text-[1.2rem] leading-[1.3] font-bold" id="archive-title">Archive “Q3 brand refresh”?</h2>
        <p class="text-[.95rem] text-ink-soft" id="archive-desc">The project and its 214 files move to the archive. Nobody can edit them until you restore it, and the share links stop working.</p>
      </div>
      <div class="flex flex-wrap justify-end gap-2.5 border-t border-glass-border px-[26px] pt-4 pb-[22px]">
        <button class="inline-flex cursor-pointer items-center justify-center gap-2 rounded-full border border-glass-edge bg-glass-control leading-none font-semibold text-ink no-underline inset-shadow-glass backdrop-blur-glass transition-[background-color,translate] duration-200 hover:bg-glass-strong active:translate-y-px disabled:cursor-not-allowed disabled:opacity-50 focus-visible:outline-3 focus-visible:outline-offset-3 focus-visible:outline-focus motion-reduce:transition-none motion-reduce:active:translate-y-0 min-h-11 px-5 text-[.95rem]" value="cancel">Cancel</button>
        <button class="inline-flex cursor-pointer items-center justify-center gap-2 rounded-full border border-transparent bg-accent-glass leading-none font-semibold text-on-accent no-underline inset-shadow-glass backdrop-blur-glass transition-[filter,translate] duration-200 hover:brightness-[1.08] active:translate-y-px focus-visible:outline-3 focus-visible:outline-offset-3 focus-visible:outline-focus motion-reduce:transition-none motion-reduce:active:translate-y-0 min-h-11 px-5 text-[.95rem]" value="archive">Archive project</button>
      </div>
    </form>
  </dialog>
</div>
<div class="flex flex-col items-stretch gap-3.5"><span class="self-start inline-block rounded-full border border-glass-border bg-glass-strong px-[11px] py-[5px] text-[.72rem] font-bold tracking-[.12em] text-ink-soft uppercase backdrop-blur-glass">Toasts and alert</span>
  <div class="grid gap-2.5" role="status">
    <div class="border border-glass-border bg-glass-strong text-ink shadow-glass inset-shadow-glass backdrop-blur-glass backdrop-saturate-150 flex items-start gap-3 rounded-2xl p-3.5" data-toast><span class="grid size-[34px] flex-none place-items-center rounded-[11px] bg-good-glass text-good" aria-hidden="true"><svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.5l4.5 4.5L19 7.5"/></svg></span>
      <p class="min-w-0 flex-1 text-[.85rem] text-ink-soft"><b class="block text-[.92rem] text-ink">Invoice sent</b>INV-2048 is on its way to Halden & Co.</p>
      <button type="button" class="-mt-1 -mr-1 grid size-8 flex-none cursor-pointer place-items-center rounded-[10px] text-ink hover:bg-glass-control focus-visible:outline-3 focus-visible:-outline-offset-1 focus-visible:outline-focus" aria-label="Dismiss: Invoice sent" data-toast-dismiss><svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" aria-hidden="true"><path d="M6 6l12 12M18 6 6 18"/></svg></button></div>
    <div class="border border-glass-border bg-glass-strong text-ink shadow-glass inset-shadow-glass backdrop-blur-glass backdrop-saturate-150 flex items-start gap-3 rounded-2xl p-3.5" data-toast><span class="grid size-[34px] flex-none place-items-center rounded-[11px] bg-bad-glass text-bad" aria-hidden="true"><svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"><path d="M12 7v6M12 17v.5"/><circle cx="12" cy="12" r="9"/></svg></span>
      <p class="min-w-0 flex-1 text-[.85rem] text-ink-soft"><b class="block text-[.92rem] text-ink">Upload failed</b>brief-final.pdf is over the 25 MB limit.</p>
      <button type="button" class="-mt-1 -mr-1 grid size-8 flex-none cursor-pointer place-items-center rounded-[10px] text-ink hover:bg-glass-control focus-visible:outline-3 focus-visible:-outline-offset-1 focus-visible:outline-focus" aria-label="Dismiss: Upload failed" data-toast-dismiss><svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" aria-hidden="true"><path d="M6 6l12 12M18 6 6 18"/></svg></button></div>
    <div class="border border-glass-border bg-glass-strong text-ink shadow-glass inset-shadow-glass backdrop-blur-glass backdrop-saturate-150 flex items-start gap-3 rounded-2xl p-3.5" data-toast><span class="grid size-[34px] flex-none place-items-center rounded-[11px] bg-accent-glass text-on-accent" aria-hidden="true"><svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 14.5a2 2 0 0 1-2 2H8l-4 3.5V6.5a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2z"/></svg></span>
      <p class="min-w-0 flex-1 text-[.85rem] text-ink-soft"><b class="block text-[.92rem] text-ink">New comment from Theo</b>“Can we try the headline in sentence case?”</p>
      <button type="button" class="-mt-1 -mr-1 grid size-8 flex-none cursor-pointer place-items-center rounded-[10px] text-ink hover:bg-glass-control focus-visible:outline-3 focus-visible:-outline-offset-1 focus-visible:outline-focus" aria-label="Dismiss: New comment from Theo" data-toast-dismiss><svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" aria-hidden="true"><path d="M6 6l12 12M18 6 6 18"/></svg></button></div>
  </div>
  <div class="flex items-start gap-3 rounded-2xl border border-glass-border bg-warn-glass p-4 text-[.9rem] text-ink backdrop-blur-glass"><svg class="size-[22px] flex-none text-warn" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 3.5 2.5 20h19z"/><path d="M12 10v4.5M12 17.2v.3"/></svg>
    <div><b class="block text-warn">Your trial ends in 3 days</b>Add a payment method to keep your 4 projects and 12 collaborators. <a class="rounded-[4px] font-bold underline underline-offset-3 focus-visible:outline-3 focus-visible:outline-offset-3 focus-visible:outline-focus" href="#billing">Add payment method</a></div></div>
</div>
</div>
<section class="border border-glass-border bg-glass text-ink shadow-glass inset-shadow-glass backdrop-blur-glass backdrop-saturate-150 rounded-glass p-6" aria-labelledby="c3"><span class="mb-4 block text-[.72rem] font-bold tracking-[.12em] text-ink-soft uppercase" id="c3">Tooltips and dropdown menu</span>
  <div class="flex flex-wrap items-center justify-between gap-5 pt-[34px]">
    <div class="flex flex-wrap items-center gap-3">
      <span class="group relative inline-flex" data-tip data-open><button type="button" class="inline-grid cursor-pointer place-items-center rounded-full border border-glass-edge bg-glass-control p-0 text-ink inset-shadow-glass backdrop-blur-glass transition-[background-color,scale] duration-200 hover:bg-glass-strong active:scale-96 focus-visible:outline-3 focus-visible:outline-offset-3 focus-visible:outline-focus motion-reduce:transition-none motion-reduce:active:scale-100 size-11" aria-label="Copy link" aria-describedby="tip-copy"><svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1"/></svg></button><span class="invisible absolute bottom-[calc(100%+10px)] left-1/2 z-5 w-max max-w-[220px] -translate-x-1/2 translate-y-1 rounded-[10px] bg-[color-mix(in_srgb,var(--glass-ink)_90%,transparent)] px-[11px] py-[7px] text-[.82rem] leading-[1.35] font-semibold text-[rgb(var(--glass-tint))] opacity-0 backdrop-blur-[8px] transition-[opacity,translate,visibility] duration-150 group-[:hover:not([data-dismissed])]:visible group-[:hover:not([data-dismissed])]:translate-y-0 group-[:hover:not([data-dismissed])]:opacity-100 group-[:focus-within:not([data-dismissed])]:visible group-[:focus-within:not([data-dismissed])]:translate-y-0 group-[:focus-within:not([data-dismissed])]:opacity-100 group-[[data-open]:not([data-dismissed])]:visible group-[[data-open]:not([data-dismissed])]:translate-y-0 group-[[data-open]:not([data-dismissed])]:opacity-100 before:absolute before:inset-x-0 before:top-full before:h-3 before:content-[''] after:absolute after:top-full after:left-1/2 after:-ml-1.5 after:border-6 after:border-transparent after:border-t-[color-mix(in_srgb,var(--glass-ink)_90%,transparent)] after:content-[''] motion-reduce:transition-none" role="tooltip" id="tip-copy">Copy share link</span></span>
      <span class="group relative inline-flex" data-tip><button type="button" class="inline-grid cursor-pointer place-items-center rounded-full border border-glass-edge bg-glass-control p-0 text-ink inset-shadow-glass backdrop-blur-glass transition-[background-color,scale] duration-200 hover:bg-glass-strong active:scale-96 focus-visible:outline-3 focus-visible:outline-offset-3 focus-visible:outline-focus motion-reduce:transition-none motion-reduce:active:scale-100 size-11" aria-label="Download" aria-describedby="tip-dl"><svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 4v11M7 10l5 5 5-5M5 20h14"/></svg></button><span class="invisible absolute bottom-[calc(100%+10px)] left-1/2 z-5 w-max max-w-[220px] -translate-x-1/2 translate-y-1 rounded-[10px] bg-[color-mix(in_srgb,var(--glass-ink)_90%,transparent)] px-[11px] py-[7px] text-[.82rem] leading-[1.35] font-semibold text-[rgb(var(--glass-tint))] opacity-0 backdrop-blur-[8px] transition-[opacity,translate,visibility] duration-150 group-[:hover:not([data-dismissed])]:visible group-[:hover:not([data-dismissed])]:translate-y-0 group-[:hover:not([data-dismissed])]:opacity-100 group-[:focus-within:not([data-dismissed])]:visible group-[:focus-within:not([data-dismissed])]:translate-y-0 group-[:focus-within:not([data-dismissed])]:opacity-100 group-[[data-open]:not([data-dismissed])]:visible group-[[data-open]:not([data-dismissed])]:translate-y-0 group-[[data-open]:not([data-dismissed])]:opacity-100 before:absolute before:inset-x-0 before:top-full before:h-3 before:content-[''] after:absolute after:top-full after:left-1/2 after:-ml-1.5 after:border-6 after:border-transparent after:border-t-[color-mix(in_srgb,var(--glass-ink)_90%,transparent)] after:content-[''] motion-reduce:transition-none" role="tooltip" id="tip-dl">Download as ZIP, 48 MB</span></span>
      <span class="group relative inline-flex" data-tip><button type="button" class="inline-grid cursor-pointer place-items-center rounded-full border border-glass-edge bg-glass-control p-0 text-ink inset-shadow-glass backdrop-blur-glass transition-[background-color,scale] duration-200 hover:bg-glass-strong active:scale-96 focus-visible:outline-3 focus-visible:outline-offset-3 focus-visible:outline-focus motion-reduce:transition-none motion-reduce:active:scale-100 size-11" aria-label="Invite people" aria-describedby="tip-inv"><svg class="size-[18px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="9" cy="8" r="3.5"/><path d="M2.5 20a6.5 6.5 0 0 1 13 0M19 8v6M16 11h6"/></svg></button><span class="invisible absolute bottom-[calc(100%+10px)] left-1/2 z-5 w-max max-w-[220px] -translate-x-1/2 translate-y-1 rounded-[10px] bg-[color-mix(in_srgb,var(--glass-ink)_90%,transparent)] px-[11px] py-[7px] text-[.82rem] leading-[1.35] font-semibold text-[rgb(var(--glass-tint))] opacity-0 backdrop-blur-[8px] transition-[opacity,translate,visibility] duration-150 group-[:hover:not([data-dismissed])]:visible group-[:hover:not([data-dismissed])]:translate-y-0 group-[:hover:not([data-dismissed])]:opacity-100 group-[:focus-within:not([data-dismissed])]:visible group-[:focus-within:not([data-dismissed])]:translate-y-0 group-[:focus-within:not([data-dismissed])]:opacity-100 group-[[data-open]:not([data-dismissed])]:visible group-[[data-open]:not([data-dismissed])]:translate-y-0 group-[[data-open]:not([data-dismissed])]:opacity-100 before:absolute before:inset-x-0 before:top-full before:h-3 before:content-[''] after:absolute after:top-full after:left-1/2 after:-ml-1.5 after:border-6 after:border-transparent after:border-t-[color-mix(in_srgb,var(--glass-ink)_90%,transparent)] after:content-[''] motion-reduce:transition-none" role="tooltip" id="tip-inv">Invite people to this project</span></span>
    </div>
    <details class="group relative inline-block" data-menu open>
      <summary class="inline-flex cursor-pointer items-center justify-center gap-2 rounded-full border border-glass-edge bg-glass-control leading-none font-semibold text-ink no-underline inset-shadow-glass backdrop-blur-glass transition-[background-color,translate] duration-200 hover:bg-glass-strong active:translate-y-px disabled:cursor-not-allowed disabled:opacity-50 focus-visible:outline-3 focus-visible:outline-offset-3 focus-visible:outline-focus motion-reduce:transition-none motion-reduce:active:translate-y-0 min-h-11 px-5 text-[.95rem] list-none [&::-webkit-details-marker]:hidden">Project actions<svg class="size-4 transition-transform duration-200 group-open:rotate-180 motion-reduce:transition-none" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 9l6 6 6-6"/></svg></summary>
      <ul class="border border-glass-border bg-glass-strong text-ink shadow-glass inset-shadow-glass backdrop-blur-glass backdrop-saturate-150 absolute top-[calc(100%+8px)] left-0 z-10 min-w-[230px] rounded-2xl p-1.5">
        <li><button type="button" class="flex w-full cursor-pointer items-center gap-2.5 rounded-[10px] px-3 py-[9px] text-left text-[.92rem] text-ink hover:bg-glass-control focus-visible:outline-3 focus-visible:-outline-offset-1 focus-visible:outline-focus"><svg class="size-[18px] flex-none" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 20h4L19 9l-4-4L4 16z"/></svg>Rename<kbd class="ml-auto font-[inherit] text-[.78rem] text-ink-soft">R</kbd></button></li>
        <li><button type="button" class="flex w-full cursor-pointer items-center gap-2.5 rounded-[10px] px-3 py-[9px] text-left text-[.92rem] text-ink hover:bg-glass-control focus-visible:outline-3 focus-visible:-outline-offset-1 focus-visible:outline-focus"><svg class="size-[18px] flex-none" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round" aria-hidden="true"><rect x="8" y="8" width="12" height="12" rx="2"/><path d="M16 8V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h2"/></svg>Duplicate<kbd class="ml-auto font-[inherit] text-[.78rem] text-ink-soft">D</kbd></button></li>
        <li><button type="button" class="flex w-full cursor-pointer items-center gap-2.5 rounded-[10px] px-3 py-[9px] text-left text-[.92rem] text-ink hover:bg-glass-control focus-visible:outline-3 focus-visible:-outline-offset-1 focus-visible:outline-focus"><svg class="size-[18px] flex-none" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 12h12M12 6l6 6-6 6M20 4v16"/></svg>Move to team…</button></li>
        <li class="mt-1.5 border-t border-glass-border pt-1.5"><button type="button" class="flex w-full cursor-pointer items-center gap-2.5 rounded-[10px] px-3 py-[9px] text-left text-[.92rem] font-semibold text-bad hover:bg-glass-control focus-visible:outline-3 focus-visible:-outline-offset-1 focus-visible:outline-focus"><svg class="size-[18px] flex-none" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M10 11v6M14 11v6M6 7l1 12a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2l1-12M9 7V4h6v3"/></svg>Delete project</button></li>
      </ul>
    </details>
  </div>
</section>
</div>
CSS
/* ===== uiCookies Glassmorphism kit: design tokens (identical in every set) =====
   Retheme the whole kit here. Light scene on :root, dark scene on [data-scene="dark"]
   (or any [data-scene] holding a checked [data-scene-switch]). Selectors use :where()
   so the fallbacks below always win. */
:where(:root,[data-scene="light"]){
  color-scheme:light;
  /* background scene: the colour the glass frosts */
  --scene-base:linear-gradient(155deg,#eceffe 0%,#fbeef7 52%,#e6f6fb 100%);
  --scene-1:linear-gradient(140deg,#7c3aed,#c026d3);
  --scene-2:linear-gradient(140deg,#fb7185,#f97316);
  --scene-3:linear-gradient(140deg,#22d3ee,#3b82f6);
  --scene-4:linear-gradient(140deg,#fde047,#fb923c);
  /* glass */
  --glass-tint:255 255 255;
  --glass-border:rgb(255 255 255 / .8);
  --glass-edge:rgb(36 32 88 / .9);
  --glass-highlight:inset 0 1px 0 rgb(255 255 255 / .85);
  --glass-shadow:0 18px 40px -18px rgb(37 30 102 / .45);
  --glass-ink:#16133a;
  --glass-ink-soft:#3b3862;
  --glass-accent:#4338ca;
  --glass-accent-bg:rgb(67 56 202 / .92);
  --glass-on-accent:#fff;
  --glass-check-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --glass-focus:#1e1b4b;
  --glass-good:#14532d;--glass-good-bg:rgb(220 252 231 / .9);
  --glass-bad:#991b1b;--glass-bad-bg:rgb(254 226 226 / .9);
  --glass-warn:#7c2d12;--glass-warn-bg:rgb(254 243 199 / .9);
  --glass-scrim:rgb(22 19 58 / .3);
}
:where([data-scene="dark"]),:where([data-scene]:has([data-scene-switch]:checked)){
  color-scheme:dark;
  --scene-base:linear-gradient(155deg,#0a0c22 0%,#170c2c 52%,#06171f 100%);
  --scene-1:linear-gradient(140deg,#6d28d9,#a21caf);
  --scene-2:linear-gradient(140deg,#e11d48,#ea580c);
  --scene-3:linear-gradient(140deg,#0891b2,#2563eb);
  --scene-4:linear-gradient(140deg,#ca8a04,#c2410c);
  --glass-tint:16 18 44;
  --glass-border:rgb(255 255 255 / .2);
  --glass-edge:rgb(214 220 255 / .72);
  --glass-highlight:inset 0 1px 0 rgb(255 255 255 / .16);
  --glass-shadow:0 18px 40px -18px rgb(0 0 0 / .75);
  --glass-ink:#f5f6ff;
  --glass-ink-soft:#d0d3ee;
  --glass-accent:#a5b4fc;
  --glass-accent-bg:rgb(165 180 252 / .96);
  --glass-on-accent:#14123a;
  --glass-check-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%2314123a' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --glass-focus:#c7d2fe;
  --glass-good:#bbf7d0;--glass-good-bg:rgb(20 83 45 / .7);
  --glass-bad:#fecaca;--glass-bad-bg:rgb(127 29 29 / .7);
  --glass-warn:#fde68a;--glass-warn-bg:rgb(120 53 15 / .7);
  --glass-scrim:rgb(0 0 0 / .5);
}
:where(:root){
  --glass-alpha:.6;          /* panels and cards */
  --glass-alpha-strong:.82;  /* menus, dialogs, toasts: they cover unknown content */
  --glass-alpha-control:.5;  /* buttons and fields sitting on a panel */
  --glass-blur:18px;
  --glass-saturate:150%;
  --glass-radius:20px;
}
/* derived: recomputed inside every scene so a dark scene gets dark glass */
:where(:root,[data-scene]){
  --glass-bg:rgb(var(--glass-tint) / var(--glass-alpha));
  --glass-bg-strong:rgb(var(--glass-tint) / var(--glass-alpha-strong));
  --glass-bg-control:rgb(var(--glass-tint) / var(--glass-alpha-control));
}
/* no backdrop-filter: frosting can't happen, so the glass turns nearly solid */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  :where(:root){--glass-alpha:.94;--glass-alpha-strong:.97;--glass-alpha-control:.9}
}
@media (prefers-reduced-transparency:reduce){
  :where(:root){--glass-alpha:.93;--glass-alpha-strong:.97;--glass-alpha-control:.9;--glass-blur:8px}
}
@media (prefers-contrast:more){
  :where(:root){--glass-alpha:.96;--glass-alpha-strong:.98;--glass-alpha-control:.96}
  :where(:root,[data-scene]){--glass-border:var(--glass-ink);--glass-edge:var(--glass-ink)}
}
/* ===== end of tokens ===== */
/* Tailwind theme: utilities such as bg-glass, border-glass-edge, backdrop-blur-glass and text-ink read the tokens above */
@theme inline {
  --color-glass: var(--glass-bg);
  --color-glass-strong: var(--glass-bg-strong);
  --color-glass-control: var(--glass-bg-control);
  --color-glass-border: var(--glass-border);
  --color-glass-edge: var(--glass-edge);
  --color-ink: var(--glass-ink);
  --color-ink-soft: var(--glass-ink-soft);
  --color-accent: var(--glass-accent);
  --color-accent-glass: var(--glass-accent-bg);
  --color-on-accent: var(--glass-on-accent);
  --color-focus: var(--glass-focus);
  --color-good: var(--glass-good);
  --color-good-glass: var(--glass-good-bg);
  --color-bad: var(--glass-bad);
  --color-bad-glass: var(--glass-bad-bg);
  --color-warn: var(--glass-warn);
  --color-warn-glass: var(--glass-warn-bg);
  --color-scrim: var(--glass-scrim);
  --blur-glass: var(--glass-blur);
  --radius-glass: var(--glass-radius);
  --shadow-glass: var(--glass-shadow);
  --inset-shadow-glass: var(--glass-highlight);
  --animate-drift: g-drift 32s ease-in-out infinite alternate;
}
@keyframes g-drift { to { transform: translate3d(3vw,4vh,0) scale(1.06); } }
@theme { --animate-pop: g-pop .22s ease-out; }
@keyframes g-pop { from { opacity: 0; transform: translateY(10px) scale(.98); } }
JavaScript
// Dialog: open as a real modal (focus trap, Escape, ::backdrop). Toasts: dismiss. Tooltips and menus: Escape closes.
document.querySelectorAll('[data-dialog-open]').forEach(btn => btn.addEventListener('click', () => {
  const d = document.getElementById(btn.dataset.dialogOpen); if (!d) return;
  if (d.open) d.close(); d.showModal();
}));
document.querySelectorAll('[data-toast-dismiss]').forEach(btn => btn.addEventListener('click', () => btn.closest('[data-toast]')?.remove()));
document.addEventListener('keydown', e => {
  if (e.key !== 'Escape') return;
  document.querySelectorAll('[data-tip]').forEach(w => { w.dataset.dismissed = ''; });
  document.querySelectorAll('details[data-menu][open]').forEach(d => { d.open = false; d.querySelector('summary').focus(); });
});
document.querySelectorAll('[data-tip]').forEach(w => ['mouseleave', 'focusout'].forEach(ev => w.addEventListener(ev, () => delete w.dataset.dismissed)));
document.addEventListener('click', e => document.querySelectorAll('details[data-menu][open]').forEach(d => { if (!d.contains(e.target)) d.open = false; }));

About this set

Overlays and feedback for the uiCookies glassmorphism UI kit: a modal dialog, three toasts, an inline alert, tooltips and a dropdown menu. The dialog asks to archive a project, with an icon, a heading, a description and Cancel and Archive buttons; it is shown in place on the demo page and opens as a true modal from the button above it. The toasts confirm a sent invoice, report a failed upload and announce a new comment, each with a dismiss button. The alert warns that a trial is ending and links to billing. Three icon buttons carry tooltips, and a Project actions menu offers Rename, Duplicate, Move to team and Delete. Overlays use the stronger –glass-bg-strong tint because they cover content you do not control. The dialog is a native dialog element opened with showModal(), so focus is trapped and Escape closes it, and its backdrop blurs the page. The menu is a details element, so it opens without JavaScript. About a dozen lines of vanilla JavaScript open the dialog, dismiss toasts and close tooltips and the menu with Escape. The Bootstrap version feeds the tokens into Bootstrap’s own component variables, and the Tailwind version maps them to theme utilities such as bg-glass, border-glass-edge, backdrop-blur-glass and text-ink.

What’s included

  • Native dialog with a blurred backdrop, opened with showModal()
  • Success, error and info toasts with dismiss buttons
  • Inline warning alert with a link
  • Tooltips that open on hover and keyboard focus and close with Escape
  • Dropdown menu built on details and summary

Accessibility

The dialog is labelled by its heading and described by its text, traps focus as a modal and closes with Escape. Toasts sit in a role="status" region and their dismiss buttons name the toast. Tooltips use role="tooltip" with aria-describedby, open on focus as well as hover, stay open while hovered and close with Escape. All text was measured at 4.5:1, focus shows a 3px outline, and the pop-in animation stops under prefers-reduced-motion.

Customise it

Change --glass-alpha-strong for how opaque overlays are, --glass-scrim for the dialog backdrop and the --glass-good, --glass-bad and --glass-warn pairs for status colours. In Bootstrap they feed --bs-modal-*, --bs-toast-*, --bs-alert-*, --bs-tooltip-* and --bs-dropdown-* variables; in Tailwind edit bg-glass-strong and backdrop:bg-scrim.