Files
playbull/public/index.html
Mike 94b6cc3be9 Initial PlayBull release with Trilogy Hub integration.
Includes homelab deploy tooling, image position/zoom manifest persistence, and full trading/casino stack.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-02 08:31:36 +02:00

881 lines
47 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en" class="dark">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Trilogy Hub — Three Hustlers. One Vision.</title>
<meta name="description" content="Trilogy Hub — the personal brand home of three business partners: Magic Tree Co., NovaTerra Immobilien, and PG Trading Management." />
<!-- Favicon (custom SVG: three interlocking triangles) -->
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='7' fill='%230a0a0a'/%3E%3Cg fill='none' stroke='%23c9a84c' stroke-width='1.6' stroke-linejoin='round'%3E%3Cpath d='M16 6 L23 18 L9 18 Z'/%3E%3Cpath d='M10 14 L17 26 L3 26 Z' opacity='0.55'/%3E%3Cpath d='M22 14 L29 26 L15 26 Z' opacity='0.55'/%3E%3C/g%3E%3C/svg%3E" />
<!-- Fonts: Cabinet Grotesk (display) + Satoshi (body) via Fontshare -->
<link rel="preconnect" href="https://api.fontshare.com" crossorigin />
<link href="https://api.fontshare.com/v2/css?f[]=cabinet-grotesk@400,500,700,800,900&f[]=satoshi@400,500,700,900&display=swap" rel="stylesheet" />
<!-- Tailwind CSS v4 (CDN browser build) -->
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<!-- GSAP + ScrollTrigger -->
<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/ScrollTrigger.min.js"></script>
<!-- Splitting.js -->
<link rel="stylesheet" href="https://unpkg.com/splitting/dist/splitting.css" />
<script src="https://unpkg.com/splitting/dist/splitting.min.js"></script>
<!-- Lenis smooth scroll -->
<script src="https://unpkg.com/lenis@1.1.13/dist/lenis.min.js"></script>
<!-- Motion.js (Framer Motion vanilla) -->
<script src="https://cdn.jsdelivr.net/npm/motion@11.11.13/dist/motion.js"></script>
<!-- Lucide icons -->
<script src="https://unpkg.com/lucide@latest"></script>
<!-- Chart.js -->
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.4/dist/chart.umd.min.js"></script>
<style type="text/tailwindcss">
@theme {
--color-ink-900: #0a0a0a;
--color-ink-800: #111111;
--color-ink-700: #1a1a1a;
--color-ink-600: #242424;
--color-gold: #c9a84c;
--color-gold-soft: #d8bd6e;
--color-cream: #f4f1e9;
--color-success: #46c98b;
--color-error: #e0625e;
--font-display: "Cabinet Grotesk", ui-sans-serif, system-ui, sans-serif;
--font-body: "Satoshi", ui-sans-serif, system-ui, sans-serif;
}
</style>
<style>
:root {
--bg: #0a0a0a;
--bg-2: #111111;
--bg-3: #1a1a1a;
--surface: #161616;
--border: rgba(201, 168, 76, 0.18);
--border-soft: rgba(255, 255, 255, 0.08);
--text: #f4f1e9;
--text-dim: #a8a39a;
--text-faint: #6e6a62;
--gold: #c9a84c;
--gold-soft: #d8bd6e;
--success: #46c98b;
--error: #e0625e;
--ease: cubic-bezier(0.16, 1, 0.3, 1);
}
html:not(.dark) {
--bg: #f6f4ee;
--bg-2: #efece3;
--bg-3: #e7e3d8;
--surface: #ffffff;
--border: rgba(154, 124, 38, 0.28);
--border-soft: rgba(10, 10, 10, 0.1);
--text: #1a1712;
--text-dim: #4f4a40;
--text-faint: #7d7668;
--gold: #9a7c26;
--gold-soft: #b89537;
}
* { -webkit-font-smoothing: antialiased; }
html { scroll-behavior: auto; }
body {
background-color: var(--bg);
color: var(--text);
font-family: var(--font-body);
overflow-x: hidden;
transition: background-color 0.5s var(--ease), color 0.5s var(--ease);
}
.font-display { font-family: var(--font-display); }
::selection { background: var(--gold); color: #0a0a0a; }
/* Scrollbar */
::-webkit-scrollbar { width: 10px; }
::-webkit-scrollbar-track { background: var(--bg); }
::-webkit-scrollbar-thumb { background: var(--bg-3); border-radius: 8px; border: 2px solid var(--bg); }
::-webkit-scrollbar-thumb:hover { background: var(--gold); }
.text-dim { color: var(--text-dim); }
.text-faint { color: var(--text-faint); }
.text-gold { color: var(--gold); }
.bg-surface { background-color: var(--surface); }
.bg-ink2 { background-color: var(--bg-2); }
.bg-ink3 { background-color: var(--bg-3); }
.border-soft { border-color: var(--border-soft); }
.border-gold { border-color: var(--border); }
/* Section container */
.wrap { width: 100%; max-width: 1200px; margin-inline: auto; padding-inline: clamp(1.25rem, 4vw, 3rem); }
/* Pages */
.page { display: none; }
.page.active { display: block; }
/* Eyebrow label */
.eyebrow {
font-size: 0.75rem; letter-spacing: 0.22em; text-transform: uppercase;
color: var(--gold); font-weight: 700;
}
/* Buttons */
.btn {
display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
min-height: 44px; padding: 0.75rem 1.4rem; border-radius: 0.7rem;
font-weight: 700; font-size: 0.95rem; cursor: pointer;
transition: transform 0.4s var(--ease), box-shadow 0.4s var(--ease), background-color 0.3s var(--ease), color 0.3s var(--ease);
border: 1px solid transparent; text-decoration: none; line-height: 1;
}
.btn-primary { background: var(--gold); color: #0a0a0a; }
.btn-primary:hover { transform: scale(1.03); box-shadow: 0 10px 34px -8px rgba(201,168,76,0.55); }
.btn-ghost { background: transparent; color: var(--text); border-color: var(--border); }
.btn-ghost:hover { transform: scale(1.03); border-color: var(--gold); box-shadow: 0 10px 30px -12px rgba(201,168,76,0.4); }
.btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
/* Cards */
.card {
background: var(--surface); border: 1px solid var(--border-soft);
border-radius: 1.1rem; transition: transform 0.45s var(--ease), box-shadow 0.45s var(--ease), border-color 0.45s var(--ease);
}
.card-gold { border-color: var(--border); }
.card-hover:hover {
transform: translateY(-6px);
box-shadow: 0 24px 60px -24px rgba(0,0,0,0.7), 0 0 0 1px var(--border);
}
html:not(.dark) .card-hover:hover { box-shadow: 0 24px 50px -24px rgba(0,0,0,0.25), 0 0 0 1px var(--border); }
/* Photo upload slot */
.photo-slot {
position: relative; display: flex; align-items: center; justify-content: center;
flex-direction: column; gap: 0.6rem; cursor: pointer; overflow: hidden;
background: var(--bg-3); border: 1.5px dashed var(--gold);
border-radius: 1rem; color: var(--text-dim); text-align: center; padding: 1.5rem;
transition: border-color 0.4s var(--ease), background-color 0.4s var(--ease);
min-height: 180px;
}
.photo-slot:hover { border-color: var(--gold-soft); background: var(--bg-2); }
.photo-slot:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
.photo-slot .slot-icon { color: var(--gold); transition: transform 0.4s var(--ease); }
.photo-slot:hover .slot-icon { transform: translateY(-3px) scale(1.08); }
.photo-slot .slot-label { font-size: 0.8rem; font-weight: 600; letter-spacing: 0.02em; }
.photo-slot img.preview {
position: absolute; max-width: none; pointer-events: none;
opacity: 0; transition: opacity 0.6s var(--ease), filter 0.6s var(--ease);
border-radius: inherit; z-index: 2;
}
.photo-slot.has-image img.preview { opacity: 1; }
/* Subtle brightness lift on hover for uploaded images */
.photo-slot.has-image:hover img.preview { filter: saturate(1.08) brightness(1.04); }
/* Diagonal glossy shine that sweeps across images on hover */
.photo-slot.has-image::before {
content: ""; position: absolute; inset: 0; z-index: 3; pointer-events: none;
background: linear-gradient(115deg, transparent 30%, rgba(255,255,255,0.18) 48%, transparent 60%);
transform: translateX(-130%); transition: transform 0.85s var(--ease); border-radius: inherit;
}
.photo-slot.has-image:hover::before { transform: translateX(130%); }
/* Gentle gold ring glow when hovering an image */
.photo-slot.has-image:hover { box-shadow: 0 22px 55px -28px rgba(0,0,0,0.85), 0 0 0 1px var(--border); }
.photo-slot.has-image {
border-style: solid;
border-color: var(--border);
padding: 0;
}
.photo-slot .slot-default { display: flex; flex-direction: column; align-items: center; gap: 0.6rem; transition: opacity 0.4s var(--ease); z-index: 1; position: relative; }
.photo-slot .slot-hover-name {
position: absolute; inset: auto 0 0 0; padding: 0.6rem 0.9rem; z-index: 2;
background: linear-gradient(to top, rgba(0,0,0,0.82), transparent);
color: #fff; font-size: 0.78rem; font-weight: 600; opacity: 0;
transform: translateY(8px); transition: opacity 0.4s var(--ease), transform 0.4s var(--ease);
text-align: left;
}
.photo-slot.has-image:hover .slot-hover-name { opacity: 1; transform: translateY(0); }
/* Image position editor */
.img-editor-backdrop {
position: fixed; inset: 0; z-index: 200; display: flex; align-items: center; justify-content: center;
background: rgba(0,0,0,0.82); backdrop-filter: blur(10px); padding: 1.25rem;
}
.img-editor-modal { width: 100%; max-width: 420px; padding: 1.5rem; max-height: 92vh; overflow-y: auto; }
.img-editor-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.5rem; }
.img-editor-preview-outer { display: flex; justify-content: center; }
.img-editor-preview {
position: relative; overflow: hidden; background: var(--bg-3);
border: 2px solid var(--border); touch-action: none; cursor: grab;
}
.img-editor-preview:active { cursor: grabbing; }
.img-editor-preview img { position: absolute; max-width: none; pointer-events: none; user-select: none; }
.img-editor-range { width: 100%; accent-color: var(--gold); height: 6px; cursor: pointer; }
/* Nav */
.nav-link {
position: relative; font-weight: 500; color: var(--text-dim); font-size: 0.95rem;
padding: 0.4rem 0; transition: color 0.3s var(--ease); cursor: pointer; background: none; border: none;
}
.nav-link:hover, .nav-link.active { color: var(--text); }
.nav-link::after {
content: ""; position: absolute; left: 0; bottom: -2px; height: 2px; width: 0;
background: var(--gold); transition: width 0.4s var(--ease);
}
.nav-link:hover::after, .nav-link.active::after { width: 100%; }
/* Glass header */
.glass {
background: color-mix(in srgb, var(--bg) 72%, transparent);
backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
border-bottom: 1px solid var(--border-soft);
}
/* Animated reveal base (GSAP will animate). Fallback visible if no JS. */
.reveal { opacity: 0; transform: translateY(30px); }
.js-ready .reveal { will-change: opacity, transform; }
/* Splitting char stagger handled via GSAP, keep visible baseline */
.split-heading .char { display: inline-block; }
/* Hero gradient overlays */
.overlay-green { background: linear-gradient(135deg, rgba(8,30,18,0.92), rgba(10,10,10,0.7)); }
.overlay-navy { background: linear-gradient(135deg, rgba(10,18,38,0.92), rgba(10,10,10,0.7)); }
.overlay-dark { background: linear-gradient(135deg, rgba(10,10,10,0.9), rgba(10,10,10,0.55)); }
/* Price badge */
.badge {
display: inline-flex; align-items: center; gap: 0.3rem; padding: 0.35rem 0.7rem;
border-radius: 0.5rem; font-weight: 800; font-size: 0.85rem;
background: rgba(201,168,76,0.12); color: var(--gold); border: 1px solid var(--border);
}
.chip {
display: inline-flex; align-items: center; gap: 0.3rem; padding: 0.3rem 0.65rem;
border-radius: 999px; font-size: 0.78rem; font-weight: 600;
background: var(--bg-3); color: var(--text-dim); border: 1px solid var(--border-soft);
}
/* LIVE pulsing dot */
.live-dot { width: 8px; height: 8px; border-radius: 999px; background: var(--success); position: relative; }
.live-dot::after {
content: ""; position: absolute; inset: 0; border-radius: 999px; background: var(--success);
animation: ping 1.6s var(--ease) infinite;
}
@keyframes ping { 0% { transform: scale(1); opacity: 0.7; } 80%,100% { transform: scale(2.6); opacity: 0; } }
/* Price flash */
.flash-up { animation: flashUp 0.8s var(--ease); }
.flash-down { animation: flashDown 0.8s var(--ease); }
@keyframes flashUp { 0% { background: rgba(70,201,139,0.28); } 100% { background: transparent; } }
@keyframes flashDown { 0% { background: rgba(224,98,94,0.28); } 100% { background: transparent; } }
.text-success { color: var(--success); }
.text-error { color: var(--error); }
/* Modal */
.modal-backdrop {
position: fixed; inset: 0; z-index: 100; display: flex; align-items: center; justify-content: center;
background: rgba(0,0,0,0.78); backdrop-filter: blur(8px); padding: 1.25rem;
}
.input {
width: 100%; padding: 0.85rem 1rem; border-radius: 0.7rem; background: var(--bg-3);
border: 1px solid var(--border-soft); color: var(--text); font-size: 0.95rem; min-height: 44px;
transition: border-color 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
.input:focus { outline: none; border-color: var(--gold); box-shadow: 0 0 0 3px rgba(201,168,76,0.18); }
/* Masonry-ish reviews */
.masonry { columns: 1; column-gap: 1.25rem; }
@media (min-width: 640px) { .masonry { columns: 2; } }
@media (min-width: 1024px) { .masonry { columns: 3; } }
.masonry > * { break-inside: avoid; margin-bottom: 1.25rem; }
.divider { height: 1px; background: var(--border-soft); }
@media (prefers-reduced-motion: reduce) {
* { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; scroll-behavior: auto !important; }
.reveal { opacity: 1 !important; transform: none !important; }
}
.star { color: var(--gold); letter-spacing: 0.05em; }
/* ===================== ENHANCED EFFECTS ===================== */
/* Scroll progress bar (top of viewport) */
.scroll-progress {
position: fixed; top: 0; left: 0; height: 2.5px; width: 0%;
z-index: 60; transform-origin: left center;
background: linear-gradient(90deg, var(--gold), var(--gold-soft), var(--gold));
box-shadow: 0 0 12px rgba(201,168,76,0.6); will-change: width;
}
/* 3D tilt for cards — JS sets --rx/--ry, CSS handles the smoothing */
.card-hover {
transform-style: preserve-3d;
transform: perspective(900px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateY(0) translateZ(0);
transition: transform 0.5s var(--ease), box-shadow 0.45s var(--ease), border-color 0.45s var(--ease);
}
.card-hover.is-tilting { transition: box-shadow 0.45s var(--ease), border-color 0.45s var(--ease); }
.card-hover:hover {
transform: perspective(900px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateY(-6px) translateZ(0);
}
/* Glossy sweep on primary buttons */
.btn-primary { position: relative; overflow: hidden; isolation: isolate; }
.btn-primary::after {
content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
background: linear-gradient(115deg, transparent 35%, rgba(255,255,255,0.45) 50%, transparent 65%);
transform: translateX(-130%); transition: transform 0.7s var(--ease);
}
.btn-primary:hover::after { transform: translateX(130%); }
/* Floating ambient gradient orbs for hero sections */
.orbs { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: -1; }
.orb {
position: absolute; border-radius: 999px; filter: blur(60px); opacity: 0.5;
will-change: transform; mix-blend-mode: screen;
}
html:not(.dark) .orb { mix-blend-mode: multiply; opacity: 0.35; }
.orb-1 { width: 460px; height: 460px; top: -120px; left: -80px;
background: radial-gradient(circle, rgba(201,168,76,0.55), transparent 70%);
animation: orbFloat 18s ease-in-out infinite; }
.orb-2 { width: 380px; height: 380px; bottom: -140px; right: -60px;
background: radial-gradient(circle, rgba(47,158,143,0.4), transparent 70%);
animation: orbFloat 22s ease-in-out infinite reverse; }
@keyframes orbFloat {
0%, 100% { transform: translate(0, 0) scale(1); }
50% { transform: translate(40px, -30px) scale(1.12); }
}
/* Animated gold shimmer on the gold accent words */
.shimmer-gold {
background: linear-gradient(100deg, var(--gold) 0%, var(--gold-soft) 25%, #fff3cf 50%, var(--gold-soft) 75%, var(--gold) 100%);
background-size: 200% auto;
-webkit-background-clip: text; background-clip: text;
-webkit-text-fill-color: transparent; color: transparent;
animation: shimmerMove 6s linear infinite;
}
@keyframes shimmerMove { to { background-position: 200% center; } }
/* Image reveal with clip-path wipe (added by JS via .img-reveal) */
.img-reveal { clip-path: inset(0 0 100% 0); transition: clip-path 1s var(--ease); }
.img-reveal.is-in { clip-path: inset(0 0 0% 0); }
/* Nav underline gets a soft glow on active */
.nav-link.active::after { box-shadow: 0 0 10px rgba(201,168,76,0.7); }
/* Live ticker price cells subtle scale pop handled in JS via flash classes already */
/* ---- Mobile tuning: keep it smooth & tasteful on phones ---- */
@media (max-width: 767px) {
/* Big blurs are expensive on mobile GPUs — lighten them up */
.orb { filter: blur(42px); opacity: 0.4; }
.orb-1 { width: 280px; height: 280px; top: -80px; left: -60px; }
.orb-2 { width: 240px; height: 240px; bottom: -90px; right: -40px; }
.glass { backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }
/* No hover on touch, so neutralise tilt vars for crisp rendering */
.card-hover { transform: none; }
.card-hover:hover { transform: translateY(-4px); }
/* Card tap feedback for touch devices */
.card-hover:active { transform: scale(0.985); transition: transform 0.15s var(--ease); }
.btn:active { transform: scale(0.96); }
.scroll-progress { height: 2px; }
/* Make sure the diagonal image shine isn't stuck mid-frame on touch */
.photo-slot.has-image::before { display: none; }
}
@media (prefers-reduced-motion: reduce) {
.orb { animation: none; }
.shimmer-gold { animation: none; }
.img-reveal { clip-path: none !important; }
.card-hover { transform: none !important; }
.scroll-progress { display: none; }
}
</style>
</head>
<body>
<!-- Scroll progress indicator -->
<div class="scroll-progress" id="scrollProgress" aria-hidden="true"></div>
<!-- ================= HEADER / NAV ================= -->
<header class="glass fixed top-0 inset-x-0 z-50">
<nav class="wrap flex items-center justify-between h-[68px]" aria-label="Primary">
<a href="#home" class="flex items-center gap-2.5 group" aria-label="Trilogy Hub home">
<svg width="34" height="34" viewBox="0 0 32 32" aria-hidden="true">
<g fill="none" stroke="var(--gold)" stroke-width="1.7" stroke-linejoin="round">
<path d="M16 5 L24 19 L8 19 Z" />
<path d="M9 13 L17 27 L1 27 Z" opacity="0.55" />
<path d="M23 13 L31 27 L15 27 Z" opacity="0.55" />
</g>
</svg>
<span class="font-display font-extrabold text-lg tracking-tight">Trilogy<span class="text-gold">Hub</span></span>
</a>
<div class="hidden md:flex items-center gap-7">
<button class="nav-link" data-route="home">Home</button>
<button class="nav-link" data-route="magic-mike">Magic Tree Co.</button>
<button class="nav-link" data-route="nico">NovaTerra</button>
<button class="nav-link" data-route="paris">PG Trading</button>
<button class="nav-link" data-route="casino" data-members hidden>Casino</button>
</div>
<div class="flex items-center gap-2">
<button id="themeToggle" class="btn btn-ghost !p-2.5 !min-h-0 w-11 h-11" aria-label="Toggle light and dark mode" title="Toggle theme">
<i data-lucide="moon" class="block dark:hidden w-5 h-5"></i>
<i data-lucide="sun" class="hidden dark:block w-5 h-5"></i>
</button>
<button id="menuToggle" class="btn btn-ghost !p-2.5 !min-h-0 w-11 h-11 md:hidden" aria-label="Open menu" aria-expanded="false">
<i data-lucide="menu" class="w-5 h-5"></i>
</button>
</div>
</nav>
<!-- Mobile menu -->
<div id="mobileMenu" class="md:hidden hidden border-t border-soft bg-ink2">
<div class="wrap py-4 flex flex-col gap-1">
<button class="nav-link text-left py-3" data-route="home">Home</button>
<button class="nav-link text-left py-3" data-route="magic-mike">Magic Tree Co.</button>
<button class="nav-link text-left py-3" data-route="nico">NovaTerra Immobilien</button>
<button class="nav-link text-left py-3" data-route="paris">PG Trading Management</button>
<button class="nav-link text-left py-3" data-route="casino" data-members hidden>🎰 Casino & Games</button>
</div>
</div>
</header>
<main id="app" class="pt-[68px]">
<!-- ============================================================= -->
<!-- ============================ HOME ============================ -->
<!-- ============================================================= -->
<section id="page-home" class="page" aria-label="Home">
<!-- Hero -->
<div class="relative overflow-hidden">
<div class="orbs" aria-hidden="true" data-parallax="0.08"><span class="orb orb-1"></span><span class="orb orb-2"></span></div>
<div class="absolute inset-0 -z-10 opacity-[0.05]" style="background-image: radial-gradient(circle at 1px 1px, var(--gold) 1px, transparent 0); background-size: 28px 28px;"></div>
<div class="wrap pt-20 pb-16 md:pt-28 md:pb-24 text-center">
<p class="eyebrow reveal mb-5">Trees · Properties · Markets</p>
<h1 class="split-heading font-display font-black leading-[0.95] tracking-tight text-[clamp(2.6rem,8vw,6rem)]" data-splitting>
Three Hustlers.<br /><span class="text-gold shimmer-gold">One Vision.</span>
</h1>
<p class="reveal text-dim max-w-2xl mx-auto mt-7 text-lg md:text-xl">
Trees. Properties. Markets. We don't just talk — we build.
</p>
<div class="reveal flex flex-wrap items-center justify-center gap-3 mt-9">
<button class="btn btn-primary" data-route="magic-mike">Explore the Hub <i data-lucide="arrow-right" class="w-4 h-4"></i></button>
<button class="btn btn-ghost" data-route="paris">Trading Dashboard</button>
</div>
<!-- Three partner cards with photo slots -->
<div class="grid sm:grid-cols-3 gap-5 mt-16 text-left">
<article class="reveal card card-gold card-hover p-3" >
<div class="photo-slot !min-h-[260px]" data-slot="Magic Mike" tabindex="0" role="button" aria-label="Upload photo of Magic Mike">
<div class="slot-default"><i data-lucide="image-plus" class="slot-icon w-7 h-7"></i><span class="slot-label">Magic Mike</span></div>
<img class="preview" alt="Magic Mike" />
<span class="slot-hover-name">Magic Mike</span>
</div>
<div class="p-4">
<h3 class="font-display font-bold text-lg">Magic Mike</h3>
<p class="text-dim text-sm mt-1">Founder · Magic Tree Co.</p>
</div>
</article>
<article class="reveal card card-gold card-hover p-3">
<div class="photo-slot !min-h-[260px]" data-slot="Nico Gonzales" tabindex="0" role="button" aria-label="Upload photo of Nico Gonzales">
<div class="slot-default"><i data-lucide="image-plus" class="slot-icon w-7 h-7"></i><span class="slot-label">Nico Gonzales</span></div>
<img class="preview" alt="Nico Gonzales" />
<span class="slot-hover-name">Nico Gonzales</span>
</div>
<div class="p-4">
<h3 class="font-display font-bold text-lg">Nico Gonzales</h3>
<p class="text-dim text-sm mt-1">Broker · NovaTerra Immobilien</p>
</div>
</article>
<article class="reveal card card-gold card-hover p-3">
<div class="photo-slot !min-h-[260px]" data-slot="Paris" tabindex="0" role="button" aria-label="Upload photo of Paris">
<div class="slot-default"><i data-lucide="image-plus" class="slot-icon w-7 h-7"></i><span class="slot-label">Paris</span></div>
<img class="preview" alt="Paris" />
<span class="slot-hover-name">Paris</span>
</div>
<div class="p-4">
<h3 class="font-display font-bold text-lg">Paris</h3>
<p class="text-dim text-sm mt-1">Strategist · PG Trading Management</p>
</div>
</article>
</div>
</div>
</div>
<!-- Our Story -->
<div class="bg-ink2 border-y border-soft">
<div class="wrap py-20 md:py-28 grid md:grid-cols-2 gap-12 items-center">
<div class="reveal">
<p class="eyebrow mb-4">Our Story</p>
<h2 class="font-display font-extrabold text-[clamp(1.9rem,4vw,3rem)] leading-tight mb-6">It started with a handshake and a vision.</h2>
<p class="text-dim text-lg leading-relaxed mb-4">
Mike plants the seeds — literally. Nico turns land into legacy. Paris reads the market like a map.
Together, we invest in each other's ventures and grow as one unit.
</p>
<p class="text-dim text-lg leading-relaxed">
PG Trading Management finances stakes in Nico's real estate portfolio. Magic Tree supplies rare ornamental
trees to Nico's high-end property projects. <span class="text-gold font-semibold shimmer-gold">Three businesses. One ecosystem.</span>
</p>
</div>
<div class="photo-slot !min-h-[360px]" data-slot="Team Photo" tabindex="0" role="button" aria-label="Upload team photo">
<div class="slot-default"><i data-lucide="users" class="slot-icon w-8 h-8"></i><span class="slot-label">Team Photo</span></div>
<img class="preview" alt="Team photo" />
<span class="slot-hover-name">Team Photo</span>
</div>
</div>
</div>
<!-- Team Cards -->
<div class="wrap py-20 md:py-28">
<div class="text-center mb-14 reveal">
<p class="eyebrow mb-4">The Trilogy</p>
<h2 class="font-display font-extrabold text-[clamp(1.9rem,4vw,3rem)]">Three founders, three crafts.</h2>
</div>
<div class="grid md:grid-cols-3 gap-6">
<article class="reveal card card-gold card-hover p-7 flex flex-col">
<i data-lucide="trees" class="w-9 h-9 text-gold mb-5"></i>
<h3 class="font-display font-bold text-2xl">Magic Mike</h3>
<p class="text-gold text-sm font-semibold mt-1 mb-3">Magic Tree Co.</p>
<p class="text-dim leading-relaxed flex-1">Rare and ornamental trees for luxury gardens — from Japanese Maples to 300-year-old olive trees.</p>
<button class="btn btn-ghost mt-6 self-start" data-route="magic-mike">Visit Page <i data-lucide="arrow-up-right" class="w-4 h-4"></i></button>
</article>
<article class="reveal card card-gold card-hover p-7 flex flex-col">
<i data-lucide="building-2" class="w-9 h-9 text-gold mb-5"></i>
<h3 class="font-display font-bold text-2xl">Nico Gonzales</h3>
<p class="text-gold text-sm font-semibold mt-1 mb-3">NovaTerra Immobilien</p>
<p class="text-dim leading-relaxed flex-1">Premium real estate across Baden-Württemberg — buying, selling, and developing property into legacy.</p>
<button class="btn btn-ghost mt-6 self-start" data-route="nico">Visit Page <i data-lucide="arrow-up-right" class="w-4 h-4"></i></button>
</article>
<article class="reveal card card-gold card-hover p-7 flex flex-col">
<i data-lucide="line-chart" class="w-9 h-9 text-gold mb-5"></i>
<h3 class="font-display font-bold text-2xl">Paris</h3>
<p class="text-gold text-sm font-semibold mt-1 mb-3">PG Trading Management</p>
<p class="text-dim leading-relaxed flex-1">Real markets, no risk, full thrill. A paper-trading dashboard powered by live-simulated prices.</p>
<button class="btn btn-ghost mt-6 self-start" data-route="paris">Visit Page <i data-lucide="arrow-up-right" class="w-4 h-4"></i></button>
</article>
</div>
</div>
</section>
<!-- ============================================================= -->
<!-- ========================= MAGIC MIKE ========================= -->
<!-- ============================================================= -->
<section id="page-magic-mike" class="page" aria-label="Magic Mike — Magic Tree Co.">
<!-- Hero -->
<div class="relative min-h-[72vh] flex items-center overflow-hidden">
<div class="photo-slot absolute inset-0 !rounded-none !border-0 !min-h-0" data-slot="Hero Background" tabindex="0" role="button" aria-label="Upload hero background">
<div class="slot-default"><i data-lucide="image" class="slot-icon w-8 h-8"></i><span class="slot-label">Hero Background</span></div>
<img class="preview" alt="Magic Tree Co. hero" data-parallax-img="0.16" />
</div>
<div class="absolute inset-0 overlay-green pointer-events-none"></div>
<div class="wrap relative py-24 text-center md:text-left">
<p class="eyebrow mb-4">Magic Tree Co.</p>
<h1 class="split-heading font-display font-black text-[clamp(2.4rem,7vw,5.2rem)] leading-[0.95] max-w-3xl" data-splitting>Every Garden Tells a Story</h1>
<p class="reveal text-dim text-lg mt-6 max-w-xl">Premium ornamental trees, delivered with craftsmanship and a guarantee.</p>
</div>
</div>
<!-- About -->
<div class="wrap py-20 md:py-28 grid md:grid-cols-2 gap-12 items-center">
<div class="photo-slot !min-h-[380px]" data-slot="Mike's Portrait" tabindex="0" role="button" aria-label="Upload Mike's portrait">
<div class="slot-default"><i data-lucide="user" class="slot-icon w-8 h-8"></i><span class="slot-label">Mike's Portrait</span></div>
<img class="preview" alt="Mike portrait" />
<span class="slot-hover-name">Mike's Portrait</span>
</div>
<div class="reveal">
<p class="eyebrow mb-4">About Mike</p>
<h2 class="font-display font-extrabold text-[clamp(1.8rem,4vw,2.8rem)] mb-6 leading-tight">Where nature meets craftsmanship.</h2>
<p class="text-dim text-lg leading-relaxed">
Mike has been cultivating rare and ornamental trees for over a decade. From Japanese Maples to Giant
Sequoias, every tree he sells carries a story and a guarantee. Magic Tree Co. is more than a nursery —
it's where nature meets craftsmanship.
</p>
</div>
</div>
<!-- Products -->
<div class="bg-ink2 border-y border-soft">
<div class="wrap py-20 md:py-28">
<div class="mb-12 reveal">
<p class="eyebrow mb-4">The Collection</p>
<h2 class="font-display font-extrabold text-[clamp(1.8rem,4vw,2.8rem)]">Featured Trees</h2>
</div>
<div class="grid sm:grid-cols-2 lg:grid-cols-4 gap-6" id="mikeProducts"></div>
</div>
</div>
<!-- Reviews -->
<div class="wrap py-20 md:py-28">
<div class="mb-12 reveal">
<p class="eyebrow mb-4">Word of Mouth</p>
<h2 class="font-display font-extrabold text-[clamp(1.8rem,4vw,2.8rem)]">Customer Reviews</h2>
</div>
<div class="masonry" id="mikeReviews"></div>
</div>
<!-- Happy Customers Gallery -->
<div class="bg-ink2 border-y border-soft">
<div class="wrap py-20 md:py-28">
<div class="mb-12 reveal">
<p class="eyebrow mb-4">Happy Customers</p>
<h2 class="font-display font-extrabold text-[clamp(1.8rem,4vw,2.8rem)]">Their Gardens, Transformed</h2>
</div>
<div class="grid grid-cols-2 md:grid-cols-3 gap-5" id="mikeGallery"></div>
</div>
</div>
</section>
<!-- ============================================================= -->
<!-- ============================ NICO ============================ -->
<!-- ============================================================= -->
<section id="page-nico" class="page" aria-label="Nico Gonzales — NovaTerra Immobilien">
<!-- Hero -->
<div class="relative min-h-[72vh] flex items-center overflow-hidden">
<div class="photo-slot absolute inset-0 !rounded-none !border-0 !min-h-0" data-slot="Hero Background" tabindex="0" role="button" aria-label="Upload hero background">
<div class="slot-default"><i data-lucide="image" class="slot-icon w-8 h-8"></i><span class="slot-label">Hero Background</span></div>
<img class="preview" alt="NovaTerra hero" data-parallax-img="0.16" />
</div>
<div class="absolute inset-0 overlay-navy pointer-events-none"></div>
<div class="wrap relative py-24 text-center md:text-left">
<p class="eyebrow mb-4">NovaTerra Immobilien · New Ground. New Possibilities.</p>
<h1 class="split-heading font-display font-black text-[clamp(2.4rem,7vw,5.2rem)] leading-[0.95] max-w-3xl" data-splitting>Your Property. Your Legacy.</h1>
<p class="reveal text-dim text-lg mt-6 max-w-xl">Premium real estate, brokered with discretion and results.</p>
</div>
</div>
<!-- About -->
<div class="wrap py-20 md:py-28 grid md:grid-cols-2 gap-12 items-center">
<div class="reveal">
<p class="eyebrow mb-4">About Nico</p>
<h2 class="font-display font-extrabold text-[clamp(1.8rem,4vw,2.8rem)] mb-6 leading-tight">Closing premium deals across the region.</h2>
<p class="text-dim text-lg leading-relaxed">
Nico Gonzales has been closing premium real estate deals across Baden-Württemberg for years. With a network
spanning developers, investors, and private buyers, NovaTerra Immobilien is your partner for buying, selling,
and developing property — backed by the investment muscle of PG Trading Management.
</p>
</div>
<div class="photo-slot !min-h-[380px]" data-slot="Nico's Headshot" tabindex="0" role="button" aria-label="Upload Nico's headshot">
<div class="slot-default"><i data-lucide="user" class="slot-icon w-8 h-8"></i><span class="slot-label">Nico's Headshot</span></div>
<img class="preview" alt="Nico headshot" />
<span class="slot-hover-name">Nico's Headshot</span>
</div>
</div>
<!-- Listings -->
<div class="bg-ink2 border-y border-soft">
<div class="wrap py-20 md:py-28">
<div class="mb-12 reveal">
<p class="eyebrow mb-4">Portfolio</p>
<h2 class="font-display font-extrabold text-[clamp(1.8rem,4vw,2.8rem)]">Featured Listings</h2>
</div>
<div class="grid sm:grid-cols-2 gap-6" id="nicoListings"></div>
</div>
</div>
<!-- Testimonials -->
<div class="wrap py-20 md:py-28">
<div class="mb-12 reveal">
<p class="eyebrow mb-4">Trusted By</p>
<h2 class="font-display font-extrabold text-[clamp(1.8rem,4vw,2.8rem)]">Client Testimonials</h2>
</div>
<div class="grid sm:grid-cols-2 gap-6" id="nicoTestimonials"></div>
</div>
<!-- Gallery -->
<div class="bg-ink2 border-y border-soft">
<div class="wrap py-20 md:py-28">
<div class="mb-12 reveal">
<p class="eyebrow mb-4">Moments</p>
<h2 class="font-display font-extrabold text-[clamp(1.8rem,4vw,2.8rem)]">Deals & Handshakes</h2>
</div>
<div class="grid grid-cols-2 md:grid-cols-3 gap-5" id="nicoGallery"></div>
</div>
</div>
</section>
<!-- ============================================================= -->
<!-- =========================== PARIS =========================== -->
<!-- ============================================================= -->
<section id="page-paris" class="page" aria-label="Paris — PG Trading Management">
<!-- Login gate -->
<div id="parisLogin" class="wrap py-24 md:py-32">
<div class="max-w-md mx-auto text-center mb-10 reveal">
<i data-lucide="line-chart" class="w-12 h-12 text-gold mx-auto mb-5"></i>
<p class="eyebrow mb-3">PG Trading Management</p>
<h1 class="font-display font-black text-[clamp(2rem,6vw,3.4rem)] leading-tight">Your Portfolio. Your Game.</h1>
<p class="text-dim mt-4 text-lg">Real markets. No risk. Full thrill.</p>
</div>
<form id="loginForm" class="card card-gold max-w-md mx-auto p-8" novalidate>
<h2 class="font-display font-bold text-xl mb-1">Member Login</h2>
<p class="text-faint text-sm mb-6">Demo access — user: <span class="text-gold">paris</span> / pass: <span class="text-gold">trading123</span></p>
<label class="block text-sm font-semibold mb-2" for="username">Username</label>
<input class="input mb-4" type="text" id="username" name="username" autocomplete="username" placeholder="paris" />
<label class="block text-sm font-semibold mb-2" for="password">Password</label>
<input class="input mb-2" type="password" id="password" name="password" autocomplete="current-password" placeholder="••••••••" />
<p id="loginError" class="text-error text-sm h-5 mb-2" role="alert"></p>
<button type="submit" class="btn btn-primary w-full">Log In <i data-lucide="lock-open" class="w-4 h-4"></i></button>
</form>
</div>
<!-- Dashboard -->
<div id="parisDashboard" class="hidden">
<!-- Dashboard navbar -->
<div class="bg-ink2 border-b border-soft">
<div class="wrap flex flex-wrap items-center justify-between gap-4 py-4">
<div class="flex items-center gap-3">
<i data-lucide="line-chart" class="w-6 h-6 text-gold"></i>
<span class="font-display font-bold">PG Trading <span class="text-gold">Management</span></span>
<span class="chip ml-2"><span class="live-dot"></span> LIVE</span>
<span class="chip text-gold">Play Money</span>
</div>
<div class="flex items-center gap-4">
<div class="text-right">
<p class="text-faint text-xs">Portfolio</p>
<p class="font-display font-bold text-gold" data-counter="7334899.31" data-prefix="€" data-decimals="2">€7,334,899.31</p>
</div>
<span class="chip">Logged in as Paris</span>
<button id="logoutBtn" class="btn btn-ghost !min-h-0 !py-2.5">Logout <i data-lucide="log-out" class="w-4 h-4"></i></button>
</div>
</div>
</div>
<div class="wrap py-12">
<!-- KPI cards -->
<div class="grid grid-cols-2 lg:grid-cols-4 gap-4 mb-10">
<div class="card p-5">
<p class="text-faint text-xs uppercase tracking-wider mb-2">Portfolio Value</p>
<p class="font-display font-extrabold text-2xl" data-counter="7334899.31" data-prefix="€" data-decimals="2">€7,334,899.31</p>
</div>
<div class="card p-5">
<p class="text-faint text-xs uppercase tracking-wider mb-2">Today's P&L</p>
<p class="font-display font-extrabold text-2xl text-success"><span data-counter="48213.55" data-prefix="+€" data-decimals="2">+€48,213.55</span> <span class="text-sm">(+0.66%)</span></p>
</div>
<div class="card p-5">
<p class="text-faint text-xs uppercase tracking-wider mb-2">Open Positions</p>
<p class="font-display font-extrabold text-2xl" data-counter="10" data-decimals="0">10</p>
</div>
<div class="card p-5">
<p class="text-faint text-xs uppercase tracking-wider mb-2">Buying Power</p>
<p class="font-display font-extrabold text-2xl" data-counter="57539.31" data-prefix="€" data-decimals="2">€57,539.31</p>
</div>
</div>
<div class="grid lg:grid-cols-3 gap-8">
<!-- Watchlist -->
<div class="lg:col-span-2">
<h2 class="font-display font-bold text-xl mb-4 flex items-center gap-2"><i data-lucide="list" class="w-5 h-5 text-gold"></i> Watchlist</h2>
<div class="card overflow-hidden">
<div class="overflow-x-auto">
<table class="w-full text-sm" id="watchlistTable">
<thead>
<tr class="text-faint text-left border-b border-soft">
<th class="py-3 px-4 font-semibold">Ticker</th>
<th class="py-3 px-4 font-semibold">Company</th>
<th class="py-3 px-4 font-semibold text-right">Shares</th>
<th class="py-3 px-4 font-semibold text-right">Avg Buy</th>
<th class="py-3 px-4 font-semibold text-right">Price</th>
<th class="py-3 px-4 font-semibold text-right">P&L</th>
<th class="py-3 px-4 font-semibold text-right">P&L%</th>
</tr>
</thead>
<tbody id="watchlistBody"></tbody>
</table>
</div>
</div>
<!-- Trade log -->
<h2 class="font-display font-bold text-xl mt-10 mb-4 flex items-center gap-2"><i data-lucide="history" class="w-5 h-5 text-gold"></i> Trade Log</h2>
<div class="card divide-y" id="tradeLog" style="--tw-divide-opacity:1"></div>
</div>
<!-- Pie chart -->
<div>
<h2 class="font-display font-bold text-xl mb-4 flex items-center gap-2"><i data-lucide="pie-chart" class="w-5 h-5 text-gold"></i> Allocation</h2>
<div class="card p-6">
<canvas id="allocationChart" height="260"></canvas>
<div id="chartLegend" class="mt-5 space-y-2 text-sm"></div>
</div>
</div>
</div>
</div>
<!-- Disclaimer -->
<div class="bg-ink2 border-t border-soft">
<div class="wrap py-4 text-center text-faint text-sm flex items-center justify-center gap-2">
<i data-lucide="alert-triangle" class="w-4 h-4 text-gold shrink-0"></i>
<span>PG Trading Management is a simulation platform for entertainment purposes only. No real money is involved. Not financial advice.</span>
</div>
</div>
</div>
</section>
<!-- ============================================================= -->
<!-- ========================== CASINO =========================== -->
<!-- ============================================================= -->
<section id="page-casino" class="page" aria-label="PlayBull Casino & Games">
<!-- Login gate (shown when not authenticated) -->
<div id="casinoGate" class="wrap py-24 md:py-32 hidden">
<div class="max-w-md mx-auto text-center reveal">
<i data-lucide="dices" class="w-12 h-12 text-gold mx-auto mb-5"></i>
<p class="eyebrow mb-3">Members Only</p>
<h1 class="font-display font-black text-[clamp(2rem,6vw,3.4rem)] leading-tight">Casino &amp; Games</h1>
<p class="text-dim mt-4 text-lg">Chicken Road, 10×10 Deck, Crash &amp; mehr — mit deinem PlayBull-Konto.</p>
<button class="btn btn-primary mt-8" id="casinoLoginBtn">Einloggen / Registrieren <i data-lucide="log-in" class="w-4 h-4"></i></button>
</div>
</div>
<!-- Embedded full PlayBull arcade (shares the same login + balance) -->
<div id="casinoFrameWrap" class="hidden">
<div class="bg-ink2 border-b border-soft">
<div class="wrap flex flex-wrap items-center justify-between gap-3 py-4">
<div class="flex items-center gap-3">
<i data-lucide="dices" class="w-6 h-6 text-gold"></i>
<span class="font-display font-bold">PlayBull <span class="text-gold">Arcade</span></span>
<span class="chip"><span class="live-dot"></span> LIVE</span>
<span class="chip text-gold">Play Money</span>
</div>
<a href="/play.html" target="_blank" rel="noopener" class="btn btn-ghost !min-h-0 !py-2.5">Vollbild öffnen <i data-lucide="external-link" class="w-4 h-4"></i></a>
</div>
</div>
<iframe id="casinoFrame" title="PlayBull Arcade" style="width:100%;height:calc(100vh - 68px - 64px);border:0;display:block;background:var(--bg)"></iframe>
</div>
</section>
</main>
<!-- ================= FOOTER ================= -->
<footer class="bg-ink2 border-t border-soft">
<div class="wrap py-12 flex flex-col md:flex-row items-center justify-between gap-6">
<div class="flex items-center gap-2.5">
<svg width="28" height="28" viewBox="0 0 32 32" aria-hidden="true">
<g fill="none" stroke="var(--gold)" stroke-width="1.7" stroke-linejoin="round">
<path d="M16 5 L24 19 L8 19 Z" /><path d="M9 13 L17 27 L1 27 Z" opacity="0.55" /><path d="M23 13 L31 27 L15 27 Z" opacity="0.55" />
</g>
</svg>
<span class="font-display font-extrabold">Trilogy<span class="text-gold">Hub</span></span>
</div>
<nav class="flex flex-wrap items-center justify-center gap-6" aria-label="Footer">
<button class="nav-link" data-route="magic-mike">Magic Tree Co.</button>
<button class="nav-link" data-route="nico">NovaTerra Immobilien</button>
<button class="nav-link" data-route="paris">PG Trading Management</button>
<button class="nav-link" data-route="casino" data-members hidden>Casino &amp; Games</button>
</nav>
</div>
<div class="wrap pb-8 text-faint text-sm text-center md:text-left">
Trilogy Hub © 2025 — Built by three, grown together.
</div>
</footer>
<!-- ================= SCRIPTS ================= -->
<script src="/socket.io/socket.io.js"></script>
<script src="image-editor.js"></script>
<script src="app.js"></script>
<script src="playbull.js"></script>
</body>
</html>