diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index eb19727..0056372 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -45,7 +45,7 @@ jobs: - name: Setup Pages uses: actions/configure-pages@v4 - name: Upload artifact - uses: actions/upload-pages-artifact@v5 + uses: actions/upload-pages-artifact@v3 with: # Upload entire repository path: '.' diff --git a/404.html b/404.html deleted file mode 100644 index 005b0df..0000000 --- a/404.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - 404 - Spatial Data Not Found | DevGiz - - - - -
-

404

-

// Error_Coordinates_Invalid: The requested spatial node does not exist in our database.

-
- Return to Base -
-
- - - \ No newline at end of file diff --git a/Skills/analyze-project/SKILL.md b/Skills/analyze-project/SKILL.md deleted file mode 100644 index 20e8dae..0000000 --- a/Skills/analyze-project/SKILL.md +++ /dev/null @@ -1,432 +0,0 @@ ---- -name: analyze-project -description: Forensic root cause analyzer for Antigravity sessions. Classifies scope deltas, rework patterns, root causes, hotspots, and auto-improves prompts/health. -version: "1.0" -tags: [analysis, diagnostics, meta, root-cause, project-health, session-review] ---- - -# /analyze-project — Root Cause Analyst Workflow - -Analyze AI-assisted coding sessions in `~/.gemini/antigravity/brain/` and produce a report that explains not just **what happened**, but **why it happened**, **who/what caused it**, and **what should change next time**. - -## Goal - -For each session, determine: - -1. What changed from the initial ask to the final executed work -2. Whether the main cause was: - - user/spec - - agent - - repo/codebase - - validation/testing - - legitimate task complexity -3. Whether the opening prompt was sufficient -4. Which files/subsystems repeatedly correlate with struggle -5. What changes would most improve future sessions - -## Global Rules - -- Treat `.resolved.N` counts as **iteration signals**, not proof of failure -- Separate **human-added scope**, **necessary discovered scope**, and **agent-introduced scope** -- Separate **agent error** from **repo friction** -- Every diagnosis must include **evidence** and **confidence** -- Confidence levels: - - **High** = direct artifact/timestamp evidence - - **Medium** = multiple supporting signals - - **Low** = plausible inference, not directly proven -- Evidence precedence: - - artifact contents > timestamps > metadata summaries > inference -- If evidence is weak, say so - ---- - -## Step 0.5: Session Intent Classification - -Classify the primary session intent from objective + artifacts: - -- `DELIVERY` -- `DEBUGGING` -- `REFACTOR` -- `RESEARCH` -- `EXPLORATION` -- `AUDIT_ANALYSIS` - -Record: -- `session_intent` -- `session_intent_confidence` - -Use intent to contextualize severity and rework shape. -Do not judge exploratory or research sessions by the same standards as narrow delivery sessions. - ---- - -## Step 1: Discover Conversations - -1. Read available conversation summaries from system context -2. List conversation folders in the user’s Antigravity `brain/` directory -3. Build a conversation index with: - - `conversation_id` - - `title` - - `objective` - - `created` - - `last_modified` -4. If the user supplied a keyword/path, filter to matching conversations; otherwise analyze all - -Output: indexed list of conversations to analyze. - ---- - -## Step 2: Extract Session Evidence - -For each conversation, read if present: - -### Core artifacts -- `task.md` -- `implementation_plan.md` -- `walkthrough.md` - -### Metadata -- `*.metadata.json` - -### Version snapshots -- `task.md.resolved.0 ... N` -- `implementation_plan.md.resolved.0 ... N` -- `walkthrough.md.resolved.0 ... N` - -### Additional signals -- other `.md` artifacts -- timestamps across artifact updates -- file/folder/subsystem names mentioned in plans/walkthroughs -- validation/testing language -- explicit acceptance criteria, constraints, non-goals, and file targets - -Record per conversation: - -#### Lifecycle -- `has_task` -- `has_plan` -- `has_walkthrough` -- `is_completed` -- `is_abandoned_candidate` = task exists but no walkthrough - -#### Revision / change volume -- `task_versions` -- `plan_versions` -- `walkthrough_versions` -- `extra_artifacts` - -#### Scope -- `task_items_initial` -- `task_items_final` -- `task_completed_pct` -- `scope_delta_raw` -- `scope_creep_pct_raw` - -#### Timing -- `created_at` -- `completed_at` -- `duration_minutes` - -#### Content / quality -- `objective_text` -- `initial_plan_summary` -- `final_plan_summary` -- `initial_task_excerpt` -- `final_task_excerpt` -- `walkthrough_summary` -- `mentioned_files_or_subsystems` -- `validation_requirements_present` -- `acceptance_criteria_present` -- `non_goals_present` -- `scope_boundaries_present` -- `file_targets_present` -- `constraints_present` - ---- - -## Step 3: Prompt Sufficiency - -Score the opening request on a 0–2 scale for: - -- **Clarity** -- **Boundedness** -- **Testability** -- **Architectural specificity** -- **Constraint awareness** -- **Dependency awareness** - -Create: -- `prompt_sufficiency_score` -- `prompt_sufficiency_band` = High / Medium / Low - -Then note which missing prompt ingredients likely contributed to later friction. - -Do not punish short prompts by default; a narrow, obvious task can still have high sufficiency. - ---- - -## Step 4: Scope Change Classification - -Classify scope change into: - -- **Human-added scope** — new asks beyond the original task -- **Necessary discovered scope** — work required to complete the original task correctly -- **Agent-introduced scope** — likely unnecessary work introduced by the agent - -Record: -- `scope_change_type_primary` -- `scope_change_type_secondary` (optional) -- `scope_change_confidence` -- evidence - -Keep one short example in mind for calibration: -- Human-added: “also refactor nearby code while you’re here” -- Necessary discovered: hidden dependency must be fixed for original task to work -- Agent-introduced: extra cleanup or redesign not requested and not required - ---- - -## Step 5: Rework Shape - -Classify each session into one primary pattern: - -- **Clean execution** -- **Early replan then stable finish** -- **Progressive scope expansion** -- **Reopen/reclose churn** -- **Late-stage verification churn** -- **Abandoned mid-flight** -- **Exploratory / research session** - -Record: -- `rework_shape` -- `rework_shape_confidence` -- evidence - ---- - -## Step 6: Root Cause Analysis - -For every non-clean session, assign: - -### Primary root cause -One of: -- `SPEC_AMBIGUITY` -- `HUMAN_SCOPE_CHANGE` -- `REPO_FRAGILITY` -- `AGENT_ARCHITECTURAL_ERROR` -- `VERIFICATION_CHURN` -- `LEGITIMATE_TASK_COMPLEXITY` - -### Secondary root cause -Optional if materially relevant - -### Root-cause guidance -- **SPEC_AMBIGUITY**: opening ask lacked boundaries, targets, criteria, or constraints -- **HUMAN_SCOPE_CHANGE**: scope expanded because the user broadened the task -- **REPO_FRAGILITY**: hidden coupling, brittle files, unclear architecture, or environment issues forced extra work -- **AGENT_ARCHITECTURAL_ERROR**: wrong files, wrong assumptions, wrong approach, hallucinated structure -- **VERIFICATION_CHURN**: implementation mostly worked, but testing/validation caused loops -- **LEGITIMATE_TASK_COMPLEXITY**: revisions were expected for the difficulty and not clearly avoidable - -Every root-cause assignment must include: -- evidence -- why stronger alternative causes were rejected -- confidence - ---- - -## Step 6.5: Session Severity Scoring (0–100) - -Assign each session a severity score to prioritize attention. - -Components (sum, clamp 0–100): -- **Completion failure**: 0–25 (`abandoned = 25`) -- **Replanning intensity**: 0–15 -- **Scope instability**: 0–15 -- **Rework shape severity**: 0–15 -- **Prompt sufficiency deficit**: 0–10 (`low = 10`) -- **Root cause impact**: 0–10 (`REPO_FRAGILITY` / `AGENT_ARCHITECTURAL_ERROR` highest) -- **Hotspot recurrence**: 0–10 - -Bands: -- **0–19 Low** -- **20–39 Moderate** -- **40–59 Significant** -- **60–79 High** -- **80–100 Critical** - -Record: -- `session_severity_score` -- `severity_band` -- `severity_drivers` = top 2–4 contributors -- `severity_confidence` - -Use severity as a prioritization signal, not a verdict. Always explain the drivers. -Contextualize severity using session intent so research/exploration sessions are not over-penalized. - ---- - -## Step 7: Subsystem / File Clustering - -Across all conversations, cluster repeated struggle by file, folder, or subsystem. - -For each cluster, calculate: -- number of conversations touching it -- average revisions -- completion rate -- abandonment rate -- common root causes -- average severity - -Goal: identify whether friction is mostly prompt-driven, agent-driven, or concentrated in specific repo areas. - ---- - -## Step 8: Comparative Cohorts - -Compare: -- first-shot successes vs re-planned sessions -- completed vs abandoned -- high prompt sufficiency vs low prompt sufficiency -- narrow-scope vs high-scope-growth -- short sessions vs long sessions -- low-friction subsystems vs high-friction subsystems - -For each comparison, identify: -- what differs materially -- which prompt traits correlate with smoother execution -- which repo traits correlate with repeated struggle - -Do not just restate averages; extract cautious evidence-backed patterns. - ---- - -## Step 9: Non-Obvious Findings - -Generate 3–7 findings that are not simple metric restatements. - -Each finding must include: -- observation -- why it matters -- evidence -- confidence - -Examples of strong findings: -- replans cluster around weak file targeting rather than weak acceptance criteria -- scope growth often begins after initial success, suggesting post-success human expansion -- auth-related struggle is driven more by repo fragility than agent hallucination - ---- - -## Step 10: Report Generation - -Create `session_analysis_report.md` with this structure: - -# 📊 Session Analysis Report — [Project Name] - -**Generated**: [timestamp] -**Conversations Analyzed**: [N] -**Date Range**: [earliest] → [latest] - -## Executive Summary - -| Metric | Value | Rating | -|:---|:---|:---| -| First-Shot Success Rate | X% | 🟢/🟡/🔴 | -| Completion Rate | X% | 🟢/🟡/🔴 | -| Avg Scope Growth | X% | 🟢/🟡/🔴 | -| Replan Rate | X% | 🟢/🟡/🔴 | -| Median Duration | Xm | — | -| Avg Session Severity | X | 🟢/🟡/🔴 | -| High-Severity Sessions | X / N | 🟢/🟡/🔴 | - -Thresholds: -- First-shot: 🟢 >70 / 🟡 40–70 / 🔴 <40 -- Scope growth: 🟢 <15 / 🟡 15–40 / 🔴 >40 -- Replan rate: 🟢 <20 / 🟡 20–50 / 🔴 >50 - -Avg severity guidance: -- 🟢 <25 -- 🟡 25–50 -- 🔴 >50 - -Note: avg severity is an aggregate health signal, not the same as per-session severity bands. - -Then add a short narrative summary of what is going well, what is breaking down, and whether the main issue is prompt quality, repo fragility, workflow discipline, or validation churn. - -## Root Cause Breakdown - -| Root Cause | Count | % | Notes | -|:---|:---|:---|:---| - -## Prompt Sufficiency Analysis -- common traits of high-sufficiency prompts -- common missing inputs in low-sufficiency prompts -- which missing prompt ingredients correlate most with replanning or abandonment - -## Scope Change Analysis -Separate: -- Human-added scope -- Necessary discovered scope -- Agent-introduced scope - -## Rework Shape Analysis -Summarize the main failure patterns across sessions. - -## Friction Hotspots -Show the files/folders/subsystems most associated with replanning, abandonment, verification churn, and high severity. - -## First-Shot Successes -List the cleanest sessions and extract what made them work. - -## Non-Obvious Findings -List 3–7 evidence-backed findings with confidence. - -## Severity Triage -List the highest-severity sessions and say whether the best intervention is: -- prompt improvement -- scope discipline -- targeted skill/workflow -- repo refactor / architecture cleanup -- validation/test harness improvement - -## Recommendations -For each recommendation, use: -- **Observed pattern** -- **Likely cause** -- **Evidence** -- **Change to make** -- **Expected benefit** -- **Confidence** - -## Per-Conversation Breakdown - -| # | Title | Intent | Duration | Scope Δ | Plan Revs | Task Revs | Root Cause | Rework Shape | Severity | Complete? | -|:---|:---|:---|:---|:---|:---|:---|:---|:---|:---|:---| - ---- - -## Step 11: Optional Post-Analysis Improvements - -If appropriate, also: -- update any local project-health or memory artifact (if present) with recurring failure modes and fragile subsystems -- generate `prompt_improvement_tips.md` from high-sufficiency / first-shot-success sessions -- suggest missing skills or workflows when the same subsystem or task sequence repeatedly causes struggle - -Only recommend workflows/skills when the pattern appears repeatedly. - ---- - -## Final Output Standard - -The workflow must produce: -1. metrics summary -2. root-cause diagnosis -3. prompt-sufficiency assessment -4. subsystem/friction map -5. severity triage and prioritization -6. evidence-backed recommendations -7. non-obvious findings - -Prefer explicit uncertainty over fake precision. diff --git a/Skills/analyze-project/examples/sample_session_analysis_report.md b/Skills/analyze-project/examples/sample_session_analysis_report.md deleted file mode 100644 index 141a48e..0000000 --- a/Skills/analyze-project/examples/sample_session_analysis_report.md +++ /dev/null @@ -1,78 +0,0 @@ -# Sample Output: session_analysis_report.md -# Generated by /analyze-project skill on a ~3-week project with ~50 substantive sessions. -# (Trimmed for demo; real reports include full per-conversation breakdown and more cohorts.) - -# 📊 Session Analysis Report — Sample AI Video Studio - -**Generated**: 2026-03-13 -**Conversations Analyzed**: 54 substantive (with artifacts) -**Date Range**: Feb 18 – Mar 13, 2026 - -## Executive Summary - -| Metric | Value | Rating | -|-------------------------|-------------|--------| -| First-Shot Success Rate | 52% | 🟡 | -| Completion Rate | 70% | 🟢 | -| Avg Scope Growth | +58% | 🟡 | -| Replan Rate | 30% | 🟢 | -| Median Duration | ~35 min | 🟢 | -| Avg Revision Intensity | 4.8 versions| 🟡 | -| Abandoned Rate | 22% | 🟡 | - -**Narrative**: High velocity with strong completion on workflow-driven tasks. Main friction is **post-success human scope expansion** — users add "while we're here" features after initial work succeeds, turning narrow tasks into multi-phase epics. Not primarily prompt or agent issues — more workflow discipline. - -## Root Cause Breakdown (non-clean sessions only) - -| Root Cause | % | Notes | -|-----------------------------|-----|--------------------------------------------| -| Human Scope Change | 37% | New features/epics added mid-session after success | -| Legitimate Task Complexity | 26% | Multi-phase builds with expected iteration | -| Repo Fragility | 15% | Hidden coupling, pre-existing bugs | -| Verification Churn | 11% | Late test/build failures | -| Spec Ambiguity | 7% | Vague initial ask | -| Agent Architectural Error | 4% | Rare wrong approach | - -Confidence: **High** for top two (direct evidence from version diffs). - -## Scope Change Analysis Highlights - -**Human-Added** (most common): Starts narrow → grows after Phase 1 succeeds (e.g., T2E QA → A/B testing + demos + editor tools). -**Necessary Discovered**: Hidden deps, missing packages, env issues (e.g., auth bcrypt blocking E2E). -**Agent-Introduced**: Very rare (1 case of over-creating components). - -## Rework Shape Summary - -- Clean execution: 52% -- Progressive expansion: 18% (dominant failure mode) -- Early replan → stable: 11% -- Late verification churn: 7% -- Exploratory/research: 7% -- Abandoned mid-flight: 4% - -**Pattern**: Progressive expansion often follows successful implementation — user adds adjacent work in same session. - -## Friction Hotspots (top areas) - -| Subsystem | Sessions | Avg Revisions | Main Cause | -|------------------------|----------|---------------|---------------------| -| production.py + domain | 8 | 6.2 | Hidden coupling | -| fal.py (model adapter) | 7 | 5.0 | Legitimate complexity | -| billing.py + tests | 6 | 5.5 | Verification churn | -| frontend/ build | 5 | 7.0 | Missing deps/types | -| Auth/bcrypt | 3 | 4.7 | Blocks E2E testing | - -## Non-Obvious Findings (top 3) - -1. **Post-Success Expansion Dominates** — Most scope growth happens *after* initial completion succeeds, not from bad planning. (High confidence) -2. **File Targeting > Acceptance Criteria** — Missing specific files correlates more with replanning (44% vs 12%) than missing criteria. Anchors agent research early. (High) -3. **Frontend Build is Silent Killer** — Late TypeScript/import failures add 2–4 cycles repeatedly. No pre-flight check exists. (High) - -## Recommendations (top 4) - -1. **Split Sessions After Phases** — Start new conversation after successful completion to avoid context bloat and scope creep. Expected: +13% first-shot success. (High) -2. **Enforce File Targeting** — Add pre-check in prompt optimizer to flag missing file/module refs. Expected: halve replan rate. (High) -3. **Add Frontend Preflight** — Run `npm run build` early in frontend-touching sessions. Eliminates common late blockers. (High) -4. **Fix Auth Test Fixture** — Seed test users with plain passwords or bypass bcrypt for local E2E. Unblocks browser testing. (High) - -This sample shows the forensic style: evidence-backed, confidence-rated, focused on actionable patterns rather than raw counts. diff --git a/Skills/antigravity-balance/SKILL.md b/Skills/antigravity-balance/SKILL.md deleted file mode 100644 index 7581c43..0000000 --- a/Skills/antigravity-balance/SKILL.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -name: antigravity-balance -description: Check Google Antigravity AI model quota/token balance. Use when a user asks about their Antigravity usage, remaining tokens, model limits, quota status, or rate limits. Works by detecting the local Antigravity language server process and querying its API. ---- - -# Antigravity Balance - -Check your Antigravity AI model quota and token balance. - -## Quick Start - -```bash -# Check quota (auto-detects local Antigravity process) -node scripts/agquota.js - -# JSON output for parsing -node scripts/agquota.js --json - -# Verbose output (debugging) -node scripts/agquota.js -v -``` - -## How It Works - -1. **Process Detection**: Finds the running `language_server_macos_arm` (or platform equivalent) process -2. **Extracts Connection Info**: Parses `--extension_server_port` and `--csrf_token` from process args -3. **Port Discovery**: Scans nearby ports to find the HTTPS API endpoint (typically extensionPort + 1) -4. **Queries Local API**: Hits `https://127.0.0.1:{port}/exa.language_server_pb.LanguageServerService/GetUserStatus` -5. **Displays Quota**: Shows remaining percentage, reset time, and model info - -## Output Format - -Default output shows: -- User name, email, and tier -- Model name and remaining quota percentage -- Visual progress bar (color-coded: green >50%, yellow >20%, red ≤20%) -- Reset countdown (e.g., "4h 32m") - -JSON output (`--json`) returns structured data: -```json -{ - "user": { "name": "...", "email": "...", "tier": "..." }, - "models": [ - { "label": "Claude Sonnet 4.5", "remainingPercent": 80, "resetTime": "..." } - ], - "timestamp": "2026-01-28T01:00:00.000Z" -} -``` - -## Requirements - -- Node.js (uses built-in `https` module) -- Antigravity (or Windsurf) must be running - -## Troubleshooting - -If the script fails: -1. Ensure Antigravity/Windsurf is running -2. Check if the language server process exists: `ps aux | grep language_server` -3. The process must have `--app_data_dir antigravity` in its args (distinguishes from other Codeium forks) - -## Platform-Specific Process Names - -| Platform | Process Name | -|----------|--------------| -| macOS (ARM) | `language_server_macos_arm` | -| macOS (Intel) | `language_server_macos` | -| Linux | `language_server_linux` | -| Windows | `language_server_windows_x64.exe` | diff --git a/Skills/antigravity-balance/_meta.json b/Skills/antigravity-balance/_meta.json deleted file mode 100644 index d20d960..0000000 --- a/Skills/antigravity-balance/_meta.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "owner": "finderstrategy-cyber", - "slug": "antigravity-balance", - "displayName": "Antigravity Balance", - "latest": { - "version": "1.0.0", - "publishedAt": 1769563664027, - "commit": "https://github.com/clawdbot/skills/commit/bebc719d7d3d2712df5d389c05a891d02676bf6d" - }, - "history": [] -} diff --git a/Skills/antigravity-design-expert/SKILL.md b/Skills/antigravity-design-expert/SKILL.md deleted file mode 100644 index 4e12b7c..0000000 --- a/Skills/antigravity-design-expert/SKILL.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -name: antigravity-design-expert -description: Core UI/UX engineering skill for building highly interactive, spatial, weightless, and glassmorphism-based web interfaces using GSAP and 3D CSS. -risk: safe -source: community -date_added: "2026-03-07" ---- - -# Antigravity UI & Motion Design Expert - -## 🎯 Role Overview - -You are a world-class UI/UX Engineer specializing in "Antigravity Design." Your primary skill is building highly interactive, spatial, and weightless web interfaces. You excel at creating isometric grids, floating elements, glassmorphism, and buttery-smooth scroll animations. - -## 🛠️ Preferred Tech Stack - -When asked to build or generate UI components, default to the following stack unless instructed otherwise: - -- **Framework:** React / Next.js -- **Styling:** Tailwind CSS (for layout and utility) + Custom CSS for complex 3D transforms -- **Animation:** GSAP (GreenSock) + ScrollTrigger for scroll-linked motion -- **3D Elements:** React Three Fiber (R3F) or CSS 3D Transforms (`rotateX`, `rotateY`, `perspective`) - -## 📐 Design Principles (The "Antigravity" Vibe) - -- **Weightlessness:** UI cards and elements should appear to float. Use layered, soft, diffused drop-shadows (e.g., `box-shadow: 0 20px 40px rgba(0,0,0,0.05)`). -- **Spatial Depth:** Utilize Z-axis layering. Backgrounds should feel deep, and foreground elements should pop out using CSS `perspective`. -- **Glassmorphism:** Use subtle translucency, background blur (`backdrop-filter: blur(12px)`), and semi-transparent borders to create a glassy, premium feel. -- **Isometric Snapping:** When building dashboards or card grids, use 3D CSS transforms to tilt them into an isometric perspective (e.g., `transform: rotateX(60deg) rotateZ(-45deg)`). - -## 🎬 Motion & Animation Rules - -- **Never snap instantly:** All state changes (hover, focus, active) must have smooth transitions (minimum `0.3s ease-out`). -- **Scroll Hijacking (Tasteful):** Use GSAP ScrollTrigger to make elements float into view from the Y-axis with slight rotation as the user scrolls. -- **Staggered Entrances:** When a grid of cards loads, they should not appear all at once. Stagger their entrance animations by `0.1s` so they drop in like dominoes. -- **Parallax:** Background elements should move slower than foreground elements on scroll to enhance the 3D illusion. - -## 🚧 Execution Constraints - -- Always write modular, reusable components. -- Ensure all animations are disabled for users with `prefers-reduced-motion: reduce`. -- Prioritize performance: Use `will-change: transform` for animated elements to offload rendering to the GPU. Do not animate expensive properties like `box-shadow` or `filter` continuously. diff --git a/Skills/antigravity-skill-orchestrator/README.md b/Skills/antigravity-skill-orchestrator/README.md deleted file mode 100644 index c1fb179..0000000 --- a/Skills/antigravity-skill-orchestrator/README.md +++ /dev/null @@ -1,32 +0,0 @@ -# antigravity-skill-orchestrator - -A meta-skill package for the Antigravity IDE ecosystem. - -## Overview - -The `antigravity-skill-orchestrator` is an intelligent meta-skill that enhances an AI agent's ability to handle complex, multi-domain tasks. It provides strict guidelines and workflows enabling the agent to: - -1. **Evaluate Task Complexity**: Implementing guardrails to prevent the overuse of specialized skills on simple, straightforward tasks. -2. **Dynamically Select Skills**: Identifying the best combination of skills for a given complex problem. -3. **Track Skill Combinations**: Utilizing the `agent-memory-mcp` skill to store, search, and retrieve successful skill combinations for future reference, building institutional knowledge over time. - -## Installation - -This skill is designed to be used within the Antigravity IDE and integrated alongside the existing suite of AWESOME skills. - -Make sure you have the `agent-memory-mcp` skill installed and running to take full advantage of the combination tracking feature. - -## Usage - -When executing a prompt with an AI assistant via the Antigravity IDE, you can invoke this skill: - -```bash -@antigravity-skill-orchestrator Please build a comprehensive dashboard integrating fetching live data, an interactive UI, and performance optimizations. -``` - -The agent will then follow the directives in the `SKILL.md` to break down the task, search memory for similar challenges, assemble the right team of skills (e.g., `@react-patterns` + `@nodejs-backend-patterns`), and execute the task without over-complicating it. - ---- - -**Author:** [Wahid](https://github.com/wahidzzz) -**Source:** [antigravity-skill-orchestrator](https://github.com/wahidzzz/antigravity-skill-orchestrator) diff --git a/Skills/antigravity-skill-orchestrator/SKILL.md b/Skills/antigravity-skill-orchestrator/SKILL.md deleted file mode 100644 index 7bc1ebd..0000000 --- a/Skills/antigravity-skill-orchestrator/SKILL.md +++ /dev/null @@ -1,123 +0,0 @@ ---- -name: antigravity-skill-orchestrator -description: "A meta-skill that understands task requirements, dynamically selects appropriate skills, tracks successful skill combinations using agent-memory-mcp, and prevents skill overuse for simple tasks." -category: meta -risk: safe -source: community -tags: "[orchestration, meta-skill, agent-memory, task-evaluation]" -date_added: "2026-03-13" ---- - -# antigravity-skill-orchestrator - -## Overview - -The `skill-orchestrator` is a meta-skill designed to enhance the AI agent's ability to tackle complex problems. It acts as an intelligent coordinator that first evaluates the complexity of a user's request. Based on that evaluation, it determines if specialized skills are needed. If they are, it selects the right combination of skills, explicitly tracks these combinations using `@agent-memory-mcp` for future reference, and guides the agent through the execution process. Crucially, it includes strict guardrails to prevent the unnecessary use of specialized skills for simple tasks that can be solved with baseline capabilities. - -## When to Use This Skill - -- Use when tackling a complex, multi-step problem that likely requires multiple domains of expertise. -- Use when you are unsure which specific skills are best suited for a given user request, and need to discover them from the broader ecosystem. -- Use when the user explicitly asks to "orchestrate", "combine skills", or "use the best tools for the job" on a significant task. -- Use when you want to look up previously successful combinations of skills for a specific type of problem. - -## Core Concepts - -### Task Evaluation Guardrails -Not every task requires a specialized skill. For straightforward issues (e.g., small CSS fixes, simple script writing, renaming a variable), **DO NOT USE** specialized skills. Over-engineering simple tasks wastes tokens and time. - -Additionally, the orchestrator is strictly forbidden from creating new skills. Its sole purpose is to combine and use existing skills provided by the community or present in the current environment. - -Before invoking any skills, evaluate the task: -1. **Is the task simple/contained?** Solve it directly using the agent's ordinary file editing, search, and terminal capabilities available in the current environment. -2. **Is the task complex/multi-domain?** Only then should you proceed to orchestrate skills. - -### Skill Selection & Combinations -When a task is deemed complex, identify the necessary domains (e.g., frontend, database, deployment). Search available skills in the current environment to find the most relevant ones. If the required skills are not found locally, consult the master skill catalog. - -### Master Skill Catalog -The Antigravity ecosystem maintains a master catalog of highly curated skills at `https://raw.githubusercontent.com/sickn33/antigravity-awesome-skills/main/CATALOG.md`. When local skills are insufficient, fetch this catalog to discover appropriate skills across the 9 primary categories: -- `architecture` -- `business` -- `data-ai` -- `development` -- `general` -- `infrastructure` -- `security` -- `testing` -- `workflow` - -### Memory Integration (`@agent-memory-mcp`) -To build institutional knowledge, the orchestrator relies on the `agent-memory-mcp` skill to record and retrieve successful skill combinations. - -## Step-by-Step Guide - -### 1. Task Evaluation & Guardrail Check -[Triggered when facing a new user request that might need skills] -1. Read the user's request. -2. Ask yourself: "Can I solve this efficiently with just basic file editing and terminal commands?" -3. If YES: Proceed without invoking specialized skills. Stop the orchestration here. -4. If NO: Proceed to step 2. - -### 2. Retrieve Past Knowledge -[Triggered if the task is complex] -1. Use the `memory_search` tool provided by `agent-memory-mcp` to search for similar past tasks. - - Example query: `memory_search({ query: "skill combination for react native and firebase", type: "skill_combination" })` -2. If a working combination exists, read the details using `memory_read`. -3. If no relevant memory exists, proceed to Step 3. - -### 3. Discover and Select Skills -[Triggered if no past knowledge covers this task] -1. Analyze the core requirements (e.g., "needs a React UI, a Node.js backend, and a PostgreSQL database"). -2. Query the locally available skills using the current environment's skill list or equivalent discovery mechanism to find the best match for each requirement. -3. **If local skills are insufficient**, fetch the master catalog with the web or command-line retrieval tools available in the current environment: `https://raw.githubusercontent.com/sickn33/antigravity-awesome-skills/main/CATALOG.md`. -4. Scan the catalog's 9 main categories to identify the appropriate skills to bring into the current context. -5. Select the minimal set of skills needed. **Do not over-select.** - -### 4. Apply Skills and Track the Combination -[Triggered after executing the task using the selected skills] -1. Assume the task was completed successfully using a new combination of skills (e.g., `@react-patterns` + `@nodejs-backend-patterns` + `@postgresql`). -2. Record this combination for future use using `memory_write` from `agent-memory-mcp`. - - Ensure the type is `skill_combination`. - - Provide a descriptive key and content detailing why these skills worked well together. - -## Examples - -### Example 1: Handling a Simple Task (The Guardrail in Action) -**User Request:** "Change the color of the submit button in `index.css` to blue." -**Action:** The skill orchestrator evaluates the task. It determines this is a "simple/contained" task. It **does not** invoke specialized skills. It directly edits `index.css`. - -### Example 2: Recording a New Skill Combination -```javascript -// Using the agent-memory-mcp tool after successfully building a complex feature -memory_write({ - key: "combination-ecommerce-checkout", - type: "skill_combination", - content: "For e-commerce checkouts, using @stripe-integration combined with @react-state-management and @postgresql effectively handles the full flow from UI state to payment processing to order recording.", - tags: ["ecommerce", "checkout", "stripe", "react"] -}) -``` - -### Example 3: Retrieving a Combination -```javascript -// At the start of a new e-commerce task -memory_search({ - query: "ecommerce checkout", - type: "skill_combination" -}) -// Returns the key "combination-ecommerce-checkout", which you then read: -memory_read({ key: "combination-ecommerce-checkout" }) -``` - -## Best Practices - -- ✅ **Do:** Always evaluate task complexity *before* looking for skills. -- ✅ **Do:** Keep the number of orchestrated skills as small as possible. -- ✅ **Do:** Use highly descriptive keys when running `memory_write` so they are easy to search later. -- ❌ **Don't:** Use this skill for simple bug fixes or UI tweaks. -- ❌ **Don't:** Combine skills that have overlapping and conflicting instructions without a clear plan to resolve the conflict. -- ❌ **Don't:** Attempt to construct, generate, or create new skills. Only combine what is available. - -## Related Skills - -- `@agent-memory-mcp` - Essential for this skill to function. Provides the persistent storage for skill combinations. diff --git a/Skills/new-skills/analyze-project/SKILL.md b/Skills/new-skills/analyze-project/SKILL.md deleted file mode 100644 index 20e8dae..0000000 --- a/Skills/new-skills/analyze-project/SKILL.md +++ /dev/null @@ -1,432 +0,0 @@ ---- -name: analyze-project -description: Forensic root cause analyzer for Antigravity sessions. Classifies scope deltas, rework patterns, root causes, hotspots, and auto-improves prompts/health. -version: "1.0" -tags: [analysis, diagnostics, meta, root-cause, project-health, session-review] ---- - -# /analyze-project — Root Cause Analyst Workflow - -Analyze AI-assisted coding sessions in `~/.gemini/antigravity/brain/` and produce a report that explains not just **what happened**, but **why it happened**, **who/what caused it**, and **what should change next time**. - -## Goal - -For each session, determine: - -1. What changed from the initial ask to the final executed work -2. Whether the main cause was: - - user/spec - - agent - - repo/codebase - - validation/testing - - legitimate task complexity -3. Whether the opening prompt was sufficient -4. Which files/subsystems repeatedly correlate with struggle -5. What changes would most improve future sessions - -## Global Rules - -- Treat `.resolved.N` counts as **iteration signals**, not proof of failure -- Separate **human-added scope**, **necessary discovered scope**, and **agent-introduced scope** -- Separate **agent error** from **repo friction** -- Every diagnosis must include **evidence** and **confidence** -- Confidence levels: - - **High** = direct artifact/timestamp evidence - - **Medium** = multiple supporting signals - - **Low** = plausible inference, not directly proven -- Evidence precedence: - - artifact contents > timestamps > metadata summaries > inference -- If evidence is weak, say so - ---- - -## Step 0.5: Session Intent Classification - -Classify the primary session intent from objective + artifacts: - -- `DELIVERY` -- `DEBUGGING` -- `REFACTOR` -- `RESEARCH` -- `EXPLORATION` -- `AUDIT_ANALYSIS` - -Record: -- `session_intent` -- `session_intent_confidence` - -Use intent to contextualize severity and rework shape. -Do not judge exploratory or research sessions by the same standards as narrow delivery sessions. - ---- - -## Step 1: Discover Conversations - -1. Read available conversation summaries from system context -2. List conversation folders in the user’s Antigravity `brain/` directory -3. Build a conversation index with: - - `conversation_id` - - `title` - - `objective` - - `created` - - `last_modified` -4. If the user supplied a keyword/path, filter to matching conversations; otherwise analyze all - -Output: indexed list of conversations to analyze. - ---- - -## Step 2: Extract Session Evidence - -For each conversation, read if present: - -### Core artifacts -- `task.md` -- `implementation_plan.md` -- `walkthrough.md` - -### Metadata -- `*.metadata.json` - -### Version snapshots -- `task.md.resolved.0 ... N` -- `implementation_plan.md.resolved.0 ... N` -- `walkthrough.md.resolved.0 ... N` - -### Additional signals -- other `.md` artifacts -- timestamps across artifact updates -- file/folder/subsystem names mentioned in plans/walkthroughs -- validation/testing language -- explicit acceptance criteria, constraints, non-goals, and file targets - -Record per conversation: - -#### Lifecycle -- `has_task` -- `has_plan` -- `has_walkthrough` -- `is_completed` -- `is_abandoned_candidate` = task exists but no walkthrough - -#### Revision / change volume -- `task_versions` -- `plan_versions` -- `walkthrough_versions` -- `extra_artifacts` - -#### Scope -- `task_items_initial` -- `task_items_final` -- `task_completed_pct` -- `scope_delta_raw` -- `scope_creep_pct_raw` - -#### Timing -- `created_at` -- `completed_at` -- `duration_minutes` - -#### Content / quality -- `objective_text` -- `initial_plan_summary` -- `final_plan_summary` -- `initial_task_excerpt` -- `final_task_excerpt` -- `walkthrough_summary` -- `mentioned_files_or_subsystems` -- `validation_requirements_present` -- `acceptance_criteria_present` -- `non_goals_present` -- `scope_boundaries_present` -- `file_targets_present` -- `constraints_present` - ---- - -## Step 3: Prompt Sufficiency - -Score the opening request on a 0–2 scale for: - -- **Clarity** -- **Boundedness** -- **Testability** -- **Architectural specificity** -- **Constraint awareness** -- **Dependency awareness** - -Create: -- `prompt_sufficiency_score` -- `prompt_sufficiency_band` = High / Medium / Low - -Then note which missing prompt ingredients likely contributed to later friction. - -Do not punish short prompts by default; a narrow, obvious task can still have high sufficiency. - ---- - -## Step 4: Scope Change Classification - -Classify scope change into: - -- **Human-added scope** — new asks beyond the original task -- **Necessary discovered scope** — work required to complete the original task correctly -- **Agent-introduced scope** — likely unnecessary work introduced by the agent - -Record: -- `scope_change_type_primary` -- `scope_change_type_secondary` (optional) -- `scope_change_confidence` -- evidence - -Keep one short example in mind for calibration: -- Human-added: “also refactor nearby code while you’re here” -- Necessary discovered: hidden dependency must be fixed for original task to work -- Agent-introduced: extra cleanup or redesign not requested and not required - ---- - -## Step 5: Rework Shape - -Classify each session into one primary pattern: - -- **Clean execution** -- **Early replan then stable finish** -- **Progressive scope expansion** -- **Reopen/reclose churn** -- **Late-stage verification churn** -- **Abandoned mid-flight** -- **Exploratory / research session** - -Record: -- `rework_shape` -- `rework_shape_confidence` -- evidence - ---- - -## Step 6: Root Cause Analysis - -For every non-clean session, assign: - -### Primary root cause -One of: -- `SPEC_AMBIGUITY` -- `HUMAN_SCOPE_CHANGE` -- `REPO_FRAGILITY` -- `AGENT_ARCHITECTURAL_ERROR` -- `VERIFICATION_CHURN` -- `LEGITIMATE_TASK_COMPLEXITY` - -### Secondary root cause -Optional if materially relevant - -### Root-cause guidance -- **SPEC_AMBIGUITY**: opening ask lacked boundaries, targets, criteria, or constraints -- **HUMAN_SCOPE_CHANGE**: scope expanded because the user broadened the task -- **REPO_FRAGILITY**: hidden coupling, brittle files, unclear architecture, or environment issues forced extra work -- **AGENT_ARCHITECTURAL_ERROR**: wrong files, wrong assumptions, wrong approach, hallucinated structure -- **VERIFICATION_CHURN**: implementation mostly worked, but testing/validation caused loops -- **LEGITIMATE_TASK_COMPLEXITY**: revisions were expected for the difficulty and not clearly avoidable - -Every root-cause assignment must include: -- evidence -- why stronger alternative causes were rejected -- confidence - ---- - -## Step 6.5: Session Severity Scoring (0–100) - -Assign each session a severity score to prioritize attention. - -Components (sum, clamp 0–100): -- **Completion failure**: 0–25 (`abandoned = 25`) -- **Replanning intensity**: 0–15 -- **Scope instability**: 0–15 -- **Rework shape severity**: 0–15 -- **Prompt sufficiency deficit**: 0–10 (`low = 10`) -- **Root cause impact**: 0–10 (`REPO_FRAGILITY` / `AGENT_ARCHITECTURAL_ERROR` highest) -- **Hotspot recurrence**: 0–10 - -Bands: -- **0–19 Low** -- **20–39 Moderate** -- **40–59 Significant** -- **60–79 High** -- **80–100 Critical** - -Record: -- `session_severity_score` -- `severity_band` -- `severity_drivers` = top 2–4 contributors -- `severity_confidence` - -Use severity as a prioritization signal, not a verdict. Always explain the drivers. -Contextualize severity using session intent so research/exploration sessions are not over-penalized. - ---- - -## Step 7: Subsystem / File Clustering - -Across all conversations, cluster repeated struggle by file, folder, or subsystem. - -For each cluster, calculate: -- number of conversations touching it -- average revisions -- completion rate -- abandonment rate -- common root causes -- average severity - -Goal: identify whether friction is mostly prompt-driven, agent-driven, or concentrated in specific repo areas. - ---- - -## Step 8: Comparative Cohorts - -Compare: -- first-shot successes vs re-planned sessions -- completed vs abandoned -- high prompt sufficiency vs low prompt sufficiency -- narrow-scope vs high-scope-growth -- short sessions vs long sessions -- low-friction subsystems vs high-friction subsystems - -For each comparison, identify: -- what differs materially -- which prompt traits correlate with smoother execution -- which repo traits correlate with repeated struggle - -Do not just restate averages; extract cautious evidence-backed patterns. - ---- - -## Step 9: Non-Obvious Findings - -Generate 3–7 findings that are not simple metric restatements. - -Each finding must include: -- observation -- why it matters -- evidence -- confidence - -Examples of strong findings: -- replans cluster around weak file targeting rather than weak acceptance criteria -- scope growth often begins after initial success, suggesting post-success human expansion -- auth-related struggle is driven more by repo fragility than agent hallucination - ---- - -## Step 10: Report Generation - -Create `session_analysis_report.md` with this structure: - -# 📊 Session Analysis Report — [Project Name] - -**Generated**: [timestamp] -**Conversations Analyzed**: [N] -**Date Range**: [earliest] → [latest] - -## Executive Summary - -| Metric | Value | Rating | -|:---|:---|:---| -| First-Shot Success Rate | X% | 🟢/🟡/🔴 | -| Completion Rate | X% | 🟢/🟡/🔴 | -| Avg Scope Growth | X% | 🟢/🟡/🔴 | -| Replan Rate | X% | 🟢/🟡/🔴 | -| Median Duration | Xm | — | -| Avg Session Severity | X | 🟢/🟡/🔴 | -| High-Severity Sessions | X / N | 🟢/🟡/🔴 | - -Thresholds: -- First-shot: 🟢 >70 / 🟡 40–70 / 🔴 <40 -- Scope growth: 🟢 <15 / 🟡 15–40 / 🔴 >40 -- Replan rate: 🟢 <20 / 🟡 20–50 / 🔴 >50 - -Avg severity guidance: -- 🟢 <25 -- 🟡 25–50 -- 🔴 >50 - -Note: avg severity is an aggregate health signal, not the same as per-session severity bands. - -Then add a short narrative summary of what is going well, what is breaking down, and whether the main issue is prompt quality, repo fragility, workflow discipline, or validation churn. - -## Root Cause Breakdown - -| Root Cause | Count | % | Notes | -|:---|:---|:---|:---| - -## Prompt Sufficiency Analysis -- common traits of high-sufficiency prompts -- common missing inputs in low-sufficiency prompts -- which missing prompt ingredients correlate most with replanning or abandonment - -## Scope Change Analysis -Separate: -- Human-added scope -- Necessary discovered scope -- Agent-introduced scope - -## Rework Shape Analysis -Summarize the main failure patterns across sessions. - -## Friction Hotspots -Show the files/folders/subsystems most associated with replanning, abandonment, verification churn, and high severity. - -## First-Shot Successes -List the cleanest sessions and extract what made them work. - -## Non-Obvious Findings -List 3–7 evidence-backed findings with confidence. - -## Severity Triage -List the highest-severity sessions and say whether the best intervention is: -- prompt improvement -- scope discipline -- targeted skill/workflow -- repo refactor / architecture cleanup -- validation/test harness improvement - -## Recommendations -For each recommendation, use: -- **Observed pattern** -- **Likely cause** -- **Evidence** -- **Change to make** -- **Expected benefit** -- **Confidence** - -## Per-Conversation Breakdown - -| # | Title | Intent | Duration | Scope Δ | Plan Revs | Task Revs | Root Cause | Rework Shape | Severity | Complete? | -|:---|:---|:---|:---|:---|:---|:---|:---|:---|:---|:---| - ---- - -## Step 11: Optional Post-Analysis Improvements - -If appropriate, also: -- update any local project-health or memory artifact (if present) with recurring failure modes and fragile subsystems -- generate `prompt_improvement_tips.md` from high-sufficiency / first-shot-success sessions -- suggest missing skills or workflows when the same subsystem or task sequence repeatedly causes struggle - -Only recommend workflows/skills when the pattern appears repeatedly. - ---- - -## Final Output Standard - -The workflow must produce: -1. metrics summary -2. root-cause diagnosis -3. prompt-sufficiency assessment -4. subsystem/friction map -5. severity triage and prioritization -6. evidence-backed recommendations -7. non-obvious findings - -Prefer explicit uncertainty over fake precision. diff --git a/Skills/new-skills/analyze-project/examples/sample_session_analysis_report.md b/Skills/new-skills/analyze-project/examples/sample_session_analysis_report.md deleted file mode 100644 index 141a48e..0000000 --- a/Skills/new-skills/analyze-project/examples/sample_session_analysis_report.md +++ /dev/null @@ -1,78 +0,0 @@ -# Sample Output: session_analysis_report.md -# Generated by /analyze-project skill on a ~3-week project with ~50 substantive sessions. -# (Trimmed for demo; real reports include full per-conversation breakdown and more cohorts.) - -# 📊 Session Analysis Report — Sample AI Video Studio - -**Generated**: 2026-03-13 -**Conversations Analyzed**: 54 substantive (with artifacts) -**Date Range**: Feb 18 – Mar 13, 2026 - -## Executive Summary - -| Metric | Value | Rating | -|-------------------------|-------------|--------| -| First-Shot Success Rate | 52% | 🟡 | -| Completion Rate | 70% | 🟢 | -| Avg Scope Growth | +58% | 🟡 | -| Replan Rate | 30% | 🟢 | -| Median Duration | ~35 min | 🟢 | -| Avg Revision Intensity | 4.8 versions| 🟡 | -| Abandoned Rate | 22% | 🟡 | - -**Narrative**: High velocity with strong completion on workflow-driven tasks. Main friction is **post-success human scope expansion** — users add "while we're here" features after initial work succeeds, turning narrow tasks into multi-phase epics. Not primarily prompt or agent issues — more workflow discipline. - -## Root Cause Breakdown (non-clean sessions only) - -| Root Cause | % | Notes | -|-----------------------------|-----|--------------------------------------------| -| Human Scope Change | 37% | New features/epics added mid-session after success | -| Legitimate Task Complexity | 26% | Multi-phase builds with expected iteration | -| Repo Fragility | 15% | Hidden coupling, pre-existing bugs | -| Verification Churn | 11% | Late test/build failures | -| Spec Ambiguity | 7% | Vague initial ask | -| Agent Architectural Error | 4% | Rare wrong approach | - -Confidence: **High** for top two (direct evidence from version diffs). - -## Scope Change Analysis Highlights - -**Human-Added** (most common): Starts narrow → grows after Phase 1 succeeds (e.g., T2E QA → A/B testing + demos + editor tools). -**Necessary Discovered**: Hidden deps, missing packages, env issues (e.g., auth bcrypt blocking E2E). -**Agent-Introduced**: Very rare (1 case of over-creating components). - -## Rework Shape Summary - -- Clean execution: 52% -- Progressive expansion: 18% (dominant failure mode) -- Early replan → stable: 11% -- Late verification churn: 7% -- Exploratory/research: 7% -- Abandoned mid-flight: 4% - -**Pattern**: Progressive expansion often follows successful implementation — user adds adjacent work in same session. - -## Friction Hotspots (top areas) - -| Subsystem | Sessions | Avg Revisions | Main Cause | -|------------------------|----------|---------------|---------------------| -| production.py + domain | 8 | 6.2 | Hidden coupling | -| fal.py (model adapter) | 7 | 5.0 | Legitimate complexity | -| billing.py + tests | 6 | 5.5 | Verification churn | -| frontend/ build | 5 | 7.0 | Missing deps/types | -| Auth/bcrypt | 3 | 4.7 | Blocks E2E testing | - -## Non-Obvious Findings (top 3) - -1. **Post-Success Expansion Dominates** — Most scope growth happens *after* initial completion succeeds, not from bad planning. (High confidence) -2. **File Targeting > Acceptance Criteria** — Missing specific files correlates more with replanning (44% vs 12%) than missing criteria. Anchors agent research early. (High) -3. **Frontend Build is Silent Killer** — Late TypeScript/import failures add 2–4 cycles repeatedly. No pre-flight check exists. (High) - -## Recommendations (top 4) - -1. **Split Sessions After Phases** — Start new conversation after successful completion to avoid context bloat and scope creep. Expected: +13% first-shot success. (High) -2. **Enforce File Targeting** — Add pre-check in prompt optimizer to flag missing file/module refs. Expected: halve replan rate. (High) -3. **Add Frontend Preflight** — Run `npm run build` early in frontend-touching sessions. Eliminates common late blockers. (High) -4. **Fix Auth Test Fixture** — Seed test users with plain passwords or bypass bcrypt for local E2E. Unblocks browser testing. (High) - -This sample shows the forensic style: evidence-backed, confidence-rated, focused on actionable patterns rather than raw counts. diff --git a/Skills/new-skills/antigravity-balance/SKILL.md b/Skills/new-skills/antigravity-balance/SKILL.md deleted file mode 100644 index 7581c43..0000000 --- a/Skills/new-skills/antigravity-balance/SKILL.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -name: antigravity-balance -description: Check Google Antigravity AI model quota/token balance. Use when a user asks about their Antigravity usage, remaining tokens, model limits, quota status, or rate limits. Works by detecting the local Antigravity language server process and querying its API. ---- - -# Antigravity Balance - -Check your Antigravity AI model quota and token balance. - -## Quick Start - -```bash -# Check quota (auto-detects local Antigravity process) -node scripts/agquota.js - -# JSON output for parsing -node scripts/agquota.js --json - -# Verbose output (debugging) -node scripts/agquota.js -v -``` - -## How It Works - -1. **Process Detection**: Finds the running `language_server_macos_arm` (or platform equivalent) process -2. **Extracts Connection Info**: Parses `--extension_server_port` and `--csrf_token` from process args -3. **Port Discovery**: Scans nearby ports to find the HTTPS API endpoint (typically extensionPort + 1) -4. **Queries Local API**: Hits `https://127.0.0.1:{port}/exa.language_server_pb.LanguageServerService/GetUserStatus` -5. **Displays Quota**: Shows remaining percentage, reset time, and model info - -## Output Format - -Default output shows: -- User name, email, and tier -- Model name and remaining quota percentage -- Visual progress bar (color-coded: green >50%, yellow >20%, red ≤20%) -- Reset countdown (e.g., "4h 32m") - -JSON output (`--json`) returns structured data: -```json -{ - "user": { "name": "...", "email": "...", "tier": "..." }, - "models": [ - { "label": "Claude Sonnet 4.5", "remainingPercent": 80, "resetTime": "..." } - ], - "timestamp": "2026-01-28T01:00:00.000Z" -} -``` - -## Requirements - -- Node.js (uses built-in `https` module) -- Antigravity (or Windsurf) must be running - -## Troubleshooting - -If the script fails: -1. Ensure Antigravity/Windsurf is running -2. Check if the language server process exists: `ps aux | grep language_server` -3. The process must have `--app_data_dir antigravity` in its args (distinguishes from other Codeium forks) - -## Platform-Specific Process Names - -| Platform | Process Name | -|----------|--------------| -| macOS (ARM) | `language_server_macos_arm` | -| macOS (Intel) | `language_server_macos` | -| Linux | `language_server_linux` | -| Windows | `language_server_windows_x64.exe` | diff --git a/Skills/new-skills/antigravity-balance/_meta.json b/Skills/new-skills/antigravity-balance/_meta.json deleted file mode 100644 index d20d960..0000000 --- a/Skills/new-skills/antigravity-balance/_meta.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "owner": "finderstrategy-cyber", - "slug": "antigravity-balance", - "displayName": "Antigravity Balance", - "latest": { - "version": "1.0.0", - "publishedAt": 1769563664027, - "commit": "https://github.com/clawdbot/skills/commit/bebc719d7d3d2712df5d389c05a891d02676bf6d" - }, - "history": [] -} diff --git a/Skills/new-skills/antigravity-design-expert/SKILL.md b/Skills/new-skills/antigravity-design-expert/SKILL.md deleted file mode 100644 index 4e12b7c..0000000 --- a/Skills/new-skills/antigravity-design-expert/SKILL.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -name: antigravity-design-expert -description: Core UI/UX engineering skill for building highly interactive, spatial, weightless, and glassmorphism-based web interfaces using GSAP and 3D CSS. -risk: safe -source: community -date_added: "2026-03-07" ---- - -# Antigravity UI & Motion Design Expert - -## 🎯 Role Overview - -You are a world-class UI/UX Engineer specializing in "Antigravity Design." Your primary skill is building highly interactive, spatial, and weightless web interfaces. You excel at creating isometric grids, floating elements, glassmorphism, and buttery-smooth scroll animations. - -## 🛠️ Preferred Tech Stack - -When asked to build or generate UI components, default to the following stack unless instructed otherwise: - -- **Framework:** React / Next.js -- **Styling:** Tailwind CSS (for layout and utility) + Custom CSS for complex 3D transforms -- **Animation:** GSAP (GreenSock) + ScrollTrigger for scroll-linked motion -- **3D Elements:** React Three Fiber (R3F) or CSS 3D Transforms (`rotateX`, `rotateY`, `perspective`) - -## 📐 Design Principles (The "Antigravity" Vibe) - -- **Weightlessness:** UI cards and elements should appear to float. Use layered, soft, diffused drop-shadows (e.g., `box-shadow: 0 20px 40px rgba(0,0,0,0.05)`). -- **Spatial Depth:** Utilize Z-axis layering. Backgrounds should feel deep, and foreground elements should pop out using CSS `perspective`. -- **Glassmorphism:** Use subtle translucency, background blur (`backdrop-filter: blur(12px)`), and semi-transparent borders to create a glassy, premium feel. -- **Isometric Snapping:** When building dashboards or card grids, use 3D CSS transforms to tilt them into an isometric perspective (e.g., `transform: rotateX(60deg) rotateZ(-45deg)`). - -## 🎬 Motion & Animation Rules - -- **Never snap instantly:** All state changes (hover, focus, active) must have smooth transitions (minimum `0.3s ease-out`). -- **Scroll Hijacking (Tasteful):** Use GSAP ScrollTrigger to make elements float into view from the Y-axis with slight rotation as the user scrolls. -- **Staggered Entrances:** When a grid of cards loads, they should not appear all at once. Stagger their entrance animations by `0.1s` so they drop in like dominoes. -- **Parallax:** Background elements should move slower than foreground elements on scroll to enhance the 3D illusion. - -## 🚧 Execution Constraints - -- Always write modular, reusable components. -- Ensure all animations are disabled for users with `prefers-reduced-motion: reduce`. -- Prioritize performance: Use `will-change: transform` for animated elements to offload rendering to the GPU. Do not animate expensive properties like `box-shadow` or `filter` continuously. diff --git a/Skills/new-skills/antigravity-manager/SKILL.md b/Skills/new-skills/antigravity-manager/SKILL.md deleted file mode 100644 index 3c5e317..0000000 --- a/Skills/new-skills/antigravity-manager/SKILL.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -name: antigravity-manager -description: Comprehensive guide to Antigravity Manager architecture, workflows, and development. Use this to understand how to work on the project. ---- - -# Antigravity Manager Developer Guide - -## 🏗️ Architecture Overview - -Antigravity Manager is a hybrid Desktop Application built with Electron, React, and NestJS. It follows a modular architecture where the frontend (Renderer) communicates with the backend (Main) via type-safe IPC (ORPC). - -```mermaid -graph TD - User[User Interface] -->|React/Vite| Renderer[Renderer Process] - Renderer -->|ORPC Client| IPC[IPC Layer] - IPC -->|ORPC Router| Main[Main Process] - Main -->|Bootstraps| Server[NestJS Server] - Main -->|Calls| Services[Service Layer] - Services -->|Read/Write| DB[(SQLite Database)] - Services -->|HTTP| Cloud[Cloud APIs (Google/Anthropic)] -``` - -### Key Technologies - -- **Frontend**: React 19, TailwindCSS v4, TanStack Router, TanStack Query. -- **Backend**: Electron (Main), NestJS (Core Logic), Better-SQLite3 (Data). -- **Communication**: ORPC (Type-safe IPC wrapper around Electron IPC). -- **Build**: Electron Forge + Vite. - -## 📂 Directory Structure - -- `src/main.ts`: Electron Main Process entry point. -- `src/preload.ts`: Bridge between Main and Renderer. -- `src/renderer.tsx`: React App entry point. -- `src/components/`: Reusable React UI components (Radix UI based). -- `src/ipc/`: IPC Routers and Handlers (Domain logic). - - `router.ts`: Main ORPC router definition. - - `account/`, `cloud/`, `database/`: Domain-specific handlers. -- `src/server/`: NestJS application modules (proxies/gateways). -- `src/services/`: Core business logic (framework agnostic). - - `GoogleAPIService.ts`: Gemini/Cloud interactions. - - `AutoSwitchService.ts`: Account rotation logic. -- `src/routes/`: Frontend routing definitions (File-based). - -## 🚀 Development Workflow - -### Prerequisites - -- Node.js 18+ -- npm (Project uses `package-lock.json`) - -### Common Commands - -- **Start Dev Server**: `npm start` -- **Lint Code**: `npm run lint` -- **Unit Test**: `npm run test:unit` -- **E2E Test**: `npm run test:e2e` -- **Build Production**: `npm run make` - -## 🧠 Core Concepts - -### IPC Communication (ORPC) - -The project uses `orpc` for type-safe communication. - -- **Define**: Create a router in `src/ipc/router.ts` with Zod schemas. -- **Implement**: Add logic in handlers (e.g., `src/ipc/account/handler.ts`). -- **Call**: Use the generated client in React components. - -### Database Access - -Data is stored in a local SQLite file (`test.db` in dev, user data in prod). - -- Use `Better-SQLite3` for direct access. -- Logic should be encapsulated in `src/services` or `src/ipc`. - -### Account Management - -- Accounts are added via OAuth (Google/Claude). -- `GoogleAPIService` handles token exchange and refreshing. -- `AutoSwitchService` monitors usage and switches active accounts automatically. - -## ⚠️ Critical Rules - -1. **Type Safety**: strict TypeScript usage; Zod for runtime validation. -2. **Components**: Use `src/components/ui` (Radix primitives) for consistency. -3. **Async**: Handle all IPC/DB calls asynchronously with try/catch. -4. **Security**: Never commit secrets. API keys are user-provided or encrypted locally. diff --git a/Skills/new-skills/antigravity-rotator/SKILL.md b/Skills/new-skills/antigravity-rotator/SKILL.md deleted file mode 100644 index 48aa9c9..0000000 --- a/Skills/new-skills/antigravity-rotator/SKILL.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -name: antigravity-rotator -description: Google Antigravity 模型全自动运维方案。提供多账号自动轮换、优先级调度、会话热更新以及赛博朋克风仪表盘。使用场景包括:(1) 自动化管理多个 Antigravity 账号,(2) 监控配额并自动切换,(3) 在不重启会话的情况下更新模型。 ---- - -# Antigravity Rotator (反重力轮换器) 🚀 - -本 Skill 旨在为 OpenClaw 提供一套确定性的 Google Antigravity 模型运维工作流。它将复杂的配额监控与自动化调度封装为简单的 Action。 - -## 🎯 触发场景 (When to use) -- 当用户拥有多个 Antigravity 账号且希望自动最大化利用配额时。 -- 当主账号配额耗尽,需要**无感切换**(不重启会话)到备用账号时。 -- 当需要实时可视化监控所有账号状态和轮换历史时。 - -## 🛠️ 快速部署流程 (Quick Start) - -### 1. 环境初始化 (必须执行) -进入 Skill 目录并运行 setup 脚本: -```bash -cd skills/antigravity-rotator -node index.js --action=setup -``` -> **作用**:自动探测 `openclaw` 和 `node` 路径,并生成适配你系统的 `config.json`。 - -### 2. 启动管理看板 -```bash -node index.js --action=dashboard -``` -- **地址**:`http://localhost:18090` -- **初始化账号**:进入页面点击右上角 **“同步凭证”**,脚本会自动扫描并加载你已通过 `openclaw models auth login` 登录的账号。 - -### 3. 配置定时任务 (Cron) -为了让轮换全自动运行,必须在系统 `crontab` 中配置驱动: -```cron -# 每 10 分钟自动检查一次 -*/10 * * * * [NODE_PATH] [SKILL_PATH]/index.js --action=rotate >> [LOG_PATH]/cron-rotate.log 2>&1 -``` -*注:具体的路径请参考 `node index.js --action=setup` 运行后的输出结果。* - -## 📝 核心配置项详解 (`config.json`) - -| 参数 | 类型 | 说明 | -| :--- | :--- | :--- | -| `openclawBin` | String | **关键**。`openclaw` 的绝对路径。 | -| `modelPriority` | Array | 轮换优先级列表。排在前面的模型会被优先尝试。 | -| `quotas.low` | Number | 触发轮换的余量百分比阈值(建议 21)。 | -| `clientId` | String | (高级) Google OAuth 客户端 ID。默认为 Antigravity 通用 ID。 | -| `clientSecret` | String | (高级) Google OAuth 客户端密钥。 | -| `defaultProjectId` | String | (高级) Google 项目 ID,影响配额查询接口。 | - -## 🌟 核心特性 -- **会话热更新**:利用 OpenClaw Gateway API,在后台悄悄更换模型,用户正在进行的对话完全不受影响。 -- **自动 Token 刷新**:内置 Token 刷新逻辑,确保长期运行无需手动重新登录。 -- **模型激活 (Warmup)**:自动识别并激活“满血”但在计时外的模型,消除初次切换的延迟。 -- **透明化日志**:看板实时展示轮换原因(如:调度更优模型、当前余量不足等)。 - -## 🤖 开发者资源 -- **入口**: `index.js` -- **逻辑引擎**: `scripts/rotator.js` (配额查询与账号调度) -- **Web UI**: `scripts/dashboard.js` (基于 http 模块的极简服务器) -- **模板**: `assets/` 文件夹下包含详细的 JSON 模板和 Cron 示例。 - ---- -*Antigravity Rotator - 你的 Antigravity 永不宕机* 🥵 diff --git a/Skills/new-skills/antigravity-rotator/_meta.json b/Skills/new-skills/antigravity-rotator/_meta.json deleted file mode 100644 index 0b5dfd5..0000000 --- a/Skills/new-skills/antigravity-rotator/_meta.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "owner": "chocomintx", - "slug": "antigravity-rotator", - "displayName": "Publish Antigravity Rotator", - "latest": { - "version": "1.1.1", - "publishedAt": 1770417629152, - "commit": "https://github.com/openclaw/skills/commit/b8ddbef940e7c2005bb8cddba0c6410f4decf91a" - }, - "history": [] -} diff --git a/Skills/new-skills/antigravity-rotator/assets/config.example.json b/Skills/new-skills/antigravity-rotator/assets/config.example.json deleted file mode 100644 index b1c391d..0000000 --- a/Skills/new-skills/antigravity-rotator/assets/config.example.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "//_comment_1": "【必填】你的 openclaw 可执行文件路径。运行 'node index.js --action=setup' 可尝试自动获取。", - "openclawBin": "/usr/local/bin/openclaw", - - "//_comment_2": "【可选】仪表盘访问端口,默认 18090。", - "dashboardPort": 18090, - - "//_comment_3": "【必填】模型优先级列表,从上往下优先级递减。", - "modelPriority": [ - "google-antigravity/claude-sonnet-4-5", - "google-antigravity/gemini-3-flash", - "google-antigravity/gemini-3-pro-low", - "google-antigravity/gemini-3-pro-high", - "google-antigravity/claude-opus-4-5-thinking", - "google-antigravity/claude-sonnet-4-5-thinking" - ], - - "//_comment_4": "【监控账号】可以通过看板‘同步凭证’自动发现,也可以在此手动填入 Gmail 地址。", - "accounts": [], - - "//_comment_5": "【高级配置】Google OAuth 凭证。通常无需修改,除非你有自己的项目。", - "clientId": "YOUR_CLIENT_ID_HERE.apps.googleusercontent.com", - "clientSecret": "GOCSPX-YOUR_CLIENT_SECRET_HERE", - "defaultProjectId": "YOUR_PROJECT_ID", - - "//_comment_6": "【阈值设置】当模型配额低于此百分比时触发轮换。", - "quotas": { - "low": 21 - }, - - "//_comment_7": "【路径配置】通常无需修改。系统会自动在你的 .openclaw 目录下寻找文件。", - "paths": { - "home": null, - "authProfiles": ".openclaw/agents/main/agent/auth-profiles.json", - "statusDb": ".openclaw/workspace/memory/model-status.json", - "rotationLog": ".openclaw/workspace/memory/rotation.log", - "rotationState": ".openclaw/workspace/memory/rotation-state.json" - } -} diff --git a/Skills/new-skills/antigravity-rotator/assets/crontab.sample.txt b/Skills/new-skills/antigravity-rotator/assets/crontab.sample.txt deleted file mode 100644 index 02b508f..0000000 --- a/Skills/new-skills/antigravity-rotator/assets/crontab.sample.txt +++ /dev/null @@ -1 +0,0 @@ -*/10 * * * * /home/chocomint/.nvm/versions/node/v24.13.0/bin/node /home/chocomint/.openclaw/workspace/skills/antigravity-rotator/index.js --action=rotate >> /tmp/antigravity-rotate.log 2>&1 diff --git a/Skills/new-skills/antigravity-rotator/index.js b/Skills/new-skills/antigravity-rotator/index.js deleted file mode 100644 index b477c10..0000000 --- a/Skills/new-skills/antigravity-rotator/index.js +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env node -const fs = require('fs'); -const path = require('path'); -const Rotator = require('./scripts/rotator'); -const Dashboard = require('./scripts/dashboard'); - -// 1. Load Config -const configPath = path.resolve(__dirname, 'config.json'); -const exampleConfigPath = path.resolve(__dirname, 'assets/config.example.json'); - -if (!fs.existsSync(configPath)) { - if (fs.existsSync(exampleConfigPath)) { - console.log("ℹ️ Config file not found. Creating default config from example..."); - fs.copyFileSync(exampleConfigPath, configPath); - } else { - console.error("❌ config.json not found and no example available."); - process.exit(1); - } -} - -const config = JSON.parse(fs.readFileSync(configPath, 'utf8')); - -// 2. Parse Args -const args = process.argv.slice(2); -let action = 'rotate'; // default - -args.forEach(arg => { - if (arg.startsWith('--action=')) { - action = arg.split('=')[1]; - } -}); - -// 3. Execute -(async () => { - if (action === 'setup') { - console.log("🛠️ Antigravity Rotator Setup Helper"); - const { execSync } = require('child_process'); - try { - const openclawPath = execSync('which openclaw', { encoding: 'utf8' }).trim(); - const nodePath = process.execPath; - console.log(`\nFound openclaw at: ${openclawPath}`); - console.log(`Found node at: ${nodePath}`); - - config.openclawBin = openclawPath; - fs.writeFileSync(configPath, JSON.stringify(config, null, 2)); - - console.log("\n✅ config.json has been updated with your local paths."); - console.log("\nNext steps:"); - console.log(`1. Run dashboard: node ${path.relative(process.cwd(), __filename)} --action=dashboard`); - console.log(`2. Setup cron (recommended):`); - console.log(` */10 * * * * ${nodePath} ${path.resolve(__filename)} --action=rotate >> /tmp/antigravity-rotate.log 2>&1`); - } catch (e) { - console.error("\n❌ Could not automatically find openclaw. Please set 'openclawBin' in config.json manually."); - } - return; - } - - if (action === 'rotate') { - const rotator = new Rotator(config); - await rotator.run(); - } else if (action === 'dashboard') { - const dashboard = new Dashboard(config); - dashboard.start(); - } else { - console.error(`Unknown action: ${action}`); - console.log("Available actions: --action=rotate, --action=dashboard"); - } -})(); diff --git a/Skills/new-skills/antigravity-rotator/package.json b/Skills/new-skills/antigravity-rotator/package.json deleted file mode 100644 index 18be6ba..0000000 --- a/Skills/new-skills/antigravity-rotator/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "antigravity-rotator", - "version": "1.1.0", - "description": "Google Antigravity 模型自动轮换引擎与看板。支持多账号余额监控、优先级调度、VIP 自动热更以及赛博朋克风格仪表盘。", - "main": "index.js", - "author": "Antigravity", - "license": "MIT" -} diff --git a/Skills/new-skills/antigravity-rotator/scripts/dashboard.js b/Skills/new-skills/antigravity-rotator/scripts/dashboard.js deleted file mode 100644 index 5904036..0000000 --- a/Skills/new-skills/antigravity-rotator/scripts/dashboard.js +++ /dev/null @@ -1,416 +0,0 @@ -const fs = require('fs'); -const http = require('http'); -const path = require('path'); -const { exec, execSync } = require('child_process'); - -class Dashboard { - constructor(config) { - this.config = config; - this.configPath = path.resolve(__dirname, '../config.json'); - this.home = config.paths.home || process.env.HOME; - - this.paths = { - authProfiles: path.resolve(this.home, config.paths.authProfiles), - statusDb: path.resolve(this.home, config.paths.statusDb), - rotationLog: path.resolve(this.home, config.paths.rotationLog), - rotationState: path.resolve(this.home, config.paths.rotationState) - }; - - // Path handling - this.openclawBin = config.openclawBin; - if (!this.openclawBin) { - try { this.openclawBin = execSync('which openclaw', { encoding: 'utf8' }).trim(); } catch(e) {} - } - - // Inject PATH for node/openclaw compatibility - const nodeBinPath = path.dirname(process.execPath); - process.env.PATH = nodeBinPath + ':' + process.env.PATH; - - this.getCoreModels = () => { - const priority = this.config.modelPriority || []; - return priority.slice(0, 3); - }; - } - - readJson(p) { try { return JSON.parse(fs.readFileSync(p, 'utf8')); } catch { return {}; } } - writeJson(p, d) { fs.writeFileSync(p, JSON.stringify(d, null, 2)); } - - getActiveAccount() { - try { - const authData = this.readJson(this.paths.authProfiles); - const vip = authData.profiles?.['google-antigravity:vip_rotation']; - if (!vip?.access) return null; - for (const acc of this.config.accounts) { - const realKey = `google-antigravity:${acc}`; - if (authData.profiles?.[realKey]?.access === vip.access) return acc; - } - } catch (e) { } - return null; - } - - getRotationLogs() { - try { - const content = fs.readFileSync(this.paths.rotationLog, 'utf8'); - const lines = content.trim().split('\n').slice(-100).reverse(); - return lines.map(line => { - const match = line.match(/\[(.*?)\] (.*)/); - if (match) { - let time = match[1]; - let msg = match[2]; - try { if (time.includes('T') || time.includes('-')) time = new Date(time).toLocaleTimeString('zh-CN'); } catch(e) {} - return { time, message: msg }; - } - return { time: '', message: line }; - }); - } catch (e) { return []; } - } - - async getDetailedLog() { - try { - const cronLog = path.join(this.home, '.openclaw/workspace/memory/cron-rotate.log'); - if (fs.existsSync(cronLog)) { - const content = fs.readFileSync(cronLog, 'utf8'); - const lastPart = content.slice(-20000); - const sections = lastPart.split(/=== (余量查询 & 自动轮换|Antigravity Rotator Engine)/); - if (sections.length > 1) return '=== ' + sections.pop(); - return lastPart; - } - } catch (e) {} - return '暂无详细日志数据。'; - } - - formatTimeLeft(resetAt) { - const now = Date.now(); - const diff = resetAt - now; - if (diff <= 0) return '已满'; - const hours = Math.floor(diff / (1000 * 60 * 60)); - const mins = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)); - return hours > 0 ? `${hours}时 ${mins}分` : `${mins}分钟`; - } - - generateHTML() { - const statusDb = this.readJson(this.paths.statusDb); - const logs = this.getRotationLogs(); - const now = new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' }); - - let activeAccount = null; - let activeModel = null; - if (this.openclawBin) { - try { - const statusJson = execSync(`${this.openclawBin} gateway call status --params "{}" --json`, { encoding: 'utf8' }); - const realStatus = JSON.parse(statusJson); - const mainSession = realStatus.sessions?.recent?.find(s => s.key === 'agent:main:main'); - activeModel = mainSession?.model; - } catch (e) {} - } - - activeAccount = this.getActiveAccount(); - const coreModelKeys = this.getCoreModels(); - const allModelKeys = this.config.modelPriority || []; - - let accountCards = ''; - for (const acc of this.config.accounts) { - if (!acc || typeof acc !== 'string' || !acc.includes('@')) continue; - const isActive = acc === activeAccount; - const shortName = acc.split('@')[0]; - let modelsHtml = ''; - let lastUpdated = 0; - - for (const modelKey of coreModelKeys) { - const key = `${acc}:${modelKey}`; - const info = statusDb[key]; - if (!info) continue; - const quota = info.quota || 0; - const resetText = info.resetAt ? this.formatTimeLeft(info.resetAt) : '-'; - if (info.updatedAt > lastUpdated) lastUpdated = info.updatedAt; - let barClass = quota < 20 ? 'bar-critical' : (quota < 50 ? 'bar-warning' : 'bar-high'); - const displayName = modelKey.replace('google-antigravity/', ''); - const isModelCurrentlyActive = isActive && (activeModel === modelKey || activeModel === modelKey.split('/').pop()); - - modelsHtml += ` -
-
- ${displayName} ${isModelCurrentlyActive ? '🔥' : ''} - ${quota}% -
-
-
重置: ${resetText}
-
`; - } - - const updateTimeStr = lastUpdated ? new Date(lastUpdated).toLocaleTimeString() : '无数据'; - accountCards += ` -
-
- - ${isActive ? '正在使用' : ''} - -
-
${modelsHtml || '
暂无配额数据
'}
- -
`; - } - - let priorityHtml = allModelKeys.map((m, i) => { - const displayName = m.replace('google-antigravity/', ''); - return ` -
- ${i + 1}. ${displayName} -
- - -
-
`; - }).join(''); - - let logsHtml = logs.map(l => ` -
- ${l.time || ''} - ${l.message} - -
- `).join(''); - - return ` - - - - - - Antigravity 矩阵看板 - - - -
-
-
-
Antigravity 矩阵看板
-
● 在线
-
-
- ${now} - - -
-
- -
${accountCards}
- -
- - - -
-
- - - - - - - -`; - } - - start() { - const port = this.config.dashboardPort || 18090; - const server = http.createServer(async (req, res) => { - if (req.url === '/' && req.method === 'GET') { - res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); - res.end(this.generateHTML()); - } else if (req.url === '/api' && req.method === 'POST') { - let body = ''; - req.on('data', chunk => body += chunk); - req.on('end', async () => { - try { - const data = JSON.parse(body); - const result = await this.handleApi(data); - res.writeHead(200, { 'Content-Type': 'application/json' }); - res.end(JSON.stringify(result)); - } catch (e) { - res.writeHead(400); - res.end(JSON.stringify({ success: false, message: e.message })); - } - }); - } else { - res.writeHead(404); - res.end('Not Found'); - } - }); - server.listen(port, '0.0.0.0', () => { console.log(`\n🔮 Antigravity Dashboard started on http://0.0.0.0:${port}`); }); - } - - async handleApi(data) { - const { action } = data; - let changed = false; - const currentConfig = this.readJson(this.configPath); - - if (action === 'addAccount') { - if (!currentConfig.accounts.includes(data.email)) { currentConfig.accounts.push(data.email); changed = true; } - } else if (action === 'removeAccount') { - currentConfig.accounts = currentConfig.accounts.filter(a => a !== data.email); changed = true; - } else if (action === 'syncAccounts') { - const authData = this.readJson(this.paths.authProfiles); - const antigravityAccounts = Object.keys(authData.profiles || {}).filter(k => k.startsWith('google-antigravity:')).map(k => k.replace('google-antigravity:', '')); - let added = 0; - for (const email of antigravityAccounts) { if (!currentConfig.accounts.includes(email)) { currentConfig.accounts.push(email); added++; changed = true; } } - if (added > 0) { this.writeJson(this.configPath, currentConfig); this.config = currentConfig; } - return { success: true, added, accounts: antigravityAccounts }; - } else if (action === 'movePriority') { - const { index, direction } = data; - const newIndex = index + direction; - if (newIndex >= 0 && newIndex < currentConfig.modelPriority.length) { - const item = currentConfig.modelPriority.splice(index, 1)[0]; - currentConfig.modelPriority.splice(newIndex, 0, item); changed = true; - } - } else if (action === 'setPriority') { - if (Array.isArray(data.order) && data.order.length > 0) { currentConfig.modelPriority = data.order; changed = true; } - } else if (action === 'triggerRotate') { - const indexPath = path.resolve(__dirname, '../index.js'); - exec(`node ${indexPath} --action=rotate`, (err, stdout) => { console.log('Manual rotation output:', stdout); }); - return { success: true, message: 'Rotation triggered' }; - } else if (action === 'getDetailedLog') { - const log = await this.getDetailedLog(); - return { success: true, log }; - } - - if (changed) { this.writeJson(this.configPath, currentConfig); this.config = currentConfig; return { success: true }; } - return { success: false, message: 'No action taken' }; - } -} - -module.exports = Dashboard; diff --git a/Skills/new-skills/antigravity-rotator/scripts/rotator.js b/Skills/new-skills/antigravity-rotator/scripts/rotator.js deleted file mode 100644 index 38b0da2..0000000 --- a/Skills/new-skills/antigravity-rotator/scripts/rotator.js +++ /dev/null @@ -1,243 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const { execSync } = require('child_process'); - -class Rotator { - constructor(config) { - this.config = config; - this.home = config.paths.home || process.env.HOME; - - this.paths = { - authProfiles: path.resolve(this.home, config.paths.authProfiles), - statusDb: path.resolve(this.home, config.paths.statusDb), - rotationLog: path.resolve(this.home, config.paths.rotationLog), - rotationState: path.resolve(this.home, config.paths.rotationState), - dashboardConfig: path.resolve(__dirname, '../config.json') - }; - - // API Configuration (configurable via config.json) - this.QUOTA_API_URL = 'https://daily-cloudcode-pa.sandbox.googleapis.com/v1internal:fetchAvailableModels'; - this.REFRESH_TOKEN_URL = 'https://oauth2.googleapis.com/token'; - - // OAuth Credentials (from config or hardcoded Antigravity defaults) - this.CLIENT_ID = config.clientId || 'YOUR_CLIENT_ID_HERE.apps.googleusercontent.com'; - this.CLIENT_SECRET = config.clientSecret || 'GOCSPX-YOUR_CLIENT_SECRET_HERE'; - this.DEFAULT_PROJECT_ID = config.defaultProjectId || 'YOUR_PROJECT_ID'; - - this.VIP_KEY = 'google-antigravity:vip_rotation'; - this.threshold = (config.quotas && config.quotas.low) || 21; - - // Path handling - this.openclawBin = config.openclawBin; - if (!this.openclawBin) { - try { this.openclawBin = execSync('which openclaw', { encoding: 'utf8' }).trim(); } catch(e) {} - } - - // Inject PATH for node/openclaw compatibility - const nodeBinPath = path.dirname(process.execPath); - process.env.PATH = nodeBinPath + ':' + process.env.PATH; - } - - readJson(p) { try { return JSON.parse(fs.readFileSync(p, 'utf8')); } catch { return {}; } } - writeJson(p, d) { fs.writeFileSync(p, JSON.stringify(d, null, 2)); } - appendLog(msg) { - try { fs.appendFileSync(this.paths.rotationLog, `[${new Date().toISOString()}] ${msg}\n`, 'utf8'); } catch { } - } - shortEmail(email) { return email.split('@')[0]; } - - async refreshAccessToken(refreshToken) { - const postData = new URLSearchParams({ - client_id: this.CLIENT_ID, - client_secret: this.CLIENT_SECRET, - refresh_token: refreshToken, - grant_type: 'refresh_token' - }).toString(); - const cmd = `curl -s --connect-timeout 10 --retry 1 -X POST "${this.REFRESH_TOKEN_URL}" -d "${postData}"`; - try { - const output = execSync(cmd, { encoding: 'utf8', timeout: 35000 }); - const json = JSON.parse(output); - if (json.access_token) return json.access_token; - throw new Error(json.error_description || 'Token refresh failed'); - } catch (e) { throw new Error(`Refresh Failed: ${e.message}`); } - } - - async fetchAccountQuota(accessToken, projectId) { - const headers = { 'Authorization': `Bearer ${accessToken}`, 'Content-Type': 'application/json', 'User-Agent': 'antigravity/1.15.8 linux/x64' }; - const body = { project: projectId || this.DEFAULT_PROJECT_ID }; - const headerArgs = Object.entries(headers).map(([k, v]) => `-H "${k}: ${v}"`).join(' '); - const bodyStr = JSON.stringify(body).replace(/"/g, '\\"'); - const cmd = `curl -s --connect-timeout 10 --retry 1 -X POST "${this.QUOTA_API_URL}" ${headerArgs} -d "${bodyStr}"`; - try { - const output = execSync(cmd, { encoding: 'utf8', timeout: 35000 }); - if (!output.trim()) throw new Error('Empty response'); - const data = JSON.parse(output); - if (data.error) { - if (data.error.code === 403) return { forbidden: true }; - throw new Error(data.error.message || data.error.status); - } - const quotas = {}; - for (const [mId, info] of Object.entries(data.models || {})) { - const fullKey = `google-antigravity/${mId}`; - const qI = info.quotaInfo; - const rT = qI && qI.resetTime ? new Date(qI.resetTime).getTime() : 0; - let pct = 100; - if (qI) { - if (qI.remainingFraction !== undefined) pct = Math.round(qI.remainingFraction * 100); - else if (rT > Date.now()) pct = 0; - } - quotas[fullKey] = { quota: pct, resetAt: rT, updatedAt: Date.now() }; - } - return quotas; - } catch (e) { throw new Error(`Quota Fetch Failed: ${e.message}`); } - } - - async run() { - if (!this.openclawBin) { console.error('❌ openclaw binary not found. Please run "node index.js --action=setup".'); return; } - console.log(`=== Antigravity Rotator Engine [${new Date().toLocaleTimeString()}] ===\n`); - const authData = this.readJson(this.paths.authProfiles); - const modelPriority = this.config.modelPriority || []; - const accounts = this.config.accounts || []; - if (accounts.length === 0) { console.log('⚠️ No accounts.'); return; } - - console.log(`📋 Accounts: ${accounts.map(a => this.shortEmail(a)).join(', ')}`); - console.log(`📋 Priority: ${modelPriority.map(m => m.split('/').pop()).join(' > ')}\n`); - - let currentModel = null; - try { - const statusOutput = execSync(`${this.openclawBin} gateway call status --params "{}" --json`, { encoding: 'utf8' }); - const status = JSON.parse(statusOutput); - currentModel = status.sessions?.recent?.find(s => s.key === 'agent:main:main')?.model || status.sessions?.defaults?.model; - if (currentModel) console.log(`📡 Current Session Model: ${currentModel}`); - } catch (e) { } - - if (!currentModel) currentModel = modelPriority[0]; - if (!currentModel.includes('/')) { - const full = `google-antigravity/${currentModel}`; - if (modelPriority.includes(full)) currentModel = full; - } - - const currentVip = authData.profiles?.[this.VIP_KEY]; - let currentEmail = accounts[0]; - for (const acc of accounts) { - if (authData.profiles[`google-antigravity:${acc}`]?.access === currentVip?.access) { - currentEmail = acc; break; - } - } - - if (!currentModel.startsWith('google-antigravity/')) { - console.log(`ℹ️ Non-Antigravity model (${currentModel}). Skipping.`); return; - } - - console.log(`Current: ${this.shortEmail(currentEmail)} | ${currentModel}\n`); - - const statusDb = this.readJson(this.paths.statusDb) || {}; - let success = 0; - let authUpdated = false; - - for (const email of accounts) { - const profile = authData.profiles?.[`google-antigravity:${email}`]; - if (!profile) continue; - try { - let token = profile.access; - const now = Date.now(); - if (!profile.expires || profile.expires < now + 300000) { - console.log(`🔄 ${this.shortEmail(email)}: Refreshing token...`); - token = await this.refreshAccessToken(profile.refresh); - authData.profiles[`google-antigravity:${email}`].access = token; - authData.profiles[`google-antigravity:${email}`].expires = now + 3600000; - if (currentVip && currentVip.refresh === profile.refresh) { - authData.profiles[this.VIP_KEY].access = token; - authData.profiles[this.VIP_KEY].expires = now + 3600000; - } - authUpdated = true; - } - console.log(`📡 ${this.shortEmail(email)}: Fetching quotas...`); - const quotas = await this.fetchAccountQuota(token, profile.projectId); - if (quotas.forbidden) continue; - for (const [m, d] of Object.entries(quotas)) { - statusDb[`${email}:${m}`] = d; - console.log(` ${m.split('/').pop()}: ${d.quota}%`); - } - success++; - } catch (e) { console.log(`❌ ${this.shortEmail(email)}: ${e.message}`); } - } - - if (authUpdated) this.writeJson(this.paths.authProfiles, authData); - this.writeJson(this.paths.statusDb, statusDb); - if (success === 0) return; - - let choice = null; - const now = Date.now(); - for (const model of modelPriority) { - const startIdx = accounts.indexOf(currentEmail); - for (let i = 0; i < accounts.length; i++) { - const acc = accounts[(Math.max(0, startIdx) + i) % accounts.length]; - const info = statusDb[`${acc}:${model}`]; - if (!info) continue; - if (info.quota >= this.threshold || (info.resetAt && now > info.resetAt)) { - if (acc === currentEmail && model === currentModel) choice = { email: acc, model, reason: 'Maintain' }; - else if (modelPriority.indexOf(model) < modelPriority.indexOf(currentModel)) choice = { email: acc, model, reason: 'Upgrade Model' }; - else if ((statusDb[`${currentEmail}:${currentModel}`]?.quota || 0) < this.threshold) choice = { email: acc, model, reason: 'Quota Low' }; - if (choice) break; - } - } - if (choice) break; - } - - if (!choice) return; - if (choice.reason === 'Maintain') { - console.log("\n✅ Status Quo: Maintaining current setup."); - } else { - this.performRotation(authData, choice, currentEmail, currentModel); - } - await this.warmup(statusDb, authData, modelPriority, accounts); - } - - performRotation(authData, choice, currentEmail, currentModel) { - const nextKey = `google-antigravity:${choice.email}`; - authData.profiles[this.VIP_KEY] = { ...authData.profiles[nextKey], email: 'vip_rotation_active' }; - this.writeJson(this.paths.authProfiles, authData); - - try { execSync(`${this.openclawBin} models set ${choice.model}`); } catch (e) { } - try { - const patch = JSON.stringify({ key: 'agent:main:main', model: choice.model }); - execSync(`${this.openclawBin} gateway call sessions.patch --params '${patch}'`); - } catch (e) { } - - this.writeJson(this.paths.rotationState, { - lastRotation: Date.now(), previousAccount: currentEmail, newAccount: choice.email, - previousModel: currentModel, newModel: choice.model, pendingNotification: true, reason: choice.reason - }); - - const zhReason = { 'Maintain': '维持', 'Upgrade Model': '调度更高优先级', 'Quota Low': '余量过低' }[choice.reason] || choice.reason; - this.appendLog(`✅ 已轮换账号:${this.shortEmail(choice.email)} | 模型:${choice.model.split('/').pop()} | 原因:${zhReason}`); - console.log(`\n✅ Rotation: ${this.shortEmail(currentEmail)} → ${this.shortEmail(choice.email)} (${zhReason})`); - } - - async warmup(statusDb, authData, modelPriority, accounts) { - const TOP = modelPriority.slice(0, 3); - const toW = []; - for (const acc of accounts) { - for (const m of TOP) { - const info = statusDb[`${acc}:${m}`]; - if (info && info.quota >= 100 && !info.resetAt) toW.push({ acc, m }); - } - } - if (toW.length === 0) return; - console.log(`\n🔥 Warming up ${toW.length} models...`); - for (const { acc, m } of toW) { - try { - const originalVip = authData.profiles[this.VIP_KEY]; - authData.profiles[this.VIP_KEY] = { ...authData.profiles[`google-antigravity:${acc}`], email: 'warmup_temp' }; - this.writeJson(this.paths.authProfiles, authData); - const sId = `warmup-${Date.now()}`; - execSync(`${this.openclawBin} gateway call sessions.patch --params '{"key":"agent:main:${sId}","model":"${m}"}'`); - execSync(`timeout 10 ${this.openclawBin} agent --session-id ${sId} --message "1" --json 2>/dev/null || true`); - if (originalVip) { authData.profiles[this.VIP_KEY] = originalVip; this.writeJson(this.paths.authProfiles, authData); } - console.log(` ✅ ${this.shortEmail(acc)} / ${m.split('/').pop()}`); - } catch (e) { } - } - } -} - -module.exports = Rotator; diff --git a/Skills/new-skills/antigravity-skill-orchestrator/README.md b/Skills/new-skills/antigravity-skill-orchestrator/README.md deleted file mode 100644 index c1fb179..0000000 --- a/Skills/new-skills/antigravity-skill-orchestrator/README.md +++ /dev/null @@ -1,32 +0,0 @@ -# antigravity-skill-orchestrator - -A meta-skill package for the Antigravity IDE ecosystem. - -## Overview - -The `antigravity-skill-orchestrator` is an intelligent meta-skill that enhances an AI agent's ability to handle complex, multi-domain tasks. It provides strict guidelines and workflows enabling the agent to: - -1. **Evaluate Task Complexity**: Implementing guardrails to prevent the overuse of specialized skills on simple, straightforward tasks. -2. **Dynamically Select Skills**: Identifying the best combination of skills for a given complex problem. -3. **Track Skill Combinations**: Utilizing the `agent-memory-mcp` skill to store, search, and retrieve successful skill combinations for future reference, building institutional knowledge over time. - -## Installation - -This skill is designed to be used within the Antigravity IDE and integrated alongside the existing suite of AWESOME skills. - -Make sure you have the `agent-memory-mcp` skill installed and running to take full advantage of the combination tracking feature. - -## Usage - -When executing a prompt with an AI assistant via the Antigravity IDE, you can invoke this skill: - -```bash -@antigravity-skill-orchestrator Please build a comprehensive dashboard integrating fetching live data, an interactive UI, and performance optimizations. -``` - -The agent will then follow the directives in the `SKILL.md` to break down the task, search memory for similar challenges, assemble the right team of skills (e.g., `@react-patterns` + `@nodejs-backend-patterns`), and execute the task without over-complicating it. - ---- - -**Author:** [Wahid](https://github.com/wahidzzz) -**Source:** [antigravity-skill-orchestrator](https://github.com/wahidzzz/antigravity-skill-orchestrator) diff --git a/Skills/new-skills/antigravity-skill-orchestrator/SKILL.md b/Skills/new-skills/antigravity-skill-orchestrator/SKILL.md deleted file mode 100644 index 7bc1ebd..0000000 --- a/Skills/new-skills/antigravity-skill-orchestrator/SKILL.md +++ /dev/null @@ -1,123 +0,0 @@ ---- -name: antigravity-skill-orchestrator -description: "A meta-skill that understands task requirements, dynamically selects appropriate skills, tracks successful skill combinations using agent-memory-mcp, and prevents skill overuse for simple tasks." -category: meta -risk: safe -source: community -tags: "[orchestration, meta-skill, agent-memory, task-evaluation]" -date_added: "2026-03-13" ---- - -# antigravity-skill-orchestrator - -## Overview - -The `skill-orchestrator` is a meta-skill designed to enhance the AI agent's ability to tackle complex problems. It acts as an intelligent coordinator that first evaluates the complexity of a user's request. Based on that evaluation, it determines if specialized skills are needed. If they are, it selects the right combination of skills, explicitly tracks these combinations using `@agent-memory-mcp` for future reference, and guides the agent through the execution process. Crucially, it includes strict guardrails to prevent the unnecessary use of specialized skills for simple tasks that can be solved with baseline capabilities. - -## When to Use This Skill - -- Use when tackling a complex, multi-step problem that likely requires multiple domains of expertise. -- Use when you are unsure which specific skills are best suited for a given user request, and need to discover them from the broader ecosystem. -- Use when the user explicitly asks to "orchestrate", "combine skills", or "use the best tools for the job" on a significant task. -- Use when you want to look up previously successful combinations of skills for a specific type of problem. - -## Core Concepts - -### Task Evaluation Guardrails -Not every task requires a specialized skill. For straightforward issues (e.g., small CSS fixes, simple script writing, renaming a variable), **DO NOT USE** specialized skills. Over-engineering simple tasks wastes tokens and time. - -Additionally, the orchestrator is strictly forbidden from creating new skills. Its sole purpose is to combine and use existing skills provided by the community or present in the current environment. - -Before invoking any skills, evaluate the task: -1. **Is the task simple/contained?** Solve it directly using the agent's ordinary file editing, search, and terminal capabilities available in the current environment. -2. **Is the task complex/multi-domain?** Only then should you proceed to orchestrate skills. - -### Skill Selection & Combinations -When a task is deemed complex, identify the necessary domains (e.g., frontend, database, deployment). Search available skills in the current environment to find the most relevant ones. If the required skills are not found locally, consult the master skill catalog. - -### Master Skill Catalog -The Antigravity ecosystem maintains a master catalog of highly curated skills at `https://raw.githubusercontent.com/sickn33/antigravity-awesome-skills/main/CATALOG.md`. When local skills are insufficient, fetch this catalog to discover appropriate skills across the 9 primary categories: -- `architecture` -- `business` -- `data-ai` -- `development` -- `general` -- `infrastructure` -- `security` -- `testing` -- `workflow` - -### Memory Integration (`@agent-memory-mcp`) -To build institutional knowledge, the orchestrator relies on the `agent-memory-mcp` skill to record and retrieve successful skill combinations. - -## Step-by-Step Guide - -### 1. Task Evaluation & Guardrail Check -[Triggered when facing a new user request that might need skills] -1. Read the user's request. -2. Ask yourself: "Can I solve this efficiently with just basic file editing and terminal commands?" -3. If YES: Proceed without invoking specialized skills. Stop the orchestration here. -4. If NO: Proceed to step 2. - -### 2. Retrieve Past Knowledge -[Triggered if the task is complex] -1. Use the `memory_search` tool provided by `agent-memory-mcp` to search for similar past tasks. - - Example query: `memory_search({ query: "skill combination for react native and firebase", type: "skill_combination" })` -2. If a working combination exists, read the details using `memory_read`. -3. If no relevant memory exists, proceed to Step 3. - -### 3. Discover and Select Skills -[Triggered if no past knowledge covers this task] -1. Analyze the core requirements (e.g., "needs a React UI, a Node.js backend, and a PostgreSQL database"). -2. Query the locally available skills using the current environment's skill list or equivalent discovery mechanism to find the best match for each requirement. -3. **If local skills are insufficient**, fetch the master catalog with the web or command-line retrieval tools available in the current environment: `https://raw.githubusercontent.com/sickn33/antigravity-awesome-skills/main/CATALOG.md`. -4. Scan the catalog's 9 main categories to identify the appropriate skills to bring into the current context. -5. Select the minimal set of skills needed. **Do not over-select.** - -### 4. Apply Skills and Track the Combination -[Triggered after executing the task using the selected skills] -1. Assume the task was completed successfully using a new combination of skills (e.g., `@react-patterns` + `@nodejs-backend-patterns` + `@postgresql`). -2. Record this combination for future use using `memory_write` from `agent-memory-mcp`. - - Ensure the type is `skill_combination`. - - Provide a descriptive key and content detailing why these skills worked well together. - -## Examples - -### Example 1: Handling a Simple Task (The Guardrail in Action) -**User Request:** "Change the color of the submit button in `index.css` to blue." -**Action:** The skill orchestrator evaluates the task. It determines this is a "simple/contained" task. It **does not** invoke specialized skills. It directly edits `index.css`. - -### Example 2: Recording a New Skill Combination -```javascript -// Using the agent-memory-mcp tool after successfully building a complex feature -memory_write({ - key: "combination-ecommerce-checkout", - type: "skill_combination", - content: "For e-commerce checkouts, using @stripe-integration combined with @react-state-management and @postgresql effectively handles the full flow from UI state to payment processing to order recording.", - tags: ["ecommerce", "checkout", "stripe", "react"] -}) -``` - -### Example 3: Retrieving a Combination -```javascript -// At the start of a new e-commerce task -memory_search({ - query: "ecommerce checkout", - type: "skill_combination" -}) -// Returns the key "combination-ecommerce-checkout", which you then read: -memory_read({ key: "combination-ecommerce-checkout" }) -``` - -## Best Practices - -- ✅ **Do:** Always evaluate task complexity *before* looking for skills. -- ✅ **Do:** Keep the number of orchestrated skills as small as possible. -- ✅ **Do:** Use highly descriptive keys when running `memory_write` so they are easy to search later. -- ❌ **Don't:** Use this skill for simple bug fixes or UI tweaks. -- ❌ **Don't:** Combine skills that have overlapping and conflicting instructions without a clear plan to resolve the conflict. -- ❌ **Don't:** Attempt to construct, generate, or create new skills. Only combine what is available. - -## Related Skills - -- `@agent-memory-mcp` - Essential for this skill to function. Provides the persistent storage for skill combinations. diff --git a/Skills/new-skills/antigravity-workflows/SKILL.md b/Skills/new-skills/antigravity-workflows/SKILL.md deleted file mode 100644 index f807395..0000000 --- a/Skills/new-skills/antigravity-workflows/SKILL.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -name: antigravity-workflows -description: "Orchestrate multiple Antigravity skills through guided workflows for SaaS MVP delivery, security audits, AI agent builds, and browser QA." -risk: none -source: self -date_added: "2026-02-27" ---- - -# Antigravity Workflows - -Use this skill to turn a complex objective into a guided sequence of skill invocations. - -## When to Use This Skill - -Use this skill when: -- The user wants to combine several skills without manually selecting each one. -- The goal is multi-phase (for example: plan, build, test, ship). -- The user asks for best-practice execution for common scenarios like: - - Shipping a SaaS MVP - - Running a web security audit - - Building an AI agent system - - Implementing browser automation and E2E QA - -## Workflow Source of Truth - -Read workflows in this order: -1. `docs/WORKFLOWS.md` for human-readable playbooks. -2. `data/workflows.json` for machine-readable workflow metadata. - -## How to Run This Skill - -1. Identify the user's concrete outcome. -2. Propose the 1-2 best matching workflows. -3. Ask the user to choose one. -4. Execute step-by-step: - - Announce current step and expected artifact. - - Invoke recommended skills for that step. - - Verify completion criteria before moving to next step. -5. At the end, provide: - - Completed artifacts - - Validation evidence - - Remaining risks and next actions - -## Default Workflow Routing - -- Product delivery request -> `ship-saas-mvp` -- Security review request -> `security-audit-web-app` -- Agent/LLM product request -> `build-ai-agent-system` -- E2E/browser testing request -> `qa-browser-automation` -- Domain-driven design request -> `design-ddd-core-domain` - -## Copy-Paste Prompts - -```text -Use @antigravity-workflows to run the "Ship a SaaS MVP" workflow for my project idea. -``` - -```text -Use @antigravity-workflows and execute a full "Security Audit for a Web App" workflow. -``` - -```text -Use @antigravity-workflows to guide me through "Build an AI Agent System" with checkpoints. -``` - -```text -Use @antigravity-workflows to execute the "QA and Browser Automation" workflow and stabilize flaky tests. -``` - -```text -Use @antigravity-workflows to execute the "Design a DDD Core Domain" workflow for my new service. -``` - -## Limitations - -- This skill orchestrates; it does not replace specialized skills. -- It depends on the local availability of referenced skills. -- It does not guarantee success without environment access, credentials, or required infrastructure. -- For stack-specific browser automation in Go, `go-playwright` may require the corresponding skill to be present in your local skills repository. - -## Related Skills - -- `concise-planning` -- `brainstorming` -- `workflow-automation` -- `verification-before-completion` diff --git a/Skills/new-skills/antigravity-workflows/resources/implementation-playbook.md b/Skills/new-skills/antigravity-workflows/resources/implementation-playbook.md deleted file mode 100644 index 9db5deb..0000000 --- a/Skills/new-skills/antigravity-workflows/resources/implementation-playbook.md +++ /dev/null @@ -1,36 +0,0 @@ -# Antigravity Workflows Implementation Playbook - -This document explains how an agent should execute workflow-based orchestration. - -## Execution Contract - -For every workflow: - -1. Confirm objective and scope. -2. Select the best-matching workflow. -3. Execute workflow steps in order. -4. Produce one concrete artifact per step. -5. Validate before continuing. - -## Step Artifact Examples - -- Plan step -> scope document or milestone checklist. -- Build step -> code changes and implementation notes. -- Test step -> test results and failure triage. -- Release step -> rollout checklist and risk log. - -## Safety Guardrails - -- Never run destructive actions without explicit user approval. -- If a required skill is missing, state the gap and fallback to closest available skill. -- When security testing is involved, ensure authorization is explicit. - -## Suggested Completion Format - -At workflow completion, return: - -1. Completed steps -2. Artifacts produced -3. Validation evidence -4. Open risks -5. Suggested next action diff --git a/Skills/new-skills/trellis-meta/SKILL.md b/Skills/new-skills/trellis-meta/SKILL.md deleted file mode 100644 index 5a6d1cb..0000000 --- a/Skills/new-skills/trellis-meta/SKILL.md +++ /dev/null @@ -1,468 +0,0 @@ ---- -name: trellis-meta -description: | - Meta-skill for understanding and customizing Mindfold Trellis - the all-in-one AI workflow system for 9 AI coding platforms (Claude Code, Cursor, OpenCode, iFlow, Codex, Kilo, Kiro, Gemini CLI, Antigravity). This skill documents the ORIGINAL Trellis system design. When users customize their Trellis installation, modifications should be recorded in a project-local `trellis-local` skill, NOT in this meta-skill. Use this skill when: (1) understanding Trellis architecture, (2) customizing Trellis workflows, (3) adding commands/agents/hooks, (4) troubleshooting issues, or (5) adapting Trellis to specific projects. ---- - -# Trellis Meta-Skill - -## Version Compatibility - -| Item | Value | -| --------------------------- | ---------- | -| **Trellis CLI Version** | 0.3.0 | -| **Skill Last Updated** | 2026-02-28 | -| **Min Claude Code Version** | 1.0.0+ | - -> ⚠️ **Version Mismatch Warning**: If your Trellis CLI version differs from above, some features may not work as documented. Run `trellis --version` to check. - ---- - -## Platform Compatibility - -### Feature Support Matrix - -| Feature | Claude Code | iFlow | Cursor | OpenCode | Codex | Kilo | Kiro | Gemini CLI | Antigravity | -| --------------------------- | ----------- | ------- | ---------- | ---------- | ---------- | ---------- | ---------- | ---------- | ------------ | -| **Core Systems** | | | | | | | | | | -| Workspace system | ✅ Full | ✅ Full | ✅ Full | ✅ Full | ✅ Full | ✅ Full | ✅ Full | ✅ Full | ✅ Full | -| Task system | ✅ Full | ✅ Full | ✅ Full | ✅ Full | ✅ Full | ✅ Full | ✅ Full | ✅ Full | ✅ Full | -| Spec system | ✅ Full | ✅ Full | ✅ Full | ✅ Full | ✅ Full | ✅ Full | ✅ Full | ✅ Full | ✅ Full | -| Commands/Skills | ✅ Full | ✅ Full | ✅ Full | ✅ Full | ✅ Skills | ✅ Full | ✅ Skills | ✅ TOML | ✅ Workflows | -| Agent definitions | ✅ Full | ✅ Full | ⚠️ Manual | ✅ Full | ⚠️ Manual | ⚠️ Manual | ⚠️ Manual | ⚠️ Manual | ⚠️ Manual | -| **Hook-Dependent Features** | | | | | | | | | | -| SessionStart hook | ✅ Full | ✅ Full | ❌ None | ❌ None | ❌ None | ❌ None | ❌ None | ❌ None | ❌ None | -| PreToolUse hook | ✅ Full | ✅ Full | ❌ None | ❌ None | ❌ None | ❌ None | ❌ None | ❌ None | ❌ None | -| SubagentStop hook | ✅ Full | ✅ Full | ❌ None | ❌ None | ❌ None | ❌ None | ❌ None | ❌ None | ❌ None | -| Auto context injection | ✅ Full | ✅ Full | ❌ Manual | ❌ Manual | ❌ Manual | ❌ Manual | ❌ Manual | ❌ Manual | ❌ Manual | -| Ralph Loop | ✅ Full | ✅ Full | ❌ None | ❌ None | ❌ None | ❌ None | ❌ None | ❌ None | ❌ None | -| **Multi-Agent/Session** | | | | | | | | | | -| Multi-Agent (current dir) | ✅ Full | ✅ Full | ⚠️ Limited | ⚠️ Limited | ⚠️ Limited | ⚠️ Limited | ⚠️ Limited | ⚠️ Limited | ⚠️ Limited | -| Multi-Session (worktrees) | ✅ Full | ✅ Full | ❌ None | ❌ None | ❌ None | ❌ None | ❌ None | ❌ None | ❌ None | - -### Legend - -- ✅ **Full**: Feature works as documented -- ⚠️ **Limited/Manual**: Works but requires manual steps -- ❌ **None/Manual**: Not supported or requires manual workaround - -### Platform Categories - -#### Full Hook Support (Claude Code, iFlow) - -All features work as documented. Hooks provide automatic context injection and quality enforcement. iFlow shares the same Python hook system as Claude Code. - -#### Commands Only (Cursor, OpenCode, Codex, Kilo, Kiro, Gemini CLI, Antigravity) - -- **Works**: Workspace, tasks, specs, commands/skills (platform-specific format) -- **Doesn't work**: Hooks, auto-injection, Ralph Loop, Multi-Session -- **Workaround**: Manually read spec files at session start; no automatic quality gates -- **Note**: Each platform uses its own command format (Codex uses Skills, Gemini uses TOML, Antigravity uses Workflows) - -### Designing for Portability - -When customizing Trellis, consider platform compatibility: - -``` -┌─────────────────────────────────────────────────────────────┐ -│ PORTABLE (All 9 Platforms) │ -│ - .trellis/workspace/ - .trellis/tasks/ │ -│ - .trellis/spec/ - Platform commands/skills │ -│ - File-based configs - JSONL context files │ -└─────────────────────────────────────────────────────────────┘ - │ -┌─────────────────────────────▼───────────────────────────────┐ -│ HOOK-CAPABLE (Claude Code + iFlow) │ -│ - .claude/hooks/ or .iflow/hooks/ │ -│ - settings.json hook configuration │ -│ - Auto context injection - SubagentStop control │ -│ - Ralph Loop - Multi-Session worktrees │ -└─────────────────────────────────────────────────────────────┘ -``` - ---- - -## Purpose - -This is the **meta-skill** for Trellis - it documents the original, unmodified Trellis system. When customizing Trellis for a specific project, record changes in a **project-local skill** (`trellis-local`), keeping this meta-skill as the authoritative reference for vanilla Trellis. - -## Skill Hierarchy - -``` -~/.claude/skills/ -└── trellis-meta/ # THIS SKILL - Original Trellis documentation - # ⚠️ DO NOT MODIFY for project-specific changes - -project/.claude/skills/ -└── trellis-local/ # Project-specific customizations - # ✅ Record all modifications here -``` - -**Why this separation?** - -- User may have multiple projects with different Trellis customizations -- Each project's `trellis-local` skill tracks ITS OWN modifications -- The meta-skill remains clean as the reference for original Trellis -- Enables easy upgrades: compare meta-skill with new Trellis version - ---- - -## Self-Iteration Protocol - -When modifying Trellis for a project, follow this protocol: - -### 1. Check for Existing Project Skill - -```bash -# Look for project-local skill -ls -la .claude/skills/trellis-local/ -``` - -### 2. Create Project Skill if Missing - -If no `trellis-local` exists, create it: - -```bash -mkdir -p .claude/skills/trellis-local -``` - -Then create `.claude/skills/trellis-local/SKILL.md`: - -```markdown ---- -name: trellis-local -description: | - Project-specific Trellis customizations for [PROJECT_NAME]. - This skill documents modifications made to the vanilla Trellis system - in this project. Inherits from trellis-meta for base documentation. ---- - -# Trellis Local - [PROJECT_NAME] - -## Base Version - -Trellis version: X.X.X (from package.json or trellis --version) -Date initialized: YYYY-MM-DD - -## Customizations - -### Commands Added - -(none yet) - -### Agents Modified - -(none yet) - -### Hooks Changed - -(none yet) - -### Specs Customized - -(none yet) - -### Workflow Changes - -(none yet) - ---- - -## Changelog - -### YYYY-MM-DD - -- Initial setup -``` - -### 3. Record Every Modification - -When making ANY change to Trellis, update `trellis-local/SKILL.md`: - -#### Example: Adding a new command - -```markdown -### Commands Added - -#### /trellis:my-command - -- **File**: `.claude/commands/trellis/my-command.md` -- **Purpose**: [what it does] -- **Added**: 2026-01-31 -- **Why**: [reason for adding] -``` - -#### Example: Modifying a hook - -```markdown -### Hooks Changed - -#### inject-subagent-context.py - -- **Change**: Added support for `my-agent` type -- **Lines modified**: 45-67 -- **Date**: 2026-01-31 -- **Why**: [reason] -``` - -### 4. Never Modify Meta-Skill for Project Changes - -The `trellis-meta` skill should ONLY be updated when: - -- Trellis releases a new version -- Fixing documentation errors in the original -- Adding missing documentation for original features - ---- - -## Architecture Overview - -Trellis transforms AI assistants into structured development partners through **enforced context injection**. - -### System Layers - -``` -┌─────────────────────────────────────────────────────────────────────┐ -│ USER INTERACTION │ -│ /trellis:start /trellis:brainstorm /trellis:parallel /trellis:finish-work │ -└─────────────────────────────────┬───────────────────────────────────┘ - │ -┌─────────────────────────────────▼───────────────────────────────────┐ -│ SKILLS LAYER │ -│ .claude/commands/trellis/*.md (slash commands) │ -│ .claude/agents/*.md (sub-agent definitions) │ -└─────────────────────────────────┬───────────────────────────────────┘ - │ -┌─────────────────────────────────▼───────────────────────────────────┐ -│ HOOKS LAYER │ -│ SessionStart → session-start.py (injects workflow + context) │ -│ PreToolUse:Task → inject-subagent-context.py (spec injection) │ -│ SubagentStop → ralph-loop.py (quality enforcement) │ -└─────────────────────────────────┬───────────────────────────────────┘ - │ -┌─────────────────────────────────▼───────────────────────────────────┐ -│ PERSISTENCE LAYER │ -│ .trellis/workspace/ (journals, session history) │ -│ .trellis/tasks/ (task tracking, context files) │ -│ .trellis/spec/ (coding guidelines) │ -└─────────────────────────────────────────────────────────────────────┘ -``` - -### Key Design Principles - -| Principle | Description | -| ---------------------------------- | --------------------------------------------------- | -| **Specs Injected, Not Remembered** | Hooks enforce specs - agents always receive context | -| **Read Before Write** | Understand guidelines before writing code | -| **Layered Context** | Only relevant specs load (via JSONL files) | -| **Human Commits** | AI never commits - human validates first | -| **Pure Dispatcher** | Dispatch agent only orchestrates | - ---- - -## Core Components - -### 1. Workspace System - -Track development progress across sessions with per-developer isolation. - -``` -.trellis/workspace/ -├── index.md # Global overview -└── {developer}/ # Per-developer - ├── index.md # Personal index (@@@auto markers) - └── journal-N.md # Session journals (max 2000 lines) -``` - -**Key files**: `.trellis/.developer` (identity), journals (session history) - -### 2. Task System - -Track work items with phase-based execution. - -``` -.trellis/tasks/{MM-DD-slug-assignee}/ -├── task.json # Metadata, phases, branch -├── prd.md # Requirements -├── implement.jsonl # Context for implement agent -├── check.jsonl # Context for check agent -└── debug.jsonl # Context for debug agent -``` - -### 3. Spec System - -Maintain coding standards that get injected to agents. - -``` -.trellis/spec/ -├── frontend/ # Frontend guidelines -├── backend/ # Backend guidelines -└── guides/ # Thinking guides -``` - -### 4. Hooks System - -Automatically inject context and enforce quality. - -| Hook | When | Purpose | -| -------------------- | ----------------- | --------------------------------- | -| `SessionStart` | Session begins | Inject workflow, guidelines | -| `PreToolUse:Task` | Before sub-agent | Inject specs via JSONL | -| `SubagentStop:check` | Check agent stops | Enforce verification (Ralph Loop) | - -### 5. Agent System - -Specialized agents for different phases. - -| Agent | Purpose | Restriction | -| ----------- | --------------------- | ----------------------- | -| `dispatch` | Orchestrate pipeline | Pure dispatcher | -| `plan` | Evaluate requirements | Can reject unclear reqs | -| `research` | Find code patterns | Read-only | -| `implement` | Write code | No git commit | -| `check` | Review and self-fix | Ralph Loop controlled | -| `debug` | Fix issues | Precise fixes only | - -### 6. Multi-Agent Pipeline - -Run parallel isolated sessions via Git worktrees. - -``` -plan.py → start.py → Dispatch → implement → check → create-pr -``` - ---- - -## Customization Guide - -### Adding a Command - -1. Create `.claude/commands/trellis/my-command.md` -2. Update `trellis-local` skill with the change - -### Adding an Agent - -1. Create `.claude/agents/my-agent.md` with YAML frontmatter -2. Update `inject-subagent-context.py` to handle new agent type -3. Create `my-agent.jsonl` in task directories -4. Update `trellis-local` skill - -### Modifying Hooks - -1. Edit the hook script in `.claude/hooks/` -2. Document the change in `trellis-local` skill -3. Note which lines were modified and why - -### Extending Specs - -1. Create new category in `.trellis/spec/my-category/` -2. Add `index.md` and guideline files -3. Reference in JSONL context files -4. Update `trellis-local` skill - -### Changing Task Workflow - -1. Modify `next_action` array in `task.json` -2. Update dispatch or hook scripts as needed -3. Document in `trellis-local` skill - ---- - -## Resources - -Reference documents are organized by platform compatibility: - -``` -references/ -├── core/ # All Platforms (Claude Code, Cursor, etc.) -├── claude-code/ # Claude Code Only -├── how-to-modify/ # Modification Guides -└── meta/ # Documentation & Templates -``` - -### `core/` - All Platforms - -| Document | Content | -| -------------- | ---------------------------------------------- | -| `overview.md` | Core systems introduction | -| `files.md` | All `.trellis/` files with purposes | -| `workspace.md` | Workspace system, journals, developer identity | -| `tasks.md` | Task system, directories, JSONL context files | -| `specs.md` | Spec system, guidelines organization | -| `scripts.md` | Platform-independent scripts | - -### `claude-code/` - Claude Code Only - -| Document | Content | -| -------------------- | ---------------------------------- | -| `overview.md` | Claude Code features introduction | -| `hooks.md` | Hook system, context injection | -| `agents.md` | Agent types, invocation, Task tool | -| `ralph-loop.md` | Quality enforcement mechanism | -| `multi-session.md` | Parallel worktree sessions | -| `worktree-config.md` | worktree.yaml configuration | -| `scripts.md` | Claude Code only scripts | - -### `how-to-modify/` - Modification Guides - -| Document | Scenario | -| ------------------ | ------------------------------------- | -| `overview.md` | Quick reference for all modifications | -| `add-command.md` | Adding slash commands | -| `add-agent.md` | Adding new agent types | -| `add-spec.md` | Adding spec categories | -| `add-phase.md` | Adding workflow phases | -| `modify-hook.md` | Modifying hook behavior | -| `change-verify.md` | Changing verify commands | - -### `meta/` - Documentation - -| Document | Content | -| --------------------------- | -------------------------------- | -| `platform-compatibility.md` | Detailed platform support matrix | -| `self-iteration-guide.md` | How to document customizations | -| `trellis-local-template.md` | Template for project-local skill | - ---- - -## Quick Reference - -### Key Scripts - -| Script | Purpose | -| ---------------------- | -------------------- | -| `get_context.py` | Get session context | -| `task.py` | Task management | -| `add_session.py` | Record session | -| `multi_agent/start.py` | Start parallel agent | - -### Key Paths - -| Path | Purpose | -| ------------------------ | ------------------- | -| `.trellis/.developer` | Developer identity | -| `.trellis/.current-task` | Active task pointer | -| `.trellis/workflow.md` | Main workflow docs | -| `.claude/settings.json` | Hook configuration | - ---- - -## Upgrade Protocol - -When upgrading Trellis to a new version: - -1. **Compare** new meta-skill with current -2. **Review** changes in new version -3. **Check** `trellis-local` for conflicts -4. **Merge** carefully, preserving customizations -5. **Update** `trellis-local` with migration notes - -```markdown -## Changelog - -### 2026-02-01 - Upgraded to Trellis X.Y.Z - -- Merged new hook behavior from meta-skill -- Kept custom agent `my-agent` -- Updated check.jsonl template -``` diff --git a/Skills/new-skills/trellis-meta/references/claude-code/agents.md b/Skills/new-skills/trellis-meta/references/claude-code/agents.md deleted file mode 100644 index e5857e4..0000000 --- a/Skills/new-skills/trellis-meta/references/claude-code/agents.md +++ /dev/null @@ -1,448 +0,0 @@ -# Agents Reference - -Documentation for the Trellis agent system - specialized AI agents for different development phases. - ---- - -## Overview - -Trellis uses **specialized agents** for different tasks. Each agent has specific capabilities, restrictions, and context injection. - -**Key Insight**: Agents work in the **current directory** - no worktree needed. Multi-Session (worktree isolation) is a separate concept. - ---- - -## Agent Types - -| Agent | Purpose | Can Write | Git Commit | -| ----------- | --------------------- | -------------- | --------------- | -| `dispatch` | Orchestrate phases | No | Only via script | -| `plan` | Evaluate requirements | Yes (task dir) | No | -| `research` | Find patterns | No | No | -| `implement` | Write code | Yes | No | -| `check` | Review & self-fix | Yes | No | -| `debug` | Fix issues | Yes | No | - ---- - -## Agent Definitions - -Location: `.claude/agents/*.md` - -### Format - -```markdown ---- -name: agent-name -description: | - What this agent does. -tools: Read, Write, Edit, Bash, Glob, Grep -model: opus ---- - -# Agent Name - -## Core Responsibilities - -... - -## Workflow - -... - -## Forbidden Operations - -... -``` - ---- - -## Dispatch Agent - -**File**: `.claude/agents/dispatch.md` - -**Purpose**: Pure orchestrator - calls other agents in sequence. - -**Key Principle**: Does NOT read specs directly. Hooks inject context to subagents. - -**Tools**: `Read, Bash` - -**Workflow**: - -``` -1. Read .trellis/.current-task → find task directory -2. Read task.json → get next_action array -3. For each phase: - - implement → Task(subagent_type="implement") - - check → Task(subagent_type="check") - - finish → Task(subagent_type="check", prompt="[finish]...") - - create-pr → Bash("python3 ... create_pr.py") -``` - -**Forbidden**: - -- Reading spec files directly -- Modifying code -- Git operations (except via create-pr script) - ---- - -## Plan Agent - -**File**: `.claude/agents/plan.md` - -**Purpose**: Evaluate requirements and configure task directory. - -**Tools**: `Read, Bash, Glob, Grep, Task` - -**Capabilities**: - -- **REJECT** unclear/vague requirements -- Call Research Agent to analyze codebase -- Create `prd.md` with requirements -- Configure `task.json` (branch, scope, phases) -- Initialize JSONL context files - -**Rejection Criteria**: - -- Vague requirements ("make it better") -- Incomplete information -- Out of scope -- Potentially harmful -- Too large (should split) - -**Output**: - -``` -task-dir/ -├── task.json # Configured with branch, scope, dev_type -├── prd.md # Clear requirements -├── implement.jsonl -├── check.jsonl -└── debug.jsonl -``` - ---- - -## Research Agent - -**File**: `.claude/agents/research.md` - -**Purpose**: Find and explain code patterns. Pure research, no modifications. - -**Tools**: `Read, Glob, Grep, web search, chrome-devtools` - -**Allowed**: - -- Describe what exists -- Describe where it is -- Describe how it works -- Describe interactions - -**Forbidden** (unless explicitly asked): - -- Suggest improvements -- Criticize implementation -- Recommend refactoring -- Modify any files -- Git operations - -**Output Format**: - -```markdown -## Query Summary - -... - -## Files Found - -- path/to/file.ts - description - -## Code Patterns - -... - -## Related Specs - -... -``` - ---- - -## Implement Agent - -**File**: `.claude/agents/implement.md` - -**Purpose**: Write code following injected specs. - -**Tools**: `Read, Write, Edit, Bash, Glob, Grep` - -**Workflow**: - -1. Understand specs (from injected context) -2. Understand requirements (prd.md, info.md) -3. Implement features -4. Self-check (run lint/typecheck) - -**Forbidden**: - -- `git commit` -- `git push` -- `git merge` - -**Context Injection**: Hook injects `implement.jsonl` + `prd.md` + `info.md` - ---- - -## Check Agent - -**File**: `.claude/agents/check.md` - -**Purpose**: Review code and **self-fix** issues. - -**Tools**: `Read, Write, Edit, Bash, Glob, Grep` - -**Key Principle**: Fix issues yourself, don't just report them. - -**Workflow**: - -1. Get changes: `git diff` -2. Check against specs -3. Self-fix issues directly -4. Run verification (lint, typecheck) -5. Output completion markers - -**Controlled by**: Ralph Loop (SubagentStop hook) - -**Completion Markers**: - -``` -TYPECHECK_FINISH -LINT_FINISH -CODEREVIEW_FINISH -``` - ---- - -## Debug Agent - -**File**: `.claude/agents/debug.md` - -**Purpose**: Fix specific reported issues. - -**Tools**: `Read, Write, Edit, Bash, Glob, Grep` - -**Workflow**: - -1. Parse issues (prioritize P1 > P2 > P3) -2. Research if needed -3. Fix one by one -4. Verify each fix (run typecheck) - -**Forbidden**: - -- Refactor surrounding code -- Add new features -- Modify unrelated files -- Use non-null assertion (`x!`) -- Git commit - ---- - -## Invoking Agents - -Use the `Task` tool with `subagent_type`: - -```javascript -Task( - subagent_type: "implement", - prompt: "Implement the login feature", - model: "opus", - run_in_background: true // optional -) -``` - -### Agent Resolution - -1. Claude Code looks for `.claude/agents/{subagent_type}.md` -2. Loads agent definition (tools, model, instructions) -3. **PreToolUse hook fires** → `inject-subagent-context.py` -4. Hook injects context from JSONL files -5. Agent runs with full context - ---- - -## Context Injection - -### How It Works - -``` -Task(subagent_type="implement") called - │ - ▼ - PreToolUse hook fires - │ - ▼ -inject-subagent-context.py runs - │ - ├── Read .trellis/.current-task - │ - ├── Find task directory - │ - ├── Load implement.jsonl - │ {"file": ".trellis/spec/backend/index.md", "reason": "..."} - │ {"file": "src/services/auth.ts", "reason": "..."} - │ - ├── Read each file content - │ - └── Build new prompt: - # Implement Agent Task - ## Your Context - === .trellis/spec/backend/index.md === - [content] - === src/services/auth.ts === - [content] - ## Your Task - [original prompt] -``` - -### JSONL Files - -| File | Agent | Purpose | -| ----------------- | --------- | ----------------------------- | -| `implement.jsonl` | implement | Dev specs, patterns to follow | -| `check.jsonl` | check | Check specs, quality criteria | -| `debug.jsonl` | debug | Debug context, error reports | -| `research.jsonl` | research | (optional) Research scope | - ---- - -## Multi-Agent Workflow - -In the **current directory** (no worktree): - -``` -User request - │ - ▼ -Orchestrator (you or dispatch) - │ - ├── Task(subagent_type="research") - │ └── Returns: code patterns, relevant files - │ - ├── Task(subagent_type="implement") - │ └── Returns: implemented code - │ - ├── Task(subagent_type="check") - │ └── Returns: reviewed & fixed code - │ - └── Human commits -``` - -### Task Workflow (from /trellis:start) - -``` -1. User describes task -2. AI classifies (Question / Trivial / Development Task) -3. For Development Task: - a. Research Agent → analyze codebase - b. Create task directory + JSONL files - c. task.py start → set .current-task - d. Implement Agent → write code - e. Check Agent → review & fix - f. Human tests and commits -``` - ---- - -## Adding Custom Agents - -### 1. Create Definition - -`.claude/agents/my-agent.md`: - -```markdown ---- -name: my-agent -description: | - What this agent specializes in. -tools: Read, Write, Edit, Bash, Glob, Grep -model: opus ---- - -# My Agent - -## Core Responsibilities - -1. ... - -## Workflow - -1. ... - -## Forbidden Operations - -- ... -``` - -### 2. Update Hook - -Edit `.claude/hooks/inject-subagent-context.py`: - -```python -# Add constant -AGENT_MY_AGENT = "my-agent" - -# Add to list -AGENTS_ALL = (..., AGENT_MY_AGENT) - -# Add context function -def get_my_agent_context(repo_root, task_dir): - # Load my-agent.jsonl or fallback - ... - -# Add to main switch -elif subagent_type == AGENT_MY_AGENT: - context = get_my_agent_context(repo_root, task_dir) - new_prompt = build_my_agent_prompt(original_prompt, context) -``` - -### 3. Create JSONL - -In task directories, create `my-agent.jsonl`: - -```jsonl -{ - "file": ".trellis/spec/my-spec.md", - "reason": "My agent spec" -} -``` - -### 4. (Optional) Add to Dispatch - -Update `task.json` default phases: - -```json -"next_action": [ - {"phase": 1, "action": "my-agent"}, - ... -] -``` - ---- - -## vs Multi-Session - -| Aspect | Multi-Agent | Multi-Session | -| ------------- | --------------------------- | -------------------------- | -| **What** | Multiple agents in sequence | Parallel isolated sessions | -| **Where** | Current directory | Separate worktrees | -| **Isolation** | Shared filesystem | Separate filesystems | -| **Use case** | Normal development | Parallel tasks | -| **Worktree** | Not needed | Required | - -Multi-Agent is the **agent system** - dispatch calling implement, check, etc. - -Multi-Session is **parallel execution** - multiple worktrees running simultaneously. - -They can combine: Multi-Session runs Multi-Agent workflows in each worktree. diff --git a/Skills/new-skills/trellis-meta/references/claude-code/hooks.md b/Skills/new-skills/trellis-meta/references/claude-code/hooks.md deleted file mode 100644 index 209df4a..0000000 --- a/Skills/new-skills/trellis-meta/references/claude-code/hooks.md +++ /dev/null @@ -1,245 +0,0 @@ -# Hooks System - -Claude Code hooks for automatic context injection and quality enforcement. - ---- - -## Overview - -Hooks intercept Claude Code lifecycle events to inject context and enforce quality. - -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ HOOK LIFECYCLE │ -│ │ -│ Session Start ──► SessionStart hook ──► Inject workflow context │ -│ │ -│ Task() called ──► PreToolUse:Task hook ──► Inject specs from JSONL │ -│ │ -│ Agent stops ──► SubagentStop hook ──► Ralph Loop verification │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ -``` - ---- - -## Configuration - -### `.claude/settings.json` - -```json -{ - "hooks": { - "SessionStart": [ - { - "matcher": "startup", - "hooks": [ - { - "type": "command", - "command": "python3 \"$CLAUDE_PROJECT_DIR/.claude/hooks/session-start.py\"", - "timeout": 10 - } - ] - } - ], - "PreToolUse": [ - { - "matcher": "Task", - "hooks": [ - { - "type": "command", - "command": "python3 \"$CLAUDE_PROJECT_DIR/.claude/hooks/inject-subagent-context.py\"", - "timeout": 30 - } - ] - } - ], - "SubagentStop": [ - { - "matcher": "check", - "hooks": [ - { - "type": "command", - "command": "python3 \"$CLAUDE_PROJECT_DIR/.claude/hooks/ralph-loop.py\"", - "timeout": 300 - } - ] - } - ] - } -} -``` - ---- - -## SessionStart Hook - -### Purpose - -Inject initial context when a Claude Code session starts. - -### Script: `session-start.py` - -**Injects:** - -- Developer identity from `.trellis/.developer` -- Git status and recent commits -- Current task (if `.trellis/.current-task` exists) -- `workflow.md` content -- All `spec/*/index.md` files -- Start instructions - -**Output format:** - -```json -{ - "result": "continue", - "message": "# Session Context\n\n## Developer\ntaosu\n\n## Git Status\n..." -} -``` - ---- - -## PreToolUse:Task Hook - -### Purpose - -Inject relevant specs when a subagent is invoked. - -### Script: `inject-subagent-context.py` - -**Trigger:** When `Task(subagent_type="...")` is called. - -**Flow:** - -1. Read `subagent_type` from tool input -2. Find current task from `.trellis/.current-task` -3. Load `{subagent_type}.jsonl` from task directory -4. Read each file listed in JSONL -5. Build augmented prompt with context -6. Update `task.json` with current phase - -**Output format:** - -```json -{ - "result": "continue", - "updatedInput": { - "prompt": "# Implement Agent Task\n\n## Context\n...\n\n## Your Task\n..." - } -} -``` - -### JSONL Format - -```jsonl -{"file": ".trellis/spec/backend/index.md", "reason": "Backend guidelines"} -{"file": "src/services/auth.ts", "reason": "Existing pattern"} -{"file": ".trellis/tasks/01-31-add-login/prd.md", "reason": "Requirements"} -``` - ---- - -## SubagentStop Hook - -### Purpose - -Quality enforcement via Ralph Loop. - -### Script: `ralph-loop.py` - -**Trigger:** When Check Agent tries to stop. - -**Flow:** - -1. Read verify commands from `worktree.yaml` -2. Execute each command (pnpm lint, pnpm typecheck, etc.) -3. If all pass → allow stop -4. If any fail → block stop, agent continues - -→ See [ralph-loop.md](./ralph-loop.md) for details. - ---- - -## Hook Scripts Location - -``` -.claude/hooks/ -├── session-start.py # SessionStart handler -├── inject-subagent-context.py # PreToolUse:Task handler -└── ralph-loop.py # SubagentStop:check handler -``` - ---- - -## Environment Variables - -Available in hook scripts: - -| Variable | Description | -| -------------------- | ------------------------------------------- | -| `CLAUDE_PROJECT_DIR` | Project root directory | -| `HOOK_EVENT` | Event type (SessionStart, PreToolUse, etc.) | -| `TOOL_NAME` | Tool being called (for PreToolUse) | -| `TOOL_INPUT` | JSON string of tool input | -| `SUBAGENT_TYPE` | Agent type (for SubagentStop) | - ---- - -## Hook Response Format - -### Continue (allow operation) - -```json -{ - "result": "continue", - "message": "Optional message to inject" -} -``` - -### Continue with modified input - -```json -{ - "result": "continue", - "updatedInput": { - "prompt": "Modified prompt..." - } -} -``` - -### Block (prevent operation) - -```json -{ - "result": "block", - "message": "Reason for blocking" -} -``` - ---- - -## Debugging Hooks - -### View hook output - -```bash -# Check if hooks are configured -cat .claude/settings.json | grep -A 20 '"hooks"' - -# Test session-start manually -python3 .claude/hooks/session-start.py - -# Test inject-context (needs TOOL_INPUT env var) -TOOL_INPUT='{"subagent_type":"implement","prompt":"test"}' \ - python3 .claude/hooks/inject-subagent-context.py -``` - -### Common Issues - -| Issue | Cause | Solution | -| ------------------- | --------------------- | ---------------------------- | -| Hook not running | Wrong matcher | Check settings.json matcher | -| Timeout | Script too slow | Increase timeout or optimize | -| No context injected | Missing .current-task | Run `task.py start` | -| JSONL not found | Wrong task directory | Check .current-task path | diff --git a/Skills/new-skills/trellis-meta/references/claude-code/multi-session.md b/Skills/new-skills/trellis-meta/references/claude-code/multi-session.md deleted file mode 100644 index 1631d4d..0000000 --- a/Skills/new-skills/trellis-meta/references/claude-code/multi-session.md +++ /dev/null @@ -1,482 +0,0 @@ -# Multi-Session Reference - -Documentation for parallel isolated sessions using Git worktrees. - ---- - -## Overview - -Multi-Session enables **parallel, isolated development sessions** using Git worktrees. Each session runs in its own directory with its own branch. - -**Key Distinction**: - -- **Multi-Agent** = Multiple agents in current directory (dispatch → implement → check) -- **Multi-Session** = Parallel sessions in separate worktrees (this document) - ---- - -## When to Use Multi-Session - -| Scenario | Use Multi-Session? | -| ----------------------------------------------- | -------------------- | -| Normal task in current branch | No - use Multi-Agent | -| Long-running task, want to work on other things | Yes | -| Multiple independent tasks in parallel | Yes | -| Task needs clean isolated environment | Yes | -| Quick fix or small change | No | - ---- - -## Architecture - -``` -┌────────────────────────────────────────────────────────────────────────────┐ -│ MAIN REPOSITORY │ -│ (your current directory) │ -│ │ -│ /trellis:parallel → Configure task → start.py │ -│ │ │ -│ │ Creates worktree │ -│ │ Starts agent │ -│ ▼ │ -└───────────────────────────────────────────┼─────────────────────────────────┘ - │ - ┌─────────────────────────────┼─────────────────────────────────┐ - │ │ │ - ▼ ▼ ▼ -┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐ -│ WORKTREE 1 │ │ WORKTREE 2 │ │ WORKTREE 3 │ -│ feature/add-login │ │ feature/user-profile │ │ fix/api-bug │ -│ │ │ │ │ │ -│ ┌──────────────────┐ │ │ ┌──────────────────┐ │ │ ┌──────────────────┐ │ -│ │ Dispatch Agent │ │ │ │ Dispatch Agent │ │ │ │ Dispatch Agent │ │ -│ │ ↓ │ │ │ │ ↓ │ │ │ │ ↓ │ │ -│ │ Implement Agent │ │ │ │ Implement Agent │ │ │ │ Implement Agent │ │ -│ │ ↓ │ │ │ │ ↓ │ │ │ │ ↓ │ │ -│ │ Check Agent │ │ │ │ Check Agent │ │ │ │ Check Agent │ │ -│ │ ↓ │ │ │ │ ↓ │ │ │ │ ↓ │ │ -│ │ create_pr.py │ │ │ │ create_pr.py │ │ │ │ create_pr.py │ │ -│ └──────────────────┘ │ │ └──────────────────┘ │ │ └──────────────────┘ │ -│ │ │ │ │ │ -│ Session: abc123 │ │ Session: def456 │ │ Session: ghi789 │ -│ PID: 12345 │ │ PID: 12346 │ │ PID: 12347 │ -└──────────────────────┘ └──────────────────────┘ └──────────────────────┘ - -Location: ../worktrees/ (default) -``` - ---- - -## Git Worktree - -### What is a Worktree? - -Git worktrees allow multiple working directories from one repository: - -``` -/project/ # Main repo (main branch) -/project/../worktrees/ # Default: ../worktrees -├── feature/add-login/ # Worktree 1 (own branch) -├── feature/user-profile/ # Worktree 2 (own branch) -└── fix/api-bug/ # Worktree 3 (own branch) -``` - -### Benefits - -| Benefit | Description | -| ----------------------- | ----------------------------------- | -| **True isolation** | Separate filesystem per session | -| **Own branch** | Each worktree on its own branch | -| **Parallel execution** | Multiple agents work simultaneously | -| **Clean state** | Start fresh, no interference | -| **Session persistence** | Each has `.session-id` for resume | -| **Easy cleanup** | Remove worktree = remove everything | - ---- - -## Configuration - -### worktree.yaml - -Location: `.trellis/worktree.yaml` - -```yaml -# Where worktrees are created (relative to project) -# Default: ../worktrees -worktree_dir: ../worktrees - -# Files to copy to each worktree (default: []) -copy: - - .trellis/.developer # Developer identity - - .env # Environment variables - - .env.local # Local overrides - -# Commands after worktree creation (default: []) -post_create: - - npm install # Install dependencies - # - pnpm install --frozen-lockfile - -# Verification commands for Ralph Loop (default: []) -verify: - - pnpm lint - - pnpm typecheck -``` - -### Task Configuration - -Each session needs a configured task: - -```json -// task.json -{ - "branch": "feature/add-login", // Required for worktree - "base_branch": "main", - "worktree_path": null, // Set by start.py - "current_phase": 0, - "next_action": [ - { "phase": 1, "action": "implement" }, - { "phase": 2, "action": "check" }, - { "phase": 3, "action": "finish" }, - { "phase": 4, "action": "create-pr" } - ] -} -``` - ---- - -## Scripts - -### start.py - Start Session - -Creates worktree and starts agent. - -```bash -python3 .trellis/scripts/multi_agent/start.py -``` - -**Actions**: - -1. Read `task.json` for branch name -2. Create git worktree: - ```bash - git worktree add -b ../trellis-worktrees/ - ``` -3. Copy files from `worktree.yaml` copy list -4. Copy task directory to worktree -5. Run `post_create` hooks -6. Set `.trellis/.current-task` in worktree -7. Start Claude Dispatch Agent: - ```bash - claude -p --agent dispatch \ - --session-id \ - --dangerously-skip-permissions \ - --output-format stream-json \ - --verbose "Start the pipeline" - ``` -8. Register to `registry.json` - -**Example**: - -```bash -python3 .trellis/scripts/multi_agent/start.py .trellis/tasks/01-31-add-login-taosu -# Output: Started agent in ../trellis-worktrees/feature/add-login -``` - ---- - -### status.py - Monitor Sessions - -Check all running sessions. - -```bash -# Overview -python3 .trellis/scripts/multi_agent/status.py - -# Detailed view -python3 .trellis/scripts/multi_agent/status.py --detail - -# Watch mode -python3 .trellis/scripts/multi_agent/status.py --watch - -# View logs -python3 .trellis/scripts/multi_agent/status.py --log - -# Show registry -python3 .trellis/scripts/multi_agent/status.py --registry -``` - -**Output**: - -``` -Active Sessions: -┌──────────────┬──────────┬────────────────┬──────────┬───────────┐ -│ Task │ Status │ Phase │ Elapsed │ Files │ -├──────────────┼──────────┼────────────────┼──────────┼───────────┤ -│ add-login │ Running │ 2/4 (check) │ 15m 32s │ 5 changed │ -│ fix-api │ Stopped │ 1/4 (implement)│ 8m 15s │ 2 changed │ -└──────────────┴──────────┴────────────────┴──────────┴───────────┘ - -Resume stopped sessions: - cd ../trellis-worktrees/feature/fix-api && claude --resume -``` - ---- - -### create_pr.py - Create PR - -Creates PR from worktree changes. - -```bash -python3 .trellis/scripts/multi_agent/create_pr.py [--dry-run] -``` - -**Actions**: - -1. Stage changes: `git add -A` -2. Exclude: `git reset .trellis/workspace/` -3. Commit: `feat(): ` -4. Push to remote -5. Create Draft PR: `gh pr create --draft` -6. Update task.json: `status: "completed"`, `pr_url` - ---- - -### cleanup.py - Remove Worktrees - -Clean up after completion. - -```bash -# Specific worktree -python3 .trellis/scripts/multi_agent/cleanup.py - -# All merged worktrees -python3 .trellis/scripts/multi_agent/cleanup.py --merged - -# All worktrees (with confirmation) -python3 .trellis/scripts/multi_agent/cleanup.py --all -``` - -**Actions**: - -1. Archive task to `.trellis/tasks/archive/YYYY-MM/` -2. Remove from registry -3. Remove worktree: `git worktree remove ` -4. Optionally delete branch - ---- - -### plan.py - Auto-Configure Task - -Launches Plan Agent to create task configuration. - -```bash -python3 .trellis/scripts/multi_agent/plan.py \ - --name \ - --type \ - --requirement "" -``` - -**Plan Agent**: - -1. Evaluates requirements (can REJECT) -2. Calls Research Agent -3. Creates `prd.md` -4. Configures `task.json` -5. Initializes JSONL files - ---- - -## Session Registry - -Tracks all running sessions. - -**Location**: `.trellis/workspace//.agents/registry.json` - -```json -{ - "agents": [ - { - "id": "feature-add-login", - "worktree_path": "/abs/path/to/trellis-worktrees/feature/add-login", - "pid": 12345, - "started_at": "2026-01-31T10:30:00", - "task_dir": ".trellis/tasks/01-31-add-login-taosu" - } - ] -} -``` - -**API** (`common/registry.py`): - -```python -registry_add_agent(agent_id, worktree_path, pid, task_dir) -registry_remove_by_id(agent_id) -registry_remove_by_worktree(worktree_path) -registry_search_agent(pattern) -registry_list_agents() -``` - ---- - -## Complete Workflow - -### 1. Configure Task - -```bash -# Create task -python3 .trellis/scripts/task.py create "Add login" --slug add-login - -# Configure -python3 .trellis/scripts/task.py init-context fullstack -python3 .trellis/scripts/task.py set-branch feature/add-login - -# Write prd.md -# ... -``` - -### 2. Start Session - -```bash -python3 .trellis/scripts/multi_agent/start.py -``` - -### 3. Monitor - -```bash -python3 .trellis/scripts/multi_agent/status.py --watch add-login -``` - -### 4. After Completion - -```bash -# PR auto-created -# Review on GitHub, merge - -# Cleanup -python3 .trellis/scripts/multi_agent/cleanup.py feature/add-login -``` - ---- - -## Parallel Execution - -Start multiple sessions: - -```bash -# Session 1 -python3 .trellis/scripts/multi_agent/start.py .trellis/tasks/01-31-add-login - -# Session 2 (immediately) -python3 .trellis/scripts/multi_agent/start.py .trellis/tasks/01-31-fix-api - -# Session 3 -python3 .trellis/scripts/multi_agent/start.py .trellis/tasks/01-31-update-docs - -# Monitor all -python3 .trellis/scripts/multi_agent/status.py -``` - -Each runs independently: - -- Own worktree -- Own branch -- Own Claude process -- Own registry entry - ---- - -## Resuming Sessions - -If a session stops: - -```bash -# Find session info -python3 .trellis/scripts/multi_agent/status.py --detail - -# Resume -cd ../trellis-worktrees/feature/task-name -claude --resume -``` - ---- - -## Ralph Loop - -Quality enforcement for Check Agent in sessions. - -**Mechanism**: - -1. Check Agent completes -2. SubagentStop hook fires -3. `ralph-loop.py` runs verify commands -4. All pass → allow stop -5. Any fail → block, continue agent - -**Constants**: - -| Constant | Value | Description | -| ----------------------- | ----- | ----------------------- | -| `MAX_ITERATIONS` | 5 | Maximum loop iterations | -| `STATE_TIMEOUT_MINUTES` | 30 | State timeout | -| Command timeout | 120s | Per verify command | - -**Configuration** (`worktree.yaml`): - -```yaml -verify: - - pnpm lint - - pnpm typecheck -``` - -**State** (`.trellis/.ralph-state.json`): - -```json -{ - "task": ".trellis/tasks/01-31-add-login", - "iteration": 2, - "started_at": "2026-01-31T10:30:00" -} -``` - -**Limits**: Max 5 iterations (`MAX_ITERATIONS`), 30min timeout (`STATE_TIMEOUT_MINUTES`), 120s per command - ---- - -## Troubleshooting - -### Session Not Starting - -1. Check `worktree.yaml` exists -2. Verify branch name doesn't exist -3. Check `post_create` hooks -4. Look at start.py output - -### Session Stuck - -1. Check Ralph Loop iteration (max 5) -2. Verify `verify` commands -3. Manually run verify commands -4. Check `.trellis/.ralph-state.json` - -### Worktree Issues - -```bash -# Force remove -git worktree remove --force - -# Prune stale -git worktree prune - -# List all -git worktree list -``` - -### Registry Out of Sync - -```bash -# View -python3 .trellis/scripts/multi_agent/status.py --registry - -# Manual edit -vim .trellis/workspace//.agents/registry.json -``` diff --git a/Skills/new-skills/trellis-meta/references/claude-code/overview.md b/Skills/new-skills/trellis-meta/references/claude-code/overview.md deleted file mode 100644 index 8634c8f..0000000 --- a/Skills/new-skills/trellis-meta/references/claude-code/overview.md +++ /dev/null @@ -1,129 +0,0 @@ -# Claude Code Features Overview - -These features require **Claude Code** (or **iFlow**, which shares the same hook system) and don't work on other platforms. - ---- - -## Why Claude Code Only? - -Claude Code provides unique capabilities: - -| Feature | Claude Code | Why Required | -| -------------- | ----------- | -------------------------------- | -| Hooks | ✅ | Hook system for lifecycle events | -| Task tool | ✅ | Subagent invocation with context | -| `--agent` flag | ✅ | Load agent definitions | -| `--resume` | ✅ | Session persistence | -| CLI scripting | ✅ | Automation with `claude` command | - ---- - -## Feature Categories - -### Hooks System - -Automatic context injection and quality enforcement. - -| Hook | When | Purpose | -| -------------------- | ----------------- | ----------------------- | -| `SessionStart` | Session begins | Inject workflow context | -| `PreToolUse:Task` | Before subagent | Inject specs via JSONL | -| `SubagentStop:check` | Check agent stops | Ralph Loop enforcement | - -→ See [hooks.md](./hooks.md) - -### Agent System - -Specialized agents for different development phases. - -| Agent | Purpose | -| ----------- | --------------------- | -| `dispatch` | Orchestrate pipeline | -| `implement` | Write code | -| `check` | Review and self-fix | -| `debug` | Fix issues | -| `research` | Find patterns | -| `plan` | Evaluate requirements | - -→ See [agents.md](./agents.md) - -### Ralph Loop - -Quality enforcement for Check Agent. - -- Runs verify commands when Check Agent stops -- Blocks completion until all pass -- Max 5 iterations, 30min timeout - -→ See [ralph-loop.md](./ralph-loop.md) - -### Multi-Session - -Parallel isolated sessions using Git worktrees. - -- Each session in separate worktree -- Own branch, own Claude process -- Automated PR creation - -→ See [multi-session.md](./multi-session.md) - -### worktree.yaml - -Configuration for Multi-Session and Ralph Loop. - -→ See [worktree-config.md](./worktree-config.md) - ---- - -## Documents in This Directory - -| Document | Content | -| -------------------- | -------------------------------- | -| `hooks.md` | Hook system, context injection | -| `agents.md` | Agent types, invocation, context | -| `ralph-loop.md` | Quality enforcement mechanism | -| `multi-session.md` | Parallel worktree sessions | -| `worktree-config.md` | worktree.yaml configuration | -| `scripts.md` | Claude Code only scripts | - ---- - -## Architecture - -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ CLAUDE CODE INTEGRATION │ -│ │ -│ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ │ -│ │ SessionStart │ │ PreToolUse │ │ SubagentStop │ │ -│ │ Hook │ │ Hook │ │ Hook │ │ -│ └───────┬────────┘ └───────┬────────┘ └───────┬────────┘ │ -│ │ │ │ │ -│ ▼ ▼ ▼ │ -│ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ │ -│ │ session-start │ │ inject-context │ │ ralph-loop │ │ -│ │ .py │ │ .py │ │ .py │ │ -│ └───────┬────────┘ └───────┬────────┘ └───────┬────────┘ │ -│ │ │ │ │ -│ ▼ ▼ ▼ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ CORE SYSTEMS (File-Based) │ │ -│ │ Workspace │ Tasks │ Specs │ Commands │ Scripts │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ -``` - ---- - -## Checking Claude Code Availability - -```bash -# Check if Claude Code is installed -claude --version - -# Verify hooks are configured -cat .claude/settings.json | grep -A 5 '"hooks"' -``` - -If hooks aren't present, Claude Code features won't work. diff --git a/Skills/new-skills/trellis-meta/references/claude-code/ralph-loop.md b/Skills/new-skills/trellis-meta/references/claude-code/ralph-loop.md deleted file mode 100644 index 9f28314..0000000 --- a/Skills/new-skills/trellis-meta/references/claude-code/ralph-loop.md +++ /dev/null @@ -1,263 +0,0 @@ -# Ralph Loop - -Quality enforcement mechanism for Check Agent. - ---- - -## Overview - -Ralph Loop prevents Check Agent from stopping until all verification commands pass. - -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ RALPH LOOP │ -│ │ -│ Check Agent completes │ -│ │ │ -│ ▼ │ -│ SubagentStop hook fires ──► ralph-loop.py runs │ -│ │ │ -│ ▼ │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ Run verify commands from worktree.yaml: │ │ -│ │ │ │ -│ │ pnpm lint → exit 0 ✓ │ │ -│ │ pnpm typecheck → exit 0 ✓ │ │ -│ │ pnpm test → exit 1 ✗ │ │ -│ │ │ │ -│ │ Result: FAIL (test failed) │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ ┌─────────────────┐ ┌─────────────────┐ │ -│ │ All pass? │──── YES ────►│ Allow stop │ │ -│ └────────┬────────┘ └─────────────────┘ │ -│ │ NO │ -│ ▼ │ -│ ┌─────────────────┐ │ -│ │ Block stop │ ◄─── Agent continues to fix issues │ -│ │ Inject errors │ │ -│ └─────────────────┘ │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ -``` - ---- - -## Configuration - -### `worktree.yaml` - -```yaml -verify: - - pnpm lint - - pnpm typecheck - # - pnpm test - # - pnpm build -``` - ---- - -## Constants - -| Constant | Value | Description | -| ----------------------- | ----- | --------------------- | -| `MAX_ITERATIONS` | 5 | Maximum loop attempts | -| `STATE_TIMEOUT_MINUTES` | 30 | State file timeout | -| `COMMAND_TIMEOUT` | 120s | Per-command timeout | - ---- - -## State File - -### `.trellis/.ralph-state.json` - -Tracks loop state across iterations. - -```json -{ - "task": ".trellis/tasks/01-31-add-login", - "iteration": 2, - "started_at": "2026-01-31T10:30:00" -} -``` - ---- - -## Flow - -### Iteration 1 - -1. Check Agent completes work -2. SubagentStop hook fires -3. `ralph-loop.py` creates state file (iteration=1) -4. Runs verify commands -5. If fail: block stop, inject error messages -6. Check Agent continues fixing - -### Iteration 2-5 - -1. Check Agent tries to stop again -2. Hook reads state file, increments iteration -3. Runs verify commands again -4. Repeat until pass or max iterations - -### Max Iterations Reached - -1. Iteration 5 still fails -2. Hook allows stop (prevents infinite loop) -3. Logs warning about unresolved issues - -### Timeout - -1. State file older than 30 minutes -2. Hook resets state (fresh start) -3. Treats as iteration 1 - ---- - -## Verify Commands - -### Execution Order - -Commands run in config order. First failure stops execution. - -```yaml -verify: - - pnpm lint # Runs first (fast) - - pnpm typecheck # Runs second - - pnpm test # Runs third (slow) -``` - -**Recommendation**: Order fast → slow - -### Exit Codes - -- Exit 0 = Pass -- Non-zero = Fail - -### Timeout - -Each command has 120 second timeout. Long-running tests may need: - -- Splitting into smaller test suites -- Running only fast tests in Ralph Loop -- Adjusting `COMMAND_TIMEOUT` in script - ---- - -## Fallback: Completion Markers - -If `worktree.yaml` has no `verify` config, Ralph Loop uses completion markers. - -### How It Works - -1. Read `check.jsonl` for reason fields -2. Generate expected markers: `{REASON}_FINISH` -3. Check agent output for all markers -4. Missing marker = block stop - -### Example - -```jsonl -{"file": "...", "reason": "typecheck"} -{"file": "...", "reason": "lint"} -``` - -Expected markers: - -- `TYPECHECK_FINISH` -- `LINT_FINISH` - ---- - -## Debugging - -### Check State - -```bash -cat .trellis/.ralph-state.json -``` - -### Manual Verify - -```bash -# Run verify commands manually -pnpm lint && pnpm typecheck && pnpm test -``` - -### Reset State - -```bash -rm .trellis/.ralph-state.json -``` - -### View Hook Output - -Check agent output for Ralph Loop messages: - -- "Verification passed" = all commands succeeded -- "Verification failed" = blocking, shows errors -- "Max iterations reached" = giving up - ---- - -## Customizing - -### Add Test Verification - -```yaml -verify: - - pnpm lint - - pnpm typecheck - - pnpm test -``` - -### Add Build Verification - -```yaml -verify: - - pnpm lint - - pnpm typecheck - - pnpm build -``` - -### Different Languages - -**Go:** - -```yaml -verify: - - go fmt ./... - - go vet ./... - - go test ./... -``` - -**Python:** - -```yaml -verify: - - ruff check . - - mypy . - - pytest -``` - -**Rust:** - -```yaml -verify: - - cargo fmt --check - - cargo clippy - - cargo test -``` - ---- - -## Disabling Ralph Loop - -To disable for a project: - -1. Remove `verify` from `worktree.yaml` -2. Or remove SubagentStop hook from settings.json - -**Warning**: Without Ralph Loop, code quality isn't automatically enforced. diff --git a/Skills/new-skills/trellis-meta/references/claude-code/scripts.md b/Skills/new-skills/trellis-meta/references/claude-code/scripts.md deleted file mode 100644 index 658dd7f..0000000 --- a/Skills/new-skills/trellis-meta/references/claude-code/scripts.md +++ /dev/null @@ -1,258 +0,0 @@ -# Claude Code Scripts - -Scripts that require Claude Code CLI and hook system. - ---- - -## Overview - -These scripts require: - -- `claude` CLI command -- Hook system for context injection -- `--resume` for session persistence - -``` -.trellis/scripts/ -├── common/ -│ ├── worktree.py # Worktree utilities -│ └── registry.py # Agent registry -│ -└── multi_agent/ # Multi-Session scripts - ├── plan.py # Launch Plan agent - ├── start.py # Start worktree agent - ├── status.py # Monitor agents - ├── create_pr.py # Create pull request - └── cleanup.py # Cleanup worktree -``` - ---- - -## Multi-Session Scripts - -### `multi_agent/plan.py` - -Launch Plan Agent to create task configuration. - -```bash -python3 .trellis/scripts/multi_agent/plan.py \ - --name \ - --type \ - --requirement "" -``` - -**Options:** - -- `--name` - Task slug -- `--type` - `frontend`, `backend`, `fullstack` -- `--requirement` - Task description - -**Actions:** - -1. Creates task directory -2. Launches Plan Agent via `claude` -3. Plan Agent can REJECT unclear requirements -4. Creates `prd.md`, `task.json`, JSONL files - ---- - -### `multi_agent/start.py` - -Start agent in a new worktree. - -```bash -python3 .trellis/scripts/multi_agent/start.py -``` - -**Actions:** - -1. Read `task.json` for branch name -2. Create git worktree: - ```bash - git worktree add -b ../worktrees/ - ``` -3. Copy files from `worktree.yaml` copy list -4. Copy task directory to worktree -5. Run `post_create` commands -6. Set `.trellis/.current-task` -7. Start Claude Dispatch Agent: - ```bash - claude -p --agent dispatch \ - --session-id \ - --dangerously-skip-permissions \ - --output-format stream-json \ - "Start the pipeline" - ``` -8. Register to `registry.json` - ---- - -### `multi_agent/status.py` - -Monitor running sessions. - -```bash -# Overview of all sessions -python3 .trellis/scripts/multi_agent/status.py - -# Detailed view -python3 .trellis/scripts/multi_agent/status.py --detail - -# Watch mode (auto-refresh) -python3 .trellis/scripts/multi_agent/status.py --watch - -# View logs -python3 .trellis/scripts/multi_agent/status.py --log - -# Show registry -python3 .trellis/scripts/multi_agent/status.py --registry -``` - -**Output:** - -``` -Active Sessions: -┌──────────────┬──────────┬────────────────┬──────────┬───────────┐ -│ Task │ Status │ Phase │ Elapsed │ Files │ -├──────────────┼──────────┼────────────────┼──────────┼───────────┤ -│ add-login │ Running │ 2/4 (check) │ 15m 32s │ 5 changed │ -│ fix-api │ Stopped │ 1/4 (implement)│ 8m 15s │ 2 changed │ -└──────────────┴──────────┴────────────────┴──────────┴───────────┘ -``` - ---- - -### `multi_agent/create_pr.py` - -Create pull request from worktree changes. - -```bash -python3 .trellis/scripts/multi_agent/create_pr.py [--dry-run] -``` - -**Actions:** - -1. Stage changes: `git add -A` -2. Exclude workspace: `git reset .trellis/workspace/` -3. Commit with conventional format -4. Push to remote -5. Create Draft PR via `gh pr create --draft` -6. Update task.json with `pr_url` - ---- - -### `multi_agent/cleanup.py` - -Clean up completed worktrees. - -```bash -# Specific worktree -python3 .trellis/scripts/multi_agent/cleanup.py - -# All merged worktrees -python3 .trellis/scripts/multi_agent/cleanup.py --merged - -# All worktrees (with confirmation) -python3 .trellis/scripts/multi_agent/cleanup.py --all -``` - -**Actions:** - -1. Archive task to `.trellis/tasks/archive/YYYY-MM/` -2. Remove from registry -3. Remove worktree: `git worktree remove ` -4. Optionally delete branch - ---- - -## Common Utilities - -### `common/worktree.py` - -Worktree management utilities. - -```python -from common.worktree import ( - read_worktree_config, # Read worktree.yaml - get_worktree_path, # Get path for branch - create_worktree, # Create new worktree - remove_worktree, # Remove worktree -) -``` - -### `common/registry.py` - -Agent registry for tracking running sessions. - -```python -from common.registry import ( - registry_add_agent, # Add agent to registry - registry_remove_by_id, # Remove by agent ID - registry_remove_by_worktree, # Remove by path - registry_search_agent, # Search by pattern - registry_list_agents, # List all agents -) -``` - -**Registry file:** `.trellis/workspace//.agents/registry.json` - -```json -{ - "agents": [ - { - "id": "feature-add-login", - "worktree_path": "/abs/path/to/worktrees/feature/add-login", - "pid": 12345, - "started_at": "2026-01-31T10:30:00", - "task_dir": ".trellis/tasks/01-31-add-login-taosu" - } - ] -} -``` - ---- - -## Claude CLI Usage - -### Agent Mode - -```bash -claude --agent dispatch "Start the pipeline" -``` - -### Print Mode (non-interactive) - -```bash -claude -p "Do something" -``` - -### Session Resume - -```bash -claude --resume -``` - -### Automation Mode - -```bash -claude --dangerously-skip-permissions -p "..." -``` - -### JSON Output - -```bash -claude --output-format stream-json -p "..." -``` - ---- - -## Resuming Stopped Sessions - -```bash -# Find session info -python3 .trellis/scripts/multi_agent/status.py --detail - -# Resume in worktree -cd ../worktrees/feature/task-name -claude --resume -``` diff --git a/Skills/new-skills/trellis-meta/references/claude-code/worktree-config.md b/Skills/new-skills/trellis-meta/references/claude-code/worktree-config.md deleted file mode 100644 index 209468e..0000000 --- a/Skills/new-skills/trellis-meta/references/claude-code/worktree-config.md +++ /dev/null @@ -1,471 +0,0 @@ -# worktree.yaml Configuration Reference - -Complete guide to `.trellis/worktree.yaml` configuration. - ---- - -## Overview - -`worktree.yaml` configures **both** Multi-Session (worktree isolation) **and** some Multi-Agent behaviors (like Ralph Loop). - -```yaml -# .trellis/worktree.yaml - -# Multi-Session only -worktree_dir: ../worktrees # Default value -copy: - - .trellis/.developer - - .env -post_create: - - npm install - -# Both Multi-Session AND Multi-Agent -verify: - - pnpm lint - - pnpm typecheck -``` - -**Note**: Trellis uses a custom YAML parser (not PyYAML). Supports basic key-value pairs and arrays; complex nested structures may not work. - ---- - -## Configuration Sections - -### Which Config Affects What? - -| Config | Multi-Agent (current dir) | Multi-Session (worktree) | -| -------------- | ------------------------- | ----------------------------------- | -| `worktree_dir` | ❌ Not used | ✅ Worktree location | -| `copy` | ❌ Not used | ✅ Files copied to worktree | -| `post_create` | ❌ Not used | ✅ Commands after worktree creation | -| `verify` | ✅ Used by Ralph Loop | ✅ Used by Ralph Loop | - -**Key point**: `verify` config applies to BOTH modes! - ---- - -## Full Configuration - -```yaml -# ============================================================================= -# MULTI-SESSION ONLY - Only used in worktree mode -# ============================================================================= - -# Worktree creation location (relative to project root) -# Default: ../worktrees -worktree_dir: ../worktrees - -# Files to copy to each worktree -# These files are not in git, need manual copy -# Default: [] (empty array) -copy: - - .trellis/.developer # Developer identity - - .env # Environment variables - - .env.local # Local overrides - # - .npmrc # npm config - # - credentials.json # Credential files - -# Commands to run after worktree creation -# Runs in order, stops on first failure -# Default: [] (empty array) -post_create: - - npm install # or pnpm install - # - pnpm install --frozen-lockfile - # - cp .env.example .env - # - npm run db:migrate - -# ============================================================================= -# BOTH MODES - Used in both Multi-Agent and Multi-Session -# ============================================================================= - -# Verification commands - Used by Ralph Loop -# Runs when Check Agent stops -# All must pass to allow stop -# Default: [] (empty array) -verify: - - pnpm lint - - pnpm typecheck - # - pnpm test - # - pnpm build -``` - -### Default Values - -| Config | Default | Notes | -| -------------- | -------------- | ----------------------------------------------- | -| `worktree_dir` | `../worktrees` | Relative to project root | -| `copy` | `[]` | Empty array, no files copied | -| `post_create` | `[]` | Empty array, no commands run | -| `verify` | `[]` | Empty array, Ralph Loop uses completion markers | - ---- - -## Scenario: Multi-Agent in Current Directory - -**Requirement**: Run dispatch → implement → check in current directory, no worktree - -**worktree.yaml config**: - -```yaml -# These can be omitted (not used in current directory mode) -# worktree_dir: ... -# copy: ... -# post_create: ... - -# This is needed! Ralph Loop uses it -verify: - - pnpm lint - - pnpm typecheck -``` - -**Workflow**: - -1. Set `.trellis/.current-task` -2. Call `Task(subagent_type="implement")` -3. Call `Task(subagent_type="check")` -4. When Check Agent completes, Ralph Loop runs `verify` commands -5. Human commits - ---- - -## Scenario: Custom Workflows - -### Add test verification - -```yaml -verify: - - pnpm lint - - pnpm typecheck - - pnpm test # Add tests -``` - -### Add build verification - -```yaml -verify: - - pnpm lint - - pnpm typecheck - - pnpm build # Add build check -``` - -### Go projects - -```yaml -verify: - - go fmt ./... - - go vet ./... - - go test ./... -``` - -### Python projects - -```yaml -verify: - - ruff check . - - mypy . - - pytest -``` - -### Rust projects - -```yaml -verify: - - cargo fmt --check - - cargo clippy - - cargo test -``` - ---- - -## Scenario: Custom Worktree Creation - -### Different package managers - -```yaml -post_create: - # npm - - npm install - - # or pnpm - # - pnpm install --frozen-lockfile - - # or yarn - # - yarn install --frozen-lockfile - - # or bun - # - bun install -``` - -### Database migrations required - -```yaml -post_create: - - pnpm install - - pnpm db:migrate - - pnpm db:seed -``` - -### Code generation required - -```yaml -post_create: - - pnpm install - - pnpm codegen - - pnpm prisma generate -``` - -### Copy additional files - -```yaml -copy: - - .trellis/.developer - - .env - - .env.local - - .npmrc # npm private registry config - - firebase-credentials.json # Firebase credentials - - google-cloud-key.json # GCP credentials -``` - ---- - -## When worktree.yaml is Missing - -If `worktree.yaml` doesn't exist: - -| Feature | Behavior | -| ------------- | ------------------------------------------------ | -| Multi-Session | ❌ Cannot start (start.py requires config) | -| Multi-Agent | ⚠️ Works, but Ralph Loop uses completion markers | - -**Ralph Loop fallback behavior**: - -- Without `verify` config, uses completion markers -- Generates markers from `check.jsonl` reason field -- Example: `{"reason": "typecheck"}` → expects `TYPECHECK_FINISH` - ---- - -## Minimal Configuration - -### Multi-Agent only (current directory) - -```yaml -# .trellis/worktree.yaml -verify: - - pnpm lint - - pnpm typecheck -``` - -### Multi-Session only (worktree) - -```yaml -# .trellis/worktree.yaml -worktree_dir: ../worktrees -copy: - - .trellis/.developer -post_create: - - npm install -verify: - - pnpm lint - - pnpm typecheck -``` - ---- - -## Complete Examples - -### Node.js/TypeScript Project - -```yaml -worktree_dir: ../worktrees - -copy: - - .trellis/.developer - - .env - - .env.local - -post_create: - - pnpm install --frozen-lockfile - -verify: - - pnpm lint - - pnpm typecheck - - pnpm test -``` - -### Python Project - -```yaml -worktree_dir: ../worktrees - -copy: - - .trellis/.developer - - .env - - venv/ # or recreate venv - -post_create: - - python -m venv venv - - ./venv/bin/pip install -r requirements.txt - -verify: - - ./venv/bin/ruff check . - - ./venv/bin/mypy . - - ./venv/bin/pytest -``` - -### Go Project - -```yaml -worktree_dir: ../worktrees - -copy: - - .trellis/.developer - - .env - -post_create: - - go mod download - -verify: - - go fmt ./... - - go vet ./... - - golangci-lint run - - go test ./... -``` - -### Monorepo Project - -```yaml -worktree_dir: ../worktrees - -copy: - - .trellis/.developer - - .env - - .npmrc - -post_create: - - pnpm install --frozen-lockfile - - pnpm -r build # Build all packages - -verify: - - pnpm -r lint - - pnpm -r typecheck - - pnpm -r test -``` - ---- - -## Verification Command Notes - -### Ralph Loop Constants - -| Constant | Value | Description | -| ----------------------- | ----- | -------------------------- | -| `MAX_ITERATIONS` | 5 | Maximum loop iterations | -| `STATE_TIMEOUT_MINUTES` | 30 | State timeout (minutes) | -| Command timeout | 120s | Per verify command timeout | - -### Timeout - -Each verify command has **120 seconds** (2 minutes) timeout. Long-running tests may need: - -- Split tests -- Run only fast tests -- Modify `COMMAND_TIMEOUT` constant in `ralph-loop.py` - -### Exit Codes - -- Exit code 0 = Pass -- Non-zero = Fail, blocks Check Agent from stopping - -### Order - -Commands run in config order, stops on first failure. - -Recommended order: fast → slow - -```yaml -verify: - - pnpm lint # Fast (seconds) - - pnpm typecheck # Medium (seconds-minutes) - - pnpm test # Slow (minutes) -``` - ---- - -## YAML Parser Notes - -Trellis uses a custom YAML parser (not PyYAML) with these limitations: - -### Supported Syntax - -```yaml -# Simple key-value -worktree_dir: ../worktrees - -# Arrays (2-space indent, starts with -) -copy: - - .trellis/.developer - - .env - -# Quoted values -worktree_dir: "../worktrees with spaces" -``` - -### Unsupported Syntax - -```yaml -# ❌ Inline arrays -copy: [.env, .npmrc] - -# ❌ Complex nesting -nested: - key: - subkey: value - -# ❌ Multi-line strings -description: | - Multiple - lines -``` - ---- - -## Debugging Configuration - -### View current config - -```bash -cat .trellis/worktree.yaml -``` - -### Test verify commands - -```bash -# Manual run -pnpm lint && pnpm typecheck - -# Or view Ralph Loop state -cat .trellis/.ralph-state.json -``` - -### View worktree status - -```bash -git worktree list -``` - -### Ralph Loop debugging - -```bash -# View state file -cat .trellis/.ralph-state.json - -# Example output -# { -# "task": ".trellis/tasks/01-31-add-login", -# "iteration": 2, -# "started_at": "2026-01-31T10:30:00" -# } - -# Ralph Loop auto-stops when exceeding MAX_ITERATIONS (5) or STATE_TIMEOUT_MINUTES (30) -``` diff --git a/Skills/new-skills/trellis-meta/references/core/files.md b/Skills/new-skills/trellis-meta/references/core/files.md deleted file mode 100644 index 3020d9d..0000000 --- a/Skills/new-skills/trellis-meta/references/core/files.md +++ /dev/null @@ -1,382 +0,0 @@ -# Trellis File Reference - -Complete reference of all files in the `.trellis/` directory. - ---- - -## Directory Structure - -``` -.trellis/ -├── .developer # Developer identity (gitignored) -├── .current-task # Active task pointer (gitignored) -├── .ralph-state.json # Ralph Loop state (gitignored) -├── .template-hashes.json # Template version tracking -├── .version # Installed Trellis version -├── .gitignore # Git ignore rules -├── workflow.md # Main workflow documentation -├── config.yaml # Project-level configuration -├── worktree.yaml # Multi-session configuration -│ -├── workspace/ # Developer workspaces -├── tasks/ # Task tracking -├── spec/ # Coding guidelines -└── scripts/ # Automation scripts -``` - ---- - -## Root Files - -### `.developer` - -**Purpose**: Store current developer identity. - -**Created by**: `init_developer.py` - -**Format**: Plain text, single line with developer name. - -``` -taosu -``` - -**Gitignored**: Yes - each machine has its own identity. - ---- - -### `.current-task` - -**Purpose**: Point to the active task directory. - -**Created by**: `task.py start ` - -**Format**: Plain text, relative path to task directory. - -``` -.trellis/tasks/01-31-add-login-taosu -``` - -**Gitignored**: Yes - each developer works on different tasks. - -**Used by**: - -- Hooks read this to find task context -- Scripts use this for current task operations - ---- - -### `.ralph-state.json` - -**Purpose**: Track Ralph Loop iteration state. - -**Created by**: `ralph-loop.py` (Claude Code only) - -**Format**: JSON - -```json -{ - "task": ".trellis/tasks/01-31-add-login", - "iteration": 2, - "started_at": "2026-01-31T10:30:00" -} -``` - -**Gitignored**: Yes - runtime state. - -**Fields**: - -| Field | Type | Description | -| ------------ | -------- | ----------------------- | -| `task` | string | Task directory path | -| `iteration` | number | Current iteration (1-5) | -| `started_at` | ISO date | When loop started | - ---- - -### `.template-hashes.json` - -**Purpose**: Track template file versions for `trellis update`. - -**Created by**: `trellis init` or `trellis update` - -**Format**: JSON object mapping file paths to SHA-256 hashes. - -```json -{ - ".trellis/workflow.md": "028891d1fe839a266...", - ".claude/hooks/session-start.py": "0a9899e80f6bfe15...", - ".claude/commands/start.md": "d1276dcbff880299..." -} -``` - -**Used by**: - -- `trellis update` - Detect which files have been modified -- Determines if files can be auto-updated or need conflict resolution - -**Behavior**: - -- File hash matches template → Safe to update -- File hash differs → User modified, needs manual merge - ---- - -### `.version` - -**Purpose**: Track installed Trellis CLI version. - -**Created by**: `trellis init` or `trellis update` - -**Format**: Plain text, semver version string. - -``` -0.3.0 -``` - -**Used by**: - -- `trellis update` - Determine if update is needed -- Version mismatch detection - ---- - -### `.gitignore` - -**Purpose**: Define which files to exclude from git. - -**Default content**: - -```gitignore -# Developer identity (local only) -.developer - -# Current task pointer -.current-task - -# Ralph Loop state -.ralph-state.json - -# Agent runtime files -.agents/ -.agent-log -.agent-runner.sh -.session-id - -# Task directory runtime files -.plan-log - -# Atomic update temp files -*.tmp -.backup-* -*.new - -# Python cache -**/__pycache__/ -**/*.pyc -``` - ---- - -### `workflow.md` - -**Purpose**: Main workflow documentation for developers and AI. - -**Created by**: `trellis init` - -**Content sections**: - -1. Quick Start guide -2. Workflow overview -3. Session start process -4. Development process -5. Session end -6. File descriptions -7. Best practices - -**Injected by**: `session-start.py` hook (Claude Code) - -**For Cursor**: Read manually at session start. - ---- - -### `config.yaml` - -**Purpose**: Project-level Trellis configuration. - -**Created by**: `trellis init` - -**Format**: YAML - -```yaml -# Commit message used when auto-committing journal/index changes -session_commit_message: 'chore: record journal' - -# Maximum lines per journal file before rotating to a new one -max_journal_lines: 2000 -``` - -**Used by**: `common/config.py` (read by `add_session.py`) - -**Behavior**: All values have sensible hardcoded defaults. If config.yaml is missing or a key is absent, the default is used. - ---- - -### `worktree.yaml` - -**Purpose**: Configure Multi-Session and Ralph Loop. - -**Created by**: `trellis init` - -**Format**: YAML - -```yaml -worktree_dir: ../worktrees -copy: - - .trellis/.developer - - .env -post_create: - - npm install -verify: - - pnpm lint - - pnpm typecheck -``` - -→ See `claude-code/worktree-config.md` for details. - ---- - -## Runtime Files (Gitignored) - -### `.agents/` - -**Purpose**: Agent registry for Multi-Session. - -**Location**: `.trellis/workspace/{developer}/.agents/` - -**Content**: `registry.json` tracking running agents. - ---- - -### `.session-id` - -**Purpose**: Store Claude Code session ID for resume. - -**Created by**: Multi-Session `start.py` - -**Format**: UUID string. - ---- - -### `.agent-log` - -**Purpose**: Agent execution log. - -**Created by**: Multi-Session scripts. - ---- - -### `.plan-log` - -**Purpose**: Plan Agent execution log. - -**Location**: Task directory. - ---- - -## Directories - -### `workspace/` - -Developer workspaces with journals and indexes. - -→ See `core/workspace.md` - -### `tasks/` - -Task directories with PRDs and context files. - -→ See `core/tasks.md` - -### `spec/` - -Coding guidelines and specifications. - -→ See `core/specs.md` - -### `scripts/` - -Automation scripts. - -→ See `core/scripts.md` and `claude-code/scripts.md` - ---- - -## Template Files - -These files are managed by `trellis update`: - -| File | Purpose | -| ------------------------ | ------------------------ | -| `.trellis/workflow.md` | Workflow documentation | -| `.trellis/config.yaml` | Project-level config | -| `.trellis/worktree.yaml` | Multi-session config | -| `.trellis/.gitignore` | Git ignore rules | -| `.claude/hooks/*.py` | Hook scripts | -| `.claude/commands/*.md` | Slash commands | -| `.claude/agents/*.md` | Agent definitions | -| `.cursor/commands/*.md` | Cursor commands (mirror) | - -**Update behavior**: - -1. Compare file hash with `.template-hashes.json` -2. If unchanged → Auto-update -3. If modified → Create `.new` file for manual merge -4. Update hashes after successful update - ---- - -## File Lifecycle - -### Created by `trellis init` - -``` -.trellis/ -├── .template-hashes.json -├── .version -├── .gitignore -├── workflow.md -├── config.yaml -├── worktree.yaml -├── spec/ -│ ├── frontend/ -│ ├── backend/ -│ └── guides/ -└── scripts/ -``` - -### Created at runtime - -``` -.trellis/ -├── .developer # init_developer.py -├── .current-task # task.py start -├── .ralph-state.json # ralph-loop.py -├── workspace/{dev}/ # init_developer.py -│ ├── index.md -│ ├── journal-1.md -│ └── .agents/ -└── tasks/{task}/ # task.py create - ├── task.json - ├── prd.md - └── *.jsonl -``` - -### Cleaned up - -``` -# After task completion -.trellis/tasks/{task}/ → .trellis/tasks/archive/YYYY-MM/ - -# After worktree removal -.agents/registry.json entries removed -``` diff --git a/Skills/new-skills/trellis-meta/references/core/overview.md b/Skills/new-skills/trellis-meta/references/core/overview.md deleted file mode 100644 index ca03a68..0000000 --- a/Skills/new-skills/trellis-meta/references/core/overview.md +++ /dev/null @@ -1,74 +0,0 @@ -# Core Systems Overview - -These systems work on **all 9 platforms** (Claude Code, Cursor, OpenCode, iFlow, Codex, Kilo, Kiro, Gemini CLI, Antigravity). - ---- - -## What's in Core? - -| System | Purpose | Files | -| --------- | -------------------------- | --------------------------------- | -| Workspace | Session tracking, journals | `.trellis/workspace/` | -| Tasks | Work item tracking | `.trellis/tasks/` | -| Specs | Coding guidelines | `.trellis/spec/` | -| Commands | Slash command prompts | `.claude/commands/` | -| Scripts | Automation utilities | `.trellis/scripts/` (core subset) | - ---- - -## Why These Are Portable - -All core systems are **file-based**: - -- No special runtime required -- Read/write with any tool -- Works in any AI coding environment - -``` -┌─────────────────────────────────────────────────────────────┐ -│ CORE SYSTEMS (File-Based) │ -│ │ -│ .trellis/ │ -│ ├── workspace/ → Journals, session history │ -│ ├── tasks/ → Task directories, PRDs, context files │ -│ ├── spec/ → Coding guidelines │ -│ └── scripts/ → Python utilities (core subset) │ -│ │ -│ .claude/ │ -│ └── commands/ → Slash command prompts │ -│ │ -└─────────────────────────────────────────────────────────────┘ -``` - ---- - -## Platform Usage - -### Claude Code - -All core systems work automatically with hook integration. - -### iFlow - -All core systems work automatically with hook integration (same as Claude Code). - -### Cursor, OpenCode, Codex, Kilo, Kiro, Gemini CLI, Antigravity - -Read files manually at session start: - -1. Read `.trellis/workflow.md` -2. Read relevant specs from `.trellis/spec/` -3. Check `.trellis/.current-task` for active work -4. Read JSONL files for context - ---- - -## Documents in This Directory - -| Document | Content | -| -------------- | ---------------------------------------------- | -| `files.md` | All files in `.trellis/` with purposes | -| `workspace.md` | Workspace system, journals, developer identity | -| `tasks.md` | Task system, directories, JSONL context files | -| `specs.md` | Spec system, guidelines organization | -| `scripts.md` | Core scripts (platform-independent) | diff --git a/Skills/new-skills/trellis-meta/references/core/scripts.md b/Skills/new-skills/trellis-meta/references/core/scripts.md deleted file mode 100644 index 98f8bdc..0000000 --- a/Skills/new-skills/trellis-meta/references/core/scripts.md +++ /dev/null @@ -1,308 +0,0 @@ -# Core Scripts - -Platform-independent Python scripts for Trellis automation. - ---- - -## Overview - -These scripts work on all platforms - they only read/write files and don't require Claude Code's hook system. - -``` -.trellis/scripts/ -├── common/ # Shared utilities -│ ├── paths.py -│ ├── developer.py -│ ├── config.py -│ ├── task_utils.py -│ ├── phase.py -│ └── git_context.py -│ -├── init_developer.py # Initialize developer -├── get_developer.py # Get developer name -├── get_context.py # Get session context -├── task.py # Task management CLI -└── add_session.py # Record session -``` - ---- - -## Developer Scripts - -### `init_developer.py` - -Initialize developer identity. - -```bash -python3 .trellis/scripts/init_developer.py -``` - -**Creates:** - -- `.trellis/.developer` -- `.trellis/workspace//` -- `.trellis/workspace//index.md` -- `.trellis/workspace//journal-1.md` - ---- - -### `get_developer.py` - -Get current developer name. - -```bash -python3 .trellis/scripts/get_developer.py -# Output: taosu -``` - -**Exit codes:** - -- `0` - Success -- `1` - Not initialized - ---- - -## Context Scripts - -### `get_context.py` - -Get session context for AI consumption. - -```bash -python3 .trellis/scripts/get_context.py -``` - -**Output includes:** - -- Developer identity -- Git status and recent commits -- Current task (if any) -- Workspace summary - ---- - -### `add_session.py` - -Record session entry to journal. - -```bash -python3 .trellis/scripts/add_session.py \ - --title "Session Title" \ - --commit "hash1,hash2" \ - --summary "Brief summary" -``` - -**Options:** - -- `--title` - Session title (required) -- `--commit` - Comma-separated commit hashes -- `--summary` - Brief summary -- `--content-file` - Path to file with detailed content -- `--no-commit` - Skip auto-commit of workspace changes - -**Actions:** - -1. Appends to current journal -2. Updates index markers -3. Rotates journal if >max_journal_lines -4. Auto-commits `.trellis/workspace` changes (unless `--no-commit`) - ---- - -## Task Scripts - -### `task.py` - -Task management CLI. - -#### Create Task - -```bash -python3 .trellis/scripts/task.py create "Task name" --slug task-slug -``` - -**Options:** - -- `--slug` - URL-safe identifier -- `--assignee` - Developer name (default: current) -- `--type` - Dev type: frontend, backend, fullstack - -#### List Tasks - -```bash -python3 .trellis/scripts/task.py list -``` - -**Output:** - -``` -Active Tasks: - 01-31-add-login-taosu (active) - 01-30-fix-api-cursor-agent (paused) -``` - -#### Start Task - -```bash -python3 .trellis/scripts/task.py start -``` - -Sets `.trellis/.current-task` to the task directory. - -#### Stop Task - -```bash -python3 .trellis/scripts/task.py stop -``` - -Clears `.trellis/.current-task`. - -#### Initialize Context - -```bash -python3 .trellis/scripts/task.py init-context -``` - -**Dev types:** `frontend`, `backend`, `fullstack` - -Creates JSONL files with appropriate spec references. - -#### Set Branch - -```bash -python3 .trellis/scripts/task.py set-branch -``` - -Updates `branch` field in task.json. - -#### Archive Task - -```bash -python3 .trellis/scripts/task.py archive -``` - -Moves task to `.trellis/tasks/archive/YYYY-MM/`. - -#### List Archive - -```bash -python3 .trellis/scripts/task.py list-archive [month] -``` - ---- - -## Common Utilities - -### `common/paths.py` - -Path constants and utilities. - -```python -from common.paths import ( - TRELLIS_DIR, # .trellis/ - WORKSPACE_DIR, # .trellis/workspace/ - TASKS_DIR, # .trellis/tasks/ - SPEC_DIR, # .trellis/spec/ -) -``` - -### `common/developer.py` - -Developer management. - -```python -from common.developer import ( - get_developer, # Get current developer name - get_workspace_dir, # Get developer's workspace directory -) -``` - -### `common/task_utils.py` - -Task lookup functions. - -```python -from common.task_utils import ( - get_current_task, # Get current task directory - load_task_json, # Load task.json - save_task_json, # Save task.json -) -``` - -### `common/phase.py` - -Phase tracking. - -```python -from common.phase import ( - get_current_phase, # Get current phase number - advance_phase, # Move to next phase -) -``` - -### `common/config.py` - -Project-level configuration reader. - -```python -from common.config import ( - get_session_commit_message, # Commit message for auto-commit - get_max_journal_lines, # Max lines per journal file -) -``` - -Reads from `.trellis/config.yaml` with hardcoded fallback defaults. - -### `common/git_context.py` - -Git context generation. - -```python -from common.git_context import ( - get_git_status, # Get git status - get_recent_commits, # Get recent commit messages - get_branch_name, # Get current branch -) -``` - ---- - -## Usage Examples - -### Initialize New Developer - -```bash -cd /path/to/project -python3 .trellis/scripts/init_developer.py john-doe -``` - -### Create and Start Task - -```bash -# Create task -python3 .trellis/scripts/task.py create "Add user login" --slug add-login - -# Initialize context for fullstack work -python3 .trellis/scripts/task.py init-context \ - .trellis/tasks/01-31-add-login-john-doe fullstack - -# Start task -python3 .trellis/scripts/task.py start \ - .trellis/tasks/01-31-add-login-john-doe -``` - -### Record Session - -```bash -python3 .trellis/scripts/add_session.py \ - --title "Implement login form" \ - --commit "abc1234" \ - --summary "Added login form, pending API integration" -``` - -### Archive Completed Task - -```bash -python3 .trellis/scripts/task.py archive \ - .trellis/tasks/01-31-add-login-john-doe -``` diff --git a/Skills/new-skills/trellis-meta/references/core/specs.md b/Skills/new-skills/trellis-meta/references/core/specs.md deleted file mode 100644 index 4a8f394..0000000 --- a/Skills/new-skills/trellis-meta/references/core/specs.md +++ /dev/null @@ -1,224 +0,0 @@ -# Spec System - -Maintain coding standards that guide AI development. - ---- - -## Directory Structure - -``` -.trellis/spec/ -├── frontend/ # Frontend guidelines -│ ├── index.md # Overview and quick reference -│ ├── component-guidelines.md -│ ├── hook-guidelines.md -│ ├── state-management.md -│ └── ... -│ -├── backend/ # Backend guidelines -│ ├── index.md -│ ├── directory-structure.md -│ ├── error-handling.md -│ ├── api-patterns.md -│ └── ... -│ -└── guides/ # Thinking guides - ├── index.md - ├── cross-layer-thinking-guide.md - ├── code-reuse-thinking-guide.md - └── cross-platform-thinking-guide.md -``` - ---- - -## Spec Categories - -### Frontend (`frontend/`) - -UI and client-side patterns: - -- Component structure -- React hooks usage -- State management -- Styling conventions -- Accessibility - -### Backend (`backend/`) - -Server-side patterns: - -- Directory structure -- API design -- Error handling -- Database access -- Security - -### Guides (`guides/`) - -Cross-cutting thinking guides: - -- How to think about cross-layer changes -- Code reuse strategies -- Platform considerations - ---- - -## Index Files - -Each category has an `index.md` that: - -1. Provides category overview -2. Lists all specs in the category -3. Gives quick reference for common patterns - -### Example: `frontend/index.md` - -```markdown -# Frontend Specifications - -## Quick Reference - -| Topic | Guideline | -| ---------- | -------------------------------- | -| Components | Functional components only | -| State | Use React Query for server state | -| Styling | Tailwind CSS | - -## Specifications - -1. [Component Guidelines](./component-guidelines.md) -2. [Hook Guidelines](./hook-guidelines.md) -3. [State Management](./state-management.md) -``` - ---- - -## Spec File Format - -````markdown -# [Spec Title] - -## Overview - -Brief description of what this spec covers. - -## Guidelines - -### 1. [Guideline Name] - -Detailed explanation... - -**Do:** - -```typescript -// Good example -``` -```` - -**Don't:** - -```typescript -// Bad example -``` - -### 2. [Another Guideline] - -... - -## Related Specs - -- [Related Spec 1](./related-spec.md) - -```` - ---- - -## Using Specs - -### In JSONL Context Files - -Reference specs in task context: - -```jsonl -{"file": ".trellis/spec/frontend/index.md", "reason": "Frontend overview"} -{"file": ".trellis/spec/frontend/component-guidelines.md", "reason": "Component patterns"} -```` - -### Manual Reading (Cursor) - -Read specs at session start: - -``` -1. Read .trellis/spec/{category}/index.md -2. Read specific guidelines as needed -3. Follow patterns in your code -``` - ---- - -## Creating New Specs - -### 1. Choose Category - -- Frontend UI patterns → `frontend/` -- Backend/API patterns → `backend/` -- Cross-cutting guides → `guides/` - -### 2. Create Spec File - -```bash -touch .trellis/spec/frontend/new-pattern.md -``` - -### 3. Follow Format - -Use the spec file format above. - -### 4. Update Index - -Add to category's `index.md`: - -```markdown -## Specifications - -... -N. [New Pattern](./new-pattern.md) -``` - -### 5. Reference in JSONL - -Add to relevant task context files. - ---- - -## Adding New Categories - -### 1. Create Directory - -```bash -mkdir .trellis/spec/mobile -``` - -### 2. Create Index - -```bash -touch .trellis/spec/mobile/index.md -``` - -### 3. Add Category Specs - -Create individual spec files. - -### 4. Update Task Templates - -Ensure new category is available in JSONL templates. - ---- - -## Best Practices - -1. **Keep specs focused** - One topic per file -2. **Use examples** - Show do/don't patterns -3. **Link related specs** - Cross-reference -4. **Update regularly** - Specs evolve with codebase -5. **Index everything** - Keep index files current diff --git a/Skills/new-skills/trellis-meta/references/core/tasks.md b/Skills/new-skills/trellis-meta/references/core/tasks.md deleted file mode 100644 index b460ba3..0000000 --- a/Skills/new-skills/trellis-meta/references/core/tasks.md +++ /dev/null @@ -1,223 +0,0 @@ -# Task System - -Track work items with phase-based execution. - ---- - -## Directory Structure - -``` -.trellis/tasks/ -├── {MM-DD-slug-assignee}/ # Active task directories -│ ├── task.json # Metadata, phases, branch -│ ├── prd.md # Requirements document -│ ├── info.md # Additional context (optional) -│ ├── implement.jsonl # Context for implement phase -│ ├── check.jsonl # Context for check phase -│ └── debug.jsonl # Context for debug phase -│ -└── archive/ # Completed tasks - └── {YYYY-MM}/ - └── {task-dir}/ -``` - ---- - -## Task Directory Naming - -Format: `{MM-DD}-{slug}-{assignee}` - -Examples: - -- `01-31-add-login-taosu` -- `02-01-fix-api-bug-cursor-agent` - ---- - -## task.json - -Task metadata and workflow configuration. - -```json -{ - "name": "Add user login", - "slug": "add-login", - "created": "2026-01-31T10:30:00", - "assignee": "taosu", - "status": "active", - "dev_type": "fullstack", - "scope": ["frontend", "backend"], - "branch": "feature/add-login", - "base_branch": "main", - "current_phase": 1, - "next_action": [ - { "phase": 1, "action": "implement" }, - { "phase": 2, "action": "check" }, - { "phase": 3, "action": "finish" } - ] -} -``` - -### Fields - -| Field | Type | Description | -| --------------- | -------- | ---------------------------------- | -| `name` | string | Human-readable task name | -| `slug` | string | URL-safe identifier | -| `created` | ISO date | Creation timestamp | -| `assignee` | string | Developer name | -| `status` | string | `active`, `paused`, `completed` | -| `dev_type` | string | `frontend`, `backend`, `fullstack` | -| `scope` | array | Affected areas | -| `branch` | string | Git branch name | -| `base_branch` | string | Branch to merge into | -| `current_phase` | number | Current workflow phase | -| `next_action` | array | Workflow phases | - ---- - -## prd.md - -Requirements document for the task. - -```markdown -# Add User Login - -## Overview - -Implement user authentication with email/password. - -## Requirements - -1. Login form with email and password fields -2. Form validation -3. API endpoint for authentication -4. Session management - -## Acceptance Criteria - -- [ ] User can log in with valid credentials -- [ ] Error shown for invalid credentials -- [ ] Session persists across page refresh - -## Technical Notes - -- Use existing auth service pattern -- Follow security guidelines in spec -``` - ---- - -## JSONL Context Files - -List files to inject as context for each phase. - -### Format - -```jsonl -{"file": ".trellis/spec/backend/index.md", "reason": "Backend guidelines"} -{"file": "src/services/auth.ts", "reason": "Existing auth service"} -{"file": ".trellis/tasks/01-31-add-login/prd.md", "reason": "Requirements"} -``` - -### Files - -| File | Phase | Purpose | -| ----------------- | --------- | ------------------------------ | -| `implement.jsonl` | implement | Dev specs, patterns to follow | -| `check.jsonl` | check | Quality criteria, review specs | -| `debug.jsonl` | debug | Debug context, error reports | - ---- - -## Current Task Pointer - -### `.trellis/.current-task` - -Points to active task directory. - -``` -.trellis/tasks/01-31-add-login-taosu -``` - -### Set Current Task - -```bash -python3 .trellis/scripts/task.py start -``` - -### Clear Current Task - -```bash -python3 .trellis/scripts/task.py stop -``` - ---- - -## Task CLI - -### Create Task - -```bash -python3 .trellis/scripts/task.py create "Task name" --slug task-slug -``` - -### List Tasks - -```bash -python3 .trellis/scripts/task.py list -``` - -### Start Task - -```bash -python3 .trellis/scripts/task.py start -``` - -### Initialize Context - -```bash -python3 .trellis/scripts/task.py init-context -``` - -Dev types: `frontend`, `backend`, `fullstack` - -### Archive Task - -```bash -python3 .trellis/scripts/task.py archive -``` - ---- - -## Workflow Phases - -Standard phase progression: - -``` -1. implement → Write code -2. check → Review and fix -3. finish → Final verification -4. create-pr → Create pull request (Multi-Session only) -``` - -### Custom Phases - -Modify `next_action` in task.json: - -```json -"next_action": [ - {"phase": 1, "action": "research"}, - {"phase": 2, "action": "implement"}, - {"phase": 3, "action": "check"} -] -``` - ---- - -## Best Practices - -1. **One task at a time** - Use `.current-task` to track focus -2. **Clear PRDs** - Write specific, testable requirements -3. **Relevant context** - Only include needed files in JSONL -4. **Archive completed** - Keep task directory clean diff --git a/Skills/new-skills/trellis-meta/references/core/workspace.md b/Skills/new-skills/trellis-meta/references/core/workspace.md deleted file mode 100644 index 5a74232..0000000 --- a/Skills/new-skills/trellis-meta/references/core/workspace.md +++ /dev/null @@ -1,160 +0,0 @@ -# Workspace System - -Track development progress across sessions with per-developer isolation. - ---- - -## Directory Structure - -``` -.trellis/workspace/ -├── index.md # Global overview -└── {developer}/ # Per-developer directory - ├── index.md # Personal index with @@@auto markers - ├── journal-1.md # Session journal (max 2000 lines) - ├── journal-2.md # Rolls over when limit reached - └── ... -``` - ---- - -## Developer Identity - -### `.trellis/.developer` - -Stores current developer name. Created by `init_developer.py`. - -``` -taosu -``` - -### Initialize Developer - -```bash -python3 .trellis/scripts/init_developer.py -``` - -Creates: - -- `.trellis/.developer` - Identity file -- `.trellis/workspace//` - Personal workspace -- `.trellis/workspace//index.md` - Personal index -- `.trellis/workspace//journal-1.md` - First journal - ---- - -## Journals - -### Purpose - -Track session history, decisions, and context. - -### Format - -```markdown -# Journal 1 - -## Session: 2026-01-31 10:30 - -### Context - -- Working on: [task description] -- Branch: feature/add-login - -### Progress - -- [x] Completed step 1 -- [ ] Working on step 2 - -### Notes - -Key decisions and learnings... - ---- -``` - -### Journal Rotation - -When journal exceeds 2000 lines: - -1. Archive current (append to index) -2. Create new journal-N.md -3. Continue writing - ---- - -## Personal Index - -### `workspace/{developer}/index.md` - -Tracks all sessions and provides quick reference. - -```markdown -# Developer Workspace - taosu - -## Active Work - -- Current task: `.trellis/tasks/01-31-add-login-taosu` -- Branch: feature/add-login - -## Recent Sessions - - - -- 2026-01-31: Implemented login UI -- 2026-01-30: Set up auth service - - -## Journals - -- journal-1.md (lines 1-2000) -- journal-2.md (current) -``` - -### @@@auto Markers - -Scripts use these markers to auto-update sections: - -- `@@@auto-sessions-start/end` - Recent sessions list -- `@@@auto-tasks-start/end` - Task summaries - ---- - -## Global Index - -### `workspace/index.md` - -Overview of all developers and project status. - -```markdown -# Project Workspace - -## Developers - -- taosu - Last active: 2026-01-31 -- cursor-agent - Last active: 2026-01-30 - -## Recent Activity - -... -``` - ---- - -## Scripts - -| Script | Purpose | -| ------------------- | ----------------------------- | -| `init_developer.py` | Initialize developer identity | -| `get_developer.py` | Get current developer name | -| `add_session.py` | Record session to journal | -| `get_context.py` | Get session context for AI | - ---- - -## Best Practices - -1. **One developer per machine** - Identity stored in `.developer` -2. **Regular journaling** - Record decisions and context -3. **Use markers** - Let scripts auto-update indexes -4. **Review journals** - Before starting new sessions diff --git a/Skills/new-skills/trellis-meta/references/how-to-modify/add-agent.md b/Skills/new-skills/trellis-meta/references/how-to-modify/add-agent.md deleted file mode 100644 index 39b8be0..0000000 --- a/Skills/new-skills/trellis-meta/references/how-to-modify/add-agent.md +++ /dev/null @@ -1,224 +0,0 @@ -# How To: Add Agent - -Add a new agent type like `my-agent`. - -**Platform**: Claude Code only - ---- - -## Files to Modify - -| File | Action | Required | -| ------------------------------------------ | ------ | --------------------- | -| `.claude/agents/my-agent.md` | Create | Yes | -| `.claude/hooks/inject-subagent-context.py` | Modify | Yes | -| `.trellis/tasks/{template}/my-agent.jsonl` | Create | Yes | -| `trellis-local/SKILL.md` | Update | Yes | -| `.claude/agents/dispatch.md` | Modify | If adding to pipeline | - ---- - -## Step 1: Create Agent Definition - -Create `.claude/agents/my-agent.md`: - -```markdown ---- -name: my-agent -description: | - What this agent specializes in. - When it should be used. -tools: Read, Write, Edit, Bash, Glob, Grep -model: opus ---- - -# My Agent - -## Core Responsibilities - -1. Primary responsibility -2. Secondary responsibility -3. ... - -## Workflow - -1. First step -2. Second step -3. ... - -## Forbidden Operations - -- Thing 1 (why it's forbidden) -- Thing 2 (why it's forbidden) -- git commit (unless explicitly allowed) - -## Output Format - -What the agent should produce. -``` - -### Agent Definition Fields - -| Field | Required | Description | -| ------------- | -------- | --------------------------- | -| `name` | Yes | Agent identifier | -| `description` | Yes | What the agent does | -| `tools` | Yes | Allowed tools | -| `model` | No | Model to use (opus, sonnet) | - ---- - -## Step 2: Update Hook - -Edit `.claude/hooks/inject-subagent-context.py`: - -### Add Constant - -```python -# Near other agent constants -AGENT_MY_AGENT = "my-agent" - -# Add to list -AGENTS_ALL = (..., AGENT_MY_AGENT) -``` - -### Add Context Function - -```python -def get_my_agent_context(repo_root: str, task_dir: str) -> list: - """Get context for my-agent.""" - context_files = [] - - # Load from JSONL - jsonl_path = os.path.join(task_dir, "my-agent.jsonl") - if os.path.exists(jsonl_path): - context_files.extend(load_jsonl_context(jsonl_path)) - - # Add any additional files - # context_files.append({"file": "...", "reason": "..."}) - - return context_files -``` - -### Add to Main Switch - -```python -elif subagent_type == AGENT_MY_AGENT: - context = get_my_agent_context(repo_root, task_dir) - new_prompt = build_agent_prompt( - agent_name="My Agent", - original_prompt=original_prompt, - context=context - ) -``` - ---- - -## Step 3: Create JSONL Template - -Create context template for task directories. - -**Option A**: Add to `task.py init-context`: - -```python -def init_my_agent_context(task_dir, dev_type): - jsonl_path = os.path.join(task_dir, "my-agent.jsonl") - with open(jsonl_path, "w") as f: - # Add relevant specs - f.write(json.dumps({ - "file": ".trellis/spec/guides/index.md", - "reason": "Thinking guides" - }) + "\n") -``` - -**Option B**: Manually create template: - -```jsonl -{"file": ".trellis/spec/guides/index.md", "reason": "Thinking guides"} -{"file": ".trellis/tasks/{task}/prd.md", "reason": "Requirements"} -``` - ---- - -## Step 4: Add to Pipeline (Optional) - -If the agent should be part of the standard workflow: - -### Update task.json Template - -```json -"next_action": [ - {"phase": 1, "action": "implement"}, - {"phase": 2, "action": "my-agent"}, // Add here - {"phase": 3, "action": "check"}, - {"phase": 4, "action": "finish"} -] -``` - -### Update dispatch.md - -Add handling for the new phase: - -```markdown -## Phase Handling - -... - -### my-agent Phase - -- Call `Task(subagent_type="my-agent")` -- Wait for completion -- Proceed to next phase -``` - ---- - -## Step 5: Document in trellis-local - -Update `.claude/skills/trellis-local/SKILL.md`: - -```markdown -## Agents - -### Added Agents - -#### my-agent - -- **File**: `.claude/agents/my-agent.md` -- **Platform**: [CC] -- **Purpose**: What it does -- **Tools**: Read, Write, Edit, Bash, Glob, Grep -- **Added**: 2026-01-31 -- **Reason**: Why it was added - -### Hooks Changed - -#### inject-subagent-context.py - -- **Change**: Added support for `my-agent` type -- **Lines modified**: XX-YY -- **Date**: 2026-01-31 -``` - ---- - -## Testing - -1. Create a task with my-agent.jsonl -2. Set as current task: `task.py start ` -3. Invoke agent: `Task(subagent_type="my-agent", prompt="Test")` -4. Verify context injection works -5. Verify agent behavior matches definition - ---- - -## Checklist - -- [ ] Agent definition created with proper frontmatter -- [ ] Hook updated with agent constant -- [ ] Hook updated with context function -- [ ] Hook updated with main switch case -- [ ] JSONL template created -- [ ] Added to pipeline (if needed) -- [ ] Documented in trellis-local -- [ ] Tested the agent diff --git a/Skills/new-skills/trellis-meta/references/how-to-modify/add-command.md b/Skills/new-skills/trellis-meta/references/how-to-modify/add-command.md deleted file mode 100644 index 0a69d12..0000000 --- a/Skills/new-skills/trellis-meta/references/how-to-modify/add-command.md +++ /dev/null @@ -1,152 +0,0 @@ -# How To: Add Slash Command - -Add a new `/trellis:my-command` command. - -**Platform**: All (9 platforms — each has its own command format) - ---- - -## Files to Modify - -| File | Action | Required | -| ---------------------------------------- | ------ | -------- | -| `.claude/commands/trellis/my-command.md` | Create | Yes | -| `.cursor/commands/my-command.md` | Create | Optional | -| `trellis-local/SKILL.md` | Update | Yes | - ---- - -## Step 1: Create Command File - -Create `.claude/commands/trellis/my-command.md`: - -```markdown ---- -name: my-command -description: Short description of what the command does ---- - -# My Command - -## Purpose - -Detailed description of the command's purpose. - -## When to Use - -- Scenario 1 -- Scenario 2 - -## Workflow - -1. First step -2. Second step -3. Third step - -## Output - -What the command produces. -``` - -### Command Name Convention - -- Use kebab-case: `my-command`, not `myCommand` -- Prefix with category if needed: `check-backend`, `before-frontend-dev` - ---- - -## Step 2: Mirror to Other Platforms (Optional) - -Commands are automatically mirrored to configured platforms by `trellis init` and `trellis update`. Each platform uses its own format: - -| Platform | Path | Format | -| ----------- | ------------------------------------------ | -------- | -| Cursor | `.cursor/commands/trellis-my-command.md` | Markdown | -| OpenCode | `.opencode/agents/trellis-my-command.md` | Markdown | -| iFlow | `.iflow/commands/trellis/my-command.md` | Markdown | -| Codex | `.agents/skills/my-command/SKILL.md` | Skill | -| Kilo | `.kilocode/commands/trellis/my-command.md` | Markdown | -| Kiro | `.kiro/skills/my-command/SKILL.md` | Skill | -| Gemini CLI | `.gemini/commands/trellis/my-command.toml` | TOML | -| Antigravity | `.agent/workflows/my-command.md` | Markdown | - ---- - -## Step 3: Document in trellis-local - -Update `.claude/skills/trellis-local/SKILL.md`: - -```markdown -## Commands - -### Added Commands - -#### /trellis:my-command - -- **File**: `.claude/commands/trellis/my-command.md` -- **Platform**: [ALL] -- **Purpose**: What it does -- **Added**: 2026-01-31 -- **Reason**: Why it was added -``` - ---- - -## Examples - -### Simple Command - -```markdown ---- -name: check-types -description: Run TypeScript type checking ---- - -# Check Types - -Run `pnpm typecheck` and report results. - -## Usage - -Run this command after making code changes to verify type safety. -``` - -### Command with Parameters - -Commands can reference user input or context: - -```markdown ---- -name: review-file -description: Review a specific file for code quality ---- - -# Review File - -## Input - -User should specify which file to review. - -## Workflow - -1. Read the specified file -2. Check against relevant specs -3. Report issues found -``` - ---- - -## Testing - -1. Run the command: `/trellis:my-command` -2. Verify behavior matches description -3. Test edge cases - ---- - -## Checklist - -- [ ] Command file created with proper frontmatter -- [ ] Mirrored to Cursor (if needed) -- [ ] Documented in trellis-local -- [ ] Tested the command diff --git a/Skills/new-skills/trellis-meta/references/how-to-modify/add-phase.md b/Skills/new-skills/trellis-meta/references/how-to-modify/add-phase.md deleted file mode 100644 index 244d09d..0000000 --- a/Skills/new-skills/trellis-meta/references/how-to-modify/add-phase.md +++ /dev/null @@ -1,237 +0,0 @@ -# How To: Add Workflow Phase - -Add a new phase to the task workflow pipeline. - -**Platform**: Claude Code only - ---- - -## Files to Modify - -| File | Action | Required | -| ------------------------------- | ------ | ------------ | -| Task `task.json` | Modify | Yes | -| `.claude/agents/dispatch.md` | Modify | Yes | -| `.claude/agents/{new-agent}.md` | Create | If new agent | -| `inject-subagent-context.py` | Modify | If new agent | -| `trellis-local/SKILL.md` | Update | Yes | - ---- - -## Standard Phases - -Default workflow: - -``` -implement → check → finish → create-pr -``` - ---- - -## Step 1: Update task.json - -Modify the `next_action` array in task.json: - -### Add Phase After Implement - -```json -{ - "next_action": [ - { "phase": 1, "action": "implement" }, - { "phase": 2, "action": "review" }, // New phase - { "phase": 3, "action": "check" }, - { "phase": 4, "action": "finish" }, - { "phase": 5, "action": "create-pr" } - ] -} -``` - -### Add Phase Before Implement - -```json -{ - "next_action": [ - { "phase": 1, "action": "design" }, // New phase - { "phase": 2, "action": "implement" }, - { "phase": 3, "action": "check" }, - { "phase": 4, "action": "finish" } - ] -} -``` - ---- - -## Step 2: Update Dispatch Agent - -Edit `.claude/agents/dispatch.md`: - -### Add Phase Handling - -```markdown -## Phase Handling - -### implement Phase - -...existing... - -### review Phase (NEW) - -- Purpose: Review implementation before check -- Call: `Task(subagent_type="review")` -- Next: Proceed to check phase - -### check Phase - -...existing... -``` - -### Update Workflow Description - -```markdown -## Workflow - -1. Read task.json for next_action -2. Execute phases in order: - - implement: Write code - - review: Review implementation (NEW) - - check: Quality verification - - finish: Final review - - create-pr: Create pull request -``` - ---- - -## Step 3: Create Agent (If New) - -If the phase uses a new agent, create the agent definition. - -→ See `add-agent.md` for full details. - -Quick version: - -```markdown ---- -name: review -description: Review implementation before check phase. -tools: Read, Glob, Grep ---- - -# Review Agent - -## Core Responsibilities - -1. Review code changes -2. Check against requirements -3. Identify issues before check phase - -## Forbidden Operations - -- Writing code (that's implement's job) -- Git operations -``` - ---- - -## Step 4: Update Hook (If New Agent) - -If using a new agent, update `inject-subagent-context.py`: - -```python -AGENT_REVIEW = "review" -AGENTS_ALL = (..., AGENT_REVIEW) - -def get_review_context(repo_root, task_dir): - # Load review.jsonl - ... - -elif subagent_type == AGENT_REVIEW: - context = get_review_context(repo_root, task_dir) - ... -``` - ---- - -## Step 5: Update Task Templates - -Update default task.json creation in `task.py`: - -```python -default_next_action = [ - {"phase": 1, "action": "implement"}, - {"phase": 2, "action": "review"}, # Add new phase - {"phase": 3, "action": "check"}, - {"phase": 4, "action": "finish"}, -] -``` - ---- - -## Step 6: Document in trellis-local - -```markdown -## Workflow Changes - -### Added review Phase - -- **Position**: After implement, before check -- **Agent**: review -- **Purpose**: Review implementation quality -- **Date**: 2026-01-31 -- **Reason**: Catch issues before check phase -``` - ---- - -## Common Phase Patterns - -### Design → Implement → Check - -```json -"next_action": [ - {"phase": 1, "action": "design"}, - {"phase": 2, "action": "implement"}, - {"phase": 3, "action": "check"} -] -``` - -### Implement → Test → Check - -```json -"next_action": [ - {"phase": 1, "action": "implement"}, - {"phase": 2, "action": "test"}, - {"phase": 3, "action": "check"} -] -``` - -### Research → Implement → Check - -```json -"next_action": [ - {"phase": 1, "action": "research"}, - {"phase": 2, "action": "implement"}, - {"phase": 3, "action": "check"} -] -``` - ---- - -## Testing - -1. Create task with new phase in next_action -2. Set as current task -3. Run dispatch agent -4. Verify phases execute in order -5. Verify new phase works correctly - ---- - -## Checklist - -- [ ] task.json updated with new phase -- [ ] dispatch.md updated with phase handling -- [ ] Agent created (if new) -- [ ] Hook updated (if new agent) -- [ ] Task templates updated -- [ ] Documented in trellis-local -- [ ] Tested workflow diff --git a/Skills/new-skills/trellis-meta/references/how-to-modify/add-spec.md b/Skills/new-skills/trellis-meta/references/how-to-modify/add-spec.md deleted file mode 100644 index f88fcc7..0000000 --- a/Skills/new-skills/trellis-meta/references/how-to-modify/add-spec.md +++ /dev/null @@ -1,212 +0,0 @@ -# How To: Add Spec Category - -Add a new spec category like `mobile/`. - -**Platform**: All - ---- - -## Files to Modify - -| File | Action | Required | -| ------------------------------- | ------ | -------- | -| `.trellis/spec/mobile/index.md` | Create | Yes | -| `.trellis/spec/mobile/*.md` | Create | Yes | -| Task JSONL templates | Update | Yes | -| `trellis-local/SKILL.md` | Update | Yes | - ---- - -## Step 1: Create Category Directory - -```bash -mkdir -p .trellis/spec/mobile -``` - ---- - -## Step 2: Create Index File - -Create `.trellis/spec/mobile/index.md`: - -```markdown -# Mobile Specifications - -Guidelines for mobile development. - -## Quick Reference - -| Topic | Guideline | -| ------------ | ------------------ | -| Architecture | MVVM pattern | -| State | Use StateFlow | -| Navigation | Jetpack Navigation | - -## Specifications - -1. [Architecture Guidelines](./architecture.md) -2. [UI Guidelines](./ui-guidelines.md) -3. [State Management](./state-management.md) - -## Key Principles - -- Principle 1 -- Principle 2 -- Principle 3 -``` - ---- - -## Step 3: Create Spec Files - -Create individual spec files in the category: - -### Example: `architecture.md` - -````markdown -# Mobile Architecture - -## Overview - -Description of architecture approach. - -## Guidelines - -### 1. Use MVVM Pattern - -Explanation... - -**Do:** - -```kotlin -// Good example -``` -```` - -**Don't:** - -```kotlin -// Bad example -``` - -### 2. Another Guideline - -... - -## Related Specs - -- [UI Guidelines](./ui-guidelines.md) - -```` - ---- - -## Step 4: Update JSONL Templates - -Add the new specs to relevant JSONL templates. - -### Option A: Update task.py - -Modify `init-context` to include mobile specs: - -```python -def init_mobile_context(task_dir): - jsonl_path = os.path.join(task_dir, "implement.jsonl") - with open(jsonl_path, "a") as f: - f.write(json.dumps({ - "file": ".trellis/spec/mobile/index.md", - "reason": "Mobile guidelines" - }) + "\n") -```` - -### Option B: Add to Existing Templates - -Edit existing JSONL files: - -```jsonl -{"file": ".trellis/spec/mobile/index.md", "reason": "Mobile guidelines"} -{"file": ".trellis/spec/mobile/architecture.md", "reason": "Architecture patterns"} -``` - ---- - -## Step 5: Document in trellis-local - -Update `.claude/skills/trellis-local/SKILL.md`: - -```markdown -## Specs Customized - -### Added Categories - -#### mobile/ - -- **Path**: `.trellis/spec/mobile/` -- **Purpose**: Mobile development guidelines -- **Added**: 2026-01-31 -- **Files**: - - `index.md` - Overview - - `architecture.md` - Architecture patterns - - `ui-guidelines.md` - UI patterns -``` - ---- - -## Spec File Best Practices - -### Structure - -```markdown -# [Spec Title] - -## Overview - -Brief description. - -## Guidelines - -### 1. [Guideline Name] - -Explanation with examples. - -### 2. [Another Guideline] - -... - -## Related Specs - -Links to related specs. -``` - -### Naming - -- Use kebab-case: `ui-guidelines.md` -- Be descriptive: `state-management.md` not `state.md` - -### Cross-References - -Link between specs: - -```markdown -See [State Management](./state-management.md) for more details. -``` - ---- - -## Testing - -1. Verify index links work -2. Create a task with the new specs in JSONL -3. Verify specs are injected correctly (Claude Code) -4. Verify specs are readable (Cursor) - ---- - -## Checklist - -- [ ] Category directory created -- [ ] Index file created with overview -- [ ] Spec files created with proper format -- [ ] JSONL templates updated -- [ ] Documented in trellis-local -- [ ] Cross-references verified diff --git a/Skills/new-skills/trellis-meta/references/how-to-modify/change-verify.md b/Skills/new-skills/trellis-meta/references/how-to-modify/change-verify.md deleted file mode 100644 index 5df200a..0000000 --- a/Skills/new-skills/trellis-meta/references/how-to-modify/change-verify.md +++ /dev/null @@ -1,180 +0,0 @@ -# How To: Change Verify Commands - -Add or modify Ralph Loop verification commands. - -**Platform**: Claude Code only (Ralph Loop) - ---- - -## Files to Modify - -| File | Action | Required | -| ------------------------ | ------ | -------- | -| `.trellis/worktree.yaml` | Modify | Yes | - ---- - -## Step 1: Edit worktree.yaml - -Open `.trellis/worktree.yaml` and modify the `verify` section: - -```yaml -verify: - - pnpm lint - - pnpm typecheck - - pnpm test # Add this -``` - ---- - -## Common Scenarios - -### Add Test Verification - -```yaml -verify: - - pnpm lint - - pnpm typecheck - - pnpm test -``` - -### Add Build Verification - -```yaml -verify: - - pnpm lint - - pnpm typecheck - - pnpm build -``` - -### Add Specific Test Suite - -```yaml -verify: - - pnpm lint - - pnpm typecheck - - pnpm test:unit # Fast unit tests only -``` - -### Different Languages - -**Go:** - -```yaml -verify: - - go fmt ./... - - go vet ./... - - golangci-lint run - - go test ./... -``` - -**Python:** - -```yaml -verify: - - ruff check . - - mypy . - - pytest -x -``` - -**Rust:** - -```yaml -verify: - - cargo fmt --check - - cargo clippy - - cargo test -``` - ---- - -## Execution Details - -### Order - -Commands run in order. First failure stops execution. - -**Recommended order**: fast → slow - -```yaml -verify: - - pnpm lint # ~2 seconds - - pnpm typecheck # ~10 seconds - - pnpm test:unit # ~30 seconds - - pnpm build # ~60 seconds -``` - -### Timeout - -Each command has 120 second timeout. - -For long-running commands: - -- Split into smaller chunks -- Use faster subset for Ralph Loop -- Run full suite manually - -### Exit Codes - -- Exit 0 = Pass -- Non-zero = Fail, agent continues - ---- - -## Testing - -### Manual Test - -```bash -# Run commands manually -pnpm lint && pnpm typecheck && pnpm test - -# Should all pass for Ralph Loop to allow stop -``` - -### Integration Test - -1. Make a change that fails linting -2. Run check agent -3. Verify Ralph Loop blocks and shows error -4. Fix the issue -5. Verify Ralph Loop allows stop - ---- - -## Troubleshooting - -### Command Not Found - -Ensure command is available: - -```bash -which pnpm # or npm, yarn, etc. -``` - -### Timeout Issues - -Increase timeout in `ralph-loop.py`: - -```python -COMMAND_TIMEOUT = 180 # Default is 120 -``` - -### Skip Verify Temporarily - -Comment out commands: - -```yaml -verify: - - pnpm lint - # - pnpm typecheck # Skip temporarily -``` - ---- - -## Checklist - -- [ ] Commands added to worktree.yaml -- [ ] Commands tested manually -- [ ] Order is fast → slow -- [ ] No timeout issues diff --git a/Skills/new-skills/trellis-meta/references/how-to-modify/modify-hook.md b/Skills/new-skills/trellis-meta/references/how-to-modify/modify-hook.md deleted file mode 100644 index ca2181d..0000000 --- a/Skills/new-skills/trellis-meta/references/how-to-modify/modify-hook.md +++ /dev/null @@ -1,270 +0,0 @@ -# How To: Modify Hook - -Change hook behavior for context injection or validation. - -**Platform**: Claude Code only - ---- - -## Files to Modify - -| File | Action | Required | -| ------------------------- | ------ | --------------------------- | -| `.claude/hooks/{hook}.py` | Modify | Yes | -| `.claude/settings.json` | Modify | If changing matcher/timeout | -| `trellis-local/SKILL.md` | Update | Yes | - ---- - -## Hook Types - -| Hook | File | Purpose | -| ------------------ | ---------------------------- | ---------------------- | -| SessionStart | `session-start.py` | Inject initial context | -| PreToolUse:Task | `inject-subagent-context.py` | Inject agent context | -| SubagentStop:check | `ralph-loop.py` | Quality enforcement | - ---- - -## Step 1: Understand Hook Structure - -### Input (stdin) - -Hooks receive JSON input: - -```json -{ - "hook_event": "PreToolUse", - "tool_name": "Task", - "tool_input": { - "subagent_type": "implement", - "prompt": "..." - } -} -``` - -### Output (stdout) - -Hooks output JSON: - -```json -{ - "result": "continue", - "message": "Optional message to inject", - "updatedInput": { - "prompt": "Modified prompt..." - } -} -``` - -### Result Types - -| Result | Effect | -| ---------- | ---------------------------------- | -| `continue` | Allow operation, optionally modify | -| `block` | Prevent operation | - ---- - -## Step 2: Modify Hook Logic - -### Example: Add Context to Session Start - -Edit `.claude/hooks/session-start.py`: - -```python -def get_additional_context(): - """Add custom context.""" - context = [] - - # Add custom file - custom_path = os.path.join(repo_root, ".trellis/custom.md") - if os.path.exists(custom_path): - with open(custom_path) as f: - context.append(f"## Custom Context\n{f.read()}") - - return "\n".join(context) - -# In main(): -additional = get_additional_context() -message = f"{existing_message}\n\n{additional}" -``` - -### Example: Add Agent Validation - -Edit `.claude/hooks/inject-subagent-context.py`: - -```python -def validate_agent_input(subagent_type, prompt): - """Validate agent invocation.""" - if subagent_type == "implement": - if "git commit" in prompt.lower(): - return False, "Implement agent cannot commit" - return True, None - -# In main(): -valid, error = validate_agent_input(subagent_type, prompt) -if not valid: - output = {"result": "block", "message": error} - print(json.dumps(output)) - return -``` - -### Example: Add Verify Command - -Edit `.claude/hooks/ralph-loop.py`: - -```python -# Add to verify commands list -ADDITIONAL_COMMANDS = ["pnpm test:unit"] - -def get_verify_commands(): - commands = read_worktree_yaml_verify() - commands.extend(ADDITIONAL_COMMANDS) - return commands -``` - ---- - -## Step 3: Modify Settings (If Needed) - -Edit `.claude/settings.json`: - -### Change Timeout - -```json -{ - "hooks": { - "PreToolUse": [ - { - "matcher": "Task", - "hooks": [ - { - "type": "command", - "command": "python3 ...", - "timeout": 60 // Increase from 30 - } - ] - } - ] - } -} -``` - -### Change Matcher - -```json -{ - "hooks": { - "SubagentStop": [ - { - "matcher": "check|my-agent", // Add new agent - "hooks": [...] - } - ] - } -} -``` - ---- - -## Step 4: Document in trellis-local - -Update `.claude/skills/trellis-local/SKILL.md`: - -```markdown -## Hooks Changed - -#### session-start.py - -- **Hook Event**: SessionStart -- **Change**: Added custom context injection -- **Lines modified**: 45-60 -- **Date**: 2026-01-31 -- **Reason**: Need to inject project-specific context - -#### inject-subagent-context.py - -- **Hook Event**: PreToolUse:Task -- **Change**: Added validation for implement agent -- **Lines modified**: 120-135 -- **Date**: 2026-01-31 -- **Reason**: Prevent accidental git commits -``` - ---- - -## Testing - -### Manual Test - -```bash -# Test session-start -python3 .claude/hooks/session-start.py - -# Test inject-subagent-context -echo '{"tool_input":{"subagent_type":"implement","prompt":"test"}}' | \ - python3 .claude/hooks/inject-subagent-context.py - -# Test ralph-loop -echo '{"subagent_type":"check","output":"test"}' | \ - python3 .claude/hooks/ralph-loop.py -``` - -### Integration Test - -1. Start new Claude Code session -2. Verify session-start output -3. Invoke subagent -4. Verify context injection -5. Verify Ralph Loop (for check agent) - ---- - -## Common Modifications - -### Add File to Session Context - -```python -# session-start.py -files_to_inject = [ - ".trellis/workflow.md", - ".trellis/custom-context.md", # Add this -] -``` - -### Skip Injection for Certain Agents - -```python -# inject-subagent-context.py -SKIP_INJECTION = ["research"] - -if subagent_type in SKIP_INJECTION: - print(json.dumps({"result": "continue"})) - return -``` - -### Add Custom Verification - -```python -# ralph-loop.py -def custom_check(): - """Custom verification logic.""" - # Check something - return True, None - -# In verify(): -ok, error = custom_check() -if not ok: - return False, error -``` - ---- - -## Checklist - -- [ ] Hook logic modified -- [ ] Settings updated (if needed) -- [ ] Manual test passed -- [ ] Integration test passed -- [ ] Documented in trellis-local diff --git a/Skills/new-skills/trellis-meta/references/how-to-modify/overview.md b/Skills/new-skills/trellis-meta/references/how-to-modify/overview.md deleted file mode 100644 index 49ff53c..0000000 --- a/Skills/new-skills/trellis-meta/references/how-to-modify/overview.md +++ /dev/null @@ -1,227 +0,0 @@ -# How-To Modification Guide - -Common Trellis customization scenarios and what files need to be modified. - ---- - -## Quick Reference - -| Task | Files to Modify | Platform | -| ------------------------------------------------- | ------------------------------------ | -------- | -| [Add slash command](#add-slash-command) | commands/, trellis-local | All | -| [Add agent](#add-agent) | agents/, hook, jsonl, trellis-local | CC | -| [Modify hook](#modify-hook) | hooks/, settings.json, trellis-local | CC | -| [Add spec category](#add-spec-category) | spec/, jsonl, trellis-local | All | -| [Change verify commands](#change-verify-commands) | worktree.yaml | CC | -| [Add workflow phase](#add-workflow-phase) | task.json, dispatch, trellis-local | CC | -| [Add post_create step](#add-post_create-step) | worktree.yaml | CC | -| [Modify session start](#modify-session-start) | session-start.py, trellis-local | CC | -| [Add core script](#add-core-script) | scripts/, trellis-local | All | -| [Change task types](#change-task-types) | task.py, jsonl templates | All | - -**Platform**: `All` = All 9 platforms | `CC` = Claude Code + iFlow (hook-capable) - ---- - -## Detailed Guides - -### Add Slash Command - -**Scenario**: Add a new `/trellis:my-command` command. - -**Files to modify**: - -``` -.claude/commands/trellis/my-command.md # Create: Command prompt -.cursor/commands/my-command.md # Create: Mirror for Cursor (optional) -.trellis-local/SKILL.md # Update: Document the change -``` - -**Steps**: - -1. Create command file with YAML frontmatter -2. Mirror to Cursor if needed -3. Document in trellis-local - -→ See `add-command.md` for details. - ---- - -### Add Agent - -**Scenario**: Add a new agent type like `my-agent`. - -**Files to modify**: - -``` -.claude/agents/my-agent.md # Create: Agent definition -.claude/hooks/inject-subagent-context.py # Modify: Add agent handling -.trellis/tasks/{template}/my-agent.jsonl # Create: Context template -.trellis-local/SKILL.md # Update: Document the change -``` - -**Optional**: - -``` -.claude/agents/dispatch.md # Modify: If adding to pipeline -task.json template # Modify: Add to next_action -``` - -→ See `add-agent.md` for details. - ---- - -### Modify Hook - -**Scenario**: Change hook behavior (context injection, validation, etc.). - -**Files to modify**: - -``` -.claude/hooks/{hook-name}.py # Modify: Hook logic -.claude/settings.json # Modify: If changing matcher/timeout -.trellis-local/SKILL.md # Update: Document the change -``` - -→ See `modify-hook.md` for details. - ---- - -### Add Spec Category - -**Scenario**: Add a new spec category like `mobile/`. - -**Files to modify**: - -``` -.trellis/spec/mobile/index.md # Create: Category index -.trellis/spec/mobile/*.md # Create: Spec files -.trellis/tasks/{template}/*.jsonl # Update: Reference new specs -.trellis-local/SKILL.md # Update: Document the change -``` - -→ See `add-spec.md` for details. - ---- - -### Change Verify Commands - -**Scenario**: Add or modify Ralph Loop verification commands. - -**Files to modify**: - -``` -.trellis/worktree.yaml # Modify: verify section -``` - -**Example**: - -```yaml -verify: - - pnpm lint - - pnpm typecheck - - pnpm test # Add this -``` - -→ See `change-verify.md` for details. - ---- - -### Add Workflow Phase - -**Scenario**: Add a new phase to the task workflow. - -**Files to modify**: - -``` -task.json (in task directories) # Modify: next_action array -.claude/agents/dispatch.md # Modify: Handle new phase -.claude/agents/{new-phase}.md # Create: If new agent needed -.claude/hooks/inject-subagent-context.py # Modify: If new agent -.trellis-local/SKILL.md # Update: Document the change -``` - -→ See `add-phase.md` for details. - ---- - -### Add post_create Step - -**Scenario**: Add setup steps after worktree creation. - -**Files to modify**: - -``` -.trellis/worktree.yaml # Modify: post_create section -``` - -**Example**: - -```yaml -post_create: - - pnpm install - - pnpm db:migrate # Add this -``` - ---- - -### Modify Session Start - -**Scenario**: Change what context is injected at session start. - -**Files to modify**: - -``` -.claude/hooks/session-start.py # Modify: Injection logic -.trellis-local/SKILL.md # Update: Document the change -``` - -→ See `modify-session-start.md` for details. - ---- - -### Add Core Script - -**Scenario**: Add a new automation script. - -**Files to modify**: - -``` -.trellis/scripts/my-script.py # Create: Script -.trellis/scripts/common/*.py # Create/Modify: If shared utilities -.trellis-local/SKILL.md # Update: Document the change -``` - -→ See `add-script.md` for details. - ---- - -### Change Task Types - -**Scenario**: Add or modify task dev_type (frontend, backend, etc.). - -**Files to modify**: - -``` -.trellis/scripts/task.py # Modify: init-context logic -.trellis/tasks/{template}/*.jsonl # Create: New JSONL templates -.trellis-local/SKILL.md # Update: Document the change -``` - -→ See `change-task-types.md` for details. - ---- - -## Documents in This Directory - -| Document | Scenario | -| ------------------------- | -------------------------------- | -| `add-command.md` | Adding slash commands | -| `add-agent.md` | Adding new agent types | -| `modify-hook.md` | Modifying hook behavior | -| `add-spec.md` | Adding spec categories | -| `change-verify.md` | Changing verify commands | -| `add-phase.md` | Adding workflow phases | -| `modify-session-start.md` | Changing session start injection | -| `add-script.md` | Adding automation scripts | -| `change-task-types.md` | Adding task types | diff --git a/Skills/new-skills/trellis-meta/references/meta/platform-compatibility.md b/Skills/new-skills/trellis-meta/references/meta/platform-compatibility.md deleted file mode 100644 index 25df7f4..0000000 --- a/Skills/new-skills/trellis-meta/references/meta/platform-compatibility.md +++ /dev/null @@ -1,185 +0,0 @@ -# Platform Compatibility Reference - -Detailed guide on Trellis feature availability across 9 AI coding platforms. - ---- - -## Overview - -Trellis v0.3.0 supports **9 platforms**. The key differentiator is **hook support** — Claude Code and iFlow have Python hook systems that enable automatic context injection and quality enforcement. Other platforms use commands/skills with manual context loading. - -| Platform | Config Directory | CLI Flag | Hooks | Command Format | -| ----------- | ----------------------------- | --------------- | ----- | -------------- | -| Claude Code | `.claude/` | (default) | ✅ | Markdown | -| iFlow | `.iflow/` | `--iflow` | ✅ | Markdown | -| Cursor | `.cursor/` | `--cursor` | ❌ | Markdown | -| OpenCode | `.opencode/` | `--opencode` | ❌ | Markdown | -| Codex | `.agents/skills/` | `--codex` | ❌ | Skills | -| Kilo | `.kilocode/commands/trellis/` | `--kilo` | ❌ | Markdown | -| Kiro | `.kiro/skills/` | `--kiro` | ❌ | Skills | -| Gemini CLI | `.gemini/commands/trellis/` | `--gemini` | ❌ | TOML | -| Antigravity | `.agent/workflows/` | `--antigravity` | ❌ | Markdown | - ---- - -## Platform Architecture - -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ TRELLIS FEATURE LAYERS │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ ┌────────────────────────────────────────────────────────────────────┐ │ -│ │ LAYER 3: AUTOMATION │ │ -│ │ Hooks, Ralph Loop, Auto-injection, Multi-Session │ │ -│ │ ─────────────────────────────────────────────────────────────────│ │ -│ │ Platform: Claude Code + iFlow │ │ -│ └────────────────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ┌────────────────────────────────▼───────────────────────────────────┐ │ -│ │ LAYER 2: AGENTS │ │ -│ │ Agent definitions, Task tool, Subagent invocation │ │ -│ │ ─────────────────────────────────────────────────────────────────│ │ -│ │ Platform: Claude Code + iFlow (full), others (manual) │ │ -│ └────────────────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ┌────────────────────────────────▼───────────────────────────────────┐ │ -│ │ LAYER 1: PERSISTENCE │ │ -│ │ Workspace, Tasks, Specs, Commands/Skills, JSONL files │ │ -│ │ ─────────────────────────────────────────────────────────────────│ │ -│ │ Platform: ALL 9 (file-based, portable) │ │ -│ └────────────────────────────────────────────────────────────────────┘ │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ -``` - ---- - -## Detailed Feature Breakdown - -### Layer 1: Persistence (All 9 Platforms) - -These features work on all platforms because they're file-based. - -| Feature | Location | Description | -| ------------------ | ------------------------ | ----------------------------------------- | -| Workspace system | `.trellis/workspace/` | Journals, session history | -| Task system | `.trellis/tasks/` | Task tracking, requirements | -| Spec system | `.trellis/spec/` | Coding guidelines | -| Commands/Skills | Platform-specific dirs | Command prompts in each platform's format | -| JSONL context | `*.jsonl` in task dirs | Context file lists | -| Developer identity | `.trellis/.developer` | Who is working | -| Current task | `.trellis/.current-task` | Active task pointer | - -### Layer 2: Agents (Claude Code + iFlow Full, Others Manual) - -| Feature | Claude Code / iFlow | Other Platforms | -| ------------------ | ------------------------------ | ------------------------- | -| Agent definitions | Auto-loaded via `--agent` flag | Read agent files manually | -| Task tool | Full subagent support | No Task tool | -| Context injection | Automatic via hooks | Manual copy-paste | -| Agent restrictions | Enforced by definition | Honor code only | - -### Layer 3: Automation (Claude Code + iFlow Only) - -| Feature | Dependency | Why Hook-Platforms Only | -| ---------------------- | ------------------ | -------------------------------- | -| SessionStart hook | `settings.json` | Hook system for lifecycle events | -| PreToolUse hook | Hook system | Intercepts tool calls | -| SubagentStop hook | Hook system | Controls agent lifecycle | -| Auto context injection | PreToolUse:Task | Hooks inject JSONL content | -| Ralph Loop | SubagentStop:check | Blocks agent until verify passes | -| Multi-Session | CLI + hooks | Session resume, worktree scripts | - -**No workaround**: These features fundamentally require a hook system. - ---- - -## Platform Usage Guides - -### Claude Code + iFlow (Full Support) - -All features work automatically. Hooks provide context injection and quality enforcement. - -```bash -# Initialize -trellis init -u your-name # Claude Code (default) -trellis init --iflow -u your-name # iFlow -``` - -### Cursor - -```bash -trellis init --cursor -u your-name -``` - -- **Works**: Workspace, tasks, specs, commands (read via `.cursor/commands/trellis-*.md`) -- **Doesn't work**: Hooks, auto-injection, Ralph Loop, Multi-Session -- **Workaround**: Manually read spec files at session start - -### OpenCode - -```bash -trellis init --opencode -u your-name -``` - -- **Works**: Workspace, tasks, specs, agents, commands -- **Note**: Full subagent context injection requires [oh-my-opencode](https://github.com/nicepkg/oh-my-opencode). Without it, agents use Self-Loading fallback. - -### Codex - -```bash -trellis init --codex -u your-name -``` - -- Commands mapped to Codex Skills format under `.agents/skills/` -- Use `$start`, `$finish-work`, `$brainstorm` etc. to invoke - -### Kilo, Kiro, Gemini CLI, Antigravity - -```bash -trellis init --kilo -u your-name -trellis init --kiro -u your-name -trellis init --gemini -u your-name -trellis init --antigravity -u your-name -``` - -- Each platform uses its native command format -- Core file-based systems work the same across all platforms - ---- - -## Version Compatibility Matrix - -| Trellis Version | Platforms Supported | -| --------------- | ------------------- | -| 0.2.x | Claude Code, Cursor | -| 0.3.0 | All 9 platforms | - ---- - -## Checking Your Platform - -### Claude Code - -```bash -claude --version -cat .claude/settings.json | grep -A 5 '"hooks"' -``` - -### Other Platforms - -```bash -# Check if platform config directory exists -ls -la .cursor/ .opencode/ .iflow/ .agents/ .kilocode/ .kiro/ .gemini/ .agent/ 2>/dev/null -``` - -### Determining Support Level - -``` -Does the platform have hook support? -├── YES (Claude Code, iFlow) → Full Trellis support -└── NO (all others) → Partial support - ├── Can read files → Layer 1 works - └── Has agent system → Layer 2 partial -``` diff --git a/Skills/new-skills/trellis-meta/references/meta/self-iteration-guide.md b/Skills/new-skills/trellis-meta/references/meta/self-iteration-guide.md deleted file mode 100644 index 535a17e..0000000 --- a/Skills/new-skills/trellis-meta/references/meta/self-iteration-guide.md +++ /dev/null @@ -1,305 +0,0 @@ -# Trellis Self-Iteration Guide - -How to maintain skill documentation when customizing Trellis. - ---- - -## Core Principle - -**Every Trellis modification MUST be documented in the appropriate skill.** - -``` -Modification to Trellis → Update trellis-local (project skill) -Update to Trellis itself → Update trellis-meta (meta skill) -``` - ---- - -## Decision Tree - -``` -Is this a modification to Trellis? -│ -├── YES: What kind? -│ │ -│ ├── Project-specific customization -│ │ └── Update .claude/skills/trellis-local/SKILL.md -│ │ -│ ├── Bug fix to core Trellis -│ │ └── Update ~/.claude/skills/trellis-meta/ -│ │ (or project copy if reviewing first) -│ │ -│ └── New feature to core Trellis -│ └── Update trellis-meta after release -│ -└── NO: Just using Trellis - └── No skill update needed -``` - ---- - -## Self-Iteration Workflow - -### Step 1: Before Making Changes - -```bash -# Check if project skill exists -ls .claude/skills/trellis-local/SKILL.md - -# If not, create it from template -mkdir -p .claude/skills/trellis-local -# Copy template from trellis-meta/references/trellis-local-template.md -``` - -### Step 2: Make the Trellis Modification - -Do your work: add command, modify hook, etc. - -### Step 3: Document in Project Skill - -Open `.claude/skills/trellis-local/SKILL.md` and: - -1. **Find the right section** (Commands/Agents/Hooks/Specs/Workflow) -2. **Add entry using template** -3. **Update changelog** -4. **Update summary counts** - -### Step 4: Verify Documentation - -Ask yourself: - -- [ ] Would another AI understand what was changed? -- [ ] Is the "why" documented? -- [ ] Are affected files listed? -- [ ] Is the date recorded? - ---- - -## Documentation Templates - -### New Command - -```markdown -#### /trellis:my-command - -- **File**: `.claude/commands/trellis/my-command.md` -- **Purpose**: Brief description of what it does -- **Added**: 2026-01-31 -- **Reason**: Why this command was needed - -**Usage**: -``` - -/trellis:my-command [args] - -``` - -**Example**: -User asks "..." → Command does "..." -``` - -### New Agent - -```markdown -#### my-agent - -- **File**: `.claude/agents/my-agent.md` -- **Purpose**: What this agent specializes in -- **Tools**: Read, Write, Edit, Bash, Glob, Grep -- **Model**: opus -- **Added**: 2026-01-31 -- **Reason**: Why this agent was needed - -**Hook Integration**: - -- Added to `inject-subagent-context.py` at line X -- Uses `my-agent.jsonl` for context - -**Invocation**: -``` - -Task(subagent_type="my-agent", prompt="...") - -``` - -``` - -### Hook Modification - -````markdown -#### inject-subagent-context.py - -- **Hook Event**: PreToolUse:Task -- **Change**: Added handling for `my-agent` subagent type -- **Lines Modified**: 45-67, 120-135 -- **Date**: 2026-01-31 -- **Reason**: Support new agent type - -**Code Changes**: - -```python -# Added constant -AGENT_MY_AGENT = "my-agent" - -# Added to agent list -AGENTS_ALL = (..., AGENT_MY_AGENT) - -# Added context function -def get_my_agent_context(repo_root, task_dir): - ... -``` -```` - -```` - -### Spec Category Addition - -```markdown -#### security/ -- **Path**: `.trellis/spec/security/` -- **Purpose**: Security guidelines for the project -- **Files**: - - `index.md` - Category overview - - `auth-guidelines.md` - Authentication patterns - - `input-validation.md` - Validation requirements -- **Added**: 2026-01-31 -- **Reason**: Project requires security-focused development - -**JSONL Integration**: -```jsonl -{"file": ".trellis/spec/security/index.md", "reason": "Security guidelines"} -```` - -```` - -### Workflow Change - -```markdown -#### Custom Phase Order -- **What**: Changed default task phases to include research phase -- **Files Affected**: - - `.trellis/scripts/task.py` (init-context function) - - Default task.json template -- **Date**: 2026-01-31 -- **Reason**: All tasks in this project need research first - -**New Default next_action**: -```json -[ - {"phase": 1, "action": "research"}, - {"phase": 2, "action": "implement"}, - {"phase": 3, "action": "check"}, - {"phase": 4, "action": "finish"}, - {"phase": 5, "action": "create-pr"} -] -```` - -```` - ---- - -## Changelog Format - -```markdown -### 2026-01-31 - Feature: Custom Research Phase -- Added research phase as default first phase -- Modified task.py init-context -- Updated task.json template -- Reason: Project complexity requires upfront research - -### 2026-01-30 - Bugfix: Hook Timeout -- Increased ralph-loop.py timeout from 10s to 30s -- Reason: Complex verification commands were timing out - -### 2026-01-29 - Initial Setup -- Initialized trellis-local skill -- Base Trellis version: 0.3.0 -```` - ---- - -## Multi-Project Scenario - -When working with multiple Trellis projects: - -``` -~/projects/ -├── project-a/ -│ └── .claude/skills/trellis-local/ # Project A customizations -├── project-b/ -│ └── .claude/skills/trellis-local/ # Project B customizations -└── project-c/ - └── .claude/skills/trellis-local/ # Project C customizations - -~/.claude/skills/ -└── trellis-meta/ # Shared meta-skill (vanilla Trellis) -``` - -**Each project has its own `trellis-local`** documenting that project's specific customizations. - -**The meta-skill is shared** and documents vanilla Trellis. - ---- - -## Upgrade Workflow - -When upgrading Trellis to a new version: - -### 1. Review New Version Changes - -```bash -# Compare new meta-skill with current -diff -r ~/.claude/skills/trellis-meta/references/ \ - ./new-trellis-meta/references/ -``` - -### 2. Check for Conflicts - -Review each customization in `trellis-local`: - -- Does new version include this feature natively? -- Does new version break this customization? -- Can this customization be simplified? - -### 3. Merge Carefully - -```bash -# Backup current meta-skill -cp -r ~/.claude/skills/trellis-meta ~/.claude/skills/trellis-meta.backup - -# Update meta-skill -cp -r ./new-trellis-meta/* ~/.claude/skills/trellis-meta/ -``` - -### 4. Update Project Skills - -Add migration note to `trellis-local`: - -```markdown -### 2026-02-01 - Upgraded to Trellis 0.4.0 - -- Updated meta-skill to 0.4.0 -- Kept custom `security-agent` (not in vanilla) -- Migrated `my-command` to new command format -- Removed `old-hook` customization (now in vanilla) -``` - ---- - -## AI Instructions - -When an AI modifies Trellis, it MUST: - -1. **Check** if `trellis-local` exists in the project -2. **Create** it from template if missing -3. **Document** the change immediately after making it -4. **Update** the changelog with date and description -5. **Verify** the documentation is complete - -**Never** modify `trellis-meta` for project-specific changes. - -**Always** tell the user what was documented. - -Example AI response: - -> "I've added the `/trellis:deploy` command and documented it in `.claude/skills/trellis-local/SKILL.md` under the Commands section." diff --git a/Skills/new-skills/trellis-meta/references/meta/trellis-local-template.md b/Skills/new-skills/trellis-meta/references/meta/trellis-local-template.md deleted file mode 100644 index 8fd219a..0000000 --- a/Skills/new-skills/trellis-meta/references/meta/trellis-local-template.md +++ /dev/null @@ -1,309 +0,0 @@ -# Trellis Local Skill Template - -Copy this template to create a project-specific `trellis-local` skill. - ---- - -## How to Use - -1. Create directory: `mkdir -p .claude/skills/trellis-local` -2. Copy the template below to `.claude/skills/trellis-local/SKILL.md` -3. Replace `[PROJECT_NAME]` with your project name -4. Update version info - ---- - -## Template - -````markdown ---- -name: trellis-local -description: | - Project-specific Trellis customizations for [PROJECT_NAME]. - This skill documents all modifications made to the vanilla Trellis system. - Inherits from trellis-meta for base architecture documentation. - Use this skill to understand what's been customized in this project's Trellis setup. ---- - -# Trellis Local - [PROJECT_NAME] - -## Overview - -This skill documents all customizations made to Trellis in this project. For vanilla Trellis documentation, see the `trellis-meta` skill. - -## Base Information - -| Field | Value | -| ---------------- | ---------- | -| Trellis Version | X.X.X | -| Date Initialized | YYYY-MM-DD | -| Last Updated | YYYY-MM-DD | - ---- - -## Customizations Summary - -Quick reference of what's been modified: - -- **Commands**: X added, Y modified -- **Agents**: X added, Y modified -- **Hooks**: X modified -- **Specs**: X categories added -- **Workflow**: [summary of changes] - ---- - -## Commands - -### Added Commands - - - -(none yet) - -### Modified Commands - - - -(none yet) - ---- - -## Agents - -> **Note**: Agent auto-loading is [CC] (Claude Code only). On Cursor, agents are read manually. - -### Added Agents - - - -(none yet) - -### Modified Agents - - - -(none yet) - ---- - -## Hooks [CC] - -> **Claude Code Only**: Hooks require Claude Code's hook system. Not available on Cursor. - -### Modified Hooks - - - -(none yet) - ---- - -## Specs - -### Added Categories - - - -(none yet) - -### Modified Specs - - - -(none yet) - ---- - -## Workflow Changes - -### Task Configuration - - - -(none yet) - -### JSONL Templates - - - -(none yet) - ---- - -## worktree.yaml Customizations - -```yaml -# Document any changes to worktree.yaml here -``` - -(using defaults) - ---- - -## Changelog - -Record all changes chronologically. - -### YYYY-MM-DD - Initial Setup - -- Initialized trellis-local skill -- Base Trellis version: X.X.X - - - ---- - -## Migration Notes - -Document any special steps needed when upgrading Trellis. - - - -(none yet) - ---- - -## Known Issues - -Track any issues with customizations. - - - -(none yet) - -```` - ---- - -## Automation Script - -To auto-create the skill, run: - -```bash -#!/bin/bash -# create-trellis-local.sh - -PROJECT_NAME="${1:-$(basename $(pwd))}" -SKILL_DIR=".claude/skills/trellis-local" - -mkdir -p "$SKILL_DIR" - -cat > "$SKILL_DIR/SKILL.md" << 'EOF' ---- -name: trellis-local -description: | - Project-specific Trellis customizations for PROJECT_NAME_PLACEHOLDER. - This skill documents all modifications made to the vanilla Trellis system. - Inherits from trellis-meta for base architecture documentation. ---- - -# Trellis Local - PROJECT_NAME_PLACEHOLDER - -## Base Information - -| Field | Value | -|-------|-------| -| Trellis Version | $(cat package.json 2>/dev/null | grep version | head -1 | cut -d'"' -f4 || echo "unknown") | -| Date Initialized | $(date +%Y-%m-%d) | -| Last Updated | $(date +%Y-%m-%d) | - -## Customizations - -(none yet - document changes as you make them) - -## Changelog - -### $(date +%Y-%m-%d) - Initial Setup -- Initialized trellis-local skill -EOF - -sed -i '' "s/PROJECT_NAME_PLACEHOLDER/$PROJECT_NAME/g" "$SKILL_DIR/SKILL.md" - -echo "Created $SKILL_DIR/SKILL.md for project: $PROJECT_NAME" -```` diff --git a/Skills/resource-decision-guide/SKILL.md b/Skills/resource-decision-guide/SKILL.md deleted file mode 100644 index 9a336dc..0000000 --- a/Skills/resource-decision-guide/SKILL.md +++ /dev/null @@ -1,189 +0,0 @@ ---- -name: SIG-IGGA Resource Decision Guide -description: Guía maestra que mapea cada tipo de tarea a los recursos óptimos. Enseña al AI a usar el recurso correcto para cada situación, evitando sobre-ingeniería en tareas simples. ---- - -# 🧭 Guía de Decisión de Recursos — SIG-IGGA-AVISOS - -> **Regla de Oro**: No usar herramientas especializadas para tareas simples. -> Un cambio de color en CSS NO necesita un MCP de PostgreSQL. - ---- - -## 🔀 Árbol de Decisión Rápido - -``` -¿Qué tipo de tarea es? -│ -├─ 🐛 BUG / ERROR EN PRODUCCIÓN -│ ├─ ¿Error 500 en la API? → MCP Sentry + MCP PostgreSQL -│ ├─ ¿Error CORS? → Workflow /debug-cors + MCP Fetch -│ ├─ ¿Error de mapa/GIS? → Skill sig-igga-gis + MCP Filesystem -│ └─ ¿Error de datos/schema? → MCP PostgreSQL directo -│ -├─ 🚀 DEPLOY / DESPLIEGUE -│ ├─ ¿Deploy frontend? → Workflow /deploy-frontend -│ ├─ ¿Deploy completo? → Skill sig-igga-deploy -│ └─ ¿Verificar producción? → Workflow /health-check -│ -├─ 📊 REPORTES / DATOS -│ ├─ ¿Reporte Excel GEAM? → Skill sig-igga-export -│ ├─ ¿Consulta de datos? → MCP PostgreSQL -│ └─ ¿Estadísticas de avisos? → MCP PostgreSQL + MCP Fetch (API) -│ -├─ 🗺️ GIS / GEOESPACIAL -│ ├─ ¿Validar GeoJSON? → Skill sig-igga-gis -│ ├─ ¿Verificar coordenadas? → Skill sig-igga-gis + MCP PostgreSQL -│ ├─ ¿Importar capa? → MCP Filesystem + Skill sig-igga-gis -│ └─ ¿Problema con la proyección? → Skill sig-igga-gis -│ -├─ 🏗️ DESARROLLO / NUEVA FUNCIONALIDAD -│ ├─ ¿Tarea simple (CSS, fix menor)? → NINGÚN recurso extra (baseline) -│ ├─ ¿Feature compleja multi-módulo? → Skill antigravity-skill-orchestrator -│ ├─ ¿Nuevo componente visual? → Skill antigravity-design-expert -│ ├─ ¿Planificar refactorización? → MCP Sequential Thinking -│ └─ ¿Buscar skill específica? → MCP SkillsMP -│ -├─ 🧪 TESTING -│ ├─ ¿Test de API? → Skill sig-igga-testing + MCP Fetch -│ ├─ ¿Test de frontend? → Skill sig-igga-testing -│ └─ ¿Health check rápido? → Workflow /health-check -│ -├─ 📝 GESTIÓN DE CÓDIGO -│ ├─ ¿Ver diff/historial? → MCP Git -│ ├─ ¿Crear PR/Issue? → MCP GitHub -│ ├─ ¿Ver errores en prod? → MCP Sentry -│ └─ ¿Leer archivos del proyecto? → MCP Filesystem -│ -├─ 🔍 INVESTIGACIÓN / ANÁLISIS -│ ├─ ¿Analizar sesiones pasadas? → Skill analyze-project -│ ├─ ¿Buscar skills nuevas? → MCP SkillsMP -│ ├─ ¿Leer documentación web? → MCP Fetch -│ └─ ¿Planificación compleja? → MCP Sequential Thinking -│ -└─ 🔧 MANTENIMIENTO - ├─ ¿Levantar dev local? → Workflow /dev-start - ├─ ¿Verificar estado general? → Workflow /health-check - └─ ¿CI/CD? → GitHub Actions ci.yml -``` - ---- - -## 📋 Inventario Completo de Recursos - -### Nivel 1: MCPs (9 servidores — acceso directo) - -| MCP | Cuándo SÍ usar | Cuándo NO usar | -|---|---|---| -| 🐙 **GitHub** | Issues, PRs, releases, ver código remoto | Cambios locales (usar Git MCP o edición directa) | -| 🗄️ **PostgreSQL** | Diagnosticar datos, validar schema, queries rápidas | Cambios de schema (hacer manual con SQL seguro) | -| 🌐 **Fetch** | Probar API, verificar CORS, leer docs de OpenLayers | Páginas con autenticación | -| 🧠 **Memory** | Recordar decisiones, patrones de skills exitosos | Datos efímeros o temporales | -| 🧩 **Sequential Thinking** | Planificar migraciones, refactorizaciones grandes | Tareas simples y directas | -| 📂 **Git** | Commits, branches, ver historial, diffs | Operaciones destructivas sin confirmación | -| 📁 **Filesystem** | Leer GeoJSON, configs, logs, archivos de capas | Escribir archivos grandes (mejor herramientas nativas) | -| 🔍 **Sentry** | Ver errores de prod, analizar stack traces, monitorear | Errores de desarrollo local | -| 🎯 **SkillsMP** | Buscar skills nuevas, instalar capacidades dinámicas | Tareas cubiertas por skills existentes | - -### Nivel 2: Skills Personalizadas (4 — dominio SIG-IGGA) - -| Skill | Activar cuando... | NO activar cuando... | -|---|---|---| -| 📊 **sig-igga-export** | "Generar reporte", "exportar Excel", "GEAM" | Consultas simples de datos | -| 🧪 **sig-igga-testing** | "Testear", "verificar endpoints", "smoke test" | Un solo curl rápido | -| 🗺️ **sig-igga-gis** | "GeoJSON", "coordenadas", "KML", "PostGIS", "capa" | Datos sin componente geográfico | -| 🚀 **sig-igga-deploy** | "Deploy", "desplegar", "subir a producción" | Cambios locales sin push | - -### Nivel 3: Skills de Antigravity (8 — meta/utilidades) - -| Skill | Propósito | Cuándo activar | -|---|---|---| -| 🎯 **antigravity-skill-orchestrator** | Elegir la combinación correcta de skills | Tareas complejas multi-módulo donde no sabes qué skills necesitas | -| 🔍 **analyze-project** | Análisis forense de sesiones de trabajo | Al final de un sprint o cuando hay muchos problemas recurrentes | -| 🎨 **antigravity-design-expert** | UI premium: glassmorphism, animaciones, 3D CSS | Cuando se necesita un componente visual wow | -| ⚙️ **antigravity-manager** | Guía del proyecto AntigravityManager | Solo si se trabaja en el propio Antigravity Manager | -| 💰 **antigravity-balance** | Verificar cuota de tokens de Antigravity | Cuando se sospecha que la cuota está baja | -| 🔄 **antigravity-rotator** | Rotación automática de cuentas | Gestión de múltiples cuentas (no aplica para SIG-IGGA) | -| 📋 **antigravity-workflows** | Orquestar workflows multi-fase | SaaS MVP, Security Audit, AI Agent, Browser QA | -| 🏗️ **trellis-meta** | Framework de desarrollo estructurado con specs | Proyectos grandes con múltiples desarrolladores | - -### Nivel 4: Workflows (4 — atajos rápidos) - -| Workflow | Trigger | Tiempo | -|---|---|---| -| `/health-check` | "¿Está todo bien?", "verificar producción" | ~30 seg | -| `/debug-cors` | "Error CORS", "Access-Control", "blocked" | ~1 min | -| `/dev-start` | "Levantar local", "npm run dev" | ~2 min | -| `/deploy-frontend` | "Deploy frontend", "subir a Cloudflare" | ~3 min | - -### Nivel 5: CI/CD (GitHub Actions) - -| Pipeline | Trigger | Qué hace | -|---|---|---| -| `ci.yml` | Push/PR a main | Lint Python + TypeScript + health check | -| `etl_cron.yml` | Viernes 23:00 UTC | ETL SharePoint → Railway | - ---- - -## ⚡ Combinaciones Óptimas por Escenario - -### Escenario: "La app no carga en producción" - -``` -1. /health-check → ¿Backend/Frontend vivos? -2. MCP Sentry → ¿Hay errores nuevos? -3. MCP Fetch (CORS test) → ¿CORS bloqueando? -4. MCP PostgreSQL → ¿DB conectada? -5. Skill sig-igga-testing → Smoke test completo -``` - -### Escenario: "Agregar nueva capa GIS al mapa" - -``` -1. MCP Filesystem → Leer el archivo GeoJSON -2. Skill sig-igga-gis → Validar geometrías y proyección -3. MCP PostgreSQL → Verificar schema en DB -4. Edición directa → Agregar componente en frontend -5. /deploy-frontend → Subir cambios -``` - -### Escenario: "Generar reporte mensual para ISA" - -``` -1. MCP PostgreSQL → Extraer datos de avisos -2. Skill sig-igga-export → Generar Excel formateado -3. MCP Git → Commit del reporte -``` - -### Escenario: "Rediseñar el dashboard de analytics" - -``` -1. MCP Sequential Thinking → Planificar componentes -2. Skill antigravity-design-expert → Diseño premium glassmorphism -3. Edición directa → Implementar componentes React -4. Skill sig-igga-testing → Verificar que todo funciona -5. /deploy-frontend → Deploy -``` - -### Escenario: "Debuggear un error 500" - -``` -1. MCP Sentry → Ver stack trace exacto -2. MCP PostgreSQL → Verificar estado de datos -3. MCP Fetch → Reproducir el request -4. Edición directa → Aplicar fix -5. /health-check → Verificar fix en producción -``` - ---- - -## 🚫 Anti-Patrones (NO hacer) - -| ❌ No hagas | ✅ Haz en su lugar | -|---|---| -| Usar MCP PostgreSQL para cambiar un color CSS | Editar el archivo directamente | -| Activar skill-orchestrator para renombrar una variable | Renombrar directamente | -| Usar MCP Fetch para leer un archivo local | Usar MCP Filesystem o view_file | -| Activar analyze-project para un fix rápido | Solo para análisis post-sprint | -| Usar Sequential Thinking para una tarea de 1 paso | Ejecutar directamente | -| Buscar en SkillsMP algo que ya tienes como skill local | Usar la skill local primero | diff --git a/apps/api/main.py b/apps/api/main.py index 0947b1e..59f76f6 100644 --- a/apps/api/main.py +++ b/apps/api/main.py @@ -60,7 +60,7 @@ async def get_system_status(): } } -@app.get("/parcels", tags=["Cadastre"]) +@app.get("/api/parcels", tags=["Cadastre"]) async def get_ingested_parcels(db: Session = Depends(get_db)): """ Retrieves real cadastral data ingested from IGAC. @@ -93,17 +93,17 @@ async def get_ingested_parcels(db: Session = Depends(get_db)): "note": "FALLBACK_DEMO_DATA" } -@app.post("/validate", tags=["Topology"]) +@app.post("/api/validate", tags=["Topology"]) async def validate_topology(request: ValidationRequest): """Expert-level topological validation engine.""" return validate_collection_topology(request.features) -@app.post("/intelligence/parcel_score", tags=["AI"]) +@app.post("/api/intelligence/parcel_score", tags=["AI"]) async def calculate_parcel_intelligence(feature: GeoJSONFeature): """Calculates the 'Spatial Intelligence Score' for a parcel.""" return calculate_parcel_score(feature) -@app.post("/intelligence/analyze_context", tags=["GeoAI"]) +@app.post("/api/intelligence/analyze_context", tags=["GeoAI"]) async def analyze_context(feature: GeoJSONFeature): """ Advanced Environmental Analysis using Polars and DuckDB Simulation. @@ -138,7 +138,7 @@ async def query_vur(matricula: str): except Exception as e: raise HTTPException(status_code=500, detail=str(e)) -@app.get("/config/mapbox-token", tags=["System"]) +@app.get("/api/config/mapbox-token", tags=["System"]) async def get_mapbox_token(): """Returns the Mapbox token from environment variables.""" token = os.getenv("MAPBOX_TOKEN") diff --git a/apps/web/next.config.js b/apps/web/next.config.js deleted file mode 100644 index 708ffef..0000000 --- a/apps/web/next.config.js +++ /dev/null @@ -1,39 +0,0 @@ -/** @type {import('next').NextConfig} */ -const nextConfig = { - async redirects() { - return [ - { - source: '/lab/gesture_sandbox.html', - destination: '/lab/gesture-sandbox', - permanent: true, - }, - { - source: '/lab/map.html', - destination: '/projects/gis-dashboard', - permanent: true, - }, - { - source: '/projects/qgis-plugin/index.html', - destination: '/projects/qgis-plugin', - permanent: true, - }, - { - source: '/projects/automation-systems/index.html', - destination: '/projects/automation-systems', - permanent: true, - }, - { - source: '/projects/gis-dashboard/index.html', - destination: '/projects/gis-dashboard', - permanent: true, - }, - { - source: '/projects/geo-llm/index.html', - destination: '/projects/geo-llm', - permanent: true, - } - ] - } -}; - -export default nextConfig; diff --git a/apps/web/next.config.mjs b/apps/web/next.config.mjs index b108e1a..708ffef 100644 --- a/apps/web/next.config.mjs +++ b/apps/web/next.config.mjs @@ -1,6 +1,39 @@ /** @type {import('next').NextConfig} */ const nextConfig = { - /* config options here */ + async redirects() { + return [ + { + source: '/lab/gesture_sandbox.html', + destination: '/lab/gesture-sandbox', + permanent: true, + }, + { + source: '/lab/map.html', + destination: '/projects/gis-dashboard', + permanent: true, + }, + { + source: '/projects/qgis-plugin/index.html', + destination: '/projects/qgis-plugin', + permanent: true, + }, + { + source: '/projects/automation-systems/index.html', + destination: '/projects/automation-systems', + permanent: true, + }, + { + source: '/projects/gis-dashboard/index.html', + destination: '/projects/gis-dashboard', + permanent: true, + }, + { + source: '/projects/geo-llm/index.html', + destination: '/projects/geo-llm', + permanent: true, + } + ] + } }; export default nextConfig; diff --git a/apps/web/package-lock.json b/apps/web/package-lock.json index 27115b7..77cb21d 100644 --- a/apps/web/package-lock.json +++ b/apps/web/package-lock.json @@ -14,7 +14,7 @@ "@vercel/flags": "^2.6.2", "@vercel/kv": "^1.0.1", "@vercel/speed-insights": "^1.0.12", - "animejs": "^4.4.1", + "animejs": "^3.2.2", "framer-motion": "^12.38.0", "lightweight-charts": "^5.2.0", "lucide-react": "^1.16.0", @@ -2511,14 +2511,10 @@ } }, "node_modules/animejs": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/animejs/-/animejs-4.4.1.tgz", - "integrity": "sha512-XimhJw4vPb6tAd6Zaoa6BaspJ8UteQMKvL7Pvrt6MW/6u2UvJs0TB/LLqR1sigaiYvpVPC3Tokr9emcCMhWFhw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/juliangarnier" - } + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/animejs/-/animejs-3.2.2.tgz", + "integrity": "sha512-Ao95qWLpDPXXM+WrmwcKbl6uNlC5tjnowlaRYtuVDHHoygjtIPfDUoK9NthrlZsQSKjZXlmji2TrBUAVbiH0LQ==", + "license": "MIT" }, "node_modules/ansi-styles": { "version": "4.3.0", diff --git a/apps/web/package.json b/apps/web/package.json index 720ded1..c521702 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,7 +1,6 @@ { "name": "web", "version": "0.1.0", - "type": "module", "private": true, "scripts": { "dev": "next dev", @@ -16,7 +15,7 @@ "@vercel/flags": "^2.6.2", "@vercel/kv": "^1.0.1", "@vercel/speed-insights": "^1.0.12", - "animejs": "^4.4.1", + "animejs": "^3.2.2", "framer-motion": "^12.38.0", "lightweight-charts": "^5.2.0", "lucide-react": "^1.16.0", diff --git a/apps/web/public/assets/css/index.css b/apps/web/public/assets/css/index.css index c7fb338..9d98b50 100644 --- a/apps/web/public/assets/css/index.css +++ b/apps/web/public/assets/css/index.css @@ -1,4 +1,4 @@ -:root { +:root { /* --- COLOR SYSTEM (The 'Enterprise Premium' Palette) --- */ --bg-black: #02040a; --bg-dark: #0a0d17; @@ -839,7 +839,7 @@ body::-webkit-scrollbar { } .dropdown-content a::after { - content: '→'; + content: '→'; opacity: 0; transform: translateX(-10px); transition: all 0.3s var(--ease-apple); @@ -1152,7 +1152,7 @@ body::-webkit-scrollbar { content: ''; position: absolute; inset: 0; - background: url('/noise.svg'); + background: url('https://grainy-gradients.vercel.app/noise.svg'); opacity: 0.03; pointer-events: none; mix-blend-mode: overlay; @@ -1648,7 +1648,7 @@ section { } /* ============================================================ - MASTER BLUEPRINT V6.0 — NEW SECTION STYLES + MASTER BLUEPRINT V6.0 — NEW SECTION STYLES ============================================================ */ /* --- HERO V6 IDENTITY UPGRADE --- */ @@ -2768,7 +2768,7 @@ section { } /* ============================================================ - RESPONSIVE — MASTER BLUEPRINT V6 + RESPONSIVE — MASTER BLUEPRINT V6 ============================================================ */ @media (max-width: 1024px) { .lab-projects-grid { @@ -2961,7 +2961,7 @@ section { } /* ============================================================ - GIS WORKSTATION — ArcGIS Pro / QGIS Inspired Interface + GIS WORKSTATION — ArcGIS Pro / QGIS Inspired Interface ============================================================ */ .gis-mono { @@ -3218,7 +3218,7 @@ section { } .gis-layer-toggle input:checked::after { - content: '✓'; + content: '✓'; position: absolute; top: -1px; left: 1px; font-size: 0.5rem; @@ -3554,7 +3554,7 @@ section { } /* ============================================================ - PRICING — ENTERPRISE COMMERCIAL ENGINE + PRICING — ENTERPRISE COMMERCIAL ENGINE ============================================================ */ .pricing-section { @@ -4736,9 +4736,9 @@ section { .tlv2-card::after { display: none; } } -/* ══════════════════════════════════════════════════════════════ - V2 REDESIGN COMPONENTS — Clean B2B GovTech Aesthetic - ══════════════════════════════════════════════════════════════ */ +/* ══════════════════════════════════════════════════════════════ + V2 REDESIGN COMPONENTS — Clean B2B GovTech Aesthetic + ══════════════════════════════════════════════════════════════ */ /* --- Section Eyebrow (replaces // LABEL_FORMAT) --- */ .section-eyebrow-v2 { @@ -4953,7 +4953,7 @@ section { } /* - * Directional dark veil — covers the left column with a deep navy gradient + * Directional dark veil — covers the left column with a deep navy gradient * that fades to transparent by center. Text becomes perfectly readable * without any visible box or card. */ @@ -4972,7 +4972,7 @@ section { z-index: 1; } -/* Electric accent — subtle cyan bloom top-left */ +/* Electric accent — subtle cyan bloom top-left */ .hero-v2::after { content: ''; position: absolute; @@ -5003,7 +5003,7 @@ section { } } -/* Content column — sits above the veil, no box */ +/* Content column — sits above the veil, no box */ .hero-content { position: relative; z-index: 2; @@ -5014,7 +5014,7 @@ section { display: none; } -/* Heading — rich white-to-blue gradient, sharp & large */ +/* Heading — rich white-to-blue gradient, sharp & large */ .hero-h1 { font-family: 'Syne', var(--font-heading); font-size: clamp(2.6rem, 4.8vw, 4.2rem); @@ -5033,7 +5033,7 @@ section { filter: drop-shadow(0 2px 20px rgba(0, 100, 255, 0.15)); } -/* Body — warm readable slate, not pure grey */ +/* Body — warm readable slate, not pure grey */ .hero-p { font-family: 'Plus Jakarta Sans', var(--font-main); font-size: 1.12rem; @@ -6747,7 +6747,7 @@ footer a:hover { content: ''; position: absolute; inset: 0; - background: url('/noise.svg'); + background: url('https://grainy-gradients.vercel.app/noise.svg'); opacity: 0.04; pointer-events: none; mix-blend-mode: overlay; diff --git a/apps/web/public/noise.svg b/apps/web/public/noise.svg index d3f298d..834d570 100644 --- a/apps/web/public/noise.svg +++ b/apps/web/public/noise.svg @@ -1,10 +1,6 @@ - + - + diff --git a/apps/web/src/app/layout.js b/apps/web/src/app/layout.js index 62ff0d3..f78e34b 100644 --- a/apps/web/src/app/layout.js +++ b/apps/web/src/app/layout.js @@ -28,10 +28,8 @@ export default function RootLayout({ children }) { - + diff --git a/apps/web/src/app/page.js b/apps/web/src/app/page.js index 4a538a7..d6e74a2 100644 --- a/apps/web/src/app/page.js +++ b/apps/web/src/app/page.js @@ -1,24 +1,104 @@ "use client"; import { motion } from "framer-motion"; -import Link from "next/link"; -import dynamic from "next/dynamic"; import Logo from "../components/Logo"; +import ExecutiveSummarySection from "../components/ExecutiveSummarySection"; +import ChallengesSection from "../components/ChallengesSection"; +import ProfessionalProfile from "../components/ProfessionalProfile"; +import TechnicalEcosystem from "../components/TechnicalEcosystem"; +import ImpactMetrics from "../components/ImpactMetrics"; +import SimpleValueSection from "../components/SimpleValueSection"; import ContactSection from "../components/ContactSection"; import FooterSection from "../components/FooterSection"; import TechTicker from "../components/TechTicker"; +import GeoAISection from "../components/GeoAISection"; +import UnifiedCapabilities from "../components/UnifiedCapabilities"; +import SpatialLabSection from "../components/SpatialLabSection"; +import SpatialIntelligenceDashboard from "../components/SpatialIntelligenceDashboard"; +import Link from "next/link"; -const SpatialIntelligenceDashboard = dynamic( - () => import("../components/SpatialIntelligenceDashboard"), - { ssr: false } -); +import ScrambleText from "../components/ScrambleText"; export default function Home() { return ( -
+ <> +
+
+
+
+
+ +
+ {/* Logo Centerpiece */} +
+ +
+ + {/* Main Title */} +
+

+ + Dev + + + Giz + +

+
+ +
+
+ + {/* Subtitle */} +

+ Transformamos datos territoriales complejos en soluciones automáticas y precisas para el sector público y privado. +

+ + {/* Call to Actions */} + +
+
+ +
+ +
+
+ +
+
+ +
+
+ +
{/* Hero Section - Institutional Power */}
-
+ {/* Advanced Engineering Background - Dynamic Scanning */} +
+
+ +
+
+ +
@@ -82,27 +162,33 @@ export default function Home() {
+ {/* Capabilities Section */} + + {/* Strategic Vision - 3 Pillars */}
-
+
-
🏛️
+
🏛️

Gobernanza

Implementación de estándares internacionales para la seguridad jurídica del territorio nacional.

-
⚙️
+
⚙️

Ingeniería

Pipelines de procesamiento masivo desatendido con precisión milimétrica y validación automática.

-
🧠
+
🧠

Inteligencia

Visualización táctica de activos territoriales y simulación de escenarios de impacto fiscal.

+ {/* GeoAI Node */} + + {/* Territorial Control - Interactive Section */}
@@ -136,6 +222,9 @@ export default function Home() {
+ {/* Spatial Innovation Lab */} + + {/* Featured Insights - Link to Journal */}
@@ -172,9 +261,14 @@ export default function Home() {
+
+ +
+
+ +
- -
+ ); } diff --git a/apps/web/src/app/projects/[id]/page.js b/apps/web/src/app/projects/[id]/page.js deleted file mode 100644 index cf2c7d2..0000000 --- a/apps/web/src/app/projects/[id]/page.js +++ /dev/null @@ -1,214 +0,0 @@ -"use client"; -import { useState } from "react"; -import { motion } from "framer-motion"; -import Link from "next/link"; -import { useParams } from "next/navigation"; -import Logo from "../../../components/Logo"; - -// --- PROJECT DEFINITIONS --- - -const PROJECTS_DATA = { - "catastro-valle": { - title: "Catastro Multipropósito: Valle del Cauca", - category: "Gestión Territorial", - tagline: "Soberanía fiscal y seguridad jurídica mediante el estándar LADM-COL.", - image: "https://images.unsplash.com/photo-1497366216548-37526070297c?auto=format&fit=crop&q=80&w=1200", - description: "Este proyecto representa la vanguardia en administración de tierras en Colombia. Implementamos un ecosistema completo basado en la norma ISO 19152 para descentralizar la gestión catastral del departamento, garantizando interoperabilidad con el IGAC y el SNR.", - goals: [ - "Armonización de datos alfanuméricos y geográficos.", - "Cumplimiento 100% de los esquemas INTERLIS (.xtf).", - "Habilitación de trámites ciudadanos en tiempo real." - ], - challenges: "La disparidad de información entre el registro y el catastro fue el mayor bloqueo. La solución fue un motor de conciliación automática de linderos.", - impact: [ - { label: "Área Mapeada", value: "22,140 km2" }, - { label: "Precisión Legal", value: "Grado 1" }, - { label: "Interoperabilidad", value: "VUR / SNR" } - ], - lab: "CADASTRE_VIEWER" - }, - "qgis-plugin": { - title: "LADM-COL QGIS Plugin", - category: "Software de Ingeniería", - tagline: "Validación topológica nativa para gestores territoriales.", - image: "https://images.unsplash.com/photo-1581092160562-40aa08e78837?auto=format&fit=crop&q=80&w=1200", - description: "Herramienta industrial diseñada para la validación instantánea de bases de datos territoriales bajo el estándar LADM-COL. Optimiza el flujo de trabajo eliminando errores manuales en la edición cartográfica.", - goals: [ - "Detección de traslapes y huecos en tiempo real.", - "Sincronización directa con bases de datos PostGIS.", - "Generación de reportes de conformidad técnica automáticos." - ], - challenges: "El procesamiento de grandes volúmenes de datos espaciales en el cliente era lento. Optimizamos el motor usando PyQGIS y algoritmos de poda espacial.", - impact: [ - { label: "Error Humano", value: "-95%" }, - { label: "Velocidad", value: "10x Faster" }, - { label: "Soporte", value: "QGIS 3.x" } - ], - lab: "PLUGIN_SIMULATOR" - }, - "automation-systems": { - title: "Territorial ETL Pipelines", - category: "Infraestructura de Datos", - tagline: "Automatización geoespacial desatendida de alto rendimiento.", - image: "https://images.unsplash.com/photo-1451187580459-43490279c0fa?auto=format&fit=crop&q=80&w=1200", - description: "Sistemas de orquestación de datos para la migración y transformación masiva de archivos GML, GeoJSON y XTF. Diseñado para alta disponibilidad en entornos gubernamentales críticos.", - goals: [ - "Orquestación desatendida mediante motores GDAL.", - "Validación contra modelos INTERLIS oficiales.", - "Trazabilidad completa de cada transformación." - ], - challenges: "La heterogeneidad de los formatos origen impedía una migración limpia. Desarrollamos un traductor universal de esquemas territoriales.", - impact: [ - { label: "Registros/Día", value: "500k+" }, - { label: "Uptime", value: "99.99%" }, - { label: "Seguridad", value: "AES-256" } - ], - lab: "PIPELINE_MONITOR" - }, - "geo-llm": { - title: "Geo-LLM Intelligence", - category: "Inteligencia Artificial", - tagline: "Análisis espacial avanzado mediante lenguaje natural.", - image: "https://images.unsplash.com/photo-1485827404703-89b55fcc595e?auto=format&fit=crop&q=80&w=1200", - description: "Motor de IA que permite interactuar con bases de datos geográficas mediante lenguaje natural. Convierte preguntas complejas en consultas espaciales precisas sobre el territorio.", - goals: [ - "Traducción de lenguaje natural a Spatial SQL.", - "Análisis predictivo de crecimiento urbano.", - "Generación automática de reportes territoriales." - ], - challenges: "La ambigüedad del lenguaje natural en consultas espaciales. Implementamos una capa de validación semántica sobre esquemas PostGIS.", - impact: [ - { label: "Accesibilidad", value: "User-Centric" }, - { label: "Motor", value: "LLM-Hybrid" }, - { label: "Data", value: "Real-Time SQL" } - ], - lab: "AI_CHAT_LAB" - } -}; - -export default function ProjectDetailPage() { - const params = useParams(); - const id = params.id; - const project = PROJECTS_DATA[id]; - - if (!project) { - return ( -
-
-

404 // Proyecto No Encontrado

- Volver al Portfolio -
-
- ); - } - - return ( -
-
-
- -
-
-
- {project.category} - - Engineering Case Study -
-

- {project.title} -

-

- {project.tagline} -

-
- -
- {project.title} -
- -
-
-

Resumen de Entrega

-

{project.description}

-
- -
-
-

Objetivos Estratégicos

-
    - {project.goals.map(goal => ( -
  • - - {goal} -
  • - ))} -
-
-
-

Desafíos Superados

-

{project.challenges}

-
-
- - {/* Dynamic Lab Viewer Based on Project Type */} -
-
-
-
Immersion Lab // Interactive Viewer
-
Módulo de Visualización en Tiempo Real
-
-
- → -
-
-
-
-
- Secure Data Stream: Loading {project.lab}... -
-
-
-
- -
-
- -
- DevGiz Engineering - Territorial Infrastructure Lab -
-
- - Volver al Portfolio de Ingeniería - -
-
- -
-
-
-

- Especificaciones Técnicas -

-
- {project.impact.map(stat => ( -
-
{stat.label}
-
{stat.value}
-
- ))} -
-
- -
-

¿Requiere una solución a medida?

-

Diseñamos arquitecturas de datos espaciales adaptadas a la normativa vigente.

- Consultoría Técnica -
-
-
-
-
-
- ); -} diff --git a/apps/web/src/app/projects/[slug]/page.js b/apps/web/src/app/projects/[slug]/page.js new file mode 100644 index 0000000..d8a8a23 --- /dev/null +++ b/apps/web/src/app/projects/[slug]/page.js @@ -0,0 +1,273 @@ +"use client"; +import { useParams } from "next/navigation"; +import { useEffect, useRef, useState } from "react"; +import Link from "next/link"; +import Logo from "../../../components/Logo"; +import OfficialGISDemo from "../../../components/OfficialGISDemo"; +import RealDataSimulator from "../../../components/RealDataSimulator"; + +const PROJECTS_DATA = { + "qgis-plugin": { + title: "LADM-COL QGIS Plugin", + subtitle: "Validación Topológica Nativa de Siguiente Generación", + status: "STABLE_TOOL", + tag: "PYQGIS_PLUGIN", + description: "Herramienta industrial diseñada para la validación instantánea de bases de datos territoriales bajo el estándar LADM-COL. Optimiza el flujo de trabajo de gestores catastrales eliminando errores manuales.", + features: [ + { title: "Topología Avanzada", desc: "Detección de traslapes y huecos (slivers) en tiempo real." }, + { title: "Sincronización Cloud", desc: "Push directo a bases de datos PostGIS centralizadas." }, + { title: "Reportes Automáticos", desc: "Generación de informes de conformidad técnica en PDF." } + ], + tech: ["PyQGIS", "Python 3.10", "Qt5", "PostGIS"], + realData: "Conectado a IGAC Object Catalog 2024", + demoType: "CONSOLE", + visual: "🔌" + }, + "automation-systems": { + title: "Territorial ETL Pipelines", + subtitle: "Automatización Geoespacial Desatendida", + status: "ACTIVE_PIPELINE", + tag: "AUTOMATION_01", + description: "Sistemas de orquestación de datos para la migración y transformación masiva de archivos GML, GeoJSON y XTF. Diseñado para alta disponibilidad en entornos gubernamentales.", + features: [ + { title: "Orquestación GDAL", desc: "Pipelines de alto rendimiento para miles de registros." }, + { title: "Validación de Esquema", desc: "Check automático contra modelos INTERLIS oficiales." }, + { title: "Logs de Auditoría", desc: "Traceability completa de cada transformación de datos." } + ], + tech: ["Python", "Docker", "GDAL/OGR", "FME"], + realData: "Protocolos ICDE / LADM-COL V3", + demoType: "PIPELINE", + visual: "⚙️" + }, + "gis-dashboard": { + title: "Enterprise GIS Dashboard", + subtitle: "Inteligencia Territorial en Tiempo Real", + status: "LIVE_NODE", + tag: "DASHBOARD_02", + description: "Panel de control ejecutivo para la visualización de indicadores territoriales, densidades prediales y telemetría de activos IoT en una sola interfaz unificada.", + features: [ + { title: "Mapas de Calor", desc: "Análisis dinámico de valorización y densidad urbana." }, + { title: "Filtrado Espacial", desc: "Consultas SQL espaciales directas desde la UI." }, + { title: "Exportación Multi-formato", desc: "Descarga de datasets filtrados en GeoJSON/CSV." } + ], + tech: ["React", "MapLibre GL", "PostGIS", "Node.js"], + realData: "Feeds de Colombia en Mapas (WMS/WFS)", + demoType: "MAP", + visual: "📊" + }, + "geo-llm": { + title: "Geo-LLM Intelligence", + subtitle: "IA Generativa para Análisis Espacial", + status: "R&D KERNEL", + tag: "GEO_LLM_05", + description: "Motor de IA que permite interactuar con bases de datos geográficas mediante lenguaje natural. Convierte preguntas complejas en consultas espaciales precisas.", + features: [ + { title: "Natural Language to SQL", desc: "Traduce texto a consultas PostGIS complejas." }, + { title: "Análisis Predictivo", desc: "Modelado de crecimiento urbano mediante IA." }, + { title: "Insights Automáticos", desc: "Resúmenes técnicos de tendencias territoriales." } + ], + tech: ["LLMs", "Vector DBs", "Spatial SQL", "Python"], + realData: "Base Catastral Pública (Datos Abiertos CO)", + demoType: "CHAT", + visual: "🤖" + } +}; + +export default function ProjectPage() { + const { slug } = useParams(); + const project = PROJECTS_DATA[slug]; + + if (!project) return
Project Not Found
; + + return ( +
+ {/* Background Decor */} +
+
+
+
+ +
+ + ← Volver al Ecosistema + + +
+
+
+ + {project.tag} + +
+ + {project.status} +
+
+ +
+

+ {project.title.split(' ')[0]}
+ + {project.title.split(' ').slice(1).join(' ')} + +

+

{project.subtitle}

+
+ +

+ {project.description} +

+ +
+ {project.tech.map(t => ( + + {t} + + ))} +
+
+ + {/* Dynamic Demo Visualizer */} +
+
+
+ + +
+
Official Dataset Source
+
{project.realData}
+
+
+
+
+ + {/* Features Grid */} +
+ {project.features.map((f, i) => ( +
+
+

{f.title}

+

{f.desc}

+
+ ))} +
+ + {/* Simplified Branding Section */} +
+
+ +
+
+
+ Guía Ejecutiva de Valor +
+

+ ¿Qué significa esto para su organización? +

+
+
+
El Problema Común
+

+ La mayoría de las organizaciones pierden el 40% de su tiempo corrigiendo datos geográficos manualmente o esperando a que sistemas lentos procesen información territorial crítica. +

+
+
+
Nuestra Solución
+

+ Esta tecnología actúa como un auditor digital infalible. En lugar de procesar expedientes uno por uno, nuestro motor lo hace en masa, garantizando que cada metro cuadrado esté correctamente registrado bajo la ley colombiana. +

+
+
+
+
+ +
+
+ ); +} + +function InteractiveDemo({ type, slug }) { + const [logs, setLogs] = useState([]); + const mapRef = useRef(null); + + useEffect(() => { + if (type === "CONSOLE" || type === "PIPELINE") { + const interval = setInterval(() => { + const samples = { + "CONSOLE": ["[CHECK] LADM-COL V3 Topology...", "[ERROR] Overlap detected at Parcel #001", "[FIX] Auto-adjusting geometry...", "[OK] Record validated."], + "PIPELINE": ["[ETL] Ingesting GML file...", "[PARSE] Extracting 500 features...", "[TRANSFORM] Reprojecting to MAGNA-SIRGAS...", "[SUCCESS] Data exported to PostGIS."] + }[type]; + setLogs(prev => [samples[Math.floor(Math.random() * samples.length)], ...prev.slice(0, 8)]); + }, 2000); + return () => clearInterval(interval); + } + + if (type === "MAP") { + // Load dynamic map preview + const link = document.createElement("link"); + link.rel = "stylesheet"; + link.href = "https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"; + document.head.appendChild(link); + + const script = document.createElement("script"); + script.src = "https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"; + script.onload = () => { + if (window.L && mapRef.current) { + const L = window.L; + const map = L.map(mapRef.current).setView([4.6486, -74.0592], 15); + L.tileLayer("https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}").addTo(map); + L.circle([4.6486, -74.0592], { radius: 200, color: '#38BDF8', fillOpacity: 0.2 }).addTo(map); + } + }; + document.head.appendChild(script); + } + }, [type]); + + if (slug === "gis-dashboard") { + return ; + } + + if (slug === "qgis-plugin") { + return ; + } + + if (type === "CONSOLE" || type === "PIPELINE") { + return ( +
+
// {type}_STREAM_ACTIVE
+ {logs.map((log, i) => ( +
+ [{i}] {log} +
+ ))} +
+ ); + } + + if (type === "MAP") { + return
; + } + + if (type === "CHAT") { + return ( +
+
+
👤
+
+ ¿Cuántos predios en Bogotá tienen un área mayor a 500m2? +
+
+
+
🤖
+
+
GENERATING_SPATIAL_SQL...
+ SELECT COUNT(*) FROM predios WHERE st_area(geom) > 500; +
Encontrados 4,215 registros en la base catastral actual.
+
+
+
+ ); + } + + return null; +} diff --git a/apps/web/src/components/ArchitectureSection.jsx b/apps/web/src/components/ArchitectureSection.jsx index 3091102..f7a7609 100644 --- a/apps/web/src/components/ArchitectureSection.jsx +++ b/apps/web/src/components/ArchitectureSection.jsx @@ -1,3 +1,5 @@ +"use client"; + export default function ArchitectureSection() { const nodes = [ { @@ -42,7 +44,7 @@ export default function ArchitectureSection() { return (
- + {/* Header */}
@@ -71,7 +73,7 @@ export default function ArchitectureSection() {
)}
- + {/* Step number */}
STEP_{String(i + 1).padStart(2, "0")} diff --git a/apps/web/src/components/Background.jsx b/apps/web/src/components/Background.jsx index d42e98c..93ba796 100644 --- a/apps/web/src/components/Background.jsx +++ b/apps/web/src/components/Background.jsx @@ -7,19 +7,12 @@ export default function Background() { const gridRef = useRef(null); useEffect(() => { - let ticking = false; const handleMouseMove = (e) => { - if (!ticking) { - requestAnimationFrame(() => { - if (gridRef.current) { - const x = (e.clientX / window.innerWidth) * 100; - const y = (e.clientY / window.innerHeight) * 100; - gridRef.current.style.setProperty("--mouse-x", `${x}%`); - gridRef.current.style.setProperty("--mouse-y", `${y}%`); - } - ticking = false; - }); - ticking = true; + if (gridRef.current) { + const x = (e.clientX / window.innerWidth) * 100; + const y = (e.clientY / window.innerHeight) * 100; + gridRef.current.style.setProperty("--mouse-x", `${x}%`); + gridRef.current.style.setProperty("--mouse-y", `${y}%`); } }; diff --git a/apps/web/src/components/ChallengesSection.jsx b/apps/web/src/components/ChallengesSection.jsx index 7a9e679..d21256a 100644 --- a/apps/web/src/components/ChallengesSection.jsx +++ b/apps/web/src/components/ChallengesSection.jsx @@ -35,23 +35,23 @@ export default function ChallengesSection() { ]; return ( -
+
{/* Background Radar Effect */}
-
+
Status Analysis
-

+

Transformando Desafíos en Activos Digitales

-

+

Las entidades territoriales operan sobre infraestructuras de datos críticas. Identificamos los nudos operativos y los resolvemos mediante ingeniería de precisión.

@@ -60,16 +60,16 @@ export default function ChallengesSection() { {challenges.map((c) => (
-
+
Protocol_{c.num}
-

{c.problem}

+

{c.problem}

{c.impact}

@@ -89,9 +89,9 @@ export default function ChallengesSection() { ))} {/* Call to Action Slot */} -
+
-

¿Su entidad presenta estos nudos?

+

¿Su entidad presenta estos nudos?

Realizamos diagnósticos técnicos profundos para modernizar su infraestructura SIG.

diff --git a/apps/web/src/components/ExecutiveSummarySection.jsx b/apps/web/src/components/ExecutiveSummarySection.jsx index 0ab7779..e795045 100644 --- a/apps/web/src/components/ExecutiveSummarySection.jsx +++ b/apps/web/src/components/ExecutiveSummarySection.jsx @@ -36,41 +36,41 @@ export default function ExecutiveSummarySection() { ]; return ( -
+
{/* Subtle Grid Pattern Overlay */}
- +
- -
+ +
{/* Left: Message */}
- {"//_ESTRATEGIA_Y_MISIÓN"} + //_ESTRATEGIA_Y_M ISIÓN
- +
-

+

Inteligencia Territorial para la Era Digital.

-

+

En DevGiz, transformamos el caos de datos geográficos en activos estratégicos. Diseñamos el cerebro digital de su territorio para una gestión ágil, precisa y 100% auditable.

- +
-
Compliance LADM-COL
-
Alineación total con estándares IGAC.
+
Compliance LADM-COL
+
Alineación total con estándares IGAC.
-
Escalabilidad Cloud
-
Infraestructura lista para el futuro.
+
Escalabilidad Cloud
+
Infraestructura lista para el futuro.
@@ -79,16 +79,16 @@ export default function ExecutiveSummarySection() { {/* Right: Feature Matrix */}
{pillars.map((p, i) => ( -
-
+
+
{p.icon}
-
+
-

{p.title}

+

{p.title}

{p.subtitle}
-

{p.desc}

+

{p.desc}

))} diff --git a/apps/web/src/components/FooterSection.jsx b/apps/web/src/components/FooterSection.jsx index 5556a8f..dc303d2 100644 --- a/apps/web/src/components/FooterSection.jsx +++ b/apps/web/src/components/FooterSection.jsx @@ -1,32 +1,44 @@ "use client"; + +import { useState, useEffect } from "react"; import Link from "next/link"; import Logo from "./Logo"; -import { Globe, Mail, MapPin, ExternalLink } from "lucide-react"; +import { Globe, ExternalLink, Mail } from "lucide-react"; export default function FooterSection() { - const currentYear = new Date().getFullYear(); + const [time, setTime] = useState(""); - const footerLinks = { - empresa: [ - { name: "Nuestro Manifiesto", href: "/about" }, - { name: "Estándares Técnicos", href: "/standards" }, - { name: "Talento de Élite", href: "/careers" }, - ], - ecosistema: [ - { name: "Casos de Ingeniería", href: "/projects" }, - { name: "Engineering Journal", href: "/blog" }, - { name: "Centro de Conocimiento", href: "/faq" }, - ], - legal: [ - { name: "Privacidad de Datos", href: "/privacy" }, - { name: "Términos de Servicio", href: "/terms" }, - { name: "Soberanía Digital", href: "/manifesto" }, - ] - }; + useEffect(() => { + const updateTime = () => { + const now = new Date(); + const options = { timeZone: 'America/Bogota', hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit' }; + setTime(now.toLocaleTimeString('es-CO', options) + " COT"); + }; + updateTime(); + const timer = setInterval(updateTime, 1000); + return () => clearInterval(timer); + }, []); return (
+ + {/* Global Marketing Hook CTA */} +
+
+
+
Enterprise Solutions
+

¿Listo para escalar su Infraestructura Espacial?

+

Únase a los gobiernos y empresas que ya optimizan sus activos territoriales con nuestra tecnología.

+
+ + Solicitar Auditoría Espacial + +
+
{/* Brand Info */} @@ -47,59 +59,39 @@ export default function FooterSection() {
+
- {/* Links Columns */} -
-
-

Firma

-
    - {footerLinks.empresa.map(link => ( -
  • - - {link.name} - -
  • - ))} -
-
-
-

Ecosistema

-
    - {footerLinks.ecosistema.map(link => ( -
  • - - {link.name} - -
  • - ))} -
-
-
-

Oficinas

-
-
- - Sede Principal,
Colombia
-
-
- - contact@devgiz.com -
-
-
+ {/* Legal Info and System Status */} +
+
+ © 2026 ALBERT DANIEL GAVIRIA ZAPATA. TODOS LOS DERECHOS RESERVADOS. + · + LADM-COL V3 CERTIFIED
+ + {/* System Status */} +
+
+ + +
+ DGZ_OS_V6.0 //_NOMINAL
- {/* Bottom Bar */} -
-
- © {currentYear} DevGiz Engineering Lab // All Rights Reserved. + {/* Telemetry / Coordinates */} +
+
+ + {time}
-
- Terms - Privacy + // +
+ + EPSG:4326
+ +
); diff --git a/apps/web/src/components/GeoAISection.jsx b/apps/web/src/components/GeoAISection.jsx index e2d0cfd..03a52f0 100644 --- a/apps/web/src/components/GeoAISection.jsx +++ b/apps/web/src/components/GeoAISection.jsx @@ -1,7 +1,9 @@ +"use client"; + export default function GeoAISection() { return (
- + {/* Background Decor */}
@@ -9,7 +11,7 @@ export default function GeoAISection() {
- + {/* Header */}
@@ -17,30 +19,30 @@ export default function GeoAISection() { // GEOAI_MODULE

- GeoAI Intelligence + Soberanía de Datos con GeoAI

- + {/* Left Column: Text & Steps */}

- Urban Change Detection
con Imagenería Sentinel + Detección de Construcciones
No Autorizadas

- Aplicación de inteligencia artificial geoespacial para detectar cambios de cobertura urbana y rural comparando imágenes satelitales multitemporales. Pipeline completo desde descarga Sentinel hasta exportación GeoJSON. + Implementamos algoritmos de visión artificial sobre imagenería Sentinel-2 para el monitoreo dinámico del territorio, permitiendo identificar crecimientos urbanos informales y optimizar el recaudo fiscal.

{/* Steps */}
{[ - { num: "01", title: "Descarga Imagenería Sentinel-2", desc: "API Copernicus // Bandas espectrales B04, B08, B11 // resolución 10m" }, - { num: "02", title: "Procesamiento con Rasterio + GeoPandas", desc: "Normalización radiométrica // Comparación multitemporal // NumPy arrays" }, - { num: "03", title: "Clasificación con Scikit-learn", desc: "Random Forest // Detección de cambios // Vectorización de polígonos" }, - { num: "04", title: "Exportación GeoJSON → Web GIS", desc: "Visualización en MapLibre GL // Integración PostGIS // API REST" } + { num: "01", title: "Adquisición Multiespectral", desc: "Monitoreo constante vía constelación Sentinel // resolución 10m" }, + { num: "02", title: "Análisis de Cobertura Vegetal (NDVI)", desc: "Identificación de remoción de capa vegetal para nuevas obras" }, + { num: "03", title: "Segmentación con Machine Learning", desc: "Clasificación automática de cambios en el tejido urbano" }, + { num: "04", title: "Alerta de Impacto Catastral", desc: "Notificación automática a sistemas de planeación y hacienda" } ].map((step, i) => (
@@ -70,7 +72,7 @@ export default function GeoAISection() { {/* Right Column: Interactive Visualization */}
- +
[CHANGE_DETECTION_ENGINE] PROCESSING_DEMO @@ -80,10 +82,10 @@ export default function GeoAISection() {
{/* Fake satellite background grid */}
- + {/* Animated Scanner line */}
- + {/* Simulated detected polygons */}
@@ -108,10 +110,10 @@ export default function GeoAISection() { {/* Console Output */}
-
>>> SENTINEL_BAND: B08+B04+B11
-
>>> DATE_COMPARISON: 2023-01-15 vs 2025-01-15
-
>>> CHANGE_PIXELS_DETECTED: RED = URBAN_EXPANSION
-
>>> STABLE_PIXELS: GREEN = NO_CHANGE
+
>>> ENGINE_STATUS: MONITORING_ACTIVE
+
>>> TARGET: URBAN_GROWTH_CONTROL
+
>>> DETECTED: NEW_CONSTRUCTION // ACTION: UPDATE_CADASTRE
+
>>> IMPACT: REVENUE_OPTIMIZATION
diff --git a/apps/web/src/components/ImpactMetrics.jsx b/apps/web/src/components/ImpactMetrics.jsx index 985015f..d56707c 100644 --- a/apps/web/src/components/ImpactMetrics.jsx +++ b/apps/web/src/components/ImpactMetrics.jsx @@ -1,75 +1,19 @@ "use client"; import { useState, useEffect, useRef } from "react"; -import { animate, stagger } from "animejs"; - -const metrics = [ - { target: 50, suffix: "k+", label: "Registros Procesados", sub: "Predios // Catastro", color: "text-emerald-400" }, - { target: -30, suffix: "%", label: "Margen de Error", sub: "QA/QC Automático", color: "text-cyan-400" }, - { target: 115, suffix: "%", label: "Eficiencia Operativa", sub: "ROI Workflow", color: "text-amber-400" } -]; - -const techStack = [ - { - id: "backend", - label: "Backend", - symbol: "B", - color: "text-blue-400", - glow: "shadow-[0_0_20px_rgba(59,130,246,0.3)]", - description: "Motor de procesamiento geoespacial asíncrono.", - tools: [ - { name: "FastAPI", icon: "⚡", benefit: "Latencia mínima en peticiones" }, - { name: "GeoPandas", icon: "🗺️", benefit: "Análisis vectorial de alta precisión" }, - { name: "SQLAlchemy", icon: "🔗", benefit: "ORM robusto para gestión de datos" } - ] - }, - { - id: "frontend", - label: "Frontend", - symbol: "F", - color: "text-emerald-400", - glow: "shadow-[0_0_20px_rgba(52,211,153,0.3)]", - description: "Experiencia de usuario inmersiva y reactiva.", - tools: [ - { name: "Next.js 15", icon: "⚛️", benefit: "Renderizado híbrido ultra-rápido" }, - { name: "Anime.js", icon: "🎬", benefit: "Coreografías visuales de alto nivel" }, - { name: "Tailwind", icon: "🎨", benefit: "Diseño premium altamente adaptable" } - ] - }, - { - id: "database", - label: "Database", - symbol: "D", - color: "text-amber-400", - glow: "shadow-[0_0_20px_rgba(251,191,36,0.3)]", - description: "Almacenamiento elástico con soporte espacial.", - tools: [ - { name: "PostGIS", icon: "📍", benefit: "Consultas espaciales nativas" }, - { name: "Neon DB", icon: "☁️", benefit: "Escalamiento serverless instantáneo" }, - { name: "DuckDB", icon: "🦆", benefit: "Analítica local a velocidad luz" } - ] - }, - { - id: "analytics", - label: "Analytics", - symbol: "A", - color: "text-cyan-400", - glow: "shadow-[0_0_20px_rgba(34,211,238,0.3)]", - description: "Inteligencia territorial y ciencia de datos.", - tools: [ - { name: "PySAL", icon: "📈", benefit: "Estadística espacial avanzada" }, - { name: "Polars", icon: "❄️", benefit: "ETL paralelo de ultra-rendimiento" }, - { name: "LADM-COL", icon: "📜", benefit: "Estandarización bajo norma nacional" } - ] - } -]; - export default function ImpactMetrics() { const [counts, setCounts] = useState([0, 0, 0]); const sectionRef = useRef(null); - const entitiesRef = useRef(null); const [isVisible, setIsVisible] = useState(false); + const metrics = [ + { target: 50, suffix: "k+", label: "Registros Procesados", sub: "Predios // Catastro", color: "text-emerald-400" }, + { target: -30, suffix: "%", label: "Margen de Error", sub: "QA/QC Automático", color: "text-cyan-400" }, + { target: 115, suffix: "%", label: "Eficiencia Operativa", sub: "ROI Workflow", color: "text-amber-400" } + ]; + + const entities = ["IGAC", "LADM-COL", "ANT", "SNR"]; + useEffect(() => { const observer = new IntersectionObserver( ([entry]) => { @@ -116,52 +60,50 @@ export default function ImpactMetrics() { }, 1000 / frames); }); - // Advanced stagger animation for interoperability nodes - if (entitiesRef.current) { - animate(entitiesRef.current.children, { - opacity: [0, 1], - translateY: [30, 0], - scale: [0.9, 1], - duration: 1200, - delay: stagger(150, { start: 500 }), - easing: 'outElastic(1, .6)' - }); - } - return () => intervals.forEach(clearInterval); }, [isVisible]); return ( -
- {/* Decorative background glow */} -
- -
-
+
+
+
- IMPACTO REAL + IMPACTO REAL
-

Resultados
Comprobados

+

Resultados
Comprobados

{metrics.map((m, i) => ( -
-
-
-
+
+
+
{counts[i]}{m.suffix}
-
{m.label}
-
{m.sub}
+
{m.label}
+
{m.sub}
))}
+ {/* Entities bar - high end presentation */} +
+
+ Sistemas interoperables con estándares globales: +
+ {entities.map((ent, i) => ( +
+ {ent} +
+
+ ))} +
+
+
); diff --git a/apps/web/src/components/InfrastructureSection.jsx b/apps/web/src/components/InfrastructureSection.jsx index 55636fe..91ca99c 100644 --- a/apps/web/src/components/InfrastructureSection.jsx +++ b/apps/web/src/components/InfrastructureSection.jsx @@ -1,3 +1,5 @@ +"use client"; + export default function InfrastructureSection() { const stack = [ { @@ -6,7 +8,7 @@ export default function InfrastructureSection() { tooltip: "Edge Computing & Security", logo: ( - + ) }, @@ -27,7 +29,7 @@ export default function InfrastructureSection() { url: "https://neon.tech/", tooltip: "Serverless Postgres / PostGIS", logo: ( - + ) }, { @@ -41,7 +43,7 @@ export default function InfrastructureSection() { return (
- + {/* Header */}
@@ -62,10 +64,10 @@ export default function InfrastructureSection() { {/* Stack Grid */}
{stack.map((item, idx) => ( - @@ -93,7 +95,7 @@ export default function InfrastructureSection() {
{/* Background texture for callout */}
- +
PRO-TIP // ARCHITECTURE diff --git a/apps/web/src/components/InteractiveCarousel.jsx b/apps/web/src/components/InteractiveCarousel.jsx index 0b49b95..ed9fbc4 100644 --- a/apps/web/src/components/InteractiveCarousel.jsx +++ b/apps/web/src/components/InteractiveCarousel.jsx @@ -36,28 +36,28 @@ export default function InteractiveCarousel() { }; return ( -
+
{/* Navigation HUD */} -
-
+
+
-
- Interactive_Labs // v2.0 +
+ Interactive_Labs // v2.0
-

- Ecosistema
Dinámico +

+ Ecosistema Dinámico

-
+
{sections.map((s, i) => (

Spatial Intelligence
Digital Twin

@@ -307,21 +318,52 @@ export default function SpatialIntelligenceDashboard() {

- {/* Performance Stats */} -
-
-
- Polars Engine + {/* Performance / Strategic Stats */} + + {dashboardMode === "TECHNICAL" ? ( + +
+
+ Polars Engine +
+
{polarsSpeed}ms
-
{polarsSpeed}ms
-
-
-
- Latency +
+
+ Latency +
+
0.08ms
-
0.08ms
-
-
+ + ) : ( + +
+
+ Fiscal Impact +
+
+$2.4M USD
+
+
+
+ Compliance +
+
100% LADM
+
+
+ )} +
+
+
+ + {/* Card 3 */} +
+
+ SYS_NODE: PIPELINE_03 +
+ +
+
+

Sovereign Pipelines

+

+ Arquitectura ETL desatendida para ingestión geoespacial masiva, garantizando la integridad de datos a través de nodos GIS distribuidos. +

+
+ {["GDAL/OGR", "ETL", "CI/CD"].map(t => ( + {t} + ))} +
+
+ System Stable +
+
+
+
- {/* Flagship Projects - Super Premium Carousel Implementation */} -
+ {/* Flagship Projects - Carousel Implementation */} +
+ + {/* Async Geometry Validator - Expert Node */} +
+
+
Módulo de Validación Masiva
+

Auditoría Topológica Asíncrona

+

Cargue archivos Shapefile (.zip) para ejecutar procesos de limpieza topológica LADM-COL en nuestro clúster de computación distribuida.

+
+ +
+
-
+
); } @@ -62,119 +163,71 @@ function ProjectCarousel() { tag: "FLAGSHIP_NODE", status: "PRODUCTION STABLE", title: "ConstruMetrix GIS", - desc: "Plataforma de monitoreo urbano para infraestructura a nivel empresarial. Sincronización de telemetría en tiempo real y gemelos digitales 3D.", + desc: "Monitoreo GIS a nivel empresarial para infraestructura urbana moderna. Sincronización de telemetría en tiempo real a través de nodos distribuidos.", img: "/assets/img/logo-construmetrix.svg", link: "https://daga21gz.github.io/ConstruMetrix/", - tech: ["POSTGIS", "PYQGIS", "MAPBOX GL"], - theme: { - text: "text-cyan-400", - from: "from-cyan-400", - bg: "bg-cyan-500", - hoverBorder: "hover:border-cyan-500", - hoverBg: "hover:bg-cyan-500", - hoverText: "hover:text-cyan-300", - via: "via-cyan-500", - shadow: "shadow-[0_0_15px_#06b6d4]", - colorHex: "#22d3ee" - }, - glow: "shadow-[0_0_80px_rgba(6,182,212,0.3)]", - border: "border-cyan-500/50" - }, - { - id: "PROJ-EVA-01", - tag: "AI_CORE_SYSTEM", - status: "STABLE_PRODUCTION", - title: "E.V.A. Framework", - desc: "Engineering Virtual Assistant. Agente cognitivo especializado en automatización de ingeniería, soporte técnico avanzado y generación de insights.", - img: null, - icon: "🧠", - link: "https://dgz-engineering-lab.github.io/E.V.A/", - tech: ["AI_AGENT", "LLM CORE", "NODE.JS"], - theme: { - text: "text-indigo-400", - from: "from-indigo-400", - bg: "bg-indigo-500", - hoverBorder: "hover:border-indigo-500", - hoverBg: "hover:bg-indigo-500", - hoverText: "hover:text-indigo-300", - via: "via-indigo-500", - shadow: "shadow-[0_0_15px_#6366f1]", - colorHex: "#818cf8" - }, - glow: "shadow-[0_0_80px_rgba(99,102,241,0.3)]", - border: "border-indigo-500/50" + tech: ["POSTGIS", "PYQGIS", "REST_API"], + accent: "cyan" }, { id: "PROJ-GLLM-05", tag: "GEO_LLM_05", status: "R&D KERNEL", title: "Geo-LLM Intelligence", - desc: "Motor de procesamiento natural que traduce consultas humanas a Spatial SQL, ejecutando análisis territoriales complejos de forma autónoma.", + desc: "Agente de IA que traduce lenguaje natural a Spatial SQL y genera informes catastrales estadísticos en tiempo real.", img: null, icon: "🤖", link: "/projects/geo-llm", - tech: ["LLM", "POSTGIS AI", "VECTOR DB"], - theme: { - text: "text-amber-400", - from: "from-amber-400", - bg: "bg-amber-500", - hoverBorder: "hover:border-amber-500", - hoverBg: "hover:bg-amber-500", - hoverText: "hover:text-amber-300", - via: "via-amber-500", - shadow: "shadow-[0_0_15px_#f59e0b]", - colorHex: "#fbbf24" - }, - glow: "shadow-[0_0_80px_rgba(245,158,11,0.3)]", - border: "border-amber-500/50" + tech: ["LLM", "PostGIS AI", "GeoJSON"], + accent: "amber" }, { id: "PROJ-DASH-02", tag: "DASHBOARD_02", status: "LIVE_NODE", title: "Enterprise GIS Dashboard", - desc: "Interfaz interactiva conectada a PostGIS para análisis territorial, telemetría IoT y tableros de control estadístico en tiempo real.", + desc: "Interfaz interactiva conectada a PostGIS para análisis territorial y telemetría en tiempo real.", img: null, icon: "📊", link: "/projects/gis-dashboard", - tech: ["REACT 19", "POSTGIS", "MAPLIBRE"], - theme: { - text: "text-blue-400", - from: "from-blue-400", - bg: "bg-blue-500", - hoverBorder: "hover:border-blue-500", - hoverBg: "hover:bg-blue-500", - hoverText: "hover:text-blue-300", - via: "via-blue-500", - shadow: "shadow-[0_0_15px_#3b82f6]", - colorHex: "#60a5fa" - }, - glow: "shadow-[0_0_80px_rgba(59,130,246,0.3)]", - border: "border-blue-500/50" + tech: ["React", "PostGIS", "MapLibre"], + accent: "cyan" + }, + { + id: "PROJ-AUTO-01", + tag: "AUTOMATION_01", + status: "ACTIVE_PIPELINE", + title: "Territorial ETL Pipelines", + desc: "Automatización desatendida de transformaciones de datos geográficos para evitar procesos manuales lentos.", + img: null, + icon: "⚙️", + link: "/projects/automation-systems", + tech: ["Python", "FME", "GDAL"], + accent: "blue" }, { id: "PROJ-QGIS-03", tag: "PYQGIS_PLUGIN", status: "STABLE_TOOL", title: "LADM-COL QGIS Plugin", - desc: "Suite de herramientas nativas para QGIS diseñadas para la validación topológica y consistencia del modelo LADM-COL en entornos productivos.", + desc: "Herramientas nativas en la UI de QGIS para validación topológica instantánea de bases de datos territoriales.", img: null, icon: "🔌", link: "/projects/qgis-plugin", - tech: ["PYQGIS", "LADM-COL", "PYTHON"], - theme: { - text: "text-emerald-400", - from: "from-emerald-400", - bg: "bg-emerald-500", - hoverBorder: "hover:border-emerald-500", - hoverBg: "hover:bg-emerald-500", - hoverText: "hover:text-emerald-300", - via: "via-emerald-500", - shadow: "shadow-[0_0_15px_#10b981]", - colorHex: "#34d399" - }, - glow: "shadow-[0_0_80px_rgba(16,185,129,0.3)]", - border: "border-emerald-500/50" + tech: ["PyQGIS", "LADM-COL", "Python"], + accent: "purple" + }, + { + id: "PROJ-EVA-01", + tag: "AI_ASSISTANT_NODE", + status: "STABLE_PRODUCTION", + title: "E.V.A. Framework", + desc: "Engineering Virtual Assistant. Framework avanzado de IA para la automatización de procesos de ingeniería y soporte técnico especializado.", + img: null, + icon: "🧠", + link: "https://dgz-engineering-lab.github.io/E.V.A/", + tech: ["AI_AGENT", "AUTOMATION", "NODE.JS"], + accent: "purple" } ]; @@ -185,124 +238,107 @@ function ProjectCarousel() { return (
- - {/* Carousel Navigation Header */} -
-
-

- Ecosistema de Soluciones -

-

SELECCIONA UN NODO PARA INICIAR LA SECUENCIA

+
+
+
+
+ Portfolio Exhibit +
+

Proyectos Destacados

{/* Carousel Controls */} -
-
+
+
{projects.map((_, i) => (
- -
- {/* Main Cinematic Showcase Card */} -
- - {/* Dynamic Background Glow matching active project color */} -
+ {/* Active Project Card */} +
+
-
- - {/* Top/Left Visual Area */} -
- {/* Grid Pattern */} -
- - {/* Scanning Line */} -
+
-
+ {/* Visual Side */} +
+
+ +
{activeProject.img ? ( -
- {activeProject.title} -
+ {activeProject.title} ) : ( -
+
{activeProject.icon}
)}
- - {/* Overlay Gradient for visual depth */} -
+ + {/* Scanning Line Effect */} +
- {/* Bottom/Right Information Area */} -
- - {/* Tags and Status */} -
- - {activeProject.tag} - -
- - {activeProject.status} + {/* Info Side */} +
+
+ {activeProject.tag} +
+ + {activeProject.status}
- {/* Title & Description */} -
-

+
+

{activeProject.title}

-

+

{activeProject.desc}

- {/* Tech Stack Pills */} -
+
{activeProject.tech.map((t, i) => ( - + {t} ))}
- {/* Call to Action */} -
-

+
); } diff --git a/apps/web/src/components/TechMatrixSection.jsx b/apps/web/src/components/TechMatrixSection.jsx index 355710e..41f2428 100644 --- a/apps/web/src/components/TechMatrixSection.jsx +++ b/apps/web/src/components/TechMatrixSection.jsx @@ -1,3 +1,5 @@ +"use client"; + export default function TechMatrixSection() { const matrixData = [ { @@ -52,20 +54,20 @@ export default function TechMatrixSection() {
{matrixData.map((row, idx) => ( -
{/* Animated left border on hover */}
- +
{row.icon}

- {row.id} + {row.id} ACTIVE

@@ -75,8 +77,8 @@ export default function TechMatrixSection() {

{row.tags.map((tag, tIdx) => ( - {tag} diff --git a/apps/web/src/components/TechnicalEcosystem.jsx b/apps/web/src/components/TechnicalEcosystem.jsx index 78e58d9..c0b2379 100644 --- a/apps/web/src/components/TechnicalEcosystem.jsx +++ b/apps/web/src/components/TechnicalEcosystem.jsx @@ -35,14 +35,14 @@ export default function TechnicalEcosystem() { ]; return ( -
+
{/* Background Decor */}
-
+
@@ -50,20 +50,20 @@ export default function TechnicalEcosystem() {
Enterprise Ecosystem
-

Infraestructura
Alta Disponibilidad

+

Infraestructura
Alta Disponibilidad

-

+

Nuestra matriz tecnológica está diseñada bajo principios de resiliencia extrema. Cada nodo de nuestro ecosistema garantiza la integridad y velocidad de sus datos territoriales.

-
99.9%
+
99.9%
Uptime Garantizado
-
<200ms
+
<200ms
Latencia Global
@@ -71,13 +71,13 @@ export default function TechnicalEcosystem() {
{stack.map((item, i) => ( -
-
+
+
{item.icon}
-
{item.name}
+
{item.name}
{item.type}
diff --git a/apps/web/src/components/TimelineSection.jsx b/apps/web/src/components/TimelineSection.jsx index 24f031b..210fad4 100644 --- a/apps/web/src/components/TimelineSection.jsx +++ b/apps/web/src/components/TimelineSection.jsx @@ -1,3 +1,5 @@ +"use client"; + export default function TimelineSection() { const experiences = [ { @@ -52,7 +54,7 @@ export default function TimelineSection() { return (
- + {/* Background decor */}
@@ -60,7 +62,7 @@ export default function TimelineSection() {
- + {/* Left: Sticky header */}
@@ -82,27 +84,25 @@ export default function TimelineSection() {
{experiences.map((exp, i) => (
- + {/* Timeline dot */} -
+ }`}>
-
- + }`}> +
{exp.period}

{exp.role}

{exp.company}

{exp.desc}

- +
{exp.tags.map((tag, j) => ( diff --git a/apps/web/src/components/UnifiedCapabilities.jsx b/apps/web/src/components/UnifiedCapabilities.jsx index d2914e7..d00da69 100644 --- a/apps/web/src/components/UnifiedCapabilities.jsx +++ b/apps/web/src/components/UnifiedCapabilities.jsx @@ -1,11 +1,10 @@ "use client"; - import { useState, useEffect, useRef } from "react"; import Logo from "./Logo"; import RealtimeDataStream from "./RealtimeDataStream"; -import VurQuery from "./VurQuery"; -import { animate } from "animejs"; +import anime from "animejs"; +// ... existing SERVICES ... const SERVICES = [ { id: "svc-01", @@ -33,207 +32,155 @@ const SERVICES = [ metrics: ["Real-time Sync", "FastAPI Backend"], tags: ["DevOps", "Python", "Spatial Data"], color: "blue" - }, - { - id: "svc-04", - title: "Auditoría Digital VUR/SNR", - desc: "Consulta y validación jurídica en tiempo real directamente desde la base de datos de la SNR (VUR). Garantía de certeza física y jurídica.", - icon: "⚖️", - metrics: ["SNR Live Sync", "99.9% Reliability"], - tags: ["VUR", "SNR", "Legal Tech"], - color: "red" } ]; export default function UnifiedCapabilities() { const [activeTab, setActiveTab] = useState(0); - const [mounted, setMounted] = useState(false); const terminalRef = useRef(null); useEffect(() => { - setMounted(true); - }, []); - - useEffect(() => { - if (mounted && terminalRef.current) { - animate(terminalRef.current, { + if (terminalRef.current) { + anime({ + targets: terminalRef.current, opacity: [0, 1], translateX: [50, 0], duration: 1200, - easing: 'outExpo', - delay: 100 + easing: 'easeOutExpo', + delay: 300 }); } - }, [activeTab, mounted]); + }, [activeTab]); return ( -
- {/* Premium Background Decor */} -
-
+
+ {/* Background Decor */} +
-
- {/* Header Section */} -
+
+ {/* Header */} +
-
- - Soberanía Territorial Digital - +
+ Misión Crítica
-

- Inteligencia
- Multiproposito +

+ Ingeniería
+ Multiproposito

-
-

- Desplegamos infraestructuras de datos espaciales que cumplen con los más altos estándares nacionales e internacionales, garantizando precisión y cumplimiento legal absoluto. -

-
+

+ Desplegamos infraestructuras de datos espaciales que cumplen con los más altos estándares nacionales e internacionales. +

- {/* Content Matrix Grid */} -
+ {/* Content Matrix */} +
- {/* Navigation Pillar (Left) */} -
+ {/* Navigation Pillar */} +
{SERVICES.map((svc, i) => ( ))}
- {/* Visualization Terminal (Right) */} -
-
+ {/* Visualization Terminal */} +
+
{/* Terminal Header */} -
+
-
-
-
+
+
+
-
- RUNTIME: {SERVICES[activeTab].id.toUpperCase()} - -
- - EXECUTION_NOMINAL -
+
+ RUNTIME: {SERVICES[activeTab].id.toUpperCase()} + + ● EXECUTION_NOMINAL
- {/* Terminal Content Body */} -
- {/* Dynamic Background Visualizer */} -
- {activeTab === 2 ? ( -
- -
- ) : activeTab === 3 ? ( -
- ) : ( -
- -
- )} -
- - {/* Main Content Info / Component Rendering */} - {activeTab === 3 ? ( -
- -
- ) : ( -
-
-

- {SERVICES[activeTab].title} -

-

- {SERVICES[activeTab].desc} -

+ {/* Terminal Content */} +
+ {/* Background Visualizer Component */} + {activeTab === 2 ? ( +
+
- - {/* Metrics Grid */} -
- {SERVICES[activeTab].metrics.map((m, i) => ( -
-
Primary_Metric_0{i+1}
-
{m}
-
- ))} + ) : ( +
+
-
)} - {/* Footer Tags (Hide when VurQuery is active for more space) */} - {activeTab !== 3 && ( -
- {SERVICES[activeTab].tags.map(t => ( - - {t} - - ))} -
- )} -
+
+
+

+ {SERVICES[activeTab].title} +

+

+ {SERVICES[activeTab].desc} +

+
- {/* Side HUD Monitor (Desktop Only) */} -
-
-
- - STDOUT_STREAM +
+ {SERVICES[activeTab].metrics.map((m, i) => ( +
+
Primary_Metric_0{i+1}
+
{m}
+
+ ))}
- v2.4.1
-
- {mounted ? ( - <> -
[{new Date().toLocaleTimeString()}] [SYS] INIT_{SERVICES[activeTab].id.toUpperCase()}
-
[{new Date().toLocaleTimeString()}] [LOG] ALLOCATING_RESOURCES...
- {activeTab === 3 &&
[{new Date().toLocaleTimeString()}] [AUTH] VUR_USER: CLAUDIAC.GOMEZ
} -
[{new Date().toLocaleTimeString()}] [LOG] SYNC_LADM_V3_COL
-
[{new Date().toLocaleTimeString()}] [OK] READY
- - ) : ( -
[--:--:--] [SYS] INITIALIZING_TERMINAL...
- )} -
_
+ +
+ {SERVICES[activeTab].tags.map(t => ( + + {t} + + ))} +
+
+ + {/* Side HUD (Desktop Only) */} +
+
+ + STDOUT_STREAM +
+
+
[SYS] INIT_{SERVICES[activeTab].id.toUpperCase()}
+
[LOG] MAPPING_COORDS...
+
[LOG] SYNC_LADM_V3_COL
+
_
diff --git a/assets/css/cv.css b/assets/css/cv.css deleted file mode 100644 index 37557fb..0000000 --- a/assets/css/cv.css +++ /dev/null @@ -1,557 +0,0 @@ -/* --- ELITE NEURAL CV INTERFACE (V5.2 Sovereign) --- */ - -:root { - --cv-bg: rgba(2, 3, 5, 0.98); - --cv-accent: #00e5ff; - --cv-accent-gold: #ffb400; - --cv-glass: rgba(255, 255, 255, 0.03); - --cv-border: rgba(255, 255, 255, 0.08); - --cv-card-bg: linear-gradient(135deg, rgba(255, 255, 255, 0.03), rgba(255, 255, 255, 0.01)); - --status-success: #4ade80; -} - -/* --- CAPABILITIES SECTION (Neural HUD) --- */ -.capabilities-grid { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 2rem; - margin-top: 4rem; -} - -.capability-card { - background: var(--bg-surface); - border: 1px solid var(--border-glass); - padding: 3rem; - border-radius: 40px; - position: relative; - overflow: hidden; - transition: all 0.5s cubic-bezier(0.16, 1, 0.3, 1); -} - -.capability-card:hover { - border-color: var(--accent-electric); - transform: translateY(-10px); - box-shadow: 0 20px 40px rgba(0, 0, 0, 0.5), 0 0 20px rgba(0, 229, 255, 0.1); -} - -.capability-icon { - font-size: 2.5rem; - margin-bottom: 2rem; - color: var(--accent-electric); -} - -.capability-stat { - font-family: var(--font-mono); - font-size: 2.5rem; - font-weight: 900; - color: #fff; - margin: 1.5rem 0; -} - -.capability-tags { - display: flex; - flex-wrap: wrap; - gap: 0.5rem; - margin-top: 1.5rem; -} - -.v-check { - color: var(--status-success); - margin-right: 10px; -} - -.recognition-node { - display: flex; - align-items: center; - gap: 1rem; - padding: 1rem; - background: rgba(255, 255, 255, 0.02); - border: 1px solid var(--cv-border); - border-radius: 15px; - margin-bottom: 1rem; - transition: all 0.3s; -} - -.recognition-node:hover { - background: rgba(255, 255, 255, 0.05); - border-color: var(--cv-accent-gold); -} - -.recognition-icon { - font-size: 1.5rem; -} - -.recognition-info { - font-family: var(--font-mono); -} - -.recognition-title { - font-size: 0.65rem; - color: #fff; - font-weight: 800; -} - -.recognition-date { - font-size: 0.5rem; - color: var(--cv-accent-gold); -} - -.cv-overlay { - position: fixed; - inset: 0; - background: var(--cv-bg); - backdrop-filter: blur(50px) saturate(180%); - z-index: 20000; - display: none; - opacity: 0; - transition: all 0.8s cubic-bezier(0.16, 1, 0.3, 1); - padding: 2vh 5%; - overflow-y: auto; -} - -.cv-overlay.active { - display: block; - opacity: 1; -} - -.cv-container { - max-width: 1600px; - margin: 0 auto; - display: grid; - grid-template-columns: repeat(4, 1fr); - grid-auto-rows: minmax(180px, auto); - gap: 1.5rem; - padding: 60px 0 120px; -} - -.cv-card { - background: rgba(15, 20, 30, 0.4); - border: 1px solid rgba(255, 255, 255, 0.08); - border-radius: 32px; - padding: 2.5rem; - position: relative; - overflow: hidden; - -webkit-backdrop-filter: blur(25px) saturate(180%); - backdrop-filter: blur(25px) saturate(180%); - transition: all 0.6s cubic-bezier(0.16, 1, 0.3, 1); - box-shadow: - 0 20px 50px rgba(0, 0, 0, 0.4), - inset 0 0 0 1px rgba(255, 255, 255, 0.03); -} - -.cv-card:hover { - border-color: rgba(0, 229, 255, 0.4); - background: rgba(255, 255, 255, 0.05); - transform: translateY(-8px) scale(1.02); - box-shadow: - 0 30px 60px rgba(0, 0, 0, 0.6), - 0 0 20px rgba(0, 229, 255, 0.1); -} - -.cv-card::before { - content: ''; - position: absolute; - top: -50%; - left: -50%; - width: 200%; - height: 200%; - background: radial-gradient(circle at center, rgba(0, 229, 255, 0.03), transparent 70%); - opacity: 0; - transition: opacity 0.5s; - pointer-events: none; -} - -.cv-card:hover::before { - opacity: 1; -} - -.card-label { - font-family: var(--font-mono); - font-size: 0.6rem; - color: var(--cv-accent); - text-transform: uppercase; - letter-spacing: 0.3em; - margin-bottom: 2rem; - display: flex; - align-items: center; - gap: 0.8rem; - opacity: 0.6; -} - -.card-label::before { - content: ''; - width: 4px; - height: 4px; - background: currentColor; - border-radius: 50%; - box-shadow: 0 0 10px currentColor; -} - -/* Specific Card Layouts */ -.cv-profile { - grid-column: span 1; - grid-row: span 4; -} - -.cv-skills-master { - grid-column: span 2; - grid-row: span 2; -} - -.cv-exp-primary { - grid-column: span 2; - grid-row: span 2; -} - -.cv-polyglot { - grid-column: span 1; - grid-row: span 1; -} - -.cv-metrics-hero { - grid-column: span 1; - grid-row: span 1; -} - -.cv-academic { - grid-column: span 1; - grid-row: span 2; -} - -.cv-credentials { - grid-column: span 1; - grid-row: span 2; -} - -.cv-experience-log { - grid-column: span 2; - grid-row: span 2; -} - -.cv-future-nodes { - grid-column: span 1; - grid-row: span 1; -} - -.profile-image-container { - width: 160px; - height: 160px; - margin: 0 auto 2.5rem; - position: relative; - border-radius: 50%; - border: 1px solid var(--cv-accent); - display: flex; - align-items: center; - justify-content: center; -} - -.profile-image-container svg { - filter: drop-shadow(0 0 20px rgba(0, 229, 255, 0.4)); -} - -.dna-label { - display: flex; - justify-content: space-between; - font-family: var(--font-mono); - font-size: 0.7rem; - color: var(--text-secondary); - margin-bottom: 0.8rem; -} - -.dna-bar-bg { - height: 4px; - background: rgba(255, 255, 255, 0.05); - border-radius: 2px; - overflow: hidden; -} - -.dna-bar-fill { - height: 100%; - background: linear-gradient(90deg, var(--cv-accent), #7000ff); - box-shadow: 0 0 15px rgba(0, 229, 255, 0.5); -} - -.metric-value { - font-size: 3.5rem; - font-weight: 900; - letter-spacing: -0.05em; - background: linear-gradient(180deg, #fff, var(--cv-accent)); - -webkit-background-clip: text; - background-clip: text; - -webkit-text-fill-color: transparent; - margin-bottom: 0.5rem; -} - -.history-item { - padding-left: 2rem; - border-left: 1px solid rgba(255, 255, 255, 0.1); - position: relative; - margin-bottom: 2.5rem; -} - -.history-item::after { - content: ''; - position: absolute; - left: -5px; - top: 5px; - width: 9px; - height: 9px; - background: var(--cv-accent); - border-radius: 50%; - box-shadow: 0 0 15px var(--cv-accent); -} - -.close-interface { - position: fixed; - top: 2rem; - right: 3rem; - background: rgba(255, 255, 255, 0.05); - border: 1px solid var(--cv-border); - backdrop-filter: blur(20px); - color: #fff; - padding: 0.8rem 2rem; - border-radius: 100px; - font-family: var(--font-mono); - font-size: 0.7rem; - text-transform: uppercase; - letter-spacing: 0.3em; - cursor: pointer; - z-index: 21000; - transition: all 0.3s; -} - -.close-interface:hover { - background: #fff; - color: #000; - transform: translateY(-2px); - box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5); -} - -@media (max-width: 1400px) { - .cv-container { - grid-template-columns: repeat(3, 1fr); - } -} - -@media (max-width: 1100px) { - .cv-container { - grid-template-columns: repeat(2, 1fr); - } -} - -@media (max-width: 768px) { - .cv-container { - grid-template-columns: 1fr; - padding-top: 100px; - } - - .cv-profile, - .cv-skills-master, - .cv-exp-primary, - .cv-experience-log { - grid-column: span 1; - } -} - -/* --- INTERACTIVE TIMELINE (Neural Evolution) --- */ -.timeline-wrapper { - position: relative; - padding: 60px 0; - margin-top: 4rem; -} - -.timeline-line { - position: absolute; - top: 50%; - left: 0; - width: 100%; - height: 1px; - background: linear-gradient(90deg, transparent, var(--cv-border), var(--cv-accent), var(--cv-border), transparent); - z-index: 1; -} - -.timeline-items { - display: flex; - justify-content: space-between; - position: relative; - z-index: 2; -} - -.timeline-node { - display: flex; - flex-direction: column; - align-items: center; - cursor: pointer; - transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1); - position: relative; -} - -.node-dot { - width: 12px; - height: 12px; - background: var(--cv-bg); - border: 2px solid var(--cv-border); - border-radius: 50%; - margin-bottom: 1.5rem; - transition: all 0.4s; - box-shadow: 0 0 0 rgba(0, 229, 255, 0); -} - -.timeline-node:hover .node-dot, -.timeline-node.active .node-dot { - background: var(--cv-accent); - border-color: #fff; - box-shadow: 0 0 20px var(--cv-accent); - transform: scale(1.5); -} - -.node-year { - font-family: var(--font-mono); - font-size: 0.65rem; - color: var(--text-tertiary); - text-transform: uppercase; - letter-spacing: 0.1em; -} - -.timeline-node.active .node-year { - color: var(--cv-accent); - font-weight: 800; -} - -.timeline-content-display { - margin-top: 5rem; - padding: 3rem; - background: var(--cv-card-bg); - border: 1px solid var(--cv-border); - border-radius: 40px; - backdrop-filter: blur(20px); - min-height: 200px; - display: flex; - align-items: center; - justify-content: center; - text-align: center; - animation: fadeIn 0.5s ease-out; -} - -.timeline-text h3 { - font-size: 2rem; - margin-bottom: 0.5rem; - background: linear-gradient(to right, #fff, var(--cv-accent)); - -webkit-background-clip: text; - background-clip: text; - -webkit-text-fill-color: transparent; -} - -.timeline-text p#timeline-subtitle { - font-family: var(--font-mono); - color: var(--cv-accent-gold); - font-size: 0.8rem; - margin-bottom: 1.5rem; - letter-spacing: 0.1em; -} - -.timeline-text p#timeline-description { - color: var(--text-secondary); - line-height: 1.8; - max-width: 800px; - margin: 0 auto; -} - -@keyframes fadeIn { - from { - opacity: 0; - transform: translateY(10px); - } - - to { - opacity: 1; - transform: translateY(0); - } -} - -@media (max-width: 768px) { - .timeline-items { - flex-direction: column; - gap: 3rem; - align-items: flex-start; - padding-left: 30px; - } - - .timeline-line { - left: 35px; - top: 0; - width: 1px; - height: 100%; - background: linear-gradient(180deg, transparent, var(--cv-accent), transparent); - } - - .timeline-node { - flex-direction: row; - gap: 1.5rem; - } - - .node-dot { - margin-bottom: 0; - } -} - -/* --- PROFILE SKILL NODES --- */ -.cv-skill-node { - display: flex; - align-items: center; - gap: 0.8rem; - font-family: var(--font-mono); - font-size: 0.75rem; - font-weight: 600; - margin-bottom: 0.8rem; - transition: all 0.3s ease; -} - -.cv-skill-node .v-check { - font-size: 0.9rem; -} - -.cv-skill-node.success { - color: var(--status-success); -} - -.cv-skill-node.secondary { - color: var(--text-secondary); -} - -/* --- DOWNLOAD BUTTON --- */ -.cv-download-btn { - display: block; - margin-top: 1.5rem; - background: rgba(0, 229, 255, 0.05); - border: 1px solid var(--accent-electric); - color: var(--accent-electric); - text-align: center; - padding: 0.8rem; - font-size: 0.75rem; - font-weight: 800; - font-family: var(--font-mono); - text-decoration: none; - border-radius: 6px; - transition: all 0.3s; - width: 100%; - box-sizing: border-box; - text-transform: uppercase; -} - -.cv-download-btn:hover { - background: rgba(0, 229, 255, 0.1); - box-shadow: 0 0 20px rgba(0, 229, 255, 0.2); - transform: translateY(-2px); -} -.cv-skills-grid-v2 { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 2rem; -} - -@media (max-width: 768px) { - .cv-skills-grid-v2 { - grid-template-columns: 1fr; - } -} diff --git a/assets/css/index.css b/assets/css/index.css deleted file mode 100644 index 9d98b50..0000000 --- a/assets/css/index.css +++ /dev/null @@ -1,7995 +0,0 @@ -:root { - /* --- COLOR SYSTEM (The 'Enterprise Premium' Palette) --- */ - --bg-black: #02040a; - --bg-dark: #0a0d17; - --bg-surface: #111827; - --accent-electric: #00d2ff; - --accent-enterprise: #3b82f6; - --accent-gold: #fbbf24; - --text-primary: #f8fafc; - --text-secondary: #94a3b8; - --text-tertiary: #64748b; - --border-glass: rgba(255, 255, 255, 0.05); - --glass-blur: blur(25px); - - /* --- STATUS COLORS --- */ - --status-ok: #10b981; - --status-err: #ef4444; - --status-warn: #f59e0b; - - /* --- TYPOGRAPHY (Apple/Tesla Standard) --- */ - --font-main: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; - --font-mono: 'JetBrains Mono', monospace; - - /* --- SPACING & TRANSITIONS --- */ - --section-gap: 160px; - --ease-apple: cubic-bezier(0.4, 0, 0.2, 1); - --ease-spring: cubic-bezier(0.175, 0.885, 0.32, 1.275); /* Springy feel for hovers */ - --transition-slow: all 0.8s var(--ease-apple); - --transition-fast: all 0.4s var(--ease-apple); - - /* --- GLASS & DEPTH (Sovereign Quality) --- */ - --glass-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.8); - --glass-border: 1px solid rgba(255, 255, 255, 0.1); - --glass-highlight: inset 0 1px 1px rgba(255, 255, 255, 0.05); -} - -* { - margin: 0; - padding: 0; - box-sizing: border-box; - -webkit-font-smoothing: antialiased; -} - -/* --- ENTERPRISE BACKGROUND SYSTEM --- */ -.enterprise-bg { - position: fixed; - inset: 0; - z-index: -1; - background-color: var(--bg-black); - overflow: hidden; -} - -.enterprise-bg::before { - content: ''; - position: absolute; - inset: -50%; - background: - radial-gradient(circle at 20% 30%, rgba(0, 229, 255, 0.15) 0%, transparent 40%), - radial-gradient(circle at 80% 70%, rgba(139, 92, 246, 0.1) 0%, transparent 40%), - radial-gradient(circle at 50% 50%, rgba(2, 4, 10, 1) 0%, transparent 100%); - animation: devops-morph 15s infinite alternate ease-in-out; - pointer-events: none; -} - -@keyframes devops-morph { - 0% { transform: translate(0, 0) rotate(0deg) scale(1); } - 100% { transform: translate(3%, 3%) rotate(2deg) scale(1.05); } -} - -.floating-nodes { - position: absolute; - inset: 0; - pointer-events: none; -} - -.node { - position: absolute; - width: 2px; - height: 2px; - background: var(--accent-electric); - border-radius: 50%; - filter: blur(1px); - box-shadow: 0 0 10px var(--accent-electric); - opacity: 0.3; - animation: float-node 15s infinite linear; -} - -@keyframes float-node { - 0% { transform: translateY(100vh) translateX(0); opacity: 0; } - 10% { opacity: 0.4; } - 90% { opacity: 0.4; } - 100% { transform: translateY(-10vh) translateX(50px); opacity: 0; } -} - - -#topo-canvas { - position: absolute; - inset: 0; - width: 100%; - height: 100%; - pointer-events: none; - opacity: 0.9; -} - -/* --- PIPELINE DEPLOYMENT SCANLINE --- */ -.scanline { - position: absolute; - width: 100%; - height: 150px; - background: linear-gradient(to bottom, transparent, rgba(0, 229, 255, 0.08), rgba(0, 229, 255, 0.15), transparent); - top: -150px; - left: 0; - pointer-events: none; - z-index: 2; - animation: pipeline-scan 6s cubic-bezier(0.4, 0, 0.2, 1) infinite; -} - -@keyframes pipeline-scan { - 0% { top: -150px; opacity: 0; } - 10% { opacity: 1; } - 90% { opacity: 1; } - 100% { top: 100%; opacity: 0; } -} - -.noise-texture { - position: absolute; - inset: 0; - background-image: url('data:image/svg+xml,%3Csvg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg"%3E%3Cfilter id="noiseFilter"%3E%3CfeTurbulence type="fractalNoise" baseFrequency="0.65" numOctaves="3" stitchTiles="stitch"/%3E%3C/filter%3E%3Crect width="100%25" height="100%25" filter="url(%23noiseFilter)"/%3E%3C/svg%3E'); - opacity: 0.03; - pointer-events: none; -} - -/* Base Aesthetics */ -body { - background-color: var(--bg-ice); - color: var(--text-primary); - font-family: var(--font-main); - line-height: 1.6; - overflow-x: hidden; -} - -/* Hide scrollbar but keep functionality for Chrome/Safari */ -body::-webkit-scrollbar { - display: none; -} - -/* Noise Removed for Crystal Clarity */ -.noise-overlay { - display: none; -} - -/* --- HERO V2 PREMIUM --- */ -.hero-v2 { - min-height: 100vh; - display: flex; - align-items: center; - justify-content: space-between; - padding: 0 10%; - gap: 5%; - position: relative; - background: var(--bg-dark-hero); - color: #FFFFFF; - z-index: 1; -} - -.hero-v2 h1 { - font-family: var(--font-heading); - font-weight: 800; - font-size: 4.5rem; - line-height: 1.1; - margin-bottom: 1.5rem; -} - -.hero-v2 .highlight { - color: var(--accent-yellow); -} - -.btn-primary { - background: var(--accent-yellow); - color: var(--primary-deep); - padding: 1rem 2rem; - border-radius: 8px; - font-weight: 700; - text-decoration: none; - transition: all 0.3s var(--ease-apple); - display: inline-block; -} - -.btn-primary:hover { - background: var(--accent-yellow-hover); - transform: translateY(-2px); -} - -.btn-secondary { - border: 2px solid var(--primary-electric); - color: #FFFFFF; - padding: 1rem 2rem; - border-radius: 8px; - font-weight: 600; - text-decoration: none; - transition: all 0.3s var(--ease-apple); - display: inline-block; - margin-left: 1rem; -} - -.btn-secondary:hover { - background: rgba(37, 99, 235, 0.1); -} - -.hero-content { - max-width: 650px; - position: relative; -} - -.hero-h1 { - font-family: 'Syne', sans-serif; - font-size: clamp(2.5rem, 6vw, 4.2rem); - font-weight: 800; - line-height: 1.05; - letter-spacing: -0.04em; - margin-bottom: 2rem; - background: linear-gradient(to bottom, #fff 0%, #cbd5e1 100%); - -webkit-background-clip: text; - background-clip: text; - -webkit-text-fill-color: transparent; -} - -.hero-p { - font-size: 1.15rem; - color: var(--text-secondary); - line-height: 1.6; - margin-bottom: 3rem; - max-width: 500px; -} - -.hero-cta-group { - display: flex; - gap: 1.5rem; - margin-bottom: 4rem; -} - -.btn-geo-primary-v2 { - background: var(--accent-enterprise); - color: #fff; - padding: 1rem 2rem; - border-radius: 12px; - text-decoration: none; - font-weight: 600; - font-size: 0.95rem; - display: inline-flex; - align-items: center; - gap: 0.8rem; - box-shadow: 0 10px 20px rgba(59, 130, 246, 0.2); - transition: all 0.3s var(--ease-apple); - border: 1px solid rgba(255, 255, 255, 0.1); -} - -.btn-geo-primary-v2:hover { - transform: translateY(-3px); - box-shadow: 0 15px 30px rgba(59, 130, 246, 0.3); - background: #4f46e5; -} - -.btn-geo-outline-v2 { - background: rgba(255, 255, 255, 0.03); - -webkit-backdrop-filter: blur(10px); - backdrop-filter: blur(10px); - color: #fff; - padding: 1rem 2rem; - border-radius: 12px; - text-decoration: none; - font-weight: 600; - font-size: 0.95rem; - display: inline-flex; - align-items: center; - gap: 0.8rem; - border: 1px solid rgba(255, 255, 255, 0.1); - transition: all 0.3s var(--ease-apple); -} - -.btn-geo-outline-v2:hover { - background: rgba(255, 255, 255, 0.08); - border-color: rgba(255, 255, 255, 0.2); - transform: translateY(-3px); -} - -/* --- PREMIUM REVEAL SYSTEM --- */ -.reveal { - opacity: 0; - transform: translateY(30px); - transition: opacity 1.2s var(--ease-apple), transform 1.2s var(--ease-apple); - will-change: transform, opacity; -} - -.reveal.revealed { - opacity: 1; - transform: translateY(0); -} - -/* Staggered delays for a professional sequential materialization */ -.reveal-1 { transition-delay: 0.1s; } -.reveal-2 { transition-delay: 0.25s; } -.reveal-3 { transition-delay: 0.4s; } -.reveal-4 { transition-delay: 0.55s; } -.reveal-5 { transition-delay: 0.7s; } - -.intro-terminal::after { - content: " "; - display: block; - position: absolute; - top: 0; - left: 0; - bottom: 0; - right: 0; - background: rgba(18, 16, 16, 0.1); - opacity: 0; - z-index: 2; - pointer-events: none; - animation: flicker 0.15s infinite; -} - -.intro-terminal.hidden { - opacity: 0; - pointer-events: none; -} - -#terminal-content { - font-family: var(--font-mono); - color: var(--accent-electric); - font-size: 0.85rem; - line-height: 1.6; - max-width: 800px; - width: 100%; - position: relative; - z-index: 3; - text-shadow: 0 0 10px rgba(0, 229, 255, 0.5); -} - -.terminal-line { - display: block; - margin-bottom: 0.4rem; - overflow: hidden; - white-space: nowrap; -} - -.terminal-cursor { - display: inline-block; - width: 8px; - height: 15px; - background: var(--accent-electric); - margin-left: 5px; - vertical-align: middle; - animation: blink 0.8s infinite; - box-shadow: 0 0 10px var(--accent-electric); -} - -@keyframes blink { - - 0%, - 100% { - opacity: 1; - } - - 50% { - opacity: 0; - } -} - -@keyframes flicker { - 0% { - opacity: 0.27861; - } - - 5% { - opacity: 0.34769; - } - - 10% { - opacity: 0.23604; - } - - 15% { - opacity: 0.90626; - } - - /* ... shorter flicker logic ... */ - 100% { - opacity: 0.1; - } -} - -/* --- CUSTOM CURSOR (Luxury Interaction) --- */ -.cursor-main { - width: 8px; - height: 8px; - background: var(--accent-electric); - border-radius: 50%; - position: fixed; - top: 0; - left: 0; - z-index: 40000; - pointer-events: none; - mix-blend-mode: difference; - transition: width 0.3s var(--ease-spring), height 0.3s var(--ease-spring), background 0.3s; -} - -.cursor-trail { - width: 32px; - height: 32px; - border: 1px solid rgba(0, 229, 255, 0.3); - border-radius: 50%; - position: fixed; - top: 0; - left: 0; - z-index: 39999; - pointer-events: none; -} - -/* --- VIRTUAL DEPTH (Apple/Nike Style) --- */ -.glow-orb { - position: fixed; - width: 60vw; - height: 60vw; - border-radius: 50%; - background: radial-gradient(circle, rgba(0, 229, 255, 0.08) 0%, transparent 70%); - filter: blur(120px); - z-index: -1; - pointer-events: none; - animation: orbFloat 25s infinite alternate ease-in-out; -} - -.orb-1 { - top: -20%; - left: -20%; -} - -.orb-2 { - bottom: -20%; - right: -20%; - background: radial-gradient(circle, rgba(255, 180, 0, 0.05) 0%, transparent 70%); -} - -@keyframes orbFloat { - 0% { - transform: translate(0, 0) scale(1); - } - - 100% { - transform: translate(10%, 10%) scale(1.1); - } -} - -@keyframes float { - - 0%, - 100% { - transform: translateY(0px); - } - - 50% { - transform: translateY(-20px); - } -} - -@keyframes pulse { - - 0%, - 100% { - opacity: 1; - filter: drop-shadow(0 0 40px rgba(0, 229, 255, 0.3)); - } - - 50% { - opacity: 0.8; - filter: drop-shadow(0 0 60px rgba(0, 229, 255, 0.6)); - } -} - -/* --- TECH DNA SECTION (MODERN) --- */ -.tech-dna-container { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); - gap: 2rem; - padding: 4rem 0; -} - -.tech-group-modern { - background: rgba(255, 255, 255, 0.02); - border: 1px solid var(--border-glass); - padding: 2.5rem; - border-radius: 24px; - transition: all 0.5s var(--ease-spring); - position: relative; - overflow: hidden; -} - -.tech-group-modern:hover { - background: rgba(0, 229, 255, 0.05); - border-color: var(--accent-electric); - transform: translateY(-10px); -} - -.tech-group-header { - display: flex; - align-items: center; - gap: 1rem; - margin-bottom: 2rem; -} - -.tech-group-header i { - font-size: 1.5rem; - color: var(--accent-electric); -} - -.tech-group-modern h3 { - font-size: 0.8rem; - font-family: var(--font-mono); - color: #fff; - margin: 0; - letter-spacing: 0.1em; -} - -.tech-icons-modern { - display: flex; - gap: 1rem; - margin-bottom: 1.5rem; -} - -.tech-icons-modern img { - height: 38px; - filter: grayscale(1) opacity(0.5); - transition: all 0.4s ease; -} - -.tech-group-modern:hover .tech-icons-modern img { - filter: grayscale(0) opacity(1); - transform: scale(1.1); -} - -.tech-group-desc { - font-size: 0.85rem; - color: var(--text-secondary); - line-height: 1.6; -} - -@media (max-width: 900px) { - .tech-dna-container { flex-direction: column; gap: 2rem; } -} - -/* --- CONTACT SECURE CHANNEL --- */ -.contact-grid { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 4rem; - margin-top: 4rem; -} - -.contact-secure-card { - background: rgba(0, 229, 255, 0.03); - border: 1px solid var(--border-glass); - padding: 3rem; - border-radius: 24px; - position: relative; -} - -.contact-secure-card::before { - content: 'SECURE_CHANNEL_ENCRYPTED'; - position: absolute; - top: 10px; - right: 15px; - font-size: 0.5rem; - font-family: var(--font-mono); - color: var(--status-ok); - opacity: 0.5; -} - - -/* --- THE DEVOPS DATA GRID (Server/Pipeline Flow) --- */ -.neural-grid { - position: fixed; - inset: 0; - background: - linear-gradient(rgba(0, 229, 255, 0.04) 1px, transparent 1px), - linear-gradient(90deg, rgba(0, 229, 255, 0.04) 1px, transparent 1px); - background-size: 60px 60px; - z-index: -1; - pointer-events: none; - opacity: 0.9; - animation: gridPulse 8s infinite alternate; -} - -@keyframes gridPulse { - 0% { opacity: 0.5; } - 100% { opacity: 1; } -} - -.neural-grid::before { - content: ''; - position: absolute; - inset: 0; - background: radial-gradient(circle at var(--mouse-x, 50%) var(--mouse-y, 50%), rgba(0, 229, 255, 0.1) 0%, transparent 45%); - pointer-events: none; - z-index: 1; -} - -.neural-grid::after { - content: ''; - position: absolute; - inset: 0; - background: repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.05) 0px, transparent 1px, transparent 2px); - pointer-events: none; - opacity: 0.5; -} - -@keyframes scanLine { - 0% { - transform: translateY(-12px); - opacity: 0; - } - - 50% { - opacity: 0.8; - } - - 100% { - transform: translateY(12px); - opacity: 0; - } -} - -@keyframes biometricPulse { - - 0%, - 100% { - transform: scale(1); - opacity: 0.2; - } - - 50% { - transform: scale(1.6); - opacity: 0.6; - } -} - -/* --- PREMIUM NAVIGATION V6 (Sovereign Architecture) --- */ -.dgz-nav-master { - position: fixed; - top: 0; - left: 0; - width: 100%; - z-index: 10000; - padding: 1.5rem 0; - transition: all 0.5s var(--ease-apple); -} - -.dgz-nav-master.scrolled { - padding: 1rem 0; -} - -.nav-blur-bg { - position: absolute; - inset: 0; - background: rgba(2, 4, 10, 0.4); - -webkit-backdrop-filter: blur(20px) saturate(180%); - backdrop-filter: blur(20px) saturate(180%); - border-bottom: 1px solid rgba(255, 255, 255, 0.08); - opacity: 0; - transition: opacity 0.5s var(--ease-apple); -} - -.dgz-nav-master.scrolled .nav-blur-bg { - opacity: 1; -} - -.nav-content { - max-width: 1400px; - margin: 0 auto; - width: 90%; - display: flex; - justify-content: space-between; - align-items: center; - position: relative; - z-index: 2; -} - -.nav-logo { - display: flex; - align-items: center; - gap: 12px; - text-decoration: none; - color: #fff; - font-family: var(--font-main); - font-weight: 800; - font-size: 1.1rem; - letter-spacing: -0.02em; - transition: var(--transition-fast); -} - -.nav-logo svg { - transition: transform 0.6s var(--ease-spring); -} - -.nav-logo:hover svg { - transform: rotate(90deg) scale(1.1); - filter: drop-shadow(0 0 10px var(--accent-electric)); -} - -.nav-logo svg circle { - animation: logo-pulse 3s infinite ease-in-out; -} - -@keyframes logo-pulse { - 0%, 100% { opacity: 1; r: 2; fill: var(--accent-yellow); } - 50% { opacity: 0.5; r: 2.5; fill: var(--accent-electric); } -} - -.nav-logo span { - background: linear-gradient(to bottom, #fff, #94a3b8); - -webkit-background-clip: text; - background-clip: text; - -webkit-text-fill-color: transparent; - transition: all 0.4s var(--ease-apple); -} - -.nav-logo:hover span { - letter-spacing: 0.05em; - filter: drop-shadow(0 0 5px rgba(255, 255, 255, 0.2)); -} - -.nav-links { - display: flex; - gap: 3rem; - align-items: center; -} - -.nav-link { - text-decoration: none; - color: var(--text-secondary); - font-family: var(--font-mono); - font-size: 0.65rem; - font-weight: 700; - text-transform: uppercase; - letter-spacing: 0.2em; - padding: 0.5rem 0; - transition: all 0.3s var(--ease-apple); - position: relative; - cursor: pointer; - display: flex; - align-items: center; - gap: 5px; -} - -.nav-link:hover { - color: #fff; - text-shadow: 0 0 15px rgba(255, 255, 255, 0.3); - transform: translateY(-2px); -} - -.nav-link::after { - content: ''; - position: absolute; - bottom: 0; - left: 50%; - width: 0; - height: 1px; - background: var(--accent-electric); - transition: all 0.4s var(--ease-apple); - transform: translateX(-50%); -} - -.nav-link:hover::after { - width: 100%; -} - -.nav-link i { - font-size: 0.8rem; - transition: transform 0.3s var(--ease-apple); -} - -.nav-dropdown:hover .nav-link i { - transform: rotate(180deg); -} - -/* Dropdown System */ -.nav-dropdown { - position: relative; -} - -.dropdown-content { - position: absolute; - top: 100%; - left: 50%; - transform: translateX(-50%) translateY(20px); - background: rgba(10, 13, 23, 0.85); - border: 1px solid rgba(255, 255, 255, 0.08); - border-radius: 24px; - padding: 1.2rem; - min-width: 280px; - opacity: 0; - pointer-events: none; - -webkit-backdrop-filter: blur(40px) saturate(200%); - backdrop-filter: blur(40px) saturate(200%); - transition: all 0.5s cubic-bezier(0.16, 1, 0.3, 1); - box-shadow: - 0 30px 60px rgba(0, 0, 0, 0.8), - 0 0 0 1px rgba(255, 255, 255, 0.05), - inset 0 0 20px rgba(255, 255, 255, 0.02); -} - -.nav-dropdown:hover .dropdown-content { - opacity: 1; - pointer-events: auto; - transform: translateX(-50%) translateY(15px); -} - -.dropdown-content a { - display: flex; - justify-content: space-between; - align-items: center; - color: var(--text-secondary); - text-decoration: none; - font-size: 0.7rem; - font-family: var(--font-mono); - text-transform: uppercase; - letter-spacing: 0.1em; - padding: 0.8rem 1.2rem; - border-radius: 12px; - transition: all 0.3s var(--ease-apple); - margin-bottom: 0.4rem; - border: 1px solid transparent; -} - -.dropdown-content a:hover { - background: rgba(255, 255, 255, 0.05); - color: var(--accent-electric); - border-color: rgba(0, 210, 255, 0.2); - transform: translateX(8px); - box-shadow: -5px 0 15px rgba(0, 229, 255, 0.1); -} - -.dropdown-content a::after { - content: '→'; - opacity: 0; - transform: translateX(-10px); - transition: all 0.3s var(--ease-apple); -} - -.dropdown-content a:hover::after { - opacity: 1; - transform: translateX(0); -} - -.nav-actions { - display: flex; - align-items: center; - gap: 2.5rem; -} - -.system-status { - display: flex; - align-items: center; - gap: 10px; - padding: 8px 16px; - background: rgba(0, 229, 255, 0.05); - border: 1px solid rgba(0, 229, 255, 0.2); - border-radius: 100px; - font-family: var(--font-mono); - font-size: 0.55rem; - color: var(--accent-electric); - letter-spacing: 0.15em; - text-transform: uppercase; -} - -.status-dot { - width: 6px; - height: 6px; - background: var(--status-ok); - border-radius: 50%; - box-shadow: 0 0 12px var(--status-ok); - animation: status-pulse 2s infinite ease-in-out; -} - -@keyframes status-pulse { - 0%, 100% { opacity: 1; transform: scale(1); filter: brightness(1); } - 50% { opacity: 0.4; transform: scale(1.3); filter: brightness(1.5); } -} - -.lang-toggle-btn { - background: rgba(255, 255, 255, 0.03); - border: 1px solid rgba(255, 255, 255, 0.1); - color: #fff; - padding: 10px 20px; - border-radius: 100px; - cursor: pointer; - font-family: var(--font-mono); - font-size: 0.7rem; - font-weight: 800; - display: flex; - align-items: center; - gap: 8px; - transition: all 0.4s var(--ease-apple); - -webkit-backdrop-filter: blur(10px); - backdrop-filter: blur(10px); - overflow: hidden; - position: relative; -} - -.lang-toggle-btn::before { - content: ''; - position: absolute; - inset: 0; - background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent); - transform: translateX(-100%); - transition: 0.6s; -} - -.lang-toggle-btn:hover::before { - transform: translateX(100%); -} - -.lang-toggle-btn:hover { - background: rgba(255, 255, 255, 0.08); - border-color: var(--accent-electric); - transform: translateY(-2px) scale(1.05); - box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3), 0 0 15px rgba(0, 210, 255, 0.2); -} - -.lang-toggle-btn i { - font-size: 1rem; -} - -/* Scroll Progress Indicator V2 */ -.dgz-nav-master::after { - content: ''; - position: absolute; - bottom: 0; - left: 0; - height: 1px; - background: linear-gradient(90deg, transparent, var(--accent-electric), transparent); - width: var(--scroll-width, 0%); - transition: width 0.1s linear; - opacity: 0; -} - -.dgz-nav-master.scrolled::after { - opacity: 1; -} - -@media (max-width: 1024px) { - .nav-links { - gap: 1.5rem; - } -} - -@media (max-width: 900px) { - .hide-mobile { - display: none; - } - - .nav-links { - display: none; - } -} - - -/* --- MAP IMMERSIVE OVERLAY (Advanced GIS) --- */ -.map-scan-overlay { - position: absolute; - inset: 0; - pointer-events: none; - background: linear-gradient(rgba(18, 16, 16, 0) 50%, rgba(0, 0, 0, 0.1) 50%), - linear-gradient(90deg, rgba(0, 229, 255, 0.02), rgba(0, 0, 0, 0)); - background-size: 100% 4px, 100% 100%; - z-index: 400; - opacity: 0.3; -} - -.map-label-hud { - position: absolute; - top: 2rem; - left: 2rem; - background: rgba(5, 5, 7, 0.85); - -webkit-backdrop-filter: blur(20px); - backdrop-filter: blur(20px); - border: 1px solid var(--accent-electric); - padding: 1.5rem; - border-radius: 12px; - z-index: 1000; - font-family: var(--font-mono); - min-width: 220px; - box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5); -} - -.hud-line { - display: flex; - justify-content: space-between; - font-size: 0.55rem; - margin-bottom: 0.5rem; - color: var(--text-tertiary); -} - -.hud-value { - color: var(--accent-electric); - font-weight: 800; -} - -/* --- MAP CONTROL OVERLAYS --- */ -.map-controls-panel { - position: absolute; - bottom: 2rem; - right: 2rem; - display: flex; - flex-direction: column; - gap: 0.5rem; - z-index: 1000; -} - -.map-control-btn { - width: 48px; - height: 48px; - background: rgba(15, 20, 30, 0.6); - border: 1px solid rgba(255, 255, 255, 0.1); - border-radius: 12px; - color: #fff; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - -webkit-backdrop-filter: blur(20px); - backdrop-filter: blur(20px); - transition: all 0.4s var(--ease-apple); -} - -.map-control-btn:hover { - border-color: var(--accent-electric); - background: var(--accent-electric); - color: #000; - transform: translateY(-2px); - box-shadow: 0 10px 20px rgba(0, 229, 255, 0.3); -} - -.map-layer-selector { - position: absolute; - top: 2rem; - right: 2rem; - z-index: 1000; - background: rgba(15, 20, 30, 0.6); - -webkit-backdrop-filter: blur(20px); - backdrop-filter: blur(20px); - border: 1px solid rgba(255, 255, 255, 0.1); - border-radius: 16px; - padding: 0.6rem; - display: flex; - gap: 0.6rem; -} - -.layer-opt { - padding: 0.6rem 1.2rem; - font-family: var(--font-mono); - font-size: 0.7rem; - color: rgba(255, 255, 255, 0.5); - cursor: pointer; - border-radius: 10px; - transition: all 0.3s; - font-weight: 700; -} - -.layer-opt.active { - background: var(--accent-electric); - color: #000; -} - -.marker-pulse { - width: 20px; - height: 20px; - background: var(--accent-electric); - border-radius: 50%; - position: absolute; - animation: markerPulse 2s infinite; -} - -@keyframes markerPulse { - 0% { - transform: scale(1); - opacity: 0.8; - } - - 100% { - transform: scale(3); - opacity: 0; - } -} - -/* --- HERO (Tesla/Apple Influence) --- */ -.hero { - height: 100vh; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - text-align: center; - padding: 0 5%; - position: relative; - overflow: hidden; -} - -.hero h1 { - font-size: clamp(3rem, 10vw, 8rem); - font-weight: 900; - letter-spacing: -0.05em; - line-height: 0.85; - margin-bottom: 2rem; - background: linear-gradient(180deg, #fff 40%, rgba(255, 255, 255, 0.4)); - -webkit-background-clip: text; - background-clip: text; - -webkit-text-fill-color: transparent; -} - -.hero p { - font-size: 1.5rem; - color: var(--text-secondary); - max-width: 800px; - margin: 0 auto 3rem; - font-weight: 400; -} - -/* --- BENTO GRID SYSTEM (Osnaider/Print Style) --- */ -.bento-grid { - display: grid; - grid-template-columns: repeat(12, 1fr); - grid-gap: 2rem; - max-width: 1400px; - margin: 0 auto; -} - -.bento-item { - background: rgba(15, 20, 30, 0.4); - border: 1px solid rgba(255, 255, 255, 0.08); - border-radius: 32px; - padding: 3rem; - position: relative; - overflow: hidden; - transition: all 0.6s var(--ease-apple); - -webkit-backdrop-filter: blur(25px) saturate(200%); - backdrop-filter: blur(25px) saturate(200%); - transform-style: preserve-3d; - display: flex; - flex-direction: column; -} - -.bento-item::after { - content: ''; - position: absolute; - inset: 0; - background: url('https://grainy-gradients.vercel.app/noise.svg'); - opacity: 0.03; - pointer-events: none; - mix-blend-mode: overlay; - animation: card-scan 15s infinite linear; -} - -.bento-item:hover { - border-color: var(--accent-electric); - background: rgba(0, 210, 255, 0.03); - transform: translateY(-15px) scale(1.02); - box-shadow: 0 40px 80px rgba(0, 0, 0, 0.6); -} - -/* Large Flagship Hero Card */ -.bento-item.large { - grid-column: span 8; - height: 500px; -} - -.bento-item.medium { - grid-column: span 4; - height: 500px; -} - -.bento-item.tall { - grid-column: span 4; - grid-row: span 2; - height: 750px; -} - -.validator-output { - margin-top: 1rem; - padding: 10px; - background: rgba(0, 0, 0, 0.4); - border-radius: 4px; - color: var(--text-secondary); - min-height: 40px; - border-left: 2px solid var(--accent-electric); -} - -.validator-run-btn:disabled { - opacity: 0.5; - cursor: wait; -} - -/* --- BUTTONS (Tesla Minimalism) --- */ -.btn-premium { - padding: 1rem 3rem; - background: var(--text-primary); - color: var(--bg-black); - font-weight: 800; - border-radius: 100px; - text-transform: uppercase; - font-size: 0.8rem; - letter-spacing: 0.1em; - text-decoration: none; - transition: var(--transition-fast); - border: 1px solid transparent; -} - -.btn-premium:hover { - background: transparent; - color: var(--text-primary); - border-color: var(--text-primary); -} - -.btn-outline { - background: transparent; - color: var(--text-primary); - border: 1px solid var(--border-glass); -} - -/* --- INTEL MAP TOOLTIPS (Architecture) --- */ -.custom-map-tooltip { - background: rgba(0, 0, 0, 0.95); - border: 1px solid var(--accent-electric); - border-radius: 12px; - padding: 1.2rem; - color: #fff; - box-shadow: 0 10px 40px rgba(0, 0, 0, 0.8), 0 0 20px rgba(0, 229, 255, 0.2); - font-family: var(--font-main); - max-width: 280px; - white-space: normal; -} - -.custom-map-tooltip::before { - border-top-color: var(--accent-electric); -} - -.map-tooltip-content { - font-size: 0.85rem; - line-height: 1.6; -} - -.map-tooltip-content b { - display: block; - font-family: var(--font-mono); - color: var(--accent-electric); - font-size: 0.7rem; - letter-spacing: 0.15em; - margin-bottom: 0.8rem; - text-transform: uppercase; - border-bottom: 1px solid rgba(0, 229, 255, 0.3); - padding-bottom: 0.5rem; -} - -/* --- SECTIONS (The 'Slide' Flow) --- */ -section { - padding: var(--section-gap) 5%; - max-width: 1600px; - margin: 0 auto; -} - -.section-label { - display: block; - font-family: var(--font-mono); - color: var(--accent-electric); - font-size: 0.8rem; - margin-bottom: 1rem; - text-transform: uppercase; - letter-spacing: 0.3em; -} - -.section-title { - font-size: clamp(2.5rem, 5vw, 4rem); - font-weight: 800; - margin-bottom: 4rem; - letter-spacing: -0.04em; -} - -/* --- REVOLUTIONARY CONTACT PORTAL --- */ -.contact-portal { - background: var(--bg-surface); - border: 1px solid var(--border-glass); - border-radius: 40px; - padding: 5rem; - display: grid; - grid-template-columns: 1fr 1.5fr; - gap: 6rem; - position: relative; - overflow: hidden; - text-align: left; -} - -.contact-portal::after { - content: ''; - position: absolute; - top: -50%; - right: -50%; - width: 100%; - height: 100%; - background: radial-gradient(circle, rgba(0, 229, 255, 0.05), transparent 70%); - pointer-events: none; -} - -.portal-field { - margin-bottom: 2.5rem; - position: relative; -} - -.portal-field label { - display: block; - font-family: var(--font-mono); - font-size: 0.65rem; - text-transform: uppercase; - color: var(--text-tertiary); - margin-bottom: 1rem; - letter-spacing: 0.2em; -} - -.portal-input { - width: 100%; - background: transparent; - border: none; - border-bottom: 1px solid var(--border-glass); - padding: 1rem 0; - color: #fff; - font-family: var(--font-main); - font-size: 1.1rem; - transition: var(--transition-fast); - outline: none; -} - -.portal-input:focus { - border-bottom-color: var(--accent-electric); - padding-left: 1rem; -} - -/* Custom Select Styling */ -.portal-select { - appearance: none; - background: url('data:image/svg+xml;utf8,') no-repeat right center; - background-size: 1.2rem; - cursor: pointer; -} - -/* Submit Button Evolution */ -.btn-transmit { - width: 100%; - padding: 1.5rem; - background: var(--accent-electric); - color: #000; - border: none; - border-radius: 16px; - font-weight: 900; - text-transform: uppercase; - letter-spacing: 0.2em; - font-size: 0.9rem; - cursor: pointer; - transition: var(--transition-fast); - display: flex; - align-items: center; - justify-content: center; - gap: 1rem; -} - -.btn-transmit:hover { - box-shadow: 0 10px 40px rgba(0, 229, 255, 0.4); - transform: translateY(-5px); -} - -.btn-transmit:disabled { - background: var(--surface-lighter); - color: var(--text-tertiary); -} - -/* --- PREMIUM FOOTER ARCHITECTURE --- */ -.site-footer { - padding: 10rem 5%; - background: #000; - border-top: 1px solid var(--border-glass); - position: relative; - overflow: hidden; -} - -.footer-grid { - display: grid; - grid-template-columns: 2fr 1fr 1fr; - max-width: 1400px; - margin: 0 auto; - gap: 4rem; -} - -.footer-brand { - display: flex; - flex-direction: column; - gap: 1.5rem; -} - -.footer-title { - font-family: var(--font-mono); - font-size: 0.9rem; - color: #fff; - letter-spacing: 0.2em; - font-weight: 800; -} - -.footer-column h4 { - font-family: var(--font-mono); - font-size: 0.6rem; - color: var(--text-tertiary); - text-transform: uppercase; - margin-bottom: 2rem; - letter-spacing: 0.3em; -} - -.footer-link { - display: block; - color: #fff; - text-decoration: none; - font-size: 0.8rem; - margin-bottom: 1rem; - transition: var(--transition-fast); -} - -.footer-link:hover { - color: var(--accent-electric); - transform: translateX(5px); -} - -.footer-bottom { - margin-top: 8rem; - padding-top: 2rem; - border-top: 1px solid rgba(255, 255, 255, 0.05); - display: flex; - justify-content: space-between; - align-items: center; - font-size: 0.6rem; - color: var(--text-tertiary); -} - -/* --- SOCIAL DOCK (SOVEREIGN HANDLE) --- */ -.social-dock { - position: fixed; - left: 1.5rem; - top: 50%; - transform: translateY(-50%); - display: flex; - flex-direction: column; - gap: 1.2rem; - z-index: 10002; - padding: 1.5rem 0.5rem; - border-radius: 100px; - background: rgba(0, 0, 0, 0.4); - -webkit-backdrop-filter: blur(25px); - backdrop-filter: blur(25px); - border: 1px solid var(--border-glass); - width: 12px; /* Minimized */ - height: 180px; - transition: all 0.6s var(--ease-spring); - overflow: hidden; - cursor: pointer; -} - -.social-dock:hover { - width: 60px; - background: rgba(0, 0, 0, 0.85); - border-color: var(--accent-electric); - padding: 1.5rem 0.8rem; -} - -.social-item { - width: 44px; - height: 44px; - background: transparent; - border: 1px solid rgba(255, 255, 255, 0.1); - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - color: var(--text-tertiary); - transition: var(--transition-fast); - opacity: 0; - transform: translateX(-20px); -} - -.social-dock:hover .social-item { - opacity: 1; - transform: translateX(0); -} - -.social-item:hover { - border-color: var(--accent-electric); - color: var(--accent-electric); - background: rgba(0, 229, 255, 0.05); - transform: scale(1.1); -} - -/* RESPONSIVE --- */ -@media (max-width: 1024px) { - .bento-grid { - display: flex; - flex-direction: column; - } - - .bento-item { - height: auto !important; - } - - .nav-links { - display: none; - } - - .cursor-main, - .cursor-trail { - display: none; - } - - body { - cursor: auto; - } -} - -/* --- METRICS CORE (Premium Data Display) --- */ -.metrics-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); - gap: 30px; - margin-top: 4rem; -} - -.metric-card { - background: linear-gradient(145deg, rgba(255, 255, 255, 0.03) 0%, rgba(255, 255, 255, 0.01) 100%); - border: 1px solid var(--border-glass); - padding: 3rem 2rem; - border-radius: 24px; - text-align: center; - position: relative; - overflow: hidden; - transition: var(--transition-fast); -} - -.metric-card:hover { - border-color: var(--accent-electric); - background: rgba(0, 229, 255, 0.02); - transform: translateY(-5px); -} - -.metric-num { - font-size: 4rem; - font-weight: 900; - line-height: 1; - margin-bottom: 0.5rem; - background: linear-gradient(180deg, #fff, var(--accent-electric)); - -webkit-background-clip: text; - background-clip: text; - -webkit-text-fill-color: transparent; -} - -.metric-label { - font-family: var(--font-mono); - font-size: 0.7rem; - color: var(--text-tertiary); - text-transform: uppercase; - letter-spacing: 0.2em; -} - -.metric-card::before { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 1px; - background: linear-gradient(90deg, transparent, var(--accent-electric), transparent); - opacity: 0; - transition: 0.5s; -} - -.metric-card:hover::before { - opacity: 1; -} - -/* --- MAP 2.0 MARKER STYLING --- */ -.custom-marker { - display: flex; - align-items: center; - justify-content: center; -} - -.marker-core { - width: 12px; - height: 12px; - background: var(--accent-electric); - border-radius: 50%; - border: 2px solid #fff; - box-shadow: 0 0 15px var(--accent-electric); - z-index: 2; -} - -.marker-pulse { - position: absolute; - width: 40px; - height: 40px; - background: rgba(0, 229, 255, 0.2); - border-radius: 50%; - animation: markerPulse 2s infinite ease-out; - z-index: 1; -} - -@keyframes markerPulse { - 0% { - transform: scale(0.5); - opacity: 0.8; - } - - 100% { - transform: scale(3); - opacity: 0; - } -} - -.leaflet-popup-content-wrapper { - background: transparent !important; - box-shadow: none !important; - padding: 0 !important; -} - -.leaflet-popup-tip { - display: none !important; -} - -/* Scroll-triggered reveal refinement */ -.reveal { - opacity: 0; - transform: translateY(30px); - transition: opacity 1.2s cubic-bezier(0.16, 1, 0.3, 1), transform 1.2s cubic-bezier(0.16, 1, 0.3, 1); -} - -.reveal.active { - opacity: 1; - transform: translateY(0); -} - -/* ============================================================ - MASTER BLUEPRINT V6.0 — NEW SECTION STYLES - ============================================================ */ - -/* --- HERO V6 IDENTITY UPGRADE --- */ -.hero-identity-badge { - display: inline-flex; - align-items: center; - gap: 0.6rem; - background: rgba(0, 229, 255, 0.06); - border: 1px solid rgba(0, 229, 255, 0.25); - border-radius: 100px; - padding: 0.5rem 1.2rem; - margin-bottom: 2rem; - font-family: var(--font-mono); - font-size: 0.6rem; - letter-spacing: 0.15em; - color: var(--accent-electric); - text-transform: uppercase; -} - -.hero-badge-dot { - width: 6px; - height: 6px; - background: #4ade80; - border-radius: 50%; - animation: badgePulse 2s infinite; - flex-shrink: 0; -} - -@keyframes badgePulse { - - 0%, - 100% { - opacity: 1; - box-shadow: 0 0 0 0 rgba(74, 222, 128, 0.4); - } - - 50% { - opacity: 0.7; - box-shadow: 0 0 0 4px rgba(74, 222, 128, 0); - } -} - -.hero-tech-badges { - display: flex; - flex-wrap: wrap; - gap: 0.6rem; - justify-content: center; - margin-top: 2.5rem; -} - -.hero-badge-pill { - font-family: var(--font-mono); - font-size: 0.55rem; - padding: 0.4rem 1rem; - border-radius: 100px; - border: 1px solid rgba(255, 255, 255, 0.1); - color: var(--text-secondary); - background: rgba(255, 255, 255, 0.02); - letter-spacing: 0.1em; - text-transform: uppercase; - transition: all 0.3s; -} - -.hero-badge-pill:hover { - border-color: var(--accent-electric); - color: var(--accent-electric); - background: rgba(0, 229, 255, 0.05); -} - -/* --- TERRITORIAL CHALLENGES SECTION --- */ -.challenges-section { - padding: 10rem 5%; - position: relative; -} - -.challenges-grid { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 2px; - max-width: 1200px; - margin: 0 auto; - border: 1px solid var(--border-glass); - border-radius: 24px; - overflow: hidden; -} - -.challenge-header { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 2px; - grid-column: 1 / -1; -} - -.challenge-header-cell { - background: rgba(0, 229, 255, 0.08); - padding: 1.5rem 2.5rem; - font-family: var(--font-mono); - font-size: 0.65rem; - letter-spacing: 0.2em; - text-transform: uppercase; - color: var(--accent-electric); - border-bottom: 1px solid rgba(0, 229, 255, 0.2); -} - -.challenge-row { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 2px; - grid-column: 1 / -1; - transition: all 0.3s; -} - -.challenge-row:hover .challenge-cell { - background: rgba(0, 229, 255, 0.04); -} - -.challenge-cell { - padding: 2rem 2.5rem; - border-bottom: 1px solid var(--border-glass); - display: flex; - align-items: center; - gap: 1rem; - background: var(--bg-surface); - transition: all 0.3s; -} - -.challenge-cell:last-child { - border-left: 1px solid rgba(0, 229, 255, 0.1); -} - -.challenge-icon { - font-size: 1.4rem; - width: 40px; - text-align: center; - flex-shrink: 0; -} - -.challenge-problem { - font-size: 0.9rem; - color: rgba(255, 100, 100, 0.9); - font-weight: 600; -} - -.challenge-solution { - font-size: 0.9rem; - color: #4ade80; - font-weight: 600; -} - -.challenge-arrow { - font-size: 0.7rem; - color: var(--text-tertiary); - font-family: var(--font-mono); - margin-right: 0.5rem; -} - -/* --- DGZ SPATIAL LAB SECTION --- */ -.spatial-lab-section { - padding: 10rem 5%; - position: relative; -} - -.lab-header { - max-width: 1400px; - margin: 0 auto 5rem; -} - -.lab-badge { - display: inline-flex; - align-items: center; - gap: 0.5rem; - background: rgba(255, 180, 0, 0.08); - border: 1px solid rgba(255, 180, 0, 0.3); - padding: 0.4rem 1rem; - border-radius: 100px; - font-family: var(--font-mono); - font-size: 0.55rem; - color: var(--accent-gold); - letter-spacing: 0.15em; - text-transform: uppercase; - margin-bottom: 1rem; -} - -.lab-star { - color: var(--accent-gold); - animation: starGlow 2s ease-in-out infinite alternate; -} - -@keyframes starGlow { - from { - text-shadow: 0 0 5px rgba(255, 180, 0, 0.5); - } - - to { - text-shadow: 0 0 20px rgba(255, 180, 0, 0.9), 0 0 40px rgba(255, 180, 0, 0.5); - } -} - -.lab-projects-grid { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 2rem; - max-width: 1400px; - margin: 0 auto; -} - -.lab-project-card { - background: var(--bg-surface); - border: 1px solid var(--border-glass); - border-radius: 28px; - padding: 2.5rem; - position: relative; - overflow: hidden; - transition: all 0.5s var(--ease-apple); - display: flex; - flex-direction: column; -} - -.lab-project-card::before { - content: ''; - position: absolute; - inset: 0; - background: radial-gradient(circle at top right, rgba(0, 229, 255, 0.06) 0%, transparent 60%); - opacity: 0; - transition: opacity 0.5s; -} - -.lab-project-card:hover::before { - opacity: 1; -} - -.lab-project-card:hover { - border-color: rgba(0, 229, 255, 0.4); - transform: translateY(-8px); - box-shadow: 0 30px 60px rgba(0, 0, 0, 0.5), 0 0 30px rgba(0, 229, 255, 0.1); -} - -.lab-project-card.gold-accent:hover { - border-color: rgba(255, 180, 0, 0.4); -} - -.lab-project-card.gold-accent::before { - background: radial-gradient(circle at top right, rgba(255, 180, 0, 0.06) 0%, transparent 60%); -} - -.lab-card-id { - font-family: var(--font-mono); - font-size: 0.5rem; - color: var(--text-tertiary); - letter-spacing: 0.2em; - text-transform: uppercase; - margin-bottom: 1.5rem; -} - -.lab-card-icon { - width: 60px; - height: 60px; - background: rgba(0, 229, 255, 0.08); - border: 1px solid rgba(0, 229, 255, 0.2); - border-radius: 16px; - display: flex; - align-items: center; - justify-content: center; - font-size: 1.6rem; - margin-bottom: 1.5rem; - transition: all 0.3s; -} - -.lab-project-card:hover .lab-card-icon { - background: rgba(0, 229, 255, 0.15); - box-shadow: 0 0 20px rgba(0, 229, 255, 0.2); -} - -.lab-card-icon.gold { - background: rgba(255, 180, 0, 0.08); - border-color: rgba(255, 180, 0, 0.2); -} - -.lab-project-card:hover .lab-card-icon.gold { - background: rgba(255, 180, 0, 0.15); - box-shadow: 0 0 20px rgba(255, 180, 0, 0.2); -} - -.lab-card-title { - font-size: 1.4rem; - font-weight: 800; - letter-spacing: -0.03em; - margin-bottom: 1rem; - line-height: 1.2; -} - -.lab-card-desc { - font-size: 0.85rem; - color: var(--text-secondary); - line-height: 1.7; - margin-bottom: 1.5rem; - flex: 1; -} - -.lab-tech-stack { - display: flex; - flex-wrap: wrap; - gap: 0.4rem; - margin-bottom: 2rem; -} - -.lab-tech-pill { - font-family: var(--font-mono); - font-size: 0.5rem; - padding: 0.3rem 0.7rem; - border-radius: 4px; - border: 1px solid rgba(0, 229, 255, 0.2); - color: var(--accent-electric); - background: rgba(0, 229, 255, 0.03); - text-transform: uppercase; - letter-spacing: 0.1em; -} - -.lab-tech-pill.gold { - border-color: rgba(255, 180, 0, 0.25); - color: var(--accent-gold); - background: rgba(255, 180, 0, 0.03); -} - -/* --- CADASTRAL VALIDATOR INTERACTIVE --- */ -.validator-demo { - background: rgba(0, 0, 0, 0.4); - border: 1px solid rgba(0, 229, 255, 0.15); - border-radius: 16px; - padding: 1.5rem; - margin-top: auto; -} - -.validator-parcels { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 4px; - margin-bottom: 1rem; -} - -.parcel-cell { - height: 30px; - border-radius: 3px; - background: rgba(0, 229, 255, 0.1); - border: 1px solid rgba(0, 229, 255, 0.2); - transition: all 0.3s; - position: relative; -} - -.parcel-cell.valid { - background: rgba(74, 222, 128, 0.15); - border-color: rgba(74, 222, 128, 0.4); -} - -.parcel-cell.error { - background: rgba(255, 75, 43, 0.15); - border-color: rgba(255, 75, 43, 0.4); - animation: errorFlash 1s infinite; -} - -.parcel-cell.warning { - background: rgba(255, 180, 0, 0.15); - border-color: rgba(255, 180, 0, 0.4); -} - -@keyframes errorFlash { - - 0%, - 100% { - opacity: 1; - } - - 50% { - opacity: 0.5; - } -} - -.validator-run-btn { - width: 100%; - padding: 0.8rem; - background: var(--accent-electric); - color: #000; - border: none; - border-radius: 8px; - font-family: var(--font-mono); - font-size: 0.6rem; - font-weight: 800; - letter-spacing: 0.15em; - text-transform: uppercase; - cursor: pointer; - transition: all 0.3s; - display: flex; - align-items: center; - justify-content: center; - gap: 0.5rem; -} - -.validator-run-btn:hover { - box-shadow: 0 5px 20px rgba(0, 229, 255, 0.4); - transform: translateY(-2px); -} - -.validator-output { - margin-top: 0.8rem; - font-family: var(--font-mono); - font-size: 0.5rem; - color: var(--text-tertiary); - min-height: 2rem; - display: flex; - flex-direction: column; - gap: 0.2rem; -} - -/* --- PIPELINE ANIMATION DEMO --- */ -.pipeline-demo { - display: flex; - flex-direction: column; - gap: 0; - margin-top: auto; -} - -.pipeline-step { - display: flex; - align-items: center; - gap: 1rem; - padding: 0.7rem 1rem; - border-left: 2px solid rgba(0, 229, 255, 0.2); - position: relative; - transition: all 0.3s; -} - -.pipeline-step.active-step { - border-left-color: var(--accent-electric); -} - -.pipeline-step.active-step .pipeline-step-dot { - background: var(--accent-electric); - box-shadow: 0 0 10px rgba(0, 229, 255, 0.6); -} - -.pipeline-step-dot { - width: 8px; - height: 8px; - border-radius: 50%; - background: rgba(0, 229, 255, 0.3); - position: absolute; - left: -5px; - flex-shrink: 0; - transition: all 0.3s; -} - -.pipeline-step-label { - font-family: var(--font-mono); - font-size: 0.55rem; - color: var(--text-tertiary); - text-transform: uppercase; - letter-spacing: 0.1em; - transition: all 0.3s; -} - -.pipeline-step.active-step .pipeline-step-label { - color: var(--accent-electric); -} - -.pipeline-step-icon { - font-size: 0.9rem; - margin-left: auto; -} - -/* --- MAP VIEWER DEMO --- */ -.map-preview-mini { - background: rgba(0, 0, 0, 0.5); - border: 1px solid rgba(0, 229, 255, 0.2); - border-radius: 12px; - height: 160px; - position: relative; - overflow: hidden; - margin-top: auto; -} - -.map-preview-grid { - position: absolute; - inset: 0; - background: - linear-gradient(rgba(0, 229, 255, 0.04) 1px, transparent 1px), - linear-gradient(90deg, rgba(0, 229, 255, 0.04) 1px, transparent 1px); - background-size: 20px 20px; -} - -.map-preview-polygons { - position: absolute; - inset: 0; - display: flex; - align-items: center; - justify-content: center; -} - -.mini-polygon { - position: absolute; - border: 1px solid rgba(0, 229, 255, 0.5); - background: rgba(0, 229, 255, 0.06); - border-radius: 3px; - transition: all 0.3s; -} - -.mini-polygon:hover { - background: rgba(0, 229, 255, 0.15); - border-color: var(--accent-electric); -} - -.map-preview-hud { - position: absolute; - top: 8px; - left: 8px; - font-family: var(--font-mono); - font-size: 0.45rem; - color: var(--accent-electric); - background: rgba(0, 0, 0, 0.7); - padding: 0.3rem 0.5rem; - border-radius: 4px; - border: 1px solid rgba(0, 229, 255, 0.2); -} - -.map-preview-pulse { - position: absolute; - width: 10px; - height: 10px; - background: var(--accent-electric); - border-radius: 50%; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - animation: miniPulse 2s infinite; -} - -@keyframes miniPulse { - 0% { - box-shadow: 0 0 0 0 rgba(0, 229, 255, 0.6); - } - - 100% { - box-shadow: 0 0 0 20px rgba(0, 229, 255, 0); - } -} - -.lab-launch-btn { - display: inline-flex; - align-items: center; - gap: 0.6rem; - padding: 0.8rem 1.5rem; - background: transparent; - border: 1px solid rgba(0, 229, 255, 0.3); - border-radius: 8px; - color: var(--accent-electric); - font-family: var(--font-mono); - font-size: 0.55rem; - letter-spacing: 0.15em; - text-transform: uppercase; - cursor: pointer; - text-decoration: none; - transition: all 0.3s; - margin-top: 1.5rem; -} - -.lab-launch-btn:hover { - background: rgba(0, 229, 255, 0.1); - border-color: var(--accent-electric); - transform: translateX(4px); -} - -/* --- GEOAI MODULE SECTION --- */ -.geoai-section { - padding: 10rem 5%; - background: radial-gradient(ellipse at center top, rgba(0, 229, 255, 0.04) 0%, transparent 60%); -} - -.geoai-inner { - max-width: 1400px; - margin: 0 auto; -} - -.geoai-content-grid { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 5rem; - align-items: center; - margin-top: 4rem; -} - -.geoai-text h3 { - font-size: 2.2rem; - font-weight: 800; - letter-spacing: -0.04em; - margin-bottom: 1.5rem; - line-height: 1.1; -} - -.geoai-text p { - color: var(--text-secondary); - line-height: 1.8; - margin-bottom: 2rem; - font-size: 0.95rem; -} - -.geoai-steps { - display: flex; - flex-direction: column; - gap: 0; - margin-top: 2rem; -} - -.geoai-step { - display: flex; - gap: 1.5rem; - position: relative; - padding-bottom: 2rem; -} - -.geoai-step:not(:last-child)::after { - content: ''; - position: absolute; - left: 19px; - top: 40px; - width: 2px; - height: calc(100% - 20px); - background: linear-gradient(to bottom, rgba(0, 229, 255, 0.3), transparent); -} - -.geoai-step-num { - width: 40px; - height: 40px; - background: rgba(0, 229, 255, 0.08); - border: 1px solid rgba(0, 229, 255, 0.3); - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - font-family: var(--font-mono); - font-size: 0.65rem; - color: var(--accent-electric); - font-weight: 800; - flex-shrink: 0; - position: relative; - z-index: 1; -} - -.geoai-step-text h4 { - font-size: 0.9rem; - font-weight: 800; - margin-bottom: 0.4rem; -} - -.geoai-step-text p { - font-size: 0.75rem; - color: var(--text-tertiary); - margin-bottom: 0; -} - -.geoai-visualization { - background: var(--bg-surface); - border: 1px solid var(--border-glass); - border-radius: 28px; - padding: 2.5rem; - position: relative; - overflow: hidden; - height: 500px; -} - -.geoai-viz-header { - font-family: var(--font-mono); - font-size: 0.55rem; - color: var(--accent-electric); - margin-bottom: 1.5rem; - letter-spacing: 0.15em; -} - -.geoai-satellite-view { - width: 100%; - height: 200px; - background: linear-gradient(135deg, #0a1628 0%, #0d2137 50%, #091522 100%); - border-radius: 12px; - position: relative; - overflow: hidden; - margin-bottom: 1.5rem; -} - -.satellite-grid { - position: absolute; - inset: 0; - background: - linear-gradient(rgba(0, 229, 255, 0.03) 1px, transparent 1px), - linear-gradient(90deg, rgba(0, 229, 255, 0.03) 1px, transparent 1px); - background-size: 15px 15px; -} - -.change-detection-overlay { - position: absolute; - inset: 0; - display: flex; - align-items: center; - justify-content: center; - gap: 4px; - flex-wrap: wrap; - padding: 1rem; -} - -.change-pixel { - width: 14px; - height: 14px; - border-radius: 1px; - background: rgba(0, 229, 255, 0.1); - transition: all 0.3s; -} - -.change-pixel.detected { - background: rgba(255, 75, 43, 0.7); - box-shadow: 0 0 5px rgba(255, 75, 43, 0.5); -} - -.change-pixel.stable { - background: rgba(74, 222, 128, 0.2); -} - -.geoai-metrics-row { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 1rem; -} - -.geoai-metric { - background: rgba(0, 0, 0, 0.4); - border: 1px solid var(--border-glass); - border-radius: 12px; - padding: 1rem; - text-align: center; -} - -.geoai-metric-val { - font-size: 1.6rem; - font-weight: 900; - background: linear-gradient(180deg, #fff, var(--accent-electric)); - -webkit-background-clip: text; - background-clip: text; - -webkit-text-fill-color: transparent; - line-height: 1; -} - -.geoai-metric-label { - font-family: var(--font-mono); - font-size: 0.48rem; - color: var(--text-tertiary); - text-transform: uppercase; - letter-spacing: 0.1em; - margin-top: 0.4rem; -} - -.geoai-tools { - margin-top: 1.5rem; - display: flex; - flex-wrap: wrap; - gap: 0.5rem; -} - -/* --- ENGINEERING ARCHITECTURE SECTION --- */ -.arch-section { - padding: 12rem 5%; - background: radial-gradient(circle at bottom left, rgba(0, 210, 255, 0.05), transparent 50%); -} - -.arch-inner { - max-width: 1200px; - margin: 0 auto; -} - -.arch-flow { - display: flex; - justify-content: space-between; - align-items: center; - gap: 1.5rem; - margin: 6rem 0; - position: relative; -} - -.arch-node { - background: rgba(15, 20, 30, 0.4); - border: 1px solid rgba(255, 255, 255, 0.1); - border-radius: 24px; - padding: 2.5rem 1.5rem; - text-align: center; - width: 220px; - -webkit-backdrop-filter: blur(25px) saturate(200%); - backdrop-filter: blur(25px) saturate(200%); - transition: all 0.5s var(--ease-apple); - position: relative; - z-index: 2; -} - -.arch-node:hover { - transform: translateY(-10px) scale(1.05); - border-color: var(--accent-electric); - background: rgba(0, 210, 255, 0.05); - box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4); -} - -.arch-node-icon { - font-size: 2.5rem; - margin-bottom: 1.5rem; - filter: drop-shadow(0 0 10px rgba(0, 210, 255, 0.3)); -} - -.arch-node-title { - font-family: var(--font-mono); - font-size: 0.8rem; - color: #fff; - font-weight: 800; - margin-bottom: 0.5rem; -} - -.arch-node-sub { - font-size: 0.7rem; - color: var(--text-secondary); - line-height: 1.4; -} - -.arch-connector { - flex-grow: 1; - height: 2px; - background: linear-gradient(90deg, var(--accent-electric), transparent); - position: relative; - opacity: 0.3; -} - -.arch-connector::after { - content: ''; - position: absolute; - width: 8px; - height: 8px; - background: var(--accent-electric); - border-radius: 50%; - top: 50%; - left: 0; - transform: translateY(-50%); - box-shadow: 0 0 10px var(--accent-electric); - animation: flow-pulse 3s infinite linear; -} - -@keyframes flow-pulse { - 0% { left: 0; opacity: 0; } - 50% { opacity: 1; } - 100% { left: 100%; opacity: 0; } -} - -.arch-tech-card { - background: rgba(15, 20, 30, 0.4); - border: 1px solid rgba(255, 255, 255, 0.08); - border-radius: 20px; - padding: 2.5rem; - -webkit-backdrop-filter: blur(25px) saturate(200%); - backdrop-filter: blur(25px) saturate(200%); - transition: all 0.4s var(--ease-apple); - display: flex; - flex-direction: column; - align-items: center; - gap: 1rem; -} - -.arch-tech-card:hover { - background: rgba(0, 210, 255, 0.03); - border-color: var(--accent-electric); - transform: translateY(-5px); -} - -@media (max-width: 1100px) { - .arch-flow { flex-direction: column; gap: 4rem; } - .arch-connector { width: 2px; height: 4rem; background: linear-gradient(180deg, var(--accent-electric), transparent); } - .arch-connector::after { animation: flow-pulse-v 3s infinite linear; left: 50%; top: 0; transform: translateX(-50%); } -} - -/* --- ENHANCED METRICS (V6 IMPACT CORE) --- */ -.metrics-v6-grid { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 2px; - max-width: 1200px; - margin: 4rem auto 0; - border: 1px solid var(--border-glass); - border-radius: 24px; - overflow: hidden; -} - -.metric-v6-card { - background: var(--bg-surface); - padding: 3.5rem; - position: relative; - overflow: hidden; - transition: all 0.4s; - display: flex; - align-items: center; - gap: 2rem; -} - -.metric-v6-card:hover { - background: rgba(0, 229, 255, 0.03); -} - -.metric-v6-card:nth-child(2) { - border-left: 1px solid var(--border-glass); -} - -.metric-v6-card:nth-child(3) { - border-top: 1px solid var(--border-glass); -} - -.metric-v6-card:nth-child(4) { - border-top: 1px solid var(--border-glass); - border-left: 1px solid var(--border-glass); -} - -.metric-v6-icon { - font-size: 2.5rem; - width: 72px; - height: 72px; - background: rgba(0, 229, 255, 0.06); - border: 1px solid rgba(0, 229, 255, 0.15); - border-radius: 20px; - display: flex; - align-items: center; - justify-content: center; - flex-shrink: 0; -} - -.metric-v6-data { - flex: 1; -} - -.metric-v6-num { - font-size: 3.5rem; - font-weight: 900; - line-height: 1; - background: linear-gradient(135deg, #fff 0%, var(--accent-electric) 100%); - -webkit-background-clip: text; - background-clip: text; - -webkit-text-fill-color: transparent; - margin-bottom: 0.3rem; -} - -.metric-v6-label { - font-size: 0.85rem; - font-weight: 700; - margin-bottom: 0.3rem; -} - -.metric-v6-sub { - font-family: var(--font-mono); - font-size: 0.55rem; - color: var(--text-tertiary); - text-transform: uppercase; - letter-spacing: 0.1em; -} - -/* --- TIMELINE ENHANCED --- */ -.timeline-wrapper { - display: grid; - grid-template-columns: auto 1fr; - gap: 4rem; - max-width: 1200px; - margin: 4rem auto 0; - align-items: start; -} - -.timeline-line { - display: none; -} - -.timeline-items { - display: flex; - flex-direction: column; - gap: 0; - min-width: 180px; - border-left: 1px solid var(--border-glass); -} - -.timeline-node { - padding: 1rem 1.5rem; - cursor: pointer; - transition: all 0.3s; - border-left: 2px solid transparent; - margin-left: -1px; - position: relative; -} - -.timeline-node:hover { - background: rgba(255, 255, 255, 0.02); -} - -.timeline-node.active { - border-left-color: var(--accent-electric); - background: rgba(0, 229, 255, 0.04); -} - -.node-dot { - display: none; -} - -.node-year { - font-family: var(--font-mono); - font-size: 0.65rem; - color: var(--text-tertiary); - transition: all 0.3s; - letter-spacing: 0.05em; -} - -.timeline-node.active .node-year { - color: var(--accent-electric); - font-weight: 800; -} - -.timeline-content-display { - background: var(--bg-surface); - border: 1px solid var(--border-glass); - border-radius: 24px; - padding: 3rem; - transition: opacity 0.3s var(--ease-apple); -} - -.timeline-text h3 { - font-size: 1.8rem; - font-weight: 800; - letter-spacing: -0.03em; - margin-bottom: 0.5rem; -} - -.timeline-text p { - font-size: 0.85rem; - color: var(--text-secondary); - line-height: 1.7; - margin-bottom: 0.5rem; -} - -#timeline-subtitle { - font-family: var(--font-mono); - font-size: 0.6rem; - color: var(--accent-electric); - letter-spacing: 0.1em; - text-transform: uppercase; - margin-bottom: 1rem !important; -} - -/* --- CAPABILITY CARDS ENHANCED --- */ -.capabilities-grid { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 2rem; - max-width: 1400px; - margin: 4rem auto 0; -} - -.capability-card { - background: var(--bg-surface); - border: 1px solid var(--border-glass); - border-radius: 24px; - padding: 2.5rem; - position: relative; - overflow: hidden; - transition: all 0.5s var(--ease-apple); - text-align: left; -} - -.capability-card::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 1px; - background: linear-gradient(90deg, transparent, var(--accent-electric), transparent); - opacity: 0; - transition: opacity 0.5s; -} - -.capability-card:hover::before { - opacity: 1; -} - -.capability-card:hover { - border-color: rgba(0, 229, 255, 0.3); - transform: translateY(-8px); - box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5); -} - -.capability-icon { - font-size: 2rem; - margin-bottom: 1.5rem; -} - -.capability-stat { - font-size: 2.5rem; - font-weight: 900; - letter-spacing: -0.04em; - background: linear-gradient(135deg, #fff, var(--accent-electric)); - -webkit-background-clip: text; - background-clip: text; - -webkit-text-fill-color: transparent; - margin-bottom: 1rem; -} - -.capability-tags { - display: flex; - gap: 0.5rem; - flex-wrap: wrap; - margin-top: 1.5rem; -} - -/* --- NAV ENHANCEMENTS --- */ -.nav-links a[href="#lab"] { - color: var(--accent-gold); -} - -/* ============================================================ - RESPONSIVE — MASTER BLUEPRINT V6 - ============================================================ */ -@media (max-width: 1024px) { - .lab-projects-grid { - grid-template-columns: 1fr; - } - - .geoai-content-grid { - grid-template-columns: 1fr; - } - - .challenges-grid, - .challenge-header, - .challenge-row { - grid-template-columns: 1fr; - } - - .challenge-cell:last-child { - border-left: none; - border-top: 1px solid rgba(0, 229, 255, 0.1); - } - - .arch-bottom-grid { - grid-template-columns: repeat(2, 1fr); - } - - .metrics-v6-grid { - grid-template-columns: 1fr; - } - - .metric-v6-card:nth-child(2), - .metric-v6-card:nth-child(3), - .metric-v6-card:nth-child(4) { - border: none; - border-top: 1px solid var(--border-glass); - } - - .timeline-wrapper { - grid-template-columns: 1fr; - } - - .capabilities-grid { - grid-template-columns: 1fr; - } -} - -@media (max-width: 768px) { - .main-header { - padding: 1rem 5%; - } - - .logo-text { - font-size: 1.2rem; - } - - .nav-links { - display: none; - /* Hide standard nav on mobile, would need a hamburger menu in an ideal world, but let's just scale things down */ - } - - .hero-content { - padding-top: 6rem; - } - - h1, - .hero-content h1 { - font-size: 2.5rem !important; - line-height: 1.1; - } - - .hero-desc { - font-size: 1rem !important; - margin-bottom: 2rem; - } - - .hero-btn-group { - flex-direction: column; - gap: 1rem !important; - } - - .cv-modal { - width: 95%; - padding: 2rem 1rem; - } - - .cv-container { - grid-template-columns: 1fr; - gap: 2rem; - } - - .bento-grid, - #projects .bento-item, - .metrics-grid, - .arch-bottom-grid { - grid-template-columns: 1fr !important; - height: auto !important; - flex-direction: column !important; - } - - .timeline-content-display { - padding: 1.5rem; - } - - .metric-v6-card { - padding: 1.5rem; - flex-direction: column; - text-align: center; - gap: 1rem; - } - - .project-hero { - padding-top: 6rem; - } - - .project-hero h1 { - font-size: 2rem !important; - } - - /* Enforce column flex on previously mapped flex rows */ - div[style*="display: flex; gap: 8rem;"] { - gap: 4rem !important; - } - - .bento-item>div:first-child { - padding: 2rem !important; - } - - .bento-item img { - width: 200px !important; - margin: 2rem 0; - } -} - -@media (max-width: 480px) { - .cv-card { - padding: 1.5rem; - } - - .skill-tags { - flex-direction: column; - gap: 0.5rem; - } - - .section-title { - font-size: 1.8rem; - } - - .metric-num, - .capability-stat { - font-size: 2rem; - } - - .validator-parcels { - grid-template-columns: repeat(2, 1fr) !important; - } - - .geoai-container { - height: 250px !important; - margin-bottom: 2rem; - } - - .slider-image-before, - .slider-image-after { - height: 250px !important; - } -} - -/* --- SECURITY & UTILITIES --- */ -.hover-lift { - transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275), box-shadow 0.4s ease, border-color 0.4s ease; -} - -.hover-lift:hover { - transform: translateY(-8px) scale(1.02); - box-shadow: 0 15px 40px rgba(0, 229, 255, 0.15); - border-color: var(--accent-electric); -} - -.hover-lift.gold-accent:hover { - box-shadow: 0 15px 40px rgba(255, 180, 0, 0.15); - border-color: var(--accent-gold); -} - -/* ANTI-EXTRACT SHIELD: prevents text selection, drag, and highlight */ -.dgz-secure-shield { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-user-drag: none; -} - -/* ============================================================ - GIS WORKSTATION — ArcGIS Pro / QGIS Inspired Interface - ============================================================ */ - -.gis-mono { - font-family: var(--font-mono); - font-size: 0.6rem; - letter-spacing: 0.05em; - text-transform: uppercase; - color: rgba(255,255,255,0.4); -} - -.gis-workstation { - width: 100%; - background: #050508; - border: 1px solid rgba(0,229,255,0.1); - border-left: none; - border-right: none; - display: flex; - flex-direction: column; - height: 780px; -} - -/* TOP TOOLBAR */ -.gis-toolbar { - height: 44px; - background: #0a0a0f; - border-bottom: 1px solid rgba(255,255,255,0.06); - display: flex; - align-items: center; - gap: 1.5rem; - padding: 0 1rem; - flex-shrink: 0; -} - -.gis-toolbar-brand { - display: flex; - align-items: center; - gap: 0.6rem; - padding-right: 1.5rem; - border-right: 1px solid rgba(255,255,255,0.06); - white-space: nowrap; -} - -.gis-status-dot { - width: 6px; height: 6px; - background: #4ade80; - border-radius: 50%; - animation: pulse2 1.5s infinite; - flex-shrink: 0; -} - -.gis-toolbar-tools { - display: flex; - align-items: center; - gap: 2px; - flex: 1; -} - -.gis-tool { - display: flex; - align-items: center; - gap: 0.4rem; - padding: 0.3rem 0.7rem; - background: transparent; - border: 1px solid transparent; - border-radius: 6px; - color: rgba(255,255,255,0.5); - font-family: var(--font-mono); - font-size: 0.55rem; - letter-spacing: 0.05em; - cursor: pointer; - transition: all 0.2s; - white-space: nowrap; -} - -.gis-tool i { font-size: 0.9rem; } - -.gis-tool:hover { - background: rgba(255,255,255,0.05); - color: #fff; - border-color: rgba(255,255,255,0.1); -} - -.gis-tool.active { - background: rgba(0,229,255,0.1); - border-color: rgba(0,229,255,0.3); - color: #00e5ff; -} - -.gis-toolbar-coords { - display: flex; - align-items: center; - gap: 0.5rem; - margin-left: auto; - padding-left: 1rem; - border-left: 1px solid rgba(255,255,255,0.06); - white-space: nowrap; -} - -.gis-coord-val { - font-family: var(--font-mono); - font-size: 0.6rem; - color: #00e5ff; -} - -/* MAIN AREA */ -.gis-main { - display: grid; - grid-template-columns: 230px 1fr 220px; - flex: 1; - overflow: hidden; -} - -/* PANELS */ -.gis-panel { - background: #07070b; - border-color: rgba(255,255,255,0.06); - display: flex; - flex-direction: column; - overflow: hidden; -} - -.gis-panel-left { - border-right: 1px solid rgba(255,255,255,0.06); -} - -.gis-panel-right { - border-left: 1px solid rgba(255,255,255,0.06); -} - -.gis-panel-header { - display: flex; - align-items: center; - gap: 0.5rem; - padding: 0.6rem 0.8rem; - background: rgba(255,255,255,0.02); - border-bottom: 1px solid rgba(255,255,255,0.06); - font-family: var(--font-mono); - font-size: 0.55rem; - color: rgba(255,255,255,0.5); - letter-spacing: 0.1em; - text-transform: uppercase; - flex-shrink: 0; -} - -.gis-panel-header i { font-size: 0.9rem; color: #00e5ff; } - -.gis-panel-toggle { - margin-left: auto; - background: none; - border: none; - color: rgba(255,255,255,0.3); - cursor: pointer; - font-size: 0.8rem; - padding: 0 0.2rem; - transition: color 0.2s; -} -.gis-panel-toggle:hover { color: #00e5ff; } - -.gis-panel-section { - padding: 0.8rem; - border-bottom: 1px solid rgba(255,255,255,0.04); -} - -.gis-panel-label { - font-family: var(--font-mono); - font-size: 0.5rem; - color: rgba(255,255,255,0.25); - letter-spacing: 0.15em; - text-transform: uppercase; - margin-bottom: 0.6rem; -} - -/* Basemap buttons */ -.gis-basemap-btns { - display: flex; - flex-direction: column; - gap: 0.3rem; -} - -.gis-basemap-btn { - display: flex; - align-items: center; - gap: 0.5rem; - background: transparent; - border: 1px solid rgba(255,255,255,0.05); - border-radius: 6px; - padding: 0.4rem 0.6rem; - color: rgba(255,255,255,0.5); - font-family: var(--font-mono); - font-size: 0.55rem; - cursor: pointer; - transition: all 0.2s; - text-align: left; -} - -.gis-basemap-btn:hover { - border-color: rgba(0,229,255,0.3); - color: #fff; -} - -.gis-basemap-btn.active { - border-color: rgba(0,229,255,0.4); - background: rgba(0,229,255,0.05); - color: #00e5ff; -} - -.basemap-preview { - width: 24px; height: 16px; - border-radius: 3px; - flex-shrink: 0; -} -.dark-preview { background: linear-gradient(135deg, #0a0a0f, #111); } -.sat-preview { background: linear-gradient(135deg, #1a3a1a, #2d5a2d); } -.topo-preview { background: linear-gradient(135deg, #2a2a4a, #1a1a3a); } - -/* Layer list */ -.gis-layer-list { display: flex; flex-direction: column; gap: 0.2rem; } - -.gis-layer-item { - display: flex; - align-items: center; - justify-content: space-between; - padding: 0.35rem 0.4rem; - border-radius: 5px; - transition: background 0.2s; -} - -.gis-layer-item:hover { background: rgba(255,255,255,0.03); } - -.gis-layer-toggle { - display: flex; - align-items: center; - gap: 0.5rem; - cursor: pointer; - font-family: var(--font-mono); - font-size: 0.55rem; - color: rgba(255,255,255,0.6); -} - -.gis-layer-toggle input[type="checkbox"] { - appearance: none; - width: 12px; height: 12px; - border: 1px solid rgba(255,255,255,0.2); - border-radius: 2px; - background: transparent; - cursor: pointer; - position: relative; - flex-shrink: 0; -} - -.gis-layer-toggle input:checked { - background: rgba(0,229,255,0.3); - border-color: #00e5ff; -} - -.gis-layer-toggle input:checked::after { - content: '✓'; - position: absolute; - top: -1px; left: 1px; - font-size: 0.5rem; - color: #00e5ff; -} - -.gis-layer-icon { - width: 14px; height: 10px; - border-radius: 2px; - flex-shrink: 0; -} - -.gis-layer-actions { display: flex; gap: 0.2rem; } - -.gis-layer-btn { - background: none; - border: none; - color: rgba(255,255,255,0.2); - cursor: pointer; - font-size: 0.65rem; - padding: 0 0.2rem; - transition: color 0.2s; -} -.gis-layer-btn:hover { color: #00e5ff; } - -/* Legend */ -.gis-legend { display: flex; flex-direction: column; gap: 0.4rem; } - -.legend-item { - display: flex; - align-items: center; - gap: 0.5rem; - font-family: var(--font-mono); - font-size: 0.5rem; - color: rgba(255,255,255,0.4); -} - -.legend-symbol { - width: 14px; height: 10px; - flex-shrink: 0; -} - -/* Projection info */ -.gis-proj-info { - display: flex; - flex-direction: column; - gap: 0.3rem; - font-size: 0.55rem; - line-height: 1.6; - color: rgba(255,255,255,0.3); -} - -/* MAP CONTAINER */ -.gis-map-container { - position: relative; - overflow: hidden; -} - -/* Zoom controls */ -.gis-zoom-controls { - position: absolute; - right: 12px; - top: 50%; - transform: translateY(-50%); - z-index: 500; - background: rgba(10,10,15,0.85); - -webkit-backdrop-filter: blur(10px); - backdrop-filter: blur(10px); - border: 1px solid rgba(255,255,255,0.08); - border-radius: 8px; - overflow: hidden; -} - -.gis-zoom-btn { - display: block; - width: 32px; height: 32px; - background: transparent; - border: none; - color: rgba(255,255,255,0.6); - font-size: 1.1rem; - cursor: pointer; - transition: all 0.2s; - line-height: 32px; - text-align: center; -} -.gis-zoom-btn:hover { background: rgba(0,229,255,0.1); color: #00e5ff; } - -.gis-zoom-sep { - height: 1px; - background: rgba(255,255,255,0.06); -} - -/* Scale bar */ -.gis-scalebar { - position: absolute; - bottom: 14px; - left: 14px; - z-index: 500; - display: flex; - flex-direction: column; - gap: 2px; -} - -.scalebar-line { - height: 4px; - width: 80px; - background: linear-gradient(90deg, #00e5ff 50%, rgba(0,229,255,0.2) 50%); - border: 1px solid rgba(0,229,255,0.4); - border-radius: 2px; -} - -.scalebar-label { - font-size: 0.5rem; - color: rgba(255,255,255,0.5); -} - -/* Measure widget */ -.gis-measure-widget { - position: absolute; - top: 12px; - left: 12px; - z-index: 600; - background: rgba(5,5,15,0.9); - -webkit-backdrop-filter: blur(20px); - backdrop-filter: blur(20px); - border: 1px solid rgba(0,229,255,0.3); - border-radius: 10px; - padding: 1rem; - min-width: 180px; -} - -.gis-clear-measure { - margin-top: 0.8rem; - width: 100%; - background: rgba(255,75,43,0.1); - border: 1px solid rgba(255,75,43,0.3); - color: #ff4b2b; - border-radius: 4px; - padding: 0.3rem; - cursor: pointer; - font-family: var(--font-mono); - font-size: 0.55rem; - letter-spacing: 0.1em; - transition: all 0.2s; -} -.gis-clear-measure:hover { background: rgba(255,75,43,0.2); } - -/* Identify hint */ -.gis-identify-hint { - position: absolute; - top: 12px; left: 50%; - transform: translateX(-50%); - background: rgba(0,0,0,0.85); - border: 1px solid rgba(0,229,255,0.4); - border-radius: 8px; - padding: 0.5rem 1rem; - font-family: var(--font-mono); - font-size: 0.6rem; - color: #00e5ff; - z-index: 600; - display: flex; - align-items: center; - gap: 0.5rem; - animation: fadeInSlide 0.3s ease; - -webkit-backdrop-filter: blur(10px); - backdrop-filter: blur(10px); -} - -@keyframes fadeInSlide { - from { opacity: 0; transform: translateX(-50%) translateY(-8px); } - to { opacity: 1; transform: translateX(-50%) translateY(0); } -} - -/* Attribute panel */ -.attr-system-id { - font-size: 0.55rem; - color: #00e5ff; - background: rgba(0,229,255,0.05); - border: 1px solid rgba(0,229,255,0.15); - border-radius: 5px; - padding: 0.4rem 0.6rem; - margin-bottom: 0.8rem; -} - -.attr-table { - display: flex; - flex-direction: column; - gap: 1px; - margin-bottom: 1rem; -} - -.attr-row { - display: grid; - grid-template-columns: 45% 55%; - border-radius: 3px; - overflow: hidden; - border: 1px solid rgba(255,255,255,0.04); -} - -.attr-key { - padding: 0.3rem 0.4rem; - background: rgba(255,255,255,0.02); - font-family: var(--font-mono); - font-size: 0.5rem; - color: rgba(255,255,255,0.3); - letter-spacing: 0.05em; - border-right: 1px solid rgba(255,255,255,0.04); -} - -.attr-val { - padding: 0.3rem 0.4rem; - font-family: var(--font-mono); - font-size: 0.5rem; - color: rgba(255,255,255,0.7); -} - -.attr-actions { - display: flex; - gap: 0.4rem; -} - -.attr-action-btn { - flex: 1; - background: rgba(255,255,255,0.03); - border: 1px solid rgba(255,255,255,0.08); - border-radius: 6px; - color: rgba(255,255,255,0.5); - font-family: var(--font-mono); - font-size: 0.5rem; - padding: 0.4rem; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - gap: 0.3rem; - transition: all 0.2s; -} - -.attr-action-btn:hover { - background: rgba(0,229,255,0.1); - border-color: rgba(0,229,255,0.3); - color: #00e5ff; -} - -.attr-action-btn i { font-size: 0.8rem; } - -/* Map stats */ -.gis-map-stats { - margin-top: auto; - padding: 0.8rem; - border-top: 1px solid rgba(255,255,255,0.04); -} - -.gis-stat-row { - display: flex; - justify-content: space-between; - padding: 0.25rem 0; - border-bottom: 1px solid rgba(255,255,255,0.03); - font-size: 0.55rem; -} - -/* STATUS BAR */ -.gis-statusbar { - height: 24px; - background: #050508; - border-top: 1px solid rgba(255,255,255,0.06); - display: flex; - align-items: center; - gap: 1rem; - padding: 0 1rem; - font-size: 0.5rem; - overflow: hidden; - flex-shrink: 0; -} - -.gis-clock { - color: rgba(255,255,255,0.3); - letter-spacing: 0.05em; -} - -/* Custom Leaflet popup override for GIS */ -.leaflet-popup-content-wrapper { - background: rgba(5,5,15,0.95) !important; - border: 1px solid rgba(0,229,255,0.3) !important; - border-radius: 12px !important; - -webkit-backdrop-filter: blur(20px) !important; - backdrop-filter: blur(20px) !important; - box-shadow: 0 8px 32px rgba(0,0,0,0.8), 0 0 20px rgba(0,229,255,0.1) !important; - color: #fff !important; -} - -.leaflet-popup-tip { background: rgba(5,5,15,0.95) !important; } -.leaflet-popup-close-button { color: rgba(255,255,255,0.4) !important; } -.leaflet-popup-close-button:hover { color: #00e5ff !important; } - -.gis-popup-header { - font-family: var(--font-mono); - font-size: 0.55rem; - color: #00e5ff; - letter-spacing: 0.15em; - text-transform: uppercase; - margin-bottom: 0.6rem; - padding-bottom: 0.4rem; - border-bottom: 1px solid rgba(0,229,255,0.15); -} - -.gis-popup-title { - font-size: 0.9rem; - font-weight: 800; - letter-spacing: -0.02em; - margin-bottom: 0.8rem; -} - -.gis-popup-table { width: 100%; border-collapse: collapse; } -.gis-popup-table td { - font-family: var(--font-mono); - font-size: 0.5rem; - padding: 0.25rem 0.3rem; - border-bottom: 1px solid rgba(255,255,255,0.04); - vertical-align: top; -} - -.gis-popup-table td:first-child { color: rgba(255,255,255,0.3); width: 45%; } -.gis-popup-table td:last-child { color: rgba(255,255,255,0.8); } - -/* GIS Responsive */ -@media (max-width: 900px) { - .gis-main { grid-template-columns: 1fr; } - .gis-panel-left, .gis-panel-right { display: none; } - .gis-workstation { height: 550px; } - .gis-toolbar-tools span { display: none; } - .gis-toolbar-coords { display: none; } -} - -/* ============================================================ - PRICING — ENTERPRISE COMMERCIAL ENGINE - ============================================================ */ - -.pricing-section { - padding: 10rem 5%; - background: var(--bg-base); - position: relative; - overflow: hidden; -} - -.pricing-bg-deco { - position: absolute; - inset: 0; - background: - radial-gradient(ellipse at 20% 50%, rgba(0,229,255,0.04) 0%, transparent 60%), - radial-gradient(ellipse at 80% 50%, rgba(157,78,221,0.04) 0%, transparent 60%); - pointer-events: none; -} - -.pricing-header { - text-align: center; - margin-bottom: 3rem; -} - -.pricing-header-tag { - display: inline-flex; - align-items: center; - gap: 0.5rem; - font-family: var(--font-mono); - font-size: 0.6rem; - color: rgba(255,255,255,0.4); - letter-spacing: 0.2em; - margin-bottom: 1.5rem; -} - -.pricing-title { - font-size: clamp(2.5rem, 5vw, 4.5rem) !important; - margin-bottom: 1.5rem; -} - -.pricing-subtitle { - color: var(--text-secondary); - max-width: 600px; - margin: 0 auto 3rem; - font-size: 1.05rem; - line-height: 1.8; -} - -/* ROI Strip */ -.pricing-roi-strip { - display: flex; - align-items: center; - justify-content: center; - gap: 0; - max-width: 900px; - margin: 0 auto; - background: rgba(255,255,255,0.02); - border: 1px solid rgba(255,255,255,0.06); - border-radius: 20px; - overflow: hidden; -} - -.roi-stat { - flex: 1; - padding: 1.5rem; - text-align: center; -} - -.roi-val { - font-size: 1.8rem; - font-weight: 900; - color: #00e5ff; - letter-spacing: -0.04em; - font-family: var(--font-mono); - line-height: 1; - margin-bottom: 0.3rem; -} - -.roi-label { - font-size: 0.65rem; - color: rgba(255,255,255,0.4); - text-transform: uppercase; - letter-spacing: 0.08em; -} - -.roi-divider { - width: 1px; - height: 50px; - background: rgba(255,255,255,0.06); - flex-shrink: 0; -} - -/* COMPARE */ -.pricing-compare { - display: grid; - grid-template-columns: 1fr auto 1fr; - align-items: center; - gap: 2rem; - max-width: 900px; - margin: 4rem auto; -} - -.compare-col { - background: rgba(255,255,255,0.02); - border: 1px solid rgba(255,255,255,0.06); - border-radius: 20px; - padding: 2rem; -} - -.compare-col.compare-after { - border-color: rgba(74,222,128,0.2); - background: rgba(74,222,128,0.02); -} - -.compare-header { margin-bottom: 1.2rem; } - -.compare-badge { - font-family: var(--font-mono); - font-size: 0.55rem; - letter-spacing: 0.1em; - padding: 0.3rem 0.8rem; - border-radius: 100px; - text-transform: uppercase; -} - -.compare-badge.bad { background: rgba(255,75,43,0.1); color: #ff4b2b; border: 1px solid rgba(255,75,43,0.2); } -.compare-badge.good { background: rgba(74,222,128,0.1); color: #4ade80; border: 1px solid rgba(74,222,128,0.2); } - -.compare-list { - list-style: none; - display: flex; - flex-direction: column; - gap: 0.6rem; - font-size: 0.85rem; - color: rgba(255,255,255,0.5); -} - -.compare-list li { display: flex; align-items: center; gap: 0.6rem; } - -.cmp-x { color: #ff4b2b; font-weight: 900; } -.cmp-ok { color: #4ade80; font-weight: 900; } - -.compare-vs { - font-family: var(--font-mono); - font-size: 1.2rem; - font-weight: 900; - color: rgba(255,255,255,0.15); - text-align: center; - flex-shrink: 0; -} - -/* PLAN CARDS */ -.pricing-plans { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 1.5rem; - max-width: 1200px; - margin: 0 auto 4rem; - align-items: start; -} - -.plan-card { - background: rgba(255,255,255,0.02); - border: 1px solid rgba(255,255,255,0.06); - border-radius: 28px; - padding: 2.5rem; - display: flex; - flex-direction: column; - gap: 0; - position: relative; - overflow: hidden; - transition: all 0.4s var(--ease-apple); -} - -.plan-card:hover { - border-color: rgba(255,255,255,0.12); - transform: translateY(-5px); - box-shadow: 0 20px 50px rgba(0,0,0,0.5); -} - -.plan-card.plan-featured { - border-color: rgba(0,229,255,0.3); - background: rgba(0,229,255,0.02); - transform: scale(1.03); -} - -.plan-card.plan-featured:hover { - border-color: rgba(0,229,255,0.5); - box-shadow: 0 20px 60px rgba(0,229,255,0.1); - transform: scale(1.03) translateY(-5px); -} - -.plan-card.plan-gold { - border-color: rgba(255,180,0,0.15); -} - -.plan-card.plan-gold:hover { - border-color: rgba(255,180,0,0.3); - box-shadow: 0 20px 50px rgba(255,180,0,0.08); -} - -/* Beam effect for featured card */ -.plan-beam { - position: absolute; - top: 0; left: 0; right: 0; - height: 2px; - background: linear-gradient(90deg, transparent, #00e5ff, #9D4EDD, transparent); - animation: beamSlide 3s ease-in-out infinite; -} - -@keyframes beamSlide { - 0%, 100% { opacity: 0.6; } - 50% { opacity: 1; } -} - -.plan-popular-badge { - position: absolute; - top: -1px; - left: 50%; - transform: translateX(-50%); - background: linear-gradient(90deg, #00e5ff, #9D4EDD); - color: #000; - font-family: var(--font-mono); - font-size: 0.55rem; - font-weight: 900; - padding: 0.3rem 1.2rem; - border-radius: 0 0 12px 12px; - letter-spacing: 0.1em; - white-space: nowrap; -} - -.plan-tier { - font-family: var(--font-mono); - font-size: 0.55rem; - color: rgba(255,255,255,0.3); - letter-spacing: 0.2em; - text-transform: uppercase; - margin-bottom: 0.8rem; - margin-top: 1rem; -} - -.plan-name { - font-size: 1.6rem; - font-weight: 900; - letter-spacing: -0.04em; - margin-bottom: 0.4rem; -} - -.plan-for { - font-size: 0.8rem; - color: var(--text-secondary); - margin-bottom: 1.5rem; - line-height: 1.5; -} - -.plan-price { - display: flex; - align-items: baseline; - gap: 0.5rem; - margin-bottom: 1.2rem; -} - -.price-amount { - font-size: 3rem; - font-weight: 900; - letter-spacing: -0.05em; - line-height: 1; -} - -.price-period { - font-size: 0.75rem; - color: rgba(255,255,255,0.4); -} - -/* Capacity bar */ -.plan-capacity { margin-bottom: 1.5rem; } - -.capacity-label { - font-family: var(--font-mono); - font-size: 0.5rem; - color: rgba(255,255,255,0.3); - margin-bottom: 0.4rem; -} - -.capacity-bar { - height: 4px; - background: rgba(255,255,255,0.05); - border-radius: 2px; - overflow: hidden; -} - -.capacity-fill { - height: 100%; - border-radius: 2px; - transition: width 1s ease; -} - -/* Features */ -.plan-features { - list-style: none; - display: flex; - flex-direction: column; - gap: 0.6rem; - margin-bottom: 2rem; - flex: 1; -} - -.plan-features li { - display: flex; - align-items: center; - gap: 0.6rem; - font-size: 0.82rem; - color: rgba(255,255,255,0.6); -} - -.plan-features li i { font-size: 0.9rem; flex-shrink: 0; } - -.feat-ok i { color: rgba(255,255,255,0.3); } -.feat-no { opacity: 0.35; } -.feat-no i { color: rgba(255,75,43,0.5); } -.feat-cyan i { color: #00e5ff; } -.feat-cyan { color: rgba(255,255,255,0.8); } -.feat-gold i { color: #ffb400; } -.feat-gold { color: rgba(255,255,255,0.8); } - -/* Plan buttons */ -.plan-btn { - display: flex; - align-items: center; - justify-content: center; - gap: 0.5rem; - padding: 0.9rem 1.5rem; - border-radius: 12px; - font-family: var(--font-mono); - font-size: 0.65rem; - letter-spacing: 0.1em; - text-decoration: none; - text-transform: uppercase; - cursor: pointer; - border: none; - transition: all 0.3s; - margin-bottom: 0.8rem; -} - -.plan-btn i { font-size: 1rem; } - -.plan-btn-ghost { - background: rgba(255,255,255,0.04); - border: 1px solid rgba(255,255,255,0.1); - color: rgba(255,255,255,0.7); -} -.plan-btn-ghost:hover { - background: rgba(255,255,255,0.08); - color: #fff; - border-color: rgba(255,255,255,0.2); -} - -.plan-btn-primary { - background: linear-gradient(135deg, #00e5ff, #9D4EDD); - color: #000; - font-weight: 900; - box-shadow: 0 4px 20px rgba(0,229,255,0.25); -} -.plan-btn-primary:hover { - transform: translateY(-2px); - box-shadow: 0 8px 30px rgba(0,229,255,0.4); -} - -.plan-btn-gold { - background: rgba(255,180,0,0.1); - border: 1px solid rgba(255,180,0,0.3); - color: #ffb400; -} -.plan-btn-gold:hover { - background: rgba(255,180,0,0.15); - border-color: rgba(255,180,0,0.5); - transform: translateY(-2px); -} - -.plan-trust { - font-size: 0.5rem; - color: rgba(255,255,255,0.25); - text-align: center; - letter-spacing: 0.05em; -} - -/* TRUST STRIP */ -.trust-strip { - display: flex; - align-items: center; - justify-content: center; - gap: 0; - max-width: 1000px; - margin: 0 auto; - border: 1px solid rgba(255,255,255,0.05); - border-radius: 16px; - background: rgba(255,255,255,0.01); - padding: 1.5rem 2rem; -} - -.trust-item { - flex: 1; - display: flex; - align-items: center; - justify-content: center; - gap: 0.6rem; - font-family: var(--font-mono); - font-size: 0.6rem; - color: rgba(255,255,255,0.5); - letter-spacing: 0.05em; - text-align: center; -} - -.trust-divider { - width: 1px; - height: 30px; - background: rgba(255,255,255,0.06); - flex-shrink: 0; -} - -/* Pricing Responsive */ -@media (max-width: 1100px) { - .pricing-plans { grid-template-columns: 1fr; max-width: 480px; } - .plan-card.plan-featured { transform: none; } - .pricing-compare { grid-template-columns: 1fr; } - .compare-vs { display: none; } - .trust-strip { flex-wrap: wrap; gap: 1rem; } -} -/* ==================================================================== - UPGRADES V6.5 Hero, Timeline V2, Contact V2, Footer V2, Fullscreen - ==================================================================== */ - -/* HERO: Availability Tag (replaces identity badge) */ -.hero-availability-tag { - display: inline-flex; - align-items: center; - gap: 0.6rem; - background: rgba(74,222,128,0.08); - border: 1px solid rgba(74,222,128,0.25); - padding: 0.4rem 1rem; - border-radius: 100px; - font-family: var(--font-mono); - font-size: 0.6rem; - color: #4ade80; - letter-spacing: 0.08em; - margin-bottom: 1.5rem; -} -.avail-dot { - width: 6px; - height: 6px; - background: #4ade80; - border-radius: 50%; - animation: pulse-green 1.5s ease infinite; - flex-shrink: 0; -} -@keyframes pulse-green { - 0%, 100% { box-shadow: 0 0 0 0 rgba(74,222,128,0.5); } - 50% { box-shadow: 0 0 0 6px rgba(74,222,128,0); } -} - -/* ===================================================== - TIMELINE V2 Vertical Rich Cards - ===================================================== */ -.timeline-v2 { - display: flex; - flex-direction: column; - gap: 0; - max-width: 900px; -} - -.tlv2-item { - display: grid; - grid-template-columns: 40px 1fr; - gap: 0 2rem; - position: relative; - padding-bottom: 3rem; -} -.tlv2-item:last-child { padding-bottom: 0; } - -.tlv2-marker { - display: flex; - flex-direction: column; - align-items: center; - position: relative; -} -.tlv2-dot-outer { - width: 16px; - height: 16px; - border-radius: 50%; - background: rgba(0,229,255,0.1); - border: 2px solid rgba(0,229,255,0.4); - display: flex; - align-items: center; - justify-content: center; - flex-shrink: 0; - z-index: 2; - margin-top: 3px; -} -.tlv2-item.active-node .tlv2-dot-outer { - border-color: #4ade80; - background: rgba(74,222,128,0.15); - box-shadow: 0 0 12px rgba(74,222,128,0.4); - animation: pulse-green 2s ease infinite; -} -.tlv2-dot-inner { - width: 7px; - height: 7px; - border-radius: 50%; - background: rgba(0,229,255,0.8); -} -.tlv2-item.active-node .tlv2-dot-inner { - background: #4ade80; -} -.tlv2-line { - width: 1px; - flex: 1; - background: linear-gradient(to bottom, rgba(0,229,255,0.2), transparent); - margin-top: 4px; -} - -.tlv2-card { - background: rgba(255,255,255,0.02); - border: 1px solid rgba(255,255,255,0.06); - border-radius: 16px; - padding: 1.5rem 2rem; - transition: border-color 0.3s, background 0.3s; -} -.tlv2-card:hover { - border-color: rgba(0,229,255,0.2); - background: rgba(0,229,255,0.03); -} -.tlv2-item.active-node .tlv2-card { - border-color: rgba(74,222,128,0.2); - background: rgba(74,222,128,0.03); -} - -.tlv2-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 0.6rem; - flex-wrap: wrap; - gap: 0.5rem; -} -.tlv2-period { - color: rgba(255,255,255,0.4); - font-size: 0.55rem !important; -} -.tlv2-badge { - font-family: var(--font-mono); - font-size: 0.5rem; - padding: 0.2rem 0.6rem; - border-radius: 100px; - letter-spacing: 0.08em; -} -.tlv2-badge.active { - color: #4ade80; - background: rgba(74,222,128,0.1); - border: 1px solid rgba(74,222,128,0.3); -} -.tlv2-badge.done { - color: rgba(255,255,255,0.4); - background: rgba(255,255,255,0.04); - border: 1px solid rgba(255,255,255,0.08); -} -.tlv2-role { - font-size: 1.15rem; - font-weight: 800; - letter-spacing: -0.02em; - color: #fff; - margin-bottom: 0.3rem; -} -.tlv2-company { - font-family: var(--font-mono); - font-size: 0.6rem; - color: var(--accent-electric); - letter-spacing: 0.05em; - margin-bottom: 0.8rem; -} -.tlv2-city { - color: rgba(255,255,255,0.3); -} -.tlv2-desc { - font-size: 0.9rem; - color: var(--text-secondary); - line-height: 1.7; - margin-bottom: 1rem; -} -.tlv2-pills { - display: flex; - flex-wrap: wrap; - gap: 0.4rem; -} -.tlv2-pills span { - font-family: var(--font-mono); - font-size: 0.5rem; - padding: 0.2rem 0.6rem; - border-radius: 4px; - background: rgba(0,229,255,0.06); - border: 1px solid rgba(0,229,255,0.15); - color: rgba(0,229,255,0.7); - letter-spacing: 0.05em; - text-transform: uppercase; -} -@media (max-width: 768px) { - .tlv2-item { grid-template-columns: 28px 1fr; gap: 0 1rem; } - .tlv2-role { font-size: 1rem; } - .tlv2-card { padding: 1rem 1.2rem; } -} - -/* ===================================================== - MAP FULLSCREEN - ===================================================== */ -.gis-workstation.fullscreen-mode { - position: fixed; - inset: 0; - z-index: 9999; - height: 100vh !important; - border-radius: 0; -} -.gis-btn-fullscreen { - margin-left: auto; - background: rgba(0,229,255,0.08); - border: 1px solid rgba(0,229,255,0.2); - color: var(--accent-electric); - font-family: var(--font-mono); - font-size: 0.55rem; - padding: 0.3rem 0.7rem; - border-radius: 6px; - cursor: pointer; - display: flex; - align-items: center; - gap: 0.4rem; - transition: all 0.2s; - letter-spacing: 0.05em; -} -.gis-btn-fullscreen:hover { - background: rgba(0,229,255,0.15); - border-color: var(--accent-electric); -} - -/* ===================================================== - CONTACT V2 Enterprise Grid - ===================================================== */ -.contact-section-v2 { - padding: 12rem 5%; - position: relative; - background: radial-gradient(circle at top right, rgba(0, 210, 255, 0.03), transparent 40%); -} - -.contact-portal-v2 { - display: grid; - grid-template-columns: 1fr 1.1fr; - gap: 6rem; - align-items: start; - margin-top: 4rem; -} - -.contact-big-title { - font-size: clamp(3rem, 6vw, 4.5rem); - letter-spacing: -0.06em; - line-height: 0.9; - font-weight: 900; - margin-bottom: 1.5rem; - background: linear-gradient(to bottom, #fff 40%, rgba(255,255,255,0.4)); - -webkit-background-clip: text; - background-clip: text; - -webkit-text-fill-color: transparent; -} - -.contact-lead { - color: var(--text-secondary); - font-size: 1.15rem; - line-height: 1.8; - margin-bottom: 2.5rem; - max-width: 450px; -} - -.contact-cards-grid { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 1.2rem; - margin-bottom: 2.5rem; -} - -.contact-card { - background: rgba(255, 255, 255, 0.02); - border: 1px solid rgba(255, 255, 255, 0.08); - border-radius: 20px; - padding: 1.5rem; - text-decoration: none; - transition: all 0.5s var(--ease-apple); - position: relative; - overflow: hidden; -} - -.contact-card::before { - content: ''; - position: absolute; - inset: 0; - background: radial-gradient(circle at var(--mouse-x, 50%) var(--mouse-y, 50%), rgba(0, 210, 255, 0.1), transparent 100%); - opacity: 0; - transition: opacity 0.3s; -} - -.contact-card:hover { - border-color: var(--accent-electric); - background: rgba(0, 210, 255, 0.03); - transform: translateY(-5px); - box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4); -} - -.contact-card:hover::before { opacity: 1; } - -.cc-icon { - font-size: 1.8rem; - margin-bottom: 0.8rem; - transition: transform 0.4s var(--ease-spring); -} - -.contact-card:hover .cc-icon { transform: scale(1.2) rotate(5deg); } - -.cc-label { - font-family: var(--font-mono); - font-size: 0.65rem; - color: rgba(255, 255, 255, 0.4); - letter-spacing: 0.1em; - text-transform: uppercase; - margin-bottom: 0.4rem; -} - -.cc-value { - font-size: 0.85rem; - color: #fff; - font-weight: 700; - word-break: break-all; -} - -.contact-form-col { - background: rgba(15, 20, 30, 0.4); - border: 1px solid rgba(255, 255, 255, 0.1); - border-radius: 32px; - padding: 3.5rem; - -webkit-backdrop-filter: blur(30px) saturate(180%); - backdrop-filter: blur(30px) saturate(180%); - position: relative; -} - -.contact-form-header { - font-family: var(--font-mono); - font-size: 0.7rem !important; - color: var(--accent-electric) !important; - margin-bottom: 2.5rem; - padding-bottom: 1.2rem; - border-bottom: 1px solid rgba(255, 255, 255, 0.08); - display: flex; - justify-content: space-between; - align-items: center; -} - -.portal-field { - margin-bottom: 2rem; - position: relative; -} - -.portal-field label { - display: block; - font-family: var(--font-mono); - font-size: 0.65rem; - color: rgba(255, 255, 255, 0.4); - text-transform: uppercase; - letter-spacing: 0.1em; - margin-bottom: 0.8rem; - transition: color 0.3s; -} - -.portal-input { - width: 100%; - background: rgba(255, 255, 255, 0.03); - border: 1px solid rgba(255, 255, 255, 0.1); - border-radius: 12px; - padding: 1.2rem; - color: #fff; - font-family: var(--font-main); - font-size: 1rem; - transition: all 0.4s var(--ease-apple); -} - -.portal-input:focus { - outline: none; - background: rgba(255, 255, 255, 0.05); - border-color: var(--accent-electric); - box-shadow: 0 0 20px rgba(0, 210, 255, 0.15); -} - -.portal-field:focus-within label { - color: var(--accent-electric); -} - -.btn-transmit { - width: 100%; - padding: 1.5rem; - background: linear-gradient(135deg, var(--accent-electric), #2563EB); - color: #000; - border-radius: 14px; - font-family: var(--font-mono); - font-size: 0.8rem; - font-weight: 900; - letter-spacing: 0.15em; - text-transform: uppercase; - display: flex; - align-items: center; - justify-content: center; - gap: 1rem; - cursor: pointer; - transition: all 0.5s var(--ease-spring); - position: relative; - overflow: hidden; -} - -.btn-transmit::before { - content: ''; - position: absolute; - inset: 0; - background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent); - transform: translateX(-100%); - transition: transform 0.6s; -} - -.btn-transmit:hover { - transform: translateY(-3px) scale(1.02); - box-shadow: 0 15px 35px rgba(0, 210, 255, 0.4); -} - -.btn-transmit:hover::before { - transform: translateX(100%); -} - -.btn-transmit i { font-size: 1.2rem; } - -@media (max-width: 1024px) { - .contact-portal-v2 { grid-template-columns: 1fr; gap: 4rem; } - .contact-big-title { font-size: 3.5rem; } -} - -@media (max-width: 768px) { - .contact-cards-grid { grid-template-columns: 1fr; } - .contact-form-col { padding: 2rem; } -} - -/* Expert Reveal System */ -.reveal { - opacity: 0; - transform: translateY(40px) scale(0.98); - transition: all 1s var(--ease-apple); - visibility: hidden; -} - -.reveal.revealed { - opacity: 1; - transform: translateY(0) scale(1); - visibility: visible; -} - -.reveal-left { transform: translateX(-40px); } -.reveal-right { transform: translateX(40px); } -.reveal-scale { transform: scale(0.9); } - -/* ===================================================== - FOOTER BOTTOM V2 Enterprise grade - ===================================================== */ -.footer-bottom-v2 { - border-top: 1px solid rgba(255,255,255,0.04); - padding: 1.5rem 5%; - display: flex; - align-items: center; - justify-content: space-between; - gap: 2rem; - flex-wrap: wrap; -} -.footer-bottom-left { - display: flex; - align-items: center; - gap: 1rem; -} -.fb-logo-mark { - font-family: var(--font-mono); - font-size: 0.7rem; - font-weight: 900; - color: rgba(0,229,255,0.4); - border: 1px solid rgba(0,229,255,0.15); - padding: 0.2rem 0.5rem; - border-radius: 4px; - letter-spacing: 0.15em; - flex-shrink: 0; -} -.fb-legal { - display: flex; - align-items: center; - gap: 0.6rem; - flex-wrap: wrap; - font-size: 0.55rem; - color: rgba(255,255,255,0.25); -} -.fb-sep { - color: rgba(255,255,255,0.1); -} -.footer-bottom-center { - flex: 1; - display: flex; - justify-content: center; -} -.fb-status-pill { - display: inline-flex; - align-items: center; - gap: 0.5rem; - border: 1px solid rgba(74,222,128,0.15); - padding: 0.3rem 0.8rem; - border-radius: 100px; - background: rgba(74,222,128,0.04); -} -.fb-status-dot { - width: 5px; - height: 5px; - background: #4ade80; - border-radius: 50%; - animation: pulse-green 2s ease infinite; - flex-shrink: 0; -} -.footer-bottom-right { - display: flex; - align-items: center; - gap: 0.8rem; - font-size: 0.5rem !important; -} -@media (max-width: 768px) { - .footer-bottom-v2 { flex-direction: column; text-align: center; gap: 1rem; } - .footer-bottom-center { width: 100%; } -} - -/* ==================================================================== - TIMELINE V3 Sophisticated Glassmorphism + Gradient Accent - ==================================================================== */ - -/* Override V2 with enhanced V3 styles (these take precedence) */ - -.timeline-v2 { - position: relative; - padding-left: 3.5rem; -} - -/* Continuous gradient accent line */ -.timeline-v2::before { - content: ''; - position: absolute; - left: 0; - top: 8px; - bottom: 0; - width: 2px; - background: linear-gradient( - to bottom, - #4ade80 0%, - rgba(0,229,255,0.6) 25%, - rgba(0,229,255,0.3) 50%, - rgba(0,229,255,0.15) 75%, - transparent 100% - ); - border-radius: 2px; -} - -/* Redo marker alignment fixed left column */ -.tlv2-item { - display: block; - position: relative; - padding-bottom: 2.5rem; - padding-left: 0; -} -.tlv2-item:last-child { padding-bottom: 0; } - -.tlv2-marker { - position: absolute; - left: -3.5rem; - top: 4px; - display: flex; - flex-direction: column; - align-items: center; - gap: 0; -} - -.tlv2-dot-outer { - width: 18px; - height: 18px; - border-radius: 50%; - background: rgba(2,2,5,1); - border: 2px solid rgba(0,229,255,0.4); - display: flex; - align-items: center; - justify-content: center; - z-index: 2; - box-shadow: 0 0 0 4px rgba(2,2,5,1); - transition: all 0.3s; -} -.tlv2-item.active-node .tlv2-dot-outer { - border-color: #4ade80; - box-shadow: 0 0 0 4px rgba(2,2,5,1), 0 0 14px rgba(74,222,128,0.5); -} -.tlv2-dot-inner { - width: 8px; - height: 8px; - border-radius: 50%; - background: rgba(0,229,255,0.8); - transition: all 0.3s; -} -.tlv2-item.active-node .tlv2-dot-inner { - background: #4ade80; - box-shadow: 0 0 8px rgba(74,222,128,0.8); -} -.tlv2-line { display: none; } - -/* The card glassmorphism V3 */ -.tlv2-card { - background: linear-gradient(135deg, rgba(255,255,255,0.03) 0%, rgba(255,255,255,0.01) 100%); - border: 1px solid rgba(255,255,255,0.07); - border-radius: 18px; - padding: 1.6rem 2rem; - position: relative; - transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); - overflow: hidden; -} - -/* Subtle top accent line per card */ -.tlv2-card::before { - content: ''; - position: absolute; - top: 0; left: 0; right: 0; - height: 1px; - background: linear-gradient(90deg, transparent, rgba(0,229,255,0.2), transparent); - opacity: 0; - transition: opacity 0.3s; -} -.tlv2-card:hover::before { opacity: 1; } - -/* Active card has green accent */ -.tlv2-item.active-node .tlv2-card::before { - background: linear-gradient(90deg, transparent, rgba(74,222,128,0.4), transparent); - opacity: 1; -} -.tlv2-item.active-node .tlv2-card { - border-color: rgba(74,222,128,0.18); - background: linear-gradient(135deg, rgba(74,222,128,0.04) 0%, rgba(0,229,255,0.02) 100%); -} - -.tlv2-card:hover { - border-color: rgba(0,229,255,0.2); - transform: translateX(4px); - background: linear-gradient(135deg, rgba(0,229,255,0.04) 0%, rgba(255,255,255,0.02) 100%); -} -.tlv2-item.active-node .tlv2-card:hover { - border-color: rgba(74,222,128,0.35); - transform: translateX(4px); -} - -/* Small connector arrow from line to card */ -.tlv2-card::after { - content: ''; - position: absolute; - left: -8px; - top: 13px; - width: 8px; - height: 1px; - background: rgba(0,229,255,0.25); -} -.tlv2-item.active-node .tlv2-card::after { - background: rgba(74,222,128,0.4); -} - -/* Year floating above badge */ -.tlv2-period { - font-size: 0.6rem !important; - color: rgba(0,229,255,0.5) !important; - letter-spacing: 0.12em; -} -.tlv2-item.active-node .tlv2-period { - color: rgba(74,222,128,0.6) !important; -} - -/* Role title premium typography */ -.tlv2-role { - font-size: 1.2rem; - font-weight: 900; - letter-spacing: -0.03em; - color: #fff; - margin-bottom: 0.35rem; - line-height: 1.2; -} - -/* Company line */ -.tlv2-company { - font-family: var(--font-mono); - font-size: 0.55rem; - color: rgba(0,229,255,0.6); - letter-spacing: 0.08em; - text-transform: uppercase; - margin-bottom: 0.9rem; - display: flex; - align-items: center; - gap: 0.4rem; -} -.tlv2-item.active-node .tlv2-company { - color: rgba(74,222,128,0.7); -} -.tlv2-city { - color: rgba(255,255,255,0.25); - font-weight: 400; -} - -/* Description */ -.tlv2-desc { - font-size: 0.88rem; - color: rgba(255,255,255,0.5); - line-height: 1.75; - margin-bottom: 1.1rem; -} - -/* Pills refined */ -.tlv2-pills { - display: flex; - flex-wrap: wrap; - gap: 0.4rem; -} -.tlv2-pills span { - font-family: var(--font-mono); - font-size: 0.48rem; - padding: 0.2rem 0.6rem; - border-radius: 4px; - background: rgba(0,229,255,0.05); - border: 1px solid rgba(0,229,255,0.12); - color: rgba(0,229,255,0.6); - letter-spacing: 0.06em; - text-transform: uppercase; - transition: all 0.2s; -} -.tlv2-pills span:hover { - background: rgba(0,229,255,0.1); - border-color: rgba(0,229,255,0.3); - color: rgba(0,229,255,0.9); -} -.tlv2-item.active-node .tlv2-pills span { - background: rgba(74,222,128,0.05); - border-color: rgba(74,222,128,0.15); - color: rgba(74,222,128,0.7); -} - -/* Badge */ -.tlv2-badge { - font-family: var(--font-mono); - font-size: 0.48rem; - padding: 0.2rem 0.7rem; - border-radius: 100px; - letter-spacing: 0.1em; - font-weight: 700; -} -.tlv2-badge.active { - color: #4ade80; - background: rgba(74,222,128,0.08); - border: 1px solid rgba(74,222,128,0.25); - animation: pulse-green 2s ease infinite; -} -.tlv2-badge.done { - color: rgba(255,255,255,0.3); - background: rgba(255,255,255,0.03); - border: 1px solid rgba(255,255,255,0.07); -} - -@media (max-width: 768px) { - .timeline-v2 { padding-left: 2.5rem; } - .tlv2-marker { left: -2.5rem; } - .tlv2-role { font-size: 1rem; } - .tlv2-card { padding: 1.2rem 1.3rem; } - .tlv2-card::after { display: none; } -} - -/* ══════════════════════════════════════════════════════════════ - V2 REDESIGN COMPONENTS — Clean B2B GovTech Aesthetic - ══════════════════════════════════════════════════════════════ */ - -/* --- Section Eyebrow (replaces // LABEL_FORMAT) --- */ -.section-eyebrow-v2 { - display: inline-flex; - align-items: center; - gap: 0.5rem; - color: #00E87A; - font-size: 0.78rem; - font-weight: 700; - letter-spacing: 0.1em; - text-transform: uppercase; - margin-bottom: 0.75rem; - font-family: 'Plus Jakarta Sans', var(--font-main); -} -.section-eyebrow-v2 > span:first-child { - display: inline-block; - width: 20px; - height: 2px; - background: #00E87A; -} - -/* --- Services Grid V2 --- */ -.services-grid-v2 { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); - gap: 1.5rem; - margin-top: 2.5rem; -} - -.service-card-v2 { - background: rgba(255,255,255,0.03); - border: 1px solid rgba(255,255,255,0.07); - border-radius: 14px; - padding: 2rem; - transition: border-color 0.3s, transform 0.3s; - cursor: default; -} -.service-card-v2:hover { - border-color: rgba(0,232,122,0.25); - transform: translateY(-4px); -} - -.svc-icon { - width: 48px; - height: 48px; - background: rgba(0,232,122,0.08); - border-radius: 12px; - display: flex; - align-items: center; - justify-content: center; - font-size: 1.4rem; - margin-bottom: 1.25rem; -} - -.service-card-v2 h3 { - font-family: 'Syne', var(--font-main); - font-size: 1.05rem; - font-weight: 700; - margin-bottom: 0.5rem; - color: #fff; -} - -.service-card-v2 p { - font-size: 0.88rem; - color: var(--text-secondary); - line-height: 1.65; - margin-bottom: 1rem; - font-family: 'Plus Jakarta Sans', var(--font-main); -} - -.svc-tags { - display: flex; - gap: 0.4rem; - flex-wrap: wrap; -} -.svc-tags span { - background: rgba(0,232,122,0.07); - color: #00E87A; - border-radius: 4px; - padding: 0.2rem 0.55rem; - font-size: 0.7rem; - font-weight: 600; - letter-spacing: 0.03em; -} -.svc-tags span.blue { - background: rgba(14,165,233,0.1); - color: #0EA5E9; -} - -/* --- Fade In Animation --- */ -.fade-in-v2 { - opacity: 0; - transform: translateY(24px); - transition: opacity 0.7s ease, transform 0.7s ease; -} -.fade-in-v2.visible { - opacity: 1; - transform: translateY(0); -} - -/* --- Challenges Grid V2 --- */ -.challenges-grid-v2 { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); - gap: 1.25rem; -} - -.chal-card-v2 { - background: rgba(10, 15, 20, 0.4); - border: 1px solid rgba(255,255,255,0.05); - border-radius: 12px; - padding: 2rem 1.5rem; - transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); - position: relative; - overflow: hidden; - -webkit-backdrop-filter: blur(5px); - backdrop-filter: blur(5px); -} -.chal-card-v2:hover { - border-color: rgba(0,232,122,0.4); - transform: translateY(-8px); - box-shadow: 0 10px 30px rgba(0,232,122,0.1); -} -.chal-glow-backdrop { - position: absolute; - inset: 0; - background: radial-gradient(circle at top right, rgba(0,232,122,0.1), transparent 70%); - opacity: 0; - transition: opacity 0.4s ease; - pointer-events: none; - z-index: 0; -} -.chal-card-v2:hover .chal-glow-backdrop { - opacity: 1; -} - -.chal-number { - position: relative; - z-index: 2; - font-family: 'Syne', var(--font-heading); - font-size: 2.2rem; - font-weight: 800; - color: rgba(0,232,122,0.15); - margin-bottom: 1rem; - line-height: 1; - display: flex; - align-items: center; - gap: 0.5rem; - transition: color 0.4s ease; -} -.chal-card-v2:hover .chal-number { - color: rgba(0,232,122,0.4); -} - -.chal-card-v2 h4 { - position: relative; - z-index: 2; - font-family: 'Plus Jakarta Sans', var(--font-main); - font-size: 1.05rem; - font-weight: 600; - color: #fff; - margin-bottom: 1rem; - line-height: 1.4; -} - -.chal-divider { - position: relative; - z-index: 2; - width: 2rem; - height: 2px; - background: rgba(255,255,255,0.1); - margin-bottom: 1rem; - transition: width 0.4s ease, background 0.4s ease; -} -.chal-card-v2:hover .chal-divider { - width: 4rem; - background: rgba(0,232,122,0.5); -} - -.chal-sol-text { - position: relative; - z-index: 2; - font-size: 0.9rem; - color: #00E87A; - font-family: 'Plus Jakarta Sans', var(--font-main); - font-weight: 500; - display: flex; - align-items: flex-start; - gap: 0.5rem; -} - -.chal-arrow-icon { - color: rgba(0,232,122,0.6); - margin-top: 0.1rem; - font-size: 1.1rem; - transition: transform 0.3s ease; -} -.chal-card-v2:hover .chal-arrow-icon { - transform: translateX(4px); -} - -/* --- HERO V2 SAAS SPLIT LAYOUT --- */ -.hero-v2 { - display: grid; - grid-template-columns: 1.1fr 0.9fr; - gap: 4rem; - min-height: 100vh; - align-items: center; - padding: 0 7% 0 6%; - position: relative; - overflow: hidden; -} - -/* - * Directional dark veil — covers the left column with a deep navy gradient - * that fades to transparent by center. Text becomes perfectly readable - * without any visible box or card. - */ -.hero-v2::before { - content: ''; - position: absolute; - inset: 0; - background: linear-gradient( - 105deg, - rgba(4, 8, 18, 0.92) 0%, - rgba(4, 8, 18, 0.80) 30%, - rgba(4, 8, 18, 0.40) 55%, - transparent 75% - ); - pointer-events: none; - z-index: 1; -} - -/* Electric accent — subtle cyan bloom top-left */ -.hero-v2::after { - content: ''; - position: absolute; - top: -15%; - left: -5%; - width: 650px; - height: 650px; - background: radial-gradient(ellipse at center, - rgba(0, 229, 255, 0.055) 0%, - rgba(37, 99, 235, 0.04) 45%, - transparent 70% - ); - pointer-events: none; - filter: blur(8px); - z-index: 0; -} - -@media (max-width: 968px) { - .hero-v2 { - grid-template-columns: 1fr; - padding: 9rem 5% 5rem; - gap: 3rem; - text-align: center; - } - /* On mobile the veil covers full width */ - .hero-v2::before { - background: rgba(4, 8, 18, 0.82); - } -} - -/* Content column — sits above the veil, no box */ -.hero-content { - position: relative; - z-index: 2; -} - -.hero-content::before { - /* Remove the old accent bar */ - display: none; -} - -/* Heading — rich white-to-blue gradient, sharp & large */ -.hero-h1 { - font-family: 'Syne', var(--font-heading); - font-size: clamp(2.6rem, 4.8vw, 4.2rem); - line-height: 1.08; - letter-spacing: -0.045em; - margin-bottom: 1.6rem; - background: linear-gradient( - 150deg, - #FFFFFF 0%, - #E8F4FF 45%, - rgba(100, 190, 255, 0.8) 100% - ); - -webkit-background-clip: text; - background-clip: text; - -webkit-text-fill-color: transparent; - filter: drop-shadow(0 2px 20px rgba(0, 100, 255, 0.15)); -} - -/* Body — warm readable slate, not pure grey */ -.hero-p { - font-family: 'Plus Jakarta Sans', var(--font-main); - font-size: 1.12rem; - color: rgba(185, 210, 235, 0.88); - line-height: 1.78; - margin-bottom: 2.8rem; - max-width: 580px; -} - -@media (max-width: 968px) { - .hero-p { margin-left: auto; margin-right: auto; } - .hero-eyebrow-v2 { margin-left: auto; margin-right: auto; } -} - -.hero-cta-group { - display: flex; - gap: 1rem; - margin-bottom: 3.5rem; - flex-wrap: wrap; -} - -@media (max-width: 968px) { - .hero-cta-group { justify-content: center; } -} - -/* Primary CTA */ -.btn-primary { - display: inline-flex; - align-items: center; - gap: 0.5rem; - background: linear-gradient(135deg, var(--accent-electric), #0077FF); - color: #000; - padding: 0.9rem 2.2rem; - border-radius: 12px; - font-weight: 800; - font-family: 'Plus Jakarta Sans', var(--font-main); - font-size: 0.9rem; - text-decoration: none; - transition: all 0.4s var(--ease-apple); - box-shadow: 0 8px 25px rgba(0, 229, 255, 0.3); - letter-spacing: 0.02em; - position: relative; - overflow: hidden; -} - -.btn-primary::after { - content: ''; - position: absolute; - inset: 0; - background: rgba(255,255,255,0.15); - opacity: 0; - transition: opacity 0.3s; -} - -.btn-primary:hover { - transform: translateY(-3px); - box-shadow: 0 16px 40px rgba(0, 229, 255, 0.45); -} - -.btn-primary:hover::after { opacity: 1; } - -/* Secondary CTA */ -.btn-secondary { - display: inline-flex; - align-items: center; - gap: 0.5rem; - background: rgba(255, 255, 255, 0.05); - border: 1px solid rgba(255, 255, 255, 0.15); - color: rgba(255, 255, 255, 0.85); - padding: 0.9rem 2.2rem; - border-radius: 12px; - font-weight: 600; - font-family: 'Plus Jakarta Sans', var(--font-main); - font-size: 0.9rem; - text-decoration: none; - transition: all 0.4s var(--ease-apple); - -webkit-backdrop-filter: blur(10px); - backdrop-filter: blur(10px); - letter-spacing: 0.02em; -} - -.btn-secondary:hover { - background: rgba(255, 255, 255, 0.1); - border-color: rgba(0, 229, 255, 0.35); - color: #fff; - transform: translateY(-3px); -} - -/* Stats Strip */ -.hero-stats-strip-v2 { - display: flex; - gap: 2.5rem; - align-items: center; - border-top: 1px solid rgba(255, 255, 255, 0.08); - padding-top: 2rem; -} - -@media (max-width: 968px) { - .hero-stats-strip-v2 { justify-content: center; flex-wrap: wrap; border-top: none; } -} - -.h-stat-v2 { - display: flex; - flex-direction: column; - gap: 0.3rem; -} - -.h-stat-v2 .val { - font-family: 'Syne', var(--font-heading); - font-size: 1.5rem; - font-weight: 800; - color: #fff; - letter-spacing: -0.02em; -} - -.h-stat-v2 .lbl { - font-family: var(--font-mono); - font-size: 0.65rem; - color: rgba(160, 190, 220, 0.6); - text-transform: uppercase; - letter-spacing: 0.12em; -} - -.h-stat-sep-v2 { - width: 1px; - height: 36px; - background: linear-gradient(to bottom, transparent, rgba(255,255,255,0.15), transparent); -} - -/* ====== GEO-INTELLIGENCE HUB ====== */ -.hero-graphic { - position: relative; - z-index: 2; -} - -.geo-hub { - position: relative; - width: 100%; - max-width: 560px; - aspect-ratio: 1 / 1; - margin: 0 auto; - /* 3D perspective tilt for depth */ - perspective: 900px; - transform-style: preserve-3d; -} - -/* Everything inside tilts as a flat plane viewed from above */ -.geo-hub > * { - transform: rotateX(12deg); -} - -/* --- GIS coordinate grid background --- */ -.geo-hub-grid { - position: absolute; - inset: 0; - border-radius: 50%; - background-image: - repeating-linear-gradient(0deg, rgba(0,229,255,0.04) 0px, transparent 1px, transparent 40px), - repeating-linear-gradient(90deg, rgba(0,229,255,0.04) 0px, transparent 1px, transparent 40px); - -webkit-mask-image: radial-gradient(ellipse at center, black 40%, transparent 72%); - mask-image: radial-gradient(ellipse at center, black 40%, transparent 72%); - pointer-events: none; - animation: gridPulse 6s ease-in-out infinite alternate; -} -@keyframes gridPulse { - 0% { opacity: 0.4; } - 100% { opacity: 1.0; } -} - -/* --- SVG connection layer --- */ -.geo-hub-svg { - position: absolute; - inset: 0; - width: 100%; - height: 100%; - pointer-events: none; - transform: rotateX(12deg); - transform-origin: center center; -} -.hub-line { - stroke: rgba(0, 229, 255, 0.18); - stroke-width: 1; - fill: none; -} -.hub-line-inner { - stroke: rgba(0, 229, 255, 0.28); - stroke-dasharray: 3 5; -} -.hub-dot { - filter: drop-shadow(0 0 4px rgba(0,229,255,0.8)); -} - -/* --- Central Hexagon Core --- */ -.geo-hub-core { - position: absolute; - top: 50%; left: 50%; - transform: translate(-50%, -50%) rotateX(12deg); - width: 100px; - height: 100px; - z-index: 10; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; -} - -/* Hexagonal shape */ -.geo-hub-core-inner { - width: 90px; - height: 90px; - background: linear-gradient(145deg, rgba(5, 10, 22, 0.98), rgba(0, 20, 40, 0.95)); - border: 1px solid rgba(0, 229, 255, 0.55); - clip-path: polygon(50% 0%, 93% 25%, 93% 75%, 50% 100%, 7% 75%, 7% 25%); - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - gap: 4px; - position: relative; - z-index: 2; - box-shadow: 0 0 40px rgba(0, 229, 255, 0.2); - transition: box-shadow 0.4s ease; -} - -.geo-hub-core:hover .geo-hub-core-inner { - box-shadow: 0 0 60px rgba(0, 229, 255, 0.5); - border-color: rgba(0, 229, 255, 0.9); -} - -.geo-hub-core-inner img { - width: 36px; - height: 36px; -} - -.geo-hub-core-inner span { - font-family: var(--font-mono); - font-size: 0.6rem; - color: rgba(0, 229, 255, 0.8); - letter-spacing: 0.1em; - text-transform: uppercase; -} - -/* Pulse rings */ -.geo-hub-pulse { - position: absolute; - border-radius: 50%; - border: 1px solid rgba(0, 229, 255, 0.2); - animation: hubPulse 3s ease-out infinite; - pointer-events: none; -} -.geo-hub-pulse-1 { width: 120px; height: 120px; animation-delay: 0s; } -.geo-hub-pulse-2 { width: 150px; height: 150px; animation-delay: 1s; } - -@keyframes hubPulse { - 0% { transform: scale(0.8); opacity: 0.8; } - 100% { transform: scale(1.4); opacity: 0; } -} - -/* Tooltip (shared across all hub elements) */ -.geo-hub-core::after, -.geo-node::after, -.geo-node-sm::after { - content: attr(data-tooltip); - position: absolute; - bottom: calc(100% + 10px); - left: 50%; - transform: translateX(-50%) translateY(6px); - background: rgba(6, 12, 24, 0.97); - border: 1px solid rgba(0, 229, 255, 0.3); - color: rgba(210, 235, 255, 0.95); - padding: 0.5rem 0.9rem; - border-radius: 10px; - font-size: 0.72rem; - font-family: var(--font-mono); - white-space: nowrap; - opacity: 0; - pointer-events: none; - transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); - box-shadow: 0 10px 30px rgba(0,0,0,0.6); - z-index: 200; - -webkit-backdrop-filter: blur(12px); - backdrop-filter: blur(12px); -} -.geo-hub-core:hover::after, -.geo-node:hover::after, -.geo-node-sm:hover::after { - opacity: 1; - transform: translateX(-50%) translateY(0); -} - -/* --- Outer hex nodes (pill shape with icon + label) --- */ -.geo-node { - position: absolute; - display: flex; - align-items: center; - gap: 8px; - padding: 8px 14px 8px 10px; - background: rgba(8, 14, 26, 0.85); - -webkit-backdrop-filter: blur(14px); - backdrop-filter: blur(14px); - border: 1px solid rgba(255, 255, 255, 0.1); - border-radius: 40px; - cursor: pointer; - transition: all 0.4s var(--ease-apple); - font-family: var(--font-mono); - font-size: 0.7rem; - font-weight: 600; - color: rgba(200, 220, 240, 0.9); - letter-spacing: 0.06em; - box-shadow: 0 4px 20px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.05); - white-space: nowrap; - transform: rotateX(12deg); - z-index: 5; -} -.geo-node:hover { - border-color: rgba(0, 229, 255, 0.5); - box-shadow: 0 8px 30px rgba(0, 229, 255, 0.2), inset 0 1px 0 rgba(255,255,255,0.08); - transform: rotateX(12deg) translateY(-4px); - color: #fff; -} -.geo-node img { - width: 22px; - height: 22px; - border-radius: 4px; -} -.geo-node-text-icon { - font-size: 1.1rem; - line-height: 1; -} - -/* Hexagonal positioning (center = 50%/50%) */ -.geo-node-top { top: 4%; left: 50%; transform: translateX(-50%) rotateX(12deg); } -.geo-node-top-right { top: 22%; right: 4%; } -.geo-node-bottom-right{ bottom: 22%; right: 4%; } -.geo-node-bottom { bottom: 4%; left: 50%; transform: translateX(-50%) rotateX(12deg); } -.geo-node-bottom-left { bottom: 22%; left: 4%; } -.geo-node-top-left { top: 22%; left: 4%; } - -/* Staggered entrance float animations */ -.geo-node-top { animation: hubFloat 5s ease-in-out infinite; } -.geo-node-top-right { animation: hubFloat 5s ease-in-out infinite 0.8s; } -.geo-node-bottom-right{ animation: hubFloat 5s ease-in-out infinite 1.6s; } -.geo-node-bottom { animation: hubFloat 5s ease-in-out infinite 2.4s; } -.geo-node-bottom-left { animation: hubFloat 5s ease-in-out infinite 3.2s; } -.geo-node-top-left { animation: hubFloat 5s ease-in-out infinite 4s; } - -@keyframes hubFloat { - 0%, 100% { translate: 0 0; } - 50% { translate: 0 -6px; } -} - -/* --- Inner small nodes --- */ -.geo-node-sm { - position: absolute; - width: 44px; - height: 44px; - background: rgba(8, 14, 26, 0.9); - -webkit-backdrop-filter: blur(14px); - backdrop-filter: blur(14px); - border: 1px solid rgba(255,255,255,0.1); - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - transition: all 0.4s var(--ease-apple); - box-shadow: 0 4px 16px rgba(0,0,0,0.5); - transform: rotateX(12deg); - z-index: 5; -} -.geo-node-sm:hover { - border-color: rgba(0,229,255,0.5); - box-shadow: 0 6px 24px rgba(0,229,255,0.25); - transform: rotateX(12deg) scale(1.1); -} -.geo-node-sm img { width: 22px; height: 22px; } - -.geo-node-sm-a { top: 32%; left: 50%; transform: translate(-50%, -50%) rotateX(12deg); } -.geo-node-sm-b { top: 50%; left: 64%; transform: translate(-50%, -50%) rotateX(12deg); } - -/* --- Floating metric badges --- */ -.geo-badge { - position: absolute; - padding: 0.5rem 0.9rem; - background: rgba(0, 10, 25, 0.7); - -webkit-backdrop-filter: blur(16px); - backdrop-filter: blur(16px); - border: 1px solid rgba(0, 229, 255, 0.2); - border-radius: 12px; - display: flex; - flex-direction: column; - gap: 1px; - z-index: 6; - transform: rotateX(12deg); - animation: badgeFloat 7s ease-in-out infinite; -} -.geo-badge-tl { top: 8%; left: 36%; animation-delay: 0s; } -.geo-badge-br { bottom: 8%; right: 36%; animation-delay: 3.5s; } - -@keyframes badgeFloat { - 0%, 100% { translate: 0 0; } - 50% { translate: 0 -8px; } -} - -.geo-badge-val { - font-family: 'Syne', var(--font-heading); - font-size: 1rem; - font-weight: 800; - color: #fff; - letter-spacing: -0.02em; -} -.geo-badge-lbl { - font-family: var(--font-mono); - font-size: 0.55rem; - color: rgba(0, 229, 255, 0.7); - text-transform: uppercase; - letter-spacing: 0.12em; -} - - -/* --- ABOUT GRID V2 (Skill Bars) --- */ -.about-grid-v2 { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 6rem; - align-items: center; -} -@media (max-width: 1024px) { - .about-grid-v2 { grid-template-columns: 1fr; gap: 4rem; } -} - -.about-highlights { - display: flex; - flex-direction: column; - gap: 1.2rem; - margin-top: 2rem; -} -.a-high { - display: flex; - align-items: center; - gap: 1rem; - font-family: 'Plus Jakarta Sans', var(--font-main); - color: var(--text-secondary); - font-weight: 500; - font-size: 0.95rem; - padding: 0.8rem 1.2rem; - background: rgba(255, 255, 255, 0.02); - border: 1px solid rgba(255, 255, 255, 0.05); - border-radius: 12px; - transition: all 0.3s var(--ease-apple); -} -.a-high i { - font-size: 1.2rem; - filter: drop-shadow(0 0 5px rgba(0, 232, 122, 0.3)); -} -.a-high:hover { - background: rgba(255, 255, 255, 0.04); - border-color: rgba(0, 232, 122, 0.2); - transform: translateX(5px); - color: #fff; -} - -.skill-group { - margin-bottom: 2.5rem; - position: relative; -} -.skill-head { - display: flex; - justify-content: space-between; - margin-bottom: 1rem; - font-family: var(--font-mono); - font-size: 0.75rem; - color: var(--text-tertiary); - font-weight: 700; - letter-spacing: 0.1em; - text-transform: uppercase; -} -.skill-head span:last-child { - color: #fff; - background: rgba(255, 255, 255, 0.05); - padding: 0.2rem 0.6rem; - border-radius: 4px; -} -.skill-bar { - width: 100%; - height: 6px; - background: rgba(255, 255, 255, 0.03); - border-radius: 100px; - overflow: hidden; - position: relative; -} -.skill-fill { - height: 100%; - border-radius: 100px; - position: relative; - transition: width 2s cubic-bezier(0.16, 1, 0.3, 1); -} -.skill-fill::after { - content: ''; - position: absolute; - top: 0; left: 0; right: 0; bottom: 0; - background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent); - background-size: 200% 100%; - animation: skill-shine 3s infinite linear; -} - -@keyframes skill-shine { - 0% { background-position: -200% 0; } - 100% { background-position: 200% 0; } -} - -.skill-group:hover .skill-fill { - filter: brightness(1.2); - box-shadow: 0 0 20px currentColor; -} - - -/* --- TECH ROWS CONTAINER (SaaS Blade Style) --- */ -.tech-rows-container { - display: flex; - flex-direction: column; - gap: 1.2rem; -} -.tech-row { - display: grid; - grid-template-columns: 100px 1.5fr 1fr; - background: rgba(15, 20, 30, 0.3); - border: 1px solid rgba(255, 255, 255, 0.06); - border-radius: 24px; - padding: 2rem 3rem; - align-items: center; - gap: 3rem; - position: relative; - overflow: hidden; - transition: all 0.5s cubic-bezier(0.16, 1, 0.3, 1); - -webkit-backdrop-filter: blur(20px); - backdrop-filter: blur(20px); -} -.tech-row::before { - content: ''; - position: absolute; - top: 0; left: -100%; - width: 100%; height: 100%; - background: linear-gradient(90deg, transparent, rgba(0, 229, 255, 0.05), transparent); - transition: left 0.6s; -} -.tech-row:hover { - background: rgba(255, 255, 255, 0.03); - border-color: rgba(0, 229, 255, 0.2); - transform: scale(1.01); - box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3); -} -.tech-row:hover::before { - left: 100%; -} - -@media (max-width: 968px) { - .tech-row { - grid-template-columns: 1fr; - text-align: center; - justify-items: center; - gap: 1.5rem; - padding: 2.5rem 1.5rem; - } -} - -.t-row-icon { - width: 70px; - height: 70px; - background: rgba(0, 229, 255, 0.08); - border: 1px solid rgba(0, 229, 255, 0.1); - border-radius: 18px; - display: flex; - align-items: center; - justify-content: center; - font-size: 2rem; - color: var(--accent-electric); - transition: all 0.4s; -} -.tech-row:hover .t-row-icon { - background: var(--accent-electric); - color: #000; - transform: rotate(-5deg); -} - -.t-row-info h3 { - font-family: var(--font-mono); - font-size: 0.8rem; - color: var(--accent-electric); - letter-spacing: 0.2em; - margin-bottom: 0.8rem; - opacity: 0.8; -} -.t-row-info p { - font-family: 'Plus Jakarta Sans', var(--font-main); - color: #fff; - font-size: 1.1rem; - font-weight: 500; - line-height: 1.4; -} - -.t-row-tags { - display: flex; - gap: 0.6rem; - flex-wrap: wrap; - justify-content: flex-end; -} -@media (max-width: 968px) { - .t-row-tags { justify-content: center; } -} - -.t-tech-tag { - background: rgba(255, 255, 255, 0.03); - border: 1px solid rgba(255, 255, 255, 0.08); - padding: 0.5rem 1rem; - border-radius: 100px; - font-size: 0.75rem; - color: var(--text-secondary); - font-family: var(--font-mono); - display: flex; - align-items: center; - gap: 0.5rem; - transition: all 0.3s; -} -.t-tech-tag img { - width: 16px; - height: 16px; - opacity: 0.8; -} -.t-tech-tag:hover { - background: rgba(255, 255, 255, 0.08); - border-color: rgba(255, 255, 255, 0.2); - color: #fff; - transform: translateY(-2px); -} - - -/* --- METRICS GRID V3 (Data HUD Style) --- */ -.metrics-grid-v3 { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); - gap: 1.5rem; -} -.metric-card-v3 { - background: rgba(10, 15, 25, 0.4); - border: 1px solid rgba(255, 255, 255, 0.05); - border-radius: 32px; - padding: 3rem 2.5rem; - position: relative; - overflow: hidden; - transition: all 0.6s cubic-bezier(0.16, 1, 0.3, 1); - -webkit-backdrop-filter: blur(30px) saturate(150%); - backdrop-filter: blur(30px) saturate(150%); - display: flex; - flex-direction: column; - justify-content: flex-end; - min-height: 240px; -} -.metric-card-v3::before { - content: ''; - position: absolute; - top: 0; right: 0; - width: 120px; height: 120px; - background: radial-gradient(circle at top right, var(--accent-electric), transparent 70%); - opacity: 0.05; - transition: opacity 0.4s; -} -.metric-card-v3:hover { - border-color: rgba(255, 255, 255, 0.15); - transform: translateY(-8px); - background: rgba(15, 22, 35, 0.6); -} -.metric-card-v3:hover::before { - opacity: 0.2; -} - -.m-v3-val { - font-family: var(--font-mono); - font-size: 3.5rem; - font-weight: 800; - color: #fff; - line-height: 1; - margin-bottom: 1rem; - letter-spacing: -0.05em; - position: relative; - z-index: 2; -} -.m-v3-label { - font-family: 'Syne', var(--font-heading); - font-size: 1.1rem; - color: #fff; - font-weight: 600; - margin-bottom: 0.4rem; - position: relative; - z-index: 2; -} -.m-v3-sub { - font-family: 'Plus Jakarta Sans', var(--font-main); - font-size: 0.85rem; - color: var(--text-tertiary); - text-transform: uppercase; - letter-spacing: 0.1em; - position: relative; - z-index: 2; -} -.m-v3-accent { - position: absolute; - bottom: 0; left: 0; - width: 100%; height: 4px; - opacity: 0.3; - transition: all 0.3s; -} -.metric-card-v3:hover .m-v3-accent { - opacity: 1; - height: 6px; -} - -/* --- LAB GRID V2 (Sovereign Modules) --- */ -.lab-grid-v2 { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); - gap: 2.5rem; -} - -.lab-card-v2 { - background: rgba(10, 15, 25, 0.4); - border: 1px solid rgba(255, 255, 255, 0.06); - border-radius: 32px; - padding: 3rem; - display: flex; - flex-direction: column; - transition: all 0.6s cubic-bezier(0.16, 1, 0.3, 1); - position: relative; - overflow: hidden; - -webkit-backdrop-filter: blur(40px) saturate(180%); - backdrop-filter: blur(40px) saturate(180%); -} - -.lab-card-v2::before { - content: ''; - position: absolute; - inset: 0; - background: linear-gradient(135deg, rgba(255,255,255,0.02), transparent); - pointer-events: none; -} - -.lab-card-v2:hover { - transform: translateY(-10px) scale(1.02); - border-color: rgba(255, 255, 255, 0.12); - background: rgba(15, 22, 35, 0.5); - box-shadow: 0 30px 60px rgba(0, 0, 0, 0.5); -} - -.lc-head { - display: flex; - justify-content: space-between; - align-items: flex-start; - margin-bottom: 2.5rem; -} -.lc-id { - font-family: var(--font-mono); - font-size: 0.7rem; - color: var(--text-tertiary); - background: rgba(255, 255, 255, 0.05); - padding: 0.4rem 0.8rem; - border-radius: 100px; - letter-spacing: 0.1em; - border: 1px solid rgba(255, 255, 255, 0.05); -} -.lc-icon { - font-size: 2.5rem; - filter: drop-shadow(0 0 15px currentColor); - transition: all 0.4s; -} -.lab-card-v2:hover .lc-icon { - transform: scale(1.2) rotate(5deg); -} - -.lc-body h3 { - font-family: 'Syne', var(--font-heading); - font-size: 1.6rem; - color: #fff; - margin-bottom: 1rem; - letter-spacing: -0.02em; -} -.lc-body p { - font-family: 'Plus Jakarta Sans', var(--font-main); - color: var(--text-secondary); - font-size: 1rem; - line-height: 1.6; - margin-bottom: 2rem; -} - -.lc-footer { - margin-top: auto; - display: flex; - justify-content: space-between; - align-items: center; - padding-top: 1.5rem; - border-top: 1px solid rgba(255, 255, 255, 0.05); -} -.lc-status { - font-family: var(--font-mono); - font-size: 0.65rem; - color: #00E87A; - display: flex; - align-items: center; - gap: 0.5rem; - text-transform: uppercase; - letter-spacing: 0.05em; -} -.lc-status::before { - content: ''; - width: 6px; height: 6px; - background: currentColor; - border-radius: 50%; - box-shadow: 0 0 10px currentColor; - animation: pulse 2s infinite; -} - -.lc-title { - font-family: 'Syne', var(--font-heading); - font-size: 1.5rem; - color: #fff; - margin-bottom: 1rem; -} -.lc-desc { - font-family: 'Plus Jakarta Sans', var(--font-main); - color: var(--text-secondary); - font-size: 0.95rem; - line-height: 1.6; - margin-bottom: 2rem; - flex-grow: 1; -} - -.lc-tags { - display: flex; - gap: 0.5rem; - flex-wrap: wrap; - margin-bottom: 2rem; -} -.lc-tags span { - font-family: var(--font-mono); - font-size: 0.7rem; - color: var(--accent-electric); - border: 1px solid rgba(0,229,255,0.3); - padding: 0.3rem 0.8rem; - border-radius: 50px; -} -.gold-theme .lc-tags span { color: var(--accent-gold); border-color: rgba(255,180,0,0.3); } -.green-theme .lc-tags span { color: #00E87A; border-color: rgba(0,232,122,0.3); } - -/* Simplified mockup previews directly inside the new CSS */ -.lc-preview { - background: rgba(0,0,0,0.3); - border-radius: 8px; - height: 120px; - margin-bottom: 2rem; - display: flex; - align-items: center; - justify-content: center; - border: 1px solid rgba(255,255,255,0.02); - position: relative; - overflow: hidden; -} -.lc-btn { - display: inline-flex; - align-items: center; - justify-content: center; - gap: 0.5rem; - width: 100%; - padding: 1rem; - background: rgba(255,255,255,0.03); - border: 1px solid rgba(255,255,255,0.1); - color: #fff; - border-radius: 6px; - font-family: 'Plus Jakarta Sans', var(--font-main); - font-weight: 600; - text-decoration: none; - cursor: pointer; - transition: background 0.3s, border-color 0.3s; -} -.lc-btn:hover { background: rgba(0,229,255,0.1); border-color: var(--accent-electric); } -.gold-theme .lc-btn:hover { background: rgba(255,180,0,0.1); border-color: var(--accent-gold); } -.green-theme .lc-btn:hover { background: rgba(0,232,122,0.1); border-color: #00E87A; } - -/* Mini Map Val Grid & Pipe previews */ -.val-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px; width: 60%; height: 60%; opacity: 0.5; } -.val-grid div { background: var(--accent-gold); transition: opacity 0.3s; } -.pipe-preview { display:flex; justify-content:space-between; padding: 0 10%; width: 100%; } -.pipe-node { font-family:var(--font-mono); font-size:0.7rem; color:rgba(255,255,255,0.4); display:flex; flex-direction:column; align-items:center; gap:0.5rem; } -.pipe-node i { font-size:1.5rem; } -.pipe-node.active { color:#00E87A; } - -/* --- TIMELINE V3 (SAAS SIDEBAR) --- */ -@media (max-width: 968px) { - .timeline-v3-layout { - grid-template-columns: 1fr !important; - gap: 2rem !important; - } - .timeline-sidebar { position: relative !important; top: 0 !important; } -} - -.timeline-v3-feed { - border-left: 1px solid rgba(255,255,255,0.05); - padding-left: 3rem; -} -@media (max-width: 768px) { - .timeline-v3-feed { padding-left: 1.5rem; } -} - -.tlv3-card { - position: relative; - padding-bottom: 3.5rem; - border-bottom: 1px solid rgba(255,255,255,0.05); - margin-bottom: 3.5rem; -} -.tlv3-card::before { - content: ''; - position: absolute; - left: -3rem; - top: 5px; - width: 12px; - height: 12px; - background: rgba(10,10,15,1); - border: 2px solid var(--accent-electric); - border-radius: 50%; - transform: translateX(-50%); - box-shadow: 0 0 10px rgba(0,229,255,0.3); -} -@media (max-width: 768px) { - .tlv3-card::before { left: -1.5rem; } -} - -.tlv3-period { - font-family: var(--font-mono); - font-size: 0.8rem; - color: var(--accent-electric); - background: rgba(0,229,255,0.1); - display: inline-block; - padding: 0.3rem 0.8rem; - border-radius: 50px; - margin-bottom: 1rem; - font-weight: 600; -} -.tlv3-role { - font-family: 'Syne', var(--font-heading); - font-size: 1.6rem; - color: #fff; - margin-bottom: 0.5rem; -} -.tlv3-company { - font-family: 'Plus Jakarta Sans', var(--font-main); - font-size: 0.95rem; - color: var(--text-tertiary); - margin-bottom: 1.2rem; - text-transform: uppercase; - letter-spacing: 0.05em; -} -.tlv3-desc { - font-family: 'Plus Jakarta Sans', var(--font-main); - font-size: 1rem; - color: var(--text-secondary); - line-height: 1.6; - margin-bottom: 1.5rem; -} -.tlv3-tags { - display: flex; - flex-wrap: wrap; - gap: 0.5rem; -} -.tlv3-tags span { - font-family: var(--font-mono); - font-size: 0.75rem; - color: var(--text-secondary); - background: rgba(255,255,255,0.03); - padding: 0.3rem 0.6rem; - border-radius: 4px; - border: 1px solid rgba(255,255,255,0.1); -} - -/* --- TECH DNA ROW TAGS V2 --- */ -.t-tech-tag { - display: inline-flex; - align-items: center; - gap: 0.4rem; - padding: 0.4rem 0.7rem; - background: rgba(255, 255, 255, 0.03); - border: 1px solid rgba(255, 255, 255, 0.1); - border-radius: 6px; - font-family: var(--font-mono); - font-size: 0.75rem; - color: var(--text-secondary); - transition: all 0.3s ease; - cursor: default; -} -.t-tech-tag img { - width: 14px; - height: 14px; - filter: drop-shadow(0 0 5px rgba(255,255,255,0.1)); -} -.t-tech-tag i { - font-size: 1rem; -} -.t-row-tags:hover .t-tech-tag { - opacity: 0.4; /* Dim others on container hover */ -} -.t-row-tags .t-tech-tag:hover { - opacity: 1; - transform: translateY(-2px); - background: rgba(255, 255, 255, 0.08); - border-color: rgba(255, 255, 255, 0.3); - color: #fff; - box-shadow: 0 4px 15px rgba(0,0,0,0.3); -} - -/* --- ORBIT INTERACTION --- */ -.orbit-container:hover .orbit-ring, -.orbit-container:hover .sat { - animation-play-state: paused !important; -} -.orbit-container .sat { - transition: transform 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease, background 0.3s ease; -} -.orbit-container .center-core { - transition: transform 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease, background 0.3s ease; -} - -/* --- PREMIUM SAAS FOOTER V6 --- */ -.site-footer-v6 { - background: #050508; - border-top: 1px solid rgba(255,255,255,0.05); - padding: 6rem 5% 2rem; - position: relative; - overflow: hidden; -} -.site-footer-v6::before { - content: ''; - position: absolute; - top: 0; left: 0; right: 0; - height: 1px; - background: linear-gradient(90deg, transparent, rgba(0,229,255,0.5), transparent); -} -.footer-v6-grid { - display: grid; - grid-template-columns: 2fr 1fr 1fr; - gap: 4rem; - margin-bottom: 5rem; - max-width: 1400px; - margin-inline: auto; -} -@media (max-width: 968px) { - .footer-v6-grid { grid-template-columns: 1fr; gap: 3rem; } -} -.f-v6-brand h2 { - font-family: 'Syne', var(--font-heading); - font-size: 1.8rem; - font-weight: 800; - color: #fff; - margin-bottom: 1rem; - letter-spacing: -0.03em; -} -.f-v6-brand p { - font-family: 'Plus Jakarta Sans', var(--font-main); - color: var(--text-tertiary); - font-size: 0.9rem; - line-height: 1.8; - max-width: 400px; - margin-bottom: 2rem; -} -.f-v6-badges { - display: flex; - gap: 0.6rem; - flex-wrap: wrap; -} -.f-v6-badge { - padding: 0.3rem 0.8rem; - background: rgba(255,255,255,0.03); - border: 1px solid rgba(255,255,255,0.08); - border-radius: 50px; - font-family: var(--font-mono); - font-size: 0.65rem; - color: var(--text-secondary); - letter-spacing: 0.05em; - text-transform: uppercase; -} -.f-v6-col h3 { - font-family: 'Syne', var(--font-main); - color: #fff; - font-size: 0.9rem; - font-weight: 700; - letter-spacing: 0.1em; - text-transform: uppercase; - margin-bottom: 1.5rem; -} -.f-v6-link { - display: flex; - align-items: center; - gap: 0.5rem; - color: var(--text-tertiary); - font-family: 'Plus Jakarta Sans', var(--font-main); - text-decoration: none; - font-size: 0.9rem; - margin-bottom: 1rem; - transition: color 0.3s ease, transform 0.3s ease; -} -.f-v6-link:hover { - color: var(--accent-electric); - transform: translateX(5px); -} -.f-v6-link.highlight { color: #00E87A; font-weight: 600; } -.f-v6-link.highlight:hover { color: #4ade80; } - -.footer-v6-bottom { - gap: 1.5rem; -} - -/* --- FLAGSHIP PROJECTS V2 (Premium Grid) --- */ -.projects-grid-v2 { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); - gap: 2rem; - margin-top: 4rem; -} - -.project-card-v3 { - background: rgba(10, 15, 25, 0.4); - border: 1px solid rgba(255, 255, 255, 0.06); - border-radius: 28px; - padding: 2.5rem; - display: flex; - flex-direction: column; - text-decoration: none; - transition: all 0.6s cubic-bezier(0.16, 1, 0.3, 1); - position: relative; - overflow: hidden; - -webkit-backdrop-filter: blur(30px) saturate(140%); - backdrop-filter: blur(30px) saturate(140%); -} - -.project-card-v3::before { - content: ''; - position: absolute; - top: 0; left: 0; right: 0; height: 1px; - background: linear-gradient(90deg, transparent, rgba(255,255,255,0.1), transparent); -} - -.project-card-v3:hover { - transform: translateY(-8px); - border-color: rgba(0, 229, 255, 0.2); - background: rgba(15, 22, 35, 0.5); - box-shadow: 0 25px 50px rgba(0, 0, 0, 0.4); -} - -.pc-head { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 2rem; -} - -.pc-id { - font-family: var(--font-mono); - font-size: 0.65rem; - color: var(--accent-electric); - letter-spacing: 0.1em; - opacity: 0.8; -} - -.pc-status-tag { - font-family: var(--font-mono); - font-size: 0.6rem; - background: rgba(0, 232, 122, 0.1); - color: #00E87A; - padding: 0.2rem 0.6rem; - border-radius: 4px; - border: 1px solid rgba(0, 232, 122, 0.2); -} - -.pc-body h3 { - font-family: 'Syne', var(--font-heading); - font-size: 1.5rem; - color: #fff; - margin-bottom: 1rem; - letter-spacing: -0.02em; -} - -.pc-body p { - font-family: 'Plus Jakarta Sans', var(--font-main); - color: var(--text-secondary); - font-size: 0.95rem; - line-height: 1.6; - margin-bottom: 2rem; - flex-grow: 1; -} - -.pc-tags { - display: flex; - gap: 0.5rem; - flex-wrap: wrap; - margin-top: auto; -} - -.pc-tag { - font-family: var(--font-mono); - font-size: 0.65rem; - color: var(--text-tertiary); - background: rgba(255,255,255,0.03); - padding: 0.3rem 0.7rem; - border-radius: 4px; - border: 1px solid rgba(255,255,255,0.06); -} - -/* Special Full-Width Card (The Ultra Blade) */ -.pc-large { - grid-column: 1 / -1; - display: grid; - grid-template-columns: 1fr 1.5fr; - gap: 3rem; - padding: 4rem; - align-items: center; - background: radial-gradient(circle at 10% 10%, rgba(0, 229, 255, 0.05), transparent 60%), - rgba(10, 15, 25, 0.4); -} - -@media (max-width: 1024px) { - .pc-large { grid-template-columns: 1fr; padding: 3rem; } -} - -.pc-large-visual { - position: relative; - height: 200px; - background: rgba(0,0,0,0.2); - border-radius: 20px; - display: flex; - align-items: center; - justify-content: center; - border: 1px solid rgba(0, 229, 255, 0.1); -} - -.pc-large-visual img { - width: 280px; - filter: drop-shadow(0 0 30px rgba(0, 229, 255, 0.2)); -} - -.gold-accent .pc-id { color: var(--accent-gold); } -.gold-accent .pc-status-tag { color: var(--accent-gold); background: rgba(255,180,0,0.1); border-color: rgba(255,180,0,0.2); } -/* --- TECH PREMIUM COMPONENTS --- */ -/* --- PREMIUM CAPABILITIES (SERVICES) V2 --- */ -.capabilities-section { - position: relative; - padding: 10rem 10% 8rem; - background: radial-gradient(circle at 10% 20%, rgba(37, 99, 235, 0.03) 0%, transparent 40%), - radial-gradient(circle at 90% 80%, rgba(0, 232, 122, 0.02) 0%, transparent 40%); - overflow: hidden; -} - -/* Subtle background grid for GIS feel */ -.capabilities-section::before { - content: ''; - position: absolute; - inset: 0; - background-image: - linear-gradient(rgba(255, 255, 255, 0.02) 1px, transparent 1px), - linear-gradient(90deg, rgba(255, 255, 255, 0.02) 1px, transparent 1px); - background-size: 60px 60px; - -webkit-mask-image: radial-gradient(ellipse at center, black, transparent 80%); - mask-image: radial-gradient(ellipse at center, black, transparent 80%); - pointer-events: none; -} - -.services-grid-v2 { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(380px, 1fr)); - gap: 2rem; - margin-top: 4rem; -} - -.service-card-v2 { - position: relative; - background: rgba(15, 23, 42, 0.3); - border: 1px solid rgba(255, 255, 255, 0.05); - border-radius: 32px; - padding: 3rem 2.5rem; - overflow: hidden; - transition: all 0.6s var(--ease-apple); - display: flex; - flex-direction: column; - gap: 1.5rem; - -webkit-backdrop-filter: blur(20px); - backdrop-filter: blur(20px); -} - -/* Glass-glow effect on top corner */ -.service-card-v2::before { - content: ''; - position: absolute; - top: -50px; right: -50px; - width: 150px; height: 150px; - background: radial-gradient(circle, rgba(37, 99, 235, 0.15) 0%, transparent 70%); - filter: blur(20px); - transition: transform 0.8s ease; -} - -/* --- LINT FIXES / MIGRATED INLINE STYLES --- */ - -/* CV Overlay Refinement */ -.cv-title-main { - font-size: 1.6rem; - line-height: 1; - margin-bottom: 0.5rem; - font-weight: 900; -} - -.cv-meta-v2 { - font-family: var(--font-mono); - font-size: 0.55rem; - color: var(--cv-accent); - margin-bottom: 1.5rem; - letter-spacing: 0.1em; - opacity: 0.7; -} - -.cv-desc-v2 { - text-align: left; - font-size: 0.75rem; - line-height: 1.7; - color: var(--text-secondary); -} - -.cv-skills-list-v2 { - margin-top: 1.5rem; - display: flex; - flex-direction: column; - gap: 0.6rem; - text-align: left; -} - -.cv-skill-node { - font-size: 0.65rem; -} - -.cv-contact-group { - margin-top: 2rem; - display: flex; - flex-direction: column; - gap: 0.8rem; - text-align: left; - border-top: 1px solid var(--cv-border); - padding-top: 1.5rem; -} - -.cv-contact-node { - font-size: 0.65rem; - color: var(--text-tertiary); -} - -/* About Section Refinement */ -.about-section-v2 { - padding: 10rem 5%; - position: relative; -} - -.about-bg-glow { - position: absolute; - top: 10%; - left: 50%; - transform: translateX(-50%); - width: 600px; - height: 600px; - background: radial-gradient(circle, rgba(0, 229, 255, 0.05) 0%, transparent 70%); - pointer-events: none; -} - -.about-content-v2 { - position: relative; - z-index: 2; -} - -.about-title-v2 { - font-family: 'Syne', var(--font-heading); - font-size: clamp(1.8rem, 3vw, 2.4rem); - letter-spacing: -0.03em; - margin-bottom: 1.5rem; -} - -.about-desc-v2 { - color: var(--text-secondary); - line-height: 1.8; - font-size: 1.1rem; - margin-bottom: 2.5rem; - font-family: 'Plus Jakarta Sans', var(--font-main); -} - -.service-card-v2:hover { - transform: translateY(-10px) scale(1.02); - background: rgba(15, 23, 42, 0.5); - border-color: rgba(37, 99, 235, 0.3); - box-shadow: 0 30px 60px -12px rgba(0, 0, 0, 0.5), - 0 18px 36px -18px rgba(37, 99, 235, 0.3); -} - -.service-card-v2:hover::before { - transform: translate(-20px, 20px) scale(1.5); -} - -.svc-header { - display: flex; - justify-content: space-between; - align-items: flex-start; - margin-bottom: 0.5rem; -} - -.svc-id { - font-family: var(--font-mono); - font-size: 0.65rem; - color: rgba(255, 255, 255, 0.3); - letter-spacing: 0.15em; - text-transform: uppercase; -} - -.svc-status { - display: flex; - align-items: center; - gap: 0.5rem; - font-family: var(--font-mono); - font-size: 0.6rem; - color: #00E87A; - background: rgba(0, 232, 122, 0.1); - padding: 0.3rem 0.8rem; - border-radius: 50px; - border: 1px solid rgba(0, 232, 122, 0.2); -} - -.svc-status span { - width: 6px; height: 6px; - background: #00E87A; - border-radius: 50%; - box-shadow: 0 0 10px #00E87A; -} - -.svc-icon-box { - width: 64px; height: 64px; - background: linear-gradient(135deg, rgba(255, 255, 255, 0.05), transparent); - border: 1px solid rgba(255, 255, 255, 0.1); - border-radius: 18px; - display: flex; - align-items: center; - justify-content: center; - font-size: 1.8rem; - margin-bottom: 0.5rem; - transition: all 0.4s ease; -} - -.service-card-v2:hover .svc-icon-box { - background: linear-gradient(135deg, var(--primary-electric), transparent); - border-color: rgba(255, 255, 255, 0.2); - transform: rotate(-5deg); -} - -.service-card-v2 h3 { - font-size: 1.5rem; - font-weight: 800; - color: #fff; - letter-spacing: -0.02em; -} - -.service-card-v2 p { - color: var(--text-secondary); - line-height: 1.7; - font-size: 1rem; - margin: 0; -} - -.svc-metric { - display: flex; - align-items: center; - gap: 1rem; - padding-top: 1.5rem; - border-top: 1px solid rgba(255, 255, 255, 0.05); - margin-top: auto; -} - -.metric-item { - display: flex; - flex-direction: column; -} - -.metric-val { - font-family: var(--font-mono); - font-size: 1.1rem; - font-weight: 700; - color: #fff; -} - -.metric-lbl { - font-size: 0.65rem; - text-transform: uppercase; - color: var(--text-tertiary); - letter-spacing: 0.05em; -} - -.svc-tags { - display: flex; - gap: 0.6rem; - flex-wrap: wrap; - margin-top: 1rem; -} - -.svc-tags span { - background: rgba(255, 255, 255, 0.04); - border: 1px solid rgba(255, 255, 255, 0.1); - color: rgba(255, 255, 255, 0.6); - padding: 0.4rem 1rem; - border-radius: 50px; - font-size: 0.7rem; - font-family: var(--font-mono); - transition: all 0.3s ease; -} - -.service-card-v2:hover .svc-tags span { - border-color: rgba(37, 99, 235, 0.3); - color: #fff; -} - -/* --- PREMIUM CHALLENGES V2 --- */ -.challenges-section { - padding: 10rem 10% 12rem; - background: #060B18; - position: relative; -} - -.challenges-grid-v2 { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); - gap: 1.5rem; -} - -.chal-card-v2 { - background: rgba(15, 23, 42, 0.4); - border: 1px solid rgba(255, 255, 255, 0.06); - border-radius: 28px; - padding: 2.5rem; - position: relative; - overflow: hidden; - transition: all 0.5s var(--ease-apple); -} - -.chal-card-v2:hover { - border-color: var(--accent-yellow); - transform: scale(1.03); - box-shadow: 0 20px 50px rgba(0,0,0,0.4); -} - -.chal-number { - font-family: var(--font-mono); - font-size: 0.75rem; - color: var(--accent-yellow); - display: flex; - align-items: center; - gap: 0.5rem; - margin-bottom: 1.5rem; - opacity: 0.8; -} - -.chal-card-v2 h4 { - font-size: 1.25rem; - font-weight: 700; - color: #fff; - margin-bottom: 1.5rem; - line-height: 1.4; -} - -.chal-divider { - width: 40px; height: 2px; - background: var(--accent-yellow); - margin-bottom: 1.5rem; - transition: width 0.5s ease; -} - -.chal-card-v2:hover .chal-divider { width: 100%; } - -.chal-sol-text { - display: flex; - gap: 1rem; - align-items: flex-start; - font-size: 0.95rem; - color: var(--text-secondary); - line-height: 1.6; -} - -.chal-arrow-icon { - color: var(--accent-yellow); - font-size: 1.2rem; - margin-top: 2px; -} - -.chal-glow-backdrop { - position: absolute; - inset: 0; - background: radial-gradient(circle at center, rgba(255, 215, 0, 0.05) 0%, transparent 70%); - opacity: 0; - transition: opacity 0.5s ease; -} - -.chal-card-v2:hover .chal-glow-backdrop { opacity: 1; } - - -footer { - background: var(--primary-deep); - padding: 8rem 10% 4rem; - color: #CBD5E1; -} - -footer a { - color: #CBD5E1; - text-decoration: none; - transition: color 0.3s; -} - -footer a:hover { - color: var(--accent-yellow); -} - -.f-v6-status { - display: flex; - align-items: center; - gap: 0.5rem; - background: rgba(37, 99, 235, 0.08); - border: 1px solid rgba(37, 99, 235, 0.2); - padding: 0.4rem 1rem; - border-radius: 50px; -} - -.f-v6-dot { - width: 6px; height: 6px; - background: var(--primary-electric); - border-radius: 50%; - animation: pulse 2s ease infinite; -} - -.f-v6-status-text { - font-family: var(--font-mono); - font-size: 0.65rem; - color: var(--primary-electric); - letter-spacing: 0.05em; - text-transform: uppercase; -} - -/* --- GEO-LLM AI ASSISTANT STYLES --- */ -.geo-assistant-btn { - position: fixed; - bottom: 40px; - right: 40px; - width: 64px; - height: 64px; - background: linear-gradient(135deg, var(--accent-electric), #00A3FF); - border-radius: 20px; - display: flex; - align-items: center; - justify-content: center; - color: #000; - font-size: 1.8rem; - cursor: pointer; - z-index: 10000; - box-shadow: - 0 10px 30px rgba(0, 229, 255, 0.4), - inset 0 0 15px rgba(255, 255, 255, 0.4); - transition: all 0.5s var(--ease-spring); -} - -.geo-assistant-btn:hover { - transform: scale(1.1) rotate(10deg); - box-shadow: 0 15px 40px rgba(0, 229, 255, 0.6); -} - -.ai-ripple { - position: absolute; - inset: -5px; - border: 2px solid var(--accent-electric); - border-radius: 50%; - animation: ai-ripple 2s infinite; -} - -@keyframes ai-ripple { - 0% { transform: scale(1); opacity: 0.8; } - 100% { transform: scale(1.5); opacity: 0; } -} - -.geo-assistant-panel { - position: fixed; - bottom: 120px; - right: 40px; - width: 380px; - height: 520px; - background: rgba(15, 20, 30, 0.4); - -webkit-backdrop-filter: blur(35px) saturate(210%); - backdrop-filter: blur(35px) saturate(210%); - border: 1px solid rgba(255, 255, 255, 0.1); - border-radius: 32px; - z-index: 10000; - display: flex; - flex-direction: column; - overflow: hidden; - box-shadow: 0 40px 100px rgba(0, 0, 0, 0.8); - transition: all 0.6s var(--ease-apple); - transform-origin: bottom right; -} - -.geo-assistant-panel::after { - content: ''; - position: absolute; - inset: 0; - background: url('https://grainy-gradients.vercel.app/noise.svg'); - opacity: 0.04; - pointer-events: none; - mix-blend-mode: overlay; - z-index: 1; -} - -.geo-assistant-panel.collapsed { - transform: scale(0.8) translateY(100px); - opacity: 0; - pointer-events: none; -} - -.assistant-header { - padding: 1.2rem; - background: rgba(255, 255, 255, 0.05); - display: flex; - justify-content: space-between; - align-items: center; - border-bottom: 1px solid rgba(255, 255, 255, 0.1); -} - -.assistant-title { - display: flex; - align-items: center; - gap: 0.8rem; - font-family: var(--font-mono); - font-size: 0.75rem; - color: var(--accent-electric); - letter-spacing: 0.1em; -} - -.close-btn { - background: none; - border: none; - color: rgba(255, 255, 255, 0.5); - cursor: pointer; - font-size: 1.2rem; - transition: color 0.3s; -} - -.close-btn:hover { color: #fff; } - -.assistant-chat { - flex: 1; - padding: 1.2rem; - overflow-y: auto; - display: flex; - flex-direction: column; - gap: 1rem; -} - -.ai-msg { - background: rgba(255, 255, 255, 0.05); - padding: 0.8rem 1rem; - border-radius: 12px 12px 12px 0; - font-size: 0.85rem; - line-height: 1.4; - color: rgba(255, 255, 255, 0.9); - max-width: 85%; - border-left: 3px solid var(--accent-electric); -} - -.user-msg { - align-self: flex-end; - background: var(--accent-electric); - color: #000; - padding: 0.8rem 1rem; - border-radius: 12px 12px 0 12px; - font-size: 0.85rem; - font-weight: 600; - max-width: 85%; -} - -.assistant-input-area { - padding: 1rem; - background: rgba(0, 0, 0, 0.2); - display: flex; - gap: 0.6rem; -} - -.assistant-input-area input { - flex: 1; - background: rgba(255, 255, 255, 0.05); - border: 1px solid rgba(255, 255, 255, 0.1); - border-radius: 10px; - padding: 0.6rem 1rem; - color: #fff; - outline: none; - font-size: 0.85rem; -} - -.assistant-input-area button { - width: 40px; - height: 40px; - background: var(--accent-electric); - border: none; - border-radius: 10px; - color: #000; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - transition: transform 0.2s; -} - -.assistant-input-area button:hover { transform: scale(1.05); } - -/* --- PROFESSIONAL TIMELINE V3 --- */ -.timeline-v3-feed { - display: flex; - flex-direction: column; -} - -.tlv3-card { - background: rgba(15, 20, 30, 0.4); - border: 1px solid rgba(255, 255, 255, 0.08); - border-radius: 28px; - padding: 3rem; - margin-bottom: 2rem; - -webkit-backdrop-filter: blur(25px) saturate(200%); - backdrop-filter: blur(25px) saturate(200%); - position: relative; - overflow: hidden; - transition: all 0.6s var(--ease-apple); -} - -.tlv3-card::before { - content: ''; - position: absolute; - top: 0; left: 0; width: 100%; height: 2px; - background: linear-gradient(90deg, transparent, var(--accent-electric), transparent); - transform: translateX(-100%); - transition: transform 0.8s; -} - -.tlv3-card:hover { - transform: translateX(15px); - border-color: var(--accent-electric); - background: rgba(0, 210, 255, 0.03); -} - -.tlv3-card:hover::before { transform: translateX(100%); } - -.tlv3-period { - font-family: var(--font-mono); - font-size: 0.75rem; - color: var(--accent-electric); - margin-bottom: 1.2rem; - letter-spacing: 0.1em; -} - -.tlv3-role { - font-size: 1.8rem; - font-weight: 900; - color: #fff; - margin-bottom: 0.5rem; - letter-spacing: -0.02em; -} - -.tlv3-company { - font-size: 1rem; - color: rgba(255, 255, 255, 0.5); - margin-bottom: 1.5rem; - font-weight: 600; -} - -.tlv3-desc { - color: var(--text-secondary); - line-height: 1.8; - margin-bottom: 2rem; - font-size: 1.05rem; -} - -.tlv3-tags { - display: flex; - gap: 0.8rem; - flex-wrap: wrap; -} - -.tlv3-tags span { - background: rgba(255, 255, 255, 0.04); - border: 1px solid rgba(255, 255, 255, 0.1); - color: rgba(255, 255, 255, 0.6); - padding: 0.5rem 1.2rem; - border-radius: 100px; - font-size: 0.75rem; - font-family: var(--font-mono); - transition: all 0.3s; -} - -.tlv3-card:hover .tlv3-tags span { - border-color: rgba(0, 210, 210, 0.3); - color: #fff; -} - -/* --- PREMIUM PLUS ARCHITECTURE --- */ -.about-section-v2 { - padding: 10rem 10% !important; - position: relative; -} - -.section-header-v2 { - max-width: 800px; - margin-bottom: 6rem; -} - -.section-eyebrow-v2 { - display: flex; - align-items: center; - gap: 1.5rem; - color: var(--accent-electric); - font-family: var(--font-mono); - text-transform: uppercase; - letter-spacing: 0.3em; - font-size: 0.8rem; - margin-bottom: 2rem; -} - -.section-eyebrow-v2 span:first-child { - width: 60px; - height: 1px; - background: var(--accent-electric); -} - -.section-title-v2 { - font-size: clamp(2.5rem, 5vw, 4.5rem); - font-weight: 900; - line-height: 1.1; - color: #fff; - margin-bottom: 2rem; - letter-spacing: -0.03em; -} - -.section-desc-v2 { - font-size: 1.25rem; - line-height: 1.8; - color: var(--text-secondary); - max-width: 600px; -} - -/* --- PROJECTS GRID V2 --- */ -.projects-grid-v2 { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(450px, 1fr)); - gap: 3rem; -} - -@media (max-width: 1200px) { - .projects-grid-v2 { - grid-template-columns: 1fr; - } -} - -.project-card-v2 { - background: rgba(15, 20, 30, 0.4); - border: 1px solid rgba(255, 255, 255, 0.08); - border-radius: 40px; - padding: 4rem; - transition: all 0.8s var(--ease-apple); - position: relative; - overflow: hidden; - -webkit-backdrop-filter: blur(20px); - backdrop-filter: blur(20px); -} - -.project-card-v2:hover { - transform: translateY(-20px) scale(1.02); - border-color: var(--accent-electric); - background: rgba(0, 210, 255, 0.03); -} - -.project-meta-v2 { - display: flex; - gap: 1rem; - margin-bottom: 2rem; -} - -.project-status-pill { - background: rgba(0, 255, 157, 0.1); - color: #00ff9d; - padding: 0.4rem 1rem; - border-radius: 100px; - font-size: 0.7rem; - font-family: var(--font-mono); - text-transform: uppercase; - font-weight: 700; -} - -.project-category-v2 { - font-family: var(--font-mono); - font-size: 0.8rem; - color: var(--accent-electric); - margin-bottom: 1.5rem; - display: block; -} - -.project-title-v2 { - font-size: 2.2rem; - font-weight: 800; - color: #fff; - margin-bottom: 1.5rem; - letter-spacing: -0.02em; -} - -.project-desc-v2 { - font-size: 1.1rem; - line-height: 1.7; - color: var(--text-secondary); - margin-bottom: 2.5rem; -} - -.project-tech-v2 { - display: flex; - flex-wrap: wrap; - gap: 0.8rem; -} - -.tech-tag-v2 { - background: rgba(255, 255, 255, 0.03); - border: 1px solid rgba(255, 255, 255, 0.08); - padding: 0.5rem 1.2rem; - border-radius: 100px; - font-size: 0.75rem; - color: rgba(255, 255, 255, 0.5); - font-family: var(--font-mono); -} - -/* --- ARCHITECTURE VISUALIZER --- */ -.arch-grid-v2 { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); - gap: 2.5rem; -} - -.arch-tech-card { - background: rgba(255, 255, 255, 0.02); - border: 1px solid rgba(255, 255, 255, 0.05); - border-radius: 32px; - padding: 3rem; - transition: all 0.5s var(--ease-apple); - position: relative; -} - -.arch-tech-card:hover { - background: rgba(0, 210, 255, 0.02); - border-color: rgba(0, 210, 255, 0.3); - transform: translateY(-10px); -} - -.arch-icon-v2 { - width: 60px; - height: 60px; - background: rgba(0, 210, 255, 0.1); - border-radius: 18px; - display: flex; - align-items: center; - justify-content: center; - font-size: 1.8rem; - margin-bottom: 2rem; - color: var(--accent-electric); -} - -.arch-tech-card h3 { - font-size: 1.5rem; - font-weight: 700; - color: #fff; - margin-bottom: 1rem; -} - -.arch-tech-card p { - color: var(--text-secondary); - line-height: 1.6; - font-size: 0.95rem; -} - -/* --- PROJECT CARD V3 (BENTO) --- */ -.project-card-v3 { - background: rgba(15, 20, 30, 0.4); - border: 1px solid rgba(255, 255, 255, 0.08); - border-radius: 32px; - padding: 2.5rem; - display: flex; - flex-direction: column; - text-decoration: none; - transition: all 0.6s var(--ease-apple); - position: relative; - overflow: hidden; - -webkit-backdrop-filter: blur(20px); - backdrop-filter: blur(20px); -} - -.project-card-v3:hover { - transform: translateY(-10px); - border-color: var(--accent-electric); - background: rgba(0, 210, 255, 0.03); -} - -.project-card-v3.pc-large { - grid-column: span 2; - flex-direction: row; - padding: 0; -} - -@media (max-width: 1200px) { - .project-card-v3.pc-large { - grid-column: span 1; - flex-direction: column; - } -} - -.pc-large-visual { - flex: 1; - background: rgba(0, 210, 255, 0.05); - display: flex; - align-items: center; - justify-content: center; - border-right: 1px solid rgba(255, 255, 255, 0.05); -} - -.pc-large-visual img { - width: 200px; - height: auto; - filter: drop-shadow(0 0 30px rgba(0, 210, 255, 0.3)); -} - -.pc-body { - flex: 1.2; - padding: 4rem; - display: flex; - flex-direction: column; -} - -.project-card-v3:not(.pc-large) .pc-body { - padding: 0; - margin-top: 1.5rem; -} - -.pc-head { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 2rem; -} - -.pc-id { - font-family: var(--font-mono); - font-size: 0.7rem; - color: var(--accent-electric); - letter-spacing: 0.1em; -} - -.pc-status-tag { - background: rgba(0, 255, 157, 0.1); - color: #00ff9d; - padding: 0.4rem 0.8rem; - border-radius: 6px; - font-size: 0.65rem; - font-family: var(--font-mono); - font-weight: 700; -} - -.project-card-v3 h3 { - font-size: 1.8rem; - font-weight: 800; - color: #fff; - margin-bottom: 1rem; - letter-spacing: -0.02em; -} - -.project-card-v3 p { - color: var(--text-secondary); - line-height: 1.6; - margin-bottom: 2rem; - font-size: 1rem; -} - -.pc-tags { - display: flex; - flex-wrap: wrap; - gap: 0.6rem; - margin-top: auto; -} - -.pc-tag { - background: rgba(255, 255, 255, 0.04); - border: 1px solid rgba(255, 255, 255, 0.08); - padding: 0.4rem 0.8rem; - border-radius: 8px; - font-size: 0.7rem; - color: rgba(255, 255, 255, 0.5); - font-family: var(--font-mono); -} - -.about-title-v2 { - font-size: clamp(2.5rem, 5vw, 4rem); - font-weight: 900; - color: #fff; - margin-bottom: 2rem; - letter-spacing: -0.03em; -} - -/* --- TIMELINE V3: PROFESSIONAL CHRONOLOGY --- */ -.timeline-v3-layout { - position: relative; - max-width: 1000px; - margin: 0 auto; -} - -.tlv3-container { - position: relative; - padding-left: 3rem; - border-left: 2px solid rgba(0, 229, 255, 0.1); -} - -/* --- PRICING V2: ENTERPRISE TIERS --- */ -.pricing-grid-v2 { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); - gap: 2rem; - margin-top: 5rem; -} - -.plan-card { - background: rgba(15, 20, 30, 0.4); - border: 1px solid rgba(255, 255, 255, 0.05); - border-radius: 24px; - padding: 3rem 2rem; - position: relative; - overflow: hidden; - transition: all 0.5s var(--ease-apple); - -webkit-backdrop-filter: blur(15px); - backdrop-filter: blur(15px); - display: flex; - flex-direction: column; -} - -.plan-card:hover { - transform: translateY(-12px); - border-color: rgba(255, 255, 255, 0.15); - background: rgba(15, 20, 30, 0.6); -} - -.plan-card.plan-featured { - border-color: rgba(0, 229, 255, 0.3); - background: rgba(0, 210, 255, 0.02); -} - -.plan-card.plan-featured:hover { - border-color: var(--accent-electric); -} - -.plan-tier { - font-family: var(--font-mono); - font-size: 0.75rem; - letter-spacing: 2px; - margin-bottom: 1.5rem; - font-weight: 700; -} - -.plan-name { - font-family: var(--font-heading); - font-size: 2rem; - color: #fff; - margin-bottom: 0.5rem; -} - -.plan-for { - font-size: 0.95rem; - color: var(--text-secondary); - margin-bottom: 2rem; -} - -.plan-price { - margin-bottom: 2rem; -} - -.price-amount { - font-size: 3.5rem; - font-weight: 900; - font-family: var(--font-heading); - color: #fff; -} - -.price-period { - font-size: 0.9rem; - color: var(--text-tertiary); -} - -.plan-capacity { - margin-bottom: 2rem; -} - -.capacity-label { - font-family: var(--font-mono); - font-size: 0.75rem; - margin-bottom: 0.75rem; -} - -.capacity-bar { - height: 4px; - background: rgba(255, 255, 255, 0.05); - border-radius: 2px; - overflow: hidden; -} - -.capacity-fill { - height: 100%; - transition: width 1.5s var(--ease-apple); -} - -.plan-features { - list-style: none; - padding: 0; - margin: 0 0 3rem 0; - display: flex; - flex-direction: column; - gap: 1rem; -} - -.plan-features li { - display: flex; - align-items: center; - gap: 0.75rem; - font-size: 0.9rem; - color: var(--text-secondary); -} - -.plan-features i { - font-size: 1.2rem; -} - -.feat-cyan i { color: var(--accent-electric); } -.feat-gold i { color: var(--accent-gold); } - -/* --- CONTACT V2: ENTERPRISE PORTAL --- */ -.contact-portal-v2 { - display: grid; - grid-template-columns: 1.2fr 1fr; - gap: 6rem; - margin-top: 5rem; -} - -.contact-big-title { - font-size: clamp(2.5rem, 5vw, 4rem); - font-weight: 900; - color: #fff; - line-height: 1.1; - margin-bottom: 2rem; -} - -.contact-lead { - font-size: 1.2rem; - color: var(--text-secondary); - line-height: 1.7; - margin-bottom: 4rem; - max-width: 500px; -} - -.contact-cards-grid { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 1.5rem; -} - -.contact-card { - background: rgba(255, 255, 255, 0.02); - border: 1px solid rgba(255, 255, 255, 0.05); - padding: 1.5rem; - border-radius: 16px; - text-decoration: none; - transition: all 0.3s ease; -} - -.contact-card:hover { - background: rgba(255, 255, 255, 0.05); - border-color: rgba(255, 255, 255, 0.1); - transform: translateY(-5px); -} - -.cc-icon { - font-size: 1.8rem; - margin-bottom: 1rem; -} - -.cc-label { - font-family: var(--font-mono); - font-size: 0.7rem; - color: var(--text-tertiary); - text-transform: uppercase; - letter-spacing: 1px; - margin-bottom: 0.25rem; -} - -.cc-value { - color: #fff; - font-weight: 600; - font-size: 0.9rem; -} - -/* --- GIS WORKSTATION INTERNAL STYLES --- */ -.legend-symbol { - width: 12px; - height: 12px; - flex-shrink: 0; -} - -.gis-proj-info div span { - color: var(--accent-electric); -} - -.gis-measure-widget { - background: rgba(10, 10, 15, 0.9); - border: 1px solid var(--accent-electric); - padding: 1rem; - border-radius: 8px; - position: absolute; - bottom: 2rem; - left: 2rem; - z-index: 10; - -webkit-backdrop-filter: blur(10px); - backdrop-filter: blur(10px); -} - -.attr-system-id { - color: var(--accent-electric); - font-size: 0.65rem; - margin-bottom: 1rem; - opacity: 0.7; -} - -.gis-stat-row span:last-child { - color: var(--accent-electric); -} - -@media (max-width: 1200px) { - .contact-portal-v2 { - grid-template-columns: 1fr; - gap: 4rem; - } -} - -@media (max-width: 768px) { - .contact-cards-grid { - grid-template-columns: 1fr; - } -} - -.map-placeholder-status { - font-family: var(--font-mono); - color: var(--accent-electric); - margin-bottom: 2rem; - font-size: 0.9rem; - display: flex; - align-items: center; - justify-content: center; - gap: 0.75rem; -} - -.map-placeholder-status span { - color: var(--accent-electric); - animation: pulse 2s infinite; -} - -.map-grid-overlay { - position: absolute; - inset: 0; - background: linear-gradient(rgba(0, 229, 255, 0.03) 1px, transparent 1px), - linear-gradient(90deg, rgba(0, 229, 255, 0.03) 1px, transparent 1px); - background-size: 40px 40px; - pointer-events: none; - z-index: 0; -} - -@media (max-width: 768px) { - .tlv3-container { - padding-left: 2rem; - } - .tlv3-card::before { - left: -2.65rem; - } - .tlv3-role { - font-size: 1.2rem; - } -} - - -/* --- UTILITY & ABSTRACTION CLASSES (Premium Plus) --- */ -.icon-social-v2 { font-size: 1.4rem; } - -.divider-glass-v2 { - width: 100%; - height: 1px; - background: rgba(255, 255, 255, 0.1); - margin: 5px 0; -} - -.dna-label-v2 { margin-top: 1rem; } - -.flex-column-gap-1 { - display: flex; - flex-direction: column; - gap: 1rem; -} - -.flex-wrap-gap-05 { - display: flex; - gap: 0.5rem; - flex-wrap: wrap; - margin-top: 2rem; -} - -.hero-eyebrow-container { - display: inline-flex; - align-items: center; - gap: 0.5rem; - background: rgba(37, 99, 235, 0.08); - border: 1px solid rgba(37, 99, 235, 0.2); - color: #2563EB; - border-radius: 50px; - padding: 0.4rem 1.2rem; - font-size: 0.8rem; - font-weight: 600; - margin-bottom: 2rem; - letter-spacing: 0.04em; - font-family: var(--font-main); -} - -.hero-eyebrow-dot { - width: 7px; - height: 7px; - background: #2563EB; - border-radius: 50%; - animation: pulse 2s ease infinite; -} - -.cv-sidebar-divider { - height: 1px; - background: var(--cv-border); - margin: 1.2rem 0; -} - -.cv-edu-title { - font-weight: 800; - color: #fff; - font-size: 0.8rem; -} - -.cv-edu-meta { - font-family: var(--font-mono); - font-size: 0.55rem; - color: var(--cv-accent); -} - -.cv-skills-mini-grid { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 0.8rem; -} - -.cv-skill-item { - font-size: 0.55rem; - color: var(--text-secondary); - display: flex; - gap: 5px; -} - -.history-item-gold { border-left-color: var(--cv-accent-gold) !important; } - -.history-item-title-v2 { - font-weight: 800; - color: #fff; - font-size: 1.1rem; - letter-spacing: -0.02em; -} - -.history-item-meta-v2 { - font-family: var(--font-mono); - font-size: 0.65rem; - color: var(--cv-accent-gold); - margin: 0.4rem 0 1rem; -} - -.history-item-desc-v2 { - font-size: 0.75rem; - color: var(--text-secondary); - line-height: 1.6; -} - -.gis-modal-close-btn { - position: absolute; - top: 1rem; - right: 1.5rem; - color: #fff; - font-size: 1.5rem; - cursor: pointer; - z-index: 9999; - background: rgba(0,0,0,0.5); - padding: 0.5rem; - border-radius: 5px; - border: 1px solid rgba(255,255,255,0.1); -} - -.gis-workstation-full { - width: 100%; - height: 100vh; - max-width: none; - border-radius: 0; - box-shadow: none; -} - -.gis-mono-label { - color: rgba(255, 255, 255, 0.3); -} - -.icon-accent { color: var(--accent-electric); } -.icon-white { color: #fff; } -.icon-wa { color: #25D366; } - -.submit-btn-v2 { - width: 100%; - border-radius: 12px; - border: none; -} - -.ml-8 { margin-left: 8px; } -.mr-4 { margin-right: 4px; } -.va-middle { vertical-align: middle; } - -.color-glass-1 { color: rgba(255, 255, 255, 0.1); } -.color-accent-4 { color: rgba(0, 229, 255, 0.4); } - -.plan-tier-electric { color: var(--accent-electric); } -.plan-tier-gold { color: var(--accent-gold); } - -.bg-electric { background: var(--accent-electric); } -.bg-gold { background: var(--accent-gold); } - -.icon-linkedin { color: #0077b5; } - -.btn-premium { - width: 100%; - border-radius: 12px; - box-shadow: 0 10px 30px rgba(0, 229, 255, 0.2); -} - -.btn-outline-v2 { - width: 100%; - border-radius: 12px; -} - -.w-full { width: 100%; } -.w-20 { width: 20%; } - -.color-success { color: #4ade80; } -.color-error { color: #ff4b2b; } -.color-warning { color: #ffb400; } - -.bg-purple { background: var(--purple); } - -.badge-dot-v2 { - width: 5px; - height: 5px; - border-radius: 50%; - display: inline-block; -} - -/* --- PREMIUM ENHANCEMENTS & STACK NODES --- */ - -.nav-logo-bg { - position: relative; - padding: 0.6rem 1.2rem; - border-radius: 50px; - background: linear-gradient(135deg, rgba(96, 165, 250, 0.15), rgba(30, 58, 138, 0.25)); - border: 1px solid rgba(0, 229, 255, 0.15); - display: flex; - align-items: center; - gap: 0.8rem; - transition: all 0.4s cubic-bezier(0.165, 0.84, 0.44, 1); - box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1), inset 0 0 10px rgba(96, 165, 250, 0.05); -} - -.nav-logo-bg:hover { - background: linear-gradient(135deg, rgba(96, 165, 250, 0.2), rgba(30, 58, 138, 0.35)); - border-color: rgba(0, 229, 255, 0.4); - box-shadow: 0 8px 25px rgba(0, 229, 255, 0.15); - transform: translateY(-1px); -} - -/* Standardized Premium Section Backgrounds (Higher Opacity) */ -.premium-section { - background: rgba(8, 12, 24, 0.85) !important; /* Deep Navy, higher opacity for readability */ - -webkit-backdrop-filter: blur(12px) saturate(150%); - backdrop-filter: blur(12px) saturate(150%); - border-top: 1px solid rgba(255, 255, 255, 0.06); - border-bottom: 1px solid rgba(255, 255, 255, 0.06); - position: relative; - z-index: 2; -} - -/* Increasing Global Card Opacity for Premium Feel */ -.glass-card, .plan-card-v2, .service-card-v2, .chal-card-v2, .plan-card { - background: rgba(15, 23, 42, 0.82) !important; - -webkit-backdrop-filter: blur(20px) saturate(180%); - backdrop-filter: blur(20px) saturate(180%); - border: 1px solid rgba(255, 255, 255, 0.12) !important; - box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3); -} - - -/* Hero Eyebrow Modernization */ -.hero-eyebrow-v2 { - display: inline-flex; - align-items: center; - gap: 0.6rem; - background: rgba(37, 99, 235, 0.1); - border: 1px solid rgba(37, 99, 235, 0.25); - color: var(--primary-electric); - border-radius: 50px; - padding: 0.5rem 1.4rem; - font-size: 0.85rem; - font-weight: 600; - margin-bottom: 2.5rem; - letter-spacing: 0.03em; - font-family: var(--font-main); - box-shadow: 0 4px 15px rgba(37, 99, 235, 0.1); -} - -.hero-eyebrow-v2 .dot { - width: 8px; - height: 8px; - background: var(--primary-electric); - border-radius: 50%; - box-shadow: 0 0 10px var(--primary-electric); -} - -/* Stack Section Styling */ -.stack-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); - gap: 2rem; - margin-top: 3rem; - justify-items: center; - align-items: center; -} - -.stack-item { - display: flex; - flex-direction: column; - align-items: center; - gap: 0.8rem; - opacity: 0.6; - filter: grayscale(1); - transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); -} - -.stack-item:hover { - opacity: 1; - filter: grayscale(0); - transform: translateY(-5px); -} - -.stack-item img { - height: 32px; - width: auto; -} - -.stack-item span { - font-family: var(--font-mono); - font-size: 0.7rem; - color: var(--slate-400); - text-transform: uppercase; - letter-spacing: 0.1em; -} -/* Consolidated Premium Section Styling handled above */ - -/* Enhancing existing section classes */ -.about-section-v2, .spatial-lab-section-v2, .section { - position: relative; - overflow: hidden; -} - -.infrastructure-header { - text-align: center; - margin-bottom: 4rem; -} - -.infrastructure-header h2 { - font-size: clamp(2rem, 5vw, 3.5rem); - background: linear-gradient(to right, #fff, var(--slate-400)); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - margin-bottom: 1rem; -} - -.infrastructure-header p { - color: var(--slate-400); - font-size: 1.1rem; - max-width: 600px; - margin: 0 auto; -} - -/* Timeline V3 Layout */ -.timeline-v3-layout { - display: grid; - grid-template-columns: 300px 1fr; - gap: 4rem; - align-items: start; -} - -.timeline-sidebar { - position: sticky; - top: 120px; -} - -@media (max-width: 992px) { - .timeline-v3-layout { - grid-template-columns: 1fr; - gap: 2rem; - } - - .timeline-sidebar { - position: relative; - top: 0; - } -} - -/* Infrastructure Callout - Premium Plus */ -.infrastructure-callout { - margin-top: 5rem; - padding: 3rem; - background: linear-gradient(135deg, rgba(37, 99, 235, 0.08), rgba(30, 58, 138, 0.12)); - border: 1px solid rgba(0, 229, 255, 0.2); - border-radius: 24px; - text-align: center; - position: relative; - overflow: hidden; - box-shadow: 0 20px 50px rgba(0, 0, 0, 0.2); -} - -.callout-badge { - position: absolute; - top: 1.5rem; - left: 50%; - transform: translateX(-50%); - background: var(--accent-yellow); - color: var(--primary-deep); - padding: 0.3rem 1rem; - border-radius: 50px; - font-size: 0.65rem; - font-weight: 800; - letter-spacing: 0.1em; - box-shadow: 0 4px 10px rgba(255, 180, 0, 0.3); -} - -.infrastructure-callout h3 { - color: var(--primary-electric); - margin-bottom: 1.2rem; - font-family: var(--font-main); - font-weight: 700; -} - -.infrastructure-callout p { - color: var(--slate-300); - max-width: 800px; - margin: 0 auto; - font-size: 1rem; - line-height: 1.7; -} - -.infrastructure-callout strong { - color: var(--accent-yellow); -} - -/* DGZ Engineering - Technical Utilities */ -.text-center { text-align: center; } -.mx-auto { margin-left: auto; margin-right: auto; } - -.section-header-centered { - display: flex; - flex-direction: column; - align-items: center; - text-align: center; - margin-bottom: 4rem; -} - -.section-header-centered .section-eyebrow-v2 { - justify-content: center; - margin-bottom: 1.5rem; -} - -.section-header-centered .section-title { - font-family: 'Syne', var(--font-heading); - font-size: clamp(2rem, 4vw, 3rem); - letter-spacing: -0.03em; - margin-bottom: 1rem; -} - -.section-header-centered .section-desc { - color: var(--text-secondary); - max-width: 800px; - font-size: 1.1rem; - line-height: 1.8; -} - -.icon-gold { - color: var(--accent-gold) !important; - background: rgba(255, 180, 0, 0.1) !important; - border: 1px solid rgba(255, 180, 0, 0.2); -} - -.gold-accent { - border-color: var(--accent-gold) !important; -} - -.btn-lab-launch { - display: inline-flex; - align-items: center; - gap: 8px; - background: linear-gradient(135deg, var(--accent-purple) 0%, #3C096C 100%); - color: #fff; - border: 1px solid rgba(255, 255, 255, 0.1); - padding: 0.8rem 1.5rem; - border-radius: 8px; - font-weight: 600; - transition: all 0.3s var(--ease-apple); -} - -.btn-lab-launch:hover { - transform: translateY(-2px); - box-shadow: 0 10px 20px rgba(60, 9, 108, 0.3); - border-color: rgba(255, 255, 255, 0.3); -} - -/* GeoAI Visualization Meta */ -.geoai-viz-meta { - margin-top: 1.5rem; - font-family: var(--font-mono); - font-size: 0.65rem; - color: var(--text-tertiary); - line-height: 2; -} - -.geoai-viz-meta span.red { color: #ff4b2b; } -.geoai-viz-meta span.green { color: #4ade80; } - diff --git a/assets/data/sovereign_sample.geojson b/assets/data/sovereign_sample.geojson deleted file mode 100644 index d3b50d8..0000000 --- a/assets/data/sovereign_sample.geojson +++ /dev/null @@ -1,27 +0,0 @@ -{ - "type": "FeatureCollection", - "name": "DGZ_SOVEREIGN_SAMPLE_2026", - "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, - "features": [ - { - "type": "Feature", - "properties": { "npu": "010100010001000", "area_m2": 120.5, "uso": "Residencial", "estrato": 3 }, - "geometry": { "type": "Polygon", "coordinates": [ [ [ -75.565, 6.245 ], [ -75.564, 6.245 ], [ -75.564, 6.244 ], [ -75.565, 6.244 ], [ -75.565, 6.245 ] ] ] } - }, - { - "type": "Feature", - "properties": { "npu": "010100010002000", "area_m2": 115.2, "uso": "Residencial", "estrato": 3 }, - "geometry": { "type": "Polygon", "coordinates": [ [ [ -75.564, 6.245 ], [ -75.563, 6.245 ], [ -75.563, 6.244 ], [ -75.564, 6.244 ], [ -75.564, 6.245 ] ] ] } - }, - { - "type": "Feature", - "properties": { "npu": "OVERLAP_ERROR_01", "area_m2": 50.0, "uso": "Comercial", "estrato": 4 }, - "geometry": { "type": "Polygon", "coordinates": [ [ [ -75.5645, 6.2448 ], [ -75.5635, 6.2448 ], [ -75.5635, 6.2442 ], [ -75.5645, 6.2442 ], [ -75.5645, 6.2448 ] ] ] } - }, - { - "type": "Feature", - "properties": { "npu": "SLIVER_ERROR_02", "area_m2": 0.005, "uso": "Residual", "estrato": 1 }, - "geometry": { "type": "Polygon", "coordinates": [ [ [ -75.565, 6.2451 ], [ -75.5651, 6.2451 ], [ -75.5651, 6.24511 ], [ -75.565, 6.2451 ], [ -75.565, 6.2451 ] ] ] } - } - ] -} diff --git a/assets/favicons/favicon.ico b/assets/favicons/favicon.ico deleted file mode 100644 index ddecc26..0000000 --- a/assets/favicons/favicon.ico +++ /dev/null @@ -1 +0,0 @@ - diff --git a/assets/img/geoai_after.png b/assets/img/geoai_after.png deleted file mode 100644 index abb4c01..0000000 Binary files a/assets/img/geoai_after.png and /dev/null differ diff --git a/assets/img/geoai_base.png b/assets/img/geoai_base.png deleted file mode 100644 index f9a9a76..0000000 Binary files a/assets/img/geoai_base.png and /dev/null differ diff --git a/assets/img/geoai_before.png b/assets/img/geoai_before.png deleted file mode 100644 index 7327b91..0000000 Binary files a/assets/img/geoai_before.png and /dev/null differ diff --git a/assets/img/logo-construmetrix.svg b/assets/img/logo-construmetrix.svg deleted file mode 100644 index 8cbc3bd..0000000 --- a/assets/img/logo-construmetrix.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/img/logo_icon.svg b/assets/img/logo_icon.svg deleted file mode 100644 index 15c56f9..0000000 --- a/assets/img/logo_icon.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/assets/img/topo-bg.png b/assets/img/topo-bg.png deleted file mode 100644 index 9e9a094..0000000 Binary files a/assets/img/topo-bg.png and /dev/null differ diff --git a/assets/js/dgz-core.js b/assets/js/dgz-core.js deleted file mode 100644 index 89c89ed..0000000 --- a/assets/js/dgz-core.js +++ /dev/null @@ -1,1085 +0,0 @@ -/** - * DGZ_CORE_v1.0 - Global Intelligence & Navigation - * Handles i18n, Global Header injection, and Navigation Bridges. - */ - -const dgzTranslations = { - en: { - nav_home: "Nucleus", - nav_lab: "Spatial Lab", - nav_validator: "Command Center", - nav_map: "Intel Map", - nav_projects: "Technical Assets", - nav_about: "Strategic Overview", - nav_contact: "Contact", - nav_cv: "Neural_Datasheet", - lang_switch: "ES", - back_to_core: "Return to Core", - system_status: "SYSTEM_LEVEL: SOVEREIGN", - api_connected: "API CONNECTED", - ai_active: "Groq Llama-3 Active", - - // Hero - hero_tag: "// SPATIAL_SYSTEMS_ENGINEERING", - hero_available: "Available for Projects · Medellín, Colombia", - hero_h1: "Automating Multipurpose Cadastre & Territorial Intelligence Systems", - hero_desc: "High-Performance Geospatial Engineering & Automated Systems for Multipurpose Cadastre, GovTech, and Territorial Intelligence.", - hero_btn_lab: "⭐ Explore Spatial Lab", - hero_btn_contact: "Link_Direct", - hero_btn_map: "🗺️ Intel Map", - - // CV Modal - cv_close: "EXIT_INTERFACE", - cv_label_profile: "Professional_Identity", - cv_label_skills: "Technical_DNA", - cv_label_langs: "Communication_Nodes", - cv_label_metrics: "Architectural_Impact", - cv_label_edu: "Academic_Trajectory", - cv_label_cert: "Certifications & Credentials", - cv_label_exp_main: "Current_Deployment", - cv_label_exp_log: "Operational_History", - cv_download: "Download Technical Datasheet (PDF)", - cv_summary: "Spatial Systems Engineer focused on merging high-precision GIS expertise with robust architectural design and automated software development for territorial management.", - cv_role_1: "Geographic Analyst", - cv_role_2: "GIS Coordinator", - cv_role_3: "QA/QC Specialist", - cv_role_4: "Field Operations Leader", - cv_role_5: "Drone & photogrammetry Lead", - cv_edu_1: "B.S. Spatial Engineering (Candidate)", - cv_edu_2: "Maintenance Technician", - cv_rec_1: "Management Systems", - cv_rec_2: "GIS Environmental Institute", - cv_rec_3: "Electrical Design", - cv_rec_4: "Occupational Health", - - // Capabilities / Services - cap_tag: "Specialized Services", - cap_title: "Specialized solutions for every territorial challenge", - svc_1_title: "Mass Cadastral Update", - svc_1_desc: "Management and validation of 500+ parcels per cycle. Full automation of land recognition workflow under IGAC and LADM-COL V3 standards.", - svc_2_title: "Cadastral QA/QC (Quality Control)", - svc_2_desc: "Technical audits with Python and QGIS. Automatic detection of overlaps, gaps, and topological errors. Certified PDF reports for oversight.", - svc_3_title: "Geospatial ETL Pipelines", - svc_3_desc: "Unattended transformation architecture for massive GIS data ingestion. From field to database with zero manual intervention.", - svc_4_title: "GeoAI — Change Detection", - svc_4_desc: "Machine Learning on Sentinel-2 imagery to detect urban expansion, land cover changes, and multi-temporal territorial mutations.", - svc_5_title: "Enterprise GIS Dashboards", - svc_5_desc: "Interactive interfaces connected to PostGIS for real-time territorial analysis. Visualization of cadastral indicators for executives and entities.", - svc_6_title: "GIS Field Coordination", - svc_6_desc: "Leadership of technical teams in complex terrains. Topographic leveling, mass digitization, and coordination under NSR-10 regulations.", - - // Challenges - chal_tag: "Territorial Challenges", - chal_title: "What I solve for your entity", - chal_desc: "Governments and territorial entities face critical spatial data challenges that hinder development. These are the problems I transform into automated solutions.", - chal_prob_1: "Slow and error-prone manual QA", - chal_sol_1: "Automated validation with Python + PostGIS", - chal_prob_2: "Inconsistent parcel data", - chal_sol_2: "Structured LADM-COL spatial modeling", - chal_prob_3: "Slow digitization processes", - chal_sol_3: "Automated GIS pipelines with GDAL/FME", - chal_prob_4: "Broken cadastral topology", - chal_sol_4: "Automated topological validation engines", - chal_prob_5: "No visibility on land cover changes", - chal_sol_5: "GeoAI: Change detection with Sentinel + Rasterio", - - // About - about_label: "Engineering Core", - about_title: "GIS Excellence & Software Architecture", - about_h3: "GIS EXCELLENCE & SOFTWARE ARCHITECTURE.", - about_p1: "We bridge the gap between traditional GIS mapping and scalable software architecture. Focused on high-precision data flows and technical automation. Our core transforms unstructured geographic data into automated, sovereign territorial intelligence.", - - // Tech DNA - tech_tag: "Tech Stack", - tech_title: "The Engineering Matrix", - tech_infra: "GIS_SPATIAL_INFRA", - tech_infra_desc: "PostGIS topology matrix, LADM-COL V3 compliance, and high-fidelity vector architecture.", - tech_sys: "SYSTEMS_ENGINEERING", - tech_sys_desc: "Backend systems for spatial intelligence, RESTful Node architecture, and automated logic.", - tech_auto: "AUTOMATION_DEVOPS", - tech_auto_desc: "CI/CD pipelines for geospatial assets, containerized spatial nodes, and kernel optimization.", - - // Metrics - metrics_label: "Proven Performance", - metrics_title: "Impact Metrics", - metrics_1_label: "Spatial Records Processed", - metrics_1_sub: "Parcels // Cartography // Cadastre", - metrics_2_label: "Error Margin Reduction", - metrics_2_sub: "QA/QC // Automation // Validation", - metrics_3_label: "Operational Efficiency", - metrics_3_sub: "ROI // Workflow Automation", - metrics_4_label: "Multipurpose Cadastre Projects", - metrics_4_sub: "LADM-COL // IGAC Standards", - - // Lab - lab_title: "Spatial Intelligence Laboratory", - lab_desc: "High-performance geospatial nodes demonstrating territorial automation, multipurpose cadastral engines, and advanced spatial systems engineering.", - lab_live: "The following assets are active demonstrations, not mere placeholders.", - lab_gesture: "Free Trial: Vision Sandbox (Gestural AI)", - lab_p1_title: "Interactive Spatial Node", - lab_p1_desc: "High-precision GIS viewer with real-time parcel rendering. Interacting with local datasets exported from QGIS with deep topology attributes.", - lab_p1_btn: "EXECUTE_VIEWER", - lab_p2_title: "Cadastral Intelligence Engine", - lab_p2_desc: "Automated LADM-COL V3 validator. Detecting overlaps, slivers, and topological inconsistencies using high-fidelity Python kernels.", - lab_p2_btn: "INITIALIZE_VAL_ENGINE", - lab_p2_full: "ACCESS_FULL_INTERFACE", - lab_p3_title: "Sovereign Data Pipelines", - lab_p3_desc: "Unattended ETL architecture for massive geospatial ingestion, ensuring data integrity across distributed GIS nodes.", - - // Projects - proj_label: "// FLAGSHIP_ASSETS", - proj_title: "Technical Deployments", - proj_1_desc: "Enterprise level GIS monitoring for modern urban infrastructure. Synchronizing real-time telemetry across distributed nodes.", - proj_2_title: "Territorial ETL Pipelines", - proj_2_desc: "Unattended automation of geographic data transformations to avoid slow manual processes.", - proj_3_title: "Enterprise GIS Dashboard", - proj_3_desc: "Interactive interface connected to PostGIS for territorial analysis and real-time telemetry.", - proj_4_title: "LADM-COL QGIS Plugin", - proj_4_desc: "Scripts inserted as native tools in the QGIS UI for instantaneous topological validation.", - proj_5_title: "GeoAI Experimental", - proj_5_desc: "Machine Learning prototype lab on Sentinel-2 for urban change detection.", - proj_6_title: "Geo-LLM Intelligence", - proj_6_desc: "Artificial Intelligence agent that translates natural language into Spatial SQL queries and generates statistical cadastral reports in real-time.", - - // GeoAI - geoai_label: "// GEOAI_MODULE", - geoai_title: "GeoAI Intelligence", - geoai_sub: "Urban Change Detection with Sentinel Imagery", - geoai_desc: "Application of geospatial artificial intelligence to detect urban and rural cover changes by comparing multi-temporal satellite images. Complete pipeline from Sentinel download to GeoJSON export.", - geoai_step_1_title: "Sentinel-2 Imagery Download", - geoai_step_1_desc: "Copernicus API // Spectral bands B04, B08, B11 // 10m resolution", - geoai_step_2_title: "Processing with Rasterio + GeoPandas", - geoai_step_2_desc: "Radiometric normalization // Multi-temporal comparison // NumPy arrays", - geoai_step_3_title: "Classification with Scikit-learn", - geoai_step_3_desc: "Random Forest // Change detection // Polygon vectorization", - geoai_step_4_title: "GeoJSON Export → Web GIS", - geoai_step_4_desc: "MapLibre GL visualization // PostGIS integration // REST API", - geoai_status: "[CHANGE_DETECTION_ENGINE] STATUS: PROCESSING_DEMO", - - // Architecture - arch_label: "// ENGINEERING_ARCHITECTURE", - arch_title: "System Architecture", - arch_desc: "Complete architecture of the modern GovTech stack — from field capture to web publication. Designed to scale at municipal, departmental, or national levels.", - arch_node_1: "Field Capture", - arch_node_1_sub: "GPS // 360° Survey // Drones", - arch_node_2: "Python Validation Engine", - arch_node_2_sub: "GDAL // GeoPandas // Shapely", - arch_node_3: "PostGIS Database", - arch_node_3_sub: "PostgreSQL // LADM-COL Schema", - arch_node_4: "FastAPI Spatial API", - arch_node_4_sub: "/validate // /topology // /parcel_score", - arch_node_5: "Web GIS Interface", - arch_node_5_sub: "MapLibre GL JS // Chart.js", - - // Timeline - timeline_label: "Professional Trajectory", - timeline_title: "Professional Trajectory", - timeline_desc: "6+ years of specialized GIS and territorial engineering across Colombia's most complex cadastral projects.", - tl_role_1: "Geographic Analyst", - tl_desc_1: "Advanced geospatial processing via photointerpretation, 360° input analysis and vector restitution. Mass digitization for cadastral update with topological validation under LADM-COL V3.", - tl_role_2: "Cadastral Quality Control (QA/QC)", - tl_desc_2: "Technical quality audits for predial recognition. IGAC QA standards enforcement, topological consistency checks, and field report validation.", - tl_role_3: "GIS Coordinator & Field Leader", - tl_desc_3: "Co-leader of field survey teams. Urban/rural topographic leveling, mass digitization, and GIS coordination for multipurpose cadastre missions in complex terrain.", - tl_role_4: "Professional GIS Coordinator", - tl_desc_4: "LADM-COL standards implementation, mass digitization and GIS coordination for Smart City multipurpose cadastre deployment. QA/QC across distributed field nodes.", - tl_role_5: "GIS Professional — Drones & Geomatics", - tl_desc_5: "Drone-based photogrammetric surveys, predial management, and vector GIS production. Spatial analysis and cartographic outputs for real estate and environmental projects.", - tl_role_6: "Digitizer / Topographer", - tl_desc_6: "Road topography surveys and GIS digitization for vial infrastructure projects. GPS field surveys and cartographic production under professional standards.", - - // Map - map_label: "// SPATIAL_INTEL_WORKSTATION_V6", - map_title: "Territorial Intelligence Hub", - map_desc: "Full-stack GIS workstation — interactive parcel data, toggleable layers, real coordinate intelligence, and live attribute queries. Click any map node to inspect its LADM-COL attributes.", - map_layer_manager: "LAYER_MANAGER", - map_vector_layers: "VECTOR_LAYERS", - map_legend_label: "LEGEND", - map_projection_label: "PROJECTION INFO", - map_identify_hint: "IDENTIFY MODE — Click a feature to inspect", - legend_hq_node: "HQ Node — Active", - legend_field_node: "Field Node — Remote", - legend_parcel_validated: "Parcel — Validated", - legend_parcel_error: "Parcel — Error", - legend_urban_perimeter: "Urban Perimeter", - - // Pricing - pricing_tag: "ACQUIRE_OS_LICENSE // SPATIAL_INTELLIGENCE_SaaS", - pricing_desc: "The most advanced cadastral validation engine in Latin America. Designed for auditing, municipalities, and GIS contractors who need real results.", - pricing_roi_1: "Faster than manual QA", - pricing_roi_2: "Error Reduction", - pricing_roi_3: "Parcels Processed", - pricing_roi_4: "V3 Certified Engine", - pricing_bad_header: "⛔ WITHOUT DGZ SPATIAL OS", - pricing_good_header: "✅ WITH DGZ SPATIAL OS", - pricing_bad_1: "Manual QA: 3-5 days per municipality", - pricing_bad_2: "Undetected topological errors", - pricing_bad_3: "Manual SNR crossing (error-prone)", - pricing_bad_4: "Non-standard Excel reports", - pricing_bad_5: "No traceability on mutation history", - pricing_good_1: "Automatic validation in minutes", - pricing_good_2: "LADM-COL V3 topological engine", - pricing_good_3: "Automatic SNR matricular crossing", - pricing_good_4: "Certified Technical PDF and GeoJSON", - pricing_good_5: "Full traceability of every parcel", - - plan_starter_tier: "STARTER_CORE", - plan_starter_name: "Spatial Explorer", - plan_starter_for: "For GIS professionals, technicians, and advanced students.", - plan_starter_price: "$0", - plan_starter_period: "/month · Forever Free", - plan_starter_cap: "Capacity: 5,000 parcels/layer", - plan_starter_feat_1: "Basic LADM-COL topological validation", - plan_starter_feat_2: "Up to 5,000 parcels per layer", - plan_starter_feat_3: "5 Geo-LLM Reports / day", - plan_starter_feat_4: "Embedded interactive GIS viewer", - plan_starter_no_1: "Physical-Legal SNR Cross-check", - plan_starter_no_2: "FastAPI for automation", - plan_starter_no_3: "Premium technical support", - plan_starter_btn: "Get Started Free", - - plan_pro_tier: "INTERVENTORÍA_PRO", - plan_pro_name: "Spatial Pro", - plan_pro_for: "For handover contracts, massive QA/QC, and technical teams.", - plan_pro_price: "$10", - plan_pro_period: "/month · per user", - plan_pro_cap: "Capacity: Unlimited ∞", - plan_pro_feat_1: "Unlimited parcels (.shp / .gpkg)", - plan_pro_feat_2: "Automatic SNR Matricular Crossing (Excel)", - plan_pro_feat_3: "Certified technical PDF reports", - plan_pro_feat_4: "FastAPI for full automation", - plan_pro_feat_5: "Export GeoJSON + PostGIS ready", - plan_pro_feat_6: "Real-time analytics dashboard", - plan_pro_feat_7: "48h priority technical support", - plan_pro_btn: "Acquire Pro License", - plan_pro_trust: "🔒 Secure payment · Cancel anytime", - - plan_gov_tier: "GOVERNMENT_NODE", - plan_gov_name: "Sovereign Tier", - plan_gov_for: "For Cadastre Offices, IGAC, Municipalities, and large contractors.", - plan_gov_price: "Custom", - plan_gov_period: "/project · On-prem available", - plan_gov_cap: "Enterprise-Scale · Dedicated Infra", - plan_gov_feat_1: "On-Premises deployment (own servers)", - plan_gov_feat_2: "SGDEA / Municipal Tax integration", - plan_gov_feat_3: "Fine-tuned Geo-LLM models for the municipality", - plan_gov_feat_4: "On-site training for the GIS team", - plan_gov_feat_5: "Guaranteed technical SLA (72h response)", - plan_gov_feat_6: "White-label: municipality's own brand", - plan_gov_feat_7: "Full access to source code (license)", - plan_gov_btn: "Contact Architect", - plan_gov_trust: "Response in < 24h · NDA available", - - // Contact - contact_label: "Start a Project", - contact_title: "Let's discuss your
next project.", - contact_desc: "Architecting the next generation of spatial intelligence. Let's discuss your project, municipality, or enterprise GIS challenge.", - contact_email_label: "Email", - contact_loc_label: "Location", - contact_linkedin_label: "LinkedIn", - contact_github_label: "GitHub", - form_name: "Full_Name", - form_placeholder_name: "Organization / Lead Architect", - form_email: "Email_Uplink", - form_service: "Service_Type", - form_service_select: "— Select Service —", - form_svc_1: "GIS Automation & ETL Pipeline", - form_svc_2: "Cadastral QA/QC (LADM-COL)", - form_svc_3: "Enterprise GIS Dashboard", - form_svc_4: "GeoAI / Satellite Analysis", - form_svc_5: "Government / Municipal Project", - form_svc_6: "Other / Consulting", - form_msg: "Mission_Brief", - form_placeholder_msg: "Define mission parameters & objectives...", - form_btn: "INITIATE_HANDSHAKE", - - // Footer - footer_copy: "© 2026 ALBERT DANIEL GAVIRIA ZAPATA. ALL RIGHTS RESERVED.", - - boot_1: "DGZ_OS_v5.2_SOVEREIGN [BOOT_SEQUENCE_INIT]", - boot_2: "Mounting PostGIS Vector Engine... OK", - boot_3: "Initializing LADM-COL Validation Matrix...", - boot_4: "Hydrating Spatial Intelligence Layers...", - boot_5: "Handshaker: Geo-LLM Proxy Status... CONNECTED", - boot_6: "DGZ_CORE: Decrypting Sovereign Credentials...", - boot_7: "ACCESS_GRANTED: Welcome, Engineer Zapata.", - - demo_btn_run: "RUN_VALIDATION_DEMO", - demo_btn_processing: "PROCESSING_NODES...", - demo_log_1: "[ENGINE] Initializing LADM-COL V3 ruleset...", - demo_log_2: "Extracting geometries via GeoPandas...", - demo_log_3: "Checking overlap matrix (O(n log n))...", - demo_log_4: "Analyzing sliver polygons < 0.05m2...", - demo_log_5: "CONSULTING_DGZ_ENGINE: PASS" - }, - es: { - nav_home: "Núcleo", - nav_lab: "Lab Espacial", - nav_validator: "Centro de Mando", - nav_map: "Mapa Intel", - nav_projects: "Activos Técnicos", - nav_about: "Visión Estratégica", - nav_contact: "Contacto", - nav_cv: "Datasheet_Neural", - lang_switch: "EN", - back_to_core: "Volver al Núcleo", - system_status: "NIVEL_SISTEMA: SOBERANO", - api_connected: "API CONECTADA", - ai_active: "Groq Llama-3 Activo", - - // Hero - hero_tag: "// INGENIERÍA_DE_SISTEMAS_ESPACIALES", - hero_available: "Disponible para Proyectos · Medellín, Colombia", - hero_h1: "Automatizando Sistemas de Inteligencia Territorial y Catastro Multipropósito", - hero_desc: "Ingeniería Geoespacial de Alto Rendimiento y Sistemas Automatizados para Catastro Multipropósito, GovTech e Inteligencia Territorial.", - hero_btn_lab: "⭐ Explorar Lab Espacial", - hero_btn_contact: "Enlace_Directo", - hero_btn_map: "🗺️ Mapa Intel", - - // CV Modal - cv_close: "SALIR_INTERFAZ", - cv_label_profile: "Identidad_Profesional", - cv_label_skills: "ADN_Técnico", - cv_label_langs: "Nodos_Comunicación", - cv_label_metrics: "Impacto_Arquitectónico", - cv_label_edu: "Trayectoria_Académica", - cv_label_cert: "Certificaciones y Credenciales", - cv_label_exp_main: "Despliegue_Actual", - cv_label_exp_log: "Historial_Operativo", - cv_download: "Descargar Datasheet Técnico (PDF)", - cv_summary: "Ingeniero de Sistemas Espaciales enfocado en fusionar la experiencia SIG de alta precisión con un diseño arquitectónico robusto y desarrollo de software automatizado para la gestión territorial.", - cv_role_1: "Analista Geográfico", - cv_role_2: "Coordinador Profesional SIG", - cv_role_3: "Control Calidad Catastral (QA/QC)", - cv_role_4: "Coordinador & Líder de Campo", - cv_role_5: "Profesional SIG (Drones & GIS)", - cv_edu_1: "Ingeniería de Sistemas (C)", - cv_edu_2: "Técnico Conservación", - cv_rec_1: "Sistemas de Gestión", - cv_rec_2: "Instituto Ambiental SIG", - cv_rec_3: "Diseño Eléctrico", - cv_rec_4: "Seguridad y Salud", - - // Capabilities / Services - cap_tag: "Servicios Especializados", - cap_title: "Soluciones especializadas para cada desafío territorial", - svc_1_title: "Actualización Catastral Masiva", - svc_1_desc: "Gestión y validación de +500 predios por ciclo. Automatización completa del flujo de reconocimiento predial bajo estándares IGAC y LADM-COL V3.", - svc_2_title: "QA/QC Catastral (Control de Calidad)", - svc_2_desc: "Auditorías técnicas con Python y QGIS. Detección automática de solapamientos, huecos y errores topológicos. Reportes PDF certificados para interventoría.", - svc_3_title: "Pipelines ETL Geoespaciales", - svc_3_desc: "Arquitectura de transformación desatendida para ingesta masiva de datos GIS. De campo a base de datos sin intervención manual.", - svc_4_title: "GeoAI — Detección de Cambios", - svc_4_desc: "Machine Learning sobre imagenería Sentinel-2 para detectar expansión urbana, cambios de cobertura y mutaciones territoriales multitemporales.", - svc_5_title: "Dashboards GIS Empresariales", - svc_5_desc: "Interfaces interactivas conectadas a PostGIS para análisis territorial en tiempo real. Visualización de indicadores catastrales para directivos y entidades.", - svc_6_title: "Coordinación de Campo GIS", - svc_6_desc: "Liderazgo de equipos técnicos en terrenos complejos. Nivelación topográfica, digitalización masiva y coordinación bajo normativa NSR-10.", - - // Challenges - chal_tag: "Desafíos Territoriales", - chal_title: "Lo que resuelvo para su entidad", - chal_desc: "Los gobiernos y entidades territoriales enfrentan desafíos críticos de datos espaciales que frenan el desarrollo. Estos son los problemas que transformo en soluciones automatizadas.", - chal_prob_1: "QA manual lento y propenso a errores", - chal_sol_1: "Validación automática con Python + PostGIS", - chal_prob_2: "Datos prediales inconsistentes", - chal_sol_2: "Modelado espacial LADM-COL estructurado", - chal_prob_3: "Procesos de digitalización lentos", - chal_sol_3: "Pipelines SIG automatizados con GDAL/FME", - chal_prob_4: "Topología catastral rota", - chal_sol_4: "Motores de validación topológica automatizados", - chal_prob_5: "Sin visibilidad sobre cambios de cobertura", - chal_sol_5: "GeoAI: detección cambios con Sentinel + Rasterio", - - // About - about_label: "Núcleo de Ingeniería", - about_title: "Excelencia GIS & Arquitectura de Software", - about_h3: "EXCELENCIA SIG Y ARQUITECTURA DE SOFTWARE.", - about_p1: "Cerramos la brecha entre el mapeo SIG tradicional y la arquitectura de software escalable. Enfocados en flujos de datos de alta precisión y automatización técnica. Nuestro núcleo transforma datos geográficos sin estructura en inteligencia territorial automatizada y soberana.", - - // Tech DNA - tech_tag: "Stack Tecnológico", - tech_title: "La Matriz de Ingeniería", - tech_infra: "INFRAESTRUCTURA_ESPACIAL_SIG", - tech_infra_desc: "Matriz de topología PostGIS, cumplimiento LADM-COL V3 y arquitectura vectorial de alta fidelidad.", - tech_sys: "INGENIERÍA_DE_SISTEMAS", - tech_sys_desc: "Sistemas backend para inteligencia espacial, arquitectura Node RESTful y lógica automatizada.", - tech_auto: "AUTOMATIZACIÓN_DEVOPS", - tech_auto_desc: "Pipelines CI/CD para activos geoespaciales, nodos espaciales en contenedores y optimización de kernel.", - - // Metrics - metrics_label: "Rendimiento Comprobado", - metrics_title: "Métricas de Impacto", - metrics_1_label: "Registros Espaciales Procesados", - metrics_1_sub: "Predios // Cartografía // Catastro", - metrics_2_label: "Reducción del Margen de Error", - metrics_2_sub: "QA/QC // Automatización // Validación", - metrics_3_label: "Eficiencia Operativa", - metrics_3_sub: "ROI // Automatización de Workflow", - metrics_4_label: "Proyectos de Catastro Multipropósito", - metrics_4_sub: "LADM-COL // Estándares IGAC", - - // Lab - lab_title: "Laboratorio de Inteligencia Espacial", - lab_desc: "Nodos geoespaciales de alto rendimiento que demuestran automatización territorial, motores catastrales multipropósito e ingeniería de sistemas espaciales avanzada.", - lab_live: "Los siguientes activos son demostraciones activas, no simples marcadores.", - lab_gesture: "Prueba Gratuita: Vision Sandbox (IA Gestual)", - lab_p1_title: "Nodo Espacial Interactivo", - lab_p1_desc: "Visor SIG de alta precisión con renderizado de predios en tiempo real. Interactuando con datasets locales exportados de QGIS con atributos topológicos profundos.", - lab_p1_btn: "EJECUTAR_VISOR", - lab_p2_title: "Motor de Inteligencia Catastral", - lab_p2_desc: "Validador automatizado LADM-COL V3. Detección de traslapes, slivers e inconsistencias topológicas utilizando kernels de Python de alta fidelidad.", - lab_p2_btn: "INICIALIZAR_MOTOR_VAL", - lab_p2_full: "ACCEDER_INTERFAZ_COMPLETA", - lab_p3_title: "Pipelines de Datos Soberanos", - lab_p3_desc: "Arquitectura ETL desatendida para ingesta geoespacial masiva, garantizando la integridad de los datos en nodos SIG distribuidos.", - - // Projects - proj_label: "// ACTIVOS_ESTRELLA", - proj_title: "Despliegues Técnicos", - proj_1_desc: "Monitoreo SIG de nivel empresarial para infraestructura urbana moderna. Sincronización de telemetría en tiempo real entre nodos distribuidos.", - proj_2_title: "Pipelines ETL Territoriales", - proj_2_desc: "Automatización desatendida de transformaciones de datos geográficos para evitar procesos manuales lentos.", - proj_3_title: "Tablero GIS Empresarial", - proj_3_desc: "Interfaz interactiva conectada a PostGIS para análisis territorial y telemetría en tiempo real.", - proj_4_title: "Plugin QGIS LADM-COL", - proj_4_desc: "Scripts insertados como herramientas nativas en la UI de QGIS para validación topológica instantánea.", - proj_5_title: "GeoAI Experimental", - proj_5_desc: "Laboratorio de prototipos de Machine Learning sobre Sentinel-2 para detección de cambios urbanos.", - proj_6_title: "Inteligencia Geo-LLM", - proj_6_desc: "Agente de Inteligencia Artificial que traduce lenguaje natural a sentencias Spatial SQL y genera informes catastrales estadísticos en tiempo real.", - - // GeoAI - geoai_label: "// MÓDULO_GEOAI", - geoai_title: "Inteligencia GeoAI", - geoai_sub: "Detección de Cambios Urbanos con Imágenes Sentinel", - geoai_desc: "Aplicación de inteligencia artificial geoespacial para detectar cambios de cobertura urbana y rural comparando imágenes satelitales multitemporales. Pipeline completo desde descarga Sentinel hasta exportación GeoJSON.", - geoai_step_1_title: "Descarga de Imágenes Sentinel-2", - geoai_step_1_desc: "API Copernicus // Bandas espectrales B04, B08, B11 // resolución 10m", - geoai_step_2_title: "Procesamiento con Rasterio + GeoPandas", - geoai_step_2_desc: "Normalización radiométrica // Comparación multitemporal // NumPy arrays", - geoai_step_3_title: "Clasificación con Scikit-learn", - geoai_step_3_desc: "Random Forest // Detección de cambios // Vectorización de polígonos", - geoai_step_4_title: "Exportación GeoJSON → Web GIS", - geoai_step_4_desc: "Visualización en MapLibre GL // Integración PostGIS // API REST", - geoai_status: "[MOTOR_DETECCIÓN_CAMBIOS] ESTADO: PROCESANDO_DEMO", - - // Architecture - arch_label: "// ARQUITECTURA_DE_INGENIERÍA", - arch_title: "Arquitectura del Sistema", - arch_desc: "Arquitectura completa del stack GovTech moderno — desde captura en campo hasta publicación web. Diseñado para escalar a nivel municipal, departamental o nacional.", - arch_node_1: "Captura en Campo", - arch_node_1_sub: "GPS // Levantamiento 360° // Drones", - arch_node_2: "Motor de Validación Python", - arch_node_2_sub: "GDAL // GeoPandas // Shapely", - arch_node_3: "Base de Datos PostGIS", - arch_node_3_sub: "PostgreSQL // Esquema LADM-COL", - arch_node_4: "FastAPI Spatial API", - arch_node_4_sub: "/validate // /topology // /parcel_score", - arch_node_5: "Interfaz Web GIS", - arch_node_5_sub: "MapLibre GL JS // Chart.js", - - // Timeline - timeline_label: "Trayectoria Profesional", - timeline_title: "Trayectoria Profesional", - timeline_desc: "Más de 6 años de experiencia especializada en SIG e ingeniería territorial en los proyectos catastrales más complejos de Colombia.", - tl_role_1: "Analista Geográfico", - tl_desc_1: "Procesamiento avanzado de información geoespacial mediante fotointerpretación, análisis de insumos 360° y restitución vectorial. Digitalización masiva para actualización catastral con validación topológica bajo LADM-COL V3.", - tl_role_2: "Control de Calidad Catastral (QA/QC)", - tl_desc_2: "Auditorías de calidad técnica para reconocimiento predial. Aplicación de estándares de calidad IGAC, comprobaciones de consistencia topológica y validación de informes de campo.", - tl_role_3: "Coordinador SIG y Líder de Campo", - tl_desc_3: "Co-líder de equipos de levantamiento de campo. Nivelación topográfica urbana/rural, digitalización masiva y coordinación SIG para misiones de catastro multipropósito en terrenos complejos.", - tl_role_4: "Coordinador Profesional SIG", - tl_desc_4: "Implementación de estándares LADM-COL, digitalización masiva y coordinación SIG para despliegue de catastro multipropósito en Smart Cities. QA/QC en nodos de campo distribuidos.", - tl_role_5: "Profesional SIG — Drones y Geomática", - tl_desc_5: "Levantamientos fotogramétricos con drones, gestión predial y producción SIG vectorial. Análisis espacial y salidas cartográficas para proyectos inmobiliarios y ambientales.", - tl_role_6: "Digitalizador / Topógrafo", - tl_desc_6: "Levantamientos topográficos viales y digitalización SIG para proyectos de infraestructura víal. Levantamientos de campo con GPS y producción cartográfica bajo estándares profesionales.", - - // Map - map_label: "// ESTACIÓN_DE_TRABAJO_INTEL_ESPACIAL_V6", - map_title: "Hub de Inteligencia Territorial", - map_desc: "Estación de trabajo SIG completa — datos prediales interactivos, capas conmutables, inteligencia de coordenadas reales y consultas de atributos en vivo. Haga clic en cualquier nodo del mapa para inspeccionar sus atributos LADM-COL.", - map_layer_manager: "GESTOR_CAPAS", - map_vector_layers: "CAPAS_VECTORIALES", - map_legend_label: "LEYENDA", - map_projection_label: "INFO PROYECCIÓN", - map_identify_hint: "MODO IDENTIFICAR — Click en un elemento para inspeccionar", - legend_hq_node: "Nodo HQ — Activo", - legend_field_node: "Nodo Campo — Remoto", - legend_parcel_validated: "Predio — Validado", - legend_parcel_error: "Predio — Error", - legend_urban_perimeter: "Perímetro Urbano", - - // Pricing - pricing_tag: "ADQUIRIR_LICENCIA_OS // Inteligencia_Espacial_SaaS", - pricing_desc: "El motor de validación catastral más avanzado de Latinoamérica. Diseñado para interventorías, municipios y contratistas SIG que necesitan resultados reales.", - pricing_roi_1: "Más rápido que QA manual", - pricing_roi_2: "Reducción de Errores", - pricing_roi_3: "Predios Procesados", - pricing_roi_4: "Motor Certificado V3", - pricing_bad_header: "⛔ SIN DGZ SPATIAL OS", - pricing_good_header: "✅ CON DGZ SPATIAL OS", - pricing_bad_1: "QA manual: 3-5 días por municipio", - pricing_bad_2: "Errores topológicos sin detectar", - pricing_bad_3: "Cruce SNR manual (propenso a error)", - pricing_bad_4: "Reportes en Excel sin estándar", - pricing_bad_5: "Sin trazabilidad sobre historia de mutaciones", - pricing_good_1: "Validación automática en minutos", - pricing_good_2: "Motor topológico LADM-COL V3", - pricing_good_3: "Cruce matricular automático SNR", - pricing_good_4: "PDF Técnico y GeoJSON certificado", - pricing_good_5: "Trazabilidad completa de cada predio", - - plan_starter_tier: "STARTER_CORE", - plan_starter_name: "Explorador Espacial", - plan_starter_for: "Para profesionales SIG, técnicos y estudiantes avanzados.", - plan_starter_price: "$0", - plan_starter_period: "/mes · Gratis por Siempre", - plan_starter_cap: "Capacidad: 5,000 predios/capa", - plan_starter_feat_1: "Validación topológica LADM-COL básica", - plan_starter_feat_2: "Hasta 5,000 predios por capa", - plan_starter_feat_3: "5 Reportes Geo-LLM / día", - plan_starter_feat_4: "Visor GIS interactivo embebido", - plan_starter_no_1: "Cruce Físico-Jurídico SNR", - plan_starter_no_2: "API FastAPI para automatización", - plan_starter_no_3: "Soporte técnico premium", - plan_starter_btn: "Comenzar Gratis", - - plan_pro_tier: "INTERVENTORÍA_PRO", - plan_pro_name: "Spatial Pro", - plan_pro_for: "Para contratos de empalme, QA/QC masivo y equipos técnicos.", - plan_pro_price: "$10", - plan_pro_period: "/mes · por usuario", - plan_pro_cap: "Capacidad: Ilimitada ∞", - plan_pro_feat_1: "Predios ilimitados (.shp / .gpkg)", - plan_pro_feat_2: "Cruce Matricular SNR automático (Excel)", - plan_pro_feat_3: "Reportes PDF técnicos certificados", - plan_pro_feat_4: "FastAPI para automatización completa", - plan_pro_feat_5: "Export GeoJSON + PostGIS ready", - plan_pro_feat_6: "Dashboard de analítica en tiempo real", - plan_pro_feat_7: "Soporte técnico prioritario 48h", - plan_pro_btn: "Adquirir Licencia Pro", - plan_pro_trust: "🔒 Pago seguro · Cancela cuando quieras", - - plan_gov_tier: "NODO_GUBERNAMENTAL", - plan_gov_name: "Nivel Soberano", - plan_gov_for: "Para Oficinas de Catastro, IGAC, Alcaldías y grandes contratistas.", - plan_gov_price: "Personalizado", - plan_gov_period: "/proyecto · On-prem disponible", - plan_gov_cap: "Escala Empresarial · Infra Dedicada", - plan_gov_feat_1: "Despliegue On-Premises (servidores propios)", - plan_gov_feat_2: "Integración SGDEA / Rentas municipales", - plan_gov_feat_3: "Modelos Geo-LLM ajustados al municipio", - plan_gov_feat_4: "Capacitación presencial del equipo SIG", - plan_gov_feat_5: "SLA técnico garantizado (72h respuesta)", - plan_gov_feat_6: "White-label: marca propia del municipio", - plan_gov_feat_7: "Acceso total al código fuente (licencia)", - plan_gov_btn: "Contactar Arquitecto", - plan_gov_trust: "Respuesta en < 24h · NDA disponible", - - // Contact - contact_label: "Iniciar Proyecto", - contact_title: "Hablemos de su
próximo proyecto.", - contact_desc: "Arquitectando la próxima generación de inteligencia espacial. Hablemos de su proyecto, municipio o desafío SIG empresarial.", - contact_email_label: "Correo", - contact_loc_label: "Ubicación", - contact_linkedin_label: "LinkedIn", - contact_github_label: "GitHub", - form_name: "Nombre_Completo", - form_placeholder_name: "Organización / Arquitecto Líder", - form_email: "Enlace_Email", - form_service: "Tipo_de_Servicio", - form_service_select: "— Seleccionar Servicio —", - form_svc_1: "Automatización SIG y Pipeline ETL", - form_svc_2: "QA/QC Catastral (LADM-COL)", - form_svc_3: "Tablero GIS Empresarial", - form_svc_4: "GeoAI / Análisis Satelital", - form_svc_5: "Proyecto Gubernamental / Municipal", - form_svc_6: "Otro / Consultoría", - form_msg: "Breve_de_Misión", - form_placeholder_msg: "Defina parámetros y objetivos de la misión...", - form_btn: "INICIAR_HANDSHAKE", - - // Footer - footer_copy: "© 2026 ALBERT DANIEL GAVIRIA ZAPATA. TODOS LOS DERECHOS RESERVADOS.", - - boot_1: "DGZ_OS_v5.2_SOBERANO [INICIANDO_SECUENCIA_ARRANQUE]", - boot_2: "Montando Motor Vectorial PostGIS... OK", - boot_3: "Inicializando Matriz de Validación LADM-COL...", - boot_4: "Hidratando Capas de Inteligencia Espacial...", - boot_5: "Estado Proxy Geo-LLM... CONECTADO", - boot_6: "DGZ_CORE: Desencriptando Credenciales Soberanas...", - boot_7: "ACCESO_CONCEDIDO: Bienvenido, Ingeniero Zapata.", - - demo_btn_run: "EJECUTAR_DEMO_VALIDACIÓN", - demo_btn_processing: "PROCESANDO_NODOS...", - demo_log_1: "[MOTOR] Inicializando reglas LADM-COL V3...", - demo_log_2: "Extrayendo geometrías vía GeoPandas...", - demo_log_3: "Comprobando matriz de traslapes (O(n log n))...", - demo_log_4: "Analizando polígonos astilla < 0.05m2...", - demo_log_5: "CONSULTANDO_MOTOR_DGZ: PASA" - } -}; - -class DGZCore { - constructor() { - this.lang = localStorage.getItem('dgz_lang') || 'es'; - this.init(); - } - - init() { - document.addEventListener('DOMContentLoaded', () => { - // Skip terminal intro and load page directly - const intro = document.getElementById('terminal-intro'); - if (intro) intro.remove(); - - this.applyTranslations(); - this.setupListeners(); - this.injectHeader(); - this.setupScrollListener(); - this.setupNeuralNodes(); - this.setupIntersectionObserver(); - this.setupMouseTracking(); - this.initAssistant(); - this.startTelemetry(); - - // Initialize Tactical GIS Workstation if map exists - if (document.getElementById('intel-map')) { - this.gis = new GISWorkstation(); - } - }); - } - - setupNeuralNodes() { - const container = document.getElementById('neural-nodes'); - if (!container) return; - - const nodeCount = 25; - for (let i = 0; i < nodeCount; i++) { - const node = document.createElement('div'); - node.className = 'node'; - - // Random parameters for organic feel - const left = Math.random() * 100; - const size = Math.random() * 3 + 1; - const delay = Math.random() * 20; - const duration = 15 + Math.random() * 10; - - node.style.left = `${left}%`; - node.style.width = `${size}px`; - node.style.height = `${size}px`; - node.style.animationDelay = `-${delay}s`; - node.style.animationDuration = `${duration}s`; - - container.appendChild(node); - } - } - - setupIntersectionObserver() { - const options = { - threshold: 0.15, - rootMargin: '0px 0px -50px 0px' - }; - - const observer = new IntersectionObserver((entries) => { - entries.forEach(entry => { - if (entry.isIntersecting) { - entry.target.classList.add('revealed'); - // Optional: stop observing once revealed for performance - // observer.unobserve(entry.target); - } - }); - }, options); - - document.querySelectorAll('.reveal').forEach(el => observer.observe(el)); - } - - setupScrollListener() { - const header = document.getElementById('dgz-global-header'); - if (!header) return; - - window.addEventListener('scroll', () => { - // Scrolled class toggle - if (window.scrollY > 50) { - header.classList.add('scrolled'); - } else { - header.classList.remove('scrolled'); - } - - // Scroll progress calculation - const winScroll = document.body.scrollTop || document.documentElement.scrollTop; - const height = document.documentElement.scrollHeight - document.documentElement.clientHeight; - const scrolled = (winScroll / height) * 100; - header.style.setProperty('--scroll-width', scrolled + '%'); - }); - } - - handleReveal() { - const reveals = document.querySelectorAll('.reveal'); - - const observer = new IntersectionObserver((entries) => { - entries.forEach(entry => { - if (entry.isIntersecting) { - entry.target.classList.add('revealed'); - } - }); - }, { threshold: 0.1 }); - - reveals.forEach(reveal => { - observer.observe(reveal); - }); - - // Force reveal hero elements immediately - setTimeout(() => { - const heroReveals = document.querySelectorAll('.hero-v2 .reveal'); - heroReveals.forEach(el => el.classList.add('revealed')); - }, 100); - } - - setupMouseTracking() { - let ticking = false; - document.addEventListener('mousemove', (e) => { - if (!ticking) { - window.requestAnimationFrame(() => { - const x = (e.clientX / window.innerWidth) * 100; - const y = (e.clientY / window.innerHeight) * 100; - document.documentElement.style.setProperty('--mouse-x', `${x}%`); - document.documentElement.style.setProperty('--mouse-y', `${y}%`); - - const cursor = document.querySelector('.cursor-main'); - const trail = document.querySelector('.cursor-trail'); - if (cursor && trail) { - cursor.style.transform = `translate3d(${e.clientX - 4}px, ${e.clientY - 4}px, 0)`; - trail.style.transform = `translate3d(${e.clientX - 16}px, ${e.clientY - 16}px, 0)`; - } - - // Enterprise Background Parallax - const mesh = document.querySelector('.mesh-gradient'); - if (mesh) { - const moveX = (x - 50) * 0.1; - const moveY = (y - 50) * 0.1; - mesh.style.transform = `scale(1.1) translate(${moveX}%, ${moveY}%)`; - } - ticking = false; - }); - ticking = true; - } - }); - } - - async handleTerminal() { - const terminal = document.getElementById('terminal-content'); - if (!terminal) return; - - // Reset terminal - terminal.innerHTML = ''; - const t = dgzTranslations[this.lang]; - - const lines = [ - { text: t.boot_1, color: "var(--accent-cyan)" }, - { text: t.boot_2, color: "#fff" }, - { text: t.boot_3, color: "#fff" }, - { text: t.boot_4, color: "#fff" }, - { text: t.boot_5, color: "var(--status-ok)" }, - { text: t.boot_6, color: "#fff" }, - { text: t.boot_7, color: "var(--accent-electric)" } - ]; - - for (const line of lines) { - const div = document.createElement('div'); - div.className = 'terminal-line'; - div.style.color = line.color; - terminal.appendChild(div); - - for (let i = 0; i < line.text.length; i++) { - div.textContent += line.text[i]; - await new Promise(r => setTimeout(r, 10)); - } - await new Promise(r => setTimeout(r, 200)); - } - - setTimeout(() => { - const intro = document.getElementById('terminal-intro'); - if (intro) intro.classList.add('hidden'); - sessionStorage.setItem('dgz_skip_intro', 'true'); - this.startTelemetry(); - }, 800); - } - - startTelemetry() { - const latency = document.getElementById('tele-latency'); - if (!latency) return; - - setInterval(() => { - const ms = Math.floor(Math.random() * 15) + 5; - latency.textContent = `${ms}ms`; - }, 3000); - } - - injectHeader() { - // Prevent double injection - if (document.getElementById('dgz-global-header')) return; - - const header = document.createElement('header'); - header.id = 'dgz-global-header'; - header.className = 'dgz-nav-master'; - - const isSubDir = window.location.pathname.includes('/projects/') || window.location.pathname.includes('/lab/'); - const rootPath = isSubDir ? (window.location.pathname.includes('/projects/') ? '../../' : '../') : './'; - - header.innerHTML = ` - -
- `; - - document.body.prepend(header); - } - - addStyles() { - // Styles moved to index.css for premium architecture - } - - setupListeners() { - const btn = document.getElementById('dgz-lang-toggle'); - if (btn) { - btn.addEventListener('click', () => { - this.lang = this.lang === 'en' ? 'es' : 'en'; - localStorage.setItem('dgz_lang', this.lang); - document.getElementById('lang-label').textContent = this.lang === 'en' ? 'ES' : 'EN'; - this.applyTranslations(); - window.dispatchEvent(new CustomEvent('dgzLangChanged', { detail: this.lang })); - }); - } - } - - applyTranslations() { - const t = dgzTranslations[this.lang]; - document.querySelectorAll('[data-i18n]').forEach(el => { - const key = el.getAttribute('data-i18n'); - if (t[key]) { - if (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') { - el.placeholder = t[key]; - } else if (el.tagName === 'SELECT') { - // Logic for select options if needed - } else { - el.innerHTML = t[key]; - } - } - }); - document.documentElement.lang = this.lang; - } - - initAssistant() { - const trigger = document.getElementById('geo-assistant-trigger'); - const panel = document.getElementById('geo-assistant-panel'); - const closeBtn = document.getElementById('close-assistant'); - const sendBtn = document.getElementById('send-to-ai'); - const input = document.getElementById('assistant-input'); - const chat = document.getElementById('assistant-chat'); - - if (!trigger || !panel) return; - - trigger.addEventListener('click', () => { - panel.classList.remove('collapsed'); - trigger.style.display = 'none'; - }); - - closeBtn.addEventListener('click', () => { - panel.classList.add('collapsed'); - trigger.style.display = 'flex'; - }); - - const sendMessage = () => { - const text = input.value.trim(); - if (!text) return; - - // User Message - const userMsg = document.createElement('div'); - userMsg.className = 'user-msg'; - userMsg.textContent = text; - chat.appendChild(userMsg); - input.value = ''; - chat.scrollTop = chat.scrollHeight; - - // Mock AI Response - setTimeout(() => { - const aiMsg = document.createElement('div'); - aiMsg.className = 'ai-msg'; - aiMsg.textContent = "Procesando consulta geoespacial... Analizando topología LADM-COL... [Mock Response: Los datos parecen correctos.]"; - chat.appendChild(aiMsg); - chat.scrollTop = chat.scrollHeight; - }, 1000); - }; - - sendBtn.addEventListener('click', sendMessage); - input.addEventListener('keypress', (e) => { - if (e.key === 'Enter') sendMessage(); - }); - } -} - -/** - * TACTICAL GIS WORKSTATION v1.0 - * Handles Intel Map Hub interactions, telemetry, and layer management. - */ -class GISWorkstation { - constructor() { - this.layers = { - parcels: true, - infra: false, - geoai: false - }; - this.init(); - } - - init() { - this.bindEvents(); - this.startTelemetry(); - console.log("GIS_WORKSTATION_ACTIVE: Nucleus Online"); - } - - bindEvents() { - const layerBtns = document.querySelectorAll('.layer-opt'); - layerBtns.forEach(btn => { - btn.addEventListener('click', () => { - const layer = btn.dataset.layer; - this.toggleLayer(layer, btn); - }); - }); - - // Tooltip logic for map nodes - const mapNodes = document.querySelectorAll('.map-node'); - mapNodes.forEach(node => { - node.addEventListener('mouseenter', (e) => this.showTooltip(e, node)); - node.addEventListener('mouseleave', () => this.hideTooltip()); - }); - } - - toggleLayer(layerId, btn) { - // Simple visual toggle for the demo - const isActive = btn.classList.contains('active'); - - btn.classList.toggle('active'); - this.layers[layerId] = !isActive; - - // Visual feedback - const map = document.getElementById('intel-map'); - if (map) { - map.setAttribute('data-active-layer', layerId); - map.style.opacity = '0.7'; - setTimeout(() => map.style.opacity = '1', 300); - } - - console.log(`GIS_LAYER_UPDATE: ${layerId} -> ${this.layers[layerId] ? 'VISIBLE' : 'HIDDEN'}`); - } - - startTelemetry() { - const coordDisplay = document.querySelector('.map-projection-label'); - if (!coordDisplay) return; - - setInterval(() => { - const lat = (8.2 + Math.random() * 0.1).toFixed(6); - const lng = (-76.3 + Math.random() * 0.1).toFixed(6); - coordDisplay.innerHTML = `COORD_UPLINK: ${lat}°N, ${lng}°W [WGS84]`; - }, 2000); - } - - showTooltip(e, node) { - const tooltip = document.getElementById('map-tooltip'); - if (!tooltip) return; - - const data = node.dataset; - tooltip.innerHTML = ` -
- LADM-COL_NODE_v3 -

IDENTIFIER: ${data.id || 'PRDL_7712'}

-

STATUS: ${data.status || 'VALIDATED'}

-

AREA: ${data.area || '142.5'} m²

-
- `; - - tooltip.style.left = `${e.clientX + 15}px`; - tooltip.style.top = `${e.clientY + 15}px`; - tooltip.classList.add('visible'); - } - - hideTooltip() { - const tooltip = document.getElementById('map-tooltip'); - if (tooltip) tooltip.classList.remove('visible'); - } -} - -// Global instance -window.dgzCore = new DGZCore(); - -// Support for the Inline Demo in index.html -async function runCadastralValidation() { - const btn = document.getElementById('run-validator'); - const output = document.getElementById('validator-output'); - if (!btn || !output) return; - - const currentLang = localStorage.getItem('dgz_lang') || 'es'; - const t = dgzTranslations[currentLang]; - - btn.disabled = true; - btn.textContent = t.demo_btn_processing; - output.innerHTML = `
${t.demo_log_1}
`; - - const phases = [ - { t: t.demo_log_2, c: "#fff" }, - { t: t.demo_log_3, c: "#fff" }, - { t: t.demo_log_4, c: "#fff" }, - { t: t.demo_log_5, c: "var(--status-ok)" } - ]; - - for (const p of phases) { - await new Promise(r => setTimeout(r, 1200)); - const line = document.createElement('div'); - line.style.color = p.c; - line.textContent = `> ${p.t}`; - output.appendChild(line); - } - - btn.textContent = "VALIDATION_COMPLETE"; - btn.style.background = "var(--status-ok)"; - btn.style.color = "#000"; -} - -window.runCadastralValidation = runCadastralValidation; diff --git a/assets/js/dgz-topo.js b/assets/js/dgz-topo.js deleted file mode 100644 index 77e629d..0000000 --- a/assets/js/dgz-topo.js +++ /dev/null @@ -1,159 +0,0 @@ -/** - * DGZ_SOVEREIGN_RIDGE v5.0 - * High-Density Geospatial Relief - * Ultra-Sharp Vector-Grade Rendering - */ - -class DGZSovereignRidge { - constructor() { - this.canvas = document.getElementById('topo-canvas'); - if (!this.canvas) return; - this.ctx = this.canvas.getContext('2d', { alpha: true }); - - this.layers = 5; - this.points = []; - this.time = 0; - - // Increase density for smoothness - this.density = 100; - - this.mouse = { x: 0, y: 0, targetX: 0, targetY: 0 }; - this.colors = [ - '#F1F5F9', // Ultra Light Slate - '#E2E8F0', // Light Slate - '#CBD5E1', // Mid Slate - '#94A3B8', // Steel Gray - '#2563EB' // Electric Blue (Accent Layer) - ]; - - this.init(); - this.animate(); - this.setupListeners(); - } - - init() { - this.resize(); - this.generatePoints(); - } - - resize() { - this.width = window.innerWidth; - this.height = window.innerHeight; - - const dpr = window.devicePixelRatio || 1; - this.canvas.width = this.width * dpr; - this.canvas.height = this.height * dpr; - this.canvas.style.width = `${this.width}px`; - this.canvas.style.height = `${this.height}px`; - - this.ctx.resetTransform(); - this.ctx.scale(dpr, dpr); - - // Enable smoothing for vector-like paths - this.ctx.imageSmoothingEnabled = true; - this.ctx.imageSmoothingQuality = 'high'; - } - - generatePoints() { - this.points = []; - const segment = this.width / (this.density - 1); - - for (let i = 0; i < this.layers; i++) { - const layerPoints = []; - for (let j = 0; j < this.density; j++) { - layerPoints.push({ - x: j * segment, - baseY: this.height * (0.45 + (i * 0.12)), - offset: j * 0.1 + Math.random() * 0.5, - phase: Math.random() * Math.PI * 2 - }); - } - this.points.push(layerPoints); - } - } - - animate() { - this.ctx.clearRect(0, 0, this.width, this.height); - this.time += 0.003; - - // Smooth Mouse - this.mouse.x += (this.mouse.targetX - this.mouse.x) * 0.05; - this.mouse.y += (this.mouse.targetY - this.mouse.y) * 0.05; - - // Render Layers - for (let i = this.layers - 1; i >= 0; i--) { - this.drawLayer(i); - } - - requestAnimationFrame(() => this.animate()); - } - - drawLayer(index) { - const layer = this.points[index]; - const color = this.colors[index]; - - this.ctx.beginPath(); - this.ctx.moveTo(0, this.height); - - const parallaxX = (this.mouse.x - this.width / 2) * (index + 1) * 0.015; - const parallaxY = (this.mouse.y - this.height / 2) * (index + 1) * 0.008; - - for (let i = 0; i < layer.length; i++) { - const p = layer[i]; - - const x = p.x + parallaxX; - const y_base = p.baseY + parallaxY; - - // Mouse Interaction Logic - const dx = x - this.mouse.x; - const dy = y_base - this.mouse.y; - const dist = Math.sqrt(dx * dx + dy * dy); - const maxDist = 300; - let mouseInfluence = 0; - - if (dist < maxDist) { - // Subtle push effect - mouseInfluence = (1 - dist / maxDist) * 40 * (index + 1) * 0.2; - } - - // High-frequency math for "natural" ridges - const wave1 = Math.sin(this.time + p.phase) * (20 - index * 3); - const wave2 = Math.cos(this.time * 0.5 + p.offset) * 10; - - const finalY = y_base + wave1 + wave2 - mouseInfluence; - - if (i === 0) { - this.ctx.lineTo(x, finalY); - } else { - this.ctx.lineTo(x, finalY); - } - } - - this.ctx.lineTo(this.width + 50, this.height); - this.ctx.lineTo(-50, this.height); - this.ctx.closePath(); - - this.ctx.fillStyle = index === 4 ? 'rgba(37, 99, 235, 0.05)' : color; - this.ctx.fill(); - - // High-precision rim lighting (only on top edges) - this.ctx.strokeStyle = index === 4 ? 'rgba(37, 99, 235, 0.2)' : `rgba(30, 41, 59, ${0.1 - index * 0.01})`; - this.ctx.lineWidth = index === 4 ? 1 : 0.5; - this.ctx.stroke(); - } - - setupListeners() { - window.addEventListener('resize', () => { - this.resize(); - this.generatePoints(); - }); - window.addEventListener('mousemove', (e) => { - this.mouse.targetX = e.clientX; - this.mouse.targetY = e.clientY; - }); - } -} - -document.addEventListener('DOMContentLoaded', () => { - new DGZSovereignRidge(); -}); diff --git a/assets/js/main.js b/assets/js/main.js deleted file mode 100644 index 945c043..0000000 --- a/assets/js/main.js +++ /dev/null @@ -1,1194 +0,0 @@ -const translations = { - en: { - nav_about: "About Me", - nav_projects: "Assets", - nav_map: "Map", - nav_contact: "Contact", - nav_cv: "CV", - hero_tag: "// SPATIAL_SYSTEMS_ENGINEERING", - hero_h1: "Automating Multipurpose Cadastre & Territorial Intelligence Systems", - hero_title: "Automating Multipurpose Cadastre & Territorial Intelligence Systems", - hero_desc: "High-Performance Geospatial Engineering & Automated Systems Architecture.", - hero_btn_projects: "Explore System", - hero_btn_contact: "Contact", - lab_live: "DGZ SPATIAL LAB · LIVE DEMOS", - lab_gesture: "Free Trial: Vision Sandbox (Gestural AI)", - terminal_init: "LOADING_CORE_SYSTEM...", - terminal_status_1: "FETCH_SPATIAL_NODES...", - terminal_status_2: "SYNC_POSTGIS_BUFFERS...", - terminal_status_3: "BYPASS_MANUAL_LIMITS...", - terminal_done: "ACCESS_GRANTED.", - about_label: "Engineering Core", - about_title: "GIS Excellence & Software Architecture", - about_p1: "We bridge the gap between traditional GIS mapping and scalable software architecture. Focused on high-precision data workflows and technical automation.", - proj_label: "// FLAGSHIP_ASSETS", - cv_header: "BIO-NEURAL CV // ALBERT GAVIRIA V5.2", - cv_close: "EXIT_INTERFACE", - cv_label_profile: "Personal_Profile", - cv_label_skills: "Technical_DNA", - cv_label_langs: "Languages", - cv_label_metrics: "Impact_Metrics", - cv_label_edu: "Academic_History", - cv_label_cert: "Credentials", - cv_label_exp_main: "Current_Mission", - cv_label_exp_log: "Professional_Log", - cv_label_future: "Future_Nodes", - cv_summary: "Profesional SIG con una visión integral que fusiona la excelencia técnica en Sistemas de Información Geográfica con una sólida maestría en arquitectura de bases de datos y desarrollo de software. Especialista en la automatización de flujos de trabajo geoespaciales mediante Python y SQL Server/PostgreSQL para diseñar infraestructuras de alto rendimiento.", - footer_copy: "© 2026 ALBERT DANIEL GAVIRIA ZAPATA. ALL RIGHTS RESERVED.", - form_name: "Full_Name", - form_email: "Email_Uplink", - form_msg: "Mission_Brief", - form_btn: "INITIATE_HANDSHAKE", - metrics_label: "Proven Performance", - metrics_title: "Impact Metrics", - metric_roi: "Operational Efficiency", - metric_error: "Error Margin Reduction", - metric_team: "Personnel Managed", - metric_nodes: "Primary Data Nodes", - contact_title: "HANDSHAKE PROTOCOL.", - contact_desc: "Architecting the next generation of spatial intelligence. Establish your secure link to initiate technical consultation.", - contact_secure: ">>> CH_SECURE: ALBERT_GAVIRIA", - contact_loc: ">>> LOC_SYNC: 6.2442° N, 75.5812° W", - form_placeholder_name: "Organization / Lead Architect", - form_placeholder_msg: "Define mission parameters & objectives...", - node_medellin: "GEOSAT S.A.S // ANALISTA GEOGRÁFICO
Procesamiento avanzado de información geoespacial, fotointerpretación y restitución vectorial. Digitalización de precisión para actualización catastral masiva.", - node_solita: "ACCION DEL CAUCA S.A.S // QA/QC RECONOCIMIENTO
Auditorías técnicas de calidad sobre información predial bajo normativa IGAC. Validación de componentes físicos, jurídicos y económicos.", - node_uraba: "ARBIRTRIUM S.A.S // LÍDER Y COORDINADOR SIG
Liderazgo técnico de equipos de reconocimiento predial y digitalización catastral masiva. Gestión avanzada de calidad y estructuración topológica.", - node_arboletes: "ARBIRTRIUM S.A.S // COORDINADOR CAMPO
Coordinación estratégica de operativos de campo para identificación predial y barrido catastral.", - node_barranquilla: "UT SMART CITY // COORDINADOR PROFESIONAL SIG
Implementación de estándares LADM-COL y dirección de procesos de digitalización masiva. Especialista en gestión predial y fotogrametría con drones.", - node_gaitan: "COSARGO SAS // GESTOR AMBIENTAL
Supervisión de cumplimiento normativo ambiental en proyectos de infraestructura y gestión de recursos naturales.", - lab_title: "Spatial Intelligence Laboratory", - lab_desc: "Real-world projects demonstrating GIS capabilities, cadastral automation, and spatial systems architecture. This is NOT just a portfolio — it's an active lab.", - geoai_title: "GeoAI Intelligence", - geoai_subtitle: "Urban Change Detection with Sentinel Imagery", - hero_avail: "Available for Projects — Colombia & Remote", - hero_btn_lab: "⭐ Explore Spatial Lab", - hero_btn_map: "🗺️ Intel Map", - map_label: "// SPATIAL_INTEL_WORKSTATION_V6", - map_title: "Territorial Intelligence Hub", - map_desc: "Full-stack GIS workstation — interactive parcel data, toggleable layers, real coordinate intelligence. Click any map node to inspect LADM-COL attributes.", - timeline_label: "Professional Trajectory", - timeline_title: "Professional Trajectory", - timeline_desc: "6+ years of specialized GIS and territorial engineering across Colombia's most complex cadastral projects.", - tl_role_1: "Geographic Analyst", - tl_desc_1: "Advanced geospatial processing via photointerpretation, 360° input analysis and vector restitution. Mass digitization for cadastral update with topological validation under LADM-COL V3.", - tl_role_2: "Cadastral Quality Control (QA/QC)", - tl_desc_2: "Technical quality audits for predial recognition. IGAC QA standards enforcement, topological consistency checks, and field report validation.", - tl_role_3: "Field Coordinator & GIS Leader", - tl_desc_3: "Co-leader of field survey teams. Urban/rural topographic leveling, mass digitization, and GIS coordination for multipurpose cadastre missions in complex terrain.", - tl_role_4: "Professional GIS Coordinator", - tl_desc_4: "LADM-COL standards implementation, mass digitization and GIS coordination for Smart City multipurpose cadastre deployment. QA/QC across distributed field nodes.", - tl_role_5: "GIS Professional — Drones & Geomatics", - tl_desc_5: "Drone-based photogrammetric surveys, predial management, and vector GIS production. Spatial analysis and cartographic outputs for real estate and environmental projects.", - tl_role_6: "Digitizer / Topographer", - tl_desc_6: "Road topography surveys and GIS digitization for vial infrastructure projects. GPS field surveys and cartographic production under professional standards.", - contact_title: "Let's discuss your
next project.", - contact_desc: "Next-generation territorial intelligence. Let's discuss your project, municipality, or enterprise GIS challenge.", - contact_label: "Start a Project", - contact_email_label: "Email", - contact_loc_label: "Location", - form_service: "Service_Type", - form_service_select: "— Select Service —", - form_svc_1: "GIS Automation & ETL Pipeline", - form_svc_2: "Cadastral QA/QC (LADM-COL)", - form_svc_3: "Enterprise GIS Dashboard", - form_svc_4: "GeoAI / Satellite Analysis", - form_svc_5: "Government / Municipal Project", - form_svc_6: "Other / Consulting", - cv_download: "Download Datasheet (PDF)", - hero_available: "Available for Projects · Medellín, Colombia", - cap_tag: "Specialized Services", - cap_title: "Specialized solutions for every territorial challenge", - svc_1_title: "Mass Cadastral Update", - svc_1_desc: "Management and validation of 500+ parcels per cycle. Full automation of land recognition workflow under IGAC and LADM-COL V3 standards.", - svc_2_title: "Cadastral QA/QC (Quality Control)", - svc_2_desc: "Technical audits with Python and QGIS. Automatic detection of overlaps, gaps, and topological errors. Certified PDF reports for oversight.", - svc_3_title: "Geospatial ETL Pipelines", - svc_3_desc: "Unattended transformation architecture for massive GIS data ingestion. From field to database with zero manual intervention.", - svc_4_title: "GeoAI — Change Detection", - svc_4_desc: "Machine Learning on Sentinel-2 imagery to detect urban expansion, land cover changes, and multi-temporal territorial mutations.", - svc_5_title: "Enterprise GIS Dashboards", - svc_5_desc: "Interactive interfaces connected to PostGIS for real-time territorial analysis. Visualization of cadastral indicators for executives and entities.", - svc_6_title: "GIS Field Coordination", - svc_6_desc: "Leadership of technical teams in complex terrains. Topographic leveling, mass digitization, and coordination under NSR-10 regulations." - }, - es: { - nav_about: "Sobre Mí", - nav_projects: "Proyectos Desplegados", - nav_map: "Mapa", - nav_contact: "Contacto", - nav_cv: "CV", - hero_tag: "// INGENIERÍA DE SISTEMAS ESPACIALES", - hero_h1: "Automatizando Sistemas de Inteligencia Territorial y Catastro Multipropósito", - hero_title: "Automatizando Sistemas de Inteligencia Territorial y Catastro Multipropósito", - hero_desc: "Ingeniería geoespacial de alto rendimiento y arquitectura de sistemas automatizados.", - hero_btn_projects: "Explorar Sistema", - hero_btn_contact: "Contactame", - lab_live: "DGZ SPATIAL LAB · LIVE DEMOS", - lab_gesture: "Prueba Gratuita: Vision Sandbox (IA Gestual)", - terminal_init: "CARGANDO_SISTEMA_CORE...", - terminal_status_1: "RECUPERANDO_NODOS...", - terminal_status_2: "SINCRONIZANDO_POSTGIS...", - terminal_status_3: "OMITIENDO_LIMITES_MANUALES...", - terminal_done: "ACCESO_CONCEDIDO.", - about_label: "Núcleo de Ingeniería", - about_title: "Excelencia GIS & Arquitectura de Software", - about_p1: "Cerramos la brecha entre el mapeo SIG tradicional y la arquitectura de software escalable. Enfocados en flujos de datos de alta precisión y automatización técnica.", - proj_label: "// DESPLIEGUES_TÉCNICOS", - cv_header: "CV BIO-NEURONAL // ALBERT GAVIRIA V5.2", - cv_close: "SALIR_INTERFAZ", - cv_label_profile: "Perfil_Personal", - cv_label_skills: "ADN_Técnico", - cv_label_langs: "Idiomas", - cv_label_metrics: "Métricas_Impacto", - cv_label_edu: "Historial_Académico", - cv_label_cert: "Credenciales", - cv_label_exp_main: "Misión_Actual", - cv_label_exp_log: "Registro_Profesional", - cv_label_future: "Nodos_Futuros", - cv_summary: "Tecnólogo y Profesional SIG fusionando la excelencia técnica en Sistemas Geosociales con una profunda experiencia en arquitectura de bases de datos e ingeniería de software. Dominando SQL Server y PostgreSQL para diseñar infraestructuras espaciales de alto rendimiento.", - footer_copy: "© 2026 ALBERT DANIEL GAVIRIA ZAPATA. TODOS LOS DERECHOS RESERVADOS.", - form_name: "Nombre_Completo", - form_email: "Correo_Uplink", - form_msg: "Breve_Misión", - form_btn: "INICIAR_PROTOCOLO", - metrics_label: "Rendimiento Comprobado", - metrics_title: "Métricas de Impacto", - metric_roi: "Eficiencia Operativa", - metric_error: "Reducción de Margen de Error", - metric_team: "Personal Gestionado", - metric_nodes: "Nodos de Datos Primarios", - contact_title: "PROTOCOLO DE ENLACE.", - contact_desc: "Arquitectando la próxima generación de inteligencia espacial. Establezca su enlace seguro para iniciar la consulta técnica.", - contact_secure: ">>> CANAL_SEGURO: ALBERT_GAVIRIA", - contact_loc: ">>> LOC_SYNC: 6.2442° N, 75.5812° W", - form_placeholder_name: "Organización / Arquitecto Principal", - form_placeholder_msg: "Defina los parámetros y objetivos de la misión...", - node_medellin: "GEOSAT S.A.S // ANALISTA GEOGRÁFICO
Procesamiento avanzado de información geoespacial, fotointerpretación y restitución vectorial. Digitalización de precisión para actualización catastral masiva.", - node_solita: "ACCION DEL CAUCA S.A.S // QA/QC RECONOCIMIENTO
Auditorías técnicas de calidad sobre información predial bajo normativa IGAC. Validación de componentes físicos, jurídicos y económicos.", - node_uraba: "ARBIRTRIUM S.A.S // LÍDER Y COORDINADOR SIG
Liderazgo técnico de equipos de reconocimiento predial y digitalización catastral masiva. Gestión avanzada de calidad y estructuración topológica.", - node_arboletes: "ARBIRTRIUM S.A.S // COORDINADOR CAMPO
Coordinación estratégica de operativos de campo para identificación predial y barrido catastral.", - node_barranquilla: "UT SMART CITY // COORDINADOR PROFESIONAL SIG
Implementación de estándares LADM-COL y dirección de procesos de digitalización masiva. Especialista en gestión predial y fotogrametría con drones.", - node_gaitan: "COSARGO SAS // GESTOR AMBIENTAL
Supervisión de cumplimiento normativo ambiental en proyectos de infraestructura y gestión de recursos naturales.", - lab_title: "Laboratorio de Inteligencia Espacial", - lab_desc: "Proyectos reales demostrando capacidades GIS, automatización catastral y arquitectura de sistemas espaciales. Esto NO es un portafolio — es un laboratorio activo.", - geoai_title: "GeoAI Intelligence", - geoai_subtitle: "Detección de Cambios Urbanos con Imagenería Sentinel", - hero_avail: "Disponible para Proyectos — Colombia y Remoto", - hero_btn_lab: "⭐ Explorar Spatial Lab", - hero_btn_map: "🗺️ Mapa Intel", - map_label: "// ESTACIÓN_SIG_INTEL_V6", - map_title: "Hub de Inteligencia Territorial", - map_desc: "Estación GIS full-stack — datos prediales interactivos, capas configurables, inteligencia de coordenadas en vivo. Haga clic en cualquier nodo para inspeccionar atributos LADM-COL.", - timeline_label: "Trayectoria Profesional", - timeline_title: "Trayectoria Profesional", - timeline_desc: "+6 años de ingeniería GIS especializada y territorial en los proyectos catastrales más complejos de Colombia.", - tl_role_1: "Analista Geográfico", - tl_desc_1: "Procesamiento avanzado de información geoespacial mediante fotointerpretación, análisis de insumos 360° y restitución vectorial. Digitalización masiva para actualización catastral con validación topológica bajo LADM-COL V3.", - tl_role_2: "Control de Calidad Catastral (QA/QC)", - tl_desc_2: "Auditorías técnicas de calidad sobre información predial. Aplicación de estándares QA IGAC, verificación de consistencia topológica y validación de informes de campo.", - tl_role_3: "Coordinador y Líder de Campo SIG", - tl_desc_3: "Co-líder de equipos de reconocimiento predial. Nivelación topográfica urbana/rural, digitalización masiva y coordinación GIS para misiones de catastro multipropósito en terrenos complejos.", - tl_role_4: "Coordinador Profesional SIG", - tl_desc_4: "Implementación de estándares LADM-COL, digitalización masiva y coordinación GIS para despliegue de catastro multipropósito en Smart City. QA/QC en nodos de campo distribuidos.", - tl_role_5: "Profesional SIG — Drones y Geomática", - tl_desc_5: "Levantamientos fotogrametrícos con drones, gestión predial y producción de GIS vectorial. Análisis espacial y salidas cartográficas para proyectos inmobiliarios y ambientales.", - tl_role_6: "Digitalizador / Topógrafo", - tl_desc_6: "Levantamientos topográficos viales y digitalización GIS para proyectos de infraestructura. Trabajo de campo GPS y producción cartográfica bajo estándares profesionales.", - contact_title: "Hablemos de su
próximo proyecto.", - contact_desc: "Inteligencia territorial de próxima generación. Hablemos de su proyecto, municipio o desafío GIS empresarial.", - contact_label: "Iniciar Proyecto", - contact_email_label: "Correo", - contact_loc_label: "Ubicación", - form_service: "Tipo_Servicio", - form_service_select: "— Seleccionar Servicio —", - form_svc_1: "Automatización GIS y Pipeline ETL", - form_svc_2: "QA/QC Catastral (LADM-COL)", - form_svc_3: "Dashboard GIS Empresarial", - form_svc_4: "GeoAI / Análisis Satelital", - form_svc_5: "Proyecto Gubernamental / Municipal", - form_svc_6: "Otro / Consultoría", - cv_download: "Descargar Datasheet (PDF)", - hero_available: "Disponible para Proyectos · Medellín, Colombia", - cap_tag: "Servicios Especializados", - cap_title: "Soluciones especializadas para cada desafío territorial", - svc_1_title: "Actualización Catastral Masiva", - svc_1_desc: "Gestión y validación de +500 predios por ciclo. Automatización completa del flujo de reconocimiento predial bajo estándares IGAC y LADM-COL V3.", - svc_2_title: "QA/QC Catastral (Control de Calidad)", - svc_2_desc: "Auditorías técnicas con Python y QGIS. Detección automática de solapamientos, huecos y errores topológicos. Reportes PDF certificados para interventoría.", - svc_3_title: "Pipelines ETL Geoespaciales", - svc_3_desc: "Arquitectura de transformación desatendida para ingesta masiva de datos GIS. De campo a base de datos sin intervención manual.", - svc_4_title: "GeoAI — Detección de Cambios", - svc_4_desc: "Machine Learning sobre imagenería Sentinel-2 para detectar expansión urbana, cambios de cobertura y mutaciones territoriales multitemporales.", - svc_5_title: "Dashboards GIS Empresariales", - svc_5_desc: "Interfaces interactivas conectadas a PostGIS para análisis territorial en tiempo real. Visualización de indicadores catastrales para directivos y entidades.", - svc_6_title: "Coordinación de Campo GIS", - svc_6_desc: "Liderazgo de equipos técnicos en terrenos complejos. Nivelación topográfica, digitalización masiva y coordinación bajo normativa NSR-10." - } -}; - -document.addEventListener('DOMContentLoaded', () => { - // 0. LUXURY CURSOR PHYSICS - const cursor = document.querySelector('.cursor-main'); - const trail = document.querySelector('.cursor-trail'); - let mouseX = 0, mouseY = 0, trailX = 0, trailY = 0; - - document.addEventListener('mousemove', (e) => { - mouseX = e.clientX; mouseY = e.clientY; - if (cursor) cursor.style.transform = `translate3d(${mouseX}px, ${mouseY}px, 0)`; - }); - - const animateTrail = () => { - trailX += (mouseX - trailX) * 0.15; - trailY += (mouseY - trailY) * 0.15; - if (trail) trail.style.transform = `translate3d(${trailX - 16}px, ${trailY - 16}px, 0)`; - requestAnimationFrame(animateTrail); - }; - animateTrail(); - - // 1. ADVANCED CV MODAL LOGIC - const cvTrigger = document.getElementById('cv-trigger'); - const cvOverlay = document.getElementById('cv-neural-overlay'); - const cvClose = document.getElementById('cv-neural-close'); - const dnaBars = document.querySelectorAll('.dna-bar-fill'); - - if (cvTrigger) { - cvTrigger.addEventListener('click', (e) => { - cvOverlay.classList.add('active'); - document.body.style.overflow = 'hidden'; - setTimeout(() => { - dnaBars.forEach(bar => { - const level = bar.getAttribute('data-level'); - bar.style.width = level; - }); - }, 500); - }); - } - - if (cvClose) { - cvClose.addEventListener('click', () => { - cvOverlay.classList.remove('active'); - document.body.style.overflow = 'auto'; - dnaBars.forEach(bar => bar.style.width = '0'); - }); - } - - // 2. TERMINAL BOOTUP (V5.2 Character-by-Character) - const terminal = document.getElementById('terminal-intro'); - const terminalContent = document.getElementById('terminal-content'); - - let currentLang = 'en'; - try { currentLang = localStorage.getItem('dgz_lang') || 'en'; } catch (e) { } - - const introSteps = ['terminal_init', 'terminal_status_1', 'terminal_status_2', 'terminal_status_3', 'terminal_done']; - let stepIndex = 0; - - const typeChar = (lineEl, text, charIdx, resolve) => { - if (charIdx < text.length) { - lineEl.textContent += text[charIdx]; - setTimeout(() => typeChar(lineEl, text, charIdx + 1, resolve), 30 + Math.random() * 40); - } else { - resolve(); - } - }; - - const runTerminal = async () => { - if (!terminalContent) return; - - // Add initial system headers - const header = document.createElement('div'); - header.style.color = 'var(--accent-gold)'; - header.style.marginBottom = '1.5rem'; - header.textContent = `[DGZ_SIRIUS_OS_V5.2_LOADER] -- KERNEL: 0x${Math.random().toString(16).slice(2, 10).toUpperCase()}`; - terminalContent.appendChild(header); - - for (const stepKey of introSteps) { - const line = document.createElement('div'); - line.className = 'terminal-line'; - line.textContent = '>>> '; - terminalContent.appendChild(line); - - const text = translations[currentLang][stepKey]; - await new Promise(resolve => typeChar(line, text, 0, resolve)); - - // Random glitch line sometimes - if (Math.random() > 0.7) { - const glitch = document.createElement('div'); - glitch.style.opacity = '0.3'; - glitch.style.fontSize = '0.6rem'; - glitch.textContent = `[MEM_BUFFER] 0x${Math.random().toString(16).slice(2, 14)} -- STABLE`; - terminalContent.appendChild(glitch); - } - - await new Promise(r => setTimeout(r, 200)); - } - - // Add cursor at the end - const cursor = document.createElement('span'); - cursor.className = 'terminal-cursor'; - terminalContent.appendChild(cursor); - - setTimeout(() => { - if (terminal) { - terminal.classList.add('hidden'); - setTimeout(() => terminal.style.display = 'none', 1000); - } - }, 1200); - }; - - if (terminal) runTerminal(); - - // 3. i18n ENGINE - const langBtns = document.querySelectorAll('.lang-btn'); - const setLanguage = (lang) => { - try { localStorage.setItem('dgz_lang', lang); } catch (e) { } - document.querySelectorAll('[data-i18n]').forEach(el => { - const key = el.getAttribute('data-i18n'); - if (translations[lang] && translations[lang][key]) { - if (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') { - el.placeholder = translations[lang][key]; - } else { - el.innerHTML = translations[lang][key]; - } - } - }); - langBtns.forEach(btn => btn.classList.toggle('active', btn.getAttribute('data-lang') === lang)); - - // Dispatch event for map markers - window.dispatchEvent(new Event('languageChanged')); - }; - langBtns.forEach(btn => btn.addEventListener('click', () => setLanguage(btn.getAttribute('data-lang')))); - setLanguage(currentLang); - - // 4. OBSERVATION SYSTEM & COUNTERS - const observer = new IntersectionObserver((entries) => { - entries.forEach(entry => { - if (entry.isIntersecting) { - entry.target.classList.add('active'); - - // Animate Numbers if it's a metric - if (entry.target.classList.contains('metric-card')) { - const numEl = entry.target.querySelector('.metric-num'); - const target = parseInt(numEl.innerText.replace(/\D/g, '')); - const suffix = numEl.innerText.replace(/[0-9]/g, ''); - const prefix = numEl.innerText.startsWith('+') ? '+' : (numEl.innerText.startsWith('-') ? '-' : ''); - - let current = 0; - const duration = 2000; - const stepTime = Math.abs(Math.floor(duration / target)); - - const counter = setInterval(() => { - current += 1; - numEl.textContent = prefix + current + suffix; - if (current >= target) { - numEl.textContent = prefix + target + suffix; - clearInterval(counter); - } - }, stepTime); - } - } - }); - }, { threshold: 0.1 }); - document.querySelectorAll('.reveal').forEach(el => observer.observe(el)); - - // 5. MAP ARCHITECTURE — ENTERPRISE GIS WORKSTATION V6 - const mapElement = document.getElementById('interactive-map'); - if (mapElement && typeof L !== 'undefined') { - const hqCoord = [6.2442, -75.5812]; - - const map = L.map('interactive-map', { - center: hqCoord, - zoom: 6, - zoomControl: false, - attributionControl: false, - scrollWheelZoom: true - }); - - // ---- BASEMAP TILES ---- - const tiles = { - dark: L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', { maxZoom: 19 }), - satellite: L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', { maxZoom: 19 }), - topo: L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', { maxZoom: 17 }) - }; - tiles.dark.addTo(map); - - // ---- SIMULATED CADASTRAL PARCELS (GeoJSON) ---- - // Medellín area parcels with LADM-COL attributes - const cadastralData = { - type: 'FeatureCollection', - features: [ - { - type: 'Feature', - geometry: { type: 'Polygon', coordinates: [[[-75.578, 6.248], [-75.575, 6.248], [-75.575, 6.245], [-75.578, 6.245], [-75.578, 6.248]]] }, - properties: { NUMERO_PREDIO: 'ANT-001-0012', MUNICIPIO: 'Medellín', AREA_GRF: '2,340 m²', ESTADO: 'VALIDATED', PROPIETARIO: 'Empresa A S.A.S', MATRICULA: 'SNR-0012-2023', CRR: 'A01', FEC_ACTUALIZ: '2024-11-15', TIPO: 'Comercial', VALOR_CATASTRAL: '$450,000,000' } - }, - { - type: 'Feature', - geometry: { type: 'Polygon', coordinates: [[[-75.583, 6.243], [-75.580, 6.243], [-75.580, 6.240], [-75.583, 6.240], [-75.583, 6.243]]] }, - properties: { NUMERO_PREDIO: 'ANT-001-0087', MUNICIPIO: 'Medellín', AREA_GRF: '1,890 m²', ESTADO: 'ERROR', PROPIETARIO: 'Persona Natural', MATRICULA: 'SNR-0087-2022', CRR: 'B03', FEC_ACTUALIZ: '2023-08-22', TIPO: 'Residencial', VALOR_CATASTRAL: '$230,000,000' } - }, - { - type: 'Feature', - geometry: { type: 'Polygon', coordinates: [[[-75.572, 6.252], [-75.569, 6.252], [-75.569, 6.249], [-75.572, 6.249], [-75.572, 6.252]]] }, - properties: { NUMERO_PREDIO: 'ANT-001-0234', MUNICIPIO: 'Medellín', AREA_GRF: '3,120 m²', ESTADO: 'VALIDATED', PROPIETARIO: 'Constructora XYZ', MATRICULA: 'SNR-0234-2024', CRR: 'C02', FEC_ACTUALIZ: '2024-01-10', TIPO: 'Industrial', VALOR_CATASTRAL: '$890,000,000' } - }, - { - type: 'Feature', - geometry: { type: 'Polygon', coordinates: [[[-75.565, 6.238], [-75.562, 6.238], [-75.562, 6.236], [-75.565, 6.236], [-75.565, 6.238]]] }, - properties: { NUMERO_PREDIO: 'ANT-001-0456', MUNICIPIO: 'Medellín', AREA_GRF: '780 m²', ESTADO: 'VALIDATED', PROPIETARIO: 'Fondo Nacional', MATRICULA: 'SNR-0456-2023', CRR: 'D05', FEC_ACTUALIZ: '2024-03-30', TIPO: 'Dotacional', VALOR_CATASTRAL: '$1,200,000,000' } - } - ] - }; - - // ---- URBAN BOUNDARY (Simplified Medellín perimeter) ---- - const urbanBoundary = L.polygon([ - [6.355, -75.665], [6.37, -75.60], [6.34, -75.535], [6.29, -75.51], - [6.22, -75.52], [6.18, -75.555], [6.165, -75.62], [6.20, -75.68], - [6.27, -75.695], [6.32, -75.68], [6.355, -75.665] - ], { - color: '#4ade80', - weight: 2, - fill: true, - fillColor: '#4ade80', - fillOpacity: 0.03, - dashArray: '8 4', - interactive: false - }); - - // ---- ATTRIBUTE FUNCTION ---- - let selectedFeatureLayer = null; - - const showAttributes = (properties, layerRef, title) => { - document.getElementById('attr-default-state').style.display = 'none'; - document.getElementById('attr-panel-content').style.display = 'block'; - document.getElementById('attr-system-id').textContent = 'LAYER: ' + title; - - const table = document.getElementById('attr-table'); - table.innerHTML = ''; - Object.entries(properties).forEach(([k, v]) => { - const row = document.createElement('div'); - row.className = 'attr-row'; - row.innerHTML = `
${k}
${v}
`; - table.appendChild(row); - }); - - if (selectedFeatureLayer) { - try { selectedFeatureLayer.setStyle && selectedFeatureLayer.setStyle({ weight: 1 }); } catch(e) {} - } - selectedFeatureLayer = layerRef; - if (layerRef && layerRef.setStyle) { - layerRef.setStyle({ weight: 3, color: '#fff' }); - } - - setStatus(`Feature selected — ${Object.keys(properties)[0]}: ${Object.values(properties)[0]}`); - }; - - // ---- CADASTRAL LAYER ---- - const cadastralLayer = L.geoJSON(cadastralData, { - style: feat => ({ - color: feat.properties.ESTADO === 'ERROR' ? '#ff4b2b' : '#ffb400', - weight: 1.5, - fill: true, - fillColor: feat.properties.ESTADO === 'ERROR' ? '#ff4b2b' : '#ffb400', - fillOpacity: feat.properties.ESTADO === 'ERROR' ? 0.25 : 0.12 - }), - onEachFeature: (feat, layer) => { - const popup = L.popup({ closeButton: true, maxWidth: 280 }).setContent(` -
-
LADM-COL // REGISTRO_CATASTRAL
-
${feat.properties.NUMERO_PREDIO}
- - - - - - - - -
Municipio${feat.properties.MUNICIPIO}
Área Gráfica${feat.properties.AREA_GRF}
Estado${feat.properties.ESTADO}
Propietario${feat.properties.PROPIETARIO}
Matrícula SNR${feat.properties.MATRICULA}
Tipo${feat.properties.TIPO}
Valor Catastral${feat.properties.VALOR_CATASTRAL}
-
- `); - layer.bindPopup(popup); - layer.on('click', () => showAttributes(feat.properties, layer, 'CADASTRAL_PARCELS')); - } - }); - - // ---- EXPERIENCE NODES ---- - const expNodes = [ - { loc:[6.2442,-75.5812], key:'node_medellin', accent:'#00e5ff', isHQ:true, - attrs:{ NODO:'MED_HQ', EMPRESA:'GEOSAT S.A.S', ROL:'Analista Geográfico', PERÍODO:'2025 Q4', PROTOCOLO:'LADM-COL', ESTADO:'ACTIVE' } }, - { loc:[0.9639,-75.6453], key:'node_solita', accent:'#ff4b2b', isHQ:false, - attrs:{ NODO:'SOLITA_01', EMPRESA:'ACCION DEL CAUCA S.A.S', ROL:'QA/QC Reconocimiento', PERÍODO:'2025 Q2', PROTOCOLO:'IGAC_QA', ESTADO:'COMPLETE' } }, - { loc:[10.9685,-74.7813], key:'node_barranquilla', accent:'#ffb400', isHQ:false, - attrs:{ NODO:'BQ_SMART', EMPRESA:'UT SMART CITY', ROL:'Coordinador Profesional SIG', PERÍODO:'2024-Act', PROTOCOLO:'LADM-COL V3', ESTADO:'ACTIVE' } }, - { loc:[8.2753,-76.3773], key:'node_uraba', accent:'#00e5ff', isHQ:false, - attrs:{ NODO:'URB_02', EMPRESA:'ARBIRTRIUM S.A.S', ROL:'Líder y Coordinador SIG', PERÍODO:'2024 Q3', PROTOCOLO:'IGAC_TOPO', ESTADO:'COMPLETE' } }, - { loc:[8.8504,-76.4255], key:'node_arboletes', accent:'#ffb400', isHQ:false, - attrs:{ NODO:'ARB_03', EMPRESA:'ARBIRTRIUM S.A.S', ROL:'Coordinador Campo', PERÍODO:'2023-24', PROTOCOLO:'BARRIDO_PRED', ESTADO:'COMPLETE' } }, - { loc:[4.3134,-72.0811], key:'node_gaitan', accent:'#00e5ff', isHQ:false, - attrs:{ NODO:'GAI_ENV', EMPRESA:'COSARGO SAS', ROL:'Gestor Ambiental', PERÍODO:'2022', PROTOCOLO:'ENV_NORM', ESTADO:'ARCHIVED' } } - ]; - - const markerGroup = L.layerGroup(); - - expNodes.forEach(node => { - let marker; - if (node.isHQ) { - const icon = L.divIcon({ - className: '', - html: `
-
-
-
`, - iconSize: [20, 20], iconAnchor: [10, 10] - }); - marker = L.marker(node.loc, { icon }); - } else { - marker = L.circleMarker(node.loc, { - radius: 8, - fillColor: node.accent, - color: '#fff', - weight: 2, - fillOpacity: 0.9 - }); - } - - const lang = () => localStorage.getItem('dgz_lang') || 'en'; - const content = () => ` -
-
SPATIAL_NODE // ${node.attrs.NODO}
-
${node.attrs.EMPRESA}
- - - - - - -
Rol${node.attrs.ROL}
Período${node.attrs.PERÍODO}
Protocolo${node.attrs.PROTOCOLO}
Estado${node.attrs.ESTADO}
Lat,Lng${node.loc[0].toFixed(4)}, ${node.loc[1].toFixed(4)}
-
`; - - marker.bindPopup(L.popup({ closeButton: true, maxWidth: 260 }).setContent(content())); - marker.on('click', () => { - marker.getPopup().setContent(content()); - showAttributes(node.attrs, marker, 'PROFESSIONAL_NODES'); - }); - window.addEventListener('languageChanged', () => { - if (marker.getPopup()) marker.getPopup().setContent(content()); - }); - markerGroup.addLayer(marker); - }); - - // ---- NEURAL SCAN ANIMATION ---- - let scanRadius = 0, isMapVisible = false; - const scanCircle = L.circle(hqCoord, { - radius: 0, color: '#00e5ff', weight: 1, - fillOpacity: 0.03, fillColor: '#00e5ff', interactive: false - }); - - const mapObserver = new IntersectionObserver(entries => { - isMapVisible = entries[0].isIntersecting; - if (isMapVisible) animateScan(); - }, { threshold: 0.1 }); - mapObserver.observe(mapElement); - - function animateScan() { - if (!isMapVisible && scanRadius === 0) return; - scanRadius += 3000; - if (scanRadius > 300000) scanRadius = 0; - scanCircle.setRadius(scanRadius); - scanCircle.setStyle({ opacity: 1 - (scanRadius / 300000) }); - if (isMapVisible || scanRadius > 0) requestAnimationFrame(animateScan); - } - - // ---- ADD ALL LAYERS ---- - function addAllLayers() { - urbanBoundary.addTo(map); - cadastralLayer.addTo(map); - markerGroup.addTo(map); - scanCircle.addTo(map); - } - addAllLayers(); - - // ---- LAYER TOGGLES (checkboxes) ---- - document.getElementById('layer-chk-nodes')?.addEventListener('change', e => { - e.target.checked ? markerGroup.addTo(map) : map.removeLayer(markerGroup); - }); - document.getElementById('layer-chk-parcels')?.addEventListener('change', e => { - e.target.checked ? cadastralLayer.addTo(map) : map.removeLayer(cadastralLayer); - }); - document.getElementById('layer-chk-boundary')?.addEventListener('change', e => { - e.target.checked ? urbanBoundary.addTo(map) : map.removeLayer(urbanBoundary); - }); - document.getElementById('layer-chk-scan')?.addEventListener('change', e => { - e.target.checked ? scanCircle.addTo(map) : map.removeLayer(scanCircle); - }); - - // ---- BASEMAP SWITCHER (new panel buttons) ---- - document.querySelectorAll('.gis-basemap-btn').forEach(btn => { - btn.addEventListener('click', () => { - const lyr = btn.getAttribute('data-layer'); - document.querySelectorAll('.gis-basemap-btn').forEach(b => b.classList.remove('active')); - btn.classList.add('active'); - Object.values(tiles).forEach(t => map.removeLayer(t)); - tiles[lyr].addTo(map); - tiles[lyr].bringToBack(); - setStatus(`Basemap switched to: ${lyr.toUpperCase()}`); - }); - }); - - // ---- COORDINATE HUD (live on mousemove) ---- - const hudLat = document.getElementById('hud-lat'); - const hudLng = document.getElementById('hud-lng'); - const hudZoom = document.getElementById('hud-zoom'); - const coordLat = document.getElementById('gis-coord-lat'); - const coordLng = document.getElementById('gis-coord-lng'); - - map.on('mousemove', e => { - const lat = e.latlng.lat.toFixed(4); - const lng = e.latlng.lng.toFixed(4); - if (hudLat) hudLat.textContent = lat; - if (hudLng) hudLng.textContent = lng; - if (coordLat) coordLat.textContent = lat; - if (coordLng) coordLng.textContent = lng; - }); - - map.on('zoomend', () => { - if (hudZoom) hudZoom.textContent = map.getZoom(); - updateScalebar(); - }); - - // ---- SCALE BAR ---- - function updateScalebar() { - const zoom = map.getZoom(); - const metersPerPixel = 156543.03 * Math.cos(hqCoord[0] * Math.PI / 180) / Math.pow(2, zoom); - const barPx = 80; - const meters = barPx * metersPerPixel; - const label = meters > 1000 ? (meters / 1000).toFixed(1) + ' km' : Math.round(meters) + ' m'; - const sl = document.getElementById('scalebar-label'); - if (sl) sl.textContent = label; - } - updateScalebar(); - - // ---- TOOLS ---- - let activeTool = 'pan'; - let measurePoints = [], measureLine = null; - - const setStatus = (msg) => { - const s = document.getElementById('gis-status-msg'); - if (s) s.textContent = '● ' + msg; - }; - - document.querySelectorAll('.gis-tool').forEach(btn => { - btn.addEventListener('click', () => { - activeTool = btn.getAttribute('data-tool'); - document.querySelectorAll('.gis-tool').forEach(b => b.classList.remove('active')); - btn.classList.add('active'); - - // Handle tool-specific UI - const measureWidget = document.getElementById('gis-measure-widget'); - const identifyHint = document.getElementById('gis-identify-hint'); - - if (activeTool === 'measure') { - measureWidget.style.display = 'block'; - identifyHint.style.display = 'none'; - map.getContainer().style.cursor = 'crosshair'; - setStatus('MEASURE_TOOL active — click to add points, double-click to finish'); - } else if (activeTool === 'identify') { - measureWidget.style.display = 'none'; - identifyHint.style.display = 'flex'; - map.getContainer().style.cursor = 'help'; - setStatus('IDENTIFY_TOOL active — click a feature to inspect attributes'); - } else if (activeTool === 'zoom') { - measureWidget.style.display = 'none'; - identifyHint.style.display = 'none'; - map.flyTo(hqCoord, 13, { duration: 2 }); - setStatus('Zooming to HQ — Medellín, Colombia'); - activeTool = 'pan'; - setTimeout(() => { - document.getElementById('tool-pan').classList.add('active'); - btn.classList.remove('active'); - }, 100); - } else if (activeTool === 'scan') { - scanRadius = 0; - animateScan(); - setStatus('NEURAL_SCAN triggered from HQ node'); - activeTool = 'pan'; - setTimeout(() => { - document.getElementById('tool-pan').classList.add('active'); - btn.classList.remove('active'); - }, 100); - } else { - measureWidget.style.display = 'none'; - identifyHint.style.display = 'none'; - map.getContainer().style.cursor = ''; - setStatus('PAN_TOOL active — drag to navigate'); - } - }); - }); - - // ---- MEASURE ON MAP CLICK ---- - map.on('click', e => { - if (activeTool !== 'measure') return; - measurePoints.push(e.latlng); - document.getElementById('measure-points').textContent = measurePoints.length; - - if (measureLine) map.removeLayer(measureLine); - if (measurePoints.length > 1) { - let total = 0; - for (let i = 1; i < measurePoints.length; i++) { - total += measurePoints[i-1].distanceTo(measurePoints[i]); - } - const label = total > 1000 ? (total/1000).toFixed(2) + ' km' : Math.round(total) + ' m'; - document.getElementById('measure-distance').textContent = label; - measureLine = L.polyline(measurePoints, { color: '#00e5ff', weight: 2, dashArray: '6 4' }).addTo(map); - } - }); - - document.getElementById('clear-measure')?.addEventListener('click', () => { - measurePoints = []; - if (measureLine) { map.removeLayer(measureLine); measureLine = null; } - document.getElementById('measure-distance').textContent = '—'; - document.getElementById('measure-points').textContent = '0'; - }); - - // ---- ZOOM CONTROLS ---- - document.getElementById('map-zoom-in')?.addEventListener('click', () => map.zoomIn()); - document.getElementById('map-zoom-out')?.addEventListener('click', () => map.zoomOut()); - - // Legacy support (recenter/scan if old HTML left) - document.getElementById('map-recenter')?.addEventListener('click', () => map.flyTo(hqCoord, 13, { duration: 2 })); - document.getElementById('map-scan')?.addEventListener('click', () => { scanRadius = 0; animateScan(); }); - - // ---- LIVE CLOCK IN STATUS BAR ---- - const clockEl = document.getElementById('gis-clock'); - if (clockEl) { - setInterval(() => { - const now = new Date(); - clockEl.textContent = now.toTimeString().slice(0, 8) + ' COT'; - }, 1000); - } - - setStatus('SYSTEM READY — DGZ Territorial Intelligence v6.0 // Nodes: 6 active'); - } - - - // 6. TRANSMISSION FORM (AJAX) - const form = document.getElementById('dgz-transmission-form'); - if (form) { - form.addEventListener('submit', async (e) => { - e.preventDefault(); - const submitBtn = document.getElementById('submit-btn'); - const btnText = document.getElementById('btn-text'); - const feedback = document.getElementById('form-feedback'); - - submitBtn.disabled = true; - if (btnText) btnText.textContent = "TRANSMITTING..."; - if (feedback) { - feedback.style.color = "var(--accent-electric)"; - feedback.textContent = ">>> ENCRYPTING_HANDSHAKE_V2.1..."; - } - - try { - const response = await fetch(form.action, { - method: 'POST', - body: new FormData(form), - headers: { 'Accept': 'application/json' } - }); - if (response.ok) { - if (feedback) feedback.textContent = ">>> HANDSHAKE_STABLE. MISSION_INITIATED."; - if (btnText) btnText.textContent = "STABLE"; - form.reset(); - setTimeout(() => { - submitBtn.disabled = false; - if (btnText) btnText.textContent = "INITIATE_HANDSHAKE"; - if (feedback) feedback.textContent = ""; - }, 5000); - } else { throw new Error(); } - } catch (error) { - if (feedback) { - feedback.style.color = "#ff4b2b"; - feedback.textContent = ">>> TRANSMISSION_CRITICAL_FAILURE. RETRY."; - } - submitBtn.disabled = false; - if (btnText) btnText.textContent = "RE-INITIATE"; - } - }); - } - - // 7. TILT EFFECT (Integrated from index.html & Optimized) - const tiltItems = document.querySelectorAll('[data-tilt]'); - tiltItems.forEach(item => { - item.addEventListener('mousemove', (e) => { - const rect = item.getBoundingClientRect(); - const x = e.clientX - rect.left - rect.width / 2; - const y = e.clientY - rect.top - rect.height / 2; - item.style.transform = `perspective(2000px) rotateY(${x / 40}deg) rotateX(${-y / 40}deg) scale(1.02)`; - }); - item.addEventListener('mouseleave', () => { - item.style.transform = 'perspective(2000px) rotateY(0deg) rotateX(0deg) scale(1)'; - }); - }); - - // 8. SCROLL PROGRESS (Integrated from index.html) - window.addEventListener('scroll', () => { - const progress = document.getElementById('scroll-progress'); - if (progress) { - const total = document.documentElement.scrollHeight - window.innerHeight; - progress.style.width = (window.scrollY / total * 100) + '%'; - } - - // Header scroll effect - const header = document.getElementById('main-header'); - if (header) { - header.classList.toggle('scrolled', window.scrollY > 50); - } - }, { passive: true }); - - // 9. PERFORMANCE LOG (Innovation) - console.log("%c DGZ_ENGINEERING_V6.0 %c SPATIAL_INTELLIGENCE %c ACCESS_LEVEL: SOVEREIGN ", - "background: #00e5ff; color: #000; font-weight: 800; padding: 2px 5px; border-radius: 3px 0 0 3px;", - "background: #ffb400; color: #000; font-weight: 800; padding: 2px 5px;", - "background: #222; color: #00e5ff; padding: 2px 5px; border-radius: 0 3px 3px 0;"); - console.log(">>> [STATUS] Spatial_Lab: ACTIVE // GeoAI_Module: READY // Architecture: V6.0 // Kernel: 0x" + Math.random().toString(16).slice(2, 10).toUpperCase()); - - // 11. PIPELINE ANIMATION (Automation Pipeline Demo) - const pipelineSteps = document.querySelectorAll('.pipeline-step'); - if (pipelineSteps.length > 0) { - let currentPipelineStep = 0; - const stepIcons = ['step-icon-1', 'step-icon-2', 'step-icon-3', 'step-icon-4']; - - const advancePipeline = () => { - if (currentPipelineStep < pipelineSteps.length - 1) { - currentPipelineStep++; - pipelineSteps.forEach((s, i) => { - if (i <= currentPipelineStep) { - s.classList.add('active-step'); - const iconId = `step-icon-${i}`; - const iconEl = document.getElementById(iconId); - if (iconEl && i > 0) iconEl.textContent = '✅'; - } - }); - if (currentPipelineStep < pipelineSteps.length - 1) { - setTimeout(advancePipeline, 1200); - } else { - const lastIcon = document.getElementById('step-icon-4'); - if (lastIcon) lastIcon.textContent = '✅'; - // Reset after 3 seconds - setTimeout(() => { - currentPipelineStep = 0; - pipelineSteps.forEach((s, i) => { - if (i > 0) s.classList.remove('active-step'); - }); - stepIcons.forEach(id => { - const el = document.getElementById(id); - if (el) el.textContent = '⏳'; - }); - setTimeout(advancePipeline, 1200); - }, 3000); - } - } - }; - - // Start pipeline animation when in view - const pipelineObserver = new IntersectionObserver((entries) => { - if (entries[0].isIntersecting) { - setTimeout(advancePipeline, 800); - pipelineObserver.disconnect(); - } - }, { threshold: 0.3 }); - const pipelineContainer = document.getElementById('pipeline-demo'); - if (pipelineContainer) pipelineObserver.observe(pipelineContainer); - } - - // 12. GEOAI CHANGE DETECTION PIXELS - const changePixelsContainer = document.getElementById('change-pixels'); - if (changePixelsContainer) { - // Generate pixel grid - const totalPixels = 80; - for (let i = 0; i < totalPixels; i++) { - const pixel = document.createElement('div'); - pixel.className = 'change-pixel'; - changePixelsContainer.appendChild(pixel); - } - - const animatePixels = () => { - const pixels = changePixelsContainer.querySelectorAll('.change-pixel'); - pixels.forEach(p => p.className = 'change-pixel'); - - // Randomly assign detected/stable/neutral - pixels.forEach(pixel => { - const rand = Math.random(); - if (rand < 0.2) pixel.classList.add('detected'); - else if (rand < 0.6) pixel.classList.add('stable'); - }); - }; - - animatePixels(); - setInterval(animatePixels, 2500); - } - - // 10. INTERACTIVE TIMELINE LOGIC - const timelineNodes = document.querySelectorAll('.timeline-node'); - const timelineData = { - "2025 (Q4)": { - title: "Analista Geográfico", - subtitle: "GEOGRAFÍA SATELITAL GEOSAT S.A.S. | Medellín", - desc: "Procesamiento avanzado de información geoespacial mediante fotointerpretación, análisis de insumos 360° y restitución vectorial. Digitalización de unidades de construcción para actualización catastral masiva." - }, - "2025 (Q2)": { - title: "QA/QC Calidad Predial", - subtitle: "ACCION DEL CAUCA S.A.S. | Solita, Caquetá", - desc: "Ejecución de auditorías técnicas de calidad (QA/QC) sobre reconocimiento predial, asegurando cumplimiento de normativa IGAC y validación de componentes físicos, jurídicos y económicos." - }, - "2024 - Act": { - title: "Coordinador Profesional SIG", - subtitle: "UNION TEMPORAL SMART CITY | Barranquilla", - desc: "Implementación de estándares LADM-COL e interoperabilidad. Dirección de procesos de digitalización masiva y control de calidad (QA) con cero inconsistencias gráficas." - }, - "2024 (Q3)": { - title: "Líder de Reconocimiento", - subtitle: "ARBIRTRIUM S.A.S | Antioquia", - desc: "Liderazgo técnico de equipos de reconocimiento predial. Verificación exhaustiva de mutaciones catastrales y componentes jurídicos en articulación con Registro." - }, - "2023 - 24": { - title: "Profesional SIG", - subtitle: "GRUPO EMPRESARIAL OD | Barranquilla", - desc: "Especialista en Geomática y gestión predial: procesamiento de ortofotos, fotogrametría y topografía con drones para proyectos de infraestructura." - }, - "2022": { - title: "Digitalizador Profesional SIG", - subtitle: "CINTELI S.A.S | Barranquilla", - desc: "Digitalización masiva conforme a normativa IGAC. Integración y cruce de bases de datos gráficas y alfanuméricas para garantizar consistencia topológica." - } - }; - - const timelineTitle = document.getElementById('timeline-title'); - const timelineSubtitle = document.getElementById('timeline-subtitle'); - const timelineDescription = document.getElementById('timeline-description'); - const timelineContainer = document.querySelector('.timeline-content-display'); - - if (timelineNodes.length > 0) { - timelineNodes.forEach(node => { - node.addEventListener('click', () => { - timelineNodes.forEach(n => n.classList.remove('active')); - node.classList.add('active'); - const year = node.querySelector('.node-year').textContent; - const data = timelineData[year]; - if (data && timelineTitle) { - timelineContainer.style.opacity = '0'; - setTimeout(() => { - timelineTitle.textContent = data.title; - timelineSubtitle.textContent = data.subtitle; - timelineDescription.textContent = data.desc; - timelineContainer.style.opacity = '1'; - }, 300); - } - }); - }); - } -}); - -// ============================================================ -// GLOBAL FUNCTIONS (called from HTML inline events) -// ============================================================ - -// CADASTRAL VALIDATOR ENGINE -function runCadastralValidation() { - const parcels = document.getElementById('validator-parcels'); - const output = document.getElementById('validator-output'); - const btn = document.getElementById('run-validator'); - if (!parcels || !output || !btn) return; - - // Reset - const cells = parcels.querySelectorAll('.parcel-cell'); - cells.forEach(c => c.className = 'parcel-cell'); - output.innerHTML = ''; - btn.textContent = '⏳ SCANNING...'; - btn.disabled = true; - - // Log initial state - const addLog = (msg, color = 'var(--text-tertiary)') => { - const line = document.createElement('div'); - line.style.color = color; - line.textContent = msg; - output.appendChild(line); - }; - - addLog('>>> INITIATING_CADASTRAL_VALIDATION...'); - - // Randomly assign states with a staggered animation - const states = ['valid', 'valid', 'valid', 'valid', 'error', 'warning', 'valid', 'valid', 'valid']; - const shuffled = states.sort(() => Math.random() - 0.5); - let errorCount = 0, warningCount = 0; - - cells.forEach((cell, i) => { - setTimeout(() => { - cell.classList.add(shuffled[i]); - if (shuffled[i] === 'error') errorCount++; - if (shuffled[i] === 'warning') warningCount++; - - if (i === cells.length - 1) { - setTimeout(() => { - if (errorCount > 0) { - addLog(`>>> TOPOLOGY_ERROR: ${errorCount} overlap(s) detected`, '#ff4b2b'); - } - if (warningCount > 0) { - addLog(`>>> WARNING: ${warningCount} area inconsistenc(y)`, '#ffb400'); - } - addLog(`>>> VALID_PARCELS: ${cells.length - errorCount - warningCount}/${cells.length}`, '#4ade80'); - addLog('>>> VALIDATION_COMPLETE_V2.1'); - - btn.innerHTML = ` RUN_VALIDATION`; - btn.disabled = false; - }, 200); - } - }, i * 120); - }); - - // If API configured, also POST GeoJSON to backend `/validate` and show real results - const apiBase = window.API_BASE || 'https://dgz-engineering.onrender.com'; - if (apiBase && window.validatorGeoJSON) { - const url = apiBase.replace(/\/+$/, '') + '/validate'; - addLog(`>>> POSTING ${window.validatorGeoJSON.features.length} features to ${url}`, 'var(--accent-electric)'); - fetch(url, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(window.validatorGeoJSON) - }).then(r => r.json()).then(j => { - addLog('>>> API RESPONSE: ' + JSON.stringify(j), 'var(--text-secondary)'); - // Highlight invalid features if reported - if (j.invalid && Array.isArray(j.invalid)) { - j.invalid.forEach(inv => { - const idx = inv.index; - const el = cells[idx]; - if (el) el.classList.add('error'); - }); - } - // If no API configured, run client-side validation using Turf.js (zero-cost, GitHub Pages compatible) - if ((!apiBase || apiBase === '') && window.validatorGeoJSON && typeof turf !== 'undefined') { - addLog('>>> RUNNING CLIENT-SIDE VALIDATION (Turf.js) — zero-cost mode', 'var(--accent-electric)'); - const feats = window.validatorGeoJSON.features; - let clientErrors = 0; - - // compute per-feature area and mark warnings if mismatch - feats.forEach((f, i) => { - try { - const turfArea = turf.area(f); // in m² when geometry in WGS84 - const reported = parseFloat(f.properties.area_m2) || 0; - const diffPct = Math.abs((turfArea - reported) / Math.max(reported, 1)) * 100; - if (diffPct > 30) { // threshold - clientErrors++; - const el = cells[i]; if (el) el.classList.add('error'); - addLog(`>>> AREA_MISMATCH idx=${i} reported=${reported}m² computed=${Math.round(turfArea)}m² diff=${Math.round(diffPct)}%`, '#ffb400'); - } - } catch (err) { - clientErrors++; - const el = cells[i]; if (el) el.classList.add('error'); - addLog(`>>> GEOM_ERROR idx=${i} ${err.message}`, '#ff4b2b'); - } - }); - - // naive overlap detection O(n^2) - let overlaps = 0; - for (let i = 0; i < feats.length; i++) { - for (let j = i + 1; j < feats.length; j++) { - try { - if (turf.booleanIntersects(feats[i], feats[j])) { - overlaps++; - const eli = cells[i]; const elj = cells[j]; - if (eli) eli.classList.add('error'); - if (elj) elj.classList.add('error'); - } - } catch (err) { - // skip geometry errors - } - } - } - - addLog(`>>> CLIENT VALIDATION COMPLETE — errors=${clientErrors} overlaps=${overlaps}`, 'var(--text-secondary)'); - } - if (typeof j.overlaps !== 'undefined') addLog(`>>> OVERLAPS: ${j.overlaps}`, '#ffb400'); - }).catch(err => { - addLog('>>> API ERROR: ' + err.message, '#ff4b2b'); - }); - } -} - -// ============================================================ -// SYSTEM SECURITY & ANTI-SCRAPE MODULE -// ============================================================ -document.addEventListener('contextmenu', event => event.preventDefault()); // Block right click -document.addEventListener('keydown', function (e) { - // Block F12 - if (e.key === 'F12') { - e.preventDefault(); - } - // Block Ctrl+Shift+I (Inspect), Ctrl+Shift+J (Console), Ctrl+U (View Source) - if (e.ctrlKey && (e.key === 'u' || e.key === 'U')) { e.preventDefault(); } - if (e.ctrlKey && e.shiftKey && (e.key === 'i' || e.key === 'I' || e.key === 'j' || e.key === 'J' || e.key === 'c' || e.key === 'C')) { - e.preventDefault(); - } - - // Escape to exit fullscreen GIS - if (e.key === 'Escape') { - const ws = document.getElementById('gis-workstation'); - if (ws && ws.classList.contains('fullscreen-mode')) { - ws.classList.remove('fullscreen-mode'); - const btn = document.getElementById('gis-fullscreen-btn'); - if (btn) btn.innerHTML = ' FULLSCREEN'; - } - } -}); - -// Protect images from drag and drop -document.querySelectorAll('img').forEach(img => { - img.addEventListener('dragstart', (e) => e.preventDefault()); -}); - -// ---- GIS FULLSCREEN BUTTON ---- -document.addEventListener('DOMContentLoaded', () => { - const toolbar = document.querySelector('.gis-toolbar-tools'); - if (toolbar) { - const btn = document.createElement('button'); - btn.id = 'gis-fullscreen-btn'; - btn.className = 'gis-btn-fullscreen'; - btn.innerHTML = ' FULLSCREEN'; - btn.title = 'Toggle Fullscreen'; - toolbar.appendChild(btn); - - btn.addEventListener('click', () => { - const ws = document.getElementById('gis-workstation'); - if (!ws) return; - const isFs = ws.classList.toggle('fullscreen-mode'); - btn.innerHTML = isFs - ? ' EXIT FULL' - : ' FULLSCREEN'; - // Invalidate Leaflet map size - setTimeout(() => { - if (window.__dgzMap) window.__dgzMap.invalidateSize(); - }, 200); - }); - } - - // ---- FOOTER CLOCK ---- - const footerClock = document.getElementById('footer-clock'); - if (footerClock) { - const updateFClock = () => { - footerClock.textContent = new Date().toTimeString().slice(0, 8) + ' COT'; - }; - updateFClock(); - setInterval(updateFClock, 1000); - } - - // ---- CHANGE DETECTION PIXEL ANIMATION (GeoAI section) ---- - const pixelContainer = document.getElementById('change-pixels'); - if (pixelContainer && pixelContainer.children.length === 0) { - const types = ['', 'stable', 'detected']; - for (let i = 0; i < 81; i++) { - const px = document.createElement('div'); - px.className = 'change-pixel ' + types[Math.floor(Math.random() * types.length)]; - pixelContainer.appendChild(px); - } - } -}); - diff --git a/assets/js/vision/gestures.js b/assets/js/vision/gestures.js deleted file mode 100644 index e4c3c6c..0000000 --- a/assets/js/vision/gestures.js +++ /dev/null @@ -1,280 +0,0 @@ -/** - * DGZ Vision — Hand Gesture Detection & Smoothing - */ -import { playSciFiBlip } from './utils.js'; -import { isMapLoaded, getMap } from './map-engine.js'; -import { onFeatureHover } from './ui-controller.js'; - -let videoElement, canvasElement, canvasCtx, cursor, statusText, gestureFeedback; -let isPinching = false; -let dragStartMapCenter = null; -let dragStartCursorPos = null; -let activeDragPanel = null; -let dragOffset = { x: 0, y: 0 }; -let currentGestureState = "NONE"; -let lastZoomActionTime = 0; -let frameCount = 0; -let lastFPSUpdate = Date.now(); -let currentFPS = 60; - -// Smoothing logic -let smoothedX = window.innerWidth / 2; -let smoothedY = window.innerHeight / 2; -let lastMappedX = smoothedX; -let lastMappedY = smoothedY; - -const BASE_SMOOTHING = 0.15; -const MAX_SMOOTHING = 0.6; -const VELOCITY_SENSITIVITY = 0.05; -const basePinchThreshold = 0.06; - -export function initVisionElements(elements) { - videoElement = elements.video; - canvasElement = elements.canvas; - canvasCtx = elements.ctx; - cursor = elements.cursor; - statusText = elements.statusText; - gestureFeedback = elements.gestureFeedback; -} - -export async function initVision() { - statusText.innerText = 'CARGANDO MODELO...'; - - try { - const hands = new Hands({locateFile: (file) => { - return `https://cdn.jsdelivr.net/npm/@mediapipe/hands/${file}`; - }}); - - hands.setOptions({ - maxNumHands: 2, - modelComplexity: 1, - minDetectionConfidence: 0.70, - minTrackingConfidence: 0.70 - }); - - hands.onResults(onResults); - - const camera = new Camera(videoElement, { - onFrame: async () => { - await hands.send({image: videoElement}); - }, - width: 1280, - height: 720 - }); - - await camera.start(); - document.getElementById('btn-start').style.display = 'none'; - statusText.style.color = '#00E5FF'; - statusText.innerText = 'ONLINE / TRACKING'; - cursor.style.display = 'block'; - - } catch (err) { - console.error(err); - statusText.innerText = 'ERROR ACCESO CÁMARA'; - statusText.style.color = '#ff4b2b'; - } -} - -function setGestureState(newState, text, color) { - if (currentGestureState !== newState) { - currentGestureState = newState; - if(newState === 'DRAG') playSciFiBlip(400, 'square', 0.15); - else if(newState === 'ZOOM_IN') playSciFiBlip(1200, 'sine', 0.1); - else if(newState === 'ZOOM_OUT') playSciFiBlip(600, 'sine', 0.1); - else if(newState === 'RESET') playSciFiBlip(300, 'sawtooth', 0.3); - else if(newState === 'POINTER') playSciFiBlip(900, 'sine', 0.05); - } - gestureFeedback.innerText = text; - gestureFeedback.style.color = color; -} - -function onResults(results) { - canvasCtx.save(); - canvasCtx.clearRect(0, 0, canvasElement.width, canvasElement.height); - - if (results.multiHandLandmarks && results.multiHandLandmarks.length > 0) { - const landmarks = results.multiHandLandmarks[0]; - - drawConnectors(canvasCtx, landmarks, HAND_CONNECTIONS, {color: 'rgba(0, 229, 255, 0.4)', lineWidth: 3}); - drawLandmarks(canvasCtx, landmarks, {color: '#9D4EDD', lineWidth: 1, radius: 4}); - - const wrist = landmarks[0]; - const thumbTip = landmarks[4]; - const indexTip = landmarks[8]; - const indexMcp = landmarks[5]; - const midTip = landmarks[12]; - const midMcp = landmarks[9]; - const ringTip = landmarks[16]; - const ringMcp = landmarks[13]; - const pinkyTip = landmarks[20]; - const pinkyMcp = landmarks[17]; - - const dist = (p1, p2) => Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2)); - - const isIndexOpen = dist(indexTip, wrist) > dist(indexMcp, wrist) + 0.05; - const isMidOpen = dist(midTip, wrist) > dist(midMcp, wrist) + 0.05; - const isRingOpen = dist(ringTip, wrist) > dist(ringMcp, wrist) + 0.05; - const isPinkyOpen = dist(pinkyTip, wrist) > dist(pinkyMcp, wrist) + 0.05; - - const handScale = dist(wrist, indexMcp) * 5; - const adaptivePinchThreshold = basePinchThreshold * handScale; - - const rawX = (1 - indexTip.x) * window.innerWidth; - const rawY = indexTip.y * window.innerHeight; - - const velocity = dist({x: rawX, y: rawY}, {x: lastMappedX, y: lastMappedY}) / 100; - const dynamicSmoothing = Math.min(MAX_SMOOTHING, BASE_SMOOTHING + (velocity * VELOCITY_SENSITIVITY)); - - smoothedX = smoothedX + (rawX - smoothedX) * dynamicSmoothing; - smoothedY = smoothedY + (rawY - smoothedY) * dynamicSmoothing; - - lastMappedX = rawX; - lastMappedY = rawY; - - cursor.style.left = `${smoothedX}px`; - cursor.style.top = `${smoothedY}px`; - - const tiltX = (smoothedY / window.innerHeight - 0.5) * 20; - const tiltY = (smoothedX / window.innerWidth - 0.5) * -20; - document.querySelectorAll('.vision-glass-panel').forEach(p => { - if (!p.classList.contains('is-dragging')) { - p.style.transform = `perspective(1000px) rotateX(${tiltX}deg) rotateY(${tiltY}deg)`; - } - }); - - const pinchDist = dist(indexTip, thumbTip); - const pinchThreshold = adaptivePinchThreshold; - const depthZ = Math.round(indexTip.z * 1000); - const now = Date.now(); - const map = getMap(); - - // GESTURES - if (!isIndexOpen && !isMidOpen && !isRingOpen && !isPinkyOpen) { - setGestureState('RESET', `ACCION: RESET VISTA [Z:${depthZ}]`, "var(--status-err)"); - if (isMapLoaded() && now - lastZoomActionTime > 2000) { - map.flyTo({ center: [-74.0721, 4.7110], zoom: 6, bearing: 0, pitch: 0 }); - lastZoomActionTime = now; - } - isPinching = false; - cursor.classList.remove('pinching'); - } - else if (isIndexOpen && isMidOpen && !isRingOpen && !isPinkyOpen) { - setGestureState('ZOOM_IN', `ACCION: ZOOM IN (+) [Z:${depthZ}]`, "var(--accent-cyan)"); - cursor.classList.add('zooming'); - if (isMapLoaded() && now - lastZoomActionTime > 150) { - map.zoomTo(map.getZoom() + 0.2, {duration: 150}); - lastZoomActionTime = now; - } - isPinching = false; - cursor.classList.remove('pinching'); - } - else if (isIndexOpen && isMidOpen && isRingOpen && isPinkyOpen && pinchDist > pinchThreshold) { - setGestureState('ZOOM_OUT', `ACCION: ZOOM OUT (-) [Z:${depthZ}]`, "var(--accent-purple)"); - cursor.classList.add('zooming'); - if (isMapLoaded() && now - lastZoomActionTime > 150) { - map.zoomTo(map.getZoom() - 0.2, {duration: 150}); - lastZoomActionTime = now; - } - isPinching = false; - cursor.classList.remove('pinching'); - } - else if (pinchDist < pinchThreshold) { - setGestureState('DRAG', `ACCION: ARRASTRE [Z:${depthZ}]`, "#fff"); - - if (!isPinching) { - isPinching = true; - cursor.classList.add('pinching'); - - const elementUnder = document.elementFromPoint(smoothedX, smoothedY); - if (elementUnder && elementUnder.closest('.vision-glass-panel')) { - activeDragPanel = elementUnder.closest('.vision-glass-panel'); - activeDragPanel.classList.add('is-dragging'); - - const rect = activeDragPanel.getBoundingClientRect(); - activeDragPanel.style.position = 'fixed'; - activeDragPanel.style.left = rect.left + 'px'; - activeDragPanel.style.top = rect.top + 'px'; - activeDragPanel.style.width = rect.width + 'px'; - activeDragPanel.style.margin = '0'; - - dragOffset = { - x: smoothedX - rect.left, - y: smoothedY - rect.top - }; - } else { - activeDragPanel = null; - dragStartMapCenter = map.getCenter(); - dragStartCursorPos = { x: smoothedX, y: smoothedY }; - } - } else { - if (activeDragPanel) { - activeDragPanel.style.left = (smoothedX - dragOffset.x) + 'px'; - activeDragPanel.style.top = (smoothedY - dragOffset.y) + 'px'; - } else { - const pixelDeltaX = dragStartCursorPos.x - smoothedX; - const pixelDeltaY = dragStartCursorPos.y - smoothedY; - - if(isMapLoaded()) { - const zoomFactor = Math.pow(2, map.getZoom()); - const lngDelta = (pixelDeltaX / 512) * (360 / zoomFactor); - const latDelta = -(pixelDeltaY / 512) * (360 / zoomFactor) * Math.cos(dragStartMapCenter.lat * Math.PI / 180); - - map.setCenter([ - dragStartMapCenter.lng + lngDelta, - dragStartMapCenter.lat + latDelta - ]); - } - } - } - } - else { - setGestureState('POINTER', `TRACKING: PUNTERO [Z:${depthZ}]`, "rgba(255,255,255,0.5)"); - - if (isPinching) { - isPinching = false; - cursor.classList.remove('pinching'); - if(activeDragPanel) { - activeDragPanel.classList.remove('is-dragging'); - activeDragPanel = null; - } - - const elementUnderCursor = document.elementFromPoint(smoothedX, smoothedY); - if(elementUnderCursor && (elementUnderCursor.tagName === 'BUTTON' || elementUnderCursor.closest('button'))) { - const btn = elementUnderCursor.tagName === 'BUTTON' ? elementUnderCursor : elementUnderCursor.closest('button'); - btn.click(); - playSciFiBlip(1000, 'square', 0.05); - } - } else { - document.querySelectorAll('button').forEach(btn => btn.classList.remove('hovered')); - const element = document.elementFromPoint(smoothedX, smoothedY); - if(element && (element.tagName === 'BUTTON' || element.closest('button'))) { - const btn = element.tagName === 'BUTTON' ? element : element.closest('button'); - btn.classList.add('hovered'); - } - } - } - - if (currentGestureState === 'POINTER') { - onFeatureHover(smoothedX, smoothedY); - } else { - document.getElementById('spatial-tooltip').style.display = 'none'; - } - - } else { - if (isPinching) { - isPinching = false; - cursor.classList.remove('pinching'); - } - frameCount++; - const currentTime = Date.now(); - if (currentTime - lastFPSUpdate > 1000) { - currentFPS = frameCount; - frameCount = 0; - lastFPSUpdate = currentTime; - } - gestureFeedback.innerText = `ESPERANDO INPUT... | FPS:${currentFPS}`; - } - canvasCtx.restore(); -} - -export function getCurrentGestureState() { return currentGestureState; } diff --git a/assets/js/vision/index.js b/assets/js/vision/index.js deleted file mode 100644 index a3c26b3..0000000 --- a/assets/js/vision/index.js +++ /dev/null @@ -1,64 +0,0 @@ -/** - * DGZ Vision — Main Entry Point - */ -import { initMap, changeBasemap, toggleIGAC, toggleCadastre, togglePowerLayer } from './map-engine.js'; -import { togglePanel, initMouseDrag, onFeatureHover } from './ui-controller.js'; -import { initVision, initVisionElements, getCurrentGestureState } from './gestures.js'; - -// 1. Mapbox Configuration - Fetching from backend for security -async function getMapboxToken() { - try { - // En Vercel, el backend suele estar en /api o la ruta configurada - const response = await fetch('/api/config/mapbox-token'); - if(!response.ok) throw new Error('Backend config error'); - const data = await response.json(); - return data.token; - } catch (e) { - console.warn("Security policy: no local fallback allowed."); - return ''; - } -} - -document.addEventListener('DOMContentLoaded', async () => { - const MAPBOX_TOKEN = await getMapboxToken(); - - // 2. Initialize Map - const map = initMap(MAPBOX_TOKEN); - - // 3. Initialize Vision Elements - const elements = { - video: document.querySelector('.input_video'), - canvas: document.querySelector('.output_canvas'), - ctx: document.querySelector('.output_canvas').getContext('2d'), - cursor: document.getElementById('cyber-cursor'), - statusText: document.getElementById('vision-status'), - gestureFeedback: document.getElementById('gesture-status') - }; - initVisionElements(elements); - - // 4. Global Map Events - map.on('mousemove', (e) => { - const state = getCurrentGestureState(); - if (state === "NONE" || state === "POINTER") { - onFeatureHover(e.point.x, e.point.y); - } - }); - - // 5. Canvas Resize - const canvas = elements.canvas; - function resizeCanvas() { - canvas.width = window.innerWidth; - canvas.height = window.innerHeight; - } - window.addEventListener('resize', resizeCanvas); - resizeCanvas(); - - // 6. Expose functions to window (for legacy onclick attributes) - window.togglePanel = togglePanel; - window.initMouseDrag = initMouseDrag; - window.changeBasemap = changeBasemap; - window.toggleIGAC = toggleIGAC; - window.toggleCadastre = toggleCadastre; - window.togglePowerLayer = togglePowerLayer; - window.initVision = initVision; -}); diff --git a/assets/js/vision/map-engine.js b/assets/js/vision/map-engine.js deleted file mode 100644 index 616c501..0000000 --- a/assets/js/vision/map-engine.js +++ /dev/null @@ -1,292 +0,0 @@ -/** - * DGZ Vision — Map Engine Controller - */ -import { playSciFiBlip } from './utils.js'; - -let map; -let mapLoaded = false; -let isIGACActive = false; -let isCadastreActive = false; -let isPowerActive = false; - -const cadastreGeoJSON = { - "type": "FeatureCollection", - "features": [ - { "type": "Feature", "properties": { "predio": "001-A", "uso": "Residencial", "area": "120m²", "propietario": "J. Pérez", "avaluo": "$150M" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0721, 4.7110 ], [ -74.0725, 4.7110 ], [ -74.0725, 4.7114 ], [ -74.0721, 4.7114 ], [ -74.0721, 4.7110 ] ] ] } }, - { "type": "Feature", "properties": { "predio": "001-B", "uso": "Comercial", "area": "85m²", "propietario": "M. Gómez", "avaluo": "$210M" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0721, 4.7106 ], [ -74.0725, 4.7106 ], [ -74.0725, 4.7110 ], [ -74.0721, 4.7110 ], [ -74.0721, 4.7106 ] ] ] } }, - { "type": "Feature", "properties": { "predio": "002-A", "uso": "Lote Baldío", "area": "400m²", "propietario": "Distrito Capital", "avaluo": "$30M" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -74.0715, 4.7106 ], [ -74.0721, 4.7106 ], [ -74.0721, 4.7114 ], [ -74.0715, 4.7114 ], [ -74.0715, 4.7106 ] ] ] } } - ] -}; - -const powerLinesGeoJSON = { - "type": "FeatureCollection", - "features": [ - { "type": "Feature", "properties": { "type": "HighVoltage", "voltage": "230kV", "status": "Active" }, "geometry": { "type": "LineString", "coordinates": [ [-74.0721, 4.7110], [-74.10, 4.75], [-74.15, 4.80] ] } }, - { "type": "Feature", "properties": { "type": "Substation", "name": "Bogota-Norte", "capacity": "500MW" }, "geometry": { "type": "Point", "coordinates": [-74.0721, 4.7110] } } - ] -}; - -export function initMap(accessToken) { - mapboxgl.accessToken = accessToken; - map = new mapboxgl.Map({ - container: 'map-container', - style: 'mapbox://styles/mapbox/dark-v11', - center: [-74.0721, 4.7110], - zoom: 6, - pitch: 45, - bearing: 0, - antialias: true, - projection: 'globe' - }); - - map.on('style.load', () => { - map.setFog({ - 'color': 'rgb(186, 210, 235)', - 'high-color': 'rgb(36, 92, 223)', - 'horizon-blend': 0.02, - 'space-color': 'rgb(11, 11, 25)', - 'star-intensity': 0.6 - }); - - map.addSource('mapbox-dem', { - 'type': 'raster-dem', - 'url': 'mapbox://mapbox.mapbox-terrain-dem-v1', - 'tileSize': 512, - 'maxzoom': 14 - }); - map.setTerrain({ 'source': 'mapbox-dem', 'exaggeration': 1.5 }); - mapLoaded = true; - addCustomLayers(); - }); - - return map; -} - -export function addCustomLayers() { - if (!map) return; - - // 1. Colombia Departamentos - if (!map.getSource('colombia-departamentos')) { - map.addSource('colombia-departamentos', { - type: 'geojson', - data: 'https://raw.githubusercontent.com/johan/world.geo.json/master/countries/COL.geo.json' - }); - } - if (!map.getLayer('col-layer')) { - map.addLayer({ - id: 'col-layer', - type: 'line', - source: 'colombia-departamentos', - paint: { 'line-color': '#00E5FF', 'line-width': 2, 'line-opacity': 0.6 } - }); - map.addLayer({ - id: 'col-fill', - type: 'fill', - source: 'colombia-departamentos', - paint: { 'fill-color': '#9D4EDD', 'fill-opacity': 0.1 } - }); - } - - // 2. Earthquakes - if (!map.getSource('earthquakes')) { - map.addSource('earthquakes', { - type: 'geojson', - data: 'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_month.geojson' - }); - } - if (!map.getLayer('earthquakes-glow')) { - map.addLayer({ - id: 'earthquakes-glow', - type: 'circle', - source: 'earthquakes', - paint: { - 'circle-radius': ['*', ['get', 'mag'], 4], - 'circle-color': '#ff4b2b', - 'circle-opacity': 0.2, - 'circle-blur': 1 - } - }); - map.addLayer({ - id: 'earthquakes-core', - type: 'circle', - source: 'earthquakes', - paint: { - 'circle-radius': ['*', ['get', 'mag'], 1.5], - 'circle-color': '#FFB400', - 'circle-opacity': 0.8, - 'circle-stroke-width': 1, - 'circle-stroke-color': '#000' - } - }); - } - - // 3. SGC WMS - if (isIGACActive) { - if (!map.getSource('sgc-wms')) { - map.addSource('sgc-wms', { - 'type': 'raster', - 'tiles': [ - 'https://srvags.sgc.gov.co/arcgis/services/Mapa_Geologico_Colombia_2015/Mapa_Geologico_Colombia_2015/MapServer/WMSServer?bbox={bbox-epsg-3857}&format=image/png&service=WMS&version=1.1.1&request=GetMap&srs=EPSG:3857&transparent=true&width=256&height=256&layers=17,18,19,20,60&styles=,,,,' - ], - 'tileSize': 256 - }); - } - if (!map.getLayer('sgc-layer')) { - map.addLayer({ - 'id': 'sgc-layer', - 'type': 'raster', - 'source': 'sgc-wms', - 'paint': { 'raster-opacity': 0.8 } - }, 'col-fill'); - } - } else if (map.getLayer('sgc-layer')) { - map.removeLayer('sgc-layer'); - map.removeSource('sgc-wms'); - } - - // 4. Cadastre - if (isCadastreActive) { - if (!map.getSource('cadastre')) { - map.addSource('cadastre', { - type: 'geojson', - data: cadastreGeoJSON - }); - } - if (!map.getLayer('cadastre-fill')) { - map.addLayer({ - id: 'cadastre-fill', - type: 'fill', - source: 'cadastre', - paint: { - 'fill-color': [ - 'match', ['get', 'uso'], - 'Residencial', '#00E5FF', - 'Comercial', '#FFB400', - '#9D4EDD' - ], - 'fill-opacity': 0.4 - } - }); - map.addLayer({ - id: 'cadastre-line', - type: 'line', - source: 'cadastre', - paint: { - 'line-color': '#FFF', - 'line-width': 1 - } - }); - map.flyTo({ center: [-74.0720, 4.7110], zoom: 16.5, speed: 1.5 }); - } - } else { - if (map.getLayer('cadastre-fill')) map.removeLayer('cadastre-fill'); - if (map.getLayer('cadastre-line')) map.removeLayer('cadastre-line'); - if (map.getSource('cadastre')) map.removeSource('cadastre'); - } - - // 5. Power Lines - if (isPowerActive) { - if (!map.getSource('power')) { - map.addSource('power', { type: 'geojson', data: powerLinesGeoJSON }); - } - if (!map.getLayer('power-lines')) { - map.addLayer({ - id: 'power-lines-glow', - type: 'line', - source: 'power', - paint: { 'line-color': '#39FF14', 'line-width': 6, 'line-blur': 4, 'line-opacity': 0.4 } - }); - map.addLayer({ - id: 'power-lines', - type: 'line', - source: 'power', - paint: { 'line-color': '#FFF', 'line-width': 2, 'line-opacity': 0.8 } - }); - map.addLayer({ - id: 'power-points', - type: 'circle', - source: 'power', - filter: ['==', '$type', 'Point'], - paint: { 'circle-radius': 8, 'circle-color': '#39FF14', 'circle-stroke-width': 2, 'circle-stroke-color': '#FFF' } - }); - - animatePower(); - } - } else { - if (map.getLayer('power-lines')) map.removeLayer('power-lines'); - if (map.getLayer('power-lines-glow')) map.removeLayer('power-lines-glow'); - if (map.getLayer('power-points')) map.removeLayer('power-points'); - if (map.getSource('power')) map.removeSource('power'); - } -} - -let powerStep = 0; -function animatePower() { - if (!isPowerActive || !map) return; - powerStep = (powerStep + 1) % 100; - const opacity = 0.3 + (Math.sin(powerStep / 10) * 0.3); - if (map.getLayer('power-lines-glow')) { - map.setPaintProperty('power-lines-glow', 'line-opacity', opacity); - } - requestAnimationFrame(animatePower); -} - -export function changeBasemap(type) { - playSciFiBlip(500, 'square', 0.1); - document.getElementById('btn-dark').classList.remove('active'); - document.getElementById('btn-sat').classList.remove('active'); - - if (type === 'dark') { - document.getElementById('btn-dark').classList.add('active'); - map.setStyle('https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json'); - } else { - document.getElementById('btn-sat').classList.add('active'); - map.setStyle({ - 'version': 8, - 'sources': { - 'esri-sat': { - 'type': 'raster', - 'tiles': ['https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}'], - 'tileSize': 256 - } - }, - 'layers': [{ - 'id': 'satellite', - 'type': 'raster', - 'source': 'esri-sat', - 'minzoom': 0, - 'maxzoom': 22 - }] - }); - } -} - -export function toggleIGAC() { - playSciFiBlip(700, 'sawtooth', 0.15); - isIGACActive = !isIGACActive; - const btn = document.getElementById('btn-igac'); - if (isIGACActive) btn.classList.add('active'); - else btn.classList.remove('active'); - addCustomLayers(); -} - -export function toggleCadastre() { - playSciFiBlip(800, 'square', 0.1); - isCadastreActive = !isCadastreActive; - const btn = document.getElementById('btn-cadastre'); - if (isCadastreActive) btn.classList.add('active'); - else btn.classList.remove('active'); - addCustomLayers(); -} - -export function togglePowerLayer() { - playSciFiBlip(900, 'sine', 0.2); - isPowerActive = !isPowerActive; - const btn = document.getElementById('btn-power'); - if (isPowerActive) btn.classList.add('active'); - else btn.classList.remove('active'); - addCustomLayers(); -} - -export function isMapLoaded() { return mapLoaded; } -export function getMap() { return map; } diff --git a/assets/js/vision/ui-controller.js b/assets/js/vision/ui-controller.js deleted file mode 100644 index e748276..0000000 --- a/assets/js/vision/ui-controller.js +++ /dev/null @@ -1,113 +0,0 @@ -/** - * DGZ Vision — UI interaction Controller - */ -import { playSciFiBlip } from './utils.js'; -import { isMapLoaded, getMap } from './map-engine.js'; - -let activeDragPanel = null; -let dragOffset = { x: 0, y: 0 }; - -export function togglePanel(btnElement) { - playSciFiBlip(600, 'sine', 0.05); - const content = btnElement.nextElementSibling; - const icon = btnElement.querySelector('.toggle-icon'); - content.classList.toggle('collapsed'); - icon.classList.toggle('rotated'); -} - -export function initMouseDrag(e, panel) { - e.stopPropagation(); - activeDragPanel = panel; - - const rect = panel.getBoundingClientRect(); - panel.style.position = 'fixed'; - panel.style.left = rect.left + 'px'; - panel.style.top = rect.top + 'px'; - panel.style.width = rect.width + 'px'; - panel.style.margin = '0'; - - dragOffset = { - x: e.clientX - rect.left, - y: e.clientY - rect.top - }; - - panel.classList.add('is-dragging'); - - document.addEventListener('mousemove', onMouseDrag); - document.addEventListener('mouseup', stopMouseDrag); -} - -function onMouseDrag(e) { - if (!activeDragPanel) return; - activeDragPanel.style.left = (e.clientX - dragOffset.x) + 'px'; - activeDragPanel.style.top = (e.clientY - dragOffset.y) + 'px'; -} - -function stopMouseDrag() { - if (activeDragPanel) activeDragPanel.classList.remove('is-dragging'); - activeDragPanel = null; - document.removeEventListener('mousemove', onMouseDrag); - document.removeEventListener('mouseup', stopMouseDrag); -} - -export function onFeatureHover(x, y) { - if (!isMapLoaded()) return; - const map = getMap(); - - let features = []; - try { - const layersToQuery = []; - if (map.getLayer('earthquakes-core')) layersToQuery.push('earthquakes-core'); - if (map.getLayer('col-fill')) layersToQuery.push('col-fill'); - if (map.getLayer('cadastre-fill')) layersToQuery.push('cadastre-fill'); - - if (layersToQuery.length > 0) { - features = map.queryRenderedFeatures([x, y], { layers: layersToQuery }); - } - } catch (err) { - console.warn("Query rendering error", err); - return; - } - - const tooltip = document.getElementById('spatial-tooltip'); - - if (features.length > 0) { - const f = features[0]; - tooltip.style.display = 'block'; - tooltip.style.left = `${x}px`; - tooltip.style.top = `${y}px`; - - const ttId = document.getElementById('tt-id'); - const ttContent = document.getElementById('tt-content'); - - if (f.layer.id === 'earthquakes-core') { - const mag = parseFloat(f.properties.mag).toFixed(1); - const place = f.properties.place; - const date = new Date(f.properties.time).toLocaleString(); - ttId.innerText = "SISMO [USGS]"; - ttContent.innerHTML = ` -
Magnitud${mag} M
-
Epicentro${place.split(' of ').pop()}
-
Timestamp${date}
- `; - } else if (f.layer.id === 'col-fill') { - const name = f.properties.name || "Territorio Nacional"; - ttId.innerText = "CAPA [COL]"; - ttContent.innerHTML = ` -
Provincia${name}
-
SoberaníaAutónoma
-
ResoluciónAlta (LADM-COL)
- `; - } else if (f.layer.id === 'cadastre-fill') { - ttId.innerText = "PREDIO [" + f.properties.predio + "]"; - ttContent.innerHTML = ` -
Uso${f.properties.uso}
-
Área${f.properties.area}
-
Propietario${f.properties.propietario}
-
Avalúo${f.properties.avaluo}
- `; - } - } else { - tooltip.style.display = 'none'; - } -} diff --git a/assets/js/vision/utils.js b/assets/js/vision/utils.js deleted file mode 100644 index e9fe420..0000000 --- a/assets/js/vision/utils.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * DGZ Vision — Utility Functions - */ - -const audioCtx = new (window.AudioContext || window.webkitAudioContext)(); - -export function playSciFiBlip(freq = 800, type = 'sine', duration = 0.1) { - if (audioCtx.state === 'suspended') audioCtx.resume(); - const osc = audioCtx.createOscillator(); - const gain = audioCtx.createGain(); - osc.type = type; - osc.frequency.setValueAtTime(freq, audioCtx.currentTime); - gain.gain.setValueAtTime(0.05, audioCtx.currentTime); - gain.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + duration); - osc.connect(gain); - gain.connect(audioCtx.destination); - osc.start(); - osc.stop(audioCtx.currentTime + duration); -} diff --git a/backend/qa_engine/core_validator.py b/backend/qa_engine/core_validator.py index 94f11dc..dd5d7ad 100644 --- a/backend/qa_engine/core_validator.py +++ b/backend/qa_engine/core_validator.py @@ -124,7 +124,7 @@ def cross_reference_excel(self, gdf: gpd.GeoDataFrame, excel_path: str, join_col df_registral = pl.read_csv(excel_path, ignore_errors=True) except Exception as e: return {"error": f"Error al cargar el archivo tabular con Polars: {e}"} - + # Normalizar nombres de columnas a minúsculas para evitar errores de digitación gdf.columns = [c.lower() for c in gdf.columns] df_registral = df_registral.rename({col: col.lower() for col in df_registral.columns}) @@ -156,23 +156,23 @@ def cross_reference_excel(self, gdf: gpd.GeoDataFrame, excel_path: str, join_col area_discrepancies_count = 0 if area_col_snr: snr_area_col = area_col_snr[0] - + # Asegurar que el área en el registro sea float df_registral = df_registral.with_columns(pl.col(snr_area_col).cast(pl.Float64, strict=False)) - + # Inner join para comparar los que existen en ambos merged = df_spatial.join(df_registral.select([join_col, snr_area_col]), on=join_col, how="inner") - + # Filtramos diferencias mayores a 1 m2 discrepancies = merged.with_columns( (pl.col("area_m2_calc") - pl.col(snr_area_col)).abs().alias("diff_m2") ).filter(pl.col("diff_m2") > 1.0).sort("diff_m2", descending=True) - + area_discrepancies_count = discrepancies.height - + # Limitamos el reporte a las primeras 100 anomalías para no saturar JSON area_diffs = discrepancies.head(100).select([join_col, "diff_m2"]).to_dicts() - + # Formateamos la lista resultante for diff in area_diffs: diff['id'] = diff.pop(join_col) diff --git a/backend/qa_engine/main.py b/backend/qa_engine/main.py index 2de2100..1e3106e 100644 --- a/backend/qa_engine/main.py +++ b/backend/qa_engine/main.py @@ -84,16 +84,16 @@ async def analyze_shapefile(background_tasks: BackgroundTasks, file: UploadFile job_id = str(uuid.uuid4()) JOB_TRACKER[job_id] = {"status": "Processing", "file": file.filename, "result": None, "error": None} - + # Enviar a Background Tasks de FastAPI (Nativo, no bloqueante) background_tasks.add_task( - _background_process_shapefile, + _background_process_shapefile, job_id, temp_dir, temp_file_path, file.filename ) - + return { - "job_id": job_id, - "status": "Processing", + "job_id": job_id, + "status": "Processing", "message": "Archivo encolado. Use /api/v1/jobs/{job_id} para ver el resultado." } diff --git a/backend/qa_engine/test_core_validator.py b/backend/qa_engine/test_core_validator.py index 66e04db..a586fa9 100644 --- a/backend/qa_engine/test_core_validator.py +++ b/backend/qa_engine/test_core_validator.py @@ -13,7 +13,7 @@ def sample_gdf(): # Creamos un polígono válido y uno inválido ("moño" que se auto-intersecta) poly_valid = Polygon([(0, 0), (0, 10), (10, 10), (10, 0), (0, 0)]) poly_invalid = Polygon([(0, 0), (0, 10), (10, 0), (10, 10), (0, 0)]) - + gdf = gpd.GeoDataFrame({ "npu": ["10001", "10002"], "geometry": [poly_valid, poly_invalid] @@ -22,9 +22,9 @@ def sample_gdf(): def test_validate_geometries_auto_heals(validator, sample_gdf): assert not sample_gdf.geometry.is_valid.all(), "El GDF original debería tener geometrías inválidas" - + result = validator.validate_geometries(sample_gdf) - + assert result["invalid_geometries_found"] == 1 assert sample_gdf.geometry.is_valid.all(), "El validador debió curar las geometrías" @@ -32,9 +32,9 @@ def test_detect_slivers(validator): # Creamos un sliver (área < 5) y un polígono grande (área 100) sliver = Polygon([(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)]) large = Polygon([(0, 0), (0, 10), (10, 10), (10, 0), (0, 0)]) - + gdf = gpd.GeoDataFrame({"npu": ["1", "2"], "geometry": [sliver, large]}, crs="EPSG:3116") - + result = validator.detect_slivers(gdf) assert result["slivers_count"] == 1 assert len(result["sliver_indices"]) == 1 @@ -44,9 +44,9 @@ def test_detect_overlaps(validator): # Dos polígonos que comparten un área sustancial (overlap) poly1 = Polygon([(0, 0), (0, 10), (10, 10), (10, 0), (0, 0)]) poly2 = Polygon([(5, 5), (5, 15), (15, 15), (15, 5), (5, 5)]) - + gdf = gpd.GeoDataFrame({"npu": ["1", "2"], "geometry": [poly1, poly2]}, crs="EPSG:3116") - + result = validator.detect_overlaps(gdf) assert result["overlaps_count"] == 1 assert len(result["overlap_pairs"]) == 1 \ No newline at end of file diff --git a/geoai/change_detection.py b/geoai/change_detection.py deleted file mode 100644 index 028a508..0000000 --- a/geoai/change_detection.py +++ /dev/null @@ -1,52 +0,0 @@ -""" -GeoAI — Simple change detection example -Requires: rasterio, numpy, geopandas - -Usage: - python geoai/change_detection.py before.tif after.tif output_changes.geojson - -This script compares two aligned single-band rasters and exports detected -change areas as polygons (GeoJSON). -""" -import sys -import numpy as np -import rasterio -from rasterio import features -import json - - -def detect_change(path_before, path_after, out_geojson, threshold=30): - with rasterio.open(path_before) as src1, rasterio.open(path_after) as src2: - arr1 = src1.read(1).astype('float32') - arr2 = src2.read(1).astype('float32') - - # Simple difference and threshold - diff = np.abs(arr2 - arr1) - change_mask = (diff >= threshold).astype('uint8') - - # Vectorize mask - transform = src1.transform - shapes = features.shapes(change_mask, transform=transform) - - features_list = [] - for geom, val in shapes: - if val == 1: - features_list.append({ - 'type': 'Feature', - 'properties': {'detected': 1}, - 'geometry': geom - }) - - feature_collection = {'type': 'FeatureCollection', 'features': features_list} - - with open(out_geojson, 'w', encoding='utf-8') as fh: - json.dump(feature_collection, fh) - - print(f"Wrote {len(features_list)} change features to {out_geojson}") - - -if __name__ == '__main__': - if len(sys.argv) < 4: - print('Usage: change_detection.py before.tif after.tif out.geojson') - sys.exit(1) - detect_change(sys.argv[1], sys.argv[2], sys.argv[3]) diff --git a/index.html b/index.html deleted file mode 100644 index ae7f945..0000000 --- a/index.html +++ /dev/null @@ -1,2164 +0,0 @@ - - - - - - - DevGIZ | Smart Geospatial DevOps Systems - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
-
-
-
-
-
-
-
-
- - - - - - - - - -
- - -
- -
-
Personal_Profile
-
- - - - - -
-

ALBERT DANIEL GAVIRIA ZAPATA

-
- CC: 1007533510 // HQ: MEDELLÍN
V5.2_SOVEREIGN_SYSTEM // 23Y
STATUS: ACTIVE // IMMEDIATE_DEP -
-

- Profesional SIG con una visión integral que fusiona la excelencia técnica en Sistemas de Información - Geográfica con maestría en arquitectura de bases de datos y desarrollo de software. -

-
SIG + - Python/SQL Technologist
-
- Expert: ArcGIS Pro, QGIS, Civil 3D
-
QA/QC - & Property Management
-
- LADM-COL & IGAC Standards
-
- -
-
📍 Medellín, Colombia
-
📞 305 326 1466
-
- -
- - - Download Datasheet (PDF) - - - - -
-
Technical_DNA
-
-
-
QGIS / ArcGIS Pro100%
-
-
-
-
SQL Server / - AutoCAD90%
-
-
-
-
Civil 3D / - Photoshop90%
-
-
-
-
-
-
Global Mapper80%
-
-
-
-
PostgreSQL / - PostGIS85%
-
-
-
-
Python / Web - Development85%
-
-
-
-
-
-
- MapInfo Earth Pro - Revit (Basic) FME -
-
- - -
-
Languages
-
-
EspañolNative
-
EnglishC1_ADV
-
FrançaisB1_INT
-
DeutschB1_INT
-
-
- - -
-
Impact_Metrics
-
-
115%
-
- ROI_OPERATIONAL
-
-
30%
-
- ERROR_REDUCTION
-
-
- - -
-
Academic_Trajectory
-
-
Ingeniería de Sistemas (C)
-
EAFIT // 2024 - - ACTUAL
-
-
-
Técnico Conservación
-
SENA // - 2019
-
-
- - -
-
Credentials & Courses
-
-
- QGIS Maps (23) -
-
- Python Data (23) -
-
- Project Mgmt (23) -
-
- AutoCAD 2D (23) -
-
- Intro SIG (23) -
-
- LADM-COL Std -
-
- English B2/C1 -
-
- ISO 14001:2015 -
-
-
- - -
-
Current_Mission
-
-
Analista - Geográfico
-
- GEOGRAFÍA SATELITAL GEOSAT S.A.S. // 09/2025 - 12/2025
-

- Procesamiento avanzado de información geoespacial mediante fotointerpretación, análisis de - insumos 360° y restitución vectorial. Digitalización masiva para actualización catastral con - validación topológica. -

-
-
- - -
-
Professional_Log
-
-
-
Coordinador - Profesional SIG
-
UT - SMART CITY // 2024 - ACTUAL
-
-
-
Control Calidad - Catastral (QA/QC) -
-
ACCION - DEL CAUCA // 2025
-
-
-
Coordinador & - Líder de Campo -
-
- ARBIRTRIUM S.A.S // 2024 - 2025
-
-
-
Profesional SIG - (Drones & GIS) -
-
GRUPO - EMPRESARIAL OD // 2023 - 2024
-
-
-
- - -
-
Verified_Recognitions
-
-
- -
-
Sistemas de Gestión
-
2023
-
-
-
- 🌍 -
-
Instituto Ambiental SIG
-
2023
-
-
-
- -
-
Diseño Eléctrico
-
Electrical Training
-
-
-
- 👷 -
-
Seguridad y Salud
-
SG-SST 2023
-
-
-
-
-
-
- - - - -
- -
-
-
- - Disponible para Proyectos · Medellín, Colombia -
- -

- DevGiz -

- -

- Smart Geospatial DevOps Systems — Building Digital Territories -

- - - -
-
- 50k+ - Spatial Nodes -
-
-
- 0.02s - Query Latency -
-
-
- LADM-COL - V3 Protocol -
-
-
- - -
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
- PostGIS - PostGIS -
-
- - -
- Python - Python -
-
- FastAPI - FastAPI -
-
- Docker - Docker -
-
- QGIS - QGIS -
-
- - GeoAI -
-
- - LADM-COL -
- - -
- React -
-
- Node.js -
- -
- 50k+ - Spatial Nodes -
-
- v3 - LADM-COL -
- -
- 50k+ - Spatial Nodes -
-
- v3 - LADM-COL -
-
-
-
- - -
-
-
Servicios Especializados -
-

Soluciones especializadas para cada desafío - territorial

- -
- -
-
- SVC-M-01 -
SISTEMA - ACTIVO
-
-
🗺️
-

Actualización Catastral Masiva

-

Gestión y validación de +500 predios por ciclo. Automatización - completa del flujo de reconocimiento predial bajo estándares IGAC y LADM-COL V3.

-
-
- +500 - Predios/Ciclo -
-
- 99.8% - Precisión SIG -
-
-
ArcGIS ProLADM-COLPostGIS
-
- - -
-
- SVC-Q-02 -
SISTEMA - ACTIVO
-
-
⚙️
-

QA/QC Catastral (Control de Calidad)

-

Auditorías técnicas con Python y QGIS. Detección automática de - solapamientos, huecos y errores topológicos. Reportes certificados.

-
-
- 100% - Integridad Topo -
-
- Automated - Engine -
-
-
PythonShapelyQGIS
-
- - -
-
- SVC-E-03 -
SISTEMA - ACTIVO
-
-
🔄
-

Pipelines ETL Geoespaciales

-

Arquitectura de transformación desatendida para ingesta masiva de - datos GIS. De campo a base de datos sin intervención manual.

-
-
- Headless - Processing -
-
- Real-time - Sync Status -
-
-
GDAL/OGRFMEFastAPI
-
- - -
-
- SVC-A-04 -
- EN DESARROLLO -
-
-
🛰️
-

GeoAI — Detección de Cambios

-

Machine Learning sobre imagenería Sentinel-2 para detectar expansión - urbana, cambios de cobertura y mutaciones territoriales.

-
-
- Sentinel-2 - DataSource -
-
- CNN - Model Architecture -
-
-
Scikit-learnRasterioSentinel-2 -
-
- - -
-
- SVC-D-05 -
SISTEMA - ACTIVO
-
-
📊
-

Dashboards GIS Empresariales

-

Interfaces interactivas conectadas a PostGIS para análisis territorial - en tiempo real. Visualización de indicadores catastrales.

-
-
- WebMap - Rendering -
-
- Cloud - Deployment -
-
-
MapLibre GLReactREST API
-
- - -
-
- SVC-C-06 -
SISTEMA - ACTIVO
-
-
🏗️
-

Coordinación de Campo GIS

-

Liderazgo de equipos técnicos en terrenos complejos. Nivelación - topográfica, digitalización masiva y coordinación normativa.

-
-
- RTK - Hardware -
-
- NSR-10 - Compliance -
-
-
GPS RTKCivil 3DAutoCAD
-
-
-
-
- - -
-
-
Desafíos Territoriales -
-

Lo que resuelvo para su entidad

-

Los gobiernos y entidades territoriales enfrentan desafíos críticos de datos - espaciales. Estos son los problemas que transformo en soluciones automatizadas.

- -
-
-
01
-

QA manual lento y propenso a errores

-
-

Validación - automática con Python + PostGIS

-
-
-
-
02
-

Datos prediales inconsistentes

-
-

Modelado - espacial LADM-COL estructurado

-
-
-
-
03
-

Procesos de digitalización lentos

-
-

Pipelines - SIG automatizados con GDAL/FME

-
-
-
-
04
-

Topología catastral rota

-
-

Motores de - validación topológica automatizados

-
-
-
-
05
-

Sin visibilidad sobre cambios de cobertura

-
-

GeoAI: - detección cambios con Sentinel + Rasterio

-
-
-
-
-
- - - -
-
-
-
Núcleo de Ingeniería -
- -
-
-

Excelencia GIS & Arquitectura - de Software

-

- Cerramos la brecha entre el mapeo SIG tradicional y la arquitectura de software escalable. - Enfocados en flujos de datos de alta precisión y automatización técnica. Nuestro núcleo - transforma datos geográficos sin estructura en inteligencia territorial automatizada y - soberana. -

-
-
Arquitectura LADM-COL Autónoma
-
Pipeline ETL Desatendido
-
- Nodos Geospaciales en la Nube -
-
-
- -
-
-
- Spatial Data Engineering - 95% -
-
-
-
-
-
-
- Python Automatization (GDAL/PyQGIS) - 90% -
-
-
-
-
-
-
- PostGIS & Database Architecture - 85% -
-
-
-
-
-
-
- Frontend Web GIS (React/MapLibre) - 80% -
-
-
-
-
-
-
-
-
- - -
-
-
Stack Tecnológico -
-

La Matriz de Ingeniería

- -
- -
-
-
-

ID_GIS_SPATIAL_INFRA

-

PostGIS topology matrix, LADM-COL V3 compliance, and - high-fidelity vector architecture.

-
-
- PostGIS - PostGIS - QGIS QGIS - Supabase - Supabase - LADM-COL -
-
- -
-
-
-

ID_SYSTEMS_ENGINEERING

-

Backend systems for spatial intelligence, RESTful Node - architecture, and automated logic.

-
-
- Python - Python - FastAPI - FastAPI - TypeScript - TypeScript - Node.js - Node.js - React - React -
-
- -
-
-
-

ID_AUTOMATION_DEVOPS

-

CI/CD pipelines for geospatial assets, containerized spatial - nodes, and kernel optimization.

-
-
- Actions GitHub Actions - Docker - Docker - Vercel - Vercel - Linux Linux - Kernel -
-
-
-
-
- - -
-
-
Rendimiento - Comprobado
-

Métricas de Impacto

- -
-
-
50k+ -
-
Spatial Records Processed
-
Parcels // Cartography // Cadastre
-
-
-
-
-30% -
-
Error Margin Reduction
-
QA/QC // Automation // Validation
-
-
-
-
115% -
-
Operational Efficiency
-
ROI // Workflow Automation
-
-
-
-
6+ -
-
Multipurpose Cadastre Projects
-
LADM-COL // IGAC Standards
-
-
-
-
-
- - -
-
-
-
- DGZ SPATIAL LAB · LIVE DEMOS -
-

Spatial Intelligence Laboratory

-

- High-performance geospatial nodes demonstrating territorial automation, multipurpose cadastral - engines, and advanced spatial systems engineering. -

- -
- -
- -
-
-
SYS_NODE: VIEWER_01
-
-
-
-

Interactive Spatial Node

-

High-precision GIS viewer with real-time parcel rendering. - Interacting with local datasets exported from QGIS with deep topology attributes.

-
- MapLibre GLVector TilesPostGIS -
-
- -
- - -
-
-
SYS_NODE: VALIDATOR_02
-
-
-
-

Cadastral Intelligence Engine

-

Automated LADM-COL V3 validator. Detecting overlaps, slivers, and - topological inconsistencies using high-fidelity Python kernels.

-
- FastAPIShapelyTopology -
-
- -
- - -
-
-
SYS_NODE: PIPELINE_03
-
-
-
-

Sovereign Data Pipelines

-

Unattended ETL architecture for massive geospatial ingestion, - ensuring data integrity across distributed GIS nodes.

-
- GDAL/OGRETLCI/CD -
-
- -
-
-
-
- - -
- -
-
-
- - -
-
- -

GeoAI Intelligence

- -
-
-

Urban Change Detection
con Imagenería Sentinel

-

Aplicación de inteligencia artificial geoespacial para detectar - cambios de cobertura urbana y - rural comparando imágenes satelitales multitemporales. Pipeline completo desde descarga - Sentinel hasta exportación GeoJSON.

- -
-
-
01
-
-

Descarga Imagenería Sentinel-2

-

API Copernicus // Bandas espectrales B04, B08, B11 - // resolución 10m

-
-
-
-
02
-
-

Procesamiento con Rasterio + GeoPandas

-

Normalización radiométrica // Comparación - multitemporal // NumPy arrays

-
-
-
-
03
-
-

Clasificación con Scikit-learn

-

Random Forest // Detección de cambios // - Vectorización de polígonos

-
-
-
-
04
-
-

Exportación GeoJSON → Web GIS

-

Visualización en MapLibre GL // Integración PostGIS - // API REST

-
-
-
- -
- Rasterio - GeoPandas - NumPy - Scikit-learn - Sentinel-2 - Shapely -
-
- -
-
[CHANGE_DETECTION_ENGINE] STATUS: - PROCESSING_DEMO
-
-
-
-
-
-
-
94%
-
Accuracy
-
-
-
2.3km²
-
Area Detected
-
-
-
847
-
Polygons
-
-
-
- >>> SENTINEL_BAND: B08+B04+B11
- >>> DATE_COMPARISON: 2023-01-15 vs 2025-01-15
- >>> CHANGE_PIXELS_DETECTED: RED = URBAN_EXPANSION
- >>> STABLE_PIXELS: GREEN = NO_CHANGE -
-
-
-
-
- - -
-
-
Arquitectura de - Sistemas
-

Ecosistema Territorial

-

- Arquitectura integral para la gestión de datos espaciales a gran escala, desde la captura masiva en - campo hasta la analítica avanzada en la nube. -

- -
-
-
-

Captura de Campo

-

Sistemas GNSS RTK, levantamientos 360° y fotogrametría con drones - para alta precisión.

-
- -
-
-

Motor de Validación

-

Algoritmos en Python (GDAL/Shapely) para control de calidad - topológico y normativo LADM-COL.

-
- -
-
-

PostGIS Engine

-

Bases de datos espaciales de alto rendimiento bajo esquema - certificado LADM-COL V3.

-
- -
-
-

Spatial API

-

Microservicios en FastAPI para despliegue de capas, consultas y - telemetría territorial.

-
-
-
-
- - -
-
-
- -
-
Professional Chronology
-

Trayectoria Técnica

-

- +6 años de ingeniería GIS especializada y territorial en los proyectos catastrales y de - infraestructura más complejos de Colombia. -

-
- - -
-
-
2025 Q4 — Actual
-

Analista Geográfico

-
GEOGRAFÍA SATELITAL GEOSAT S.A.S. // Medellín
-

Procesamiento geoespacial avanzado, análisis de - insumos 360° y restitución vectorial. Digitalización masiva para actualización catastral - con validación topográfica bajo LADM-COL V3.

-
LADM-COL V3360° - SurveyPyQGISRestitución
-
- -
-
2025 Q2
-

Control de Calidad Catastral (QA/QC)

-
ACCION DEL CAUCA S.A.S. // Solita, Caquetá
-

Auditoría técnica de calidad para reconocimiento - predial masivo. Control de estándares IGAC, consistencia topográfica y validación de - reportes técnicos de campo.

-
IGAC QAAuditTopología
-
- -
-
2024 — 2025
-

Coordinador & Líder de Campo SIG

-
ARBIRTRIUM S.A.S. // Urabá, Antioquia
-

Liderazgo de cuadrillas de campo para nivelación - topográfica urbana/rural y barrido predial masivo. Coordinación SIG para misiones - catastrales en terrenos complejos.

-
Barrido - PredialCoordinaciónQGISGPS RTK
-
- -
-
2024 — Actual
-

Coordinador Profesional SIG

-
UT SMART CITY // Barranquilla
-

Implementación de estándares LADM-COL y - digitalización masiva para el despliegue de ciudades inteligentes. Aseguramiento de - calidad en nodos distribuidos.

-
LADM-COLSmart CityMass Digit. -
-
- -
-
2021 — 2022
-

Digitalizador / Topógrafo

-
CINTELI / Consorcio Vial BAQ // Barranquilla
-

Levantamientos topográficos viales y - digitalización SIG para proyectos de infraestructura. Operación de sistemas GPS y - producción cartográfica profesional.

-
TopografíaGPSAutoCAD
-
-
-
-
-
- - -
-
-
SPATIAL_INTEL_WORKSTATION_V6
-

Territorial Intelligence - Hub

-

- Full-stack GIS workstation — datos prediales interactivos, capas conmutables e inteligencia de - coordenadas en tiempo real. Explore la infraestructura LADM-COL directamente. -

- -
-
- STATUS: OFFLINE // AWAITING INIT -
- -
- -
- -
-
-
-
- - -
-
- -
-
- - -
- -
- - DGZ_SPATIAL_OS // KERNEL_V6 // LADM-COL -
-
- - - - - -
-
- X: - -75.5812 - Y: - 6.2442 - EPSG: - 4326 -
-
- - -
- - -
-
- - LAYER_MANAGER - -
- -
-
BASEMAP
-
- - - -
-
- -
-
VECTOR_LAYERS
-
- -
- -
- -
-
- -
- -
- -
-
- -
- -
- -
-
- -
- -
- -
-
- -
-
- -
-
LEGEND
-
-
-
- HQ Node — Active -
-
-
- Field Node — Remote -
-
-
- Parcel — Validated -
-
-
- Parcel — Error -
-
-
- Urban Perimeter -
-
-
- -
-
PROJECTION INFO
-
-
CRS: WGS84 EPSG:4326
-
Units: Decimal Degrees
-
Datum: GRS 1980
-
-
-
- - -
-
-
- - -
- -
- -
- - -
-
-
1 km
-
- - - - - - -
- - -
-
- - ATTRIBUTE_TABLE -
- -
-
🗺️
-
- SELECT A FEATURE
TO DISPLAY
ATTRIBUTES -
-
- - - - -
-
LIVE_TELEMETRY
-
- LAT6.2442 -
-
- LNG-75.5812 -
-
- ZOOM13 -
-
- STATUSSYNC_OK ● -
-
- NODES6_ACTIVE -
-
-
- -
- - -
- ● SYSTEM READY — DGZ Territorial Intelligence - v6.0 - | - Features: 6 - | - Protocol: LADM-COL V3 - | - CRS: WGS84 - | - 00:00:00 -
-
-
- - - - -
- - -
-
-
- ENTERPRISE SOLUTIONS -

DGZ Spatial OS Engine

-

El motor de validación catastral más avanzado de Latinoamérica. - Diseñado para interventorías y municipios que exigen precisión absoluta.

-
- -
- -
-
STARTER_CORE
-

Spatial Explorer

-

Para profesionales GIS y técnicos avanzados.

-
- $0 - / month · Forever Free -
-
-
SYSTEM ALLOCATION
-
-
-
-
-
    -
  • Validación topográfica básica
  • -
  • Hasta 5,000 predios por capa
  • -
  • Visor GIS interactivo
  • -
- Comenzar Gratis -
- - - - - -
-
GOVERNMENT_NODE
-

Sovereign Tier

-

Para Oficinas de Catastro y Alcaldías.

-
- Custom -
-
-
SYSTEM ALLOCATION
-
-
-
-
-
    -
  • Despliegue On-Premises
  • -
  • Integración SGDEA / Rentas
  • -
  • Capacitación presencial
  • -
- Contactar Arquitecto -
-
-
-
- - -
-
-
- CLOUD ARCHITECTURE -

Professional Cloud Stack

-

Infraestructura de alto rendimiento para el despliegue de sistemas - territoriales soberanos y microservicios geoespaciales.

-
- - - -
-
PRO-TIP
-

Repotencialización Scalable (Free Tier)

-

- Para proyectos de alto impacto con presupuesto inicial optimizado, recomendamos la combinación - de Neon DB (PostgreSQL + PostGIS serverless) y Supabase para - autenticación y almacenamiento. Despliegue en Vercel para un frontend - ultrarrápido y use Cloudflare para protección de borde. Todo disponible en - capas gratuitas generosas para potenciar su MVP GIS. -

-
-
-
- - -
-
-
- INICIAR PROYECTO -

Territorial Intelligence Hub

-

Hablemos de su proyecto, municipio o desafío GIS empresarial.

-
- -
-
-

Hablemos de su
próximo proyecto.

-

Inteligencia territorial de próxima generación - para infraestructura crítica.

- - -
- -
-
-
- - -
-
- - -
-
- - -
-
- - -
- -
-
-
-
-
- - - -
- - - -
- - -
-
- -
- - - - - - \ No newline at end of file diff --git a/lab/geoai.html b/lab/geoai.html deleted file mode 100644 index f305c27..0000000 --- a/lab/geoai.html +++ /dev/null @@ -1,833 +0,0 @@ - - - - - - GeoAI Change Detection Node | DGZ Spatial OS - - - - - - - - - -
-
- - - - -
- - -
-
-
SYSTEM_ID: GEO_AI_NODE_01
-

GeoAI Urban Growth
Analysis Engine

-

Deep learning inference applied to multitemporal Sentinel-2 imagery. Our neural engine detects topological mutations and urban expansion patterns with high-fidelity classification accuracy.

- -
- 96.4% - Classification
Accuracy
-
- -
-
-
- Sentinel-2 Band Ingestion [B04, B08, B11] -
-
-
- Radiometric Normalization & Reprojection -
-
-
- Scikit-Learn Random Forest Classification -
-
-
- Raster-to-Vector (OpenCV + Shapely) -
-
-
- PostGIS → GeoJSON Export → Web GIS -
-
-
- -
-
[GEOAI_ENGINE] SYSTEM_LOG // ACTIVE
-
[OK] Copernicus API Connection: ESTABLISHED
-
[OK] Sentinel-2 L2A Tiles: LOADED (12 tiles)
-
[OK] Band Stack B04+B08+B11: NORMALIZED
-
[RUN] Temporal Delta Analysis: PROCESSING
-
[FLAG] Change Pixels Detected: 2,341
-
[OUT] Vector Export: ./output/changes.geojson
-
[OK] PostGIS Insert: 847 polygons → SUCCESS
-
>>> KERNEL: 0x8F3A92B // PROTOCOL: LADM-COL_SYNC
-
-
- - -
-
-
-

Change Detection: Medellín Area

-
TEMPORAL_DELTA: 2020-01-15 vs 2024-01-15 // RESOLUTION: 10m/px
-
-
-
- INFERENCE_LIVE -
-
- -
- - - -
-
-
- -
-
- -
- BASELINE: 2020 - INFERENCE: 2024 -
-
- - -
-
-
2.3km²
-
Area Changed
-
-
-
847
-
Polygons Detected
-
-
-
23.4%
-
Urban Expansion
-
-
-
12 tiles
-
Sentinel-2 AOI
-
-
-
- - -
-
-
-

Neural Segmentation

-

U-Net architecture optimized for high-resolution cadastral boundaries and spectral signature differentiation across multitemporal stacks.

-
- Scikit-Learn - NumPy - OpenCV -
-
-
-
-

Sentinel-2 Sync

-

Automated ingestion of ESA Copernicus data for continuous monitoring of informal urban settlements with 10m pixel resolution.

-
- Rasterio - GeoPandas - Copernicus API -
-
-
-
-

Topological Fusion

-

Raster-to-vector transformation using OpenCV and PostGIS to create validated cadastral mutation records under LADM-COL V3.

-
- PostGIS - Shapely - LADM-COL -
-
-
- - - - -
- - - - diff --git a/lab/gesture_sandbox.html b/lab/gesture_sandbox.html deleted file mode 100644 index 09683aa..0000000 --- a/lab/gesture_sandbox.html +++ /dev/null @@ -1,514 +0,0 @@ - - - - - - - DGZ Spatial OS — Gestures Sandbox (Free Trial) - - - - - - - - - - - - - - - - - - - - - - -
- - -
- - -
- - -
-
- - Volver a Validator - - - - DGZ - - VISION - Free Trial Sandbox -
-
- - -
- -
-

Usa la cámara frontal de tu dispositivo para controlar el módulo sin tocar la pantalla.

-
    -
  • Índice: Mover Cursor
  • -
  • Pinza: Arrastrar/Clic Espacial
  • -
  • Paz: Acercar Zoom (+)
  • -
  • Cinco Dedos: Alejar Zoom (-)
  • -
  • Puño: Resetear Vista
  • -
-
-
- - -
-
- -
- - -
-
- -
- -
- - - -
-
-
- - -
-
- OBJETO ESPACIAL - ID: 000 -
-
-
- - -
-
- Óptica Geométrica - STANDBY - Esperando Input... -
-
- - - -
-
- -
- - - - - - diff --git a/lab/map.html b/lab/map.html deleted file mode 100644 index fffba93..0000000 --- a/lab/map.html +++ /dev/null @@ -1,1135 +0,0 @@ - - - - - - - DGZ Spatial Lab — Cadastral Viewer | DevGiz - - - - - - - - - - - - - - - - - - -
- - -
- -
-
Map Layers
-
-
-
-
- Predios Catastrales -
-
-
-
-
-
- Red Vial -
-
-
-
-
-
- Límite Urbano -
-
-
-
-
-
-
- Etiquetas -
-
-
-
-
- - -
-
Base Map
-
-
- VOID
DARK
-
-
- GEO
SAT
-
-
- TOPO
MAP
-
-
-
- - -
-
Leyenda
-
-
-
- Predio Validado -
-
-
- En Proceso -
-
-
- Error Topológico -
-
-
- Sin Clasificar -
-
-
- - -
-
Información Predial
-
-
🖱️
-
Click en un predio
para ver atributos -
-
-
-
- NPU - -
-
- Área (m²) - -
-
- Uso Suelo - -
-
- Estrato - -
-
- Estado - -
-
- Municipio - -
-
-
-
- - -
-
- - -
-
-
[SPATIAL_INTEL]
-
LATITUDE6.2442°N
-
LONGITUDE75.5812°W
-
ZOOM14.0
-
CRSWGS84
-
-
-
[DATASET_STATUS]
-
PREDIOS0 -
-
VALID0
-
ERRORS0
-
STATUSSYNC_OK
-
-
- - -
-
🏠
-
📡
-
-
-
-
- - -
-
DGZ_SPATIAL_LAB_V1.0
-
ENGINE: MAPLIBRE_GL_4.1
-
SCHEMA: LADM-COL_v2
-
FEATURES:
-
CURSOR:
-
-
© 2026 DevGiz
-
- - - - - \ No newline at end of file diff --git a/lab/validator.html b/lab/validator.html deleted file mode 100644 index 6c3f5f4..0000000 --- a/lab/validator.html +++ /dev/null @@ -1,1231 +0,0 @@ - - - - - - - DGZ Spatial OS — Catastral Intelligence Command Center - - - - - - - - - - - - - - - - - - -
- - -
-
- -

SECURE CLEARANCE

-

- Estás intentando acceder al Sistema Operativo DGZ Spatial. Requiere identificación de contratista autorizada - para procesar geometría topológica LADM. -

- - - -
- DGZ ENGINE ACCESS NODE v2.0 -
-
-
- - -
-
- Hub - - - DGZ - - DGZ - Spatial OS - V2.0 LADM -
-
-
00:00:00
-
- - API CONNECTED -
-
- Groq Llama-3 Active -
-
- Av - User - -
-
-
- - -
- - - - -
- - -
-
-

LADM-COL QA/QC

-

Validación topológica estricta sobre cartografía base. - Detecta superposiciones, slivers y completitud alfanumérica geométrica.

-
- -
-
-
- - -
Carga Vectorial (Cartografía)
-
.ZIP (Shapefile), .GPKG, .KML, .GEOJSON
- -
-
- - - -
-
-
- [1] Parseando Nodos GeoPandas
[2] Consultando Geo-LLM Proxy... -
-
- - -
-
- - -
-
-

Cruce Físico-Jurídico

-

Sincronización de Base de Datos Catastral (.shp/.gpkg) vs - Matriz de SNR Registro (.xlsx) para detectar inconsistencias de área e identificador.

-
- -
-
-
- - -
1. Base Cartográfica
- -
- -
- - -
2. Matriz Registral (SNR/Rentas)
-
.XLSX, .CSV (Requiere col: NPU)
- -
-
- - - -
- Módulo en construcción en el Backend. Al presionar, simulará la lógica. -
- -
-
- - -
-
-

Command - Center

-

Visualización agregada de la salud cartográfica en tiempo real. Métricas de eficiencia - y tipos de errores recurrentes.

-
-
-
-
-
0
-
Predios Validados Acumulados
-
-
-
- 0
-
Errores LADM Detectados
-
-
- -
- -
-
-
-
- - -
-
- - - - - -
- - -
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/projects/automation-systems/index.html b/projects/automation-systems/index.html deleted file mode 100644 index a4274bb..0000000 --- a/projects/automation-systems/index.html +++ /dev/null @@ -1,90 +0,0 @@ - - - - - Spatial ETL Automation | DevGiz - - - - - -
-
- PROJECTS_HUB - -
// SYSTEM_ID: ETL_AUTOMATION_02 // STATUS: LIVE // ZERO_COST_ARCH
-

Spatial ETL
Automation Pipeline

-

Unattended geospatial data processing engine — from raw field capture to validated PostGIS records with zero manual intervention. LADM-COL V3 compliant by design.

- -
-
-
📡
Field Input
KML // GeoJSON // XLS
-
-
🐍
Python Engine
GDAL // Shapely // pandas
-
-
🔍
QA/QC
Topology // Overlaps // LADM
-
-
🗄️
PostGIS
Spatial DB // LADM-COL
-
-
🌐
Web GIS
FastAPI // MapLibre
-
-
- -
-
01
Ingest — Multi-Format Input
Watches a directory for KML, GeoJSON, Shapefile, DXF, or Excel inputs. Automatically detects format and normalizes to WGS84.
-
02
Transform — GDAL/OGR + GeoPandas
Reprojects, clips to study area, joins attribute tables, and applies LADM-COL V3 schema enforcing required fields.
-
03
Validate — Shapely Topology Engine
Detects overlaps, gaps, slivers, invalid geometries, and attribute completeness violations. Flags errors with severity codes.
-
04
Load — PostGIS + Audit Log
Clean features inserted into PostgreSQL/PostGIS with full audit trail: timestamp, source file, user, validation score, and spatial index.
-
- -
-
⚙️
Zero Config
Drop files in folder — pipeline triggers automatically. No GUI needed.
-
🔍
Topology QA
Overlap & gap detection using Shapely. LADM-COL V3 schema enforcement.
-
📋
Audit Logging
Full transaction history per record — timestamp, source, validation result.
-
🔄
Multi-Format
KML, GeoJSON, SHP, DXF, XLS unified into one PostGIS LADM schema.
-
- - - - \ No newline at end of file diff --git a/projects/geo-llm/index.html b/projects/geo-llm/index.html deleted file mode 100644 index 221fafe..0000000 --- a/projects/geo-llm/index.html +++ /dev/null @@ -1,91 +0,0 @@ - - - - - GeoLLM Intelligence Node | DevGiz - - - - - -
-
- PROJECTS_HUB - -
BETA
-
// SYSTEM_ID: GEOLLM_03 // NATURAL_LANGUAGE_GIS
-

GeoLLM
Intelligence Node

-

Ask your GIS database questions in plain language — English or Spanish — and get instant spatial results. No SQL needed. Powered by LLM + PostGIS function calling architecture.

- -
-
GEOLLM_DEMO_SESSION // SIMULATED_INTERACTION
-
-
USER_QUERY
- Show all cadastral parcels with topology errors in zone Norte where area is less than 500m² -
-
-
GEOLLM_RESPONSE
- >>> PARSING_QUERY...
- >>> GENERATING SQL: SELECT * FROM predios WHERE zona='NORTE' AND area_m2 < 500 AND has_topology_error = TRUE;
- >>> FETCHING... 23 records found.
- >>> RENDERING map layer: "TOPOLOGY_ERRORS_NORTE_ZONE"
- >>> EXPORT options: GeoJSON | CSV | PostGIS view -
-
-
USER_QUERY
- ¿Cuántos predios en Barranquilla tienen matrícula SNR sin validar? -
-
-
GEOLLM_RESPONSE
- >>> IDIOMA_DETECTADO: Español
- >>> QUERY: SELECT COUNT(*) FROM predios WHERE municipio='Barranquilla' AND snr_validated = FALSE;
- >>> RESULTADO: 1,847 predios sin validación SNR.
- >>> ACCIÓN_SUGERIDA: Ejecutar batch_snr_validation_pipeline.py -
-
- -
-
🧠
NL to SQL
Converts natural language queries to optimized PostGIS SQL using LLM function calling.
-
🌐
Bilingual
Full Spanish and English support — answers in the same language you asked.
-
🗺️
Map Output
Query results rendered directly on interactive MapLibre GL map with styled layers.
-
🔒
Secure
Read-only query mode. No destructive operations. RBAC per user role.
-
- - - - \ No newline at end of file diff --git a/projects/gis-dashboard/index.html b/projects/gis-dashboard/index.html deleted file mode 100644 index 225cc6f..0000000 --- a/projects/gis-dashboard/index.html +++ /dev/null @@ -1,95 +0,0 @@ - - - - - Enterprise GIS Dashboard | DevGiz - - - - - -
-
- PROJECTS_HUB - -
// SYSTEM_ID: GIS_DASHBOARD_01 // STATUS: LIVE // POSTGIS + MAPLIBRE
-

Enterprise GIS
Territorial Dashboard

-

Real-time territorial analytics platform for multipurpose cadastre operations. Filter by geographic zone, track SLA compliance, monitor field team progress, and visualize topology errors on an interactive map.

- - -
-
ZONE_FILTER_DEMO // CLICK TO SIMULATE
-
-
NORTE
-
CENTRO
-
SUR
-
ORIENTE
-
-
-
12,450
Parcels
-
94%
SLA Compliance
-
3
Topology Errors
-
1.2k
Processed Today
-
-
- -
-
🗺️
Live Map
Vector tile rendering with real-time parcel status overlays and clickable attribute inspection.
-
📊
Zone Analytics
Filter by Norte, Centro, Sur, Oriente with instant animated chart transitions.
-
⚠️
SLA Alerts
Automated threshold alerts for bottlenecks and deadline overruns with severity levels.
-
👤
Field Teams
Track operator progress, assign parcels, and monitor daily production targets in real time.
-
- - - - - - diff --git a/projects/index.html b/projects/index.html deleted file mode 100644 index 3786966..0000000 --- a/projects/index.html +++ /dev/null @@ -1,281 +0,0 @@ - - - - - - DGZ Projects Hub | Spatial Engineering Deployments - - - - - - - -
-
-
- - - -
-
// FLAGSHIP_ASSETS // ACTIVE_DEPLOYMENTS
-

Technical
Deployments.

-

Enterprise-grade geospatial systems — from LADM-COL automation to GeoAI and Smart City platforms. Each project is production-ready and battle-tested.

-
-
-
5+
-
Active Systems
-
-
-
50k+
-
Parcels Processed
-
-
-
LADM-COL
-
Certified Standard
-
-
-
- -
- - - -
SYSTEM_ID: GIS_DASHBOARD_01
-
🗺️
-
LIVE
-

Enterprise GIS Dashboard

-

Real-time territorial analytics platform — filterable by geographic zone, with dynamic chart updates, SLA monitoring, and spatial workflow orchestration.

-
- MapLibre GL - PostGIS - Chart.js - FastAPI -
-
EXECUTE_DASHBOARD
-
- - - -
SYSTEM_ID: ETL_AUTOMATION_02
-
⚙️
-
LIVE
-

Spatial ETL Automation

-

Unattended pipeline system for massive GeoJSON/KML ingestion, LADM-COL topology validation, overlap detection, and automated PostgreSQL sync without human intervention.

-
- Python - GDAL/OGR - Shapely - GeoPandas -
-
EXECUTE_PIPELINE
-
- - - -
SYSTEM_ID: GEOLLM_03
-
🧠
-
BETA
-

GeoLLM Intelligence Node

-

Natural language interface for territorial data — query your GIS database in plain language. Ask "Show all parcels with topology errors in zone B" and get an instant map response.

-
- LLM API - LangChain - PostGIS - FastAPI -
-
EXECUTE_GEOLLM
-
- - - -
SYSTEM_ID: QGIS_PLUGIN_04
-
🔌
-
BETA
-

PyQGIS LADM-COL Plugin

-

Custom QGIS plugin automating LADM-COL V3 compliance checks, batch parcel renaming, coordinate transformation, and direct PostGIS export with topological validation built-in.

-
- PyQGIS - LADM-COL V3 - PyQt5 - PostGIS -
-
VIEW_PLUGIN
-
- - - -
SYSTEM_ID: RESEARCH_05
-
🔬
-
RESEARCH
-

GeoAI Research Lab

-

Applied GeoAI research — Sentinel-2 change detection, Random Forest land cover classification, urban growth modeling, and machine learning applied to cadastral quality prediction.

-
- Rasterio - Scikit-learn - NumPy - Sentinel-2 -
-
VIEW_RESEARCH
-
- -
- - diff --git a/projects/qgis-plugin/index.html b/projects/qgis-plugin/index.html deleted file mode 100644 index 4472a9b..0000000 --- a/projects/qgis-plugin/index.html +++ /dev/null @@ -1,88 +0,0 @@ - - - - - PyQGIS LADM-COL Plugin | DevGiz - - - - - -
-
- PROJECTS_HUB - -
// SYSTEM_ID: QGIS_PLUGIN_04 // STATUS: BETA // PYQGIS_3.x
-

PyQGIS LADM-COL
Automation Plugin

-

Custom QGIS plugin that automates LADM-COL V3 cadastral compliance. Batch parcel renaming, coordinate transformation, topology QA, and direct PostGIS export — all in one toolbar click.

- -
-
PLUGIN_CORE_SNIPPET // ladm_col_validator.py
- from qgis.core import QgsProject, QgsVectorLayer
- from shapely.geometry import shape
- import geopandas as gpd

- class LadmColValidator:
-     def run_full_validation(self, layer: QgsVectorLayer):
-         # 1. Export to GeoDataFrame
-         gdf = gpd.GeoDataFrame.from_qgis(layer)
-         # 2. Validate LADM-COL V3 required fields
-         errors = self.check_schema(gdf, schema="LADM_COL_V3")
-         # 3. Topology check — overlaps & gaps
-         topology_errors = self.check_topology(gdf)
-         # 4. Write to PostGIS if no critical errors
-         if not topology_errors.critical:
-             self.export_postgis(gdf, table="predios_ladm") -
- -
-
🔌
One-Click QA
Full LADM-COL V3 validation with a single toolbar button. Results appear as styled QGIS layer.
-
🏷️
Batch Rename
Auto-rename predios to IGAC convention based on municipality code + sequential numbering.
-
🗄️
PostGIS Export
Validated features pushed directly to PostGIS with spatial index and audit log entry.
-
🌐
CRS Enforcer
Automatically reprojects any layer to EPSG:4326 / Magna-Sirgas as required by IGAC.
-
- -
-
INSTALLATION // QGIS_PLUGIN_MANAGER
- 1. Open QGIS → Plugins → Manage and Install Plugins
- 2. Search: DGZ_LADM_COL_Validator
- 3. Install → Restart QGIS
- 4. DGZ toolbar appears automatically in GIS panel -
- - - - \ No newline at end of file diff --git a/projects/research/index.html b/projects/research/index.html deleted file mode 100644 index 5d45443..0000000 --- a/projects/research/index.html +++ /dev/null @@ -1,94 +0,0 @@ - - - - - GeoAI Research Lab | DevGiz - - - - - -
-
- PROJECTS_HUB - -
// SYSTEM_ID: RESEARCH_05 // STATUS: ACTIVE_RESEARCH // SENTINEL-2
-

GeoAI
Research Lab

-

Applied artificial intelligence for territorial analysis — Sentinel-2 satellite change detection, machine learning land cover classification, and predictive models for cadastral quality scoring.

- -
-
94%
Detection Accuracy
-
2.3km²
Urban Change Detected
-
847
Polygons Vectorized
-
10m
Spatial Resolution
-
- -
-
-
01
-
Urban Change Detection
-
Multitemporal Sentinel-2 imagery analysis comparing 2020 vs 2025. Random Forest classifier trained on labeled urban expansion samples from IGAC datasets.
-
Sentinel-2RasterioScikit-learnNumPy
-
-
-
02
-
Cadastral Quality ML Predictor
-
Gradient Boosting model predicting topological error probability in predios based on neighborhood, area, shape index, and historical QA results. Achieves 89% precision.
-
XGBoostPostGISGeoPandasSHAP
-
-
-
03
-
Land Cover Classification
-
4-class supervised classification (urban, vegetation, water, bare soil) over Medellín metropolitan area using spectral indices NDVI, NDWI, MNDWI from Sentinel-2 bands.
-
NDVIRandom ForestShapelyGDAL
-
-
-
04
-
Drone + Satellite Fusion
-
Integration of centimeter-resolution drone orthophotos with 10m Sentinel data for hybrid cadastral update workflows. Reduces field verification trips by ~60%.
-
AgisoftOpenDroneMapRasterioQGIS
-
-
- - - - \ No newline at end of file diff --git a/stitch_temp/stitch/dgz_home_hub_de_ingenier_a_2026/code.html b/stitch_temp/stitch/dgz_home_hub_de_ingenier_a_2026/code.html deleted file mode 100644 index fd51195..0000000 --- a/stitch_temp/stitch/dgz_home_hub_de_ingenier_a_2026/code.html +++ /dev/null @@ -1,295 +0,0 @@ - - - - - - - - - - - - - - -
-
-
-
-
- -
-
-
-
-precision_manufacturing -
-

DGZENGINEERING

-
- -
- -
-
-
-
- -
-
-
-
- - - - -Certified ABB Technical Partner -
-

- MAXIMIZING
INDUSTRIAL
UPTIME. -

-

- Operational excellence through premium engineering. We deliver technical solutions for decision makers who demand efficiency and sustainable growth. -

-
- -
-
-
99.9%
-
System Reliability
-
-
-
-
-
-
-
- -
-Live Operations Feed -
-
-
-
-
-
-
-
- -
-
-
-
-

Core Philosophy

-

The intersection of
Power & Intelligence.

-
-
-

- "At DGZ, we merge deep engineering expertise with Green UX principles, ensuring that industrial systems are not just powerful, but intuitive and environmentally conscious." -

-
-
-eco -

Green UX

-

Reducing cognitive load and energy consumption through interface design.

-
-
-bolt -

Uptime Focus

-

Predictive maintenance cycles that prevent costly downtime.

-
-
-precision_manufacturing -

ABB Integration

-

World-class hardware meets custom-engineered software.

-
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
Success Case
-
Global Logistics Terminal
-
-
- +22% Throughput -
-
-
-
-
-
-
-

Specialization

-

PORT
AUTOMATION

-

- Leveraging ABB's cutting-edge technology, we transform maritime infrastructure into semi-autonomous logistical hubs. Our solutions prioritize safety, speed, and real-time visibility. -

-
    -
  • check_circle Crane Control Systems
  • -
  • check_circle Terminal Operation Optimization
  • -
  • check_circle Automated Horizontal Transport
  • -
-
-
-
-
-
- -
-
-
-
-

Strategic Footprint

-

Rosario, Argentina

-

- Positioned at the heart of South America's industrial hub, our Rosario office serves as the regional engineering powerhouse, bridging local operational needs with global standards. -

-
-
-location_on -
-
Regional HQ
-
Distrito Puerto, Rosario
-
-
-
-headset_mic -
-
24/7 Field Service
-
Supporting Southern Cone Operations
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-Global Sites -120+ -
-
-
-CO2 Saved -14% -
-
-
-ABB Certs -Platinum -
-
-
-Active Assets -24/7 -
-
-
-
-
- - \ No newline at end of file diff --git a/stitch_temp/stitch/dgz_home_hub_de_ingenier_a_2026/screen.png b/stitch_temp/stitch/dgz_home_hub_de_ingenier_a_2026/screen.png deleted file mode 100644 index cf92f9a..0000000 Binary files a/stitch_temp/stitch/dgz_home_hub_de_ingenier_a_2026/screen.png and /dev/null differ diff --git a/stitch_temp/stitch/especializaci_n_automatizaci_n_portuaria/code.html b/stitch_temp/stitch/especializaci_n_automatizaci_n_portuaria/code.html deleted file mode 100644 index f94bed0..0000000 --- a/stitch_temp/stitch/especializaci_n_automatizaci_n_portuaria/code.html +++ /dev/null @@ -1,302 +0,0 @@ - - - - - - - - - - - - - -
- -
-
-
-
-precision_manufacturing -
-DevGiz -
- -
- - -
-
-
-
- -
-
-
-
- - - - - ABB Certified Partner -
-

- Advanced Crane Commissioning -

-

- Driving port efficiency across Mexico and Panama through high-precision STS and ASC automation. Leveraging ABB industrial frameworks for seamless terminal logistics. -

-
- - -
-
-
-
-
-
-
-
-analytics -Live System Monitoring: Active -
-
-
-
-
-
- -
-
-
-12+ -Regional Ports -
-
-45+ -ASC Systems -
-
-99.9% -System Uptime -
-
-300ms -Latent Response -
-
-
- -
-
-
-
-

Engineering Excellence

-

Terminal Operating System
(TOS) Integration

-
-

We provide end-to-end commissioning for high-tier ABB automation hardware and software stacks.

-
-
- -
-
-settings_input_component -
-

STS Crane Precision

-

Expert laser-guided positioning and anti-sway logic implementation for Ship-to-Shore cranes.

-
    -
  • check_circle ABB ACS880 Drive Suites
  • -
  • check_circle Dynamic Load Sensing
  • -
-
- -
-
-hub -
-

ASC Flow Optimization

-

Automated Stacking Crane logic design for streamlined yard logistics and collision avoidance.

-
    -
  • check_circle Multi-Crane Coordination
  • -
  • check_circle Optimized Pathfinding
  • -
-
- -
-
-memory -
-

PLC & Drive Commissioning

-

Full lifecycle commissioning of ABB PLC systems and industrial drives for extreme port environments.

-
    -
  • check_circle Real-time Telemetry
  • -
  • check_circle Remote Diagnostics
  • -
-
-
-
-
- -
-
-
-
-public -
-
-

Pan-Regional Presence

-

Specialized support for Mexico's Lázaro Cárdenas and Veracruz ports, and Panama's strategic Colon and Balboa terminals.

-
-
-
Mexico Operations
-

Full field service engineering & logistics support in Manzanillo.

-
-
-
Panama Operations
-

Strategic hub for Canal-side automated terminal commissioning.

-
-
-
-
-
-
-
-
-location_on -Active Field Service -
-
-
-
-
- -
-
-
-

Automation Logic Flow

-

The commissioning cycle of a DGZ-engineered STS crane.

-
-
- -
-
01
-
Hardware Integration
-
-
-
02
-
ABB Drive Setup
-
-
-
03
-
Logic Validation
-
-
-
04
-
Full Autonomy
-
-
-
-
- -
-
-
-

Secure Your Port’s
Technical Future

-

Connect with our senior engineering team for a full system evaluation and ABB-aligned automation roadmap.

-
- - -
-
-
-
- -
-
-
-
-
-precision_manufacturing -
-DevGiz -
-

- Leading terminal automation partner specializing in ABB-driven crane commissioning for global logistics hubs in the Americas. -

-
-
-
Offices
-
    -
  • Mexico City, MX
  • -
  • Panama City, PA
  • -
  • Houston, TX (HQ)
  • -
-
-
-
Compliance
-
    -
  • ISO 9001:2015
  • -
  • ABB Partner Portal
  • -
  • Site Safety Protocols
  • -
-
-
-
-

© 2024 DevGiz. Industrial Automation Systems.

- -
-
-
- \ No newline at end of file diff --git a/stitch_temp/stitch/especializaci_n_automatizaci_n_portuaria/screen.png b/stitch_temp/stitch/especializaci_n_automatizaci_n_portuaria/screen.png deleted file mode 100644 index cc5475e..0000000 Binary files a/stitch_temp/stitch/especializaci_n_automatizaci_n_portuaria/screen.png and /dev/null differ diff --git a/stitch_temp/stitch/matriz_de_ingenier_a_y_servicios/code.html b/stitch_temp/stitch/matriz_de_ingenier_a_y_servicios/code.html deleted file mode 100644 index ebe5635..0000000 --- a/stitch_temp/stitch/matriz_de_ingenier_a_y_servicios/code.html +++ /dev/null @@ -1,359 +0,0 @@ - - - - - - - - - - -Engineering Matrix | DevGiz - - -
- -
-
-
-
- - - -
-

DGZ Engineering

-
- -
-
- -
- -
-
-
-
-
- - - -
- -
-
-Engineering Matrix -/ -Technical Repository -
-
-
-

Engineering Matrix Screen

-

High-fidelity technical specifications with cross-functional synchronization and real-time telemetry.

-
-
- - -
-
- -
-
-
-

Active Nodes

-hub -
-

1,248

-
-trending_up -+12.4% -
-
-
-
-

Compliance

-verified -
-

99.92%

-
-trending_flat -Stable -
-
-
-
-

System Latency

-speed -
-

14ms

-
-arrow_downward --2ms -
-
-
-
-

Integrity

-security -
-

Verified

-
-SHA-256 Validated -
-
-
- -
-
-

-database - Technical Repository Detail -

-
- - - -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Ref IDModule / ServiceSpecification NodeDynamic ValueToleranceStatusActions
PRC-402 -
-Process -Hydro-Static Flow Control -
-
FlowRate_α_04124.5 m³/h±0.005 -Optimal - - -
MEC-119 -
-Mechanical -Torque Vector Analysis -
-
Shaft_Rotation_Deg4,500 RPM±12.0 -Warning - - -
SAF-001 -
-Safety -Atmospheric Monitoring -
-
O2_Saturation_Level20.9%±0.02 -Optimal - - -
CIV-882 -
-Civil -Foundation Stress Load -
-
Concrete_PSI_Val6,500 PSI±50.0 -Certified - - -
QAC-092 -
-QA/QC -Batch Consistency Audit -
-
Spec_Conformance_Idx0.998±0.001 -Verified - - -
-
-
-

Displaying 5 of 128 dynamic parameters

-
- - -
-
-
- -
-
- -
-
-

Connected Stack Philosophy

-

- Engineering data isn't just numbers; it's the heartbeat of the infrastructure. Our Connected Stack integrates real-time telemetry from site sensors directly into your technical repository, ensuring zero-latency decision making. -

-
-
-

Site Integration

-

API ACTIVE

-
-
-

Data Flow

-

BIDIRECTIONAL

-
-
-

Validation

-

AUTOMATED

-
-
-

Encryption

-

AES-256

-
-
-
-
-
-
-map -
-
-

Regional Deployment

-

Global Cluster Nodes Active

-
-
-Global satellite technical map display -
-
-
-
-
-
-
- \ No newline at end of file diff --git a/stitch_temp/stitch/matriz_de_ingenier_a_y_servicios/screen.png b/stitch_temp/stitch/matriz_de_ingenier_a_y_servicios/screen.png deleted file mode 100644 index 978c8bc..0000000 Binary files a/stitch_temp/stitch/matriz_de_ingenier_a_y_servicios/screen.png and /dev/null differ diff --git a/stitch_temp/stitch/panel_de_control_del_proyecto/code.html b/stitch_temp/stitch/panel_de_control_del_proyecto/code.html deleted file mode 100644 index e6a0bf6..0000000 --- a/stitch_temp/stitch/panel_de_control_del_proyecto/code.html +++ /dev/null @@ -1,339 +0,0 @@ - - - - - -DevGiz | Project Management Dashboard - - - - - - - - -
- -
-
-
- -
-

Project Hyperion

-ID: DGZ-2024-X9 -
-
-
- -
- - -
-
-
-
-
-
-System Efficiency -bolt -
-
-94.2% -+2.4% -
-
-
-
-
-
-
-Build Milestone -precision_manufacturing -
-
-Phase 3 -of 5 -
-
-
-
-
-
-
-
-
-
-
-Active Components -settings_input_component -
-
-1,402 -Synced -
-
- -TELEMETRY_LINK_STABLE -
-
-
-
-Time to Deploy -timer -
-
-12d 04h -
-
-Deadline: May 24 -On Schedule -
-
-
-
-
-
-
- - -
-
-
-
-
-
-
-token -

Initializing Visualizer Proxy...

-
-
-Lat: 34.0522° N -Lon: 118.2437° W -Alt: 420.5m -
-3D Engineering model placeholder -
-
-
-
-

-folder_open Technical Documentation -

-
-
-
-description -
-

Structural_Analysis_V4.pdf

-

Updated 2h ago • 12.4 MB

-
-
-download -
-
-
-inventory_2 -
-

BOM_Final_Rev.xlsx

-

Updated Yesterday • 4.1 MB

-
-
-download -
-
- -
-
-

-schedule Recent Activity Log -

-
-
-
-
-

Model Synchronized

-

CAD Export #422 completed by Sarah W.

-

09:12 AM

-
-
-
-
-
-

Issue Detected

-

Thermal threshold deviation in Cluster B.

-

07:45 AM

-
-
-
-
-
-

Client Review

-

Feedback received on Phase 2 deliverables.

-

Yesterday

-
-
-
-
-
-
-
-
-

-contact_support Engineer Direct Connect -

-
-
-
- Good morning. The structural stress tests for Phase 3 are showing excellent results. Would you like to review the raw data? -
-James Chen, Lead Engineer • 10:15 AM -
-
-
- Yes, please send the CSV files over. Does this change the timeline? -
-You • 10:22 AM -
-
-
- No changes to the timeline. We are actually 2 days ahead on the fabrication sequence. -
-James Chen • 10:25 AM -
-
-
-New Message Received -
-
-
- -
- - -
-
-
-

Assigned Team

-
-
-Team member -
-
-Team member -
-
-Team member -
-
- +2 -
-
- -
-
-
-
-
-
-
- \ No newline at end of file diff --git a/stitch_temp/stitch/panel_de_control_del_proyecto/screen.png b/stitch_temp/stitch/panel_de_control_del_proyecto/screen.png deleted file mode 100644 index 9cfb34b..0000000 Binary files a/stitch_temp/stitch/panel_de_control_del_proyecto/screen.png and /dev/null differ