Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 53 additions & 1 deletion frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,39 @@ <h1 class="welcome-title">Toprağın <span>dijital</span> nabzı</h1>
</div>
</div>

<!-- 🐜 1. TOPRAK KATMANI DEKORU: dolu kahverengide rise ile belirir (fill-intro gibi).
Yüzey-altı ışık hüzmesi + üstten sarkan kökler + karıncalar (biri yaprak taşır) +
çakıllar → geçiş katmanı boş/düz kalmasın. Merkez (başlık) temiz. -->
<div class="welcome-fill-decor" aria-hidden="true">
<!-- üstten sarkan kökler (yüzeyin altına geçtik) -->
<svg class="wfd-root" style="left:70%; width:34px;" viewBox="0 0 60 150" fill="none" stroke="#4f3620" stroke-linecap="round">
<path d="M30 0 C28 34 34 58 30 92 C26 126 32 140 30 150" stroke-width="4"/>
<path d="M30 64 C40 72 44 72 52 84" stroke-width="2.6"/>
</svg>
<!-- karınca izi (yaprak taşıyan dahil) -->
<svg class="wfd-ant" style="left:19%; top:64%;" viewBox="0 0 30 18" fill="none">
<path d="M9 10l-4 4M11 10l-2 5M14 10l-1 5M16 10l1 5M9 10l-4-2M16 10l2-3" stroke="#241710" stroke-width="1" stroke-linecap="round"/>
<ellipse cx="7" cy="9" rx="5" ry="4" fill="#2e1d11"/><ellipse cx="14" cy="9" rx="2.6" ry="2.4" fill="#2e1d11"/><circle cx="19" cy="9" r="3" fill="#2e1d11"/>
<path d="M21 7q3-3 5-4M21 9q3-1 6-1" stroke="#241710" stroke-width=".9" stroke-linecap="round"/><circle cx="20" cy="8.4" r=".7" fill="#e8d8c0"/>
</svg>
<svg class="wfd-ant" style="left:26%; top:69%;" viewBox="0 0 30 18" fill="none">
<path d="M9 10l-4 4M11 10l-2 5M14 10l-1 5M16 10l1 5M9 10l-4-2M16 10l2-3" stroke="#241710" stroke-width="1" stroke-linecap="round"/>
<ellipse cx="7" cy="9" rx="5" ry="4" fill="#2e1d11"/><ellipse cx="14" cy="9" rx="2.6" ry="2.4" fill="#2e1d11"/><circle cx="19" cy="9" r="3" fill="#2e1d11"/>
<path d="M21 7q3-3 5-4M21 9q3-1 6-1" stroke="#241710" stroke-width=".9" stroke-linecap="round"/><circle cx="20" cy="8.4" r=".7" fill="#e8d8c0"/>
</svg>
<svg class="wfd-ant wfd-ant-flip" style="left:78%; top:66%;" viewBox="0 0 30 18" fill="none">
<path d="M9 10l-4 4M11 10l-2 5M14 10l-1 5M16 10l1 5M9 10l-4-2M16 10l2-3" stroke="#241710" stroke-width="1" stroke-linecap="round"/>
<ellipse cx="7" cy="9" rx="5" ry="4" fill="#2e1d11"/><ellipse cx="14" cy="9" rx="2.6" ry="2.4" fill="#2e1d11"/><circle cx="19" cy="9" r="3" fill="#2e1d11"/>
<path d="M21 7q3-3 5-4M21 9q3-1 6-1" stroke="#241710" stroke-width=".9" stroke-linecap="round"/><circle cx="20" cy="8.4" r=".7" fill="#e8d8c0"/>
<path class="wfd-ant-load" d="M23 4 q4-3 6 1 q-2 4-6 2 Z" fill="#7cc36a"/>
</svg>
<!-- çakıllar -->
<span class="wfd-pebble" style="left:34%; top:80%; --s:9px;"></span>
<span class="wfd-pebble" style="left:63%; top:84%; --s:12px;"></span>
<span class="wfd-pebble" style="left:15%; top:85%; --s:8px;"></span>
<span class="wfd-pebble" style="left:84%; top:81%; --s:10px;"></span>
</div>

