Overlays

Modal panels on a navy scrim (DS-012), multi-step headers, toasts, popover menus, tooltips and inline notices. Layering follows the z-index ladder (DS-013).

Modal

Use a native <dialog>: showModal() gives the scrim via ::backdrop, focus trapping and Escape for free. The same classes work on a div inside .saga-scrim.

Edit Session

<button class="saga-btn" onclick="document.getElementById('demo-dialog').showModal()">Open Edit Session</button>
<button class="saga-btn saga-btn--secondary" onclick="document.getElementById('demo-steps-dialog').showModal()">Open Configure Period</button>
<dialog class="saga-modal" id="demo-dialog" aria-labelledby="demo-dialog-title">
	<form method="dialog" style="display:contents">
		<div class="saga-modal__header">
			<h2 class="saga-modal__title" id="demo-dialog-title">Edit Session</h2>
			<button class="saga-btn saga-btn--quiet saga-btn--icon saga-modal__close" aria-label="Close" value="cancel"><iconify-icon icon="material-symbols-light:close-rounded"></iconify-icon></button>
		</div>
		<div class="saga-modal__body">
			<div class="saga-field"><label class="saga-label" for="m-title">Session Title</label><input class="saga-input" id="m-title" value="Out Of Window Test - Early"></div>
		</div>
		<div class="saga-modal__footer">
			<div class="saga-modal__footer-end">
				<button class="saga-btn saga-btn--secondary" value="cancel">Cancel</button>
				<button class="saga-btn" value="save">Save</button>
				<button class="saga-btn saga-btn--danger" value="delete">Delete</button>
			</div>
		</div>
	</form>
</dialog>

Shown inline

<div class="saga-modal" role="dialog" aria-labelledby="inl-title" aria-modal="true" style="margin:0 auto">
	<div class="saga-modal__header">
		<h2 class="saga-modal__title" id="inl-title">Edit Session</h2>
		<button class="saga-btn saga-btn--quiet saga-btn--icon saga-modal__close" aria-label="Close"><iconify-icon icon="material-symbols-light:close-rounded"></iconify-icon></button>
	</div>
	<div class="saga-modal__body">
		<div class="saga-field"><label class="saga-label" for="m2-title">Session Title</label><input class="saga-input" id="m2-title" value="Out Of Window Test - Early"></div>
	</div>
	<div class="saga-modal__footer">
		<div class="saga-modal__footer-end">
			<button class="saga-btn saga-btn--secondary">Cancel</button>
			<button class="saga-btn">Save</button>
			<button class="saga-btn saga-btn--danger">Delete</button>
		</div>
	</div>
</div>

Confirm dialog

.saga-modal--confirm is 440px: a question for a title, one secondary paragraph, two buttons, role="alertdialog", the safe button focused first. Caution confirms use .saga-btn--caution (--color-warning-strong) and a --color-warning-border top edge.

Delete this session?

Students will lose their place in Pod 6. This cannot be undone.

<dialog class="saga-modal saga-modal--confirm" id="demo-confirm" aria-labelledby="dc-title">
	<form method="dialog" style="display:contents">
		<div class="saga-modal__header"><h2 class="saga-modal__title" id="dc-title">Delete this session?</h2></div>
		<div class="saga-modal__body"><p class="text-secondary">Students will lose their place in Pod 6. This cannot be undone.</p></div>
		<div class="saga-modal__footer"><div class="saga-modal__footer-end"><button class="saga-btn saga-btn--secondary" value="cancel" autofocus>Cancel</button><button class="saga-btn saga-btn--danger" value="delete">Delete session</button></div></div>
	</form>
</dialog>

Shown inline: danger and caution

Delete this session?

Students will lose their place in Pod 6. This cannot be undone.

Move 3 students to Pod 2?

They keep their attendance history. Their current tutor will see the change on the next schedule refresh.

<div class="saga-modal saga-modal--confirm" role="alertdialog" aria-modal="true" aria-labelledby="cf-title" aria-describedby="cf-body" style="margin:0 auto">
	<div class="saga-modal__header"><h2 class="saga-modal__title" id="cf-title">Delete this session?</h2></div>
	<div class="saga-modal__body"><p class="text-secondary" id="cf-body">Students will lose their place in Pod 6. This cannot be undone.</p></div>
	<div class="saga-modal__footer">
		<div class="saga-modal__footer-end">
			<button class="saga-btn saga-btn--secondary">Cancel</button>
			<button class="saga-btn saga-btn--danger">Delete session</button>
		</div>
	</div>
</div>
<div class="saga-modal saga-modal--confirm" role="alertdialog" aria-modal="true" aria-labelledby="cf2-title" style="margin:0 auto;border-top:var(--space-xs) solid var(--color-warning-border)">
	<div class="saga-modal__header"><h2 class="saga-modal__title" id="cf2-title">Move 3 students to Pod 2?</h2></div>
	<div class="saga-modal__body"><p class="text-secondary">They keep their attendance history. Their current tutor will see the change on the next schedule refresh.</p></div>
	<div class="saga-modal__footer">
		<div class="saga-modal__footer-end">
			<button class="saga-btn saga-btn--secondary">Never mind</button>
			<button class="saga-btn saga-btn--caution">Yes, move them</button>
		</div>
	</div>
