puzzle-trainer/globals.css
2026-05-23 01:05:21 +00:00

141 lines
5.5 KiB
CSS

@import "tailwindcss";
/* ── Design tokens ──────────────────────────────────────────────────────────── */
:root {
--radius-sm: 6px;
--radius-md: 12px;
--radius-lg: 20px;
--radius-full: 9999px;
--shadow-card: 0 1px 3px 0 rgb(0 0 0 / 0.06), 0 1px 2px -1px rgb(0 0 0 / 0.04);
--shadow-hover: 0 4px 12px 0 rgb(0 0 0 / 0.08), 0 2px 4px -1px rgb(0 0 0 / 0.05);
--shadow-win: 0 8px 24px 0 rgb(34 197 94 / 0.18);
--transition-base: 150ms ease;
--transition-smooth: 250ms cubic-bezier(0.4, 0, 0.2, 1);
}
/* ── Reset & base ───────────────────────────────────────────────────────────── */
* { box-sizing: border-box; }
html {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
scroll-behavior: smooth;
color-scheme: light;
}
body {
background: #f8fafc;
color: #09090b;
font-family: -apple-system, BlinkMacSystemFont, "Inter", "Segoe UI", "Helvetica Neue", Arial, sans-serif;
line-height: 1.5;
}
/* ── Focus visible ──────────────────────────────────────────────────────────── */
:focus-visible {
outline: 2px solid #3b82f6;
outline-offset: 2px;
border-radius: 4px;
}
/* ── Scrollbar ──────────────────────────────────────────────────────────────── */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #d1d5db; border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: #9ca3af; }
/* ── Page fade-in ───────────────────────────────────────────────────────────── */
@keyframes fadeUp {
from { opacity: 0; transform: translateY(8px); }
to { opacity: 1; transform: translateY(0); }
}
main > div { animation: fadeUp 0.25s ease both; }
/* ── Win banner animation ───────────────────────────────────────────────────── */
@keyframes popIn {
0% { transform: scale(0.85); opacity: 0; }
60% { transform: scale(1.04); }
100% { transform: scale(1); opacity: 1; }
}
.win-banner {
animation: popIn 0.38s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}
/* ── Cell flash (win feedback) ──────────────────────────────────────────────── */
@keyframes cellWin {
0% { background-color: inherit; }
40% { background-color: #bbf7d0; }
100% { background-color: inherit; }
}
.cell-win { animation: cellWin 0.6s ease both; }
/* ── Shake animation (error) ────────────────────────────────────────────────── */
@keyframes shake {
0%, 100% { transform: translateX(0); }
20% { transform: translateX(-4px); }
40% { transform: translateX(4px); }
60% { transform: translateX(-3px); }
80% { transform: translateX(3px); }
}
.shake { animation: shake 0.35s ease; }
/* ── Skeleton loading ───────────────────────────────────────────────────────── */
@keyframes shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
.skeleton {
background: linear-gradient(90deg, #f1f5f9 25%, #e2e8f0 50%, #f1f5f9 75%);
background-size: 200% 100%;
animation: shimmer 1.4s ease infinite;
border-radius: var(--radius-md);
}
/* ── Progress bar ───────────────────────────────────────────────────────────── */
.progress-track {
height: 5px;
border-radius: var(--radius-full);
background: #e2e8f0;
overflow: hidden;
}
.progress-fill {
height: 100%;
border-radius: var(--radius-full);
transition: width 0.7s cubic-bezier(0.4, 0, 0.2, 1);
}
/* ── Timer display ──────────────────────────────────────────────────────────── */
.timer-mono {
font-variant-numeric: tabular-nums;
letter-spacing: 0.05em;
}
/* ── Pulse ring (current level) ─────────────────────────────────────────────── */
@keyframes pulseRing {
0%, 100% { box-shadow: 0 0 0 0px currentColor; }
50% { box-shadow: 0 0 0 3px currentColor; }
}
.level-current { animation: pulseRing 1.8s ease-in-out infinite; }
/* ── Solved card overlay ────────────────────────────────────────────────────── */
.card-solved {
position: relative;
}
.card-solved::after {
content: "✓";
position: absolute;
top: 6px;
right: 8px;
font-size: 11px;
font-weight: 700;
color: #16a34a;
opacity: 0.8;
}