feat(10-04): collapsible panel with flyout, user menu with logout, breadcrumbs and dark mode

- useSidebar: collapsed below 1100px (matchMedia) or by the admin's choice,
  persisted as a boolean under summer-admin.sidebar; the viewport never
  overwrites the stored choice
- SectionPanel collapse and rail expand buttons; SectionFlyout (role menu)
  opens on hover, focus, Enter or ArrowDown on a rail item, closes on Esc or
  about 200 ms after leaving and returns focus to the rail item
- Breadcrumbs with plugin, controller and record crumbs; UserMenu (Reka
  DropdownMenu) with initials, name, role and Wyloguj
- useAuth.logout POSTs /auth/logout, clears user, navigation and settings
  and routes to login even when the call fails
- applyColorScheme toggles .dark from prefers-color-scheme (no toggle, A6)
- newest toast first, 200 ms fade and scale for dialogs and toasts
- one relation-manager type constant in the registry
- shell smoke tests; tests default to a desktop, light matchMedia
This commit is contained in:
Jakub Zych
2026-09-27 17:26:44 +02:00
parent f4e97cccad
commit 445404e394
24 changed files with 1056 additions and 77 deletions

View File

@@ -104,6 +104,7 @@
}
.dark {
color-scheme: dark;
--c-bg: #111726;
--c-surface: #182033;
--c-subtle: #1f283d;
@@ -164,3 +165,56 @@
color: var(--c-placeholder);
}
}
/* Motion (design: Interactions, Transitions): subtle only. Hover and
background changes use the 150 ms ease-out utilities on each control;
dialogs and their backdrop fade in and scale from 0.98 over 200 ms; toasts
fade in the same way. Closing is immediate, so Reka's presence never waits
on an exit animation. No decorative animation. */
@keyframes summer-fade-in {
from {
opacity: 0;
}
}
@keyframes summer-dialog-in {
from {
opacity: 0;
scale: 0.98;
}
}
@layer components {
/* Backdrops of the picker (data-dialog-overlay) and of ConfirmDialog. */
.bg-overlay[data-state="open"] {
animation: summer-fade-in 200ms ease-out;
}
[data-dialog-content][data-state="open"],
[role="alertdialog"][data-state="open"] {
animation: summer-dialog-in 200ms ease-out;
}
.toast-enter-active {
transition:
opacity 200ms ease-out,
scale 200ms ease-out;
}
.toast-enter-from {
opacity: 0;
scale: 0.98;
}
}
@media (prefers-reduced-motion: reduce) {
.bg-overlay,
[data-dialog-content],
[role="alertdialog"] {
animation: none !important;
}
.toast-enter-active {
transition: none;
}
}