</div>

Framed shell with a local scrim and toast stack

A .saga-shell--framed fills its positioned frame instead of the viewport (a decision-board scene, a preview). Inside it, .saga-scrim--local and .saga-toast-stack--local are absolute to the frame, so overlays stay in the scene. A native <dialog> always goes to the top layer, so a framed scene uses the div form (DS-118).

Demo Program 08/17

A framed shell: the scrim and toast stack stay inside this box.

Discard changes?

Your edits to Period 1 will be lost.

Period 2 saved.
<div class="demo-frame">
	<div class="saga-shell saga-shell--framed">
		<nav class="saga-nav" aria-label="Scene nav"><div class="saga-nav__logo"></div><ul class="saga-nav__items"><li><a class="saga-nav__item" href="#" aria-current="page"><iconify-icon icon="material-symbols-light:calendar-month-outline-rounded"></iconify-icon> Sessions</a></li></ul></nav>
		<div class="saga-shell__main">
			<header class="saga-topbar"><h1 class="saga-topbar__title">Demo Program 08/17</h1></header>
			<main class="saga-page"><p class="text-secondary">A framed shell: the scrim and toast stack stay inside this box.</p></main>
		</div>
		<div class="saga-scrim saga-scrim--local">
			<div class="saga-modal saga-modal--confirm" role="alertdialog" aria-modal="true" aria-labelledby="cf3-title">
				<div class="saga-modal__header"><h2 class="saga-modal__title" id="cf3-title">Discard changes?</h2></div>
				<div class="saga-modal__body"><p class="text-secondary">Your edits to Period 1 will be lost.</p></div>
				<div class="saga-modal__footer"><div class="saga-modal__footer-end"><button class="saga-btn saga-btn--secondary">Keep editing</button><button class="saga-btn saga-btn--danger">Discard</button></div></div>
			</div>
		</div>
		<div class="saga-toast-stack saga-toast-stack--local"><div class="saga-toast saga-toast--success" role="status"><span class="saga-toast__msg">Period 2 saved.</span></div></div>
	</div>
</div>

Steps header

A multi-step modal puts .saga-steps directly under the header. Numbers are auto-counted when .saga-step__num is empty; aria-current="step" marks the active step, data-complete a finished one.

<div class="saga-modal saga-modal--large" role="dialog" aria-labelledby="st-title" aria-modal="true" style="margin:0 auto">
	<div class="saga-modal__header">
		<h2 class="saga-modal__title" id="st-title"><em>Period 2</em> &nbsp;|&nbsp; Configure Period</h2>
		<button class="saga-btn saga-btn--quiet saga-btn--icon saga-modal__close" aria-label="Close"><iconify-icon icon="material-symbols-light:close-rounded"></iconify-icon></button>
	</div>
	<ol class="saga-steps">
		<li class="saga-step" aria-current="step"><span class="saga-step__num"></span> Configure Period</li>
		<li class="saga-step"><span class="saga-step__num"></span> Build Pods</li>
	</ol>
	<div class="saga-modal__body">
		<p class="text-secondary">Step content goes here.</p>
	</div>
	<div class="saga-modal__footer">
		<div class="saga-modal__footer-end">
			<button class="saga-btn saga-btn--secondary">Cancel</button>
			<button class="saga-btn">Continue</button>
		</div>
	</div>
</div>

Period 2  |  Configure Period

  1. Configure Period
  2. 2 Build Pods

Step 2 content.

Toasts

Bottom-right stack, navy surface, a 4px colored left edge (DS-102, DS-115). Dwell is 3500ms + 50ms per character, clamped to 4–15s. Enter and exit animate opacity and transform only; under reduced motion the rise collapses and the fade stays.

<button class="saga-btn saga-btn--secondary" onclick="showToast('Roster uploaded.', 'success')">Success toast</button>
<button class="saga-btn saga-btn--secondary" onclick="showToast('Session saved without a period — it will not appear on the schedule.', 'warning', 'Undo')">Warning with action</button>
<button class="saga-btn saga-btn--secondary" onclick="showToast('Could not reach the server. Your changes were not saved.', 'danger')">Danger toast</button>
<button class="saga-btn saga-btn--secondary" onclick="showToast('You have 2 students online now, waiting in Period 1 (B.1).', '', 'Join')">Default</button>
Roster uploaded.
Session saved without a period.
2 students are waiting in Period 1 (B.1).
<div class="saga-toast-stack" style="position:static;width:auto;align-items:stretch">
	<div class="saga-toast saga-toast--success" role="status"><span class="saga-toast__icon"><iconify-icon icon="material-symbols-light:check-circle-outline-rounded"></iconify-icon></span><span class="saga-toast__msg">Roster uploaded.</span><button class="saga-toast__close" aria-label="Dismiss"><iconify-icon icon="material-symbols-light:close-rounded"></iconify-icon></button></div>
	<div class="saga-toast saga-toast--warning" role="status"><span class="saga-toast__icon"><iconify-icon icon="material-symbols-light:warning-outline-rounded"></iconify-icon></span><span class="saga-toast__msg">Session saved without a period.</span><button class="saga-toast__action">Undo</button><button class="saga-toast__close" aria-label="Dismiss"><iconify-icon icon="material-symbols-light:close-rounded"></iconify-icon></button></div>
	<div class="saga-toast saga-toast--danger" role="alert"><span class="saga-toast__icon"><iconify-icon icon="material-symbols-light:error-outline-rounded"></iconify-icon></span><span class="saga-toast__msg">Could not reach the server.</span><button class="saga-toast__close" aria-label="Dismiss"><iconify-icon icon="material-symbols-light:close-rounded"></iconify-icon></button></div>
	<div class="saga-toast" role="status"><span class="saga-toast__msg">2 students are waiting in Period 1 (B.1).</span><button class="saga-toast__action">Join</button></div>
