feat(v2): 9–10 Ekim çalışma ağacı — deneyim dili 1. dalga, PWA manifest, revizyon niyet modeli, listem/tadımlık bileşen denetimi
9–10 Ekim oturumlarının commit'lenmemiş işi tek parça alındı (raporlar: docs/ekip-raporlari/2026-10-09, 2026-10-10): - Landing deneyim dili 1. dalga: sayfa geçişi (ViewTransition), piksel morf/şerit, sorun sahneleri, adım akışı, sayan sayı, mobil menü, adım göstergesi, logoya tepki; DESIGN.md §11 ve AGENTS.md kuralları, tasarım denetimine yeni kurallar - Tema: tema ikonu, D kısayolu, tema geçişi - PWA: manifest.ts ve ikonlar - Danışman: revizyon niyet modeli (OPENROUTER_NIYET_MODEL), sohbet geçmişi, soru API'si - /listem ve /sonuc tadımlığı bileşen denetimi düzeltmeleri - eslint: .venv-tts/ yok sayılır tsc, eslint ve tasarım denetimi sıfır hata. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -74,6 +74,11 @@
|
||||
--chart-4: oklch(0.371 0 0);
|
||||
--chart-5: oklch(0.269 0 0);
|
||||
--radius: 0.625rem;
|
||||
/* Hareket eğrileri (DESIGN.md §6); JS karşılığı src/lib/hareket.ts EGRI */
|
||||
--egri-giris: cubic-bezier(0.16, 1, 0.3, 1);
|
||||
--egri-standart: cubic-bezier(0.22, 1, 0.36, 1);
|
||||
--egri-guclu-cikis: cubic-bezier(0.23, 1, 0.32, 1);
|
||||
--egri-yerlesme: cubic-bezier(0.32, 0.72, 0, 1);
|
||||
--sidebar: oklch(0.985 0 0);
|
||||
--sidebar-foreground: oklch(0.145 0 0);
|
||||
--sidebar-primary: oklch(0.205 0 0);
|
||||
@@ -484,3 +489,297 @@
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tema geçişi (DESIGN.md §2.3, lib/tema-gecisi.ts): yeni tema header'daki
|
||||
logodan yumuşak bir halka gibi açılır. Eski görüntü yerinde durur; yeni
|
||||
görüntü radyal degrade maskesiyle üstünde belirir. Maskenin kenarı keskin
|
||||
değil: yarıçapın %55'ine kadar tam opak, oradan kenara doğru tüy gibi
|
||||
söner (--kt-tema-cekirdek; JS'teki CEKIRDEK ile aynı olmalı) — ışık
|
||||
yayılır gibi, sert çizgi yok. Yarıçap (--kt-tema-r) 0 → --kt-tema-son
|
||||
yumuşak kalkıp yumuşak durur; kısa ve hafif (600 ms) — asıl gösteri,
|
||||
geçiş bitince oynayan logo dönüşümüdür. Merkez ve son yarıçap JS'ten gelir.
|
||||
Hareket azaltılmışsa JS geçişi hiç başlatmaz, tema düz değişir. */
|
||||
@property --kt-tema-r {
|
||||
syntax: "<length>";
|
||||
inherits: true;
|
||||
initial-value: 0px;
|
||||
}
|
||||
.kt-tema-gecis {
|
||||
view-transition-name: root;
|
||||
--kt-tema-cekirdek: 0.55;
|
||||
}
|
||||
.kt-tema-gecis::view-transition-old(root),
|
||||
.kt-tema-gecis::view-transition-new(root) {
|
||||
animation: none;
|
||||
mix-blend-mode: normal;
|
||||
}
|
||||
.kt-tema-gecis::view-transition-old(root) {
|
||||
z-index: 1;
|
||||
}
|
||||
.kt-tema-gecis::view-transition-new(root) {
|
||||
z-index: 2;
|
||||
mask-image: radial-gradient(
|
||||
circle at var(--kt-tema-x) var(--kt-tema-y),
|
||||
#000 calc(var(--kt-tema-r) * var(--kt-tema-cekirdek)),
|
||||
transparent var(--kt-tema-r)
|
||||
);
|
||||
animation: kt-tema-halka 600ms cubic-bezier(0.4, 0, 0.2, 1) both;
|
||||
}
|
||||
@keyframes kt-tema-halka {
|
||||
from {
|
||||
--kt-tema-r: 0px;
|
||||
}
|
||||
to {
|
||||
--kt-tema-r: var(--kt-tema-son);
|
||||
}
|
||||
}
|
||||
|
||||
/* Sayfa geçişi (DESIGN.md §6, components/sayfa-gecisi.tsx): rota değişince
|
||||
eski içerik hızla söner, yenisi hafifçe yükselerek belirir — çıkış girişten
|
||||
hızlı. Üst çubuk kendi grubunda ve animasyonsuz: içerik değişir, çubuk
|
||||
yerinde kalır (uygulama hissi, §11.4). Tema geçişinde (`.kt-tema-gecis`)
|
||||
çubuk adını bırakır ki halka onu da kaplasın. */
|
||||
.kt-ust-cubuk {
|
||||
view-transition-name: kt-ust-cubuk;
|
||||
}
|
||||
.kt-tema-gecis .kt-ust-cubuk {
|
||||
view-transition-name: none;
|
||||
}
|
||||
::view-transition-group(kt-ust-cubuk) {
|
||||
animation: none;
|
||||
z-index: 100;
|
||||
}
|
||||
::view-transition-old(kt-ust-cubuk) {
|
||||
display: none;
|
||||
}
|
||||
::view-transition-new(kt-ust-cubuk) {
|
||||
animation: none;
|
||||
}
|
||||
::view-transition-old(.kt-sayfa-cik) {
|
||||
animation: 120ms var(--egri-standart) both kt-sayfa-sol reverse;
|
||||
}
|
||||
::view-transition-new(.kt-sayfa-gir) {
|
||||
animation:
|
||||
200ms var(--egri-standart) 80ms both kt-sayfa-sol,
|
||||
280ms var(--egri-giris) both kt-sayfa-yuksel;
|
||||
}
|
||||
@keyframes kt-sayfa-sol {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@keyframes kt-sayfa-yuksel {
|
||||
from {
|
||||
translate: 0 8px;
|
||||
}
|
||||
to {
|
||||
translate: 0 0;
|
||||
}
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
::view-transition-old(.kt-sayfa-cik),
|
||||
::view-transition-new(.kt-sayfa-gir) {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ana sayfa ilk ekranının girişi (DESIGN.md §6 "sayfa başına tek orkestre
|
||||
giriş", §11.2): önce harita belirir, sonra başlık, sonra form netleşerek
|
||||
gelir — sırayla, üst üste binmeden. `--sira` ile kademelenir. Başlık LCP
|
||||
öğesi olduğundan hiçbir kare tam saydam başlamaz (opaklık 0,35'ten). */
|
||||
.kt-hero-gir {
|
||||
animation: kt-hero-gir 0.7s var(--egri-giris) both;
|
||||
animation-delay: calc(var(--sira, 0) * 110ms + 80ms);
|
||||
}
|
||||
.kt-hero-harita {
|
||||
animation: kt-hero-harita 1.1s var(--egri-standart) both;
|
||||
}
|
||||
@keyframes kt-hero-gir {
|
||||
from {
|
||||
opacity: 0.35;
|
||||
filter: blur(10px);
|
||||
translate: 0 12px;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
filter: blur(0);
|
||||
translate: 0 0;
|
||||
}
|
||||
}
|
||||
@keyframes kt-hero-harita {
|
||||
from {
|
||||
opacity: 0;
|
||||
scale: 0.985;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
scale: 1;
|
||||
}
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.kt-hero-gir,
|
||||
.kt-hero-harita {
|
||||
animation: kt-unblur-sade 0.25s ease-out both;
|
||||
}
|
||||
}
|
||||
|
||||
/* "Nasıl çalışır" adımları arasındaki çizgi (DESIGN.md §4.32): adımın rakamı
|
||||
biçimine dönüşüp geri toplanınca (adim-akisi.tsx `data-dolu` yazar) soldan
|
||||
maviyle dolar. JS'siz istemcide dolu durur. */
|
||||
@media (scripting: enabled) {
|
||||
.kt-cizgi-dol {
|
||||
transform: scaleX(0);
|
||||
transform-origin: left;
|
||||
transition: transform 0.6s var(--egri-guclu-cikis);
|
||||
}
|
||||
.kt-cizgi-dol[data-dolu] {
|
||||
transform: scaleX(1);
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.kt-cizgi-dol {
|
||||
transform: none;
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Piksel morf (components/piksel-morf.tsx, DESIGN.md §4.38): her piksel bir
|
||||
<g>; yeri `translate` ile verilir ve kare değişince yeni hücresine süzülür.
|
||||
`gizli` küçülüp söner. Turuncu vurgu, doku karesinin üstündeki ikinci
|
||||
karedir: çabuk ısınır, yavaş soğur (ısı fırçasıyla aynı asimetri).
|
||||
Sekme yok (§6); kayma süresi sahneye göre `--morf-sure` ile ayarlanır. */
|
||||
.kt-morf-px {
|
||||
transform-box: fill-box;
|
||||
transform-origin: center;
|
||||
transition:
|
||||
translate var(--morf-sure, 0.55s) var(--egri-standart) var(--g, 0ms),
|
||||
opacity 0.3s var(--egri-standart) var(--g, 0ms),
|
||||
scale 0.3s var(--egri-standart) var(--g, 0ms);
|
||||
}
|
||||
.kt-morf-px[data-ton="gizli"] {
|
||||
opacity: 0;
|
||||
scale: 0.6;
|
||||
}
|
||||
.kt-morf-vurgu {
|
||||
opacity: 0;
|
||||
fill-opacity: 0.7;
|
||||
transition: opacity 1.2s var(--egri-standart);
|
||||
}
|
||||
.kt-morf-taban {
|
||||
transition: opacity 0.6s var(--egri-standart);
|
||||
}
|
||||
.kt-morf-px[data-ton="vurgu"] > .kt-morf-taban {
|
||||
opacity: 0;
|
||||
transition: opacity 0.25s var(--egri-standart) var(--g, 0ms);
|
||||
}
|
||||
.kt-morf-px[data-ton="vurgu"] > .kt-morf-vurgu {
|
||||
opacity: 1;
|
||||
animation:
|
||||
kt-morf-isin 0.25s var(--egri-standart) var(--g, 0ms) backwards,
|
||||
kt-morf-nabiz 3.6s ease-in-out var(--n, 0s) infinite;
|
||||
}
|
||||
@keyframes kt-morf-isin {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@keyframes kt-morf-nabiz {
|
||||
50% {
|
||||
fill-opacity: 0.35;
|
||||
}
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.kt-morf-px,
|
||||
.kt-morf-taban,
|
||||
.kt-morf-vurgu {
|
||||
transition: none;
|
||||
}
|
||||
.kt-morf-px[data-ton="vurgu"] > .kt-morf-vurgu {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Kendini çizen tik (landing-parcalari.tsx, DESIGN.md §5.2.3): karşılaştırma
|
||||
tablosu ekrana girince (Reveal → .kt-reveal-in) önce halka, sonra işaret
|
||||
çizilir; satır gecikmesi `--tik-g` ile gelir. `pathLength="1"` bekler. */
|
||||
@media (scripting: enabled) and (prefers-reduced-motion: no-preference) {
|
||||
.kt-reveal .kt-tik-ciz {
|
||||
stroke-dasharray: 1;
|
||||
stroke-dashoffset: 1;
|
||||
opacity: 0;
|
||||
transition:
|
||||
stroke-dashoffset 0.5s var(--egri-standart) calc(var(--tik-g, 0ms) + 250ms),
|
||||
opacity 0.01s linear calc(var(--tik-g, 0ms) + 250ms);
|
||||
}
|
||||
.kt-reveal .kt-tik-isaret {
|
||||
transition-duration: 0.3s, 0.01s;
|
||||
transition-delay:
|
||||
calc(var(--tik-g, 0ms) + 600ms),
|
||||
calc(var(--tik-g, 0ms) + 600ms);
|
||||
}
|
||||
.kt-reveal.kt-reveal-in .kt-tik-ciz {
|
||||
stroke-dashoffset: 0;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Hero haritasının serpintisi (turkey-pixel-map.tsx, DESIGN.md §11.1 V2):
|
||||
piksel bir süre yerinde durur, kopup `--d` birim (10 = bir hücre) düşerken
|
||||
söner, sonra yerinde yeniden belirir. Süre ve faz satır içi. */
|
||||
@keyframes kt-serpinti {
|
||||
0%,
|
||||
42% {
|
||||
translate: 0 0;
|
||||
opacity: 1;
|
||||
animation-timing-function: ease-in;
|
||||
}
|
||||
76% {
|
||||
translate: 0 calc(var(--d, 20) * 1px);
|
||||
opacity: 0;
|
||||
animation-timing-function: step-end;
|
||||
}
|
||||
80% {
|
||||
translate: 0 0;
|
||||
opacity: 0;
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
100% {
|
||||
translate: 0 0;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.kt-serpinti {
|
||||
animation: kt-serpinti 6s infinite;
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.kt-serpinti {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Piksel şeridi (components/piksel-serit.tsx, DESIGN.md §4.38): kaydırmaya
|
||||
bağlı sütun. Okuma çizgisini geçen piksel `data-yandi` alır ve turuncuya
|
||||
ısınır; geri kaydırınca yavaş soğur. Şeridin ucu (`data-uc`) tam turuncu. */
|
||||
.kt-serit-px {
|
||||
fill: currentColor;
|
||||
fill-opacity: var(--op, 0.2);
|
||||
transition:
|
||||
fill 0.9s var(--egri-standart),
|
||||
fill-opacity 0.9s var(--egri-standart);
|
||||
}
|
||||
.kt-serit-px[data-yandi] {
|
||||
fill: var(--color-orange-500);
|
||||
fill-opacity: 0.62;
|
||||
transition-duration: 0.16s;
|
||||
}
|
||||
.kt-serit-px[data-uc] {
|
||||
fill-opacity: 1;
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.kt-serit-px {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user