trackops 1.0.0 → 1.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.
- package/README.md +341 -232
- package/bin/trackops.js +102 -70
- package/lib/config.js +260 -35
- package/lib/control.js +518 -475
- package/lib/env.js +227 -0
- package/lib/i18n.js +61 -53
- package/lib/init.js +146 -55
- package/lib/locale.js +63 -0
- package/lib/opera-bootstrap.js +523 -0
- package/lib/opera.js +319 -170
- package/lib/registry.js +27 -13
- package/lib/release.js +56 -0
- package/lib/resources.js +42 -0
- package/lib/server.js +912 -418
- package/lib/skills.js +148 -124
- package/lib/workspace.js +260 -0
- package/locales/en.json +331 -139
- package/locales/es.json +331 -139
- package/package.json +14 -3
- package/scripts/skills-marketplace-smoke.js +124 -0
- package/scripts/smoke-tests.js +445 -0
- package/scripts/sync-skill-version.js +21 -0
- package/scripts/validate-skill.js +88 -0
- package/skills/trackops/SKILL.md +64 -0
- package/skills/trackops/agents/openai.yaml +3 -0
- package/skills/trackops/references/activation.md +39 -0
- package/skills/trackops/references/troubleshooting.md +34 -0
- package/skills/trackops/references/workflow.md +20 -0
- package/skills/trackops/scripts/bootstrap-trackops.js +201 -0
- package/skills/trackops/skill.json +29 -0
- package/templates/etapa/agent.md +2 -2
- package/templates/etapa/references/etapa-cycle.md +1 -1
- package/templates/opera/agent.md +1 -1
- package/templates/opera/en/agent.md +26 -0
- package/templates/opera/en/genesis.md +79 -0
- package/templates/opera/en/references/autonomy-and-recovery.md +23 -0
- package/templates/opera/en/references/opera-cycle.md +62 -0
- package/templates/opera/en/registry.md +28 -0
- package/templates/opera/en/router.md +39 -0
- package/templates/opera/genesis.md +79 -94
- package/templates/skills/changelog-updater/locales/en/SKILL.md +11 -0
- package/templates/skills/commiter/locales/en/SKILL.md +11 -0
- package/templates/skills/project-starter-skill/SKILL.md +5 -3
- package/templates/skills/project-starter-skill/locales/en/SKILL.md +24 -0
- package/ui/css/base.css +266 -0
- package/ui/css/charts.css +327 -0
- package/ui/css/components.css +570 -0
- package/ui/css/panels.css +956 -0
- package/ui/css/tokens.css +227 -0
- package/ui/favicon.svg +5 -0
- package/ui/index.html +91 -351
- package/ui/js/api.js +220 -0
- package/ui/js/app.js +200 -0
- package/ui/js/console-logger.js +172 -0
- package/ui/js/i18n.js +14 -0
- package/ui/js/icons.js +104 -0
- package/ui/js/onboarding.js +439 -0
- package/ui/js/router.js +125 -0
- package/ui/js/state.js +130 -0
- package/ui/js/theme.js +100 -0
- package/ui/js/time-tracker.js +248 -0
- package/ui/js/utils.js +175 -0
- package/ui/js/views/board.js +255 -0
- package/ui/js/views/execution.js +256 -0
- package/ui/js/views/flash.js +47 -0
- package/ui/js/views/insights.js +340 -0
- package/ui/js/views/overview.js +365 -0
- package/ui/js/views/settings.js +381 -0
- package/ui/js/views/sidebar.js +131 -0
- package/ui/js/views/skills.js +163 -0
- package/ui/js/views/tasks.js +406 -0
- package/ui/js/views/topbar.js +239 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Skills Router
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
This file defines the routing rules between the main agent and the available skills. When the agent detects a specific context, it should consult these rules and choose the right skill.
|
|
5
|
+
|
|
6
|
+
## Routing Rules
|
|
7
|
+
|
|
8
|
+
### Context: Code commit
|
|
9
|
+
- **Trigger**: The user asks for a commit or a code change has just been completed.
|
|
10
|
+
- **Skill**: `commiter`
|
|
11
|
+
- **Action**: Use the skill to format the commit message.
|
|
12
|
+
|
|
13
|
+
### Context: Post-commit
|
|
14
|
+
- **Trigger**: A successful commit has just happened.
|
|
15
|
+
- **Skill**: `changelog-updater`
|
|
16
|
+
- **Action**: Run the changelog update flow.
|
|
17
|
+
|
|
18
|
+
### Context: Project initialization
|
|
19
|
+
- **Trigger**: The user wants to create a new project.
|
|
20
|
+
- **Skill**: `project-starter-skill` (global)
|
|
21
|
+
- **Action**: Run the full initialization protocol.
|
|
22
|
+
|
|
23
|
+
### Context: Operational tracking
|
|
24
|
+
- **Trigger**: A work block is about to start, resume, or close.
|
|
25
|
+
- **Skill**: No external skill.
|
|
26
|
+
- **Action**: Run `trackops status`, take the next task with `trackops next`, and keep `project_control.json` as the operational source of truth.
|
|
27
|
+
|
|
28
|
+
## Adding New Rules
|
|
29
|
+
|
|
30
|
+
Use this format for each new rule:
|
|
31
|
+
|
|
32
|
+
```markdown
|
|
33
|
+
### Context: [description]
|
|
34
|
+
- **Trigger**: [what activates the rule]
|
|
35
|
+
- **Skill**: [skill name]
|
|
36
|
+
- **Action**: [what the agent should do]
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
When a new skill is installed with `trackops skill install <name>`, add its routing rule here.
|
|
@@ -1,94 +1,79 @@
|
|
|
1
|
-
# {{PROJECT_NAME}} — Genesis
|
|
2
|
-
|
|
3
|
-
> **La Constitución del proyecto.** Este documento es la fuente de verdad. Antes de tomar cualquier decisión arquitectónica o de implementación, consulta este archivo. Si un script contradice lo definido aquí, el script está mal.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 1. Directriz Principal
|
|
8
|
-
|
|
9
|
-
_¿Cuál es el resultado singular deseado de este proyecto?_
|
|
10
|
-
|
|
11
|
-
>
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## 2. Integraciones Externas
|
|
16
|
-
|
|
17
|
-
_¿Qué servicios externos necesitamos? ¿Están listas las claves?_
|
|
18
|
-
|
|
19
|
-
| Servicio | Estado | Clave / Config |
|
|
20
|
-
|----------|--------|----------------|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## 3. Fuente de la Verdad
|
|
26
|
-
|
|
27
|
-
_¿Dónde viven los datos primarios?_
|
|
28
|
-
|
|
29
|
-
>
|
|
30
|
-
|
|
31
|
-
---
|
|
32
|
-
|
|
33
|
-
## 4. Carga Útil (Payload)
|
|
34
|
-
|
|
35
|
-
_¿Cómo y dónde debe entregarse el resultado final?_
|
|
36
|
-
|
|
37
|
-
>
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
## 5. Reglas de Comportamiento
|
|
42
|
-
|
|
43
|
-
_Restricciones, tono y reglas específicas del dominio._
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
---
|
|
48
|
-
|
|
49
|
-
## Esquema de Datos
|
|
50
|
-
|
|
51
|
-
> **Regla "Datos-Primero"**: Este schema debe estar definido antes de escribir cualquier código.
|
|
52
|
-
|
|
53
|
-
```json
|
|
54
|
-
{
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
<!-- Ejemplo:
|
|
81
|
-
### tool_fetch.py → tool_transform.py
|
|
82
|
-
- Output: `.tmp/raw_data.json`
|
|
83
|
-
- Formato: JSON array según schema X
|
|
84
|
-
-->
|
|
85
|
-
|
|
86
|
-
---
|
|
87
|
-
|
|
88
|
-
## Templates
|
|
89
|
-
|
|
90
|
-
_Referencias a las plantillas de output definidas en `templates/`._
|
|
91
|
-
|
|
92
|
-
<!-- Ejemplo:
|
|
93
|
-
- `templates/report.md` — Plantilla para reportes
|
|
94
|
-
-->
|
|
1
|
+
# {{PROJECT_NAME}} — Genesis
|
|
2
|
+
|
|
3
|
+
> **La Constitución del proyecto.** Este documento es la fuente de verdad. Antes de tomar cualquier decisión arquitectónica o de implementación, consulta este archivo. Si un script contradice lo definido aquí, el script está mal.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Directriz Principal
|
|
8
|
+
|
|
9
|
+
_¿Cuál es el resultado singular deseado de este proyecto?_
|
|
10
|
+
|
|
11
|
+
> {{DESIRED_OUTCOME}}
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 2. Integraciones Externas
|
|
16
|
+
|
|
17
|
+
_¿Qué servicios externos necesitamos? ¿Están listas las claves?_
|
|
18
|
+
|
|
19
|
+
| Servicio | Estado | Clave / Config |
|
|
20
|
+
|----------|--------|----------------|
|
|
21
|
+
{{SERVICES_TABLE}}
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 3. Fuente de la Verdad
|
|
26
|
+
|
|
27
|
+
_¿Dónde viven los datos primarios?_
|
|
28
|
+
|
|
29
|
+
> {{SOURCE_OF_TRUTH}}
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 4. Carga Útil (Payload)
|
|
34
|
+
|
|
35
|
+
_¿Cómo y dónde debe entregarse el resultado final?_
|
|
36
|
+
|
|
37
|
+
> {{PAYLOAD}}
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## 5. Reglas de Comportamiento
|
|
42
|
+
|
|
43
|
+
_Restricciones, tono y reglas específicas del dominio._
|
|
44
|
+
|
|
45
|
+
{{BEHAVIOR_RULES}}
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Esquema de Datos
|
|
50
|
+
|
|
51
|
+
> **Regla "Datos-Primero"**: Este schema debe estar definido antes de escribir cualquier código.
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{{DATA_SCHEMA}}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Invariantes Arquitectónicas
|
|
60
|
+
|
|
61
|
+
_Decisiones técnicas inamovibles. Cambiarlas requiere aprobación explícita (Nivel Rojo)._
|
|
62
|
+
|
|
63
|
+
{{ARCHITECTURAL_INVARIANTS}}
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Pipeline
|
|
68
|
+
|
|
69
|
+
_Documenta el grafo de dependencias entre herramientas._
|
|
70
|
+
|
|
71
|
+
{{PIPELINE_ITEMS}}
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Templates
|
|
76
|
+
|
|
77
|
+
_Referencias a las plantillas de output definidas en `templates/`._
|
|
78
|
+
|
|
79
|
+
{{TEMPLATE_ITEMS}}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "changelog-updater"
|
|
3
|
+
description: "Automatically update CHANGELOG.md from the latest commit after a successful commit."
|
|
4
|
+
metadata:
|
|
5
|
+
version: "1.0"
|
|
6
|
+
type: "project"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Changelog Updater
|
|
10
|
+
|
|
11
|
+
Use this skill right after a successful commit to update `CHANGELOG.md` from the git history. It should parse the latest commit, classify it using Conventional Commit semantics, and append the entry to the proper dated section.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "commiter"
|
|
3
|
+
description: "Generate commit messages in English following strict Conventional Commits rules with emojis."
|
|
4
|
+
metadata:
|
|
5
|
+
version: "1.0"
|
|
6
|
+
type: "project"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Commit Writer
|
|
10
|
+
|
|
11
|
+
Use this skill whenever a commit message must be generated. The message must follow Conventional Commits, keep the scope explicit when relevant, and preserve the emoji convention used by the project.
|
|
@@ -156,10 +156,12 @@ proyecto/
|
|
|
156
156
|
│ ├── hub/
|
|
157
157
|
│ │ ├── agent.md # Instrucciones del agente
|
|
158
158
|
│ │ └── router.md # Enrutamiento a skills
|
|
159
|
-
│ └──
|
|
160
|
-
│
|
|
159
|
+
│ └── hub/
|
|
160
|
+
│ ├── agent.md # Instrucciones del agente
|
|
161
|
+
│ └── router.md # Enrutamiento a skills
|
|
161
162
|
├── .agents/
|
|
162
163
|
│ └── skills/
|
|
164
|
+
│ ├── _registry.md # Índice de skills instaladas
|
|
163
165
|
│ └── [skill-name]/
|
|
164
166
|
│ └── SKILL.md # Contenido de skills
|
|
165
167
|
├── genesis.md # 📜 La Constitución
|
|
@@ -191,7 +193,7 @@ proyecto/
|
|
|
191
193
|
- [ ] findings.md generado
|
|
192
194
|
- [ ] .agent/hub/agent.md configurado
|
|
193
195
|
- [ ] .agent/hub/router.md configurado
|
|
194
|
-
- [ ] .
|
|
196
|
+
- [ ] .agents/skills/_registry.md creado
|
|
195
197
|
- [ ] Skills base instaladas (commiter, changelog-updater)
|
|
196
198
|
- [ ] Repositorio GitHub creado
|
|
197
199
|
- [ ] README.md generado
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "project-starter-skill"
|
|
3
|
+
description: "Global skill to initialize complete projects using the O.P.E.R.A. protocol. Use it when the user wants to start a new project, scaffold a repo, initialize an agent structure, or kick off a new automation."
|
|
4
|
+
metadata:
|
|
5
|
+
version: "3.0"
|
|
6
|
+
type: "global"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Project Starter Skill
|
|
10
|
+
|
|
11
|
+
You are the system pilot. Your job is to initialize deterministic, recoverable projects under the O.P.E.R.A. protocol.
|
|
12
|
+
|
|
13
|
+
## Protocol
|
|
14
|
+
|
|
15
|
+
1. Ask discovery questions about the desired outcome, integrations, source of truth, payload, and behavior rules.
|
|
16
|
+
2. Run `npx trackops init --with-opera`.
|
|
17
|
+
3. Populate `genesis.md` with schemas, constraints, and invariants.
|
|
18
|
+
4. Regenerate docs with `trackops sync` and refine the plan.
|
|
19
|
+
5. Ensure base skills are present: `commiter` and `changelog-updater`.
|
|
20
|
+
6. Suggest optional repo governance tasks if needed.
|
|
21
|
+
|
|
22
|
+
## Rule
|
|
23
|
+
|
|
24
|
+
Do not write delivery code before the data contract exists in `genesis.md`.
|
package/ui/css/base.css
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
/* ═══════════════════════════════════════════════════════
|
|
2
|
+
BASE — Reset + Layout + Tipografía global
|
|
3
|
+
═══════════════════════════════════════════════════════ */
|
|
4
|
+
|
|
5
|
+
/* ── Google Fonts se cargan en index.html ── */
|
|
6
|
+
|
|
7
|
+
*, *::before, *::after {
|
|
8
|
+
box-sizing: border-box;
|
|
9
|
+
margin: 0;
|
|
10
|
+
padding: 0;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
html {
|
|
14
|
+
font-size: 16px;
|
|
15
|
+
scroll-behavior: smooth;
|
|
16
|
+
-webkit-text-size-adjust: 100%;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
body {
|
|
20
|
+
font-family: var(--font-ui);
|
|
21
|
+
font-size: var(--text-base);
|
|
22
|
+
color: var(--text-primary);
|
|
23
|
+
background-color: var(--surface-0);
|
|
24
|
+
line-height: 1.55;
|
|
25
|
+
min-height: 100dvh;
|
|
26
|
+
overflow-x: hidden;
|
|
27
|
+
-webkit-font-smoothing: antialiased;
|
|
28
|
+
-moz-osx-font-smoothing: grayscale;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/* ── Accesibilidad: Skip link ── */
|
|
32
|
+
.skip-link {
|
|
33
|
+
position: absolute;
|
|
34
|
+
top: -100%;
|
|
35
|
+
left: var(--space-4);
|
|
36
|
+
z-index: var(--z-onboard);
|
|
37
|
+
padding: var(--space-2) var(--space-4);
|
|
38
|
+
background: var(--accent);
|
|
39
|
+
color: white;
|
|
40
|
+
font-weight: 700;
|
|
41
|
+
font-size: var(--text-sm);
|
|
42
|
+
border-radius: var(--radius-md);
|
|
43
|
+
text-decoration: none;
|
|
44
|
+
transition: top var(--duration-base) var(--ease-out);
|
|
45
|
+
}
|
|
46
|
+
.skip-link:focus {
|
|
47
|
+
top: var(--space-4);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* ── Accesibilidad: Visually hidden ── */
|
|
51
|
+
.sr-only {
|
|
52
|
+
position: absolute;
|
|
53
|
+
width: 1px;
|
|
54
|
+
height: 1px;
|
|
55
|
+
padding: 0;
|
|
56
|
+
margin: -1px;
|
|
57
|
+
overflow: hidden;
|
|
58
|
+
clip: rect(0,0,0,0);
|
|
59
|
+
white-space: nowrap;
|
|
60
|
+
border: 0;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/* ── Layout principal: sidebar fija + contenido ── */
|
|
64
|
+
.app-shell {
|
|
65
|
+
display: grid;
|
|
66
|
+
grid-template-columns: var(--sidebar-width) 1fr;
|
|
67
|
+
grid-template-rows: var(--topbar-height) 1fr;
|
|
68
|
+
grid-template-areas:
|
|
69
|
+
"sidebar topbar"
|
|
70
|
+
"sidebar content";
|
|
71
|
+
min-height: 100dvh;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
#sidebar {
|
|
75
|
+
grid-area: sidebar;
|
|
76
|
+
position: fixed;
|
|
77
|
+
top: 0;
|
|
78
|
+
left: 0;
|
|
79
|
+
width: var(--sidebar-width);
|
|
80
|
+
height: 100dvh;
|
|
81
|
+
z-index: var(--z-sidebar);
|
|
82
|
+
overflow-y: auto;
|
|
83
|
+
overflow-x: hidden;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
#topbar {
|
|
87
|
+
grid-area: topbar;
|
|
88
|
+
position: sticky;
|
|
89
|
+
top: 0;
|
|
90
|
+
z-index: var(--z-topbar);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
#view-container {
|
|
94
|
+
grid-area: content;
|
|
95
|
+
padding: var(--content-pad);
|
|
96
|
+
min-height: calc(100dvh - var(--topbar-height));
|
|
97
|
+
overflow-y: auto;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/* ── Tipografía ── */
|
|
101
|
+
h1, h2, h3, h4, h5, h6 {
|
|
102
|
+
font-family: var(--font-heading);
|
|
103
|
+
font-weight: 700;
|
|
104
|
+
line-height: 1.15;
|
|
105
|
+
letter-spacing: -0.02em;
|
|
106
|
+
color: var(--text-primary);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
h1 { font-size: var(--text-3xl); }
|
|
110
|
+
h2 { font-size: var(--text-2xl); }
|
|
111
|
+
h3 { font-size: var(--text-xl); }
|
|
112
|
+
h4 { font-size: var(--text-lg); }
|
|
113
|
+
h5 { font-size: var(--text-md); }
|
|
114
|
+
h6 { font-size: var(--text-base); }
|
|
115
|
+
|
|
116
|
+
p { margin: 0; }
|
|
117
|
+
|
|
118
|
+
code, pre, .mono {
|
|
119
|
+
font-family: var(--font-mono);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
a {
|
|
123
|
+
color: var(--accent);
|
|
124
|
+
text-decoration: none;
|
|
125
|
+
transition: color var(--duration-fast) var(--ease-out);
|
|
126
|
+
}
|
|
127
|
+
a:hover { color: var(--accent-hover); }
|
|
128
|
+
|
|
129
|
+
button, input, textarea, select {
|
|
130
|
+
font: inherit;
|
|
131
|
+
color: inherit;
|
|
132
|
+
}
|
|
133
|
+
button { cursor: pointer; border: none; background: none; }
|
|
134
|
+
|
|
135
|
+
img, svg { display: block; max-width: 100%; }
|
|
136
|
+
|
|
137
|
+
ul, ol { list-style: none; }
|
|
138
|
+
|
|
139
|
+
/* ── Scrollbars personalizadas (idénticas a la web) ── */
|
|
140
|
+
::-webkit-scrollbar { width: 5px; height: 5px; }
|
|
141
|
+
::-webkit-scrollbar-track { background: var(--surface-1); }
|
|
142
|
+
::-webkit-scrollbar-thumb { background: var(--surface-3); border-radius: var(--radius-full); }
|
|
143
|
+
::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }
|
|
144
|
+
|
|
145
|
+
/* ── Focus outline accesible ── */
|
|
146
|
+
:focus-visible {
|
|
147
|
+
outline: 2px solid var(--accent);
|
|
148
|
+
outline-offset: 2px;
|
|
149
|
+
border-radius: var(--radius-xs);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/* ── Selección de texto ── */
|
|
153
|
+
::selection {
|
|
154
|
+
background: var(--accent);
|
|
155
|
+
color: white;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/* ── Animaciones de entrada ── */
|
|
159
|
+
@keyframes fadeInUp {
|
|
160
|
+
from { opacity: 0; transform: translateY(12px); }
|
|
161
|
+
to { opacity: 1; transform: translateY(0); }
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
@keyframes fadeIn {
|
|
165
|
+
from { opacity: 0; }
|
|
166
|
+
to { opacity: 1; }
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
@keyframes pulse {
|
|
170
|
+
0%, 100% { opacity: 1; }
|
|
171
|
+
50% { opacity: 0.5; }
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
@keyframes spin {
|
|
175
|
+
to { transform: rotate(360deg); }
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
@keyframes slideInRight {
|
|
179
|
+
from { opacity: 0; transform: translateX(20px); }
|
|
180
|
+
to { opacity: 1; transform: translateX(0); }
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
@keyframes slideInLeft {
|
|
184
|
+
from { opacity: 0; transform: translateX(-20px); }
|
|
185
|
+
to { opacity: 1; transform: translateX(0); }
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
@keyframes dash {
|
|
189
|
+
to { stroke-dashoffset: 0; }
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
@keyframes barGrow {
|
|
193
|
+
from { transform: scaleX(0); }
|
|
194
|
+
to { transform: scaleX(1); }
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
@keyframes heightGrow {
|
|
198
|
+
from { transform: scaleY(0); }
|
|
199
|
+
to { transform: scaleY(1); }
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/* ── Clases de utilidad ── */
|
|
203
|
+
.view-enter { animation: fadeInUp var(--duration-slow) var(--ease-out) both; }
|
|
204
|
+
.stagger-1 { animation-delay: 0.05s; }
|
|
205
|
+
.stagger-2 { animation-delay: 0.10s; }
|
|
206
|
+
.stagger-3 { animation-delay: 0.15s; }
|
|
207
|
+
.stagger-4 { animation-delay: 0.20s; }
|
|
208
|
+
.stagger-5 { animation-delay: 0.25s; }
|
|
209
|
+
|
|
210
|
+
.truncate {
|
|
211
|
+
overflow: hidden;
|
|
212
|
+
text-overflow: ellipsis;
|
|
213
|
+
white-space: nowrap;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.eyebrow {
|
|
217
|
+
font-size: var(--text-xs);
|
|
218
|
+
font-weight: 700;
|
|
219
|
+
letter-spacing: 0.12em;
|
|
220
|
+
text-transform: uppercase;
|
|
221
|
+
color: var(--accent);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.label-sm {
|
|
225
|
+
font-size: var(--text-xs);
|
|
226
|
+
font-weight: 600;
|
|
227
|
+
letter-spacing: 0.06em;
|
|
228
|
+
text-transform: uppercase;
|
|
229
|
+
color: var(--text-muted);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.text-muted { color: var(--text-muted); }
|
|
233
|
+
.text-second { color: var(--text-secondary); }
|
|
234
|
+
.text-accent { color: var(--accent); }
|
|
235
|
+
.text-success { color: var(--success); }
|
|
236
|
+
.text-warning { color: var(--warning); }
|
|
237
|
+
.text-danger { color: var(--danger); }
|
|
238
|
+
|
|
239
|
+
/* ── Responsive: sidebar colapsable en pantallas menores a 1024px ── */
|
|
240
|
+
@media (max-width: 1024px) {
|
|
241
|
+
.app-shell {
|
|
242
|
+
grid-template-columns: 1fr;
|
|
243
|
+
grid-template-areas:
|
|
244
|
+
"topbar"
|
|
245
|
+
"content";
|
|
246
|
+
}
|
|
247
|
+
#sidebar {
|
|
248
|
+
transform: translateX(-100%);
|
|
249
|
+
transition: transform var(--duration-slow) var(--ease-out);
|
|
250
|
+
}
|
|
251
|
+
#sidebar.is-open {
|
|
252
|
+
transform: translateX(0);
|
|
253
|
+
box-shadow: var(--shadow-xl);
|
|
254
|
+
}
|
|
255
|
+
#view-container {
|
|
256
|
+
padding: var(--space-4);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/* ── Divider ── */
|
|
261
|
+
.divider {
|
|
262
|
+
height: 1px;
|
|
263
|
+
background: var(--border);
|
|
264
|
+
border: none;
|
|
265
|
+
margin: var(--space-4) 0;
|
|
266
|
+
}
|