import { useState, useEffect, useRef } from "react"; // ─── STYLES ────────────────────────────────────────────────────────────────── const GLOBAL_CSS = ` @import url('https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&family=Syne:wght@400;600;700;800&family=DM+Sans:ital,wght@0,300;0,400;0,500;1,300&display=swap'); *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } :root { --bg: #0a0a0f; --surface: #111118; --card: #16161f; --border: #1e1e2e; --border-lit: #2a2a3e; --accent: #e8ff47; --accent2: #47ffce; --accent3: #ff6b47; --accent4: #a78bfa; --text: #e8e8f0; --muted: #555568; --muted2: #333345; --font-mono: 'Space Mono', monospace; --font-display: 'Syne', sans-serif; --font-body: 'DM Sans', sans-serif; --radius: 12px; --radius-lg: 20px; --shadow: 0 4px 32px rgba(0,0,0,0.6); --glow: 0 0 24px rgba(232,255,71,0.15); --glow2: 0 0 24px rgba(71,255,206,0.15); } html, body, #root { height: 100%; width: 100%; background: var(--bg); } /* Scrollbar */ ::-webkit-scrollbar { width: 4px; } ::-webkit-scrollbar-track { background: var(--bg); } ::-webkit-scrollbar-thumb { background: var(--border-lit); border-radius: 2px; } /* Haptik-Button base */ .btn { font-family: var(--font-display); font-weight: 700; letter-spacing: 0.04em; cursor: pointer; border: none; outline: none; transition: all 0.12s cubic-bezier(0.34, 1.56, 0.64, 1); user-select: none; position: relative; overflow: hidden; } .btn:active { transform: scale(0.95) translateY(1px) !important; } .btn::after { content: ''; position: absolute; inset: 0; background: radial-gradient(circle at 50% 0%, rgba(255,255,255,0.12) 0%, transparent 60%); pointer-events: none; } .pulse { animation: pulse 2s cubic-bezier(0.4,0,0.6,1) infinite; } @keyframes pulse { 0%,100%{opacity:1} 50%{opacity:0.5} } @keyframes slideUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes scaleIn { from { opacity: 0; transform: scale(0.92); } to { opacity: 1; transform: scale(1); } } @keyframes shimmer { 0% { background-position: -200% center; } 100% { background-position: 200% center; } } @keyframes glow-pulse { 0%, 100% { box-shadow: 0 0 12px rgba(232,255,71,0.2); } 50% { box-shadow: 0 0 32px rgba(232,255,71,0.5); } } .slide-up { animation: slideUp 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) both; } .fade-in { animation: fadeIn 0.3s ease both; } .scale-in { animation: scaleIn 0.35s cubic-bezier(0.34, 1.56, 0.64, 1) both; } /* Noise texture overlay */ .noise::before { content: ''; position: fixed; inset: 0; background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='0.04'/%3E%3C/svg%3E"); pointer-events: none; z-index: 9999; opacity: 0.4; } `; // ─── HELPERS ───────────────────────────────────────────────────────────────── const now = () => new Date().toISOString(); const fmt = (iso) => { if (!iso) return "—"; const d = new Date(iso); return d.toLocaleDateString("de-DE", { day: "2-digit", month: "short", year: "numeric" }) + " · " + d.toLocaleTimeString("de-DE", { hour: "2-digit", minute: "2-digit" }); }; const fmtDate = (iso) => { if (!iso) return "—"; return new Date(iso).toLocaleDateString("de-DE", { day: "2-digit", month: "short" }); }; const STORAGE_KEY = "tmj_sessions_v1"; const loadSessions = () => { try { return JSON.parse(localStorage.getItem(STORAGE_KEY) || "[]"); } catch { return []; } }; const saveSessions = (s) => localStorage.setItem(STORAGE_KEY, JSON.stringify(s)); // ─── DATA ──────────────────────────────────────────────────────────────────── const MOODS = [ { id: "🔥", label: "Focused", color: "#ff6b47" }, { id: "😤", label: "Motivated", color: "#e8ff47" }, { id: "😌", label: "Calm", color: "#47ffce" }, { id: "😰", label: "Anxious", color: "#a78bfa" }, { id: "😤", label: "Frustrated", color: "#ff4747" }, { id: "😶", label: "Numb", color: "#555568" }, ]; const EMOTIONS = [ "Excited", "Confident", "Clear-headed", "Patient", "Impulsive", "FOMO", "Revenge-trading", "Overconfident", "Doubtful", "Tired", "Distracted", "Greedy", ]; const MARKET_CONDITIONS = ["Trending", "Ranging", "Volatile", "Choppy", "Low Volume"]; const SESSIONS_TYPES = ["Scalping", "Day Trade", "Swing", "Review Only"]; const RISK_LEVELS = ["1R", "2R", "3R", "Max", "Reduced"]; const BIASES = ["Bullish", "Bearish", "Neutral", "No Bias"]; const REVIEW_RATINGS = [1, 2, 3, 4, 5]; // ─── SUB COMPONENTS ────────────────────────────────────────────────────────── const Card = ({ children, style = {}, glow = false }) => (