/* * Command palette recipe — ⌘K command bar. * * [data-command] → root container (input + list) * [data-command-input] → search input * [data-command-list] → scrolling listbox * [data-command-viewport] → optional inner scroller (if List wraps it) * [data-command-empty] → "no results" message * [data-command-loading] → progress bar slot * [data-command-group] → group container * [data-command-group-heading]→ group label * [data-command-group-items] → group items wrapper * [data-command-item] → row (highlighted via data-selected) * [data-command-link-item] → anchor-style row * [data-command-separator] → 1px divider * [data-command-item-icon] → leading glyph slot (eidos sub-part) * [data-command-item-shortcut]→ trailing kbd hint slot (eidos sub-part) * * Sizes — sm | md | lg via `data-size` on [data-command]. * Inside `` the panel chrome comes from dialog.css; this * recipe only paints the inner palette. */ [data-command] { --_command-input-px: var(--space-3); --_command-input-font-size: var(--font-size-md); --_command-item-px: var(--space-3); --_command-item-font-size: var(--font-size-md); /* Radius of the surface the palette lives in — the concentric reference for the input (which sits at the surface's top corners). Inline that surface is the command's own panel (radius-lg, matching the combobox popup). Inside it's overridden to the dialog panel's radius so the input corner stays parallel to the ACTUAL outer corner. */ --_command-radius: var(--radius-lg); display: flex; flex-direction: column; inline-size: 100%; min-inline-size: 0; /* Typography is anchored on the root so EVERY descendant (item, group heading, icon, shortcut) inherits the UI font + leading regardless of context. Inside the palette is portaled, which severs the ambient page-font inheritance — without this the rows fall back to the browser serif (Times New Roman). Self-contained typography keeps the portaled dialog identical to the inline palette. */ font-family: var(--font-ui); line-height: var(--leading-ui); color: var(--color-content-primary); /* Elevation — surface · border · shadow — from the `overlay` plane via `data-depth` (A1). Inside the dialog panel is the surface, so the `[data-dialog-content] [data-command]` override below (higher specificity) strips the plane. Radius / overflow stay the panel's own. */ border-radius: var(--_command-radius); overflow: hidden; outline: none; } /* Inside a Dialog (``) the dialog panel IS the surface — strip ONLY the command's own panel chrome (border / bg / shadow) so the two panels don't nest. Everything else (the boxed input, the list padding, the type scale, the item rows) is inherited unchanged, so the palette is identical to the inline , just hosted inside the dialog panel. */ [data-dialog-content] [data-command] { /* The visible surface is now the dialog panel — adopt ITS radius so the input stays concentric with the actual outer corner the user sees. */ --_command-radius: var(--dialog-content-radius); border: 0; border-radius: 0; background: transparent; box-shadow: none; } /* The command brings its own internal spacing (input margin + list padding), so the dialog content adds none of its own. */ [data-dialog-content]:has([data-command]) { padding: 0; } /* Reserve room at the input's inline-end so the placeholder / query never runs under the floating close — which sits at the dialog's default top-right inset, centred on the boxed input row. */ [data-dialog-content] [data-command-input] { padding-inline-end: calc(var(--control-height-sm) + var(--space-2)); } [data-command][data-size='sm'] { --_command-input-px: var(--space-2); --_command-input-font-size: var(--font-size-sm); --_command-item-px: var(--space-2); --_command-item-font-size: var(--font-size-sm); } [data-command][data-size='lg'] { --_command-input-px: var(--space-4); --_command-input-font-size: var(--font-size-lg); --_command-item-px: var(--space-4); --_command-item-font-size: var(--font-size-lg); } /* ── Input ──────────────────────────────────────────────────────────── */ /* Boxed search field — same field treatment as the Select trigger (border + radius + surface bg + focus ring), inset from the panel edges, instead of the old flush borderless input with a bottom-rule separator. */ [data-command-input] { box-sizing: border-box; /* Same density-driven block padding as the options (archetype) so the input row and the option rows share one vertical rhythm. */ padding-block: var(--space-1-5); margin: var(--space-2); padding-inline: var(--_command-input-px); border: var(--border-width) solid var(--color-border-default); border-radius: var(--radius-md); background: var(--color-surface-default); color: var(--color-content-primary); font-family: var(--font-ui); font-size: var(--_command-input-font-size); line-height: var(--leading-ui); outline: 0; transition: border-color var(--duration-fast) var(--ease-default), box-shadow var(--duration-fast) var(--ease-default); } [data-command-input]:focus-visible { border-color: var(--color-primary-border); box-shadow: var(--focus-ring); } [data-command-input]::placeholder { color: var(--color-content-muted); } /* ── Loading progress (slim bar under Input) ───────────────────────── */ [data-command-loading] { display: block; block-size: 2px; background: linear-gradient( to right, var(--color-primary-solid) 0%, var(--color-primary-solid) var(--_command-loading-progress, 0%), transparent var(--_command-loading-progress, 0%) ); } /* ── List + Viewport ──────────────────────────────────────────────── */ /* The soma list is a transparent marker; the composed (command-list.svelte) owns the scroll + the design-system scrollbar, shared with select / combobox so the scroll chrome (incl. its colour) is common. */ [data-command-list] { display: contents; } [data-command-list] [data-scroll-area-viewport] { --scroll-area-auto-max-block: min(60vh, 24rem); display: flex; flex-direction: column; gap: var(--space-1); padding-inline: var(--space-1); padding-block-end: var(--space-1); overscroll-behavior: contain; } /* Reserve the scrollbar footprint + a matching inline gap when it shows. */ [data-command-list] [data-scroll-area]:has(> [data-scroll-area-scrollbar][data-orientation='vertical']) > [data-scroll-area-viewport] { padding-inline-end: calc(var(--space-1) + var(--space-3-5)); } [data-command-viewport] { display: flex; flex-direction: column; gap: var(--space-1); max-block-size: min(60vh, 24rem); padding: var(--space-1); overflow: auto; overscroll-behavior: contain; } /* ── Group / GroupHeading / GroupItems ────────────────────────────── */ [data-command-group] { display: grid; gap: var(--space-1); } [data-command-group-heading] { padding-block: var(--space-1); padding-inline: var(--_command-item-px); color: var(--color-content-muted); font-size: var(--font-size-xs); font-weight: 500; text-transform: uppercase; letter-spacing: var(--tracking-caps); } [data-command-group-items] { display: grid; gap: 1px; } /* ── Item / LinkItem ──────────────────────────────────────────────── */ [data-command-item], [data-command-link-item] { display: flex; align-items: center; gap: var(--space-2); padding-inline: var(--_command-item-px); /* Height + block padding come from the canonical archetype (density-driven `--space-*`). Radius concentric with the panel: panel radius − inset. */ border-radius: calc(var(--radius-md) - var(--space-1)); color: var(--color-content-primary); font-size: var(--_command-item-font-size); line-height: var(--leading-ui); text-decoration: none; cursor: pointer; user-select: none; transition: background var(--duration-fast) var(--ease-default), color var(--duration-fast) var(--ease-default); } /* The active-row highlight comes from the canonical archetype layer (archetypes.css), shared with select / combobox / listbox / menus. */ [data-command-item][data-disabled], [data-command-link-item][data-disabled] { cursor: default; opacity: var(--opacity-disabled); } /* ── Item sub-parts (eidos-only) ──────────────────────────────────── */ [data-command-item-icon] { display: inline-flex; flex: 0 0 auto; align-items: center; justify-content: center; inline-size: 1.125em; block-size: 1.125em; color: var(--color-content-secondary); } [data-command-item-shortcut] { display: inline-flex; flex: 0 0 auto; align-items: center; gap: var(--space-1); margin-inline-start: auto; color: var(--color-content-muted); font-size: 0.875em; } /* When the row is highlighted, lift the muted sub-parts to primary. */ [data-command-item][data-selected] [data-command-item-icon], [data-command-item][data-selected] [data-command-item-shortcut], [data-command-link-item][data-selected] [data-command-item-icon], [data-command-link-item][data-selected] [data-command-item-shortcut] { color: var(--color-content-primary); } /* ── Empty state ──────────────────────────────────────────────────── */ [data-command-empty] { padding-block: var(--space-4); padding-inline: var(--_command-item-px); color: var(--color-content-muted); font-size: var(--_command-item-font-size); text-align: center; } /* ── Separator ────────────────────────────────────────────────────── */ [data-command-separator] { block-size: 1px; margin-block: var(--space-1); background: var(--color-border-subtle); }