Open demo

CSS code

HTML
<svg width="0" height="0" style="position:absolute" aria-hidden="true" focusable="false">
  <symbol id="dk-i-search" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><circle cx="11" cy="11" r="6.5"/><path d="m16 16 4.5 4.5"/></symbol>
  <symbol id="dk-i-x" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M6.5 6.5l11 11M17.5 6.5l-11 11"/></symbol>
  <symbol id="dk-i-plus" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><path d="M12 5v14M5 12h14"/></symbol>
  <symbol id="dk-i-user" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="9.5" cy="8" r="3.5"/><path d="M3.5 19.5c.8-3.2 3.1-5 6-5s5.2 1.8 6 5M18.5 8v6M15.5 11h6"/></symbol>
  <symbol id="dk-i-sliders" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><path d="M4 7h9M18 7h2M4 17h3M12 17h8"/><circle cx="15.5" cy="7" r="2.5"/><circle cx="9.5" cy="17" r="2.5"/></symbol>
  <symbol id="dk-i-box" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"><path d="M4 7.5 12 3.5l8 4v9l-8 4-8-4z"/><path d="m4 7.5 8 4 8-4M12 11.5v9"/></symbol>
  <symbol id="dk-i-kbd" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><rect x="3" y="6" width="18" height="12" rx="2.5"/><path d="M7 10h.01M10.5 10h.01M14 10h.01M17 10h.01M8 14h8"/></symbol>
  <symbol id="dk-i-help" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><circle cx="12" cy="12" r="8.5"/><circle cx="12" cy="12" r="3.5"/><path d="m6 6 3.5 3.5M14.5 14.5 18 18M18 6l-3.5 3.5M9.5 14.5 6 18"/></symbol>
  <symbol id="dk-i-key" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="15.5" r="4"/><path d="m11 12.5 8.5-8.5M16 7l2.5 2.5M13.5 9.5l2 2"/></symbol>
  <symbol id="dk-i-warn" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 4 2.8 19.5h18.4z"/><path d="M12 10v4.5M12 17h.01"/></symbol>
  <symbol id="dk-i-check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="m5.5 12.5 4 4 9-9"/></symbol>
  <symbol id="dk-i-spark" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3.5l1.9 5.2 5.1 1.9-5.1 1.9L12 17.7l-1.9-5.2L5 10.6l5.1-1.9z"/><path d="M18.5 16v4M16.5 18h4"/></symbol>
</svg>
<div><span class="lbl">Command palette</span>
<div class="btns"><button class="dk-launch" type="button" data-open="dk-palette" aria-haspopup="dialog" aria-keyshortcuts="Control+K Meta+K"><svg aria-hidden="true"><use href="#dk-i-search"/></svg><span>Search commands</span><span class="dk-keys" aria-hidden="true"><kbd>Ctrl</kbd><kbd>K</kbd></span></button></div></div>

<div><span class="lbl">Revoke API key</span>
<div class="btns"><button class="dk-btn is-danger" type="button" data-open="dk-revoke" aria-haspopup="dialog">Revoke key</button></div></div>

<div><span class="lbl">Upgrade plan</span>
<div class="btns"><button class="dk-btn is-primary" type="button" data-open="dk-upgrade" aria-haspopup="dialog"><svg aria-hidden="true"><use href="#dk-i-spark"/></svg>Upgrade to Pro</button></div></div>

<!-- 1. Command palette -->
<dialog class="dk is-palette" id="dk-palette" aria-labelledby="dk-palette-title">
  <form class="dk-form" method="dialog">
    <h2 class="dk-sr" id="dk-palette-title">Command palette</h2>
    <div class="dk-search">
      <svg aria-hidden="true"><use href="#dk-i-search"/></svg>
      <label class="dk-sr" for="dk-palette-q">Search commands and projects</label>
      <input id="dk-palette-q" type="text" placeholder="Type a command or search…" autocomplete="off" spellcheck="false" autofocus>
      <button class="dk-esc" value="close" aria-label="Close (Esc)">Esc</button>
    </div>
    <div class="dk-results" tabindex="0" role="region" aria-label="Results">
      <div class="dk-group" role="group" aria-labelledby="dk-g-sugg" data-dk-group>
        <h3 class="dk-group-title" id="dk-g-sugg">Suggestions</h3>
        <button class="dk-item" value="new-project" data-dk-item="New project create"><span class="dk-ico" aria-hidden="true"><svg><use href="#dk-i-plus"/></svg></span><span class="dk-name">New project</span><span class="dk-keys" aria-hidden="true"><kbd>N</kbd></span></button>
        <button class="dk-item" value="invite" data-dk-item="Invite teammate add member"><span class="dk-ico" aria-hidden="true"><svg><use href="#dk-i-user"/></svg></span><span class="dk-name">Invite teammate</span><span class="dk-keys" aria-hidden="true"><kbd>I</kbd></span></button>
        <button class="dk-item" value="settings" data-dk-item="Open settings preferences"><span class="dk-ico" aria-hidden="true"><svg><use href="#dk-i-sliders"/></svg></span><span class="dk-name">Open settings</span><span class="dk-keys" aria-hidden="true"><kbd>Ctrl</kbd><kbd>,</kbd></span></button>
      </div>
      <div class="dk-group" role="group" aria-labelledby="dk-g-proj" data-dk-group>
        <h3 class="dk-group-title" id="dk-g-proj">Projects</h3>
        <a class="dk-item" href="#" data-dk-item="Aurora API project"><span class="dk-ico is-cyan" aria-hidden="true"><svg><use href="#dk-i-box"/></svg></span><span class="dk-name">Aurora API</span><span class="dk-keys" aria-hidden="true"><kbd>G</kbd><kbd>1</kbd></span></a>
        <a class="dk-item" href="#" data-dk-item="Nimbus web project"><span class="dk-ico is-pink" aria-hidden="true"><svg><use href="#dk-i-box"/></svg></span><span class="dk-name">Nimbus web</span><span class="dk-keys" aria-hidden="true"><kbd>G</kbd><kbd>2</kbd></span></a>
        <a class="dk-item" href="#" data-dk-item="Tidewater mobile project"><span class="dk-ico is-amber" aria-hidden="true"><svg><use href="#dk-i-box"/></svg></span><span class="dk-name">Tidewater mobile</span><span class="dk-keys" aria-hidden="true"><kbd>G</kbd><kbd>3</kbd></span></a>
      </div>
      <div class="dk-group" role="group" aria-labelledby="dk-g-help" data-dk-group>
        <h3 class="dk-group-title" id="dk-g-help">Help</h3>
        <button class="dk-item" value="shortcuts" data-dk-item="Keyboard shortcuts help"><span class="dk-ico" aria-hidden="true"><svg><use href="#dk-i-kbd"/></svg></span><span class="dk-name">Keyboard shortcuts</span><span class="dk-keys" aria-hidden="true"><kbd>?</kbd></span></button>
        <a class="dk-item" href="#" data-dk-item="Contact support help"><span class="dk-ico" aria-hidden="true"><svg><use href="#dk-i-help"/></svg></span><span class="dk-name">Contact support</span><span class="dk-keys" aria-hidden="true"><kbd>Ctrl</kbd><kbd>/</kbd></span></a>
      </div>
      <p class="dk-empty" id="dk-palette-empty" hidden>No results for “<span data-dk-query></span>”</p>
    </div>
    <p class="dk-sr" id="dk-palette-count" aria-live="polite"></p>
    <div class="dk-hints"><span><kbd>↑</kbd><kbd>↓</kbd> to navigate</span><span><kbd>Enter</kbd> to open</span><span><kbd>Esc</kbd> to close</span></div>
  </form>
</dialog>

<!-- 2. Destructive confirmation -->
<dialog class="dk is-alert" id="dk-revoke" role="alertdialog" aria-labelledby="dk-revoke-title" aria-describedby="dk-revoke-desc">
  <form class="dk-form" method="dialog">
    <div class="dk-head">
      <span class="dk-glow" aria-hidden="true"><svg><use href="#dk-i-key"/></svg></span>
      <div class="dk-titles"><h2 class="dk-title" id="dk-revoke-title">Revoke production key?</h2><p class="dk-sub" id="dk-revoke-desc">Requests signed with this key will be rejected at once. This cannot be undone.</p></div>
    </div>
    <div class="dk-body">
      <div class="dk-keycard">
        <div class="dk-keycard-top"><code>sk_live_…4f2a</code><span class="dk-chip">Live</span></div>
        <p>Created 12 Mar 2026 · Last used 3 hours ago</p>
      </div>
      <div class="dk-warn"><svg aria-hidden="true"><use href="#dk-i-warn"/></svg><p>2 services use this key: <b>billing-worker</b> and <b>webhooks-relay</b>. They will stop authenticating until you give them a new key.</p></div>
    </div>
    <div class="dk-foot">
      <button class="dk-btn" value="cancel" autofocus>Cancel</button>
      <button class="dk-btn is-red" value="revoke">Revoke key</button>
    </div>
  </form>
</dialog>

<!-- 3. Upgrade plan -->
<dialog class="dk is-plan" id="dk-upgrade" aria-labelledby="dk-upgrade-title">
  <form class="dk-form" method="dialog">
    <div class="dk-head">
      <div class="dk-titles"><p class="dk-eyebrow"><svg aria-hidden="true"><use href="#dk-i-spark"/></svg>Upgrade</p><h2 class="dk-title" id="dk-upgrade-title">Nimbus Pro</h2><p class="dk-sub">Everything in Team, with room for every project you ship.</p></div>
      <button class="dk-x" value="close" aria-label="Close"><svg aria-hidden="true"><use href="#dk-i-x"/></svg></button>
    </div>
    <div class="dk-body">
      <fieldset class="dk-seg">
        <legend class="dk-sr">Billing period</legend>
        <input class="dk-sr" type="radio" name="dk-billing" id="dk-bill-m" value="monthly" checked><label for="dk-bill-m">Monthly</label>
        <input class="dk-sr" type="radio" name="dk-billing" id="dk-bill-y" value="yearly"><label for="dk-bill-y">Yearly <span class="dk-save">2 months free</span></label>
      </fieldset>
      <p class="dk-price" aria-live="polite">
        <span class="is-monthly"><b>£24</b>/mo <small>billed monthly</small></span>
        <span class="is-yearly"><b>£20</b>/mo <small>billed yearly at £240</small></span>
      </p>
      <ul class="dk-feats">
        <li><svg aria-hidden="true"><use href="#dk-i-check"/></svg>Unlimited projects</li>
        <li><svg aria-hidden="true"><use href="#dk-i-check"/></svg>50 GB storage</li>
        <li><svg aria-hidden="true"><use href="#dk-i-check"/></svg>Priority support</li>
        <li><svg aria-hidden="true"><use href="#dk-i-check"/></svg>SSO & audit log</li>
      </ul>
      <div class="dk-cta"><button class="dk-btn is-primary" value="upgrade">Upgrade now</button></div>
      <p class="dk-fine">Prices exclude VAT. Cancel any time; Pro runs to the end of the period you paid for.</p>
    </div>
  </form>
</dialog>
CSS
/* Dark modals on the native <dialog> element: near-black panels with a hairline border, a cyan focus ring
   and a violet accent. showModal() puts the dialog in the top layer, traps focus and closes it on Esc. */
.dk-sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.dk-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:42px;padding:9px 16px;border:1px solid #2e3441;border-radius:10px;
  background:#161a22;color:#e6e8ee;font-family:inherit;font-size:.9rem;font-weight:600;line-height:1.2;text-decoration:none;cursor:pointer;
  transition:background-color .15s,border-color .15s,box-shadow .15s,color .15s}
