Adds a compact shortcuts row inside the composer panel for one-click
instruction queuing, with full lifecycle management stored in localStorage.
Features
--------
- Six built-in defaults (Stop, Summarize, Explain error, Undo, Continue, etc.)
- Click any chip → instantly POSTs to /api/instructions, no typing required
- Cyan border pulse on fire; green glow flash on success
- Edit mode (toggle button in header):
- Per-chip edit (✏) button → replaces chip with inline input, Enter to save
- Per-chip delete (✕) button → removes with vanish animation
- '+ Add' chip → inline form appended below rail
- All changes persisted to localStorage key 'local-mcp-shortcuts'
- Accessible: button elements, aria-labels, keyboard support (Enter/Escape)
Files
-----
- static/js/shortcuts.js new module (loadShortcuts, renderShortcuts,
startInlineEdit, showAddPrompt, initShortcuts)
- static/index.html #shortcuts-container inside composer .panel-body
- static/js/app.js import + initShortcuts() in bootstrap()
- static/css/components.css .shortcuts-container, .shortcut-chip variants,
.shortcut-inline-edit, keyframes chip-fire/sent/vanish
767 lines
19 KiB
CSS
767 lines
19 KiB
CSS
/*
|
||
* static/css/components.css
|
||
* Reusable UI components: buttons, inputs, badges, status indicators,
|
||
* instruction cards, and animations.
|
||
*/
|
||
|
||
/* ── Status indicator (LED dot) ─────────────────────────────────────────── */
|
||
|
||
.led {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: var(--space-2);
|
||
font-size: var(--text-xs);
|
||
font-weight: 700;
|
||
letter-spacing: 0.1em;
|
||
text-transform: uppercase;
|
||
}
|
||
|
||
.led__dot {
|
||
width: 8px;
|
||
height: 8px;
|
||
border-radius: 50%;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.led--green .led__dot { background: var(--green); box-shadow: 0 0 6px var(--green), 0 0 12px var(--green-glow); }
|
||
.led--amber .led__dot { background: var(--amber); box-shadow: 0 0 6px var(--amber), 0 0 12px var(--amber-glow); }
|
||
.led--red .led__dot { background: var(--red); box-shadow: 0 0 6px var(--red), 0 0 12px var(--red-glow); }
|
||
.led--muted .led__dot { background: var(--text-muted); box-shadow: none; }
|
||
.led--cyan .led__dot { background: var(--cyan); box-shadow: 0 0 6px var(--cyan), 0 0 12px var(--cyan-glow); }
|
||
|
||
.led--green .led__label { color: var(--green); }
|
||
.led--amber .led__label { color: var(--amber); }
|
||
.led--red .led__label { color: var(--red); }
|
||
.led--muted .led__label { color: var(--text-muted); }
|
||
.led--cyan .led__label { color: var(--cyan); }
|
||
|
||
/* Pulse for "connected" / "active" */
|
||
.led--pulse .led__dot {
|
||
animation: pulse 2.4s ease-in-out infinite;
|
||
}
|
||
|
||
@keyframes pulse {
|
||
0%, 100% { opacity: 1; transform: scale(1); }
|
||
50% { opacity: 0.5; transform: scale(0.85); }
|
||
}
|
||
|
||
/* ── Queue count badge ───────────────────────────────────────────────────── */
|
||
|
||
.badge {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
min-width: 20px;
|
||
height: 20px;
|
||
padding: 0 var(--space-2);
|
||
border-radius: 10px;
|
||
font-size: var(--text-xs);
|
||
font-weight: 700;
|
||
line-height: 1;
|
||
}
|
||
|
||
.badge--cyan { background: var(--cyan-glow); color: var(--cyan); border: 1px solid rgba(0,212,255,0.3); }
|
||
.badge--amber { background: var(--amber-glow); color: var(--amber); border: 1px solid rgba(255,190,11,0.3); }
|
||
.badge--muted { background: var(--bg-overlay); color: var(--text-muted); border: 1px solid var(--border-subtle); }
|
||
|
||
/* ── Buttons ─────────────────────────────────────────────────────────────── */
|
||
|
||
.btn {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: var(--space-2);
|
||
padding: var(--space-2) var(--space-4);
|
||
border: 1px solid transparent;
|
||
border-radius: var(--radius-md);
|
||
font-family: var(--font-ui);
|
||
font-size: var(--text-sm);
|
||
font-weight: 600;
|
||
letter-spacing: 0.04em;
|
||
cursor: pointer;
|
||
text-decoration: none;
|
||
transition:
|
||
background var(--duration-fast) var(--ease-in-out),
|
||
border-color var(--duration-fast) var(--ease-in-out),
|
||
box-shadow var(--duration-fast) var(--ease-in-out),
|
||
transform var(--duration-fast) var(--ease-in-out);
|
||
user-select: none;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.btn:disabled {
|
||
opacity: 0.4;
|
||
cursor: not-allowed;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.btn:active:not(:disabled) {
|
||
transform: scale(0.97);
|
||
}
|
||
|
||
/* Primary – cyan */
|
||
.btn--primary {
|
||
background: var(--cyan);
|
||
border-color: var(--cyan);
|
||
color: #000;
|
||
}
|
||
.btn--primary:hover {
|
||
background: #1de9ff;
|
||
box-shadow: 0 0 16px var(--cyan-glow);
|
||
}
|
||
|
||
/* Ghost */
|
||
.btn--ghost {
|
||
background: transparent;
|
||
border-color: var(--border-muted);
|
||
color: var(--text-secondary);
|
||
}
|
||
.btn--ghost:hover {
|
||
background: var(--bg-hover);
|
||
border-color: var(--border-strong);
|
||
color: var(--text-primary);
|
||
}
|
||
|
||
/* Danger */
|
||
.btn--danger {
|
||
background: transparent;
|
||
border-color: var(--red-dim);
|
||
color: var(--red);
|
||
}
|
||
.btn--danger:hover {
|
||
background: var(--red-glow);
|
||
border-color: var(--red);
|
||
}
|
||
|
||
/* Icon-only */
|
||
.btn--icon {
|
||
padding: var(--space-2);
|
||
width: 32px;
|
||
height: 32px;
|
||
border-radius: var(--radius-sm);
|
||
}
|
||
|
||
/* Small */
|
||
.btn--sm {
|
||
padding: var(--space-1) var(--space-3);
|
||
font-size: var(--text-xs);
|
||
height: 28px;
|
||
}
|
||
|
||
/* ── Form elements ──────────────────────────────────────────────────────── */
|
||
|
||
.input, .textarea {
|
||
width: 100%;
|
||
background: var(--bg-overlay);
|
||
border: 1px solid var(--border-muted);
|
||
border-radius: var(--radius-md);
|
||
color: var(--text-primary);
|
||
font-family: var(--font-mono);
|
||
font-size: var(--text-base);
|
||
padding: var(--space-3) var(--space-4);
|
||
transition:
|
||
border-color var(--duration-fast) var(--ease-in-out),
|
||
box-shadow var(--duration-fast) var(--ease-in-out);
|
||
outline: none;
|
||
resize: vertical;
|
||
}
|
||
|
||
.input::placeholder, .textarea::placeholder {
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.input:focus, .textarea:focus {
|
||
border-color: var(--cyan-dim);
|
||
box-shadow: 0 0 0 3px rgba(0,212,255,0.08);
|
||
}
|
||
|
||
.textarea {
|
||
min-height: 88px;
|
||
line-height: 1.6;
|
||
}
|
||
|
||
.form-group {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-2);
|
||
}
|
||
|
||
.form-row {
|
||
display: flex;
|
||
gap: var(--space-3);
|
||
align-items: flex-end;
|
||
}
|
||
|
||
.form-row .textarea { flex: 1; }
|
||
|
||
/* ── Instruction card ─────────────────────────────────────────────────────── */
|
||
|
||
.instruction-card {
|
||
padding: var(--space-4) var(--space-5);
|
||
border-bottom: 1px solid var(--border-subtle);
|
||
display: grid;
|
||
grid-template-columns: 1fr auto;
|
||
gap: var(--space-2) var(--space-4);
|
||
align-items: start;
|
||
transition: background var(--duration-fast) var(--ease-in-out);
|
||
animation: card-in var(--duration-slow) var(--ease-out-expo) both;
|
||
}
|
||
|
||
@keyframes card-in {
|
||
from { opacity: 0; transform: translateY(-8px); }
|
||
to { opacity: 1; transform: translateY(0); }
|
||
}
|
||
|
||
.instruction-card:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
.instruction-card:hover {
|
||
background: var(--bg-hover);
|
||
}
|
||
|
||
.instruction-card__meta {
|
||
grid-column: 1 / -1;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-4);
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.instruction-card__pos {
|
||
font-size: var(--text-xs);
|
||
font-weight: 700;
|
||
font-family: var(--font-mono);
|
||
color: var(--cyan);
|
||
background: var(--cyan-glow);
|
||
border: 1px solid rgba(0,212,255,0.25);
|
||
border-radius: var(--radius-sm);
|
||
padding: 1px 6px;
|
||
letter-spacing: 0.08em;
|
||
}
|
||
|
||
.instruction-card__content {
|
||
font-family: var(--font-mono);
|
||
font-size: var(--text-base);
|
||
line-height: 1.65;
|
||
color: var(--text-primary);
|
||
word-break: break-word;
|
||
white-space: pre-wrap;
|
||
}
|
||
|
||
.instruction-card__time {
|
||
font-size: var(--text-xs);
|
||
color: var(--text-muted);
|
||
font-family: var(--font-mono);
|
||
}
|
||
|
||
.instruction-card__actions {
|
||
display: flex;
|
||
gap: var(--space-2);
|
||
align-items: center;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
/* Edit mode */
|
||
.instruction-card__edit-area {
|
||
grid-column: 1 / -1;
|
||
display: flex;
|
||
gap: var(--space-3);
|
||
align-items: flex-end;
|
||
margin-top: var(--space-2);
|
||
}
|
||
|
||
.instruction-card__edit-area .textarea {
|
||
flex: 1;
|
||
min-height: 72px;
|
||
}
|
||
|
||
/* Consumed card */
|
||
.instruction-card--consumed {
|
||
opacity: 0.45;
|
||
}
|
||
|
||
.instruction-card--consumed .instruction-card__content {
|
||
text-decoration: line-through;
|
||
text-decoration-color: var(--amber-dim);
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
.instruction-card--consumed .instruction-card__pos {
|
||
background: var(--amber-glow);
|
||
border-color: rgba(255,190,11,0.2);
|
||
color: var(--amber);
|
||
}
|
||
|
||
.instruction-card--consumed:hover {
|
||
opacity: 0.65;
|
||
}
|
||
|
||
.instruction-card__consumed-by {
|
||
font-size: var(--text-xs);
|
||
color: var(--amber);
|
||
font-family: var(--font-mono);
|
||
}
|
||
|
||
/* ── Empty state ─────────────────────────────────────────────────────────── */
|
||
|
||
.empty-state {
|
||
padding: var(--space-10) var(--space-6);
|
||
text-align: center;
|
||
color: var(--text-muted);
|
||
font-size: var(--text-sm);
|
||
letter-spacing: 0.04em;
|
||
}
|
||
|
||
.empty-state__icon {
|
||
font-size: 1.5rem;
|
||
margin-bottom: var(--space-3);
|
||
opacity: 0.4;
|
||
}
|
||
|
||
/* ── Status panel items ──────────────────────────────────────────────────── */
|
||
|
||
.stat-row {
|
||
display: flex;
|
||
align-items: baseline;
|
||
justify-content: space-between;
|
||
padding: var(--space-2) 0;
|
||
border-bottom: 1px solid var(--border-subtle);
|
||
}
|
||
|
||
.stat-row:last-child { border-bottom: none; }
|
||
|
||
.stat-label {
|
||
font-size: var(--text-xs);
|
||
font-weight: 700;
|
||
letter-spacing: 0.1em;
|
||
text-transform: uppercase;
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
.stat-value {
|
||
font-family: var(--font-mono);
|
||
font-size: var(--text-sm);
|
||
color: var(--text-primary);
|
||
}
|
||
|
||
.stat-value--cyan { color: var(--cyan); }
|
||
.stat-value--amber { color: var(--amber); }
|
||
|
||
/* ── Config form ─────────────────────────────────────────────────────────── */
|
||
|
||
.config-field {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-1);
|
||
margin-bottom: var(--space-4);
|
||
}
|
||
|
||
.config-field:last-child { margin-bottom: 0; }
|
||
|
||
.config-label {
|
||
font-size: var(--text-xs);
|
||
font-weight: 700;
|
||
letter-spacing: 0.1em;
|
||
text-transform: uppercase;
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
.config-hint {
|
||
font-size: var(--text-xs);
|
||
color: var(--text-muted);
|
||
margin-top: var(--space-1);
|
||
}
|
||
|
||
.input--sm {
|
||
padding: var(--space-2) var(--space-3);
|
||
font-size: var(--text-sm);
|
||
}
|
||
|
||
/* ── Toast notification ──────────────────────────────────────────────────── */
|
||
|
||
#toast-container {
|
||
position: fixed;
|
||
bottom: var(--space-6);
|
||
right: var(--space-6);
|
||
z-index: 9999;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-2);
|
||
pointer-events: none;
|
||
}
|
||
|
||
.toast {
|
||
background: var(--bg-overlay);
|
||
border: 1px solid var(--border-strong);
|
||
border-radius: var(--radius-md);
|
||
padding: var(--space-3) var(--space-5);
|
||
font-size: var(--text-sm);
|
||
color: var(--text-primary);
|
||
box-shadow: var(--shadow-lg);
|
||
animation: toast-in var(--duration-normal) var(--ease-out-expo) both;
|
||
pointer-events: auto;
|
||
max-width: 320px;
|
||
}
|
||
|
||
.toast--success { border-color: var(--green-dim); color: var(--green); }
|
||
.toast--error { border-color: var(--red-dim); color: var(--red); }
|
||
.toast--info { border-color: var(--cyan-dim); color: var(--cyan); }
|
||
|
||
@keyframes toast-in {
|
||
from { opacity: 0; transform: translateY(12px) scale(0.95); }
|
||
to { opacity: 1; transform: translateY(0) scale(1); }
|
||
}
|
||
|
||
@keyframes toast-out {
|
||
from { opacity: 1; transform: translateY(0) scale(1); }
|
||
to { opacity: 0; transform: translateY(4px) scale(0.97); }
|
||
}
|
||
|
||
/* ── Theme toggle (header) ────────────────────────────────────────────────── */
|
||
|
||
#theme-toggle {
|
||
color: var(--text-secondary);
|
||
border-color: transparent;
|
||
transition: color var(--duration-fast) var(--ease-in-out),
|
||
background var(--duration-fast) var(--ease-in-out);
|
||
}
|
||
|
||
#theme-toggle:hover {
|
||
color: var(--text-primary);
|
||
background: var(--bg-hover);
|
||
border-color: var(--border-subtle);
|
||
}
|
||
|
||
/* ── SVG icons ───────────────────────────────────────────────────────────── */
|
||
|
||
.icon {
|
||
width: 16px;
|
||
height: 16px;
|
||
flex-shrink: 0;
|
||
stroke-width: 2;
|
||
stroke: currentColor;
|
||
fill: none;
|
||
stroke-linecap: round;
|
||
stroke-linejoin: round;
|
||
}
|
||
|
||
.icon--sm { width: 12px; height: 12px; }
|
||
|
||
/* ── Page load animation ─────────────────────────────────────────────────── */
|
||
|
||
.fade-in {
|
||
animation: fade-in var(--duration-slow) var(--ease-out-expo) both;
|
||
}
|
||
|
||
.fade-in--delay-1 { animation-delay: 60ms; }
|
||
.fade-in--delay-2 { animation-delay: 120ms; }
|
||
.fade-in--delay-3 { animation-delay: 200ms; }
|
||
.fade-in--delay-4 { animation-delay: 300ms; }
|
||
|
||
@keyframes fade-in {
|
||
from { opacity: 0; transform: translateY(10px); }
|
||
to { opacity: 1; transform: translateY(0); }
|
||
}
|
||
|
||
/* ── Loading spinner ─────────────────────────────────────────────────────── */
|
||
|
||
.spinner {
|
||
display: inline-block;
|
||
width: 14px;
|
||
height: 14px;
|
||
border: 2px solid var(--border-muted);
|
||
border-top-color: var(--cyan);
|
||
border-radius: 50%;
|
||
animation: spin 0.7s linear infinite;
|
||
}
|
||
|
||
@keyframes spin {
|
||
to { transform: rotate(360deg); }
|
||
}
|
||
|
||
/* ── Auth overlay ─────────────────────────────────────────────────────────── */
|
||
|
||
.auth-overlay {
|
||
position: fixed;
|
||
inset: 0;
|
||
z-index: 9000;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: rgba(0, 0, 0, 0.72);
|
||
backdrop-filter: blur(6px);
|
||
-webkit-backdrop-filter: blur(6px);
|
||
}
|
||
|
||
.auth-card {
|
||
width: 100%;
|
||
max-width: 380px;
|
||
margin: var(--space-4);
|
||
padding: var(--space-8);
|
||
background: var(--surface-raised);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-lg);
|
||
box-shadow: 0 32px 64px rgba(0, 0, 0, 0.48);
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: var(--space-4);
|
||
text-align: center;
|
||
}
|
||
|
||
.auth-card__icon {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 64px;
|
||
height: 64px;
|
||
border-radius: 50%;
|
||
background: color-mix(in srgb, var(--cyan) 10%, transparent);
|
||
border: 1px solid color-mix(in srgb, var(--cyan) 25%, transparent);
|
||
margin-bottom: var(--space-2);
|
||
}
|
||
|
||
.auth-card__title {
|
||
font-family: var(--font-display);
|
||
font-size: var(--text-lg);
|
||
font-weight: 700;
|
||
color: var(--text-primary);
|
||
margin: 0;
|
||
}
|
||
|
||
.auth-card__desc {
|
||
font-size: var(--text-sm);
|
||
color: var(--text-muted);
|
||
margin: 0;
|
||
line-height: 1.6;
|
||
}
|
||
|
||
.auth-card__desc code {
|
||
font-family: var(--font-mono);
|
||
font-size: 0.9em;
|
||
color: var(--cyan);
|
||
background: color-mix(in srgb, var(--cyan) 10%, transparent);
|
||
padding: 1px 5px;
|
||
border-radius: 3px;
|
||
}
|
||
|
||
.auth-card__form {
|
||
width: 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-3);
|
||
}
|
||
|
||
.auth-card__error {
|
||
font-size: var(--text-xs);
|
||
color: var(--red);
|
||
margin: 0;
|
||
}
|
||
|
||
/* ── Quick shortcuts ─────────────────────────────────────────────────────── */
|
||
|
||
.shortcuts-container {
|
||
margin-top: var(--space-3);
|
||
border-top: 1px solid var(--border-subtle);
|
||
padding-top: var(--space-3);
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-2);
|
||
}
|
||
|
||
.shortcuts-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: var(--space-3);
|
||
}
|
||
|
||
.shortcuts-label {
|
||
font-family: var(--font-ui);
|
||
font-size: var(--text-xs);
|
||
font-weight: 700;
|
||
letter-spacing: 0.12em;
|
||
text-transform: uppercase;
|
||
color: var(--text-muted);
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.shortcut-edit-toggle {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: var(--space-1);
|
||
padding: 2px var(--space-2);
|
||
background: none;
|
||
border: 1px solid var(--border-subtle);
|
||
border-radius: var(--radius-sm);
|
||
font-family: var(--font-ui);
|
||
font-size: var(--text-xs);
|
||
font-weight: 600;
|
||
letter-spacing: 0.06em;
|
||
color: var(--text-muted);
|
||
cursor: pointer;
|
||
transition: border-color 150ms, color 150ms;
|
||
}
|
||
.shortcut-edit-toggle:hover {
|
||
border-color: var(--border-strong);
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
.shortcuts-rail {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: var(--space-2);
|
||
min-height: 28px;
|
||
}
|
||
|
||
/* Individual shortcut chip */
|
||
.shortcut-chip {
|
||
position: relative;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: var(--space-1);
|
||
max-width: 220px;
|
||
padding: 4px var(--space-3);
|
||
background: var(--bg-overlay);
|
||
border: 1px solid var(--border-muted);
|
||
border-radius: 4px;
|
||
font-family: var(--font-mono);
|
||
font-size: var(--text-xs);
|
||
font-weight: 400;
|
||
color: var(--text-secondary);
|
||
cursor: pointer;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
transition: border-color 140ms ease, color 140ms ease,
|
||
background 140ms ease, transform 80ms ease;
|
||
user-select: none;
|
||
}
|
||
|
||
.shortcut-chip:hover {
|
||
border-color: var(--cyan-dim);
|
||
color: var(--text-primary);
|
||
background: var(--bg-hover);
|
||
}
|
||
|
||
.shortcut-chip:active {
|
||
transform: scale(0.95);
|
||
}
|
||
|
||
.shortcut-chip__text {
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
|
||
/* Delete handle (shown in edit mode) */
|
||
.shortcut-chip__del {
|
||
display: none; /* toggled via JS */
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 14px;
|
||
height: 14px;
|
||
flex-shrink: 0;
|
||
border-radius: 50%;
|
||
background: var(--red-dim);
|
||
color: var(--red);
|
||
transition: background 120ms;
|
||
}
|
||
.shortcut-chip:hover .shortcut-chip__del {
|
||
background: var(--red);
|
||
color: #fff;
|
||
}
|
||
|
||
/* Edit handle (shown in edit mode) */
|
||
.shortcut-chip__edit {
|
||
display: none; /* toggled via JS */
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 14px;
|
||
height: 14px;
|
||
flex-shrink: 0;
|
||
border-radius: 50%;
|
||
background: var(--border-muted);
|
||
color: var(--text-secondary);
|
||
transition: background 120ms;
|
||
}
|
||
.shortcut-chip:hover .shortcut-chip__edit {
|
||
background: var(--cyan-dim);
|
||
color: var(--cyan);
|
||
}
|
||
|
||
/* Inline chip edit row */
|
||
.shortcut-inline-edit {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: var(--space-2);
|
||
animation: chip-fire 160ms ease;
|
||
}
|
||
.shortcut-inline-input {
|
||
width: 180px;
|
||
padding: 3px var(--space-2);
|
||
font-size: var(--text-xs);
|
||
height: 26px;
|
||
}
|
||
|
||
/* Firing state (just clicked) */
|
||
.shortcut-chip--firing {
|
||
border-color: var(--cyan);
|
||
color: var(--cyan);
|
||
animation: chip-fire 280ms ease;
|
||
}
|
||
|
||
/* Sent confirmation flash */
|
||
.shortcut-chip--sent {
|
||
border-color: var(--green);
|
||
color: var(--green);
|
||
animation: chip-sent 600ms ease;
|
||
}
|
||
|
||
/* Add chip */
|
||
.shortcut-chip--add {
|
||
border-style: dashed;
|
||
border-color: var(--border-subtle);
|
||
color: var(--text-muted);
|
||
gap: var(--space-1);
|
||
padding: 4px var(--space-2);
|
||
}
|
||
.shortcut-chip--add:hover {
|
||
border-color: var(--cyan-dim);
|
||
color: var(--cyan);
|
||
}
|
||
|
||
/* Chip animations */
|
||
@keyframes chip-fire {
|
||
0% { transform: scale(1); }
|
||
40% { transform: scale(0.93); }
|
||
100% { transform: scale(1); }
|
||
}
|
||
|
||
@keyframes chip-sent {
|
||
0% { box-shadow: 0 0 0 0 var(--green-glow); }
|
||
50% { box-shadow: 0 0 0 6px transparent; }
|
||
100% { box-shadow: none; }
|
||
}
|
||
|
||
@keyframes chip-vanish {
|
||
to { opacity: 0; transform: scale(0.8); width: 0; padding: 0; margin: 0; }
|
||
}
|
||
|
||
/* Add shortcut inline form */
|
||
.shortcut-add-form {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: var(--space-2);
|
||
padding-top: var(--space-2);
|
||
border-top: 1px solid var(--border-subtle);
|
||
margin-top: var(--space-1);
|
||
animation: fade-in-up 180ms ease;
|
||
}
|
||
|
||
.shortcut-add-actions {
|
||
display: flex;
|
||
gap: var(--space-2);
|
||
}
|