╔═══════════════════════════════════════════════════════════════╗
║ ███████╗██████╗ ██████╗ ███╗ ██╗████████╗ ║
║ ██╔════╝██╔══██╗██╔═══██╗████╗ ██║╚══██╔══╝ ║
║ █████╗ ██████╔╝██║ ██║██╔██╗ ██║ ██║ ║
║ ██╔══╝ ██╔══██╗██║ ██║██║╚██╗██║ ██║ ║
║ ██║ ██║ ██║╚██████╔╝██║ ╚████║ ██║ ║
║ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═╝ ║
║ ║
║ 30+ Web Projects · GitHub Pages · Universal Build Engine ║
╚═══════════════════════════════════════════════════════════════╝
30+ web projects deployed to diegonmarcos.github.io via GitHub Pages.
Built with a universal build.sh engine — one engine, per-project build.json config, zero boilerplate.
- A.1 Quick Start
- A.2 Project Map
- A.3 Project Categories
- A.4 Frameworks & Archetypes
- A.5 Analytics
- A.6 Domains & Deployment
- A.7 Code Standards Summary
- B.1 Build System Architecture
- B.2 Build Modules
- B.3 build.json Schema
- B.4 config.json Schema
- B.5 CI/CD Pipeline
- B.6 Per-Project Structure
- B.7 Code Standards Specification
- B.8 Generated Data
- B.9 Dev Server Ports
# Install all dependencies (merged from all 30+ projects)
./build.sh deps
# Build a single project
cd a_Portals/linktree && bash build.sh build
# Dev server with hot reload
cd c_Circus/movies && bash build.sh dev
# Build everything
./build.sh build
# Generate project topology
./build.sh configfront/
├── a_Portals/ Portal & entry-point sites
│ ├── cloud Cloud dashboard (Sass+esbuild)
│ ├── linktree Digital card (Sass+esbuild)
│ ├── linktree_mindmap Digital card variant
│ └── linktree_pixel-world Pixel art card
│
├── b_Profiles/ Work profiles & company sites
│ ├── cv_pdf PDF resume (static copy)
│ ├── cv_web Web resume (Sass+esbuild)
│ ├── landpage Landing page (Sass+tsc)
│ ├── leafy Plant tracker (Sass+tsc)
│ ├── myprofile Portfolio platform (SvelteKit)
│ └── nexus Company site (Sass+esbuild)
│
├── c_Suite/ Tools suite
│ ├── json-vision JSON editor (Vue 3 + Vite)
│ ├── mymail Mail client (static copy)
│ └── suite Browser tools (Sass+esbuild)
│
├── c-MyTools/ Personal tools & apps
│ ├── astro Astronomy viewer (Nuxt)
│ ├── myfeed Feed aggregator (Vue 3)
│ ├── mygames Games collection (SvelteKit)
│ ├── myhealth Health portal (landing page)
│ ├── myhealth-feedyourself Nutrition calculator (Sass+esbuild)
│ ├── myhealth-profile Health profile (static copy)
│ ├── myhealth-tracker Health tracker dashboard
│ ├── mymaps Maps portal (landing page)
│ ├── mymaps-maps Interactive maps (SvelteKit)
│ ├── mymaps-mytrips Travel planner (Vue 3+Vite)
│ ├── mymaps-navigation Strategic maps (SvelteKit+MapLibre)
│ ├── mymovies Movie browser (Vue 3+Vite)
│ ├── mymusic Music library (Vue 3+Vite)
│ ├── myphotos Photo viewer (static copy)
│ └── myphotos-myorkut Social network homage (dark Orkut)
│
├── c_LabTools/ Lab experiments & data tools
│ ├── carto Cartography games (Sass+tsc)
│ ├── central_bank Banking tool (Vite)
│ ├── market_watch Market tracker (Sass+esbuild)
│ └── sailytics Sailing analytics (Sass+esbuild)
│
├── c-Cloud/ Cloud & API documentation
│ ├── api API docs (static Swagger)
│ ├── mcp-api-swagger MCP API documentation
│ └── skills_mcp Skills MCP docs (Sass+esbuild)
│
├── e-Others/ Miscellaneous
│ └── others Python scripts
│
└── e-Root/ Main index — 3D cube navigation (Vite+Sass+TS)
| Category | Folder | Count | Description |
|---|---|---|---|
| Portals | a_Portals/ |
4 | Entry points, dashboards, digital cards |
| Profiles | b_Profiles/ |
6 | CV, portfolio, landing pages, company sites |
| Suite | c_Suite/ |
5 | Integrated tools (JSON editor, analytics, mail, photos) |
| MyTools | c-MyTools/ |
15 | Personal apps (health, maps, movies, music, games, photos) |
| LabTools | c_LabTools/ |
4 | Lab experiments & data tools (carto, finance, sailing) |
| Cloud | c-Cloud/ |
3 | API docs, MCP docs, Swagger UI |
| Others | e-Others/ |
1 | Python scripts, misc |
| Root | e-Root/ |
1 | Main 3D cube index page |
| Archetype | Build Pipeline | Projects |
|---|---|---|
| Vite | Vite HMR + bundler | mymovies, mymusic, json-vision, central_bank, mymaps-mytrips |
| SvelteKit | Vite + SSR | mygames, myprofile, mymaps-navigation, mymaps-maps |
| Vue 3 | Composition API + <script setup> |
myfeed, mymovies, mymusic, mymaps-mytrips, json-vision |
| React | Vite + MapLibre | maps |
| Sass+esbuild | sass → CSS, esbuild → JS | linktree, cv_web, cloud, market_watch, nexus, skills_mcp |
| Sass+tsc | sass → CSS, tsc → JS | carto, landpage, leafy |
| Nuxt | SSR + nuxt.config.ts | astro |
| Static copy | File copy only | cv_pdf, myhealth-profile, mymail, myphotos |
All projects include Matomo tag manager (container_odwLIyPV) and Umami analytics. Both are self-hosted on analytics.diegonmarcos.com.
The tracking snippet is required in every HTML <head>:
<script>
var _mtm = window._mtm = window._mtm || [];
_mtm.push({'mtm.startTime': (new Date().getTime()), 'event': 'mtm.Start'});
(function() {
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src='https://analytics.diegonmarcos.com/matomo/js/container_odwLIyPV.js';
s.parentNode.insertBefore(g,s);
})();
</script>| Domain | Purpose |
|---|---|
| diegonmarcos.github.io | GitHub Pages — all 30+ projects |
| diegonmarcos.com | Main domain (Cloudflare DNS) |
Deployment is automatic — push to main triggers GitHub Actions. Only changed projects rebuild (conditional builds via changed-files action).
- TypeScript: Strict mode, no
any, handlenull/undefined, ES Modules only - Svelte 5: Runes mode —
$props(),$state(),$derived(), standard HTML events - Vue 3:
<script setup lang="ts">,defineProps<{}>(),ref<T>() - SCSS: ITCSS methodology, mixins (
mq(),flex-center,grid-auto-fit). Never inline styles - HTML: Semantic tags,
<a>for navigation,<button>for actions,alton images,<label>on inputs
Full details: Code Practices | Stack Spec
Pattern: Universal engine + declarative config
1_cicd/src/scripts/_engine.sh Universal build engine (SoT, ~65K)
1_cicd/src/scripts/build.sh Root orchestrator (SoT)
build.sh Symlink → 1_cicd/src/scripts/build.sh
config.json Root config (analytics, defaults, system deps)
<project>/build.sh Symlink → ../../1_cicd/src/scripts/_engine.sh
<project>/build.json Per-project declarative config
Engine commands (per-project):
| Command | Action |
|---|---|
build |
Compile src/ → dist/ using build modules |
dev |
Start dev server with hot reload |
stop |
Stop running dev server |
clean |
Remove dist/ and build artifacts |
status |
Show server state from .build.pid |
Root orchestrator commands:
| Command | Action |
|---|---|
deps |
Merge all package.json → root, npm install |
build |
Build all projects |
clean |
Clean all dist/ directories |
config |
Generate front-topology.json (project registry) |
status |
Show all running dev servers |
Each project's build.json declares an ordered pipeline of build modules:
| Module | Input | Output | Purpose |
|---|---|---|---|
esbuild |
.ts |
.js |
Fast TypeScript bundling (IIFE/ESM) |
sass |
.scss |
.css |
ITCSS stylesheet compilation |
copy |
files list | dist/ | Static file copying |
symlink |
directory | dist/ | Symlink public assets (images, fonts) |
inline |
HTML+CSS+JS | single HTML | Inline all assets into one file |
Dev server fallback chain: vite → sveltekit → live-server → node-static → python3 → busybox → php
{
"name": "Project Name",
"framework": "vanilla | vue | svelte | react | nuxt",
"port": 8001,
"src": "src",
"dist": "dist",
"build": [
{ "mod": "esbuild", "input": "src/typescript/main.ts", "output": "script.js", "format": "iife", "target": "es2020" },
{ "mod": "sass", "input": "src/scss/main.scss", "output": "style.css" },
{ "mod": "copy", "files": "index.html", "from": "src" },
{ "mod": "symlink", "files": "public" }
],
"serve": {
"mode": "auto",
"dir": "src",
"watch": ["src/scss/**/*.scss", "src/typescript/**/*.ts"]
}
}Root configuration for the monorepo orchestrator:
{
"analytics": {
"matomo": { "container_id": "container_odwLIyPV", "url": "..." },
"umami": { "site_id": "...", "url": "..." }
},
"defaults": { "src": "src", "dist": "dist", "port": 8000, "framework": "vanilla" },
"deploy": { "branch": "main" },
"deps": {
"system": { "node": { "nix": "nodejs_22" }, "npm": {...}, "git": {...} },
"npm": { "flags": "--no-fund --no-audit --legacy-peer-deps" }
}
}Workflow: .github/workflows/ship.yml
| Step | Action |
|---|---|
| 1. Trigger | Push to main |
| 2. Setup | Node.js 22 + bash build.sh deps |
| 3. Detect | changed-files action per project |
| 4. Build | Only changed projects rebuild |
| 5. Assemble | All dist/ → _site/<project>/, e-Root/dist/ → _site/ root |
| 6. Deploy | Upload artifact → GitHub Pages |
Config generation: .github/workflows/gen-configs.yml
- Trigger: Changes to any
build.jsonor rootbuild.sh - Runs
bash build.sh config→ commitsfront-topology.json
<project>/
├── build.sh → ../../1_cicd/src/scripts/_engine.sh (symlink)
├── build.json Declarative build config
├── src/
│ ├── scss/ ITCSS stylesheets
│ ├── typescript/ TypeScript source
│ ├── index.html Entry HTML
│ └── public/ Static assets (images, fonts)
└── dist/ Build output (gitignored)
- Strict mode enabled, no
anytype - Explicit null/undefined handling
- DOM elements cast explicitly, check null (
querySelectorreturnsElement | null) - ES Modules:
import/export, no CommonJS
let { propName }: { propName: Type } = $props(); // Props
let count = $state(0); // State
let doubled = $derived(count * 2); // Computed
// Events: standard HTML (onclick, not on:click)// Always <script setup lang="ts">
defineProps<{ id: number; name: string }>();
const user = ref<User | null>(null);@include mq(sm|md|lg|xl) // Breakpoints
@include flex-center; // Center anything
@include flex-row(justify, align, gap); // Row layout
@include grid-auto-fit(min-size, gap); // Auto gridRule: Never use style="" inline CSS. All styling goes through SCSS classes.
- Semantic:
<header>,<nav>,<main>,<section>,<article>,<footer> <a>for navigation,<button>for actions- All
<img>havealt, all inputs have<label>
| File | Source | Content |
|---|---|---|
front-topology.json |
build.sh config |
Project registry (name, framework, port, category) |
front-data/front-deps.json |
C3 engine | Merged npm dependencies per project |
package.json |
build.sh deps |
Merged dependencies from all 30+ projects |
Ports 8000–8023, assigned per project in build.json. Each project has a unique port — no conflicts.
Last Updated: 2026-03-18