初始提交:三玩法 Web 原型与设计文档

- 玩法一 数字一笔:规则库、求解器、26 关、竖屏触摸 Web 原型、测试
- 玩法二 连连气球:连消畅玩版核心、Web 原型、Cocos 球槽组件与导出脚本
- 玩法三 六边一笔:规则库、求解器、10 关 + 转墙实验包、Web 原型、测试
- 产品文档、UI 设计规范、各玩法 GDD / HANDOFF
- 文档移除全部外部参考作引用;删除玩法二 v0 旧稿
This commit is contained in:
cabinw
2026-09-16 14:30:59 +08:00
commit 8026e4628d
169 changed files with 22162 additions and 0 deletions
+444
View File
@@ -0,0 +1,444 @@
:root {
--bg: #ffffff;
--ink: #20223a;
--ink-2: #686a80;
--ink-3: #a3a5b5;
--cell: #e4e6ee;
--primary: #4f5bd5;
--primary-soft: #e9ebfb;
--danger: #e5484d;
--wall: #1f1f27;
--wall-stripe: #ffc826;
--hex: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
--safe-top: env(safe-area-inset-top, 0px);
--safe-bottom: env(safe-area-inset-bottom, 0px);
--safe-left: env(safe-area-inset-left, 0px);
--safe-right: env(safe-area-inset-right, 0px);
}
* {
box-sizing: border-box;
-webkit-tap-highlight-color: transparent;
}
html,
body {
margin: 0;
height: 100%;
background: #f2f2f6;
color: var(--ink);
font-family: "SF Pro Rounded", "PingFang SC", "Helvetica Neue", "Segoe UI", system-ui, -apple-system, sans-serif;
-webkit-font-smoothing: antialiased;
user-select: none;
-webkit-user-select: none;
touch-action: manipulation;
overscroll-behavior: none;
}
#app {
position: relative;
margin: 0 auto;
width: 100%;
max-width: 480px;
height: 100vh;
height: 100dvh;
background: var(--bg);
overflow: hidden;
}
.screen {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
padding: calc(var(--safe-top) + 12px) calc(var(--safe-right) + 20px) calc(var(--safe-bottom) + 16px)
calc(var(--safe-left) + 20px);
}
.screen.hidden {
display: none;
}
button {
font: inherit;
color: inherit;
background: none;
border: 0;
padding: 0;
cursor: pointer;
-webkit-touch-callout: none;
}
button:active {
transform: scale(0.97);
}
/* ---------- 选关 ---------- */
.select-header {
padding: 24px 4px 8px;
}
.logo {
display: flex;
gap: 4px;
margin-bottom: 14px;
}
.logo-hex {
width: 26px;
height: 30px;
background: var(--cell);
clip-path: var(--hex);
}
.logo-hex.on {
background: var(--primary);
}
.logo-hex.wall {
background: repeating-linear-gradient(135deg, var(--wall) 0 5px, var(--wall-stripe) 5px 10px);
}
.select-header h1 {
margin: 0;
font-size: 34px;
font-weight: 800;
letter-spacing: 0.02em;
}
.select-header .sub {
margin: 8px 0 0;
color: var(--ink-2);
font-size: 15px;
}
.pack {
margin-top: 24px;
}
.pack-title {
display: flex;
align-items: baseline;
justify-content: space-between;
padding: 0 4px 12px;
font-size: 17px;
font-weight: 700;
}
.pack-progress {
color: var(--ink-3);
font-size: 14px;
font-weight: 600;
font-variant-numeric: tabular-nums;
}
.level-grid {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 10px 12px;
}
.pack-head {
grid-column: 1 / -1;
padding: 10px 4px 0;
color: var(--ink-3);
font-size: 13px;
font-weight: 700;
letter-spacing: 0.06em;
}
.pack-head:first-child {
padding-top: 0;
}
.level-tile {
position: relative;
aspect-ratio: 0.9;
clip-path: var(--hex);
background: var(--cell);
color: var(--ink);
font-size: 20px;
font-weight: 700;
font-variant-numeric: tabular-nums;
display: flex;
align-items: center;
justify-content: center;
transition: transform 0.12s ease;
}
.level-tile.cleared {
background: var(--primary);
color: #fff;
}
.level-tile.cleared::after {
content: "";
position: absolute;
right: 22%;
top: 22%;
width: 7px;
height: 7px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.85);
}
.level-tile.current {
background: var(--primary-soft);
color: var(--primary);
}
.level-tile.current::before {
content: "";
position: absolute;
inset: 0;
clip-path: var(--hex);
background: var(--primary);
z-index: -1;
}
.level-tile.current span {
position: relative;
}
.level-tile.current {
isolation: isolate;
}
.level-tile.current::after {
content: "";
position: absolute;
inset: 3px;
clip-path: var(--hex);
background: var(--primary-soft);
z-index: -1;
}
.level-tile.locked {
color: var(--ink-3);
background: #f0f0f4;
}
.level-tile.locked::before {
content: "";
width: 10px;
height: 12px;
border: 2px solid var(--ink-3);
border-radius: 3px;
border-top-width: 3px;
}
.level-tile.locked span {
display: none;
}
.level-tile.shake {
animation: shake 0.3s ease;
}
.primary {
margin-top: auto;
height: 54px;
border-radius: 16px;
background: var(--primary);
color: #fff;
font-size: 18px;
font-weight: 700;
box-shadow: 0 6px 18px rgba(79, 91, 213, 0.28);
}
.select-footer {
display: flex;
justify-content: center;
gap: 10px;
padding-top: 18px;
}
.chip {
height: 34px;
padding: 0 14px;
border-radius: 17px;
background: #f0f0f4;
color: var(--ink-2);
font-size: 13px;
font-weight: 600;
}
.chip.on {
background: var(--primary-soft);
color: var(--primary);
}
.chip.danger {
color: var(--danger);
}
/* ---------- 对局 ---------- */
.topbar {
display: grid;
grid-template-columns: 44px 1fr 44px;
align-items: center;
height: 48px;
}
.topbar .icon {
width: 44px;
height: 44px;
display: flex;
align-items: center;
justify-content: center;
color: var(--ink-2);
border-radius: 22px;
}
.level-title {
text-align: center;
font-size: 20px;
font-weight: 800;
letter-spacing: 0.04em;
font-variant-numeric: tabular-nums;
}
.remaining {
justify-self: end;
display: flex;
align-items: center;
gap: 6px;
color: var(--ink-2);
font-size: 15px;
font-weight: 700;
font-variant-numeric: tabular-nums;
min-width: 44px;
justify-content: flex-end;
}
.remaining .hex-dot {
width: 13px;
height: 15px;
clip-path: var(--hex);
background: var(--ink-3);
}
.caption {
height: 40px;
margin-top: 4px;
display: flex;
align-items: center;
justify-content: center;
color: var(--ink-2);
font-size: 15px;
text-align: center;
transition: opacity 0.2s;
}
.caption:empty {
opacity: 0;
}
.board-wrap {
flex: 1;
min-height: 0;
position: relative;
}
#board {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
touch-action: none;
display: block;
}
.bottombar {
display: flex;
justify-content: center;
gap: 14px;
padding-top: 12px;
}
.action {
flex: 1;
max-width: 170px;
height: 56px;
border-radius: 18px;
background: #f0f0f4;
color: var(--ink);
font-size: 16px;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
transition: background 0.15s;
}
.action.pulse {
animation: pulse 0.9s ease infinite;
}
.action:disabled {
opacity: 0.4;
pointer-events: none;
}
.toast {
position: absolute;
left: 50%;
bottom: calc(var(--safe-bottom) + 92px);
transform: translate(-50%, 8px);
padding: 10px 16px;
border-radius: 12px;
background: rgba(32, 34, 58, 0.92);
color: #fff;
font-size: 14px;
font-weight: 600;
white-space: nowrap;
opacity: 0;
pointer-events: none;
transition: opacity 0.18s, transform 0.18s;
}
.toast.show {
opacity: 1;
transform: translate(-50%, 0);
}
@keyframes shake {
0%,
100% {
transform: translateX(0);
}
25% {
transform: translateX(-5px);
}
50% {
transform: translateX(5px);
}
75% {
transform: translateX(-3px);
}
}
@keyframes pulse {
0%,
100% {
box-shadow: 0 0 0 0 rgba(255, 122, 26, 0);
}
50% {
box-shadow: 0 0 0 5px rgba(255, 122, 26, 0.35);
}
}
@media (min-width: 520px) {
body {
padding: 24px 0;
}
#app {
height: calc(100vh - 48px);
height: calc(100dvh - 48px);
border-radius: 28px;
box-shadow: 0 20px 60px rgba(20, 20, 40, 0.14);
}
}