ZDDC/shared/toast.css
ZDDC b5b3c92905 feat(shared): cap.js client helpers for permission gating
Three small helpers under window.zddc.cap, wired into every tool's
build:

  cap.at(path)               — Promise<AccessView|null>. Fetches
                               /.profile/access?path=<urlpath> and
                               memoises per-path for the session.
                               Used by tools to gate top-of-page
                               affordances on path_verbs / path_is_admin
                               / path_can_elevate_grant.
  cap.has(node, verb)        — boolean. Reads the listing entry's
                               verbs string for the named verb.
                               Falls back to node.writable for 'w'
                               when verbs is absent (offline FS-API
                               listings or pre-promotion clients).
  cap.handleForbidden(resp,  — parses a 403 response's JSON body for
                  opts)        missing_verb and renders an error
                               toast. When opts.path is supplied AND
                               the path-scoped access view reports
                               path_can_elevate_grant covering the
                               missing verb, the toast appends an
                               "Elevate" button that flips the
                               elevation cookie and reloads.

Browse loader.js + tree.js carry the new verbs field through to the
node objects so context-menu gating can call cap.has(node, 'w'|'d')
without changing the legacy node.writable contract. New CSS rule
.zddc-toast__action styles the inline Elevate button.

Concatenation order: cap.js comes after toast.js + elevation.js so
the dependencies (window.zddc.toast, window.zddc.elevation) are
present at module-load time.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 08:42:05 -05:00

59 lines
1.8 KiB
CSS

/* 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. */
.zddc-toast {
position: fixed;
bottom: 2rem;
right: 2rem;
background: var(--bg);
color: var(--text);
padding: 0.875rem 1.25rem;
border-radius: var(--radius);
border: 1px solid var(--border);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
z-index: 9000;
max-width: 400px;
font-size: 0.875rem;
cursor: pointer;
animation: zddc-toast-in 0.3s ease-out;
}
.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);
}