parapet-rails 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +48 -0
- data/Rakefile +7 -0
- data/app/assets/config/parapet/grammar-registry.json +52 -0
- data/app/assets/images/parapet/icons/activities/component-inspector.svg +4 -0
- data/app/assets/images/parapet/icons/activities/coverage-heatmap.svg +3 -0
- data/app/assets/images/parapet/icons/activities/discovery-sidebar.svg +3 -0
- data/app/assets/images/parapet/icons/activities/environment-toggles.svg +4 -0
- data/app/assets/images/parapet/icons/activities/failure-inspector.svg +5 -0
- data/app/assets/images/parapet/icons/activities/flaky-history.svg +3 -0
- data/app/assets/images/parapet/icons/activities/flight-recorder.svg +5 -0
- data/app/assets/images/parapet/icons/activities/health-graph.svg +3 -0
- data/app/assets/images/parapet/icons/activities/injection-engine.svg +3 -0
- data/app/assets/images/parapet/icons/activities/live-sql-stream.svg +5 -0
- data/app/assets/images/parapet/icons/activities/live-web-preview.svg +4 -0
- data/app/assets/images/parapet/icons/activities/monaco-editor.svg +5 -0
- data/app/assets/images/parapet/icons/activities/progress-area.svg +3 -0
- data/app/assets/images/parapet/icons/activities/registry-metadata.svg +5 -0
- data/app/assets/images/parapet/icons/activities/seed-inspector.svg +4 -0
- data/app/assets/images/parapet/icons/activities/slow-test-bottlenecks.svg +4 -0
- data/app/assets/images/parapet/icons/activities/smart-search.svg +4 -0
- data/app/assets/images/parapet/icons/activities/snippet-library.svg +4 -0
- data/app/assets/images/parapet/icons/activities/terminal.svg +4 -0
- data/app/assets/images/parapet/icons/activities/unified-schema-view.svg +4 -0
- data/app/assets/images/parapet/icons/activities/visual-comparison.svg +3 -0
- data/app/assets/images/parapet/icons/activities/visual-summary-bar.svg +5 -0
- data/app/assets/images/parapet/icons/nav/ideas.svg +4 -0
- data/app/assets/images/parapet/icons/nav/languages.svg +8 -0
- data/app/assets/images/parapet/icons/nav/profile.svg +4 -0
- data/app/assets/images/parapet/icons/nav/pulse.svg +7 -0
- data/app/assets/images/parapet/icons/nav/settings.svg +4 -0
- data/app/assets/images/parapet/icons/nav/state.svg +5 -0
- data/app/assets/images/parapet/icons/nav/styles.svg +7 -0
- data/app/assets/images/parapet/icons/nav/tests.svg +4 -0
- data/app/assets/images/parapet/icons/nav/traffic.svg +12 -0
- data/app/assets/javascripts/parapet/activity-card.js +439 -0
- data/app/assets/javascripts/parapet/activity-cards.js +291 -0
- data/app/assets/javascripts/parapet/activity-registry.js +181 -0
- data/app/assets/javascripts/parapet/activity-toggles.js +76 -0
- data/app/assets/javascripts/parapet/application.js +37 -0
- data/app/assets/javascripts/parapet/card-failure-inspector.js +134 -0
- data/app/assets/javascripts/parapet/card-file-editor.js +1722 -0
- data/app/assets/javascripts/parapet/card-progress-area.js +297 -0
- data/app/assets/javascripts/parapet/card-smart-search.js +114 -0
- data/app/assets/javascripts/parapet/card-snippet-library.js +251 -0
- data/app/assets/javascripts/parapet/explorer-resizer.js +92 -0
- data/app/assets/javascripts/parapet/parapet_qss.js +342 -0
- data/app/assets/javascripts/parapet/proficiency-filter.js +53 -0
- data/app/assets/javascripts/parapet/sidebar-resizer.js +197 -0
- data/app/assets/javascripts/parapet/styles-workbench.js +819 -0
- data/app/assets/javascripts/parapet/tree-logic.js +320 -0
- data/app/assets/stylesheets/parapet/_qss_variables.scss +122 -0
- data/app/assets/stylesheets/parapet/parapet_qss.scss +69 -0
- data/app/assets/stylesheets/parapet/qss_application.css +260940 -0
- data/app/assets/stylesheets/parapet/qss_application.css.map +1 -0
- data/app/assets/stylesheets/parapet/qss_application.scss +5 -0
- data/app/assets/stylesheets/parapet/qss_workspace.scss +209 -0
- data/app/assets/stylesheets/parapet/sample.qss +22 -0
- data/app/controllers/parapet/application_controller.rb +54 -0
- data/app/controllers/parapet/base_controller.rb +18 -0
- data/app/controllers/parapet/build_suite/dashboard_controller.rb +10 -0
- data/app/controllers/parapet/css_suite/compiler_controller.rb +95 -0
- data/app/controllers/parapet/css_suite/dashboard_controller.rb +10 -0
- data/app/controllers/parapet/css_suite/preview_controller.rb +46 -0
- data/app/controllers/parapet/dashboard_controller.rb +8 -0
- data/app/controllers/parapet/drafts_controller.rb +30 -0
- data/app/controllers/parapet/explorers_controller.rb +53 -0
- data/app/controllers/parapet/files_controller.rb +208 -0
- data/app/controllers/parapet/footers_controller.rb +24 -0
- data/app/controllers/parapet/intentions_suite/dashboard_controller.rb +10 -0
- data/app/controllers/parapet/landing_controller.rb +14 -0
- data/app/controllers/parapet/monitor_suite/dashboard_controller.rb +10 -0
- data/app/controllers/parapet/pm_suite/publish_controller.rb +16 -0
- data/app/controllers/parapet/polyglot_suite/dashboard_controller.rb +10 -0
- data/app/controllers/parapet/runner_controller.rb +34 -0
- data/app/controllers/parapet/sessions_controller.rb +35 -0
- data/app/controllers/parapet/signal_suite/dashboard_controller.rb +10 -0
- data/app/controllers/parapet/test_suite/dashboard_controller.rb +10 -0
- data/app/controllers/parapet/widgets_controller.rb +33 -0
- data/app/helpers/parapet/application_helper.rb +23 -0
- data/app/helpers/parapet/icon_helper.rb +57 -0
- data/app/jobs/parapet/application_job.rb +4 -0
- data/app/mailers/parapet/application_mailer.rb +6 -0
- data/app/models/parapet/activity.rb +14 -0
- data/app/models/parapet/application_record.rb +5 -0
- data/app/models/parapet/current.rb +6 -0
- data/app/models/parapet/draft_recovery.rb +9 -0
- data/app/models/parapet/internal_record.rb +34 -0
- data/app/models/parapet/run_history.rb +22 -0
- data/app/models/parapet/runtime_setting.rb +8 -0
- data/app/models/parapet/session.rb +7 -0
- data/app/models/parapet/suite_assignment.rb +30 -0
- data/app/models/parapet/user.rb +12 -0
- data/app/services/parapet/activity_phrase_renderer.rb +35 -0
- data/app/services/parapet/activity_writer.rb +26 -0
- data/app/services/parapet/authorization.rb +198 -0
- data/app/services/parapet/consistency_auditor.rb +58 -0
- data/app/services/parapet/directory_scanner.rb +159 -0
- data/app/services/parapet/draft_recovery_store.rb +18 -0
- data/app/services/parapet/explorer_manager.rb +402 -0
- data/app/services/parapet/file_save_service.rb +21 -0
- data/app/services/parapet/git_side_ref_committer.rb +50 -0
- data/app/services/parapet/noun_discovery.rb +26 -0
- data/app/services/parapet/publish_gate.rb +83 -0
- data/app/services/parapet/test_runner.rb +178 -0
- data/app/views/layouts/parapet/application.html.erb +83 -0
- data/app/views/layouts/parapet/landing.html.erb +19 -0
- data/app/views/parapet/activities/_ai_error_explainer.html.erb +33 -0
- data/app/views/parapet/activities/_ai_explainer_widget.html.erb +20 -0
- data/app/views/parapet/activities/_calendar_widget.html.erb +31 -0
- data/app/views/parapet/activities/_code_snippets_widget.html.erb +22 -0
- data/app/views/parapet/activities/_coverage_explorer.html.erb +1 -0
- data/app/views/parapet/activities/_dropdown_test.html.erb +20 -0
- data/app/views/parapet/activities/_explorer_node.html.erb +102 -0
- data/app/views/parapet/activities/_explorer_tree.html.erb +16 -0
- data/app/views/parapet/activities/_file_editor.html.erb +183 -0
- data/app/views/parapet/activities/_file_explorer.html.erb +23 -0
- data/app/views/parapet/activities/_fix_suggestions_widget.html.erb +13 -0
- data/app/views/parapet/activities/_generic.html.erb +6 -0
- data/app/views/parapet/activities/_live_preview.html.erb +13 -0
- data/app/views/parapet/activities/_perspective_filters.html.erb +36 -0
- data/app/views/parapet/activities/_progress_area.html.erb +37 -0
- data/app/views/parapet/activities/_project_explorer.html.erb +1 -0
- data/app/views/parapet/activities/_registry_explorer.html.erb +1 -0
- data/app/views/parapet/activities/_run_history.html.erb +2 -0
- data/app/views/parapet/activities/_smart_search.html.erb +11 -0
- data/app/views/parapet/activities/file_explorer/_perspective_scripts.html.erb +58 -0
- data/app/views/parapet/activities/file_explorer/_perspectives.html.erb +0 -0
- data/app/views/parapet/activities/file_explorer/_viewport_scripts.html.erb +33 -0
- data/app/views/parapet/css_suite/_workbench.html.erb +51 -0
- data/app/views/parapet/dashboards/index.html.erb +113 -0
- data/app/views/parapet/debug_panel.html.erb +79 -0
- data/app/views/parapet/debug_panel_tailwind.html.erb +98 -0
- data/app/views/parapet/erb_patch_test.html.erb +5 -0
- data/app/views/parapet/explorers/show.html.erb +1 -0
- data/app/views/parapet/git_viewer.html.erb +62 -0
- data/app/views/parapet/git_viewer_after.html.erb +14 -0
- data/app/views/parapet/git_viewer_before.html.erb +14 -0
- data/app/views/parapet/git_viewer_governed.html.erb +88 -0
- data/app/views/parapet/git_viewer_governed_after.html.erb +36 -0
- data/app/views/parapet/git_viewer_governed_before.html.erb +36 -0
- data/app/views/parapet/git_viewer_tailwind.html.erb +88 -0
- data/app/views/parapet/git_viewer_thin_wrapper.html.erb +85 -0
- data/app/views/parapet/hierarchical_layout_test.html.erb +85 -0
- data/app/views/parapet/hybrid_stress_test.html.erb +25 -0
- data/app/views/parapet/index.html.erb +35 -0
- data/app/views/parapet/mutation_stress_test.html.erb +82 -0
- data/app/views/parapet/recursive_anchoring_test.html.erb +66 -0
- data/app/views/parapet/sessions/new.html.erb +28 -0
- data/app/views/parapet/shared/_cad_inspector.html.erb +92 -0
- data/app/views/parapet/shared/_discovery_sidebar.html.erb +48 -0
- data/app/views/parapet/shared/_explorer_bar.html.erb +71 -0
- data/app/views/parapet/shared/_footer.html.erb +10 -0
- data/app/views/parapet/shared/_footer_ideas.html.erb +36 -0
- data/app/views/parapet/shared/_footer_languages.html.erb +33 -0
- data/app/views/parapet/shared/_footer_pulse.html.erb +33 -0
- data/app/views/parapet/shared/_footer_state.html.erb +33 -0
- data/app/views/parapet/shared/_footer_styles.html.erb +37 -0
- data/app/views/parapet/shared/_footer_tests.html.erb +39 -0
- data/app/views/parapet/shared/_footer_traffic.html.erb +45 -0
- data/app/views/parapet/shared/_global_nav.html.erb +55 -0
- data/app/views/parapet/shared/_head.html.erb +4 -0
- data/app/views/parapet/shared/_header.html.erb +20 -0
- data/app/views/parapet/shared/_object_inspector.html.erb +76 -0
- data/app/views/parapet/shared/_ribbon_header.html.erb +3 -0
- data/app/views/parapet/shared/_root_selector_modal.html.erb +15 -0
- data/app/views/parapet/shared/_tab_bar.html.erb +62 -0
- data/app/views/parapet/shared/activities_ribbon/_agent_group.html.erb +15 -0
- data/app/views/parapet/shared/activities_ribbon/_analysis_group.html.erb +15 -0
- data/app/views/parapet/shared/activities_ribbon/_architect_group.html.erb +21 -0
- data/app/views/parapet/shared/activities_ribbon/_explorer_group.html.erb +12 -0
- data/app/views/parapet/shared/activities_ribbon/_inspector_group.html.erb +15 -0
- data/app/views/parapet/shared/activities_ribbon/_proficiency_filter.html.erb +24 -0
- data/app/views/parapet/shared/activities_ribbon/_runner_group.html.erb +21 -0
- data/app/views/parapet/shared/activities_ribbon/_spatial_inspector_group.html.erb +18 -0
- data/app/views/parapet/shared/activities_ribbon/_studio_group.html.erb +18 -0
- data/app/views/parapet/shared/activities_ribbon/_stylist_group.html.erb +18 -0
- data/app/views/parapet/shared/explorers/_base.html.erb +107 -0
- data/app/views/parapet/shared/explorers/_css.html.erb +1 -0
- data/app/views/parapet/shared/explorers/_intentions.html.erb +1 -0
- data/app/views/parapet/shared/explorers/_project.html.erb +1 -0
- data/app/views/parapet/shared/explorers/_tests.html.erb +1 -0
- data/app/views/parapet/shared/head/_meta.html.erb +3 -0
- data/app/views/parapet/shared/head/_styles_activities.html.erb +152 -0
- data/app/views/parapet/shared/head/_styles_shared.html.erb +52 -0
- data/app/views/parapet/shared/head/_styles_workspace.html.erb +67 -0
- data/app/views/parapet/shared/ribbon_header/_diagnostic_controls.html.erb +17 -0
- data/app/views/parapet/shared/ribbon_header/_execution_controls.html.erb +28 -0
- data/app/views/parapet/shared/ribbon_header/_focus_search.html.erb +5 -0
- data/app/views/parapet/shared/root_selector/_header.html.erb +10 -0
- data/app/views/parapet/shared/root_selector/_path_input.html.erb +13 -0
- data/app/views/parapet/shared/root_selector/_quick_select.html.erb +20 -0
- data/app/views/parapet/shared/root_selector/_scripts.html.erb +61 -0
- data/app/views/parapet/shared/root_selector/_warning.html.erb +11 -0
- data/app/views/parapet/shared/widgets/_base.html.erb +6 -0
- data/app/views/parapet/shared/widgets/_css.html.erb +79 -0
- data/app/views/parapet/widgets/_explainer.html.erb +17 -0
- data/app/views/parapet/widgets/_hotkeys.html.erb +20 -0
- data/app/views/parapet/widgets/_search.html.erb +68 -0
- data/app/views/parapet/widgets/_spatial_inspector.html.erb +54 -0
- data/app/views/parapet/widgets/_widget-explainer.html.erb +17 -0
- data/app/views/parapet/widgets/_widget-hotkeys.html.erb +20 -0
- data/app/views/parapet/widgets/_widget-search.html.erb +68 -0
- data/app/views/parapet/widgets/_widget-snippets.html.erb +18 -0
- data/app/views/parapet/widgets/_widget-suggestions.html.erb +15 -0
- data/app/views/parapet/widgets/show.html.erb +3 -0
- data/app/views/shared/_footer.html.erb +0 -0
- data/config/parapet/qss_config.yml +117 -0
- data/config/parapet/qss_registry.yml +14 -0
- data/config/routes.rb +40 -0
- data/db/migrate/20260916035300_create_run_histories.rb +16 -0
- data/db/migrate/20261002000000_expand_run_histories_for_activity_tracking.rb +7 -0
- data/db/parapet_migrate/20260929184200_create_parapet_users.rb +12 -0
- data/db/parapet_migrate/20260929184300_create_parapet_sessions.rb +9 -0
- data/db/parapet_migrate/20260930000000_create_parapet_runtime_settings.rb +12 -0
- data/db/parapet_migrate/20260930000100_create_parapet_suite_assignments.rb +14 -0
- data/db/parapet_migrate/20261002000000_create_parapet_activities.rb +16 -0
- data/db/parapet_migrate/20261002000100_create_parapet_draft_recoveries.rb +13 -0
- data/db/parapet_schema.rb +64 -0
- data/db/schema.rb +21 -0
- data/db/schema.released.rb +0 -0
- data/lib/parapet/engine.rb +11 -0
- data/lib/parapet/environment_guard.rb +14 -0
- data/lib/parapet/version.rb +3 -0
- data/lib/parapet-rails.rb +1 -0
- data/lib/parapet.rb +59 -0
- data/lib/tasks/parapet_qss.rake +26 -0
- data/lib/tasks/parapet_tasks.rake +25 -0
- data/lib/tasks/randomize_explorer_health.rb +101 -0
- metadata +423 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
// Tree Logic
|
|
2
|
+
// Handles dynamic file explorer tree rendering and interactions.
|
|
3
|
+
|
|
4
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
5
|
+
console.log("Tree Logic: DOMContentLoaded fired");
|
|
6
|
+
|
|
7
|
+
const refreshTree = (container) => {
|
|
8
|
+
if (!container) return;
|
|
9
|
+
|
|
10
|
+
const endpoint = container.getAttribute('data-endpoint');
|
|
11
|
+
|
|
12
|
+
fetch(endpoint)
|
|
13
|
+
.then(response => {
|
|
14
|
+
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
|
|
15
|
+
return response.json();
|
|
16
|
+
})
|
|
17
|
+
.then(data => {
|
|
18
|
+
if (!data || (Array.isArray(data.children) && data.children.length === 0)) {
|
|
19
|
+
container.innerHTML = '<div class="qss-p[16] qss-text-slate-600 qss-text-size[10] qss-uppercase qss-font-bold qss-tracking-widest qss-text-center">Empty Filesystem</div>';
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
container.innerHTML = '';
|
|
23
|
+
const treeHtml = renderNode(data, 0);
|
|
24
|
+
container.appendChild(treeHtml);
|
|
25
|
+
})
|
|
26
|
+
.catch(error => {
|
|
27
|
+
console.error('Error loading file tree:', error);
|
|
28
|
+
container.innerHTML = `<div class="qss-p[16] qss-text-red-400 qss-text-size[10] qss-flex qss-flex-col qss-gap[8]">
|
|
29
|
+
<span class="qss-font-bold qss-uppercase">Load Error</span>
|
|
30
|
+
<span>${error.message}</span>
|
|
31
|
+
</div>`;
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const initStandaloneTree = () => {
|
|
36
|
+
const containers = document.querySelectorAll('#qss-tree-container');
|
|
37
|
+
containers.forEach(container => {
|
|
38
|
+
// Check if it's already initialized (avoid multiple fetches if card-based also uses it)
|
|
39
|
+
if (container.closest('.qss-activity-card')) return;
|
|
40
|
+
refreshTree(container);
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// Attach initialization logic to the registry if it exists
|
|
45
|
+
if (window.ActivityCards && window.ActivityCards.registry) {
|
|
46
|
+
console.log("Tree Logic: Registering file-explorer init");
|
|
47
|
+
window.ActivityCards.registry['file-explorer'] = window.ActivityCards.registry['file-explorer'] || {};
|
|
48
|
+
|
|
49
|
+
window.ActivityCards.registry['file-explorer'].init = function(card) {
|
|
50
|
+
const container = card.element.querySelector('#qss-tree-container');
|
|
51
|
+
refreshTree(container);
|
|
52
|
+
card._refreshTree = () => refreshTree(container);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// Global listener for file system changes
|
|
56
|
+
document.addEventListener('parapet:fileSystemChanged', () => {
|
|
57
|
+
// Refresh standalone trees
|
|
58
|
+
initStandaloneTree();
|
|
59
|
+
// Refresh card-based trees
|
|
60
|
+
Object.values(window.ActivityCards.active).forEach(card => {
|
|
61
|
+
if (card.id === 'file-explorer' || card.constructor.name === 'FileExplorerCard' || card._refreshTree) {
|
|
62
|
+
if (card._refreshTree) card._refreshTree();
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
} else {
|
|
67
|
+
console.error("Tree Logic: window.ActivityCards or registry not found");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
initStandaloneTree();
|
|
71
|
+
document.addEventListener('turbo:load', initStandaloneTree);
|
|
72
|
+
|
|
73
|
+
// Dynamic Sidebar Title based on Key Area
|
|
74
|
+
document.addEventListener('activityActivated', (e) => {
|
|
75
|
+
const { keyArea } = e.detail;
|
|
76
|
+
const titleSpan = document.querySelector('#qss-sidebar-title span');
|
|
77
|
+
if (titleSpan && keyArea) {
|
|
78
|
+
// Map internal key areas to readable titles
|
|
79
|
+
const areaMap = {
|
|
80
|
+
'Explorer': 'Test Suite',
|
|
81
|
+
'Runner': 'Test Runner',
|
|
82
|
+
'Studio': 'Code Studio',
|
|
83
|
+
'Stylist': 'CSS Suite',
|
|
84
|
+
'General': 'Workspace'
|
|
85
|
+
};
|
|
86
|
+
titleSpan.textContent = areaMap[keyArea] || keyArea;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// Event delegation for toggling folders
|
|
91
|
+
document.addEventListener('click', (e) => {
|
|
92
|
+
const toggle = e.target.closest('.qss-folder-toggle');
|
|
93
|
+
if (!toggle) return;
|
|
94
|
+
|
|
95
|
+
const container = toggle.nextElementSibling;
|
|
96
|
+
const chevron = toggle.querySelector('.qss-chevron-icon');
|
|
97
|
+
const folderIcon = toggle.querySelector('.qss-folder-icon');
|
|
98
|
+
|
|
99
|
+
if (container) {
|
|
100
|
+
const isHidden = container.classList.contains('qss-hidden');
|
|
101
|
+
|
|
102
|
+
if (!isHidden) {
|
|
103
|
+
// Collapse
|
|
104
|
+
container.classList.add('qss-hidden');
|
|
105
|
+
if (chevron) {
|
|
106
|
+
chevron.innerHTML = getIconSvg('chevron-right', '');
|
|
107
|
+
}
|
|
108
|
+
if (folderIcon) {
|
|
109
|
+
const isRoot = folderIcon.closest('.qss-tree-node-wrapper').parentElement.id === 'qss-tree-container';
|
|
110
|
+
const iconColor = isRoot ? 'qss-text-amber-500' : 'qss-text-amber-600/60';
|
|
111
|
+
folderIcon.innerHTML = getIconSvg('folder', iconColor);
|
|
112
|
+
}
|
|
113
|
+
} else {
|
|
114
|
+
// Expand
|
|
115
|
+
container.classList.remove('qss-hidden');
|
|
116
|
+
if (chevron) {
|
|
117
|
+
chevron.innerHTML = getIconSvg('chevron-down', '');
|
|
118
|
+
}
|
|
119
|
+
if (folderIcon) {
|
|
120
|
+
const isRoot = folderIcon.closest('.qss-tree-node-wrapper').parentElement.id === 'qss-tree-container';
|
|
121
|
+
const iconColor = isRoot ? 'qss-text-amber-500' : 'qss-text-amber-600/60';
|
|
122
|
+
folderIcon.innerHTML = getIconSvg('folder-open', iconColor);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// Global listener for dragstart via delegation
|
|
129
|
+
document.addEventListener('dragstart', (e) => {
|
|
130
|
+
const row = e.target.closest('.qss-tree-row');
|
|
131
|
+
if (!row) return;
|
|
132
|
+
|
|
133
|
+
const node = row.hasAttribute('data-path') ? row : row.closest('.qss-explorer-node');
|
|
134
|
+
if (!node) return;
|
|
135
|
+
|
|
136
|
+
const path = node.getAttribute('data-path');
|
|
137
|
+
const type = node.getAttribute('data-type');
|
|
138
|
+
|
|
139
|
+
if (type === 'file' && path) {
|
|
140
|
+
e.dataTransfer.setData('text/plain', path);
|
|
141
|
+
e.dataTransfer.effectAllowed = 'copy';
|
|
142
|
+
console.log("Tree Logic: Dragging file:", path);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// Global listener for opening files via double-click
|
|
147
|
+
document.addEventListener('dblclick', (e) => {
|
|
148
|
+
const row = e.target.closest('.qss-tree-row');
|
|
149
|
+
if (!row) return;
|
|
150
|
+
|
|
151
|
+
// Find the node container (it might be the row itself or a parent .qss-explorer-node)
|
|
152
|
+
const node = row.hasAttribute('data-path') ? row : row.closest('.qss-explorer-node');
|
|
153
|
+
if (!node) return;
|
|
154
|
+
|
|
155
|
+
const path = node.getAttribute('data-path');
|
|
156
|
+
const type = node.getAttribute('data-type');
|
|
157
|
+
|
|
158
|
+
if (type === 'file' && path) {
|
|
159
|
+
e.preventDefault();
|
|
160
|
+
e.stopPropagation();
|
|
161
|
+
console.log("Tree Logic: Double-click opening file:", path);
|
|
162
|
+
document.dispatchEvent(new CustomEvent('parapet:fileSelected', {
|
|
163
|
+
detail: { path: path }
|
|
164
|
+
}));
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// Auxiliary Widget Logic (Active class toggling for Turbo links)
|
|
169
|
+
document.addEventListener('click', (e) => {
|
|
170
|
+
const tab = e.target.closest('.qss-widget-tab');
|
|
171
|
+
if (!tab) return;
|
|
172
|
+
|
|
173
|
+
const container = tab.closest('#qss-auxiliary-widget-window');
|
|
174
|
+
if (!container) return;
|
|
175
|
+
|
|
176
|
+
const allTabs = container.querySelectorAll('.qss-widget-tab');
|
|
177
|
+
|
|
178
|
+
// Update Tabs styling
|
|
179
|
+
allTabs.forEach(t => {
|
|
180
|
+
t.classList.remove('qss-active', 'qss-bg-indigo-500/10', 'qss-border-indigo-500/30', 'qss-text-indigo-400');
|
|
181
|
+
t.classList.add('qss-bg-slate-800/50', 'qss-border-slate-700', 'qss-text-slate-500');
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
tab.classList.add('qss-active', 'qss-bg-indigo-500/10', 'qss-border-indigo-500/30', 'qss-text-indigo-400');
|
|
185
|
+
tab.classList.remove('qss-bg-slate-800/50', 'qss-border-slate-700', 'qss-text-slate-500');
|
|
186
|
+
|
|
187
|
+
// Turbo will handle the content replacement via the auxiliary-widget-frame
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
function getIconSvg(name, colorClass) {
|
|
192
|
+
const icons = {
|
|
193
|
+
'chevron-down': '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="qss-w[12] qss-h[12]"><polyline points="6 9 12 15 18 9"></polyline></svg>',
|
|
194
|
+
'chevron-right': '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="qss-w[12] qss-h[12]"><polyline points="9 18 15 12 9 6"></polyline></svg>',
|
|
195
|
+
'folder': '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="qss-w[14] qss-h[14]"><path d="M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"></path></svg>',
|
|
196
|
+
'folder-open': '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="qss-w[14] qss-h[14]"><path d="m6 14 1.45-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.55 6a2 2 0 0 1-1.94 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.93a2 2 0 0 1 1.66.9l.82 1.2a2 2 0 0 0 1.66.9H18a2 2 0 0 1 2 2v2"></path></svg>',
|
|
197
|
+
'file': '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="qss-w[14] qss-h[14]"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"></path><polyline points="14 2 14 8 20 8"></polyline></svg>',
|
|
198
|
+
'gem': '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="qss-w[14] qss-h[14]"><path d="M6 3h12l4 6-10 13L2 9z"></path><path d="M11 3 8 9l3 13 3-13-3-6z"></path><path d="M2 9h20"></path></svg>',
|
|
199
|
+
'database': '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="qss-w[14] qss-h[14]"><ellipse cx="12" cy="5" rx="9" ry="3"></ellipse><path d="M3 5V19A9 3 0 0 0 21 19V5"></path><path d="M3 12A9 3 0 0 0 21 12"></path></svg>',
|
|
200
|
+
'layers': '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="qss-w[14] qss-h[14]"><polygon points="12 2 2 7 12 12 22 7 12 2"></polygon><polyline points="2 17 12 22 22 17"></polyline><polyline points="2 12 12 17 22 12"></polyline></svg>',
|
|
201
|
+
'layout': '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="qss-w[14] qss-h[14]"><rect width="18" height="18" x="3" y="3" rx="2" ry="2"></rect><line x1="3" y1="9" x2="21" y2="9"></line><line x1="9" y1="21" x2="9" y2="9"></line></svg>',
|
|
202
|
+
'package': '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="qss-w[14] qss-h[14]"><path d="m7.5 4.27 9 5.15"></path><path d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"></path><path d="m3.27 6.96 8.73 5.05 8.73-5.05"></path><path d="M12 22.08V12"></path></svg>',
|
|
203
|
+
'list-checks': '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="qss-w[14] qss-h[14]"><path d="m3 17 2 2 4-4"></path><path d="m3 7 2 2 4-4"></path><path d="M13 6h8"></path><path d="M13 12h8"></path><path d="M13 18h8"></path></svg>',
|
|
204
|
+
'image': '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="qss-w[14] qss-h[14]"><rect width="18" height="18" x="3" y="3" rx="2" ry="2"></rect><circle cx="9" cy="9" r="2"></circle><path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"></path></svg>'
|
|
205
|
+
};
|
|
206
|
+
return `<span class="${colorClass} qss-flex qss-items-center qss-justify-center">${icons[name] || icons['file']}</span>`;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function renderNode(node, depth) {
|
|
210
|
+
const div = document.createElement('div');
|
|
211
|
+
div.className = 'qss-tree-node-wrapper qss-space-y[0]';
|
|
212
|
+
|
|
213
|
+
const basePadding = 8;
|
|
214
|
+
const indentSize = 14;
|
|
215
|
+
const paddingLeft = `${basePadding + (depth * indentSize)}px`;
|
|
216
|
+
|
|
217
|
+
if (node.type === 'directory') {
|
|
218
|
+
const toggle = document.createElement('div');
|
|
219
|
+
toggle.className = 'qss-folder-toggle qss-flex qss-items-center qss-justify-between qss-px[8] qss-h[44] hover:qss-bg-[#1a1d23] qss-cursor-pointer qss-group';
|
|
220
|
+
toggle.style.paddingLeft = paddingLeft;
|
|
221
|
+
|
|
222
|
+
const isRoot = depth === 0;
|
|
223
|
+
let iconName = 'folder-open';
|
|
224
|
+
let iconColor = isRoot ? 'qss-text-amber-500' : 'qss-text-amber-600/60';
|
|
225
|
+
|
|
226
|
+
if (node.icon) {
|
|
227
|
+
iconName = node.icon.replace('lucide-', '').replace('qss-icon-', '').replace('icon-', '');
|
|
228
|
+
iconColor = node.iconColor || iconColor;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
let healthBarHtml = '';
|
|
232
|
+
if (node.health) {
|
|
233
|
+
const red = node.health.red || 0;
|
|
234
|
+
const green = node.health.green || 0;
|
|
235
|
+
const orange = node.health.orange || 0;
|
|
236
|
+
healthBarHtml = `
|
|
237
|
+
<div class="qss-ml[6] qss-flex qss-h[4] qss-w[40] qss-bg-slate-800 qss-rounded-full qss-overflow-hidden qss-flex-shrink-0 qss-opacity-60 qss-translate-y-[0.5px]">
|
|
238
|
+
${red > 0 ? `<div class="qss-bg-red-500 qss-h-full" style="width: ${red}%"></div>` : ''}
|
|
239
|
+
${orange > 0 ? `<div class="qss-bg-orange-500 qss-h-full" style="width: ${orange}%"></div>` : ''}
|
|
240
|
+
${green > 0 ? `<div class="qss-bg-emerald-500 qss-h-full" style="width: ${green}%"></div>` : ''}
|
|
241
|
+
</div>
|
|
242
|
+
`;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
toggle.innerHTML = `
|
|
246
|
+
<div class="qss-flex qss-items-center qss-gap[6] qss-overflow-hidden">
|
|
247
|
+
<span class="qss-text-slate-500 qss-chevron-icon qss-flex-shrink-0">${getIconSvg('chevron-down', '')}</span>
|
|
248
|
+
<span class="qss-folder-icon qss-flex-shrink-0">${getIconSvg(iconName, iconColor)}</span>
|
|
249
|
+
<span class="qss-truncate ${isRoot ? 'qss-font-bold' : 'qss-text-slate-300'} qss-text-size[11] ${isRoot ? '' : 'qss-uppercase qss-tracking-wider qss-font-semibold'}">${node.name}</span>
|
|
250
|
+
${healthBarHtml}
|
|
251
|
+
</div>
|
|
252
|
+
`;
|
|
253
|
+
|
|
254
|
+
const childrenContainer = document.createElement('div');
|
|
255
|
+
childrenContainer.className = 'qss-space-y[0]';
|
|
256
|
+
|
|
257
|
+
if (node.children) {
|
|
258
|
+
node.children.forEach(child => {
|
|
259
|
+
childrenContainer.appendChild(renderNode(child, depth + 1));
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
div.appendChild(toggle);
|
|
264
|
+
div.appendChild(childrenContainer);
|
|
265
|
+
} else {
|
|
266
|
+
const file = document.createElement('div');
|
|
267
|
+
file.className = 'qss-flex qss-items-center qss-justify-between qss-px[8] qss-py[2] hover:qss-bg-white/5 qss-cursor-pointer qss-group qss-tree-row';
|
|
268
|
+
file.style.paddingLeft = paddingLeft;
|
|
269
|
+
file.setAttribute('data-path', node.path);
|
|
270
|
+
file.setAttribute('data-type', 'file');
|
|
271
|
+
file.setAttribute('draggable', 'true');
|
|
272
|
+
|
|
273
|
+
let iconName = node.icon || 'file';
|
|
274
|
+
let iconColor = node.iconColor || 'qss-text-slate-600';
|
|
275
|
+
|
|
276
|
+
if (node.icon) {
|
|
277
|
+
iconName = node.icon.replace('lucide-', '').replace('qss-icon-', '').replace('icon-', '');
|
|
278
|
+
// Ensure iconColor has qss- prefix if it's a tailwind-like class
|
|
279
|
+
if (node.iconColor && !node.iconColor.startsWith('qss-')) {
|
|
280
|
+
iconColor = 'qss-' + node.iconColor;
|
|
281
|
+
}
|
|
282
|
+
} else {
|
|
283
|
+
if (node.ext === 'rb') { iconName = 'gem'; iconColor = 'qss-text-red-400/80'; }
|
|
284
|
+
else if (node.ext === 'js') { iconName = 'file'; iconColor = 'qss-text-amber-400/80'; }
|
|
285
|
+
else if (node.ext === 'erb') { iconName = 'layout'; iconColor = 'qss-text-indigo-400/80'; }
|
|
286
|
+
else if (node.ext === 'css' || node.ext === 'scss') { iconName = 'layers'; iconColor = 'qss-text-cyan-400/80'; }
|
|
287
|
+
else if (['svg', 'png', 'jpg', 'webp'].includes(node.ext)) { iconName = 'image'; iconColor = 'qss-text-emerald-400/80'; }
|
|
288
|
+
else if (node.ext === 'feature') { iconName = 'list-checks'; iconColor = 'qss-text-emerald-400/80'; }
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
let statusDot = '';
|
|
292
|
+
if (node.status) {
|
|
293
|
+
const colors = {
|
|
294
|
+
red: 'qss-bg-red-500 qss-shadow-[0_0_8px_rgba(239,68,68,0.4)]',
|
|
295
|
+
green: 'qss-bg-emerald-500 qss-shadow-[0_0_8px_rgba(16,185,129,0.4)]',
|
|
296
|
+
orange: 'qss-bg-orange-500 qss-shadow-[0_0_8px_rgba(245,158,11,0.4)]',
|
|
297
|
+
grey: 'qss-bg-slate-700'
|
|
298
|
+
};
|
|
299
|
+
statusDot = `<div class="qss-w[6] qss-h[6] qss-rounded-full ${colors[node.status] || colors.grey} qss-flex-shrink-0"></div>`;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
file.innerHTML = `
|
|
303
|
+
<div class="qss-flex qss-items-center qss-gap[8] qss-overflow-hidden qss-pointer-events-none">
|
|
304
|
+
<span class="qss-flex-shrink-0">${getIconSvg(iconName, iconColor)}</span>
|
|
305
|
+
<span class="qss-truncate qss-text-slate-400 qss-text-size[11] qss-tree-row-name">${node.name}</span>
|
|
306
|
+
</div>
|
|
307
|
+
${statusDot}
|
|
308
|
+
`;
|
|
309
|
+
|
|
310
|
+
// Single click to select/highlight
|
|
311
|
+
file.addEventListener('click', () => {
|
|
312
|
+
document.querySelectorAll('.qss-tree-row.qss-selected').forEach(el => el.classList.remove('qss-selected', 'qss-bg-indigo-500/10'));
|
|
313
|
+
file.classList.add('qss-selected', 'qss-bg-indigo-500/10');
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
div.appendChild(file);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
return div;
|
|
320
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/* Generated from grammar.yml + config/parapet/qss_config.yml - DO NOT EDIT MANUALLY */
|
|
2
|
+
|
|
3
|
+
$qss-unit: 1px;
|
|
4
|
+
$qss-anchor: "#qss-canvas";
|
|
5
|
+
|
|
6
|
+
/* Overlay portal root; "" = rules scoped to the anchor only. */
|
|
7
|
+
$qss-portal-root: "#pp-portal-root";
|
|
8
|
+
|
|
9
|
+
$qss-palette: (
|
|
10
|
+
"black": #000000,
|
|
11
|
+
"white": #ffffff,
|
|
12
|
+
"transparent": transparent,
|
|
13
|
+
"none": none,
|
|
14
|
+
"slate-50": #f8fafc,
|
|
15
|
+
"slate-100": #f1f5f9,
|
|
16
|
+
"slate-200": #e2e8f0,
|
|
17
|
+
"slate-300": #cbd5e1,
|
|
18
|
+
"slate-400": #94a3b8,
|
|
19
|
+
"slate-500": #64748b,
|
|
20
|
+
"slate-600": #475569,
|
|
21
|
+
"slate-700": #334155,
|
|
22
|
+
"slate-800": #1e293b,
|
|
23
|
+
"slate-900": #0f172a,
|
|
24
|
+
"slate-950": #020617,
|
|
25
|
+
"rose-500": #f43f5e,
|
|
26
|
+
"brand-header": #1a1d23,
|
|
27
|
+
"brand-main": #0f1115,
|
|
28
|
+
"novice": #10b981,
|
|
29
|
+
"intermediate": #f59e0b,
|
|
30
|
+
"advanced": #6366f1,
|
|
31
|
+
"pro": #8b5cf6,
|
|
32
|
+
"power": #ec4899,
|
|
33
|
+
"shared": #64748b,
|
|
34
|
+
"floating": #94a3b8,
|
|
35
|
+
"indigo-300": #a5b4fc,
|
|
36
|
+
"indigo-400": #818cf8,
|
|
37
|
+
"indigo-500": #6366f1,
|
|
38
|
+
"indigo-600": #4f46e5,
|
|
39
|
+
"rose-400": #fb7185,
|
|
40
|
+
"rose-600": #e11d48,
|
|
41
|
+
"emerald-300": #6ee7b7,
|
|
42
|
+
"emerald-400": #34d399,
|
|
43
|
+
"emerald-500": #10b981,
|
|
44
|
+
"emerald-600": #059669,
|
|
45
|
+
"emerald-950": #064e3b,
|
|
46
|
+
"amber-200": #fde68a,
|
|
47
|
+
"amber-300": #fcd34d,
|
|
48
|
+
"amber-400": #fbbf24,
|
|
49
|
+
"amber-500": #f59e0b,
|
|
50
|
+
"amber-600": #d97706,
|
|
51
|
+
"blue-50": #eff6ff,
|
|
52
|
+
"blue-400": #60a5fa,
|
|
53
|
+
"blue-500": #3b82f6,
|
|
54
|
+
"blue-600": #2563eb,
|
|
55
|
+
"blue-700": #1d4ed8,
|
|
56
|
+
"blue-900": #1e3a8a,
|
|
57
|
+
"red-300": #fca5a5,
|
|
58
|
+
"red-400": #f87171,
|
|
59
|
+
"red-500": #ef4444,
|
|
60
|
+
"red-600": #dc2626,
|
|
61
|
+
"red-900": #7f1d1d,
|
|
62
|
+
"red-950": #450a0a,
|
|
63
|
+
"violet-300": #c4b5fd,
|
|
64
|
+
"violet-400": #a78bfa,
|
|
65
|
+
"violet-500": #8b5cf6,
|
|
66
|
+
"violet-600": #7c3aed,
|
|
67
|
+
"sky-400": #38bdf8,
|
|
68
|
+
"gray-100": #f3f4f6,
|
|
69
|
+
"gray-500": #6b7280,
|
|
70
|
+
"gray-600": #4b5563,
|
|
71
|
+
"orange-500": #f97316,
|
|
72
|
+
"yellow-500": #eab308,
|
|
73
|
+
"pink-500": #ec4899
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
$qss-depths: (
|
|
77
|
+
"canvas": 0,
|
|
78
|
+
"content": 100,
|
|
79
|
+
"ui": 500,
|
|
80
|
+
"overlay": 900,
|
|
81
|
+
"modal": 1000
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
$qss-quantization: (
|
|
85
|
+
"units": 1000,
|
|
86
|
+
"borders": 50
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
/* Text scale (item 2, SETTLED 2026-09-21). */
|
|
90
|
+
$qss-text-scale: (
|
|
91
|
+
"calibration-width": 1440,
|
|
92
|
+
"floor-px": 9,
|
|
93
|
+
"floor-multiplier": 0.875,
|
|
94
|
+
"cap-multiplier": 1.5
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
/* Non-text content scale (item 3, SETTLED 2026-09-21). */
|
|
98
|
+
$qss-content-scale: (
|
|
99
|
+
"calibration-width": 1440
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
/* Named-group registry (consumer-supplied). */
|
|
103
|
+
$qss-group-names: ("row", "eye", "focus", "mini-explorer", "new-menu", "link-menu", "btn");
|
|
104
|
+
|
|
105
|
+
$qss-breakpoints: (
|
|
106
|
+
"sm": 640px,
|
|
107
|
+
"md": 768px,
|
|
108
|
+
"lg": 1024px,
|
|
109
|
+
"xl": 1280px
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
$qss-vertical-breakpoints: (
|
|
113
|
+
"v-sm": 400px,
|
|
114
|
+
"v-md": 600px,
|
|
115
|
+
"v-lg": 800px,
|
|
116
|
+
"v-xl": 1000px
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
$qss-fonts: (
|
|
120
|
+
"sans": "Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif",
|
|
121
|
+
"mono": "'JetBrains Mono', 'Fira Code', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace"
|
|
122
|
+
);
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Parapet-side QSS styling (QSS item C, 2026-09-23).
|
|
3
|
+
* Project-specific rules moved out of qss_core.scss so the core carries no Parapet
|
|
4
|
+
* content. Imported by qss_application.scss AFTER qss_core (it uses the core's
|
|
5
|
+
* qss-dsl-boost / qss-group-boost / qss-state-boost mixins and $qss-palette).
|
|
6
|
+
* Not part of the QSS core / gem.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/* The QSS Stage: Parapet's shell background (core keeps the structural html/body rule). */
|
|
10
|
+
html, body {
|
|
11
|
+
background-color: map-get($qss-palette, "brand-main");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* Used by 6 Parapet files (search inputs, file editor, inspector, snippet library). */
|
|
15
|
+
@include qss-state-boost(".focus\\:qss-outline-none", "focus") { outline: none; }
|
|
16
|
+
|
|
17
|
+
/* Parapet's own named groups (_file_editor.html.erb portal dropdowns). Kept as a
|
|
18
|
+
local list, not in qss_config.yml group_names, so the generated accent-rule
|
|
19
|
+
count stays unchanged by this move. */
|
|
20
|
+
@each $group-name in ("mini-explorer", "new-menu", "link-menu") {
|
|
21
|
+
@include qss-group-boost(".group\\/#{$group-name}", "hover", ".group-hover\\/#{$group-name}\\:qss-block") { display: block; }
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/* Icon Atmosphere */
|
|
25
|
+
@include qss-dsl-boost(".qss-icon-folder") { color: map-get($qss-palette, "amber-500"); opacity: 0.8; }
|
|
26
|
+
@include qss-dsl-boost(".qss-icon-file") { color: map-get($qss-palette, "slate-500"); opacity: 0.6; }
|
|
27
|
+
@include qss-dsl-boost(".qss-icon-gem") { color: map-get($qss-palette, "rose-500"); opacity: 0.9; }
|
|
28
|
+
@include qss-dsl-boost(".qss-icon-box") { color: map-get($qss-palette, "indigo-500"); opacity: 0.8; }
|
|
29
|
+
@include qss-dsl-boost(".qss-icon-component") { color: map-get($qss-palette, "emerald-500"); opacity: 0.8; }
|
|
30
|
+
@include qss-dsl-boost(".qss-icon-activity") { color: map-get($qss-palette, "violet-500"); opacity: 0.8; }
|
|
31
|
+
|
|
32
|
+
/* Workbench Specifics */
|
|
33
|
+
.qss-inspector-selected {
|
|
34
|
+
outline: 2px solid map-get($qss-palette, "indigo-500");
|
|
35
|
+
outline-offset: -2px;
|
|
36
|
+
box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.2);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/* Phantom Object Reveal (Standard specificity) */
|
|
40
|
+
@include qss-dsl-boost(".qss-phantom-revealed") {
|
|
41
|
+
display: block;
|
|
42
|
+
visibility: visible;
|
|
43
|
+
opacity: 0.5;
|
|
44
|
+
outline: 2px dashed rgba(129, 140, 248, 0.5);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* Shell dimensions (item B, step 1).
|
|
48
|
+
*
|
|
49
|
+
* POLICY (Kraig, 2026-09-23): absolute lengths (px) for the Parapet shell live ONLY here, as named tokens; the
|
|
50
|
+
* markup references them and carries no raw lengths. Each token holds exactly the value that was previously a
|
|
51
|
+
* literal fallback in an inline style, and the properties themselves stay UNDEFINED (some are set at runtime by
|
|
52
|
+
* explorer-resizer.js, and --footer-h is also used locally by the file editor), so nothing else changes.
|
|
53
|
+
* Step 2 will express these in QSS units with clamp() bounds.
|
|
54
|
+
*/
|
|
55
|
+
:root {
|
|
56
|
+
--global-nav-w-default: 24px;
|
|
57
|
+
--explorer-bar-w-default: 260px; /* the explorer bar's own width */
|
|
58
|
+
--explorer-bar-offset-default: 200px; /* the width the workspace panes ASSUME for the bar. It differs from the line
|
|
59
|
+
above, so until a user drags the resizer the bar overlaps the workspace by
|
|
60
|
+
60px. Preserved as found; an open decision, not a design. */
|
|
61
|
+
--explorer-bar-min-w: calc(180 * var(--qnt)); /* QSS units, as at HEAD before the token rewrite */
|
|
62
|
+
--explorer-bar-max-w: calc(400 * var(--qnt));
|
|
63
|
+
--inspector-bar-w-default: 200px;
|
|
64
|
+
--code-source-h-default: 175px;
|
|
65
|
+
--footer-h-default: 15px;
|
|
66
|
+
--agent-interface-h-default: 150px;
|
|
67
|
+
--explorer-widgets-h-default: 120px;
|
|
68
|
+
--sidebar-header-h-default: 40px;
|
|
69
|
+
}
|