216 lines
8.5 KiB
HTML
216 lines
8.5 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="tr">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Numex Aqua World — Gelecek, denizin altında</title>
|
||
<meta name="description" content="Tarayıcıda çalışan, tamamen kodla üretilmiş etkileşimli 3D su altı şehri.">
|
||
<style>
|
||
:root{
|
||
--cam: rgba(8, 42, 74, 0.55);
|
||
--cam-brd: rgba(120, 220, 255, 0.28);
|
||
--txt: #dff4ff;
|
||
--accent: #46e0ff;
|
||
--warm: #ffca7a;
|
||
}
|
||
*{ box-sizing: border-box; }
|
||
html, body{ margin:0; padding:0; height:100%; overflow:hidden; background:#02121f; }
|
||
body{
|
||
font-family: "Segoe UI", system-ui, -apple-system, "Trebuchet MS", sans-serif;
|
||
color: var(--txt);
|
||
-webkit-font-smoothing: antialiased;
|
||
user-select: none;
|
||
}
|
||
#scene{ position:fixed; inset:0; display:block; }
|
||
canvas{ display:block; }
|
||
|
||
/* ---------- Yükleniyor ---------- */
|
||
#loader{
|
||
position:fixed; inset:0; z-index:50;
|
||
display:flex; flex-direction:column; align-items:center; justify-content:center;
|
||
background: radial-gradient(circle at 50% 30%, #0a3352 0%, #031523 55%, #010a12 100%);
|
||
transition: opacity 1.1s ease, visibility 1.1s ease;
|
||
}
|
||
#loader.hide{ opacity:0; visibility:hidden; }
|
||
.bubble{
|
||
width:74px; height:74px; border-radius:50%;
|
||
border:1px solid rgba(130,230,255,.5);
|
||
box-shadow: 0 0 26px rgba(70,224,255,.35), inset 0 0 22px rgba(70,224,255,.18);
|
||
animation: pulse 2.2s ease-in-out infinite;
|
||
margin-bottom:26px;
|
||
}
|
||
@keyframes pulse{
|
||
0%,100%{ transform: scale(.92); opacity:.75; }
|
||
50%{ transform: scale(1.06); opacity:1; }
|
||
}
|
||
#loader h1{
|
||
margin:0; font-size: clamp(20px, 3.4vw, 34px); font-weight:300; letter-spacing:.42em;
|
||
text-transform: uppercase; text-indent:.42em;
|
||
}
|
||
#loader p{ margin:12px 0 0; font-size:13px; letter-spacing:.18em; color:#7fc9e6; text-transform:uppercase; }
|
||
|
||
/* ---------- Başlık ---------- */
|
||
#brand{
|
||
position:fixed; top:22px; left:26px; z-index:10; pointer-events:none;
|
||
transition: opacity .6s ease;
|
||
}
|
||
#brand h2{
|
||
margin:0; font-size:clamp(15px, 1.7vw, 21px); font-weight:300; letter-spacing:.30em; text-transform:uppercase;
|
||
text-shadow: 0 0 18px rgba(70,224,255,.55);
|
||
}
|
||
#brand span{
|
||
display:block; margin-top:6px; font-size:10.5px; letter-spacing:.24em; text-transform:uppercase; color:#87cfe8;
|
||
}
|
||
|
||
/* ---------- Kontrol paneli ---------- */
|
||
#hud{
|
||
position:fixed; right:20px; top:20px; z-index:12;
|
||
display:flex; flex-direction:column; gap:7px; width:min(212px, 42vw);
|
||
backdrop-filter: blur(14px) saturate(140%);
|
||
background: var(--cam);
|
||
border:1px solid var(--cam-brd);
|
||
border-radius:16px; padding:12px;
|
||
box-shadow: 0 16px 40px rgba(0,0,0,.38);
|
||
}
|
||
#hud .hud-title{
|
||
font-size:9.5px; letter-spacing:.26em; text-transform:uppercase; color:#8ed6ee; padding:2px 4px 4px;
|
||
}
|
||
.btn{
|
||
-webkit-appearance:none; appearance:none; cursor:pointer;
|
||
display:flex; align-items:center; gap:9px;
|
||
min-height:44px; padding:0 12px; width:100%;
|
||
font-family:inherit; font-size:12.5px; letter-spacing:.04em; color:var(--txt); text-align:left;
|
||
background: rgba(70,224,255,.07);
|
||
border:1px solid rgba(130,230,255,.18);
|
||
border-radius:11px;
|
||
transition: background .22s, border-color .22s, transform .12s;
|
||
}
|
||
.btn:hover{ background: rgba(70,224,255,.17); border-color: rgba(130,230,255,.42); }
|
||
.btn:active{ transform: scale(.985); }
|
||
.btn:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
|
||
.btn .dot{
|
||
width:9px; height:9px; border-radius:50%; flex:none;
|
||
background:#2a6d8a; box-shadow: inset 0 0 4px rgba(0,0,0,.5);
|
||
transition: background .3s, box-shadow .3s;
|
||
}
|
||
.btn.on{ background: rgba(70,224,255,.22); border-color: rgba(130,230,255,.6); }
|
||
.btn.on .dot{ background: var(--accent); box-shadow: 0 0 12px var(--accent); }
|
||
|
||
/* ---------- Alt bilgi / ipucu ---------- */
|
||
#hint{
|
||
position:fixed; left:26px; bottom:20px; z-index:10;
|
||
font-size:11.5px; letter-spacing:.08em; color:#8fc6dd;
|
||
display:flex; gap:14px; flex-wrap:wrap; max-width: 62vw;
|
||
text-shadow: 0 1px 6px rgba(0,0,0,.6);
|
||
}
|
||
#hint b{ color:#cfeeff; font-weight:600; }
|
||
|
||
/* ---------- Kubbe bilgi kartı ---------- */
|
||
#card{
|
||
position:fixed; left:50%; bottom:64px; transform: translate(-50%, 18px);
|
||
z-index:14; width:min(430px, 88vw);
|
||
padding:16px 18px 15px;
|
||
border-radius:16px;
|
||
backdrop-filter: blur(16px) saturate(140%);
|
||
background: rgba(6, 38, 66, .66);
|
||
border:1px solid rgba(130,230,255,.32);
|
||
box-shadow: 0 20px 50px rgba(0,0,0,.45);
|
||
opacity:0; visibility:hidden; transition: opacity .45s ease, transform .45s ease, visibility .45s;
|
||
}
|
||
#card.show{ opacity:1; visibility:visible; transform: translate(-50%, 0); }
|
||
#card h3{
|
||
margin:0 0 4px; font-size:15px; font-weight:400; letter-spacing:.14em; text-transform:uppercase; color:#eafaff;
|
||
}
|
||
#card .sub{ font-size:10.5px; letter-spacing:.2em; text-transform:uppercase; color:var(--warm); margin-bottom:9px; }
|
||
#card p{ margin:0; font-size:12.5px; line-height:1.55; color:#b9dff0; }
|
||
#card .metrics{ display:flex; gap:18px; margin-top:11px; }
|
||
#card .metrics div{ font-size:10px; letter-spacing:.13em; text-transform:uppercase; color:#7fc0d8; }
|
||
#card .metrics strong{ display:block; font-size:15px; letter-spacing:.02em; color:#d9f6ff; font-weight:500; margin-top:2px; }
|
||
#card .close{
|
||
position:absolute; top:10px; right:10px; width:32px; height:32px; min-height:32px;
|
||
border-radius:50%; border:1px solid rgba(130,230,255,.22); background:rgba(70,224,255,.08);
|
||
color:#cdeeff; cursor:pointer; font-size:15px; line-height:1; font-family:inherit;
|
||
}
|
||
#card .close:hover{ background:rgba(70,224,255,.2); }
|
||
|
||
/* ---------- Sinematik çerçeve ---------- */
|
||
#bars{ position:fixed; inset:0; z-index:8; pointer-events:none; }
|
||
#bars::before, #bars::after{
|
||
content:""; position:absolute; left:0; right:0; height:0; background:#010a11;
|
||
transition: height .9s cubic-bezier(.4,0,.2,1);
|
||
}
|
||
#bars::before{ top:0; }
|
||
#bars::after{ bottom:0; }
|
||
body.cinematic #bars::before, body.cinematic #bars::after{ height:9vh; }
|
||
body.cinematic #hud, body.cinematic #hint{ opacity:.18; }
|
||
body.cinematic #brand{ opacity:.3; }
|
||
|
||
#toast{
|
||
position:fixed; left:50%; top:74px; transform:translate(-50%,-6px);
|
||
z-index:16; padding:9px 18px; border-radius:999px;
|
||
background: rgba(6,38,66,.78); border:1px solid rgba(130,230,255,.3);
|
||
font-size:11.5px; letter-spacing:.16em; text-transform:uppercase; color:#d3f2ff;
|
||
opacity:0; transition: opacity .4s ease, transform .4s ease; pointer-events:none;
|
||
}
|
||
#toast.show{ opacity:1; transform:translate(-50%,0); }
|
||
|
||
@media (max-width: 640px){
|
||
#brand{ top:14px; left:16px; }
|
||
#hud{ right:12px; top:12px; width:min(164px, 46vw); padding:9px; gap:6px; border-radius:13px; }
|
||
#hud .hud-title{ font-size:8.5px; letter-spacing:.2em; }
|
||
.btn{ font-size:11px; padding:0 9px; gap:7px; min-height:44px; border-radius:9px; }
|
||
#hint{ left:14px; bottom:12px; max-width:86vw; font-size:10.5px; gap:9px; }
|
||
#card{ bottom:52px; padding:14px; }
|
||
#card .metrics{ gap:12px; }
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<canvas id="scene"></canvas>
|
||
|
||
<div id="bars"></div>
|
||
|
||
<div id="brand">
|
||
<h2>Aqua World</h2>
|
||
<span>Gelecek, denizin altında</span>
|
||
</div>
|
||
|
||
<div id="hud">
|
||
<div class="hud-title">Kontrol</div>
|
||
<button class="btn" id="btn-tour"><span class="dot"></span>Sinematik Tur</button>
|
||
<button class="btn" id="btn-night"><span class="dot"></span>Gece Modu</button>
|
||
<button class="btn" id="btn-follow"><span class="dot"></span>Denizaltı Takibi</button>
|
||
<button class="btn" id="btn-reset"><span class="dot"></span>Kamerayı Sıfırla</button>
|
||
</div>
|
||
|
||
<div id="hint">
|
||
<span><b>Sürükle</b> döndür</span>
|
||
<span><b>Tekerlek</b> yakınlaş</span>
|
||
<span><b>Kubbeye tıkla</b> yaklaş</span>
|
||
</div>
|
||
|
||
<div id="card">
|
||
<button class="close" id="card-close" aria-label="Kapat">✕</button>
|
||
<h3 id="card-title">Kubbe</h3>
|
||
<div class="sub" id="card-sub">Yaşam Alanı</div>
|
||
<p id="card-desc"></p>
|
||
<div class="metrics">
|
||
<div>Nüfus<strong id="card-pop">—</strong></div>
|
||
<div>Derinlik<strong id="card-depth">—</strong></div>
|
||
<div>Durum<strong id="card-state">—</strong></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="toast"></div>
|
||
|
||
<div id="loader">
|
||
<div class="bubble"></div>
|
||
<h1>Aqua World</h1>
|
||
<p id="loader-text">Şehir inşa ediliyor</p>
|
||
</div>
|
||
|
||
<script type="importmap">{"imports":{"three":"./vendor/three.module.js","three/addons/":"./vendor/jsm/"}}</script>
|
||
<script type="module" src="src/main.js"></script>
|
||
</body>
|
||
</html>
|