Command Palette
Command palettes are power-user interfaces triggered by keyboard shortcuts (Cmd+K, Ctrl+K). They provide fast access to actions, navigation, search, and settings without leaving the keyboard. This guide covers production-ready command palette patterns in plain HTML/CSS, Tailwind CSS, and Bootstrap — including search, grouped results, recent actions, section tabs, inline bars, empty states, keyboard navigation, and accessibility.
info
A minimal command palette with a search input, scrollable results list, keyboard shortcut badges, and an ESC hint. The overlay backdrop focuses attention on the search and dismisses on click or Escape key. Click the trigger or press ⌘K / Ctrl+K to open it.
| 1 | <div class="cp-demo"> |
| 2 | <button class="cp-trigger" id="cp-open"> |
| 3 | <span class="cp-trigger-label"> |
| 4 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 5 | <circle cx="11" cy="11" r="8"/> |
| 6 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 7 | </svg> |
| 8 | Search commands... |
| 9 | </span> |
| 10 | <span class="cp-shortcut"> |
| 11 | ⌘K |
| 12 | </span> |
| 13 | </button> |
| 14 | <div class="cp-overlay" id="cp-overlay"> |
| 15 | <div class="cp-modal" role="dialog" aria-label="Command palette" aria-modal="true"> |
| 16 | <div class="cp-input-wrap"> |
| 17 | <svg class="cp-search-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 18 | <circle cx="11" cy="11" r="8"/> |
| 19 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 20 | </svg> |
| 21 | <input type="text" class="cp-input" placeholder="Type a command or search..." id="cp-input" autofocus /> |
| 22 | <span class="cp-esc"> |
| 23 | ESC |
| 24 | </span> |
| 25 | </div> |
| 26 | <div class="cp-results"> |
| 27 | <div class="cp-group"> |
| 28 | <span class="cp-group-label"> |
| 29 | Suggestions |
| 30 | </span> |
| 31 | <button class="cp-item active"> |
| 32 | <span class="cp-item-icon"> |
| 33 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 34 | <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/> |
| 35 | <polyline points="14 2 14 8 20 8"/> |
| 36 | <line x1="16" y1="13" x2="8" y2="13"/> |
| 37 | <line x1="16" y1="17" x2="8" y2="17"/> |
| 38 | <polyline points="10 9 9 9 8 9"/> |
| 39 | </svg> |
| 40 | </span> |
| 41 | <span class="cp-item-text"> |
| 42 | Create new document |
| 43 | </span> |
| 44 | <span class="cp-item-badge"> |
| 45 | ⌘N |
| 46 | </span> |
| 47 | </button> |
| 48 | <button class="cp-item"> |
| 49 | <span class="cp-item-icon"> |
| 50 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 51 | <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/> |
| 52 | </svg> |
| 53 | </span> |
| 54 | <span class="cp-item-text"> |
| 55 | Open project |
| 56 | </span> |
| 57 | <span class="cp-item-badge"> |
| 58 | ⌘O |
| 59 | </span> |
| 60 | </button> |
| 61 | <button class="cp-item"> |
| 62 | <span class="cp-item-icon"> |
| 63 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 64 | <circle cx="11" cy="11" r="8"/> |
| 65 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 66 | </svg> |
| 67 | </span> |
| 68 | <span class="cp-item-text"> |
| 69 | Search files |
| 70 | </span> |
| 71 | <span class="cp-item-badge"> |
| 72 | ⌘P |
| 73 | </span> |
| 74 | </button> |
| 75 | </div> |
| 76 | <div class="cp-group"> |
| 77 | <span class="cp-group-label"> |
| 78 | Actions |
| 79 | </span> |
| 80 | <button class="cp-item"> |
| 81 | <span class="cp-item-icon"> |
| 82 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 83 | <circle cx="12" cy="12" r="3"/> |
| 84 | <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/> |
| 85 | </svg> |
| 86 | </span> |
| 87 | <span class="cp-item-text"> |
| 88 | Open settings |
| 89 | </span> |
| 90 | <span class="cp-item-badge"> |
| 91 | ⌘, |
| 92 | </span> |
| 93 | </button> |
| 94 | <button class="cp-item"> |
| 95 | <span class="cp-item-icon"> |
| 96 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 97 | <circle cx="12" cy="12" r="5"/> |
| 98 | <path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/> |
| 99 | </svg> |
| 100 | </span> |
| 101 | <span class="cp-item-text"> |
| 102 | Toggle theme |
| 103 | </span> |
| 104 | <span class="cp-item-badge"> |
| 105 | ⌘D |
| 106 | </span> |
| 107 | </button> |
| 108 | <button class="cp-item"> |
| 109 | <span class="cp-item-icon"> |
| 110 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 111 | <path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/> |
| 112 | <rect x="8" y="2" width="8" height="4" rx="1" ry="1"/> |
| 113 | </svg> |
| 114 | </span> |
| 115 | <span class="cp-item-text"> |
| 116 | Show clipboard |
| 117 | </span> |
| 118 | <span class="cp-item-badge"> |
| 119 | ⌘V |
| 120 | </span> |
| 121 | </button> |
| 122 | </div> |
| 123 | </div> |
| 124 | </div> |
| 125 | </div> |
| 126 | </div> |
| 1 | .cp-demo { |
| 2 | position:relative; |
| 3 | padding:20px 24px; |
| 4 | font-family:system-ui, |
| 5 | sans-serif; |
| 6 | min-height:360px |
| 7 | } |
| 8 | .cp-trigger { |
| 9 | display:flex; |
| 10 | align-items:center; |
| 11 | justify-content:space-between; |
| 12 | width:100%; |
| 13 | max-width:420px; |
| 14 | margin:0 auto; |
| 15 | padding:12px 16px; |
| 16 | border-radius:10px; |
| 17 | border:1px solid #2A2A2A; |
| 18 | background:#111; |
| 19 | color:#808080; |
| 20 | font-size:13px; |
| 21 | font-family:system-ui, |
| 22 | sans-serif; |
| 23 | cursor:pointer; |
| 24 | transition:all .2s |
| 25 | } |
| 26 | .cp-trigger:hover { |
| 27 | border-color:#3A3A3A; |
| 28 | color:#A0A0A0 |
| 29 | } |
| 30 | .cp-trigger-label { |
| 31 | display:flex; |
| 32 | align-items:center; |
| 33 | gap:10px |
| 34 | } |
| 35 | .cp-shortcut { |
| 36 | font-size:11px; |
| 37 | background:rgba(255, |
| 38 | 255, |
| 39 | 255, |
| 40 | .06); |
| 41 | padding:2px 8px; |
| 42 | border-radius:4px; |
| 43 | border:1px solid #2A2A2A; |
| 44 | color:#666 |
| 45 | } |
| 46 | .cp-overlay { |
| 47 | display:none; |
| 48 | position:absolute; |
| 49 | inset:0; |
| 50 | background:rgba(0, |
| 51 | 0, |
| 52 | 0, |
| 53 | .5); |
| 54 | backdrop-filter:blur(4px); |
| 55 | align-items:flex-start; |
| 56 | justify-content:center; |
| 57 | padding-top:40px; |
| 58 | z-index:100 |
| 59 | } |
| 60 | .cp-overlay.open { |
| 61 | display:flex |
| 62 | } |
| 63 | .cp-modal { |
| 64 | width:100%; |
| 65 | max-width:460px; |
| 66 | background:#111; |
| 67 | border:1px solid #2A2A3E; |
| 68 | border-radius:12px; |
| 69 | overflow:hidden; |
| 70 | box-shadow:0 24px 64px rgba(0, |
| 71 | 0, |
| 72 | 0, |
| 73 | .6); |
| 74 | animation:cpIn .2s ease |
| 75 | } |
| 76 | @keyframes cpIn { |
| 77 | from { |
| 78 | opacity:0; |
| 79 | transform:scale(.96) translateY(-8px) |
| 80 | } |
| 81 | to { |
| 82 | opacity:1; |
| 83 | transform:scale(1) translateY(0) |
| 84 | } |
| 85 | } |
| 86 | .cp-input-wrap { |
| 87 | display:flex; |
| 88 | align-items:center; |
| 89 | gap:10px; |
| 90 | padding:14px 16px; |
| 91 | border-bottom:1px solid #222 |
| 92 | } |
| 93 | .cp-search-icon { |
| 94 | color:#666; |
| 95 | flex-shrink:0 |
| 96 | } |
| 97 | .cp-input { |
| 98 | flex:1; |
| 99 | background:transparent; |
| 100 | border:none; |
| 101 | color:#E0E0E0; |
| 102 | font-size:14px; |
| 103 | font-family:system-ui, |
| 104 | sans-serif; |
| 105 | outline:none |
| 106 | } |
| 107 | .cp-input::placeholder { |
| 108 | color:#555 |
| 109 | } |
| 110 | .cp-esc { |
| 111 | font-size:10px; |
| 112 | color:#555; |
| 113 | background:rgba(255, |
| 114 | 255, |
| 115 | 255, |
| 116 | .04); |
| 117 | padding:2px 6px; |
| 118 | border-radius:3px; |
| 119 | border:1px solid #222; |
| 120 | flex-shrink:0 |
| 121 | } |
| 122 | .cp-results { |
| 123 | max-height:300px; |
| 124 | overflow-y:auto; |
| 125 | padding:8px |
| 126 | } |
| 127 | .cp-group { |
| 128 | margin-bottom:4px |
| 129 | } |
| 130 | .cp-group-label { |
| 131 | display:block; |
| 132 | padding:6px 12px 4px; |
| 133 | font-size:10px; |
| 134 | color:#555; |
| 135 | text-transform:uppercase; |
| 136 | letter-spacing:.5px; |
| 137 | font-weight:600 |
| 138 | } |
| 139 | .cp-item { |
| 140 | display:flex; |
| 141 | align-items:center; |
| 142 | gap:10px; |
| 143 | width:100%; |
| 144 | padding:10px 12px; |
| 145 | border-radius:8px; |
| 146 | border:none; |
| 147 | background:transparent; |
| 148 | color:#A0A0A0; |
| 149 | font-size:13px; |
| 150 | font-family:system-ui, |
| 151 | sans-serif; |
| 152 | cursor:pointer; |
| 153 | text-align:left; |
| 154 | transition:background .1s |
| 155 | } |
| 156 | .cp-item:hover, |
| 157 | .cp-item.active { |
| 158 | background:rgba(255, |
| 159 | 255, |
| 160 | 255, |
| 161 | .05); |
| 162 | color:#E0E0E0 |
| 163 | } |
| 164 | .cp-item.active { |
| 165 | background:rgba(0, |
| 166 | 255, |
| 167 | 65, |
| 168 | .06) |
| 169 | } |
| 170 | .cp-item-icon { |
| 171 | display:flex; |
| 172 | align-items:center; |
| 173 | justify-content:center; |
| 174 | width:20px; |
| 175 | height:20px; |
| 176 | color:#666; |
| 177 | flex-shrink:0 |
| 178 | } |
| 179 | .cp-item-text { |
| 180 | flex:1 |
| 181 | } |
| 182 | .cp-item-badge { |
| 183 | font-size:10px; |
| 184 | color:#555; |
| 185 | background:rgba(255, |
| 186 | 255, |
| 187 | 255, |
| 188 | .04); |
| 189 | padding:2px 6px; |
| 190 | border-radius:3px; |
| 191 | border:1px solid #222; |
| 192 | flex-shrink:0 |
| 193 | } |
| 1 | const open=document.getElementById('cp-open'); |
| 2 | const overlay=document.getElementById('cp-overlay'); |
| 3 | const input=document.getElementById('cp-input'); |
| 4 | open.addEventListener('click',()=>{ |
| 5 | overlay.classList.add('open'); |
| 6 | setTimeout(()=>input.focus(),50); |
| 7 | }); |
| 8 | overlay.addEventListener('click',e=>{ |
| 9 | if(e.target===overlay)overlay.classList.remove('open'); |
| 10 | }); |
| 11 | document.addEventListener('keydown',e=>{ |
| 12 | if((e.metaKey||e.ctrlKey)&&e.key==='k'){ |
| 13 | e.preventDefault(); |
| 14 | overlay.classList.toggle('open'); |
| 15 | if(overlay.classList.contains('open'))setTimeout(()=>input.focus(),50); |
| 16 | } |
| 17 | if(e.key==='Escape')overlay.classList.remove('open'); |
| 18 | }); |
| 19 | const items=document.querySelectorAll('.cp-item'); |
| 20 | let idx=0; |
| 21 | function highlight(i){ |
| 22 | items.forEach((item,j)=>item.classList.toggle('active',j===i)); |
| 23 | idx=i; |
| 24 | } |
| 25 | document.addEventListener('keydown',e=>{ |
| 26 | if(!overlay.classList.contains('open'))return; |
| 27 | if(e.key==='ArrowDown'){e.preventDefault();highlight((idx+1)%items.length)} |
| 28 | if(e.key==='ArrowUp'){e.preventDefault();highlight((idx-1+items.length)%items.length)} |
| 29 | if(e.key==='Enter'){e.preventDefault();items[idx].click();overlay.classList.remove('open')} |
| 30 | }); |
| 31 | items.forEach((item,i)=>item.addEventListener('mouseenter',()=>highlight(i))) |
| 1 | <div class="relative p-6 font-sans min-h-[360px]"> |
| 2 | <button id="cp-open-tw" class="flex items-center justify-between w-full max-w-[420px] mx-auto px-4 py-3 rounded-[10px] border border-[#2A2A2A] bg-[#111] text-[#808080] text-[13px] hover:border-[#3A3A3A] hover:text-[#A0A0A0] transition-all"> |
| 3 | <span class="flex items-center gap-2.5"> |
| 4 | <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 5 | <circle cx="11" cy="11" r="8"/> |
| 6 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 7 | </svg> |
| 8 | Search commands... |
| 9 | </span> |
| 10 | <span class="text-[11px] bg-white/[0.06] px-2 py-0.5 rounded border border-[#2A2A2A] text-[#666]"> |
| 11 | ⌘K |
| 12 | </span> |
| 13 | </button> |
| 14 | <div id="cp-overlay-tw" class="hidden absolute inset-0 bg-black/50 backdrop-blur-sm items-start justify-center pt-10 z-50"> |
| 15 | <div role="dialog" aria-label="Command palette" aria-modal="true" class="w-full max-w-[460px] bg-[#111] border border-[#2A2A3E] rounded-xl overflow-hidden shadow-2xl animate-[cpIn_.2s_ease]"> |
| 16 | <div class="flex items-center gap-2.5 px-4 py-3.5 border-b border-[#222]"> |
| 17 | <svg class="w-4 h-4 text-[#666] flex-shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 18 | <circle cx="11" cy="11" r="8"/> |
| 19 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 20 | </svg> |
| 21 | <input id="cp-input-tw" type="text" class="flex-1 bg-transparent border-none text-[#E0E0E0] text-sm outline-none placeholder:text-[#555]" placeholder="Type a command or search..." autofocus /> |
| 22 | <span class="text-[10px] text-[#555] bg-white/[0.04] px-1.5 py-0.5 rounded border border-[#222] flex-shrink-0"> |
| 23 | ESC |
| 24 | </span> |
| 25 | </div> |
| 26 | <div class="max-h-[300px] overflow-y-auto p-2"> |
| 27 | <div class="mb-1"> |
| 28 | <span class="block px-3 py-1 text-[10px] text-[#555] uppercase tracking-wider font-semibold"> |
| 29 | Suggestions |
| 30 | </span> |
| 31 | <button class="cp-item-tw active flex items-center gap-2.5 w-full px-3 py-2.5 rounded-lg border-none bg-transparent text-[#A0A0A0] text-[13px] text-left transition-colors hover:bg-white/5"> |
| 32 | <span class="flex items-center justify-center w-5 h-5 text-[#666]"> |
| 33 | <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 34 | <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/> |
| 35 | <polyline points="14 2 14 8 20 8"/> |
| 36 | <line x1="16" y1="13" x2="8" y2="13"/> |
| 37 | <line x1="16" y1="17" x2="8" y2="17"/> |
| 38 | <polyline points="10 9 9 9 8 9"/> |
| 39 | </svg> |
| 40 | </span> |
| 41 | <span class="flex-1"> |
| 42 | Create new document |
| 43 | </span> |
| 44 | <span class="text-[10px] text-[#555] bg-white/[0.04] px-1.5 py-0.5 rounded border border-[#222] flex-shrink-0"> |
| 45 | ⌘N |
| 46 | </span> |
| 47 | </button> |
| 48 | <button class="cp-item-tw flex items-center gap-2.5 w-full px-3 py-2.5 rounded-lg border-none bg-transparent text-[#A0A0A0] text-[13px] text-left transition-colors hover:bg-white/5"> |
| 49 | <span class="flex items-center justify-center w-5 h-5 text-[#666]"> |
| 50 | <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 51 | <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/> |
| 52 | </svg> |
| 53 | </span> |
| 54 | <span class="flex-1"> |
| 55 | Open project |
| 56 | </span> |
| 57 | <span class="text-[10px] text-[#555] bg-white/[0.04] px-1.5 py-0.5 rounded border border-[#222] flex-shrink-0"> |
| 58 | ⌘O |
| 59 | </span> |
| 60 | </button> |
| 61 | <button class="cp-item-tw flex items-center gap-2.5 w-full px-3 py-2.5 rounded-lg border-none bg-transparent text-[#A0A0A0] text-[13px] text-left transition-colors hover:bg-white/5"> |
| 62 | <span class="flex items-center justify-center w-5 h-5 text-[#666]"> |
| 63 | <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 64 | <circle cx="11" cy="11" r="8"/> |
| 65 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 66 | </svg> |
| 67 | </span> |
| 68 | <span class="flex-1"> |
| 69 | Search files |
| 70 | </span> |
| 71 | <span class="text-[10px] text-[#555] bg-white/[0.04] px-1.5 py-0.5 rounded border border-[#222] flex-shrink-0"> |
| 72 | ⌘P |
| 73 | </span> |
| 74 | </button> |
| 75 | </div> |
| 76 | <div class="mb-1"> |
| 77 | <span class="block px-3 py-1 text-[10px] text-[#555] uppercase tracking-wider font-semibold"> |
| 78 | Actions |
| 79 | </span> |
| 80 | <button class="cp-item-tw flex items-center gap-2.5 w-full px-3 py-2.5 rounded-lg border-none bg-transparent text-[#A0A0A0] text-[13px] text-left transition-colors hover:bg-white/5"> |
| 81 | <span class="flex items-center justify-center w-5 h-5 text-[#666]"> |
| 82 | <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 83 | <circle cx="12" cy="12" r="3"/> |
| 84 | <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/> |
| 85 | </svg> |
| 86 | </span> |
| 87 | <span class="flex-1"> |
| 88 | Open settings |
| 89 | </span> |
| 90 | <span class="text-[10px] text-[#555] bg-white/[0.04] px-1.5 py-0.5 rounded border border-[#222] flex-shrink-0"> |
| 91 | ⌘, |
| 92 | </span> |
| 93 | </button> |
| 94 | <button class="cp-item-tw flex items-center gap-2.5 w-full px-3 py-2.5 rounded-lg border-none bg-transparent text-[#A0A0A0] text-[13px] text-left transition-colors hover:bg-white/5"> |
| 95 | <span class="flex items-center justify-center w-5 h-5 text-[#666]"> |
| 96 | <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 97 | <circle cx="12" cy="12" r="5"/> |
| 98 | <path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/> |
| 99 | </svg> |
| 100 | </span> |
| 101 | <span class="flex-1"> |
| 102 | Toggle theme |
| 103 | </span> |
| 104 | <span class="text-[10px] text-[#555] bg-white/[0.04] px-1.5 py-0.5 rounded border border-[#222] flex-shrink-0"> |
| 105 | ⌘D |
| 106 | </span> |
| 107 | </button> |
| 108 | <button class="cp-item-tw flex items-center gap-2.5 w-full px-3 py-2.5 rounded-lg border-none bg-transparent text-[#A0A0A0] text-[13px] text-left transition-colors hover:bg-white/5"> |
| 109 | <span class="flex items-center justify-center w-5 h-5 text-[#666]"> |
| 110 | <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 111 | <path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/> |
| 112 | <rect x="8" y="2" width="8" height="4" rx="1" ry="1"/> |
| 113 | </svg> |
| 114 | </span> |
| 115 | <span class="flex-1"> |
| 116 | Show clipboard |
| 117 | </span> |
| 118 | <span class="text-[10px] text-[#555] bg-white/[0.04] px-1.5 py-0.5 rounded border border-[#222] flex-shrink-0"> |
| 119 | ⌘V |
| 120 | </span> |
| 121 | </button> |
| 122 | </div> |
| 123 | </div> |
| 124 | </div> |
| 125 | </div> |
| 126 | </div> |
| 127 | <style> |
| 128 | @keyframes cpIn{from{opacity:0;transform:scale(.96) translateY(-8px)}to{opacity:1;transform:scale(1) translateY(0)}} .cp-item-tw.active{background:rgba(0,255,65,.06);color:#E0E0E0} |
| 129 | </style> |
| 1 | <div class="p-4 font-sans min-vh-50 position-relative"> |
| 2 | <button id="cp-open-bs" class="btn btn-dark d-flex align-items-center justify-content-between w-100 border-secondary" style="max-width:420px;margin:0 auto;padding:12px 16px;border-radius:10px;background:#111;color:#808080;font-size:13px"> |
| 3 | <span class="d-flex align-items-center gap-2"> |
| 4 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 5 | <circle cx="11" cy="11" r="8"/> |
| 6 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 7 | </svg> |
| 8 | Search commands... |
| 9 | </span> |
| 10 | <span class="badge border-secondary text-secondary fw-normal" style="background:rgba(255,255,255,.06);font-size:11px"> |
| 11 | ⌘K |
| 12 | </span> |
| 13 | </button> |
| 14 | <div id="cp-overlay-bs" class="d-none position-absolute start-0 end-0 top-0 bottom-0 align-items-start justify-content-center pt-5" style="background:rgba(0,0,0,.5);backdrop-filter:blur(4px);z-index:1000"> |
| 15 | <div role="dialog" aria-label="Command palette" aria-modal="true" class="card border-secondary bg-dark overflow-hidden" style="width:100%;max-width:460px;border-radius:12px;box-shadow:0 24px 64px rgba(0,0,0,.6)"> |
| 16 | <div class="card-header border-secondary bg-dark d-flex align-items-center gap-2 px-3 py-3"> |
| 17 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="text-secondary flex-shrink-0"> |
| 18 | <circle cx="11" cy="11" r="8"/> |
| 19 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 20 | </svg> |
| 21 | <input id="cp-input-bs" type="text" class="form-control border-0 bg-transparent text-light shadow-none px-0" placeholder="Type a command or search..." style="font-size:14px" autofocus /> |
| 22 | <span class="badge border-secondary text-secondary fw-normal flex-shrink-0" style="background:rgba(255,255,255,.04);font-size:10px"> |
| 23 | ESC |
| 24 | </span> |
| 25 | </div> |
| 26 | <div class="card-body p-2" style="max-height:300px;overflow-y:auto"> |
| 27 | <div class="mb-1"> |
| 28 | <span class="d-block px-3 py-1 text-uppercase fw-semibold" style="font-size:10px;color:#555"> |
| 29 | Suggestions |
| 30 | </span> |
| 31 | <button class="cp-item-bs active btn btn-dark text-start w-100 border-0 d-flex align-items-center gap-2 px-3 py-2" style="border-radius:8px;font-size:13px;color:#A0A0A0;background:transparent"> |
| 32 | <span class="d-flex align-items-center justify-content-center flex-shrink-0" style="width:20px;height:20px;color:#666"> |
| 33 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 34 | <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/> |
| 35 | <polyline points="14 2 14 8 20 8"/> |
| 36 | <line x1="16" y1="13" x2="8" y2="13"/> |
| 37 | <line x1="16" y1="17" x2="8" y2="17"/> |
| 38 | <polyline points="10 9 9 9 8 9"/> |
| 39 | </svg> |
| 40 | </span> |
| 41 | <span class="flex-fill"> |
| 42 | Create new document |
| 43 | </span> |
| 44 | <span class="badge border-secondary text-secondary fw-normal flex-shrink-0" style="background:rgba(255,255,255,.04);font-size:10px"> |
| 45 | ⌘N |
| 46 | </span> |
| 47 | </button> |
| 48 | <button class="cp-item-bs btn btn-dark text-start w-100 border-0 d-flex align-items-center gap-2 px-3 py-2" style="border-radius:8px;font-size:13px;color:#A0A0A0;background:transparent"> |
| 49 | <span class="d-flex align-items-center justify-content-center flex-shrink-0" style="width:20px;height:20px;color:#666"> |
| 50 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 51 | <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/> |
| 52 | </svg> |
| 53 | </span> |
| 54 | <span class="flex-fill"> |
| 55 | Open project |
| 56 | </span> |
| 57 | <span class="badge border-secondary text-secondary fw-normal flex-shrink-0" style="background:rgba(255,255,255,.04);font-size:10px"> |
| 58 | ⌘O |
| 59 | </span> |
| 60 | </button> |
| 61 | <button class="cp-item-bs btn btn-dark text-start w-100 border-0 d-flex align-items-center gap-2 px-3 py-2" style="border-radius:8px;font-size:13px;color:#A0A0A0;background:transparent"> |
| 62 | <span class="d-flex align-items-center justify-content-center flex-shrink-0" style="width:20px;height:20px;color:#666"> |
| 63 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 64 | <circle cx="11" cy="11" r="8"/> |
| 65 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 66 | </svg> |
| 67 | </span> |
| 68 | <span class="flex-fill"> |
| 69 | Search files |
| 70 | </span> |
| 71 | <span class="badge border-secondary text-secondary fw-normal flex-shrink-0" style="background:rgba(255,255,255,.04);font-size:10px"> |
| 72 | ⌘P |
| 73 | </span> |
| 74 | </button> |
| 75 | </div> |
| 76 | <div class="mb-1"> |
| 77 | <span class="d-block px-3 py-1 text-uppercase fw-semibold" style="font-size:10px;color:#555"> |
| 78 | Actions |
| 79 | </span> |
| 80 | <button class="cp-item-bs btn btn-dark text-start w-100 border-0 d-flex align-items-center gap-2 px-3 py-2" style="border-radius:8px;font-size:13px;color:#A0A0A0;background:transparent"> |
| 81 | <span class="d-flex align-items-center justify-content-center flex-shrink-0" style="width:20px;height:20px;color:#666"> |
| 82 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 83 | <circle cx="12" cy="12" r="3"/> |
| 84 | <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/> |
| 85 | </svg> |
| 86 | </span> |
| 87 | <span class="flex-fill"> |
| 88 | Open settings |
| 89 | </span> |
| 90 | <span class="badge border-secondary text-secondary fw-normal flex-shrink-0" style="background:rgba(255,255,255,.04);font-size:10px"> |
| 91 | ⌘, |
| 92 | </span> |
| 93 | </button> |
| 94 | <button class="cp-item-bs btn btn-dark text-start w-100 border-0 d-flex align-items-center gap-2 px-3 py-2" style="border-radius:8px;font-size:13px;color:#A0A0A0;background:transparent"> |
| 95 | <span class="d-flex align-items-center justify-content-center flex-shrink-0" style="width:20px;height:20px;color:#666"> |
| 96 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 97 | <circle cx="12" cy="12" r="5"/> |
| 98 | <path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/> |
| 99 | </svg> |
| 100 | </span> |
| 101 | <span class="flex-fill"> |
| 102 | Toggle theme |
| 103 | </span> |
| 104 | <span class="badge border-secondary text-secondary fw-normal flex-shrink-0" style="background:rgba(255,255,255,.04);font-size:10px"> |
| 105 | ⌘D |
| 106 | </span> |
| 107 | </button> |
| 108 | <button class="cp-item-bs btn btn-dark text-start w-100 border-0 d-flex align-items-center gap-2 px-3 py-2" style="border-radius:8px;font-size:13px;color:#A0A0A0;background:transparent"> |
| 109 | <span class="d-flex align-items-center justify-content-center flex-shrink-0" style="width:20px;height:20px;color:#666"> |
| 110 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 111 | <path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/> |
| 112 | <rect x="8" y="2" width="8" height="4" rx="1" ry="1"/> |
| 113 | </svg> |
| 114 | </span> |
| 115 | <span class="flex-fill"> |
| 116 | Show clipboard |
| 117 | </span> |
| 118 | <span class="badge border-secondary text-secondary fw-normal flex-shrink-0" style="background:rgba(255,255,255,.04);font-size:10px"> |
| 119 | ⌘V |
| 120 | </span> |
| 121 | </button> |
| 122 | </div> |
| 123 | </div> |
| 124 | </div> |
| 125 | </div> |
| 126 | </div> |
| 127 | <style> |
| 128 | .cp-item-bs.active{background:rgba(0,255,65,.06)!important;color:#E0E0E0!important}.cp-item-bs:hover:not(.active){background:rgba(255,255,255,.05)!important;color:#E0E0E0!important} |
| 129 | </style> |
Results organized by category with matched text highlighting. The search term "de" highlights matching substrings in green. Groups help users scan quickly and understand the type of each result.
| 1 | <div class="cpg-demo"> |
| 2 | <div class="cpg-modal"> |
| 3 | <div class="cpg-input-wrap"> |
| 4 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 5 | <circle cx="11" cy="11" r="8"/> |
| 6 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 7 | </svg> |
| 8 | <input type="text" class="cpg-input" value="de" readonly /> |
| 9 | <span class="cpg-count"> |
| 10 | 4 results |
| 11 | </span> |
| 12 | </div> |
| 13 | <div class="cpg-results"> |
| 14 | <div class="cpg-group"> |
| 15 | <span class="cpg-group-label"> |
| 16 | Navigation |
| 17 | </span> |
| 18 | <button class="cpg-item"> |
| 19 | <span class="cpg-icon" style="color:#3B82F6"> |
| 20 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 21 | <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/> |
| 22 | </svg> |
| 23 | </span> |
| 24 | <span class="cpg-text"> |
| 25 | Dashboard |
| 26 | </span> |
| 27 | <span class="cpg-desc"> |
| 28 | Main overview page |
| 29 | </span> |
| 30 | </button> |
| 31 | <button class="cpg-item active"> |
| 32 | <span class="cpg-icon" style="color:#3B82F6"> |
| 33 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 34 | <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/> |
| 35 | </svg> |
| 36 | </span> |
| 37 | <span class="cpg-text"> |
| 38 | <mark> |
| 39 | De |
| 40 | </mark> |
| 41 | ployments |
| 42 | </span> |
| 43 | <span class="cpg-desc"> |
| 44 | View all deployments |
| 45 | </span> |
| 46 | </button> |
| 47 | </div> |
| 48 | <div class="cpg-group"> |
| 49 | <span class="cpg-group-label"> |
| 50 | Actions |
| 51 | </span> |
| 52 | <button class="cpg-item"> |
| 53 | <span class="cpg-icon" style="color:#00FF41"> |
| 54 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 55 | <path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z"/> |
| 56 | <path d="M12 15l-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z"/> |
| 57 | <path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0"/> |
| 58 | <path d="M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"/> |
| 59 | </svg> |
| 60 | </span> |
| 61 | <span class="cpg-text"> |
| 62 | <mark> |
| 63 | De |
| 64 | </mark> |
| 65 | lete project |
| 66 | </span> |
| 67 | <span class="cpg-desc"> |
| 68 | Permanently remove |
| 69 | </span> |
| 70 | </button> |
| 71 | <button class="cpg-item"> |
| 72 | <span class="cpg-icon" style="color:#F97316"> |
| 73 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 74 | <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/> |
| 75 | <line x1="12" y1="9" x2="12" y2="13"/> |
| 76 | <line x1="12" y1="17" x2="12.01" y2="17"/> |
| 77 | </svg> |
| 78 | </span> |
| 79 | <span class="cpg-text"> |
| 80 | <mark> |
| 81 | De |
| 82 | </mark> |
| 83 | activate env |
| 84 | </span> |
| 85 | <span class="cpg-desc"> |
| 86 | Disable environment |
| 87 | </span> |
| 88 | </button> |
| 89 | </div> |
| 90 | </div> |
| 91 | </div> |
| 92 | </div> |
| 1 | .cpg-demo { |
| 2 | padding:20px 24px; |
| 3 | font-family:system-ui, |
| 4 | sans-serif; |
| 5 | min-height:360px; |
| 6 | display:flex; |
| 7 | justify-content:center |
| 8 | } |
| 9 | .cpg-modal { |
| 10 | width:100%; |
| 11 | max-width:480px; |
| 12 | background:#111; |
| 13 | border:1px solid #2A2A3E; |
| 14 | border-radius:12px; |
| 15 | overflow:hidden; |
| 16 | box-shadow:0 24px 64px rgba(0, |
| 17 | 0, |
| 18 | 0, |
| 19 | .6) |
| 20 | } |
| 21 | .cpg-input-wrap { |
| 22 | display:flex; |
| 23 | align-items:center; |
| 24 | gap:10px; |
| 25 | padding:14px 16px; |
| 26 | border-bottom:1px solid #222 |
| 27 | } |
| 28 | .cpg-input-wrap svg { |
| 29 | color:#666; |
| 30 | flex-shrink:0 |
| 31 | } |
| 32 | .cpg-input { |
| 33 | flex:1; |
| 34 | background:transparent; |
| 35 | border:none; |
| 36 | color:#E0E0E0; |
| 37 | font-size:14px; |
| 38 | font-family:system-ui, |
| 39 | sans-serif; |
| 40 | outline:none |
| 41 | } |
| 42 | .cpg-input::placeholder { |
| 43 | color:#555 |
| 44 | } |
| 45 | .cpg-count { |
| 46 | font-size:11px; |
| 47 | color:#555; |
| 48 | flex-shrink:0 |
| 49 | } |
| 50 | .cpg-results { |
| 51 | max-height:320px; |
| 52 | overflow-y:auto; |
| 53 | padding:8px |
| 54 | } |
| 55 | .cpg-group { |
| 56 | margin-bottom:4px |
| 57 | } |
| 58 | .cpg-group-label { |
| 59 | display:block; |
| 60 | padding:8px 12px 4px; |
| 61 | font-size:10px; |
| 62 | color:#555; |
| 63 | text-transform:uppercase; |
| 64 | letter-spacing:.5px; |
| 65 | font-weight:600 |
| 66 | } |
| 67 | .cpg-item { |
| 68 | display:flex; |
| 69 | align-items:center; |
| 70 | gap:10px; |
| 71 | width:100%; |
| 72 | padding:10px 12px; |
| 73 | border-radius:8px; |
| 74 | border:none; |
| 75 | background:transparent; |
| 76 | color:#A0A0A0; |
| 77 | font-size:13px; |
| 78 | font-family:system-ui, |
| 79 | sans-serif; |
| 80 | cursor:pointer; |
| 81 | text-align:left; |
| 82 | transition:background .1s |
| 83 | } |
| 84 | .cpg-item:hover, |
| 85 | .cpg-item.active { |
| 86 | background:rgba(255, |
| 87 | 255, |
| 88 | 255, |
| 89 | .05); |
| 90 | color:#E0E0E0 |
| 91 | } |
| 92 | .cpg-item.active { |
| 93 | background:rgba(0, |
| 94 | 255, |
| 95 | 65, |
| 96 | .06) |
| 97 | } |
| 98 | .cpg-icon { |
| 99 | display:flex; |
| 100 | align-items:center; |
| 101 | justify-content:center; |
| 102 | width:20px; |
| 103 | height:20px; |
| 104 | flex-shrink:0 |
| 105 | } |
| 106 | .cpg-text { |
| 107 | flex:1 |
| 108 | } |
| 109 | .cpg-text mark { |
| 110 | background:rgba(0, |
| 111 | 255, |
| 112 | 65, |
| 113 | .2); |
| 114 | color:#00FF41; |
| 115 | border-radius:2px; |
| 116 | padding:0 1px |
| 117 | } |
| 118 | .cpg-desc { |
| 119 | font-size:11px; |
| 120 | color:#555; |
| 121 | flex-shrink:0 |
| 122 | } |
| 1 | <div class="p-6 font-sans min-h-[360px] flex justify-center bg-[#0A0A0A]"> |
| 2 | <div class="w-full max-w-[480px] bg-[#111] border border-[#2A2A3E] rounded-xl overflow-hidden shadow-2xl"> |
| 3 | <div class="flex items-center gap-2.5 px-4 py-3.5 border-b border-[#222]"> |
| 4 | <svg class="w-4 h-4 text-[#666] flex-shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 5 | <circle cx="11" cy="11" r="8"/> |
| 6 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 7 | </svg> |
| 8 | <input type="text" value="de" readonly class="flex-1 bg-transparent border-none text-[#E0E0E0] text-sm outline-none" /> |
| 9 | <span class="text-[11px] text-[#555] flex-shrink-0"> |
| 10 | 4 results |
| 11 | </span> |
| 12 | </div> |
| 13 | <div class="max-h-[320px] overflow-y-auto p-2"> |
| 14 | <div class="mb-1"> |
| 15 | <span class="block px-3 py-1 text-[10px] text-[#555] uppercase tracking-wider font-semibold"> |
| 16 | Navigation |
| 17 | </span> |
| 18 | <button class="flex items-center gap-2.5 w-full px-3 py-2.5 rounded-lg border-none bg-transparent text-[#A0A0A0] text-[13px] text-left hover:bg-white/5 transition-colors"> |
| 19 | <span class="flex items-center justify-center w-5 h-5 text-[#3B82F6] flex-shrink-0"> |
| 20 | <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 21 | <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/> |
| 22 | </svg> |
| 23 | </span> |
| 24 | <span class="flex-1"> |
| 25 | Dashboard |
| 26 | </span> |
| 27 | <span class="text-[11px] text-[#555] flex-shrink-0"> |
| 28 | Main overview page |
| 29 | </span> |
| 30 | </button> |
| 31 | <button class="flex items-center gap-2.5 w-full px-3 py-2.5 rounded-lg border-none bg-[rgba(0,255,65,0.06)] text-[#E0E0E0] text-[13px] text-left transition-colors"> |
| 32 | <span class="flex items-center justify-center w-5 h-5 text-[#3B82F6] flex-shrink-0"> |
| 33 | <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 34 | <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/> |
| 35 | </svg> |
| 36 | </span> |
| 37 | <span class="flex-1"> |
| 38 | <mark class="bg-[rgba(0,255,65,0.2)] text-[#00FF41] rounded px-0.5"> |
| 39 | De |
| 40 | </mark> |
| 41 | ployments |
| 42 | </span> |
| 43 | <span class="text-[11px] text-[#555] flex-shrink-0"> |
| 44 | View all deployments |
| 45 | </span> |
| 46 | </button> |
| 47 | </div> |
| 48 | <div class="mb-1"> |
| 49 | <span class="block px-3 py-1 text-[10px] text-[#555] uppercase tracking-wider font-semibold"> |
| 50 | Actions |
| 51 | </span> |
| 52 | <button class="flex items-center gap-2.5 w-full px-3 py-2.5 rounded-lg border-none bg-transparent text-[#A0A0A0] text-[13px] text-left hover:bg-white/5 transition-colors"> |
| 53 | <span class="flex items-center justify-center w-5 h-5 text-[#00FF41] flex-shrink-0"> |
| 54 | <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 55 | <path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z"/> |
| 56 | <path d="M12 15l-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z"/> |
| 57 | <path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0"/> |
| 58 | <path d="M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"/> |
| 59 | </svg> |
| 60 | </span> |
| 61 | <span class="flex-1"> |
| 62 | <mark class="bg-[rgba(0,255,65,0.2)] text-[#00FF41] rounded px-0.5"> |
| 63 | De |
| 64 | </mark> |
| 65 | lete project |
| 66 | </span> |
| 67 | <span class="text-[11px] text-[#555] flex-shrink-0"> |
| 68 | Permanently remove |
| 69 | </span> |
| 70 | </button> |
| 71 | <button class="flex items-center gap-2.5 w-full px-3 py-2.5 rounded-lg border-none bg-transparent text-[#A0A0A0] text-[13px] text-left hover:bg-white/5 transition-colors"> |
| 72 | <span class="flex items-center justify-center w-5 h-5 text-[#F97316] flex-shrink-0"> |
| 73 | <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 74 | <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/> |
| 75 | <line x1="12" y1="9" x2="12" y2="13"/> |
| 76 | <line x1="12" y1="17" x2="12.01" y2="17"/> |
| 77 | </svg> |
| 78 | </span> |
| 79 | <span class="flex-1"> |
| 80 | <mark class="bg-[rgba(0,255,65,0.2)] text-[#00FF41] rounded px-0.5"> |
| 81 | De |
| 82 | </mark> |
| 83 | activate env |
| 84 | </span> |
| 85 | <span class="text-[11px] text-[#555] flex-shrink-0"> |
| 86 | Disable environment |
| 87 | </span> |
| 88 | </button> |
| 89 | </div> |
| 90 | </div> |
| 91 | </div> |
| 92 | </div> |
| 1 | <div class="p-4 font-sans min-vh-50 d-flex justify-content-center bg-dark"> |
| 2 | <div class="card border-secondary bg-dark overflow-hidden" style="width:100%;max-width:480px;border-radius:12px;box-shadow:0 24px 64px rgba(0,0,0,.6)"> |
| 3 | <div class="card-header border-secondary bg-dark d-flex align-items-center gap-2 px-3 py-3"> |
| 4 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="text-secondary flex-shrink-0"> |
| 5 | <circle cx="11" cy="11" r="8"/> |
| 6 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 7 | </svg> |
| 8 | <input type="text" value="de" readonly class="form-control border-0 bg-transparent text-light shadow-none px-0" style="font-size:14px" /> |
| 9 | <span class="text-secondary flex-shrink-0" style="font-size:11px"> |
| 10 | 4 results |
| 11 | </span> |
| 12 | </div> |
| 13 | <div class="card-body p-2" style="max-height:320px;overflow-y:auto"> |
| 14 | <div class="mb-1"> |
| 15 | <span class="d-block px-3 py-1 text-uppercase fw-semibold" style="font-size:10px;color:#555"> |
| 16 | Navigation |
| 17 | </span> |
| 18 | <button class="btn btn-dark text-start w-100 border-0 d-flex align-items-center gap-2 px-3 py-2" style="border-radius:8px;font-size:13px;color:#A0A0A0;background:transparent"> |
| 19 | <span class="d-flex align-items-center justify-content-center flex-shrink-0" style="width:20px;height:20px;color:#3B82F6"> |
| 20 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 21 | <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/> |
| 22 | </svg> |
| 23 | </span> |
| 24 | <span class="flex-fill"> |
| 25 | Dashboard |
| 26 | </span> |
| 27 | <span class="flex-shrink-0" style="font-size:11px;color:#555"> |
| 28 | Main overview page |
| 29 | </span> |
| 30 | </button> |
| 31 | <button class="btn btn-dark text-start w-100 border-0 d-flex align-items-center gap-2 px-3 py-2" style="border-radius:8px;font-size:13px;color:#E0E0E0;background:rgba(0,255,65,.06)"> |
| 32 | <span class="d-flex align-items-center justify-content-center flex-shrink-0" style="width:20px;height:20px;color:#3B82F6"> |
| 33 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 34 | <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/> |
| 35 | </svg> |
| 36 | </span> |
| 37 | <span class="flex-fill"> |
| 38 | <mark style="background:rgba(0,255,65,.2);color:#00FF41;border-radius:2px;padding:0 2px"> |
| 39 | De |
| 40 | </mark> |
| 41 | ployments |
| 42 | </span> |
| 43 | <span class="flex-shrink-0" style="font-size:11px;color:#555"> |
| 44 | View all deployments |
| 45 | </span> |
| 46 | </button> |
| 47 | </div> |
| 48 | <div class="mb-1"> |
| 49 | <span class="d-block px-3 py-1 text-uppercase fw-semibold" style="font-size:10px;color:#555"> |
| 50 | Actions |
| 51 | </span> |
| 52 | <button class="btn btn-dark text-start w-100 border-0 d-flex align-items-center gap-2 px-3 py-2" style="border-radius:8px;font-size:13px;color:#A0A0A0;background:transparent"> |
| 53 | <span class="d-flex align-items-center justify-content-center flex-shrink-0" style="width:20px;height:20px;color:#00FF41"> |
| 54 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 55 | <path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z"/> |
| 56 | <path d="M12 15l-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z"/> |
| 57 | <path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0"/> |
| 58 | <path d="M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"/> |
| 59 | </svg> |
| 60 | </span> |
| 61 | <span class="flex-fill"> |
| 62 | <mark style="background:rgba(0,255,65,.2);color:#00FF41;border-radius:2px;padding:0 2px"> |
| 63 | De |
| 64 | </mark> |
| 65 | lete project |
| 66 | </span> |
| 67 | <span class="flex-shrink-0" style="font-size:11px;color:#555"> |
| 68 | Permanently remove |
| 69 | </span> |
| 70 | </button> |
| 71 | <button class="btn btn-dark text-start w-100 border-0 d-flex align-items-center gap-2 px-3 py-2" style="border-radius:8px;font-size:13px;color:#A0A0A0;background:transparent"> |
| 72 | <span class="d-flex align-items-center justify-content-center flex-shrink-0" style="width:20px;height:20px;color:#F97316"> |
| 73 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 74 | <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/> |
| 75 | <line x1="12" y1="9" x2="12" y2="13"/> |
| 76 | <line x1="12" y1="17" x2="12.01" y2="17"/> |
| 77 | </svg> |
| 78 | </span> |
| 79 | <span class="flex-fill"> |
| 80 | <mark style="background:rgba(0,255,65,.2);color:#00FF41;border-radius:2px;padding:0 2px"> |
| 81 | De |
| 82 | </mark> |
| 83 | activate env |
| 84 | </span> |
| 85 | <span class="flex-shrink-0" style="font-size:11px;color:#555"> |
| 86 | Disable environment |
| 87 | </span> |
| 88 | </button> |
| 89 | </div> |
| 90 | </div> |
| 91 | </div> |
| 92 | </div> |
Showing recently used actions at the top of an empty search helps repeat workflows faster. Recent items fade as the user types to filter. Time-since labels reinforce recency.
| 1 | <div class="cpr-demo"> |
| 2 | <div class="cpr-modal"> |
| 3 | <div class="cpr-input-wrap"> |
| 4 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 5 | <circle cx="11" cy="11" r="8"/> |
| 6 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 7 | </svg> |
| 8 | <input type="text" class="cpr-input" placeholder="Type a command..." /> |
| 9 | <span class="cpr-esc"> |
| 10 | ESC |
| 11 | </span> |
| 12 | </div> |
| 13 | <div class="cpr-results"> |
| 14 | <div class="cpr-group"> |
| 15 | <span class="cpr-group-label"> |
| 16 | <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 17 | <circle cx="12" cy="12" r="10"/> |
| 18 | <polyline points="12 6 12 12 16 14"/> |
| 19 | </svg> |
| 20 | Recent |
| 21 | </span> |
| 22 | <button class="cpr-item"> |
| 23 | <span class="cpr-icon"> |
| 24 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 25 | <path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z"/> |
| 26 | <path d="M12 15l-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z"/> |
| 27 | <path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0"/> |
| 28 | <path d="M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"/> |
| 29 | </svg> |
| 30 | </span> |
| 31 | <span class="cpr-text"> |
| 32 | Deploy to production |
| 33 | </span> |
| 34 | <span class="cpr-time"> |
| 35 | 2m ago |
| 36 | </span> |
| 37 | </button> |
| 38 | <button class="cpr-item"> |
| 39 | <span class="cpr-icon"> |
| 40 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 41 | <polyline points="23 4 23 10 17 10"/> |
| 42 | <path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"/> |
| 43 | </svg> |
| 44 | </span> |
| 45 | <span class="cpr-text"> |
| 46 | Restart dev server |
| 47 | </span> |
| 48 | <span class="cpr-time"> |
| 49 | 15m ago |
| 50 | </span> |
| 51 | </button> |
| 52 | <button class="cpr-item"> |
| 53 | <span class="cpr-icon"> |
| 54 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 55 | <line x1="16.5" y1="9.4" x2="7.5" y2="4.21"/> |
| 56 | <path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/> |
| 57 | <polyline points="3.27 6.96 12 12.01 20.73 6.96"/> |
| 58 | <line x1="12" y1="22.08" x2="12" y2="12"/> |
| 59 | </svg> |
| 60 | </span> |
| 61 | <span class="cpr-text"> |
| 62 | Build for staging |
| 63 | </span> |
| 64 | <span class="cpr-time"> |
| 65 | 1h ago |
| 66 | </span> |
| 67 | </button> |
| 68 | </div> |
| 69 | <div class="cpr-divider"> |
| 70 | </div> |
| 71 | <div class="cpr-group"> |
| 72 | <span class="cpr-group-label"> |
| 73 | All Commands |
| 74 | </span> |
| 75 | <button class="cpr-item"> |
| 76 | <span class="cpr-icon"> |
| 77 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 78 | <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/> |
| 79 | <polyline points="14 2 14 8 20 8"/> |
| 80 | <line x1="16" y1="13" x2="8" y2="13"/> |
| 81 | <line x1="16" y1="17" x2="8" y2="17"/> |
| 82 | <polyline points="10 9 9 9 8 9"/> |
| 83 | </svg> |
| 84 | </span> |
| 85 | <span class="cpr-text"> |
| 86 | New file |
| 87 | </span> |
| 88 | <span class="cpr-key"> |
| 89 | ⌘N |
| 90 | </span> |
| 91 | </button> |
| 92 | <button class="cpr-item"> |
| 93 | <span class="cpr-icon"> |
| 94 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 95 | <path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/> |
| 96 | <polyline points="17 21 17 13 7 13 7 21"/> |
| 97 | <polyline points="7 3 7 8 15 8"/> |
| 98 | </svg> |
| 99 | </span> |
| 100 | <span class="cpr-text"> |
| 101 | Save all |
| 102 | </span> |
| 103 | <span class="cpr-key"> |
| 104 | ⌘S |
| 105 | </span> |
| 106 | </button> |
| 107 | <button class="cpr-item"> |
| 108 | <span class="cpr-icon"> |
| 109 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 110 | <circle cx="11" cy="11" r="8"/> |
| 111 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 112 | </svg> |
| 113 | </span> |
| 114 | <span class="cpr-text"> |
| 115 | Find in files |
| 116 | </span> |
| 117 | <span class="cpr-key"> |
| 118 | ⌘F |
| 119 | </span> |
| 120 | </button> |
| 121 | <button class="cpr-item"> |
| 122 | <span class="cpr-icon"> |
| 123 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 124 | <circle cx="12" cy="12" r="3"/> |
| 125 | <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/> |
| 126 | </svg> |
| 127 | </span> |
| 128 | <span class="cpr-text"> |
| 129 | Preferences |
| 130 | </span> |
| 131 | <span class="cpr-key"> |
| 132 | ⌘, |
| 133 | </span> |
| 134 | </button> |
| 135 | </div> |
| 136 | </div> |
| 137 | </div> |
| 138 | </div> |
| 1 | .cpr-demo { |
| 2 | padding:20px 24px; |
| 3 | font-family:system-ui, |
| 4 | sans-serif; |
| 5 | min-height:360px; |
| 6 | display:flex; |
| 7 | justify-content:center |
| 8 | } |
| 9 | .cpr-modal { |
| 10 | width:100%; |
| 11 | max-width:460px; |
| 12 | background:#111; |
| 13 | border:1px solid #2A2A3E; |
| 14 | border-radius:12px; |
| 15 | overflow:hidden; |
| 16 | box-shadow:0 24px 64px rgba(0, |
| 17 | 0, |
| 18 | 0, |
| 19 | .6) |
| 20 | } |
| 21 | .cpr-input-wrap { |
| 22 | display:flex; |
| 23 | align-items:center; |
| 24 | gap:10px; |
| 25 | padding:14px 16px; |
| 26 | border-bottom:1px solid #222 |
| 27 | } |
| 28 | .cpr-input-wrap svg { |
| 29 | color:#666; |
| 30 | flex-shrink:0 |
| 31 | } |
| 32 | .cpr-input { |
| 33 | flex:1; |
| 34 | background:transparent; |
| 35 | border:none; |
| 36 | color:#E0E0E0; |
| 37 | font-size:14px; |
| 38 | font-family:system-ui, |
| 39 | sans-serif; |
| 40 | outline:none |
| 41 | } |
| 42 | .cpr-input::placeholder { |
| 43 | color:#555 |
| 44 | } |
| 45 | .cpr-esc { |
| 46 | font-size:10px; |
| 47 | color:#555; |
| 48 | background:rgba(255, |
| 49 | 255, |
| 50 | 255, |
| 51 | .04); |
| 52 | padding:2px 6px; |
| 53 | border-radius:3px; |
| 54 | border:1px solid #222; |
| 55 | flex-shrink:0 |
| 56 | } |
| 57 | .cpr-results { |
| 58 | max-height:320px; |
| 59 | overflow-y:auto; |
| 60 | padding:8px |
| 61 | } |
| 62 | .cpr-group { |
| 63 | margin-bottom:4px |
| 64 | } |
| 65 | .cpr-group-label { |
| 66 | display:flex; |
| 67 | align-items:center; |
| 68 | gap:6px; |
| 69 | padding:8px 12px 4px; |
| 70 | font-size:10px; |
| 71 | color:#555; |
| 72 | text-transform:uppercase; |
| 73 | letter-spacing:.5px; |
| 74 | font-weight:600 |
| 75 | } |
| 76 | .cpr-item { |
| 77 | display:flex; |
| 78 | align-items:center; |
| 79 | gap:10px; |
| 80 | width:100%; |
| 81 | padding:10px 12px; |
| 82 | border-radius:8px; |
| 83 | border:none; |
| 84 | background:transparent; |
| 85 | color:#A0A0A0; |
| 86 | font-size:13px; |
| 87 | font-family:system-ui, |
| 88 | sans-serif; |
| 89 | cursor:pointer; |
| 90 | text-align:left; |
| 91 | transition:background .1s |
| 92 | } |
| 93 | .cpr-item:hover { |
| 94 | background:rgba(255, |
| 95 | 255, |
| 96 | 255, |
| 97 | .05); |
| 98 | color:#E0E0E0 |
| 99 | } |
| 100 | .cpr-icon { |
| 101 | display:flex; |
| 102 | align-items:center; |
| 103 | justify-content:center; |
| 104 | width:20px; |
| 105 | height:20px; |
| 106 | color:#666; |
| 107 | flex-shrink:0 |
| 108 | } |
| 109 | .cpr-text { |
| 110 | flex:1 |
| 111 | } |
| 112 | .cpr-time { |
| 113 | font-size:10px; |
| 114 | color:#555; |
| 115 | flex-shrink:0 |
| 116 | } |
| 117 | .cpr-key { |
| 118 | font-size:10px; |
| 119 | color:#555; |
| 120 | background:rgba(255, |
| 121 | 255, |
| 122 | 255, |
| 123 | .04); |
| 124 | padding:2px 6px; |
| 125 | border-radius:3px; |
| 126 | border:1px solid #222; |
| 127 | flex-shrink:0 |
| 128 | } |
| 129 | .cpr-divider { |
| 130 | height:1px; |
| 131 | background:#222; |
| 132 | margin:4px 12px |
| 133 | } |
| 1 | <div class="p-6 font-sans min-h-[360px] flex justify-center bg-[#0A0A0A]"> |
| 2 | <div class="w-full max-w-[460px] bg-[#111] border border-[#2A2A3E] rounded-xl overflow-hidden shadow-2xl"> |
| 3 | <div class="flex items-center gap-2.5 px-4 py-3.5 border-b border-[#222]"> |
| 4 | <svg class="w-4 h-4 text-[#666] flex-shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 5 | <circle cx="11" cy="11" r="8"/> |
| 6 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 7 | </svg> |
| 8 | <input type="text" class="flex-1 bg-transparent border-none text-[#E0E0E0] text-sm outline-none placeholder:text-[#555]" placeholder="Type a command..." /> |
| 9 | <span class="text-[10px] text-[#555] bg-white/[0.04] px-1.5 py-0.5 rounded border border-[#222] flex-shrink-0"> |
| 10 | ESC |
| 11 | </span> |
| 12 | </div> |
| 13 | <div class="max-h-[320px] overflow-y-auto p-2"> |
| 14 | <div class="mb-1"> |
| 15 | <span class="flex items-center gap-1.5 px-3 py-1 text-[10px] text-[#555] uppercase tracking-wider font-semibold"> |
| 16 | <svg class="w-3 h-3" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 17 | <circle cx="12" cy="12" r="10"/> |
| 18 | <polyline points="12 6 12 12 16 14"/> |
| 19 | </svg> |
| 20 | Recent |
| 21 | </span> |
| 22 | <button class="flex items-center gap-2.5 w-full px-3 py-2.5 rounded-lg border-none bg-transparent text-[#A0A0A0] text-[13px] text-left hover:bg-white/5 transition-colors"> |
| 23 | <span class="flex items-center justify-center w-5 h-5 text-[#666] flex-shrink-0"> |
| 24 | <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 25 | <path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z"/> |
| 26 | <path d="M12 15l-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z"/> |
| 27 | <path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0"/> |
| 28 | <path d="M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"/> |
| 29 | </svg> |
| 30 | </span> |
| 31 | <span class="flex-1"> |
| 32 | Deploy to production |
| 33 | </span> |
| 34 | <span class="text-[10px] text-[#555] flex-shrink-0"> |
| 35 | 2m ago |
| 36 | </span> |
| 37 | </button> |
| 38 | <button class="flex items-center gap-2.5 w-full px-3 py-2.5 rounded-lg border-none bg-transparent text-[#A0A0A0] text-[13px] text-left hover:bg-white/5 transition-colors"> |
| 39 | <span class="flex items-center justify-center w-5 h-5 text-[#666] flex-shrink-0"> |
| 40 | <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 41 | <polyline points="23 4 23 10 17 10"/> |
| 42 | <path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"/> |
| 43 | </svg> |
| 44 | </span> |
| 45 | <span class="flex-1"> |
| 46 | Restart dev server |
| 47 | </span> |
| 48 | <span class="text-[10px] text-[#555] flex-shrink-0"> |
| 49 | 15m ago |
| 50 | </span> |
| 51 | </button> |
| 52 | <button class="flex items-center gap-2.5 w-full px-3 py-2.5 rounded-lg border-none bg-transparent text-[#A0A0A0] text-[13px] text-left hover:bg-white/5 transition-colors"> |
| 53 | <span class="flex items-center justify-center w-5 h-5 text-[#666] flex-shrink-0"> |
| 54 | <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 55 | <line x1="16.5" y1="9.4" x2="7.5" y2="4.21"/> |
| 56 | <path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/> |
| 57 | <polyline points="3.27 6.96 12 12.01 20.73 6.96"/> |
| 58 | <line x1="12" y1="22.08" x2="12" y2="12"/> |
| 59 | </svg> |
| 60 | </span> |
| 61 | <span class="flex-1"> |
| 62 | Build for staging |
| 63 | </span> |
| 64 | <span class="text-[10px] text-[#555] flex-shrink-0"> |
| 65 | 1h ago |
| 66 | </span> |
| 67 | </button> |
| 68 | </div> |
| 69 | <div class="h-px bg-[#222] my-1 mx-3"> |
| 70 | </div> |
| 71 | <div class="mb-1"> |
| 72 | <span class="block px-3 py-1 text-[10px] text-[#555] uppercase tracking-wider font-semibold"> |
| 73 | All Commands |
| 74 | </span> |
| 75 | <button class="flex items-center gap-2.5 w-full px-3 py-2.5 rounded-lg border-none bg-transparent text-[#A0A0A0] text-[13px] text-left hover:bg-white/5 transition-colors"> |
| 76 | <span class="flex items-center justify-center w-5 h-5 text-[#666] flex-shrink-0"> |
| 77 | <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 78 | <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/> |
| 79 | <polyline points="14 2 14 8 20 8"/> |
| 80 | <line x1="16" y1="13" x2="8" y2="13"/> |
| 81 | <line x1="16" y1="17" x2="8" y2="17"/> |
| 82 | <polyline points="10 9 9 9 8 9"/> |
| 83 | </svg> |
| 84 | </span> |
| 85 | <span class="flex-1"> |
| 86 | New file |
| 87 | </span> |
| 88 | <span class="text-[10px] text-[#555] bg-white/[0.04] px-1.5 py-0.5 rounded border border-[#222] flex-shrink-0"> |
| 89 | ⌘N |
| 90 | </span> |
| 91 | </button> |
| 92 | <button class="flex items-center gap-2.5 w-full px-3 py-2.5 rounded-lg border-none bg-transparent text-[#A0A0A0] text-[13px] text-left hover:bg-white/5 transition-colors"> |
| 93 | <span class="flex items-center justify-center w-5 h-5 text-[#666] flex-shrink-0"> |
| 94 | <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 95 | <path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/> |
| 96 | <polyline points="17 21 17 13 7 13 7 21"/> |
| 97 | <polyline points="7 3 7 8 15 8"/> |
| 98 | </svg> |
| 99 | </span> |
| 100 | <span class="flex-1"> |
| 101 | Save all |
| 102 | </span> |
| 103 | <span class="text-[10px] text-[#555] bg-white/[0.04] px-1.5 py-0.5 rounded border border-[#222] flex-shrink-0"> |
| 104 | ⌘S |
| 105 | </span> |
| 106 | </button> |
| 107 | <button class="flex items-center gap-2.5 w-full px-3 py-2.5 rounded-lg border-none bg-transparent text-[#A0A0A0] text-[13px] text-left hover:bg-white/5 transition-colors"> |
| 108 | <span class="flex items-center justify-center w-5 h-5 text-[#666] flex-shrink-0"> |
| 109 | <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 110 | <circle cx="11" cy="11" r="8"/> |
| 111 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 112 | </svg> |
| 113 | </span> |
| 114 | <span class="flex-1"> |
| 115 | Find in files |
| 116 | </span> |
| 117 | <span class="text-[10px] text-[#555] bg-white/[0.04] px-1.5 py-0.5 rounded border border-[#222] flex-shrink-0"> |
| 118 | ⌘F |
| 119 | </span> |
| 120 | </button> |
| 121 | <button class="flex items-center gap-2.5 w-full px-3 py-2.5 rounded-lg border-none bg-transparent text-[#A0A0A0] text-[13px] text-left hover:bg-white/5 transition-colors"> |
| 122 | <span class="flex items-center justify-center w-5 h-5 text-[#666] flex-shrink-0"> |
| 123 | <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 124 | <circle cx="12" cy="12" r="3"/> |
| 125 | <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/> |
| 126 | </svg> |
| 127 | </span> |
| 128 | <span class="flex-1"> |
| 129 | Preferences |
| 130 | </span> |
| 131 | <span class="text-[10px] text-[#555] bg-white/[0.04] px-1.5 py-0.5 rounded border border-[#222] flex-shrink-0"> |
| 132 | ⌘, |
| 133 | </span> |
| 134 | </button> |
| 135 | </div> |
| 136 | </div> |
| 137 | </div> |
| 138 | </div> |
| 1 | <div class="p-4 font-sans min-vh-50 d-flex justify-content-center bg-dark"> |
| 2 | <div class="card border-secondary bg-dark overflow-hidden" style="width:100%;max-width:460px;border-radius:12px;box-shadow:0 24px 64px rgba(0,0,0,.6)"> |
| 3 | <div class="card-header border-secondary bg-dark d-flex align-items-center gap-2 px-3 py-3"> |
| 4 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="text-secondary flex-shrink-0"> |
| 5 | <circle cx="11" cy="11" r="8"/> |
| 6 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 7 | </svg> |
| 8 | <input type="text" class="form-control border-0 bg-transparent text-light shadow-none px-0" placeholder="Type a command..." style="font-size:14px" /> |
| 9 | <span class="badge border-secondary text-secondary fw-normal flex-shrink-0" style="background:rgba(255,255,255,.04);font-size:10px"> |
| 10 | ESC |
| 11 | </span> |
| 12 | </div> |
| 13 | <div class="card-body p-2" style="max-height:320px;overflow-y:auto"> |
| 14 | <div class="mb-1"> |
| 15 | <span class="d-flex align-items-center gap-1 px-3 py-1 text-uppercase fw-semibold" style="font-size:10px;color:#555"> |
| 16 | <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 17 | <circle cx="12" cy="12" r="10"/> |
| 18 | <polyline points="12 6 12 12 16 14"/> |
| 19 | </svg> |
| 20 | Recent |
| 21 | </span> |
| 22 | <button class="btn btn-dark text-start w-100 border-0 d-flex align-items-center gap-2 px-3 py-2" style="border-radius:8px;font-size:13px;color:#A0A0A0;background:transparent"> |
| 23 | <span class="d-flex align-items-center justify-content-center flex-shrink-0" style="width:20px;height:20px;color:#666"> |
| 24 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 25 | <path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z"/> |
| 26 | <path d="M12 15l-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z"/> |
| 27 | <path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0"/> |
| 28 | <path d="M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"/> |
| 29 | </svg> |
| 30 | </span> |
| 31 | <span class="flex-fill"> |
| 32 | Deploy to production |
| 33 | </span> |
| 34 | <span class="flex-shrink-0" style="font-size:10px;color:#555"> |
| 35 | 2m ago |
| 36 | </span> |
| 37 | </button> |
| 38 | <button class="btn btn-dark text-start w-100 border-0 d-flex align-items-center gap-2 px-3 py-2" style="border-radius:8px;font-size:13px;color:#A0A0A0;background:transparent"> |
| 39 | <span class="d-flex align-items-center justify-content-center flex-shrink-0" style="width:20px;height:20px;color:#666"> |
| 40 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 41 | <polyline points="23 4 23 10 17 10"/> |
| 42 | <path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"/> |
| 43 | </svg> |
| 44 | </span> |
| 45 | <span class="flex-fill"> |
| 46 | Restart dev server |
| 47 | </span> |
| 48 | <span class="flex-shrink-0" style="font-size:10px;color:#555"> |
| 49 | 15m ago |
| 50 | </span> |
| 51 | </button> |
| 52 | <button class="btn btn-dark text-start w-100 border-0 d-flex align-items-center gap-2 px-3 py-2" style="border-radius:8px;font-size:13px;color:#A0A0A0;background:transparent"> |
| 53 | <span class="d-flex align-items-center justify-content-center flex-shrink-0" style="width:20px;height:20px;color:#666"> |
| 54 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 55 | <line x1="16.5" y1="9.4" x2="7.5" y2="4.21"/> |
| 56 | <path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/> |
| 57 | <polyline points="3.27 6.96 12 12.01 20.73 6.96"/> |
| 58 | <line x1="12" y1="22.08" x2="12" y2="12"/> |
| 59 | </svg> |
| 60 | </span> |
| 61 | <span class="flex-fill"> |
| 62 | Build for staging |
| 63 | </span> |
| 64 | <span class="flex-shrink-0" style="font-size:10px;color:#555"> |
| 65 | 1h ago |
| 66 | </span> |
| 67 | </button> |
| 68 | </div> |
| 69 | <div style="height:1px;background:#222;margin:4px 12px"> |
| 70 | </div> |
| 71 | <div class="mb-1"> |
| 72 | <span class="d-block px-3 py-1 text-uppercase fw-semibold" style="font-size:10px;color:#555"> |
| 73 | All Commands |
| 74 | </span> |
| 75 | <button class="btn btn-dark text-start w-100 border-0 d-flex align-items-center gap-2 px-3 py-2" style="border-radius:8px;font-size:13px;color:#A0A0A0;background:transparent"> |
| 76 | <span class="d-flex align-items-center justify-content-center flex-shrink-0" style="width:20px;height:20px;color:#666"> |
| 77 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 78 | <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/> |
| 79 | <polyline points="14 2 14 8 20 8"/> |
| 80 | <line x1="16" y1="13" x2="8" y2="13"/> |
| 81 | <line x1="16" y1="17" x2="8" y2="17"/> |
| 82 | <polyline points="10 9 9 9 8 9"/> |
| 83 | </svg> |
| 84 | </span> |
| 85 | <span class="flex-fill"> |
| 86 | New file |
| 87 | </span> |
| 88 | <span class="badge border-secondary text-secondary fw-normal flex-shrink-0" style="background:rgba(255,255,255,.04);font-size:10px"> |
| 89 | ⌘N |
| 90 | </span> |
| 91 | </button> |
| 92 | <button class="btn btn-dark text-start w-100 border-0 d-flex align-items-center gap-2 px-3 py-2" style="border-radius:8px;font-size:13px;color:#A0A0A0;background:transparent"> |
| 93 | <span class="d-flex align-items-center justify-content-center flex-shrink-0" style="width:20px;height:20px;color:#666"> |
| 94 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 95 | <path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/> |
| 96 | <polyline points="17 21 17 13 7 13 7 21"/> |
| 97 | <polyline points="7 3 7 8 15 8"/> |
| 98 | </svg> |
| 99 | </span> |
| 100 | <span class="flex-fill"> |
| 101 | Save all |
| 102 | </span> |
| 103 | <span class="badge border-secondary text-secondary fw-normal flex-shrink-0" style="background:rgba(255,255,255,.04);font-size:10px"> |
| 104 | ⌘S |
| 105 | </span> |
| 106 | </button> |
| 107 | <button class="btn btn-dark text-start w-100 border-0 d-flex align-items-center gap-2 px-3 py-2" style="border-radius:8px;font-size:13px;color:#A0A0A0;background:transparent"> |
| 108 | <span class="d-flex align-items-center justify-content-center flex-shrink-0" style="width:20px;height:20px;color:#666"> |
| 109 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 110 | <circle cx="11" cy="11" r="8"/> |
| 111 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 112 | </svg> |
| 113 | </span> |
| 114 | <span class="flex-fill"> |
| 115 | Find in files |
| 116 | </span> |
| 117 | <span class="badge border-secondary text-secondary fw-normal flex-shrink-0" style="background:rgba(255,255,255,.04);font-size:10px"> |
| 118 | ⌘F |
| 119 | </span> |
| 120 | </button> |
| 121 | <button class="btn btn-dark text-start w-100 border-0 d-flex align-items-center gap-2 px-3 py-2" style="border-radius:8px;font-size:13px;color:#A0A0A0;background:transparent"> |
| 122 | <span class="d-flex align-items-center justify-content-center flex-shrink-0" style="width:20px;height:20px;color:#666"> |
| 123 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 124 | <circle cx="12" cy="12" r="3"/> |
| 125 | <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/> |
| 126 | </svg> |
| 127 | </span> |
| 128 | <span class="flex-fill"> |
| 129 | Preferences |
| 130 | </span> |
| 131 | <span class="badge border-secondary text-secondary fw-normal flex-shrink-0" style="background:rgba(255,255,255,.04);font-size:10px"> |
| 132 | ⌘, |
| 133 | </span> |
| 134 | </button> |
| 135 | </div> |
| 136 | </div> |
| 137 | </div> |
| 138 | </div> |
Some command palettes include a tab bar to switch between sections — All, Commands, Files, People, Settings. This reduces noise when the user knows what category they're searching. Tabs use a green underline indicator for the active section.
| 1 | <div class="cpt-demo"> |
| 2 | <div class="cpt-modal"> |
| 3 | <div class="cpt-input-wrap"> |
| 4 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 5 | <circle cx="11" cy="11" r="8"/> |
| 6 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 7 | </svg> |
| 8 | <input type="text" class="cpt-input" placeholder="Search everything..." /> |
| 9 | </div> |
| 10 | <div class="cpt-tabs"> |
| 11 | <button class="cpt-tab active"> |
| 12 | All |
| 13 | </button> |
| 14 | <button class="cpt-tab"> |
| 15 | Commands |
| 16 | </button> |
| 17 | <button class="cpt-tab"> |
| 18 | Files |
| 19 | </button> |
| 20 | <button class="cpt-tab"> |
| 21 | People |
| 22 | </button> |
| 23 | </div> |
| 24 | <div class="cpt-results"> |
| 25 | <div class="cpt-group"> |
| 26 | <span class="cpt-group-label"> |
| 27 | Files |
| 28 | </span> |
| 29 | <button class="cpt-item active"> |
| 30 | <span class="cpt-icon"> |
| 31 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 32 | <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/> |
| 33 | <polyline points="14 2 14 8 20 8"/> |
| 34 | <line x1="16" y1="13" x2="8" y2="13"/> |
| 35 | <line x1="16" y1="17" x2="8" y2="17"/> |
| 36 | <polyline points="10 9 9 9 8 9"/> |
| 37 | </svg> |
| 38 | </span> |
| 39 | <span class="cpt-text"> |
| 40 | src/components/Button.tsx |
| 41 | </span> |
| 42 | <span class="cpt-badge"> |
| 43 | File |
| 44 | </span> |
| 45 | </button> |
| 46 | <button class="cpt-item"> |
| 47 | <span class="cpt-icon"> |
| 48 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 49 | <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/> |
| 50 | <polyline points="14 2 14 8 20 8"/> |
| 51 | <line x1="16" y1="13" x2="8" y2="13"/> |
| 52 | <line x1="16" y1="17" x2="8" y2="17"/> |
| 53 | <polyline points="10 9 9 9 8 9"/> |
| 54 | </svg> |
| 55 | </span> |
| 56 | <span class="cpt-text"> |
| 57 | src/styles/globals.css |
| 58 | </span> |
| 59 | <span class="cpt-badge"> |
| 60 | File |
| 61 | </span> |
| 62 | </button> |
| 63 | </div> |
| 64 | <div class="cpt-group"> |
| 65 | <span class="cpt-group-label"> |
| 66 | People |
| 67 | </span> |
| 68 | <button class="cpt-item"> |
| 69 | <span class="cpt-avatar"> |
| 70 | S |
| 71 | </span> |
| 72 | <span class="cpt-text"> |
| 73 | Sarah Chen |
| 74 | </span> |
| 75 | <span class="cpt-badge green"> |
| 76 | Online |
| 77 | </span> |
| 78 | </button> |
| 79 | <button class="cpt-item"> |
| 80 | <span class="cpt-avatar"> |
| 81 | M |
| 82 | </span> |
| 83 | <span class="cpt-text"> |
| 84 | Mike Johnson |
| 85 | </span> |
| 86 | <span class="cpt-badge yellow"> |
| 87 | Away |
| 88 | </span> |
| 89 | </button> |
| 90 | </div> |
| 91 | </div> |
| 92 | </div> |
| 93 | </div> |
| 1 | .cpt-demo { |
| 2 | padding:20px 24px; |
| 3 | font-family:system-ui, |
| 4 | sans-serif; |
| 5 | min-height:380px; |
| 6 | display:flex; |
| 7 | justify-content:center |
| 8 | } |
| 9 | .cpt-modal { |
| 10 | width:100%; |
| 11 | max-width:480px; |
| 12 | background:#111; |
| 13 | border:1px solid #2A2A3E; |
| 14 | border-radius:12px; |
| 15 | overflow:hidden; |
| 16 | box-shadow:0 24px 64px rgba(0, |
| 17 | 0, |
| 18 | 0, |
| 19 | .6) |
| 20 | } |
| 21 | .cpt-input-wrap { |
| 22 | display:flex; |
| 23 | align-items:center; |
| 24 | gap:10px; |
| 25 | padding:14px 16px; |
| 26 | border-bottom:1px solid #222 |
| 27 | } |
| 28 | .cpt-input-wrap svg { |
| 29 | color:#666; |
| 30 | flex-shrink:0 |
| 31 | } |
| 32 | .cpt-input { |
| 33 | flex:1; |
| 34 | background:transparent; |
| 35 | border:none; |
| 36 | color:#E0E0E0; |
| 37 | font-size:14px; |
| 38 | font-family:system-ui, |
| 39 | sans-serif; |
| 40 | outline:none |
| 41 | } |
| 42 | .cpt-input::placeholder { |
| 43 | color:#555 |
| 44 | } |
| 45 | .cpt-tabs { |
| 46 | display:flex; |
| 47 | gap:0; |
| 48 | border-bottom:1px solid #222; |
| 49 | padding:0 8px |
| 50 | } |
| 51 | .cpt-tab { |
| 52 | padding:10px 14px; |
| 53 | font-size:12px; |
| 54 | font-weight:500; |
| 55 | color:#666; |
| 56 | background:transparent; |
| 57 | border:none; |
| 58 | cursor:pointer; |
| 59 | font-family:system-ui, |
| 60 | sans-serif; |
| 61 | position:relative; |
| 62 | transition:color .2s |
| 63 | } |
| 64 | .cpt-tab:hover { |
| 65 | color:#A0A0A0 |
| 66 | } |
| 67 | .cpt-tab.active { |
| 68 | color:#00FF41 |
| 69 | } |
| 70 | .cpt-tab.active::after { |
| 71 | content:''; |
| 72 | position:absolute; |
| 73 | bottom:-1px; |
| 74 | left:8px; |
| 75 | right:8px; |
| 76 | height:2px; |
| 77 | background:#00FF41; |
| 78 | border-radius:1px |
| 79 | } |
| 80 | .cpt-results { |
| 81 | max-height:260px; |
| 82 | overflow-y:auto; |
| 83 | padding:8px |
| 84 | } |
| 85 | .cpt-group { |
| 86 | margin-bottom:4px |
| 87 | } |
| 88 | .cpt-group-label { |
| 89 | display:block; |
| 90 | padding:8px 12px 4px; |
| 91 | font-size:10px; |
| 92 | color:#555; |
| 93 | text-transform:uppercase; |
| 94 | letter-spacing:.5px; |
| 95 | font-weight:600 |
| 96 | } |
| 97 | .cpt-item { |
| 98 | display:flex; |
| 99 | align-items:center; |
| 100 | gap:10px; |
| 101 | width:100%; |
| 102 | padding:10px 12px; |
| 103 | border-radius:8px; |
| 104 | border:none; |
| 105 | background:transparent; |
| 106 | color:#A0A0A0; |
| 107 | font-size:13px; |
| 108 | font-family:system-ui, |
| 109 | sans-serif; |
| 110 | cursor:pointer; |
| 111 | text-align:left; |
| 112 | transition:background .1s |
| 113 | } |
| 114 | .cpt-item:hover, |
| 115 | .cpt-item.active { |
| 116 | background:rgba(255, |
| 117 | 255, |
| 118 | 255, |
| 119 | .05); |
| 120 | color:#E0E0E0 |
| 121 | } |
| 122 | .cpt-item.active { |
| 123 | background:rgba(0, |
| 124 | 255, |
| 125 | 65, |
| 126 | .06) |
| 127 | } |
| 128 | .cpt-icon { |
| 129 | display:flex; |
| 130 | align-items:center; |
| 131 | justify-content:center; |
| 132 | width:20px; |
| 133 | height:20px; |
| 134 | color:#666; |
| 135 | flex-shrink:0 |
| 136 | } |
| 137 | .cpt-avatar { |
| 138 | width:24px; |
| 139 | height:24px; |
| 140 | border-radius:50%; |
| 141 | background:rgba(255, |
| 142 | 255, |
| 143 | 255, |
| 144 | .08); |
| 145 | color:#A0A0A0; |
| 146 | font-size:11px; |
| 147 | font-weight:600; |
| 148 | display:flex; |
| 149 | align-items:center; |
| 150 | justify-content:center; |
| 151 | flex-shrink:0 |
| 152 | } |
| 153 | .cpt-text { |
| 154 | flex:1 |
| 155 | } |
| 156 | .cpt-badge { |
| 157 | font-size:10px; |
| 158 | color:#555; |
| 159 | background:rgba(255, |
| 160 | 255, |
| 161 | 255, |
| 162 | .04); |
| 163 | padding:2px 6px; |
| 164 | border-radius:3px; |
| 165 | border:1px solid #222; |
| 166 | flex-shrink:0 |
| 167 | } |
| 168 | .cpt-badge.green { |
| 169 | color:#00FF41; |
| 170 | border-color:rgba(0, |
| 171 | 255, |
| 172 | 65, |
| 173 | .2); |
| 174 | background:rgba(0, |
| 175 | 255, |
| 176 | 65, |
| 177 | .06) |
| 178 | } |
| 179 | .cpt-badge.yellow { |
| 180 | color:#EAB308; |
| 181 | border-color:rgba(234, |
| 182 | 179, |
| 183 | 8, |
| 184 | .2); |
| 185 | background:rgba(234, |
| 186 | 179, |
| 187 | 8, |
| 188 | .06) |
| 189 | } |
| 1 | document.querySelectorAll('.cpt-tab').forEach(tab=>{ |
| 2 | tab.addEventListener('click',()=>{ |
| 3 | document.querySelectorAll('.cpt-tab').forEach(t=>t.classList.remove('active')); |
| 4 | tab.classList.add('active'); |
| 5 | }); |
| 6 | }) |
| 1 | <div class="p-6 font-sans min-h-[380px] flex justify-center bg-[#0A0A0A]"> |
| 2 | <div class="w-full max-w-[480px] bg-[#111] border border-[#2A2A3E] rounded-xl overflow-hidden shadow-2xl"> |
| 3 | <div class="flex items-center gap-2.5 px-4 py-3.5 border-b border-[#222]"> |
| 4 | <svg class="w-4 h-4 text-[#666] flex-shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 5 | <circle cx="11" cy="11" r="8"/> |
| 6 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 7 | </svg> |
| 8 | <input type="text" class="flex-1 bg-transparent border-none text-[#E0E0E0] text-sm outline-none placeholder:text-[#555]" placeholder="Search everything..." /> |
| 9 | </div> |
| 10 | <div class="flex gap-0 border-b border-[#222] px-2"> |
| 11 | <button class="cpt-tab-tw active relative px-4 py-2.5 text-xs font-medium text-[#00FF41] bg-transparent border-none cursor-pointer transition-colors hover:text-[#A0A0A0]"> |
| 12 | All |
| 13 | </button> |
| 14 | <button class="cpt-tab-tw relative px-4 py-2.5 text-xs font-medium text-[#666] bg-transparent border-none cursor-pointer transition-colors hover:text-[#A0A0A0]"> |
| 15 | Commands |
| 16 | </button> |
| 17 | <button class="cpt-tab-tw relative px-4 py-2.5 text-xs font-medium text-[#666] bg-transparent border-none cursor-pointer transition-colors hover:text-[#A0A0A0]"> |
| 18 | Files |
| 19 | </button> |
| 20 | <button class="cpt-tab-tw relative px-4 py-2.5 text-xs font-medium text-[#666] bg-transparent border-none cursor-pointer transition-colors hover:text-[#A0A0A0]"> |
| 21 | People |
| 22 | </button> |
| 23 | </div> |
| 24 | <style> |
| 25 | .cpt-tab-tw.active::after{content:'';position:absolute;bottom:-1px;left:8px;right:8px;height:2px;background:#00FF41;border-radius:1px} |
| 26 | </style> |
| 27 | <div class="max-h-[260px] overflow-y-auto p-2"> |
| 28 | <div class="mb-1"> |
| 29 | <span class="block px-3 py-1 text-[10px] text-[#555] uppercase tracking-wider font-semibold"> |
| 30 | Files |
| 31 | </span> |
| 32 | <button class="flex items-center gap-2.5 w-full px-3 py-2.5 rounded-lg border-none bg-[rgba(0,255,65,0.06)] text-[#E0E0E0] text-[13px] text-left transition-colors hover:bg-white/5"> |
| 33 | <span class="flex items-center justify-center w-5 h-5 text-[#666] flex-shrink-0"> |
| 34 | <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 35 | <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/> |
| 36 | <polyline points="14 2 14 8 20 8"/> |
| 37 | <line x1="16" y1="13" x2="8" y2="13"/> |
| 38 | <line x1="16" y1="17" x2="8" y2="17"/> |
| 39 | <polyline points="10 9 9 9 8 9"/> |
| 40 | </svg> |
| 41 | </span> |
| 42 | <span class="flex-1"> |
| 43 | src/components/Button.tsx |
| 44 | </span> |
| 45 | <span class="text-[10px] text-[#555] bg-white/[0.04] px-1.5 py-0.5 rounded border border-[#222] flex-shrink-0"> |
| 46 | File |
| 47 | </span> |
| 48 | </button> |
| 49 | <button class="flex items-center gap-2.5 w-full px-3 py-2.5 rounded-lg border-none bg-transparent text-[#A0A0A0] text-[13px] text-left hover:bg-white/5 transition-colors"> |
| 50 | <span class="flex items-center justify-center w-5 h-5 text-[#666] flex-shrink-0"> |
| 51 | <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 52 | <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/> |
| 53 | <polyline points="14 2 14 8 20 8"/> |
| 54 | <line x1="16" y1="13" x2="8" y2="13"/> |
| 55 | <line x1="16" y1="17" x2="8" y2="17"/> |
| 56 | <polyline points="10 9 9 9 8 9"/> |
| 57 | </svg> |
| 58 | </span> |
| 59 | <span class="flex-1"> |
| 60 | src/styles/globals.css |
| 61 | </span> |
| 62 | <span class="text-[10px] text-[#555] bg-white/[0.04] px-1.5 py-0.5 rounded border border-[#222] flex-shrink-0"> |
| 63 | File |
| 64 | </span> |
| 65 | </button> |
| 66 | </div> |
| 67 | <div class="mb-1"> |
| 68 | <span class="block px-3 py-1 text-[10px] text-[#555] uppercase tracking-wider font-semibold"> |
| 69 | People |
| 70 | </span> |
| 71 | <button class="flex items-center gap-2.5 w-full px-3 py-2.5 rounded-lg border-none bg-transparent text-[#A0A0A0] text-[13px] text-left hover:bg-white/5 transition-colors"> |
| 72 | <span class="w-6 h-6 rounded-full bg-white/[0.08] text-[#A0A0A0] text-[11px] font-semibold flex items-center justify-center flex-shrink-0"> |
| 73 | S |
| 74 | </span> |
| 75 | <span class="flex-1"> |
| 76 | Sarah Chen |
| 77 | </span> |
| 78 | <span class="text-[10px] text-[#00FF41] bg-[rgba(0,255,65,0.06)] px-1.5 py-0.5 rounded border border-[rgba(0,255,65,0.2)] flex-shrink-0"> |
| 79 | Online |
| 80 | </span> |
| 81 | </button> |
| 82 | <button class="flex items-center gap-2.5 w-full px-3 py-2.5 rounded-lg border-none bg-transparent text-[#A0A0A0] text-[13px] text-left hover:bg-white/5 transition-colors"> |
| 83 | <span class="w-6 h-6 rounded-full bg-white/[0.08] text-[#A0A0A0] text-[11px] font-semibold flex items-center justify-center flex-shrink-0"> |
| 84 | M |
| 85 | </span> |
| 86 | <span class="flex-1"> |
| 87 | Mike Johnson |
| 88 | </span> |
| 89 | <span class="text-[10px] text-[#EAB308] bg-[rgba(234,179,8,0.06)] px-1.5 py-0.5 rounded border border-[rgba(234,179,8,0.2)] flex-shrink-0"> |
| 90 | Away |
| 91 | </span> |
| 92 | </button> |
| 93 | </div> |
| 94 | </div> |
| 95 | </div> |
| 96 | </div> |
| 1 | <div class="p-4 font-sans min-vh-50 d-flex justify-content-center bg-dark"> |
| 2 | <div class="card border-secondary bg-dark overflow-hidden" style="width:100%;max-width:480px;border-radius:12px;box-shadow:0 24px 64px rgba(0,0,0,.6)"> |
| 3 | <div class="card-header border-secondary bg-dark d-flex align-items-center gap-2 px-3 py-3"> |
| 4 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="text-secondary flex-shrink-0"> |
| 5 | <circle cx="11" cy="11" r="8"/> |
| 6 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 7 | </svg> |
| 8 | <input type="text" class="form-control border-0 bg-transparent text-light shadow-none px-0" placeholder="Search everything..." style="font-size:14px" /> |
| 9 | </div> |
| 10 | <div class="d-flex border-bottom border-secondary px-2"> |
| 11 | <button class="cpt-tab-bs active btn btn-link text-decoration-none position-relative" style="padding:10px 14px;font-size:12px;font-weight:500;color:#00FF41"> |
| 12 | All |
| 13 | </button> |
| 14 | <button class="cpt-tab-bs btn btn-link text-decoration-none position-relative" style="padding:10px 14px;font-size:12px;font-weight:500;color:#666"> |
| 15 | Commands |
| 16 | </button> |
| 17 | <button class="cpt-tab-bs btn btn-link text-decoration-none position-relative" style="padding:10px 14px;font-size:12px;font-weight:500;color:#666"> |
| 18 | Files |
| 19 | </button> |
| 20 | <button class="cpt-tab-bs btn btn-link text-decoration-none position-relative" style="padding:10px 14px;font-size:12px;font-weight:500;color:#666"> |
| 21 | People |
| 22 | </button> |
| 23 | </div> |
| 24 | <style> |
| 25 | .cpt-tab-bs.active::after{content:'';position:absolute;bottom:-1px;left:8px;right:8px;height:2px;background:#00FF41;border-radius:1px}.cpt-tab-bs:hover{color:#A0A0A0!important} |
| 26 | </style> |
| 27 | <div class="card-body p-2" style="max-height:260px;overflow-y:auto"> |
| 28 | <div class="mb-1"> |
| 29 | <span class="d-block px-3 py-1 text-uppercase fw-semibold" style="font-size:10px;color:#555"> |
| 30 | Files |
| 31 | </span> |
| 32 | <button class="btn btn-dark text-start w-100 border-0 d-flex align-items-center gap-2 px-3 py-2" style="border-radius:8px;font-size:13px;color:#E0E0E0;background:rgba(0,255,65,.06)"> |
| 33 | <span class="d-flex align-items-center justify-content-center flex-shrink-0" style="width:20px;height:20px;color:#666"> |
| 34 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 35 | <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/> |
| 36 | <polyline points="14 2 14 8 20 8"/> |
| 37 | <line x1="16" y1="13" x2="8" y2="13"/> |
| 38 | <line x1="16" y1="17" x2="8" y2="17"/> |
| 39 | <polyline points="10 9 9 9 8 9"/> |
| 40 | </svg> |
| 41 | </span> |
| 42 | <span class="flex-fill"> |
| 43 | src/components/Button.tsx |
| 44 | </span> |
| 45 | <span class="badge border-secondary text-secondary fw-normal flex-shrink-0" style="background:rgba(255,255,255,.04);font-size:10px"> |
| 46 | File |
| 47 | </span> |
| 48 | </button> |
| 49 | <button class="btn btn-dark text-start w-100 border-0 d-flex align-items-center gap-2 px-3 py-2" style="border-radius:8px;font-size:13px;color:#A0A0A0;background:transparent"> |
| 50 | <span class="d-flex align-items-center justify-content-center flex-shrink-0" style="width:20px;height:20px;color:#666"> |
| 51 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 52 | <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/> |
| 53 | <polyline points="14 2 14 8 20 8"/> |
| 54 | <line x1="16" y1="13" x2="8" y2="13"/> |
| 55 | <line x1="16" y1="17" x2="8" y2="17"/> |
| 56 | <polyline points="10 9 9 9 8 9"/> |
| 57 | </svg> |
| 58 | </span> |
| 59 | <span class="flex-fill"> |
| 60 | src/styles/globals.css |
| 61 | </span> |
| 62 | <span class="badge border-secondary text-secondary fw-normal flex-shrink-0" style="background:rgba(255,255,255,.04);font-size:10px"> |
| 63 | File |
| 64 | </span> |
| 65 | </button> |
| 66 | </div> |
| 67 | <div class="mb-1"> |
| 68 | <span class="d-block px-3 py-1 text-uppercase fw-semibold" style="font-size:10px;color:#555"> |
| 69 | People |
| 70 | </span> |
| 71 | <button class="btn btn-dark text-start w-100 border-0 d-flex align-items-center gap-2 px-3 py-2" style="border-radius:8px;font-size:13px;color:#A0A0A0;background:transparent"> |
| 72 | <span class="d-flex align-items-center justify-content-center rounded-circle flex-shrink-0" style="width:24px;height:24px;background:rgba(255,255,255,.08);color:#A0A0A0;font-size:11px;font-weight:600"> |
| 73 | S |
| 74 | </span> |
| 75 | <span class="flex-fill"> |
| 76 | Sarah Chen |
| 77 | </span> |
| 78 | <span class="badge fw-normal flex-shrink-0" style="font-size:10px;color:#00FF41;border-color:rgba(0,255,65,.2);background:rgba(0,255,65,.06)"> |
| 79 | Online |
| 80 | </span> |
| 81 | </button> |
| 82 | <button class="btn btn-dark text-start w-100 border-0 d-flex align-items-center gap-2 px-3 py-2" style="border-radius:8px;font-size:13px;color:#A0A0A0;background:transparent"> |
| 83 | <span class="d-flex align-items-center justify-content-center rounded-circle flex-shrink-0" style="width:24px;height:24px;background:rgba(255,255,255,.08);color:#A0A0A0;font-size:11px;font-weight:600"> |
| 84 | M |
| 85 | </span> |
| 86 | <span class="flex-fill"> |
| 87 | Mike Johnson |
| 88 | </span> |
| 89 | <span class="badge fw-normal flex-shrink-0" style="font-size:10px;color:#EAB308;border-color:rgba(234,179,8,.2);background:rgba(234,179,8,.06)"> |
| 90 | Away |
| 91 | </span> |
| 92 | </button> |
| 93 | </div> |
| 94 | </div> |
| 95 | </div> |
| 96 | </div> |
An inline command bar that lives at the top of the page rather than in a modal overlay. This pattern is common in IDEs and dashboards where the palette is always visible and accessible. Focus ring highlights in green when active.
| 1 | <div class="cpsi-demo"> |
| 2 | <div class="cpsi-bar"> |
| 3 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 4 | <circle cx="11" cy="11" r="8"/> |
| 5 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 6 | </svg> |
| 7 | <input type="text" class="cpsi-input" placeholder="Quick actions..." /> |
| 8 | <div class="cpsi-hints"> |
| 9 | <span class="cpsi-key"> |
| 10 | ⌘K |
| 11 | </span> |
| 12 | <span class="cpsi-key"> |
| 13 | / |
| 14 | </span> |
| 15 | </div> |
| 16 | </div> |
| 17 | </div> |
| 1 | .cpsi-demo { |
| 2 | padding:20px 24px; |
| 3 | font-family:system-ui, |
| 4 | sans-serif |
| 5 | } |
| 6 | .cpsi-bar { |
| 7 | display:flex; |
| 8 | align-items:center; |
| 9 | gap:10px; |
| 10 | max-width:500px; |
| 11 | margin:0 auto; |
| 12 | padding:10px 16px; |
| 13 | border-radius:10px; |
| 14 | border:1px solid #2A2A2A; |
| 15 | background:#0F0F0F; |
| 16 | transition:border-color .2s |
| 17 | } |
| 18 | .cpsi-bar:focus-within { |
| 19 | border-color:rgba(0, |
| 20 | 255, |
| 21 | 65, |
| 22 | .4); |
| 23 | box-shadow:0 0 0 3px rgba(0, |
| 24 | 255, |
| 25 | 65, |
| 26 | .06) |
| 27 | } |
| 28 | .cpsi-bar svg { |
| 29 | color:#555; |
| 30 | flex-shrink:0 |
| 31 | } |
| 32 | .cpsi-input { |
| 33 | flex:1; |
| 34 | background:transparent; |
| 35 | border:none; |
| 36 | color:#E0E0E0; |
| 37 | font-size:14px; |
| 38 | font-family:system-ui, |
| 39 | sans-serif; |
| 40 | outline:none |
| 41 | } |
| 42 | .cpsi-input::placeholder { |
| 43 | color:#444 |
| 44 | } |
| 45 | .cpsi-hints { |
| 46 | display:flex; |
| 47 | gap:4px; |
| 48 | flex-shrink:0 |
| 49 | } |
| 50 | .cpsi-key { |
| 51 | font-size:10px; |
| 52 | color:#555; |
| 53 | background:rgba(255, |
| 54 | 255, |
| 55 | 255, |
| 56 | .04); |
| 57 | padding:2px 6px; |
| 58 | border-radius:3px; |
| 59 | border:1px solid #222 |
| 60 | } |
| 1 | <div class="p-6 font-sans bg-[#0A0A0A]"> |
| 2 | <div class="flex items-center gap-2.5 max-w-[500px] mx-auto px-4 py-2.5 rounded-[10px] border border-[#2A2A2A] bg-[#0F0F0F] focus-within:border-[rgba(0,255,65,0.4)] focus-within:shadow-[0_0_0_3px_rgba(0,255,65,0.06)] transition-colors"> |
| 3 | <svg class="w-4 h-4 text-[#555] flex-shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 4 | <circle cx="11" cy="11" r="8"/> |
| 5 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 6 | </svg> |
| 7 | <input type="text" class="flex-1 bg-transparent border-none text-[#E0E0E0] text-sm outline-none placeholder:text-[#444]" placeholder="Quick actions..." /> |
| 8 | <div class="flex gap-1 flex-shrink-0"> |
| 9 | <span class="text-[10px] text-[#555] bg-white/[0.04] px-1.5 py-0.5 rounded border border-[#222]"> |
| 10 | ⌘K |
| 11 | </span> |
| 12 | <span class="text-[10px] text-[#555] bg-white/[0.04] px-1.5 py-0.5 rounded border border-[#222]"> |
| 13 | / |
| 14 | </span> |
| 15 | </div> |
| 16 | </div> |
| 17 | </div> |
| 1 | <div class="p-4 font-sans bg-dark"> |
| 2 | <div class="d-flex align-items-center gap-2 mx-auto border-secondary bg-black" style="max-width:500px;padding:10px 16px;border-radius:10px;border:1px solid #2A2A2A"> |
| 3 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="text-secondary flex-shrink-0"> |
| 4 | <circle cx="11" cy="11" r="8"/> |
| 5 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 6 | </svg> |
| 7 | <input type="text" class="form-control border-0 bg-transparent text-light shadow-none px-0 flex-fill" placeholder="Quick actions..." style="font-size:14px" /> |
| 8 | <div class="d-flex gap-1 flex-shrink-0"> |
| 9 | <span class="badge border-secondary text-secondary fw-normal" style="background:rgba(255,255,255,.04);font-size:10px"> |
| 10 | ⌘K |
| 11 | </span> |
| 12 | <span class="badge border-secondary text-secondary fw-normal" style="background:rgba(255,255,255,.04);font-size:10px"> |
| 13 | / |
| 14 | </span> |
| 15 | </div> |
| 16 | </div> |
| 17 | </div> |
Command palettes need clear empty states when no results match and error states when search fails. Both should offer a recovery action and stay within the palette context.
| 1 | <div class="cpe-demo"> |
| 2 | <div class="cpe-stack"> |
| 3 | <div class="cpe-modal"> |
| 4 | <div class="cpe-input-wrap"> |
| 5 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 6 | <circle cx="11" cy="11" r="8"/> |
| 7 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 8 | </svg> |
| 9 | <input type="text" class="cpe-input" value="xyz" readonly /> |
| 10 | </div> |
| 11 | <div class="cpe-empty"> |
| 12 | <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"> |
| 13 | <circle cx="11" cy="11" r="8"/> |
| 14 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 15 | </svg> |
| 16 | <p class="cpe-title"> |
| 17 | No results found |
| 18 | </p> |
| 19 | <p class="cpe-subtitle"> |
| 20 | We couldn't find anything matching "xyz". |
| 21 | </p> |
| 22 | <button class="cpe-action"> |
| 23 | Clear search |
| 24 | </button> |
| 25 | </div> |
| 26 | </div> |
| 27 | <div class="cpe-modal"> |
| 28 | <div class="cpe-input-wrap"> |
| 29 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| 30 | <circle cx="11" cy="11" r="8"/> |
| 31 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 32 | </svg> |
| 33 | <input type="text" class="cpe-input" placeholder="Search..." /> |
| 34 | </div> |
| 35 | <div class="cpe-error"> |
| 36 | <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"> |
| 37 | <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/> |
| 38 | <line x1="12" y1="9" x2="12" y2="13"/> |
| 39 | <line x1="12" y1="17" x2="12.01" y2="17"/> |
| 40 | </svg> |
| 41 | <p class="cpe-title"> |
| 42 | Search failed |
| 43 | </p> |
| 44 | <p class="cpe-subtitle"> |
| 45 | Couldn't connect to the search service. |
| 46 | </p> |
| 47 | <button class="cpe-action error"> |
| 48 | Retry |
| 49 | </button> |
| 50 | </div> |
| 51 | </div> |
| 52 | </div> |
| 53 | </div> |
| 1 | .cpe-demo { |
| 2 | padding:20px 24px; |
| 3 | font-family:system-ui, |
| 4 | sans-serif; |
| 5 | min-height:380px; |
| 6 | display:flex; |
| 7 | justify-content:center |
| 8 | } |
| 9 | .cpe-stack { |
| 10 | display:flex; |
| 11 | flex-direction:column; |
| 12 | gap:16px; |
| 13 | width:100%; |
| 14 | max-width:460px |
| 15 | } |
| 16 | .cpe-modal { |
| 17 | width:100%; |
| 18 | background:#111; |
| 19 | border:1px solid #2A2A3E; |
| 20 | border-radius:12px; |
| 21 | overflow:hidden; |
| 22 | box-shadow:0 24px 64px rgba(0, |
| 23 | 0, |
| 24 | 0, |
| 25 | .6) |
| 26 | } |
| 27 | .cpe-input-wrap { |
| 28 | display:flex; |
| 29 | align-items:center; |
| 30 | gap:10px; |
| 31 | padding:14px 16px; |
| 32 | border-bottom:1px solid #222 |
| 33 | } |
| 34 | .cpe-input-wrap svg { |
| 35 | color:#666; |
| 36 | flex-shrink:0 |
| 37 | } |
| 38 | .cpe-input { |
| 39 | flex:1; |
| 40 | background:transparent; |
| 41 | border:none; |
| 42 | color:#E0E0E0; |
| 43 | font-size:14px; |
| 44 | font-family:system-ui, |
| 45 | sans-serif; |
| 46 | outline:none |
| 47 | } |
| 48 | .cpe-input::placeholder { |
| 49 | color:#555 |
| 50 | } |
| 51 | .cpe-empty, |
| 52 | .cpe-error { |
| 53 | display:flex; |
| 54 | flex-direction:column; |
| 55 | align-items:center; |
| 56 | justify-content:center; |
| 57 | padding:40px 24px; |
| 58 | text-align:center; |
| 59 | gap:10px |
| 60 | } |
| 61 | .cpe-empty svg { |
| 62 | color:#555 |
| 63 | } |
| 64 | .cpe-error svg { |
| 65 | color:#EF4444 |
| 66 | } |
| 67 | .cpe-title { |
| 68 | font-size:14px; |
| 69 | font-weight:600; |
| 70 | color:#E0E0E0; |
| 71 | margin:0 |
| 72 | } |
| 73 | .cpe-subtitle { |
| 74 | font-size:12px; |
| 75 | color:#666; |
| 76 | margin:0 |
| 77 | } |
| 78 | .cpe-action { |
| 79 | padding:8px 16px; |
| 80 | border-radius:6px; |
| 81 | border:1px solid #2A2A2A; |
| 82 | background:#151515; |
| 83 | color:#A0A0A0; |
| 84 | font-size:12px; |
| 85 | font-weight:500; |
| 86 | cursor:pointer; |
| 87 | transition:all .2s; |
| 88 | margin-top:6px |
| 89 | } |
| 90 | .cpe-action:hover { |
| 91 | border-color:#3A3A3A; |
| 92 | color:#E0E0E0; |
| 93 | background:#1A1A1A |
| 94 | } |
| 95 | .cpe-action.error:hover { |
| 96 | border-color:#EF4444; |
| 97 | color:#EF4444; |
| 98 | background:rgba(239, |
| 99 | 68, |
| 100 | 68, |
| 101 | .06) |
| 102 | } |
| 1 | <div class="p-6 font-sans min-h-[380px] flex justify-center bg-[#0A0A0A]"> |
| 2 | <div class="flex flex-col gap-4 w-full max-w-[460px]"> |
| 3 | <div class="w-full bg-[#111] border border-[#2A2A3E] rounded-xl overflow-hidden shadow-2xl"> |
| 4 | <div class="flex items-center gap-2.5 px-4 py-3.5 border-b border-[#222]"> |
| 5 | <svg class="w-4 h-4 text-[#666] flex-shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 6 | <circle cx="11" cy="11" r="8"/> |
| 7 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 8 | </svg> |
| 9 | <input type="text" value="xyz" readonly class="flex-1 bg-transparent border-none text-[#E0E0E0] text-sm outline-none" /> |
| 10 | </div> |
| 11 | <div class="flex flex-col items-center justify-center px-6 py-10 text-center gap-2.5"> |
| 12 | <svg class="w-10 h-10 text-[#555]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"> |
| 13 | <circle cx="11" cy="11" r="8"/> |
| 14 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 15 | </svg> |
| 16 | <p class="text-sm font-semibold text-[#E0E0E0] m-0"> |
| 17 | No results found |
| 18 | </p> |
| 19 | <p class="text-xs text-[#666] m-0"> |
| 20 | We couldn't find anything matching "xyz". |
| 21 | </p> |
| 22 | <button class="mt-1.5 px-4 py-2 rounded-md border border-[#2A2A2A] bg-[#151515] text-[#A0A0A0] text-xs font-medium hover:border-[#3A3A3A] hover:text-[#E0E0E0] hover:bg-[#1A1A1A] transition-all"> |
| 23 | Clear search |
| 24 | </button> |
| 25 | </div> |
| 26 | </div> |
| 27 | <div class="w-full bg-[#111] border border-[#2A2A3E] rounded-xl overflow-hidden shadow-2xl"> |
| 28 | <div class="flex items-center gap-2.5 px-4 py-3.5 border-b border-[#222]"> |
| 29 | <svg class="w-4 h-4 text-[#666] flex-shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 30 | <circle cx="11" cy="11" r="8"/> |
| 31 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 32 | </svg> |
| 33 | <input type="text" placeholder="Search..." class="flex-1 bg-transparent border-none text-[#E0E0E0] text-sm outline-none placeholder:text-[#555]" /> |
| 34 | </div> |
| 35 | <div class="flex flex-col items-center justify-center px-6 py-10 text-center gap-2.5"> |
| 36 | <svg class="w-8 h-8 text-[#EF4444]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"> |
| 37 | <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/> |
| 38 | <line x1="12" y1="9" x2="12" y2="13"/> |
| 39 | <line x1="12" y1="17" x2="12.01" y2="17"/> |
| 40 | </svg> |
| 41 | <p class="text-sm font-semibold text-[#E0E0E0] m-0"> |
| 42 | Search failed |
| 43 | </p> |
| 44 | <p class="text-xs text-[#666] m-0"> |
| 45 | Couldn't connect to the search service. |
| 46 | </p> |
| 47 | <button class="mt-1.5 px-4 py-2 rounded-md border border-[#2A2A2A] bg-[#151515] text-[#A0A0A0] text-xs font-medium hover:border-[#EF4444] hover:text-[#EF4444] hover:bg-[rgba(239,68,68,0.06)] transition-all"> |
| 48 | Retry |
| 49 | </button> |
| 50 | </div> |
| 51 | </div> |
| 52 | </div> |
| 53 | </div> |
| 1 | <div class="p-4 font-sans min-vh-50 d-flex justify-content-center bg-dark"> |
| 2 | <div class="d-flex flex-column gap-3 w-100" style="max-width:460px"> |
| 3 | <div class="card border-secondary bg-dark overflow-hidden" style="border-radius:12px;box-shadow:0 24px 64px rgba(0,0,0,.6)"> |
| 4 | <div class="card-header border-secondary bg-dark d-flex align-items-center gap-2 px-3 py-3"> |
| 5 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="text-secondary flex-shrink-0"> |
| 6 | <circle cx="11" cy="11" r="8"/> |
| 7 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 8 | </svg> |
| 9 | <input type="text" value="xyz" readonly class="form-control border-0 bg-transparent text-light shadow-none px-0" style="font-size:14px" /> |
| 10 | </div> |
| 11 | <div class="card-body d-flex flex-column align-items-center justify-content-center text-center gap-2 px-4 py-5"> |
| 12 | <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" class="text-secondary"> |
| 13 | <circle cx="11" cy="11" r="8"/> |
| 14 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 15 | </svg> |
| 16 | <p class="fw-semibold text-light m-0" style="font-size:14px"> |
| 17 | No results found |
| 18 | </p> |
| 19 | <p class="m-0" style="font-size:12px;color:#666"> |
| 20 | We couldn't find anything matching "xyz". |
| 21 | </p> |
| 22 | <button class="btn btn-dark border-secondary mt-1" style="font-size:12px;color:#A0A0A0;background:#151515"> |
| 23 | Clear search |
| 24 | </button> |
| 25 | </div> |
| 26 | </div> |
| 27 | <div class="card border-secondary bg-dark overflow-hidden" style="border-radius:12px;box-shadow:0 24px 64px rgba(0,0,0,.6)"> |
| 28 | <div class="card-header border-secondary bg-dark d-flex align-items-center gap-2 px-3 py-3"> |
| 29 | <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="text-secondary flex-shrink-0"> |
| 30 | <circle cx="11" cy="11" r="8"/> |
| 31 | <line x1="21" y1="21" x2="16.65" y2="16.65"/> |
| 32 | </svg> |
| 33 | <input type="text" class="form-control border-0 bg-transparent text-light shadow-none px-0" placeholder="Search..." style="font-size:14px" /> |
| 34 | </div> |
| 35 | <div class="card-body d-flex flex-column align-items-center justify-content-center text-center gap-2 px-4 py-5"> |
| 36 | <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" class="text-danger"> |
| 37 | <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/> |
| 38 | <line x1="12" y1="9" x2="12" y2="13"/> |
| 39 | <line x1="12" y1="17" x2="12.01" y2="17"/> |
| 40 | </svg> |
| 41 | <p class="fw-semibold text-light m-0" style="font-size:14px"> |
| 42 | Search failed |
| 43 | </p> |
| 44 | <p class="m-0" style="font-size:12px;color:#666"> |
| 45 | Couldn't connect to the search service. |
| 46 | </p> |
| 47 | <button class="btn btn-dark border-secondary mt-1" style="font-size:12px;color:#A0A0A0;background:#151515" onmouseover="this.style.borderColor='#EF4444';this.style.color='#EF4444'" onmouseout="this.style.borderColor='';this.style.color=''"> |
| 48 | Retry |
| 49 | </button> |
| 50 | </div> |
| 51 | </div> |
| 52 | </div> |
| 53 | </div> |
Command palettes are keyboard-first UI patterns, so accessibility is not optional. The palette must announce itself, trap focus, and expose the correct ARIA states to assistive technologies.
- Wrap the palette in a container with role="dialog" and aria-modal="true".
- Move focus to the search input immediately when the palette opens.
- Trap focus inside the palette while it is open; restore focus to the trigger on close.
- Use real <button> elements for results so they are keyboard-activatable.
- Highlight the active result visually and ensure screen readers can detect selection changes via a live region.
- Provide an accessible label for every icon-only control using aria-label.
- Announce result counts and empty states with an aria-live="polite" region.
- Respect the user's prefers-reduced-motion setting by disabling entrance animations.
- Use ⌘K / Ctrl+K as the universal trigger — users expect it across platforms.
- Trap focus inside the palette and restore it to the trigger element on close.
- Fuzzy-match search results using substring or Levenshtein distance for forgiving input.
- Group results by category with visible labels — don't mix unrelated items.
- Show keyboard shortcuts as badges next to each action — users learn by osmosis.
- Cap visible results at 8–10 items per group with scroll for overflow.
- Add a subtle backdrop blur and overlay to separate the palette from the page.
- Debounce search input (100–150ms) if results involve API calls.
- Use <mark> or background highlight on matched text segments for visual feedback.
- Provide a visible trigger button (e.g., "⌘K Search...") as a mouse fallback.
Community
Get help on Slack, Discord or VIP
Stuck on a guide? Join the community and ask.