From c685c27eac6ef603797601db601157f20e28f0d6 Mon Sep 17 00:00:00 2001 From: madgerm Date: Mon, 2 Feb 2026 23:59:30 +0100 Subject: [PATCH] Split web root into desktop and mobile --- README.md | 8 +- docs/README.md | 11 +- web/{ => desktop}/public/assets/starfield.js | 0 web/{ => desktop}/public/assets/style.css | 0 web/{ => desktop}/public/assets/ui.js | 0 web/{ => desktop}/public/index.php | 0 web/{ => desktop}/src/partials/menue-foot.php | 0 web/{ => desktop}/src/partials/menue-top.php | 0 web/{ => desktop}/src/partials/menue.php | 0 web/{ => desktop}/src/partials/menue2.php | 0 web/{ => desktop}/src/partials/ressourcen.php | 0 web/{ => desktop}/src/partials/site.php | 0 web/mobile/public/assets/starfield.js | 114 +++ web/mobile/public/assets/style.css | 733 ++++++++++++++++++ web/mobile/public/assets/ui.js | 121 +++ web/mobile/public/index.php | 244 ++++++ web/mobile/src/partials/menue-foot.php | 12 + web/mobile/src/partials/menue-top.php | 10 + web/mobile/src/partials/menue.php | 36 + web/mobile/src/partials/menue2.php | 35 + web/mobile/src/partials/ressourcen.php | 29 + web/mobile/src/partials/site.php | 100 +++ 22 files changed, 1444 insertions(+), 9 deletions(-) rename web/{ => desktop}/public/assets/starfield.js (100%) rename web/{ => desktop}/public/assets/style.css (100%) rename web/{ => desktop}/public/assets/ui.js (100%) rename web/{ => desktop}/public/index.php (100%) rename web/{ => desktop}/src/partials/menue-foot.php (100%) rename web/{ => desktop}/src/partials/menue-top.php (100%) rename web/{ => desktop}/src/partials/menue.php (100%) rename web/{ => desktop}/src/partials/menue2.php (100%) rename web/{ => desktop}/src/partials/ressourcen.php (100%) rename web/{ => desktop}/src/partials/site.php (100%) create mode 100644 web/mobile/public/assets/starfield.js create mode 100644 web/mobile/public/assets/style.css create mode 100644 web/mobile/public/assets/ui.js create mode 100644 web/mobile/public/index.php create mode 100644 web/mobile/src/partials/menue-foot.php create mode 100644 web/mobile/src/partials/menue-top.php create mode 100644 web/mobile/src/partials/menue.php create mode 100644 web/mobile/src/partials/menue2.php create mode 100644 web/mobile/src/partials/ressourcen.php create mode 100644 web/mobile/src/partials/site.php diff --git a/README.md b/README.md index 98840a1..d5a46d6 100644 --- a/README.md +++ b/README.md @@ -4,15 +4,15 @@ Alles, was später auf den Webserver gehört, lebt unter `web/`. Die anderen Ordner dokumentieren Planung und Infos, die nicht direkt ausgeliefert werden. ## Struktur -- `web/public/`: Webserver-Entry-Point und Assets (CSS/JS) für die HUD-Demo. -- `web/src/partials/`: Die PHP-Partial-Templates für Menüs, Ressourcen und Content. +- `web/desktop/`: Desktop-geeigneter Build mit eigenem `public/` (Entry-Point) und `src/partials/`. +- `web/mobile/`: Mobile-Version (aktuell ein Spiegel des Desktop-Builds; anpassbar für responsive Varianten). - `docs/`: Projektdokumentation; siehe `docs/README.md` für Details zur Anwendung. - `planning/`: Freifläche für Skizzen, Notizen oder Quelltext, der nicht ins Webroot gehört. ## Entwicklung 1. `cd /path/to/Space-Theme` -2. `php -S localhost:8000 -t web/public` -3. Öffne `http://localhost:8000/index.php?s=overview&p=dashboard` +2. `php -S localhost:8000 -t web/desktop/public` +3. Öffne `http://localhost:8000/index.php?s=overview&p=dashboard` (für mobile Tests `-t web/mobile/public`). ## Weitere Infos - Die ausführliche Demo-Beschreibung und Abläufe stehen in `docs/README.md`. diff --git a/docs/README.md b/docs/README.md index f782c47..ccea3c9 100644 --- a/docs/README.md +++ b/docs/README.md @@ -4,9 +4,10 @@ Diese Demo zeigt eine HUD-artige Navigation mit statischem Hauptmenü, kontextabhängiger Subnav, Sticky-Ressourcenleiste, Toasts und einem generischen Content-Bereich. Das HTML wird vom zentralen Entry-Point `public/index.php` zusammengesetzt, die einzelnen Bausteine liegen als Partial-Templates in `src/partials`. ## Verzeichnisstruktur -- `web/public/`: Dokumentenwurzel, in der der Entry Point sitzt und auf die Assets unter `web/public/assets/` zugreift. Alles, was ausgeliefert wird, gehört hierhin. -- `web/public/assets/`: CSS- und JS-Dateien (`style.css`, `ui.js`, `starfield.js`), die das HUD und den Starfield-Canvas bedienen. -- `web/src/partials/`: Menü-, Footer-, Ressourcendarstellung und Content-Renderer, die `web/public/index.php` inkludiert. +- `web/desktop/public/`: Dokumentenwurzel für den Desktop-Entry-Point und seine Assets (`assets/`). +- `web/desktop/src/partials/`: Die PHP-Partial-Templates für Menüs, Ressourcen und Content im Desktop-Build. +- `web/mobile/public/`: Mobile-Entry-Point; derzeit eine Kopie des Desktop-Systems, die für responsive Änderungen angepasst werden kann. +- `web/mobile/src/partials/`: Mobile-Partial-Templates (momentan identisch zum Desktop-Set). ## Layout-Highlights - **Sidebar**: Hauptmenü (links) mit statischem Link-Set plus optionaler Planetenliste auf der Unterseite. @@ -18,8 +19,8 @@ Diese Demo zeigt eine HUD-artige Navigation mit statischem Hauptmenü, kontextab ## Lokale Entwicklung 1. `cd /path/to/Space-Theme`. -2. `php -S localhost:8000 -t web/public` (setzt die Dokumentenwurzel auf `web/public/`). -3. Öffne `http://localhost:8000/index.php` und wechsle z. B. über `?s=build&p=demolish` die Sections. +2. `php -S localhost:8000 -t web/desktop/public` (setzt die Dokumentenwurzel auf den Desktop-Build). +3. Öffne `http://localhost:8000/index.php` und wechsle z. B. über `?s=build&p=demolish` die Sections oder wechsle mit `-t web/mobile/public` zur mobilen Variante. ## Hinweise - Die PHP-Session (`session_start()`) im Entry-Point dient Flash-Toasts und Alert-Messages. diff --git a/web/public/assets/starfield.js b/web/desktop/public/assets/starfield.js similarity index 100% rename from web/public/assets/starfield.js rename to web/desktop/public/assets/starfield.js diff --git a/web/public/assets/style.css b/web/desktop/public/assets/style.css similarity index 100% rename from web/public/assets/style.css rename to web/desktop/public/assets/style.css diff --git a/web/public/assets/ui.js b/web/desktop/public/assets/ui.js similarity index 100% rename from web/public/assets/ui.js rename to web/desktop/public/assets/ui.js diff --git a/web/public/index.php b/web/desktop/public/index.php similarity index 100% rename from web/public/index.php rename to web/desktop/public/index.php diff --git a/web/src/partials/menue-foot.php b/web/desktop/src/partials/menue-foot.php similarity index 100% rename from web/src/partials/menue-foot.php rename to web/desktop/src/partials/menue-foot.php diff --git a/web/src/partials/menue-top.php b/web/desktop/src/partials/menue-top.php similarity index 100% rename from web/src/partials/menue-top.php rename to web/desktop/src/partials/menue-top.php diff --git a/web/src/partials/menue.php b/web/desktop/src/partials/menue.php similarity index 100% rename from web/src/partials/menue.php rename to web/desktop/src/partials/menue.php diff --git a/web/src/partials/menue2.php b/web/desktop/src/partials/menue2.php similarity index 100% rename from web/src/partials/menue2.php rename to web/desktop/src/partials/menue2.php diff --git a/web/src/partials/ressourcen.php b/web/desktop/src/partials/ressourcen.php similarity index 100% rename from web/src/partials/ressourcen.php rename to web/desktop/src/partials/ressourcen.php diff --git a/web/src/partials/site.php b/web/desktop/src/partials/site.php similarity index 100% rename from web/src/partials/site.php rename to web/desktop/src/partials/site.php diff --git a/web/mobile/public/assets/starfield.js b/web/mobile/public/assets/starfield.js new file mode 100644 index 0000000..980d858 --- /dev/null +++ b/web/mobile/public/assets/starfield.js @@ -0,0 +1,114 @@ +(() => { + const canvas = document.getElementById("starfield"); + if (!canvas) return; + + const reduceMotion = window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches; + if (reduceMotion) return; + + const ctx = canvas.getContext("2d", { alpha: true }); + + const cfg = { + get perf(){ return (document.documentElement.dataset.perf || "auto").toLowerCase(); }, + starCount(){ return this.perf === "high" ? 1100 : this.perf === "medium" ? 650 : this.perf === "low" ? 0 : 500; }, + fps(){ return this.perf === "high" ? 60 : this.perf === "medium" ? 30 : this.perf === "low" ? 0 : 25; }, + dpr(){ return this.perf === "high" ? Math.min(devicePixelRatio||1, 2) : 1; }, + twinkle(){ return this.perf === "high" ? 0.45 : 0.35; }, + }; + + let w=0,h=0,dpr=1,stars=[],mouseX=0,mouseY=0,last=performance.now(),acc=0; + let lastPerf = ""; + + function rand(min,max){ return min + Math.random()*(max-min); } + + function newStar(randomZ=false){ + return { x: rand(-1,1), y: rand(-1,1), z: randomZ ? Math.random() : 1, r: rand(0.6,1.7), t: Math.random()*Math.PI*2 }; + } + + function initStars(){ + const n = cfg.starCount(); + stars = Array.from({length:n}, ()=>newStar(true)); + } + + function resize(){ + dpr = cfg.dpr(); + w = Math.floor(window.innerWidth); + h = Math.floor(window.innerHeight); + canvas.width = Math.floor(w*dpr); + canvas.height = Math.floor(h*dpr); + canvas.style.width = w+"px"; + canvas.style.height = h+"px"; + ctx.setTransform(dpr,0,0,dpr,0,0); + initStars(); + } + + function project(s){ + const cx=w*0.5, cy=h*0.5; + const p = 1/(s.z*1.25); + return { x: cx + s.x*cx*p, y: cy + s.y*cy*p, size: s.r*p }; + } + + function tick(dt){ + ctx.clearRect(0,0,w,h); + + const g = ctx.createRadialGradient(w*0.5,h*0.45,0,w*0.5,h*0.45,Math.min(w,h)*0.85); + g.addColorStop(0,"rgba(66,245,255,0.04)"); + g.addColorStop(0.5,"rgba(255,61,242,0.02)"); + g.addColorStop(1,"rgba(0,0,0,0)"); + ctx.fillStyle=g; + ctx.fillRect(0,0,w,h); + + const mx=(mouseX-w*0.5)/(w*0.5), my=(mouseY-h*0.5)/(h*0.5); + const speed = (cfg.perf==="high" ? 0.03 : 0.022); + + for(let i=0;iw+60||p.y<-60||p.y>h+60) continue; + + const tw = 0.7 + Math.sin(s.t)*cfg.twinkle()*0.25; + const alpha = Math.min(0.95, (0.18 + (1-s.z)*0.85)*tw); + + const par = 0.22*(1-s.z); + const x2 = p.x + mx*18*par; + const y2 = p.y + my*12*par; + + ctx.fillStyle = `rgba(240,247,255,${alpha})`; + ctx.beginPath(); + ctx.arc(x2,y2,Math.max(0.7,p.size*0.55),0,Math.PI*2); + ctx.fill(); + } + } + + function frame(now){ + const perf = cfg.perf; + if(perf !== lastPerf){ + lastPerf = perf; + resize(); + } + + const fps = cfg.fps(); + if(fps <= 0){ requestAnimationFrame(frame); return; } + + const dt = Math.min((now-last)/1000, 0.05); + last = now; + acc += dt; + + const step = 1/fps; + while(acc >= step){ + tick(step); + acc -= step; + } + requestAnimationFrame(frame); + } + + window.addEventListener("mousemove",(e)=>{ mouseX=e.clientX; mouseY=e.clientY; }, {passive:true}); + window.addEventListener("resize", resize, {passive:true}); + + resize(); + mouseX = window.innerWidth*0.5; mouseY = window.innerHeight*0.5; + requestAnimationFrame(frame); +})(); \ No newline at end of file diff --git a/web/mobile/public/assets/style.css b/web/mobile/public/assets/style.css new file mode 100644 index 0000000..3cd9b8a --- /dev/null +++ b/web/mobile/public/assets/style.css @@ -0,0 +1,733 @@ +:root{ + --gap: 16px; + --radius: 18px; + + --bg0: #050510; + --bg1: #070a1f; + --card0: rgba(10, 14, 40, .65); + --card1: rgba(16, 22, 60, .55); + --border: rgba(145, 220, 255, .18); + + --text: rgba(240, 247, 255, .92); + --muted: rgba(200, 220, 255, .65); + + --neon-cyan: #42f5ff; + --neon-blue: #5b7cff; + --neon-pink: #ff3df2; + --neon-green: #3dffb5; + --neon-warn: #ffd34d; + + --danger: #ff3b6a; + --shadow: 0 12px 40px rgba(0,0,0,.45); + --glow-cyan: 0 0 18px rgba(66,245,255,.35), 0 0 46px rgba(66,245,255,.18); + --glow-pink: 0 0 18px rgba(255,61,242,.28), 0 0 46px rgba(255,61,242,.16); + + --sidebarW: 320px; + + --font-ui: system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif; + --font-sci: "Orbitron", system-ui, sans-serif; +} + +/* Performance profiles */ +html[data-perf="low"] .starfield{ display:none; } +html[data-perf="low"] .space-bg::after{ display:none; } /* planet off in low */ + +*{ box-sizing: border-box; } +html, body{ height: 100%; } +body{ + margin: 0; + color: var(--text); + font-family: var(--font-ui); + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + + background: + radial-gradient(1200px 800px at 20% 10%, rgba(91,124,255,.18), transparent 65%), + radial-gradient(900px 700px at 80% 0%, rgba(255,61,242,.12), transparent 60%), + radial-gradient(900px 800px at 60% 110%, rgba(66,245,255,.10), transparent 60%), + linear-gradient(180deg, var(--bg0), var(--bg1)); + + overflow-x: hidden; +} + +/* Starfield Canvas */ +.starfield{ + position: fixed; + inset: 0; + z-index: 0; + width: 100%; + height: 100%; + pointer-events: none; + opacity: .98; +} + +/* Nebula/Planet Overlay */ +.space-bg{ + position: fixed; + inset: 0; + z-index: 1; + pointer-events: none; +} +.space-bg::before{ + content:""; + position:absolute; + inset: 0; + background: + radial-gradient(900px 600px at 20% 15%, rgba(91,124,255,.12), transparent 60%), + radial-gradient(700px 500px at 80% 10%, rgba(255,61,242,.10), transparent 55%), + radial-gradient(900px 700px at 60% 110%, rgba(66,245,255,.08), transparent 60%); + opacity: .9; +} +.space-bg::after{ + content:""; + position:absolute; + width: 420px; + height: 420px; + left: 72%; + top: 55%; + border-radius: 50%; + background: + radial-gradient(closest-side at 30% 30%, rgba(255,255,255,.20), transparent 55%), + radial-gradient(closest-side at 55% 60%, rgba(66,245,255,.16), transparent 62%), + radial-gradient(closest-side at 70% 75%, rgba(0,0,0,.50), rgba(0,0,0,.80) 70%), + radial-gradient(circle at 40% 40%, rgba(90,140,255,.30), rgba(40,60,120,.14) 55%, rgba(0,0,0,0) 72%); + box-shadow: 0 0 50px rgba(91,124,255,.18), 0 0 120px rgba(255,61,242,.09); + animation: planetFloat 90s ease-in-out infinite; + opacity: .58; +} +@keyframes planetFloat{ + 0% { transform: translate(-40px,-20px) scale(1); } + 50% { transform: translate(30px,10px) scale(1.02); } + 100% { transform: translate(-40px,-20px) scale(1); } +} + +/* Layout */ +.container{ + width: min(1280px, 100% - 32px); + margin-inline: auto; + padding-block: 16px; + position: relative; + z-index: 2; +} +.container::before{ + content:""; + position:absolute; + inset:-14px; + pointer-events:none; + background: + radial-gradient(1200px 700px at 50% 40%, transparent 55%, rgba(0,0,0,.55) 85%), + linear-gradient(135deg, rgba(255,255,255,.05), transparent 35%); + border-radius: 28px; + opacity: .55; + filter: blur(.2px); +} + +.app{ + min-height: calc(100vh - 32px); + display:grid; + gap: var(--gap); + grid-template-columns: var(--sidebarW) 1fr; + grid-template-rows: auto auto auto auto 1fr auto; + grid-template-areas: + "sidebar topbar" + "sidebar alertbar" + "sidebar subnav" + "sidebar resourcebar" + "sidebar content" + "footer footer"; +} + +.sidebar{ grid-area: sidebar; } +.topbar{ grid-area: topbar; } +.alertbar{ grid-area: alertbar; } +.subnav{ grid-area: subnav; } +.resourcebar{ grid-area: resourcebar; } +.content{ grid-area: content; } +.footer{ grid-area: footer; } + +.sidebar{ + display:grid; + gap: var(--gap); + align-content:start; + position: sticky; + top: 16px; + max-height: calc(100vh - 32px); + overflow: auto; + padding-right: 4px; +} + +/* Cards / Panels + Hologramm */ +.card{ + border-radius: var(--radius); + border: 1px solid var(--border); + background: linear-gradient(180deg, rgba(10, 14, 40, .65), rgba(16, 22, 60, .55)); + box-shadow: var(--shadow); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + position: relative; + overflow: hidden; +} +.panel{ padding: 14px 16px; } + +.card::after{ + content:""; + position:absolute; + inset:-2px; + border-radius: inherit; + background: + radial-gradient(600px 120px at 20% 0%, rgba(66,245,255,.18), transparent 70%), + radial-gradient(500px 120px at 80% 0%, rgba(255,61,242,.12), transparent 70%); + pointer-events:none; + opacity:.85; +} +.card::before{ + content:""; + position:absolute; + inset:0; + pointer-events:none; + background: + repeating-linear-gradient(180deg, rgba(66,245,255,.00) 0px, rgba(66,245,255,.00) 3px, rgba(66,245,255,.05) 4px); + opacity: .22; + mix-blend-mode: screen; +} + +@keyframes hudShimmer{ + 0% { transform: translateX(-120%) skewX(-20deg); opacity: 0; } + 20% { opacity: .35; } + 100% { transform: translateX(120%) skewX(-20deg); opacity: 0; } +} +.card:hover .panel::after{ + content:""; + position:absolute; + top:0; left:0; + height:100%; + width:40%; + background: linear-gradient(90deg, transparent, rgba(66,245,255,.18), transparent); + filter: blur(2px); + pointer-events:none; + animation: hudShimmer 1.1s ease; +} + +/* Typography */ +.panel-title, +.brand-title, +.hud-title, +h1,h2,h3, +button,.btn,input[type="submit"], .chip, .tab, +label,.label{ + font-family: var(--font-sci); + letter-spacing: .6px; +} +.hud-title{ margin: 0 0 6px; text-transform: uppercase; } +.h2{ margin: 0 0 10px; } +.muted{ color: var(--muted); font-size: .95rem; } +.tiny{ font-size: .8rem; } + +.divider{ height: 1px; background: rgba(145,220,255,.14); margin: 14px 0; } +.w-full{ display:block; width: 100%; text-align:center; } + +/* Topbar */ +.topbar{ position: relative; } +.topbar-inner{ + display:flex; + align-items:center; + justify-content:space-between; + gap: 12px; + flex-wrap: wrap; +} +.brand{ display:flex; align-items:center; gap: 12px; } +.brand-dot{ + width: 12px; height: 12px; + border-radius: 50%; + background: linear-gradient(180deg, rgba(66,245,255,.85), rgba(255,61,242,.55)); + box-shadow: var(--glow-cyan); +} +.top-actions{ display:flex; gap: 10px; align-items:center; flex-wrap: wrap; } + +.iconbtn{ + border: 1px solid rgba(145,220,255,.18); + background: rgba(0,0,0,.18); + color: var(--text); + border-radius: 14px; + padding: 9px 12px; + cursor:pointer; + font-family: var(--font-sci); + letter-spacing: .6px; +} +.iconbtn:hover{ box-shadow: var(--glow-cyan); border-color: rgba(66,245,255,.45); transform: translateY(-1px); } +.badge{ + display:inline-block; + margin-left: 8px; + padding: 2px 8px; + border-radius: 999px; + border: 1px solid rgba(255,61,242,.25); + background: rgba(255,61,242,.10); + font-size: .8rem; +} + +/* Notification panel */ +.notif{ + position: absolute; + right: 12px; + top: calc(100% + 10px); + width: min(360px, 100%); + border-radius: 16px; + border: 1px solid rgba(145,220,255,.18); + background: linear-gradient(180deg, rgba(10, 14, 40, .92), rgba(16, 22, 60, .75)); + box-shadow: var(--shadow); + overflow: hidden; +} +.notif-head{ + display:flex; + align-items:center; + justify-content:space-between; + padding: 10px 12px; + border-bottom: 1px solid rgba(145,220,255,.12); +} +.notif-list{ display:grid; } +.notif-item{ + display:flex; + gap: 10px; + align-items:center; + padding: 10px 12px; + border: 0; + background: transparent; + color: var(--text); + text-align:left; + cursor:pointer; +} +.notif-item:hover{ background: rgba(66,245,255,.06); } +.notif-ico{ width: 24px; text-align:center; } +.notif-title{ display:block; font-family: var(--font-sci); letter-spacing:.6px; } +.notif-meta{ display:block; color: var(--muted); font-size: .82rem; margin-top: 2px; } + +/* Subnav (Kontextmenü in der Mitte) */ +.subnav{ + display:flex; + align-items:center; + justify-content:space-between; + gap: 12px; + flex-wrap: wrap; +} +.subnav-tabs{ display:flex; gap: 10px; flex-wrap: wrap; } +.tab{ + display:inline-flex; + align-items:center; + padding: 8px 12px; + border-radius: 999px; + border: 1px solid rgba(145,220,255,.18); + background: rgba(0,0,0,.18); + color: var(--text); + text-decoration:none; + transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease; +} +.tab:hover{ transform: translateY(-1px); border-color: rgba(66,245,255,.45); box-shadow: var(--glow-cyan); } +.tab.is-active{ + border-color: rgba(66,245,255,.55); + box-shadow: var(--glow-cyan); + background: linear-gradient(180deg, rgba(66,245,255,.18), rgba(91,124,255,.10)); +} + +/* Main menu list */ +.navlist{ list-style:none; padding:0; margin: 12px 0 0; display:grid; gap: 10px; } +.navlist a{ + display:flex; + align-items:center; + justify-content:flex-start; + gap: 10px; + padding: 10px 12px; + border-radius: 14px; + border: 1px solid rgba(145,220,255,.14); + background: rgba(0,0,0,.18); + transition: transform .15s ease, border-color .15s ease, box-shadow .15s ease; + text-decoration: none; + color: var(--text); +} +.navlist a:hover{ + transform: translateY(-1px); + border-color: rgba(66,245,255,.35); + box-shadow: var(--glow-cyan); +} +.navlist a.is-active{ + border-color: rgba(66,245,255,.55); + box-shadow: var(--glow-cyan); +} +.mi{ width: 22px; text-align:center; } + +/* Planet list */ +.planetlist{ list-style:none; padding:0; margin: 12px 0 0; display:grid; gap: 10px; } +.planetlist a{ + display:flex; + align-items:center; + gap: 10px; + padding: 10px 12px; + border-radius: 14px; + border: 1px solid rgba(145,220,255,.14); + background: rgba(0,0,0,.18); + text-decoration: none; + color: var(--text); + justify-content:space-between; +} +.planetlist a:hover{ border-color: rgba(66,245,255,.35); box-shadow: var(--glow-cyan); transform: translateY(-1px); } +.planetlist a.is-active{ border-color: rgba(66,245,255,.55); box-shadow: var(--glow-cyan); } +.pl-name{ flex: 1; } +.pl-dot{ + width: 10px; height: 10px; border-radius: 999px; + background: rgba(145,220,255,.20); + box-shadow: 0 0 10px rgba(255,255,255,.08); +} +.pl-dot.on{ background: var(--neon-green); box-shadow: 0 0 18px rgba(61,255,181,.24); } + +.navhint{ + color: rgba(200,220,255,.55); + font-size: .8rem; + border: 1px solid rgba(145,220,255,.16); + border-radius: 10px; + padding: 2px 8px; + background: rgba(0,0,0,.18); +} + +/* Buttons */ +button, .btn, input[type="submit"]{ + appearance:none; + border: 1px solid rgba(66,245,255,.28); + background: linear-gradient(180deg, rgba(66,245,255,.18), rgba(91,124,255,.10)); + color: var(--text); + border-radius: 14px; + padding: 10px 14px; + cursor:pointer; + transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease, filter .15s ease; + text-decoration: none; + display: inline-block; +} +button:hover, .btn:hover, input[type="submit"]:hover{ + transform: translateY(-1px); + border-color: rgba(66,245,255,.55); + box-shadow: var(--glow-cyan); + filter: brightness(1.08); +} +button:active, .btn:active, input[type="submit"]:active{ transform: translateY(0) scale(.99); } +.btn-primary{ + border-color: rgba(255,61,242,.32); + background: linear-gradient(180deg, rgba(255,61,242,.18), rgba(66,245,255,.08)); +} +.btn-primary:hover{ box-shadow: var(--glow-pink); } +.btn-mini{ padding: 7px 10px; border-radius: 12px; font-size: .85rem; } + +.actions{ display:flex; gap: 12px; margin-top: 14px; flex-wrap: wrap; } + +/* Resourcebar sticky */ +.resourcebar{ + position: sticky; + top: 16px; + z-index: 5; +} + +.resource-row, .footer-row{ + display:flex; + align-items:center; + justify-content:space-between; + gap: 12px; + flex-wrap: wrap; +} +.stats{ display:flex; gap: 12px; flex-wrap: wrap; } +.stat{ + border: 1px solid rgba(145,220,255,.14); + background: rgba(0,0,0,.18); + border-radius: 14px; + padding: 8px 12px; + min-width: 160px; +} +.stat-k{ color: var(--muted); font-size: .86rem; } +.stat-v{ font-family: var(--font-sci); letter-spacing: .6px; margin-top: 2px; } +.dot{ + display:inline-block; + width: 8px; height: 8px; + border-radius: 999px; + margin-right: 8px; + box-shadow: 0 0 14px rgba(255,255,255,.12); +} +.dot-cyan{ background: var(--neon-cyan); box-shadow: var(--glow-cyan); } +.dot-pink{ background: var(--neon-pink); box-shadow: var(--glow-pink); } +.dot-green{ background: var(--neon-green); box-shadow: 0 0 18px rgba(61,255,181,.24); } +.dot-warn{ background: var(--neon-warn); box-shadow: 0 0 18px rgba(255,211,77,.18); } +.stat-bar{ + margin-top: 8px; + height: 6px; + border-radius: 999px; + background: rgba(145,220,255,.10); + overflow: hidden; +} +.stat-bar > span{ + display:block; + height: 100%; + border-radius: 999px; + background: linear-gradient(90deg, rgba(66,245,255,.55), rgba(255,61,242,.35)); +} + +/* Cockpit Window */ +.cockpit{ padding-top: 10px; } +.cockpit-hud{ + display:flex; + align-items:center; + justify-content:space-between; + gap: 10px; + flex-wrap: wrap; + margin-bottom: 12px; + padding: 10px 12px; + border-radius: 14px; + border: 1px solid rgba(145,220,255,.16); + background: rgba(0,0,0,.18); +} +.hud-left, .hud-right{ + font-family: var(--font-sci); + letter-spacing: .7px; + font-size: .85rem; + color: rgba(240,247,255,.88); + text-transform: uppercase; +} +.hud-pill{ + display:inline-block; + padding: 6px 10px; + border-radius: 999px; + border: 1px solid rgba(66,245,255,.20); + background: rgba(0,0,0,.16); + margin-left: 8px; +} +.cockpit::after{ + content:""; + position:absolute; + inset: 10px; + border-radius: calc(var(--radius) - 6px); + pointer-events:none; + border: 1px solid rgba(66,245,255,.22); + box-shadow: 0 0 22px rgba(66,245,255,.14), inset 0 0 20px rgba(255,61,242,.06); +} +.cockpit::before{ + content:""; + position:absolute; + inset: 0; + pointer-events:none; + background: + linear-gradient(90deg, rgba(66,245,255,.35), rgba(66,245,255,0)) 0 0 / 120px 2px no-repeat, + linear-gradient(180deg, rgba(66,245,255,.35), rgba(66,245,255,0)) 0 0 / 2px 120px no-repeat, + linear-gradient(90deg, rgba(66,245,255,0), rgba(66,245,255,.35)) 100% 0 / 120px 2px no-repeat, + linear-gradient(180deg, rgba(66,245,255,.35), rgba(66,245,255,0)) 100% 0 / 2px 120px no-repeat, + linear-gradient(90deg, rgba(66,245,255,.35), rgba(66,245,255,0)) 0 100% / 120px 2px no-repeat, + linear-gradient(180deg, rgba(66,245,255,0), rgba(66,245,255,.35)) 0 100% / 2px 120px no-repeat, + linear-gradient(90deg, rgba(66,245,255,0), rgba(66,245,255,.35)) 100% 100% / 120px 2px no-repeat, + linear-gradient(180deg, rgba(66,245,255,0), rgba(66,245,255,.35)) 100% 100% / 2px 120px no-repeat, + repeating-linear-gradient(90deg, rgba(66,245,255,.04) 0px, rgba(66,245,255,.04) 1px, transparent 1px, transparent 60px), + repeating-linear-gradient(180deg, rgba(66,245,255,.03) 0px, rgba(66,245,255,.03) 1px, transparent 1px, transparent 60px), + radial-gradient(900px 300px at 20% 0%, rgba(255,255,255,.06), transparent 55%); + opacity: .55; + mix-blend-mode: screen; +} + +/* Timeline + Queue */ +.grid-2{ display:grid; grid-template-columns: 1fr 1fr; gap: 14px; } +.inner.card{ background: rgba(0,0,0,.10); } +.timeline{ display:grid; gap: 10px; margin-top: 10px; } +.tl-item{ + padding: 10px 12px; + border-radius: 14px; + border: 1px solid rgba(145,220,255,.14); + background: rgba(0,0,0,.18); +} +.tl-dot{ display:inline-block; width: 8px; height: 8px; border-radius: 999px; margin-right: 10px; vertical-align: middle; } +.tl-cyan{ background: var(--neon-cyan); box-shadow: var(--glow-cyan); } +.tl-pink{ background: var(--neon-pink); box-shadow: var(--glow-pink); } +.tl-green{ background: var(--neon-green); box-shadow: 0 0 18px rgba(61,255,181,.24); } + +.queue{ display:grid; gap: 12px; margin-top: 10px; } +.q-card{ + border: 1px solid rgba(145,220,255,.14); + background: rgba(0,0,0,.18); + border-radius: 14px; + padding: 12px; +} +.q-head{ display:flex; gap: 10px; align-items:center; } +.q-bar{ + margin-top: 10px; + height: 8px; + border-radius: 999px; + background: rgba(145,220,255,.10); + overflow: hidden; +} +.q-bar > span{ + display:block; + height: 100%; + border-radius: 999px; + background: linear-gradient(90deg, rgba(66,245,255,.55), rgba(255,61,242,.35)); +} +.q-meta{ + display:flex; + align-items:center; + justify-content:space-between; + gap: 10px; + flex-wrap: wrap; + margin-top: 10px; + color: var(--muted); +} + +/* Settings segments */ +.settings-row{ display:flex; gap: 14px; flex-wrap: wrap; align-items:flex-end; } +.settings-block{ min-width: 240px; } +.seg{ display:flex; gap: 10px; flex-wrap: wrap; } +.seg-btn{ + border: 1px solid rgba(145,220,255,.18); + background: rgba(0,0,0,.18); + color: var(--text); + border-radius: 999px; + padding: 9px 12px; + cursor:pointer; +} +.seg-btn:hover{ box-shadow: var(--glow-cyan); border-color: rgba(66,245,255,.45); transform: translateY(-1px); } +.seg-btn.is-selected{ + border-color: rgba(66,245,255,.55); + box-shadow: var(--glow-cyan); + background: linear-gradient(180deg, rgba(66,245,255,.18), rgba(91,124,255,.10)); +} +.check{ display:flex; gap: 10px; align-items:center; margin-top: 6px; } +.check input{ accent-color: var(--neon-cyan); } + +/* Alert pulse modes via html[data-alertpulse] */ +html[data-alertpulse="burst"] { --alert-iter: 3; } +html[data-alertpulse="loop"] { --alert-iter: infinite; } + +.alert.alert-pro{ + position: relative; + display: flex; + gap: 12px; + align-items: flex-start; + padding: 14px 14px; + border-radius: 16px; + border: 1px solid rgba(255,59,106,.42); + background: + linear-gradient(180deg, rgba(255,59,106,.16), rgba(0,0,0,.18)), + repeating-linear-gradient(135deg, rgba(255,59,106,.06) 0px, rgba(255,59,106,.06) 10px, rgba(0,0,0,0) 10px, rgba(0,0,0,0) 22px); + box-shadow: 0 0 18px rgba(255,59,106,.22), 0 0 52px rgba(255,59,106,.10); +} +.alert.alert-pro::before{ + content:""; + position:absolute; + inset:-10px; + border-radius: 18px; + pointer-events:none; + background: radial-gradient(closest-side at 20% 30%, rgba(255,59,106,.30), rgba(255,59,106,.10) 45%, rgba(0,0,0,0) 70%); + opacity: .55; + transform: scale(1); + animation: alertPulse 1.25s ease-in-out 0s var(--alert-iter) both; +} +.alert-led{ + flex: 0 0 auto; + width: 12px; + height: 12px; + border-radius: 999px; + background: radial-gradient(circle at 30% 30%, rgba(255,255,255,.30), rgba(255,59,106,.95)); + box-shadow: 0 0 10px rgba(255,59,106,.35), 0 0 24px rgba(255,59,106,.18); + margin-top: 2px; + animation: ledBreathe 1.25s ease-in-out 0s var(--alert-iter) both; +} +.alert-title{ text-transform: uppercase; letter-spacing: .8px; margin-bottom: 6px; } +.alert-text{ color: rgba(240,247,255,.92); } + +@keyframes alertPulse{ + 0% { opacity: .45; transform: scale(1); } + 45% { opacity: .95; transform: scale(1.01); } + 100% { opacity: .55; transform: scale(1); } +} +@keyframes ledBreathe{ + 0% { transform: scale(1); opacity: .75; } + 45% { transform: scale(1.2); opacity: 1; } + 100% { transform: scale(1); opacity: .85; } +} + +/* Toasts */ +.toast-host{ + position: fixed; + right: 16px; + bottom: 16px; + display: grid; + gap: 10px; + z-index: 9999; + width: min(360px, calc(100vw - 32px)); +} + +.toast{ + display:flex; + gap: 12px; + align-items:flex-start; + padding: 12px 12px; + border-radius: 16px; + border: 1px solid rgba(145,220,255,.18); + background: linear-gradient(180deg, rgba(10, 14, 40, .82), rgba(16, 22, 60, .65)); + box-shadow: var(--shadow); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + overflow: hidden; + animation: toastIn .18s ease-out; + position: relative; +} +.toast::before{ + content:""; + position:absolute; + inset:0; + pointer-events:none; + background: repeating-linear-gradient(180deg, rgba(66,245,255,.00) 0px, rgba(66,245,255,.00) 3px, rgba(66,245,255,.05) 4px); + opacity: .18; + mix-blend-mode: screen; +} +.toast-icon{ font-size: 18px; line-height: 1; margin-top: 2px; filter: drop-shadow(0 0 12px rgba(66,245,255,.22)); } +.toast-title{ text-transform: uppercase; font-size: .92rem; } +.toast-msg{ color: rgba(240,247,255,.85); font-size: .95rem; margin-top: 2px; } +.toast-x{ + margin-left: auto; + border: 1px solid rgba(145,220,255,.18); + background: rgba(0,0,0,.18); + color: var(--text); + border-radius: 12px; + padding: 6px 9px; +} +.toast-success{ border-color: rgba(61,255,181,.25); } +.toast-error{ border-color: rgba(255,59,106,.30); } +.toast-info{ border-color: rgba(66,245,255,.25); } +@keyframes toastIn{ from{ transform: translateY(8px); opacity: 0; } to{ transform: translateY(0); opacity: 1; } } +.toast.out{ animation: toastOut .18s ease-in forwards; } +@keyframes toastOut{ to{ transform: translateY(8px); opacity: 0; } } + +/* Scrollbar */ +.sidebar::-webkit-scrollbar{ width: 10px; } +.sidebar::-webkit-scrollbar-track{ background: rgba(0,0,0,.12); border-radius: 999px; } +.sidebar::-webkit-scrollbar-thumb{ + background: linear-gradient(180deg, rgba(66,245,255,.35), rgba(255,61,242,.25)); + border-radius: 999px; + border: 2px solid rgba(0,0,0,.18); +} + +/* Responsive */ +@media (max-width: 980px){ + :root{ --sidebarW: 1fr; } + .app{ + grid-template-columns: 1fr; + grid-template-rows: auto auto auto auto auto 1fr auto; + grid-template-areas: + "topbar" + "alertbar" + "subnav" + "resourcebar" + "content" + "sidebar" + "footer"; + } + .sidebar{ position: static; max-height: none; overflow: visible; padding-right: 0; } + .grid-2{ grid-template-columns: 1fr; } + .resourcebar{ position: static; } +} + +/* Reduced motion */ +@media (prefers-reduced-motion: reduce){ + .starfield{ display:none; } + .space-bg::after{ animation: none !important; } + .alert.alert-pro::before, .alert-led{ animation: none !important; } +} diff --git a/web/mobile/public/assets/ui.js b/web/mobile/public/assets/ui.js new file mode 100644 index 0000000..98bff62 --- /dev/null +++ b/web/mobile/public/assets/ui.js @@ -0,0 +1,121 @@ +(function(){ + const host = document.getElementById("toastHost"); + + function iconFor(type){ + if(type === "success") return "✅"; + if(type === "error") return "⛔"; + if(type === "info") return "🛰️"; + return "🔔"; + } + + window.toast = function(type="info", title="Notice", message="", ttl=3200){ + if(!host) return; + + const el = document.createElement("div"); + el.className = `toast toast-${type}`; + el.innerHTML = ` +
${iconFor(type)}
+
+
${escapeHtml(title)}
+
${escapeHtml(message)}
+
+ + `; + + const remove = () => { + el.classList.add("out"); + el.addEventListener("animationend", () => el.remove(), { once:true }); + }; + + el.querySelector(".toast-x").addEventListener("click", remove); + host.appendChild(el); + if (ttl > 0) setTimeout(remove, ttl); + }; + + function escapeHtml(s){ + return String(s ?? "") + .replaceAll("&","&") + .replaceAll("<","<") + .replaceAll(">",">") + .replaceAll('"',""") + .replaceAll("'","'"); + } + + // Notifications dropdown (tiny JS) + const notif = document.getElementById("notifPanel"); + window.toggleNotif = function(){ + if(!notif) return; + const isHidden = notif.hasAttribute("hidden"); + if(isHidden) notif.removeAttribute("hidden"); + else notif.setAttribute("hidden",""); + }; + document.addEventListener("click", (e)=>{ + if(!notif) return; + const btn = e.target.closest(".iconbtn"); + const inside = e.target.closest("#notifPanel"); + if(inside || btn) return; + notif.setAttribute("hidden",""); + }); + + // Settings helpers: perf + alertpulse (no cookies) + function setStorage(key, val, remember){ + try{ + if (remember) { + localStorage.setItem(key, val); + sessionStorage.removeItem(key); + } else { + sessionStorage.setItem(key, val); + localStorage.removeItem(key); + } + }catch(e){} + } + function applyDataset(key, val){ + document.documentElement.dataset[key] = val; + if (key === "perf") { + const label = document.getElementById("perfLabel"); + if(label) label.textContent = val.toUpperCase(); + } + } + + window.applyPerfFromUI = function(){ + const chosen = document.querySelector(".seg-btn.is-selected[data-perf]")?.dataset.perf; + const remember = document.getElementById("rememberPerf")?.checked; + const val = chosen || "auto"; + setStorage("perf", val, remember); + applyDataset("perf", val); + toast("success","Performance", `Profil: ${val.toUpperCase()}`, 2200); + if (val === "low") toast("info","Hint","Low deaktiviert Starfield", 1800); + }; + + window.applyPulseFromUI = function(){ + const chosen = document.querySelector(".seg-btn.is-selected[data-alertpulse]")?.dataset.alertpulse; + const remember = document.getElementById("rememberPulse")?.checked; + const val = chosen || "burst"; + setStorage("alertpulse", val, remember); + applyDataset("alertpulse", val); + toast("success","Alerts", `Pulse: ${val.toUpperCase()}`, 2200); + }; + + // Segment button selection behavior + document.addEventListener("click", (e)=>{ + const b = e.target.closest(".seg-btn"); + if(!b) return; + const parent = b.closest(".seg"); + if(parent){ + parent.querySelectorAll(".seg-btn").forEach(x=>x.classList.remove("is-selected")); + b.classList.add("is-selected"); + } + }); + + // Pre-select in settings pages + document.addEventListener("DOMContentLoaded", ()=>{ + const perf = document.documentElement.dataset.perf || "auto"; + document.querySelectorAll('.seg-btn[data-perf]').forEach(b=>{ + if(b.dataset.perf === perf) b.classList.add("is-selected"); + }); + const pulse = document.documentElement.dataset.alertpulse || "burst"; + document.querySelectorAll('.seg-btn[data-alertpulse]').forEach(b=>{ + if(b.dataset.alertpulse === pulse) b.classList.add("is-selected"); + }); + }); +})(); \ No newline at end of file diff --git a/web/mobile/public/index.php b/web/mobile/public/index.php new file mode 100644 index 0000000..d1eb6f4 --- /dev/null +++ b/web/mobile/public/index.php @@ -0,0 +1,244 @@ + 'success', 'title' => 'Mission Update', 'message' => 'Daten erfolgreich gespeichert.']; + header("Location: index.php?s=$section&p=" . urlencode((string)$sub) . "&planet=$planet"); + exit; +} +if (($_GET['toast'] ?? '') === 'err') { + $_SESSION['flash_error'] = "Bitte alle Pflichtfelder ausfüllen (Hyperdrive-Parameter fehlen)."; + $_SESSION['flash_toast'][] = ['type' => 'error', 'title' => 'System Alert', 'message' => 'Eingabe unvollständig – überprüfe die Felder.']; + header("Location: index.php?s=$section&p=" . urlencode((string)$sub) . "&planet=$planet"); + exit; +} + +// Alertbar nur wenn Fehler vorhanden +$errorMessage = $_SESSION['flash_error'] ?? null; +unset($_SESSION['flash_error']); + +// Toasts (Flash) +$toasts = $_SESSION['flash_toast'] ?? []; +unset($_SESSION['flash_toast']); + +// Kontextmenü-Definitionen (Subnav in der Mitte) +$subnav = [ + 'overview' => [['key'=>'dashboard','label'=>'Übersicht'], ['key'=>'events','label'=>'Events'], ['key'=>'queues','label'=>'Queues']], + 'build' => [['key'=>'build','label'=>'Bauen'], ['key'=>'demolish','label'=>'Abreißen']], + 'research' => [['key'=>'list','label'=>'Forschungen'], ['key'=>'tree','label'=>'Forschungstree']], + 'shipyard' => [['key'=>'small','label'=>'Klein'], ['key'=>'medium','label'=>'Mittel'], ['key'=>'large','label'=>'Groß']], + 'fleet' => [['key'=>'send','label'=>'Versenden'], ['key'=>'missions','label'=>'Missionen'], ['key'=>'scrap','label'=>'Verschrotten']], + 'messages' => [['key'=>'inbox','label'=>'Posteingang'], ['key'=>'outbox','label'=>'Ausgang'], ['key'=>'addressbook','label'=>'Adressbuch']], + 'reports' => [['key'=>'combat','label'=>'Kampfberichte'], ['key'=>'spy','label'=>'Spionage'], ['key'=>'archive','label'=>'Archiv']], + 'galaxy' => [['key'=>'view','label'=>'Galaxy View'], ['key'=>'bookmark','label'=>'Lesezeichen'], ['key'=>'scan','label'=>'Scan']], + 'stargate' => [['key'=>'overview','label'=>'Übersicht'], ['key'=>'links','label'=>'Verbindungen'], ['key'=>'log','label'=>'Protokoll']], + 'pod' => [['key'=>'pad','label'=>'Abschussrampe'], ['key'=>'production','label'=>'Produktion']], + 'trade' => [['key'=>'hub','label'=>'Handelszentrum'], ['key'=>'market','label'=>'Börsenkurse']], + 'blackmarket' => [['key'=>'overview','label'=>'Übersicht'], ['key'=>'create','label'=>'Inserieren'], ['key'=>'mine','label'=>'Meine Inserate']], + 'bank' => [['key'=>'overview','label'=>'Übersicht'], ['key'=>'transfer','label'=>'Überweisung'], ['key'=>'accounts','label'=>'Konten hinzufügen']], + 'terraformer' => [['key'=>'overview','label'=>'Übersicht']], + 'settings' => [['key'=>'ui','label'=>'UI'], ['key'=>'performance','label'=>'Performance'], ['key'=>'alerts','label'=>'Alerts'], ['key'=>'account','label'=>'Account']], +]; + +if (!isset($subnav[$section])) $section = 'overview'; +$items = $subnav[$section]; + +// Default sub page +if ($sub === null && !empty($items)) $sub = $items[0]['key']; +$validSub = array_column($items, 'key'); +if (!in_array($sub, $validSub, true) && !empty($items)) $sub = $items[0]['key']; + +// Page title +$pageTitle = "Space UI – $section / $sub"; + +// Admin demo (set to true to see footer admin link) +$isAdmin = false; +$partialsPath = __DIR__ . '/../src/partials'; +?> + + + + + + <?= htmlspecialchars($pageTitle) ?> + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+
+
+ +
+
ORBIT STATION
+
HUD Navigation • Planet:
+
+
+ +
+ + +
+
+ + + +
+ + + + + + + + + + +
+ +
+ + +
+
+
SECTOR: ORION • DOCK-PORT: A3
+
+ SHIELD 87% + PING 14ms + PERF AUTO +
+
+ + +
+ + + + +
+
+ + +
+ + + + + + + + + diff --git a/web/mobile/src/partials/menue-foot.php b/web/mobile/src/partials/menue-foot.php new file mode 100644 index 0000000..5b5710d --- /dev/null +++ b/web/mobile/src/partials/menue-foot.php @@ -0,0 +1,12 @@ + diff --git a/web/mobile/src/partials/menue-top.php b/web/mobile/src/partials/menue-top.php new file mode 100644 index 0000000..e64e1ef --- /dev/null +++ b/web/mobile/src/partials/menue-top.php @@ -0,0 +1,10 @@ + +
+ +
+
SYSTEM WARNING
+
+
+
diff --git a/web/mobile/src/partials/menue.php b/web/mobile/src/partials/menue.php new file mode 100644 index 0000000..c737358 --- /dev/null +++ b/web/mobile/src/partials/menue.php @@ -0,0 +1,36 @@ +'.$icon.''.$label.''; +} +?> + diff --git a/web/mobile/src/partials/menue2.php b/web/mobile/src/partials/menue2.php new file mode 100644 index 0000000..8cc1693 --- /dev/null +++ b/web/mobile/src/partials/menue2.php @@ -0,0 +1,35 @@ +'earth', 'name'=>'Earth Prime', 'hint'=>'L1'], + ['id'=>'mars', 'name'=>'Mars Outpost', 'hint'=>'L2'], + ['id'=>'io', 'name'=>'Io Refinery', 'hint'=>'L3'], + ['id'=>'vega', 'name'=>'Vega Station', 'hint'=>'L4'], +]; +?> + diff --git a/web/mobile/src/partials/ressourcen.php b/web/mobile/src/partials/ressourcen.php new file mode 100644 index 0000000..f171757 --- /dev/null +++ b/web/mobile/src/partials/ressourcen.php @@ -0,0 +1,29 @@ +
+
+
RESOURCES
+
sticky bar
+
+ +
+
+
Metall
+
12.340
+
+
+
+
Kristall
+
6.120
+
+
+
+
Deuterium
+
3.880
+
+
+
+
Energie
+
+120
+
+
+
+
diff --git a/web/mobile/src/partials/site.php b/web/mobile/src/partials/site.php new file mode 100644 index 0000000..31908f2 --- /dev/null +++ b/web/mobile/src/partials/site.php @@ -0,0 +1,100 @@ + +

/

+

Demo-Seite: Hier renderst du später die echten Inhalte pro Bereich.

+ + +
+
+

Event Timeline

+
+
Bau fertig in 00:12:31
+
Forschung fertig in 01:02:10
+
Flotte ankommend in 00:07:55
+
+
+ +
+

Queues

+
+
+
BUILDMetallmine Stufe 12
+
+
ETA 00:12:31
+
+
+
RESEARCHAntriebstechnik Stufe 5
+
+
ETA 01:02:10
+
+
+
+
+ + +
+

Performance Profile

+

Speicherung ohne Cookies: sessionStorage (temporär) oder localStorage (merken).

+ +
+
+
Profil
+
+ + + + +
+
+ +
+ +
Wenn aus: nur sessionStorage.
+
+
+ +
+ + +
+
+ + +
+

Alert Pulse

+

Wähle: 3× Puls (Burst) oder dauerhaft (Loop).

+ +
+
+ + +
+ +
+ +
Wenn aus: nur sessionStorage.
+
+
+ +
+ + Demo Warning +
+
+ + +
+

Platzhalter

+

Hier kommt später die Seite für / .

+
+ +
+
+