diff --git a/frontend/index.html b/frontend/index.html
index 7ee387a..5b9a183 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -261,6 +261,39 @@
Toprağın dijital nabzı
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -317,7 +350,6 @@
Toprağın altında, veriye dönüşen tarım<
-
@@ -435,6 +467,26 @@ Toprağın altında, veriye dönüşen tarım<
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/main.js b/frontend/src/main.js
index 510e662..8187db4 100644
--- a/frontend/src/main.js
+++ b/frontend/src/main.js
@@ -231,6 +231,7 @@ 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 = () => {
@@ -238,6 +239,19 @@ async function init() {
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", () => {
diff --git a/frontend/src/styles/welcome.css b/frontend/src/styles/welcome.css
index ee4da12..1c3f93e 100644
--- a/frontend/src/styles/welcome.css
+++ b/frontend/src/styles/welcome.css
@@ -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,
@@ -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; }
@@ -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; } }