1939 lines
131 KiB
HTML
1939 lines
131 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Admin Redesign Spec — Concept C · Familienarchiv</title>
|
||
<style>
|
||
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
|
||
body{font-family:'Helvetica Neue',Arial,sans-serif;background:#ECEAE4;color:#1A1A1A;line-height:1.5}
|
||
.doc{max-width:1560px;margin:0 auto;padding:48px 32px}
|
||
|
||
/* ── Doc header ── */
|
||
.doc-masthead{margin-bottom:56px;border-bottom:2px solid #C8C4BE;padding-bottom:28px}
|
||
.doc-masthead h1{font-size:26px;font-weight:800;color:#002850;letter-spacing:-.5px}
|
||
.doc-masthead p{margin-top:6px;color:#666;font-size:14px;max-width:680px;line-height:1.6}
|
||
.doc-masthead .meta{margin-top:10px;font-size:11px;color:#AAA;font-weight:600;letter-spacing:1px;text-transform:uppercase}
|
||
|
||
/* ── Section ── */
|
||
.section{margin-bottom:72px}
|
||
.section+.section{border-top:2px dashed #C8C4BE;padding-top:64px}
|
||
.sec-intro{display:flex;align-items:flex-start;gap:20px;margin-bottom:28px}
|
||
.sec-num{font-size:52px;font-weight:900;color:#DDD;line-height:1;flex-shrink:0;width:64px}
|
||
.sec-meta{}
|
||
.sec-badge{display:inline-block;font-size:10px;font-weight:800;padding:3px 10px;border-radius:20px;text-transform:uppercase;letter-spacing:1px;margin-bottom:6px}
|
||
.badge-arch{background:#F0F0F0;color:#555}
|
||
.badge-users{background:#E3EEFF;color:#1D4ED8}
|
||
.badge-groups{background:#E5F5EC;color:#15803D}
|
||
.badge-tags{background:#FEF3C7;color:#B45309}
|
||
.badge-system{background:#FEE2E2;color:#B91C1C}
|
||
.badge-edge{background:#F3E8FF;color:#7C3AED}
|
||
.sec-title{font-size:20px;font-weight:800;color:#002850;margin-bottom:4px}
|
||
.sec-tagline{font-size:13px;color:#666;max-width:620px;line-height:1.6}
|
||
|
||
/* ── Screen layout ── */
|
||
.screens{display:flex;gap:20px;align-items:flex-start;margin-bottom:16px;flex-wrap:wrap}
|
||
.screens.cols2{display:grid;grid-template-columns:1fr 1fr;gap:20px}
|
||
.screens.cols3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:16px}
|
||
.screen-block{display:flex;flex-direction:column;min-width:0}
|
||
.screen-label{font-size:10px;font-weight:800;color:#888;text-transform:uppercase;letter-spacing:1.5px;margin-bottom:8px;display:flex;align-items:center;gap:8px}
|
||
.sz{background:#E8E4DF;color:#666;padding:1px 6px;border-radius:3px;font-size:9px}
|
||
.state-tag{padding:1px 7px;border-radius:3px;font-size:9px;font-weight:700;background:#DBEAFE;color:#1E40AF}
|
||
.state-tag.new{background:#DCFCE7;color:#166534}
|
||
.state-tag.edit{background:#FEF3C7;color:#92400E}
|
||
.state-tag.del{background:#FEE2E2;color:#991B1B}
|
||
.state-tag.empty{background:#F3F4F6;color:#374151}
|
||
.state-tag.err{background:#FEE2E2;color:#991B1B}
|
||
.screen-cap{font-size:9px;color:#888;margin-top:6px;text-align:center;font-style:italic;line-height:1.5}
|
||
|
||
/* ── Wireframe frame ── */
|
||
.wf{background:#fff;border:2px solid #B8B4AE;border-radius:10px;overflow:hidden;box-shadow:0 4px 20px rgba(0,0,0,.08);position:relative}
|
||
.wf-bar{height:26px;background:#E8E4DF;border-bottom:1px solid #C8C4BE;display:flex;align-items:center;padding:0 10px;gap:5px}
|
||
.dot{width:8px;height:8px;border-radius:50%;background:#C8C4BE}
|
||
.urlbar{flex:1;height:13px;background:#D8D4CE;border-radius:3px;margin-left:8px}
|
||
|
||
/* ── Navbar ── */
|
||
.NAV{height:44px;background:#0D2240;display:flex;align-items:center;padding:0 18px;gap:14px}
|
||
.NAV-m{height:46px;background:#0D2240;display:flex;align-items:center;padding:0 14px;justify-content:space-between}
|
||
.logo{font-size:10px;font-weight:900;color:#fff;letter-spacing:1px}
|
||
.nl{font-size:8px;color:rgba(255,255,255,.55);font-weight:700;text-transform:uppercase;letter-spacing:.5px}
|
||
.nl.on{color:#fff;border-bottom:2px solid #A6DAD8;padding-bottom:2px}
|
||
.nr{margin-left:auto;display:flex;gap:8px;align-items:center}
|
||
.nico{width:22px;height:22px;background:rgba(255,255,255,.12);border-radius:5px}
|
||
.nlang{font-size:8px;color:rgba(255,255,255,.5);font-weight:700;display:flex;gap:4px}
|
||
.nlang .on{color:#fff}
|
||
|
||
/* ── Entity Nav ── */
|
||
.EN{width:120px;background:#0D2240;flex-shrink:0;display:flex;flex-direction:column}
|
||
.EN-head{padding:10px 12px 6px;font-size:7.5px;font-weight:800;color:rgba(255,255,255,.3);text-transform:uppercase;letter-spacing:1px}
|
||
.EN-item{padding:11px 14px;display:flex;flex-direction:column;gap:3px;cursor:pointer;border-left:3px solid transparent;flex-shrink:0}
|
||
.EN-item.on{background:rgba(255,255,255,.1);border-left-color:#A6DAD8}
|
||
.EN-lbl{font-size:9px;font-weight:800;color:rgba(255,255,255,.55);text-transform:uppercase;letter-spacing:.5px}
|
||
.EN-item.on .EN-lbl{color:#fff}
|
||
.EN-cnt{font-size:13px;font-weight:900;color:rgba(255,255,255,.2)}
|
||
.EN-item.on .EN-cnt{color:rgba(255,255,255,.65)}
|
||
.EN-spacer{flex:1}
|
||
.EN-item.sys{border-top:1px solid rgba(255,255,255,.1);margin-top:auto}
|
||
|
||
/* ── List Panel ── */
|
||
.LP{width:240px;flex-shrink:0;border-right:1px solid #E0DDD6;display:flex;flex-direction:column;background:#F7F5F2}
|
||
.LP-head{padding:10px 14px;border-bottom:1px solid #E0DDD6;background:#F0EDE8;display:flex;align-items:center;justify-content:space-between}
|
||
.LP-title{font-size:10px;font-weight:800;color:#0D2240;text-transform:uppercase;letter-spacing:.5px}
|
||
.LP-search{margin:8px 10px 4px;height:28px;border:1.5px solid #D1D5DB;border-radius:5px;background:#fff;display:flex;align-items:center;padding:0 8px;font-size:9px;color:#AAA;font-style:italic;gap:4px}
|
||
.LP-item{padding:9px 14px;border-bottom:1px solid #EAE7E2;cursor:pointer;display:flex;align-items:center;justify-content:space-between}
|
||
.LP-item:hover{background:#EEEAE5}
|
||
.LP-item.on{background:#EEF2FF;border-right:3px solid #002850}
|
||
.LP-name{font-size:10px;font-weight:700;color:#1A1A1A}
|
||
.LP-item.on .LP-name{color:#002850}
|
||
.LP-sub{font-size:8px;color:#999;margin-top:1px}
|
||
.LP-item.on .LP-sub{color:#7B9FD4}
|
||
.LP-chev{font-size:11px;color:#CCC}
|
||
.LP-item.on .LP-chev{color:#002850}
|
||
.LP-empty{padding:24px 14px;text-align:center;font-size:9px;color:#BBB;font-style:italic}
|
||
|
||
/* ── Detail Panel ── */
|
||
.DP{flex:1;display:flex;flex-direction:column;min-width:0;background:#fff}
|
||
.DP-head{padding:14px 20px;border-bottom:1px solid #E8E4DF;background:#F7F5F2;display:flex;align-items:flex-start;justify-content:space-between;flex-shrink:0}
|
||
.DP-title{font-size:14px;font-weight:800;color:#0D2240}
|
||
.DP-sub{font-size:9px;color:#888;margin-top:2px}
|
||
.DP-body{padding:16px 20px;flex:1;display:flex;flex-direction:column;gap:0;overflow:hidden}
|
||
.DP-empty{flex:1;display:flex;align-items:center;justify-content:center;flex-direction:column;gap:8px;padding:32px}
|
||
.DP-empty-icon{font-size:32px;opacity:.2}
|
||
.DP-empty-msg{font-size:11px;color:#AAA;text-align:center;line-height:1.6}
|
||
.DP-footer{background:#fff;border-top:1.5px solid #E8E4DF;padding:10px 20px;display:flex;align-items:center;justify-content:space-between;flex-shrink:0;box-shadow:0 -2px 8px rgba(0,0,0,.05)}
|
||
|
||
/* ── Shell ── */
|
||
.BODY{display:flex;min-height:0;flex:1}
|
||
|
||
/* ── Buttons ── */
|
||
.BTN{display:inline-flex;align-items:center;gap:4px;font-size:8px;font-weight:800;padding:5px 10px;border-radius:4px;text-transform:uppercase;letter-spacing:.5px;cursor:pointer;white-space:nowrap}
|
||
.BTN-sm{font-size:7.5px;padding:3px 8px}
|
||
.BTN-xs{font-size:7px;padding:2px 6px}
|
||
.BTN-primary{background:#002850;color:#fff}
|
||
.BTN-outline{border:1.5px solid #002850;color:#002850;background:transparent}
|
||
.BTN-ghost{color:#777;background:transparent}
|
||
.BTN-danger{border:1.5px solid #DC2626;color:#DC2626;background:#FEF2F2}
|
||
.BTN-danger-fill{background:#DC2626;color:#fff}
|
||
.BTN-warn{background:#D97706;color:#fff}
|
||
.BTN-green{background:#15803D;color:#fff}
|
||
.BTN-amber{border:1.5px solid #D97706;color:#D97706;background:#FFFBEB}
|
||
|
||
/* ── Form ── */
|
||
.FG{margin-bottom:10px}
|
||
.FG-row{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:10px}
|
||
.FL{display:block;font-size:8px;font-weight:800;color:#888;text-transform:uppercase;letter-spacing:.5px;margin-bottom:3px}
|
||
.FL .req{color:#DC2626}
|
||
.FI{width:100%;height:26px;border:1.5px solid #D1D5DB;border-radius:4px;background:#F9FAFB}
|
||
.FI.focus{border-color:#002850;background:#fff;box-shadow:0 0 0 3px rgba(0,40,80,.07)}
|
||
.FI.filled{display:flex;align-items:center;padding:0 8px;font-size:9px;color:#333}
|
||
.FTA{width:100%;height:52px;border:1.5px solid #D1D5DB;border-radius:4px;background:#F9FAFB}
|
||
.FI.err{border-color:#DC2626;background:#FFF5F5}
|
||
.ferr{font-size:8px;color:#DC2626;margin-top:2px}
|
||
|
||
/* ── Section header inside form ── */
|
||
.SH{font-size:8px;font-weight:800;color:#AAA;text-transform:uppercase;letter-spacing:1.5px;padding:10px 0 6px;border-top:1px solid #F0EDE6;margin-top:4px}
|
||
.SH:first-child{border-top:none;margin-top:0;padding-top:0}
|
||
|
||
/* ── Chips ── */
|
||
.CH{display:inline-flex;align-items:center;font-size:7.5px;font-weight:800;padding:2px 6px;border-radius:10px;text-transform:uppercase;letter-spacing:.3px}
|
||
.CH+.CH{margin-left:3px}
|
||
.CH-blue{background:#DBEAFE;color:#1E40AF;border:1px solid #BFDBFE}
|
||
.CH-red{background:#FEE2E2;color:#991B1B;border:1px solid #FCA5A5}
|
||
.CH-green{background:#DCFCE7;color:#166534;border:1px solid #BBF7D0}
|
||
.CH-grey{background:#F3F4F6;color:#374151;border:1px solid #E5E7EB}
|
||
.CH-warn{background:#FEF3C7;color:#92400E;border:1px solid #FDE68A}
|
||
.CH-amber{background:#FEF9C3;color:#854D0E;border:1px solid #FEF08A}
|
||
|
||
/* ── Perm grid ── */
|
||
.PG{display:grid;grid-template-columns:1fr 1fr;gap:5px}
|
||
.PI{display:flex;align-items:center;gap:5px;font-size:8px;color:#555;font-weight:600}
|
||
.CB{width:12px;height:12px;border:1.5px solid #C8C4BE;border-radius:2px;flex-shrink:0}
|
||
.CB.on{background:#002850;border-color:#002850}
|
||
.CB.warn{background:#DC2626;border-color:#DC2626}
|
||
|
||
/* ── Alerts ── */
|
||
.AL{padding:8px 10px;border-radius:5px;font-size:9px;line-height:1.5}
|
||
.AL-warn{background:#FFFBEB;border:1px solid #FDE68A;color:#92400E}
|
||
.AL-info{background:#EFF6FF;border:1px solid #BFDBFE;color:#1E40AF}
|
||
.AL-err{background:#FEF2F2;border:1px solid #FCA5A5;color:#991B1B}
|
||
.AL-ok{background:#F0FDF4;border:1px solid #BBF7D0;color:#166534}
|
||
|
||
/* ── Danger zone ── */
|
||
.DZ{border:1.5px solid #FCA5A5;border-radius:6px;padding:12px 14px;margin-top:4px;background:#FFF5F5}
|
||
.DZ-title{font-size:10px;font-weight:800;color:#991B1B;margin-bottom:4px;display:flex;align-items:center;gap:5px}
|
||
.DZ-desc{font-size:8.5px;color:#777;line-height:1.5;margin-bottom:8px}
|
||
.DZ-confirm{background:#FEE2E2;border:1.5px solid #FCA5A5;border-radius:4px;padding:8px 10px;margin-top:6px}
|
||
.DZ-confirm-msg{font-size:9px;color:#7F1D1D;font-weight:600;margin-bottom:6px}
|
||
|
||
/* ── System cards ── */
|
||
.SC{border:1.5px solid #E8E4DF;border-radius:6px;padding:12px 14px;margin-bottom:10px}
|
||
.SC.warn{border-color:#FDE68A;background:#FFFBEB}
|
||
.SC.danger{border-color:#FCA5A5;background:#FFF5F5}
|
||
.SC-title{font-size:11px;font-weight:800;color:#1A1A1A;margin-bottom:3px;display:flex;align-items:center;gap:6px}
|
||
.SC-badge{font-size:7.5px;padding:1px 5px;border-radius:3px;font-weight:800;text-transform:uppercase}
|
||
.SC.warn .SC-badge{background:#FDE68A;color:#92400E}
|
||
.SC.danger .SC-badge{background:#FCA5A5;color:#7F1D1D}
|
||
.SC-desc{font-size:8.5px;color:#777;line-height:1.5;margin-bottom:10px}
|
||
.SC-inline-confirm{background:#fff;border:1.5px solid #FDE68A;border-radius:4px;padding:8px 10px;margin-top:0}
|
||
.SC-loading{display:flex;align-items:center;gap:8px;font-size:9px;color:#666;padding:6px 0}
|
||
.SC-spinner{width:14px;height:14px;border:2px solid #E8E4DF;border-top-color:#002850;border-radius:50%}
|
||
|
||
/* ── Tag list ── */
|
||
.TL-row{display:flex;align-items:center;padding:8px 14px;border-bottom:1px solid #F0EDE6}
|
||
.TL-row:hover{background:#FAFAF7}
|
||
.TL-chip{display:inline-block;background:#F3F4F6;border:1px solid #E5E7EB;border-radius:4px;padding:2px 8px;font-size:9px;font-weight:600;color:#374151}
|
||
.TL-cnt{font-size:8px;color:#AAA;margin-left:6px}
|
||
.TL-actions{display:flex;gap:5px;margin-left:auto}
|
||
|
||
/* ── Icon buttons ── */
|
||
.IB{width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:5px;font-size:13px;border:1px solid #E8E4DF;background:#fff;color:#666;cursor:pointer}
|
||
.IB.edit{color:#2563EB;border-color:#BFDBFE;background:#EFF6FF}
|
||
.IB.del{color:#DC2626;border-color:#FCA5A5;background:#FEF2F2}
|
||
|
||
/* ── Decision box ── */
|
||
.DECISION{background:#F0F7FF;border:1.5px solid #BFDBFE;border-radius:8px;padding:14px 16px;margin:16px 0}
|
||
.DECISION-title{font-size:10px;font-weight:800;color:#1E40AF;text-transform:uppercase;letter-spacing:.5px;margin-bottom:6px;display:flex;align-items:center;gap:6px}
|
||
.DECISION ul{display:flex;flex-direction:column;gap:4px;padding-left:0}
|
||
.DECISION li{font-size:11px;color:#1E3A5F;line-height:1.5;list-style:none;padding-left:14px;position:relative}
|
||
.DECISION li::before{content:'→';position:absolute;left:0;color:#60A5FA}
|
||
|
||
/* ── Spec notes ── */
|
||
.SPEC{background:#fff;border:1px solid #E8E4DF;border-radius:8px;padding:16px;margin-top:16px}
|
||
.SPEC-title{font-size:10px;font-weight:800;color:#555;text-transform:uppercase;letter-spacing:1px;margin-bottom:10px}
|
||
.SPEC-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px}
|
||
.SPEC-col{}
|
||
.SPEC-rule{margin-bottom:8px}
|
||
.SPEC-rule-num{font-size:9px;font-weight:800;color:#002850;margin-bottom:2px}
|
||
.SPEC-rule-text{font-size:11px;color:#444;line-height:1.5}
|
||
.SPEC-rule-code{font-size:10px;font-family:monospace;background:#F3F4F6;padding:1px 4px;border-radius:2px;color:#1A1A1A}
|
||
|
||
/* ── Mobile mini screens ── */
|
||
.mobile-flow{display:flex;gap:12px;align-items:flex-start;flex-wrap:wrap}
|
||
.mobile-step{display:flex;flex-direction:column;align-items:center;gap:4px}
|
||
.mobile-step-label{font-size:8px;color:#888;font-style:italic;text-align:center}
|
||
.mobile-arrow{font-size:20px;color:#CCC;align-self:center;margin-top:36px}
|
||
.wf-m{background:#fff;border:2px solid #B8B4AE;border-radius:10px;overflow:hidden;box-shadow:0 4px 16px rgba(0,0,0,.08);position:relative;width:155px}
|
||
|
||
/* ── URL bar annotation ── */
|
||
.URL-LINE{background:#F0EDE8;border:1px solid #DDD8D0;border-radius:4px;padding:4px 10px;font-size:9px;font-family:monospace;color:#555;margin-bottom:8px}
|
||
.URL-LINE span.qs{color:#1D4ED8}
|
||
|
||
/* ── Placeholder ── */
|
||
.PH{height:8px;background:#E8E4DF;border-radius:3px;margin-bottom:5px}
|
||
.PH.w30{width:30%}.PH.w50{width:50%}.PH.w70{width:70%}.PH.w40{width:40%}.PH.w60{width:60%}
|
||
|
||
/* ── Breakpoint table ── */
|
||
.BP-table{width:100%;border-collapse:collapse;font-size:11px;margin-top:8px}
|
||
.BP-table th{text-align:left;padding:8px 12px;font-size:10px;font-weight:800;color:#888;text-transform:uppercase;letter-spacing:.5px;border-bottom:2px solid #E8E4DF;background:#F7F5F2}
|
||
.BP-table td{padding:8px 12px;border-bottom:1px solid #F0EDE6;color:#444;vertical-align:top}
|
||
.BP-table tr:last-child td{border-bottom:none}
|
||
.BP-table code{font-size:10px;font-family:monospace;background:#F3F4F6;padding:1px 4px;border-radius:2px}
|
||
|
||
/* ── Summary table (end) ── */
|
||
.SUM-table{width:100%;border-collapse:collapse;font-size:11px}
|
||
.SUM-table th{text-align:left;padding:9px 14px;font-size:10px;font-weight:800;color:#888;text-transform:uppercase;letter-spacing:.5px;border-bottom:2px solid #E8E4DF;background:#F7F5F2}
|
||
.SUM-table td{padding:8px 14px;border-bottom:1px solid #F0EDE6;color:#444;vertical-align:middle}
|
||
.SUM-table tr:nth-child(even) td{background:#FAFAF7}
|
||
|
||
/* ── Entity Icon Strip (48px — tablet) ── */
|
||
.EI{width:48px;background:#0D2240;flex-shrink:0;display:flex;flex-direction:column;border-right:1px solid rgba(255,255,255,.08)}
|
||
.EI-item{width:48px;height:52px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;cursor:pointer;border-left:3px solid transparent;flex-shrink:0;position:relative}
|
||
.EI-item.on{background:rgba(255,255,255,.1);border-left-color:#A6DAD8}
|
||
.EI-icon{width:20px;height:20px;border-radius:4px;background:rgba(255,255,255,.2);flex-shrink:0}
|
||
.EI-item.on .EI-icon{background:rgba(166,218,216,.7)}
|
||
.EI-cnt{font-size:9px;font-weight:800;color:rgba(255,255,255,.35)}
|
||
.EI-item.on .EI-cnt{color:rgba(255,255,255,.8)}
|
||
.EI-tip{position:absolute;left:52px;top:50%;transform:translateY(-50%);background:#0D2240;color:#fff;font-size:9px;font-weight:700;padding:4px 8px;border-radius:4px;white-space:nowrap;pointer-events:none;box-shadow:2px 2px 8px rgba(0,0,0,.3);border:1px solid rgba(255,255,255,.15);z-index:20}
|
||
.EI-tip::before{content:'';position:absolute;left:-5px;top:50%;transform:translateY(-50%);width:0;height:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-right:5px solid #0D2240}
|
||
.EI-spacer{flex:1}
|
||
.EI-item.sys{border-top:1px solid rgba(255,255,255,.1)}
|
||
|
||
/* ── List Panel — collapse toggle ── */
|
||
.LP-toggle{width:24px;height:24px;display:flex;align-items:center;justify-content:center;border-radius:4px;background:#E8E4DF;color:#555;font-size:12px;cursor:pointer;flex-shrink:0;border:none;font-weight:700}
|
||
.LP-toggle:hover{background:#D8D4CE}
|
||
|
||
/* ── Collapsed list handle ── */
|
||
.LP-handle{width:32px;flex-shrink:0;background:#F0EDE8;border-right:1px solid #E0DDD6;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;padding-top:8px;gap:6px;cursor:pointer}
|
||
.LP-handle:hover{background:#E8E4DF}
|
||
.LP-handle-btn{width:24px;height:24px;border-radius:4px;background:#E0DDD6;display:flex;align-items:center;justify-content:center;font-size:12px;color:#555;font-weight:700}
|
||
.LP-handle-label{font-size:8px;font-weight:800;color:#AAA;text-transform:uppercase;letter-spacing:1px;writing-mode:vertical-rl;transform:rotate(180deg);margin-top:4px}
|
||
|
||
/* ── Entity Flyout overlay ── */
|
||
.EF{position:absolute;left:48px;top:0;bottom:0;width:160px;background:#0D2240;z-index:15;box-shadow:4px 0 20px rgba(0,0,0,.4);display:flex;flex-direction:column}
|
||
.EF-head{padding:10px 14px 6px;font-size:7.5px;font-weight:800;color:rgba(255,255,255,.35);text-transform:uppercase;letter-spacing:1px;display:flex;align-items:center;justify-content:space-between}
|
||
.EF-close{font-size:14px;color:rgba(255,255,255,.5);cursor:pointer}
|
||
.EF-item{padding:11px 16px;display:flex;align-items:center;gap:10px;cursor:pointer;border-left:3px solid transparent}
|
||
.EF-item.on{background:rgba(255,255,255,.1);border-left-color:#A6DAD8}
|
||
.EF-item-icon{width:16px;height:16px;border-radius:3px;background:rgba(255,255,255,.2);flex-shrink:0}
|
||
.EF-item.on .EF-item-icon{background:rgba(166,218,216,.6)}
|
||
.EF-item-label{font-size:10px;font-weight:800;color:rgba(255,255,255,.6);text-transform:uppercase;letter-spacing:.5px}
|
||
.EF-item.on .EF-item-label{color:#fff}
|
||
.EF-item-cnt{margin-left:auto;font-size:9px;font-weight:800;color:rgba(255,255,255,.25);background:rgba(255,255,255,.1);padding:1px 6px;border-radius:8px}
|
||
.EF-item.on .EF-item-cnt{color:rgba(255,255,255,.7);background:rgba(255,255,255,.15)}
|
||
.EF-dim{position:absolute;left:208px;top:0;right:0;bottom:0;background:rgba(0,0,0,.3);z-index:14}
|
||
|
||
/* ── Layout spec diagram ── */
|
||
.layout-diagram{display:flex;gap:0;height:56px;border:1.5px solid #D1D5DB;border-radius:6px;overflow:hidden;font-size:8px;font-weight:800;text-transform:uppercase;letter-spacing:.5px}
|
||
.ld-en{background:#0D2240;color:rgba(255,255,255,.7);display:flex;align-items:center;justify-content:center;flex-shrink:0;border-right:1px solid rgba(255,255,255,.2)}
|
||
.ld-lp{background:#F7F5F2;color:#888;display:flex;align-items:center;justify-content:center;flex-shrink:0;border-right:1px solid #D1D5DB}
|
||
.ld-dp{background:#fff;color:#334155;display:flex;align-items:center;justify-content:center;flex:1}
|
||
.ld-label{font-size:7.5px;font-weight:800;text-align:center;line-height:1.4}
|
||
.ld-px{font-size:9px;font-weight:900;margin-top:2px}
|
||
|
||
/* ── Transition arrow rows ── */
|
||
.transition-row{display:flex;align-items:center;gap:16px;margin:8px 0;padding:10px 16px;background:#fff;border:1px solid #E8E4DF;border-radius:6px}
|
||
.transition-label{font-size:9px;font-weight:800;color:#002850;background:#EEF2FF;border-radius:4px;padding:2px 8px;flex-shrink:0;min-width:44px;text-align:center}
|
||
.transition-arrow{font-size:18px;color:#A6DAD8;flex-shrink:0}
|
||
.transition-desc{font-size:11px;color:#444;line-height:1.4}
|
||
|
||
/* ── Comparison table ── */
|
||
.CMP{width:100%;border-collapse:collapse;font-size:11px;margin-top:8px}
|
||
.CMP th{text-align:left;padding:8px 12px;font-size:10px;font-weight:800;color:#888;text-transform:uppercase;letter-spacing:.5px;border-bottom:2px solid #E8E4DF;background:#F7F5F2}
|
||
.CMP td{padding:8px 12px;border-bottom:1px solid #F0EDE6;color:#444;vertical-align:top}
|
||
.CMP tr:last-child td{border-bottom:none}
|
||
.yes{color:#15803D;font-weight:700}
|
||
.no{color:#DC2626;font-weight:700}
|
||
|
||
/* ── State tags ── */
|
||
.st{padding:1px 7px;border-radius:3px;font-size:9px;font-weight:700}
|
||
.st-a{background:#DBEAFE;color:#1E40AF}
|
||
.st-b{background:#DCFCE7;color:#166534}
|
||
.st-c{background:#FEF3C7;color:#92400E}
|
||
|
||
/* ── Tablet section badge ── */
|
||
.badge-tablet{background:#E0F2FE;color:#0369A1}
|
||
|
||
/* ── Code ── */
|
||
code{font-size:10px;font-family:monospace;background:#F3F4F6;padding:1px 4px;border-radius:2px;color:#1A1A1A}
|
||
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="doc">
|
||
|
||
<!-- ══ HEADER ══ -->
|
||
<div class="doc-masthead">
|
||
<h1>Admin Section — Concept C Specification</h1>
|
||
<p>Complete screen spec for the Master-Detail Command Center redesign. Covers all four entity types (Users, Groups, Tags, System) across every state: default, create, edit, delete confirmation, empty, and error. Desktop (1440px) and mobile (375px) flows for each entity. Includes a tablet addendum (sections A–D) covering the collapseable 768–1023px panel layout.</p>
|
||
<div class="meta">Leonie Voss · Familienarchiv Admin Spec · v1.1 · 2026-03</div>
|
||
</div>
|
||
|
||
|
||
<!-- ══════════════════════════════════════════════════════════ -->
|
||
<!-- S0 · ARCHITECTURE -->
|
||
<!-- ══════════════════════════════════════════════════════════ -->
|
||
<div class="section">
|
||
<div class="sec-intro">
|
||
<div class="sec-num">0</div>
|
||
<div class="sec-meta">
|
||
<span class="sec-badge badge-arch">Architecture</span>
|
||
<div class="sec-title">Panel Anatomy & Navigation Model</div>
|
||
<div class="sec-tagline">Three persistent panels on desktop. Stacked push-navigation on mobile. All state lives in URL query params.</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Architecture diagram -->
|
||
<div class="screens" style="margin-bottom:20px">
|
||
<div class="screen-block" style="flex:1">
|
||
<div class="screen-label">Desktop panel anatomy <span class="sz">≥1024px</span></div>
|
||
<div class="wf">
|
||
<div class="wf-bar"><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="urlbar"></div></div>
|
||
<div class="NAV">
|
||
<div class="logo">FAMILIENARCHIV</div>
|
||
<div class="nl">Documents</div><div class="nl">Persons</div><div class="nl">Conversations</div><div class="nl on">Admin</div>
|
||
<div class="nr"><div class="nlang"><span>DE</span><span class="on">EN</span><span>ES</span></div><div class="nico"></div><div class="nico"></div><div class="nico"></div></div>
|
||
</div>
|
||
<div class="BODY" style="height:260px">
|
||
<!-- Entity nav annotated -->
|
||
<div class="EN" style="position:relative">
|
||
<div style="position:absolute;top:-22px;left:0;right:0;text-align:center;font-size:8px;font-weight:800;color:#1D4ED8;background:#E3EEFF;border-radius:3px;padding:2px 4px">ENTITY NAV · 120px</div>
|
||
<div class="EN-head">Admin</div>
|
||
<div class="EN-item on"><div class="EN-cnt">4</div><div class="EN-lbl">Users</div></div>
|
||
<div class="EN-item"><div class="EN-cnt">3</div><div class="EN-lbl">Groups</div></div>
|
||
<div class="EN-item"><div class="EN-cnt">3</div><div class="EN-lbl">Tags</div></div>
|
||
<div class="EN-spacer"></div>
|
||
<div class="EN-item sys"><div class="EN-lbl">System</div></div>
|
||
</div>
|
||
<!-- List panel annotated -->
|
||
<div class="LP" style="position:relative;width:200px">
|
||
<div style="position:absolute;top:-22px;left:0;right:0;text-align:center;font-size:8px;font-weight:800;color:#15803D;background:#E5F5EC;border-radius:3px;padding:2px 4px">LIST PANEL · 240px</div>
|
||
<div class="LP-head"><div class="LP-title">All Users</div><div class="BTN BTN-primary BTN-sm">+ New</div></div>
|
||
<div class="LP-search">🔍 Search…</div>
|
||
<div class="LP-item on"><div><div class="LP-name">reader</div><div class="LP-sub">Leser</div></div><div class="LP-chev">›</div></div>
|
||
<div class="LP-item"><div><div class="LP-name">marcel</div><div class="LP-sub">Marcel Raddatz</div></div><div class="LP-chev">›</div></div>
|
||
<div class="LP-item"><div><div class="LP-name">berit</div><div class="LP-sub">Berit Cram</div></div><div class="LP-chev">›</div></div>
|
||
<div class="LP-item"><div><div class="LP-name">admin</div><div class="LP-sub">Administrators</div></div><div class="LP-chev">›</div></div>
|
||
</div>
|
||
<!-- Detail panel annotated -->
|
||
<div class="DP" style="position:relative">
|
||
<div style="position:absolute;top:-22px;left:0;right:0;text-align:center;font-size:8px;font-weight:800;color:#B45309;background:#FEF3C7;border-radius:3px;padding:2px 4px">DETAIL PANEL · flex (all remaining width)</div>
|
||
<div class="DP-head"><div><div class="DP-title">Edit user: reader</div><div class="DP-sub">Last modified 2026-03-27 · Leser group</div></div><div class="BTN BTN-danger BTN-sm">Delete…</div></div>
|
||
<div class="DP-body">
|
||
<div class="SH" style="padding-top:0;border-top:none">Personal info</div>
|
||
<div class="FG-row"><div class="FG"><div class="FL">First name</div><div class="FI"></div></div><div class="FG"><div class="FL">Last name</div><div class="FI"></div></div></div>
|
||
<div class="FG"><div class="FL">Email address</div><div class="FI"></div></div>
|
||
</div>
|
||
<div class="DP-footer"><div class="BTN BTN-ghost">Discard</div><div class="BTN BTN-primary">Save changes</div></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Breakpoint + URL tables side by side -->
|
||
<div class="screens cols2" style="margin-top:32px">
|
||
<div class="screen-block">
|
||
<div class="screen-label">Breakpoint behaviour</div>
|
||
<div style="background:#fff;border:1px solid #E8E4DF;border-radius:8px;overflow:hidden">
|
||
<table class="BP-table">
|
||
<thead><tr><th>Viewport</th><th>Layout</th><th>Entity Nav</th></tr></thead>
|
||
<tbody>
|
||
<tr><td><code>≥1024px</code></td><td>3 panels side-by-side</td><td>Always visible (left)</td></tr>
|
||
<tr><td><code>768–1023px</code></td><td>List + Detail (2 panels)</td><td>Collapsed to icon-strip top bar</td></tr>
|
||
<tr><td><code><768px</code></td><td>Full-screen per step</td><td>Step 1 full-screen</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
<div class="screen-block">
|
||
<div class="screen-label">URL scheme (SvelteKit query params)</div>
|
||
<div style="background:#fff;border:1px solid #E8E4DF;border-radius:8px;overflow:hidden">
|
||
<table class="BP-table">
|
||
<thead><tr><th>State</th><th>URL</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>Admin landing</td><td><code>/admin</code></td></tr>
|
||
<tr><td>Users list</td><td><code>/admin?v=users</code></td></tr>
|
||
<tr><td>Create new user</td><td><code>/admin?v=users&id=new</code></td></tr>
|
||
<tr><td>Edit user</td><td><code>/admin?v=users&id=<uuid></code></td></tr>
|
||
<tr><td>Groups / create</td><td><code>/admin?v=groups&id=new</code></td></tr>
|
||
<tr><td>Tags / edit tag</td><td><code>/admin?v=tags&id=<uuid></code></td></tr>
|
||
<tr><td>System</td><td><code>/admin?v=system</code></td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="DECISION" style="margin-top:16px">
|
||
<div class="DECISION-title">🏗 Key architectural decisions</div>
|
||
<ul>
|
||
<li>URL params make every admin state shareable and browser-back navigable — no lost context on refresh</li>
|
||
<li>Entity nav uses count badges loaded from the same server load as the page — no extra requests</li>
|
||
<li>Detail panel save bar is docked to the detail panel only — not full-width — so it doesn't cover the list on wide screens</li>
|
||
<li>On mobile, each panel is full-screen; <code>goto()</code> pushes the next step; the browser back button pops it</li>
|
||
<li>SvelteKit: <code>+page.svelte</code> reads <code>$page.url.searchParams</code> for <code>v</code> and <code>id</code>; server load pre-fetches the selected entity</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<!-- ══════════════════════════════════════════════════════════ -->
|
||
<!-- S1 · USERS -->
|
||
<!-- ══════════════════════════════════════════════════════════ -->
|
||
<div class="section">
|
||
<div class="sec-intro">
|
||
<div class="sec-num">1</div>
|
||
<div class="sec-meta">
|
||
<span class="sec-badge badge-users">Entity: Users</span>
|
||
<div class="sec-title">User Management</div>
|
||
<div class="sec-tagline">Four states: empty selection, create new, edit existing, delete confirmation. Users navigate to /admin/users/[id] in the current design — in the new design this all happens within /admin.</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 1a: Landing state (no item selected) -->
|
||
<div class="screens" style="margin-bottom:8px">
|
||
<div class="screen-block" style="flex:1">
|
||
<div class="screen-label">1a — Users selected, no item chosen <span class="sz">1440px</span> <span class="state-tag empty">Empty selection</span></div>
|
||
<div class="URL-LINE">/admin<span class="qs">?v=users</span></div>
|
||
<div class="wf">
|
||
<div class="wf-bar"><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="urlbar"></div></div>
|
||
<div class="NAV"><div class="logo">FAMILIENARCHIV</div><div class="nl">Documents</div><div class="nl">Persons</div><div class="nl on">Admin</div><div class="nr"><div class="nico"></div><div class="nico"></div><div class="nico"></div></div></div>
|
||
<div class="BODY" style="height:320px">
|
||
<div class="EN">
|
||
<div class="EN-head">Admin</div>
|
||
<div class="EN-item on"><div class="EN-cnt">4</div><div class="EN-lbl">Users</div></div>
|
||
<div class="EN-item"><div class="EN-cnt">3</div><div class="EN-lbl">Groups</div></div>
|
||
<div class="EN-item"><div class="EN-cnt">3</div><div class="EN-lbl">Tags</div></div>
|
||
<div class="EN-spacer"></div>
|
||
<div class="EN-item sys"><div class="EN-lbl">System</div></div>
|
||
</div>
|
||
<div class="LP">
|
||
<div class="LP-head"><div class="LP-title">All Users</div><div class="BTN BTN-primary BTN-sm">+ New</div></div>
|
||
<div class="LP-search">🔍 Search users…</div>
|
||
<div class="LP-item"><div><div class="LP-name">reader</div><div class="LP-sub"><span class="CH CH-blue">Leser</span></div></div><div class="LP-chev">›</div></div>
|
||
<div class="LP-item"><div><div class="LP-name">marcel</div><div class="LP-sub">Marcel Raddatz</div></div><div class="LP-chev">›</div></div>
|
||
<div class="LP-item"><div><div class="LP-name">berit</div><div class="LP-sub">Berit Cram</div></div><div class="LP-chev">›</div></div>
|
||
<div class="LP-item"><div><div class="LP-name">admin</div><div class="LP-sub"><span class="CH CH-red">Administrators</span></div></div><div class="LP-chev">›</div></div>
|
||
</div>
|
||
<div class="DP">
|
||
<div class="DP-empty">
|
||
<div class="DP-empty-icon">👤</div>
|
||
<div class="DP-empty-msg">Select a user to view and edit their details,<br>or create a new user with the button above.</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="screen-cap">No item pre-selected on first load — prompt guides user to the next action</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 1b + 1c side by side -->
|
||
<div class="screens cols2" style="margin-top:20px">
|
||
<!-- 1b: Create -->
|
||
<div class="screen-block">
|
||
<div class="screen-label">1b — Create new user <span class="sz">1440px</span> <span class="state-tag new">New</span></div>
|
||
<div class="URL-LINE">/admin<span class="qs">?v=users&id=new</span></div>
|
||
<div class="wf">
|
||
<div class="wf-bar"><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="urlbar"></div></div>
|
||
<div class="NAV"><div class="logo">FAMILIENARCHIV</div><div class="nl on">Admin</div><div class="nr"><div class="nico"></div></div></div>
|
||
<div class="BODY" style="height:400px">
|
||
<div class="EN">
|
||
<div class="EN-head">Admin</div>
|
||
<div class="EN-item on"><div class="EN-cnt">4</div><div class="EN-lbl">Users</div></div>
|
||
<div class="EN-item"><div class="EN-cnt">3</div><div class="EN-lbl">Groups</div></div>
|
||
<div class="EN-item"><div class="EN-cnt">3</div><div class="EN-lbl">Tags</div></div>
|
||
<div class="EN-spacer"></div>
|
||
<div class="EN-item sys"><div class="EN-lbl">System</div></div>
|
||
</div>
|
||
<div class="LP">
|
||
<div class="LP-head"><div class="LP-title">All Users</div><div class="BTN BTN-primary BTN-sm">+ New</div></div>
|
||
<div class="LP-search">🔍 Search…</div>
|
||
<div class="LP-item" style="background:#F0FDF4;border-right:3px solid #15803D"><div><div class="LP-name" style="color:#15803D">+ New user</div><div class="LP-sub" style="color:#6EE7B7;font-style:italic">Unsaved</div></div><div class="LP-chev" style="color:#15803D">›</div></div>
|
||
<div class="LP-item"><div><div class="LP-name">reader</div><div class="LP-sub">Leser</div></div><div class="LP-chev">›</div></div>
|
||
<div class="LP-item"><div><div class="LP-name">marcel</div><div class="LP-sub">Marcel Raddatz</div></div><div class="LP-chev">›</div></div>
|
||
</div>
|
||
<div class="DP">
|
||
<div class="DP-head" style="background:#F0FDF4;border-bottom-color:#BBF7D0"><div><div class="DP-title" style="color:#15803D">Create new user</div><div class="DP-sub">Fill in credentials and personal info below</div></div></div>
|
||
<div class="DP-body" style="overflow:auto">
|
||
<div class="SH" style="border-top:none;padding-top:0">Credentials <span style="color:#DC2626;font-size:8px">* required</span></div>
|
||
<div class="FG-row">
|
||
<div class="FG"><div class="FL">Login / Username <span class="req">*</span></div><div class="FI focus"></div></div>
|
||
<div class="FG"><div class="FL">Password <span class="req">*</span></div><div class="FI"></div></div>
|
||
</div>
|
||
<div class="SH">Personal information</div>
|
||
<div class="FG-row">
|
||
<div class="FG"><div class="FL">First name</div><div class="FI"></div></div>
|
||
<div class="FG"><div class="FL">Last name</div><div class="FI"></div></div>
|
||
</div>
|
||
<div class="FG-row">
|
||
<div class="FG"><div class="FL">Date of birth</div><div class="FI" style="display:flex;align-items:center;padding:0 8px;font-size:9px;color:#BBB;font-style:italic">DD.MM.YYYY</div></div>
|
||
<div class="FG"><div class="FL">Email address</div><div class="FI"></div></div>
|
||
</div>
|
||
<div class="FG"><div class="FL">Contact details</div><div class="FTA"></div></div>
|
||
<div class="SH">Groups</div>
|
||
<div style="display:flex;gap:10px;flex-wrap:wrap">
|
||
<div class="PI"><div class="CB"></div> Leser</div>
|
||
<div class="PI"><div class="CB"></div> Administrators</div>
|
||
<div class="PI"><div class="CB on"></div> Editor</div>
|
||
</div>
|
||
</div>
|
||
<div class="DP-footer"><div class="BTN BTN-ghost">Cancel</div><div class="BTN BTN-green">Create user</div></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="screen-cap">"+ New user" placeholder appears at top of list · Detail panel has green tint to signal create mode</div>
|
||
</div>
|
||
|
||
<!-- 1c: Edit existing -->
|
||
<div class="screen-block">
|
||
<div class="screen-label">1c — Edit existing user <span class="sz">1440px</span> <span class="state-tag edit">Edit</span></div>
|
||
<div class="URL-LINE">/admin<span class="qs">?v=users&id=a1b2c3…</span></div>
|
||
<div class="wf">
|
||
<div class="wf-bar"><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="urlbar"></div></div>
|
||
<div class="NAV"><div class="logo">FAMILIENARCHIV</div><div class="nl on">Admin</div><div class="nr"><div class="nico"></div></div></div>
|
||
<div class="BODY" style="height:400px">
|
||
<div class="EN">
|
||
<div class="EN-head">Admin</div>
|
||
<div class="EN-item on"><div class="EN-cnt">4</div><div class="EN-lbl">Users</div></div>
|
||
<div class="EN-item"><div class="EN-cnt">3</div><div class="EN-lbl">Groups</div></div>
|
||
<div class="EN-item"><div class="EN-cnt">3</div><div class="EN-lbl">Tags</div></div>
|
||
<div class="EN-spacer"></div>
|
||
<div class="EN-item sys"><div class="EN-lbl">System</div></div>
|
||
</div>
|
||
<div class="LP">
|
||
<div class="LP-head"><div class="LP-title">All Users</div><div class="BTN BTN-primary BTN-sm">+ New</div></div>
|
||
<div class="LP-search">🔍 Search…</div>
|
||
<div class="LP-item"><div><div class="LP-name">reader</div><div class="LP-sub">Leser</div></div><div class="LP-chev">›</div></div>
|
||
<div class="LP-item on"><div><div class="LP-name">marcel</div><div class="LP-sub">Marcel Raddatz</div></div><div class="LP-chev">›</div></div>
|
||
<div class="LP-item"><div><div class="LP-name">berit</div><div class="LP-sub">Berit Cram</div></div><div class="LP-chev">›</div></div>
|
||
<div class="LP-item"><div><div class="LP-name">admin</div></div><div class="LP-chev">›</div></div>
|
||
</div>
|
||
<div class="DP">
|
||
<div class="DP-head"><div><div class="DP-title">Edit user: marcel</div><div class="DP-sub">Created 2025-01-12 · Editor group · last login 2026-03-28</div></div><div class="BTN BTN-danger BTN-sm">Delete…</div></div>
|
||
<div class="DP-body" style="overflow:auto">
|
||
<div class="SH" style="border-top:none;padding-top:0">Credentials</div>
|
||
<div class="FG"><div class="FL">Login (username)</div><div class="FI filled" style="background:#F3F4F6;color:#888">marcel <span style="font-size:8px;color:#AAA;margin-left:4px">— cannot be changed</span></div></div>
|
||
<div class="SH">Personal information</div>
|
||
<div class="FG-row">
|
||
<div class="FG"><div class="FL">First name</div><div class="FI filled">Marcel</div></div>
|
||
<div class="FG"><div class="FL">Last name</div><div class="FI filled">Raddatz</div></div>
|
||
</div>
|
||
<div class="FG-row">
|
||
<div class="FG"><div class="FL">Date of birth</div><div class="FI"></div></div>
|
||
<div class="FG"><div class="FL">Email address</div><div class="FI filled" style="font-size:8.5px">m.raddatz@example.com</div></div>
|
||
</div>
|
||
<div class="FG"><div class="FL">Contact details</div><div class="FTA"></div></div>
|
||
<div class="SH">Groups</div>
|
||
<div style="display:flex;gap:10px;flex-wrap:wrap;margin-bottom:8px">
|
||
<div class="PI"><div class="CB"></div> Leser</div>
|
||
<div class="PI"><div class="CB"></div> Administrators</div>
|
||
<div class="PI"><div class="CB on"></div> Editor</div>
|
||
</div>
|
||
<div class="SH">Change password</div>
|
||
<div class="FG-row">
|
||
<div class="FG"><div class="FL">New password</div><div class="FI"></div></div>
|
||
<div class="FG"><div class="FL">Repeat new password</div><div class="FI"></div></div>
|
||
</div>
|
||
</div>
|
||
<div class="DP-footer"><div class="BTN BTN-ghost">Discard changes</div><div class="BTN BTN-primary">Save changes</div></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="screen-cap">Username is read-only in edit mode · Password fields optional · Delete button top-right of detail header</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 1d: Delete confirmation -->
|
||
<div class="screens" style="margin-top:20px">
|
||
<div class="screen-block" style="flex:1">
|
||
<div class="screen-label">1d — Delete confirmation (inline danger zone) <span class="sz">1440px</span> <span class="state-tag del">Delete</span></div>
|
||
<div class="URL-LINE">/admin<span class="qs">?v=users&id=a1b2c3…</span> — same URL, detail panel reveals danger zone</div>
|
||
<div class="wf">
|
||
<div class="wf-bar"><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="urlbar"></div></div>
|
||
<div class="NAV"><div class="logo">FAMILIENARCHIV</div><div class="nl on">Admin</div><div class="nr"><div class="nico"></div></div></div>
|
||
<div class="BODY" style="height:280px">
|
||
<div class="EN">
|
||
<div class="EN-head">Admin</div>
|
||
<div class="EN-item on"><div class="EN-cnt">4</div><div class="EN-lbl">Users</div></div>
|
||
<div class="EN-item"><div class="EN-cnt">3</div><div class="EN-lbl">Groups</div></div>
|
||
</div>
|
||
<div class="LP">
|
||
<div class="LP-head"><div class="LP-title">All Users</div><div class="BTN BTN-primary BTN-sm">+ New</div></div>
|
||
<div class="LP-item on" style="background:#FFF5F5;border-right-color:#DC2626"><div><div class="LP-name" style="color:#991B1B">marcel</div><div class="LP-sub" style="color:#FCA5A5">Pending delete…</div></div><div class="LP-chev" style="color:#DC2626">›</div></div>
|
||
<div class="LP-item" style="opacity:.4"><div><div class="LP-name">reader</div></div></div>
|
||
<div class="LP-item" style="opacity:.4"><div><div class="LP-name">berit</div></div></div>
|
||
</div>
|
||
<div class="DP">
|
||
<div class="DP-head" style="background:#FFF5F5;border-bottom-color:#FCA5A5"><div><div class="DP-title" style="color:#991B1B">⚠ Delete user: marcel</div><div class="DP-sub">This action cannot be undone</div></div><div class="BTN BTN-ghost BTN-sm">✕ Cancel</div></div>
|
||
<div class="DP-body">
|
||
<div class="DZ">
|
||
<div class="DZ-title">🗑 Permanently delete "marcel"</div>
|
||
<div class="DZ-desc">This user will be permanently removed. Their name may still appear on historical document records as sender or recipient, but they will no longer be able to log in.</div>
|
||
<div class="DZ-confirm">
|
||
<div class="DZ-confirm-msg">Type the username to confirm: <strong>marcel</strong></div>
|
||
<div class="FG"><div class="FI focus" style="display:flex;align-items:center;padding:0 8px;font-size:10px;font-weight:700;color:#991B1B">marcel</div></div>
|
||
<div style="display:flex;gap:8px;margin-top:8px">
|
||
<div class="BTN BTN-ghost">Cancel</div>
|
||
<div class="BTN BTN-danger-fill">Permanently delete user</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="screen-cap">Clicking "Delete…" in the detail header replaces the form with the danger zone · User must type the username to confirm · List item shows "Pending delete…" state</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 1e: Mobile flow -->
|
||
<div style="margin-top:20px">
|
||
<div class="screen-label">1e — Mobile navigation flow <span class="sz">375px</span></div>
|
||
<div class="mobile-flow">
|
||
|
||
<!-- Step 1: Entity picker -->
|
||
<div class="mobile-step">
|
||
<div class="mobile-step-label">Step 1 · Entity picker</div>
|
||
<div class="wf-m">
|
||
<div class="NAV-m" style="height:44px"><div class="logo" style="font-size:9px">FAMILIENARCHIV</div><div style="display:flex;gap:5px"><div class="nico" style="width:20px;height:20px"></div></div></div>
|
||
<div style="background:#0D2240;min-height:280px">
|
||
<div style="padding:10px 14px 6px;font-size:7px;font-weight:800;color:rgba(255,255,255,.3);text-transform:uppercase;letter-spacing:1px">Manage</div>
|
||
<div style="padding:14px 16px;border-bottom:1px solid rgba(255,255,255,.08);display:flex;justify-content:space-between;align-items:center">
|
||
<div><div style="font-size:12px;font-weight:800;color:#fff">Users</div><div style="font-size:8.5px;color:rgba(255,255,255,.4)">4 accounts</div></div>
|
||
<div style="font-size:13px;color:rgba(255,255,255,.4)">›</div>
|
||
</div>
|
||
<div style="padding:14px 16px;border-bottom:1px solid rgba(255,255,255,.08);display:flex;justify-content:space-between;align-items:center">
|
||
<div><div style="font-size:12px;font-weight:800;color:#fff">Groups</div><div style="font-size:8.5px;color:rgba(255,255,255,.4)">3 groups</div></div>
|
||
<div style="font-size:13px;color:rgba(255,255,255,.4)">›</div>
|
||
</div>
|
||
<div style="padding:14px 16px;border-bottom:1px solid rgba(255,255,255,.08);display:flex;justify-content:space-between;align-items:center">
|
||
<div><div style="font-size:12px;font-weight:800;color:#fff">Tags</div><div style="font-size:8.5px;color:rgba(255,255,255,.4)">3 tags</div></div>
|
||
<div style="font-size:13px;color:rgba(255,255,255,.4)">›</div>
|
||
</div>
|
||
<div style="padding:14px 16px;display:flex;justify-content:space-between;align-items:center">
|
||
<div style="font-size:12px;font-weight:800;color:rgba(255,255,255,.5)">System</div>
|
||
<div style="font-size:13px;color:rgba(255,255,255,.3)">›</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mobile-arrow">›</div>
|
||
|
||
<!-- Step 2: User list -->
|
||
<div class="mobile-step">
|
||
<div class="mobile-step-label">Step 2 · User list</div>
|
||
<div class="wf-m">
|
||
<div style="height:44px;background:#0D2240;display:flex;align-items:center;padding:0 14px;gap:8px">
|
||
<div style="color:rgba(255,255,255,.7);font-size:14px">‹</div>
|
||
<div style="font-size:11px;font-weight:800;color:#fff;flex:1">Users</div>
|
||
<div class="BTN BTN-primary BTN-xs">+ New</div>
|
||
</div>
|
||
<div style="background:#F7F5F2;min-height:280px">
|
||
<div style="padding:6px 10px;background:#fff;border-bottom:1px solid #E8E4DF">
|
||
<div style="height:26px;border:1.5px solid #D1D5DB;border-radius:4px;background:#F9FAFB;display:flex;align-items:center;padding:0 8px;font-size:8.5px;color:#AAA;font-style:italic">🔍 Search users…</div>
|
||
</div>
|
||
<div style="padding:10px 12px;border-bottom:1px solid #EAE7E2;display:flex;justify-content:space-between;align-items:center">
|
||
<div><div style="font-size:11px;font-weight:700">reader</div><div style="margin-top:2px"><span class="CH CH-blue">Leser</span></div></div>
|
||
<div style="font-size:13px;color:#CCC">›</div>
|
||
</div>
|
||
<div style="padding:10px 12px;border-bottom:1px solid #EAE7E2;display:flex;justify-content:space-between;align-items:center;background:#EEF2FF;border-right:3px solid #002850">
|
||
<div><div style="font-size:11px;font-weight:700;color:#002850">marcel</div><div style="font-size:8.5px;color:#7B9FD4;margin-top:1px">Marcel Raddatz</div></div>
|
||
<div style="font-size:13px;color:#002850">›</div>
|
||
</div>
|
||
<div style="padding:10px 12px;border-bottom:1px solid #EAE7E2;display:flex;justify-content:space-between;align-items:center">
|
||
<div><div style="font-size:11px;font-weight:700">berit</div><div style="font-size:8.5px;color:#999;margin-top:1px">Berit Cram</div></div>
|
||
<div style="font-size:13px;color:#CCC">›</div>
|
||
</div>
|
||
<div style="padding:10px 12px;display:flex;justify-content:space-between;align-items:center">
|
||
<div><div style="font-size:11px;font-weight:700">admin</div><div style="margin-top:2px"><span class="CH CH-red">Administrators</span></div></div>
|
||
<div style="font-size:13px;color:#CCC">›</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mobile-arrow">›</div>
|
||
|
||
<!-- Step 3: Edit detail -->
|
||
<div class="mobile-step">
|
||
<div class="mobile-step-label">Step 3 · User detail</div>
|
||
<div class="wf-m">
|
||
<div style="height:44px;background:#0D2240;display:flex;align-items:center;padding:0 14px;gap:8px">
|
||
<div style="color:rgba(255,255,255,.7);font-size:14px">‹</div>
|
||
<div style="font-size:10px;font-weight:800;color:#fff;flex:1">Edit: marcel</div>
|
||
<div class="BTN BTN-danger BTN-xs">Delete</div>
|
||
</div>
|
||
<div style="padding:12px;background:#fff;min-height:260px;overflow:hidden">
|
||
<div class="SH" style="padding-top:0;border-top:none">Personal</div>
|
||
<div class="FG"><div class="FL">First name</div><div class="FI filled" style="height:30px">Marcel</div></div>
|
||
<div class="FG"><div class="FL">Last name</div><div class="FI filled" style="height:30px">Raddatz</div></div>
|
||
<div class="FG"><div class="FL">Email</div><div class="FI" style="height:30px"></div></div>
|
||
<div class="SH">Groups</div>
|
||
<div style="display:flex;flex-direction:column;gap:6px">
|
||
<div class="PI" style="font-size:10px"><div class="CB" style="width:16px;height:16px"></div> Leser</div>
|
||
<div class="PI" style="font-size:10px"><div class="CB" style="width:16px;height:16px"></div> Administrators</div>
|
||
<div class="PI" style="font-size:10px"><div class="CB on" style="width:16px;height:16px"></div> Editor</div>
|
||
</div>
|
||
</div>
|
||
<div style="background:#fff;border-top:1.5px solid #E8E4DF;padding:10px 12px;display:flex;justify-content:space-between;align-items:center">
|
||
<div style="font-size:8px;font-weight:700;color:#888;text-transform:uppercase">Cancel</div>
|
||
<div class="BTN BTN-primary BTN-sm">Save changes</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="SPEC" style="margin-top:20px">
|
||
<div class="SPEC-title">Spec — Users entity</div>
|
||
<div class="SPEC-grid">
|
||
<div class="SPEC-col">
|
||
<div class="SPEC-rule"><div class="SPEC-rule-num">1.1 · Login field</div><div class="SPEC-rule-text">Username is required on create. On edit it is displayed as a read-only chip — username changes are not allowed without an explicit admin reset flow.</div></div>
|
||
<div class="SPEC-rule"><div class="SPEC-rule-num">1.2 · After create</div><div class="SPEC-rule-text">On success: list refreshes, new user appears alphabetically sorted, detail panel switches to edit mode for that user. URL updates to <span class="SPEC-rule-code">?v=users&id=<new-uuid></span>.</div></div>
|
||
<div class="SPEC-rule"><div class="SPEC-rule-num">1.3 · After save</div><div class="SPEC-rule-text">List item subtitle updates immediately. Save bar shows brief "Saved ✓" confirmation text for 2 seconds, then reverts to "Discard / Save changes".</div></div>
|
||
</div>
|
||
<div class="SPEC-col">
|
||
<div class="SPEC-rule"><div class="SPEC-rule-num">1.4 · Delete confirmation</div><div class="SPEC-rule-text">User must type the exact username to enable the confirm button. Username match is case-sensitive. After deletion: list removes item, detail shows empty-selection prompt, URL resets to <span class="SPEC-rule-code">?v=users</span>.</div></div>
|
||
<div class="SPEC-rule"><div class="SPEC-rule-num">1.5 · Unsaved changes guard</div><div class="SPEC-rule-text">If user clicks another list item while there are unsaved changes, show an inline warning banner at top of detail panel: "You have unsaved changes — save or discard before switching."</div></div>
|
||
<div class="SPEC-rule"><div class="SPEC-rule-num">1.6 · Password on edit</div><div class="SPEC-rule-text">Both "New password" fields are optional. If one is filled and the other is empty, show validation error inline before allowing save.</div></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<!-- ══════════════════════════════════════════════════════════ -->
|
||
<!-- S2 · GROUPS -->
|
||
<!-- ══════════════════════════════════════════════════════════ -->
|
||
<div class="section">
|
||
<div class="sec-intro">
|
||
<div class="sec-num">2</div>
|
||
<div class="sec-meta">
|
||
<span class="sec-badge badge-groups">Entity: Groups</span>
|
||
<div class="sec-title">Permission Groups</div>
|
||
<div class="sec-tagline">Groups define what users can do. The permission matrix (5 checkboxes) is the core of the edit form. ADMIN permission is visually distinguished from safe permissions.</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 2a + 2b side by side -->
|
||
<div class="screens cols2">
|
||
<!-- 2a: Create group -->
|
||
<div class="screen-block">
|
||
<div class="screen-label">2a — Create new group <span class="sz">1440px</span> <span class="state-tag new">New</span></div>
|
||
<div class="URL-LINE">/admin<span class="qs">?v=groups&id=new</span></div>
|
||
<div class="wf">
|
||
<div class="wf-bar"><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="urlbar"></div></div>
|
||
<div class="NAV"><div class="logo">FAMILIENARCHIV</div><div class="nl on">Admin</div><div class="nr"><div class="nico"></div></div></div>
|
||
<div class="BODY" style="height:360px">
|
||
<div class="EN">
|
||
<div class="EN-head">Admin</div>
|
||
<div class="EN-item"><div class="EN-cnt">4</div><div class="EN-lbl">Users</div></div>
|
||
<div class="EN-item on"><div class="EN-cnt">3</div><div class="EN-lbl">Groups</div></div>
|
||
<div class="EN-item"><div class="EN-cnt">3</div><div class="EN-lbl">Tags</div></div>
|
||
<div class="EN-spacer"></div>
|
||
<div class="EN-item sys"><div class="EN-lbl">System</div></div>
|
||
</div>
|
||
<div class="LP">
|
||
<div class="LP-head"><div class="LP-title">All Groups</div><div class="BTN BTN-primary BTN-sm">+ New</div></div>
|
||
<div class="LP-item" style="background:#F0FDF4;border-right:3px solid #15803D"><div><div class="LP-name" style="color:#15803D">+ New group</div><div class="LP-sub" style="color:#6EE7B7;font-style:italic">Unsaved</div></div><div class="LP-chev" style="color:#15803D">›</div></div>
|
||
<div class="LP-item"><div><div class="LP-name">Leser</div><div class="LP-sub">1 permission</div></div><div class="LP-chev">›</div></div>
|
||
<div class="LP-item"><div><div class="LP-name">Administrators</div><div class="LP-sub">6 permissions</div></div><div class="LP-chev">›</div></div>
|
||
<div class="LP-item"><div><div class="LP-name">Editor</div><div class="LP-sub">2 permissions</div></div><div class="LP-chev">›</div></div>
|
||
</div>
|
||
<div class="DP">
|
||
<div class="DP-head" style="background:#F0FDF4;border-bottom-color:#BBF7D0"><div><div class="DP-title" style="color:#15803D">Create new group</div><div class="DP-sub">Define a name and assign permissions</div></div></div>
|
||
<div class="DP-body">
|
||
<div class="SH" style="border-top:none;padding-top:0">Group name <span style="color:#DC2626;font-size:8px">* required</span></div>
|
||
<div class="FG"><div class="FL">Name</div><div class="FI focus"></div></div>
|
||
<div class="SH">Permissions</div>
|
||
<div style="background:#F7F5F2;border:1px solid #E8E4DF;border-radius:6px;padding:12px;display:flex;flex-direction:column;gap:8px">
|
||
<!-- Safe perms -->
|
||
<div style="font-size:8px;font-weight:800;color:#888;text-transform:uppercase;letter-spacing:1px;margin-bottom:2px">Standard access</div>
|
||
<div style="display:flex;gap:16px;flex-wrap:wrap">
|
||
<div class="PI"><div class="CB on"></div> READ_ALL <span style="font-size:7.5px;color:#888;margin-left:3px">— read documents</span></div>
|
||
<div class="PI"><div class="CB"></div> WRITE_ALL <span style="font-size:7.5px;color:#888;margin-left:3px">— create & edit docs</span></div>
|
||
<div class="PI"><div class="CB"></div> ANNOTATE_ALL <span style="font-size:7.5px;color:#888;margin-left:3px">— add annotations</span></div>
|
||
</div>
|
||
<!-- Danger perms -->
|
||
<div style="font-size:8px;font-weight:800;color:#DC2626;text-transform:uppercase;letter-spacing:1px;margin-top:4px;margin-bottom:2px">⚙ Administrative (grant carefully)</div>
|
||
<div style="display:flex;gap:16px;flex-wrap:wrap">
|
||
<div class="PI"><div class="CB"></div> <span style="color:#DC2626;font-weight:800">ADMIN</span> <span style="font-size:7.5px;color:#888;margin-left:3px">— full admin access</span></div>
|
||
<div class="PI"><div class="CB"></div> ADMIN_USER <span style="font-size:7.5px;color:#888;margin-left:3px">— manage users</span></div>
|
||
<div class="PI"><div class="CB"></div> ADMIN_TAG <span style="font-size:7.5px;color:#888;margin-left:3px">— manage tags</span></div>
|
||
<div class="PI"><div class="CB"></div> ADMIN_PERMISSION <span style="font-size:7.5px;color:#888;margin-left:3px">— manage perms</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="DP-footer"><div class="BTN BTN-ghost">Cancel</div><div class="BTN BTN-green">Create group</div></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="screen-cap">Permissions split into "Standard" and "Administrative" sections · Admin perms shown in red with ⚙ icon</div>
|
||
</div>
|
||
|
||
<!-- 2b: Edit group (Administrators expanded) -->
|
||
<div class="screen-block">
|
||
<div class="screen-label">2b — Edit group: Administrators <span class="sz">1440px</span> <span class="state-tag edit">Edit</span></div>
|
||
<div class="URL-LINE">/admin<span class="qs">?v=groups&id=b2c3d4…</span></div>
|
||
<div class="wf">
|
||
<div class="wf-bar"><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="urlbar"></div></div>
|
||
<div class="NAV"><div class="logo">FAMILIENARCHIV</div><div class="nl on">Admin</div><div class="nr"><div class="nico"></div></div></div>
|
||
<div class="BODY" style="height:360px">
|
||
<div class="EN">
|
||
<div class="EN-head">Admin</div>
|
||
<div class="EN-item"><div class="EN-cnt">4</div><div class="EN-lbl">Users</div></div>
|
||
<div class="EN-item on"><div class="EN-cnt">3</div><div class="EN-lbl">Groups</div></div>
|
||
<div class="EN-item"><div class="EN-cnt">3</div><div class="EN-lbl">Tags</div></div>
|
||
<div class="EN-spacer"></div>
|
||
<div class="EN-item sys"><div class="EN-lbl">System</div></div>
|
||
</div>
|
||
<div class="LP">
|
||
<div class="LP-head"><div class="LP-title">All Groups</div><div class="BTN BTN-primary BTN-sm">+ New</div></div>
|
||
<div class="LP-item"><div><div class="LP-name">Leser</div><div class="LP-sub">1 permission · 1 user</div></div><div class="LP-chev">›</div></div>
|
||
<div class="LP-item on"><div><div class="LP-name">Administrators</div><div class="LP-sub">6 permissions · 1 user</div></div><div class="LP-chev">›</div></div>
|
||
<div class="LP-item"><div><div class="LP-name">Editor</div><div class="LP-sub">2 permissions · 2 users</div></div><div class="LP-chev">›</div></div>
|
||
</div>
|
||
<div class="DP">
|
||
<div class="DP-head"><div><div class="DP-title">Edit group: Administrators</div><div class="DP-sub">1 user in this group · 6 permissions assigned</div></div><div class="BTN BTN-danger BTN-sm">Delete…</div></div>
|
||
<div class="DP-body">
|
||
<div class="SH" style="border-top:none;padding-top:0">Group name</div>
|
||
<div class="FG"><div class="FL">Name</div><div class="FI filled">Administrators</div></div>
|
||
<div class="SH">Standard permissions</div>
|
||
<div style="display:flex;gap:16px;flex-wrap:wrap;margin-bottom:10px">
|
||
<div class="PI"><div class="CB on"></div> READ_ALL</div>
|
||
<div class="PI"><div class="CB on"></div> WRITE_ALL</div>
|
||
<div class="PI"><div class="CB on"></div> ANNOTATE_ALL</div>
|
||
</div>
|
||
<div class="SH" style="color:#DC2626;border-top-color:#FCA5A5">⚙ Administrative permissions</div>
|
||
<div style="display:flex;gap:16px;flex-wrap:wrap;background:#FFF5F5;border:1px solid #FCA5A5;border-radius:4px;padding:8px;margin-bottom:8px">
|
||
<div class="PI"><div class="CB on" style="background:#DC2626;border-color:#DC2626"></div> <span style="color:#991B1B;font-weight:800">ADMIN</span></div>
|
||
<div class="PI"><div class="CB on" style="background:#DC2626;border-color:#DC2626"></div> ADMIN_USER</div>
|
||
<div class="PI"><div class="CB on" style="background:#DC2626;border-color:#DC2626"></div> ADMIN_TAG</div>
|
||
<div class="PI"><div class="CB on" style="background:#DC2626;border-color:#DC2626"></div> ADMIN_PERMISSION</div>
|
||
</div>
|
||
<div class="SH">Members</div>
|
||
<div style="display:flex;gap:6px;flex-wrap:wrap">
|
||
<div style="display:flex;align-items:center;gap:4px;background:#F3F4F6;border:1px solid #E5E7EB;border-radius:20px;padding:3px 8px;font-size:9px;font-weight:600">admin <span style="color:#AAA;cursor:pointer;margin-left:2px">✕</span></div>
|
||
</div>
|
||
</div>
|
||
<div class="DP-footer"><div class="BTN BTN-ghost">Discard</div><div class="BTN BTN-primary">Save changes</div></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="screen-cap">Admin permissions shown in a red-tinted box · Members shown as removable chips · Subtitle shows counts</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Mobile groups flow -->
|
||
<div style="margin-top:20px">
|
||
<div class="screen-label">2c — Mobile flow <span class="sz">375px</span></div>
|
||
<div class="mobile-flow">
|
||
<div class="mobile-step">
|
||
<div class="mobile-step-label">Group list</div>
|
||
<div class="wf-m">
|
||
<div style="height:44px;background:#0D2240;display:flex;align-items:center;padding:0 14px;gap:8px"><div style="color:rgba(255,255,255,.7);font-size:14px">‹</div><div style="font-size:11px;font-weight:800;color:#fff;flex:1">Groups</div><div class="BTN BTN-primary BTN-xs">+ New</div></div>
|
||
<div style="background:#F7F5F2;min-height:260px">
|
||
<div style="padding:10px 12px;border-bottom:1px solid #EAE7E2;display:flex;justify-content:space-between;align-items:center"><div><div style="font-size:11px;font-weight:700">Leser</div><div style="font-size:8px;color:#999;margin-top:1px">1 permission</div></div><div style="font-size:13px;color:#CCC">›</div></div>
|
||
<div style="padding:10px 12px;border-bottom:1px solid #EAE7E2;display:flex;justify-content:space-between;align-items:center;background:#EEF2FF;border-right:3px solid #002850"><div><div style="font-size:11px;font-weight:700;color:#002850">Administrators</div><div style="font-size:8px;color:#7B9FD4;margin-top:1px">6 permissions</div></div><div style="font-size:13px;color:#002850">›</div></div>
|
||
<div style="padding:10px 12px;display:flex;justify-content:space-between;align-items:center"><div><div style="font-size:11px;font-weight:700">Editor</div><div style="font-size:8px;color:#999;margin-top:1px">2 permissions</div></div><div style="font-size:13px;color:#CCC">›</div></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="mobile-arrow">›</div>
|
||
<div class="mobile-step">
|
||
<div class="mobile-step-label">Group detail</div>
|
||
<div class="wf-m">
|
||
<div style="height:44px;background:#0D2240;display:flex;align-items:center;padding:0 14px;gap:8px"><div style="color:rgba(255,255,255,.7);font-size:14px">‹</div><div style="font-size:10px;font-weight:800;color:#fff;flex:1">Administrators</div><div class="BTN BTN-danger BTN-xs">Del</div></div>
|
||
<div style="padding:12px;background:#fff;min-height:270px">
|
||
<div class="FG"><div class="FL">Group name</div><div class="FI filled" style="height:30px">Administrators</div></div>
|
||
<div style="font-size:8px;font-weight:800;color:#888;text-transform:uppercase;letter-spacing:1px;margin:8px 0 4px">Standard</div>
|
||
<div style="display:flex;flex-direction:column;gap:5px;margin-bottom:8px">
|
||
<div class="PI" style="font-size:10px"><div class="CB on" style="width:15px;height:15px"></div> READ_ALL</div>
|
||
<div class="PI" style="font-size:10px"><div class="CB on" style="width:15px;height:15px"></div> WRITE_ALL</div>
|
||
</div>
|
||
<div style="font-size:8px;font-weight:800;color:#DC2626;text-transform:uppercase;letter-spacing:1px;margin-bottom:4px">⚙ Administrative</div>
|
||
<div style="display:flex;flex-direction:column;gap:5px;background:#FFF5F5;border:1px solid #FCA5A5;border-radius:4px;padding:8px">
|
||
<div class="PI" style="font-size:10px"><div class="CB on" style="width:15px;height:15px;background:#DC2626;border-color:#DC2626"></div> <span style="color:#991B1B;font-weight:800">ADMIN</span></div>
|
||
<div class="PI" style="font-size:10px"><div class="CB on" style="width:15px;height:15px;background:#DC2626;border-color:#DC2626"></div> ADMIN_USER</div>
|
||
</div>
|
||
</div>
|
||
<div style="background:#fff;border-top:1.5px solid #E8E4DF;padding:10px 12px;display:flex;justify-content:space-between;">
|
||
<div style="font-size:8px;font-weight:700;color:#888;text-transform:uppercase">Discard</div>
|
||
<div class="BTN BTN-primary BTN-sm">Save</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<!-- ══════════════════════════════════════════════════════════ -->
|
||
<!-- S3 · TAGS -->
|
||
<!-- ══════════════════════════════════════════════════════════ -->
|
||
<div class="section">
|
||
<div class="sec-intro">
|
||
<div class="sec-num">3</div>
|
||
<div class="sec-meta">
|
||
<span class="sec-badge badge-tags">Entity: Tags</span>
|
||
<div class="sec-title">Tag Management</div>
|
||
<div class="sec-tagline">Tags are simple (name only) but high-impact — renaming or deleting affects all linked documents. The detail panel shows the document count prominently and requires an explicit confirmation for destructive changes.</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="screens cols2">
|
||
<!-- 3a: Tag detail / rename -->
|
||
<div class="screen-block">
|
||
<div class="screen-label">3a — Tag detail (rename) <span class="sz">1440px</span> <span class="state-tag edit">Edit</span></div>
|
||
<div class="URL-LINE">/admin<span class="qs">?v=tags&id=c3d4e5…</span></div>
|
||
<div class="wf">
|
||
<div class="wf-bar"><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="urlbar"></div></div>
|
||
<div class="NAV"><div class="logo">FAMILIENARCHIV</div><div class="nl on">Admin</div><div class="nr"><div class="nico"></div></div></div>
|
||
<div class="BODY" style="height:360px">
|
||
<div class="EN">
|
||
<div class="EN-head">Admin</div>
|
||
<div class="EN-item"><div class="EN-cnt">4</div><div class="EN-lbl">Users</div></div>
|
||
<div class="EN-item"><div class="EN-cnt">3</div><div class="EN-lbl">Groups</div></div>
|
||
<div class="EN-item on"><div class="EN-cnt">3</div><div class="EN-lbl">Tags</div></div>
|
||
<div class="EN-spacer"></div>
|
||
<div class="EN-item sys"><div class="EN-lbl">System</div></div>
|
||
</div>
|
||
<div class="LP">
|
||
<div class="LP-head"><div class="LP-title">All Tags</div><div class="BTN BTN-primary BTN-sm">+ New</div></div>
|
||
<div class="LP-search">🔍 Filter tags…</div>
|
||
<div class="LP-item"><div><div class="LP-name">Familie</div><div class="LP-sub">34 documents</div></div><div class="LP-chev">›</div></div>
|
||
<div class="LP-item on"><div><div class="LP-name">Krieg</div><div class="LP-sub">12 documents</div></div><div class="LP-chev">›</div></div>
|
||
<div class="LP-item"><div><div class="LP-name">Urlaub</div><div class="LP-sub">7 documents</div></div><div class="LP-chev">›</div></div>
|
||
</div>
|
||
<div class="DP">
|
||
<div class="DP-head"><div><div class="DP-title">Edit tag: Krieg</div><div class="DP-sub">Used in 12 documents</div></div><div class="BTN BTN-danger BTN-sm">Delete…</div></div>
|
||
<div class="DP-body">
|
||
<div class="SH" style="border-top:none;padding-top:0">Tag name</div>
|
||
<div class="FG"><div class="FL">Name <span class="req">*</span></div><div class="FI focus filled">Krieg</div></div>
|
||
<div class="AL AL-warn" style="margin-top:4px">
|
||
⚠ <strong>Renaming</strong> this tag will update all 12 linked documents. The old name will no longer appear anywhere in the archive.
|
||
</div>
|
||
<div class="SH">Usage</div>
|
||
<div style="background:#F7F5F2;border:1px solid #E8E4DF;border-radius:6px;padding:12px;display:flex;gap:16px">
|
||
<div style="text-align:center"><div style="font-size:22px;font-weight:900;color:#0D2240">12</div><div style="font-size:8px;color:#888;text-transform:uppercase;letter-spacing:.5px">Documents</div></div>
|
||
<div style="flex:1;font-size:9px;color:#666;line-height:1.6">This tag is attached to 12 documents. You can browse them by going to Documents and filtering by this tag.</div>
|
||
</div>
|
||
<div class="SH">Danger zone</div>
|
||
<div class="DZ">
|
||
<div class="DZ-title">🗑 Delete this tag</div>
|
||
<div class="DZ-desc">Removes the tag from all 12 documents. Documents are not deleted — only the tag association is removed.</div>
|
||
<div class="BTN BTN-danger BTN-sm">Delete tag…</div>
|
||
</div>
|
||
</div>
|
||
<div class="DP-footer"><div class="BTN BTN-ghost">Discard</div><div class="BTN BTN-primary">Rename tag</div></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="screen-cap">Document count shown in list subtitle AND in detail usage card · Rename warning banner prominently above save bar</div>
|
||
</div>
|
||
|
||
<!-- 3b: Delete confirmation -->
|
||
<div class="screen-block">
|
||
<div class="screen-label">3b — Delete confirmation <span class="sz">1440px</span> <span class="state-tag del">Delete</span></div>
|
||
<div class="URL-LINE">/admin<span class="qs">?v=tags&id=c3d4e5…</span> — detail panel shows danger confirmation</div>
|
||
<div class="wf">
|
||
<div class="wf-bar"><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="urlbar"></div></div>
|
||
<div class="NAV"><div class="logo">FAMILIENARCHIV</div><div class="nl on">Admin</div><div class="nr"><div class="nico"></div></div></div>
|
||
<div class="BODY" style="height:360px">
|
||
<div class="EN">
|
||
<div class="EN-head">Admin</div>
|
||
<div class="EN-item"><div class="EN-cnt">4</div><div class="EN-lbl">Users</div></div>
|
||
<div class="EN-item"><div class="EN-cnt">3</div><div class="EN-lbl">Groups</div></div>
|
||
<div class="EN-item on"><div class="EN-cnt">3</div><div class="EN-lbl">Tags</div></div>
|
||
<div class="EN-spacer"></div>
|
||
<div class="EN-item sys"><div class="EN-lbl">System</div></div>
|
||
</div>
|
||
<div class="LP">
|
||
<div class="LP-head"><div class="LP-title">All Tags</div><div class="BTN BTN-primary BTN-sm">+ New</div></div>
|
||
<div class="LP-search">🔍 Filter tags…</div>
|
||
<div class="LP-item"><div><div class="LP-name">Familie</div><div class="LP-sub">34 documents</div></div><div class="LP-chev">›</div></div>
|
||
<div class="LP-item on" style="background:#FFF5F5;border-right-color:#DC2626"><div><div class="LP-name" style="color:#991B1B">Krieg</div><div class="LP-sub" style="color:#FCA5A5">Pending delete…</div></div><div class="LP-chev" style="color:#DC2626">›</div></div>
|
||
<div class="LP-item"><div><div class="LP-name">Urlaub</div><div class="LP-sub">7 documents</div></div><div class="LP-chev">›</div></div>
|
||
</div>
|
||
<div class="DP">
|
||
<div class="DP-head" style="background:#FFF5F5;border-bottom-color:#FCA5A5"><div><div class="DP-title" style="color:#991B1B">⚠ Delete tag: Krieg</div><div class="DP-sub">Used in 12 documents — this cannot be undone</div></div><div class="BTN BTN-ghost BTN-sm">✕ Cancel</div></div>
|
||
<div class="DP-body">
|
||
<div class="DZ">
|
||
<div class="DZ-title">🗑 Permanently delete tag "Krieg"</div>
|
||
<div class="DZ-desc">This will remove the "Krieg" tag from <strong>12 documents</strong>. The documents themselves will not be affected — only the tag association will be removed.</div>
|
||
<div class="AL AL-warn" style="margin-bottom:10px">The documents will still be searchable, but this tag will no longer appear as a filter option.</div>
|
||
<div class="DZ-confirm">
|
||
<div class="DZ-confirm-msg">Type the tag name to confirm: <strong>Krieg</strong></div>
|
||
<div class="FG"><div class="FI focus" style="display:flex;align-items:center;padding:0 8px;font-size:10px;font-weight:700;color:#991B1B">Krieg</div></div>
|
||
<div style="display:flex;gap:8px;margin-top:8px">
|
||
<div class="BTN BTN-ghost">Cancel</div>
|
||
<div class="BTN BTN-danger-fill">Delete tag and remove from 12 documents</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="screen-cap">Document count is prominently in the confirm button label — "Remove from 12 documents" — so impact is impossible to miss</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- New tag state -->
|
||
<div class="screens" style="margin-top:20px">
|
||
<div class="screen-block" style="max-width:640px">
|
||
<div class="screen-label">3c — Create new tag (minimal form) <span class="sz">1440px</span> <span class="state-tag new">New</span></div>
|
||
<div class="URL-LINE">/admin<span class="qs">?v=tags&id=new</span></div>
|
||
<div class="wf">
|
||
<div class="wf-bar"><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="urlbar"></div></div>
|
||
<div class="NAV"><div class="logo">FAMILIENARCHIV</div><div class="nl on">Admin</div><div class="nr"><div class="nico"></div></div></div>
|
||
<div class="BODY" style="height:240px">
|
||
<div class="EN">
|
||
<div class="EN-head">Admin</div>
|
||
<div class="EN-item"><div class="EN-cnt">4</div><div class="EN-lbl">Users</div></div>
|
||
<div class="EN-item"><div class="EN-cnt">3</div><div class="EN-lbl">Groups</div></div>
|
||
<div class="EN-item on"><div class="EN-cnt">3</div><div class="EN-lbl">Tags</div></div>
|
||
</div>
|
||
<div class="LP">
|
||
<div class="LP-head"><div class="LP-title">All Tags</div><div class="BTN BTN-primary BTN-sm">+ New</div></div>
|
||
<div class="LP-item" style="background:#F0FDF4;border-right:3px solid #15803D"><div><div class="LP-name" style="color:#15803D">+ New tag</div><div class="LP-sub" style="color:#6EE7B7;font-style:italic">Unsaved</div></div><div class="LP-chev" style="color:#15803D">›</div></div>
|
||
<div class="LP-item"><div><div class="LP-name">Familie</div><div class="LP-sub">34 docs</div></div><div class="LP-chev">›</div></div>
|
||
<div class="LP-item"><div><div class="LP-name">Krieg</div><div class="LP-sub">12 docs</div></div><div class="LP-chev">›</div></div>
|
||
</div>
|
||
<div class="DP">
|
||
<div class="DP-head" style="background:#F0FDF4;border-bottom-color:#BBF7D0"><div><div class="DP-title" style="color:#15803D">Create new tag</div></div></div>
|
||
<div class="DP-body">
|
||
<div class="SH" style="border-top:none;padding-top:0">Tag name</div>
|
||
<div class="FG" style="max-width:400px"><div class="FL">Name <span class="req">*</span></div><div class="FI focus"></div></div>
|
||
<div style="font-size:9px;color:#888;margin-top:4px">The tag will be immediately available for use on documents.</div>
|
||
</div>
|
||
<div class="DP-footer"><div class="BTN BTN-ghost">Cancel</div><div class="BTN BTN-green">Create tag</div></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="screen-cap">Tags are name-only — the create form is deliberately minimal. No over-engineering.</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<!-- ══════════════════════════════════════════════════════════ -->
|
||
<!-- S4 · SYSTEM -->
|
||
<!-- ══════════════════════════════════════════════════════════ -->
|
||
<div class="section">
|
||
<div class="sec-intro">
|
||
<div class="sec-num">4</div>
|
||
<div class="sec-meta">
|
||
<span class="sec-badge badge-system">Entity: System</span>
|
||
<div class="sec-title">System Maintenance Actions</div>
|
||
<div class="sec-tagline">No list panel for System — the entity nav goes directly to the detail panel (single-panel mode). Destructive / intensive operations use an inline expand-to-confirm pattern. async operations show inline progress and result.</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="screens cols2">
|
||
<!-- 4a: System idle -->
|
||
<div class="screen-block">
|
||
<div class="screen-label">4a — System panel (idle state) <span class="sz">1440px</span></div>
|
||
<div class="URL-LINE">/admin<span class="qs">?v=system</span></div>
|
||
<div class="wf">
|
||
<div class="wf-bar"><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="urlbar"></div></div>
|
||
<div class="NAV"><div class="logo">FAMILIENARCHIV</div><div class="nl on">Admin</div><div class="nr"><div class="nico"></div></div></div>
|
||
<div class="BODY" style="height:340px">
|
||
<div class="EN">
|
||
<div class="EN-head">Admin</div>
|
||
<div class="EN-item"><div class="EN-cnt">4</div><div class="EN-lbl">Users</div></div>
|
||
<div class="EN-item"><div class="EN-cnt">3</div><div class="EN-lbl">Groups</div></div>
|
||
<div class="EN-item"><div class="EN-cnt">3</div><div class="EN-lbl">Tags</div></div>
|
||
<div class="EN-spacer"></div>
|
||
<div class="EN-item sys on"><div class="EN-lbl">System</div></div>
|
||
</div>
|
||
<!-- No list panel for System — content fills the rest -->
|
||
<div style="flex:1;padding:20px;background:#fff;overflow:auto">
|
||
<div style="font-size:14px;font-weight:800;color:#0D2240;margin-bottom:4px">System Maintenance</div>
|
||
<div style="font-size:11px;color:#888;margin-bottom:20px">Run these operations carefully. They affect data across the entire archive.</div>
|
||
<div class="SC warn">
|
||
<div class="SC-title">Backfill history data <span class="SC-badge">MAINTENANCE</span></div>
|
||
<div class="SC-desc">Creates an initial history entry for all documents that do not have one yet (e.g. imported documents). Safe to run multiple times — already-backfilled documents are skipped.</div>
|
||
<div class="BTN BTN-amber BTN-sm">Backfill history…</div>
|
||
</div>
|
||
<div class="SC danger">
|
||
<div class="SC-title">Compute file hashes <span class="SC-badge">INTENSIVE</span></div>
|
||
<div class="SC-desc">Computes SHA-256 hashes for all uploaded documents that do not have one yet. CPU-intensive — recommend running during off-peak hours. Correctly links annotations to file versions.</div>
|
||
<div class="BTN BTN-danger BTN-sm">Compute file hashes…</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="screen-cap">System uses full-width content area (no list panel) · Each card styled by severity · "…" suffix on buttons signals "click to expand confirm"</div>
|
||
</div>
|
||
|
||
<!-- 4b: One action expanding to confirm + one in progress -->
|
||
<div class="screen-block">
|
||
<div class="screen-label">4b — Backfill confirming · Hashes in progress <span class="sz">1440px</span></div>
|
||
<div class="URL-LINE">/admin<span class="qs">?v=system</span></div>
|
||
<div class="wf">
|
||
<div class="wf-bar"><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="urlbar"></div></div>
|
||
<div class="NAV"><div class="logo">FAMILIENARCHIV</div><div class="nl on">Admin</div><div class="nr"><div class="nico"></div></div></div>
|
||
<div class="BODY" style="height:340px">
|
||
<div class="EN">
|
||
<div class="EN-head">Admin</div>
|
||
<div class="EN-item"><div class="EN-cnt">4</div><div class="EN-lbl">Users</div></div>
|
||
<div class="EN-item"><div class="EN-cnt">3</div><div class="EN-lbl">Groups</div></div>
|
||
<div class="EN-item"><div class="EN-cnt">3</div><div class="EN-lbl">Tags</div></div>
|
||
<div class="EN-spacer"></div>
|
||
<div class="EN-item sys on"><div class="EN-lbl">System</div></div>
|
||
</div>
|
||
<div style="flex:1;padding:20px;background:#fff;overflow:auto">
|
||
<div style="font-size:14px;font-weight:800;color:#0D2240;margin-bottom:20px">System Maintenance</div>
|
||
<!-- Backfill: confirm expanded -->
|
||
<div class="SC warn" style="border-color:#FCD34D">
|
||
<div class="SC-title">Backfill history data <span class="SC-badge">MAINTENANCE</span></div>
|
||
<div class="SC-desc">Creates an initial history entry for all documents without one.</div>
|
||
<div class="SC-inline-confirm">
|
||
<div style="font-size:9px;font-weight:700;color:#92400E;margin-bottom:8px">⚠ This will modify history records for documents that are missing an entry. Continue?</div>
|
||
<div style="display:flex;gap:8px">
|
||
<div class="BTN BTN-ghost BTN-sm">Cancel</div>
|
||
<div class="BTN BTN-warn BTN-sm">Yes, run backfill now</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- Hashes: running -->
|
||
<div class="SC danger" style="border-color:#FCA5A5">
|
||
<div class="SC-title">Compute file hashes <span class="SC-badge">RUNNING…</span></div>
|
||
<div class="SC-desc">Computing SHA-256 for all documents without a hash.</div>
|
||
<div class="SC-loading">
|
||
<div class="SC-spinner" style="animation:none;border-top-color:#DC2626"></div>
|
||
<span style="font-size:9px;color:#DC2626;font-weight:600">Processing… (this may take a few minutes)</span>
|
||
</div>
|
||
<!-- Progress bar -->
|
||
<div style="height:4px;background:#FEE2E2;border-radius:2px;margin-top:8px"><div style="width:62%;height:100%;background:#DC2626;border-radius:2px"></div></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="screen-cap">Backfill: "Backfill now" expands inline confirm · Hash computation: button replaced by progress bar + spinner · Both operations non-blocking (page stays usable)</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 4c: Success state -->
|
||
<div class="screens" style="margin-top:20px">
|
||
<div class="screen-block" style="max-width:640px">
|
||
<div class="screen-label">4c — Post-completion success state <span class="sz">1440px</span></div>
|
||
<div class="wf">
|
||
<div class="wf-bar"><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="urlbar"></div></div>
|
||
<div class="NAV"><div class="logo">FAMILIENARCHIV</div><div class="nl on">Admin</div></div>
|
||
<div class="BODY" style="height:200px">
|
||
<div class="EN">
|
||
<div class="EN-head">Admin</div>
|
||
<div class="EN-item"><div class="EN-cnt">4</div><div class="EN-lbl">Users</div></div>
|
||
<div class="EN-spacer"></div>
|
||
<div class="EN-item sys on"><div class="EN-lbl">System</div></div>
|
||
</div>
|
||
<div style="flex:1;padding:20px;background:#fff">
|
||
<div class="SC warn">
|
||
<div class="SC-title">Backfill history data <span class="SC-badge" style="background:#BBF7D0;color:#166534">DONE</span></div>
|
||
<div class="SC-desc">Already completed. Run again if new imports have been added since last run.</div>
|
||
<div class="AL AL-ok" style="margin-bottom:8px">✓ Backfill complete — <strong>43 documents</strong> received a history entry.</div>
|
||
<div class="BTN BTN-amber BTN-sm">Run again…</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="screen-cap">Success banner replaces the confirm block · Shows count of affected records · "Run again" button available</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<!-- ══════════════════════════════════════════════════════════ -->
|
||
<!-- S5 · EDGE & ERROR STATES -->
|
||
<!-- ══════════════════════════════════════════════════════════ -->
|
||
<div class="section">
|
||
<div class="sec-intro">
|
||
<div class="sec-num">5</div>
|
||
<div class="sec-meta">
|
||
<span class="sec-badge badge-edge">Edge Cases</span>
|
||
<div class="sec-title">Empty, Error, and Unsaved-Change States</div>
|
||
<div class="sec-tagline">Every state that can occur outside the happy path — including empty lists, save errors, API failures, and navigation guards for unsaved changes.</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="screens cols3">
|
||
<!-- 5a: Empty list -->
|
||
<div class="screen-block">
|
||
<div class="screen-label">5a — Empty list state <span class="state-tag empty">Empty</span></div>
|
||
<div class="wf">
|
||
<div class="wf-bar"><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="urlbar"></div></div>
|
||
<div class="NAV"><div class="logo">FAMILIENARCHIV</div><div class="nl on">Admin</div></div>
|
||
<div class="BODY" style="height:240px">
|
||
<div class="EN">
|
||
<div class="EN-head">Admin</div>
|
||
<div class="EN-item on"><div class="EN-cnt">0</div><div class="EN-lbl">Users</div></div>
|
||
</div>
|
||
<div class="LP">
|
||
<div class="LP-head"><div class="LP-title">All Users</div><div class="BTN BTN-primary BTN-sm">+ New</div></div>
|
||
<div class="LP-empty">No users yet.<br>Create the first one →</div>
|
||
</div>
|
||
<div class="DP">
|
||
<div class="DP-empty">
|
||
<div class="DP-empty-icon">👥</div>
|
||
<div class="DP-empty-msg">No users have been created yet.<br>Click <strong>+ New</strong> to add the first user.</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="screen-cap">Empty list shows copy in both LP and DP · Count in entity nav shows 0</div>
|
||
</div>
|
||
|
||
<!-- 5b: Unsaved changes guard -->
|
||
<div class="screen-block">
|
||
<div class="screen-label">5b — Unsaved changes warning <span class="state-tag err">Guard</span></div>
|
||
<div class="wf">
|
||
<div class="wf-bar"><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="urlbar"></div></div>
|
||
<div class="NAV"><div class="logo">FAMILIENARCHIV</div><div class="nl on">Admin</div></div>
|
||
<div class="BODY" style="height:240px">
|
||
<div class="EN">
|
||
<div class="EN-head">Admin</div>
|
||
<div class="EN-item on"><div class="EN-cnt">4</div><div class="EN-lbl">Users</div></div>
|
||
</div>
|
||
<div class="LP">
|
||
<div class="LP-head"><div class="LP-title">All Users</div></div>
|
||
<div class="LP-item on"><div><div class="LP-name" style="color:#D97706">● marcel</div><div class="LP-sub" style="color:#F59E0B">Unsaved changes</div></div></div>
|
||
<div class="LP-item" style="opacity:.5"><div><div class="LP-name">berit</div></div></div>
|
||
</div>
|
||
<div class="DP">
|
||
<div class="DP-head" style="background:#FFFBEB;border-bottom-color:#FDE68A">
|
||
<div><div class="DP-title" style="color:#92400E">Edit user: marcel</div></div>
|
||
</div>
|
||
<div class="DP-body">
|
||
<div class="AL AL-warn" style="margin-bottom:10px">
|
||
<strong>⚠ You have unsaved changes.</strong><br>
|
||
Save or discard before selecting a different user.
|
||
</div>
|
||
<div style="display:flex;gap:8px">
|
||
<div class="BTN BTN-ghost BTN-sm">Discard changes</div>
|
||
<div class="BTN BTN-primary BTN-sm">Save now</div>
|
||
</div>
|
||
</div>
|
||
<div class="DP-footer" style="background:#FFFBEB">
|
||
<div class="BTN BTN-ghost">Discard</div>
|
||
<div class="BTN BTN-primary">Save changes</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="screen-cap">List item shows amber dot + "Unsaved changes" · Clicking another item triggers the inline warning (not a modal)</div>
|
||
</div>
|
||
|
||
<!-- 5c: Save error -->
|
||
<div class="screen-block">
|
||
<div class="screen-label">5c — API / save error <span class="state-tag err">Error</span></div>
|
||
<div class="wf">
|
||
<div class="wf-bar"><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="urlbar"></div></div>
|
||
<div class="NAV"><div class="logo">FAMILIENARCHIV</div><div class="nl on">Admin</div></div>
|
||
<div class="BODY" style="height:240px">
|
||
<div class="EN">
|
||
<div class="EN-head">Admin</div>
|
||
<div class="EN-item on"><div class="EN-cnt">4</div><div class="EN-lbl">Users</div></div>
|
||
</div>
|
||
<div class="LP">
|
||
<div class="LP-head"><div class="LP-title">All Users</div></div>
|
||
<div class="LP-item on"><div><div class="LP-name">marcel</div></div></div>
|
||
</div>
|
||
<div class="DP">
|
||
<div class="DP-head"><div><div class="DP-title">Edit user: marcel</div></div></div>
|
||
<div class="DP-body">
|
||
<div class="AL AL-err" style="margin-bottom:10px">
|
||
<strong>✕ Save failed.</strong> The server returned an error: <em>Email address is already in use by another account.</em><br>
|
||
<span style="font-size:8.5px;margin-top:3px;display:block">Your changes are preserved — correct the error and try again.</span>
|
||
</div>
|
||
<div class="FG"><div class="FL">Email address</div><div class="FI err filled" style="font-size:8.5px">duplicate@example.com</div><div class="ferr">This email is already registered to another user.</div></div>
|
||
</div>
|
||
<div class="DP-footer" style="background:#FFF5F5;border-top-color:#FCA5A5">
|
||
<div class="BTN BTN-ghost">Discard</div>
|
||
<div class="BTN BTN-primary">Retry save</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="screen-cap">Error shown inline at top of form + on the specific field · Changes are NOT lost · Save bar button changes to "Retry save"</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
<!-- ══════════════════════════════════════════════════════════ -->
|
||
<!-- TABLET ADDENDUM (768–1023px) -->
|
||
<!-- ══════════════════════════════════════════════════════════ -->
|
||
<div style="margin:48px 0 24px;padding:20px 28px;background:#E0F2FE;border:2px solid #BAE6FD;border-radius:10px">
|
||
<div style="font-size:16px;font-weight:800;color:#0369A1;margin-bottom:6px">Tablet Addendum — 768–1023px</div>
|
||
<div style="font-size:13px;color:#0C4A6E;line-height:1.6;max-width:760px">The three-panel layout at 768px leaves the detail panel with ~408px — too cramped for a form. This addendum introduces collapseable panels: the entity nav shrinks to a 48px icon strip, and the list panel gets a one-click collapse toggle. Three states (A, B, C) plus an implementation spec (D) are defined below.</div>
|
||
</div>
|
||
|
||
<div class="section">
|
||
<div class="sec-intro">
|
||
<div class="sec-num">0</div>
|
||
<div class="sec-meta">
|
||
<span class="sec-badge">Problem</span>
|
||
<div class="sec-title">Space budget at 768px</div>
|
||
<div class="sec-tagline">Why the original spec fails at tablet width and how the three states solve it.</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Before vs After layout diagrams -->
|
||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:24px;margin-bottom:20px">
|
||
<div>
|
||
<div class="screen-label" style="margin-bottom:10px">Before — original spec</div>
|
||
<div class="layout-diagram">
|
||
<div class="ld-en" style="width:120px"><div class="ld-label">Entity<br>Nav<div class="ld-px">120px</div></div></div>
|
||
<div class="ld-lp" style="width:240px"><div class="ld-label">List<br>Panel<div class="ld-px">240px</div></div></div>
|
||
<div class="ld-dp" style="background:#FEF2F2"><div class="ld-label" style="color:#DC2626">Detail<div class="ld-px" style="color:#DC2626">408px ✗</div></div></div>
|
||
</div>
|
||
<div style="font-size:10px;color:#DC2626;margin-top:6px;font-weight:600">360px eaten by navigation — barely enough room for a single-column form</div>
|
||
</div>
|
||
<div>
|
||
<div class="screen-label" style="margin-bottom:10px">After — reworked tablet (default state)</div>
|
||
<div class="layout-diagram">
|
||
<div class="ld-en" style="width:48px"><div class="ld-label" style="font-size:7px">Icons<div class="ld-px">48px</div></div></div>
|
||
<div class="ld-lp" style="width:200px"><div class="ld-label">List<br>Panel<div class="ld-px">200px</div></div></div>
|
||
<div class="ld-dp"><div class="ld-label" style="color:#15803D">Detail<div class="ld-px" style="color:#15803D">520px ✓</div></div></div>
|
||
</div>
|
||
<div style="font-size:10px;color:#15803D;margin-top:6px;font-weight:600">248px saved — enough for a comfortable two-column form layout</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Three state summary -->
|
||
<div style="background:#fff;border:1px solid #E8E4DF;border-radius:8px;overflow:hidden;margin-bottom:16px">
|
||
<table class="CMP">
|
||
<thead><tr><th>State</th><th>Entity Nav</th><th>List Panel</th><th>Detail Panel</th><th>Triggered by</th></tr></thead>
|
||
<tbody>
|
||
<tr><td><strong>A · Default</strong></td><td>48px icon strip</td><td>200px visible</td><td>520px</td><td>Page load / switching entity</td></tr>
|
||
<tr><td><strong>B · List hidden</strong></td><td>48px icon strip</td><td>32px collapsed handle</td><td>688px</td><td>Tapping ‹ in list header</td></tr>
|
||
<tr><td><strong>C · Entity flyout</strong></td><td>48px strip + 160px flyout overlay</td><td>Dimmed behind flyout</td><td>Dimmed behind flyout</td><td>Tapping any entity icon</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- Transition flow -->
|
||
<div style="display:flex;flex-direction:column;gap:8px">
|
||
<div class="transition-row">
|
||
<div class="transition-label">A → B</div>
|
||
<div class="transition-arrow">→</div>
|
||
<div class="transition-desc">User clicks the <strong>‹ collapse</strong> button in the list header. List panel slides to 32px collapsed handle. Detail panel expands to fill the freed space. Animation: 200ms ease-out slide.</div>
|
||
</div>
|
||
<div class="transition-row">
|
||
<div class="transition-label">B → A</div>
|
||
<div class="transition-arrow">→</div>
|
||
<div class="transition-desc">User clicks the <strong>› expand</strong> handle on the left edge of the detail panel. List panel slides back to 200px. This restores the browsable list view.</div>
|
||
</div>
|
||
<div class="transition-row">
|
||
<div class="transition-label">A/B → C</div>
|
||
<div class="transition-arrow">→</div>
|
||
<div class="transition-desc">User taps any <strong>entity icon</strong> in the 48px strip. A 160px flyout slides in from the left, overlapping the list/detail panels. Tapping an entity in the flyout navigates and dismisses. Tapping outside dismisses without navigating.</div>
|
||
</div>
|
||
<div class="transition-row">
|
||
<div class="transition-label">C → A/B</div>
|
||
<div class="transition-arrow">→</div>
|
||
<div class="transition-desc">Flyout dismisses (slides out) after entity selection, or on tap-outside. Returns to previous state (A or B).</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<!-- ══════════════════════════════════════════════════════════ -->
|
||
<!-- STATE A: DEFAULT -->
|
||
<!-- ══════════════════════════════════════════════════════════ -->
|
||
<div class="section">
|
||
<div class="sec-intro">
|
||
<div class="sec-num">A</div>
|
||
<div class="sec-meta">
|
||
<span class="sec-badge">State A</span>
|
||
<div class="sec-title">Default — Icon strip + List + Detail</div>
|
||
<div class="sec-tagline">The landing state for all tablet sessions. Entity nav collapses from 120px text labels to 48px icon-only strip with count badges. List panel stays visible at 200px. Detail gets 520px — enough for a two-column form.</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- State A: Users edit -->
|
||
<div class="screens">
|
||
<div class="screen-block" style="flex:1">
|
||
<div class="screen-label">State A — Users: editing a user <span class="sz">768px</span> <span class="st st-a">Default</span></div>
|
||
<div class="wf" style="width:720px">
|
||
<div class="wf-bar"><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="urlbar"></div></div>
|
||
<div class="NAV"><div class="logo">FAMILIENARCHIV</div><div class="nl">Documents</div><div class="nl">Persons</div><div class="nl on">Admin</div><div class="nr"><div class="nico"></div><div class="nico"></div></div></div>
|
||
<div class="BODY" style="height:380px">
|
||
<!-- Entity icon strip (48px) -->
|
||
<div class="EI">
|
||
<div class="EI-item on">
|
||
<div class="EI-icon"></div>
|
||
<div class="EI-cnt">4</div>
|
||
<!-- Tooltip (shown on hover in impl) -->
|
||
<div class="EI-tip">Users</div>
|
||
</div>
|
||
<div class="EI-item">
|
||
<div class="EI-icon"></div>
|
||
<div class="EI-cnt">3</div>
|
||
</div>
|
||
<div class="EI-item">
|
||
<div class="EI-icon"></div>
|
||
<div class="EI-cnt">3</div>
|
||
</div>
|
||
<div class="EI-spacer"></div>
|
||
<div class="EI-item sys">
|
||
<div class="EI-icon"></div>
|
||
</div>
|
||
</div>
|
||
<!-- List Panel (200px) -->
|
||
<div class="LP" style="width:200px">
|
||
<div class="LP-head">
|
||
<div class="LP-title">Users</div>
|
||
<div style="display:flex;gap:5px;align-items:center">
|
||
<div class="BTN BTN-primary BTN-xs">+ New</div>
|
||
<div class="LP-toggle" title="Collapse list">‹</div>
|
||
</div>
|
||
</div>
|
||
<div class="LP-search">🔍 Search…</div>
|
||
<div class="LP-item">
|
||
<div><div class="LP-name">reader</div><div class="LP-sub"><span class="CH CH-blue">Leser</span></div></div>
|
||
<div class="LP-chev">›</div>
|
||
</div>
|
||
<div class="LP-item on">
|
||
<div><div class="LP-name">marcel</div><div class="LP-sub">Marcel Raddatz</div></div>
|
||
<div class="LP-chev">›</div>
|
||
</div>
|
||
<div class="LP-item">
|
||
<div><div class="LP-name">berit</div><div class="LP-sub">Berit Cram</div></div>
|
||
<div class="LP-chev">›</div>
|
||
</div>
|
||
<div class="LP-item">
|
||
<div><div class="LP-name">admin</div><div class="LP-sub"><span class="CH CH-red">Admins</span></div></div>
|
||
<div class="LP-chev">›</div>
|
||
</div>
|
||
</div>
|
||
<!-- Detail Panel (520px) -->
|
||
<div class="DP">
|
||
<div class="DP-head">
|
||
<div><div class="DP-title">Edit user: marcel</div><div class="DP-sub">Marcel Raddatz · Editor group</div></div>
|
||
<div class="BTN BTN-danger BTN-xs">Delete…</div>
|
||
</div>
|
||
<div class="DP-body">
|
||
<div class="SH">Personal info</div>
|
||
<div class="FG-row">
|
||
<div class="FG"><div class="FL">First name</div><div class="FI filled">Marcel</div></div>
|
||
<div class="FG"><div class="FL">Last name</div><div class="FI filled">Raddatz</div></div>
|
||
</div>
|
||
<div class="FG-row">
|
||
<div class="FG"><div class="FL">Date of birth</div><div class="FI"></div></div>
|
||
<div class="FG"><div class="FL">Email address</div><div class="FI filled" style="font-size:8px">m.raddatz@example.com</div></div>
|
||
</div>
|
||
<div class="FG"><div class="FL">Contact details</div><div class="FTA"></div></div>
|
||
<div class="SH">Groups</div>
|
||
<div style="display:flex;gap:14px;flex-wrap:wrap;margin-bottom:6px">
|
||
<div class="PI"><div class="CB"></div> Leser</div>
|
||
<div class="PI"><div class="CB"></div> Administrators</div>
|
||
<div class="PI"><div class="CB on"></div> Editor</div>
|
||
</div>
|
||
<div class="SH">Change password</div>
|
||
<div class="FG-row">
|
||
<div class="FG"><div class="FL">New password</div><div class="FI"></div></div>
|
||
<div class="FG"><div class="FL">Repeat</div><div class="FI"></div></div>
|
||
</div>
|
||
</div>
|
||
<div class="DP-footer">
|
||
<div class="BTN BTN-ghost">Discard</div>
|
||
<div class="BTN BTN-primary">Save changes</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="screen-cap">
|
||
Entity nav shrinks from 120px → 48px (icon + count only) · ‹ collapse button visible in list header top-right · Two-column form layout fits comfortably in 520px detail · Tooltip appears on icon hover showing entity name
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- State A: Tags view -->
|
||
<div class="screens" style="margin-top:20px">
|
||
<div class="screen-block" style="flex:1">
|
||
<div class="screen-label">State A — Tags list view <span class="sz">768px</span> <span class="st st-a">Default</span></div>
|
||
<div class="wf" style="width:720px">
|
||
<div class="wf-bar"><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="urlbar"></div></div>
|
||
<div class="NAV"><div class="logo">FAMILIENARCHIV</div><div class="nl on">Admin</div><div class="nr"><div class="nico"></div><div class="nico"></div></div></div>
|
||
<div class="BODY" style="height:260px">
|
||
<div class="EI">
|
||
<div class="EI-item"><div class="EI-icon"></div><div class="EI-cnt">4</div></div>
|
||
<div class="EI-item"><div class="EI-icon"></div><div class="EI-cnt">3</div></div>
|
||
<div class="EI-item on"><div class="EI-icon"></div><div class="EI-cnt">3</div></div>
|
||
<div class="EI-spacer"></div>
|
||
<div class="EI-item sys"><div class="EI-icon"></div></div>
|
||
</div>
|
||
<div class="LP" style="width:200px">
|
||
<div class="LP-head">
|
||
<div class="LP-title">Tags</div>
|
||
<div style="display:flex;gap:5px;align-items:center">
|
||
<div class="BTN BTN-primary BTN-xs">+ New</div>
|
||
<div class="LP-toggle">‹</div>
|
||
</div>
|
||
</div>
|
||
<div class="LP-search">🔍 Filter tags…</div>
|
||
<div class="LP-item"><div><div class="LP-name">Familie</div><div class="LP-sub">34 documents</div></div><div class="LP-chev">›</div></div>
|
||
<div class="LP-item on"><div><div class="LP-name">Krieg</div><div class="LP-sub">12 documents</div></div><div class="LP-chev">›</div></div>
|
||
<div class="LP-item"><div><div class="LP-name">Urlaub</div><div class="LP-sub">7 documents</div></div><div class="LP-chev">›</div></div>
|
||
</div>
|
||
<div class="DP">
|
||
<div class="DP-head">
|
||
<div><div class="DP-title">Edit tag: Krieg</div><div class="DP-sub">Used in 12 documents</div></div>
|
||
<div class="BTN BTN-danger BTN-xs">Delete…</div>
|
||
</div>
|
||
<div class="DP-body">
|
||
<div class="SH" style="border-top:none;padding-top:0">Tag name</div>
|
||
<div class="FG" style="max-width:300px"><div class="FL">Name</div><div class="FI filled">Krieg</div></div>
|
||
<div style="padding:8px;background:#FFFBEB;border:1px solid #FDE68A;border-radius:4px;font-size:8.5px;color:#92400E;margin-top:6px">⚠ Renaming affects all 12 linked documents.</div>
|
||
</div>
|
||
<div class="DP-footer"><div class="BTN BTN-ghost">Discard</div><div class="BTN BTN-primary">Rename tag</div></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="screen-cap">Tags panel: list fits compactly at 200px, detail has generous space for the rename form + warning</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<!-- ══════════════════════════════════════════════════════════ -->
|
||
<!-- STATE B: LIST COLLAPSED -->
|
||
<!-- ══════════════════════════════════════════════════════════ -->
|
||
<div class="section">
|
||
<div class="sec-intro">
|
||
<div class="sec-num">B</div>
|
||
<div class="sec-meta">
|
||
<span class="sec-badge">State B</span>
|
||
<div class="sec-title">List Collapsed — Maximum Detail Space</div>
|
||
<div class="sec-tagline">User clicks ‹ to collapse the list panel. It slides to a 32px narrow handle showing a › expand button and the rotated entity name. Detail panel grows to 688px — ideal for forms with many fields or when reading long content.</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- State B: Groups edit (complex permissions form) -->
|
||
<div class="screens">
|
||
<div class="screen-block" style="flex:1">
|
||
<div class="screen-label">State B — Groups: editing permissions (list collapsed) <span class="sz">768px</span> <span class="st st-b">List collapsed</span></div>
|
||
<div class="wf" style="width:720px">
|
||
<div class="wf-bar"><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="urlbar"></div></div>
|
||
<div class="NAV"><div class="logo">FAMILIENARCHIV</div><div class="nl on">Admin</div><div class="nr"><div class="nico"></div><div class="nico"></div></div></div>
|
||
<div class="BODY" style="height:360px">
|
||
<!-- Entity strip -->
|
||
<div class="EI">
|
||
<div class="EI-item"><div class="EI-icon"></div><div class="EI-cnt">4</div></div>
|
||
<div class="EI-item on"><div class="EI-icon"></div><div class="EI-cnt">3</div></div>
|
||
<div class="EI-item"><div class="EI-icon"></div><div class="EI-cnt">3</div></div>
|
||
<div class="EI-spacer"></div>
|
||
<div class="EI-item sys"><div class="EI-icon"></div></div>
|
||
</div>
|
||
<!-- Collapsed list handle (32px) -->
|
||
<div class="LP-handle">
|
||
<div class="LP-handle-btn" title="Show list">›</div>
|
||
<div class="LP-handle-label">Groups</div>
|
||
</div>
|
||
<!-- Detail (688px — 720-48-32-2px border) -->
|
||
<div class="DP">
|
||
<div class="DP-head">
|
||
<div><div class="DP-title">Edit group: Administrators</div><div class="DP-sub">1 user · 6 permissions · last modified 2026-03-01</div></div>
|
||
<div class="BTN BTN-danger BTN-xs">Delete…</div>
|
||
</div>
|
||
<div class="DP-body">
|
||
<div class="SH" style="border-top:none;padding-top:0">Group name</div>
|
||
<div class="FG" style="max-width:320px"><div class="FL">Name</div><div class="FI filled">Administrators</div></div>
|
||
<!-- Permissions: now has more room to display in a single wider row -->
|
||
<div class="SH">Standard permissions</div>
|
||
<div style="display:flex;gap:20px;flex-wrap:wrap;margin-bottom:10px">
|
||
<div class="PI"><div class="CB on"></div> READ_ALL</div>
|
||
<div class="PI"><div class="CB on"></div> WRITE_ALL</div>
|
||
<div class="PI"><div class="CB on"></div> ANNOTATE_ALL</div>
|
||
</div>
|
||
<div class="SH" style="color:#DC2626;border-top-color:#FCA5A5">⚙ Administrative permissions</div>
|
||
<div style="display:flex;gap:20px;flex-wrap:wrap;background:#FFF5F5;border:1px solid #FCA5A5;border-radius:4px;padding:8px">
|
||
<div class="PI"><div class="CB on" style="background:#DC2626;border-color:#DC2626"></div> <span style="color:#991B1B;font-weight:800">ADMIN</span></div>
|
||
<div class="PI"><div class="CB on" style="background:#DC2626;border-color:#DC2626"></div> ADMIN_USER</div>
|
||
<div class="PI"><div class="CB on" style="background:#DC2626;border-color:#DC2626"></div> ADMIN_TAG</div>
|
||
<div class="PI"><div class="CB on" style="background:#DC2626;border-color:#DC2626"></div> ADMIN_PERMISSION</div>
|
||
</div>
|
||
<div class="SH">Members</div>
|
||
<div style="display:flex;gap:6px">
|
||
<div style="display:flex;align-items:center;gap:4px;background:#F3F4F6;border:1px solid #E5E7EB;border-radius:20px;padding:3px 8px;font-size:9px;font-weight:600">admin <span style="color:#AAA;margin-left:2px">✕</span></div>
|
||
</div>
|
||
</div>
|
||
<div class="DP-footer"><div class="BTN BTN-ghost">Discard</div><div class="BTN BTN-primary">Save changes</div></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="screen-cap">
|
||
List collapsed to 32px handle showing › expand button + "Groups" label rotated · Detail grows to 688px — permissions all fit in one row with breathing room · The entity strip stays visible for entity switching
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- State B: User create (full form) -->
|
||
<div class="screens" style="margin-top:20px">
|
||
<div class="screen-block" style="flex:1">
|
||
<div class="screen-label">State B — Users: creating a new user (list collapsed) <span class="sz">768px</span> <span class="st st-b">List collapsed</span></div>
|
||
<div class="wf" style="width:720px">
|
||
<div class="wf-bar"><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="urlbar"></div></div>
|
||
<div class="NAV"><div class="logo">FAMILIENARCHIV</div><div class="nl on">Admin</div><div class="nr"><div class="nico"></div></div></div>
|
||
<div class="BODY" style="height:360px">
|
||
<div class="EI">
|
||
<div class="EI-item on"><div class="EI-icon"></div><div class="EI-cnt">4</div></div>
|
||
<div class="EI-item"><div class="EI-icon"></div><div class="EI-cnt">3</div></div>
|
||
<div class="EI-item"><div class="EI-icon"></div><div class="EI-cnt">3</div></div>
|
||
<div class="EI-spacer"></div>
|
||
<div class="EI-item sys"><div class="EI-icon"></div></div>
|
||
</div>
|
||
<div class="LP-handle">
|
||
<div class="LP-handle-btn">›</div>
|
||
<div class="LP-handle-label">Users</div>
|
||
</div>
|
||
<div class="DP" style="background:#F0FDF4">
|
||
<div class="DP-head" style="background:#E0FFF4;border-bottom-color:#BBF7D0">
|
||
<div><div class="DP-title" style="color:#15803D">Create new user</div><div class="DP-sub">Fill in the details below</div></div>
|
||
</div>
|
||
<div class="DP-body">
|
||
<div class="SH" style="border-top:none;padding-top:0">Credentials</div>
|
||
<div class="FG-row">
|
||
<div class="FG"><div class="FL">Login / Username <span style="color:#DC2626">*</span></div><div class="FI"></div></div>
|
||
<div class="FG"><div class="FL">Password <span style="color:#DC2626">*</span></div><div class="FI"></div></div>
|
||
</div>
|
||
<div class="SH">Personal info</div>
|
||
<div class="FG-row">
|
||
<div class="FG"><div class="FL">First name</div><div class="FI"></div></div>
|
||
<div class="FG"><div class="FL">Last name</div><div class="FI"></div></div>
|
||
</div>
|
||
<div class="FG-row">
|
||
<div class="FG"><div class="FL">Date of birth</div><div class="FI"></div></div>
|
||
<div class="FG"><div class="FL">Email</div><div class="FI"></div></div>
|
||
</div>
|
||
<div class="SH">Groups</div>
|
||
<div style="display:flex;gap:16px;flex-wrap:wrap">
|
||
<div class="PI"><div class="CB"></div> Leser</div>
|
||
<div class="PI"><div class="CB"></div> Administrators</div>
|
||
<div class="PI"><div class="CB on"></div> Editor</div>
|
||
</div>
|
||
</div>
|
||
<div class="DP-footer" style="background:#F0FDF4;border-top-color:#BBF7D0"><div class="BTN BTN-ghost">Cancel</div><div class="BTN BTN-primary" style="background:#15803D">Create user</div></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="screen-cap">
|
||
Auto-collapse: when user clicks "+ New", the list panel auto-collapses to give maximum space for the create form · User can tap › to restore the list at any time
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<!-- ══════════════════════════════════════════════════════════ -->
|
||
<!-- STATE C: ENTITY FLYOUT -->
|
||
<!-- ══════════════════════════════════════════════════════════ -->
|
||
<div class="section">
|
||
<div class="sec-intro">
|
||
<div class="sec-num">C</div>
|
||
<div class="sec-meta">
|
||
<span class="sec-badge">State C</span>
|
||
<div class="sec-title">Entity Flyout — Temporary Navigation Overlay</div>
|
||
<div class="sec-tagline">Tapping any entity icon in the 48px strip slides out a 160px labeled flyout. It sits above the list and detail panels (which dim behind it). Tapping an entity navigates and auto-dismisses. Tapping outside dismisses without navigating.</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- State C: flyout open -->
|
||
<div class="screens">
|
||
<div class="screen-block" style="flex:1">
|
||
<div class="screen-label">State C — Entity flyout open (Groups icon tapped) <span class="sz">768px</span> <span class="st st-c">Flyout open</span></div>
|
||
<div class="wf" style="width:720px;overflow:hidden">
|
||
<div class="wf-bar"><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="urlbar"></div></div>
|
||
<div class="NAV"><div class="logo">FAMILIENARCHIV</div><div class="nl on">Admin</div><div class="nr"><div class="nico"></div></div></div>
|
||
<div class="BODY" style="height:340px;position:relative">
|
||
<!-- Entity strip (stays on top) -->
|
||
<div class="EI" style="z-index:20;position:relative">
|
||
<div class="EI-item"><div class="EI-icon"></div><div class="EI-cnt">4</div></div>
|
||
<div class="EI-item on" style="background:rgba(255,255,255,.18)"><div class="EI-icon" style="background:rgba(166,218,216,.8)"></div><div class="EI-cnt" style="color:rgba(255,255,255,.9)">3</div></div>
|
||
<div class="EI-item"><div class="EI-icon"></div><div class="EI-cnt">3</div></div>
|
||
<div class="EI-spacer"></div>
|
||
<div class="EI-item sys"><div class="EI-icon"></div></div>
|
||
</div>
|
||
<!-- Dimmed list + detail behind flyout -->
|
||
<div style="flex:1;display:flex;filter:brightness(.55);pointer-events:none;position:relative">
|
||
<div class="LP" style="width:200px">
|
||
<div class="LP-head"><div class="LP-title">Users</div></div>
|
||
<div class="LP-item"><div><div class="LP-name">reader</div></div></div>
|
||
<div class="LP-item on"><div><div class="LP-name">marcel</div></div></div>
|
||
<div class="LP-item"><div><div class="LP-name">berit</div></div></div>
|
||
</div>
|
||
<div class="DP">
|
||
<div class="DP-head"><div><div class="DP-title">Edit user: marcel</div></div></div>
|
||
<div class="DP-body"><div class="PH w70"></div><div class="PH w50"></div><div class="PH w60"></div></div>
|
||
</div>
|
||
</div>
|
||
<!-- Flyout overlay -->
|
||
<div class="EF">
|
||
<div class="EF-head">
|
||
Navigate
|
||
<div class="EF-close">✕</div>
|
||
</div>
|
||
<div class="EF-item">
|
||
<div class="EF-item-icon"></div>
|
||
<div class="EF-item-label">Users</div>
|
||
<div class="EF-item-cnt">4</div>
|
||
</div>
|
||
<div class="EF-item on">
|
||
<div class="EF-item-icon"></div>
|
||
<div class="EF-item-label">Groups</div>
|
||
<div class="EF-item-cnt">3</div>
|
||
</div>
|
||
<div class="EF-item">
|
||
<div class="EF-item-icon"></div>
|
||
<div class="EF-item-label">Tags</div>
|
||
<div class="EF-item-cnt">3</div>
|
||
</div>
|
||
<div style="flex:1"></div>
|
||
<div class="EF-item" style="border-top:1px solid rgba(255,255,255,.1)">
|
||
<div class="EF-item-icon"></div>
|
||
<div class="EF-item-label">System</div>
|
||
</div>
|
||
</div>
|
||
<!-- Dim overlay for the rest -->
|
||
<div class="EF-dim"></div>
|
||
</div>
|
||
</div>
|
||
<div class="screen-cap">
|
||
160px flyout slides in from the left over the list panel · Full entity names + counts visible · Active entity (Groups) highlighted · Tap outside (dimmed area) dismisses without navigating · ✕ close button in header · List/detail dimmed to 55% to signal non-interactable state
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- State C: flyout with list collapsed -->
|
||
<div class="screens" style="margin-top:20px">
|
||
<div class="screen-block" style="flex:1">
|
||
<div class="screen-label">State C — Flyout open while list is collapsed <span class="sz">768px</span> <span class="st st-c">Flyout + collapsed list</span></div>
|
||
<div class="wf" style="width:720px;overflow:hidden">
|
||
<div class="wf-bar"><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="urlbar"></div></div>
|
||
<div class="NAV"><div class="logo">FAMILIENARCHIV</div><div class="nl on">Admin</div><div class="nr"><div class="nico"></div></div></div>
|
||
<div class="BODY" style="height:280px;position:relative">
|
||
<div class="EI" style="z-index:20;position:relative">
|
||
<div class="EI-item on" style="background:rgba(255,255,255,.18)"><div class="EI-icon" style="background:rgba(166,218,216,.8)"></div><div class="EI-cnt" style="color:rgba(255,255,255,.9)">4</div></div>
|
||
<div class="EI-item"><div class="EI-icon"></div><div class="EI-cnt">3</div></div>
|
||
<div class="EI-item"><div class="EI-icon"></div><div class="EI-cnt">3</div></div>
|
||
<div class="EI-spacer"></div>
|
||
<div class="EI-item sys"><div class="EI-icon"></div></div>
|
||
</div>
|
||
<div style="flex:1;display:flex;filter:brightness(.55);pointer-events:none">
|
||
<div class="LP-handle"><div class="LP-handle-btn">›</div></div>
|
||
<div class="DP">
|
||
<div class="DP-head"><div><div class="DP-title">Edit user: marcel</div></div></div>
|
||
<div class="DP-body"><div class="PH w70"></div><div class="PH w50"></div></div>
|
||
</div>
|
||
</div>
|
||
<div class="EF">
|
||
<div class="EF-head">Navigate <div class="EF-close">✕</div></div>
|
||
<div class="EF-item on"><div class="EF-item-icon"></div><div class="EF-item-label">Users</div><div class="EF-item-cnt">4</div></div>
|
||
<div class="EF-item"><div class="EF-item-icon"></div><div class="EF-item-label">Groups</div><div class="EF-item-cnt">3</div></div>
|
||
<div class="EF-item"><div class="EF-item-icon"></div><div class="EF-item-label">Tags</div><div class="EF-item-cnt">3</div></div>
|
||
<div style="flex:1"></div>
|
||
<div class="EF-item" style="border-top:1px solid rgba(255,255,255,.1)"><div class="EF-item-icon"></div><div class="EF-item-label">System</div></div>
|
||
</div>
|
||
<div class="EF-dim"></div>
|
||
</div>
|
||
</div>
|
||
<div class="screen-cap">Flyout works identically whether list is expanded or collapsed — it always overlays from the left edge at 48px</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<!-- ══════════════════════════════════════════════════════════ -->
|
||
<!-- INTERACTION & IMPLEMENTATION SPEC -->
|
||
<!-- ══════════════════════════════════════════════════════════ -->
|
||
<div class="section">
|
||
<div class="sec-intro">
|
||
<div class="sec-num">D</div>
|
||
<div class="sec-meta">
|
||
<span class="sec-badge">Implementation</span>
|
||
<div class="sec-title">Interaction & Implementation Spec</div>
|
||
<div class="sec-tagline">Exact behaviour, animation timings, and SvelteKit implementation notes for each panel behaviour.</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="SPEC">
|
||
<div class="SPEC-title">Tablet panel behaviour spec</div>
|
||
<div class="SPEC-grid">
|
||
<div class="SPEC-col">
|
||
<div class="SPEC-rule">
|
||
<div class="SPEC-rule-num">D.1 · Entity strip — icon resolution</div>
|
||
<div class="SPEC-rule-text">Each entity icon is a recognisable SVG: 👤 Users, 🔐 Groups, 🏷 Tags, ⚙ System. At 20×20px, use outline-style icons (Heroicons or Lucide). Count badge below icon, not overlapping. Tooltip on hover: <code>title</code> attribute is sufficient (no custom tooltip needed).</div>
|
||
</div>
|
||
<div class="SPEC-rule">
|
||
<div class="SPEC-rule-num">D.2 · List panel — collapse animation</div>
|
||
<div class="SPEC-rule-text">CSS transition: <code>width 200ms ease-out</code> on <code>.LP</code>. Collapsed width: 32px. The inner content (<code>overflow: hidden</code>) disappears as the panel shrinks. The handle (<code>.LP-handle</code>) is a sibling element that becomes visible via <code>display: flex</code> when state is collapsed.</div>
|
||
</div>
|
||
<div class="SPEC-rule">
|
||
<div class="SPEC-rule-num">D.3 · List panel — auto-collapse on create</div>
|
||
<div class="SPEC-rule-text">When user clicks "+ New", automatically collapse the list panel (set <code>listCollapsed = true</code> in Svelte state) to give the create form maximum space. Restore list when user navigates away from the create form or saves.</div>
|
||
</div>
|
||
<div class="SPEC-rule">
|
||
<div class="SPEC-rule-num">D.4 · Collapse state — persistence</div>
|
||
<div class="SPEC-rule-text">Store collapse state in <code>localStorage</code> under key <code>admin_list_collapsed</code>. Restore on next visit. Do not persist across breakpoints — desktop always shows full panels regardless of tablet collapse state.</div>
|
||
</div>
|
||
</div>
|
||
<div class="SPEC-col">
|
||
<div class="SPEC-rule">
|
||
<div class="SPEC-rule-num">D.5 · Entity flyout — open/close</div>
|
||
<div class="SPEC-rule-text">Flyout triggered by tapping any entity icon in the strip. CSS transition: <code>transform: translateX(-160px) → translateX(0)</code>, duration 180ms ease-out. Dim overlay: <code>background: rgba(0,0,0,.3)</code>, fade in 150ms. Tapping overlay or pressing Escape closes flyout.</div>
|
||
</div>
|
||
<div class="SPEC-rule">
|
||
<div class="SPEC-rule-num">D.6 · Entity flyout — after selection</div>
|
||
<div class="SPEC-rule-text">After tapping an entity in the flyout: 1) update URL (<code>goto('/admin?v=groups')</code>), 2) close flyout immediately (no wait for navigation), 3) list panel loads new entity's items. If selected entity is already active, just dismiss.</div>
|
||
</div>
|
||
<div class="SPEC-rule">
|
||
<div class="SPEC-rule-num">D.7 · Breakpoint detection</div>
|
||
<div class="SPEC-rule-text">Use a Svelte store: <code>isTablet = $derived(windowWidth >= 768 && windowWidth < 1024)</code>. On desktop (≥1024px) the entity nav always renders at full 120px with labels — the icon strip is tablet-only. On mobile (<768px) both panels are hidden and navigation is handled by push-routing.</div>
|
||
</div>
|
||
<div class="SPEC-rule">
|
||
<div class="SPEC-rule-num">D.8 · Accessibility</div>
|
||
<div class="SPEC-rule-text">‹ collapse button: <code>aria-label="Collapse list panel"</code>, <code>aria-expanded</code> attribute toggles. Flyout: <code>role="dialog"</code>, <code>aria-modal="true"</code>, focus trapped inside while open. Flyout close button: <code>aria-label="Close navigation"</code>. Entity icons: <code>aria-label="Users (4 items)"</code>.</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Updated breakpoint table -->
|
||
<div style="margin-top:20px">
|
||
<div class="screen-label">Updated breakpoint specification</div>
|
||
<div style="background:#fff;border:1px solid #E8E4DF;border-radius:8px;overflow:hidden">
|
||
<table class="CMP">
|
||
<thead><tr><th>Viewport</th><th>Entity nav</th><th>List panel</th><th>Detail panel</th><th>Notes</th></tr></thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code><768px</code> Mobile</td>
|
||
<td>Full-screen step 1</td>
|
||
<td>Full-screen step 2</td>
|
||
<td>Full-screen step 3</td>
|
||
<td>Push navigation, browser back to go up</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>768–1023px</code> Tablet</td>
|
||
<td>48px icon strip (always)<br>+ 160px flyout on tap</td>
|
||
<td>200px default<br>32px when collapsed</td>
|
||
<td>520px default<br>688px when list collapsed</td>
|
||
<td>‹ toggle in list header · state persisted to localStorage</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>≥1024px</code> Desktop</td>
|
||
<td>120px with text labels</td>
|
||
<td>240px, always visible</td>
|
||
<td>All remaining width</td>
|
||
<td>No collapse functionality — all panels always visible</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="DECISION" style="margin-top:20px">
|
||
<div class="DECISION-title">🏗 Design decisions for tablet</div>
|
||
<ul>
|
||
<li>48px icon strip was chosen over a full collapse (0px) because completely removing the entity nav creates orientation loss — users no longer know which entity they're in without looking at the list header</li>
|
||
<li>32px collapsed list handle was chosen over 0px for the same reason — the rotated label + expand button makes the list recoverable without hunting for a menu</li>
|
||
<li>Flyout overlays (not pushes) the list panel so the detail panel position doesn't jump during navigation — the user's current edit context is not disturbed</li>
|
||
<li>Auto-collapse on "+ New" is an affordance designed for tablet: the most common reason to want more space is filling a form, which happens on create</li>
|
||
<li>localStorage persistence means a user who prefers collapsed list doesn't have to collapse it every session</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ══════════════════════════════════════════════════════════ -->
|
||
<!-- INTERACTION SPEC TABLE -->
|
||
<!-- ══════════════════════════════════════════════════════════ -->
|
||
<div style="background:#fff;border:1.5px solid #E8E4DF;border-radius:10px;padding:28px 32px;margin-top:48px">
|
||
<div style="font-size:15px;font-weight:800;color:#002850;margin-bottom:16px">Interaction Specification — All Entities</div>
|
||
<table class="SUM-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Trigger</th>
|
||
<th>Entity</th>
|
||
<th>Behaviour</th>
|
||
<th>URL change</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr><td>Click entity in nav</td><td>Any</td><td>Load list panel, clear detail, set list title</td><td><code>?v=users</code></td></tr>
|
||
<tr><td>Click list item</td><td>Any</td><td>Load detail panel for that item; highlight item in list</td><td><code>?v=users&id=uuid</code></td></tr>
|
||
<tr><td>Click "+ New"</td><td>Any</td><td>Add unsaved placeholder at top of list; open blank create form in detail</td><td><code>?v=users&id=new</code></td></tr>
|
||
<tr><td>Submit create form (success)</td><td>Any</td><td>List refreshes; new item highlighted; detail switches to edit mode</td><td><code>?v=users&id=new-uuid</code></td></tr>
|
||
<tr><td>Submit edit form (success)</td><td>Any</td><td>List subtitle updates; "Saved ✓" flashes in footer for 2s</td><td>Unchanged</td></tr>
|
||
<tr><td>Submit form (error)</td><td>Any</td><td>Inline error banner + field-level errors; changes preserved; button → "Retry save"</td><td>Unchanged</td></tr>
|
||
<tr><td>Click "Delete…" header button</td><td>Users, Groups, Tags</td><td>Detail panel switches to danger zone; list item turns red</td><td>Unchanged</td></tr>
|
||
<tr><td>Confirm delete (success)</td><td>Any</td><td>Item removed from list; detail → empty-selection state; count in entity nav decrements</td><td><code>?v=users</code></td></tr>
|
||
<tr><td>Click different list item (dirty form)</td><td>Any</td><td>Inline warning in detail: "Save or discard first"; block navigation</td><td>Unchanged</td></tr>
|
||
<tr><td>Click "Discard changes"</td><td>Any</td><td>Form resets to last saved values; unsaved indicator cleared</td><td>Unchanged</td></tr>
|
||
<tr><td>Click System in entity nav</td><td>System</td><td>List panel hidden; detail fills remaining width with maintenance cards</td><td><code>?v=system</code></td></tr>
|
||
<tr><td>Click "Action…" (System)</td><td>System</td><td>Inline confirm card expands below the button</td><td>Unchanged</td></tr>
|
||
<tr><td>Confirm system action</td><td>System</td><td>Button replaced by spinner + progress; on done: success banner with affected count</td><td>Unchanged</td></tr>
|
||
<tr><td>Browser back (mobile)</td><td>Any</td><td>Pop one step: detail → list → entity picker</td><td>URL pops one param</td></tr>
|
||
<tr><td>Direct URL load with params</td><td>Any</td><td>Server pre-fetches entity + item; renders correct panel state on first paint</td><td>Preserves URL</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
</div><!-- /doc -->
|
||
</body>
|
||
</html>
|