From 87f011519a4ff2c2c2117cae514dfd8d5ad9495d Mon Sep 17 00:00:00 2001
From: bilalgursen
Date: Sun, 11 Oct 2026 02:03:06 +0300
Subject: [PATCH 1/2] =?UTF-8?q?feat(program-ayrinti):=20a=C3=A7=C4=B1l?=
=?UTF-8?q?=C4=B1=C5=9Fta=20logo=20kareleri=20ba=C5=9Fl=C4=B1=C4=9Fa=20de?=
=?UTF-8?q?=C4=9Fil=20g=C3=B6sterge=20karelerine=20d=C3=B6n=C3=BC=C5=9F?=
=?UTF-8?q?=C3=BCr?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Logonun üç karesi içerikteki kart alanlarına (kontenjan, netler, istihdam)
uçup onların boyuna büyür; kart kareden belirir. Başlık ilk andan görünür.
Hedefi olmayan kare olduğu yerde söner.
Co-Authored-By: Claude Opus 5.5
---
docs/tasarim/DESIGN.md | 9 ++-
src/components/ui/acilis-sahnesi.tsx | 76 ++++++++++++-------
.../katalog/components/program-ayrinti.tsx | 28 +++----
3 files changed, 68 insertions(+), 45 deletions(-)
diff --git a/docs/tasarim/DESIGN.md b/docs/tasarim/DESIGN.md
index b1f6396..20d77f9 100644
--- a/docs/tasarim/DESIGN.md
+++ b/docs/tasarim/DESIGN.md
@@ -723,8 +723,13 @@ sihirbaz modalı içindir; yeni bir ayrıntı için `Dialog` açılmaz.
altında yan yana durur, dokununca yer değiştirir. Odak dönüşen öğeyle gider (açılınca çarpı,
kapanınca kare). "Hareketi azalt"ta dönüşüm yok (`MotionConfig reducedMotion="user"`). Verisi
olmayan bölümün karesi çizilmez. 10 Ekim'deki "bu çekmecede kart yok" kuralı bu üç bölüm için
- kalktı; koşullar, üniversite ve kaynak satırı kartsız kalır. Açılış sahnesi değişmedi (logo →
- başlık); kareler tek `data-sonra` bloğu olarak netleşir.
+ kalktı; koşullar, üniversite ve kaynak satırı kartsız kalır.
+- **11 Eki 2026 — logo → gösterge kareleri:** Bilal: "logonun dönüştüğü başlık olmamalı, içerikteki
+ kart alanları olmalı." Logonun üç karesi artık başlığa değil, aşağıdaki gösterge karelerine uçar
+ ve onların boyuna büyür (`data-logo-hedef="sol|sag-ust|sag-alt"`, `AcilisSahnesi` sözleşmesi;
+ kareler sırayla sol / sağ üst / sağ alt logo karesini alır); kare uçuşun son yarısında solar,
+ kart o sırada belirir. Hedefi olmayan logo karesi (verisi olmayan bölüm) olduğu yerde söner.
+ Başlık ilk andan görünür. 10 Ekim'deki logo → başlık dönüşümü kalktı.
- **10 Eki 2026 — büyük logo, logo → başlık (morph):** Bilal: "logo küçücük kalmış; logolar
küçülürken başlıktaki yazıya morph olsun." Logo kabı `size-44` (akademik göstergelerdeki
logoyla aynı ölçek). Kareler sönmek yerine küçülerek (scale 0.2) başlık yazısının üç eşit
diff --git a/src/components/ui/acilis-sahnesi.tsx b/src/components/ui/acilis-sahnesi.tsx
index 6fb1336..008fab8 100644
--- a/src/components/ui/acilis-sahnesi.tsx
+++ b/src/components/ui/acilis-sahnesi.tsx
@@ -9,9 +9,10 @@
// - Kartsız (program-ayrinti.tsx, §4.19 "kart yok"): `[data-kare]` yok,
// `[data-logo]` kabındaki üç `[data-logo-kare]` belirir, kısa durur, sonra
// sönerek kaybolur (scale 0.6 + opacity 0; Bilal, 7 Eki 2026) ve
-// `[data-sonra]` bloklar netleşerek gelir. sahnenin kardeşi bir `[data-logo-hedef]` varsa kareler
-// sönmek yerine küçülerek o yazıya (çekmece başlığı) uçar, yazı onlardan
-// netleşir (Bilal, 10 Eki 2026).
+// `[data-sonra]` bloklar netleşerek gelir. İçerikte `[data-logo-hedef]`
+// kart alanları varsa kareler sönmek yerine aynı adlı karta uçar ve onun
+// boyuna büyür; kart kareden belirir (Bilal, 11 Eki 2026; önce çekmece
+// başlığına dönüşüyordu).
// "Hareketi azalt"ta logo ve büyüme yok, yalnız 0,25 s solma (§6). Veri
// bekleyen çekmecede (`hazir` verilmiş) sahne yalnız veri ilk geldiğinde
// (false → true) oynar; önbellekli yeniden açılışta aynı 0,25 s solma
@@ -58,8 +59,8 @@ const LOGO_ZAMANLARI = [
(LOGO_BELIRME + LOGO_DURUS) / LOGO_SURE,
1,
];
-// Hedefli kartsız mod: kareler sönmek yerine LOGO_UCUS süresince hedef yazıya
-// uçar; uçuşun son yarısında solar, yazı o sırada netleşir.
+// Hedefli kartsız mod: kareler sönmek yerine LOGO_UCUS süresince hedef karta
+// uçup onun boyuna büyür; uçuşun son yarısında solar, kart o sırada belirir.
const LOGO_UCUS = 0.45;
const UCUS_SURE = LOGO_BELIRME + LOGO_DURUS + LOGO_UCUS;
const UCUS_ZAMANLARI = [
@@ -127,9 +128,10 @@ export function logoKareStili(slot: Slot, kapBoyu = LOGO_KAP_BOYU) {
* çekmece daha ekrana kaymadan oynuyor, gövde boş kalıyordu. Verilmezse
* (içerik sunucudan hazır gelen çekmece) sahne her montajda oynar.
*
- * `data-logo-hedef`: kartsız modda logo karelerinin küçülerek dönüşeceği yazı
- * (sahnenin kardeşi, ör. çekmece başlığı). Kareler yazının üç eşit dilimine
- * uçar; yazı sahne başında görünmez olur, kareler varırken netleşir.
+ * `data-logo-hedef="sol|sag-ust|sag-alt"`: kartsız modda o logo karesinin
+ * dönüşeceği kart alanı (içerikte, ör. gösterge karesi). Kare kartın yerine
+ * uçup onun boyuna büyür; kart sahne başında görünmez olur, kare varırken
+ * belirir. Hedefi olmayan kare olduğu yerde söner.
*/
export function AcilisSahnesi({
children,
@@ -224,15 +226,12 @@ export function AcilisSahnesi({
// iner ki altında boşluk kalmasın; içerik KARTSIZ_ICERIK_BASI'ndan
// itibaren, sönmeyle çaprazlanarak gelir.
let sonKare = 0;
- // Hedef yazının kutusu (blok değil, yazının kendisi: Range).
- const hedef =
- kap.parentElement?.querySelector("[data-logo-hedef]") ?? null;
- let hedefKutu: DOMRect | null = null;
- if (hedef) {
- const aralik = document.createRange();
- aralik.selectNodeContents(hedef);
- hedefKutu = aralik.getBoundingClientRect();
- }
+ const hedefler = new Map();
+ kap
+ .querySelectorAll("[data-logo-hedef]")
+ .forEach((el) => hedefler.set(el.dataset.logoHedef ?? "", el));
+ // Logo kabı sıfır boya inince kartlar bu kadar yukarı kayar.
+ const logoBoyu = logo!.offsetHeight;
logoKareleri.forEach((el) => {
const slot = (el.dataset.logoKare ?? "sol") as Slot;
const sira = SLOT_SIRASI.indexOf(slot);
@@ -240,16 +239,31 @@ export function AcilisSahnesi({
sonKare = Math.max(sonKare, gecikme);
el.style.opacity = "0";
dokunulan.push(el);
- if (hedefKutu) {
+ const hedef = hedefler.get(slot);
+ if (hedef) {
// Kare ile hedef aynı çekmecede: çekmece kayarken fark değişmez.
const k = el.getBoundingClientRect();
- const dx =
- hedefKutu.left + (hedefKutu.width * (sira + 0.5)) / 3 - (k.left + k.width / 2);
- const dy = hedefKutu.top + hedefKutu.height / 2 - (k.top + k.height / 2);
+ const h = hedef.getBoundingClientRect();
+ const dx = h.left + h.width / 2 - (k.left + k.width / 2);
+ const dy = h.top + h.height / 2 - logoBoyu - (k.top + k.height / 2);
+ const sx = h.width / k.width;
+ const sy = h.height / k.height;
+ // Ölçek köşeyi de büyütür; kartın köşesi için ters ölçekli elips.
+ const kose = getComputedStyle(el).borderTopLeftRadius;
+ const kartKose = parseFloat(getComputedStyle(hedef).borderTopLeftRadius) || 0;
+ const ucusBasi = gecikme + LOGO_BELIRME + LOGO_DURUS;
+ hedef.style.opacity = "0";
+ dokunulan.push(hedef);
kontroller.push(
animate(
el,
- { x: [0, 0, 0, dx], y: [0, 0, 0, dy], scale: [0.4, 1, 1, 0.2] },
+ {
+ x: [0, 0, 0, dx],
+ y: [0, 0, 0, dy],
+ scaleX: [0.4, 1, 1, sx],
+ scaleY: [0.4, 1, 1, sy],
+ borderRadius: [kose, kose, kose, `${kartKose / sx}px / ${kartKose / sy}px`],
+ },
{
duration: UCUS_SURE,
delay: gecikme,
@@ -267,6 +281,11 @@ export function AcilisSahnesi({
ease: [GUCLU_CIKIS, "linear", "easeIn"],
},
),
+ animate(
+ hedef,
+ { opacity: [0, 1] },
+ { duration: LOGO_UCUS * 0.5, delay: ucusBasi + LOGO_UCUS * 0.4, ease: "easeOut" },
+ ),
);
return;
}
@@ -288,22 +307,21 @@ export function AcilisSahnesi({
});
const sonmeBasi = sonKare + LOGO_SURE * LOGO_ZAMANLARI[2];
dokunulan.push(logo!);
- if (hedef && hedefKutu) {
- netlestir(hedef, sonmeBasi + LOGO_UCUS * 0.4, 0.4);
- }
const kapat = animate(
logo!,
{ height: [logo!.offsetHeight, 0] },
- { duration: hedefKutu ? LOGO_UCUS : LOGO_SONME, delay: sonmeBasi, ease: YERLESME },
+ { duration: hedefler.size > 0 ? LOGO_UCUS : LOGO_SONME, delay: sonmeBasi, ease: YERLESME },
);
kapat.then(() => {
logo!.style.display = "none";
});
kontroller.push(kapat);
- sonra.forEach((el, i) =>
- netlestir(el, KARTSIZ_ICERIK_BASI + i * KARTSIZ_BLOK_ADIMI, KARTSIZ_NETLESME),
- );
+ sonra.forEach((el, i) => {
+ // Hedef kartları taşıyan blok kendi netleşmez: kartlar karelerden belirir.
+ if (el.querySelector("[data-logo-hedef]")) return;
+ netlestir(el, KARTSIZ_ICERIK_BASI + i * KARTSIZ_BLOK_ADIMI, KARTSIZ_NETLESME);
+ });
return temizle;
}
diff --git a/src/features/katalog/components/program-ayrinti.tsx b/src/features/katalog/components/program-ayrinti.tsx
index a39b0e5..914585f 100644
--- a/src/features/katalog/components/program-ayrinti.tsx
+++ b/src/features/katalog/components/program-ayrinti.tsx
@@ -197,15 +197,7 @@ export function ProgramAyrintiButonu({
Kapat
- {/* Başlık veri gelene dek görünmez: logo kareleri küçülüp buraya
- uçar, yazı onlardan netleşir (AcilisSahnesi `data-logo-hedef`). */}
-
+
{isim}
@@ -248,12 +240,13 @@ function AyrintiIcerik({ durum, veri }: { durum: Durum; veri: ProgramAyrintisi |
);
}
- // Sıra = AcilisSahnesi'nin `data-sonra` sırası: logo küçülerek başlığa
- // dönüşür, bloklar yukarıdan aşağıya 0,05 s arayla netleşir.
+ // Sıra = AcilisSahnesi'nin `data-sonra` sırası: logo kareleri gösterge
+ // karelerine dönüşür, bloklar yukarıdan aşağıya 0,05 s arayla netleşir.
return (
<>
- {/* Logo kareleri: sahne sırasında görünür, küçülerek başlığa uçar; kap
- sıfır boya iner. */}
+ {/* Logo kareleri: sahne sırasında görünür, aşağıdaki gösterge karelerine
+ uçup onlara dönüşür (BolumKutulari `data-logo-hedef`); kap sıfır boya
+ iner. */}
{LOGO_SLOTLARI.map((slot) => (
(
-
+ {
kareRef.current[x.anahtar] = el;
}}
@@ -618,6 +617,7 @@ function BolumKutulari({ veri }: { veri: ProgramAyrintisi }) {
— {x.baslik}, tamamını göster
+
);
return (
From 90181111f187027c318ac049ef8add05f8b57f7e Mon Sep 17 00:00:00 2001
From: bilalgursen
Date: Sun, 11 Oct 2026 02:09:22 +0300
Subject: [PATCH 2/2] chore(surum): 2.0.1
Co-Authored-By: Claude Opus 5.5
---
package.json | 2 +-
src/app/surum-notlari/page.tsx | 8 ++++++++
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 8971798..021ae96 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "kolaytercih",
- "version": "2.0.0",
+ "version": "2.0.1",
"private": true,
"scripts": {
"dev": "next dev",
diff --git a/src/app/surum-notlari/page.tsx b/src/app/surum-notlari/page.tsx
index 84f1d12..b164a25 100644
--- a/src/app/surum-notlari/page.tsx
+++ b/src/app/surum-notlari/page.tsx
@@ -26,6 +26,14 @@ const SURUMLER: {
maddeler: string[];
arayuz?: string[];
}[] = [
+ {
+ surum: "2.0.1",
+ tarih: "11 Ekim 2026",
+ maddeler: [],
+ arayuz: [
+ "Program ayrıntısı açılırken logo kareleri başlığa değil, kontenjan, netler ve mezun istihdamı karelerine dönüşür.",
+ ],
+ },
{
surum: "2.0.0",
tarih: "11 Ekim 2026",