feat(ui): reduce diagram size 75% and add permanent side-by-side panel
SUMMARY: Reduced interactive diagram size by 75% (to 25% of original) and implemented permanent service detail panel that displays side-by-side with the diagram on all viewports. CHANGES: 1. Diagram Size Reduction (architecture.html): - Mobile: 384px → 96px (max-w-[96px]) - Tablet: 448px → 128px (sm:max-w-[128px]) - Desktop: 512px → 160px (lg:max-w-[160px]) - Removed max-height constraint - Removed mobile/desktop conditional widths 2. Permanent Service Panel (architecture.html): - Added permanent #service-detail-panel div - Default state: Info icon with instructions - Always visible (flex-1 layout) - Min height: 300px for consistent sizing - Background: gray-50 with shadow-inner 3. JavaScript Updates (interactive-diagram.js): - Removed dynamic panel creation/removal logic - Removed close button functionality - Removed closePanel() method entirely - Removed fade-in/fade-out animations - Panel now updates in-place when service clicked - Border color changes to match selected service 4. Layout Improvements (architecture.html): - Changed to gap-6 (applies to all viewports) - Diagram and panel always side-by-side on desktop - Stacked vertically on mobile (flex-col lg:flex-row) - Removed mb-6 lg:mb-0 (gap handles spacing) RESPONSIVE BEHAVIOR: - Mobile (<1024px): Stacked vertically, diagram 96px, panel below - Desktop (≥1024px): Side-by-side, diagram 160px, panel fills remaining space UX IMPROVEMENTS: ✓ Diagram much smaller, less dominant ✓ Service details always visible on canvas ✓ No modal/popup behavior - permanent panel ✓ Default state guides user to click nodes ✓ Cleaner, more professional layout CACHE-BUSTING: Updated interactive-diagram.js version to v=20251019164500 🤖 Generated with Claude Code (https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
2b7b378d08
commit
f0ebd1a2b0
2 changed files with 26 additions and 65 deletions
|
|
@ -331,23 +331,32 @@
|
|||
</div>
|
||||
|
||||
<div id="diagram-container" class="relative bg-white rounded-xl shadow-lg p-4 sm:p-6 lg:p-8 border border-gray-200">
|
||||
<!-- Flex container for side-by-side layout on desktop -->
|
||||
<div class="flex flex-col lg:flex-row lg:items-start lg:gap-6">
|
||||
<!-- Interactive SVG -->
|
||||
<div class="flex-shrink-0 flex justify-center lg:justify-start w-full lg:w-auto mb-6 lg:mb-0">
|
||||
<!-- Flex container for side-by-side layout -->
|
||||
<div class="flex flex-col lg:flex-row lg:items-start gap-6">
|
||||
<!-- Interactive SVG (reduced to 25% of original size) -->
|
||||
<div class="flex-shrink-0 flex justify-center lg:justify-start">
|
||||
<object
|
||||
data="/images/architecture-diagram-interactive.svg"
|
||||
type="image/svg+xml"
|
||||
id="interactive-svg-object"
|
||||
class="w-full max-w-sm sm:max-w-md lg:max-w-lg h-auto max-h-[500px]"
|
||||
class="w-full max-w-[96px] sm:max-w-[128px] lg:max-w-[160px] h-auto"
|
||||
aria-label="Interactive Tractatus Architecture Diagram">
|
||||
<!-- Fallback for browsers that don't support object tag -->
|
||||
<img src="/images/architecture-diagram-interactive.svg" alt="Tractatus Architecture Diagram" class="w-full max-w-sm sm:max-w-md lg:max-w-lg" />
|
||||
<img src="/images/architecture-diagram-interactive.svg" alt="Tractatus Architecture Diagram" class="w-full max-w-[96px] sm:max-w-[128px] lg:max-w-[160px]" />
|
||||
</object>
|
||||
</div>
|
||||
|
||||
<!-- Service detail panel will be dynamically inserted here by interactive-diagram.js -->
|
||||
<!-- It will appear to the right of the diagram on desktop, below on mobile -->
|
||||
<!-- Service detail panel (permanent, updates on click) -->
|
||||
<div id="service-detail-panel" class="flex-1 bg-gray-50 rounded-xl shadow-inner p-6 border border-gray-200 min-h-[300px]">
|
||||
<!-- Default state - will be replaced when service is clicked -->
|
||||
<div id="panel-default-state" class="flex flex-col items-center justify-center h-full text-center">
|
||||
<svg class="w-16 h-16 text-gray-400 mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
||||
</svg>
|
||||
<h3 class="text-lg font-semibold text-gray-700 mb-2">Explore the Governance Services</h3>
|
||||
<p class="text-sm text-gray-500 max-w-md">Click any service node in the diagram (colored circles) or the central "T" to learn more about how Tractatus enforces AI safety.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -512,7 +521,7 @@
|
|||
<script src="/js/scroll-animations.js"></script>
|
||||
|
||||
<!-- Interactive Architecture Diagram (Phase 3) -->
|
||||
<script src="/js/components/interactive-diagram.js?v=20251019163000"></script>
|
||||
<script src="/js/components/interactive-diagram.js?v=20251019164500"></script>
|
||||
|
||||
<!-- Footer Component -->
|
||||
<script src="/js/components/footer.js"></script>
|
||||
|
|
|
|||
|
|
@ -250,28 +250,19 @@ class InteractiveDiagram {
|
|||
}
|
||||
|
||||
renderServicePanel(service) {
|
||||
let panel = document.getElementById('service-detail-panel');
|
||||
const panel = document.getElementById('service-detail-panel');
|
||||
|
||||
if (!panel) {
|
||||
panel = document.createElement('div');
|
||||
panel.id = 'service-detail-panel';
|
||||
panel.className = 'w-full lg:flex-1 bg-white rounded-xl shadow-2xl p-4 sm:p-6 border-2 lg:min-w-[400px]';
|
||||
panel.style.borderColor = service.color;
|
||||
|
||||
// Insert into the flex container for side-by-side layout
|
||||
const flexContainer = document.querySelector('#diagram-container > div');
|
||||
if (flexContainer) {
|
||||
flexContainer.appendChild(panel);
|
||||
} else {
|
||||
console.error('[InteractiveDiagram] Flex container not found');
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
panel.style.borderColor = service.color;
|
||||
console.error('[InteractiveDiagram] Service detail panel not found in DOM');
|
||||
return;
|
||||
}
|
||||
|
||||
// Update border color to match selected service
|
||||
panel.style.borderColor = service.color;
|
||||
panel.style.borderWidth = '2px';
|
||||
|
||||
const html = `
|
||||
<div class="flex items-start justify-between mb-4">
|
||||
<div class="flex items-start mb-4">
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="w-12 h-12 rounded-xl flex items-center justify-center text-2xl service-icon-box" data-color="${service.color}">
|
||||
${service.icon}
|
||||
|
|
@ -281,11 +272,6 @@ class InteractiveDiagram {
|
|||
<span class="text-xs font-medium text-gray-600 uppercase">${service.shortName}</span>
|
||||
</div>
|
||||
</div>
|
||||
<button id="close-panel-btn" class="text-gray-400 hover:text-gray-600 transition" aria-label="Close">
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p class="text-gray-700 mb-4 leading-relaxed">${service.description}</p>
|
||||
|
|
@ -339,40 +325,6 @@ class InteractiveDiagram {
|
|||
const color = promiseText.getAttribute('data-color');
|
||||
promiseText.style.color = color;
|
||||
}
|
||||
|
||||
// Add close button event listener (CSP-compliant)
|
||||
const closeBtn = panel.querySelector('#close-panel-btn');
|
||||
if (closeBtn) {
|
||||
closeBtn.addEventListener('click', () => this.closePanel());
|
||||
}
|
||||
|
||||
panel.style.opacity = '0';
|
||||
panel.style.transform = 'translateY(20px)';
|
||||
panel.style.transition = 'opacity 0.3s ease, transform 0.3s ease';
|
||||
|
||||
setTimeout(() => {
|
||||
panel.style.opacity = '1';
|
||||
panel.style.transform = 'translateY(0)';
|
||||
}, 10);
|
||||
}
|
||||
|
||||
closePanel() {
|
||||
const panel = document.getElementById('service-detail-panel');
|
||||
if (panel) {
|
||||
panel.style.opacity = '0';
|
||||
panel.style.transform = 'translateY(20px)';
|
||||
|
||||
setTimeout(() => {
|
||||
panel.remove();
|
||||
}, 300);
|
||||
}
|
||||
|
||||
if (this.svg) {
|
||||
this.svg.querySelectorAll('.service-node').forEach(n => n.classList.remove('active'));
|
||||
this.svg.querySelectorAll('.connection-line').forEach(l => l.classList.remove('active'));
|
||||
}
|
||||
|
||||
this.activeService = null;
|
||||
}
|
||||
|
||||
addKeyboardNavigation(nodes) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue