Skip to content

Commit 8101829

Browse files
committed
Migrate to scss
1 parent 8695260 commit 8101829

17 files changed

Lines changed: 6976 additions & 50 deletions
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
.card {
2+
background: rgba(0, 0, 0, 0.3);
3+
border: 2px solid rgba(255, 255, 255, 0.1);
4+
border-radius: 1rem;
5+
padding: 2rem;
6+
text-align: center;
7+
cursor: pointer;
8+
transition: all 300ms ease-in-out;
9+
position: relative;
10+
overflow: hidden;
11+
12+
&:hover {
13+
transform: translateY(-0.75rem) scale(1.05);
14+
border-color: #667eea;
15+
box-shadow: 0 20px 40px rgba(102, 126, 234, 0.4);
16+
17+
.backgroundGradient {
18+
opacity: 0.1;
19+
}
20+
}
21+
}
22+
23+
.backgroundGradient {
24+
position: absolute;
25+
inset: 0;
26+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
27+
opacity: 0;
28+
transition: opacity 300ms ease-in-out;
29+
z-index: 0;
30+
}
31+
32+
.content {
33+
position: relative;
34+
z-index: 10;
35+
}
36+
37+
.icon {
38+
font-size: 3rem;
39+
margin-bottom: 1rem;
40+
}
41+
42+
.title {
43+
font-size: 1.25rem;
44+
margin-bottom: 0.75rem;
45+
color: white;
46+
font-weight: 600;
47+
}
48+
49+
.description {
50+
color: rgba(255, 255, 255, 0.7);
51+
font-size: 0.875rem;
52+
line-height: 1.6;
53+
}

‎abacus-app/components/TrainerCard.tsx‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import React from 'react';
44
import Link from 'next/link';
55
import { Trainer } from '@/types';
6+
import styles from './TrainerCard.module.scss';
67

