feat(tema): açık / koyu / sistem teması
All checks were successful
Deploy / deploy (push) Successful in 6m23s

- TemaSaglayici (next-themes) + alt bilgide TemaSecici
- globals.css: .dark bloğunda palet token'ları çevrilir; bileşenlere
  dark: sınıfı yazılmaz
- yüzeyler bg-white → bg-card, koyu haplar text-slate-50, SVG'lerde
  sabit renk yerine değişken
- DESIGN.md §2.3 + tasarim-denetim kuralları (yuzey-beyaz,
  koyu-hap-beyaz-yazi, dark-sinif), AGENTS.md karanlık mod bölümü
- docs: koyu tema denetimi raporu

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
bilalgursen
2026-10-05 10:20:02 +03:00
parent 9e4c5608eb
commit 78ad84922a
70 changed files with 637 additions and 243 deletions

View File

@@ -82,40 +82,137 @@
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
/* Harita il zeminleri (tercih-haritasi, yurtdisi-haritalar) */
--kt-harita-secili: oklch(0.97 0.014 254.6); /* blue-50 */
--kt-harita-dolu: oklch(0.882 0.059 254.1); /* blue-200 */
}
.dark {
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
--card: oklch(0.205 0 0);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.205 0 0);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.707 0.143 254.6);
--primary-foreground: oklch(0.145 0 0);
--secondary: oklch(0.269 0 0);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.269 0 0);
--muted-foreground: oklch(0.708 0 0);
--accent: oklch(0.269 0 0);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.556 0 0);
--chart-1: oklch(0.87 0 0);
--chart-2: oklch(0.556 0 0);
--chart-3: oklch(0.439 0 0);
--chart-4: oklch(0.371 0 0);
--chart-5: oklch(0.269 0 0);
--sidebar: oklch(0.205 0 0);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.269 0 0);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.556 0 0);
/* Karanlık mod (DESIGN.md §2.3). Bileşenlere `dark:` sınıfı yazılmaz; tema
palet token'larını çevirerek çalışır: slate ölçeği ters döner (50 = sayfa
zemini, 900 = başlık metni), yüzeyler `bg-card`'dan gelir, renkli açık
zeminler (orange-50, amber-50…) koyu tona, koyu renkli metinler (amber-900,
emerald-800…) açık tona iner. `text-white` ve dolu marka zeminleri
(orange-500, primary, emerald-500…) iki temada aynıdır.
`@media screen`: yazdırma çıktısı tema ne olursa olsun açık kalır. */
@media screen {
.dark {
--background: oklch(0.21 0.03 262);
--foreground: oklch(0.95 0.008 250);
--card: oklch(0.21 0.03 262);
--card-foreground: oklch(0.95 0.008 250);
--popover: oklch(0.21 0.03 262);
--popover-foreground: oklch(0.95 0.008 250);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.26 0.03 262);
--secondary-foreground: oklch(0.95 0.008 250);
--muted: oklch(0.26 0.03 262);
--muted-foreground: oklch(0.68 0.04 257);
--accent: oklch(0.26 0.03 262);
--accent-foreground: oklch(0.95 0.008 250);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(0.31 0.03 260);
--input: oklch(0.31 0.03 260);
--sidebar: oklch(0.21 0.03 262);
--sidebar-foreground: oklch(0.95 0.008 250);
--sidebar-primary: oklch(0.623 0.188 259.8);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.26 0.03 262);
--sidebar-accent-foreground: oklch(0.95 0.008 250);
--sidebar-border: oklch(0.31 0.03 260);
--sidebar-ring: oklch(0.556 0 0);
/* Nötr ölçek: ters çevrilmiş slate. 950 çevrilmez — koyu vurgu
yüzeyinin (kt-koyu-yuzey) zeminidir, iki temada koyu kalır. */
--color-slate-50: oklch(0.165 0.025 262);
--color-slate-100: oklch(0.26 0.03 262);
--color-slate-200: oklch(0.31 0.03 260);
--color-slate-300: oklch(0.4 0.035 258);
--color-slate-400: oklch(0.6 0.04 257);
--color-slate-500: oklch(0.68 0.04 257);
--color-slate-600: oklch(0.76 0.035 256);
--color-slate-700: oklch(0.83 0.025 255);
--color-slate-800: oklch(0.89 0.015 255);
--color-slate-900: oklch(0.95 0.008 250);
/* Renkli açık zeminler ve kenarlıklar → koyu ton */
--color-orange-50: oklch(0.27 0.05 50);
--color-orange-100: oklch(0.32 0.07 50);
--color-orange-200: oklch(0.45 0.1 48);
--color-amber-50: oklch(0.27 0.045 80);
--color-amber-100: oklch(0.32 0.06 80);
--color-amber-200: oklch(0.45 0.09 78);
--color-emerald-50: oklch(0.26 0.04 165);
--color-emerald-100: oklch(0.31 0.055 165);
--color-emerald-200: oklch(0.42 0.08 165);
--color-red-50: oklch(0.26 0.05 25);
--color-red-100: oklch(0.31 0.07 25);
--color-red-200: oklch(0.42 0.1 25);
--color-rose-50: oklch(0.26 0.05 12);
--color-rose-100: oklch(0.31 0.07 12);
--color-sky-50: oklch(0.26 0.04 235);
--color-sky-100: oklch(0.31 0.055 235);
--color-sky-200: oklch(0.42 0.07 235);
--color-violet-50: oklch(0.27 0.05 293);
/* Koyu renkli metinler → açık ton (koyu zeminde okunsun) */
--color-orange-700: oklch(0.8 0.13 55);
--color-amber-700: oklch(0.84 0.13 85);
--color-amber-800: oklch(0.88 0.11 88);
--color-amber-900: oklch(0.92 0.08 90);
--color-emerald-600: oklch(0.74 0.15 163);
--color-emerald-700: oklch(0.8 0.13 163);
--color-emerald-800: oklch(0.86 0.11 164);
--color-emerald-900: oklch(0.91 0.08 165);
--color-red-600: oklch(0.7 0.19 24);
--color-red-700: oklch(0.77 0.15 22);
--color-red-800: oklch(0.84 0.11 20);
--color-red-900: oklch(0.9 0.07 18);
--color-rose-700: oklch(0.8 0.12 12);
--color-rose-800: oklch(0.86 0.09 10);
--color-sky-600: oklch(0.74 0.13 235);
--kt-harita-secili: oklch(0.27 0.05 258);
--kt-harita-dolu: oklch(0.42 0.1 258);
}
/* Koyu vurgu yüzeyi (CTA bandı, arama funnel kartı): zemini slate-950,
içindeki açık slate metinler iki temada aynı kalsın diye ölçek burada
açık temadaki değerlerine geri döner. */
.dark .kt-koyu-yuzey {
--color-slate-50: oklch(0.984 0.003 247.858);
--color-slate-100: oklch(0.968 0.007 247.896);
--color-slate-200: oklch(0.929 0.013 255.508);
--color-slate-300: oklch(0.869 0.022 252.894);
--color-slate-400: oklch(0.704 0.04 256.788);
--color-slate-500: oklch(0.554 0.046 257.417);
--color-slate-600: oklch(0.446 0.043 257.281);
--color-slate-700: oklch(0.372 0.044 257.287);
--color-slate-800: oklch(0.279 0.041 260.031);
--color-slate-900: oklch(0.208 0.042 265.755);
}
/* El çizimi şemalar (mermaid) açık kâğıt için çizilir: düğüm renkleri
tanımın içinde sabit. Koyu temada şema beyaz bir kâğıdın üstünde durur. */
.dark .kt-sema-kagit {
padding: 0.75rem;
border-radius: 1rem;
background: #fff;
}
/* Tek renk koyu logolar (URAP): koyu temada açığa çevrilir; yerleşim
oynamaz. Çok renkli marka logolarında kullanılmaz (renk bozulur). */
.dark .kt-koyu-cevir {
filter: invert(1) hue-rotate(180deg);
}
/* Çok renkli, koyu metinli logo görselleri (iyzico bandı: kart markaları)
beyaz hap üstünde durur. */
.dark .kt-acik-logo {
box-sizing: content-box;
padding: 0.5rem 0.875rem;
border-radius: 0.75rem;
background: #fff;
}
}
/* TypingAnimation imleci (animate-blink-cursor utility'si) */
@@ -280,14 +377,14 @@
Maske bulanıklığı aynı yönde söndürür — sert kenar kalmaz. */
.kt-sayfa-blur-ust {
top: 0;
background: linear-gradient(to top, transparent, #f8fafc);
background: linear-gradient(to top, transparent, var(--color-slate-50));
-webkit-mask-image: linear-gradient(to bottom, #000 50%, transparent);
mask-image: linear-gradient(to bottom, #000 50%, transparent);
}
.kt-sayfa-blur-alt {
bottom: 0;
background: linear-gradient(to bottom, transparent, #f8fafc);
background: linear-gradient(to bottom, transparent, var(--color-slate-50));
-webkit-mask-image: linear-gradient(to top, #000 50%, transparent);
mask-image: linear-gradient(to top, #000 50%, transparent);
}
@@ -373,7 +470,7 @@
border-radius: 9999px;
font-size: 0.875rem;
font-weight: 600;
color: #fff;
color: var(--color-slate-50);
background: var(--color-slate-900);
}
.toaster [data-sonner-toast][data-styled="true"] [data-button]:hover {

View File

@@ -26,7 +26,7 @@ export default function IletisimPage() {
</p>
<a
href="mailto:destek@kolaytercih.com"
className="mt-6 inline-flex items-center gap-2 rounded-full border border-slate-200 bg-white px-4 py-3 text-sm font-semibold text-slate-900 shadow-xs transition-colors hover:border-slate-300 hover:bg-slate-50"
className="mt-6 inline-flex items-center gap-2 rounded-full border border-slate-200 bg-card px-4 py-3 text-sm font-semibold text-slate-900 shadow-xs transition-colors hover:border-slate-300 hover:bg-slate-50"
>
<Mail className="size-4 text-primary" aria-hidden />
destek@kolaytercih.com

View File

@@ -12,6 +12,7 @@ import { HeaderGate } from "@/components/header-gate";
import { DevPanelMount } from "@/components/dev/dev-panel-mount";
import { ConsoleAsr } from "@/components/console-asr";
import { CerezBilgi } from "@/components/cerez-bilgi";
import { TemaSaglayici } from "@/components/tema-saglayici";
import { JsonLd, organizationJsonLd, webSiteJsonLd, SITE_URL } from "@/lib/seo";
import "./globals.css";
@@ -71,7 +72,11 @@ export const metadata: Metadata = {
};
export const viewport: Viewport = {
themeColor: "#f8fafc",
// Gövde zemini (bg-slate-50) — açık ve koyu temadaki karşılığı
themeColor: [
{ media: "(prefers-color-scheme: light)", color: "#f8fafc" },
{ media: "(prefers-color-scheme: dark)", color: "#080e19" },
],
};
export default function RootLayout({
@@ -82,16 +87,20 @@ export default function RootLayout({
return (
<html
lang="tr"
// next-themes ilk boyamadan önce <html>'e `dark` sınıfını ve
// color-scheme'i yazar; sunucu HTML'iyle fark beklenen bir farktır.
suppressHydrationWarning
// `h-full` verme: html auto yükseklikte içerikle büyür, viewport tabanı
// body'deki min-h-dvh'den gelir.
className={`${calSans.variable} ${clarityCity.variable} ${geistMono.variable} ${bricolage.variable} antialiased`}
>
<body className="min-h-dvh flex flex-col bg-slate-50">
<TemaSaglayici>
{/* Klavyeyle gelen için ilk durak: üst bandı ve menüyü atla
(WCAG 2.4.1). Odaklanınca görünür, sitenin hap ölçüsünde. */}
<a
href="#icerik"
className="sr-only focus:not-sr-only focus:fixed focus:top-3 focus:left-3 focus:z-[60] focus:inline-flex focus:h-11 focus:items-center focus:rounded-full focus:border focus:border-slate-200 focus:bg-white focus:px-4 focus:text-sm focus:font-semibold focus:text-slate-900 focus:shadow-lg focus:outline-none focus-visible:ring-3 focus-visible:ring-ring/50"
className="sr-only focus:not-sr-only focus:fixed focus:top-3 focus:left-3 focus:z-[60] focus:inline-flex focus:h-11 focus:items-center focus:rounded-full focus:border focus:border-slate-200 focus:bg-card focus:px-4 focus:text-sm focus:font-semibold focus:text-slate-900 focus:shadow-lg focus:outline-none focus-visible:ring-3 focus-visible:ring-ring/50"
>
İçeriğe geç
</a>
@@ -125,6 +134,7 @@ export default function RootLayout({
<ConsoleAsr />
{/* Dev süperadmin paneli — prod build'de modül grafiğine bile girmez */}
{process.env.NODE_ENV !== "production" ? <DevPanelMount /> : null}
</TemaSaglayici>
<JsonLd data={organizationJsonLd()} />
<JsonLd data={webSiteJsonLd()} />
{/* Rybbit analitik — afterInteractive: hydration sonrası client'ta

View File

@@ -243,7 +243,7 @@ export default function Home() {
</div>
<div
aria-hidden
className="pointer-events-none absolute inset-0 -z-10 bg-[radial-gradient(ellipse_58%_52%_at_50%_42%,rgba(248,250,252,0.9)_25%,rgba(248,250,252,0)_75%)]"
className="pointer-events-none absolute inset-0 -z-10 bg-[radial-gradient(ellipse_58%_52%_at_50%_42%,color-mix(in_oklab,var(--color-slate-50)_90%,transparent)_25%,transparent_75%)]"
/>
<Parallax
fromStart
@@ -257,7 +257,7 @@ export default function Home() {
>
<HeroForm />
</div>
<div className="mt-3 inline-flex items-center gap-2.5 rounded-lg border border-slate-200 bg-white px-3 py-2 text-left text-xs text-slate-700 shadow-xs">
<div className="mt-3 inline-flex items-center gap-2.5 rounded-lg border border-slate-200 bg-card px-3 py-2 text-left text-xs text-slate-700 shadow-xs">
<span>
<strong className="font-semibold text-slate-900">
Veri: YÖK Atlas
@@ -364,7 +364,7 @@ export default function Home() {
<Parallax strength={7} className="mt-12 grid gap-6 md:grid-cols-3">
{steps.map((s, i) => (
<Reveal key={s.step} delay={i * 0.08} className="h-full">
<div className="relative h-full rounded-2xl border border-slate-200/70 bg-white p-8 shadow-sm transition-all duration-300 hover:-translate-y-1 hover:border-orange-500 hover:shadow-lg hover:shadow-orange-500/5">
<div className="relative h-full rounded-2xl border border-slate-200/70 bg-card p-8 shadow-sm transition-all duration-300 hover:-translate-y-1 hover:border-orange-500 hover:shadow-lg hover:shadow-orange-500/5">
<span className="absolute -top-4 left-8 flex size-8 items-center justify-center rounded-full bg-orange-500 font-heading text-sm font-bold text-white">
{s.step}
</span>
@@ -385,7 +385,7 @@ export default function Home() {
<Parallax strength={10} className="mx-auto mt-12 w-full max-w-3xl">
<Reveal
delay={0.1}
className="overflow-hidden rounded-2xl border border-slate-200/70 bg-white shadow-sm"
className="overflow-hidden rounded-2xl border border-slate-200/70 bg-card shadow-sm"
>
<dl className="grid grid-cols-1 divide-y divide-slate-200 sm:grid-cols-3 sm:divide-x sm:divide-y-0">
{[
@@ -466,10 +466,10 @@ export default function Home() {
lg'de klasik dört sütunlu tablo. */}
<Parallax strength={7} className="mt-12">
<Reveal delay={0.08}>
<div className="rounded-2xl border border-slate-200/70 bg-white shadow-sm lg:hidden">
<div className="rounded-2xl border border-slate-200/70 bg-card shadow-sm lg:hidden">
<div
aria-hidden
className="sticky top-24 z-10 grid grid-cols-3 sm:top-32 gap-2 rounded-t-2xl border-b border-slate-100 bg-white/95 px-3 py-3 text-center text-sm font-semibold text-slate-500 backdrop-blur"
className="sticky top-24 z-10 grid grid-cols-3 sm:top-32 gap-2 rounded-t-2xl border-b border-slate-100 bg-card/95 px-3 py-3 text-center text-sm font-semibold text-slate-500 backdrop-blur"
>
<span>Robotlar ve botlar</span>
<span>İnsan danışman</span>
@@ -508,7 +508,7 @@ export default function Home() {
</ul>
</div>
<div className="hidden overflow-hidden rounded-2xl border border-slate-200/70 bg-white shadow-sm lg:block">
<div className="hidden overflow-hidden rounded-2xl border border-slate-200/70 bg-card shadow-sm lg:block">
<Table>
<TableHeader>
<TableRow className="bg-slate-50 hover:bg-slate-50">
@@ -590,7 +590,7 @@ export default function Home() {
>
<Reveal
delay={0.08}
className="rounded-2xl border-2 border-orange-500 bg-white p-8 shadow-sm"
className="rounded-2xl border-2 border-orange-500 bg-card p-8 shadow-sm"
>
<div className="flex flex-wrap items-baseline justify-between gap-2">
<h3 className="font-heading text-xl font-bold">
@@ -643,7 +643,7 @@ export default function Home() {
<Reveal
delay={0.16}
className="flex h-fit flex-col rounded-2xl border border-slate-200/70 bg-white p-6 shadow-sm sm:w-56"
className="flex h-fit flex-col rounded-2xl border border-slate-200/70 bg-card p-6 shadow-sm sm:w-56"
>
<div className="flex items-center gap-2">
<Coins className="size-4 text-amber-500" aria-hidden />
@@ -691,7 +691,7 @@ export default function Home() {
<Accordion
type="single"
collapsible
className="mt-10 rounded-2xl border border-slate-200/70 bg-white px-6 shadow-sm"
className="mt-10 rounded-2xl border border-slate-200/70 bg-card px-6 shadow-sm"
>
{faqs.map((faq) => (
<AccordionItem