: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); } }