chore: initialize typing-chud project with Unified API structure
- Copy vim-snake structure stripped of game-specific logic - Remove finalScore calculation (raw data only) - Setup example app with keybinding state management - Empty board renders and waits for game logic
This commit is contained in:
Executable
+149
@@ -0,0 +1,149 @@
|
||||
/* =========================================================
|
||||
🔧 Controls (tweak these)
|
||||
========================================================= */
|
||||
:root {
|
||||
--snake-cell-size: 32px;
|
||||
}
|
||||
|
||||
/* =========================================================
|
||||
Container & Board Base
|
||||
========================================================= */
|
||||
#snake-board {
|
||||
position: relative;
|
||||
background-color: var(--card, #1e2030);
|
||||
border-radius: 0.5rem;
|
||||
box-shadow: 0 0 10px rgba(27, 29, 43, 0.6), inset 0 0 6px color-mix(in srgb, var(--primary, #82aaff) 5%, transparent);
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
/* =========================================================
|
||||
Snake Board Layout
|
||||
========================================================= */
|
||||
.snake-row {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.snake-cell {
|
||||
width: var(--snake-cell-size);
|
||||
height: var(--snake-cell-size);
|
||||
background-color: var(--muted, #2f334d);
|
||||
border: 1px solid var(--border, #3b3f5c);
|
||||
box-sizing: border-box;
|
||||
transition: background-color 0.1s ease;
|
||||
}
|
||||
|
||||
/* =========================================================
|
||||
Snake Rendering
|
||||
========================================================= */
|
||||
.snake-cell.snake-head {
|
||||
background-color: var(--accent, #ffc777);
|
||||
box-shadow:
|
||||
0 0 8px color-mix(in srgb, var(--accent, #ffc777) 70%, transparent),
|
||||
inset 0 0 4px color-mix(in srgb, var(--accent, #ffc777) 90%, transparent);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.snake-cell.snake-head.dir-up {
|
||||
border-radius: 6px 6px 2px 2px;
|
||||
}
|
||||
|
||||
.snake-cell.snake-head.dir-down {
|
||||
border-radius: 2px 2px 6px 6px;
|
||||
}
|
||||
|
||||
.snake-cell.snake-head.dir-left {
|
||||
border-radius: 6px 2px 2px 6px;
|
||||
}
|
||||
|
||||
.snake-cell.snake-head.dir-right {
|
||||
border-radius: 2px 6px 6px 2px;
|
||||
}
|
||||
|
||||
.snake-cell.snake-head::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 25%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 60%;
|
||||
height: 30%;
|
||||
background: radial-gradient(circle, var(--accent-foreground, #1b1d2b) 30%, transparent 60%);
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.snake-cell.snake-body {
|
||||
background-color: var(--accent, #ffc777);
|
||||
opacity: 0.7;
|
||||
box-shadow: inset 0 0 3px color-mix(in srgb, var(--accent, #ffc777) 50%, transparent);
|
||||
}
|
||||
|
||||
.snake-cell.snake-tail {
|
||||
background-color: var(--accent, #ffc777);
|
||||
opacity: 0.5;
|
||||
box-shadow: 0 0 4px color-mix(in srgb, var(--accent, #ffc777) 40%, transparent);
|
||||
}
|
||||
|
||||
.snake-cell.snake-tail.dir-up {
|
||||
border-radius: 6px 6px 2px 2px;
|
||||
}
|
||||
|
||||
.snake-cell.snake-tail.dir-down {
|
||||
border-radius: 2px 2px 6px 6px;
|
||||
}
|
||||
|
||||
.snake-cell.snake-tail.dir-left {
|
||||
border-radius: 6px 2px 2px 6px;
|
||||
}
|
||||
|
||||
.snake-cell.snake-tail.dir-right {
|
||||
border-radius: 2px 6px 6px 2px;
|
||||
}
|
||||
|
||||
/* =========================================================
|
||||
Collision Effect
|
||||
========================================================= */
|
||||
.snake-cell.collision {
|
||||
background-color: var(--destructive, #c53b53) !important;
|
||||
box-shadow:
|
||||
0 0 12px color-mix(in srgb, var(--destructive, #c53b53) 90%, transparent),
|
||||
0 0 24px color-mix(in srgb, var(--destructive, #c53b53) 60%, transparent),
|
||||
inset 0 0 8px color-mix(in srgb, var(--destructive, #c53b53) 70%, transparent) !important;
|
||||
animation: collision-pulse 0.5s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes collision-pulse {
|
||||
0% {
|
||||
box-shadow:
|
||||
0 0 12px color-mix(in srgb, var(--destructive, #c53b53) 90%, transparent),
|
||||
0 0 24px color-mix(in srgb, var(--destructive, #c53b53) 60%, transparent),
|
||||
inset 0 0 8px color-mix(in srgb, var(--destructive, #c53b53) 70%, transparent);
|
||||
}
|
||||
100% {
|
||||
box-shadow:
|
||||
0 0 20px color-mix(in srgb, var(--destructive, #c53b53) 100%, transparent),
|
||||
0 0 40px color-mix(in srgb, var(--destructive, #c53b53) 80%, transparent),
|
||||
inset 0 0 12px color-mix(in srgb, var(--destructive, #c53b53) 90%, transparent);
|
||||
}
|
||||
}
|
||||
|
||||
/* =========================================================
|
||||
Food Rendering
|
||||
========================================================= */
|
||||
.snake-cell.food {
|
||||
background-color: var(--chart-2, #c3e88d);
|
||||
border-radius: 50%;
|
||||
box-shadow:
|
||||
0 0 8px color-mix(in srgb, var(--chart-2, #c3e88d) 60%, transparent),
|
||||
inset 0 0 4px color-mix(in srgb, var(--chart-2, #c3e88d) 80%, transparent);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.snake-cell.food::after {
|
||||
content: "🍎";
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user