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:
+440
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user