diff --git a/components.json b/components.json
index cb51d7a..cb47ab0 100644
--- a/components.json
+++ b/components.json
@@ -23,6 +23,7 @@
},
"registries": {
"@skiper-ui": "https://skiper-ui.com/registry/{name}.json",
- "@magicui": "https://magicui.design/r/{name}"
+ "@magicui": "https://magicui.design/r/{name}",
+ "@uiarc": "https://uiarc.dev/r/{name}.json"
}
}
diff --git a/docs/tasarim/DESIGN.md b/docs/tasarim/DESIGN.md
index 5a9faa6..91d6a88 100644
--- a/docs/tasarim/DESIGN.md
+++ b/docs/tasarim/DESIGN.md
@@ -686,6 +686,26 @@ genişletilebilir olmalı; UI için prompt-kit kullan."
zaman yazılıdır (§2.2). Sohbet ilerlese de kalır. Yeni bir liste uyarısı gerekince
`listeUyarilari`'na eklenir, sayfaya yeni kutu açılmaz.
+### 4.21 Sayı rulosu — `SayiRulo`, `src/components/ui/sayi-rulo.tsx`
+Ekranda **değişen** sayı (üst çubuk rozeti ve kredi hapı, "Listende 5/24", çekmece sayacı,
+danışman kredi rozeti, "40 / 312 program", üst şeridin sezon geri sayımı, giriş formunun
+"Yeniden gönder (59)" sayacı, kaydet bildirimindeki seçim sayısı) rulo gibi döner:
+eklemede yukarı, çıkarmada aşağı; basamak artınca yeni sütun yayla açılır. Yazı boyu/rengi
+kapsayıcıdan gelir. Yay §6 varsayılanı; hareketi azalt'ta düz metin; ekran okuyucu düz metni
+okur. Kaynak Arc UI "Number field" (uiarc.dev, 6 Eki 2026); oradaki −/+ adım butonları ve
+sürükleme alınmadı — sıralama girişi `Input` hapı olarak kalır (§4.6), rulo yalnız gösterime
+takılır. Durağan sayıya (taban sıralaması, kontenjan) takılmaz. Geri sayım gibi basamak
+dolgusu isteyen sayaçta `enAzBasamak={2}` ("05") ve sabit `yon={-1}` (00 → 59 sarması da aşağı
+döner) verilir; sitede ikinci bir rakam kütüphanesi yoktur (`@number-flow/react` 6 Eki 2026'da
+kaldırıldı, üst şerit de bu ruloyu kullanır).
+
+### 4.22 Kayan vurgulu seçim hapları — `SecimHaplari`, `src/components/ui/secim-haplari.tsx`
+Tek seçimli hap grubunda seçili vurgu yeniden boyanmaz, tek yüzey olarak seçenekten seçeneğe
+**kayar** (`layoutId`). `ayrik`: kenarlıklı ayrı haplar + mavi dolu vurgu (puan türü çipleri —
+hero ve CTA formu). `kapsul`: tek kapsülde koyu hap, yazı `text-slate-50` (tema seçici). Yay §6;
+hareketi azalt'ta vurgu yerinde belirir. Kaynak Arc UI "Chip group" (6 Eki 2026). Çok seçimli
+çipler (sihirbaz alan/il) bu desene girmez — orada her çip kendi başına yanar.
+
## 5. Yerleşim
### 5.1 Genel
diff --git a/package.json b/package.json
index b44556d..e2ad7c0 100644
--- a/package.json
+++ b/package.json
@@ -31,7 +31,6 @@
"@ai-sdk/react": "^4.0.130",
"@cds/city": "^1.1.0",
"@libsql/client": "^0.17.4",
- "@number-flow/react": "^0.6.2",
"@shadcn/helpers": "^0.2.0",
"ai": "^7.0.127",
"better-auth": "^1.6.23",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index de81d55..3bb9b06 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -20,9 +20,6 @@ importers:
'@libsql/client':
specifier: ^0.17.4
version: 0.17.4
- '@number-flow/react':
- specifier: ^0.6.2
- version: 0.6.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@shadcn/helpers':
specifier: ^0.2.0
version: 0.2.0(ai@7.0.127(zod@4.4.3))
@@ -1289,12 +1286,6 @@ packages:
resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==}
engines: {node: '>=12.4.0'}
- '@number-flow/react@0.6.2':
- resolution: {integrity: sha512-WjZuV4aA+vhRCgCF+adGLgFVVAJ8vdvq6EchRT2FiBIgElTXtDOA3YgkcMr9UHpvpS9v4H70AB5wZv0D9jc3QA==}
- peerDependencies:
- react: ^18 || ^19
- react-dom: ^18 || ^19
-
'@opentelemetry/semantic-conventions@1.43.0':
resolution: {integrity: sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==}
engines: {node: '>=14'}
@@ -3547,9 +3538,6 @@ packages:
jiti:
optional: true
- esm-env@1.2.2:
- resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==}
-
espree@10.4.0:
resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -4692,9 +4680,6 @@ packages:
resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==}
engines: {node: '>=18'}
- number-flow@0.6.2:
- resolution: {integrity: sha512-MCnImG4Q5vPwhSXnov56nOuyyKn6LC+Qd7II1UiKc+ACRtug5iAtn0+CwXNxM38AC5lSowEY+oYEtZX2qMnUyw==}
-
oauth-sign@0.9.0:
resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==}
@@ -6693,13 +6678,6 @@ snapshots:
'@nolyfill/is-core-module@1.0.39': {}
- '@number-flow/react@0.6.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
- dependencies:
- esm-env: 1.2.2
- number-flow: 0.6.2
- react: 19.2.4
- react-dom: 19.2.4(react@19.2.4)
-
'@opentelemetry/semantic-conventions@1.43.0': {}
'@postman/form-data@3.1.1':
@@ -9109,8 +9087,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- esm-env@1.2.2: {}
-
espree@10.4.0:
dependencies:
acorn: 8.17.0
@@ -10435,10 +10411,6 @@ snapshots:
path-key: 4.0.0
unicorn-magic: 0.3.0
- number-flow@0.6.2:
- dependencies:
- esm-env: 1.2.2
-
oauth-sign@0.9.0: {}
object-assign@4.1.1: {}
diff --git a/src/components/site-top-banner.tsx b/src/components/site-top-banner.tsx
index 52b9032..589fbc9 100644
--- a/src/components/site-top-banner.tsx
+++ b/src/components/site-top-banner.tsx
@@ -1,7 +1,7 @@
"use client";
+import { SayiRulo } from "@/components/ui/sayi-rulo";
import { startTransition, useEffect, useState } from "react";
-import NumberFlow, { NumberFlowGroup } from "@number-flow/react";
import { CalendarDays, Clock3 } from "lucide-react";
import {
BANT_ARIA,
@@ -131,45 +131,28 @@ export function SiteTopBanner() {
: "Geri sayım yükleniyor"
}
>
-
- {BIRIMLER.map(({ anahtar, etiket }) => (
-
-
{etiket}
-
- {geriSayim ? (
-
- ) : (
- "--"
- )}
-
- {etiket}
-
-
-
- ))}
-
+ {/* Rulo rakam (DESIGN.md §4.21): her birim kendi tekerleğinde
+ aşağı döner; 00 → 59 sarması da aşağı (yon=-1). */}
+ {BIRIMLER.map(({ anahtar, etiket }) => (
+
+
{etiket}
+
+ {geriSayim ? (
+
+ ) : (
+ "--"
+ )}
+
+ {etiket}
+
+
+
+ ))}
) : null}
diff --git a/src/components/tema-secici.tsx b/src/components/tema-secici.tsx
index f4a2e0d..9290305 100644
--- a/src/components/tema-secici.tsx
+++ b/src/components/tema-secici.tsx
@@ -3,20 +3,22 @@
import { useSyncExternalStore } from "react";
import { useTheme } from "next-themes";
import { Monitor, Moon, Sun } from "lucide-react";
-import { cn } from "@/lib/utils";
+import { SecimHaplari } from "@/components/ui/secim-haplari";
const SECENEKLER = [
{ deger: "light", etiket: "Açık", ikon: Sun },
{ deger: "dark", etiket: "Koyu", ikon: Moon },
{ deger: "system", etiket: "Sistem", ikon: Monitor },
] as const;
+type Tema = (typeof SECENEKLER)[number]["deger"];
const aboneOlma = () => () => {};
/**
* Tema seçici: açık / koyu / sistem (DESIGN.md §2.3). Seçili tema yalnızca
* tarayıcıda bilinir; sunucu HTML'inde hiçbir seçenek işaretli gelmez,
- * hydration sonrası işaretlenir (yerleşim oynamaz).
+ * hydration sonrası işaretlenir (yerleşim oynamaz). Koyu vurgu seçenekten
+ * seçeneğe kayar (secim-haplari.tsx, kapsül varyantı).
*/
export function TemaSecici({ className }: { className?: string }) {
const { theme, setTheme } = useTheme();
@@ -25,37 +27,19 @@ export function TemaSecici({ className }: { className?: string }) {
() => true,
() => false,
);
+ const secili = tarayicida
+ ? (SECENEKLER.find((s) => s.deger === theme)?.deger ?? null)
+ : null;
return (
-
- {SECENEKLER.map(({ deger, etiket, ikon: Ikon }) => {
- const secili = tarayicida && theme === deger;
- return (
-
- );
- })}
-
+
+ ariaLabel="Tema"
+ secenekler={SECENEKLER}
+ deger={secili}
+ onChange={setTheme}
+ varyant="kapsul"
+ boyut="md"
+ className={className}
+ />
);
}
diff --git a/src/components/ui/sayi-rulo.tsx b/src/components/ui/sayi-rulo.tsx
new file mode 100644
index 0000000..0dd7ad1
--- /dev/null
+++ b/src/components/ui/sayi-rulo.tsx
@@ -0,0 +1,172 @@
+"use client";
+
+// Rulo rakam (odometer): sayı değişince her basamak kendi tekerleğinde döner —
+// artarken yukarı, azalırken aşağı; 9 → 0 sarar, 10 → 9 geri döner. Basamak
+// sayısı değişince (9 → 10) yeni sütun genişliğini yayla açar, kalkan sütun
+// kapanır; sütunlar basamak değerine göre anahtarlı olduğundan birler hanesi
+// hep birler hanesi kalır.
+//
+// Kaynak: Arc UI "Number field" (uiarc.dev) rakam rulosu. Oradaki adım
+// butonları, sürükleyerek değiştirme ve sınır notu alınmadı — 6 haneli
+// sıralama girişine uymuyor; rulo yalnız EKRANDA DEĞİŞEN sayıya takılır
+// (liste sayacı gibi). Yay DESIGN.md §6 varsayılanı (sekmesiz, 0,35 s);
+// hareketi azalt'ta düz metin. Ekran okuyucu düz metni okur, rulo aria-hidden.
+
+import { useLayoutEffect, useRef, useState } from "react";
+import {
+ AnimatePresence,
+ animate,
+ motion,
+ useMotionValue,
+ useReducedMotion,
+ useTransform,
+ type MotionValue,
+ type Variants,
+} from "motion/react";
+import { cn } from "@/lib/utils";
+
+const YAY = { type: "spring", bounce: 0, duration: 0.35 } as const;
+const RAKAMLAR = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+const BICIMLER = new Map();
+/** Basamak dolgusu isteyen sayaç (geri sayım "05") binlik ayracı kullanmaz. */
+function bicimAl(enAzBasamak: number): Intl.NumberFormat {
+ let b = BICIMLER.get(enAzBasamak);
+ if (!b) {
+ b = new Intl.NumberFormat("tr-TR", {
+ numberingSystem: "latn",
+ minimumIntegerDigits: enAzBasamak,
+ useGrouping: enAzBasamak <= 1,
+ });
+ BICIMLER.set(enAzBasamak, b);
+ }
+ return b;
+}
+
+type Parca =
+ | { anahtar: string; rakam: number }
+ | { anahtar: string; metin: string };
+
+/** Biçimlenmiş sayıyı basamak değerine göre anahtarlı sütunlara böler. */
+function parcala(deger: number, bicim: Intl.NumberFormat): Parca[] {
+ const parcalar = bicim.formatToParts(deger);
+ let basamak = parcalar.reduce(
+ (n, p) => n + (p.type === "integer" ? p.value.length : 0),
+ 0,
+ );
+ return parcalar.flatMap((p, i): Parca[] => {
+ if (p.type === "integer")
+ return [...p.value].map((c) => ({ anahtar: `b${--basamak}`, rakam: Number(c) }));
+ return [
+ { anahtar: p.type === "group" ? `g${basamak}` : `${p.type}${i}`, metin: p.value },
+ ];
+ });
+}
+
+// Sütun açılırken değişim yönünde yükselir, kapanırken aynı yoldan gider (§6:
+// giriş ve çıkış aynı yoldan).
+const yuva: Variants = {
+ giris: (yon: number) => ({ width: 0, opacity: 0, y: `${yon * 0.3}em` }),
+ merkez: { width: "auto", opacity: 1, y: 0, transition: YAY },
+ cikis: (yon: number) => ({
+ width: 0,
+ opacity: 0,
+ y: `${yon * -0.3}em`,
+ transition: YAY,
+ }),
+};
+
+/** Tekerlekteki bir rakam: tekerleğin konumuna uzaklığı yerini ve görünürlüğünü belirler. */
+function Glif({ konum, rakam }: { konum: MotionValue; rakam: number }) {
+ const uzaklik = (simdiki: number) =>
+ ((((rakam - simdiki) % 10) + 15) % 10) - 5;
+ const y = useTransform(konum, (c) => `${uzaklik(c) * 1.05}em`);
+ const opacity = useTransform(konum, (c) =>
+ Math.max(0, 1 - Math.abs(uzaklik(c)) ** 1.5 * 1.1),
+ );
+ const visibility = useTransform(konum, (c) =>
+ Math.abs(uzaklik(c)) >= 1 ? "hidden" : "visible",
+ );
+ return (
+
+ {rakam}
+
+ );
+}
+
+/** Bir basamağın tekerleği: sayının gittiği yönde döner, yarım turdan uzunsa kısa yolu seçer. */
+function Tekerlek({ rakam, yon }: { rakam: number; yon: number }) {
+ const konum = useMotionValue(rakam);
+ const durum = useRef({ rakam, hedef: rakam });
+ useLayoutEffect(() => {
+ const d = durum.current;
+ if (d.rakam === rakam) return;
+ let fark =
+ yon > 0 ? (rakam - d.rakam + 10) % 10 : -((d.rakam - rakam + 10) % 10);
+ if (Math.abs(fark) > 5) fark -= Math.sign(fark) * 10;
+ d.hedef += fark;
+ d.rakam = rakam;
+ animate(konum, d.hedef, YAY);
+ }, [rakam, yon, konum]);
+ return (
+ <>
+ 0
+ {RAKAMLAR.map((r) => (
+
+ ))}
+ >
+ );
+}
+
+/**
+ * Ekranda değişen bir sayı (liste sayacı gibi). Yazı boyu/rengi/ağırlığı
+ * kapsayıcıdan gelir; `className` yalnız yerleşim için.
+ */
+export function SayiRulo({
+ deger,
+ className,
+ enAzBasamak = 1,
+ yon: sabitYon,
+}: {
+ deger: number;
+ className?: string;
+ /** Basamak dolgusu: 2 → "05". Üst çubuk geri sayımı; binlik ayracı kapanır. */
+ enAzBasamak?: number;
+ /** Dönüş yönünü sabitler: geri sayımda 00 → 59 yukarı değil aşağı dönsün. */
+ yon?: 1 | -1;
+}) {
+ const azalt = useReducedMotion();
+ const [iz, setIz] = useState({ deger, yon: 1 });
+ if (iz.deger !== deger) setIz({ deger, yon: deger > iz.deger ? 1 : -1 });
+ const yon =
+ sabitYon ?? (iz.deger === deger ? iz.yon : deger > iz.deger ? 1 : -1);
+ const bicim = bicimAl(enAzBasamak);
+ const metin = bicim.format(deger);
+
+ if (azalt) return {metin};
+
+ return (
+
+ {metin}
+
+
+ {parcala(deger, bicim).map((p) => (
+
+ {"rakam" in p ? : p.metin}
+
+ ))}
+
+
+
+ );
+}
diff --git a/src/components/ui/secim-haplari.tsx b/src/components/ui/secim-haplari.tsx
new file mode 100644
index 0000000..b0777c3
--- /dev/null
+++ b/src/components/ui/secim-haplari.tsx
@@ -0,0 +1,104 @@
+"use client";
+
+// Tek seçimli hap grubu (puan türü, tema): seçili vurgu ayrı ayrı yeniden
+// boyanmak yerine TEK bir yüzey olarak seçenekten seçeneğe kayar
+// (`layoutId`). Göz "hangisi seçili" sorusunu hareketin bittiği yerde okur.
+//
+// Kaynak: Arc UI "Chip group" / "Floating button group" (uiarc.dev) kayan
+// vurgu deseni; sınıf dizisi DESIGN.md hap dili. İki varyant:
+// - `ayrik`: her seçenek kendi kenarlıklı hapı, vurgu mavi dolu hap (hero ve
+// CTA formundaki puan türü çipleri).
+// - `kapsul`: tek kapsül içinde koyu hap (üst çubuk "Giriş yap" diliyle aynı,
+// tema seçici). Koyu hap yazısı `text-slate-50` (§2.3).
+// Yay §6 varsayılanı; hareketi azalt'ta vurgu kaymaz, yerinde belirir.
+
+import { useId, type ComponentType } from "react";
+import { motion, useReducedMotion } from "motion/react";
+import { cn } from "@/lib/utils";
+
+const YAY = { type: "spring", bounce: 0, duration: 0.35 } as const;
+
+export interface SecimHapiSecenek {
+ deger: T;
+ etiket: string;
+ ikon?: ComponentType<{ className?: string; "aria-hidden"?: boolean }>;
+}
+
+export function SecimHaplari({
+ secenekler,
+ deger,
+ onChange,
+ ariaLabel,
+ varyant = "ayrik",
+ boyut = "sm",
+ className,
+}: {
+ secenekler: readonly SecimHapiSecenek[];
+ /** `null`: henüz seçim yok (ör. tema hidrasyondan önce) — vurgu çizilmez. */
+ deger: T | null;
+ onChange: (deger: T) => void;
+ ariaLabel: string;
+ varyant?: "ayrik" | "kapsul";
+ boyut?: "sm" | "md";
+ className?: string;
+}) {
+ const uid = useId();
+ const azalt = useReducedMotion();
+ const kapsul = varyant === "kapsul";
+ const yukseklik = boyut === "md" ? "h-9 px-3 text-sm" : "h-8 px-3 text-xs";
+
+ return (
+
+ {secenekler.map(({ deger: d, etiket, ikon: Ikon }) => {
+ const secili = deger === d;
+ return (
+
+ );
+ })}
+
+ );
+}
diff --git a/src/features/kullanici/components/giris-form.tsx b/src/features/kullanici/components/giris-form.tsx
index 614b65b..e21880b 100644
--- a/src/features/kullanici/components/giris-form.tsx
+++ b/src/features/kullanici/components/giris-form.tsx
@@ -1,5 +1,6 @@
"use client";
+import { SayiRulo } from "@/components/ui/sayi-rulo";
import { useEffect, useRef, useState } from "react";
import { ArrowRight, MailCheck } from "lucide-react";
import { toast } from "sonner";
@@ -129,11 +130,15 @@ export function GirisForm({ callbackURL }: { callbackURL: string }) {
disabled={busy !== null || bekleme > 0}
className="cursor-pointer font-medium text-primary underline-offset-2 hover:underline disabled:cursor-default disabled:text-slate-400 disabled:no-underline"
>
- {busy === "email"
- ? "Gönderiliyor…"
- : bekleme > 0
- ? `Yeniden gönder (${bekleme})`
- : "Yeniden gönder"}
+ {busy === "email" ? (
+ "Gönderiliyor…"
+ ) : bekleme > 0 ? (
+ <>
+ Yeniden gönder ()
+ >
+ ) : (
+ "Yeniden gönder"
+ )}
);
diff --git a/src/features/liste/components/program-tablosu.tsx b/src/features/liste/components/program-tablosu.tsx
index 31631bb..1ba6711 100644
--- a/src/features/liste/components/program-tablosu.tsx
+++ b/src/features/liste/components/program-tablosu.tsx
@@ -22,6 +22,7 @@ import type {
} from "@/types/yokatlas";
import { DILIM_ETIKET, riskHesapla } from "@/lib/risk";
import { bolumSayfaSlug, ilSayfaHref, trBaslikDuzeni, uniSayfaSlug } from "@/lib/slug";
+import { SayiRulo } from "@/components/ui/sayi-rulo";
import { TurCipi } from "@/components/tur-cipi";
import { cn } from "@/lib/utils";
import { VERI_YIL_SAYISI } from "@/lib/veri-yillari";
@@ -306,7 +307,7 @@ export function ProgramTablosu({
- {satirlar.length.toLocaleString("tr-TR")} /{" "}
+ /{" "}
{toplam.toLocaleString("tr-TR")} program
diff --git a/src/features/rapor/components/sohbet-client.tsx b/src/features/rapor/components/sohbet-client.tsx
index a16d895..85b9f83 100644
--- a/src/features/rapor/components/sohbet-client.tsx
+++ b/src/features/rapor/components/sohbet-client.tsx
@@ -19,6 +19,7 @@ import {
} from "lucide-react";
import { toast } from "sonner";
import { cn } from "@/lib/utils";
+import { SayiRulo } from "@/components/ui/sayi-rulo";
import { AnimasyonluMark } from "@/components/animasyonlu-mark";
import { AracPilleri, aracPilleri } from "./arac-pilleri";
import { SOHBET_MARKDOWN_BILESENLERI, baglantilariIsaretle } from "./sohbet-baglanti";
@@ -643,7 +644,7 @@ export function SohbetClient({
title="Kredilerin — yüklemek için tıkla"
>
- {kredi} kredi
+ kredi
diff --git a/src/features/sihirbaz/components/cta-sira-form.tsx b/src/features/sihirbaz/components/cta-sira-form.tsx
index 4c34c7e..e2f3d26 100644
--- a/src/features/sihirbaz/components/cta-sira-form.tsx
+++ b/src/features/sihirbaz/components/cta-sira-form.tsx
@@ -6,6 +6,7 @@ import { useRouter } from "next/navigation";
import { ArrowRight, Trophy, X } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
+import { SecimHaplari } from "@/components/ui/secim-haplari";
import {
Drawer,
DrawerClose,
@@ -37,6 +38,7 @@ const PUAN_TURLERI_SECENEK = [
{ deger: "dil", etiket: "Dil" },
{ deger: "tyt", etiket: "TYT" },
] as const;
+type PuanTuru = (typeof PUAN_TURLERI_SECENEK)[number]["deger"];
// Kayıtlı profilli CTA'lar /listem boş durumunun dilini taşır (bkz.
// listem-bos-cta.tsx): büyük turuncu buton. Sınıf seti tek yerde.
@@ -138,7 +140,7 @@ export function CtaSiraForm({
const [acik, setAcik] = useState(false);
const [adim, setAdim] = useState<"sira" | "sihirbaz">("sira");
const [siralama, setSiralama] = useState("");
- const [tur, setTur] = useState("say");
+ const [tur, setTur] = useState("say");
const [sira, setSira] = useState(null);
const [facetler, setFacetler] = useState(null);
const [yukleniyor, setYukleniyor] = useState(false);
@@ -236,28 +238,14 @@ export function CtaSiraForm({
: "flex flex-col gap-3"
}
>
-
- {PUAN_TURLERI_SECENEK.map((t) => (
-
- ))}
-
+ {/* Seçili vurgu çipten çipe kayar (Arc kayan vurgu, secim-haplari.tsx). */}
+