Add 'Coming Soon' states for incomplete skills and commands

- Add readySkills and readyCommands arrays in data.js to track completion
- Only /normalize command is marked as ready (first to be completed)
- All skills marked as coming soon (still being refined)
- Show 'Soon' badges in navigation for incomplete items
- Show placeholder with clock icon when selecting incomplete items
- Ready items show full demo, downloads, and details
This commit is contained in:
Paul Bakaus
2025-12-06 12:39:05 -08:00
parent 6c29963af9
commit 5b6aafc85e
4 changed files with 126 additions and 6 deletions
+60 -1
View File
@@ -318,6 +318,64 @@
}
/* Coming Soon States */
.skill-nav-item.coming-soon,
.command-nav-item.coming-soon {
opacity: 0.7;
}
.coming-soon-badge {
display: inline-block;
font-size: 0.5625rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
padding: 2px 5px;
background: var(--c-mist);
color: var(--c-ash);
border-radius: 2px;
margin-left: var(--s-xs);
vertical-align: middle;
}
.coming-soon-showcase {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
padding: var(--s-2xl);
min-height: 300px;
}
.coming-soon-icon {
color: var(--c-mist);
margin-bottom: var(--s-lg);
}
.coming-soon-showcase h3 {
font-family: var(--font-display);
font-size: 1.75rem;
font-weight: 300;
font-style: italic;
margin: 0 0 var(--s-sm) 0;
color: var(--c-text);
}
.coming-soon-text {
font-size: 1rem;
color: var(--c-accent);
font-weight: 500;
margin-bottom: var(--s-md);
}
.coming-soon-showcase .skill-description {
max-width: 50ch;
color: var(--c-ash);
font-size: 0.9375rem;
line-height: 1.6;
}
/* Animation */
@keyframes fadeIn {
from {
@@ -331,6 +389,7 @@
}
.skills-showcase,
.command-detail-panel {
.command-detail-panel,
.coming-soon-showcase {
animation: fadeIn 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
+31 -3
View File
@@ -7,12 +7,18 @@ import {
commandCategories,
commandProcessSteps,
commandRelationships,
readyCommands,
} from "./data.js";
import { setupCommandDemoToggles } from "./demo-toggles.js";
let currentCommand = null;
let currentCategory = "all";
// Check if a command is ready for public use
function isCommandReady(id) {
return readyCommands.includes(id);
}
export function renderWorkflowDiagram(allCommands, onSelectCommand) {
const container = document.getElementById("workflow-diagram");
if (!container) return;
@@ -24,18 +30,23 @@ export function renderWorkflowDiagram(allCommands, onSelectCommand) {
system: ['extract', 'onboard']
};
const renderNavItem = (id) => {
const ready = isCommandReady(id);
return `<button class="command-nav-item ${!ready ? 'coming-soon' : ''}" data-command="${id}">/${id}${!ready ? '<span class="coming-soon-badge">Soon</span>' : ''}</button>`;
};
container.innerHTML = `
<div class="command-nav-group">
<span class="command-nav-label">Production</span>
${groups.production.map(id => `<button class="command-nav-item" data-command="${id}">/${id}</button>`).join('')}
${groups.production.map(renderNavItem).join('')}
</div>
<div class="command-nav-group">
<span class="command-nav-label">Aesthetic</span>
${groups.aesthetic.map(id => `<button class="command-nav-item" data-command="${id}">/${id}</button>`).join('')}
${groups.aesthetic.map(renderNavItem).join('')}
</div>
<div class="command-nav-group">
<span class="command-nav-label">System</span>
${groups.system.map(id => `<button class="command-nav-item" data-command="${id}">/${id}</button>`).join('')}
${groups.system.map(renderNavItem).join('')}
</div>
`;
@@ -116,6 +127,23 @@ function renderCommandDetail(command) {
const relationships = commandRelationships[command.id] || {};
const steps = commandProcessSteps[command.id] || [];
const category = commandCategories[command.id] || "other";
const ready = isCommandReady(command.id);
// Coming soon placeholder for incomplete commands
if (!ready) {
return `
<div class="coming-soon-showcase">
<div class="coming-soon-icon">
<svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
<path d="M12 6v6l4 2M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10z"/>
</svg>
</div>
<h3>/${command.id}</h3>
<p class="coming-soon-text">This command is being refined and will be available soon.</p>
<p class="skill-description">${command.description}</p>
</div>
`;
}
return `
<div class="command-detail-panel">
+10
View File
@@ -2,6 +2,16 @@
// DATA: Skill focus areas, command processes, relationships
// ============================================
// Items that are fully complete and ready for public use
// All others will show "Coming Soon"
export const readySkills = [
// None ready yet - all skills are still being refined
];
export const readyCommands = [
'normalize' // First command to be fully completed
];
export const skillFocusAreas = {
'typography': [
{ area: 'Scale & Rhythm', detail: 'Harmonious systems' },
+25 -2
View File
@@ -2,7 +2,7 @@
// SKILLS - Rendering and selection logic
// ============================================
import { skillFocusAreas } from "./data.js";
import { skillFocusAreas, readySkills } from "./data.js";
import { setupDemoToggles } from "./demo-toggles.js";
import { renderSkillDemo, setupDemoTabs } from "./skill-demos.js";
@@ -20,6 +20,11 @@ function formatSkillName(id) {
.join(" ");
}
// Check if a skill is ready for public use
function isSkillReady(id) {
return readySkills.includes(id);
}
// Filter out frontend-design (Anthropic's skill, not ours)
function filterSkills(skills) {
return skills.filter((s) => s.id !== "frontend-design");
@@ -34,8 +39,9 @@ export function renderSkillsNav(skills, onSelect) {
nav.innerHTML = filteredSkills
.map(
(skill) => `
<button class="skill-nav-item" data-id="${skill.id}">
<button class="skill-nav-item ${!isSkillReady(skill.id) ? 'coming-soon' : ''}" data-id="${skill.id}">
${formatSkillName(skill.id)}
${!isSkillReady(skill.id) ? '<span class="coming-soon-badge">Soon</span>' : ''}
</button>
`,
)
@@ -82,6 +88,23 @@ export function selectSkill(skill, allSkills) {
function renderSkillShowcase(skill, allSkills) {
const focusAreas = skillFocusAreas[skill.id] || [];
const displayName = formatSkillName(skill.id);
const ready = isSkillReady(skill.id);
// Coming soon placeholder for incomplete skills
if (!ready) {
return `
<div class="coming-soon-showcase">
<div class="coming-soon-icon">
<svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
<path d="M12 6v6l4 2M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10z"/>
</svg>
</div>
<h3>${displayName}</h3>
<p class="coming-soon-text">This skill is being refined and will be available soon.</p>
<p class="skill-description">${skill.description}</p>
</div>
`;
}
return `
<div class="skill-demo-area">