141 lines
5.5 KiB
CSS
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;
|
|
}
|