<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<title>8IE TIME</title>
<style>
:root{
--accent:#00C805; --accent-dim:#00c80522; --ink:#0b0b0b; --paper:#F4F1E9; --paper2:#ffffff;
--line:#0b0b0b; --sub:#6b6b66; --mono:'SF Mono','JetBrains Mono',Menlo,Consolas,monospace;
padding-top:env(safe-area-inset-top,0px); padding-bottom:env(safe-area-inset-bottom,0px); box-sizing:border-box;
}
*{box-sizing:border-box; -webkit-tap-highlight-color:transparent;}
html,body{height:100%; margin:0; overflow:hidden; background:#d9d4c6;}
body{
font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;
display:flex; align-items:center; justify-content:center; min-height:100%; color:var(--ink);
background:repeating-linear-gradient(135deg,#d9d4c6,#d9d4c6 2px,#d3cec0 2px,#d3cec0 4px);
}
.phone{
position:relative; width:min(94vw,420px); height:min(94vh,86vh); max-height:840px;
border-radius:22px; overflow:hidden; background:var(--paper);
border:3px solid var(--ink); box-shadow:10px 10px 0 var(--ink);
}
.track{ position:relative; z-index:1; display:flex; width:300%; height:100%; transition:transform .48s cubic-bezier(.65,0,.35,1); }
.screen{ width:33.3334%; height:100%; flex-shrink:0; position:relative; overflow:hidden; display:flex; flex-direction:column; }
.hdr{ flex-shrink:0; padding:18px 20px 10px; display:flex; align-items:center; justify-content:space-between; border-bottom:3px solid var(--ink); background:var(--paper2); }
.hdr .mark{ font-weight:900; font-size:15px; letter-spacing:.02em; display:flex; align-items:center; gap:7px; }
.hdr .mark .sq{ width:11px; height:11px; background:var(--accent); border:2px solid var(--ink); transition:background .3s; }
.hdr .tag{ font-family:var(--mono); font-size:9.5px; color:var(--sub); letter-spacing:.06em; text-transform:uppercase; border:1.5px solid var(--ink); padding:3px 8px; border-radius:20px; }
/* ---------- WATCH SCREEN ---------- */
#watchScreen{ display:flex; flex-direction:column; height:100%; }
.watch-body{ flex:1; min-height:0; display:flex; flex-direction:column; align-items:center; justify-content:center; padding:14px 20px 10px; overflow:hidden; }
.stage-wrap{ position:relative; width:100%; max-width:280px; flex:0 1 auto; min-height:0; }
.stage{ width:100%; max-height:44vh; aspect-ratio:660/800; margin:0 auto; display:block; filter:drop-shadow(6px 8px 0 rgba(0,0,0,.15)); animation:riseIn .6s cubic-bezier(.2,.9,.25,1); }
@keyframes riseIn{ from{opacity:0; transform:translateY(16px);} to{opacity:1; transform:translateY(0);} }
svg{ width:100%; height:100%; display:block; overflow:visible; }
.info-strip{ width:100%; max-width:280px; margin-top:12px; display:flex; gap:8px; flex-shrink:0; }
.info-chip{ flex:1; border:2px solid var(--ink); background:var(--paper2); border-radius:10px; padding:8px 9px; text-align:center; }
.info-chip .k{ font-family:var(--mono); font-size:8.5px; color:var(--sub); letter-spacing:.1em; text-transform:uppercase; }
.info-chip .v{ font-family:var(--mono); font-size:12px; font-weight:700; margin-top:2px; }
.info-chip .v b{ color:var(--accent); }
.pulse-sq{ display:inline-block; width:6px; height:6px; background:var(--accent); margin-right:4px; animation:blink 1.6s ease-in-out infinite; }
@keyframes blink{ 0%,100%{opacity:1;} 50%{opacity:.2;} }
/* ---------- BOTTOM TAB BAR (shared) ---------- */
.tabbar{ flex-shrink:0; z-index:4; display:flex; border-top:3px solid var(--ink); background:var(--paper2); }
.tabbtn{ flex:1; border:none; background:transparent; padding:13px 4px 10px; display:flex; flex-direction:column; align-items:center; gap:4px; cursor:pointer; border-right:2px solid var(--ink); color:var(--sub); }
.tabbtn:last-child{ border-right:none; }
.tabbtn svg{ width:19px; height:19px; stroke:var(--sub); transition:stroke .2s; }
.tabbtn span{ font-family:var(--mono); font-size:9px; font-weight:700; letter-spacing:.04em; text-transform:uppercase; }
.tabbtn.active{ background:var(--accent); color:var(--ink); }
.tabbtn.active svg{ stroke:var(--ink); }
/* ---------- SETTINGS SCREEN ---------- */
.settings-inner{ flex:1; min-height:0; overflow-y:auto; padding:18px 18px 24px; }
.pagetitle{ font-size:26px; font-weight:900; letter-spacing:-.02em; }
.pagesub{ font-family:var(--mono); font-size:11px; color:var(--sub); margin:4px 0 18px; }
.card{ background:var(--paper2); border:2.5px solid var(--ink); border-radius:14px; padding:16px; margin-bottom:12px; box-shadow:4px 4px 0 var(--ink); animation:fadeUp .45s cubic-bezier(.2,.9,.25,1) both; }
.card:nth-of-type(1){animation-delay:.02s;} .card:nth-of-type(2){animation-delay:.06s;} .card:nth-of-type(3){animation-delay:.1s;} .card:nth-of-type(4){animation-delay:.14s;}
@keyframes fadeUp{ from{opacity:0; transform:translateY(10px);} to{opacity:1; transform:translateY(0);} }
.card-label{ font-family:var(--mono); font-size:11px; font-weight:800; letter-spacing:.08em; text-transform:uppercase; margin-bottom:12px; display:flex; align-items:center; gap:7px; }
.card-label .bar{ width:4px; height:14px; background:var(--accent); }
input[type="date"], input[type="time"], select{
width:100%; background:var(--paper); border:2px solid var(--ink); color:var(--ink);
border-radius:9px; padding:11px 12px; font-size:14.5px; font-family:var(--mono); font-weight:600;
outline:none; appearance:none;
}
.row2{ display:flex; gap:9px; }
.row2 > div{ flex:1; }
.field-sub{ font-family:var(--mono); font-size:10px; color:var(--sub); margin-top:9px; line-height:1.5; }
.apply-btn{
width:100%; margin-top:10px; background:var(--accent); color:var(--ink); border:2.5px solid var(--ink); border-radius:9px;
padding:12px; font-weight:800; font-size:13px; letter-spacing:.02em; cursor:pointer; text-transform:uppercase;
transition:transform .1s ease, box-shadow .15s; box-shadow:3px 3px 0 var(--ink);
}
.apply-btn:active{ transform:translate(3px,3px); box-shadow:0 0 0 var(--ink); }
.ghost-btn{ width:100%; margin-top:4px; background:var(--paper); color:var(--ink); border:2px solid var(--ink); border-radius:9px; padding:11px; font-weight:700; font-size:12.5px; cursor:pointer; text-transform:uppercase; font-family:var(--mono); transition:transform .1s; }
.ghost-btn:active{ transform:scale(.97); }
.swatches{ display:flex; gap:10px; flex-wrap:wrap; }
.swatch-wrap{ display:flex; flex-direction:column; align-items:center; gap:6px; cursor:pointer; }
.swatch{ width:38px; height:38px; border-radius:8px; border:2.5px solid var(--ink); transition:transform .15s; }
.swatch-wrap:active .swatch{ transform:scale(.88); }
.swatch.active{ box-shadow:3px 3px 0 var(--ink); }
.swatch-name{ font-family:var(--mono); font-size:9px; color:var(--sub); font-weight:700; }
.live-preview{ display:flex; align-items:center; gap:8px; margin-top:14px; padding-top:14px; border-top:2px dashed var(--ink); font-family:var(--mono); }
.live-preview span{ font-size:11px; color:var(--sub); }
.live-preview b{ color:var(--ink); }
.toast{
position:absolute; left:50%; bottom:80px; transform:translate(-50%,20px); opacity:0;
background:var(--ink); color:var(--paper); border:2px solid var(--ink);
padding:10px 18px; border-radius:20px; font-size:12px; font-weight:700; font-family:var(--mono); white-space:nowrap;
transition:transform .3s cubic-bezier(.22,.9,.3,1), opacity .3s ease; pointer-events:none; z-index:5;
}
.toast.show{ transform:translate(-50%,0); opacity:1; }
::-webkit-scrollbar{ width:0; }
/* ---------- GAMES SCREEN ---------- */
.games-inner{ flex:1; min-height:0; overflow-y:auto; padding:18px 18px 24px; }
.game-grid{ display:grid; grid-template-columns:1fr 1fr; gap:10px; }
.game-card{ background:var(--paper2); border:2.5px solid var(--ink); border-radius:14px; padding:14px 12px; cursor:pointer; box-shadow:4px 4px 0 var(--ink); transition:transform .12s, box-shadow .12s; animation:fadeUp .45s cubic-bezier(.2,.9,.25,1) both; }
.game-card:active{ transform:translate(4px,4px); box-shadow:0 0 0 var(--ink); }
.game-card:nth-child(1){animation-delay:.02s;} .game-card:nth-child(2){animation-delay:.05s;} .game-card:nth-child(3){animation-delay:.08s;} .game-card:nth-child(4){animation-delay:.11s;} .game-card:nth-child(5){animation-delay:.14s;}
.game-emoji{ font-size:24px; margin-bottom:7px; }
.game-name{ font-size:12.5px; font-weight:800; }
.game-desc{ font-family:var(--mono); font-size:9.5px; color:var(--sub); margin-top:3px; }
.game-view{ display:none; flex-direction:column; align-items:center; }
.game-view.active{ display:flex; }
.game-back{ display:flex; align-items:center; gap:8px; align-self:flex-start; background:var(--paper2); border:2px solid var(--ink); border-radius:20px; padding:7px 14px 7px 9px; font-size:11.5px; font-weight:700; color:var(--ink); cursor:pointer; margin-bottom:16px; font-family:var(--mono); text-transform:uppercase; }
.game-back svg{ width:13px; height:13px; stroke:var(--ink); }
.game-title{ font-size:17px; font-weight:900; margin-bottom:14px; }
.ttt-board{ display:grid; grid-template-columns:repeat(3,1fr); gap:7px; width:210px; }
.ttt-cell{ aspect-ratio:1; background:var(--paper2); border:2.5px solid var(--ink); border-radius:10px; display:flex; align-items:center; justify-content:center; font-size:30px; font-weight:900; cursor:pointer; }
.game-status{ margin-top:14px; font-family:var(--mono); font-size:12px; color:var(--sub); font-weight:700; min-height:16px; text-align:center; }
.rps-row{ display:flex; gap:11px; }
.rps-btn{ width:60px; height:60px; border-radius:50%; background:var(--paper2); border:2.5px solid var(--ink); font-size:24px; cursor:pointer; transition:transform .12s; }
.rps-btn:active{ transform:scale(.88); }
.rps-result{ margin-top:16px; font-size:14px; font-weight:800; text-align:center; }
.rps-score{ margin-top:6px; font-family:var(--mono); font-size:10.5px; color:var(--sub); }
.guess-input{ width:130px; text-align:center; font-size:20px; font-weight:800; background:var(--paper2); border:2.5px solid var(--ink); border-radius:10px; padding:11px; color:var(--ink); outline:none; font-family:var(--mono); }
.mem-board{ display:grid; grid-template-columns:repeat(4,1fr); gap:6px; width:250px; }
.mem-cell{ aspect-ratio:1; background:var(--paper2); border:2px solid var(--ink); border-radius:8px; display:flex; align-items:center; justify-content:center; font-size:18px; cursor:pointer; }
.mem-cell.flipped{ background:var(--accent-dim); }
.mem-cell.matched{ opacity:.3; }
.react-box{ width:250px; height:160px; border-radius:14px; display:flex; align-items:center; justify-content:center; font-size:13px; font-weight:800; text-align:center; cursor:pointer; background:var(--paper2); border:2.5px solid var(--ink); color:var(--sub); font-family:var(--mono); text-transform:uppercase; }
.react-box.go{ background:var(--accent); color:var(--ink); }
.react-box.early{ background:#FF5000; color:#fff; }
</style>
</head>
<body>
<div class="phone">
<div class="track" id="track">
<div class="screen" id="watchScreen">
<div class="hdr"><div class="mark"><span class="sq"></span>8IE TIME</div><div class="tag">Time On Chain</div></div>
<div class="watch-body">
<div class="stage-wrap">
<div class="stage">
<svg viewBox="0 0 660 800" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="caseGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#2c2c30"/><stop offset="18%" stop-color="#0a0a0c"/>
<stop offset="50%" stop-color="#161619"/><stop offset="82%" stop-color="#050506"/>
<stop offset="100%" stop-color="#2a2a2e"/>
</linearGradient>
<radialGradient id="dialGrad" cx="38%" cy="30%" r="80%">
<stop offset="0%" stop-color="#1a1c1f"/><stop offset="45%" stop-color="#101113"/>
<stop offset="80%" stop-color="#0a0b0c"/><stop offset="100%" stop-color="#050506"/>
</radialGradient>
<linearGradient id="steelGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#ffffff"/><stop offset="35%" stop-color="#d7dde3"/>
<stop offset="55%" stop-color="#8b95a1"/><stop offset="75%" stop-color="#f2f5f8"/>
<stop offset="100%" stop-color="#a7b0ba"/>
</linearGradient>
<linearGradient id="steelGradV" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stop-color="#ffffff"/><stop offset="40%" stop-color="#ced5db"/>
<stop offset="60%" stop-color="#828c98"/><stop offset="100%" stop-color="#eef1f4"/>
</linearGradient>
<pattern id="clous" width="18" height="18" patternUnits="userSpaceOnUse">
<rect x="2" y="2" width="14" height="14" fill="#16181a" opacity="0.6"/>
<rect x="2" y="2" width="14" height="7" fill="#232629" opacity="0.5"/>
<rect x="2" y="9" width="14" height="7" fill="#0a0b0c" opacity="0.55"/>
</pattern>
<radialGradient id="vignette" cx="50%" cy="45%" r="65%">
<stop offset="60%" stop-color="#000" stop-opacity="0"/><stop offset="100%" stop-color="#000" stop-opacity="0.6"/>
</radialGradient>
<clipPath id="dialClip"><rect x="60" y="34" width="540" height="732" rx="150" ry="150"/></clipPath>
<filter id="softShadow" x="-30%" y="-30%" width="160%" height="160%">
<feDropShadow dx="0" dy="3" stdDeviation="4" flood-color="#000" flood-opacity="0.45"/>
</filter>
</defs>
<rect x="4" y="4" width="652" height="792" rx="164" ry="164" fill="url(#caseGrad)"/>
<rect x="20" y="20" width="620" height="760" rx="150" ry="150" fill="none" stroke="#4a4a50" stroke-width="2" opacity="0.5"/>
<g clip-path="url(#dialClip)">
<rect x="60" y="34" width="540" height="732" fill="url(#dialGrad)"/>
<rect x="60" y="34" width="540" height="732" fill="url(#clous)"/>
<rect x="60" y="34" width="540" height="732" fill="url(#vignette)"/>
<rect x="60" y="34" width="540" height="732" rx="150" ry="150" fill="none" id="dialRing" stroke="#00C805" stroke-width="3" opacity="0.4"/>
</g>
<g id="hourMarkers"></g>
<g id="minuteTicks"></g>
<g transform="translate(462,398)">
<rect x="-42" y="-30" width="84" height="60" rx="4" fill="#08090a" stroke="#1c1f22" stroke-width="2"/>
<rect x="-38" y="-26" width="76" height="52" rx="2" fill="#111315"/>
<rect x="-38" y="18" width="76" height="8" id="dateStripe" fill="#00C805" opacity="0.85"/>
<text id="dateText" x="0" y="10" text-anchor="middle" font-family="Arial, sans-serif" font-size="34" font-weight="600" fill="#eef3f8">15</text>
</g>
<g text-anchor="middle" fill="#e9eef4">
<text x="330" y="200" font-family="Georgia, 'Times New Roman', serif" font-size="46" font-weight="700" letter-spacing="2" fill="#f2f5f9" filter="url(#softShadow)">8IE</text>
<g filter="url(#softShadow)">
<text x="330" y="260" font-family="Georgia, 'Times New Roman', serif" font-size="30" font-weight="600" letter-spacing="2.5" fill="#f4f7fb">8IE TIME</text>
<rect x="207" y="268" width="246" height="2" id="ruleBottom" fill="#00C805" opacity="0.75"/>
<rect x="207" y="234" width="246" height="2" id="ruleTop" fill="#00C805" opacity="0.75"/>
</g>
<text x="330" y="712" font-family="Arial, sans-serif" font-size="12.5" letter-spacing="3" fill="#dbe4ee" opacity="0.85">TIME ON CHAIN</text>
</g>
<g id="handsGroup" transform="translate(330,398)">
<g id="hourHand" filter="url(#softShadow)"><path d="M -6,10 L -4,-140 L 0,-158 L 4,-140 L 6,10 Z" fill="url(#steelGrad)" stroke="#5b6672" stroke-width="0.6"/></g>
<g id="minuteHand" filter="url(#softShadow)"><path d="M -5,14 L -3.4,-210 L 0,-228 L 3.4,-210 L 5,14 Z" fill="url(#steelGrad)" stroke="#5b6672" stroke-width="0.6"/></g>
<g id="secondHand">
<line x1="0" y1="46" x2="0" y2="-238" id="secLine" stroke="#00C805" stroke-width="2"/>
<circle cx="0" cy="-198" r="7" fill="none" id="secDot" stroke="#00C805" stroke-width="2"/>
<circle cx="0" cy="46" r="4" id="secTail" fill="#00C805"/>
</g>
<circle cx="0" cy="0" r="9" fill="url(#steelGrad)" stroke="#3a4149" stroke-width="1"/>
<circle cx="0" cy="0" r="3" fill="#2a2f35"/>
</g>
</svg>
</div>
</div>
<div class="info-strip">
<div class="info-chip"><div class="k"><span class="pulse-sq"></span>Status</div><div class="v">Synced</div></div>
<div class="info-chip"><div class="k">Region</div><div class="v" id="statusTz">Local</div></div>
</div>
</div>
<div class="tabbar" id="tabbar1"></div>
</div>
<div class="screen" id="gamesScreen">
<div class="hdr"><div class="mark"><span class="sq"></span>8IE TIME</div><div class="tag">Games</div></div>
<div class="games-inner">
<div id="gameList">
<div class="pagetitle">Games</div>
<div class="pagesub">// 5 quick games, on the house</div>
<div class="game-grid">
<div class="game-card" data-game="ttt"><div class="game-emoji">⭕</div><div class="game-name">Tic Tac Toe</div><div class="game-desc">Classic 3x3</div></div>
<div class="game-card" data-game="rps"><div class="game-emoji">✂️</div><div class="game-name">Rock Paper Scissors</div><div class="game-desc">Beat the bot</div></div>
<div class="game-card" data-game="guess"><div class="game-emoji">🎯</div><div class="game-name">Number Guess</div><div class="game-desc">1–50, few tries</div></div>
<div class="game-card" data-game="mem"><div class="game-emoji">🧠</div><div class="game-name">Memory Match</div><div class="game-desc">Find the pairs</div></div>
<div class="game-card" data-game="react"><div class="game-emoji">⚡</div><div class="game-name">Reaction Time</div><div class="game-desc">Tap on green</div></div>
</div>
</div>
<div class="game-view" id="view-ttt">
<div class="game-back" data-back><svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 6l-6 6 6 6"/></svg>Games</div>
<div class="game-title">Tic Tac Toe</div>
<div class="ttt-board" id="tttBoard"></div>
<div class="game-status" id="tttStatus">Your turn — X</div>
<button class="ghost-btn" id="tttReset" style="width:210px;">New Game</button>
</div>
<div class="game-view" id="view-rps">
<div class="game-back" data-back><svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 6l-6 6 6 6"/></svg>Games</div>
<div class="game-title">Rock Paper Scissors</div>
<div class="rps-row">
<button class="rps-btn" data-pick="rock">🪨</button>
<button class="rps-btn" data-pick="paper">📄</button>
<button class="rps-btn" data-pick="scissors">✂️</button>
</div>
<div class="rps-result" id="rpsResult">Make your move</div>
<div class="rps-score" id="rpsScore">You 0 · Bot 0</div>
</div>
<div class="game-view" id="view-guess">
<div class="game-back" data-back><svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 6l-6 6 6 6"/></svg>Games</div>
<div class="game-title">Number Guess</div>
<input class="guess-input" id="guessInput" type="number" min="1" max="50" placeholder="1-50">
<button class="apply-btn" id="guessBtn" style="width:210px;">Guess</button>
<div class="game-status" id="guessStatus">Pick a number between 1 and 50</div>
<button class="ghost-btn" id="guessReset" style="width:210px;">New Game</button>
</div>
<div class="game-view" id="view-mem">
<div class="game-back" data-back><svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 6l-6 6 6 6"/></svg>Games</div>
<div class="game-title">Memory Match</div>
<div class="mem-board" id="memBoard"></div>
<div class="game-status" id="memStatus">Moves: 0</div>
<button class="ghost-btn" id="memReset" style="width:210px;">New Game</button>
</div>
<div class="game-view" id="view-react">
<div class="game-back" data-back><svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 6l-6 6 6 6"/></svg>Games</div>
<div class="game-title">Reaction Time</div>
<div class="react-box" id="reactBox">Tap to start<br>wait for green</div>
<div class="game-status" id="reactStatus">Best: –</div>
</div>
</div>
<div class="tabbar" id="tabbar2"></div>
</div>
<div class="screen" id="settingsScreen">
<div class="hdr"><div class="mark"><span class="sq"></span>8IE TIME</div><div class="tag">Settings</div></div>
<div class="settings-inner">
<div class="pagetitle">Settings</div>
<div class="pagesub">// customize your watch</div>
<div class="card">
<div class="card-label"><span class="bar"></span>Theme Color</div>
<div class="swatches" id="swatches"></div>
</div>
<div class="card">
<div class="card-label"><span class="bar"></span>Region & Time Zone</div>
<select id="regionSelect"></select>
<div class="field-sub">Watch hands follow this region's local time.</div>
</div>
<div class="card">
<div class="card-label"><span class="bar"></span>Set Date & Time</div>
<div class="row2">
<div><input type="date" id="dateInput"></div>
<div><input type="time" id="timeInput" step="1"></div>
</div>
<button class="apply-btn" id="applyBtn">Apply to Watch</button>
<div class="live-preview">Live — <b id="livePreview">--:--:--</b></div>
</div>
<button class="ghost-btn" id="resetBtn">Reset to Real Time</button>
</div>
<div class="toast" id="toast"></div>
<div class="tabbar" id="tabbar3"></div>
</div>
</div>
</div>
<script>
(function(){
const NS="http://www.w3.org/2000/svg";
const cx=330, cy=398, outerR=262, innerR=218, tickOuterR=268, tickInnerR=256;
const hourMarkersG=document.getElementById("hourMarkers");
const minuteTicksG=document.getElementById("minuteTicks");
for(let i=0;i<12;i++){
const angle=(i*30)*Math.PI/180;
if(i===0){
[-9,9].forEach(off=>{
const line=document.createElementNS(NS,"line");
line.setAttribute("x1",cx+off); line.setAttribute("y1",cy-outerR);
line.setAttribute("x2",cx+off); line.setAttribute("y2",cy-innerR);
line.setAttribute("stroke","url(#steelGradV)"); line.setAttribute("stroke-width","10");
line.setAttribute("stroke-linecap","round"); line.setAttribute("filter","url(#softShadow)");
hourMarkersG.appendChild(line);
});
} else {
const x1=cx+innerR*Math.sin(angle), y1=cy-innerR*Math.cos(angle);
const x2=cx+outerR*Math.sin(angle), y2=cy-outerR*Math.cos(angle);
const line=document.createElementNS(NS,"line");
line.setAttribute("x1",x1); line.setAttribute("y1",y1);
line.setAttribute("x2",x2); line.setAttribute("y2",y2);
line.setAttribute("stroke","url(#steelGrad)");
line.setAttribute("stroke-width", i===3? "10":"13");
line.setAttribute("stroke-linecap","round"); line.setAttribute("filter","url(#softShadow)");
hourMarkersG.appendChild(line);
}
}
for(let i=0;i<60;i++){
if(i%5===0) continue;
const angle=(i*6)*Math.PI/180;
const x1=cx+tickInnerR*Math.sin(angle), y1=cy-tickInnerR*Math.cos(angle);
const x2=cx+tickOuterR*Math.sin(angle), y2=cy-tickOuterR*Math.cos(angle);
const line=document.createElementNS(NS,"line");
line.setAttribute("x1",x1); line.setAttribute("y1",y1);
line.setAttribute("x2",x2); line.setAttribute("y2",y2);
line.setAttribute("stroke","#5a6068"); line.setAttribute("stroke-width","2"); line.setAttribute("opacity","0.55");
minuteTicksG.appendChild(line);
}
/* Bottom tab bars — build once, clone into each screen */
const TABS = [
{id:"watch", label:"Watch", svg:'<circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 3"/>'},
{id:"games", label:"Games", svg:'<rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/>'},
{id:"settings", label:"Settings", svg:'<circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .34 1.87l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.7 1.7 0 0 0-1.87-.34 1.7 1.7 0 0 0-1 1.55V21a2 2 0 1 1-4 0v-.09A1.7 1.7 0 0 0 9 19.4a1.7 1.7 0 0 0-1.87.34l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.7 1.7 0 0 0 4.6 15a1.7 1.7 0 0 0-1.55-1H3a2 2 0 1 1 0-4h.09A1.7 1.7 0 0 0 4.6 9a1.7 1.7 0 0 0-.34-1.87l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.7 1.7 0 0 0 9 4.6a1.7 1.7 0 0 0 1-1.55V3a2 2 0 1 1 4 0v.09a1.7 1.7 0 0 0 1 1.55 1.7 1.7 0 0 0 1.87-.34l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.7 1.7 0 0 0 19.4 9a1.7 1.7 0 0 0 1.55 1H21a2 2 0 1 1 0 4h-.09a1.7 1.7 0 0 0-1.55 1z"/>'}
];
["tabbar1","tabbar2","tabbar3"].forEach(barId=>{
const bar=document.getElementById(barId);
TABS.forEach(t=>{
const b=document.createElement("button");
b.className="tabbtn"; b.dataset.pane=t.id;
b.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">'+t.svg+'</svg><span>'+t.label+'</span>';
b.addEventListener("click", ()=>goTo(PANES.indexOf(t.id)));
bar.appendChild(b);
});
});
const THEMES = [
{id:"green", name:"Classic", hex:"#00C805"},
{id:"red", name:"Alert", hex:"#FF5000"},
{id:"gold", name:"Gold", hex:"#FFD700"},
{id:"mono", name:"Mono", hex:"#0b0b0b"},
];
const strokeEls = ["dialRing","secLine","secDot"];
const fillEls = ["dateStripe","ruleBottom","ruleTop","secTail"];
const swatchesEl = document.getElementById("swatches");
THEMES.forEach(t=>{
const wrap=document.createElement("div"); wrap.className="swatch-wrap";
const s=document.createElement("div");
s.className="swatch"; s.style.background=t.hex; s.dataset.id=t.id;
const label=document.createElement("div"); label.className="swatch-name"; label.textContent=t.name;
wrap.appendChild(s); wrap.appendChild(label);
wrap.addEventListener("click",()=>setTheme(t.id, true));
swatchesEl.appendChild(wrap);
});
function setTheme(id, showToast){
const t = THEMES.find(x=>x.id===id) || THEMES[0];
document.documentElement.style.setProperty("--accent", t.hex);
document.documentElement.style.setProperty("--accent-dim", t.hex+"22");
strokeEls.forEach(id2=>{ const el=document.getElementById(id2); if(el) el.setAttribute("stroke", t.hex); });
fillEls.forEach(id2=>{ const el=document.getElementById(id2); if(el) el.setAttribute("fill", t.hex); });
document.querySelectorAll(".swatch").forEach(s=>s.classList.toggle("active", s.dataset.id===t.id));
localStorage.setItem("8ie_theme", t.id);
if(showToast) fireToast("Theme set to " + t.name);
}
const REGIONS = [
["auto","Device Local Time"],["America/New_York","New York (ET)"],["America/Los_Angeles","Los Angeles (PT)"],
["America/Chicago","Chicago (CT)"],["Europe/London","London (GMT)"],["Europe/Paris","Paris (CET)"],
["Europe/Zurich","Zurich (CET)"],["Asia/Dubai","Dubai (GST)"],["Asia/Tokyo","Tokyo (JST)"],
["Asia/Hong_Kong","Hong Kong (HKT)"],["Asia/Singapore","Singapore (SGT)"],["Australia/Sydney","Sydney (AEST)"],
];
const regionSelect = document.getElementById("regionSelect");
const statusTz = document.getElementById("statusTz");
REGIONS.forEach(([val,label])=>{
const o=document.createElement("option"); o.value=val; o.textContent=label; regionSelect.appendChild(o);
});
function updateStatusTz(){
const label = regionSelect.options[regionSelect.selectedIndex].text;
statusTz.textContent = regionSelect.value==="auto" ? "Local" : label.replace(/\s*\(.*\)/,"");
}
regionSelect.addEventListener("change", ()=>{
localStorage.setItem("8ie_region", regionSelect.value);
updateStatusTz();
fireToast("Region set to " + regionSelect.options[regionSelect.selectedIndex].text);
});
let timeOffsetMs = parseFloat(localStorage.getItem("8ie_offset")||"0") || 0;
document.getElementById("applyBtn").addEventListener("click", ()=>{
const d = document.getElementById("dateInput").value;
const t = document.getElementById("timeInput").value;
if(!d || !t){ fireToast("Pick a date and time first"); return; }
const chosen = new Date(d + "T" + (t.length===5? t+":00": t));
timeOffsetMs = chosen.getTime() - Date.now();
localStorage.setItem("8ie_offset", String(timeOffsetMs));
fireToast("Watch time updated");
});
document.getElementById("resetBtn").addEventListener("click", ()=>{
timeOffsetMs = 0; localStorage.removeItem("8ie_offset");
fireToast("Reset to real time");
});
let toastTimer;
function fireToast(msg){
const el = document.getElementById("toast");
el.textContent = msg; el.classList.add("show");
clearTimeout(toastTimer);
toastTimer = setTimeout(()=>el.classList.remove("show"), 1800);
}
setTheme(localStorage.getItem("8ie_theme") || "green", false);
regionSelect.value = localStorage.getItem("8ie_region") || "auto";
updateStatusTz();
const track = document.getElementById("track");
const phone = document.querySelector(".phone");
const PANES = ["watch","games","settings"];
let startX=0, dragging=false, currentOffset=0, paneIdx=0;
function goTo(idx){
paneIdx = Math.max(0, Math.min(PANES.length-1, idx));
track.style.transform = "translateX(-" + (paneIdx*33.3334) + "%)";
document.querySelectorAll(".tabbtn").forEach(b=>b.classList.toggle("active", b.dataset.pane===PANES[paneIdx]));
}
function onStart(x){ startX=x; dragging=true; track.style.transition="none"; }
function onMove(x){
if(!dragging) return;
let delta = x - startX;
const base = -paneIdx * phone.offsetWidth;
let px = base + delta;
px = Math.max(-2*phone.offsetWidth, Math.min(0, px));
track.style.transform = "translateX(" + px + "px)";
currentOffset = delta;
}
function onEnd(){
if(!dragging) return;
dragging=false;
track.style.transition="transform .48s cubic-bezier(.65,0,.35,1)";
if(currentOffset < -60) goTo(paneIdx+1);
else if(currentOffset > 60) goTo(paneIdx-1);
else goTo(paneIdx);
currentOffset=0;
}
phone.addEventListener("touchstart", e=>onStart(e.touches[0].clientX), {passive:true});
phone.addEventListener("touchmove", e=>onMove(e.touches[0].clientX), {passive:true});
phone.addEventListener("touchend", onEnd);
phone.addEventListener("mousedown", e=>onStart(e.clientX));
window.addEventListener("mousemove", e=>{ if(dragging) onMove(e.clientX); });
window.addEventListener("mouseup", onEnd);
goTo(0);
/* ================= GAMES ================= */
const gameList = document.getElementById("gameList");
document.querySelectorAll(".game-card").forEach(card=>{
card.addEventListener("click", ()=>{
gameList.style.display="none";
document.getElementById("view-"+card.dataset.game).classList.add("active");
});
});
document.querySelectorAll("[data-back]").forEach(b=>{
b.addEventListener("click", ()=>{
document.querySelectorAll(".game-view").forEach(v=>v.classList.remove("active"));
gameList.style.display="block";
});
});
(function(){ // Tic Tac Toe
const board = document.getElementById("tttBoard");
const status = document.getElementById("tttStatus");
let cells, turn, over;
function reset(){
cells = Array(9).fill(""); turn = "X"; over=false; board.innerHTML="";
cells.forEach((_,i)=>{
const c=document.createElement("div"); c.className="ttt-cell"; c.dataset.i=i;
c.addEventListener("click", ()=>play(i));
board.appendChild(c);
});
status.textContent="Your turn — X";
}
const WINS=[[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]];
function checkWin(pl){ return WINS.some(w=>w.every(i=>cells[i]===pl)); }
function play(i){
if(over || cells[i]) return;
cells[i]=turn; board.children[i].textContent=turn;
board.children[i].style.color = turn==="X" ? "var(--accent)" : "#0b0b0b";
if(checkWin(turn)){ status.textContent = turn+" wins!"; over=true; return; }
if(cells.every(c=>c)){ status.textContent="Draw game"; over=true; return; }
turn = turn==="X" ? "O" : "X";
status.textContent = turn==="X" ? "Your turn — X" : "Bot thinking...";
if(turn==="O") setTimeout(botMove, 400);
}
function botMove(){
if(over) return;
let open = cells.map((c,i)=>c?null:i).filter(i=>i!==null);
play(open[Math.floor(Math.random()*open.length)]);
}
document.getElementById("tttReset").addEventListener("click", reset);
reset();
})();
(function(){ // RPS
const result = document.getElementById("rpsResult");
const scoreEl = document.getElementById("rpsScore");
const opts=["rock","paper","scissors"]; const emo={rock:"🪨",paper:"📄",scissors:"✂️"};
let you=0, bot=0;
document.querySelectorAll(".rps-btn").forEach(b=>{
b.addEventListener("click", ()=>{
const pick=b.dataset.pick; const cpu=opts[Math.floor(Math.random()*3)];
let msg;
if(pick===cpu) msg="Tie — both " + emo[pick];
else if((pick==="rock"&&cpu==="scissors")||(pick==="paper"&&cpu==="rock")||(pick==="scissors"&&cpu==="paper")){ you++; msg="You win! "+emo[pick]+" beats "+emo[cpu]; }
else { bot++; msg="Bot wins. "+emo[cpu]+" beats "+emo[pick]; }
result.textContent=msg;
scoreEl.textContent="You "+you+" · Bot "+bot;
});
});
})();
(function(){ // Number Guess
const input=document.getElementById("guessInput");
const status=document.getElementById("guessStatus");
let target, tries;
function reset(){ target=1+Math.floor(Math.random()*50); tries=0; input.value=""; status.textContent="Pick a number between 1 and 50"; }
document.getElementById("guessBtn").addEventListener("click", ()=>{
const v=parseInt(input.value,10);
if(!v || v<1 || v>50){ status.textContent="Enter a number 1–50"; return; }
tries++;
if(v===target) status.textContent="Correct! " + target + " in " + tries + " tries 🎉";
else status.textContent = v<target ? "Higher ↑ (try "+tries+")" : "Lower ↓ (try "+tries+")";
});
document.getElementById("guessReset").addEventListener("click", reset);
reset();
})();
(function(){ // Memory Match
const board=document.getElementById("memBoard");
const status=document.getElementById("memStatus");
const EMOJI=["🍀","🔥","⭐","🌙","💎","🎧","🚀","🧩"];
let flipped, moves, lock;
function reset(){
const deck=[...EMOJI,...EMOJI].sort(()=>Math.random()-.5);
flipped=[]; moves=0; lock=false;
board.innerHTML=""; status.textContent="Moves: 0";
deck.forEach((sym,i)=>{
const c=document.createElement("div"); c.className="mem-cell"; c.dataset.sym=sym;
c.addEventListener("click", ()=>flip(c));
board.appendChild(c);
});
}
function flip(c){
if(lock || c.classList.contains("flipped") || c.classList.contains("matched")) return;
c.classList.add("flipped"); c.textContent=c.dataset.sym;
flipped.push(c);
if(flipped.length===2){
moves++; status.textContent="Moves: "+moves; lock=true;
const [a,b]=flipped;
if(a.dataset.sym===b.dataset.sym){
a.classList.add("matched"); b.classList.add("matched");
flipped=[]; lock=false;
if(document.querySelectorAll("#memBoard .mem-cell.matched").length===16) status.textContent="Solved in "+moves+" moves 🎉";
} else {
setTimeout(()=>{ a.classList.remove("flipped"); b.classList.remove("flipped"); a.textContent=""; b.textContent=""; flipped=[]; lock=false; }, 650);
}
}
}
document.getElementById("memReset").addEventListener("click", reset);
reset();
})();
(function(){ // Reaction Time
const box=document.getElementById("reactBox");
const status=document.getElementById("reactStatus");
let state="idle", timer, t0;
let best = parseFloat(localStorage.getItem("8ie_reactBest")||"0") || null;
if(best) status.textContent="Best: "+Math.round(best)+"ms";
box.addEventListener("click", ()=>{
if(state==="idle"){
state="waiting"; box.textContent="Wait for green..."; box.className="react-box";
const delay=800+Math.random()*2200;
timer=setTimeout(()=>{ state="go"; t0=performance.now(); box.textContent="TAP NOW"; box.className="react-box go"; }, delay);
} else if(state==="waiting"){
clearTimeout(timer); state="idle"; box.textContent="Too soon! Tap to retry"; box.className="react-box early";
setTimeout(()=>{ box.textContent="Tap to start<br>wait for green"; box.className="react-box"; }, 900);
} else if(state==="go"){
const t=performance.now()-t0; state="idle";
box.textContent="Tap to start<br>wait for green"; box.className="react-box";
if(!best || t<best){ best=t; localStorage.setItem("8ie_reactBest", String(best)); }
status.textContent = Math.round(t)+"ms · Best: "+Math.round(best)+"ms";
}
});
})();
const hourHand=document.getElementById("hourHand");
const minuteHand=document.getElementById("minuteHand");
const secondHand=document.getElementById("secondHand");
const dateText=document.getElementById("dateText");
const livePreview=document.getElementById("livePreview");
function getEffectiveNow(){
const now = new Date(Date.now() + timeOffsetMs);
const tz = regionSelect.value;
if(tz === "auto") return now;
try{
const parts = new Intl.DateTimeFormat("en-US",{
timeZone: tz, hour12:false, year:"numeric", month:"2-digit", day:"2-digit",
hour:"2-digit", minute:"2-digit", second:"2-digit"
}).formatToParts(now);
const p={}; parts.forEach(x=>p[x.type]=x.value);
return new Date(+p.year, +p.month-1, +p.day, +p.hour, +p.minute, +p.second, now.getMilliseconds());
}catch(e){ return now; }
}
function tick(){
const eff = getEffectiveNow();
const h=eff.getHours()%12, m=eff.getMinutes(), s=eff.getSeconds(), ms=eff.getMilliseconds();
hourHand.setAttribute("transform","rotate(" + ((h+m/60)*30) + ")");
minuteHand.setAttribute("transform","rotate(" + ((m+s/60)*6) + ")");
secondHand.setAttribute("transform","rotate(" + ((s+ms/1000)*6) + ")");
dateText.textContent = String(eff.getDate()).padStart(2,"0");
livePreview.textContent = eff.toLocaleTimeString("en-US",{hour12:false});
requestAnimationFrame(tick);
}
requestAnimationFrame(tick);
})();
</script>
</body>
</html>
htmlSub-10k
#003195 · 8IE TIME
3196 of 3,226 inscriptions · text/html · 52.10 KB onchain
Not listed
Offers open once there is a relay to hold themConnect a wallet to buy, offer or transfer.
DetailsView on Explorer ↗
- Creator
- 0x2bb5…3823
- Owner
- 0x2bb5…3823
- Inscribed
- Sep 25, 2026, 8:58 PM
- Block
- 72,531,113 · idx 4
- Tx
- 0x58ff7df0…f9c3ff1a
- Size
- 52.10 KB
- Mime
- text/html
- Collection
- 8IE TIME Collection
- Provenance
- Held by creator
Provenance1 event
- Inscribed by 0x2bb5…3823Created
