feat: Instagram data sync, gold accent, SVG logo, FAQ & Pricing sections

- Sync all content from Instagram: fix addresses, trainer names, add 5 new
  trainers, remove 2 inactive, update class descriptions
- Add FAQ section (11 Q&A items) and Pricing section (tabs: subscriptions,
  rental, rules)
- Redesign with editorial magazine feel: centered headings, generous spacing,
  section glow effects, glassmorphism cards
- Migrate entire accent palette from rose to warm gold (#c9a96e)
- Replace low-res PNG logo with vector SVG traced via potrace — crisp at any
  size, animated gradient (black↔gold), heartbeat pulse animation
- Make header brand name gold

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-10 00:45:50 +03:00
parent 9cf09b6894
commit a75922c730
25 changed files with 614 additions and 174 deletions

View File

@@ -89,7 +89,7 @@ export function ClassModal({ classItem, onClose }: ClassModalProps) {
{!heroImage && (
<div className="flex items-center justify-between p-6 pb-0">
<div className="flex items-center gap-3">
<div className="flex h-9 w-9 items-center justify-center rounded-lg bg-rose-50 text-rose-600 dark:bg-rose-500/10 dark:text-rose-400">
<div className="flex h-9 w-9 items-center justify-center rounded-lg bg-[#c9a96e]/10 text-[#a08050] dark:bg-[#c9a96e]/10 dark:text-[#d4b87a]">
{iconMap[classItem.icon]}
</div>
<h3 className="heading-text text-xl font-bold">
@@ -107,7 +107,7 @@ export function ClassModal({ classItem, onClose }: ClassModalProps) {
)}
{classItem.detailedDescription && (
<div className="p-6 text-sm leading-relaxed whitespace-pre-line text-neutral-600 dark:text-neutral-400">
<div className="p-6 text-sm leading-relaxed whitespace-pre-line text-neutral-600 dark:text-neutral-300">
{classItem.detailedDescription}
</div>
)}

View File

@@ -33,7 +33,7 @@ export function FloatingHearts() {
{hearts.map((heart) => (
<div
key={heart.id}
className="absolute text-rose-500"
className="absolute text-[#c9a96e]"
style={{
left: `${heart.left}%`,
bottom: "-20px",

View File

@@ -0,0 +1,46 @@
interface HeroLogoProps {
className?: string;
size?: number;
animated?: boolean;
}
export function HeroLogo({ className = "", size = 220, animated = false }: HeroLogoProps) {
const h = Math.round(size * (192 / 234));
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 234 192"
width={size}
height={h}
className={className}
role="img"
aria-label="Black Heart logo"
>
{animated && (
<defs>
<linearGradient id="heart-gradient" x1="0%" y1="0%" x2="100%" y2="100%" gradientUnits="userSpaceOnUse">
<stop offset="0%" stopColor="#000">
<animate attributeName="stop-color" values="#000;#c9a96e;#000" dur="6s" repeatCount="indefinite" />
</stop>
<stop offset="40%" stopColor="#000">
<animate attributeName="stop-color" values="#000;#000;#c9a96e" dur="6s" repeatCount="indefinite" />
</stop>
<stop offset="60%" stopColor="#c9a96e">
<animate attributeName="stop-color" values="#c9a96e;#000;#000" dur="6s" repeatCount="indefinite" />
</stop>
<stop offset="100%" stopColor="#000">
<animate attributeName="stop-color" values="#000;#c9a96e;#000" dur="6s" repeatCount="indefinite" />
<animate attributeName="offset" values="1;1;1" dur="6s" repeatCount="indefinite" />
</stop>
</linearGradient>
</defs>
)}
<path
fill={animated ? "url(#heart-gradient)" : "currentColor"}
fillRule="evenodd"
d="M118.02,188.43 C118.04,184.10 120.51,173.30 122.96,166.79 C126.11,158.42 133.55,147.62 144.55,135.42 C165.53,112.15 170.96,101.38 170.99,82.98 C171.00,72.35 168.51,62.96 162.47,50.94 C160.00,46.02 157.78,42.00 157.53,42.00 C157.29,42.00 158.24,45.04 159.64,48.75 C163.04,57.78 165.96,71.24 165.96,78.00 C165.97,85.89 163.51,95.22 159.27,103.40 C156.31,109.09 152.52,113.57 140.17,126.00 C131.69,134.53 123.42,143.44 121.79,145.81 C116.23,153.88 110.87,167.99 109.81,177.28 C109.51,179.99 109.37,179.90 105.02,174.28 C102.55,171.10 98.74,166.54 96.55,164.15 L92.56,159.80 L95.53,157.70 C100.61,154.12 105.90,148.12 108.76,142.70 C111.22,138.02 111.50,136.50 111.47,127.50 C111.45,118.43 111.02,116.15 106.86,103.00 C101.17,85.06 99.60,76.75 100.25,68.17 C100.75,61.51 104.60,48.83 107.29,45.00 C108.57,43.16 108.76,43.69 109.31,50.84 C110.42,65.22 115.99,75.08 126.37,81.04 C133.31,85.02 133.82,84.76 128.92,79.75 C124.20,74.93 119.44,65.68 118.16,58.84 C116.46,49.75 119.09,39.24 125.73,28.59 L128.79,23.69 L130.02,29.59 C130.69,32.84 133.23,39.92 135.65,45.33 C143.15,62.02 144.36,69.90 141.53,83.29 C140.04,90.28 134.00,104.04 127.66,114.86 C125.68,118.24 124.39,120.97 124.78,120.93 C125.18,120.90 128.41,117.53 131.97,113.46 C145.06,98.47 150.50,85.84 150.46,70.50 C150.43,59.80 149.70,57.36 141.46,40.79 C137.98,33.80 134.83,26.02 134.45,23.49 C133.85,19.50 134.07,18.56 136.10,16.40 C139.50,12.77 147.93,7.39 153.86,5.06 L159.00,3.03 L159.00,9.32 C159.00,18.37 162.11,24.01 172.06,33.00 C176.46,36.97 180.72,41.50 181.53,43.06 C183.67,47.20 183.39,56.94 180.95,63.13 C178.14,70.25 180.87,67.95 184.97,59.74 C190.78,48.12 188.70,39.73 177.15,28.15 C173.28,24.27 169.43,20.06 168.61,18.80 C166.51,15.58 164.79,7.21 165.54,3.83 C166.16,1.00 166.17,1.00 174.33,1.01 C178.82,1.02 184.15,1.29 186.17,1.63 C189.69,2.21 189.81,2.37 189.29,5.62 C188.42,10.94 190.83,20.71 195.10,29.20 C197.26,33.49 199.19,37.00 199.40,37.00 C199.62,37.00 198.67,33.51 197.31,29.25 C195.35,23.12 194.91,19.90 195.17,13.83 C195.36,9.61 195.85,5.81 196.28,5.39 C197.35,4.31 205.52,8.43 211.67,13.15 C218.45,18.35 221.00,23.72 220.99,32.74 C220.98,36.46 220.28,41.98 219.42,45.00 C218.57,48.02 217.63,51.40 217.34,52.50 C216.30,56.51 222.34,45.32 224.52,39.20 C225.76,35.73 227.01,32.66 227.29,32.38 C227.57,32.09 228.79,34.48 229.99,37.68 C238.21,59.57 232.78,83.80 215.76,101.15 C209.43,107.60 207.42,108.54 209.17,104.25 C210.91,100.00 210.37,85.54 208.08,74.64 C206.93,69.22 205.95,62.24 205.90,59.14 C205.80,53.85 205.74,53.72 204.93,57.00 C204.45,58.92 204.13,68.15 204.22,77.50 C204.37,93.11 204.20,94.91 202.15,99.45 C198.99,106.51 192.06,115.46 190.76,114.16 C188.49,111.89 189.93,84.88 192.72,77.19 C194.09,73.45 189.30,79.05 186.68,84.26 C182.02,93.55 180.69,101.03 181.41,113.97 L182.05,125.50 L169.94,135.00 C153.90,147.58 132.06,170.01 124.13,182.05 C118.83,190.09 118.00,190.96 118.02,188.43 Z M83.09,150.59 C78.00,145.44 77.78,144.99 78.44,141.34 C78.82,139.23 81.24,133.00 83.81,127.50 C88.47,117.57 88.50,117.43 88.49,107.00 C88.47,99.38 87.96,94.99 86.59,91.00 C84.28,84.21 77.06,69.61 76.36,70.30 C76.08,70.58 76.56,72.19 77.43,73.87 C79.91,78.65 82.99,92.88 82.99,99.57 C83.00,108.39 80.69,114.86 73.96,124.82 C70.68,129.67 68.00,134.17 68.00,134.82 C68.00,135.47 67.62,136.00 67.16,136.00 C66.07,136.00 57.00,128.93 57.00,128.07 C57.00,127.71 59.03,123.47 61.50,118.66 C66.60,108.75 67.24,103.18 64.48,92.59 C62.01,83.09 61.32,83.22 61.40,93.17 C61.45,100.19 61.02,103.39 59.69,106.10 C57.49,110.57 48.29,121.00 46.56,121.00 C44.40,121.00 39.79,109.24 39.24,102.34 C38.56,93.90 40.48,89.09 48.68,78.77 C62.32,61.60 65.53,49.22 60.98,31.41 C58.70,22.51 54.61,13.20 50.08,6.62 C47.54,2.92 47.30,2.10 48.60,1.60 C50.50,0.87 66.31,0.80 68.17,1.51 C69.18,1.90 69.42,4.19 69.15,10.95 C68.88,18.05 69.27,21.45 71.06,27.48 C72.30,31.66 73.77,35.36 74.33,35.70 C74.97,36.10 75.06,35.62 74.57,34.41 C74.15,33.36 73.57,28.88 73.27,24.45 C72.70,15.76 74.85,5.38 77.44,4.39 C79.59,3.56 92.09,10.37 97.73,15.45 C100.57,18.00 103.83,21.61 104.99,23.48 L107.09,26.88 L103.66,31.69 C94.93,43.97 91.54,55.17 91.64,71.50 C91.72,84.83 92.69,89.79 99.08,109.50 C105.86,130.41 104.79,139.90 94.39,151.01 C91.83,153.75 89.44,156.00 89.08,156.00 C88.72,156.00 86.03,153.57 83.09,150.59 Z M29.50,109.90 C26.20,107.67 21.64,104.05 19.38,101.84 L15.26,97.83 L17.24,92.67 C19.86,85.83 19.20,74.50 15.57,64.04 C12.16,54.24 10.98,53.26 12.75,61.71 C14.48,69.97 13.94,81.02 11.53,86.50 L9.77,90.50 L6.92,84.50 C2.82,75.84 1.00,67.75 1.00,58.18 C1.00,42.04 6.09,29.69 17.39,18.40 C23.48,12.31 32.07,6.09 30.82,8.67 C30.59,9.13 28.88,12.62 27.02,16.44 C21.43,27.90 22.74,38.16 31.08,48.28 C35.14,53.21 36.55,53.01 33.93,47.87 C31.25,42.61 30.40,34.47 31.90,28.31 C33.17,23.08 42.81,3.00 44.05,3.00 C44.47,3.00 46.18,6.79 47.86,11.42 C58.07,39.63 56.90,53.23 42.67,72.14 C31.96,86.38 29.60,96.21 33.92,108.52 C34.98,111.54 35.77,113.99 35.67,113.97 C35.58,113.96 32.80,112.12 29.50,109.90 Z"
/>
</svg>
);
}

View File

@@ -1,15 +1,22 @@
interface SectionHeadingProps {
children: React.ReactNode;
className?: string;
centered?: boolean;
}
export function SectionHeading({ children, className = "" }: SectionHeadingProps) {
export function SectionHeading({ children, className = "", centered = false }: SectionHeadingProps) {
return (
<h2
className={`font-display text-3xl font-bold tracking-tight sm:text-4xl lg:text-5xl ${className}`}
>
{children}
<span className="mt-3 block h-[2px] w-16 rounded-full bg-gradient-to-r from-rose-500 to-rose-500/0" />
</h2>
<div className={centered ? "text-center" : ""}>
<h2
className={`font-display text-4xl font-bold uppercase tracking-wide sm:text-5xl lg:text-6xl heading-text ${className}`}
>
{children}
</h2>
<span
className={`mt-4 block h-[1px] w-20 bg-gradient-to-r from-[#c9a96e] to-transparent ${
centered ? "mx-auto" : ""
}`}
/>
</div>
);
}

View File

@@ -68,7 +68,7 @@ export function TeamMemberModal({ member, onClose }: TeamMemberModalProps) {
href={member.instagram}
target="_blank"
rel="noopener noreferrer"
className="mt-2 inline-flex items-center gap-2 text-sm text-white/70 transition-colors hover:text-rose-400"
className="mt-2 inline-flex items-center gap-2 text-sm text-white/70 transition-colors hover:text-[#d4b87a]"
>
<Instagram size={15} className="shrink-0" />
<span>{member.instagram.split("/").filter(Boolean).pop()}</span>
@@ -80,7 +80,7 @@ export function TeamMemberModal({ member, onClose }: TeamMemberModalProps) {
{/* Description */}
{member.description && (
<div className="overflow-y-auto p-6">
<p className="text-sm leading-relaxed text-neutral-600 dark:text-neutral-400">
<p className="text-sm leading-relaxed text-neutral-600 dark:text-neutral-300">
{member.description}
</p>
</div>

View File

@@ -8,8 +8,7 @@ export function ThemeToggle() {
useEffect(() => {
const stored = localStorage.getItem("theme");
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
const isDark = stored === "dark" || (!stored && prefersDark);
const isDark = stored !== "light";
setDark(isDark);
document.documentElement.classList.toggle("dark", isDark);
}, []);
@@ -25,9 +24,9 @@ export function ThemeToggle() {
<button
onClick={toggle}
aria-label="Переключить тему"
className="social-icon rounded-full p-2"
className="rounded-full p-2 text-neutral-400 transition-all duration-300 hover:bg-neutral-100 hover:text-neutral-900 dark:text-neutral-500 dark:hover:bg-white/[0.05] dark:hover:text-white"
>
{dark ? <Sun size={20} /> : <Moon size={20} />}
{dark ? <Sun size={18} /> : <Moon size={18} />}
</button>
);
}