feat(audio,site): calm santoor default music + card-fan logo site redesign
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 2m0s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m9s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 1m18s

- audio: default background music is now the santoor track (calm Persian),
  rebuilt as a real plucked-santoor loop — fast metallic attack, shimmer
  overtones, soft tonic drone, longer Dastgah-e-Shur phrase
- site: marketing logo is now the app's card-fan icon (Logo.tsx + icon.svg);
  hero features the big logo with gold halo, floating suit motifs, and
  polished section dividers

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-16 21:48:59 +03:30
parent 6aa4f37642
commit 9901c5e6d4
5 changed files with 192 additions and 32 deletions
+34
View File
@@ -78,3 +78,37 @@ body {
linear-gradient(-45deg, rgba(212, 175, 55, 0.04) 25%, transparent 25%);
background-size: 22px 22px;
}
/* Gentle float for the hero logo. */
@keyframes float-y {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-12px); }
}
.float-y {
animation: float-y 5.5s ease-in-out infinite;
}
/* Soft gold halo behind the hero logo. */
.gold-halo {
background: radial-gradient(circle, rgba(212, 175, 55, 0.28), transparent 62%);
filter: blur(8px);
}
/* Card-suit accent for hero/section glyphs. */
.suit {
color: var(--gold);
opacity: 0.16;
user-select: none;
line-height: 1;
}
/* Thin gold hairline divider. */
.rule-gold {
height: 1px;
background: linear-gradient(90deg, transparent, rgba(212, 175, 55, 0.5), transparent);
}
@media (prefers-reduced-motion: reduce) {
.float-y { animation: none; }
html { scroll-behavior: auto; }
}
+21 -2
View File
@@ -2,6 +2,7 @@ import {
Users, Bot, Trophy, Gift, MessageCircle, Globe, ShieldCheck, Zap, Crown, Star,
} from "lucide-react";
import { DownloadButtons } from "@/components/DownloadButtons";
import { Logo } from "@/components/Logo";
import { BRAND } from "@/lib/site";
const FEATURES = [
@@ -29,8 +30,22 @@ export default function Home() {
return (
<>
{/* Hero */}
<section className="felt card-pattern">
<section className="felt card-pattern relative overflow-hidden">
{/* decorative card suits floating in the backdrop */}
<span className="suit pointer-events-none absolute right-[6%] top-16 text-8xl"></span>
<span className="suit pointer-events-none absolute left-[8%] top-40 text-7xl"></span>
<span className="suit pointer-events-none absolute left-[14%] bottom-12 text-6xl"></span>
<span className="suit pointer-events-none absolute right-[12%] bottom-20 text-7xl"></span>
<div className="mx-auto max-w-6xl px-4 py-16 text-center sm:py-24">
{/* card-fan brand mark */}
<div className="relative mx-auto mb-8 grid h-40 w-40 place-items-center sm:h-48 sm:w-48">
<div className="gold-halo absolute inset-0 rounded-full" />
<div className="float-y relative">
<Logo size={160} glow />
</div>
</div>
<span className="inline-flex items-center gap-1.5 rounded-full glass px-3 py-1 text-xs text-gold-soft">
<Star size={13} /> بازی حکمِ ایرانی، حرفهایتر از همیشه
</span>
@@ -48,7 +63,7 @@ export default function Home() {
<div className="mx-auto mt-12 grid max-w-3xl gap-3 sm:grid-cols-3">
{STATS.map((s) => (
<div key={s.label} className="glass rounded-2xl px-4 py-4">
<div key={s.label} className="glass rounded-2xl px-4 py-4 transition hover:border-gold/40">
<s.icon className="mx-auto text-teal" size={22} />
<div className="mt-2 text-sm font-bold text-cream">{s.label}</div>
<div className="text-xs text-cream/55">{s.value}</div>
@@ -66,6 +81,7 @@ export default function Home() {
<p className="mx-auto mt-3 max-w-xl text-center text-cream/60">
همهٔ چیزی که یک بازی حکم بینقص لازم دارد، در یک اپ.
</p>
<div className="rule-gold mx-auto mt-6 max-w-xs" />
<div className="mt-10 grid gap-5 sm:grid-cols-2 lg:grid-cols-3">
{FEATURES.map((f) => (
<div key={f.title} className="glass rounded-2xl p-6 transition hover:border-gold/40">
@@ -97,6 +113,9 @@ export default function Home() {
{/* Final CTA */}
<section className="mx-auto max-w-4xl px-4 py-16 text-center">
<div className="mx-auto mb-6 w-fit">
<Logo size={64} glow />
</div>
<h2 className="text-3xl font-black sm:text-4xl">
همین حالا <span className="gold-text">حکم</span> را شروع کن
</h2>
+60 -17
View File
@@ -1,24 +1,67 @@
export function Logo({ size = 36 }: { size?: number }) {
/**
* Brand mark — the app's card-fan icon (mirrors public/icon.svg): three gold-edged
* playing cards fanned out, a spade on the face card. Scales cleanly from the nav
* (≈34px) to the hero (≈160px). `glow` adds a soft gold halo for hero use.
*/
export function Logo({ size = 36, glow = false }: { size?: number; glow?: boolean }) {
return (
<svg width={size} height={size} viewBox="0 0 100 100" fill="none" aria-hidden>
<rect x="6" y="6" width="88" height="88" rx="22" fill="url(#lg)" stroke="#d4af37" strokeWidth="3" />
<text
x="50"
y="62"
textAnchor="middle"
fontSize="46"
fontWeight="900"
fill="#d4af37"
fontFamily="Vazirmatn Variable, sans-serif"
>
و
</text>
<svg
width={size}
height={size}
viewBox="0 0 512 512"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-hidden
style={glow ? { filter: "drop-shadow(0 10px 36px rgba(212,175,55,0.35))" } : undefined}
>
<defs>
<linearGradient id="lg" x1="0" y1="0" x2="100" y2="100" gradientUnits="userSpaceOnUse">
<stop stopColor="#111a33" />
<stop offset="1" stopColor="#070b18" />
<radialGradient id="frbg" cx="50%" cy="36%" r="78%">
<stop offset="0" stopColor="#16284f" />
<stop offset="0.62" stopColor="#0a142e" />
<stop offset="1" stopColor="#060c1f" />
</radialGradient>
<linearGradient id="frgold" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stopColor="#f6e4a0" />
<stop offset="0.5" stopColor="#d4af37" />
<stop offset="1" stopColor="#b8860b" />
</linearGradient>
<linearGradient id="frface" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stopColor="#fffdf7" />
<stop offset="1" stopColor="#f1e6cd" />
</linearGradient>
<linearGradient id="frnavy" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stopColor="#1d356a" />
<stop offset="1" stopColor="#0a142e" />
</linearGradient>
</defs>
<rect width="512" height="512" rx="116" fill="url(#frbg)" />
<circle cx="256" cy="196" r="185" fill="#2dd4bf" opacity="0.07" />
<rect x="30" y="30" width="452" height="452" rx="100" fill="none" stroke="url(#frgold)" strokeWidth="6" opacity="0.6" />
<g transform="rotate(-25 256 396)">
<rect x="182" y="180" width="148" height="210" rx="16" fill="url(#frnavy)" stroke="url(#frgold)" strokeWidth="4" />
<rect x="198" y="196" width="116" height="178" rx="10" fill="none" stroke="#d4af37" strokeWidth="2" opacity="0.45" />
<path d="M256 250 l16 35 -16 35 -16 -35 z" fill="#d4af37" opacity="0.75" />
</g>
<g transform="rotate(25 256 396)">
<rect x="182" y="180" width="148" height="210" rx="16" fill="url(#frnavy)" stroke="url(#frgold)" strokeWidth="4" />
<rect x="198" y="196" width="116" height="178" rx="10" fill="none" stroke="#d4af37" strokeWidth="2" opacity="0.45" />
<path d="M256 250 l16 35 -16 35 -16 -35 z" fill="#d4af37" opacity="0.75" />
</g>
<g transform="translate(0 -24)">
<rect x="181" y="178" width="150" height="212" rx="16" fill="url(#frface)" stroke="url(#frgold)" strokeWidth="5" />
<rect x="193" y="190" width="126" height="188" rx="10" fill="none" stroke="#d4af37" strokeWidth="2" />
<g transform="translate(256 268) scale(1.45)">
<path
d="M0,-44 C0,-44 -42,-6 -42,16 C-42,30 -31,40 -18,40 C-11,40 -5,37 0,32 C-2,44 -10,52 -20,55 L20,55 C10,52 2,44 0,32 C5,37 11,40 18,40 C31,40 42,30 42,16 C42,-6 0,-44 0,-44 Z"
fill="url(#frgold)"
stroke="#7a5a00"
strokeWidth="1.5"
/>
</g>
</g>
</svg>
);
}
+44 -3
View File
@@ -1,4 +1,45 @@
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100">
<rect x="6" y="6" width="88" height="88" rx="22" fill="#0b1226" stroke="#d4af37" stroke-width="4"/>
<text x="50" y="64" text-anchor="middle" font-size="48" font-weight="900" fill="#d4af37" font-family="Tahoma, sans-serif">و</text>
<svg width="512" height="512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient id="bg" cx="50%" cy="36%" r="78%">
<stop offset="0" stop-color="#16284f"/>
<stop offset="0.62" stop-color="#0a142e"/>
<stop offset="1" stop-color="#060c1f"/>
</radialGradient>
<linearGradient id="gold" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#f6e4a0"/>
<stop offset="0.5" stop-color="#d4af37"/>
<stop offset="1" stop-color="#b8860b"/>
</linearGradient>
<linearGradient id="face" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#fffdf7"/>
<stop offset="1" stop-color="#f1e6cd"/>
</linearGradient>
<linearGradient id="navy" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#1d356a"/>
<stop offset="1" stop-color="#0a142e"/>
</linearGradient>
</defs>
<rect width="512" height="512" rx="116" fill="url(#bg)"/>
<circle cx="256" cy="196" r="185" fill="#2dd4bf" opacity="0.07"/>
<rect x="30" y="30" width="452" height="452" rx="100" fill="none" stroke="url(#gold)" stroke-width="6" opacity="0.6"/>
<g transform="rotate(-25 256 396)">
<rect x="182" y="180" width="148" height="210" rx="16" fill="url(#navy)" stroke="url(#gold)" stroke-width="4"/>
<rect x="198" y="196" width="116" height="178" rx="10" fill="none" stroke="#d4af37" stroke-width="2" opacity="0.45"/>
<path d="M256 250 l16 35 -16 35 -16 -35 z" fill="#d4af37" opacity="0.75"/>
</g>
<g transform="rotate(25 256 396)">
<rect x="182" y="180" width="148" height="210" rx="16" fill="url(#navy)" stroke="url(#gold)" stroke-width="4"/>
<rect x="198" y="196" width="116" height="178" rx="10" fill="none" stroke="#d4af37" stroke-width="2" opacity="0.45"/>
<path d="M256 250 l16 35 -16 35 -16 -35 z" fill="#d4af37" opacity="0.75"/>
</g>
<g transform="translate(0 -24)">
<rect x="181" y="178" width="150" height="212" rx="16" fill="url(#face)" stroke="url(#gold)" stroke-width="5"/>
<rect x="193" y="190" width="126" height="188" rx="10" fill="none" stroke="#d4af37" stroke-width="2"/>
<g transform="translate(256 268) scale(1.45)">
<path d="M0,-44 C0,-44 -42,-6 -42,16 C-42,30 -31,40 -18,40 C-11,40 -5,37 0,32 C-2,44 -10,52 -20,55 L20,55 C10,52 2,44 0,32 C5,37 11,40 18,40 C31,40 42,30 42,16 C42,-6 0,-44 0,-44 Z" fill="url(#gold)" stroke="#7a5a00" stroke-width="1.5"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 331 B

After

Width:  |  Height:  |  Size: 2.4 KiB