feat: rebuild Process Studio into multi-phase Process Creation Wizard\n\n- Replace toy Studio.tsx with proper Wizard.tsx canvas\n- Build 6-step flow: Intake -> Analyze -> Generate -> Validate -> Draft saved -> Publish\n- Implement incremental EA2 writes via wizardApi.ts (flow, batch apply)\n- Use localStorage for draft recovery across reloads\n- Apply industrial-blueprint UI styling matching core doctrine\n- Add Vitest tests for Wizard components and API wrappers

This commit is contained in:
2026-06-14 03:47:26 +04:00
parent b2c1e57c86
commit 4bc7ae228a
27 changed files with 2274 additions and 275 deletions
+440
View File
@@ -8,6 +8,17 @@
- light paper canvas + navy frame + amber accent
- 1px rules, square edges, monospace operational density
===================================================================== */
[data-theme="dark"] {
--bp-paper: #0c1322;
--bp-paper-2: #1a2740;
--bp-paper-3: #243453;
--bp-navy: #e6edf7;
--bp-navy-2: #d5dde9;
--bp-muted: #7a8aa8;
--bp-muted-2: #4a5b80;
}
:root {
/* Doctrinal hex tokens — declared once, referenced everywhere via var(). */
--bp-paper: #f5f7fb;
@@ -108,6 +119,8 @@ kbd {
Topbar (industrial instrument strip)
===================================================================== */
.topbar {
position: relative;
z-index: 190;
display: grid;
grid-template-columns: auto auto 1fr auto;
align-items: stretch;
@@ -1143,6 +1156,198 @@ select.studio-input { background: var(--bp-paper); }
.toast-warn { border-left-color: var(--bp-amber); }
.toast-err { border-left-color: var(--bp-err); }
/* =====================================================================
Login Page
===================================================================== */
.login-page {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
background: var(--bp-paper);
background-image: linear-gradient(var(--bp-grid-minor) 1px, transparent 1px),
linear-gradient(90deg, var(--bp-grid-minor) 1px, transparent 1px);
background-size: 20px 20px;
}
.login-card {
width: 380px;
background: var(--bp-paper);
border: 1px solid var(--bp-navy);
padding: 24px 32px;
position: relative;
}
.login-card::before {
content: '';
position: absolute;
top: 0; left: 0;
width: 18px; height: 18px;
border-right: 1px solid var(--bp-navy);
border-bottom: 1px solid var(--bp-navy);
background: var(--bp-paper-2);
}
.login-head {
text-align: center;
margin-bottom: 24px;
}
.login-head .brand-mark {
display: inline-block;
width: 24px; height: 24px;
background: var(--bp-amber);
border: 1px solid var(--bp-navy);
margin-bottom: 12px;
}
.login-head h1 {
margin: 0;
font-family: var(--bp-mono);
font-size: 16px;
font-weight: 700;
letter-spacing: 0.05em;
color: var(--bp-navy);
}
.login-sub {
margin-top: 4px;
font-size: 10px;
color: var(--bp-muted);
letter-spacing: 0.15em;
}
.login-form {
display: flex;
flex-direction: column;
gap: 16px;
}
.login-field {
display: flex;
flex-direction: column;
gap: 6px;
}
.login-field label {
font-size: 10px;
font-weight: 700;
color: var(--bp-muted);
letter-spacing: 0.1em;
}
.login-input {
background: var(--bp-paper);
border: 1px solid var(--bp-navy);
padding: 8px 12px;
font-family: var(--bp-mono);
font-size: 13px;
color: var(--bp-navy);
}
.login-input:focus {
outline: 2px solid var(--bp-amber);
outline-offset: 0;
}
.login-input:disabled {
opacity: 0.6;
background: var(--bp-paper-2);
}
.login-row {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: -4px;
}
.login-checkbox {
display: flex;
align-items: center;
gap: 8px;
font-size: 11px;
color: var(--bp-navy);
cursor: pointer;
}
.login-checkbox input {
accent-color: var(--bp-amber);
width: 14px;
height: 14px;
}
.login-link {
font-size: 11px;
color: var(--bp-amber);
text-decoration: underline;
}
.login-actions {
margin-top: 8px;
}
.login-actions .btn {
width: 100%;
}
.login-divider {
display: flex;
align-items: center;
text-align: center;
margin: 24px 0;
}
.login-divider::before,
.login-divider::after {
content: '';
flex: 1;
border-bottom: 1px solid var(--bp-navy);
opacity: 0.2;
}
.login-divider span {
padding: 0 10px;
font-size: 10px;
color: var(--bp-muted);
letter-spacing: 0.1em;
}
.login-sso-actions {
display: flex;
flex-direction: column;
gap: 12px;
}
.sso-btn {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
width: 100%;
padding: 8px 12px;
background: var(--bp-paper);
border: 1px solid var(--bp-navy);
color: var(--bp-navy);
font-family: var(--bp-mono);
font-size: 11px;
font-weight: 700;
letter-spacing: 0.05em;
transition: background 0.1s;
}
.sso-btn:hover:not(:disabled) {
background: var(--bp-paper-2);
}
.dev-login-btn {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
width: 100%;
padding: 8px 12px;
background: var(--bp-paper-2);
border: 1px dashed var(--bp-navy);
color: var(--bp-muted);
font-family: var(--bp-mono);
font-size: 10px;
font-weight: 700;
letter-spacing: 0.05em;
transition: background 0.1s, color 0.1s;
}
.dev-login-btn:hover:not(:disabled) {
background: var(--bp-paper-3);
color: var(--bp-navy);
}
.dev-login-btn:disabled, .sso-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.login-error {
margin-bottom: 16px;
padding: 8px 12px;
background: var(--bp-err-soft);
border-left: 2px solid var(--bp-err);
color: var(--bp-err);
font-size: 11px;
}
/* =====================================================================
Scrollbars
===================================================================== */
@@ -1347,3 +1552,238 @@ select.studio-input { background: var(--bp-paper); }
[data-canvas="blueprint"] .react-flow__edge.selected .react-flow__edge-path,
[data-canvas="blueprint"] .react-flow__edge:focus .react-flow__edge-path { stroke: var(--bp-amber); }
[data-canvas="blueprint"] .react-flow__attribution { display: none; }
/* Wizard */
.wizard-container {
display: flex;
flex-direction: column;
gap: var(--space-xl);
padding: var(--space-xl) var(--space-2xl);
height: 100%;
overflow-y: auto;
}
.wizard-header {
display: flex;
flex-direction: column;
gap: var(--space-xl);
}
.wizard-progress {
display: flex;
align-items: center;
gap: var(--space-xs);
background: var(--paper);
padding: var(--space-md);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
}
.wizard-step-marker {
display: flex;
align-items: center;
gap: var(--space-sm);
color: var(--text-3);
font-family: var(--font-mono);
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.5px;
padding: var(--space-xs) var(--space-sm);
border-radius: var(--radius-sm);
}
.wizard-step-marker.active {
background: var(--amber);
color: var(--navy);
font-weight: 600;
}
.wizard-step-marker.past {
color: var(--text-1);
background: var(--ok-soft);
}
.step-num {
width: 16px;
height: 16px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background: currentColor;
color: var(--paper);
font-size: 9px;
font-weight: 700;
}
.wizard-step-marker.active .step-num {
background: var(--navy);
color: var(--amber);
}
.wizard-step-marker.past .step-num {
background: var(--ok);
color: var(--paper);
}
.step-chevron {
color: var(--border);
margin-left: var(--space-xs);
}
.wizard-content {
display: flex;
flex-direction: column;
gap: var(--space-xl);
max-width: 800px;
}
.wizard-panel {
background: var(--paper);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
padding: var(--space-xl);
display: flex;
flex-direction: column;
gap: var(--space-lg);
}
.wizard-panel.success-panel {
align-items: center;
text-align: center;
border-color: var(--ok);
background: var(--ok-soft);
}
.success-icon {
color: var(--ok);
margin-bottom: var(--space-sm);
}
.field-group {
display: flex;
flex-direction: column;
gap: var(--space-xs);
}
.field-group label {
font-size: 13px;
color: var(--text-2);
font-weight: 500;
}
.field-group input, .field-group textarea {
background: var(--paper-2);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
padding: var(--space-sm) var(--space-md);
color: var(--text-1);
font-family: var(--font-sans);
font-size: 14px;
}
.field-group input:focus, .field-group textarea:focus {
outline: none;
border-color: var(--amber);
}
.warning-text {
color: var(--warn);
font-size: 12px;
margin-top: var(--space-xs);
}
.node-list, .field-list {
display: flex;
flex-direction: column;
gap: var(--space-sm);
}
.node-card, .field-row {
display: flex;
align-items: center;
gap: var(--space-md);
background: var(--paper-2);
border: 1px solid var(--border);
padding: var(--space-sm) var(--space-md);
border-radius: var(--radius-sm);
}
.node-header {
display: flex;
align-items: center;
gap: var(--space-sm);
flex: 1;
}
.node-idx {
font-family: var(--font-mono);
font-size: 11px;
color: var(--text-3);
background: var(--border);
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
}
.node-header input, .field-row input {
background: transparent;
border: 1px solid transparent;
color: var(--text-1);
font-family: var(--font-sans);
font-size: 14px;
width: 100%;
padding: var(--space-xs) var(--space-sm);
}
.node-header input:hover, .field-row input:hover {
border-color: var(--border);
}
.node-header input:focus, .field-row input:focus {
outline: none;
border-color: var(--amber);
background: var(--paper);
}
.node-meta select, .field-row select {
background: var(--paper);
border: 1px solid var(--border);
color: var(--text-2);
font-size: 13px;
padding: var(--space-xs) var(--space-sm);
border-radius: var(--radius-sm);
}
.summary-stats {
display: flex;
gap: var(--space-xl);
padding: var(--space-md);
background: var(--paper-2);
border-radius: var(--radius-sm);
}
.summary-stats div {
display: flex;
flex-direction: column;
gap: var(--space-2xs);
font-size: 18px;
font-weight: 500;
color: var(--text-1);
}
.summary-stats span {
font-size: 11px;
text-transform: uppercase;
color: var(--text-3);
letter-spacing: 0.5px;
}
.actions-row {
display: flex;
gap: var(--space-md);
align-items: center;
}