diff --git a/frontend/packages/dashboard/src/common.css b/frontend/packages/dashboard/src/common.css index cfe2adc8..ea353cbe 100644 --- a/frontend/packages/dashboard/src/common.css +++ b/frontend/packages/dashboard/src/common.css @@ -4,6 +4,7 @@ @import "@hive/shared/terminal.css"; @import "@hive/shared/tabs.css"; @import "@hive/shared/chrome.css"; +@import "./modal.css"; /* ─── global typography ───────────────────────────────────────────── Element-level rules shared across all three pages (index, flow, diff --git a/frontend/packages/dashboard/src/dashboard.css b/frontend/packages/dashboard/src/dashboard.css index 0f80eee4..d53825a6 100644 --- a/frontend/packages/dashboard/src/dashboard.css +++ b/frontend/packages/dashboard/src/dashboard.css @@ -414,113 +414,6 @@ body.dashboard-shell { } .container-row .actions form.inline { display: inline-block; margin: 0; } -/* Themed confirm modal — `themedConfirm()` in common.js. In-theme replacement - for the native confirm() on destructive actions (stop / restart / destroy), - carrying the optional "stop gracefully" checkbox. */ -.tc-backdrop { - position: fixed; - inset: 0; - z-index: 1000; - display: flex; - align-items: center; - justify-content: center; - padding: 1em; - background: color-mix(in srgb, var(--crust) 60%, transparent); - -webkit-backdrop-filter: blur(2px); - backdrop-filter: blur(2px); -} -.tc-box { - background: var(--bg-elev); - border: 1px solid var(--purple-dim); - box-shadow: 0 8px 40px -8px var(--crust); - padding: 1.2em 1.4em; - max-width: min(32em, 92vw); - display: flex; - flex-direction: column; - gap: 0.9em; -} -.tc-title { - font-weight: bold; - text-transform: uppercase; - letter-spacing: 0.08em; - color: var(--subtext0); -} -.tc-message { color: var(--fg); line-height: 1.45; } -.tc-checks { display: flex; flex-direction: column; gap: 0.4em; } -.tc-checkrow { - display: flex; - align-items: flex-start; - gap: 0.5em; - cursor: pointer; - color: var(--subtext0); - font-size: 0.92em; - line-height: 1.35; -} -.tc-checkrow .tc-check { margin-top: 0.2em; flex: 0 0 auto; } -.tc-actions { - display: flex; - justify-content: flex-end; - gap: 0.6em; - margin-top: 0.2em; -} -.tc-cancel { color: var(--subtext0); } -.tc-confirm { color: var(--green); } -.tc-confirm.tc-danger { color: var(--red); } - -/* themedPrompt input field */ -.tc-promptfield { display: flex; flex-direction: column; gap: 0.4em; } -.tc-promptlabel { color: var(--subtext0); font-size: 0.9em; } -.tc-input { - font-family: inherit; - font-size: 1em; - width: 100%; - box-sizing: border-box; - background: var(--crust); - color: var(--fg); - border: 1px solid var(--purple-dim); - padding: 0.4em 0.6em; -} -.tc-input:focus { outline: 1px solid var(--green); } -/* themedPrompt's field is always a resizable textarea (Enter submits, - Shift+Enter inserts a newline) — sensible min-height, wrapped output. */ -.tc-textarea { - resize: vertical; - min-height: 4.5em; - line-height: 1.4; - white-space: pre-wrap; -} - -/* themedToast — non-blocking transient notifications (errors/info/ok) */ -.tc-toasts { - position: fixed; - top: 1em; - right: 1em; - z-index: 1100; - display: flex; - flex-direction: column; - gap: 0.5em; - max-width: min(28em, 92vw); - pointer-events: none; -} -.tc-toast { - pointer-events: auto; - cursor: pointer; - background: var(--bg-elev); - border: 1px solid var(--purple-dim); - border-left-width: 3px; - box-shadow: 0 4px 20px -6px var(--crust); - padding: 0.6em 0.9em; - font-size: 0.9em; - color: var(--fg); - white-space: pre-wrap; - opacity: 1; - transition: opacity 0.2s ease, transform 0.2s ease; -} -.tc-toast-out { opacity: 0; transform: translateX(0.5em); } -.tc-toast-error { border-left-color: var(--red); } -.tc-toast-info { border-left-color: var(--purple-dim); } -.tc-toast-ok { border-left-color: var(--green); } - .agent-status { font-size: 0.82em; color: var(--subtext0); diff --git a/frontend/packages/dashboard/src/modal.css b/frontend/packages/dashboard/src/modal.css new file mode 100644 index 00000000..31318c18 --- /dev/null +++ b/frontend/packages/dashboard/src/modal.css @@ -0,0 +1,111 @@ +/* modal.css — themed dialog component styles. + Pairs with modal.js (themedConfirm / themedPrompt / themedToast). The + dialogs are raised from common.js's data-async / data-confirm handler, + which every page loads, so common.css @imports this to keep the styles + present wherever a dialog can fire — not just the main dashboard. + (Previously these rules lived in dashboard.css, so dialogs rendered + unstyled on standalone pages such as /core.) */ + +.tc-backdrop { + position: fixed; + inset: 0; + z-index: 1000; + display: flex; + align-items: center; + justify-content: center; + padding: 1em; + background: color-mix(in srgb, var(--crust) 60%, transparent); + -webkit-backdrop-filter: blur(2px); + backdrop-filter: blur(2px); +} +.tc-box { + background: var(--bg-elev); + border: 1px solid var(--purple-dim); + box-shadow: 0 8px 40px -8px var(--crust); + padding: 1.2em 1.4em; + max-width: min(32em, 92vw); + display: flex; + flex-direction: column; + gap: 0.9em; +} +.tc-title { + font-weight: bold; + text-transform: uppercase; + letter-spacing: 0.08em; + color: var(--subtext0); +} +.tc-message { color: var(--fg); line-height: 1.45; } +.tc-checks { display: flex; flex-direction: column; gap: 0.4em; } +.tc-checkrow { + display: flex; + align-items: flex-start; + gap: 0.5em; + cursor: pointer; + color: var(--subtext0); + font-size: 0.92em; + line-height: 1.35; +} +.tc-checkrow .tc-check { margin-top: 0.2em; flex: 0 0 auto; } +.tc-actions { + display: flex; + justify-content: flex-end; + gap: 0.6em; + margin-top: 0.2em; +} +.tc-cancel { color: var(--subtext0); } +.tc-confirm { color: var(--green); } +.tc-confirm.tc-danger { color: var(--red); } + +/* themedPrompt input field */ +.tc-promptfield { display: flex; flex-direction: column; gap: 0.4em; } +.tc-promptlabel { color: var(--subtext0); font-size: 0.9em; } +.tc-input { + font-family: inherit; + font-size: 1em; + width: 100%; + box-sizing: border-box; + background: var(--crust); + color: var(--fg); + border: 1px solid var(--purple-dim); + padding: 0.4em 0.6em; +} +.tc-input:focus { outline: 1px solid var(--green); } +/* themedPrompt's field is always a resizable textarea (Enter submits, + Shift+Enter inserts a newline) — sensible min-height, wrapped output. */ +.tc-textarea { + resize: vertical; + min-height: 4.5em; + line-height: 1.4; + white-space: pre-wrap; +} + +/* themedToast — non-blocking transient notifications (errors/info/ok) */ +.tc-toasts { + position: fixed; + top: 1em; + right: 1em; + z-index: 1100; + display: flex; + flex-direction: column; + gap: 0.5em; + max-width: min(28em, 92vw); + pointer-events: none; +} +.tc-toast { + pointer-events: auto; + cursor: pointer; + background: var(--bg-elev); + border: 1px solid var(--purple-dim); + border-left-width: 3px; + box-shadow: 0 4px 20px -6px var(--crust); + padding: 0.6em 0.9em; + font-size: 0.9em; + color: var(--fg); + white-space: pre-wrap; + opacity: 1; + transition: opacity 0.2s ease, transform 0.2s ease; +} +.tc-toast-out { opacity: 0; transform: translateX(0.5em); } +.tc-toast-error { border-left-color: var(--red); } +.tc-toast-info { border-left-color: var(--purple-dim); } +.tc-toast-ok { border-left-color: var(--green); }