ZDDC/shared/toast.css
ZDDC cb1456e55f feat(shared): sticky, dismissible, selectable toasts
Toasts now collect in a bottom-right stack. Error/warning toasts are STICKY —
they stay until dismissed so the user can read, select, and copy them while
troubleshooting (e.g. classifier scan errors); info/success still auto-dismiss
(opts.durationMs:0 forces sticky for any level). Each toast has a × to dismiss
it, a "Clear all" appears when 2+ are stacked, and the message text is
selectable/copyable. alert() maps to a sticky error toast.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 10:38:09 -05:00

111 lines
3.2 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* shared/toast.css — single-toast notification styles paired with
shared/toast.js. Uses BEM-ish .zddc-toast prefix to avoid collisions
with tool-local .toast classes; the old classifier rules can stay
alongside until this file is concatenated above them in the build. */
/* Toast STACK — bottom-right, newest at the bottom. The container is
click-through (pointer-events:none) so the gaps don't block the page; each
toast + button re-enables pointer events. */
.zddc-toasts {
position: fixed;
bottom: 1.5rem;
right: 1.5rem;
z-index: 9000;
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 0.5rem;
max-height: calc(100vh - 3rem);
overflow-y: auto;
pointer-events: none;
}
/* "Clear all" — shown above the stack when 2+ toasts are present. */
.zddc-toasts__clear {
pointer-events: auto;
align-self: flex-end;
background: var(--bg);
color: var(--text);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 0.2rem 0.6rem;
font-size: 0.78rem;
cursor: pointer;
}
.zddc-toasts__clear:hover { background: var(--bg-secondary, rgba(0, 0, 0, 0.05)); }
.zddc-toast {
position: relative;
pointer-events: auto;
background: var(--bg);
color: var(--text);
padding: 0.7rem 1.7rem 0.7rem 1rem; /* room for the × at top-right */
border-radius: var(--radius);
border: 1px solid var(--border);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
max-width: 420px;
font-size: 0.875rem;
animation: zddc-toast-in 0.3s ease-out;
}
/* Message text — selectable + copyable; long/multi-line errors wrap. */
.zddc-toast__msg {
user-select: text;
-webkit-user-select: text;
cursor: text;
white-space: pre-wrap;
word-break: break-word;
}
/* Per-toast dismiss. */
.zddc-toast__close {
position: absolute;
top: 0.2rem;
right: 0.35rem;
border: none;
background: transparent;
color: var(--text-muted, #888);
font-size: 1.15rem;
line-height: 1;
cursor: pointer;
padding: 0 0.15rem;
}
.zddc-toast__close:hover { color: var(--text); }
.zddc-toast--success { border-left: 4px solid var(--success); }
.zddc-toast--error { border-left: 4px solid var(--danger); }
.zddc-toast--info { border-left: 4px solid var(--info); }
.zddc-toast--warning { border-left: 4px solid var(--warning); }
.zddc-toast--fade {
animation: zddc-toast-out 0.3s ease-out forwards;
}
@keyframes zddc-toast-in {
from { transform: translateX(100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
@keyframes zddc-toast-out {
from { transform: translateX(0); opacity: 1; }
to { transform: translateX(100%); opacity: 0; }
}
/* Inline action button appended to a toast by zddc.cap.handleForbidden
when an Elevate path is offered. Stops click propagation on its own
so clicking the button doesn't also dismiss the toast. */
.zddc-toast__action {
display: inline-block;
margin-left: 0.75rem;
padding: 0.25rem 0.75rem;
background: var(--accent, var(--text));
color: var(--bg);
border: none;
border-radius: var(--radius);
font-size: 0.8125rem;
font-weight: 600;
cursor: pointer;
}
.zddc-toast__action:hover {
filter: brightness(1.1);
}