Two-slot shell topbar (home, left, center, bell, user menu) with SDK API (setLeft/setSlot/setTitle/hide/show). All 4 primary surfaces migrated: Settings and Team Admin to Pattern B (flat tabs), Admin to Pattern C (category tabs + sidebar), Docs to Pattern A (default). Backend WS events: package.changed (broadcast), auth.changed (targeted), notification.all_read. User menu re-fetches on package/auth changes. Bell syncs read state across tabs. Error handling pass with .sw-inline-error CSS primitive. Empty state guidance for Admin Workflows/Groups. Announcement global dismiss via localStorage. Rebrand assets deployed (both b/e icon variants, wordmarks, full icon library). Docs outline scroll-to-heading fix. Bug fixes: ICD security assertion tightened, workflow-demo error surfacing, signoff display names, hello-dashboard + team-admin/groups.js deleted. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
175 lines
11 KiB
XML
175 lines
11 KiB
XML
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
|
|
<style>
|
|
@keyframes center-pulse {
|
|
0%, 100% { r: 8; }
|
|
50% { r: 9.5; }
|
|
}
|
|
.center-node { animation: center-pulse 2.4s ease-in-out infinite; }
|
|
</style>
|
|
|
|
<rect width="200" height="200" rx="32" fill="#14142a"/>
|
|
|
|
<!--
|
|
B-state (flat diamond) positions:
|
|
top: 100,51 left: 55,100 right: 145,100 bottom: 100,149 center: 100,100
|
|
|
|
E-state (wireframe cube) positions:
|
|
topBack: 100,42 backLeft: 46,72 backRight: 154,72
|
|
center: 100,100 frontLeft: 46,128 frontRight: 154,128 bottom: 100,158
|
|
|
|
Mapping B→E:
|
|
top → topBack (100,51 → 100,42)
|
|
left → backLeft (55,100 → 46,72) AND spawns frontLeft (55,100 → 46,128)
|
|
right → backRight (145,100 → 154,72) AND spawns frontRight (145,100 → 154,128)
|
|
bottom → bottom (100,149 → 100,158)
|
|
center → center (100,100 → 100,100) stays
|
|
|
|
Timing: 1.5s hold B, 1s morph to E, 2s hold E, 1s morph back, repeat
|
|
-->
|
|
|
|
<!-- ═══ EDGES ═══ -->
|
|
<!-- Diamond outline (B) that morphs to cube edges (E) -->
|
|
|
|
<!-- top→right becomes topBack→backRight -->
|
|
<line stroke="#c8c8d0" stroke-width="2" stroke-linecap="round" opacity="0.25"
|
|
x1="100" y1="51" x2="145" y2="100">
|
|
<animate attributeName="x1" values="100;100;100;100;100" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="y1" values="51;51;42;42;51" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="x2" values="145;145;154;154;145" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="y2" values="100;100;72;72;100" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
</line>
|
|
|
|
<!-- right→bottom becomes backRight→frontRight -->
|
|
<line stroke="#c8c8d0" stroke-width="2" stroke-linecap="round" opacity="0.25"
|
|
x1="145" y1="100" x2="100" y2="149">
|
|
<animate attributeName="x1" values="145;145;154;154;145" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="y1" values="100;100;72;72;100" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="x2" values="100;100;154;154;100" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="y2" values="149;149;128;128;149" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
</line>
|
|
|
|
<!-- bottom→left becomes frontRight→bottom (front bottom-right) -->
|
|
<line stroke="#c8c8d0" stroke-width="2.5" stroke-linecap="round" opacity="0.25"
|
|
x1="100" y1="149" x2="55" y2="100">
|
|
<animate attributeName="x1" values="100;100;154;154;100" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="y1" values="149;149;128;128;149" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="x2" values="55;55;100;100;55" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="y2" values="100;100;158;158;100" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="opacity" values="0.25;0.25;0.9;0.9;0.25" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
</line>
|
|
|
|
<!-- left→top becomes backLeft→topBack -->
|
|
<line stroke="#c8c8d0" stroke-width="2" stroke-linecap="round" opacity="0.25"
|
|
x1="55" y1="100" x2="100" y2="51">
|
|
<animate attributeName="x1" values="55;55;46;46;55" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="y1" values="100;100;72;72;100" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="x2" values="100;100;100;100;100" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="y2" values="51;51;42;42;51" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
</line>
|
|
|
|
<!-- Cross: left→center becomes backLeft→center -->
|
|
<line stroke="#c8c8d0" stroke-width="2" stroke-linecap="round" opacity="0.4"
|
|
x1="55" y1="100" x2="100" y2="100">
|
|
<animate attributeName="x1" values="55;55;46;46;55" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="y1" values="100;100;72;72;100" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
</line>
|
|
|
|
<!-- Cross: right→center becomes backRight→center -->
|
|
<line stroke="#c8c8d0" stroke-width="2" stroke-linecap="round" opacity="0.4"
|
|
x1="145" y1="100" x2="100" y2="100">
|
|
<animate attributeName="x1" values="145;145;154;154;145" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="y1" values="100;100;72;72;100" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
</line>
|
|
|
|
<!-- Cross: center→bottom stays vertical but bottom moves -->
|
|
<line stroke="#c8c8d0" stroke-width="2" stroke-linecap="round" opacity="0.4"
|
|
x1="100" y1="100" x2="100" y2="149">
|
|
<animate attributeName="y2" values="149;149;158;158;149" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
</line>
|
|
|
|
<!-- Cross: top→center vertical -->
|
|
<line stroke="#c8c8d0" stroke-width="2" stroke-linecap="round" opacity="0.4"
|
|
x1="100" y1="51" x2="100" y2="100">
|
|
<animate attributeName="y1" values="51;51;42;42;51" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
</line>
|
|
|
|
<!-- NEW edges that appear in E-state (start invisible) -->
|
|
<!-- frontLeft→bottom -->
|
|
<line stroke="#c8c8d0" stroke-width="2.5" stroke-linecap="round"
|
|
x1="55" y1="100" x2="100" y2="149" opacity="0">
|
|
<animate attributeName="x1" values="55;55;46;46;55" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="y1" values="100;100;128;128;100" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="y2" values="149;149;158;158;149" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="opacity" values="0;0;0.9;0.9;0" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
</line>
|
|
|
|
<!-- backLeft→frontLeft (left vertical) -->
|
|
<line stroke="#c8c8d0" stroke-width="2.5" stroke-linecap="round"
|
|
x1="55" y1="100" x2="55" y2="100" opacity="0">
|
|
<animate attributeName="x1" values="55;55;46;46;55" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="y1" values="100;100;72;72;100" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="x2" values="55;55;46;46;55" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="y2" values="100;100;128;128;100" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="opacity" values="0;0;0.9;0.9;0" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
</line>
|
|
|
|
<!-- ═══ NODES ═══ -->
|
|
|
|
<!-- Top → TopBack -->
|
|
<circle cx="100" cy="51" r="8" fill="#3B82F6">
|
|
<animate attributeName="cy" values="51;51;42;42;51" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="opacity" values="1;1;0.55;0.55;1" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="r" values="8;8;6;6;8" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
</circle>
|
|
|
|
<!-- Left → BackLeft -->
|
|
<circle cx="55" cy="100" r="8" fill="#3B82F6">
|
|
<animate attributeName="cx" values="55;55;46;46;55" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="cy" values="100;100;72;72;100" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="opacity" values="1;1;0.55;0.55;1" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="r" values="8;8;6;6;8" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
</circle>
|
|
|
|
<!-- Right → BackRight -->
|
|
<circle cx="145" cy="100" r="8" fill="#EF4444">
|
|
<animate attributeName="cx" values="145;145;154;154;145" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="cy" values="100;100;72;72;100" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="opacity" values="1;1;0.55;0.55;1" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="r" values="8;8;6;6;8" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
</circle>
|
|
|
|
<!-- Bottom → Bottom (slight shift) -->
|
|
<circle cx="100" cy="149" r="8" fill="#3B82F6">
|
|
<animate attributeName="cy" values="149;149;158;158;149" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="r" values="8;8;6;6;8" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
</circle>
|
|
|
|
<!-- FrontLeft: spawns from Left position, invisible in B -->
|
|
<circle cx="55" cy="100" r="0" fill="#EF4444" opacity="0">
|
|
<animate attributeName="cx" values="55;55;46;46;55" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="cy" values="100;100;128;128;100" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="r" values="0;0;6;6;0" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
</circle>
|
|
|
|
<!-- FrontRight: spawns from Right position, invisible in B -->
|
|
<circle cx="145" cy="100" r="0" fill="#3B82F6" opacity="0">
|
|
<animate attributeName="cx" values="145;145;154;154;145" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="cy" values="100;100;128;128;100" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="r" values="0;0;6;6;0" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="opacity" values="0;0;1;1;0" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
</circle>
|
|
|
|
<!-- Center (always visible, pulse) -->
|
|
<circle cx="100" cy="100" r="10" fill="#3B82F6" class="center-node">
|
|
<animate attributeName="r" values="10;10;8;8;10" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="opacity" values="1;1;0.7;0.7;1" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
</circle>
|
|
|
|
<!-- Center glow -->
|
|
<circle cx="100" cy="100" r="16" fill="#3B82F6" opacity="0.12">
|
|
<animate attributeName="r" values="16;16;12;12;16" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="opacity" values="0.12;0.12;0.06;0.06;0.12" keyTimes="0;0.27;0.45;0.73;1" dur="5.5s" repeatCount="indefinite"/>
|
|
</circle>
|
|
</svg>
|