.dk-btn:hover{background:#1c212b;border-color:#3d4453}
.dk-btn:focus-visible{outline:2px solid #22d3ee;outline-offset:2px}
.dk-btn svg{width:18px;height:18px;flex:none}
.dk-btn.is-primary{border-color:transparent;background:linear-gradient(135deg,#7c3aed,#4f46e5);color:#fff;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 10px 28px -12px rgba(139,92,246,.9)}
.dk-btn.is-primary:hover{background:linear-gradient(135deg,#6d28d9,#4338ca)}
.dk-btn.is-danger{border-color:#dc2626;background:transparent;color:#fca5a5}
.dk-btn.is-danger:hover{background:rgba(239,68,68,.12);color:#fecaca}
.dk-btn.is-red{border-color:#dc2626;background:#dc2626;color:#fff;box-shadow:inset 0 1px 0 rgba(255,255,255,.18),0 10px 28px -12px rgba(239,68,68,.9)}
.dk-btn.is-red:hover{background:#b91c1c;border-color:#b91c1c}
/* The palette trigger looks like a search field with its shortcut */
.dk-launch{display:flex;align-items:center;gap:10px;width:100%;max-width:300px;min-height:44px;padding:8px 8px 8px 12px;border:1px solid #2e3441;border-radius:10px;
  background:#12151c;color:#9aa3b5;font-family:inherit;font-size:.9rem;text-align:left;cursor:pointer;transition:border-color .15s,color .15s}
.dk-launch:hover{border-color:#3d4453;color:#e6e8ee}
.dk-launch:focus-visible{outline:2px solid #22d3ee;outline-offset:2px}
.dk-launch>svg{width:18px;height:18px;flex:none}
.dk-launch>span:first-of-type{flex:1}
.dk-keys{display:flex;flex:none;gap:4px;margin-left:auto}
.dk-launch kbd,.dk kbd{min-width:22px;padding:1px 6px;border:1px solid #2e3441;border-bottom-width:2px;border-radius:6px;background:#1a1f29;color:#b4bccb;
  font:600 .7rem/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;text-align:center}

.dk{--dk-bg:#12151c;--dk-line:#262b37;--dk-ink:#e6e8ee;--dk-muted:#8b93a5;--dk-ring:#22d3ee;--dk-soft:#0e1117;--dk-w:460px;
  width:min(var(--dk-w),calc(100% - 32px));max-width:none;max-height:calc(100dvh - 56px);margin:auto;padding:0;border:1px solid var(--dk-line);border-radius:16px;
  background:var(--dk-bg) linear-gradient(rgba(255,255,255,.035),rgba(255,255,255,0) 140px);color:var(--dk-ink);color-scheme:dark;font-size:.95rem;line-height:1.55;
  overflow:hidden;overscroll-behavior:contain;box-shadow:inset 0 1px 0 rgba(255,255,255,.07),0 32px 80px -24px rgba(0,0,0,.9)}
.dk[open]{display:flex;flex-direction:column;animation:dk-in .2s cubic-bezier(.2,.8,.2,1)}
.dk::backdrop{background:rgba(3,4,8,.72);backdrop-filter:blur(6px)}
.dk[open]::backdrop{animation:dk-fade .2s ease-out}
@keyframes dk-in{from{opacity:0;transform:translateY(8px) scale(.98)}}
@keyframes dk-fade{from{opacity:0}}
html:has(.dk:modal){overflow:hidden} /* stop the page scrolling behind an open modal */

.dk-form{display:flex;flex-direction:column;flex:1;min-height:0;margin:0}
.dk-head{display:flex;align-items:flex-start;gap:14px;padding:24px 24px 4px}
.dk-titles{flex:1;min-width:0}
.dk-title{margin:0;font-size:1.15rem;font-weight:700;letter-spacing:-.01em;line-height:1.35}
.dk-sub{margin:4px 0 0;color:var(--dk-muted);font-size:.875rem}
.dk-x{flex:none;display:grid;place-items:center;width:36px;height:36px;margin:-6px -10px 0 0;padding:0;border:0;border-radius:10px;background:transparent;color:var(--dk-muted);cursor:pointer;
  transition:background-color .15s,color .15s}
.dk-x:hover{background:#1c212b;color:var(--dk-ink)}
.dk-x:focus-visible{outline:2px solid var(--dk-ring);outline-offset:1px}
.dk-x svg{width:20px;height:20px}
.dk-body{flex:1 1 auto;min-height:0;padding:14px 24px 22px;color:var(--dk-muted)}
.dk-body p{margin:0}
.dk-foot{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:10px;padding:16px 24px;border-top:1px solid var(--dk-line);background:var(--dk-soft)}

/* 1. Command palette: near the top of the viewport, results scroll under a fixed search row */
.dk.is-palette{--dk-w:640px;margin:15vh auto auto;max-height:calc(85vh - 24px)}
.dk-search{display:flex;align-items:center;gap:12px;padding:0 14px 0 18px;border-bottom:1px solid var(--dk-line)}
.dk-search:focus-within{box-shadow:inset 0 -2px 0 var(--dk-ring)}
.dk-search>svg{width:20px;height:20px;flex:none;color:var(--dk-muted)}
.dk-search input{flex:1;min-width:0;height:58px;padding:0;border:0;background:transparent;color:var(--dk-ink);font:inherit;font-size:1.05rem;outline:0}
.dk-search input::placeholder{color:#7d869a}
.dk-esc{flex:none;min-height:28px;padding:2px 8px;border:1px solid #2e3441;border-bottom-width:2px;border-radius:6px;background:#1a1f29;color:#b4bccb;
  font:600 .72rem/1 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;cursor:pointer}
.dk-esc:hover{color:var(--dk-ink);border-color:#3d4453}
.dk-esc:focus-visible{outline:2px solid var(--dk-ring);outline-offset:2px}
.dk-results{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:8px}
.dk-results:focus-visible{outline:2px solid var(--dk-ring);outline-offset:-2px}
.dk-group{padding:2px 0 6px}
.dk-group-title{margin:8px 10px 4px;color:var(--dk-muted);font-size:.7rem;font-weight:600;letter-spacing:.1em;text-transform:uppercase}
.dk-item{display:flex;align-items:center;gap:12px;width:100%;min-height:44px;padding:7px 10px;border:0;border-radius:10px;background:transparent;color:#d4d8e1;
  font-family:inherit;font-size:.92rem;line-height:1.3;text-align:left;text-decoration:none;cursor:pointer}
.dk-item[hidden],.dk-group[hidden],.dk-empty[hidden]{display:none}
.dk-item:hover{background:#1a1f29;color:#fff}
.dk-item:focus-visible{outline:2px solid var(--dk-ring);outline-offset:-2px;background:#1a1f29;color:#fff}
.dk-ico{flex:none;display:grid;place-items:center;width:30px;height:30px;border:1px solid #2a303c;border-radius:8px;background:#171b24;color:#a78bfa}
.dk-ico svg{width:17px;height:17px}
.dk-ico.is-cyan{color:#67e8f9}
.dk-ico.is-amber{color:#fcd34d}
.dk-ico.is-pink{color:#f9a8d4}
.dk-name{flex:1;min-width:0}
.dk-empty{margin:0;padding:32px 16px;color:var(--dk-muted);text-align:center}
.dk-empty span{color:var(--dk-ink)}
.dk-hints{display:flex;flex-wrap:wrap;gap:6px 18px;padding:10px 16px;border-top:1px solid var(--dk-line);background:var(--dk-soft);color:var(--dk-muted);font-size:.78rem}
.dk-hints kbd{margin-right:2px}

/* 2. Revoke API key: a destructive confirmation */
.dk.is-alert{--dk-w:460px}
.dk-glow{flex:none;display:grid;place-items:center;width:44px;height:44px;border-radius:12px;background:rgba(239,68,68,.12);color:#f87171;
  box-shadow:0 0 0 1px rgba(248,113,113,.3),0 0 32px -4px rgba(239,68,68,.6)}
.dk-glow svg{width:22px;height:22px}
.dk-keycard{margin-top:16px;padding:12px 14px;border:1px solid var(--dk-line);border-radius:10px;background:var(--dk-soft)}
.dk-keycard-top{display:flex;align-items:center;justify-content:space-between;gap:10px}
.dk-keycard code{color:var(--dk-ink);font:600 .92rem/1.4 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
.dk-keycard p{margin:4px 0 0;font-size:.8rem}
.dk-chip{flex:none;padding:2px 8px;border:1px solid rgba(248,113,113,.35);border-radius:999px;background:rgba(239,68,68,.1);color:#fca5a5;font-size:.7rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase}
.dk-warn{display:flex;align-items:flex-start;gap:10px;margin-top:12px;padding:10px 12px;border:1px solid rgba(251,191,36,.28);border-radius:10px;background:rgba(251,191,36,.07);color:#fcd34d;font-size:.85rem}
.dk-warn svg{width:18px;height:18px;flex:none;margin-top:1px}
.dk-warn b{color:#fde68a;font-weight:600}

/* 3. Upgrade plan: a gradient border, a CSS-only billing toggle */
.dk.is-plan{--dk-w:440px;border-color:transparent;
  background:linear-gradient(#161a23,#12151c 160px) padding-box,linear-gradient(135deg,#8b5cf6,#22d3ee) border-box;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07),0 32px 90px -28px rgba(139,92,246,.55),0 24px 60px -24px rgba(0,0,0,.9)}
.dk-eyebrow{display:inline-flex;align-items:center;gap:6px;margin:0 0 8px;padding:3px 10px 3px 8px;border:1px solid rgba(167,139,250,.35);border-radius:999px;background:rgba(139,92,246,.12);color:#c4b5fd;font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase}
.dk-eyebrow svg{width:14px;height:14px}
.dk.is-plan .dk-title{font-size:1.5rem;letter-spacing:-.02em}
.dk-seg{display:grid;grid-template-columns:1fr 1fr;gap:4px;min-width:0;margin:0;padding:4px;border:1px solid var(--dk-line);border-radius:12px;background:var(--dk-soft)}
.dk-seg label{display:flex;align-items:center;justify-content:center;gap:8px;min-height:38px;padding:6px 10px;border-radius:9px;color:var(--dk-muted);font-size:.88rem;font-weight:600;cursor:pointer;transition:background-color .15s,color .15s}
.dk-seg label:hover{color:var(--dk-ink)}
.dk-seg input:checked+label{background:#1f2430;color:#fff;box-shadow:inset 0 0 0 1px rgba(139,92,246,.75),0 1px 2px rgba(0,0,0,.4)}
.dk-seg input:focus-visible+label{outline:2px solid var(--dk-ring);outline-offset:1px}
.dk-save{padding:1px 7px;border-radius:999px;background:rgba(34,211,238,.12);color:#67e8f9;font-size:.68rem;font-weight:700;white-space:nowrap}
.dk-price{margin:18px 0 0!important;color:var(--dk-ink)}
.dk-price>span{display:flex;align-items:baseline;flex-wrap:wrap;gap:4px 6px}
.dk-price b{font-size:2.5rem;font-weight:700;letter-spacing:-.03em;line-height:1}
.dk-price small{margin-left:4px;color:var(--dk-muted);font-size:.85rem}
.dk-price .is-yearly,.dk.is-plan:has(input[value="yearly"]:checked) .dk-price .is-monthly{display:none}
.dk.is-plan:has(input[value="yearly"]:checked) .dk-price .is-yearly{display:flex}
.dk-feats{display:grid;gap:10px;margin:18px 0 0;padding:18px 0 0;border-top:1px solid var(--dk-line);list-style:none}
.dk-feats li{display:flex;align-items:center;gap:10px;color:#d4d8e1;font-size:.9rem}
.dk-feats svg{flex:none;width:20px;height:20px;padding:3px;border-radius:50%;background:rgba(34,211,238,.12);color:#22d3ee}
.dk-cta{margin-top:22px}
.dk-cta .dk-btn{width:100%;min-height:46px;font-size:.95rem}
.dk-fine{margin-top:12px!important;font-size:.78rem;text-align:center}

@media (max-width:600px){
  .dk{max-height:calc(100dvh - 32px)}
  .dk.is-palette{margin-top:10vh;max-height:calc(90vh - 16px)}
  .dk-head,.dk-foot{padding-left:18px;padding-right:18px}
  .dk-body{padding-left:18px;padding-right:18px}
  .dk-foot .dk-btn{flex:1 1 auto}
  .dk-item .dk-keys{display:none}
}
@media (prefers-reduced-motion:reduce){
  .dk[open],.dk[open]::backdrop{animation:none}
  .dk-btn,.dk-launch,.dk-x,.dk-seg label{transition:none}
}
JavaScript
// Open a dialog from any button with data-open="dialog-id". showModal() traps focus, closes on Esc
// and makes the page behind inert. Buttons inside <form method="dialog"> close it with no script.
document.querySelectorAll('[data-open]').forEach(function (btn) {
  var dialog = document.getElementById(btn.getAttribute('data-open'));
  if (!dialog) return;
  btn.addEventListener('click', function () {
    dialog.showModal();
    dialog.addEventListener('close', function () { btn.focus(); }, { once: true }); // focus back to the trigger
  });
  // A click on the backdrop lands on the <dialog> itself (its form fills the box), so close it
  dialog.addEventListener('click', function (e) { if (e.target === dialog) dialog.close(); });
});

// Command palette: Ctrl+K / Cmd+K opens it from anywhere, typing filters the results,
// ArrowUp/ArrowDown move between visible results and Enter in the search box opens the first one.
(function () {
  var pal = document.getElementById('dk-palette');
  if (!pal) return;
  var input = document.getElementById('dk-palette-q');
  var empty = document.getElementById('dk-palette-empty');
  var count = document.getElementById('dk-palette-count');
  var items = [].slice.call(pal.querySelectorAll('[data-dk-item]'));
  var groups = [].slice.call(pal.querySelectorAll('[data-dk-group]'));
  function shown() { return items.filter(function (el) { return !el.hidden; }); }

  function filter() {
    var q = input.value.trim().toLowerCase();
    items.forEach(function (el) { el.hidden = el.getAttribute('data-dk-item').toLowerCase().indexOf(q) === -1; });
    groups.forEach(function (g) { g.hidden = !g.querySelector('[data-dk-item]:not([hidden])'); });
    var n = shown().length;
    empty.hidden = n > 0;
    empty.querySelector('[data-dk-query]').textContent = input.value.trim();
    count.textContent = !q ? '' : n ? n + (n === 1 ? ' result' : ' results') : 'No results'; // read out by aria-live
  }
  input.addEventListener('input', filter);
  pal.addEventListener('close', function () { input.value = ''; filter(); }); // start fresh next time

  pal.addEventListener('keydown', function (e) {
    var list = shown(), i = list.indexOf(document.activeElement);
    if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
      e.preventDefault();
      if (!list.length) return;
      if (e.key === 'ArrowDown') (list[i + 1] || list[0]).focus();
      else if (i <= 0) input.focus();
      else list[i - 1].focus();
    } else if (e.key === 'Enter' && e.target === input) {
      e.preventDefault(); // do not submit the form; open the top result instead
      if (list[0]) list[0].click();
    } else if (i > -1 && e.key.length === 1 && e.key !== ' ' && !e.ctrlKey && !e.metaKey && !e.altKey) {
      input.focus(); // typing on a result goes back to the search box
    }
  });
  // Links do not close a dialog by themselves
  items.forEach(function (el) { if (el.tagName === 'A') el.addEventListener('click', function () { pal.close(); }); });

  document.addEventListener('keydown', function (e) {
    if (!(e.ctrlKey || e.metaKey) || e.key.toLowerCase() !== 'k') return;
    e.preventDefault();
    if (pal.open) { input.focus(); return; }
    if (document.querySelector('dialog:modal')) return; // another dialog is already open
    var back = document.activeElement;
    pal.showModal();
    pal.addEventListener('close', function () { if (back && back.focus) back.focus(); }, { once: true });
  });
})();

Bootstrap 5 code

Requires: Bootstrap 5.3.8 CSS, Bootstrap 5.3.8 JS bundle

HTML
<svg width="0" height="0" style="position:absolute" aria-hidden="true" focusable="false">
  <symbol id="dk-i-search" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><circle cx="11" cy="11" r="6.5"/><path d="m16 16 4.5 4.5"/></symbol>
  <symbol id="dk-i-x" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M6.5 6.5l11 11M17.5 6.5l-11 11"/></symbol>
  <symbol id="dk-i-plus" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><path d="M12 5v14M5 12h14"/></symbol>
  <symbol id="dk-i-user" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="9.5" cy="8" r="3.5"/><path d="M3.5 19.5c.8-3.2 3.1-5 6-5s5.2 1.8 6 5M18.5 8v6M15.5 11h6"/></symbol>
  <symbol id="dk-i-sliders" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><path d="M4 7h9M18 7h2M4 17h3M12 17h8"/><circle cx="15.5" cy="7" r="2.5"/><circle cx="9.5" cy="17" r="2.5"/></symbol>
  <symbol id="dk-i-box" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"><path d="M4 7.5 12 3.5l8 4v9l-8 4-8-4z"/><path d="m4 7.5 8 4 8-4M12 11.5v9"/></symbol>
  <symbol id="dk-i-kbd" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><rect x="3" y="6" width="18" height="12" rx="2.5"/><path d="M7 10h.01M10.5 10h.01M14 10h.01M17 10h.01M8 14h8"/></symbol>
  <symbol id="dk-i-help" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><circle cx="12" cy="12" r="8.5"/><circle cx="12" cy="12" r="3.5"/><path d="m6 6 3.5 3.5M14.5 14.5 18 18M18 6l-3.5 3.5M9.5 14.5 6 18"/></symbol>
  <symbol id="dk-i-key" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="15.5" r="4"/><path d="m11 12.5 8.5-8.5M16 7l2.5 2.5M13.5 9.5l2 2"/></symbol>
  <symbol id="dk-i-warn" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 4 2.8 19.5h18.4z"/><path d="M12 10v4.5M12 17h.01"/></symbol>
  <symbol id="dk-i-check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="m5.5 12.5 4 4 9-9"/></symbol>
  <symbol id="dk-i-spark" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3.5l1.9 5.2 5.1 1.9-5.1 1.9L12 17.7l-1.9-5.2L5 10.6l5.1-1.9z"/><path d="M18.5 16v4M16.5 18h4"/></symbol>
</svg>
<div><span class="lbl">Command palette</span>
<div class="d-flex flex-wrap gap-2"><button class="btn dk-launch" type="button" data-bs-toggle="modal" data-bs-target="#dk-palette" aria-keyshortcuts="Control+K Meta+K"><svg aria-hidden="true"><use href="#dk-i-search"/></svg><span>Search commands</span><span class="dk-keys" aria-hidden="true"><kbd>Ctrl</kbd><kbd>K</kbd></span></button></div></div>

<div><span class="lbl">Revoke API key</span>
<div class="d-flex flex-wrap gap-2"><button class="btn dk-btn btn-outline-danger" type="button" data-bs-toggle="modal" data-bs-target="#dk-revoke">Revoke key</button></div></div>

<div><span class="lbl">Upgrade plan</span>
<div class="d-flex flex-wrap gap-2"><button class="btn dk-btn btn-primary" type="button" data-bs-toggle="modal" data-bs-target="#dk-upgrade"><svg aria-hidden="true"><use href="#dk-i-spark"/></svg>Upgrade to Pro</button></div></div>

<!-- 1. Command palette -->
<div class="modal fade dk dk-palette" id="dk-palette" tabindex="-1" aria-labelledby="dk-palette-title" aria-hidden="true" data-bs-theme="dark">
  <div class="modal-dialog">
    <div class="modal-content">
      <h2 class="visually-hidden" id="dk-palette-title">Command palette</h2>
      <div class="dk-search">
        <svg aria-hidden="true"><use href="#dk-i-search"/></svg>
        <label class="visually-hidden" for="dk-palette-q">Search commands and projects</label>
        <input class="form-control" id="dk-palette-q" type="text" placeholder="Type a command or search…" autocomplete="off" spellcheck="false">
        <button class="dk-esc" type="button" data-bs-dismiss="modal" aria-label="Close (Esc)">Esc</button>
      </div>
      <div class="modal-body dk-results" tabindex="0" role="region" aria-label="Results">
        <div class="dk-group" role="group" aria-labelledby="dk-g-sugg" data-dk-group>
          <h3 class="dk-group-title" id="dk-g-sugg">Suggestions</h3>
          <div class="list-group">
            <button class="list-group-item list-group-item-action dk-item" type="button" data-bs-dismiss="modal" data-dk-item="New project create"><span class="dk-ico" aria-hidden="true"><svg><use href="#dk-i-plus"/></svg></span><span class="dk-name">New project</span><span class="dk-keys" aria-hidden="true"><kbd>N</kbd></span></button>
            <button class="list-group-item list-group-item-action dk-item" type="button" data-bs-dismiss="modal" data-dk-item="Invite teammate add member"><span class="dk-ico" aria-hidden="true"><svg><use href="#dk-i-user"/></svg></span><span class="dk-name">Invite teammate</span><span class="dk-keys" aria-hidden="true"><kbd>I</kbd></span></button>
            <button class="list-group-item list-group-item-action dk-item" type="button" data-bs-dismiss="modal" data-dk-item="Open settings preferences"><span class="dk-ico" aria-hidden="true"><svg><use href="#dk-i-sliders"/></svg></span><span class="dk-name">Open settings</span><span class="dk-keys" aria-hidden="true"><kbd>Ctrl</kbd><kbd>,</kbd></span></button>
          </div>
        </div>
        <div class="dk-group" role="group" aria-labelledby="dk-g-proj" data-dk-group>
          <h3 class="dk-group-title" id="dk-g-proj">Projects</h3>
          <div class="list-group">
            <a class="list-group-item list-group-item-action dk-item" href="#" data-dk-item="Aurora API project"><span class="dk-ico is-cyan" aria-hidden="true"><svg><use href="#dk-i-box"/></svg></span><span class="dk-name">Aurora API</span><span class="dk-keys" aria-hidden="true"><kbd>G</kbd><kbd>1</kbd></span></a>
            <a class="list-group-item list-group-item-action dk-item" href="#" data-dk-item="Nimbus web project"><span class="dk-ico is-pink" aria-hidden="true"><svg><use href="#dk-i-box"/></svg></span><span class="dk-name">Nimbus web</span><span class="dk-keys" aria-hidden="true"><kbd>G</kbd><kbd>2</kbd></span></a>
            <a class="list-group-item list-group-item-action dk-item" href="#" data-dk-item="Tidewater mobile project"><span class="dk-ico is-amber" aria-hidden="true"><svg><use href="#dk-i-box"/></svg></span><span class="dk-name">Tidewater mobile</span><span class="dk-keys" aria-hidden="true"><kbd>G</kbd><kbd>3</kbd></span></a>
          </div>
        </div>
        <div class="dk-group" role="group" aria-labelledby="dk-g-help" data-dk-group>
          <h3 class="dk-group-title" id="dk-g-help">Help</h3>
          <div class="list-group">
            <button class="list-group-item list-group-item-action dk-item" type="button" data-bs-dismiss="modal" data-dk-item="Keyboard shortcuts help"><span class="dk-ico" aria-hidden="true"><svg><use href="#dk-i-kbd"/></svg></span><span class="dk-name">Keyboard shortcuts</span><span class="dk-keys" aria-hidden="true"><kbd>?</kbd></span></button>
            <a class="list-group-item list-group-item-action dk-item" href="#" data-dk-item="Contact support help"><span class="dk-ico" aria-hidden="true"><svg><use href="#dk-i-help"/></svg></span><span class="dk-name">Contact support</span><span class="dk-keys" aria-hidden="true"><kbd>Ctrl</kbd><kbd>/</kbd></span></a>
          </div>
        </div>
        <p class="dk-empty" id="dk-palette-empty" hidden>No results for “<span data-dk-query></span>”</p>
      </div>
      <p class="visually-hidden" id="dk-palette-count" aria-live="polite"></p>
      <div class="modal-footer dk-hints"><span><kbd>↑</kbd><kbd>↓</kbd> to navigate</span><span><kbd>Enter</kbd> to open</span><span><kbd>Esc</kbd> to close</span></div>
    </div>
  </div>
</div>

<!-- 2. Destructive confirmation -->
<div class="modal fade dk dk-alert" id="dk-revoke" tabindex="-1" role="alertdialog" aria-labelledby="dk-revoke-title" aria-describedby="dk-revoke-desc" aria-hidden="true" data-bs-theme="dark">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header">
        <span class="dk-glow" aria-hidden="true"><svg><use href="#dk-i-key"/></svg></span>
        <div class="flex-grow-1"><h2 class="modal-title" id="dk-revoke-title">Revoke production key?</h2><p class="dk-sub" id="dk-revoke-desc">Requests signed with this key will be rejected at once. This cannot be undone.</p></div>
      </div>
      <div class="modal-body">
        <div class="dk-keycard">
          <div class="d-flex align-items-center justify-content-between gap-2"><code>sk_live_…4f2a</code><span class="badge rounded-pill dk-chip">Live</span></div>
          <p>Created 12 Mar 2026 · Last used 3 hours ago</p>
        </div>
        <div class="alert dk-warn"><svg aria-hidden="true"><use href="#dk-i-warn"/></svg><p>2 services use this key: <b>billing-worker</b> and <b>webhooks-relay</b>. They will stop authenticating until you give them a new key.</p></div>
      </div>
      <div class="modal-footer">
        <button class="btn dk-btn" type="button" data-bs-dismiss="modal" autofocus>Cancel</button>
        <button class="btn dk-btn btn-danger" type="button" data-bs-dismiss="modal">Revoke key</button>
      </div>
    </div>
  </div>
</div>

<!-- 3. Upgrade plan -->
<div class="modal fade dk dk-plan" id="dk-upgrade" tabindex="-1" aria-labelledby="dk-upgrade-title" aria-hidden="true" data-bs-theme="dark">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header">
        <div class="flex-grow-1"><p class="badge rounded-pill dk-eyebrow"><svg aria-hidden="true"><use href="#dk-i-spark"/></svg>Upgrade</p><h2 class="modal-title" id="dk-upgrade-title">Nimbus Pro</h2><p class="dk-sub">Everything in Team, with room for every project you ship.</p></div>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <fieldset class="dk-seg">
          <legend class="visually-hidden">Billing period</legend>
          <input class="btn-check" type="radio" name="dk-billing" id="dk-bill-m" value="monthly" checked><label class="btn" for="dk-bill-m">Monthly</label>
          <input class="btn-check" type="radio" name="dk-billing" id="dk-bill-y" value="yearly"><label class="btn" for="dk-bill-y">Yearly <span class="badge rounded-pill dk-save">2 months free</span></label>
        </fieldset>
        <p class="dk-price" aria-live="polite">
          <span class="is-monthly"><b>£24</b>/mo <small>billed monthly</small></span>
          <span class="is-yearly"><b>£20</b>/mo <small>billed yearly at £240</small></span>
        </p>
        <ul class="list-unstyled dk-feats">
          <li><svg aria-hidden="true"><use href="#dk-i-check"/></svg>Unlimited projects</li>
          <li><svg aria-hidden="true"><use href="#dk-i-check"/></svg>50 GB storage</li>
          <li><svg aria-hidden="true"><use href="#dk-i-check"/></svg>Priority support</li>
          <li><svg aria-hidden="true"><use href="#dk-i-check"/></svg>SSO & audit log</li>
        </ul>
        <button class="btn dk-btn btn-primary dk-cta w-100" type="button" data-bs-dismiss="modal">Upgrade now</button>
        <p class="dk-fine">Prices exclude VAT. Cancel any time; Pro runs to the end of the period you paid for.</p>
      </div>
    </div>
  </div>
</div>
CSS
/* Bootstrap's Modal in its dark colour mode (data-bs-theme="dark"), restyled through --bs-modal-*, --bs-btn-*,
   --bs-list-group-* and --bs-backdrop-* variables: near-black panels, hairline borders, a cyan focus ring, a violet accent. */
.dk-btn{--bs-btn-padding-x:16px;--bs-btn-padding-y:9px;--bs-btn-font-size:.9rem;--bs-btn-font-weight:600;--bs-btn-line-height:1.2;--bs-btn-border-radius:10px;
  --bs-btn-bg:#161a22;--bs-btn-color:#e6e8ee;--bs-btn-border-color:#2e3441;--bs-btn-hover-bg:#1c212b;--bs-btn-hover-color:#e6e8ee;--bs-btn-hover-border-color:#3d4453;
  --bs-btn-active-bg:#222834;--bs-btn-active-color:#fff;--bs-btn-active-border-color:#3d4453;
  display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:42px}
.dk-btn:focus-visible,.dk-launch:focus-visible{outline:2px solid #22d3ee;outline-offset:2px;box-shadow:none}
.dk-btn svg{width:18px;height:18px;flex:none}
.dk-btn.btn-primary{--bs-btn-color:#fff;--bs-btn-hover-color:#fff;--bs-btn-active-color:#fff;--bs-btn-border-color:transparent;--bs-btn-hover-border-color:transparent;--bs-btn-active-border-color:transparent;
  background-image:linear-gradient(135deg,#7c3aed,#4f46e5);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 10px 28px -12px rgba(139,92,246,.9)}
.dk-btn.btn-primary:hover,.dk-btn.btn-primary:active{background-image:linear-gradient(135deg,#6d28d9,#4338ca)}
.dk-btn.btn-outline-danger{--bs-btn-bg:transparent;--bs-btn-color:#fca5a5;--bs-btn-border-color:#dc2626;--bs-btn-hover-bg:rgba(239,68,68,.12);--bs-btn-hover-color:#fecaca;--bs-btn-hover-border-color:#dc2626;
  --bs-btn-active-bg:rgba(239,68,68,.2);--bs-btn-active-color:#fecaca;--bs-btn-active-border-color:#dc2626}
.dk-btn.btn-danger{--bs-btn-bg:#dc2626;--bs-btn-color:#fff;--bs-btn-border-color:#dc2626;--bs-btn-hover-bg:#b91c1c;--bs-btn-hover-color:#fff;--bs-btn-hover-border-color:#b91c1c;
  --bs-btn-active-bg:#991b1b;--bs-btn-active-color:#fff;--bs-btn-active-border-color:#991b1b;box-shadow:inset 0 1px 0 rgba(255,255,255,.18),0 10px 28px -12px rgba(239,68,68,.9)}
/* The palette trigger looks like a search field with its shortcut */
.dk-launch{--bs-btn-padding-x:0;--bs-btn-padding-y:0;--bs-btn-font-size:.9rem;--bs-btn-font-weight:400;--bs-btn-border-radius:10px;--bs-btn-bg:#12151c;--bs-btn-color:#9aa3b5;--bs-btn-border-color:#2e3441;
  --bs-btn-hover-bg:#12151c;--bs-btn-hover-color:#e6e8ee;--bs-btn-hover-border-color:#3d4453;--bs-btn-active-bg:#12151c;--bs-btn-active-color:#e6e8ee;--bs-btn-active-border-color:#3d4453;
  display:flex;align-items:center;gap:10px;width:100%;max-width:300px;min-height:44px;padding:8px 8px 8px 12px;text-align:left}
.dk-launch>svg{width:18px;height:18px;flex:none}
.dk-launch>span:first-of-type{flex:1}
.dk-keys{display:flex;flex:none;gap:4px;margin-left:auto}
.dk-launch kbd,.dk kbd{min-width:22px;padding:1px 6px;border:1px solid #2e3441;border-bottom-width:2px;border-radius:6px;background:#1a1f29;color:#b4bccb;
  font:600 .7rem/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;text-align:center}

.dk{--bs-modal-width:460px;--bs-modal-margin:1rem;--bs-modal-color:#e6e8ee;--bs-modal-bg:#12151c;--bs-modal-border-color:#262b37;--bs-modal-border-width:1px;
  --bs-modal-border-radius:16px;--bs-modal-inner-border-radius:15px;--bs-modal-header-padding:24px 24px 4px;--bs-modal-header-border-width:0;--bs-modal-title-line-height:1.35;
  --bs-modal-footer-bg:#0e1117;--bs-modal-footer-border-color:#262b37;font-size:.95rem;line-height:1.55}
@media (min-width:576px){.dk{--bs-modal-margin:1.75rem}}
.dk .modal-content{overflow:hidden;background-image:linear-gradient(rgba(255,255,255,.035),rgba(255,255,255,0) 140px);box-shadow:inset 0 1px 0 rgba(255,255,255,.07),0 32px 80px -24px rgba(0,0,0,.9)}
.dk .modal-header{align-items:flex-start;gap:14px}
.dk .modal-title{font-size:1.15rem;font-weight:700;letter-spacing:-.01em}
.dk-sub{margin:4px 0 0;color:#8b93a5;font-size:.875rem}
.dk .modal-body{padding:14px 24px 22px;color:#8b93a5}
.dk .modal-body p{margin:0}
.dk .modal-footer{gap:10px;padding:16px 24px}
.dk .modal-footer>*{margin:0}
.dk .modal-header .btn-close{flex:none;width:36px;height:36px;margin:-6px -10px 0 auto;padding:0;border-radius:10px;background-size:13px;opacity:.7}
.dk .btn-close:hover{background-color:#1c212b;opacity:1}
.dk .btn-close:focus-visible{outline:2px solid #22d3ee;outline-offset:1px;box-shadow:none;opacity:1}
/* Same entrance as the plain version: a short rise instead of Bootstrap's 50px drop */
.dk.fade .modal-dialog{transform:translateY(8px) scale(.98);transition:transform .2s cubic-bezier(.2,.8,.2,1)}
.dk.show .modal-dialog{transform:none}
.modal-backdrop{--bs-backdrop-bg:rgba(3,4,8,.72);--bs-backdrop-opacity:1;backdrop-filter:blur(6px)}

/* 1. Command palette: near the top of the viewport, results scroll under a fixed search row */
.dk-palette{--bs-modal-width:640px}
.dk-palette .modal-dialog{margin-top:15vh}
.dk-palette .modal-content{max-height:calc(85vh - 24px)}
.dk-search{display:flex;align-items:center;gap:12px;padding:0 14px 0 18px;border-bottom:1px solid #262b37}
.dk-search:focus-within{box-shadow:inset 0 -2px 0 #22d3ee}
.dk-search>svg{width:20px;height:20px;flex:none;color:#8b93a5}
.dk-search .form-control{flex:1;min-width:0;height:58px;padding:0;border:0;border-radius:0;background:transparent;color:#e6e8ee;font-size:1.05rem;box-shadow:none}
.dk-search .form-control::placeholder{color:#7d869a}
.dk-esc{flex:none;min-height:28px;padding:2px 8px;border:1px solid #2e3441;border-bottom-width:2px;border-radius:6px;background:#1a1f29;color:#b4bccb;
  font:600 .72rem/1 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
.dk-esc:hover{color:#e6e8ee;border-color:#3d4453}
.dk-esc:focus-visible{outline:2px solid #22d3ee;outline-offset:2px}
.dk-palette .modal-body.dk-results{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:8px}
.dk-results:focus-visible{outline:2px solid #22d3ee;outline-offset:-2px}
.dk-group{padding:2px 0 6px}
.dk-group-title{margin:8px 10px 4px;color:#8b93a5;font-size:.7rem;font-weight:600;letter-spacing:.1em;line-height:1.55;text-transform:uppercase}
.dk-palette .list-group{--bs-list-group-bg:transparent;--bs-list-group-color:#d4d8e1;--bs-list-group-border-width:0;--bs-list-group-border-radius:10px;
  --bs-list-group-item-padding-x:10px;--bs-list-group-item-padding-y:7px;--bs-list-group-action-color:#d4d8e1;--bs-list-group-action-hover-color:#fff;
  --bs-list-group-action-hover-bg:#1a1f29;--bs-list-group-action-active-color:#fff;--bs-list-group-action-active-bg:#222834}
.dk-palette .dk-item{display:flex;align-items:center;gap:12px;min-height:44px;border-radius:10px;font-size:.92rem;line-height:1.3}
.dk-palette .dk-item:focus-visible{outline:2px solid #22d3ee;outline-offset:-2px}
.dk-ico{flex:none;display:grid;place-items:center;width:30px;height:30px;border:1px solid #2a303c;border-radius:8px;background:#171b24;color:#a78bfa}
.dk-ico svg{width:17px;height:17px}
.dk-ico.is-cyan{color:#67e8f9}
.dk-ico.is-amber{color:#fcd34d}
.dk-ico.is-pink{color:#f9a8d4}
.dk-name{flex:1;min-width:0}
.dk-empty{padding:32px 16px;color:#8b93a5;text-align:center}
.dk-empty span{color:#e6e8ee}
.dk-palette .modal-footer.dk-hints{justify-content:flex-start;gap:6px 18px;padding:10px 16px;color:#8b93a5;font-size:.78rem}
.dk-hints kbd{margin-right:2px}

/* 2. Revoke API key: a destructive confirmation */
.dk-glow{flex:none;display:grid;place-items:center;width:44px;height:44px;border-radius:12px;background:rgba(239,68,68,.12);color:#f87171;
  box-shadow:0 0 0 1px rgba(248,113,113,.3),0 0 32px -4px rgba(239,68,68,.6)}
.dk-glow svg{width:22px;height:22px}
.dk-keycard{margin-top:16px;padding:12px 14px;border:1px solid #262b37;border-radius:10px;background:#0e1117}
.dk-keycard code{color:#e6e8ee;font:600 .92rem/1.4 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
.dk .dk-keycard p{margin:4px 0 0;font-size:.8rem}
.dk-chip{--bs-badge-padding-x:8px;--bs-badge-padding-y:3px;--bs-badge-font-size:.7rem;--bs-badge-color:#fca5a5;border:1px solid rgba(248,113,113,.35);background:rgba(239,68,68,.1);letter-spacing:.04em;text-transform:uppercase}
.dk-warn{--bs-alert-bg:rgba(251,191,36,.07);--bs-alert-color:#fcd34d;--bs-alert-border-color:rgba(251,191,36,.28);--bs-alert-padding-x:12px;--bs-alert-padding-y:10px;
  --bs-alert-margin-bottom:0;--bs-alert-border-radius:10px;display:flex;align-items:flex-start;gap:10px;margin-top:12px;font-size:.85rem}
.dk-warn svg{width:18px;height:18px;flex:none;margin-top:1px}
.dk-warn b{color:#fde68a;font-weight:600}

/* 3. Upgrade plan: a gradient border, a CSS-only billing toggle */
.dk-plan{--bs-modal-width:440px;--bs-modal-border-color:transparent}
.dk-plan .modal-content{background:linear-gradient(#161a23,#12151c 160px) padding-box,linear-gradient(135deg,#8b5cf6,#22d3ee) border-box;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07),0 32px 90px -28px rgba(139,92,246,.55),0 24px 60px -24px rgba(0,0,0,.9)}
.dk-eyebrow{--bs-badge-padding-x:10px;--bs-badge-padding-y:4px;--bs-badge-font-size:.72rem;--bs-badge-color:#c4b5fd;display:inline-flex;align-items:center;gap:6px;margin:0 0 8px;padding-left:8px;
  border:1px solid rgba(167,139,250,.35);background:rgba(139,92,246,.12);letter-spacing:.06em;text-transform:uppercase}
.dk-eyebrow svg{width:14px;height:14px}
.dk-plan .modal-title{font-size:1.5rem;letter-spacing:-.02em}
.dk-seg{display:grid;grid-template-columns:1fr 1fr;gap:4px;min-width:0;margin:0;padding:4px;border:1px solid #262b37;border-radius:12px;background:#0e1117}
.dk-seg .btn{--bs-btn-padding-y:6px;--bs-btn-padding-x:10px;--bs-btn-font-size:.88rem;--bs-btn-font-weight:600;--bs-btn-border-radius:9px;--bs-btn-border-width:0;
  --bs-btn-color:#8b93a5;--bs-btn-hover-color:#e6e8ee;--bs-btn-active-bg:#1f2430;--bs-btn-active-color:#fff;
  display:flex;align-items:center;justify-content:center;gap:8px;min-height:38px}
.dk-seg .btn-check:checked+.btn{box-shadow:inset 0 0 0 1px rgba(139,92,246,.75),0 1px 2px rgba(0,0,0,.4)}
.dk-seg .btn-check:focus-visible+.btn{outline:2px solid #22d3ee;outline-offset:1px}
.dk-save{--bs-badge-padding-x:7px;--bs-badge-padding-y:2px;--bs-badge-font-size:.68rem;--bs-badge-color:#67e8f9;background:rgba(34,211,238,.12)}
.dk .modal-body .dk-price{margin-top:18px;color:#e6e8ee}
.dk-price>span{display:flex;align-items:baseline;flex-wrap:wrap;gap:4px 6px}
.dk-price b{font-size:2.5rem;font-weight:700;letter-spacing:-.03em;line-height:1}
.dk-price small{margin-left:4px;color:#8b93a5;font-size:.85rem}
.dk-price .is-yearly,.dk-plan:has(.btn-check[value="yearly"]:checked) .dk-price .is-monthly{display:none}
.dk-plan:has(.btn-check[value="yearly"]:checked) .dk-price .is-yearly{display:flex}
.dk-feats{display:grid;gap:10px;margin:18px 0 0;padding-top:18px;border-top:1px solid #262b37}
.dk-feats li{display:flex;align-items:center;gap:10px;color:#d4d8e1;font-size:.9rem}
.dk-feats svg{flex:none;width:20px;height:20px;padding:3px;border-radius:50%;background:rgba(34,211,238,.12);color:#22d3ee}
.dk-plan .dk-cta{min-height:46px;margin-top:22px;font-size:.95rem}
.dk .modal-body .dk-fine{margin-top:12px;font-size:.78rem;text-align:center}

@media (max-width:600px){
  .dk{--bs-modal-header-padding:24px 18px 4px}
  .dk-palette .modal-dialog{margin-top:10vh}
  .dk-palette .modal-content{max-height:calc(90vh - 16px)}
  .dk .modal-body{padding-left:18px;padding-right:18px}
  .dk .modal-footer{padding-left:18px;padding-right:18px}
  .dk .modal-footer .dk-btn{flex:1 1 auto}
  .dk-item .dk-keys{display:none}
}
@media (prefers-reduced-motion:reduce){.dk.fade .modal-dialog,.dk-btn,.dk-launch,.dk-seg .btn{transition:none}}
JavaScript
// Bootstrap ignores autofocus inside modals: honour it (the Cancel button of the confirmation)
document.querySelectorAll('.modal').forEach(function (m) {
  m.addEventListener('shown.bs.modal', function () { var a = m.querySelector('[autofocus]'); if (a) a.focus(); });
});

// Command palette: Ctrl+K / Cmd+K opens it from anywhere, typing filters the results,
// ArrowUp/ArrowDown move between visible results and Enter in the search box opens the first one.
(function () {
  var pal = document.getElementById('dk-palette');
  if (!pal || !window.bootstrap) return;
  var modal = bootstrap.Modal.getOrCreateInstance(pal);
  var input = document.getElementById('dk-palette-q');
  var empty = document.getElementById('dk-palette-empty');
  var count = document.getElementById('dk-palette-count');
  var items = [].slice.call(pal.querySelectorAll('[data-dk-item]'));
  var groups = [].slice.call(pal.querySelectorAll('[data-dk-group]'));
  var back = null;
  function shown() { return items.filter(function (el) { return !el.hidden; }); }

  function filter() {
    var q = input.value.trim().toLowerCase();
    items.forEach(function (el) { el.hidden = el.getAttribute('data-dk-item').toLowerCase().indexOf(q) === -1; });
    groups.forEach(function (g) { g.hidden = !g.querySelector('[data-dk-item]:not([hidden])'); });
    var n = shown().length;
    empty.hidden = n > 0;
    empty.querySelector('[data-dk-query]').textContent = input.value.trim();
    count.textContent = !q ? '' : n ? n + (n === 1 ? ' result' : ' results') : 'No results'; // read out by aria-live
  }
  input.addEventListener('input', filter);

  pal.addEventListener('show.bs.modal', function () { back = document.activeElement; });
  pal.addEventListener('shown.bs.modal', function () { input.focus(); });
  pal.addEventListener('hidden.bs.modal', function () {
    input.value = ''; filter(); // start fresh next time
    if (back && back !== document.body && back.focus) back.focus(); // also covers opening with Ctrl+K
  });

  pal.addEventListener('keydown', function (e) {
    var list = shown(), i = list.indexOf(document.activeElement);
    if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
      e.preventDefault();
      if (!list.length) return;
      if (e.key === 'ArrowDown') (list[i + 1] || list[0]).focus();
      else if (i <= 0) input.focus();
      else list[i - 1].focus();
    } else if (e.key === 'Enter' && e.target === input) {
      e.preventDefault();
      if (list[0]) list[0].click(); // open the top result
    } else if (i > -1 && e.key.length === 1 && e.key !== ' ' && !e.ctrlKey && !e.metaKey && !e.altKey) {
      input.focus(); // typing on a result goes back to the search box
    }
  });
  // Links close the palette without data-bs-dismiss, which would cancel their navigation
  items.forEach(function (el) { if (el.tagName === 'A') el.addEventListener('click', function () { modal.hide(); }); });

  document.addEventListener('keydown', function (e) {
    if (!(e.ctrlKey || e.metaKey) || e.key.toLowerCase() !== 'k') return;
    e.preventDefault();
    if (pal.classList.contains('show')) { input.focus(); return; }
    if (document.querySelector('.modal.show')) return; // another modal is already open
    modal.show();
  });
})();

Tailwind 4 code

Requires: Tailwind CSS 4

HTML
<svg width="0" height="0" style="position:absolute" aria-hidden="true" focusable="false">
  <symbol id="dk-i-search" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><circle cx="11" cy="11" r="6.5"/><path d="m16 16 4.5 4.5"/></symbol>
  <symbol id="dk-i-x" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M6.5 6.5l11 11M17.5 6.5l-11 11"/></symbol>
  <symbol id="dk-i-plus" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><path d="M12 5v14M5 12h14"/></symbol>
  <symbol id="dk-i-user" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="9.5" cy="8" r="3.5"/><path d="M3.5 19.5c.8-3.2 3.1-5 6-5s5.2 1.8 6 5M18.5 8v6M15.5 11h6"/></symbol>
  <symbol id="dk-i-sliders" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><path d="M4 7h9M18 7h2M4 17h3M12 17h8"/><circle cx="15.5" cy="7" r="2.5"/><circle cx="9.5" cy="17" r="2.5"/></symbol>
  <symbol id="dk-i-box" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"><path d="M4 7.5 12 3.5l8 4v9l-8 4-8-4z"/><path d="m4 7.5 8 4 8-4M12 11.5v9"/></symbol>
  <symbol id="dk-i-kbd" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><rect x="3" y="6" width="18" height="12" rx="2.5"/><path d="M7 10h.01M10.5 10h.01M14 10h.01M17 10h.01M8 14h8"/></symbol>
  <symbol id="dk-i-help" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><circle cx="12" cy="12" r="8.5"/><circle cx="12" cy="12" r="3.5"/><path d="m6 6 3.5 3.5M14.5 14.5 18 18M18 6l-3.5 3.5M9.5 14.5 6 18"/></symbol>
  <symbol id="dk-i-key" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="15.5" r="4"/><path d="m11 12.5 8.5-8.5M16 7l2.5 2.5M13.5 9.5l2 2"/></symbol>
  <symbol id="dk-i-warn" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 4 2.8 19.5h18.4z"/><path d="M12 10v4.5M12 17h.01"/></symbol>
  <symbol id="dk-i-check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="m5.5 12.5 4 4 9-9"/></symbol>
  <symbol id="dk-i-spark" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3.5l1.9 5.2 5.1 1.9-5.1 1.9L12 17.7l-1.9-5.2L5 10.6l5.1-1.9z"/><path d="M18.5 16v4M16.5 18h4"/></symbol>
</svg>
<div><span class="mb-3 block text-[.72rem] tracking-[.12em] text-[#8a93a6] uppercase">Command palette</span>
<div class="flex flex-wrap gap-2.5"><button class="flex min-h-[44px] w-full max-w-[300px] cursor-pointer items-center gap-2.5 rounded-[10px] border border-[#2e3441] bg-[#12151c] py-2 pr-2 pl-3 text-left text-[.9rem] text-[#9aa3b5] transition-[border-color,color] duration-150 hover:border-[#3d4453] hover:text-[#e6e8ee] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#22d3ee] motion-reduce:transition-none" type="button" data-open="dk-palette" aria-haspopup="dialog" aria-keyshortcuts="Control+K Meta+K"><svg class="size-[18px] flex-none" aria-hidden="true"><use href="#dk-i-search"/></svg><span class="flex-1">Search commands</span><span class="ml-auto flex flex-none gap-1" aria-hidden="true"><kbd class="min-w-[22px] rounded-md border border-b-2 border-[#2e3441] bg-[#1a1f29] px-1.5 py-px text-center font-mono text-[.7rem] leading-[1.6] font-semibold text-[#b4bccb]">Ctrl</kbd><kbd class="min-w-[22px] rounded-md border border-b-2 border-[#2e3441] bg-[#1a1f29] px-1.5 py-px text-center font-mono text-[.7rem] leading-[1.6] font-semibold text-[#b4bccb]">K</kbd></span></button></div></div>

<div><span class="mb-3 block text-[.72rem] tracking-[.12em] text-[#8a93a6] uppercase">Revoke API key</span>
<div class="flex flex-wrap gap-2.5"><button class="inline-flex min-h-[42px] cursor-pointer items-center justify-center gap-2 rounded-[10px] border px-4 py-[9px] text-[.9rem] leading-[1.2] font-semibold no-underline transition-[background-color,border-color,box-shadow,color] duration-150 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#22d3ee] motion-reduce:transition-none border-[#dc2626] bg-transparent text-[#fca5a5] hover:bg-[rgba(239,68,68,.12)] hover:text-[#fecaca]" type="button" data-open="dk-revoke" aria-haspopup="dialog">Revoke key</button></div></div>

<div><span class="mb-3 block text-[.72rem] tracking-[.12em] text-[#8a93a6] uppercase">Upgrade plan</span>
<div class="flex flex-wrap gap-2.5"><button class="inline-flex min-h-[42px] cursor-pointer items-center justify-center gap-2 rounded-[10px] border px-4 py-[9px] text-[.9rem] leading-[1.2] font-semibold no-underline transition-[background-color,border-color,box-shadow,color] duration-150 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#22d3ee] motion-reduce:transition-none border-transparent bg-[linear-gradient(135deg,#7c3aed,#4f46e5)] text-white shadow-[inset_0_1px_0_rgba(255,255,255,.2),0_10px_28px_-12px_rgba(139,92,246,.9)] hover:bg-[linear-gradient(135deg,#6d28d9,#4338ca)]" type="button" data-open="dk-upgrade" aria-haspopup="dialog"><svg class="size-[18px] flex-none" aria-hidden="true"><use href="#dk-i-spark"/></svg>Upgrade to Pro</button></div></div>

<!-- 1. Command palette -->
<dialog class="mx-auto mt-[15vh] mb-auto max-[600px]:mt-[10vh] max-h-[calc(85vh-24px)] max-[600px]:max-h-[calc(90vh-16px)] w-[min(640px,calc(100%-32px))] max-w-none overflow-hidden overscroll-contain rounded-2xl border border-[#262b37] bg-[#12151c] bg-[linear-gradient(rgba(255,255,255,.035),rgba(255,255,255,0)_140px)] p-0 text-[.95rem] leading-[1.55] text-[#e6e8ee] [color-scheme:dark] shadow-[inset_0_1px_0_rgba(255,255,255,.07),0_32px_80px_-24px_rgba(0,0,0,.9)] backdrop:bg-[rgba(3,4,8,.72)] backdrop:backdrop-blur-[6px] open:flex open:flex-col motion-safe:open:animate-[dk-in_.2s_cubic-bezier(.2,.8,.2,1)] motion-safe:open:backdrop:animate-[dk-fade_.2s_ease-out]" id="dk-palette" aria-labelledby="dk-palette-title">
  <form class="m-0 flex min-h-0 flex-1 flex-col" method="dialog">
    <h2 class="sr-only" id="dk-palette-title">Command palette</h2>
    <div class="flex items-center gap-3 border-b border-[#262b37] pr-3.5 pl-[18px] focus-within:shadow-[inset_0_-2px_0_#22d3ee]">
      <svg class="size-5 flex-none text-[#8b93a5]" aria-hidden="true"><use href="#dk-i-search"/></svg>
      <label class="sr-only" for="dk-palette-q">Search commands and projects</label>
      <input class="h-[58px] min-w-0 flex-1 border-0 bg-transparent p-0 text-[1.05rem] text-[#e6e8ee] outline-0 placeholder:text-[#7d869a]" id="dk-palette-q" type="text" placeholder="Type a command or search…" autocomplete="off" spellcheck="false" autofocus>
      <button class="min-h-7 flex-none cursor-pointer rounded-md border border-b-2 border-[#2e3441] bg-[#1a1f29] px-2 py-0.5 font-mono text-[.72rem] leading-none font-semibold text-[#b4bccb] hover:border-[#3d4453] hover:text-[#e6e8ee] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#22d3ee]" value="close" aria-label="Close (Esc)">Esc</button>
    </div>
    <div class="min-h-0 flex-auto overflow-y-auto overscroll-contain p-2 focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-[#22d3ee]" tabindex="0" role="region" aria-label="Results">
      <div class="pt-0.5 pb-1.5" role="group" aria-labelledby="dk-g-sugg" data-dk-group>
        <h3 class="mx-2.5 mt-2 mb-1 text-[.7rem] font-semibold tracking-[.1em] text-[#8b93a5] uppercase" id="dk-g-sugg">Suggestions</h3>
        <button class="flex min-h-[44px] w-full cursor-pointer items-center gap-3 rounded-[10px] border-0 bg-transparent px-2.5 py-[7px] text-left text-[.92rem] leading-[1.3] text-[#d4d8e1] no-underline hover:bg-[#1a1f29] hover:text-white focus-visible:bg-[#1a1f29] focus-visible:text-white focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-[#22d3ee]" value="new-project" data-dk-item="New project create"><span class="grid size-[30px] flex-none place-items-center rounded-lg border border-[#2a303c] bg-[#171b24] text-[#a78bfa]" aria-hidden="true"><svg class="size-[17px]"><use href="#dk-i-plus"/></svg></span><span class="min-w-0 flex-1">New project</span><span class="ml-auto flex flex-none gap-1 max-[600px]:hidden" aria-hidden="true"><kbd class="min-w-[22px] rounded-md border border-b-2 border-[#2e3441] bg-[#1a1f29] px-1.5 py-px text-center font-mono text-[.7rem] leading-[1.6] font-semibold text-[#b4bccb]">N</kbd></span></button>
        <button class="flex min-h-[44px] w-full cursor-pointer items-center gap-3 rounded-[10px] border-0 bg-transparent px-2.5 py-[7px] text-left text-[.92rem] leading-[1.3] text-[#d4d8e1] no-underline hover:bg-[#1a1f29] hover:text-white focus-visible:bg-[#1a1f29] focus-visible:text-white focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-[#22d3ee]" value="invite" data-dk-item="Invite teammate add member"><span class="grid size-[30px] flex-none place-items-center rounded-lg border border-[#2a303c] bg-[#171b24] text-[#a78bfa]" aria-hidden="true"><svg class="size-[17px]"><use href="#dk-i-user"/></svg></span><span class="min-w-0 flex-1">Invite teammate</span><span class="ml-auto flex flex-none gap-1 max-[600px]:hidden" aria-hidden="true"><kbd class="min-w-[22px] rounded-md border border-b-2 border-[#2e3441] bg-[#1a1f29] px-1.5 py-px text-center font-mono text-[.7rem] leading-[1.6] font-semibold text-[#b4bccb]">I</kbd></span></button>
        <button class="flex min-h-[44px] w-full cursor-pointer items-center gap-3 rounded-[10px] border-0 bg-transparent px-2.5 py-[7px] text-left text-[.92rem] leading-[1.3] text-[#d4d8e1] no-underline hover:bg-[#1a1f29] hover:text-white focus-visible:bg-[#1a1f29] focus-visible:text-white focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-[#22d3ee]" value="settings" data-dk-item="Open settings preferences"><span class="grid size-[30px] flex-none place-items-center rounded-lg border border-[#2a303c] bg-[#171b24] text-[#a78bfa]" aria-hidden="true"><svg class="size-[17px]"><use href="#dk-i-sliders"/></svg></span><span class="min-w-0 flex-1">Open settings</span><span class="ml-auto flex flex-none gap-1 max-[600px]:hidden" aria-hidden="true"><kbd class="min-w-[22px] rounded-md border border-b-2 border-[#2e3441] bg-[#1a1f29] px-1.5 py-px text-center font-mono text-[.7rem] leading-[1.6] font-semibold text-[#b4bccb]">Ctrl</kbd><kbd class="min-w-[22px] rounded-md border border-b-2 border-[#2e3441] bg-[#1a1f29] px-1.5 py-px text-center font-mono text-[.7rem] leading-[1.6] font-semibold text-[#b4bccb]">,</kbd></span></button>
      </div>
      <div class="pt-0.5 pb-1.5" role="group" aria-labelledby="dk-g-proj" data-dk-group>
        <h3 class="mx-2.5 mt-2 mb-1 text-[.7rem] font-semibold tracking-[.1em] text-[#8b93a5] uppercase" id="dk-g-proj">Projects</h3>
        <a class="flex min-h-[44px] w-full cursor-pointer items-center gap-3 rounded-[10px] border-0 bg-transparent px-2.5 py-[7px] text-left text-[.92rem] leading-[1.3] text-[#d4d8e1] no-underline hover:bg-[#1a1f29] hover:text-white focus-visible:bg-[#1a1f29] focus-visible:text-white focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-[#22d3ee]" href="#" data-dk-item="Aurora API project"><span class="grid size-[30px] flex-none place-items-center rounded-lg border border-[#2a303c] bg-[#171b24] text-[#67e8f9]" aria-hidden="true"><svg class="size-[17px]"><use href="#dk-i-box"/></svg></span><span class="min-w-0 flex-1">Aurora API</span><span class="ml-auto flex flex-none gap-1 max-[600px]:hidden" aria-hidden="true"><kbd class="min-w-[22px] rounded-md border border-b-2 border-[#2e3441] bg-[#1a1f29] px-1.5 py-px text-center font-mono text-[.7rem] leading-[1.6] font-semibold text-[#b4bccb]">G</kbd><kbd class="min-w-[22px] rounded-md border border-b-2 border-[#2e3441] bg-[#1a1f29] px-1.5 py-px text-center font-mono text-[.7rem] leading-[1.6] font-semibold text-[#b4bccb]">1</kbd></span></a>
        <a class="flex min-h-[44px] w-full cursor-pointer items-center gap-3 rounded-[10px] border-0 bg-transparent px-2.5 py-[7px] text-left text-[.92rem] leading-[1.3] text-[#d4d8e1] no-underline hover:bg-[#1a1f29] hover:text-white focus-visible:bg-[#1a1f29] focus-visible:text-white focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-[#22d3ee]" href="#" data-dk-item="Nimbus web project"><span class="grid size-[30px] flex-none place-items-center rounded-lg border border-[#2a303c] bg-[#171b24] text-[#f9a8d4]" aria-hidden="true"><svg class="size-[17px]"><use href="#dk-i-box"/></svg></span><span class="min-w-0 flex-1">Nimbus web</span><span class="ml-auto flex flex-none gap-1 max-[600px]:hidden" aria-hidden="true"><kbd class="min-w-[22px] rounded-md border border-b-2 border-[#2e3441] bg-[#1a1f29] px-1.5 py-px text-center font-mono text-[.7rem] leading-[1.6] font-semibold text-[#b4bccb]">G</kbd><kbd class="min-w-[22px] rounded-md border border-b-2 border-[#2e3441] bg-[#1a1f29] px-1.5 py-px text-center font-mono text-[.7rem] leading-[1.6] font-semibold text-[#b4bccb]">2</kbd></span></a>
        <a class="flex min-h-[44px] w-full cursor-pointer items-center gap-3 rounded-[10px] border-0 bg-transparent px-2.5 py-[7px] text-left text-[.92rem] leading-[1.3] text-[#d4d8e1] no-underline hover:bg-[#1a1f29] hover:text-white focus-visible:bg-[#1a1f29] focus-visible:text-white focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-[#22d3ee]" href="#" data-dk-item="Tidewater mobile project"><span class="grid size-[30px] flex-none place-items-center rounded-lg border border-[#2a303c] bg-[#171b24] text-[#fcd34d]" aria-hidden="true"><svg class="size-[17px]"><use href="#dk-i-box"/></svg></span><span class="min-w-0 flex-1">Tidewater mobile</span><span class="ml-auto flex flex-none gap-1 max-[600px]:hidden" aria-hidden="true"><kbd class="min-w-[22px] rounded-md border border-b-2 border-[#2e3441] bg-[#1a1f29] px-1.5 py-px text-center font-mono text-[.7rem] leading-[1.6] font-semibold text-[#b4bccb]">G</kbd><kbd class="min-w-[22px] rounded-md border border-b-2 border-[#2e3441] bg-[#1a1f29] px-1.5 py-px text-center font-mono text-[.7rem] leading-[1.6] font-semibold text-[#b4bccb]">3</kbd></span></a>
      </div>
      <div class="pt-0.5 pb-1.5" role="group" aria-labelledby="dk-g-help" data-dk-group>
        <h3 class="mx-2.5 mt-2 mb-1 text-[.7rem] font-semibold tracking-[.1em] text-[#8b93a5] uppercase" id="dk-g-help">Help</h3>
        <button class="flex min-h-[44px] w-full cursor-pointer items-center gap-3 rounded-[10px] border-0 bg-transparent px-2.5 py-[7px] text-left text-[.92rem] leading-[1.3] text-[#d4d8e1] no-underline hover:bg-[#1a1f29] hover:text-white focus-visible:bg-[#1a1f29] focus-visible:text-white focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-[#22d3ee]" value="shortcuts" data-dk-item="Keyboard shortcuts help"><span class="grid size-[30px] flex-none place-items-center rounded-lg border border-[#2a303c] bg-[#171b24] text-[#a78bfa]" aria-hidden="true"><svg class="size-[17px]"><use href="#dk-i-kbd"/></svg></span><span class="min-w-0 flex-1">Keyboard shortcuts</span><span class="ml-auto flex flex-none gap-1 max-[600px]:hidden" aria-hidden="true"><kbd class="min-w-[22px] rounded-md border border-b-2 border-[#2e3441] bg-[#1a1f29] px-1.5 py-px text-center font-mono text-[.7rem] leading-[1.6] font-semibold text-[#b4bccb]">?</kbd></span></button>
        <a class="flex min-h-[44px] w-full cursor-pointer items-center gap-3 rounded-[10px] border-0 bg-transparent px-2.5 py-[7px] text-left text-[.92rem] leading-[1.3] text-[#d4d8e1] no-underline hover:bg-[#1a1f29] hover:text-white focus-visible:bg-[#1a1f29] focus-visible:text-white focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-[#22d3ee]" href="#" data-dk-item="Contact support help"><span class="grid size-[30px] flex-none place-items-center rounded-lg border border-[#2a303c] bg-[#171b24] text-[#a78bfa]" aria-hidden="true"><svg class="size-[17px]"><use href="#dk-i-help"/></svg></span><span class="min-w-0 flex-1">Contact support</span><span class="ml-auto flex flex-none gap-1 max-[600px]:hidden" aria-hidden="true"><kbd class="min-w-[22px] rounded-md border border-b-2 border-[#2e3441] bg-[#1a1f29] px-1.5 py-px text-center font-mono text-[.7rem] leading-[1.6] font-semibold text-[#b4bccb]">Ctrl</kbd><kbd class="min-w-[22px] rounded-md border border-b-2 border-[#2e3441] bg-[#1a1f29] px-1.5 py-px text-center font-mono text-[.7rem] leading-[1.6] font-semibold text-[#b4bccb]">/</kbd></span></a>
      </div>
      <p class="m-0 px-4 py-8 text-center text-[#8b93a5]" id="dk-palette-empty" hidden>No results for “<span class="text-[#e6e8ee]" data-dk-query></span>”</p>
    </div>
    <p class="sr-only" id="dk-palette-count" aria-live="polite"></p>
    <div class="flex flex-wrap gap-x-[18px] gap-y-1.5 border-t border-[#262b37] bg-[#0e1117] px-4 py-2.5 text-[.78rem] text-[#8b93a5]"><span><kbd class="min-w-[22px] rounded-md border border-b-2 border-[#2e3441] bg-[#1a1f29] px-1.5 py-px text-center font-mono text-[.7rem] leading-[1.6] font-semibold text-[#b4bccb] mr-0.5">↑</kbd><kbd class="min-w-[22px] rounded-md border border-b-2 border-[#2e3441] bg-[#1a1f29] px-1.5 py-px text-center font-mono text-[.7rem] leading-[1.6] font-semibold text-[#b4bccb] mr-0.5">↓</kbd> to navigate</span><span><kbd class="min-w-[22px] rounded-md border border-b-2 border-[#2e3441] bg-[#1a1f29] px-1.5 py-px text-center font-mono text-[.7rem] leading-[1.6] font-semibold text-[#b4bccb] mr-0.5">Enter</kbd> to open</span><span><kbd class="min-w-[22px] rounded-md border border-b-2 border-[#2e3441] bg-[#1a1f29] px-1.5 py-px text-center font-mono text-[.7rem] leading-[1.6] font-semibold text-[#b4bccb] mr-0.5">Esc</kbd> to close</span></div>
  </form>
</dialog>

<!-- 2. Destructive confirmation -->
<dialog class="m-auto max-h-[calc(100dvh-56px)] max-[600px]:max-h-[calc(100dvh-32px)] w-[min(460px,calc(100%-32px))] max-w-none overflow-hidden overscroll-contain rounded-2xl border border-[#262b37] bg-[#12151c] bg-[linear-gradient(rgba(255,255,255,.035),rgba(255,255,255,0)_140px)] p-0 text-[.95rem] leading-[1.55] text-[#e6e8ee] [color-scheme:dark] shadow-[inset_0_1px_0_rgba(255,255,255,.07),0_32px_80px_-24px_rgba(0,0,0,.9)] backdrop:bg-[rgba(3,4,8,.72)] backdrop:backdrop-blur-[6px] open:flex open:flex-col motion-safe:open:animate-[dk-in_.2s_cubic-bezier(.2,.8,.2,1)] motion-safe:open:backdrop:animate-[dk-fade_.2s_ease-out]" id="dk-revoke" role="alertdialog" aria-labelledby="dk-revoke-title" aria-describedby="dk-revoke-desc">
  <form class="m-0 flex min-h-0 flex-1 flex-col" method="dialog">
    <div class="flex items-start gap-3.5 px-6 pt-6 pb-1 max-[600px]:px-[18px]">
      <span class="grid size-11 flex-none place-items-center rounded-xl bg-[rgba(239,68,68,.12)] text-[#f87171] shadow-[0_0_0_1px_rgba(248,113,113,.3),0_0_32px_-4px_rgba(239,68,68,.6)]" aria-hidden="true"><svg class="size-[22px]"><use href="#dk-i-key"/></svg></span>
      <div class="min-w-0 flex-1"><h2 class="m-0 text-[1.15rem] leading-[1.35] font-bold tracking-[-.01em]" id="dk-revoke-title">Revoke production key?</h2><p class="mt-1 mb-0 text-[.875rem] text-[#8b93a5]" id="dk-revoke-desc">Requests signed with this key will be rejected at once. This cannot be undone.</p></div>
    </div>
    <div class="min-h-0 flex-auto px-6 pt-3.5 pb-[22px] text-[#8b93a5] max-[600px]:px-[18px]">
      <div class="mt-4 rounded-[10px] border border-[#262b37] bg-[#0e1117] px-3.5 py-3">
        <div class="flex items-center justify-between gap-2.5"><code class="font-mono text-[.92rem] leading-[1.4] font-semibold text-[#e6e8ee]">sk_live_…4f2a</code><span class="flex-none rounded-full border border-[rgba(248,113,113,.35)] bg-[rgba(239,68,68,.1)] px-2 py-0.5 text-[.7rem] font-bold tracking-[.04em] text-[#fca5a5] uppercase">Live</span></div>
        <p class="mt-1 mb-0 text-[.8rem]">Created 12 Mar 2026 · Last used 3 hours ago</p>
      </div>
      <div class="mt-3 flex items-start gap-2.5 rounded-[10px] border border-[rgba(251,191,36,.28)] bg-[rgba(251,191,36,.07)] px-3 py-2.5 text-[.85rem] text-[#fcd34d]"><svg class="mt-px size-[18px] flex-none" aria-hidden="true"><use href="#dk-i-warn"/></svg><p class="m-0">2 services use this key: <b class="font-semibold text-[#fde68a]">billing-worker</b> and <b class="font-semibold text-[#fde68a]">webhooks-relay</b>. They will stop authenticating until you give them a new key.</p></div>
    </div>
    <div class="flex flex-wrap justify-end gap-2.5 border-t border-[#262b37] bg-[#0e1117] px-6 py-4 max-[600px]:px-[18px]">
      <button class="inline-flex min-h-[42px] cursor-pointer items-center justify-center gap-2 rounded-[10px] border px-4 py-[9px] text-[.9rem] leading-[1.2] font-semibold no-underline transition-[background-color,border-color,box-shadow,color] duration-150 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#22d3ee] motion-reduce:transition-none border-[#2e3441] bg-[#161a22] text-[#e6e8ee] hover:border-[#3d4453] hover:bg-[#1c212b] max-[600px]:flex-auto" value="cancel" autofocus>Cancel</button>
      <button class="inline-flex min-h-[42px] cursor-pointer items-center justify-center gap-2 rounded-[10px] border px-4 py-[9px] text-[.9rem] leading-[1.2] font-semibold no-underline transition-[background-color,border-color,box-shadow,color] duration-150 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#22d3ee] motion-reduce:transition-none border-[#dc2626] bg-[#dc2626] text-white shadow-[inset_0_1px_0_rgba(255,255,255,.18),0_10px_28px_-12px_rgba(239,68,68,.9)] hover:border-[#b91c1c] hover:bg-[#b91c1c] max-[600px]:flex-auto" value="revoke">Revoke key</button>
    </div>
  </form>
</dialog>

<!-- 3. Upgrade plan -->
<dialog class="group m-auto max-h-[calc(100dvh-56px)] max-[600px]:max-h-[calc(100dvh-32px)] w-[min(440px,calc(100%-32px))] max-w-none overflow-hidden overscroll-contain rounded-2xl border border-transparent [background:linear-gradient(#161a23,#12151c_160px)_padding-box,linear-gradient(135deg,#8b5cf6,#22d3ee)_border-box] p-0 text-[.95rem] leading-[1.55] text-[#e6e8ee] [color-scheme:dark] shadow-[inset_0_1px_0_rgba(255,255,255,.07),0_32px_90px_-28px_rgba(139,92,246,.55),0_24px_60px_-24px_rgba(0,0,0,.9)] backdrop:bg-[rgba(3,4,8,.72)] backdrop:backdrop-blur-[6px] open:flex open:flex-col motion-safe:open:animate-[dk-in_.2s_cubic-bezier(.2,.8,.2,1)] motion-safe:open:backdrop:animate-[dk-fade_.2s_ease-out]" id="dk-upgrade" aria-labelledby="dk-upgrade-title">
  <form class="m-0 flex min-h-0 flex-1 flex-col" method="dialog">
    <div class="flex items-start gap-3.5 px-6 pt-6 pb-1 max-[600px]:px-[18px]">
      <div class="min-w-0 flex-1"><p class="mt-0 mb-2 inline-flex items-center gap-1.5 rounded-full border border-[rgba(167,139,250,.35)] bg-[rgba(139,92,246,.12)] py-[3px] pr-2.5 pl-2 text-[.72rem] font-bold tracking-[.06em] text-[#c4b5fd] uppercase"><svg class="size-3.5" aria-hidden="true"><use href="#dk-i-spark"/></svg>Upgrade</p><h2 class="m-0 text-[1.5rem] leading-[1.35] font-bold tracking-[-.02em]" id="dk-upgrade-title">Nimbus Pro</h2><p class="mt-1 mb-0 text-[.875rem] text-[#8b93a5]">Everything in Team, with room for every project you ship.</p></div>
      <button class="-mt-1.5 -mr-2.5 grid size-9 flex-none cursor-pointer place-items-center rounded-[10px] border-0 bg-transparent p-0 text-[#8b93a5] transition-colors duration-150 hover:bg-[#1c212b] hover:text-[#e6e8ee] focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[#22d3ee] motion-reduce:transition-none" value="close" aria-label="Close"><svg class="size-5" aria-hidden="true"><use href="#dk-i-x"/></svg></button>
    </div>
    <div class="min-h-0 flex-auto px-6 pt-3.5 pb-[22px] text-[#8b93a5] max-[600px]:px-[18px]">
      <fieldset class="m-0 grid min-w-0 grid-cols-2 gap-1 rounded-xl border border-[#262b37] bg-[#0e1117] p-1">
        <legend class="sr-only">Billing period</legend>
        <input class="peer/m sr-only" type="radio" name="dk-billing" id="dk-bill-m" value="monthly" checked><label class="flex min-h-[38px] cursor-pointer items-center justify-center gap-2 rounded-[9px] px-2.5 py-1.5 text-[.88rem] font-semibold text-[#8b93a5] transition-colors duration-150 hover:text-[#e6e8ee] motion-reduce:transition-none peer-checked/m:bg-[#1f2430] peer-checked/m:text-white peer-checked/m:shadow-[inset_0_0_0_1px_rgba(139,92,246,.75),0_1px_2px_rgba(0,0,0,.4)] peer-focus-visible/m:outline-2 peer-focus-visible/m:outline-offset-1 peer-focus-visible/m:outline-[#22d3ee]" for="dk-bill-m">Monthly</label>
        <input class="peer/y sr-only" type="radio" name="dk-billing" id="dk-bill-y" value="yearly"><label class="flex min-h-[38px] cursor-pointer items-center justify-center gap-2 rounded-[9px] px-2.5 py-1.5 text-[.88rem] font-semibold text-[#8b93a5] transition-colors duration-150 hover:text-[#e6e8ee] motion-reduce:transition-none peer-checked/y:bg-[#1f2430] peer-checked/y:text-white peer-checked/y:shadow-[inset_0_0_0_1px_rgba(139,92,246,.75),0_1px_2px_rgba(0,0,0,.4)] peer-focus-visible/y:outline-2 peer-focus-visible/y:outline-offset-1 peer-focus-visible/y:outline-[#22d3ee]" for="dk-bill-y">Yearly <span class="rounded-full bg-[rgba(34,211,238,.12)] px-[7px] py-px text-[.68rem] font-bold whitespace-nowrap text-[#67e8f9]">2 months free</span></label>
      </fieldset>
      <p class="mt-[18px] mb-0 text-[#e6e8ee]" aria-live="polite">
        <span class="flex items-baseline flex-wrap gap-x-1.5 gap-y-1 group-has-[#dk-bill-y:checked]:hidden"><b class="text-[2.5rem] leading-none font-bold tracking-[-.03em]">£24</b>/mo <small class="ml-1 text-[.85rem] text-[#8b93a5]">billed monthly</small></span>
        <span class="hidden items-baseline flex-wrap gap-x-1.5 gap-y-1 group-has-[#dk-bill-y:checked]:flex"><b class="text-[2.5rem] leading-none font-bold tracking-[-.03em]">£20</b>/mo <small class="ml-1 text-[.85rem] text-[#8b93a5]">billed yearly at £240</small></span>
      </p>
      <ul class="mt-[18px] mb-0 grid list-none gap-2.5 border-t border-[#262b37] p-0 pt-[18px]">
        <li class="flex items-center gap-2.5 text-[.9rem] text-[#d4d8e1]"><svg class="size-5 flex-none rounded-full bg-[rgba(34,211,238,.12)] p-[3px] text-[#22d3ee]" aria-hidden="true"><use href="#dk-i-check"/></svg>Unlimited projects</li>
        <li class="flex items-center gap-2.5 text-[.9rem] text-[#d4d8e1]"><svg class="size-5 flex-none rounded-full bg-[rgba(34,211,238,.12)] p-[3px] text-[#22d3ee]" aria-hidden="true"><use href="#dk-i-check"/></svg>50 GB storage</li>
        <li class="flex items-center gap-2.5 text-[.9rem] text-[#d4d8e1]"><svg class="size-5 flex-none rounded-full bg-[rgba(34,211,238,.12)] p-[3px] text-[#22d3ee]" aria-hidden="true"><use href="#dk-i-check"/></svg>Priority support</li>
        <li class="flex items-center gap-2.5 text-[.9rem] text-[#d4d8e1]"><svg class="size-5 flex-none rounded-full bg-[rgba(34,211,238,.12)] p-[3px] text-[#22d3ee]" aria-hidden="true"><use href="#dk-i-check"/></svg>SSO & audit log</li>
      </ul>
      <div class="mt-[22px]"><button class="inline-flex min-h-[46px] cursor-pointer items-center justify-center gap-2 rounded-[10px] border px-4 py-[9px] text-[.95rem] leading-[1.2] font-semibold no-underline transition-[background-color,border-color,box-shadow,color] duration-150 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#22d3ee] motion-reduce:transition-none border-transparent bg-[linear-gradient(135deg,#7c3aed,#4f46e5)] text-white shadow-[inset_0_1px_0_rgba(255,255,255,.2),0_10px_28px_-12px_rgba(139,92,246,.9)] hover:bg-[linear-gradient(135deg,#6d28d9,#4338ca)] w-full" value="upgrade">Upgrade now</button></div>
      <p class="mt-3 mb-0 text-center text-[.78rem]">Prices exclude VAT. Cancel any time; Pro runs to the end of the period you paid for.</p>
    </div>
  </form>
</dialog>
CSS
/* Entrance keyframes for the dialogs and their backdrop (used through motion-safe:open:animate-[…]) */
@keyframes dk-in { from { opacity: 0; transform: translateY(8px) scale(.98); } }
@keyframes dk-fade { from { opacity: 0; } }
/* Stop the page scrolling behind an open modal */
html:has(dialog:modal) { overflow: hidden; }
JavaScript
// Open a dialog from any button with data-open="dialog-id". showModal() traps focus, closes on Esc
// and makes the page behind inert. Buttons inside <form method="dialog"> close it with no script.
document.querySelectorAll('[data-open]').forEach(function (btn) {
  var dialog = document.getElementById(btn.getAttribute('data-open'));
  if (!dialog) return;
  btn.addEventListener('click', function () {
    dialog.showModal();
    dialog.addEventListener('close', function () { btn.focus(); }, { once: true }); // focus back to the trigger
  });
  // A click on the backdrop lands on the <dialog> itself (its form fills the box), so close it
  dialog.addEventListener('click', function (e) { if (e.target === dialog) dialog.close(); });
});

// Command palette: Ctrl+K / Cmd+K opens it from anywhere, typing filters the results,
// ArrowUp/ArrowDown move between visible results and Enter in the search box opens the first one.
(function () {
  var pal = document.getElementById('dk-palette');
  if (!pal) return;
  var input = document.getElementById('dk-palette-q');
  var empty = document.getElementById('dk-palette-empty');
  var count = document.getElementById('dk-palette-count');
  var items = [].slice.call(pal.querySelectorAll('[data-dk-item]'));
  var groups = [].slice.call(pal.querySelectorAll('[data-dk-group]'));
  function shown() { return items.filter(function (el) { return !el.hidden; }); }

  function filter() {
    var q = input.value.trim().toLowerCase();
    items.forEach(function (el) { el.hidden = el.getAttribute('data-dk-item').toLowerCase().indexOf(q) === -1; });
    groups.forEach(function (g) { g.hidden = !g.querySelector('[data-dk-item]:not([hidden])'); });
    var n = shown().length;
    empty.hidden = n > 0;
    empty.querySelector('[data-dk-query]').textContent = input.value.trim();
    count.textContent = !q ? '' : n ? n + (n === 1 ? ' result' : ' results') : 'No results'; // read out by aria-live
  }
  input.addEventListener('input', filter);
  pal.addEventListener('close', function () { input.value = ''; filter(); }); // start fresh next time

  pal.addEventListener('keydown', function (e) {
    var list = shown(), i = list.indexOf(document.activeElement);
    if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
      e.preventDefault();
      if (!list.length) return;
      if (e.key === 'ArrowDown') (list[i + 1] || list[0]).focus();
      else if (i <= 0) input.focus();
      else list[i - 1].focus();
    } else if (e.key === 'Enter' && e.target === input) {
      e.preventDefault(); // do not submit the form; open the top result instead
      if (list[0]) list[0].click();
    } else if (i > -1 && e.key.length === 1 && e.key !== ' ' && !e.ctrlKey && !e.metaKey && !e.altKey) {
      input.focus(); // typing on a result goes back to the search box
    }
  });
  // Links do not close a dialog by themselves
  items.forEach(function (el) { if (el.tagName === 'A') el.addEventListener('click', function () { pal.close(); }); });

  document.addEventListener('keydown', function (e) {
    if (!(e.ctrlKey || e.metaKey) || e.key.toLowerCase() !== 'k') return;
    e.preventDefault();
    if (pal.open) { input.focus(); return; }
    if (document.querySelector('dialog:modal')) return; // another dialog is already open
    var back = document.activeElement;
    pal.showModal();
    pal.addEventListener('close', function () { if (back && back.focus) back.focus(); }, { once: true });
  });
})();

About this set

Three dark-theme dialogs for developer tools and SaaS dashboards: near-black panels with a hairline border, a soft top highlight, a cyan focus ring and a violet accent over a blurred backdrop. The Command palette opens from its trigger or with Ctrl+K or Cmd+K anywhere on the page and sits near the top of the screen. Typing filters grouped results (suggestions, projects, help), hides empty groups, shows a no-results message and announces the result count. The arrow keys move between results, and Enter opens the top result. Revoke API key is a destructive confirmation: an alertdialog with a red-glow icon, the masked key in monospace, created and last-used dates, a warning that two services depend on it, and Cancel focused first. Upgrade plan is a pricing card with a violet-to-cyan gradient border. Its monthly and yearly toggle uses real radio inputs and :has() to switch the price with no script, and a feature list and full-width call to action follow. The plain and Tailwind versions use the native dialog element and showModal(); the Bootstrap version uses the Modal plugin in its dark colour mode. The only script beyond the opener is the palette’s filtering and shortcut code.

What’s included

  • Command palette with Ctrl+K / Cmd+K, live filtering, grouped results and arrow-key navigation
  • Destructive alertdialog with a masked API key, usage details and a dependency warning
  • Pricing card with a gradient border and a CSS-only monthly/yearly price toggle
  • Near-black panels with hairline borders, a blurred backdrop and text contrast of 4.5:1 or better
  • Bootstrap version in Bootstrap 5.3's dark colour mode (data-bs-theme="dark")

Accessibility

Each dialog is named by its heading (a visually hidden one for the palette), the revoke confirmation is a role="alertdialog" described by its warning line, and the search box has a real label. Filtering updates a visually hidden aria-live count, the arrow keys move focus between visible results, the billing toggle is a fieldset of real radio inputs with a legend, and every control shows a cyan focus ring. Focus returns to the trigger, or to the element in use when Ctrl+K was pressed, and entrance animations are switched off under prefers-reduced-motion.

Customise it

In the plain version change --dk-bg, --dk-line, --dk-ink, --dk-muted, --dk-ring and --dk-w on .dk, and the gradient on .dk.is-plan. In Bootstrap change --bs-modal-bg, --bs-modal-border-color, --bs-modal-width and the --bs-btn-* and --bs-list-group-* variables. In Tailwind change the bg-[#12151c], border-[#262b37] and outline-[#22d3ee] classes.