<!-- Dolum ÖDÜLÜ (#2): toprak dolarken başlık, dolu kahverenginin üstünde belirip
oturur. opacity/transform --rise'a bağlı (scroll-linked); pin'le yukarı kayıp gider. -->
<div class="welcome-fill-intro" aria-hidden="true">
Expand Down Expand Up @@ -317,7 +350,6 @@ <h2 class="wu-title">Toprağın altında, <span>veriye dönüşen</span> tarım<
<circle cx="131" cy="47" r="3.6" fill="#edabab"/>
<circle cx="134" cy="38" r="2.7" fill="#3a2414"/>
<circle cx="135" cy="37.1" r=".85" fill="#fff"/>
<path d="M129.5,45 Q133.5,49.5 138,44.5" stroke="#3a2414" stroke-width="1.7" stroke-linecap="round"/>
</svg>

<!-- 🍄 Mantar -->
Expand Down Expand Up @@ -435,6 +467,26 @@ <h2 class="wu-title">Toprağın altında, <span>veriye dönüşen</span> tarım<
<span class="wu-mineral" style="top:556vh; left:72%; --c:#f0c98f;"></span>
</div>

<!-- 🎬 Sinematik atmosfer: god-rays + toz zerreleri + derinlik sisi.
viewport'a STICKY (top:0, 100vh) → toprağa inince hep sahnede kalır; --depth-t
(JS, scroll 0→1) ile sis derinleştikçe koyulaşır. decor(z0) ÜSTÜ, scene(z1) ALTI. -->
<div class="wu-atmos" aria-hidden="true">
<span class="wu-ray" style="--x:7%; --w:250px; --rot:-13deg; --o:.55;"></span>
<span class="wu-ray" style="--x:26%; --w:150px; --rot:-17deg; --o:.32;"></span>
<span class="wu-ray" style="--x:62%; --w:120px; --rot:-9deg; --o:.22;"></span>
<span class="wu-mote" style="--x:9%; --y:24%; --s:3px; --d:13s; --dx:16px; --dy:-26px; --o:.6;"></span>
<span class="wu-mote" style="--x:14%; --y:52%; --s:2px; --d:17s; --dx:-12px; --dy:-30px; --o:.45;"></span>
<span class="wu-mote" style="--x:19%; --y:38%; --s:4px; --d:21s; --dx:20px; --dy:-22px; --o:.5;"></span>
<span class="wu-mote" style="--x:24%; --y:68%; --s:2.5px; --d:15s; --dx:14px; --dy:-34px; --o:.4;"></span>
<span class="wu-mote" style="--x:31%; --y:30%; --s:3px; --d:19s; --dx:-16px; --dy:-26px; --o:.45;"></span>
<span class="wu-mote" style="--x:40%; --y:58%; --s:2px; --d:23s; --dx:18px; --dy:-20px; --o:.32;"></span>
<span class="wu-mote" style="--x:52%; --y:42%; --s:3px; --d:18s; --dx:-14px; --dy:-30px; --o:.35;"></span>
<span class="wu-mote" style="--x:64%; --y:64%; --s:2.5px; --d:25s; --dx:12px; --dy:-24px; --o:.28;"></span>
<span class="wu-mote" style="--x:12%; --y:80%; --s:3px; --d:16s; --dx:22px; --dy:-28px; --o:.5;"></span>
<span class="wu-mote" style="--x:46%; --y:22%; --s:2px; --d:20s; --dx:-10px; --dy:-32px; --o:.3;"></span>
<div class="wu-fog"></div>
</div>

<!-- Özellik sahneleri (zigzag: kart bir tarafta, açıklama karşıda) -->
<section class="wu-scene" data-side="left">
<article class="wu-card wu-reveal" style="--accent:#38bdf8">
Expand Down
14 changes: 14 additions & 0 deletions frontend/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,13 +231,27 @@ async function init() {
const welcome = document.getElementById("welcome");
const pin = document.querySelector(".welcome-pin");
const act1 = document.querySelector(".welcome-act1");
const ug = document.querySelector(".welcome-underground");
if (!welcome || !pin || !act1) return;
let ticking = false;
const update = () => {
// sticky yol = act1 yüksekliği − 1 ekran (pin'in takılı kaldığı mesafe)
const travel = Math.max(act1.offsetHeight - welcome.clientHeight, 1);
const rise = Math.min(Math.max(welcome.scrollTop / travel, 0), 1); // [0,1] (iOS rubber-band clamp)
pin.style.setProperty("--rise", rise.toFixed(4));
// page-1'i geçince fill-intro + fill-decor SÖNSÜN (page-2 içeriğiyle üst üste binmesin):
const exit = Math.min(Math.max((welcome.scrollTop - travel) / (travel * 0.5), 0), 1);
pin.style.setProperty("--exit", exit.toFixed(4));
// 🎬 Toprak-altı sinematik derinlik: --depth-t (0=giriş → 1=en derin) sis için;
// --cam (px, ham scroll) parallax katmanları için. Underground act1'den SONRA başlar.
if (ug) {
const ugTop = act1.offsetHeight;
const ugRange = Math.max(welcome.scrollHeight - welcome.clientHeight - ugTop, 1);
const depthT = Math.min(Math.max((welcome.scrollTop - ugTop) / ugRange, 0), 1);
ug.style.setProperty("--depth-t", depthT.toFixed(4));
ug.style.setProperty("--cam", Math.round(welcome.scrollTop));
ug.style.setProperty("--rise", rise.toFixed(4)); // atmos opacity → yüzeyde gizli, dolumda belirir
}
ticking = false;
};
welcome.addEventListener("scroll", () => {
Expand Down
121 changes: 119 additions & 2 deletions frontend/src/styles/welcome.css
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
flex-shrink: 0;
height: 200vh;
position: relative; z-index: 4; /* soil(3)+filiz(2) üstünde → bindirme seam'i + Filiz sızmasını örter */
margin-top: -8px; /* pin altıyla hafif bindirme → sub-pixel boşluk/sızma kapanır (dikişsiz) */
margin-top: 0; /* TAM act1 dibinde başlar → page-1 snap'inde alttan SIZMAZ. Dikişi soil-fill'in
+2px bindirmesi + eşleşen #4e3119 renk kapatır (negatif margin sızmaya yol açıyordu). */
/* üst = soil SVG dibi (#4e3119) → dikişsiz; KADEMELİ ve nazik koyulaşır (sert bant yok),
dip hafif cooler/grayer (taşımsı derin toprak hissi). */
background: linear-gradient(180deg,
Expand Down Expand Up @@ -368,7 +369,7 @@ html:not([data-theme="light"]) .welcome-intro .wstar-descend { transform: transl
position: absolute; inset: 0; z-index: 4; pointer-events: none;
display: flex; flex-direction: column; align-items: center; justify-content: center;
text-align: center; padding: 0 30px;
opacity: clamp(0, calc((var(--rise, 0) - 0.5) * 2.6), 1);
opacity: calc(clamp(0, calc((var(--rise, 0) - 0.5) * 2.6), 1) * (1 - var(--exit, 0))); /* page-1'i geçince söner */
transform: translateY(clamp(0px, calc((0.88 - var(--rise, 0)) * 60px), 34px));
}
.welcome-fill-intro .wu-lead { max-width: 520px; }
Expand Down Expand Up @@ -674,3 +675,119 @@ html:not([data-theme="light"]) .welcome-intro .wstar-descend { transform: transl
text-transform: uppercase;
color: rgba(255, 255, 255, .55);
}

/* ════════════════════════════════════════════════════════════════
🎬 SİNEMATİK ATMOSFER — god-rays + toz zerreleri + derinlik sisi
.wu-atmos viewport'a STICKY; --depth-t (JS, scroll 0→1) ile sis
derinleşir. decor(z0) ÜSTÜ / scene(z1) ALTI. transform/opacity (GPU).
════════════════════════════════════════════════════════════════ */
.wu-atmos {
position: sticky; top: 0; height: 100vh; z-index: 0;
/* page-1'den (dolum) İTİBAREN yapışır → ışık TEK ve viewport-sabit katman: 1.→2. katman
geçişinde de huzmeler "kayar" (içerik altından akar). margin-top natural-top'u page-1'e (scroll
400) çeker; margin-bottom YOK → net flow 0 → SAHNELER KAYMAZ (margin-top+height+0 = 0). */
margin-top: -100vh;
pointer-events: none; overflow: hidden;
opacity: clamp(0, calc((var(--rise, 0) - 0.45) * 2), 1); /* yüzeyde gizli; dolumda belirir; yeraltında tam */
}
/* Işık huzmeleri — sol-üstten sıcak ışık, screen blend ile toprağı aydınlatır */
.wu-ray {
position: absolute; top: -25%; left: var(--x, 10%);
width: var(--w, 200px); height: 160%;
background: linear-gradient(to bottom,
color-mix(in srgb, #ffe9b5 36%, transparent) 0%,
color-mix(in srgb, #ffe9b5 13%, transparent) 42%,
transparent 76%);
transform: rotate(var(--rot, 13deg)); transform-origin: top center;
filter: blur(14px); mix-blend-mode: screen; opacity: var(--o, .5);
animation: wuRaySway 11s ease-in-out infinite alternate;
will-change: transform, opacity;
}
@keyframes wuRaySway {
from { transform: rotate(var(--rot, 13deg)) translateX(-7px); opacity: calc(var(--o, .5) * .72); }
to { transform: rotate(calc(var(--rot, 13deg) + 2.5deg)) translateX(7px); opacity: var(--o, .5); }
}
/* Toz zerreleri — ışıkta süzülen ince parçacıklar */
.wu-mote {
position: absolute; left: var(--x, 50%); top: var(--y, 50%);
width: var(--s, 3px); height: var(--s, 3px); border-radius: 50%;
background: radial-gradient(circle, rgba(255, 243, 214, .95), rgba(255, 243, 214, 0) 70%);
opacity: var(--o, .5);
animation: wuMoteDrift var(--d, 16s) ease-in-out infinite alternate;
will-change: transform;
}
@keyframes wuMoteDrift {
from { transform: translate(0, 0); }
to { transform: translate(var(--dx, 12px), var(--dy, -24px)); }
}
/* Derinlik sisi — vignette hep var; derinleştikçe (--depth-t) cool koyu artar (DoF hissi) */
.wu-fog {
position: absolute; inset: 0;
background:
radial-gradient(140% 105% at 50% 20%, transparent 38%, rgba(8, 6, 3, .62) 100%),
linear-gradient(180deg, transparent 35%,
color-mix(in srgb, #0a0e14 calc(var(--depth-t, 0) * 65%), transparent) 100%);
opacity: calc(.4 + var(--depth-t, 0) * .42);
}
@media (max-width: 768px) { /* mobil: tek huzme + daha hafif sis (perf) */
.wu-ray ~ .wu-ray { display: none; }
.wu-fog { opacity: calc(.3 + var(--depth-t, 0) * .35); }
}
@media (prefers-reduced-motion: reduce) {
.wu-ray, .wu-mote { animation: none; }
}

/* 🌙 GÜN/GECE IŞIK AÇISI — gündüz: güneş SOL-üst (mevcut, sıcak). Gece: ay SAĞ-üst
→ atmosferi yatay AYNALA (ışık sağdan gelir) + huzmeler daha SOLUK ve SOĞUK
(narin ay ışığı). data-theme yoksa = gece (default). */
html:not([data-theme="light"]) .wu-atmos { transform: scaleX(-1); }
html:not([data-theme="light"]) .wu-ray {
filter: blur(14px) opacity(.5); /* gece daha soluk/narin */
background: linear-gradient(to bottom,
color-mix(in srgb, #cfddf5 26%, transparent) 0%,
color-mix(in srgb, #cfddf5 9%, transparent) 42%,
transparent 76%); /* soğuk ay ışığı (mavimsi-beyaz) */
}

/* ════════════════════════════════════════════════════════════════
🐜 1. TOPRAK KATMANI DEKORU (.welcome-fill-decor) — dolum-ödülü brown'unda
rise ile belirir; yüzey-altı hüzme + sarkan kökler + karıncalar + çakıllar.
z-index: soil-fill(3) ÜSTÜ (DOM'da sonra) / fill-intro(4) ALTI. ════════════ */
.welcome-fill-decor {
position: absolute; inset: 0; z-index: 3;
overflow: hidden; pointer-events: none;
opacity: calc(clamp(0, calc((var(--rise, 0) - 0.55) * 2.6), 1) * (1 - var(--exit, 0))); /* belirir + page-1'i geçince söner */
}
.welcome-fill-decor svg { overflow: visible; }
/* yüzey-altı ışık hüzmesi (soluk; gündüz SOL, gece SAĞ — aşağıda mirror) */
.wfd-ray {
position: absolute; top: -15%; left: var(--x, 15%);
width: 165px; height: 130%;
background: linear-gradient(to bottom, color-mix(in srgb, #ffe9b5 26%, transparent) 0%, transparent 70%);
/* 1. katman: toprak kayarken (--rise) ışık YOKTAN büyüyüp parlayarak girer (yapışık değil) */
transform: rotate(var(--rot, -13deg)) scaleY(calc(0.35 + var(--rise, 0) * 0.65)); transform-origin: top center;
filter: blur(17px) brightness(calc(0.55 + var(--rise, 0) * 0.95)); mix-blend-mode: screen; opacity: var(--o, .35);
}
/* üstten sarkan kökler — hafif salınım */
.wfd-root { position: absolute; top: -2vh; transform-origin: top center; will-change: transform;
animation: wfdRootSway 7s ease-in-out infinite alternate; }
@keyframes wfdRootSway { from { transform: rotate(-1.5deg); } to { transform: rotate(1.5deg); } }
/* karıncalar — hafif yürüme bob'u */
.wfd-ant { position: absolute; width: 30px; will-change: transform; animation: wfdAntWalk 2.4s ease-in-out infinite; }
.wfd-ant-flip { transform: scaleX(-1); animation: wfdAntWalkFlip 2.4s ease-in-out infinite; }
@keyframes wfdAntWalk { 0%,100% { transform: translate(0,0); } 50% { transform: translate(3px,-1.5px); } }
@keyframes wfdAntWalkFlip { 0%,100% { transform: scaleX(-1) translate(0,0); } 50% { transform: scaleX(-1) translate(3px,-1.5px); } }
/* çakıllar */
.wfd-pebble {
position: absolute; width: var(--s, 10px); height: calc(var(--s, 10px) * .72);
border-radius: 50%; background: radial-gradient(circle at 38% 32%, #6e5235, #3a2a18 72%);
box-shadow: inset 0 1px 1px rgba(255, 255, 255, .12);
}
/* 🌙 gece: hüzmeyi SAĞA al + ters açı + soluk/soğuk (narin ay ışığı); kök/karınca aynen kalır */
html:not([data-theme="light"]) .wfd-ray {
left: auto; right: var(--x, 15%);
transform: rotate(calc(var(--rot, -13deg) * -1)) scaleY(calc(0.35 + var(--rise, 0) * 0.65));
filter: blur(17px) brightness(calc(0.5 + var(--rise, 0) * 0.7)) opacity(.6);
background: linear-gradient(to bottom, color-mix(in srgb, #cfddf5 22%, transparent) 0%, transparent 70%);
}
@media (prefers-reduced-motion: reduce) { .wfd-ray, .wfd-root, .wfd-ant, .wfd-ant-flip { animation: none; } }
Loading