hatch-slidev-builder-mcp
Version:
A comprehensive MCP server for creating Slidev presentations with component library, interactive elements, and team collaboration features
225 lines (221 loc) • 8.09 kB
JavaScript
/**
* Layer 2: Layout Optimization Engine
* Smart layout selection based on content type and design patterns
*/
export class LayoutOptimizationEngine {
static layouts = [
{
name: 'hero-centered',
grid_system: 'flexbox',
visual_hierarchy: 'center-focused',
layout_type: 'hero',
responsive_breakpoints: ['mobile', 'tablet', 'desktop'],
best_for: ['opening slides', 'title slides', 'key messages', 'announcements']
},
{
name: 'content-split',
grid_system: '12-column',
visual_hierarchy: 'Z-pattern',
layout_type: 'split',
responsive_breakpoints: ['tablet', 'desktop'],
best_for: ['comparisons', 'before/after', 'problem/solution', 'feature descriptions']
},
{
name: 'information-grid',
grid_system: 'css-grid',
visual_hierarchy: 'F-pattern',
layout_type: 'grid',
responsive_breakpoints: ['mobile', 'tablet', 'desktop'],
best_for: ['data presentation', 'multiple points', 'dashboard views', 'feature grids']
},
{
name: 'process-timeline',
grid_system: 'flexbox',
visual_hierarchy: 'left-aligned',
layout_type: 'timeline',
responsive_breakpoints: ['tablet', 'desktop'],
best_for: ['step-by-step processes', 'roadmaps', 'chronological data', 'workflows']
},
{
name: 'comparison-table',
grid_system: '12-column',
visual_hierarchy: 'F-pattern',
layout_type: 'comparison',
responsive_breakpoints: ['tablet', 'desktop'],
best_for: ['feature comparisons', 'competitive analysis', 'pros/cons', 'options evaluation']
},
{
name: 'process-flow',
grid_system: 'flexbox',
visual_hierarchy: 'Z-pattern',
layout_type: 'process_flow',
responsive_breakpoints: ['tablet', 'desktop'],
best_for: ['workflows', 'user journeys', 'system processes', 'methodology explanations']
}
];
/**
* Recommend optimal layout based on content analysis
*/
static recommendLayout(slideType, contentDensity, audience, hasVisuals = false) {
let recommendedLayout;
let confidence_score = 0;
let reason = '';
// Layout selection logic
switch (slideType) {
case 'hero':
recommendedLayout = this.layouts.find(l => l.name === 'hero-centered');
confidence_score = 0.95;
reason = 'Hero layout optimal for opening slides and key messages';
break;
case 'problem':
case 'solution':
if (hasVisuals) {
recommendedLayout = this.layouts.find(l => l.name === 'content-split');
confidence_score = 0.9;
reason = 'Split layout ideal for problem/solution with supporting visuals';
}
else {
recommendedLayout = this.layouts.find(l => l.name === 'hero-centered');
confidence_score = 0.8;
reason = 'Centered layout for text-heavy problem/solution slides';
}
break;
case 'evidence':
if (contentDensity === 'high') {
recommendedLayout = this.layouts.find(l => l.name === 'information-grid');
confidence_score = 0.85;
reason = 'Grid layout handles high-density evidence effectively';
}
else {
recommendedLayout = this.layouts.find(l => l.name === 'content-split');
confidence_score = 0.8;
reason = 'Split layout for evidence with supporting visuals';
}
break;
case 'comparison':
recommendedLayout = this.layouts.find(l => l.name === 'comparison-table');
confidence_score = 0.9;
reason = 'Comparison layout optimized for side-by-side analysis';
break;
case 'process':
case 'workflow':
recommendedLayout = this.layouts.find(l => l.name === 'process-flow');
confidence_score = 0.88;
reason = 'Process flow layout ideal for step-by-step content';
break;
default:
// Default based on content density
if (contentDensity === 'high') {
recommendedLayout = this.layouts.find(l => l.name === 'information-grid');
confidence_score = 0.7;
reason = 'Grid layout for high-density content';
}
else {
recommendedLayout = this.layouts.find(l => l.name === 'content-split');
confidence_score = 0.75;
reason = 'Split layout as versatile default';
}
}
// Calculate accessibility score
const accessibility_score = this.calculateAccessibilityScore(recommendedLayout, audience);
return {
pattern: recommendedLayout,
confidence_score,
accessibility_score,
reason,
css_framework: this.generateCSSFramework(recommendedLayout)
};
}
/**
* Calculate accessibility score for layout
*/
static calculateAccessibilityScore(layout, audience) {
let score = 0.8; // Base score
// Boost for mobile-friendly layouts
if (layout.responsive_breakpoints.includes('mobile')) {
score += 0.1;
}
// Boost for clear visual hierarchy
if (layout.visual_hierarchy === 'F-pattern' || layout.visual_hierarchy === 'Z-pattern') {
score += 0.1;
}
// Adjustment for executive audience (prefer simpler layouts)
if (audience === 'executive' && layout.layout_type === 'hero') {
score += 0.05;
}
return Math.min(1.0, score);
}
/**
* Generate CSS framework code for layout
*/
static generateCSSFramework(layout) {
switch (layout.grid_system) {
case '12-column':
return `
.slide-container {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 1rem;
padding: 2rem;
}`;
case 'flexbox':
return `
.slide-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 2rem;
min-height: 100vh;
}`;
case 'css-grid':
return `
.slide-container {
display: grid;
grid-template-areas:
"header header header"
"content content sidebar"
"footer footer footer";
gap: 1.5rem;
padding: 2rem;
}`;
default:
return `
.slide-container {
display: flex;
flex-direction: column;
padding: 2rem;
}`;
}
}
/**
* Generate responsive breakpoints
*/
static generateResponsiveCSS(layout) {
return `
/* Mobile First Approach */
.slide-container {
${this.generateCSSFramework(layout)}
}
@media (min-width: 768px) {
/* Tablet adjustments */
.slide-container {
padding: 3rem;
}
}
@media (min-width: 1024px) {
/* Desktop adjustments */
.slide-container {
padding: 4rem;
max-width: 1200px;
margin: 0 auto;
}
}
@media (min-width: 1440px) {
/* Large screen optimizations */
.slide-container {
padding: 5rem;
}
}`;
}
}