fix: update badge styles and animations for consistency
All checks were successful
Deploy / deploy (push) Successful in 7m13s
All checks were successful
Deploy / deploy (push) Successful in 7m13s
Refined the styling of badge and eyebrow elements to ensure uniformity across the site, aligning them with the main section headers. Updated the `PixelMark` component to enhance its animation behavior, introducing new keyframes for smoother transitions. Adjusted CSS properties for better visual consistency and removed unnecessary uppercase text styling. Improved the `SectionEyebrow` component to reflect these changes.
This commit is contained in:
@@ -13,7 +13,7 @@ Push emri geldiğinde önce lokalde `pnpm build` başarıyla geçmeli; geçmeden
|
|||||||
|
|
||||||
# Badge/eyebrow rozetleri: tek kaynak SectionEyebrow
|
# Badge/eyebrow rozetleri: tek kaynak SectionEyebrow
|
||||||
|
|
||||||
Site genelindeki tüm badge/rozet/eyebrow elemanları ana sayfadaki section başlıklarının üstünde duran rozetle birebir aynı olmalı. Kanonik bileşen `src/components/pixel-decor.tsx` içindeki `SectionEyebrow`dur (piksel imzalı `PixelMark` ikonu + `rounded-full border border-slate-200 bg-white px-3.5 py-1.5 text-xs font-semibold uppercase tracking-[0.12em] text-primary`). Yeni bir badge/eyebrow gerektiğinde `SectionEyebrow` kullan (`className` prop'u kenar boşluğu için var); `@/components/ui/badge`'deki `Badge` ile ya da elle yazılmış pill span'lerle yeni badge tasarlama. İnteraktif chip/buton pill'leri (filtre çipleri, nav butonları) bu kuralın dışındadır.
|
Site genelindeki tüm badge/rozet/eyebrow elemanları ana sayfadaki section başlıklarının üstünde duran rozetle birebir aynı olmalı. Kanonik bileşen `src/components/pixel-decor.tsx` içindeki `SectionEyebrow`dur (piksel imzalı `PixelMark` ikonu + `rounded-full border border-slate-200 bg-white px-3.5 py-1.5 font-bricolage text-xs font-semibold text-primary`; metin büyük-küçük harfli yazılır — uppercase yok). Yeni bir badge/eyebrow gerektiğinde `SectionEyebrow` kullan (`className` prop'u kenar boşluğu için var); `@/components/ui/badge`'deki `Badge` ile ya da elle yazılmış pill span'lerle yeni badge tasarlama. İnteraktif chip/buton pill'leri (filtre çipleri, nav butonları) bu kuralın dışındadır.
|
||||||
|
|
||||||
# UI tutarlılığı: ortak elemanlar tek kaynaktan
|
# UI tutarlılığı: ortak elemanlar tek kaynaktan
|
||||||
|
|
||||||
|
|||||||
@@ -129,6 +129,37 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Rozet (PixelMark) pikselleri: sırayla turuncuya ısınır, iz gibi yavaşça söner.
|
||||||
|
Zamanlama ısı fırçasıyla aynı dili konuşur: ani ısınma (%8), uzun soğuma (%66). */
|
||||||
|
@theme {
|
||||||
|
--animate-pixel-isi: pixel-isi 2.4s ease-in-out infinite;
|
||||||
|
--animate-pixel-isi-accent: pixel-isi-accent 2.4s ease-in-out infinite;
|
||||||
|
|
||||||
|
@keyframes pixel-isi {
|
||||||
|
0%,
|
||||||
|
66%,
|
||||||
|
100% {
|
||||||
|
fill: currentColor;
|
||||||
|
fill-opacity: var(--px-op, 0.3);
|
||||||
|
}
|
||||||
|
8% {
|
||||||
|
fill: var(--color-orange-500);
|
||||||
|
fill-opacity: 0.85;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pixel-isi-accent {
|
||||||
|
0%,
|
||||||
|
66%,
|
||||||
|
100% {
|
||||||
|
fill-opacity: 0.55;
|
||||||
|
}
|
||||||
|
8% {
|
||||||
|
fill-opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Ödeme dönüşünde kilidi açılan listenin blur çözülme animasyonu */
|
/* Ödeme dönüşünde kilidi açılan listenin blur çözülme animasyonu */
|
||||||
@keyframes kt-unblur {
|
@keyframes kt-unblur {
|
||||||
from {
|
from {
|
||||||
|
|||||||
@@ -314,7 +314,7 @@ export default function Home() {
|
|||||||
{/* Kuralların şeffaf anlatımına köprü: /meraklisina */}
|
{/* Kuralların şeffaf anlatımına köprü: /meraklisina */}
|
||||||
<Link
|
<Link
|
||||||
href="/meraklisina"
|
href="/meraklisina"
|
||||||
className="group inline-flex items-center gap-1.5 rounded-full bg-orange-500 px-3.5 py-1.5 text-xs font-semibold uppercase tracking-[0.12em] text-white transition-colors duration-200 hover:bg-orange-600"
|
className="group inline-flex items-center gap-1.5 rounded-full bg-orange-500 px-3.5 py-1.5 font-bricolage text-xs font-semibold text-white transition-colors duration-200 hover:bg-orange-600"
|
||||||
>
|
>
|
||||||
Meraklısına
|
Meraklısına
|
||||||
<ArrowUpRight
|
<ArrowUpRight
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useMemo, useRef, type ReactNode } from "react";
|
import { useMemo, useRef, type CSSProperties, type ReactNode } from "react";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { usePixelHeat } from "@/components/use-pixel-heat";
|
import { usePixelHeat } from "@/components/use-pixel-heat";
|
||||||
|
|
||||||
@@ -229,23 +229,51 @@ function fixedPixel(x: number, y: number, opacity: number) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Eyebrow rozetlerinde kullanılan 2×2'lik minik piksel imzası. */
|
/** PixelMark pikseli: kendi kendine, sırası geldiğinde ısınıp sönen rect. */
|
||||||
export function PixelMark({ className }: { className?: string }) {
|
function markPixel(x: number, y: number, opacity: number, delay: number) {
|
||||||
const svgRef = useRef<SVGSVGElement>(null);
|
return (
|
||||||
usePixelHeat(svgRef, { radius: 24 });
|
<rect
|
||||||
|
x={x + INSET}
|
||||||
|
y={y + INSET}
|
||||||
|
width={DOT}
|
||||||
|
height={DOT}
|
||||||
|
rx={2}
|
||||||
|
className="animate-pixel-isi motion-reduce:animate-none"
|
||||||
|
fill="currentColor"
|
||||||
|
fillOpacity={opacity}
|
||||||
|
style={
|
||||||
|
{ "--px-op": opacity, animationDelay: `${delay}s` } as CSSProperties
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Eyebrow rozetlerinde kullanılan 2×2'lik minik piksel imzası.
|
||||||
|
* Pikseller imleç fırçasına katılmak yerine saat yönünde sırayla
|
||||||
|
* ısınıp söner; ikisi aynı fill/fillOpacity'yi sürdüğü için çakışır.
|
||||||
|
*/
|
||||||
|
export function PixelMark({ className }: { className?: string }) {
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
ref={svgRef}
|
|
||||||
viewBox="0 0 20 20"
|
viewBox="0 0 20 20"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
className={cn("size-3.5 shrink-0", className)}
|
className={cn("size-3.5 shrink-0", className)}
|
||||||
>
|
>
|
||||||
{fixedPixel(0, 0, 0.35)}
|
{markPixel(0, 0, 0.35, 0)}
|
||||||
<rect x={11.3} y={1.3} width={7.4} height={7.4} rx={2} className="fill-orange-500" fillOpacity={0.85} />
|
<rect
|
||||||
{fixedPixel(0, 10, 0.6)}
|
x={11.3}
|
||||||
{fixedPixel(10, 10, 0.18)}
|
y={1.3}
|
||||||
|
width={7.4}
|
||||||
|
height={7.4}
|
||||||
|
rx={2}
|
||||||
|
className="animate-pixel-isi-accent fill-orange-500 motion-reduce:animate-none"
|
||||||
|
fillOpacity={0.85}
|
||||||
|
style={{ animationDelay: "0.6s" }}
|
||||||
|
/>
|
||||||
|
{markPixel(10, 10, 0.18, 1.2)}
|
||||||
|
{markPixel(0, 10, 0.6, 1.8)}
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -281,7 +309,7 @@ export function SectionEyebrow({
|
|||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
className={cn(
|
className={cn(
|
||||||
"inline-flex items-center gap-2 rounded-full border border-slate-200 bg-white px-3.5 py-1.5 text-xs font-semibold uppercase tracking-[0.12em] text-primary",
|
"inline-flex items-center gap-2 rounded-full border border-slate-200 bg-white px-3.5 py-1.5 text-xs font-semibold text-primary",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user