78
interface TrainerCardProps {
89
trainer: Trainer;
@@ -11,14 +12,14 @@ interface TrainerCardProps {
1112
export const TrainerCard: React.FC<TrainerCardProps> = ({ trainer }) => {
1213
return (
1314
<Link href={trainer.path}>
14-
<div className="bg-black/30 border-2 border-white/10 rounded-2xl p-8 text-center cursor-pointer transition-all duration-300 relative overflow-hidden group hover:-translate-y-3 hover:scale-105 hover:border-[#667eea] hover:shadow-[0_20px_40px_rgba(102,126,234,0.4)]">
15+
<div className={styles.card}>
1516
{/* Background gradient on hover */}
16-
<div className="absolute inset-0 bg-gradient-primary opacity-0 group-hover:opacity-10 transition-opacity duration-300 z-0" />
17+
<div className={styles.backgroundGradient} />
1718

18-
<div className="relative z-10">
19-
<div className="text-5xl mb-4">{trainer.icon}</div>
20-
<h3 className="text-xl mb-3 text-white font-semibold">{trainer.title}</h3>
21-
<p className="text-white/70 text-sm leading-relaxed">{trainer.description}</p>
19+
<div className={styles.content}>
20+
<div className={styles.icon}>{trainer.icon}</div>
21+
<h3 className={styles.title}>{trainer.title}</h3>
22+
<p className={styles.description}>{trainer.description}</p>
2223
</div>
2324
</div>
2425
</Link>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
.abacusCard {
2+
background: linear-gradient(
3+
135deg,
4+
rgba(102, 126, 234, 0.1) 0%,
5+
rgba(118, 75, 162, 0.1) 100%
6+
);
7+
}
8+
9+
.title {
10+
font-size: 1.875rem;
11+
margin-bottom: 1.25rem;
12+
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
13+
background-clip: text;
14+
-webkit-background-clip: text;
15+
-webkit-text-fill-color: transparent;
16+
font-weight: bold;
17+
}
18+
19+
.container {
20+
display: flex;
21+
justify-content: center;
22+
padding: 2.5rem 0;
23+
}
24+
25+
.abacusFrame {
26+
display: flex;
27+
gap: 1rem;
28+
background: rgba(0, 0, 0, 0.3);
29+
padding: 2rem;
30+
border-radius: 1rem;
31+
box-shadow: inset 0 5px 20px rgba(0, 0, 0, 0.5);
32+
}
33+
34+
.footer {
35+
text-align: center;
36+
margin-top: 1.25rem;
37+
color: rgba(255, 255, 255, 0.7);
38+
39+
p {
40+
margin-bottom: 0.25rem;
41+
}
42+
}

‎abacus-app/components/trainers/Abacus.tsx‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import React, { useEffect } from 'react';
44
import { AbacusColumn } from './AbacusColumn';
55
import { useAbacus } from '@/hooks/useAbacus';
66
import { Card } from '@/components/ui/Card';
7+
import styles from './Abacus.module.scss';
78

89
interface AbacusProps {
910
columns?: number;
@@ -37,13 +38,13 @@ export const Abacus: React.FC<AbacusProps> = ({
3738
}, [currentValue, onChange]);
3839

3940
return (
40-
<Card className="bg-gradient-to-br from-[rgba(102,126,234,0.1)] to-[rgba(118,75,162,0.1)]">
41-
<h2 className="text-3xl mb-5 bg-gradient-accent bg-clip-text text-transparent font-bold">
41+
<Card className={styles.abacusCard}>
42+
<h2 className={styles.title}>
4243
Соробан (Японский абакус)
4344
</h2>
4445

45-
<div className="flex justify-center py-10">
46-
<div className="flex gap-4 bg-black/30 p-8 rounded-2xl shadow-[inset_0_5px_20px_rgba(0,0,0,0.5)]">
46+
<div className={styles.container}>
47+
<div className={styles.abacusFrame}>
4748
{Array.from({ length: columns }, (_, i) => columns - 1 - i).map((col) => (
4849
<AbacusColumn
4950
key={col}
@@ -57,8 +58,8 @@ export const Abacus: React.FC<AbacusProps> = ({
5758
</div>
5859

5960
{showValue && (
60-
<div className="text-center mt-5 text-white/70">
61-
<p className="mb-1">Нажимайте на бусины, чтобы двигать их</p>
61+
<div className={styles.footer}>
62+
<p>Нажимайте на бусины, чтобы двигать их</p>
6263
<p>Верхняя бусина = 5, нижние бусины = 1</p>
6364
</div>
6465
)}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
.column {
2+
display: flex;
3+
flex-direction: column;
4+
align-items: center;
5+
gap: 0.75rem;
6+
}
7+
8+
.label {
9+
font-size: 0.875rem;
10+
color: rgba(255, 255, 255, 0.7);
11+
margin-bottom: 0.25rem;
12+
font-weight: 600;
13+
}
14+
15+
.rodContainer {
16+
position: relative;
17+
}
18+
19+
.rod {
20+
width: 0.375rem;
21+
height: 300px;
22+
background: linear-gradient(to bottom, #4b5563, #1f2937);
23+
border-radius: 9999px;
24+
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
25+
}
26+
27+
.divider {
28+
position: absolute;
29+
width: 2rem;
30+
height: 0.25rem;
31+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
32+
left: 50%;
33+
transform: translateX(-50%);
34+
top: 5rem;
35+
border-radius: 9999px;
36+
box-shadow: 0 0 10px rgba(102, 126, 234, 0.5);
37+
}
38+
39+
.topBeadsContainer {
40+
position: absolute;
41+
top: 0.5rem;
42+
left: 50%;
43+
transform: translateX(-50%);
44+
display: flex;
45+
flex-direction: column;
46+
gap: 0.5rem;
47+
}
48+
49+
.bottomBeadsContainer {
50+
position: absolute;
51+
bottom: 0.5rem;
52+
left: 50%;
53+
transform: translateX(-50%);
54+
display: flex;
55+
flex-direction: column;
56+
gap: 0.5rem;
57+
}

‎abacus-app/components/trainers/AbacusColumn.tsx‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import React from 'react';
44
import { Bead } from './Bead';
55
import { BeadPosition } from '@/types';
66
import { getSuperscript } from '@/lib/utils';
7+
import styles from './AbacusColumn.module.scss';
78

89
interface AbacusColumnProps {
910
column: number;
@@ -27,18 +28,18 @@ export const AbacusColumn: React.FC<AbacusColumnProps> = ({
2728
.sort((a, b) => a.index - b.index);
2829

2930
return (
30-
<div className="flex flex-col items-center gap-3">
31-
<div className="text-sm text-white/70 mb-1 font-semibold">{label}</div>
31+
<div className={styles.column}>
32+
<div className={styles.label}>{label}</div>
3233

33-
<div className="relative">
34+
<div className={styles.rodContainer}>
3435
{/* Rod */}
35-
<div className="w-1.5 h-[300px] bg-gradient-to-b from-gray-600 to-gray-800 rounded-full shadow-[0_0_10px_rgba(0,0,0,0.5)]" />
36+
<div className={styles.rod} />
3637

3738
{/* Divider */}
38-
<div className="absolute w-8 h-1 bg-gradient-primary left-1/2 -translate-x-1/2 top-20 rounded-full shadow-[0_0_10px_rgba(102,126,234,0.5)]" />
39+
<div className={styles.divider} />
3940

4041
{/* Top bead container */}
41-
<div className="absolute top-2 left-1/2 -translate-x-1/2 flex flex-col gap-2">
42+
<div className={styles.topBeadsContainer}>
4243
{topBead && (
4344
<Bead
4445
active={topBead.active}
@@ -49,7 +50,7 @@ export const AbacusColumn: React.FC<AbacusColumnProps> = ({
4950
</div>
5051

5152
{/* Bottom beads container */}
52-
<div className="absolute bottom-2 left-1/2 -translate-x-1/2 flex flex-col gap-2">
53+
<div className={styles.bottomBeadsContainer}>
5354
{bottomBeads.map((bead) => (
5455
<Bead
5556
key={`${bead.column}-${bead.type}-${bead.index}`}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
.bead {
2+
width: 2.25rem;
3+
height: 2.25rem;
4+
border-radius: 50%;
5+
cursor: pointer;
6+
position: relative;
7+
z-index: 10;
8+
transition: all 300ms ease-in-out;
9+
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
10+
11+
&:hover {
12+
transform: scale(1.1);
13+
box-shadow: 0 8px 25px rgba(240, 147, 251, 0.6);
14+
}
15+
16+
&:active {
17+
transform: scale(0.95);
18+
}
19+
20+
&.active {
21+
background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
22+
box-shadow: 0 5px 25px rgba(67, 233, 123, 0.6);
23+
}
24+
25+
&.inactive {
26+
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
27+
}
28+
}

‎abacus-app/components/trainers/Bead.tsx‎

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import React from 'react';
44
import { cn } from '@/lib/utils';
5+
import styles from './Bead.module.scss';
56

67
interface BeadProps {
78
active: boolean;
@@ -14,12 +15,8 @@ export const Bead: React.FC<BeadProps> = ({ active, onClick, type }) => {
1415
<div
1516
onClick={onClick}
1617
className={cn(
17-
'w-9 h-9 rounded-full cursor-pointer transition-all duration-300 relative z-10',
18-
'shadow-[0_5px_15px_rgba(0,0,0,0.3)]',
19-
'hover:scale-110 hover:shadow-[0_8px_25px_rgba(240,147,251,0.6)] active:scale-95',
20-
active
21-
? 'bg-gradient-success shadow-[0_5px_25px_rgba(67,233,123,0.6)]'
22-
: 'bg-gradient-secondary'
18+
styles.bead,
19+
active ? styles.active : styles.inactive
2320
)}
2421
/>
2522
);
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
.button {
2+
padding: 1rem 2rem;
3+
font-size: 1rem;
4+
font-weight: 600;
5+
border-radius: 0.75rem;
6+
cursor: pointer;
7+
transition: all 300ms ease-in-out;
8+
position: relative;
9+
overflow: hidden;
10+
color: white;
11+
12+
&:disabled {
13+
opacity: 0.5;
14+
cursor: not-allowed;
15+
}
16+
17+
&:active:not(:disabled) {
18+
transform: scale(0.95);
19+
}
20+
}
21+
22+
.primary {
23+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
24+
box-shadow: 0 10px 30px rgba(102, 126, 234, 0.4);
25+
26+
&:hover:not(:disabled) {
27+
box-shadow: 0 15px 40px rgba(102, 126, 234, 0.6);
28+
}
29+
}
30+
31+
.secondary {
32+
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
33+
box-shadow: 0 10px 30px rgba(240, 147, 251, 0.4);
34+
35+
&:hover:not(:disabled) {
36+
box-shadow: 0 15px 40px rgba(240, 147, 251, 0.6);
37+
}
38+
}
39+
40+
.accent {
41+
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
42+
box-shadow: 0 10px 30px rgba(79, 172, 254, 0.4);
43+
44+
&:hover:not(:disabled) {
45+
box-shadow: 0 15px 40px rgba(79, 172, 254, 0.6);
46+
}
47+
}

‎abacus-app/components/ui/Button.tsx‎

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22
import { cn } from '@/lib/utils';
3+
import styles from './Button.module.scss';
34

45
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
56
variant?: 'primary' | 'secondary' | 'accent';
@@ -12,17 +13,9 @@ export const Button: React.FC<ButtonProps> = ({
1213
className,
1314
...props
1415
}) => {
15-
const baseStyles = 'px-8 py-4 text-base font-semibold rounded-xl cursor-pointer transition-all duration-300 relative overflow-hidden text-white disabled:opacity-50 disabled:cursor-not-allowed';
16-
17-
const variantStyles = {
18-
primary: 'bg-gradient-primary shadow-[0_10px_30px_rgba(102,126,234,0.4)] hover:shadow-[0_15px_40px_rgba(102,126,234,0.6)] active:scale-95',
19-
secondary: 'bg-gradient-secondary shadow-[0_10px_30px_rgba(240,147,251,0.4)] hover:shadow-[0_15px_40px_rgba(240,147,251,0.6)] active:scale-95',
20-
accent: 'bg-gradient-accent shadow-[0_10px_30px_rgba(79,172,254,0.4)] hover:shadow-[0_15px_40px_rgba(79,172,254,0.6)] active:scale-95',
21-
};
22-
2316
return (
2417
<button
25-
className={cn(baseStyles, variantStyles[variant], className)}
18+
className={cn(styles.button, styles[variant], className)}
2619
{...props}
2720
>
2821
{children}

0 commit comments

Comments
 (0)