petter2025 commited on
Commit
48d7a6c
·
verified ·
1 Parent(s): 03cfe7a

Delete ui

Browse files
ui/__init__.py DELETED
File without changes
ui/enhancements/progressive_disclosure.py DELETED
@@ -1,279 +0,0 @@
1
- """
2
- Progressive disclosure components for better UX
3
- Collapsible sections, tooltips, and conditional displays
4
- """
5
-
6
- class ProgressiveDisclosure:
7
- """Components that reveal information gradually"""
8
-
9
- @staticmethod
10
- def create_collapsible_section(title: str, content: str, initially_open: bool = False,
11
- badge_text: str = "", badge_color: str = "#3b82f6"):
12
- """Create expandable/collapsible section with optional badge"""
13
- section_id = f"section_{hash(title)}"
14
-
15
- badge_html = ""
16
- if badge_text:
17
- badge_html = f"""
18
- <span style="padding: 3px 10px; background: {badge_color}20; color: {badge_color};
19
- border-radius: 12px; font-size: 11px; font-weight: bold; margin-left: 10px;">
20
- {badge_text}
21
- </span>
22
- """
23
-
24
- return f"""
25
- <div class="collapsible-section" style="margin: 1rem 0;">
26
- <button
27
- onclick="toggleSection('{section_id}')"
28
- class="section-toggle {'open' if initially_open else ''}"
29
- aria-expanded="{str(initially_open).lower()}"
30
- aria-controls="{section_id}"
31
- style="width: 100%; padding: 1rem; background: var(--color-neutral-50);
32
- border: 1px solid var(--color-border); border-radius: 0.5rem;
33
- text-align: left; font-weight: 600; color: var(--color-text);
34
- cursor: pointer; display: flex; justify-content: space-between;
35
- align-items: center; transition: background 0.2s;"
36
- >
37
- <div style="display: flex; align-items: center; gap: 0.5rem;">
38
- <span style="font-size: 1.25rem;">{'▼' if initially_open else '▶'}</span>
39
- <span>{title}</span>
40
- {badge_html}
41
- </div>
42
- </button>
43
- <div
44
- id="{section_id}"
45
- class="section-content"
46
- style="display: {'block' if initially_open else 'none'}; padding: 1rem;
47
- background: white; border: 1px solid var(--color-border);
48
- border-top: none; border-radius: 0 0 0.5rem 0.5rem;"
49
- aria-hidden="{str(not initially_open).lower()}"
50
- >
51
- {content}
52
- </div>
53
- </div>
54
-
55
- <script>
56
- function toggleSection(id) {{
57
- const section = document.getElementById(id);
58
- const button = section.previousElementSibling;
59
- const isExpanded = section.style.display === 'none';
60
-
61
- // Toggle visibility
62
- section.style.display = isExpanded ? 'block' : 'none';
63
- section.setAttribute('aria-hidden', !isExpanded);
64
-
65
- // Update button state
66
- button.classList.toggle('open', isExpanded);
67
- button.setAttribute('aria-expanded', isExpanded);
68
-
69
- // Update toggle icon
70
- const icon = button.querySelector('span:first-child');
71
- icon.textContent = isExpanded ? '▼' : '▶';
72
-
73
- // Smooth scroll if opening
74
- if (isExpanded) {{
75
- section.scrollIntoView({{ behavior: 'smooth', block: 'nearest' }});
76
- }}
77
- }}
78
- </script>
79
- """
80
-
81
- @staticmethod
82
- def create_tooltip(text: str, tooltip_content: str, position: str = "top"):
83
- """Create text with a hover tooltip"""
84
- position_classes = {
85
- "top": "bottom: 125%; left: 50%; margin-left: -100px;",
86
- "bottom": "top: 125%; left: 50%; margin-left: -100px;",
87
- "left": "top: 50%; right: 125%; margin-top: -15px;",
88
- "right": "top: 50%; left: 125%; margin-top: -15px;"
89
- }
90
-
91
- position_css = position_classes.get(position, position_classes["top"])
92
-
93
- return f"""
94
- <span class="tooltip-container" style="position: relative; display: inline-block;">
95
- {text}
96
- <span class="tooltip-text" style="
97
- visibility: hidden; width: 200px; background: var(--color-neutral-800);
98
- color: white; text-align: center; padding: 0.5rem; border-radius: 0.375rem;
99
- position: absolute; z-index: 1000; {position_css} opacity: 0;
100
- transition: opacity 0.3s; font-size: 0.875rem; font-weight: normal;
101
- box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1);
102
- ">
103
- {tooltip_content}
104
- </span>
105
- </span>
106
-
107
- <style>
108
- .tooltip-container:hover .tooltip-text {{
109
- visibility: visible;
110
- opacity: 1;
111
- }}
112
- </style>
113
- """
114
-
115
- @staticmethod
116
- def create_progressive_form(steps: list):
117
- """Create a multi-step form with progressive disclosure"""
118
- steps_html = ""
119
- for i, step in enumerate(steps):
120
- step_id = f"step_{i}"
121
- steps_html += f"""
122
- <div id="{step_id}" class="form-step"
123
- style="display: {'block' if i == 0 else 'none'}; margin-bottom: 2rem;">
124
- <div style="display: flex; align-items: center; gap: 0.5rem; margin-bottom: 1rem;">
125
- <div style="width: 28px; height: 28px; background: {'var(--color-primary)' if i == 0 else 'var(--color-neutral-300)'};
126
- color: white; border-radius: 50%; display: flex; align-items: center;
127
- justify-content: center; font-weight: bold; font-size: 0.875rem;">
128
- {i + 1}
129
- </div>
130
- <h3 style="margin: 0; font-size: 1.125rem; color: var(--color-text);">
131
- {step['title']}
132
- </h3>
133
- </div>
134
- <div style="background: var(--color-neutral-50); border-radius: 0.5rem; padding: 1.5rem;">
135
- {step['content']}
136
- </div>
137
- </div>
138
- """
139
-
140
- # Navigation buttons HTML
141
- nav_html = """
142
- <div style="display: flex; justify-content: space-between; margin-top: 2rem;">
143
- <button onclick="previousStep()"
144
- style="padding: 0.5rem 1rem; background: var(--color-neutral-100);
145
- border: 1px solid var(--color-border); border-radius: 0.375rem;
146
- cursor: pointer; font-weight: 500;" id="prevBtn">
147
- ← Previous
148
- </button>
149
- <button onclick="nextStep()"
150
- style="padding: 0.5rem 1rem; background: var(--color-primary);
151
- color: white; border: none; border-radius: 0.375rem;
152
- cursor: pointer; font-weight: 500;" id="nextBtn">
153
- Next →
154
- </button>
155
- </div>
156
- """
157
-
158
- # JavaScript for step navigation
159
- js = f"""
160
- <script>
161
- let currentStep = 0;
162
- const totalSteps = {len(steps)};
163
-
164
- function updateButtons() {{
165
- document.getElementById('prevBtn').style.display = currentStep === 0 ? 'none' : 'block';
166
- document.getElementById('nextBtn').textContent = currentStep === totalSteps - 1 ? 'Finish' : 'Next →';
167
- }}
168
-
169
- function showStep(stepIndex) {{
170
- // Hide all steps
171
- document.querySelectorAll('.form-step').forEach(step => {{
172
- step.style.display = 'none';
173
- }});
174
-
175
- // Show current step
176
- document.getElementById('step_' + stepIndex).style.display = 'block';
177
- currentStep = stepIndex;
178
- updateButtons();
179
-
180
- // Smooth scroll to step
181
- document.getElementById('step_' + stepIndex).scrollIntoView({{
182
- behavior: 'smooth',
183
- block: 'start'
184
- }});
185
- }}
186
-
187
- function nextStep() {{
188
- if (currentStep < totalSteps - 1) {{
189
- showStep(currentStep + 1);
190
- }} else {{
191
- // Form completion logic
192
- alert('Form completed!');
193
- }}
194
- }}
195
-
196
- function previousStep() {{
197
- if (currentStep > 0) {{
198
- showStep(currentStep - 1);
199
- }}
200
- }}
201
-
202
- // Initialize
203
- updateButtons();
204
- </script>
205
- """
206
-
207
- return f"""
208
- <div style="max-width: 800px; margin: 0 auto;">
209
- {steps_html}
210
- {nav_html}
211
- {js}
212
- </div>
213
- """
214
-
215
- @staticmethod
216
- def create_accordion(items: list, allow_multiple: bool = False):
217
- """Create an accordion with multiple collapsible items"""
218
- accordion_id = f"accordion_{hash(str(items))}"
219
-
220
- items_html = ""
221
- for i, item in enumerate(items):
222
- item_id = f"{accordion_id}_item_{i}"
223
- items_html += f"""
224
- <div style="border: 1px solid var(--color-border); border-radius: 0.5rem;
225
- margin-bottom: 0.5rem; overflow: hidden;">
226
- <button
227
- onclick="toggleAccordionItem('{item_id}', {str(allow_multiple).lower()})"
228
- style="width: 100%; padding: 1rem; background: var(--color-neutral-50);
229
- border: none; text-align: left; font-weight: 600; color: var(--color-text);
230
- cursor: pointer; display: flex; justify-content: space-between;
231
- align-items: center; transition: background 0.2s;"
232
- >
233
- <span>{item['title']}</span>
234
- <span style="font-size: 1.25rem; transition: transform 0.2s;" id="{item_id}_icon">
235
-
236
- </span>
237
- </button>
238
- <div
239
- id="{item_id}"
240
- style="display: none; padding: 1rem; background: white;"
241
- >
242
- {item['content']}
243
- </div>
244
- </div>
245
- """
246
-
247
- return f"""
248
- <div id="{accordion_id}">
249
- {items_html}
250
- </div>
251
-
252
- <script>
253
- function toggleAccordionItem(itemId, allowMultiple) {{
254
- const content = document.getElementById(itemId);
255
- const icon = document.getElementById(itemId + '_icon');
256
-
257
- if (!allowMultiple) {{
258
- // Close all other items in this accordion
259
- const accordion = document.getElementById('{accordion_id}');
260
- accordion.querySelectorAll('div[id^="{accordion_id}_item_"]').forEach(item => {{
261
- if (item.id !== itemId) {{
262
- item.style.display = 'none';
263
- const otherIcon = document.getElementById(item.id + '_icon');
264
- if (otherIcon) otherIcon.textContent = '▼';
265
- }}
266
- }});
267
- }}
268
-
269
- // Toggle current item
270
- if (content.style.display === 'none') {{
271
- content.style.display = 'block';
272
- icon.textContent = '▲';
273
- }} else {{
274
- content.style.display = 'none';
275
- icon.textContent = '▼';
276
- }}
277
- }}
278
- </script>
279
- """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ui/interactions.py DELETED
File without changes
ui/modern_components.py DELETED
@@ -1,1710 +0,0 @@
1
- """
2
- ui/modern_components.py - ENHANCED VERSION
3
- 🚀 Modern UI Components for ARF v3.3.9 with Complete Psychological Integration
4
- Features:
5
- 1. Design token system with CSS variables
6
- 2. All psychological features (observation gate, sequencing, historical evidence, healing intent)
7
- 3. Accessibility (ARIA labels, keyboard nav)
8
- 4. Performance optimizations
9
- 5. Dark mode support
10
- 6. Integration with arf_modern_ui.py systems
11
- """
12
-
13
- import json
14
- from datetime import datetime, timezone
15
- from typing import Dict, List, Any, Optional, Tuple
16
- import plotly.graph_objects as go
17
- import plotly.express as px
18
- import numpy as np
19
-
20
- # ===========================================
21
- # DESIGN TOKEN SYSTEM - ALIGNED WITH arf_modern_ui.py
22
- # ===========================================
23
- DESIGN_TOKENS = {
24
- "colors": {
25
- "primary": {
26
- "50": "#eff6ff",
27
- "100": "#dbeafe",
28
- "200": "#bfdbfe",
29
- "300": "#93c5fd",
30
- "400": "#60a5fa",
31
- "500": "#3b82f6", # enterprise_primary
32
- "600": "#2563eb",
33
- "700": "#1d4ed8",
34
- "800": "#1e40af",
35
- "900": "#1e3a8a"
36
- },
37
- "success": {
38
- "50": "#f0fdf4",
39
- "100": "#dcfce7",
40
- "200": "#bbf7d0",
41
- "300": "#86efac",
42
- "400": "#4ade80",
43
- "500": "#22c55e", # success
44
- "600": "#16a34a",
45
- "700": "#15803d",
46
- "800": "#166534",
47
- "900": "#14532d"
48
- },
49
- "warning": {
50
- "50": "#fffbeb",
51
- "100": "#fef3c7",
52
- "200": "#fde68a",
53
- "300": "#fcd34d",
54
- "400": "#fbbf24",
55
- "500": "#f59e0b", # warning
56
- "600": "#d97706",
57
- "700": "#b45309",
58
- "800": "#92400e",
59
- "900": "#78350f"
60
- },
61
- "danger": {
62
- "50": "#fef2f2",
63
- "100": "#fee2e2",
64
- "200": "#fecaca",
65
- "300": "#fca5a5",
66
- "400": "#f87171",
67
- "500": "#ef4444", # danger
68
- "600": "#dc2626",
69
- "700": "#b91c1c",
70
- "800": "#991b1b",
71
- "900": "#7f1d1d"
72
- },
73
- "neutral": {
74
- "50": "#f8fafc",
75
- "100": "#f1f5f9",
76
- "200": "#e2e8f0",
77
- "300": "#cbd5e1",
78
- "400": "#94a3b8",
79
- "500": "#64748b",
80
- "600": "#475569",
81
- "700": "#334155",
82
- "800": "#1e293b",
83
- "900": "#0f172a"
84
- }
85
- },
86
- "spacing": {
87
- "1": "0.25rem",
88
- "2": "0.5rem",
89
- "3": "0.75rem",
90
- "4": "1rem",
91
- "5": "1.25rem",
92
- "6": "1.5rem",
93
- "8": "2rem",
94
- "10": "2.5rem",
95
- "12": "3rem",
96
- "16": "4rem",
97
- "20": "5rem"
98
- },
99
- "typography": {
100
- "fontSizes": {
101
- "xs": "0.75rem",
102
- "sm": "0.875rem",
103
- "base": "1rem",
104
- "lg": "1.125rem",
105
- "xl": "1.25rem",
106
- "2xl": "1.5rem",
107
- "3xl": "1.875rem",
108
- "4xl": "2.25rem"
109
- },
110
- "fontWeights": {
111
- "light": "300",
112
- "normal": "400",
113
- "medium": "500",
114
- "semibold": "600",
115
- "bold": "700",
116
- "extrabold": "800"
117
- }
118
- },
119
- "breakpoints": {
120
- "sm": "640px",
121
- "md": "768px",
122
- "lg": "1024px",
123
- "xl": "1280px",
124
- "2xl": "1536px"
125
- },
126
- "shadows": {
127
- "sm": "0 1px 2px 0 rgb(0 0 0 / 0.05)",
128
- "md": "0 4px 6px -1px rgb(0 0 0 / 0.1)",
129
- "lg": "0 10px 15px -3px rgb(0 0 0 / 0.1)",
130
- "xl": "0 20px 25px -5px rgb(0 0 0 / 0.1)"
131
- },
132
- "borderRadius": {
133
- "sm": "0.25rem",
134
- "md": "0.375rem",
135
- "lg": "0.5rem",
136
- "xl": "0.75rem",
137
- "2xl": "1rem",
138
- "full": "9999px"
139
- }
140
- }
141
-
142
- # ===========================================
143
- # CSS VARIABLES INJECTION
144
- # ===========================================
145
- def inject_design_tokens() -> str:
146
- """Inject CSS variables for design tokens into the page"""
147
- css_variables = []
148
-
149
- # Convert design tokens to CSS variables
150
- for category, values in DESIGN_TOKENS.items():
151
- if isinstance(values, dict):
152
- for key, value in values.items():
153
- if isinstance(value, dict):
154
- for subkey, subvalue in value.items():
155
- css_variables.append(f"--{category}-{key}-{subkey}: {subvalue};")
156
- else:
157
- css_variables.append(f"--{category}-{key}: {value};")
158
-
159
- return f"""
160
- <style id="design-tokens">
161
- :root {{
162
- {chr(10).join(css_variables)}
163
-
164
- /* Semantic aliases matching arf_modern_ui.py */
165
- --color-enterprise-primary: var(--colors-primary-500);
166
- --color-success: var(--colors-success-500);
167
- --color-warning: var(--colors-warning-500);
168
- --color-danger: var(--colors-danger-500);
169
- --color-oss-primary: var(--colors-success-500);
170
- --color-surface-light: #ffffff;
171
- --color-surface-dark: var(--colors-neutral-800);
172
- --color-background-light: var(--colors-neutral-50);
173
- --color-background-dark: var(--colors-neutral-900);
174
-
175
- /* Spacing aliases */
176
- --spacing-xs: var(--spacing-2);
177
- --spacing-sm: var(--spacing-3);
178
- --spacing-md: var(--spacing-4);
179
- --spacing-lg: var(--spacing-6);
180
- --spacing-xl: var(--spacing-8);
181
-
182
- /* Font families */
183
- --font-sans: system-ui, -apple-system, sans-serif;
184
- --font-mono: 'JetBrains Mono', 'SF Mono', Monaco, 'Cascadia Code', monospace;
185
-
186
- /* Transitions matching arf_modern_ui.py */
187
- --transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
188
- --transition-normal: 300ms cubic-bezier(0.4, 0, 0.2, 1);
189
- --transition-slow: 500ms cubic-bezier(0.4, 0, 0.2, 1);
190
- }}
191
-
192
- /* Dark mode overrides */
193
- [data-theme="dark"] {{
194
- --colors-neutral-50: #0f172a;
195
- --colors-neutral-100: #1e293b;
196
- --colors-neutral-200: #334155;
197
- --colors-neutral-300: #475569;
198
- --colors-neutral-400: #64748b;
199
- --colors-neutral-500: #94a3b8;
200
- --colors-neutral-600: #cbd5e1;
201
- --colors-neutral-700: #e2e8f0;
202
- --colors-neutral-800: #f1f5f9;
203
- --colors-neutral-900: #f8fafc;
204
- }}
205
-
206
- /* Utility classes */
207
- .sr-only {{
208
- position: absolute;
209
- width: 1px;
210
- height: 1px;
211
- padding: 0;
212
- margin: -1px;
213
- overflow: hidden;
214
- clip: rect(0, 0, 0, 0);
215
- white-space: nowrap;
216
- border: 0;
217
- }}
218
-
219
- .focus-ring {{
220
- outline: 2px solid var(--color-enterprise-primary);
221
- outline-offset: 2px;
222
- }}
223
-
224
- .focus-ring:focus:not(:focus-visible) {{
225
- outline: none;
226
- }}
227
-
228
- @media (prefers-reduced-motion: reduce) {{
229
- *,
230
- *::before,
231
- *::after {{
232
- animation-duration: 0.01ms !important;
233
- animation-iteration-count: 1 !important;
234
- transition-duration: 0.01ms !important;
235
- }}
236
- }}
237
- </style>
238
- """
239
-
240
- # ===========================================
241
- # BASE COMPONENT CLASS
242
- # ===========================================
243
- class ModernComponent:
244
- """Base class for all modern components with consistent styling"""
245
-
246
- def __init__(self):
247
- self.component_id = f"component_{datetime.now().timestamp()}"
248
-
249
- @staticmethod
250
- def create_container(children: str, **kwargs) -> str:
251
- """Create a responsive container"""
252
- classes = kwargs.get('classes', '')
253
- style = kwargs.get('style', '')
254
-
255
- return f"""
256
- <div class="container {classes}" style="{style}">
257
- {children}
258
- </div>
259
- """
260
-
261
- @staticmethod
262
- def create_section(title: str = "", children: str = "", **kwargs) -> str:
263
- """Create a semantic section with optional title"""
264
- section_id = kwargs.get('id', '')
265
- aria_label = kwargs.get('aria_label', title)
266
-
267
- title_html = f'<h2 class="section-title">{title}</h2>' if title else ''
268
-
269
- return f"""
270
- <section id="{section_id}" class="section" aria-label="{aria_label}">
271
- {title_html}
272
- <div class="section-content">
273
- {children}
274
- </div>
275
- </section>
276
- """
277
-
278
- # ===========================================
279
- # ATOMIC COMPONENTS
280
- # ===========================================
281
- class Card(ModernComponent):
282
- """Card component with multiple variants"""
283
-
284
- @staticmethod
285
- def create(content: str, **kwargs) -> str:
286
- """Create a card with optional header and footer"""
287
- title = kwargs.get('title', '')
288
- footer = kwargs.get('footer', '')
289
- variant = kwargs.get('variant', 'default') # default, elevated, outlined, filled
290
- border_color = kwargs.get('border_color', 'var(--colors-neutral-200)')
291
-
292
- variant_classes = {
293
- 'default': 'card-default',
294
- 'elevated': 'card-elevated',
295
- 'outlined': 'card-outlined',
296
- 'filled': 'card-filled'
297
- }
298
-
299
- header_html = f"""
300
- <div class="card-header">
301
- <h3 class="card-title">{title}</h3>
302
- </div>
303
- """ if title else ''
304
-
305
- footer_html = f"""
306
- <div class="card-footer">
307
- {footer}
308
- </div>
309
- """ if footer else ''
310
-
311
- return f"""
312
- <div class="card {variant_classes.get(variant, 'card-default')}"
313
- style="--border-color: {border_color};">
314
- {header_html}
315
- <div class="card-body">
316
- {content}
317
- </div>
318
- {footer_html}
319
- </div>
320
- """
321
-
322
- @staticmethod
323
- def create_metric(value: str, label: str, **kwargs) -> str:
324
- """Create a metric card for KPIs"""
325
- trend = kwargs.get('trend', None) # 'up', 'down', 'neutral'
326
- change = kwargs.get('change', '')
327
-
328
- trend_icon = {
329
- 'up': '↗',
330
- 'down': '↘',
331
- 'neutral': '→'
332
- }.get(trend, '')
333
-
334
- trend_color = {
335
- 'up': 'var(--color-success)',
336
- 'down': 'var(--color-danger)',
337
- 'neutral': 'var(--colors-neutral-500)'
338
- }.get(trend, 'var(--colors-neutral-500)')
339
-
340
- return f"""
341
- <div class="card card-metric" role="status" aria-label="{label}: {value}">
342
- <div class="metric-value" aria-live="polite">{value}</div>
343
- <div class="metric-label">{label}</div>
344
- {f'<div class="metric-trend" style="color: {trend_color};">{trend_icon} {change}</div>' if trend else ''}
345
- </div>
346
- """
347
-
348
- # ===========================================
349
- # CRITICAL PSYCHOLOGICAL COMPONENTS
350
- # ===========================================
351
- class ObservationGate(ModernComponent):
352
- """Observation gate component showing system restraint - PSYCHOLOGICAL CORE"""
353
-
354
- @staticmethod
355
- def create(confidence: float = 65.0, **kwargs) -> str:
356
- """Create observation gate display with psychological restraint"""
357
- reason = kwargs.get('reason', 'uncertainty_too_high_for_action')
358
- frozen_until = kwargs.get('frozen_until', '')
359
-
360
- threshold = 70.0
361
- is_blocked = confidence < threshold
362
-
363
- # Format countdown if available
364
- countdown_html = ""
365
- if frozen_until:
366
- try:
367
- frozen_dt = datetime.fromisoformat(frozen_until.replace("Z", "+00:00"))
368
- now = datetime.now(timezone.utc)
369
- if frozen_dt.tzinfo is None:
370
- frozen_dt = frozen_dt.replace(tzinfo=timezone.utc)
371
- time_left = frozen_dt - now
372
- minutes_left = max(0, int(time_left.total_seconds() / 60))
373
- countdown_html = f"""
374
- <div class="countdown">
375
- <div class="countdown-label">Next evaluation:</div>
376
- <div class="countdown-timer">{minutes_left}:00</div>
377
- </div>
378
- """
379
- except:
380
- countdown_html = """
381
- <div class="countdown">
382
- <div class="countdown-label">Next evaluation:</div>
383
- <div class="countdown-timer">5:00</div>
384
- </div>
385
- """
386
-
387
- status_text = "Observation Gate: Awaiting confirmation" if is_blocked else "Observation Gate Cleared"
388
- status_color = "var(--color-warning)" if is_blocked else "var(--color-success)"
389
- icon = "⏳" if is_blocked else "✅"
390
-
391
- # Psychological messaging
392
- restraint_message = """
393
- <div class="psych-message">
394
- <h4>Decision Intentionally Deferred</h4>
395
- <p>The system has detected uncertainty (<strong>{confidence:.1f}% confidence</strong>)
396
- and has <strong>chosen to observe</strong> rather than act. Historical evidence indicates
397
- premature action increases risk by <strong>47%</strong>, so the system is enforcing an observation-first policy.</p>
398
- <p class="psych-note"><em>"What you are seeing is not waiting. It is judgment under uncertainty."</em></p>
399
- </div>
400
- """ if is_blocked else """
401
- <div class="psych-message">
402
- <h4>Proceed with Policy Action</h4>
403
- <p>Confidence exceeds threshold. System may proceed with sequenced actions.
404
- Historical evidence will be consulted before any execution.</p>
405
- </div>
406
- """
407
-
408
- return f"""
409
- <div class="observation-gate" style="--status-color: {status_color};">
410
- <div class="observation-gate-header">
411
- <div class="observation-icon">{icon}</div>
412
- <div class="observation-title">
413
- <h3>{status_text}</h3>
414
- <p>System restraint engaged</p>
415
- </div>
416
- <div class="observation-badge">
417
- ACTIVE RESTRAINT
418
- </div>
419
- </div>
420
-
421
- <div class="observation-content">
422
- {restraint_message}
423
-
424
- <div class="confidence-comparison">
425
- <div class="confidence-item">
426
- <div class="confidence-label">Confidence Threshold</div>
427
- <div class="confidence-value">{threshold}%</div>
428
- <div class="confidence-note">Required for action</div>
429
- </div>
430
-
431
- <div class="confidence-item">
432
- <div class="confidence-label">Current Confidence</div>
433
- <div class="confidence-value" style="color: {status_color};">{confidence:.1f}%</div>
434
- <div class="confidence-note">{"Below threshold → Observe" if is_blocked else "Above threshold → Proceed"}</div>
435
- </div>
436
- </div>
437
-
438
- <div class="confidence-visualization">
439
- <div class="confidence-scale">
440
- <div class="scale-marker" style="left: {confidence}%;"></div>
441
- <div class="scale-bar" style="width: {confidence}%; background: {status_color};"></div>
442
- </div>
443
- <div class="scale-labels">
444
- <span>{"Observe" if is_blocked else "Ready"} ({confidence:.1f}%)</span>
445
- <span>Threshold ({threshold}%)</span>
446
- <span>{"Act" if is_blocked else "Proceed"} (75%+)</span>
447
- </div>
448
- </div>
449
-
450
- {countdown_html}
451
-
452
- <div class="prevented-actions">
453
- <h5>Prevented Actions (Contraindicated)</h5>
454
- <div class="action-tags">
455
- <span class="action-tag">scale_during_retry_storm</span>
456
- <span class="action-tag">add_capacity_during_amplification</span>
457
- <span class="action-tag">any_action_during_high_uncertainty</span>
458
- </div>
459
- </div>
460
- </div>
461
- </div>
462
- """
463
-
464
- class SequencingFlow(ModernComponent):
465
- """Visualization of policy-enforced sequencing - PSYCHOLOGICAL CORE"""
466
-
467
- @staticmethod
468
- def create(steps: List[Dict[str, Any]] = None, **kwargs) -> str:
469
- """Create sequencing flow visualization"""
470
- if steps is None:
471
- steps = [
472
- {"title": "Dampening", "description": "Prevent amplification first", "badge": "REQUIRED"},
473
- {"title": "Concurrency", "description": "Manage load, then observe", "badge": "REQUIRED"},
474
- {"title": "Observe", "description": "Validate trends for 5+ minutes", "badge": "REQUIRED"},
475
- {"title": "Scale", "description": "Only if all previous succeed", "badge": "OPTIONAL"}
476
- ]
477
-
478
- current_step = kwargs.get('current_step', 0)
479
-
480
- steps_html = []
481
- for i, step in enumerate(steps):
482
- is_current = i == current_step
483
- is_completed = i < current_step
484
- is_future = i > current_step
485
-
486
- status_class = 'completed' if is_completed else 'current' if is_current else 'future'
487
-
488
- steps_html.append(f"""
489
- <div class="sequencing-step {status_class}" data-step="{i}">
490
- <div class="step-number">{i + 1}</div>
491
- <div class="step-content">
492
- <div class="step-title">{step.get('title', 'Step')}</div>
493
- <div class="step-description">{step.get('description', '')}</div>
494
- <div class="step-badge">{step.get('badge', 'REQUIRED')}</div>
495
- </div>
496
- </div>
497
- """)
498
-
499
- # Add connecting lines
500
- connectors_html = '<div class="step-connectors">'
501
- for i in range(len(steps) - 1):
502
- is_completed = i < current_step
503
- connector_class = 'completed' if is_completed else ''
504
- connectors_html += f'<div class="step-connector {connector_class}"></div>'
505
- connectors_html += '</div>'
506
-
507
- return f"""
508
- <div class="sequencing-flow">
509
- <div class="sequencing-header">
510
- <h3>🔄 Doctrinal Sequencing: Policy Over Reaction</h3>
511
- <p>System enforces sequencing regardless of prediction confidence</p>
512
- <div class="policy-badge">POLICY ENFORCED</div>
513
- </div>
514
-
515
- <div class="sequencing-steps">
516
- {connectors_html}
517
- {''.join(steps_html)}
518
- </div>
519
-
520
- <div class="sequencing-constraint">
521
- <div class="constraint-icon">🎯</div>
522
- <div class="constraint-content">
523
- <h4>Doctrinal Constraint: Scaling Cannot Appear First</h4>
524
- <p>If retry amplification is detected, scaling is <strong>contraindicated entirely</strong>.
525
- The system must observe stabilization before considering capacity increases.
526
- Historical evidence shows scaling-first fails <strong>76%</strong> of the time during amplification.</p>
527
- <p class="psych-note"><em>"What happened is more important than what might happen."</em></p>
528
- </div>
529
- </div>
530
- </div>
531
- """
532
-
533
- class ProcessDisplay(ModernComponent):
534
- """Display for ARF processes (Detection, Recall, Decision) - PSYCHOLOGICAL CORE"""
535
-
536
- @staticmethod
537
- def create(process_type: str, data: Dict[str, Any]) -> str:
538
- """Create process display card"""
539
- icons = {
540
- 'detection': '🕵️‍♂️',
541
- 'recall': '🧠',
542
- 'decision': '🎯',
543
- 'safety': '🛡️',
544
- 'execution': '⚡',
545
- 'learning': '📚'
546
- }
547
-
548
- status_colors = {
549
- 'active': 'var(--color-success)',
550
- 'inactive': 'var(--colors-neutral-400)',
551
- 'error': 'var(--color-danger)'
552
- }
553
-
554
- icon = icons.get(process_type, '📊')
555
- status = data.get('status', 'inactive')
556
- title = data.get('title', process_type.title())
557
- description = data.get('description', '')
558
-
559
- # Metrics display
560
- metrics_html = ""
561
- if 'metrics' in data:
562
- metrics = data['metrics']
563
- metrics_html = '<div class="process-metrics">'
564
- for key, value in metrics.items():
565
- metrics_html += f"""
566
- <div class="process-metric">
567
- <div class="metric-key">{key}</div>
568
- <div class="metric-value">{value}</div>
569
- </div>
570
- """
571
- metrics_html += '</div>'
572
-
573
- # Next step
574
- next_step_html = ""
575
- if 'next_step' in data:
576
- next_step_html = f"""
577
- <div class="process-next-step">
578
- <div class="next-step-label">Next Step:</div>
579
- <div class="next-step-value">{data['next_step']}</div>
580
- </div>
581
- """
582
-
583
- # Content with psychological emphasis
584
- content_html = data.get('content', '')
585
- if process_type == 'recall' and 'historical_evidence' in data:
586
- content_html += f"""
587
- <div class="psych-emphasis">
588
- <div class="emphasis-icon">🧠</div>
589
- <div class="emphasis-content">
590
- <strong>Recall Dominance:</strong> Historical evidence outweighs predictive confidence.
591
- The system prioritizes what <em>has happened</em> over what <em>might happen</em>.
592
- </div>
593
- </div>
594
- """
595
-
596
- return f"""
597
- <div class="process-card" data-process="{process_type}" data-status="{status}">
598
- <div class="process-header">
599
- <div class="process-icon">{icon}</div>
600
- <div class="process-title">
601
- <h4>{title}</h4>
602
- <p>{description}</p>
603
- </div>
604
- <div class="process-status" style="--status-color: {status_colors.get(status, 'var(--colors-neutral-400)')};">
605
- STATUS: {status.upper()}
606
- </div>
607
- </div>
608
-
609
- <div class="process-body">
610
- {metrics_html}
611
- {content_html}
612
- {next_step_html}
613
- </div>
614
- </div>
615
- """
616
-
617
- class HistoricalEvidencePanel(ModernComponent):
618
- """Historical evidence panel - PSYCHOLOGICAL CORE (Recall Dominance)"""
619
-
620
- @staticmethod
621
- def create(evidence_data: Dict[str, Any] = None, **kwargs) -> str:
622
- """Create historical evidence panel showing recall dominance"""
623
- if evidence_data is None:
624
- evidence_data = {
625
- "scaling_failures": [
626
- {
627
- "date": "2024-11-15",
628
- "environment": "prod-east",
629
- "action": "Scale during retry storm",
630
- "outcome": "Amplification increased 300%",
631
- "lesson": "Scaling during amplification worsens the problem"
632
- },
633
- {
634
- "date": "2024-09-22",
635
- "environment": "staging",
636
- "action": "Add capacity without dampening",
637
- "outcome": "45 min outage, $8.2K loss",
638
- "lesson": "New capacity consumed by amplification loop"
639
- }
640
- ],
641
- "dampening_successes": [
642
- {
643
- "date": "2024-12-03",
644
- "environment": "prod-west",
645
- "action": "Request coalescing + backoff",
646
- "outcome": "Resolved in 8 min, $5.1K saved",
647
- "lesson": "Dampening broke amplification cycle"
648
- },
649
- {
650
- "date": "2024-10-17",
651
- "environment": "prod-eu",
652
- "action": "Circuit breaker + observability",
653
- "outcome": "12 min recovery, 0 user impact",
654
- "lesson": "Sequencing prevented escalation"
655
- }
656
- ]
657
- }
658
-
659
- # Build failures HTML
660
- failures_html = ""
661
- for i, failure in enumerate(evidence_data.get('scaling_failures', [])[:3]):
662
- failures_html += f"""
663
- <div class="evidence-item evidence-failure">
664
- <div class="evidence-header">
665
- <div class="evidence-date">{failure.get('date', 'Unknown')} • {failure.get('environment', 'Unknown')}</div>
666
- <div class="evidence-badge failure">FAILED</div>
667
- </div>
668
- <div class="evidence-content">
669
- <div class="evidence-action"><strong>Action:</strong> {failure.get('action', 'Unknown')}</div>
670
- <div class="evidence-outcome"><strong>Outcome:</strong> {failure.get('outcome', 'Unknown')}</div>
671
- <div class="evidence-lesson">"{failure.get('lesson', 'No lesson captured')}"</div>
672
- </div>
673
- </div>
674
- """
675
-
676
- # Build successes HTML
677
- successes_html = ""
678
- for i, success in enumerate(evidence_data.get('dampening_successes', [])[:3]):
679
- successes_html += f"""
680
- <div class="evidence-item evidence-success">
681
- <div class="evidence-header">
682
- <div class="evidence-date">{success.get('date', 'Unknown')} • {success.get('environment', 'Unknown')}</div>
683
- <div class="evidence-badge success">SUCCESS</div>
684
- </div>
685
- <div class="evidence-content">
686
- <div class="evidence-action"><strong>Action:</strong> {success.get('action', 'Unknown')}</div>
687
- <div class="evidence-outcome"><strong>Outcome:</strong> {success.get('outcome', 'Unknown')}</div>
688
- <div class="evidence-lesson">"{success.get('lesson', 'No lesson captured')}"</div>
689
- </div>
690
- </div>
691
- """
692
-
693
- return f"""
694
- <div class="historical-evidence-panel">
695
- <div class="evidence-header-main">
696
- <div>
697
- <h3>🧠 Historical Evidence (Why Sequencing Matters)</h3>
698
- <p>Real outcomes from similar incidents—this evidence dominates decision logic</p>
699
- </div>
700
- <div class="evidence-dominance-badge">
701
- Historical evidence outweighs model confidence
702
- </div>
703
- </div>
704
-
705
- <div class="evidence-comparison">
706
- <div class="evidence-column">
707
- <div class="column-header failure">
708
- <span>⛔</span> Scaling-First Failures
709
- </div>
710
- {failures_html if failures_html else '''
711
- <div class="evidence-empty">
712
- <div class="empty-icon">📊</div>
713
- <div class="empty-text">Scaling-First Failures (Evidence Present)</div>
714
- </div>
715
- '''}
716
- </div>
717
-
718
- <div class="evidence-column">
719
- <div class="column-header success">
720
- <span>✅</span> Dampening-First Successes
721
- </div>
722
- {successes_html if successes_html else '''
723
- <div class="evidence-empty">
724
- <div class="empty-icon">📊</div>
725
- <div class="empty-text">Dampening-First Successes (Evidence Present)</div>
726
- </div>
727
- '''}
728
- </div>
729
- </div>
730
-
731
- <div class="psych-principle">
732
- <div class="principle-icon">🎯</div>
733
- <div class="principle-content">
734
- <h4>If history shows failure, the system will not repeat it.</h4>
735
- <p>The system prioritizes <strong>historical evidence over predictive confidence</strong>.
736
- If scaling-first failed in similar conditions, scaling is contraindicated regardless of model confidence.</p>
737
- <p class="psych-note"><em>"What happened is more important than what might happen."</em></p>
738
- </div>
739
- </div>
740
- </div>
741
- """
742
-
743
- class HealingIntentDisplay(ModernComponent):
744
- """Formal HealingIntent display - PSYCHOLOGICAL CORE"""
745
-
746
- @staticmethod
747
- def create(healing_intent: Dict[str, Any], **kwargs) -> str:
748
- """Create formal HealingIntent display with all fields"""
749
- confidence = healing_intent.get('confidence', 0.0)
750
- primary_action = healing_intent.get('primary_action', '')
751
- sequencing_rule = healing_intent.get('sequencing_rule', '')
752
- preconditions = healing_intent.get('preconditions', [])
753
- contraindications = healing_intent.get('contraindications', [])
754
- reversibility = healing_intent.get('reversibility_statement', '')
755
- historical_evidence = healing_intent.get('historical_evidence', [])
756
-
757
- # Preconditions HTML
758
- preconditions_html = ""
759
- if preconditions:
760
- preconditions_html = "<div class='preconditions-list'>"
761
- for pre in preconditions:
762
- preconditions_html += f"<div class='precondition-item'>• {pre}</div>"
763
- preconditions_html += "</div>"
764
-
765
- # Contraindications HTML
766
- contraindications_html = ""
767
- if contraindications:
768
- contraindications_html = "<div class='contraindications-list'>"
769
- for contra in contraindications:
770
- contraindications_html += f"<div class='contraindication-item'>⛔ {contra}</div>"
771
- contraindications_html += "</div>"
772
-
773
- # Historical evidence HTML
774
- historical_html = ""
775
- if historical_evidence:
776
- historical_html = "<div class='historical-list'>"
777
- for evidence in historical_evidence:
778
- historical_html += f"<div class='historical-item'>📊 {evidence}</div>"
779
- historical_html += "</div>"
780
-
781
- return f"""
782
- <div class="healing-intent-display">
783
- <div class="intent-header">
784
- <div>
785
- <h3>📝 Formal HealingIntent Created</h3>
786
- <p>Preconditions checked, contraindications listed, reversibility guaranteed</p>
787
- </div>
788
- <div class="confidence-badge" style="--confidence-color: {'' if confidence >= 70 else 'var(--color-warning)'};">
789
- CONFIDENCE: {confidence:.1f}%
790
- </div>
791
- </div>
792
-
793
- <div class="intent-grid">
794
- <div class="intent-section">
795
- <div class="section-title">Primary Action</div>
796
- <div class="section-content primary-action">
797
- {primary_action}
798
- </div>
799
- </div>
800
-
801
- <div class="intent-section">
802
- <div class="section-title">Sequencing Rule</div>
803
- <div class="section-content sequencing-rule">
804
- {sequencing_rule}
805
- </div>
806
- </div>
807
- </div>
808
-
809
- <div class="intent-details">
810
- <div class="detail-section">
811
- <div class="detail-title">Preconditions</div>
812
- <div class="detail-content">
813
- {preconditions_html if preconditions_html else '<div class="empty-detail">No preconditions specified</div>'}
814
- </div>
815
- </div>
816
-
817
- <div class="detail-section">
818
- <div class="detail-title">Contraindications</div>
819
- <div class="detail-content">
820
- {contraindications_html if contraindications_html else '<div class="empty-detail">No contraindications</div>'}
821
- </div>
822
- </div>
823
-
824
- <div class="detail-section">
825
- <div class="detail-title">Reversibility Statement</div>
826
- <div class="detail-content reversibility">
827
- {reversibility if reversibility else '<div class="empty-detail">No reversibility statement</div>'}
828
- </div>
829
- </div>
830
- </div>
831
-
832
- {historical_html if historical_html else ''}
833
-
834
- <div class="psych-doctrine">
835
- <div class="doctrine-icon">⚖️</div>
836
- <div class="doctrine-content">
837
- <h4>Doctrinal Principle: Formal Documentation Prevents Mistakes</h4>
838
- <p>Every HealingIntent must document preconditions, contraindications, and reversibility.
839
- This formal structure ensures decisions are reviewable, reversible, and grounded in evidence.</p>
840
- </div>
841
- </div>
842
- </div>
843
- """
844
-
845
- # ===========================================
846
- # COMPONENT STYLES (CSS) - ENHANCED
847
- # ===========================================
848
- def create_component_styles() -> str:
849
- """Create all component styles with psychological enhancements"""
850
- return """
851
- <style>
852
- /* Base styles */
853
- body, .gr-box, .gr-form, .gr-panel, .gr-tab, .gr-container {
854
- background-color: var(--color-background-light) !important;
855
- color: var(--colors-neutral-900) !important;
856
- font-family: var(--font-sans);
857
- }
858
-
859
- [data-theme="dark"] body,
860
- [data-theme="dark"] .gr-box,
861
- [data-theme="dark"] .gr-form,
862
- [data-theme="dark"] .gr-panel,
863
- [data-theme="dark"] .gr-tab,
864
- [data-theme="dark"] .gr-container {
865
- background-color: var(--color-background-dark) !important;
866
- color: var(--colors-neutral-100) !important;
867
- }
868
-
869
- /* Card styles */
870
- .card {
871
- background: var(--color-surface-light);
872
- border-radius: var(--borderRadius-lg);
873
- padding: var(--spacing-6);
874
- border: 1px solid var(--border-color, var(--colors-neutral-200));
875
- transition: box-shadow var(--transition-normal);
876
- color: var(--colors-neutral-900);
877
- }
878
-
879
- [data-theme="dark"] .card {
880
- background: var(--color-surface-dark);
881
- border-color: var(--colors-neutral-700);
882
- color: var(--colors-neutral-100);
883
- }
884
-
885
- .card:hover {
886
- box-shadow: var(--shadows-md);
887
- }
888
-
889
- /* Observation gate styles */
890
- .observation-gate {
891
- border: 3px solid var(--status-color, var(--color-warning));
892
- border-radius: var(--borderRadius-xl);
893
- padding: var(--spacing-6);
894
- background: linear-gradient(135deg,
895
- color-mix(in srgb, var(--status-color, var(--color-warning)) 5%, transparent),
896
- color-mix(in srgb, var(--status-color, var(--color-warning)) 10%, transparent));
897
- margin: var(--spacing-6) 0;
898
- color: var(--colors-neutral-900);
899
- }
900
-
901
- [data-theme="dark"] .observation-gate {
902
- color: var(--colors-neutral-100);
903
- }
904
-
905
- .observation-gate-header {
906
- display: flex;
907
- align-items: center;
908
- gap: var(--spacing-4);
909
- margin-bottom: var(--spacing-4);
910
- }
911
-
912
- .observation-icon {
913
- font-size: 48px;
914
- color: var(--status-color, var(--color-warning));
915
- }
916
-
917
- .observation-title h3 {
918
- margin: 0;
919
- color: color-mix(in srgb, var(--status-color, var(--color-warning)) 90%, var(--colors-neutral-900));
920
- font-size: var(--typography-fontSizes-2xl);
921
- font-weight: var(--typography-fontWeights-bold);
922
- }
923
-
924
- .observation-title p {
925
- margin: var(--spacing-1) 0 0 0;
926
- color: color-mix(in srgb, var(--status-color, var(--color-warning)) 70%, var(--colors-neutral-700));
927
- }
928
-
929
- .observation-badge {
930
- margin-left: auto;
931
- padding: var(--spacing-2) var(--spacing-4);
932
- background: var(--status-color, var(--color-warning));
933
- color: white;
934
- border-radius: var(--borderRadius-full);
935
- font-size: var(--typography-fontSizes-xs);
936
- font-weight: var(--typography-fontWeights-bold);
937
- text-transform: uppercase;
938
- letter-spacing: 1px;
939
- }
940
-
941
- .psych-message {
942
- background: white;
943
- border: 2px solid var(--status-color, var(--color-warning));
944
- padding: var(--spacing-4);
945
- margin: var(--spacing-4) 0;
946
- border-radius: var(--borderRadius-lg);
947
- }
948
-
949
- [data-theme="dark"] .psych-message {
950
- background: var(--colors-neutral-800);
951
- }
952
-
953
- .psych-message h4 {
954
- margin: 0 0 var(--spacing-2) 0;
955
- color: var(--colors-neutral-900);
956
- font-size: var(--typography-fontSizes-lg);
957
- }
958
-
959
- .psych-message p {
960
- margin: var(--spacing-2) 0;
961
- color: var(--colors-neutral-700);
962
- line-height: 1.6;
963
- }
964
-
965
- .psych-note {
966
- font-style: italic;
967
- color: var(--colors-neutral-600);
968
- margin-top: var(--spacing-2);
969
- border-left: 3px solid var(--status-color, var(--color-warning));
970
- padding-left: var(--spacing-3);
971
- }
972
-
973
- .confidence-comparison {
974
- display: grid;
975
- grid-template-columns: 1fr 1fr;
976
- gap: var(--spacing-4);
977
- margin: var(--spacing-4) 0;
978
- }
979
-
980
- .confidence-item {
981
- background: var(--color-surface-light);
982
- border-radius: var(--borderRadius-lg);
983
- padding: var(--spacing-4);
984
- text-align: center;
985
- border: 1px solid var(--colors-neutral-200);
986
- }
987
-
988
- [data-theme="dark"] .confidence-item {
989
- background: var(--colors-neutral-800);
990
- border-color: var(--colors-neutral-700);
991
- }
992
-
993
- .confidence-label {
994
- font-size: var(--typography-fontSizes-sm);
995
- color: var(--colors-neutral-600);
996
- text-transform: uppercase;
997
- letter-spacing: 0.05em;
998
- margin-bottom: var(--spacing-2);
999
- }
1000
-
1001
- .confidence-value {
1002
- font-size: var(--typography-fontSizes-3xl);
1003
- font-weight: var(--typography-fontWeights-bold);
1004
- margin-bottom: var(--spacing-1);
1005
- }
1006
-
1007
- .confidence-note {
1008
- font-size: var(--typography-fontSizes-xs);
1009
- color: var(--colors-neutral-500);
1010
- }
1011
-
1012
- .confidence-visualization {
1013
- margin: var(--spacing-6) 0;
1014
- }
1015
-
1016
- .confidence-scale {
1017
- height: 8px;
1018
- background: var(--colors-neutral-200);
1019
- border-radius: var(--borderRadius-full);
1020
- position: relative;
1021
- margin: var(--spacing-4) 0 var(--spacing-2);
1022
- }
1023
-
1024
- .scale-bar {
1025
- height: 100%;
1026
- border-radius: var(--borderRadius-full);
1027
- transition: width var(--transition-normal);
1028
- }
1029
-
1030
- .scale-marker {
1031
- position: absolute;
1032
- top: -4px;
1033
- width: 16px;
1034
- height: 16px;
1035
- background: white;
1036
- border: 2px solid var(--colors-neutral-900);
1037
- border-radius: 50%;
1038
- transform: translateX(-50%);
1039
- }
1040
-
1041
- .scale-labels {
1042
- display: flex;
1043
- justify-content: space-between;
1044
- font-size: var(--typography-fontSizes-xs);
1045
- color: var(--colors-neutral-600);
1046
- }
1047
-
1048
- .prevented-actions {
1049
- margin-top: var(--spacing-6);
1050
- padding-top: var(--spacing-4);
1051
- border-top: 2px solid var(--colors-neutral-200);
1052
- }
1053
-
1054
- .prevented-actions h5 {
1055
- margin: 0 0 var(--spacing-3) 0;
1056
- color: var(--colors-neutral-700);
1057
- font-size: var(--typography-fontSizes-sm);
1058
- text-transform: uppercase;
1059
- letter-spacing: 0.05em;
1060
- }
1061
-
1062
- .action-tags {
1063
- display: flex;
1064
- flex-wrap: wrap;
1065
- gap: var(--spacing-2);
1066
- }
1067
-
1068
- .action-tag {
1069
- padding: var(--spacing-1) var(--spacing-3);
1070
- background: var(--color-danger);
1071
- color: white;
1072
- border-radius: var(--borderRadius-full);
1073
- font-size: var(--typography-fontSizes-xs);
1074
- font-weight: var(--typography-fontWeights-medium);
1075
- }
1076
-
1077
- /* Sequencing flow styles */
1078
- .sequencing-flow {
1079
- background: var(--color-surface-light);
1080
- border: 2px solid var(--color-enterprise-primary);
1081
- border-radius: var(--borderRadius-xl);
1082
- padding: var(--spacing-6);
1083
- margin: var(--spacing-6) 0;
1084
- }
1085
-
1086
- [data-theme="dark"] .sequencing-flow {
1087
- background: var(--colors-neutral-800);
1088
- }
1089
-
1090
- .sequencing-header {
1091
- margin-bottom: var(--spacing-6);
1092
- text-align: center;
1093
- }
1094
-
1095
- .sequencing-header h3 {
1096
- margin: 0 0 var(--spacing-2) 0;
1097
- color: var(--colors-neutral-900);
1098
- font-size: var(--typography-fontSizes-xl);
1099
- }
1100
-
1101
- .sequencing-header p {
1102
- margin: 0;
1103
- color: var(--colors-neutral-600);
1104
- }
1105
-
1106
- .policy-badge {
1107
- display: inline-block;
1108
- margin-top: var(--spacing-3);
1109
- padding: var(--spacing-2) var(--spacing-4);
1110
- background: var(--color-enterprise-primary);
1111
- color: white;
1112
- border-radius: var(--borderRadius-full);
1113
- font-size: var(--typography-fontSizes-xs);
1114
- font-weight: var(--typography-fontWeights-bold);
1115
- text-transform: uppercase;
1116
- letter-spacing: 1px;
1117
- }
1118
-
1119
- .sequencing-steps {
1120
- display: flex;
1121
- justify-content: space-between;
1122
- align-items: center;
1123
- position: relative;
1124
- margin: var(--spacing-8) 0;
1125
- }
1126
-
1127
- .step-connectors {
1128
- position: absolute;
1129
- top: 30px;
1130
- left: 60px;
1131
- right: 60px;
1132
- display: flex;
1133
- justify-content: space-between;
1134
- z-index: 1;
1135
- }
1136
-
1137
- .step-connector {
1138
- flex: 1;
1139
- height: 3px;
1140
- background: var(--colors-neutral-300);
1141
- margin: 0 var(--spacing-2);
1142
- }
1143
-
1144
- .step-connector.completed {
1145
- background: linear-gradient(90deg, var(--color-enterprise-primary), var(--color-success));
1146
- }
1147
-
1148
- .sequencing-step {
1149
- text-align: center;
1150
- position: relative;
1151
- z-index: 2;
1152
- flex: 1;
1153
- }
1154
-
1155
- .step-number {
1156
- width: 60px;
1157
- height: 60px;
1158
- background: var(--colors-neutral-100);
1159
- color: var(--colors-neutral-700);
1160
- border-radius: 50%;
1161
- display: flex;
1162
- align-items: center;
1163
- justify-content: center;
1164
- margin: 0 auto var(--spacing-3);
1165
- font-size: var(--typography-fontSizes-xl);
1166
- font-weight: var(--typography-fontWeights-bold);
1167
- border: 4px solid white;
1168
- transition: all var(--transition-normal);
1169
- }
1170
-
1171
- .sequencing-step.current .step-number {
1172
- background: var(--color-enterprise-primary);
1173
- color: white;
1174
- box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
1175
- }
1176
-
1177
- .sequencing-step.completed .step-number {
1178
- background: var(--color-success);
1179
- color: white;
1180
- }
1181
-
1182
- .step-title {
1183
- font-size: var(--typography-fontSizes-base);
1184
- font-weight: var(--typography-fontWeights-bold);
1185
- color: var(--colors-neutral-900);
1186
- margin-bottom: var(--spacing-1);
1187
- }
1188
-
1189
- .step-description {
1190
- font-size: var(--typography-fontSizes-sm);
1191
- color: var(--colors-neutral-600);
1192
- margin-bottom: var(--spacing-2);
1193
- max-width: 180px;
1194
- margin: 0 auto;
1195
- }
1196
-
1197
- .step-badge {
1198
- display: inline-block;
1199
- padding: var(--spacing-1) var(--spacing-3);
1200
- background: var(--colors-neutral-100);
1201
- color: var(--colors-neutral-700);
1202
- border-radius: var(--borderRadius-full);
1203
- font-size: var(--typography-fontSizes-xs);
1204
- font-weight: var(--typography-fontWeights-bold);
1205
- margin-top: var(--spacing-2);
1206
- }
1207
-
1208
- .sequencing-step.current .step-badge {
1209
- background: var(--color-enterprise-primary);
1210
- color: white;
1211
- }
1212
-
1213
- .sequencing-constraint {
1214
- background: var(--colors-neutral-50);
1215
- border-radius: var(--borderRadius-lg);
1216
- padding: var(--spacing-4);
1217
- border-left: 4px solid var(--color-enterprise-primary);
1218
- margin-top: var(--spacing-6);
1219
- }
1220
-
1221
- [data-theme="dark"] .sequencing-constraint {
1222
- background: var(--colors-neutral-800);
1223
- }
1224
-
1225
- .constraint-icon {
1226
- font-size: 24px;
1227
- color: var(--color-enterprise-primary);
1228
- margin-bottom: var(--spacing-2);
1229
- }
1230
-
1231
- .constraint-content h4 {
1232
- margin: 0 0 var(--spacing-2) 0;
1233
- color: var(--colors-neutral-900);
1234
- font-size: var(--typography-fontSizes-lg);
1235
- }
1236
-
1237
- .constraint-content p {
1238
- margin: 0;
1239
- color: var(--colors-neutral-700);
1240
- line-height: 1.6;
1241
- }
1242
-
1243
- /* Historical evidence panel styles */
1244
- .historical-evidence-panel {
1245
- border: 3px solid var(--color-enterprise-primary);
1246
- border-radius: var(--borderRadius-xl);
1247
- padding: var(--spacing-6);
1248
- margin: var(--spacing-6) 0;
1249
- background: var(--color-surface-light);
1250
- }
1251
-
1252
- [data-theme="dark"] .historical-evidence-panel {
1253
- background: var(--colors-neutral-800);
1254
- }
1255
-
1256
- .evidence-header-main {
1257
- display: flex;
1258
- justify-content: space-between;
1259
- align-items: center;
1260
- margin-bottom: var(--spacing-6);
1261
- }
1262
-
1263
- .evidence-header-main h3 {
1264
- margin: 0 0 var(--spacing-2) 0;
1265
- color: var(--colors-neutral-900);
1266
- font-size: var(--typography-fontSizes-xl);
1267
- }
1268
-
1269
- .evidence-header-main p {
1270
- margin: 0;
1271
- color: var(--colors-neutral-600);
1272
- }
1273
-
1274
- .evidence-dominance-badge {
1275
- padding: var(--spacing-2) var(--spacing-4);
1276
- background: var(--color-enterprise-primary);
1277
- color: white;
1278
- border-radius: var(--borderRadius-full);
1279
- font-size: var(--typography-fontSizes-xs);
1280
- font-weight: var(--typography-fontWeights-bold);
1281
- }
1282
-
1283
- .evidence-comparison {
1284
- display: grid;
1285
- grid-template-columns: 1fr 1fr;
1286
- gap: var(--spacing-6);
1287
- margin-bottom: var(--spacing-6);
1288
- }
1289
-
1290
- .evidence-column {
1291
- display: flex;
1292
- flex-direction: column;
1293
- gap: var(--spacing-4);
1294
- }
1295
-
1296
- .column-header {
1297
- font-size: var(--typography-fontSizes-lg);
1298
- font-weight: var(--typography-fontWeights-bold);
1299
- margin-bottom: var(--spacing-2);
1300
- display: flex;
1301
- align-items: center;
1302
- gap: var(--spacing-2);
1303
- }
1304
-
1305
- .column-header.failure {
1306
- color: var(--color-danger);
1307
- }
1308
-
1309
- .column-header.success {
1310
- color: var(--color-success);
1311
- }
1312
-
1313
- .evidence-item {
1314
- border-left: 4px solid;
1315
- padding-left: var(--spacing-4);
1316
- margin-bottom: var(--spacing-3);
1317
- }
1318
-
1319
- .evidence-failure {
1320
- border-left-color: var(--color-danger);
1321
- }
1322
-
1323
- .evidence-success {
1324
- border-left-color: var(--color-success);
1325
- }
1326
-
1327
- .evidence-header {
1328
- display: flex;
1329
- justify-content: space-between;
1330
- align-items: flex-start;
1331
- margin-bottom: var(--spacing-2);
1332
- }
1333
-
1334
- .evidence-date {
1335
- font-size: var(--typography-fontSizes-sm);
1336
- font-weight: var(--typography-fontWeights-semibold);
1337
- color: var(--colors-neutral-900);
1338
- }
1339
-
1340
- .evidence-badge {
1341
- padding: 2px 8px;
1342
- border-radius: var(--borderRadius-full);
1343
- font-size: var(--typography-fontSizes-xs);
1344
- font-weight: var(--typography-fontWeights-bold);
1345
- }
1346
-
1347
- .evidence-badge.failure {
1348
- background: var(--color-danger);
1349
- color: white;
1350
- }
1351
-
1352
- .evidence-badge.success {
1353
- background: var(--color-success);
1354
- color: white;
1355
- }
1356
-
1357
- .evidence-content {
1358
- font-size: var(--typography-fontSizes-sm);
1359
- }
1360
-
1361
- .evidence-action {
1362
- color: var(--colors-neutral-700);
1363
- margin-bottom: var(--spacing-1);
1364
- }
1365
-
1366
- .evidence-outcome {
1367
- color: var(--colors-neutral-600);
1368
- margin-bottom: var(--spacing-2);
1369
- font-weight: var(--typography-fontWeights-medium);
1370
- }
1371
-
1372
- .evidence-failure .evidence-outcome {
1373
- color: var(--color-danger);
1374
- }
1375
-
1376
- .evidence-success .evidence-outcome {
1377
- color: var(--color-success);
1378
- }
1379
-
1380
- .evidence-lesson {
1381
- font-style: italic;
1382
- color: var(--colors-neutral-500);
1383
- background: var(--colors-neutral-50);
1384
- padding: var(--spacing-2);
1385
- border-radius: var(--borderRadius-md);
1386
- font-size: var(--typography-fontSizes-xs);
1387
- }
1388
-
1389
- [data-theme="dark"] .evidence-lesson {
1390
- background: var(--colors-neutral-700);
1391
- }
1392
-
1393
- .psych-principle {
1394
- background: linear-gradient(135deg, var(--colors-primary-50), var(--colors-neutral-50));
1395
- border-radius: var(--borderRadius-lg);
1396
- padding: var(--spacing-4);
1397
- border: 2px solid var(--colors-primary-300);
1398
- margin-top: var(--spacing-6);
1399
- }
1400
-
1401
- [data-theme="dark"] .psych-principle {
1402
- background: linear-gradient(135deg, var(--colors-primary-900), var(--colors-neutral-800));
1403
- border-color: var(--colors-primary-700);
1404
- }
1405
-
1406
- .principle-icon {
1407
- font-size: 28px;
1408
- color: var(--color-enterprise-primary);
1409
- margin-bottom: var(--spacing-2);
1410
- }
1411
-
1412
- .principle-content h4 {
1413
- margin: 0 0 var(--spacing-2) 0;
1414
- color: var(--colors-neutral-900);
1415
- font-size: var(--typography-fontSizes-lg);
1416
- }
1417
-
1418
- .principle-content p {
1419
- margin: 0;
1420
- color: var(--colors-neutral-700);
1421
- line-height: 1.6;
1422
- }
1423
-
1424
- /* Healing intent display styles */
1425
- .healing-intent-display {
1426
- background: var(--color-surface-light);
1427
- border: 2px solid var(--color-success);
1428
- border-radius: var(--borderRadius-xl);
1429
- padding: var(--spacing-6);
1430
- margin: var(--spacing-6) 0;
1431
- }
1432
-
1433
- [data-theme="dark"] .healing-intent-display {
1434
- background: var(--colors-neutral-800);
1435
- }
1436
-
1437
- .intent-header {
1438
- display: flex;
1439
- justify-content: space-between;
1440
- align-items: center;
1441
- margin-bottom: var(--spacing-6);
1442
- padding-bottom: var(--spacing-4);
1443
- border-bottom: 2px solid var(--colors-neutral-200);
1444
- }
1445
-
1446
- .intent-header h3 {
1447
- margin: 0 0 var(--spacing-2) 0;
1448
- color: var(--colors-neutral-900);
1449
- font-size: var(--typography-fontSizes-xl);
1450
- }
1451
-
1452
- .intent-header p {
1453
- margin: 0;
1454
- color: var(--colors-neutral-600);
1455
- }
1456
-
1457
- .confidence-badge {
1458
- padding: var(--spacing-2) var(--spacing-4);
1459
- background: var(--confidence-color, var(--color-success));
1460
- color: white;
1461
- border-radius: var(--borderRadius-full);
1462
- font-size: var(--typography-fontSizes-sm);
1463
- font-weight: var(--typography-fontWeights-bold);
1464
- text-transform: uppercase;
1465
- letter-spacing: 0.05em;
1466
- }
1467
-
1468
- .intent-grid {
1469
- display: grid;
1470
- grid-template-columns: 1fr 1fr;
1471
- gap: var(--spacing-4);
1472
- margin-bottom: var(--spacing-6);
1473
- }
1474
-
1475
- .intent-section {
1476
- background: var(--colors-neutral-50);
1477
- border-radius: var(--borderRadius-lg);
1478
- padding: var(--spacing-4);
1479
- }
1480
-
1481
- [data-theme="dark"] .intent-section {
1482
- background: var(--colors-neutral-700);
1483
- }
1484
-
1485
- .section-title {
1486
- font-size: var(--typography-fontSizes-sm);
1487
- color: var(--colors-neutral-600);
1488
- text-transform: uppercase;
1489
- letter-spacing: 0.05em;
1490
- margin-bottom: var(--spacing-2);
1491
- }
1492
-
1493
- .section-content {
1494
- font-size: var(--typography-fontSizes-base);
1495
- color: var(--colors-neutral-900);
1496
- font-weight: var(--typography-fontWeights-medium);
1497
- }
1498
-
1499
- [data-theme="dark"] .section-content {
1500
- color: var(--colors-neutral-100);
1501
- }
1502
-
1503
- .primary-action {
1504
- color: var(--color-success);
1505
- font-weight: var(--typography-fontWeights-semibold);
1506
- }
1507
-
1508
- .sequencing-rule {
1509
- color: var(--color-enterprise-primary);
1510
- font-family: var(--font-mono);
1511
- font-size: var(--typography-fontSizes-sm);
1512
- }
1513
-
1514
- .intent-details {
1515
- display: grid;
1516
- grid-template-columns: repeat(3, 1fr);
1517
- gap: var(--spacing-4);
1518
- margin-bottom: var(--spacing-6);
1519
- }
1520
-
1521
- .detail-section {
1522
- background: var(--colors-neutral-50);
1523
- border-radius: var(--borderRadius-lg);
1524
- padding: var(--spacing-4);
1525
- }
1526
-
1527
- [data-theme="dark"] .detail-section {
1528
- background: var(--colors-neutral-700);
1529
- }
1530
-
1531
- .detail-title {
1532
- font-size: var(--typography-fontSizes-sm);
1533
- color: var(--colors-neutral-600);
1534
- text-transform: uppercase;
1535
- letter-spacing: 0.05em;
1536
- margin-bottom: var(--spacing-2);
1537
- }
1538
-
1539
- .detail-content {
1540
- font-size: var(--typography-fontSizes-sm);
1541
- color: var(--colors-neutral-700);
1542
- line-height: 1.5;
1543
- }
1544
-
1545
- [data-theme="dark"] .detail-content {
1546
- color: var(--colors-neutral-300);
1547
- }
1548
-
1549
- .preconditions-list {
1550
- display: flex;
1551
- flex-direction: column;
1552
- gap: var(--spacing-1);
1553
- }
1554
-
1555
- .precondition-item {
1556
- color: var(--colors-neutral-700);
1557
- }
1558
-
1559
- .contraindications-list {
1560
- display: flex;
1561
- flex-direction: column;
1562
- gap: var(--spacing-1);
1563
- }
1564
-
1565
- .contraindication-item {
1566
- color: var(--color-danger);
1567
- font-weight: var(--typography-fontWeights-medium);
1568
- }
1569
-
1570
- .reversibility {
1571
- color: var(--color-success);
1572
- font-style: italic;
1573
- }
1574
-
1575
- .psych-doctrine {
1576
- background: linear-gradient(135deg, var(--colors-success-50), var(--colors-neutral-50));
1577
- border-radius: var(--borderRadius-lg);
1578
- padding: var(--spacing-4);
1579
- border: 2px solid var(--colors-success-300);
1580
- margin-top: var(--spacing-6);
1581
- }
1582
-
1583
- [data-theme="dark"] .psych-doctrine {
1584
- background: linear-gradient(135deg, var(--colors-success-900), var(--colors-neutral-800));
1585
- border-color: var(--colors-success-700);
1586
- }
1587
-
1588
- .doctrine-icon {
1589
- font-size: 28px;
1590
- color: var(--color-success);
1591
- margin-bottom: var(--spacing-2);
1592
- }
1593
-
1594
- .doctrine-content h4 {
1595
- margin: 0 0 var(--spacing-2) 0;
1596
- color: var(--colors-neutral-900);
1597
- font-size: var(--typography-fontSizes-lg);
1598
- }
1599
-
1600
- .doctrine-content p {
1601
- margin: 0;
1602
- color: var(--colors-neutral-700);
1603
- line-height: 1.6;
1604
- }
1605
-
1606
- /* Responsive adjustments */
1607
- @media (max-width: 768px) {
1608
- .confidence-comparison {
1609
- grid-template-columns: 1fr;
1610
- }
1611
-
1612
- .sequencing-steps {
1613
- flex-direction: column;
1614
- gap: var(--spacing-6);
1615
- }
1616
-
1617
- .step-connectors {
1618
- display: none;
1619
- }
1620
-
1621
- .evidence-comparison {
1622
- grid-template-columns: 1fr;
1623
- }
1624
-
1625
- .intent-grid {
1626
- grid-template-columns: 1fr;
1627
- }
1628
-
1629
- .intent-details {
1630
- grid-template-columns: 1fr;
1631
- }
1632
- }
1633
-
1634
- @media (max-width: 480px) {
1635
- .observation-gate-header {
1636
- flex-direction: column;
1637
- text-align: center;
1638
- gap: var(--spacing-2);
1639
- }
1640
-
1641
- .observation-badge {
1642
- margin-left: 0;
1643
- margin-top: var(--spacing-2);
1644
- }
1645
-
1646
- .card {
1647
- padding: var(--spacing-3);
1648
- }
1649
-
1650
- .sequencing-flow,
1651
- .historical-evidence-panel,
1652
- .healing-intent-display {
1653
- padding: var(--spacing-3);
1654
- }
1655
- }
1656
- </style>
1657
- """
1658
-
1659
- # ===========================================
1660
- # INITIALIZATION FUNCTION
1661
- # ===========================================
1662
- def initialize_modern_ui() -> str:
1663
- """Initialize all modern UI components and styles"""
1664
- components = [
1665
- inject_design_tokens(),
1666
- create_component_styles(),
1667
- """
1668
- <style>
1669
- /* Additional responsive utilities */
1670
- .container {
1671
- width: 100%;
1672
- max-width: 1200px;
1673
- margin: 0 auto;
1674
- padding: 0 var(--spacing-4);
1675
- }
1676
-
1677
- @media (min-width: 768px) {
1678
- .container {
1679
- padding: 0 var(--spacing-6);
1680
- }
1681
- }
1682
-
1683
- @media (min-width: 1024px) {
1684
- .container {
1685
- padding: 0 var(--spacing-8);
1686
- }
1687
- }
1688
- </style>
1689
- """
1690
- ]
1691
-
1692
- return "\n".join(components)
1693
-
1694
- # ===========================================
1695
- # EXPORT LIST
1696
- # ===========================================
1697
- __all__ = [
1698
- # Core components
1699
- 'ModernComponent', 'Card',
1700
-
1701
- # CRITICAL PSYCHOLOGICAL COMPONENTS
1702
- 'ObservationGate', 'SequencingFlow', 'ProcessDisplay',
1703
- 'HistoricalEvidencePanel', 'HealingIntentDisplay',
1704
-
1705
- # Design system
1706
- 'DESIGN_TOKENS',
1707
-
1708
- # Initialization
1709
- 'initialize_modern_ui', 'inject_design_tokens', 'create_component_styles'
1710
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ui/modern_integration.py DELETED
@@ -1,80 +0,0 @@
1
- """
2
- ui/modern_integration.py
3
- Modern UI integration for Gradio app
4
- """
5
-
6
- import gradio as gr
7
- from ui.modern_components import (
8
- initialize_modern_ui,
9
- Card, Button, Badge, Grid, Stack,
10
- ObservationGate, SequencingFlow, ProcessDisplay, Chart,
11
- ResponsiveUtils, Accessibility, DarkMode
12
- )
13
-
14
- class ModernUIIntegration:
15
- """Integrate modern UI components with Gradio"""
16
-
17
- @staticmethod
18
- def inject_css_and_js() -> str:
19
- """Inject modern UI CSS and JavaScript"""
20
- return initialize_modern_ui()
21
-
22
- @staticmethod
23
- def create_modern_layout() -> dict:
24
- """Create modern layout structure for tabs"""
25
- return {
26
- "css": ModernUIIntegration.inject_css_and_js(),
27
- "container_class": "container container-lg",
28
- "header": """
29
- <div class="app-header">
30
- <h1 class="text-3xl font-bold text-primary mb-2">
31
- 🚀 Agentic Reliability Framework v3.3.9
32
- </h1>
33
- <p class="text-muted mb-6">
34
- OSS advises → Enterprise executes | Modern UI Enabled
35
- </p>
36
- </div>
37
- """,
38
- "tab_classes": {
39
- "live_demo": "p-4 bg-gradient-to-br from-green-50 to-white dark:from-green-900/20 dark:to-gray-900",
40
- "roi": "p-4 bg-gradient-to-br from-blue-50 to-white dark:from-blue-900/20 dark:to-gray-900",
41
- "enterprise": "p-4 bg-gradient-to-br from-purple-50 to-white dark:from-purple-900/20 dark:to-gray-900",
42
- "audit": "p-4 bg-gradient-to-br from-orange-50 to-white dark:from-orange-900/20 dark:to-gray-900",
43
- "learning": "p-4 bg-gradient-to-br from-indigo-50 to-white dark:from-indigo-900/20 dark:to-gray-900"
44
- }
45
- }
46
-
47
- @staticmethod
48
- def wrap_component(component, card_config=None):
49
- """Wrap Gradio component with modern styling"""
50
- if card_config:
51
- # Create a card wrapper
52
- title = card_config.get("title", "")
53
- variant = card_config.get("variant", "default")
54
- border_color = card_config.get("border_color", "")
55
-
56
- with gr.Group(elem_classes=f"card card-{variant}"):
57
- if title:
58
- gr.Markdown(f"### {title}", elem_classes="card-title")
59
- return component
60
- return component
61
-
62
- @staticmethod
63
- def create_boundary_display(oss_content, enterprise_content):
64
- """Create OSS vs Enterprise boundary display"""
65
- with gr.Row(elem_classes="boundary-row"):
66
- with gr.Column(scale=1, elem_classes="oss-column"):
67
- with gr.Group(elem_classes="card card-outlined border-l-4 border-l-green-500"):
68
- gr.Markdown("### 🟢 OSS Advisory Layer",
69
- elem_classes="text-lg font-semibold mb-2")
70
- gr.Markdown("*Analysis & Recommendations*",
71
- elem_classes="text-sm text-muted mb-4")
72
- yield oss_content
73
-
74
- with gr.Column(scale=1, elem_classes="enterprise-column"):
75
- with gr.Group(elem_classes="card card-elevated border-l-4 border-l-purple-500"):
76
- gr.Markdown("### 🟣 Enterprise Execution Layer",
77
- elem_classes="text-lg font-semibold mb-2")
78
- gr.Markdown("*Autonomous Action & Execution*",
79
- elem_classes="text-sm text-muted mb-4")
80
- yield enterprise_content
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ui/styles.py DELETED
@@ -1,235 +0,0 @@
1
- """
2
- UI Styles for ARF Demo - LIGHT THEME FOR READABILITY
3
- """
4
- import logging
5
-
6
- logger = logging.getLogger(__name__)
7
-
8
- def get_styles() -> str:
9
- """
10
- Return CSS styles for the ARF demo - LIGHT THEME FOR READABILITY
11
- """
12
- css = """
13
- /* ARF Demo Styles - Clean Light Theme */
14
-
15
- /* Fix for all text to be readable */
16
- body, .gr-box, .gr-form, .gr-panel, .gr-tab, .gr-container {
17
- background-color: #f8fafc !important;
18
- color: #1e293b !important;
19
- }
20
-
21
- /* Make all text black/dark */
22
- h1, h2, h3, h4, h5, h6, p, span, div, label, .markdown, .gr-markdown {
23
- color: #1e293b !important;
24
- }
25
-
26
- /* Header gradient - keep but ensure text is white */
27
- .header-gradient {
28
- background: linear-gradient(135deg, #1e3a8a 0%, #3b82f6 100%) !important;
29
- border-radius: 16px;
30
- padding: 30px 40px !important;
31
- color: white !important;
32
- }
33
-
34
- .header-gradient h1,
35
- .header-gradient h2,
36
- .header-gradient h3,
37
- .header-gradient p {
38
- color: white !important;
39
- }
40
-
41
- /* Status bar */
42
- .status-bar {
43
- background: #f1f5f9 !important;
44
- border: 1px solid #e2e8f0 !important;
45
- border-radius: 12px;
46
- padding: 15px !important;
47
- }
48
-
49
- /* Cards - white background with readable text */
50
- .arf-card, .gr-box, .gr-panel {
51
- background: white !important;
52
- border: 1px solid #e2e8f0 !important;
53
- border-radius: 14px !important;
54
- color: #1e293b !important;
55
- }
56
-
57
- /* Tab navigation */
58
- .tab-nav {
59
- background: white !important;
60
- border-bottom: 2px solid #e2e8f0 !important;
61
- }
62
-
63
- .tab-nav .tab {
64
- color: #64748b !important;
65
- padding: 12px 24px !important;
66
- }
67
-
68
- .tab-nav .tab.selected {
69
- color: #3b82f6 !important;
70
- background: #f8fafc !important;
71
- border: 2px solid #e2e8f0 !important;
72
- border-bottom-color: white !important;
73
- }
74
-
75
- /* Buttons */
76
- button {
77
- border-radius: 10px !important;
78
- font-weight: 600 !important;
79
- }
80
-
81
- button.primary {
82
- background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%) !important;
83
- color: white !important;
84
- border: none !important;
85
- }
86
-
87
- button.secondary {
88
- background: white !important;
89
- border: 2px solid #e2e8f0 !important;
90
- color: #1e293b !important;
91
- }
92
-
93
- /* Form elements */
94
- .gr-dropdown, .gr-slider, .gr-textbox, .gr-checkbox, .gr-radio {
95
- background: white !important;
96
- border: 1px solid #e2e8f0 !important;
97
- color: #1e293b !important;
98
- }
99
-
100
- .gr-dropdown label, .gr-slider label, .gr-textbox label {
101
- color: #1e293b !important;
102
- font-weight: 600 !important;
103
- }
104
-
105
- /* Plots - ensure they have white background */
106
- .gr-plot, .plotly.js-plotly-plot {
107
- background: white !important;
108
- border-radius: 12px;
109
- border: 1px solid #e2e8f0;
110
- }
111
-
112
- /* JSON display */
113
- .gr-json {
114
- background: white !important;
115
- border: 1px solid #e2e8f0 !important;
116
- border-radius: 8px;
117
- color: #1e293b !important;
118
- }
119
-
120
- /* Dataframes */
121
- .gr-dataframe {
122
- background: white !important;
123
- border: 1px solid #e2e8f0 !important;
124
- border-radius: 8px;
125
- }
126
-
127
- /* Agent cards */
128
- .agent-card {
129
- background: white !important;
130
- border: 2px solid #e2e8f0 !important;
131
- border-radius: 14px;
132
- color: #1e293b !important;
133
- }
134
-
135
- .agent-card.active {
136
- border-color: #10b981 !important;
137
- background: #f0fdf4 !important;
138
- }
139
-
140
- /* Metric cards */
141
- .metric-card {
142
- background: white !important;
143
- border: 1px solid #e2e8f0 !important;
144
- border-left: 4px solid #3b82f6 !important;
145
- border-radius: 12px;
146
- color: #1e293b !important;
147
- }
148
-
149
- /* Footer */
150
- footer {
151
- background: #f1f5f9 !important;
152
- color: #64748b !important;
153
- border-top: 2px solid #e2e8f0 !important;
154
- }
155
-
156
- footer a {
157
- color: #3b82f6 !important;
158
- }
159
-
160
- /* Badges */
161
- .badge {
162
- color: white !important;
163
- font-weight: bold !important;
164
- }
165
-
166
- /* Ensure all HTML content has proper colors */
167
- .gr-html div, .gr-html span, .gr-html p, .gr-html h1, .gr-html h2, .gr-html h3, .gr-html h4 {
168
- color: #1e293b !important;
169
- }
170
-
171
- /* Fix for scenario card */
172
- .scenario-card {
173
- background: white !important;
174
- border: 1px solid #e2e8f0 !important;
175
- color: #1e293b !important;
176
- }
177
-
178
- /* Make sure all text in the workflow section is readable */
179
- #tab1 .gr-markdown,
180
- #tab1 .gr-html,
181
- #tab1 h1, #tab1 h2, #tab1 h3,
182
- #tab1 p, #tab1 span, #tab1 div {
183
- color: #1e293b !important;
184
- }
185
-
186
- /* Plot titles */
187
- .gr-plot h3, .gr-plot .plot-title {
188
- color: #1e293b !important;
189
- }
190
-
191
- /* Section headers */
192
- .section-header {
193
- color: #1e293b !important;
194
- border-bottom: 2px solid #e2e8f0 !important;
195
- }
196
-
197
- /* Fix for approval display */
198
- .approval-display {
199
- background: white !important;
200
- border: 2px solid #e2e8f0 !important;
201
- color: #1e293b !important;
202
- }
203
-
204
- /* OSS vs Enterprise sections */
205
- .oss-section, .enterprise-section {
206
- background: white !important;
207
- border: 2px solid #e2e8f0 !important;
208
- color: #1e293b !important;
209
- }
210
-
211
- .oss-section {
212
- border-color: #0ea5e9 !important;
213
- }
214
-
215
- .enterprise-section {
216
- border-color: #10b981 !important;
217
- }
218
- """
219
-
220
- return css
221
-
222
-
223
- def get_installation_badges() -> str:
224
- """Get installation badge HTML - SIMPLIFIED VERSION"""
225
- return """
226
- <div style="display: flex; justify-content: center; gap: 10px; margin-top: 10px; flex-wrap: wrap;">
227
- <span style="padding: 4px 12px; background: #f59e0b;
228
- color: white; border-radius: 20px; font-size: 12px; font-weight: bold;
229
- display: flex; align-items: center; gap: 6px;">
230
- ⚠️ Checking ARF Installation...
231
- </span>
232
- </div>
233
- """
234
-
235
- __all__ = ["get_styles", "get_installation_badges"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ui/styles/modern.css DELETED
@@ -1,342 +0,0 @@
1
- /* ui/styles/modern.css - Design System Foundation */
2
- :root {
3
- /* Primary Colors (matching your current scheme) */
4
- --color-primary-50: #eff6ff;
5
- --color-primary-100: #dbeafe;
6
- --color-primary-200: #bfdbfe;
7
- --color-primary-300: #93c5fd;
8
- --color-primary-400: #60a5fa;
9
- --color-primary-500: #3b82f6;
10
- --color-primary-600: #2563eb;
11
- --color-primary-700: #1d4ed8;
12
- --color-primary-800: #1e40af;
13
- --color-primary-900: #1e3a8a;
14
-
15
- /* Success Colors */
16
- --color-success-50: #f0fdf4;
17
- --color-success-100: #dcfce7;
18
- --color-success-200: #bbf7d0;
19
- --color-success-300: #86efac;
20
- --color-success-400: #4ade80;
21
- --color-success-500: #22c55e;
22
- --color-success-600: #16a34a;
23
- --color-success-700: #15803d;
24
- --color-success-800: #166534;
25
- --color-success-900: #14532d;
26
-
27
- /* Warning Colors */
28
- --color-warning-50: #fffbeb;
29
- --color-warning-100: #fef3c7;
30
- --color-warning-200: #fde68a;
31
- --color-warning-300: #fcd34d;
32
- --color-warning-400: #fbbf24;
33
- --color-warning-500: #f59e0b;
34
- --color-warning-600: #d97706;
35
- --color-warning-700: #b45309;
36
- --color-warning-800: #92400e;
37
- --color-warning-900: #78350f;
38
-
39
- /* Danger Colors */
40
- --color-danger-50: #fef2f2;
41
- --color-danger-100: #fee2e2;
42
- --color-danger-200: #fecaca;
43
- --color-danger-300: #fca5a5;
44
- --color-danger-400: #f87171;
45
- --color-danger-500: #ef4444;
46
- --color-danger-600: #dc2626;
47
- --color-danger-700: #b91c1c;
48
- --color-danger-800: #991b1b;
49
- --color-danger-900: #7f1d1d;
50
-
51
- /* Neutral Colors */
52
- --color-neutral-50: #f8fafc;
53
- --color-neutral-100: #f1f5f9;
54
- --color-neutral-200: #e2e8f0;
55
- --color-neutral-300: #cbd5e1;
56
- --color-neutral-400: #94a3b8;
57
- --color-neutral-500: #64748b;
58
- --color-neutral-600: #475569;
59
- --color-neutral-700: #334155;
60
- --color-neutral-800: #1e293b;
61
- --color-neutral-900: #0f172a;
62
-
63
- /* Spacing */
64
- --spacing-1: 0.25rem;
65
- --spacing-2: 0.5rem;
66
- --spacing-3: 0.75rem;
67
- --spacing-4: 1rem;
68
- --spacing-5: 1.25rem;
69
- --spacing-6: 1.5rem;
70
- --spacing-8: 2rem;
71
- --spacing-10: 2.5rem;
72
- --spacing-12: 3rem;
73
- --spacing-16: 4rem;
74
- --spacing-20: 5rem;
75
-
76
- /* Typography */
77
- --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
78
- --font-mono: 'JetBrains Mono', 'SF Mono', Monaco, monospace;
79
-
80
- /* Border Radius */
81
- --radius-sm: 0.25rem;
82
- --radius-md: 0.5rem;
83
- --radius-lg: 0.75rem;
84
- --radius-xl: 1rem;
85
- --radius-2xl: 1.5rem;
86
- --radius-full: 9999px;
87
-
88
- /* Shadows */
89
- --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
90
- --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
91
- --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
92
- --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1);
93
-
94
- /* Transitions */
95
- --transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
96
- --transition-normal: 250ms cubic-bezier(0.4, 0, 0.2, 1);
97
- --transition-slow: 350ms cubic-bezier(0.4, 0, 0.2, 1);
98
- }
99
-
100
- /* Semantic aliases for easier use */
101
- :root {
102
- --color-primary: var(--color-primary-500);
103
- --color-success: var(--color-success-500);
104
- --color-warning: var(--color-warning-500);
105
- --color-danger: var(--color-danger-500);
106
- --color-border: var(--color-neutral-200);
107
- --color-bg: var(--color-neutral-50);
108
- --color-text: var(--color-neutral-900);
109
- --color-text-secondary: var(--color-neutral-600);
110
- }
111
-
112
- /* Dark mode overrides */
113
- [data-theme="dark"] {
114
- --color-primary: var(--color-primary-400);
115
- --color-success: var(--color-success-400);
116
- --color-warning: var(--color-warning-400);
117
- --color-danger: var(--color-danger-400);
118
- --color-border: var(--color-neutral-700);
119
- --color-bg: var(--color-neutral-900);
120
- --color-text: var(--color-neutral-100);
121
- --color-text-secondary: var(--color-neutral-400);
122
- }
123
-
124
- /* Base styles */
125
- * {
126
- box-sizing: border-box;
127
- }
128
-
129
- body {
130
- font-family: var(--font-sans);
131
- color: var(--color-text);
132
- background: var(--color-bg);
133
- margin: 0;
134
- padding: 0;
135
- line-height: 1.5;
136
- }
137
-
138
- /* Container utilities */
139
- .container {
140
- width: 100%;
141
- max-width: 1200px;
142
- margin: 0 auto;
143
- padding: 0 var(--spacing-4);
144
- }
145
-
146
- .container-sm {
147
- max-width: 800px;
148
- }
149
-
150
- .container-lg {
151
- max-width: 1400px;
152
- }
153
-
154
- /* Grid system */
155
- .grid {
156
- display: grid;
157
- gap: var(--spacing-4);
158
- }
159
-
160
- .grid-2 {
161
- grid-template-columns: repeat(2, 1fr);
162
- }
163
-
164
- .grid-3 {
165
- grid-template-columns: repeat(3, 1fr);
166
- }
167
-
168
- .grid-4 {
169
- grid-template-columns: repeat(4, 1fr);
170
- }
171
-
172
- /* Flex utilities */
173
- .flex {
174
- display: flex;
175
- }
176
-
177
- .flex-col {
178
- flex-direction: column;
179
- }
180
-
181
- .items-center {
182
- align-items: center;
183
- }
184
-
185
- .justify-between {
186
- justify-content: space-between;
187
- }
188
-
189
- .justify-center {
190
- justify-content: center;
191
- }
192
-
193
- .gap-2 {
194
- gap: var(--spacing-2);
195
- }
196
-
197
- .gap-4 {
198
- gap: var(--spacing-4);
199
- }
200
-
201
- .gap-6 {
202
- gap: var(--spacing-6);
203
- }
204
-
205
- /* Card base styles */
206
- .card {
207
- background: white;
208
- border-radius: var(--radius-lg);
209
- border: 1px solid var(--color-border);
210
- padding: var(--spacing-6);
211
- transition: box-shadow var(--transition-normal);
212
- }
213
-
214
- .card:hover {
215
- box-shadow: var(--shadow-md);
216
- }
217
-
218
- .card-elevated {
219
- box-shadow: var(--shadow-lg);
220
- border: none;
221
- }
222
-
223
- .card-outlined {
224
- border: 2px solid var(--color-primary);
225
- background: transparent;
226
- }
227
-
228
- /* Button base styles */
229
- .btn {
230
- display: inline-flex;
231
- align-items: center;
232
- justify-content: center;
233
- padding: var(--spacing-2) var(--spacing-4);
234
- border-radius: var(--radius-md);
235
- font-weight: 500;
236
- font-size: 0.875rem;
237
- border: none;
238
- cursor: pointer;
239
- transition: all var(--transition-fast);
240
- text-decoration: none;
241
- gap: var(--spacing-2);
242
- }
243
-
244
- .btn:disabled {
245
- opacity: 0.5;
246
- cursor: not-allowed;
247
- }
248
-
249
- .btn-primary {
250
- background: var(--color-primary);
251
- color: white;
252
- }
253
-
254
- .btn-primary:hover:not(:disabled) {
255
- background: var(--color-primary-600);
256
- }
257
-
258
- .btn-secondary {
259
- background: var(--color-neutral-100);
260
- color: var(--color-text);
261
- border: 1px solid var(--color-border);
262
- }
263
-
264
- .btn-secondary:hover:not(:disabled) {
265
- background: var(--color-neutral-200);
266
- }
267
-
268
- /* Typography utilities */
269
- .text-sm {
270
- font-size: 0.875rem;
271
- }
272
-
273
- .text-base {
274
- font-size: 1rem;
275
- }
276
-
277
- .text-lg {
278
- font-size: 1.125rem;
279
- }
280
-
281
- .text-xl {
282
- font-size: 1.25rem;
283
- }
284
-
285
- .text-2xl {
286
- font-size: 1.5rem;
287
- }
288
-
289
- .font-medium {
290
- font-weight: 500;
291
- }
292
-
293
- .font-semibold {
294
- font-weight: 600;
295
- }
296
-
297
- .font-bold {
298
- font-weight: 700;
299
- }
300
-
301
- .text-primary {
302
- color: var(--color-primary);
303
- }
304
-
305
- .text-success {
306
- color: var(--color-success);
307
- }
308
-
309
- .text-warning {
310
- color: var(--color-warning);
311
- }
312
-
313
- .text-danger {
314
- color: var(--color-danger);
315
- }
316
-
317
- .text-muted {
318
- color: var(--color-text-secondary);
319
- }
320
-
321
- /* Utility classes for gradients */
322
- .gradient-primary {
323
- background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-700) 100%);
324
- }
325
-
326
- .gradient-success {
327
- background: linear-gradient(135deg, var(--color-success) 0%, var(--color-success-700) 100%);
328
- }
329
-
330
- .gradient-warning {
331
- background: linear-gradient(135deg, var(--color-warning) 0%, var(--color-warning-700) 100%);
332
- }
333
-
334
- /* Focus styles for accessibility */
335
- :focus {
336
- outline: 2px solid var(--color-primary);
337
- outline-offset: 2px;
338
- }
339
-
340
- :focus:not(:focus-visible) {
341
- outline: none;
342
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ui/styles/responsive.css DELETED
@@ -1,161 +0,0 @@
1
- /* ui/styles/responsive.css - Mobile-First Responsive Utilities */
2
-
3
- /* Mobile-first: default styles are for mobile */
4
- .container {
5
- padding: 0 var(--spacing-4);
6
- }
7
-
8
- /* Hide/show utilities for different screen sizes */
9
- .mobile-only {
10
- display: block;
11
- }
12
-
13
- .tablet-only {
14
- display: none;
15
- }
16
-
17
- .desktop-only {
18
- display: none;
19
- }
20
-
21
- /* Responsive grid columns */
22
- .grid-2, .grid-3, .grid-4 {
23
- grid-template-columns: 1fr;
24
- }
25
-
26
- /* Responsive typography */
27
- .text-responsive {
28
- font-size: 0.875rem;
29
- }
30
-
31
- /* Responsive spacing */
32
- .responsive-padding {
33
- padding: var(--spacing-4);
34
- }
35
-
36
- /* Tablet styles (≥ 768px) */
37
- @media (min-width: 768px) {
38
- .container {
39
- padding: 0 var(--spacing-6);
40
- }
41
-
42
- .mobile-only {
43
- display: none;
44
- }
45
-
46
- .tablet-only {
47
- display: block;
48
- }
49
-
50
- .grid-2 {
51
- grid-template-columns: repeat(2, 1fr);
52
- }
53
-
54
- .grid-3 {
55
- grid-template-columns: repeat(2, 1fr);
56
- }
57
-
58
- .text-responsive {
59
- font-size: 1rem;
60
- }
61
-
62
- .responsive-padding {
63
- padding: var(--spacing-6);
64
- }
65
- }
66
-
67
- /* Desktop styles (≥ 1024px) */
68
- @media (min-width: 1024px) {
69
- .container {
70
- padding: 0 var(--spacing-8);
71
- }
72
-
73
- .tablet-only {
74
- display: none;
75
- }
76
-
77
- .desktop-only {
78
- display: block;
79
- }
80
-
81
- .grid-3 {
82
- grid-template-columns: repeat(3, 1fr);
83
- }
84
-
85
- .grid-4 {
86
- grid-template-columns: repeat(4, 1fr);
87
- }
88
-
89
- .text-responsive {
90
- font-size: 1.125rem;
91
- }
92
-
93
- .responsive-padding {
94
- padding: var(--spacing-8);
95
- }
96
- }
97
-
98
- /* Large desktop (≥ 1280px) */
99
- @media (min-width: 1280px) {
100
- .text-responsive {
101
- font-size: 1.25rem;
102
- }
103
- }
104
-
105
- /* Ultra-wide screens (≥ 1536px) */
106
- @media (min-width: 1536px) {
107
- .container {
108
- max-width: 1400px;
109
- }
110
- }
111
-
112
- /* Touch-friendly styles for mobile */
113
- @media (hover: none) and (pointer: coarse) {
114
- .btn, button, [role="button"] {
115
- min-height: 44px;
116
- min-width: 44px;
117
- }
118
-
119
- input, select, textarea {
120
- font-size: 16px; /* Prevents iOS zoom on focus */
121
- }
122
- }
123
-
124
- /* Reduce motion preference */
125
- @media (prefers-reduced-motion: reduce) {
126
- *,
127
- *::before,
128
- *::after {
129
- animation-duration: 0.01ms !important;
130
- animation-iteration-count: 1 !important;
131
- transition-duration: 0.01ms !important;
132
- }
133
- }
134
-
135
- /* High contrast mode support */
136
- @media (prefers-contrast: high) {
137
- .card {
138
- border: 2px solid var(--color-text);
139
- }
140
-
141
- .btn {
142
- border: 2px solid currentColor;
143
- }
144
- }
145
-
146
- /* Print styles */
147
- @media print {
148
- .no-print {
149
- display: none !important;
150
- }
151
-
152
- .card {
153
- border: 1px solid #000;
154
- box-shadow: none;
155
- }
156
-
157
- a {
158
- color: #000;
159
- text-decoration: underline;
160
- }
161
- }