@realiizlabs/admin 0.9.1 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19,15 +19,21 @@ declare function ThemeToggle({ theme, onChange }: {
19
19
  interface ShellUser {
20
20
  email: string;
21
21
  name?: string | null;
22
+ /** Profile photo; initials show when absent. */
23
+ avatarUrl?: string | null;
22
24
  }
23
25
  declare function firstNameOf(user: ShellUser): string;
24
26
  declare function initialsOf(user: ShellUser): string;
25
- declare function AccountMenu({ user, role, theme, onTheme, signOutPath }: {
27
+ declare function AccountMenu({ user, role, theme, onTheme, signOutPath, accountHref, helpHref }: {
26
28
  user: ShellUser;
27
29
  role: string;
28
30
  theme: Theme;
29
31
  onTheme: (t: Theme) => void;
30
32
  signOutPath: string;
33
+ /** The Account page (My Profile · Change Password · Team · Business). Omit to hide the item. */
34
+ accountHref?: string;
35
+ /** The Help centre. Omit to hide the item. */
36
+ helpHref?: string;
31
37
  }): react.JSX.Element;
32
38
 
33
39
  /**
@@ -69,12 +75,24 @@ interface AdminShellProps {
69
75
  basePath?: string;
70
76
  /** Default `${basePath}/auth/signout`. */
71
77
  signOutPath?: string;
78
+ /** Account page for the avatar menu. Default `${basePath}/account`; null hides the item. */
79
+ accountHref?: string | null;
80
+ /** Help centre for the avatar menu. Default `${basePath}/help`; null hides the item. */
81
+ helpHref?: string | null;
82
+ /**
83
+ * The client's own branding (Business tab). `name` replaces siteName in the top bar
84
+ * and `logoUrl` replaces the logo; the product word ("Studio") stays.
85
+ */
86
+ branding?: {
87
+ name?: string | null;
88
+ logoUrl?: string | null;
89
+ } | null;
72
90
  defaultTheme?: Theme;
73
91
  children: ReactNode;
74
92
  }
75
- declare function AdminShell({ siteName, productName, logoUrl, user, role, nav, pinnedNav, activeHref, basePath, signOutPath, defaultTheme, children, }: AdminShellProps): react.JSX.Element;
93
+ declare function AdminShell({ siteName, productName, logoUrl, user, role, nav, pinnedNav, activeHref, basePath, signOutPath, accountHref, helpHref, branding, defaultTheme, children, }: AdminShellProps): react.JSX.Element;
76
94
 
77
- declare function TopBar({ siteName, productName, logoUrl, homeHref, user, role, theme, onTheme, signOutPath }: {
95
+ declare function TopBar({ siteName, productName, logoUrl, homeHref, user, role, theme, onTheme, signOutPath, accountHref, helpHref }: {
78
96
  siteName: string;
79
97
  productName: string;
80
98
  logoUrl?: string | null;
@@ -84,6 +102,8 @@ declare function TopBar({ siteName, productName, logoUrl, homeHref, user, role,
84
102
  theme: Theme;
85
103
  onTheme: (t: Theme) => void;
86
104
  signOutPath: string;
105
+ accountHref?: string;
106
+ helpHref?: string;
87
107
  }): react.JSX.Element;
88
108
 
89
109
  type ButtonVariant = "primary" | "secondary" | "danger" | "ghost";
@@ -169,6 +189,26 @@ declare function iconFor(id: string): IconName;
169
189
  * The block at the end maps the forms-ui variables onto these tokens, so
170
190
  * ContentForm and MagicLinkForm re-skin without touching their own code.
171
191
  */
172
- declare const SHELL_CSS = "\n.rz-admin, .rz-admin[data-theme=\"light\"] {\n /* realiiz.com palette (src/app/globals.css): ink, bone, paper, signal blue, slate, line, amber */\n --ink: #0e1726; --bone: #f7f5f0; --signal: #1f6feb;\n --surface-0: #f7f5f0; --surface-1: #ffffff; --surface-2: #f1eee7; --surface-3: #e8e4da;\n --text-primary: #0e1726; --text-secondary: #5b6678; --text-muted: #8a93a5;\n --signal-dim: #1a63d8; --signal-glow: #5b9bff; --signal-warn: #e0a03b; --series-blue: #1f6feb;\n --border: #d9d4c8; --separator: #e9e5dc;\n --status-up: #15803d; --status-down: #dc2626; --status-neutral: var(--text-muted); --status-blocked: var(--border);\n --signal-fg: #ffffff;\n}\n.rz-admin[data-theme=\"dark\"] { color-scheme: dark; }\n.rz-admin[data-theme=\"dark\"] {\n --ink: #eef0f5; --bone: #1b2334; --signal: #3b82f6;\n --surface-0: #1b2334; --surface-1: #222c42; --surface-2: #29344a; --surface-3: #36415c;\n --text-primary: #eef0f5; --text-secondary: #a2abbf; --text-muted: #77819a;\n --signal-dim: #8db4ff; --signal-glow: #aec9ff; --signal-warn: #eab058; --series-blue: #3b82f6;\n --border: #36415c; --separator: #2c3750;\n --status-up: #4ade80; --status-down: #f87171; --status-neutral: var(--text-muted); --status-blocked: var(--border);\n --signal-fg: #ffffff;\n}\n.rz-admin {\n --rz-font: system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif;\n --rz-font-display: var(--rz-font);\n --rz-font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;\n --rz-radius: 6px;\n --rz-sidebar: 220px; --rz-sidebar-collapsed: 58px; --rz-topbar: 52px;\n\n /* forms-ui speaks these; map them once so both packages agree */\n --realiiz-form-fg: var(--text-primary); --realiiz-form-muted: var(--text-muted);\n --realiiz-form-border: var(--border); --realiiz-form-accent: var(--signal);\n --realiiz-form-accent-fg: var(--signal-fg); --realiiz-form-danger: var(--status-down);\n --realiiz-form-radius: var(--rz-radius); --realiiz-form-font: var(--rz-font);\n --realiiz-form-focus-ring: 0 0 0 3px color-mix(in srgb, var(--signal) 25%, transparent);\n\n box-sizing: border-box; min-height: 100vh; display: flex; flex-direction: column;\n background: var(--surface-0); color: var(--text-primary);\n font-family: var(--rz-font); font-size: 14px; line-height: 1.45;\n}\n.rz-admin *, .rz-admin *::before, .rz-admin *::after { box-sizing: inherit; }\n.rz-admin a { color: inherit; }\n.rz-admin h1, .rz-admin h2, .rz-admin h3 { font-family: var(--rz-font-display); color: var(--text-primary); margin: 0; }\n.rz-admin .realiiz-form__control { background: var(--surface-0); }\n.rz-admin .realiiz-image { background: var(--surface-0); }\n.rz-admin .realiiz-image__thumb { background: var(--surface-2); }\n.rz-admin[data-theme=\"dark\"] .realiiz-form__control::-webkit-calendar-picker-indicator { filter: invert(1) opacity(.7); }\n.rz-admin .realiiz-form__button { background: var(--surface-1); color: var(--text-primary); }\n.rz-admin .realiiz-form__button--primary { background: var(--signal); color: var(--signal-fg); }\n\n/* ---- frame ---------------------------------------------------------- */\n.rz-topbar { height: var(--rz-topbar); display: flex; align-items: center; gap: 1rem; padding: 0 1.25rem; border-bottom: 1px solid var(--border); background: var(--surface-1); flex-shrink: 0; }\n.rz-topbar__brand { display: flex; align-items: center; gap: .6rem; font-weight: 600; font-size: .9375rem; text-decoration: none; }\n.rz-topbar__logo { height: 22px; width: auto; display: block; }\n.rz-topbar__product { font-weight: 400; color: var(--text-secondary); }\n.rz-topbar__right { margin-left: auto; display: flex; align-items: center; gap: 1rem; }\n.rz-topbar__greeting { color: var(--text-secondary); font-size: .8rem; }\n.rz-body { display: flex; flex: 1; min-height: 0; }\n/* Top bar and sidebar stay put while the content scrolls, so Collapse is always at the bottom-left. */\n.rz-topbar { position: sticky; top: 0; z-index: 20; }\n.rz-sidebar { position: sticky; top: var(--rz-topbar); height: calc(100vh - var(--rz-topbar)); width: var(--rz-sidebar); flex-shrink: 0; border-right: 1px solid var(--border); background: var(--surface-1); display: flex; flex-direction: column; transition: width .15s ease; overflow: hidden; }\n.rz-sidebar--collapsed { width: var(--rz-sidebar-collapsed); }\n.rz-sidebar__nav { padding: .75rem 0; flex: 1; overflow-y: auto; }\n.rz-sidebar__item { display: flex; align-items: center; gap: .65rem; padding: .55rem 1rem; color: var(--text-secondary); text-decoration: none; font-size: .875rem; font-weight: 400; white-space: nowrap; overflow: hidden; }\n.rz-sidebar__item:hover { background: var(--surface-2); color: var(--text-primary); }\n.rz-sidebar__item--active { background: var(--surface-2); color: var(--signal); font-weight: 500; }\n.rz-sidebar__item--disabled, .rz-sidebar__item--disabled:hover { color: var(--text-muted); opacity: .55; background: transparent; cursor: default; }\n.rz-sidebar--collapsed .rz-sidebar__item { justify-content: center; padding: .55rem 0; }\n.rz-sidebar--collapsed .rz-sidebar__label { display: none; }\n.rz-sidebar__pinned { border-top: 1px solid var(--separator); padding: .3rem 0; }\n.rz-sidebar__collapse { display: flex; align-items: center; gap: .7rem; padding: .6rem 1rem; border: 0; border-top: 1px solid var(--separator); background: transparent; color: var(--text-muted); cursor: pointer; font: inherit; font-size: .8rem; text-align: left; }\n.rz-sidebar__collapse:hover { color: var(--text-primary); }\n.rz-sidebar__collapse svg { flex-shrink: 0; }\n.rz-sidebar--collapsed .rz-sidebar__collapse { justify-content: center; padding: .6rem 0; }\n.rz-main { flex: 1; min-width: 0; }\n.rz-content { max-width: 1400px; margin: 0; padding: 28px 32px 80px; }\n.rz-content .realiiz-form { max-width: none; }\n.rz-content .realiiz-form fieldset, .rz-content .realiiz-form__alert, .rz-content .realiiz-form__actions { max-width: 920px; }\n/* The form's save bar pins to the bottom of the content column: bleed out over .rz-content's padding, then pad back in. */\n.rz-content .realiiz-form__bar { position: sticky; bottom: 0; z-index: 10; margin: 24px -32px -80px; padding: 12px 32px; background: var(--surface-1); border-top: 1px solid var(--border); box-shadow: 0 -6px 16px rgba(14,23,38,.05); }\n.rz-content .realiiz-form__status { color: var(--text-muted); }\n.rz-content .realiiz-form__bar[data-dirty] .realiiz-form__status { color: var(--text-primary); font-weight: 500; }\n\n/* ---- primitives ----------------------------------------------------- */\n/* Same metrics as the form's Save button (.realiiz-form__button) so every button in the admin matches. */\n.rz-btn { font-family: inherit; font-weight: 600; border-radius: var(--rz-radius); cursor: pointer; text-decoration: none; display: inline-flex; align-items: center; justify-content: center; gap: .4rem; white-space: nowrap; line-height: 1.2; }\n.rz-btn--md { padding: 10px 16px; font-size: 15px; min-height: 40px; }\n.rz-btn--sm { padding: 6px 12px; font-size: 13px; min-height: 32px; }\n.rz-admin .rz-btn--primary, .rz-admin a.rz-btn--primary { background: var(--signal); color: var(--signal-fg); border: 1px solid var(--signal); }\n.rz-admin .rz-btn--secondary, .rz-admin a.rz-btn--secondary { background: var(--surface-1); color: var(--text-primary); border: 1px solid var(--border); }\n.rz-admin .rz-btn--danger, .rz-admin a.rz-btn--danger { background: transparent; color: var(--status-down); border: 1px solid var(--status-down); }\n.rz-admin .rz-btn--ghost, .rz-admin a.rz-btn--ghost { background: var(--surface-1); color: var(--text-primary); border: 1px solid var(--border); }\n.rz-admin .rz-btn:disabled { opacity: .55; cursor: default; }\n.rz-arrow { width: 1.1em; height: 1.1em; flex-shrink: 0; transition: transform .15s ease-out; }\n@media (prefers-reduced-motion: no-preference) {\n .rz-btn:hover .rz-arrow, a:hover .rz-arrow { transform: translate(2px, -2px); }\n .rz-btn:hover .rz-arrow--fwd, a:hover .rz-arrow--fwd { transform: translateX(4px); }\n}\n.rz-card { background: var(--surface-1); border: 1px solid var(--border); border-radius: 8px; padding: 18px 20px; }\n.rz-card--narrow { max-width: 760px; }\n.rz-card__title { font-size: .9375rem; font-weight: 600; margin-bottom: .35rem; }\n.rz-card__meta { color: var(--text-muted); font-size: .8rem; }\n.rz-card__actions { display: flex; gap: .5rem; margin-top: .9rem; flex-wrap: wrap; }\n.rz-grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }\n.rz-pagehead { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 20px; flex-wrap: wrap; }\n.rz-pagehead__eyebrow { font-family: var(--rz-font-mono); font-size: .6875rem; text-transform: uppercase; letter-spacing: .08em; color: var(--text-muted); margin-bottom: .3rem; }\n.rz-pagehead h1 { font-size: 1.375rem; font-weight: 600; }\n.rz-pagehead__sub { color: var(--text-secondary); font-size: .85rem; margin-top: .25rem; }\n.rz-pill { display: inline-flex; align-items: center; gap: .4rem; white-space: nowrap; font-family: var(--rz-font-mono); font-size: .6875rem; text-transform: uppercase; letter-spacing: .06em; padding: .15rem .5rem; border: 1px solid var(--border); border-radius: 999px; color: var(--text-secondary); }\n.rz-pill::before { content: \"\"; width: 7px; height: 7px; border-radius: 50%; background: var(--status-neutral); }\n.rz-pill--up::before { background: var(--status-up); } .rz-pill--warn::before { background: var(--signal-warn); } .rz-pill--down::before { background: var(--status-down); }\n.rz-pill--plain::before { display: none; }\n/* ---- steps tracker ------------------------------------------------- */\n/* Dots on one rail, connectors dot-to-dot, label under each dot; left-aligned like the rest of the page. */\n.rz-steps { list-style: none; margin: 4px 0 22px; padding: 0 0 22px; display: flex; border-bottom: 1px solid var(--separator); }\n.rz-step { flex: 1; position: relative; display: flex; flex-direction: column; align-items: flex-start; text-align: left; gap: 8px; min-width: 0; }\n.rz-step:last-child { flex: 0 0 auto; }\n.rz-step:not(:last-child)::after { content: \"\"; position: absolute; top: 12px; left: 26px; right: 0; height: 2px; background: var(--border); }\n.rz-step--done:not(:last-child)::after { background: var(--status-up); }\n.rz-step__dot { width: 26px; height: 26px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: .75rem; font-weight: 600; flex-shrink: 0; border: 2px solid var(--border); color: var(--text-muted); background: var(--surface-1); }\n.rz-step--done .rz-step__dot { background: var(--status-up); border-color: var(--status-up); color: #fff; }\n.rz-step--active .rz-step__dot { position: relative; border-color: color-mix(in srgb, var(--signal) 30%, transparent); color: var(--signal); }\n/* A spinning arc over the ring: the step is working, not waiting on you. */\n.rz-step--active .rz-step__dot::after { content: \"\"; position: absolute; inset: -2px; border-radius: 50%; border: 2px solid transparent; border-top-color: var(--signal); animation: rz-spin .9s linear infinite; }\n@media (prefers-reduced-motion: reduce) { .rz-step--active .rz-step__dot::after { animation: none; border-color: var(--signal); } }\n@keyframes rz-spin { to { transform: rotate(360deg); } }\n.rz-step--failed .rz-step__dot { background: var(--status-down); border-color: var(--status-down); color: #fff; }\n.rz-step__text { display: flex; flex-direction: column; gap: 1px; padding-right: 16px; }\n.rz-step__label { font-size: .875rem; font-weight: 500; color: var(--text-secondary); }\n.rz-step--active .rz-step__label, .rz-step--done .rz-step__label { color: var(--text-primary); }\n.rz-step--failed .rz-step__label { color: var(--status-down); }\n.rz-step__note { font-size: .75rem; color: var(--text-muted); }\n@keyframes rz-pulse { 0%, 100% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--signal) 18%, transparent); } 50% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--signal) 8%, transparent); } }\n.rz-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 20px; }\n.rz-actions__hint { font-size: .8rem; color: var(--text-muted); }\n.rz-notice { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 12px 16px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface-1); margin-bottom: 18px; font-size: .9rem; }\n.rz-notice__text { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }\n.rz-status-link { text-decoration: none; }\n.rz-discard { margin-top: 22px; padding-top: 14px; border-top: 1px solid var(--separator); display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: .85rem; color: var(--text-secondary); }\n.rz-discard__link { background: none; border: 0; padding: 0; font: inherit; font-size: .85rem; color: var(--text-muted); text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }\n.rz-discard__link:hover { color: var(--status-down); }\n.rz-nowrap { white-space: nowrap; }\n.rz-table td.rz-fit, .rz-table th.rz-fit { width: 1%; white-space: nowrap; }\n.rz-empty { border: 1px dashed var(--border); border-radius: 8px; padding: 32px; text-align: center; color: var(--text-secondary); }\n.rz-empty h3 { font-size: 1rem; margin-bottom: .4rem; }\n.rz-table-wrap { width: 100%; }\n.rz-table { width: 100%; border-collapse: collapse; background: var(--surface-1); border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }\n.rz-table th, .rz-table td { text-align: left; padding: 10px 14px; border-bottom: 1px solid var(--separator); font-size: .875rem; vertical-align: top; }\n.rz-table th { font-family: var(--rz-font-mono); font-size: .6875rem; text-transform: uppercase; letter-spacing: .06em; color: var(--text-muted); background: var(--surface-2); }\n.rz-table tr:last-child td { border-bottom: 0; }\n.rz-muted { color: var(--text-muted); }\n.rz-alert { border: 1px solid var(--status-down); color: var(--status-down); border-radius: var(--rz-radius); padding: 12px 14px; margin: 0 0 16px; }\n.rz-ok { border: 1px solid var(--status-up); color: var(--signal-dim); border-radius: var(--rz-radius); padding: 12px 14px; margin: 0 0 16px; }\n\n/* ---- account menu --------------------------------------------------- */\n.rz-avatar { width: 2rem; height: 2rem; border-radius: 50%; background: var(--surface-3); border: 1px solid var(--border); color: var(--text-primary); font-size: .6875rem; font-weight: 600; letter-spacing: .04em; display: flex; align-items: center; justify-content: center; cursor: pointer; font-family: inherit; padding: 0; }\n.rz-menu { position: absolute; right: 0; top: calc(100% + 8px); min-width: 15rem; background: var(--surface-1); border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 8px 24px rgba(14,23,38,.14); overflow: hidden; z-index: 50; }\n.rz-menu__who { padding: .75rem .9rem; border-bottom: 1px solid var(--border); margin-bottom: .3rem; }\n.rz-menu__name { font-weight: 600; font-size: .875rem; }\n.rz-menu__email { color: var(--text-muted); font-size: .75rem; word-break: break-all; }\n.rz-menu__sep { height: 1px; background: var(--border); margin: .3rem 0; }\n.rz-menu__item { display: flex; align-items: center; gap: .55rem; width: 100%; padding: .45rem .9rem; font: inherit; font-size: .8125rem; color: var(--text-secondary); background: none; border: 0; text-align: left; cursor: pointer; text-decoration: none; }\n.rz-menu__item:hover { background: var(--surface-2); color: var(--text-primary); }\n.rz-menu__item svg { flex-shrink: 0; }\n.rz-menu__item--static { cursor: default; }\n.rz-menu__item--static:hover { background: none; color: var(--text-secondary); }\n.rz-menu__item .rz-menu__end { margin-left: auto; }\n.rz-menu__signout { margin: 0 0 .3rem; }\n.rz-seg { display: inline-flex; border: 1px solid var(--border); border-radius: var(--rz-radius); overflow: hidden; }\n.rz-seg button { font: inherit; font-size: .75rem; padding: .15rem .55rem; line-height: 1.3; background: transparent; color: var(--text-secondary); border: 0; cursor: pointer; }\n.rz-seg button[aria-pressed=\"true\"] { background: var(--surface-3); color: var(--text-primary); }\n\n/* ---- mobile: sidebar becomes a strip under the top bar --------------- */\n@media (max-width: 720px) {\n .rz-body { flex-direction: column; }\n .rz-sidebar, .rz-sidebar--collapsed { width: 100%; border-right: 0; border-bottom: 1px solid var(--border); flex-direction: row; }\n .rz-sidebar__nav { display: flex; padding: .35rem .25rem; overflow-x: auto; }\n .rz-sidebar__item { flex-direction: column; gap: .2rem; font-size: .6875rem; padding: .4rem .6rem; border-radius: 6px; }\n .rz-sidebar--collapsed .rz-sidebar__label { display: block; }\n .rz-sidebar__collapse { display: none; }\n .rz-sidebar__pinned { display: flex; border-top: 0; padding: .35rem .25rem; }\n .rz-topbar__greeting { display: none; }\n .rz-content { padding: 18px 14px 60px; }\n /* The sidebar is a top strip now, so it must not be sticky-height; the topbar stays pinned. */\n .rz-sidebar, .rz-sidebar--collapsed { position: static; height: auto; }\n .rz-sidebar__item--disabled { display: none; }\n /* Save bar: bleed matches the narrower content padding; stack status above the buttons. */\n .rz-content .realiiz-form__bar { margin: 18px -14px -60px; padding: 10px 14px; flex-wrap: wrap; }\n .rz-content .realiiz-form__status { flex-basis: 100%; margin-right: 0; font-size: .8rem; }\n /* Editor toolbar wraps; the Insert group drops its label and left rule to save width. */\n .rz-admin .realiiz-md__head { padding: 5px; }\n .rz-admin .realiiz-md__insert { border-left: 0; padding-left: 0; margin-left: 0; }\n .rz-admin .realiiz-md__lab { display: none; }\n .rz-admin .realiiz-md--fs { padding: 8px; }\n /* Tracker: notes hide, labels shrink, so three steps fit a phone. */\n .rz-step__note { display: none; }\n .rz-step__label { font-size: .8rem; }\n .rz-step:not(:last-child)::after { right: 6px; }\n /* Tables scroll sideways inside their own box instead of stretching the page. */\n .rz-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }\n .rz-pagehead { align-items: flex-start; flex-direction: column; }\n .rz-notice { flex-direction: column; align-items: flex-start; }\n .rz-card--narrow { max-width: none; }\n}\n\n/* ---- forms extras: markdown editor, chips, gauges, preview prose --------- */\n.rz-admin .realiiz-md { --_md-head: var(--surface-2); --_md-hover: var(--surface-2); --_md-hover-line: var(--signal-glow); --_md-on: color-mix(in srgb, var(--signal) 12%, var(--surface-1)); --_md-tip: var(--ink); }\n.rz-admin .realiiz-md__mode { background: var(--surface-2); }\n.rz-admin .realiiz-md__mode button { color: var(--text-secondary); }\n.rz-admin .realiiz-md__mode button[aria-selected=\"true\"] { background: var(--surface-1); color: var(--text-primary); box-shadow: 0 1px 2px rgba(14,23,38,.12); }\n.rz-admin .realiiz-md__panel, .rz-admin .realiiz-md__tgrid, .rz-admin .realiiz-md--fs, .rz-admin .realiiz-md .realiiz-md__ta, .rz-admin .realiiz-md__preview, .rz-admin .realiiz-md__head button { background: var(--surface-1); }\n.rz-admin .realiiz-md__head { background: var(--surface-2); }\n.rz-admin .realiiz-md__head button { color: var(--text-primary); }\n.rz-admin .realiiz-md__insert button { background: var(--surface-2); color: var(--text-secondary); }\n.rz-admin .realiiz-md__tgcells i { background: var(--surface-1); }\n.rz-admin .realiiz-md__tgcells i.hot { background: color-mix(in srgb, var(--signal) 18%, var(--surface-1)); }\n.rz-admin .realiiz-md__loading { color: var(--text-muted); font-size: .8rem; }\n.rz-admin .realiiz-prose { max-width: 68ch; font-size: 1rem; line-height: 1.65; color: var(--text-primary); }\n.rz-admin .realiiz-prose h1, .rz-admin .realiiz-prose h2, .rz-admin .realiiz-prose h3 { font-family: var(--rz-font-display); line-height: 1.25; margin: 1.4em 0 .5em; }\n.rz-admin .realiiz-prose h2 { font-size: 1.35rem; } .rz-admin .realiiz-prose h3 { font-size: 1.1rem; }\n.rz-admin .realiiz-prose p, .rz-admin .realiiz-prose ul, .rz-admin .realiiz-prose ol, .rz-admin .realiiz-prose blockquote { margin: 0 0 1em; }\n.rz-admin .realiiz-prose a { color: var(--signal); }\n/* The site's prose class picks a slate body colour for a light page; on the dark surface that reads as disabled. */\n.rz-admin[data-theme=\"dark\"] .realiiz-prose, .rz-admin[data-theme=\"dark\"] .realiiz-prose :is(p, li, td, th, dd, dt, figcaption, strong, b, em, i, h1, h2, h3, h4, h5, h6) { color: var(--text-primary); }\n.rz-admin[data-theme=\"dark\"] .realiiz-prose :is(code, kbd) { color: var(--text-primary); background: var(--surface-3); }\n.rz-admin[data-theme=\"dark\"] .realiiz-prose a { color: var(--signal-dim); }\n.rz-admin[data-theme=\"dark\"] .realiiz-prose hr { border-color: var(--border); }\n.rz-admin[data-theme=\"dark\"] .realiiz-prose blockquote { color: var(--text-secondary); }\n.rz-admin .realiiz-prose blockquote { border-left: 3px solid var(--border); padding-left: 1em; color: var(--text-secondary); }\n.rz-admin .realiiz-prose code { background: var(--surface-2); padding: 0 4px; border-radius: 4px; font-family: var(--rz-font-mono); font-size: .9em; }\n.rz-admin .realiiz-prose pre { background: var(--surface-2); padding: 12px 14px; border-radius: 6px; overflow-x: auto; }\n.rz-admin .realiiz-prose img { max-width: 100%; height: auto; border-radius: 6px; }\n.rz-admin .realiiz-chips { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; min-height: 40px; padding: 5px 8px; background: var(--surface-0); border: 1px solid var(--border); border-radius: var(--rz-radius); }\n.rz-admin .realiiz-chips:focus-within { border-color: var(--signal); box-shadow: var(--realiiz-form-focus-ring); }\n.rz-admin .realiiz-chip { display: inline-flex; align-items: center; gap: 4px; padding: 2px 4px 2px 9px; background: var(--surface-3); border: 1px solid var(--border); border-radius: 999px; font-size: .8rem; color: var(--text-primary); }\n.rz-admin .realiiz-chip button { font: inherit; line-height: 1; width: 18px; height: 18px; border-radius: 50%; border: 0; background: transparent; color: var(--text-muted); cursor: pointer; }\n.rz-admin .realiiz-chip button:hover { background: var(--status-down); color: #fff; }\n.rz-admin .realiiz-chips__input { flex: 1; min-width: 120px; border: 0; background: transparent; font: inherit; color: inherit; outline: none; padding: 4px; }\n.rz-admin .realiiz-chips__count { margin-left: auto; color: var(--text-muted); font-size: .75rem; font-variant-numeric: tabular-nums; }\n.rz-admin .realiiz-gauge { color: var(--text-muted); }\n.rz-admin .realiiz-gauge__bar { background: var(--surface-3); }\n.rz-admin .realiiz-gauge__zone { background: color-mix(in srgb, var(--status-up) 28%, transparent); }\n.rz-admin .realiiz-gauge__fill { background: var(--text-muted); }\n.rz-admin .realiiz-gauge--ok .realiiz-gauge__fill { background: var(--status-up); } .rz-admin .realiiz-gauge--ok { color: var(--status-up); }\n.rz-admin .realiiz-gauge--over .realiiz-gauge__fill { background: var(--status-down); } .rz-admin .realiiz-gauge--over { color: var(--status-down); }\n";
192
+ declare const SHELL_CSS = "\n.rz-admin, .rz-admin[data-theme=\"light\"] {\n /* realiiz.com palette (src/app/globals.css): ink, bone, paper, signal blue, slate, line, amber */\n --ink: #0e1726; --bone: #f7f5f0; --signal: #1f6feb;\n --surface-0: #f7f5f0; --surface-1: #ffffff; --surface-2: #f1eee7; --surface-3: #e8e4da;\n --text-primary: #0e1726; --text-secondary: #5b6678; --text-muted: #8a93a5;\n --signal-dim: #1a63d8; --signal-glow: #5b9bff; --signal-warn: #e0a03b; --series-blue: #1f6feb;\n --border: #d9d4c8; --separator: #e9e5dc;\n --status-up: #15803d; --status-down: #dc2626; --status-neutral: var(--text-muted); --status-blocked: var(--border);\n --signal-fg: #ffffff;\n}\n.rz-admin[data-theme=\"dark\"] { color-scheme: dark; }\n.rz-admin[data-theme=\"dark\"] {\n --ink: #eef0f5; --bone: #1b2334; --signal: #3b82f6;\n --surface-0: #1b2334; --surface-1: #222c42; --surface-2: #29344a; --surface-3: #36415c;\n --text-primary: #eef0f5; --text-secondary: #a2abbf; --text-muted: #77819a;\n --signal-dim: #8db4ff; --signal-glow: #aec9ff; --signal-warn: #eab058; --series-blue: #3b82f6;\n --border: #36415c; --separator: #2c3750;\n --status-up: #4ade80; --status-down: #f87171; --status-neutral: var(--text-muted); --status-blocked: var(--border);\n --signal-fg: #ffffff;\n}\n.rz-admin {\n --rz-font: system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif;\n --rz-font-display: var(--rz-font);\n --rz-font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;\n --rz-radius: 6px;\n --rz-sidebar: 220px; --rz-sidebar-collapsed: 58px; --rz-topbar: 52px;\n\n /* forms-ui speaks these; map them once so both packages agree */\n --realiiz-form-fg: var(--text-primary); --realiiz-form-muted: var(--text-muted);\n --realiiz-form-border: var(--border); --realiiz-form-accent: var(--signal);\n --realiiz-form-accent-fg: var(--signal-fg); --realiiz-form-danger: var(--status-down);\n --realiiz-form-radius: var(--rz-radius); --realiiz-form-font: var(--rz-font);\n --realiiz-form-focus-ring: 0 0 0 3px color-mix(in srgb, var(--signal) 25%, transparent);\n\n box-sizing: border-box; min-height: 100vh; display: flex; flex-direction: column;\n background: var(--surface-0); color: var(--text-primary);\n font-family: var(--rz-font); font-size: 14px; line-height: 1.45;\n}\n.rz-admin *, .rz-admin *::before, .rz-admin *::after { box-sizing: inherit; }\n.rz-admin a { color: inherit; }\n.rz-admin h1, .rz-admin h2, .rz-admin h3 { font-family: var(--rz-font-display); color: var(--text-primary); margin: 0; }\n.rz-admin .realiiz-form__control { background: var(--surface-0); }\n.rz-admin .realiiz-image { background: var(--surface-0); }\n.rz-admin .realiiz-image__thumb { background: var(--surface-2); }\n.rz-admin[data-theme=\"dark\"] .realiiz-form__control::-webkit-calendar-picker-indicator { filter: invert(1) opacity(.7); }\n.rz-admin .realiiz-form__button { background: var(--surface-1); color: var(--text-primary); }\n.rz-admin .realiiz-form__button--primary { background: var(--signal); color: var(--signal-fg); }\n\n/* ---- frame ---------------------------------------------------------- */\n.rz-topbar { height: var(--rz-topbar); display: flex; align-items: center; gap: 1rem; padding: 0 1.25rem; border-bottom: 1px solid var(--border); background: var(--surface-1); flex-shrink: 0; }\n.rz-topbar__brand { display: flex; align-items: center; gap: .6rem; font-weight: 600; font-size: .9375rem; text-decoration: none; }\n.rz-topbar__logo { height: 22px; width: auto; display: block; }\n.rz-topbar__product { font-weight: 400; color: var(--text-secondary); }\n.rz-topbar__right { margin-left: auto; display: flex; align-items: center; gap: 1rem; }\n.rz-topbar__greeting { color: var(--text-secondary); font-size: .8rem; }\n.rz-body { display: flex; flex: 1; min-height: 0; }\n/* Top bar and sidebar stay put while the content scrolls, so Collapse is always at the bottom-left. */\n.rz-topbar { position: sticky; top: 0; z-index: 20; }\n.rz-sidebar { position: sticky; top: var(--rz-topbar); height: calc(100vh - var(--rz-topbar)); width: var(--rz-sidebar); flex-shrink: 0; border-right: 1px solid var(--border); background: var(--surface-1); display: flex; flex-direction: column; transition: width .15s ease; overflow: hidden; }\n.rz-sidebar--collapsed { width: var(--rz-sidebar-collapsed); }\n.rz-sidebar__nav { padding: .75rem 0; flex: 1; overflow-y: auto; }\n.rz-sidebar__item { display: flex; align-items: center; gap: .65rem; padding: .55rem 1rem; color: var(--text-secondary); text-decoration: none; font-size: .875rem; font-weight: 400; white-space: nowrap; overflow: hidden; }\n.rz-sidebar__item:hover { background: var(--surface-2); color: var(--text-primary); }\n.rz-sidebar__item--active { background: var(--surface-2); color: var(--signal); font-weight: 500; }\n.rz-sidebar__item--disabled, .rz-sidebar__item--disabled:hover { color: var(--text-muted); opacity: .55; background: transparent; cursor: default; }\n.rz-sidebar--collapsed .rz-sidebar__item { justify-content: center; padding: .55rem 0; }\n.rz-sidebar--collapsed .rz-sidebar__label { display: none; }\n.rz-sidebar__pinned { border-top: 1px solid var(--separator); padding: .3rem 0; }\n.rz-sidebar__collapse { display: flex; align-items: center; gap: .7rem; padding: .6rem 1rem; border: 0; border-top: 1px solid var(--separator); background: transparent; color: var(--text-muted); cursor: pointer; font: inherit; font-size: .8rem; text-align: left; }\n.rz-sidebar__collapse:hover { color: var(--text-primary); }\n.rz-sidebar__collapse svg { flex-shrink: 0; }\n.rz-sidebar--collapsed .rz-sidebar__collapse { justify-content: center; padding: .6rem 0; }\n.rz-main { flex: 1; min-width: 0; }\n.rz-content { max-width: 1400px; margin: 0; padding: 28px 32px 80px; }\n.rz-content .realiiz-form { max-width: none; }\n.rz-content .realiiz-form fieldset, .rz-content .realiiz-form__alert, .rz-content .realiiz-form__actions { max-width: 920px; }\n/* The form's save bar pins to the bottom of the content column: bleed out over .rz-content's padding, then pad back in. */\n.rz-content .realiiz-form__bar { position: sticky; bottom: 0; z-index: 10; margin: 24px -32px -80px; padding: 12px 32px; background: var(--surface-1); border-top: 1px solid var(--border); box-shadow: 0 -6px 16px rgba(14,23,38,.05); }\n.rz-content .realiiz-form__status { color: var(--text-muted); }\n.rz-content .realiiz-form__bar[data-dirty] .realiiz-form__status { color: var(--text-primary); font-weight: 500; }\n\n/* ---- primitives ----------------------------------------------------- */\n/* Same metrics as the form's Save button (.realiiz-form__button) so every button in the admin matches. */\n.rz-btn { font-family: inherit; font-weight: 600; border-radius: var(--rz-radius); cursor: pointer; text-decoration: none; display: inline-flex; align-items: center; justify-content: center; gap: .4rem; white-space: nowrap; line-height: 1.2; }\n.rz-btn--md { padding: 10px 16px; font-size: 15px; min-height: 40px; }\n.rz-btn--sm { padding: 6px 12px; font-size: 13px; min-height: 32px; }\n.rz-admin .rz-btn--primary, .rz-admin a.rz-btn--primary { background: var(--signal); color: var(--signal-fg); border: 1px solid var(--signal); }\n.rz-admin .rz-btn--secondary, .rz-admin a.rz-btn--secondary { background: var(--surface-1); color: var(--text-primary); border: 1px solid var(--border); }\n.rz-admin .rz-btn--danger, .rz-admin a.rz-btn--danger { background: transparent; color: var(--status-down); border: 1px solid var(--status-down); }\n.rz-admin .rz-btn--ghost, .rz-admin a.rz-btn--ghost { background: var(--surface-1); color: var(--text-primary); border: 1px solid var(--border); }\n.rz-admin .rz-btn:disabled { opacity: .55; cursor: default; }\n.rz-arrow { width: 1.1em; height: 1.1em; flex-shrink: 0; transition: transform .15s ease-out; }\n@media (prefers-reduced-motion: no-preference) {\n .rz-btn:hover .rz-arrow, a:hover .rz-arrow { transform: translate(2px, -2px); }\n .rz-btn:hover .rz-arrow--fwd, a:hover .rz-arrow--fwd { transform: translateX(4px); }\n}\n.rz-card { background: var(--surface-1); border: 1px solid var(--border); border-radius: 8px; padding: 18px 20px; }\n.rz-card--narrow { max-width: 760px; }\n.rz-card__title { font-size: .9375rem; font-weight: 600; margin-bottom: .35rem; }\n.rz-card__meta { color: var(--text-muted); font-size: .8rem; }\n.rz-card__actions { display: flex; gap: .5rem; margin-top: .9rem; flex-wrap: wrap; }\n.rz-grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }\n.rz-pagehead { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 20px; flex-wrap: wrap; }\n.rz-pagehead__eyebrow { font-family: var(--rz-font-mono); font-size: .6875rem; text-transform: uppercase; letter-spacing: .08em; color: var(--text-muted); margin-bottom: .3rem; }\n.rz-pagehead h1 { font-size: 1.375rem; font-weight: 600; }\n.rz-pagehead__sub { color: var(--text-secondary); font-size: .85rem; margin-top: .25rem; }\n.rz-pill { display: inline-flex; align-items: center; gap: .4rem; white-space: nowrap; font-family: var(--rz-font-mono); font-size: .6875rem; text-transform: uppercase; letter-spacing: .06em; padding: .15rem .5rem; border: 1px solid var(--border); border-radius: 999px; color: var(--text-secondary); }\n.rz-pill::before { content: \"\"; width: 7px; height: 7px; border-radius: 50%; background: var(--status-neutral); }\n.rz-pill--up::before { background: var(--status-up); } .rz-pill--warn::before { background: var(--signal-warn); } .rz-pill--down::before { background: var(--status-down); }\n.rz-pill--plain::before { display: none; }\n/* ---- steps tracker ------------------------------------------------- */\n/* Dots on one rail, connectors dot-to-dot, label under each dot; left-aligned like the rest of the page. */\n.rz-steps { list-style: none; margin: 4px 0 22px; padding: 0 0 22px; display: flex; border-bottom: 1px solid var(--separator); }\n.rz-step { flex: 1; position: relative; display: flex; flex-direction: column; align-items: flex-start; text-align: left; gap: 8px; min-width: 0; }\n.rz-step:last-child { flex: 0 0 auto; }\n.rz-step:not(:last-child)::after { content: \"\"; position: absolute; top: 12px; left: 26px; right: 0; height: 2px; background: var(--border); }\n.rz-step--done:not(:last-child)::after { background: var(--status-up); }\n.rz-step__dot { width: 26px; height: 26px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: .75rem; font-weight: 600; flex-shrink: 0; border: 2px solid var(--border); color: var(--text-muted); background: var(--surface-1); }\n.rz-step--done .rz-step__dot { background: var(--status-up); border-color: var(--status-up); color: #fff; }\n.rz-step--active .rz-step__dot { position: relative; border-color: color-mix(in srgb, var(--signal) 30%, transparent); color: var(--signal); }\n/* A spinning arc over the ring: the step is working, not waiting on you. */\n.rz-step--active .rz-step__dot::after { content: \"\"; position: absolute; inset: -2px; border-radius: 50%; border: 2px solid transparent; border-top-color: var(--signal); animation: rz-spin .9s linear infinite; }\n@media (prefers-reduced-motion: reduce) { .rz-step--active .rz-step__dot::after { animation: none; border-color: var(--signal); } }\n@keyframes rz-spin { to { transform: rotate(360deg); } }\n.rz-step--failed .rz-step__dot { background: var(--status-down); border-color: var(--status-down); color: #fff; }\n.rz-step__text { display: flex; flex-direction: column; gap: 1px; padding-right: 16px; }\n.rz-step__label { font-size: .875rem; font-weight: 500; color: var(--text-secondary); }\n.rz-step--active .rz-step__label, .rz-step--done .rz-step__label { color: var(--text-primary); }\n.rz-step--failed .rz-step__label { color: var(--status-down); }\n.rz-step__note { font-size: .75rem; color: var(--text-muted); }\n@keyframes rz-pulse { 0%, 100% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--signal) 18%, transparent); } 50% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--signal) 8%, transparent); } }\n.rz-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 20px; }\n.rz-actions__hint { font-size: .8rem; color: var(--text-muted); }\n.rz-notice { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 12px 16px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface-1); margin-bottom: 18px; font-size: .9rem; }\n.rz-notice__text { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }\n.rz-status-link { text-decoration: none; }\n.rz-discard { margin-top: 22px; padding-top: 14px; border-top: 1px solid var(--separator); display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: .85rem; color: var(--text-secondary); }\n.rz-discard__link { background: none; border: 0; padding: 0; font: inherit; font-size: .85rem; color: var(--text-muted); text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }\n.rz-discard__link:hover { color: var(--status-down); }\n.rz-nowrap { white-space: nowrap; }\n.rz-table td.rz-fit, .rz-table th.rz-fit { width: 1%; white-space: nowrap; }\n.rz-empty { border: 1px dashed var(--border); border-radius: 8px; padding: 32px; text-align: center; color: var(--text-secondary); }\n.rz-empty h3 { font-size: 1rem; margin-bottom: .4rem; }\n.rz-table-wrap { width: 100%; }\n.rz-table { width: 100%; border-collapse: collapse; background: var(--surface-1); border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }\n.rz-table th, .rz-table td { text-align: left; padding: 10px 14px; border-bottom: 1px solid var(--separator); font-size: .875rem; vertical-align: top; }\n.rz-table th { font-family: var(--rz-font-mono); font-size: .6875rem; text-transform: uppercase; letter-spacing: .06em; color: var(--text-muted); background: var(--surface-2); }\n.rz-table tr:last-child td { border-bottom: 0; }\n.rz-muted { color: var(--text-muted); }\n.rz-alert { border: 1px solid var(--status-down); color: var(--status-down); border-radius: var(--rz-radius); padding: 12px 14px; margin: 0 0 16px; }\n.rz-ok { border: 1px solid var(--status-up); color: var(--signal-dim); border-radius: var(--rz-radius); padding: 12px 14px; margin: 0 0 16px; }\n\n/* ---- account menu --------------------------------------------------- */\n.rz-avatar__img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; display: block; }\n.rz-tabs { display: flex; gap: .25rem; border-bottom: 1px solid var(--border); margin: 0 0 1.5rem; flex-wrap: wrap; }\n.rz-tabs__tab { padding: .55rem .9rem; font: inherit; font-size: .88rem; color: var(--text-secondary); background: none; border: 0; border-bottom: 2px solid transparent; margin-bottom: -1px; cursor: pointer; }\n.rz-tabs__tab:hover { color: var(--text-primary); }\n.rz-tabs__tab[aria-selected=\"true\"] { color: var(--text-primary); border-bottom-color: var(--signal); font-weight: 600; }\n.rz-tabs__tab:focus-visible { outline: 2px solid var(--signal); outline-offset: -2px; border-radius: 4px; }\n.rz-avatar { width: 2rem; height: 2rem; border-radius: 50%; background: var(--surface-3); border: 1px solid var(--border); color: var(--text-primary); font-size: .6875rem; font-weight: 600; letter-spacing: .04em; display: flex; align-items: center; justify-content: center; cursor: pointer; font-family: inherit; padding: 0; overflow: hidden; }\n.rz-menu { position: absolute; right: 0; top: calc(100% + 8px); min-width: 15rem; background: var(--surface-1); border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 8px 24px rgba(14,23,38,.14); overflow: hidden; z-index: 50; }\n.rz-menu__who { padding: .75rem .9rem; border-bottom: 1px solid var(--border); margin-bottom: .3rem; }\n.rz-menu__name { font-weight: 600; font-size: .875rem; }\n.rz-menu__email { color: var(--text-muted); font-size: .75rem; word-break: break-all; }\n.rz-menu__sep { height: 1px; background: var(--border); margin: .3rem 0; }\n.rz-menu__item { display: flex; align-items: center; gap: .55rem; width: 100%; padding: .45rem .9rem; font: inherit; font-size: .8125rem; color: var(--text-secondary); background: none; border: 0; text-align: left; cursor: pointer; text-decoration: none; }\n.rz-menu__item:hover { background: var(--surface-2); color: var(--text-primary); }\n.rz-menu__item svg { flex-shrink: 0; }\n.rz-menu__item--static { cursor: default; }\n.rz-menu__item--static:hover { background: none; color: var(--text-secondary); }\n.rz-menu__item .rz-menu__end { margin-left: auto; }\n.rz-menu__signout { margin: 0 0 .3rem; }\n.rz-seg { display: inline-flex; border: 1px solid var(--border); border-radius: var(--rz-radius); overflow: hidden; }\n.rz-seg button { font: inherit; font-size: .75rem; padding: .15rem .55rem; line-height: 1.3; background: transparent; color: var(--text-secondary); border: 0; cursor: pointer; }\n.rz-seg button[aria-pressed=\"true\"] { background: var(--surface-3); color: var(--text-primary); }\n\n/* ---- mobile: sidebar becomes a strip under the top bar --------------- */\n@media (max-width: 720px) {\n .rz-body { flex-direction: column; }\n .rz-sidebar, .rz-sidebar--collapsed { width: 100%; border-right: 0; border-bottom: 1px solid var(--border); flex-direction: row; }\n .rz-sidebar__nav { display: flex; padding: .35rem .25rem; overflow-x: auto; }\n .rz-sidebar__item { flex-direction: column; gap: .2rem; font-size: .6875rem; padding: .4rem .6rem; border-radius: 6px; }\n .rz-sidebar--collapsed .rz-sidebar__label { display: block; }\n .rz-sidebar__collapse { display: none; }\n .rz-sidebar__pinned { display: flex; border-top: 0; padding: .35rem .25rem; }\n .rz-topbar__greeting { display: none; }\n .rz-content { padding: 18px 14px 60px; }\n /* The sidebar is a top strip now, so it must not be sticky-height; the topbar stays pinned. */\n .rz-sidebar, .rz-sidebar--collapsed { position: static; height: auto; }\n .rz-sidebar__item--disabled { display: none; }\n /* Save bar: bleed matches the narrower content padding; stack status above the buttons. */\n .rz-content .realiiz-form__bar { margin: 18px -14px -60px; padding: 10px 14px; flex-wrap: wrap; }\n .rz-content .realiiz-form__status { flex-basis: 100%; margin-right: 0; font-size: .8rem; }\n /* Editor toolbar wraps; the Insert group drops its label and left rule to save width. */\n .rz-admin .realiiz-md__head { padding: 5px; }\n .rz-admin .realiiz-md__insert { border-left: 0; padding-left: 0; margin-left: 0; }\n .rz-admin .realiiz-md__lab { display: none; }\n .rz-admin .realiiz-md--fs { padding: 8px; }\n /* Tracker: notes hide, labels shrink, so three steps fit a phone. */\n .rz-step__note { display: none; }\n .rz-step__label { font-size: .8rem; }\n .rz-step:not(:last-child)::after { right: 6px; }\n /* Tables scroll sideways inside their own box instead of stretching the page. */\n .rz-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }\n .rz-pagehead { align-items: flex-start; flex-direction: column; }\n .rz-notice { flex-direction: column; align-items: flex-start; }\n .rz-card--narrow { max-width: none; }\n}\n\n/* ---- forms extras: markdown editor, chips, gauges, preview prose --------- */\n.rz-admin .realiiz-md { --_md-head: var(--surface-2); --_md-hover: var(--surface-2); --_md-hover-line: var(--signal-glow); --_md-on: color-mix(in srgb, var(--signal) 12%, var(--surface-1)); --_md-tip: var(--ink); }\n.rz-admin .realiiz-md__mode { background: var(--surface-2); }\n.rz-admin .realiiz-md__mode button { color: var(--text-secondary); }\n.rz-admin .realiiz-md__mode button[aria-selected=\"true\"] { background: var(--surface-1); color: var(--text-primary); box-shadow: 0 1px 2px rgba(14,23,38,.12); }\n.rz-admin .realiiz-md__panel, .rz-admin .realiiz-md__tgrid, .rz-admin .realiiz-md--fs, .rz-admin .realiiz-md .realiiz-md__ta, .rz-admin .realiiz-md__preview, .rz-admin .realiiz-md__head button { background: var(--surface-1); }\n.rz-admin .realiiz-md__head { background: var(--surface-2); }\n.rz-admin .realiiz-md__head button { color: var(--text-primary); }\n.rz-admin .realiiz-md__insert button { background: var(--surface-2); color: var(--text-secondary); }\n.rz-admin .realiiz-md__tgcells i { background: var(--surface-1); }\n.rz-admin .realiiz-md__tgcells i.hot { background: color-mix(in srgb, var(--signal) 18%, var(--surface-1)); }\n.rz-admin .realiiz-md__loading { color: var(--text-muted); font-size: .8rem; }\n.rz-admin .realiiz-prose { max-width: 68ch; font-size: 1rem; line-height: 1.65; color: var(--text-primary); }\n.rz-admin .realiiz-prose h1, .rz-admin .realiiz-prose h2, .rz-admin .realiiz-prose h3 { font-family: var(--rz-font-display); line-height: 1.25; margin: 1.4em 0 .5em; }\n.rz-admin .realiiz-prose h2 { font-size: 1.35rem; } .rz-admin .realiiz-prose h3 { font-size: 1.1rem; }\n.rz-admin .realiiz-prose p, .rz-admin .realiiz-prose ul, .rz-admin .realiiz-prose ol, .rz-admin .realiiz-prose blockquote { margin: 0 0 1em; }\n.rz-admin .realiiz-prose a { color: var(--signal); }\n/* The site's prose class picks a slate body colour for a light page; on the dark surface that reads as disabled. */\n.rz-admin[data-theme=\"dark\"] .realiiz-prose, .rz-admin[data-theme=\"dark\"] .realiiz-prose :is(p, li, td, th, dd, dt, figcaption, strong, b, em, i, h1, h2, h3, h4, h5, h6) { color: var(--text-primary); }\n.rz-admin[data-theme=\"dark\"] .realiiz-prose :is(code, kbd) { color: var(--text-primary); background: var(--surface-3); }\n.rz-admin[data-theme=\"dark\"] .realiiz-prose a { color: var(--signal-dim); }\n.rz-admin[data-theme=\"dark\"] .realiiz-prose hr { border-color: var(--border); }\n.rz-admin[data-theme=\"dark\"] .realiiz-prose blockquote { color: var(--text-secondary); }\n.rz-admin .realiiz-prose blockquote { border-left: 3px solid var(--border); padding-left: 1em; color: var(--text-secondary); }\n.rz-admin .realiiz-prose code { background: var(--surface-2); padding: 0 4px; border-radius: 4px; font-family: var(--rz-font-mono); font-size: .9em; }\n.rz-admin .realiiz-prose pre { background: var(--surface-2); padding: 12px 14px; border-radius: 6px; overflow-x: auto; }\n.rz-admin .realiiz-prose img { max-width: 100%; height: auto; border-radius: 6px; }\n.rz-admin .realiiz-chips { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; min-height: 40px; padding: 5px 8px; background: var(--surface-0); border: 1px solid var(--border); border-radius: var(--rz-radius); }\n.rz-admin .realiiz-chips:focus-within { border-color: var(--signal); box-shadow: var(--realiiz-form-focus-ring); }\n.rz-admin .realiiz-chip { display: inline-flex; align-items: center; gap: 4px; padding: 2px 4px 2px 9px; background: var(--surface-3); border: 1px solid var(--border); border-radius: 999px; font-size: .8rem; color: var(--text-primary); }\n.rz-admin .realiiz-chip button { font: inherit; line-height: 1; width: 18px; height: 18px; border-radius: 50%; border: 0; background: transparent; color: var(--text-muted); cursor: pointer; }\n.rz-admin .realiiz-chip button:hover { background: var(--status-down); color: #fff; }\n.rz-admin .realiiz-chips__input { flex: 1; min-width: 120px; border: 0; background: transparent; font: inherit; color: inherit; outline: none; padding: 4px; }\n.rz-admin .realiiz-chips__count { margin-left: auto; color: var(--text-muted); font-size: .75rem; font-variant-numeric: tabular-nums; }\n.rz-admin .realiiz-gauge { color: var(--text-muted); }\n.rz-admin .realiiz-gauge__bar { background: var(--surface-3); }\n.rz-admin .realiiz-gauge__zone { background: color-mix(in srgb, var(--status-up) 28%, transparent); }\n.rz-admin .realiiz-gauge__fill { background: var(--text-muted); }\n.rz-admin .realiiz-gauge--ok .realiiz-gauge__fill { background: var(--status-up); } .rz-admin .realiiz-gauge--ok { color: var(--status-up); }\n.rz-admin .realiiz-gauge--over .realiiz-gauge__fill { background: var(--status-down); } .rz-admin .realiiz-gauge--over { color: var(--status-down); }\n";
173
193
 
174
- export { AccountMenu, AdminShell, type AdminShellProps, Button, type ButtonSize, type ButtonVariant, Card, EmptyState, ForwardArrow, Icon, type IconName, LinkButton, type NavItem, OutboundArrow, PageHeader, type PillTone, SHELL_CSS, type ShellUser, Sidebar, StatusPill, type StepState, Steps, type Theme, ThemeToggle, TopBar, buttonClass, buttonStyle, firstNameOf, iconFor, initialsOf, isActive, useTheme };
194
+ /**
195
+ * Tabs — which SECTION of this page am I on (Account: My Profile · Change
196
+ * Password · Team · Business). Underlined strip, same as the visibility
197
+ * tracker's: five two-word labels stay on one line where pills would wrap.
198
+ * Not for choosing a value or filtering — that is a segmented control.
199
+ * Keyboard: Left/Right (and Home/End) move between tabs.
200
+ */
201
+ interface TabOption {
202
+ value: string;
203
+ label: string;
204
+ /** A small marker after the label — a count, an unsaved dot. Keep it short. */
205
+ suffix?: string;
206
+ }
207
+ declare function Tabs({ options, value, onChange, label }: {
208
+ options: TabOption[];
209
+ value: string;
210
+ onChange: (value: string) => void;
211
+ label?: string;
212
+ }): react.JSX.Element;
213
+
214
+ export { AccountMenu, AdminShell, type AdminShellProps, Button, type ButtonSize, type ButtonVariant, Card, EmptyState, ForwardArrow, Icon, type IconName, LinkButton, type NavItem, OutboundArrow, PageHeader, type PillTone, SHELL_CSS, type ShellUser, Sidebar, StatusPill, type StepState, Steps, type TabOption, Tabs, type Theme, ThemeToggle, TopBar, buttonClass, buttonStyle, firstNameOf, iconFor, initialsOf, isActive, useTheme };
@@ -173,12 +173,21 @@ var SunIcon = () => /* @__PURE__ */ jsxs("svg", { ...ico, children: [
173
173
  /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "4" }),
174
174
  /* @__PURE__ */ jsx("path", { d: "M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4" })
175
175
  ] });
176
+ var UserIcon = () => /* @__PURE__ */ jsxs("svg", { ...ico, children: [
177
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "8", r: "4" }),
178
+ /* @__PURE__ */ jsx("path", { d: "M4 21a8 8 0 0 1 16 0" })
179
+ ] });
180
+ var HelpIcon = () => /* @__PURE__ */ jsxs("svg", { ...ico, children: [
181
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "9" }),
182
+ /* @__PURE__ */ jsx("path", { d: "M9.5 9.5a2.5 2.5 0 1 1 3.5 2.3c-.7.3-1 .8-1 1.7" }),
183
+ /* @__PURE__ */ jsx("path", { d: "M12 17h.01" })
184
+ ] });
176
185
  var OutIcon = () => /* @__PURE__ */ jsxs("svg", { ...ico, children: [
177
186
  /* @__PURE__ */ jsx("path", { d: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" }),
178
187
  /* @__PURE__ */ jsx("path", { d: "M16 17l5-5-5-5" }),
179
188
  /* @__PURE__ */ jsx("path", { d: "M21 12H9" })
180
189
  ] });
181
- function AccountMenu({ user, role, theme, onTheme, signOutPath }) {
190
+ function AccountMenu({ user, role, theme, onTheme, signOutPath, accountHref, helpHref }) {
182
191
  const [open, setOpen] = useState(false);
183
192
  const wrap = useRef(null);
184
193
  useEffect(() => {
@@ -197,12 +206,21 @@ function AccountMenu({ user, role, theme, onTheme, signOutPath }) {
197
206
  };
198
207
  }, [open]);
199
208
  return /* @__PURE__ */ jsxs("div", { ref: wrap, style: { position: "relative" }, children: [
200
- /* @__PURE__ */ jsx("button", { type: "button", className: "rz-avatar", "aria-haspopup": "menu", "aria-expanded": open, "aria-label": "Account menu", onClick: () => setOpen((v) => !v), children: initialsOf(user) }),
209
+ /* @__PURE__ */ jsx("button", { type: "button", className: "rz-avatar", "aria-haspopup": "menu", "aria-expanded": open, "aria-label": "Account menu", onClick: () => setOpen((v) => !v), children: user.avatarUrl ? /* @__PURE__ */ jsx("img", { src: user.avatarUrl, alt: "", className: "rz-avatar__img" }) : initialsOf(user) }),
201
210
  open && /* @__PURE__ */ jsxs("div", { className: "rz-menu", role: "menu", children: [
202
211
  /* @__PURE__ */ jsxs("div", { className: "rz-menu__who", children: [
203
212
  /* @__PURE__ */ jsx("div", { className: "rz-menu__name", children: user.name?.trim() || user.email }),
204
213
  user.name?.trim() && /* @__PURE__ */ jsx("div", { className: "rz-menu__email", children: user.email })
205
214
  ] }),
215
+ accountHref && /* @__PURE__ */ jsxs("a", { href: accountHref, role: "menuitem", className: "rz-menu__item", children: [
216
+ /* @__PURE__ */ jsx(UserIcon, {}),
217
+ "Account"
218
+ ] }),
219
+ helpHref && /* @__PURE__ */ jsxs("a", { href: helpHref, role: "menuitem", className: "rz-menu__item", children: [
220
+ /* @__PURE__ */ jsx(HelpIcon, {}),
221
+ "Help"
222
+ ] }),
223
+ (accountHref || helpHref) && /* @__PURE__ */ jsx("div", { className: "rz-menu__sep" }),
206
224
  /* @__PURE__ */ jsxs("div", { className: "rz-menu__item rz-menu__item--static", role: "menuitem", "aria-disabled": "true", children: [
207
225
  /* @__PURE__ */ jsx(ShieldIcon, {}),
208
226
  /* @__PURE__ */ jsx("span", { children: "Role" }),
@@ -221,7 +239,7 @@ function AccountMenu({ user, role, theme, onTheme, signOutPath }) {
221
239
  ] })
222
240
  ] });
223
241
  }
224
- function TopBar({ siteName, productName, logoUrl, homeHref, user, role, theme, onTheme, signOutPath }) {
242
+ function TopBar({ siteName, productName, logoUrl, homeHref, user, role, theme, onTheme, signOutPath, accountHref, helpHref }) {
225
243
  return /* @__PURE__ */ jsxs("header", { className: "rz-topbar", children: [
226
244
  /* @__PURE__ */ jsxs("a", { href: homeHref, className: "rz-topbar__brand", children: [
227
245
  logoUrl && /* @__PURE__ */ jsx("img", { src: logoUrl, alt: "", className: "rz-topbar__logo" }),
@@ -233,7 +251,7 @@ function TopBar({ siteName, productName, logoUrl, homeHref, user, role, theme, o
233
251
  "Welcome back, ",
234
252
  firstNameOf(user)
235
253
  ] }),
236
- /* @__PURE__ */ jsx(AccountMenu, { user, role, theme, onTheme, signOutPath })
254
+ /* @__PURE__ */ jsx(AccountMenu, { user, role, theme, onTheme, signOutPath, accountHref, helpHref })
237
255
  ] })
238
256
  ] });
239
257
  }
@@ -393,7 +411,13 @@ var SHELL_CSS = `
393
411
  .rz-ok { border: 1px solid var(--status-up); color: var(--signal-dim); border-radius: var(--rz-radius); padding: 12px 14px; margin: 0 0 16px; }
394
412
 
395
413
  /* ---- account menu --------------------------------------------------- */
396
- .rz-avatar { width: 2rem; height: 2rem; border-radius: 50%; background: var(--surface-3); border: 1px solid var(--border); color: var(--text-primary); font-size: .6875rem; font-weight: 600; letter-spacing: .04em; display: flex; align-items: center; justify-content: center; cursor: pointer; font-family: inherit; padding: 0; }
414
+ .rz-avatar__img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; display: block; }
415
+ .rz-tabs { display: flex; gap: .25rem; border-bottom: 1px solid var(--border); margin: 0 0 1.5rem; flex-wrap: wrap; }
416
+ .rz-tabs__tab { padding: .55rem .9rem; font: inherit; font-size: .88rem; color: var(--text-secondary); background: none; border: 0; border-bottom: 2px solid transparent; margin-bottom: -1px; cursor: pointer; }
417
+ .rz-tabs__tab:hover { color: var(--text-primary); }
418
+ .rz-tabs__tab[aria-selected="true"] { color: var(--text-primary); border-bottom-color: var(--signal); font-weight: 600; }
419
+ .rz-tabs__tab:focus-visible { outline: 2px solid var(--signal); outline-offset: -2px; border-radius: 4px; }
420
+ .rz-avatar { width: 2rem; height: 2rem; border-radius: 50%; background: var(--surface-3); border: 1px solid var(--border); color: var(--text-primary); font-size: .6875rem; font-weight: 600; letter-spacing: .04em; display: flex; align-items: center; justify-content: center; cursor: pointer; font-family: inherit; padding: 0; overflow: hidden; }
397
421
  .rz-menu { position: absolute; right: 0; top: calc(100% + 8px); min-width: 15rem; background: var(--surface-1); border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 8px 24px rgba(14,23,38,.14); overflow: hidden; z-index: 50; }
398
422
  .rz-menu__who { padding: .75rem .9rem; border-bottom: 1px solid var(--border); margin-bottom: .3rem; }
399
423
  .rz-menu__name { font-weight: 600; font-size: .875rem; }
@@ -495,25 +519,32 @@ function AdminShell({
495
519
  activeHref,
496
520
  basePath = "/admin",
497
521
  signOutPath,
522
+ accountHref,
523
+ helpHref,
524
+ branding,
498
525
  defaultTheme = "light",
499
526
  children
500
527
  }) {
501
528
  const [theme, setTheme] = useTheme(defaultTheme);
502
529
  const showNav = Boolean(user && role);
530
+ const shownName = branding?.name?.trim() || siteName;
531
+ const shownLogo = branding?.logoUrl || logoUrl;
503
532
  return /* @__PURE__ */ jsxs("div", { className: "rz-admin", "data-theme": theme, children: [
504
533
  /* @__PURE__ */ jsx("style", { children: SHELL_CSS }),
505
534
  /* @__PURE__ */ jsx(
506
535
  TopBar,
507
536
  {
508
- siteName,
537
+ siteName: shownName,
509
538
  productName,
510
- logoUrl,
539
+ logoUrl: shownLogo,
511
540
  homeHref: basePath,
512
541
  user,
513
542
  role,
514
543
  theme,
515
544
  onTheme: setTheme,
516
- signOutPath: signOutPath ?? `${basePath}/auth/signout`
545
+ signOutPath: signOutPath ?? `${basePath}/auth/signout`,
546
+ accountHref: accountHref === null ? void 0 : accountHref ?? `${basePath}/account`,
547
+ helpHref: helpHref === null ? void 0 : helpHref ?? `${basePath}/help`
517
548
  }
518
549
  ),
519
550
  /* @__PURE__ */ jsxs("div", { className: "rz-body", children: [
@@ -588,7 +619,45 @@ function Steps({ steps }) {
588
619
  ] })
589
620
  ] }, i)) });
590
621
  }
622
+ function Tabs({ options, value, onChange, label = "Sections" }) {
623
+ const list = useRef(null);
624
+ const onKey = (e) => {
625
+ const i = options.findIndex((o) => o.value === value);
626
+ if (i < 0) return;
627
+ let next = i;
628
+ if (e.key === "ArrowRight") next = (i + 1) % options.length;
629
+ else if (e.key === "ArrowLeft") next = (i - 1 + options.length) % options.length;
630
+ else if (e.key === "Home") next = 0;
631
+ else if (e.key === "End") next = options.length - 1;
632
+ else return;
633
+ e.preventDefault();
634
+ onChange(options[next].value);
635
+ list.current?.children[next]?.focus();
636
+ };
637
+ return /* @__PURE__ */ jsx("div", { ref: list, className: "rz-tabs", role: "tablist", "aria-label": label, onKeyDown: onKey, children: options.map((o) => {
638
+ const active = o.value === value;
639
+ return /* @__PURE__ */ jsxs(
640
+ "button",
641
+ {
642
+ type: "button",
643
+ role: "tab",
644
+ className: "rz-tabs__tab",
645
+ "aria-selected": active,
646
+ tabIndex: active ? 0 : -1,
647
+ onClick: () => onChange(o.value),
648
+ children: [
649
+ o.label,
650
+ o.suffix && /* @__PURE__ */ jsxs("span", { className: "rz-muted", children: [
651
+ " ",
652
+ o.suffix
653
+ ] })
654
+ ]
655
+ },
656
+ o.value
657
+ );
658
+ }) });
659
+ }
591
660
 
592
- export { AccountMenu, AdminShell, Button, Card, EmptyState, ForwardArrow, Icon, LinkButton, OutboundArrow, PageHeader, SHELL_CSS, Sidebar, StatusPill, Steps, ThemeToggle, TopBar, buttonClass, buttonStyle, firstNameOf, iconFor, initialsOf, isActive, useTheme };
661
+ export { AccountMenu, AdminShell, Button, Card, EmptyState, ForwardArrow, Icon, LinkButton, OutboundArrow, PageHeader, SHELL_CSS, Sidebar, StatusPill, Steps, Tabs, ThemeToggle, TopBar, buttonClass, buttonStyle, firstNameOf, iconFor, initialsOf, isActive, useTheme };
593
662
  //# sourceMappingURL=index.js.map
594
663
  //# sourceMappingURL=index.js.map