</div>

Popover menu

<ul class="saga-popover" role="menu" aria-label="Session actions">
	<li class="saga-popover__heading">Session</li>
	<li><button class="saga-popover__item" role="menuitem"><iconify-icon icon="material-symbols-light:edit-outline-rounded"></iconify-icon> Edit session</button></li>
	<li><button class="saga-popover__item" role="menuitem"><iconify-icon icon="material-symbols-light:content-copy-outline-rounded"></iconify-icon> Duplicate</button></li>
	<li><button class="saga-popover__item is-active" role="menuitemradio" aria-checked="true"><iconify-icon icon="material-symbols-light:calendar-view-month-outline-rounded"></iconify-icon> Month view</button></li>
	<li><button class="saga-popover__item" role="menuitem" disabled><iconify-icon icon="material-symbols-light:lock-outline"></iconify-icon> Lock (no permission)</button></li>
	<li class="saga-popover__divider" role="separator"></li>
	<li><button class="saga-popover__item" role="menuitem" data-danger><iconify-icon icon="material-symbols-light:delete-outline-rounded"></iconify-icon> Delete session</button></li>
</ul>

Tooltip

White with a --color-border-strong hairline and --shadow-md, as dash's core-ui Tooltip renders (DS-057, DS-120); --filled is the primary-blue variant for the info-icon trigger; --rich is left-aligned with a semibold .saga-tooltip__title first line.

Configure program Students and tutors always meet in the same pods. Tooltips wrap at 16rem. Search pages ⌘K Aaliyah LawrencePeriod 1 · Pod 6 · joined 09/02/2026
<span class="saga-tooltip" role="tooltip">Configure program</span>
<span class="saga-tooltip" role="tooltip">Students and tutors always meet in the same pods. Tooltips wrap at 16rem.</span>
<span class="saga-tooltip saga-tooltip--filled" role="tooltip">Search pages <kbd>⌘K</kbd></span>
<span class="saga-tooltip saga-tooltip--rich" role="tooltip"><span class="saga-tooltip__title">Aaliyah Lawrence</span>Period 1 · Pod 6 · joined 09/02/2026</span>

Notices

Levels are the modifier: bare .saga-notice is the notice level (--notice is an accepted alias), then --warning, --danger, --success, and --attention for a standing problem.

Preview deploy skipped Switch the PR to ready for review to trigger it.
This session has no period and will not appear on the schedule.
Program configuration saved.
Needs attention 2 pods have no tutor assigned.
<div class="saga-notice" role="status"><span class="saga-notice__icon"><iconify-icon icon="material-symbols-light:info-outline-rounded"></iconify-icon></span><div class="saga-notice__body"><span class="saga-notice__title">Preview deploy skipped</span> Switch the PR to ready for review to trigger it.</div><button class="saga-btn saga-btn--quiet saga-btn--icon saga-btn--sm saga-notice__dismiss" aria-label="Dismiss"><iconify-icon icon="material-symbols-light:close-rounded"></iconify-icon></button></div>
<div class="saga-notice saga-notice--warning" role="status"><span class="saga-notice__icon"><iconify-icon icon="material-symbols-light:warning-outline-rounded"></iconify-icon></span><div class="saga-notice__body">This session has no period and will not appear on the schedule. <button class="saga-notice__action">Assign a period</button></div></div>
<div class="saga-notice saga-notice--danger" role="alert"><span class="saga-notice__icon"><iconify-icon icon="material-symbols-light:error-outline-rounded"></iconify-icon></span><div class="saga-notice__body"><span class="saga-notice__title">Upload failed</span> 3 rows had an unknown school code.</div></div>
<div class="saga-notice saga-notice--success" role="status"><span class="saga-notice__icon"><iconify-icon icon="material-symbols-light:check-circle-outline-rounded"></iconify-icon></span><div class="saga-notice__body">Program configuration saved.</div></div>
<div class="saga-notice saga-notice--attention" role="status"><span class="saga-notice__icon"><iconify-icon icon="material-symbols-light:flag-outline-rounded"></iconify-icon></span><div class="saga-notice__body"><span class="saga-notice__title">Needs attention</span> 2 pods have no tutor assigned.</div></div>